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