- $_ = $line;
- if ($normstate eq 'incoming-recv') {
- my $pl= $_;
- $pl =~ s/\n+$//;
- m/^Received: \(at (\S+)\) by (\S+)\;/
- || &quitcgi("bad line \`$pl' in state incoming-recv");
- $thisheader = "<h2>Message received at ".htmlsanit("$1\@$2")
- . ":</h2>\n";
- $this = '';
- $normstate= 'go';
- push @mail, $_;
- } elsif ($normstate eq 'html') {
- $this .= $_;
- } elsif ($normstate eq 'go') {
- s/^\030//;
- if (!$suppressnext && !$found_msgid &&
- /^Message-ID: <(.*)>/i) {
- my $msgid = $1;
- $found_msgid = 1;
- if ($seen_msgid{$msgid}) {
- $suppressnext = 1;
- } else {
- $seen_msgid{$msgid} = 1;
- }
- }
- if (@mail) {
- push @mail, $_;
- } else {
- $this .= htmlsanit($_);
- }
- } elsif ($normstate eq 'go-nox') {
- next if !s/^X//;
- if (!$suppressnext && !$found_msgid &&
- /^Message-ID: <(.*)>/i) {
- my $msgid = $1;
- $found_msgid = 1;
- if ($seen_msgid{$msgid}) {
- $suppressnext = 1;
- } else {
- $seen_msgid{$msgid} = 1;
- }
- }
- if (@mail) {
- push @mail, $_;
- } else {
- $this .= htmlsanit($_);
- }
- } elsif ($normstate eq 'recips') {
- if (m/^-t$/) {
- $thisheader = "<h2>Message sent:</h2>\n";
- } else {
- s/\04/, /g; s/\n$//;
- $thisheader = "<h2>Message sent to ".htmlsanit($_).":</h2>\n";
- }
- $this = "";
- $normstate= 'kill-body';
- } elsif ($normstate eq 'autocheck') {
- next if !m/^X-Debian-Bugs(-\w+)?: This is an autoforward from (\S+)/;
- $normstate= 'autowait';
- $thisheader = "<h2>Message received at $2:</h2>\n";
- $this = '';
- push @mail, $_;
- } elsif ($normstate eq 'autowait') {
- next if !m/^$/;
- $normstate= 'go-nox';
- } else {
- &quitcgi("$ref state $normstate line \`$_'");
- }
+my $buglogfh;
+if ($buglog =~ m/\.gz$/) {
+ my $oldpath = $ENV{'PATH'};
+ $ENV{'PATH'} = '/bin:/usr/bin';
+ $buglogfh = new IO::File "zcat $buglog |" or &quitcgi("open log for $ref: $!");
+ $ENV{'PATH'} = $oldpath;
+} else {
+ $buglogfh = new IO::File "<$buglog" or &quitcgi("open log for $ref: $!");
+}
+
+
+my @records;
+eval{
+ @records = read_log_records($buglogfh);
+};
+if ($@) {
+ quitcgi("Bad bug log for $gBug $ref. Unable to read records: $@");
+}
+undef $buglogfh;
+
+=head2 handle_email_message
+
+ handle_email_message($record->{text},
+ ref => $bug_number,
+ msg_number => $msg_number,
+ );
+
+Returns a decoded e-mail message and displays entities/attachments as
+appropriate.
+
+
+=cut
+
+sub handle_email_message{
+ my ($email,%options) = @_;
+
+ my $output = '';
+ my $parser = new MIME::Parser;
+ # Because we are using memory, not tempfiles, there's no need to
+ # clean up here like in Debbugs::MIME
+ $parser->tmp_to_core(1);
+ $parser->output_to_core(1);
+ my $entity = $parser->parse_data( $email);
+ my @attachments = ();
+ display_entity($entity, $options{ref}, 1, $options{msg_number}, $output, @attachments);
+ return $output;
+
+}
+
+=head2 handle_record
+
+ push @log, handle_record($record,$ref,$msg_num);
+
+Deals with a record in a bug log as returned by
+L<Debbugs::Log::read_log_records>; returns the log information that
+should be output to the browser.
+
+=cut
+
+sub handle_record{
+ my ($record,$bug_number,$msg_number,$seen_msg_ids) = @_;
+
+ my $output = '';
+ local $_ = $record->{type};
+ if (/html/) {
+ my ($time) = $record->{text} =~ /<!--\s+time:(\d+)\s+-->/;
+ my $class = $record->{text} =~ /^<strong>(?:Acknowledgement|Reply|Information|Report|Notification)/ ? 'infmessage':'msgreceived';
+ $output .= decode_rfc1522($record->{text});
+ # Link to forwarded http:// urls in the midst of the report
+ # (even though these links already exist at the top)
+ $output =~ s,((?:ftp|http|https)://[\S~-]+?/?)([\)\'\:\.\,]?(?:\s|\.<|$)),<a href=\"$1\">$1</a>$2,go;
+ # Add links to the cloned bugs
+ $output =~ s{(Bug )(\d+)( cloned as bugs? )(\d+)(?:\-(\d+)|)}{$1.bug_links($2).$3.bug_links($4,$5)}eo;
+ # Add links to merged bugs
+ $output =~ s{(?<=Merged )([\d\s]+)(?=\.)}{join(' ',map {bug_links($_)} (split /\s+/, $1))}eo;
+ # Add links to blocked bugs
+ $output =~ s{(?<=Blocking bugs)(?:( of )(\d+))?( (?:added|set to|removed):\s+)([\d\s\,]+)}
+ {(defined $2?$1.bug_links($2):'').$3.
+ join(' ',map {bug_links($_)} (split /\,?\s+/, $4))}eo;
+ # Add links to reassigned packages
+ $output =~ s{(Bug reassigned from package \`)([^']+)((?:'|\&\#39;) to \`)([^']+)((?:'|\&\#39;))}
+ {$1.q(<a href=").pkg_url(pkg=>$2).qq(">$2</a>).$3.q(<a href=").pkg_url(pkg=>$4).qq(">$4</a>).$5}eo;
+ if (defined $time) {
+ $output .= ' ('.strftime('%a, %d %b %Y %T GMT',gmtime($time)).') ';
+ }
+ $output .= '<a href="' . bug_url($ref, msg => ($msg_number+1)) . '">Full text</a> and <a href="' .
+ bug_url($ref, msg => ($msg_number+1), mbox => 'yes') . '">rfc822 format</a> available.';
+
+ $output = qq(<div class="$class"><hr>\n<a name="$msg_number"></a>\n) . $output . "</div>\n";
+ }
+ elsif (/recips/) {
+ my ($msg_id) = $record->{text} =~ /^Message-Id:\s+<(.+)>/im;
+ if (defined $msg_id and exists $$seen_msg_ids{$msg_id}) {
+ return ();
+ }
+ elsif (defined $msg_id) {
+ $$seen_msg_ids{$msg_id} = 1;
+ }
+ $output .= qq(<hr><p class="msgreceived"><a name="$msg_number"></a>\n);
+ $output .= 'View this message in <a href="' . bug_url($ref, msg=>$msg_number, mbox=>'yes') . '">rfc822 format</a></p>';
+ $output .= handle_email_message($record->{text},
+ ref => $bug_number,
+ msg_number => $msg_number,
+ );
+ }
+ elsif (/autocheck/) {
+ # Do nothing
+ }
+ elsif (/incoming-recv/) {
+ my ($msg_id) = $record->{text} =~ /^Message-Id:\s+<(.+)>/im;
+ if (defined $msg_id and exists $$seen_msg_ids{$msg_id}) {
+ return ();
+ }
+ elsif (defined $msg_id) {
+ $$seen_msg_ids{$msg_id} = 1;
+ }
+ # Incomming Mail Message
+ my ($received,$hostname) = $record->{text} =~ m/Received: \(at (\S+)\) by (\S+)\;/;
+ $output .= qq|<hr><p class="msgreceived"><a name="$msg_number"></a><a name="msg$msg_number">Message received</a> at |.
+ html_escape("$received\@$hostname") . q| (<a href="| . bug_url($ref, msg=>$msg_number) . '">full text</a>'.q|, <a href="| . bug_url($ref, msg=>$msg_number,mbox=>'yes') .'">mbox</a>)'.":</p>\n";
+ $output .= handle_email_message($record->{text},
+ ref => $bug_number,
+ msg_number => $msg_number,
+ );
+ }
+ else {
+ die "Unknown record type $_";
+ }
+ return $output;