2 # $Id: process.in,v 1.107 2005/10/19 01:22:14 don 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";
150 # Allow pseudo headers to set x-debbugs- stuff [#179340]
151 for my $key (grep /X-Debbugs-.*/i, keys %pheader) {
152 $header{$key} = $pheader{$key} if not exists $header{$key};
155 $fwd .= join("\n",@msg[$i..$#msg]);
157 print DEBUG "***\n$fwd\n***\n";
159 if (defined $header{'resent-from'} && !defined $header{'from'}) {
160 $header{'from'} = $header{'resent-from'};
162 defined($header{'from'}) || &quit("no From header");
164 $replyto = $header{'reply-to'};
165 $replyto = '' unless defined $replyto;
168 unless (length $replyto) {
169 $replyto = $header{'from'};
173 $_= "$2 <$1>" if m/^([^\<\> \t\n\(\)]+) \(([^\(\)\<\>]+)\)$/;
175 print DEBUG "replytocompare >$replytocompare<\n";
177 if (!defined($header{'subject'}))
181 Your message did not contain a Subject field. They are recommended and
182 useful because the title of a $gBug is determined using this field.
183 Please remember to include a Subject field in your messages in future.
186 # RFC822 actually lists it as an `optional-field'.
188 $subject= '(no subject)';
190 $subject= $header{'subject'};
194 $subject =~ s/^Re:\s*//i; $_= $subject."\n";
195 if ($tryref < 0 && m/^Bug ?\#(\d+)\D/i) {
201 ($bfound, $data)= &lockreadbugmerge($tryref);
205 &htmllog("Reply","sent", $replyto,"Unknown problem report number <code>$tryref</code>.");
206 my $archivenote = '';
208 $archivenote = <<END;
209 This may be because that $gBug report has been resolved for more than $gRemoveAge
210 days, and the record of it has been archived and made read-only, or
211 because you mistyped the $gBug report number.
215 &sendmessage(<<END, '');
216 From: $gMaintainerEmail ($gProject $gBug Tracking System)
218 Subject: Unknown problem report $gBug#$tryref ($subject)
219 Message-ID: <handler.x.$nn.unknown\@$gEmailDomain>
220 In-Reply-To: $header{'message-id'}
221 References: $header{'message-id'} $data->{msgid}
223 X-$gProject-PR-Message: error
225 You sent a message to the $gBug tracking system which gave (in the
226 Subject line or encoded into the recipient at $gEmailDomain),
227 the number of a nonexistent $gBug report (#$tryref).
229 ${archivenote}Your message was dated $header{'date'} and was sent to
230 $baddress\@$gEmailDomain. It had
231 Message-ID $header{'message-id'}
232 and Subject $subject.
234 It has been filed (under junk) but otherwise ignored.
236 Please consult your records to find the correct $gBug report number, or
237 contact me, the system administrator, for assistance.
240 (administrator, $gProject $gBugs database)
242 (NB: If you are a system administrator and have no idea what I am
243 talking about this indicates a serious mail system misconfiguration
244 somewhere. Please contact me immediately.)
251 &filelock('lock/-1');
254 if ($codeletter eq 'D' || $codeletter eq 'F')
256 if ($replyto =~ m/$gBounceFroms/o ||
257 $header{'from'} =~ m/$gBounceFroms/o)
259 &quit("bounce detected ! Mwaap! Mwaap!");
261 $markedby= $header{'from'} eq $replyto ? $replyto :
262 "$header{'from'} (reply to $replyto)";
263 if ($codeletter eq 'F') {
264 (&appendlog,&finish) if length($data->{forwarded});
265 $receivedat= "forwarded\@$gEmailDomain";
266 $markaswhat= 'forwarded';
267 $set_forwarded= $header{'to'};
268 if ( length( $gListDomain ) > 0 && length( $gForwardList ) > 0 ) {
269 $generalcc= "$gForwardList\@$gListDomain";
274 if (length($data->{done}) and
275 not defined $pheader{'source-version'} and
276 not defined $pheader{'version'}) {
280 $receivedat= "done\@$gEmailDomain";
282 $set_done= $header{'from'};
283 if ( length( $gListDomain ) > 0 && length( $gDoneList ) > 0 ) {
284 $generalcc= "$gDoneList\@$gListDomain";
289 if (defined $gStrongList and isstrongseverity($data->{severity})) {
290 $generalcc = join ', ', $generalcc, "$gStrongList\@$gListDomain";
293 &htmllog("Warning","sent",$replyto,"Message ignored.");
294 &sendmessage(<<END, '');
295 From: $gMaintainerEmail ($gProject $gBug Tracking System)
297 Subject: Message with no $gBug number ignored by $receivedat
299 Message-ID: <header.x.$nn.warnignore\@$gEmailDomain>
300 In-Reply-To: $header{'message-id'}
301 References: $header{'message-id'} $data->{msgid}
303 X-$gProject-PR-Message: error
305 You sent a message to the $gProject $gBug tracking system old-style
306 unified mark as $markaswhat address ($receivedat),
307 without a recognisable $gBug number in the Subject.
308 Your message has been filed under junk but otherwise ignored.
310 If you don't know what I'm talking about then probably either:
312 (a) you unwittingly sent a message to done\@$gEmailDomain
313 because you replied to all recipients of the message a developer used
314 to mark a $gBug as done and you modified the Subject. In this case,
315 please do not be alarmed. To avoid confusion do not do it again, but
316 there is no need to apologise or mail anyone asking for an explanation.
318 (b) you are a system administrator, reading this because the $gBug
319 tracking system is responding to a misdirected bounce message. In this
320 case there is a serious mail system misconfiguration somewhere - please
321 contact me immediately.
323 Your message was dated $header{'date'} and had
324 message-id $header{'message-id'}
325 and subject $subject.
327 If you need any assistance or explanation please contact me.
330 (administrator, $gProject $gBugs database)
339 $noticeccval.= join(', ', grep($_ ne $replyto,@maintaddrs));
340 $noticeccval =~ s/\s+\n\s+/ /g;
341 $noticeccval =~ s/^\s+/ /; $noticeccval =~ s/\s+$//;
342 if (length($noticeccval)) { $noticecc= "Cc: $noticeccval\n"; }
344 @process= ($ref,split(/ /,$data->{mergedwith}));
347 for $ref (@process) {
348 if ($ref != $orgref) {
350 $data = &lockreadbug($ref)
351 || die "huh ? $ref from $orgref out of @process";
353 $data->{done}= $set_done if defined($set_done);
354 $data->{forwarded}= $set_forwarded if defined($set_forwarded);
355 if ($codeletter eq 'D') {
356 $data->{keywords} = join ' ', grep $_ ne 'pending',
357 split ' ', $data->{keywords};
358 if (defined $pheader{'source-version'}) {
359 addfixedversions($data, $pheader{source}, $pheader{'source-version'}, '');
360 } elsif (defined $pheader{version}) {
361 addfixedversions($data, $pheader{package}, $pheader{version}, 'binary');
365 # Add bug mailing list to $generalbcc as appropriate
366 my $generalbcc = join(', ', $generalcc, @addsrcaddrs,"bugs=$ref\@$gListDomain");
367 $generalbcc =~ s/\s+\n\s+/ /g;
368 $generalbcc =~ s/^\s+/ /; $generalbcc =~ s/\s+$//;
369 if (length $generalbcc) {$generalbcc = "Bcc: $generalbcc\n"};
371 writebug($ref, $data);
373 my $hash = get_hashname($ref);
374 open(O,"db-h/$hash/$ref.report") || &quit("read original report: $!");
375 $x= join('',<O>); close(O);
376 if ($codeletter eq 'F') {
377 &htmllog("Reply","sent",$replyto,"You have marked $gBug as forwarded.");
378 &sendmessage(<<END."---------------------------------------\n".join( "\n", @msg ), '');
379 From: $gMaintainerEmail ($gProject $gBug Tracking System)
381 ${noticecc}${generalbcc}Subject: $gBug#$ref: marked as forwarded ($data->{subject})
382 Message-ID: <header.$ref.$nn.ackfwdd\@$gEmailDomain>
383 In-Reply-To: $header{'message-id'}
384 References: $header{'message-id'} $data->{msgid}
386 X-$gProject-PR-Message: forwarded $ref
387 X-$gProject-PR-Package: $data->{package}
388 X-$gProject-PR-Keywords: $data->{keywords}
390 Your message dated $header{'date'}
391 with message-id $header{'message-id'}
392 has caused the $gProject $gBug report #$ref,
393 regarding $data->{subject}
394 to be marked as having been forwarded to the upstream software
395 author(s) $data->{forwarded}.
397 (NB: If you are a system administrator and have no idea what I am
398 talking about this indicates a serious mail system misconfiguration
399 somewhere. Please contact me immediately.)
402 (administrator, $gProject $gBugs database)
407 &htmllog("Reply","sent",$replyto,"You have taken responsibility.");
408 &sendmessage(<<END."--------------------------------------\n".$x."---------------------------------------\n".join( "\n", @msg ), '');
409 From: $gMaintainerEmail ($gProject $gBug Tracking System)
411 ${noticecc}${generalbcc}Subject: $gBug#$ref: marked as done ($data->{subject})
412 Message-ID: <handler.$ref.$nn.ackdone\@$gEmailDomain>
413 In-Reply-To: $header{'message-id'}
414 References: $header{'message-id'} $data->{msgid}
416 X-$gProject-PR-Message: closed $ref
417 X-$gProject-PR-Package: $data->{package}
418 X-$gProject-PR-Keywords: $data->{keywords}
420 Your message dated $header{'date'}
421 with message-id $header{'message-id'}
422 and subject line $subject
423 has caused the attached $gBug report to be marked as done.
425 This means that you claim that the problem has been dealt with.
426 If this is not the case it is now your responsibility to reopen the
427 $gBug report if necessary, and/or fix the problem forthwith.
429 (NB: If you are a system administrator and have no idea what I am
430 talking about this indicates a serious mail system misconfiguration
431 somewhere. Please contact me immediately.)
434 (administrator, $gProject $gBugs database)
437 &htmllog("Notification","sent",$data->{originator},
438 "$gBug acknowledged by developer.");
439 &sendmessage(<<END.join("\n",@msg),'');
440 From: $gMaintainerEmail ($gProject $gBug Tracking System)
441 To: $data->{originator}
442 Subject: $gBug#$ref acknowledged by developer
444 Message-ID: <handler.$ref.$nn.notifdone\@$gEmailDomain>
445 In-Reply-To: $data->{msgid}
446 References: $header{'message-id'} $data->{msgid}
447 X-$gProject-PR-Message: they-closed $ref
448 X-$gProject-PR-Package: $data->{package}
449 X-$gProject-PR-Keywords: $data->{keywords}
450 Reply-To: $ref\@$gEmailDomain
452 This is an automatic notification regarding your $gBug report
453 #$ref: $data->{subject},
454 which was filed against the $data->{package} package.
456 It has been closed by one of the developers, namely
459 Their explanation is attached below. If this explanation is
460 unsatisfactory and you have not received a better one in a separate
461 message then please contact the developer, by replying to this email.
464 (administrator, $gProject $gBugs database)
474 if ($codeletter eq 'U') {
475 &htmllog("Warning","sent",$replyto,"Message not forwarded.");
476 &sendmessage(<<END, '');
477 From: $gMaintainerEmail ($gProject $gBug Tracking System)
479 Subject: Message with no $gBug number cannot be sent to submitter !
481 Message-ID: <handler.x.$nn.nonumnosub\@$gEmailDomain>
482 In-Reply-To: $header{'message-id'}
483 References: $header{'message-id'} $data->{msgid}
485 X-$gProject-PR-Message: error
487 You sent a message to the $gProject $gBug tracking system's $gBug
488 report submitter address $baddress\@$gEmailDomain, without a
489 recognisable $gBug number in the Subject. Your message has been filed
490 under junk but otherwise ignored.
492 If you don't know what I'm talking about then probably either:
494 (a) you unwittingly sent a message to $baddress\@$gEmailDomain
495 because you replied to all recipients of the message a developer sent
496 to a $gBug\'s submitter and you modified the Subject. In this case,
497 please do not be alarmed. To avoid confusion do not do it again, but
498 there is no need to apologise or mail anyone asking for an
501 (b) you are a system administrator, reading this because the $gBug
502 tracking system is responding to a misdirected bounce message. In this
503 case there is a serious mail system misconfiguration somewhere - please
504 contact me immediately.
506 Your message was dated $header{'date'} and had
507 message-id $header{'message-id'}
508 and subject $subject.
510 If you need any assistance or explanation please contact me.
513 (administrator, $gProject $gBugs database)
520 $data->{found_versions} = [];
521 $data->{fixed_versions} = [];
523 if (defined $pheader{source}) {
524 $data->{package} = $pheader{source};
525 } elsif (defined $pheader{package}) {
526 $data->{package} = $pheader{package};
528 &htmllog("Warning","sent",$replyto,"Message not forwarded.");
529 &sendmessage(<<END."---------------------------------------------------------------------------\n".join("\n", @msg), '');
530 From: $gMaintainerEmail ($gProject $gBug Tracking System)
532 Subject: Message with no Package: tag cannot be processed!
534 Message-ID: <handler.x.$nn.nonumnosub\@$gEmailDomain>
535 In-Reply-To: $header{'message-id'}
536 References: $header{'message-id'} $data->{msgid}
538 X-$gProject-PR-Message: error
540 Your message didn't have a Package: line at the start (in the
541 pseudo-header following the real mail header), or didn't have a
542 pseudo-header at all. Your message has been filed under junk but
545 This makes it much harder for us to categorise and deal with your
546 problem report. Please _resubmit_ your report to $baddress\@$gEmailDomain
547 and tell us which package the report is on. For help, check out
548 http://$gWebDomain/Reporting$gHTMLSuffix.
550 Your message was dated $header{'date'} and had
551 message-id $header{'message-id'}
552 and subject $subject.
553 The complete text of it is attached to this message.
555 If you need any assistance or explanation please contact me.
558 (administrator, $gProject $gBugs database)
565 $data->{keywords}= '';
566 if (defined($pheader{'keywords'})) {
567 $data->{keywords}= $pheader{'keywords'};
568 } elsif (defined($pheader{'tags'})) {
569 $data->{keywords}= $pheader{'tags'};
571 if (length($data->{keywords})) {
573 my %gkws = map { ($_, 1) } @gTags;
574 foreach my $kw (sort split(/[,\s]+/, lc($data->{keywords}))) {
575 push @kws, $kw if (defined $gkws{$kw});
577 $data->{keywords} = join(" ", @kws);
579 $data->{severity}= '';
580 if (defined($pheader{'severity'}) || defined($pheader{'priority'})) {
581 $data->{severity}= $pheader{'severity'};
582 $data->{severity}= $pheader{'priority'} unless ($data->{severity});
583 $data->{severity} =~ s/^\s*(.+)\s*$/$1/;
585 if (!grep($_ eq $data->{severity}, @severities, "$gDefaultSeverity")) {
588 Your message specified a Severity: in the pseudo-header, but
589 the severity value $data->{severity} was not recognised.
590 The default severity $gDefaultSeverity is being used instead.
591 The recognised values are: $gShowSeverities.
593 # if we use @gSeverityList array in the above line, perl -c gives:
594 # In string, @gSeverityList now must be written as \@gSeverityList at
595 # process line 452, near "$gDefaultSeverity is being used instead.
596 $data->{severity}= '';
599 if (defined($pheader{owner})) {
600 $data->{owner}= $pheader{owner};
602 if (defined($pheader{forwarded})) {
603 $data->{'forwarded-to'} = $pheader{forwarded};
605 &filelock("nextnumber.lock");
606 open(N,"nextnumber") || &quit("nextnumber: read: $!");
607 $v=<N>; $v =~ s/\n$// || &quit("nextnumber bad format");
608 $ref= $v+0; $v += 1; $newref=1;
609 &overwrite('nextnumber', "$v\n");
611 my $hash = get_hashname($ref);
612 &overwrite("db-h/$hash/$ref.log",'');
613 $data->{originator} = $replyto;
614 $data->{date} = $intdate;
615 $data->{subject} = $subject;
616 $data->{msgid} = $header{'message-id'};
617 writebug($ref, $data);
618 &overwrite("db-h/$hash/$ref.report",
619 join("\n",@msg)."\n");
624 print DEBUG "maintainers >@maintaddrs<\n";
626 $orgsender= defined($header{'sender'}) ? "Original-Sender: $header{'sender'}\n" : '';
627 $newsubject= $subject; $newsubject =~ s/^$gBug#$ref:*\s*//;
629 $xcchdr= $header{ 'x-debbugs-cc' };
630 if ($xcchdr =~ m/\S/) {
631 push(@resentccs,$xcchdr);
632 $resentccexplain.= <<END;
634 As you requested using X-Debbugs-CC, your message was also forwarded to
636 (after having been given a $gBug report number, if it did not have one).
640 if (@maintaddrs && ($codeletter eq 'B' || $codeletter eq 'M')) {
641 push(@resentccs,@maintaddrs);
642 $resentccexplain.= <<END." ".join("\n ",@maintaddrs)."\n";
644 Your message has been sent to the package maintainer(s):
648 @bccs = @addsrcaddrs;
649 if (defined $gStrongList and isstrongseverity($data->{severity})) {
650 push @bccs, "$gStrongList\@$gListDomain";
653 # Send mail to the per bug list subscription too
654 push @bccs, "bugs=$ref\@$gListDomain";
656 if (defined $pheader{source}) {
657 # Prefix source versions with the name of the source package. They
658 # appear that way in version trees so that we can deal with binary
659 # packages moving from one source package to another.
660 if (defined $pheader{'source-version'}) {
661 addfoundversions($data, $pheader{source}, $pheader{'source-version'}, '');
662 } elsif (defined $pheader{version}) {
663 addfoundversions($data, $pheader{source}, $pheader{version}, '');
665 writebug($ref, $data);
666 } elsif (defined $pheader{package}) {
667 # TODO: could handle Source-Version: by looking up the source package?
668 addfoundversions($data, $pheader{package}, $pheader{version}, 'binary');
669 writebug($ref, $data);
672 $veryquiet= $codeletter eq 'Q';
673 if ($codeletter eq 'M' && !@maintaddrs) {
677 You requested that the message be sent to the package maintainer(s)
678 but either the $gBug report is not associated with any package (probably
679 because of a missing Package pseudo-header field in the original $gBug
680 report), or the package(s) specified do not have any maintainer(s).
682 Your message has *not* been sent to any package maintainers; it has
683 merely been filed in the $gBug tracking system. If you require assistance
684 please contact $gMaintainerEmail quoting the $gBug number $ref.
688 $resentccval.= join(', ',@resentccs);
689 $resentccval =~ s/\s+\n\s+/ /g; $resentccval =~ s/^\s+/ /; $resentccval =~ s/\s+$//;
690 if (length($resentccval)) {
691 $resentcc= "Resent-CC: $resentccval\n";
694 if ($codeletter eq 'U') {
695 &htmllog("Message", "sent on", $data->{originator}, "$gBug#$ref.");
696 &sendmessage(<<END,[$data->{originator},@resentccs],[@bccs]);
697 Subject: $gBug#$ref: $newsubject
698 Reply-To: $replyto, $ref-quiet\@$gEmailDomain
699 ${orgsender}Resent-To: $data->{originator}
700 ${resentcc}Resent-Date: $tdate
701 Resent-Message-ID: <handler.$ref.$nn\@$gEmailDomain>
702 Resent-Sender: $gMaintainerEmail
703 X-$gProject-PR-Message: report $ref
704 X-$gProject-PR-Package: $data->{package}
705 X-$gProject-PR-Keywords: $data->{keywords}
708 } elsif ($codeletter eq 'B') {
709 &htmllog($newref ? "Report" : "Information", "forwarded",
710 join(', ',"$gSubmitList\@$gListDomain",@resentccs),
711 "<code>$gBug#$ref</code>".
712 (length($data->{package})? "; Package <code>".&sani($data->{package})."</code>" : '').
714 &sendmessage(<<END,["$gSubmitList\@$gListDomain",@resentccs],[@bccs]);
715 Subject: $gBug#$ref: $newsubject
716 Reply-To: $replyto, $ref\@$gEmailDomain
717 Resent-From: $header{'from'}
718 ${orgsender}Resent-To: $gSubmitList\@$gListDomain
719 ${resentcc}Resent-Date: $tdate
720 Resent-Message-ID: <handler.$ref.$nn\@$gEmailDomain>
721 Resent-Sender: $gMaintainerEmail
722 X-$gProject-PR-Message: report $ref
723 X-$gProject-PR-Package: $data->{package}
724 X-$gProject-PR-Keywords: $data->{keywords}
727 } elsif (@resentccs or @bccs) {
728 # D and F done far earlier; B just done - so this must be M or Q
729 # We preserve whichever it was in the Reply-To (possibly adding
732 &htmllog($newref ? "Report" : "Information", "forwarded",
734 "<code>$gBug#$ref</code>".
735 (length($data->{package}) ? "; Package <code>".&sani($data->{package})."</code>" : '').
738 &htmllog($newref ? "Report" : "Information", "stored",
740 "<code>$gBug#$ref</code>".
741 (length($data->{package}) ? "; Package <code>".&sani($data->{package})."</code>" : '').
744 &sendmessage(<<END,[@resentccs],[@bccs]);
745 Subject: $gBug#$ref: $newsubject
746 Reply-To: $replyto, $ref-$baddressroot\@$gEmailDomain
747 Resent-From: $header{'from'}
748 ${orgsender}Resent-To: $resentccval
750 Resent-Message-ID: <handler.$ref.$nn\@$gEmailDomain>
751 Resent-Sender: $gMaintainerEmail
752 X-$gProject-PR-Message: report $ref
753 X-$gProject-PR-Package: $data->{package}
754 X-$gProject-PR-Keywords: $data->{keywords}
759 $htmlbreak= length($brokenness) ? "<p>\n".&sani($brokenness)."\n<p>\n" : '';
760 $htmlbreak =~ s/\n\n/\n<P>\n\n/g;
761 if (length($resentccval)) {
762 $htmlbreak = " Copy sent to <code>".&sani($resentccval)."</code>.".
765 unless (exists $header{'x-debbugs-no-ack'}) {
767 &htmllog("Acknowledgement","sent",$replyto,
769 "New $gBug report received and filed, but not forwarded." :
770 "New $gBug report received and forwarded."). $htmlbreak);
771 &sendmessage($veryquiet ? <<END : $codeletter eq 'M' ? <<END : <<END,'');
772 From: $gMaintainerEmail ($gProject $gBug Tracking System)
774 Subject: $gBug#$ref: Acknowledgement of QUIET report
776 Message-ID: <handler.$ref.$nn.ackquiet\@$gEmailDomain>
777 In-Reply-To: $header{'message-id'}
778 References: $header{'message-id'}
780 X-$gProject-PR-Message: ack-quiet $ref
781 X-$gProject-PR-Package: $data->{package}
782 X-$gProject-PR-Keywords: $data->{keywords}
783 Reply-To: $ref-quiet\@$gEmailDomain
785 Thank you for the problem report you have sent regarding $gProject.
786 This is an automatically generated reply, to let you know your message
787 has been received. It has not been forwarded to the package maintainers
788 or other interested parties; you should ensure that the developers are
789 aware of the problem you have entered into the system - preferably
790 quoting the $gBug reference number, #$ref.
792 If you wish to submit further information on your problem, please send it
793 to $ref-$baddressroot\@$gEmailDomain (and *not*
794 to $baddress\@$gEmailDomain).
796 Please do not reply to the address at the top of this message,
797 unless you wish to report a problem with the $gBug-tracking system.
800 (administrator, $gProject $gBugs database)
802 From: $gMaintainerEmail ($gProject $gBug Tracking System)
804 Subject: $gBug#$ref: Acknowledgement of maintainer-only report
806 Message-ID: <handler.$ref.$nn.ackmaint\@$gEmailDomain>
807 In-Reply-To: $header{'message-id'}
808 References: $header{'message-id'}
810 X-$gProject-PR-Message: ack-maintonly $ref
811 X-$gProject-PR-Package: $data->{package}
812 X-$gProject-PR-Keywords: $data->{keywords}
813 Reply-To: $ref-maintonly\@$gEmailDomain
815 Thank you for the problem report you have sent regarding $gProject.
816 This is an automatically generated reply, to let you know your message has
817 been received. It is being forwarded to the package maintainers (but not
818 other interested parties, as you requested) for their attention; they will
821 If you wish to submit further information on your problem, please send
822 it to $ref-$baddressroot\@$gEmailDomain (and *not*
823 to $baddress\@$gEmailDomain).
825 Please do not reply to the address at the top of this message,
826 unless you wish to report a problem with the $gBug-tracking system.
829 (administrator, $gProject $gBugs database)
831 From: $gMaintainerEmail ($gProject $gBug Tracking System)
833 Subject: $gBug#$ref: Acknowledgement ($subject)
834 Message-ID: <handler.$ref.$nn.ack\@$gEmailDomain>
835 In-Reply-To: $header{'message-id'}
836 References: $header{'message-id'}
838 X-$gProject-PR-Message: ack $ref
839 X-$gProject-PR-Package: $data->{package}
840 X-$gProject-PR-Keywords: $data->{keywords}
841 Reply-To: $ref\@$gEmailDomain
843 Thank you for the problem report you have sent regarding $gProject.
844 This is an automatically generated reply, to let you know your message has
845 been received. It is being forwarded to the package maintainers and other
846 interested parties for their attention; they will reply in due course.
848 If you wish to submit further information on your problem, please send
849 it to $ref\@$gEmailDomain (and *not* to
850 $baddress\@$gEmailDomain).
852 Please do not reply to the address at the top of this message,
853 unless you wish to report a problem with the $gBug-tracking system.
856 (administrator, $gProject $gBugs database)
858 } elsif ($codeletter ne 'U' and
859 $header{'precedence'} !~ /\b(?:bulk|junk|list)\b/) {
860 &htmllog("Acknowledgement","sent",$replyto,
861 ($veryquiet ? "Extra info received and filed, but not forwarded." :
862 $codeletter eq 'M' ? "Extra info received and forwarded to maintainer." :
863 "Extra info received and forwarded to list."). $htmlbreak);
864 &sendmessage($veryquiet ? <<END : $codeletter eq 'M' ? <<END : <<END,'');
865 From: $gMaintainerEmail ($gProject $gBug Tracking System)
867 Subject: $gBug#$ref: Info received and FILED only
869 Message-ID: <handler.$ref.$nn.ackinfoquiet\@$gEmailDomain>
870 In-Reply-To: $header{'message-id'}
871 References: $header{'message-id'}
873 X-$gProject-PR-Message: ack-info-quiet $ref
874 X-$gProject-PR-Package: $data->{package}
875 X-$gProject-PR-Keywords: $data->{keywords}
876 Reply-To: $ref-quiet\@$gEmailDomain
878 Thank you for the additional information you have supplied regarding
879 this problem report. It has NOT been forwarded to the package
880 maintainers, but will accompany the original report in the $gBug
881 tracking system. Please ensure that you yourself have sent a copy of
882 the additional information to any relevant developers or mailing lists.
884 If you wish to continue to submit further information on your problem,
885 please send it to $ref-$baddressroot\@$gEmailDomain, as before.
887 Please do not reply to the address at the top of this message,
888 unless you wish to report a problem with the $gBug-tracking system.
891 (administrator, $gProject $gBugs database)
893 From: $gMaintainerEmail ($gProject $gBug Tracking System)
895 Subject: $gBug#$ref: Info received for maintainer only
897 Message-ID: <handler.$ref.$nn.ackinfomaint\@$gEmailDomain>
898 In-Reply-To: $header{'message-id'}
899 References: $header{'message-id'}
901 X-$gProject-PR-Message: ack-info-maintonly $ref
902 X-$gProject-PR-Package: $data->{package}
903 X-$gProject-PR-Keywords: $data->{keywords}
904 Reply-To: $ref-maintonly\@$gEmailDomain
906 Thank you for the additional information you have supplied regarding
907 this problem report. It has been forwarded to the package maintainer(s)
908 (but not to other interested parties) to accompany the original report.
910 If you wish to continue to submit further information on your problem,
911 please send it to $ref-$baddressroot\@$gEmailDomain, as before.
913 Please do not reply to the address at the top of this message,
914 unless you wish to report a problem with the $gBug-tracking system.
917 (administrator, $gProject $gBugs database)
919 From: $gMaintainerEmail ($gProject $gBug Tracking System)
921 Subject: $gBug#$ref: Info received (was $subject)
922 Message-ID: <handler.$ref.$nn.ackinfo\@$gEmailDomain>
923 In-Reply-To: $header{'message-id'}
924 References: $header{'message-id'}
926 X-$gProject-PR-Message: ack-info $ref
927 X-$gProject-PR-Package: $data->{package}
928 X-$gProject-PR-Keywords: $data->{keywords}
930 Thank you for the additional information you have supplied regarding
931 this problem report. It has been forwarded to the package maintainer(s)
932 and to other interested parties to accompany the original report.
934 If you wish to continue to submit further information on your problem,
935 please send it to $ref\@$gEmailDomain, as before.
937 Please do not reply to the address at the top of this message,
938 unless you wish to report a problem with the $gBug-tracking system.
941 (administrator, $gProject $gBugs database)
943 # Reply-To: in previous ack disabled by doogie due to mail loops.
944 # Are these still a concern?
945 # Reply-To: $ref\@$gEmailDomain
954 open(NEW,">$f.new") || &quit("$f.new: create: $!");
955 print(NEW "$v") || &quit("$f.new: write: $!");
956 close(NEW) || &quit("$f.new: close: $!");
957 rename("$f.new","$f") || &quit("rename $f.new to $f: $!");
961 my $hash = get_hashname($ref);
962 if (!open(AP,">>db-h/$hash/$ref.log")) {
963 print DEBUG "failed open log<\n";
964 print DEBUG "failed open log err $!<\n";
965 &quit("opening db-h/$hash/$ref.log (li): $!");
967 print(AP "\7\n",@{escapelog(@log)},"\n\3\n") || &quit("writing db-h/$hash/$ref.log (li): $!");
968 close(AP) || &quit("closing db-h/$hash/$ref.log (li): $!");
972 utime(time,time,"db");
974 while ($u= $cleanups[$#cleanups]) { &$u; }
975 unlink("incoming/P$nn") || &quit("unlinking incoming/P$nn: $!");
979 &quit("wot no exit");
981 sub chldhandle { $chldexit = 'yes'; }
984 local ($whatobj,$whatverb,$where,$desc) = @_;
985 my $hash = get_hashname($ref);
986 open(AP,">>db-h/$hash/$ref.log") || &quit("opening db-h/$hash/$ref.log (lh): $!");
989 "<strong>$whatobj $whatverb</strong>".
990 ($where eq '' ? "" : " to <code>".&sani($where)."</code>").
992 "\n\3\n") || &quit("writing db-h/$hash/$ref.log (lh): $!");
993 close(AP) || &quit("closing db-h/$hash/$ref.log (lh): $!");
1000 while ($msg =~ s/(.*\n)//) {
1007 # strip continuation lines too
1021 local ($msg,$recips,$bcc) = @_;
1022 if ((!ref($recips) && $recips eq '') || @$recips == 0) {
1025 $msg = "X-Loop: $gMaintainerEmail\n" . $msg;
1026 # The original message received is written out in appendlog, so
1027 # before writing out the other messages we've sent out, we need to
1028 # RFC1522 encode the header.
1029 $msg = encode_headers($msg);
1031 my $hash = get_hashname($ref);
1032 #save email to the log
1033 open(AP,">>db-h/$hash/$ref.log") || &quit("opening db-h/$hash/$ref.log (lo): $!");
1034 print(AP "\2\n",join("\4",@$recips),"\n\5\n",
1035 @{escapelog(stripbccs($msg))},"\n\3\n") ||
1036 &quit("writing db-h/$hash/$ref.log (lo): $!");
1037 close(AP) || &quit("closing db-h/$hash/$ref.log (lo): $!");
1040 shift @$recips if $recips->[0] eq '-t';
1041 push @$recips, @$bcc;
1044 send_mail_message(message => $msg,
1045 # Because we encode the headers above, we do not want to encode them here
1046 encode_headers => 0,
1047 recipients => $recips);
1050 sub checkmaintainers {
1051 return if $maintainerschecked++;
1052 return if !length($data->{package});
1053 open(MAINT,"$gMaintainerFile") || die &quit("maintainers open: $!");
1057 m/^(\S+)\s+(\S.*\S)\s*\n$/ || &quit("maintainers bogus \`$_'");
1058 $a= $1; $b= $2; $a =~ y/A-Z/a-z/;
1059 $maintainerof{$1}= $2;
1062 open(MAINT,"$gMaintainerFileOverride") || die &quit("maintainers.override open: $!");
1066 m/^(\S+)\s+(\S.*\S)\s*\n$/ || &quit("maintainers.override bogus \`$_'");
1067 $a= $1; $b= $2; $a =~ y/A-Z/a-z/;
1068 $maintainerof{$1}= $2;
1071 open(SOURCES,"$gPackageSource") || &quit("pkgsrc open: $!");
1073 next unless m/^(\S+)\s+\S+\s+(\S.*\S)\s*$/;
1079 $anymaintfound=0; $anymaintnotfound=0;
1080 for $p (split(m/[ \t?,():]+/,$data->{package})) {
1082 $p =~ /([a-z0-9.+-]+)/;
1084 next unless defined $p;
1085 if (defined $gSubscriptionDomain) {
1086 if (defined($pkgsrc{$p})) {
1087 push @addsrcaddrs, "$pkgsrc{$p}\@$gSubscriptionDomain";
1089 push @addsrcaddrs, "$p\@$gSubscriptionDomain";
1092 if (defined($maintainerof{$p})) {
1093 print DEBUG "maintainer add >$p|$maintainerof{$p}<\n";
1094 $addmaint= $maintainerof{$p};
1095 push(@maintaddrs,$addmaint) unless
1096 $addmaint eq $replyto || grep($_ eq $addmaint, @maintaddrs);
1099 print DEBUG "maintainer none >$p<\n";
1100 push(@maintaddrs,$gUnknownMaintainerEmail) unless $anymaintnotfound;
1101 $anymaintnotfound++;
1106 if (length $data->{owner}) {
1107 print DEBUG "owner add >$data->{package}|$data->{owner}<\n";
1108 $addmaint = $data->{owner};
1109 push(@maintaddrs, $addmaint) unless
1110 $addmaint eq $replyto or grep($_ eq $addmaint, @maintaddrs);
1114 =head2 bug_list_forward
1116 bug_list_forward($spool_filename) if $codeletter eq 'L';
1119 Given the spool file, will forward a bug to the per bug mailing list
1120 subscription system.
1124 sub bug_list_forward{
1126 # Read the bug information and package information for passing to
1128 my ($bug_number) = $bug_fn =~ /^L(\d+)\./;
1129 my ($bfound, $data)= lockreadbugmerge($bug_number);
1130 my $bug_fh = new IO::File "incoming/P$bug_fn" or die "Unable to open incoming/P$bug_fn $!";
1133 my $bug_message = <$bug_fh>;
1134 my ($bug_address) = $bug_message =~ /^Received: \(at ([^\)]+)\) by/;
1135 my ($envelope_from) = $bug_message =~ s/\nFrom\s+([^\s]+)[^\n]+\n/\n/;
1136 if (not defined $envelope_from) {
1137 # Try to use the From: header or something to set it
1138 ($envelope_from) = $bug_message =~ /\nFrom:\s+(.+?)\n/;
1139 # Kludgy, and should really be using a full scale header
1140 # parser to do this.
1141 $envelope_from =~ s/^.+?<([^>]+)>.+$/$1/;
1143 my ($header,$body) = split /\n\n/, $bug_message, 2;
1144 # Add X-$gProject-PR-Message: list bug_number, package name, and bug title headers
1145 $header .= qq(\nX-$gProject-PR-Message: list $bug_number\n).
1146 qq(X-$gProject-PR-Package: $data->{package}\n).
1147 qq(X-$gProject-PR-Title: $data->{subject})
1149 print STDERR "Tried to loop me with $envelope_from\n"
1150 and exit 1 if $envelope_from =~ /\Q$gListDomain\E|\Q$gEmailDomain\E/;
1151 print DEBUG $envelope_from,qq(\n);
1152 # If we don't have a bug address, something has gone horribly wrong.
1153 print STDERR "Doesn't match: $bug_address\n" and exit 1 unless defined $bug_address;
1154 $bug_address =~ s/\@.+//;
1155 print DEBUG "Sending message to bugs=$bug_address\@$gListDomain\n";
1156 print DEBUG $header.qq(\n\n).$body;
1157 send_mail_message(message => $header.qq(\n\n).$body,
1158 recipients => ["bugs=$bug_address\@$gListDomain"],
1159 envelope_from => $envelope_from,
1160 encode_headers => 0,
1162 unlink("incoming/P$bug_fn") || &quit("unlinking incoming/P$bug_fn: $!");