) {
+ $linenum++;
+ if ($line =~ m/^.$/ and 1 <= ord($line) && ord($line) <= 7) {
+ # state transitions
+ my $newstate;
+ my $statenum = ord($line);
+
+ $newstate = 'autocheck' if ($statenum == 1);
+ $newstate = 'recips' if ($statenum == 2);
+ $newstate = 'kill-end' if ($statenum == 3);
+ $newstate = 'go' if ($statenum == 5);
+ $newstate = 'html' if ($statenum == 6);
+ $newstate = 'incoming-recv' if ($statenum == 7);
+
+ # disallowed transitions:
+ $_ = "$normstate $newstate";
+ unless (m/^(go|go-nox|html) kill-end$/
+ || m/^(kill-init|kill-end) (incoming-recv|autocheck|recips|html)$/
+ || m/^kill-body go$/)
+ {
+ &quit("$ref: Transition from $normstate to $newstate at $linenum disallowed");
+ }
+
+ if ($newstate eq 'go') {
+ $this .= "\n";
+ }
+
+ if ($newstate eq 'html') {
+ $this = '';
+ }
+
+ if ($newstate eq 'kill-end') {
+
+ $this .= "
\n"
+ if $normstate eq 'go' || $normstate eq 'go-nox';
+
+ if ($normstate eq 'html') {
+ $this .= " Full text available.";
+ }
+
+ my $show = 1;
+ $show = $boring
+ if ($suppressnext && $normstate ne 'html');
+
+ $show = ($xmessage == $msg) if ($msg);
+
+ if ($show) {
+ if ($reverse) {
+ $log = "$this\n
$log";
+ } else {
+ $log .= "$this\n
\n";
+ }
+ }
+
+ $xmessage++ if ($normstate ne 'html');
+
+ $suppressnext = $normstate eq 'html';
+ }
+
+ $normstate = $newstate;
+ next;
+ }
+
+ $_ = $line;
+ if ($normstate eq 'incoming-recv') {
+ my $pl= $_;
+ $pl =~ s/\n+$//;
+ m/^Received: \(at (\S+)\) by (\S+)\;/
+ || &quit("bad line \`$pl' in state incoming-recv");
+ $this = "Message received at ".&sani("$1\@$2")
+ . ":
\n\n$_";
+ $normstate= 'go';
+ } elsif ($normstate eq 'html') {
+ $this .= $_;
+ } elsif ($normstate eq 'go') {
+ $this .= &sani($_);
+ } elsif ($normstate eq 'go-nox') {
+ next if !s/^X//;
+ $this .= &sani($_);
+ } elsif ($normstate eq 'recips') {
+ if (m/^-t$/) {
+ $this = "Message sent:
\n";
+ } else {
+ s/\04/, /g; s/\n$//;
+ $this = "Message sent to ".&sani($_).":
\n";
+ }
+ $normstate= 'kill-body';
+ } elsif ($normstate eq 'autocheck') {
+ next if !m/^X-Debian-Bugs(-\w+)?: This is an autoforward from (\S+)/;
+ $normstate= 'autowait';
+ $this = "Message received at $2:
\n";
+ } elsif ($normstate eq 'autowait') {
+ next if !m/^$/;
+ $normstate= 'go-nox';
+ $this .= "\n";
+ } else {
+ &quit("$ref state $normstate line \`$_'");
+ }
+}
+&quit("$ref state $normstate at end") unless $normstate eq 'kill-end';
+close(L);
+
+print header;
+print start_html("$debbugs::gProject $debbugs::gBug report logs - $short");
+
+print h1("$debbugs::gProject $debbugs::gBug report logs - $short
\n"
+ . sani($status{subject}));
+
+print "$descriptivehead\n";
+print hr;
+print "$log";
+print $tail_html;
+
+print end_html;
+
+sub maintencoded {
+ return "";
+}
+
+exit 0;
diff --git a/cgi/common.pl b/cgi/common.pl
new file mode 100644
index 00000000..aaf00ae9
--- /dev/null
+++ b/cgi/common.pl
@@ -0,0 +1,181 @@
+#!/usr/bin/perl -w
+
+sub quit {
+ my $msg = shift;
+ print header . start_html("Error");
+ print "An error occurred. Dammit.\n";
+ print "Error was: $msg.\n";
+ print end_html;
+ exit 0;
+}
+
+sub htmlindexentry {
+ my $ref = shift;
+
+ my %status = getbugstatus($ref);
+ my $result = "";
+
+ if ($status{severity} eq 'normal') {
+ $showseverity = '';
+ } elsif (grep($status{severity} eq $_, @debbugs::gStrongSeverities)) {
+ $showseverity = "Severity: $status{severity};\n";
+ } else {
+ $showseverity = "Severity: $status{severity};\n";
+ }
+
+ $result .= "Package: "
+ . htmlsanit($status{package}) . ";\n"
+ if (length($status{package}));
+ $result .= $showseverity;
+ $result .= "Reported by: " . htmlsanit($status{originator});
+ $result .= ";\nKeywords: " . htmlsanit($status{keywords})
+ if (length($status{keywords}));
+
+ my @merged= split(/ /,$status{mergedwith});
+ if (@merged) {
+ my $mseparator= ";\nmerged with ";
+ for my $m (@merged) {
+ $result .= $mseparator."#$m";
+ $mseparator= ", ";
+ }
+ }
+
+ if (length($status{done})) {
+ $result .= ";\nDone: " . htmlsanit($status{done});
+ } elsif (length($status{forwarded})) {
+ $result .= ";\nForwarded to "
+ . htmlsanit($status{forwarded});
+ } else {
+ my $daysold = int((time - $status{date}) / 86400); # seconds to days
+ if ($daysold >= 7) {
+ my $font = "";
+ my $efont = "";
+ $font = "em" if ($daysold > 30);
+ $font = "strong" if ($daysold > 60);
+ $efont = "$font>" if ($font);
+ $font = "<$font>" if ($font);
+
+ my $yearsold = int($daysold / 364);
+ $daysold = $daysold - $yearsold * 364;
+
+ $result .= ";\n $font";
+ $result .= "1 year and " if ($yearsold == 1);
+ $result .= "$yearsold years and " if ($yearsold > 1);
+ $result .= "1 day old" if ($daysold == 1);
+ $result .= "$daysold days old" if ($daysold != 1);
+ $result .= "$efont";
+ }
+ }
+
+ $result .= ".";
+
+ return $result;
+}
+
+sub pkgurl {
+ my $ref = shift;
+ my $params = "pkg=$ref";
+ foreach my $val (@_) { 1 }
+
+ return $debbugs::gCGIDomain . "pkgreport.cgi" . "?" . "$params";
+}
+
+%saniarray= ('<','lt', '>','gt', '&','amp', '"','quot');
+
+sub htmlsanit {
+ my $in = shift;
+ my $out;
+ while ($in =~ m/[<>&"]/) {
+ $out.= $`. '&'. $saniarray{$&}. ';';
+ $in=$';
+ }
+ $out .= $in;
+ return $out;
+}
+
+sub bugurl {
+ my $ref = shift;
+ my $params = "bug=$ref";
+ foreach my $val (@_) {
+ $params .= "\&msg=$1" if ($val =~ /^msg=([0-9]+)$/);
+ }
+
+ return $debbugs::gCGIDomain . "bugreport.cgi" . "?" . "$params";
+}
+
+sub packageurl {
+ my $ref = shift;
+ return $debbugs::gCGIDomain . "package.cgi" . "?" . "package=$ref";
+}
+
+sub allbugs {
+ my @bugs = ();
+
+ opendir(D, $debbugs::gSpoolDir/db) || &quit("opendir db: $!");
+ @bugs = sort { $a <=> $b }
+ grep s/\.status$//,
+ (grep m/^[0-9]+\.status$/,
+ (readdir(D)));
+ closedir(D);
+
+ return @bugs;
+}
+
+sub pkgbugs {
+ my $pkg = shift;
+ my @bugs = ();
+ open I, "<$gAJIndex" || &quit("bugindex: $!");
+ while() {
+ push @bugs, $1 if (/^([0-9]+) $pkg$/);
+ }
+ @bugs = sort { $a <=> $b } @bugs;
+ return @bugs;
+}
+
+sub getmaintainers {
+ my %maintainer;
+
+ open(MM,"$gMaintainerFile") || &quit("open $gMaintainerFile: $!");
+ while() {
+ m/^(\S+)\s+(\S.*\S)\s*$/ || &quit("$gMaintainerFile: \`$_'");
+ ($a,$b)=($1,$2);
+ $a =~ y/A-Z/a-z/;
+ $maintainer{$a}= $b;
+ }
+ close(MM);
+
+ return %maintainer;
+}
+
+sub getbugstatus {
+ my $bugnum = shift;
+
+ my %status;
+
+ open(S,"$gSpoolDir/db/$bugnum.status") || &quit("open $bugnum.status: $!");
+ my @lines = qw(originator date subject msgid package keywords done
+ forwarded mergedwith severity);
+ while() {
+ chomp;
+ $status{shift @lines} = $_;
+ }
+ close(S);
+ $status{shift @lines} = '' while(@lines);
+
+ $status{package} =~ s/\s*$//;
+ $status{package} = 'unknown' if ($status{package} eq '');
+ $status{severity} = 'normal' if ($status{severity} eq '');
+
+ $status{pending} = 'pending';
+ $status{pending} = 'forwarded' if (length($status{forwarded}));
+ $status{pending} = 'done' if (length($status{done}));
+
+ return %status;
+}
+
+sub buglog {
+ my $bugnum = shift;
+ return "$gSpoolDir/db/$bugnum.log";
+}
+
+1