2 # $Id: process.in,v 1.103 2005/08/19 05:44:28 don Exp $
7 use POSIX qw(strftime tzset);
13 use Debbugs::MIME qw(decode_rfc1522);
14 use Debbugs::Mail qw(send_mail_message encode_headers);
16 $config_path = '/etc/debbugs';
17 $lib_path = '/usr/lib/debbugs';
19 require "$config_path/config";
20 require "$lib_path/errorlib";
21 $ENV{'PATH'} = $lib_path.':'.$ENV{'PATH'};
23 chdir( "$gSpoolDir" ) || die "chdir spool: $!\n";
25 #open(DEBUG,"> /tmp/debbugs.debug");
27 open DEBUG, ">/dev/null";
29 defined( $intdate= time ) || &quit( "failed to get time: $!" );
32 m/^([BMQFDUL])(\d*)\.\d+$/ || &quit("bad argument");
34 $tryref= length($2) ? $2+0 : -1;
37 if (!rename("incoming/G$nn","incoming/P$nn"))
39 $_=$!.''; m/no such file or directory/i && exit 0;
40 &quit("renaming to lock: $!");
43 $baddress= 'submit' if $codeletter eq 'B';
44 $baddress= 'maintonly' if $codeletter eq 'M';
45 $baddress= 'quiet' if $codeletter eq 'Q';
46 $baddress= 'forwarded' if $codeletter eq 'F';
47 $baddress= 'done' if $codeletter eq 'D';
48 $baddress= 'submitter' if $codeletter eq 'U';
49 bug_list_forward($nn) if $codeletter eq 'L';
50 $baddress || &quit("bad codeletter $codeletter");
51 $baddressroot= $baddress;
52 $baddress= "$tryref-$baddress" if $tryref>=0;
54 open(M,"incoming/P$nn");
61 print DEBUG "###\n",join("##\n",@msg),"\n###\n";
63 $tdate = strftime "%a, %d %h %Y %T UTC", localtime;
65 Received: via spool by $baddress\@$gEmailDomain id=$nn
66 (code $codeletter ref $tryref); $tdate
69 # header and decoded body respectively
70 my (@headerlines, @bodylines);
72 my $parser = new MIME::Parser;
73 mkdir "$gSpoolDir/mime.tmp", 0777;
74 $parser->output_under("$gSpoolDir/mime.tmp");
75 my $entity = eval { $parser->parse_data(join('',@log)) };
77 if ($entity and $entity->head->tags) {
78 @headerlines = @{$entity->head->header};
81 my $entity_body = getmailbody($entity);
82 @bodylines = $entity_body ? $entity_body->as_lines() : ();
85 # set $i to beginning of encoded body data, so we can dump it out
88 ++$i while $msg[$i] =~ /./;
90 # Legacy pre-MIME code, kept around in case MIME::Parser fails.
91 for ($i = 0; $i <= $#msg; $i++) {
93 last unless length($_);
94 while ($msg[$i+1] =~ m/^\s/) {
98 push @headerlines, $_;
101 @bodylines = @msg[$i..$#msg];
104 for my $hdr (@headerlines) {
105 $hdr = decode_rfc1522($hdr);
108 &finish if m/^x-loop: (\S+)$/i && $1 eq "$gMaintainerEmail";
109 my $ins = !m/^subject:/i && !m/^reply-to:/i && !m/^return-path:/i
110 && !m/^From / && !m/^X-Debbugs-/i;
111 $fwd .= $hdr."\n" if $ins;
112 # print DEBUG ">$_<\n";
113 if (s/^(\S+):\s*//) {
115 print DEBUG ">$v=$_<\n";
118 print DEBUG "!>$_<\n";
123 shift @bodylines while @bodylines and $bodylines[0] !~ /\S/;
125 # Strip off RFC2440-style PGP clearsigning.
126 if (@bodylines and $bodylines[0] =~ /^-----BEGIN PGP SIGNED/) {
127 shift @bodylines while @bodylines and length $bodylines[0];
128 shift @bodylines while @bodylines and $bodylines[0] !~ /\S/;
129 for my $findsig (0 .. $#bodylines) {
130 if ($bodylines[$findsig] =~ /^-----BEGIN PGP SIGNATURE/) {
131 $#bodylines = $findsig - 1;
135 map { s/^- // } @bodylines;
138 # extract pseudo-headers
139 for my $phline (@bodylines)
141 last if $phline !~ m/^([\w-]+):\s*(\S.*)/;
142 my ($fn, $fv) = ($1, $2);
144 print DEBUG ">$fn|$fv|\n";
148 print DEBUG ">$fn~$fv<\n";
152 $fwd .= join("\n",@msg[$i..$#msg]);
154 print DEBUG "***\n$fwd\n***\n";
156 if (defined $header{'resent-from'} && !defined $header{'from'}) {
157 $header{'from'} = $header{'resent-from'};
159 defined($header{'from'}) || &quit("no From header");
161 $replyto = $header{'reply-to'};
162 $replyto = '' unless defined $replyto;
165 unless (length $replyto) {
166 $replyto = $header{'from'};
170 $_= "$2 <$1>" if m/^([^\<\> \t\n\(\)]+) \(([^\(\)\<\>]+)\)$/;
172 print DEBUG "replytocompare >$replytocompare<\n";
174 if (!defined($header{'subject'}))
178 Your message did not contain a Subject field. They are recommended and
179 useful because the title of a $gBug is determined using this field.
180 Please remember to include a Subject field in your messages in future.
183 # RFC822 actually lists it as an `optional-field'.
185 $subject= '(no subject)';
187 $subject= $header{'subject'};
191 $subject =~ s/^Re:\s*//i; $_= $subject."\n";
192 if ($tryref < 0 && m/^Bug ?\#(\d+)\D/i) {
198 ($bfound, $data)= &lockreadbugmerge($tryref);
202 &htmllog("Reply","sent", $replyto,"Unknown problem report number <code>$tryref</code>.");
203 my $archivenote = '';
205 $archivenote = <<END;
206 This may be because that $gBug report has been resolved for more than $gRemoveAge
207 days, and the record of it has been archived and made read-only, or
208 because you mistyped the $gBug report number.
212 &sendmessage(<<END, '');
213 From: $gMaintainerEmail ($gProject $gBug Tracking System)
215 Subject: Unknown problem report $gBug#$tryref ($subject)
216 Message-ID: <handler.x.$nn.unknown\@$gEmailDomain>
217 In-Reply-To: $header{'message-id'}
218 References: $header{'message-id'} $data->{msgid}
220 X-$gProject-PR-Message: error
222 You sent a message to the $gBug tracking system which gave (in the
223 Subject line or encoded into the recipient at $gEmailDomain),
224 the number of a nonexistent $gBug report (#$tryref).
226 ${archivenote}Your message was dated $header{'date'} and was sent to
227 $baddress\@$gEmailDomain. It had
228 Message-ID $header{'message-id'}
229 and Subject $subject.
231 It has been filed (under junk) but otherwise ignored.
233 Please consult your records to find the correct $gBug report number, or
234 contact me, the system administrator, for assistance.
237 (administrator, $gProject $gBugs database)
239 (NB: If you are a system administrator and have no idea what I am
240 talking about this indicates a serious mail system misconfiguration
241 somewhere. Please contact me immediately.)
248 &filelock('lock/-1');
251 if ($codeletter eq 'D' || $codeletter eq 'F')
253 if ($replyto =~ m/$gBounceFroms/o ||
254 $header{'from'} =~ m/$gBounceFroms/o)
256 &quit("bounce detected ! Mwaap! Mwaap!");
258 $markedby= $header{'from'} eq $replyto ? $replyto :
259 "$header{'from'} (reply to $replyto)";
260 if ($codeletter eq 'F') {
261 (&appendlog,&finish) if length($data->{forwarded});
262 $receivedat= "forwarded\@$gEmailDomain";
263 $markaswhat= 'forwarded';
264 $set_forwarded= $header{'to'};
265 if ( length( $gListDomain ) > 0 && length( $gForwardList ) > 0 ) {
266 $generalcc= "$gForwardList\@$gListDomain";
271 if (length($data->{done}) and
272 not defined $pheader{'source-version'} and
273 not defined $pheader{'version'}) {
277 $receivedat= "done\@$gEmailDomain";
279 $set_done= $header{'from'};
280 if ( length( $gListDomain ) > 0 && length( $gDoneList ) > 0 ) {
281 $generalcc= "$gDoneList\@$gListDomain";
286 if (defined $gStrongList and isstrongseverity($data->{severity})) {
287 $generalcc = join ', ', $generalcc, "$gStrongList\@$gListDomain";
290 &htmllog("Warning","sent",$replyto,"Message ignored.");
291 &sendmessage(<<END, '');
292 From: $gMaintainerEmail ($gProject $gBug Tracking System)
294 Subject: Message with no $gBug number ignored by $receivedat
296 Message-ID: <header.x.$nn.warnignore\@$gEmailDomain>
297 In-Reply-To: $header{'message-id'}
298 References: $header{'message-id'} $data->{msgid}
300 X-$gProject-PR-Message: error
302 You sent a message to the $gProject $gBug tracking system old-style
303 unified mark as $markaswhat address ($receivedat),
304 without a recognisable $gBug number in the Subject.
305 Your message has been filed under junk but otherwise ignored.
307 If you don't know what I'm talking about then probably either:
309 (a) you unwittingly sent a message to done\@$gEmailDomain
310 because you replied to all recipients of the message a developer used
311 to mark a $gBug as done and you modified the Subject. In this case,
312 please do not be alarmed. To avoid confusion do not do it again, but
313 there is no need to apologise or mail anyone asking for an explanation.
315 (b) you are a system administrator, reading this because the $gBug
316 tracking system is responding to a misdirected bounce message. In this
317 case there is a serious mail system misconfiguration somewhere - please
318 contact me immediately.
320 Your message was dated $header{'date'} and had
321 message-id $header{'message-id'}
322 and subject $subject.
324 If you need any assistance or explanation please contact me.
327 (administrator, $gProject $gBugs database)
336 $noticeccval.= join(', ', grep($_ ne $replyto,@maintaddrs));
337 $noticeccval =~ s/\s+\n\s+/ /g;
338 $noticeccval =~ s/^\s+/ /; $noticeccval =~ s/\s+$//;
339 if (length($noticeccval)) { $noticecc= "Cc: $noticeccval\n"; }
341 @process= ($ref,split(/ /,$data->{mergedwith}));
344 for $ref (@process) {
345 if ($ref != $orgref) {
347 $data = &lockreadbug($ref)
348 || die "huh ? $ref from $orgref out of @process";
350 $data->{done}= $set_done if defined($set_done);
351 $data->{forwarded}= $set_forwarded if defined($set_forwarded);
352 if ($codeletter eq 'D') {
353 $data->{keywords} = join ' ', grep $_ ne 'pending',
354 split ' ', $data->{keywords};
355 if (defined $pheader{'source-version'}) {
356 addfixedversions($data, $pheader{source}, $pheader{'source-version'}, '');
357 } elsif (defined $pheader{version}) {
358 addfixedversions($data, $pheader{package}, $pheader{version}, 'binary');
362 # Add bug mailing list to $generalbcc as appropriate
363 my $generalbcc = join(', ', $generalcc, @addsrcaddrs,"bugs=$ref\@$gListDomain");
364 $generalbcc =~ s/\s+\n\s+/ /g;
365 $generalbcc =~ s/^\s+/ /; $generalbcc =~ s/\s+$//;
366 if (length $generalbcc) {$generalbcc = "Bcc: $generalbcc\n"};
368 writebug($ref, $data);
370 my $hash = get_hashname($ref);
371 open(O,"db-h/$hash/$ref.report") || &quit("read original report: $!");
372 $x= join('',<O>); close(O);
373 if ($codeletter eq 'F') {
374 &htmllog("Reply","sent",$replyto,"You have marked $gBug as forwarded.");
375 &sendmessage(<<END."---------------------------------------\n".join( "\n", @msg ), '');
376 From: $gMaintainerEmail ($gProject $gBug Tracking System)
378 ${noticecc}${generalbcc}Subject: $gBug#$ref: marked as forwarded ($data->{subject})
379 Message-ID: <header.$ref.$nn.ackfwdd\@$gEmailDomain>
380 In-Reply-To: $header{'message-id'}
381 References: $header{'message-id'} $data->{msgid}
383 X-$gProject-PR-Message: forwarded $ref
384 X-$gProject-PR-Package: $data->{package}
385 X-$gProject-PR-Keywords: $data->{keywords}
387 Your message dated $header{'date'}
388 with message-id $header{'message-id'}
389 has caused the $gProject $gBug report #$ref,
390 regarding $data->{subject}
391 to be marked as having been forwarded to the upstream software
392 author(s) $data->{forwarded}.
394 (NB: If you are a system administrator and have no idea what I am
395 talking about this indicates a serious mail system misconfiguration
396 somewhere. Please contact me immediately.)
399 (administrator, $gProject $gBugs database)
404 &htmllog("Reply","sent",$replyto,"You have taken responsibility.");
405 &sendmessage(<<END."--------------------------------------\n".$x."---------------------------------------\n".join( "\n", @msg ), '');
406 From: $gMaintainerEmail ($gProject $gBug Tracking System)
408 ${noticecc}${generalbcc}Subject: $gBug#$ref: marked as done ($data->{subject})
409 Message-ID: <handler.$ref.$nn.ackdone\@$gEmailDomain>
410 In-Reply-To: $header{'message-id'}
411 References: $header{'message-id'} $data->{msgid}
413 X-$gProject-PR-Message: closed $ref
414 X-$gProject-PR-Package: $data->{package}
415 X-$gProject-PR-Keywords: $data->{keywords}
417 Your message dated $header{'date'}
418 with message-id $header{'message-id'}
419 and subject line $subject
420 has caused the attached $gBug report to be marked as done.
422 This means that you claim that the problem has been dealt with.
423 If this is not the case it is now your responsibility to reopen the
424 $gBug report if necessary, and/or fix the problem forthwith.
426 (NB: If you are a system administrator and have no idea what I am
427 talking about this indicates a serious mail system misconfiguration
428 somewhere. Please contact me immediately.)
431 (administrator, $gProject $gBugs database)
434 &htmllog("Notification","sent",$data->{originator},
435 "$gBug acknowledged by developer.");
436 &sendmessage(<<END.join("\n",@msg),'');
437 From: $gMaintainerEmail ($gProject $gBug Tracking System)
438 To: $data->{originator}
439 Subject: $gBug#$ref acknowledged by developer
441 Message-ID: <handler.$ref.$nn.notifdone\@$gEmailDomain>
442 In-Reply-To: $data->{msgid}
443 References: $header{'message-id'} $data->{msgid}
444 X-$gProject-PR-Message: they-closed $ref
445 X-$gProject-PR-Package: $data->{package}
446 X-$gProject-PR-Keywords: $data->{keywords}
447 Reply-To: $ref\@$gEmailDomain
449 This is an automatic notification regarding your $gBug report
450 #$ref: $data->{subject},
451 which was filed against the $data->{package} package.
453 It has been closed by one of the developers, namely
456 Their explanation is attached below. If this explanation is
457 unsatisfactory and you have not received a better one in a separate
458 message then please contact the developer, by replying to this email.
461 (administrator, $gProject $gBugs database)
471 if ($codeletter eq 'U') {
472 &htmllog("Warning","sent",$replyto,"Message not forwarded.");
473 &sendmessage(<<END, '');
474 From: $gMaintainerEmail ($gProject $gBug Tracking System)
476 Subject: Message with no $gBug number cannot be sent to submitter !
478 Message-ID: <handler.x.$nn.nonumnosub\@$gEmailDomain>
479 In-Reply-To: $header{'message-id'}
480 References: $header{'message-id'} $data->{msgid}
482 X-$gProject-PR-Message: error
484 You sent a message to the $gProject $gBug tracking system's $gBug
485 report submitter address $baddress\@$gEmailDomain, without a
486 recognisable $gBug number in the Subject. Your message has been filed
487 under junk but otherwise ignored.
489 If you don't know what I'm talking about then probably either:
491 (a) you unwittingly sent a message to $baddress\@$gEmailDomain
492 because you replied to all recipients of the message a developer sent
493 to a $gBug\'s submitter and you modified the Subject. In this case,
494 please do not be alarmed. To avoid confusion do not do it again, but
495 there is no need to apologise or mail anyone asking for an
498 (b) you are a system administrator, reading this because the $gBug
499 tracking system is responding to a misdirected bounce message. In this
500 case there is a serious mail system misconfiguration somewhere - please
501 contact me immediately.
503 Your message was dated $header{'date'} and had
504 message-id $header{'message-id'}
505 and subject $subject.
507 If you need any assistance or explanation please contact me.
510 (administrator, $gProject $gBugs database)
517 $data->{found_versions} = [];
518 $data->{fixed_versions} = [];
520 if (defined $pheader{source}) {
521 $data->{package} = $pheader{source};
522 } elsif (defined $pheader{package}) {
523 $data->{package} = $pheader{package};
525 &htmllog("Warning","sent",$replyto,"Message not forwarded.");
526 &sendmessage(<<END."---------------------------------------------------------------------------\n".join("\n", @msg), '');
527 From: $gMaintainerEmail ($gProject $gBug Tracking System)
529 Subject: Message with no Package: tag cannot be processed!
531 Message-ID: <handler.x.$nn.nonumnosub\@$gEmailDomain>
532 In-Reply-To: $header{'message-id'}
533 References: $header{'message-id'} $data->{msgid}
535 X-$gProject-PR-Message: error
537 Your message didn't have a Package: line at the start (in the
538 pseudo-header following the real mail header), or didn't have a
539 pseudo-header at all. Your message has been filed under junk but
542 This makes it much harder for us to categorise and deal with your
543 problem report. Please _resubmit_ your report to $baddress\@$gEmailDomain
544 and tell us which package the report is on. For help, check out
545 http://$gWebDomain/Reporting$gHTMLSuffix.
547 Your message was dated $header{'date'} and had
548 message-id $header{'message-id'}
549 and subject $subject.
550 The complete text of it is attached to this message.
552 If you need any assistance or explanation please contact me.
555 (administrator, $gProject $gBugs database)
562 $data->{keywords}= '';
563 if (defined($pheader{'keywords'})) {
564 $data->{keywords}= $pheader{'keywords'};
565 } elsif (defined($pheader{'tags'})) {
566 $data->{keywords}= $pheader{'tags'};
568 if (length($data->{keywords})) {
570 my %gkws = map { ($_, 1) } @gTags;
571 foreach my $kw (sort split(/[,\s]+/, lc($data->{keywords}))) {
572 push @kws, $kw if (defined $gkws{$kw});
574 $data->{keywords} = join(" ", @kws);
576 $data->{severity}= '';
577 if (defined($pheader{'severity'}) || defined($pheader{'priority'})) {
578 $data->{severity}= $pheader{'severity'};
579 $data->{severity}= $pheader{'priority'} unless ($data->{severity});
580 $data->{severity} =~ s/^\s*(.+)\s*$/$1/;
582 if (!grep($_ eq $data->{severity}, @severities, "$gDefaultSeverity")) {
585 Your message specified a Severity: in the pseudo-header, but
586 the severity value $data->{severity} was not recognised.
587 The default severity $gDefaultSeverity is being used instead.
588 The recognised values are: $gShowSeverities.
590 # if we use @gSeverityList array in the above line, perl -c gives:
591 # In string, @gSeverityList now must be written as \@gSeverityList at
592 # process line 452, near "$gDefaultSeverity is being used instead.
593 $data->{severity}= '';
596 if (defined($pheader{owner})) {
597 $data->{owner}= $pheader{owner};
599 &filelock("nextnumber.lock");
600 open(N,"nextnumber") || &quit("nextnumber: read: $!");
601 $v=<N>; $v =~ s/\n$// || &quit("nextnumber bad format");
602 $ref= $v+0; $v += 1; $newref=1;
603 &overwrite('nextnumber', "$v\n");
605 my $hash = get_hashname($ref);
606 &overwrite("db-h/$hash/$ref.log",'');
607 $data->{originator} = $replyto;
608 $data->{date} = $intdate;
609 $data->{subject} = $subject;
610 $data->{msgid} = $header{'message-id'};
611 writebug($ref, $data);
612 &overwrite("db-h/$hash/$ref.report",
613 join("\n",@msg)."\n");
618 print DEBUG "maintainers >@maintaddrs<\n";
620 $orgsender= defined($header{'sender'}) ? "Original-Sender: $header{'sender'}\n" : '';
621 $newsubject= $subject; $newsubject =~ s/^$gBug#$ref:*\s*//;
623 $xcchdr= $header{ 'x-debbugs-cc' };
624 if ($xcchdr =~ m/\S/) {
625 push(@resentccs,$xcchdr);
626 $resentccexplain.= <<END;
628 As you requested using X-Debbugs-CC, your message was also forwarded to
630 (after having been given a $gBug report number, if it did not have one).
634 if (@maintaddrs && ($codeletter eq 'B' || $codeletter eq 'M')) {
635 push(@resentccs,@maintaddrs);
636 $resentccexplain.= <<END." ".join("\n ",@maintaddrs)."\n";
638 Your message has been sent to the package maintainer(s):
642 @bccs = @addsrcaddrs;
643 if (defined $gStrongList and isstrongseverity($data->{severity})) {
644 push @bccs, "$gStrongList\@$gListDomain";
647 # Send mail to the per bug list subscription too
648 push @bccs, "bugs=$ref\@$gListDomain";
650 if (defined $pheader{source}) {
651 # Prefix source versions with the name of the source package. They
652 # appear that way in version trees so that we can deal with binary
653 # packages moving from one source package to another.
654 if (defined $pheader{'source-version'}) {
655 addfoundversions($data, $pheader{source}, $pheader{'source-version'}, '');
656 } elsif (defined $pheader{version}) {
657 addfoundversions($data, $pheader{source}, $pheader{version}, '');
659 writebug($ref, $data);
660 } elsif (defined $pheader{package}) {
661 # TODO: could handle Source-Version: by looking up the source package?
662 addfoundversions($data, $pheader{package}, $pheader{version}, 'binary');
663 writebug($ref, $data);
666 $veryquiet= $codeletter eq 'Q';
667 if ($codeletter eq 'M' && !@maintaddrs) {
671 You requested that the message be sent to the package maintainer(s)
672 but either the $gBug report is not associated with any package (probably
673 because of a missing Package pseudo-header field in the original $gBug
674 report), or the package(s) specified do not have any maintainer(s).
676 Your message has *not* been sent to any package maintainers; it has
677 merely been filed in the $gBug tracking system. If you require assistance
678 please contact $gMaintainerEmail quoting the $gBug number $ref.
682 $resentccval.= join(', ',@resentccs);
683 $resentccval =~ s/\s+\n\s+/ /g; $resentccval =~ s/^\s+/ /; $resentccval =~ s/\s+$//;
684 if (length($resentccval)) {
685 $resentcc= "Resent-CC: $resentccval\n";
688 if ($codeletter eq 'U') {
689 &htmllog("Message", "sent on", $data->{originator}, "$gBug#$ref.");
690 &sendmessage(<<END,[$data->{originator},@resentccs],[@bccs]);
691 Subject: $gBug#$ref: $newsubject
692 Reply-To: $replyto, $ref-quiet\@$gEmailDomain
693 ${orgsender}Resent-To: $data->{originator}
694 ${resentcc}Resent-Date: $tdate
695 Resent-Message-ID: <handler.$ref.$nn\@$gEmailDomain>
696 Resent-Sender: $gMaintainerEmail
697 X-$gProject-PR-Message: report $ref
698 X-$gProject-PR-Package: $data->{package}
699 X-$gProject-PR-Keywords: $data->{keywords}
702 } elsif ($codeletter eq 'B') {
703 &htmllog($newref ? "Report" : "Information", "forwarded",
704 join(', ',"$gSubmitList\@$gListDomain",@resentccs),
705 "<code>$gBug#$ref</code>".
706 (length($data->{package})? "; Package <code>".&sani($data->{package})."</code>" : '').
708 &sendmessage(<<END,["$gSubmitList\@$gListDomain",@resentccs],[@bccs]);
709 Subject: $gBug#$ref: $newsubject
710 Reply-To: $replyto, $ref\@$gEmailDomain
711 Resent-From: $header{'from'}
712 ${orgsender}Resent-To: $gSubmitList\@$gListDomain
713 ${resentcc}Resent-Date: $tdate
714 Resent-Message-ID: <handler.$ref.$nn\@$gEmailDomain>
715 Resent-Sender: $gMaintainerEmail
716 X-$gProject-PR-Message: report $ref
717 X-$gProject-PR-Package: $data->{package}
718 X-$gProject-PR-Keywords: $data->{keywords}
721 } elsif (@resentccs or @bccs) {
722 # D and F done far earlier; B just done - so this must be M or Q
723 # We preserve whichever it was in the Reply-To (possibly adding
726 &htmllog($newref ? "Report" : "Information", "forwarded",
728 "<code>$gBug#$ref</code>".
729 (length($data->{package}) ? "; Package <code>".&sani($data->{package})."</code>" : '').
732 &htmllog($newref ? "Report" : "Information", "stored",
734 "<code>$gBug#$ref</code>".
735 (length($data->{package}) ? "; Package <code>".&sani($data->{package})."</code>" : '').
738 &sendmessage(<<END,[@resentccs],[@bccs]);
739 Subject: $gBug#$ref: $newsubject
740 Reply-To: $replyto, $ref-$baddressroot\@$gEmailDomain
741 Resent-From: $header{'from'}
742 ${orgsender}Resent-To: $resentccval
744 Resent-Message-ID: <handler.$ref.$nn\@$gEmailDomain>
745 Resent-Sender: $gMaintainerEmail
746 X-$gProject-PR-Message: report $ref
747 X-$gProject-PR-Package: $data->{package}
748 X-$gProject-PR-Keywords: $data->{keywords}
753 $htmlbreak= length($brokenness) ? "<p>\n".&sani($brokenness)."\n<p>\n" : '';
754 $htmlbreak =~ s/\n\n/\n<P>\n\n/g;
755 if (length($resentccval)) {
756 $htmlbreak = " Copy sent to <code>".&sani($resentccval)."</code>.".
759 unless (exists $header{'x-debbugs-no-ack'}) {
761 &htmllog("Acknowledgement","sent",$replyto,
763 "New $gBug report received and filed, but not forwarded." :
764 "New $gBug report received and forwarded."). $htmlbreak);
765 &sendmessage($veryquiet ? <<END : $codeletter eq 'M' ? <<END : <<END,'');
766 From: $gMaintainerEmail ($gProject $gBug Tracking System)
768 Subject: $gBug#$ref: Acknowledgement of QUIET report
770 Message-ID: <handler.$ref.$nn.ackquiet\@$gEmailDomain>
771 In-Reply-To: $header{'message-id'}
772 References: $header{'message-id'}
774 X-$gProject-PR-Message: ack-quiet $ref
775 X-$gProject-PR-Package: $data->{package}
776 X-$gProject-PR-Keywords: $data->{keywords}
777 Reply-To: $ref-quiet\@$gEmailDomain
779 Thank you for the problem report you have sent regarding $gProject.
780 This is an automatically generated reply, to let you know your message
781 has been received. It has not been forwarded to the package maintainers
782 or other interested parties; you should ensure that the developers are
783 aware of the problem you have entered into the system - preferably
784 quoting the $gBug reference number, #$ref.
786 If you wish to submit further information on your problem, please send it
787 to $ref-$baddressroot\@$gEmailDomain (and *not*
788 to $baddress\@$gEmailDomain).
790 Please do not reply to the address at the top of this message,
791 unless you wish to report a problem with the $gBug-tracking system.
794 (administrator, $gProject $gBugs database)
796 From: $gMaintainerEmail ($gProject $gBug Tracking System)
798 Subject: $gBug#$ref: Acknowledgement of maintainer-only report
800 Message-ID: <handler.$ref.$nn.ackmaint\@$gEmailDomain>
801 In-Reply-To: $header{'message-id'}
802 References: $header{'message-id'}
804 X-$gProject-PR-Message: ack-maintonly $ref
805 X-$gProject-PR-Package: $data->{package}
806 X-$gProject-PR-Keywords: $data->{keywords}
807 Reply-To: $ref-maintonly\@$gEmailDomain
809 Thank you for the problem report you have sent regarding $gProject.
810 This is an automatically generated reply, to let you know your message has
811 been received. It is being forwarded to the package maintainers (but not
812 other interested parties, as you requested) for their attention; they will
815 If you wish to submit further information on your problem, please send
816 it to $ref-$baddressroot\@$gEmailDomain (and *not*
817 to $baddress\@$gEmailDomain).
819 Please do not reply to the address at the top of this message,
820 unless you wish to report a problem with the $gBug-tracking system.
823 (administrator, $gProject $gBugs database)
825 From: $gMaintainerEmail ($gProject $gBug Tracking System)
827 Subject: $gBug#$ref: Acknowledgement ($subject)
828 Message-ID: <handler.$ref.$nn.ack\@$gEmailDomain>
829 In-Reply-To: $header{'message-id'}
830 References: $header{'message-id'}
832 X-$gProject-PR-Message: ack $ref
833 X-$gProject-PR-Package: $data->{package}
834 X-$gProject-PR-Keywords: $data->{keywords}
835 Reply-To: $ref\@$gEmailDomain
837 Thank you for the problem report you have sent regarding $gProject.
838 This is an automatically generated reply, to let you know your message has
839 been received. It is being forwarded to the package maintainers and other
840 interested parties for their attention; they will reply in due course.
842 If you wish to submit further information on your problem, please send
843 it to $ref\@$gEmailDomain (and *not* to
844 $baddress\@$gEmailDomain).
846 Please do not reply to the address at the top of this message,
847 unless you wish to report a problem with the $gBug-tracking system.
850 (administrator, $gProject $gBugs database)
852 } elsif ($codeletter ne 'U' and
853 $header{'precedence'} !~ /\b(?:bulk|junk|list)\b/) {
854 &htmllog("Acknowledgement","sent",$replyto,
855 ($veryquiet ? "Extra info received and filed, but not forwarded." :
856 $codeletter eq 'M' ? "Extra info received and forwarded to maintainer." :
857 "Extra info received and forwarded to list."). $htmlbreak);
858 &sendmessage($veryquiet ? <<END : $codeletter eq 'M' ? <<END : <<END,'');
859 From: $gMaintainerEmail ($gProject $gBug Tracking System)
861 Subject: $gBug#$ref: Info received and FILED only
863 Message-ID: <handler.$ref.$nn.ackinfoquiet\@$gEmailDomain>
864 In-Reply-To: $header{'message-id'}
865 References: $header{'message-id'}
867 X-$gProject-PR-Message: ack-info-quiet $ref
868 X-$gProject-PR-Package: $data->{package}
869 X-$gProject-PR-Keywords: $data->{keywords}
870 Reply-To: $ref-quiet\@$gEmailDomain
872 Thank you for the additional information you have supplied regarding
873 this problem report. It has NOT been forwarded to the package
874 maintainers, but will accompany the original report in the $gBug
875 tracking system. Please ensure that you yourself have sent a copy of
876 the additional information to any relevant developers or mailing lists.
878 If you wish to continue to submit further information on your problem,
879 please send it to $ref-$baddressroot\@$gEmailDomain, as before.
881 Please do not reply to the address at the top of this message,
882 unless you wish to report a problem with the $gBug-tracking system.
885 (administrator, $gProject $gBugs database)
887 From: $gMaintainerEmail ($gProject $gBug Tracking System)
889 Subject: $gBug#$ref: Info received for maintainer only
891 Message-ID: <handler.$ref.$nn.ackinfomaint\@$gEmailDomain>
892 In-Reply-To: $header{'message-id'}
893 References: $header{'message-id'}
895 X-$gProject-PR-Message: ack-info-maintonly $ref
896 X-$gProject-PR-Package: $data->{package}
897 X-$gProject-PR-Keywords: $data->{keywords}
898 Reply-To: $ref-maintonly\@$gEmailDomain
900 Thank you for the additional information you have supplied regarding
901 this problem report. It has been forwarded to the package maintainer(s)
902 (but not to other interested parties) to accompany the original report.
904 If you wish to continue to submit further information on your problem,
905 please send it to $ref-$baddressroot\@$gEmailDomain, as before.
907 Please do not reply to the address at the top of this message,
908 unless you wish to report a problem with the $gBug-tracking system.
911 (administrator, $gProject $gBugs database)
913 From: $gMaintainerEmail ($gProject $gBug Tracking System)
915 Subject: $gBug#$ref: Info received (was $subject)
916 Message-ID: <handler.$ref.$nn.ackinfo\@$gEmailDomain>
917 In-Reply-To: $header{'message-id'}
918 References: $header{'message-id'}
920 X-$gProject-PR-Message: ack-info $ref
921 X-$gProject-PR-Package: $data->{package}
922 X-$gProject-PR-Keywords: $data->{keywords}
924 Thank you for the additional information you have supplied regarding
925 this problem report. It has been forwarded to the package maintainer(s)
926 and to other interested parties to accompany the original report.
928 If you wish to continue to submit further information on your problem,
929 please send it to $ref\@$gEmailDomain, as before.
931 Please do not reply to the address at the top of this message,
932 unless you wish to report a problem with the $gBug-tracking system.
935 (administrator, $gProject $gBugs database)
937 # Reply-To: in previous ack disabled by doogie due to mail loops.
938 # Are these still a concern?
939 # Reply-To: $ref\@$gEmailDomain
948 open(NEW,">$f.new") || &quit("$f.new: create: $!");
949 print(NEW "$v") || &quit("$f.new: write: $!");
950 close(NEW) || &quit("$f.new: close: $!");
951 rename("$f.new","$f") || &quit("rename $f.new to $f: $!");
955 my $hash = get_hashname($ref);
956 if (!open(AP,">>db-h/$hash/$ref.log")) {
957 print DEBUG "failed open log<\n";
958 print DEBUG "failed open log err $!<\n";
959 &quit("opening db-h/$hash/$ref.log (li): $!");
961 print(AP "\7\n",@{escapelog(@log)},"\n\3\n") || &quit("writing db-h/$hash/$ref.log (li): $!");
962 close(AP) || &quit("closing db-h/$hash/$ref.log (li): $!");
966 utime(time,time,"db");
968 while ($u= $cleanups[$#cleanups]) { &$u; }
969 unlink("incoming/P$nn") || &quit("unlinking incoming/P$nn: $!");
973 &quit("wot no exit");
975 sub chldhandle { $chldexit = 'yes'; }
978 local ($whatobj,$whatverb,$where,$desc) = @_;
979 my $hash = get_hashname($ref);
980 open(AP,">>db-h/$hash/$ref.log") || &quit("opening db-h/$hash/$ref.log (lh): $!");
983 "<strong>$whatobj $whatverb</strong>".
984 ($where eq '' ? "" : " to <code>".&sani($where)."</code>").
986 "\n\3\n") || &quit("writing db-h/$hash/$ref.log (lh): $!");
987 close(AP) || &quit("closing db-h/$hash/$ref.log (lh): $!");
994 while ($msg =~ s/(.*\n)//) {
1001 # strip continuation lines too
1015 local ($msg,$recips,$bcc) = @_;
1016 if ((!ref($recips) && $recips eq '') || @$recips == 0) {
1019 $msg = "X-Loop: $gMaintainerEmail\n" . $msg;
1020 # The original message received is written out in appendlog, so
1021 # before writing out the other messages we've sent out, we need to
1022 # RFC1522 encode the header.
1023 $msg = encode_headers($msg);
1025 my $hash = get_hashname($ref);
1026 #save email to the log
1027 open(AP,">>db-h/$hash/$ref.log") || &quit("opening db-h/$hash/$ref.log (lo): $!");
1028 print(AP "\2\n",join("\4",@$recips),"\n\5\n",
1029 @{escapelog(stripbccs($msg))},"\n\3\n") ||
1030 &quit("writing db-h/$hash/$ref.log (lo): $!");
1031 close(AP) || &quit("closing db-h/$hash/$ref.log (lo): $!");
1034 shift @$recips if $recips->[0] eq '-t';
1035 push @$recips, @$bcc;
1038 send_mail_message(message => $msg,
1039 # Because we encode the headers above, we do not want to encode them here
1040 encode_headers => 0,
1041 recipients => $recips);
1044 sub checkmaintainers {
1045 return if $maintainerschecked++;
1046 return if !length($data->{package});
1047 open(MAINT,"$gMaintainerFile") || die &quit("maintainers open: $!");
1051 m/^(\S+)\s+(\S.*\S)\s*\n$/ || &quit("maintainers bogus \`$_'");
1052 $a= $1; $b= $2; $a =~ y/A-Z/a-z/;
1053 $maintainerof{$1}= $2;
1056 open(MAINT,"$gMaintainerFileOverride") || die &quit("maintainers.override open: $!");
1060 m/^(\S+)\s+(\S.*\S)\s*\n$/ || &quit("maintainers.override bogus \`$_'");
1061 $a= $1; $b= $2; $a =~ y/A-Z/a-z/;
1062 $maintainerof{$1}= $2;
1065 open(SOURCES,"$gPackageSource") || &quit("pkgsrc open: $!");
1067 next unless m/^(\S+)\s+\S+\s+(\S.*\S)\s*$/;
1073 $anymaintfound=0; $anymaintnotfound=0;
1074 for $p (split(m/[ \t?,():]+/,$data->{package})) {
1076 $p =~ /([a-z0-9.+-]+)/;
1078 next unless defined $p;
1079 if (defined $gSubscriptionDomain) {
1080 if (defined($pkgsrc{$p})) {
1081 push @addsrcaddrs, "$pkgsrc{$p}\@$gSubscriptionDomain";
1083 push @addsrcaddrs, "$p\@$gSubscriptionDomain";
1086 if (defined($maintainerof{$p})) {
1087 print DEBUG "maintainer add >$p|$maintainerof{$p}<\n";
1088 $addmaint= $maintainerof{$p};
1089 push(@maintaddrs,$addmaint) unless
1090 ($addmaint eq $replyto and $codeletter ne 'M') ||
1091 grep($_ eq $addmaint, @maintaddrs);
1094 print DEBUG "maintainer none >$p<\n";
1095 push(@maintaddrs,$gUnknownMaintainerEmail) unless $anymaintnotfound;
1096 $anymaintnotfound++;
1101 if (length $data->{owner}) {
1102 print DEBUG "owner add >$data->{package}|$data->{owner}<\n";
1103 $addmaint = $data->{owner};
1104 push(@maintaddrs, $addmaint) unless
1105 $addmaint eq $replyto or grep($_ eq $addmaint, @maintaddrs);
1109 =head2 bug_list_forward
1111 bug_list_forward($spool_filename) if $codeletter eq 'L';
1114 Given the spool file, will forward a bug to the per bug mailing list
1115 subscription system.
1119 sub bug_list_forward{
1121 # Read the bug information and package information for passing to
1123 my ($bug_number) = $bug_fn =~ /^L(\d+)\./;
1124 my ($bfound, $data)= lockreadbugmerge($bug_number);
1125 my $bug_fh = new IO::File "incoming/P$bug_fn" or die "Unable to open incoming/P$bug_fn $!";
1128 my $bug_message = <$bug_fh>;
1129 my ($bug_address) = $bug_message =~ /^Received: \(at ([^\)]+)\) by/;
1130 my ($envelope_from) = $bug_message =~ s/\nFrom\s+([^\s]+)[^\n]+\n/\n/;
1131 if (not defined $envelope_from) {
1132 # Try to use the From: header or something to set it
1133 ($envelope_from) = $bug_message =~ /\nFrom:\s+(.+?)\n/;
1134 # Kludgy, and should really be using a full scale header
1135 # parser to do this.
1136 $envelope_from =~ s/^.+?<([^>]+)>.+$/$1/;
1138 my ($header,$body) = split /\n\n/, $bug_message, 2;
1139 # Add X-$gProject-PR-Message: list bug_number and package name headers
1140 if (defined $data and $bfound) {
1141 $header .= qq(\nX-$gProject-PR-Message: list $bug_number\n).
1142 qq(X-$gProject-PR-Package: $data->{package}\n).
1143 qq(X-$gProject-PR-Title: $data->{subject});
1146 $header .= qq(\nX-$gProject-PR-Message: list inactivebug);
1148 print STDERR "Tried to loop me with $envelope_from\n"
1149 and exit 1 if $envelope_from =~ /\Q$gListDomain\E|\Q$gEmailDomain\E/;
1150 print DEBUG $envelope_from,qq(\n);
1151 # If we don't have a bug address, something has gone horribly wrong.
1152 print STDERR "Doesn't match: $bug_address\n" and exit 1 unless defined $bug_address;
1153 $bug_address =~ s/\@.+//;
1154 print DEBUG "Sending message to bugs=$bug_address\@$gListDomain\n";
1155 print DEBUG $header.qq(\n\n).$body;
1156 send_mail_message(message => $header.qq(\n\n).$body,
1157 recipients => ["bugs=$bug_address\@$gListDomain"],
1158 envelope_from => $envelope_from,
1159 encode_headers => 0,
1161 unlink("incoming/P$bug_fn") || &quit("unlinking incoming/P$bug_fn: $!");