]> git.donarmstrong.com Git - debbugs.git/blob - scripts/process.in
3e6b7ee86a06ae0d9aed832e377426d64cc6f7a6
[debbugs.git] / scripts / process.in
1 #!/usr/bin/perl
2 # $Id: process.in,v 1.5 1999/09/17 22:07:34 gecko Exp $
3 #
4 # Usage: process nn
5 # Temps:  incoming/Pnn
6
7 use Mail::Address;
8 require( '/etc/debbugs/config' );
9 require( '/usr/lib/debbugs/errorlib' );
10 chdir( "$gSpoolDir" ) || die 'chdir spool: $!\n';
11 @showseverities=();
12
13 #open(DEBUG,"> /tmp/debbugs.debug");
14
15 defined( $intdate= time ) || &quit( "failed to get time: $!" );
16
17 $_=shift;
18 m/^([BMQFDU])(\d*)\.\d+$/ || &quit("bad argument");
19 $codeletter= $1;
20 $tryref= length($2) ? $2+0 : -1;
21 $nn= $_;
22
23 if (!rename("incoming/G$nn","incoming/P$nn")) 
24 {       $_=$!.'';  m/no such file or directory/i && exit 0;
25     &quit("renaming to lock: $!");
26 }    
27
28 $baddress= 'bugs' if $codeletter eq 'B';
29 $baddress= 'maintonly' if $codeletter eq 'M';
30 $baddress= 'quiet' if $codeletter eq 'Q';
31 $baddress= 'forwarded' if $codeletter eq 'F';
32 $baddress= 'done' if $codeletter eq 'D';
33 $baddress= 'submitter' if $codeletter eq 'U';
34 $baddress || &quit("bad codeletter $codeletter");
35 $baddressroot= $baddress;
36 $baddress= "$tryref-$baddress" if $tryref>=0;
37
38 open(M,"incoming/P$nn");
39 @log=<M>;
40 close(M);
41
42 @msg=@log;
43 grep(s/\n+$//,@msg);
44
45 print DEBUG "###\n",join("##\n",@msg),"\n###\n";
46
47 chop($tdate= `date -u '+%a, %d %h %Y %T GMT'`);
48 $fwd= <<END;
49 X-Loop: $gMaintainerEmail
50 Received: via spool by $baddress\@$gEmailDomain id=$nn
51           (code $codeletter ref $tryref); $tdate
52 END
53
54 for ($i=0; $i<=$#msg; $i++) {
55     $_ = $msg[$i];
56     last unless length($_);
57     &quit("looping detected") if m/^x-loop: (\S+)$/i && $1 eq "$gMaintainerEmail";
58     $ins= !m/^subject:/i && !m/^reply-to:/i && !m/^return-path:/i
59        && !m/^From / && !m/^X-Debbugs-CC:/i && !m/^received:/i;
60     $fwd .= $_."\n" if $ins;
61     while ($msg[$i+1] =~ m/^\s/) {
62         $i++;
63         $fwd .= $msg[$i]."\n" if $ins;
64         $_ .= ' '.$msg[$i];
65     }
66 # print DEBUG ">$_<\n";
67     if (s/^(\S+):\s*//) {
68         $v= $1; $v =~ y/A-Z/a-z/;
69                 print DEBUG ">$v=$_<\n";
70         $header{$v}= $_;
71     } else {
72         print DEBUG "!>$_<\n";
73     }
74 }
75
76 #remove blank lines
77 while ($i <= $#msg && !length($msg[$i])) { $fwd .= "\n"; $i++; }
78
79 #skips the "this is mime" message and any blank space after it
80 if ( $msg[$i] =~ /^This is a multi-part message in MIME format./ )
81 {
82         while ( $i <= $#msg && length( $msg[$i] ) ) { $fwd .= $msg[$i] . "\n"; $i++; }
83         while ( $i <= $#msg && !length( $msg[$i] ) ) { $fwd .= "\n"; $i++; }
84 }
85 #if the lines starts with -- or is nothing but blank space...
86 #skip to the next blank line(s) then skip past the blank line(s)
87 if ( $msg[$i] =~ /^--/ || $msg[$i] =~ /^\s*$/ )
88 {
89         while ( $i <= $#msg && length( $msg[$i] ) ) { $fwd .= $msg[$i] . "\n"; $i++; }
90         while ( $i <= $#msg && !length( $msg[$i] ) ) { $fwd .= "\n"; $i++; }
91 }               
92
93 while (defined ($msg[$i] ) )
94 {
95         last if ( $msg[$i] !~ m/^([\w]+):\s*(\S+)/ );
96         $i++;
97         $fn = $1; $fv = $2;
98         print DEBUG ">$fn|$'|\n";
99     $fwd .= $fn.': '.$fv."\n";
100     $fn =~ y/A-Z/a-z/;
101     $pheader{$fn}= $fv;
102         print DEBUG ">$fn~$fv<\n";
103 }
104
105
106 $fwd .= join("\n",@msg[$i..$#msg]);
107
108 print DEBUG "***\n$fwd\n***\n";
109
110 defined($header{'from'}) || &quit("no From header");
111 $replyto= defined($header{'reply-to'}) ? $header{'reply-to'} : $header{'from'};
112
113 $_= $replyto;
114 $_= "$2 <$1>" if m/^([^\<\> \t\n\(\)]+) \(([^\(\)\<\>]+)\)$/;
115 $replytocompare= $_;
116 print DEBUG "replytocompare >$replytocompare<\n";
117     
118 if (!defined($header{'subject'})) 
119 {       $brokenness.= <<END;
120
121 Your message did not contain a Subject field.  This is broken, I am
122 afraid - the Subject: line is a Required Header according to RFC822.
123 Please remember to include a Subject field in your messages in future.
124 If you did so the fact that it got lost probably indicates a poorly
125 configured mail system at your site or an intervening one.
126 END
127     $subject= '(no subject)';
128 } else { $subject= $header{'subject'}; }
129
130 $ref=-1;
131 $subject =~ s/^Re:\s*//i; $_= $subject."\n";
132 if ($tryref < 0 && m/^Bug ?\#(\d+)\D/i) { $tryref= $1+0; }
133
134 if ($tryref >= 0) 
135 {       $bfound= &lockreadbugmerge($tryref);
136     if ($bfound) { $ref= $tryref; } 
137         else 
138         {       &htmllog("Reply","sent", $replyto,"Unknown problem report number <code>$tryref</code>.");
139         &sendmessage(<<END, '');
140 From: $gMaintainerEmail ($gProject $gBug Tracking System)
141 To: $replyto
142 Subject: Unknown problem report $gBug#$tryref ($subject)
143 Message-ID: <handler.x.$nn.unknown\@$gEmailDomain>
144 In-Reply-To: $header{'message-id'}
145 References: $header{'message-id'} $s_msgid
146 X-$gProject-PR-Message: error
147
148 You sent a message to the $gBug tracking system which gave (in the
149 Subject line or encoded into the recipient at $gEmailDomain),
150 the number of a nonexistent $gBug report (#$tryref).
151
152 This may be because that $gBug report has been resolved for more than $gRemoveAge
153 days, and the record of it has been expunged, or because you mistyped
154 the $gBug report number.
155
156 Your message was dated $header{'date'} and was sent to
157 $baddress\@$gEmailDomain.  It had
158 Message-ID $header{'message-id'}
159 and Subject $subject.
160
161 It has been filed (under junk) but otherwise ignored.
162
163 Please consult your records to find the correct $gBug report number, or
164 contact me, the system administrator, for assistance.
165
166 $gMaintainer
167 (administrator, $gProject $gBugs database)
168
169 (NB: If you are a system administrator and have no idea what I am
170 talking about this indicates a serious mail system misconfiguration
171 somewhere.  Please contact me immediately.)
172
173 END
174                 &appendlog;
175         &finish;
176     }
177 } else { &filelock('lock/-1'); }
178
179 if ($codeletter eq 'D' || $codeletter eq 'F') 
180 {       if ($replyto =~ m/$gBounceFroms/o ||
181                 $header{'from'} =~ m/$gBounceFroms/o) 
182                 { &quit("bounce detected !  Mwaap! Mwaap!"); }
183     $markedby= $header{'from'} eq $replyto ? $replyto :
184                "$header{'from'} (reply to $replyto)";
185     if ($codeletter eq 'F') 
186         {       (&appendlog,&finish) if length($s_forwarded);
187         $receivedat= "forwarded\@$gEmailDomain";
188         $markaswhat= 'forwarded';
189         $set_forwarded= $header{'to'};
190                 if ( length( $gListDomain ) > 0 && length( $gFowardList ) > 0 ) 
191                         { $generalcc= "$gFowardList\@$gListDomain"; } 
192                 else { $generalcc=''; }
193     } else 
194         {       (&appendlog,&finish) if length($s_done);
195         $receivedat= "done\@$gEmailDomain";
196         $markaswhat= 'done';
197         $set_done= $header{'from'};
198                 if ( length( $gListDomain ) > 0 && length( $gDoneList ) > 0 ) 
199                         { $generalcc= "$gDoneList\@$gListDomain"; } 
200                 else { $generalcc=''; }
201     }
202     if ($ref<0) 
203         {       &htmllog("Warning","sent",$replyto,"Message ignored.");
204         &sendmessage(<<END, '');
205 From: $gMaintainerEmail ($gProject $gBug Tracking System)
206 To: $replyto
207 Subject: Message with no $gBug number ignored by $receivedat
208          ($subject)
209 Message-ID: <header.x.$nn.warnignore\@$gEmailDomain>
210 In-Reply-To: $header{'message-id'}
211 References: $header{'message-id'} $s_msgid
212 X-$gProject-PR-Message: error
213
214 You sent a message to the $gProject $gBug tracking system old-style
215 unified mark as $markaswhat address ($receivedat),
216 without a recognisable $gBug number in the Subject.
217 Your message has been filed under junk but otherwise ignored.
218
219 If you don't know what I'm talking about then probably either:
220
221 (a) you unwittingly sent a message to done\@$gEmailDomain
222 because you replied to all recipients of the message a developer used
223 to mark a $gBug as done and you modified the Subject.  In this case,
224 please do not be alarmed.  To avoid confusion do not do it again, but
225 there is no need to apologise or mail anyone asking for an explanation.
226
227 (b) you are a system administrator, reading this because the $gBug 
228 tracking system is responding to a misdirected bounce message.  In this
229 case there is a serious mail system misconfiguration somewhere - please
230 contact me immediately.
231
232 Your message was dated $header{'date'} and had
233 message-id $header{'message-id'}
234 and subject $subject.
235
236 If you need any assistance or explanation please contact me.
237
238 $gMaintainer
239 (administrator, $gProject $gBugs database)
240
241 END
242                 &appendlog;
243                 &finish;
244     }
245     &checkmaintainers;
246     $noticeccval.= join(', ', grep($_ ne $replyto,@maintaddrs));
247     $noticeccval =~ s/\s+\n\s+/ /g; $noticeccval =~ s/^\s+/ /; $noticeccval =~ s/\s+$//;
248     if (length($noticeccval)) { $noticecc= "Cc: $noticeccval\n"; }
249         if (length($generalcc)) { $noticecc.= "Bcc: $generalcc\n"; }
250     @process= ($ref,split(/ /,$s_mergedwith));
251     $orgref= $ref;
252     for $ref (@process) 
253         {       if ($ref != $orgref) 
254                 {       &unfilelock;
255                 &lockreadbug($ref) || die "huh ? $ref from $orgref out of @process";
256                 }
257         $s_done= $set_done if defined($set_done);
258         $s_forwarded= $set_forwarded if defined($set_forwarded);
259                 &overwrite("db/$ref.status",
260                    "$s_originator\n$s_date\n$s_subject\n$s_msgid\n".
261                    "$s_package\n$s_keywords\n$s_done\n$s_forwarded\n$s_mergedwith\n$s_severity\n");
262         open(O,"db/$ref.report") || &quit("read original report: $!");
263         $x= join('',<O>); close(O);
264         if ($codeletter eq 'F') 
265                 {       &htmllog("Reply","sent",$replyto,"You have marked $gBug as forwarded.");
266             &sendmessage(<<END.$x, '');
267 From: $gMaintainerEmail ($gProject $gBug Tracking System)
268 To: $replyto
269 ${noticecc}Subject: $gBug#$ref: marked as forwarded ($s_subject)
270 Message-ID: <header.$ref.$nn.ackfwdd\@$gEmailDomain>
271 In-Reply-To: $header{'message-id'}
272 References: $header{'message-id'} $s_msgid
273 X-$gProject-PR-Message: forwarded $ref
274
275 Your message dated $header{'date'}
276 with message-id $header{'message-id'}
277 and subject line $subject
278 has caused the $gProject $gBug report #$ref,
279 regarding $s_subject
280 to be marked as having been forwarded to the upstream software
281 author(s) $s_forwarded.
282
283 (NB: If you are a system administrator and have no idea what I am
284 talking about this indicates a serious mail system misconfiguration
285 somewhere.  Please contact me immediately.)
286
287 $gMaintainer
288 (administrator, $gProject $gBugs database)
289
290 END
291         } else 
292                 {   &htmllog("Reply","sent",$replyto,"You have taken responsibility.");
293             &sendmessage(<<END.$x, '');
294 From: $gMaintainerEmail ($gProject $gBug Tracking System)
295 To: $replyto
296 ${noticecc}Subject: $gBug#$ref: marked as done ($s_subject)
297 Message-ID: <handler.$ref.$nn.ackdone\@$gEmailDomain>
298 In-Reply-To: $header{'message-id'}
299 References: $header{'message-id'} $s_msgid
300 X-$gProject-PR-Message: closed $ref
301
302 Your message dated $header{'date'}
303 with message-id $header{'message-id'}
304 and subject line $subject
305 has caused the attached $gBug report to be marked as done.
306
307 This means that you claim that the problem has been dealt with.
308 If this is not the case it is now your responsibility to reopen the
309 $gBug report if necessary, and/or fix the problem forthwith.
310
311 (NB: If you are a system administrator and have no idea what I am
312 talking about this indicates a serious mail system misconfiguration
313 somewhere.  Please contact me immediately.)
314
315 $gMaintainer
316 (administrator, $gProject $gBugs database)
317
318 END
319             &htmllog("Notification","sent",$s_originator, 
320                                 "$gBug acknowledged by developer.");
321             &sendmessage(<<END.join("\n",@msg),'');
322 From: $gMaintainerEmail ($gProject $gBug Tracking System)
323 To: $s_originator
324 Subject: $gBug#$ref acknowledged by developer ($s_subject)
325 Message-ID: <handler.$ref.$nn.notifdone\@$gEmailDomain>
326 In-Reply-To: $s_msgid
327 References: $header{'message-id'} $s_msgid
328 X-$gProject-PR-Message: they-closed $ref
329
330 This is an automatic notification regarding your $gBug report.
331
332 It has been closed by one of the developers, namely
333 $markedby.
334
335 Their explanation is attached below.  If this explanation is
336 unsatisfactory and you have not received a better one in a separate
337 message then please contact the developer directly, or email
338 submit\@$gEmailDomain or me.
339
340 $gMaintainer
341 (administrator, $gProject $gBugs database)
342
343 END
344         }
345                 &appendlog;
346     }
347     &finish;
348 }
349
350 if ($ref<0) 
351 {       if ($codeletter eq 'U') 
352         {       &htmllog("Warning","sent",$replyto,"Message not forwarded.");
353         &sendmessage(<<END, '');
354 From: $gMaintainerEmail ($gProject $gBug Tracking System)
355 To: $replyto
356 Subject: Message with no $gBug number cannot be sent to submitter !
357          ($subject)
358 Message-ID: <handler.x.$nn.nonumnosub\@$gEmailDomain>
359 In-Reply-To: $header{'message-id'}
360 References: $header{'message-id'} $s_msgid
361 X-$gProject-PR-Message: error
362
363 You sent a message to the $gProject $gBug tracking system send to $gBug 
364 report submitter address $baddress\@$gEmailDomain, without a
365 recognisable $gBug number in the Subject.  Your message has been filed
366 under junk but otherwise ignored.
367
368 If you don't know what I'm talking about then probably either:
369
370 (a) you unwittingly sent a message to $baddress\@$gEmailDomain
371 because you replied to all recipients of the message a developer sent
372 to a $gBug's submitter and you modified the Subject.  In this case,
373 please do not be alarmed.  To avoid confusion do not do it again, but
374 there is no need to apologise or mail anyone asking for an
375 explanation.
376
377 (b) you are a system administrator, reading this because the $gBug 
378 tracking system is responding to a misdirected bounce message.  In this
379 case there is a serious mail system misconfiguration somewhere - please
380 contact me immediately.
381
382 Your message was dated $header{'date'} and had
383 message-id $header{'message-id'}
384 and subject $subject.
385
386 If you need any assistance or explanation please contact me.
387
388 $gMaintainer
389 (administrator, $gProject $gBugs database)
390
391 END
392         &appendlog;
393         &finish;
394     }
395     if (!defined($pheader{'package'}))
396         {       &htmllog("Warning","sent",$replyto,"Message not forwarded.");
397         &sendmessage(<<END, '');
398 From: $gMaintainerEmail ($gProject $gBug Tracking System)
399 To: $replyto
400 Subject: Message with no Package: tag cannot be processed!
401          ($subject)
402 Message-ID: <handler.x.$nn.nonumnosub\@$gEmailDomain>
403 In-Reply-To: $header{'message-id'}
404 References: $header{'message-id'} $s_msgid
405 X-$gProject-PR-Message: error
406
407 Your message didn't have a Package: line at the start (in the
408 pseudo-header following the real mail header), or didn't have a
409 psuedo-header at all.
410
411 This makes it much harder for us to categorise and deal with your
412 problem report. Please resubmit your report and tell us which package the
413 report is on.  For help, check out http://$gWebDomain/Reporting.html.
414
415 Your message was dated $header{'date'} and had
416 message-id $header{'message-id'}
417 and subject $subject.
418
419 If you need any assistance or explanation please contact me.
420
421 $gMaintainer
422 (administrator, $gProject $gBugs database)
423
424 END
425         &appendlog;
426         &finish;
427     } else {
428         $s_package= $pheader{'package'};
429                 print "Package: $s_package\n";
430     }
431     if (defined($pheader{'keywords'})) {
432         $s_keywords= $pheader{'keywords'};
433     }
434     $s_severity= '';
435     if (defined($pheader{'severity'})) {
436         $s_severity= $pheader{'severity'};
437         if (!grep($_ eq $s_severity, @severities, "$gDefaultSeverity")) {
438             $brokenness.= <<END;
439
440 Your message specified a Severity: in the psuedo-header, but
441 the severity value $s_severity was not recognised.
442 The default severity $gDefaultSeverity is being used instead.
443 The recognised values are: @showseverities.
444 END
445             $s_severity= '';
446         }
447     }
448     &filelock("nextnumber.lock");
449     open(N,"nextnumber") || &quit("nextnumber: read: $!");
450     $v=<N>; $v =~ s/\n$// || &quit("nextnumber bad format");
451     $ref= $v+0;  $v += 1;  $newref=1;
452     &overwrite('nextnumber', "$v\n");
453     &unfilelock;
454     &overwrite("db/$ref.log",'');
455     &overwrite("db/$ref.status",
456                "$replyto\n$intdate\n$subject\n$header{'message-id'}\n".
457                "$s_package\n$s_keywords\n\n\n\n$s_severity\n");
458     &overwrite("db/$ref.report",
459                join("\n",@msg)."\n");
460 }
461
462 &checkmaintainers;
463
464 print DEBUG "maintainers >@maintaddrs<\n";
465
466 $orgsender= defined($header{'sender'}) ? "Orignal-Sender: $header{'sender'}\n" : '';
467 $newsubject= $subject;  $newsubject =~ s/^$gBug#$ref\W*\s*//;
468
469 $xcchdr= $header{x-debbugs-cc};
470 if ($xcchdr =~ m/\S/) {
471     push(@resentccs,$xcchdr);
472     $resentccexplain.= <<END;
473
474 As you requested using X-Debbugs-CC, your message was also forwarded to
475    $xcchdr
476 (after having been given a $gBug report number, if it did not have one).
477 END
478 }
479
480 if (@maintaddrs && ($codeletter eq 'B' || $codeletter eq 'M')) {
481     push(@resentccs,@maintaddrs);
482     $resentccexplain.= <<END." ".join("\n ",@maintaddrs)."\n";
483
484 Your message has been sent to the package maintainer(s):
485 END
486 }
487
488 $veryquiet= $codeletter eq 'Q';
489 if ($codeletter eq 'M' && !@maintaddrs) {
490     $veryquiet= 1;
491     $brokenness.= <<END;
492
493 You requested that the message be sent to the package maintainer(s)
494 but either the $gBug report is not associated with any package (probably
495 because of a missing Package psuedo-header field in the original $gBug
496 report), or the package(s) specified do not have any maintainer(s).
497
498 Your message has *not* been sent to any package maintainers; it has
499 merely been filed in the $gBug tracking system.  If you require assistance
500 please contact $gMaintainerEmail quoting the $gBug number $ref.
501 END
502 }
503
504 $resentccval.= join(', ',@resentccs);
505 $resentccval =~ s/\s+\n\s+/ /g; $resentccval =~ s/^\s+/ /; $resentccval =~ s/\s+$//;
506 if (length($resentccval)) { $resentcc= "Resent-CC: $resentccval\n"; }
507
508 if ($codeletter eq 'U') {
509     &htmllog("Message", "sent on", $s_originator, "$gBug#$ref.");
510     &sendmessage(<<END,$s_originator,@resentccs);
511 Subject: $gBug#$ref: $newsubject
512 Reply-To: $replyto, $ref-quiet\@$gEmailDomain
513 ${orgsender}Resent-To: $s_originator
514 ${resentcc}Resent-Date: $tdate
515 Resent-Message-ID: <handler.$ref.$nn\@$gEmailDomain>
516 Resent-Sender: $gMaintainerEmail
517 X-$gProject-PR-Message: report $ref
518 X-$gProject-PR-Package: $s_package
519 X-$gProject-PR-Keywords: $s_keywords
520 $fwd
521 END
522 } elsif ($codeletter eq 'B') {
523     &htmllog($newref ? "Report" : "Information", "forwarded",
524              join(', ',"$gSubmitList\@$gListDomain",@resentccs),
525              "<code>$gBug#$ref</code>".
526              (length($s_package)? "; Package <code>".&sani($s_package)."</code>" : '').
527              (length($s_keywords)? "; Keywords <code>".&sani($s_keywords)."</code>":'').
528              ".");
529     &sendmessage(<<END,"$gSubmitList\@$gListDomain",@resentccs);
530 Subject: $gBug#$ref: $newsubject
531 Reply-To: $replyto, $ref\@$gEmailDomain
532 Resent-From: $header{'from'}
533 ${orgsender}Resent-To: $gSubmitList\@$gListDomain
534 ${resentcc}Resent-Date: $tdate
535 Resent-Message-ID: <handler.$ref.$nn\@$gEmailDomain>
536 Resent-Sender: $gMaintainerEmail
537 X-$gProject-PR-Message: report $ref
538 X-$gProject-PR-Package: $s_package
539 X-$gProject-PR-Keywords: $s_keywords
540 $fwd
541 END
542 } elsif (@resentccs) {
543     # D and F done far earlier; B just done - so this must be M or Q
544     # We preserve whichever it was in the Reply-To (possibly adding
545     # the $gBug#).
546     &htmllog($newref ? "Report" : "Information", "forwarded",
547              $resentccval,
548              "<code>$gBug#$ref</code>".
549              (length($s_package)? "; Package <code>".&sani($s_package)."</code>" : '').
550              (length($s_keywords)? "; Keywords <code>".&sani($s_keywords)."</code>":'').
551              ".");
552     &sendmessage(<<END,@resentccs);
553 Subject: $gBug#$ref: $newsubject
554 Reply-To: $replyto, $ref-$baddressroot\@$gEmailDomain
555 Resent-From: $header{'from'}
556 ${orgsender}Resent-To: $resentccval
557 Resent-Date: $tdate
558 Resent-Message-ID: <handler.$ref.$nn\@$gEmailDomain>
559 Resent-Sender: $gMaintainerEmail
560 X-$gProject-PR-Message: report $ref
561 X-$gProject-PR-Package: $s_package
562 X-$gProject-PR-Keywords: $s_keywords
563 $fwd
564 END
565 }
566
567 $htmlbreak= length($brokenness) ? "<p>\n".&sani($brokenness)."\n<p>\n" : '';
568 $htmlbreak =~ s/\n\n/\n<P>\n\n/g;
569 if (length($resentccval)) {
570     $htmlbreak =
571         "  Copy sent to <code>".&sani($resentccval)."</code>.".
572         $htmlbreak;
573 }
574 if ($newref) {
575     &htmllog("Acknowledgement","sent",$replyto,
576              ($veryquiet ?
577               "New $gBug report received and filed, but not forwarded." :
578               "New $gBug report received and forwarded."). $htmlbreak);
579     &sendmessage($veryquiet ? <<END : $codeletter eq 'M' ? <<END : <<END,'');
580 From: $gMaintainerEmail ($gProject $gBug Tracking System)
581 To: $replyto
582 Subject: $gBug#$ref: Acknowledgement of QUIET report
583          ($subject)
584 Message-ID: <handler.$ref.$nn.ackquiet\@$gEmailDomain>
585 In-Reply-To: $header{'message-id'}
586 References: $header{'message-id'}
587 X-$gProject-PR-Message: ack-quiet $ref
588
589 Thank you for the problem report you have sent regarding $gProject.
590 This is an automatically generated reply, to let you know your message
591 has been received.  It has not been forwarded to the developers or
592 their mailing list; you should ensure that the developers are aware of
593 the problem you have entered into the system - preferably quoting the
594 $gBug reference number, #$ref.
595 $resentccexplain
596 If you wish to submit further information on your problem, please send it
597 to $ref-$baddressroot\@$gEmailDomain (and *not*
598 to $baddress\@$gEmailDomain).
599
600 Please do not reply to the address at the top of this message,
601 unless you wish to report a problem with the $gBug-tracking system.
602 $brokenness
603 $gMaintainer
604 (administrator, $gProject $gBugs database)
605 END
606 From: $gMaintainerEmail ($gProject $gBug Tracking System)
607 To: $replyto
608 Subject: $gBug#$ref: Acknowledgement of maintainer-only report
609          ($subject)
610 Message-ID: <handler.$ref.$nn.ackmaint\@$gEmailDomain>
611 In-Reply-To: $header{'message-id'}
612 References: $header{'message-id'}
613 X-$gProject-PR-Message: ack-maintonly $ref
614
615 Thank you for the problem report you have sent regarding $gProject.
616 This is an automatically generated reply, to let you know your message has
617 been received.  It is being forwarded to the developers (but not the mailing
618 list, as you requested) for their attention; they will reply in due course.
619 $resentccexplain
620 If you wish to submit further information on your problem, please send
621 it to $ref-$baddressroot\@$gEmailDomain (and *not*
622 to $baddress\@$gEmailDomain).
623
624 Please do not reply to the address at the top of this message,
625 unless you wish to report a problem with the $gBug-tracking system.
626 $brokenness
627 $gMaintainer
628 (administrator, $gProject $gBugs database)
629 END
630 From: $gMaintainerEmail ($gProject $gBug Tracking System)
631 To: $replyto
632 Subject: $gBug#$ref: Acknowledgement ($subject)
633 Message-ID: <handler.$ref.$nn.ack\@$gEmailDomain>
634 In-Reply-To: $header{'message-id'}
635 References: $header{'message-id'}
636 X-$gProject-PR-Message: ack $ref
637
638 Thank you for the problem report you have sent regarding $gProject.
639 This is an automatically generated reply, to let you know your message has
640 been received.  It is being forwarded to the developers mailing list for
641 their attention; they will reply in due course.
642 $resentccexplain
643 If you wish to submit further information on your problem, please send
644 it to $ref\@$gEmailDomain (and *not* to
645 $baddress\@$gEmailDomain).
646
647 Please do not reply to the address at the top of this message,
648 unless you wish to report a problem with the $gBug-tracking system.
649 $brokenness
650 $gMaintainer
651 (administrator, $gProject $gBugs database)
652 END
653 } elsif ($codeletter ne 'U') {
654     &htmllog("Acknowledgement","sent",$replyto,
655              ($veryquiet ? "Extra info received and filed, but not forwarded." :
656               $codeletter eq 'M' ? "Extra info received and forwarded to maintainer." :
657               "Extra info received and forwarded to list."). $htmlbreak);
658     &sendmessage($veryquiet ? <<END : $codeletter eq 'M' ? <<END : <<END,'');
659 From: $gMaintainerEmail ($gProject $gBug Tracking System)
660 To: $replyto
661 Subject: $gBug#$ref: Info received and FILED only
662          (was $subject)
663 Message-ID: <handler.$ref.$nn.ackinfoquiet\@$gEmailDomain>
664 In-Reply-To: $header{'message-id'}
665 References: $header{'message-id'}
666 X-$gProject-PR-Message: ack-info-quiet $ref
667
668 Thank you for the additional information you have supplied regarding
669 this problem report.  It has NOT been forwarded to the developers, but
670 will accompany the original report in the $gBug tracking system.  Please
671 ensure that you yourself have sent a copy of the additional
672 information to any relevant developers or mailing lists.
673 $resentccexplain
674 If you wish to continue to submit further information on your problem,
675 please send it to $ref-$baddressroot\@$gEmailDomain, as before.
676
677 Please do not reply to the address at the top of this message,
678 unless you wish to report a problem with the $gBug-tracking system.
679 $brokenness
680 $gMaintainer
681 (administrator, $gProject $gBugs database)
682 END
683 From: $gMaintainerEmail ($gProject $gBug Tracking System)
684 To: $replyto
685 Subject: $gBug#$ref: Info received for maintainer only
686          (was $subject)
687 Message-ID: <handler.$ref.$nn.ackinfomaint\@$gEmailDomain>
688 In-Reply-To: $header{'message-id'}
689 References: $header{'message-id'}
690 X-$gProject-PR-Message: ack-info $ref
691
692 Thank you for the additional information you have supplied regarding
693 this problem report.  It has been forwarded to the developer(s) (but
694 not to the mailing list) to accompany the original report.
695 $resentccexplain
696 If you wish to continue to submit further information on your problem,
697 please send it to $ref-$baddressroot\@$gEmailDomain, as before.
698
699 Please do not reply to the address at the top of this message,
700 unless you wish to report a problem with the $gBug-tracking system.
701 $brokenness
702 $gMaintainer
703 (administrator, $gProject $gBugs database)
704 END
705 From: $gMaintainerEmail ($gProject $gBug Tracking System)
706 To: $replyto
707 Subject: $gBug#$ref: Info received (was $subject)
708 Message-ID: <handler.$ref.$nn.ackinfo\@$gEmailDomain>
709 In-Reply-To: $header{'message-id'}
710 References: $header{'message-id'}
711 X-$gProject-PR-Message: ack-info-maintonly $ref
712
713 Thank you for the additional information you have supplied regarding
714 this problem report.  It has been forwarded to the developer(s) and
715 to the developers mailing list to accompany the original report.
716 $resentccexplain
717 If you wish to continue to submit further information on your problem,
718 please send it to $ref\@$gEmailDomain, as before.
719
720 Please do not reply to the address at the top of this message,
721 unless you wish to report a problem with the $gBug-tracking system.
722 $brokenness
723 $gMaintainer
724 (administrator, $gProject $gBugs database)
725 END
726 }
727
728 &appendlog;
729 &finish;
730
731 sub overwrite {
732     local ($f,$v) = @_;
733     open(NEW,">$f.new") || &quit("$f.new: create: $!");
734     print(NEW "$v") || &quit("$f.new: write: $!");
735     close(NEW) || &quit("$f.new: close: $!");
736     rename("$f.new","$f") || &quit("rename $f.new to $f: $!");
737 }
738
739 sub appendlog {
740     if (!open(AP,">>db/$ref.log")) {
741         print DEBUG "failed open log<\n";
742         print DEBUG "failed open log err $!<\n";
743         &quit("opening db/$ref.log (li): $!");
744     }
745     print(AP "\7\n",@log,"\n\3\n") || &quit("writing db/$ref.log (li): $!");
746     close(AP) || &quit("closing db/$ref.log (li): $!");
747 }
748
749 sub finish {
750     utime(time,time,"db");
751     local ($u);
752     while ($u= $cleanups[$#cleanups]) { &$u; }
753     unlink("incoming/P$nn") || &quit("unlinking incoming/P$nn: $!");
754     exit $_[0];
755 }
756
757 &quit("wot no exit");
758
759 sub chldhandle { $chldexit = 'yes'; }
760
761 sub htmllog {
762     local ($whatobj,$whatverb,$where,$desc) = @_;
763     open(AP,">>db/$ref.log") || &quit("opening db/$ref.log (lh): $!");
764     print(AP
765           "\6\n".
766           "<strong>$whatobj $whatverb</strong> to <code>".&sani($where).
767           "</code>:<br>\n". $desc.
768           "\n\3\n") || &quit("writing db/$ref.log (lh): $!");
769     close(AP) || &quit("closing db/$ref.log (lh): $!");
770 }    
771
772 sub get_addresses {
773         return
774                 map { $_->address() }
775                 map { Mail::Address->parse($_) } @_;
776 }
777
778
779 sub sendmessage {
780     local ($msg,@recips) = @_;
781     if ($recips[0] eq '' && $#recips == 0) { @recips= ('-t'); }
782     open(AP,">>db/$ref.log") || &quit("opening db/$ref.log (lo): $!");
783     print(AP "\2\n",join("\4",@recips),"\n\5\n$msg\n\3\n") ||
784         &quit("writing db/$ref.log (lo): $!");
785     close(AP) || &quit("closing db/$ref.log (lo): $!");
786     
787     print DEBUG "mailing to >",join('|',@recips),"<\n";
788     $SIG{'CHLD'}='chldhandle';
789         #print DEBUG "mailing sigchild set up<\n";
790         $chldexit = 'no';
791     $c= open(U,"-|");
792         #print DEBUG "mailing opened pipe fork<\n";
793     defined($c) || die $!;
794         #print DEBUG "mailing opened pipe fork ok $c<\n";
795     if (!$c) { # ie, we are in the child process
796                 #print DEBUG "mailing child<\n";
797         unless (open(STDERR,">&STDOUT")) {
798                         #print DEBUG "mailing child opened stderr<\n";
799             print STDOUT "redirect stderr: $!\n";
800                         #print DEBUG "mailing child opened stderr fail<\n";
801             exit 1;
802                         #print DEBUG "mailing child opened stderr fail exit !?<\n";
803         }
804                 #print DEBUG "mailing child opened stderr ok<\n";
805         $c= open(D,"|-");
806                 #print DEBUG "mailing child forked again<\n";
807         defined($c) || die $!;
808                 #print DEBUG "mailing child forked again ok $c<\n";
809         if (!$c) { # ie, we are the child process
810                         #print DEBUG "mailing grandchild<\n";
811             exec '/usr/lib/sendmail','-f'."$gMaintainerEmail",'-odi','-oem','-oi',get_addresses(@recips);
812                         #print DEBUG "mailing grandchild exec failed<\n";
813             die $!;
814                         #print DEBUG "mailing grandchild died !?<\n";
815         }
816                 #print DEBUG "mailing child not grandchild<\n";
817         print(D $msg) || die $!;
818                 #print DEBUG "mailing child printed msg<\n";
819         close(D);
820                 #print DEBUG "mailing child closed pipe<\n";
821         die "\n*** command returned exit status $?\n" if $?;
822                 #print DEBUG "mailing child exit status ok<\n";
823         exit 0;
824                 #print DEBUG "mailing child exited ?!<\n";
825     }
826         #print DEBUG "mailing parent<\n";
827     $results='';
828         #print DEBUG "mailing parent results emptied<\n";
829     while( $chldexit eq 'no' ) { $results.= $_; }
830         #print DEBUG "mailing parent results read >$results<\n";
831     close(U);
832         #print DEBUG "mailing parent results closed<\n";
833     $results.= "\n*** child returned exit status $?\n" if $?;
834         #print DEBUG "mailing parent exit status ok<\n";
835     $SIG{'CHLD'}='DEFAULT';
836         #print DEBUG "mailing parent sigchild default<\n";
837     if (length($results)) { &quit("running sendmail: $results"); }
838         #print DEBUG "mailing parent results ok<\n";
839 }
840
841 sub checkmaintainers {
842     return if $maintainerschecked++;
843     return if !length($s_package);
844     open(MAINT,"$gMaintainerFile") || die &quit("maintainers open: $!");
845     while (<MAINT>) {
846         m/^(\S+)\s+(\S.*\S)\n$/ || &quit("maintainers bogus \`$_'");
847         $a= $1; $b= $2; $a =~ y/A-Z/a-z/;
848         $maintainerof{$1}= $2;
849     }
850     close(MAINT);
851     $anymaintfound=0; $anymaintnotfound=0;
852     for $p (split(m/[ \t?,()]+/,$s_package)) {
853         $p =~ y/A-Z/a-z/;
854         if (defined($maintainerof{$p})) {
855 print DEBUG "maintainer add >$p|$maintainerof{$p}<\n";
856             $addmaint= $maintainerof{$p};
857             push(@maintaddrs,$addmaint) unless
858                 $addmaint eq $replyto || grep($_ eq $addmaint, @maintaddrs);
859             $anymaintfound++;
860         } else {
861 print DEBUG "maintainer none >$p<\n";
862             $anymaintnotfound++;
863             last;
864         }
865     }
866 }