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