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