]> git.donarmstrong.com Git - bugscan.git/commitdiff
Initial import of official branch.
authorSteinar H. Gunderson <sesse@rietz>
Wed, 7 Mar 2007 11:38:57 +0000 (11:38 +0000)
committerSteinar H. Gunderson <sesse@rietz>
Wed, 7 Mar 2007 11:38:57 +0000 (11:38 +0000)
16 files changed:
Makefile [new file with mode: 0644]
bugcfg.pm [new file with mode: 0644]
bugcounts [new file with mode: 0755]
bugdiff [new file with mode: 0755]
bugreport [new file with mode: 0755]
bugscan [new file with mode: 0755]
cleancomments [new file with mode: 0755]
comments [new file with mode: 0644]
crontab [new file with mode: 0755]
dograph [new file with mode: 0755]
dohtml [new file with mode: 0755]
dopost [new file with mode: 0755]
dostatus [new file with mode: 0755]
makepost [new file with mode: 0755]
scanlib.pm [new file with mode: 0644]
z [new file with mode: 0755]

diff --git a/Makefile b/Makefile
new file mode 100644 (file)
index 0000000..ce8065f
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,17 @@
+
+html:
+       ./dohtml
+
+graph:
+       ./dograph
+
+post:
+       ./dopost
+
+status:
+       ./dostatus
+
+rescan:
+       ./crontab
+
+.PHONY: html graph post status rescan
diff --git a/bugcfg.pm b/bugcfg.pm
new file mode 100644 (file)
index 0000000..d8f1852
--- /dev/null
+++ b/bugcfg.pm
@@ -0,0 +1,34 @@
+#! /usr/bin/perl
+# vim: ts=4 sw=4 nowrap
+
+# General configuration stuff
+
+$host=`hostname`;
+chomp $host;
+if ($host eq "master" or $host eq "spohr" or $host eq 'rietz') {
+       $spooldir       = "/org/bugs.debian.org/debbugs/spool/db-h";
+       $maintainerlist = "/etc/debbugs/Maintainers";
+       $debian_ftproot = "/org/bugs.debian.org/etc/indices/ftp/testing";
+       $nonUS_ftproot  = "/org/bugs.debian.org/etc/indices/nonus/testing";
+       $debian_sources = "/etc/debbugs/indices/ftp.sources";
+       $nonUS_sources  = "/etc/debbugs/indices/nonus.sources";
+       $pseudolist     = "/org/bugs.debian.org/etc/pseudo-packages.description";
+       $nonuslist      = "/debian/home/maor/masterfiles/Packages.non-US";
+} elsif ($host eq "lightning") {
+       $spooldir       = "/debian/home/iwj/debian-bugs/spool/db";
+       $maintainerlist = "/debian/debian/indices/Maintainers";
+       $ftproot        = "/debian/debian/dists/potato/";
+       $pseudolist     = "/debian/home/maor/masterfiles/pseudo-packages.description";
+       $nonuslist      = "/debian/home/maor/masterfiles/Packages.non-US";
+} else {
+       die "Unknown machine, please configure paths in bugcfg.pm\n";
+}
+
+$btsURL                        = "http://www.debian.org/Bugs/";
+@architectures         = ( "i386", "m68k", "alpha", "sparc", "powerpc", "arm", "hppa", "ia64", "mips", "mipsel", "s390" );
+@sections              = ( "main", "contrib", "non-free" );
+@priorities            = ( "serious", "grave", "critical" );
+@skiptags              = ( "wontfix", "fixed" );
+
+1;
+
diff --git a/bugcounts b/bugcounts
new file mode 100755 (executable)
index 0000000..8792983
--- /dev/null
+++ b/bugcounts
@@ -0,0 +1,74 @@
+#! /usr/bin/perl
+# vim: ts=4 sw=4 nowrap
+
+# Generate some counts for the bugreports
+
+use Getopt::Std;
+require scanlib;
+require bugcfg;
+
+$Version               = "BugCount 1.1\nCopyright (C) Wichert Akkerman <wakkerma\@debian.org>\n";
+$statusfile            = "status";
+$commentsfile  = "comments";
+
+sub ShowVersion() {
+       print "$Version\n";
+       exit 0;
+}
+
+sub ShowUsage() {
+       print <<EOF;
+Usage:
+  $0 [-V] [-h] [-S file] [-C file]
+Options:
+  -V    show version
+  -h    show some (hopefully) helpfull information
+  -S    use different statusfile
+  -C    use different commentsfile
+EOF
+       exit 0;
+}
+
+getopts('VhS:C:');
+ShowUsage if ($opt_h);
+ShowVersion if ($opt_V);
+$statusfile=$opt_S if ($opt_S);
+$commentsfile=$opt_C if ($opt_C);
+
+&readstatus($statusfile);
+&readcomments($commentsfile);
+
+$total=0;                      # total number of bugs
+$removecount=0;                # Number of bugs that will disappear if packages are removed
+$patchcount=0;         # Number of bugs that have a fix proposed
+$pendingcount=0;       # Number of bugs that will have a fix uploaded RSN
+$ignorecount=0;         # Number of bugs being ignored
+$nottestingcount=0;    # Number of bugs on packages not in testing
+$worrycount=0;         # Number of bugs we're actually worried about
+%sectcount=();         # Bugs per type
+
+for $p (keys %packagelist) {
+       next if (defined $exclude{$p});
+       for $nr (sort split(/ /, $packagelist{$p})) {
+               next if (defined $exclude{$nr});
+               $total++;
+               $pendingcount++ if ($bugs{$nr} =~ m/^\[[^]]*P/);
+               $patchcount++ if ($bugs{$nr} =~ m/^\[[^]]*\+/);
+               $ignorecount++ if ($bugs{$nr} =~ m/^\[[^]]*I/);
+               $nottestingcount++ if ($bugs{$nr} =~ m/ \[[^]]*X/);
+               if (defined $comments{$nr}) {
+                       ($sect) = ($comments{$nr} =~ m/\[([^]]*)\]/);
+                       $sectcount{$sect}++;
+               }
+               $worrycount++ unless (
+                       $bugs{$nr} =~ m/^\[[^]]*I/ or
+                       $bugs{$nr} =~ m/ \[[^]]*X/ or
+                       ($bugs{$nr} =~ m/ \[[^]]*[OSUE]/ and $bugs{$nr} !~ m/ \[[^]]*T/));
+       }
+
+       if (defined($comments{$p}) && $comments{$p} =~ m/^\[REMOVE\]/) {
+               $removecount+=scalar(split(/ /,$packagelist{$p}));
+       }
+}
+
+printf("%d %d %d %d %d %d %d\n", $total, $pendingcount, $patchcount, $removecount, $ignorecount, $nottestingcount, $worrycount);
diff --git a/bugdiff b/bugdiff
new file mode 100755 (executable)
index 0000000..677877e
--- /dev/null
+++ b/bugdiff
@@ -0,0 +1,128 @@
+#!/usr/bin/perl
+# vim: ts=4 sw=4 nowrap
+
+# Compare two buglist status-files
+
+use Getopt::Std;
+require scanlib;
+require bugcfg;
+
+$Version               = "BugDiff 1.0\nCopyright (C) Wichert Akkerman <wakkerma\@debian.org>\n";
+$html                  = 0;
+
+
+sub ShowVersion() {
+       print "$Version\n";
+       exit 0;
+}
+
+sub ShowUsage() {
+       print <<EOF;
+Usage:
+  $0 [-V] [-h] [-H] <status1> <status2>
+Options:
+  -V    show version
+  -h    show some (hopefully) helpfull information
+  -H    produce HTML output
+  -n    list newly opened bugs
+  -c    list closed bugs
+  -s    show statistics
+EOF
+       exit 0;
+}
+
+sub closedbugs() {
+       if ($html) {
+               if (%removed) {
+                       print "<h2>Closed/downgraded release-critical bugs</h2>\n";
+                       print "<ul>\n";
+                       for $p (sort keys %removed) {
+                               print "  <li><em>" . &wwwname($p) . ":</em>\n";
+                               for $b (sort split(/ /, $removed{$p})) {
+                                       print &wwwnumber($b) . " ";
+                               }
+                               print "\n";
+                       }
+                       print "</ul>\n";
+               }
+       } else {
+               print "Closed/downgraded release-critical bugs:\n" if (%removed>0);
+               for $p (sort keys %removed) {
+                       print "   $p: ";
+                       print join(", ", sort split(/ /, $removed{$p}));
+                       print "\n";
+               }
+       }
+}
+
+
+sub openedbugs() {
+       if ($html) {
+               if (%new) {
+                       print "<h2>Opened/upgraded release-critical bugs</h2>\n";
+                       print "<ul>\n";
+                       for $p (sort keys %new) {
+                               print "  <li><em>" . &wwwname($p) . ":</em>\n";
+                               for $b (sort split(/ /, $new{$p})) {
+                                       print &wwwnumber($b) . " ";
+                               }
+                               print "\n";
+                       }
+                       print "</ul>\n";
+               }
+       } else {
+               print "Opened/upgraded release-critical bugs:\n" if (%new);
+               for $p (sort keys %new) {
+                       print "   $p: ";
+                       print join(", ", sort split(/ /, $new{$p}));
+                       print "\n";
+               }
+       }
+}
+
+sub statistics() {
+       if ($html) {
+               print "<STRONG>" . ($closed ? $closed : "NO") . "</STRONG> release-critical bugs were closed and ";
+               print "<STRONG>" . ($opened ? $opened : "NONE") . "</STRONG> were opened.<P>\n";
+       } else {
+               print "" . ($closed ? $closed : "NO") . " release-critical bugs were closed ";
+               print "and " . ($opened ? $opened : "NONE") . " were opened.\n\n";
+       }
+}
+
+getopts('VhHncs');
+ShowUsage if ($opt_h or ($#ARGV != 1));
+ShowVersion if ($opt_V);
+$html=1 if ($opt_H);
+
+&readstatus($ARGV[0]);
+%oldbugs=%packagelist;
+%packagelist=();
+
+&readstatus($ARGV[1]);
+
+$closed=0;
+for $p (keys %oldbugs) {
+       for $b (split(/ /, $oldbugs{$p})) {
+               if (not ($packagelist{$p} =~ m/\b$b\b/)) {
+                       $removed{$p} .= "$b ";
+                       $closed++;
+               }
+       }
+}
+
+$opened=0;
+for $p (keys %packagelist) {
+       for $b (split(/ /, $packagelist{$p})) {
+               if (not ($oldbugs{$p} =~ m/\b$b\b/)) {
+                       $new{$p} .= "$b ";
+                       $opened++;
+               }
+       }
+}
+
+statistics if ($opt_s);
+closedbugs if ($opt_c);
+openedbugs if ($opt_n);
+
+exit 0;
diff --git a/bugreport b/bugreport
new file mode 100755 (executable)
index 0000000..e06d3c9
--- /dev/null
+++ b/bugreport
@@ -0,0 +1,202 @@
+#!/usr/bin/perl
+# vim: ts=4 sw=4 nowrap
+
+# Generate a report of the release-critical bugs for packages
+
+use Getopt::Std;
+require scanlib;
+require bugcfg;
+
+$Version               = "BugReport 1.4\nCopyright (C) 1998-2002 Wichert Akkerman <wakkerma\@debian.org>\n";
+$html                  = 0;
+$statusfile            = "status";
+$commentsfile  = "comments";
+$NMUfile               = "/debian/home/doogie/public_html/incoming/bugs_closed";
+$NMUfile               = "/debian/home/doogie/chgscan/db/bugs_closed"; # Changed as of request by dark  -Joey, 99/11/22
+$NMUfile               = "http://auric.debian.org/~doogie/incoming/bugs_closed"; # Changed as of request by dark  -Joey, 99/11/22
+
+sub ShowVersion() {
+       print "$Version\n";
+       exit 0;
+}
+
+sub ShowUsage() {
+       print <<EOF;
+Usage:
+  $0 [-V] [-h] [-H] [-l] -[s] [-d distrib] [-S file] [-C file]
+Options:
+  -V    show version
+  -h    show some (hopefully) helpful information
+  -H    produce HTML output
+  -l    list all release-critical bugs
+  -s    list bug statistics
+  -d    only list these distributions (comma-separated)
+  -S    use different statusfile
+  -C    use different commentsfile
+EOF
+       exit 0;
+}
+
+sub PrintPackageHeader() {
+       local($p)       = shift;        # Package to print
+       local ($name, $email);  # Name & email of maintainer
+
+       if ($html) {
+               print "\n<a name=\"$p\"><strong>Package:</strong> " . &wwwname($p);
+               print " ($section{$p}).\n";
+               print "<strong>Maintainer:</strong> ";
+               if (defined($maintainer{$p})) {
+                       $_ = $maintainer{$p};
+                       ($name,$email) = m/(.*) <([^>]*)>/;
+                       print "$name &lt;<a href=\"http://bugs.debian.org/$email\">$email</A>&gt;\n";
+               } else {
+                       print "unknown\n";
+               }
+       } else {
+               print "\nPackage: $p ($section{$p})\n";
+               print "Maintainer: " . (defined($maintainer{$p}) ? $maintainer{$p} : "unknown") . "\n";
+       }
+}
+
+
+sub MakeBuglist() {
+       local ($p);                             # Index variable
+       local ($nr);                    # Current bugnumber
+       local ($sect);                  # BTS-subsection for bugnumber
+       local ($header);                # Flag if packagename has already been printed
+       local ($fontset);               # Did we change the font?
+
+       print "<pre>\n" if ($html);
+       for $p (sort {$a cmp $b} keys %packagelist) {
+               next if (defined $exclude{$p});
+               $header = 0;
+               $fontset = 0;
+               if (defined $comments{$p}) {
+                       if ($html && defined($comments{$p})) {
+                               if ($comments{$p} =~ m/^\[REMOVE\]/) {
+                                       $fontset=1;
+                                       print "<font color=red>";
+                               }
+                       }
+                       $header=1;
+                       &PrintPackageHeader($p);
+                       print $comments{$p};
+               }
+               for $nr (sort split(/ /, $packagelist{$p})) {
+                       next if (defined $exclude{$nr});
+                       if (! $header) {
+                               $header = 1;
+                               &PrintPackageHeader($p);
+                       }
+
+                       if ($html) {
+                               if ($bugs{$nr} =~ m/ \[[^]]*X/) {
+                                       print '<font color="#808080">';
+                               } elsif ($bugs{$nr} =~ m/^\[[^]]*P/) {
+                                       print '<font color="#f040d0">';
+                               } elsif ($bugs{$nr} =~ m/^\[[^]]*\+/) {
+                                       print '<font color="#00aa00">';
+                               } elsif ($bugs{$nr} =~ m/^\[[^]]*H/) {
+                                       print '<font color="#ffaa30">';
+                               }
+                               print "<strike>" if ($bugs{$nr} =~ m/^\[.......I\]/);
+                               ($sect=$nr) =~ s/([0-9]{2}).*/$1/;
+                               print "<A NAME=\"$nr\">  " . &wwwnumber($nr) . ' ' .
+                                         htmlsanit($bugs{$nr}) . "\n";
+                               print "</strike>" if ($bugs{$nr} =~ m/^\[.......I\]/);
+                       } else {
+                               printf("  %-6d %s\n", $nr, $bugs{$nr});
+                       }
+                       print $comments{$nr} if (defined($comments{$nr}));
+                       print "[FIX] Fixed by package " . $NMU{$nr, "source"} . ", version " . $NMU{$nr, "version"} . " in Incoming\n" if (defined $NMU{$nr});
+                       print "</font>" if ($html && ($bugs{$nr} =~ m/^\[[^]]*[H+P]/ ||
+                                                     $bugs{$nr} =~ m/ \[[^]]*X/));
+               }
+               print "</font>" if ($fontset);
+       }
+       print "</pre>\n" if ($html);
+}
+
+
+sub MakeStatistics() {
+       local($bugcount);               # Total number of bugs so far
+       local($count);                  # Number of bugs for this package
+       local($remtotal);               # Total number of bugs for packages marked REMOVE
+       local($patchtotal);             # Total number of bugs marked patch
+       local($pendingtotal);           # Total number of bugs marked pending
+       local($ignoretotal);            # Total number of bugs marked ignore
+       local($nottestingtotal);        # Total number of bugs on packages not in testing
+       local($worrytotal);             # Total number of bugs we're actually worried about
+       local($p);                              # Index variable
+       local(%list);                   # List of bugnumber associated with package
+
+       $bugcount=0;
+       for $p (sort keys %packagelist) {
+               next if (defined $exclude{$p});
+               $count=0;
+               for $nr (split(/ /, $packagelist{$p})) {
+                       $pendingtotal++ if ($bugs{$nr} =~ m/^\[[^]]*P/);
+                       $patchtotal++ if ($bugs{$nr} =~ m/^\[[^]]*\+/);
+                       $ignoretotal++ if ($bugs{$nr} =~ m/^\[[^]]*I/);
+                       $nottestingtotal++ if ($bugs{$nr} =~ m/ \[[^]]*X/);
+                       $worrytotal++ unless (
+                               $bugs{$nr} =~ m/^\[[^]]*I/ or
+                               $bugs{$nr} =~ m/ \[[^]]*X/ or
+                               ($bugs{$nr} =~ m/ \[[^]]*[OSUE]/ and $bugs{$nr} !~ m/ \[[^]]*T/));
+
+                       if (not defined($exclude{$nr})) {
+                               $bugcount++;
+                               $count++;
+                       } 
+               }
+               $remtotal+=$count if (defined($comments{$p}) && $comments{$p} =~ m/^\[REMOVE\]/);
+       }
+
+       if ($html) {
+               print "<strong>Total number of release-critical bugs:</strong> $bugcount<BR>\n";
+               printf("<strong>Number that will disappear after removing packages marked [REMOVE]:</strong> %d<BR>\n", $remtotal);
+               printf("<strong>Number that have a patch:</strong> %d<BR>\n", $patchtotal);
+               printf("<strong>Number that have a fix prepared and waiting to upload:</strong> %d<BR>\n", $pendingtotal);
+               printf("<strong>Number that are being ignored:</strong> %d<BR>\n", $ignoretotal);
+               printf("<strong>Number on packages not in testing:</strong> %d<BR>\n", $nottestingtotal);
+               printf("<strong>Number concerning the next release (excluding ignored and not-in-testing):</strong> %d<P>\n", $worrytotal);
+       } else {
+               print "Total number of release-critical bugs: $bugcount\n";
+               printf("Number that will disappear after removing packages marked [REMOVE]: %d\n", $remtotal);
+               printf("Number that have a patch: %d\n", $patchtotal);
+               printf("Number that have a fix prepared and waiting to upload: %d\n", $pendingtotal);
+               printf("Number that are being ignored: %d\n", $ignoretotal);
+               printf("Number on packages not in testing: %d\n", $nottestingtotal);
+               printf("Number concerning the next release (excluding ignored and not-in-testing): %d\n", $worrytotal);
+       }
+}
+
+
+sub FilterPackages() {
+       local($filter) = shift;         # Distribution we want to keep
+
+       for $p (sort keys %packagelist) {
+               delete $packagelist{$p} unless ($section{$p} =~ m/^$filter/);
+       }
+}
+
+getopts('VhHlsd:S:C:');
+ShowUsage if ($opt_h);
+ShowVersion if ($opt_V);
+$statusfile=$opt_S if ($opt_S);
+$commentsfile=$opt_C if ($opt_C);
+$html=1 if ($opt_H);
+
+&readstatus($statusfile);
+&readcomments($commentsfile);
+&readNMUstatus($NMUfile);
+
+&FilterPackages($opt_d) if ($opt_d);
+
+MakeStatistics if ($opt_s);
+if ($opt_l) {
+       MakeBuglist 
+}
+
+exit 0;
+
diff --git a/bugscan b/bugscan
new file mode 100755 (executable)
index 0000000..c6b0778
--- /dev/null
+++ b/bugscan
@@ -0,0 +1,35 @@
+#! /usr/bin/perl
+
+require bugcfg;
+require scanlib;
+
+# Main part
+
+&readpackages($debian_ftproot, "debian") if defined $debian_ftproot;
+&readpackages($nonUS_ftproot, "non-US")  if defined $nonUS_ftproot;
+&readsources($debian_ftproot, "debian")  if defined $debian_ftproot;
+&readsources($nonUS_ftproot, "non-US")   if defined $nonUS_ftproot;
+
+&readdebbugssources($debian_sources, "debian") if defined $debian_sources;
+&readdebbugssources($nonUS_sources, "non-US") if defined $nonUS_sources;
+
+
+&readpseudopackages;
+&readmaintainers;
+&scanspool;
+
+for $p (keys %packagelist) {
+       my $section;
+       if (exists $section{$p}) {
+           $section = $section{$p};
+       } else {
+           $section = $debbugssection{$p};
+       }
+       print "$p $section $maintainer{$p}";
+       for $b (split(/ /, $packagelist{$p})) {
+               print "$bugs{$b}\n";
+       }
+}
+
+exit 0;
+
diff --git a/cleancomments b/cleancomments
new file mode 100755 (executable)
index 0000000..b62e8ed
--- /dev/null
@@ -0,0 +1,60 @@
+#!/usr/bin/perl
+# vim: ts=4 sw=4 nowrap
+
+# Read a comments-file and output only the comments that are still relevant
+
+use Getopt::Std;
+require scanlib;
+require bugcfg;
+
+$Version               = "CommentClean 1.0\nCopyright (C) Wichert Akkerman <wakkerma\@debian.org>\n";
+$html                  = 0;
+$statusfile            = "status";
+$commentfile   = "comments";
+
+sub ShowVersion() {
+       print "$Version\n";
+       exit 0;
+}
+
+sub ShowUsage() {
+       print <<EOF;
+Usage:
+  $0 [-V] [-h] [-S file] [-C file]
+Options:
+  -V    show version
+  -h    show some (hopefully) helpfull information
+  -S    use different statusfile
+  -C    use different commentfile
+EOF
+       exit 0;
+}
+
+
+getopts('VhS:C:');
+ShowUsage if ($opt_h);
+ShowVersion if ($opt_V);
+$statusfile=$opt_S if ($opt_S);
+$commentfile=$opt_C if ($opt_C);
+
+&readstatus($statusfile);
+&readcomments($commentfile);
+
+for $p (keys %packagelist) {
+       for $nr (split(/ /, $packagelist{$p})) {
+               $found{$nr}=1;
+       }
+}
+
+for $n (sort keys %exclude) {
+       print "$n EXCLUDE\n\n"
+               if (defined($found{$n}) or defined ($packagelist{$n}));
+}
+
+for $n (sort keys %comments) {
+       print "$n\n$comments{$n}\n"
+               if (defined($found{$n}) or defined ($packagelist{$n}));
+}
+
+exit 0;
+
diff --git a/comments b/comments
new file mode 100644 (file)
index 0000000..fb82baf
--- /dev/null
+++ b/comments
@@ -0,0 +1,16 @@
+
+no-such-package
+[REMOVE]
+
+cl-imho
+[REMOVE]
+
+cl-uncommonsql
+[REMOVE]
+
+libapache-mod-webapp
+[REMOVE]
+
+onshore-timesheet
+[REMOVE]
+
diff --git a/crontab b/crontab
new file mode 100755 (executable)
index 0000000..40b9b59
--- /dev/null
+++ b/crontab
@@ -0,0 +1,32 @@
+#! /bin/sh
+
+set -e
+
+cd /org/bugs.debian.org/bugscan
+
+# Run script from doogie to check packages in Incoming
+# ../../doogie/chgscan/update -o quiet=yes
+
+time=`date +"%Y%m%d%H%M"`
+statusfile="stati/status-$time"
+countfile="counts/count-$time"
+
+if [ -f $statusfile ]; then
+       echo "Error: $statusfile already exists"
+       exit 1
+fi
+
+./bugscan > $statusfile
+
+rm -f status-old
+if [ -f status ]; then
+       mv -f status status-old
+fi
+
+ln -sf $statusfile status
+./bugcounts > $countfile
+ln -sf $countfile count
+
+./dohtml
+./dostatus
+./dograph
diff --git a/dograph b/dograph
new file mode 100755 (executable)
index 0000000..182cb85
--- /dev/null
+++ b/dograph
@@ -0,0 +1,37 @@
+#! /bin/sh
+
+set -e
+
+cd /org/bugs.debian.org/bugscan
+
+tmp=`tempfile`
+tmp2=`tempfile`
+
+find counts -type f | sort | xargs grep '^' /dev/null |
+    sed 's/^.*count-//;s/ .*$//;s/:/ /' >"$tmp"
+find counts -type f | sort | xargs egrep '^(.* ){6}' /dev/null |
+    sed 's/^.*count-//;s/:.* / /;' >"$tmp2"
+    
+
+#for i in counts/count-[0-9]* ; do
+#      date=`echo $i | sed -e s/.*count-//`
+#      count=`sed -e 's/ .*//' $i`
+#      echo $date $count >> ${tmp}2
+#done
+
+cat <<EOF | gnuplot
+set xdata time
+set timefmt "%Y%m%d%H%M"
+set format x "%m\n%Y"
+set title "Number of release-critical bugs"
+set nokey
+set terminal png
+set yrange [0:]
+#set xtics 2678400
+#set nomxtics
+set output "/org/bugs.debian.org/www/bugscan/graph.png"
+plot "$tmp" using 1:2 with lines, "$tmp2" using 1:2 with lines
+quit
+EOF
+
+rm "$tmp" "$tmp2"
diff --git a/dohtml b/dohtml
new file mode 100755 (executable)
index 0000000..19813e1
--- /dev/null
+++ b/dohtml
@@ -0,0 +1,188 @@
+#! /bin/sh
+
+htmldir=/org/bugs.debian.org/www/bugscan
+
+realmakepage() {
+       local   filter="$1"     # Distributions to list
+       local   title="$2"      # Title of page
+       local   date="$3"       # Date
+       local   descr           # Description of filter
+
+       if [ -z "$filter" ]; then
+               descr="all"
+       else
+               descr="$filter"
+               filter="-d $filter"
+       fi
+
+       cat <<EOF
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+  <head>
+    <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+    <title>$title, $date</title>
+  </head>
+<body bgcolor="white">
+<h1 align="center">$title</h1>
+
+<h2 align="center">$date</h2>
+
+<p align="center">for distribution(s): $descr</p>
+
+<hr>
+
+<p>Check out Steinar H. Gunderson's beta <a href="http://people.debian.org/~sesse/bugscan/">version-tracking aware release critical bug page</a>.
+
+<hr>
+
+<p>
+EOF
+       ./bugreport -H -s $filter
+       
+       cat <<EOF
+<p>
+Explanation for comment tags:
+<ul>
+   <li><strong>[FIX]</strong>: describes a simple method to deal with
+       the bug.
+   <li><strong>[STRATEGY]</strong>: describes a possible approach for
+       fixing the bug.
+   <li><strong>[HELP]</strong>: help is needed to fix this bug.
+   <li><strong>[REMOVE]</strong>: package will be removed if bug is not fixed
+</ul>
+
+<p>
+Explanation for <a href="http://www.debian.org/Bugs/Developer#tags">bug
+tags</a>:
+
+<ul>
+   <li><strong>P</strong>: pending</li>
+   <li><strong>+</strong>: patch</li>
+   <li><strong>H</strong>: help</li>
+   <li><strong>M</strong>: moreinfo</li>
+   <li><strong>R</strong>: unreproducible</li>
+   <li><strong>S</strong>: security</li>
+   <li><strong>U</strong>: upstream</li>
+   <li><strong>I</strong>: etch-ignore</li>
+</ul>
+
+<p>
+Some bugs have an additional set of tags indicating they only apply
+to a particular release: O for oldstable (woody), S for stable (sarge),
+T for testing (etch), U for unstable (sid) or E for experimental. X
+indicates that the package is not in testing.
+
+<p>
+
+EOF
+       ./bugreport -H -l $filter
+
+       cat <<EOF
+<hr>
+This page is automatically generated.<br>
+Please contact
+<a href="mailto:owner@bugs.debian.org">owner@bugs.debian.org</a> for comments.
+</body>
+</html>
+EOF
+}
+
+makemainpage() {
+       cat <<EOF
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+  <head>
+    <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+    <title>$title, $time</title>
+  </head>
+<body bgcolor="white">
+<h1 align="center">$title</h1>
+
+<h2 align="center">$time</h2>
+
+<p align="center">
+EOF
+
+       ./bugreport -Hs
+
+       cat <<EOF
+</p>
+
+<div align="center"><img src="graph.png" alt="Graph of RC bugs"></div>
+
+<p>The red line graphs all bugs with release-critical severities; the green
+line graphs the number of bugs that are actually a concern for the next
+release (excluding ignored bugs, bugs on packages not in testing, and bugs
+whose tags indicate that they don't apply to testing).</p>
+
+<h2>Recent changes</h2>
+EOF
+
+       ./bugdiff -Hncs status-old status
+
+       cat <<EOF
+
+<h2>Detailed lists of RC bug reports:</h2>
+
+<ul>
+  <li> <a href="debian/all.html">All</a>
+    <br>
+     + <a href="debian-non-US/all.html">All non-US</a>
+  <li> <a href="debian/main.html">main</a>
+    <br>
+     + <a href="debian-non-US/main.html">main non-US</a>
+  <li> <a href="debian/source.html">source</a> 
+    <br>
+     + <a href="debian-non-US/source.html">source non-US</a> 
+  <li> <a href="debian/contrib.html">contrib</a>
+    <br>
+     + <a href="debian-non-US/contrib.html">contrib non-US</a>
+  <li> <a href="debian/non-free.html">non-free</a>
+    <br>
+     + <a href="debian-non-US/non-free.html">non-free non-US</a>
+  <li><a href="other/pseudo.html">pseudo-packages</a>
+       <a href="http://www.debian.org/Bugs/pseudo-packages">(?)</a>
+  <li><a href="other/all.html">Everything in one page</a>
+</ul>
+<p clear=both>
+<hr>
+This page is automatically generated.<br>
+Please contact
+<a href="mailto:owner@bugs.debian.org">owner@bugs.debian.org</a> for comments.
+To receive all mails sent to release-critical bugs, subscribe to the
+<a href="http://lists.debian.org/debian-bugs-rc/">debian-bugs-rc</a>
+mailing list.
+
+EOF
+}
+
+makepage() {
+       if [ ! -d "`dirname $3`" ]; then mkdir -p "`dirname $3`"; fi
+       realmakepage "$1" "$2" "$4" > $3.new
+       mv -f $3.new $3
+}
+
+time=$(date -u --date="1970-1-1 00:00:00 UTC + $(stat -c %Y status) secs")
+oldtime=$(date -u --date="1970-1-1 00:00:00 UTC + $(stat -c %Y status-old) secs")
+title="Release-critical bugs status"
+
+
+makepage "debian" "$title" "$htmldir/debian/all.html" "$time"
+makepage "debian/main" "$title" $htmldir/debian/main.html "$time"
+makepage "debian/contrib" "$title" $htmldir/debian/contrib.html "$time"
+makepage "debian/non-free" "$title" $htmldir/debian/non-free.html "$time"
+makepage "debian/source" "$title" $htmldir/debian/source.html "$time"
+
+makepage "non-US" "$title" "$htmldir/debian-non-US/all.html" "$time"
+makepage "non-US/main" "$title" $htmldir/debian-non-US/main.html "$time"
+makepage "non-US/contrib" "$title" $htmldir/debian-non-US/contrib.html "$time"
+makepage "non-US/non-free" "$title" $htmldir/debian-non-US/non-free.html "$time"
+makepage "non-US/source" "$title" $htmldir/debian-non-US/source.html "$time"
+
+makepage "other/pseudo" "$title" $htmldir/other/pseudo.html "$time"
+
+makepage "" "$title" $htmldir/other/all.html "$time"
+
+makemainpage > $htmldir/index.html.new
+mv -f $htmldir/index.html.new $htmldir/index.html
+
diff --git a/dopost b/dopost
new file mode 100755 (executable)
index 0000000..51345fa
--- /dev/null
+++ b/dopost
@@ -0,0 +1,27 @@
+#! /bin/sh
+
+cd /org/bugs.debian.org/bugscan
+
+rm pstatus-old
+mv pstatus pstatus-old
+now=`ls -al status | sed -e 's/.*-\([0-9]*\)/\1/'`
+ln -s stati/status-$now pstatus
+
+./makepost > posts/post-$now
+
+cat <<EOF >> posts/post-$now
+-- 
+This post is automatically generated on a regular basis.
+Up-to-date information available at http://bugs.debian.org/release-critical/
+Please send comments to bugscan@debian.org
+EOF
+
+cat posts/post-$now | \
+       mutt \
+               -e "my_hdr Reply-To: debian-devel@lists.debian.org,bugscan\@debian.org" \
+               -e "my_hdr From: BugScan reporter <bugscan\@debian.org>" \
+                -e "set send_charset='us-ascii:utf-8'" \
+                -e "set charset='utf-8'" \
+               -s "Release-critical Bugreport for `date +'%B %e, %Y'`" \
+               debian-devel-announce@lists.debian.org
+
diff --git a/dostatus b/dostatus
new file mode 100755 (executable)
index 0000000..572dc40
--- /dev/null
+++ b/dostatus
@@ -0,0 +1,6 @@
+#!/bin/sh
+
+newtime=`ls -al status | cut -c 43-54`
+echo -n "$newtime (CST): " > /org/bugs.debian.org/www/bugscan/status
+./bugreport -s >> /org/bugs.debian.org/www/bugscan/status
+
diff --git a/makepost b/makepost
new file mode 100755 (executable)
index 0000000..7d9bee3
--- /dev/null
+++ b/makepost
@@ -0,0 +1,35 @@
+#! /bin/sh
+
+newtime=`ls -alL pstatus | cut -c 44-55`
+oldtime=`ls -alL pstatus-old | cut -c 44-55`
+title="Bug stamp-out list for $newtime (CST)"
+cat <<EOF
+$title
+
+EOF
+./bugreport -s 
+
+cat <<EOF
+
+Explanation for bug tags:
+
+   P  pending
+   +  patch
+   H  help
+   M  moreinfo
+   R  unreproducible
+   S  security
+   U  upstream
+   I  etch-ignore
+
+Some bugs have an additional set of tags indicating they only apply
+to a particular release: O for oldstable (woody), S for stable (sarge),
+T for testing (etch), U for unstable (sid) or E for experimental. X
+indicates that the package is not in testing.
+
+------------------------------------------------------------------------------
+EOF
+
+./bugreport -l -S pstatus
+
+
diff --git a/scanlib.pm b/scanlib.pm
new file mode 100644 (file)
index 0000000..faee90c
--- /dev/null
@@ -0,0 +1,360 @@
+#! /usr/bin/perl
+# vim: ts=4 sw=4 nowrap
+#
+# General functions for scanning the BTS-database.
+# Based on bugscan, written by Richard Braakman <dark@debian.org>,
+# which was based on an unknown other script.
+#
+# Global variables:
+#   %comments       - map from bugnumber to bug description
+#   %premature      - list of prematurely closed bugreports
+#   %exclude        - list of bugreports to exclude from the report
+#   %maintainer     - map from packagename to maintainer
+#   %section        - map from packagename to section in the FTP-site
+#   %packagelist    - map from packagename to bugreports
+#   %NMU            - map with NMU information
+
+use LWP::UserAgent;
+require bugcfg;
+
+sub readcomments() {
+# Read bug commentary 
+# It is in paragraph format, with the first line of each paragraph being
+# the bug number or package name to which the comment applies.
+# Prefix a bug number with a * to force it to be listed even if it's closed.
+# (This deals with prematurely closed bugs)
+
+       local($index);                                  # Bug-number for current comment
+       local($file);                                   # Name of comments-file
+
+       %comments = ();                                 # Initialize our data
+       %premature = ();
+       %exclude = ();
+       $file=shift;
+       open(C, $file) or die "open $file: $!\n";
+       while (<C>) {
+               chomp;
+               if (m/^\s*$/) {                         # Check for paragraph-breaks
+                       undef $index;
+               } elsif (defined $index) {
+                       $comments{$index} .= $_ . "\n";
+               } else {
+                       if (s/^\*//) {                  # Test & remove initial *
+                               $premature{$_} = 1;
+                       }
+                       if (s/\s+EXCLUDE\s*//) {        # Test & remove EXCLUDE
+                               $exclude{$_} = 1;
+                               next;
+                       }
+                       $index = $_;
+                       $comments{$index} = ''; # New comment, initialize data
+               }
+       }
+       close(C);
+}
+
+
+# Read the list of maintainer 
+sub readmaintainers() {
+       local ($pkg);                                   # Name of package
+       local ($mnt);                                   # Maintainer name & email
+
+       open(M, $maintainerlist) or die "open $maintainerlist: $!\n";
+       while (<M>) {
+               chomp;
+               m/^(\S+)\s+(\S.*\S)\s*$/ or die "Maintainers: $_ ?";
+               ($pkg, $mnt) = ($1, $2);
+               $pkg =~ y/A-Z/a-z/;                     # Normalize package-name. why???
+               $_=$mnt;
+               if (not m/</) {
+                       $mnt="$2 <$1>" if ( m/(\S+)\s+\(([^)]+)\)/ );
+               }
+               $maintainer{$pkg}= $mnt;
+       }
+       close(M);
+}
+
+
+sub readsources() {
+       local($root);                                   # Root of archive we are scanning
+       local($archive);                                # Name of archive we are scanning
+       local($sect);                                   # Name of current section
+
+       $root=shift;
+       $archive=shift;
+       for $sect ( @sections) {
+               open(P, "zcat $root/$sect/source/Sources.gz|")
+                       or die open "open: $sect / $arch sourcelist: $!\n";
+               while (<P>) {
+                       chomp;
+                       next unless m/^Package:\s/;
+                       s/^Package:\s*//;                       # Strip the fieldname
+                       $section{$_} = "$archive/$sect";
+               }
+               close (P);
+       }
+}
+
+sub readpackages() {
+       local($root);                                   # Root of archive we are scanning
+       local($archive);                                # Name of archive we are scanning
+       local($sect);                                   # Name of current section
+       local($arch);                                   # Name of current architecture
+
+       $root=shift;
+       $archive=shift;
+       for $arch ( @architectures ) {
+               for $sect ( @sections) {
+                       open(P, "zcat $root/$sect/binary-$arch/Packages.gz|")
+                               or die "open: $root/$sect/binary-$arch/Packages.gz: $!\n";
+                       while (<P>) {
+                               chomp;
+                               next unless m/^Package:\s/;     # We're only interested in the packagenames
+                               s/^Package:\s*//;                       # Strip the fieldname
+                               $section{$_} = "$archive/$sect";
+                       }
+                       close(P);
+               }
+       }
+}
+
+sub readdebbugssources() {
+       local($file);
+       local($archive);
+
+       $file=shift;
+       $archive=shift;
+       open(P, $file)
+               or die "open: $file: $!\n";
+       while (<P>) {
+               chomp;
+               my ($host, $bin, $sect, $ver, $src) = split /\s+/;
+               my $sectname = ($sect =~ /^\Q$archive/) ? $sect : "$archive/$sect";
+               $debbugssection{$bin} = $sectname;
+               $debbugssection{$src} = $sectname;
+       }
+       close(P);
+}
+
+sub readpseudopackages() {
+       open(P, $pseudolist) or die("open $pseudolist: $!\n");
+       while (<P>) {
+               chomp;
+               s/\s.*//;
+               $section{$_} = "pseudo";
+       }
+       close(P);
+}
+
+
+sub scanspool() {
+       local(@dirs);
+       local($dir);
+
+       chdir($spooldir) or die "chdir $spooldir: $!\n";
+
+       opendir(DIR, $spooldir) or die "opendir $spooldir: $!\n";
+       @dirs=grep(m/^\d+$/,readdir(DIR));
+       closedir(DIR);
+
+       for $dir (@dirs) {
+               scanspooldir("$spooldir/$dir");
+       }
+
+}
+
+sub scanspooldir() {
+       local($dir)             = @_;
+       local($f);                      # While we're currently processing
+       local(@list);           # List of files to process
+       local($s_originator, $s_date, $s_subject, $s_msgid, $s_package, $s_keywords);
+       local($s_done, $s_forwarded, $s_mergedwith, $s_severity);
+       local($skip);           # Flow control
+       local($walk);           # index variable
+       local($taginfo);        # Tag info
+
+       chdir($dir) or die "chdir $dir: $!\n";
+
+       opendir(DIR, $dir) or die "opendir $dir: $!\n";
+       @list = grep { s/\.status$// }
+                       grep { m/^\d+\.status$/ } 
+                       readdir(DIR);
+       closedir(DIR);
+
+       for $f (@list) {
+               next if $exclude{$f};                   # Check the list of bugs to skip
+               next if (!open(S,"$f.status")); # Check bugs without a status (?)
+
+               chomp($s_originator = <S>);
+               chomp($s_date = <S>);
+               chomp($s_subject = <S>);
+               chomp($s_msgid = <S>);
+               chomp($s_package = <S>);
+               chomp($s_tags = <S>);
+               chomp($s_done = <S>);
+               chomp($s_forwarded = <S>);
+               chomp($s_mergedwith = <S>);
+               chomp($s_severity = <S>);
+               close(S);
+
+               next if length($s_done) and not $premature{$f};
+               $premature{$f}++ if length($s_done);
+
+               $s_severity =~ y/A-Z/a-z/;
+               $s_tags =~ y/A-Z/a-z/;
+
+               $skip=1;
+               for $walk (@priorities) {
+                       $skip=0 if $walk eq $s_severity;
+               }
+
+               for $tag (split(' ', $s_tags)) {
+                       for $s (@skiptags) {
+                               $skip=1 if $tag eq $s;
+                       }
+               }
+               next if $skip==1;
+
+               $relinfo = "";
+               $relinfo .= ($s_tags =~ /\bwoody\b/         ? "O" : "");
+               $relinfo .= ($s_tags =~ /\bsarge(|\s.*)%/   ? "S" : "");
+               $relinfo .= ($s_tags =~ /\betch(|\s.*)$/    ? "T" : "");
+                       # etch-ignore matches \betch\b :(
+               $relinfo .= ($s_tags =~ /\bsid\b/           ? "U" : "");
+               $relinfo .= ($s_tags =~ /\bexperimental\b/  ? "E" : "");
+
+               $taginfo = "[";
+               $taginfo .= ($s_tags =~ /\bpending\b/        ? "P" : " ");
+               $taginfo .= ($s_tags =~ /\bpatch\b/          ? "+" : " ");
+               $taginfo .= ($s_tags =~ /\bhelp\b/           ? "H" : " ");
+               $taginfo .= ($s_tags =~ /\bmoreinfo\b/       ? "M" : " ");
+               $taginfo .= ($s_tags =~ /\bunreproducible\b/ ? "R" : " ");
+               $taginfo .= ($s_tags =~ /\bsecurity\b/       ? "S" : " ");
+               $taginfo .= ($s_tags =~ /\bupstream\b/       ? "U" : " ");
+               $taginfo .= ($s_tags =~ /\betch-ignore\b/    ? "I" : " ");
+               $taginfo .= "]";
+
+               if ($s_mergedwith) {                    # Only show the first package if things are merged
+                       my @merged = split(' ', $s_mergedwith);
+                       next if ($merged[0] < $f);
+               }
+
+               for $package (split /[,\s]+/, $s_package) {
+                       $_= $package; y/A-Z/a-z/; $_= $` if m/[^-+._a-z0-9]/;
+                       if (not defined $section{$_}) {
+                               if (defined $debbugssection{$_}) {
+                                       $relinfo .= "X";
+                               } else {
+                                       next;   # Skip unavailable packages
+                               }
+                       }
+
+                       $packagelist{$_} .= " $f";
+               }
+
+               if ($relinfo eq "") { # or $relinfo eq "U" # confuses e.g. #210306
+                       $relinfo = "";
+               } else {
+                       $relinfo = " [$relinfo]";
+               }
+
+               $bugs{$f} = "$f $taginfo$relinfo $s_subject";
+       }
+}
+
+
+sub readstatus() {
+       local ($bug);           # Number of current bug
+       local ($subject);       # Subject for current bug
+       local ($pkg);           # Name of current package
+       local ($file);          # Name of statusfile
+       local ($sect);          # Section of current package
+       local ($mnt);           # Maintainer of current package
+
+       $file=shift;
+       open(P, $file) or die "open $file: $!";
+       while (<P>) {
+               chomp;
+               if (m/^[0-9]+ \[/) {
+                       ($bug,$subject)=split(/ /, $_, 2);
+                       $bugs{$bug}=$subject;
+                       $packagelist{$pkg} .= "$bug ";
+               } else {
+                       ($pkg,$sect, $mnt)=split(/ /, $_, 3);
+                       $section{$pkg}=$sect;
+                       $maintainer{$pkg}=$mnt;
+               }
+       }
+       close P;
+}
+
+
+sub readNMUstatus() {
+       local ($bug);       # Number of current bug
+       local ($source);    # Source upload which closes this bug.
+       local ($version);   # Version where this bug was closed.
+       local ($flag);      # Whether this paragraph has been processed.
+       local ($field, $value);
+
+       for (split /\n/, LWP::UserAgent->new->request(HTTP::Request->new(GET => shift))->content) {
+               chomp;
+               if (m/^$/) {
+                       $NMU{$bug} = 1;
+                       $NMU{$bug, "source"} = $source;
+                       $NMU{$bug, "version"} = $version;
+#                      $comments{$bug} .= "[FIXED] Fixed package $source is in Incoming\n";
+                       $flag = 0;
+               } else {
+                       ($field, $value) = split(/: /, $_, 2);
+                       $bug = $value if($field =~ /bug/i);
+                       $source = $value if($field =~ /source/i);
+                       $version = $value if($field =~ /version/i);
+                       $flag = 1;
+               }
+       }
+       if ($flag) {
+               $NMU{$bug} = 1;
+               $NMU{$bug, "source"} = $source;
+               $NMU{$bug, "version"} = $version;
+#              $comments{$bug} .= "[FIXED] Fixed package $source in in Incoming\n";
+       }
+       close P;
+}
+
+
+sub urlsanit {
+       my $url = shift;
+       $url =~ s/%/%25/g;
+       $url =~ s/\+/%2b/g;
+       my %saniarray = ('<','lt', '>','gt', '&','amp', '"','quot');
+       $url =~ s/([<>&"])/\&$saniarray{$1};/g;
+       return $url;
+}
+
+sub htmlsanit {
+    my %saniarray = ('<','lt', '>','gt', '&','amp', '"','quot');
+    my $in = shift || "";
+    $in =~ s/([<>&"])/\&$saniarray{$1};/g;
+    return $in;
+}
+
+sub wwwnumber() {
+       local ($number) = shift;                # Number of bug to html-ize
+#      local ($section);                               # Section for the bug
+
+       "<A HREF=\"http://bugs.debian.org/cgi-bin/bugreport.cgi?archive=no&amp;bug=" .
+               urlsanit($number) . '">' . htmlsanit($number) . '</A>';
+#      ($section=$number) =~ s/([0-9]{2}).*/$1/;
+#      "<A HREF=\"${btsURL}/db/$section/$number.html\">$number</A>";
+}
+
+sub wwwname() {
+       local ($name) = shift;                  # Name of package
+
+       "<A HREF=\"http://bugs.debian.org/cgi-bin/pkgreport.cgi?archive=no&amp;pkg=" .
+               urlsanit($name) . '">' . htmlsanit($name) . '</A>';
+#      "<A HREF=\"${btsURL}/db/pa/l$name.html\">$name</A>";
+}
+
+1;
+
diff --git a/z b/z
new file mode 100755 (executable)
index 0000000..b4d612a
--- /dev/null
+++ b/z
@@ -0,0 +1,24 @@
+#! /bin/sh
+
+cd /org/bugs.debian.org/bugscan
+
+rm pstatus-old
+mv pstatus pstatus-old
+now=`ls -al status | sed -e 's/.*-\([0-9]*\)/\1/'`
+ln -s stati/status-$now pstatus
+
+./makepost > posts/post-$now
+
+cat <<EOF >> posts/post-$now
+
+This post is automatically generated. Please send comments to
+bugscan@debian.org .
+EOF
+
+cat posts/post-$now | \
+       mutt \
+               -e "my_hdr Reply-To: debian-devel@lists.debian.org,bugscan\@debian.org" \
+               -e "my_hdr From: BugScan reporter <bugscan\@debian.org>" \
+               -s "Release-critical Bugreport for `date +'%B %e, %Y'`" \
+               debian-devel-announce@lists.debian.org
+