]> git.donarmstrong.com Git - debbugs.git/blobdiff - cgi/bugreport.cgi
[project @ 2003-05-03 20:42:15 by doogie]
[debbugs.git] / cgi / bugreport.cgi
index 78050d1fac7c062311c53e76bcf038c648c37960..8f55221c136e7c92f016e86c47212e8881cd2db5 100755 (executable)
@@ -7,6 +7,7 @@ use POSIX qw(strftime tzset);
 use MIME::Parser;
 use MIME::Decoder;
 use IO::Scalar;
+use IO::Lines;
 
 #require '/usr/lib/debbugs/errorlib';
 require './common.pl';
@@ -14,27 +15,41 @@ require './common.pl';
 require '/etc/debbugs/config';
 require '/etc/debbugs/text';
 
-use vars(qw($gHTMLTail $gWebDomain));
+use vars(qw($gEmailDomain $gHTMLTail $gSpoolDir $gWebDomain));
 
 my %param = readparse();
 
 my $tail_html;
 
-my %maintainer = %{getmaintainers()};
-my %pkgsrc = %{getpkgsrc()};
-
-my $ref = $param{'bug'} || quit("No bug number");
+my $ref = $param{'bug'} || quitcgi("No bug number");
+$ref =~ /(\d+)/ or quitcgi("Invalid bug number");
+$ref = $1;
+my $short = "#$ref";
 my $msg = $param{'msg'} || "";
-my $att = $param{'att'} || "0";
+my $att = $param{'att'};
 my $boring = ($param{'boring'} || 'no') eq 'yes'; 
+my $terse = ($param{'terse'} || 'no') eq 'yes';
 my $reverse = ($param{'reverse'} || 'no') eq 'yes';
 my $mbox = ($param{'mbox'} || 'no') eq 'yes'; 
 
-my %status = %{getbugstatus($ref)} or &quit("Couldn't get bug status: $!");
+my $buglog = buglog($ref);
+
+if ($ENV{REQUEST_METHOD} eq 'HEAD' and not defined($att) and not $mbox) {
+    print "Content-Type: text/html\n";
+    my @stat = stat $buglog;
+    if (@stat) {
+       my $mtime = strftime '%a, %d %b %Y %T GMT', gmtime($stat[9]);
+       print "Last-Modified: $mtime\n";
+    }
+    print "\n";
+    exit 0;
+}
+
+my %maintainer = %{getmaintainers()};
+my %pkgsrc = %{getpkgsrc()};
 
 my $indexentry;
 my $descriptivehead;
-my $submitted;
 my $showseverity;
 
 my $tpack;
@@ -47,10 +62,27 @@ my $dtime = strftime "%a, %e %b %Y %T UTC", localtime;
 $tail_html = $debbugs::gHTMLTail;
 $tail_html =~ s/SUBSTITUTE_DTIME/$dtime/;
 
+my %status = %{getbugstatus($ref)};
+unless (%status) {
+    print <<EOF;
+Content-Type: text/html
+
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+<head><title>$debbugs::gProject $debbugs::gBug report logs - $short</title></head>
+<body>
+<h1>$debbugs::gProject $debbugs::gBug report logs - $short</h1>
+<p>There is no record of $debbugs::gBug $short.
+Try the <a href="http://$gWebDomain/">search page</a> instead.</p>
+$tail_html</body></html>
+EOF
+    exit 0;
+}
+
 $|=1;
 
 $tpack = lc $status{'package'};
-$tpack =~ s/[^-+._a-z0-9()].*$//;
+my @tpacks = splitpackages($tpack);
 
 if  ($status{severity} eq 'normal') {
        $showseverity = '';
@@ -60,47 +92,57 @@ if  ($status{severity} eq 'normal') {
        $showseverity = "Severity: <em>$status{severity}</em>;\n";
 }
 
-$indexentry .= $showseverity;
-$indexentry .= "Package: <A HREF=\"" . pkgurl($status{package}) . "\">"
-           .htmlsanit($status{package})."</A>;\n";
+$indexentry .= "<p>$showseverity";
+$indexentry .= htmlpackagelinks($status{package}, 0);
 
 $indexentry .= "Reported by: <a href=\"" . submitterurl($status{originator})
-              . "\">" . htmlsanit($status{originator}) . "</a>";
-$indexentry .= ";\nTags: <strong>"
+              . "\">" . htmlsanit($status{originator}) . "</a>;\n";
+
+my $dummy = strftime "%a, %e %b %Y %T UTC", localtime($status{date});
+$indexentry .= "Date: ".$dummy.";\n<br>";
+
+my @descstates;
+
+push @descstates, "Tags: <strong>"
                . htmlsanit(join(", ", sort(split(/\s+/, $status{tags}))))
                . "</strong>"
                        if length($status{tags});
 
 my @merged= split(/ /,$status{mergedwith});
 if (@merged) {
-       my $mseparator= ";\nmerged with ";
+       my $descmerged = 'merged with ';
+       my $mseparator = '';
        for my $m (@merged) {
-               $indexentry .= $mseparator."<A href=\"" . bugurl($m) . "\">#$m</A>";
+               $descmerged .= $mseparator."<a href=\"" . bugurl($m) . "\">#$m</a>";
                $mseparator= ",\n";
        }
+       push @descstates, $descmerged;
 }
 
-my $dummy = strftime "%a, %e %b %Y %T UTC", localtime($status{date});
-$submitted = ";\ndated ".$dummy;
-
 if (length($status{done})) {
-       $indexentry .= ";\n<strong>Done:</strong> ".htmlsanit($status{done});
+       push @descstates, "<strong>Done:</strong> ".htmlsanit($status{done});
 } elsif (length($status{forwarded})) {
-       $indexentry .= ";\n<strong>Forwarded</strong> to ".htmlsanit($status{forwarded});
+       push @descstates, "<strong>Forwarded</strong> to ".maybelink($status{forwarded});
 }
 
-my ($short, $tmaint, $tsrc);
-$short = $ref; $short =~ s/^\d+/#$&/;
-$tmaint = defined($maintainer{$tpack}) ? $maintainer{$tpack} : '(unknown)';
-$tsrc = defined($pkgsrc{$tpack}) ? $pkgsrc{$tpack} : '(unknown)';
-$descriptivehead= $indexentry.$submitted.";\nMaintainer for $status{package} is\n".
-            '<A href="http://'.$debbugs::gWebDomain.'/db/ma/l'.&maintencoded($tmaint).'.html">'.htmlsanit($tmaint).'</A>';
-$descriptivehead.= ";\n<br>Source for $status{package} is\n".
-           '<A href="'.srcurl($tsrc)."\">$tsrc</A>";
-$descriptivehead.= ".";
+$indexentry .= join(";\n", @descstates) . ";\n<br>" if @descstates;
 
-my $buglog = buglog($ref);
-open L, "<$buglog" or &quit("open log for $ref: $!");
+$descriptivehead = $indexentry;
+foreach my $pkg (@tpacks) {
+    my $tmaint = defined($maintainer{$pkg}) ? $maintainer{$pkg} : '(unknown)';
+    my $tsrc = defined($pkgsrc{$pkg}) ? $pkgsrc{$pkg} : '(unknown)';
+
+    $descriptivehead .= "Maintainer for $pkg is\n".
+            '<a href="'.mainturl($tmaint).'">'.htmlsanit($tmaint).'</a>';
+    $descriptivehead .= ";\nSource for $pkg is\n".
+            '<a href="'.srcurl($tsrc)."\">$tsrc</a>" if ($tsrc ne "(unknown)");
+    $descriptivehead .= ".\n<br>";
+}
+
+open L, "<$buglog" or &quitcgi("open log for $ref: $!");
+if ($buglog !~ m#^\Q$gSpoolDir/db-h/#) {
+    $descriptivehead .= "\n<p>Bug is <strong>archived</strong>. No further changes may be made.</p>";
+}
 
 my $log='';
 
@@ -114,7 +156,7 @@ my $cmsg = 1;
 
 my $normstate= 'kill-init';
 my $linenum = 0;
-my $mail = '';
+my @mail = ();
 my @mails = ();
 while(my $line = <L>) {
        $linenum++;
@@ -136,13 +178,14 @@ while(my $line = <L>) {
                    || m/^(kill-init|kill-end) (incoming-recv|autocheck|recips|html)$/
                    || m/^kill-body go$/)
                {
-                       &quit("$ref: Transition from $normstate to $newstate at $linenum disallowed");
+                       &quitcgi("$ref: Transition from $normstate to $newstate at $linenum disallowed");
                }
 
-               if ($newstate eq 'go') {
-                       $this .= "<pre>\n";
-               }
+#$this .= "\n<br>states: $normstate $newstate<br>\n";
 
+#              if ($newstate eq 'go') {
+#                      $this .= "<pre>\n";
+#              }
                if ($newstate eq 'html') {
                        $this = '';
                }
@@ -155,18 +198,18 @@ while(my $line = <L>) {
 
                        $show = ($xmessage == $msg) if ($msg);
 
-                       push @mails, $mail if ( $mbox && $mail );
+                       push @mails, join( '', @mail ) if ( $mbox && @mail );
                        if ($show) {
                                my $downloadHtml = '';
-                               if ($mail) {
+                               if (@mail) {
                                        my $parser = new MIME::Parser;
                                        $parser->tmp_to_core(1);
                                        $parser->output_to_core(1);
 #                                      $parser->output_under("/tmp");
-                                       my $entity = $parser->parse_data($mail);
+                                       my $entity = $parser->parse( new IO::Lines \@mail );
                                        # TODO: make local subdir, clean it outselves
                                        # the following does NOT delete the msg dirs in /tmp
-                                       END { $entity->purge; $parser->filer->purge; }
+                                       END { if ( $entity ) { $entity->purge; } if ( $parser ) { $parser->filer->purge; } }
                                        my @attachments = ();
                                        if ( $entity->is_multipart ) {
                                                my @parts = $entity->parts_DFS;
@@ -186,7 +229,7 @@ while(my $line = <L>) {
                                                                push @attachments, $_;
                                                                my $file = $_->head->recommended_filename;
                                                                $downloadHtml .= "View Attachment: <a href=\"".dlurl($ref,"msg=$xmessage","att=$#attachments","filename=$file")."\">$file</a>\n";
-                                                               if ($msg && $att eq $#attachments) {
+                                                               if ($msg && defined($att) && $att eq $#attachments) {
                                                                        my $head = $_->head;
                                                                        my $type;
                                                                        chomp($type = $head->mime_attr("content-type"));
@@ -211,18 +254,22 @@ while(my $line = <L>) {
                                        $this .= htmlsanit($entity->stringify);
                                }
                                $this = "$downloadHtml\n$this$downloadHtml" if $downloadHtml;
-                               $downloadHtml = '';
-                               $this = "<pre>\n$this</pre>\n"
-                                       if $normstate eq 'go' || $normstate eq 'go-nox';
-                               $this = "$thisheader$this" if $thisheader && !( $normstate eq 'html' );;
-                               $thisheader = '';
+#                              if ($normstate eq 'go' || $normstate eq 'go-nox') {
+                               if ($normstate ne 'html') {
+                                       $this = "<pre>\n$this</pre>\n";
+                               }
                                if ($normstate eq 'html') {
-                                       $this .= "  <em><A href=\"" . bugurl($ref, "msg=$xmessage") . "\">Full text</A> available.</em>";
+                                       $this .= "  <em><a href=\"" . bugurl($ref, "msg=$xmessage") . "\">Full text</a> available.</em>";
                                }
+                               $this = "$thisheader$this" if $thisheader && !( $normstate eq 'html' );;
+                               $this = "$downloadHtml" if ($terse && $normstate ne 'html');
+                               $downloadHtml = '';
+                               $thisheader = '';
+                               my $delim = $terse ? "<p>" : "<hr>";
                                if ($reverse) {
-                                       $log = "$this\n<hr>$log";
+                                       $log = "$this\n$delim$log";
                                } else {
-                                       $log .= "$this\n<hr>\n";
+                                       $log .= "$this\n$delim\n";
                                }
                        }
 
@@ -232,7 +279,7 @@ while(my $line = <L>) {
                }
                
                $normstate = $newstate;
-               $mail = '';
+               @mail = ();
                next;
        }
 
@@ -241,48 +288,51 @@ while(my $line = <L>) {
                my $pl= $_;
                $pl =~ s/\n+$//;
                m/^Received: \(at (\S+)\) by (\S+)\;/
-                       || &quit("bad line \`$pl' in state incoming-recv");
+                       || &quitcgi("bad line \`$pl' in state incoming-recv");
                $thisheader = "<h2>Message received at ".htmlsanit("$1\@$2")
-                       . ":</h2><br>\n";
+                       . ":</h2>\n";
                $this = '';
                $normstate= 'go';
-               $mail .= $_;
+               push @mail, $_;
        } elsif ($normstate eq 'html') {
                $this .= $_;
        } elsif ($normstate eq 'go') {
-               if ($mail) {
-                       $mail .= $_;
+               s/^\030//;
+               if (@mail) {
+                       push @mail, $_;
                } else {
                        $this .= htmlsanit($_);
                }
        } elsif ($normstate eq 'go-nox') {
                next if !s/^X//;
-               if ($mail) {
-                       $mail .= $_;
+               if (@mail) {
+                       push @mail, $_;
                } else {
                        $this .= htmlsanit($_);
                }
         } elsif ($normstate eq 'recips') {
                if (m/^-t$/) {
-                       $this = "<h2>Message sent:</h2><br>\n";
+                       $thisheader = "<h2>Message sent:</h2>\n";
                } else {
                        s/\04/, /g; s/\n$//;
-                       $this = "<h2>Message sent to ".htmlsanit($_).":</h2><br>\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';
-               $this = "<h2>Message received at $2:</h2><br>\n";
+               $thisheader = "<h2>Message received at $2:</h2>\n";
+               $this = '';
+               push @mail, $_;
        } elsif ($normstate eq 'autowait') {
                next if !m/^$/;
                $normstate= 'go-nox';
-               $this .= "<pre>\n";
        } else {
-               &quit("$ref state $normstate line \`$_'");
+               &quitcgi("$ref state $normstate line \`$_'");
        }
 }
-&quit("$ref state $normstate at end") unless $normstate eq 'kill-end';
+&quitcgi("$ref state $normstate at end") unless $normstate eq 'kill-end';
 close(L);
 
 if ( $mbox ) {
@@ -293,14 +343,13 @@ if ( $mbox ) {
                        my $tmp = $lines[ 0 ];
                        $lines[ 0 ] = $lines[ 1 ];
                        $lines[ 1 ] = $tmp;
-                       $_ = join( "\n", @lines ) . "\n";
                }
                if ( !( $lines[ 0 ] =~ m/^From / ) ) {
-                       $ENV{ PATH } = "/bin:/usr/bin:/usr/local/bin";
-                       my $date = `date "+%a %b %d %T %Y"`;
-                       chomp $date;
-                       $_ = "From unknown $date\n" . $_;
+                       my $date = strftime "%a %b %d %T %Y", localtime;
+                       unshift @lines, "From unknown $date";
                }
+               map { s/^(>*From )/>$1/ } @lines[ 1 .. $#lines ];
+               $_ = join( "\n", @lines ) . "\n";
        }
        print join("", @mails );
        exit 0;
@@ -313,11 +362,11 @@ print "<HTML><HEAD>\n" .
     "</HEAD>\n" .
     '<BODY TEXT="#000000" BGCOLOR="#FFFFFF" LINK="#0000FF" VLINK="#800080">' .
     "\n";
-print "<H1>" .  "$debbugs::gProject $debbugs::gBug report logs - <A HREF=\"mailto:$ref\@bugs.debian.org\">$short</A>" .
+print "<H1>" .  "$debbugs::gProject $debbugs::gBug report logs - <A HREF=\"mailto:$ref\@$gEmailDomain\">$short</A>" .
       "<BR>" . htmlsanit($status{subject}) . "</H1>\n";
 
 print "$descriptivehead\n";
-printf "<p><a href=\"%s\">View</a> this report as an mbox folder.</p>", mboxurl($ref);
+printf "<p>View this report as an <a href=\"%s\">mbox folder</a>.</p>\n", mboxurl($ref);
 print "<HR>";
 print "$log";
 print $tail_html;