]> git.donarmstrong.com Git - debbugs.git/blob - scripts/process.in
[project @ 2001-11-22 03:04:10 by doogie]
[debbugs.git] / scripts / process.in
1 #!/usr/bin/perl
2 # $Id: process.in,v 1.41 2001/11/22 03:04:10 doogie 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 }
495
496 &checkmaintainers;
497
498 print DEBUG "maintainers >@maintaddrs<\n";
499
500 $orgsender= defined($header{'sender'}) ? "Original-Sender: $header{'sender'}\n" : '';
501 $newsubject= $subject;  $newsubject =~ s/^$gBug#$ref\W*\s*//;
502
503 $xcchdr= $header{ 'x-debbugs-cc' };
504 if ($xcchdr =~ m/\S/) {
505     push(@resentccs,$xcchdr);
506     $resentccexplain.= <<END;
507
508 As you requested using X-Debbugs-CC, your message was also forwarded to
509    $xcchdr
510 (after having been given a $gBug report number, if it did not have one).
511 END
512 }
513
514 if (@maintaddrs && ($codeletter eq 'B' || $codeletter eq 'M')) {
515     push(@resentccs,@maintaddrs);
516     $resentccexplain.= <<END." ".join("\n ",@maintaddrs)."\n";
517
518 Your message has been sent to the package maintainer(s):
519 END
520 }
521
522 $veryquiet= $codeletter eq 'Q';
523 if ($codeletter eq 'M' && !@maintaddrs) {
524     $veryquiet= 1;
525     $brokenness.= <<END;
526
527 You requested that the message be sent to the package maintainer(s)
528 but either the $gBug report is not associated with any package (probably
529 because of a missing Package pseudo-header field in the original $gBug
530 report), or the package(s) specified do not have any maintainer(s).
531
532 Your message has *not* been sent to any package maintainers; it has
533 merely been filed in the $gBug tracking system.  If you require assistance
534 please contact $gMaintainerEmail quoting the $gBug number $ref.
535 END
536 }
537
538 $resentccval.= join(', ',@resentccs);
539 $resentccval =~ s/\s+\n\s+/ /g; $resentccval =~ s/^\s+/ /; $resentccval =~ s/\s+$//;
540 if (length($resentccval)) { $resentcc= "Resent-CC: $resentccval\n"; }
541
542 if ($codeletter eq 'U') {
543     &htmllog("Message", "sent on", $s_originator, "$gBug#$ref.");
544     &sendmessage(<<END,$s_originator,@resentccs);
545 Subject: $gBug#$ref: $newsubject
546 Reply-To: $replyto, $ref-quiet\@$gEmailDomain
547 ${orgsender}Resent-To: $s_originator
548 ${resentcc}Resent-Date: $tdate
549 Resent-Message-ID: <handler.$ref.$nn\@$gEmailDomain>
550 Resent-Sender: $gMaintainerEmail
551 X-$gProject-PR-Message: report $ref
552 X-$gProject-PR-Package: $s_package
553 X-$gProject-PR-Keywords: $s_keywords
554 $fwd
555 END
556 } elsif ($codeletter eq 'B') {
557     &htmllog($newref ? "Report" : "Information", "forwarded",
558              join(', ',"$gSubmitList\@$gListDomain",@resentccs),
559              "<code>$gBug#$ref</code>".
560              (length($s_package)? "; Package <code>".&sani($s_package)."</code>" : '').
561              ".");
562     &sendmessage(<<END,"$gSubmitList\@$gListDomain",@resentccs);
563 Subject: $gBug#$ref: $newsubject
564 Reply-To: $replyto, $ref\@$gEmailDomain
565 Resent-From: $header{'from'}
566 ${orgsender}Resent-To: $gSubmitList\@$gListDomain
567 ${resentcc}Resent-Date: $tdate
568 Resent-Message-ID: <handler.$ref.$nn\@$gEmailDomain>
569 Resent-Sender: $gMaintainerEmail
570 X-$gProject-PR-Message: report $ref
571 X-$gProject-PR-Package: $s_package
572 X-$gProject-PR-Keywords: $s_keywords
573 $fwd
574 END
575 } elsif (@resentccs) {
576     # D and F done far earlier; B just done - so this must be M or Q
577     # We preserve whichever it was in the Reply-To (possibly adding
578     # the $gBug#).
579     &htmllog($newref ? "Report" : "Information", "forwarded",
580              $resentccval,
581              "<code>$gBug#$ref</code>".
582              (length($s_package)? "; Package <code>".&sani($s_package)."</code>" : '').
583              ".");
584     &sendmessage(<<END,@resentccs);
585 Subject: $gBug#$ref: $newsubject
586 Reply-To: $replyto, $ref-$baddressroot\@$gEmailDomain
587 Resent-From: $header{'from'}
588 ${orgsender}Resent-To: $resentccval
589 Resent-Date: $tdate
590 Resent-Message-ID: <handler.$ref.$nn\@$gEmailDomain>
591 Resent-Sender: $gMaintainerEmail
592 X-$gProject-PR-Message: report $ref
593 X-$gProject-PR-Package: $s_package
594 X-$gProject-PR-Keywords: $s_keywords
595 $fwd
596 END
597 }
598
599 $htmlbreak= length($brokenness) ? "<p>\n".&sani($brokenness)."\n<p>\n" : '';
600 $htmlbreak =~ s/\n\n/\n<P>\n\n/g;
601 if (length($resentccval)) {
602     $htmlbreak =
603         "  Copy sent to <code>".&sani($resentccval)."</code>.".
604         $htmlbreak;
605 }
606 if ($newref) {
607     &htmllog("Acknowledgement","sent",$replyto,
608              ($veryquiet ?
609               "New $gBug report received and filed, but not forwarded." :
610               "New $gBug report received and forwarded."). $htmlbreak);
611     &sendmessage($veryquiet ? <<END : $codeletter eq 'M' ? <<END : <<END,'');
612 From: $gMaintainerEmail ($gProject $gBug Tracking System)
613 To: $replyto
614 Subject: $gBug#$ref: Acknowledgement of QUIET report
615          ($subject)
616 Message-ID: <handler.$ref.$nn.ackquiet\@$gEmailDomain>
617 In-Reply-To: $header{'message-id'}
618 References: $header{'message-id'}
619 X-$gProject-PR-Message: ack-quiet $ref
620 Reply-To: $ref-quiet\@$gEmailDomain
621
622 Thank you for the problem report you have sent regarding $gProject.
623 This is an automatically generated reply, to let you know your message
624 has been received.  It has not been forwarded to the developers or
625 their mailing list; you should ensure that the developers are aware of
626 the problem you have entered into the system - preferably quoting the
627 $gBug reference number, #$ref.
628 $resentccexplain
629 If you wish to submit further information on your problem, please send it
630 to $ref-$baddressroot\@$gEmailDomain (and *not*
631 to $baddress\@$gEmailDomain).
632
633 Please do not reply to the address at the top of this message,
634 unless you wish to report a problem with the $gBug-tracking system.
635 $brokenness
636 $gMaintainer
637 (administrator, $gProject $gBugs database)
638 END
639 From: $gMaintainerEmail ($gProject $gBug Tracking System)
640 To: $replyto
641 Subject: $gBug#$ref: Acknowledgement of maintainer-only report
642          ($subject)
643 Message-ID: <handler.$ref.$nn.ackmaint\@$gEmailDomain>
644 In-Reply-To: $header{'message-id'}
645 References: $header{'message-id'}
646 X-$gProject-PR-Message: ack-maintonly $ref
647 Reply-To: $ref-maintonly\@$gEmailDomain
648
649 Thank you for the problem report you have sent regarding $gProject.
650 This is an automatically generated reply, to let you know your message has
651 been received.  It is being forwarded to the developers (but not the mailing
652 list, as you requested) for their attention; they will reply in due course.
653 $resentccexplain
654 If you wish to submit further information on your problem, please send
655 it to $ref-$baddressroot\@$gEmailDomain (and *not*
656 to $baddress\@$gEmailDomain).
657
658 Please do not reply to the address at the top of this message,
659 unless you wish to report a problem with the $gBug-tracking system.
660 $brokenness
661 $gMaintainer
662 (administrator, $gProject $gBugs database)
663 END
664 From: $gMaintainerEmail ($gProject $gBug Tracking System)
665 To: $replyto
666 Subject: $gBug#$ref: Acknowledgement ($subject)
667 Message-ID: <handler.$ref.$nn.ack\@$gEmailDomain>
668 In-Reply-To: $header{'message-id'}
669 References: $header{'message-id'}
670 X-$gProject-PR-Message: ack $ref
671 Reply-To: $ref\@$gEmailDomain
672
673 Thank you for the problem report you have sent regarding $gProject.
674 This is an automatically generated reply, to let you know your message has
675 been received.  It is being forwarded to the developers mailing list for
676 their attention; they will reply in due course.
677 $resentccexplain
678 If you wish to submit further information on your problem, please send
679 it to $ref\@$gEmailDomain (and *not* to
680 $baddress\@$gEmailDomain).
681
682 Please do not reply to the address at the top of this message,
683 unless you wish to report a problem with the $gBug-tracking system.
684 $brokenness
685 $gMaintainer
686 (administrator, $gProject $gBugs database)
687 END
688 } elsif ($codeletter ne 'U') {
689     &htmllog("Acknowledgement","sent",$replyto,
690              ($veryquiet ? "Extra info received and filed, but not forwarded." :
691               $codeletter eq 'M' ? "Extra info received and forwarded to maintainer." :
692               "Extra info received and forwarded to list."). $htmlbreak);
693     &sendmessage($veryquiet ? <<END : $codeletter eq 'M' ? <<END : <<END,'');
694 From: $gMaintainerEmail ($gProject $gBug Tracking System)
695 To: $replyto
696 Subject: $gBug#$ref: Info received and FILED only
697          (was $subject)
698 Message-ID: <handler.$ref.$nn.ackinfoquiet\@$gEmailDomain>
699 In-Reply-To: $header{'message-id'}
700 References: $header{'message-id'}
701 X-$gProject-PR-Message: ack-info-quiet $ref
702 Reply-To: $ref-quiet\@$gEmailDomain
703
704 Thank you for the additional information you have supplied regarding
705 this problem report.  It has NOT been forwarded to the developers, but
706 will accompany the original report in the $gBug tracking system.  Please
707 ensure that you yourself have sent a copy of the additional
708 information to any relevant developers or mailing lists.
709 $resentccexplain
710 If you wish to continue to submit further information on your problem,
711 please send it to $ref-$baddressroot\@$gEmailDomain, as before.
712
713 Please do not reply to the address at the top of this message,
714 unless you wish to report a problem with the $gBug-tracking system.
715 $brokenness
716 $gMaintainer
717 (administrator, $gProject $gBugs database)
718 END
719 From: $gMaintainerEmail ($gProject $gBug Tracking System)
720 To: $replyto
721 Subject: $gBug#$ref: Info received for maintainer only
722          (was $subject)
723 Message-ID: <handler.$ref.$nn.ackinfomaint\@$gEmailDomain>
724 In-Reply-To: $header{'message-id'}
725 References: $header{'message-id'}
726 X-$gProject-PR-Message: ack-info-maintonly $ref
727 Reply-To: $ref-maintonly\@$gEmailDomain
728
729 Thank you for the additional information you have supplied regarding
730 this problem report.  It has been forwarded to the developer(s) (but
731 not to the mailing list) to accompany the original report.
732 $resentccexplain
733 If you wish to continue to submit further information on your problem,
734 please send it to $ref-$baddressroot\@$gEmailDomain, as before.
735
736 Please do not reply to the address at the top of this message,
737 unless you wish to report a problem with the $gBug-tracking system.
738 $brokenness
739 $gMaintainer
740 (administrator, $gProject $gBugs database)
741 END
742 From: $gMaintainerEmail ($gProject $gBug Tracking System)
743 To: $replyto
744 Subject: $gBug#$ref: Info received (was $subject)
745 Message-ID: <handler.$ref.$nn.ackinfo\@$gEmailDomain>
746 In-Reply-To: $header{'message-id'}
747 References: $header{'message-id'}
748 X-$gProject-PR-Message: ack-info $ref
749 Disabled-Doogie-Reply-To: $ref\@$gEmailDomain
750
751 Thank you for the additional information you have supplied regarding
752 this problem report.  It has been forwarded to the developer(s) and
753 to the developers mailing list to accompany the original report.
754 $resentccexplain
755 If you wish to continue to submit further information on your problem,
756 please send it to $ref\@$gEmailDomain, as before.
757
758 Please do not reply to the address at the top of this message,
759 unless you wish to report a problem with the $gBug-tracking system.
760 $brokenness
761 $gMaintainer
762 (administrator, $gProject $gBugs database)
763 END
764 }
765
766 &appendlog;
767 &finish;
768
769 sub overwrite {
770     local ($f,$v) = @_;
771     open(NEW,">$f.new") || &quit("$f.new: create: $!");
772     print(NEW "$v") || &quit("$f.new: write: $!");
773     close(NEW) || &quit("$f.new: close: $!");
774     rename("$f.new","$f") || &quit("rename $f.new to $f: $!");
775 }
776
777 sub appendlog {
778     my $hash = get_hashname($ref);
779     if (!open(AP,">>db-h/$hash/$ref.log")) {
780         print DEBUG "failed open log<\n";
781         print DEBUG "failed open log err $!<\n";
782         &quit("opening db-h/$hash/$ref.log (li): $!");
783     }
784     print(AP "\7\n",@log,"\n\3\n") || &quit("writing db-h/$hash/$ref.log (li): $!");
785     close(AP) || &quit("closing db-h/$hash/$ref.log (li): $!");
786 }
787
788 sub finish {
789     utime(time,time,"db");
790     local ($u);
791     while ($u= $cleanups[$#cleanups]) { &$u; }
792     unlink("incoming/P$nn") || &quit("unlinking incoming/P$nn: $!");
793     exit $_[0];
794 }
795
796 &quit("wot no exit");
797
798 sub chldhandle { $chldexit = 'yes'; }
799
800 sub htmllog {
801     local ($whatobj,$whatverb,$where,$desc) = @_;
802     my $hash = get_hashname($ref);
803     open(AP,">>db-h/$hash/$ref.log") || &quit("opening db-h/$hash/$ref.log (lh): $!");
804     print(AP
805           "\6\n".
806           "<strong>$whatobj $whatverb</strong> to <code>".&sani($where).
807           "</code>:<br>\n". $desc.
808           "\n\3\n") || &quit("writing db-h/$hash/$ref.log (lh): $!");
809     close(AP) || &quit("closing db-h/$hash/$ref.log (lh): $!");
810 }    
811
812 sub get_addresses {
813         return
814                 map { $_->address() }
815                 map { Mail::Address->parse($_) } @_;
816 }
817
818 sub sendmessage {
819     local ($msg,@recips) = @_;
820     if ($recips[0] eq '' && $#recips == 0) { @recips= ('-t'); }
821     $msg = "X-Loop: $gMaintainerEmail\n" . $msg;
822
823     my $hash = get_hashname($ref);
824     #save email to the log
825     open(AP,">>db-h/$hash/$ref.log") || &quit("opening db-h/$hash/$ref.log (lo): $!");
826     print(AP "\2\n",join("\4",@recips),"\n\5\n$msg\n\3\n") ||
827         &quit("writing db-h/$hash/$ref.log (lo): $!");
828     close(AP) || &quit("closing db-h/$hash/$ref.log (lo): $!");
829     
830 #if debbuging.. save email to a log
831 #    open AP, ">>debug";
832 #    print AP join( '|', @recips )."\n>>";
833 #    print AP get_addresses( @recips );
834 #    print AP "<<\n".$msg;
835 #    print AP "\n--------------------------------------------------------\n";
836 #    close AP;
837
838     #start mailing
839     $_ = '';
840     $SIG{'CHLD'}='chldhandle';
841     #print DEBUG "mailing sigchild set up<\n";
842     $chldexit = 'no';
843     $c= open(U,"-|");
844     #print DEBUG "mailing opened pipe fork<\n";
845     defined($c) || die $!;
846     #print DEBUG "mailing opened pipe fork ok $c<\n";
847     if (!$c) { # ie, we are in the child process
848         #print DEBUG "mailing child<\n";
849         unless (open(STDERR,">&STDOUT")) {
850             #print DEBUG "mailing child opened stderr<\n";
851             print STDOUT "redirect stderr: $!\n";
852             #print DEBUG "mailing child opened stderr fail<\n";
853             exit 1;
854             #print DEBUG "mailing child opened stderr fail exit !?<\n";
855         }
856         #print DEBUG "mailing child opened stderr ok<\n";
857         $c= open(D,"|-");
858         #print DEBUG "mailing child forked again<\n";
859         defined($c) || die $!;
860         #print DEBUG "mailing child forked again ok $c<\n";
861         if (!$c) { # ie, we are the child process
862             #print DEBUG "mailing grandchild<\n";
863             exec '/usr/lib/sendmail','-f'."$gMaintainerEmail",'-odq','-oem','-oi',get_addresses(@recips);
864             #print DEBUG "mailing grandchild exec failed<\n";
865             die $!;
866             #print DEBUG "mailing grandchild died !?<\n";
867         }
868         #print DEBUG "mailing child not grandchild<\n";
869         print(D $msg) || die $!;
870         #print DEBUG "mailing child printed msg<\n";
871         close(D);
872         #print DEBUG "mailing child closed pipe<\n";
873         die "\n*** command returned exit status $?\n" if $?;
874         #print DEBUG "mailing child exit status ok<\n";
875         exit 0;
876         #print DEBUG "mailing child exited ?!<\n";
877     }
878     #print DEBUG "mailing parent<\n";
879     $results='';
880     #print DEBUG "mailing parent results emptied<\n";
881     while( $chldexit eq 'no' ) { $results.= $_; }
882     #print DEBUG "mailing parent results read >$results<\n";
883     close(U);
884     #print DEBUG "mailing parent results closed<\n";
885     $results.= "\n*** child returned exit status $?\n" if $?;
886     #print DEBUG "mailing parent exit status ok<\n";
887     $SIG{'CHLD'}='DEFAULT';
888     #print DEBUG "mailing parent sigchild default<\n";
889     if (length($results)) { &quit("running sendmail: $results"); }
890     #print DEBUG "mailing parent results ok<\n";
891 }
892
893 sub checkmaintainers {
894     return if $maintainerschecked++;
895     return if !length($s_package);
896     open(MAINT,"$gMaintainerFile") || die &quit("maintainers open: $!");
897     while (<MAINT>) {
898         m/^\n$/ && next;
899         m/^\s*$/ && next;
900         m/^(\S+)\s+(\S.*\S)\s*\n$/ || &quit("maintainers bogus \`$_'");
901         $a= $1; $b= $2; $a =~ y/A-Z/a-z/;
902         $maintainerof{$1}= $2;
903     }
904     close(MAINT);
905     open(MAINT,"$gMaintainerFileOverride") || die &quit("maintainers.override open: $!");
906     while (<MAINT>) {
907         m/^\n$/ && next;
908         m/^\s*$/ && next;
909         m/^(\S+)\s+(\S.*\S)\s*\n$/ || &quit("maintainers.override bogus \`$_'");
910         $a= $1; $b= $2; $a =~ y/A-Z/a-z/;
911         $maintainerof{$1}= $2;
912     }
913     close(MAINT);
914     $anymaintfound=0; $anymaintnotfound=0;
915     for $p (split(m/[ \t?,()]+/,$s_package)) {
916         $p =~ y/A-Z/a-z/;
917         if (defined($maintainerof{$p})) {
918 print DEBUG "maintainer add >$p|$maintainerof{$p}<\n";
919             $addmaint= $maintainerof{$p};
920             push(@maintaddrs,$addmaint) unless
921                 $addmaint eq $replyto || grep($_ eq $addmaint, @maintaddrs);
922             $anymaintfound++;
923         } else {
924 print DEBUG "maintainer none >$p<\n";
925             push(@maintaddrs,$gUnknownMaintainerEmail) unless $anymaintnotfound;
926             $anymaintnotfound++;
927             last;
928         }
929     }
930 }