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