--- /dev/null
+#!/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 <<END;
+Content-Type: text/html
+
+<html><head><title>Bug number not numeric</title>
+</head><body>
+<h1>Invalid input to specific bug fetch form</h1>
+
+You must type a number, being the bug reference number.
+There should be no nondigits in your entry.
+</html>
+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 <<END;
+Content-Type: text/html
+
+<html><head><title>Package name contains invalid characters</title>
+</head><body>
+<h1>Invalid input to package buglist fetch form</h1>
+
+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).
+</html>
+END
+ exit(0);
+ }
+ $suburl= "pa/l$_.html";
+} else {
+ print <<END;
+Content-Type: text/plain
+
+Please use the real DBC_WHO form. (invalid type value)
+END
+ exit(0);
+}
+
+$base= $ENV{'HTTP_REFERER'};
+if ($base =~ s:/Bugs/.*$::) {
+ for $y (keys %map) {
+ $base= $map{$y} if $base eq $y;
+ }
+} else {
+ $base= $in{'base'};
+}
+
+$newurl= "$base/Bugs/db/$suburl";
+print <<END;
+Status: 301 Redirect
+Location: $newurl
+
+The bug report data you are looking for ($suburl)
+is available <A href="$newurl">here</A>.
+
+(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);
--- /dev/null
+#!/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,'<form><input type="submit"> Data: <input name="myfield">';
+#}
+
+# 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 <head> of a document and the beginning of the body
+# with the title and a body <h1> header as specified by the parameter
+
+sub HtmlTop
+{
+ local ($title) = @_;
+
+ return <<END_OF_TEXT;
+<html>
+<head>
+<title>$title</title>
+</head>
+<body>
+<h1>$title</h1>
+END_OF_TEXT
+}
+
+# Html Bot
+# Returns the </body>, </html> codes for the bottom of every HTML page
+
+sub HtmlBot
+{
+ return "</body>\n</html>\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 "<html><head><title>$msg[0]</title></head>\n";
+ print "<body><h1>$msg[0]</h1>\n";
+ foreach $i (1 .. $#msg) {
+ print "<p>$msg[$i]</p>\n";
+ }
+ print "</body></html>\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<dl compact>\n";
+ foreach $key (sort keys(%in)) {
+ foreach (split("\0", $in{$key})) {
+ ($out = $_) =~ s/\n/<br>\n/g;
+ $output .= "<dt><b>$key</b>\n <dd><i>$out</i><br>\n";
+ }
+ }
+ $output .= "</dl>\n";
+ $* = $old;
+
+ return $output;
+}
+
+# PrintVariablesShort
+# Now obsolete; just calls PrintVariables
+
+sub PrintVariablesShort {
+ return &PrintVariables(@_);
+}
+
+1; #return true
+
+
--- /dev/null
+debbugs (2.2-3) unstable; urgency=low
+
+ * Perl Depends change
+
+ -- Darren Benham <gecko@debian.org> Tue, 27 Jul 1999 11:27:22 -0700
+
+debbugs (2.2-2) unstable; urgency=low
+
+ * Added mailtools to dependency
+
+ -- Darren Benham <gecko@debian.org> 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 <gecko@debian.org> 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 <gecko@debian.org> 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 <gecko@debian.org> Sat, 27 Mar 1999 10:37:37 -0800
+
+debbugs (1.0-4) unstable; urgency=low
+
+ * Tried a stopgap measure for config files
+
+ -- Darren Benham <gecko@debian.org> 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 <gecko@debian.org> 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 <gecko@debian.org> Wed, 10 Feb 1999 10:39:18 -0800
+
+debbugs (1.0-1) unstable; urgency=low
+
+ * Initial Release.
+
+ -- Darren Benham <gecko@debian.org> Thu, 21 Jan 1999 20:55:51 -0800
+
+Local variables:
+mode: debian-changelog
+add-log-mailing-address: "gecko@debian.org"
+End:
--- /dev/null
+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 <ijackson@chiark.greenend.org.uk>
+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 <gecko@debian.org>
+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.
--- /dev/null
+#!/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:$/ .. /^\<hr\>/' \
+ /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
--- /dev/null
+/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
--- /dev/null
+$gAccessHtml = <<HTML_END
+<HTML>
+<HEAD>
+ <TITLE>$gProject $gBugs - Accessing the logs</TITLE>
+ <LINK REV="made" HREF="mailto:$gMaintainerEmail">
+</HEAD>
+<BODY>
+<A NAME="developers">
+ <H1>Accessing $gBug reports in the tracking system logs</H1>
+</A>
+
+Each message received at or sent by the $gBug processing system is
+logged and made available in a number of ways.
+<P>
+
+$gHTMLCopies
+
+There is a <A HREF="server-request.html">mailserver</A> which can send
+$gBug reports as plain text on request. To use it send the word
+<CODE>help</CODE> as the sole contents of an email to
+<CODE>request</CODE> (the <CODE>Subject</CODE> of the
+message is ignored), or read the instructions on the World Wide Web or
+in the file <CODE>bug-log-mailserver.txt</CODE>.
+
+<HR>
+
+Other pages:
+<UL>
+ <LI><A href="./">$gBug tracking system main contents page.</A>
+ <LI><A href="Reporting.html">Instructions for reporting $gBugs.</A>
+ <LI><A href="Developer.html">Developers' information regarding the $gBug processing system.</A>
+ <LI><A href="db/ix/full.html">Full list of outstanding and recent $gBug reports.</A>
+ <LI><A href="db/ix/packages.html">Packages with $gBug reports.</A>
+ <LI><A href="db/ix/maintainers.html">Maintainers of packages with $gBug reports.</A>
+
+$gHTMLOtherPageList
+
+</ul>
+
+$gHTMLTail
+
+HTML_END
--- /dev/null
+$gDeveloperHtml = <<HTML_END
+<HTML>
+<HEAD>
+ <title>$gProject - Developers' information</title>
+ <link rev="made" href="mailto:$gMaintainerEmail">
+</head>
+<body>
+ <h1><A name="developers">Developers' information regarding the $gBug processing system</A></h1>
+
+Initially, a $gBug report is submitted by a user as an ordinary mail
+message to <code>submit\@$gEmailDomain</code>. This will then be
+given a number, acknowledged to the user, and forwarded to a mailing
+list (if configured). If the submitter included a <code>Package</code>
+line listing a package with a known maintainer the maintainer will get
+a copy too.
+<p>
+
+The <code>Subject</code> line will have
+<code>$gBug#</code><var>nnn</var><code>:</code> added, and the
+<code>Reply-To</code> will be set to include both the submitter of the
+report and <var>nnn</var><code>\@$gEmailDomain</code>.
+<p>
+
+<h2>Closing $gBug reports</h2>
+
+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 <code>To</code> field to say
+<var>nnn</var><code>-done\@$gEmailDomain</code> instead of
+<var>nnn</var><code>\@$gEmailDomain</code>
+(<var>nnn</var><code>-close</code> is provided as an alias for
+<var>nnn</var><code>-done</code>).
+<p>
+
+The address of the original submitter of the $gBug report will be
+included in the default <code>To</code> field, because the $gBug system
+included it in the <code>Reply-To</code>.
+<p>
+
+`Done' messages are forwarded to a mailing list if the mailing list has been
+set up.
+<P>
+
+The person closing the $gBug and the person who submitted it will each
+get a notification about the change in status of the report.
+
+<h2>Followup messages</h2>
+
+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 <var>nnn</var><code>\@$gEmailDomain</code> 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.
+<p>
+
+If you wish to send a followup message which is not appropriate for
+any mailing list you can do so by sending it to
+<var>nnn</var><code>-quiet\@$gEmailDomain</code> or
+<var>nnn</var><code>-maintonly\@$gEmailDomain</code>, which only file it (not
+forwarding it anywhere) and send it on only to the maintainer of the
+package in question, respectively.
+<p>
+
+Do <em>not</em> 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
+<var>nnn</var><code>\@$gEmailDomain</code> and to
+<code>submit\@$gEmailDomain</code>, because the $gBug system will then
+get two copies of it and each one will be forwarded to the designated
+mailing list separately.
+<p>
+
+<h2><A name="severities">Severity levels</A></h2>
+
+The $gBug system records a severity level with each $gBug report. This is
+set to <code>$gDefaultSeverity</code> by default, but can be overridden either by
+supplying a <code>Severity</code> line in the psuedo-header when the
+$gBug is submitted (see the
+<A href="Reporting.html#psuedoheader">instructions for reporting
+$gBugs</A>), or by using the <code>severity</code> command with the
+<A href="#requestserv">control request server</A>.
+
+<p>
+
+The severity levels are:
+
+<dl>
+$gHTMLSeverityDesc
+</dl>
+
+<h2><A name="forward">Recording that you have passed on a $gBug report</A></h2>
+
+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:
+<p>
+
+Make sure that the <code>To</code> 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
+<var>nnn</var><code>-forwarded\@$gEmailDomain</code> in the
+<code>CC</code> field.
+<p>
+
+Ask the author to preserve the <code>CC</code> to
+<var>nnn</var><code>-forwarded\@$gEmailDomain</code> when they reply, so that
+the $gBug tracking system will file their reply with the original
+report.
+<p>
+
+When the $gBug tracking system gets a message at
+<var>nnn</var><code>-forwarded</code> it will mark the relevant $gBug as
+having been forwarded to the address(es) in the <code>To</code> field
+of the message it gets.
+<p>
+
+You can also manipulate the `forwarded to' information by sending messages to
+<A href="server-control.html"><code>control\@$gEmailDomain</code></A>.
+
+<h2>Summary postings</h2>
+
+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.
+<p>
+
+$gBadMaintHtml
+
+<h2><A name="requestserv">Reopening, reassigning and manipulating $gBugs</A></h2>
+
+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 <code>control\@$gEmailDomain</code>.
+<p>
+
+The <A href="server-control.html">format of these messages</A> is
+described in another document available on the World Wide Web or in
+the file <code>bug-maint-mailcontrol.txt</code>. A plain text version
+can also be obtained by mailing the word <code>help</code> to the
+server at the address above.
+
+<h2>More-or-less obsolete subject-scanning feature</h2>
+(this is likely to be removed the next version)<BR>
+Messages that arrive at <code>submit</code> or <code>$gBugs</code> whose
+Subject starts <code>Bug#</code><var>nnn</var> will be treated as
+having been sent to <var>nnn</var><code>\@$gEmailDomain</code>. This is both
+for backwards compatibility with mail forwarded from the old
+addresses, and to catch followup mail sent to <code>submit</code> by
+mistake (for example, by using reply to all recipients).
+
+<p>
+
+A similar scheme operates for <code>maintonly</code>,
+<code>done</code>, <code>quiet</code> and <code>forwarded</code>,
+which treat mail arriving with a Subject tag as having been sent to
+the corresponding <var>nnn-whatever</var><code>\@$gEmailDomain</code> address.
+
+<p>
+
+Messages arriving at plain <code>forwarded</code> and
+<code>done</code> - 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.
+
+<h2><A name="future">Future plans</A></h2>
+
+At some point the <code>Package:</code> secondary header field may
+become mandatory - at the moment omitting it just produces a warning
+message.
+
+<hr>
+Other pages:
+<ul>
+<li><A href="./">$gBug tracking system main contents page.</A>
+<li><A href="Reporting.html">Instructions for reporting $gBugs.</A>
+<li><A href="Access.html">Accessing the $gBug tracking logs other than by WWW.</A>
+<li><A href="server-refcard.html">Mailservers' reference card.</A>
+<li><A href="db/ix/full.html">Full list of outstanding and recent $gBug reports.</A>
+<li><A href="db/ix/packages.html">Packages with $gBug reports.</A>
+<li><A href="db/ix/maintainers.html">Maintainers of packages with $gBug reports.</A>
+
+$gHTMLOtherPageList
+
+</ul>
+
+$gHTMLTail
+
+HTML_END
--- /dev/null
+$gReportingHtml = <<HTML_END
+<html><head><title>$gProject $gBugs - how to report a $gBug</title>
+<link rev="made" href="mailto:$gMaintainerEmail">
+</head><body>
+<h1>How to report a $gBug in $gProject</h1>
+
+Send mail to
+<A href="mailto:submit\@$gEmailDomain"><code>submit\@$gEmailDomain</code></A>,
+as described below.
+<p>
+
+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
+<code>submit\@$gEmailDomain</code> (for details of how to do this right, see
+<A href="#xcc">below</A>).
+<p>
+
+Lists of currently-outstanding $gBugs are available <A href="./">on
+the World Wide Web</A> and <A href="Access.html">elsewhere</A> - see
+other documents for details.
+<p>
+
+You should put a pseudo-header at the start of the body of the
+message, with the <code>Package:</code> and <code>Version:</code>
+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
+
+<em>See below for <A href="#details">further requirements</A></em>.
+<p>
+
+$gHTMLPseudoDesc
+
+<h2><A name="example">Example</A></h2>
+
+A $gBug report, with mail header, looks something like this:
+<pre>
+ To: submit\@$gEmailDomain
+ From: diligent\@testing.linux.org
+ Subject: Hello says `goodbye'
+<A name="psuedoheader">
+ Package: hello</A>
+ 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.
+</pre>
+
+<h2><A name="details">Please include in your report:</A></h2>
+
+<ul>
+<li>The <em>exact</em> and <em>complete</em> text of any error
+messages printed or logged. This is very important!
+<li>Exactly what you typed or did to demonstrate the problem.
+<li>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.
+<li>A suggested fix, or even a patch, if you have one.
+<li>Details of the configuration of the program with the problem.
+Include the complete text of its configuration files.
+$gXtraBugInfo
+</ul>
+
+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.).
+
+<p>
+
+Of course, like any email, you should include a clear, descriptive
+<code>Subject</code> 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 !
+
+<h2><A name="xcc">Sending copies of $gBug reports to other addresses</A></h2>
+
+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.
+<p>
+
+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 <code>Reply-To</code> field and the <code>Subject</code> line.
+When the recipients reply they will probably preserve the
+<code>submit\@$gEmailDomain</code> entry in the header and have their
+message filed as a new $gBug report. This leads to many duplicated
+reports.
+<p>
+
+The <em>right</em> way to do this is to use the
+<code>X-$gProject-CC</code> header. Add a line like this to your
+message's mail header (not to the psuedo header with the
+<code>Package</code> field):
+<pre>
+ X-$gProject-CC: other-list\@cosmic.edu
+</pre>
+This will cause the $gBug tracking system to send a copy of your report
+to the address(es) in the <code>X-$gProject-CC</code> line as well as to
+any mailing list.
+<p>
+
+This feature can often be combined usefully with mailing
+<code>quiet</code> - see below.
+
+
+<h2><A name="severities">Severity levels</A></h2>
+
+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.
+<p>
+
+To assign a severity level put a
+<code>Severity: <var>severity</var></code> line in the psuedo-header,
+together with <code>Package</code> and <code>Version</code>. The
+severity levels available are described in the
+<A href="Developer.html#severities">developers' documentation</A>.
+
+
+<h2>Not forwarding to the mailing list - minor $gBug reports</h2>
+
+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 <code>maintonly\@$gEmailDomain</code> or <code>quiet\@$gEmailDomain</code>.
+<code>maintonly</code> will send the report on to the package
+maintainer (provided you supply a correct <code>Package</code> line in
+the pseudo-header and the maintainer is known), and <code>quiet</code>
+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).
+<p>
+
+If you do this the $gBug system will set the <code>Reply-To</code> of
+any forwarded message so that replies will by default be processed in
+the same way as the original report.
+
+<h3>Unknown packages or $gBugs with no <code>Package</code> key</h3>
+
+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 <code>maintonly</code> was used.
+<p>
+
+When sending to <code>maintonly\@$gEmailDomain</code> or
+<var>nnn</var><code>-maintonly\@$gEmailDomain</code> you should make sure that
+the $gBug report is assigned to the right package, by putting a correct
+<code>Package</code> at the top of an original submission of a report,
+or by using <A href="server-control.html">the
+<code>control\@$gEmailDomain</code> service</A> to (re)assign the report
+appropriately first if it isn't correct already.
+
+$gXtraReportingInfo
+
+<hr>
+Other pages:
+<ul>
+<li><A href="./">Bug tracking system main contents page.</A>
+<li><A href="Developer.html">Developers'
+information regarding the $gBug processing system.</A>
+<li><A href="Access.html">Accessing the $gBug tracking logs other than by WWW.</A>
+<li><A href="db/ix/full.html">Full list of outstanding and recent $gBug reports.</A>
+<li><A href="db/ix/packages.html">Packages with $gBug reports.</A>
+<li><A href="db/ix/maintainers.html">Maintainers of packages with $gBug reports.</A>
+
+$gHTMLOtherPageList
+
+</ul>
+
+$gHTMLEnd
+
+HTML_END
--- /dev/null
+$gIndexHtml = <<HTML_END
+<html><head>
+<title>$gProject $gBug tracking system</title>
+<link rev="made" href="mailto:$gMaintainerEmail">
+</head><body>
+<h1>$gProject $gBug tracking system main contents page</h1>
+
+$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
+
+<h2>Documentation about the $gBug tracking system</h2>
+
+<ul>
+<li><A href="Reporting.html">Instructions for reporting a $gBug.</A>
+<li><A href="Access.html">Ways of accessing the $gBug reporting logs.</A>
+<li><A href="server-request.html">Requesting $gBug reports by email.</A>
+<li><A href="Developer.html">Developers' information on how to use the system.</A>
+<li><A href="server-control.html">Developers' information on
+manipulating $gBugs by email.</A>
+<li><A href="server-refcard.html">Mailservers' reference card.</A>
+</ul>
+
+<h2>Reviewing $gBug reports on the WWW</h2>
+
+<ul>
+<li><A href="db/ix/full.html">Full list of outstanding and recent $gBug reports.</A>
+<li><A href="db/ix/packages.html">Index of packages with $gBug reports.</A>
+<li><A href="db/ix/maintainers.html">Index of maintainers of packages with $gBug reports.</A>
+<li>Outstanding
+<A href="db/si/pendingcritical.html">critical</A>,
+<A href="db/si/pendinggrave.html">grave</A> and
+<A href="db/si/pendingnormal.html">normal</A> $gBugs and
+<A href="db/si/pendingwishlist.html">wishlist</A> items.
+<li>Forwarded
+<A href="db/si/forwardedcritical.html">critical</A>,
+<A href="db/si/forwardedgrave.html">grave</A> and
+<A href="db/si/forwardednormal.html">normal</A> $gBugs and
+<A href="db/si/forwardedwishlist.html">wishlist</A> items.
+<li>Resolved
+<A href="db/si/donecritical.html">critical</A>,
+<A href="db/si/donegrave.html">grave</A> and
+<A href="db/si/donenormal.html">normal</A> $gBugs and
+<A href="db/si/donewishlist.html">wishlist</A> items.
+<li><A href="db/ix/psummary.html">Summary of outstanding reports, sorted by package.</A>
+<li><A href="db/ix/summary.html">Summary of outstanding reports, sorted by number.</A>
+<li><A href="db/ju/junk.html">Logs not associated with a particular $gBug report.</A>
+<li><A href="db/ix/zstamp.html">Time stamp page (for checking that mirror is current).</A>
+</ul>
+
+Each closed $gBug report is expired from these logs $gRemoveAge days after the
+last message relating to it is received and filed.
+
+<h3>Find a $gBug report by reference number</h2>
+
+<form method="get" action="$gCGIDomain/bugs-fetch2.pl">
+<input type="hidden" name="type" value="ref">
+<input type="text" size="10" name="ref" value="">
+<input type="hidden" name="base" value="http://$gWebDomain">
+<input type="submit" value="Fetch">
+</form>
+`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 <A href="db/ix/zstamp.html">timestamp page</A>.
+
+<h3>Find a $gBug report by package</h2>
+
+<form method="get" action="$gCGIDomain/bugs-fetch2.pl">
+<input type="hidden" name="type" value="package">
+<input type="text" size="30" name="package" value="">
+<input type="hidden" name="base" value="http://$gWebDomain">
+<input type="submit" value="Fetch">
+</form>
+`Not found' means that that package does not exist or does not have
+any outstanding or recently closed $gBug reports.
+
+$gHTMLOtherPages
+
+$gHTMLTail
+
+HTML_END
+
--- /dev/null
+$gControlHtml = <<HTML_END
+<html><head>
+<html><head>
+<title>$gProject $gBug system - control mail server commands</title>
+<link rev="made" href="mailto:$gMaintainerEmail">
+</head><body>
+<h1>Introduction to the $gBug control and manipulation mailserver</h1>
+
+In addition to the mailserver on <code>request\@$gEmailDomain</code>
+which allows the retrieval of $gBug data and documentation by email,
+there is another server on <code>control\@$gEmailDomain</code> which
+also allows $gBug reports to be manipulated in various ways.
+<p>
+
+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.
+<p>
+
+Please see the
+<A href="server-request.html#introduction">introduction to
+the request server</A>
+available on the World Wide Web, in the file
+<code>bug-maint-mailcontrol.txt</code>, or by sending
+<code>help</code> to either mailserver, for details of the basics of
+operating the mailservers and the common commands available when
+mailing either address.
+<p>
+
+The <A href="server-refcard.html">reference card</A> for the
+mailservers is available via the WWW, in
+<code>bug-mailserver-refcard.txt</code> or by email using the
+<code>refcard</code> command).
+
+<h1>Commands available only at the control mailserver</h1>
+
+<dl>
+
+<dt><code>close</code> <var>bugnumber</var>
+<dd>
+
+Close $gBug report #<var>bugnumber</var>.
+<p>
+
+A notification is sent to the user who reported the $gBug, but (in
+contrast to mailing <var>bugnumber</var><code>-done@$gEmailDomain</code>) the
+text of the mail which caused the $gBug to be closed is <em>not</em>
+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.
+
+<dt><code>reassign</code> <var>bugnumber</var> <var>package</var>
+<dd>
+
+Records that $gBug #<var>$gBugnumber</var> is a $gBug in <var>package</var>.
+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).
+
+<dt><code>reopen</code> <var>bugnumber</var>
+ [ <var>originator-address</var> | <code>=</code> | <code>!</code> ]
+<dd>
+
+Reopens #<var>bugnumber</var> if it is closed.
+<p>
+
+By default, or if you specify <code>=</code>, the original submitter is
+still as the originator of the report, so that they will get the ack
+when it is closed again.
+<p>
+
+If you supply an <var>originator-address</var> 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 <code>!</code>
+shorthand or specify your own email address.
+<p>
+
+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.
+<p>
+
+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).
+
+<dt><code>forwarded</code> <var>bugnumber</var> <var>address</var>
+<dd>
+
+Notes that <var>bugnumber</var> has been forwarded to the upstream
+maintainer at <var>address</var>. 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.
+
+<dt><code>notforwarded</code> <var>bugnumber</var>
+<dd>
+
+Forgets any idea that <var>bugnumber</var> has been forwarded to any
+upstream maintainer. If the $gBug was not recorded as having been
+forwarded then this will do nothing.
+
+<dt><code>retitle</code> <var>bugnumber</var> <var>new-title</var>
+<dd>
+
+Changes the title of a $gBug report to that specified (the default is
+the <code>Subject</code> mail header from the original report.
+<p>
+
+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.
+
+<dt><code>severity</code> <var>bugnumber</var> <var>severity</var>
+<dd>
+
+Set the severity level for $gBug report #<var>bugnumber</var> to
+<var>severity</var>. No notification is sent to the user who reported
+the $gBug.
+<p>
+
+For <A href="Developer.html#severities">their meanings</A> please
+consult the general developers' documentation for the $gBug system.
+
+<dt><code>merge</code> <var>bugnumber</var> <var>bugnumber</var> ...
+<dd>
+
+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.
+<p>
+
+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 <code>reassign</code>, <code>reopen</code>
+and so forth to make sure that they are before using
+<code>merge</code>.
+<p>
+
+If any of the $gBugs listed in a <code>merge</code> 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.
+<p>
+
+Merging reports causes a note to appear on each report's logs; on the
+WWW pages this is includes links to the other $gBugs.
+<p>
+
+Merged reports are all expired simultaneously, and only when all of
+the reports each separately meet the criteria for expiry.
+
+<dt><code>unmerge</code> <var>bugnumber</var>
+<dd>
+
+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.
+<p>
+
+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.
+<p>
+
+You can only unmerge one report with each <code>unmerge</code>
+command; if you want to disconnect more than one $gBug simply include
+several <code>unmerge</code> commands in your message.
+
+</dl>
+
+<hr>
+Other pages:
+<ul>
+<li><A href="./">$gBug tracking system main contents page.</A>
+<li><A href="Reporting.html">Instructions for reporting $gBugs.</A>
+<li><A href="Access.html">Accessing the $gBug tracking logs other than by WWW.</A>
+<li><A href="Developer.html">Developers'
+information regarding the $gBug processing system.</A>
+<li><A href="server-request.html">Fundamentals of the mailserver
+and commands for retrieving $gBugs.</A>
+<li><A href="server-refcard.html">Mailservers' reference card.</A>
+<li><A href="db/ix/full.html">Full list of outstanding and recent $gBug reports.</A>
+<li><A href="db/ix/packages.html">Packages with $gBug reports.</A>
+<li><A href="db/ix/maintainers.html">Maintainers of packages with $gBug reports.</A>
+ $gHTMLOtherPageList
+</ul>
+
+$gHTMLTail
+
+HTML_END
--- /dev/null
+$gRefcardHtml = <<HTML_END
+<html><head>
+<title>$gProject $gBug system - mail servers' reference card</title>
+<link rev="made" href="mailto:$gMaintainerEmail">
+</head><body>
+<h1>Mail servers' reference card</h1>
+
+Full documentation of the mail servers is available on the WWW, in the
+files
+<A href="server-request.html">bug-log-mailserver.txt</A> and
+<A href="server-control.html">bug-maint-mailcontrol.txt</A> or by
+sending the word <code>help</code> to each mailserver.
+
+<h2>Synopsis of commands available at <code>request@$gEmailDomain</code></h2>
+
+<ul compact>
+<li><code>send</code> <var>bugnumber</var>
+<li><code>send-detail</code> <var>bugnumber</var>
+<li><code>index</code> [<code>full</code>]
+<li><code>index-summary by-package</code>
+<li><code>index-summary by-number</code>
+<li><code>index-maint</code>
+<li><code>index maint</code> <var>maintainer-substring</var>
+<li><code>index-packages</code>
+<li><code>index packages</code> <var>package-substring</var>
+<li><code>send-unmatched</code> [<code>this</code>|<code>0</code>]
+<li><code>send-unmatched</code> <code>last</code>|<code>-1</code>
+<li><code>send-unmatched</code> <code>old</code>|<code>-2</code>
+<li><code>getinfo</code> <var>filename</var> <em>(see below)</em>
+<li><code>help</code>
+<li><code>refcard</code>
+<li><code>quit</code>|<code>stop</code>|<code>thank</code>...|<code>--</code>...
+<li><code>#</code>... <em>(comment)</em>
+<li><code>debug</code> <var>level</var>
+</ul>
+
+<h3>List of info files for <code>getinfo</code></h3>
+<ul compact>
+<li><code>maintainers</code>
+<li><code>override.stable</code>
+<li><code>override.development</code>
+<li><code>override.contrib</code>
+<li><code>override.non-free</code>
+<li><code>override.experimental</code>
+<li><code>override.</code><var>codeword</var>
+<li><code>pseudo-packages.description</code>
+<li><code>pseudo-packages.maintainers</code>
+</ul>
+
+<h2>Synopsis of extra commands available at control mailserver</h2>
+
+<ul compact>
+<li><code>close</code> <var>bugnumber</var>
+ <em>(you must separately tell originator why)</em>
+<li><code>reassign</code> <var>bugnumber</var> <var>package</var>
+<li><code>severity</code> <var>bugnumber</var> <var>severity</var>
+<li><code>reopen</code> <var>bugnumber</var>
+ [ <var>originator-address</var> | <code>=</code> | <code>!</code> ]
+<li><code>forwarded</code> <var>bugnumber</var> <var>address</var>
+<li><code>notforwarded</code> <var>bugnumber</var>
+<li><code>retitle</code> <var>bugnumber</var> <var>new-title</var>
+<li><code>merge</code> <var>bugnumber</var> <var>bugnumber</var> ...
+<li><code>unmerge</code> <var>bugnumber</var>
+</ul>
+<code>reopen</code> with <code>=</code> or no originator address leaves
+the originator as the original submitter; <code>!</code> sets it to
+you, the person doing the reopen.
+<p>
+
+$gHTMLSeverityDesc
+
+<hr>
+Other pages:
+<ul>
+<li><A href="./">$gBug tracking system main contents page.</A>
+<li><A href="server-request.html">Full documentation of the request mailserver.</A>
+<li><A href="server-control.html">Full documentation of the control mailserver.</A>
+<li><A href="Reporting.html">Instructions for reporting $gBugs.</A>
+<li><A href="Access.html">Accessing the $gBug tracking logs other than by WWW.</A>
+<li><A href="Developer.html">Developers'
+information regarding the $gBug processing system.</A>
+<li><A href="db/ix/full.html">Full list of outstanding and recent $gBug reports.</A>
+<li><A href="db/ix/packages.html">Packages with $gBug reports.</A>
+<li><A href="db/ix/maintainers.html">Maintainers of packages with $gBug reports.</A>
+$gHTMLOtherPageList
+</ul>
+
+$gHTMLTail
+
+HTML_END
--- /dev/null
+$gRequestHtml = <<HTML_END
+<html><head>
+<title>$gProject $gBug system - $gBug logs by mail server</title>
+<link rev="made" href="mailto:$gMaintainerEmail">
+</head><body>
+<A name="introduction">
+<h1>Introduction to the $gBug system request server</h1>
+</A>
+
+There is a mailserver which can send the $gBug reports and
+indices as plain text on request.
+<p>
+
+To use it you send a mail message to
+<A href="mailto:request\@$gEmailDomain"><code>request\@$gEmailDomain</code></A>.
+The <code>Subject</code> of the message is ignored, except
+for generating the <code>Subject</code> of the reply.
+<p>
+
+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.
+<p>
+
+Any text on a line starting with a hash sign <code>#</code> is
+ignored; the server will stop processing when it finds a line starting
+with <code>quit</code>, <code>stop</code>, <code>thank</code> 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.
+
+<h1>Commands available</h1>
+
+<dl>
+<dt><code>send</code> <var>bugnumber</var>
+<dt><code>send-detail</code> <var>bugnumber</var>
+<dd>
+
+Requests the transcript for the $gBug report in question.
+<code>send-detail</code> sends all of the `boring' messages in the
+transcript, such as the various auto-acks (you should usually use
+<code>send</code> as well, as the interesting messages are not sent by
+<code>send-detail</code>).
+
+<dt><code>index</code> [<code>full</code>]
+<dt><code>index-summary by-package</code>
+<dt><code>index-summary by-number</code>
+<dd>
+
+Request the full index (with full details, and including done and
+forwarded reports), or the summary sorted by package or by number,
+respectively.
+
+<dt><code>index-maint</code>
+<dd>
+
+Requests the index page giving the list of maintainers with $gBugs (open
+and recently-closed) in the tracking sytem.
+
+<dt><code>index maint</code> <var>maintainer</var>
+<dd>
+
+Requests the index pages of $gBugs in the system for all maintainers
+containing the string <var>maintainer</var>. The search term is a
+case insensitive substring. The $gBug index for each matching
+maintainer will be sent in a separate message.
+
+<dt><code>index-packages</code>
+<dd>
+
+Requests the index page giving the list of packages with $gBugs (open
+and recently-closed) in the tracking sytem.
+
+<dt><code>index packages</code> <var>package</var>
+<dd>
+
+Requests the index pages of $gBugs in the system for all packages
+containing the string <var>package</var>. The search term is a case
+insensitive substring. The $gBug index for each matching package will
+be sent in a separate message.
+
+<dt><code>send-unmatched</code> [<code>this</code>|<code>0</code>]
+<dt><code>send-unmatched</code> <code>last</code>|<code>-1</code>
+<dt><code>send-unmatched</code> <code>old</code>|<code>-2</code>
+<dd>
+
+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.)
+
+<dt><code>getinfo</code> <var>filename</var>
+<dd>
+
+Request a file containing information about package(s) and or
+maintainer(s) - the files available are:
+<dl compact>
+<dt><code>maintainers</code>
+<dd>
+The unified list of packages' maintainers, as used by the tracking
+system.
+
+$gCreateMaintainers
+
+<!-- Override file quivilent information -->
+
+<dt><code>pseudo-packages.description</code>
+<dt><code>pseudo-packages.maintainers</code>
+<dd>
+List of descriptions and maintainers respectively for pseudo-packages.
+</dl>
+
+<dt><code>refcards</code>
+<dd>
+Requests that the mailservers' reference card be sent in plain ASCII.
+
+<dt><code>help</code>
+<dd>
+Requests that this help document be sent by email in plain ASCII.
+
+<dt><code>quit</code>
+<dt><code>stop</code>
+<dt><code>thank</code>...
+<dt><code>--</code>...
+<dd>
+
+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 <code>#</code>, for
+example for the benefit of human readers of your message (reading it
+via the tracking system logs or due to a <code>CC</code> or
+<code>BCC</code>).
+
+<dt><code>#</code>...
+<dd>
+
+One-line comment. The <code>#</code> must be at the start of the
+line.
+
+<dt><code>debug</code> <var>level</var>
+<dd>
+
+Sets the debugging level to <var>level</var>, 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.
+
+</dl>
+
+There is a <A href="server-refcard.html">reference card</A> for the
+mailservers, available via the WWW, in
+<code>bug-mailserver-refcard.txt</code> or by email using the
+<code>refcard</code> command (see above).
+<p>
+
+If you wish to manipulate $gBug reports you should use the
+<code>control\@gEmailDomain</code> address, which understands a
+<A href="server-control.html">superset of the commands listed
+above</A>. This is described in another document, available on the
+WWW</A>, in the file <code>bug-maint-mailcontrol.txt</code>, or by
+sending <code>help</code> to <code>control\@$gEmailDomain</code>.
+<p>
+
+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
+<code>http://$gWebDomain/</code>.
+<p>
+
+<hr>
+Other pages:
+<ul>
+<li><A href="./">$gBug tracking system main contents page.</A>
+<li><A href="Reporting.html">Instructions for reporting $gBugs.</A>
+<li><A href="Access.html">Accessing the $gBug tracking logs other than by WWW.</A>
+<li><A href="Developer.html">Developers'
+information regarding the $gBug processing system.</A>
+<li><A href="server-control.html">Developers'
+information - $gBug manipulation using the email control interface.</A>
+<li><A href="server-refcard.html">Mailservers' reference card.</A>
+<li><A href="db/ix/full.html">Full list of outstanding and recent $gBug reports.</A>
+<li><A href="db/ix/packages.html">Packages with $gBug reports.</A>
+<li><A href="db/ix/maintainers.html">Maintainers of packages with $gBug reports.</A>
+$gHTMLOtherPageList
+</ul>
+
+$gHTMLTail
+
+HTML_END
--- /dev/null
+sample John Smith <gecko@benham.net>
+test Mary Jane <gecko@benham.net>
--- /dev/null
+# 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
--- /dev/null
+#!/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
--- /dev/null
+#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";
--- /dev/null
+#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";
--- /dev/null
+#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";
--- /dev/null
+#!/usr/bin/perl
+# $Id: db2html.in,v 1.1 1999/09/02 19:25:01 gecko Exp $
+# usage: db2html [-diff] [-stampfile=<stampfile>] [-lastrun=<days>] <wwwbase>
+
+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',$_."</body></html>\n");
+ print "noremoves\n";
+ exit 0;
+}
+
+open(MM,"$gMaintainerFile") || &quit("open $gMaintainerFile: $!");
+while(<MM>) {
+ 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 <code>done\@$gEmailDomain</code>\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 <code>request@$gEmailDomain</code> (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= <S>);
+ chomp($s_date= <S>);
+ chomp($s_subject= <S>);
+ chomp($s_msgid= <S>);
+ chomp($s_package= <S>);
+ chomp($s_keywords= <S>);
+ chomp($s_done= <S>);
+ chomp($s_forwarded= <S>);
+ chomp($s_mergedwith= <S>);
+ chomp($s_severity= <S>);
+ $_= $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= "<strong>Severity: $s_severity</strong>;\n";
+ $addseverity= $s_severity;
+ } else {
+ $showseverity= "Severity: <em>$s_severity</em>;\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: <A href=\"../$packfile\"><strong>".
+ &sani($s_package)."</strong></A>;\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."<A href=\"../$mfile.html\">#$m</A>";
+ $mseparator= ",\n";
+ }
+ }
+ $daysold=$submitted='';
+ if (length($s_done)) {
+ $indexentry .= ";\n<strong>Done:</strong> ".&sani($s_done);
+ $indexpart= "done$addseverity";
+ } elsif (length($s_forwarded)) {
+ $indexentry .= ";\n<strong>Forwarded</strong> 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 .= "</pre><h2>$msg:</h2><pre>\n$shorthead\n";
+ $amonths= $cmonths;
+ }
+ $pad= 6-length(sprintf("%d",$f));
+ $thissient=
+ ($pad>0 ? ' 'x$pad : '').
+ sprintf("<A href=\"../%s.html\">%d</A>",$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>" : '';
+ $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".
+ '<A href="../ma/l'.&maintencoded($tmaint).'.html">'.&sani($tmaint).'</A>.';
+ $indexentry .= $daysold;
+ $indexentry .= ".";
+ }
+ $indexadd='';
+ $indexadd .= "<!--iid $iiref-->" if defined($iiref);
+ $indexadd .= "<li><A href=\"../$linkto.html\">".$indexlink."</A>";
+ $indexadd .= "<br>\n".$indexentry if length($indexentry);
+ $indexadd .= "<!--/iid-->" 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= "<!--ii $iiref-->\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(<L>) {
+ 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 .= "</pre>\n" if $normstate eq 'go' || $normstate eq 'go-nox';
+ if ($normstate eq 'html') {
+ $xmessage++;
+ $this .= " <em><A href=\"../$linkto-b.html#m$xmessage\">Full text</A>".
+ " available.</em>";
+ }
+ if ($suppressnext && $normstate ne 'html') {
+ $ntis= $this; $ntis =~ s:\<pre\>:</A><pre>:i;
+ $boring .= "<hr><A name=\"m$xmessage\">\n$ntis\n";
+ } else {
+ $log = $this. "<hr>\n". $log;
+ }
+ $suppressnext= $normstate eq 'html';
+ $normstate= 'kill-end';
+ } elsif (m/^\05$/) {
+ $normstate eq 'kill-body' || &quit("^E in state $normstate");
+ $this .= "<pre>\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 = "<h2>Message received at ".&sani("$1\@$2").":</h2><br>\n".
+ "<pre>\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 = "<h2>Message sent:</h2><br>\n";
+ } else {
+ s/\04/, /g; s/\n$//;
+ $this = "<h2>Message sent to ".&sani($_).":</h2><br>\n";
+ }
+ $normstate= 'kill-body';
+ } elsif ($normstate eq 'autocheck') {
+ next if !m/^X-Debian-Bugs(-\w+)?: This is an autoforward from (\S+)/;
+ $normstate= 'autowait';
+ $this = "<h2>Message received at $2:</h2><br>\n";
+ } elsif ($normstate eq 'autowait') {
+ next if !m/^$/;
+ $normstate= 'go-nox';
+ $this .= "<pre>\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',
+ "<html><head><title>$gProject $gBug report logs - ".
+ "$short, boring messages</title>\n".
+ "<link rev=\"made\" href=\"mailto:$gMaintainerEmail)\">\n".
+ "</head><body><h1>$gProject $gBugreport logs -".
+ "\n <A href=\"../$linkto.html\">$short</A>,".
+ " boring messages</h1>\n$boring\n<hr>\n".
+ $tail_html."</body></html>\n");
+ }
+ &file("$linkto.html",'non',
+ "<html><head><title>$gProject $gBug report logs - ".
+ "$short</title>\n".
+ "<link rev=\"made\" href=\"mailto:$gMaintainerEmail)\">\n".
+ "</head><body><h1>$gProject) $gBug report logs - $short<br>\n".
+ &sani($s_subject)."</h1>".
+ "$descriptivehead\n".
+ "\n<hr>\n".
+ $log.
+ $tail_html."</body></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).'<strong>'.&sani($sort1d.$sort2d).'</strong>'.&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.= "<hr>\n<h2>".&heading($pending,$severity).":</h2>\n".
+ "(List of <A href=\"../si/$pending$severity.html\">all".
+ " such $gBugs</A> is available.)\n<ul>\n".
+ $$value.
+ "</ul>\n";
+ $anydone=1 if $pending eq 'done';
+ }
+ }
+ $text.= $expirynote_html if $anydone;
+ return $text;
+}
+
+&file("ix/full.html",'def',
+ $gFullIndex.
+ makeindex('$index',"",'').
+ "<hr>\n".
+ $tail_html."</body><html>\n");
+
+&file("ju/junk.html",'non',
+ $gJunkIndex.
+ "<hr>\n<h2>Junk (messages without a specific $gBug report number):</h2>\n".
+ "(\`this week' is everything since last Wednesday.)\n<ul>\n".
+ $indexunmatched.
+ "</ul><hr>\n".
+ $tail_html."</body><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 <A HREF\"../../\">$gBug system top-level
+contents WWW page</A>.
+
+";
+
+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',
+ "<html><head><title>$who_html $gBug reports: $headstring</title>\n".
+ "<link rev=\"made\" href=\"mailto:".&sani($owner_addr)."\">\n".
+ "</head><body><h1>$who_html $gBug reports: $headstring</h1>\n".
+ $otherindex_html.
+ ($pending eq 'done' ? "<P>\n$expirynote_html" : '').
+ "<hr>\n".
+ $$value.
+ "<hr>\n".
+ $tail_html."</body></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 .= "<li><A href=\"../$tfilename\">".&$getdisplayref($tkey)."</A>"."\n".
+ " ($xitext)\n";
+ $backnext= '';
+ if ($i>0) {
+ $refto= $$keysref[$i-1];
+ $xitext= &$getxindexref($refto);
+ $xitext= " ($xitext)" if length($xitext);
+ $backnext .= "<br>\nPrevious $what in list, <A href=\"../".
+ &$getfilenameref($refto)."\">".&$getdisplayref($refto)."</A>".
+ "$xitext\n";
+ }
+ if ($i<$#$keysref) {
+ $refto= $$keysref[$i+1];
+ $xitext= &$getxindexref($refto);
+ $xitext= " ($xitext)" if length($xitext);
+ $backnext .= "<br>\nNext $what in list, <A href=\"../".
+ &$getfilenameref($refto)."\">".&$getdisplayref($refto)."</A>".
+ "$xitext\n";
+ }
+ &file($tfilename,'ref',
+ "<html><head><title>$gProject $gBug reports: $what $sani</title>\n".
+ "<link rev=\"made\" href=\"mailto:$gMaintainerEmail\">\n".
+ "</head><body><h1>$gProject $gBug reports: $what $sani</h1>\n".
+ &$getxinforef($tkey).
+ $caveat.
+ "See the <A href=\"../$filename\">listing of $whatplural</A>.\n".
+ $backnext.
+ &makeindex("\$per${abbrev}","{\$tkey}",$tkey).
+ "<hr>\n".
+ $tail_html."</body></html>\n");
+ }
+ &file($filename,'non',
+ $ihead.
+ "<hr><ul>\n".
+ $itext.
+ "</ul><hr>\n".
+ $tail_html."</body></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.<P>",
+ '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.<P>",
+ 'packages',
+ 'pack',
+ $gPackageIndex,
+ sub {
+ return unless defined($maintainer{$_[0]});
+ $tmaint= $maintainer{$_[0]};
+ return "Maintainer for $_[0] is <A href=\"../ma/l".
+ &maintencoded($tmaint).
+ ".html\">".&sani($tmaint)."</A>.\n<p>\n";
+ },
+ sub {
+ return unless defined($maintainer{$_[0]});
+ $tmaint= $maintainer{$_[0]};
+ return "<A href=\"../ma/l".
+ &maintencoded($tmaint).
+ ".html\">".&sani($tmaint)."</A>";
+ });
+
+&file('ix/summary.html','non',
+ $gSummaryIndex.
+ "<hr><pre>\n".
+ $shortindex.
+ "</pre><hr>\n".
+ $tail_html."</body></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.
+ "<hr><pre>\n$shorthead\n".
+ $bypackageindex.
+ "</pre><hr>\n".
+ $tail_html."</body></html>\n");
+
+open(P,"$gPseudoDescFile") ||
+ &quit("$gPseudoDescFile: $!");
+$ppd=''; while(<P>) { s/\s*\n$//; $ppd.= &sani($_)."\n"; } close(P);
+&file('ix/pseudopackages.html','non',
+ $gPseudoIndex.
+ "<hr><pre>\n$ppd".
+ "</pre><hr>\n".
+ $tail_html."</body></html>\n");
+
+$_= $gHTMLStamp; s/SUBSTITUTE_DTIME/$dtime/o;
+
+&file('ix/zstamp.html','non',$_."</body></html>\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= <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= <P>; $/= "\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;
--- /dev/null
+# -*- 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= <S>);
+ chop($s_date= <S>);
+ chop($s_subject= <S>);
+ chop($s_msgid= <S>);
+ chop($s_package= <S>);
+ chop($s_keywords= <S>);
+ chop($s_done= <S>);
+ chop($s_forwarded= <S>);
+ chop($s_mergedwith= <S>);
+ chop($s_severity= <S>);
+ 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;
--- /dev/null
+#!/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: $!");
--- /dev/null
+#!/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=<US>);
+ chop($lastsub=<US>);
+ 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 <<END
+From: $gMaintainerEmail ($gMaintainer)
+To: $gMirrorList\@$gListDomain
+Subject: $gProject $gBugs autoupdate 259012
+Message-ID: <handle.htmlup.$seqmid\@gEmailDebian>
+X-$gProject=PR: update $sequences
+
+END
+ ) or nonawful("write html-data.mail header: $!");
+} else {
+print(MM <<END
+From: $gMaintainerEmail ($gMaintainer)
+To: $gMaintainerEmail
+Subject: $gProject $gBugs autoupdate 259012
+Message-ID: <handle.htmlup.$seqmid\@gEmailDebian>
+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 <html-data 2>&1",sub { &quit; });
+runshell("gzip -9 html-data 2>&1",sub { &quit; });
+#runshell("btoa 2>&1 <html-data.gz >>html-data.mail",sub { &quit; });
+#runshell('2>&1 '.join(' ',('/usr/lib/sendmail','-f'."$gMaintainerEmail")).' -oem -oi -t <html-data.mail',
+# sub { &quit; });
+
+rename("stamp.html.new","stamp.html") or &quit("install new stamp.html: $!");
+
+unlink("html-data.gz") or warn "remove html-data.gz: $!";
+unlink("html-data.mail") or warn "remove html-data.mail: $!";
+unlink("stamp.html.run") || $!==&ENOENT or warn "remove stamp.html.run: $!";
+
+print "sequences $lastmain $lastsub\n";
+
+&unfilelock();
+exit(0);
--- /dev/null
+#!/usr/bin/perl
+# Takes 1 argument - directory tree to install into
+# Tree _must_ be synch'd with one used by db2html to generate file
+
+use POSIX;
+require( '/etc/debbugs/config' );
+
+$dirtree= shift(@ARGV);
+defined($dirtree) or die 'usage';
+chdir $dirtree or die $!;
+
+$filenamere= '[0-9a-z]{2}/[0-9a-z][-+_:,.0-9a-zA-Z]*';
+
+opendir(D,".") or die " opendir: $!";
+while ($dir=readdir(D)) {
+ next if $dir =~ m/^\.\.?$/;
+ if (-f $dir) {
+ $remove{$dir}= 1;
+ } else {
+ opendir(E,"$dir") or die " opendir $dir: $!";
+ while ($_=readdir(E)) {
+ next if $_ =~ m/^\.\.?$/;
+ $remove{"$dir/$_"}= 1;
+ }
+ closedir(E) or die " closedir $dir: $!";
+ $rmdir{$dir}= 1;
+ }
+}
+closedir(D) or die " closedir: $!";
+
+while(<>) {
+ 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=<STDIN>;
+ 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=<STDIN>) eq "that$filediff $file\n" or die die "not confirmed >$z<";
+ if ($filediff eq 'diff') {
+ $q= `ed -s <recv.tmp 2>&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 (<I>) {
+ 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 (<I>) {
+ 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 $!";
--- /dev/null
+#!/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 <<END || die "complete sendmail";
+From: $gMaintainerEmail ($gMaintainer)
+To: submit\@$gListDomain
+Subject: $subject
+
+$intro
+$v
+Every Tuesday, the listing by package maintainer is posted.
+Every Frideay, the listing by age of the report is posted.
+
+Please see the documentation for more information about how to
+use the $gBug tracking system. It is available on the WWW at
+<A HREF=\"http://$gWebUrl/txt/\">$gWebUrl/txt</A>
+END
+
+close(D);
+$? && die "sendmail failed $?: $!\n";
+
+print length($v)," bytes of summary posted.\n";
--- /dev/null
+#!/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=<M>;
+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= <<END;
+X-Loop: $gMaintainerEmail
+Received: via spool by $baddress\@$gEmailDomain id=$nn
+ (code $codeletter ref $tryref); $tdate
+END
+
+for ($i=0; $i<=$#msg; $i++) {
+ $_ = $msg[$i];
+ last unless length($_);
+ &quit("looping detected") if m/^x-loop: (\S+)$/i && $1 eq "$gMaintainerEmail";
+ $ins= !m/^subject:/i && !m/^reply-to:/i && !m/^return-path:/i
+ && !m/^From / && !m/^X-$gProjct-Message:/i && !m/^received:/i;
+ $fwd .= $_."\n" if $ins;
+ while ($msg[$i+1] =~ m/^\s/) {
+ $i++;
+ $fwd .= $msg[$i]."\n" if $ins;
+ $_ .= ' '.$msg[$i];
+ }
+# print DEBUG ">$_<\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.= <<END;
+
+Your message did not contain a Subject field. This is broken, I am
+afraid - the Subject: line is a Required Header according to RFC822.
+Please remember to include a Subject field in your messages in future.
+If you did so the fact that it got lost probably indicates a poorly
+configured mail system at your site or an intervening one.
+END
+ $subject= '(no subject)';
+} else {
+ $subject= $header{'subject'};
+}
+
+$ref=-1;
+$subject =~ s/^Re:\s*//i; $_= $subject."\n";
+if ($tryref < 0 && m/^Bug ?\#(\d+)\D/i) {
+ $tryref= $1+0;
+}
+if ($tryref >= 0) {
+ $bfound= &lockreadbugmerge($tryref);
+ if ($bfound) {
+ $ref= $tryref;
+ } else {
+ &htmllog("Reply","sent", $replyto,"Unknown problem report number <code>$tryref</code>.");
+ &sendmessage(<<END, '');
+From: $gMaintainerEmail ($Maintainer)
+To: $replyto
+Subject: Unknown problem report $gBug#$tryref ($subject)
+Message-ID: <handler.x.$nn.unknown\@$gEmailDomain>
+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(<<END, '');
+From: $gMaintainerEmail
+To: $replyto
+Subject: Message with no $gBug number ignored by $receivedat
+ ($subject)
+Message-ID: <header.x.$nn.warnignore\@$gEmailDomain>
+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('',<O>); close(O);
+ if ($codeletter eq 'F') {
+ &htmllog("Reply","sent",$replyto,"You have marked $gBug as forwarded.");
+ &sendmessage(<<END.$x, '');
+From: $gMaintainerEmail ($gMaintainer)
+To: $replyto
+${noticecc}Subject: $gBug#$ref: marked as forwarded ($s_subject)
+Message-ID: <header.$ref.$nn.ackfwdd\@$gEmailDomain>
+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(<<END.$x, '');
+From: $gMaintainerEmail ($gMaintainer)
+To: $replyto
+${noticecc}Subject: $gBug#$ref: marked as done ($s_subject)
+Message-ID: <handler.$ref.$nn.ackdone\@$gEmailDomain>
+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(<<END.join("\n",@msg),'');
+From: $gMaintainerEmail ($gMaintainer)
+To: $s_originator
+Subject: $gBug#$ref acknowledged by developer ($s_subject)
+Message-ID: <handler.$ref.$nn.notifdone\@$gEmailDomain>
+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(<<END, '');
+From: $gMaintainerEmail ($gMaintainer)
+To: $replyto
+Subject: Message with no $gBug number cannot be sent to submitter !
+ ($subject)
+Message-ID: <handler.x.$nn.nonumnosub\@$gEmailDomain>
+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.= <<END;
+
+Your message didn't have a Package: line at the start (in the
+pseudo-header following the real mail header), or didn't have a
+psuedo-header at all.
+
+This makes it much harder for us to categorise and deal with your
+problem report; please ensure that you say which package(s) and
+version(s) the problem is with next time. Some time in the future the
+problem reports system may start rejecting such messages.
+END
+ } else {
+ $s_package= $pheader{'package'};
+ }
+ if (defined($pheader{'keywords'})) {
+ $s_keywords= $pheader{'keywords'};
+ }
+ $s_severity= '';
+ if (defined($pheader{'severity'})) {
+ $s_severity= $pheader{'severity'};
+ if (!grep($_ eq $s_severity, @severities, "$gDefaultSeverity")) {
+ $brokenness.= <<END;
+
+Your message specified a Severity: in the psuedo-header, but
+the severity value $s_severity was not recognised.
+The default severity $gDefaultSeverity is being used instead.
+The recognised values are: @showseverities.
+END
+ $s_severity= '';
+ }
+ }
+ &filelock("nextnumber.lock");
+ open(N,"nextnumber") || &quit("nextnumber: read: $!");
+ $v=<N>; $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.= <<END;
+
+As you requested using X-$gProject-CC, your message was also forwarded to
+ $xcchdr
+(after having been given a $gBug report number, if it did not have one).
+END
+}
+
+if (@maintaddrs && ($codeletter eq 'B' || $codeletter eq 'M')) {
+ push(@resentccs,@maintaddrs);
+ $resentccexplain.= <<END." ".join("\n ",@maintaddrs)."\n";
+
+Your message has been sent to the package maintainer(s):
+END
+}
+
+$veryquiet= $codeletter eq 'Q';
+if ($codeletter eq 'M' && !@maintaddrs) {
+ $veryquiet= 1;
+ $brokenness.= <<END;
+
+You requested that the message be sent to the package maintainer(s)
+but either the $gBug report is not associated with any package (probably
+because of a missing Package psuedo-header field in the original $gBug
+report), or the package(s) specified do not have any maintainer(s).
+
+Your message has *not* been sent to any package maintainers; it has
+merely been filed in the $gBug tracking system. If you require assistance
+please contact $gMaintainerEmail quoting the $gBug number $ref.
+END
+}
+
+$resentccval.= join(', ',@resentccs);
+$resentccval =~ s/\s+\n\s+/ /g; $resentccval =~ s/^\s+/ /; $resentccval =~ s/\s+$//;
+if (length($resentccval)) { $resentcc= "Resent-CC: $resentccval\n"; }
+
+if ($codeletter eq 'U') {
+ &htmllog("Message", "sent on", $s_originator, "$gBug#$ref.");
+ &sendmessage(<<END,$s_originator,@resentccs);
+Subject: $gBug#$ref: $newsubject
+Reply-To: $replyto, $ref-quiet\@$gEmailDomain
+${orgsender}Resent-To: $s_originator
+${resentcc}Resent-Date: $tdate
+Resent-Message-ID: <handler.$ref.$nn\@$gEmailDomain>
+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),
+ "<code>$gBug#$ref</code>".
+ (length($s_package)? "; Package <code>".&sani($s_package)."</code>" : '').
+ (length($s_keywords)? "; Keywords <code>".&sani($s_keywords)."</code>":'').
+ ".");
+ &sendmessage(<<END,"$gSubmitList\@$gListDomain",@resentccs);
+Subject: $gBug#$ref: $newsubject
+Reply-To: $replyto, $ref\@$gEmailDomain
+Resent-From: $header{'from'}
+${orgsender}Resent-To: $gSubmitList\@$gListDomain
+${resentcc}Resent-Date: $tdate
+Resent-Message-ID: <handler.$ref.$nn\@$gEmailDomain>
+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,
+ "<code>$gBug#$ref</code>".
+ (length($s_package)? "; Package <code>".&sani($s_package)."</code>" : '').
+ (length($s_keywords)? "; Keywords <code>".&sani($s_keywords)."</code>":'').
+ ".");
+ &sendmessage(<<END,@resentccs);
+Subject: $gBug#$ref: $newsubject
+Reply-To: $replyto, $ref-$baddressroot\@$gEmailDomain
+Resent-From: $header{'from'}
+${orgsender}Resent-To: $resentccval
+Resent-Date: $tdate
+Resent-Message-ID: <handler.$ref.$nn\@$gEmailDomain>
+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) ? "<p>\n".&sani($brokenness)."\n<p>\n" : '';
+$htmlbreak =~ s/\n\n/\n<P>\n\n/g;
+if (length($resentccval)) {
+ $htmlbreak =
+ " Copy sent to <code>".&sani($resentccval)."</code>.".
+ $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 ? <<END : $codeletter eq 'M' ? <<END : <<END,'');
+From: $gMaintainerEmail ($gMaintainer)
+To: $replyto
+Subject: $gBug#$ref: Acknowledgement of QUIET report
+ ($subject)
+Message-ID: <handler.$ref.$nn.ackquiet\@$gEmailDomain>
+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: <handler.$ref.$nn.ackmaint\@$gEmailDomain>
+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: <handler.$ref.$nn.ack\@$gEmailDomain>
+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 ? <<END : $codeletter eq 'M' ? <<END : <<END,'');
+From: $gMaintainerEmail ($gMaintainer)
+To: $replyto
+Subject: $gBug#$ref: Info received and FILED only
+ (was $subject)
+Message-ID: <handler.$ref.$nn.ackinfoquiet\@$gEmailDomain>
+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: <handler.$ref.$nn.ackinfomaint\@$gEmailDomain>
+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: <handler.$ref.$nn.ackinfo\@$gEmailDomain>
+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".
+ "<strong>$whatobj $whatverb</strong> to <code>".&sani($where).
+ "</code>:<br>\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 (<MAINT>) {
+ 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;
+ }
+ }
+}
--- /dev/null
+#!/usr/bin/perl
+#
+# Usage: processall
+#
+# Uses up: incoming/I<code><bugnum>.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);
--- /dev/null
+#!/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/\<//;
+}
+
+
+#remove everything from @ to end of line
+s/\@.*$//;
+
+#convert remaining upper case to lower case
+y/A-Z/a-z/;
+
+#set up to determine command
+%withnaddressmap= ('-submit', 'B',
+ '', 'B',
+ '-maintonly', 'M',
+ '-quiet', 'Q',
+ '-forwarded', 'F',
+ '-done', 'D',
+ '-close', 'D',
+ '-submitter', 'U');
+
+%withoutnaddressmap= ('submit', 'B',
+ 'bugs', 'B',
+ 'maintonly', 'M',
+ 'quiet', 'Q',
+ 'forwarded', 'F',
+ 'done', 'D',
+ 'close', 'D',
+ 'request', 'R',
+ 'submitter', 'U',
+ 'control', 'C');
+
+#determine command
+if (s/^(\d{1,9})\b//) {
+ $bugnumber= $1;
+ $map= $withnaddressmap{$_};
+ $addrrec= "$bugnumber$_";
+} else {
+ $bugnumber= '';
+ $map= $withoutnaddressmap{$_};
+ $addrrec= "$_";
+}
+
+#print no command received
+if (!defined($map)) {
+ print STDERR <<ENDTEXT;
+$gBadEmailPrefix
+$gBadEmailPrefix Unknown $gBug service address $_\@$gEmailDomain.
+$gBadEmailPrefix Recognised addresses are:
+$gBadEmailPrefix
+$gBadEmailPrefix General: Read $gBug# in Subject: $gBug# is NNNN:
+$gBadEmailPrefix
+$gBadEmailPrefix request submit $gBug NNNN NNNN-submit
+$gBadEmailPrefix control maintonly NNNN-maintonly
+$gBadEmailPrefix owner quiet NNNN-quiet
+$gBadEmailPrefix postmaster forwarded NNNN-forwarded
+$gBadEmailPrefix done close NNNN-done NNNN-close
+$gBadEmailPrefix submitter NNNN-submitter
+$gBadEmailPrefix
+$gBadEmailPrefix (all \@$gEmailDomain.)
+$gBadEmailPrefix
+$gBadEmailPrefix For instructions via the WWW see:
+$gBadEmailPrefix http://$gWebDomain/
+$gBadEmailPrefix http://$gWebDomain/Reporting.html
+$gBadEmailPrefix http://$gWebDomain/Developer.html
+$gBadEmailPrefix http://$gWebDomain/Access.html
+$gBadEmailPrefix $gTextInstructions
+$gBadEmailPrefix For details of how to access $gBug report logs by email:
+$gBadEmailPrefix send \`request\@$gEmailDomain' the word \`help'
+$gBadEmailPrefix
+ENDTEXT
+ exit(100);
+}
+
+@months=qw(Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec);
+($sec,$min,$hour,$mday,$mon,$year)= gmtime(time);
+
+$queue= "$map$bugnumber";
+
+chdir("$gSpoolDir/incoming") || &failure("chdir to spool: $!");
+
+$id= time.$$;
+open(FILE,">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(<STDIN>) { 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
+}
--- /dev/null
+#!/usr/bin/perl
+#
+# Usage: service <code>.nn
+# Temps: incoming/P<code>.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=<M>;
+@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= <<END;
+Received: via spool for service; $tdate
+END
+
+for ($i=0; $i<=$#msg; $i++) {
+ $_ = $msg[$i];
+ last unless length($_);
+ $fwd .= $_."\n";
+ while ($msg[$i+1] =~ m/^\s/) {
+ $i++;
+ $fwd .= $msg[$i]."\n" if $ins; # Huh ? Where is ins set ?
+ $_ .= ' '.$msg[$i];
+ }
+# print DEBUG ">$_<\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(<P>) { $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(<<END);
+There is no $gProject $gBug mailing list. If you wish to review bug reports
+please do so via http://$gWebUrl/ or ask this mailserver
+to send them to you.
+soon: MAILINGLISTS_TEXT
+END
+ } elsif (m/^unsubscribe/) {
+ &transcript(<<END);
+soon: UNSUBSCRIBE_TEXT
+soon: MAILINGLISTS_TEXT
+END
+ } elsif (!$control) {
+ &transcript(<<END);
+Unknown command or malformed arguments to command.
+(Use control\@$gEmailDomain to manipulate reports.)
+
+END
+ if (++$unknowns >= 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= <<END;
+From: $gMaintainerEmail ($gMaintainer)
+To: $s_originator
+Subject: $gBug#$ref acknowledged by developer
+ ($s_subject)
+References: $header{'message-id'} $s_msgid
+In-Reply-To: $s_msgid
+Message-ID: <handler.$ref.$nn.notifdonectrl.$midix\@$gEmailDomain>
+
+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= <<END;
+From: $gMaintainerEmail ($gMaintainer)
+To: $replyto
+${maintccs}Subject: Processed: $header{'subject'}
+In-Reply-To: $header{'message-id'}
+References: $header{'message-id'}
+Message-ID: <handler.s.$nn.transcript\@$gEmailDomain>
+
+${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".
+ "<strong>Request received</strong> from <code>".
+ &sani($header{'from'})."</code>\n".
+ "to <code>".&sani($controlrequestaddr)."</code>\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".
+ "<strong>".&sani($action)."</strong>\n".
+ "Request was from <code>".&sani($header{'from'})."</code>\n".
+ "to <code>".&sani($controlrequestaddr)."</code>. \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(<D>) { $doc.=$_; }
+ close(D);
+ &transcript("Sending $description in separate message.\n");
+ &sendmailmessage(<<END.$doc,$replyto);
+From: $gMaintainerEmail ($gMaintainer)
+To: $replyto
+Subject: $gProject $gBug help: $description
+References: $header{'message-id'}
+In-Reply-To: $header{'message-id'}
+Message-ID: <handler.s.$nn.help.$midix\@$gEmailDomain>
+
+END
+ $ok++;
+}
+
+sub sendlynxdocraw {
+ local ($relpath,$description) = @_;
+ $doc='';
+ open(L,"lynx -nolist -dump $wwwbase/$relpath 2>&1 |") || &quit("fork for lynx: $!");
+ while(<L>) { $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.$doc,$replyto);
+From: $gMaintainerEmail ($gMaintainer)
+To: $replyto
+Subject: $gProject $gBugs information: $description
+References: $header{'message-id'}
+In-Reply-To: $header{'message-id'}
+Message-ID: <handler.s.$nn.info.$midix\@$gEmailDomain>
+
+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 (<MAINT>) {
+ m/^(\S+)\s+(\S.*\S)\n$/ || &quit("maintainers bogus \`$_'");
+ $a= $1; $b= $2; $a =~ y/A-Z/a-z/;
+ $maintainerof{$1}= $2;
+ }
+ close(MAINT);
+}
--- /dev/null
+#!/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>) {
+ 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= <S>);
+ chop($s_date= <S>);
+ chop($s_subject= <S>);
+ chop($s_msgid= <S>);
+ chop($s_package= <S>);
+ chop($s_keywords= <S>);
+ chop($s_done= <S>);
+ chop($s_forwarded= <S>);
+ $_= $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: $!");
--- /dev/null
+############################################################################
+# 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<BR>
+# <A HREF=\"http://mirror1.domain\"><CODE>http://mirror1.domain</CODE></A><BR>
+# <A HREF=\"http://mirror2.domain\"><CODE>http://mirror2.domain</CODE></A>";
+############################################################################
+$gHTMLCopies = "";
+
+
+############################################################################
+# notice other links you want to note, like your list archives or project
+# home page.
+#
+#$gHTMLOtherPages = "Other Links of note:<BR>
+# <A HREF=\"http://www.debian.org/\">The Debian Project</A><BR>
+# <A HREF=\"http://another.domain\">Description of URL</A>";
+############################################################################
+$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 = "<LI><A HREF=\"http://www.debian.org/\">
+# The Debian Project</A>
+# <LI><A HREF=\"http://another.domain\">Description of URL</A>";
+############################################################################
+$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 <CODE>Package</CODE> line when reporting a $gBug in something other than an
+# actual $gProject software package. There is
+# <A HREF="db/ix/pseudopackages.html"> a list of these</A> 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 = "<DT><CODE>critical</CODE>
+ <DD>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.
+
+ <DT><CODE>grave</CODE>
+ <DD>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.
+
+ <DT><CODE>normal</CODE>
+ <DD>the default value, for normal $gBugs.
+
+ <DT><CODE>wishlist</CODE>
+ <DD>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 = "<HR><ADDRESS><A HREF=\"$gMaintainerWebpage\">$gMaintainer</A> /
+ <A HREF=\"mailto:$gMaintainerEmail\">$gMaintainerEmail</A>. Last modifed:
+ <!--timestamp-->
+ SUBSTITUTE_DTIME
+ <!--timestamp-->
+ (<A HREF=\"$gWebDomain/ix/zstamp.html\">timestamp page</A> available).
+
+ <P>
+ Debian $gBug tracking system<BR>
+ copyright 1997 nCipher Corporation Ltd,<BR>
+ copyright 1994-1997 Ian Jackson,<BR>
+ copyright 1995 Steven Brenner.<BR>
+ <A HREF=\"http://www.chiark.greenend.org.uk/~ian/debbugs/\">
+ Available under the GPL.</A>
+ </ADDRESS>
+ </BODY>
+ </HTML>";
+
+############################################################################
+# 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 = "<HTML><HEAD><TITLE>$gProject $gBugs - timestamp page</TITLE>
+ <LINK REV=\"made\" HREF=\"mailto:$gMaintainerEmail\">
+ </HEAD><BODY><H1>Is this $gBug log or mirror up to date?</H1>
+
+ 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.
+ <P>
+ The last
+ <!--updateupdate-->update<!--/updateupdate-->
+ was at
+ <STRONG><!--updatetime-->SUBSTITUTE_DTIME<!--/updatetime--></STRONG>;
+ The logs are usually checked every hour and updated if necessary.
+ <P>
+ For the $gBug index or for other information about $gProject and the $gBug
+ system, see the <A HREF=\"../../\">$gBug system main contents page</A>.
+
+ <HR>
+ <ADDRESS>
+ <A HREF=\"mailto:$gMaintainerEmail\">$gMaintainerEmail</A>,
+ through the <A HREF=\"../../\">$gProject $gBug database</a>
+ </ADDRESS>
+ <!--version 1.0-4.3-->";
+
+############################################################################
+# Makeup of the indices pages
+############################################################################
+$gFullIndex = "<HTML><HEAD><TITLE>$gProject $gBugs - full index</TITLE>
+ <LINK REV=\"make\" HREF=\"mailto:$gMaintainerEmail\">
+ </HEAD><BODY><H1>$gProject $gBug report logs - index</H1>
+
+ This index gives access to $gBugs sent to <CODE>submit\@$gEmailDomain</CODE>
+ 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).
+ <P>
+ For other kinds of indices or for other information about $gProject and
+ the $gBug system, see <A HREF=\"../../\">$gBug system top-level contents WWW
+ page</A>.
+
+
+ ";
+
+$gJunkIndex = "<HTML><HEAD><TITLE>$gProject $gBug reports - Junk</TITLE>
+ <LINK REV=\"made\" HREF=\"$gMaintainerEmail\">
+ </HEAD><BODY><H1>$gProject $gBug reports - Junk</H1>
+
+ This is the index page for logs of messages not associated with a specific
+ $gBug report.
+ <P>
+ For other kinds of indices or for other information about $gProject and
+ the $gBug system, see <A HREF=\"../../\"> $gBug system top-level contents WWW
+ page</A>.
+
+
+ ";
+
+$gMaintIndex = "<HTML><HEAD><TITLE>$gProject $gBug reports by maintainer</TITLE>
+ <LINK REF=\"made\" HREF=\"mailto:$gMaintainerEmail\">
+ </HEAD><BODY><H1>$gProject $gBug reports by maintainer</H1>
+
+ 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 <CODE>Maintainer</CODE>
+ package control file field may appear several times.<P>
+ If the maintainers information here is not accurate, please see
+ <A HREF=\"../../Developer.html#maintincorrect\">the developers\'
+ instructions</A> to find how this can happen and what to do about it. <P>
+ For other kinds of indices or for other information about $gProject and
+ the $gBug system, see <A HREF=\"../../\">$gBug system top-level contents WWW
+ page</A>.
+
+
+ ";
+
+$gPackageIndex = "<HTML><HEAD><TITLE>$gProject $gBug reports by package</TITLE>
+ <LINK REF=\"made\" HREF=\"mailto:$gMaintainerEmail\">
+ </HEAD><BODY><H1>$gProject $gBug reports by package</H1>
+
+ 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).<P>
+ For other kinds of indices or for other information about $gProject and
+ the $gBug system, see <A HREF=\"../../\">$gBug system top-level contents WWW
+ page</A>.
+
+
+ ";
+
+$gSummaryIndex = "<HTML><HEAD><TITLE>$gProject $gBug report logs - summary index</TITLE>
+ <LINK REF=\"made\" HREF=\"mailto:$gMaintainerEmail\">
+ </HEAD><BODY><H1>$gProject $gBug report logs - summary index</H1>
+
+ This summary index breiefly lists $gBugs sent to <CODE>submit\@$gEmailDomain
+ </CODE> 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).<P>
+ For other kinds of indices or for other information about $gProject and
+ the $gBug system, see <A HREF=\"../../\">$gBug system top-level contents WWW
+ page</A>.
+
+
+ ";
+
+$gPackageLog = "<HTML><HEAD><TITLE>$gProject $gBug report logs - index by package</TITLE>
+ <LINK REF=\"made\" HREF=\"mailto:$gMaintainerEmail\">
+ </HEAD><BODY><H1>$gProject $gBug report logs - index by package</H1>
+
+ This summary index breiefly lists $gBugs sent to <CODE>submit\@$gEmailDomain
+ </CODE> but not yet marked as done, or as fowarded to an upstream author.
+ Here they are sorted by package name.<P>
+ For other kinds of indices or for other information about $gProject and
+ the $gBug system, see <A HREF=\"../../\">$gBug system top-level contents WWW
+ page</A>.
+
+
+ ";
+
+$gPseudoIndex = "<HTML><HEAD><TITLE>$gProject $gBug report pseudo-packages</TITLE>
+ <LINK REF=\"made\" HREF=\"mailto:$gMaintainerEmail\">
+ </HEAD><BODY><H1>$gProject $gBug report pseudo-packages</H1>
+
+ This page lists the pseudo-packages available for use in the
+ <CODE>Package:</CODE> line in $gBug reports.<P>
+
+ See the <A HREF=\"../../Reporting.html\">instructions for reporting a
+ $gBug</A> for details of how to specify a <CODE>Package:</CODE> line.<P>
+ For other kinds of indices or for other information about $gProject and
+ the $gBug system, see <A HREF=\"../../\">$gBug system top-level contents WWW
+ page</A>.
+
+
+ ";