2 # $Id: process.in,v 1.105 2005/10/06 03:40:32 ajt Exp $
7 use POSIX qw(strftime tzset);
12 use Debbugs::MIME qw(decode_rfc1522);
13 use Debbugs::Mail qw(send_mail_message encode_headers);
15 $config_path = '/etc/debbugs';
16 $lib_path = '/usr/lib/debbugs';
18 require "$config_path/config";
19 require "$lib_path/errorlib";
20 $ENV{'PATH'} = $lib_path.':'.$ENV{'PATH'};
22 chdir( "$gSpoolDir" ) || die "chdir spool: $!\n";
24 #open(DEBUG,"> /tmp/debbugs.debug");
26 open DEBUG, ">/dev/null";
28 defined( $intdate= time ) || &quit( "failed to get time: $!" );
31 m/^([BMQFDUL])(\d*)\.\d+$/ || &quit("bad argument");
33 $tryref= length($2) ? $2+0 : -1;
36 if (!rename("incoming/G$nn","incoming/P$nn"))
38 $_=$!.''; m/no such file or directory/i && exit 0;
39 &quit("renaming to lock: $!");
42 $baddress= 'submit' if $codeletter eq 'B';
43 $baddress= 'maintonly' if $codeletter eq 'M';
44 $baddress= 'quiet' if $codeletter eq 'Q';
45 $baddress= 'forwarded' if $codeletter eq 'F';
46 $baddress= 'done' if $codeletter eq 'D';
47 $baddress= 'submitter' if $codeletter eq 'U';
48 bug_list_forward($nn) if $codeletter eq 'L';
49 $baddress || &quit("bad codeletter $codeletter");
50 $baddressroot= $baddress;
51 $baddress= "$tryref-$baddress" if $tryref>=0;
53 open(M,"incoming/P$nn");
60 print DEBUG "###\n",join("##\n",@msg),"\n###\n";
62 $tdate = strftime "%a, %d %h %Y %T UTC", localtime;
64 Received: via spool by $baddress\@$gEmailDomain id=$nn
65 (code $codeletter ref $tryref); $tdate
68 # header and decoded body respectively
69 my (@headerlines, @bodylines);
71 my $parser = new MIME::Parser;
72 mkdir "$gSpoolDir/mime.tmp", 0777;
73 $parser->output_under("$gSpoolDir/mime.tmp");
74 my $entity = eval { $parser->parse_data(join('',@log)) };
76 if ($entity and $entity->head->tags) {
77 @headerlines = @{$entity->head->header};
80 my $entity_body = getmailbody($entity);
81 @bodylines = $entity_body ? $entity_body->as_lines() : ();
84 # set $i to beginning of encoded body data, so we can dump it out
87 ++$i while $msg[$i] =~ /./;
89 # Legacy pre-MIME code, kept around in case MIME::Parser fails.
90 for ($i = 0; $i <= $#msg; $i++) {
92 last unless length($_);
93 while ($msg[$i+1] =~ m/^\s/) {
97 push @headerlines, $_;
100 @bodylines = @msg[$i..$#msg];
103 for my $hdr (@headerlines) {
104 $hdr = decode_rfc1522($hdr);
107 &finish if m/^x-loop: (\S+)$/i && $1 eq "$gMaintainerEmail";
108 my $ins = !m/^subject:/i && !m/^reply-to:/i && !m/^return-path:/i
109 && !m/^From / && !m/^X-Debbugs-/i;
110 $fwd .= $hdr."\n" if $ins;
111 # print DEBUG ">$_<\n";
112 if (s/^(\S+):\s*//) {
114 print DEBUG ">$v=$_<\n";
117 print DEBUG "!>$_<\n";
122 shift @bodylines while @bodylines and $bodylines[0] !~ /\S/;
124 # Strip off RFC2440-style PGP clearsigning.
125 if (@bodylines and $bodylines[0] =~ /^-----BEGIN PGP SIGNED/) {
126 shift @bodylines while @bodylines and length $bodylines[0];
127 shift @bodylines while @bodylines and $bodylines[0] !~ /\S/;
128 for my $findsig (0 .. $#bodylines) {
129 if ($bodylines[$findsig] =~ /^-----BEGIN PGP SIGNATURE/) {
130 $#bodylines = $findsig - 1;
134 map { s/^- // } @bodylines;
137 # extract pseudo-headers
138 for my $phline (@bodylines)
140 last if $phline !~ m/^([\w-]+):\s*(\S.*)/;
141 my ($fn, $fv) = ($1, $2);
143 print DEBUG ">$fn|$fv|\n";
147 print DEBUG ">$fn~$fv<\n";
151 $fwd .= join("\n",@msg[$i..$#msg]);
153 print DEBUG "***\n$fwd\n***\n";
155 if (defined $header{'resent-from'} && !defined $header{'from'}) {
156 $header{'from'} = $header{'resent-from'};
158 defined($header{'from'}) || &quit("no From header");
160 $replyto = $header{'reply-to'};
161 $replyto = '' unless defined $replyto;
164 unless (length $replyto) {
165 $replyto = $header{'from'};
169 $_= "$2 <$1>" if m/^([^\<\> \t\n\(\)]+) \(([^\(\)\<\>]+)\)$/;
171 print DEBUG "replytocompare >$replytocompare<\n";
173 if (!defined($header{'subject'}))
177 Your message did not contain a Subject field. They are recommended and
178 useful because the title of a $gBug is determined using this field.
179 Please remember to include a Subject field in your messages in future.
182 # RFC822 actually lists it as an `optional-field'.
184 $subject= '(no subject)';
186 $subject= $header{'subject'};
190 $subject =~ s/^Re:\s*//i; $_= $subject."\n";
191 if ($tryref < 0 && m/^Bug ?\#(\d+)\D/i) {
197 ($bfound, $data)= &lockreadbugmerge($tryref);
201 &htmllog("Reply","sent", $replyto,"Unknown problem report number <code>$tryref</code>.");
202 my $archivenote = '';
204 $archivenote = <<END;
205 This may be because that $gBug report has been resolved for more than $gRemoveAge
206 days, and the record of it has been archived and made read-only, or
207 because you mistyped the $gBug report number.
211 &sendmessage(<<END, '');
212 From: $gMaintainerEmail ($gProject $gBug Tracking System)
214 Subject: Unknown problem report $gBug#$tryref ($subject)
215 Message-ID: <handler.x.$nn.unknown\@$gEmailDomain>
216 In-Reply-To: $header{'message-id'}
217 References: $header{'message-id'} $data->{msgid}
219 X-$gProject-PR-Message: error
221 You sent a message to the $gBug tracking system which gave (in the
222 Subject line or encoded into the recipient at $gEmailDomain),
223 the number of a nonexistent $gBug report (#$tryref).
225 ${archivenote}Your message was dated $header{'date'} and was sent to
226 $baddress\@$gEmailDomain. It had
227 Message-ID $header{'message-id'}
228 and Subject $subject.
230 It has been filed (under junk) but otherwise ignored.
232 Please consult your records to find the correct $gBug report number, or
233 contact me, the system administrator, for assistance.
236 (administrator, $gProject $gBugs database)
238 (NB: If you are a system administrator and have no idea what I am
239 talking about this indicates a serious mail system misconfiguration
240 somewhere. Please contact me immediately.)
247 &filelock('lock/-1');
250 if ($codeletter eq 'D' || $codeletter eq 'F')
252 if ($replyto =~ m/$gBounceFroms/o ||
253 $header{'from'} =~ m/$gBounceFroms/o)
255 &quit("bounce detected ! Mwaap! Mwaap!");
257 $markedby= $header{'from'} eq $replyto ? $replyto :
258 "$header{'from'} (reply to $replyto)";
259 if ($codeletter eq 'F') {
260 (&appendlog,&finish) if length($data->{forwarded});
261 $receivedat= "forwarded\@$gEmailDomain";
262 $markaswhat= 'forwarded';
263 $set_forwarded= $header{'to'};
264 if ( length( $gListDomain ) > 0 && length( $gForwardList ) > 0 ) {
265 $generalcc= "$gForwardList\@$gListDomain";
270 if (length($data->{done}) and
271 not defined $pheader{'source-version'} and
272 not defined $pheader{'version'}) {
276 $receivedat= "done\@$gEmailDomain";
278 $set_done= $header{'from'};
279 if ( length( $gListDomain ) > 0 && length( $gDoneList ) > 0 ) {
280 $generalcc= "$gDoneList\@$gListDomain";
285 if (defined $gStrongList and isstrongseverity($data->{severity})) {
286 $generalcc = join ', ', $generalcc, "$gStrongList\@$gListDomain";
289 &htmllog("Warning","sent",$replyto,"Message ignored.");
290 &sendmessage(<<END, '');
291 From: $gMaintainerEmail ($gProject $gBug Tracking System)
293 Subject: Message with no $gBug number ignored by $receivedat
295 Message-ID: <header.x.$nn.warnignore\@$gEmailDomain>
296 In-Reply-To: $header{'message-id'}
297 References: $header{'message-id'} $data->{msgid}
299 X-$gProject-PR-Message: error
301 You sent a message to the $gProject $gBug tracking system old-style
302 unified mark as $markaswhat address ($receivedat),
303 without a recognisable $gBug number in the Subject.
304 Your message has been filed under junk but otherwise ignored.
306 If you don't know what I'm talking about then probably either:
308 (a) you unwittingly sent a message to done\@$gEmailDomain
309 because you replied to all recipients of the message a developer used
310 to mark a $gBug as done and you modified the Subject. In this case,
311 please do not be alarmed. To avoid confusion do not do it again, but
312 there is no need to apologise or mail anyone asking for an explanation.
314 (b) you are a system administrator, reading this because the $gBug
315 tracking system is responding to a misdirected bounce message. In this
316 case there is a serious mail system misconfiguration somewhere - please
317 contact me immediately.
319 Your message was dated $header{'date'} and had
320 message-id $header{'message-id'}
321 and subject $subject.
323 If you need any assistance or explanation please contact me.
326 (administrator, $gProject $gBugs database)
335 $noticeccval.= join(', ', grep($_ ne $replyto,@maintaddrs));
336 $noticeccval =~ s/\s+\n\s+/ /g;
337 $noticeccval =~ s/^\s+/ /; $noticeccval =~ s/\s+$//;
338 if (length($noticeccval)) { $noticecc= "Cc: $noticeccval\n"; }
340 @process= ($ref,split(/ /,$data->{mergedwith}));
343 for $ref (@process) {
344 if ($ref != $orgref) {
346 $data = &lockreadbug($ref)
347 || die "huh ? $ref from $orgref out of @process";
349 $data->{done}= $set_done if defined($set_done);
350 $data->{forwarded}= $set_forwarded if defined($set_forwarded);
351 if ($codeletter eq 'D') {
352 $data->{keywords} = join ' ', grep $_ ne 'pending',
353 split ' ', $data->{keywords};
354 if (defined $pheader{'source-version'}) {
355 addfixedversions($data, $pheader{source}, $pheader{'source-version'}, '');
356 } elsif (defined $pheader{version}) {
357 addfixedversions($data, $pheader{package}, $pheader{version}, 'binary');
361 # Add bug mailing list to $generalbcc as appropriate
362 my $generalbcc = join(', ', $generalcc, @addsrcaddrs,"bugs=$ref\@$gListDomain");
363 $generalbcc =~ s/\s+\n\s+/ /g;
364 $generalbcc =~ s/^\s+/ /; $generalbcc =~ s/\s+$//;
365 if (length $generalbcc) {$generalbcc = "Bcc: $generalbcc\n"};
367 writebug($ref, $data);
369 my $hash = get_hashname($ref);
370 open(O,"db-h/$hash/$ref.report") || &quit("read original report: $!");
371 $x= join('',<O>); close(O);
372 if ($codeletter eq 'F') {
373 &htmllog("Reply","sent",$replyto,"You have marked $gBug as forwarded.");
374 &sendmessage(<<END."---------------------------------------\n".join( "\n", @msg ), '');
375 From: $gMaintainerEmail ($gProject $gBug Tracking System)
377 ${noticecc}${generalbcc}Subject: $gBug#$ref: marked as forwarded ($data->{subject})
378 Message-ID: <header.$ref.$nn.ackfwdd\@$gEmailDomain>
379 In-Reply-To: $header{'message-id'}
380 References: $header{'message-id'} $data->{msgid}
382 X-$gProject-PR-Message: forwarded $ref
383 X-$gProject-PR-Package: $data->{package}
384 X-$gProject-PR-Keywords: $data->{keywords}
386 Your message dated $header{'date'}
387 with message-id $header{'message-id'}
388 has caused the $gProject $gBug report #$ref,
389 regarding $data->{subject}
390 to be marked as having been forwarded to the upstream software
391 author(s) $data->{forwarded}.
393 (NB: If you are a system administrator and have no idea what I am
394 talking about this indicates a serious mail system misconfiguration
395 somewhere. Please contact me immediately.)
398 (administrator, $gProject $gBugs database)
403 &htmllog("Reply","sent",$replyto,"You have taken responsibility.");
404 &sendmessage(<<END."--------------------------------------\n".$x."---------------------------------------\n".join( "\n", @msg ), '');
405 From: $gMaintainerEmail ($gProject $gBug Tracking System)
407 ${noticecc}${generalbcc}Subject: $gBug#$ref: marked as done ($data->{subject})
408 Message-ID: <handler.$ref.$nn.ackdone\@$gEmailDomain>
409 In-Reply-To: $header{'message-id'}
410 References: $header{'message-id'} $data->{msgid}
412 X-$gProject-PR-Message: closed $ref
413 X-$gProject-PR-Package: $data->{package}
414 X-$gProject-PR-Keywords: $data->{keywords}
416 Your message dated $header{'date'}
417 with message-id $header{'message-id'}
418 and subject line $subject
419 has caused the attached $gBug report to be marked as done.
421 This means that you claim that the problem has been dealt with.
422 If this is not the case it is now your responsibility to reopen the
423 $gBug report if necessary, and/or fix the problem forthwith.
425 (NB: If you are a system administrator and have no idea what I am
426 talking about this indicates a serious mail system misconfiguration
427 somewhere. Please contact me immediately.)
430 (administrator, $gProject $gBugs database)
433 &htmllog("Notification","sent",$data->{originator},
434 "$gBug acknowledged by developer.");
435 &sendmessage(<<END.join("\n",@msg),'');
436 From: $gMaintainerEmail ($gProject $gBug Tracking System)
437 To: $data->{originator}
438 Subject: $gBug#$ref acknowledged by developer
440 Message-ID: <handler.$ref.$nn.notifdone\@$gEmailDomain>
441 In-Reply-To: $data->{msgid}
442 References: $header{'message-id'} $data->{msgid}
443 X-$gProject-PR-Message: they-closed $ref
444 X-$gProject-PR-Package: $data->{package}
445 X-$gProject-PR-Keywords: $data->{keywords}
446 Reply-To: $ref\@$gEmailDomain
448 This is an automatic notification regarding your $gBug report
449 #$ref: $data->{subject},
450 which was filed against the $data->{package} package.
452 It has been closed by one of the developers, namely
455 Their explanation is attached below. If this explanation is
456 unsatisfactory and you have not received a better one in a separate
457 message then please contact the developer, by replying to this email.
460 (administrator, $gProject $gBugs database)
470 if ($codeletter eq 'U') {
471 &htmllog("Warning","sent",$replyto,"Message not forwarded.");
472 &sendmessage(<<END, '');
473 From: $gMaintainerEmail ($gProject $gBug Tracking System)
475 Subject: Message with no $gBug number cannot be sent to submitter !
477 Message-ID: <handler.x.$nn.nonumnosub\@$gEmailDomain>
478 In-Reply-To: $header{'message-id'}
479 References: $header{'message-id'} $data->{msgid}
481 X-$gProject-PR-Message: error
483 You sent a message to the $gProject $gBug tracking system's $gBug
484 report submitter address $baddress\@$gEmailDomain, without a
485 recognisable $gBug number in the Subject. Your message has been filed
486 under junk but otherwise ignored.
488 If you don't know what I'm talking about then probably either:
490 (a) you unwittingly sent a message to $baddress\@$gEmailDomain
491 because you replied to all recipients of the message a developer sent
492 to a $gBug\'s submitter and you modified the Subject. In this case,
493 please do not be alarmed. To avoid confusion do not do it again, but
494 there is no need to apologise or mail anyone asking for an
497 (b) you are a system administrator, reading this because the $gBug
498 tracking system is responding to a misdirected bounce message. In this
499 case there is a serious mail system misconfiguration somewhere - please
500 contact me immediately.
502 Your message was dated $header{'date'} and had
503 message-id $header{'message-id'}
504 and subject $subject.
506 If you need any assistance or explanation please contact me.
509 (administrator, $gProject $gBugs database)
516 $data->{found_versions} = [];
517 $data->{fixed_versions} = [];
519 if (defined $pheader{source}) {
520 $data->{package} = $pheader{source};
521 } elsif (defined $pheader{package}) {
522 $data->{package} = $pheader{package};
524 &htmllog("Warning","sent",$replyto,"Message not forwarded.");
525 &sendmessage(<<END."---------------------------------------------------------------------------\n".join("\n", @msg), '');
526 From: $gMaintainerEmail ($gProject $gBug Tracking System)
528 Subject: Message with no Package: tag cannot be processed!
530 Message-ID: <handler.x.$nn.nonumnosub\@$gEmailDomain>
531 In-Reply-To: $header{'message-id'}
532 References: $header{'message-id'} $data->{msgid}
534 X-$gProject-PR-Message: error
536 Your message didn't have a Package: line at the start (in the
537 pseudo-header following the real mail header), or didn't have a
538 pseudo-header at all. Your message has been filed under junk but
541 This makes it much harder for us to categorise and deal with your
542 problem report. Please _resubmit_ your report to $baddress\@$gEmailDomain
543 and tell us which package the report is on. For help, check out
544 http://$gWebDomain/Reporting$gHTMLSuffix.
546 Your message was dated $header{'date'} and had
547 message-id $header{'message-id'}
548 and subject $subject.
549 The complete text of it is attached to this message.
551 If you need any assistance or explanation please contact me.
554 (administrator, $gProject $gBugs database)
561 $data->{keywords}= '';
562 if (defined($pheader{'keywords'})) {
563 $data->{keywords}= $pheader{'keywords'};
564 } elsif (defined($pheader{'tags'})) {
565 $data->{keywords}= $pheader{'tags'};
567 if (length($data->{keywords})) {
569 my %gkws = map { ($_, 1) } @gTags;
570 foreach my $kw (sort split(/[,\s]+/, lc($data->{keywords}))) {
571 push @kws, $kw if (defined $gkws{$kw});
573 $data->{keywords} = join(" ", @kws);
575 $data->{severity}= '';
576 if (defined($pheader{'severity'}) || defined($pheader{'priority'})) {
577 $data->{severity}= $pheader{'severity'};
578 $data->{severity}= $pheader{'priority'} unless ($data->{severity});
579 $data->{severity} =~ s/^\s*(.+)\s*$/$1/;
581 if (!grep($_ eq $data->{severity}, @severities, "$gDefaultSeverity")) {
584 Your message specified a Severity: in the pseudo-header, but
585 the severity value $data->{severity} was not recognised.
586 The default severity $gDefaultSeverity is being used instead.
587 The recognised values are: $gShowSeverities.
589 # if we use @gSeverityList array in the above line, perl -c gives:
590 # In string, @gSeverityList now must be written as \@gSeverityList at
591 # process line 452, near "$gDefaultSeverity is being used instead.
592 $data->{severity}= '';
595 if (defined($pheader{owner})) {
596 $data->{owner}= $pheader{owner};
598 &filelock("nextnumber.lock");
599 open(N,"nextnumber") || &quit("nextnumber: read: $!");
600 $v=<N>; $v =~ s/\n$// || &quit("nextnumber bad format");
601 $ref= $v+0; $v += 1; $newref=1;
602 &overwrite('nextnumber', "$v\n");
604 my $hash = get_hashname($ref);
605 &overwrite("db-h/$hash/$ref.log",'');
606 $data->{originator} = $replyto;
607 $data->{date} = $intdate;
608 $data->{subject} = $subject;
609 $data->{msgid} = $header{'message-id'};
610 writebug($ref, $data);
611 &overwrite("db-h/$hash/$ref.report",
612 join("\n",@msg)."\n");
617 print DEBUG "maintainers >@maintaddrs<\n";
619 $orgsender= defined($header{'sender'}) ? "Original-Sender: $header{'sender'}\n" : '';
620 $newsubject= $subject; $newsubject =~ s/^$gBug#$ref:*\s*//;
622 $xcchdr= $header{ 'x-debbugs-cc' };
623 if ($xcchdr =~ m/\S/) {
624 push(@resentccs,$xcchdr);
625 $resentccexplain.= <<END;
627 As you requested using X-Debbugs-CC, your message was also forwarded to
629 (after having been given a $gBug report number, if it did not have one).
633 if (@maintaddrs && ($codeletter eq 'B' || $codeletter eq 'M')) {
634 push(@resentccs,@maintaddrs);
635 $resentccexplain.= <<END." ".join("\n ",@maintaddrs)."\n";
637 Your message has been sent to the package maintainer(s):
641 @bccs = @addsrcaddrs;
642 if (defined $gStrongList and isstrongseverity($data->{severity})) {
643 push @bccs, "$gStrongList\@$gListDomain";
646 # Send mail to the per bug list subscription too
647 push @bccs, "bugs=$ref\@$gListDomain";
649 if (defined $pheader{source}) {
650 # Prefix source versions with the name of the source package. They
651 # appear that way in version trees so that we can deal with binary
652 # packages moving from one source package to another.
653 if (defined $pheader{'source-version'}) {
654 addfoundversions($data, $pheader{source}, $pheader{'source-version'}, '');
655 } elsif (defined $pheader{version}) {
656 addfoundversions($data, $pheader{source}, $pheader{version}, '');
658 writebug($ref, $data);
659 } elsif (defined $pheader{package}) {
660 # TODO: could handle Source-Version: by looking up the source package?
661 addfoundversions($data, $pheader{package}, $pheader{version}, 'binary');
662 writebug($ref, $data);
665 $veryquiet= $codeletter eq 'Q';
666 if ($codeletter eq 'M' && !@maintaddrs) {
670 You requested that the message be sent to the package maintainer(s)
671 but either the $gBug report is not associated with any package (probably
672 because of a missing Package pseudo-header field in the original $gBug
673 report), or the package(s) specified do not have any maintainer(s).
675 Your message has *not* been sent to any package maintainers; it has
676 merely been filed in the $gBug tracking system. If you require assistance
677 please contact $gMaintainerEmail quoting the $gBug number $ref.
681 $resentccval.= join(', ',@resentccs);
682 $resentccval =~ s/\s+\n\s+/ /g; $resentccval =~ s/^\s+/ /; $resentccval =~ s/\s+$//;
683 if (length($resentccval)) {
684 $resentcc= "Resent-CC: $resentccval\n";
687 if ($codeletter eq 'U') {
688 &htmllog("Message", "sent on", $data->{originator}, "$gBug#$ref.");
689 &sendmessage(<<END,[$data->{originator},@resentccs],[@bccs]);
690 Subject: $gBug#$ref: $newsubject
691 Reply-To: $replyto, $ref-quiet\@$gEmailDomain
692 ${orgsender}Resent-To: $data->{originator}
693 ${resentcc}Resent-Date: $tdate
694 Resent-Message-ID: <handler.$ref.$nn\@$gEmailDomain>
695 Resent-Sender: $gMaintainerEmail
696 X-$gProject-PR-Message: report $ref
697 X-$gProject-PR-Package: $data->{package}
698 X-$gProject-PR-Keywords: $data->{keywords}
701 } elsif ($codeletter eq 'B') {
702 &htmllog($newref ? "Report" : "Information", "forwarded",
703 join(', ',"$gSubmitList\@$gListDomain",@resentccs),
704 "<code>$gBug#$ref</code>".
705 (length($data->{package})? "; Package <code>".&sani($data->{package})."</code>" : '').
707 &sendmessage(<<END,["$gSubmitList\@$gListDomain",@resentccs],[@bccs]);
708 Subject: $gBug#$ref: $newsubject
709 Reply-To: $replyto, $ref\@$gEmailDomain
710 Resent-From: $header{'from'}
711 ${orgsender}Resent-To: $gSubmitList\@$gListDomain
712 ${resentcc}Resent-Date: $tdate
713 Resent-Message-ID: <handler.$ref.$nn\@$gEmailDomain>
714 Resent-Sender: $gMaintainerEmail
715 X-$gProject-PR-Message: report $ref
716 X-$gProject-PR-Package: $data->{package}
717 X-$gProject-PR-Keywords: $data->{keywords}
720 } elsif (@resentccs or @bccs) {
721 # D and F done far earlier; B just done - so this must be M or Q
722 # We preserve whichever it was in the Reply-To (possibly adding
725 &htmllog($newref ? "Report" : "Information", "forwarded",
727 "<code>$gBug#$ref</code>".
728 (length($data->{package}) ? "; Package <code>".&sani($data->{package})."</code>" : '').
731 &htmllog($newref ? "Report" : "Information", "stored",
733 "<code>$gBug#$ref</code>".
734 (length($data->{package}) ? "; Package <code>".&sani($data->{package})."</code>" : '').
737 &sendmessage(<<END,[@resentccs],[@bccs]);
738 Subject: $gBug#$ref: $newsubject
739 Reply-To: $replyto, $ref-$baddressroot\@$gEmailDomain
740 Resent-From: $header{'from'}
741 ${orgsender}Resent-To: $resentccval
743 Resent-Message-ID: <handler.$ref.$nn\@$gEmailDomain>
744 Resent-Sender: $gMaintainerEmail
745 X-$gProject-PR-Message: report $ref
746 X-$gProject-PR-Package: $data->{package}
747 X-$gProject-PR-Keywords: $data->{keywords}
752 $htmlbreak= length($brokenness) ? "<p>\n".&sani($brokenness)."\n<p>\n" : '';
753 $htmlbreak =~ s/\n\n/\n<P>\n\n/g;
754 if (length($resentccval)) {
755 $htmlbreak = " Copy sent to <code>".&sani($resentccval)."</code>.".
758 unless (exists $header{'x-debbugs-no-ack'}) {
760 &htmllog("Acknowledgement","sent",$replyto,
762 "New $gBug report received and filed, but not forwarded." :
763 "New $gBug report received and forwarded."). $htmlbreak);
764 &sendmessage($veryquiet ? <<END : $codeletter eq 'M' ? <<END : <<END,'');
765 From: $gMaintainerEmail ($gProject $gBug Tracking System)
767 Subject: $gBug#$ref: Acknowledgement of QUIET report
769 Message-ID: <handler.$ref.$nn.ackquiet\@$gEmailDomain>
770 In-Reply-To: $header{'message-id'}
771 References: $header{'message-id'}
773 X-$gProject-PR-Message: ack-quiet $ref
774 X-$gProject-PR-Package: $data->{package}
775 X-$gProject-PR-Keywords: $data->{keywords}
776 Reply-To: $ref-quiet\@$gEmailDomain
778 Thank you for the problem report you have sent regarding $gProject.
779 This is an automatically generated reply, to let you know your message
780 has been received. It has not been forwarded to the package maintainers
781 or other interested parties; you should ensure that the developers are
782 aware of the problem you have entered into the system - preferably
783 quoting the $gBug reference number, #$ref.
785 If you wish to submit further information on your problem, please send it
786 to $ref-$baddressroot\@$gEmailDomain (and *not*
787 to $baddress\@$gEmailDomain).
789 Please do not reply to the address at the top of this message,
790 unless you wish to report a problem with the $gBug-tracking system.
793 (administrator, $gProject $gBugs database)
795 From: $gMaintainerEmail ($gProject $gBug Tracking System)
797 Subject: $gBug#$ref: Acknowledgement of maintainer-only report
799 Message-ID: <handler.$ref.$nn.ackmaint\@$gEmailDomain>
800 In-Reply-To: $header{'message-id'}
801 References: $header{'message-id'}
803 X-$gProject-PR-Message: ack-maintonly $ref
804 X-$gProject-PR-Package: $data->{package}
805 X-$gProject-PR-Keywords: $data->{keywords}
806 Reply-To: $ref-maintonly\@$gEmailDomain
808 Thank you for the problem report you have sent regarding $gProject.
809 This is an automatically generated reply, to let you know your message has
810 been received. It is being forwarded to the package maintainers (but not
811 other interested parties, as you requested) for their attention; they will
814 If you wish to submit further information on your problem, please send
815 it to $ref-$baddressroot\@$gEmailDomain (and *not*
816 to $baddress\@$gEmailDomain).
818 Please do not reply to the address at the top of this message,
819 unless you wish to report a problem with the $gBug-tracking system.
822 (administrator, $gProject $gBugs database)
824 From: $gMaintainerEmail ($gProject $gBug Tracking System)
826 Subject: $gBug#$ref: Acknowledgement ($subject)
827 Message-ID: <handler.$ref.$nn.ack\@$gEmailDomain>
828 In-Reply-To: $header{'message-id'}
829 References: $header{'message-id'}
831 X-$gProject-PR-Message: ack $ref
832 X-$gProject-PR-Package: $data->{package}
833 X-$gProject-PR-Keywords: $data->{keywords}
834 Reply-To: $ref\@$gEmailDomain
836 Thank you for the problem report you have sent regarding $gProject.
837 This is an automatically generated reply, to let you know your message has
838 been received. It is being forwarded to the package maintainers and other
839 interested parties for their attention; they will reply in due course.
841 If you wish to submit further information on your problem, please send
842 it to $ref\@$gEmailDomain (and *not* to
843 $baddress\@$gEmailDomain).
845 Please do not reply to the address at the top of this message,
846 unless you wish to report a problem with the $gBug-tracking system.
849 (administrator, $gProject $gBugs database)
851 } elsif ($codeletter ne 'U' and
852 $header{'precedence'} !~ /\b(?:bulk|junk|list)\b/) {
853 &htmllog("Acknowledgement","sent",$replyto,
854 ($veryquiet ? "Extra info received and filed, but not forwarded." :
855 $codeletter eq 'M' ? "Extra info received and forwarded to maintainer." :
856 "Extra info received and forwarded to list."). $htmlbreak);
857 &sendmessage($veryquiet ? <<END : $codeletter eq 'M' ? <<END : <<END,'');
858 From: $gMaintainerEmail ($gProject $gBug Tracking System)
860 Subject: $gBug#$ref: Info received and FILED only
862 Message-ID: <handler.$ref.$nn.ackinfoquiet\@$gEmailDomain>
863 In-Reply-To: $header{'message-id'}
864 References: $header{'message-id'}
866 X-$gProject-PR-Message: ack-info-quiet $ref
867 X-$gProject-PR-Package: $data->{package}
868 X-$gProject-PR-Keywords: $data->{keywords}
869 Reply-To: $ref-quiet\@$gEmailDomain
871 Thank you for the additional information you have supplied regarding
872 this problem report. It has NOT been forwarded to the package
873 maintainers, but will accompany the original report in the $gBug
874 tracking system. Please ensure that you yourself have sent a copy of
875 the additional information to any relevant developers or mailing lists.
877 If you wish to continue to submit further information on your problem,
878 please send it to $ref-$baddressroot\@$gEmailDomain, as before.
880 Please do not reply to the address at the top of this message,
881 unless you wish to report a problem with the $gBug-tracking system.
884 (administrator, $gProject $gBugs database)
886 From: $gMaintainerEmail ($gProject $gBug Tracking System)
888 Subject: $gBug#$ref: Info received for maintainer only
890 Message-ID: <handler.$ref.$nn.ackinfomaint\@$gEmailDomain>
891 In-Reply-To: $header{'message-id'}
892 References: $header{'message-id'}
894 X-$gProject-PR-Message: ack-info-maintonly $ref
895 X-$gProject-PR-Package: $data->{package}
896 X-$gProject-PR-Keywords: $data->{keywords}
897 Reply-To: $ref-maintonly\@$gEmailDomain
899 Thank you for the additional information you have supplied regarding
900 this problem report. It has been forwarded to the package maintainer(s)
901 (but not to other interested parties) to accompany the original report.
903 If you wish to continue to submit further information on your problem,
904 please send it to $ref-$baddressroot\@$gEmailDomain, as before.
906 Please do not reply to the address at the top of this message,
907 unless you wish to report a problem with the $gBug-tracking system.
910 (administrator, $gProject $gBugs database)
912 From: $gMaintainerEmail ($gProject $gBug Tracking System)
914 Subject: $gBug#$ref: Info received (was $subject)
915 Message-ID: <handler.$ref.$nn.ackinfo\@$gEmailDomain>
916 In-Reply-To: $header{'message-id'}
917 References: $header{'message-id'}
919 X-$gProject-PR-Message: ack-info $ref
920 X-$gProject-PR-Package: $data->{package}
921 X-$gProject-PR-Keywords: $data->{keywords}
923 Thank you for the additional information you have supplied regarding
924 this problem report. It has been forwarded to the package maintainer(s)
925 and to other interested parties to accompany the original report.
927 If you wish to continue to submit further information on your problem,
928 please send it to $ref\@$gEmailDomain, as before.
930 Please do not reply to the address at the top of this message,
931 unless you wish to report a problem with the $gBug-tracking system.
934 (administrator, $gProject $gBugs database)
936 # Reply-To: in previous ack disabled by doogie due to mail loops.
937 # Are these still a concern?
938 # Reply-To: $ref\@$gEmailDomain
947 open(NEW,">$f.new") || &quit("$f.new: create: $!");
948 print(NEW "$v") || &quit("$f.new: write: $!");
949 close(NEW) || &quit("$f.new: close: $!");
950 rename("$f.new","$f") || &quit("rename $f.new to $f: $!");
954 my $hash = get_hashname($ref);
955 if (!open(AP,">>db-h/$hash/$ref.log")) {
956 print DEBUG "failed open log<\n";
957 print DEBUG "failed open log err $!<\n";
958 &quit("opening db-h/$hash/$ref.log (li): $!");
960 print(AP "\7\n",@{escapelog(@log)},"\n\3\n") || &quit("writing db-h/$hash/$ref.log (li): $!");
961 close(AP) || &quit("closing db-h/$hash/$ref.log (li): $!");
965 utime(time,time,"db");
967 while ($u= $cleanups[$#cleanups]) { &$u; }
968 unlink("incoming/P$nn") || &quit("unlinking incoming/P$nn: $!");
972 &quit("wot no exit");
974 sub chldhandle { $chldexit = 'yes'; }
977 local ($whatobj,$whatverb,$where,$desc) = @_;
978 my $hash = get_hashname($ref);
979 open(AP,">>db-h/$hash/$ref.log") || &quit("opening db-h/$hash/$ref.log (lh): $!");
982 "<strong>$whatobj $whatverb</strong>".
983 ($where eq '' ? "" : " to <code>".&sani($where)."</code>").
985 "\n\3\n") || &quit("writing db-h/$hash/$ref.log (lh): $!");
986 close(AP) || &quit("closing db-h/$hash/$ref.log (lh): $!");
993 while ($msg =~ s/(.*\n)//) {
1000 # strip continuation lines too
1014 local ($msg,$recips,$bcc) = @_;
1015 if ((!ref($recips) && $recips eq '') || @$recips == 0) {
1018 $msg = "X-Loop: $gMaintainerEmail\n" . $msg;
1019 # The original message received is written out in appendlog, so
1020 # before writing out the other messages we've sent out, we need to
1021 # RFC1522 encode the header.
1022 $msg = encode_headers($msg);
1024 my $hash = get_hashname($ref);
1025 #save email to the log
1026 open(AP,">>db-h/$hash/$ref.log") || &quit("opening db-h/$hash/$ref.log (lo): $!");
1027 print(AP "\2\n",join("\4",@$recips),"\n\5\n",
1028 @{escapelog(stripbccs($msg))},"\n\3\n") ||
1029 &quit("writing db-h/$hash/$ref.log (lo): $!");
1030 close(AP) || &quit("closing db-h/$hash/$ref.log (lo): $!");
1033 shift @$recips if $recips->[0] eq '-t';
1034 push @$recips, @$bcc;
1037 send_mail_message(message => $msg,
1038 # Because we encode the headers above, we do not want to encode them here
1039 encode_headers => 0,
1040 recipients => $recips);
1043 sub checkmaintainers {
1044 return if $maintainerschecked++;
1045 return if !length($data->{package});
1046 open(MAINT,"$gMaintainerFile") || die &quit("maintainers open: $!");
1050 m/^(\S+)\s+(\S.*\S)\s*\n$/ || &quit("maintainers bogus \`$_'");
1051 $a= $1; $b= $2; $a =~ y/A-Z/a-z/;
1052 $maintainerof{$1}= $2;
1055 open(MAINT,"$gMaintainerFileOverride") || die &quit("maintainers.override open: $!");
1059 m/^(\S+)\s+(\S.*\S)\s*\n$/ || &quit("maintainers.override bogus \`$_'");
1060 $a= $1; $b= $2; $a =~ y/A-Z/a-z/;
1061 $maintainerof{$1}= $2;
1064 open(SOURCES,"$gPackageSource") || &quit("pkgsrc open: $!");
1066 next unless m/^(\S+)\s+\S+\s+(\S.*\S)\s*$/;
1072 $anymaintfound=0; $anymaintnotfound=0;
1073 for $p (split(m/[ \t?,():]+/,$data->{package})) {
1075 $p =~ /([a-z0-9.+-]+)/;
1077 next unless defined $p;
1078 if (defined $gSubscriptionDomain) {
1079 if (defined($pkgsrc{$p})) {
1080 push @addsrcaddrs, "$pkgsrc{$p}\@$gSubscriptionDomain";
1082 push @addsrcaddrs, "$p\@$gSubscriptionDomain";
1085 if (defined($maintainerof{$p})) {
1086 print DEBUG "maintainer add >$p|$maintainerof{$p}<\n";
1087 $addmaint= $maintainerof{$p};
1088 push(@maintaddrs,$addmaint) unless
1089 $addmaint eq $replyto || grep($_ eq $addmaint, @maintaddrs);
1092 print DEBUG "maintainer none >$p<\n";
1093 push(@maintaddrs,$gUnknownMaintainerEmail) unless $anymaintnotfound;
1094 $anymaintnotfound++;
1099 if (length $data->{owner}) {
1100 print DEBUG "owner add >$data->{package}|$data->{owner}<\n";
1101 $addmaint = $data->{owner};
1102 push(@maintaddrs, $addmaint) unless
1103 $addmaint eq $replyto or grep($_ eq $addmaint, @maintaddrs);
1107 =head2 bug_list_forward
1109 bug_list_forward($spool_filename) if $codeletter eq 'L';
1112 Given the spool file, will forward a bug to the per bug mailing list
1113 subscription system.
1117 sub bug_list_forward{
1119 # Read the bug information and package information for passing to
1121 my ($bug_number) = $bug_fn =~ /^L(\d+)\./;
1122 my ($bfound, $data)= lockreadbugmerge($bug_number);
1123 my $bug_fh = new IO::File "incoming/P$bug_fn" or die "Unable to open incoming/P$bug_fn $!";
1126 my $bug_message = <$bug_fh>;
1127 my ($bug_address) = $bug_message =~ /^Received: \(at ([^\)]+)\) by/;
1128 my ($envelope_from) = $bug_message =~ s/\nFrom\s+([^\s]+)[^\n]+\n/\n/;
1129 if (not defined $envelope_from) {
1130 # Try to use the From: header or something to set it
1131 ($envelope_from) = $bug_message =~ /\nFrom:\s+(.+?)\n/;
1132 # Kludgy, and should really be using a full scale header
1133 # parser to do this.
1134 $envelope_from =~ s/^.+?<([^>]+)>.+$/$1/;
1136 my ($header,$body) = split /\n\n/, $bug_message, 2;
1137 # Add X-$gProject-PR-Message: list bug_number, package name, and bug title headers
1138 $header .= qq(\nX-$gProject-PR-Message: list $bug_number\n).
1139 qq(X-$gProject-PR-Package: $data->{package}\n).
1140 qq(X-$gProject-PR-Title: $data->{subject})
1142 print STDERR "Tried to loop me with $envelope_from\n"
1143 and exit 1 if $envelope_from =~ /\Q$gListDomain\E|\Q$gEmailDomain\E/;
1144 print DEBUG $envelope_from,qq(\n);
1145 # If we don't have a bug address, something has gone horribly wrong.
1146 print STDERR "Doesn't match: $bug_address\n" and exit 1 unless defined $bug_address;
1147 $bug_address =~ s/\@.+//;
1148 print DEBUG "Sending message to bugs=$bug_address\@$gListDomain\n";
1149 print DEBUG $header.qq(\n\n).$body;
1150 send_mail_message(message => $header.qq(\n\n).$body,
1151 recipients => ["bugs=$bug_address\@$gListDomain"],
1152 envelope_from => $envelope_from,
1153 encode_headers => 0,
1155 unlink("incoming/P$bug_fn") || &quit("unlinking incoming/P$bug_fn: $!");