From 96da3ca68f6f6492bfa7e7f414326c45290839f8 Mon Sep 17 00:00:00 2001 From: gecko <> Date: Thu, 2 Sep 1999 18:25:01 -0800 Subject: [PATCH] [project @ 1999-09-02 19:25:01 by gecko] Initial revision --- cgi/bugs-fetch2.pl.in | 80 ++++ cgi/cgi-lib.pl | 203 +++++++++ debian/changelog | 70 +++ debian/copyright | 36 ++ debian/debbugs-maketxt | 27 ++ debian/dirs | 12 + html/Access.html.in | 42 ++ html/Developer.html.in | 193 +++++++++ html/Reporting.html.in | 191 ++++++++ html/index.html.in | 85 ++++ html/lynx-cfg | 1 + html/server-control.html.in | 202 +++++++++ html/server-refcard.html.in | 90 ++++ html/server-request.html.in | 190 ++++++++ misc/Maintainers | 2 + misc/crontab.in | 10 + scripts/age-1.in | 7 + scripts/config.debian | 65 +++ scripts/config.in | 66 +++ scripts/config.in.default | 55 +++ scripts/db2html.in | 638 +++++++++++++++++++++++++++ scripts/errorlib.in | 104 +++++ scripts/expire.in | 65 +++ scripts/html-control.in | 93 ++++ scripts/html-install.in | 116 +++++ scripts/mailsummary.in | 78 ++++ scripts/process.in | 837 ++++++++++++++++++++++++++++++++++++ scripts/processall.in | 61 +++ scripts/receive.in | 116 +++++ scripts/service.in | 805 ++++++++++++++++++++++++++++++++++ scripts/summary.in | 88 ++++ scripts/text.in | 265 ++++++++++++ 32 files changed, 4893 insertions(+) create mode 100644 cgi/bugs-fetch2.pl.in create mode 100644 cgi/cgi-lib.pl create mode 100644 debian/changelog create mode 100644 debian/copyright create mode 100755 debian/debbugs-maketxt create mode 100644 debian/dirs create mode 100644 html/Access.html.in create mode 100644 html/Developer.html.in create mode 100644 html/Reporting.html.in create mode 100644 html/index.html.in create mode 100644 html/lynx-cfg create mode 100644 html/server-control.html.in create mode 100644 html/server-refcard.html.in create mode 100644 html/server-request.html.in create mode 100644 misc/Maintainers create mode 100644 misc/crontab.in create mode 100755 scripts/age-1.in create mode 100644 scripts/config.debian create mode 100644 scripts/config.in create mode 100644 scripts/config.in.default create mode 100755 scripts/db2html.in create mode 100755 scripts/errorlib.in create mode 100755 scripts/expire.in create mode 100755 scripts/html-control.in create mode 100755 scripts/html-install.in create mode 100755 scripts/mailsummary.in create mode 100755 scripts/process.in create mode 100755 scripts/processall.in create mode 100755 scripts/receive.in create mode 100755 scripts/service.in create mode 100755 scripts/summary.in create mode 100644 scripts/text.in diff --git a/cgi/bugs-fetch2.pl.in b/cgi/bugs-fetch2.pl.in new file mode 100644 index 0000000..24c7021 --- /dev/null +++ b/cgi/bugs-fetch2.pl.in @@ -0,0 +1,80 @@ +#!/usr/bin/perl + +require '/etc/debbugs/config'; +require '/var/lib/debbugs/www/cgi/cgi-lib.pl'; + +%map= ($gMirrors); + +ReadParse() or CgiDie("need form data"); + +if ($in{'type'} eq 'ref') { + $_= $in{'ref'}; + s/^\s+//; s/^\#//; s/^\s+//; s/^0*//; s/\s+$//; + + if (m/\D/ || !m/\d/) { + print <Bug number not numeric + +

Invalid input to specific bug fetch form

+ +You must type a number, being the bug reference number. +There should be no nondigits in your entry. + +END + exit(0); + } + $suburl= $_; + $suburl =~ s,^..,$&/$&,; + $suburl.= '.html'; +} elsif ($in{'type'} eq 'package') { + $_= $in{'package'}; + s/^\s+//; s/\s+$//; y/A-Z/a-z/; + if (m/^[^0-9a-z]/ || m/[^-+.0-9a-z]/) { + print <Package name contains invalid characters + +

Invalid input to package buglist fetch form

+ +You must type a package name. Package names start with a letter +or digit and contain only letters, digits and the characters +- + . (hyphen, plus, full stop). + +END + exit(0); + } + $suburl= "pa/l$_.html"; +} else { + print <here. + +(If this link does not work then the bug or package does not exist in +the tracking system any more, or does not yet, or never did.) +END + +exit(0); diff --git a/cgi/cgi-lib.pl b/cgi/cgi-lib.pl new file mode 100644 index 0000000..bc35ed9 --- /dev/null +++ b/cgi/cgi-lib.pl @@ -0,0 +1,203 @@ +#!/usr/bin/perl + +# Perl Routines to Manipulate CGI input +# +# Copyright (c) 1995 Steven E. Brenner +# Permission granted to use and modify this library so long as the +# copyright above is maintained, modifications are documented, and +# credit is given for any use of the library. +# +# Thanks are due to many people for reporting bugs and suggestions +# especially Meng Weng Wong, Maki Watanabe, Bo Frese Rasmussen, +# Andrew Dalke, Mark-Jason Dominus, Dave Dittrich, Jason Mathews + +# For more information, see: +# http://www.bio.cam.ac.uk/web/form.html +# http://www.seas.upenn.edu/~mengwong/forms/ + +# Minimalist http form and script (http://www.bio.cam.ac.uk/web/minimal.cgi): +# +# require "cgi-lib.pl"; +# if (&ReadParse(*input)) { +# print &PrintHeader, &PrintVariables(%input); +# } else { +# print &PrintHeader,'
Data: '; +#} + +# ReadParse +# Reads in GET or POST data, converts it to unescaped text, +# creates key/value pairs in %in, using '\0' to separate multiple +# selections + +# Returns TRUE if there was input, FALSE if there was no input +# UNDEF may be used in the future to indicate some failure. + +# Now that cgi scripts can be put in the normal file space, it is useful +# to combine both the form and the script in one place. If no parameters +# are given (i.e., ReadParse returns FALSE), then a form could be output. + +# If a variable-glob parameter (e.g., *cgi_input) is passed to ReadParse, +# information is stored there, rather than in $in, @in, and %in. + +sub ReadParse { + local (*in) = @_ if @_; + local ($i, $key, $val); + + # Read in text + if (&MethGet) { + $in = $ENV{'QUERY_STRING'}; + } elsif (&MethPost) { + read(STDIN,$in,$ENV{'CONTENT_LENGTH'}); + } + + @in = split(/[&;]/,$in); + + foreach $i (0 .. $#in) { + # Convert plus's to spaces + $in[$i] =~ s/\+/ /g; + + # Split into key and value. + ($key, $val) = split(/=/,$in[$i],2); # splits on the first =. + + # Convert %XX from hex numbers to alphanumeric + $key =~ s/%(..)/pack("c",hex($1))/ge; + $val =~ s/%(..)/pack("c",hex($1))/ge; + + # Associate key and value + $in{$key} .= "\0" if (defined($in{$key})); # \0 is the multiple separator + $in{$key} .= $val; + + } + + return scalar(@in); +} + + +# PrintHeader +# Returns the magic line which tells WWW that we're an HTML document + +sub PrintHeader { + return "Content-type: text/html\n\n"; +} + + +# HtmlTop +# Returns the of a document and the beginning of the body +# with the title and a body

header as specified by the parameter + +sub HtmlTop +{ + local ($title) = @_; + + return < + +$title + + +

$title

+END_OF_TEXT +} + +# Html Bot +# Returns the , codes for the bottom of every HTML page + +sub HtmlBot +{ + return "\n\n"; + } + + +# MethGet +# Return true if this cgi call was using the GET request, false otherwise + +sub MethGet { + return ($ENV{'REQUEST_METHOD'} eq "GET"); +} + + +# MethPost +# Return true if this cgi call was using the POST request, false otherwise + +sub MethPost { + return ($ENV{'REQUEST_METHOD'} eq "POST"); +} + + +# MyURL +# Returns a URL to the script + +sub MyURL { + local ($port); + $port = ":" . $ENV{'SERVER_PORT'} if $ENV{'SERVER_PORT'} != 80; + return 'http://' . $ENV{'SERVER_NAME'} . $port . $ENV{'SCRIPT_NAME'}; +} + + +# CgiError +# Prints out an error message which which containes appropriate headers, +# markup, etcetera. +# Parameters: +# If no parameters, gives a generic error message +# Otherwise, the first parameter will be the title and the rest will +# be given as different paragraphs of the body + +sub CgiError { + local (@msg) = @_; + local ($i,$name); + + if (!@msg) { + $name = &MyURL; + @msg = ("Error: script $name encountered fatal error"); + }; + + print &PrintHeader; + print "$msg[0]\n"; + print "

$msg[0]

\n"; + foreach $i (1 .. $#msg) { + print "

$msg[$i]

\n"; + } + print "\n"; +} + + +# CgiDie +# Identical to CgiError, but also quits with the passed error message. + +sub CgiDie { + local (@msg) = @_; + &CgiError (@msg); + die @msg; +} + + +# PrintVariables +# Nicely formats variables in an associative array passed as a parameter +# And returns the HTML string. +sub PrintVariables { + local (%in) = @_; + local ($old, $out, $output); + $old = $*; $* =1; + $output .= "\n
\n"; + foreach $key (sort keys(%in)) { + foreach (split("\0", $in{$key})) { + ($out = $_) =~ s/\n/
\n/g; + $output .= "
$key\n
$out
\n"; + } + } + $output .= "
\n"; + $* = $old; + + return $output; +} + +# PrintVariablesShort +# Now obsolete; just calls PrintVariables + +sub PrintVariablesShort { + return &PrintVariables(@_); +} + +1; #return true + + diff --git a/debian/changelog b/debian/changelog new file mode 100644 index 0000000..b9d2b6b --- /dev/null +++ b/debian/changelog @@ -0,0 +1,70 @@ +debbugs (2.2-3) unstable; urgency=low + + * Perl Depends change + + -- Darren Benham Tue, 27 Jul 1999 11:27:22 -0700 + +debbugs (2.2-2) unstable; urgency=low + + * Added mailtools to dependency + + -- Darren Benham Thu, 13 May 1999 13:13:15 -0700 + +debbugs (2.2-1) unstable; urgency=low + + * NATIVE Qmail (mailer) support! No more "other MTA" needed + for Qmail users! + * Improved sendmail support. + * Changed lynx dependancies to simply "lynx" + * fixed bad spelling in service script (fixes #36205) + + -- Darren Benham Thu, 8 Apr 1999 16:00:32 -0700 + +debbugs (2.1-1) unstable; urgency=low + + * Added variable in "bad email" message (receive) + * Fixed SUBSTITUTE_DTIME in main html pages + * Changed crontab sample (had bad directories) + * Added some documentation for MTA setup + * Added support for sendmail + * Removed use of btoa to move change around. It's non-free. + + -- Darren Benham Thu, 1 Apr 1999 14:17:01 -0800 + +debbugs (2.0-1) unstable; urgency=low + + * First public release of deb + * Config modification implemented + + -- Darren Benham Sat, 27 Mar 1999 10:37:37 -0800 + +debbugs (1.0-4) unstable; urgency=low + + * Tried a stopgap measure for config files + + -- Darren Benham Mon, 15 Feb 1999 22:11:08 -0800 + +debbugs (1.0-3) unstable; urgency=low + + * $gListDomain yet again + * removed nextnumber, config and text from deb for time bing + + -- Darren Benham Wed, 10 Feb 1999 11:09:47 -0800 + +debbugs (1.0-2) unstable; urgency=low + + * internal release + * fixed scripting bugs in list email + + -- Darren Benham Wed, 10 Feb 1999 10:39:18 -0800 + +debbugs (1.0-1) unstable; urgency=low + + * Initial Release. + + -- Darren Benham Thu, 21 Jan 1999 20:55:51 -0800 + +Local variables: +mode: debian-changelog +add-log-mailing-address: "gecko@debian.org" +End: diff --git a/debian/copyright b/debian/copyright new file mode 100644 index 0000000..76e68b6 --- /dev/null +++ b/debian/copyright @@ -0,0 +1,36 @@ +This package was debianized by Johnie Ingram (johnie@debian.org) +on Tue Jan 6 10:20:12 EST 1998. + +It was downloaded from: + http://www.chiark.greenend.org.uk/~ian/debbugs/ + + +COPYRIGHT AND LACK-OF-WARRANTY NOTICE + +Copyright 1994,1995,1996,1997 Ian Jackson +Copyright 1997 nCipher Corporation Limited +Copyright 1995 Steven Brenner (for cgi-lib.pl). + +This bug system 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 and documentation 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, or one should be available above; if not, write to the +Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA +02111-1307, USA, or email debbugs-maint@chiark.greenend.org.uk. + + - Ian Jackson 30.10.1997 + +Modifications from version 1.0 to 2.0 are +Copyright (C) 1999 Darren Benham +and released under the terms of the GPL -- version 2. + +On Debian/GNU Linux systems, the text of the GPL can be found in +/usr/doc/copyright/GPL. diff --git a/debian/debbugs-maketxt b/debian/debbugs-maketxt new file mode 100755 index 0000000..cbb6c00 --- /dev/null +++ b/debian/debbugs-maketxt @@ -0,0 +1,27 @@ +#!/bin/sh + +set -e + +cwd="`pwd`" +date="`date +'%d %h %Y'`" + +txtconvert () { + src=$1; dst=$2 + echo " generating $dst from $src ..." + rm -f /var/lib/debbugs/www/txt/$dst.html /var/lib/debbugs/www/txt/$dst + perl -ne 'print unless m/^Other pages:$/ .. /^\/' \ + /var/lib/debbugs/www/$src > /var/lib/debbugs/www/txt/$dst.html + HOME=/dev/null lynx -nolist -dump -cfg=/etc/debbugs/lynx-cfg \ + file://localhost/var/lib/debbugs/www/txt/$dst.html > /var/lib/debbugs/www/txt/$dst + rm /var/lib/debbugs/www/txt/$dst.html +} + +echo "documentation conversion ..." +txtconvert Reporting.html bug-reporting.txt +txtconvert Access.html bug-log-access.txt +txtconvert server-request.html bug-log-mailserver.txt +txtconvert Developer.html bug-maint-info.txt +txtconvert server-control.html bug-maint-mailcontrol.txt +txtconvert server-refcard.html bug-mailserver-refcard.txt + +exit 0 diff --git a/debian/dirs b/debian/dirs new file mode 100644 index 0000000..aa96c6e --- /dev/null +++ b/debian/dirs @@ -0,0 +1,12 @@ +/etc/debbugs/html +usr/lib/debbugs +usr/sbin +usr/doc/debbugs/examples +var/lib/debbugs/indices +var/lib/debbugs/www/cgi +var/lib/debbugs/www/db +var/lib/debbugs/www/txt +var/lib/debbugs/spool/lock +var/lib/debbugs/spool/archive +var/lib/debbugs/spool/incoming +var/lib/debbugs/spool/db diff --git a/html/Access.html.in b/html/Access.html.in new file mode 100644 index 0000000..aa28c60 --- /dev/null +++ b/html/Access.html.in @@ -0,0 +1,42 @@ +$gAccessHtml = < + + $gProject $gBugs - Accessing the logs + + + + +

Accessing $gBug reports in the tracking system logs

+
+ +Each message received at or sent by the $gBug processing system is +logged and made available in a number of ways. +

+ +$gHTMLCopies + +There is a mailserver which can send +$gBug reports as plain text on request. To use it send the word +help as the sole contents of an email to +request (the Subject of the +message is ignored), or read the instructions on the World Wide Web or +in the file bug-log-mailserver.txt. + +


+ +Other pages: + + +$gHTMLTail + +HTML_END diff --git a/html/Developer.html.in b/html/Developer.html.in new file mode 100644 index 0000000..d19d3b0 --- /dev/null +++ b/html/Developer.html.in @@ -0,0 +1,193 @@ +$gDeveloperHtml = < + + $gProject - Developers' information + + + +

Developers' information regarding the $gBug processing system

+ +Initially, a $gBug report is submitted by a user as an ordinary mail +message to submit\@$gEmailDomain. This will then be +given a number, acknowledged to the user, and forwarded to a mailing +list (if configured). If the submitter included a Package +line listing a package with a known maintainer the maintainer will get +a copy too. +

+ +The Subject line will have +$gBug#nnn: added, and the +Reply-To will be set to include both the submitter of the +report and nnn\@$gEmailDomain. +

+ +

Closing $gBug reports

+ +A developer who receives a $gBug from the tracking system, or sees it on +the mailing list, and takes responsibility for it should hit Reply in +their favourite mailreader, +and then edit the To field to say +nnn-done\@$gEmailDomain instead of +nnn\@$gEmailDomain +(nnn-close is provided as an alias for +nnn-done). +

+ +The address of the original submitter of the $gBug report will be +included in the default To field, because the $gBug system +included it in the Reply-To. +

+ +`Done' messages are forwarded to a mailing list if the mailing list has been +set up. +

+ +The person closing the $gBug and the person who submitted it will each +get a notification about the change in status of the report. + +

Followup messages

+ +If a developer wishes to reply to a $gBug report without marking the $gBug +as done they may simply reply to the message. Their reply will (by +default) go to nnn\@$gEmailDomain and to the original +submitter of the $gBug report. The $gBug tracking system will file the +reply with the rest of the logs for that $gBug report and forward it to +a designated mailing list. The $gBug will not be marked as done. +

+ +If you wish to send a followup message which is not appropriate for +any mailing list you can do so by sending it to +nnn-quiet\@$gEmailDomain or +nnn-maintonly\@$gEmailDomain, which only file it (not +forwarding it anywhere) and send it on only to the maintainer of the +package in question, respectively. +

+ +Do not use the `reply to all recipients' or `followup' +feature of your mailer unless you intend to edit down the recipients +substantially. In particular, don't send a followup message both to +nnn\@$gEmailDomain and to +submit\@$gEmailDomain, because the $gBug system will then +get two copies of it and each one will be forwarded to the designated +mailing list separately. +

+ +

Severity levels

+ +The $gBug system records a severity level with each $gBug report. This is +set to $gDefaultSeverity by default, but can be overridden either by +supplying a Severity line in the psuedo-header when the +$gBug is submitted (see the +instructions for reporting +$gBugs), or by using the severity command with the +control request server. + +

+ +The severity levels are: + +

+$gHTMLSeverityDesc +
+ +

Recording that you have passed on a $gBug report

+ +When a developer forwards a $gBug report to the developer of the +upstream source package from which the $gProject package is derived, +they should note this in the $gBug tracking system as follows: +

+ +Make sure that the To field of your message to the author +to has only the author(s) address(es) in it; put both the person who +reported the $gBug and +nnn-forwarded\@$gEmailDomain in the +CC field. +

+ +Ask the author to preserve the CC to +nnn-forwarded\@$gEmailDomain when they reply, so that +the $gBug tracking system will file their reply with the original +report. +

+ +When the $gBug tracking system gets a message at +nnn-forwarded it will mark the relevant $gBug as +having been forwarded to the address(es) in the To field +of the message it gets. +

+ +You can also manipulate the `forwarded to' information by sending messages to +control\@$gEmailDomain. + +

Summary postings

+ +Every Friday, a list of outstanding $gBug reports is posted to a summary mailing +list (if set up), sorted by age of report. +Every Tuesday, a list of $gBug reports that have gone unanswered too long is +posted, sorted by package maintainer. +

+ +$gBadMaintHtml + +

Reopening, reassigning and manipulating $gBugs

+ +It is possible to reassign $gBug reports to other packages, to reopen +erroneously-closed ones, to modify the information saying to where, if +anywhere, a $gBug report has been forwarded, to change the severities +and titles of reports and to merge and unmerge $gBug reports. This is +done by sending mail to control\@$gEmailDomain. +

+ +The format of these messages is +described in another document available on the World Wide Web or in +the file bug-maint-mailcontrol.txt. A plain text version +can also be obtained by mailing the word help to the +server at the address above. + +

More-or-less obsolete subject-scanning feature

+(this is likely to be removed the next version)
+Messages that arrive at submit or $gBugs whose +Subject starts Bug#nnn will be treated as +having been sent to nnn\@$gEmailDomain. This is both +for backwards compatibility with mail forwarded from the old +addresses, and to catch followup mail sent to submit by +mistake (for example, by using reply to all recipients). + +

+ +A similar scheme operates for maintonly, +done, quiet and forwarded, +which treat mail arriving with a Subject tag as having been sent to +the corresponding nnn-whatever\@$gEmailDomain address. + +

+ +Messages arriving at plain forwarded and +done - ie, with no $gBug report number in the address - and +without a $gBug number in the Subject will be filed under `junk' and +kept for a few weeks, but otherwise ignored. + +

Future plans

+ +At some point the Package: secondary header field may +become mandatory - at the moment omitting it just produces a warning +message. + +
+Other pages: + + +$gHTMLTail + +HTML_END diff --git a/html/Reporting.html.in b/html/Reporting.html.in new file mode 100644 index 0000000..b4f76f2 --- /dev/null +++ b/html/Reporting.html.in @@ -0,0 +1,191 @@ +$gReportingHtml = <$gProject $gBugs - how to report a $gBug + + +

How to report a $gBug in $gProject

+ +Send mail to +submit\@$gEmailDomain, +as described below. +

+ +Please don't report several unrelated $gBugs - especially ones in +different packages - in one message. Also, please don't mail your $gBug +report to any mailing lists or recipients other than +submit\@$gEmailDomain (for details of how to do this right, see +below). +

+ +Lists of currently-outstanding $gBugs are available on +the World Wide Web and elsewhere - see +other documents for details. +

+ +You should put a pseudo-header at the start of the body of the +message, with the Package: and Version: +lines giving the name and version of the package which has the $gBug. +(The pseudo-header fields must start at the very start of their lines, +and the $gBug system does not currently understand them if they're +buried in MIMEd or PGPd mail.) + +$gHTMLFindPackage + +See below for further requirements. +

+ +$gHTMLPseudoDesc + +

Example

+ +A $gBug report, with mail header, looks something like this: +
+  To: submit\@$gEmailDomain
+  From: diligent\@testing.linux.org
+  Subject: Hello says `goodbye'
+
+  Package: hello
+  Version: 1.3-2
+
+  When I invoke `hello' without arguments from an ordinary shell
+  prompt it prints `goodbye', rather than the expected `hello, world'.
+  Here is a transcript:
+
+  $ hello
+  goodbye
+  $ /usr/bin/hello
+  goodbye
+  $
+
+  I suggest that the output string, in hello.c, be corrected.
+
+  I am using Debian 1.1, kernel version 1.3.99.15z
+  and libc 5.2.18.3.2.1.3-beta.
+
+ +

Please include in your report:

+ +
    +
  • The exact and complete text of any error +messages printed or logged. This is very important! +
  • Exactly what you typed or did to demonstrate the problem. +
  • A description of the incorrect behaviour: exactly what behaviour +you were expecting, and what you observed. A transcript of an +example session is a good way of showing this. +
  • A suggested fix, or even a patch, if you have one. +
  • Details of the configuration of the program with the problem. +Include the complete text of its configuration files. +$gXtraBugInfo +
+ +Include any detail that seems relevant - you are in very little danger +of making your report too long by including too much information. If +they are small please include in your report any files you were using +to reproduce the problem (uuencoding them if they may contain odd +characters etc.). + +

+ +Of course, like any email, you should include a clear, descriptive +Subject line in your main mail header. The subject you +give will be used as the initial $gBug title in the tracking system, so +please try to make it informative ! + +

Sending copies of $gBug reports to other addresses

+ +Sometimes it is necessary to send a copy of a $gBug report to somewhere +else besides the mailing list and the package maintainer, which is where they +are normally sent. +

+ +You could do this by CC'ing your $gBug report to the other address(es), +but then the other copies would not have the $gBug report number put in +the Reply-To field and the Subject line. +When the recipients reply they will probably preserve the +submit\@$gEmailDomain entry in the header and have their +message filed as a new $gBug report. This leads to many duplicated +reports. +

+ +The right way to do this is to use the +X-$gProject-CC header. Add a line like this to your +message's mail header (not to the psuedo header with the +Package field): +

+ X-$gProject-CC: other-list\@cosmic.edu
+
+This will cause the $gBug tracking system to send a copy of your report +to the address(es) in the X-$gProject-CC line as well as to +any mailing list. +

+ +This feature can often be combined usefully with mailing +quiet - see below. + + +

Severity levels

+ +If a report is of a particularly serious $gBug, or is merely a feature +request that, you can set the severity level of the $gBug as you report +it. This is not required, however, and the developers will assign an +appropriate severity level to your report if you do not. +

+ +To assign a severity level put a +Severity: severity line in the psuedo-header, +together with Package and Version. The +severity levels available are described in the +developers' documentation. + + +

Not forwarding to the mailing list - minor $gBug reports

+ +If a $gBug report is minor (for example, a documentation typo or other +trivial build problem), or you're submitting many reports at once, +send them to maintonly\@$gEmailDomain or quiet\@$gEmailDomain. +maintonly will send the report on to the package +maintainer (provided you supply a correct Package line in +the pseudo-header and the maintainer is known), and quiet +will not forward it anywhere at all but only file it as a $gBug (useful +if, for example, you are submitting many similar $gBugs and want to post +only a summary). +

+ +If you do this the $gBug system will set the Reply-To of +any forwarded message so that replies will by default be processed in +the same way as the original report. + +

Unknown packages or $gBugs with no Package key

+ +If the $gBug tracking system doesn't know who the maintainer of the +relevant package is it'll forward the report to +the mailing list even if maintonly was used. +

+ +When sending to maintonly\@$gEmailDomain or +nnn-maintonly\@$gEmailDomain you should make sure that +the $gBug report is assigned to the right package, by putting a correct +Package at the top of an original submission of a report, +or by using the +control\@$gEmailDomain service to (re)assign the report +appropriately first if it isn't correct already. + +$gXtraReportingInfo + +


+Other pages: + + +$gHTMLEnd + +HTML_END diff --git a/html/index.html.in b/html/index.html.in new file mode 100644 index 0000000..4fce7c2 --- /dev/null +++ b/html/index.html.in @@ -0,0 +1,85 @@ +$gIndexHtml = < +$gProject $gBug tracking system + + +

$gProject $gBug tracking system main contents page

+ +$gProjectTitle has a $gBug tracking system which files +details of $gBugs reported by users and developers. Each $gBug is given a +number, and is kept on file until it is marked as having been dealt +with. + +$gHTMLCopies + +

Documentation about the $gBug tracking system

+ + + +

Reviewing $gBug reports on the WWW

+ + + +Each closed $gBug report is expired from these logs $gRemoveAge days after the +last message relating to it is received and filed. + +

Find a $gBug report by reference number

+ + + + + + + +`Not found' means that the $gBug was closed and expired or +never existed, or that this mirror has not yet recorded that $gBug - see +also the timestamp page. + +

Find a $gBug report by package

+ +
+ + + + +
+`Not found' means that that package does not exist or does not have +any outstanding or recently closed $gBug reports. + +$gHTMLOtherPages + +$gHTMLTail + +HTML_END + diff --git a/html/lynx-cfg b/html/lynx-cfg new file mode 100644 index 0000000..792d600 --- /dev/null +++ b/html/lynx-cfg @@ -0,0 +1 @@ +# diff --git a/html/server-control.html.in b/html/server-control.html.in new file mode 100644 index 0000000..5ba35c6 --- /dev/null +++ b/html/server-control.html.in @@ -0,0 +1,202 @@ +$gControlHtml = < + +$gProject $gBug system - control mail server commands + + +

Introduction to the $gBug control and manipulation mailserver

+ +In addition to the mailserver on request\@$gEmailDomain +which allows the retrieval of $gBug data and documentation by email, +there is another server on control\@$gEmailDomain which +also allows $gBug reports to be manipulated in various ways. +

+ +The control server works just like the request server, except that it +has some additional commands; in fact, it's the same program. The two +addresses are only separated to avoid users making mistakes and +causing problems while merely trying to request information. +

+ +Please see the +introduction to +the request server +available on the World Wide Web, in the file +bug-maint-mailcontrol.txt, or by sending +help to either mailserver, for details of the basics of +operating the mailservers and the common commands available when +mailing either address. +

+ +The reference card for the +mailservers is available via the WWW, in +bug-mailserver-refcard.txt or by email using the +refcard command). + +

Commands available only at the control mailserver

+ +
+ +
close bugnumber +
+ +Close $gBug report #bugnumber. +

+ +A notification is sent to the user who reported the $gBug, but (in +contrast to mailing bugnumber-done@$gEmailDomain) the +text of the mail which caused the $gBug to be closed is not +included in that notification. The maintainer who closes a report +should ensure, probably by sending a separate message, that the user +who reported the $gBug knows why it is being closed. + +

reassign bugnumber package +
+ +Records that $gBug #$gBugnumber is a $gBug in package. +This can be used to set the package if the user forgot the +pseudo-header, or to change an earlier assignment. No notifications +are sent to anyone (other than the usual information in the processing +transcript). + +
reopen bugnumber + [ originator-address | = | ! ] +
+ +Reopens #bugnumber if it is closed. +

+ +By default, or if you specify =, the original submitter is +still as the originator of the report, so that they will get the ack +when it is closed again. +

+ +If you supply an originator-address the originator will be +set to the address you supply. If you wish to become the new +originator of the reopened report you can use the ! +shorthand or specify your own email address. +

+ +It is usually a good idea to tell the person who is about to be +recorded as the originator that you're reopening the report, so that +they will know to expect the ack which they'll get when it is closed +again. +

+ +If the $gBug is not closed then reopen won't do anything, not even +change the originator. There is no way to change the originator of an +open $gBug report (this is deliberate, so that you can't have a $gBug be +closed and then deleted $gRemoveAge days later without someone being told about +it). + +

forwarded bugnumber address +
+ +Notes that bugnumber has been forwarded to the upstream +maintainer at address. This does not actually forward the +report. This can be used to change an existing incorrect forwarded-to +address, or to record a new one for a $gBug that wasn't previously noted +as having been forwarded. + +
notforwarded bugnumber +
+ +Forgets any idea that bugnumber has been forwarded to any +upstream maintainer. If the $gBug was not recorded as having been +forwarded then this will do nothing. + +
retitle bugnumber new-title +
+ +Changes the title of a $gBug report to that specified (the default is +the Subject mail header from the original report. +

+ +Unlike most of the other $gBug-manipulation commands when used on one of +a set of merged reports this will change the title of only the +individual $gBug requested, and not all those with which it is merged. + +

severity bugnumber severity +
+ +Set the severity level for $gBug report #bugnumber to +severity. No notification is sent to the user who reported +the $gBug. +

+ +For their meanings please +consult the general developers' documentation for the $gBug system. + +

merge bugnumber bugnumber ... +
+ +Merges two or more $gBug reports. When reports are merged opening, +closing, marking or unmarking as forwarded and reassigning any of the +$gBugs to a new package will have an identical effect on all of the +merged reports. +

+ +Before $gBugs can be merged they must be in exactly the same state: +either all open or all closed, with the same forwarded-to upstream +author address or all not marked as forwarded, and all assigned to the +same package or package(s) (an exact string comparison is done on the +package to which the $gBug is assigned). If they don't start out in the +same state you should use reassign, reopen +and so forth to make sure that they are before using +merge. +

+ +If any of the $gBugs listed in a merge command is already +merged with another $gBug then all the reports merged with any of the +ones listed will all be merged together. Merger is like equality: it +is reflexive, transitive and symmetric. +

+ +Merging reports causes a note to appear on each report's logs; on the +WWW pages this is includes links to the other $gBugs. +

+ +Merged reports are all expired simultaneously, and only when all of +the reports each separately meet the criteria for expiry. + +

unmerge bugnumber +
+ +Disconnects a $gBug report from any other reports with which it may have +been merged. If the report listed is merged with several others then +they are all left merged with each other; only their associations with +the $gBug explicitly named are removed. +

+ +If many $gBug reports are merged and you wish to split them into two +separate groups of merged reports you must unmerge each report in one +of the new groups separately and then merge them into the required new +group. +

+ +You can only unmerge one report with each unmerge +command; if you want to disconnect more than one $gBug simply include +several unmerge commands in your message. + +

+ +
+Other pages: + + +$gHTMLTail + +HTML_END diff --git a/html/server-refcard.html.in b/html/server-refcard.html.in new file mode 100644 index 0000000..892e2e6 --- /dev/null +++ b/html/server-refcard.html.in @@ -0,0 +1,90 @@ +$gRefcardHtml = < +$gProject $gBug system - mail servers' reference card + + +

Mail servers' reference card

+ +Full documentation of the mail servers is available on the WWW, in the +files +bug-log-mailserver.txt and +bug-maint-mailcontrol.txt or by +sending the word help to each mailserver. + +

Synopsis of commands available at request@$gEmailDomain

+ +
    +
  • send bugnumber +
  • send-detail bugnumber +
  • index [full] +
  • index-summary by-package +
  • index-summary by-number +
  • index-maint +
  • index maint maintainer-substring +
  • index-packages +
  • index packages package-substring +
  • send-unmatched [this|0] +
  • send-unmatched last|-1 +
  • send-unmatched old|-2 +
  • getinfo filename (see below) +
  • help +
  • refcard +
  • quit|stop|thank...|--... +
  • #... (comment) +
  • debug level +
+ +

List of info files for getinfo

+
    +
  • maintainers +
  • override.stable +
  • override.development +
  • override.contrib +
  • override.non-free +
  • override.experimental +
  • override.codeword +
  • pseudo-packages.description +
  • pseudo-packages.maintainers +
+ +

Synopsis of extra commands available at control mailserver

+ +
    +
  • close bugnumber + (you must separately tell originator why) +
  • reassign bugnumber package +
  • severity bugnumber severity +
  • reopen bugnumber + [ originator-address | = | ! ] +
  • forwarded bugnumber address +
  • notforwarded bugnumber +
  • retitle bugnumber new-title +
  • merge bugnumber bugnumber ... +
  • unmerge bugnumber +
+reopen with = or no originator address leaves +the originator as the original submitter; ! sets it to +you, the person doing the reopen. +

+ +$gHTMLSeverityDesc + +


+Other pages: + + +$gHTMLTail + +HTML_END diff --git a/html/server-request.html.in b/html/server-request.html.in new file mode 100644 index 0000000..7136cb3 --- /dev/null +++ b/html/server-request.html.in @@ -0,0 +1,190 @@ +$gRequestHtml = < +$gProject $gBug system - $gBug logs by mail server + + + +

Introduction to the $gBug system request server

+
+ +There is a mailserver which can send the $gBug reports and +indices as plain text on request. +

+ +To use it you send a mail message to +request\@$gEmailDomain. +The Subject of the message is ignored, except +for generating the Subject of the reply. +

+ +The body you send should be a series of commands, one per line. +You'll receive a reply which looks like a transcript of your message +being interpreted, with a response to each command. No notifications +are sent to anyone for most commands; however, the messages are logged +and made available in the WWW pages. +

+ +Any text on a line starting with a hash sign # is +ignored; the server will stop processing when it finds a line starting +with quit, stop, thank or two +hyphens (to avoid parsing a signature). It will also stop if it +encounters too many unrecognised or badly-formatted commands. If no +commands are successfully handled it will send the help text for the +server. + +

Commands available

+ +
+
send bugnumber +
send-detail bugnumber +
+ +Requests the transcript for the $gBug report in question. +send-detail sends all of the `boring' messages in the +transcript, such as the various auto-acks (you should usually use +send as well, as the interesting messages are not sent by +send-detail). + +
index [full] +
index-summary by-package +
index-summary by-number +
+ +Request the full index (with full details, and including done and +forwarded reports), or the summary sorted by package or by number, +respectively. + +
index-maint +
+ +Requests the index page giving the list of maintainers with $gBugs (open +and recently-closed) in the tracking sytem. + +
index maint maintainer +
+ +Requests the index pages of $gBugs in the system for all maintainers +containing the string maintainer. The search term is a +case insensitive substring. The $gBug index for each matching +maintainer will be sent in a separate message. + +
index-packages +
+ +Requests the index page giving the list of packages with $gBugs (open +and recently-closed) in the tracking sytem. + +
index packages package +
+ +Requests the index pages of $gBugs in the system for all packages +containing the string package. The search term is a case +insensitive substring. The $gBug index for each matching package will +be sent in a separate message. + +
send-unmatched [this|0] +
send-unmatched last|-1 +
send-unmatched old|-2 +
+ +Requests logs of messages not matched to a particular $gBug report, for +this week, last week and the week before. (Each week ends on a +Wednesday.) + +
getinfo filename +
+ +Request a file containing information about package(s) and or +maintainer(s) - the files available are: +
+
maintainers +
+The unified list of packages' maintainers, as used by the tracking +system. + +$gCreateMaintainers + + + +
pseudo-packages.description +
pseudo-packages.maintainers +
+List of descriptions and maintainers respectively for pseudo-packages. +
+ +
refcards +
+Requests that the mailservers' reference card be sent in plain ASCII. + +
help +
+Requests that this help document be sent by email in plain ASCII. + +
quit +
stop +
thank... +
--... +
+ +Stops processing at this point of the message. After this you may +include any text you like, and it will be ignored. You can use this +to include longer comments than are suitable for #, for +example for the benefit of human readers of your message (reading it +via the tracking system logs or due to a CC or +BCC). + +
#... +
+ +One-line comment. The # must be at the start of the +line. + +
debug level +
+ +Sets the debugging level to level, which should be a +nonnegative integer. 0 is no debugging; 1 is usually sufficient. The +debugging output appears in the transcript. It is not likely to be +useful to general users of the $gBug system. + +
+ +There is a reference card for the +mailservers, available via the WWW, in +bug-mailserver-refcard.txt or by email using the +refcard command (see above). +

+ +If you wish to manipulate $gBug reports you should use the +control\@gEmailDomain address, which understands a +superset of the commands listed +above. This is described in another document, available on the +WWW, in the file bug-maint-mailcontrol.txt, or by +sending help to control\@$gEmailDomain. +

+ +In case you are reading this as a plain text file or via email: an +HTML version is available via the $gBug system main contents page +http://$gWebDomain/. +

+ +


+Other pages: + + +$gHTMLTail + +HTML_END diff --git a/misc/Maintainers b/misc/Maintainers new file mode 100644 index 0000000..2bb65d9 --- /dev/null +++ b/misc/Maintainers @@ -0,0 +1,2 @@ +sample John Smith +test Mary Jane diff --git a/misc/crontab.in b/misc/crontab.in new file mode 100644 index 0000000..ebedc46 --- /dev/null +++ b/misc/crontab.in @@ -0,0 +1,10 @@ +# Example crontab for bugs system. You can just install the crontab.out +# version of this file if you like. +DBC_CRONTAB_MAILTO +DBC_PROCESS_FREQ * * * DBC_SCRIPT_PATH/processall >/dev/null +DBC_HTMLCHECK_FREQ * * * DBC_SCRIPT_PATH/html-control >/dev/null +22 7 * * * touch DBC_SPOOL_PATH/db +23 7 * * 3 DBC_SCRIPT_PATH/age-1 +24 7 * * * DBC_SCRIPT_PATH/expire >/dev/null +23 16 * * 5 DBC_SCRIPT_PATH/mailsummary undone >/dev/null +23 16 * * 2 DBC_SCRIPT_PATH/mailsummary bymaint >/dev/null diff --git a/scripts/age-1.in b/scripts/age-1.in new file mode 100755 index 0000000..704f320 --- /dev/null +++ b/scripts/age-1.in @@ -0,0 +1,7 @@ +#!/bin/sh +set -e +cd /var/lib/debbugs/spool +test -f ./-3.log && rm ./-3.log +test -f ./-2.log && mv ./-2.log ./-3.log +test -f ./-1.log && mv ./-1.log ./-2.log +rm -f ../stamp.html diff --git a/scripts/config.debian b/scripts/config.debian new file mode 100644 index 0000000..83c141a --- /dev/null +++ b/scripts/config.debian @@ -0,0 +1,65 @@ +#domains +$gEmailDomain = "bugs.benham"; #bugs.debian.org +$gListDomain = "lists.benham"; #lists.debian.org +$gWebDomain = "localhost/Bugs"; #www.debian.org/Bugs +$gCGIDomain = "/Bugs/cgi"; #cgi.debian.org +$gMirrors = ""; #comma seperated list + +#Identification +$gProject = "Benham"; #Debian +$gProjectTitle = "Benham DebBug Test"; #Debian GNU/Linux + +#person responsible for this installation +$gMaintainer = "owner"; #Ian Jackson +$gMaintainerWebpage = "http://localhost/benham"; #http://www.debian.org/~iwj +$gMaintainerEmail = "root\@benham"; #ownder@bugs.debian.org + +#directories +#don't change location of dirs. They are currently hardcoded. Variables are +#for future expantion. +$gSpoolDir = "/var/lib/debbugs/spool"; #working directory +$gIncomingDir = "incoming"; #unprocessed emails +$gWebDir = "/var/lib/debbugs/www"; #base location of web pages +$gDocDir = "/var/lib/debbugs/www/txt"; #location of doc files + +#data files +$gMaintainerFile = "/etc/debbugs/Maintainers"; +$gPseudoDescFile = "/etc/debbugs/pseudo-packages.description"; + +#lists +$gSubmitList = "submit.list"; #debian-bugs-dist@lists +$gMaintList = "maint.list"; # +$gQuietList = "quiet.list"; # +$gFowardList = "foward.list"; #debian-bugs-fowarded@lists +$gDoneList = "done.list"; #debian-bugs-closed@lists +$gRequestList = "request.list"; +$gSubmitterList = "submitter.list"; +$gControlList = "control.list"; +$gMirrorList = "mirrors.list"; #sends to all mirrors + +#config +$gMailer='exim'; +$gBug='bug'; +$gBugs='bugs'; +$gRemoveAge = 28; #days +$gDefaultSeverity = 'normal'; +@gStrongSeverities= ('critical','grave'); +@gSeverityList= ('critical','grave','','wishlist'); +%gSeverityDisplay=('critical',"Critical $gBugs", + 'grave',"Grave $gBugs", + 'normal',"Normal $gBugs",, + 'wishlist','Wishlist items'); + +$gTextInstructions = "Instructions are available from ftp.debian.org +and at all Debian mirror sites, in the files: + debian/doc/bug-reporting.txt + debian/doc/bug-log-access.txt + debian/doc/bug-maint-info.txt"; + + + + + + +#dont change +$gBounceFroms = "^mailer|^da?emon|^post.*mast|^root|^wpuser|^mmdf|^smt.*|\\$emd|^mrgate|^vmmail|^mail.*system|^uucp|-maiser-|^mal\@|^mail.*agent|^tcpmail|^bitmail|^mailman"; diff --git a/scripts/config.in b/scripts/config.in new file mode 100644 index 0000000..034e53f --- /dev/null +++ b/scripts/config.in @@ -0,0 +1,66 @@ +#domains +$gEmailDomain = "bugs.benham"; #bugs.debian.org +$gListDomain = "lists.benham"; #lists.debian.org +$gWebDomain = "localhost/Bugs"; #www.debian.org/Bugs +$gDBPath = "Reports"; +$gCGIDomain = "/Bugs/cgi"; #cgi.debian.org +$gMirrors = ""; #comma seperated list + +#Identification +$gProject = "Benham"; #Debian +$gProjectTitle = "Benham DebBug Test"; #Debian GNU/Linux + +#person responsible for this installation +$gMaintainer = "owner"; #Ian Jackson +$gMaintainerWebpage = "http://localhost/benham"; #http://www.debian.org/~iwj +$gMaintainerEmail = "root\@benham"; #ownder@bugs.debian.org + +#directories +#don't change location of dirs. They are currently hardcoded. Variables are +#for future expantion. +$gSpoolDir = "/var/lib/debbugs/spool"; #working directory +$gIncomingDir = "incoming"; #unprocessed emails +$gWebDir = "/var/lib/debbugs/www"; #base location of web pages +$gDocDir = "/var/lib/debbugs/www/txt"; #location of doc files + +#data files +$gMaintainerFile = "/etc/debbugs/Maintainers"; +$gPseudoDescFile = "/etc/debbugs/pseudo-packages.description"; + +#lists +$gSubmitList = "submit.list"; #debian-bugs-dist@lists +$gMaintList = "maint.list"; # +$gQuietList = "quiet.list"; # +$gFowardList = "foward.list"; #debian-bugs-fowarded@lists +$gDoneList = "done.list"; #debian-bugs-closed@lists +$gRequestList = "request.list"; +$gSubmitterList = "submitter.list"; +$gControlList = "control.list"; +$gMirrorList = "mirrors.list"; #sends to all mirrors + +#config +$gMailer='exim'; #valid: exim, qmail and sendmail +$gBug='bug'; +$gBugs='bugs'; +$gRemoveAge = 28; #days +$gDefaultSeverity = 'normal'; +@gStrongSeverities= ('critical','grave'); +@gSeverityList= ('critical','grave','','wishlist'); +%gSeverityDisplay=('critical',"Critical $gBugs", + 'grave',"Grave $gBugs", + 'normal',"Normal $gBugs",, + 'wishlist','Wishlist items'); + +$gTextInstructions = "Instructions are available from ftp.debian.org +and at all Debian mirror sites, in the files: + debian/doc/bug-reporting.txt + debian/doc/bug-log-access.txt + debian/doc/bug-maint-info.txt"; + + + + + + +#dont change +$gBounceFroms = "^mailer|^da?emon|^post.*mast|^root|^wpuser|^mmdf|^smt.*|\\$emd|^mrgate|^vmmail|^mail.*system|^uucp|-maiser-|^mal\@|^mail.*agent|^tcpmail|^bitmail|^mailman"; diff --git a/scripts/config.in.default b/scripts/config.in.default new file mode 100644 index 0000000..8a5be18 --- /dev/null +++ b/scripts/config.in.default @@ -0,0 +1,55 @@ +#domains +$gEmailDomain = "bugs.top.domain"; #bugs.debian.org +$gListDomain = "lists.top.domain"; #lists.debian.org +$gWebDomain = "www.top.domain"; #www.debian.org/Bugs +$gCGIDomain = "cgi.top.domain"; #cgi.debian.org + +#Identification +$gProject = "project"; #Debian +$gProjectTitle = "project title"; #Debian GNU/Linux + +#person responsible for this installation +$gMaintainer = "name"; #Ian Jackson +$gMaintainerWebpage = "url"; #http://www.debian.org/~iwj +$gMaintainerEmail = "address"; #ownder@bugs.debian.org + +#directories +$gSpoolDir = "/var/lib/debbugs/spool"; #working directory +$gIncomingDir = "incoming"; #unprocessed emails +$gWebDir = "/var/lib/debbugs/www"; #base location of web pages +$gDocDir = "/usr/lib/debbugs"; #location of doc files + +#data files +$gMaintainerFile = "/etc/debbugs/Maintainers"; +$gPseudoDescFile = "/etc/debbugs/pseudo-packages.description"; + +#lists +$gSubmitList = "submit.list"; #debian-bugs-dist@lists +$gMaintList = "maint.list"; # +$gQuietList = "quiet.list"; # +$gFowardList = "foward.list"; #debian-bugs-fowarded@lists +$gDoneList = "done.list"; #debian-bugs-closed@lists +$gRequestList = "request.list"; +$gSubmitterList = "submitter.list"; +$gControlList = "control.list"; +$gMirrorList = "mirrors.list"; #sends to all mirrors + +#config +$gMailer='exim'; +$gRemoveAge = 28; #days +$gDefaultSeverity = 'normal'; +@gStrongSeverities= ('critical','grave'); +@gSeverityList= ('critical','grave','','wishlist'); +%gSeverityDisplay=('critical','Critical bugs', + 'grave','Grave bugs', + 'normal','Normal bugs', + 'wishlist','Wishlist items'); + + + + + + + +#dont change +$gBounceFroms = "^mailer|^da?emon|^post.*mast|^root|^wpuser|^mmdf|^smt.*|\\$emd|^mrgate|^vmmail|^mail.*system|^uucp|-maiser-|^mal\@|^mail.*agent|^tcpmail|^bitmail|^mailman"; diff --git a/scripts/db2html.in b/scripts/db2html.in new file mode 100755 index 0000000..938f57f --- /dev/null +++ b/scripts/db2html.in @@ -0,0 +1,638 @@ +#!/usr/bin/perl +# $Id: db2html.in,v 1.1 1999/09/02 19:25:01 gecko Exp $ +# usage: db2html [-diff] [-stampfile=] [-lastrun=] + +require('/etc/debbugs/config'); +require('/etc/debbugs/text'); +require('/usr/lib/debbugs/errorlib'); +$ENV{'PATH'}= '/usr/lib/debbugs'.$ENV{'PATH'}; +chdir("$gSpoolDir") || die "chdir spool: $!\n"; +#push(@INC,'/usr/lib/debbugs'); + +chop($dtime=`date -u '+%H:%M:%S GMT %a %d %h'`); $? and die $?; + +%displayshowpendings= ('pending','outstanding', + 'done','resolved', + 'forwarded','forwarded to upstream software authors'); + +$diff=0; +$stampfile= 'stamp.html'; +$tail_html= $gHTMLTail; $tail_html =~ s/SUBSTITUTE_DTIME/$dtime/; +$expirynote_html= $gHTMLExpireNote; + +while (@ARGV && $ARGV[0] =~ m/^-/) { + if ($ARGV[0] eq '-diff') { $diff=1; } + elsif ($ARGV[0] =~ m/^-lastrun\=([0-9.]+)$/) { $lastrun= $1; undef $stampfile; } + elsif ($ARGV[0] =~ m/^-full$/) { undef $lastrun; undef $stampfile; } + elsif ($ARGV[0] =~ m/^-stampfile\=(\S+)$/) { $stampfile= $1; } + else { &quit("bad usage"); } + shift; +} + +@ARGV==1 or die; +$wwwbase= shift(@ARGV); + +defined($startdate= time) || &quit("failed to get time: $!"); + +$|=1; + +if (defined($stampfile)) { + if (open(X,"< $stampfile")) { + $lastrun= -M X; + close(X); + printf "progress last run %.7f days\n",$lastrun; + } else { + print "progress stamp file $stampfile: $! - full\n"; + } +} + +if (defined($lastrun) && -M "db" > $lastrun) { + $_= $gHTMLStamp; + s/SUBSTITUTE_DTIME/$dtime/o; + s/\<\!\-\-updateupdate\-\-\>.*\<\!\-\-\/updateupdate\-\-\>/check/; + &file('ix/zstamp.html','non',$_."\n"); + print "noremoves\n"; + exit 0; +} + +open(MM,"$gMaintainerFile") || &quit("open $gMaintainerFile: $!"); +while() { + m/^(\S+)\s+(\S.*\S)\s*$/ || &quit("$gMaintainerFile: \`$_'"); + ($a,$b)=($1,$2); + $a =~ y/A-Z/a-z/; + $maintainer{$a}= $b; +} +close(MM); + +opendir(D,'db') || &quit("opendir db: $!"); +@files= sort { $a <=> $b } readdir(D); +closedir(D); + +$shorthead=' Ref Package Keywords/Subject Submitter'; +$shortindex=''; $amonths=-1; +$indexunmatched=''; +for $pending (qw(pending done forwarded)) { + for $severity (@showseverities) { + eval "\$index${pending}${severity}= \$iiindex${pending}${severity}= ''; 1;" + or &quit("reset \$index${pending}${severity}: $@"); + } +} + +for $f (@files) { + next unless $f =~ m/^(-?\d+)\.log$/; + $ref= $1; +#((print STDERR "$ref\n"), +#next +#) +# unless $ref =~ m/^-/ || $ref =~ m/^124/; + &filelock("lock/$ref"); + $preserveonly= defined($lastrun) && -M "db/$ref.log" > $lastrun; + if ($ref =~ m/^-\d$/) { + $week= $ref eq '-1' ? 'this week' : + $ref eq '-2' ? 'last week' : + $ref eq '-3' ? 'two weeks ago' : + ($ref-1)." weeks ago"; + $linkto= "ju/unmatched$ref"; + $short= "junk, $week"; + $descriptivehead= + "This includes messages sent to done\@$gEmailDomain\n". + "which did not have a $gBug reference number in the Subject line\n". + "or which contained an\n". + "unknown or out of date $gBug report number (these cause a warning\n". + "to be sent to the sender) and details about the messages\n". + "sent to request@$gEmailDomain (all of which". + "produce replies).\n"; + $indexlink= "Messages not matched to a specific $gBug report - $week"; + $s_subject= ''; + $indexentry= ''; + undef $tpack; + undef $tmaint; + undef $iiref; + $tpackfile= "pnone.html"; + $indexpart= 'unmatched'; + } else { + open(S,"db/$ref.status") || &quit("open db/$ref.status: $!"); + chomp($s_originator= ); + chomp($s_date= ); + chomp($s_subject= ); + chomp($s_msgid= ); + chomp($s_package= ); + chomp($s_keywords= ); + chomp($s_done= ); + chomp($s_forwarded= ); + chomp($s_mergedwith= ); + chomp($s_severity= ); + $_= $s_package; y/A-Z/a-z/; $_= $` if m/[^-+._a-z0-9()]/; + $tpack= $_; + if ($s_severity eq '' || $s_severity eq 'normal') { + $showseverity= ''; + $addseverity= $gDefaultSeverity; + } elsif (grep($s_severity eq $_, @strongseverities)) { + $showseverity= "Severity: $s_severity;\n"; + $addseverity= $s_severity; + } else { + $showseverity= "Severity: $s_severity;\n"; + $addseverity= $s_severity; + } + $days= int(($startdate - $s_date)/86400); close(S); + $indexlink= "#$ref: ".&sani($s_subject); + $indexentry= ''; + $packfile= length($tpack) ? "pa/l$tpack.html" : "pa/none.html"; + $indexentry .= "Package: ". + &sani($s_package).";\n" + if length($s_package); + $indexentry .= $showseverity; + $indexentry .= "Reported by: ".&sani($s_originator); + $indexentry .= ";\nKeywords: ".&sani($s_keywords) + if length($s_keywords); + $linkto= $ref; $linkto =~ s,^..,$&/$&,; + @merged= split(/ /,$s_mergedwith); + if (@merged) { + $mseparator= ";\nmerged with "; + for $m (@merged) { + $mfile= $m; $mfile =~ s,^..,$&/$&,; + $indexentry .= $mseparator."#$m"; + $mseparator= ",\n"; + } + } + $daysold=$submitted=''; + if (length($s_done)) { + $indexentry .= ";\nDone: ".&sani($s_done); + $indexpart= "done$addseverity"; + } elsif (length($s_forwarded)) { + $indexentry .= ";\nForwarded to ".&sani($s_forwarded); + $indexpart= "forwarded$addseverity"; + } else { + $cmonths= int($days/30); + if ($cmonths != $amonths) { + $msg= $cmonths == 0 ? "Submitted in the last month" : + $cmonths == 1 ? "Over one month old" : + $cmonths == 2 ? "Over two months old - attention is required" : + "OVER $cmonths MONTHS OLD - ATTENTION IS REQUIRED"; + $shortindex .= "

$msg:

\n$shorthead\n";
+                $amonths= $cmonths;
+            }
+            $pad= 6-length(sprintf("%d",$f));
+            $thissient=
+                ($pad>0 ? ' 'x$pad : '').
+                sprintf("%d",$linkto,$ref).
+                &sani(sprintf(" %-10.10s %-35.35s %-.25s\n",
+                        $s_package,
+                        (length($s_keywords) ? $s_keywords.'/' : '').
+                        $s_subject, $s_originator));
+            $shortindex.= $thissient;
+            $sient{"$ref $s_package"}= $thissient;
+            if ($days >= 7) {
+                $font= $days <= 30 ? '' :
+                       $days <= 60 ? 'em' :
+                                     'strong';
+                $efont= length($font) ? "" : '';
+                $font= length($font) ? "<$font>" : '';
+                $daysold= "; $font$days days old$efont";
+            }
+            if ($preserveonly) {
+                $submitted= 'THIS IS A BUG IN THE BUG PROCESSOR';
+            } else {
+                $submitted= `TZ=GMT LANG=C \\
+                             date -d '1 Jan 1970 00:00:00 + $s_date seconds' \\
+                                     '+ %a, %d %b %Y %T %Z'`;
+                $? and die $?;
+            }
+            $submitted =~ s/\n$//; $submitted =~ s/, 0/, /g;
+            $submitted= "; dated $submitted";
+            $indexpart= "pending$addseverity";
+        }
+        $iiref= $ref;
+        $short= $ref; $short =~ s/^\d+/#$&/;
+        $tmaint= defined($maintainer{$tpack}) ? $maintainer{$tpack} : '(unknown)';
+        $qpackage= &sani($_);
+        $descriptivehead= $indexentry.$submitted.";\nMaintainer for $qpackage is\n".
+            ''.&sani($tmaint).'.';
+        $indexentry .= $daysold;
+        $indexentry .= ".";
+    }
+    $indexadd='';
+    $indexadd .= "" if defined($iiref);
+    $indexadd .= "
  • ".$indexlink.""; + $indexadd .= "
    \n".$indexentry if length($indexentry); + $indexadd .= "" if defined($iiref); + $indexadd .= "\n"; + $estr= "\$index$indexpart = \$indexadd.\$index$indexpart; 1;"; + eval($estr) || &quit("eval add to \$index$indexpart ($estr) failed: $@"); +#print STDERR ">$estr|$indexadd<\n"; + $indexadd= "\n" if defined($iiref); + eval("\$iiindex$indexpart = \$indexadd.\$iiindex$indexpart; 1;") || + &quit("eval add to \$iiindex$indexpart failed: $@"); + if (defined($tmaint)) { + $countpermaint{$tmaint} += length($s_done) ? 0 : length($s_forwarded) ? 0 : 1; + eval("\$permaint${indexpart}{\$tmaint} .= \$indexadd; 1;") || + &quit("eval add to \$permaint${indexpart}{\$tmaint} failed: $@"); + } + if (defined($tpack)) { + $countperpack{$tpack} += length($s_done) ? 0 : length($s_forwarded) ? 0 : 1; + eval("\$perpack${indexpart}{\$tpack} .= \$indexadd; 1;") || + &quit("eval add to \$perpack${indexpart}{\$tpack} failed: $@"); + } + if ($preserveonly) { + &preserve("$linkto.html"); &preserve("$linkto-b.html"); &unfilelock; next; + } + open(L,"db/$ref.log") || &quit("open db/$ref.log: $!"); + $log=''; + $boring=''; $xmessage= 0; + $normstate= 'kill-init'; + $suppressnext= 0; + while() { + if (m/^\07$/) { + $normstate eq 'kill-init' || $normstate eq 'kill-end' || + &quit("$ref ^G in state $normstate"); + $normstate= 'incoming-recv'; + } elsif (m/^\01$/) { + $normstate eq 'kill-init' || $normstate eq 'kill-end' || + &quit("$ref ^A in state $normstate"); + $normstate= 'autocheck'; + } elsif (m/^\02$/) { + $normstate eq 'kill-init' || $normstate eq 'kill-end' || + &quit("$ref ^B in state $normstate"); + $normstate= 'recips'; + } elsif (m/^\03$/) { + $normstate eq 'go' || $normstate eq 'go-nox' || $normstate eq 'html' || + &quit("$ref ^C in state $normstate"); + $this .= "
  • \n" if $normstate eq 'go' || $normstate eq 'go-nox'; + if ($normstate eq 'html') { + $xmessage++; + $this .= " Full text". + " available."; + } + if ($suppressnext && $normstate ne 'html') { + $ntis= $this; $ntis =~ s:\:
    :i;
    +                $boring .= "
    \n$ntis\n"; + } else { + $log = $this. "
    \n". $log; + } + $suppressnext= $normstate eq 'html'; + $normstate= 'kill-end'; + } elsif (m/^\05$/) { + $normstate eq 'kill-body' || &quit("^E in state $normstate"); + $this .= "
    \n";
    +            $normstate= 'go';
    +        } elsif (m/^\06$/) {
    +            $normstate eq 'kill-init' || $normstate eq 'kill-end' ||
    +                &quit("$ref ^F in state $normstate");
    +            $normstate= 'html'; $this= '';
    +        } elsif ($normstate eq 'incoming-recv') {
    +            $pl= $_; $pl =~ s/\n+$//;
    +            m/^Received: \(at (\S+)\) by (\S+)\;/ ||
    +                &quit("bad line \`$pl' in state incoming-recv");
    +            $this = "

    Message received at ".&sani("$1\@$2").":


    \n". + "
    \n".
    +                    "$_";
    +            $normstate= 'go';
    +        } elsif ($normstate eq 'html') {
    +            $this .= $_;
    +        } elsif ($normstate eq 'go') {
    +            $this .= &sani($_);
    +        } elsif ($normstate eq 'go-nox') {
    +            next if !s/^X//;
    +            $this .= &sani($_);
    +        } elsif ($normstate eq 'recips') {
    +            if (m/^-t$/) {
    +                $this = "

    Message sent:


    \n"; + } else { + s/\04/, /g; s/\n$//; + $this = "

    Message sent to ".&sani($_).":


    \n"; + } + $normstate= 'kill-body'; + } elsif ($normstate eq 'autocheck') { + next if !m/^X-Debian-Bugs(-\w+)?: This is an autoforward from (\S+)/; + $normstate= 'autowait'; + $this = "

    Message received at $2:


    \n"; + } elsif ($normstate eq 'autowait') { + next if !m/^$/; + $normstate= 'go-nox'; + $this .= "
    \n";
    +        } else {
    +            &quit("$ref state $normstate line \`$_'");
    +        }
    +    }
    +    &quit("$ref state $normstate at end") unless $normstate eq 'kill-end';
    +    close(L);
    +    if (length($boring)) {
    +        &file("$linkto-b.html",'non',
    +              "$gProject $gBug report logs - ".
    +              "$short, boring messages\n".
    +              "\n".
    +              "

    $gProject $gBugreport logs -". + "\n $short,". + " boring messages

    \n$boring\n
    \n". + $tail_html."\n"); + } + &file("$linkto.html",'non', + "$gProject $gBug report logs - ". + "$short\n". + "\n". + "

    $gProject) $gBug report logs - $short
    \n". + &sani($s_subject)."

    ". + "$descriptivehead\n". + "\n
    \n". + $log. + $tail_html."\n"); + &unfilelock; +} + +sub maintsort { + $_= $_[0]; + s/([^<>()]+) \(([^()<>]+)\)/$2 \<$1\>/; + + s/\s+/ /g; + s/^\s*//; + $email= s/ *\<[^<>()]+\>$//g ? $& : ''; + $_= "$1 $_" if s/ (\S+)$//; + $_.= $email; + $_; +} + +sub maintencoded { + return $maintencoded{$_[0]} if defined($maintencoded{$_[0]}); + local ($input)= @_; + local ($todo,$encoded)= ($input); + while ($todo =~ m/\W/) { + $encoded.=$`.sprintf("-%02x_",unpack("C",$&)); + $todo= $'; + } + $encoded.= $todo; + $encoded =~ s/-2e_/\./g; + $encoded =~ s/^([^,]+)-20_-3c_(.*)-40_(.*)-3e_/$1,$2,$3,/; + $encoded =~ s/^(.*)-40_(.*)-20_-28_([^,]+)-29_$/,$1,$2,$3/; + $encoded =~ s/-20_/_/g; + $encoded =~ s/-([^_]+)_-/-$1/g; + $maintencoded{$input}= $encoded; +} + +for $tmaint (keys %countpermaint) { + $_= $tmaint; + $after=$before=$sort2d=$sort2s=$sort1d=$sort1s=''; + $after= "$&$after" if s/\s*\<[^<>()]+\>\s*$//; + $after= "$&$after" if s/\s*\)\s*$//; + $after= "$&$after" if s/\s*,.*$//; + $before.= $& if s/^.*\(\s*//; + $sort2d= $& if s/\S+$//; + $sort1d= $_; + while (s/^([^()<>]+)\. */$1 /) { }; + s/\s+$//; y/A-Za-z/a-zA-Z/; $sort1s= $_; + $sort2s= $sort2d; $sort2s =~ y/A-Za-z/a-zA-Z/; + $maintsort{$tmaint}= $sort2s.' '.$sort1s.' '.$before.$sort1d.$sort2d.$after; + $maintdisplay{$tmaint}= + &sani($before).''.&sani($sort1d.$sort2d).''.&sani($after); +} + +sub heading ($$) { + my ($pt,$sv) = @_; + return $displayshowseverities{$sv}.' - '.$displayshowpendings{$pt}; +} + +sub makeindex ($$$) { + my ($varprefix,$varsuffix,$tkey) = @_; + my ($pending,$severity,$anydone,$text); + $anydone= 0; + $text= ''; + for $pending (qw(pending forwarded done)) { + for $severity (@showseverities) { + $estr= "\$value= \\${varprefix}${pending}${severity}${varsuffix}; 1;"; +#print STDERR $estr; + eval $estr + or &quit("eval get \$${varprefix}${pending}${severity} failed: $@"); +#print STDERR ">$$value<\n"; + next unless length($$value); + $text.= "
    \n

    ".&heading($pending,$severity).":

    \n". + "(List of all". + " such $gBugs is available.)\n
      \n". + $$value. + "
    \n"; + $anydone=1 if $pending eq 'done'; + } + } + $text.= $expirynote_html if $anydone; + return $text; +} + +&file("ix/full.html",'def', + $gFullIndex. + makeindex('$index',"",''). + "
    \n". + $tail_html."\n"); + +&file("ju/junk.html",'non', + $gJunkIndex. + "
    \n

    Junk (messages without a specific $gBug report number):

    \n". + "(\`this week' is everything since last Wednesday.)\n
      \n". + $indexunmatched. + "

    \n". + $tail_html."\n"); + +$nobugs_html= "No reports are currently in this state."; +$who_html= $gProject; +$owner_addr= $gMaintainerEmail; +$otherindex_html= "For other kinds of index or for other information about +$gProject and the $gBug system, see the $gBug system top-level +contents WWW page. + +"; + +for $pending (qw(pending forwarded done)) { + for $severity (@showseverities) { + eval "\$value= \\\$iiindex${pending}${severity}; 1;" + or &quit("eval get \$iiindex${pendingtype}${severity} failed: $@"); + $value= \$nobugs_html if !length($$value); + $headstring= &heading($pending,$severity); + &file("si/$pending$severity.html",'ref', + "$who_html $gBug reports: $headstring\n". + "\n". + "

    $who_html $gBug reports: $headstring

    \n". + $otherindex_html. + ($pending eq 'done' ? "

    \n$expirynote_html" : ''). + "


    \n". + $$value. + "
    \n". + $tail_html."\n"); + } +} + +sub individualindexes ($\@&\%&&$$$$$&&) { + my ($filename,$keysref,$getfilenameref,$countref,$getdisplayref, + $getsimpledisplayref,$what,$caveat,$whatplural,$abbrev,$ihead, + $getxinforef,$getxindexref) = @_; + my ($itext,$i,$tkey,$sani,$count,$tfilename,$refto,$backnext,$xitext,$bugbugs); + $itext=''; + for ($i=0; $i<=$#$keysref; $i++) { + $tkey= $$keysref[$i]; + $tfilename= &$getfilenameref($tkey); + $sani= &$getsimpledisplayref($tkey); + $count= $$countref{$tkey}; + $count= $count >= 1 ? "$count" : "no"; + $bugbugs= $count == 1 ? "$gBug" : "$gBugs"; + $xitext= &$getxindexref($tkey); + $xitext= length($xitext) ? "$count $bugbugs; $xitext" + : "$count outstanding $bugbugs"; + $itext .= "
  • ".&$getdisplayref($tkey).""."\n". + " ($xitext)\n"; + $backnext= ''; + if ($i>0) { + $refto= $$keysref[$i-1]; + $xitext= &$getxindexref($refto); + $xitext= " ($xitext)" if length($xitext); + $backnext .= "
    \nPrevious $what in list, ".&$getdisplayref($refto)."". + "$xitext\n"; + } + if ($i<$#$keysref) { + $refto= $$keysref[$i+1]; + $xitext= &$getxindexref($refto); + $xitext= " ($xitext)" if length($xitext); + $backnext .= "
    \nNext $what in list, ".&$getdisplayref($refto)."". + "$xitext\n"; + } + &file($tfilename,'ref', + "$gProject $gBug reports: $what $sani\n". + "\n". + "

    $gProject $gBug reports: $what $sani

    \n". + &$getxinforef($tkey). + $caveat. + "See the listing of $whatplural.\n". + $backnext. + &makeindex("\$per${abbrev}","{\$tkey}",$tkey). + "
    \n". + $tail_html."\n"); + } + &file($filename,'non', + $ihead. + "
      \n". + $itext. + "

    \n". + $tail_html."\n"); +} + +@maintainers= sort { $maintsort{$a} cmp $maintsort{$b}; } keys %countpermaint; +individualindexes('ix/maintainers.html', + @maintainers, + sub { 'ma/l'.&maintencoded($_[0]).'.html'; }, + %countpermaint, + sub { $maintdisplay{$_[0]}; }, + sub { &sani($_[0]); }, + 'maintainer', + "Note that there may be other reports filed under different + variations on the maintainer\'s name and email address.

    ", + 'maintainers', + 'maint', + $gMaintIndex, + sub { return ''; }, + sub { return ''; }); + +@packages= sort keys %countperpack; +individualindexes('ix/packages.html', + @packages, + sub { length($_[0]) ? "pa/l$_[0].html" : 'pa/none.html'; }, + %countperpack, + sub { length($_[0]) ? $_[0] : 'not specified'; }, + sub { &sani(length($_[0]) ? $_[0] : 'not specified'); }, + 'package', + "Note that with multi-binary packages there may be other + reports filed under the different binary package names.

    ", + 'packages', + 'pack', + $gPackageIndex, + sub { + return unless defined($maintainer{$_[0]}); + $tmaint= $maintainer{$_[0]}; + return "Maintainer for $_[0] is ".&sani($tmaint).".\n

    \n"; + }, + sub { + return unless defined($maintainer{$_[0]}); + $tmaint= $maintainer{$_[0]}; + return "".&sani($tmaint).""; + }); + +&file('ix/summary.html','non', + $gSummaryIndex. + "


    \n".
    +      $shortindex.
    +      "

    \n". + $tail_html."\n"); + +$bypackageindex=''; +for $k (map {$_->[0] } + sort { $a->[2] cmp $b->[2] || $a->[1] <=> $b->[1] } + map { [$_, split(' ',$_,2)] } keys %sient) + { $bypackageindex.= $sient{$k}; } +&file('ix/psummary.html','non', + $gPackageLog. + "
    \n$shorthead\n".
    +      $bypackageindex.
    +      "

    \n". + $tail_html."\n"); + +open(P,"$gPseudoDescFile") || + &quit("$gPseudoDescFile: $!"); +$ppd=''; while(

    ) { s/\s*\n$//; $ppd.= &sani($_)."\n"; } close(P); +&file('ix/pseudopackages.html','non', + $gPseudoIndex. + "


    \n$ppd".
    +      "

    \n". + $tail_html."\n"); + +$_= $gHTMLStamp; s/SUBSTITUTE_DTIME/$dtime/o; + +&file('ix/zstamp.html','non',$_."\n"); + +sub notimestamp ($) { + $_= $_[0]; + s/\<\!\-\-timestamp\-\-\>\n.*\n\<\!\-\-\/timestamp\-\-\>\n//; + return $_; +} + +sub file { + local ($name,$ii,$file)= @_; + if ($diff) { + $cmppath= "$wwwbase/$name".($ii eq 'ref' ? '.ref' : ''); + if (open(ORIG,"$cmppath")) { + undef $/; $orig= ; $/= "\n"; + close(ORIG); + if (¬imestamp($orig) eq ¬imestamp($file)) { + print "preserve $name\n"; + return; + } + defined($c= open(P,"-|")) or &quit("pipe/fork for diff: $!"); + if (!$c) { + open(Q,"|diff -e $cmppath -") or die "pipe/fork II for diff: $!\n"; + print Q $file or die "write orig to diff: $!\n"; + close(Q); $?==0 || $?==256 or die "diff gave $?\n"; + exit($?>>8); + } + undef $/; $difftxt=

    ; $/= "\n"; + close(P); $?==0 || $?==256 or die "diff fork gave $?\n"; + if ($?==0) { + print "preserve $name\n"; + return; + } + $v= (split(/\n/,$difftxt)); + print "diff $v $ii $name\n${difftxt}thatdiff $name\n" + or &quit("stdout (diff): $!"); + return; + } + } + $v= (split(/\n/,$file)); + print "file $v $ii $name\n${file}thatfile $name\n" or &quit("stdout: $!"); +} + +sub preserve { + print "preserve $_[0]\n"; +} + +print "end\n"; + +while ($u= $cleanups[$#cleanups]) { &$u; } +exit 0; diff --git a/scripts/errorlib.in b/scripts/errorlib.in new file mode 100755 index 0000000..3c36796 --- /dev/null +++ b/scripts/errorlib.in @@ -0,0 +1,104 @@ +# -*- perl -*- + +sub F_SETLK { 6; } sub F_WRLCK{ 1; } +$flockstruct= 'sslll'; # And there ought to be something for this too. + +sub unlockreadbugmerge { + local ($rv) = @_; + &unfilelock if $rv >= 2; + &unfilelock if $rv >= 1; +} + +sub lockreadbugmerge { + local ($lref) = @_; + if (!&lockreadbug($lref)) { return 0; } + if (!length($s_mergedwith)) { return 1; } + &unfilelock; + &filelock('lock/merge'); + if (!&lockreadbug($lref)) { &unfilelock; return 0; } + return 2; +} + +sub lockreadbug { + local ($lref) = @_; + &filelock("lock/$lref"); + if (!open(S,"db/$lref.status")) { &unfilelock; return 0; } + chop($s_originator= ); + chop($s_date= ); + chop($s_subject= ); + chop($s_msgid= ); + chop($s_package= ); + chop($s_keywords= ); + chop($s_done= ); + chop($s_forwarded= ); + chop($s_mergedwith= ); + chop($s_severity= ); + close(S); + return 1; +} + +sub filelock { + # NB - NOT COMPATIBLE WITH `with-lock' + local ($lockfile,$flockpushno,$evalstring,$count,$errors,@s1,@s2) = @_; + $flockpushno= $#filelocks+1; + $count= 10; $errors= ''; + for (;;) { + $evalstring= " + open(FLOCK${flockpushno},\"> \$lockfile\") || die \"open: \$!\"; + \$flockwant= pack(\$flockstruct,&F_WRLCK,0,0,1,0);". + ($] >= 5.000 ? " + fcntl(FLOCK$flockpushno,&F_SETLK,\$flockwant) || die \"setlk: \$!\";" : " + \$z= syscall(&SYS_fcntl,fileno(FLOCK$flockpushno),&F_SETLK,\$flockwant) < 0 + && die \"syscall fcntl setlk: \$!\";") ." + (\@s1= lstat(\$lockfile)) || die \"lstat: \$!\"; + (\@s2= stat(FLOCK$flockpushno)) || die \"fstat: \$!\"; + join(',',\@s1) eq join(',',\@s2) || die \"file switched\"; + 1; + "; + last if eval $evalstring; + $errors .= $@; + eval "close(FLOCK$flockpushno);"; + if (--$count <=0) { + $errors =~ s/\n+$//; + &quit("failed to get lock on file $lockfile: $errors // $evalstring"); + } + sleep 10; + } + push(@cleanups,'unfilelock'); + push(@filelocks,$lockfile); +} + +sub unfilelock { + local ($lockfile) = pop(@filelocks); + pop(@cleanups); + eval 'close(FLOCK'.($#filelocks+1).');' || warn "failed to close lock file: $!"; + unlink($lockfile) || warn "failed to remove lock file: $!"; +} + +sub quit { + print DEBUG "quitting >$_[0]<\n"; + local ($u); + while ($u= $cleanups[$#cleanups]) { &$u; } + die "*** $_[0]\n"; +} + +%saniarray= ('<','lt', '>','gt', '&','amp', '"','quot'); + +sub sani { + local ($in) = @_; + local ($out); + while ($in =~ m/[<>&"]/) { + $out.= $`. '&'. $saniarray{$&}. ';'; + $in=$'; + } + $out.= $in; + $out; +} + +@severities= @gSeverityList; +@showseverities= @severities; +grep ($_= $_ eq '' ? $gDefaultSeverity : $_, @showseverities); +@strongseverities= @gStrongSeverities; +%displayshowseverities= %gSeverityDisplay; + +1; diff --git a/scripts/expire.in b/scripts/expire.in new file mode 100755 index 0000000..c8da4dd --- /dev/null +++ b/scripts/expire.in @@ -0,0 +1,65 @@ +#!/usr/bin/perl + +require('/etc/debbugs/config'); +require('/usr/lib/debbugs/errorlib'); +$ENV{'PATH'}= '/usr/lib/debbugs'.$ENV{'PATH'}; +chdir("$gSpoolDir") || die "chdir spool: $!\n"; +#push(@INC,'/usr/lib/debbugs'); + +#open(DEBUG,">&4"); + +defined($startdate= time) || &quit("failed to get time: $!"); + +opendir(DIR,"db") || &quit("opendir db: $!\n"); +@list= grep(m/^\d+\.status$/,readdir(DIR)); +grep(s/\.status$//,@list); +@list= sort { $a <=> $b } @list; + +while (length($ref=shift(@list))) { +#print DEBUG "$ref $considering\n"; + $bfound= &lockreadbugmerge($ref); +#print DEBUG "$ref read $bfound\n"; + $bfound || next; +#print DEBUG "$ref read ok (done $s_done)\n"; + (&unlockreadbugmerge($bfound), next) unless length($s_done); +#print DEBUG "$ref read done\n"; + @aref= ($ref); + if (length($s_mergedwith)) { push(@aref,split/ /,$s_mergedwith); } +#print DEBUG "$ref aref @aref\n"; + $oktoremove= 1; + for $mref (@aref) { +#print DEBUG "$ref $mref check\n"; + if ($mref != $ref) { +#print DEBUG "$ref $mref reading\n"; + &lockreadbug($mref) || die "huh ?"; +#print DEBUG "$ref $mref read ok\n"; + $bfound++; + } +#print DEBUG "$ref $mref read/not\n"; + $expectmerge= join(' ',grep($_ != $mref, sort { $a <=> $b } @aref)); + $s_mergedwith eq $expectmerge || + die "$ref -> $mref: ($s_mergedwith) vs. ($expectmerge) (@aref)"; +#print DEBUG "$ref $mref merge-ok\n"; + length($s_done) || die "$ref -> $mref"; +#print DEBUG "$ref $mref done-ok\n"; + $days= -M "db/$mref.log"; +#print DEBUG "$ref $mref days $days\n"; + if ($days <= $gRemoveAge) { +#print DEBUG "$ref $mref saved\n"; + $oktoremove= 0; + } + } + if ($oktoremove) { +#print DEBUG "$ref removing\n"; + for $mref (@aref) { +#print DEBUG "$ref removing $mref\n"; + unlink("db/$mref.log", "db/$mref.status", "db/$mref.report"); + print("deleted $mref (from $ref)\n") || &quit("output old: $!"); + } + } +#print DEBUG "$ref unlocking $bfound\n"; + for ($i=0; $i<$bfound; $i++) { &unfilelock; } +#print DEBUG "$ref unlocking done\n"; +} + +close(STDOUT) || &quit("close stdout: $!"); diff --git a/scripts/html-control.in b/scripts/html-control.in new file mode 100755 index 0000000..3e0a538 --- /dev/null +++ b/scripts/html-control.in @@ -0,0 +1,93 @@ +#!/usr/bin/perl + +use POSIX; + +require '/etc/debbugs/config'; +require '/usr/lib/debbugs/errorlib'; +$ENV{'PATH'}= '/usr/lib/debbugs'.$ENV{'PATH'}; +chdir("$gSpoolDir") || die "chdir spool: $!\n"; +#push(@INC,'/usr/lib/debbugs'); + +&filelock("html.fcntl-lock"); + +unlink("html-data.gz") || $!==&ENOENT or &quit("remove html-data.gz: $!"); + +sub nonawful ($) { + rename("stamp.html.run","stamp.html") or warn "warning: put back stamp.html: $!"; + &quit($_[0]); +} + +if (open(US,'updateseqs') && -f 'stamp.html') { + chop($lastmain=); + chop($lastsub=); + close(US); + + $lastsub++; + $args= "-diff -stampfile=stamp.html.run"; + rename("stamp.html","stamp.html.run") or &quit("rename stamp.html: $!"); +} else { + $lastsub=0; + chop($lastmain=`TZ=GMT date '+%Y%m%d%H%M%S'`); + $args= '-full'; + unlink('stamp.html') || $!==&ENOENT or &quit("excise stale stamp.html: $!"); +} + +open(X,">stamp.html.new") or &quit("stamp.html.new: $!"); +close(X) or &quit("close stamp.html.new: $!"); + +open(US,'>updateseqs.new') || &quit("create updateseqs.new: $!"); +print(US "$lastmain\n$lastsub\n") || &quit("write updateseqs.new: $!"); +close(US) || &quit("close updateseqs.new: $!"); +rename('updateseqs.new','updateseqs') or nonawful("install updateseqs: $!"); + +sub runshell ($&) { + my ($cmd,$errhref) = @_; + print "xx $cmd\n"; + system $cmd; + !$? && !length($stderr) or &$errhref("$cmd failed - gave $? / $stderr"); +} + +$sequences="$lastmain $lastsub"; +$seqmid= $sequences; $seqmid =~ y/ /-/; +open(MM,">html-data.mail") or nonawful("open html-data.mail: $!"); +if ( length( $gListDomain ) > 0 && length( $gMirrorList ) > 0 ) { +print(MM < +X-$gProject=PR: update $sequences + +END + ) or nonawful("write html-data.mail header: $!"); +} else { +print(MM < +X-$gProject=PR: update $sequences + +END + ) or nonawful("write html-data.mail header: $!"); +} +close(MM) or nonawful("close html-data.mail: $!"); + +runshell("/usr/lib/debbugs/db2html $args 2>&1 >html-data $gWebDir/db", + sub { &nonawful; }); +runshell("/usr/lib/debbugs/html-install $gWebDir/db &1",sub { &quit; }); +runshell("gzip -9 html-data 2>&1",sub { &quit; }); +#runshell("btoa 2>&1 >html-data.mail",sub { &quit; }); +#runshell('2>&1 '.join(' ',('/usr/lib/sendmail','-f'."$gMaintainerEmail")).' -oem -oi -t ) { + chomp; + if (m/^end$/) { + print "end, removing\n"; + for $k (keys %remove) { unlink($k) || $!==&ENOENT or die "$k: $!"; } + for $k (keys %rmdir) { rmdir($k) || $!==&ENOTEMPTY || $!==EEXIST or die "$k: $!"; } + exit 0; + } elsif (s/^progress //) { + y/-+:._!#=,0-9a-zA-Z //cd; + print " progress $_\n"; + } elsif (m/^preserve ($filenamere)$/o) { + delete $remove{$1}; + delete $remove{"$1.ref"}; + print " preserve $1\n"; + } elsif (m/^(file|diff) (\d+) (ref|def|non) ($filenamere)$/o) { + $filediff= $1; $linestodo= $2; $ii= $3; $file= $4; + print " $filediff $ii $file\n"; + delete $remove{$file}; + delete $remove{"$file.ref"} if $ii eq 'ref'; + $file =~ m,^(..)/, or die $file; + mkdir($1,0777) || $!==EEXIST or die $!; + $tranfile= $file; + $tranfile.= '.ref' if $ii eq 'ref'; + open(DT,"> recv.tmp") or die $!; + if ($filediff eq 'diff') { print DT "r $tranfile\n" or die $!; } + $indata= 0; + while ($linestodo--) { + $z=; + if ($filediff eq 'diff') { + if ($indata) { $indata=0 if $incmd && m/^\.$/; } + elsif ($z =~ m/^[0-9,]+[ac]/) { $indata= 1; } + elsif ($z !~ m/^[0-9,]+[ds]/) { die "SECURITY $file >$z<"; } + } + print DT $z or die $!; + } + if ($filediff eq 'diff') { print DT "w new.tmp\nq\n" or die $!; } + close(DT) or die $!; + ($z=) eq "that$filediff $file\n" or die die "not confirmed >$z<"; + if ($filediff eq 'diff') { + $q= `ed -s &1`; + length($q) || $? and die "ed $q $?"; + rename("new.tmp","$tranfile") or die "$tranfile $!"; + unlink("recv.tmp") or die $!; + } else { + rename("recv.tmp","$tranfile") or die "$tranfile $!"; + } + if ($ii eq 'ref') { + open(I,"$tranfile") or die $!; + open(O,"> ref.tmp") or die $!; + while () { + if (m/^\<\!\-\-ii (\d+)\-\-\>$/) { + defined($iival{$1}) or die "$tranfile $1"; + print O $iival{$1} or die $!; + } else { + print O or die $!; + } + } + close(I) or die $!; + close(O) or die $!; + rename("ref.tmp","$file") or die $!; + } elsif ($ii eq 'def') { + open(I,"$file") or die $!; + undef $cdef; $ctext= ''; + while () { + if (s/^\<\!\-\-iid (\d+)\-\-\>//) { + defined($cdef) and die $file; + $cdef= $1; + $ctext= $_; + } elsif (s/\<\!\-\-\/iid\-\-\>\n$//) { + defined($cdef) or die $file; + $iival{$cdef}= $ctext.$_."\n"; + $ctext=''; undef $cdef; + } else { + $ctext.= $_ if defined($cdef); + } + } + } + } elsif (m/^noremoves$/) { + print "noremoves\n"; + exit 0; + } else { + die " huh ? $_"; + } +} + +die "eof $!"; diff --git a/scripts/mailsummary.in b/scripts/mailsummary.in new file mode 100755 index 0000000..eca80a3 --- /dev/null +++ b/scripts/mailsummary.in @@ -0,0 +1,78 @@ +#!/usr/bin/perl + +require( '/etc/debbugs/config' ); + +$ENV{'PATH'}= '/usr/lib/debbugs'.$ENV{'PATH'}; +chdir("$gSpoolDir") || die "chdir spool: $!\n"; + +#open(DEBUG,">&4"); + +if ($ARGV[0] eq 'undone') { + $vdef= "(no outstanding $gBug reports on file, or problem running script)\n"; + $subject= "Unanswered problem reports by date"; + $intro= +"The following problem reports have not yet been marked as `taken up\' by a +message to done\@$gEmailDomain or or `forwarded\' by a +message to fowarded\@$gEmailDomain." + ; +} elsif ($ARGV[0] eq 'bymaint') { + $vdef= "(no outstanding $gBug reports on file, or problem running script)\n"; + $subject= "Unanswered problem reports by maintainer and package"; + $intro= +"The following problem reports have not yet been marked as `taken up\' by a +message to done\@$gEmailDomain or or `forwarded\' by a +message to forwarded\@$gEmailDomain. +The maintainer listed against each package is derived from the Maintainer +field of the package found in the development tree; there is an override file +that can be amended to get the right results if you have taken over a package +and do not expect to issue a new version soon. + +Variant versions of the Maintainer field for the same actual package +maintainer will be listed separately. + +Maintainers with few outstanding $gBug appear first, to avoid those with few +$gBugs being lost deep in the message. +" + ; +} elsif ($ARGV[0] eq 'veryold') { + $vdef= ''; + $subject= "Overdue problem reports by age"; + $intro= +"The following problem reports are very old but have not yet been marked +as `taken up\' by a message to done\@$gEmailDomain as forwarded +to a developer by CCing a message to fowarded\@$gEmailDomain. +Please help ensure that these $gBugs are dealt with quickly, even if you +are not the package maintainer in question. (NB a full list of outstanding +$gBug reports is posted periodically - this is a partial list only!) +" +} else { + die "urgk, wrong argument @ARGV"; +} + +$v=`/usr/lib/debbugs/summary $ARGV[0]`; $? && die "undone failed $?: $!\n"; + +$v= $vdef if $v eq ''; +exit 0 if $v eq ''; + +open(D, '| '.join(' ',('/usr/lib/sendmail','-f'.$gMaintainerEmail)).' -odi -oem -oi -t') || + die "start sendmail: $!"; + +print D <$gWebUrl/txt +END + +close(D); +$? && die "sendmail failed $?: $!\n"; + +print length($v)," bytes of summary posted.\n"; diff --git a/scripts/process.in b/scripts/process.in new file mode 100755 index 0000000..68ad5df --- /dev/null +++ b/scripts/process.in @@ -0,0 +1,837 @@ +#!/usr/bin/perl +# +# Usage: process nn +# Temps: incoming/Pnn + +use Mail::Address; +require( '/etc/debbugs/config' ); +require( '/usr/lib/debbugs/errorlib' ); +chdir( "$gSpoolDir" ) || die 'chdir spool: $!\n'; +@showseverities=(); + +#open(DEBUG,"> /tmp/debbugs.debug"); + +defined( $intdate= time ) || &quit( "failed to get time: $!" ); + +$_=shift; +m/^([BMQFDU])(\d*)\.\d+$/ || &quit("bad argument"); +$codeletter= $1; +$tryref= length($2) ? $2+0 : -1; +$nn= $_; + +if (!rename("incoming/G$nn","incoming/P$nn")) { + $_=$!.''; m/no such file or directory/i && exit 0; + &quit("renaming to lock: $!"); +} + +$baddress= 'bugs' if $codeletter eq 'B'; +$baddress= 'maintonly' if $codeletter eq 'M'; +$baddress= 'quiet' if $codeletter eq 'Q'; +$baddress= 'forwarded' if $codeletter eq 'F'; +$baddress= 'done' if $codeletter eq 'D'; +$baddress= 'submitter' if $codeletter eq 'U'; +$baddress || &quit("bad codeletter $codeletter"); +$baddressroot= $baddress; +$baddress= "$tryref-$baddress" if $tryref>=0; + +open(M,"incoming/P$nn"); +@log=; +close(M); + +@msg=@log; +grep(s/\n+$//,@msg); + +print DEBUG "###\n",join("##\n",@msg),"\n###\n"; + +chop($tdate= `date -u '+%a, %d %h 19%y %T GMT'`); +$fwd= <$_<\n"; + if (s/^(\S+):\s*//) { + $v= $1; $v =~ y/A-Z/a-z/; +print DEBUG ">$v=$_<\n"; + $header{$v}= $_; + } else { +print DEBUG "!>$_<\n"; + } +} + +while ($i <= $#msg && !length($msg[$i])) { $fwd .= "\n"; $i++; } + +while ($msg[$i] =~ m/^(\w+):\s*/) { + $fn=$1; $fv = $'; +print DEBUG ">$fn|$'|\n"; + $fwd .= $fn.': '.$fv."\n"; + while ($msg[++$i] =~ m/^\s/) { $fwd .= $msg[$i]."\n"; $fv .= ' '.$msg[$i]; } + $fn =~ y/A-Z/a-z/; + $pheader{$fn}= $fv; +print DEBUG ">$fn~$fv<\n"; +} + +$fwd .= join("\n",@msg[$i..$#msg]); + +print DEBUG "***\n$fwd\n***\n"; + +defined($header{'from'}) || &quit("no From header"); +$replyto= defined($header{'reply-to'}) ? $header{'reply-to'} : $header{'from'}; + +$_= $replyto; +$_= "$2 <$1>" if m/^([^\<\> \t\n\(\)]+) \(([^\(\)\<\>]+)\)$/; +$replytocompare= $_; +print DEBUG "replytocompare >$replytocompare<\n"; + +if (!defined($header{'subject'})) { + $brokenness.= <= 0) { + $bfound= &lockreadbugmerge($tryref); + if ($bfound) { + $ref= $tryref; + } else { + &htmllog("Reply","sent", $replyto,"Unknown problem report number $tryref."); + &sendmessage(< +In-Reply-To: $header{'message-id'} +References: $header{'message-id'} $s_msgid +X-$gProject-PR-Message: error + +You sent a message to the $gBug tracking system which gave (in the +Subject line or encoded into the recipient at $gEmailDomain), +the number of a nonexistent $gBug report (#$tryref). + +This may be because that $gBug report has been resolved for more than $gRemoveAge +days, and the record of it has been expunged, or because you mistyped +the $gBug report number. + +Your message was dated $header{'date'} and was sent to +$baddress\@$gEmailDomain. It had +Message-ID $header{'message-id'} +and Subject $subject. + +It has been filed (under junk) but otherwise ignored. + +Please consult your records to find the correct $gBug report number, or +contact me, the system administrator, for assistance. + +$gMaintainer +(administrator, $gProject $gBugs database) + +(NB: If you are a system administrator and have no idea what I am +talking about this indicates a serious mail system misconfiguration +somewhere. Please contact me immediately.) + +END + &appendlog; + &finish; + } +} else { + &filelock('lock/-1'); +} + +if ($codeletter eq 'D' || $codeletter eq 'F') { + if ($replyto =~ m/$gBounceFroms/o || + $header{'from'} =~ m/$gBounceFroms/o) { + &quit("bounce detected ! Mwaap! Mwaap!"); + } + $markedby= $header{'from'} eq $replyto ? $replyto : + "$header{'from'} (reply to $replyto)"; + if ($codeletter eq 'F') { + (&appendlog,&finish) if length($s_forwarded); + $receivedat= "forwarded\@$gEmailDomain"; + $markaswhat= 'forwarded'; + $set_forwarded= $header{'to'}; + if ( length( $gListDomain ) > 0 && length( $gFowardList ) > 0 ) { + $generalcc= "$gFowardList\@$gListDomain"; + } else { + $generalcc=''; + } + } else { + (&appendlog,&finish) if length($s_done); + $receivedat= "done\@$gEmailDomain"; + $markaswhat= 'done'; + $set_done= $header{'from'}; + if ( length( $gListDomain ) > 0 && length( $gDoneList ) > 0 ) { + $generalcc= "$gDoneList\@$gListDomain"; + } else { + $generalcc=''; + } + } + if ($ref<0) { + &htmllog("Warning","sent",$replyto,"Message ignored."); + &sendmessage(< +In-Reply-To: $header{'message-id'} +References: $header{'message-id'} $s_msgid +X-$gProject-PR-Message: error + +You sent a message to the $gProject $gBug tracking system old-style +unified mark as $markaswhat address ($receivedat), +without a recognisable $gBug number in the Subject. +Your message has been filed under junk but otherwise ignored. + +If you don't know what I'm talking about then probably either: + +(a) you unwittingly sent a message to done\@$gEmailDomain +because you replied to all recipients of the message a developer used +to mark a $gBug as done and you modified the Subject. In this case, +please do not be alarmed. To avoid confusion do not do it again, but +there is no need to apologise or mail anyone asking for an explanation. + +(b) you are a system administrator, reading this because the $gBug +tracking system is responding to a misdirected bounce message. In this +case there is a serious mail system misconfiguration somewhere - please +contact me immediately. + +Your message was dated $header{'date'} and had +message-id $header{'message-id'} +and subject $subject. + +If you need any assistance or explanation please contact me. + +$gMaintainer +(administrator, $gProject $gBugs database) + +END + &appendlog; + &finish; + } + &checkmaintainers; + $noticeccval.= join(', ', grep($_ ne $replyto,@maintaddrs)); + $noticeccval =~ s/\s+\n\s+/ /g; $noticeccval =~ s/^\s+/ /; $noticeccval =~ s/\s+$//; + if (length($noticeccval)) { $noticecc= "Cc: $noticeccval\n"; } + if (length($generalcc)) { $noticecc.= "Bcc: $generalcc\n"; } + @process= ($ref,split(/ /,$s_mergedwith)); + $orgref= $ref; + for $ref (@process) { + if ($ref != $orgref) { + &unfilelock; + &lockreadbug($ref) || die "huh ? $ref from $orgref out of @process"; + } + $s_done= $set_done if defined($set_done); + $s_forwarded= $set_forwarded if defined($set_forwarded); + &overwrite("db/$ref.status", + "$s_originator\n$s_date\n$s_subject\n$s_msgid\n". + "$s_package\n$s_keywords\n$s_done\n$s_forwarded\n$s_mergedwith\n$s_severity\n"); + open(O,"db/$ref.report") || &quit("read original report: $!"); + $x= join('',); close(O); + if ($codeletter eq 'F') { + &htmllog("Reply","sent",$replyto,"You have marked $gBug as forwarded."); + &sendmessage(< +In-Reply-To: $header{'message-id'} +References: $header{'message-id'} $s_msgid +X-$gProject-PR-Message: forwarded $ref + +Your message dated $header{'date'} +with message-id $header{'message-id'} +and subject line $subject +has caused the $gProject $gBug report #$ref, +regarding $s_subject +to be marked as having been forwarded to the upstream software +author(s) $s_forwarded. + +(NB: If you are a system administrator and have no idea what I am +talking about this indicates a serious mail system misconfiguration +somewhere. Please contact me immediately.) + +$gMaintainer +(administrator, $gProject $gBugs database) + +END + } else { + &htmllog("Reply","sent",$replyto,"You have taken responsibility."); + &sendmessage(< +In-Reply-To: $header{'message-id'} +References: $header{'message-id'} $s_msgid +X-$gProject-PR-Message: closed $ref + +Your message dated $header{'date'} +with message-id $header{'message-id'} +and subject line $subject +has caused the attached $gBug report to be marked as done. + +This means that you claim that the problem has been dealt with. +If this is not the case it is now your responsibility to reopen the +$gBug report if necessary, and/or fix the problem forthwith. + +(NB: If you are a system administrator and have no idea what I am +talking about this indicates a serious mail system misconfiguration +somewhere. Please contact me immediately.) + +$gMaintainer +(administrator, $gProject $gBugs database) + +END + &htmllog("Notification","sent",$s_originator, + "$gBug acknowledged by developer."); + &sendmessage(< +In-Reply-To: $s_msgid +References: $header{'message-id'} $s_msgid +X-$gProject-PR-Message: they-closed $ref + +This is an automatic notification regarding your $gBug report. + +It has been closed by one of the developers, namely +$markedby. + +Their explanation is attached below. If this explanation is +unsatisfactory and you have not received a better one in a separate +message then please contact the developer directly, or email +submit\@$gEmailDomain or me. + +$gMaintainer +(administrator, $gProject $gBugs database) + +END + } + &appendlog; + } + &finish; +} + +if ($ref<0) { + if ($codeletter eq 'U') { + &htmllog("Warning","sent",$replyto,"Message not forwarded."); + &sendmessage(< +In-Reply-To: $header{'message-id'} +References: $header{'message-id'} $s_msgid +X-$gProject-PR-Message: error + +You sent a message to the $gProject $gBug tracking system send to $gBug +report submitter address $baddress\@$gEmailDomain, without a +recognisable $gBug number in the Subject. Your message has been filed +under junk but otherwise ignored. + +If you don't know what I'm talking about then probably either: + +(a) you unwittingly sent a message to $baddress\@$gEmailDomain +because you replied to all recipients of the message a developer sent +to a $gBug's submitter and you modified the Subject. In this case, +please do not be alarmed. To avoid confusion don't do it again, but +there is no need to apologise or mail anyone asking for an +explanation. + +(b) you are a system administrator, reading this because the $gBug +tracking system is responding to a misdirected bounce message. In this +case there is a serious mail system misconfiguration somewhere - please +contact me immediately. + +Your message was dated $header{'date'} and had +message-id $header{'message-id'} +and subject $subject. + +If you need any assistance or explanation please contact me. + +$gMaintainer +(administrator, $gProject $gBugs database) + +END + &appendlog; + &finish; + } + if (!defined($pheader{'package'})) { + $brokenness.= <; $v =~ s/\n$// || &quit("nextnumber bad format"); + $ref= $v+0; $v += 1; $newref=1; + &overwrite('nextnumber', "$v\n"); + &unfilelock; + &overwrite("db/$ref.log",''); + &overwrite("db/$ref.status", + "$replyto\n$intdate\n$subject\n$header{'message-id'}\n". + "$s_package\n$s_keywords\n\n\n\n$s_severity\n"); + &overwrite("db/$ref.report", + join("\n",@msg)."\n"); +} + +&checkmaintainers; + +print DEBUG "maintainers >@maintaddrs<\n"; + +$orgsender= defined($header{'sender'}) ? "Orignal-Sender: $header{'sender'}\n" : ''; +$newsubject= $subject; $newsubject =~ s/^$gBug#$ref\W*\s*//; + +$xcchdr= $header{dbc_xcc_hdr}; +if ($xcchdr =~ m/\S/) { + push(@resentccs,$xcchdr); + $resentccexplain.= < +Resent-Sender: $gMaintainerEmail +X-$gProject-PR-Message: report $ref +X-$gProject-PR-Package: $s_package +X-$gProject-PR-Keywords: $s_keywords +$fwd +END +} elsif ($codeletter eq 'B') { + &htmllog($newref ? "Report" : "Information", "forwarded", + join(', ',"$gSubmitList\@$gListDomain",@resentccs), + "$gBug#$ref". + (length($s_package)? "; Package ".&sani($s_package)."" : ''). + (length($s_keywords)? "; Keywords ".&sani($s_keywords)."":''). + "."); + &sendmessage(< +Resent-Sender: $gMaintainerEmail +X-$gProject-PR-Message: report $ref +X-$gProject-PR-Package: $s_package +X-$gProject-PR-Keywords: $s_keywords +$fwd +END +} elsif (@resentccs) { + # D and F done far earlier; B just done - so this must be M or Q + # We preserve whichever it was in the Reply-To (possibly adding + # the $gBug#). + &htmllog($newref ? "Report" : "Information", "forwarded", + $resentccval, + "$gBug#$ref". + (length($s_package)? "; Package ".&sani($s_package)."" : ''). + (length($s_keywords)? "; Keywords ".&sani($s_keywords)."":''). + "."); + &sendmessage(< +Resent-Sender: $gMaintainerEmail +X-$gProject-PR-Message: report $ref +X-$gProject-PR-Package: $s_package +X-$gProject-PR-Keywords: $s_keywords +$fwd +END +} + +$htmlbreak= length($brokenness) ? "

    \n".&sani($brokenness)."\n

    \n" : ''; +$htmlbreak =~ s/\n\n/\n

    \n\n/g; +if (length($resentccval)) { + $htmlbreak = + " Copy sent to ".&sani($resentccval).".". + $htmlbreak; +} +if ($newref) { + &htmllog("Acknowledgement","sent",$replyto, + ($veryquiet ? + "New $gBug report received and filed, but not forwarded." : + "New $gBug report received and forwarded."). $htmlbreak); + &sendmessage($veryquiet ? < +In-Reply-To: $header{'message-id'} +References: $header{'message-id'} +X-$gProject-PR-Message: ack-quiet $ref + +Thank you for the problem report you have sent regarding $gProject. +This is an automatically generated reply, to let you know your message +has been received. It has not been forwarded to the developers or +their mailing list; you should ensure that the developers are aware of +the problem you have entered into the system - preferably quoting the +$gBug reference number, #$ref. +$resentccexplain +If you wish to submit further information on your problem, please send it +to $ref-$baddressroot\@$gEmailDomain (and *not* +to $baddress\@$gEmailDomain). + +Please do not reply to the address at the top of this message, +unless you wish to report a problem with the $gBug-tracking system. +$brokenness +$gMaintainer +(administrator, $gProject $gBugs database) +END +From: $gMaintainerEmail ($gMaintainer) +To: $replyto +Subject: $gBug#$ref: Acknowledgement of maintainer-only report + ($subject) +Message-ID: +In-Reply-To: $header{'message-id'} +References: $header{'message-id'} +X-$gProject-PR-Message: ack-maintonly $ref + +Thank you for the problem report you have sent regarding $gProject. +This is an automatically generated reply, to let you know your message has +been received. It is being forwarded to the developers (but not the mailing +list, as you requested) for their attention; they will reply in due course. +$resentccexplain +If you wish to submit further information on your problem, please send +it to $ref-$baddressroot\@$gEmailDomain (and *not* +to $baddress\@$gEmailDomain). + +Please do not reply to the address at the top of this message, +unless you wish to report a problem with the $gBug-tracking system. +$brokenness +$gMaintainer +(administrator, $gProject $gBugs database) +END +From: $gMaintainerEmail ($gMaintainer) +To: $replyto +Subject: $gBug#$ref: Acknowledgement ($subject) +Message-ID: +In-Reply-To: $header{'message-id'} +References: $header{'message-id'} +X-$gProject-PR-Message: ack $ref + +Thank you for the problem report you have sent regarding $gProject. +This is an automatically generated reply, to let you know your message has +been received. It is being forwarded to the developers mailing list for +their attention; they will reply in due course. +$resentccexplain +If you wish to submit further information on your problem, please send +it to $ref\@$gEmailDomain (and *not* to +$baddress\@$gEmailDomain). + +Please do not reply to the address at the top of this message, +unless you wish to report a problem with the $gBug-tracking system. +$brokenness +$gMaintainer +(administrator, $gProject $gBugs database) +END +} elsif ($codeletter ne 'U') { + &htmllog("Acknowledgement","sent",$replyto, + ($veryquiet ? "Extra info received and filed, but not forwarded." : + $codeletter eq 'M' ? "Extra info received and forwarded to maintainer." : + "Extra info received and forwarded to list."). $htmlbreak); + &sendmessage($veryquiet ? < +In-Reply-To: $header{'message-id'} +References: $header{'message-id'} +X-$gProject-PR-Message: ack-info-quiet $ref + +Thank you for the additional information you have supplied regarding +this problem report. It has NOT been forwarded to the developers, but +will accompany the original report in the $gBug tracking system. Please +ensure that you yourself have sent a copy of the additional +information to any relevant developers or mailing lists. +$resentccexplain +If you wish to continue to submit further information on your problem, +please send it to $ref-$baddressroot\@$gEmailDomain, as before. + +Please do not reply to the address at the top of this message, +unless you wish to report a problem with the $gBug-tracking system. +$brokenness +$gMaintainer +(administrator, $gProject $gBugs database) +END +From: $gMaintainerEmail ($gMaintainer) +To: $replyto +Subject: $gBug#$ref: Info received for maintainer only + (was $subject) +Message-ID: +In-Reply-To: $header{'message-id'} +References: $header{'message-id'} +X-$gProject-PR-Message: ack-info $ref + +Thank you for the additional information you have supplied regarding +this problem report. It has been forwarded to the developer(s) (but +not to the mailing list) to accompany the original report. +$resentccexplain +If you wish to continue to submit further information on your problem, +please send it to $ref-$baddressroot\@$gEmailDomain, as before. + +Please do not reply to the address at the top of this message, +unless you wish to report a problem with the $gBug-tracking system. +$brokenness +$gMaintainer +(administrator, $gProject $gBugs database) +END +From: $gMaintainerEmail ($gMaintainer) +To: $replyto +Subject: $gBug#$ref: Info received (was $subject) +Message-ID: +In-Reply-To: $header{'message-id'} +References: $header{'message-id'} +X-$gProject-PR-Message: ack-info-maintonly $ref + +Thank you for the additional information you have supplied regarding +this problem report. It has been forwarded to the developer(s) and +to the developers mailing list to accompany the original report. +$resentccexplain +If you wish to continue to submit further information on your problem, +please send it to $ref\@$gEmailDomain, as before. + +Please do not reply to the address at the top of this message, +unless you wish to report a problem with the $gBug-tracking system. +$brokenness +$gMaintainer +(administrator, $gProject $gBugs database) +END +} + +&appendlog; +&finish; + +sub overwrite { + local ($f,$v) = @_; + open(NEW,">$f.new") || &quit("$f.new: create: $!"); + print(NEW "$v") || &quit("$f.new: write: $!"); + close(NEW) || &quit("$f.new: close: $!"); + rename("$f.new","$f") || &quit("rename $f.new to $f: $!"); +} + +sub appendlog { + if (!open(AP,">>db/$ref.log")) { + print DEBUG "failed open log<\n"; + print DEBUG "failed open log err $!<\n"; + &quit("opening db/$ref.log (li): $!"); + } + print(AP "\7\n",@log,"\n\3\n") || &quit("writing db/$ref.log (li): $!"); + close(AP) || &quit("closing db/$ref.log (li): $!"); +} + +sub finish { + utime(time,time,"db"); + local ($u); + while ($u= $cleanups[$#cleanups]) { &$u; } + unlink("incoming/P$nn") || &quit("unlinking incoming/P$nn: $!"); + exit $_[0]; +} + +&quit("wot no exit"); + +sub chldhandle { $chldexit = 'yes'; } + +sub htmllog { + local ($whatobj,$whatverb,$where,$desc) = @_; + open(AP,">>db/$ref.log") || &quit("opening db/$ref.log (lh): $!"); + print(AP + "\6\n". + "$whatobj $whatverb to ".&sani($where). + ":
    \n". $desc. + "\n\3\n") || &quit("writing db/$ref.log (lh): $!"); + close(AP) || &quit("closing db/$ref.log (lh): $!"); +} + +sub get_addresses { + return + map { $_->address() } + map { Mail::Address->parse($_) } @_; +} + + +sub sendmessage { + local ($msg,@recips) = @_; + if ($recips[0] eq '' && $#recips == 0) { @recips= ('-t'); } + open(AP,">>db/$ref.log") || &quit("opening db/$ref.log (lo): $!"); + print(AP "\2\n",join("\4",@recips),"\n\5\n$msg\n\3\n") || + &quit("writing db/$ref.log (lo): $!"); + close(AP) || &quit("closing db/$ref.log (lo): $!"); + + print DEBUG "mailing to >",join('|',@recips),"<\n"; + $SIG{'CHLD'}='chldhandle'; + #print DEBUG "mailing sigchild set up<\n"; + $chldexit = 'no'; + $c= open(U,"-|"); + #print DEBUG "mailing opened pipe fork<\n"; + defined($c) || die $!; + #print DEBUG "mailing opened pipe fork ok $c<\n"; + if (!$c) { # ie, we are in the child process + #print DEBUG "mailing child<\n"; + unless (open(STDERR,">&STDOUT")) { + #print DEBUG "mailing child opened stderr<\n"; + print STDOUT "redirect stderr: $!\n"; + #print DEBUG "mailing child opened stderr fail<\n"; + exit 1; + #print DEBUG "mailing child opened stderr fail exit !?<\n"; + } + #print DEBUG "mailing child opened stderr ok<\n"; + $c= open(D,"|-"); + #print DEBUG "mailing child forked again<\n"; + defined($c) || die $!; + #print DEBUG "mailing child forked again ok $c<\n"; + if (!$c) { # ie, we are the child process + #print DEBUG "mailing grandchild<\n"; + exec '/usr/lib/sendmail','-f'."$gMaintainerEmail",'-odi','-oem','-oi',get_addresses(@recips); + #print DEBUG "mailing grandchild exec failed<\n"; + die $!; + #print DEBUG "mailing grandchild died !?<\n"; + } + #print DEBUG "mailing child not grandchild<\n"; + print(D $msg) || die $!; + #print DEBUG "mailing child printed msg<\n"; + close(D); + #print DEBUG "mailing child closed pipe<\n"; + die "\n*** command returned exit status $?\n" if $?; + #print DEBUG "mailing child exit status ok<\n"; + exit 0; + #print DEBUG "mailing child exited ?!<\n"; + } + #print DEBUG "mailing parent<\n"; + $results=''; + #print DEBUG "mailing parent results emptied<\n"; + while( $chldexit eq 'no' ) { $results.= $_; } + #print DEBUG "mailing parent results read >$results<\n"; + close(U); + #print DEBUG "mailing parent results closed<\n"; + $results.= "\n*** child returned exit status $?\n" if $?; + #print DEBUG "mailing parent exit status ok<\n"; + $SIG{'CHLD'}='DEFAULT'; + #print DEBUG "mailing parent sigchild default<\n"; + if (length($results)) { &quit("running sendmail: $results"); } + #print DEBUG "mailing parent results ok<\n"; +} + +sub checkmaintainers { + return if $maintainerschecked++; + return if !length($s_package); + open(MAINT,"$gMaintainerFile") || die &quit("maintainers open: $!"); + while () { + m/^(\S+)\s+(\S.*\S)\n$/ || &quit("maintainers bogus \`$_'"); + $a= $1; $b= $2; $a =~ y/A-Z/a-z/; + $maintainerof{$1}= $2; + } + close(MAINT); + $anymaintfound=0; $anymaintnotfound=0; + for $p (split(m/[ \t?,()]+/,$s_package)) { + $p =~ y/A-Z/a-z/; + if (defined($maintainerof{$p})) { +print DEBUG "maintainer add >$p|$maintainerof{$p}<\n"; + $addmaint= $maintainerof{$p}; + push(@maintaddrs,$addmaint) unless + $addmaint eq $replyto || grep($_ eq $addmaint, @maintaddrs); + $anymaintfound++; + } else { +print DEBUG "maintainer none >$p<\n"; + $anymaintnotfound++; + last; + } + } +} diff --git a/scripts/processall.in b/scripts/processall.in new file mode 100755 index 0000000..1ae25e0 --- /dev/null +++ b/scripts/processall.in @@ -0,0 +1,61 @@ +#!/usr/bin/perl +# +# Usage: processall +# +# Uses up: incoming/I.nn +# Temps: incoming/[GP].nn +# Creates: incoming/E.nn +# Stop; process/stop + +require( '/etc/debbugs/config' ); +$ENV{'PATH'} = '/usr/lib/debbugs'.$ENV{'PATH'}; +chdir( "$gSpoolDir" ) || die 'chdir spool: $!\n'; +push( @INC, '/usr/lib/debbugs' ); + +#open(DEBUG,">&4"); + +$|=1; +undef %fudged; + +for (;;) { + if (-f 'stop') { + print(STDERR "stop file created\n") || die $!; + last; + } + if (!@ids) { + opendir(DIR,"incoming") || die $!; + while ($_= readdir(DIR)) { push(@ids,$_) if s/^I//; } + last unless @ids; + @ids= sort(@ids); + } + stat("$gMaintainerFile") || die "stat $gMaintainerFile: $!\n"; + $nf= @ids; + $id= shift(@ids); + unless (rename("incoming/I$id","incoming/G$id")) { + if ($fudged{$id}) { + die "$id already fudged once! $!\n"; + } + $fudged{$id}= 1; + next; + } + if ($id =~ m/^[RC]/) { + print(STDOUT "[$nf] $id service ...") || die $!; + defined($c=fork) || die $!; + if (!$c) { exec("/usr/lib/debbugs/service",$id); die $!; } + } elsif ($id =~ m/^[BMQFDU]/) { + print(STDOUT "[$nf] $id process ...") || die $!; + defined($c=fork) || die $!; + if (!$c) { exec("/usr/lib/debbugs/process",$id); die $!; } + } else { + die "bad name $id"; + } + $cc=waitpid($c,0); $cc == $c || die "$cc $c $!"; + $status=$?; + if ($status) { + print(STDERR "$id: process failed ($status $!) - now in [PG]$id\n") || die $!; + } + print(STDOUT " done\n") || die $!; + $ndone++; +} + +exit(0); diff --git a/scripts/receive.in b/scripts/receive.in new file mode 100755 index 0000000..72f6cb1 --- /dev/null +++ b/scripts/receive.in @@ -0,0 +1,116 @@ +#!/usr/bin/perl + +#load configuration file +require( '/etc/debbugs/config' ); + +#set source of mail delivery +#sets any prefix needed to get mailer to add it to error mail +if ( $gMailer eq 'exim' ) +{ $gBadEmailPrefix = ''; + $_ = $ENV{'LOCAL_PART'}; +} elsif ( $gMailer eq 'qmail' ) +{ $gBadEmailPrefix = '//'; + $_ = $ENV{'DEFAULT'}; +# $_ = $ENV{'RECIPIENT'}; +# s/^\w+-bugs--?//; +} else +{ $gBadEmailPrefix = ''; + $_ = $ARGV[0]; + s/\>//; + s/\T.$id") || &failure("open temporary file: $!"); +printf(FILE "Received: (at %s) by $gEmailDomain; %d %s %d %02d:%02d:%02d +0000\n", + $addrrec, $mday,$months[$mon],$year+1900, $hour,$min,$sec) || + &failure("write header to temporary file: $!"); +while() { print(FILE) || &failure("write temporary file: $!"); } +close(FILE) || &failure("close temporary file: $!"); + +rename("T.$id","I$queue.$id") || &failure("rename spool message: $!"); + +exit(0); + +sub failure { + length($id) && unlink("T.$id"); + print STDERR "bugs receive failure: @_\n"; + exit(75); # EX_TEMPFAIL +} diff --git a/scripts/service.in b/scripts/service.in new file mode 100755 index 0000000..93954b6 --- /dev/null +++ b/scripts/service.in @@ -0,0 +1,805 @@ +#!/usr/bin/perl +# +# Usage: service .nn +# Temps: incoming/P.nn + +use Mail::Address; +require('/etc/debbugs/config'); +require('/usr/lib/debbugs/errorlib'); +$ENV{'PATH'}= '/usr/lib/debbugs'.$ENV{'PATH'};; +chdir("$gSpoolDir") || die "chdir spool: $!\n"; + +# open(DEBUG,">&4"); + +$wwwbase= "$gWebDir"; + +# defined($intdate= time) || &quit("failed to get time: $!"); + +$_=shift; +m/^[RC]\.\d+$/ || &quit("bad argument"); +$control= m/C/; +$nn= $_; +if (!rename("incoming/G$nn","incoming/P$nn")) { + $_=$!.''; m/no such file or directory/i && exit 0; + &quit("renaming to lock: $!"); +} + +open(M,"incoming/P$nn"); +@log=; +@msg=@log; +close(M); + +grep((s/\n$//,s/\s+$//),@msg); + +print DEBUG "###\n",join("##\n",@msg),"\n###\n"; + +chop($tdate= `date -u '+%a, %d %h 19%y %T GMT'`); +$fwd= <$_<\n"; + if (s/^(\S+):\s*//) { + $v= $1; $v =~ y/A-Z/a-z/; +print DEBUG ">$v=$_<\n"; + $header{$v}= $_; + } else { +print DEBUG "!>$_<\n"; + } +} + +defined($header{'from'}) || &quit("no From header"); +$replyto= defined($header{'reply-to'}) ? $header{'reply-to'} : $header{'from'}; + +$controlrequestaddr= $control ? "control\@$gEmailDomain" : "request\@$gEmailDomain"; +$transcript=''; +&transcript("Processing commands for $controlrequestaddr:\n\n"); + +$dl= 0; +$state= 'idle'; +$lowstate= 'idle'; +$mergelowstate= 'idle'; +$midix=0; + +for ($procline=$i; $procline<=$#msg; $procline++) { + $state eq 'idle' || "$state ?"; + $lowstate eq 'idle' || "$lowstate ?"; + $mergelowstate eq 'idle' || "$mergelowstate ?"; + $_= $msg[$procline]; s/\s+$//; + next unless m/\S/; next if m/^\s*\#/; + &transcript("> $_\n"); + $action= ''; + if (m/^stop$/ || m/^quit$/ || m/^--/ || m/^thank/) { + &transcript("Stopping processing here.\n\n"); + last; + } elsif (m/^debug\s+(\d+)$/ && $1 >= 0 && $1 <= 1000) { + $dl= $1+0; + &transcript("Debug level $dl.\n\n"); + } elsif (m/^(send|get)\s+\#?(\d{3,})$/) { + $ref= $2+0; $reffile= $ref; $reffile =~ s,^..,$&/$&,; + &sendlynxdoc("db/$reffile.html","logs for $gBug#$ref"); + } elsif (m/^send-detail\s+\#?(\d+)$/) { + $ref= $1+0; $reffile= $ref; $reffile =~ s,^..,$&/$&,; + &sendlynxdoc("db/$reffile-b.html","additional logs for $gBug#$ref"); + } elsif (m/^index(\s+full)?$/) { + &sendlynxdoc("db/ix/full.html",'full index'); + } elsif (m/^index-summary\s+by-package$/) { + &sendlynxdoc("db/ix/psummary.html",'summary index sorted by package/title'); + } elsif (m/^index-summary(\s+by-number)?$/) { + &sendlynxdoc("db/ix/summary.html",'summary index sorted by number/date'); + } elsif (m/^index(\s+|-)pack(age)?s?$/) { + &sendlynxdoc("db/ix/packages.html",'index of packages'); + } elsif (m/^index(\s+|-)maints?$/) { + &sendlynxdoc("db/ix/maintainers.html",'index of maintainers'); + } elsif (m/^index(\s+|-)maint\s+(\S.*\S)$/) { + $substrg= $2; $matches=0; + opendir(DBD,"$gWebDir/db/ma") || die $!; + while (defined($_=readdir(DBD))) { + next unless m/^l/ && m/\.html$/; + &transcript("F|$_\n") if $dl>1; + $filename= $_; s/^l//; s/\.html$//; + &transcript("P|$_\n") if $dl>2; + while (s/-(..)([^_])/-$1_-$2/) { } + &transcript("P|$_\n") if $dl>2; + s/^(.{0,2})_/$1-20_/g; while (s/([^-]..)_/$1-20_/) { }; + &transcript("P|$_\n") if $dl>2; + s/^,(.*),(.*),([^,]+)$/$1-40_$2-20_-28_$3-29_/; + &transcript("P|$_\n") if $dl>2; + s/^([^,]+),(.*),(.*),$/$1-20_-3c_$2-40_$3-3e_/; + &transcript("P|$_\n") if $dl>2; + s/\./-2e_/g; + &transcript("P|$_\n") if $dl>2; + $out=''; + while (m/-(..)_/) { $out.= $`.sprintf("%c",hex($1)); $_=$'; } + $out.=$_; + &transcript("M|$out\n") if $dl>1; + next unless index(lc $out, lc $substrg)>=0; + &transcript("S|$filename\n") if $dl>0; + &transcript("S|$out\n") if $dl>0; + $matches++; + &sendlynxdocraw("db/ma/$filename","$gBug list for maintainer \`$out'"); + } + if ($matches) { + &transcript("$gBug list(s) for $matches maintainer(s) sent.\n\n"); + } else { + &transcript("No maintainers found containing \`$substrg'.\n". + "Use \`index-maint' to get list of maintainers.\n\n"); + } + $ok++; + } elsif (m/^index(\s+|-)pack(age)?s?\s+(\S.*\S)$/) { + $substrg= $+; $matches=0; + opendir(DBD,"$gWebDir/db/pa") || die $!; + while (defined($_=readdir(DBD))) { + next unless m/^l/ && m/\.html$/; + &transcript("F|$_\n") if $dl>1; + $filename= $_; s/^l//; s/\.html$//; + next unless index(lc $_, lc $substrg)>=0; + &transcript("S|$filename\n") if $dl>0; + &transcript("S|$out\n") if $dl>0; + $matches++; + &sendlynxdocraw("db/pa/$filename","$gBug list for package \`$_'"); + } + if ($matches) { + &transcript("$gBug list(s) for $matches package(s) sent.\n\n"); + } else { + &transcript("No packages found containing \`$substrg'.\n". + "Use \`index-packages' to get list of packages.\n\n"); + } + $ok++; + } elsif (m/^send-unmatched(\s+this|\s+-?0)?$/) { + &sendlynxdoc("db/ju/unmatched-1.html","junk (this week)"); + } elsif (m/^send-unmatched\s+(last|-1)$/) { + &sendlynxdoc("db/ju/unmatched-2.html","junk (last week)"); + } elsif (m/^send-unmatched\s+(old|-2)$/) { + &sendlynxdoc("db/ju/unmatched-3.html","junk (two weeks ago)"); + } elsif (m/^getinfo\s+(\S+)$/) { + $file= $1; + if ($file =~ m/^\./ || $file !~ m/^[-.0-9a-z]+$/ || $file =~ m/\.gz$/) { + &transcript("Filename $file is badly formatted.\n\n"); + } elsif (open(P,"$gDocDir/$file")) { + $ok++; + &transcript("Info file $file appears below.\n\n"); + $extras.= "\n---------- Info file $file follows:\n\n"; + while(

    ) { $extras.= $_; } + close(P); + } else { + &transcript("Info file $file does not exist.\n\n"); + } + } elsif (m/^help$/) { + &sendhelp; + &transcript("\n"); + $ok++; + } elsif (m/^refcard$/) { + &sendtxthelp("bug-mailserver-refcard.txt","mailservers' reference card"); + } elsif (m/^subscribe/) { + &transcript(<= 3) { + &transcript("Too many unknown commands, stopping here.\n\n"); + last; + } + } elsif (m/^close\s+\#?(\d+)$/) { + $ok++; + $ref= $1; + if (&setbug) { + if (length($s_done)) { + &transcript("$gBug is already closed, cannot re-close.\n\n"); + &nochangebug; + } else { + $action= "$gBug closed, ack sent to submitter - they'd better know why !"; + do { + &addmaintainers($s_package); + if ( length( $gDoneList ) > 0 && length( $gListDomain ) > + 0 ) { &addccaddress("$gDoneList\@$gListDomain"); } + $s_done= $replyto; + $message= < + +This is an automatic notification regarding your $gBug report. + +It has been marked as closed by one of the developers, namely +$replyto. + +You should be hearing from them with a substantive response shortly, +if you have not already done so. If not, please contact them +directly, or email DB_SUBMIT_ADDRPQ or myself. + +$gMaintainer +(administrator, $gProject $gBugs database) +END + &sendmailmessage($message,$s_originator); + } while (&getnextbug); + } + } + } elsif (m/^reassign\s+\#?(\d+)\s+(\S.*\S)$/) { + $ok++; + $ref= $1; $newpackage= $2; + if (&setbug) { + if (length($s_package)) { + $action= "$gBug reassigned from package \`$s_package'". + " to \`$newpackage'."; + } else { + $action= "$gBug assigned to package \`$newpackage'."; + } + do { + &addmaintainers($s_package); + &addmaintainers($newpackage); + $s_package= $newpackage; + } while (&getnextbug); + } + } elsif (m/^reopen\s+\#?(\d+)$/ ? ($noriginator='', 1) : + m/^reopen\s+\#?(\d+)\s+\=$/ ? ($noriginator='', 1) : + m/^reopen\s+\#?(\d+)\s+\!$/ ? ($noriginator=$replyto, 1) : + m/^reopen\s+\#?(\d+)\s+(\S.*\S)$/ ? ($noriginator=$2, 1) : 0) { + $ok++; + $ref= $1; + if (&setbug) { + if (!length($s_done)) { + &transcript("$gByg is already open, cannot reopen.\n\n"); + &nochangebug; + } else { + $action= + $noriginator eq '' ? "$gBug reopened, originator not changed." : + "$gBug reopened, originator set to $noriginator."; + do { + &addmaintainers($s_package); + $s_originator= $noriginator eq '' ? $s_originator : $noriginator; + $s_done= ''; + } while (&getnextbug); + } + } + } elsif (m/^forwarded\s+\#?(\d+)\s+(\S.*\S)$/) { + $ok++; + $ref= $1; $whereto= $2; + if (&setbug) { + if (length($s_forwarded)) { + $action= "Forwarded-to-address changed from $s_forwarded to $whereto."; + } else { + $action= "Noted your statement that $gBug has been forwarded to $whereto."; + } + if (length($s_done)) { + $extramessage= "(By the way, this $gBug is currently marked as done.)\n"; + } + do { + &addmaintainers($s_package); + if (length($gFowardList)>0 && length($gListDomain)>0 ) + { &addccaddress("$gFowardList\@$gListDomain"); } + $s_forwarded= $whereto; + } while (&getnextbug); + } + } elsif (m/^notforwarded\s+\#?(\d+)$/) { + $ok++; + $ref= $1; + if (&setbug) { + if (!length($s_forwarded)) { + &transcript("$gBug is not marked as having been forwarded.\n\n"); + &nochangebug; + } else { + $action= "Removed annotation that $gBug had been forwarded to $s_forwarded."; + do { + &addmaintainers($s_package); + $s_forwarded= ''; + } while (&getnextbug); + } + } + } elsif (m/^severity\s+\#?(\d+)\s+([-0-9a-z]+)$/) { + $ok++; + $ref= $1; + $newseverity= $2; + if (!grep($_ eq $newseverity, @severities, "$gDefaultSeverity")) { + &transcript("Severity level \`$newseverity' is not known.\n". + "Recognised are: ".join(' ',@showseverities).".\n\n"); + } elsif (&setbug) { + $printseverity= $s_severity; + $printseverity= "$gDefaultSeverity" if $printseverity eq ''; + $action= "Severity set to \`$newseverity'."; + do { + &addmaintainers($s_package); + $s_severity= $newseverity; + } while (&getnextbug); + } + } elsif (m/^retitle\s+\#?(\d+)\s+(\S.*\S)\s*$/) { + $ok++; + $ref= $1; $newtitle= $2; + if (&getbug) { + &foundbug; + &addmaintainers($s_package); + $s_subject= $newtitle; + $action= "Changed $gBug title."; + &savebug; + &transcript("$action\n"); + if (length($s_done)) { + &transcript("(By the way, that $gBug is currently marked as done.)\n"); + } + &transcript("\n"); + } else { + ¬foundbug; + } + } elsif (m/^unmerge\s+\#?(\d+)$/) { + $ok++; + $ref= $1; + if (&setbug) { + if (!length($s_mergedwith)) { + &transcript("$gBug is not marked as being merged with any others.\n\n"); + &nochangebug; + } else { + $mergelowstate eq 'locked' || die "$mergelowstate ?"; + $action= "Disconnected #$ref from all other report(s)."; + @newmergelist= split(/ /,$s_mergedwith); + $discref= $ref; + do { + &addmaintainers($s_package); + $s_mergedwith= ($ref == $discref) ? '' + : join(' ',grep($_ ne $ref,@newmergelist)); + } while (&getnextbug); + } + } + } elsif (m/^merge\s(\d+(\s+\d+)+)\s*$/) { + $ok++; + @tomerge= sort { $a <=> $b } split(/\s+/,$1); + @newmergelist= (); + &getmerge; + while (defined($ref= shift(@tomerge))) { + &transcript("D| checking merge $ref\n") if $dl; + $ref+= 0; + next if grep($_ eq $ref,@newmergelist); + if (!&getbug) { ¬foundbug; @newmergelist=(); last } + &foundbug; + &transcript("D| adding $ref ($s_mergewith)\n") if $dl; + $mismatch= ''; + &checkmatch('package','m_package',$s_package); + &checkmatch('forwarded addr','m_forwarded',$s_forwarded); + &checkmatch('severity','m_severity',$s_severity); + &checkmatch('done mark','m_done',length($s_done) ? 'done' : 'open'); + if (length($mismatch)) { + &transcript("Mismatch - only $Bugs in same state can be merged:\n". + $mismatch."\n"); + &cancelbug; @newmergelist=(); last; + } + push(@newmergelist,$ref); + push(@tomerge,split(/ /,$s_mergedwith)); + &cancelbug; + } + if (@newmergelist) { + @newmergelist= sort { $a <=> $b } @newmergelist; + $action= "Merged @newmergelist."; + for $ref (@newmergelist) { + &getbug || die "huh ? $gBug $ref disappeared during merge"; + &addmaintainers($s_package); + $s_mergedwith= join(' ',grep($_ ne $ref,@newmergelist)); + &savebug; + } + &transcript("$action\n\n"); + } + &endmerge; + } else { + &transcript("Unknown command or malformed arguments to command.\n\n"); + if (++$unknowns >= 5) { + &transcript("Too many unknown commands, stopping here.\n\n"); + last; + } + } +} +if ($procline>$#msg) { + &transcript(">\nEnd of message, stopping processing here.\n\n"); +} +if (!$ok) { + &transcript("No commands successfully parsed; sending the help text(s).\n"); + &sendhelp; + &transcript("\n"); +} + +&transcript("MC\n") if $dl>1; +@maintccs= (); +for $maint (keys %maintccreasons) { +&transcript("MM|$maint|\n") if $dl>1; + next if $maint eq $replyto; + $reasonstring= ''; + $reasonsref= $maintccreasons{$maint}; +&transcript("MY|$maint|\n") if $dl>2; + for $p (sort keys %$reasonsref) { +&transcript("MP|$p|\n") if $dl>2; + $reasonstring.= ', ' if length($reasonstring); + $reasonstring.= $p.' ' if length($p); + $reasonstring.= join(' ',map("#$_",sort keys %{$$reasonsref{$p}})); + } + push(@maintccs,"$maint ($reasonstring)"); + push(@maintccaddrs,"$maint"); +} +if (@maintccs) { + &transcript("MC|@maintccs|\n") if $dl>2; + $maintccs= "Cc: ".join(",\n ",@maintccs)."\n"; +} + +$reply= < + +${transcript}Please contact me if you need assistance. + +$gMaintainer +(administrator, $gProject $gBugs database) +$extras +END + +$repliedshow= join(', ',$replyto,@maintccaddrs); +&filelock("lock/-1"); +open(AP,">>db/-1.log") || &quit("open db/-1.log: $!"); +print(AP + "\2\n$repliedshow\n\5\n$reply\n\3\n". + "\6\n". + "Request received from ". + &sani($header{'from'})."\n". + "to ".&sani($controlrequestaddr)."\n". + "\3\n". + "\7\n",@log,"\n\3\n") || &quit("writing db/-1.log: $!"); +close(AP) || &quit("open db/-1.log: $!"); +&unfilelock; +utime(time,time,"db"); + +&sendmailmessage($reply,$replyto,@maintccaddrs); + +unlink("incoming/P$nn") || &quit("unlinking incoming/P$nn: $!"); + +sub get_addresses { + return + map { $_->address() } + map { Mail::Address->parse($_) } @_; +} + +sub sendmailmessage { + local ($message,@recips) = @_; + print DEBUG "mailing to >@recips<\n"; + $c= open(D,"|-"); + defined($c) || &quit("mailing forking for sendmail: $!"); + if (!$c) { # ie, we are the child process + exec '/usr/lib/sendmail','-f'."$gMaintainerEmail",'-odi','-oem','-oi',get_addresses(@recips); + die $!; + } + print(D $message) || &quit("writing to sendmail process: $!"); + $!=0; close(D); $? && &quit("sendmail gave exit status $? ($!)"); + $midix++; +} + +sub sendhelp { + &sendtxthelpraw("bug-log-mailserver.txt","instructions for request\@$gEmailDomain"); + &sendtxthelpraw("bug-maint-mailcontrol.txt","instructions for control\@$gEmailDomain") + if $control; +} + +#sub unimplemented { +# &transcript("Sorry, command $_[0] not yet implemented.\n\n"); +#} + +sub checkmatch { + local ($string,$mvarname,$svarvalue) = @_; + local ($mvarvalue); + if (@newmergelist) { + eval "\$mvarvalue= \$$mvarname"; + &transcript("D| checkmatch \`$string' /$mvarname/$mvarvalue/$svarvalue/\n") + if $dl; + $mismatch .= + "Values for \`$string' don't match:\n". + " #$newmergelist[0] has \`$mvarvalue';\n". + " #$ref has \`$svarvalue'\n" + if $mvarvalue ne $svarvalue; + } else { + &transcript("D| setupmatch \`$string' /$mvarname/$svarvalue/\n") + if $dl; + eval "\$$mvarname= \$svarvalue"; + } +} + +# High-level bug manipulation calls +# Do announcements themselves +# +# Possible calling sequences: +# setbug (returns 0) +# +# setbug (returns 1) +# &transcript(something) +# nochangebug +# +# setbug (returns 1) +# $action= (something) +# do { +# (modify s_* variables) +# } while (getnextbug); + +sub nochangebug { + &dlen("nochangebug"); + $state eq 'single' || $state eq 'multiple' || die "$state ?"; + &cancelbug; + &endmerge if $manybugs; + $state= 'idle'; + &dlex("nochangebug"); +} + +sub setbug { + &dlen("setbug $ref"); + $state eq 'idle' || die "$state ?"; + if (!&getbug) { + ¬foundbug; + &dlex("setbug => 0s"); + return 0; + } + @thisbugmergelist= split(/ /,$s_mergedwith); + if (!@thisbugmergelist) { + &foundbug; + $manybugs= 0; + $state= 'single'; + $sref=$ref; + &dlex("setbug => 1s"); + return 1; + } + &cancelbug; + &getmerge; + $manybugs= 1; + if (!&getbug) { + ¬foundbug; + &endmerge; + &dlex("setbug => 0mc"); + return 0; + } + &foundbug; + $state= 'multiple'; $sref=$ref; + &dlex("setbug => 1m"); + return 1; +} + +sub getnextbug { + &dlen("getnextbug"); + $state eq 'single' || $state eq 'multiple' || die "$state ?"; + &savebug; + if (!$manybugs || !@thisbugmergelist) { + length($action) || die; + &transcript("$action\n$extramessage\n"); + &endmerge if $manybugs; + $state= 'idle'; + &dlex("getnextbug => 0"); + return 0; + } + $ref= shift(@thisbugmergelist); + &getbug || die "bug $ref disappeared"; + &foundbug; + &dlex("getnextbug => 1"); + return 1; +} + +# Low-level bug-manipulation calls +# Do no announcements +# +# getbug (returns 0) +# +# getbug (returns 1) +# cancelbug +# +# getmerge +# $action= (something) +# getbug (returns 1) +# savebug/cancelbug +# getbug (returns 1) +# savebug/cancelbug +# [getbug (returns 0)] +# &transcript("$action\n\n") +# endmerge + +sub notfoundbug { &transcript("$gBug number $ref not found.\n\n"); } +sub foundbug { &transcript("$gBug#$ref: $s_subject\n"); } + +sub getmerge { + &dlen("getmerge"); + $mergelowstate eq 'idle' || die "$mergelowstate ?"; + &filelock('lock/merge'); + $mergelowstate='locked'; + &dlex("getmerge"); +} + +sub endmerge { + &dlen("endmerge"); + $mergelowstate eq 'locked' || die "$mergelowstate ?"; + &unfilelock; + $mergelowstate='idle'; + &dlex("endmerge"); +} + +sub getbug { + &dlen("getbug $ref"); + $lowstate eq 'idle' || die "$state ?"; + if (&lockreadbug($ref)) { + $sref= $ref; + $lowstate= "open"; + &dlex("getbug => 1"); + $extramessage=''; + return 1; + } + $lowstate= 'idle'; + &dlex("getbug => 0"); + return 0; +} + +sub cancelbug { + &dlen("cancelbug"); + $lowstate eq 'open' || die "$state ?"; + &unfilelock; + $lowstate= 'idle'; + &dlex("cancelbug"); +} + +sub savebug { + &dlen("savebug $ref"); + $lowstate eq 'open' || die "$lowstate ?"; + length($action) || die; + $ref == $sref || die "read $sref but saving $ref ?"; + open(L,">>db/$ref.log") || &quit("opening db/$ref.log: $!"); + print(L + "\6\n". + "".&sani($action)."\n". + "Request was from ".&sani($header{'from'})."\n". + "to ".&sani($controlrequestaddr).". \n". + "\3\n". + "\7\n",@log,"\n\3\n") || &quit("writing db/$ref.log: $!"); + close(L) || &quit("closing db/$ref.log: $!"); + open(S,">db/$ref.status.new") || &quit("opening db/$ref.status.new: $!"); + print(S + "$s_originator\n". + "$s_date\n". + "$s_subject\n". + "$s_msgid\n". + "$s_package\n". + "$s_keywords\n". + "$s_done\n". + "$s_forwarded\n". + "$s_mergedwith\n". + "$s_severity\n") || &quit("writing db/$ref.status.new: $!"); + close(S) || &quit("closing db/$ref.status.new: $!"); + rename("db/$ref.status.new","db/$ref.status") || + &quit("installing new db/$ref.status: $!"); + &unfilelock; + $lowstate= "idle"; + &dlex("savebug"); +} + +sub dlen { + return if !$dl; + &transcript("C> @_ ($state $lowstate $mergelowstate)\n"); +} + +sub dlex { + return if !$dl; + &transcript("R> @_ ($state $lowstate $mergelowstate)\n"); +} + +sub transcript { + print(DEBUG $_[0]); + $transcript.= $_[0]; +} + +sub sendlynxdoc { + &sendlynxdocraw; + &transcript("\n"); + $ok++; +} + +sub sendtxthelp { + &sendtxthelpraw; + &transcript("\n"); + $ok++; +} + +sub sendtxthelpraw { + local ($relpath,$description) = @_; + $doc=''; + open(D,"$gDocDir/$relpath") || &quit("open doc file $relpath: $!"); + while() { $doc.=$_; } + close(D); + &transcript("Sending $description in separate message.\n"); + &sendmailmessage(< + +END + $ok++; +} + +sub sendlynxdocraw { + local ($relpath,$description) = @_; + $doc=''; + open(L,"lynx -nolist -dump $wwwbase/$relpath 2>&1 |") || &quit("fork for lynx: $!"); + while() { $doc.=$_; } + $!=0; close(L); + if ($? == 255 && $doc =~ m/^\n*lynx: Can\'t access start file/) { + &transcript("Information ($description) is not available -\n". + "perhaps the $gBug does not exist or is not on the WWW yet.\n"); + $ok++; + } elsif ($?) { + &transcript("Error getting $description (code $? $!):\n$doc\n"); + } else { + &transcript("Sending $description.\n"); + &sendmailmessage(< + +END + $ok++; + } +} + +sub addccaddress { + my ($cca) = @_; + $maintccreasons{$cca}{''}{$ref}= 1; +} + +sub addmaintainers { + # Data structure is: + # maintainer email address &c -> assoc of packages -> assoc of bug#'s + my $p, $addmaint, $pshow; + &ensuremaintainersloaded; + $anymaintfound=0; $anymaintnotfound=0; + for $p (split(m/[ \t?,()]+/,$_[0])) { + $p =~ y/A-Z/a-z/; + $pshow= ($p =~ m/[-+.a-z0-9]+/ ? $& : ''); + if (defined($maintainerof{$p})) { + $addmaint= $maintainerof{$p}; +&transcript("MR|$addmaint|$p|$ref|\n") if $dl>2; + $maintccreasons{$addmaint}{$p}{$ref}= 1; +print DEBUG "maintainer add >$p|$addmaint<\n"; + } else { +print DEBUG "maintainer none >$p<\n"; + } + } +} + +sub ensuremaintainersloaded { + my $a,$b; + return if $maintainersloaded++; + open(MAINT,"$gMaintainerFile") || die &quit("maintainers open: $!"); + while () { + m/^(\S+)\s+(\S.*\S)\n$/ || &quit("maintainers bogus \`$_'"); + $a= $1; $b= $2; $a =~ y/A-Z/a-z/; + $maintainerof{$1}= $2; + } + close(MAINT); +} diff --git a/scripts/summary.in b/scripts/summary.in new file mode 100755 index 0000000..7dbb185 --- /dev/null +++ b/scripts/summary.in @@ -0,0 +1,88 @@ +#!/usr/bin/perl + +require('/etc/debbugs/config'); +require('/usr/lib/debbugs/errorlib'); +chdir("$gSpoolDir") || die "chdir spool: $!\n"; + +#open(DEBUG,">&4"); + +$mode= shift(@ARGV); + +open(M,"$gMaintainerFile") || &quit("open $gMaintainerFile: $!"); +while () { + m/^(\S+)\s+(\S.*\S)\s*$/ || warn "$_ ?"; + ($a,$b)=($1,$2); + $a =~ y/A-Z/a-z/; + $maintainer{$a}= $b; +} +close(M); + +defined($startdate= time) || &quit("failed to get time: $!"); + +opendir(DIR,"db") || &quit("opendir db: $!\n"); +@list= grep(m/^\d+\.status$/,readdir(DIR)); +grep(s/\.status$//,@list); +@list= sort { $a <=> $b } @list; + +$head= $mode eq 'bymaint' + ? ' Package Ref Subject' + : ' Ref Package Keywords/Subject Package maintainer'; +$amonths=-1; + +while (length($f=shift(@list))) { + &filelock("lock/$f"); + if (!open(S,"db/$f.status")) { &unlinklock; next; } + chop($s_originator= ); + chop($s_date= ); + chop($s_subject= ); + chop($s_msgid= ); + chop($s_package= ); + chop($s_keywords= ); + chop($s_done= ); + chop($s_forwarded= ); + $_= $s_package; y/A-Z/a-z/; $_= $` if m/[^-+._a-z0-9]/; + $s_maintainer= + defined($maintainer{$_}) ? $maintainer{$_} : + length($_) ? "(unknown -- \`$_')" : + "(unknown)"; + if ($mode eq 'undone' || $mode eq 'veryold') { + &unfilelock; + next if length($s_done) || length($s_forwarded); + $cmonths= int(($startdate - $s_date)/2592000); # 3600*24*30 (30 days) + next if $mode eq 'veryold' && $cmonths < 2; + if ($cmonths != $amonths) { + $msg= $cmonths == 0 ? "Submitted in the last month" : + $cmonths == 1 ? "Over one month old" : + $cmonths == 2 ? "Over two months old - attention is required" : + "OVER $cmonths MONTHS OLD - ATTENTION IS REQUIRED"; + print "\n$msg:\n$head\n"; + $amonths= $cmonths; + } + printf("%6d %-10.10s %-30.30s %-.31s\n", $f, $s_package, + (length($s_keywords) ? $s_keywords.'/' : '').$s_subject, + $s_maintainer) || &quit("output undone: $!"); + } elsif ($mode eq 'bymaint') { + &unfilelock; + next if length($s_done) || length($s_forwarded); + $string{$f}= + sprintf(" %-10.10s %6d %-.59s\n", $s_package, $f, $s_subject); + $s_maintainer= "(unknown)" if $s_maintainer =~ m/^\(unknown \-\-/; + $maintainercnt{$s_maintainer}++; + $maintainerlist{$s_maintainer}.= " $f"; + } else { + &quit("badmode $mode"); + } +} + +if ($mode eq 'bymaint') { + print("$head\n") || &quit("output head: $!"); + for $m (sort { $maintainercnt{$a} <=> $maintainercnt{$b} } keys %maintainercnt) { + printf("\n%s (%d $gBugs):\n",$m,$maintainercnt{$m}) + || &quit("output mainthead: $!"); + for $i (sort { $string{$a} cmp $string{$b} } split(/ /,$maintainerlist{$m})) { + printf($string{$i}) || &quit("output 1bymaint: $!"); + } + } +} + +close(STDOUT) || &quit("close stdout: $!"); diff --git a/scripts/text.in b/scripts/text.in new file mode 100644 index 0000000..d70377a --- /dev/null +++ b/scripts/text.in @@ -0,0 +1,265 @@ +############################################################################ +# Here is a blurb for any mirrors of the web site. Here's a sample: +# +#$gHTMLCopies = "Copies of the logs are available on the World Wide Web at
    +# http://mirror1.domain
    +# http://mirror2.domain"; +############################################################################ +$gHTMLCopies = ""; + + +############################################################################ +# notice other links you want to note, like your list archives or project +# home page. +# +#$gHTMLOtherPages = "Other Links of note:
    +# The Debian Project
    +# Description of URL"; +############################################################################ +$gHTMLOtherPages = ""; + + +############################################################################ +# list of other links you want to note, like your list archives or project +# home page. Some pages already have links in a list, this adds them to +# the end of the list. +# +#$gHTMLOtherPageList = "

  • +# The Debian Project +#
  • Description of URL"; +############################################################################ +$gHTMLOtherPageList = ""; + + +############################################################################ +# gives explanation of bad maintainer situation and instructions on how to +# correct. +############################################################################ +$gBadMaintHtml = ""; + + +############################################################################ +# give directions here for how to find the proper title for Package: +# pseudo header line. +############################################################################ +$gHTMLFindPackage = ""; + + +############################################################################ +# If you have pseudo packages, place a blurb here. For example: +# $gHTMLPseudoDesc = "There are some pseudo-packages available for putting in +# the Package line when reporting a $gBug in something other than an +# actual $gProject software package. There is +# a list of these on the $gBugs WWW +# pages."; +############################################################################ +$gHTMLPseudoDesc = ""; + + +############################################################################ +# List any extra information you would like included in bug reports +############################################################################ +$gXtraBugInfo = ""; + + +############################################################################ +# List any extra information you would like about reporting bugs +############################################################################ +$gXtraReportingInfo = ""; + + +############################################################################ +# Process used by system to create Maintainers index file +############################################################################ +$gCreateMaintainers = ""; + + +########################################################################### +# You shouldn't have to modify anything below here unless it's for personal +# preference. Be very careful and don't touch unless you *know* what +# you're doing. Much of the stuff has hardcoded duplicates elsewhere. + + +############################################################################ +# Description of the severities +############################################################################ +$gHTMLSeverityDesc = "
    critical +
    makes unrelated software on the system (or the whole system) break, or + causes serious data loss, or introduces a security hole on systems where + you install the package. + +
    grave +
    makes the package in question unuseable or mostly so, or causes data + loss, or introduces a security hole allowing access to the accounts of + users who use the package. + +
    normal +
    the default value, for normal $gBugs. + +
    wishlist +
    for any feature request, and also for any $gBugs that are very difficult + to fix due to major design considerations."; + +############################################################################ +# shows up at the end of (most) html pages. You shouldn't have +############################################################################ +$gHTMLTail = "
    $gMaintainer / + $gMaintainerEmail. Last modifed: + + SUBSTITUTE_DTIME + + (timestamp page available). + +

    + Debian $gBug tracking system
    + copyright 1997 nCipher Corporation Ltd,
    + copyright 1994-1997 Ian Jackson,
    + copyright 1995 Steven Brenner.
    + + Available under the GPL. +

    + + "; + +############################################################################ +# Message on when reports are purged. 28 days is hardcoded. +############################################################################ +$gHTMLExpireNote = "(Closed $gBugs are cleaned out 28 days after the last related message is received.)"; + +############################################################################ +# Makeup of the stamp page +############################################################################ +$gHTMLStamp = "$gProject $gBugs - timestamp page + +

    Is this $gBug log or mirror up to date?

    + + Unlike all the other $gBug pages, this small timestamp page is updated every + time the update check job runs. If the timestamp here is recent it\'s + likely that the mirror in which you\'re reading it is up to date. +

    + The last + update + was at + SUBSTITUTE_DTIME; + The logs are usually checked every hour and updated if necessary. +

    + For the $gBug index or for other information about $gProject and the $gBug + system, see the $gBug system main contents page. + +


    +
    + $gMaintainerEmail, + through the $gProject $gBug database +
    + "; + +############################################################################ +# Makeup of the indices pages +############################################################################ +$gFullIndex = "$gProject $gBugs - full index + +

    $gProject $gBug report logs - index

    + + This index gives access to $gBugs sent to submit\@$gEmailDomain + but not yet marked as done, and to $gBugs marked as done but not yet purged + from the database (this happens 28 days after the last message relating to + the report). +

    + For other kinds of indices or for other information about $gProject and + the $gBug system, see $gBug system top-level contents WWW + page. + + + "; + +$gJunkIndex = "$gProject $gBug reports - Junk + +

    $gProject $gBug reports - Junk

    + + This is the index page for logs of messages not associated with a specific + $gBug report. +

    + For other kinds of indices or for other information about $gProject and + the $gBug system, see $gBug system top-level contents WWW + page. + + + "; + +$gMaintIndex = "$gProject $gBug reports by maintainer + +

    $gProject $gBug reports by maintainer

    + + This page lists the package maintainers against whose packages there are + outstanding, fowarded or recently-closed $gBug reports. A maintainer who + has several versions of their email address in the Maintainer + package control file field may appear several times.

    + If the maintainers information here is not accurate, please see + the developers\' + instructions to find how this can happen and what to do about it.

    + For other kinds of indices or for other information about $gProject and + the $gBug system, see $gBug system top-level contents WWW + page. + + + "; + +$gPackageIndex = "$gProject $gBug reports by package + +

    $gProject $gBug reports by package

    + + This page lists the package against which there are outstanding, fowarded or + recently-closed $gBug reports. A multi-binary package may appear several + times, once for each binary package name and once for the source package + name (if it is different).

    + For other kinds of indices or for other information about $gProject and + the $gBug system, see $gBug system top-level contents WWW + page. + + + "; + +$gSummaryIndex = "$gProject $gBug report logs - summary index + +

    $gProject $gBug report logs - summary index

    + + This summary index breiefly lists $gBugs sent to submit\@$gEmailDomain + but not yet marked as done, or as fowarded to an upstream author. + Here they are sorted by reference number (and therefore by submission date, + too).

    + For other kinds of indices or for other information about $gProject and + the $gBug system, see $gBug system top-level contents WWW + page. + + + "; + +$gPackageLog = "$gProject $gBug report logs - index by package + +

    $gProject $gBug report logs - index by package

    + + This summary index breiefly lists $gBugs sent to submit\@$gEmailDomain + but not yet marked as done, or as fowarded to an upstream author. + Here they are sorted by package name.

    + For other kinds of indices or for other information about $gProject and + the $gBug system, see $gBug system top-level contents WWW + page. + + + "; + +$gPseudoIndex = "$gProject $gBug report pseudo-packages + +

    $gProject $gBug report pseudo-packages

    + + This page lists the pseudo-packages available for use in the + Package: line in $gBug reports.

    + + See the instructions for reporting a + $gBug for details of how to specify a Package: line.

    + For other kinds of indices or for other information about $gProject and + the $gBug system, see $gBug system top-level contents WWW + page. + + + "; -- 2.39.2