]> git.donarmstrong.com Git - wannabuild.git/commitdiff
initial import of /org/wanna-build
authorwanna-build admin <wbadm@raff.debian.org>
Sun, 23 Nov 2008 15:37:46 +0000 (15:37 +0000)
committerwanna-build admin <wbadm@raff.debian.org>
Sun, 23 Nov 2008 15:37:46 +0000 (15:37 +0000)
46 files changed:
.gitignore [new file with mode: 0644]
bin/WannaBuild.pm [new file with mode: 0644]
bin/catgdbm [new file with mode: 0755]
bin/dep-wait-build [new symlink]
bin/failed-build [new symlink]
bin/forget-build [new symlink]
bin/give-back-build [new symlink]
bin/list-building [new symlink]
bin/list-dep-wait [new symlink]
bin/list-failed [new symlink]
bin/list-installed [new symlink]
bin/list-needs-build [new symlink]
bin/list-not-for-us [new symlink]
bin/list-uploaded [new symlink]
bin/no-build [new symlink]
bin/ssh-wrapper [new file with mode: 0755]
bin/trigger-wrapper [new file with mode: 0755]
bin/uploaded-build [new symlink]
bin/wanna-build [new file with mode: 0755]
bin/wanna-build-statistics [new file with mode: 0755]
bin/wb-graph [new file with mode: 0755]
bin/wb-make-rev [new file with mode: 0755]
db/.keep [new file with mode: 0644]
etc/.gitignore [new file with mode: 0644]
etc/cron/Makefile [new file with mode: 0644]
etc/cron/crontab [new file with mode: 0644]
etc/graph.R [new file with mode: 0644]
etc/wanna-build.conf [new file with mode: 0644]
etc/wanna-build.conf.local [new file with mode: 0644]
fixperms [new file with mode: 0755]
home/.gitignore [new file with mode: 0644]
home/.ssh/authorized_keys [new file with mode: 0644]
postrelease [new file with mode: 0644]
ssh-keys/README [new file with mode: 0644]
ssh-keys/buildd_alpha [new file with mode: 0644]
ssh-keys/buildd_arm [new file with mode: 0644]
ssh-keys/buildd_hppa [new file with mode: 0644]
ssh-keys/buildd_i386 [new file with mode: 0644]
ssh-keys/buildd_ia64 [new file with mode: 0644]
ssh-keys/buildd_m68k [new file with mode: 0644]
ssh-keys/buildd_mips [new file with mode: 0644]
ssh-keys/buildd_powerpc [new file with mode: 0644]
ssh-keys/buildd_s390 [new file with mode: 0644]
ssh-keys/buildd_sparc [new file with mode: 0644]
trigger.daily [new file with mode: 0755]
trigger.often [new file with mode: 0755]

diff --git a/.gitignore b/.gitignore
new file mode 100644 (file)
index 0000000..21862a0
--- /dev/null
@@ -0,0 +1,4 @@
+.da-backup.trace
+trigger.curlrc
+tmp
+db
diff --git a/bin/WannaBuild.pm b/bin/WannaBuild.pm
new file mode 100644 (file)
index 0000000..300eb12
--- /dev/null
@@ -0,0 +1,199 @@
+#
+# WannaBuild.pm: library for wanna-build and sbuild
+# Copyright (C) 2005 Ryan Murray <rmurray@debian.org>
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License as
+# published by the Free Software Foundation; either version 2 of the
+# License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+#
+# $Id$
+#
+
+package WannaBuild;
+
+use strict;
+use POSIX;
+use FileHandle;
+use Time::Local;
+
+require Exporter;
+@WannaBuild::ISA = qw(Exporter);
+@WannaBuild::EXPORT = qw(version_less version_lesseq version_eq
+                       version_compare binNMU_version parse_date isin);
+
+$WannaBuild::opt_correct_version_cmp = 0;
+
+sub version_less {
+       my $v1 = shift;
+       my $v2 = shift;
+       
+       return version_compare( $v1, "<<", $v2 );
+}
+
+sub version_lesseq {
+       my $v1 = shift;
+       my $v2 = shift;
+
+       return version_compare( $v1, "<=", $v2 );
+}
+
+sub version_eq {
+       my $v1 = shift;
+       my $v2 = shift;
+
+       return version_compare( $v1, "=", $v2 );
+}
+
+sub version_compare {
+       my $v1 = shift;
+       my $rel = shift;
+       my $v2 = shift;
+       
+       if ($WannaBuild::opt_correct_version_cmp) {
+               system "dpkg", "--compare-versions", $v1, $rel, $v2;
+               return $? == 0;
+       }
+       else {
+               if ($rel eq "=" || $rel eq "==") {
+                       return $v1 eq $v2;
+               }
+               elsif ($rel eq "<<") {
+                       return do_version_cmp( $v1, $v2 );
+               }
+               elsif ($rel eq "<=" || $rel eq "<") {
+                       return $v1 eq $v2 || do_version_cmp( $v1, $v2 );
+               }
+               elsif ($rel eq ">=" || $rel eq ">") {
+                       return !do_version_cmp( $v1, $v2 );
+               }
+               elsif ($rel eq ">>") {
+                       return $v1 ne $v2 && !do_version_cmp( $v1, $v2 );
+               }
+               else {
+                       warn "version_compare called with bad relation '$rel'\n";
+                       return $v1 eq $2;
+               }
+       }
+}
+
+sub do_version_cmp {
+       my($versa, $versb) = @_;
+       my($epocha,$upstra,$reva);
+       my($epochb,$upstrb,$revb);
+       my($r);
+
+       ($epocha,$upstra,$reva) = split_version($versa);
+       ($epochb,$upstrb,$revb) = split_version($versb);
+
+       # compare epochs
+       return 1 if $epocha < $epochb;
+       return 0 if $epocha > $epochb;
+
+       # compare upstream versions
+       $r = version_cmp_single( $upstra, $upstrb );
+       return $r < 0 if $r != 0;
+
+       # compare Debian revisions
+       $r = version_cmp_single( $reva, $revb );
+       return $r < 0;
+}
+
+sub order {
+       for ($_[0])
+       {
+       /\~/     and return -1;
+       /\d/     and return  0;
+       /[a-z]/i and return ord;
+                    return (ord) + 256;
+       }
+}
+
+sub version_cmp_single {
+       my($versa, $versb) = @_;
+       my($a,$b,$lena,$lenb,$va,$vb,$i);
+
+       for(;;) {
+               # compare non-numeric parts
+               $versa =~ /^([^\d]*)(.*)/; $a = $1; $versa = $2;
+               $versb =~ /^([^\d]*)(.*)/; $b = $1; $versb = $2;
+               $lena = length($a);
+               $lenb = length($b);
+               for( $i = 0; $i < $lena || $i < $lenb; ++$i ) {
+                       $va = $i < $lena ? order(substr( $a, $i, 1 )) : 0;
+                       $vb = $i < $lenb ? order(substr( $b, $i, 1 )) : 0;
+                       return $va - $vb if $va != $vb;
+               }
+               # compare numeric parts
+               $versa =~ /^(\d*)(.*)/; $a = $1; $a ||= 0; $versa = $2;
+               $versb =~ /^(\d*)(.*)/; $b = $1; $b ||= 0; $versb = $2;
+               return $a - $b if $a != $b;
+               return 0 if !$versa && !$versb;
+               if (!$versa) {
+                       return +1 if order(substr( $versb, 0, 1 ) ) < 0;
+                       return -1;
+               }
+               if (!$versb) {
+                       return -1 if order(substr( $versa, 0, 1 ) ) < 0;
+                       return +1;
+               }
+       }
+}
+
+sub split_version {
+       my($vers) = @_;
+       my($epoch,$revision) = (0,"");
+
+       if ($vers =~ /^(\d+):(.*)/) {
+               $epoch = $1;
+               $vers = $2;
+       }
+
+       if ($vers =~ /(.*)-([^-]+)$/) {
+               $revision = $2;
+               $vers = $1;
+       }
+
+       return( $epoch, $vers, $revision );
+}
+
+sub binNMU_version {
+       my $v = shift;
+       my $binNMUver = shift;
+
+       return "$v+b$binNMUver";
+}
+
+
+my %monname = ('jan', 0, 'feb', 1, 'mar', 2, 'apr', 3, 'may', 4, 'jun', 5,
+               'jul', 6, 'aug', 7, 'sep', 8, 'oct', 9, 'nov', 10, 'dec', 11 );
+
+sub parse_date {
+       my $text = shift;
+
+       return 0 if !$text;
+       die "Cannot parse date: $text\n"
+               if $text !~ /^(\d{4}) (\w{3}) (\d+) (\d{2}):(\d{2}):(\d{2})$/;
+       my ($year, $mon, $day, $hour, $min, $sec) = ($1, $2, $3, $4, $5, $6);
+       $mon =~ y/A-Z/a-z/;
+       die "Invalid month name $mon" if !exists $monname{$mon};
+       $mon = $monname{$mon};
+       return timegm($sec, $min, $hour, $day, $mon, $year);
+}
+
+sub isin {
+       my $val = shift;
+
+       return grep( $_ eq $val, @_ );
+}
+
+1;
diff --git a/bin/catgdbm b/bin/catgdbm
new file mode 100755 (executable)
index 0000000..d7f6bbe
--- /dev/null
@@ -0,0 +1,42 @@
+#!/usr/bin/perl
+
+use File::Basename;
+$progname = basename($0);
+
+use DB_File;
+use GDBM_File;
+
+die "Filename missing\n" if !@ARGV;
+die "$ARGV[0]: $!\n" if !-f $ARGV[0];
+
+if ($progname =~ /catdb/) {
+       tie %db, 'DB_File', $ARGV[0], O_RDONLY, 0664, $DB_HASH;
+}
+elsif ($progname =~ /catgdbm/) {
+       tie %db, 'GDBM_File', $ARGV[0], GDBM_READER, 0644;
+}
+else {
+       die "Called for unknown db type\n";
+}
+shift;
+
+if (@ARGV > 0) {
+       foreach $key (@ARGV) {
+               print "-"x78, "\n";
+               if (exists $db{$key}) {
+                       print "$key:\n$db{$key}\n";
+               }
+               else {
+                       print "*UNDEFINED*\n";
+               }
+       }
+}
+else {
+       while( ($key,$val) = each %db ) {
+               print "-"x78, "\n";
+               print "$key:\n$val\n";
+       }
+}
+
+untie %db;
+exit 0;
diff --git a/bin/dep-wait-build b/bin/dep-wait-build
new file mode 120000 (symlink)
index 0000000..0b45c3e
--- /dev/null
@@ -0,0 +1 @@
+wanna-build
\ No newline at end of file
diff --git a/bin/failed-build b/bin/failed-build
new file mode 120000 (symlink)
index 0000000..0b45c3e
--- /dev/null
@@ -0,0 +1 @@
+wanna-build
\ No newline at end of file
diff --git a/bin/forget-build b/bin/forget-build
new file mode 120000 (symlink)
index 0000000..0b45c3e
--- /dev/null
@@ -0,0 +1 @@
+wanna-build
\ No newline at end of file
diff --git a/bin/give-back-build b/bin/give-back-build
new file mode 120000 (symlink)
index 0000000..0b45c3e
--- /dev/null
@@ -0,0 +1 @@
+wanna-build
\ No newline at end of file
diff --git a/bin/list-building b/bin/list-building
new file mode 120000 (symlink)
index 0000000..0b45c3e
--- /dev/null
@@ -0,0 +1 @@
+wanna-build
\ No newline at end of file
diff --git a/bin/list-dep-wait b/bin/list-dep-wait
new file mode 120000 (symlink)
index 0000000..0b45c3e
--- /dev/null
@@ -0,0 +1 @@
+wanna-build
\ No newline at end of file
diff --git a/bin/list-failed b/bin/list-failed
new file mode 120000 (symlink)
index 0000000..0b45c3e
--- /dev/null
@@ -0,0 +1 @@
+wanna-build
\ No newline at end of file
diff --git a/bin/list-installed b/bin/list-installed
new file mode 120000 (symlink)
index 0000000..0b45c3e
--- /dev/null
@@ -0,0 +1 @@
+wanna-build
\ No newline at end of file
diff --git a/bin/list-needs-build b/bin/list-needs-build
new file mode 120000 (symlink)
index 0000000..0b45c3e
--- /dev/null
@@ -0,0 +1 @@
+wanna-build
\ No newline at end of file
diff --git a/bin/list-not-for-us b/bin/list-not-for-us
new file mode 120000 (symlink)
index 0000000..0b45c3e
--- /dev/null
@@ -0,0 +1 @@
+wanna-build
\ No newline at end of file
diff --git a/bin/list-uploaded b/bin/list-uploaded
new file mode 120000 (symlink)
index 0000000..0b45c3e
--- /dev/null
@@ -0,0 +1 @@
+wanna-build
\ No newline at end of file
diff --git a/bin/no-build b/bin/no-build
new file mode 120000 (symlink)
index 0000000..0b45c3e
--- /dev/null
@@ -0,0 +1 @@
+wanna-build
\ No newline at end of file
diff --git a/bin/ssh-wrapper b/bin/ssh-wrapper
new file mode 100755 (executable)
index 0000000..a340934
--- /dev/null
@@ -0,0 +1,18 @@
+#!/bin/bash
+
+bin=/org/wanna-build/bin/wanna-build
+
+[ -n "$SSH_ORIGINAL_COMMAND" ] || exit 1
+
+set -- $SSH_ORIGINAL_COMMAND
+
+bn=$(basename "$1")
+if [ "$bn" != "wanna-build" ]; then
+       exit 1
+fi
+
+shift
+
+[ -f "$bin" -a -x "$bin" ] || exit 1
+
+exec $bin $@
diff --git a/bin/trigger-wrapper b/bin/trigger-wrapper
new file mode 100755 (executable)
index 0000000..7832f87
--- /dev/null
@@ -0,0 +1,20 @@
+#!/bin/bash
+
+[ -n "$SSH_ORIGINAL_COMMAND" ] || exit 1
+
+set -- $SSH_ORIGINAL_COMMAND
+
+bn=$(basename "$1")
+if [ "$bn" = "trigger.daily" ]; then
+       bin=/org/wanna-build/trigger.daily
+elif [ "$bn" = "trigger.often" ]; then
+       bin=/org/wanna-build/trigger.often
+else
+       exit 1
+fi
+
+shift
+
+[ -f "$bin" -a -x "$bin" ] || exit 1
+
+exec $bin
diff --git a/bin/uploaded-build b/bin/uploaded-build
new file mode 120000 (symlink)
index 0000000..0b45c3e
--- /dev/null
@@ -0,0 +1 @@
+wanna-build
\ No newline at end of file
diff --git a/bin/wanna-build b/bin/wanna-build
new file mode 100755 (executable)
index 0000000..7b9c4ea
--- /dev/null
@@ -0,0 +1,2497 @@
+#!/usr/bin/perl
+# 
+# wanna-build: coordination script for Debian buildds
+# Copyright (C) 1998 Roman Hodek <Roman.Hodek@informatik.uni-erlangen.de>
+# Copyright (C) 2005-2008 Ryan Murray <rmurray@debian.org>
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License as
+# published by the Free Software Foundation; either version 2 of the
+# License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+#
+
+package conf;
+# defaults
+$basedir = "/var/lib/debbuild";
+$dbbase = "build-db";
+$transactlog = "transactions.log";
+$mailprog = "/usr/sbin/sendmail";
+require "/etc/wanna-build.conf";
+die "$conf::basedir is not a directory\n" if ! -d $conf::basedir;
+die "dbbase is empty\n" if ! $dbbase;
+die "transactlog is empty\n" if ! $transactlog;
+die "mailprog binary $conf::mailprog does not exist or isn't executable\n"
+       if !-x $conf::mailprog;
+die "no distributions defined\n" if ! %distributions;
+package main;
+
+use strict;
+use POSIX;
+use FileHandle;
+use GDBM_File;
+use MLDBM qw(GDBM_File Storable);
+use WannaBuild;
+
+our ($verbose, $mail_logs, $list_order, $list_state,
+    $curr_date, $op_mode, $user, $real_user, $distribution,
+    $fail_reason, $opt_override, $import_from, $export_to, $opt_create_db,
+    $transactlog, %db, %otherdb, %otherdb_lock, %prioval, %sectval,
+    $info_all_dists, $hostname, $arch,
+    $category, %catval, %short_category,
+    $short_date, $list_min_age, $dbbase, $host_set, @curr_time,
+    $build_priority, %new_vers, $binNMUver, %merge_srcvers, %merge_binsrc);
+
+# global vars
+$ENV{'PATH'} = "/bin:/usr/bin:/usr/local/bin";
+$verbose = 0;
+$mail_logs = "";
+@curr_time = gmtime;
+$curr_date = strftime("%Y %b %d %H:%M:%S",@curr_time);
+$short_date = strftime("%m/%d/%y",@curr_time);
+$| = 1;
+
+# map program invocation names to operation modes
+my %prognames = ( "uploaded-build"  => "set-uploaded",
+                                 "failed-build"    => "set-failed",
+                                 "no-build"            => "set-not-for-us",
+                                 "give-back-build" => "set-needs-build",
+                                 "dep-wait-build"  => "set-dep-wait",
+                                 "forget-build"        => "forget",
+                                 "merge-quinn"         => "merge-quinn",
+                                 "merge-packages"  => "merge-packages",
+                                 "merge-sources"   => "merge-sources",
+                                 "build-info"          => "info" );
+
+%short_category = ( u => "uploaded-fixed-pkg",
+                                   f => "fix-expected",
+                                       r => "reminder-sent",
+                                       n => "nmu-offered",
+                                       e => "easy",
+                                       m => "medium",
+                                       h => "hard",
+                                       c => "compiler-error",
+                                       "" => "none" );
+
+my $progname;
+($progname = $0) =~ s,.*/,,;
+if ($prognames{$progname}) {
+       $op_mode = $prognames{$progname};
+}
+elsif ($progname =~ /^list-(.*)$/) {
+       $op_mode = "list";
+       $list_state = ($1 eq "all") ? "" : $1;
+}
+
+my %options =
+       (# flags
+        verbose        => { short => "v", flag => \$verbose },
+        override               => { short => "o", flag => \$opt_override },
+        "create-db"    => { flag => \$opt_create_db },
+        "correct-compare" => { flag => \$WannaBuild::opt_correct_version_cmp },
+        # TODO: remove after buildds no longer pass to wanna-build
+        "no-propagation" => { short => "N" },
+        "no-down-propagation" => { short => "D" },
+        # normal actions
+        take                   => { mode => "set-building" },
+        failed                 => { short => "f", mode => "set-failed" },
+        uploaded               => { short => "u", mode => "set-uploaded" },
+        "no-build"             => { short => "n", mode => "set-not-for-us" },
+        built                  => { mode => "set-built" },
+        attempted              => { mode => "set-attempted" },
+        "give-back"            => { mode => "set-needs-build" },
+        "dep-wait"             => { mode => "set-dep-wait" },
+        forget                 => { mode => "forget" },
+        'forget-user' => { mode => 'forget-user' },
+        "merge-quinn"  => { mode => "merge-quinn" },
+        "merge-partial-quinn" => { mode => "merge-partial-quinn" },
+        "merge-packages" => { mode => "merge-packages" },
+        "merge-sources" => { mode => "merge-sources" },
+        "pretend-avail" => { short => "p", mode => "pretend-avail" },
+        "merge-all"     => { mode => "merge-all" },
+        info                   => { short => "i", mode => "info" },
+        'binNMU' => { mode => 'set-binary-nmu', arg => \$binNMUver, 
+                            code => sub { die "Invalid binNMU version: $binNMUver\n"
+                               if $binNMUver !~ /^([\d]*)$/ and $1 >= 0; } },
+        'perm-build-priority'    => { mode => "set-permanent-build-priority", arg => \$build_priority,
+                             code => sub { die "Invalid build priority: $build_priority\n"
+                               if $build_priority !~ /^-?[\d]+$/; } },
+        'build-priority'    => { mode => "set-build-priority", arg => \$build_priority,
+                             code => sub { die "Invalid build priority: $build_priority\n"
+                               if $build_priority !~ /^-?[\d]+$/; } },
+        list                   =>
+        { short => "l", mode => "list", arg => \$list_state,
+          code => sub {
+                  die "Unknown state to list: $list_state\n"
+                          if !isin( $list_state, qw(needs-build building uploaded
+                                                built build-attempted failed installed dep-wait
+                                                not-for-us all failed-removed
+                                                install-wait reupload-wait));} },
+        # options with args
+        dist           =>
+        { short => "d", arg => \$distribution,
+          code => sub {
+                  if ($distribution eq "a" || $distribution eq "all") {
+                          $info_all_dists = 1;
+                          $distribution = "";
+                  }
+                  else {
+                          $distribution = "stable"   if $distribution eq "s";
+                          $distribution = "testing"  if $distribution eq "t";
+                          $distribution = "unstable" if $distribution eq "u";
+                  }
+          } },
+        order          =>
+        { short => "O", arg => \$list_order,
+          code => sub {
+                  die "Bad ordering character\n"
+                          if $list_order !~ /^[PSpsncb]+$/;
+          } },
+        message        => { short => "m", arg => \$fail_reason },
+        database       => { short => "b", arg => \$conf::dbbase },
+        arch           => { short => "A", arg => \$arch },
+        user           => { short => "U", arg => \$user },
+        category               => { short => "c", arg => \$category,
+                                                code => sub {
+                                                        $category = $short_category{$category}
+                                                                if exists $short_category{$category};
+                                                        die "Unknown category: $category\n"
+                                                                if !isin( $category, values %short_category );
+                                                } },
+        "min-age"      => { short => "a", arg => \$list_min_age,
+                                                code => sub {
+                                                        die "Argument of --min-age must be a non-zero number\n"
+                                                                if $list_min_age == 0;
+                                                        $list_min_age *= 24*60*60;
+                                                } },
+        "max-age"      => { arg => \$list_min_age,
+                                                code => sub {
+                                                        die "Argument of --max-age must be a non-zero number\n"
+                                                                if $list_min_age == 0;
+                                                        $list_min_age *= -24*60*60;
+                                                } },
+        # special actions
+        import         => { arg => \$import_from, mode => "import" },
+        export         => { arg => \$export_to, mode => "export" },
+        "manual-edit"  => { mode => "manual-edit" },
+        "create-maintenance-lock" => { mode => "maintlock-create" },
+        "remove-maintenance-lock" => { mode => "maintlock-remove" },
+        "clean-db" => { mode => "clean-db" },
+        );
+
+while( @ARGV && $ARGV[0] =~ /^-/ ) {
+       $_ = shift @ARGV;
+       last if $_ eq "--";
+       my($opt, $optname, $arg);
+       if (/^--([^=]+)(=|$)/) {
+               $optname = $1;
+               $opt = $options{$optname};
+               $arg = $1 if /^--\Q$optname\E=((.|\n)*)$/;
+       }
+       else {
+               $optname = substr( $_, 1, 1 );
+               $opt = (grep { defined($_->{short}) ? $_->{short} eq $optname : 0} values %options)[0];
+               $arg = $1 if /^-$optname(.+)$/;
+       }
+       if (!$opt) {
+               warn "Unknown option: --$1\n";
+               usage();
+       }
+       if ($opt->{arg}) {
+               if (!defined $arg) {
+                       die "$optname option missing argument\n" if !@ARGV;
+                       $arg = shift @ARGV;
+               }
+               ${$opt->{arg}} = $arg;
+       }
+       elsif (defined $arg) {
+               die "Option $optname takes no argument\n";
+       }
+       
+       if ($opt->{mode}) {
+               die "Conflicting operation modes\n" if $op_mode;
+               $op_mode = $opt->{mode};
+       }
+       if ($opt->{flag}) {
+               ${$opt->{flag}}++;
+       }
+       if ($opt->{code}) {
+               &{$opt->{code}};
+       }
+}
+
+$op_mode = $category ? "set-failed" : "set-building"
+       if !$op_mode; # default operation
+$list_order = $list_state eq "failed" ? 'fPcpsn' : 'PScpsn'
+       if !$list_order and $list_state;
+$distribution ||= "unstable";
+die "Bad distribution '$distribution'\n"
+       if !isin($distribution, keys %conf::distributions);
+$conf::dbbase =~ m#^([^/]+/)#;
+$transactlog = "$conf::basedir/$1$conf::transactlog";
+
+if ($verbose) {
+       my $version = '$Revision: db181a534e9d $ $Date: 2008/03/26 06:20:22 $ $Author: rmurray $';
+       $version =~ s/(^\$| \$ .*$)//g;
+       print "wanna-build $version for $distribution on $conf::dbbase\n";
+}
+
+if (!@ARGV && !isin( $op_mode, qw(list merge-quinn merge-partial-quinn import export
+                                 merge-packages manual-edit maintlock-create
+                                 merge-sources maintlock-remove clean-db))) {
+       warn "No packages given.\n";
+       usage();
+}
+
+$real_user = (getpwuid($<))[0];
+die "Can't determine your user name\n"
+       if $op_mode ne "list" && !$user &&
+          !($user = $real_user);
+
+if (!$fail_reason) {
+       if ($op_mode eq "set-failed" && !$category) {
+               print "Enter reason for failing (end with '.' alone on ".
+                     "its line):\n";
+               my $line;
+               while(!eof(STDIN)) {
+                       $line = <STDIN>;
+                       last if $line eq ".\n";
+                       $line = ".\n" if $line eq "\n";
+                       $fail_reason .= $line;
+               }
+               chomp( $fail_reason );
+       } elsif ($op_mode eq "set-dep-wait") {
+               print "Enter dependencies (one line):\n";
+               my $line;
+               while( !$line && !eof(STDIN) ) {
+                       chomp( $line = <STDIN> );
+               }
+               die "No dependencies given\n" if !$line;
+               $fail_reason = $line;
+       } elsif ($op_mode eq "set-binary-nmu" and $binNMUver > 0) {
+               print "Enter changelog entry (one line):\n";
+               my $line;
+               while( !$line && !eof(STDIN) ) {
+                       chomp( $line = <STDIN> );
+               }
+               die "No changelog entry given\n" if !$line;
+               $fail_reason = $line;
+       }
+}
+if ($op_mode eq "maintlock-create") {
+       create_maintlock();
+       exit 0;
+}
+if ($op_mode eq "maintlock-remove") {
+       remove_maintlock();
+       exit 0;
+}
+waitfor_maintlock() if $op_mode !~ /^(?:merge-|clean-db$)/;
+
+if (!-f db_filename( $distribution ) && !$opt_create_db) {
+       die "Database for $distribution doesn't exist\n";
+}
+lock_db( $distribution );
+END {
+    untie %db;
+       unlock_db( $distribution );
+       foreach (keys %conf::distributions) {
+               untie %{$otherdb{$_}} if tied(%{$otherdb{$_}});
+               unlock_db( $_ ) if $otherdb_lock{$_};
+       }
+}
+
+tie %db, 'MLDBM', db_filename( $distribution ), GDBM_WRCREAT, 0664
+       or die "FATAL: Cannot open database\n";
+
+process();
+
+if ($mail_logs && $conf::log_mail) {
+       send_mail( $conf::log_mail,
+                          "wanna-build $distribution state changes $curr_date",
+                          "State changes at $curr_date for distribution ".
+                          "$distribution:\n\n$mail_logs\n" );
+}
+
+exit 0;
+
+
+sub process {
+
+       SWITCH: foreach ($op_mode) {
+               /^set-(.+)/ && do {
+                       add_packages( $1, @ARGV );
+                       last SWITCH;
+               };
+               /^list/ && do {
+                       list_packages( $list_state );
+                       last SWITCH;
+               };
+               /^info/ && do {
+                       info_packages( @ARGV );
+                       last SWITCH;
+               };
+               /^forget-user/ && do {
+                       die "This operation is restricted to admin users\n"
+                               if (defined @conf::admin_users and
+                                   !isin( $real_user, @conf::admin_users));
+                       forget_users( @ARGV );
+                       last SWITCH;
+               };
+               /^forget/ && do {
+                       forget_packages( @ARGV );
+                       last SWITCH;
+               };
+               /^merge-partial-quinn/ && do {
+                       die "This operation is restricted to admin users\n"
+                               if (defined @conf::admin_users and
+                                   !isin( $real_user, @conf::admin_users));
+                       parse_quinn_diff(1);
+                       last SWITCH;
+               };
+               /^merge-quinn/ && do {
+                       die "This operation is restricted to admin users\n"
+                               if (defined @conf::admin_users and
+                                   !isin( $real_user, @conf::admin_users));
+                       parse_quinn_diff(0);
+                       last SWITCH;
+               };
+               /^merge-packages/ && do {
+                       die "This operation is restricted to admin users\n"
+                               if (defined @conf::admin_users and
+                                   !isin( $real_user, @conf::admin_users));
+                       parse_packages();
+                       last SWITCH;
+               };
+               /^merge-sources/ && do {
+                       die "This operation is restricted to admin users\n"
+                               if (defined @conf::admin_users and
+                                   !isin( $real_user, @conf::admin_users));
+                       parse_sources(0);
+                       last SWITCH;
+               };
+               /^pretend-avail/ && do {
+                       pretend_avail( @ARGV );
+                       last SWITCH;
+               };
+               /^merge-all/ && do {
+                       die "This operation is restricted to admin users\n"
+                               if (defined @conf::admin_users and
+                                   !isin( $real_user, @conf::admin_users));
+                       my @ARGS = @ARGV;
+                       @ARGV = ( $ARGS[0] );
+                       my $pkgs = parse_packages();
+                       @ARGV = ( $ARGS[1] );
+                       parse_quinn_diff(0);
+                       @ARGV = ( $ARGS[2] );
+                       my $build_deps = parse_sources(1);
+                       auto_dep_wait( $build_deps, $pkgs );
+                       clean_db();
+                       last SWITCH;
+               };
+               /^import/ && do {
+                       die "This operation is restricted to admin users\n"
+                               if (defined @conf::admin_users and
+                                   !isin( $real_user, @conf::admin_users));
+                       %db = (); # clear all current contents
+                       read_db( $import_from );
+                       last SWITCH;
+               };
+               /^export/ && do {
+                       write_db( $export_to );
+                       last SWITCH;
+               };
+               /^manual-edit/ && do {
+                       die "This operation is restricted to admin users\n"
+                               if (defined @conf::admin_users and
+                                   !isin( $real_user, @conf::admin_users));
+                       my $tmpfile_pattern = "/tmp/wanna-build-$distribution.$$-";
+                       my ($tmpfile, $i);
+                       for( $i = 0;; ++$i ) {
+                               $tmpfile = $tmpfile_pattern . $i;
+                               last if ! -e $tmpfile;
+                       }
+                       write_db( $tmpfile );
+                       my $editor = $ENV{'VISUAL'} ||
+                                                "/usr/bin/sensible-editor";
+                       system "$editor $tmpfile";
+                       %db = (); # clear all current contents
+                       read_db( $tmpfile );
+                       unlink( $tmpfile );
+                       last SWITCH;
+               };
+               /^clean-db/ && do {
+                       die "This operation is restricted to admin users\n"
+                               if (defined @conf::admin_users and
+                                   !isin( $real_user, @conf::admin_users));
+                       clean_db();
+                       last SWITCH;
+               };
+
+               die "Unexpected operation mode $op_mode\n";
+       }
+       if (not -t and $user =~ /-/) {
+               my $userinfo = $db{'_userinfo'};
+               my $ui = $userinfo->{$user};
+
+               $userinfo->{$user}->{'Last-Seen'} = $curr_date;
+               $db{'_userinfo'} = $userinfo;
+       }
+}
+
+sub add_packages {
+       my $newstate = shift;
+       my( $package, $name, $version, $ok, $reason );
+       
+       foreach $package (@_) {
+               $package =~ s,^.*/,,; # strip path
+               $package =~ s/\.(dsc|diff\.gz|tar\.gz|deb)$//; # strip extension
+               $package =~ s/_[a-zA-Z\d-]+\.changes$//; # strip extension
+               if ($package =~ /^([\w\d.+-]+)_([\w\d:.+~-]+)/) {
+                       ($name,$version) = ($1,$2);
+               }
+               else {
+                       warn "$package: can't extract package name and version ".
+                                "(bad format)\n";
+                       next;
+               }
+
+               if ($op_mode eq "set-building") {
+                       add_one_building( $name, $version );
+               }
+               elsif ($op_mode eq "set-built") {
+                       add_one_built( $name, $version );
+               }
+               elsif ($op_mode eq "set-attempted") {
+                       add_one_attempted( $name, $version );
+               }
+               elsif ($op_mode eq "set-uploaded") {
+                       add_one_uploaded( $name, $version );
+               }
+               elsif ($op_mode eq "set-failed") {
+                       add_one_failed( $name, $version );
+               }
+               elsif ($op_mode eq "set-not-for-us") {
+                       add_one_notforus( $name, $version );
+               }
+               elsif ($op_mode eq "set-needs-build") {
+                       add_one_needsbuild( $name, $version );
+               }
+               elsif ($op_mode eq "set-dep-wait") {
+                       add_one_depwait( $name, $version );
+               }
+               elsif ($op_mode eq "set-build-priority") {
+                       set_one_buildpri( $name, $version, 'BuildPri' );
+               }
+               elsif ($op_mode eq "set-permanent-build-priority") {
+                       set_one_buildpri( $name, $version, 'PermBuildPri' );
+               }
+               elsif ($op_mode eq "set-binary-nmu") {
+                       set_one_binnmu( $name, $version );
+               }
+       }
+}
+
+sub add_one_building {
+       my $name = shift;
+       my $version = shift;
+       my( $ok, $reason );
+
+       $ok = 1;
+       my $pkg = $db{$name};
+       if (defined($pkg)) {
+               if ($pkg->{'State'} eq "Not-For-Us") {
+                       $ok = 0;
+                       $reason = "not suitable for this architecture";
+               }
+               elsif ($pkg->{'State'} =~ /^Dep-Wait/) {
+                       $ok = 0;
+                       $reason = "not all source dependencies available yet";
+               }
+               elsif ($pkg->{'State'} eq "Uploaded" &&
+                          (version_lesseq($version, $pkg->{'Version'}))) {
+                       $ok = 0;
+                       $reason = "already uploaded by $pkg->{'Builder'}";
+                       $reason .= " (in newer version $pkg->{'Version'})"
+                               if !version_eq($pkg, $version);
+               }
+               elsif ($pkg->{'State'} eq "Installed" &&
+                          version_less($version,$pkg->{'Version'})) {
+                       if ($opt_override) {
+                               print "$name: Warning: newer version $pkg->{'Version'} ".
+                                         "already installed, but overridden.\n";
+                       }
+                       else {
+                               $ok = 0;
+                               $reason = "newer version $pkg->{'Version'} already in ".
+                                                 "archive; doesn't need rebuilding";
+                               print "$name: Note: If the following is due to an epoch ",
+                                         " change, use --override\n";
+                       }
+               }
+               elsif ($pkg->{'State'} eq "Installed" &&
+                          pkg_version_eq($pkg,$version)) {
+                       $ok = 0;
+                       $reason = "is up-to-date in the archive; doesn't need rebuilding";
+               }
+               elsif ($pkg->{'State'} eq "Needs-Build" &&
+                          version_less($version,$pkg->{'Version'})) {
+                       if ($opt_override) {
+                               print "$name: Warning: newer version $pkg->{'Version'} ".
+                                         "needs building, but overridden.";
+                       }
+                       else {
+                               $ok = 0;
+                               $reason = "newer version $pkg->{'Version'} needs building, ".
+                                                 "not $version";
+                       }
+               }
+               elsif (isin($pkg->{'State'},qw(Building Built Build-Attempted))) {
+                       if (version_less($pkg->{'Version'},$version)) {
+                               print "$name: Warning: Older version $pkg->{'Version'} ",
+                                     "is being built by $pkg->{'Builder'}\n";
+                               if ($pkg->{'Builder'} ne $user) {
+                                       send_mail( $pkg->{'Builder'},
+                                                          "package takeover in newer version",
+                                                          "You are building package '$name' in ".
+                                                          "version $version\n".
+                                                          "(as far as I'm informed).\n".
+                                                          "$user now has taken the newer ".
+                                                          "version $version for building.".
+                                                          "You can abort the build if you like.\n" );
+                               }
+                       }
+                       else {
+                               if ($opt_override) {
+                                       print "User $pkg->{'Builder'} had already ",
+                                             "taken the following package,\n",
+                                                 "but overriding this as you request:\n";
+                                       send_mail( $pkg->{'Builder'}, "package takeover",
+                                                          "The package '$name' (version $version) that ".
+                                                          "was locked by you\n".
+                                                          "has been taken over by $user\n" );
+                               }
+                               elsif ($pkg->{'Builder'} eq $user) {
+                                       print "$name: Note: already taken by you.\n";
+                                       print "$name: ok\n" if $verbose;
+                                       return;
+                               }
+                               else {
+                                       $ok = 0;
+                                       $reason = "already taken by $pkg->{'Builder'}";
+                                       $reason .= " (in newer version $pkg->{'Version'})"
+                                               if !version_eq($pkg->{'Version'}, $version);
+                               }
+                       }
+               }
+               elsif ($pkg->{'State'} =~ /^Failed/ &&
+                          pkg_version_eq($pkg, $version)) {
+                       if ($opt_override) {
+                               print "The following package previously failed ",
+                                         "(by $pkg->{'Builder'})\n",
+                                         "but overriding this as you request:\n";
+                               send_mail( $pkg->{'Builder'}, "failed package takeover",
+                                                  "The package '$name' (version $version) that ".
+                                                  "is locked by you\n".
+                                                  "and has failed previously has been taken over ".
+                                                  "by $user\n" )
+                                       if $pkg->{'Builder'} ne $user;
+                       }
+                       else {
+                               $ok = 0;
+                               $reason = "build of $version failed previously:\n    ";
+                               $reason .= join( "\n    ", split( "\n", $pkg->{'Failed'} ));
+                               $reason .= "\nalso the package doesn't need builing"
+                                       if $pkg->{'State'} eq 'Failed-Removed';
+                       }
+               }
+       }
+       if ($ok) {
+               my $ok = 'ok';
+               if ($pkg->{'Binary-NMU-Version'}) {
+                       print "$name: Warning: needs binary NMU $pkg->{'Binary-NMU-Version'}\n" .
+                             "$pkg->{'Binary-NMU-Changelog'}\n";
+                       $ok = 'aok';
+               } else {
+                       print "$name: Warning: Previous version failed!\n"
+                               if $pkg->{'Previous-State'} =~ /^Failed/ ||
+                                  $pkg->{'State'} =~ /^Failed/;
+               }
+               change_state( \$pkg, 'Building' );
+               $pkg->{'Package'} = $name;
+               $pkg->{'Version'} = $version;
+               $pkg->{'Builder'} = $user;
+               log_ta( $pkg, "--take" );
+               $db{$name} = $pkg;
+               print "$name: $ok\n" if $verbose;
+       }
+       else {
+               print "$name: NOT OK!\n  $reason\n";
+       }
+}
+
+sub add_one_attempted {
+       my $name = shift;
+       my $version = shift;
+       my $pkg = $db{$name};
+
+       if (!defined($pkg)) {
+               print "$name: not registered yet.\n";
+               return;
+       }
+
+       if ($pkg->{'State'} ne "Building" ) {
+               print "$name: not taken for building (state is $pkg->{'State'}). ",
+                         "Skipping.\n";
+               return;
+       }
+       if ($pkg->{'Builder'} ne $user) {
+               print "$name: not taken by you, but by $pkg->{'Builder'}. Skipping.\n";
+               return;
+       }
+       elsif ( !pkg_version_eq($pkg, $version) ) {
+               print "$name: version mismatch ".
+                         "$(pkg->{'Version'} ".
+                         "by $pkg->{'Builder'})\n";
+               return;
+       }
+
+       change_state( \$pkg, 'Build-Attempted' );
+       log_ta( $pkg, "--attempted" );
+       $db{$name} = $pkg;
+       print "$name: registered as uploaded\n" if $verbose;
+}
+
+sub add_one_built {
+       my $name = shift;
+       my $version = shift;
+       my $pkg = $db{$name};
+
+       if (!defined($pkg)) {
+               print "$name: not registered yet.\n";
+               return;
+       }
+
+       if ($pkg->{'State'} ne "Building" ) {
+               print "$name: not taken for building (state is $pkg->{'State'}). ",
+                         "Skipping.\n";
+               return;
+       }
+       if ($pkg->{'Builder'} ne $user) {
+               print "$name: not taken by you, but by $pkg->{'Builder'}. Skipping.\n";
+               return;
+       }
+       elsif ( !pkg_version_eq($pkg, $version) ) {
+               print "$name: version mismatch ".
+                         "$(pkg->{'Version'} ".
+                         "by $pkg->{'Builder'})\n";
+               return;
+       }
+       change_state( \$pkg, 'Built' );
+       log_ta( $pkg, "--built" );
+       $db{$name} = $pkg;
+       print "$name: registered as built\n" if $verbose;
+}
+
+sub add_one_uploaded {
+       my $name = shift;
+       my $version = shift;
+       my $pkg = $db{$name};
+
+       if (!defined($pkg)) {
+               print "$name: not registered yet.\n";
+               return;
+       }
+
+       if ($pkg->{'State'} eq "Uploaded" &&
+               pkg_version_eq($pkg,$version)) {
+               print "$name: already uploaded\n";
+               return;
+       }
+       if (!isin( $pkg->{'State'}, qw(Building Built Build-Attempted))) {
+               print "$name: not taken for building (state is $pkg->{'State'}). ",
+                         "Skipping.\n";
+               return;
+       }
+       if ($pkg->{'Builder'} ne $user) {
+               print "$name: not taken by you, but by $pkg->{'Builder'}. Skipping.\n";
+               return;
+       }
+       # strip epoch -- buildd-uploader used to go based on the filename.
+       # (to remove at some point)
+       my $pkgver;
+       ($pkgver = $pkg->{'Version'}) =~ s/^\d+://;
+       $version =~ s/^\d+://; # for command line use
+       if ($pkg->{'Binary-NMU-Version'} ) {
+               my $nmuver = binNMU_version($pkgver, $pkg->{'Binary-NMU-Version'});
+               if (!version_eq( $nmuver, $version )) {
+                       print "$name: version mismatch ($nmuver registered). ",
+                                 "Skipping.\n";
+                       return;
+               }
+       } elsif (!version_eq($pkgver, $version)) {
+               print "$name: version mismatch ($pkg->{'Version'} registered). ",
+                         "Skipping.\n";
+               return;
+       }
+
+       change_state( \$pkg, 'Uploaded' );
+       log_ta( $pkg, "--uploaded" );
+       $db{$name} = $pkg;
+       print "$name: registered as uploaded\n" if $verbose;
+}
+
+sub add_one_failed {
+       my $name = shift;
+       my $version = shift;
+       my ($state, $cat);
+       my $pkg = $db{$name};
+
+       if (!defined($pkg)) {
+               print "$name: not registered yet.\n";
+               return;
+       }
+       $state = $pkg->{'State'};
+
+       if ($state eq "Not-For-Us") {
+               print "$name: not suitable for this architecture anyway. Skipping.\n";
+               return;
+       }
+       elsif ($state eq "Failed-Removed") {
+               print "$name: failed previously and doesn't need building. Skipping.\n";
+               return;
+       }
+       elsif ($state eq "Installed") {
+               print "$name: Is already installed in archive. Skipping.\n";
+               return;
+       }
+       elsif ($pkg->{'Builder'} &&
+                  (($user ne $pkg->{'Builder'}) &&
+                   !($pkg->{'Builder'} =~ /^(\w+)-\w+/ && $1 eq $user))) {
+               print "$name: not taken by you, but by ".
+                         "$pkg->{'Builder'}. Skipping.\n";
+               return;
+       }
+       elsif ( !pkg_version_eq($pkg, $version) ) {
+               print "$name: version mismatch ".
+                         "$(pkg->{'Version'} ".
+                         "by $pkg->{'Builder'})\n";
+               return;
+       }
+
+       $cat = $category;
+       if (!$cat && $fail_reason =~ /^\[([^\]]+)\]/) {
+               $cat = $1;
+               $cat = $short_category{$cat} if exists $short_category{$cat};
+               if (!isin( $cat, values %short_category )) {
+                       print "$name: Warning: unknown category $cat; discarded\n";
+                       $cat = "";
+               }
+               $fail_reason =~ s/^\[[^\]]+\][ \t]*\n*//;
+       }
+
+       if ($state eq "Needs-Build") {
+               print "$name: Warning: not registered for building previously, ".
+                         "but processing anyway.\n";
+       }
+       elsif ($state eq "Uploaded") {
+               print "$name: Warning: marked as uploaded previously, ".
+                         "but processing anyway.\n";
+       }
+       elsif ($state eq "Dep-Wait") {
+               print "$name: Warning: marked as waiting for dependencies, ".
+                         "but processing anyway.\n";
+       }
+       elsif ($state eq "Failed") {
+               print "$name: already registered as failed; will append new message\n"
+                       if $fail_reason;
+               print "$name: already registered as failed; changing category\n"
+                       if $cat;
+       }
+
+       if (($cat eq "reminder-sent" || $cat eq "nmu-offered") &&
+               exists $pkg->{'Failed-Category'} &&
+               $pkg->{'Failed-Category'} ne $cat) {
+               (my $action = $cat) =~ s/-/ /;
+               $fail_reason .= "\n$short_date: $action";
+       }
+
+       change_state( \$pkg, 'Failed' );
+       $pkg->{'Builder'} = $user;
+       $pkg->{'Failed'} .= "\n" if $pkg->{'Failed'};
+       $pkg->{'Failed'} .= $fail_reason;
+       $pkg->{'Failed-Category'} = $cat if $cat;
+       if (defined $pkg->{'PermBuildPri'}) {
+               $pkg->{'BuildPri'} = $pkg->{'PermBuildPri'};
+       } else {
+               delete $pkg->{'BuildPri'};
+       }
+       log_ta( $pkg, "--failed" );
+       $db{$name} = $pkg;
+       print "$name: registered as failed\n" if $verbose;
+}
+
+sub add_one_notforus {
+       my $name = shift;
+       my $version = shift;
+       my $pkg = $db{$name};
+
+       if ($pkg->{'State'} eq 'Not-For-Us') {
+               # reset Not-For-Us state in case it's called twice; this is
+               # the only way to get a package out of this state...
+               # There is no really good state in which such packages should
+               # be put :-( So use Failed for now.
+               change_state( \$pkg, 'Failed' );
+               $pkg->{'Package'} = $name;
+               $pkg->{'Failed'} = "Was Not-For-Us previously";
+               delete $pkg->{'Builder'};
+               delete $pkg->{'Depends'};
+               log_ta( $pkg, "--no-build(rev)" );
+               print "$name: now not unsuitable anymore\n";
+
+               send_mail( $conf::notforus_maint,
+                                  "$name moved out of Not-For-Us state",
+                                  "The package '$name' has been moved out of the Not-For-Us ".
+                                  "state by $user.\n".
+                                  "It should probably also be removed from ".
+                                  "Packages-arch-specific or\n".
+                                  "the action was wrong.\n" )
+                       if $conf::notforus_maint;
+       }
+       else {
+               change_state( \$pkg, 'Not-For-Us' );
+               $pkg->{'Package'} = $name;
+               delete $pkg->{'Builder'};
+               delete $pkg->{'Depends'};
+               delete $pkg->{'BuildPri'};
+               delete $pkg->{'Binary-NMU-Version'};
+               delete $pkg->{'Binary-NMU-Changelog'};
+               log_ta( $pkg, "--no-build" );
+               print "$name: registered as unsuitable\n" if $verbose;
+
+               send_mail( $conf::notforus_maint,
+                                  "$name set to Not-For-Us",
+                                  "The package '$name' has been set to state Not-For-Us ".
+                                  "by $user.\n".
+                                  "It should probably also be added to ".
+                                  "Packages-arch-specific or\n".
+                                  "the Not-For-Us state is wrong.\n" )
+                       if $conf::notforus_maint;
+       }
+       $db{$name} = $pkg;
+}
+
+sub add_one_needsbuild {
+       my $name = shift;
+       my $version = shift;
+       my $state;
+       my $pkg = $db{$name};
+
+       if (!defined($pkg)) {
+               print "$name: not registered; can't give back.\n";
+               return;
+       }
+       $state = $pkg->{'State'};
+
+       if ($state eq "Dep-Wait") {
+               if ($opt_override) {
+                       print "$name: Forcing source dependency list to be cleared\n";
+               }
+               else {
+                       print "$name: waiting for source dependencies. Skipping\n",
+                                 "  (use --override to clear dependency list and ",
+                                 "give back anyway)\n";
+                       return;
+               }
+       }
+       elsif (!isin( $state, qw(Building Built Build-Attempted))) {
+               print "$name: not taken for building (state is $state).";
+               if ($opt_override) {
+                       print "\n$name: Forcing give-back\n";
+               }
+               else {
+                       print " Skipping.\n";
+                       return;
+               }
+       }
+       if (defined ($pkg->{'Builder'}) && $user ne $pkg->{'Builder'} &&
+                   !($pkg->{'Builder'} =~ /^(\w+)-\w+/ && $1 eq $user)) {
+               print "$name: not taken by you, but by ".
+                         "$pkg->{'Builder'}. Skipping.\n";
+               return;
+       }
+       if (!pkg_version_eq($pkg, $version)) {
+               print "$name: version mismatch ($pkg->{'Version'} registered). ",
+                         "Skipping.\n";
+               return;
+       }
+       change_state( \$pkg, 'Needs-Build' );
+       delete $pkg->{'Builder'};
+       delete $pkg->{'Depends'};
+       log_ta( $pkg, "--give-back" );
+       $db{$name} = $pkg;
+       print "$name: given back\n" if $verbose;
+}
+
+sub set_one_binnmu {
+       my $name = shift;
+       my $version = shift;
+       my $pkg = $db{$name};
+       my $state;
+
+       if (!defined($pkg)) {
+               print "$name: not registered; can't register for binNMU.\n";
+               return;
+       }
+       my $db_ver = $pkg->{'Version'};
+
+       if (!version_eq($db_ver, $version)) {
+               print "$name: version mismatch ($db_ver registered). ",
+                         "Skipping.\n";
+               return;
+       }
+       $state = $pkg->{'State'};
+
+       if (defined $pkg->{'Binary-NMU-Version'}) {
+               if ($binNMUver == 0) {
+                       change_state( \$pkg, 'Installed' );
+                       delete $pkg->{'Builder'};
+                       delete $pkg->{'Depends'};
+                       delete $pkg->{'Binary-NMU-Version'};
+                       delete $pkg->{'Binary-NMU-Changelog'};
+               } elsif ($binNMUver <= $pkg->{'Binary-NMU-Version'}) {
+                       print "$name: already building binNMU $pkg->{'Binary-NMU-Version'}\n";
+                       return;
+               } else {
+                       $pkg->{'Binary-NMU-Version'} = $binNMUver;
+                       $pkg->{'Binary-NMU-Changelog'} = $fail_reason;
+                       $pkg->{'Notes'} = 'out-of-date';
+                       $pkg->{'BuildPri'} = $pkg->{'PermBuildPri'}
+                               if (defined $pkg->{'PermBuildPri'});
+               }
+               log_ta( $pkg, "--binNMU" );
+               $db{$name} = $pkg;
+               return;
+       } elsif ($binNMUver == 0) {
+                print "${name}_$version: no scheduled binNMU to cancel.\n";
+                return;
+        }
+
+       if ($state ne 'Installed') {
+               print "${name}_$version: not installed; can't register for binNMU.\n";
+               return;
+       }
+
+       my $fullver = binNMU_version($version,$binNMUver);
+       if ( version_lesseq( $fullver, $pkg->{'Installed-Version'} ) )
+       {
+               print "$name: binNMU $fullver is not newer than current version $pkg->{'Installed-Version'}\n";
+               return;
+       }
+
+       change_state( \$pkg, 'Needs-Build' );
+       delete $pkg->{'Builder'};
+       delete $pkg->{'Depends'};
+       $pkg->{'Binary-NMU-Version'} = $binNMUver;
+       $pkg->{'Binary-NMU-Changelog'} = $fail_reason;
+       $pkg->{'Notes'} = 'out-of-date';
+       log_ta( $pkg, "--binNMU" );
+       $db{$name} = $pkg;
+       print "${name}: registered for binNMU $fullver\n" if $verbose;
+}
+
+sub set_one_buildpri {
+       my $name = shift;
+       my $version = shift;
+       my $key = shift;
+       my $pkg = $db{$name};
+       my $state;
+
+       if (!defined($pkg)) {
+               print "$name: not registered; can't set priority.\n";
+               return;
+       }
+       $state = $pkg->{'State'};
+
+       if ($state eq "Not-For-Us") {
+               print "$name: not suitable for this architecture. Skipping.\n";
+               return;
+       } elsif ($state eq "Failed-Removed") {
+               print "$name: failed previously and doesn't need building. Skipping.\n";
+               return;
+        }
+       if (!pkg_version_eq($pkg, $version)) {
+               print "$name: version mismatch ($pkg->{'Version'} registered). ",
+                         "Skipping.\n";
+               return;
+       }
+       if ( $build_priority == 0 ) {
+               delete $pkg->{'BuildPri'}
+                       if $key eq 'PermBuildPri' and defined $pkg->{'BuildPri'}
+                       and $pkg->{'BuildPri'} == $pkg->{$key};
+               delete $pkg->{$key};
+       } else {
+               $pkg->{'BuildPri'} = $build_priority
+                       if $key eq 'PermBuildPri';
+               $pkg->{$key} = $build_priority;
+       }
+       $db{$name} = $pkg;
+       print "$name: set to build priority $build_priority\n" if $verbose;
+}
+
+sub add_one_depwait {
+       my $name = shift;
+       my $version = shift;
+       my $state;
+       my $pkg = $db{$name};
+
+       if (!defined($pkg)) {
+               print "$name: not registered yet.\n";
+               return;
+       }
+       $state = $pkg->{'State'};
+
+       if ($state eq "Dep-Wait") {
+               print "$name: merging with previously registered dependencies\n";
+       }
+       
+       if (isin( $state, qw(Needs-Build Failed))) {
+               print "$name: Warning: not registered for building previously, ".
+                         "but processing anyway.\n";
+       }
+       elsif ($state eq "Not-For-Us") {
+               print "$name: not suitable for this architecture anyway. Skipping.\n";
+               return;
+       }
+       elsif ($state eq "Failed-Removed") {
+               print "$name: failed previously and doesn't need building. Skipping.\n";
+               return;
+       }
+       elsif ($state eq "Installed") {
+               print "$name: Is already installed in archive. Skipping.\n";
+               return;
+       }
+       elsif ($state eq "Uploaded") {
+               print "$name: Is already uploaded. Skipping.\n";
+               return;
+       }
+       elsif ($pkg->{'Builder'} &&
+                  $user ne $pkg->{'Builder'}) {
+               print "$name: not taken by you, but by ".
+                         "$pkg->{'Builder'}. Skipping.\n";
+               return;
+       }
+       elsif ( !pkg_version_eq($pkg,$version)) {
+               print "$name: version mismatch ".
+                         "($pkg->{'Version'} ".
+                         "by $pkg->{'Builder'})\n";
+               return;
+       }
+       elsif ($fail_reason =~ /^\s*$/ ||
+                  !parse_deplist( $fail_reason, 1 )) {
+               print "$name: Bad dependency list\n";
+               return;
+       }
+       change_state( \$pkg, 'Dep-Wait' );
+       $pkg->{'Builder'} = $user;
+       if (defined $pkg->{'PermBuildPri'}) {
+               $pkg->{'BuildPri'} = $pkg->{'PermBuildPri'};
+       } else {
+               delete $pkg->{'BuildPri'};
+       }
+       my $deplist = parse_deplist( $pkg->{'Depends'} );
+       my $new_deplist = parse_deplist( $fail_reason );
+       # add new dependencies, maybe overwriting old entries
+       foreach (keys %$new_deplist) {
+               $deplist->{$_} = $new_deplist->{$_};
+       }
+       $pkg->{'Depends'} = build_deplist($deplist);
+       log_ta( $pkg, "--dep-wait" );
+       $db{$name} = $pkg;
+       print "$name: registered as waiting for dependencies\n" if $verbose;
+}
+
+
+sub parse_sources {
+       my %pkgs;
+       my %srcver;
+       my $name;
+       my $full = shift;
+
+       local($/) = ""; # read in paragraph mode
+       while( <> ) {
+               my( $version, $arch, $section, $priority, $builddep, $buildconf, $binaries );
+               s/\s*$//m;
+               /^Package:\s*(\S+)$/mi and $name = $1;
+               /^Version:\s*(\S+)$/mi and $version = $1;
+               /^Architecture:\s*(\S+)$/mi and $arch = $1;
+               /^Section:\s*(\S+)$/mi and $section = $1;
+               /^Priority:\s*(\S+)$/mi and $priority = $1;
+               /^Build-Depends:\s*(.*)$/mi and $builddep = $1;
+               /^Build-Conflicts:\s*(.*)$/mi and $buildconf = $1;
+                /^Binary:\s*(.*)$/mi and $binaries = $1;
+
+               next if (defined $srcver{$name} and version_less( $version, $srcver{$name} ));
+               $srcver{$name} = $version;
+               if ($buildconf) {
+                   $buildconf = join( ", ", map { "!$_" } split( /\s*,\s*/, $buildconf ));
+                   if ($builddep) {
+                       $builddep .= "," . $buildconf;
+                   } else {
+                       $builddep = $buildconf;
+                   }
+               }
+
+               $pkgs{$name}{'dep'} = defined $builddep ? $builddep : "";
+               $pkgs{$name}{'ver'} = $version;
+               $pkgs{$name}{'bin'} = $binaries;
+               my $pkg = $db{$name};
+
+               if (defined $pkg) {
+                       my $change = 0;
+
+                       if ($arch eq "all" && !version_less( $version, $pkg->{'Version'} )) {
+                               # package is now Arch: all, delete it from db
+                               change_state( \$pkg, 'deleted' );
+                               log_ta( $pkg, "--merge-sources" );
+                               print "$name ($pkg->{'Version'}): deleted ".
+                                         "from database, because now Arch: all\n"
+                                                 if $verbose;
+                               delete $db{$name};
+                               next;
+                       }
+
+                       # The "Version" should always be the source version --
+                       # not a possible binNMU version number.
+                       $pkg->{'Version'} = $version, $change++
+                               if ($pkg->{'State'} eq 'Installed' and
+                               !version_eq( $pkg->{'Version'}, $version));
+                       # Always update priority and section, if available
+                       $pkg->{'Priority'} = $priority, $change++
+                               if defined $priority and (not defined($pkg->{'Priority'}) or $pkg->{'Priority'} ne $priority);
+
+                       $pkg->{'Section'} = $section, $change++
+                               if defined $section and (not defined($pkg->{'Section'}) or $pkg->{'Section'} ne $section);
+                       $db{$name} = $pkg if $change;
+               }
+       }
+        # Now that we only have the latest source version, build the list
+        # of binary packages from the Sources point of view
+        foreach $name (keys %pkgs) {
+            foreach my $bin (split( /\s*,\s*/, $pkgs{$name}{'bin'} ) ) {
+                $merge_binsrc{$bin} = $name;
+            }
+        }
+       # remove installed packages that no longer have source available
+       # or binaries installed
+       foreach $name (keys %db) {
+               next if $name =~ /^_/;
+               my $pkg = $db{$name};
+               if (not defined($pkgs{$name})) {
+                       change_state( \$pkg, 'deleted' );
+                       log_ta( $pkg, "--merge-sources" );
+                       print "$name ($pkg->{'Version'}): ".
+                                 "deleted from database, because ".
+                                 "not in Sources anymore\n"
+                                         if $verbose;
+                       delete $db{$name};
+               } else {
+                       next if !isin( $pkg->{'State'}, qw(Installed) );
+                       if ($full && not defined $merge_srcvers{$name}) {
+                            change_state( \$pkg, 'deleted' );
+                            log_ta( $pkg, "--merge-sources" );
+                            print "$name ($pkg->{'Version'}): ".
+                                      "deleted from database, because ".
+                                      "binaries don't exist anymore\n"
+                                              if $verbose;
+                            delete $db{$name};
+                        } elsif ($full && version_less( $merge_srcvers{$name}, $pkg->{'Version'})) {
+                            print "$name ($pkg->{'Version'}): ".
+                                      "package is Installed but binaries are from ".
+                                      $merge_srcvers{$name}. "\n"
+                                              if $verbose;
+                        }
+                }
+       }
+       return \%pkgs;
+}
+
+# This function looks through a Packages file and sets the state of
+# packages to 'Installed'
+sub parse_packages {
+       my $installed;
+
+       local($/) = ""; # read in paragraph mode
+       while( <> ) {
+               my( $name, $version, $depends, $source, $sourcev, $architecture, $provides, $binaryv, $binnmu );
+               s/\s*$//m;
+               /^Package:\s*(\S+)$/mi and $name = $1;
+               /^Version:\s*(\S+)$/mi and $version = $1;
+               /^Depends:\s*(.*)$/mi and $depends = $1;
+               /^Source:\s*(\S+)(\s*\((\S+)\))?$/mi and ($source,$sourcev) = ($1, $3);
+               /^Architecture:\s*(\S+)$/mi and $architecture = $1;
+               /^Provides:\s*(.*)$/mi and $provides = $1;
+               next if !$name || !$version;
+               next if ($arch ne $architecture and $architecture ne "all");
+               next if (defined ($installed->{$name}) and $installed->{$name}{'Version'} ne "" and
+                       version_lesseq( $version, $installed->{$name}{'Version'} ));
+               $installed->{$name}{'Version'} = $version;
+               $installed->{$name}{'Depends'} = $depends;
+               $installed->{$name}{'all'} = 1 if $architecture eq "all";
+               undef $installed->{$name}{'Provider'};
+               $installed->{$name}{'Source'} = $source ? $source : $name;
+               if ($provides) {
+                    foreach (split( /\s*,\s*/, $provides )) {
+                        if (not defined ($installed->{$_})) {
+                            $installed->{$_}{'Version'} = "";
+                            $installed->{$_}{'Provider'} = $name;
+                        }
+                    }
+               }
+               if ( $version =~ /\+b(\d+)$/ ) {
+                    $binnmu = $1;
+               }
+               $version = $sourcev if $sourcev;
+               $binaryv = $version;
+               $binaryv =~ s/\+b\d+$//;
+               $installed->{$name}{'Sourcev'} = $sourcev ? $sourcev : $binaryv;
+               $binaryv .= "+b$binnmu" if defined($binnmu);
+
+               next if $architecture ne $arch;
+               $name = $source if $source;
+               next if defined($merge_srcvers{$name}) and $merge_srcvers{$name} eq $version;
+               $merge_srcvers{$name} = $version;
+
+               my $pkg = $db{$name};
+
+               if (defined $pkg) {
+                       if (isin( $pkg->{'State'}, qw(Not-For-Us)) ||
+                               (isin($pkg->{'State'}, qw(Installed)) &&
+                                version_lesseq($binaryv, $pkg->{'Installed-Version'}))) {
+                               print "Skipping $name because State == $pkg->{'State'}\n"
+                                       if $verbose >= 2;
+                               next;
+                       }
+                       if ($pkg->{'Binary-NMU-Version'} ) {
+                               my $nmuver = binNMU_version($pkg->{'Version'}, $pkg->{'Binary-NMU-Version'});
+                               if (version_less( $binaryv, $nmuver )) {
+                                       print "Skipping $name ($version) because have newer ".
+                                               "version ($nmuver) in db.\n"
+                                                       if $verbose >= 2;
+                                       next;
+                               }
+                       } elsif (version_less($version, $pkg->{'Version'})) {
+                               print "Skipping $name ($version) because have newer ".
+                                       "version ($pkg->{'Version'}) in db.\n"
+                                               if $verbose >= 2;
+                               next;
+                       }
+
+                       if (!pkg_version_eq($pkg, $version) &&
+                          $pkg->{'State'} ne "Installed") {
+                               warn "Warning: $name: newer version than expected appeared ".
+                                        "in archive ($version vs. $pkg->{'Version'})\n";
+                               delete $pkg->{'Builder'};
+                       }
+
+                       if (!isin( $pkg->{'State'}, qw(Uploaded) )) {
+                               warn "Warning: Package $name was not in uploaded state ".
+                                        "before (but in '$pkg->{'State'}').\n";
+                               delete $pkg->{'Builder'};
+                               delete $pkg->{'Depends'};
+                       }
+               } else {
+                       $pkg = {};
+                       $pkg->{'Version'} = $version;
+               }
+               
+               change_state( \$pkg, 'Installed' );
+               $pkg->{'Package'} = $name;
+               $pkg->{'Installed-Version'} = $binaryv;
+               if (defined $pkg->{'PermBuildPri'}) {
+                       $pkg->{'BuildPri'} = $pkg->{'PermBuildPri'};
+               } else {
+                       delete $pkg->{'BuildPri'};
+               }
+               $pkg->{'Version'} = $version
+                       if version_less( $pkg->{'Version'}, $version);
+               delete $pkg->{'Binary-NMU-Version'};
+               delete $pkg->{'Binary-NMU-Changelog'};
+               log_ta( $pkg, "--merge-packages" );
+               $db{$name} = $pkg;
+               print "$name ($version) is up-to-date now.\n" if $verbose;
+       }
+
+       check_dep_wait( "--merge-packages", $installed );
+       return $installed;
+}
+
+sub pretend_avail {
+       my ($package, $name, $version, $installed);
+       
+       foreach $package (@_) {
+               $package =~ s,^.*/,,; # strip path
+               $package =~ s/\.(dsc|diff\.gz|tar\.gz|deb)$//; # strip extension
+               $package =~ s/_[\w\d]+\.changes$//; # strip extension
+               if ($package =~ /^([\w\d.+-]+)_([\w\d:.+~-]+)/) {
+                       ($name,$version) = ($1,$2);
+               }
+               else {
+                       warn "$package: can't extract package name and version ".
+                                "(bad format)\n";
+                       next;
+               }
+               $installed->{$name}{'Version'} = $version;
+       }
+
+       check_dep_wait( "--pretend-avail", $installed );
+}
+
+sub check_dep_wait {
+       my $action = shift;
+       my $installed = shift;
+       
+       # check all packages in state Dep-Wait if dependencies are all
+       # available now
+       my $name;
+       foreach $name (keys %db) {
+               next if $name =~ /^_/;
+               my $pkg = $db{$name};
+               next if $pkg->{'State'} ne "Dep-Wait";
+               my $deps = $pkg->{'Depends'};
+               if (!$deps) {
+                       print "$name: was in state Dep-Wait, but with empty ",
+                                 "dependencies!\n";
+                       goto make_needs_build;
+               }
+               my $deplist = parse_deplist($deps);
+               my $new_deplist;
+               my $allok = 1;
+               my @removed_deps;
+               foreach (keys %$deplist) {
+                       if (!exists $installed->{$_} ||
+                               ($deplist->{$_}->{'Rel'} && $deplist->{$_}->{'Version'} &&
+                                !version_compare( $installed->{$_}{'Version'},
+                                                                  $deplist->{$_}->{'Rel'},
+                                                                  $deplist->{$_}->{'Version'}))) {
+                               $allok = 0;
+                               $new_deplist->{$_} = $deplist->{$_};
+                       }
+                       else {
+                               push( @removed_deps, $_ );
+                       }
+               }
+               if ($allok) {
+                 make_needs_build:
+                       change_state( \$pkg, 'Needs-Build' );
+                       log_ta( $pkg, $action );
+                       delete $pkg->{'Builder'};
+                       delete $pkg->{'Depends'};
+                       print "$name ($pkg->{'Version'}) has all ",
+                                 "dependencies available now\n" if $verbose;
+                       $new_vers{$name}++;
+                       $db{$name} = $pkg;
+               }
+               elsif (@removed_deps) {
+                       $pkg->{'Depends'} = build_deplist( $new_deplist );
+                       print "$name ($pkg->{'Version'}): some dependencies ",
+                                 "(@removed_deps) available now, but not all yet\n"
+                               if $verbose;
+                       $db{$name} = $pkg;
+               }
+       }
+}
+
+# This function accepts quinn-diff output (either from a file named on
+# the command line, or on stdin) and sets the packages named there to
+# state 'Needs-Build'.
+sub parse_quinn_diff {
+       my $partial = shift;
+       my %quinn_pkgs;
+       my $dubious = "";
+       
+       while( <> ) {
+               my $change = 0;
+               next if !m,^([-\w\d/]*)/                        # section
+                              ([-\w\d.+]+)_                    # package name
+                                  ([\w\d:.~+-]+)\.dsc\s*       # version
+                                  \[([^:]*):                           # priority
+                                  ([^]]+)\]\s*$,x;                     # rest of notes
+               my($section,$name,$version,$priority,$notes) = ($1, $2, $3, $4, $5);
+               $quinn_pkgs{$name}++;
+               $section ||= "unknown";
+               $priority ||= "unknown";
+               $priority = "unknown" if $priority eq "-";
+               $priority = "standard" if ($name eq "debian-installer");
+
+               my $pkg = $db{$name};
+
+               # Always update section and priority.
+               if (defined($pkg)) {
+
+                       $pkg->{'Section'}  = $section, $change++ if not defined
+                               $pkg->{'Section'} or $section ne "unknown";
+                       $pkg->{'Priority'} = $priority, $change++ if not defined
+                               $pkg->{'Priority'} or $priority ne "unknown";
+               }
+
+               if (defined($pkg) &&
+                       $pkg->{'State'} =~ /^Dep-Wait/ &&
+                       version_less( $pkg->{'Version'}, $version )) {
+                       change_state( \$pkg, 'Dep-Wait' );
+                       $pkg->{'Version'}  = $version;
+                       delete $pkg->{'Binary-NMU-Version'};
+                       delete $pkg->{'Binary-NMU-Changelog'};
+                       log_ta( $pkg, "--merge-quinn" );
+                       $change++;
+                       print "$name ($version) still waiting for dependencies.\n"
+                               if $verbose;
+               }
+               elsif (defined($pkg) &&
+                          $pkg->{'State'} =~ /-Removed$/ &&
+                          version_eq($pkg->{'Version'}, $version)) {
+                       # reinstantiate a package that has been removed earlier
+                       # (probably due to a quinn-diff malfunction...)
+                       my $newstate = $pkg->{'State'};
+                       $newstate =~ s/-Removed$//;
+                       change_state( \$pkg, $newstate );
+                       $pkg->{'Version'}  = $version;
+                       $pkg->{'Notes'}    = $notes;
+                       log_ta( $pkg, "--merge-quinn" );
+                       $change++;
+                       print "$name ($version) reinstantiated to $newstate.\n"
+                               if $verbose;
+               }
+               elsif (defined($pkg) &&
+                          $pkg->{'State'} eq "Not-For-Us" &&
+                          version_less( $pkg->{'Version'}, $version )) {
+                       # for Not-For-Us packages just update the version etc., but
+                       # keep the state
+                       change_state( \$pkg, "Not-For-Us" );
+                       $pkg->{'Package'}  = $name;
+                       $pkg->{'Version'}  = $version;
+                       $pkg->{'Notes'}    = $notes;
+                       delete $pkg->{'Builder'};
+                       log_ta( $pkg, "--merge-quinn" );
+                       $change++;
+                       print "$name ($version) still Not-For-Us.\n" if $verbose;
+               }
+               elsif (!defined($pkg) ||
+                          $pkg->{'State'} ne "Not-For-Us" &&
+                          (version_less( $pkg->{'Version'}, $version ) ||
+                          ($pkg->{'State'} eq "Installed" && version_less($pkg->{'Installed-Version'}, $version)))) {
+
+                       if (defined( $pkg->{'State'} ) && isin( $pkg->{'State'}, qw(Building Built Build-Attempted))) {
+                               send_mail( $pkg->{'Builder'},
+                                                  "new version of $name (dist=$distribution)",
+                                                  "As far as I'm informed, you're currently ".
+                                                  "building the package $name\n".
+                                                  "in version $pkg->{'Version'}.\n\n".
+                                                  "Now there's a new source version $version. ".
+                                                  "If you haven't finished\n".
+                                                  "compiling $name yet, you can stop it to ".
+                                                  "save some work.\n".
+                                                  "Just to inform you...\n".
+                                                  "(This is an automated message)\n" );
+                               print "$name: new version ($version) while building ".
+                                         "$pkg->{'Version'} -- sending mail ".
+                                         "to builder ($pkg->{'Builder'})\n"
+                                 if $verbose;
+                       }
+                       change_state( \$pkg, 'Needs-Build' );
+                       $pkg->{'Package'}  = $name;
+                       $pkg->{'Version'}  = $version;
+                       $pkg->{'Section'}  = $section;
+                       $pkg->{'Priority'} = $priority;
+                       $pkg->{'Notes'}    = $notes;
+                       delete $pkg->{'Builder'};
+                       delete $pkg->{'Binary-NMU-Version'};
+                       delete $pkg->{'Binary-NMU-Changelog'};
+                       log_ta( $pkg, "--merge-quinn" );
+                       $new_vers{$name}++;
+                       $change++;
+                       print "$name ($version) needs rebuilding now.\n" if $verbose;
+               }
+               elsif (defined($pkg) &&
+                          !version_eq( $pkg->{'Version'}, $version ) &&
+                          isin( $pkg->{'State'}, qw(Installed Not-For-Us) )) {
+                       print "$name: skipping because version in db ".
+                                 "($pkg->{'Version'}) is >> than ".
+                                 "what quinn-diff says ($version) ".
+                                 "(state is $pkg->{'State'})\n"
+                                         if $verbose;
+                       $dubious .= "$pkg->{'State'}: ".
+                                               "db ${name}_$pkg->{'Version'} >> ".
+                                               "quinn $version\n" if !$partial;
+               }
+               elsif ($verbose >= 2) {
+                       if ($pkg->{'State'} eq "Not-For-Us") {
+                               print "Skipping $name because State == ".
+                                         "$pkg->{'State'}\n";
+                       }
+                       elsif (!version_less($pkg->{'Version'}, $version)) {
+                               print "Skipping $name because version in db ".
+                                         "($pkg->{'Version'}) is >= than ".
+                                         "what quinn-diff says ($version)\n";
+                       }
+               }
+               $db{$name} = $pkg if $change;
+       }
+
+       if ($dubious) {
+               send_mail( $conf::db_maint,
+                                  "Dubious versions in $distribution $conf::dbbase database",
+                                  "The following packages have a newer version in the ".
+                                  "wanna-build database\n".
+                                  "than what quinn-diff says, and this is strange for ".
+                                  "their state\n".
+                                  "It could be caused by a lame mirror, or the version ".
+                                  "in the database\n".
+                                  "is wrong.\n\n".
+                                  $dubious );
+       }
+
+       # Now re-check the DB for packages in states Needs-Build, Failed,
+       # or Dep-Wait and remove them if they're not listed anymore by quinn-diff.
+       if ( !$partial ) {
+               my $name;
+               foreach $name (keys %db) {
+                       next if $name =~ /^_/;
+                       my $pkg = $db{$name};
+                       next if defined $pkg->{'Binary-NMU-Version'};
+                       next if !isin( $pkg->{'State'},
+                                                  qw(Needs-Build Building Built Build-Attempted Uploaded Failed Dep-Wait) );
+                       my $virtual_delete = $pkg->{'State'} eq 'Failed';
+                                                                
+                       if (!$quinn_pkgs{$name}) {
+                               change_state( \$pkg, $virtual_delete ?
+                                                         $pkg->{'State'}."-Removed" :
+                                                         'deleted' );
+                               log_ta( $pkg, "--merge-quinn" );
+                               print "$name ($pkg->{'Version'}): ".
+                                         ($virtual_delete ? "(virtually) " : "") . "deleted ".
+                                         "from database, because not in quinn-diff anymore\n"
+                                                 if $verbose;
+                               if ($virtual_delete) {
+                                   $db{$name} = $pkg;
+                               } else {
+                                   delete $db{$name};
+                               }
+                       }
+               }
+       }
+}
+
+sub send_reupload_mail {
+       my $to = shift;
+       my $pkg = shift;
+       my $version = shift;
+       my $dist = shift;
+       my $other_dist = shift;
+
+       send_mail( $to,
+                          "Please reupload ${pkg}_${'Version'} for $dist",
+                          "You have recently built (or are currently building)\n".
+                          "${pkg}_${'Version'} for $other_dist.\n".
+                          "This version is now also needed in the $dist distribution.\n".
+                          "Please reupload the files now present in the Debian archive\n".
+                          "(best with buildd-reupload).\n" );
+}
+
+
+# for sorting priorities and sections
+BEGIN {
+       %prioval = ( required             => -5,
+                                important            => -4,
+                                standard             => -3,
+                                optional             => -2,
+                                extra                => -1,
+                                unknown              => -1 );
+       %sectval = ( 
+                                libs                   => -200,
+                                'debian-installer'     => -199,
+                                base                   => -198,
+                                devel                  => -197,
+                                shells                 => -196,
+                                perl                   => -195,
+                                python                 => -194,
+                                graphics               => -193,
+                                admin                  => -192,
+                                utils                  => -191,
+                                x11                    => -190,
+                                editors                => -189,
+                                net                    => -188,
+                                mail                   => -187,
+                                news                   => -186,
+                                tex                    => -185,
+                                text                   => -184,
+                                web                    => -183,
+                                doc                    => -182,
+                                interpreters           => -181,
+                                gnome                  => -180,
+                                kde                    => -179,
+                                games                  => -178,
+                                misc                   => -177,
+                                otherosfs              => -176,
+                                oldlibs                => -175,
+                                libdevel               => -174,
+                                sound                  => -173,
+                                math                   => -172,
+                                science                => -171,
+                                comm                   => -170,
+                                electronics            => -169,
+                                hamradio               => -168,
+                                embedded               => -166,
+       );
+       foreach my $i (keys %sectval) {
+               $sectval{"contrib/$i"} = $sectval{$i}+40;
+               $sectval{"non-free/$i"} = $sectval{$i}+80;
+       }
+       $sectval{'unknown'}     = -165;
+
+       %catval =  ( "none"                           => -20,
+                                "uploaded-fixed-pkg" => -19,
+                                "fix-expected"       => -18,
+                                "reminder-sent"      => -17,
+                                "nmu-offered"        => -16,
+                                "easy"               => -15,
+                                "medium"                     => -14,
+                                "hard"                   => -13,
+                                "compiler-error"     => -12 );
+}
+
+sub sort_list_func {
+       my( $letter, $x, $ax, $bx );
+
+       foreach $letter (split( "", $list_order )) {
+         SWITCH: foreach ($letter) {
+                 /P/ && do {
+                       $x = $b->{'BuildPri'} <=> $a->{'BuildPri'};
+                       return $x if $x != 0;
+                       last SWITCH;
+                 };
+                 /p/ && do {
+                         $x = $prioval{$a->{'Priority'}} <=> $prioval{$b->{'Priority'}};
+                         return $x if $x != 0;
+                         last SWITCH;
+                 };
+                 /s/ && do {
+                         $x = $sectval{$a->{'Section'}} <=> $sectval{$b->{'Section'}};
+                         return $x if $x != 0;
+                         last SWITCH;
+                 };
+                 /n/ && do {
+                         $x = $a->{'Package'} cmp $b->{'Package'};
+                         return $x if $x != 0;
+                         last SWITCH;
+                 };
+                 /b/ && do {
+                         $x = $a->{'Builder'} cmp $b->{'Builder'};
+                         return $x if $x != 0;
+                         last SWITCH;
+                 };
+                 /c/ && do {
+                         $ax = ($a->{'Notes'} =~ /^(out-of-date|partial)/) ? 0 :
+                                   ($a->{'Notes'} =~ /^uncompiled/) ? 2 : 1;
+                         $bx = ($b->{'Notes'} =~ /^(out-of-date|partial)/) ? 0 :
+                                   ($b->{'Notes'} =~ /^uncompiled/) ? 2 : 1;
+                         $x = $ax <=> $bx;
+                         return $x if $x != 0;
+                         last SWITCH;
+                 };
+                 /f/ && do {
+                         my $ca = exists $a->{'Failed-Category'} ?
+                                 $a->{'Failed-Category'} : "none";
+                         my $cb = exists $b->{'Failed-Category'} ?
+                                 $b->{'Failed-Category'} : "none";
+                         $x = $catval{$ca} <=> $catval{$cb};
+                         return $x if $x != 0;
+                         last SWITCH;
+                 };
+                 /S/ && do {
+                         my $pa = $prioval{$a->{'Priority'}} >
+                                 $prioval{'standard'};
+                         my $pb = $prioval{$b->{'Priority'}} >
+                                 $prioval{'standard'};
+                         $x = $pa <=> $pb;
+                         return $x if $x != 0;
+                         last SWITCH;
+                 };
+         }
+       }
+       return 0;
+}
+
+sub list_packages {
+       my $state = shift;
+       my( $name, $pkg, @list );
+       my $cnt = 0;
+       my %scnt;
+       my $ctime = time;
+
+       foreach $name (keys %db) {
+               next if $name =~ /^_/;
+               $pkg = $db{$name};
+               next if $state ne "all" && $pkg->{'State'} !~ /^\Q$state\E$/i;
+               next if $user && (lc($state) ne 'needs-build' and $pkg->{'Builder'} ne $user);
+               next if $category && $pkg->{'State'} eq "Failed" &&
+                               $pkg->{'Failed-Category'} ne $category;
+               next if ($list_min_age > 0 &&
+                                ($ctime-parse_date($pkg->{'State-Change'})) < $list_min_age)||
+                               ($list_min_age < 0 &&
+                                ($ctime-parse_date($pkg->{'State-Change'})) > -$list_min_age);
+               push( @list, $pkg );
+       }
+
+       foreach $pkg (sort sort_list_func @list) {
+               print "$pkg->{'Section'}/$pkg->{'Package'}_$pkg->{'Version'}";
+               print ": $pkg->{'State'}"
+                       if $state eq "all";
+               print " by $pkg->{'Builder'}"
+                       if $pkg->{'State'} ne "Needs-Build" && $pkg->{'Builder'};
+               print " [$pkg->{'Priority'}:$pkg->{'Notes'}";
+               print ":PREV-FAILED"
+                       if $pkg->{'Previous-State'} =~ /^Failed/;
+               print ":bp{" . $pkg->{'BuildPri'} . "}"
+                       if exists $pkg->{'BuildPri'};
+               print ":binNMU{" . $pkg->{'Binary-NMU-Version'} . "}"
+                       if exists $pkg->{'Binary-NMU-Version'};
+               print "]\n";
+               print "  Reasons for failing:\n",
+                         "    [Category: ",
+                         exists $pkg->{'Failed-Category'} ? $pkg->{'Failed-Category'} : "none",
+                         "]\n    ",
+                         join("\n    ",split("\n",$pkg->{'Failed'})), "\n"
+                       if $pkg->{'State'} =~ /^Failed/;
+               print "  Dependencies: $pkg->{'Depends'}\n"
+                       if $pkg->{'State'} eq "Dep-Wait";
+               print "  Previous state was $pkg->{'Previous-State'} until ",
+                         "$pkg->{'State-Change'}\n"
+                       if $verbose && $pkg->{'Previous-State'};
+               print "  Previous failing reasons:\n    ",
+                     join("\n    ",split("\n",$pkg->{'Old-Failed'})), "\n"
+                       if $verbose && $pkg->{'Old-Failed'};
+               ++$cnt;
+               $scnt{$pkg->{'State'}}++ if $state eq "all";
+       }
+       if ($state eq "all") {
+               foreach (sort keys %scnt) {
+                       print "Total $scnt{$_} package(s) in state $_.\n";
+               }
+       }
+       print "Total $cnt package(s)\n";
+       
+}
+
+sub info_packages {
+       my( $name, $pkg, $key, $dist );
+       my @firstkeys = qw(Package Version Builder State Section Priority
+                                          Installed-Version Previous-State State-Change);
+       my @dists = $info_all_dists ? keys %conf::distributions : ($distribution);
+       
+       foreach $dist (@dists) {
+               if ($dist ne $distribution) {
+                       if (!-f db_filename( $dist ) || !open_other_db( $dist )) {
+                               warn "Cannot open database for $dist!\n";
+                               @dists = grep { $_ ne $dist } @dists;
+                       }
+               }
+       }
+
+       foreach $name (@_) {
+               $name =~ s/_.*$//; # strip version
+               foreach $dist (@dists) {
+                       my $db = $dist ne $distribution ? $otherdb{$dist} : \%db;
+                       my $pname = "$name" . ($info_all_dists ? "($dist)" : "");
+                       
+                       $pkg = $db->{$name};
+                       if (!defined( $pkg )) {
+                               print "$pname: not registered\n";
+                               next;
+                       }
+
+                       print "$pname:\n";
+                       foreach $key (@firstkeys) {
+                               next if !exists $pkg->{$key};
+                               my $val = $pkg->{$key};
+                               chomp( $val );
+                               $val = "\n$val" if isin( $key, qw(Failed Old-Failed));
+                               $val =~ s/\n/\n /g;
+                               printf "  %-20s: %s\n", $key, $val;
+                       }
+                       foreach $key (sort keys %$pkg) {
+                               next if isin( $key, @firstkeys );
+                               my $val = $pkg->{$key};
+                               chomp( $val );
+                               $val = "\n$val" if isin( $key, qw(Failed Old-Failed));
+                               $val =~ s/\n/\n /g;
+                               printf "  %-20s: %s\n", $key, $val;
+                       }
+               }
+       }
+}
+
+sub forget_packages {
+       my( $name, $pkg, $key, $data );
+       
+       foreach $name (@_) {
+               $name =~ s/_.*$//; # strip version
+               $pkg = $db{$name};
+               if (!defined( $pkg )) {
+                       print "$name: not registered\n";
+                       next;
+               }
+
+               $data = "";
+               foreach $key (sort keys %$pkg) {
+                       my $val = $pkg->{$key};
+                       chomp( $val );
+                       $val =~ s/\n/\n /g;
+                       $data .= sprintf "  %-20s: %s\n", $key, $val;
+               }
+               send_mail( $conf::db_maint,
+                                  "$name deleted from DB $conf::dbbase",
+                                  "The package '$name' has been deleted from the database ".
+                                  "by $user.\n\n".
+                                  "Data registered about the deleted package:\n".
+                                  "$data\n" ) if $conf::db_maint;
+               change_state( \$pkg, 'deleted' );
+               log_ta( $pkg, "--forget" );
+               delete $db{$name};
+               print "$name: deleted from database\n" if $verbose;
+       }
+}
+
+sub forget_users {
+       my( $name, $ui );
+       my $change = 0;
+       
+       $ui = $db{'_userinfo'};
+       foreach $name (@_) {
+               if (!defined( $ui->{$name} )) {
+                       print "$name: not registered\n";
+                       next;
+               }
+
+               delete $ui->{$name};
+               $change++;
+               print "$name: deleted from database\n" if $verbose;
+       }
+       $db{'_userinfo'} = $ui if $change;
+}
+
+sub lock_db {
+       my $dist = shift;
+       my $try = 0;
+       my $lockfile = db_filename($dist) . ".lock";
+       local( *F );
+       
+       print "Locking $dist database\n" if $verbose >= 2;
+  repeat:
+       if (!sysopen( F, $lockfile, O_WRONLY|O_CREAT|O_TRUNC|O_EXCL, 0644 )){
+               if ($! == EEXIST) {
+                       # lock file exists, wait
+                       goto repeat if !open( F, "<$lockfile" );
+                       my $line = <F>;
+                       close( F );
+                       if ($line !~ /^(\d+)\s+([\w\d.-]+)$/) {
+                               warn "Bad lock file contents -- still trying\n";
+                       }
+                       else {
+                               my($pid, $usr) = ($1, $2);
+                               if (kill( 0, $pid ) == 0 && $! == ESRCH) {
+                                       # process doesn't exist anymore, remove stale lock
+                                       print "Removing stale lock file (pid $pid, user $usr)\n";
+                                       unlink( $lockfile );
+                                       goto repeat;
+                               }
+                               warn "Database locked by $usr -- please wait\n" if $try == 0;
+                       }
+                       if (++$try > 200) {
+                               # avoid the END routine removes the lock
+                               $main::keep_lock{$dist} = 1;
+                               die "Lock still present after 200 * 5 seconds.\n";
+                       }
+                       sleep 5;
+                       goto repeat;
+               }
+               die "Can't create lock file $lockfile: $!\n";
+       }
+       F->print("$$ $real_user\n");
+       F->close();
+}
+
+sub unlock_db {
+       my $dist = shift;
+       my $lockfile = db_filename($dist) . ".lock";
+
+       if (!$main::keep_lock{$dist}) {
+               print "Unlocking $dist database\n" if $verbose >= 2;
+               unlink $lockfile;
+       }
+}
+
+sub create_maintlock {
+       my $lockfile = db_filename("maintenance") . ".lock";
+       my $try = 0;
+       local( *F );
+       
+       print "Creating maintenance lock\n" if $verbose >= 2;
+  repeat:
+       if (!sysopen( F, $lockfile, O_WRONLY|O_CREAT|O_TRUNC|O_EXCL, 0644 )){
+               if ($! == EEXIST) {
+                       # lock file exists, wait
+                       goto repeat if !open( F, "<$lockfile" );
+                       my $line = <F>;
+                       close( F );
+                       if ($line !~ /^(\d+)\s+([\w\d.-]+)$/) {
+                               warn "Bad maintenance lock file contents -- still trying\n";
+                       }
+                       else {
+                               my($pid, $usr) = ($1, $2);
+                               if (kill( 0, $pid ) == 0 && $! == ESRCH) {
+                                       # process doesn't exist anymore, remove stale lock
+                                       print "Removing stale lock file (pid $pid, user $usr)\n";
+                                       unlink( $lockfile );
+                                       goto repeat;
+                               }
+                               warn "Maintenance lock already exists by $usr -- ".
+                                        "please wait\n" if $try == 0;
+                       }
+                       if (++$try > 120) {
+                               die "Lock still present after 120 * 60 seconds.\n";
+                       }
+                       sleep 60;
+                       goto repeat;
+               }
+               die "Can't create maintenance lock $lockfile: $!\n";
+       }
+       F->print(getppid(), " $real_user\n");
+       F->close();
+}
+
+sub remove_maintlock {
+       my $lockfile = db_filename("maintenance") . ".lock";
+
+       print "Removing maintenance lock\n" if $verbose >= 2;
+       unlink $lockfile;
+}
+
+sub waitfor_maintlock {
+       my $lockfile = db_filename("maintenance") . ".lock";
+       my $try = 0;
+       local( *F );
+       
+       print "Checking for maintenance lock\n" if $verbose >= 2;
+  repeat:
+       if (open( F, "<$lockfile" )) {
+               my $line = <F>;
+               close( F );
+               if ($line !~ /^(\d+)\s+([\w\d.-]+)$/) {
+                       warn "Bad maintenance lock file contents -- still trying\n";
+               }
+               else {
+                       my($pid, $usr) = ($1, $2);
+                       if (kill( 0, $pid ) == 0 && $! == ESRCH) {
+                               # process doesn't exist anymore, remove stale lock
+                               print "Removing stale maintenance lock (pid $pid, user $usr)\n";
+                               unlink( $lockfile );
+                               return;
+                       }
+                       warn "Databases locked for general maintenance by $usr -- ".
+                                "please wait\n" if $try == 0;
+               }
+               if (++$try > 120) {
+                       die "Lock still present after 120 * 60 seconds.\n";
+               }
+               sleep 60;
+               goto repeat;
+       }
+}
+
+
+sub read_db {
+       my $file = shift;
+
+       print "Reading ASCII database from $file..." if $verbose >= 1;
+       open( F, "<$file" ) or
+               die "Can't open database $file: $!\n";
+
+       local($/) = ""; # read in paragraph mode
+       while( <F> ) {
+               my( %thispkg, $name );
+               s/[\s\n]+$//;
+               s/\n[ \t]+/\376\377/g;  # fix continuation lines
+               s/\376\377\s*\376\377/\376\377/og;
+  
+               while( /^(\S+):[ \t]*(.*)[ \t]*$/mg ) {
+                       my ($key, $val) = ($1, $2);
+                       $val =~ s/\376\377/\n/g;
+                       $thispkg{$key} = $val;
+               }
+               check_entry( \%thispkg );
+               # add to db
+               $name = $thispkg{'Package'};
+               $db{$name} = \%thispkg;
+       }
+       close( F );
+       print "done\n" if $verbose >= 1;
+}
+
+sub check_entry {
+       my $pkg = shift;
+       my $field;
+
+       return if $op_mode eq "manual-edit"; # no checks then
+       
+       # check for required fields
+       if (!exists $pkg->{'Package'}) {
+               print STDERR "Bad entry: ",
+                         join( "\n", map { "$_: $pkg->{$_}" } keys %$pkg ), "\n";
+               die "Database entry lacks Package: field\n";
+       }
+       if (!exists $pkg->{'Version'}) {
+               die "Database entry for $pkg->{'Package'} lacks Version: field\n";
+       }
+       # if no State: field, generate one (for old db compat)
+       if (!exists($pkg->{'State'})) {
+               $pkg->{'State'} =
+                       exists $pkg->{'Failed'} ? 'Failed' : 'Building';
+       }
+       # check state field
+       die "Bad state $pkg->{'State'} of package $pkg->{Package}\n"
+               if !isin( $pkg->{'State'},
+                                 qw(Needs-Build Building Built Build-Attempted Uploaded Installed Dep-Wait
+                                        Failed Failed-Removed Not-For-Us
+                                        ) );
+}
+
+sub write_db {
+       my $file = shift;
+       my($name,$pkg,$key);
+       
+       print "Writing ASCII database to $file..." if $verbose >= 1;
+       open( F, ">$file" ) or
+               die "Can't open database $file: $!\n";
+
+       foreach $name (sort keys %db) {
+               my $pkg = $db{$name};
+               foreach $key (keys %{$pkg}) {
+                       my $val = $pkg->{$key};
+                       chomp( $val );
+                       $val =~ s/\n/\n /g;
+                       print F "$key: $val\n";
+               }
+               print F "\n";
+       }
+       close( F );
+       print "done\n" if $verbose >= 1;
+}
+
+sub change_state {
+       my $pkgr = shift;
+       my $pkg = $$pkgr;
+       my $newstate = shift;
+       my $for_dist = shift;
+       my $db;
+       if ($for_dist) {
+               return if !open_other_db( $for_dist );
+               $db = $otherdb{$for_dist};
+               $pkg = \$db{$pkg->{'Package'}};
+       }
+       else {
+               $db = \%db;
+       }
+       my $state = \$pkg->{'State'};
+       
+       return if defined($$state) and $$state eq $newstate;
+        $pkg->{'Previous-State'} = $$state if defined($$state);
+       $pkg->{'State-Change'} = $curr_date;
+
+       if (defined($$state) and $$state eq 'Failed') {
+               $pkg->{'Old-Failed'} =
+                       "-"x20 . " $pkg->{'Version'} " . "-"x20 . "\n" .
+                       $pkg->{'Failed'} . "\n" .
+                       $pkg->{'Old-Failed'};
+               delete $pkg->{'Failed'};
+               delete $pkg->{'Failed-Category'};
+       }
+       $$state = $newstate;
+}
+
+sub open_other_db {
+       my $dist = shift;
+
+       if (!tied(%{$otherdb{$dist}})) {
+               lock_db( $dist );
+               $otherdb_lock{$dist} = 1;
+               if (!(tie %{$otherdb{$dist}}, 'MLDBM', db_filename($dist), 0, 0664)){
+                       warn "Serious warning: Cannot open database for $dist\n";
+                       unlock_db( $dist );
+                       $otherdb_lock{$dist} = 0;
+                       return 0;
+               }
+       }
+       return 1;
+}
+
+sub log_ta {
+       my $pkg = shift;
+       my $action = shift;
+        my $db = \%db;
+        my $dist = $distribution;
+       my $str;
+       my $prevstate;
+
+       $prevstate = $pkg->{'Previous-State'};
+       $str = "$action($dist): $pkg->{'Package'}_$pkg->{'Version'} ".
+                  "changed from $prevstate to $pkg->{'State'} ".
+                  "by $real_user as $user";
+       
+       if (!open( LOG, ">>$transactlog" )) {
+               warn "Can't open log file $transactlog: $!\n";
+               return;
+       }
+       print LOG "$curr_date: $str\n";
+       close( LOG );
+
+       if (!($prevstate eq 'Failed' && $pkg->{'State'} eq 'Failed')) {
+               $str .= " (with --override)"
+                       if $opt_override;
+               $mail_logs .= "$str\n";
+       }
+}
+
+
+sub send_mail {
+       my $to = shift;
+       my $subject = shift;
+       my $text = shift;
+
+       my $from = $conf::db_maint;
+
+       if ($host_set != 1) {
+               chomp( $hostname = `/bin/hostname -f` );
+               $host_set = 1;
+       }
+       $from .= "\@$hostname" if $from !~ /\@/;
+
+       $to .= '@' . $hostname if $to !~ /\@/;
+       $text =~ s/^\.$/../mg;
+       local $SIG{'PIPE'} = 'IGNORE';
+       open( PIPE,  "| $conf::mailprog -oem $to" )
+               or die "Can't open pipe to $conf::mailprog: $!\n";
+       chomp $text;
+       print PIPE "From: $from\n";
+       print PIPE "Subject: $subject\n\n";
+       print PIPE "$text\n";
+       close( PIPE );
+}
+
+sub db_filename {
+       my $dist = shift;
+       return "$conf::basedir/$conf::dbbase-$dist";
+}
+
+# for parsing input to dep-wait
+sub parse_deplist {
+    my $deps = shift;
+    my $verify = shift;
+    my %result;
+    
+    foreach (split( /\s*,\s*/, $deps )) {
+        if ($verify) {
+            # verification requires > starting prompts, no | crap
+            if (!/^(\S+)\s*(\(\s*(>(?:[>=])?)\s*(\S+)\s*\))?\s*$/) {
+                return 0;
+            }
+            next;
+        }
+        my @alts = split( /\s*\|\s*/, $_ );
+        # Anything with an | is ignored, as it can be configured on a
+        # per-buildd basis what will be installed
+        next if $#alts != 0;
+        $_ = shift @alts;
+
+        if (!/^(\S+)\s*(\(\s*(>=|=|==|>|>>|<<|<=)\s*(\S+)\s*\))?\s*$/) {
+            warn( "parse_deplist: bad dependency $_\n" );
+            next;
+        }
+        my($dep, $rel, $relv) = ($1, $3, $4);
+        $rel = ">>" if defined($rel) and $rel eq ">";
+        $result{$dep}->{'Package'} = $dep;
+        if ($rel && $relv) {
+            $result{$dep}->{'Rel'} = $rel;
+            $result{$dep}->{'Version'} = $relv;
+        }
+    }
+    return 1 if $verify;
+    return \%result;
+}
+
+# for parsing Build-Depends from Sources
+sub parse_srcdeplist {
+    my $pkg = shift;
+    my $deps = shift;
+    my $arch = shift;
+    my $dep;
+    my @results;
+    
+    foreach $dep (split( /\s*,\s*/, $deps )) {
+       my @alts = split( /\s*\|\s*/, $dep );
+        # Anything with an | is ignored, as it can be configured on a
+        # per-buildd basis what will be installed
+        next if $#alts != 0;
+       $_ = shift @alts;
+        if (!/^([^\s([]+)\s*(\(\s*([<=>]+)\s*(\S+)\s*\))?(\s*\[([^]]+)\])?/) {
+            warn( "parse_srcdeplist: bad dependency $_\n" );
+            next;
+        }
+        my($dep, $rel, $relv, $archlist) = ($1, $3, $4, $6);
+        if ($archlist) {
+            $archlist =~ s/^\s*(.*)\s*$/$1/;
+            my @archs = split( /\s+/, $archlist );
+            my ($use_it, $ignore_it, $include) = (0, 0, 0);
+            foreach (@archs) {
+                if (/^!/) {
+                    $ignore_it = 1 if substr($_, 1) eq $arch;
+                } else {
+                    $use_it = 1 if $_ eq $arch;
+                    $include = 1;
+                }
+            }
+            warn "Warning: inconsistent arch restriction on ",
+                 "$pkg: $dep depedency\n"
+                 if $ignore_it && $use_it;
+            next if $ignore_it || ($include && !$use_it);
+        }
+        my $neg = 0;
+        if ($dep =~ /^!/) {
+            $dep =~ s/^!\s*//;
+            $neg = 1;
+        }
+        my $result;
+        $result->{'Package'} = $dep;
+        $result->{'Neg'} = $neg;
+        if ($rel && $relv) {
+            $result->{'Rel'} = $rel;
+            $result->{'Version'} = $relv;
+        }
+        push @results, $result;
+    }
+    return \@results;
+}
+
+sub build_deplist {
+       my $list = shift;
+       my($key, $result);
+       
+       foreach $key (keys %$list) {
+               $result .= ", " if $result;
+               $result .= $key;
+               $result .= " ($list->{$key}->{'Rel'} $list->{$key}->{'Version'})"
+                       if $list->{$key}->{'Rel'} && $list->{$key}->{'Version'};
+       }
+       return $result;
+}
+
+sub clean_db {
+       my %new_db;
+       tie %new_db, 'MLDBM', db_filename( $distribution ) . ".new", GDBM_WRCREAT, 0664
+               or die "FATAL: Cannot create new database\n";
+       %new_db = %db;
+       untie %db or die "FATAL: Cannot untie old database\n";
+       system ("cp " . db_filename( $distribution ) . ".new " .
+               db_filename( $distribution ) ) == 0
+               or die "FATAL: Cannot overwrite old database";
+       unlink db_filename( $distribution ) . ".new";
+       %db = %new_db;
+}
+
+
+sub get_unsatisfied_dep {
+    my $bd  = shift;
+    my $pkgs = shift;
+    my $dep = shift;
+    my $savedep = shift;
+
+    my $pkgname = $dep->{'Package'};
+
+    if (defined $pkgs->{$pkgname}{'Provider'}) {
+        # provides.  leave them for buildd/sbuild.
+        return "";
+    }
+
+    # check cache
+    return $pkgs->{$pkgname}{'Unsatisfied'} if $savedep and defined($pkgs->{$pkgname}{'Unsatisfied'});
+
+    # Return unsatisfied deps to a higher caller to process
+    if ((!defined($pkgs->{$pkgname})) or
+        (defined($dep->{'Rel'}) and !version_compare( $pkgs->{$pkgname}{'Version'}, $dep->{'Rel'}, $dep->{'Version'} ) ) ) {
+        my %deplist;
+        $deplist{$pkgname} = $dep;
+        my $deps = build_deplist(\%deplist);
+        $pkgs->{$pkgname}{'Unsatisfied'} = $deps if $savedep;
+        return $deps;
+    }
+
+    # set cache to "" to avoid infinite recursion
+    $pkgs->{$pkgname}{'Unsatisfied'} = "" if $savedep;
+
+    if (defined $pkgs->{$dep->{'Package'}}{'Depends'}) {
+        my $deps = parse_deplist( $pkgs->{$dep->{'Package'}}{'Depends'} );
+        foreach (keys %$deps) {
+            $dep = $$deps{$_};
+            # recur on dep.
+            my $ret = get_unsatisfied_dep($bd,$pkgs,$dep,1);
+            if ($ret ne "") {
+                my $retdep = parse_deplist( $ret );
+                foreach (keys %$retdep) {
+                    $dep = $$retdep{$_};
+
+                    $dep->{'Rel'} = '>=' if defined($dep->{'Rel'}) and $dep->{'Rel'} =~ '^=';
+
+                    if (defined($dep->{'Rel'}) and $dep->{'Rel'} =~ '^>' and defined ($pkgs->{$dep->{'Package'}}) and
+                        version_compare($bd->{$pkgs->{$dep->{'Package'}}{'Source'}}{'ver'},'>>',$pkgs->{$dep->{'Package'}}{'Sourcev'})) {
+                        if (not defined($merge_binsrc{$dep->{'Package'}})) {
+                            # the uninstallable package doesn't exist in the new source; look for something else that does.
+                            delete $$retdep{$dep->{'Package'}};
+                            foreach (sort (split( /\s*,\s*/, $bd->{$pkgs->{$dep->{'Package'}}{'Source'}}{'bin'}))) {
+                                next if ($pkgs->{$_}{'all'} or not defined $pkgs->{$_}{'Version'});
+                                $dep->{'Package'} = $_;
+                                $dep->{'Rel'} = '>>';
+                                $dep->{'Version'} = $pkgs->{$_}{'Version'};
+                                $$retdep{$_} = $dep;
+                                last;
+                            }
+                        }
+                    } else {
+                        # sanity check to make sure the depending binary still exists, and the depended binary exists and dep-wait on a new version of it
+                        if ( defined($merge_binsrc{$pkgname}) and defined($pkgs->{$dep->{'Package'}}{'Version'}) ) {
+                            delete $$retdep{$dep->{'Package'}};
+                            $dep->{'Package'} = $pkgname;
+                            $dep->{'Rel'} = '>>';
+                            $dep->{'Version'} = $pkgs->{$pkgname}{'Version'};
+                            $$retdep{$pkgname} = $dep;
+                        }
+                        delete $$retdep{$dep->{'Package'}} if (defined ($dep->{'Rel'}) and $dep->{'Rel'} =~ '^>');
+                    }
+                }
+                $ret = build_deplist($retdep);
+                $pkgs->{$pkgname}{'Unsatisfied'} = $ret if $savedep;
+                return $ret;
+            }
+        }
+    }
+    return "";
+}
+
+sub auto_dep_wait {
+    my $bd = shift;
+    my $pkgs = shift;
+    my $key;
+    
+    return if defined ($conf::distributions{$distribution}{noadw});
+
+    # We need to walk all of needs-build, as any new upload could make
+    # something in needs-build have uninstallable deps
+    foreach $key (keys %db) {
+       my $pkg = $db{$key};
+       next
+           if not defined $pkg or $pkg->{'State'} ne "Needs-Build";
+       my $srcdeps = parse_srcdeplist($key,$bd->{$key}{'dep'},$arch);
+        foreach my $srcdep (@$srcdeps) {
+            next if $srcdep->{'Neg'} != 0; # we ignore conflicts atm
+            my $rc = get_unsatisfied_dep($bd,$pkgs,$srcdep,0);
+            if ($rc ne "") {
+                # set dep-wait
+                my $deplist = parse_deplist( $pkg->{'Depends'} );
+                my $newdeps = parse_deplist( $rc );
+                my $change = 0;
+                foreach (%$newdeps) {
+                    my $dep = $$newdeps{$_};
+                    # ensure we're not waiting on ourselves, or a package that has been removed
+                    next if (not defined($merge_binsrc{$dep->{'Package'}})) or ($merge_binsrc{$dep->{'Package'}} eq $key);
+                    if ($dep->{'Rel'} =~ '^>') {
+                        $deplist->{$dep->{'Package'}} = $dep;
+                        $change++;
+                    }
+                }
+                if ($change) {
+                    $pkg->{'Depends'} = build_deplist($deplist);
+                    change_state( \$pkg, 'Dep-Wait' );
+                    log_ta( $pkg, "--merge-all" );
+                    $db{$key} = $pkg;
+                    print "Auto-Dep-Waiting ${key}_$pkg->{'Version'} to $pkg->{'Depends'}\n" if $verbose;
+                }
+                last;
+            }
+       }
+    }
+}
+
+sub usage {
+       my $prgname;
+       ($prgname = $0) =~ s,^.*/,,;
+       print <<"EOF";
+Usage: $prgname <options...> <package_version...>
+Options:
+    -v, --verbose: Verbose execution.
+    --take: Take package for building [default operation]
+    -f, --failed: Record in database that a build failed due to
+        deficiencies in the package (that aren't fixable without a new
+        source version).
+    -u, --uploaded: Record in the database that the packages build
+        correctly and were uploaded.
+    -n, --no-build: Record in the database that the packages aren't
+        desired for m68k and shouldn't appear in listings even if
+        they're out of date.
+    --dep-wait: Record in the database that the packages are waiting
+        for some source dependencies to become available
+    --merge-quinn: Merge quinn-diff output into database.
+    --merge-packages: Merge Packages files into database.
+    --pretend-avail: Pretend that given packages are available now and give
+        free packages waiting for them
+    -i SRC_PKG, --info SRC_PKG: Show information for source package
+    -l STATE, --list=STATE: List all packages in state STATE; can be
+        combined with -U to restrict to a specific user; STATE can
+        also be 'all'
+    -m MESSAGE, --message=MESSAGE: Give reason why package failed or
+        source dependency list
+        (used with -f, --dep-wait, and --binNMU)
+    -o, --override: Override another user's lock on a package, i.e.
+        take it over; a notice mail will be sent to the other user
+    -U USER, --user=USER: select user name for which listings should
+        apply, if not given all users are listed.
+        if -l is missing, set user name to be entered in db; usually
+        automatically choosen
+    --import FILE: Import database from a ASCII file FILE
+    --export FILE: Export database to a ASCII file FILE
+The remaining arguments (depending on operation) usually start with
+"name_version", the trailer is ignored. This allows to pass the names
+of .dsc files, for which file name completion can be used.
+--merge-packages and --merge-quinn take Package/quin--diff file names
+on the command line or read stdin. --list needs nothing more on the
+command line. --info takes source package names (without version).
+EOF
+       exit 1;
+}
+
+sub pkg_version_eq {
+       my $pkg = shift;
+       my $version = shift;
+
+       return 1
+              if (defined $pkg->{'Binary-NMU-Version'}) and 
+              version_compare(binNMU_version($pkg->{'Version'},
+                       $pkg->{'Binary-NMU-Version'}),'=', $version);
+       return version_compare( $pkg->{'Version'}, "=", $version );
+}
diff --git a/bin/wanna-build-statistics b/bin/wanna-build-statistics
new file mode 100755 (executable)
index 0000000..70a689f
--- /dev/null
@@ -0,0 +1,167 @@
+#!/usr/bin/perl
+#
+# wanna-build-statistics: print statistics for wanna-build databases
+# Copyright (C) 1998 Roman Hodek <Roman.Hodek@informatik.uni-erlangen.de>
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License as
+# published by the Free Software Foundation; either version 2 of the
+# License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+#
+# $Id: wanna-build-statistics 43 2005-06-01 09:28:43Z rmurray $
+#
+# $Log: wanna-build-statistics,v $
+# Revision 1.4  2000/10/19 09:15:37  rnhodek
+# percent: handle $total == 0 case.
+#
+# Revision 1.3  1999/01/13 09:57:17  rnhodek
+# If wanna-build returns error status, also print last message from it.
+#
+# Revision 1.2  1998/12/16 10:51:34  rnhodek
+# Print nothing at all if wanna-build says that the db doesn't exist.
+# Remove debugging stuff.
+#
+# Revision 1.1  1998/12/16 10:29:09  rnhodek
+# Initial writing.
+#
+
+use strict;
+use vars qw($verbose $dist $database);
+
+$verbose = 0;
+$dist = "unstable";
+$database = "build-db";
+
+while( @ARGV && $ARGV[0] =~ /^-/ ) {
+       $_ = shift @ARGV;
+       if (/^-v$/ || /^--verbose$/) {
+               $verbose++;
+       }
+       elsif (/^-d/ || /^--dist/) {
+               if (/^-d(.)/ || /^--dist=(.)/) {
+                       $dist = $1.$';
+               }
+               elsif (!@ARGV) {
+                       die "$_ option missing argument\n";
+               }
+               else {
+                       $dist = shift @ARGV;
+               }
+               $dist = "stable"   if $dist eq "s";
+               $dist = "testing"  if $dist eq "t";
+               $dist = "unstable" if $dist eq "u";
+               die "Bad distribution\n" if !isin($dist, qw(stable testing unstable stable-security testing-security));
+       }
+       elsif (/^--$/) {
+               last;
+       }
+       elsif (/^--database=(.*)$/) {
+               $database = $1;
+       }
+       else {
+               die "Unknown option: $_\n";
+       }
+}
+
+my($lastmsg, %n_state, $total, %n_builder);
+open( PIPE, "wanna-build --database=$database --dist=$dist --list=all 2>&1 |" )
+       or die "Cannot spawn wanna-build: $!\n";
+while( <PIPE> ) {
+       if (/^Database for $dist doesn't exist$/) {
+               exit 1;
+       }
+       elsif (/^Total (\d+) package\(s\) in state (\S+)\.$/) {
+               $n_state{$2} = $1;
+       }
+       elsif (/^Total (\d+) package\(s\)$/) {
+               $total = $1;
+       }
+       elsif (/^\S+: (\S+) by (\S+)/) {
+               $n_builder{$1}->{$2}++;
+       }
+       $lastmsg = $_;
+}
+close( PIPE );
+if ($?) {
+       print "$lastmsg";
+       die "Bad exit status $? from wanna-build\n";
+}
+
+print "Distribution $dist:\n";
+print "--------------", "-" x length($dist), "\n";
+
+my $total_width = 78;
+my @state_list = qw(Installed Needs-Build Building Built Build-Attempted Uploaded Failed Dep-Wait
+                                       Failed-Removed Dep-Wait-Removed
+                                       Not-For-Us);
+my $statewidth = 0;
+grep { $statewidth = length($_) if length($_) > $statewidth } @state_list;
+my $startcol = $statewidth + 9;
+
+my($state, $builder);
+foreach $state (@state_list) {
+       printf "%-${statewidth}s: %5d", $state, $n_state{$state};
+       if (!keys %{$n_builder{$state}}) {
+               print "\n";
+               next;
+       }
+       my $sum = 0;
+       foreach $builder (keys %{$n_builder{$state}}) {
+               $sum += $n_builder{$state}->{$builder};
+       }
+       $n_builder{$state}->{"unknown"} = $n_state{$state} - $sum;
+       print " (";
+       my $is_first = 1;
+       my $pos = $startcol;
+       foreach $builder (sort keys %{$n_builder{$state}}) {
+               next if !$n_builder{$state}->{$builder};
+               my $str = "$builder: $n_builder{$state}->{$builder}";
+               $str = ", $str" if !$is_first;
+               $is_first = 0;
+               if ($pos + length($str) > $total_width) {
+                       print ",\n", " " x $startcol;
+                       $pos = $startcol;
+                       $str =~ s/^, //;
+               }
+               print $str;
+               $pos += length($str);
+       }
+       print ")\n";
+}
+printf "%-${statewidth}s: %5d\n", "total", $total;
+print "\n";
+
+$total -= $n_state{"Not-For-Us"};
+print percent(qw(Installed)), " up-to-date, ";
+print percent(qw(Installed Uploaded)), " if also counting uploaded pkgs\n";
+print percent(qw(Built Installed Uploaded)), " if also counting built pkgs\n";
+print percent(qw(Needs-Build)), " uncompiled\n";
+print percent(qw(Building)), " currently building (short-term delay)\n";
+print percent(qw(Build-Attempted)), " currently failed building (short-term delay)\n";
+print percent(qw(Failed Dep-Wait)), " failed or waiting (long-term delay)\n";
+
+exit 0;
+
+sub percent {
+       my $n = 0;
+       foreach (@_) {
+               $n += $n_state{$_};
+       }
+
+       return sprintf "%6.2f%%", $n*100/$total if $total;
+       return sprintf "%6.2f%%", 0;
+}
+
+sub isin {
+       my $val = shift;
+       return grep( $_ eq $val, @_ );
+}
diff --git a/bin/wb-graph b/bin/wb-graph
new file mode 100755 (executable)
index 0000000..1a65dbc
--- /dev/null
@@ -0,0 +1,90 @@
+#!/usr/bin/perl
+#
+
+use strict;
+use vars qw($dist);
+my $previously_built;
+
+$dist = "unstable";
+
+while( @ARGV && $ARGV[0] =~ /^-/ ) {
+       $_ = shift @ARGV;
+       if (/^-d/ || /^--dist/) {
+               if (/^-d(.)/ || /^--dist=(.)/) {
+                       $dist = $1.$';
+               }
+               elsif (!@ARGV) {
+                       die "$_ option missing argument\n";
+               }
+               else {
+                       $dist = shift @ARGV;
+               }
+               $dist = "stable"   if $dist eq "s";
+               $dist = "frozen"   if $dist eq "f";
+               $dist = "unstable" if $dist eq "u";
+               die "Bad distribution\n" if !isin($dist, qw(stable testing unstable));
+       }
+       elsif (/^--$/) {
+               last;
+       }
+       elsif (/^-p$/ || /^--previously-built$/) {
+               $previously_built = 1;
+       }
+       else {
+               die "Unknown option: $_\n";
+       }
+}
+
+my $date=`date +%m/%d/%Y`;
+chop($date);
+print "$date";
+
+my @archs = qw(alpha arm hppa hurd-i386 i386 ia64 m68k mips mipsel powerpc s390 amd64 sparc armel);
+my $arch;
+
+foreach $arch (@archs) {
+
+my($lastmsg, %n_state, $total, %n_builder, $pu_total);
+$pu_total = 0;
+$n_state{"Installed"} = 0;
+open( PIPE, "wanna-build --database=$arch/build-db --dist=$dist --list=all 2>&1 |" )
+       or die "Cannot spawn wanna-build: $!\n";
+while( <PIPE> ) {
+       if (/^Database for $dist doesn't exist$/) {
+               last;
+       }
+       elsif (/^Total (\d+) package\(s\) in state (\S+)\.$/) {
+               $n_state{$2} = $1;
+               $pu_total += $1 if ( $2 eq "Installed" );
+       }
+       elsif (/^Total (\d+) package\(s\)$/) {
+               $total = $1;
+       }
+       elsif (/: Installed (?:by [\w-]+ )?\[[\w-]*:/) {
+               next;
+       }
+       elsif (/: [\w-]+ (?:by [\w-]+ )?\[\w+:(out-of-date|partial)/) {
+               $pu_total++;
+       }
+       $lastmsg = $_;
+}
+close( PIPE );
+if ($?) {
+       print ", 0, 0";
+} else {
+#      $total -= $n_state{"Not-For-Us"};
+       if ( $previously_built ) {
+               print ", ".$n_state{"Installed"}.", ".$pu_total;
+       } else {
+               print ", ".$n_state{"Installed"}.", ".$total;
+       }
+}
+}
+print "\n";
+
+exit 0;
+
+sub isin {
+       my $val = shift;
+       return grep( $_ eq $val, @_ );
+}
diff --git a/bin/wb-make-rev b/bin/wb-make-rev
new file mode 100755 (executable)
index 0000000..dad0946
--- /dev/null
@@ -0,0 +1,44 @@
+#!/usr/bin/perl -w
+
+use strict;
+
+my $arch = "i386";
+my $suite = "unstable";
+my %dep;
+
+my $in_bd = 0;
+
+open F, "/org/wanna-build/tmp/Sources.$suite-old";
+while (<F>) {
+       if (s/^Build-Depends:// or (/^\s/ and $in_bd)) {
+               foreach my $pkg (split/,|\|/) {
+                       $pkg =~ s/\(.+\)//;
+                       $pkg =~ s/\[.+\]//;
+                       $pkg =~ s/^\s*(\S+)\s*/$1/;
+                       $dep{$pkg} = 1 if $pkg ne "\n";
+               }
+               $in_bd = 1;
+       } else {
+               $in_bd = 0;
+       }
+}
+close F;
+
+open F, "/org/wanna-build/tmp/Packages.$suite.$arch-old";
+while (<F>) {
+       if (s/^Package:
+       if (s/^Depends:// or (/^\s/ and $in_bd)) {
+               foreach my $pkg (split/,|\|/) {
+                       $pkg =~ s/\(.+\)//;
+                       $pkg =~ s/\[.+\]//;
+                       $pkg =~ s/^\s*(\S+)\s*/$1/;
+                       $dep{$pkg} = 1 if $pkg ne "\n";
+               }
+               $in_bd = 1;
+       } else {
+               $in_bd = 0;
+       }
+}
+
+       
+print join ("\n",sort keys %dep);
diff --git a/db/.keep b/db/.keep
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/etc/.gitignore b/etc/.gitignore
new file mode 100644 (file)
index 0000000..530b263
--- /dev/null
@@ -0,0 +1,2 @@
+graph-data
+graph2-data
diff --git a/etc/cron/Makefile b/etc/cron/Makefile
new file mode 100644 (file)
index 0000000..7de81dd
--- /dev/null
@@ -0,0 +1,13 @@
+CRONTAB = $(CURDIR)/crontab
+
+install:
+       @if [ `whoami` = wbadm ]; then \
+           crontab $(CRONTAB); \
+       else \
+           echo >&2 'Error: must run as user wbadm.'; \
+           exit 1; \
+       fi
+
+check:
+       @-crontab -l | diff -u $(CRONTAB) -
+
diff --git a/etc/cron/crontab b/etc/cron/crontab
new file mode 100644 (file)
index 0000000..f5331a7
--- /dev/null
@@ -0,0 +1,12 @@
+# Never change wbadm's crontab with `crontab -e`. Instead, edit
+# ~wbadm/etc/cron/crontab, and run `make` in that directory (or
+# install that file by hand). Also, please `svn commit` any
+# non-temporary changes you make.
+
+#
+# Stats update.
+#
+MAILTO=wb-team@buildd.debian.org
+43 * * * *       /org/buildd.debian.org/bin/wb-export
+
+3  0 * * *       make -sC /org/wanna-build/etc/cron check
diff --git a/etc/graph.R b/etc/graph.R
new file mode 100644 (file)
index 0000000..c4d71f9
--- /dev/null
@@ -0,0 +1,45 @@
+arch <- c("alpha", "amd64", "arm", "armel", "hppa", "i386", "ia64", "m68k", "mips",
+       "mipsel", "powerpc", "s390", "sparc")
+palette(c("black", "turquoise", "red", "OrangeRed", "green3", "cyan", "magenta", "tomato4",
+       "violetred2","thistle4", "steelblue2", "springgreen4",
+       "salmon", "gray"))
+
+readdata <- function (file,start) {
+       t <- read.table(file,row.names=1,header=FALSE,
+       sep=",",col.names=c("date","alpha","at","arm","art","hppa","ht","hurd-i386",
+       "hit","i386","it","ia64","i6t","m68k","mt","mips","mit","mipsel","mipt",
+       "powerpc","pt","s390","st","amd64","amdt","sparc","spt","armel","aret"))
+       ts(as.matrix(data.frame(t[1]/t[2]*100,t[23]/t[24]*100,t[3]/t[4]*100,
+       t[27]/t[28]*100,t[5]/t[6]*100,t[9]/t[10]*100,t[11]/t[12]*100,
+       t[13]/t[14]*100,t[15]/t[16]*100,t[17]/t[18]*100,t[19]/t[20]*100,
+       t[21]/t[22]*100,t[25]/t[26]*100)),c(2001,start),frequency=365.25)
+}
+
+plotwb <- function (file,title,p,linept=85,height=7.5,width=10,pch=1:14) {
+       bitmap(file=file,type="png16m",width=width,height=height,res=64)
+       layout(matrix(c(1,1,2,2),2,2),widths=c(0.85,0.15))
+       par(mar=c(5,4,4,2)+0.1) 
+       par(lab=c(10,10,7))
+       plot(p,type="o",plot.type="single",col=1:14,pch=pch,xlab="date",
+               ylab="percentage of packages",main=title,cex=2)
+       abline(h=90,lty=2,col=3)
+       abline(h=linept,lty=2,col=3)
+       axis(4)
+       plot.new()
+       par(plt=c(0,1,0,1))        
+       legend(-1.2,1, arch, col=1:14, pch=pch, lwd=2, bg='gray90', cex=1.5)  
+}
+v <- readdata("/org/wanna-build/etc/graph-data",164)
+plotwb("/org/buildd.debian.org/web/stats/graph.png","What percent is built for each architecture",v,85,7.5,10,".")
+plotwb("/org/buildd.debian.org/web/stats/graph-big.png","What percent is built for each architecture",v,85,15,20,".")
+plotwb("/org/buildd.debian.org/web/stats/graph-week.png","What percent is built for each architecture (past two weeks)",window(v,start=time(v)[length(time(v))-14]),85)
+plotwb("/org/buildd.debian.org/web/stats/graph-week-big.png","What percent is built for each architecture (past two weeks)",window(v,start=time(v)[length(time(v))-14]),85,15,20)
+plotwb("/org/buildd.debian.org/web/stats/graph-quarter.png","What percent is built for each architecture (past quarter)",window(v,start=time(v)[length(time(v))-90]),85)
+plotwb("/org/buildd.debian.org/web/stats/graph-quarter-big.png","What percent is built for each architecture (past quarter)",window(v,start=time(v)[length(time(v))-90]),85,15,20)
+v <- readdata("/org/wanna-build/etc/graph2-data",279)
+plotwb("/org/buildd.debian.org/web/stats/graph2.png","How architectures are keeping up",v,95,7.5,10,".")
+plotwb("/org/buildd.debian.org/web/stats/graph2-big.png","How architectures are keeping up",v,95,15,20,".")
+plotwb("/org/buildd.debian.org/web/stats/graph2-week.png","How architectures are keeping up (past two weeks)",window(v,start=time(v)[length(time(v))-14]),95)
+plotwb("/org/buildd.debian.org/web/stats/graph2-week-big.png","How architectures are keeping up (past two weeks)",window(v,start=time(v)[length(time(v))-14]),95,15,20)
+plotwb("/org/buildd.debian.org/web/stats/graph2-quarter.png","How architectures are keeping up (past quarter)",window(v,start=time(v)[length(time(v))-90]),95)
+plotwb("/org/buildd.debian.org/web/stats/graph2-quarter-big.png","How architectures are keeping up (past quarter)",window(v,start=time(v)[length(time(v))-90]),95,15,20)
diff --git a/etc/wanna-build.conf b/etc/wanna-build.conf
new file mode 100644 (file)
index 0000000..dfad13a
--- /dev/null
@@ -0,0 +1,33 @@
+#
+# /etc/wanna-build.conf: wanna-build configurations that are
+# supposed to be changed only by the buildd author, not by the user.
+# Of course you're free to override values here in /etc/wanna-build.conf.local
+#
+# $Id: wanna-build.conf,v 1.21 1999/09/01 13:57:51 rnhodek Exp $
+#
+
+# directory for the databases, lock files and log files
+$basedir = "/var/state/debbuild";
+
+# base name of the database, "-DIST" is appended automatically, and ".lock"
+# for lock files
+#$dbbase = "build-db";
+
+# name of transaction log file (in base dir)
+#$transactlog = "transactions.log";
+
+# ignore all epochs? (needed if quinn-diff prints no epochs)
+#$ignore_epochs = 0;
+
+# All mail address variables below can contain more than one address
+# if you separate them by spaces. All of them also can be empty, no
+# mails to that address will be sent in this case.
+
+# Program to send mail
+#$mailprog = "/usr/lib/sendmail";
+
+# read local config file
+require '/org/wanna-build/etc/wanna-build.conf.local';
+
+# don't remove this, Perl needs it:
+1;
diff --git a/etc/wanna-build.conf.local b/etc/wanna-build.conf.local
new file mode 100644 (file)
index 0000000..95d4efb
--- /dev/null
@@ -0,0 +1,64 @@
+#
+# /etc/wanna-build.conf: local wanna-build configuration
+#
+# This is an example file, values are for for the m68k wanna-build on
+# m68k.debian.org.
+#
+
+# directory for the databases, lock files and log files
+$basedir = "/org/wanna-build/db";
+
+# ignore all epochs? (needed if quinn-diff prints no epochs)
+#$ignore_epochs = 0;
+
+# mail address of database maintainer (informed about a few things)
+$db_maint = "wb-team\@buildd.debian.org";
+
+# mail address of not-for-us maintainer (informed about Not-For-Us state
+# changes)
+$notforus_maint = "rmurray-wanna-build";
+
+# mail address for logs of all state changes
+#$log_mail = "m68k-changes\@nocrew.org";
+
+# where to send wanna-build statistics mails
+$stat_mail = "wb-team\@buildd.debian.org";
+
+# file to publish statistics over WWW (optional)
+#$web_stats = "/var/www/buildd/stats.txt";
+
+# sections to import and maintain in the database
+# the full list would be:
+# @sections = qw(main contrib non-free non-US non-US/main non-US/contrib non-US/non-free);
+@sections = qw(main contrib non-US/main non-US/contrib);
+
+# source for Packages files (for do-merge-packages)
+# can be an ftp or http URL, or a local path
+$pkgs_source = "/org/ftp.debian.org/ftp";
+
+# source for quinn-diff output (for do-merge-quinn)
+# can be an ftp or http URL, or a local path
+#$quinn_source = "http://ftp.uni-erlangen.de/pub/Linux/LOCAL/Debian-support/quinn-diff";
+$quinn_source = "/org/buildd.debian.org/web/quinn-diff/output";
+
+# Is there quinn-diff output for more than one section (main)? This changes
+# what structure under $quinn_source is assumed:
+#   $quinn_source_has_section == 0 : ARCH/source-dependencies-DIST.gz
+#   $quinn_source_has_section == 1 : ARCH/SECTION/DIST
+# ftp.uni-erlangen.de is multi-section, buildd.debian.org not (yet)
+$quinn_source_multi_section = 0;
+
+@admin_users = qw(wbadm);
+
+%distributions = (
+        "unstable" => { },
+        "testing" => { },
+        "testing-security" => { noadw => 1, hidden => 1 },
+        "stable" => { },
+        "stable-security" => { noadw => 1, hidden => 1 },
+        "oldstable" => { },
+        "oldstable-security" => { noadw => 1, hidden => 1 },
+);
+
+# don't remove this, Perl needs it:
+1;
diff --git a/fixperms b/fixperms
new file mode 100755 (executable)
index 0000000..322a409
--- /dev/null
+++ b/fixperms
@@ -0,0 +1,8 @@
+#!/bin/sh
+#
+# This is meant to be run from the db dir with an arch param
+
+if [ -d "$1" ]; then
+       chmod 664 $1/build-db-*
+       chmod 660 $1/build-db-*-security
+fi
diff --git a/home/.gitignore b/home/.gitignore
new file mode 100644 (file)
index 0000000..1ae1ecd
--- /dev/null
@@ -0,0 +1,10 @@
+.alias
+.bash_history
+.bash_logout
+.bash_profile
+.bashrc
+.cshrc
+.lesshst
+.viminfo
+.zshrc
+attic
diff --git a/home/.ssh/authorized_keys b/home/.ssh/authorized_keys
new file mode 100644 (file)
index 0000000..7683131
--- /dev/null
@@ -0,0 +1,2 @@
+from="194.109.137.218",command="/org/wanna-build/bin/ssh-wrapper",no-pty,no-port-forwarding,no-X11-forwarding,no-agent-forwarding ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAIEA6jS3UMgoU5AUcp79EbDjIGLK5X0tY9qH1f4hDtNHgvtgeQOfJgvcbYSZIsMpOxgCuTrxVE3c4815nyLjjBZZizs1ujc4D9Lse/P8rMUJ9LVp6rjpZomVPZrBvOeIWyKzuENI9fRstxY8buG2QFGwJkECsRCFvC9xabGtj44TojU= katie@klecker
+from="128.148.34.103",command="/org/wanna-build/bin/trigger-wrapper",no-pty,no-port-forwarding,no-X11-forwarding,no-agent-forwarding ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAngnAalVfDsWonP7ibwaEmj3zKr/e9kiMS4Xlr3mfascFP3phaiBjhhhj4m5PNOacHoLi+mz6RWhOUd91bsMfEEAOt/hmVA3/lttP494FneNEBvD2v3DMoOv415wtjDErIMhjVu0EdHGnn/20AokPxotE4r4BMxnbXP3bvUvidgEw3I+ciqMNAzfEx12B+HL9ApyFKo6JBmFTJyKGFNZ2arb1GL2V9BHsY4luME0vvjmJMqC/289P+Zx6NECsVHMguC/ZIWKdQbTxFUQNO+oUAO+EZVQUJq/fs+gwjcrbjU9mj6c4eiJwPsw8ysqogeuq3tku1DMNekNH0WhvarVLgw== dak@ries
diff --git a/postrelease b/postrelease
new file mode 100644 (file)
index 0000000..ebe33b2
--- /dev/null
@@ -0,0 +1,45 @@
+#!/bin/sh
+# Meant to be run from the /srv/wanna-build/db dir
+
+set -e
+
+# etch
+ARCHS_stable="m68k arm sparc alpha powerpc i386 mips mipsel ia64 hppa s390"
+ARCHS_testing="arm sparc alpha powerpc i386 amd64 mips mipsel ia64 hppa s390"
+
+#for a in $ALL_ARCHS; do
+#   rm $a/build-db-oldstable
+#   rm $a/build-db-oldstable-security
+#done
+
+for a in $ARCHS_stable; do
+    mv $a/build-db-stable $a/build-db-oldstable
+    mv $a/build-db-stable-security $a/build-db-oldstable-security
+done
+
+for a in $ARCHS_testing; do
+    mv $a/build-db-testing $a/build-db-stable
+    mv $a/build-db-testing-security $a/build-db-stable-security
+done
+
+for a in $ARCHS_testing; do
+    group=wb-$a
+    chmod 400 $a/build-db-stable
+    cp -a $a/build-db-stable $a/build-db-testing
+    wanna-build -b $a/build-db -d testing-security --create-db --list all
+    if [ "$a" = "powerpc" ]; then
+        group=wb-ppc
+    fi
+    if [ "$a" = "mipsel" ]; then
+        group=wb-mips
+    fi
+    if [ "$a" = "amd64" ]; then
+        group=wb-i386
+    fi
+    chgrp $group $a/build-db-testing*
+    chmod 000 $a/build-db-testing
+    chmod 000 $a/build-db-testing-security
+done
+
+# Important!  And rebuild it afterwards, check for sanity.
+#rm ../tmp/*
diff --git a/ssh-keys/README b/ssh-keys/README
new file mode 100644 (file)
index 0000000..a453d79
--- /dev/null
@@ -0,0 +1,3 @@
+push updates using sudo update-buildd-sshkeys
+
+weasel, Sat, 22 Nov 2008 00:52:41 +0100
diff --git a/ssh-keys/buildd_alpha b/ssh-keys/buildd_alpha
new file mode 100644 (file)
index 0000000..0eca30a
--- /dev/null
@@ -0,0 +1 @@
+from="::ffff:193.62.202.26,193.62.202.26",command="/org/wanna-build/bin/ssh-wrapper",no-pty,no-port-forwarding,no-X11-forwarding,no-agent-forwarding ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEA2dM0fIuFomAzzQVCJ1hDE0tmlY8Wyf2VpV+5OBy1BwC+5ZEQrQnQG+TewQFY9EVNEjZQJzM1zF+lv8DPfGehcTV6H0KbdW7ef13uUxeUg7DT0IKDNLE7D8l6r0Tun8ZpRqjSzVUcfTIWvhMyS8vTzaCrsNiTZJ17ZUEyEYiem5WEJbKXQ21CscSaYAdMTt2zy2KRou3XtOEVJnLRsl6f5TzP2TIH9Wj3IsdyWktlPfhTLtMNWyuo2vQUUPl7zaHRG9ntx7ttC2Sze5YRS4x/RxRBmPg/jFONQklaCwQufkGJYQcn9gSkbv95ToPTXU6dCQyR89lI8GjYQhOkq3kB8w== buildd@goetz
diff --git a/ssh-keys/buildd_arm b/ssh-keys/buildd_arm
new file mode 100644 (file)
index 0000000..1f7486f
--- /dev/null
@@ -0,0 +1,17 @@
+# arm
+from="::ffff:82.71.203.197,82.71.203.197",command="/org/wanna-build/bin/ssh-wrapper",no-pty,no-port-forwarding,no-X11-forwarding,no-agent-forwarding ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAIEAyM/keZV6OZbBwe5i+RDZfYgOTt9MWCBo7XglqC5mSOxCbokKzqkrjivF84Ls+RxikPPAVoT89FDTUbq2NiH4+ixGq4rTIfsWFIIDSU3yD6b2Ph+B96LBQKSMekJESFeRwKVP/q7C8ZuYbCLA5bEAPDDPQ29dkUqrSNNLITHEPKc= buildd@smackdown
+from="::ffff:192.133.104.24,192.133.104.24",command="/org/wanna-build/bin/ssh-wrapper",no-pty,no-port-forwarding,no-X11-forwarding,no-agent-forwarding ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAIEA45lmJLrCakTyjB5zuFDCpsbe4g8TjBGgz5s60yfLkYHgapgMlcit/b0GT5Dd5B81E0oun93ryDK03I/11BjL/VC5WuD4f9sEEQx+vEOAjx62D+YjtUIoruTAtcM7qz9+CEa+lnll58lxK8xdmSeCcBj5+AwEFrbZkefoGZYm0ZM= buildd@netwinder
+from="::ffff:78.32.9.218,78.32.9.218",command="/org/wanna-build/bin/ssh-wrapper",no-pty,no-port-forwarding,no-X11-forwarding,no-agent-forwarding ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEArvxNR6a9fkpvhY54W9Bz8UX14R6731CwJ/vIDGyhnpT/Y9kaQ24o6GclMKgA+VWcKAAy5DdgZudbTUbBkqsZ1cy0yWb8XaJBmuJuX4I0ofAREdMW7HQ1gqJzOSubYQJpgdXJza5aC8VDBtyzNwk9q9VpsWuhM7spQvRHGMRdq4iOea0d8ev5tlwTmNvNZmueM1WYzC2JVR0PJ7qLhPS6IVlaNVDHkXhAt7Hr2pewccx5OytGuxN9csIqxqe2/UrFUI3wv+aHFdhCdumXqMcvDXigsxPUnVD2YH+MayDNpKhdGW1yt6oTolfBL9bVb6eKA05zXEg3ouWXhAQ09HuQYQ== buildd@jaffaholic
+from="86.3.74.169",command="/org/wanna-build/bin/ssh-wrapper",no-pty,no-port-forwarding,no-X11-forwarding,no-agent-forwarding ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAraCI2Uy76mUOmZB+5SATAFnV53tqyF2apupjBXyqvNgcA1JFAlLzCEeraXFpUuovkevhQcjGIUiPz+0X3MSB5J5cDag23zTWNfcC/YPiMWZ+xb5X83ccX6wgxF57eTTQPRnjgrrmTX269mzzJojYB0YdNj5ZLq+wFnuuEsYqJ+kJuydAufPf5NSrCIVpA80IASBQrq2y1xFJjR7+aGbtRjquJDoQLJRvw1XGpLmNSTFeVfUAN9AT6yj2Cp+NbeeFMVs23NuXH7AtjNpfNJck2Oa+h4bM9TXXoGhjGzz962xn71GaF5/kxv7WUDvv2kxr439tq0eME897eO91Jv387w== buildd@cats
+from="::ffff:62.116.5.75,62.116.5.75",command="/org/wanna-build/bin/ssh-wrapper",no-pty,no-port-forwarding,no-X11-forwarding,no-agent-forwarding ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAuMxRFfo954ZwkTScdp1O+iA1NfKIfjXAaWWTwSpZUB89cP9qVOEfYLvm1JNNwZOxQY5hIiZQJ05749x9pzbDqi5Z/tBJhODkPOpxzZ1eQJpEWt6ErBIwqjzln2TLWH6KL1k3h3bWGZ1Q7wfTPcEIQly52zSNy3YExW2wVa9p632ZL8AouvAutVOI9K+EqGVbvWY4xpW3IRoi4ifCIdXCFHUP8c5kPcdENvbdg2JpCRuMMfE2v7ns9csKmsH8ym+jPSmU+3QIA6JTviTPxRIgwnfxlf8HSaJ/9oc2HAMqZvFlM3wKK8MUqqyVAsxRL0FbKKja7tYkhmqAf7ZoTf05UQ== buildd@grieg
+from="::ffff:67.210.160.89,67.210.160.89",command="/org/wanna-build/bin/ssh-wrapper",no-pty,no-port-forwarding,no-X11-forwarding,no-agent-forwarding ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAnN41Akb/8KU7n10twyuQHZhqmoL12vG7hvdTi9LokcNKOgNXi6LpCUNQHz9HB7T5wKAe+XtxvwYOVvyF4xBoF1czyLiqFxmTPxkNtPJlzlMybZhYFQ4jGC0MxAncNCZPfq5dSwpxDrZe9ATPXBG7XQRFHIXKxg0jAs63VGUO8pn0Nc2InMOxdo6yi4gLag05CRPw5gLlf/G2EHDgTmZCD40HBuaNNF+KHtHhoWlVv0zdx8Y69Zsse4R0pc5y/p8DuybadDX8h5bOdY1ZMf2s9/D4gPlRjOSMlQ+8EO0RCe5DQqRSAPdtgAO5/Axg7oXZXSw85ag837kQBOf4fvBkYQ== buildd@europa
+from="::ffff:67.210.160.90,67.210.160.90",command="/org/wanna-build/bin/ssh-wrapper",no-pty,no-port-forwarding,no-X11-forwarding,no-agent-forwarding ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAtuS4t99RBEW7Af4nLwXZLMdjMlhcWE13ZgFkxc4m7cqVg/+Xf/f3AXE/UfWjvLEIXzyhLczO1twA5tLPak2yHazqYYMKIUYBHz48WLqxuVEQqrG06IsCkjM5XszCZ+IlTBUporqBWgt/GV33jOOM1Q5ww2XGnpwaG+XFIDeVfjSkjaA9rRXtxQNpiUZZlFFd4DtqZf+LQgxyp3tMr1OoEuf6E4Z1mzfGfL4WXlkX7vqSamxZ8UZ+HEyuLzYEUiB4/RZsFMyWvGC1VMh3Gjrlcs9Cu9RTEJH13S+jYfxugS5PEKCTUda42WAUNSXbJ83ftaLjr6FlE54proUdVwpAyw== buildd@elara
+from="::ffff:209.251.101.204,209.251.101.204",command="/org/wanna-build/bin/ssh-wrapper",no-pty,no-port-forwarding,no-X11-forwarding,no-agent-forwarding ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAIEA1R2GSoGyZ3mn6adKXBhguXa0MvulAWrU24AuuviWBMWXt4sMpR0JR6gbRrGhUuSIzy8viS0DVv5OcjpNDMZwjXiYJ+wEDZ/Z2HLWRcgrlVBwjaI51QZLDhwYYXxA47tNEZk8CWAQBeGlUvPCQAEgma6mW6ZwI+/N+K5ujzKleFM= buildd@hedges
+# armel
+from="::ffff:82.195.75.87,82.195.75.87",command="/org/wanna-build/bin/ssh-wrapper",no-pty,no-port-forwarding,no-X11-forwarding,no-agent-forwarding ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAwroffEAOUmkpGGbhhydE1g/HqDMKdAI44eQLyCF1a95n7rs9Heh4ULvwVgACdIjMQ4LVHL6qVLlcLivWJdj892et2blRsCKsJUk2auwWY6HFYwQ28Rq+wpQxvBm+dCJC0HJJQx3tuF4Havv4pRW2tUyYEqutLybWEuPUh/SiEbErSDY7mY6RlvCcA8N/PwOvMo7nv0FrQRB8JZw6xtWjpMdxv3t1vF7QD9n0h582pqbFz/VMy0kjCFW9IR4U3PkapdohBeZBe5nP9U58srcZkIa9CDcSTAk3Wj/sT2mocdEXxCAcWkLpw/Y/0BX3AW6TsiNSTyAFyGJ7ntfxkt/cHw== buildd@arcadelt
+from="::ffff:195.49.152.174,195.49.152.174",command="/org/wanna-build/bin/ssh-wrapper",no-pty,no-port-forwarding,no-X11-forwarding,no-agent-forwarding ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEA2n0BIpLNAATBbW2hUXM3pMYnbu2UTZQgEDrZDuoIOQliAAFB/h3ObXcDyqWbXf3GIfHxBSTA39sh5/utIjjO6zaX9KQwZAolKuwh9ijk9qGjklyG+OEkEyBJngmeHC8ukrmVZESxbyXYhfxjjmpk/7SOEV/pwbGy+pbKr14wJDJqAeh6nxarH8yC6FMHQYfqHS34oN67aHXR0eGF9my4vpa4NVGSQwV1gKoNWZ8Q0xmcFSXZ5g5GYUmOw/Nn5EM1UwbcNtAKqmamy7Hv8uRyQazogGPQ8RU/6xYgK0/fMjHvw7knUc0bZNA1M0a27fnCE2dGp9QL/GVdfPQD0kAh1Q== buildd@argento
+from="::ffff:157.193.39.233,157.193.39.233",command="/org/wanna-build/bin/ssh-wrapper",no-pty,no-port-forwarding,no-X11-forwarding,no-agent-forwarding ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEA2vWWlEahAxnW2J9licbr1acOlD8oD3hG0PvxR4+fc3Nb0T33Zx1SYX9B4ppoV0TjRGDUZlAhjNyxKT6fU3L41+V0lb3/dkxAq4KoQ/fyYM+2m4AdY8pmVkmIrKFJGcJUNxBtbksUBuKcoIBHoqEiLp6Y/ibfq9L5fzVPSh4FyBn9nzn+E8CaYLukgFUS/xAUb0y3R5RMOU1lv5cMBenXqiaEKgrkPzpte1NQUe6/FKbAxmb6LiKhIiypLn8VyXFUOg2kfzSBqaPKb+tT5/HzzqQimE7FhIO9+YDovi4GNjfkZh3Xzo/flcFwNGKgB2OP+p+RizLY/LlOtfPyNMo0wQ== buildd@allegri
+# armel (dyn)
+command="/org/wanna-build/bin/ssh-wrapper",no-pty,no-port-forwarding,no-X11-forwarding,no-agent-forwarding ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEA3W+zlc85/J6v9QVelhevO8rZLtdMXjFoM6n8460C7psdsn9CMEd81kWFchCjSqsnpXLeQ3tu5n6HvyDtHF7FP22kmGY9YKPnh13OAomIP53RNyBJxhmwksruxspedrVk4N+vk3sokY0UuFOLzkPjE3QICsH+KxXC0TGeWxLL3P1IL0Gx+GbX70eb4807F4/vS4lGhlcK7R3/m27izIi4Sa6uDQPz7GPVYOsGKQA82n2vwl/7XF2o2b1fFRhUUWzcC4nM8gFbiN7J0a6qfmYRgFktPNJk5vqo13Z7/NC4kShjA4zw/F2ruFGxYBa0iG4UUV342Iwhmy4K3LjwLbtq2Q== buildd@muscat
+command="/org/wanna-build/bin/ssh-wrapper",no-pty,no-port-forwarding,no-X11-forwarding,no-agent-forwarding ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEA347Yls7VDd9ISTO0ZjD4PxVl5IDr17nEJrMdffboTZgWB6VVuBySPl0qvSZlwPLZBViaxn+3VUc/smmOLBcdpcLDd/Zi7tBPMVMCKrDjhlY7qVwVPEYiGQXlP6h7IRkYvJprCus2XtDsgVeiKarYQcrTManaJGvKqE2prl4Ep/814FAmqc2fOEhbXE5cTgQgH4yQFNw/aG9puCQphWnSt51sRiumi5+Ur/iI6kv6M0at3FPTUvz15X8epswuPrbJb5eMoDt4N2kCb1CtGjlW3s8gSapTRMTkBfPUG8JQufxKW/5LRYhBEXbF4iWFRDenOXDFSv6UnnejanHwnyb1PQ== buildd@ALL6500
+command="/org/wanna-build/bin/ssh-wrapper",no-pty,no-port-forwarding,no-X11-forwarding,no-agent-forwarding ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAvAwdXbvqaYHE9XaJDH1x0cq6ARxuJXyp8swKp4xh1sihkt61NqocyGkktyK7tai0OKg4qmg3/B/VaGvQ3llRDKtzVtzz0o/ZRpH/viizjTuxNfLVCMgrksPxfu6QytaEV4e1kdWA7D8acGu4h3XTBDdEHy8vHyxa7z3b/FPZktpjKp2xvBy95nB+MvxsexljKPaJ3nFlbzd1NiNObFuMZmCJGutlYiITq/DwmD8OzRclCOnsklowJjAckniqZKjUMuF5ZsmOwSmr/fX2grtHXPNXLeyWlDQqU0tSePtu6KJKN7z7r4+jHlLz0cxC0S8bVL64EorEr286iCrGOioPFQ== buildd@all6500-2
diff --git a/ssh-keys/buildd_hppa b/ssh-keys/buildd_hppa
new file mode 100644 (file)
index 0000000..d23727f
--- /dev/null
@@ -0,0 +1,2 @@
+from="::ffff:192.25.206.15,192.25.206.15",command="/org/wanna-build/bin/ssh-wrapper",no-pty,no-port-forwarding,no-X11-forwarding,no-agent-forwarding ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEA0k/bqIUDKIpwMcnk4lkFmLoaChBjUNx0L18PFpvp77scdB18tf7lpNjq0p9WT5tH/hC6GzSlaS8NciuxEvm2jr9nlhLaVShAxWy3RO/WpSxFEJu2M6PWEAURz/OUA5ylLVAZM6cDS3ddDdu0zMMTTAU5A2V6yB2/Pih7nxxWyJJkpMjpSN+c2DKUP3d0cuVSPbcVVfa27wFy8TD1wvHTlJ9WXjFRC3Q1Qoer68tDSooaz0eaYjHHkK5Dh/r1IrlZ7GESwjE30sQSdXqN9Qoet5lrjI3QrbOIZnD3ypgALKNLpK3lrYDL9MH8yaMlTKDQn3jeFjD1iigL7bFuU3bRvQ== buildd@peri
+from="::ffff:192.25.206.68,192.25.206.68",command="/org/wanna-build/bin/ssh-wrapper",no-pty,no-port-forwarding,no-X11-forwarding,no-agent-forwarding ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAylzBBBSGsSIfnid5nlKUK99/O8AC1wbkm3b9Vt+keupUszv19uNqRHnN1Cl09KD5DyB+XRVuBQGysBOsvnHwafLVDK2RV5Fxnogr5fnNvjgXveMkNqFo0CEyQ6zlMrKXfqfV9DqegrqgbDeNAMPHjZ7kMJP6OptSC80OP83wrf2a3szY4XEBvsT2b3kLY9zJiWyhuX6Vuw5EKUtVrqryJTKDtkINGILQkQ8OmW7JFg0lCpTWH86ja7iGk6E51nGhE4W3qgZkKXWXv/6MLF2ZgQ8a/8mIIJ3TRTCtNHGGvefF9rNrXuQzqy5YinGU0ON1eMJ9jw+IbdMf3rsIzf2usQ== buildd@penalosa
diff --git a/ssh-keys/buildd_i386 b/ssh-keys/buildd_i386
new file mode 100644 (file)
index 0000000..c1968b5
--- /dev/null
@@ -0,0 +1,7 @@
+# i386
+from="::ffff:24.84.192.180,24.84.192.180",command="/org/wanna-build/bin/ssh-wrapper",no-pty,no-port-forwarding,no-X11-forwarding,no-agent-forwarding ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAIEA3Fm82LFu5897FH8/A4DP+aWeVdQfKaTMUon5CeK734yVFIpUgflX9X9PC+QPdR6qac7EC7BVr9vmjD63JiMFrm7z55YJsUCauE73QrDsuoOixRFKiCOSLSn4EN5+oqu20WiMZiKkU7nl6djbJ7gzVKtO4cXkJ5XvIR6bKt79bes= buildd@cyberhq
+from="87.106.4.56",command="/org/wanna-build/bin/ssh-wrapper",no-pty,no-port-forwarding,no-X11-forwarding,no-agent-forwarding ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEA1RJRWEnU2cqZd25ejj+KT5ARXJdlRTaGgY4+KZ3A6j+UDJPnFipSujW4AcDqKlDnYD2M1pOjmFrUjuhkcndqJbZOjmZjXCe4gbRw7kp9mFDZ6N8WkFget+Auk/+g/bTfpqfQBYvkB7egjV4ZXrL5ndy8E5hqL3+9hfyBvmjatr4xFTSDuo07fvXcaYn/wuANu18u04lU1YrSSwJU6cJYG2gMcQ9QVSK2p4PInNTlmby88wZIOsf8Ztm7epai+skj31l9ghdBQIdewKAnGavwmp45QBdmoW9QWaV/0tV2AGQvHQG8uPWOJsxkqDmAhtpxNHnaN4SrYHGzg2/SsHQWNQ== buildd@puccini
+
+# amd64
+from="::ffff:77.243.184.66,77.243.184.66",command="/org/wanna-build/bin/ssh-wrapper",no-pty,no-port-forwarding,no-X11-forwarding,no-agent-forwarding ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEA4Ti4R6mILSIiR6SBoyxY3r+f4cstoKgcVkjEE20Y/S77Y97lItFSjkqVDoFtjTGCLcza7aKCVahGWzf8gZKYZ+SnzFA86fN9XLJJnVMBKd46mJiUtHyOoEgqQUx77rKg0Y5fwEClQUFV+BiaIjMSUPx+V+qDcQZ1iapZoe9V39ClLvuZ1rUAIuM1OYWstcRzK/0ubNEhtwYfSGTeZGpk4Jj7G/yDaxRst7oZKVt1TR5bWUXUPZJz54tg6QOiQwvL+jyaKR1CiL3SIB+pp7zd5TokFR78Ei4krMLtp2M1vKmWL/zvsnsk6cfM48zIADtvtpryZvuWXc3qA/lqiWT5dw== buildd@excelsior
+from="::ffff:194.0.163.247,194.0.163.247",command="/org/wanna-build/bin/ssh-wrapper",no-pty,no-port-forwarding,no-X11-forwarding,no-agent-forwarding ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAgEA9vips7l/IdrCpfiGIX9LrFIQjYn/oWfiaWoJ4z7hxHV6kVQ1tiuQSqnJcj/pE3jGLicgtfafZEBRP9qPGemcVKKP0grIV0l09Ua8qXbVpj847GaYBYOpmhbodz1Dhcxa/G4msjrfsZJe9zt5LmmTpCmAOTh6SeINHUmpmfvdO8IsKyfbUYdtLWpCOCvVS/MFP8nkcj4hdzebryKIVgTAQvEVdRQy3WDi1eA6PS1gqGOIpere1GSs2pKECfp9jVjn0lvFJCfVIDG6ytNtbUZSf472V7tLT/D5uXHsV8vw5FiAAPxuK70QpAJtl+mCa4FrH+mXUfbE7OocEdikzQocHJ2jv2ySWyuVd27/7p70cRyKj7yd/YrFhmLGQJ/O3g9sMfdVuEzqhgvDTUnBTnyQj2TL/oSrHr+oKAyQP4e+W3jSMhcMppBF8LArCL4sm66hSERLG5lwFaQNgXqb7qF2AqD+RHVAUpOapfcNjwhaWF+dYrVYoGkjmYfQ83eLMrDwGgA6rYFiyslS/zfB61I5NVo5AXL5CFuW0TJdjoighc2AZtQGsjFKZAv6/UkD3Fp9MdVXSHS2zy25k41TeHQYZs8aUoPiliBEfiPPPl1blkEEfLHTyx+/YinnoKKJMCY7rZOh9L1YaiPNX7BoLkUJKsNkwyG9PvhaQjW9z6/pYcM= buildd@nautilus
diff --git a/ssh-keys/buildd_ia64 b/ssh-keys/buildd_ia64
new file mode 100644 (file)
index 0000000..30e653e
--- /dev/null
@@ -0,0 +1,2 @@
+from="::ffff:193.201.200.200,193.201.200.200",command="/org/wanna-build/bin/ssh-wrapper",no-pty,no-port-forwarding,no-X11-forwarding,no-agent-forwarding ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEA6cnXw3IsbCCyw/MnLxRENmRiHtVxWFNSVcbmblFRvjWJbgR6f6gYJZRYIuxntdaJXntmXWj9fEgJP0pMpC2DsMJHaRsRNIJJbA9hM9V57f60tvWSgAZunPZdeRU05dRQVe4GwnAeudRykjut8++2jYWKSJC3/q5zy/zNbqYCvF4yl3d9uAcB/CUuYNJ5T9VenNDv2ZsYWsYDhRcqE58G3CkD4lzv3hownIKkkx0EO3wIETzuX4mJKuZUbzzqTTaMvEpnzleMVuQ+5cxmIsiSwqr5moZ0g0JWmmeszFPaCfMeyFqfvNClUirR0jVCK7TfZIghv4+USnga2gDpbRlwnw== buildd@caballero
+from="::ffff:192.25.206.62,192.25.206.62",command="/org/wanna-build/bin/ssh-wrapper",no-pty,no-port-forwarding,no-X11-forwarding,no-agent-forwarding ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEA1T7OEch0/VQxMLgiPLlPJiGYbOljVvCFs5KLj5qgJt4tSQ5VjINs9tU7R9m5693pmwfgyd/T+JQCKzlTYFbVZx7ixOWKdY8I2UNIpSdcK34q9OPVHqbDr0WgL4GfhLNtNv567L0Z8TijbWVYjhJIbX71YWM2PyYVlIzQkhoW4lE7K4X9+DG0y+1PjNzRHqNfbdW+Nf6a45TgpPDPawv6c/keftE1J+xjLTOonQwoddypmctB4lbSO2m1XhR4E/rR0LJFAF7gvdh8cF+5aQVgOKb/CIrG6T3q9+Jl2fD5nLjnAsLUhzDtLTfc6V03z6ZRw7zHCZM9Bn96Y+fK9POJHw== buildd@mundy
diff --git a/ssh-keys/buildd_m68k b/ssh-keys/buildd_m68k
new file mode 100644 (file)
index 0000000..9d22e99
--- /dev/null
@@ -0,0 +1,48 @@
+#
+## Buildds on static IPs
+
+# schmitz@
+from="::ffff:134.99.176.50,134.99.176.50",command="/org/wanna-build/bin/ssh-wrapper",no-pty,no-port-forwarding,no-X11-forwarding,no-agent-forwarding ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAIEAnTTQJl4vVxUgNl+NJrcsOsFmATQipH9IcZAtUUXYrZDjfbhvf5+o3k26TmRs1cv+rKU2yVUYKlVWPeAGfCV45Beijz2DK05p0P7whhTGVKBxGfrL8HYvNCjVQtD6qn3pbBAGQRwXv5F2KHKNAbGkax8vEM4dH795KIqyWfqWlys= buildd@q650
+from="::ffff:217.114.76.82,217.114.76.82",command="/org/wanna-build/bin/ssh-wrapper",no-pty,no-port-forwarding,no-X11-forwarding,no-agent-forwarding ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEA0DC5JDIL1x54cIfy2pPCO/REad5pOXEYKAsBLso55zlzkZebfqNWyTc66+SwmAYeIwhnZl0n1NmFk3lvB4Y+oAtbJtOiOTLFaAXo5cZUHDvUD5+0DZ5AmzXHW1ZCdzBNmI2uHn7nHsv2gQ/ol3pityqQ3/9fzGrO+UJFLqkfcbvCzKtWEfIDUrIHJsFqbpwt60KMuo/zfouiiiqWC95JIk4n9F1HQN8OjU0ckYg2p+kHO7S+8wLtp60HouamZKoI7ZJV1R524FAPH6Rn+GR7B+91caiTq3jX25Kw/4gyYMZCn6v/OXE+OFXoQWFdeSCBrlWtjdJzjTY3g9CUMYLytQ== buildd@kullervo
+from="::ffff:217.114.76.83,217.114.76.83",command="/org/wanna-build/bin/ssh-wrapper",no-pty,no-port-forwarding,no-X11-forwarding,no-agent-forwarding ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAzaClk8i93tNL3MseNHCLZBfqPzdujURnJbcMQljHmEYTzD3uEwAmKL8gtfrXBgWGiIdPZrvh2+OU8x0swJUU0L/FMcdF4SyLnu+/ePnUiHr/YwkInM7ZXF74ZQj83RVcGkKGl7Gu5A09pIr+udGm2wdt4zpAarKYYE6BNheGeWmKdaLMMszFoxh03CfSqg1riw90FGyCZ/ZnJ4JRvrR6P8IJ4nxiljGt6H6qyet5F5D8DjcFbUSAIbn49cXcsXdATfgvpSfxOBVJqQlM4yfwa92MrUHCb7eez+lJHWZnNUbIkRyuz5G7oABHrWYAkpFbz/h4dK3HEBaCMqPMCKreKw== buildd@crest
+from="::ffff:217.114.76.84,217.114.76.84",command="/org/wanna-build/bin/ssh-wrapper",no-pty,no-port-forwarding,no-X11-forwarding,no-agent-forwarding ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEA4KkoVKlyO0f3pomvxjxTpaoqJGbdsH+jwQE0K5oWedNLqRfBjTjzPlQDvxHOnBvWhospkcZ6MHWcpjQ57l2QZOkR9Dyig3qDAt9ny2KlbLeHRs2uKy4FpZkFrC6ocbMR2e7CQNfAsAC88eP7iCOwKEf0LKGEWahBFtHMxbCg6YcTZoZvybOizpNmozAXMM7nVgxH4WnBMvolN99OrV0fXfZJnDEwctKtfvc1QUGYNK1NfNdNRVCJwlw21gRd/V4DRiWR1s5SgO4UETFzX66n7BLt4QRUvEG8m+jvpSQKjc+A1fQ0NeMVCVpVL59kOX7xqaGZ8vWPdDLNBvUeAWFf9Q== buildd@elgar
+from="::ffff:134.99.176.41,134.99.176.41",command="/org/wanna-build/bin/ssh-wrapper",no-pty,no-port-forwarding,no-X11-forwarding,no-agent-forwarding ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAIEAyorS1nYen5OmKgSxTlWXO5bBMlNdmnTUhTje2XeBiEqqge2dvAooMU9JppTS9ZebSPEcVfNkWfZ9sHIsl0h3nabEvZRvUWzBF8JRzdZFVW2ZrgWz76iVaP+uOqDhtAkwN2WWqBBSSyZNVEIBcWrtDzAmpI3HUSyHuNrp2nOCXLk= buildd@hobbes
+
+# wouter@
+from="::ffff:193.40.6.67,193.40.6.67",command="/org/wanna-build/bin/ssh-wrapper",no-pty,no-port-forwarding,no-X11-forwarding,no-agent-forwarding ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEA3XVbTuDaO91/wD7xukMnrztMtMi3FtfA2zWCqdmwJSnQ3eOpBUZVLFPueIt5i5pI3TJPAdA0OIpR/eRQo5FxLu0B4+WQK415odrcyHd86sYDVCeFowEN8atbxooShnCPICgRK9aWn5uOsQCKoDP6BrI0kDJ8SfSJ3LpMyfqmEQYeYZqYtwzSSbt+B5X15SU5RJCozEwHXwN1TRsyRSpQ//OFb6YP6AWWEMjCKcAaLtURCiwXXAlvYSRAMeYXTHj3AoUBt3mZoLKyX/DcKgxNssu6kSUQbFGqRcEDhsM/BYFpXAD0UdYXaHsxdUd2b8t7tCdqPTPia8ES9MPDoHdqGw== buildd@kiivi
+
+# smurf@
+from="::ffff:192.109.102.51,192.109.102.51",command="/org/wanna-build/bin/ssh-wrapper",no-pty,no-port-forwarding,no-X11-forwarding,no-agent-forwarding ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAwUXdZJcOI3rXYo4HD6jzlMjn86x5yUK0aFQ6Qs07R1IEZ/SRuMdg8pO1sG8bc5XDKpmdiwcVAGo1xQ+Tlg62Ajoi2j7QrhCbgjsN/5pniD0W9T8ud0V1+oYVzx5nPlw60cQEqhHq7g74qjO2T2APde2dwsyX5ZlRs6gChjBwC9eVlir+SkgvcsbH57u1MD0jvsq+ByE9t4J7IyvPYduPTWK1K9RpLEve7sFkW7W20UewFYGtwBGEKyehkyvniywYuxvRK7KNvODf+3qbrwBe/3mVZ0SyPiqly9eN3r5ouTVtlSuLQR2Sp40d/4oQMIq2Xe1IsU5faGovunHic0RJaQ== buildd@akire
+
+# younie@
+
+#
+## buildds on dynamic IPs
+
+# smarenka@
+command="/org/wanna-build/bin/ssh-wrapper",no-pty,no-port-forwarding,no-X11-forwarding,no-agent-forwarding ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEArRPb4XLES+Z6351MYLC/+DzsCXCSZrJ1dOUFIppIBXRofwQWu8JhPcYTFDoaAefKT4QIBLqV7MGk54lQSOjcnlXlJVQ2FrQ+cmG/25gkP1SV4++uwOdY9lP0MQax4vg32qhh0LwpAeLAaX7gVkllTMSJoYHpFHx9/KhWXoMf7t5RVQVCbXVTr6qMG7FPqsbvUCHITI08WBYLjfddoGBnbEo5APVzfyvdAYU8MfA0cRfYv/54Sem9I6qguJrRdxU4rqRkyktnMHRziLsgMhU2u8dJ1hr/VKhGw/s8PzoXcFvgxZ7EeCMsVlzCGDvqblFy9MBF9OuWdSmeCgWwTr4B7Q== buildd@zeus
+command="/org/wanna-build/bin/ssh-wrapper",no-pty,no-port-forwarding,no-X11-forwarding,no-agent-forwarding ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEA87tSzPlPdLpVxk9DXmc9qhg65VqOX2a/QrLoWqZZakivRzQ2yNdoAIxrLcp6agIxdQ7JXpXuXCGzGQA2u9ligdf0pJzxCGgizpF5h+2a5eJ8zAAtfcXDVi3ZLvZ3MLuhVk72161wgHE/MPzg8iICoyd9MsYqv+TC7XUu7J5Rs602CGoKXjJn2GAF2fZSK309xKlmuJrVpsttERyPJA6mNS7s/bAjKB+kst9E9bJl6muV1BT6qCYyWsIDFxQ6CSIGCmY6jMjzHdlNrQPqOj0m/QAQISl5CDF2cFeJOgEOq5L9xY9r4aQo4fbOTJKkZGJO6WbogsfrJLiDlp+hYecMbQ== buildd@poseidon
+command="/org/wanna-build/bin/ssh-wrapper",no-pty,no-port-forwarding,no-X11-forwarding,no-agent-forwarding ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAnbX7IdN6u6sLTjCA+XP6LbxqZo8skgIzpA71cHCQNs2TlNYwmV+ia6CuuU9YBKJkoYXoOlmmSMbKIRFTjDIsE9u7Yww/wuetp2Cd0VgJibw2lG4lyaH+FEAyIK6ij5U/XXzXtWlUFChMlUe4UdVO6g4gzIcOIBGkpb7OhayZq1QYrgfhGV0NFlHHcm+vkd31T4y/RqN3mNmuALfLWI5RkauQ8REWPjtU43UeTMQ4TgOgmML6/GcBopdZyjEhad/bFUHwLYdAA7duRTAI3SjgtQHNte3haZe/xfwBpeAsZ/nCYsvBhBvdlDHWI3UQ/ZkFnFDGJTGrVm0U/zWM3KG0ZQ== buildd@thing2
+command="/org/wanna-build/bin/ssh-wrapper",no-pty,no-port-forwarding,no-X11-forwarding,no-agent-forwarding ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEA1jeAU6UzTiDjTsHAPwYHmdMdEVF7JFigYYqi0ZNQP5aHoKbr8I4QdHQdlM60yL0LKNsgWBZcCSKe3J6MWZLdYjDt8XIWSNixn6hdwIXsmDoqY1xwG+VbAUxmivjM7M9Fv29xYG9S/WzbiyRaRwWsbx/mBnA2qcz+E/vZhZ71MfkxvAhHIqXdvSY/OUQBtGR8m0ihnJyPzbt0VhNU4bVo4uMgSPLRZ/TE9HxjV9w1cBPFmHOd/sWiaF/nUsIp7C+UMPv4+9y749f/LfzCxodjS0/UGElE00utESOmSkzmjnvcqynrip2AXGf8HdOHO9jqAWElAJKfHSzGONE1jBMXDQ== buildd@vault13
+# aranym
+# command="/org/wanna-build/bin/ssh-wrapper",no-pty,no-port-forwarding,no-X11-forwarding,no-agent-forwarding ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEA6B87qF9nUOfZ6YqhrVs088TI0l0R8To0qMoz4Ws5fhBQxY/d585aqYASqgFyRyTbcezLSJgpcrDhNFuOoRgxjlArmagJCS3n6SqmFE4n8K4tDDu0ozw9pJEo08Z00L+lJbqYlyMSn8wu85CB0mwYB2XWvM47WNTEMmzCcP1IbEp+uhop8YV356keupJoGOBDLRlO5Is6lK7M3liuoAcsWJV8tzSCPF18BEzTskmxPhfuJ5H4pTWM0PRleF8SrkTvib/n0D703Wyp0cMh7TkEJwbUG5WuuJrxV1cI2A0mPymQLXahxygW3ceulViVrAMwoQZGyg3AXVC4lqGVooMASQ== buildd@cybele
+# command="/org/wanna-build/bin/ssh-wrapper",no-pty,no-port-forwarding,no-X11-forwarding,no-agent-forwarding ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEA56XH5+K3rBfI9in/HDt8amfoSrqPagIT7YEhqiPy6GRoMYHIeTILyh/7Ov+dYawD5FBNTW9x96qrXsFffpd/pmtnSBSzh8BKDAj7a3xEC98HLXUrgWtvoqwD70YwXbY8sWkUDvLvMIkdBtpum8Kq97YD40+IKm9kxuAfYy3WZmKQuHlTZpD83QKwUqVCmTKA9sWlwS2OWsBuCZAlYonJdbGN/EMBDi0VTJAbV0Wki4UgnrTCQERWtjlLY7ZPG/ZkNGnFc8PpY3Nm86k52ulbV9vkx7bnYVioWwPwECn0FDkDmHQEn6ox+uSpWmDHoL8dBO+9ab5BwuvLsuHOR2oMQQ== buildd@minthe
+# command="/org/wanna-build/bin/ssh-wrapper",no-pty,no-port-forwarding,no-X11-forwarding,no-agent-forwarding ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAvGh4b49MY3tJ2bE/wBZZB7uyuE1RXoNzGoHtizO7YsINUsGe8Fr+8RZlYJVBrBSP6mLj2yzwuRHeaOCKr3beRi3U6jGHZ61pPTFvUaeOf802KeefjLtyTurPTPB9QOql1Z5UNut2Tdqyud9Gv2wIkNYm+h9/LOOpD1xZVfKfQBvTYvqKseAel1REHHm+iPAGj1ifQiMtCVPQHrX1J3qrOQS+NExowXGAcObI+xqIzdXBcAWmDULjHISxkt2mXPqD2Guob+d3OW+zFj0vAusZBjEJfCpLiP036XyyYWc8ibWBlCQAd1sFZsAfyR8ji4XH/oAfM5THI7TN1nFVCuA5LQ== buildd@phoebe
+# command="/org/wanna-build/bin/ssh-wrapper",no-pty,no-port-forwarding,no-X11-forwarding,no-agent-forwarding ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEA010hOo4UdcSMrcm8TBp6UNAmcjrqBPkCOMKZbUjwh+3Ghkikc8wpCoyxwIahgRzb9kz+bCqO9MZ+vAxSoTaVTJLhvBMrbRvNPhHu0ayauPBBNjpM879RTKOkvgcgHvuciWnKiR4MY52csZqzb/LXm1Hg/Y6qfeO7PR0JxDm3pPmPM8C9cp8k0BatusvunxiGI1lCpkkkndYHggNQNWF9VEp4ZWIzTlaWKsrUMBEVbldICHhfBUhJcRutZojgGnCYS+sjCGpzYXQ4T3Kvzz0zSVsffd0yJgnuYgpO6sN4l791ymdgO5WqTrSBSzMjn8NR5I+SBJJSnX/59jmELjtlyw== buildd@theia
+# command="/org/wanna-build/bin/ssh-wrapper",no-pty,no-port-forwarding,no-X11-forwarding,no-agent-forwarding ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEA69Do4o+VL0OvGn5q8mRscv1ab1RrknEs2MdIIAsBSMtUIiph4C9G5U67oLb6svjTL/o2Qwb5BSo5v9LcH73CBOLNw2HF31ncIOnB+6JDY1blIpWupkC99YNbLw07rjPAxuvWEb/1nvSLW8svq76xs/yDd1l01jX9hP0SNWbbap+elIa8qLdWyGPir9kN60jigSh7aPUujFEgvL3ZIhIE1xXGreVfWMIc0Sks1LwhGAVhpa2mvUJS9Lcqdpr6Ql/R5NpL1AtqfBNbORu/yOJYPbKlmN5JLRnYMUGpXwHxStfe/nXC80Btalwd1sxB24rRNq156kZnw1KV8HaLGFzcEw== buildd@chaos
+# command="/org/wanna-build/bin/ssh-wrapper",no-pty,no-port-forwarding,no-X11-forwarding,no-agent-forwarding ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAz/8SkkKaepTv94GPsEAM4bBqp2XSb0plIq+ZCyol32QQHgUFAA6blAU5RZcxP1EZFuyDhuxLOrpz/oBKCVtEDy854vWrtoPYGmRLOPFJHCby3BjX/oVnGPfPlTqRuB7m0tF4dwBUqxnf2G1yEwRrnUbkFQXxJ6McCURubXdcpeFZn/rB9t2WRnrf5YmcRkD7a7esm8dDfRLVAB7fKg1znzklOTMLxgQvMcQ6qFZjlprvzRTMxSRrfV046NXyNNk8er+0EPWmk1/Xm+bFvd+xM1Zekrqd6eABxUEp9JkH89oh7Y0Rj3126ef6mfMHxC8y2SMft96jLUYVitNWQsEtcw== buildd@cronos
+# command="/org/wanna-build/bin/ssh-wrapper",no-pty,no-port-forwarding,no-X11-forwarding,no-agent-forwarding ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAnSV6ojpTyq4gBb1LPn2acxlRzb7CizFbR6zWP5MVdhf5ndY2nC1jrQv5+dP1TijLMRhFcCabb34U7uErv98PG64B0wVpPGG8F6f2ZdpCA/+IpxaAUmezhZCiAKtOBDfsEhrRgasyHsG+UqRlbf2fUrpMp9XSPEWiYvES7AGw/k8go3oVA8WcSs7pNsiN+4pwpF0d7KRJczNd87vgs3ttBdSORV7iXegq5Y0pwFiCt8en5/OKZLjJcblmMHdGqx9yeREqhdX/LUc8OMdrz5bC90uGnpwGneQ54TuN7tdFCs4YbgXR5HEFMf8FxyzpfGB89MPLnmhLdU8EsmWWeuUaXw== buildd@diablos1
+# command="/org/wanna-build/bin/ssh-wrapper",no-pty,no-port-forwarding,no-X11-forwarding,no-agent-forwarding ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAy+L+jE79636Q6cZA/o407q95fgYKaN+ciw+lpiB+A8szCCfrfhGiUVWfX3wgVjXZ5/xZ+K44DafQ5/CH++CO588UuZ6R3l83hawb6kAz/CmOtc5MQjhpr8xJYfhCrOzSsWPifmhVaesq5kN6WaOD0F+rOaorbxept/delIN9Z4QcBaDEA0eeu7zNIsItwP9iIJDgJoHJaege3ggPVZ4CNTKY1tO5dsBM6ansZvYqO9aR8JyjnpcKUe2WIUP03itAUE3xTg3UnRE2uSNWU1/bIoMq+kbTOe3E2MlMhyRu0PnycAfpuHj9einVAGcVaXJDRbN3Vgkf92+SmzSgtulyKQ== buildd@diablos2
+# command="/org/wanna-build/bin/ssh-wrapper",no-pty,no-port-forwarding,no-X11-forwarding,no-agent-forwarding ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAx4fov1N0xFADwEhECTRfZavAa4nnxQEz7ocZRttBbJwiWl6u+nxSKE30AFsvH8OJbv588WUAEhEjTHRCSYDi/kIWyCbSAMM4sfaVPiVyCZg/UyQ342L6Muq5wJ2k/R0bjrJk/nN0NEuRbwcs86wymuMnBcOWlpGwoysXTbLeAPgm+kT4vkQh6LVjjCOfLzJXkniHkN8M0/xyME6TCF9d9hCb8D8fbFV1e+usw5jSwDL8bGU6WcqHulIsf0GZZ43/OSAcsgpUroOW9B7ucjJbv6m/ZoCI/CfGntz2gqccde6CFwVYE3cR9VIJryKEahYEZz9+XvK5R4cEp8S5OouqHQ== buildd@diablos3
+
+# cts@
+
+# wouter@
+
+# ingo
+command="/org/wanna-build/bin/ssh-wrapper",no-pty,no-port-forwarding,no-X11-forwarding,no-agent-forwarding ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEA27L4aLKbSP2IcuiBkpPqEO4y4hNTC7pkGlUkf+LF3SeKAE/zq/G6W2lNNgZW3av6rvEfMS5NsWxqCPa2KZOiVetJOaEJ2rqyE533rpbPKNIJaj/mKUse4Mgb9snOUh/hXlJHu+Lsx9IuHhnBp5+rdpF2JBQ3thzoGw2fkxOQ51g13bXLYYnAkLu0uQbh+RbiBWCSDo6B89gznWL0hOifDPRzzGjHnzpho4IT6DXkYJmJSxqGuK1XN99vGcSG+f1DU53i2M7JZQ6igEjeX4++TlFQ1mwEzb3Tn4+pA6iOWA7hMAEZ4OREmbGAoWDHjzgPpyfPuibSXG3EoVhXsVG6rQ== buildd@arrakis
+command="/org/wanna-build/bin/ssh-wrapper",no-pty,no-port-forwarding,no-X11-forwarding,no-agent-forwarding ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAqr7hkLsTIQpN0l5/omY6GcwpxDw8WD7WBoKmer7Xj00akzoeBNNskZRfTj64KkMyLCpcQEPBZH6JAuf3tmTfXYCOTnO8HMlTasiNvDqlJcuasDOA7ATmzGGB/merHUgFO7zphYgwVy3gNoGPycyGHz62WDdaZLVVAUvQRIQ/9iBEjGI0gBvSVU5WciBIiePLoVk5RnWATpn6VEmE5pu+Etsh518x7Nty2hvDqrbWPbua/qmUsH4c7sXIbM6kb8GlS45c29WXeaiNenkIQeQGT1RfEUb2ONHhljvUXi2T3GwwvDSiuhdaTVkCCPuPY+lGKInWsEJUixkV2SzYLGaPaw== buildd@vivaldi
+command="/org/wanna-build/bin/ssh-wrapper",no-pty,no-port-forwarding,no-X11-forwarding,no-agent-forwarding ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEA0zJxJPvABPYAte2vGurvOp/1Kle4hYSa2gOpxvUcepl6C9ScqdybP8VOcJS4sIpfLLht6y8bnhsQLWeQgkAI7qtiKqDt0GQuFABfVyiyVp96u7TLGsfU4CUn2QqTNk1AHBwmegM0IordXqC6SvgexIn/LphNSX+LSHWQksi/Rx4QANU2uWQlWwsXcDPZy0+UF3NezWDT6mIIRRI9wPDflyF2AzhhvkSzQQyMRKhhKn5bawP8PEdK6mTIthalFX4HTKzex08KYX1CTsWuWCXlTDmTwc4y3eYBqi/fq/faCrlyVFczid/vCKMaSQOS2j6ZOYAjCdpB3ofl5OAUBzvNkQ== buildd@spice
+
+#
+## non-buildd keys
diff --git a/ssh-keys/buildd_mips b/ssh-keys/buildd_mips
new file mode 100644 (file)
index 0000000..ecc0fde
--- /dev/null
@@ -0,0 +1,6 @@
+# mipsel
+from="::ffff:195.71.99.217,195.71.99.217",command="/org/wanna-build/bin/ssh-wrapper",no-pty,no-port-forwarding,no-X11-forwarding,no-agent-forwarding ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAIEAsaS8OpwUZj9r02wEmYdhcTFiiLxyni5N5I/8kRXlWvn4Qru9rWfTSdyD0tveGEsfCqgAB2wxLQNqzVxCmWHcs+LZ1nAhfnT2vgiouvPaFCUFTiso/nKQJITcEO8MvMdT7dhZ6VOdb5MNsX5+eS/uVSQa/pDDamCYmFJkLp6oEnM= buildd@rem
+from="::ffff:140.211.166.78,140.211.166.78",command="/org/wanna-build/bin/ssh-wrapper",no-pty,no-port-forwarding,no-X11-forwarding,no-agent-forwarding ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEA3xERSQ4LgRNWyf5HMOQdpELohhDhetAAe52V4EO2B+D/7ahlza2IO6uVvG6qvKQf5NJB7sZtVwz0oE72sGHjWsH3B7KBZN9GL5UvHNtZ07OSPxXxTEotrRtxnumDRlYG0MxROHMpFMu1hjNoPjvQZ7p3wwUV3hsNUAneMJkVJmZ97/NTigeS7QZwt+k3pf/4pXIbRLT73ZLZ9cu5sFn9g/ZARcPifa2OpW4Z3UQYde6h4Sjcmg0htKEEOYnqiMqNJyfXA0BvdIcFztaF2uzpb8t7kfpkc2vFORk0Ybxbvuhc9RbFdpmDLXB5Y4NVHNXAa45rHKA0VTRYgSB6d5YziQ== buildd@mayer
+# mips
+from="::ffff:217.147.81.21,217.147.81.21,::ffff:78.32.9.213,78.32.9.213",command="/org/wanna-build/bin/ssh-wrapper",no-pty,no-port-forwarding,no-X11-forwarding,no-agent-forwarding ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAIEAvrSXyX1ZTv9u4CM4C4xjDfl2CkKB4nl9fZ53lI2OnFEfKFX5P4xKJyRZAo0HkcldOVuTVznqYaG9EM79zLtKuR9Gh8Lemr1r3AUidrv2sLdMNlpZ9Efy37V7EgfkAHBA+isRq+8AR7xXdQ5O9P+mzHiwACPF8RoDmYKNmbWvRaE= buildd@ball
+from="::ffff:140.211.166.58,140.211.166.58",command="/org/wanna-build/bin/ssh-wrapper",no-pty,no-port-forwarding,no-X11-forwarding,no-agent-forwarding ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAyU8j+EmLo231kYJxXyt+TZmcTdfNoSTKkjSvN4Oh8Ms7+4+NUGP6XIgltoLMxL8QVgdIDf/A/CLnwJ7ccHpuOO2JQ16MvbeFPuOZaZtxaw9Q9WxXOSa8jgNxvBfGP5Qe2qgk1paPjDM+FVkgi/VM76vMgL4IV+6o341idNTuyTmWiSwrUJR9G3FncZajm7uLRIZALcN+WMiuZ24HkFDREEL2UbbMwS6LT8gY7z6jzNQjFMACxEVK8J0+9ACaMBuP+htKHJAcNWkmBJAO11wmR/IDnanhkc/bEQhRji5J9Ve99zsiW7j0ePosNkAd3ByFTXBeD7Yu1Jl9hbsliv5r/Q== buildd@mayr
diff --git a/ssh-keys/buildd_powerpc b/ssh-keys/buildd_powerpc
new file mode 100644 (file)
index 0000000..7f08a44
--- /dev/null
@@ -0,0 +1,2 @@
+from="::ffff:72.66.115.54,72.66.115.54",command="/org/wanna-build/bin/ssh-wrapper",no-pty,no-port-forwarding,no-X11-forwarding,no-agent-forwarding ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAuOY514PT+X3VT/zd+tO9YkpYdOLDgFC/vO1jAEFfMQWeOu55L5ynkkKe81lk9ARU2AmuiaHfyX9jhQ+Z3ivUAUxa7pILAB3D3cQxGMygAnQIQoEvUEOvm5FYtWrkOEwyECZ0X1hA6h1qBfLgA3ajYqmO0ErgTgyYYJTFBi5pX/OvZ+mEH0pCKjWmrTqeHQ3BoV8Dr4ivtNRzK6u+z4gas9BrlHVlhe34vqXSJimIzg9nrsI5BLhw4+Ca+NlxtCvGl3UeZ5ob7Z3dLA6vO116xT4ETIHKkCxg4dAPluR6VnJ7P9gVX81s5DSX6punTxDLuaPrZQmV7d1cmfxiKORZKQ== buildd@voltaire
+from="::ffff:140.211.166.27,140.211.166.27",command="/org/wanna-build/bin/ssh-wrapper",no-pty,no-port-forwarding,no-X11-forwarding,no-agent-forwarding ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAIEA9meQiK60jqQ3jEkqqo6rHHQiYwWiLKiE6Ax/Z0rDtTf4+oMDDHkioRK10Huttuyi2Vuyl26sOY+UWX6Sg/osRAyL7uUE4UX9IctoyA3FIPygXWbA5zPCWvPaZ64LBKteydOTTLTMsKl+eILFN7KTEHM41Deqy7Ql9b9A1mS6yvk= buildd@malo
diff --git a/ssh-keys/buildd_s390 b/ssh-keys/buildd_s390
new file mode 100644 (file)
index 0000000..3a83887
--- /dev/null
@@ -0,0 +1,3 @@
+from="::ffff:80.245.147.60,80.245.147.60",command="/org/wanna-build/bin/ssh-wrapper",no-pty,no-port-forwarding,no-X11-forwarding,no-agent-forwarding ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAuxRL16P9zPbqiDNkqGz83jM5fN//zhVUXVdLzzlmFKJ9i9m9FX+asZEWxP//KDOkpNiPfdRM5m2j3e6PjtlI/rjDp5pQB99/DfBvibbQvNkpNcXRxuFgSPj2vRSaQeHQp9jAse7vxviO6cmQf0Hcj8tPyh1LPx9JFMut8RvqW5sEg55ZwwRhM6FADWvC4kUQgQMCurnzz9SGcRKyt/usCcPg4D3bfoxb5ejV8/USvkMCOmOqyzbigaqvC7KLtVct05orntIGePDhWCK7RLxqxJctwXw2TLRX0ZoLK2oupbH6JHjDzxScyxzhWYb+gA7ZIO62WY6kvdS/h2gNdjTdGw== buildd@lxdebian.bfinv.de
+from="::ffff:195.243.109.161,195.243.109.161",command="/org/wanna-build/bin/ssh-wrapper",no-pty,no-port-forwarding,no-X11-forwarding,no-agent-forwarding ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEA2Q8NpL6W8Wou+ejA08pYXm7XyNu2HN2vqrFN3h7nnc7N2KR/reRQBdahh2nABxMUEn4+kv9HAsJj1R+cDIlyTA5+9zWY6j0DVwRn+4T3nTIkIY+wHSwZz3BtokpRCQ92Ym56ni+Q67AfATIVqn8TROZB3zNHnyARtb5cQDQGxfHsjLtZBT3i1THTzpDnvN7SevWfWsa3Y0moeP6LPly9Lk8NKApec9VDjXk1A7subKbNowsXGwmyBYUUhLxovw5R24GXgLucXVhc2UH9+xADmYu00Y37hcM1lOh2hIBwHAMpu1aBn3SKogjWk6GOOy31mv7BCvFPnApGkVxh1U0MQQ== buildd@debian01.zseries.org
+from="::ffff:148.100.96.45,148.100.96.45",command="/org/wanna-build/bin/ssh-wrapper",no-pty,no-port-forwarding,no-X11-forwarding,no-agent-forwarding ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEA2EZ0fOFLL7TNj9ndxSEWjtT/+vQj2f90yKNqVktsNyivvT4fUwIFSbsEuOVDfKcsiVU2Wyg61MUmZgXzhGaxFaxVSc6/hyW+LlOVqWBkIsDh4mSEVlC6scmI8sHoajufLs9xzEmRAeYLGGCCQpvNtGEx4rrtm7g25oa+r3APmPtH92j1gPXbPG/pYBB01VSlTksDMqdYIaBCNkLNFudWWX5Z8UW6maW5wV39NC7WFiydZkwWden85Z/oilPCqoky8mc1fb7gSbHj6GsGLTJ1IdVzIh6fjkK2R7FkZ+J7NnBxL2chzRuShdVGyZnUAlz03NBSsjo7i9yhDKk5oXp/Ow== buildd@debian-31.osdl.marist.edu
diff --git a/ssh-keys/buildd_sparc b/ssh-keys/buildd_sparc
new file mode 100644 (file)
index 0000000..6bb4f52
--- /dev/null
@@ -0,0 +1,3 @@
+from="::ffff:137.82.84.42,137.82.84.42",command="/org/wanna-build/bin/ssh-wrapper",no-pty,no-port-forwarding,no-X11-forwarding,no-agent-forwarding ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAIEA0K+ctT+ip1tSpv+96hJmBk0kN32DeVxLExGB58NEZMBiOivU2LWjPLASEjhqOHmGBV0aWCFCzhGgcsCwQEaB9iZTe6uvUZMk+KtBGLOH4pyYS/smvs5YkZvlaxGfYPmh8ZxSnnODyj9rJ2GY2RhY3sZnup2wCRnWXWGnIAOmey0= buildd@spontini
+from="::ffff:193.198.184.10,193.198.184.10",command="/org/wanna-build/bin/ssh-wrapper",no-pty,no-port-forwarding,no-X11-forwarding,no-agent-forwarding ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAIEAtA9/hr5J14/fbHNpIjHhMkc1nm6hL6gjHVZ/48gsBNItROwrk36rHYOld6/eDx+W66Nwr7q0NKEATFLqONoV+VdP5sVGYfImsfmAaB4XzgJBtU0Evsqs61D6zgIWZ0jAT35BC+chrQHG87ZcT/0e2e4ZnkH0KhmBACVsoFx8rC0= buildd@lebrun
+from="::ffff:193.198.184.11,193.198.184.11",command="/org/wanna-build/bin/ssh-wrapper",no-pty,no-port-forwarding,no-X11-forwarding,no-agent-forwarding ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAIEA177wFtAVJhzlVjIHzo8EfXgmtjYQnY9Y6wPEh918BsKTKSx4ik0GmNWMj+9sMPVWgKESMXfvCSk2tBRKQVaLv1ppiMePZp+S4MZlm8+9s6wB27B4OZDXZWsz9lRVbEufviNP4CyM80gJ/HJSbE5oep3JrwlpKBPk0PkvI0c2skk= buildd@schroeder
diff --git a/trigger.daily b/trigger.daily
new file mode 100755 (executable)
index 0000000..5deb795
--- /dev/null
@@ -0,0 +1,261 @@
+#!/bin/bash
+#
+# Updates wanna-build databases after the archive maintenance
+# finishes
+#
+# Files:
+#     Sources-* == upstream fetched file
+#     Sources.* == uncompressed, concat'd version
+
+LANG=C
+PATH="/bin:/usr/bin"
+#testing must be before unstable so late upld don't build for testing needlessly
+DISTS="oldstable-security stable-security testing-security oldstable stable testing unstable"
+STATS_DISTS="unstable testing stable"
+SECTIONS="main contrib non-free"
+ARCHS_oldstable="m68k arm sparc alpha powerpc i386 mips mipsel ia64 hppa s390"
+ARCHS_stable="arm sparc alpha powerpc i386 amd64 mips mipsel ia64 hppa s390"
+ARCHS_testing="$ARCHS_stable armel"
+ARCHS_unstable="$ARCHS_testing hurd-i386 m68k"
+TMPDIR="/org/wanna-build/tmp"
+LOCKFILE="/org/wanna-build/tmp/DB_Maintenance_In_Progress"
+MASTER="http://incoming.debian.org/debian/dists"
+MASTERBUILDD="http://incoming.debian.org/buildd"
+SECMASTER="http://security-master.debian.org/debian-security/dists"
+SECMASTERBUILDD=http://security-master.debian.org/buildd
+CURLOPT="-q -s -S -R -f -Y 10 -y 120 -K /srv/wanna-build/trigger.curlrc"
+NEWARCH=""
+
+curl_index () {
+    local url tmpname destname appendname curlopt
+    url="$1"
+    destname="$2"
+    appendname="$3"
+    tmpname=".$destname"
+    rc=0
+    rm -f "$tmpname"
+    if [ -e "$destname" ]; then
+       refdate=`perl -e "print scalar gmtime(((stat ('$destname'))[9]))"`
+        curl $CURLOPT -z "$refdate" "$url" -o "$tmpname"
+        rc=$?
+    else
+       curl $CURLOPT "$url" -o "$tmpname"
+       rc=$?
+    fi
+    if [ $rc -eq 0 -a -e "$tmpname" ]; then
+       if gzip -t "$tmpname"; then
+           mv "$tmpname" "$destname"
+       else
+           rc=$?
+       fi
+    fi
+    gzip -dc "$destname" >> "$appendname"
+    return $rc
+}
+
+DAY=`date +%w`
+
+if lockfile -! -l 3600 $LOCKFILE; then
+    echo "Cannot lock $LOCKFILE"
+    exit 1
+fi
+
+cleanup() {
+    rm -f "$LOCKFILE"
+}
+trap cleanup 0
+
+echo Updating wanna-build databases...
+umask 027
+
+if [ "$DAY" = "0" ]; then
+       savelog -c 26 -p /srv/wanna-build/db/merge.log
+fi
+
+exec 3<&1 >> /srv/wanna-build/db/merge.log 2>&1
+
+echo -------------------------------------------------------------------------
+echo "merge triggered: `date`"
+echo "merge triggered          : `date -u`" >&3
+
+cd $TMPDIR
+
+#
+# Make one big Packages and Sources file.
+#
+for d in $DISTS; do
+    dist=`echo $d | sed s/-.*$//`
+    case "$dist" in
+       oldstable)
+           ARCHS="$ARCHS_oldstable"
+           ;;
+       stable)
+           ARCHS="$ARCHS_stable"
+           ;;
+       testing)
+           ARCHS="$ARCHS_testing"
+           ;;
+       *)
+           ARCHS="$ARCHS_unstable"
+           ;;
+    esac
+    rm -f Sources.$d Sources.$d-p-u
+
+    for a in $ARCHS; do
+       rm -f Packages.$d.$a Packages.$d-p-u.$a quinn-$d-p-u.$a
+    done
+
+    for s in $SECTIONS; do
+       if echo $d | grep -qv -- -security; then
+           curl_index "$MASTER/$dist/$s/source/Sources.gz" "Sources-$d.$s.gz" "Sources.$d"
+           if [ "$d" != "unstable" ]; then
+               curl_index "$MASTER/$dist-proposed-updates/$s/source/Sources.gz" "Sources-$d-proposed-updates.$s.gz" "Sources.$d-p-u"
+           fi
+
+           for a in $ARCHS; do
+               curl_index "$MASTER/$dist/$s/binary-$a/Packages.gz" "Packages-$d.$s.$a.gz" "Packages.$d.$a"
+               if [ "$d" != "unstable" ]; then
+                   curl_index "$MASTER/$dist-proposed-updates/$s/binary-$a/Packages.gz" "Packages-$d-proposed-updates.$s.$a.gz" "Packages.$d-p-u.$a"
+                   if [ "$d" != "oldstable" -o "$s" = "main" ]; then
+                       curl_index "$MASTER/$dist-proposed-updates/$s/debian-installer/binary-$a/Packages.gz" "Packages-$d-proposed-updates-debian-installer.$s.$a.gz" "Packages.$d-p-u.$a"
+                   fi
+               fi
+               if [ "$d" != "oldstable" -o "$s" = "main" ]; then
+                   curl_index "$MASTER/$d/$s/debian-installer/binary-$a/Packages.gz" "Packages-$d-debian-installer.$s.$a.gz" "Packages.$d.$a"
+               fi
+           done
+       else
+           curl_index "$SECMASTER/$dist/updates/$s/source/Sources.gz" "Sources-$d.$s.gz" "Sources.$d"
+           if [ "$s" = "main" ]; then
+               curl_index "$SECMASTERBUILDD/$dist/Sources.gz" "Sources-$d.accepted.gz" "Sources.$d"
+               curl_index "$SECMASTERBUILDD/$dist/Packages.gz" "Packages-$d.accepted.gz" "/dev/null"
+           fi
+           for a in $ARCHS ; do
+               curl_index "$SECMASTER/$dist/updates/$s/binary-$a/Packages.gz" "Packages-$d.$s.$a.gz" "Packages.$d.$a"
+               if [ "$s" = "main" ]; then
+                   gzip -dc "Packages-$d.accepted.gz" >> "Packages.$d.$a"
+               fi
+           done
+       fi
+    done
+
+#
+# It's important that the accepted file is rebuilt before the daily run,
+# and that you have that should-be-empty version, to avoid unaccepts and
+# double builds.
+#
+    if [ "$d" = "unstable" ]; then
+       rm -f "Sources.$d.base"
+       cp "Sources.$d" "Sources.$d.base"
+       curl_index "$MASTERBUILDD/Sources.gz" "Sources-$d.accepted.gz" "Sources.$d"
+       curl_index "$MASTERBUILDD/Packages.gz" "Packages-$d.accepted.gz" "/dev/null"
+
+       for a in $ARCHS; do
+           rm -f "Packages.$d.$a.base"
+           cp "Packages.$d.$a" "Packages.$d.$a.base"
+           gzip -dc "Packages-$d.accepted.gz" >> "Packages.$d.$a"
+       done
+    else
+       if [ -e "Sources.$d-p-u" ]; then
+           cat "Sources.$d" >> "Sources.$d-p-u"
+       fi
+    fi
+
+    for a in $ARCHS; do
+       quinn-diff -A $a -a /srv/buildd.debian.org/web/quinn-diff/Packages-arch-specific -s Sources.$d -p Packages.$d.$a >> quinn-$d.$a 2>/dev/null
+       if echo $d | grep -qv -- -security; then
+           if [ "$d" != "unstable" ]; then
+               cat "Packages.$d.$a" >> "Packages.$d-p-u.$a"
+               quinn-diff -A $a -a /srv/buildd.debian.org/web/quinn-diff/Packages-arch-specific -s Sources.$d-p-u -p Packages.$d-p-u.$a >> quinn-$d-p-u.$a 2>/dev/null
+               sed -e 's/\[[-a-z]*:[-a-z]*\]$//' quinn-$d.$a > quinn-$d.$a.grep
+               if [ ! -z quinn-$d.$a.grep ]; then
+                   fgrep -vf quinn-$d.$a.grep quinn-$d-p-u.$a > quinn-$d.$a
+               else
+                   cp quinn-$d-p-u.$a quinn-$d.$a
+               fi
+               rm quinn-$d.$a.grep
+               mv "Packages.$d-p-u.$a" "Packages.$d.$a"
+           fi
+       fi
+    done
+    if [ -e "Sources.$d-p-u" ]; then
+       mv "Sources.$d-p-u" "Sources.$d"
+    fi
+done
+echo "fetch and quinn completed: `date -u`"
+echo "fetch and quinn completed: `date -u`" >&3
+
+umask 002
+for a in $ARCHS_unstable ; do
+       wanna-build --create-maintenance-lock --database=$a/build-db
+
+       for d in $DISTS ; do
+               dist=`echo $d | sed s/-.*$//`
+               case "$dist" in
+                       oldstable)
+                               if echo $ARCHS_oldstable | grep -q -v "\b$a\b"; then
+                                       continue
+                               fi
+                               ;;
+                       stable)
+                               if echo $ARCHS_stable | grep -q -v "\b$a\b"; then
+                                       continue
+                               fi
+                               ;;
+                       testing)
+                               if echo $ARCHS_testing | grep -q -v "\b$a\b"; then
+                                       continue
+                               fi
+                               ;;
+                       *)
+                               if echo $ARCHS_unstable | grep -q -v "\b$a\b"; then
+                                       continue
+                               fi
+                               ;;
+               esac
+               # non-free is excluded for legal reasons.  buildd needs to
+               # confirm on a per-package and per-buildd basis whether or not
+               # it is buildable
+               perl -pi -e 's#^(non-free)/.*$##msg' quinn-$d.$a
+               if [ "$a" = "$NEWARCH" ]; then
+               wanna-build -v --merge-all --arch=$a --dist=$d --database=$a/build-db Packages.$d.$a quinn-$d.$a Sources.unstable.$NEWARCH
+               else
+               wanna-build -v --merge-all --arch=$a --dist=$d --database=$a/build-db Packages.$d.$a quinn-$d.$a Sources.$d
+               fi
+               mv Packages.$d.$a Packages.$d.$a-old
+               mv quinn-$d.$a quinn-$d.$a-old
+       done
+       if [ "$DAY" = "0" ]; then
+               savelog -p -c 26 /srv/wanna-build/db/$a/transactions.log
+       fi
+       wanna-build --remove-maintenance-lock --database=$a/build-db
+done
+umask 022
+for d in $DISTS; do
+    mv Sources.$d Sources.$d-old
+done
+
+echo "merge ended: `date`"
+#
+# Only update stats if it's been at least 20h since the last time.
+#
+interval=72000
+last=`stat --format="%Y" /srv/wanna-build/etc/graph-data`
+now=`date +%s`
+if (( $last + $interval < $now )); then
+        echo "stats start: `date`"
+       /srv/wanna-build/bin/wb-graph >> /srv/wanna-build/etc/graph-data
+       /srv/wanna-build/bin/wb-graph -p >> /srv/wanna-build/etc/graph2-data
+       rm -f "$LOCKFILE"
+       trap - 0
+       /srv/buildd.debian.org/bin/makegraph
+       for a in $ARCHS_stable; do
+           echo Last Updated: `date -u` > /srv/buildd.debian.org/web/stats/$a.txt
+           for d in $STATS_DISTS; do
+               /srv/wanna-build/bin/wanna-build-statistics --database=$a/build-db --dist=$d >> /srv/buildd.debian.org/web/stats/$a.txt
+           done
+       done
+       echo Last Updated: `date -u` > /srv/buildd.debian.org/web/stats/amd64.txt
+       /srv/wanna-build/bin/wanna-build-statistics --database=amd64/build-db --dist=unstable >> /srv/buildd.debian.org/web/stats/amd64.txt
+        echo "stats ended: `date`"
+fi
diff --git a/trigger.often b/trigger.often
new file mode 100755 (executable)
index 0000000..0821c80
--- /dev/null
@@ -0,0 +1,89 @@
+#!/bin/bash
+#
+# Updates wanna-build databases after the archive maintenance
+# finishes
+#
+# Files:
+#     Sources-* == upstream fetched file
+#     Sources.* == uncompressed, concat'd version
+#
+# RM: disabled for etch release
+
+LANG=C
+PATH="/bin:/usr/bin"
+ARCHS="m68k arm armel sparc alpha powerpc i386 mips mipsel ia64 hppa s390 amd64"
+TMPDIR="/org/wanna-build/tmp"
+WGETOPT="-q -t2 -w0 -T10"
+LOCKFILE="/org/wanna-build/tmp/DB_Maintenance_In_Progress"
+NEWARCH=""
+
+if lockfile -! -l 3600 $LOCKFILE; then
+       echo "Cannot lock $LOCKFILE"
+       exit 1
+fi
+
+cleanup() {
+       rm -f "$LOCKFILE"
+}
+trap cleanup 0
+
+umask 027
+
+exec >> /org/wanna-build/db/merge.log 2>&1
+
+echo --
+echo "incoming merge triggered: `date`"
+
+cd $TMPDIR
+
+rm -rf srcdep
+umask 022
+cvs -d :pserver:anonymous@cvs.debian.org:/cvs/dak checkout srcdep/Packages-arch-specific >/dev/null
+if [ -f srcdep/Packages-arch-specific ]; then
+       cp -p srcdep/Packages-arch-specific /org/buildd.debian.org/web/quinn-diff/
+fi
+rm -rf srcdep
+umask 027
+
+#
+# Make one big Packages and Sources file from accepted autobuilding.
+#
+rm -f Sources.unstable Sources.gz Packages.gz
+if wget $WGETOPT http://incoming.debian.org/buildd/Sources.gz; then
+       mv Sources.gz Sources-unstable.accepted.gz
+fi
+if wget $WGETOPT http://incoming.debian.org/buildd/Packages.gz; then
+       mv Packages.gz Packages-unstable.accepted.gz
+fi
+cp Sources.unstable.base Sources.unstable
+zcat Sources-unstable.accepted.gz >> Sources.unstable
+for a in $ARCHS; do
+       rm -f Packages.unstable.$a
+       cp Packages.unstable.$a.base Packages.unstable.$a
+       zcat Packages-unstable.accepted.gz >> Packages.unstable.$a
+done
+       
+umask 007
+for a in $ARCHS ; do
+       if [ "$a" = "i386" ]; then
+               quinn-diff -i -D 177 -A $a -a /org/buildd.debian.org/web/quinn-diff/Packages-arch-specific -s Sources.unstable -p Packages.unstable.$a >> quinn-unstable.$a 2> /dev/null
+       else
+               if [ "$a" = "$NEWARCH" ]; then
+                       quinn-diff -i -A $a -a /org/buildd.debian.org/web/quinn-diff/Packages-arch-specific -s Sources.unstable.$NEWARCH -p Packages.unstable.$a >> quinn-unstable.$a 2> /dev/null
+               else
+                       quinn-diff -i -A $a -a /org/buildd.debian.org/web/quinn-diff/Packages-arch-specific -s Sources.unstable -p Packages.unstable.$a >> quinn-unstable.$a 2> /dev/null
+               fi
+       fi
+       perl -pi -e 's#^(non-free)/.*$##msg' quinn-unstable.$a
+       if [ "$a" = "$NEWARCH" ]; then
+               wanna-build -v --merge-all --arch=$a --dist=unstable --database=$a/build-db Packages.unstable.$a quinn-unstable.$a Sources.unstable.$NEWARCH
+       else
+               wanna-build -v --merge-all --arch=$a --dist=unstable --database=$a/build-db Packages.unstable.$a quinn-unstable.$a Sources.unstable
+       fi
+       mv Packages.unstable.$a Packages.unstable.$a-old
+       mv quinn-unstable.$a quinn-unstable.$a-old
+done
+mv Sources.unstable Sources.unstable-old
+
+echo "incoming merge ended: `date`"
+exit 0