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