]> git.donarmstrong.com Git - debbugs.git/blobdiff - scripts/process.in
[project @ 2003-08-06 10:57:23 by cjwatson]
[debbugs.git] / scripts / process.in
index ddc85e4edf6413e391de684a91feac8a4c8f63aa..5ae31922b863b38e3b6a4eafde9a25344ab76776 100755 (executable)
@@ -1,10 +1,13 @@
 #!/usr/bin/perl
-# $Id: process.in,v 1.58 2003/01/05 17:54:23 cjwatson Exp $
+# $Id: process.in,v 1.77 2003/08/06 10:57:23 cjwatson Exp $
 #
 # Usage: process nn
 # Temps:  incoming/Pnn
 
-use Mail::Address;
+use POSIX qw(strftime tzset);
+$ENV{"TZ"} = 'UTC';
+tzset();
+
 use MIME::Parser;
 
 $config_path = '/etc/debbugs';
@@ -53,7 +56,7 @@ chomp @msg;
 
 print DEBUG "###\n",join("##\n",@msg),"\n###\n";
 
-chop($tdate= `date -u '+%a, %d %h %Y %T GMT'`);
+$tdate = strftime "%a, %d %h %Y %T UTC", localtime;
 $fwd= <<END;
 Received: via spool by $baddress\@$gEmailDomain id=$nn
           (code $codeletter ref $tryref); $tdate
@@ -97,10 +100,9 @@ if ($entity and $entity->head->tags) {
 for my $hdr (@headerlines) {
     $_ = $hdr;
     s/\n\s/ /g;
-    &quit("looping detected")
-       if m/^x-loop: (\S+)$/i && $1 eq "$gMaintainerEmail";
+    &finish if m/^x-loop: (\S+)$/i && $1 eq "$gMaintainerEmail";
     my $ins = !m/^subject:/i && !m/^reply-to:/i && !m/^return-path:/i
-           && !m/^From / && !m/^X-Debbugs-CC:/i && !m/^received:/i;
+           && !m/^From / && !m/^X-Debbugs-/i;
     $fwd .= $hdr."\n" if $ins;
     # print DEBUG ">$_<\n";
     if (s/^(\S+):\s*//) {
@@ -133,6 +135,7 @@ for my $phline (@bodylines)
 {
     last if $phline !~ m/^([\w]+):\s*(\S.*)/;
     my ($fn, $fv) = ($1, $2);
+    $fv =~ s/\s*$//;
     print DEBUG ">$fn|$fv|\n";
     $fn = lc $fn;
     $fv = lc $fv;
@@ -180,29 +183,35 @@ if ($tryref < 0 && m/^Bug ?\#(\d+)\D/i) {
 
 if ($tryref >= 0) 
 {
-    $bfound= &lockreadbugmerge($tryref);
+    ($bfound, $data)= &lockreadbugmerge($tryref);
     if ($bfound) { 
         $ref= $tryref; 
     } else {
         &htmllog("Reply","sent", $replyto,"Unknown problem report number <code>$tryref</code>.");
+        my $archivenote = '';
+        if ($gRemoveAge) {
+            $archivenote = <<END;
+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.
+
+END
+        }
         &sendmessage(<<END, '');
 From: $gMaintainerEmail ($gProject $gBug Tracking System)
 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
+References: $header{'message-id'} $data->{msgid}
+Precedence: bulk
 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
+${archivenote}Your message was dated $header{'date'} and was sent to
 $baddress\@$gEmailDomain.  It had
 Message-ID $header{'message-id'}
 and Subject $subject.
@@ -237,7 +246,7 @@ if ($codeletter eq 'D' || $codeletter eq 'F')
     $markedby= $header{'from'} eq $replyto ? $replyto :
                "$header{'from'} (reply to $replyto)";
     if ($codeletter eq 'F') {
-        (&appendlog,&finish) if length($s_forwarded);
+        (&appendlog,&finish) if length($data->{forwarded});
         $receivedat= "forwarded\@$gEmailDomain";
         $markaswhat= 'forwarded';
         $set_forwarded= $header{'to'};
@@ -247,7 +256,7 @@ if ($codeletter eq 'D' || $codeletter eq 'F')
            $generalcc=''; 
         }
     } else {
-       (&appendlog,&finish) if length($s_done);
+       (&appendlog,&finish) if length($data->{done});
         $receivedat= "done\@$gEmailDomain";
         $markaswhat= 'done';
         $set_done= $header{'from'};
@@ -266,7 +275,8 @@ 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
+References: $header{'message-id'} $data->{msgid}
+Precedence: bulk
 X-$gProject-PR-Message: error
 
 You sent a message to the $gProject $gBug tracking system old-style
@@ -303,31 +313,36 @@ END
 
     &checkmaintainers;
 
-    $noticeccval.= join(', ', grep($_ ne $replyto,@maintaddrs,@addsrcaddrs));
+    $noticeccval.= join(', ', grep($_ ne $replyto,@maintaddrs));
     $noticeccval =~ s/\s+\n\s+/ /g; 
     $noticeccval =~ s/^\s+/ /; $noticeccval =~ s/\s+$//;
 
+    $generalcc = join(', ', $generalcc, @addsrcaddrs);
+    $generalcc =~ s/\s+\n\s+/ /g; 
+    $generalcc =~ s/^\s+/ /; $generalcc =~ s/\s+$//;
+
     if (length($noticeccval)) { $noticecc= "Cc: $noticeccval\n"; }
     if (length($generalcc)) { $noticecc.= "Bcc: $generalcc\n"; }
 
-    @process= ($ref,split(/ /,$s_mergedwith));
+    @process= ($ref,split(/ /,$data->{mergedwith}));
     $orgref= $ref;
 
     for $ref (@process) {
        if ($ref != $orgref) {
            &unfilelock;
-           &lockreadbug($ref) || die "huh ? $ref from $orgref out of @process";
+           $data = &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);
-       my $hash = get_hashname($ref);
-       &overwrite("db-h/$hash/$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");
-       &bughook('change',$ref,
-                  "$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");
+        $data->{done}= $set_done if defined($set_done);
+        $data->{forwarded}= $set_forwarded if defined($set_forwarded);
+        if ($codeletter eq 'D') {
+            $data->{keywords} = join ' ', grep $_ ne 'pending',
+                                     split ' ', $data->{keywords};
+        }
 
+       writebug($ref, $data);
+
+       my $hash = get_hashname($ref);
         open(O,"db-h/$hash/$ref.report") || &quit("read original report: $!");
         $x= join('',<O>); close(O);
         if ($codeletter eq 'F') {
@@ -335,18 +350,21 @@ END
             &sendmessage(<<END."---------------------------------------\n".join( "\n", @msg ), '');
 From: $gMaintainerEmail ($gProject $gBug Tracking System)
 To: $replyto
-${noticecc}Subject: $gBug#$ref: marked as forwarded ($s_subject)
+${noticecc}Subject: $gBug#$ref: marked as forwarded ($data->{subject})
 Message-ID: <header.$ref.$nn.ackfwdd\@$gEmailDomain>
 In-Reply-To: $header{'message-id'}
-References: $header{'message-id'} $s_msgid
+References: $header{'message-id'} $data->{msgid}
+Precedence: bulk
 X-$gProject-PR-Message: forwarded $ref
+X-$gProject-PR-Package: $data->{package}
+X-$gProject-PR-Keywords: $data->{keywords}
 
 Your message dated $header{'date'}
 with message-id $header{'message-id'}
 has caused the $gProject $gBug report #$ref,
-regarding $s_subject
+regarding $data->{subject}
 to be marked as having been forwarded to the upstream software
-author(s) $s_forwarded.
+author(s) $data->{forwarded}.
 
 (NB: If you are a system administrator and have no idea what I am
 talking about this indicates a serious mail system misconfiguration
@@ -362,11 +380,14 @@ END
             &sendmessage(<<END."--------------------------------------\n".$x."---------------------------------------\n".join( "\n", @msg ), '');
 From: $gMaintainerEmail ($gProject $gBug Tracking System)
 To: $replyto
-${noticecc}Subject: $gBug#$ref: marked as done ($s_subject)
+${noticecc}Subject: $gBug#$ref: marked as done ($data->{subject})
 Message-ID: <handler.$ref.$nn.ackdone\@$gEmailDomain>
 In-Reply-To: $header{'message-id'}
-References: $header{'message-id'} $s_msgid
+References: $header{'message-id'} $data->{msgid}
+Precedence: bulk
 X-$gProject-PR-Message: closed $ref
+X-$gProject-PR-Package: $data->{package}
+X-$gProject-PR-Keywords: $data->{keywords}
 
 Your message dated $header{'date'}
 with message-id $header{'message-id'}
@@ -385,22 +406,24 @@ $gMaintainer
 (administrator, $gProject $gBugs database)
 
 END
-            &htmllog("Notification","sent",$s_originator
+            &htmllog("Notification","sent",$data->{originator}
                "$gBug acknowledged by developer.");
             &sendmessage(<<END.join("\n",@msg),'');
 From: $gMaintainerEmail ($gProject $gBug Tracking System)
-To: $s_originator
+To: $data->{originator}
 Subject: $gBug#$ref acknowledged by developer
          ($header{'subject'})
 Message-ID: <handler.$ref.$nn.notifdone\@$gEmailDomain>
-In-Reply-To: $s_msgid
-References: $header{'message-id'} $s_msgid
+In-Reply-To: $data->{msgid}
+References: $header{'message-id'} $data->{msgid}
 X-$gProject-PR-Message: they-closed $ref
+X-$gProject-PR-Package: $data->{package}
+X-$gProject-PR-Keywords: $data->{keywords}
 Reply-To: $ref\@$gEmailDomain
 
 This is an automatic notification regarding your $gBug report
-#$ref: $s_subject,
-which was filed against the $s_package package.
+#$ref: $data->{subject},
+which was filed against the $data->{package} package.
 
 It has been closed by one of the developers, namely
 $markedby.
@@ -429,7 +452,8 @@ 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
+References: $header{'message-id'} $data->{msgid}
+Precedence: bulk
 X-$gProject-PR-Message: error
 
 You sent a message to the $gProject $gBug tracking system send to $gBug 
@@ -473,7 +497,8 @@ Subject: Message with no Package: tag cannot be processed!
          ($subject)
 Message-ID: <handler.x.$nn.nonumnosub\@$gEmailDomain>
 In-Reply-To: $header{'message-id'}
-References: $header{'message-id'} $s_msgid
+References: $header{'message-id'} $data->{msgid}
+Precedence: bulk
 X-$gProject-PR-Message: error
 
 Your message didn't have a Package: line at the start (in the
@@ -481,8 +506,9 @@ pseudo-header following the real mail header), or didn't have a
 pseudo-header at all.
 
 This makes it much harder for us to categorise and deal with your
-problem report. Please _resubmit_ your report and tell us which package
-the report is on. For help, check out http://$gWebDomain/Reporting.html.
+problem report. Please _resubmit_ your report to $baddress\@$gEmailDomain
+and tell us which package the report is on. For help, check out
+http://$gWebDomain/Reporting$gHTMLSuffix.
 
 Your message was dated $header{'date'} and had
 message-id $header{'message-id'}
@@ -498,54 +524,54 @@ END
        &appendlog;
        &finish;
     } else {
-       $s_package= $pheader{'package'}; 
+       $data->{package}= $pheader{'package'}; 
     }
 
-    $s_versions= '';
+    $data->{versions}= '';
     if (defined($pheader{'version'})) {
-        $s_versions = $pheader{'version'};
-        $s_versions =~ s/\s+/ /;
+        $data->{versions} = $pheader{'version'};
+        $data->{versions} =~ s/\s+/ /;
        # BUG: need to bounce unknown versions back to submitter here
     }
 
-    $s_fixed_versions= '';
+    $data->{fixed_versions}= '';
     if (defined($pheader{'fixed-in-version'})) {
-        $s_fixed_versions = $pheader{'fixed-in-version'};
-        $s_fixed_versions =~ s/\s+/ /;
+        $data->{fixed_versions} = $pheader{'fixed-in-version'};
+        $data->{fixed_versions} =~ s/\s+/ /;
     }
 
-    $s_keywords= '';
+    $data->{keywords}= '';
     if (defined($pheader{'keywords'})) {
-        $s_keywords= $pheader{'keywords'};
+        $data->{keywords}= $pheader{'keywords'};
     } elsif (defined($pheader{'tags'})) {
-        $s_keywords= $pheader{'tags'};
+        $data->{keywords}= $pheader{'tags'};
     }
-    if (length($s_keywords)) {
+    if (length($data->{keywords})) {
         my @kws;
         my %gkws = map { ($_, 1) } @gTags;
-        foreach my $kw (sort split(/[,\s]+/, lc($s_keywords))) {
+        foreach my $kw (sort split(/[,\s]+/, lc($data->{keywords}))) {
             push @kws, $kw if (defined $gkws{$kw});
         }
-        $s_keywords = join(" ", @kws);
+        $data->{keywords} = join(" ", @kws);
     }
-    $s_severity= '';
+    $data->{severity}= '';
     if (defined($pheader{'severity'}) || defined($pheader{'priority'})) {
-       $s_severity= $pheader{'severity'};
-       $s_severity= $pheader{'priority'} unless ($s_severity);
-       $s_severity =~ s/^\s*(.+)\s*$/$1/;
+       $data->{severity}= $pheader{'severity'};
+       $data->{severity}= $pheader{'priority'} unless ($data->{severity});
+       $data->{severity} =~ s/^\s*(.+)\s*$/$1/;
 
-       if (!grep($_ eq $s_severity, @severities, "$gDefaultSeverity")) {
+       if (!grep($_ eq $data->{severity}, @severities, "$gDefaultSeverity")) {
             $brokenness.= <<END;
 
 Your message specified a Severity: in the pseudo-header, but
-the severity value $s_severity was not recognised.
+the severity value $data->{severity} was not recognised.
 The default severity $gDefaultSeverity is being used instead.
 The recognised values are: $gShowSeverities.
 END
 # if we use @gSeverityList array in the above line, perl -c gives:
 # In string, @gSeverityList now must be written as \@gSeverityList at
 #          process line 452, near "$gDefaultSeverity is being used instead.
-            $s_severity= '';
+            $data->{severity}= '';
         }
     }
     &filelock("nextnumber.lock");
@@ -556,14 +582,11 @@ END
     &unfilelock;
     my $hash = get_hashname($ref);
     &overwrite("db-h/$hash/$ref.log",'');
-    &overwrite("db-h/$hash/$ref.status",
-               "$replyto\n$intdate\n$subject\n$header{'message-id'}\n".
-               "$s_package\n$s_keywords\n\n\n\n$s_severity\n$s_versions\n".
-               "$s_fixed_versions\n");
-    &bughook('new',$ref,
-               "$replyto\n$intdate\n$subject\n$header{'message-id'}\n".
-               "$s_package\n$s_keywords\n\n\n\n$s_severity\n$s_versions\n".
-               "$s_fixed_versions\n");
+    $data->{originator} = $replyto;
+    $data->{date} = $intdate;
+    $data->{subject} = $subject;
+    $data->{msgid} = $header{'message-id'};
+    writebug($ref, $data);
     &overwrite("db-h/$hash/$ref.report",
                join("\n",@msg)."\n");
 }
@@ -594,7 +617,7 @@ Your message has been sent to the package maintainer(s):
 END
 }
 
-push(@resentccs, @addsrcaddrs);
+@bccs = @addsrcaddrs;
 
 $veryquiet= $codeletter eq 'Q';
 if ($codeletter eq 'M' && !@maintaddrs) {
@@ -619,26 +642,26 @@ if (length($resentccval)) {
 }
 
 if ($codeletter eq 'U') {
-    &htmllog("Message", "sent on", $s_originator, "$gBug#$ref.");
-    &sendmessage(<<END,$s_originator,@resentccs);
+    &htmllog("Message", "sent on", $data->{originator}, "$gBug#$ref.");
+    &sendmessage(<<END,[$data->{originator},@resentccs],[@bccs]);
 Subject: $gBug#$ref: $newsubject
 Reply-To: $replyto, $ref-quiet\@$gEmailDomain
-${orgsender}Resent-To: $s_originator
+${orgsender}Resent-To: $data->{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
+X-$gProject-PR-Package: $data->{package}
+X-$gProject-PR-Keywords: $data->{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($data->{package})? "; Package <code>".&sani($data->{package})."</code>" : '').
              ".");
-    &sendmessage(<<END,"$gSubmitList\@$gListDomain",@resentccs);
+    &sendmessage(<<END,["$gSubmitList\@$gListDomain",@resentccs],[@bccs]);
 Subject: $gBug#$ref: $newsubject
 Reply-To: $replyto, $ref\@$gEmailDomain
 Resent-From: $header{'from'}
@@ -647,20 +670,28 @@ ${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
+X-$gProject-PR-Package: $data->{package}
+X-$gProject-PR-Keywords: $data->{keywords}
 $fwd
 END
-} elsif (@resentccs) {
+} elsif (@resentccs or @bccs) {
     # 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>" : '').
-             ".");
-    &sendmessage(<<END,@resentccs);
+    if (@resentccs) {
+        &htmllog($newref ? "Report" : "Information", "forwarded",
+                 $resentccval,
+                 "<code>$gBug#$ref</code>".
+                 (length($data->{package}) ? "; Package <code>".&sani($data->{package})."</code>" : '').
+                 ".");
+    } else {
+        &htmllog($newref ? "Report" : "Information", "stored",
+                 "",
+                 "<code>$gBug#$ref</code>".
+                 (length($data->{package}) ? "; Package <code>".&sani($data->{package})."</code>" : '').
+                 ".");
+    }
+    &sendmessage(<<END,[@resentccs],[@bccs]);
 Subject: $gBug#$ref: $newsubject
 Reply-To: $replyto, $ref-$baddressroot\@$gEmailDomain
 Resent-From: $header{'from'}
@@ -669,8 +700,8 @@ 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
+X-$gProject-PR-Package: $data->{package}
+X-$gProject-PR-Keywords: $data->{keywords}
 $fwd
 END
 }
@@ -681,12 +712,13 @@ 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,'');
+unless (exists $header{'x-debbugs-no-ack'}) {
+    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 ($gProject $gBug Tracking System)
 To: $replyto
 Subject: $gBug#$ref: Acknowledgement of QUIET report
@@ -694,15 +726,18 @@ Subject: $gBug#$ref: Acknowledgement of QUIET report
 Message-ID: <handler.$ref.$nn.ackquiet\@$gEmailDomain>
 In-Reply-To: $header{'message-id'}
 References: $header{'message-id'}
+Precedence: bulk
 X-$gProject-PR-Message: ack-quiet $ref
+X-$gProject-PR-Package: $data->{package}
+X-$gProject-PR-Keywords: $data->{keywords}
 Reply-To: $ref-quiet\@$gEmailDomain
 
 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.
+has been received.  It has not been forwarded to the package maintainers
+or other interested parties; 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*
@@ -721,13 +756,17 @@ Subject: $gBug#$ref: Acknowledgement of maintainer-only report
 Message-ID: <handler.$ref.$nn.ackmaint\@$gEmailDomain>
 In-Reply-To: $header{'message-id'}
 References: $header{'message-id'}
+Precedence: bulk
 X-$gProject-PR-Message: ack-maintonly $ref
+X-$gProject-PR-Package: $data->{package}
+X-$gProject-PR-Keywords: $data->{keywords}
 Reply-To: $ref-maintonly\@$gEmailDomain
 
 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.
+been received.  It is being forwarded to the package maintainers (but not
+other interested parties, 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*
@@ -745,13 +784,16 @@ Subject: $gBug#$ref: Acknowledgement ($subject)
 Message-ID: <handler.$ref.$nn.ack\@$gEmailDomain>
 In-Reply-To: $header{'message-id'}
 References: $header{'message-id'}
+Precedence: bulk
 X-$gProject-PR-Message: ack $ref
+X-$gProject-PR-Package: $data->{package}
+X-$gProject-PR-Keywords: $data->{keywords}
 Reply-To: $ref\@$gEmailDomain
 
 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.
+been received.  It is being forwarded to the package maintainers and other
+interested parties 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
@@ -763,12 +805,13 @@ $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,'');
+    } elsif ($codeletter ne 'U' and
+             $header{'precedence'} !~ /\b(?:bulk|junk|list)\b/) {
+        &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 ($gProject $gBug Tracking System)
 To: $replyto
 Subject: $gBug#$ref: Info received and FILED only
@@ -776,14 +819,17 @@ Subject: $gBug#$ref: Info received and FILED only
 Message-ID: <handler.$ref.$nn.ackinfoquiet\@$gEmailDomain>
 In-Reply-To: $header{'message-id'}
 References: $header{'message-id'}
+Precedence: bulk
 X-$gProject-PR-Message: ack-info-quiet $ref
+X-$gProject-PR-Package: $data->{package}
+X-$gProject-PR-Keywords: $data->{keywords}
 Reply-To: $ref-quiet\@$gEmailDomain
 
 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.
+this problem report.  It has NOT been forwarded to the package
+maintainers, 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.
@@ -801,12 +847,15 @@ Subject: $gBug#$ref: Info received for maintainer only
 Message-ID: <handler.$ref.$nn.ackinfomaint\@$gEmailDomain>
 In-Reply-To: $header{'message-id'}
 References: $header{'message-id'}
+Precedence: bulk
 X-$gProject-PR-Message: ack-info-maintonly $ref
+X-$gProject-PR-Package: $data->{package}
+X-$gProject-PR-Keywords: $data->{keywords}
 Reply-To: $ref-maintonly\@$gEmailDomain
 
 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.
+this problem report.  It has been forwarded to the package maintainer(s)
+(but not to other interested parties) 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.
@@ -823,12 +872,14 @@ Subject: $gBug#$ref: Info received (was $subject)
 Message-ID: <handler.$ref.$nn.ackinfo\@$gEmailDomain>
 In-Reply-To: $header{'message-id'}
 References: $header{'message-id'}
+Precedence: bulk
 X-$gProject-PR-Message: ack-info $ref
-Disabled-Doogie-Reply-To: $ref\@$gEmailDomain
+X-$gProject-PR-Package: $data->{package}
+X-$gProject-PR-Keywords: $data->{keywords}
 
 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.
+this problem report.  It has been forwarded to the package maintainer(s)
+and to other interested parties 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.
@@ -839,6 +890,10 @@ $brokenness
 $gMaintainer
 (administrator, $gProject $gBugs database)
 END
+# Reply-To: in previous ack disabled by doogie due to mail loops.
+# Are these still a concern?
+# Reply-To: $ref\@$gEmailDomain
+    }
 }
 
 &appendlog;
@@ -881,34 +936,61 @@ sub htmllog {
     open(AP,">>db-h/$hash/$ref.log") || &quit("opening db-h/$hash/$ref.log (lh): $!");
     print(AP
           "\6\n".
-          "<strong>$whatobj $whatverb</strong> to <code>".&sani($where).
-          "</code>:<br>\n". $desc.
+          "<strong>$whatobj $whatverb</strong>".
+          ($where eq '' ? "" : " to <code>".&sani($where)."</code>").
+          ":<br>\n". $desc.
           "\n\3\n") || &quit("writing db-h/$hash/$ref.log (lh): $!");
     close(AP) || &quit("closing db-h/$hash/$ref.log (lh): $!");
 }    
 
-sub get_addresses {
-       return
-               map { $_->address() }
-               map { Mail::Address->parse($_) } @_;
+sub stripbccs {
+    my $msg = shift;
+    my $ret = '';
+    my $bcc = 0;
+    while ($msg =~ s/(.*\n)//) {
+       local $_ = $1;
+       if (/^$/) {
+           $ret .= $_;
+           last;
+       }
+       if ($bcc) {
+           # strip continuation lines too
+           next if /^\s/;
+           $bcc = 0;
+       }
+       if (/^Bcc:/i) {
+           $bcc = 1;
+       } else {
+           $ret .= $_;
+       }
+    }
+    return $ret . $msg;
 }
 
 sub sendmessage {
-    local ($msg,@recips) = @_;
-    if ($recips[0] eq '' && $#recips == 0) { @recips= ('-t'); }
+    local ($msg,$recips,$bcc) = @_;
+    if ((!ref($recips) && $recips eq '') || @$recips == 0) {
+        $recips = ['-t'];
+    }
     $msg = "X-Loop: $gMaintainerEmail\n" . $msg;
 
     my $hash = get_hashname($ref);
     #save email to the log
     open(AP,">>db-h/$hash/$ref.log") || &quit("opening db-h/$hash/$ref.log (lo): $!");
-    print(AP "\2\n",join("\4",@recips),"\n\5\n",@{escapelog($msg)},"\n\3\n") ||
+    print(AP "\2\n",join("\4",@$recips),"\n\5\n",
+          @{escapelog(stripbccs($msg))},"\n\3\n") ||
         &quit("writing db-h/$hash/$ref.log (lo): $!");
     close(AP) || &quit("closing db-h/$hash/$ref.log (lo): $!");
-    
-#if debbuging.. save email to a log
+
+    if (ref($bcc)) {
+        shift @$recips if $recips->[0] eq '-t';
+        push @$recips, @$bcc;
+    }
+
+#if debugging.. save email to a log
 #    open AP, ">>debug";
-#    print AP join( '|', @recips )."\n>>";
-#    print AP get_addresses( @recips );
+#    print AP join( '|', @$recips )."\n>>";
+#    print AP get_addresses( @$recips );
 #    print AP "<<\n".$msg;
 #    print AP "\n--------------------------------------------------------\n";
 #    close AP;
@@ -938,7 +1020,7 @@ sub sendmessage {
        #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",'-odq','-oem','-oi',get_addresses(@recips);
+            exec '/usr/lib/sendmail','-f'."$gMaintainerEmail",'-odq','-oem','-oi',get_addresses(@$recips);
            #print DEBUG "mailing grandchild exec failed<\n";
             die $!;
            #print DEBUG "mailing grandchild died !?<\n";
@@ -970,7 +1052,7 @@ sub sendmessage {
 
 sub checkmaintainers {
     return if $maintainerschecked++;
-    return if !length($s_package);
+    return if !length($data->{package});
     open(MAINT,"$gMaintainerFile") || die &quit("maintainers open: $!");
     while (<MAINT>) {
        m/^\n$/ && next;
@@ -998,7 +1080,7 @@ sub checkmaintainers {
     }
     close(SOURCES);
     $anymaintfound=0; $anymaintnotfound=0;
-    for $p (split(m/[ \t?,()]+/,$s_package)) {
+    for $p (split(m/[ \t?,()]+/,$data->{package})) {
         $p =~ y/A-Z/a-z/;
        if (defined $gSubscriptionDomain) {
            if (defined($pkgsrc{$p})) {