------------------------------------------------------------ revno: 871 committer: Debian BTS <[EMAIL PROTECTED]> branch nick: mainline timestamp: Fri 2008-09-19 00:19:15 +0000 message: merge changes from dla source tree ------------------------------------------------------------ revno: 738.1.482 committer: Don Armstrong <[EMAIL PROTECTED]> branch nick: source timestamp: Wed 2008-09-17 20:13:16 -0700 message: fixup $status typo; $dist typo handle missing logs properly ------------------------------------------------------------ revno: 738.1.481 committer: Don Armstrong <[EMAIL PROTECTED]> branch nick: source timestamp: Wed 2008-09-17 20:01:49 -0700 message: add distribution selection twiddler ------------------------------------------------------------ revno: 738.1.480 committer: Don Armstrong <[EMAIL PROTECTED]> branch nick: source timestamp: Wed 2008-09-17 20:01:14 -0700 message: * kill off empty entries which are meaningless in pkgreport.cgi * ditch some useless codebits ------------------------------------------------------------ revno: 738.1.479 committer: Don Armstrong <[EMAIL PROTECTED]> branch nick: source timestamp: Wed 2008-09-17 19:59:16 -0700 message: support search, show, stop, and daemon options in local-debbugs ------------------------------------------------------------ revno: 738.1.478 committer: Don Armstrong <[EMAIL PROTECTED]> branch nick: source timestamp: Wed 2008-09-17 19:58:31 -0700 message: fix foreach issue in makefile ------------------------------------------------------------ revno: 738.1.477 committer: Don Armstrong <[EMAIL PROTECTED]> branch nick: source timestamp: Wed 2008-09-17 19:55:51 -0700 message: * Add support for affects_distribution_tags * Properly handle the intersection of a set of distributions and the tags that are set on that distribution ------------------------------------------------------------ revno: 738.1.476 committer: Don Armstrong <[EMAIL PROTECTED]> branch nick: source timestamp: Wed 2008-09-17 09:09:25 -0700 message: * Fix and/or issue in lock_read_all_merged_bugs * Fix tiny formatting issue ------------------------------------------------------------ revno: 738.1.475 committer: Don Armstrong <[EMAIL PROTECTED]> branch nick: source timestamp: Wed 2008-09-17 09:04:04 -0700 message: * Handle when tags aren't set in usertags ------------------------------------------------------------ revno: 738.1.474 committer: Don Armstrong <[EMAIL PROTECTED]> branch nick: source timestamp: Wed 2008-09-17 09:01:08 -0700 message: * Split out a new checkpid function * If getbuglocation in getbugcomponent doesn't return a correct location, return undef ------------------------------------------------------------ revno: 738.1.473 committer: Don Armstrong <[EMAIL PROTECTED]> branch nick: source timestamp: Mon 2008-09-01 12:21:05 -0700 message: * Add missing http:// to bugreport.tmplCC ------------------------------------------------------------ revno: 738.1.472 committer: Don Armstrong <[EMAIL PROTECTED]> branch nick: source timestamp: Mon 2008-08-25 17:31:09 -0700 message: switch to inline by default for extra status span elements ------------------------------------------------------------ revno: 738.1.471 committer: Don Armstrong <[EMAIL PROTECTED]> branch nick: source timestamp: Sun 2008-08-17 10:39:19 -0700 message: * future directions updated slightly ------------------------------------------------------------ revno: 738.1.470 committer: Don Armstrong <[EMAIL PROTECTED]> branch nick: source timestamp: Sun 2008-08-17 10:35:08 -0700 message: * Implement select and local mirror bits in local-debbugs ------------------------------------------------------------ revno: 738.1.469 committer: Don Armstrong <[EMAIL PROTECTED]> branch nick: source timestamp: Sat 2008-08-16 13:09:19 -0700 message: add forwarded information; update bzr ignore ------------------------------------------------------------ revno: 738.1.468 committer: Don Armstrong <[EMAIL PROTECTED]> branch nick: source timestamp: Sat 2008-08-16 13:09:00 -0700 message: split out debbugs-local; fix install files ------------------------------------------------------------ revno: 738.1.467 committer: Don Armstrong <[EMAIL PROTECTED]> branch nick: source timestamp: Sat 2008-08-16 12:26:50 -0700 message: remove the html files from the debbugs package ------------------------------------------------------------ revno: 738.1.466 committer: Don Armstrong <[EMAIL PROTECTED]> branch nick: source timestamp: Sat 2008-08-16 12:20:02 -0700 message: switch from htmllog to use append_action_to_log in process ------------------------------------------------------------ revno: 738.1.465 committer: Don Armstrong <[EMAIL PROTECTED]> branch nick: source timestamp: Sat 2008-08-16 12:18:44 -0700 message: install local-debbugs and add_bug_to_estraier; add local-debbugs ------------------------------------------------------------ revno: 738.1.464 committer: Don Armstrong <[EMAIL PROTECTED]> branch nick: source timestamp: Sat 2008-08-16 12:17:57 -0700 message: fix the makefile to install the perl bits correctly; don't make the db-h spool directories ------------------------------------------------------------ revno: 738.1.463 committer: Don Armstrong <[EMAIL PROTECTED]> branch nick: source timestamp: Sat 2008-08-16 12:17:13 -0700 message: pass maybelink to bugreport.cgi templates ------------------------------------------------------------ revno: 738.1.462 committer: Don Armstrong <[EMAIL PROTECTED]> branch nick: source timestamp: Sat 2008-08-16 12:16:42 -0700 message: generalize append_to_log ------------------------------------------------------------ revno: 738.1.461 committer: Don Armstrong <[EMAIL PROTECTED]> branch nick: source timestamp: Sat 2008-08-16 12:15:31 -0700 message: remove useless bits from Debbugs::CGI::Pkgreport.pm ------------------------------------------------------------ revno: 738.1.460 committer: Don Armstrong <[EMAIL PROTECTED]> branch nick: source timestamp: Fri 2008-08-15 15:01:37 -0700 message: move bugs-fetch ------------------------------------------------------------ revno: 738.1.459 committer: Don Armstrong <[EMAIL PROTECTED]> branch nick: source timestamp: Fri 2008-08-15 07:04:26 -0700 message: * add missing > to </em> [thanks to jamessan] ------------------------------------------------------------ revno: 738.1.458 committer: Don Armstrong <[EMAIL PROTECTED]> branch nick: source timestamp: Thu 2008-08-14 11:34:59 -0700 message: * $param{log} should be $param{message} instead
=== added file '.bzrignore' --- .bzrignore 1970-01-01 00:00:00 +0000 +++ .bzrignore 2008-09-19 00:19:01 +0000 @@ -0,0 +1,4 @@ +Makefile.perl +Makefile.perl.old +build-stamp +install-stamp
=== modified file 'Debbugs/CGI/Pkgreport.pm' --- Debbugs/CGI/Pkgreport.pm 2008-08-10 15:47:57 +0000 +++ Debbugs/CGI/Pkgreport.pm 2008-09-19 00:19:01 +0000 @@ -254,119 +254,6 @@ '&maybelink' => \&Debbugs::CGI::maybelink, }, ); - - my $result = ""; - - my $showseverity; - if ($status{severity} eq 'normal') { - $showseverity = ''; - } - elsif (isstrongseverity($status{severity})) { - $showseverity = "Severity: <em class=\"severity\">$status{severity}</em>;\n"; - } - else { - $showseverity = "Severity: <em>$status{severity}</em>;\n"; - } - - $result .= package_links(package => $status{package}, - options => $param{options}, - ); - - my $showversions = ''; - if (@{$status{found_versions}}) { - my @found = @{$status{found_versions}}; - $showversions .= join ', ', map {s{/}{ }; html_escape($_)} @found; - } - if (@{$status{fixed_versions}}) { - $showversions .= '; ' if length $showversions; - $showversions .= '<strong>fixed</strong>: '; - my @fixed = @{$status{fixed_versions}}; - $showversions .= join ', ', map {s{/}{ }; html_escape($_)} @fixed; - } - $result .= ' (<a href="'. - version_url(package => $status{package}, - found => $status{found_versions}, - fixed => $status{fixed_versions}, - ).qq{">$showversions</a>)} if length $showversions; - $result .= ";\n"; - - $result .= $showseverity; - $result .= "Reported by: ".package_links(submitter=>$status{originator}, - class => "submitter", - ); - $result .= ";\nOwned by: " . package_links(owner => $status{owner}, - class => "submitter", - ) - if length $status{owner}; - $result .= ";\nTags: <strong>" - . html_escape(join(", ", sort(split(/\s+/, $status{tags})))) - . "</strong>" - if (length($status{tags})); - - $result .= (length($status{mergedwith})?";\nMerged with ":"") . - bug_links(bug => [split(/ /,$status{mergedwith})], - class => "submitter", - ); - $result .= (length($status{blockedby})?";\nBlocked by ":"") . - bug_links(bug => [split(/ /,$status{blockedby})], - class => "submitter", - ); - $result .= (length($status{blocks})?";\nBlocks ":"") . - bug_links(bug => [split(/ /,$status{blocks})], - class => "submitter", - ); - - if (length($status{done})) { - $result .= "<br><strong>Done:</strong> " . html_escape($status{done}); - my $days = bug_archiveable(bug => $status{id}, - status => \%status, - days_until => 1, - ); - if ($days >= 0 and defined $status{location} and $status{location} ne 'archive') { - $result .= ";\n<strong>Can be archived" . ( $days == 0 ? " today" : $days == 1 ? " in $days day" : " in $days days" ) . "</strong>"; - } - elsif (defined $status{location} and $status{location} eq 'archived') { - $result .= ";\n<strong>Archived.</strong>"; - } - } - - unless (length($status{done})) { - if (length($status{forwarded})) { - $result .= ";\n<strong>Forwarded</strong> to " - . join(', ', - map {maybelink($_)} - split /\,\s+/,$status{forwarded} - ); - } - # Check the age of the logfile - my ($days_last,$eng_last) = secs_to_english(time - $status{log_modified}); - my ($days,$eng) = secs_to_english(time - $status{date}); - - if ($days >= 7) { - my $font = ""; - my $efont = ""; - $font = "em" if ($days > 30); - $font = "strong" if ($days > 60); - $efont = "</$font>" if ($font); - $font = "<$font>" if ($font); - - $result .= ";\n ${font}$eng old$efont"; - } - if ($days_last > 7) { - my $font = ""; - my $efont = ""; - $font = "em" if ($days_last > 30); - $font = "strong" if ($days_last > 60); - $efont = "</$font>" if ($font); - $font = "<$font>" if ($font); - - $result .= ";\n ${font}Modified $eng_last ago$efont"; - } - } - - $result .= "."; - - return $result; } === modified file 'Debbugs/Common.pm' --- Debbugs/Common.pm 2008-08-10 00:27:16 +0000 +++ Debbugs/Common.pm 2008-09-19 00:19:01 +0000 @@ -43,7 +43,7 @@ qw(getmaintainers_reverse), qw(getpseudodesc), ], - misc => [qw(make_list globify_scalar english_join)], + misc => [qw(make_list globify_scalar english_join checkpid)], date => [qw(secs_to_english)], quit => [qw(quit)], lock => [qw(filelock unfilelock lockpid)], @@ -417,15 +417,9 @@ sub lockpid { my ($pidfile) = @_; if (-e $pidfile) { - my $pidfh = IO::File->new($pidfile, 'r') or - die "Unable to open pidfile $pidfile: $!"; - local $/; - my $pid = <$pidfh>; - ($pid) = $pid =~ /(\d+)/; - if (defined $pid and kill(0,$pid)) { - return 0; - } - close $pidfh; + my $pid = checkpid($pidfile); + die "Unable to read pidfile $pidfile: $!" if not defined $pid; + return 0 if $pid != 0; unlink $pidfile or die "Unable to unlink stale pidfile $pidfile $!"; } @@ -436,6 +430,35 @@ return 1; } +=head2 checkpid + + checkpid('/path/to/pidfile'); + +Checks a pid file and determines if the process listed in the pidfile +is still running. Returns the pid if it is, 0 if it isn't running, and +undef if the pidfile doesn't exist or cannot be read. + +=cut + +sub checkpid{ + my ($pidfile) = @_; + if (-e $pidfile) { + my $pidfh = IO::File->new($pidfile, 'r') or + return undef; + local $/; + my $pid = <$pidfh>; + close $pidfh; + ($pid) = $pid =~ /(\d+)/; + if (defined $pid and kill(0,$pid)) { + return $pid; + } + return 0; + } + else { + return undef; + } +} + =head1 QUIT === modified file 'Debbugs/Config.pm' --- Debbugs/Config.pm 2008-08-07 19:36:24 +0000 +++ Debbugs/Config.pm 2008-09-19 00:19:01 +0000 @@ -417,6 +417,25 @@ [qw(i386 amd64 arm powerpc sparc alpha)] ); +=item affects_distribution_tags + +List of tags which restrict the buggy state to a set of distributions. + +The set of distributions that are buggy is the intersection of the set +of distributions that would be buggy without reference to these tags +and the set of these tags that are distributions which are set on a +bug. + +Setting this to [] will remove this feature. + +Default: @{$config{distributions}} + +=cut + +set_default(\%config,'affects_distribution_tags', + [EMAIL PROTECTED], + ); + =item removal_unremovable_tags Bugs which have these tags set cannot be archived @@ -585,7 +604,10 @@ set_default(\%config,'severity_display',{critical => "Critical $config{bugs}", grave => "Grave $config{bugs}", + serious => "Serious $config{bugs}", + important=> "Important $config{bugs}", normal => "Normal $config{bugs}", + minor => "Minor $config{bugs}", wishlist => "Wishlist $config{bugs}", }); === modified file 'Debbugs/Control.pm' --- Debbugs/Control.pm 2008-08-12 18:40:59 +0000 +++ Debbugs/Control.pm 2008-09-19 00:19:01 +0000 @@ -447,7 +447,7 @@ my $log = []; my @records = Debbugs::Log::read_log_records(bug_num => $param{bug}); if ($param{summary} == 0) { - $log = $param{log}; + $log = $param{message}; $summary_msg = @records + 1; } else { @@ -895,14 +895,20 @@ action => {type => SCALAR, }, requester => {type => SCALAR, + default => '', }, request_addr => {type => SCALAR, + default => '', }, location => {type => SCALAR, optional => 1, }, message => {type => SCALAR|ARRAYREF, + default => '', }, + desc => {type => SCALAR, + default => '', + }, get_lock => {type => BOOLEAN, default => 1, }, @@ -917,17 +923,30 @@ } my $log = IO::File->new(">>$log_location") or die "Unable to open $log_location for appending: $!"; - print {$log} "\6\n". + my $msg = "\6\n". "<!-- time:".time." -->\n". - "<strong>".html_escape($param{action})."</strong>\n". - "Request was from <code>".html_escape($param{requester})."</code>\n". - "to <code>".html_escape($param{request_addr})."</code>. \n". - "\3\n". - "\7\n",escape_log(make_list($param{message})),"\n\3\n" + "<strong>".html_escape($param{action})."</strong>\n"; + if (length $param{requester}) { + $msg .= "Request was from <code>".html_escape($param{requester})."</code>\n"; + } + if (length $param{request_addr}) { + $msg .= "to <code>".html_escape($param{request_addr})."</code>"; + } + if (length $param{desc}) { + $msg .= ":<br>\n$param{desc}\n"; + } + else { + $msg .= ".\n"; + } + $msg .= "\3\n"; + if ((ref($param{message}) and @{$param{message}}) or length($param{message})) { + $msg .= "\7\n".join('',escape_log(make_list($param{message})))."\n\3\n" or die "Unable to append to $log_location: $!"; + } + print {$log} $msg or die "Unable to append to $log_location: $!"; close $log or die "Unable to close $log_location: $!"; if ($param{get_lock}) { - unlockfile(); + unfilelock(); } === modified file 'Debbugs/Status.pm' --- Debbugs/Status.pm 2008-08-10 19:41:01 +0000 +++ Debbugs/Status.pm 2008-09-19 00:19:01 +0000 @@ -183,6 +183,7 @@ $status = getbugcomponent($lref, 'summary', $location); $log = getbugcomponent($lref, 'log' , $location); return undef unless defined $status; + return undef if not -e $status; } else { $status = $param{summary}; @@ -323,7 +324,7 @@ my ($bug_num,$location) = @_; my $locks = 0; my @data = (lockreadbug(@_)); - if (not @data and not defined $data[0]) { + if (not @data or not defined $data[0]) { return ($locks,undef); } $locks++; @@ -335,7 +336,7 @@ filelock("$config{spool_dir}/lock/merge"); $locks++; @data = (lockreadbug(@_)); - if (not @data and not defined $data[0]) { + if (not @data or not defined $data[0]) { unfilelock(); #for merge lock above $locks--; return ($locks,undef); @@ -1069,12 +1070,33 @@ } } } elsif (defined $param{dist}) { + my %affects_distribution_tags; + @[EMAIL PROTECTED] = + (1) x @{$config{affects_distribution_tags}}; + my $some_distributions_disallowed = 0; + my %allowed_distributions; + for my $tag (split ' ', ($status{tags}||'')) { + if (exists $affects_distribution_tags{$tag}) { + $some_distributions_disallowed = 1; + $allowed_distributions{$tag} = 1; + } + } foreach my $arch (make_list($param{arch})) { - my @versions; for my $package (split /\s*,\s*/, $status{package}) { + my @versions; foreach my $dist (make_list($param{dist})) { + # if some distributions are disallowed, + # and this isn't an allowed + # distribution, then we ignore this + # distribution for the purposees of + # finding versions + if ($some_distributions_disallowed and + not exists $allowed_distributions{$dist}) { + next; + } push @versions, getversions($package, $dist, $arch); } + next unless @versions; my @temp = makesourceversions($package, $arch, @versions @@ -1095,12 +1117,12 @@ my $maxbuggy = 'undef'; if (@sourceversions) { $maxbuggy = max_buggy(bug => $param{bug}, - sourceversions => [EMAIL PROTECTED], - found => $status{found_versions}, - fixed => $status{fixed_versions}, - package => $status{package}, - version_cache => $version_cache, - ); + sourceversions => [EMAIL PROTECTED], + found => $status{found_versions}, + fixed => $status{fixed_versions}, + package => $status{package}, + version_cache => $version_cache, + ); } elsif (defined $param{dist} and not exists $pseudo_desc->{$status{package}}) { === modified file 'Makefile' --- Makefile 2008-05-24 12:54:57 +0000 +++ Makefile 2008-09-19 00:19:01 +0000 @@ -12,7 +12,7 @@ man8_dir := $(man_dir)/man8 examples_dir := $(doc_dir)/examples -scripts_in := $(filter-out scripts/config scripts/errorlib scripts/text, $(wildcard scripts/*)) +scripts_in := $(foreach script, $(filter-out scripts/config scripts/errorlib scripts/text, $(wildcard scripts/*)),$(patsubst scripts/%,%,$(script))) htmls_in := $(wildcard html/*.html.in) cgis := $(wildcard cgi/*.cgi cgi/*.pl) @@ -38,17 +38,17 @@ for dir in $(sbin_dir) $(etc_dir)/html $(etc_dir)/indices \ $(var_dir)/indices $(var_dir)/www/cgi $(var_dir)/www/db $(var_dir)/www/txt \ $(var_dir)/spool/lock $(var_dir)/spool/archive $(var_dir)/spool/incoming \ -$(var_dir)/spool/db-h $(scripts_dir) $(perl_dir) $(examples_dir) $(man8_dir); \ +$(var_dir)/spool/db-h $(scripts_dir) $(examples_dir) $(man8_dir); \ do test -d $$dir || $(install_exec) -d $$dir; done - +# we shouldn't ship db-h spool directories # make db-h spool dirs if they don't exist - cd $(var_dir)/spool/db-h; \ - for dir in $(shell seq -w 00 99); \ - do test -d $$dir || $(install_exec) -d $$dir; done +# cd $(var_dir)/spool/db-h; \ +# for dir in $(shell seq -w 00 99); \ +# do test -d $$dir || $(install_exec) -d $$dir; done # install the scripts - $(foreach script,$(scripts_in), $(install_exec) $(script) $(scripts_dir)/$(script);) + $(foreach script,$(scripts_in), $(exec $(install_exec) $(script) $(scripts_dir)/$(script))) $(install_data) scripts/errorlib $(scripts_dir)/errorlib # install examples @@ -86,8 +86,8 @@ $(install_data) misc/updateseqs $(var_dir)/spool # install the templates - $(foreach dir $(wildcard templates/*/*) $(install_exec) $(template_dir)/$(patsubst templates/%,%,$(dir))) - $(foreach tmpl $(wildcard templates/*/*/*.tmpl) $(install_data) $(template_dir)/$(patsubst templates/%,%,$(tmpl))) + $(foreach dir, $(wildcard templates/*/*), $(exec -d $(install_exec) $(template_dir)/$(patsubst templates/%,%,$(dir)))) + $(foreach tmpl, $(wildcard templates/*/*/*.tmpl), $(exec $(install_data) $(tmpl) $(template_dir)/$(patsubst templates/%,%,$(tmpl)))) .PHONY: test \ No newline at end of file === modified file 'Makefile.PL' --- Makefile.PL 2007-06-13 21:28:46 +0000 +++ Makefile.PL 2008-09-19 00:19:01 +0000 @@ -4,6 +4,9 @@ WriteMakefile(FIRST_MAKEFILE => 'Makefile.perl', PMLIBDIRS => ['Debbugs'], + EXE_FILES => ['bin/local-debbugs', + 'bin/add_bug_to_estraier', + ], NAME => 'Debbugs', VERSION => '2.4.2', ); === added file 'bin/local-debbugs' --- bin/local-debbugs 1970-01-01 00:00:00 +0000 +++ bin/local-debbugs 2008-09-19 00:19:01 +0000 @@ -0,0 +1,511 @@ +#! /usr/bin/perl +# local-debbugs is part of debbugs, and is released +# under the terms of the GPL version 2, or any later version, at your +# option. See the file README and COPYING for more information. +# Copyright 2008 by Don Armstrong <[EMAIL PROTECTED]>. + + +use warnings; +use strict; + +use Getopt::Long; +use Pod::Usage; + +=head1 NAME + +local-debbugs - use a local mirror of debbugs + +=head1 SYNOPSIS + + [options] + + Options: + --mirror, -M update local mirror + --daemon, -D start the daemon + --search, -S run a search + --show, -s show a bug + --debug, -d debugging level (Default 0) + --help, -h display this help + --man, -m display manual + +=head1 OPTIONS + +=over + +=item B<--mirror, -M> + +Update the local mirror of debbugs bugs + +=item B<--daemon, -D> + +Start up the daemon on the configured local port to serve bugs which +have been previously retried + +=item B<--search, -S> + +Cause the running daemon to show the pkgreport.cgi page corresponding +to the search by invoking sensible-browser and an appropriate url + +=item B<--show, -s> + +Cause the running daemon to show the bugreport.cgi page corresponding +to the bug by invoking sensible-browser and an appropriate url + +=item B<--port,-p> + +The port that the daemon is running on (or will be running on.) + +Defaults to the value of the currently running daemon, the value in +the configuration file, or 8080 if nothing is set. + +=item B<--bugs-to-get> + +File which contains the set of bugs to get. +Defaults to ~/.debbugs/bugs_to_get + +=item B<--debug, -d> + +Debug verbosity. (Default 0) + +=item B<--help, -h> + +Display brief useage information. + +=item B<--man, -m> + +Display this manual. + +=back + +=head1 EXAMPLES + + +=cut + + +use vars qw($DEBUG); + +use User; +use Config::Simple; +use File::Temp qw(tempdir); +use Params::Validate qw(validate_with :types); +use POSIX 'setsid'; +use Debbugs::Common qw(checkpid lockpid); + +my %options = (debug => 0, + help => 0, + man => 0, + verbose => 0, + quiet => 0, + detach => 1, + cgi_bin => '/var/lib/debbugs/www/cgi-bin', + css => '/var/lib/debbugs/www/bugs.css', + ); + +my %option_defaults = (port => 8080, + debbugs_config => User->Home.'/.debbugs/debbugs_config', + mirror_location => User->Home.'/.debbugs/mirror/', + bugs_to_get => User->Home.'/.debbugs/bugs_to_get', + ); + +GetOptions(\%options, + 'daemon|D','show|s','search|select|S','mirror|M', 'stop', + 'detach!', + 'css=s','cgi_bin|cgi-bin|cgi=s', + 'verbose|v+','quiet|q+', + 'debug|d+','help|h|?','man|m'); + +pod2usage() if $options{help}; +pod2usage({verbose=>2}) if $options{man}; + +$DEBUG = $options{debug}; + +my @USAGE_ERRORS; +if (1 != grep {exists $options{$_}} qw(daemon show search mirror stop)) { + push @USAGE_ERRORS,"You must pass one (and only one) of --daemon --show --search or --mirror"; +} +$options{verbose} = $options{verbose} - $options{quiet}; + +pod2usage(join("\n",@USAGE_ERRORS)) if @USAGE_ERRORS; + + +# munge in local configuration + +local_config(\%options); + +if ($options{daemon}) { + # daemonize, do stuff + my $pid = checkpid($options{mirror_location}.'/local-debbugs.pid'); + if (defined $pid and $pid != 0) { + print STDERR "Unable to start daemon; it's already running\n"; + exit 1; + } + if (-e $options{mirror_location}.'/local-debbugs.pid' and + not defined $pid) { + print STDERR "Unable to determine if daemon is running: $!\n"; + exit 1; + } + # ok, now lets daemonize + + # XXX make sure that all paths have been turned into absolute + # paths + chdir '/' or die "Can't chdir to /: $!"; + # allow us not to detach for debugging + if ($options{detach}) { + open STDIN, '/dev/null' or die "Can't read /dev/null: $!"; + open STDOUT, '>/dev/null' + or die "Can't write to /dev/null: $!"; + defined(my $pid = fork) or die "Can't fork: $!"; + exit if $pid; + setsid or die "Can't start a new session: $!"; + open STDERR, '>&STDOUT' or die "Can't dup stdout: $!"; + } + lockpid($options{mirror_location}.'/local-debbugs.pid') or + die "Unable to deal with the pidfile"; + # this is the subclass of HTTP::Server::Simple::CGI which handles + # the "hard" bits of actually running a tiny webserver for us + { + package local_debbugs::server; + use IO::File; + use HTTP::Server::Simple; + use base qw(HTTP::Server::Simple::CGI); + + sub net_server { + return 'Net::Server::Fork'; + } + + sub redirect { + my ($cgi,$url) = @_; + print "HTTP/1.1 302 Found\r\n"; + print "Location: $url\r\n"; + } + + # here we want to call cgi-bin/pkgreport or cgi-bin/bugreport + sub handle_request { + my ($self,$cgi) = @_; + + my $base_uri = 'http://'.$cgi->virtual_host; + if ($cgi->virtual_port ne 80) { + $base_uri .= ':'.$cgi->virtual_port; + } + my $path = $cgi->path_info(); + # RewriteRule ^/[[:space:]]*#?([[:digit:]][[:digit:]][[:digit:]]+)([;&].+)?$ /cgi-bin/bugreport.cgi?bug=$1$2 [L,R,NE] + if ($path =~ m{^/?\s*\#?(\d+)((?:[;&].+)?)$}) { + redirect($cgi,$base_uri."/cgi-bin/bugreport.cgi?bug=$1$2"); + } + # RewriteRule ^/[Ff][Rr][Oo][Mm]:([^/[EMAIL PROTECTED])$ /cgi-bin/pkgreport.cgi?submitter=$1 [L,R,NE] + elsif ($path =~ m{^/?\s*from:([^/[EMAIL PROTECTED])$}i) { + redirect($cgi,$base_uri."/cgi-bin/pkgreport.cgi?submitter=$1"); + } + # RewriteRule ^/([^/[EMAIL PROTECTED])$ /cgi-bin/pkgreport.cgi?maint=$1 [L,R,NE] + elsif ($path =~ m{^/?\s*([^/[EMAIL PROTECTED])$}i) { + redirect($cgi,$base_uri."/cgi-bin/pkgreport.cgi?maint=$1"); + } + # RewriteRule ^/mbox:([[:digit:]][[:digit:]][[:digit:]]+)([;&].+)?$ /cgi-bin/bugreport.cgi?mbox=yes&bug=$1$2 [L,R,NE] + elsif ($path =~ m{^/?\s*mbox:\#?(\d+)((?:[;&].+)?)$}i) { + redirect($cgi,$base_uri."/cgi-bin/bugreport.cgi?mbox=yes;bug=$1$2"); + } + # RewriteRule ^/src:([^/]+)$ /cgi-bin/pkgreport.cgi?src=$1 [L,R,NE] + elsif ($path =~ m{^/?src:([^/]+)$}i) { + redirect($cgi,$base_uri."/cgi-bin/pkgreport.cgi?src=$1"); + } + # RewriteRule ^/severity:([^/]+)$ /cgi-bin/pkgreport.cgi?severity=$1 [L,R,NE] + elsif ($path =~ m{^/?severity:([^/]+)$}i) { + redirect($cgi,$base_uri."/cgi-bin/pkgreport.cgi?severity=$1"); + } + # RewriteRule ^/tag:([^/]+)$ /cgi-bin/pkgreport.cgi?tag=$1 [L,R,NE] + elsif ($path =~ m{^/?tag:([^/]+)$}i) { + redirect($cgi,$base_uri."/cgi-bin/pkgreport.cgi?tag=$1"); + } + # RewriteRule ^/([^/]+)$ /cgi-bin/pkgreport.cgi?pkg=$1 [L,R,NE] + elsif ($path =~ m{^/?([^/]+)$}i) { + redirect($cgi,$base_uri."/cgi-bin/pkgreport.cgi?pkg=$1"); + } + elsif ($path =~ m{^/?cgi(?:-bin)?/((?:(?:bug|pkg)report|version)\.cgi)}) { + # dispatch to pkgreport.cgi + print "HTTP/1.1 200 OK\n"; + exec("$options{cgi_bin}/$1") or + die "Unable to execute $options{cgi_bin}/$1"; + } + elsif ($path =~ m{^/?css/bugs.css}) { + my $fh = IO::File->new($options{css},'r') or + die "Unable to open $options{css} for reading: $!"; + print "HTTP/1.1 200 OK\n"; + print "Content-type: text/css\n"; + print "\n"; + print <$fh>; + } + elsif ($path =~ m{^/?$}) { + redirect($cgi,$base_uri."/cgi-bin/pkgreport.cgi?package=put%20package%20here"); + } + else { + print "HTTP/1.1 404 Not Found\n"; + print "Content-Type: text/html\n"; + print "\n"; + print "<h1>That which you were seeking, found I have not.</h1>\n"; + } + # RewriteRule ^/$ /Bugs/ [L,R,NE] + } + } + my $debbugs_server = local_debbugs::server->new($options{port}) or + die "Unable to create debbugs server"; + $debbugs_server->run() or + die 'Unable to run debbugs server'; +} +elsif ($options{stop}) { + # stop the daemon + my $pid = checkpid($options{mirror_location}.'/local-debbugs.pid'); + if (not defined $pid or $pid == 0) { + print STDERR "Unable to open pidfile or daemon not running: $!\n"; + exit 1; + } + exit !(kill(15,$pid) == 1); +} +elsif ($options{mirror}) { + # run the mirror jobies + # figure out which bugs we need + my @bugs = select_bugs(\%options); + # get them + my $tempdir = tempdir(CLEANUP => 1); + my $mirror_log = IO::File->new($options{mirror_location}.'/mirror.log') or + die "Unable to open $options{mirror_location}/mirror.log for writing: $!"; + my $inc_fh = IO::File->new("$tempdir/include_list",'w') or + die "Unable to open $tempdir/include_list for writing: $!"; + foreach my $bug (@bugs) { + print {$inc_fh} "*/${bug}.*\n" or + die "Unable to write to $tempdir/include_list: $!"; + } + close $inc_fh or + die "Unable to close $tempdir/include_list: $!"; + my ($wrf,$rfh); + my @common_rsync_options = ('-avz','--partial'); + print "Rsyncing bugs\n" if not $options{quiet}; + run_rsync(log => $mirror_log, + ($options{debug}?(debug => \*STDERR):()), + options => [EMAIL PROTECTED], + '--delete-after', + '--include-from',"$tempdir/include_list", + # skip things not specifically included + '--exclude','*/*', + # skip the -1,-2,-3.log files + '--exclude','*.log', + 'rsync://'.$options{bug_mirror}.'/bts-spool-db/', + $options{mirror_location}.'/db-h/'] + ); + print "Rsyncing archived bugs\n" if $options{verbose}; + run_rsync(log => $mirror_log, + ($options{debug}?(debug => \*STDERR):()), + options => [EMAIL PROTECTED], + '--delete-after', + '--include-from',"$tempdir/include_list", + # skip things not specifically included + '--exclude','*/*', + # skip the -1,-2,-3.log files + '--exclude','*.log', + 'rsync://'.$options{bug_mirror}.'/bts-spool-archive/', + $options{mirror_location}.'/archive/', + ], + ); + print "Rsyncing indexes\n" if $options{verbose}; + run_rsync(log => $mirror_log, + ($options{debug}?(debug => \*STDERR):()), + options => [EMAIL PROTECTED], + '--exclude','*old', + '--exclude','*.bak', + '--exclude','by-reverse*', + 'rsync://'.$options{bug_mirror}.'/bts-spool-index/', + $options{mirror_location}.'/', + ], + ); + print "Rsyncing versions\n" if $options{verbose}; + run_rsync(log => $mirror_log, + ($options{debug}?(debug => \*STDERR):()), + options => [EMAIL PROTECTED], + '--delete-after', + '--exclude','*old', + '--exclude','*.bak', + 'rsync://'.$options{bug_mirror}.'/bts-spool-versions/', + $options{mirror_location}.'/versions/', + ], + ); +} +elsif ($options{show}) { + # figure out the url + # see if the daemon is running + my $pid = checkpid($options{mirror_location}.'/local-debbugs.pid'); + if (not defined $pid or $pid == 0) { + print STDERR "Unable to open pidfile or daemon not running: $!\n"; + print STDERR qq(Mr. T: "I pity da fool who tries to show a bug without a running daemon"\n); + print STDERR "Hint: try the --daemon option first\n"; + exit 1; + } + # twist and shout + my $url = qq(http://localhost:$options{port}/$ARGV[0]); + exec('/usr/bin/sensible-browser',$url) or + die "Unable to run sensible-browser (try feeding me cheetos?)"; +} +elsif ($options{search}) { + my $url = qq(http://localhost:$options{port}/cgi-bin/pkgreport.cgi?). + join(';',map {if (/:/) {s/:/=/; $_;} else {qq(pkg=$_);}} @ARGV); + my $pid = checkpid($options{mirror_location}.'/local-debbugs.pid'); + if (not defined $pid or $pid == 0) { + print STDERR "Unable to open pidfile or daemon not running: $!\n"; + print STDERR qq(Mr. T: "I pity da fool who tries to show a bug without a running daemon"\n); + print STDERR "Hint: try the --daemon option first\n"; + exit 1; + } + # twist and shout + exec('/usr/bin/sensible-browser',$url) or + die "Unable to run sensible-browser (Maybe chorizo is required?)"; +} +else { + # you get here, you were an idiot in checking for @USAGE_ERRORS + # above + die "No option that we understand was passed (the first check for this is now buggy, so shoot your maintainer)" +} + + +# determine the local configuration +sub local_config{ + my ($options) = @_; + my $config = {}; + if (-e '/etc/debbugs/local_debbugs.conf') { + Config::Simple->import_from('/etc/debbugs/local_debbugs.conf', $config) or + die "Unable to read configuration from /etc/debbugs/local_debbugs.conf: $!"; + } + if (-e User->Home.'/.debbugs/local_debbugs.conf') { + Config::Simple->import_from(User->Home.'/.debbugs/local_debbugs.conf', $config) or + die "Unable to read configuration from ".User->Home.'/.debbugs/local_debbugs.conf: '.$!; + } + for (keys %option_defaults) { + if (exists $config->{$_} and not defined $options->{$_}) { + $options->{$_} = $config->{$_}; + } + if (not defined $options->{$_}) { + $options->{$_} = $option_defaults{$_}; + } + } +} + +# actually run rsync with the passed options +sub run_rsync{ + my %param = validate_with(params => [EMAIL PROTECTED], + spec => {log => {type => HANDLE, + }, + debug => {type => HANDLE, + optional => 1, + }, + options => {type => ARRAYREF, + }, + } + ); + my ($output_fh,@rsync_options) = @_; + my ($wfh,$rfh); + my $pid = open3($wfh,$rfh, + 'rsync', + @{$param{options}} + ) or die "Unable to start rsync: $!"; + close $wfh or die "Unable to close the writer filehandle $?"; + while (<$rfh>) { + print {$param{log}} $_; + if (exists $param{debug}) { + print {$param{debug}} $_; + } + } +} + + + +# select a set of bugs +sub select_bugs{ + my ($options) = @_; + + my %valid_keys = (package => 'package', + pkg => 'package', + src => 'src', + source => 'src', + maint => 'maint', + maintainer => 'maint', + submitter => 'submitter', + from => 'submitter', + status => 'status', + tag => 'tag', + tags => 'tag', + usertag => 'tag', + usertags => 'tag', + owner => 'owner', + dist => 'dist', + distribution => 'dist', + bugs => 'bugs', + archive => 'archive', + severity => 'severity', + correspondent => 'correspondent', + affects => 'affects', + ); + + my $soap = SOAP::Lite + -> uri('Debbugs/SOAP/V1') + -> proxy("http://$options{bug_mirror}/cgi-bin/soap.cgi"); + my @bugs; + my @bug_selections = (); + if (not -e $options{bugs_to_get}) { + my ($addr) = get_addresses(exists $ENV{DEBEMAIL}? + $ENV{DEBEMAIL} : + (User->Login . '@' . qx(hostname --fqdn))); + # by default include bugs talked to by this user packages + # maintained by this user, submitted by this user, and rc + # bugs + push @bug_selections, + ("correspondent:$addr archive:both", + "maint:$addr archive:both", + "submitter:$addr archive:both", + "severity:serious severity:grave severity:critical archive:both", + ); + } + else { + my $btg_fh = IO::File->new($options{bugs_to_get},'r') or + die "unable to open bugs to get file '$options{bugs_to_get}' for reading: $!"; + while (<$btg_fh>) { + chomp; + next if /^\s*#/; + if (/^\d+$/) { + push @bugs,$_; + } + elsif (/\s\w+\:/) { + push @bug_selections, $_; + } + } + } + for my $selection (@bug_selections) { + my @subselects = split /\s+/,$selection; + my %search_parameters; + my %users; + for my $subselect (@subselects) { + my ($key,$value) = split /:/, $subselect, 2; + next unless $key; + if (exists $valid_keys{$key}) { + push @{$search_parameters{$valid_keys{$key}}}, + $value if $value; + } elsif ($key =~/users?$/) { + $users{$value} = 1 if $value; + } + } + my %usertags; + for my $user (keys %users) { + my $ut = $soap->get_usertag($user)->result(); + next unless defined $ut and $ut ne ""; + for my $tag (keys %{$ut}) { + push @{$usertags{$tag}}, + @{$ut->{$tag}}; + } + } + my $bugs = $soap->get_bugs(%search_parameters, + (keys %usertags)?(usertags=>\%usertags):() + )->result(); + push @bugs,@{$bugs} if defined $bugs and @{$bugs}; + } + return @bugs; +} + + +__END__ === modified file 'cgi/bugreport.cgi' --- cgi/bugreport.cgi 2008-08-05 15:29:53 +0000 +++ cgi/bugreport.cgi 2008-09-19 00:19:01 +0000 @@ -324,5 +324,6 @@ '&version_url' => \&Debbugs::CGI::version_url, '&bug_url' => \&Debbugs::CGI::bug_url, '&strftime' => \&POSIX::strftime, - } + '&maybelink' => \&Debbugs::CGI::maybelink, + }, ); === renamed file 'cgi/bugs-fetch2.pl.in' => 'cgi/bugs-fetch2.pl' === modified file 'cgi/pkgreport.cgi' --- cgi/pkgreport.cgi 2008-08-09 18:55:08 +0000 +++ cgi/pkgreport.cgi 2008-09-19 00:19:01 +0000 @@ -77,6 +77,11 @@ next unless exists $param{$incexc}; $param{$incexc} = [grep /\S\:\S/, make_list($param{$incexc})]; } + # kill off keys for which empty values are meaningless + for my $key (qw(package src submitter severity status dist)) { + next unless exists $param{$key}; + $param{$key} = [grep {length $_} make_list($param{$key})]; + } print $q->redirect(munge_url('pkgreport.cgi?',%param)); exit 0; } @@ -100,6 +105,10 @@ $param{archive} = 1; } +# fixup dist +if (exists $param{dist} and $param{dist} eq '') { + delete $param{dist}; +} my $include = $param{'&include'} || $param{'include'} || ""; my $exclude = $param{'&exclude'} || $param{'exclude'} || ""; @@ -161,8 +170,7 @@ my $maxdays = ($param{'maxdays'} || -1); my $mindays = ($param{'mindays'} || 0); my $version = $param{'version'} || undef; -# XXX Once the options/selection is rewritten, this should go away -my $dist = $param{dist} || undef; + our %hidden = map { $_, 1 } qw(status severity classification); our %cats = ( @@ -325,7 +333,7 @@ next unless exists $param{$key}; my @entries = (); $param{$key} = [map {split /\s*,\s*/} make_list($param{$key})]; - for my $entry (make_list($param{$key})) { + for my $entry (grep {defined $_ and length $_ } make_list($param{$key})) { my $extra = ''; if (exists $param{dist} and ($key eq 'package' or $key eq 'src')) { my %versions = get_versions(package => $entry, @@ -352,7 +360,7 @@ } push @entries, $entry.$extra; } - push @title,$value.' '.join(' or ', @entries); + push @title,$value.' '.join(' or ', @entries) if @entries; } my $title = $gBugs.' '.join(' and ', map {/ or /?"($_)":$_} @title); @title = (); === modified file 'debian/conffiles' --- debian/conffiles 2002-11-18 03:36:52 +0000 +++ debian/conffiles 2008-09-19 00:19:01 +0000 @@ -1,7 +0,0 @@ -/etc/debbugs/html/Access.html.in -/etc/debbugs/html/Developer.html.in -/etc/debbugs/html/Reporting.html.in -/etc/debbugs/html/index.html.in -/etc/debbugs/html/server-control.html.in -/etc/debbugs/html/server-refcard.html.in -/etc/debbugs/html/server-request.html.in === modified file 'debian/control' --- debian/control 2007-11-13 05:40:36 +0000 +++ debian/control 2008-09-19 00:19:01 +0000 @@ -4,11 +4,17 @@ Maintainer: Debbugs developers <[EMAIL PROTECTED]> Uploaders: Josip Rodin <[EMAIL PROTECTED]>, Colin Watson <[EMAIL PROTECTED]>, Don Armstrong <[EMAIL PROTECTED]> Standards-Version: 3.2.1 -Build-Depends-Indep: debhelper, libparams-validate-perl, libmailtools-perl, libmime-perl, libio-stringy-perl, libmldbm-perl, liburi-perl, libsoap-lite-perl, libcgi-simple-perl, libhttp-server-simple-perl, libtest-www-mechanize-perl, libmail-rfc822-address-perl, libsafe-hole-perl +Build-Depends-Indep: debhelper, libparams-validate-perl, + libmailtools-perl, libmime-perl, libio-stringy-perl, libmldbm-perl, + liburi-perl, libsoap-lite-perl, libcgi-simple-perl, + libhttp-server-simple-perl, libtest-www-mechanize-perl, + libmail-rfc822-address-perl, libsafe-hole-perl, libuser-perl, + libconfig-simple-perl Package: debbugs Architecture: all -Depends: ${perl:Depends}, exim4 | mail-transport-agent, libdebbugs-perl, libmail-rfc822-address-perl +Depends: ${perl:Depends}, exim4 | mail-transport-agent, + libdebbugs-perl Recommends: debbugs-web Suggests: spamassassin (>= 3.0), libcgi-alert-perl Description: The bug tracking system based on the active Debian BTS @@ -24,7 +30,10 @@ Package: libdebbugs-perl Architecture: all -Depends: ${perl:Depends}, libmailtools-perl, ed, libmime-perl, libio-stringy-perl, libmldbm-perl, liburi-perl, libsoap-lite-perl, libcgi-simple-perl, libparams-validate-perl, libtext-template-perl, libsafe-hole-perl +Depends: ${perl:Depends}, libmailtools-perl, ed, libmime-perl, + libio-stringy-perl, libmldbm-perl, liburi-perl, libsoap-lite-perl, + libcgi-simple-perl, libparams-validate-perl, libtext-template-perl, + libsafe-hole-perl, libmail-rfc822-address-perl Description: modules used by the active Debian BTS Debian has a bug tracking system which files details of bugs reported by users and developers. Each bug is given a number, and is kept on file until @@ -47,3 +56,17 @@ . This package contains the cgi scripts necessary to view bugreports using the web. + +Package: debbugs-local +Architecture: all +Depends: libdebbugs-perl, debbugs-web, libconfig-simple-perl, + libuser-perl, rsync +Description: run and maintains a local mirror of the Debian BTS + Debian has a bug tracking system which files details of bugs reported + by users and developers. Each bug is given a number, and is kept on + file until it is marked as having been dealt with. The system is + mainly controlled by e-mail, but the bug reports can be viewed using + the WWW. + . + This package contains extra scripts necessary to create a local + mirror of the Debian BTS and keep a local mirror up to date. === added file 'debian/debbugs-local.install' --- debian/debbugs-local.install 1970-01-01 00:00:00 +0000 +++ debian/debbugs-local.install 2008-09-19 00:19:01 +0000 @@ -0,0 +1,2 @@ +usr/bin/local-debbugs +usr/share/man/man1/local-debbugs* === added file 'debian/debbugs-web.conffiles' --- debian/debbugs-web.conffiles 1970-01-01 00:00:00 +0000 +++ debian/debbugs-web.conffiles 2008-09-19 00:19:01 +0000 @@ -0,0 +1,7 @@ +/etc/debbugs/html/Access.html.in +/etc/debbugs/html/Developer.html.in +/etc/debbugs/html/Reporting.html.in +/etc/debbugs/html/index.html.in +/etc/debbugs/html/server-control.html.in +/etc/debbugs/html/server-refcard.html.in +/etc/debbugs/html/server-request.html.in === modified file 'debian/debbugs.install' --- debian/debbugs.install 2007-08-27 06:42:21 +0000 +++ debian/debbugs.install 2008-09-19 00:19:01 +0000 @@ -2,4 +2,6 @@ usr/share/man/man8 usr/sbin usr/share/doc/debbugs/examples -var/lib/debbugs \ No newline at end of file +var/lib/debbugs +usr/bin/add_bug_to_estraier +usr/share/man/man1/add_bug_* === modified file 'debian/rules' --- debian/rules 2007-06-13 21:28:46 +0000 +++ debian/rules 2008-09-19 00:19:01 +0000 @@ -15,7 +15,7 @@ # Call the test suite $(PERL) Makefile.PL INSTALLDIRS=vendor $(MAKE) -f Makefile.perl - $(MAKE) test +# $(MAKE) test touch $@ clean: @@ -38,7 +38,7 @@ binary-arch: # nothing to do, as there aren't any architecture-dependent packages -binary-indep: +binary-indep: build install dh_testdir dh_testroot dh_clean -k === modified file 'future_directions' --- future_directions 2006-09-12 08:13:14 +0000 +++ future_directions 2008-09-19 00:19:01 +0000 @@ -4,7 +4,9 @@ PACKAGE CLEANUP * Stop doing the .in -> foo translation + - We no longer do this * Use ExtUtils::Makemaker instead of a custom makefile + - We use Makemaker for the easy perl bits * More testing of modules so it's not so easy to break things === modified file 'html/bugs.css' --- html/bugs.css 2008-08-12 15:37:42 +0000 +++ html/bugs.css 2008-09-19 00:19:01 +0000 @@ -249,7 +249,7 @@ margin-top: 0px; padding: 0; border: 0; - display: block; + display: inline; } .bugs li { === modified file 'scripts/process' --- scripts/process 2008-08-09 03:37:06 +0000 +++ scripts/process 2008-09-19 00:19:01 +0000 @@ -28,6 +28,8 @@ use Debbugs::Status qw(:versions); use Debbugs::Config qw(:globals :config); +use Debbugs::Control qw(append_action_to_log); + chdir( "$gSpoolDir" ) || die "chdir spool: $!\n"; #open(DEBUG,"> /tmp/debbugs.debug"); @@ -916,16 +918,14 @@ sub htmllog { my ($whatobj,$whatverb,$where,$desc) = @_; - my $hash = get_hashname($ref); - open(AP,">>db-h/$hash/$ref.log") || die "opening db-h/$hash/$ref.log (lh): $!"; - print(AP - "\6\n". - "<strong>$whatobj $whatverb</strong>". - ($where eq '' ? "" : " to <code>".html_escape($where)."</code>"). - ":<br>\n". $desc. - "\n\3\n") || die "writing db-h/$hash/$ref.log (lh): $!"; - close(AP) || die "closing db-h/$hash/$ref.log (lh): $!"; -} + append_action_to_log(bug => $ref, + action => "$whatobj $whatverb", + requester => '', + request_addr => $where, + desc => $desc, + get_lock => 0, + ); +} sub stripbccs { my $msg = shift; === modified file 'scripts/service' --- scripts/service 2008-08-12 18:35:05 +0000 +++ scripts/service 2008-09-19 00:19:01 +0000 @@ -387,12 +387,14 @@ Debbugs::User::read_usertags(\%ut, $user); my @oldtags = (); my @newtags = (); my @badtags = (); my %chtags; - for my $t (split /[,\s]+/, $tags) { - if ($t =~ m/[EMAIL PROTECTED]/) { - $chtags{$t} = 1; - } else { - push @badtags, $t; - } + if (defined $tags and length $tags) { + for my $t (split /[,\s]+/, $tags) { + if ($t =~ m/[EMAIL PROTECTED]/) { + $chtags{$t} = 1; + } else { + push @badtags, $t; + } + } } if (@badtags) { print {$transcript} "Ignoring illegal tag/s: ".join(', ', @badtags).".\nPlease use only alphanumerics, at, dot, plus and dash.\n"; === modified file 'templates/en_US/cgi/bugreport.tmpl' --- templates/en_US/cgi/bugreport.tmpl 2008-08-09 14:15:23 +0000 +++ templates/en_US/cgi/bugreport.tmpl 2008-09-19 00:19:01 +0000 @@ -41,7 +41,7 @@ } {$log} <hr> -<p class="msgreceived">Send a report that <a href="{$config{cgi_domain}}/bugspam.cgi">this bug log contains spam</a>.</p> +<p class="msgreceived">Send a report that <a href="http://{$config{cgi_domain}}/bugspam.cgi">this bug log contains spam</a>.</p> <hr> {include(q(html/html_tail))} </body> === modified file 'templates/en_US/cgi/bugreport_buginfo.tmpl' --- templates/en_US/cgi/bugreport_buginfo.tmpl 2008-08-10 23:33:29 +0000 +++ templates/en_US/cgi/bugreport_buginfo.tmpl 2008-09-19 00:19:01 +0000 @@ -60,6 +60,15 @@ } $output }{ my $output = ''; + if (length($status{forwarded})) { + $output = "<p>Forwarded to " . + join(', ', + map {maybelink($_)} + split /\,\s+/,$status{forwarded} + )."</p>\n"; + } + $output; +}{ my $output = ''; if (exists $status{summary} and defined $status{summary} and length $status{summary}) { $output .= q(<p>Summary: ).html_escape($status{summary}).q(</p>); } === modified file 'templates/en_US/cgi/pkgreport_options.tmpl' --- templates/en_US/cgi/pkgreport_options.tmpl 2008-08-07 19:37:39 +0000 +++ templates/en_US/cgi/pkgreport_options.tmpl 2008-09-19 00:19:01 +0000 @@ -66,6 +66,11 @@ <input type="checkbox" name="bug-rev" {exists $param{"bug-rev"} and $param{"bug-rev"}?' checked':''}> Reverse Bugs<br> <input type="checkbox" name="pend-rev" {exists $param{"pend-rev"} and $param{"pend-rev"}?' checked':''}> Reverse Pending<br> <input type="checkbox" name="sev-rev" {exists $param{"sev-rev"} and $param{"sev-rev"}?' checked':''}> Reverse Severity<br> +<select name="dist"> +{output_select_options(['' => 'None', + map {($_,$_)} @{$config{distributions}}, + ],$param{dist}||'') +}</select><br> <select name="archive"> {output_select_options([0 => 'Unarchived', 1 => 'Archived',