Adding upstream version 2.25.15.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
This commit is contained in:
parent
10737b110a
commit
b543f2e88d
485 changed files with 191459 additions and 0 deletions
600
scripts/mass-bug.pl
Executable file
600
scripts/mass-bug.pl
Executable file
|
@ -0,0 +1,600 @@
|
|||
#!/usr/bin/perl
|
||||
|
||||
# mass-bug: mass-file a bug report against a list of packages
|
||||
# For options, see the usage message below.
|
||||
#
|
||||
# Copyright 2006 by Joey Hess <joeyh@debian.org>
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 2 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
=head1 NAME
|
||||
|
||||
mass-bug - mass-file a bug report against a list of packages
|
||||
|
||||
=head1 SYNOPSIS
|
||||
|
||||
B<mass-bug> [I<options>] B<--subject=">I<bug subject>B<"> I<template package-list>
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
mass-bug assists in filing a mass bug report in the Debian BTS on a set of
|
||||
packages. For each package in the package-list file (which should list one
|
||||
package per line together with an optional version number separated
|
||||
from the package name by an underscore), it fills out the template, adds
|
||||
BTS pseudo-headers, and either displays or sends the bug report.
|
||||
|
||||
Warning: Some care has been taken to avoid unpleasant and common mistakes,
|
||||
but this is still a power tool that can generate massive amounts of bug
|
||||
report mails. Use it with care, and read the documentation in the
|
||||
Developer's Reference about mass filing of bug reports first.
|
||||
|
||||
=head1 TEMPLATE
|
||||
|
||||
The template file is the body of the message that will be sent for each bug
|
||||
report, excluding the BTS pseudo-headers. In the template, #PACKAGE# is
|
||||
replaced with the name of the package. If a version was specified for
|
||||
the package, #VERSION# will be replaced by that version.
|
||||
|
||||
The components of the version number may be specified using #EPOCH#,
|
||||
#UPSTREAM_VERSION# and #REVISION#. #EPOCH# includes the trailing colon and
|
||||
#REVISION# the leading dash so that #EPOCH#UPSTREAM_VERSION##REVISION# is
|
||||
always the same as #VERSION#.
|
||||
|
||||
If B<--include> has been passed, #INCLUDE# is replaced by the contents of
|
||||
the named file. This contents is also subject to text wrapping as described
|
||||
below.
|
||||
|
||||
Note that text in the template will be automatically word-wrapped to 70
|
||||
columns, up to the start of a signature (indicated by S<'-- '> at the
|
||||
start of a line on its own). This is another reason to avoid including
|
||||
BTS pseudo-headers in your template.
|
||||
|
||||
=head1 OPTIONS
|
||||
|
||||
B<mass-bug> examines the B<devscripts> configuration files as described
|
||||
below. Command line options override the configuration file settings,
|
||||
though.
|
||||
|
||||
=over 4
|
||||
|
||||
=item B<--severity=>(B<wishlist>|B<minor>|B<normal>|B<important>|B<serious>|B<grave>|B<critical>)
|
||||
|
||||
Specify the severity with which bugs should be filed. Default
|
||||
is B<normal>.
|
||||
|
||||
=item B<--display>
|
||||
|
||||
Fill out the templates for each package and display them all for
|
||||
verification. This is the default behavior.
|
||||
|
||||
=item B<--send>
|
||||
|
||||
Actually send the bug reports.
|
||||
|
||||
=item B<--subject=">I<bug subject>B<">
|
||||
|
||||
Specify the subject of the bug report. The subject will be automatically
|
||||
prefixed with the name of the package that the bug is filed against.
|
||||
|
||||
=item B<--tags>
|
||||
|
||||
Set the BTS pseudo-header for tags.
|
||||
|
||||
=item B<--user>
|
||||
|
||||
Set the BTS pseudo-header for a usertags' user.
|
||||
|
||||
=item B<--usertags>
|
||||
|
||||
Set the BTS pseudo-header for usertags.
|
||||
|
||||
=item B<--control=>I<COMMAND>
|
||||
|
||||
Add a BTS control command. This option may be repeated to add multiple
|
||||
control commands. For example, if you are mass-bug-filing "please stop
|
||||
depending on this deprecated package", and bug 123456 represents removal
|
||||
of the deprecated package, you could use:
|
||||
|
||||
mass-bug --control='block 123456 by -1' ...
|
||||
|
||||
=item B<--source>
|
||||
|
||||
Specify that package names refer to source packages rather than binary
|
||||
packages.
|
||||
|
||||
=item B<--sendmail=>I<SENDMAILCMD>
|
||||
|
||||
Specify the B<sendmail> command. The command will be split on white
|
||||
space and will not be passed to a shell. Default is F</usr/sbin/sendmail>.
|
||||
|
||||
=item B<--no-wrap>
|
||||
|
||||
Do not wrap the template to lines of 70 characters.
|
||||
|
||||
=item B<--no-conf>, B<--noconf>
|
||||
|
||||
Do not read any configuration files. This can only be used as the
|
||||
first option given on the command-line.
|
||||
|
||||
=item B<--include=FILENAME>
|
||||
|
||||
Include the contents of B<FILENAME> in the template, replacing the #INCLUDE#
|
||||
placeholder. A %s in B<FILENAME> gets replaced by the current package name.
|
||||
|
||||
=item B<--help>
|
||||
|
||||
Provide a usage message.
|
||||
|
||||
=item B<--version>
|
||||
|
||||
Display version information.
|
||||
|
||||
=back
|
||||
|
||||
=head1 ENVIRONMENT
|
||||
|
||||
B<DEBEMAIL> and B<EMAIL> can be set in the environment to control the email
|
||||
address that the bugs are sent from.
|
||||
|
||||
=head1 CONFIGURATION VARIABLES
|
||||
|
||||
The two configuration files F</etc/devscripts.conf> and
|
||||
F<~/.devscripts> are sourced by a shell in that order to set
|
||||
configuration variables. Command line options can be used to override
|
||||
configuration file settings. Environment variable settings are
|
||||
ignored for this purpose. The currently recognised variables are:
|
||||
|
||||
=over 4
|
||||
|
||||
=item B<BTS_SENDMAIL_COMMAND>
|
||||
|
||||
If this is set, specifies a B<sendmail> command to use instead of
|
||||
F</usr/sbin/sendmail>. Same as the B<--sendmail> command line option.
|
||||
|
||||
=back
|
||||
|
||||
=cut
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
use Getopt::Long qw(:config bundling permute no_getopt_compat);
|
||||
use Text::Wrap;
|
||||
use File::Basename;
|
||||
use Dpkg::Path qw(find_command);
|
||||
use POSIX qw(locale_h strftime);
|
||||
|
||||
setlocale(LC_TIME, "C"); # so that strftime is locale independent
|
||||
|
||||
my $progname = basename($0);
|
||||
$Text::Wrap::columns = 70;
|
||||
my $submission_email = "maintonly\@bugs.debian.org";
|
||||
my $sendmailcmd = '/usr/sbin/sendmail';
|
||||
my $modified_conf_msg;
|
||||
my %versions;
|
||||
|
||||
sub usageerror {
|
||||
die
|
||||
"Usage: $progname [options] --subject=\"bug subject\" <template> <package-list>\n";
|
||||
}
|
||||
|
||||
sub usage {
|
||||
print <<"EOT";
|
||||
Usage:
|
||||
$progname [options] --subject="bug subject" <template> <package-list>
|
||||
|
||||
Valid options are:
|
||||
--display Display the messages but don\'t send them
|
||||
--send Actually send the mass bug reports to the BTS
|
||||
--subject="bug subject"
|
||||
Text for email subject line (will be prefixed
|
||||
with "package: ")
|
||||
--severity=(wishlist|minor|normal|important|serious|grave|critical)
|
||||
Specify the severity of the bugs to be filed
|
||||
(default "normal")
|
||||
|
||||
--tags=tags Set the BTS pseudo-header for tags.
|
||||
--user=user Set the BTS pseudo-header for a usertags' user
|
||||
--usertags=usertags Set the BTS pseudo-header for usertags
|
||||
--control="COMMAND" Add an arbitrary BTS control command (repeatable)
|
||||
--source Specify that package names refer to source packages
|
||||
|
||||
--sendmail=cmd Sendmail command to use (default /usr/sbin/sendmail)
|
||||
--no-wrap Don't wrap the template to 70 chars.
|
||||
--no-conf, --noconf Don\'t read devscripts config files;
|
||||
must be the first option given
|
||||
--help Display this message
|
||||
--version Display version and copyright info
|
||||
|
||||
--include="PATTERN" Pattern specifying filename to be included in the
|
||||
template, replacing #INCLUDE#. %s in the pattern will
|
||||
be replaced with the package name, e.g.
|
||||
--include="logs/%s.log"
|
||||
<template> File containing email template; #PACKAGE# will
|
||||
be replaced by the package name, #VERSION#
|
||||
with the corresponding version (or a blank
|
||||
string if the version was not specified),
|
||||
and #INCLUDE# with the contents of the file
|
||||
specified by --include (if given).
|
||||
<package-list> File containing list of packages, one per line
|
||||
in the format package(_version)
|
||||
|
||||
Ensure that you read the Developer\'s Reference on mass-filing bugs before
|
||||
using this script!
|
||||
|
||||
Default settings modified by devscripts configuration files:
|
||||
$modified_conf_msg
|
||||
EOT
|
||||
}
|
||||
|
||||
sub version () {
|
||||
print <<"EOF";
|
||||
This is $progname, from the Debian devscripts package, version ###VERSION###
|
||||
This code is copyright 2006 by Joey Hess, all rights reserved.
|
||||
This program comes with ABSOLUTELY NO WARRANTY.
|
||||
You are free to redistribute this code under the terms of the
|
||||
GNU General Public License, version 2 or later.
|
||||
EOF
|
||||
}
|
||||
|
||||
# Next, read read configuration files and then command line
|
||||
# The next stuff is boilerplate
|
||||
|
||||
if (@ARGV and $ARGV[0] =~ /^--no-?conf$/) {
|
||||
$modified_conf_msg = " (no configuration files read)";
|
||||
shift;
|
||||
} else {
|
||||
my @config_files = ('/etc/devscripts.conf', '~/.devscripts');
|
||||
my %config_vars = ('BTS_SENDMAIL_COMMAND' => '/usr/sbin/sendmail',);
|
||||
my %config_default = %config_vars;
|
||||
|
||||
my $shell_cmd;
|
||||
# Set defaults
|
||||
foreach my $var (keys %config_vars) {
|
||||
$shell_cmd .= qq[$var="$config_vars{$var}";\n];
|
||||
}
|
||||
$shell_cmd .= 'for file in ' . join(" ", @config_files) . "; do\n";
|
||||
$shell_cmd .= '[ -f $file ] && . $file; done;' . "\n";
|
||||
# Read back values
|
||||
foreach my $var (keys %config_vars) { $shell_cmd .= "echo \$$var;\n" }
|
||||
my $shell_out = `/bin/bash -c '$shell_cmd'`;
|
||||
@config_vars{ keys %config_vars } = split /\n/, $shell_out, -1;
|
||||
|
||||
# Check validity
|
||||
$config_vars{'BTS_SENDMAIL_COMMAND'} =~ /./
|
||||
or $config_vars{'BTS_SENDMAIL_COMMAND'} = '/usr/sbin/sendmail';
|
||||
|
||||
if ($config_vars{'BTS_SENDMAIL_COMMAND'} ne '/usr/sbin/sendmail') {
|
||||
my $cmd = (split ' ', $config_vars{'BTS_SENDMAIL_COMMAND'})[0];
|
||||
unless ($cmd =~ /^~?[A-Za-z0-9_\-\+\.\/]*$/) {
|
||||
warn
|
||||
"BTS_SENDMAIL_COMMAND contained funny characters: $cmd\nReverting to default value /usr/sbin/sendmail\n";
|
||||
$config_vars{'BTS_SENDMAIL_COMMAND'} = '/usr/sbin/sendmail';
|
||||
} elsif (!find_command($cmd)) {
|
||||
warn
|
||||
"BTS_SENDMAIL_COMMAND $cmd could not be executed.\nReverting to default value /usr/sbin/sendmail\n";
|
||||
$config_vars{'BTS_SENDMAIL_COMMAND'} = '/usr/sbin/sendmail';
|
||||
}
|
||||
}
|
||||
|
||||
foreach my $var (sort keys %config_vars) {
|
||||
if ($config_vars{$var} ne $config_default{$var}) {
|
||||
$modified_conf_msg .= " $var=$config_vars{$var}\n";
|
||||
}
|
||||
}
|
||||
$modified_conf_msg ||= " (none)\n";
|
||||
chomp $modified_conf_msg;
|
||||
|
||||
$sendmailcmd = $config_vars{'BTS_SENDMAIL_COMMAND'};
|
||||
}
|
||||
|
||||
sub gen_subject {
|
||||
my $subject = shift;
|
||||
my $package = shift;
|
||||
|
||||
return "$package\: $subject";
|
||||
}
|
||||
|
||||
sub gen_bug {
|
||||
my $template_text = shift;
|
||||
my $package = shift;
|
||||
my $severity = shift;
|
||||
my $tags = shift;
|
||||
my $user = shift;
|
||||
my $usertags = shift;
|
||||
my $nowrap = shift;
|
||||
my $type = shift;
|
||||
my $control = shift;
|
||||
my $include = shift;
|
||||
my $version = "";
|
||||
my $bugtext;
|
||||
|
||||
$version = $versions{$package} || "";
|
||||
|
||||
my ($epoch, $upstream, $revision)
|
||||
= ($version =~ /^(\d+:)?(.+?)(-[^-]+)?$/);
|
||||
$epoch ||= "";
|
||||
$revision ||= "";
|
||||
|
||||
if ($include) {
|
||||
my $filename = sprintf($include, $package);
|
||||
if (-r $filename) {
|
||||
open(INCLUDE, $filename) or die("Cannot open $filename: $!");
|
||||
my @lines = <INCLUDE>;
|
||||
my $text = join("", @lines);
|
||||
chomp $text;
|
||||
$template_text =~ s/#INCLUDE#/$text/g;
|
||||
close INCLUDE;
|
||||
}
|
||||
}
|
||||
$template_text =~ s/#PACKAGE#/$package/g;
|
||||
$template_text =~ s/#VERSION#/$version/g;
|
||||
$template_text =~ s/#EPOCH#/$epoch/g;
|
||||
$template_text =~ s/#UPSTREAM_VERSION#/$upstream/g;
|
||||
$template_text =~ s/#REVISION#/$revision/g;
|
||||
|
||||
$version = "Version: $version\n" if $version;
|
||||
|
||||
unless ($nowrap) {
|
||||
if ($template_text =~ /\A(.*?)(^-- $)(.*)/ms)
|
||||
{ # there's a sig involved
|
||||
my ($presig, $sig) = ($1, $2 . $3);
|
||||
$template_text = fill("", "", $presig) . "\n" . $sig;
|
||||
} else {
|
||||
$template_text = fill("", "", $template_text);
|
||||
}
|
||||
}
|
||||
if (defined $control) {
|
||||
$control = join '', map { "Control: $_\n" } @$control;
|
||||
} else {
|
||||
$control = '';
|
||||
}
|
||||
$bugtext = "$type: $package\n$version"
|
||||
. "Severity: $severity\n$tags$user$usertags$control\n$template_text";
|
||||
return $bugtext;
|
||||
}
|
||||
|
||||
sub div {
|
||||
print +("-" x 79) . "\n";
|
||||
}
|
||||
|
||||
sub mailbts {
|
||||
my ($subject, $body, $to, $from) = @_;
|
||||
|
||||
if (defined $from) {
|
||||
my $date = strftime "%a, %d %b %Y %T %z", localtime;
|
||||
|
||||
my $pid = open(MAIL, "|-");
|
||||
if (!defined $pid) {
|
||||
die "$progname: Couldn't fork: $!\n";
|
||||
}
|
||||
$SIG{'PIPE'} = sub { die "$progname: pipe for $sendmailcmd broke\n"; };
|
||||
if ($pid) {
|
||||
# parent
|
||||
print MAIL <<"EOM";
|
||||
From: $from
|
||||
To: $to
|
||||
Subject: $subject
|
||||
Date: $date
|
||||
X-Generator: mass-bug from devscripts ###VERSION###
|
||||
|
||||
$body
|
||||
EOM
|
||||
close MAIL or die "$progname: sendmail error: $!\n";
|
||||
} else {
|
||||
# child
|
||||
exec(split(' ', $sendmailcmd), "-t")
|
||||
or die "$progname: error running sendmail: $!\n";
|
||||
}
|
||||
} else { # No $from
|
||||
if (!find_command('mail')) {
|
||||
die
|
||||
"$progname: You need to either specify an email address (say using DEBEMAIL)\n or have the mailx/mailutils package installed to send mail!\n";
|
||||
}
|
||||
my $pid = open(MAIL, "|-");
|
||||
if (!defined $pid) {
|
||||
die "$progname: Couldn't fork: $!\n";
|
||||
}
|
||||
$SIG{'PIPE'} = sub { die "$progname: pipe for mail broke\n"; };
|
||||
if ($pid) {
|
||||
# parent
|
||||
print MAIL $body;
|
||||
close MAIL or die "$progname: error running mail: $!\n";
|
||||
} else {
|
||||
# child
|
||||
exec("mail", "-s", $subject, $to)
|
||||
or die "$progname: error running mail: $!\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
my $mode = "display";
|
||||
my $subject;
|
||||
my $severity = "normal";
|
||||
my $tags = "";
|
||||
my $user = "";
|
||||
my $usertags = "";
|
||||
my @control = ();
|
||||
my $type = "Package";
|
||||
my $opt_sendmail;
|
||||
my $nowrap = "";
|
||||
my $include = "";
|
||||
|
||||
if (
|
||||
!GetOptions(
|
||||
"display" => sub { $mode = "display" },
|
||||
"send" => sub { $mode = "send" },
|
||||
"subject=s" => \$subject,
|
||||
"severity=s" => \$severity,
|
||||
"tags=s" => \$tags,
|
||||
"user=s" => \$user,
|
||||
"usertags=s" => \$usertags,
|
||||
"control=s" => \@control,
|
||||
"source" => sub { $type = "Source"; },
|
||||
"sendmail=s" => \$opt_sendmail,
|
||||
"help" => sub { usage(); exit 0; },
|
||||
"version" => sub { version(); exit 0; },
|
||||
"no-wrap" => sub { $nowrap = 1; },
|
||||
'noconf|no-conf' =>
|
||||
sub { die '--noconf must come first on the command line' },
|
||||
'include=s' => \$include,
|
||||
)
|
||||
) {
|
||||
usageerror();
|
||||
}
|
||||
|
||||
if (!defined $subject || !length $subject) {
|
||||
print STDERR
|
||||
"$progname: You must specify a subject for the bug reports.\n";
|
||||
usageerror();
|
||||
}
|
||||
|
||||
unless (
|
||||
$severity =~ /^(wishlist|minor|normal|important|serious|grave|critical)$/)
|
||||
{
|
||||
print STDERR
|
||||
"$progname: Severity must be one of wishlist, minor, normal, important, serious, grave or critical.\n";
|
||||
usageerror();
|
||||
}
|
||||
|
||||
if (@ARGV != 2) {
|
||||
usageerror();
|
||||
}
|
||||
|
||||
if ($tags) {
|
||||
$tags = "Tags: $tags\n";
|
||||
}
|
||||
|
||||
if ($user) {
|
||||
$user = "User: $user\n";
|
||||
}
|
||||
|
||||
if ($usertags) {
|
||||
$usertags = "Usertags: $usertags\n";
|
||||
}
|
||||
|
||||
if ($opt_sendmail) {
|
||||
if ( $opt_sendmail ne '/usr/sbin/sendmail'
|
||||
and $opt_sendmail ne $sendmailcmd) {
|
||||
my $cmd = (split ' ', $opt_sendmail)[0];
|
||||
unless ($cmd =~ /^~?[A-Za-z0-9_\-\+\.\/]*$/) {
|
||||
warn
|
||||
"--sendmail command contained funny characters: $cmd\nReverting to default value $sendmailcmd\n";
|
||||
undef $opt_sendmail;
|
||||
} elsif (!find_command($cmd)) {
|
||||
warn
|
||||
"--sendmail command $cmd could not be executed.\nReverting to default value $sendmailcmd\n";
|
||||
undef $opt_sendmail;
|
||||
}
|
||||
}
|
||||
}
|
||||
$sendmailcmd = $opt_sendmail if $opt_sendmail;
|
||||
|
||||
my $template = shift;
|
||||
my $package_list = shift;
|
||||
|
||||
my $template_text;
|
||||
open(T, "$template") || die "$progname: error reading $template: $!\n";
|
||||
{
|
||||
local $/ = undef;
|
||||
$template_text = <T>;
|
||||
}
|
||||
close T;
|
||||
if (!length $template_text) {
|
||||
die "$progname: empty template\n";
|
||||
}
|
||||
|
||||
my @packages;
|
||||
open(L, "$package_list") || die "$progname: error reading $package_list: $!\n";
|
||||
while (<L>) {
|
||||
chomp;
|
||||
if (!/^([-+\.a-z0-9]+)(?:_(.*))?$/) {
|
||||
die "\"$_\" does not look like the name of a Debian package\n";
|
||||
}
|
||||
push @packages, $1;
|
||||
$versions{$1} = $2 if $2;
|
||||
}
|
||||
close L;
|
||||
|
||||
# Uses variables from above.
|
||||
sub showsample {
|
||||
my $package = shift;
|
||||
|
||||
print "To: $submission_email\n";
|
||||
print "Subject: " . gen_subject($subject, $package) . "\n";
|
||||
print "\n";
|
||||
print gen_bug(
|
||||
$template_text, $package, $severity, $tags, $user,
|
||||
$usertags, $nowrap, $type, \@control, $include,
|
||||
) . "\n";
|
||||
}
|
||||
|
||||
if ($mode eq 'display') {
|
||||
print "Displaying all " . scalar(@packages) . " bug reports..\n";
|
||||
print "Run again with --send switch to send the bug reports.\n";
|
||||
div();
|
||||
foreach my $package (@packages) {
|
||||
showsample($package);
|
||||
div();
|
||||
}
|
||||
} elsif ($mode eq 'send') {
|
||||
my $from;
|
||||
$from ||= $ENV{'DEBEMAIL'};
|
||||
$from ||= $ENV{'EMAIL'};
|
||||
|
||||
print "Preparing to send "
|
||||
. scalar(@packages)
|
||||
. " bug reports like this one:\n";
|
||||
div();
|
||||
showsample($packages[0]);
|
||||
div();
|
||||
$| = 1;
|
||||
print
|
||||
"Are you sure that you have read the Developer's Reference on mass-filing\nbug reports, have checked this case out on debian-devel, and really want to\nsend out these "
|
||||
. scalar(@packages)
|
||||
. " bug reports? [yes/no] ";
|
||||
my $ans = <STDIN>;
|
||||
|
||||
unless ($ans =~ /^yes$/i) {
|
||||
print "OK, aborting.\n";
|
||||
exit 0;
|
||||
}
|
||||
print "OK, going ahead then...\n";
|
||||
foreach my $package (@packages) {
|
||||
print "Sending bug for $package ...\n";
|
||||
mailbts(
|
||||
gen_subject($subject, $package),
|
||||
gen_bug(
|
||||
$template_text, $package, $severity, $tags,
|
||||
$user, $usertags, $nowrap, $type,
|
||||
\@control, $include,
|
||||
),
|
||||
$submission_email,
|
||||
$from
|
||||
);
|
||||
}
|
||||
print "All bugs sent.\n";
|
||||
}
|
||||
|
||||
=head1 COPYRIGHT
|
||||
|
||||
This program is Copyright (C) 2006 by Joey Hess <joeyh@debian.org>.
|
||||
|
||||
It is licensed under the terms of the GPL, either version 2 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
=head1 AUTHOR
|
||||
|
||||
Joey Hess <joeyh@debian.org>
|
||||
|
||||
=cut
|
Loading…
Add table
Add a link
Reference in a new issue