]> git.decadent.org.uk Git - dak.git/commitdiff
Merge commit 'ftpmaster/master' into psycopg2
authorMark Hymers <mhy@debian.org>
Sat, 24 Jan 2009 19:35:26 +0000 (19:35 +0000)
committerMark Hymers <mhy@debian.org>
Sat, 24 Jan 2009 19:35:26 +0000 (19:35 +0000)
44 files changed:
ChangeLog [deleted file]
ChangeLog.old [new file with mode: 0644]
README.coding [new file with mode: 0644]
config/debian/dak.conf
config/debian/extensions.py
dak/check_archive.py
dak/cruft_report.py
dak/dak.py
dak/dakdb/__init__.py [new file with mode: 0644]
dak/dakdb/update1.py [new file with mode: 0644]
dak/dakdb/update2.py [new file with mode: 0755]
dak/dakdb/update3.py [new file with mode: 0755]
dak/examine_package.py
dak/generate_index_diffs.py
dak/generate_releases.py
dak/import_archive.py
dak/import_keyring.py
dak/import_ldap_fingerprints.py
dak/make_maintainers.py
dak/make_overrides.py
dak/make_suite_file_list.py
dak/mirror_split.py [deleted file]
dak/new_security_install.py
dak/override.py
dak/process_accepted.py
dak/process_new.py
dak/process_unchecked.py
dak/queue_report.py
dak/reject_proposed_updates.py
dak/rm.py
dak/show_new.py
dak/update_db.py [new file with mode: 0755]
daklib/dak_exceptions.py
daklib/database.py
daklib/queue.py
daklib/utils.py
scripts/debian/byhand-dm
scripts/debian/dm-monitor
scripts/debian/moveftp.sh [new file with mode: 0755]
src/Makefile [deleted file]
src/sql-aptvc.cpp [deleted file]
templates/rm.bug-close
tools/removals.pl
web/dinstall.html

diff --git a/ChangeLog b/ChangeLog
deleted file mode 100644 (file)
index 946cf32..0000000
--- a/ChangeLog
+++ /dev/null
@@ -1,5860 +0,0 @@
-2008-12-30  Joerg Jaspert  <joerg@debian.org>
-
-       * config/debian/cron.hourly: Generate the 822 format for accepted,
-       new, byhand and proposed-updates
-
-2008-12-30  Michael Casadevall <sonicmctails@gmail.com>
-
-       * dak/queue_report.py   - Added directories option to queue report
-
-2008-12-28  Frank Lichtenheld  <djpig@debian.org>
-
-       * dak/override.py (main): Handle source-only packages better
-
-2008-12-26  Michael Casadevall <sonicmctails@gmail.com>
-
-       * dak/queue_report.py - Added Last Modified in asctime() for QA team
-
-2008-12-23  Michael Casadevall <sonicmctails@gmail.com>
-
-        * dak/queue_report.py - Added 822 output format
-
-        * dak/queue_report.py - Fixed display of BYHAND packages
-
-        * dak/queue_report.py - Added queue field
-
-        * config/debian/dak.conf - Added 822 output location
-
-        * dak/process_accepted.py - Added orig.tar.gz copying when going
-          inbetween two components
-
-2008-12-23  Joerg Jaspert  <joerg@debian.org>
-
-       * dak/make_suite_file_list.py (stable_dislocation_p): Removed
-
-       * config/debian/dak.conf, config/debian-security/dak.conf: Remove "StableDislocationSupport "false";"
-
-2008-12-19  Joerg Jaspert  <joerg@debian.org>
-
-       * daklib/utils.py: move the html escape stuff here.
-
-       * dak/examine_package.py: Remove the html escape stuff.
-
-       * dak/queue_report.py: lotsa html changes to get more info on the
-       page and to get Tinchos css foo working.
-
-       * web/style.css: Added new stuff from Tincho
-
-2008-12-18  Philipp Kern  <pkern@debian.org>
-
-       * config/debian-security/cron.buildd: simplify wanna-build update
-       by calling a trigger script on the wanna-build host
-       * config/debian-security/cron.daily: no need to refresh
-       packages-arch-specific anymore
-
-2008-12-16  Joerg Jaspert  <joerg@debian.org>
-
-       * config/debian/cron.dinstall: Run logs.py as last command before
-       we mail the log.
-
-       * tools/logs.py: Added script from Thomas.
-       Modifications from me:
-        - Use path entries that fit ftpmaster dak user
-        - Make the bz2 extension optional for log files, so we can run it
-       out of cron.dinstall, where it is not yet compressed.
-        - Also show the two largest time killers in the totals graph.
-        - do not drop old entries from the cachefile
-        - fiddle with the color palette
-
-2008-12-15  Joerg Jaspert  <joerg@debian.org>
-
-       * config/debian/cron.hourly: Call the removals.pl
-
-2008-12-09  Joerg Jaspert  <joerg@debian.org>
-
-       * config/debian/cron.hourly: Added queue_rss.py to hourly cron.
-
-2008-12-09  Filippo Giunchedi <filippo@debian.org>
-
-       * tools/queue_rss.py: Added, generates RSS feeds of NEW.
-
-2008-12-09  Philipp Kern  <pkern@debian.org>
-
-       * daklib/queue.py (cross_suite_version_check): add an additional
-       parameter to specify if an upload is sourceful or not; do not reject
-       uploads that do not satisfy the "must be newer than" criteria and
-       are binary-only
-       * daklib/queue.py (check_source_against_db, check_binary_against_db):
-       invoke cross_suite_version_check as above
-
-2008-12-04  Philipp Kern  <pkern@debian.org>
-
-       * dak/process_new.py (recheck): call reject for
-       Upload.check_{binary,source}_against_db with an empty prefix to not
-       reject on warnings
-
-2008-11-30  Philipp Kern  <pkern@debian.org>
-
-       * dak/process_unchecked.py (do_stableupdate, do_oldstableupdate):
-       move files to NEW for {old,}stable-proposed-updates world-readable
-       (Closes: #368056)
-
-2008-11-30  Joerg Jaspert  <joerg@debian.org>
-
-       * config/debian/apt.conf: Lets generate experimental content
-       files.
-
-       * dak/daklib/queue.py (Upload.cross_suite_version_check): Add a
-       few () to make cross_suite_version_check finally work as
-       intended (well, we hope). Thanks to Philipp Kern for spotting this.
-
-2008-11-28  Mark Hymers  <mhy@debian.org>
-
-       * dak/new_security_install.py: Don't attempt to delete the .changes files
-       which have already been moved to queue/done by now.
-
-2008-11-27  Mark Hymers  <mhy@debian.org>
-
-       * dak/new_security_install.py: Attempt to tidy up the buildd queue.  The
-       buildd team believes that the fact that the packages are in the security
-       pool after this point should be good enough.
-
-2008-11-25  Joerg Jaspert  <joerg@debian.org>
-
-       * dak/process_unchecked.py (queue_(un)embargo): (Hopefully) enable
-       sending mails again, which got broken when testing-security
-       handling was (not completly correctly) implemented. Closes: #440004
-
-2008-11-24  Joerg Jaspert  <joerg@debian.org>
-
-       * dak/process_unchecked.py (check_signed_by_key): remove the
-       binary-upload restriction stuff. unused.
-
-       * config/debian-security/apt.conf.buildd: byebye sarge
-
-       * scripts/nfu/get-w-b-db: remove m68k
-
-       * scripts/debian/update-ftpstats: remove m68k
-
-       * config/debian/dak.conf: remove m68k
-       remove the binary-upload-restrictions
-
-       * config/debian/vars (archs): Remove m68k
-
-2008-11-23  Joerg Jaspert  <joerg@debian.org>
-
-       * dak/process_unchecked.py (check_files): fix this armel mess
-
-       * config/debian-security/dak.conf: Set ValidTime
-
-       * config/debian-security/cron.weekly: Added
-
-2008-11-17  Joerg Jaspert  <joerg@debian.org>
-
-       * dak/security-install.py: Removed, no longer in use.
-
-2008-11-16  Joerg Jaspert  <joerg@debian.org>
-
-       * scripts/debian/mkfilesindices: useless typical, doesnt have
-       i18n/ dirs. Force them in (i hope).
-
-2008-11-15  Thomas Viehmann <tv@beamnet.de>
-
-       * dak/show_deferred.py: handle uploads that do not close bugs
-
-2008-11-11  Joerg Jaspert  <joerg@debian.org>
-
-       * config/debian/dak.conf: good bye oldstable/o-p-u
-
-2008-11-10  Joerg Jaspert  <joerg@debian.org>
-
-       * config/debian/cron.unchecked: how about us ignoring bugs.d.o
-       down? It's not like it is time critical or something to transfer
-       this stuff, it doesn't hurt to have it there a bit later...
-
-2008-11-08  Joerg Jaspert  <joerg@debian.org>
-
-       * config/debian/cron.hourly: Create new tracefile format.
-
-2008-11-05  Joerg Jaspert  <joerg@debian.org>
-
-       * dak/new_security_install.py (_do_Approve): This sudo call
-       definitely wants the -H option.
-
-2008-11-01  Joerg Jaspert  <joerg@debian.org>
-
-       * dak/process_unchecked.py (check_files): Also check the
-       upload_suite for uploads. I guess we could kill the default_suite
-       totally, but for now we just look into the upload_suite one too.
-
-       * config/debian-security/dak.conf: Let DefaultSuite be stable
-
-2008-10-27  Joerg Jaspert  <joerg@debian.org>
-
-       * scripts/debian/mkfilesindices: Remove oldstable
-
-       * config/debian/vars: Remove sarge
-
-       * config/debian/dak.conf: Untouchable o-p-u, until we removed all
-       of sarge and its files.
-
-       * config/debian/apt.conf.oldstable: Removed
-
-       * config/debian/apt.conf: Remove oldstable
-
-2008-10-14  Thomas Viehmann <tv@beamnet.de>
-
-       * dak/show_deferred.py: produce .changes and improve status
-
-2008-10-07  Joerg Jaspert  <joerg@debian.org>
-
-       * config/debian/cron.dinstall: Only keep the last 60 days of
-       dinstall logfiles on disc.
-
-2008-10-05  Thomas Viehmann <tv@beamnet.de>
-
-        * daklib/database.py: added get_suites
-       * dak/dak.py, dak/show_deferred.py: add show-deferred to dak.
-
-2008-09-23  Joerg Jaspert  <joerg@debian.org>
-
-       * config/debian/dak.conf: Add the validtime fields, set to 7
-       days.
-
-       * dak/generate_releases.py (main): Add a "Valid-Until" line into
-       our release files, meaning "$receiver shouldn't trust this files
-       after that date". Should be used by apt and similar tools to
-       detect some kind of MITM attacks, see #499897
-
-2008-09-21  Joerg Jaspert  <joerg@debian.org>
-
-       * config/debian/cron.hourly: Generate the DEFERRED queue
-       overview.
-
-2008-09-13  Philipp Kern  <pkern@debian.org>
-
-       * dak/queue.py (dump_vars): make .dak u,g=rw,o=r; James'
-       assumption (as stated in 2002-05-18's ChangeLog entry)
-       was that people will use the information therein albeit
-       it is "just" a duplication of information present in
-       other control files; people should still not use it
-       as source of information but access to those files makes
-       dak debugging easier and there is no leak of sensitive
-       information involved
-
-2008-09-12  Philipp Kern  <pkern@debian.org>
-
-       * dak/new_security_install.py (actually_upload): remove
-       oldstable-security/amd64 check; Etch, as the next oldstable,
-       already had proper amd64 support
-
-2008-09-12  Joerg Jaspert  <joerg@debian.org>
-
-       * scripts/debian/update-pseudopackages.sh: s/i/file/
-
-2008-09-11  Joerg Jaspert  <joerg@debian.org>
-
-       * config/debian/pseudo-packages.description, ...maintainers:
-       Removed, now with the bts people
-
-       * scripts/debian/update-pseudopackages.sh: Added, fetching
-       pseudo-packages from new bts location
-
-       * scripts/debian/mkmaintainers: Use new location
-
-2008-09-08  Philipp Kern  <pkern@debian.org>
-
-       * dak/check_archive.py (check_checksums): rewind the files
-       before the sha1sum/sha256sum checks as they got seeked by
-       md5sum
-
-       * daklib/utils.py (build_file_list): do not die on very
-       old dsc files without format header
-
-2008-09-07  Philipp Kern  <pkern@debian.org>
-
-       * daklib/utils.py (check_hash): try..except..finally only
-       works on python >=2.5.
-
-       * dak/process_accepted.py (install): better use dsc_file
-       instead of the (for the loop iteration) static file
-       variable
-
-2008-09-07  Philipp Kern  <pkern@debian.org>
-
-       * daklib/utils.py (check_hash): change the comment and warn
-       if a file is not found when checking the hashes (i.e. when
-       it is probably in the pool)
-
-       * daklib/utils.py (check_size): do not bail out if the file
-       is not found, because it may be in the pool
-
-       * dak/process_accepted.py (install): bail out and skip the
-       upload when ensure_hashes fails, print the rejection messages
-       as warnings
-
-2008-08-28  Philipp Kern  <pkern@debian.org>
-
-       * daklib/utils.py (check_hashes): adapt to different API, check
-       sizes separately
-
-       * daklib/utils.py (parse_changes, parse_deb822): refactor
-       the string-based logic of parse_changes into a new function
-       parse_deb822; parse_changes itself remains file-based
-
-       * daklib/utils.py (hash_key): gives the key of a hash in the
-       files dict
-
-       * daklib/utils.py (create_hash, check_size): made more readable
-
-       * daklib/utils.py (check_hash): just check the hashes and complain
-       about missing checksums
-
-       * daklib/utils.py (check_hash_fields): function to reject unknown
-       checksums fields
-
-       * daklib/utils.py (_ensure_changes_hash, _ensure_dsc_hash): helper
-       functions for ensure_hashes; check their corresponding manifests'
-       hashes
-
-       * daklib/utils.py (ensure_hashes): retrieve the checksums fields
-       from the original filecontents blob so that they do not need to
-       be present in the .dak; refactored the actual checks by calling
-       the aforementioned helper functions
-
-       * daklib/utils.py (parse_checksums): parse a given checksums field
-       in a manifest and insert the values found into the files dict,
-       checking the file sizes on the way
-
-2008-09-06  Philipp Kern  <pkern@debian.org>
-
-       * dak/process_new.py (is_source_in_queue_dir): Access the right
-       variable to check if the given entry in the queue is the sourceful
-       upload we are looking for.
-
-2008-09-02  Joerg Jaspert  <joerg@debian.org>
-
-       * config/debian/pseudo-packages.description: Added debian-i18n and
-       buildd.emdebian.org
-
-       * dak/process_new.py (_accept): Fix Philipps new helper function
-       to not break by moving Upload.build_summaries there.
-
-2008-08-31  Philipp Kern  <pkern@debian.org>
-
-       * dak/process_new.py (_accept): new helper function to accept
-       an upload regularly, obeying no-action if set
-       * dak/process_new.py (do_accept): use _accept
-       * dak/process_new.py (do_accept_stableupdate): bail out in else
-       on binary uploads, in case we missed something; use the _accept
-       helper
-
-2008-08-30  Philipp Kern  <pkern@debian.org>
-
-       * dak/process_new.py (is_source_in_queue_dir): join the queue path
-       because os.listdir entries come with their path stripped
-
-2008-08-30  Philipp Kern  <pkern@debian.org>
-
-       * dak/process_new.py (do_accept_stableupdate): state what we intend
-       to do
-
-2008-08-26  Philipp Kern  <pkern@debian.org>
-
-       * dak/process_new.py (is_source_in_queue_dir): fix variable usage
-       * dak/process_new.py (move_to_holding): just state what we intend
-       to do in no-action mode
-       * dak/process_new.py (do_accept_stableupdate): fetch summaries,
-       fix invokation of is_source_in_queue_dir, actually accept sourceful
-       uploads in p-u holding
-
-2008-08-26  Philipp Kern  <pkern@debian.org>
-
-       * dak/process_new.py (do_accept): do not try to free the unchecked
-       lockfile in no-action mode
-
-2008-08-16  Joerg Jaspert  <joerg@debian.org>
-
-       * config/debian/cron.dinstall: We dont want i18n to ever fail
-       dinstall, add a || true
-
-2008-08-15  Mark Hymers  <mhy@debian.org>
-
-       * daklib/utils.py: Actually import a module before using it.
-
-       * daklib/utils.py: Actually check we have basedict before trying to
-       use it.
-
-       *  dak/process_accepted.py, dak/process_unchecked.py,
-       daklib/database.py: Don't change get_files_id to use sha1sum and
-       sha256sum.
-
-       * setup/init_pool.sql, dak/check_archive.py, dak/decode_dot_dak.py,
-       dak/process_accepted.py, dak/process_unchecked.py, daklib/database.py,
-       daklib/queue.py, daklib/utils.py: Attempt to add sha1sum and
-       sha256sums into the database.  The complication is that we have to
-       keep backwards compatibility with the .dak files already in existance.
-       Note that import_archive hasn't been hacked to deal with this yet.
-
-2008-08-14  Joerg Jaspert  <joerg@debian.org>
-
-       * config/debian/cron.dinstall: Added the i18n retrieval of package
-       description translations
-
-2008-08-12  Joerg Jaspert  <joerg@debian.org>
-
-       * config/debian/cron.dinstall: Complicate the i18n export a little
-       by using date/hour based directories which we then link into the
-       web view. They contain a signed timestamp file now, which means
-       the i18n people can take a long time to generate files, yet we
-       still know exactly on which dataset their data is based on, and
-       can then verify it with that. Ensures we only get descriptions for
-       packages we know off (or knew of in the past 2 days).
-
-2008-08-11  Joerg Jaspert  <joerg@debian.org>
-
-       * web/dinstall.html: Added
-
-       * config/debian/dak.conf: Added back the pgp keyrings for now, as
-       it seems that we should keep it for a few more days, until we
-       somehow got ll those oldtimers to get a newer key into the
-       keyring. Unfortunately our logic to look for uploads done from
-       that keyring wasnt the most perfect one, so well, it is actually
-       used. Damn.
-
-2008-08-09  Joerg Jaspert  <joerg@debian.org>
-
-       * config/debian/dak.conf: No longer use the pgp keyring - no
-       uploads recorded for any of the pgp keys for a long time.
-
-       * config/debian/cron.dinstall: Export the i18n foo.
-
-2008-08-08  Joerg Jaspert  <joerg@debian.org>
-
-       * config/debian/cron.dinstall: Create a hardlinked tree of the
-       ftp/ in mirror/ so we have more atomic mirror updates for the
-       buildds
-
-       * config/debian/cron.unchecked: Added signing of buildd incoming
-
-2008-08-07  Philipp Kern  <pkern@debian.org>
-
-       * dak/process_new.py (do_accept): handle uploads to (oldstable-)
-         proposed-updates differently and put them into p-u holding
-         for review instead of unconditionally accepting them into
-         p-u proper; additional care needed to be taken to look
-         out for the source if a binary-only upload is being handled
-
-2008-08-07  Joerg Jaspert  <joerg@debian.org>
-
-       * dak/cruft_report.py (parse_nfu): call utils.warn instead of warn
-       (main): Only do the nfu stuff if nfu is a check we want to run
-       later.
-       (main): And another place where we dont want to do nfu foo unless
-       we need nfu
-
-       * dak/make_suite_file_list.py (main): Fix a bug that has been
-       there for ages, but "just" never triggered.
-
-2008-08-07  Stephen Gran  <sgran@debian.org>
-
-       * Drop use of exec to eval variable interpolation
-2008-08-07  Joerg Jaspert  <joerg@debian.org>
-
-       * dak/process_accepted.py (install): Error out with the new
-       exception if we dont know the source package for a file we want to
-       install. Shouldn't ever hit us, but better safe than sorry.
-
-       * daklib/dak_exceptions.py (dakerrors): new exception - no source field.
-
-2008-08-05  Joerg Jaspert  <joerg@debian.org>
-
-       * config/debian/cron.unchecked: disable the ssh-move insanity (and
-       as soon as rietz is back online - replace it with a one-line scp
-       or rsync statement followed by a one-line rm)
-       And now replaced this 128 line perl "not-invented-here" with a
-       one-line rsync command, using a feature rsync only understands
-       since sarge - damn new-fangled technology.
-
-2008-08-05  Joachim Breitner <nomeata@debian.org>
-
-       * dak/cruft_report.py: In full mode, report out-of-date binaries on
-       architectures that have set Not-For-Us for that package.
-
-       * scripts/nfu/get-w-b-db: Script to fetch the wanna-build database
-       dump from http://buildd.debian.org/
-
-       * config/debian/cron.weekly: Run the above script
-
-2008-08-03  Mark Hymers <mhy@debian.org>
-
-       * dak/process_new.py: Apply jvw's patch so that process_new shows
-       packages which need binary uploads sorted earlier than other packages.
-
-2008-07-26  Joerg Jaspert  <joerg@debian.org>
-
-       * templates/reject-proposed-updates.rejected,dak/reject_proposed_updates.py:
-       applied a patch by luk modifying the stable rejection mails to fit
-       reality a bit more
-
-       * config/debian/dak.conf: no m68k in testing, so no m68k in t-p-u
-       r4 now
-
-2008-06-19  Thomas Viehmann  <tv@beamnet.de>
-
-       * dak/process_unchecked.py (check_dsc,check_hashes): Catch
-       UnknownFormatError and reject
-
-2008-06-15  Joerg Jaspert  <joerg@debian.org>
-
-       * config/debian/cron.weekly: Work around a git bug until git is
-       fixed upstream and the fix is on backports.org
-
-       * config/debian/cron.dinstall: (various ssh calls): Make them use
-       batchmode/connect/setuptimeout to not take too long with
-       connections... Also || true them, no need to die in dinstall if
-       one host isn't reachable.
-       Also do not die when the ldap server is unreachable, just ignore
-       that error.
-
-       * README: Updated mailing list location
-
-2008-06-14  Otavio Salvador  <otavio@debian.org>
-
-       * docs/manpages/clean-suites.1.sgml: Minor typo fix
-
-       * dak/import_archive.py: Add support to udeb packages
-
-       * dak/control_suite.py (main): Handle SystemError exception in
-       case of a incompatible commandline parameter
-
-       * dak/check_overrides.py (main): Use case-insensitive comparing
-       for codename
-
-2008-06-14  Joerg Jaspert  <joerg@debian.org>
-
-       * scripts/debian/byhand-task: Merged patch from Frans Pop to
-       fail on byhand-task uploads if they do not go to unstable.
-
-       * config/debian/cron.weekly: Do a little git cleanup work too.
-
-       * config/debian/cron.buildd: Add batchmode and also
-       Connect/SetupTimeout parameters to ssh
-
-       * config/debian/cron.dinstall (POSTDUMP): Compress all
-       uncompressed psql backups
-
-2008-06-08  Joerg Jaspert  <joerg@debian.org>
-
-       * dak/process_unchecked.py (check_urgency): Lowercase urgency
-       before we (eventually) warn on it. Patch taken from Russ Allbery.
-
-2008-06-01  Otavio Salvador  <otavio@debian.org>
-
-       * daklib/queue.py (check_valid): allow debian-installer specific
-       sources to have 'debian-installer' section.
-
-2008-05-28  Frans Pop  <fjp@debian.org>
-
-       * add autobyhand support for task overrides (from tasksel)
-
-2008-05-27  Joerg Jaspert  <joerg@debian.org>
-
-       * config/debian/pseudo-packages.maintainers: Change ftp.debian.org
-       pseudopackage maintainer name.
-
-2008-05-12  Joerg Jaspert  <joerg@debian.org>
-
-       * dak/transitions.py: use yaml.dump instead of syck.dump, as syck
-       seems to have a bug in its dump(), causing it to write illegal entries
-       And also do this for load.
-
-2008-05-10  Stephen Gran   <sgran@debian.org>
-       * tools/debianqueued-0.9/debianqueued: First pass at a send_mail
-         implementation that sucks less
-       * Update debian/control to reflect new perl dependency
-
-2008-05-09  Joerg Jaspert  <joerg@debian.org>
-
-       * dak/override.py (main): substitute value in X-Debian-Package
-       header
-
-       * templates/override.bug-close: Add X-Debian-Package header
-       * templates/reject-proposed-updates.rejected: dito
-       * templates/queue.rejected: dito
-       * templates/process-unchecked.new: dito
-       * templates/process-unchecked.bug-nmu-fixed: dito
-       * templates/process-unchecked.bug-experimental-fixed: dito
-       * templates/process-unchecked.bug-close: dito
-       * templates/process-unchecked.announce: dito
-       * templates/process-unchecked.accepted: dito
-       * templates/process-new.prod: dito
-       * templates/process-accepted.unaccept: dito
-       * templates/process-accepted.install: dito
-       * templates/process-unchecked.override-disparity: dito
-
-2008-05-08  Joerg Jaspert  <joerg@debian.org>
-
-       * templates/override.bug-close: Add X-Debian header
-       * templates/rm.bug-close: dito
-       * templates/reject-proposed-updates.rejected: dito
-       * templates/queue.rejected: dito
-       * templates/process-unchecked.new: dito
-       * templates/process-unchecked.bug-nmu-fixed: dito
-       * templates/process-unchecked.bug-experimental-fixed: dito
-       * templates/process-unchecked.bug-close: dito
-       * templates/process-unchecked.announce: dito
-       * templates/process-unchecked.accepted: dito
-       * templates/process-new.prod: dito
-       * templates/process-accepted.unaccept: dito
-       * templates/process-accepted.install: dito
-       * templates/process-unchecked.override-disparity: dito, but also
-       mention that people should include the package lists with the
-       override disparities.
-
-2008-05-06  Joerg Jaspert  <joerg@debian.org>
-
-       * config/debian/cron.dinstall: Put the timestamp stuff into an own
-       function, call that from everywhere. Also change the timestamp
-       format to not be local dependent.
-
-2008-05-05  Joerg Jaspert  <joerg@debian.org>
-
-       * daklib/dak_exceptions.py (dakerrors): add TransitionsError
-       * dak/transitions.py: Use it, instead of the own definition
-
-2008-05-05  Mark Hymers  <mhy@debian.org>
-
-       * daklib/dak_exceptions.py: Add a default message and tidy up our string
-       representation
-
-2008-05-05  Joerg Jaspert  <joerg@debian.org>
-
-       * daklib/dak_exceptions.py: New file, central place for all those
-       own exceptions dak may raise.
-
-       * daklib/utils.py: Use dak_exceptions and delete all those string
-       exception raising stuff, which is depcreated.
-       During that delete the unknown_hostname_exc, as it wasnt used.
-
-       * dak/import_archive.py: use the new Exception class
-       * dak/rm.py: dito
-       * dak/generate_releases.py: dito
-       * dak/queue_report.py: dito
-       * daklib/queue.py: dito
-
-2008-05-04  Joerg Jaspert  <joerg@debian.org>
-
-       * daklib/queue.py: Various pychecker cleanups
-
-       * dak/import_keyring.py: Remove unused daklib.logging and Logger
-       and add the actually used daklib/utils
-
-       * dak/examine_package.py: remove daklib.queue import, never used
-
-       * dak/check_proposed_updates.py: Import stuff from daklib as
-       "import daklib.foo as foo"
-       * dak/clean_proposed_updates.py: likewise
-       * dak/clean_queues.py: likewise
-       * dak/clean_suites.py: likewise
-       * dak/compare_suites.py: likewise
-       * dak/cruft_report.py: likewise
-       (get_suite_binaries): Seperated in own function, out of main. More
-       of main should be splitted. (Or well, cruft_report redesigned a
-       little, so its easier to run on multiple suites with differing tests)
-
-       * dak/examine_package.py: likewise
-       * dak/find_null_maintainers.py: likewise
-       * dak/generate_index_diffs.py: likewise
-       * dak/generate_releases.py: likewise
-       * dak/import_archive.py: likewise
-       * dak/import_ldap_fingerprints.py: likewise
-       * dak/import_users_from_passwd.py: likewise
-       * dak/init_db.py: likewise
-       * dak/init_dirs.py: likewise
-       * dak/ls.py: likewise
-       * dak/make_maintainers.py: likewise
-       * dak/make_overrides.py: likewise
-       * dak/make_suite_file_list.py: likewise
-       * dak/new_security_install.py: likewise
-       * dak/override.py: likewise
-       * dak/process_accepted.py: likewise
-       * dak/process_new.py: likewise
-       * dak/process_unchecked.py: likewise
-       * dak/rm.py: likewise
-       * dak/show_new.py: likewise
-       * dak/split_done.py: likewise
-       * dak/stats.py: likewise
-       * dak/transitions.py: likewise
-
-       * dak/check_archive.py (check_files_not_symlinks): Remove
-       long-time unused and commented code. Import stuff from daklib as
-       "import daklib.foo as foo"
-
-2008-05-04  Thomas Viehmann  <tv@beamnet.de>
-
-       * dak/process_unchecked.py (check_signed_by_key): cater for uid_email
-       None in sponsor notification
-
-2008-05-03  Joerg Jaspert  <joerg@debian.org>
-
-       * dak/examine_package.py: clean up pychecker warnings (merged with
-       Thomas changes to the NEW display)
-
-2008-05-03  Mark Hymers <mhy@debian.org>
-
-       * dak/check_archive.py: clean up pychecker warnings
-       * dak/check_overrides.py: likewise
-       * dak/check_proposed_updates.py: likewise
-       * dak/clean_proposed_updates.py: likewise
-       * dak/clean_queues.py: likewise
-       * dak/control_overrides.py: likewise
-       * dak/control_suite.py: likewise
-       * dak/decode_dot_dak.py: likewise
-       * dak/examine_package.py: likewise
-       * dak/process_new.py: likewise
-       * dak/process_unchecked.py: likewise
-       * dak/queue_report.py: likewise
-       * dak/reject_proposed_updates.py: likewise
-       * dak/security_install.py: likewise
-       * dak/show_new.py: likewise
-       * dak/stats.py: likewise
-       * dak/symlink_dists.py: likewise
-       * dak/transitions.py: likewise
->>>>>>> sec-merge:ChangeLog
-
-2008-05-03  Joerg Jaspert  <joerg@debian.org>
-
-       * config/debian/cron.daily: Rename to
-       * config/debian/cron.dinstall: this, as its not really something run
-       daily for some time now. And while dinstall is an OLD name, its
-       recognized pretty well within Debian
-       Also add some more timing information
-       Do not allow automated [o-]p-u-new processing to break dinstall
-
-2008-05-03  Thomas Viehmann  <tv@beamnet.de>
-
-       * web/,web/style.css: add web dir and current style.css
-
-       * dak/examine_package.py, dak/show_new.py: improve NEW html pages,
-       based on mock-up by M. Ferrari.
-       remove Checksums-* from examine-package output
-
-2008-05-03  Thomas Viehmann  <tv@beamnet.de>
-
-       * dak/process_unchecked.py (check_hashes): Reject on error while
-       parsing Checksums-*.
-
-2008-05-02  Joerg Jaspert  <joerg@debian.org>
-
-       * config/debian/pseudo-packages*: Removed listarchives, closes #468667
-       added wiki.debian.org (currently pointing to debian-www), closes #194206
-       added security-tracker, closes #436152
-       added release.debian.org, closes #451005
-
-       * config/debian/cron.buildd: Cleanup unreachable code. (If someone
-       still wants it - its in revision control...)
-
-       * config/debian/cron.daily: Modify call to update-ftpstats to only
-       use files log/2*, instead of log/*, so it ignores the new cron/
-       subdir. Makes sure it can't get confused, and is also safe for
-       nearly thousand years. If this code is really in use in year 3000,
-       im sure people can adjust it! :)
-
-       * config/debian/vars: Add logdir as a place for cronjob log output
-
-       * config/debian/cron.daily: Use a logfile and be more verbose of
-       whats going on.
-         Also moved the commented VACUUM ; VACUUM ANALYZE calls over to
-       cron.weekly, ...
-       * config/debian/cron.weekly: likewise,
-         ... and activate those calls again. Once a week, as an
-       additional safety bet to be sure the stuff does get run is ok,
-       even if we have autovacuum by default.
-
-2008-05-02  Thomas Viehmann  <tv@beamnet.de>
-
-       * dak/process_unchecked.py (check_hashes): fix typo in
-         checksum reject message.
-
-2008-05-02  Joerg Jaspert  <joerg@debian.org>
-
-       * config/debian/extensions.py: used reindent.py from the python
-       2.x source examples to get all dak code use the same indentation
-       style, no longer a mix of 4 spaces / 1 tab.
-       * dak/check_archive.py: likewise
-       * dak/check_overrides.py: likewise
-       * dak/check_proposed_updates.py: likewise
-       * dak/clean_proposed_updates.py: likewise
-       * dak/clean_queues.py: likewise
-       * dak/clean_suites.py: likewise
-       * dak/compare_suites.py: likewise
-       * dak/control_overrides.py: likewise
-       * dak/control_suite.py: likewise
-       * dak/cruft_report.py: likewise
-       * dak/dak.py: likewise
-       * dak/decode_dot_dak.py: likewise
-       * dak/examine_package.py: likewise
-       * dak/find_null_maintainers.py: likewise
-       * dak/generate_index_diffs.py: likewise
-       * dak/generate_releases.py: likewise
-       * dak/import_archive.py: likewise
-       * dak/import_keyring.py: likewise
-       * dak/import_ldap_fingerprints.py: likewise
-       * dak/import_users_from_passwd.py: likewise
-       * dak/init_db.py: likewise
-       * dak/init_dirs.py: likewise
-       * dak/ls.py: likewise
-       * dak/make_maintainers.py: likewise
-       * dak/make_overrides.py: likewise
-       * dak/make_suite_file_list.py: likewise
-       * dak/mirror_split.py: likewise
-       * dak/new_security_install.py: likewise
-       * dak/override.py: likewise
-       * dak/poolize.py: likewise
-       * dak/process_accepted.py: likewise
-       * dak/process_new.py: likewise
-       * dak/process_unchecked.py: likewise
-       * dak/queue_report.py: likewise
-       * dak/reject_proposed_updates.py: likewise
-       * dak/rm.py: likewise
-       * dak/security_install.py: likewise
-       * dak/show_new.py: likewise
-       * dak/split_done.py: likewise
-       * dak/stats.py: likewise
-       * dak/symlink_dists.py: likewise
-       * dak/test/001/test.py: likewise
-       * dak/test/002/test.py: likewise
-       * dak/transitions.py: likewise
-       * daklib/extensions.py: likewise
-       * daklib/logging.py: likewise
-       * daklib/queue.py: likewise
-       * daklib/utils.py: likewise
-       * scripts/debian/insert_missing_changedby.py: likewise
-
-       * dak/process_new.py (recheck): Make the path check more robust,
-       so we no longer have to keep process_new seperate trees between
-       security and normal archive.
-
-2008-04-27  Joerg Jaspert  <joerg@debian.org>
-
-       * dak/process_accepted.py (Urgency_Log.__init__): Warn if the
-       configured path does not exist or is not writeable by us. Use a
-       tmp path if so, so we do not lose the urgencies in such cases.
-
-       * config/debian/dak.conf: Changed path for UrgencyLog
-       Same for the ReleaseTransitions file
-
-       * config/debian/cron.daily: Notify qa user on merkel of dinstall
-       start, Remove the britney call
-
-2008-04-26  Joerg Jaspert  <joerg@debian.org>
-
-       * dak/process_new.py: Call end() whenever we try to leave by
-       pressing Q
-
-       * config/debian/cron.daily: Also report NBS in experimental
-
-2008-04-25  Joerg Jaspert  <joerg@debian.org>
-
-       * dak/cruft_report.py (main): Make it possible to look at
-       experimental too, especially NBS
-
-       * dak/split_done.py (main): Only move files into their subdirs if
-       they are older than 30 days. That enables us to run this script as
-       part of a cronjob.
-
-       * config/debian/cron.weekly: Run dak split-done
-
-2008-04-23  Thomas Viehmann  <tviehmann@debian.org>
-
-       * dak/process_unchecked.py: add changes["sponsoremail"]
-         for sponsored uploads if desired
-       * daklib/queue.py: add changes["sponsoremail"] to
-         Subst["__MAINTAINER_TO__"] if present
-       * daklib/utils.py: add functions
-         is_email_alias to check which accounts allow email forwarding,
-         which_alias_file to find the alias file, and
-         gpg_get_key_addresses to find uid addresses for a given
-           fingerprint
-
-2008-04-22  Joerg Jaspert  <joerg@debian.org>
-
-       * setup/init_pool.sql: added a function/aggregate for the release
-       team to base some script on it.
-
-       * config/debian/cron.daily: push katie@merkel to immediately start
-       the sync of projectb there.
-
-2008-04-21  Joerg Jaspert  <joerg@debian.org>
-
-       * scripts/debian/expire_dumps: New script, expires old database
-       dumps, using a scheme to keep more of the recent dumps.
-
-       * config/debian/cron.daily: Use the new script. Also - compress
-       all files older than 7 days, instead of 30.
-
-       * dak/process_accepted.py (install): Do not break if a
-       source/maintainer combination is already in src_uploaders, "just"
-       warn us.
-
-2008-04-20  Thomas Viehmann  <tviehmann@debian.org>
-
-       * daklib/utils.py (build_file_list): Deal with "Format 3 style"
-       Format lines (ie. those having extra text appended).
-
-2008-04-19  Joerg Jaspert  <joerg@debian.org>
-
-       * dak/process_unchecked.py (check_files): Sanity check the
-       provides field, which closes #472783
-
-2008-04-18  Joerg Jaspert  <joerg@debian.org>
-
-       * config/debian/dak.conf: Add mapping stable-proposed-updates
-         -> proposed-updates.
-
-       * dak/transitions.py (load_transitions): Additionally check for
-       invalid package list indentation
-
-2008-04-17  Joerg Jaspert  <joerg@debian.org>
-
-       * config/debian/dak.conf: Add TempPath statement for the Release
-       Transitions script
-
-       * dak/transitions.py (temp_transitions_file): Use the TempPath
-       (write_transitions_from_file): Check if the file we should get our
-       transitions from is in our TempPath, error out if it isnt
-       (main): Check for TempPath existance
-
-2008-04-12  James Troup  <troup@debian.org>
-
-       * dak/clean_proposed_updates.py: add support for -s/--suite and
-       -n/--no-action.
-
-2008-04-11  Anthony Towns  <ajt@debian.org>
-
-       * dak/utils.py: build_file_list() extra parameters so it can
-       build a file list for checksums-foo fields. Don't use float() to
-       compare formats, because Format: 1.10 should compare greater than
-       Format: 1.9 (use "1.9".split(".",1) and tuple comparison instead)
-
-       * dak/process_unchecked.py: check_md5sum becomes check_hashes
-       and check_hash. If changes format is 1.8 or later, also check
-       checksums-sha1 and checksums-sha256 for both .changes and .dsc,
-       and reject on presence/absence of un/expected checksums-* fields.
-
-2008-04-07  Joerg Jaspert  <joerg@debian.org>
-
-       * daklib/utils.py (build_file_list): Check for dpkg .changes
-       adjusted to reject newer (and right now broken) 1.8 version, until
-       dpkg (or debsign) is fixed and doesn't produce invalid .changes anymore
-
-2008-03-22  Joerg Jaspert  <joerg@debian.org>
-
-       * dak/transitions.py (load_transitions): Check if all our keys are
-       defined, if there are only keys defined we want and also the types
-       of the various keys.
-
-2008-03-22  Anthony Towns  <ajt@debian.org>
-
-       * dak/edit_transitions.py: Add --import option.
-       Add --use-sudo option. Use fcntl locking for writing.
-       Move writing into a function (write_transitions).
-       Reinvoke self using sudo and --import if necessary.
-       Move temporary file creation into a function, use mkstemp.
-       Rename to "dak transitions".
-
-2008-03-21  Joerg Jaspert  <joerg@debian.org>
-
-       * dak/edit_transitions.py (edit_transitions): Use sudo to copy the
-       edited file back in place
-       (check_transitions): Use proper locking and also use sudo to copy
-       the new file in place
-
-2008-03-21  Anthony Towns <ajt@debian.org>
-
-       * config/debian/extensions.py: Add infrastructure for replacing
-       functions in dak modules; add upload blocking for dpkg.
-
-2008-03-12  Joerg Jaspert  <joerg@debian.org>
-
-       * dak/edit_transitions.py: Done a number of cleanups to make code
-       working. Also changed the way prompting/answering goes, to not
-       have to import daklib/queue.
-       (edit_transitions): When done with a successful edit - also print
-       a final overview about defined transitions
-
-2008-03-11  Joerg Jaspert  <joerg@debian.org>
-
-       * dak/process_unchecked.py: Import syck module directly, not "from
-       syck import *"
-       (check_transition): Do the check for sourceful upload in here
-       Also adjust the syck loading commands, rename new_vers to
-       expected, curvers to current, to make it more clear what they mean.
-
-       * daklib/database.py (get_suite_version): Renamed from
-       get_testing_version. Also changed the cache variables name
-
-       * The above changes are based on modifications from Anthony.
-
-       * dak/dak.py (init): Renamed check -> edit transitions
-
-       * dak/edit_transitions.py: Renamed from check_transitions.py
-       (main): Also rename new_vers/curvers to expected/current
-       Basically a nice rewrite, so it now does checks and edit,
-       depending on how you call it. Check also removes old transitions,
-       if user wants it.
-
-2008-03-02  Joerg Jaspert  <joerg@debian.org>
-
-       * debian/control (Suggests): Add python-syck to Depends:
-
-       * dak/dak.py (init): Tell it about check_transitions
-
-       * dak/check_transitions.py (usage): Added, checks the transitions
-       file (if any)
-
-       * daklib/database.py (get_testing_version): Added. Returns the
-       version for the source in testing, if any
-
-       * dak/process_unchecked.py (check_transition): Added. Checks if a
-       release team member defined a transition, and rejects based on
-       that data.
-       (process_it): Use it.
-       (check_transition): Warn on broken transitions file and return,
-       not doing anything.
-       (check_transition): Moved out of here, into daklib/queue
-       (process_it): Call check_transitions only if
-       changes[architecture] has source included.
-       (check_transition): Now call the database.get_testing_version
-
-2008-02-09  Christoph Berg <myon@debian.org>
-
-       * daklib/queue.py (get_type): fubar does not exist in global
-       namespace.
-
-       * setup/add_constraints.sql setup/init_pool.sql: Add changedby column
-       to source table, and move src_uploaders after source so the REFERNCES
-       clause works.
-       * dak/process_accepted.py (install): Fill the changedby column from
-       the information found in the .changes. This will allow to identify
-       NMUs and sponsored uploads more precisely in tools querying projectb.
-       * scripts/debian/insert_missing_changedby.py: Script to import yet
-       missing fields from filippo's uploads-history DB.
-
-2008-02-06  Joerg Jaspert  <joerg@debian.org>
-
-       * daklib/utils.py (check_signature): Make variable key available,
-       so we can access it.
-
-2008-01-07  Joerg Jaspert  <joerg@debian.org>
-
-       * dak/examine_package.py (check_deb): Remove linda call. It
-       provides no added benefit to lintian anymore.
-
-2008-01-07  Joerg Jaspert  <joerg@debian.org>
-
-       * dak/examine_package.py (check_deb): Remove linda call. It
-       provides no added benefit to lintian anymore.
-
-2008-01-06  Joerg Jaspert  <joerg@debian.org>
-
-       * dak/examine_package.py (do_lintian): lintian now supports html
-       coloring, so use it.
-       (do_command): Dont escape html chars if param escaped = 1
-
-2008-01-06  Joerg Jaspert  <joerg@debian.org>
-
-       * dak/examine_package.py (do_lintian): lintian now supports html
-       coloring, so use it.
-       (do_command): Dont escape html chars if param escaped = 1
-
-2007-12-31  Anthony Towns  <ajt@debian.org>
-
-       * dak/process_new.py (recheck): pass "" for prefix_str to reject()
-       when processing result of check_dsc_against_db so we don't promote
-       warnings to rejections.
-
-2007-12-31  Anthony Towns  <ajt@debian.org>
-
-       * dak/process_new.py (recheck): pass "" for prefix_str to reject()
-       when processing result of check_dsc_against_db so we don't promote
-       warnings to rejections.
-
-2007-12-30  Joerg Jaspert  <joerg@debian.org>
-
-       * dak/dak.py (init): add show-new. This is based on a patch
-       submitted by Thomas Viehmann in Bug #408318, but large parts of
-       handling it are rewritten and show-new is done by me.
-
-       * dak/queue_report.py (table_row): Add link to generated html page
-       for NEW package.
-
-       * dak/show_new.py: new file, generates html overview for NEW
-       packages, similar to what we see with examine-package.
-
-       * config/debian/cron.hourly: Add show-new call
-
-       * config/debian/dak.conf: Add HTMLPath for Show-New
-
-       * dak/examine_package.py (print_copyright): ignore stderr when
-       finding copyright file.
-       (main): add html option
-       (html_escape): new function
-       (escape_if_needed): ditto
-       (headline): ditto
-       (colour_output): ditto
-       (print_escaped_text): ditto
-       (print_formatted_text): ditto
-       - use those functions everywhere where we generate output, as they
-       easily know if we want html or not and just DTRT
-       (do_lintian): new function
-       (check_deb): use it
-       (output_deb_info): Use print_escaped_text, not print_formatted_text.
-       Also import daklib.queue, determine_new now lives there
-
-       Also add a variable to see if we want html output. Default is
-       disabled, show_new enables it for its use.
-       Most of html, besides header/footer are in examine_package instead
-       of show_new, as it makes it a whole lot easier to deal with it at
-       the point the info is generated.
-
-
-       * dak/process_new.py (determine_new): Moved out of here.
-       (check_valid): Moved out of here.
-       (get_type): Moved out of here.
-
-       * daklib/queue.py (determine_new): Moved here.
-       (check_valid): Moved here.
-       (get_type): Moved here.
-
-       * dak/init_db.py (do_section): Remove non-US code
-
-       * dak/make_overrides.py (main): ditto
-
-       * dak/process_new.py (determine_new): ditto
-
-       * daklib/queue.py (Upload.in_override_p),
-       (Upload.check_override): ditto
-
-       * daklib/utils.py (extract_component_from_section):,
-       (poolify): ditto
-
-       * dak/import_archive.py (update_section): ditto
-
-       * dak/symlink_dists.py (fix_component_section): ditto
-
-       * scripts/debian/mkmaintainers: ditto
-
-       * scripts/debian/update-mirrorlists (masterlist): ditto
-
-       * config/debian-non-US/*: Remove subdir
-
-       * scripts/debian/update-readmenonus: Removed.
-
-
-2007-12-30  Joerg Jaspert  <joerg@debian.org>
-
-       * dak/dak.py (init): add show-new. This is based on a patch
-       submitted by Thomas Viehmann in Bug #408318, but large parts of
-       handling it are rewritten and show-new is done by me.
-
-       * dak/queue_report.py (table_row): Add link to generated html page
-       for NEW package.
-
-       * dak/show_new.py: new file, generates html overview for NEW
-       packages, similar to what we see with examine-package.
-
-       * config/debian/cron.hourly: Add show-new call
-
-       * config/debian/dak.conf: Add HTMLPath for Show-New
-
-       * dak/examine_package.py (print_copyright): ignore stderr when
-       finding copyright file.
-       (main): add html option
-       (html_escape): new function
-       (escape_if_needed): ditto
-       (headline): ditto
-       (colour_output): ditto
-       (print_escaped_text): ditto
-       (print_formatted_text): ditto
-       - use those functions everywhere where we generate output, as they
-       easily know if we want html or not and just DTRT
-       (do_lintian): new function
-       (check_deb): use it
-       (output_deb_info): Use print_escaped_text, not print_formatted_text.
-       Also import daklib.queue, determine_new now lives there
-
-       Also add a variable to see if we want html output. Default is
-       disabled, show_new enables it for its use.
-       Most of html, besides header/footer are in examine_package instead
-       of show_new, as it makes it a whole lot easier to deal with it at
-       the point the info is generated.
-
-
-       * dak/process_new.py (determine_new): Moved out of here.
-       (check_valid): Moved out of here.
-       (get_type): Moved out of here.
-
-       * daklib/queue.py (determine_new): Moved here.
-       (check_valid): Moved here.
-       (get_type): Moved here.
-
-       * dak/init_db.py (do_section): Remove non-US code
-
-       * dak/make_overrides.py (main): ditto
-
-       * dak/process_new.py (determine_new): ditto
-
-       * daklib/queue.py (Upload.in_override_p),
-       (Upload.check_override): ditto
-
-       * daklib/utils.py (extract_component_from_section):,
-       (poolify): ditto
-
-       * dak/import_archive.py (update_section): ditto
-
-       * dak/symlink_dists.py (fix_component_section): ditto
-
-       * scripts/debian/mkmaintainers: ditto
-
-       * scripts/debian/update-mirrorlists (masterlist): ditto
-
-       * config/debian-non-US/*: Remove subdir
-
-       * scripts/debian/update-readmenonus: Removed.
-
-
-2007-12-28  Anthony Towns  <ajt@debian.org>
-
-       * daklib/utils.py (check_signature): add NOTATION_DATA and
-       NOTATION_NAME to known keywords.
-
-       * daklib/queue.py (Upload.check_source_against_db):
-
-       * dak/make_suite_file_list.py: add -f/--force option.
-
-       * dak/generate_releases.py: add -a/--apt-conf=FILE and
-       -f/--force-touch options.  Pull version info from the database.
-       Make suite description optional.
-
-       * config/debian/dak.conf: update
-       Reject-Proposed-Updates::MoreInfoURL.  Comment out
-       Suite::Stable::Version and ::Description.
-
-       * config/debian/apt.conf: Add hurd-i386 to unstable
-       debian-installer stanza.
-
-2007-12-28  Joerg Jaspert  <joerg@debian.org>
-
-       * KEYEXPIRED is actually a known keyword. We do check it earlier
-       on and reject in case the sig is bad (or unknown)
-
-2007-12-28  Anthony Towns  <ajt@debian.org>
-
-       * daklib/utils.py (check_signature): add NOTATION_DATA and
-       NOTATION_NAME to known keywords.
-
-       * daklib/queue.py (Upload.check_source_against_db):
-
-       * dak/make_suite_file_list.py: add -f/--force option.
-
-       * dak/generate_releases.py: add -a/--apt-conf=FILE and
-       -f/--force-touch options.  Pull version info from the database.
-       Make suite description optional.
-
-       * config/debian/dak.conf: update
-       Reject-Proposed-Updates::MoreInfoURL.  Comment out
-       Suite::Stable::Version and ::Description.
-
-       * config/debian/apt.conf: Add hurd-i386 to unstable
-       debian-installer stanza.
-
-2007-12-28  Joerg Jaspert  <joerg@debian.org>
-
-       * KEYEXPIRED is actually a known keyword. We do check it earlier
-       on and reject in case the sig is bad (or unknown)
-
-2007-12-24  Joerg Jaspert  <joerg@debian.org>
-
-       * Also run lintian on the .dsc file to check the source itself.
-
-       * Fix the direct usage of ar | tar etc to get the copyright file
-       and use dpkg-deb, which is made for this and makes us able to
-       process data.tar.bz2 (or whatever format it will be in the
-       future).
-
-2007-12-24  Joerg Jaspert  <joerg@debian.org>
-
-       * Also run lintian on the .dsc file to check the source itself.
-
-       * Fix the direct usage of ar | tar etc to get the copyright file
-       and use dpkg-deb, which is made for this and makes us able to
-       process data.tar.bz2 (or whatever format it will be in the
-       future).
-
-2007-12-21  Joerg Jaspert  <joerg@debian.org>
-
-       * Remove the (now useless) check for a pre-depends on dpkg for
-         binaries that contain bzip2 compressed data tarballs.
-
-2007-12-21  Joerg Jaspert  <joerg@debian.org>
-
-       * Remove the (now useless) check for a pre-depends on dpkg for
-         binaries that contain bzip2 compressed data tarballs.
-
-2007-08-28  Anthony Towns  <ajt@debian.org>
-
-       * process_unchecked.py: Add support for automatic BYHAND
-       processing.
-       * config/debian/dak.conf, scripts/debian/byhand-tag: Automatic
-       processing of tag-overrides.
-       * examine_package.py: Summarise duplicate copyright file entries
-       (same md5sum) with a reference to the previous instance, rather
-       than repeating them.
-       * process_new.py: When rejecting from the p-u-new or o-p-u-new
-       holding queues, don't worry if dak has its own reasons for
-       rejecting the package as well as the SRMs.
-
-2007-08-28  Anthony Towns  <ajt@debian.org>
-
-       * process_unchecked.py: Add support for automatic BYHAND
-       processing.
-       * config/debian/dak.conf, scripts/debian/byhand-tag: Automatic
-       processing of tag-overrides.
-       * examine_package.py: Summarise duplicate copyright file entries
-       (same md5sum) with a reference to the previous instance, rather
-       than repeating them.
-       * process_new.py: When rejecting from the p-u-new or o-p-u-new
-       holding queues, don't worry if dak has its own reasons for
-       rejecting the package as well as the SRMs.
-
-2007-06-19  Anthony Towns  <ajt@debian.org>
-
-       * Add nm.debian.org pseudopackage
-
-2007-06-19  Anthony Towns  <ajt@debian.org>
-
-       * Add nm.debian.org pseudopackage
-
-2007-06-18  Anthony Towns  <ajt@debian.org>
-
-       * daklib/logging.py: Set umask to not exclude group-writability
-       so we don't get reminded at the start of each month. Thanks to
-       Random J.
-       * dak/override.py: More changes from Herr von Wifflepuck: warn
-       if section of source is different to binary section; restore
-       functionality on source-only overrides; croak if trying to set
-       priority of a source override; never set priority of source
-       overrides; correct typo in logging (s/priority/section/ at
-       one place)
-
-       * config/debian/apt.conf.oldstable: Added for oldstable point releases.
-       * config/debian/cron.daily: auotmatically accept/reject
-       oldstable-proposed-updates based on COMMENTS directory
-
-2007-06-18  Anthony Towns  <ajt@debian.org>
-
-       * config/debian/apt.conf, config/debian/apt.conf.stable,
-       config/debian/dak.conf: update for 4.0r0 (etch), and 3.1r6
-       (sarge), support for oldstable-proposed-updates, dropping m68k
-       from etch, creating etch-m68k suite, creating lenny.
-
-       * config/debian/vars: update for lenny
-
-       * config/debian/dak.conf: typo fix for Dinstall::GPGKeyring,
-       drop upload limitations, add release postgres user
-
-       * dak/process_new.py: support for automatically accepting and rejecting
-       packages from proposed-updates holding queues via COMMENTS directory
-       * cron.daily: automatically process COMMENTS-based approvals
-       and rejections for proposed-updates holding queues
-
-       * dak/process_unchecked.py: add support for oldproposedupdates
-       holding queue
-
-       * dak/control_suite.py: allow control-suite to work with etch-m68k
-
-       * dak/generate_releases.py: unlink old Release files before updating
-       them if nlinks > 1 (ie, if two files used to be the same, maybe they
-       shouldn't be when generate-releases is run)
-
-       * dak/generate_releases.py: add a couple of commented lines to make
-       it easier to deal with point releases
-
-       * dak/make_overrides.py: generate overrides for !contrib udebs
-
-       * docs/README.stable-point-release: update docs for doing a
-       point release
-
-2007-06-18  Anthony Towns  <ajt@debian.org>
-
-       * daklib/logging.py: Set umask to not exclude group-writability
-       so we don't get reminded at the start of each month. Thanks to
-       Random J.
-       * dak/override.py: More changes from Herr von Wifflepuck: warn
-       if section of source is different to binary section; restore
-       functionality on source-only overrides; croak if trying to set
-       priority of a source override; never set priority of source
-       overrides; correct typo in logging (s/priority/section/ at
-       one place)
-
-       * config/debian/apt.conf.oldstable: Added for oldstable point releases.
-       * config/debian/cron.daily: auotmatically accept/reject
-       oldstable-proposed-updates based on COMMENTS directory
-
-2007-06-18  Anthony Towns  <ajt@debian.org>
-
-       * config/debian/apt.conf, config/debian/apt.conf.stable,
-       config/debian/dak.conf: update for 4.0r0 (etch), and 3.1r6
-       (sarge), support for oldstable-proposed-updates, dropping m68k
-       from etch, creating etch-m68k suite, creating lenny.
-
-       * config/debian/vars: update for lenny
-
-       * config/debian/dak.conf: typo fix for Dinstall::GPGKeyring,
-       drop upload limitations, add release postgres user
-
-       * dak/process_new.py: support for automatically accepting and rejecting
-       packages from proposed-updates holding queues via COMMENTS directory
-       * cron.daily: automatically process COMMENTS-based approvals
-       and rejections for proposed-updates holding queues
-
-       * dak/process_unchecked.py: add support for oldproposedupdates
-       holding queue
-
-       * dak/control_suite.py: allow control-suite to work with etch-m68k
-
-       * dak/generate_releases.py: unlink old Release files before updating
-       them if nlinks > 1 (ie, if two files used to be the same, maybe they
-       shouldn't be when generate-releases is run)
-
-       * dak/generate_releases.py: add a couple of commented lines to make
-       it easier to deal with point releases
-
-       * dak/make_overrides.py: generate overrides for !contrib udebs
-
-       * docs/README.stable-point-release: update docs for doing a
-       point release
-
-2007-03-05  Anthony Towns  <ajt@debian.org>
-
-       * config/debian/dak.conf: update for 3.1r5.
-       * scripts/debian/ssh-move: add ssh-move script from debbugs
-       * config/debian/cron.unchecked: push version info to debbugs using
-       ssh-move.
-
-2007-03-05  Anthony Towns  <ajt@debian.org>
-
-       * config/debian/dak.conf: update for 3.1r5.
-       * scripts/debian/ssh-move: add ssh-move script from debbugs
-       * config/debian/cron.unchecked: push version info to debbugs using
-       ssh-move.
-
-2007-02-14  James Troup  <troup@ries.debian.org>
-
-       * docs/README.config: remove Dinstall::GroupOverrideFilename.
-       * config/debian/dak.conf: likewise.
-       * config/debian-non-US/dak.conf: likewise.
-       * config/debian-security/dak.conf: likewise.
-
-       * daklib/queue.py (Upload.close_bugs): no longer handle NMUs or
-       experimental differently, just close the bugs and let version
-       tracking sort it out.
-        (nmu_p): remove entire class - now unused.
-        (Upload.__init__): don't use nmu_p.
-
-2007-02-14  James Troup  <troup@ries.debian.org>
-
-       * docs/README.config: remove Dinstall::GroupOverrideFilename.
-       * config/debian/dak.conf: likewise.
-       * config/debian-non-US/dak.conf: likewise.
-       * config/debian-security/dak.conf: likewise.
-
-       * daklib/queue.py (Upload.close_bugs): no longer handle NMUs or
-       experimental differently, just close the bugs and let version
-       tracking sort it out.
-        (nmu_p): remove entire class - now unused.
-        (Upload.__init__): don't use nmu_p.
-
-2007-02-08  Anthony Towns  <ajt@debian.org>
-
-       * config/debian/dak.conf: update for 3.1r4.  Use new 'etch'
-       signing key.  Drop maximum index diffs down to 14.
-
-       * config/debian/apt.conf: add udeb support for non-free (testing,
-       unstable) and experimental.
-       * config/debian/dak.conf: likewise.
-
-       * dak/generate_releases.py (main): handle udebs in any component.
-
-       * daklib/queue.py (Upload.build_summaries): handle files without a
-       'type' gracefully.
-
-       * dak/generate_releases.py (print_sha256_files): new function.
-       (main): use it.
-
-       * dak/process_accepted.py (stable_install): fix name of template
-       mail.
-
-       * dak/process_unchecked.py (is_stableupdate): fix invocation of
-       database.get_suite_id().
-
-       * templates/process-new.bxa_notification: Update on request
-       of/after discussion with BIS staff.
-
-       * scripts/debian/mkfilesindices: also handle proposed-updates.
-
-2007-02-08  Ryan Murray  <rmurray@debian.org>
-
-       * config/debian/cron.monthly: use $ftpgroup instead of hardcoding
-       group name for chgrp of mail archives.
-
-       * daklib/queue.py (Upload.check_dsc_against_db): handle multiple
-       orig.tar.gz's by picking the first one by file id.
-
-       * dak/override.py (main): limit to binary overrides only for now.
-       (usage): update to match.
-
-       * config/debian/cron.daily: track when we have the accepted lock
-       and clean it up on exit if we have it.  Take/check the
-       cron.unchecked lock just before traping to cleanup on exit.
-       Remove potato override handling.  Remove any dangling symlinks in
-       /srv/incoming.d.o/buildd.  Clean up apt-ftparchive's databases.
-
-       * config/debian/apt.conf: change default compression scheme for
-       both Sources and Packages to gzip and bzip2 rather than
-       uncompressed and gzip (Packages) and gzip (Sources).  Use old
-       defaults for proposed-updates.
-
-       * dak/control_overrides.py (main): refuse to operate on
-       untouchable suites.
-
-       * config/debian/pseudo-packages.maintainers: drop install,
-       installation, boot-floppy, slink-cd, potato-cd and
-       nonus.debian.org.  Update base.
-       * config/debian/pseudo-packages.description: likewise.
-
-       * daklib/utils.py (re_srchasver): new regex.
-       (parse_changes): use regex to split 'Source (Version)' style
-       Source fields into 'source' and 'source-version'.
-
-       * config/debian/cron.daily: use $base instead of hardcoding path
-       name.
-
-       * scripts/debian/mkfilesindices: source 'vars' file and use it's
-       variables instead of hardcoding path names.
-
-       * config/debian/apt.conf: switch from /org to /srv.
-       * config/debian/apt.conf.buildd: likewise.
-       * config/debian/apt.conf.stable: likewise.
-       * config/debian/cron.daily: likewise.
-       * config/debian/cron.hourly: likewise.
-       * config/debian/cron.monthly: likewise.
-       * config/debian/cron.unchecked: likewise.
-       * config/debian/cron.weekly: likewise.
-       * config/debian/dak.conf: likewise.
-       * config/debian/vars: likewise.
-       * scripts/debian/mkfilesindices: likewise.
-
-2007-02-08  James Troup  <james@nocrew.org>
-
-       * dak/process_unchecked.py (check_signed_by_key): new function to
-       ensure .changes files are signed by an authorized uploader.
-       (process_it): use it.
-
-       * config/debian/dak.conf (Binary-Upload-Restrictions): new stanza
-       to configure per suite/component/architecture binary upload
-       restrictions.
-
-2007-02-08  Anthony Towns  <ajt@debian.org>
-
-       * config/debian/dak.conf: update for 3.1r4.  Use new 'etch'
-       signing key.  Drop maximum index diffs down to 14.
-
-       * config/debian/apt.conf: add udeb support for non-free (testing,
-       unstable) and experimental.
-       * config/debian/dak.conf: likewise.
-
-       * dak/generate_releases.py (main): handle udebs in any component.
-
-       * daklib/queue.py (Upload.build_summaries): handle files without a
-       'type' gracefully.
-
-       * dak/generate_releases.py (print_sha256_files): new function.
-       (main): use it.
-
-       * dak/process_accepted.py (stable_install): fix name of template
-       mail.
-
-       * dak/process_unchecked.py (is_stableupdate): fix invocation of
-       database.get_suite_id().
-
-       * templates/process-new.bxa_notification: Update on request
-       of/after discussion with BIS staff.
-
-       * scripts/debian/mkfilesindices: also handle proposed-updates.
-
-2007-02-08  Ryan Murray  <rmurray@debian.org>
-
-       * config/debian/cron.monthly: use $ftpgroup instead of hardcoding
-       group name for chgrp of mail archives.
-
-       * daklib/queue.py (Upload.check_dsc_against_db): handle multiple
-       orig.tar.gz's by picking the first one by file id.
-
-       * dak/override.py (main): limit to binary overrides only for now.
-       (usage): update to match.
-
-       * config/debian/cron.daily: track when we have the accepted lock
-       and clean it up on exit if we have it.  Take/check the
-       cron.unchecked lock just before traping to cleanup on exit.
-       Remove potato override handling.  Remove any dangling symlinks in
-       /srv/incoming.d.o/buildd.  Clean up apt-ftparchive's databases.
-
-       * config/debian/apt.conf: change default compression scheme for
-       both Sources and Packages to gzip and bzip2 rather than
-       uncompressed and gzip (Packages) and gzip (Sources).  Use old
-       defaults for proposed-updates.
-
-       * dak/control_overrides.py (main): refuse to operate on
-       untouchable suites.
-
-       * config/debian/pseudo-packages.maintainers: drop install,
-       installation, boot-floppy, slink-cd, potato-cd and
-       nonus.debian.org.  Update base.
-       * config/debian/pseudo-packages.description: likewise.
-
-       * daklib/utils.py (re_srchasver): new regex.
-       (parse_changes): use regex to split 'Source (Version)' style
-       Source fields into 'source' and 'source-version'.
-
-       * config/debian/cron.daily: use $base instead of hardcoding path
-       name.
-
-       * scripts/debian/mkfilesindices: source 'vars' file and use it's
-       variables instead of hardcoding path names.
-
-       * config/debian/apt.conf: switch from /org to /srv.
-       * config/debian/apt.conf.buildd: likewise.
-       * config/debian/apt.conf.stable: likewise.
-       * config/debian/cron.daily: likewise.
-       * config/debian/cron.hourly: likewise.
-       * config/debian/cron.monthly: likewise.
-       * config/debian/cron.unchecked: likewise.
-       * config/debian/cron.weekly: likewise.
-       * config/debian/dak.conf: likewise.
-       * config/debian/vars: likewise.
-       * scripts/debian/mkfilesindices: likewise.
-
-2007-02-08  James Troup  <james@nocrew.org>
-
-       * dak/process_unchecked.py (check_signed_by_key): new function to
-       ensure .changes files are signed by an authorized uploader.
-       (process_it): use it.
-
-       * config/debian/dak.conf (Binary-Upload-Restrictions): new stanza
-       to configure per suite/component/architecture binary upload
-       restrictions.
-
-2006-10-09  James Troup  <james.troup@canonical.com>
-
-       * dak/process_unchecked.py (check_timestamps): change match to
-       search as recent versions of python-apt prefix the string with 'E: '.
-
-2006-10-09  James Troup  <james.troup@canonical.com>
-
-       * dak/process_unchecked.py (check_timestamps): change match to
-       search as recent versions of python-apt prefix the string with 'E: '.
-
-2006-06-26  Ryan Murray  <rmurray@debian.org>
-
-       * dak/process_unchecked.py (check_files): strip optional source version
-       from Source: field in changes file, and ensure what is left is a valid
-       package name.
-
-2006-06-26  Ryan Murray  <rmurray@debian.org>
-
-       * dak/process_unchecked.py (check_files): strip optional source version
-       from Source: field in changes file, and ensure what is left is a valid
-       package name.
-
-2006-06-23  Ryan Murray  <rmurray@debian.org>
-
-       * dak/process_unchecked.py (check_files): also check ProposedUpdates
-       queue for source.
-
-2006-06-23  Ryan Murray  <rmurray@debian.org>
-
-       * dak/process_unchecked.py (check_files): also check ProposedUpdates
-       queue for source.
-
-2006-06-18  Ryan Murray  <rmurray@debian.org>
-
-       * dak/scripts/debian/update-ftpstats: look for dak named processes in
-       the log, too.
-
-       * dak/process_unchecked.py (check_files): only check embargoed and
-       unembargoed queues if the keys are set.
-
-       * dak/config/debian-security/apt.conf: set Packages::Compress to gzip
-       and bzip2 for etch.
-
-2006-06-18  Ryan Murray  <rmurray@debian.org>
-
-       * dak/scripts/debian/update-ftpstats: look for dak named processes in
-       the log, too.
-
-       * dak/process_unchecked.py (check_files): only check embargoed and
-       unembargoed queues if the keys are set.
-
-       * dak/config/debian-security/apt.conf: set Packages::Compress to gzip
-       and bzip2 for etch.
-
-2006-06-16  James Troup  <james@nocrew.org>
-
-       * dak/dak.py (init): add new-security-install.
-
-       * dak/new_security_install.py: cleanups and adapt for new naming
-       scheme and other changes.
-
-2006-06-16  Anthony Towns  <ajt@debian.org>
-
-       * dak/new_security_install.py: initial version imported from
-       klecker.
-
-2006-06-16  James Troup  <james@nocrew.org>
-
-       [Merged changes from klecker - original author unknown.]
-
-       * daklib/queue.py (Upload.dump_vars): also save changes["adv id"].
-
-       * dak/security_install.py (do_upload): fix check for oldstable and
-       upload file list handling.
-
-       * dak/process_unchecked.py (check_files): update "check for
-       source" code to also look in Embargoed and Unembargoed queues.
-       (is_unembargo): fix handling of Dir::Queue::Disembargo.
-
-       * dak/decode_dot_dak.py (main): add support for changes["adv id"].
-
-       * config/debian-security/vars (disembargo): add.
-
-       * config/debian-security/dak.conf (Dinstall::SigningKeyIds):
-       update.
-       (Process-Unchecked::AcceptedLockFile): add.
-       (Suite::Testing): clean up Version and Description.
-       (SuiteMappings): add silent map from etch-secure to testing.
-
-       * config/debian-security/cron.unchecked: add support for
-       disembargoed queues.
-
-       * config/debian-security/apt.conf.buildd: add bzip2ed Packages
-       files too.
-
-       * config/debian-security/apt.conf: add amd64 to architectures for
-       testing-security.
-
-2006-06-11  James Troup  <troup@spohr.debian.org>
-
-       * config/debian/cron.daily: invoke process-accepted not
-       process-unchecked.
-
-       * config/debian/vars (scriptsdir): new variable.
-       * config/debian/cron.daily: use it.
-
-       * scripts/debian/mkmaintainers: put Maintainers_Versions-non-US in
-       $base/misc/ instead of versioned $masterdir.  Correct 'dak
-       make-maintainers' invocation to look in $configdir for
-       pseudo-packages.maintainers.
-
-       * daklib/queue.py (Upload.do_reject): use correct name for
-       rejection template.
-
-2006-06-11  James Troup  <james@nocrew.org>
-
-       * dak/override.py (main): temporarily add content of old X-Katie
-       header back as the PTS apparently filters on it.
-       * dak/process_accepted.py (main): likewise.
-       * dak/process_new.py (main): likewise.
-       * dak/process_unchecked.py (main): likewise.
-       * dak/reject_proposed_updates.py (main): likewise.
-       * dak/rm.py (main): likewise.
-       * daklib/queue.py (Upload.do_reject): likewise.
-
-       * config/debian/cron.unchecked: set -u to error out on undefined
-       variables.  Preset LOCKDAILY to "" accordingly.
-       * config/debian/cron.hourly: likewise.
-       * config/debian/cron.monthly: likewise.
-       * config/debian/cron.weekly: likewise.
-
-       * config/debian/vars (configdir): add new variable pointing to
-       this directory.
-
-       * config/debian/cron.daily: use $configdir inplace of $masterdir
-       when that's what we mean, and don't cd into $masterdir just to run
-       dak scripts as we don't need to do that anymore.
-       * config/debian/cron.hourly: likewise.
-       * config/debian/cron.unchecked: likewise.
-       * config/debian/cron.weekly: likewise.
-
-       * config/debian/dak.conf
-       (Import-Users-From-Passwd::KnownPostgres): temporarily add 'katie'
-       user back to list of known users as it's non-trivial to entirely
-       change the owner of a database with postgresql 7.4.
-
-       * daklib/queue.py (Upload.source_exists): use string object
-       methods rather than string module.
-       (Upload.get_anyversion): likewise.
-
-       * daklib/utils.py (validate_changes_file_arg): update filename
-       slicing to cope with new .dak filenames.
-
-       * dak/ls.py (main): add back 'heidi' as a valid argument for
-       -f/--format as people are using it in scripts and breaking that
-       without warning seems rude.
-
-2006-05-21  James Troup  <james@nocrew.org>
-
-       * dak/rm.py (main): use string .isdigit() rather than
-       utils.str_isnum().
-       * dak/process_new.py (edit_overrides): likewise.
-
-       * daklib/utils.py (str_isnum): removed accordingly.  Also drop
-       string import.
-
-2006-05-21  James Troup  <james@nocrew.org>
-
-       * dak/check_archive.py (check_indices_files_exist): use list
-       comprehension instead of map().  No longer need to import
-       deprecated string module as a side-effect.
-       * dak/check_overrides.py (process): likewise.
-       (main): likewise.
-       * dak/cruft_report.py (do_obsolete_source): likewise.
-       (main): likewise.
-       * dak/ls.py (main): likewise.
-       * dak/make_suite_file_list.py (write_filelists): likewise.
-       * dak/process_accepted.py (stable_install): likewise.
-       * dak/rm.py (main): likewise.
-       * dak/stats.py (number_of_packages): likewise.
-       * daklib/logging.py (Logger.log): likewise.
-       * daklib/queue.py (Upload.source_exists): likewise.
-       (Upload.cross_suite_version_check): likewise.
-       * daklib/utils.py (parse_args): likewise.
-
-2006-05-21  James Troup  <james@nocrew.org>
-
-       * daklib/utils.py (process_gpgv_output): new function, split out
-       of check_signature().
-       (check_signature): adapt accordingly.
-       (retrieve_key): new function that will try to retrieve the key
-       that signed a given file from a keyserver.
-       (check_signature): add 'autofetch' argument that if not set
-       defaults to the value of Dinstall::KeyAutoFetch (if that exists).
-       If 'autofetch' is true, invoke retrieve_key().
-
-       * docs/README.config: document Dinstall::KeyAutoFetch and
-       Dinstall:KeyServer.
-
-2006-05-20  James Troup  <james@nocrew.org>
-
-       * dak/find_null_maintainers.py (main):
-       s/createtimestamp/createTimestamp/ to make things work with modern
-       slapd.
-
-       * config/debian/dak.conf: Update StableRejector, MoreInfoURL,
-       Stable::Version and Stable::Description for 3.1r2.
-
-       * config/debian-non-US/dak.conf: sync with klecker - update
-       version number of 3.0 and MoreInfoURL.
-
-       * docs/README.stable-point-release: Add notes about updating
-       dak.conf and Reject-Proposed-Updates section in particular.
-       s/woody/stable/.  Also need to update README.html.
-
-       * scripts/debian/mklslar: drop support for uncompressed ls-lR file.
-
-       * config/debian/apt.conf: Add udeb tree for proposed-updates.
-
-2006-05-20  Ryan Murray  <rmurray@debian.org>
-
-       * scripts/debian/update-ftpstats: new script to update daily
-       architecture size graph data.
-
-       * config/debian/cron.buildd: sync with spohr - due to ftp-master /
-       buildd split, simply ssh to buildd.d.o and call 'trigger.often'
-       there.
-
-       * config/debian/cron.daily: ssh to buildd and run 'trigger.daily'
-       before we finish.  Don't push to merkel.
-
-       * dak/process_unchecked.py (check_changes): Also look in
-       ProposedUpdates queue dir.
-       (check_files): likewise.
-
-2006-05-20  Anthony Towns  <ajt@debian.org>
-
-       * scripts/debian/mkfilesindices: new script to generate file
-       indices used for partial mirroring.
-
-       * config/debian/cron.daily: add progress timestamps.
-
-       * config/debian/dak.conf: update Dinstall::SigningKeyIds. Add
-       amd64 to testing, unstable and experimental.  Drop sh from
-       experimental.  Move Experimental to dists/experimental.  Add
-       Dir::ProposedUpdates.  Add Architectures::amd64.
-
-       * config/debian/apt.conf: add amd64 to testing, unstable and
-       experimental.  Drop uncompressed Packages files from testing. Drop
-       sh from experimental.  Move experimental to dists/experimental/.
-
-       * config/debian/vars (archs): add amd64.
-
-       * dak/process_unchecked.py (action): Add support for
-       proposed-updates approval queue.
-       (is_stableupdate): new function - checks if the upload is targeted
-       at proposed-updates.
-       (do_stableupdate): likewise - moves upload to proposed-updates
-       holding area.
-
-       * dak/process_new.py (do_new): warn if original or new target
-       suite are invalid.
-
-       * dak/generate_releases.py (print_md5sha_files): less whitespace
-       between the hash and size.
-
-       * dak/generate_index_diffs.py (genchanges): don't say we're not
-       doing anything.  Better formatting of other messages.
-       (main): don't skip experimental and remove some 'doing stuff'
-       prints.
-
-2006-05-18  James Troup  <james@nocrew.org>
-
-       * dak/clean_suites.py (clean_binaries): remove debug print of SQL
-       query.
-
-       * dak/init_dirs.py: pylint cleanups - long lines, unused globals,
-       docstrings, untabify, don't shadow builtins, lowercase non-global
-       variable names, spaces after commas.  Also bail if given any
-       arguments since we don't accept any.
-       * dak/init_db.py: likewise.  Also split large main() into
-       subfunctions and rename get() to sql_get().
-
-       * dak/init_db.py (main): check returned value from
-       database.get_archive_id().
-
-       * dak/dak.py: renamed from shell.py.  Update to support new source
-       layout.  Created init() and usage() functions.  Various
-       pylint-inspired cleanups.  Use daklib utils.warn() and
-       utils.fubar().  Change 'functionality' variable to only have
-       (command, description) and always invoke main() when running the
-       module.  Also support -h.
-
-2006-05-17  James Troup  <james@nocrew.org>
-
-       * dak/check_archive.py: remove $Id$ and $Revision$ strings.  Update
-       imports of and calls to daklib modules.  Change script name
-       everywhere, i.e. in output, mails, comments and configuration tree
-       + filenames.  Also update references to other renamed scripts,
-       classes and templates.  Use '.dak' instead of '.katie' for the
-       queue info storage files.
-       (Renamed from tea)
-       * dak/check_overrides.py: likewise.  (Renamed from cindy)
-       * dak/check_proposed_updates.py: likewise.  (Renamed from jeri)
-       * dak/clean_proposed_updates.py: likewise.  (Renamed from halle)
-       * dak/clean_queues.py: likewise.  (Renamed from shania)
-       * dak/clean_suites.py: likewise.  (Renamed from rhona)
-       * dak/compare_suites.py: likewise.  (Renamed from andrea)
-       * dak/control_overrides.py: likewise.  (Renamed from natalie)
-       * dak/control_suite.py: likewise.  (Renamed from heidi)
-       * dak/cruft_report.py: likewise.  (Renamed from rene)
-       * dak/decode_dot_dak.py: likewise.  (Renamed from ashley)
-       * dak/find_null_maintainers.py: likewise.  (Renamed from rosamund)
-       * dak/generate_index_diffs.py: likewise.  (Renamed from tiffani)
-       * dak/generate_releases.py: likewise.  (Renamed from ziyi)
-       * dak/import_archive.py: likewise.  (Renamed from neve)
-       * dak/import_ldap_fingerprints.py: likewise. (Renamed from emilie)
-       * dak/import_users_from_passwd.py: likewise. (Renamed from julia)
-       * dak/init_db.py: likewise. (Renamed from alyson)
-       * dak/init_dirs.py: likewise. (Renamed from rose)
-       * dak/ls.py: likewise. (Renamed from madison)
-       * dak/make_maintainers.py: likewise.  (Renamed from charisma)
-       * dak/make_overrides.py: likewise.  (Renamed from denise)
-       * dak/make_suite_file_list.py: likewise.  (Renamed from jenna)
-       * dak/mirror_split.py: likewise.  (Renamed from billie)
-       * dak/override.py: likewise.  (Renamed from alicia)
-       * dak/poolize.py: likewise.  (Renamed from catherine)
-       * dak/process_accepted.py: likewise.  (Renamed from kelly)
-       * dak/process_new.py: likewise.  (Renamed from lisa)
-       * dak/process_unchecked.py: likewise.  (Renamed from jennifer)
-       * dak/queue_report.py: likewise.  (Renamed from helena)
-       * dak/reject_proposed_updates.py: likewise.  (Renamed from lauren)
-       * dak/rm.py: likewise.  (Renamed from melanie)
-       * dak/security_install.py: likewise.  (Renamed from amber)
-       * dak/split_done.py: likewise.  (Renamed from nina)
-       * dak/stats.py: likewise.  (Renamed from saffron)
-       * dak/symlink_dists.py: likewise.  (Renamed from saffron)
-       * daklib/database.py: likewise.  (Renamed from db_access)
-       * daklib/queue.py: likewise.  'Katie' class -> 'Upload'. (Renamed from katie)
-       * daklib/utils.py: likewise.
-
-       * dak/cruft_report.py: Use '[auto-cruft]' as the magic "this removal
-       doesn't need to notify anyone" string.
-       * dak/rm.py: likewise, look for '[auto-cruft]' as the magic string.
-
-       * dak/process_accepted.py (init): drop -V/--version argument.
-       * dak/process_new.py (init): likewise.
-       * dak/process_unchecked.py (init): likewise.
-       * dak/reject_proposed_updates.py (init): likewise
-
-       * dak/shell.py: Renamed from dak.  ".katie" -> ".dak"
-
-       * dak/stats.py: in usage() output change STAT to MODE.
-
-2006-05-15  James Troup  <james@nocrew.org>
-
-       * dak/queue_report.py: remove unused encodings imports.
-
-       * dak/mirror_split.py: drop unused pg, pwd, db_access and logging
-       imports.  Initalize 'Cnf' as a global.
-       (BillieDB._internal_recurse): fix 'util.' typo.
-
-       * dak/import_ldap_fingerprints.py (main): drop unused time import and
-       commented out time check for LDAP search.
-
-2005-12-16  Ryan Murray  <rmurray@debian.org>
-
-       * halle: add support for udebs
-       * kelly: stable_install: add support for binNMU versions
-
-2005-12-05  Anthony Towns  <aj@erisian.com.au>
-
-       * katie.py: Move accept() autobuilding support into separate function 
-       (queue_build), and generalise to build different queues
-
-       * db_access.py: Add get_or_set_queue_id instead of hardcoding accepted=0
-
-       * jennifer: Initial support for enabling embargo handling with the
-       Dinstall::SecurityQueueHandling option.
-       * jennifer: Shift common code into remove_from_unchecked and move_to_dir
-       functions.
-
-       * katie.conf-security: Include embargo options
-       * katie.conf-security: Add Lock dir
-       * init_pool.sql-security: Create disembargo table
-       * init_pool.sql-security: Add constraints for disembargo table
-
-2005-11-26  Anthony Towns  <aj@erisian.com.au>
-
-       * Merge of changes from klecker, by various people
-
-       * amber: special casing for not passing on amd64 and oldstable updates
-       * amber: security mirror triggering
-       * templates/amber.advisory: updated advisory structure
-       * apt.conf.buildd-security: update for sarge's release
-       * apt.conf-security: update for sarge's release
-       * cron.buildd-security: generalise suite support, update for sarge's release
-       * cron.daily-security: update for sarge's release, add udeb support
-       * vars-security: update for sarge's release
-       * katie.conf-security: update for sarge's release, add amd64 support,
-       update signing key
-
-       * docs/README.names, docs/README.quotes: include the additions
-
-2005-11-25  Anthony Towns  <aj@erisian.com.au>
-
-       * Changed accepted_autobuild to queue_build everywhere.
-       * Add a queue table.
-       * Add a "queue" field in the queue_build table (currently always 0)
-
-       * jennifer: Restructure to make it easier to support special
-       purpose queues between unchecked and accepted.
-
-2005-11-25  Anthony Towns  <aj@erisian.com.au>
-
-       * Finishing merge of changes from spohr, by various people still
-
-       * jennifer: If changed-by parsing fails, set variables to "" so REJECT
-       works
-       * jennifer: Re-enable .deb ar format checking
-       * katie.py: Convert to +bX binNMU special casing
-       * rhona: Add some debug output when deleting binaries
-       * cron.daily: Add emilie
-       * cron.unchecked: Add lock files
-
-2005-11-15  Anthony Towns  <aj@erisian.com.au>
-
-       * Merge of changes from spohr, by various people.
-
-       * tiffani: new script to do patches to Packages, Sources and Contents
-       files for quicker downloads.
-       * ziyi: update to authenticate tiffani generated files
-
-       * dak: new script to provide a single binary with less arbitrary names
-       for access to dak functionality.
-
-       * cindy: script implemented
-
-       * saffron: cope with suites that don't have a Priority specified
-       * heidi: use get_suite_id()
-       * denise: don't hardcode stable and unstable, or limit udebs to unstable
-       * denise: remove override munging for testing (now done by cindy)
-       * helena: expanded help, added new, sort and age options, and fancy headers
-       * jennifer: require description, add a reject for missing dsc file
-       * jennifer: change lock file
-       * kelly: propogation support
-       * lisa: honour accepted lock, use mtime not ctime, add override type_id
-       * madison: don't say "dep-retry"
-       * melanie: bug fix in output (missing %)
-       * natalie: cope with maintainer_override == None; add type_id for overrides
-       * nina: use mtime, not ctime
-
-       * katie.py: propogation bug fixes
-       * logging.py: add debugging support, use | as the logfile separator
-
-       * katie.conf: updated signing key (4F368D5D)
-       * katie.conf: changed lockfile to dinstall.lock
-       * katie.conf: added Lisa::AcceptedLockFile, Dir::Lock
-       * katie.conf: added tiffani, cindy support
-       * katie.conf: updated to match 3.0r6 release
-       * katie.conf: updated to match sarge's release
-
-       * apt.conf: update for sarge's release
-       * apt.conf.stable: update for sarge's release
-       * apt.conf: bump daily max Contents change to 25MB from 12MB
-
-       * cron.daily: add accepted lock and invoke cindy
-       * cron.daily: add daily.lock
-       * cron.daily: invoke tiffani
-       * cron.daily: rebuild accepted buildd stuff
-       * cron.daily: save rene-daily output on the web site
-       * cron.daily: disable billie
-       * cron.daily: add stats pr0n
-
-       * cron.hourly: invoke helena
-
-       * pseudo-packages.maintainers,.descriptions: miscellaneous updates
-       * vars: add lockdir, add etch to copyoverrides
-       * Makefile: add -Ipostgresql/server to CXXFLAGS
-
-       * docs/: added README.quotes
-       * docs/: added manpages for alicia, catherine, charisma, cindy, heidi,
-       julia, katie, kelly, lisa, madison, melanie, natalie, rhona.
-
-       * TODO: correct spelling of "conflicts"
-
-2005-05-28  James Troup  <james@nocrew.org>
-
-       * helena (process_changes_files): use MTIME rather than CTIME (the
-       C's not for 'creation', stupid).
-       * lisa (sort_changes): likewise.
-
-       * jennifer (check_distributions): use has_key rather than an 'in'
-       test which doesn't work with python2.1.  [Probably by AJ]
-
-2005-03-19  James Troup  <james@nocrew.org>
-
-       * rene (main): use Suite::<suite>::UdebComponents to determine
-       what components have udebs rather than assuming only 'main' does.
-
-2005-03-18  James Troup  <james@nocrew.org>
-
-       * utils.py (rfc2047_encode): use codecs.lookup() rather than
-       encodings.<encoding>.Codec().decode() as encodings.utf_8 no longer
-       has a Codec() module in python2.4.  Thanks to Andrew Bennetts
-       <andrew@ubuntu.com>.
-
-2005-03-06  Joerg Jaspert  <ganneff@debian.org>
-
-       * helena: add -n/--new HTML output option and improved sorting
-       options.
-
-2005-03-06  Ryan Murray  <rmurray@debian.org>
-
-       * shania(main): use Cnf::Dir::Reject instead of REJECT
-
-2005-02-08  James Troup  <james@nocrew.org>
-
-       * rene (main): add partial NBS support by checking that binary
-       packages are built by their real parent and not some random
-       stranger.
-       (do_partial_nbs): likewise.
-
-2005-01-18  James Troup  <james@nocrew.org>
-
-       * katie.py (Katie.build_summaries): avoid leaking file handle when
-       extracting package description.
-       (Katie.force_reject): remember and close each file descriptor we
-       use.
-       (Katie.do_reject): s/file/temp_fh/ to avoid pychecker warning.
-       s/reason_file/reason_fd/ because it's a file descriptor.
-       (Katie.check_dsc_against_db): avoid leaking file handle whenever
-       invoking apt_pkg.md5sum().
-
-       * jennifer (check_deb_ar): new function: sanity check the ar
-       contents of a .deb.
-       (check_files): use it.
-       (check_timestamps): check for data.tar.bz2 if data.tar.gz can't be
-       found.
-       (check_files): accept 'raw-installer' as an alias for 'byhand'.
-
-2005-01-14  Anthony Towns  <ajt@debian.org>
-
-       * kelly: when UNACCEPTing, don't double up the "Rejecting:"
-
-       * propup stuff (thanks to Andreas Barth)
-       * katie.conf: add stable MustBeOlderThan testing, add -security
-         propup
-       * jennifer: set distribution-version in .katie if propup may be needed
-       * katie.py: add propogation to cross_suite_version_check
-
-2004-11-27  James Troup  <james@nocrew.org>
-
-       * nina: new script to split monolithic queue/done into date-based
-       hierarchy.
-
-       * rene (usage): document -s/--suite.
-       (add_nbs): use .setdefault().
-       (do_anais): likewise.
-       (do_nbs): don't set a string to "" and then += it.
-       (do_obsolete_source): new function - looks for obsolete source
-       packages (i.e source packages whose binary packages are ALL a)
-       claimed by someone else and b) newer when built from the other
-       source package).
-       (main): support -s/--suite.  Add 'obsolete source' to both 'daily'
-       and 'full' check modes.  Check for obsolete source packages.
-       linux-wlan-ng has been fixed - remove hideous bodge.
-
-       * jennifer (check_distributions): support 'reject' suite map type.
-
-       * utils.py (validate_changes_file_arg): s/file/filename/.
-       s/fatal/require_changes/.  If require_changes is -1, ignore errors
-       and return the .changes filename regardless.
-       (re_no_epoch): s/\*/+/ as there must be a digit in an epoch.
-       (re_no_revision): don't escape '-', it's not a special character.
-       s/\*/+/ as there must be at least one non-dash character after the
-       dash in a revision.  Thanks to Christian Reis for noticing both of
-       these.
-
-       * ashley (main): pass require_changes=-1 to
-       utils.validate_changes_file_arg().
-
-       * pseudo-packages.maintainers (kernel): switch to 'Debian Kernel
-       Team <debian-kernel@lists.debian.org>'.
-
-       * katie.py (Katie.in_override_p): fix .startswith() usage.
-
-       * katie.conf (Dinstall::DefaultSuite): add as 'unstable'.
-       (Lauren::MoreInfoURL): update to 3.0r3.
-       (Suite::Stable::Version): likewise.
-       (Suite::Stable::Description): likewise.
-
-       * cron.daily: disable automatic task override generation.
-
-       * cindy (process): restrict "find all packages" queries by
-       component.  Respect Options["No-Action"].
-       (main): add -n/--no-action support.  Only run on unstable.  Rename
-       type to otype (pychecker).
-
-2004-11-27  Daniel Silverstone  <dsilvers@digital-scurf.org>
-
-       * katie.conf (Billie::BasicTrees): add all architectures.
-       (Billie::CombinationTrees): remove 'welovehp' and 'embedded', add
-       'everything'.
-
-       * cron.daily: Update a 'current' symlink when creating the
-       post-daily-cron-job database backup to aid mirroring to merkel.
-       Run billie.
-
-       * billie (BillieTarget.poolish_match): handle .udeb too.
-
-2004-10-13  Ryan Murray  <rmurray@debian.org>
-
-       * amber (do_upload): Sort changes files in "katie" order so that
-         source always arrives before binary-only rebuilds
-
-2004-10-05  James Troup  <james@nocrew.org>
-
-       * jennifer (check_dsc): correct reject message on invalid
-       Maintainer field.
-
-2004-09-20  James Troup  <james@nocrew.org>
-
-       * alicia: remove unused 'pwd' import.
-
-       * tea (check_override): underline suite name in output properly.
-
-       * rene (main): read a compressed Packages file.
-       * tea (validate_packages): likewise.
-
-       * katie.py (re_fdnic): add 'r' prefix.
-       (re_bin_only_nmu_of_mu): likewise.
-       (re_bin_only_nmu_of_nmu): likewise.
-
-       * madison (main): retrieve component information too and display
-       it if it's not 'main'.
-       * melanie (reverse_depends_check): likewise.
-
-       * utils.py (pp_dep): renamed...
-       (pp_deps): ... to this.
-       * jeri (check_dep): update calls to utils.pp_deps().
-       * melanie (reverse_depends_check): likewise.
-
-       * jennifer (check_changes): move initalization of email variables
-       from here...
-       (process_it): ...to here as we no longer always run
-       check_changes().  Don't bother to initialize
-       changes["architecture"].
-
-       * denise (list): renamed to...
-       (do_list): ...this to avoid name clash with builtin 'list'.
-       Similarly, s/file/output_file/, s/type/otype/.  Use .setdefault()
-       for dictionaries.
-       (main): Likewise for name clash avoidance and also
-       s/override_type/suffix/.  Adjust call to do_list().
-
-2004-09-01  Ryan Murray  <rmurray@debian.org>
-
-       * tea (check_files): check the pool/ directory instead of dists/
-
-2004-08-04  James Troup  <james@nocrew.org>
-
-       * jenna (cleanup): use .setdefault() for dictionaries.
-       (write_filelists): likewise.
-
-       (write_filelists): Use utils.split_args() not split() to split
-       command line arguments.
-       (stable_dislocation_p): likewise.
-
-       (write_filelists): Add support for mapping side of suite-based
-       "Arch: all mapping".
-       (do_da_do_da): ensure that if we're not doing all suites that we
-       process enough to be able correct map arch: all packages.
-
-       * utils.py (cant_open_exc): correct exception string,
-       s/read/open/, s/.$//.
-
-       * templates/amber.advisory: update to match reality a little
-       better.
-
-       * melanie (reverse_depends_check): read Packages.gz rather than
-       Packages.
-
-       * jennifer (check_files): check for unknown component before
-       checking for NEWness.
-
-       * katie.py (Katie.in_override_p): use .startswith in favour of a
-       slice.
-
-       * docs/melanie.1.sgml: document -R/--rdep-check.
-
-2004-07-12  Daniel Silverstone  <dsilvers@digital-scurf.org>
-
-       * billie (main): Make the verbatim lists include all the README
-         elements.
-       * docs/README.names: Add billie in (correcting oversight)
-
-2004-07-01  James Troup  <james@nocrew.org>
-
-       * emilie (main): handle woody's case-sensitive python-ldap,
-       s/keyfingerprint/keyFingerPrint/.
-
-2004-06-25  James Troup  <james@nocrew.org>
-
-       * debian/control (Depends): add dpkg-dev since jennifer uses
-       dpkg-source.
-
-2004-06-24  James Troup  <james@nocrew.org>
-
-       * melanie (main): s/file/temp_file/ and close file handle before
-       removing the temporary file.
-       (main): don't warn about needing a --carbon-copy if in no-action
-       mode.
-
-       * rene (do_nbs): pcmcia-cs has been fixed - remove hideous bodge.
-       (main): likewise.
-
-       * test/006/test.py (main): check bracketed email-only form.
-
-       * utils.py (fix_maintainer): if the Maintainer string is bracketed
-       email-only, strip the brackets so we don't end up with
-       <<james@nocrew.org>>.
-
-2004-06-20  James Troup  <james@nocrew.org>
-
-       * jennifer (process_it): only run check_changes() if
-       check_signature() returns something.  (Likewise)
-
-       * utils.py (changes_compare): if there's no changes["version"] use
-       "0" rather than None.  (Avoids a crash on unsigned changes file.)
-
-2004-06-17  Martin Michlmayr  <tbm@cyrius.com>
-
-       * jeri (pp_dep): moved from here to ...
-       * utils.py (pp_dep): here.
-
-       * melanie (main): add reverse dependency checking.
-
-2004-06-17  James Troup  <james@nocrew.org>
-
-       * jennifer (check_dsc): s/dsc_whitespace_rules/signing_rules/.
-       * tea (check_dscs): likewise.
-
-       * utils.py (parse_changes): s/dsc_whitespace_rules/signing_rules/,
-       change from boolean to a variable with 3 possible values, 0 and 1
-       as before, -1 means don't require a signature.  Makes
-       parse_changes() useful for parsing arbitary RFC822-style files,
-       e.g. 'Release' files.
-       (check_signature): add support for detached signatures by passing
-       the files the signature is for as an optional third argument.
-       s/filename/sig_filename/g.  Add a fourth optional argument to
-       choose the keyring(s) to use.  Don't os.path.basename() the
-       sig_filename before checking it for taint.
-       (re_taint_free): allow '/'.
-
-2004-06-11  James Troup  <james@nocrew.org>
-
-       * tea (check_files): make override.unreadable optional.
-       (validate_sources): close the Sources file handle.
-
-       * docs/README.first: clarify that 'alyson' and running
-       add_constraints.sql by hand is something you only want to do if
-       you're not running 'neve'.
-
-       * docs/README.config (Location::$LOCATION::Suites): document.
-
-       * db_access.py (do_query): also print out the result of the query.
-
-2004-06-10  James Troup  <james@nocrew.org>
-
-       * katie.py (Katie.cross_suite_version_check): post-woody versions
-       of python-apt's apt_pkg.VersionCompare() function apparently
-       returns variable integers for less than or greater than results -
-       update our result checking to match.
-       * jenna (resolve_arch_all_vs_any): likewise.
-       * charisma (main): likewise.
-
-2004-06-09  James Troup  <james@nocrew.org>
-
-       * jennifer (process_it): s/changes_valid/valid_changes_p/.  Add
-       valid_dsc_p and don't run check_source() if check_dsc() failed.
-       (check_dsc): on fatal failures return 0 so check_source() isn't
-       run (since it makes fatal assumptions about the presence of
-       mandatory .dsc fields).
-       Remove unused and obsolete re_bad_diff and re_is_changes regexps.
-
-2004-05-07  James Troup  <james@nocrew.org>
-
-       * katie.conf (Rhona::OverrideFilename): unused and obsolete, remove.
-       * katie.conf-non-US (Rhona::OverrideFilename): likewise.
-
-       * katie.conf (Dir::Override): remove duplicate definition.
-
-       * neve (get_or_set_files_id): add an always-NULL last_used column
-       to output.
-
-2004-04-27  James Troup  <james@nocrew.org>
-
-       * apt.conf-security (tree "dists/stable/updates"): add
-       ExtraOverride - noticed by Joey Hess (#246050).
-       (tree "dists/testing/updates"): likewise.
-
-2004-04-20  James Troup  <james@nocrew.org>
-
-       * jennifer (check_files): check for existing .changes or .katie
-       files of the same name in the Suite::<suite>::Copy{Changes,Katie}
-       directories.
-
-2004-04-19  James Troup  <james@nocrew.org>
-
-       * jennifer (check_source): handle failure to remove the temporary
-        directory (used for source tree extraction) better, specifically:
-        if we fail with -EACCES, chmod -R u+rwx the temporary directory
-        and try again and if that works, REJECT the package.
-
-2004-04-17  James Troup  <james@nocrew.org>
-
-       * docs/madison.1.sgml: document -b/--binary-type,
-       -g/--greaterorequal and -G/--greaterthan.
-
-       * madison (usage): -b/--binary-type only takes a single argument.
-       Document -g/--greaterorequal and -G/--greaterthan.
-       (main): add support for -g/--greaterorequal and -G/--greaterthan.
-
-2004-04-12  Daniel Silverstone  <dsilvers@digital-scurf.org>
-
-       * billie: Cleaned up a load of comments, added /README.non-US to
-         the verbatim matches list.
-
-2004-04-07  Daniel Silverstone  <dsilvers@digital-scurf.org>
-
-       * utils.py (size_type): Make it use real binary megabytes and
-         kilobytes, instead of the marketing terms used before.
-
-2004-04-07  James Troup  <james@nocrew.org>
-
-       * katie.py (Katie.check_dsc_against_db): in the case we're
-       ignoring an identical-to-existing orig.tar.gz remember the path to
-       the existent version in pkg.orig_tar_gz.  Adjust query to grab
-       location.path too to be able to do so.
-
-2004-04-03  James Troup  <james@nocrew.org>
-
-       * debian/control (Depends): add python2.1-email | python (>= 2.2)
-       needed for new utils.rfc2047_encode() function.
-
-       * utils.py (re_parse_maintainer): allow whitespace inside the
-       email address.
-       (Error): new exception base class.
-       (ParseMaintError): new exception class.
-       (force_to_utf8): new function.
-       (rfc2047_encode): likewise.
-       (fix_maintainer): rework.  use force_to_utf8() to force name and
-       rfc822 return values to always use UTF-8.  use rfc2047_encode() to
-       return an rfc2047 value.  Validate the address to catch missing
-       email addresses and (some) broken ones.
-
-       * katie.py (nmu_p.is_an_nmu): adapt for new utils.fix_maintainer()
-       by adopting foo2047 return value.
-       (Katie.dump_vars): add changedby2047 and maintainer2047 as
-       mandatory changes fields.  Promote changes and maintainer822 to
-       mandatory fields.
-       (Katie.update_subst): default maintainer2047 rather than
-       maintainer822.  User foo2047 rather than foo822 when setting
-       __MAINTAINER_TO__ or __MAINTAINER_FROM__.
-
-       * jennifer (check_changes): set default changes["maintainer2047"]
-       and changes["changedby2047"] values rather than their 822
-       equivalents.  Makes changes["changes"] a mandatory field.  Adapt
-       to new utils.fix_maintainer() - reject on exception and adopt
-       foo2047 return value.
-       (check_dsc): if a mandatory field is missing don't do any further
-       checks and as a result reduce paranoia about dsc[var] existence.
-       Validate the maintainer field by calling new
-       utils.fix_maintainer().
-
-       * ashley (main): add changedby2047 and maintainer2047 to mandatory
-       changes fields.  Promote maintainer822 to a mandatory changes
-       field.  add "pool name" to files fields.
-
-       * test/006/test.py: new file - tests for new
-       utils.fix_maintainer().
-
-2004-04-01  James Troup  <james@nocrew.org>
-
-       * templates/lisa.prod (To): use __MAINTAINER_TO__ not __MAINTAINER__.
-
-       * jennifer (get_changelog_versions): create a symlink mirror of
-       the source files in the temporary directory.
-       (check_source): if check_dsc_against_db() couldn't find the
-       orig.tar.gz bail out.
-
-       * katie.py (Katie.check_dsc_against_db): if the orig.tar.gz is not
-       part of the upload store the path to it in pkg.orig_tar_gz and if
-       it can't be found set pkg.orig_tar_gz to -1.
-
-       Explicitly return the second value as None in the (usual) case
-       where we don't have to reprocess.  Remove obsolete diagnostic
-       logs.
-
-       * lisa (prod_maintainer): don't return anything, no one cares. (pychecker)
-
-       * utils.py (temp_filename): new helper function that wraps around
-       tempfile.mktemp().
-
-       * katie.py (Katie.do_reject): use it and don't import tempfile.
-       * lisa (prod_maintainer): likewise.
-       (edit_note): likewise.
-       (edit_new): likewise.
-       * lauren (reject): likewise.
-       * melanie (main): likewise.
-       * neve (do_sources): likewise.
-       * rene (main): likewise.
-       * tea (validate_sources): likewise.
-
-2004-03-31  James Troup  <james@nocrew.org>
-
-       * tea (validate_sources): remove unused 's' temporary variable.
-
-2004-03-15  James Troup  <james@nocrew.org>
-
-       * jennifer (check_dsc): check changes["architecture"] for
-       source before we do anything else.
-
-2004-03-21  Daniel Silverstone  <dsilvers@digital-scurf.org>
-
-       * billie: Added
-       * katie.conf (Billie): Added sample Billie stanza to katie.conf
-
-2004-03-12  James Troup  <james@nocrew.org>
-
-       * docs/README.config (Dir::Queue::BTSVersionTrack): document.
-
-       * katie.conf (Dir::Queue::BTSVersionTrack): define.
-
-       * katie.py (Katie.accept): add support for DebBugs Version
-       Tracking by writing out .versions (generated in jennifer's
-       get_changelog_versions()) and .debinfo (mapping of binary ->
-       source) files.
-
-       * ashley (main): add dsc["bts changelog"].
-
-       * katie.py (Katie.dump_vars): store dsc["bts changelog"] too.
-
-       * jennifer (check_diff): obsoleted by check_source(), removed.
-       (check_source): new function: create a temporary directory and
-       move into it and call get_changelog_versions().
-       (get_changelog_versions): new function: extract the source package
-       and optionally parse debian/changelog to obtain the version
-       history for the BTS.
-       (process_it): call check_source() rather than check_diff().
-
-2004-03-08  James Troup  <james@nocrew.org>
-
-       * lisa (edit_index): Fix logic swapo from 'use "if varfoo in
-       listbar" rather than "if listbar.count(varfoo)"' change on
-       2004-02-24.
-
-2004-03-05  James Troup  <james@nocrew.org>
-
-       * alicia (main): don't warn about not closing bugs - we don't
-       manage overrides through the BTS.
-
-2004-02-27  Martin Michlmayr  <tbm@cyrius.com>
-
-       * docs/README.config: lots of updates and corrections.
-       * docs/README.first: likewise.
-
-       * docs/README.config: drop unused Dir::Queue::Root.
-       * katie.conf-non-US: likewise.
-       * katie.conf: likewise.
-       * katie.conf-security: likewise.
-
-2004-02-27  James Troup  <james@nocrew.org>
-
-       * rose (process_tree): use 'if var in [ list ]' rather than long
-       'if var == foo or var == bar or var == baz'.  Suggested by Martin
-       Michlmayr.
-
-       * jennifer (check_files): reduce 'if var != None' to 'if var' as
-       suggested by Martin Michlmayr.
-       * catherine (poolize): likewise.
-       * charisma (main): likewise.
-       * halle (check_changes): likewise.
-       * heidi (main): likewise.
-       (process_file): likewise.
-       * kelly (install): likewise.
-       (stable_install): likewise.
-       * utils.py (fix_maintainer): likewise.
-
-       * apt.conf: add support for debian-installer in testing-proposed-updates.
-       * katie.conf (Suite::Testing-Proposed-Updates::UdebComponents):
-       add - set to main.
-
-       * mkmaintainers: add "-T15" option to wget of non-US packages file
-       so that we don't hang cron.daily if non-US is down.
-
-       * templates/lisa.prod (Subject): Prefix with "Comments regarding".
-
-       * templates/jennifer.bug-close: add Source and Source-Version
-       pseudo-headers that may be used for BTS Version Tracking someday
-       [ajt@].
-
-       * rene (do_nbs): special case linux-wlan-ng like we do for pcmcia.
-       (main): likewise.
-
-       * cron.unchecked: it's /org/ftp.debian.org not ftp-master.
-
-2004-02-25  James Troup  <james@nocrew.org>
-
-       * katie.conf (SuiteMappings): don't map testing-security to
-       proposed-updates.
-
-2004-02-24  James Troup  <james@nocrew.org>
-
-       * katie.py (Katie.__init__): remove unused 'values' field.
-
-       * utils.py (extract_component_from_section): use 's.find(c) != -1'
-       rather than 's.count(c) > 0'.
-
-       * katie.py (Katie.source_exists): use "if varfoo in listbar"
-       rather than "if listbar.count(varfoo)".
-       * halle (check_joey): likewise.
-       * jeri (check_joey): likewise.
-       * lisa (edit_index): likewise.
-       * jenna (stable_dislocation_p): likewise.
-
-       * jennifer (main): remove unused global 'nmu'.
-
-2004-02-03  Daniel Silverstone  <dsilvers@digital-scurf.org>
-
-       * pseudo-packages.maintainers (ftp.debian.org): Changed the maintainer
-         to be ftpmaster@ftp-master.debian.org to bring it into line with how
-         the dak tools close bugs.
-
-2004-02-02  Daniel Silverstone  <dsilvers@digital-scurf.org>
-
-       * katie.conf (Alicia): Added an Alicia section with email address
-       * templates/alicia.bug-close: Added
-       * docs/alicia.1.sgml: Added the docs for the -d/--done argument
-       * alicia (main): Added a -d/--done argument
-
-2004-02-02  Daniel Silverstone  <dsilvers@digital-scurf.org>
-
-       * templates/lisa.prod: Oops, missed a BITCH->PROD conversion
-
-2004-01-29  Daniel Silverstone  <dsilvers@digital-scurf.org>
-
-       * lisa (prod_maintainer): Added function to prod the maintainer without
-         accepting or rejecting the package
-       * templates/lisa.prod: Added this template for the prodding mail
-
-       * .cvsignore: Added neve-files which turns up in new installations
-
-2004-01-30  Daniel Silverstone  <dsilvers@digital-scurf.org>
-
-       * alicia (usage): Fixed usage message to offer section and priority
-         as seperately optional arguments.
-       * alicia (main): Added a % (arg) interpolation needed when only
-         one of section or priority is provided and it cannot be found.
-
-2004-01-29  Daniel Silverstone  <dsilvers@digital-scurf.org>
-
-       * alicia: Added
-       * docs/alicia.1.sgml: Added
-       * docs/Makefile: Added alicia to the list of manpages to build
-       * docs/README.names: Noted what alicia does
-       * docs/README.first: Noted where alicia is useful
-
-2004-01-21  James Troup  <james@nocrew.org>
-
-       * madison (main): add -b/--binary-type.
-       (usage): likewise.
-
-       * denise (main): generate debian-installer overrides for testing
-       too.
-       * apt.conf: add support for debian-installer in testing.
-       * katie.conf (Suite::Testing::UdebComponents): set to main.
-
-       * katie.conf (Dinstall::SigningKeyIds): 2004 key.
-       * katie.conf-non-US (Dinstall::SigningKeyIds): likewise.
-       * katie.conf-security (Dinstall::SigningKeyIds): likewise.
-
-       * utils.py (parse_changes): don't process data not inside the
-       signed data.  Thanks to Andrew Suffield <asuffield@debian.org> for
-       pointing this out.
-       * test/005/test.py (main): new test to test for above.
-
-2004-01-04  James Troup  <james@nocrew.org>
-
-       * jenna (write_filelists): correct typo, s/Components/Component/
-       for Options.
-
-2004-01-04  Ryan Murray  <rmurray@debian.org>
-
-       * cron.buildd: move update of overrides and Packages file...
-       * cron.unchecked: to here.
-       * katie.conf-non-US: (Dinstall::SingingKeyIds) update for 2003v2 key
-       * katie.conf-security: likewise
-
-2003-11-20  James Troup  <james@nocrew.org>
-
-       * jenna (main): don't use utils.try_with_debug(), it produces way
-       too much output.
-
-       * halle (check_changes): don't error out if a .changes refers to a
-       non-existent package, just warn and skip the file.
-
-       * docs/README.stable-point-release: mention halle and .changes
-       obsoleted by removal through melanie.  Update for 3.0r2.
-
-       * katie.conf (Suite::Stable::Version): bump to 3.0r2.
-       (Suite::Stable::Description): update for 3.0r2.
-       (Lauren::MoreInfoURL): likewise.
-       * katie.conf-non-US (Suite::Stable::Version): likewise.
-       (Suite::Stable::Description): likewise.
-       (Lauren::MoreInfoURL): likewise.
-
-       * apt.conf.stable (Default): don't define MaxContentsChange.
-       * apt.conf.stable-non-US (Default): likewise.
-
-       * lauren (reject): hack to work around partial replacement of an
-       upload, i.e. one or more binaries superseded by another source
-       package.
-
-2003-11-17  James Troup  <james@nocrew.org>
-
-       * pseudo-packages.maintainers: point installation-reports at
-       debian-boot@l.d.o rather than debian-testing@l.d.o at jello@d.o's
-       request.
-
-       * utils.py (parse_changes): calculate the number of lines once
-       with len() rather than max().
-
-       * jennifer (check_dsc): handle the .orig.tar.gz disappearing from
-       files, since check_dsc_against_db() deletes the .orig.tar.gz
-       entry.
-
-2003-11-13  Ryan Murray  <rmurray@debian.org>
-
-       * apt.conf: specify a src override file for debian-installer
-
-2003-11-10  James Troup  <james@nocrew.org>
-
-       * fernanda.py (strip_pgp_signature): new function - strips PGP
-       signature from a file and returns the modified contents of the
-       file in a string.
-       (display_changes): use it.
-       (read_dsc): likewise.
-
-2003-11-09  Ryan Murray  <rmurray@debian.org>
-
-       * cron.buildd: export accepted_autobuild table for unstable, and use
-       it to generate the incoming Packages/Sources rather than having apt
-       walk the directory.
-       * apt.conf.buildd: use exported table from cron.buildd to generate
-       Packages/Sources
-
-2003-11-07  James Troup  <james@nocrew.org>
-
-       * kelly: import errno.
-
-       * katie.py (Katie.build_summaries): sort override disparities.
-
-       * kelly (install): set dsc_component based on the .dsc's component
-       not a random binaries.
-
-2003-10-29  James Troup  <james@nocrew.org>
-
-       * katie.py (Katie.build_summaries): don't assume changes["source"]
-       exists since it might not.
-
-2003-10-20  James Troup  <james@nocrew.org>
-
-       * pseudo-packages.maintainers: update security.d.o to use
-       team@s.d.o at joy@'s request.
-
-2003-10-17  James Troup  <james@nocrew.org>
-
-       * jennifer (check_dsc): use .startswith rather than .find() == 0.
-
-2003-10-17  Martin Michlmayr  <tbm@cyrius.com>
-
-       * tea (chk_bd_process_dir): use .endswith rather than slice.
-
-2003-10-14  James Troup  <james@nocrew.org>
-
-       * tea (check_build_depends): new function.
-       (chk_bd_process_dir): likewise.  Validates build-depends in .dsc's
-       in the archive.
-       (main): update for new function.
-       (usage): likewise.
-
-       * katie.py (Katie.do_reject): sanitize variable names,
-       s/reject_filename/reason_filename/, s/fd/reason_fd/.  Move shared
-       os.close() to outside if clause.
-
-       * jennifer (check_dsc): check build-depends and
-       build-depends-indep by running them past apt_pkg.ParseSrcDepends.
-       Fold the ARRAY check into the same code block and tidy up it's
-       rejection message.
-       (check_changes): ensure that the Files field is non-empty.
-       Suggested by Santiago Vila <sanvila@unex.es>
-       (check_changes): normalize reject messages.
-       (check_dsc): instead of doing most of the checks inside a for loop
-       and an if, find the dsc_filename in a short loop over files first
-       and then do all the checks.  Add check for more than one .dsc in a
-       .changes which we can't handle.  Normalize reject messages.
-
-2003-10-13  James Troup  <james@nocrew.org>
-
-       * katie.conf (Dinstall::Reject::NoSourceOnly): set to true.
-       * katie.conf-non-US (Dinstall::Reject::NoSourceOnly): likewise.
-
-       * jennifer (check_files): Set 'has_binaries' and 'has_source'
-       variables while iterating over 'files'.  Don't regenerate it when
-       checking for source if source is mentioned.
-
-       Reject source only uploads if the config variable
-       Dinstall::Reject::NoSourceOnly is set.
-
-2003-10-03  James Troup  <james@nocrew.org>
-
-       * rene (main): add nasty hardcoded reference to debian-installer
-       so we detect NBS .udebs.
-
-2003-09-29  James Troup  <james@nocrew.org>
-
-       * apt.conf (old-proposed-updates): remove.
-       * apt.conf-non-US (old-proposed-updates): likewise.
-
-2003-09-24  James Troup  <james@nocrew.org>
-
-       * tea (check_files_not_symlinks): new function, ensure files
-       mentioned in the database aren't symlinks.  Includes code to
-       update any files that are like this to their real filenames +
-       location; commented out by though.
-       (usage): update for new function.
-       (main): likewise.
-
-2003-09-24  Anthony Towns  <ajt@debian.org>
-
-       * vars: external-overrides variable added
-       * cron.daily: Update testing/unstable Task: overrides from joeyh
-       managed external source.
-
-2003-09-22  James Troup  <james@nocrew.org>
-
-       * kelly (install): if we can't move the .changes into queue/done,
-       fail don't warn and carry on.  The old behaviour pre-dates NI and
-       doesn't make much sense now since jennifer checks both
-       queue/accepted and queue/done for any .changes files it's
-       processing.
-
-       * utils.py (move): don't throw exceptions on existing files or
-       can't overwrite, instead just fubar out.
-
-       * jennifer (check_dsc): also check Build-Depends-Indep for
-       ARRAY-lossage.  Noticed by Matt Zimmerman <mdz@debian.org>.
-
-2003-09-18  James Troup  <james@nocrew.org>
-
-       * katie.py (Katie.close_bugs): only log the bugs we've closed
-       once.
-
-       * kelly (main): log as 'kelly', not 'katie'.
-
-2003-09-16  James Troup  <james@nocrew.org>
-
-       * katie.py (Katie.check_binary_against_db): likewise noramlize.
-
-       * jennifer (check_changes): normalize reject message for "changes
-       file already exists" to be %s: <foo>.
-       (check_dsc): add a check for 'Build-Depends: ARRAY(<hex>)'
-       produced by broken dpkg-source in 1.10.11.  Tone down and
-       normalize rejection message for incompatible 'Format' version
-       numbers.
-       (check_diff): likewise tone down and normalize.
-
-2003-09-07  James Troup  <james@nocrew.org>
-
-       * utils.py (parse_changes): if dsc_whitespace_rules is false,
-       don't bomb out on bogus empty lines.
-       (build_file_list): check for changes["files"] earlier.  use Dict
-       to create files[name] dictionary.
-       (send_mail): don't bother validating arguments.
-       (check_signature): minor improvements to some of the rejection
-       messages including listing the key id of the key that wasn't found
-       in the keyring.
-       (wrap): new function.
-
-       * tea: add new check 'validate-indices' that ensures all files
-       mentioned in indices (Packages, Sources) files do in fact exist.
-
-       * catherine (poolize): use a local re_isadeb which handles legacy
-       (i.e. no architecture) style .deb filenames.
-
-       * rosamund: new script.
-
-       * rhona (check_binaries): when checking for binary packages not in
-       a suite, don't bother selecting files that already have a
-       last_used date.
-       (check_sources): likewise.
-
-       * rhona: change all SQL EXISTS sub-query clauses to use the
-       postgres suggested convention of "SELECT 1 FROM".
-       * andrea (main): likewise.
-       * tea (check_override): likewise.
-       * catherine (main): likewise.
-
-       * katie.conf (Suite): remove OldStable and Old-Proposed-Updates
-       entries and in other suites MustBeNewerThan's.
-       (SuiteMappings): likewise
-       * katie.conf-non-US: likewise.
-       * katie.conf-security: likewise.
-
-       * apt.conf-security: remove oldstable.
-       * apt.conf.stable: likewise.
-       * apt.conf.stable-non-US: likewise.
-       * cron.buildd-security: likewise.
-       * cron.daily-security: likewise.
-       * vars-security (suites): likewise.
-       * wanna-build/trigger.daily: likewise.
-
-       * claire.py (clean_symlink): move...
-       * utils.py (clean_symlink): here.
-
-       * claire.py (find_dislocated_stable): update accordingly.
-
-2003-08-16  Anthony Towns  <ajt@debian.org>
-
-       * katie.py (source_exists): expand the list of distributions
-       the source may exist in to include any suite that's mapped to
-       the destination suite (even transitively (a->b->c)). This should
-       unbreak binary uploads to *-proposed-updates.
-
-2003-08-09  Randall Donald  <rdonald@debian.org>
-
-       * lisa (recheck): change changes["distribution"].keys() to
-       Katie.pkg.changes...
-
-2003-08-08  Randall Donald  <rdonald@debian.org>
-
-       * katie.py: only tag bugs as fixed-in-experimental for
-       experimental uploads
-
-2003-07-26  Anthony Towns  <ajt@debian.org>
-
-       * katie.py (source_exists): add an extra parameter to limit the
-       distribution(s) the source must exist in.
-       * kelly, lisa, jennifer: update to use the new source_exists
-
-2003-07-15  Anthony Towns  <ajt@debian.org>
-
-       * ziyi: quick hack to support a FakeDI line in apt.conf to generate
-       checksums for debian-installer stuff even when it's just a symlink to
-       another suite
-
-       * apt.conf: add the FakeDI line
-
-2003-06-09  James Troup  <james@nocrew.org>
-
-       * kelly (check): make sure the 'file' we're looking for in 'files'
-       hasn't been deleted by katie.check_dsc_against_db().
-
-2003-05-07  James Troup  <james@nocrew.org>
-
-       * helena (time_pp): fix s/years/year/ typo.
-
-2003-04-29  James Troup  <james@nocrew.org>
-
-       * madison (usage): document -c/--component.
-
-       * madison (usage): Fix s/seperated/separated/.
-       * melanie (usage): likewise.
-       * jenna (usage): likewise.
-
-2003-04-24  James Troup  <james@nocrew.org>
-
-       * cron.daily-non-US: if there's nothing for kelly to install, say
-       so.
-
-       * jennifer (check_timestamps): print sys.exc_value as well as
-       sys.exc_type when capturing exceptions.  Prefix 'timestamp check
-       failed' with 'deb contents' to make it clearer what timestamp(s)
-       are being checked.
-
-2003-04-15  James Troup  <james@nocrew.org>
-
-       * cron.daily-non-US: only run kelly if there are some .changes
-       files in accepted.
-
-       * rene: add -m/--mode argument which can be either daily (default)
-       or full.  In daily mode only 'nviu' and 'nbs' checks are run.
-       Various changes to make this possible including a poor attempt at
-       splitting main() up a little.  De-hardcode suite numbers from SQL
-       queries and return quietly from do_nviu() if experimental doesn't
-       exist (i.e. non-US).  Hardcode pcmcia-cs as dubious NBS since it
-       is.
-
-       * debian/control (Depends): remove python-zlib as it's obsolete.
-
-       * charisma (main): don't slice the \n off strings when we're
-       strip()-ing it anyway.
-       * heidi (set_suite): likewise.
-       (process_file): likewise.
-       * natalie (process_file): likewise.
-
-2003-04-08  James Troup  <james@nocrew.org>
-
-       * katie.py (Katie.check_dsc_against_db): improve the speed of two
-       slow queries by using one LIKE '%foo%' and then matching against
-       '%s' or '/%s$' in python.  Also only join location when we need it
-       (i.e. the .orig.tar.gz query).  On auric, this knocks ~3s of each
-       query, so 6s for each sourceful package.
-
-       * cron.daily: invoke rene and send the report to ftpmaster.
-       * cron.daily-non-US: likewise.
-
-2003-03-14  James Troup  <james@nocrew.org>
-
-       * utils.py (send_mail): default filename to blank.
-       * amber (make_advisory): adapt.
-       * jennifer (acknowledge_new): likewise.
-       * katie.py (Katie.close_bugs): likewise.
-       (Katie.announce): likewise.
-       (Katie.accept): likewise.
-       (Katie.check_override): likewise.
-       (Katie.do_reject): likewise.
-       * kelly (do_reject): likewise.
-       (stable_install): likewise.
-       * lisa (do_bxa_notification): likewise.
-       * lauren (reject): likewise.
-       * melanie (main): likewise.
-
-       * rene (add_nbs): check any NBS packages against unstable to see
-       if they haven't been removed already.
-
-       * templates/katie.rejected: remove paragraph about rejected files
-       since they're o-rwx due to c-i-m and the uploader can't do
-       anything about them and shania will take care of them anyway.
-
-       * madison (usage): update usage example to use comma seperation.
-       * melanie (usage): likewise.
-
-       * utils.py (split_args): new function; splits command line
-       arguments either by space or comma (whichever is used).  Also has
-       optional-but-default DWIM spurious space detection to avoid
-       'command -a i386, m68k' problems.
-       (parse_args): use it.
-       * melanie (main): likewise.
-
-       * melanie (main): force the admin to tell someone if we're not
-       doing a rene-led removal (or closing a bug, which counts as
-       telling someone).
-
-2003-03-05  James Troup  <james@nocrew.org>
-
-       * katie.conf (Section): add embedded, gnome, kde, libdevel, perl
-       and python sections.
-       * katie.conf-security (Section): likewise.
-
-       * add_constraints.sql: add uid and uid_id_seq to grants.
-
-       * lisa (determine_new): also warn about adding overrides to
-       oldstable.
-
-       * madison (main): make the -S/--source-and-binary query obey
-       -s/--suite restrictions.
-
-2003-03-03  James Troup  <james@nocrew.org>
-
-       * madison (main): if the Archive_Maintenance_In_Progress lockfile
-       exists, warn the user that our output might seem strange.  (People
-       get confused by multiple versions in a suite which happens
-       post-kelly but pre-jenna.)
-
-2003-02-21  James Troup  <james@nocrew.org>
-
-       * kelly (main): we don't need to worry about StableRejector.
-
-       * melanie (main): sort versions with apt_pkg.VersionCompare()
-       prior to output.
-
-       * lauren: new script to manually reject packages from
-       proposed-updates.  Updated code from pre-NI kelly (nee katie).
-
-2003-02-20  James Troup  <james@nocrew.org>
-
-       * kelly (init): remove unused -m/--manual-reject argument.
-
-       * katie.py (Katie.force_reject): renamed from force_move to make
-       it more explicit what this function does.
-       (Katie.do_reject): update to match.
-
-       * utils.py (prefix_multi_line_string): add an optional argument
-       include_blank_lines which defaults to 0.  If non-zero, blank lines
-       will be includes in the output.
-
-       * katie.py (Katie.do_reject): don't add leading space to each line
-       of the reject message.  Include blank lines when showing the
-       message to the user.
-
-2003-02-19  Martin Michlmayr  <tbm@cyrius.com>
-
-       * utils.py (fix_maintainer): replace pointless re.sub() with
-       simple string format.
-
-2003-02-11  James Troup  <james@nocrew.org>
-
-       * lisa (edit_overrides): only strip-to-one-char and upper-case
-       non-numeric answers.  Fixes editing of items with indices >= 10;
-       noticed by Randall.
-       (edit_overrides): correct order of arguments to "not a valid
-       index" error message.
-
-       * jenna (cleanup): call resolve_arch_all_vs_any() rather than
-       remove_duplicate_versions(); thanks to aj for the initial
-       diagnosis.
-       (remove_duplicate_versions): correct how we return
-       dominant_versions.
-       (resolve_arch_all_vs_any): arch_all_versions needs to be a list of
-       a tuple rather than just a tuple.
-
-2003-02-10  James Troup  <james@nocrew.org>
-
-       * emilie: new script - sync fingerprint and uid tables with a
-       debian.org LDAP DB.
-
-       * init_pool.sql: new table 'uid'; contains user ids.  Reference it
-       in 'fingerprint'.
-
-       * db_access.py (get_or_set_uid_id): new function.
-
-       * jennifer (main): update locking to a) not used FCNTL (deprecated
-       in python >= 2.2) and b) acknowledge upstream's broken
-       implementation of lockf (see Debian bug #74777), c) try to acquire
-       the lock non-blocking.
-       * kelly (main): likewise.
-
-       * contrib/python_1.5.2-fcntl_lockf.diff: obsolete, removed.
-
-       * madison (main): only append the package to new_packages if it's
-       not already in there; fixes -S/--source-and-binary for cases where
-       the source builds a binary package of the same name.
-
-2003-02-10  Anthony Towns  <ajt@debian.org>
-
-       * madison (main): use explicit JOIN syntax for
-       -S/--source-and-binary queries to reduce the query's runtime from
-       >10 seconds to negligible.
-
-2003-02-08  James Troup  <james@nocrew.org>
-
-       * rene (main): in the NVIU output, append items to lists, not
-       extend them; fixes amusing suggestion that "g n u m e r i c" (sic)
-       should be removed.
-
-2003-02-07  James Troup  <james@nocrew.org>
-
-       * apt.conf (tree "dists/unstable"): Add bzip2-ed Packages and
-       Sources [aj].
-
-       * pseudo-packages.maintainers (bugs.debian.org): s/Darren
-       O. Benham/Adam Heath/.
-
-       * katie.conf (Suite::Stable::Version): bump to 3.0r1a.
-       (Suite::Stable::Description): update for 3.0r1a.
-       (Dinstall::SigningKeyIds): update for 2003 key [aj].
-
-       * utils.py (gpgv_get_status_output): rename from
-       get_status_output().
-
-       * neve (check_signature): use gpgv_get_status_output and Dict from
-       utils().  Add missing newline to error message about duplicate tokens.
-
-       * saffron (per_arch_space_use): also print space used by source.
-       (output_format): correct string.join() invocation.
-
-       * jennifer (check_signature): ignored duplicate EXPIRED tokens.
-
-2003-02-04  James Troup  <james@nocrew.org>
-
-       * cron.buildd: correct generation of Packages/Sources and grep out
-       non-US/non-free as well as non-free.
-
-2003-02-03  Ryan Murray  <rmurray@debian.org>
-
-       * cron.buildd: generate quinn-diff output with full Packages/Sources
-         files to get out-of-date vs. uncompiled right.
-       * apt.conf.buildd: no longer generate uncompressed files, as they
-         are generated in cron.buildd instead
-       * add -i option to quinn-diff to ignore binary-all packages
-       * apt.conf.buildd: remove and readd udeb to extensions.  If the udebs
-         aren't in the packages file, the arch that uploaded them will build
-         them anyways...
-
-2003-01-30  James Troup  <james@nocrew.org>
-
-       * rene (main): only print suggested melanie command when there's
-       some NBS to remove.
-
-2003-01-30  Ryan Murray  <rmurray@debian.org>
-
-       * cron.buildd: fix incorrectly inverted lockfile check
-
-2003-01-29  Ryan Murray  <rmurray@debian.org>
-
-       * cron.buildd: generate override.sid.all3.src
-       * apt.conf.buildd: use generated override.sid.all3.src
-
-2003-01-27  Martin Michlmayr  <tbm@cyrius.com>
-
-       * utils.py (get_status_output): moved from jennifer.
-       (Dict): likewise.
-       (check_signature): likewise.
-
-       * jennifer (get_status_output): moved to utils.py.
-       (Dict): likewise.
-       (check_signature): likewise.
-
-       * utils.py (check_signature): add an argument to specifiy which
-       function to call when an error was found.
-       (check_signature): document this function better.
-
-       * jennifer (check_files): pass the reject function as an argument
-       to utils.check_signature.
-       (process_it): likewise.
-
-2003-01-20  James Troup  <james@nocrew.org>
-
-       * rene (main): lots of changes to improve the output and make it
-       more useful.
-
-       * katie.py (Katie.check_override): make the override messages
-       clearer (hopefully).
-
-2002-12-26  James Troup  <james@nocrew.org>
-
-       * ziyi (usage): document the ability to pass suite(s) as
-       argument(s).
-       (main): read apt.conf after checking for -h/--help.
-
-       * tea (main): take the check to run as an argument.
-
-       * saffron.R: R script to graph daily install runs.
-
-       * saffron: new script; various stats functions.
-
-       * rhona (main): connect to the database after checking for -h/--help.
-
-       * neve (do_da_do_da): if no -a/--action option is given, bail out.
-
-       * melanie (main): sort versions with utils.arch_compare_sw().
-
-       * madison (usage): alphabetize order of options.
-       * melanie (usage): likewise.
-
-       * kelly (usage): fix usage short description (we aren't dinstall).
-
-       * julia (usage): fix usage description and alphabetize order of
-       options.
-
-       * jeri (usage): fix usage short description.
-
-       * jennifer (main): move --help and --version checks from here...
-       (init): to here so that they work with an empty katie.conf.
-       * kelly: likewise.
-
-       * alyson (usage): new function.
-       (main): use it.
-       * andrea: likewise.
-       * ashley: likewise.
-       * cindy: likewise.
-       * denise: likewise.
-       * helena: likewise.
-       * neve: likewise.
-       * rene: likewise.
-       * rose: likewise.
-       * tea: likewise.
-
-       * apt.conf.stable (tree "dists/stable"): add missing ExtraOverride
-       entry that caused tasks to be omitted from 3.0r1.
-
-2002-12-10  James Troup  <james@nocrew.org>
-
-       * jennifer (check_files): sanity check the Depends field to ensure
-       it's non-empty if present since apt chokes on an empty one.
-       Thanks to Ryan Murray for the idea.
-
-2002-12-08  James Troup  <james@nocrew.org>
-
-       * katie.conf-security (Helena::Directories): new; include accepted
-       in addition to byhand and new.
-
-       * helena (process_changes_files): use utils.arch_compare_sw().
-       Justify things based on the longest [package, version,
-       architecture].  Reduce '[note]' to '[N]' to save space, and remove
-       the commas in architecture and version lists for the same reason.
-       (main): make directories we process configurable through
-       Helena::Directories in the config file; if that doesn't exist
-       default to the old hardcoded values (byhand & new).
-
-       * utils.py (arch_compare_sw): moved here from madison.
-       * madison (main): adjust to compensate.
-
-2002-12-06  James Troup  <james@nocrew.org>
-
-       * ziyi (main): fix "suite foo not in apt.conf" msg to use the
-       right filename.
-
-2002-12-05  James Troup  <james@nocrew.org>
-
-       * katie.conf-non-US (Julia::KnownPostgres): add 'udmsearch'.
-
-2002-11-28  Randall Donald  <rdonald@debian.org>
-
-       * fernanda.py (read_control): fix typo of 'Architecture'.
-
-2002-11-26  James Troup  <james@nocrew.org>
-
-       * lisa (check_pkg): call less with '-R' so we see the colour from
-       Randall's fernanda changes.
-
-       * neve (process_sources): if Directory points to a legacy location
-       but the .dsc isn't there; assume it's broken and look in the pool.
-       (update_section): new, borroed from alyson.
-       (do_da_do_da): use it.
-       (process_packages): add suite_it to the cache key used for
-       arch_all_cache since otherwise we only add a package to the first
-       suite it's in and ignore any subsequent ones.
-
-       * katie.conf-non-US (Location): fixed to reflect reality (all
-       suites, except old-proposed-updates (which is legacy-mixed)) are
-       pool.
-
-       * utils.py (try_with_debug): wrapper for print_exc().
-       * jenna (main): use it.
-       * neve (main): likewise.
-
-2002-11-25  Randall Donald  <rdonald@debian.org>
-
-       * fernanda.py (main): added -R to less command line for raw control
-       character support to print colours
-       (check_deb): Instead of running dpkg -I on deb file, call
-       output_deb_info, the new colourized control reporter.
-       (check_dsc): add call to colourized dsc info reader, read_dsc, instead
-       of printing out each .dsc line.
-       (output_deb_info): new function. Outputs each key/value pair from
-       read_control except in special cases where we highlight section,
-       maintainer, architecture, depends and recommends.
-       (create_depends_string): new function. Takes Depends tree and looks
-       up it's compontent via projectb db, colourizes and constructs a
-       depends string in original order.
-       (read_dsc): new function. reads and parses .dsc info via
-       utils.parse_changes. Build-Depends and Build-Depends-Indep are
-       colourized.
-       (read_control): new function. reads and parses control info via
-       apt_pkg. Depends and Recommends are split in to list structures,
-       Section and Architecture are colourized. Maintainer is colourized
-       if it has a localhost.localdomain address.
-       (split_depends): new function. Creates a list of lists of
-       dictionaries of depends (package,version relation). Top list is
-       colected from comma delimited items. Sub lists are | delimited.
-       (get_comma_list): new function. splits string input among commas
-       (get_or_list): new function. splits string input among | delimiters
-       (get_depends_parts): new function. Creates dictionary of package name
-       and version relation from dependancy string.
-       Colours for section and depends are per component. Unfound depends
-       are in bold. Lookups using version info is not supported yet.
-
-2002-11-22  James Troup  <james@nocrew.org>
-
-       * katie.conf-security (Julia::KnownPostgres): add 'www-data' and
-       'udmsearch'.
-
-       * amber (make_advisory): string.atol() is deprecated and hasn't
-       been ported to string methods.  Use long() instead.
-
-       * init_pool.sql: explicitly specify the encoding (SQL_ASCII) when
-       creating the database since we'll fail badly if it's created with
-       e.g. UNICODE encoding.
-
-       * rose (main): AptCnf is a global.
-
-       * neve (get_location_path): new function determines the location
-       from the the first (left-most) directory of a Filename/Directory.
-       (process_sources): don't need 'location' anymore.  Use
-       utils.warn().  Use the Directory: field for each package to find
-       the .dsc.  Use get_location_path() to determine the location for
-       each .dsc.
-       (process_packages): do't need 'location' anymore.  Use
-       utils.warn().  Use get_location_path().
-       (do_sources): don't need 'location', drop 'prefix' in favour of
-       being told the full path to the Sources file, like
-       process_packages().
-       (do_da_do_da): main() renamed, so that main can call us in a
-       try/except.  Adapt for the changes in do_sources() and
-       process_packages() above.  Assume Sources and Packages file are in
-       <root>/dists/<etc.>.  Treat pool locations like we do legacy ones.
-
-       * katie.conf-security (Location): fixed to reflect reality (all
-       suites are pool, not legacy).
-
-       * utils.py (print_exc): more useful (i.e. much more verbose)
-       traceback; a recipe from the Python cookbook.
-       * jenna (main): use it.
-       * neve (main): likewise.
-
-2002-11-19  James Troup  <james@nocrew.org>
-
-       * kelly (install): fix brain-damaged CopyChanges/CopyKatie
-       handling which was FUBAR for multi-suite uploads.  Now we just
-       make a dictionary of destinations to copy to and iterate over
-       those.
-
-       * fernanda.py (check_deb): run linda as well as lintian.
-
-2002-10-21  James Troup  <james@nocrew.org>
-
-       * melanie (main): change X-Melanie to X-Katie and prefix it with
-       'melanie '.
-
-       * lisa (main): prefix X-Katie with 'lisa '.
-
-       * jennifer (clean_holding): fix typo in string method changes;
-       s/file.find(file/file.find(/.
-
-       * cron.daily: invoke helena and send the report to ftpmaster.
-       * cron.daily-non-US: likewise.
-
-2002-10-16  James Troup  <james@nocrew.org>
-
-       * kelly (check): call reject() with a blank prefix when parsing
-       the return of check_dsc_against_db() since it does its own
-       prefix-ing.
-
-       * rose: new script; only handles directory creation initally.
-
-       * katie.conf (Dinstall::NewAckList): obsolete, removed.
-       * katie.conf-non-US (Dinstall::NewAckList): likewise.
-
-2002-10-06  James Troup  <james@nocrew.org>
-
-       * rene (main): remove bogus argument handling.
-
-       * kelly: katie, renamed.
-       * cron.daily: adapt for katie being renamed to kelly.
-       * cron.daily-non-US: likewise.
-       * amber (main): likewise.
-
-       * Changes for python 2.1.
-
-       * kelly: time.strftime no longer requires a second argument of
-       "time.localtime(time.time())".
-       * logging.py: likewise.
-       * rhona: likewise.
-       * shania (init): likewise.
-
-       * amber: use augmented assignment.
-       * catherine (poolize): likewise.
-       * claire.py (fix_component_section): likewise.
-       * halle (check_changes): likewise.
-       * helena: likewise.
-       * jenna: likewise.
-       * jennifer: likewise.
-       * jeri: likewise.
-       * katie.py: likewise.
-       * kelly: likewise.
-       * lisa: likewise.
-       * madison (main): likewise.
-       * melanie: likewise.
-       * natalie: likewise.
-       * neve: likewise.
-       * rhona: likewise.
-       * tea: likewise.
-       * utils.py: likewise.
-       * ziyi: likewise.
-
-       * amber: use .endswith.
-       * fernanda.py: likewise.
-       * halle (main): likewise.
-       * jennifer: likewise.
-       * jeri: likewise.
-       * katie.py: likewise.
-       * kelly: likewise.
-       * lisa: likewise.
-       * neve: likewise.
-       * shania (main): likewise.
-       * utils.py: likewise.
-
-       * alyson: use string methods.
-       * amber: likewise.
-       * andrea: likewise.
-       * ashley: likewise.
-       * catherine: likewise.
-       * charisma: likewise.
-       * claire.py: likewise.
-       * db_access.py: likewise.
-       * denise: likewise.
-       * halle: likewise.
-       * heidi: likewise.
-       * helena: likewise.
-       * jenna: likewise.
-       * jennifer: likewise.
-       * jeri: likewise.
-       * julia: likewise.
-       * katie.py: likewise.
-       * kelly: likewise.
-       * lisa: likewise.
-       * logging.py: likewise.
-       * madison: likewise.
-       * melanie: likewise.
-       * natalie: likewise.
-       * neve: likewise.
-       * rene: likewise.
-       * tea: likewise.
-       * utils.py: likewise.
-       * ziyi: likewise.
-
-2002-09-20  Martin Michlmayr  <tbm@cyrius.com>
-
-       * utils.py (parse_changes): use <string>.startswith() rather than
-       string.find().
-
-2002-08-27  Anthony Towns  <ajt@debian.org>
-
-       * katie.py (in_override_p): when searching for a source override,
-       and the dsc query misses, search for both udeb and deb overrides
-       as well. Should fix the UNACCEPT issues with udebs.
-
-2002-08-24  James Troup  <james@nocrew.org>
-
-       * melanie (main): remove gratuitous WHERE EXISTS sub-select from
-       source+binary package finding code which was causing severe
-       performance degradation with postgres 7.2.
-
-2002-08-14  James Troup  <james@nocrew.org>
-
-       * julia (main): use the pwd.getpwall() to get system user info
-       rather than trying to read a password file.  Add a -n/--no-action
-       option.
-
-       * cron.hourly: julia no longer takes any arguments.
-       * cron.hourly-non-US: likewise.
-
-2002-08-07  James Troup  <james@nocrew.org>
-
-       * katie (install): handle multi-suite uploads when CopyChanges
-       and/or CopyKatie are in use, ensuring we only copy stuff once.
-
-2002-08-01  Ryan Murray  <rmurray@debian.org>
-
-       * wanna-build/trigger.daily: initial commit, with locking
-       * cron.buildd: add locking against daily run
-
-2002-07-30  James Troup  <james@nocrew.org>
-
-       * melanie (main): readd creation of suite_ids_list so melanie is
-       remotely useful again.
-
-       * katie.conf: adopt for woody release; diable
-       StableDislocationSupport, add oldstable, adjust other suites and
-       mappings, fix up location.
-       * katie.conf-non-US: likewise.
-       * katie.conf-security: likewise.
-
-       * apt.conf.stable: adapt for woody release; add oldstable, adjust
-       stable.
-       * apt.conf.stable-non-US: likewise.
-
-       * apt.conf-security: adapt for woody release; adding oldstable,
-       oldstable, adjust stable and testing.
-       * cron.daily-security: likewise.
-       * cron.buildd-security: likewise.
-
-       * apt.conf: adapt for woody release; rename woody-proposed-updates
-       to testing-proposed-updates and proposed-updates to
-       old-proposed-updates.
-       * apt.conf-non-US: likewise.
-
-       * vars-non-US (copyoverrides): add sarge.
-       * vars (copyoverrides): likewise.
-
-       * vars-security (suites): add oldstable.
-
-2002-07-22  Ryan Murray  <rmurray@debian.org>
-
-       * apt.conf.security-buildd: use suite codenames instead of
-         distnames.
-
-2002-07-16  James Troup  <james@nocrew.org>
-
-       * denise (main): fix filenames for testing override files.
-
-2002-07-14  James Troup  <james@nocrew.org>
-
-       * jennifer (process_it): call check_md5sums later so we can check
-       files in the .dsc too
-       (check_md5sums): check files in the .dsc too.  Check both md5sum
-       and size.
-
-       * melanie (main): use parse_args() and join_with_commas_and() from
-       utils.  If there's nothing to do, say so and exit, don't ask for
-       confirmation etc.
-
-       * amber (join_with_commas_and): moved from here to ...
-       * utils.py (join_with_commas_and): here.
-
-2002-07-13  James Troup  <james@nocrew.org>
-
-       * madison (main): use parse_args() from utils.  Support
-       -c/--component.
-
-       * jenna (parse_args): moved from here to ...
-       * utils.py (parse_args): here.
-
-       * katie.conf (Architectures): minor corrections to the description
-       for arm, mips and mipsel.
-       * katie.conf-non-US (Architectures): likewise.
-       * katie.conf-security (Architectures): likewise.
-
-       * cron.daily-security: use natalie's new -a/--add functionality to
-       flesh out the security overrides.
-
-2002-07-12  James Troup  <james@nocrew.org>
-
-       * cron.buildd (ARCHS): add arm.
-
-       * katie.conf: 2.2r7 was released.
-       * katie.conf-non-US: likewise.
-
-       * utils.py (parse_changes): handle a multi-line field with no
-       starting line.
-
-2002-06-25  James Troup  <james@nocrew.org>
-
-       * templates/amber.advisory (To): add missing email address since
-       __WHOAMI__ is only a name.
-
-       * katie.conf-security (Melane::LogFile): correct to go somewhere
-       katie has write access to.
-       (Location::/org/security.debian.org/ftp/dists/::Suites): add
-       Testing.
-
-       * natalie: add support for -a/-add which adds packages only
-       (ignoring changes and deletions).
-
-       * katie.py (Katie.announce): Dinstall::CloseBugs is a boolean so
-       use FindB, not get.
-
-2002-06-22  James Troup  <james@nocrew.org>
-
-       * jennifer (check_files): validate the package name and version
-       field.  If 'Package', 'Version' or 'Architecture' are missing,
-       don't try any further checks.
-       (check_dsc): likewise.
-
-       * utils.py (re_taint_free): add '~' as a valid character.
-
-2002-06-20  Anthony Towns  <ajt@debian.org>
-
-       * katie.conf-non-US: add OverrideSuite for w-p-u to allow uploads
-
-2002-06-09  James Troup  <james@nocrew.org>
-
-       * jennifer (check_files): reduce useless code.
-
-       * cron.daily-security: run symlinks -dr on $ftpdir.
-
-       * vars-security (ftpdir): add.
-
-2002-06-08  James Troup  <james@nocrew.org>
-
-       * neve (update_override_type): transaction is handled higher up in
-       main().
-       (update_priority): likewise.
-       (process_sources): remove code that makes testing a duplicate of
-       stable.
-       (process_packages): likewise.
-
-       * templates/amber.advisory: add missing mail headers.
-
-       * cron.daily-security: also call apt-ftparchive clean for
-       apt.conf.buildd-security.
-       * cron.weekly: likewise.
-
-       * amber (do_upload): write out a list of source packages (and
-       their version) uploaded for testing.
-       (make_advisory): add more Subst mappings for the mail headers.
-       (spawn): check for suspicious characters in the command and abort
-       if their found.
-
-2002-06-07  James Troup  <james@nocrew.org>
-
-       * ziyi (main): remove the 'nonus'/'security' hacks and use
-       Dinstall::SuiteSuffix (if it exists) instead.  Always try to write
-       the lower level Release files, even if they don't exist.  fubar
-       out if we can't open a lower level Release file for writing.
-
-       * katie.conf-non-US (Dinstall): add SuiteSuffix, used to simplify
-       ziyi.
-       * katie.conf-security (Dinstall): likewise.
-
-       * amber (do_upload): renamed from get_file_list().  Determine the
-       upload host from the original component.
-       (init): Add a -n/--no-action option.  Fix how we get changes_files
-       (i.e. from the return value of apt_pkg.ParseCommandLine(), not
-       sys.argv).  Add an Options global.
-       (make_advisory): support -n/--no-action.
-       (spawn): likewise.
-       (main): likewise.
-       (usage): document -n/--no-action.
-
-       * cron.buildd-security: fix path to Packages-arch-specific in
-       quinn-diff invocation.
-
-       * katie.conf-security (Dinstall::AcceptedAutoBuildSuites): change
-       to proper suite names (i.e. stable, testing) rather than codenames
-       (potato, woody).
-       (Dinstall::DefaultSuite): likewise.
-       (Suite): likewise.
-       (Location::/org/security.debian.org/ftp/dists/::Suites): likewise.
-       * vars-security (suites): likewise.
-       * apt.conf-security: likewise.
-
-       * katie.conf-security (Component): add "updates/" prefix.
-       (Suite::*::Components): likewise.
-       (ComponentMappings): new; map all {ftp-master,non-US} components
-       -> updates/<foo>.
-
-       * katie.conf-security (Natalie): removed; the options have
-       defaults and ComponentPosition is used by alyson which doesn't
-       work on security.d.o.
-       (Amber): replace UploadHost and UploadDir with ComponentMappings
-       which is a mapping of components -> URI.
-       (Suite::*::CodeName): strip bogus "/updates" suffix hack.
-       (SuiteMappings): use "silent-map" in preference to "map".
-
-       * cron.unchecked-security: fix call to cron.buildd-security.
-
-       * cron.daily-security: map local suite (stable) -> override suite
-       (potato) when fixing overrides.  Correct component in natalie call
-       to take into account "updates/" prefix.  Fix cut'n'waste in
-       override.$dist.all3 generation, the old files weren't being
-       removed, so they were endlessly growing.
-
-       * neve (main): don't use .Find for the CodeName since we require
-       it.  Location::*::Suites is a ValueList.
-       (check_signature): ignore duplicate SIGEXPIRED tokens.  Don't bomb
-       out on expired keys, just warn.
-       (update_override_type): new function; lifted from alyson.
-       (update_priority): likewise.
-       (main): use update_{override_type,priority}().
-
-       * jennifer (check_distributions): remove redunant test for
-       SuiteMappings; ValueList("does-not-exist") returns [] which is
-       fine.  Add support for a "silent-map" type which doesn't warn
-       about the mapping to the user.
-       (check_files): add support for ComponentMappings, similar to
-       SuiteMappings, but there's no type, just a source and a
-       destination and the original component is stored in "original
-       component".
-       * katie.py (Katie.dump_vars): add "original component" as an
-       optionsal files[file] dump variable.
-
-       * claire.py (find_dislocated_stable): dehardcode 'potato' in SQL
-       query.  Add support for section-less legacy locations like current
-       security.debian.org through YetAnotherConfigBoolean
-       'LegacyStableHasNoSections'.
-       * katie.conf-security (Dinstall): LegacyStableHasNoSections is true.
-
-       * utils.py (real_arch): moved here from ziyi.
-       * ziyi (real_arch): moved to utils.py.
-       * ziyi (main): likewise.
-
-       * claire.py (find_dislocated_stable): use real_arch() with
-       filter() to strip out source and all.
-       * neve (main): likewise.
-       * rene (main): likewise.
-       * jeri (parse_packages): likewise.
-
-2002-06-06  James Troup  <james@nocrew.org>
-
-       * tea (check_missing_tar_gz_in_dsc): modifed patch from Martin
-       Michlmayr <tbm@cyrius.com> to be more verbose about what we're
-       doing.
-
-2002-05-23  Martin Michlmayr  <tbm@cyrius.com>
-
-       * jeri (check_joey): check if the line contains two elements
-       before accessing the second.  Also, strip trailing spaces as well
-       as the newline.
-       * halle (check_joey): likewise.
-
-2002-06-05  James Troup  <james@nocrew.org>
-
-       * cron.unchecked-security: new file; like cron.unchecked but if
-       there's nothing to do exit so we don't call cron.buildd-security.
-
-       * apt.conf.buildd-security: new file.
-
-       * vars (archs): alphabetize.
-       * vars-non-US (archs): likewise.
-
-       * vars-security: add unchecked.
-
-       * madison (main): reduce rather bizarrely verbose and purposeless
-       code to print arches to a simple string.join.
-
-       * katie.conf (Suites::Unstable): add UdebComponents, a new
-       valuelist of suites, used by jenna to flesh out the list of
-       <suite>_main-debian-installer-binary-<arch>.list files generated.
-       (Dinstall): add StableDislocationSupport, a new boolean used by
-       jenna to enable or disable stable dislocation support
-       (i.e. claire), as true.
-
-       * katie.conf (Dinstall): add StableDislocationSupport, a new
-       boolean used by jenna to enable or disable stable dislocation
-       support (i.e. claire), as true.
-       * katie.conf-non-US: likewise.
-       * katie.conf-security: likewise.
-
-       * cron.daily-security: generate .all3 overrides for the buildd
-       support.  Freshen a local copy of Packages-arch-specific from
-       buildd.debian.org.
-
-       * claire.py (find_dislocated_stable): disable the support for
-       files in legacy-mixed locations since none of the Debian archives
-       have any anymore.
-
-       * helena: new script; produces a report on NEW and BYHAND
-       packages.
-
-       * jenna: rewritten from scratch to fix speed problems.  Run time
-       on auric goes down from 31.5 minutes to 3.5 minutes.  Of that 3.5
-       minutes, 105 seconds are the monster query and 70 odd seconds is
-       claire.
-
-       * apt.conf.buildd (Default): remove MaxContentsChange as it's
-       irrelevant.
-
-2002-06-05  Ryan Murray  <rmurray@debian.org>
-
-       * cron.buildd-security: new file.
-
-2002-06-05  Matt Kraai  <kraai@alumni.cmu.edu>
-
-       * denise (list): take a file argument and use it.
-       (main): don't abuse sys.stdout, just write to the file.
-
-       * claire.py (usage): Fix misspelling.
-       (clean_symlink): Simplify.
-       (find_dislocated_stable): Avoid unnecessary work.
-
-2002-05-29  James Troup  <james@nocrew.org>
-
-       * cameron: removed; apt-ftparchive can simply walk the directory.
-
-2002-05-26  Anthony Towns  <ajt@debian.org>
-
-       * katie.conf{,-non-US}: Map testing to testing-proposed-updates
-       for the autobuilders.
-
-2002-05-24  Ryan Murray  <rmurray@debian.org>
-
-       * cron.buildd: update override files before running apt-ftparchive
-
-2002-05-23  Martin Michlmayr  <tbm@cyrius.com>
-
-       * amber (main): remove extra space in prompt.
-
-       * utils.py (validate_changes_file_arg): use original filename in
-       error messages.
-
-       * jeri (check_joey): close file after use.
-       (parse_packages): likewise.
-       (main): setup debug option properly.
-
-       * melanie (main): remove unused packages variable and simplify the
-       code to build up con_packages by using repr().
-
-2002-05-23  James Troup  <james@nocrew.org>
-
-       * lisa (recheck): when we reject, also return 0 so the package is
-       skipped.
-       (sg_compare): fix note sorting.
-       (recheck): remove the .katie file after rejection.
-
-       * katie.py (Katie.accept): accepted auto-build support take 3;
-       this time adding support for security.  Security needs a) non-pool
-       files copied rather than symlinked since accepted is readable only
-       by katie/security and www-data needs to be able to see the files,
-       b) needs per-suite directories.  SpecialAcceptedAutoBuild becomes
-       AcceptedAutoBuildSuites and is a ValueList containing the suites.
-       SecurityAcceptedAutoBuild is a new boolean which controls whether
-       or not normal or security style is used.  The unstable_accepted
-       table was renamed to accepted_autobuild and a suite column added.
-       Also fix a bug noticed by Ryan where an existent orig.tar.gz
-       didn't have it's last_used/in_accepted flags correctly updated.
-       * katie (install): likewise.
-       * rhona (clean_accepted_autobuild): likewise.
-
-2002-05-22  James Troup  <james@nocrew.org>
-
-       * lisa (sort_changes): new function; sorts changes properly.
-       Finally.
-       (sg_compare): new function; helper for sort_changes().  Sorts by
-       have note and time of oldest upload.
-       (indiv_sg_compare): new function; helper for sort_changes().
-       Sorts by source version, have source and filename.
-       (main): use sort_changes().
-       (changes_compare): obsoleted; removed.
-
-2002-05-20  James Troup  <james@nocrew.org>
-
-       * rhona (clean_accepted_autobuild): don't die if a file we're
-       trying to remove doesn't exist.  Makes rhona more friendly to
-       katie/katie.py crashes/bugs without any undue cost.
-
-2002-05-19  James Troup  <james@nocrew.org>
-
-       * lisa (main): if sorting a large number of changes give some
-       feedback.
-       (recheck): new function, run the same checks (modulo NEW,
-       obviously) as katie does, if they fail do the standard
-       reject/skip/quit dance.
-       (do_pkg): use it.
-
-       * katie (install): don't try to unlink the symlink in the
-       AcceptedAutoBuild support if the destination is not a symlink (or
-       doesn't exist).  Avoids unnecessary bombs on previous partial
-       accepts and will still bomb hard if the file exists and isn't a
-       symlink.
-
-       * utils.py: blah, commands _is_ used when the mail stuff isn't
-       commented out like it is in my test environment.
-
-       * lisa (changes_compare): "has note" overrides everything else.
-       Use .katie files rather than running parse_changes, faster and
-       allows "has note" to work.  Correct version compare, it was
-       reversed.  Ctime check should only kick in if the source packages
-       are not the same.
-       (print_new): print out and return any note.  Rename 'ret_code' to
-       'broken'.
-       (edit_new): renamed from spawn_editor.  Don't leak file
-       descriptors.  Clean up error message if editor fails.
-       (edit_note): new function, allows one to edit notes.
-       (do_new): add note support, editing and removing.
-       (init): kill -s/--sort; with notes we always want to use our
-       sorting method.
-       (usage): likewise.
-
-       * katie.py (Katie.dump_vars): add "lisa note" as an optional
-       changes field.
-
-       * utils.py (build_file_list): rename 'dsc' to 'is_a_dsc' and have
-       it default to 0.  Adapt tests to assume it's boolean.
-       * fernanda.py (check_changes): adjust call appropriately.
-       * halle (check_changes): likewise.
-       * jennifer (check_changes): likewise.
-       * jeri (check_changes): likewise.
-       * shania (flush_orphans): likewise.
-
-       * jennifer (check_dsc): pass is_a_dsc by name when calling
-       build_file_list() for clarity.
-       * shania (flush_orphans): likewise.
-       * tea (check_missing_tar_gz_in_dsc): likewise.
-
-       * jennifer (check_dsc): pass dsc_whitespace_rules by name when
-       calling parse_changes() for clarity.
-       * tea (check_dscs): likewise.
-
-       * utils.py (parse_changes): make dsc_whitespace_rules default to
-       not true.
-       * halle (check_changes): adjust call appropriately.
-       * jennifer (check_changes): likewise.
-       * jeri (check_changes): likewise.
-       * lisa (changes_compare): likewise.
-       * utils.py (changes_compare): likewise.
-       * melanie (main): likewise.
-       * shania (flush_orphans): likewise.
-       * fernanda.py (check_changes): likewise.
-
-2002-05-18  James Troup  <james@nocrew.org>
-
-       * katie.py (Katie.dump_vars): make the .katie file unreadable,
-       it's not useful and by and large a duplication of information
-       available in readable format in other files.
-
-2002-05-16  Ryan Murray  <rmurray@debian.org>
-
-       * melanie: Dir::TemplatesDir -> Dir::Templates
-
-2002-05-15  Ryan Murray  <rmurray@debian.org>
-
-       * cameron: correct the use of os.path.join
-
-2002-05-15  Anthony Towns  <ajt@debian.org>
-
-       * ziyi: Update to match the new format for Architectures/Components
-       in katie.conf.
-
-2002-05-14  James Troup  <james@nocrew.org>
-
-       * amber: new script; 'installer' wrapper script for the security
-       team.
-
-       * katie.py (Katie.announce): remove unused 'dsc' local
-       variable. (pychecker)
-
-       * ziyi: pre-define AptCnf and out globals to None. (pychecker)
-
-       * neve: don't import sys, we don't use it. (pychecker)
-       (check_signature): fix return type mismatch. (pychecker)
-
-       * utils.py: don't import commands, we don't use it.  (pychecker)
-
-       * katie (install): SpecialAcceptedAutoBuild is a boolean.
-
-       * katie.py (Katie.dump_vars): don't store "oldfiles", it's
-       obsoleted by the change to "othercomponents" handling in jennifer
-       detailed below.
-       (Katie.cross_suite_version_check): new function; implements
-       cross-suite version checking rules specified in the conf file
-       while also enforcing the standard "must be newer than target
-       suite" rule.
-       (Katie.check_binary_against_db): renamed, since it's invoked once
-       per-binary, "binaries" was inaccurate.  Use
-       cross_suite_version_check() and don't bother with the "oldfiles"
-       rubbish as jennifer works out "othercomponents" herself now.
-       (Katie.check_source_against_db): use cross_suite_version_check().
-
-       * katie (check): the version and file overwrite checks
-       (check_{binary,source,dsc}_against_db) are not per-suite.
-
-       * jennifer (check_files): less duplication of
-       'control.Find("Architecture", "")' by putting it in a local
-       variable.
-       (check_files): call check_binary_against_db higher up since it's
-       not a per-suite check.
-       (check_files): get "othercomponents" directly rather than having
-       check_binary_against_db do it for us.
-
-       * heidi (main): 'if x:', not 'if x != []:'.
-       * katie.py (Katie.in_override_p): likewise.
-       (Katie.check_dsc_against_db): likewise.
-       * natalie (main): likewise.
-       * rene (main): likewise.
-       * ziyi (real_arch): likewise.
-
-       * alyson (main): Suite::%s::Architectures, Suite::%s::Components
-       and OverrideType are now value lists, not lists.
-       * andrea (main): likewise.
-       * cindy (main): likewise.
-       * claire.py (find_dislocated_stable): likewise.
-       * denise (main): likewise.
-       * jenna (main): likewise.
-       * jennifer (check_distributions): likewise.
-       (check_files): likewise.
-       (check_urgency): likewise (Urgency::Valid).
-       * jeri (parse_packages): likewise.
-       * neve (main): likewise (and Location::%s::Suites).
-       * rene (main): likewise.
-
-2002-05-13  James Troup  <james@nocrew.org>
-
-       * katie.py (Katie.check_source_against_db): correct case of reject
-       message to be consistent with binary checks.
-
-       * jennifer (get_status_output): don't leak 2 file descriptors per
-       invocation.
-       (check_signature): add missing '\n' to "duplicate status token"
-       error message.
-
-2002-05-09  James Troup  <james@nocrew.org>
-
-       * utils.py (validate_changes_file_arg): new function; validates an
-       argument which should be a .changes file.
-       * ashley (main): use it.
-       * lisa (main): likewise.
-
-       * katie.py (Katie.check_dsc_against_db): since there can be more
-       than one .orig.tar.gz make sure we don't assume the .orig.tar.gz
-       entry still exists in files.
-
-       * jennifer (check_dsc): handle the .orig.tar.gz disappearing from
-       files, since check_dsc_against_db() deletes the .orig.tar.gz
-       entry.
-
-       * cameron: cleanups.
-
-       * utils.py (changes_compare): change sort order so that source
-       name and source version trump 'have source'; this should fix
-       UNACCEPT problems in katie where -1 hppa+source & i386, -2
-       i386&source & hppa lead to -1 i386 unaccept.  Problem worked out
-       by Ryan.
-
-       * lisa (main): allow the arguments to be .katie files too.
-
-2002-05-07  Ryan Murray  <rmurray@debian.org>
-
-       * cron.buildd: add s390 to arch list again
-
-2002-05-05  Ryan Murray  <rmurray@debian.org>
-
-       * cron.buildd: new script, update w-b database from unstable_accepted
-       table
-       * cameron: new script, take list in unstable_accepted and write out
-       a file list for apt-ftparchive
-       * apt.conf.buildd: new apt configuration for Packages/Sources for
-       unstable_accepted
-       * vars: add s390 to arch list.
-
-2002-05-03  James Troup  <james@nocrew.org>
-
-       * neve (main): don't hard code the calling user as that doesn't
-       work with modern postgres installs.  Fix psql invocation for
-       init_pool.sql (database name required).  Dont' hard code the
-       database name.
-       (process_sources): add support for fingerprint and install_date.
-       (process_packages): add support for fingerprint.
-       (do_sources): pass in the directory, fingerprint support needs it.
-       (get_status_output): borrowed from jennifer.
-       (reject): likewise.
-       (check_signature): likewise.
-
-       * katie (install): only try to log urgencies if Urgency_Logger is
-       defined.
-       (main): only initialize Urgency_Logger is Dir::UrgencyLog is
-       defined; only close Urgency_Logger if it's defined.
-
-       * catherine (poolize): adapt for Dir rationalization.
-       * claire.py (find_dislocated_stable): likewise.
-       * denise (main): likewise.
-       * halle (check_joey): likewise.
-       * jenna: likewise.
-       * jennifer: likewise.
-       * jeri: likewise.
-       * katie.py: likewise.
-       * katie: likewise.
-       * lisa (do_bxa_notification): likewise.
-       * logging.py (Logger.__init__): likewise
-       * rene (main): likewise.
-       * rhona (clean): likewise.
-       * shania (init): likewise.
-       * tea: likewise.
-       * ziyi: likewise.
-
-       * lisa (add_overrides): Dinstall::BXANotify is a boolean, use
-       FindB, not FindI.
-
-       * rhona (clean_accepted_autobuild): SpecialAcceptedAutoBuild is a
-       boolean, use FindB, not get.
-
-       * katie.py (Katie.check_dsc_against_db): ignore duplicate
-       .orig.tar.gz's which are an exact (size/md5sum) match.
-
-       * ashley (main): really allow *.katie files as arguments too;
-       noticed by aj.
-
-       * sql-aptvc.cpp: postgres.h moved to a "server" subdirectory.
-
-2002-05-03  Anthony Towns  <ajt@debian.org>
-
-       * ziyi: support for security.
-
-2002-05-02  James Troup  <james@nocrew.org>
-
-       * jennifer (accept): call Katie.check_override() unconditional as
-       no-mail check moved into that function.
-       (do_byhand): likewise.
-
-       * katie.py (Katie.check_override): don't do anything if we're a)
-       not sending mail or b) the override disparity checks have been
-       disbled via Dinstall::OverrideDisparityCheck.
-
-       * jennifer (check_files): don't hard code Unstable as the suite
-       used to check for architecture validity; use
-       Dinstall::DefaultSuite instead, if it exists.
-       (accept): conditionalize
-
-       * katie.py (Katie.update_subst): support global maintainer
-       override with Dinstall::OverrideMaintainer.
-
-       * jennifer (check_distributions): new function, Distribution
-       validation and mapping.  Uses new SuiteMappings variable from
-       config file to abstract suite mappings.
-       (check_changes): call it.
-
-       * natalie: renamed; nothing imports or likely will for some time.
-
-       * denise (main): remove unused natalie import and init().
-
-       * natalie.py (init): removed.
-       (main): initalize here instead and don't hardcode the database
-       name.
-
-2002-04-30  James Troup  <james@nocrew.org>
-
-       * katie.py (Katie.close_bugs): new function, split out from
-       announce().
-       (Katie.announce): only call close_bugs() if Dinstall::CloseBugs is
-       true.
-       (Katie.close_bugs): new function, split out
-       (Katie.close_bugs): return immediately if there are no bugs to
-       close.
-
-       * jennifer (acknowledge_new): adapt for new utils.TemplateSubst().
-       * katie (do_reject): likewise.
-       (stable_install): likewise.
-       * katie.py (Katie.announce): likewise.
-       (Katie.accept): likewise.
-       (Katie.check_override): likewise.
-       (Katie.do_reject): likewise.
-       * lisa (do_bxa_notification): likewise.
-       * melanie (main): likewise.
-
-       * utils.py (TemplateSubst): change second argument to be a
-       filename rather than a template since every caller opened a file
-       on the fly which was ugly and leaked file descriptor.
-
-2002-04-29  James Troup  <james@nocrew.org>
-
-       * katie.py (Katie.announce): (modified) patch from Raphael Hertzog
-       <hertzog@debian.org> to send 'accepted' announce mails to the
-       PTS. [#128140]
-
-2002-04-24  James Troup  <james@nocrew.org>
-
-       * init_pool.sql (unstable_accepted): add two new fields to
-       unstable_accepted; in_accepted is a boolean indicating whether or
-       not the file is in accepted and last_used is a timestamp used by
-       rhona to determine when to remove symlinks for installed packages.
-
-       * katie.py (Katie.accept): auto-build support take 2.  Create
-       symlinks for all files into a seperate directory.  Add files to
-       unstable_accepted as paths to the new directory; mark them as
-       being in accepted for cameron.  Properly conditionalize it on a
-       configuration variable.
-
-       * katie (install): likewise.  Update symlinks to point into the
-       pool; mark the files for later deletion by rhona and mark them as
-       not being in accepted for cameron.
-
-       * rhona (clean_accepted_autobuild): new function.
-
-2002-04-22  James Troup  <james@nocrew.org>
-
-       * jennifer (check_files): handle db_access.get_location_id()
-       returning -1 properly/better.
-
-       * rhona (clean_fingerprints): new function.
-
-2002-04-21  James Troup  <james@nocrew.org>
-
-       * utils.py (touch_file): unused; remove.
-       (plural): likewise.
-
-       * jennifer (check_files): close file descriptor used to get the
-       control file.
-       (check_md5sums): likewise.
-       (callback): likewise.
-
-       * katie.py (Katie.do_reject): handle manual rejects much better;
-       call the editor first and get confirmation from the user before
-       proceeding.
-
-       * jennifer (check_signature): prefix_multi_line_string() moved to
-       utils.
-
-       * utils.py (prefix_multi_line_string): moved here from jennifer.
-
-2002-04-20  James Troup  <james@nocrew.org>
-
-       * lisa (main): handle non-existent files.
-
-       * ashley (main): allow *.katie files as arguments too.
-
-2002-04-19  James Troup  <james@nocrew.org>
-
-       * katie.py (Katie.accept): add stuff to help auto-building from
-       accepted; if the .orig.tar.gz is not part of the upload (i.e. it's
-       in the pool), create a symlink to it in the accepted directory and
-       add the .dsc and .{u,}deb(s) to a new 'unstable_accepted' table.
-
-       * katie (install): undo the "auto-building from accepted" stuff
-       (i.e. remove the .orig.tar.gz symlink and remove the files from
-       unstable_accepted table).
-
-2002-04-16  James Troup  <james@nocrew.org>
-
-       * jennifer (upload_too_new): fix typo which was causing all
-       timestamp comparisons to be against the .changes file.  Also move
-       back to the original directory so we do the comparisons against
-       accurate timestamps.
-
-       * tea (check_missing_tar_gz_in_dsc): new function.
-
-       * jennifer (check_dsc): add a check to ensure there is a .tar.gz
-       file mentioned in the .dsc.
-
-       * lisa (main): use X-Katie in the mail headers, not X-Lisa; that
-       way mails reach debian-{devel-,}changes@l.d.o.
-
-2002-04-02  Ryan Murray  <rmurray@debian.org>
-
-       * cron.daily: run shania after rhona
-       * cron.daily-non-US: likewise.
-
-2002-04-01  James Troup  <james@nocrew.org>
-
-       * katie: re-add proposed-updates/stable install support.
-
-       * katie.py (Katie.dump_vars): add changes["changes"] as an
-       optional field; should be mandatory later.
-
-2002-03-31  James Troup  <james@nocrew.org>
-
-       * katie (install): support a Suite::<foo>::CopyKatie similar to
-       CopyChanges.  Done seperately because .katie files don't need to
-       be mirrored and will probably be copied to another directory as a
-       result.
-
-       * halle (main): add missing debug to options.
-
-2002-03-29  James Troup  <james@nocrew.org>
-
-       * madison (main): add a -r/--regex option.
-
-2002-03-26  James Troup  <james@nocrew.org>
-
-       * lisa: don't trample on changes["distribution"]; make a copy of
-       it as changes["suite"] instead and use that.
-
-2002-03-16  Anthony Towns  <ajt@debian.org>
-
-       * templates/lisa.bxa_notification: Fix some grammatical errors.
-       Encourage contact via bxa@ftp-master email address.
-
-2002-03-15  James Troup  <james@nocrew.org>
-
-       * jennifer (check_timestamps): remove bogus raise in except.
-
-2002-03-15  Anthony Towns  <ajt@debian.org>
-
-       * cron.monthly: rotate mail/archive/bxamail as well as
-       mail/archive/mail. This is for a complete archive of
-       correspondence with the BXA.
-
-2002-03-14  Anthony Towns  <ajt@debian.org>
-
-       * crypto-in-main changes.
-
-       * utils.py (move, copy): add an optional perms= parameter to let you
-       set the resulting permissions of the moved/copied file
-       * katie.py (force_move): rejected/morgued files should be unreadable
-       * jennifer (do_byhand, acknowledge_new): pending new and byhand files
-       should be unreadable.
-
-2002-03-07  Ryan Murray  <rmurray@debian.org>
-
-       * katie (install): check for existance of "files id" key as well as
-       it being set to a valid value.
-       * katie (install): check for existense and valid value for location
-       id as well
-
-2002-03-05  Ryan Murray  <rmurray@debian.org>
-
-       * katie.py (do_reject): reread the reason file after editing it.
-
-2002-02-25  James Troup  <james@nocrew.org>
-
-       * jennifer (check_changes): don't enforce sanity in .changes file
-       names since it doesn't seem to be possible; pcmica-cs and similar
-       freak show packages in particular cause real problems.
-
-       * katie.py (Katie.check_dsc_against_db): initialize 'found' for
-       each dsc_file since the .orig.tar.gz checking code now uses it as
-       a boolean.  Fixes bizarro rejections which bogusly claimed
-       .diff.gz md5sum/size was incorrect.
-
-2002-02-24  James Troup  <james@nocrew.org>
-
-       * katie (process_it): reset reject_message.
-
-2002-02-22  James Troup  <james@nocrew.org>
-
-       * db_access.py(set_files_id): disable use of
-       currval('files_id_seq') because it was taking 3 seconds on auric
-       which is insane (most calls take < 0.01) and simply call
-       get_files_id() for the return value instead.
-
-       * katie.py (Katie.do_query): convenience function; unused by
-       default, useful for profiling.
-       * db_access.py (do_query): likewise.
-
-       * katie (install): fix insert SQL call when binary has no source.
-
-       * lisa (determine_new): auto-correct non-US/main to non-US.
-       (determine_new): add a warning when adding things to stable.
-       (edit_index): use our_raw_input().
-       (edit_overrides): likewise.
-       (do_new): likewise.  Use re.search() not re.match() since the
-       default answer may not be the first one.
-       (do_byhand): likewise.
-       (do_new): Default to 'S'kip and never 'A'dd.
-
-       * jennifer (action): pass prompt to our_raw_input().
-       * melanie (game_over): likewise.
-       * katie (action): likewise.
-
-       * utils.py (our_raw_input): add an optional prompt argument to
-       make the function more usable as a drop in replacement for
-       raw_input().
-
-       * jennifer (check_files): correct reject() to not double prefix
-       when using katie.py based functions.
-       (check_dsc): likewise.
-
-       * katie.py (Katie.reject): prepend a new line if appropriate
-       rathen than appending one to avoid double new lines when caller
-       adds one of his own.
-
-       * lisa (determine_new): warn if the package is also in other
-       components.
-
-2002-02-20  James Troup  <james@nocrew.org>
-
-       * jennifer (check_files): if .changes file lists "source" in
-       Architecture field, there must be a .dsc.
-
-2002-02-15  James Troup  <james@nocrew.org>
-
-       * ashley (main): add some missing fields.
-
-       * katie.py (Katie.check_dsc_against_db): fix to take into account
-       the fact that the .orig.tar.gz might be in byhand, accepted or
-       new.  Also fix calling of reject().
-       (Katie.check_binaries_against_db): fix calling of reject().
-       (Katie.check_source_against_db): likewise.
-       (Katie.dump_vars): add missing variables used for bug closures.
-
-       * lisa (changes_compare_by_time): sort by reverse time.
-
-       * katie.py (Katie.accept): log.
-       (Katie.dump_vars): missing has_key test for optional changes fields.
-
-       * jennifer (main): print "Accepted blah blah" to stdout, not stderr.
-       (process_it): traceback goes to stderr, not stdout.
-       (acknowledge_new): log.
-       (do_byhand): likewise.
-
-       * katie.py (Katie.update_subst): fix typo (Cnf vs. self.Cnf).
-
-       * add_constraints.sql: add grants for the new fingerprint table.
-
-2002-02-13  James Troup  <james@nocrew.org>
-
-       * katie (do_reject): basename the .changes filename before trying
-       to use it to construct the .reason filename.
-       (process_it): call Katie.update_subst() so do_reject() DTRT with
-       the mail template.
-       (do_reject): setup the mail template correctly.
-
-2002-02-12  James Troup  <james@nocrew.org>
-
-       * tea (process_dir): renamed 'arg' to 'unused' for clarity.
-       (check_files): don't abuse global dictionaries.
-       (Ent): use all variables.
-       (check_timestamps): don't abuse global dictionaries.
-
-       * fernanda.py: renamed to .py so lisa can import it.
-       (check_dsc): remove unused local variables (pychecker).
-       (display_changes): split off from check_changes.
-
-       * katie: rewritten; most of the functionality moves to jennifer;
-       what's left is the code to install packages once a day from the
-       'accepted' directory.
-
-       * jennifer: new program, processes packages in 'unchecked'
-       (i.e. most of the non-install functionality of old katie).
-
-       * katie.py: common functions shared between the clique of
-       jennifer, lisa and katie.
-
-       * lisa: new program; handles NEW and BYHAND packages.
-
-       * jeri (usage): new function.
-       (main): use it.
-       (check_package): remove unused local variable (pychecker).
-
-       * init_pool.sql: new table fingerprint.  Add fingerprint colums to
-       binaries and source.  Add install_date to source.
-
-       * halle (usage): new function.
-       (main): use it.  Remove unused options.
-       (check_changes): remove unused local variable (pychecker).
-
-       * add_constraints.sql: add fingerprint references.
-
-       * db_access.py (get_or_set_fingerprint_id): new function.
-
-       * ashley (main): new program; dumps the contents of a .katie file
-       to stdout.
-
-       * alyson (main): remove option handling since we don't actually
-       support any.
-       * cindy (main): likewise.
-
-       * remove unnecessary imports and pre-define globals (pychecker).
-
-2002-02-11  Anthony Towns  <ajt@debian.org>
-
-       * added installation-report and upgrade-report pseudo-packages
-
-2002-01-28  Martin Michlmayr  <tbm@cyrius.com>
-
-       * katie (update_subst): use Dinstall::TrackingServer.
-       * melanie (main): likewise.
-
-2002-01-27  James Troup  <james@nocrew.org>
-
-       * shania (main): it's IntLevel not IntVal; thanks to tbm@ for
-       noticing, jgg@ for fix.
-
-2002-01-19  James Troup  <james@nocrew.org>
-
-       * utils.py (extract_component_from_section): handle non-US
-       non-main properly.
-
-2002-01-12  James Troup  <james@nocrew.org>
-
-       * madison: add support for -S/--source-and-binary which displays
-       information for the source package and all it's binary children.
-
-2002-01-13  Anthony Towns  <ajt@debian.org>
-
-       * katie.conf: Remove Catherine Limit and bump stable to 2.2r5
-       * katie.conf: Add Dinstall::SigningKeyIds option, set to the 2001
-         and 2002 key ids.
-       * katie.conf-non-US: Likewise.
-       * ziyi: Suppoer Dinstall::SigningKeyIds to sign a Release file with
-         multiple keys automatically. This is probably only useful for
-         transitioning from an expired (or revoked?) key.
-
-2002-01-08  Ryan Murray  <rmurray@debian.org>
-
-       * debian/python-dep: new file that prints out python:Depends for
-         substvars
-       * debian/control: use python:Depends, build-depend on python
-         lower Depends: on postgresql to Suggests:
-       * debian/rules: determine python version, install to the correct
-         versioned dir
-
-2001-12-18  Anthony Towns  <ajt@debian.org>
-
-       * ziyi: unlink Release files before overwriting them (in case they've
-         been merged)
-       * ziyi: always include checksums/sizes for the uncompressed versions
-         of Sources and Packages, even if they're not present on disk
-
-2001-11-26  Ryan Murray  <rmurray@debian.org>
-
-       * ziyi (main): add SigningPubKey config option
-       * katie.conf: use SigningPubKey config option
-       * katie.conf-non-US: likewise
-
-2001-11-24  James Troup  <james@nocrew.org>
-
-       * katie (acknowledge_new): log newness.
-
-2001-11-24  Anthony Towns  <ajt@debian.org>
-
-       * ziyi (real_arch): bail out if some moron forgot to reset
-       untouchable on stable.
-       (real_arch): source Release files.
-
-2001-11-19  James Troup  <james@nocrew.org>
-
-       * claire.py (main): don't use apt_pkg.ReadConfigFileISC and
-       utils.get_conf().
-       * shania (main): likewise.
-
-       * rhona (main): add default options.
-
-       * db_access.py (get_archive_id): case independent.
-
-       * katie (action): sort files so that ordering is consistent
-       between mails; noticed/requested by Joey.
-
-2001-11-17  Ryan Murray  <rmurray@debian.org>
-
-       * utils.py: add get_conf function, change startup code to read all
-         config files to the Cnf that get_conf returns
-         use the component list from the katie conf rather than the hardcoded
-         list.
-       * all scripts: use new get_conf function
-       * shania: fix try/except around changes files
-       * jenna: only do debian-installer if it is a section in Cnf
-
-2001-11-16  Ryan Murray  <rmurray@debian.org>
-
-       * shania (main): Initialize days to a string of a number.
-                (main): Initialize Cnf vars before reading in Cnf
-
-2001-11-14  Ryan Murray  <rmurray@debian.org>
-
-       * shania (main): Initialize days to a number.
-
-2001-11-04  James Troup  <james@nocrew.org>
-
-       * docs/Makefile: use docbook-utils' docbook2man binary.
-
-       * Change all "if foo == []" constructs into "if not foo".
-
-       * katie (check_changes): when installing into stable from
-       proposed-updates, remove all non-stable target distributions.
-       (check_override): don't check for override disparities on stable
-       installs.
-       (stable_install): update install_bytes appropriately.
-       (reject): stable rejection support; i.e. don't remove files when
-       rejecting files in the pool, rather remove them from the
-       proposed-update suite instead, rhona will do the rest.
-       (manual_reject): support for a stable specific template.
-       (main): setup up stable rejector in subst.
-
-2001-11-04  Martin Michlmayr  <tbm@cyrius.com>
-
-       * debian/control (Build-Depends): docbook2man has been superseded
-       by docbook-utils.
-
-       * neve (main): exit with a more useful error message.
-       (update_suites): Suite::<suite>::Version, Origin and Description
-       are not required, so don't fail if they don't exist.
-
-       * db_access.py (get_archive_id): return -1 on error rather than
-       raise an exception.
-       (get_location_id): likewise.
-
-       * madison (main): don't exit on the first not-found package,
-       rather exit with an appropriate return code after processing all
-       packages.
-
-2001-11-03  James Troup  <james@nocrew.org>
-
-       * claire.py (find_dislocated_stable): add per-architecture
-       symlinks for dislocated architecture: all debs.
-
-2001-10-19  Anthony Towns  <ajt@debian.org>
-
-       * apt.conf*, katie.conf*: add mips, mipsel, s390 to testing.
-
-2001-10-10  Anthony Towns  <ajt@debian.org>
-
-       * claire.py (fix_component_section): do _not_ assign to None under
-       any circumstances
-
-2001-10-07  Martin Michlmayr  <tbm@cyrius.com>
-
-       * melanie (main): don't duplicate architectures when removing from
-       more than one suite.
-
-       * heidi (main, process_file, get_list): report suite name not ID.
-
-       * naima (nmu_p): be case insensitive.
-
-       * naima (action): more list handling clean ups.
-
-       * melanie (main): clean up lists handling to use string.join and
-       IN's.
-
-       * madison (main): clean up suite and architecture argument parsing
-       to use slices less and string.join more.
-
-       * utils.py (parse_changes): Use string.find() instead of slices for
-       string comparisons thereby avoid hardcoding the length of strings.
-       * ziyi (main): likewise.
-
-2001-10-07  James Troup  <james@nocrew.org>
-
-       * Remove mode argument from utils.open_files() calls if it's the
-       default, i.e. 'r'.
-
-2001-09-27  James Troup  <james@nocrew.org>
-
-       * katie (init): new function; options clean up.
-       (usage): add missing options, remove obsolete ones.
-       (main): adapt for the two changes above.  If the lock file or
-       new-ack log file don't exist, create them.  Don't try to open the
-       new-ack log file except running in new-ack mode.
-
-       * alyson (main): initialize all the tables that are based on the
-       conf file.
-
-       * utils.py (touch_file): like touch(1).
-       (where_am_i): typo.
-
-       * catherine (usage): new.
-       (main): use it.  options cleanup.
-       * claire.py: likewise.
-       * fernanda: likewise.
-       * heidi: likewise.
-       * jenna: likewise.
-       * shania: likewise.
-       * ziyi: likewise.
-
-       * andrea: options cleanup.
-       * charisma: likewise.
-       * julia: likewise.
-       * madison: likewise.
-       * melanie: likewise.
-       * natalie: likewise.
-       * rhona: likewise.
-       * tea: likewise.
-
-2001-09-26  James Troup  <james@nocrew.org>
-
-       * utils.py: default to sane config file locations
-       (/etc/katie/{apt,katie}.conf.  They can be the actual config files
-       or they can point to the real ones through use of a new Config
-       section.  Based on an old patch by Adam Heath.
-       (where_am_i): use the new default config stuff.
-       (which_conf_file): likewise.
-       (which_apt_conf_file): likewise.
-
-       * charisma (main): output defaults to
-       `Package~Version\tMaintainer'; input can be of either form.  When
-       parsing the new format do version comparisons, when parsing the
-       old format assume anything in the extra file wins.  This fixes the
-       problem of newer non-US packages being overwhelmed by older
-       versions still in stable on main.
-
-2001-09-17  James Troup  <james@nocrew.org>
-
-       * natalie.py (list): use result_join().
-
-       * denise (main): result_join() moved to utils.
-
-       * utils.py (result_join): move to utils; add an optional seperator
-       argument.
-
-2001-09-14  James Troup  <james@nocrew.org>
-
-       * heidi (set_suite): new function; does --set like natalie does,
-       i.e. turns it into a sequence of --add's and --remove's
-       internally.  This is a major win (~20 minute run time > ~20
-       seconds) in the common, everday (i.e. testing) case.
-       (get_id): common code used by set_suite() and process_file().
-       (process_file): call set_suite() and get_id().
-       (main): add logging support.
-
-       * julia: new script; syncs PostgeSQL with (LDAP-generated) passwd
-       files.
-
-       * utils.py (parse_changes): use slices or simple string comparison
-       in favour of regexes where possible.
-
-       * sql-aptvc.cpp (versioncmp): rewritten to take into account the
-       fact that the string VARDATA() points to are not null terminated.
-
-       * denise (result_join): new function; like string.join() but
-       handles None's.
-       (list): use it.
-       (main): likewise.
-
-       * charisma (main): python-pygresql 7.1 returns None not "".
-
-2001-09-14  Ryan Murray  <rmurray@debian.org>
-
-       * natalie.py (list): handle python-pygresql 7.1 returning None.
-
-2001-09-10  Martin Michlmayr  <tbm@cyrius.com>
-
-       * madison (main): return 1 if no package is found.
-
-2001-09-08  Martin Michlmayr  <tbm@cyrius.com>
-
-       * madison (main): better error handling for incorrect
-       -a/--architecture or -s/--suite arguments.
-       (usage): new.
-       (main): use it.
-
-2001-09-05  Ryan Murray  <rmurray@debian.org>
-
-       * charisma, madison, katie: remove use of ROUser
-       * katie.conf,katie.conf-non-US: remove defintion of ROUser
-
-2001-08-26  James Troup  <james@nocrew.org>
-
-       * katie (nmu_p.is_an_nmu): use maintaineremail to check for group
-       maintained packages at cjwatson@'s request.
-
-2001-08-21  James Troup  <james@nocrew.org>
-
-       * madison (main): add -a/--architecture support.
-
-       * jenna: use logging instead of being overly verbose on stdout.
-
-2001-08-11  Ryan Murray  <rmurray@debian.org>
-
-       * melanie: add functional help option
-
-2001-08-07  Anthony Towns  <ajt@debian.org>
-
-       * apt.conf, katie.conf: Add ia64 and hppa to testing.
-
-2001-07-28  James Troup  <james@nocrew.org>
-
-       * katie (check_dsc): ensure source version is >> than existing
-       source in target suite.
-
-2001-07-25  James Troup  <james@nocrew.org>
-
-       * natalie.py: add logging support.
-
-       * utils.py (open_file): make the second argument optional and
-       default to read-only.
-
-       * rene (main): work around broken source packages that duplicate
-       arch: all packages with arch: !all packages (no longer allowed
-       into the archive by katie).
-
-2001-07-13  James Troup  <james@nocrew.org>
-
-       * katie (action): don't assume distribution is a dictionary.
-       (update_subst): don't assume architecture is a dictionary and that
-       maintainer822 is defined.
-       (check_changes): recognise nk_format exceptions.
-       (check_changes): reject on 'testing' only uploads.
-       (check_files): when checking to ensure all packages are newer
-       versions check against arch-all packages too.
-       (check_dsc): enforce the existent of a sane set of mandatory
-       fields.  Ensure the version number in the .dsc (modulo epoch)
-       matches the version number in the .changes file.
-
-       * utils.py (changes_compare): ignore all exceptions when parsing
-       the changes files.
-       (build_file_list): don't UNDEF on a changes file with no format
-       field.
-
-2001-07-07  James Troup  <james@nocrew.org>
-
-       * katie (nmu_p.is_an_nmu): check 'changedby822' for emptiness
-       rather than 'changedbyname' to avoid false negatives on uploads
-       with an email-address-only Changed-By field.
-       (check_dsc): don't overwrite reject_message; append to it.
-       (check_signature): likewise.
-       (check_changes): likewise.
-       (announce): condition logging on 'action'.
-
-       * logging.py: new logging module.
-
-       * katie: Cleaned up code by putting Cnf["Dinstall::Options"]
-       sub-tree into a separate (global) variable.
-       (check_dsc): ensure format is 1.0 to retain backwards
-       compatability with dpkg-source in potato.
-       (main): only try to obtain the lock when not running in no-action
-       mode.
-       Use the new logging module.
-
-       * christina: initial version; only partially usable.
-
-2001-06-28  Anthony Towns  <ajt@debian.org>
-
-       * apt.conf: Add ExtraOverrides to auric.
-
-2001-06-25  James Troup  <james@nocrew.org>
-
-       * katie (nmu_p.is_an_nmu): the wonderful dpkg developers decided
-       they preferred the name 'Uploaders'.
-
-2001-06-23  James Troup  <james@nocrew.org>
-
-       * katie (check_files): fix typo in uncommon rejection message,
-       s/sourceversion/source version/.
-
-       * denise (main): we can't use print because stdout has been
-       redirected.
-
-       * katie (source_exists): new function; moved out of check_files()
-       and added support for binary-only NMUs of earlier sourceful NMUs.
-
-       * rhona (clean): find_next_free has moved.
-
-       * utils.py (find_next_free): new function; moved here from rhona.
-       Change too_many to be an argument with a default value, rather
-       than a hardcoded variable.
-
-       * shania: rewritten to work better; REJECTion reminder mail
-       handling got lost though.
-
-2001-06-22  James Troup  <james@nocrew.org>
-
-       * rhona (main): remove unused override code.
-
-       * fernanda (main): remove extraneous \n's from utils.warn calls.
-       * natalie.py (list): likewise.
-
-       * catherine, cindy, denise, heidi, jenna, katie, neve, rhona, tea:
-       use utils.{warn,fubar} where appropriate.
-
-2001-06-21  James Troup  <james@nocrew.org>
-
-       * katie (nmu_p): new class that encapsulates the "is a nmu?"
-       functionality.
-       (nmu_p.is_an_nmu): add support for multiple maintainers specified
-       by the "Maintainers" field in the .dsc file and maintainer groups.
-       (nmu_p.__init__): read in the list of group maintainer names.
-       (announce): use nmu_p.
-
-2001-06-20  James Troup  <james@nocrew.org>
-
-       * rene (main): hardcode the suite experimental is compared to by
-       name rather than number.
-
-       * katie (check_files): differentiate between doesn't-exist and
-       permission-denied in "can not read" rejections; requested by edd@.
-       (check_dsc): use os.path.exists rather than os.access to allow the
-       above check to kick in.
-
-       * heidi (process_file): read all input before doing anything and
-       use transactions.
-
-2001-06-15  James Troup  <james@nocrew.org>
-
-       * fernanda: new script; replaces old 'check' shell script
-       nastiness.
-
-2001-06-14  James Troup  <james@nocrew.org>
-
-       * katie: actually import traceback module to avoid amusing
-       infinite loop.
-
-2001-06-10  James Troup  <james@nocrew.org>
-
-       * utils.py (extract_component_from_section): fix to handle just
-       'non-free' and 'contrib'.  Also fix to handle non-US in a
-       completely case insensitive manner as a component.
-
-2001-06-08  James Troup  <james@nocrew.org>
-
-       * madison (arch_compare): sort function that sorts 'source' first
-       then alphabetically.
-       (main): use it.
-
-2001-06-05  Jeff Licquia  <jlicquia@progeny.com>
-
-       * catherine (poolize): explicitly make poolized_size a long so it
-       doesn't overflow when poolizing e.g. entire archives.
-
-2001-06-01  James Troup  <james@nocrew.org>
-
-       * utils.py (send_mail): throw exceptions rather than exiting.
-
-       * katie (process_it): catch exceptions and ignore them.
-
-2001-06-01  Michael Beattie  <mjb@debian.org>
-
-       * added update-mailingliststxt and update-readmenonus to update
-       those files, respectively. modified cron.daily{,-non-US} to
-       use them.
-
-2001-05-31  Anthony Towns  <ajt@debian.org>
-
-       * rhona: make StayOfExecution work.
-
-2001-05-31  James Troup  <james@nocrew.org>
-
-       * rhona (find_next_free): fixes to not overwrite files but rename
-       them by appending .<n> instead.
-       (clean): use find_next_free and use dated sub-directories in the
-       morgue.
-
-       * utils.py (move): don't overwrite files unless forced to.
-       (copy): likewise.
-
-2001-05-24  James Troup  <james@nocrew.org>
-
-       * katie (check_files): determine the source version here instead
-       of during install().
-       (check_files): check for existent source with bin-only NMU
-       support.
-       (main): sort the list of changes so that the source-must-exist
-       check Does The Right Thing(tm).
-
-       * utils.py (changes_compare): new function; sorts a list of
-       changes files by 'have-source', source, version.
-       (cc_fix_changes): helper function.
-       (parse_changes): use compiled regexes.
-       (fix_maintainer): likewise.
-
-       * rene (main): warn about packages in experimental that are
-       superseded by newer versions in unstable.
-
-2001-05-21  James Troup  <james@nocrew.org>
-
-       * rene (main): add support for checking for ANAIS (Architecture
-       Not Allowed In Source) packages.
-
-2001-05-17  James Troup  <james@nocrew.org>
-
-       * katie (check_changes): initalize `architecture' dictionary in
-       changes global so that if we can't parse the changes file for
-       whatever reason we don't undef later on.
-
-       * utils.py (parse_changes): fix handling of multi-line fields
-       where the first line did have data.
-
-2001-05-05  Anthony Towns  <ajt@debian.org>
-
-       * ziyi: Add "NotAutomatic: yes" to experimental Release files.
-       (It should always have been there. Ooopsy.)
-
-2001-05-03  Anthony Towns  <ajt@debian.org>
-
-       * jenna: Cleanup packages that move from arch:any to arch:all or
-       vice-versa.
-
-2001-04-24  Anthony Towns  <ajt@debian.org>
-
-       * ziyi: add ``SHA1:'' info to Release files. Also hack them up to
-       cope with debian-installer and boot-floppies' md5sum.txt.
-
-2001-04-16  James Troup  <james@nocrew.org>
-
-       * katie (check_changes): add missing %s format string argument.
-       (stable_install): temporary work around for morgue location to
-       move installed changes files into.
-       (stable_install): helps if you actually read in the template.
-       (manual_reject): fix for editing of reject messages which was
-       using the wrong variable name.
-
-       * jenna (generate_src_list): typo; s/package/source/; fixes undef crash.
-
-2001-04-13  James Troup  <james@nocrew.org>
-
-       * katie (manual_reject): Cc the installer.
-       (reject): don't.
-       (check_changes): remove unused maintainer-determination code.
-       (update_subst): add support for Changed-By when setting the
-       *MAINTAINER* variables.
-
-       * rene (bar): new function to check for packages on architectures
-       when they shouldn't be.
-
-       * natalie.py (main): use fubar() and warn() from utils.
-
-       * utils.py (whoami): new mini-function().
-       * melanie (main): use it.
-       * katie (manual_reject): likewise.
-
-2001-04-03  James Troup  <james@nocrew.org>
-
-       * katie (action): ignore exceptions from os.path.getmtime() so we
-       don't crash on non-existent changes files (e.g. when they are
-       moved between the start of the install run in cron.daily and the
-       time we get round to processing them).
-
-       * madison (main): also list source and accept -s/--suite.
-
-       * jenna (generate_src_list): missing \n in error message.
-
-       * katie (update_subst): add sane defaults for when changes is
-       skeletal.
-
-2001-03-29  James Troup  <james@nocrew.org>
-
-       * melanie (main): use fubar() and warn() from utils.  Remember who
-       the maintainer for the removed packages are and display that info
-       to the user.  Readd support for melanie-specific Bcc-ing that got
-       lost in the TemplateSubst transition.
-
-       * utils.py (fubar): new function.
-       (warn): like wise.
-
-       * db_access.py (get_maintainer): as below.
-
-       * charisma (get_maintainer): moved the bulk of this function to
-       db_access so that melanie can use it too.
-
-       * claire.py (find_dislocated_stable): restrict the override join
-       to those entries where the suite is stable; this avoids problems
-       with packages which have moved to new sections (e.g. science)
-       between stable and unstable.
-
-2001-03-24  James Troup  <james@nocrew.org>
-
-       * catherine (poolize): new function; not really independent of
-       main() fully, yet.
-       (main): use it.
-
-       * katie (stable_install): __SUITE__ needs to be space prefixed
-       because buildd's check for 'INSTALLED$'.
-
-2001-03-22  James Troup  <james@nocrew.org>
-
-       * utils.py (regex_safe): also need to escape '.'; noticed by ajt@.
-
-       * jenna: rewritten; now does deletions on a per-suite level
-       instead of a per-suite-component-architecture-type level.  This
-       allows mutli-component packages to be auto-cleaned (and as a
-       bonus, reduces the code size and duplication).
-
-2001-03-22  Anthony Towns  <ajt@debian.org>
-
-       * ziyi (main): fix ziyi to overwrite existing Release.gpg files
-       instead of just giving a gpg error.
-
-2001-03-21  James Troup  <james@nocrew.org>
-
-       * madison (main): use apt_pkg.VersionCompare to sort versions so
-       that output is correctly sorted for packages like debhlper.
-       Noticed by ajt@.
-
-       * tea (check_source_in_one_dir): actually find problematic source
-       packages.
-
-       * katie (check_dsc): remember the orig.tar.gz's location ID if
-       it's not in a legacy suite.
-       (check_diff): we don't use orig_tar_id.
-       (install): add code to handle sourceful diff-only upload of
-       packages which change components by copying the .orig.tar.gz into
-       the new component, if it doesn't already exist there.
-       (process_it): reset orig_tar_location (as above).
-
-       * melanie (main): use template substiution for the bug closing
-       emails.
-       (main): don't hardcode bugs.debian.org or packages.debian.org
-       either; use configuration items.
-
-       * katie: likewise.
-
-       * natalie.py (init): use None rather than 'localhost' for the
-       hostname given to pg.connect.
-
-       * utils.py (TemplateSubst): new function; lifted from
-       userdir-ldap.
-
-2001-03-21  Ryan Murray  <rmurray@debian.org>
-
-       * katie (announce): fix the case of non-existent
-       Suite::$SUITE::Announce.
-
-2001-03-20  Ryan Murray  <rmurray@debian.org>
-
-       * debian/rules (binary-indep): install melanie into /usr/bin/ not
-       /usr/.
-
-       * alyson (main): use config variable for database name.
-       * andrea (main): likewise.
-       * catherine (main): likewise.
-       * charisma (main): likewise.
-       * cindy (main): likewise.
-       * claire.py (main): likewise.
-       * denise (main): likewise.
-       * heidi (main): likewise.
-       * jenna (main): likewise.
-       * katie (main): likewise.
-       * madison (main): likewise.
-       * melanie (main): likewise.
-       * neve (main): likewise.
-       * rhona (main): likewise.
-       * tea (main): likewise.
-
-2001-03-15  James Troup  <james@nocrew.org>
-
-       * rhona (check_sources): fixed evil off by one (letter) error
-       which was causing only .dsc files to be deleted when cleaning
-       source packages.
-
-       * charisma (get_maintainer_from_source): remove really stupid and
-       gratuitous IN sub-query and replace with normal inner join.
-       (main): connect as read-only user nobody.
-
-       * rhona (clean_maintainers): rewritten to use SELECT and sub-query
-       with EXISTS.
-       (check_files): likewise; still disabled by default though.
-       (clean_binaries): add ' seconds' to the mysterious number in the
-       output.
-       (clean): likewise.
-
-       * tea (check_files): add missing global declaration on db_files.
-
-2001-03-14  James Troup  <james@nocrew.org>
-
-       * rhona: rewritten large chunks. Removed a lot of the silly
-       selecting into dictionaries and replaced it with 'where exists'
-       based sub queries.  Added support for StayOfExecution.  Fix the
-       problem with deleting dsc_files too early and disable cleaning of
-       unattached files.
-
-2001-03-14  Anthony Towns  <ajt@debian.org>
-
-       * katie (announce): also check Changed-By when trying to detect
-       NMUs.
-
-2001-03-06  Anthony Towns  <ajt@debian.org>
-
-       * ziyi (main): Generate Release.gpg files as well, using the key from
-       Dinstall::SigningKey in katie.conf, if present. That key has to be
-       passwordless, and hence kept fairly secretly.
-
-2001-03-02  James Troup  <james@nocrew.org>
-
-       * utils.py (str_isnum): new function; checks to see if the string
-       is a number.
-
-       * shania (main): fix _hideous_ bug which was causing all files > 2
-       weeks old to be deleted from incoming, even if they were part of a
-       valid upload.
-
-2001-02-27  James Troup  <james@nocrew.org>
-
-       * melanie (main): accept new argument -C/--carbon-copy which
-       allows arbitarty carbon-copying of the bug closure messages.
-       Cleaned up code by putting Cnf["Melanie::Options"] sub-tree into a
-       separate variable.
-
-2001-02-27  Anthony Towns  <ajt@debian.org>
-
-       * ziyi: new program; generates Release files.
-
-2001-02-25  James Troup  <james@nocrew.org>
-
-       * katie (reject): add missing '\n' to error message.
-       (manual_reject): likewise.
-       (install): catch exceptions from moving the changes file into DONE
-       and ignore them.
-
-       * tea (check_md5sums): new function.
-
-2001-02-25  Michael Beattie  <mjb@debian.org>
-
-       * melanie: use $EDITOR if available.
-
-2001-02-15  James Troup  <james@nocrew.org>
-
-       * utils.py (parse_changes): don't crash and burn on empty .changes
-       files.  Symptoms noticed by mjb@.
-
-2001-02-15  Adam Heath  <doogie@debian.org>
-
-       * denise (main): use an absolute path for the output filename.
-
-       * sql-aptvc.cpp: don't #include <utils/builtins.h> as it causes
-       compile errors with postgresql-dev >= 7.0.
-
-2001-02-12  James Troup  <james@nocrew.org>
-
-       * rene: initial version.
-
-       * andrea: initial version.
-
-       * catherine (main): remove obsolete assignment of arguments.
-
-2001-02-09  James Troup  <james@nocrew.org>
-
-       * catherine: first working version.
-
-2001-02-06  James Troup  <james@nocrew.org>
-
-       * katie (check_files): validate the priority field; i.e. ensure it
-       doesn't contain a '/' (to catch people prepending the priority
-       with the component rather than the section).
-       (check_override): don't warn about source packages; the only check
-       is on section and we have no GUI tools that would use the Section
-       field for a Sources file.
-       (announce): use tags rather than severities for NMUs.  Requested
-       by Josip Rodin <joy@>. [#78035]
-
-2001-02-04  James Troup  <james@nocrew.org>
-
-       * tea (check_override): new function; ensures packages in suites
-       are also in the override file.  Thanks to bod@ for noticing that
-       such packages existed.
-
-       * katie: move file type compiled regular expressions to utils as
-       catherine uses them too.
-       (check_changes): always default maintainer822 to the installer
-       address so that any bail out won't cause undefs later.
-       (check_files): update file type re's to match above.
-       (stable_install): likewise.
-       (reject): handle any except from moving the changes files.  Fixes
-       crashes on unreadable changes files.
-
-       * melanie (main): add an explanation of why things are not removed
-       from testing.
-
-2001-01-31  James Troup  <james@nocrew.org>
-
-       * melanie (main): ignore a) no message, b) removing from stable or
-       testing when invoked with -n/--no-action.
-
-       * katie (check_override): lower section before checking to see if
-       we're whining about 'non-US' versus 'non-US/main'.
-
-       * sql-aptvc.cpp: new file; wrapper around apt's version comparison
-       function so that we can use inside of PostgreSQL.
-
-2001-01-28  James Troup  <james@nocrew.org>
-
-       * katie: updated to pass new flag to parse_changes() and deal with
-       the exception raised on invalid .dsc's if appropriate.
-       * shania (main): likewise.
-       * melanie (main): likewise.
-
-       * tea (check_dscs): new function to validate all .dsc files in
-       unstable.
-
-       * utils.py (parse_changes): if passed an additional flag, validate
-       the .dsc file to ensure it's extractable by dpkg-source.
-       Requested by Ben Collins <bcollins@>.
-
-2001-01-27  James Troup  <james@nocrew.org>
-
-       * madison (main): connect to the DB as nobody.
-
-       * katie (check_files): remove support for -r/--no-version-check
-       since it makes no sense under katie (jenna will automatically
-       remove the (new) older version) and was evil in any event.
-       (check_changes): add missing new line to rejection message.
-       (check_dsc): likewise.
-       (process_it): reset reject_message here.
-       (main): not here.  Also remove support for -r.
-
-2001-01-26  James Troup  <james@nocrew.org>
-
-       * katie (check_override): don't whine about 'non-US/main' versus
-       'non-US'.
-
-2001-01-26  Michael Beattie  <mjb@debian.org>
-
-       * natalie.py (usage): new function.
-       (main): use it.
-
-2001-01-25  Antti-Juhani Kaijanaho  <gaia@iki.fi>
-
-       * update-mirrorlists: Update README.non-US too (request from Joy).
-
-2001-01-25  James Troup  <james@nocrew.org>
-
-       * katie (reject): catch any exception from utils.move() and just
-       pass, we previously only caught can't-overwrite errors and not
-       can't-read ones.
-
-       * jenna (generate_src_list): use ORDER BY in selects to avoid
-       unnecessary changes to Packages files.
-       (generate_bin_list): likewise.
-
-       * utils.py (extract_component_from_section): separated out from
-       build_file_list() as it's now used by claire too.
-
-       * claire.py (find_dislocated_stable): rewrite the query to extract
-       section information and handle component-less locations properly.
-       Thanks to ajt@ for the improved queries.
-       (fix_component_section): new function to fix components and
-       sections.
-
-2001-01-23  James Troup  <james@nocrew.org>
-
-       * katie (check_files): set file type for (u?)debs first thing, so
-       that if we continue, other functions which rely on file type
-       existing don't bomb out.  If apt_pkg or apt_inst raise an
-       exception when parsing the control file, don't try any other
-       checks, just drop out.
-       (check_changes): new test to ensure there is actually a target
-       distribution.
-
-2001-01-22  James Troup  <james@nocrew.org>
-
-       * katie (usage): s/dry-run/no-action/.  Noticed by Peter Gervai
-       <grin@>.
-       (check_changes): when mapping to unstable, remember to actually
-       add unstable to the suite list and not just remove the invalid
-       suite.
-
-2001-01-21  James Troup  <james@nocrew.org>
-
-       * katie (check_files): catch exceptions from debExtractControl()
-       and reject packages which raise any.
-
-2001-01-19  James Troup  <james@nocrew.org>
-
-       * katie (check_signature): basename() file name in rejection
-       message.
-
-2001-01-18  James Troup  <james@nocrew.org>
-
-       * katie (in_override_p): remember the section and priority from
-       the override file so we can check them against the package later.
-       (check_override): new function; checks section and priority (for
-       binaries) from the package against the override file and mails the
-       maintainer about any disparities.
-       (install): call check_override after announcing the upload.
-
-2001-01-16  James Troup  <james@nocrew.org>
-
-       * utils.py (build_file_list): catch ValueError's from splitting up
-       the files field and translate it into a parse error.
-
-       * tea: add support for finding unreferenced files.
-
-       * katie (in_override_p): add support for suite-aliasing so that
-       proposed-updates uploads work again.
-       (check_changes): catch parses errors from utils.build_file_list().
-       (check_dsc): likewise.
-       (check_diff): yet more dpkg breakage so we require even newer a
-       version.
-
-       * jenna (generate_bin_list): don't do nasty path munging that's no
-       longer needed.
-
-       * denise (main): support for non-US; and rename testing's override
-       files so they're based on testing's codename.
-
-2001-01-16  Martin Michlmayr  <tbm@cyrius.com>
-
-       * melanie: add to the bug closing message explaining what happens
-       (or rather doesn't) with bugs against packages that have been
-       removed.
-
-2001-01-14  James Troup  <james@nocrew.org>
-
-       * charisma (main): fix silly off-by-one error; suite priority
-       checking was done using "less than" rather than "less than or
-       equal to" which was causing weird hesienbugs with wrong Maintainer
-       fields.
-
-2001-01-10  James Troup  <james@nocrew.org>
-
-       * katie (in_override_p): adapted to use SQL-based overrides.
-       read_override_file function disappears.
-
-       * db_access.py: add new functions get_section_id, get_priority_id
-       and get_override_type_id.
-       (get_architecture_id): return -1 if the architecture is not found.
-
-       * heidi: switch %d -> %d in all SQL queries.
-       (get_list): Use string.join where appropriate.
-
-       * rhona (in_override_p): don't die if the override file doesn't
-       exist.
-       (main): warn if the override file doesn't exist.
-
-       * alyson: new script; will eventually sync the config file and the
-       SQL database.
-
-       * natalie.py: new script; manipulates overrides.
-
-       * melanie: new script; removes packages from suites.
-
-2001-01-08  James Troup  <james@nocrew.org>
-
-       * katie (re_bad_diff): whee; dpkg 1.8.1.1 didn't actually fix
-       anything it just changed the symptom.  Recognise the new breakage
-       and reject them too.
-
-2001-01-07  James Troup  <james@nocrew.org>
-
-       * katie (check_dsc): when adding the cwd copy of the .orig.tar.gz
-       to the .changes file, be sure to set up files[filename]["type"]
-       too.
-
-2001-01-06  James Troup  <james@nocrew.org>
-
-       * katie (check_diff): new function; detects bad diff files
-       produced by dpkg 1.8.1 and rejects thems.
-       (process_it): call check_diff().
-       (check_dsc): gar.  Add support for multiple versions of the
-       .orig.tar.gz file in the archive from -sa uploads.  Check md5sum
-       and size against all versions and use one which matches if
-       possible and exclude any that don't from being poolized to avoid
-       file overwrites.  Thanks to broonie@ for providing the example.
-       (install): skip any files marked as excluded as above.
-
-2001-01-05  James Troup  <james@nocrew.org>
-
-       * heidi (process_file): add missing argument to error message.
-
-2001-01-04  James Troup  <james@nocrew.org>
-
-       * heidi (main): fix handling of multiple files by reading all
-       files not just the first file n times (where n = the number of
-       files passed as arguments).
-
-2001-01-04  Anthony Towns  <ajt@debian.org>
-
-       * katie (check_dsc): proper fix for the code which locates the
-       .orig.tar.gz; check for '<filename>$' or '^<filename>$'.
-
-2000-12-20  James Troup  <james@nocrew.org>
-
-       * rhona: replace IN's with EXISTS's to make DELETE time for
-       binaries and source sane on auric.  Add a -n/--no-action flag and
-       make it stop actions if used.  Fixed a bug in binaries deletion
-       with no StayOfExecution (s/</<=/).  Add working -h/--help and
-       -V/--version.  Giving timing info on deletion till I'm sure it's
-       sane.
-
-       * katie (check_changes): map testing to unstable.
-
-       * madison: new script; shows versions in different architectures.
-
-       * katie (check_dsc): ensure size matches as well as md5sum;
-       suggested by Ben Collins <bcollins@debian.org> in Debian Bug
-       #69702.
-
-2000-12-19  James Troup  <james@nocrew.org>
-
-       * katie (reject): ignore the "can't overwrite file" exception from
-       utils.move() and leave the files where they are.
-       (reject): doh! os.access() test was reversed so we only tried to
-       move files which didn't exist... replaced with os.path.exists()
-       test the right way round.
-
-       * utils.py (move): raise an exception if we can't overwrite the
-       destination file.
-       (copy): likewise.
-
-2000-12-18  James Troup  <james@nocrew.org>
-
-       * rhona: first working version.
-
-       * db_access.py (get_files_id): force both sizes to be integers.
-
-       * katie (main): use size_type().
-
-       * utils.py (size_type): new function; pretty prints a file size.
-
-2000-12-17  James Troup  <james@nocrew.org>
-
-       * charisma (main): do version compares so that older packages do
-       not override newer ones and process source first as source wins
-       over binaries in terms of who we think of as the Maintainer.
-
-2000-12-15  James Troup  <james@nocrew.org>
-
-       * katie (install): use the files id for the .orig.tar.gz from
-       check_dsc().
-       (install): limit select for legacy source to a) source in legacy
-       or legacy-mixed type locations and b) distinct on files.id.
-       (install): rather than the bizarre insert new, delete old method
-       for moving legacy source into the pool, use a simple update of
-       files.
-       (process_it): initalize some globals before each process.
-
-2000-12-14  James Troup  <james@nocrew.org>
-
-       * katie (in_override_p): index on binary_type too since .udeb
-       overrides are in a different file.
-       (read_override_file): likewise.
-       (check_files): correct filename passed to get_files_id().
-       (check_dsc): we _have_ to preprend '/' to the filename to avoid
-       mismatches like jabber.orig.tar.gz versus libjabber.orig.tar.gz.
-       (check_dsc): remember the files id of the .orig.tar.gz, not the
-       location id.
-
-2000-12-13  James Troup  <james@nocrew.org>
-
-       * utils.py (poolify): force the component to lower case except for
-       non-US.
-
-       * katie (in_override_p): handle .udeb-specific override files.
-       (check_files): pass the binary type to in_override_p().
-       (check_dsc): remember the location id of the old .orig.tar.gz in
-       case it's not in the pool.
-       (install): use location id from dsc_files; which is where
-       check_dsc() puts it for old .orig.tar.gz files.
-       (install): install files after all DB work is complete.
-       (reject): basename() the changes filename.
-       (manual_reject): likewise.
-
-       * shania: new progam; replaces incomingcleaner.
-
-2000-12-05  James Troup  <james@nocrew.org>
-
-       * katie (check_changes): if inside stable and can't find files
-       from the .changes; assume it's installed in the pool and chdir()
-       to there.
-       (check_files): we are not installing for stable installs, so don't
-       check for overwriting existing files.
-       (check_dsc): likewise.
-       (check_dsc): reorder .orig.tar.gz handling so that we search in
-       the pool first and only then fall back on any .orig.tar.gz in the
-       cwd; this avoids false positives on the overwrite check when
-       people needlessly reupoad the .orig.tar.gz in a non-sa upload.
-       (install): if this is a stable install, bail out to
-       stable_install() immediately.
-       (install): dsc_files handling was horribly broken. a) we need to
-       add files from the .dsc and not the .changes (duh), b) we need to
-       add the .dsc file itself to dsc_files (to be consistent with neve
-       if for no other reason).
-       (stable_install): new function; handles installs from inside
-       proposed-updates to stable.
-       (acknowledge_new): basename changes_filename before doing
-       anything.
-       (process_it): absolutize the changes filename to avoid the
-       requirement of being in the same directory as the .changes file.
-       (process_it): save and restore the cwd as stable installs can
-       potentially jump into the pool to find files.
-
-       * jenna: dislocated_files support using claire.
-
-       * heidi (process_file): select package field from binaries
-       explicitly.
-
-       * db_access.py (get_files_id): fix cache key used.
-
-       * utils.py (build_file_list): fix 'non-US/non-free' case in
-       section/component splitting.
-       (move): use os.path.isdir() rather than stat.
-       (copy): likewise.
-
-       * claire.py: new file; stable in non-stable munger.
-
-       * tea: new file; simply ensures all files in the DB exist.
-
-2000-12-01  James Troup  <james@nocrew.org>
-
-       * katie (check_dsc): use regex_safe().
-       (check_changes): typo in changes{} key:
-       s/distributions/distribution/.
-       (install): use changes["source"], not files[file]["source"] as the
-       latter may not exist and the former is used elsewhere.  Commit the
-       SQL transaction earlier.
-
-       * utils.py (regex_safe): new function; escapes characters which
-       have meaning to SQL's regex comparison operator ('~').
-
-2000-11-30  James Troup  <james@nocrew.org>
-
-       * katie (install): pool_location is based on source package name,
-       not binary package.
-
-       * utils.py (move): if dest is a directory, append the filename
-       before chmod-ing.
-       (copy): ditto.
-
-       * katie (check_files): don't allow overwriting of existing .debs.
-       (check_dsc): don't allow overwriting of existing source files.
-
-2000-11-27  James Troup  <james@nocrew.org>
-
-       * katie (check_signature): don't try to load rsaref; it's
-       obsolete.
-       (in_override_p): don't try to lookup override entries for packages
-       with an invalid suite name.
-       (announce): don't assume the suite name is valid; use Find() to
-       lookup the mailing list name for announcements.
-
-       * utils.py (where_am_i): typo; hostname is in the first element,
-       not second.
-
-       * db_access.py (get_suite_id): return -1 on an unknown suite.
-
-2000-11-26  James Troup  <james@nocrew.org>
-
-       * katie (install): fix CopyChanges handling; typo in in checking
-       Cnf for CopyChanges flag and was calling non-existent function
-       copy_file.
-
-       * utils.py (copy): new function; clone of move without the
-       unlink().
-
-2000-11-25  James Troup  <james@nocrew.org>
-
-       * utils.py (build_file_list): handle non-US prefixes properly
-       (i.e. 'non-US' -> 'non-US/main' and 'non-US/libs' -> 'non-US/main'
-       + 'libs' not 'non-US/libs').
-       (send_mail): add '-odq' to sendmail invocation to avoid DNS lookup
-       delays.  This is possibly(/probably) exim speicifc and (like other
-       sendmail options) needs to be in the config file.
-
-2000-11-24  James Troup  <james@nocrew.org>
-
-       * rhona (check_sources): we need file id from dsc_files; not id.
-       Handle non .dsc source files being re-referenced in dsc_files.
-
-       * katie (in_override_p): strip out any 'non-US' prefix.
-       (check_files): use utils.where_am_i() rather than hardcoding.
-       (check_files): validate the component.
-       (install): use utils.where_am_i() rather than hardcoding.
-       (install): fix mail to go to actual recepient.
-       (reject): likewise.
-       (manual_reject): likewise.
-       (acknowledge_new): likewise.
-       (announce): likewise.
-
-       * db_access.py (get_component_id): ignore case when searching for
-       the component and don't crash if the component can't be found, but
-       return -1.
-       (get_location_id): handle -1 from get_component_id().
-
-       * jenna (generate_src_list): don't bring 'suite' into our big
-       multi-table-joining select as we already know the 'suite_id'.
-       (generate_bin_list): likewise.
-
-       * neve (main): don't quit if not on ftp-master.
-       (process_packages): remove unused variable 'suite_codename'.
-
-       * utils.py (move): actually move the file.
-       (build_file_list): handle non-US prefixes in the section.
-
-       * catherine (main): use which_conf_file().
-       * charisma (main): likewise.
-       * heidi (main): likewise.
-       * jenna (main): likewise.
-       * katie (main): likewise.
-       * neve (main): likewise.
-       * rhona (main): likewise.
-
-       * utils.py (where_am_i): new routine; determines the archive as
-       understood by other 'dak' programs.
-       (which_conf_file): new routine; determines the conf file to read.
-
-2000-11-17  James Troup  <james@nocrew.org>
-
-       * katie (install): fix where .changes files for proposed-updates
-       go.
-
-2000-11-04  James Troup  <james@nocrew.org>
-
-       * jenna (main): handle architecture properly if no
-       -a/--architecture argument is given, i.e. reset architecture with
-       the values for the suite for each suite.
-
-       * Add apt_pkg.init() to the start of all scripts as it's now
-       required by python-apt.
-
-2000-10-29  James Troup  <james@nocrew.org>
-
-       * jenna (generate_bin_list): take an additional argument 'type'
-       and use it in the SELECT.
-       (main): if processing component 'main', process udebs and debs.
-
-       * neve (process_packages): set up 'type' in 'binaries' (by
-       assuming .deb).
-
-       * katie (re_isadeb): accept ".udeb" or ".deb" as a file ending.
-       (check_files): set up files[file]["dbtype"].
-       (install): use files[file]["dbtype"] to set up the 'type' field in
-       the 'binaries' table.
-
-       * init_pool.sql: add a 'type' field to the 'binaries' table to
-       distinguisgh between ".udeb" and ".deb" files.
-
-       * utils.py (move): scrap basename() usage; use a "dir_p(dest) :
-       dest ? dirname(dest)" type check instead.
-
-       * katie (check_dsc): handle the case of an .orig.tar.gz not found
-       in the pool without crashing.  Also handle the case of being asked
-       to look for something other than an .orig.tar.gz in the pool.
-
-2000-10-26  James Troup  <james@nocrew.org>
-
-       * katie (install): fix filenames put into files table during
-       poolification of legacy source.
-
-       * utils.py (move): work around a bug in os.path.basename() which
-       cunningly returns '' if there is a trailing slash on the path
-       passed to it.
-
-       * katie (check_dsc): Remove more cruft.  If we find the
-       .orig.tar.gz in the pool and it's in a legacy (or legacy-mixed)
-       location, make a note of that so we can fix things in install().
-       (install): as above.  Move any old source out of legacy locations
-       so that 'apt-get source' will work.
-       (process_it): reset the flag that indicates to install that the
-       source needs moved.
-
-       * cron.daily: more.  Nowhere near complete yet though.
-
-       * katie (install): don't run os.makedirs, a) utils.move() does
-       this now, b) we weren't removing the user's umask and were
-       creating dirs with SNAFU permissions.
-       (check_dsc): rewrite the .orig.tar.gz handling to take into
-       account, err, package pools.  i.e. look anywhere in the pool
-       rather than faffing around with two simple paths.
-
-       * neve (process_sources): add the .dsc to dsc_files too.
-
-2000-10-25  James Troup  <james@nocrew.org>
-
-       * neve (process_sources): don't duplicate .orig.tar.gz's.
-
-2000-10-23  James Troup  <james@nocrew.org>
-
-       * utils.py (re_extract_src_version): moved here.
-
-       * neve: move re_extract_src_version to utils.
-       (process_packages): reflect change.
-
-       * katie (install): reflect change.
-
-2000-10-19  James Troup  <james@nocrew.org>
-
-       * jenna (generate_src_list): handle locations with null
-       components.
-       (generate_bin_list): likewise.
-
diff --git a/ChangeLog.old b/ChangeLog.old
new file mode 100644 (file)
index 0000000..1513626
--- /dev/null
@@ -0,0 +1,5873 @@
+2008-12-31  Joerg Jaspert  <joerg@debian.org>
+
+       * dak/queue_report.py (process_changes_files): Actually use the
+       right changes filename
+
+2008-12-30  Michael Casadevall  <sonicmctails@gmail.com>
+
+       * src/sql-aptvc.cpp     - Fixed to work on modern postgresql version
+
+       * src/Makefile          - Gave it a brain on finding postgres headers
+
+        * queue-report.py      - Added changes file to the 822 output for QA team
+
+2008-12-30  Joerg Jaspert  <joerg@debian.org>
+
+       * config/debian/cron.hourly: Generate the 822 format for accepted,
+       new, byhand and proposed-updates
+
+2008-12-30  Michael Casadevall <sonicmctails@gmail.com>
+
+       * dak/queue_report.py   - Added directories option to queue report
+
+2008-12-28  Frank Lichtenheld  <djpig@debian.org>
+
+       * dak/override.py (main): Handle source-only packages better
+
+2008-12-26  Michael Casadevall <sonicmctails@gmail.com>
+
+       * dak/queue_report.py - Added Last Modified in asctime() for QA team
+
+2008-12-23  Michael Casadevall <sonicmctails@gmail.com>
+
+        * dak/queue_report.py - Added 822 output format
+
+        * dak/queue_report.py - Fixed display of BYHAND packages
+
+        * dak/queue_report.py - Added queue field
+
+        * config/debian/dak.conf - Added 822 output location
+
+        * dak/process_accepted.py - Added orig.tar.gz copying when going
+          inbetween two components
+
+2008-12-23  Joerg Jaspert  <joerg@debian.org>
+
+       * dak/make_suite_file_list.py (stable_dislocation_p): Removed
+
+       * config/debian/dak.conf, config/debian-security/dak.conf: Remove "StableDislocationSupport "false";"
+
+2008-12-19  Joerg Jaspert  <joerg@debian.org>
+
+       * daklib/utils.py: move the html escape stuff here.
+
+       * dak/examine_package.py: Remove the html escape stuff.
+
+       * dak/queue_report.py: lotsa html changes to get more info on the
+       page and to get Tinchos css foo working.
+
+       * web/style.css: Added new stuff from Tincho
+
+2008-12-18  Philipp Kern  <pkern@debian.org>
+
+       * config/debian-security/cron.buildd: simplify wanna-build update
+       by calling a trigger script on the wanna-build host
+       * config/debian-security/cron.daily: no need to refresh
+       packages-arch-specific anymore
+
+2008-12-16  Joerg Jaspert  <joerg@debian.org>
+
+       * config/debian/cron.dinstall: Run logs.py as last command before
+       we mail the log.
+
+       * tools/logs.py: Added script from Thomas.
+       Modifications from me:
+        - Use path entries that fit ftpmaster dak user
+        - Make the bz2 extension optional for log files, so we can run it
+       out of cron.dinstall, where it is not yet compressed.
+        - Also show the two largest time killers in the totals graph.
+        - do not drop old entries from the cachefile
+        - fiddle with the color palette
+
+2008-12-15  Joerg Jaspert  <joerg@debian.org>
+
+       * config/debian/cron.hourly: Call the removals.pl
+
+2008-12-09  Joerg Jaspert  <joerg@debian.org>
+
+       * config/debian/cron.hourly: Added queue_rss.py to hourly cron.
+
+2008-12-09  Filippo Giunchedi <filippo@debian.org>
+
+       * tools/queue_rss.py: Added, generates RSS feeds of NEW.
+
+2008-12-09  Philipp Kern  <pkern@debian.org>
+
+       * daklib/queue.py (cross_suite_version_check): add an additional
+       parameter to specify if an upload is sourceful or not; do not reject
+       uploads that do not satisfy the "must be newer than" criteria and
+       are binary-only
+       * daklib/queue.py (check_source_against_db, check_binary_against_db):
+       invoke cross_suite_version_check as above
+
+2008-12-04  Philipp Kern  <pkern@debian.org>
+
+       * dak/process_new.py (recheck): call reject for
+       Upload.check_{binary,source}_against_db with an empty prefix to not
+       reject on warnings
+
+2008-11-30  Philipp Kern  <pkern@debian.org>
+
+       * dak/process_unchecked.py (do_stableupdate, do_oldstableupdate):
+       move files to NEW for {old,}stable-proposed-updates world-readable
+       (Closes: #368056)
+
+2008-11-30  Joerg Jaspert  <joerg@debian.org>
+
+       * config/debian/apt.conf: Lets generate experimental content
+       files.
+
+       * dak/daklib/queue.py (Upload.cross_suite_version_check): Add a
+       few () to make cross_suite_version_check finally work as
+       intended (well, we hope). Thanks to Philipp Kern for spotting this.
+
+2008-11-28  Mark Hymers  <mhy@debian.org>
+
+       * dak/new_security_install.py: Don't attempt to delete the .changes files
+       which have already been moved to queue/done by now.
+
+2008-11-27  Mark Hymers  <mhy@debian.org>
+
+       * dak/new_security_install.py: Attempt to tidy up the buildd queue.  The
+       buildd team believes that the fact that the packages are in the security
+       pool after this point should be good enough.
+
+2008-11-25  Joerg Jaspert  <joerg@debian.org>
+
+       * dak/process_unchecked.py (queue_(un)embargo): (Hopefully) enable
+       sending mails again, which got broken when testing-security
+       handling was (not completly correctly) implemented. Closes: #440004
+
+2008-11-24  Joerg Jaspert  <joerg@debian.org>
+
+       * dak/process_unchecked.py (check_signed_by_key): remove the
+       binary-upload restriction stuff. unused.
+
+       * config/debian-security/apt.conf.buildd: byebye sarge
+
+       * scripts/nfu/get-w-b-db: remove m68k
+
+       * scripts/debian/update-ftpstats: remove m68k
+
+       * config/debian/dak.conf: remove m68k
+       remove the binary-upload-restrictions
+
+       * config/debian/vars (archs): Remove m68k
+
+2008-11-23  Joerg Jaspert  <joerg@debian.org>
+
+       * dak/process_unchecked.py (check_files): fix this armel mess
+
+       * config/debian-security/dak.conf: Set ValidTime
+
+       * config/debian-security/cron.weekly: Added
+
+2008-11-17  Joerg Jaspert  <joerg@debian.org>
+
+       * dak/security-install.py: Removed, no longer in use.
+
+2008-11-16  Joerg Jaspert  <joerg@debian.org>
+
+       * scripts/debian/mkfilesindices: useless typical, doesnt have
+       i18n/ dirs. Force them in (i hope).
+
+2008-11-15  Thomas Viehmann <tv@beamnet.de>
+
+       * dak/show_deferred.py: handle uploads that do not close bugs
+
+2008-11-11  Joerg Jaspert  <joerg@debian.org>
+
+       * config/debian/dak.conf: good bye oldstable/o-p-u
+
+2008-11-10  Joerg Jaspert  <joerg@debian.org>
+
+       * config/debian/cron.unchecked: how about us ignoring bugs.d.o
+       down? It's not like it is time critical or something to transfer
+       this stuff, it doesn't hurt to have it there a bit later...
+
+2008-11-08  Joerg Jaspert  <joerg@debian.org>
+
+       * config/debian/cron.hourly: Create new tracefile format.
+
+2008-11-05  Joerg Jaspert  <joerg@debian.org>
+
+       * dak/new_security_install.py (_do_Approve): This sudo call
+       definitely wants the -H option.
+
+2008-11-01  Joerg Jaspert  <joerg@debian.org>
+
+       * dak/process_unchecked.py (check_files): Also check the
+       upload_suite for uploads. I guess we could kill the default_suite
+       totally, but for now we just look into the upload_suite one too.
+
+       * config/debian-security/dak.conf: Let DefaultSuite be stable
+
+2008-10-27  Joerg Jaspert  <joerg@debian.org>
+
+       * scripts/debian/mkfilesindices: Remove oldstable
+
+       * config/debian/vars: Remove sarge
+
+       * config/debian/dak.conf: Untouchable o-p-u, until we removed all
+       of sarge and its files.
+
+       * config/debian/apt.conf.oldstable: Removed
+
+       * config/debian/apt.conf: Remove oldstable
+
+2008-10-14  Thomas Viehmann <tv@beamnet.de>
+
+       * dak/show_deferred.py: produce .changes and improve status
+
+2008-10-07  Joerg Jaspert  <joerg@debian.org>
+
+       * config/debian/cron.dinstall: Only keep the last 60 days of
+       dinstall logfiles on disc.
+
+2008-10-05  Thomas Viehmann <tv@beamnet.de>
+
+        * daklib/database.py: added get_suites
+       * dak/dak.py, dak/show_deferred.py: add show-deferred to dak.
+
+2008-09-23  Joerg Jaspert  <joerg@debian.org>
+
+       * config/debian/dak.conf: Add the validtime fields, set to 7
+       days.
+
+       * dak/generate_releases.py (main): Add a "Valid-Until" line into
+       our release files, meaning "$receiver shouldn't trust this files
+       after that date". Should be used by apt and similar tools to
+       detect some kind of MITM attacks, see #499897
+
+2008-09-21  Joerg Jaspert  <joerg@debian.org>
+
+       * config/debian/cron.hourly: Generate the DEFERRED queue
+       overview.
+
+2008-09-13  Philipp Kern  <pkern@debian.org>
+
+       * dak/queue.py (dump_vars): make .dak u,g=rw,o=r; James'
+       assumption (as stated in 2002-05-18's ChangeLog entry)
+       was that people will use the information therein albeit
+       it is "just" a duplication of information present in
+       other control files; people should still not use it
+       as source of information but access to those files makes
+       dak debugging easier and there is no leak of sensitive
+       information involved
+
+2008-09-12  Philipp Kern  <pkern@debian.org>
+
+       * dak/new_security_install.py (actually_upload): remove
+       oldstable-security/amd64 check; Etch, as the next oldstable,
+       already had proper amd64 support
+
+2008-09-12  Joerg Jaspert  <joerg@debian.org>
+
+       * scripts/debian/update-pseudopackages.sh: s/i/file/
+
+2008-09-11  Joerg Jaspert  <joerg@debian.org>
+
+       * config/debian/pseudo-packages.description, ...maintainers:
+       Removed, now with the bts people
+
+       * scripts/debian/update-pseudopackages.sh: Added, fetching
+       pseudo-packages from new bts location
+
+       * scripts/debian/mkmaintainers: Use new location
+
+2008-09-08  Philipp Kern  <pkern@debian.org>
+
+       * dak/check_archive.py (check_checksums): rewind the files
+       before the sha1sum/sha256sum checks as they got seeked by
+       md5sum
+
+       * daklib/utils.py (build_file_list): do not die on very
+       old dsc files without format header
+
+2008-09-07  Philipp Kern  <pkern@debian.org>
+
+       * daklib/utils.py (check_hash): try..except..finally only
+       works on python >=2.5.
+
+       * dak/process_accepted.py (install): better use dsc_file
+       instead of the (for the loop iteration) static file
+       variable
+
+2008-09-07  Philipp Kern  <pkern@debian.org>
+
+       * daklib/utils.py (check_hash): change the comment and warn
+       if a file is not found when checking the hashes (i.e. when
+       it is probably in the pool)
+
+       * daklib/utils.py (check_size): do not bail out if the file
+       is not found, because it may be in the pool
+
+       * dak/process_accepted.py (install): bail out and skip the
+       upload when ensure_hashes fails, print the rejection messages
+       as warnings
+
+2008-08-28  Philipp Kern  <pkern@debian.org>
+
+       * daklib/utils.py (check_hashes): adapt to different API, check
+       sizes separately
+
+       * daklib/utils.py (parse_changes, parse_deb822): refactor
+       the string-based logic of parse_changes into a new function
+       parse_deb822; parse_changes itself remains file-based
+
+       * daklib/utils.py (hash_key): gives the key of a hash in the
+       files dict
+
+       * daklib/utils.py (create_hash, check_size): made more readable
+
+       * daklib/utils.py (check_hash): just check the hashes and complain
+       about missing checksums
+
+       * daklib/utils.py (check_hash_fields): function to reject unknown
+       checksums fields
+
+       * daklib/utils.py (_ensure_changes_hash, _ensure_dsc_hash): helper
+       functions for ensure_hashes; check their corresponding manifests'
+       hashes
+
+       * daklib/utils.py (ensure_hashes): retrieve the checksums fields
+       from the original filecontents blob so that they do not need to
+       be present in the .dak; refactored the actual checks by calling
+       the aforementioned helper functions
+
+       * daklib/utils.py (parse_checksums): parse a given checksums field
+       in a manifest and insert the values found into the files dict,
+       checking the file sizes on the way
+
+2008-09-06  Philipp Kern  <pkern@debian.org>
+
+       * dak/process_new.py (is_source_in_queue_dir): Access the right
+       variable to check if the given entry in the queue is the sourceful
+       upload we are looking for.
+
+2008-09-02  Joerg Jaspert  <joerg@debian.org>
+
+       * config/debian/pseudo-packages.description: Added debian-i18n and
+       buildd.emdebian.org
+
+       * dak/process_new.py (_accept): Fix Philipps new helper function
+       to not break by moving Upload.build_summaries there.
+
+2008-08-31  Philipp Kern  <pkern@debian.org>
+
+       * dak/process_new.py (_accept): new helper function to accept
+       an upload regularly, obeying no-action if set
+       * dak/process_new.py (do_accept): use _accept
+       * dak/process_new.py (do_accept_stableupdate): bail out in else
+       on binary uploads, in case we missed something; use the _accept
+       helper
+
+2008-08-30  Philipp Kern  <pkern@debian.org>
+
+       * dak/process_new.py (is_source_in_queue_dir): join the queue path
+       because os.listdir entries come with their path stripped
+
+2008-08-30  Philipp Kern  <pkern@debian.org>
+
+       * dak/process_new.py (do_accept_stableupdate): state what we intend
+       to do
+
+2008-08-26  Philipp Kern  <pkern@debian.org>
+
+       * dak/process_new.py (is_source_in_queue_dir): fix variable usage
+       * dak/process_new.py (move_to_holding): just state what we intend
+       to do in no-action mode
+       * dak/process_new.py (do_accept_stableupdate): fetch summaries,
+       fix invokation of is_source_in_queue_dir, actually accept sourceful
+       uploads in p-u holding
+
+2008-08-26  Philipp Kern  <pkern@debian.org>
+
+       * dak/process_new.py (do_accept): do not try to free the unchecked
+       lockfile in no-action mode
+
+2008-08-16  Joerg Jaspert  <joerg@debian.org>
+
+       * config/debian/cron.dinstall: We dont want i18n to ever fail
+       dinstall, add a || true
+
+2008-08-15  Mark Hymers  <mhy@debian.org>
+
+       * daklib/utils.py: Actually import a module before using it.
+
+       * daklib/utils.py: Actually check we have basedict before trying to
+       use it.
+
+       *  dak/process_accepted.py, dak/process_unchecked.py,
+       daklib/database.py: Don't change get_files_id to use sha1sum and
+       sha256sum.
+
+       * setup/init_pool.sql, dak/check_archive.py, dak/decode_dot_dak.py,
+       dak/process_accepted.py, dak/process_unchecked.py, daklib/database.py,
+       daklib/queue.py, daklib/utils.py: Attempt to add sha1sum and
+       sha256sums into the database.  The complication is that we have to
+       keep backwards compatibility with the .dak files already in existance.
+       Note that import_archive hasn't been hacked to deal with this yet.
+
+2008-08-14  Joerg Jaspert  <joerg@debian.org>
+
+       * config/debian/cron.dinstall: Added the i18n retrieval of package
+       description translations
+
+2008-08-12  Joerg Jaspert  <joerg@debian.org>
+
+       * config/debian/cron.dinstall: Complicate the i18n export a little
+       by using date/hour based directories which we then link into the
+       web view. They contain a signed timestamp file now, which means
+       the i18n people can take a long time to generate files, yet we
+       still know exactly on which dataset their data is based on, and
+       can then verify it with that. Ensures we only get descriptions for
+       packages we know off (or knew of in the past 2 days).
+
+2008-08-11  Joerg Jaspert  <joerg@debian.org>
+
+       * web/dinstall.html: Added
+
+       * config/debian/dak.conf: Added back the pgp keyrings for now, as
+       it seems that we should keep it for a few more days, until we
+       somehow got ll those oldtimers to get a newer key into the
+       keyring. Unfortunately our logic to look for uploads done from
+       that keyring wasnt the most perfect one, so well, it is actually
+       used. Damn.
+
+2008-08-09  Joerg Jaspert  <joerg@debian.org>
+
+       * config/debian/dak.conf: No longer use the pgp keyring - no
+       uploads recorded for any of the pgp keys for a long time.
+
+       * config/debian/cron.dinstall: Export the i18n foo.
+
+2008-08-08  Joerg Jaspert  <joerg@debian.org>
+
+       * config/debian/cron.dinstall: Create a hardlinked tree of the
+       ftp/ in mirror/ so we have more atomic mirror updates for the
+       buildds
+
+       * config/debian/cron.unchecked: Added signing of buildd incoming
+
+2008-08-07  Philipp Kern  <pkern@debian.org>
+
+       * dak/process_new.py (do_accept): handle uploads to (oldstable-)
+         proposed-updates differently and put them into p-u holding
+         for review instead of unconditionally accepting them into
+         p-u proper; additional care needed to be taken to look
+         out for the source if a binary-only upload is being handled
+
+2008-08-07  Joerg Jaspert  <joerg@debian.org>
+
+       * dak/cruft_report.py (parse_nfu): call utils.warn instead of warn
+       (main): Only do the nfu stuff if nfu is a check we want to run
+       later.
+       (main): And another place where we dont want to do nfu foo unless
+       we need nfu
+
+       * dak/make_suite_file_list.py (main): Fix a bug that has been
+       there for ages, but "just" never triggered.
+
+2008-08-07  Stephen Gran  <sgran@debian.org>
+
+       * Drop use of exec to eval variable interpolation
+2008-08-07  Joerg Jaspert  <joerg@debian.org>
+
+       * dak/process_accepted.py (install): Error out with the new
+       exception if we dont know the source package for a file we want to
+       install. Shouldn't ever hit us, but better safe than sorry.
+
+       * daklib/dak_exceptions.py (dakerrors): new exception - no source field.
+
+2008-08-05  Joerg Jaspert  <joerg@debian.org>
+
+       * config/debian/cron.unchecked: disable the ssh-move insanity (and
+       as soon as rietz is back online - replace it with a one-line scp
+       or rsync statement followed by a one-line rm)
+       And now replaced this 128 line perl "not-invented-here" with a
+       one-line rsync command, using a feature rsync only understands
+       since sarge - damn new-fangled technology.
+
+2008-08-05  Joachim Breitner <nomeata@debian.org>
+
+       * dak/cruft_report.py: In full mode, report out-of-date binaries on
+       architectures that have set Not-For-Us for that package.
+
+       * scripts/nfu/get-w-b-db: Script to fetch the wanna-build database
+       dump from http://buildd.debian.org/
+
+       * config/debian/cron.weekly: Run the above script
+
+2008-08-03  Mark Hymers <mhy@debian.org>
+
+       * dak/process_new.py: Apply jvw's patch so that process_new shows
+       packages which need binary uploads sorted earlier than other packages.
+
+2008-07-26  Joerg Jaspert  <joerg@debian.org>
+
+       * templates/reject-proposed-updates.rejected,dak/reject_proposed_updates.py:
+       applied a patch by luk modifying the stable rejection mails to fit
+       reality a bit more
+
+       * config/debian/dak.conf: no m68k in testing, so no m68k in t-p-u
+       r4 now
+
+2008-06-19  Thomas Viehmann  <tv@beamnet.de>
+
+       * dak/process_unchecked.py (check_dsc,check_hashes): Catch
+       UnknownFormatError and reject
+
+2008-06-15  Joerg Jaspert  <joerg@debian.org>
+
+       * config/debian/cron.weekly: Work around a git bug until git is
+       fixed upstream and the fix is on backports.org
+
+       * config/debian/cron.dinstall: (various ssh calls): Make them use
+       batchmode/connect/setuptimeout to not take too long with
+       connections... Also || true them, no need to die in dinstall if
+       one host isn't reachable.
+       Also do not die when the ldap server is unreachable, just ignore
+       that error.
+
+       * README: Updated mailing list location
+
+2008-06-14  Otavio Salvador  <otavio@debian.org>
+
+       * docs/manpages/clean-suites.1.sgml: Minor typo fix
+
+       * dak/import_archive.py: Add support to udeb packages
+
+       * dak/control_suite.py (main): Handle SystemError exception in
+       case of a incompatible commandline parameter
+
+       * dak/check_overrides.py (main): Use case-insensitive comparing
+       for codename
+
+2008-06-14  Joerg Jaspert  <joerg@debian.org>
+
+       * scripts/debian/byhand-task: Merged patch from Frans Pop to
+       fail on byhand-task uploads if they do not go to unstable.
+
+       * config/debian/cron.weekly: Do a little git cleanup work too.
+
+       * config/debian/cron.buildd: Add batchmode and also
+       Connect/SetupTimeout parameters to ssh
+
+       * config/debian/cron.dinstall (POSTDUMP): Compress all
+       uncompressed psql backups
+
+2008-06-08  Joerg Jaspert  <joerg@debian.org>
+
+       * dak/process_unchecked.py (check_urgency): Lowercase urgency
+       before we (eventually) warn on it. Patch taken from Russ Allbery.
+
+2008-06-01  Otavio Salvador  <otavio@debian.org>
+
+       * daklib/queue.py (check_valid): allow debian-installer specific
+       sources to have 'debian-installer' section.
+
+2008-05-28  Frans Pop  <fjp@debian.org>
+
+       * add autobyhand support for task overrides (from tasksel)
+
+2008-05-27  Joerg Jaspert  <joerg@debian.org>
+
+       * config/debian/pseudo-packages.maintainers: Change ftp.debian.org
+       pseudopackage maintainer name.
+
+2008-05-12  Joerg Jaspert  <joerg@debian.org>
+
+       * dak/transitions.py: use yaml.dump instead of syck.dump, as syck
+       seems to have a bug in its dump(), causing it to write illegal entries
+       And also do this for load.
+
+2008-05-10  Stephen Gran   <sgran@debian.org>
+       * tools/debianqueued-0.9/debianqueued: First pass at a send_mail
+         implementation that sucks less
+       * Update debian/control to reflect new perl dependency
+
+2008-05-09  Joerg Jaspert  <joerg@debian.org>
+
+       * dak/override.py (main): substitute value in X-Debian-Package
+       header
+
+       * templates/override.bug-close: Add X-Debian-Package header
+       * templates/reject-proposed-updates.rejected: dito
+       * templates/queue.rejected: dito
+       * templates/process-unchecked.new: dito
+       * templates/process-unchecked.bug-nmu-fixed: dito
+       * templates/process-unchecked.bug-experimental-fixed: dito
+       * templates/process-unchecked.bug-close: dito
+       * templates/process-unchecked.announce: dito
+       * templates/process-unchecked.accepted: dito
+       * templates/process-new.prod: dito
+       * templates/process-accepted.unaccept: dito
+       * templates/process-accepted.install: dito
+       * templates/process-unchecked.override-disparity: dito
+
+2008-05-08  Joerg Jaspert  <joerg@debian.org>
+
+       * templates/override.bug-close: Add X-Debian header
+       * templates/rm.bug-close: dito
+       * templates/reject-proposed-updates.rejected: dito
+       * templates/queue.rejected: dito
+       * templates/process-unchecked.new: dito
+       * templates/process-unchecked.bug-nmu-fixed: dito
+       * templates/process-unchecked.bug-experimental-fixed: dito
+       * templates/process-unchecked.bug-close: dito
+       * templates/process-unchecked.announce: dito
+       * templates/process-unchecked.accepted: dito
+       * templates/process-new.prod: dito
+       * templates/process-accepted.unaccept: dito
+       * templates/process-accepted.install: dito
+       * templates/process-unchecked.override-disparity: dito, but also
+       mention that people should include the package lists with the
+       override disparities.
+
+2008-05-06  Joerg Jaspert  <joerg@debian.org>
+
+       * config/debian/cron.dinstall: Put the timestamp stuff into an own
+       function, call that from everywhere. Also change the timestamp
+       format to not be local dependent.
+
+2008-05-05  Joerg Jaspert  <joerg@debian.org>
+
+       * daklib/dak_exceptions.py (dakerrors): add TransitionsError
+       * dak/transitions.py: Use it, instead of the own definition
+
+2008-05-05  Mark Hymers  <mhy@debian.org>
+
+       * daklib/dak_exceptions.py: Add a default message and tidy up our string
+       representation
+
+2008-05-05  Joerg Jaspert  <joerg@debian.org>
+
+       * daklib/dak_exceptions.py: New file, central place for all those
+       own exceptions dak may raise.
+
+       * daklib/utils.py: Use dak_exceptions and delete all those string
+       exception raising stuff, which is depcreated.
+       During that delete the unknown_hostname_exc, as it wasnt used.
+
+       * dak/import_archive.py: use the new Exception class
+       * dak/rm.py: dito
+       * dak/generate_releases.py: dito
+       * dak/queue_report.py: dito
+       * daklib/queue.py: dito
+
+2008-05-04  Joerg Jaspert  <joerg@debian.org>
+
+       * daklib/queue.py: Various pychecker cleanups
+
+       * dak/import_keyring.py: Remove unused daklib.logging and Logger
+       and add the actually used daklib/utils
+
+       * dak/examine_package.py: remove daklib.queue import, never used
+
+       * dak/check_proposed_updates.py: Import stuff from daklib as
+       "import daklib.foo as foo"
+       * dak/clean_proposed_updates.py: likewise
+       * dak/clean_queues.py: likewise
+       * dak/clean_suites.py: likewise
+       * dak/compare_suites.py: likewise
+       * dak/cruft_report.py: likewise
+       (get_suite_binaries): Seperated in own function, out of main. More
+       of main should be splitted. (Or well, cruft_report redesigned a
+       little, so its easier to run on multiple suites with differing tests)
+
+       * dak/examine_package.py: likewise
+       * dak/find_null_maintainers.py: likewise
+       * dak/generate_index_diffs.py: likewise
+       * dak/generate_releases.py: likewise
+       * dak/import_archive.py: likewise
+       * dak/import_ldap_fingerprints.py: likewise
+       * dak/import_users_from_passwd.py: likewise
+       * dak/init_db.py: likewise
+       * dak/init_dirs.py: likewise
+       * dak/ls.py: likewise
+       * dak/make_maintainers.py: likewise
+       * dak/make_overrides.py: likewise
+       * dak/make_suite_file_list.py: likewise
+       * dak/new_security_install.py: likewise
+       * dak/override.py: likewise
+       * dak/process_accepted.py: likewise
+       * dak/process_new.py: likewise
+       * dak/process_unchecked.py: likewise
+       * dak/rm.py: likewise
+       * dak/show_new.py: likewise
+       * dak/split_done.py: likewise
+       * dak/stats.py: likewise
+       * dak/transitions.py: likewise
+
+       * dak/check_archive.py (check_files_not_symlinks): Remove
+       long-time unused and commented code. Import stuff from daklib as
+       "import daklib.foo as foo"
+
+2008-05-04  Thomas Viehmann  <tv@beamnet.de>
+
+       * dak/process_unchecked.py (check_signed_by_key): cater for uid_email
+       None in sponsor notification
+
+2008-05-03  Joerg Jaspert  <joerg@debian.org>
+
+       * dak/examine_package.py: clean up pychecker warnings (merged with
+       Thomas changes to the NEW display)
+
+2008-05-03  Mark Hymers <mhy@debian.org>
+
+       * dak/check_archive.py: clean up pychecker warnings
+       * dak/check_overrides.py: likewise
+       * dak/check_proposed_updates.py: likewise
+       * dak/clean_proposed_updates.py: likewise
+       * dak/clean_queues.py: likewise
+       * dak/control_overrides.py: likewise
+       * dak/control_suite.py: likewise
+       * dak/decode_dot_dak.py: likewise
+       * dak/examine_package.py: likewise
+       * dak/process_new.py: likewise
+       * dak/process_unchecked.py: likewise
+       * dak/queue_report.py: likewise
+       * dak/reject_proposed_updates.py: likewise
+       * dak/security_install.py: likewise
+       * dak/show_new.py: likewise
+       * dak/stats.py: likewise
+       * dak/symlink_dists.py: likewise
+       * dak/transitions.py: likewise
+>>>>>>> sec-merge:ChangeLog
+
+2008-05-03  Joerg Jaspert  <joerg@debian.org>
+
+       * config/debian/cron.daily: Rename to
+       * config/debian/cron.dinstall: this, as its not really something run
+       daily for some time now. And while dinstall is an OLD name, its
+       recognized pretty well within Debian
+       Also add some more timing information
+       Do not allow automated [o-]p-u-new processing to break dinstall
+
+2008-05-03  Thomas Viehmann  <tv@beamnet.de>
+
+       * web/,web/style.css: add web dir and current style.css
+
+       * dak/examine_package.py, dak/show_new.py: improve NEW html pages,
+       based on mock-up by M. Ferrari.
+       remove Checksums-* from examine-package output
+
+2008-05-03  Thomas Viehmann  <tv@beamnet.de>
+
+       * dak/process_unchecked.py (check_hashes): Reject on error while
+       parsing Checksums-*.
+
+2008-05-02  Joerg Jaspert  <joerg@debian.org>
+
+       * config/debian/pseudo-packages*: Removed listarchives, closes #468667
+       added wiki.debian.org (currently pointing to debian-www), closes #194206
+       added security-tracker, closes #436152
+       added release.debian.org, closes #451005
+
+       * config/debian/cron.buildd: Cleanup unreachable code. (If someone
+       still wants it - its in revision control...)
+
+       * config/debian/cron.daily: Modify call to update-ftpstats to only
+       use files log/2*, instead of log/*, so it ignores the new cron/
+       subdir. Makes sure it can't get confused, and is also safe for
+       nearly thousand years. If this code is really in use in year 3000,
+       im sure people can adjust it! :)
+
+       * config/debian/vars: Add logdir as a place for cronjob log output
+
+       * config/debian/cron.daily: Use a logfile and be more verbose of
+       whats going on.
+         Also moved the commented VACUUM ; VACUUM ANALYZE calls over to
+       cron.weekly, ...
+       * config/debian/cron.weekly: likewise,
+         ... and activate those calls again. Once a week, as an
+       additional safety bet to be sure the stuff does get run is ok,
+       even if we have autovacuum by default.
+
+2008-05-02  Thomas Viehmann  <tv@beamnet.de>
+
+       * dak/process_unchecked.py (check_hashes): fix typo in
+         checksum reject message.
+
+2008-05-02  Joerg Jaspert  <joerg@debian.org>
+
+       * config/debian/extensions.py: used reindent.py from the python
+       2.x source examples to get all dak code use the same indentation
+       style, no longer a mix of 4 spaces / 1 tab.
+       * dak/check_archive.py: likewise
+       * dak/check_overrides.py: likewise
+       * dak/check_proposed_updates.py: likewise
+       * dak/clean_proposed_updates.py: likewise
+       * dak/clean_queues.py: likewise
+       * dak/clean_suites.py: likewise
+       * dak/compare_suites.py: likewise
+       * dak/control_overrides.py: likewise
+       * dak/control_suite.py: likewise
+       * dak/cruft_report.py: likewise
+       * dak/dak.py: likewise
+       * dak/decode_dot_dak.py: likewise
+       * dak/examine_package.py: likewise
+       * dak/find_null_maintainers.py: likewise
+       * dak/generate_index_diffs.py: likewise
+       * dak/generate_releases.py: likewise
+       * dak/import_archive.py: likewise
+       * dak/import_keyring.py: likewise
+       * dak/import_ldap_fingerprints.py: likewise
+       * dak/import_users_from_passwd.py: likewise
+       * dak/init_db.py: likewise
+       * dak/init_dirs.py: likewise
+       * dak/ls.py: likewise
+       * dak/make_maintainers.py: likewise
+       * dak/make_overrides.py: likewise
+       * dak/make_suite_file_list.py: likewise
+       * dak/mirror_split.py: likewise
+       * dak/new_security_install.py: likewise
+       * dak/override.py: likewise
+       * dak/poolize.py: likewise
+       * dak/process_accepted.py: likewise
+       * dak/process_new.py: likewise
+       * dak/process_unchecked.py: likewise
+       * dak/queue_report.py: likewise
+       * dak/reject_proposed_updates.py: likewise
+       * dak/rm.py: likewise
+       * dak/security_install.py: likewise
+       * dak/show_new.py: likewise
+       * dak/split_done.py: likewise
+       * dak/stats.py: likewise
+       * dak/symlink_dists.py: likewise
+       * dak/test/001/test.py: likewise
+       * dak/test/002/test.py: likewise
+       * dak/transitions.py: likewise
+       * daklib/extensions.py: likewise
+       * daklib/logging.py: likewise
+       * daklib/queue.py: likewise
+       * daklib/utils.py: likewise
+       * scripts/debian/insert_missing_changedby.py: likewise
+
+       * dak/process_new.py (recheck): Make the path check more robust,
+       so we no longer have to keep process_new seperate trees between
+       security and normal archive.
+
+2008-04-27  Joerg Jaspert  <joerg@debian.org>
+
+       * dak/process_accepted.py (Urgency_Log.__init__): Warn if the
+       configured path does not exist or is not writeable by us. Use a
+       tmp path if so, so we do not lose the urgencies in such cases.
+
+       * config/debian/dak.conf: Changed path for UrgencyLog
+       Same for the ReleaseTransitions file
+
+       * config/debian/cron.daily: Notify qa user on merkel of dinstall
+       start, Remove the britney call
+
+2008-04-26  Joerg Jaspert  <joerg@debian.org>
+
+       * dak/process_new.py: Call end() whenever we try to leave by
+       pressing Q
+
+       * config/debian/cron.daily: Also report NBS in experimental
+
+2008-04-25  Joerg Jaspert  <joerg@debian.org>
+
+       * dak/cruft_report.py (main): Make it possible to look at
+       experimental too, especially NBS
+
+       * dak/split_done.py (main): Only move files into their subdirs if
+       they are older than 30 days. That enables us to run this script as
+       part of a cronjob.
+
+       * config/debian/cron.weekly: Run dak split-done
+
+2008-04-23  Thomas Viehmann  <tviehmann@debian.org>
+
+       * dak/process_unchecked.py: add changes["sponsoremail"]
+         for sponsored uploads if desired
+       * daklib/queue.py: add changes["sponsoremail"] to
+         Subst["__MAINTAINER_TO__"] if present
+       * daklib/utils.py: add functions
+         is_email_alias to check which accounts allow email forwarding,
+         which_alias_file to find the alias file, and
+         gpg_get_key_addresses to find uid addresses for a given
+           fingerprint
+
+2008-04-22  Joerg Jaspert  <joerg@debian.org>
+
+       * setup/init_pool.sql: added a function/aggregate for the release
+       team to base some script on it.
+
+       * config/debian/cron.daily: push katie@merkel to immediately start
+       the sync of projectb there.
+
+2008-04-21  Joerg Jaspert  <joerg@debian.org>
+
+       * scripts/debian/expire_dumps: New script, expires old database
+       dumps, using a scheme to keep more of the recent dumps.
+
+       * config/debian/cron.daily: Use the new script. Also - compress
+       all files older than 7 days, instead of 30.
+
+       * dak/process_accepted.py (install): Do not break if a
+       source/maintainer combination is already in src_uploaders, "just"
+       warn us.
+
+2008-04-20  Thomas Viehmann  <tviehmann@debian.org>
+
+       * daklib/utils.py (build_file_list): Deal with "Format 3 style"
+       Format lines (ie. those having extra text appended).
+
+2008-04-19  Joerg Jaspert  <joerg@debian.org>
+
+       * dak/process_unchecked.py (check_files): Sanity check the
+       provides field, which closes #472783
+
+2008-04-18  Joerg Jaspert  <joerg@debian.org>
+
+       * config/debian/dak.conf: Add mapping stable-proposed-updates
+         -> proposed-updates.
+
+       * dak/transitions.py (load_transitions): Additionally check for
+       invalid package list indentation
+
+2008-04-17  Joerg Jaspert  <joerg@debian.org>
+
+       * config/debian/dak.conf: Add TempPath statement for the Release
+       Transitions script
+
+       * dak/transitions.py (temp_transitions_file): Use the TempPath
+       (write_transitions_from_file): Check if the file we should get our
+       transitions from is in our TempPath, error out if it isnt
+       (main): Check for TempPath existance
+
+2008-04-12  James Troup  <troup@debian.org>
+
+       * dak/clean_proposed_updates.py: add support for -s/--suite and
+       -n/--no-action.
+
+2008-04-11  Anthony Towns  <ajt@debian.org>
+
+       * dak/utils.py: build_file_list() extra parameters so it can
+       build a file list for checksums-foo fields. Don't use float() to
+       compare formats, because Format: 1.10 should compare greater than
+       Format: 1.9 (use "1.9".split(".",1) and tuple comparison instead)
+
+       * dak/process_unchecked.py: check_md5sum becomes check_hashes
+       and check_hash. If changes format is 1.8 or later, also check
+       checksums-sha1 and checksums-sha256 for both .changes and .dsc,
+       and reject on presence/absence of un/expected checksums-* fields.
+
+2008-04-07  Joerg Jaspert  <joerg@debian.org>
+
+       * daklib/utils.py (build_file_list): Check for dpkg .changes
+       adjusted to reject newer (and right now broken) 1.8 version, until
+       dpkg (or debsign) is fixed and doesn't produce invalid .changes anymore
+
+2008-03-22  Joerg Jaspert  <joerg@debian.org>
+
+       * dak/transitions.py (load_transitions): Check if all our keys are
+       defined, if there are only keys defined we want and also the types
+       of the various keys.
+
+2008-03-22  Anthony Towns  <ajt@debian.org>
+
+       * dak/edit_transitions.py: Add --import option.
+       Add --use-sudo option. Use fcntl locking for writing.
+       Move writing into a function (write_transitions).
+       Reinvoke self using sudo and --import if necessary.
+       Move temporary file creation into a function, use mkstemp.
+       Rename to "dak transitions".
+
+2008-03-21  Joerg Jaspert  <joerg@debian.org>
+
+       * dak/edit_transitions.py (edit_transitions): Use sudo to copy the
+       edited file back in place
+       (check_transitions): Use proper locking and also use sudo to copy
+       the new file in place
+
+2008-03-21  Anthony Towns <ajt@debian.org>
+
+       * config/debian/extensions.py: Add infrastructure for replacing
+       functions in dak modules; add upload blocking for dpkg.
+
+2008-03-12  Joerg Jaspert  <joerg@debian.org>
+
+       * dak/edit_transitions.py: Done a number of cleanups to make code
+       working. Also changed the way prompting/answering goes, to not
+       have to import daklib/queue.
+       (edit_transitions): When done with a successful edit - also print
+       a final overview about defined transitions
+
+2008-03-11  Joerg Jaspert  <joerg@debian.org>
+
+       * dak/process_unchecked.py: Import syck module directly, not "from
+       syck import *"
+       (check_transition): Do the check for sourceful upload in here
+       Also adjust the syck loading commands, rename new_vers to
+       expected, curvers to current, to make it more clear what they mean.
+
+       * daklib/database.py (get_suite_version): Renamed from
+       get_testing_version. Also changed the cache variables name
+
+       * The above changes are based on modifications from Anthony.
+
+       * dak/dak.py (init): Renamed check -> edit transitions
+
+       * dak/edit_transitions.py: Renamed from check_transitions.py
+       (main): Also rename new_vers/curvers to expected/current
+       Basically a nice rewrite, so it now does checks and edit,
+       depending on how you call it. Check also removes old transitions,
+       if user wants it.
+
+2008-03-02  Joerg Jaspert  <joerg@debian.org>
+
+       * debian/control (Suggests): Add python-syck to Depends:
+
+       * dak/dak.py (init): Tell it about check_transitions
+
+       * dak/check_transitions.py (usage): Added, checks the transitions
+       file (if any)
+
+       * daklib/database.py (get_testing_version): Added. Returns the
+       version for the source in testing, if any
+
+       * dak/process_unchecked.py (check_transition): Added. Checks if a
+       release team member defined a transition, and rejects based on
+       that data.
+       (process_it): Use it.
+       (check_transition): Warn on broken transitions file and return,
+       not doing anything.
+       (check_transition): Moved out of here, into daklib/queue
+       (process_it): Call check_transitions only if
+       changes[architecture] has source included.
+       (check_transition): Now call the database.get_testing_version
+
+2008-02-09  Christoph Berg <myon@debian.org>
+
+       * daklib/queue.py (get_type): fubar does not exist in global
+       namespace.
+
+       * setup/add_constraints.sql setup/init_pool.sql: Add changedby column
+       to source table, and move src_uploaders after source so the REFERNCES
+       clause works.
+       * dak/process_accepted.py (install): Fill the changedby column from
+       the information found in the .changes. This will allow to identify
+       NMUs and sponsored uploads more precisely in tools querying projectb.
+       * scripts/debian/insert_missing_changedby.py: Script to import yet
+       missing fields from filippo's uploads-history DB.
+
+2008-02-06  Joerg Jaspert  <joerg@debian.org>
+
+       * daklib/utils.py (check_signature): Make variable key available,
+       so we can access it.
+
+2008-01-07  Joerg Jaspert  <joerg@debian.org>
+
+       * dak/examine_package.py (check_deb): Remove linda call. It
+       provides no added benefit to lintian anymore.
+
+2008-01-07  Joerg Jaspert  <joerg@debian.org>
+
+       * dak/examine_package.py (check_deb): Remove linda call. It
+       provides no added benefit to lintian anymore.
+
+2008-01-06  Joerg Jaspert  <joerg@debian.org>
+
+       * dak/examine_package.py (do_lintian): lintian now supports html
+       coloring, so use it.
+       (do_command): Dont escape html chars if param escaped = 1
+
+2008-01-06  Joerg Jaspert  <joerg@debian.org>
+
+       * dak/examine_package.py (do_lintian): lintian now supports html
+       coloring, so use it.
+       (do_command): Dont escape html chars if param escaped = 1
+
+2007-12-31  Anthony Towns  <ajt@debian.org>
+
+       * dak/process_new.py (recheck): pass "" for prefix_str to reject()
+       when processing result of check_dsc_against_db so we don't promote
+       warnings to rejections.
+
+2007-12-31  Anthony Towns  <ajt@debian.org>
+
+       * dak/process_new.py (recheck): pass "" for prefix_str to reject()
+       when processing result of check_dsc_against_db so we don't promote
+       warnings to rejections.
+
+2007-12-30  Joerg Jaspert  <joerg@debian.org>
+
+       * dak/dak.py (init): add show-new. This is based on a patch
+       submitted by Thomas Viehmann in Bug #408318, but large parts of
+       handling it are rewritten and show-new is done by me.
+
+       * dak/queue_report.py (table_row): Add link to generated html page
+       for NEW package.
+
+       * dak/show_new.py: new file, generates html overview for NEW
+       packages, similar to what we see with examine-package.
+
+       * config/debian/cron.hourly: Add show-new call
+
+       * config/debian/dak.conf: Add HTMLPath for Show-New
+
+       * dak/examine_package.py (print_copyright): ignore stderr when
+       finding copyright file.
+       (main): add html option
+       (html_escape): new function
+       (escape_if_needed): ditto
+       (headline): ditto
+       (colour_output): ditto
+       (print_escaped_text): ditto
+       (print_formatted_text): ditto
+       - use those functions everywhere where we generate output, as they
+       easily know if we want html or not and just DTRT
+       (do_lintian): new function
+       (check_deb): use it
+       (output_deb_info): Use print_escaped_text, not print_formatted_text.
+       Also import daklib.queue, determine_new now lives there
+
+       Also add a variable to see if we want html output. Default is
+       disabled, show_new enables it for its use.
+       Most of html, besides header/footer are in examine_package instead
+       of show_new, as it makes it a whole lot easier to deal with it at
+       the point the info is generated.
+
+
+       * dak/process_new.py (determine_new): Moved out of here.
+       (check_valid): Moved out of here.
+       (get_type): Moved out of here.
+
+       * daklib/queue.py (determine_new): Moved here.
+       (check_valid): Moved here.
+       (get_type): Moved here.
+
+       * dak/init_db.py (do_section): Remove non-US code
+
+       * dak/make_overrides.py (main): ditto
+
+       * dak/process_new.py (determine_new): ditto
+
+       * daklib/queue.py (Upload.in_override_p),
+       (Upload.check_override): ditto
+
+       * daklib/utils.py (extract_component_from_section):,
+       (poolify): ditto
+
+       * dak/import_archive.py (update_section): ditto
+
+       * dak/symlink_dists.py (fix_component_section): ditto
+
+       * scripts/debian/mkmaintainers: ditto
+
+       * scripts/debian/update-mirrorlists (masterlist): ditto
+
+       * config/debian-non-US/*: Remove subdir
+
+       * scripts/debian/update-readmenonus: Removed.
+
+
+2007-12-30  Joerg Jaspert  <joerg@debian.org>
+
+       * dak/dak.py (init): add show-new. This is based on a patch
+       submitted by Thomas Viehmann in Bug #408318, but large parts of
+       handling it are rewritten and show-new is done by me.
+
+       * dak/queue_report.py (table_row): Add link to generated html page
+       for NEW package.
+
+       * dak/show_new.py: new file, generates html overview for NEW
+       packages, similar to what we see with examine-package.
+
+       * config/debian/cron.hourly: Add show-new call
+
+       * config/debian/dak.conf: Add HTMLPath for Show-New
+
+       * dak/examine_package.py (print_copyright): ignore stderr when
+       finding copyright file.
+       (main): add html option
+       (html_escape): new function
+       (escape_if_needed): ditto
+       (headline): ditto
+       (colour_output): ditto
+       (print_escaped_text): ditto
+       (print_formatted_text): ditto
+       - use those functions everywhere where we generate output, as they
+       easily know if we want html or not and just DTRT
+       (do_lintian): new function
+       (check_deb): use it
+       (output_deb_info): Use print_escaped_text, not print_formatted_text.
+       Also import daklib.queue, determine_new now lives there
+
+       Also add a variable to see if we want html output. Default is
+       disabled, show_new enables it for its use.
+       Most of html, besides header/footer are in examine_package instead
+       of show_new, as it makes it a whole lot easier to deal with it at
+       the point the info is generated.
+
+
+       * dak/process_new.py (determine_new): Moved out of here.
+       (check_valid): Moved out of here.
+       (get_type): Moved out of here.
+
+       * daklib/queue.py (determine_new): Moved here.
+       (check_valid): Moved here.
+       (get_type): Moved here.
+
+       * dak/init_db.py (do_section): Remove non-US code
+
+       * dak/make_overrides.py (main): ditto
+
+       * dak/process_new.py (determine_new): ditto
+
+       * daklib/queue.py (Upload.in_override_p),
+       (Upload.check_override): ditto
+
+       * daklib/utils.py (extract_component_from_section):,
+       (poolify): ditto
+
+       * dak/import_archive.py (update_section): ditto
+
+       * dak/symlink_dists.py (fix_component_section): ditto
+
+       * scripts/debian/mkmaintainers: ditto
+
+       * scripts/debian/update-mirrorlists (masterlist): ditto
+
+       * config/debian-non-US/*: Remove subdir
+
+       * scripts/debian/update-readmenonus: Removed.
+
+
+2007-12-28  Anthony Towns  <ajt@debian.org>
+
+       * daklib/utils.py (check_signature): add NOTATION_DATA and
+       NOTATION_NAME to known keywords.
+
+       * daklib/queue.py (Upload.check_source_against_db):
+
+       * dak/make_suite_file_list.py: add -f/--force option.
+
+       * dak/generate_releases.py: add -a/--apt-conf=FILE and
+       -f/--force-touch options.  Pull version info from the database.
+       Make suite description optional.
+
+       * config/debian/dak.conf: update
+       Reject-Proposed-Updates::MoreInfoURL.  Comment out
+       Suite::Stable::Version and ::Description.
+
+       * config/debian/apt.conf: Add hurd-i386 to unstable
+       debian-installer stanza.
+
+2007-12-28  Joerg Jaspert  <joerg@debian.org>
+
+       * KEYEXPIRED is actually a known keyword. We do check it earlier
+       on and reject in case the sig is bad (or unknown)
+
+2007-12-28  Anthony Towns  <ajt@debian.org>
+
+       * daklib/utils.py (check_signature): add NOTATION_DATA and
+       NOTATION_NAME to known keywords.
+
+       * daklib/queue.py (Upload.check_source_against_db):
+
+       * dak/make_suite_file_list.py: add -f/--force option.
+
+       * dak/generate_releases.py: add -a/--apt-conf=FILE and
+       -f/--force-touch options.  Pull version info from the database.
+       Make suite description optional.
+
+       * config/debian/dak.conf: update
+       Reject-Proposed-Updates::MoreInfoURL.  Comment out
+       Suite::Stable::Version and ::Description.
+
+       * config/debian/apt.conf: Add hurd-i386 to unstable
+       debian-installer stanza.
+
+2007-12-28  Joerg Jaspert  <joerg@debian.org>
+
+       * KEYEXPIRED is actually a known keyword. We do check it earlier
+       on and reject in case the sig is bad (or unknown)
+
+2007-12-24  Joerg Jaspert  <joerg@debian.org>
+
+       * Also run lintian on the .dsc file to check the source itself.
+
+       * Fix the direct usage of ar | tar etc to get the copyright file
+       and use dpkg-deb, which is made for this and makes us able to
+       process data.tar.bz2 (or whatever format it will be in the
+       future).
+
+2007-12-24  Joerg Jaspert  <joerg@debian.org>
+
+       * Also run lintian on the .dsc file to check the source itself.
+
+       * Fix the direct usage of ar | tar etc to get the copyright file
+       and use dpkg-deb, which is made for this and makes us able to
+       process data.tar.bz2 (or whatever format it will be in the
+       future).
+
+2007-12-21  Joerg Jaspert  <joerg@debian.org>
+
+       * Remove the (now useless) check for a pre-depends on dpkg for
+         binaries that contain bzip2 compressed data tarballs.
+
+2007-12-21  Joerg Jaspert  <joerg@debian.org>
+
+       * Remove the (now useless) check for a pre-depends on dpkg for
+         binaries that contain bzip2 compressed data tarballs.
+
+2007-08-28  Anthony Towns  <ajt@debian.org>
+
+       * process_unchecked.py: Add support for automatic BYHAND
+       processing.
+       * config/debian/dak.conf, scripts/debian/byhand-tag: Automatic
+       processing of tag-overrides.
+       * examine_package.py: Summarise duplicate copyright file entries
+       (same md5sum) with a reference to the previous instance, rather
+       than repeating them.
+       * process_new.py: When rejecting from the p-u-new or o-p-u-new
+       holding queues, don't worry if dak has its own reasons for
+       rejecting the package as well as the SRMs.
+
+2007-08-28  Anthony Towns  <ajt@debian.org>
+
+       * process_unchecked.py: Add support for automatic BYHAND
+       processing.
+       * config/debian/dak.conf, scripts/debian/byhand-tag: Automatic
+       processing of tag-overrides.
+       * examine_package.py: Summarise duplicate copyright file entries
+       (same md5sum) with a reference to the previous instance, rather
+       than repeating them.
+       * process_new.py: When rejecting from the p-u-new or o-p-u-new
+       holding queues, don't worry if dak has its own reasons for
+       rejecting the package as well as the SRMs.
+
+2007-06-19  Anthony Towns  <ajt@debian.org>
+
+       * Add nm.debian.org pseudopackage
+
+2007-06-19  Anthony Towns  <ajt@debian.org>
+
+       * Add nm.debian.org pseudopackage
+
+2007-06-18  Anthony Towns  <ajt@debian.org>
+
+       * daklib/logging.py: Set umask to not exclude group-writability
+       so we don't get reminded at the start of each month. Thanks to
+       Random J.
+       * dak/override.py: More changes from Herr von Wifflepuck: warn
+       if section of source is different to binary section; restore
+       functionality on source-only overrides; croak if trying to set
+       priority of a source override; never set priority of source
+       overrides; correct typo in logging (s/priority/section/ at
+       one place)
+
+       * config/debian/apt.conf.oldstable: Added for oldstable point releases.
+       * config/debian/cron.daily: auotmatically accept/reject
+       oldstable-proposed-updates based on COMMENTS directory
+
+2007-06-18  Anthony Towns  <ajt@debian.org>
+
+       * config/debian/apt.conf, config/debian/apt.conf.stable,
+       config/debian/dak.conf: update for 4.0r0 (etch), and 3.1r6
+       (sarge), support for oldstable-proposed-updates, dropping m68k
+       from etch, creating etch-m68k suite, creating lenny.
+
+       * config/debian/vars: update for lenny
+
+       * config/debian/dak.conf: typo fix for Dinstall::GPGKeyring,
+       drop upload limitations, add release postgres user
+
+       * dak/process_new.py: support for automatically accepting and rejecting
+       packages from proposed-updates holding queues via COMMENTS directory
+       * cron.daily: automatically process COMMENTS-based approvals
+       and rejections for proposed-updates holding queues
+
+       * dak/process_unchecked.py: add support for oldproposedupdates
+       holding queue
+
+       * dak/control_suite.py: allow control-suite to work with etch-m68k
+
+       * dak/generate_releases.py: unlink old Release files before updating
+       them if nlinks > 1 (ie, if two files used to be the same, maybe they
+       shouldn't be when generate-releases is run)
+
+       * dak/generate_releases.py: add a couple of commented lines to make
+       it easier to deal with point releases
+
+       * dak/make_overrides.py: generate overrides for !contrib udebs
+
+       * docs/README.stable-point-release: update docs for doing a
+       point release
+
+2007-06-18  Anthony Towns  <ajt@debian.org>
+
+       * daklib/logging.py: Set umask to not exclude group-writability
+       so we don't get reminded at the start of each month. Thanks to
+       Random J.
+       * dak/override.py: More changes from Herr von Wifflepuck: warn
+       if section of source is different to binary section; restore
+       functionality on source-only overrides; croak if trying to set
+       priority of a source override; never set priority of source
+       overrides; correct typo in logging (s/priority/section/ at
+       one place)
+
+       * config/debian/apt.conf.oldstable: Added for oldstable point releases.
+       * config/debian/cron.daily: auotmatically accept/reject
+       oldstable-proposed-updates based on COMMENTS directory
+
+2007-06-18  Anthony Towns  <ajt@debian.org>
+
+       * config/debian/apt.conf, config/debian/apt.conf.stable,
+       config/debian/dak.conf: update for 4.0r0 (etch), and 3.1r6
+       (sarge), support for oldstable-proposed-updates, dropping m68k
+       from etch, creating etch-m68k suite, creating lenny.
+
+       * config/debian/vars: update for lenny
+
+       * config/debian/dak.conf: typo fix for Dinstall::GPGKeyring,
+       drop upload limitations, add release postgres user
+
+       * dak/process_new.py: support for automatically accepting and rejecting
+       packages from proposed-updates holding queues via COMMENTS directory
+       * cron.daily: automatically process COMMENTS-based approvals
+       and rejections for proposed-updates holding queues
+
+       * dak/process_unchecked.py: add support for oldproposedupdates
+       holding queue
+
+       * dak/control_suite.py: allow control-suite to work with etch-m68k
+
+       * dak/generate_releases.py: unlink old Release files before updating
+       them if nlinks > 1 (ie, if two files used to be the same, maybe they
+       shouldn't be when generate-releases is run)
+
+       * dak/generate_releases.py: add a couple of commented lines to make
+       it easier to deal with point releases
+
+       * dak/make_overrides.py: generate overrides for !contrib udebs
+
+       * docs/README.stable-point-release: update docs for doing a
+       point release
+
+2007-03-05  Anthony Towns  <ajt@debian.org>
+
+       * config/debian/dak.conf: update for 3.1r5.
+       * scripts/debian/ssh-move: add ssh-move script from debbugs
+       * config/debian/cron.unchecked: push version info to debbugs using
+       ssh-move.
+
+2007-03-05  Anthony Towns  <ajt@debian.org>
+
+       * config/debian/dak.conf: update for 3.1r5.
+       * scripts/debian/ssh-move: add ssh-move script from debbugs
+       * config/debian/cron.unchecked: push version info to debbugs using
+       ssh-move.
+
+2007-02-14  James Troup  <troup@ries.debian.org>
+
+       * docs/README.config: remove Dinstall::GroupOverrideFilename.
+       * config/debian/dak.conf: likewise.
+       * config/debian-non-US/dak.conf: likewise.
+       * config/debian-security/dak.conf: likewise.
+
+       * daklib/queue.py (Upload.close_bugs): no longer handle NMUs or
+       experimental differently, just close the bugs and let version
+       tracking sort it out.
+        (nmu_p): remove entire class - now unused.
+        (Upload.__init__): don't use nmu_p.
+
+2007-02-14  James Troup  <troup@ries.debian.org>
+
+       * docs/README.config: remove Dinstall::GroupOverrideFilename.
+       * config/debian/dak.conf: likewise.
+       * config/debian-non-US/dak.conf: likewise.
+       * config/debian-security/dak.conf: likewise.
+
+       * daklib/queue.py (Upload.close_bugs): no longer handle NMUs or
+       experimental differently, just close the bugs and let version
+       tracking sort it out.
+        (nmu_p): remove entire class - now unused.
+        (Upload.__init__): don't use nmu_p.
+
+2007-02-08  Anthony Towns  <ajt@debian.org>
+
+       * config/debian/dak.conf: update for 3.1r4.  Use new 'etch'
+       signing key.  Drop maximum index diffs down to 14.
+
+       * config/debian/apt.conf: add udeb support for non-free (testing,
+       unstable) and experimental.
+       * config/debian/dak.conf: likewise.
+
+       * dak/generate_releases.py (main): handle udebs in any component.
+
+       * daklib/queue.py (Upload.build_summaries): handle files without a
+       'type' gracefully.
+
+       * dak/generate_releases.py (print_sha256_files): new function.
+       (main): use it.
+
+       * dak/process_accepted.py (stable_install): fix name of template
+       mail.
+
+       * dak/process_unchecked.py (is_stableupdate): fix invocation of
+       database.get_suite_id().
+
+       * templates/process-new.bxa_notification: Update on request
+       of/after discussion with BIS staff.
+
+       * scripts/debian/mkfilesindices: also handle proposed-updates.
+
+2007-02-08  Ryan Murray  <rmurray@debian.org>
+
+       * config/debian/cron.monthly: use $ftpgroup instead of hardcoding
+       group name for chgrp of mail archives.
+
+       * daklib/queue.py (Upload.check_dsc_against_db): handle multiple
+       orig.tar.gz's by picking the first one by file id.
+
+       * dak/override.py (main): limit to binary overrides only for now.
+       (usage): update to match.
+
+       * config/debian/cron.daily: track when we have the accepted lock
+       and clean it up on exit if we have it.  Take/check the
+       cron.unchecked lock just before traping to cleanup on exit.
+       Remove potato override handling.  Remove any dangling symlinks in
+       /srv/incoming.d.o/buildd.  Clean up apt-ftparchive's databases.
+
+       * config/debian/apt.conf: change default compression scheme for
+       both Sources and Packages to gzip and bzip2 rather than
+       uncompressed and gzip (Packages) and gzip (Sources).  Use old
+       defaults for proposed-updates.
+
+       * dak/control_overrides.py (main): refuse to operate on
+       untouchable suites.
+
+       * config/debian/pseudo-packages.maintainers: drop install,
+       installation, boot-floppy, slink-cd, potato-cd and
+       nonus.debian.org.  Update base.
+       * config/debian/pseudo-packages.description: likewise.
+
+       * daklib/utils.py (re_srchasver): new regex.
+       (parse_changes): use regex to split 'Source (Version)' style
+       Source fields into 'source' and 'source-version'.
+
+       * config/debian/cron.daily: use $base instead of hardcoding path
+       name.
+
+       * scripts/debian/mkfilesindices: source 'vars' file and use it's
+       variables instead of hardcoding path names.
+
+       * config/debian/apt.conf: switch from /org to /srv.
+       * config/debian/apt.conf.buildd: likewise.
+       * config/debian/apt.conf.stable: likewise.
+       * config/debian/cron.daily: likewise.
+       * config/debian/cron.hourly: likewise.
+       * config/debian/cron.monthly: likewise.
+       * config/debian/cron.unchecked: likewise.
+       * config/debian/cron.weekly: likewise.
+       * config/debian/dak.conf: likewise.
+       * config/debian/vars: likewise.
+       * scripts/debian/mkfilesindices: likewise.
+
+2007-02-08  James Troup  <james@nocrew.org>
+
+       * dak/process_unchecked.py (check_signed_by_key): new function to
+       ensure .changes files are signed by an authorized uploader.
+       (process_it): use it.
+
+       * config/debian/dak.conf (Binary-Upload-Restrictions): new stanza
+       to configure per suite/component/architecture binary upload
+       restrictions.
+
+2007-02-08  Anthony Towns  <ajt@debian.org>
+
+       * config/debian/dak.conf: update for 3.1r4.  Use new 'etch'
+       signing key.  Drop maximum index diffs down to 14.
+
+       * config/debian/apt.conf: add udeb support for non-free (testing,
+       unstable) and experimental.
+       * config/debian/dak.conf: likewise.
+
+       * dak/generate_releases.py (main): handle udebs in any component.
+
+       * daklib/queue.py (Upload.build_summaries): handle files without a
+       'type' gracefully.
+
+       * dak/generate_releases.py (print_sha256_files): new function.
+       (main): use it.
+
+       * dak/process_accepted.py (stable_install): fix name of template
+       mail.
+
+       * dak/process_unchecked.py (is_stableupdate): fix invocation of
+       database.get_suite_id().
+
+       * templates/process-new.bxa_notification: Update on request
+       of/after discussion with BIS staff.
+
+       * scripts/debian/mkfilesindices: also handle proposed-updates.
+
+2007-02-08  Ryan Murray  <rmurray@debian.org>
+
+       * config/debian/cron.monthly: use $ftpgroup instead of hardcoding
+       group name for chgrp of mail archives.
+
+       * daklib/queue.py (Upload.check_dsc_against_db): handle multiple
+       orig.tar.gz's by picking the first one by file id.
+
+       * dak/override.py (main): limit to binary overrides only for now.
+       (usage): update to match.
+
+       * config/debian/cron.daily: track when we have the accepted lock
+       and clean it up on exit if we have it.  Take/check the
+       cron.unchecked lock just before traping to cleanup on exit.
+       Remove potato override handling.  Remove any dangling symlinks in
+       /srv/incoming.d.o/buildd.  Clean up apt-ftparchive's databases.
+
+       * config/debian/apt.conf: change default compression scheme for
+       both Sources and Packages to gzip and bzip2 rather than
+       uncompressed and gzip (Packages) and gzip (Sources).  Use old
+       defaults for proposed-updates.
+
+       * dak/control_overrides.py (main): refuse to operate on
+       untouchable suites.
+
+       * config/debian/pseudo-packages.maintainers: drop install,
+       installation, boot-floppy, slink-cd, potato-cd and
+       nonus.debian.org.  Update base.
+       * config/debian/pseudo-packages.description: likewise.
+
+       * daklib/utils.py (re_srchasver): new regex.
+       (parse_changes): use regex to split 'Source (Version)' style
+       Source fields into 'source' and 'source-version'.
+
+       * config/debian/cron.daily: use $base instead of hardcoding path
+       name.
+
+       * scripts/debian/mkfilesindices: source 'vars' file and use it's
+       variables instead of hardcoding path names.
+
+       * config/debian/apt.conf: switch from /org to /srv.
+       * config/debian/apt.conf.buildd: likewise.
+       * config/debian/apt.conf.stable: likewise.
+       * config/debian/cron.daily: likewise.
+       * config/debian/cron.hourly: likewise.
+       * config/debian/cron.monthly: likewise.
+       * config/debian/cron.unchecked: likewise.
+       * config/debian/cron.weekly: likewise.
+       * config/debian/dak.conf: likewise.
+       * config/debian/vars: likewise.
+       * scripts/debian/mkfilesindices: likewise.
+
+2007-02-08  James Troup  <james@nocrew.org>
+
+       * dak/process_unchecked.py (check_signed_by_key): new function to
+       ensure .changes files are signed by an authorized uploader.
+       (process_it): use it.
+
+       * config/debian/dak.conf (Binary-Upload-Restrictions): new stanza
+       to configure per suite/component/architecture binary upload
+       restrictions.
+
+2006-10-09  James Troup  <james.troup@canonical.com>
+
+       * dak/process_unchecked.py (check_timestamps): change match to
+       search as recent versions of python-apt prefix the string with 'E: '.
+
+2006-10-09  James Troup  <james.troup@canonical.com>
+
+       * dak/process_unchecked.py (check_timestamps): change match to
+       search as recent versions of python-apt prefix the string with 'E: '.
+
+2006-06-26  Ryan Murray  <rmurray@debian.org>
+
+       * dak/process_unchecked.py (check_files): strip optional source version
+       from Source: field in changes file, and ensure what is left is a valid
+       package name.
+
+2006-06-26  Ryan Murray  <rmurray@debian.org>
+
+       * dak/process_unchecked.py (check_files): strip optional source version
+       from Source: field in changes file, and ensure what is left is a valid
+       package name.
+
+2006-06-23  Ryan Murray  <rmurray@debian.org>
+
+       * dak/process_unchecked.py (check_files): also check ProposedUpdates
+       queue for source.
+
+2006-06-23  Ryan Murray  <rmurray@debian.org>
+
+       * dak/process_unchecked.py (check_files): also check ProposedUpdates
+       queue for source.
+
+2006-06-18  Ryan Murray  <rmurray@debian.org>
+
+       * dak/scripts/debian/update-ftpstats: look for dak named processes in
+       the log, too.
+
+       * dak/process_unchecked.py (check_files): only check embargoed and
+       unembargoed queues if the keys are set.
+
+       * dak/config/debian-security/apt.conf: set Packages::Compress to gzip
+       and bzip2 for etch.
+
+2006-06-18  Ryan Murray  <rmurray@debian.org>
+
+       * dak/scripts/debian/update-ftpstats: look for dak named processes in
+       the log, too.
+
+       * dak/process_unchecked.py (check_files): only check embargoed and
+       unembargoed queues if the keys are set.
+
+       * dak/config/debian-security/apt.conf: set Packages::Compress to gzip
+       and bzip2 for etch.
+
+2006-06-16  James Troup  <james@nocrew.org>
+
+       * dak/dak.py (init): add new-security-install.
+
+       * dak/new_security_install.py: cleanups and adapt for new naming
+       scheme and other changes.
+
+2006-06-16  Anthony Towns  <ajt@debian.org>
+
+       * dak/new_security_install.py: initial version imported from
+       klecker.
+
+2006-06-16  James Troup  <james@nocrew.org>
+
+       [Merged changes from klecker - original author unknown.]
+
+       * daklib/queue.py (Upload.dump_vars): also save changes["adv id"].
+
+       * dak/security_install.py (do_upload): fix check for oldstable and
+       upload file list handling.
+
+       * dak/process_unchecked.py (check_files): update "check for
+       source" code to also look in Embargoed and Unembargoed queues.
+       (is_unembargo): fix handling of Dir::Queue::Disembargo.
+
+       * dak/decode_dot_dak.py (main): add support for changes["adv id"].
+
+       * config/debian-security/vars (disembargo): add.
+
+       * config/debian-security/dak.conf (Dinstall::SigningKeyIds):
+       update.
+       (Process-Unchecked::AcceptedLockFile): add.
+       (Suite::Testing): clean up Version and Description.
+       (SuiteMappings): add silent map from etch-secure to testing.
+
+       * config/debian-security/cron.unchecked: add support for
+       disembargoed queues.
+
+       * config/debian-security/apt.conf.buildd: add bzip2ed Packages
+       files too.
+
+       * config/debian-security/apt.conf: add amd64 to architectures for
+       testing-security.
+
+2006-06-11  James Troup  <troup@spohr.debian.org>
+
+       * config/debian/cron.daily: invoke process-accepted not
+       process-unchecked.
+
+       * config/debian/vars (scriptsdir): new variable.
+       * config/debian/cron.daily: use it.
+
+       * scripts/debian/mkmaintainers: put Maintainers_Versions-non-US in
+       $base/misc/ instead of versioned $masterdir.  Correct 'dak
+       make-maintainers' invocation to look in $configdir for
+       pseudo-packages.maintainers.
+
+       * daklib/queue.py (Upload.do_reject): use correct name for
+       rejection template.
+
+2006-06-11  James Troup  <james@nocrew.org>
+
+       * dak/override.py (main): temporarily add content of old X-Katie
+       header back as the PTS apparently filters on it.
+       * dak/process_accepted.py (main): likewise.
+       * dak/process_new.py (main): likewise.
+       * dak/process_unchecked.py (main): likewise.
+       * dak/reject_proposed_updates.py (main): likewise.
+       * dak/rm.py (main): likewise.
+       * daklib/queue.py (Upload.do_reject): likewise.
+
+       * config/debian/cron.unchecked: set -u to error out on undefined
+       variables.  Preset LOCKDAILY to "" accordingly.
+       * config/debian/cron.hourly: likewise.
+       * config/debian/cron.monthly: likewise.
+       * config/debian/cron.weekly: likewise.
+
+       * config/debian/vars (configdir): add new variable pointing to
+       this directory.
+
+       * config/debian/cron.daily: use $configdir inplace of $masterdir
+       when that's what we mean, and don't cd into $masterdir just to run
+       dak scripts as we don't need to do that anymore.
+       * config/debian/cron.hourly: likewise.
+       * config/debian/cron.unchecked: likewise.
+       * config/debian/cron.weekly: likewise.
+
+       * config/debian/dak.conf
+       (Import-Users-From-Passwd::KnownPostgres): temporarily add 'katie'
+       user back to list of known users as it's non-trivial to entirely
+       change the owner of a database with postgresql 7.4.
+
+       * daklib/queue.py (Upload.source_exists): use string object
+       methods rather than string module.
+       (Upload.get_anyversion): likewise.
+
+       * daklib/utils.py (validate_changes_file_arg): update filename
+       slicing to cope with new .dak filenames.
+
+       * dak/ls.py (main): add back 'heidi' as a valid argument for
+       -f/--format as people are using it in scripts and breaking that
+       without warning seems rude.
+
+2006-05-21  James Troup  <james@nocrew.org>
+
+       * dak/rm.py (main): use string .isdigit() rather than
+       utils.str_isnum().
+       * dak/process_new.py (edit_overrides): likewise.
+
+       * daklib/utils.py (str_isnum): removed accordingly.  Also drop
+       string import.
+
+2006-05-21  James Troup  <james@nocrew.org>
+
+       * dak/check_archive.py (check_indices_files_exist): use list
+       comprehension instead of map().  No longer need to import
+       deprecated string module as a side-effect.
+       * dak/check_overrides.py (process): likewise.
+       (main): likewise.
+       * dak/cruft_report.py (do_obsolete_source): likewise.
+       (main): likewise.
+       * dak/ls.py (main): likewise.
+       * dak/make_suite_file_list.py (write_filelists): likewise.
+       * dak/process_accepted.py (stable_install): likewise.
+       * dak/rm.py (main): likewise.
+       * dak/stats.py (number_of_packages): likewise.
+       * daklib/logging.py (Logger.log): likewise.
+       * daklib/queue.py (Upload.source_exists): likewise.
+       (Upload.cross_suite_version_check): likewise.
+       * daklib/utils.py (parse_args): likewise.
+
+2006-05-21  James Troup  <james@nocrew.org>
+
+       * daklib/utils.py (process_gpgv_output): new function, split out
+       of check_signature().
+       (check_signature): adapt accordingly.
+       (retrieve_key): new function that will try to retrieve the key
+       that signed a given file from a keyserver.
+       (check_signature): add 'autofetch' argument that if not set
+       defaults to the value of Dinstall::KeyAutoFetch (if that exists).
+       If 'autofetch' is true, invoke retrieve_key().
+
+       * docs/README.config: document Dinstall::KeyAutoFetch and
+       Dinstall:KeyServer.
+
+2006-05-20  James Troup  <james@nocrew.org>
+
+       * dak/find_null_maintainers.py (main):
+       s/createtimestamp/createTimestamp/ to make things work with modern
+       slapd.
+
+       * config/debian/dak.conf: Update StableRejector, MoreInfoURL,
+       Stable::Version and Stable::Description for 3.1r2.
+
+       * config/debian-non-US/dak.conf: sync with klecker - update
+       version number of 3.0 and MoreInfoURL.
+
+       * docs/README.stable-point-release: Add notes about updating
+       dak.conf and Reject-Proposed-Updates section in particular.
+       s/woody/stable/.  Also need to update README.html.
+
+       * scripts/debian/mklslar: drop support for uncompressed ls-lR file.
+
+       * config/debian/apt.conf: Add udeb tree for proposed-updates.
+
+2006-05-20  Ryan Murray  <rmurray@debian.org>
+
+       * scripts/debian/update-ftpstats: new script to update daily
+       architecture size graph data.
+
+       * config/debian/cron.buildd: sync with spohr - due to ftp-master /
+       buildd split, simply ssh to buildd.d.o and call 'trigger.often'
+       there.
+
+       * config/debian/cron.daily: ssh to buildd and run 'trigger.daily'
+       before we finish.  Don't push to merkel.
+
+       * dak/process_unchecked.py (check_changes): Also look in
+       ProposedUpdates queue dir.
+       (check_files): likewise.
+
+2006-05-20  Anthony Towns  <ajt@debian.org>
+
+       * scripts/debian/mkfilesindices: new script to generate file
+       indices used for partial mirroring.
+
+       * config/debian/cron.daily: add progress timestamps.
+
+       * config/debian/dak.conf: update Dinstall::SigningKeyIds. Add
+       amd64 to testing, unstable and experimental.  Drop sh from
+       experimental.  Move Experimental to dists/experimental.  Add
+       Dir::ProposedUpdates.  Add Architectures::amd64.
+
+       * config/debian/apt.conf: add amd64 to testing, unstable and
+       experimental.  Drop uncompressed Packages files from testing. Drop
+       sh from experimental.  Move experimental to dists/experimental/.
+
+       * config/debian/vars (archs): add amd64.
+
+       * dak/process_unchecked.py (action): Add support for
+       proposed-updates approval queue.
+       (is_stableupdate): new function - checks if the upload is targeted
+       at proposed-updates.
+       (do_stableupdate): likewise - moves upload to proposed-updates
+       holding area.
+
+       * dak/process_new.py (do_new): warn if original or new target
+       suite are invalid.
+
+       * dak/generate_releases.py (print_md5sha_files): less whitespace
+       between the hash and size.
+
+       * dak/generate_index_diffs.py (genchanges): don't say we're not
+       doing anything.  Better formatting of other messages.
+       (main): don't skip experimental and remove some 'doing stuff'
+       prints.
+
+2006-05-18  James Troup  <james@nocrew.org>
+
+       * dak/clean_suites.py (clean_binaries): remove debug print of SQL
+       query.
+
+       * dak/init_dirs.py: pylint cleanups - long lines, unused globals,
+       docstrings, untabify, don't shadow builtins, lowercase non-global
+       variable names, spaces after commas.  Also bail if given any
+       arguments since we don't accept any.
+       * dak/init_db.py: likewise.  Also split large main() into
+       subfunctions and rename get() to sql_get().
+
+       * dak/init_db.py (main): check returned value from
+       database.get_archive_id().
+
+       * dak/dak.py: renamed from shell.py.  Update to support new source
+       layout.  Created init() and usage() functions.  Various
+       pylint-inspired cleanups.  Use daklib utils.warn() and
+       utils.fubar().  Change 'functionality' variable to only have
+       (command, description) and always invoke main() when running the
+       module.  Also support -h.
+
+2006-05-17  James Troup  <james@nocrew.org>
+
+       * dak/check_archive.py: remove $Id$ and $Revision$ strings.  Update
+       imports of and calls to daklib modules.  Change script name
+       everywhere, i.e. in output, mails, comments and configuration tree
+       + filenames.  Also update references to other renamed scripts,
+       classes and templates.  Use '.dak' instead of '.katie' for the
+       queue info storage files.
+       (Renamed from tea)
+       * dak/check_overrides.py: likewise.  (Renamed from cindy)
+       * dak/check_proposed_updates.py: likewise.  (Renamed from jeri)
+       * dak/clean_proposed_updates.py: likewise.  (Renamed from halle)
+       * dak/clean_queues.py: likewise.  (Renamed from shania)
+       * dak/clean_suites.py: likewise.  (Renamed from rhona)
+       * dak/compare_suites.py: likewise.  (Renamed from andrea)
+       * dak/control_overrides.py: likewise.  (Renamed from natalie)
+       * dak/control_suite.py: likewise.  (Renamed from heidi)
+       * dak/cruft_report.py: likewise.  (Renamed from rene)
+       * dak/decode_dot_dak.py: likewise.  (Renamed from ashley)
+       * dak/find_null_maintainers.py: likewise.  (Renamed from rosamund)
+       * dak/generate_index_diffs.py: likewise.  (Renamed from tiffani)
+       * dak/generate_releases.py: likewise.  (Renamed from ziyi)
+       * dak/import_archive.py: likewise.  (Renamed from neve)
+       * dak/import_ldap_fingerprints.py: likewise. (Renamed from emilie)
+       * dak/import_users_from_passwd.py: likewise. (Renamed from julia)
+       * dak/init_db.py: likewise. (Renamed from alyson)
+       * dak/init_dirs.py: likewise. (Renamed from rose)
+       * dak/ls.py: likewise. (Renamed from madison)
+       * dak/make_maintainers.py: likewise.  (Renamed from charisma)
+       * dak/make_overrides.py: likewise.  (Renamed from denise)
+       * dak/make_suite_file_list.py: likewise.  (Renamed from jenna)
+       * dak/mirror_split.py: likewise.  (Renamed from billie)
+       * dak/override.py: likewise.  (Renamed from alicia)
+       * dak/poolize.py: likewise.  (Renamed from catherine)
+       * dak/process_accepted.py: likewise.  (Renamed from kelly)
+       * dak/process_new.py: likewise.  (Renamed from lisa)
+       * dak/process_unchecked.py: likewise.  (Renamed from jennifer)
+       * dak/queue_report.py: likewise.  (Renamed from helena)
+       * dak/reject_proposed_updates.py: likewise.  (Renamed from lauren)
+       * dak/rm.py: likewise.  (Renamed from melanie)
+       * dak/security_install.py: likewise.  (Renamed from amber)
+       * dak/split_done.py: likewise.  (Renamed from nina)
+       * dak/stats.py: likewise.  (Renamed from saffron)
+       * dak/symlink_dists.py: likewise.  (Renamed from saffron)
+       * daklib/database.py: likewise.  (Renamed from db_access)
+       * daklib/queue.py: likewise.  'Katie' class -> 'Upload'. (Renamed from katie)
+       * daklib/utils.py: likewise.
+
+       * dak/cruft_report.py: Use '[auto-cruft]' as the magic "this removal
+       doesn't need to notify anyone" string.
+       * dak/rm.py: likewise, look for '[auto-cruft]' as the magic string.
+
+       * dak/process_accepted.py (init): drop -V/--version argument.
+       * dak/process_new.py (init): likewise.
+       * dak/process_unchecked.py (init): likewise.
+       * dak/reject_proposed_updates.py (init): likewise
+
+       * dak/shell.py: Renamed from dak.  ".katie" -> ".dak"
+
+       * dak/stats.py: in usage() output change STAT to MODE.
+
+2006-05-15  James Troup  <james@nocrew.org>
+
+       * dak/queue_report.py: remove unused encodings imports.
+
+       * dak/mirror_split.py: drop unused pg, pwd, db_access and logging
+       imports.  Initalize 'Cnf' as a global.
+       (BillieDB._internal_recurse): fix 'util.' typo.
+
+       * dak/import_ldap_fingerprints.py (main): drop unused time import and
+       commented out time check for LDAP search.
+
+2005-12-16  Ryan Murray  <rmurray@debian.org>
+
+       * halle: add support for udebs
+       * kelly: stable_install: add support for binNMU versions
+
+2005-12-05  Anthony Towns  <aj@erisian.com.au>
+
+       * katie.py: Move accept() autobuilding support into separate function 
+       (queue_build), and generalise to build different queues
+
+       * db_access.py: Add get_or_set_queue_id instead of hardcoding accepted=0
+
+       * jennifer: Initial support for enabling embargo handling with the
+       Dinstall::SecurityQueueHandling option.
+       * jennifer: Shift common code into remove_from_unchecked and move_to_dir
+       functions.
+
+       * katie.conf-security: Include embargo options
+       * katie.conf-security: Add Lock dir
+       * init_pool.sql-security: Create disembargo table
+       * init_pool.sql-security: Add constraints for disembargo table
+
+2005-11-26  Anthony Towns  <aj@erisian.com.au>
+
+       * Merge of changes from klecker, by various people
+
+       * amber: special casing for not passing on amd64 and oldstable updates
+       * amber: security mirror triggering
+       * templates/amber.advisory: updated advisory structure
+       * apt.conf.buildd-security: update for sarge's release
+       * apt.conf-security: update for sarge's release
+       * cron.buildd-security: generalise suite support, update for sarge's release
+       * cron.daily-security: update for sarge's release, add udeb support
+       * vars-security: update for sarge's release
+       * katie.conf-security: update for sarge's release, add amd64 support,
+       update signing key
+
+       * docs/README.names, docs/README.quotes: include the additions
+
+2005-11-25  Anthony Towns  <aj@erisian.com.au>
+
+       * Changed accepted_autobuild to queue_build everywhere.
+       * Add a queue table.
+       * Add a "queue" field in the queue_build table (currently always 0)
+
+       * jennifer: Restructure to make it easier to support special
+       purpose queues between unchecked and accepted.
+
+2005-11-25  Anthony Towns  <aj@erisian.com.au>
+
+       * Finishing merge of changes from spohr, by various people still
+
+       * jennifer: If changed-by parsing fails, set variables to "" so REJECT
+       works
+       * jennifer: Re-enable .deb ar format checking
+       * katie.py: Convert to +bX binNMU special casing
+       * rhona: Add some debug output when deleting binaries
+       * cron.daily: Add emilie
+       * cron.unchecked: Add lock files
+
+2005-11-15  Anthony Towns  <aj@erisian.com.au>
+
+       * Merge of changes from spohr, by various people.
+
+       * tiffani: new script to do patches to Packages, Sources and Contents
+       files for quicker downloads.
+       * ziyi: update to authenticate tiffani generated files
+
+       * dak: new script to provide a single binary with less arbitrary names
+       for access to dak functionality.
+
+       * cindy: script implemented
+
+       * saffron: cope with suites that don't have a Priority specified
+       * heidi: use get_suite_id()
+       * denise: don't hardcode stable and unstable, or limit udebs to unstable
+       * denise: remove override munging for testing (now done by cindy)
+       * helena: expanded help, added new, sort and age options, and fancy headers
+       * jennifer: require description, add a reject for missing dsc file
+       * jennifer: change lock file
+       * kelly: propogation support
+       * lisa: honour accepted lock, use mtime not ctime, add override type_id
+       * madison: don't say "dep-retry"
+       * melanie: bug fix in output (missing %)
+       * natalie: cope with maintainer_override == None; add type_id for overrides
+       * nina: use mtime, not ctime
+
+       * katie.py: propogation bug fixes
+       * logging.py: add debugging support, use | as the logfile separator
+
+       * katie.conf: updated signing key (4F368D5D)
+       * katie.conf: changed lockfile to dinstall.lock
+       * katie.conf: added Lisa::AcceptedLockFile, Dir::Lock
+       * katie.conf: added tiffani, cindy support
+       * katie.conf: updated to match 3.0r6 release
+       * katie.conf: updated to match sarge's release
+
+       * apt.conf: update for sarge's release
+       * apt.conf.stable: update for sarge's release
+       * apt.conf: bump daily max Contents change to 25MB from 12MB
+
+       * cron.daily: add accepted lock and invoke cindy
+       * cron.daily: add daily.lock
+       * cron.daily: invoke tiffani
+       * cron.daily: rebuild accepted buildd stuff
+       * cron.daily: save rene-daily output on the web site
+       * cron.daily: disable billie
+       * cron.daily: add stats pr0n
+
+       * cron.hourly: invoke helena
+
+       * pseudo-packages.maintainers,.descriptions: miscellaneous updates
+       * vars: add lockdir, add etch to copyoverrides
+       * Makefile: add -Ipostgresql/server to CXXFLAGS
+
+       * docs/: added README.quotes
+       * docs/: added manpages for alicia, catherine, charisma, cindy, heidi,
+       julia, katie, kelly, lisa, madison, melanie, natalie, rhona.
+
+       * TODO: correct spelling of "conflicts"
+
+2005-05-28  James Troup  <james@nocrew.org>
+
+       * helena (process_changes_files): use MTIME rather than CTIME (the
+       C's not for 'creation', stupid).
+       * lisa (sort_changes): likewise.
+
+       * jennifer (check_distributions): use has_key rather than an 'in'
+       test which doesn't work with python2.1.  [Probably by AJ]
+
+2005-03-19  James Troup  <james@nocrew.org>
+
+       * rene (main): use Suite::<suite>::UdebComponents to determine
+       what components have udebs rather than assuming only 'main' does.
+
+2005-03-18  James Troup  <james@nocrew.org>
+
+       * utils.py (rfc2047_encode): use codecs.lookup() rather than
+       encodings.<encoding>.Codec().decode() as encodings.utf_8 no longer
+       has a Codec() module in python2.4.  Thanks to Andrew Bennetts
+       <andrew@ubuntu.com>.
+
+2005-03-06  Joerg Jaspert  <ganneff@debian.org>
+
+       * helena: add -n/--new HTML output option and improved sorting
+       options.
+
+2005-03-06  Ryan Murray  <rmurray@debian.org>
+
+       * shania(main): use Cnf::Dir::Reject instead of REJECT
+
+2005-02-08  James Troup  <james@nocrew.org>
+
+       * rene (main): add partial NBS support by checking that binary
+       packages are built by their real parent and not some random
+       stranger.
+       (do_partial_nbs): likewise.
+
+2005-01-18  James Troup  <james@nocrew.org>
+
+       * katie.py (Katie.build_summaries): avoid leaking file handle when
+       extracting package description.
+       (Katie.force_reject): remember and close each file descriptor we
+       use.
+       (Katie.do_reject): s/file/temp_fh/ to avoid pychecker warning.
+       s/reason_file/reason_fd/ because it's a file descriptor.
+       (Katie.check_dsc_against_db): avoid leaking file handle whenever
+       invoking apt_pkg.md5sum().
+
+       * jennifer (check_deb_ar): new function: sanity check the ar
+       contents of a .deb.
+       (check_files): use it.
+       (check_timestamps): check for data.tar.bz2 if data.tar.gz can't be
+       found.
+       (check_files): accept 'raw-installer' as an alias for 'byhand'.
+
+2005-01-14  Anthony Towns  <ajt@debian.org>
+
+       * kelly: when UNACCEPTing, don't double up the "Rejecting:"
+
+       * propup stuff (thanks to Andreas Barth)
+       * katie.conf: add stable MustBeOlderThan testing, add -security
+         propup
+       * jennifer: set distribution-version in .katie if propup may be needed
+       * katie.py: add propogation to cross_suite_version_check
+
+2004-11-27  James Troup  <james@nocrew.org>
+
+       * nina: new script to split monolithic queue/done into date-based
+       hierarchy.
+
+       * rene (usage): document -s/--suite.
+       (add_nbs): use .setdefault().
+       (do_anais): likewise.
+       (do_nbs): don't set a string to "" and then += it.
+       (do_obsolete_source): new function - looks for obsolete source
+       packages (i.e source packages whose binary packages are ALL a)
+       claimed by someone else and b) newer when built from the other
+       source package).
+       (main): support -s/--suite.  Add 'obsolete source' to both 'daily'
+       and 'full' check modes.  Check for obsolete source packages.
+       linux-wlan-ng has been fixed - remove hideous bodge.
+
+       * jennifer (check_distributions): support 'reject' suite map type.
+
+       * utils.py (validate_changes_file_arg): s/file/filename/.
+       s/fatal/require_changes/.  If require_changes is -1, ignore errors
+       and return the .changes filename regardless.
+       (re_no_epoch): s/\*/+/ as there must be a digit in an epoch.
+       (re_no_revision): don't escape '-', it's not a special character.
+       s/\*/+/ as there must be at least one non-dash character after the
+       dash in a revision.  Thanks to Christian Reis for noticing both of
+       these.
+
+       * ashley (main): pass require_changes=-1 to
+       utils.validate_changes_file_arg().
+
+       * pseudo-packages.maintainers (kernel): switch to 'Debian Kernel
+       Team <debian-kernel@lists.debian.org>'.
+
+       * katie.py (Katie.in_override_p): fix .startswith() usage.
+
+       * katie.conf (Dinstall::DefaultSuite): add as 'unstable'.
+       (Lauren::MoreInfoURL): update to 3.0r3.
+       (Suite::Stable::Version): likewise.
+       (Suite::Stable::Description): likewise.
+
+       * cron.daily: disable automatic task override generation.
+
+       * cindy (process): restrict "find all packages" queries by
+       component.  Respect Options["No-Action"].
+       (main): add -n/--no-action support.  Only run on unstable.  Rename
+       type to otype (pychecker).
+
+2004-11-27  Daniel Silverstone  <dsilvers@digital-scurf.org>
+
+       * katie.conf (Billie::BasicTrees): add all architectures.
+       (Billie::CombinationTrees): remove 'welovehp' and 'embedded', add
+       'everything'.
+
+       * cron.daily: Update a 'current' symlink when creating the
+       post-daily-cron-job database backup to aid mirroring to merkel.
+       Run billie.
+
+       * billie (BillieTarget.poolish_match): handle .udeb too.
+
+2004-10-13  Ryan Murray  <rmurray@debian.org>
+
+       * amber (do_upload): Sort changes files in "katie" order so that
+         source always arrives before binary-only rebuilds
+
+2004-10-05  James Troup  <james@nocrew.org>
+
+       * jennifer (check_dsc): correct reject message on invalid
+       Maintainer field.
+
+2004-09-20  James Troup  <james@nocrew.org>
+
+       * alicia: remove unused 'pwd' import.
+
+       * tea (check_override): underline suite name in output properly.
+
+       * rene (main): read a compressed Packages file.
+       * tea (validate_packages): likewise.
+
+       * katie.py (re_fdnic): add 'r' prefix.
+       (re_bin_only_nmu_of_mu): likewise.
+       (re_bin_only_nmu_of_nmu): likewise.
+
+       * madison (main): retrieve component information too and display
+       it if it's not 'main'.
+       * melanie (reverse_depends_check): likewise.
+
+       * utils.py (pp_dep): renamed...
+       (pp_deps): ... to this.
+       * jeri (check_dep): update calls to utils.pp_deps().
+       * melanie (reverse_depends_check): likewise.
+
+       * jennifer (check_changes): move initalization of email variables
+       from here...
+       (process_it): ...to here as we no longer always run
+       check_changes().  Don't bother to initialize
+       changes["architecture"].
+
+       * denise (list): renamed to...
+       (do_list): ...this to avoid name clash with builtin 'list'.
+       Similarly, s/file/output_file/, s/type/otype/.  Use .setdefault()
+       for dictionaries.
+       (main): Likewise for name clash avoidance and also
+       s/override_type/suffix/.  Adjust call to do_list().
+
+2004-09-01  Ryan Murray  <rmurray@debian.org>
+
+       * tea (check_files): check the pool/ directory instead of dists/
+
+2004-08-04  James Troup  <james@nocrew.org>
+
+       * jenna (cleanup): use .setdefault() for dictionaries.
+       (write_filelists): likewise.
+
+       (write_filelists): Use utils.split_args() not split() to split
+       command line arguments.
+       (stable_dislocation_p): likewise.
+
+       (write_filelists): Add support for mapping side of suite-based
+       "Arch: all mapping".
+       (do_da_do_da): ensure that if we're not doing all suites that we
+       process enough to be able correct map arch: all packages.
+
+       * utils.py (cant_open_exc): correct exception string,
+       s/read/open/, s/.$//.
+
+       * templates/amber.advisory: update to match reality a little
+       better.
+
+       * melanie (reverse_depends_check): read Packages.gz rather than
+       Packages.
+
+       * jennifer (check_files): check for unknown component before
+       checking for NEWness.
+
+       * katie.py (Katie.in_override_p): use .startswith in favour of a
+       slice.
+
+       * docs/melanie.1.sgml: document -R/--rdep-check.
+
+2004-07-12  Daniel Silverstone  <dsilvers@digital-scurf.org>
+
+       * billie (main): Make the verbatim lists include all the README
+         elements.
+       * docs/README.names: Add billie in (correcting oversight)
+
+2004-07-01  James Troup  <james@nocrew.org>
+
+       * emilie (main): handle woody's case-sensitive python-ldap,
+       s/keyfingerprint/keyFingerPrint/.
+
+2004-06-25  James Troup  <james@nocrew.org>
+
+       * debian/control (Depends): add dpkg-dev since jennifer uses
+       dpkg-source.
+
+2004-06-24  James Troup  <james@nocrew.org>
+
+       * melanie (main): s/file/temp_file/ and close file handle before
+       removing the temporary file.
+       (main): don't warn about needing a --carbon-copy if in no-action
+       mode.
+
+       * rene (do_nbs): pcmcia-cs has been fixed - remove hideous bodge.
+       (main): likewise.
+
+       * test/006/test.py (main): check bracketed email-only form.
+
+       * utils.py (fix_maintainer): if the Maintainer string is bracketed
+       email-only, strip the brackets so we don't end up with
+       <<james@nocrew.org>>.
+
+2004-06-20  James Troup  <james@nocrew.org>
+
+       * jennifer (process_it): only run check_changes() if
+       check_signature() returns something.  (Likewise)
+
+       * utils.py (changes_compare): if there's no changes["version"] use
+       "0" rather than None.  (Avoids a crash on unsigned changes file.)
+
+2004-06-17  Martin Michlmayr  <tbm@cyrius.com>
+
+       * jeri (pp_dep): moved from here to ...
+       * utils.py (pp_dep): here.
+
+       * melanie (main): add reverse dependency checking.
+
+2004-06-17  James Troup  <james@nocrew.org>
+
+       * jennifer (check_dsc): s/dsc_whitespace_rules/signing_rules/.
+       * tea (check_dscs): likewise.
+
+       * utils.py (parse_changes): s/dsc_whitespace_rules/signing_rules/,
+       change from boolean to a variable with 3 possible values, 0 and 1
+       as before, -1 means don't require a signature.  Makes
+       parse_changes() useful for parsing arbitary RFC822-style files,
+       e.g. 'Release' files.
+       (check_signature): add support for detached signatures by passing
+       the files the signature is for as an optional third argument.
+       s/filename/sig_filename/g.  Add a fourth optional argument to
+       choose the keyring(s) to use.  Don't os.path.basename() the
+       sig_filename before checking it for taint.
+       (re_taint_free): allow '/'.
+
+2004-06-11  James Troup  <james@nocrew.org>
+
+       * tea (check_files): make override.unreadable optional.
+       (validate_sources): close the Sources file handle.
+
+       * docs/README.first: clarify that 'alyson' and running
+       add_constraints.sql by hand is something you only want to do if
+       you're not running 'neve'.
+
+       * docs/README.config (Location::$LOCATION::Suites): document.
+
+       * db_access.py (do_query): also print out the result of the query.
+
+2004-06-10  James Troup  <james@nocrew.org>
+
+       * katie.py (Katie.cross_suite_version_check): post-woody versions
+       of python-apt's apt_pkg.VersionCompare() function apparently
+       returns variable integers for less than or greater than results -
+       update our result checking to match.
+       * jenna (resolve_arch_all_vs_any): likewise.
+       * charisma (main): likewise.
+
+2004-06-09  James Troup  <james@nocrew.org>
+
+       * jennifer (process_it): s/changes_valid/valid_changes_p/.  Add
+       valid_dsc_p and don't run check_source() if check_dsc() failed.
+       (check_dsc): on fatal failures return 0 so check_source() isn't
+       run (since it makes fatal assumptions about the presence of
+       mandatory .dsc fields).
+       Remove unused and obsolete re_bad_diff and re_is_changes regexps.
+
+2004-05-07  James Troup  <james@nocrew.org>
+
+       * katie.conf (Rhona::OverrideFilename): unused and obsolete, remove.
+       * katie.conf-non-US (Rhona::OverrideFilename): likewise.
+
+       * katie.conf (Dir::Override): remove duplicate definition.
+
+       * neve (get_or_set_files_id): add an always-NULL last_used column
+       to output.
+
+2004-04-27  James Troup  <james@nocrew.org>
+
+       * apt.conf-security (tree "dists/stable/updates"): add
+       ExtraOverride - noticed by Joey Hess (#246050).
+       (tree "dists/testing/updates"): likewise.
+
+2004-04-20  James Troup  <james@nocrew.org>
+
+       * jennifer (check_files): check for existing .changes or .katie
+       files of the same name in the Suite::<suite>::Copy{Changes,Katie}
+       directories.
+
+2004-04-19  James Troup  <james@nocrew.org>
+
+       * jennifer (check_source): handle failure to remove the temporary
+        directory (used for source tree extraction) better, specifically:
+        if we fail with -EACCES, chmod -R u+rwx the temporary directory
+        and try again and if that works, REJECT the package.
+
+2004-04-17  James Troup  <james@nocrew.org>
+
+       * docs/madison.1.sgml: document -b/--binary-type,
+       -g/--greaterorequal and -G/--greaterthan.
+
+       * madison (usage): -b/--binary-type only takes a single argument.
+       Document -g/--greaterorequal and -G/--greaterthan.
+       (main): add support for -g/--greaterorequal and -G/--greaterthan.
+
+2004-04-12  Daniel Silverstone  <dsilvers@digital-scurf.org>
+
+       * billie: Cleaned up a load of comments, added /README.non-US to
+         the verbatim matches list.
+
+2004-04-07  Daniel Silverstone  <dsilvers@digital-scurf.org>
+
+       * utils.py (size_type): Make it use real binary megabytes and
+         kilobytes, instead of the marketing terms used before.
+
+2004-04-07  James Troup  <james@nocrew.org>
+
+       * katie.py (Katie.check_dsc_against_db): in the case we're
+       ignoring an identical-to-existing orig.tar.gz remember the path to
+       the existent version in pkg.orig_tar_gz.  Adjust query to grab
+       location.path too to be able to do so.
+
+2004-04-03  James Troup  <james@nocrew.org>
+
+       * debian/control (Depends): add python2.1-email | python (>= 2.2)
+       needed for new utils.rfc2047_encode() function.
+
+       * utils.py (re_parse_maintainer): allow whitespace inside the
+       email address.
+       (Error): new exception base class.
+       (ParseMaintError): new exception class.
+       (force_to_utf8): new function.
+       (rfc2047_encode): likewise.
+       (fix_maintainer): rework.  use force_to_utf8() to force name and
+       rfc822 return values to always use UTF-8.  use rfc2047_encode() to
+       return an rfc2047 value.  Validate the address to catch missing
+       email addresses and (some) broken ones.
+
+       * katie.py (nmu_p.is_an_nmu): adapt for new utils.fix_maintainer()
+       by adopting foo2047 return value.
+       (Katie.dump_vars): add changedby2047 and maintainer2047 as
+       mandatory changes fields.  Promote changes and maintainer822 to
+       mandatory fields.
+       (Katie.update_subst): default maintainer2047 rather than
+       maintainer822.  User foo2047 rather than foo822 when setting
+       __MAINTAINER_TO__ or __MAINTAINER_FROM__.
+
+       * jennifer (check_changes): set default changes["maintainer2047"]
+       and changes["changedby2047"] values rather than their 822
+       equivalents.  Makes changes["changes"] a mandatory field.  Adapt
+       to new utils.fix_maintainer() - reject on exception and adopt
+       foo2047 return value.
+       (check_dsc): if a mandatory field is missing don't do any further
+       checks and as a result reduce paranoia about dsc[var] existence.
+       Validate the maintainer field by calling new
+       utils.fix_maintainer().
+
+       * ashley (main): add changedby2047 and maintainer2047 to mandatory
+       changes fields.  Promote maintainer822 to a mandatory changes
+       field.  add "pool name" to files fields.
+
+       * test/006/test.py: new file - tests for new
+       utils.fix_maintainer().
+
+2004-04-01  James Troup  <james@nocrew.org>
+
+       * templates/lisa.prod (To): use __MAINTAINER_TO__ not __MAINTAINER__.
+
+       * jennifer (get_changelog_versions): create a symlink mirror of
+       the source files in the temporary directory.
+       (check_source): if check_dsc_against_db() couldn't find the
+       orig.tar.gz bail out.
+
+       * katie.py (Katie.check_dsc_against_db): if the orig.tar.gz is not
+       part of the upload store the path to it in pkg.orig_tar_gz and if
+       it can't be found set pkg.orig_tar_gz to -1.
+
+       Explicitly return the second value as None in the (usual) case
+       where we don't have to reprocess.  Remove obsolete diagnostic
+       logs.
+
+       * lisa (prod_maintainer): don't return anything, no one cares. (pychecker)
+
+       * utils.py (temp_filename): new helper function that wraps around
+       tempfile.mktemp().
+
+       * katie.py (Katie.do_reject): use it and don't import tempfile.
+       * lisa (prod_maintainer): likewise.
+       (edit_note): likewise.
+       (edit_new): likewise.
+       * lauren (reject): likewise.
+       * melanie (main): likewise.
+       * neve (do_sources): likewise.
+       * rene (main): likewise.
+       * tea (validate_sources): likewise.
+
+2004-03-31  James Troup  <james@nocrew.org>
+
+       * tea (validate_sources): remove unused 's' temporary variable.
+
+2004-03-15  James Troup  <james@nocrew.org>
+
+       * jennifer (check_dsc): check changes["architecture"] for
+       source before we do anything else.
+
+2004-03-21  Daniel Silverstone  <dsilvers@digital-scurf.org>
+
+       * billie: Added
+       * katie.conf (Billie): Added sample Billie stanza to katie.conf
+
+2004-03-12  James Troup  <james@nocrew.org>
+
+       * docs/README.config (Dir::Queue::BTSVersionTrack): document.
+
+       * katie.conf (Dir::Queue::BTSVersionTrack): define.
+
+       * katie.py (Katie.accept): add support for DebBugs Version
+       Tracking by writing out .versions (generated in jennifer's
+       get_changelog_versions()) and .debinfo (mapping of binary ->
+       source) files.
+
+       * ashley (main): add dsc["bts changelog"].
+
+       * katie.py (Katie.dump_vars): store dsc["bts changelog"] too.
+
+       * jennifer (check_diff): obsoleted by check_source(), removed.
+       (check_source): new function: create a temporary directory and
+       move into it and call get_changelog_versions().
+       (get_changelog_versions): new function: extract the source package
+       and optionally parse debian/changelog to obtain the version
+       history for the BTS.
+       (process_it): call check_source() rather than check_diff().
+
+2004-03-08  James Troup  <james@nocrew.org>
+
+       * lisa (edit_index): Fix logic swapo from 'use "if varfoo in
+       listbar" rather than "if listbar.count(varfoo)"' change on
+       2004-02-24.
+
+2004-03-05  James Troup  <james@nocrew.org>
+
+       * alicia (main): don't warn about not closing bugs - we don't
+       manage overrides through the BTS.
+
+2004-02-27  Martin Michlmayr  <tbm@cyrius.com>
+
+       * docs/README.config: lots of updates and corrections.
+       * docs/README.first: likewise.
+
+       * docs/README.config: drop unused Dir::Queue::Root.
+       * katie.conf-non-US: likewise.
+       * katie.conf: likewise.
+       * katie.conf-security: likewise.
+
+2004-02-27  James Troup  <james@nocrew.org>
+
+       * rose (process_tree): use 'if var in [ list ]' rather than long
+       'if var == foo or var == bar or var == baz'.  Suggested by Martin
+       Michlmayr.
+
+       * jennifer (check_files): reduce 'if var != None' to 'if var' as
+       suggested by Martin Michlmayr.
+       * catherine (poolize): likewise.
+       * charisma (main): likewise.
+       * halle (check_changes): likewise.
+       * heidi (main): likewise.
+       (process_file): likewise.
+       * kelly (install): likewise.
+       (stable_install): likewise.
+       * utils.py (fix_maintainer): likewise.
+
+       * apt.conf: add support for debian-installer in testing-proposed-updates.
+       * katie.conf (Suite::Testing-Proposed-Updates::UdebComponents):
+       add - set to main.
+
+       * mkmaintainers: add "-T15" option to wget of non-US packages file
+       so that we don't hang cron.daily if non-US is down.
+
+       * templates/lisa.prod (Subject): Prefix with "Comments regarding".
+
+       * templates/jennifer.bug-close: add Source and Source-Version
+       pseudo-headers that may be used for BTS Version Tracking someday
+       [ajt@].
+
+       * rene (do_nbs): special case linux-wlan-ng like we do for pcmcia.
+       (main): likewise.
+
+       * cron.unchecked: it's /org/ftp.debian.org not ftp-master.
+
+2004-02-25  James Troup  <james@nocrew.org>
+
+       * katie.conf (SuiteMappings): don't map testing-security to
+       proposed-updates.
+
+2004-02-24  James Troup  <james@nocrew.org>
+
+       * katie.py (Katie.__init__): remove unused 'values' field.
+
+       * utils.py (extract_component_from_section): use 's.find(c) != -1'
+       rather than 's.count(c) > 0'.
+
+       * katie.py (Katie.source_exists): use "if varfoo in listbar"
+       rather than "if listbar.count(varfoo)".
+       * halle (check_joey): likewise.
+       * jeri (check_joey): likewise.
+       * lisa (edit_index): likewise.
+       * jenna (stable_dislocation_p): likewise.
+
+       * jennifer (main): remove unused global 'nmu'.
+
+2004-02-03  Daniel Silverstone  <dsilvers@digital-scurf.org>
+
+       * pseudo-packages.maintainers (ftp.debian.org): Changed the maintainer
+         to be ftpmaster@ftp-master.debian.org to bring it into line with how
+         the dak tools close bugs.
+
+2004-02-02  Daniel Silverstone  <dsilvers@digital-scurf.org>
+
+       * katie.conf (Alicia): Added an Alicia section with email address
+       * templates/alicia.bug-close: Added
+       * docs/alicia.1.sgml: Added the docs for the -d/--done argument
+       * alicia (main): Added a -d/--done argument
+
+2004-02-02  Daniel Silverstone  <dsilvers@digital-scurf.org>
+
+       * templates/lisa.prod: Oops, missed a BITCH->PROD conversion
+
+2004-01-29  Daniel Silverstone  <dsilvers@digital-scurf.org>
+
+       * lisa (prod_maintainer): Added function to prod the maintainer without
+         accepting or rejecting the package
+       * templates/lisa.prod: Added this template for the prodding mail
+
+       * .cvsignore: Added neve-files which turns up in new installations
+
+2004-01-30  Daniel Silverstone  <dsilvers@digital-scurf.org>
+
+       * alicia (usage): Fixed usage message to offer section and priority
+         as seperately optional arguments.
+       * alicia (main): Added a % (arg) interpolation needed when only
+         one of section or priority is provided and it cannot be found.
+
+2004-01-29  Daniel Silverstone  <dsilvers@digital-scurf.org>
+
+       * alicia: Added
+       * docs/alicia.1.sgml: Added
+       * docs/Makefile: Added alicia to the list of manpages to build
+       * docs/README.names: Noted what alicia does
+       * docs/README.first: Noted where alicia is useful
+
+2004-01-21  James Troup  <james@nocrew.org>
+
+       * madison (main): add -b/--binary-type.
+       (usage): likewise.
+
+       * denise (main): generate debian-installer overrides for testing
+       too.
+       * apt.conf: add support for debian-installer in testing.
+       * katie.conf (Suite::Testing::UdebComponents): set to main.
+
+       * katie.conf (Dinstall::SigningKeyIds): 2004 key.
+       * katie.conf-non-US (Dinstall::SigningKeyIds): likewise.
+       * katie.conf-security (Dinstall::SigningKeyIds): likewise.
+
+       * utils.py (parse_changes): don't process data not inside the
+       signed data.  Thanks to Andrew Suffield <asuffield@debian.org> for
+       pointing this out.
+       * test/005/test.py (main): new test to test for above.
+
+2004-01-04  James Troup  <james@nocrew.org>
+
+       * jenna (write_filelists): correct typo, s/Components/Component/
+       for Options.
+
+2004-01-04  Ryan Murray  <rmurray@debian.org>
+
+       * cron.buildd: move update of overrides and Packages file...
+       * cron.unchecked: to here.
+       * katie.conf-non-US: (Dinstall::SingingKeyIds) update for 2003v2 key
+       * katie.conf-security: likewise
+
+2003-11-20  James Troup  <james@nocrew.org>
+
+       * jenna (main): don't use utils.try_with_debug(), it produces way
+       too much output.
+
+       * halle (check_changes): don't error out if a .changes refers to a
+       non-existent package, just warn and skip the file.
+
+       * docs/README.stable-point-release: mention halle and .changes
+       obsoleted by removal through melanie.  Update for 3.0r2.
+
+       * katie.conf (Suite::Stable::Version): bump to 3.0r2.
+       (Suite::Stable::Description): update for 3.0r2.
+       (Lauren::MoreInfoURL): likewise.
+       * katie.conf-non-US (Suite::Stable::Version): likewise.
+       (Suite::Stable::Description): likewise.
+       (Lauren::MoreInfoURL): likewise.
+
+       * apt.conf.stable (Default): don't define MaxContentsChange.
+       * apt.conf.stable-non-US (Default): likewise.
+
+       * lauren (reject): hack to work around partial replacement of an
+       upload, i.e. one or more binaries superseded by another source
+       package.
+
+2003-11-17  James Troup  <james@nocrew.org>
+
+       * pseudo-packages.maintainers: point installation-reports at
+       debian-boot@l.d.o rather than debian-testing@l.d.o at jello@d.o's
+       request.
+
+       * utils.py (parse_changes): calculate the number of lines once
+       with len() rather than max().
+
+       * jennifer (check_dsc): handle the .orig.tar.gz disappearing from
+       files, since check_dsc_against_db() deletes the .orig.tar.gz
+       entry.
+
+2003-11-13  Ryan Murray  <rmurray@debian.org>
+
+       * apt.conf: specify a src override file for debian-installer
+
+2003-11-10  James Troup  <james@nocrew.org>
+
+       * fernanda.py (strip_pgp_signature): new function - strips PGP
+       signature from a file and returns the modified contents of the
+       file in a string.
+       (display_changes): use it.
+       (read_dsc): likewise.
+
+2003-11-09  Ryan Murray  <rmurray@debian.org>
+
+       * cron.buildd: export accepted_autobuild table for unstable, and use
+       it to generate the incoming Packages/Sources rather than having apt
+       walk the directory.
+       * apt.conf.buildd: use exported table from cron.buildd to generate
+       Packages/Sources
+
+2003-11-07  James Troup  <james@nocrew.org>
+
+       * kelly: import errno.
+
+       * katie.py (Katie.build_summaries): sort override disparities.
+
+       * kelly (install): set dsc_component based on the .dsc's component
+       not a random binaries.
+
+2003-10-29  James Troup  <james@nocrew.org>
+
+       * katie.py (Katie.build_summaries): don't assume changes["source"]
+       exists since it might not.
+
+2003-10-20  James Troup  <james@nocrew.org>
+
+       * pseudo-packages.maintainers: update security.d.o to use
+       team@s.d.o at joy@'s request.
+
+2003-10-17  James Troup  <james@nocrew.org>
+
+       * jennifer (check_dsc): use .startswith rather than .find() == 0.
+
+2003-10-17  Martin Michlmayr  <tbm@cyrius.com>
+
+       * tea (chk_bd_process_dir): use .endswith rather than slice.
+
+2003-10-14  James Troup  <james@nocrew.org>
+
+       * tea (check_build_depends): new function.
+       (chk_bd_process_dir): likewise.  Validates build-depends in .dsc's
+       in the archive.
+       (main): update for new function.
+       (usage): likewise.
+
+       * katie.py (Katie.do_reject): sanitize variable names,
+       s/reject_filename/reason_filename/, s/fd/reason_fd/.  Move shared
+       os.close() to outside if clause.
+
+       * jennifer (check_dsc): check build-depends and
+       build-depends-indep by running them past apt_pkg.ParseSrcDepends.
+       Fold the ARRAY check into the same code block and tidy up it's
+       rejection message.
+       (check_changes): ensure that the Files field is non-empty.
+       Suggested by Santiago Vila <sanvila@unex.es>
+       (check_changes): normalize reject messages.
+       (check_dsc): instead of doing most of the checks inside a for loop
+       and an if, find the dsc_filename in a short loop over files first
+       and then do all the checks.  Add check for more than one .dsc in a
+       .changes which we can't handle.  Normalize reject messages.
+
+2003-10-13  James Troup  <james@nocrew.org>
+
+       * katie.conf (Dinstall::Reject::NoSourceOnly): set to true.
+       * katie.conf-non-US (Dinstall::Reject::NoSourceOnly): likewise.
+
+       * jennifer (check_files): Set 'has_binaries' and 'has_source'
+       variables while iterating over 'files'.  Don't regenerate it when
+       checking for source if source is mentioned.
+
+       Reject source only uploads if the config variable
+       Dinstall::Reject::NoSourceOnly is set.
+
+2003-10-03  James Troup  <james@nocrew.org>
+
+       * rene (main): add nasty hardcoded reference to debian-installer
+       so we detect NBS .udebs.
+
+2003-09-29  James Troup  <james@nocrew.org>
+
+       * apt.conf (old-proposed-updates): remove.
+       * apt.conf-non-US (old-proposed-updates): likewise.
+
+2003-09-24  James Troup  <james@nocrew.org>
+
+       * tea (check_files_not_symlinks): new function, ensure files
+       mentioned in the database aren't symlinks.  Includes code to
+       update any files that are like this to their real filenames +
+       location; commented out by though.
+       (usage): update for new function.
+       (main): likewise.
+
+2003-09-24  Anthony Towns  <ajt@debian.org>
+
+       * vars: external-overrides variable added
+       * cron.daily: Update testing/unstable Task: overrides from joeyh
+       managed external source.
+
+2003-09-22  James Troup  <james@nocrew.org>
+
+       * kelly (install): if we can't move the .changes into queue/done,
+       fail don't warn and carry on.  The old behaviour pre-dates NI and
+       doesn't make much sense now since jennifer checks both
+       queue/accepted and queue/done for any .changes files it's
+       processing.
+
+       * utils.py (move): don't throw exceptions on existing files or
+       can't overwrite, instead just fubar out.
+
+       * jennifer (check_dsc): also check Build-Depends-Indep for
+       ARRAY-lossage.  Noticed by Matt Zimmerman <mdz@debian.org>.
+
+2003-09-18  James Troup  <james@nocrew.org>
+
+       * katie.py (Katie.close_bugs): only log the bugs we've closed
+       once.
+
+       * kelly (main): log as 'kelly', not 'katie'.
+
+2003-09-16  James Troup  <james@nocrew.org>
+
+       * katie.py (Katie.check_binary_against_db): likewise noramlize.
+
+       * jennifer (check_changes): normalize reject message for "changes
+       file already exists" to be %s: <foo>.
+       (check_dsc): add a check for 'Build-Depends: ARRAY(<hex>)'
+       produced by broken dpkg-source in 1.10.11.  Tone down and
+       normalize rejection message for incompatible 'Format' version
+       numbers.
+       (check_diff): likewise tone down and normalize.
+
+2003-09-07  James Troup  <james@nocrew.org>
+
+       * utils.py (parse_changes): if dsc_whitespace_rules is false,
+       don't bomb out on bogus empty lines.
+       (build_file_list): check for changes["files"] earlier.  use Dict
+       to create files[name] dictionary.
+       (send_mail): don't bother validating arguments.
+       (check_signature): minor improvements to some of the rejection
+       messages including listing the key id of the key that wasn't found
+       in the keyring.
+       (wrap): new function.
+
+       * tea: add new check 'validate-indices' that ensures all files
+       mentioned in indices (Packages, Sources) files do in fact exist.
+
+       * catherine (poolize): use a local re_isadeb which handles legacy
+       (i.e. no architecture) style .deb filenames.
+
+       * rosamund: new script.
+
+       * rhona (check_binaries): when checking for binary packages not in
+       a suite, don't bother selecting files that already have a
+       last_used date.
+       (check_sources): likewise.
+
+       * rhona: change all SQL EXISTS sub-query clauses to use the
+       postgres suggested convention of "SELECT 1 FROM".
+       * andrea (main): likewise.
+       * tea (check_override): likewise.
+       * catherine (main): likewise.
+
+       * katie.conf (Suite): remove OldStable and Old-Proposed-Updates
+       entries and in other suites MustBeNewerThan's.
+       (SuiteMappings): likewise
+       * katie.conf-non-US: likewise.
+       * katie.conf-security: likewise.
+
+       * apt.conf-security: remove oldstable.
+       * apt.conf.stable: likewise.
+       * apt.conf.stable-non-US: likewise.
+       * cron.buildd-security: likewise.
+       * cron.daily-security: likewise.
+       * vars-security (suites): likewise.
+       * wanna-build/trigger.daily: likewise.
+
+       * claire.py (clean_symlink): move...
+       * utils.py (clean_symlink): here.
+
+       * claire.py (find_dislocated_stable): update accordingly.
+
+2003-08-16  Anthony Towns  <ajt@debian.org>
+
+       * katie.py (source_exists): expand the list of distributions
+       the source may exist in to include any suite that's mapped to
+       the destination suite (even transitively (a->b->c)). This should
+       unbreak binary uploads to *-proposed-updates.
+
+2003-08-09  Randall Donald  <rdonald@debian.org>
+
+       * lisa (recheck): change changes["distribution"].keys() to
+       Katie.pkg.changes...
+
+2003-08-08  Randall Donald  <rdonald@debian.org>
+
+       * katie.py: only tag bugs as fixed-in-experimental for
+       experimental uploads
+
+2003-07-26  Anthony Towns  <ajt@debian.org>
+
+       * katie.py (source_exists): add an extra parameter to limit the
+       distribution(s) the source must exist in.
+       * kelly, lisa, jennifer: update to use the new source_exists
+
+2003-07-15  Anthony Towns  <ajt@debian.org>
+
+       * ziyi: quick hack to support a FakeDI line in apt.conf to generate
+       checksums for debian-installer stuff even when it's just a symlink to
+       another suite
+
+       * apt.conf: add the FakeDI line
+
+2003-06-09  James Troup  <james@nocrew.org>
+
+       * kelly (check): make sure the 'file' we're looking for in 'files'
+       hasn't been deleted by katie.check_dsc_against_db().
+
+2003-05-07  James Troup  <james@nocrew.org>
+
+       * helena (time_pp): fix s/years/year/ typo.
+
+2003-04-29  James Troup  <james@nocrew.org>
+
+       * madison (usage): document -c/--component.
+
+       * madison (usage): Fix s/seperated/separated/.
+       * melanie (usage): likewise.
+       * jenna (usage): likewise.
+
+2003-04-24  James Troup  <james@nocrew.org>
+
+       * cron.daily-non-US: if there's nothing for kelly to install, say
+       so.
+
+       * jennifer (check_timestamps): print sys.exc_value as well as
+       sys.exc_type when capturing exceptions.  Prefix 'timestamp check
+       failed' with 'deb contents' to make it clearer what timestamp(s)
+       are being checked.
+
+2003-04-15  James Troup  <james@nocrew.org>
+
+       * cron.daily-non-US: only run kelly if there are some .changes
+       files in accepted.
+
+       * rene: add -m/--mode argument which can be either daily (default)
+       or full.  In daily mode only 'nviu' and 'nbs' checks are run.
+       Various changes to make this possible including a poor attempt at
+       splitting main() up a little.  De-hardcode suite numbers from SQL
+       queries and return quietly from do_nviu() if experimental doesn't
+       exist (i.e. non-US).  Hardcode pcmcia-cs as dubious NBS since it
+       is.
+
+       * debian/control (Depends): remove python-zlib as it's obsolete.
+
+       * charisma (main): don't slice the \n off strings when we're
+       strip()-ing it anyway.
+       * heidi (set_suite): likewise.
+       (process_file): likewise.
+       * natalie (process_file): likewise.
+
+2003-04-08  James Troup  <james@nocrew.org>
+
+       * katie.py (Katie.check_dsc_against_db): improve the speed of two
+       slow queries by using one LIKE '%foo%' and then matching against
+       '%s' or '/%s$' in python.  Also only join location when we need it
+       (i.e. the .orig.tar.gz query).  On auric, this knocks ~3s of each
+       query, so 6s for each sourceful package.
+
+       * cron.daily: invoke rene and send the report to ftpmaster.
+       * cron.daily-non-US: likewise.
+
+2003-03-14  James Troup  <james@nocrew.org>
+
+       * utils.py (send_mail): default filename to blank.
+       * amber (make_advisory): adapt.
+       * jennifer (acknowledge_new): likewise.
+       * katie.py (Katie.close_bugs): likewise.
+       (Katie.announce): likewise.
+       (Katie.accept): likewise.
+       (Katie.check_override): likewise.
+       (Katie.do_reject): likewise.
+       * kelly (do_reject): likewise.
+       (stable_install): likewise.
+       * lisa (do_bxa_notification): likewise.
+       * lauren (reject): likewise.
+       * melanie (main): likewise.
+
+       * rene (add_nbs): check any NBS packages against unstable to see
+       if they haven't been removed already.
+
+       * templates/katie.rejected: remove paragraph about rejected files
+       since they're o-rwx due to c-i-m and the uploader can't do
+       anything about them and shania will take care of them anyway.
+
+       * madison (usage): update usage example to use comma seperation.
+       * melanie (usage): likewise.
+
+       * utils.py (split_args): new function; splits command line
+       arguments either by space or comma (whichever is used).  Also has
+       optional-but-default DWIM spurious space detection to avoid
+       'command -a i386, m68k' problems.
+       (parse_args): use it.
+       * melanie (main): likewise.
+
+       * melanie (main): force the admin to tell someone if we're not
+       doing a rene-led removal (or closing a bug, which counts as
+       telling someone).
+
+2003-03-05  James Troup  <james@nocrew.org>
+
+       * katie.conf (Section): add embedded, gnome, kde, libdevel, perl
+       and python sections.
+       * katie.conf-security (Section): likewise.
+
+       * add_constraints.sql: add uid and uid_id_seq to grants.
+
+       * lisa (determine_new): also warn about adding overrides to
+       oldstable.
+
+       * madison (main): make the -S/--source-and-binary query obey
+       -s/--suite restrictions.
+
+2003-03-03  James Troup  <james@nocrew.org>
+
+       * madison (main): if the Archive_Maintenance_In_Progress lockfile
+       exists, warn the user that our output might seem strange.  (People
+       get confused by multiple versions in a suite which happens
+       post-kelly but pre-jenna.)
+
+2003-02-21  James Troup  <james@nocrew.org>
+
+       * kelly (main): we don't need to worry about StableRejector.
+
+       * melanie (main): sort versions with apt_pkg.VersionCompare()
+       prior to output.
+
+       * lauren: new script to manually reject packages from
+       proposed-updates.  Updated code from pre-NI kelly (nee katie).
+
+2003-02-20  James Troup  <james@nocrew.org>
+
+       * kelly (init): remove unused -m/--manual-reject argument.
+
+       * katie.py (Katie.force_reject): renamed from force_move to make
+       it more explicit what this function does.
+       (Katie.do_reject): update to match.
+
+       * utils.py (prefix_multi_line_string): add an optional argument
+       include_blank_lines which defaults to 0.  If non-zero, blank lines
+       will be includes in the output.
+
+       * katie.py (Katie.do_reject): don't add leading space to each line
+       of the reject message.  Include blank lines when showing the
+       message to the user.
+
+2003-02-19  Martin Michlmayr  <tbm@cyrius.com>
+
+       * utils.py (fix_maintainer): replace pointless re.sub() with
+       simple string format.
+
+2003-02-11  James Troup  <james@nocrew.org>
+
+       * lisa (edit_overrides): only strip-to-one-char and upper-case
+       non-numeric answers.  Fixes editing of items with indices >= 10;
+       noticed by Randall.
+       (edit_overrides): correct order of arguments to "not a valid
+       index" error message.
+
+       * jenna (cleanup): call resolve_arch_all_vs_any() rather than
+       remove_duplicate_versions(); thanks to aj for the initial
+       diagnosis.
+       (remove_duplicate_versions): correct how we return
+       dominant_versions.
+       (resolve_arch_all_vs_any): arch_all_versions needs to be a list of
+       a tuple rather than just a tuple.
+
+2003-02-10  James Troup  <james@nocrew.org>
+
+       * emilie: new script - sync fingerprint and uid tables with a
+       debian.org LDAP DB.
+
+       * init_pool.sql: new table 'uid'; contains user ids.  Reference it
+       in 'fingerprint'.
+
+       * db_access.py (get_or_set_uid_id): new function.
+
+       * jennifer (main): update locking to a) not used FCNTL (deprecated
+       in python >= 2.2) and b) acknowledge upstream's broken
+       implementation of lockf (see Debian bug #74777), c) try to acquire
+       the lock non-blocking.
+       * kelly (main): likewise.
+
+       * contrib/python_1.5.2-fcntl_lockf.diff: obsolete, removed.
+
+       * madison (main): only append the package to new_packages if it's
+       not already in there; fixes -S/--source-and-binary for cases where
+       the source builds a binary package of the same name.
+
+2003-02-10  Anthony Towns  <ajt@debian.org>
+
+       * madison (main): use explicit JOIN syntax for
+       -S/--source-and-binary queries to reduce the query's runtime from
+       >10 seconds to negligible.
+
+2003-02-08  James Troup  <james@nocrew.org>
+
+       * rene (main): in the NVIU output, append items to lists, not
+       extend them; fixes amusing suggestion that "g n u m e r i c" (sic)
+       should be removed.
+
+2003-02-07  James Troup  <james@nocrew.org>
+
+       * apt.conf (tree "dists/unstable"): Add bzip2-ed Packages and
+       Sources [aj].
+
+       * pseudo-packages.maintainers (bugs.debian.org): s/Darren
+       O. Benham/Adam Heath/.
+
+       * katie.conf (Suite::Stable::Version): bump to 3.0r1a.
+       (Suite::Stable::Description): update for 3.0r1a.
+       (Dinstall::SigningKeyIds): update for 2003 key [aj].
+
+       * utils.py (gpgv_get_status_output): rename from
+       get_status_output().
+
+       * neve (check_signature): use gpgv_get_status_output and Dict from
+       utils().  Add missing newline to error message about duplicate tokens.
+
+       * saffron (per_arch_space_use): also print space used by source.
+       (output_format): correct string.join() invocation.
+
+       * jennifer (check_signature): ignored duplicate EXPIRED tokens.
+
+2003-02-04  James Troup  <james@nocrew.org>
+
+       * cron.buildd: correct generation of Packages/Sources and grep out
+       non-US/non-free as well as non-free.
+
+2003-02-03  Ryan Murray  <rmurray@debian.org>
+
+       * cron.buildd: generate quinn-diff output with full Packages/Sources
+         files to get out-of-date vs. uncompiled right.
+       * apt.conf.buildd: no longer generate uncompressed files, as they
+         are generated in cron.buildd instead
+       * add -i option to quinn-diff to ignore binary-all packages
+       * apt.conf.buildd: remove and readd udeb to extensions.  If the udebs
+         aren't in the packages file, the arch that uploaded them will build
+         them anyways...
+
+2003-01-30  James Troup  <james@nocrew.org>
+
+       * rene (main): only print suggested melanie command when there's
+       some NBS to remove.
+
+2003-01-30  Ryan Murray  <rmurray@debian.org>
+
+       * cron.buildd: fix incorrectly inverted lockfile check
+
+2003-01-29  Ryan Murray  <rmurray@debian.org>
+
+       * cron.buildd: generate override.sid.all3.src
+       * apt.conf.buildd: use generated override.sid.all3.src
+
+2003-01-27  Martin Michlmayr  <tbm@cyrius.com>
+
+       * utils.py (get_status_output): moved from jennifer.
+       (Dict): likewise.
+       (check_signature): likewise.
+
+       * jennifer (get_status_output): moved to utils.py.
+       (Dict): likewise.
+       (check_signature): likewise.
+
+       * utils.py (check_signature): add an argument to specifiy which
+       function to call when an error was found.
+       (check_signature): document this function better.
+
+       * jennifer (check_files): pass the reject function as an argument
+       to utils.check_signature.
+       (process_it): likewise.
+
+2003-01-20  James Troup  <james@nocrew.org>
+
+       * rene (main): lots of changes to improve the output and make it
+       more useful.
+
+       * katie.py (Katie.check_override): make the override messages
+       clearer (hopefully).
+
+2002-12-26  James Troup  <james@nocrew.org>
+
+       * ziyi (usage): document the ability to pass suite(s) as
+       argument(s).
+       (main): read apt.conf after checking for -h/--help.
+
+       * tea (main): take the check to run as an argument.
+
+       * saffron.R: R script to graph daily install runs.
+
+       * saffron: new script; various stats functions.
+
+       * rhona (main): connect to the database after checking for -h/--help.
+
+       * neve (do_da_do_da): if no -a/--action option is given, bail out.
+
+       * melanie (main): sort versions with utils.arch_compare_sw().
+
+       * madison (usage): alphabetize order of options.
+       * melanie (usage): likewise.
+
+       * kelly (usage): fix usage short description (we aren't dinstall).
+
+       * julia (usage): fix usage description and alphabetize order of
+       options.
+
+       * jeri (usage): fix usage short description.
+
+       * jennifer (main): move --help and --version checks from here...
+       (init): to here so that they work with an empty katie.conf.
+       * kelly: likewise.
+
+       * alyson (usage): new function.
+       (main): use it.
+       * andrea: likewise.
+       * ashley: likewise.
+       * cindy: likewise.
+       * denise: likewise.
+       * helena: likewise.
+       * neve: likewise.
+       * rene: likewise.
+       * rose: likewise.
+       * tea: likewise.
+
+       * apt.conf.stable (tree "dists/stable"): add missing ExtraOverride
+       entry that caused tasks to be omitted from 3.0r1.
+
+2002-12-10  James Troup  <james@nocrew.org>
+
+       * jennifer (check_files): sanity check the Depends field to ensure
+       it's non-empty if present since apt chokes on an empty one.
+       Thanks to Ryan Murray for the idea.
+
+2002-12-08  James Troup  <james@nocrew.org>
+
+       * katie.conf-security (Helena::Directories): new; include accepted
+       in addition to byhand and new.
+
+       * helena (process_changes_files): use utils.arch_compare_sw().
+       Justify things based on the longest [package, version,
+       architecture].  Reduce '[note]' to '[N]' to save space, and remove
+       the commas in architecture and version lists for the same reason.
+       (main): make directories we process configurable through
+       Helena::Directories in the config file; if that doesn't exist
+       default to the old hardcoded values (byhand & new).
+
+       * utils.py (arch_compare_sw): moved here from madison.
+       * madison (main): adjust to compensate.
+
+2002-12-06  James Troup  <james@nocrew.org>
+
+       * ziyi (main): fix "suite foo not in apt.conf" msg to use the
+       right filename.
+
+2002-12-05  James Troup  <james@nocrew.org>
+
+       * katie.conf-non-US (Julia::KnownPostgres): add 'udmsearch'.
+
+2002-11-28  Randall Donald  <rdonald@debian.org>
+
+       * fernanda.py (read_control): fix typo of 'Architecture'.
+
+2002-11-26  James Troup  <james@nocrew.org>
+
+       * lisa (check_pkg): call less with '-R' so we see the colour from
+       Randall's fernanda changes.
+
+       * neve (process_sources): if Directory points to a legacy location
+       but the .dsc isn't there; assume it's broken and look in the pool.
+       (update_section): new, borroed from alyson.
+       (do_da_do_da): use it.
+       (process_packages): add suite_it to the cache key used for
+       arch_all_cache since otherwise we only add a package to the first
+       suite it's in and ignore any subsequent ones.
+
+       * katie.conf-non-US (Location): fixed to reflect reality (all
+       suites, except old-proposed-updates (which is legacy-mixed)) are
+       pool.
+
+       * utils.py (try_with_debug): wrapper for print_exc().
+       * jenna (main): use it.
+       * neve (main): likewise.
+
+2002-11-25  Randall Donald  <rdonald@debian.org>
+
+       * fernanda.py (main): added -R to less command line for raw control
+       character support to print colours
+       (check_deb): Instead of running dpkg -I on deb file, call
+       output_deb_info, the new colourized control reporter.
+       (check_dsc): add call to colourized dsc info reader, read_dsc, instead
+       of printing out each .dsc line.
+       (output_deb_info): new function. Outputs each key/value pair from
+       read_control except in special cases where we highlight section,
+       maintainer, architecture, depends and recommends.
+       (create_depends_string): new function. Takes Depends tree and looks
+       up it's compontent via projectb db, colourizes and constructs a
+       depends string in original order.
+       (read_dsc): new function. reads and parses .dsc info via
+       utils.parse_changes. Build-Depends and Build-Depends-Indep are
+       colourized.
+       (read_control): new function. reads and parses control info via
+       apt_pkg. Depends and Recommends are split in to list structures,
+       Section and Architecture are colourized. Maintainer is colourized
+       if it has a localhost.localdomain address.
+       (split_depends): new function. Creates a list of lists of
+       dictionaries of depends (package,version relation). Top list is
+       colected from comma delimited items. Sub lists are | delimited.
+       (get_comma_list): new function. splits string input among commas
+       (get_or_list): new function. splits string input among | delimiters
+       (get_depends_parts): new function. Creates dictionary of package name
+       and version relation from dependancy string.
+       Colours for section and depends are per component. Unfound depends
+       are in bold. Lookups using version info is not supported yet.
+
+2002-11-22  James Troup  <james@nocrew.org>
+
+       * katie.conf-security (Julia::KnownPostgres): add 'www-data' and
+       'udmsearch'.
+
+       * amber (make_advisory): string.atol() is deprecated and hasn't
+       been ported to string methods.  Use long() instead.
+
+       * init_pool.sql: explicitly specify the encoding (SQL_ASCII) when
+       creating the database since we'll fail badly if it's created with
+       e.g. UNICODE encoding.
+
+       * rose (main): AptCnf is a global.
+
+       * neve (get_location_path): new function determines the location
+       from the the first (left-most) directory of a Filename/Directory.
+       (process_sources): don't need 'location' anymore.  Use
+       utils.warn().  Use the Directory: field for each package to find
+       the .dsc.  Use get_location_path() to determine the location for
+       each .dsc.
+       (process_packages): do't need 'location' anymore.  Use
+       utils.warn().  Use get_location_path().
+       (do_sources): don't need 'location', drop 'prefix' in favour of
+       being told the full path to the Sources file, like
+       process_packages().
+       (do_da_do_da): main() renamed, so that main can call us in a
+       try/except.  Adapt for the changes in do_sources() and
+       process_packages() above.  Assume Sources and Packages file are in
+       <root>/dists/<etc.>.  Treat pool locations like we do legacy ones.
+
+       * katie.conf-security (Location): fixed to reflect reality (all
+       suites are pool, not legacy).
+
+       * utils.py (print_exc): more useful (i.e. much more verbose)
+       traceback; a recipe from the Python cookbook.
+       * jenna (main): use it.
+       * neve (main): likewise.
+
+2002-11-19  James Troup  <james@nocrew.org>
+
+       * kelly (install): fix brain-damaged CopyChanges/CopyKatie
+       handling which was FUBAR for multi-suite uploads.  Now we just
+       make a dictionary of destinations to copy to and iterate over
+       those.
+
+       * fernanda.py (check_deb): run linda as well as lintian.
+
+2002-10-21  James Troup  <james@nocrew.org>
+
+       * melanie (main): change X-Melanie to X-Katie and prefix it with
+       'melanie '.
+
+       * lisa (main): prefix X-Katie with 'lisa '.
+
+       * jennifer (clean_holding): fix typo in string method changes;
+       s/file.find(file/file.find(/.
+
+       * cron.daily: invoke helena and send the report to ftpmaster.
+       * cron.daily-non-US: likewise.
+
+2002-10-16  James Troup  <james@nocrew.org>
+
+       * kelly (check): call reject() with a blank prefix when parsing
+       the return of check_dsc_against_db() since it does its own
+       prefix-ing.
+
+       * rose: new script; only handles directory creation initally.
+
+       * katie.conf (Dinstall::NewAckList): obsolete, removed.
+       * katie.conf-non-US (Dinstall::NewAckList): likewise.
+
+2002-10-06  James Troup  <james@nocrew.org>
+
+       * rene (main): remove bogus argument handling.
+
+       * kelly: katie, renamed.
+       * cron.daily: adapt for katie being renamed to kelly.
+       * cron.daily-non-US: likewise.
+       * amber (main): likewise.
+
+       * Changes for python 2.1.
+
+       * kelly: time.strftime no longer requires a second argument of
+       "time.localtime(time.time())".
+       * logging.py: likewise.
+       * rhona: likewise.
+       * shania (init): likewise.
+
+       * amber: use augmented assignment.
+       * catherine (poolize): likewise.
+       * claire.py (fix_component_section): likewise.
+       * halle (check_changes): likewise.
+       * helena: likewise.
+       * jenna: likewise.
+       * jennifer: likewise.
+       * jeri: likewise.
+       * katie.py: likewise.
+       * kelly: likewise.
+       * lisa: likewise.
+       * madison (main): likewise.
+       * melanie: likewise.
+       * natalie: likewise.
+       * neve: likewise.
+       * rhona: likewise.
+       * tea: likewise.
+       * utils.py: likewise.
+       * ziyi: likewise.
+
+       * amber: use .endswith.
+       * fernanda.py: likewise.
+       * halle (main): likewise.
+       * jennifer: likewise.
+       * jeri: likewise.
+       * katie.py: likewise.
+       * kelly: likewise.
+       * lisa: likewise.
+       * neve: likewise.
+       * shania (main): likewise.
+       * utils.py: likewise.
+
+       * alyson: use string methods.
+       * amber: likewise.
+       * andrea: likewise.
+       * ashley: likewise.
+       * catherine: likewise.
+       * charisma: likewise.
+       * claire.py: likewise.
+       * db_access.py: likewise.
+       * denise: likewise.
+       * halle: likewise.
+       * heidi: likewise.
+       * helena: likewise.
+       * jenna: likewise.
+       * jennifer: likewise.
+       * jeri: likewise.
+       * julia: likewise.
+       * katie.py: likewise.
+       * kelly: likewise.
+       * lisa: likewise.
+       * logging.py: likewise.
+       * madison: likewise.
+       * melanie: likewise.
+       * natalie: likewise.
+       * neve: likewise.
+       * rene: likewise.
+       * tea: likewise.
+       * utils.py: likewise.
+       * ziyi: likewise.
+
+2002-09-20  Martin Michlmayr  <tbm@cyrius.com>
+
+       * utils.py (parse_changes): use <string>.startswith() rather than
+       string.find().
+
+2002-08-27  Anthony Towns  <ajt@debian.org>
+
+       * katie.py (in_override_p): when searching for a source override,
+       and the dsc query misses, search for both udeb and deb overrides
+       as well. Should fix the UNACCEPT issues with udebs.
+
+2002-08-24  James Troup  <james@nocrew.org>
+
+       * melanie (main): remove gratuitous WHERE EXISTS sub-select from
+       source+binary package finding code which was causing severe
+       performance degradation with postgres 7.2.
+
+2002-08-14  James Troup  <james@nocrew.org>
+
+       * julia (main): use the pwd.getpwall() to get system user info
+       rather than trying to read a password file.  Add a -n/--no-action
+       option.
+
+       * cron.hourly: julia no longer takes any arguments.
+       * cron.hourly-non-US: likewise.
+
+2002-08-07  James Troup  <james@nocrew.org>
+
+       * katie (install): handle multi-suite uploads when CopyChanges
+       and/or CopyKatie are in use, ensuring we only copy stuff once.
+
+2002-08-01  Ryan Murray  <rmurray@debian.org>
+
+       * wanna-build/trigger.daily: initial commit, with locking
+       * cron.buildd: add locking against daily run
+
+2002-07-30  James Troup  <james@nocrew.org>
+
+       * melanie (main): readd creation of suite_ids_list so melanie is
+       remotely useful again.
+
+       * katie.conf: adopt for woody release; diable
+       StableDislocationSupport, add oldstable, adjust other suites and
+       mappings, fix up location.
+       * katie.conf-non-US: likewise.
+       * katie.conf-security: likewise.
+
+       * apt.conf.stable: adapt for woody release; add oldstable, adjust
+       stable.
+       * apt.conf.stable-non-US: likewise.
+
+       * apt.conf-security: adapt for woody release; adding oldstable,
+       oldstable, adjust stable and testing.
+       * cron.daily-security: likewise.
+       * cron.buildd-security: likewise.
+
+       * apt.conf: adapt for woody release; rename woody-proposed-updates
+       to testing-proposed-updates and proposed-updates to
+       old-proposed-updates.
+       * apt.conf-non-US: likewise.
+
+       * vars-non-US (copyoverrides): add sarge.
+       * vars (copyoverrides): likewise.
+
+       * vars-security (suites): add oldstable.
+
+2002-07-22  Ryan Murray  <rmurray@debian.org>
+
+       * apt.conf.security-buildd: use suite codenames instead of
+         distnames.
+
+2002-07-16  James Troup  <james@nocrew.org>
+
+       * denise (main): fix filenames for testing override files.
+
+2002-07-14  James Troup  <james@nocrew.org>
+
+       * jennifer (process_it): call check_md5sums later so we can check
+       files in the .dsc too
+       (check_md5sums): check files in the .dsc too.  Check both md5sum
+       and size.
+
+       * melanie (main): use parse_args() and join_with_commas_and() from
+       utils.  If there's nothing to do, say so and exit, don't ask for
+       confirmation etc.
+
+       * amber (join_with_commas_and): moved from here to ...
+       * utils.py (join_with_commas_and): here.
+
+2002-07-13  James Troup  <james@nocrew.org>
+
+       * madison (main): use parse_args() from utils.  Support
+       -c/--component.
+
+       * jenna (parse_args): moved from here to ...
+       * utils.py (parse_args): here.
+
+       * katie.conf (Architectures): minor corrections to the description
+       for arm, mips and mipsel.
+       * katie.conf-non-US (Architectures): likewise.
+       * katie.conf-security (Architectures): likewise.
+
+       * cron.daily-security: use natalie's new -a/--add functionality to
+       flesh out the security overrides.
+
+2002-07-12  James Troup  <james@nocrew.org>
+
+       * cron.buildd (ARCHS): add arm.
+
+       * katie.conf: 2.2r7 was released.
+       * katie.conf-non-US: likewise.
+
+       * utils.py (parse_changes): handle a multi-line field with no
+       starting line.
+
+2002-06-25  James Troup  <james@nocrew.org>
+
+       * templates/amber.advisory (To): add missing email address since
+       __WHOAMI__ is only a name.
+
+       * katie.conf-security (Melane::LogFile): correct to go somewhere
+       katie has write access to.
+       (Location::/org/security.debian.org/ftp/dists/::Suites): add
+       Testing.
+
+       * natalie: add support for -a/-add which adds packages only
+       (ignoring changes and deletions).
+
+       * katie.py (Katie.announce): Dinstall::CloseBugs is a boolean so
+       use FindB, not get.
+
+2002-06-22  James Troup  <james@nocrew.org>
+
+       * jennifer (check_files): validate the package name and version
+       field.  If 'Package', 'Version' or 'Architecture' are missing,
+       don't try any further checks.
+       (check_dsc): likewise.
+
+       * utils.py (re_taint_free): add '~' as a valid character.
+
+2002-06-20  Anthony Towns  <ajt@debian.org>
+
+       * katie.conf-non-US: add OverrideSuite for w-p-u to allow uploads
+
+2002-06-09  James Troup  <james@nocrew.org>
+
+       * jennifer (check_files): reduce useless code.
+
+       * cron.daily-security: run symlinks -dr on $ftpdir.
+
+       * vars-security (ftpdir): add.
+
+2002-06-08  James Troup  <james@nocrew.org>
+
+       * neve (update_override_type): transaction is handled higher up in
+       main().
+       (update_priority): likewise.
+       (process_sources): remove code that makes testing a duplicate of
+       stable.
+       (process_packages): likewise.
+
+       * templates/amber.advisory: add missing mail headers.
+
+       * cron.daily-security: also call apt-ftparchive clean for
+       apt.conf.buildd-security.
+       * cron.weekly: likewise.
+
+       * amber (do_upload): write out a list of source packages (and
+       their version) uploaded for testing.
+       (make_advisory): add more Subst mappings for the mail headers.
+       (spawn): check for suspicious characters in the command and abort
+       if their found.
+
+2002-06-07  James Troup  <james@nocrew.org>
+
+       * ziyi (main): remove the 'nonus'/'security' hacks and use
+       Dinstall::SuiteSuffix (if it exists) instead.  Always try to write
+       the lower level Release files, even if they don't exist.  fubar
+       out if we can't open a lower level Release file for writing.
+
+       * katie.conf-non-US (Dinstall): add SuiteSuffix, used to simplify
+       ziyi.
+       * katie.conf-security (Dinstall): likewise.
+
+       * amber (do_upload): renamed from get_file_list().  Determine the
+       upload host from the original component.
+       (init): Add a -n/--no-action option.  Fix how we get changes_files
+       (i.e. from the return value of apt_pkg.ParseCommandLine(), not
+       sys.argv).  Add an Options global.
+       (make_advisory): support -n/--no-action.
+       (spawn): likewise.
+       (main): likewise.
+       (usage): document -n/--no-action.
+
+       * cron.buildd-security: fix path to Packages-arch-specific in
+       quinn-diff invocation.
+
+       * katie.conf-security (Dinstall::AcceptedAutoBuildSuites): change
+       to proper suite names (i.e. stable, testing) rather than codenames
+       (potato, woody).
+       (Dinstall::DefaultSuite): likewise.
+       (Suite): likewise.
+       (Location::/org/security.debian.org/ftp/dists/::Suites): likewise.
+       * vars-security (suites): likewise.
+       * apt.conf-security: likewise.
+
+       * katie.conf-security (Component): add "updates/" prefix.
+       (Suite::*::Components): likewise.
+       (ComponentMappings): new; map all {ftp-master,non-US} components
+       -> updates/<foo>.
+
+       * katie.conf-security (Natalie): removed; the options have
+       defaults and ComponentPosition is used by alyson which doesn't
+       work on security.d.o.
+       (Amber): replace UploadHost and UploadDir with ComponentMappings
+       which is a mapping of components -> URI.
+       (Suite::*::CodeName): strip bogus "/updates" suffix hack.
+       (SuiteMappings): use "silent-map" in preference to "map".
+
+       * cron.unchecked-security: fix call to cron.buildd-security.
+
+       * cron.daily-security: map local suite (stable) -> override suite
+       (potato) when fixing overrides.  Correct component in natalie call
+       to take into account "updates/" prefix.  Fix cut'n'waste in
+       override.$dist.all3 generation, the old files weren't being
+       removed, so they were endlessly growing.
+
+       * neve (main): don't use .Find for the CodeName since we require
+       it.  Location::*::Suites is a ValueList.
+       (check_signature): ignore duplicate SIGEXPIRED tokens.  Don't bomb
+       out on expired keys, just warn.
+       (update_override_type): new function; lifted from alyson.
+       (update_priority): likewise.
+       (main): use update_{override_type,priority}().
+
+       * jennifer (check_distributions): remove redunant test for
+       SuiteMappings; ValueList("does-not-exist") returns [] which is
+       fine.  Add support for a "silent-map" type which doesn't warn
+       about the mapping to the user.
+       (check_files): add support for ComponentMappings, similar to
+       SuiteMappings, but there's no type, just a source and a
+       destination and the original component is stored in "original
+       component".
+       * katie.py (Katie.dump_vars): add "original component" as an
+       optionsal files[file] dump variable.
+
+       * claire.py (find_dislocated_stable): dehardcode 'potato' in SQL
+       query.  Add support for section-less legacy locations like current
+       security.debian.org through YetAnotherConfigBoolean
+       'LegacyStableHasNoSections'.
+       * katie.conf-security (Dinstall): LegacyStableHasNoSections is true.
+
+       * utils.py (real_arch): moved here from ziyi.
+       * ziyi (real_arch): moved to utils.py.
+       * ziyi (main): likewise.
+
+       * claire.py (find_dislocated_stable): use real_arch() with
+       filter() to strip out source and all.
+       * neve (main): likewise.
+       * rene (main): likewise.
+       * jeri (parse_packages): likewise.
+
+2002-06-06  James Troup  <james@nocrew.org>
+
+       * tea (check_missing_tar_gz_in_dsc): modifed patch from Martin
+       Michlmayr <tbm@cyrius.com> to be more verbose about what we're
+       doing.
+
+2002-05-23  Martin Michlmayr  <tbm@cyrius.com>
+
+       * jeri (check_joey): check if the line contains two elements
+       before accessing the second.  Also, strip trailing spaces as well
+       as the newline.
+       * halle (check_joey): likewise.
+
+2002-06-05  James Troup  <james@nocrew.org>
+
+       * cron.unchecked-security: new file; like cron.unchecked but if
+       there's nothing to do exit so we don't call cron.buildd-security.
+
+       * apt.conf.buildd-security: new file.
+
+       * vars (archs): alphabetize.
+       * vars-non-US (archs): likewise.
+
+       * vars-security: add unchecked.
+
+       * madison (main): reduce rather bizarrely verbose and purposeless
+       code to print arches to a simple string.join.
+
+       * katie.conf (Suites::Unstable): add UdebComponents, a new
+       valuelist of suites, used by jenna to flesh out the list of
+       <suite>_main-debian-installer-binary-<arch>.list files generated.
+       (Dinstall): add StableDislocationSupport, a new boolean used by
+       jenna to enable or disable stable dislocation support
+       (i.e. claire), as true.
+
+       * katie.conf (Dinstall): add StableDislocationSupport, a new
+       boolean used by jenna to enable or disable stable dislocation
+       support (i.e. claire), as true.
+       * katie.conf-non-US: likewise.
+       * katie.conf-security: likewise.
+
+       * cron.daily-security: generate .all3 overrides for the buildd
+       support.  Freshen a local copy of Packages-arch-specific from
+       buildd.debian.org.
+
+       * claire.py (find_dislocated_stable): disable the support for
+       files in legacy-mixed locations since none of the Debian archives
+       have any anymore.
+
+       * helena: new script; produces a report on NEW and BYHAND
+       packages.
+
+       * jenna: rewritten from scratch to fix speed problems.  Run time
+       on auric goes down from 31.5 minutes to 3.5 minutes.  Of that 3.5
+       minutes, 105 seconds are the monster query and 70 odd seconds is
+       claire.
+
+       * apt.conf.buildd (Default): remove MaxContentsChange as it's
+       irrelevant.
+
+2002-06-05  Ryan Murray  <rmurray@debian.org>
+
+       * cron.buildd-security: new file.
+
+2002-06-05  Matt Kraai  <kraai@alumni.cmu.edu>
+
+       * denise (list): take a file argument and use it.
+       (main): don't abuse sys.stdout, just write to the file.
+
+       * claire.py (usage): Fix misspelling.
+       (clean_symlink): Simplify.
+       (find_dislocated_stable): Avoid unnecessary work.
+
+2002-05-29  James Troup  <james@nocrew.org>
+
+       * cameron: removed; apt-ftparchive can simply walk the directory.
+
+2002-05-26  Anthony Towns  <ajt@debian.org>
+
+       * katie.conf{,-non-US}: Map testing to testing-proposed-updates
+       for the autobuilders.
+
+2002-05-24  Ryan Murray  <rmurray@debian.org>
+
+       * cron.buildd: update override files before running apt-ftparchive
+
+2002-05-23  Martin Michlmayr  <tbm@cyrius.com>
+
+       * amber (main): remove extra space in prompt.
+
+       * utils.py (validate_changes_file_arg): use original filename in
+       error messages.
+
+       * jeri (check_joey): close file after use.
+       (parse_packages): likewise.
+       (main): setup debug option properly.
+
+       * melanie (main): remove unused packages variable and simplify the
+       code to build up con_packages by using repr().
+
+2002-05-23  James Troup  <james@nocrew.org>
+
+       * lisa (recheck): when we reject, also return 0 so the package is
+       skipped.
+       (sg_compare): fix note sorting.
+       (recheck): remove the .katie file after rejection.
+
+       * katie.py (Katie.accept): accepted auto-build support take 3;
+       this time adding support for security.  Security needs a) non-pool
+       files copied rather than symlinked since accepted is readable only
+       by katie/security and www-data needs to be able to see the files,
+       b) needs per-suite directories.  SpecialAcceptedAutoBuild becomes
+       AcceptedAutoBuildSuites and is a ValueList containing the suites.
+       SecurityAcceptedAutoBuild is a new boolean which controls whether
+       or not normal or security style is used.  The unstable_accepted
+       table was renamed to accepted_autobuild and a suite column added.
+       Also fix a bug noticed by Ryan where an existent orig.tar.gz
+       didn't have it's last_used/in_accepted flags correctly updated.
+       * katie (install): likewise.
+       * rhona (clean_accepted_autobuild): likewise.
+
+2002-05-22  James Troup  <james@nocrew.org>
+
+       * lisa (sort_changes): new function; sorts changes properly.
+       Finally.
+       (sg_compare): new function; helper for sort_changes().  Sorts by
+       have note and time of oldest upload.
+       (indiv_sg_compare): new function; helper for sort_changes().
+       Sorts by source version, have source and filename.
+       (main): use sort_changes().
+       (changes_compare): obsoleted; removed.
+
+2002-05-20  James Troup  <james@nocrew.org>
+
+       * rhona (clean_accepted_autobuild): don't die if a file we're
+       trying to remove doesn't exist.  Makes rhona more friendly to
+       katie/katie.py crashes/bugs without any undue cost.
+
+2002-05-19  James Troup  <james@nocrew.org>
+
+       * lisa (main): if sorting a large number of changes give some
+       feedback.
+       (recheck): new function, run the same checks (modulo NEW,
+       obviously) as katie does, if they fail do the standard
+       reject/skip/quit dance.
+       (do_pkg): use it.
+
+       * katie (install): don't try to unlink the symlink in the
+       AcceptedAutoBuild support if the destination is not a symlink (or
+       doesn't exist).  Avoids unnecessary bombs on previous partial
+       accepts and will still bomb hard if the file exists and isn't a
+       symlink.
+
+       * utils.py: blah, commands _is_ used when the mail stuff isn't
+       commented out like it is in my test environment.
+
+       * lisa (changes_compare): "has note" overrides everything else.
+       Use .katie files rather than running parse_changes, faster and
+       allows "has note" to work.  Correct version compare, it was
+       reversed.  Ctime check should only kick in if the source packages
+       are not the same.
+       (print_new): print out and return any note.  Rename 'ret_code' to
+       'broken'.
+       (edit_new): renamed from spawn_editor.  Don't leak file
+       descriptors.  Clean up error message if editor fails.
+       (edit_note): new function, allows one to edit notes.
+       (do_new): add note support, editing and removing.
+       (init): kill -s/--sort; with notes we always want to use our
+       sorting method.
+       (usage): likewise.
+
+       * katie.py (Katie.dump_vars): add "lisa note" as an optional
+       changes field.
+
+       * utils.py (build_file_list): rename 'dsc' to 'is_a_dsc' and have
+       it default to 0.  Adapt tests to assume it's boolean.
+       * fernanda.py (check_changes): adjust call appropriately.
+       * halle (check_changes): likewise.
+       * jennifer (check_changes): likewise.
+       * jeri (check_changes): likewise.
+       * shania (flush_orphans): likewise.
+
+       * jennifer (check_dsc): pass is_a_dsc by name when calling
+       build_file_list() for clarity.
+       * shania (flush_orphans): likewise.
+       * tea (check_missing_tar_gz_in_dsc): likewise.
+
+       * jennifer (check_dsc): pass dsc_whitespace_rules by name when
+       calling parse_changes() for clarity.
+       * tea (check_dscs): likewise.
+
+       * utils.py (parse_changes): make dsc_whitespace_rules default to
+       not true.
+       * halle (check_changes): adjust call appropriately.
+       * jennifer (check_changes): likewise.
+       * jeri (check_changes): likewise.
+       * lisa (changes_compare): likewise.
+       * utils.py (changes_compare): likewise.
+       * melanie (main): likewise.
+       * shania (flush_orphans): likewise.
+       * fernanda.py (check_changes): likewise.
+
+2002-05-18  James Troup  <james@nocrew.org>
+
+       * katie.py (Katie.dump_vars): make the .katie file unreadable,
+       it's not useful and by and large a duplication of information
+       available in readable format in other files.
+
+2002-05-16  Ryan Murray  <rmurray@debian.org>
+
+       * melanie: Dir::TemplatesDir -> Dir::Templates
+
+2002-05-15  Ryan Murray  <rmurray@debian.org>
+
+       * cameron: correct the use of os.path.join
+
+2002-05-15  Anthony Towns  <ajt@debian.org>
+
+       * ziyi: Update to match the new format for Architectures/Components
+       in katie.conf.
+
+2002-05-14  James Troup  <james@nocrew.org>
+
+       * amber: new script; 'installer' wrapper script for the security
+       team.
+
+       * katie.py (Katie.announce): remove unused 'dsc' local
+       variable. (pychecker)
+
+       * ziyi: pre-define AptCnf and out globals to None. (pychecker)
+
+       * neve: don't import sys, we don't use it. (pychecker)
+       (check_signature): fix return type mismatch. (pychecker)
+
+       * utils.py: don't import commands, we don't use it.  (pychecker)
+
+       * katie (install): SpecialAcceptedAutoBuild is a boolean.
+
+       * katie.py (Katie.dump_vars): don't store "oldfiles", it's
+       obsoleted by the change to "othercomponents" handling in jennifer
+       detailed below.
+       (Katie.cross_suite_version_check): new function; implements
+       cross-suite version checking rules specified in the conf file
+       while also enforcing the standard "must be newer than target
+       suite" rule.
+       (Katie.check_binary_against_db): renamed, since it's invoked once
+       per-binary, "binaries" was inaccurate.  Use
+       cross_suite_version_check() and don't bother with the "oldfiles"
+       rubbish as jennifer works out "othercomponents" herself now.
+       (Katie.check_source_against_db): use cross_suite_version_check().
+
+       * katie (check): the version and file overwrite checks
+       (check_{binary,source,dsc}_against_db) are not per-suite.
+
+       * jennifer (check_files): less duplication of
+       'control.Find("Architecture", "")' by putting it in a local
+       variable.
+       (check_files): call check_binary_against_db higher up since it's
+       not a per-suite check.
+       (check_files): get "othercomponents" directly rather than having
+       check_binary_against_db do it for us.
+
+       * heidi (main): 'if x:', not 'if x != []:'.
+       * katie.py (Katie.in_override_p): likewise.
+       (Katie.check_dsc_against_db): likewise.
+       * natalie (main): likewise.
+       * rene (main): likewise.
+       * ziyi (real_arch): likewise.
+
+       * alyson (main): Suite::%s::Architectures, Suite::%s::Components
+       and OverrideType are now value lists, not lists.
+       * andrea (main): likewise.
+       * cindy (main): likewise.
+       * claire.py (find_dislocated_stable): likewise.
+       * denise (main): likewise.
+       * jenna (main): likewise.
+       * jennifer (check_distributions): likewise.
+       (check_files): likewise.
+       (check_urgency): likewise (Urgency::Valid).
+       * jeri (parse_packages): likewise.
+       * neve (main): likewise (and Location::%s::Suites).
+       * rene (main): likewise.
+
+2002-05-13  James Troup  <james@nocrew.org>
+
+       * katie.py (Katie.check_source_against_db): correct case of reject
+       message to be consistent with binary checks.
+
+       * jennifer (get_status_output): don't leak 2 file descriptors per
+       invocation.
+       (check_signature): add missing '\n' to "duplicate status token"
+       error message.
+
+2002-05-09  James Troup  <james@nocrew.org>
+
+       * utils.py (validate_changes_file_arg): new function; validates an
+       argument which should be a .changes file.
+       * ashley (main): use it.
+       * lisa (main): likewise.
+
+       * katie.py (Katie.check_dsc_against_db): since there can be more
+       than one .orig.tar.gz make sure we don't assume the .orig.tar.gz
+       entry still exists in files.
+
+       * jennifer (check_dsc): handle the .orig.tar.gz disappearing from
+       files, since check_dsc_against_db() deletes the .orig.tar.gz
+       entry.
+
+       * cameron: cleanups.
+
+       * utils.py (changes_compare): change sort order so that source
+       name and source version trump 'have source'; this should fix
+       UNACCEPT problems in katie where -1 hppa+source & i386, -2
+       i386&source & hppa lead to -1 i386 unaccept.  Problem worked out
+       by Ryan.
+
+       * lisa (main): allow the arguments to be .katie files too.
+
+2002-05-07  Ryan Murray  <rmurray@debian.org>
+
+       * cron.buildd: add s390 to arch list again
+
+2002-05-05  Ryan Murray  <rmurray@debian.org>
+
+       * cron.buildd: new script, update w-b database from unstable_accepted
+       table
+       * cameron: new script, take list in unstable_accepted and write out
+       a file list for apt-ftparchive
+       * apt.conf.buildd: new apt configuration for Packages/Sources for
+       unstable_accepted
+       * vars: add s390 to arch list.
+
+2002-05-03  James Troup  <james@nocrew.org>
+
+       * neve (main): don't hard code the calling user as that doesn't
+       work with modern postgres installs.  Fix psql invocation for
+       init_pool.sql (database name required).  Dont' hard code the
+       database name.
+       (process_sources): add support for fingerprint and install_date.
+       (process_packages): add support for fingerprint.
+       (do_sources): pass in the directory, fingerprint support needs it.
+       (get_status_output): borrowed from jennifer.
+       (reject): likewise.
+       (check_signature): likewise.
+
+       * katie (install): only try to log urgencies if Urgency_Logger is
+       defined.
+       (main): only initialize Urgency_Logger is Dir::UrgencyLog is
+       defined; only close Urgency_Logger if it's defined.
+
+       * catherine (poolize): adapt for Dir rationalization.
+       * claire.py (find_dislocated_stable): likewise.
+       * denise (main): likewise.
+       * halle (check_joey): likewise.
+       * jenna: likewise.
+       * jennifer: likewise.
+       * jeri: likewise.
+       * katie.py: likewise.
+       * katie: likewise.
+       * lisa (do_bxa_notification): likewise.
+       * logging.py (Logger.__init__): likewise
+       * rene (main): likewise.
+       * rhona (clean): likewise.
+       * shania (init): likewise.
+       * tea: likewise.
+       * ziyi: likewise.
+
+       * lisa (add_overrides): Dinstall::BXANotify is a boolean, use
+       FindB, not FindI.
+
+       * rhona (clean_accepted_autobuild): SpecialAcceptedAutoBuild is a
+       boolean, use FindB, not get.
+
+       * katie.py (Katie.check_dsc_against_db): ignore duplicate
+       .orig.tar.gz's which are an exact (size/md5sum) match.
+
+       * ashley (main): really allow *.katie files as arguments too;
+       noticed by aj.
+
+       * sql-aptvc.cpp: postgres.h moved to a "server" subdirectory.
+
+2002-05-03  Anthony Towns  <ajt@debian.org>
+
+       * ziyi: support for security.
+
+2002-05-02  James Troup  <james@nocrew.org>
+
+       * jennifer (accept): call Katie.check_override() unconditional as
+       no-mail check moved into that function.
+       (do_byhand): likewise.
+
+       * katie.py (Katie.check_override): don't do anything if we're a)
+       not sending mail or b) the override disparity checks have been
+       disbled via Dinstall::OverrideDisparityCheck.
+
+       * jennifer (check_files): don't hard code Unstable as the suite
+       used to check for architecture validity; use
+       Dinstall::DefaultSuite instead, if it exists.
+       (accept): conditionalize
+
+       * katie.py (Katie.update_subst): support global maintainer
+       override with Dinstall::OverrideMaintainer.
+
+       * jennifer (check_distributions): new function, Distribution
+       validation and mapping.  Uses new SuiteMappings variable from
+       config file to abstract suite mappings.
+       (check_changes): call it.
+
+       * natalie: renamed; nothing imports or likely will for some time.
+
+       * denise (main): remove unused natalie import and init().
+
+       * natalie.py (init): removed.
+       (main): initalize here instead and don't hardcode the database
+       name.
+
+2002-04-30  James Troup  <james@nocrew.org>
+
+       * katie.py (Katie.close_bugs): new function, split out from
+       announce().
+       (Katie.announce): only call close_bugs() if Dinstall::CloseBugs is
+       true.
+       (Katie.close_bugs): new function, split out
+       (Katie.close_bugs): return immediately if there are no bugs to
+       close.
+
+       * jennifer (acknowledge_new): adapt for new utils.TemplateSubst().
+       * katie (do_reject): likewise.
+       (stable_install): likewise.
+       * katie.py (Katie.announce): likewise.
+       (Katie.accept): likewise.
+       (Katie.check_override): likewise.
+       (Katie.do_reject): likewise.
+       * lisa (do_bxa_notification): likewise.
+       * melanie (main): likewise.
+
+       * utils.py (TemplateSubst): change second argument to be a
+       filename rather than a template since every caller opened a file
+       on the fly which was ugly and leaked file descriptor.
+
+2002-04-29  James Troup  <james@nocrew.org>
+
+       * katie.py (Katie.announce): (modified) patch from Raphael Hertzog
+       <hertzog@debian.org> to send 'accepted' announce mails to the
+       PTS. [#128140]
+
+2002-04-24  James Troup  <james@nocrew.org>
+
+       * init_pool.sql (unstable_accepted): add two new fields to
+       unstable_accepted; in_accepted is a boolean indicating whether or
+       not the file is in accepted and last_used is a timestamp used by
+       rhona to determine when to remove symlinks for installed packages.
+
+       * katie.py (Katie.accept): auto-build support take 2.  Create
+       symlinks for all files into a seperate directory.  Add files to
+       unstable_accepted as paths to the new directory; mark them as
+       being in accepted for cameron.  Properly conditionalize it on a
+       configuration variable.
+
+       * katie (install): likewise.  Update symlinks to point into the
+       pool; mark the files for later deletion by rhona and mark them as
+       not being in accepted for cameron.
+
+       * rhona (clean_accepted_autobuild): new function.
+
+2002-04-22  James Troup  <james@nocrew.org>
+
+       * jennifer (check_files): handle db_access.get_location_id()
+       returning -1 properly/better.
+
+       * rhona (clean_fingerprints): new function.
+
+2002-04-21  James Troup  <james@nocrew.org>
+
+       * utils.py (touch_file): unused; remove.
+       (plural): likewise.
+
+       * jennifer (check_files): close file descriptor used to get the
+       control file.
+       (check_md5sums): likewise.
+       (callback): likewise.
+
+       * katie.py (Katie.do_reject): handle manual rejects much better;
+       call the editor first and get confirmation from the user before
+       proceeding.
+
+       * jennifer (check_signature): prefix_multi_line_string() moved to
+       utils.
+
+       * utils.py (prefix_multi_line_string): moved here from jennifer.
+
+2002-04-20  James Troup  <james@nocrew.org>
+
+       * lisa (main): handle non-existent files.
+
+       * ashley (main): allow *.katie files as arguments too.
+
+2002-04-19  James Troup  <james@nocrew.org>
+
+       * katie.py (Katie.accept): add stuff to help auto-building from
+       accepted; if the .orig.tar.gz is not part of the upload (i.e. it's
+       in the pool), create a symlink to it in the accepted directory and
+       add the .dsc and .{u,}deb(s) to a new 'unstable_accepted' table.
+
+       * katie (install): undo the "auto-building from accepted" stuff
+       (i.e. remove the .orig.tar.gz symlink and remove the files from
+       unstable_accepted table).
+
+2002-04-16  James Troup  <james@nocrew.org>
+
+       * jennifer (upload_too_new): fix typo which was causing all
+       timestamp comparisons to be against the .changes file.  Also move
+       back to the original directory so we do the comparisons against
+       accurate timestamps.
+
+       * tea (check_missing_tar_gz_in_dsc): new function.
+
+       * jennifer (check_dsc): add a check to ensure there is a .tar.gz
+       file mentioned in the .dsc.
+
+       * lisa (main): use X-Katie in the mail headers, not X-Lisa; that
+       way mails reach debian-{devel-,}changes@l.d.o.
+
+2002-04-02  Ryan Murray  <rmurray@debian.org>
+
+       * cron.daily: run shania after rhona
+       * cron.daily-non-US: likewise.
+
+2002-04-01  James Troup  <james@nocrew.org>
+
+       * katie: re-add proposed-updates/stable install support.
+
+       * katie.py (Katie.dump_vars): add changes["changes"] as an
+       optional field; should be mandatory later.
+
+2002-03-31  James Troup  <james@nocrew.org>
+
+       * katie (install): support a Suite::<foo>::CopyKatie similar to
+       CopyChanges.  Done seperately because .katie files don't need to
+       be mirrored and will probably be copied to another directory as a
+       result.
+
+       * halle (main): add missing debug to options.
+
+2002-03-29  James Troup  <james@nocrew.org>
+
+       * madison (main): add a -r/--regex option.
+
+2002-03-26  James Troup  <james@nocrew.org>
+
+       * lisa: don't trample on changes["distribution"]; make a copy of
+       it as changes["suite"] instead and use that.
+
+2002-03-16  Anthony Towns  <ajt@debian.org>
+
+       * templates/lisa.bxa_notification: Fix some grammatical errors.
+       Encourage contact via bxa@ftp-master email address.
+
+2002-03-15  James Troup  <james@nocrew.org>
+
+       * jennifer (check_timestamps): remove bogus raise in except.
+
+2002-03-15  Anthony Towns  <ajt@debian.org>
+
+       * cron.monthly: rotate mail/archive/bxamail as well as
+       mail/archive/mail. This is for a complete archive of
+       correspondence with the BXA.
+
+2002-03-14  Anthony Towns  <ajt@debian.org>
+
+       * crypto-in-main changes.
+
+       * utils.py (move, copy): add an optional perms= parameter to let you
+       set the resulting permissions of the moved/copied file
+       * katie.py (force_move): rejected/morgued files should be unreadable
+       * jennifer (do_byhand, acknowledge_new): pending new and byhand files
+       should be unreadable.
+
+2002-03-07  Ryan Murray  <rmurray@debian.org>
+
+       * katie (install): check for existance of "files id" key as well as
+       it being set to a valid value.
+       * katie (install): check for existense and valid value for location
+       id as well
+
+2002-03-05  Ryan Murray  <rmurray@debian.org>
+
+       * katie.py (do_reject): reread the reason file after editing it.
+
+2002-02-25  James Troup  <james@nocrew.org>
+
+       * jennifer (check_changes): don't enforce sanity in .changes file
+       names since it doesn't seem to be possible; pcmica-cs and similar
+       freak show packages in particular cause real problems.
+
+       * katie.py (Katie.check_dsc_against_db): initialize 'found' for
+       each dsc_file since the .orig.tar.gz checking code now uses it as
+       a boolean.  Fixes bizarro rejections which bogusly claimed
+       .diff.gz md5sum/size was incorrect.
+
+2002-02-24  James Troup  <james@nocrew.org>
+
+       * katie (process_it): reset reject_message.
+
+2002-02-22  James Troup  <james@nocrew.org>
+
+       * db_access.py(set_files_id): disable use of
+       currval('files_id_seq') because it was taking 3 seconds on auric
+       which is insane (most calls take < 0.01) and simply call
+       get_files_id() for the return value instead.
+
+       * katie.py (Katie.do_query): convenience function; unused by
+       default, useful for profiling.
+       * db_access.py (do_query): likewise.
+
+       * katie (install): fix insert SQL call when binary has no source.
+
+       * lisa (determine_new): auto-correct non-US/main to non-US.
+       (determine_new): add a warning when adding things to stable.
+       (edit_index): use our_raw_input().
+       (edit_overrides): likewise.
+       (do_new): likewise.  Use re.search() not re.match() since the
+       default answer may not be the first one.
+       (do_byhand): likewise.
+       (do_new): Default to 'S'kip and never 'A'dd.
+
+       * jennifer (action): pass prompt to our_raw_input().
+       * melanie (game_over): likewise.
+       * katie (action): likewise.
+
+       * utils.py (our_raw_input): add an optional prompt argument to
+       make the function more usable as a drop in replacement for
+       raw_input().
+
+       * jennifer (check_files): correct reject() to not double prefix
+       when using katie.py based functions.
+       (check_dsc): likewise.
+
+       * katie.py (Katie.reject): prepend a new line if appropriate
+       rathen than appending one to avoid double new lines when caller
+       adds one of his own.
+
+       * lisa (determine_new): warn if the package is also in other
+       components.
+
+2002-02-20  James Troup  <james@nocrew.org>
+
+       * jennifer (check_files): if .changes file lists "source" in
+       Architecture field, there must be a .dsc.
+
+2002-02-15  James Troup  <james@nocrew.org>
+
+       * ashley (main): add some missing fields.
+
+       * katie.py (Katie.check_dsc_against_db): fix to take into account
+       the fact that the .orig.tar.gz might be in byhand, accepted or
+       new.  Also fix calling of reject().
+       (Katie.check_binaries_against_db): fix calling of reject().
+       (Katie.check_source_against_db): likewise.
+       (Katie.dump_vars): add missing variables used for bug closures.
+
+       * lisa (changes_compare_by_time): sort by reverse time.
+
+       * katie.py (Katie.accept): log.
+       (Katie.dump_vars): missing has_key test for optional changes fields.
+
+       * jennifer (main): print "Accepted blah blah" to stdout, not stderr.
+       (process_it): traceback goes to stderr, not stdout.
+       (acknowledge_new): log.
+       (do_byhand): likewise.
+
+       * katie.py (Katie.update_subst): fix typo (Cnf vs. self.Cnf).
+
+       * add_constraints.sql: add grants for the new fingerprint table.
+
+2002-02-13  James Troup  <james@nocrew.org>
+
+       * katie (do_reject): basename the .changes filename before trying
+       to use it to construct the .reason filename.
+       (process_it): call Katie.update_subst() so do_reject() DTRT with
+       the mail template.
+       (do_reject): setup the mail template correctly.
+
+2002-02-12  James Troup  <james@nocrew.org>
+
+       * tea (process_dir): renamed 'arg' to 'unused' for clarity.
+       (check_files): don't abuse global dictionaries.
+       (Ent): use all variables.
+       (check_timestamps): don't abuse global dictionaries.
+
+       * fernanda.py: renamed to .py so lisa can import it.
+       (check_dsc): remove unused local variables (pychecker).
+       (display_changes): split off from check_changes.
+
+       * katie: rewritten; most of the functionality moves to jennifer;
+       what's left is the code to install packages once a day from the
+       'accepted' directory.
+
+       * jennifer: new program, processes packages in 'unchecked'
+       (i.e. most of the non-install functionality of old katie).
+
+       * katie.py: common functions shared between the clique of
+       jennifer, lisa and katie.
+
+       * lisa: new program; handles NEW and BYHAND packages.
+
+       * jeri (usage): new function.
+       (main): use it.
+       (check_package): remove unused local variable (pychecker).
+
+       * init_pool.sql: new table fingerprint.  Add fingerprint colums to
+       binaries and source.  Add install_date to source.
+
+       * halle (usage): new function.
+       (main): use it.  Remove unused options.
+       (check_changes): remove unused local variable (pychecker).
+
+       * add_constraints.sql: add fingerprint references.
+
+       * db_access.py (get_or_set_fingerprint_id): new function.
+
+       * ashley (main): new program; dumps the contents of a .katie file
+       to stdout.
+
+       * alyson (main): remove option handling since we don't actually
+       support any.
+       * cindy (main): likewise.
+
+       * remove unnecessary imports and pre-define globals (pychecker).
+
+2002-02-11  Anthony Towns  <ajt@debian.org>
+
+       * added installation-report and upgrade-report pseudo-packages
+
+2002-01-28  Martin Michlmayr  <tbm@cyrius.com>
+
+       * katie (update_subst): use Dinstall::TrackingServer.
+       * melanie (main): likewise.
+
+2002-01-27  James Troup  <james@nocrew.org>
+
+       * shania (main): it's IntLevel not IntVal; thanks to tbm@ for
+       noticing, jgg@ for fix.
+
+2002-01-19  James Troup  <james@nocrew.org>
+
+       * utils.py (extract_component_from_section): handle non-US
+       non-main properly.
+
+2002-01-12  James Troup  <james@nocrew.org>
+
+       * madison: add support for -S/--source-and-binary which displays
+       information for the source package and all it's binary children.
+
+2002-01-13  Anthony Towns  <ajt@debian.org>
+
+       * katie.conf: Remove Catherine Limit and bump stable to 2.2r5
+       * katie.conf: Add Dinstall::SigningKeyIds option, set to the 2001
+         and 2002 key ids.
+       * katie.conf-non-US: Likewise.
+       * ziyi: Suppoer Dinstall::SigningKeyIds to sign a Release file with
+         multiple keys automatically. This is probably only useful for
+         transitioning from an expired (or revoked?) key.
+
+2002-01-08  Ryan Murray  <rmurray@debian.org>
+
+       * debian/python-dep: new file that prints out python:Depends for
+         substvars
+       * debian/control: use python:Depends, build-depend on python
+         lower Depends: on postgresql to Suggests:
+       * debian/rules: determine python version, install to the correct
+         versioned dir
+
+2001-12-18  Anthony Towns  <ajt@debian.org>
+
+       * ziyi: unlink Release files before overwriting them (in case they've
+         been merged)
+       * ziyi: always include checksums/sizes for the uncompressed versions
+         of Sources and Packages, even if they're not present on disk
+
+2001-11-26  Ryan Murray  <rmurray@debian.org>
+
+       * ziyi (main): add SigningPubKey config option
+       * katie.conf: use SigningPubKey config option
+       * katie.conf-non-US: likewise
+
+2001-11-24  James Troup  <james@nocrew.org>
+
+       * katie (acknowledge_new): log newness.
+
+2001-11-24  Anthony Towns  <ajt@debian.org>
+
+       * ziyi (real_arch): bail out if some moron forgot to reset
+       untouchable on stable.
+       (real_arch): source Release files.
+
+2001-11-19  James Troup  <james@nocrew.org>
+
+       * claire.py (main): don't use apt_pkg.ReadConfigFileISC and
+       utils.get_conf().
+       * shania (main): likewise.
+
+       * rhona (main): add default options.
+
+       * db_access.py (get_archive_id): case independent.
+
+       * katie (action): sort files so that ordering is consistent
+       between mails; noticed/requested by Joey.
+
+2001-11-17  Ryan Murray  <rmurray@debian.org>
+
+       * utils.py: add get_conf function, change startup code to read all
+         config files to the Cnf that get_conf returns
+         use the component list from the katie conf rather than the hardcoded
+         list.
+       * all scripts: use new get_conf function
+       * shania: fix try/except around changes files
+       * jenna: only do debian-installer if it is a section in Cnf
+
+2001-11-16  Ryan Murray  <rmurray@debian.org>
+
+       * shania (main): Initialize days to a string of a number.
+                (main): Initialize Cnf vars before reading in Cnf
+
+2001-11-14  Ryan Murray  <rmurray@debian.org>
+
+       * shania (main): Initialize days to a number.
+
+2001-11-04  James Troup  <james@nocrew.org>
+
+       * docs/Makefile: use docbook-utils' docbook2man binary.
+
+       * Change all "if foo == []" constructs into "if not foo".
+
+       * katie (check_changes): when installing into stable from
+       proposed-updates, remove all non-stable target distributions.
+       (check_override): don't check for override disparities on stable
+       installs.
+       (stable_install): update install_bytes appropriately.
+       (reject): stable rejection support; i.e. don't remove files when
+       rejecting files in the pool, rather remove them from the
+       proposed-update suite instead, rhona will do the rest.
+       (manual_reject): support for a stable specific template.
+       (main): setup up stable rejector in subst.
+
+2001-11-04  Martin Michlmayr  <tbm@cyrius.com>
+
+       * debian/control (Build-Depends): docbook2man has been superseded
+       by docbook-utils.
+
+       * neve (main): exit with a more useful error message.
+       (update_suites): Suite::<suite>::Version, Origin and Description
+       are not required, so don't fail if they don't exist.
+
+       * db_access.py (get_archive_id): return -1 on error rather than
+       raise an exception.
+       (get_location_id): likewise.
+
+       * madison (main): don't exit on the first not-found package,
+       rather exit with an appropriate return code after processing all
+       packages.
+
+2001-11-03  James Troup  <james@nocrew.org>
+
+       * claire.py (find_dislocated_stable): add per-architecture
+       symlinks for dislocated architecture: all debs.
+
+2001-10-19  Anthony Towns  <ajt@debian.org>
+
+       * apt.conf*, katie.conf*: add mips, mipsel, s390 to testing.
+
+2001-10-10  Anthony Towns  <ajt@debian.org>
+
+       * claire.py (fix_component_section): do _not_ assign to None under
+       any circumstances
+
+2001-10-07  Martin Michlmayr  <tbm@cyrius.com>
+
+       * melanie (main): don't duplicate architectures when removing from
+       more than one suite.
+
+       * heidi (main, process_file, get_list): report suite name not ID.
+
+       * naima (nmu_p): be case insensitive.
+
+       * naima (action): more list handling clean ups.
+
+       * melanie (main): clean up lists handling to use string.join and
+       IN's.
+
+       * madison (main): clean up suite and architecture argument parsing
+       to use slices less and string.join more.
+
+       * utils.py (parse_changes): Use string.find() instead of slices for
+       string comparisons thereby avoid hardcoding the length of strings.
+       * ziyi (main): likewise.
+
+2001-10-07  James Troup  <james@nocrew.org>
+
+       * Remove mode argument from utils.open_files() calls if it's the
+       default, i.e. 'r'.
+
+2001-09-27  James Troup  <james@nocrew.org>
+
+       * katie (init): new function; options clean up.
+       (usage): add missing options, remove obsolete ones.
+       (main): adapt for the two changes above.  If the lock file or
+       new-ack log file don't exist, create them.  Don't try to open the
+       new-ack log file except running in new-ack mode.
+
+       * alyson (main): initialize all the tables that are based on the
+       conf file.
+
+       * utils.py (touch_file): like touch(1).
+       (where_am_i): typo.
+
+       * catherine (usage): new.
+       (main): use it.  options cleanup.
+       * claire.py: likewise.
+       * fernanda: likewise.
+       * heidi: likewise.
+       * jenna: likewise.
+       * shania: likewise.
+       * ziyi: likewise.
+
+       * andrea: options cleanup.
+       * charisma: likewise.
+       * julia: likewise.
+       * madison: likewise.
+       * melanie: likewise.
+       * natalie: likewise.
+       * rhona: likewise.
+       * tea: likewise.
+
+2001-09-26  James Troup  <james@nocrew.org>
+
+       * utils.py: default to sane config file locations
+       (/etc/katie/{apt,katie}.conf.  They can be the actual config files
+       or they can point to the real ones through use of a new Config
+       section.  Based on an old patch by Adam Heath.
+       (where_am_i): use the new default config stuff.
+       (which_conf_file): likewise.
+       (which_apt_conf_file): likewise.
+
+       * charisma (main): output defaults to
+       `Package~Version\tMaintainer'; input can be of either form.  When
+       parsing the new format do version comparisons, when parsing the
+       old format assume anything in the extra file wins.  This fixes the
+       problem of newer non-US packages being overwhelmed by older
+       versions still in stable on main.
+
+2001-09-17  James Troup  <james@nocrew.org>
+
+       * natalie.py (list): use result_join().
+
+       * denise (main): result_join() moved to utils.
+
+       * utils.py (result_join): move to utils; add an optional seperator
+       argument.
+
+2001-09-14  James Troup  <james@nocrew.org>
+
+       * heidi (set_suite): new function; does --set like natalie does,
+       i.e. turns it into a sequence of --add's and --remove's
+       internally.  This is a major win (~20 minute run time > ~20
+       seconds) in the common, everday (i.e. testing) case.
+       (get_id): common code used by set_suite() and process_file().
+       (process_file): call set_suite() and get_id().
+       (main): add logging support.
+
+       * julia: new script; syncs PostgeSQL with (LDAP-generated) passwd
+       files.
+
+       * utils.py (parse_changes): use slices or simple string comparison
+       in favour of regexes where possible.
+
+       * sql-aptvc.cpp (versioncmp): rewritten to take into account the
+       fact that the string VARDATA() points to are not null terminated.
+
+       * denise (result_join): new function; like string.join() but
+       handles None's.
+       (list): use it.
+       (main): likewise.
+
+       * charisma (main): python-pygresql 7.1 returns None not "".
+
+2001-09-14  Ryan Murray  <rmurray@debian.org>
+
+       * natalie.py (list): handle python-pygresql 7.1 returning None.
+
+2001-09-10  Martin Michlmayr  <tbm@cyrius.com>
+
+       * madison (main): return 1 if no package is found.
+
+2001-09-08  Martin Michlmayr  <tbm@cyrius.com>
+
+       * madison (main): better error handling for incorrect
+       -a/--architecture or -s/--suite arguments.
+       (usage): new.
+       (main): use it.
+
+2001-09-05  Ryan Murray  <rmurray@debian.org>
+
+       * charisma, madison, katie: remove use of ROUser
+       * katie.conf,katie.conf-non-US: remove defintion of ROUser
+
+2001-08-26  James Troup  <james@nocrew.org>
+
+       * katie (nmu_p.is_an_nmu): use maintaineremail to check for group
+       maintained packages at cjwatson@'s request.
+
+2001-08-21  James Troup  <james@nocrew.org>
+
+       * madison (main): add -a/--architecture support.
+
+       * jenna: use logging instead of being overly verbose on stdout.
+
+2001-08-11  Ryan Murray  <rmurray@debian.org>
+
+       * melanie: add functional help option
+
+2001-08-07  Anthony Towns  <ajt@debian.org>
+
+       * apt.conf, katie.conf: Add ia64 and hppa to testing.
+
+2001-07-28  James Troup  <james@nocrew.org>
+
+       * katie (check_dsc): ensure source version is >> than existing
+       source in target suite.
+
+2001-07-25  James Troup  <james@nocrew.org>
+
+       * natalie.py: add logging support.
+
+       * utils.py (open_file): make the second argument optional and
+       default to read-only.
+
+       * rene (main): work around broken source packages that duplicate
+       arch: all packages with arch: !all packages (no longer allowed
+       into the archive by katie).
+
+2001-07-13  James Troup  <james@nocrew.org>
+
+       * katie (action): don't assume distribution is a dictionary.
+       (update_subst): don't assume architecture is a dictionary and that
+       maintainer822 is defined.
+       (check_changes): recognise nk_format exceptions.
+       (check_changes): reject on 'testing' only uploads.
+       (check_files): when checking to ensure all packages are newer
+       versions check against arch-all packages too.
+       (check_dsc): enforce the existent of a sane set of mandatory
+       fields.  Ensure the version number in the .dsc (modulo epoch)
+       matches the version number in the .changes file.
+
+       * utils.py (changes_compare): ignore all exceptions when parsing
+       the changes files.
+       (build_file_list): don't UNDEF on a changes file with no format
+       field.
+
+2001-07-07  James Troup  <james@nocrew.org>
+
+       * katie (nmu_p.is_an_nmu): check 'changedby822' for emptiness
+       rather than 'changedbyname' to avoid false negatives on uploads
+       with an email-address-only Changed-By field.
+       (check_dsc): don't overwrite reject_message; append to it.
+       (check_signature): likewise.
+       (check_changes): likewise.
+       (announce): condition logging on 'action'.
+
+       * logging.py: new logging module.
+
+       * katie: Cleaned up code by putting Cnf["Dinstall::Options"]
+       sub-tree into a separate (global) variable.
+       (check_dsc): ensure format is 1.0 to retain backwards
+       compatability with dpkg-source in potato.
+       (main): only try to obtain the lock when not running in no-action
+       mode.
+       Use the new logging module.
+
+       * christina: initial version; only partially usable.
+
+2001-06-28  Anthony Towns  <ajt@debian.org>
+
+       * apt.conf: Add ExtraOverrides to auric.
+
+2001-06-25  James Troup  <james@nocrew.org>
+
+       * katie (nmu_p.is_an_nmu): the wonderful dpkg developers decided
+       they preferred the name 'Uploaders'.
+
+2001-06-23  James Troup  <james@nocrew.org>
+
+       * katie (check_files): fix typo in uncommon rejection message,
+       s/sourceversion/source version/.
+
+       * denise (main): we can't use print because stdout has been
+       redirected.
+
+       * katie (source_exists): new function; moved out of check_files()
+       and added support for binary-only NMUs of earlier sourceful NMUs.
+
+       * rhona (clean): find_next_free has moved.
+
+       * utils.py (find_next_free): new function; moved here from rhona.
+       Change too_many to be an argument with a default value, rather
+       than a hardcoded variable.
+
+       * shania: rewritten to work better; REJECTion reminder mail
+       handling got lost though.
+
+2001-06-22  James Troup  <james@nocrew.org>
+
+       * rhona (main): remove unused override code.
+
+       * fernanda (main): remove extraneous \n's from utils.warn calls.
+       * natalie.py (list): likewise.
+
+       * catherine, cindy, denise, heidi, jenna, katie, neve, rhona, tea:
+       use utils.{warn,fubar} where appropriate.
+
+2001-06-21  James Troup  <james@nocrew.org>
+
+       * katie (nmu_p): new class that encapsulates the "is a nmu?"
+       functionality.
+       (nmu_p.is_an_nmu): add support for multiple maintainers specified
+       by the "Maintainers" field in the .dsc file and maintainer groups.
+       (nmu_p.__init__): read in the list of group maintainer names.
+       (announce): use nmu_p.
+
+2001-06-20  James Troup  <james@nocrew.org>
+
+       * rene (main): hardcode the suite experimental is compared to by
+       name rather than number.
+
+       * katie (check_files): differentiate between doesn't-exist and
+       permission-denied in "can not read" rejections; requested by edd@.
+       (check_dsc): use os.path.exists rather than os.access to allow the
+       above check to kick in.
+
+       * heidi (process_file): read all input before doing anything and
+       use transactions.
+
+2001-06-15  James Troup  <james@nocrew.org>
+
+       * fernanda: new script; replaces old 'check' shell script
+       nastiness.
+
+2001-06-14  James Troup  <james@nocrew.org>
+
+       * katie: actually import traceback module to avoid amusing
+       infinite loop.
+
+2001-06-10  James Troup  <james@nocrew.org>
+
+       * utils.py (extract_component_from_section): fix to handle just
+       'non-free' and 'contrib'.  Also fix to handle non-US in a
+       completely case insensitive manner as a component.
+
+2001-06-08  James Troup  <james@nocrew.org>
+
+       * madison (arch_compare): sort function that sorts 'source' first
+       then alphabetically.
+       (main): use it.
+
+2001-06-05  Jeff Licquia  <jlicquia@progeny.com>
+
+       * catherine (poolize): explicitly make poolized_size a long so it
+       doesn't overflow when poolizing e.g. entire archives.
+
+2001-06-01  James Troup  <james@nocrew.org>
+
+       * utils.py (send_mail): throw exceptions rather than exiting.
+
+       * katie (process_it): catch exceptions and ignore them.
+
+2001-06-01  Michael Beattie  <mjb@debian.org>
+
+       * added update-mailingliststxt and update-readmenonus to update
+       those files, respectively. modified cron.daily{,-non-US} to
+       use them.
+
+2001-05-31  Anthony Towns  <ajt@debian.org>
+
+       * rhona: make StayOfExecution work.
+
+2001-05-31  James Troup  <james@nocrew.org>
+
+       * rhona (find_next_free): fixes to not overwrite files but rename
+       them by appending .<n> instead.
+       (clean): use find_next_free and use dated sub-directories in the
+       morgue.
+
+       * utils.py (move): don't overwrite files unless forced to.
+       (copy): likewise.
+
+2001-05-24  James Troup  <james@nocrew.org>
+
+       * katie (check_files): determine the source version here instead
+       of during install().
+       (check_files): check for existent source with bin-only NMU
+       support.
+       (main): sort the list of changes so that the source-must-exist
+       check Does The Right Thing(tm).
+
+       * utils.py (changes_compare): new function; sorts a list of
+       changes files by 'have-source', source, version.
+       (cc_fix_changes): helper function.
+       (parse_changes): use compiled regexes.
+       (fix_maintainer): likewise.
+
+       * rene (main): warn about packages in experimental that are
+       superseded by newer versions in unstable.
+
+2001-05-21  James Troup  <james@nocrew.org>
+
+       * rene (main): add support for checking for ANAIS (Architecture
+       Not Allowed In Source) packages.
+
+2001-05-17  James Troup  <james@nocrew.org>
+
+       * katie (check_changes): initalize `architecture' dictionary in
+       changes global so that if we can't parse the changes file for
+       whatever reason we don't undef later on.
+
+       * utils.py (parse_changes): fix handling of multi-line fields
+       where the first line did have data.
+
+2001-05-05  Anthony Towns  <ajt@debian.org>
+
+       * ziyi: Add "NotAutomatic: yes" to experimental Release files.
+       (It should always have been there. Ooopsy.)
+
+2001-05-03  Anthony Towns  <ajt@debian.org>
+
+       * jenna: Cleanup packages that move from arch:any to arch:all or
+       vice-versa.
+
+2001-04-24  Anthony Towns  <ajt@debian.org>
+
+       * ziyi: add ``SHA1:'' info to Release files. Also hack them up to
+       cope with debian-installer and boot-floppies' md5sum.txt.
+
+2001-04-16  James Troup  <james@nocrew.org>
+
+       * katie (check_changes): add missing %s format string argument.
+       (stable_install): temporary work around for morgue location to
+       move installed changes files into.
+       (stable_install): helps if you actually read in the template.
+       (manual_reject): fix for editing of reject messages which was
+       using the wrong variable name.
+
+       * jenna (generate_src_list): typo; s/package/source/; fixes undef crash.
+
+2001-04-13  James Troup  <james@nocrew.org>
+
+       * katie (manual_reject): Cc the installer.
+       (reject): don't.
+       (check_changes): remove unused maintainer-determination code.
+       (update_subst): add support for Changed-By when setting the
+       *MAINTAINER* variables.
+
+       * rene (bar): new function to check for packages on architectures
+       when they shouldn't be.
+
+       * natalie.py (main): use fubar() and warn() from utils.
+
+       * utils.py (whoami): new mini-function().
+       * melanie (main): use it.
+       * katie (manual_reject): likewise.
+
+2001-04-03  James Troup  <james@nocrew.org>
+
+       * katie (action): ignore exceptions from os.path.getmtime() so we
+       don't crash on non-existent changes files (e.g. when they are
+       moved between the start of the install run in cron.daily and the
+       time we get round to processing them).
+
+       * madison (main): also list source and accept -s/--suite.
+
+       * jenna (generate_src_list): missing \n in error message.
+
+       * katie (update_subst): add sane defaults for when changes is
+       skeletal.
+
+2001-03-29  James Troup  <james@nocrew.org>
+
+       * melanie (main): use fubar() and warn() from utils.  Remember who
+       the maintainer for the removed packages are and display that info
+       to the user.  Readd support for melanie-specific Bcc-ing that got
+       lost in the TemplateSubst transition.
+
+       * utils.py (fubar): new function.
+       (warn): like wise.
+
+       * db_access.py (get_maintainer): as below.
+
+       * charisma (get_maintainer): moved the bulk of this function to
+       db_access so that melanie can use it too.
+
+       * claire.py (find_dislocated_stable): restrict the override join
+       to those entries where the suite is stable; this avoids problems
+       with packages which have moved to new sections (e.g. science)
+       between stable and unstable.
+
+2001-03-24  James Troup  <james@nocrew.org>
+
+       * catherine (poolize): new function; not really independent of
+       main() fully, yet.
+       (main): use it.
+
+       * katie (stable_install): __SUITE__ needs to be space prefixed
+       because buildd's check for 'INSTALLED$'.
+
+2001-03-22  James Troup  <james@nocrew.org>
+
+       * utils.py (regex_safe): also need to escape '.'; noticed by ajt@.
+
+       * jenna: rewritten; now does deletions on a per-suite level
+       instead of a per-suite-component-architecture-type level.  This
+       allows mutli-component packages to be auto-cleaned (and as a
+       bonus, reduces the code size and duplication).
+
+2001-03-22  Anthony Towns  <ajt@debian.org>
+
+       * ziyi (main): fix ziyi to overwrite existing Release.gpg files
+       instead of just giving a gpg error.
+
+2001-03-21  James Troup  <james@nocrew.org>
+
+       * madison (main): use apt_pkg.VersionCompare to sort versions so
+       that output is correctly sorted for packages like debhlper.
+       Noticed by ajt@.
+
+       * tea (check_source_in_one_dir): actually find problematic source
+       packages.
+
+       * katie (check_dsc): remember the orig.tar.gz's location ID if
+       it's not in a legacy suite.
+       (check_diff): we don't use orig_tar_id.
+       (install): add code to handle sourceful diff-only upload of
+       packages which change components by copying the .orig.tar.gz into
+       the new component, if it doesn't already exist there.
+       (process_it): reset orig_tar_location (as above).
+
+       * melanie (main): use template substiution for the bug closing
+       emails.
+       (main): don't hardcode bugs.debian.org or packages.debian.org
+       either; use configuration items.
+
+       * katie: likewise.
+
+       * natalie.py (init): use None rather than 'localhost' for the
+       hostname given to pg.connect.
+
+       * utils.py (TemplateSubst): new function; lifted from
+       userdir-ldap.
+
+2001-03-21  Ryan Murray  <rmurray@debian.org>
+
+       * katie (announce): fix the case of non-existent
+       Suite::$SUITE::Announce.
+
+2001-03-20  Ryan Murray  <rmurray@debian.org>
+
+       * debian/rules (binary-indep): install melanie into /usr/bin/ not
+       /usr/.
+
+       * alyson (main): use config variable for database name.
+       * andrea (main): likewise.
+       * catherine (main): likewise.
+       * charisma (main): likewise.
+       * cindy (main): likewise.
+       * claire.py (main): likewise.
+       * denise (main): likewise.
+       * heidi (main): likewise.
+       * jenna (main): likewise.
+       * katie (main): likewise.
+       * madison (main): likewise.
+       * melanie (main): likewise.
+       * neve (main): likewise.
+       * rhona (main): likewise.
+       * tea (main): likewise.
+
+2001-03-15  James Troup  <james@nocrew.org>
+
+       * rhona (check_sources): fixed evil off by one (letter) error
+       which was causing only .dsc files to be deleted when cleaning
+       source packages.
+
+       * charisma (get_maintainer_from_source): remove really stupid and
+       gratuitous IN sub-query and replace with normal inner join.
+       (main): connect as read-only user nobody.
+
+       * rhona (clean_maintainers): rewritten to use SELECT and sub-query
+       with EXISTS.
+       (check_files): likewise; still disabled by default though.
+       (clean_binaries): add ' seconds' to the mysterious number in the
+       output.
+       (clean): likewise.
+
+       * tea (check_files): add missing global declaration on db_files.
+
+2001-03-14  James Troup  <james@nocrew.org>
+
+       * rhona: rewritten large chunks. Removed a lot of the silly
+       selecting into dictionaries and replaced it with 'where exists'
+       based sub queries.  Added support for StayOfExecution.  Fix the
+       problem with deleting dsc_files too early and disable cleaning of
+       unattached files.
+
+2001-03-14  Anthony Towns  <ajt@debian.org>
+
+       * katie (announce): also check Changed-By when trying to detect
+       NMUs.
+
+2001-03-06  Anthony Towns  <ajt@debian.org>
+
+       * ziyi (main): Generate Release.gpg files as well, using the key from
+       Dinstall::SigningKey in katie.conf, if present. That key has to be
+       passwordless, and hence kept fairly secretly.
+
+2001-03-02  James Troup  <james@nocrew.org>
+
+       * utils.py (str_isnum): new function; checks to see if the string
+       is a number.
+
+       * shania (main): fix _hideous_ bug which was causing all files > 2
+       weeks old to be deleted from incoming, even if they were part of a
+       valid upload.
+
+2001-02-27  James Troup  <james@nocrew.org>
+
+       * melanie (main): accept new argument -C/--carbon-copy which
+       allows arbitarty carbon-copying of the bug closure messages.
+       Cleaned up code by putting Cnf["Melanie::Options"] sub-tree into a
+       separate variable.
+
+2001-02-27  Anthony Towns  <ajt@debian.org>
+
+       * ziyi: new program; generates Release files.
+
+2001-02-25  James Troup  <james@nocrew.org>
+
+       * katie (reject): add missing '\n' to error message.
+       (manual_reject): likewise.
+       (install): catch exceptions from moving the changes file into DONE
+       and ignore them.
+
+       * tea (check_md5sums): new function.
+
+2001-02-25  Michael Beattie  <mjb@debian.org>
+
+       * melanie: use $EDITOR if available.
+
+2001-02-15  James Troup  <james@nocrew.org>
+
+       * utils.py (parse_changes): don't crash and burn on empty .changes
+       files.  Symptoms noticed by mjb@.
+
+2001-02-15  Adam Heath  <doogie@debian.org>
+
+       * denise (main): use an absolute path for the output filename.
+
+       * sql-aptvc.cpp: don't #include <utils/builtins.h> as it causes
+       compile errors with postgresql-dev >= 7.0.
+
+2001-02-12  James Troup  <james@nocrew.org>
+
+       * rene: initial version.
+
+       * andrea: initial version.
+
+       * catherine (main): remove obsolete assignment of arguments.
+
+2001-02-09  James Troup  <james@nocrew.org>
+
+       * catherine: first working version.
+
+2001-02-06  James Troup  <james@nocrew.org>
+
+       * katie (check_files): validate the priority field; i.e. ensure it
+       doesn't contain a '/' (to catch people prepending the priority
+       with the component rather than the section).
+       (check_override): don't warn about source packages; the only check
+       is on section and we have no GUI tools that would use the Section
+       field for a Sources file.
+       (announce): use tags rather than severities for NMUs.  Requested
+       by Josip Rodin <joy@>. [#78035]
+
+2001-02-04  James Troup  <james@nocrew.org>
+
+       * tea (check_override): new function; ensures packages in suites
+       are also in the override file.  Thanks to bod@ for noticing that
+       such packages existed.
+
+       * katie: move file type compiled regular expressions to utils as
+       catherine uses them too.
+       (check_changes): always default maintainer822 to the installer
+       address so that any bail out won't cause undefs later.
+       (check_files): update file type re's to match above.
+       (stable_install): likewise.
+       (reject): handle any except from moving the changes files.  Fixes
+       crashes on unreadable changes files.
+
+       * melanie (main): add an explanation of why things are not removed
+       from testing.
+
+2001-01-31  James Troup  <james@nocrew.org>
+
+       * melanie (main): ignore a) no message, b) removing from stable or
+       testing when invoked with -n/--no-action.
+
+       * katie (check_override): lower section before checking to see if
+       we're whining about 'non-US' versus 'non-US/main'.
+
+       * sql-aptvc.cpp: new file; wrapper around apt's version comparison
+       function so that we can use inside of PostgreSQL.
+
+2001-01-28  James Troup  <james@nocrew.org>
+
+       * katie: updated to pass new flag to parse_changes() and deal with
+       the exception raised on invalid .dsc's if appropriate.
+       * shania (main): likewise.
+       * melanie (main): likewise.
+
+       * tea (check_dscs): new function to validate all .dsc files in
+       unstable.
+
+       * utils.py (parse_changes): if passed an additional flag, validate
+       the .dsc file to ensure it's extractable by dpkg-source.
+       Requested by Ben Collins <bcollins@>.
+
+2001-01-27  James Troup  <james@nocrew.org>
+
+       * madison (main): connect to the DB as nobody.
+
+       * katie (check_files): remove support for -r/--no-version-check
+       since it makes no sense under katie (jenna will automatically
+       remove the (new) older version) and was evil in any event.
+       (check_changes): add missing new line to rejection message.
+       (check_dsc): likewise.
+       (process_it): reset reject_message here.
+       (main): not here.  Also remove support for -r.
+
+2001-01-26  James Troup  <james@nocrew.org>
+
+       * katie (check_override): don't whine about 'non-US/main' versus
+       'non-US'.
+
+2001-01-26  Michael Beattie  <mjb@debian.org>
+
+       * natalie.py (usage): new function.
+       (main): use it.
+
+2001-01-25  Antti-Juhani Kaijanaho  <gaia@iki.fi>
+
+       * update-mirrorlists: Update README.non-US too (request from Joy).
+
+2001-01-25  James Troup  <james@nocrew.org>
+
+       * katie (reject): catch any exception from utils.move() and just
+       pass, we previously only caught can't-overwrite errors and not
+       can't-read ones.
+
+       * jenna (generate_src_list): use ORDER BY in selects to avoid
+       unnecessary changes to Packages files.
+       (generate_bin_list): likewise.
+
+       * utils.py (extract_component_from_section): separated out from
+       build_file_list() as it's now used by claire too.
+
+       * claire.py (find_dislocated_stable): rewrite the query to extract
+       section information and handle component-less locations properly.
+       Thanks to ajt@ for the improved queries.
+       (fix_component_section): new function to fix components and
+       sections.
+
+2001-01-23  James Troup  <james@nocrew.org>
+
+       * katie (check_files): set file type for (u?)debs first thing, so
+       that if we continue, other functions which rely on file type
+       existing don't bomb out.  If apt_pkg or apt_inst raise an
+       exception when parsing the control file, don't try any other
+       checks, just drop out.
+       (check_changes): new test to ensure there is actually a target
+       distribution.
+
+2001-01-22  James Troup  <james@nocrew.org>
+
+       * katie (usage): s/dry-run/no-action/.  Noticed by Peter Gervai
+       <grin@>.
+       (check_changes): when mapping to unstable, remember to actually
+       add unstable to the suite list and not just remove the invalid
+       suite.
+
+2001-01-21  James Troup  <james@nocrew.org>
+
+       * katie (check_files): catch exceptions from debExtractControl()
+       and reject packages which raise any.
+
+2001-01-19  James Troup  <james@nocrew.org>
+
+       * katie (check_signature): basename() file name in rejection
+       message.
+
+2001-01-18  James Troup  <james@nocrew.org>
+
+       * katie (in_override_p): remember the section and priority from
+       the override file so we can check them against the package later.
+       (check_override): new function; checks section and priority (for
+       binaries) from the package against the override file and mails the
+       maintainer about any disparities.
+       (install): call check_override after announcing the upload.
+
+2001-01-16  James Troup  <james@nocrew.org>
+
+       * utils.py (build_file_list): catch ValueError's from splitting up
+       the files field and translate it into a parse error.
+
+       * tea: add support for finding unreferenced files.
+
+       * katie (in_override_p): add support for suite-aliasing so that
+       proposed-updates uploads work again.
+       (check_changes): catch parses errors from utils.build_file_list().
+       (check_dsc): likewise.
+       (check_diff): yet more dpkg breakage so we require even newer a
+       version.
+
+       * jenna (generate_bin_list): don't do nasty path munging that's no
+       longer needed.
+
+       * denise (main): support for non-US; and rename testing's override
+       files so they're based on testing's codename.
+
+2001-01-16  Martin Michlmayr  <tbm@cyrius.com>
+
+       * melanie: add to the bug closing message explaining what happens
+       (or rather doesn't) with bugs against packages that have been
+       removed.
+
+2001-01-14  James Troup  <james@nocrew.org>
+
+       * charisma (main): fix silly off-by-one error; suite priority
+       checking was done using "less than" rather than "less than or
+       equal to" which was causing weird hesienbugs with wrong Maintainer
+       fields.
+
+2001-01-10  James Troup  <james@nocrew.org>
+
+       * katie (in_override_p): adapted to use SQL-based overrides.
+       read_override_file function disappears.
+
+       * db_access.py: add new functions get_section_id, get_priority_id
+       and get_override_type_id.
+       (get_architecture_id): return -1 if the architecture is not found.
+
+       * heidi: switch %d -> %d in all SQL queries.
+       (get_list): Use string.join where appropriate.
+
+       * rhona (in_override_p): don't die if the override file doesn't
+       exist.
+       (main): warn if the override file doesn't exist.
+
+       * alyson: new script; will eventually sync the config file and the
+       SQL database.
+
+       * natalie.py: new script; manipulates overrides.
+
+       * melanie: new script; removes packages from suites.
+
+2001-01-08  James Troup  <james@nocrew.org>
+
+       * katie (re_bad_diff): whee; dpkg 1.8.1.1 didn't actually fix
+       anything it just changed the symptom.  Recognise the new breakage
+       and reject them too.
+
+2001-01-07  James Troup  <james@nocrew.org>
+
+       * katie (check_dsc): when adding the cwd copy of the .orig.tar.gz
+       to the .changes file, be sure to set up files[filename]["type"]
+       too.
+
+2001-01-06  James Troup  <james@nocrew.org>
+
+       * katie (check_diff): new function; detects bad diff files
+       produced by dpkg 1.8.1 and rejects thems.
+       (process_it): call check_diff().
+       (check_dsc): gar.  Add support for multiple versions of the
+       .orig.tar.gz file in the archive from -sa uploads.  Check md5sum
+       and size against all versions and use one which matches if
+       possible and exclude any that don't from being poolized to avoid
+       file overwrites.  Thanks to broonie@ for providing the example.
+       (install): skip any files marked as excluded as above.
+
+2001-01-05  James Troup  <james@nocrew.org>
+
+       * heidi (process_file): add missing argument to error message.
+
+2001-01-04  James Troup  <james@nocrew.org>
+
+       * heidi (main): fix handling of multiple files by reading all
+       files not just the first file n times (where n = the number of
+       files passed as arguments).
+
+2001-01-04  Anthony Towns  <ajt@debian.org>
+
+       * katie (check_dsc): proper fix for the code which locates the
+       .orig.tar.gz; check for '<filename>$' or '^<filename>$'.
+
+2000-12-20  James Troup  <james@nocrew.org>
+
+       * rhona: replace IN's with EXISTS's to make DELETE time for
+       binaries and source sane on auric.  Add a -n/--no-action flag and
+       make it stop actions if used.  Fixed a bug in binaries deletion
+       with no StayOfExecution (s/</<=/).  Add working -h/--help and
+       -V/--version.  Giving timing info on deletion till I'm sure it's
+       sane.
+
+       * katie (check_changes): map testing to unstable.
+
+       * madison: new script; shows versions in different architectures.
+
+       * katie (check_dsc): ensure size matches as well as md5sum;
+       suggested by Ben Collins <bcollins@debian.org> in Debian Bug
+       #69702.
+
+2000-12-19  James Troup  <james@nocrew.org>
+
+       * katie (reject): ignore the "can't overwrite file" exception from
+       utils.move() and leave the files where they are.
+       (reject): doh! os.access() test was reversed so we only tried to
+       move files which didn't exist... replaced with os.path.exists()
+       test the right way round.
+
+       * utils.py (move): raise an exception if we can't overwrite the
+       destination file.
+       (copy): likewise.
+
+2000-12-18  James Troup  <james@nocrew.org>
+
+       * rhona: first working version.
+
+       * db_access.py (get_files_id): force both sizes to be integers.
+
+       * katie (main): use size_type().
+
+       * utils.py (size_type): new function; pretty prints a file size.
+
+2000-12-17  James Troup  <james@nocrew.org>
+
+       * charisma (main): do version compares so that older packages do
+       not override newer ones and process source first as source wins
+       over binaries in terms of who we think of as the Maintainer.
+
+2000-12-15  James Troup  <james@nocrew.org>
+
+       * katie (install): use the files id for the .orig.tar.gz from
+       check_dsc().
+       (install): limit select for legacy source to a) source in legacy
+       or legacy-mixed type locations and b) distinct on files.id.
+       (install): rather than the bizarre insert new, delete old method
+       for moving legacy source into the pool, use a simple update of
+       files.
+       (process_it): initalize some globals before each process.
+
+2000-12-14  James Troup  <james@nocrew.org>
+
+       * katie (in_override_p): index on binary_type too since .udeb
+       overrides are in a different file.
+       (read_override_file): likewise.
+       (check_files): correct filename passed to get_files_id().
+       (check_dsc): we _have_ to preprend '/' to the filename to avoid
+       mismatches like jabber.orig.tar.gz versus libjabber.orig.tar.gz.
+       (check_dsc): remember the files id of the .orig.tar.gz, not the
+       location id.
+
+2000-12-13  James Troup  <james@nocrew.org>
+
+       * utils.py (poolify): force the component to lower case except for
+       non-US.
+
+       * katie (in_override_p): handle .udeb-specific override files.
+       (check_files): pass the binary type to in_override_p().
+       (check_dsc): remember the location id of the old .orig.tar.gz in
+       case it's not in the pool.
+       (install): use location id from dsc_files; which is where
+       check_dsc() puts it for old .orig.tar.gz files.
+       (install): install files after all DB work is complete.
+       (reject): basename() the changes filename.
+       (manual_reject): likewise.
+
+       * shania: new progam; replaces incomingcleaner.
+
+2000-12-05  James Troup  <james@nocrew.org>
+
+       * katie (check_changes): if inside stable and can't find files
+       from the .changes; assume it's installed in the pool and chdir()
+       to there.
+       (check_files): we are not installing for stable installs, so don't
+       check for overwriting existing files.
+       (check_dsc): likewise.
+       (check_dsc): reorder .orig.tar.gz handling so that we search in
+       the pool first and only then fall back on any .orig.tar.gz in the
+       cwd; this avoids false positives on the overwrite check when
+       people needlessly reupoad the .orig.tar.gz in a non-sa upload.
+       (install): if this is a stable install, bail out to
+       stable_install() immediately.
+       (install): dsc_files handling was horribly broken. a) we need to
+       add files from the .dsc and not the .changes (duh), b) we need to
+       add the .dsc file itself to dsc_files (to be consistent with neve
+       if for no other reason).
+       (stable_install): new function; handles installs from inside
+       proposed-updates to stable.
+       (acknowledge_new): basename changes_filename before doing
+       anything.
+       (process_it): absolutize the changes filename to avoid the
+       requirement of being in the same directory as the .changes file.
+       (process_it): save and restore the cwd as stable installs can
+       potentially jump into the pool to find files.
+
+       * jenna: dislocated_files support using claire.
+
+       * heidi (process_file): select package field from binaries
+       explicitly.
+
+       * db_access.py (get_files_id): fix cache key used.
+
+       * utils.py (build_file_list): fix 'non-US/non-free' case in
+       section/component splitting.
+       (move): use os.path.isdir() rather than stat.
+       (copy): likewise.
+
+       * claire.py: new file; stable in non-stable munger.
+
+       * tea: new file; simply ensures all files in the DB exist.
+
+2000-12-01  James Troup  <james@nocrew.org>
+
+       * katie (check_dsc): use regex_safe().
+       (check_changes): typo in changes{} key:
+       s/distributions/distribution/.
+       (install): use changes["source"], not files[file]["source"] as the
+       latter may not exist and the former is used elsewhere.  Commit the
+       SQL transaction earlier.
+
+       * utils.py (regex_safe): new function; escapes characters which
+       have meaning to SQL's regex comparison operator ('~').
+
+2000-11-30  James Troup  <james@nocrew.org>
+
+       * katie (install): pool_location is based on source package name,
+       not binary package.
+
+       * utils.py (move): if dest is a directory, append the filename
+       before chmod-ing.
+       (copy): ditto.
+
+       * katie (check_files): don't allow overwriting of existing .debs.
+       (check_dsc): don't allow overwriting of existing source files.
+
+2000-11-27  James Troup  <james@nocrew.org>
+
+       * katie (check_signature): don't try to load rsaref; it's
+       obsolete.
+       (in_override_p): don't try to lookup override entries for packages
+       with an invalid suite name.
+       (announce): don't assume the suite name is valid; use Find() to
+       lookup the mailing list name for announcements.
+
+       * utils.py (where_am_i): typo; hostname is in the first element,
+       not second.
+
+       * db_access.py (get_suite_id): return -1 on an unknown suite.
+
+2000-11-26  James Troup  <james@nocrew.org>
+
+       * katie (install): fix CopyChanges handling; typo in in checking
+       Cnf for CopyChanges flag and was calling non-existent function
+       copy_file.
+
+       * utils.py (copy): new function; clone of move without the
+       unlink().
+
+2000-11-25  James Troup  <james@nocrew.org>
+
+       * utils.py (build_file_list): handle non-US prefixes properly
+       (i.e. 'non-US' -> 'non-US/main' and 'non-US/libs' -> 'non-US/main'
+       + 'libs' not 'non-US/libs').
+       (send_mail): add '-odq' to sendmail invocation to avoid DNS lookup
+       delays.  This is possibly(/probably) exim speicifc and (like other
+       sendmail options) needs to be in the config file.
+
+2000-11-24  James Troup  <james@nocrew.org>
+
+       * rhona (check_sources): we need file id from dsc_files; not id.
+       Handle non .dsc source files being re-referenced in dsc_files.
+
+       * katie (in_override_p): strip out any 'non-US' prefix.
+       (check_files): use utils.where_am_i() rather than hardcoding.
+       (check_files): validate the component.
+       (install): use utils.where_am_i() rather than hardcoding.
+       (install): fix mail to go to actual recepient.
+       (reject): likewise.
+       (manual_reject): likewise.
+       (acknowledge_new): likewise.
+       (announce): likewise.
+
+       * db_access.py (get_component_id): ignore case when searching for
+       the component and don't crash if the component can't be found, but
+       return -1.
+       (get_location_id): handle -1 from get_component_id().
+
+       * jenna (generate_src_list): don't bring 'suite' into our big
+       multi-table-joining select as we already know the 'suite_id'.
+       (generate_bin_list): likewise.
+
+       * neve (main): don't quit if not on ftp-master.
+       (process_packages): remove unused variable 'suite_codename'.
+
+       * utils.py (move): actually move the file.
+       (build_file_list): handle non-US prefixes in the section.
+
+       * catherine (main): use which_conf_file().
+       * charisma (main): likewise.
+       * heidi (main): likewise.
+       * jenna (main): likewise.
+       * katie (main): likewise.
+       * neve (main): likewise.
+       * rhona (main): likewise.
+
+       * utils.py (where_am_i): new routine; determines the archive as
+       understood by other 'dak' programs.
+       (which_conf_file): new routine; determines the conf file to read.
+
+2000-11-17  James Troup  <james@nocrew.org>
+
+       * katie (install): fix where .changes files for proposed-updates
+       go.
+
+2000-11-04  James Troup  <james@nocrew.org>
+
+       * jenna (main): handle architecture properly if no
+       -a/--architecture argument is given, i.e. reset architecture with
+       the values for the suite for each suite.
+
+       * Add apt_pkg.init() to the start of all scripts as it's now
+       required by python-apt.
+
+2000-10-29  James Troup  <james@nocrew.org>
+
+       * jenna (generate_bin_list): take an additional argument 'type'
+       and use it in the SELECT.
+       (main): if processing component 'main', process udebs and debs.
+
+       * neve (process_packages): set up 'type' in 'binaries' (by
+       assuming .deb).
+
+       * katie (re_isadeb): accept ".udeb" or ".deb" as a file ending.
+       (check_files): set up files[file]["dbtype"].
+       (install): use files[file]["dbtype"] to set up the 'type' field in
+       the 'binaries' table.
+
+       * init_pool.sql: add a 'type' field to the 'binaries' table to
+       distinguisgh between ".udeb" and ".deb" files.
+
+       * utils.py (move): scrap basename() usage; use a "dir_p(dest) :
+       dest ? dirname(dest)" type check instead.
+
+       * katie (check_dsc): handle the case of an .orig.tar.gz not found
+       in the pool without crashing.  Also handle the case of being asked
+       to look for something other than an .orig.tar.gz in the pool.
+
+2000-10-26  James Troup  <james@nocrew.org>
+
+       * katie (install): fix filenames put into files table during
+       poolification of legacy source.
+
+       * utils.py (move): work around a bug in os.path.basename() which
+       cunningly returns '' if there is a trailing slash on the path
+       passed to it.
+
+       * katie (check_dsc): Remove more cruft.  If we find the
+       .orig.tar.gz in the pool and it's in a legacy (or legacy-mixed)
+       location, make a note of that so we can fix things in install().
+       (install): as above.  Move any old source out of legacy locations
+       so that 'apt-get source' will work.
+       (process_it): reset the flag that indicates to install that the
+       source needs moved.
+
+       * cron.daily: more.  Nowhere near complete yet though.
+
+       * katie (install): don't run os.makedirs, a) utils.move() does
+       this now, b) we weren't removing the user's umask and were
+       creating dirs with SNAFU permissions.
+       (check_dsc): rewrite the .orig.tar.gz handling to take into
+       account, err, package pools.  i.e. look anywhere in the pool
+       rather than faffing around with two simple paths.
+
+       * neve (process_sources): add the .dsc to dsc_files too.
+
+2000-10-25  James Troup  <james@nocrew.org>
+
+       * neve (process_sources): don't duplicate .orig.tar.gz's.
+
+2000-10-23  James Troup  <james@nocrew.org>
+
+       * utils.py (re_extract_src_version): moved here.
+
+       * neve: move re_extract_src_version to utils.
+       (process_packages): reflect change.
+
+       * katie (install): reflect change.
+
+2000-10-19  James Troup  <james@nocrew.org>
+
+       * jenna (generate_src_list): handle locations with null
+       components.
+       (generate_bin_list): likewise.
+
diff --git a/README.coding b/README.coding
new file mode 100644 (file)
index 0000000..bbe2417
--- /dev/null
@@ -0,0 +1,72 @@
+Some small guidelines if you want to help coding
+------------------------------------------------
+
+First: I'm always happy to get patches for Dak. I like to merge
+enhancements, bugfixes, whatever. The more, the better.
+
+Now, to not annoy us all by coming up with small fixes to patches
+multiple times before I merge them, lets write down a few small
+guidelines we all should follow. Yes, the current dakV1 code sure won't
+follow this everywhere, but no need to have new code be the same. :)
+
+I very much prefer git trees to merge from over simple patches,
+especially if you do lots of changes. (No need for a full git tree for a
+one-off fix). Reason is simple - its much easier to work with. And it is
+also way better in terms of assigning who did what, who has to earn the
+praise. :)
+In case you have more than one feature you want me to merge, one branch
+per feature please. If the location of your git tree is stable and
+doesn't change every second day I'm also very grateful. :)
+
+
+Code related:
+
+- Use readable and self-speaking variable names.
+
+- Its 4 spaces per indentation. No tab.
+
+- You want to make sure to not add useless whitespaces. If your editor
+  doesn't hilight them, Git can help you with that, just set
+  [color "diff"]
+     new = green
+     old = red
+     frag = yellow
+     meta = cyan
+     commit = normal
+  in your ~/.gitconfig, and a git diff should hilight them.
+  Even better, if you enable the hook pre-commit in your copy of the dak
+  code (chmod +x most probably), git will refuse to commit such things.
+
+- Describe *every* function you write using a docstring. No matter how small.
+
+- Also describe every file.
+
+- Don't forget the Copyright/License header in a file. We expect GPLv2 :)
+
+- Don't write long functions. If it goes above a sane limit (like 50
+  lines) - split it up.
+
+- Look at / read http://www.python.org/dev/peps/pep-0008/
+
+
+VCS related:
+
+- History rewriting is considered bad.
+
+- Always have a "Signed-off-by" line in your commit. `git commit -s`
+  automatically does it for you. Alternatively you can enable the hook
+  "prepare-commit-msg, that should also do it for you.
+
+- Write good, meaningful, commit messages. We do not have a Changelog
+  file anymore, the git commit is *the* place to tell others what you
+  did.
+  Also, try to use the standard format used in the Git world:
+
+    First comes a summary line, of around 72 caracters at most.
+
+    Then, a blank line, and as many lines and paragraphs as needed
+    to describe the change in detail. Beware, though, of including
+    in the commit message explanations that would be better to have
+    as comments in the code itself!
+
+    Signed-off-by: Your Name <and@address.com>
index 332a6170d3fc7ba5cb5f09ef5c6cc164e9a35dcb..345565b3e2b18f631bb0548a02ecab45658efad8 100644 (file)
@@ -126,6 +126,14 @@ Import-Archive
   ExportDir "/srv/ftp.debian.org/dak/import-archive-files/";
 };
 
+Import-Keyring
+{
+  /srv/ftp.debian.org/keyrings/debian-maintainers.gpg
+    {
+      Debian-Maintainer "true";
+    };
+};
+
 Reject-Proposed-Updates
 {
    StableRejector "the Stable Release Team";
index 1e7ea43321dca1816a4a20fc8f6d009ec69e2c15..0bb51bd7e8d6281f776a578efb0a95c1fd3b4796 100644 (file)
@@ -86,7 +86,7 @@ def check_signed_by_key(oldfn):
 
     if changes["source"] == "dpkg":
         fpr = changes["fingerprint"]
-        (uid, uid_name) = dak_module.lookup_uid_from_fingerprint(fpr)
+        (uid, uid_name, is_dm) = dak_module.lookup_uid_from_fingerprint(fpr)
         if fpr == "5906F687BD03ACAD0D8E602EFCF37657" or uid == "iwj":
             reject("Upload blocked due to hijack attempt 2008/03/19")
 
index 896ab1f546d0134eedeae6ce08501c60d3f3e877..33dc8481bc2aeac659c4e055e7917ebfa06829da 100755 (executable)
@@ -307,7 +307,7 @@ def validate_sources(suite, component):
     filename = "%s/dists/%s/%s/source/Sources.gz" % (Cnf["Dir::Root"], suite, component)
     print "Processing %s..." % (filename)
     # apt_pkg.ParseTagFile needs a real file handle and can't handle a GzipFile instance...
-    temp_filename = utils.temp_filename()
+    (fd, temp_filename) = utils.temp_filename()
     (result, output) = commands.getstatusoutput("gunzip -c %s > %s" % (filename, temp_filename))
     if (result != 0):
         sys.stderr.write("Gunzip invocation failed!\n%s\n" % (output))
@@ -346,7 +346,7 @@ def validate_packages(suite, component, architecture):
                % (Cnf["Dir::Root"], suite, component, architecture)
     print "Processing %s..." % (filename)
     # apt_pkg.ParseTagFile needs a real file handle and can't handle a GzipFile instance...
-    temp_filename = utils.temp_filename()
+    (fd, temp_filename) = utils.temp_filename()
     (result, output) = commands.getstatusoutput("gunzip -c %s > %s" % (filename, temp_filename))
     if (result != 0):
         sys.stderr.write("Gunzip invocation failed!\n%s\n" % (output))
index fab47bf056d72bf910fd774ed48c45e584487ce6..0f1125f81bc3c8f7eba5dcf9b170a81449ee0a9e 100755 (executable)
@@ -182,8 +182,8 @@ SELECT s.source, s.version AS experimental, s2.version AS unstable
   FROM src_associations sa, source s, source s2, src_associations sa2
   WHERE sa.suite = %s AND sa2.suite = %d AND sa.source = s.id
    AND sa2.source = s2.id AND s.source = s2.source
-   AND versioncmp(s.version, s2.version) < 0""" % (experimental_id,
-                                                   database.get_suite_id("unstable")))
+   AND s.version < s2.version""" % (experimental_id,
+                                    database.get_suite_id("unstable")))
     ql = q.getresult()
     if ql:
         nviu_to_remove = []
@@ -377,7 +377,7 @@ def main ():
     for component in components:
         filename = "%s/dists/%s/%s/source/Sources.gz" % (Cnf["Dir::Root"], suite, component)
         # apt_pkg.ParseTagFile needs a real file handle and can't handle a GzipFile instance...
-        temp_filename = utils.temp_filename()
+        (fd, temp_filename) = utils.temp_filename()
         (result, output) = commands.getstatusoutput("gunzip -c %s > %s" % (filename, temp_filename))
         if (result != 0):
             sys.stderr.write("Gunzip invocation failed!\n%s\n" % (output))
@@ -429,7 +429,7 @@ def main ():
         for architecture in architectures:
             filename = "%s/dists/%s/%s/binary-%s/Packages.gz" % (Cnf["Dir::Root"], suite, component, architecture)
             # apt_pkg.ParseTagFile needs a real file handle
-            temp_filename = utils.temp_filename()
+            (fd, temp_filename) = utils.temp_filename()
             (result, output) = commands.getstatusoutput("gunzip -c %s > %s" % (filename, temp_filename))
             if (result != 0):
                 sys.stderr.write("Gunzip invocation failed!\n%s\n" % (output))
index 9dfd026b162d90e0073c5d93cc1186d5d9b5238c..ad717ef3959f2aecf52166d6336287623e0d5126 100755 (executable)
@@ -144,14 +144,14 @@ def init():
          "Sync PostgreSQL users with passwd file"),
         ("init-db",
          "Update the database to match the conf file"),
+        ("update-db",
+         "Updates databae schema to latest revision"),
         ("init-dirs",
          "Initial setup of the archive"),
         ("make-maintainers",
          "Generates Maintainers file for BTS etc"),
         ("make-overrides",
          "Generates override files"),
-        ("mirror-split",
-         "Split the pool/ by architecture groups"),
         ("poolize",
          "Move packages from dists/ to pool/"),
         ("reject-proposed-updates",
diff --git a/dak/dakdb/__init__.py b/dak/dakdb/__init__.py
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/dak/dakdb/update1.py b/dak/dakdb/update1.py
new file mode 100644 (file)
index 0000000..3f0aa80
--- /dev/null
@@ -0,0 +1,64 @@
+#!/usr/bin/env python
+
+# Debian Archive Kit Database Update Script
+# Copyright (C) 2008  Michael Casadevall <mcasadevall@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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+
+################################################################################
+
+# <tomv_w> really, if we want to screw ourselves, let's find a better way.
+# <Ganneff> rm -rf /srv/ftp.debian.org
+
+################################################################################
+
+import psycopg2, time
+
+################################################################################
+
+def do_update(self):
+    print "Adding DM fields to database"
+
+    try:
+        c = self.db.cursor()
+        c.execute("ALTER TABLE source ADD COLUMN dm_upload_allowed BOOLEAN DEFAULT 'no' NOT NULL;")
+        c.execute("ALTER TABLE keyrings ADD COLUMN debian_maintainer BOOLEAN DEFAULT 'false' NOT NULL;")
+
+        print "Migrating DM data to source table. This might take some time ..."
+
+        c.execute("UPDATE source SET dm_upload_allowed = 't' WHERE id IN (SELECT source FROM src_uploaders);")
+        c.execute("UPDATE config SET value = '1' WHERE name = 'db_revision'")
+
+        print "Migrating DM uids to normal uids"
+        c.execute("SELECT uid FROM uid WHERE uid  LIKE 'dm:%'")
+        rows = c.fetchall()
+        for r in rows:
+            uid = r[0]
+            c.execute("UPDATE uid SET uid = '%s' WHERE uid = '%s'" % (uid[3:], uid))
+
+        self.db.commit()
+
+        print "IMPORTANT: Set the debian_maintainer flag in the config file for keyrings that are DMs!"
+        print "           Failure to do so will result in DM's having full upload abilities!"
+        print "REMINDER: Remember to run the updated byhand-dm crontab to update Debian Maintainer information"
+        print ""
+        print "Pausing for five seconds ..."
+        time.sleep (5)
+
+    except psycopg2.ProgrammingError, msg:
+        self.db.rollback()
+        print "FATAL: Unable to apply DM table update 1!"
+        print "Error Message: " + str(msg)
+        print "Database changes have been rolled back."
diff --git a/dak/dakdb/update2.py b/dak/dakdb/update2.py
new file mode 100755 (executable)
index 0000000..20154b0
--- /dev/null
@@ -0,0 +1,396 @@
+#!/usr/bin/env python
+# coding=utf8
+
+# Debian Archive Kit Database Update Script
+# Copyright Â© 2008  Michael Casadevall <mcasadevall@debian.org>
+# Copyright Â© 2008  Roger Leigh <rleigh@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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+
+################################################################################
+
+import psycopg2, time
+
+################################################################################
+
+def do_update(self):
+    print "Note: to be able to enable the the PL/Perl (plperl) procedural language, we do"
+    print "need postgresql-plperl-$postgres-version installed. Make sure that this is the"
+    print "case before you continue. Interrupt if it isn't, sleeping 5 seconds now."
+    print "(We need to be database superuser for this to work!)"
+    time.sleep (5)
+
+    try:
+        c = self.db.cursor()
+
+        print "Enabling PL/Perl language"
+        c.execute("CREATE LANGUAGE plperl;")
+        c.execute("CREATE LANGUAGE plpgsql;")
+
+        print "Adding debversion type to database."
+
+# Not present in all databases, maybe PL/Perl version-dependent?
+#        c.execute("SET SESSION plperl.use_strict TO 't';")
+
+        c.execute("CREATE DOMAIN debversion AS TEXT;")
+        c.execute("COMMENT ON DOMAIN debversion IS 'Debian package version number';")
+
+        c.execute("""ALTER DOMAIN debversion
+                     ADD CONSTRAINT debversion_syntax
+                     CHECK (VALUE !~ '[^-+:.0-9a-zA-Z~]');""")
+
+        # From Dpkg::Version::parseversion
+        c.execute("""CREATE OR REPLACE FUNCTION debversion_split (debversion)
+  RETURNS text[] AS $$
+    my $ver = shift;
+    my %verhash;
+    if ($ver =~ /:/)
+    {
+        $ver =~ /^(\d+):(.+)/ or die "bad version number '$ver'";
+        $verhash{epoch} = $1;
+        $ver = $2;
+    }
+    else
+    {
+        $verhash{epoch} = 0;
+    }
+    if ($ver =~ /(.+)-(.*)$/)
+    {
+        $verhash{version} = $1;
+        $verhash{revision} = $2;
+    }
+    else
+    {
+        $verhash{version} = $ver;
+        $verhash{revision} = 0;
+    }
+
+    return [$verhash{'epoch'}, $verhash{'version'}, $verhash{'revision'}];
+$$
+  LANGUAGE plperl
+  IMMUTABLE STRICT;""")
+        c.execute("""COMMENT ON FUNCTION debversion_split (debversion)
+                   IS 'Split debian version into epoch, upstream version and revision';""")
+
+        c.execute("""CREATE OR REPLACE FUNCTION debversion_epoch (version debversion)
+  RETURNS text AS $$
+DECLARE
+  split text[];
+BEGIN
+  split := debversion_split(version);
+  RETURN split[1];
+END;
+$$
+  LANGUAGE plpgsql
+  IMMUTABLE STRICT;
+COMMENT ON FUNCTION debversion_epoch (debversion)
+  IS 'Get debian version epoch';
+
+CREATE OR REPLACE FUNCTION debversion_version (version debversion)
+  RETURNS text AS $$
+DECLARE
+  split text[];
+BEGIN
+  split := debversion_split(version);
+  RETURN split[2];
+END;
+$$
+  LANGUAGE plpgsql
+  IMMUTABLE STRICT;""")
+        c.execute("""COMMENT ON FUNCTION debversion_version (debversion)
+                   IS 'Get debian version upstream version';""")
+
+        c.execute("""CREATE OR REPLACE FUNCTION debversion_revision (version debversion)
+  RETURNS text AS $$
+DECLARE
+  split text[];
+BEGIN
+  split := debversion_split(version);
+  RETURN split[3];
+END;
+$$
+  LANGUAGE plpgsql
+  IMMUTABLE STRICT;""")
+        c.execute("""COMMENT ON FUNCTION debversion_revision (debversion)
+                   IS 'Get debian version revision';""")
+
+# From Dpkg::Version::parseversion
+        c.execute("""CREATE OR REPLACE FUNCTION debversion_compare_single (version1 text, version2 text)
+  RETURNS integer AS $$
+     sub order{
+         my ($x) = @_;
+         ##define order(x) ((x) == '~' ? -1 \
+         #           : cisdigit((x)) ? 0 \
+         #           : !(x) ? 0 \
+         #           : cisalpha((x)) ? (x) \
+         #           : (x) + 256)
+         # This comparison is out of dpkg's order to avoid
+         # comparing things to undef and triggering warnings.
+         if (not defined $x or not length $x) {
+              return 0;
+         }
+         elsif ($x eq '~') {
+              return -1;
+         }
+         elsif ($x =~ /^\d$/) {
+              return 0;
+         }
+         elsif ($x =~ /^[A-Z]$/i) {
+              return ord($x);
+         }
+         else {
+              return ord($x) + 256;
+         }
+     }
+
+     sub next_elem(\@){
+         my $a = shift;
+         return @{$a} ? shift @{$a} : undef;
+     }
+     my ($val, $ref) = @_;
+     $val = "" if not defined $val;
+     $ref = "" if not defined $ref;
+     my @val = split //,$val;
+     my @ref = split //,$ref;
+     my $vc = next_elem @val;
+     my $rc = next_elem @ref;
+     while (defined $vc or defined $rc) {
+         my $first_diff = 0;
+         while ((defined $vc and $vc !~ /^\d$/) or
+                (defined $rc and $rc !~ /^\d$/)) {
+              my $vo = order($vc); my $ro = order($rc);
+              # Unlike dpkg's verrevcmp, we only return 1 or -1 here.
+              return (($vo - $ro > 0) ? 1 : -1) if $vo != $ro;
+              $vc = next_elem @val; $rc = next_elem @ref;
+         }
+         while (defined $vc and $vc eq '0') {
+              $vc = next_elem @val;
+         }
+         while (defined $rc and $rc eq '0') {
+              $rc = next_elem @ref;
+         }
+         while (defined $vc and $vc =~ /^\d$/ and
+                defined $rc and $rc =~ /^\d$/) {
+              $first_diff = ord($vc) - ord($rc) if !$first_diff;
+              $vc = next_elem @val; $rc = next_elem @ref;
+         }
+         return 1 if defined $vc and $vc =~ /^\d$/;
+         return -1 if defined $rc and $rc =~ /^\d$/;
+         return (($first_diff  > 0) ? 1 : -1) if $first_diff;
+     }
+     return 0;
+$$
+  LANGUAGE plperl
+  IMMUTABLE STRICT;""")
+        c.execute("""COMMENT ON FUNCTION debversion_compare_single (text, text)
+                   IS 'Compare upstream or revision parts of Debian versions';""")
+
+# Logic only derived from Dpkg::Version::parseversion
+        c.execute("""CREATE OR REPLACE FUNCTION debversion_compare (version1 debversion, version2 debversion)
+  RETURNS integer AS $$
+DECLARE
+  split1 text[];
+  split2 text[];
+  result integer;
+BEGIN
+  result := 0;
+  split1 := debversion_split(version1);
+  split2 := debversion_split(version2);
+
+  -- RAISE NOTICE 'Version 1: %', version1;
+  -- RAISE NOTICE 'Version 2: %', version2;
+  -- RAISE NOTICE 'Split 1: %', split1;
+  -- RAISE NOTICE 'Split 2: %', split2;
+
+  IF split1[1] > split2[1] THEN
+    result := 1;
+  ELSIF split1[1] < split2[1] THEN
+    result := -1;
+  ELSE
+    result := debversion_compare_single(split1[2], split2[2]);
+    IF result = 0 THEN
+      result := debversion_compare_single(split1[3], split2[3]);
+    END IF;
+  END IF;
+
+  RETURN result;
+END;
+$$
+  LANGUAGE plpgsql
+  IMMUTABLE STRICT;""")
+        c.execute("""COMMENT ON FUNCTION debversion_compare (debversion, debversion)
+  IS 'Compare Debian versions';""")
+
+        c.execute("""CREATE OR REPLACE FUNCTION debversion_eq (version1 debversion, version2 debversion)
+  RETURNS boolean AS $$
+DECLARE
+  comp integer;
+  result boolean;
+BEGIN
+  comp := debversion_compare(version1, version2);
+  result := comp = 0;
+  RETURN result;
+END;
+$$
+  LANGUAGE plpgsql
+  IMMUTABLE STRICT;""")
+        c.execute("""COMMENT ON FUNCTION debversion_eq (debversion, debversion)
+  IS 'debversion equal';""")
+
+        c.execute("""CREATE OR REPLACE FUNCTION debversion_ne (version1 debversion, version2 debversion)
+  RETURNS boolean AS $$
+DECLARE
+  comp integer;
+  result boolean;
+BEGIN
+  comp := debversion_compare(version1, version2);
+  result := comp <> 0;
+  RETURN result;
+END;
+$$
+  LANGUAGE plpgsql
+  IMMUTABLE STRICT;""")
+        c.execute("""COMMENT ON FUNCTION debversion_ne (debversion, debversion)
+  IS 'debversion not equal';""")
+
+        c.execute("""CREATE OR REPLACE FUNCTION debversion_lt (version1 debversion, version2 debversion)
+  RETURNS boolean AS $$
+DECLARE
+  comp integer;
+  result boolean;
+BEGIN
+  comp := debversion_compare(version1, version2);
+  result := comp < 0;
+  RETURN result;
+END;
+$$
+  LANGUAGE plpgsql
+  IMMUTABLE STRICT;""")
+        c.execute("""COMMENT ON FUNCTION debversion_lt (debversion, debversion)
+                   IS 'debversion less-than';""")
+
+        c.execute("""CREATE OR REPLACE FUNCTION debversion_gt (version1 debversion, version2 debversion) RETURNS boolean AS $$
+DECLARE
+  comp integer;
+  result boolean;
+BEGIN
+  comp := debversion_compare(version1, version2);
+  result := comp > 0;
+  RETURN result;
+END;
+$$
+  LANGUAGE plpgsql
+  IMMUTABLE STRICT;""")
+        c.execute("""COMMENT ON FUNCTION debversion_gt (debversion, debversion)
+                   IS 'debversion greater-than';""")
+
+        c.execute("""CREATE OR REPLACE FUNCTION debversion_le (version1 debversion, version2 debversion)
+  RETURNS boolean AS $$
+DECLARE
+  comp integer;
+  result boolean;
+BEGIN
+  comp := debversion_compare(version1, version2);
+  result := comp <= 0;
+  RETURN result;
+END;
+$$
+  LANGUAGE plpgsql
+  IMMUTABLE STRICT;""")
+        c.execute("""COMMENT ON FUNCTION debversion_le (debversion, debversion)
+                   IS 'debversion less-than-or-equal';""")
+
+        c.execute("""CREATE OR REPLACE FUNCTION debversion_ge (version1 debversion, version2 debversion)
+  RETURNS boolean AS $$
+DECLARE
+  comp integer;
+  result boolean;
+BEGIN
+  comp := debversion_compare(version1, version2);
+  result := comp >= 0;
+  RETURN result;
+END;
+$$
+  LANGUAGE plpgsql
+  IMMUTABLE STRICT;""")
+        c.execute("""COMMENT ON FUNCTION debversion_ge (debversion, debversion)
+                   IS 'debversion greater-than-or-equal';""")
+
+        c.execute("""CREATE OPERATOR = (
+                   PROCEDURE = debversion_eq,
+                   LEFTARG = debversion,
+                   RIGHTARG = debversion,
+                   COMMUTATOR = =,
+                   NEGATOR = !=);""")
+        c.execute("""COMMENT ON OPERATOR = (debversion, debversion)
+                   IS 'debversion equal';""")
+
+        c.execute("""CREATE OPERATOR != (
+                   PROCEDURE = debversion_eq,
+                   LEFTARG = debversion,
+                   RIGHTARG = debversion,
+                   COMMUTATOR = !=,
+                   NEGATOR = =);""")
+        c.execute("""COMMENT ON OPERATOR != (debversion, debversion)
+                   IS 'debversion not equal';""")
+
+        c.execute("""CREATE OPERATOR < (
+                   PROCEDURE = debversion_lt,
+                   LEFTARG = debversion,
+                   RIGHTARG = debversion,
+                   COMMUTATOR = >,
+                   NEGATOR = >=);""")
+        c.execute("""COMMENT ON OPERATOR < (debversion, debversion)
+                   IS 'debversion less-than';""")
+
+        c.execute("""CREATE OPERATOR > (
+                   PROCEDURE = debversion_gt,
+                   LEFTARG = debversion,
+                   RIGHTARG = debversion,
+                   COMMUTATOR = <,
+                   NEGATOR = >=);""")
+        c.execute("""COMMENT ON OPERATOR > (debversion, debversion)
+                   IS 'debversion greater-than';""")
+
+        c.execute("""CREATE OPERATOR <= (
+                   PROCEDURE = debversion_le,
+                   LEFTARG = debversion,
+                   RIGHTARG = debversion,
+                   COMMUTATOR = >=,
+                   NEGATOR = >);""")
+        c.execute("""COMMENT ON OPERATOR <= (debversion, debversion)
+                   IS 'debversion less-than-or-equal';""")
+
+        c.execute("""CREATE OPERATOR >= (
+                   PROCEDURE = debversion_ge,
+                   LEFTARG = debversion,
+                   RIGHTARG = debversion,
+                   COMMUTATOR = <=,
+                   NEGATOR = <);""")
+        c.execute("""COMMENT ON OPERATOR >= (debversion, debversion)
+                   IS 'debversion greater-than-or-equal';""")
+
+        c.execute("ALTER TABLE source ALTER COLUMN version TYPE debversion;")
+        c.execute("ALTER TABLE binaries ALTER COLUMN version TYPE debversion;")
+
+        c.execute("UPDATE config SET value = '2' WHERE name = 'db_revision'")
+
+        self.db.commit()
+
+    except psycopg2.ProgrammingError, msg:
+        self.db.rollback()
+        print "FATAL: Unable to apply debversion table update 2!"
+        print "Error Message: " + str(msg)
+        print "Database changes have been rolled back."
diff --git a/dak/dakdb/update3.py b/dak/dakdb/update3.py
new file mode 100755 (executable)
index 0000000..cc29786
--- /dev/null
@@ -0,0 +1,41 @@
+#!/usr/bin/env python
+
+# Debian Archive Kit Database Update Script
+# Copyright (C) 2008  Michael Casadevall <mcasadevall@debian.org>
+# Copyright (C) 2009  Joerg Jaspert <joerg@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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+
+################################################################################
+
+import psycopg2, time
+
+################################################################################
+
+def do_update(self):
+    print "Removing no longer used function versioncmp"
+
+    try:
+        c = self.db.cursor()
+        c.execute("DROP FUNCTION versioncmp(text, text);")
+        c.execute("UPDATE config SET value = '3' WHERE name = 'db_revision'")
+
+        self.db.commit()
+
+    except psycopg2.ProgrammingError, msg:
+        self.db.rollback()
+        print "FATAL: Unable to apply db update 3!"
+        print "Error Message: " + str(msg)
+        print "Database changes have been rolled back."
index c7ab7ad5865c8d9619cd9951acc8086e2610bbad..2a1a711e04ed4dd50f98855bf18770376d095553 100755 (executable)
@@ -271,7 +271,7 @@ def read_control (filename):
 
     return (control, control_keys, section, depends, recommends, arch, maintainer)
 
-def read_changes_or_dsc (filename):
+def read_changes_or_dsc (suite, filename):
     dsc = {}
 
     dsc_file = utils.open_file(filename)
@@ -290,7 +290,7 @@ def read_changes_or_dsc (filename):
 
     for k in dsc.keys():
         if k in ("build-depends","build-depends-indep"):
-            dsc[k] = create_depends_string(split_depends(dsc[k]))
+            dsc[k] = create_depends_string(suite, split_depends(dsc[k]))
         elif k == "architecture":
             if (dsc["architecture"] != "any"):
                 dsc['architecture'] = colour_output(dsc["architecture"], 'arch')
@@ -307,10 +307,13 @@ def read_changes_or_dsc (filename):
     filecontents = '\n'.join(map(lambda x: format_field(x,dsc[x.lower()]), keysinorder))+'\n'
     return filecontents
 
-def create_depends_string (depends_tree):
-    # just look up unstable for now. possibly pull from .changes later
-    suite = "unstable"
+def create_depends_string (suite, depends_tree):
     result = ""
+    if suite == 'experimental':
+        suite_where = " in ('experimental','unstable')"
+    else:
+        suite_where = " ='%s'" % suite
+
     comma_count = 1
     for l in depends_tree:
         if (comma_count >= 2):
@@ -321,7 +324,7 @@ def create_depends_string (depends_tree):
                 result += " | "
             # doesn't do version lookup yet.
 
-            q = projectB.query("SELECT DISTINCT(b.package), b.version, c.name, su.suite_name FROM  binaries b, files fi, location l, component c, bin_associations ba, suite su WHERE b.package='%s' AND b.file = fi.id AND fi.location = l.id AND l.component = c.id AND ba.bin=b.id AND ba.suite = su.id AND su.suite_name='%s' ORDER BY b.version desc" % (d['name'], suite))
+            q = projectB.query("SELECT DISTINCT(b.package), b.version, c.name, su.suite_name FROM  binaries b, files fi, location l, component c, bin_associations ba, suite su WHERE b.package='%s' AND b.file = fi.id AND fi.location = l.id AND l.component = c.id AND ba.bin=b.id AND ba.suite = su.id AND su.suite_name %s ORDER BY b.version desc" % (d['name'], suite_where))
             ql = q.getresult()
             if ql:
                 i = ql[0]
@@ -345,7 +348,7 @@ def create_depends_string (depends_tree):
         comma_count += 1
     return result
 
-def output_deb_info(filename):
+def output_deb_info(suite, filename):
     (control, control_keys, section, depends, recommends, arch, maintainer) = read_control(filename)
 
     if control == '':
@@ -353,9 +356,9 @@ def output_deb_info(filename):
     to_print = ""
     for key in control_keys :
         if key == 'Depends':
-            field_value = create_depends_string(depends)
+            field_value = create_depends_string(suite, depends)
         elif key == 'Recommends':
-            field_value = create_depends_string(recommends)
+            field_value = create_depends_string(suite, recommends)
         elif key == 'Section':
             field_value = section
         elif key == 'Architecture':
@@ -411,12 +414,12 @@ def get_copyright (deb_filename):
         printed_copyrights[copyrightmd5] = "%s (%s)" % (package, deb_filename)
     return res+formatted_text(cright)
 
-def check_dsc (dsc_filename):
-    (dsc) = read_changes_or_dsc(dsc_filename)
+def check_dsc (suite, dsc_filename):
+    (dsc) = read_changes_or_dsc(suite, dsc_filename)
     foldable_output(dsc_filename, "dsc", dsc, norow=True)
     foldable_output("lintian check for %s" % dsc_filename, "source-lintian", do_lintian(dsc_filename))
 
-def check_deb (deb_filename):
+def check_deb (suite, deb_filename):
     filename = os.path.basename(deb_filename)
     packagename = filename.split('_')[0]
 
@@ -427,7 +430,7 @@ def check_deb (deb_filename):
 
 
     foldable_output("control file for %s" % (filename), "binary-%s-control"%packagename,
-                    output_deb_info(deb_filename), norow=True)
+                    output_deb_info(suite, deb_filename), norow=True)
 
     if is_a_udeb:
         foldable_output("skipping lintian check for udeb", "binary-%s-lintian"%packagename,
@@ -452,11 +455,11 @@ def check_deb (deb_filename):
 # Read a file, strip the signature and return the modified contents as
 # a string.
 def strip_pgp_signature (filename):
-    file = utils.open_file (filename)
+    inputfile = utils.open_file (filename)
     contents = ""
     inside_signature = 0
     skip_next = 0
-    for line in file.readlines():
+    for line in inputfile.readlines():
         if line[:-1] == "":
             continue
         if inside_signature:
@@ -474,23 +477,23 @@ def strip_pgp_signature (filename):
             inside_signature = 0
             continue
         contents += line
-    file.close()
+    inputfile.close()
     return contents
 
-def display_changes(changes_filename):
-    changes = read_changes_or_dsc(changes_filename)
+def display_changes(suite, changes_filename):
+    changes = read_changes_or_dsc(suite, changes_filename)
     foldable_output(changes_filename, "changes", changes, norow=True)
 
 def check_changes (changes_filename):
-    display_changes(changes_filename)
-
     changes = utils.parse_changes (changes_filename)
+    display_changes(changes['distribution'], changes_filename)
+
     files = utils.build_file_list(changes)
     for f in files.keys():
         if f.endswith(".deb") or f.endswith(".udeb"):
-            check_deb(f)
+            check_deb(changes['distribution'], f)
         if f.endswith(".dsc"):
-            check_dsc(f)
+            check_dsc(changes['distribution'], f)
         # else: => byhand
 
 def main ():
@@ -524,9 +527,11 @@ def main ():
                 if f.endswith(".changes"):
                     check_changes(f)
                 elif f.endswith(".deb") or f.endswith(".udeb"):
-                    check_deb(file)
+                    # default to unstable when we don't have a .changes file
+                    # perhaps this should be a command line option?
+                    check_deb('unstable', file)
                 elif f.endswith(".dsc"):
-                    check_dsc(f)
+                    check_dsc('unstable', f)
                 else:
                     utils.fubar("Unrecognised file type: '%s'." % (f))
             finally:
index 286c1eba7f3ed870ead854ff7b395fb17c1ba6b8..f3f7a4a16bfec70f48db0b62268519c36031c6e1 100755 (executable)
 
 ################################################################################
 
-import sys, os, tempfile
+import sys
+import os
+import tempfile
+import subprocess
+import time
 import apt_pkg
 from daklib import utils
 
@@ -231,18 +235,7 @@ def genchanges(Options, outdir, oldfile, origfile, maxdiffs = 14):
 
     if upd.filesizesha1:
         if upd.filesizesha1 != oldsizesha1:
-            print "warning: old file seems to have changed! %s %s => %s %s" % (upd.filesizesha1 + oldsizesha1)
-
-    # XXX this should be usable now
-    #
-    #for d in upd.history.keys():
-    #    df = smartopen("%s/%s" % (outdir,d))
-    #    act_sha1size = sizesha1(df)
-    #    df.close()
-    #    exp_sha1size = upd.history[d][1]
-    #    if act_sha1size != exp_sha1size:
-    #        print "patch file %s seems to have changed! %s %s => %s %s" % \
-    #            (d,) + exp_sha1size + act_sha1size
+            print "info: old file " + oldfile + " changed! %s %s => %s %s" % (upd.filesizesha1 + oldsizesha1)
 
     if Options.has_key("CanonicalPath"): upd.can_path=Options["CanonicalPath"]
 
@@ -257,9 +250,14 @@ def genchanges(Options, outdir, oldfile, origfile, maxdiffs = 14):
         oldf.close()
         print "%s: unchanged" % (origfile)
     else:
-        if not os.path.isdir(outdir): os.mkdir(outdir)
-        w = os.popen("diff --ed - %s | gzip -c -9 > %s.gz" %
-                         (newfile, difffile), "w")
+        if not os.path.isdir(outdir):
+            os.mkdir(outdir)
+
+        cmd = "diff --ed - %s | gzip -c -9 > %s.gz" % (newfile, difffile)
+        # Do we need shell=True?
+        w = subprocess.Popen(cmd, shell=True, stdin=PIPE).stdin
+
+        # I bet subprocess can do that better than this, but lets do little steps
         pipe_file(oldf, w)
         oldf.close()
 
@@ -306,10 +304,7 @@ def main():
 
     if not Options.has_key("PatchName"):
         format = "%Y-%m-%d-%H%M.%S"
-        i,o = os.popen2("date +%s" % (format))
-        i.close()
-        Options["PatchName"] = o.readline()[:-1]
-        o.close()
+        Options["PatchName"] = time.strftime( format )
 
     AptCnf = apt_pkg.newConfiguration()
     apt_pkg.ReadConfigFileISC(AptCnf,utils.which_apt_conf_file())
index 00831192d3da8e5ce9c6390a111fcebb6bb928d7..a1552451051f2a189b9ab57cd8093da8ca2673fb 100755 (executable)
@@ -22,7 +22,8 @@
 
 ################################################################################
 
-import sys, os, popen2, tempfile, stat, time, pg
+import sys, os, stat, time, pg
+import gzip, bz2
 import apt_pkg
 from daklib import utils
 from daklib.dak_exceptions import *
@@ -77,43 +78,38 @@ def compressnames (tree,type,file):
             result.append(file + ".bz2")
     return result
 
-def create_temp_file (cmd):
-    f = tempfile.TemporaryFile()
-    r = popen2.popen2(cmd)
-    r[1].close()
-    r = r[0]
-    size = 0
-    while 1:
-        x = r.readline()
-        if not x:
-            r.close()
-            del x,r
-            break
-        f.write(x)
-        size += len(x)
-    f.flush()
-    f.seek(0)
-    return (size, f)
+decompressors = { 'zcat' : gzip.GzipFile,
+                  'bzip2' : bz2.BZ2File }
 
 def print_md5sha_files (tree, files, hashop):
     path = Cnf["Dir::Root"] + tree + "/"
     for name in files:
+        hashvalue = ""
+        hashlen = 0
         try:
             if name[0] == "<":
                 j = name.index("/")
                 k = name.index(">")
                 (cat, ext, name) = (name[1:j], name[j+1:k], name[k+1:])
-                (size, file_handle) = create_temp_file("%s %s%s%s" %
-                    (cat, path, name, ext))
+                file_handle = decompressors[ cat ]( "%s%s%s" % (path, name, ext) )
+                contents = file_handle.read()
+                hashvalue = hashop(contents)
+                hashlen = len(contents)
             else:
-                size = os.stat(path + name)[stat.ST_SIZE]
-                file_handle = utils.open_file(path + name)
+                try:
+                    file_handle = utils.open_file(path + name)
+                    hashvalue = hashop(file_handle)
+                    hashlen = os.stat(path + name).st_size
+                except:
+                    raise
+                else:
+                    if file_handle:
+                        file_handle.close()
+
         except CantOpenError:
             print "ALERT: Couldn't open " + path + name
         else:
-            hash = hashop(file_handle)
-            file_handle.close()
-            out.write(" %s %8d %s\n" % (hash, size, name))
+            out.write(" %s %8d %s\n" % (hashvalue, hashlen, name))
 
 def print_md5_files (tree, files):
     print_md5sha_files (tree, files, apt_pkg.md5sum)
@@ -239,8 +235,8 @@ def main ():
                 for arch in AptCnf["tree::%s::Architectures" % (tree)].split():
                     if arch == "source":
                         filepath = "%s/%s/Sources" % (sec, arch)
-                        for file in compressnames("tree::%s" % (tree), "Sources", filepath):
-                            files.append(file)
+                        for cfile in compressnames("tree::%s" % (tree), "Sources", filepath):
+                            files.append(cfile)
                         add_tiffani(files, Cnf["Dir::Root"] + tree, filepath)
                     else:
                         disks = "%s/disks-%s" % (sec, arch)
@@ -251,8 +247,8 @@ def main ():
                                     files.append("%s/%s/md5sum.txt" % (disks, dir))
 
                         filepath = "%s/binary-%s/Packages" % (sec, arch)
-                        for file in compressnames("tree::%s" % (tree), "Packages", filepath):
-                            files.append(file)
+                        for cfile in compressnames("tree::%s" % (tree), "Packages", filepath):
+                            files.append(cfile)
                         add_tiffani(files, Cnf["Dir::Root"] + tree, filepath)
 
                     if arch == "source":
@@ -294,10 +290,10 @@ def main ():
 
                     for arch in AptCnf["tree::%s/%s::Architectures" % (tree,dis)].split():
                         if arch != "source":  # always true
-                            for file in compressnames("tree::%s/%s" % (tree,dis),
+                            for cfile in compressnames("tree::%s/%s" % (tree,dis),
                                 "Packages",
                                 "%s/%s/binary-%s/Packages" % (dis, sec, arch)):
-                                files.append(file)
+                                files.append(cfile)
             elif AptCnf.has_key("tree::%s::FakeDI" % (tree)):
                 usetree = AptCnf["tree::%s::FakeDI" % (tree)]
                 sec = AptCnf["tree::%s/main::Sections" % (usetree)].split()[0]
@@ -306,14 +302,14 @@ def main ():
 
                 for arch in AptCnf["tree::%s/main::Architectures" % (usetree)].split():
                     if arch != "source":  # always true
-                        for file in compressnames("tree::%s/main" % (usetree), "Packages", "main/%s/binary-%s/Packages" % (sec, arch)):
-                            files.append(file)
+                        for cfile in compressnames("tree::%s/main" % (usetree), "Packages", "main/%s/binary-%s/Packages" % (sec, arch)):
+                            files.append(cfile)
 
         elif AptCnf.has_key("bindirectory::%s" % (tree)):
-            for file in compressnames("bindirectory::%s" % (tree), "Packages", AptCnf["bindirectory::%s::Packages" % (tree)]):
-                files.append(file.replace(tree+"/","",1))
-            for file in compressnames("bindirectory::%s" % (tree), "Sources", AptCnf["bindirectory::%s::Sources" % (tree)]):
-                files.append(file.replace(tree+"/","",1))
+            for cfile in compressnames("bindirectory::%s" % (tree), "Packages", AptCnf["bindirectory::%s::Packages" % (tree)]):
+                files.append(cfile.replace(tree+"/","",1))
+            for cfile in compressnames("bindirectory::%s" % (tree), "Sources", AptCnf["bindirectory::%s::Sources" % (tree)]):
+                files.append(cfile.replace(tree+"/","",1))
         else:
             print "ALERT: no tree/bindirectory for %s" % (tree)
 
index 4432ff1ac602c6b8008a2efcff154cbd9e9a3d23..53635e2acac63b7f086cb4b5b208f138ef0acd56 100755 (executable)
@@ -477,7 +477,7 @@ def process_packages (filename, suite, component, archive):
 ###############################################################################
 
 def do_sources(sources, suite, component, server):
-    temp_filename = utils.temp_filename()
+    (fd, temp_filename) = utils.temp_filename()
     (result, output) = commands.getstatusoutput("gunzip -c %s > %s" % (sources, temp_filename))
     if (result != 0):
         utils.fubar("Gunzip invocation failed!\n%s" % (output), result)
index a70a2e7811b9d8f10b9013efafa3c49867e415d5..c8013d6e7f10c598414a3b77690f9f0160c33efe 100755 (executable)
@@ -35,9 +35,9 @@ def get_uid_info():
     byname = {}
     byid = {}
     q = projectB.query("SELECT id, uid, name FROM uid")
-    for (id, uid, name) in q.getresult():
-        byname[uid] = (id, name)
-        byid[id] = (uid, name)
+    for (keyid, uid, name) in q.getresult():
+        byname[uid] = (keyid, name)
+        byid[keyid] = (uid, name)
     return (byname, byid)
 
 def get_fingerprint_info():
@@ -131,16 +131,16 @@ class Keyring:
             uid = entry["uid"][0]
             name = get_ldap_name(entry)
             fingerprints = entry["keyFingerPrint"]
-            id = None
+            keyid = None
             for f in fingerprints:
                 key = fpr_lookup.get(f, None)
                 if key not in keys: continue
                 keys[key]["uid"] = uid
 
-                if id != None: continue
-                id = database.get_or_set_uid_id(uid)
-                byuid[id] = (uid, name)
-                byname[uid] = (id, name)
+                if keyid != None: continue
+                keyid = database.get_or_set_uid_id(uid)
+                byuid[keyid] = (uid, name)
+                byname[uid] = (keyid, name)
 
         return (byname, byuid)
 
@@ -155,15 +155,15 @@ class Keyring:
                 keys[x]["uid"] = format % "invalid-uid"
             else:
                 uid = format % keys[x]["email"]
-                id = database.get_or_set_uid_id(uid)
-                byuid[id] = (uid, keys[x]["name"])
-                byname[uid] = (id, keys[x]["name"])
+                keyid = database.get_or_set_uid_id(uid)
+                byuid[keyid] = (uid, keys[x]["name"])
+                byname[uid] = (keyid, keys[x]["name"])
                 keys[x]["uid"] = uid
         if any_invalid:
             uid = format % "invalid-uid"
-            id = database.get_or_set_uid_id(uid)
-            byuid[id] = (uid, "ungeneratable user id")
-            byname[uid] = (id, "ungeneratable user id")
+            keyid = database.get_or_set_uid_id(uid)
+            byuid[keyid] = (uid, "ungeneratable user id")
+            byname[uid] = (keyid, "ungeneratable user id")
         return (byname, byuid)
 
 ################################################################################
@@ -222,6 +222,11 @@ def main():
     keyringname = keyring_names[0]
     keyring = Keyring(keyringname)
 
+    is_dm = "false"
+    if Cnf.has_key("Import-Keyring::"+keyringname+"::Debian-Maintainer"):
+        projectB.query("UPDATE keyrings SET debian_maintainer = '%s' WHERE name = '%s'" % (Cnf["Import-Keyring::"+keyringname+"::Debian-Maintainer"], keyringname.split("/")[-1]))
+        is_dm = Cnf["Import-Keyring::"+keyringname+"::Debian-Maintainer"]
+
     keyring_id = database.get_or_set_keyring_id(
                         keyringname.split("/")[-1])
 
@@ -232,14 +237,14 @@ def main():
     (db_uid_byname, db_uid_byid) = get_uid_info()
 
     ### Update full names of applicable users
-    for id in desuid_byid.keys():
-        uid = (id, desuid_byid[id][0])
-        name = desuid_byid[id][1]
-        oname = db_uid_byid[id][1]
+    for keyid in desuid_byid.keys():
+        uid = (keyid, desuid_byid[keyid][0])
+        name = desuid_byid[keyid][1]
+        oname = db_uid_byid[keyid][1]
         if name and oname != name:
             changes.append((uid[1], "Full name: %s" % (name)))
             projectB.query("UPDATE uid SET name = '%s' WHERE id = %s" %
-                (pg.escape_string(name), id))
+                (pg.escape_string(name), keyid))
 
     # The fingerprint table (fpr) points to a uid and a keyring.
     #   If the uid is being decided here (ldap/generate) we set it to it.
@@ -249,11 +254,11 @@ def main():
 
     fpr = {}
     for z in keyring.keys.keys():
-        id = db_uid_byname.get(keyring.keys[z].get("uid", None), [None])[0]
-        if id == None:
-            id = db_fin_info.get(keyring.keys[z]["fingerprints"][0], [None])[0]
+        keyid = db_uid_byname.get(keyring.keys[z].get("uid", None), [None])[0]
+        if keyid == None:
+            keyid = db_fin_info.get(keyring.keys[z]["fingerprints"][0], [None])[0]
         for y in keyring.keys[z]["fingerprints"]:
-            fpr[y] = (id,keyring_id)
+            fpr[y] = (keyid,keyring_id)
 
     # For any keys that used to be in this keyring, disassociate them.
     # We don't change the uid, leaving that for historical info; if
@@ -291,7 +296,12 @@ def main():
                 projectB.query("UPDATE fingerprint SET uid = %d WHERE id = %d" % (newuid, oldfid))
 
             if oldkid != keyring_id:
-                projectB.query("UPDATE fingerprint SET keyring = %d WHERE id = %d" % (keyring_id, oldfid))
+                # Only change the keyring if it won't result in a loss of permissions
+                q = projectB.query("SELECT debian_maintainer FROM keyrings WHERE id = '%d'" % (keyring_id))
+                if is_dm == "false" and q.getresult()[0][0] == 'f':
+                    projectB.query("UPDATE fingerprint SET keyring = %d WHERE id = %d" % (keyring_id, oldfid))
+                else:
+                    print "Key %s exists in both DM and DD keyrings. Not demoting." % (f)
 
     # All done!
 
index b568285357180b6d53a0dc690c3c922e207c6e92..49b5b056cd00f67877ee7b172a9c110bc6c3556e 100755 (executable)
@@ -151,7 +151,7 @@ SELECT f.fingerprint, f.id, u.uid FROM fingerprint f, uid u WHERE f.uid = u.id
                     print "Assigning %s to 0x%s." % (uid, fingerprint)
                 elif existing_uid == uid:
                     pass
-                elif existing_uid[:3] == "dm:":
+                elif '@' not in existing_uid:
                     q = projectB.query("UPDATE fingerprint SET uid = %s WHERE id = %s" % (uid_id, fingerprint_id))
                     print "Promoting DM %s to DD %s with keyid 0x%s." % (existing_uid, uid, fingerprint)
                 else:
index 090b8d4337d1dfdc2a3039d34512cce0d54d1c88..679ed22367ce62e3a8229fd81d9d89202853ba00 100755 (executable)
@@ -130,8 +130,8 @@ def main():
 
     # Process any additional Maintainer files (e.g. from pseudo packages)
     for filename in extra_files:
-        file = utils.open_file(filename)
-        for line in file.readlines():
+        extrafile = utils.open_file(filename)
+        for line in extrafile.readlines():
             line = utils.re_comments.sub('', line).strip()
             if line == "":
                 continue
@@ -147,7 +147,7 @@ def main():
             if not packages.has_key(package) or version == '*' \
                or apt_pkg.VersionCompare(packages[package]["version"], version) < 0:
                 packages[package] = { "maintainer": maintainer, "version": version }
-        file.close()
+        extrafile.close()
 
     package_keys = packages.keys()
     package_keys.sort()
index 1087ce286784d57110c1e51faef6450fd3ef8188..2ed4f4bafeabac1fec9f84da65b4776402d341fb 100755 (executable)
@@ -105,13 +105,13 @@ def main ():
         override_suite = Cnf["Suite::%s::OverrideCodeName" % (suite)]
         for component in Cnf.SubTree("Component").List():
             if component == "mixed":
-                continue; # Ick
+                continue # Ick
             for otype in Cnf.ValueList("OverrideType"):
                 if otype == "deb":
                     suffix = ""
                 elif otype == "udeb":
                     if component == "contrib":
-                        continue; # Ick2
+                        continue # Ick2
                     suffix = ".debian-installer"
                 elif otype == "dsc":
                     suffix = ".src"
index 41e6cb33b9765a699ae488db77eab7bc942b097e..dbbab7ec4712bcc3eacfe28ee55e2dadd99a0d91 100755 (executable)
@@ -201,10 +201,10 @@ def write_legacy_mixed_filelist(suite, list, packages, dislocated_files):
     output = utils.open_file(filename, "w")
     # Generate the final list of files
     files = {}
-    for id in list:
-        path = packages[id]["path"]
-        filename = packages[id]["filename"]
-        file_id = packages[id]["file_id"]
+    for fileid in list:
+        path = packages[fileid]["path"]
+        filename = packages[fileid]["filename"]
+        file_id = packages[fileid]["file_id"]
         if suite == "stable" and dislocated_files.has_key(file_id):
             filename = dislocated_files[file_id]
         else:
@@ -217,8 +217,8 @@ def write_legacy_mixed_filelist(suite, list, packages, dislocated_files):
     keys = files.keys()
     keys.sort()
     # Write the list of files out
-    for file in keys:
-        output.write(file+'\n')
+    for outfile in keys:
+        output.write(outfile+'\n')
     output.close()
 
 ############################################################
@@ -234,11 +234,11 @@ def write_filelist(suite, component, arch, type, list, packages, dislocated_file
     output = utils.open_file(filename, "w")
     # Generate the final list of files
     files = {}
-    for id in list:
-        path = packages[id]["path"]
-        filename = packages[id]["filename"]
-        file_id = packages[id]["file_id"]
-        pkg = packages[id]["pkg"]
+    for fileid in list:
+        path = packages[fileid]["path"]
+        filename = packages[fileid]["filename"]
+        file_id = packages[fileid]["file_id"]
+        pkg = packages[fileid]["pkg"]
         if suite == "stable" and dislocated_files.has_key(file_id):
             filename = dislocated_files[file_id]
         else:
@@ -264,12 +264,12 @@ def write_filelists(packages, dislocated_files):
         suite = packages[unique_id]["suite"]
         component = packages[unique_id]["component"]
         arch = packages[unique_id]["arch"]
-        type = packages[unique_id]["type"]
+        packagetype = packages[unique_id]["type"]
         d.setdefault(suite, {})
         d[suite].setdefault(component, {})
         d[suite][component].setdefault(arch, {})
-        d[suite][component][arch].setdefault(type, [])
-        d[suite][component][arch][type].append(unique_id)
+        d[suite][component][arch].setdefault(packagetype, [])
+        d[suite][component][arch][packagetype].append(unique_id)
     # Flesh out the index
     if not Options["Suite"]:
         suites = Cnf.SubTree("Suite").List()
@@ -282,7 +282,6 @@ def write_filelists(packages, dislocated_files):
         else:
             components = utils.split_args(Options["Component"])
         udeb_components = Cnf.ValueList("Suite::%s::UdebComponents" % (suite))
-        udeb_components = udeb_components
         for component in components:
             d[suite].setdefault(component, {})
             if component in udeb_components:
@@ -299,8 +298,8 @@ def write_filelists(packages, dislocated_files):
                     types = [ "dsc" ]
                 else:
                     types = binary_types
-                for type in types:
-                    d[suite][component][arch].setdefault(type, [])
+                for packagetype in types:
+                    d[suite][component][arch].setdefault(packagetype, [])
     # Then walk it
     for suite in d.keys():
         if Cnf.has_key("Suite::%s::Components" % (suite)):
@@ -308,25 +307,25 @@ def write_filelists(packages, dislocated_files):
                 for arch in d[suite][component].keys():
                     if arch == "all":
                         continue
-                    for type in d[suite][component][arch].keys():
-                        list = d[suite][component][arch][type]
+                    for packagetype in d[suite][component][arch].keys():
+                        filelist = d[suite][component][arch][packagetype]
                         # If it's a binary, we need to add in the arch: all debs too
                         if arch != "source":
                             archall_suite = Cnf.get("Make-Suite-File-List::ArchAllMap::%s" % (suite))
                             if archall_suite:
-                                list.extend(d[archall_suite][component]["all"][type])
+                                filelist.extend(d[archall_suite][component]["all"][packagetype])
                             elif d[suite][component].has_key("all") and \
-                                     d[suite][component]["all"].has_key(type):
-                                list.extend(d[suite][component]["all"][type])
-                        write_filelist(suite, component, arch, type, list,
+                                     d[suite][component]["all"].has_key(packagetype):
+                                filelist.extend(d[suite][component]["all"][packagetype])
+                        write_filelist(suite, component, arch, packagetype, filelist,
                                        packages, dislocated_files)
         else: # legacy-mixed suite
-            list = []
+            filelist = []
             for component in d[suite].keys():
                 for arch in d[suite][component].keys():
-                    for type in d[suite][component][arch].keys():
-                        list.extend(d[suite][component][arch][type])
-            write_legacy_mixed_filelist(suite, list, packages, dislocated_files)
+                    for packagetype in d[suite][component][arch].keys():
+                        filelist.extend(d[suite][component][arch][packagetype])
+            write_legacy_mixed_filelist(suite, filelist, packages, dislocated_files)
 
 ################################################################################
 
@@ -369,13 +368,13 @@ SELECT s.id, s.source, 'source', s.version, l.path, f.filename, c.name, f.id,
     packages = {}
     unique_id = 0
     for i in ql:
-        (id, pkg, arch, version, path, filename, component, file_id, suite, type) = i
+        (sourceid, pkg, arch, version, path, filename, component, file_id, suite, filetype) = i
         # 'id' comes from either 'binaries' or 'source', so it's not unique
         unique_id += 1
-        packages[unique_id] = Dict(id=id, pkg=pkg, arch=arch, version=version,
+        packages[unique_id] = Dict(sourceid=sourceid, pkg=pkg, arch=arch, version=version,
                                    path=path, filename=filename,
                                    component=component, file_id=file_id,
-                                   suite=suite, type = type)
+                                   suite=suite, filetype = filetype)
     cleanup(packages)
     write_filelists(packages, dislocated_files)
 
diff --git a/dak/mirror_split.py b/dak/mirror_split.py
deleted file mode 100644 (file)
index 3f79020..0000000
+++ /dev/null
@@ -1,391 +0,0 @@
-#!/usr/bin/env python
-
-# Prepare and maintain partial trees by architecture
-# Copyright (C) 2004, 2006  Daniel Silverstone <dsilvers@digital-scurf.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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
-
-
-###############################################################################
-## <kinnison> So Martin, do you have a quote for me yet?
-## <tbm> Make something damned stupid up and attribute it to me, that's okay
-###############################################################################
-
-import sys
-import apt_pkg
-
-from stat import S_ISDIR, S_ISLNK, S_ISREG
-import os
-import cPickle
-
-import daklib.utils
-
-## Master path is the main repository
-#MASTER_PATH = "/org/ftp.debian.org/scratch/dsilvers/master"
-
-MASTER_PATH = "***Configure Mirror-Split::FTPPath Please***"
-TREE_ROOT = "***Configure Mirror-Split::TreeRootPath Please***"
-TREE_DB_ROOT = "***Configure Mirror-Split::TreeDatabasePath Please***"
-trees = []
-
-Cnf = None
-
-###############################################################################
-# A MirrorSplitTarget is a representation of a target. It is a set of archs, a path
-# and whether or not the target includes source.
-##################
-
-class MirrorSplitTarget:
-    def __init__(self, name, archs, source):
-        self.name = name
-        self.root = "%s/%s" % (TREE_ROOT,name)
-        self.archs = archs.split(",")
-        self.source = source
-        self.dbpath = "%s/%s.db" % (TREE_DB_ROOT,name)
-        self.db = MirrorSplitDB()
-        if os.path.exists( self.dbpath ):
-            self.db.load_from_file( self.dbpath )
-
-    ## Save the db back to disk
-    def save_db(self):
-        self.db.save_to_file( self.dbpath )
-
-    ## Returns true if it's a poolish match
-    def poolish_match(self, path):
-        for a in self.archs:
-            if path.endswith( "_%s.deb" % (a) ):
-                return 1
-            if path.endswith( "_%s.udeb" % (a) ):
-                return 1
-        if self.source:
-            if (path.endswith( ".tar.gz" ) or
-                path.endswith( ".diff.gz" ) or
-                path.endswith( ".dsc" )):
-                return 1
-        return 0
-
-    ## Returns false if it's a badmatch distswise
-    def distish_match(self,path):
-        for a in self.archs:
-            if path.endswith("/Contents-%s.gz" % (a)):
-                return 1
-            if path.find("/binary-%s/" % (a)) != -1:
-                return 1
-            if path.find("/installer-%s/" % (a)) != -1:
-                return 1
-        if path.find("/source/") != -1:
-            if self.source:
-                return 1
-            else:
-                return 0
-        if path.find("/Contents-") != -1:
-            return 0
-        if path.find("/binary-") != -1:
-            return 0
-        if path.find("/installer-") != -1:
-            return 0
-        return 1
-
-##############################################################################
-# The applicable function is basically a predicate. Given a path and a
-# target object its job is to decide if the path conforms for the
-# target and thus is wanted.
-#
-# 'verbatim' is a list of files which are copied regardless
-# it should be loaded from a config file eventually
-##################
-
-verbatim = [
-    ]
-
-verbprefix = [
-    "/tools/",
-    "/README",
-    "/doc/"
-    ]
-
-def applicable(path, target):
-    if path.startswith("/pool/"):
-        return target.poolish_match(path)
-    if (path.startswith("/dists/") or
-        path.startswith("/project/experimental/")):
-        return target.distish_match(path)
-    if path in verbatim:
-        return 1
-    for prefix in verbprefix:
-        if path.startswith(prefix):
-            return 1
-    return 0
-
-
-##############################################################################
-# A MirrorSplitDir is a representation of a tree.
-#   It distinguishes files dirs and links
-# Dirs are dicts of (name, MirrorSplitDir)
-# Files are dicts of (name, inode)
-# Links are dicts of (name, target)
-##############
-
-class MirrorSplitDir:
-    def __init__(self):
-        self.dirs = {}
-        self.files = {}
-        self.links = {}
-
-##############################################################################
-# A MirrorSplitDB is a container for a MirrorSplitDir...
-##############
-
-class MirrorSplitDB:
-    ## Initialise a MirrorSplitDB as containing nothing
-    def __init__(self):
-        self.root = MirrorSplitDir()
-
-    def _internal_recurse(self, path):
-        bdir = MirrorSplitDir()
-        dl = os.listdir( path )
-        dl.sort()
-        dirs = []
-        for ln in dl:
-            lnl = os.lstat( "%s/%s" % (path, ln) )
-            if S_ISDIR(lnl[0]):
-                dirs.append(ln)
-            elif S_ISLNK(lnl[0]):
-                bdir.links[ln] = os.readlink( "%s/%s" % (path, ln) )
-            elif S_ISREG(lnl[0]):
-                bdir.files[ln] = lnl[1]
-            else:
-                daklib.utils.fubar( "Confused by %s/%s -- not a dir, link or file" %
-                            ( path, ln ) )
-        for d in dirs:
-            bdir.dirs[d] = self._internal_recurse( "%s/%s" % (path,d) )
-
-        return bdir
-
-    ## Recurse through a given path, setting the sequence accordingly
-    def init_from_dir(self, dirp):
-        self.root = self._internal_recurse( dirp )
-
-    ## Load this MirrorSplitDB from file
-    def load_from_file(self, fname):
-        f = open(fname, "r")
-        self.root = cPickle.load(f)
-        f.close()
-
-    ## Save this MirrorSplitDB to a file
-    def save_to_file(self, fname):
-        f = open(fname, "w")
-        cPickle.dump( self.root, f, 1 )
-        f.close()
-
-
-##############################################################################
-# Helper functions for the tree syncing...
-##################
-
-def _pth(a,b):
-    return "%s/%s" % (a,b)
-
-def do_mkdir(targ,path):
-    if not os.path.exists( _pth(targ.root, path) ):
-        os.makedirs( _pth(targ.root, path) )
-
-def do_mkdir_f(targ,path):
-    do_mkdir(targ, os.path.dirname(path))
-
-def do_link(targ,path):
-    do_mkdir_f(targ,path)
-    os.link( _pth(MASTER_PATH, path),
-             _pth(targ.root, path))
-
-def do_symlink(targ,path,link):
-    do_mkdir_f(targ,path)
-    os.symlink( link, _pth(targ.root, path) )
-
-def do_unlink(targ,path):
-    os.unlink( _pth(targ.root, path) )
-
-def do_unlink_dir(targ,path):
-    os.system( "rm -Rf '%s'" % _pth(targ.root, path) )
-
-##############################################################################
-# Reconciling a target with the sourcedb
-################
-
-def _internal_reconcile( path, srcdir, targdir, targ ):
-    # Remove any links in targdir which aren't in srcdir
-    # Or which aren't applicable
-    rm = []
-    for k in targdir.links.keys():
-        if applicable( _pth(path, k), targ ):
-            if not srcdir.links.has_key(k):
-                rm.append(k)
-        else:
-            rm.append(k)
-    for k in rm:
-        #print "-L-", _pth(path,k)
-        do_unlink(targ, _pth(path,k))
-        del targdir.links[k]
-
-    # Remove any files in targdir which aren't in srcdir
-    # Or which aren't applicable
-    rm = []
-    for k in targdir.files.keys():
-        if applicable( _pth(path, k), targ ):
-            if not srcdir.files.has_key(k):
-                rm.append(k)
-        else:
-            rm.append(k)
-    for k in rm:
-        #print "-F-", _pth(path,k)
-        do_unlink(targ, _pth(path,k))
-        del targdir.files[k]
-
-    # Remove any dirs in targdir which aren't in srcdir
-    rm = []
-    for k in targdir.dirs.keys():
-        if not srcdir.dirs.has_key(k):
-            rm.append(k)
-    for k in rm:
-        #print "-D-", _pth(path,k)
-        do_unlink_dir(targ, _pth(path,k))
-        del targdir.dirs[k]
-
-    # Add/update files
-    for k in srcdir.files.keys():
-        if applicable( _pth(path,k), targ ):
-            if not targdir.files.has_key(k):
-                #print "+F+", _pth(path,k)
-                do_link( targ, _pth(path,k) )
-                targdir.files[k] = srcdir.files[k]
-            else:
-                if targdir.files[k] != srcdir.files[k]:
-                    #print "*F*", _pth(path,k)
-                    do_unlink( targ, _pth(path,k) )
-                    do_link( targ, _pth(path,k) )
-                    targdir.files[k] = srcdir.files[k]
-
-    # Add/update links
-    for k in srcdir.links.keys():
-        if applicable( _pth(path,k), targ ):
-            if not targdir.links.has_key(k):
-                targdir.links[k] = srcdir.links[k];
-                #print "+L+",_pth(path,k), "->", srcdir.links[k]
-                do_symlink( targ, _pth(path,k), targdir.links[k] )
-            else:
-                if targdir.links[k] != srcdir.links[k]:
-                    do_unlink( targ, _pth(path,k) )
-                    targdir.links[k] = srcdir.links[k]
-                    #print "*L*", _pth(path,k), "to ->", srcdir.links[k]
-                    do_symlink( targ, _pth(path,k), targdir.links[k] )
-
-    # Do dirs
-    for k in srcdir.dirs.keys():
-        if not targdir.dirs.has_key(k):
-            targdir.dirs[k] = MirrorSplitDir()
-            #print "+D+", _pth(path,k)
-        _internal_reconcile( _pth(path,k), srcdir.dirs[k],
-                             targdir.dirs[k], targ )
-
-
-def reconcile_target_db( src, targ ):
-    _internal_reconcile( "", src.root, targ.db.root, targ )
-
-###############################################################################
-
-def load_config():
-    global MASTER_PATH
-    global TREE_ROOT
-    global TREE_DB_ROOT
-    global trees
-
-    MASTER_PATH = Cnf["Mirror-Split::FTPPath"]
-    TREE_ROOT = Cnf["Mirror-Split::TreeRootPath"]
-    TREE_DB_ROOT = Cnf["Mirror-Split::TreeDatabasePath"]
-
-    for a in Cnf.ValueList("Mirror-Split::BasicTrees"):
-        trees.append( MirrorSplitTarget( a, "%s,all" % a, 1 ) )
-
-    for n in Cnf.SubTree("Mirror-Split::CombinationTrees").List():
-        archs = Cnf.ValueList("Mirror-Split::CombinationTrees::%s" % n)
-        source = 0
-        if "source" in archs:
-            source = 1
-            archs.remove("source")
-        archs = ",".join(archs)
-        trees.append( MirrorSplitTarget( n, archs, source ) )
-
-def do_list ():
-    print "Master path",MASTER_PATH
-    print "Trees at",TREE_ROOT
-    print "DBs at",TREE_DB_ROOT
-
-    for tree in trees:
-        print tree.name,"contains",", ".join(tree.archs),
-        if tree.source:
-            print " [source]"
-        else:
-            print ""
-
-def do_help ():
-    print """Usage: dak mirror-split [OPTIONS]
-Generate hardlink trees of certain architectures
-
-  -h, --help                 show this help and exit
-  -l, --list                 list the configuration and exit
-"""
-
-
-def main ():
-    global Cnf
-
-    Cnf = daklib.utils.get_conf()
-
-    Arguments = [('h',"help","Mirror-Split::Options::Help"),
-                 ('l',"list","Mirror-Split::Options::List"),
-                 ]
-
-    arguments = apt_pkg.ParseCommandLine(Cnf,Arguments,sys.argv)
-    Cnf["Mirror-Split::Options::cake"] = ""
-    Options = Cnf.SubTree("Mirror-Split::Options")
-
-    print "Loading configuration..."
-    load_config()
-    print "Loaded."
-
-    if Options.has_key("Help"):
-        do_help()
-        return
-    if Options.has_key("List"):
-        do_list()
-        return
-
-
-    src = MirrorSplitDB()
-    print "Scanning", MASTER_PATH
-    src.init_from_dir(MASTER_PATH)
-    print "Scanned"
-
-    for tree in trees:
-        print "Reconciling tree:",tree.name
-        reconcile_target_db( src, tree )
-        print "Saving updated DB...",
-        tree.save_db()
-        print "Done"
-
-##############################################################################
-
-if __name__ == '__main__':
-    main()
index 856428e013cc5ea0f219f4cc9fcf6dcaa9288782..4071b78afdac79db33db354880ea7fbc6c138729 100755 (executable)
@@ -26,7 +26,7 @@ from daklib import utils
 from daklib import database
 import apt_pkg, os, sys, pwd, time, re, commands
 
-re_taint_free = re.compile(r"^['/;\-\+\.~\s\w]+$");
+re_taint_free = re.compile(r"^['/;\-\+\.~\s\w]+$")
 
 Cnf = None
 Options = None
index f98f03c5ae21a2f761fa1bd9550949e7e90a4b97..0bda5e769996f64f6cbaed6996aa4e3190178277 100755 (executable)
@@ -107,9 +107,9 @@ def main ():
 
     # Retrieve current section/priority...
     oldsection, oldsourcesection, oldpriority = None, None, None
-    for type in ['source', 'binary']:
+    for packagetype in ['source', 'binary']:
         eqdsc = '!='
-        if type == 'source':
+        if packagetype == 'source':
             eqdsc = '='
         q = projectB.query("""
     SELECT priority.priority AS prio, section.section AS sect, override_type.type AS type
@@ -129,7 +129,7 @@ def main ():
             utils.fubar("%s is ambiguous. Matches %d packages" % (package,q.ntuples()))
 
         r = q.getresult()
-        if type == 'binary':
+        if packagetype == 'binary':
             oldsection = r[0][1]
             oldpriority = r[0][0]
         else:
index 0d5a5387e3fbcf556c96872608d93cfc843f9005..a25c391fc374f9d286d8e515ecf74adfa64e9684 100755 (executable)
@@ -109,32 +109,32 @@ def reject (str, prefix="Rejected: "):
 def check():
     propogate={}
     nopropogate={}
-    for file in files.keys():
+    for checkfile in files.keys():
         # The .orig.tar.gz can disappear out from under us is it's a
         # duplicate of one in the archive.
-        if not files.has_key(file):
+        if not files.has_key(checkfile):
             continue
         # Check that the source still exists
-        if files[file]["type"] == "deb":
-            source_version = files[file]["source version"]
-            source_package = files[file]["source package"]
+        if files[checkfile]["type"] == "deb":
+            source_version = files[checkfile]["source version"]
+            source_package = files[checkfile]["source package"]
             if not changes["architecture"].has_key("source") \
                and not Upload.source_exists(source_package, source_version,  changes["distribution"].keys()):
-                reject("no source found for %s %s (%s)." % (source_package, source_version, file))
+                reject("no source found for %s %s (%s)." % (source_package, source_version, checkfile))
 
         # Version and file overwrite checks
         if not installing_to_stable:
-            if files[file]["type"] == "deb":
-                reject(Upload.check_binary_against_db(file), "")
-            elif files[file]["type"] == "dsc":
-                reject(Upload.check_source_against_db(file), "")
-                (reject_msg, is_in_incoming) = Upload.check_dsc_against_db(file)
+            if files[checkfile]["type"] == "deb":
+                reject(Upload.check_binary_against_db(checkfile), "")
+            elif files[checkfile]["type"] == "dsc":
+                reject(Upload.check_source_against_db(checkfile), "")
+                (reject_msg, is_in_incoming) = Upload.check_dsc_against_db(checkfile)
                 reject(reject_msg, "")
 
         # propogate in the case it is in the override tables:
         if changes.has_key("propdistribution"):
             for suite in changes["propdistribution"].keys():
-                if Upload.in_override_p(files[file]["package"], files[file]["component"], suite, files[file].get("dbtype",""), file):
+                if Upload.in_override_p(files[checkfile]["package"], files[checkfile]["component"], suite, files[checkfile].get("dbtype",""), checkfile):
                     propogate[suite] = 1
                 else:
                     nopropogate[suite] = 1
@@ -144,11 +144,11 @@ def check():
             continue
         changes["distribution"][suite] = 1
 
-    for file in files.keys():
+    for checkfile in files.keys():
         # Check the package is still in the override tables
         for suite in changes["distribution"].keys():
-            if not Upload.in_override_p(files[file]["package"], files[file]["component"], suite, files[file].get("dbtype",""), file):
-                reject("%s is NEW for %s." % (file, suite))
+            if not Upload.in_override_p(files[checkfile]["package"], files[checkfile]["component"], suite, files[checkfile].get("dbtype",""), checkfile):
+                reject("%s is NEW for %s." % (checkfile, suite))
 
 ###############################################################################
 
@@ -283,8 +283,8 @@ def install ():
         return
 
     # Add the .dsc file to the DB
-    for file in files.keys():
-        if files[file]["type"] == "dsc":
+    for newfile in files.keys():
+        if files[newfile]["type"] == "dsc":
             package = dsc["source"]
             version = dsc["version"]  # NB: not files[file]["version"], that has no epoch
             maintainer = dsc["maintainer"]
@@ -295,22 +295,26 @@ def install ():
             changedby_id = database.get_or_set_maintainer_id(changedby)
             fingerprint_id = database.get_or_set_fingerprint_id(dsc["fingerprint"])
             install_date = time.strftime("%Y-%m-%d")
-            filename = files[file]["pool name"] + file
-            dsc_component = files[file]["component"]
-            dsc_location_id = files[file]["location id"]
-            if not files[file].has_key("files id") or not files[file]["files id"]:
-                files[file]["files id"] = database.set_files_id (filename, files[file]["size"], files[file]["md5sum"], files[file]["sha1sum"], files[file]["sha256sum"], dsc_location_id)
-            projectB.query("INSERT INTO source (source, version, maintainer, changedby, file, install_date, sig_fpr) VALUES ('%s', '%s', %d, %d, %d, '%s', %s)"
-                           % (package, version, maintainer_id, changedby_id, files[file]["files id"], install_date, fingerprint_id))
+            filename = files[newfile]["pool name"] + newfile
+            dsc_component = files[newfile]["component"]
+            dsc_location_id = files[newfile]["location id"]
+            if dsc.has_key("dm-upload-allowed") and  dsc["dm-upload-allowed"] == "yes":
+                dm_upload_allowed = "true"
+            else:
+                dm_upload_allowed = "false"
+            if not files[newfile].has_key("files id") or not files[newfile]["files id"]:
+                files[newfile]["files id"] = database.set_files_id (filename, files[newfile]["size"], files[newfile]["md5sum"], files[newfile]["sha1sum"], files[newfile]["sha256sum"], dsc_location_id)
+            projectB.query("INSERT INTO source (source, version, maintainer, changedby, file, install_date, sig_fpr, dm_upload_allowed) VALUES ('%s', '%s', %d, %d, %d, '%s', %s, %s)"
+                           % (package, version, maintainer_id, changedby_id, files[newfile]["files id"], install_date, fingerprint_id, dm_upload_allowed))
 
             for suite in changes["distribution"].keys():
                 suite_id = database.get_suite_id(suite)
                 projectB.query("INSERT INTO src_associations (suite, source) VALUES (%d, currval('source_id_seq'))" % (suite_id))
 
             # Add the source files to the DB (files and dsc_files)
-            projectB.query("INSERT INTO dsc_files (source, file) VALUES (currval('source_id_seq'), %d)" % (files[file]["files id"]))
+            projectB.query("INSERT INTO dsc_files (source, file) VALUES (currval('source_id_seq'), %d)" % (files[newfile]["files id"]))
             for dsc_file in dsc_files.keys():
-                filename = files[file]["pool name"] + dsc_file
+                filename = files[newfile]["pool name"] + dsc_file
                 # If the .orig.tar.gz is already in the pool, it's
                 # files id is stored in dsc_files by check_dsc().
                 files_id = dsc_files[dsc_file].get("files id", None)
@@ -322,48 +326,47 @@ def install ():
                 projectB.query("INSERT INTO dsc_files (source, file) VALUES (currval('source_id_seq'), %d)" % (files_id))
 
             # Add the src_uploaders to the DB
-            if dsc.get("dm-upload-allowed", "no") == "yes":
-                uploader_ids = [maintainer_id]
-                if dsc.has_key("uploaders"):
-                    for u in dsc["uploaders"].split(","):
-                        u = u.replace("'", "\\'")
-                        u = u.strip()
-                        uploader_ids.append(
-                            database.get_or_set_maintainer_id(u))
-                added_ids = {}
-                for u in uploader_ids:
-                    if added_ids.has_key(u):
-                        utils.warn("Already saw uploader %s for source %s" % (u, package))
-                        continue
-                    added_ids[u]=1
-                    projectB.query("INSERT INTO src_uploaders (source, maintainer) VALUES (currval('source_id_seq'), %d)" % (u))
+            uploader_ids = [maintainer_id]
+            if dsc.has_key("uploaders"):
+                for u in dsc["uploaders"].split(","):
+                    u = u.replace("'", "\\'")
+                    u = u.strip()
+                    uploader_ids.append(
+                        database.get_or_set_maintainer_id(u))
+            added_ids = {}
+            for u in uploader_ids:
+                if added_ids.has_key(u):
+                    utils.warn("Already saw uploader %s for source %s" % (u, package))
+                    continue
+                added_ids[u]=1
+                projectB.query("INSERT INTO src_uploaders (source, maintainer) VALUES (currval('source_id_seq'), %d)" % (u))
 
 
     # Add the .deb files to the DB
-    for file in files.keys():
-        if files[file]["type"] == "deb":
-            package = files[file]["package"]
-            version = files[file]["version"]
-            maintainer = files[file]["maintainer"]
+    for newfile in files.keys():
+        if files[newfile]["type"] == "deb":
+            package = files[newfile]["package"]
+            version = files[newfile]["version"]
+            maintainer = files[newfile]["maintainer"]
             maintainer = maintainer.replace("'", "\\'")
             maintainer_id = database.get_or_set_maintainer_id(maintainer)
             fingerprint_id = database.get_or_set_fingerprint_id(changes["fingerprint"])
-            architecture = files[file]["architecture"]
+            architecture = files[newfile]["architecture"]
             architecture_id = database.get_architecture_id (architecture)
-            type = files[file]["dbtype"]
-            source = files[file]["source package"]
-            source_version = files[file]["source version"]
-            filename = files[file]["pool name"] + file
-            if not files[file].has_key("location id") or not files[file]["location id"]:
-                files[file]["location id"] = database.get_location_id(Cnf["Dir::Pool"],files[file]["component"],utils.where_am_i())
-            if not files[file].has_key("files id") or not files[file]["files id"]:
-                files[file]["files id"] = database.set_files_id (filename, files[file]["size"], files[file]["md5sum"], files[file]["sha1sum"], files[file]["sha256sum"], files[file]["location id"])
+            filetype = files[newfile]["dbtype"]
+            source = files[newfile]["source package"]
+            source_version = files[newfile]["source version"]
+            filename = files[newfile]["pool name"] + newfile
+            if not files[newfile].has_key("location id") or not files[newfile]["location id"]:
+                files[newfile]["location id"] = database.get_location_id(Cnf["Dir::Pool"],files[newfile]["component"],utils.where_am_i())
+            if not files[newfile].has_key("files id") or not files[newfile]["files id"]:
+                files[newfile]["files id"] = database.set_files_id (filename, files[newfile]["size"], files[newfile]["md5sum"], files[newfile]["sha1sum"], files[newfile]["sha256sum"], files[newfile]["location id"])
             source_id = database.get_source_id (source, source_version)
             if source_id:
                 projectB.query("INSERT INTO binaries (package, version, maintainer, source, architecture, file, type, sig_fpr) VALUES ('%s', '%s', %d, %d, %d, %d, '%s', %d)"
-                               % (package, version, maintainer_id, source_id, architecture_id, files[file]["files id"], type, fingerprint_id))
+                               % (package, version, maintainer_id, source_id, architecture_id, files[newfile]["files id"], filetype, fingerprint_id))
             else:
-                raise NoSourceFieldError, "Unable to find a source id for %s (%s), %s, file %s, type %s, signed by %s" % (package, version, architecture, file, type, sig_fpr)
+                raise NoSourceFieldError, "Unable to find a source id for %s (%s), %s, file %s, type %s, signed by %s" % (package, version, architecture, newfile, filetype, changes["fingerprint"])
             for suite in changes["distribution"].keys():
                 suite_id = database.get_suite_id(suite)
                 projectB.query("INSERT INTO bin_associations (suite, bin) VALUES (%d, currval('binaries_id_seq'))" % (suite_id))
@@ -383,7 +386,7 @@ def install ():
                 continue
             # First move the files to the new location
             legacy_filename = qid["path"] + qid["filename"]
-            pool_location = utils.poolify (changes["source"], files[file]["component"])
+            pool_location = utils.poolify (changes["source"], files[newfile]["component"])
             pool_filename = pool_location + os.path.basename(qid["filename"])
             destination = Cnf["Dir::Pool"] + pool_location
             utils.move(legacy_filename, destination)
@@ -411,11 +414,11 @@ def install ():
             projectB.query("UPDATE dsc_files SET file = %s WHERE source = %s AND file = %s" % (new_files_id, database.get_source_id(changes["source"], changes["version"]), orig_tar_id))
 
     # Install the files into the pool
-    for file in files.keys():
-        destination = Cnf["Dir::Pool"] + files[file]["pool name"] + file
-        utils.move(file, destination)
-        Logger.log(["installed", file, files[file]["type"], files[file]["size"], files[file]["architecture"]])
-        install_bytes += float(files[file]["size"])
+    for newfile in files.keys():
+        destination = Cnf["Dir::Pool"] + files[newfile]["pool name"] + newfile
+        utils.move(newfile, destination)
+        Logger.log(["installed", newfile, files[newfile]["type"], files[newfile]["size"], files[newfile]["architecture"]])
+        install_bytes += float(files[newfile]["size"])
 
     # Copy the .changes file across for suite which need it.
     copy_changes = {}
@@ -454,14 +457,14 @@ def install ():
         dest_dir = Cnf["Dir::QueueBuild"]
         if Cnf.FindB("Dinstall::SecurityQueueBuild"):
             dest_dir = os.path.join(dest_dir, suite)
-        for file in files.keys():
-            dest = os.path.join(dest_dir, file)
+        for newfile in files.keys():
+            dest = os.path.join(dest_dir, newfile)
             # Remove it from the list of packages for later processing by apt-ftparchive
             projectB.query("UPDATE queue_build SET in_queue = 'f', last_used = '%s' WHERE filename = '%s' AND suite = %s" % (now_date, dest, suite_id))
             if not Cnf.FindB("Dinstall::SecurityQueueBuild"):
                 # Update the symlink to point to the new location in the pool
-                pool_location = utils.poolify (changes["source"], files[file]["component"])
-                src = os.path.join(Cnf["Dir::Pool"], pool_location, os.path.basename(file))
+                pool_location = utils.poolify (changes["source"], files[newfile]["component"])
+                src = os.path.join(Cnf["Dir::Pool"], pool_location, os.path.basename(newfile))
                 if os.path.islink(dest):
                     os.unlink(dest)
                 os.symlink(src, dest)
@@ -490,8 +493,8 @@ def stable_install (summary, short_summary):
     projectB.query("BEGIN WORK")
 
     # Add the source to stable (and remove it from proposed-updates)
-    for file in files.keys():
-        if files[file]["type"] == "dsc":
+    for newfile in files.keys():
+        if files[newfile]["type"] == "dsc":
             package = dsc["source"]
             version = dsc["version"];  # NB: not files[file]["version"], that has no epoch
             q = projectB.query("SELECT id FROM source WHERE source = '%s' AND version = '%s'" % (package, version))
@@ -505,11 +508,11 @@ def stable_install (summary, short_summary):
             projectB.query("INSERT INTO src_associations (suite, source) VALUES ('%s', '%s')" % (suite_id, source_id))
 
     # Add the binaries to stable (and remove it/them from proposed-updates)
-    for file in files.keys():
-        if files[file]["type"] == "deb":
-            package = files[file]["package"]
-            version = files[file]["version"]
-            architecture = files[file]["architecture"]
+    for newfile in files.keys():
+        if files[newfile]["type"] == "deb":
+            package = files[newfile]["package"]
+            version = files[newfile]["version"]
+            architecture = files[newfile]["architecture"]
             q = projectB.query("SELECT b.id FROM binaries b, architecture a WHERE b.package = '%s' AND b.version = '%s' AND (a.arch_string = '%s' OR a.arch_string = 'all') AND b.architecture = a.id" % (package, version, architecture))
             ql = q.getresult()
             if not ql:
@@ -532,13 +535,13 @@ def stable_install (summary, short_summary):
         os.unlink (new_changelog_filename)
 
     new_changelog = utils.open_file(new_changelog_filename, 'w')
-    for file in files.keys():
-        if files[file]["type"] == "deb":
-            new_changelog.write("stable/%s/binary-%s/%s\n" % (files[file]["component"], files[file]["architecture"], file))
-        elif utils.re_issource.match(file):
-            new_changelog.write("stable/%s/source/%s\n" % (files[file]["component"], file))
+    for newfile in files.keys():
+        if files[newfile]["type"] == "deb":
+            new_changelog.write("stable/%s/binary-%s/%s\n" % (files[newfile]["component"], files[newfile]["architecture"], newfile))
+        elif utils.re_issource.match(newfile):
+            new_changelog.write("stable/%s/source/%s\n" % (files[newfile]["component"], newfile))
         else:
-            new_changelog.write("%s\n" % (file))
+            new_changelog.write("%s\n" % (newfile))
     chop_changes = queue.re_fdnic.sub("\n", changes["changes"])
     new_changelog.write(chop_changes + '\n\n')
     if os.access(changelog_filename, os.R_OK) != 0:
index 0b9ff9231d72c397115292944efe94c7fe529f91..496e5689babf47ba026018b6437a1bb765ccb4a5 100755 (executable)
@@ -230,6 +230,7 @@ def sort_changes(changes_files):
 class Section_Completer:
     def __init__ (self):
         self.sections = []
+        self.matches = []
         q = projectB.query("SELECT section FROM section")
         for i in q.getresult():
             self.sections.append(i[0])
@@ -251,6 +252,7 @@ class Section_Completer:
 class Priority_Completer:
     def __init__ (self):
         self.priorities = []
+        self.matches = []
         q = projectB.query("SELECT priority FROM priority")
         for i in q.getresult():
             self.priorities.append(i[0])
@@ -309,8 +311,8 @@ def index_range (index):
 
 def edit_new (new):
     # Write the current data to a temporary file
-    temp_filename = utils.temp_filename()
-    temp_file = utils.open_file(temp_filename, 'w')
+    (fd, temp_filename) = utils.temp_filename()
+    temp_file = os.fdopen(fd, 'w')
     print_new (new, 0, temp_file)
     temp_file.close()
     # Spawn an editor on that file
@@ -455,8 +457,8 @@ def edit_overrides (new):
 
 def edit_note(note):
     # Write the current data to a temporary file
-    temp_filename = utils.temp_filename()
-    temp_file = utils.open_file(temp_filename, 'w')
+    (fd, temp_filename) = utils.temp_filename()
+    temp_file = os.fdopen(fd, 'w')
     temp_file.write(note)
     temp_file.close()
     editor = os.environ.get("EDITOR","vi")
@@ -493,15 +495,16 @@ def check_pkg ():
         stdout_fd = sys.stdout
         try:
             sys.stdout = less_fd
-            examine_package.display_changes(Upload.pkg.changes_file)
+            changes = utils.parse_changes (Upload.pkg.changes_file)
+            examine_package.display_changes(changes['distribution'], Upload.pkg.changes_file)
             files = Upload.pkg.files
             for f in files.keys():
                 if files[f].has_key("new"):
                     ftype = files[f]["type"]
                     if ftype == "deb":
-                        examine_package.check_deb(f)
+                        examine_package.check_deb(changes['distribution'], f)
                     elif ftype == "dsc":
-                        examine_package.check_dsc(f)
+                        examine_package.check_dsc(changes['distribution'], f)
         finally:
             sys.stdout = stdout_fd
     except IOError, e:
@@ -560,12 +563,12 @@ def add_overrides (new):
 
 def prod_maintainer ():
     # Here we prepare an editor and get them ready to prod...
-    temp_filename = utils.temp_filename()
+    (fd, temp_filename) = utils.temp_filename()
     editor = os.environ.get("EDITOR","vi")
     answer = 'E'
     while answer == 'E':
         os.system("%s %s" % (editor, temp_filename))
-        f = utils.open_file(temp_filename)
+        f = os.fdopen(fd)
         prod_message = "".join(f.readlines())
         f.close()
         print "Prod message:"
index 690c1c115e19a51f66f29244b09c33e6bb8d0684..fae2fffb98a1d7dd65c35a19ac93ee269608e913 100755 (executable)
@@ -997,17 +997,17 @@ def check_timestamps():
 ################################################################################
 
 def lookup_uid_from_fingerprint(fpr):
-    q = Upload.projectB.query("SELECT u.uid, u.name FROM fingerprint f, uid u WHERE f.uid = u.id AND f.fingerprint = '%s'" % (fpr))
+    q = Upload.projectB.query("SELECT u.uid, u.name, k.debian_maintainer FROM fingerprint f JOIN keyrings k ON (f.keyring=k.id), uid u WHERE f.uid = u.id AND f.fingerprint = '%s'" % (fpr))
     qs = q.getresult()
     if len(qs) == 0:
-        return (None, None)
+        return (None, None, None)
     else:
         return qs[0]
 
 def check_signed_by_key():
     """Ensure the .changes is signed by an authorized uploader."""
 
-    (uid, uid_name) = lookup_uid_from_fingerprint(changes["fingerprint"])
+    (uid, uid_name, is_dm) = lookup_uid_from_fingerprint(changes["fingerprint"])
     if uid_name == None:
         uid_name = ""
 
@@ -1017,8 +1017,8 @@ def check_signed_by_key():
         may_nmu, may_sponsor = 1, 1
         # XXX by default new dds don't have a fingerprint/uid in the db atm,
         #     and can't get one in there if we don't allow nmu/sponsorship
-    elif uid[:3] == "dm:":
-        uid_email = uid[3:]
+    elif is_dm is "t":
+        uid_email = uid
         may_nmu, may_sponsor = 0, 0
     else:
         uid_email = "%s@debian.org" % (uid)
@@ -1043,25 +1043,28 @@ def check_signed_by_key():
 
     if not sponsored and not may_nmu:
         source_ids = []
-        check_suites = changes["distribution"].keys()
-        if "unstable" not in check_suites: check_suites.append("unstable")
-        for suite in check_suites:
-            suite_id = database.get_suite_id(suite)
-            q = Upload.projectB.query("SELECT s.id FROM source s JOIN src_associations sa ON (s.id = sa.source) WHERE s.source = '%s' AND sa.suite = %d" % (changes["source"], suite_id))
-            for si in q.getresult():
-                if si[0] not in source_ids: source_ids.append(si[0])
-
-        is_nmu = 1
-        for si in source_ids:
-            is_nmu = 1
-            q = Upload.projectB.query("SELECT m.name FROM maintainer m WHERE m.id IN (SELECT maintainer FROM src_uploaders WHERE src_uploaders.source = %s)" % (si))
+        q = Upload.projectB.query("SELECT s.id, s.version FROM source s JOIN src_associations sa ON (s.id = sa.source) WHERE s.source = '%s' AND s.dm_upload_allowed = 'yes'" % (changes["source"]))
+
+        highest_sid, highest_version = None, None
+
+        should_reject = True
+        for si in q.getresult():
+            if highest_version == None or apt_pkg.VersionCompare(si[1], highest_version) == 1:
+                 highest_sid = si[0]
+                 highest_version = si[1]
+
+        if highest_sid == None:
+           reject("Source package %s does not have 'DM-Upload-Allowed: yes' in its most recent version" % changes["source"])
+        else:
+            q = Upload.projectB.query("SELECT m.name FROM maintainer m WHERE m.id IN (SELECT su.maintainer FROM src_uploaders su JOIN source s ON (s.id = su.source) WHERE su.source = %s)" % (highest_sid))
             for m in q.getresult():
                 (rfc822, rfc2047, name, email) = utils.fix_maintainer(m[0])
                 if email == uid_email or name == uid_name:
-                    is_nmu=0
+                    should_reject=False
                     break
-        if is_nmu:
-            reject("%s may not upload/NMU source package %s" % (uid, changes["source"]))
+
+        if should_reject == True:
+            reject("%s is not in Maintainer or Uploaders of source package %s" % (uid, changes["source"]))
 
         for b in changes["binary"].keys():
             for suite in changes["distribution"].keys():
@@ -1300,14 +1303,14 @@ def is_stableupdate ():
 
 def do_stableupdate (summary, short_summary):
     print "Moving to PROPOSED-UPDATES holding area."
-    Logger.log(["Moving to proposed-updates", pkg.changes_file]);
+    Logger.log(["Moving to proposed-updates", pkg.changes_file])
 
-    Upload.dump_vars(Cnf["Dir::Queue::ProposedUpdates"]);
+    Upload.dump_vars(Cnf["Dir::Queue::ProposedUpdates"])
     move_to_dir(Cnf["Dir::Queue::ProposedUpdates"], perms=0664)
 
     # Check for override disparities
-    Upload.Subst["__SUMMARY__"] = summary;
-    Upload.check_override();
+    Upload.Subst["__SUMMARY__"] = summary
+    Upload.check_override()
 
 ################################################################################
 
@@ -1329,14 +1332,14 @@ def is_oldstableupdate ():
 
 def do_oldstableupdate (summary, short_summary):
     print "Moving to OLDSTABLE-PROPOSED-UPDATES holding area."
-    Logger.log(["Moving to oldstable-proposed-updates", pkg.changes_file]);
+    Logger.log(["Moving to oldstable-proposed-updates", pkg.changes_file])
 
-    Upload.dump_vars(Cnf["Dir::Queue::OldProposedUpdates"]);
+    Upload.dump_vars(Cnf["Dir::Queue::OldProposedUpdates"])
     move_to_dir(Cnf["Dir::Queue::OldProposedUpdates"], perms=0664)
 
     # Check for override disparities
-    Upload.Subst["__SUMMARY__"] = summary;
-    Upload.check_override();
+    Upload.Subst["__SUMMARY__"] = summary
+    Upload.check_override()
 
 ################################################################################
 
index 9e73d1c3e5b26a4773f07727560492bd31764dfa..29d0788124082c672d84eebebca86670d2a8608d 100755 (executable)
@@ -351,6 +351,7 @@ def process_changes_files(changes_files, type, log):
         changeby = {}
         changedby=""
         sponsor=""
+        filename=i[1]["list"][0]["filename"]
         last_modified = time.time()-i[1]["oldest"]
         source = i[1]["list"][0]["source"]
         if len(source) > max_source_len:
@@ -400,7 +401,7 @@ def process_changes_files(changes_files, type, log):
             note = " | [N]"
         else:
             note = ""
-        entries.append([source, version_list, arch_list, note, last_modified, maint, distribution, closes, fingerprint, sponsor, changedby])
+        entries.append([source, version_list, arch_list, note, last_modified, maint, distribution, closes, fingerprint, sponsor, changedby, filename])
 
     # direction entry consists of "Which field, which direction, time-consider" where
     # time-consider says how we should treat last_modified. Thats all.
@@ -442,7 +443,7 @@ def process_changes_files(changes_files, type, log):
     if Cnf.has_key("Queue-Report::Options::822"):
         # print stuff out in 822 format
         for entry in entries:
-            (source, version_list, arch_list, note, last_modified, maint, distribution, closes, fingerprint, sponsor, changedby) = entry
+            (source, version_list, arch_list, note, last_modified, maint, distribution, closes, fingerprint, sponsor, changedby, changes_file) = entry
 
             # We'll always have Source, Version, Arch, Mantainer, and Dist
             # For the rest, check to see if we have them, then print them out
@@ -471,6 +472,7 @@ def process_changes_files(changes_files, type, log):
                 for bugs in closes:
                     bug_string += "#"+bugs+", "
                 log.write("Closes: " + bug_string[:-2] + "\n")
+            log.write("Changes-File: " + os.path.basename(changes_file) + "\n")
             log.write("\n")
 
     if Cnf.has_key("Queue-Report::Options::New"):
@@ -483,7 +485,7 @@ def process_changes_files(changes_files, type, log):
             source_count = len(per_source_items)
             table_header(type.upper(), source_count, total_count)
             for entry in entries:
-                (source, version_list, arch_list, note, last_modified, maint, distribution, closes, fingerprint, sponsor, changedby) = entry
+                (source, version_list, arch_list, note, last_modified, maint, distribution, closes, fingerprint, sponsor, changedby, undef) = entry
                 table_row(source, version_list, arch_list, time_pp(last_modified), maint, distribution, closes, fingerprint, sponsor, changedby)
             table_footer(type.upper())
     elif not Cnf.has_key("Queue-Report::Options::822"):
@@ -492,7 +494,7 @@ def process_changes_files(changes_files, type, log):
 
         msg = ""
         for entry in entries:
-            (source, version_list, arch_list, note, last_modified, undef, undef, undef, undef, undef, undef) = entry
+            (source, version_list, arch_list, note, last_modified, undef, undef, undef, undef, undef, undef, undef) = entry
             msg += format % (source, version_list, arch_list, note, time_pp(last_modified))
 
         if msg:
index a61db174bd076bfc65bd817d3d5c9fc1595f002b..4510ee0e4747bed24c843d5f4ae4cbac6fb297ed 100755 (executable)
@@ -123,12 +123,12 @@ def reject (reject_message = ""):
     # If we weren't given a manual rejection message, spawn an editor
     # so the user can add one in...
     if not reject_message:
-        temp_filename = utils.temp_filename()
+        (fd, temp_filename) = utils.temp_filename()
         editor = os.environ.get("EDITOR","vi")
         answer = 'E'
         while answer == 'E':
             os.system("%s %s" % (editor, temp_filename))
-            f = utils.open_file(temp_filename)
+            f = os.fdopen(fd)
             reject_message = "".join(f.readlines())
             f.close()
             print "Reject message:"
index 350cd1ead94be0812d498dc1551f6066632c899b..c2c5fa4827be337d3170f754029d044e3a8162e9 100755 (executable)
--- a/dak/rm.py
+++ b/dak/rm.py
@@ -113,7 +113,7 @@ def reverse_depends_check(removals, suites, arches=None):
         for component in components:
             filename = "%s/dists/%s/%s/binary-%s/Packages.gz" % (Cnf["Dir::Root"], suites[0], component, architecture)
             # apt_pkg.ParseTagFile needs a real file handle and can't handle a GzipFile instance...
-            temp_filename = utils.temp_filename()
+            (fd, temp_filename) = utils.temp_filename()
             (result, output) = commands.getstatusoutput("gunzip -c %s > %s" % (filename, temp_filename))
             if (result != 0):
                 utils.fubar("Gunzip invocation failed!\n%s\n" % (output), result)
@@ -198,7 +198,7 @@ def reverse_depends_check(removals, suites, arches=None):
     for component in components:
         filename = "%s/dists/%s/%s/source/Sources.gz" % (Cnf["Dir::Root"], suites[0], component)
         # apt_pkg.ParseTagFile needs a real file handle and can't handle a GzipFile instance...
-        temp_filename = utils.temp_filename()
+        (fd, temp_filename) = utils.temp_filename()
         result, output = commands.getstatusoutput("gunzip -c %s > %s" % (filename, temp_filename))
         if result != 0:
             sys.stderr.write("Gunzip invocation failed!\n%s\n" % (output))
@@ -425,7 +425,7 @@ def main ():
     # If we don't have a reason; spawn an editor so the user can add one
     # Write the rejection email out as the <foo>.reason file
     if not Options["Reason"] and not Options["No-Action"]:
-        temp_filename = utils.temp_filename()
+        (fd, temp_filename) = utils.temp_filename()
         editor = os.environ.get("EDITOR","vi")
         result = os.system("%s %s" % (editor, temp_filename))
         if result != 0:
index 4b485f2669ad7e0a642ff2d3712809f5a7b4b79f..f650f9aa03aae6271eee09fb6f8c42c6c296f603 100755 (executable)
@@ -147,7 +147,7 @@ def do_pkg(changes_file):
     changes = Upload.pkg.changes
 
     changes["suite"] = copy.copy(changes["distribution"])
-
+    distribution = changes["distribution"].keys()[0]
     # Find out what's new
     new = queue.determine_new(changes, files, projectB, 0)
 
@@ -169,12 +169,12 @@ def do_pkg(changes_file):
         html_header(changes["source"], filestoexamine)
 
         queue.check_valid(new)
-        examine_package.display_changes(Upload.pkg.changes_file)
+        examine_package.display_changes( distribution, Upload.pkg.changes_file)
 
         for fn in filter(lambda fn: fn.endswith(".dsc"), filestoexamine):
-            examine_package.check_dsc(fn)
+            examine_package.check_dsc(distribution, fn)
         for fn in filter(lambda fn: fn.endswith(".deb") or fn.endswith(".udeb"), filestoexamine):
-            examine_package.check_deb(fn)
+            examine_package.check_deb(distribution, fn)
 
         html_footer()
         if sys.stdout != stdout_fd:
diff --git a/dak/update_db.py b/dak/update_db.py
new file mode 100755 (executable)
index 0000000..d4aefe2
--- /dev/null
@@ -0,0 +1,184 @@
+#!/usr/bin/env python
+
+# Debian Archive Kit Database Update Script
+# Copyright (C) 2008  Michael Casadevall <mcasadevall@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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+
+################################################################################
+
+# <Ganneff> when do you have it written?
+# <NCommander> Ganneff, after you make my debian account
+# <Ganneff> blackmail wont work
+# <NCommander> damn it
+
+################################################################################
+
+import psycopg2, sys, fcntl, os
+import apt_pkg
+import time
+import errno
+from daklib import database
+from daklib import utils
+
+################################################################################
+
+Cnf = None
+projectB = None
+required_database_schema = 3
+
+################################################################################
+
+class UpdateDB:
+    def usage (self, exit_code=0):
+        print """Usage: dak update-db
+Updates dak's database schema to the lastest version. You should disable crontabs while this is running
+
+  -h, --help                show this help and exit."""
+        sys.exit(exit_code)
+
+
+################################################################################
+
+    def update_db_to_zero(self):
+        # This function will attempt to update a pre-zero database schema to zero
+
+        # First, do the sure thing, and create the configuration table
+        try:
+            print "Creating configuration table ..."
+            c = self.db.cursor()
+            c.execute("""CREATE TABLE config (
+                                  id SERIAL PRIMARY KEY NOT NULL,
+                                  name TEXT UNIQUE NOT NULL,
+                                  value TEXT
+                                );""")
+            c.execute("INSERT INTO config VALUES ( nextval('config_id_seq'), 'db_revision', '0')")
+            self.db.commit()
+
+        except psycopg2.ProgrammingError:
+            self.db.rollback()
+            print "Failed to create configuration table."
+            print "Can the projectB user CREATE TABLE?"
+            print ""
+            print "Aborting update."
+            sys.exit(-255)
+
+################################################################################
+
+    def get_db_rev(self):
+        global projectB
+
+        # We keep database revision info the config table
+        # Try and access it
+
+        try:
+            c = self.db.cursor()
+            q = c.execute("SELECT value FROM config WHERE name = 'db_revision';")
+            return c.fetchone()[0]
+
+        except psycopg2.ProgrammingError:
+            # Whoops .. no config table ...
+            self.db.rollback()
+            print "No configuration table found, assuming dak database revision to be pre-zero"
+            return -1
+
+################################################################################
+
+    def update_db(self):
+        # Ok, try and find the configuration table
+        print "Determining dak database revision ..."
+
+        try:
+            # Build a connect string
+            connect_str = "dbname=%s"% (Cnf["DB::Name"])
+            if Cnf["DB::Host"] != '': connect_str += " host=%s" % (Cnf["DB::Host"])
+            if Cnf["DB::Port"] != '-1': connect_str += " port=%d" % (int(Cnf["DB::Port"]))
+
+            self.db = psycopg2.connect(connect_str)
+
+        except:
+            print "FATAL: Failed connect to database"
+            pass
+
+        database_revision = int(self.get_db_rev())
+
+        if database_revision == -1:
+            print "dak database schema predates update-db."
+            print ""
+            print "This script will attempt to upgrade it to the lastest, but may fail."
+            print "Please make sure you have a database backup handy. If you don't, press Ctrl-C now!"
+            print ""
+            print "Continuing in five seconds ..."
+            time.sleep(5)
+            print ""
+            print "Attempting to upgrade pre-zero database to zero"
+
+            self.update_db_to_zero()
+            database_revision = 0
+
+        print "dak database schema at " + str(database_revision)
+        print "dak version requires schema " + str(required_database_schema)
+
+        if database_revision == required_database_schema:
+            print "no updates required"
+            sys.exit(0)
+
+        for i in range (database_revision, required_database_schema):
+            print "updating databse schema from " + str(database_revision) + " to " + str(i+1)
+            dakdb = __import__("dakdb", globals(), locals(), ['update'+str(i+1)])
+            update_module = getattr(dakdb, "update"+str(i+1))
+            update_module.do_update(self)
+            database_revision += 1
+
+################################################################################
+
+    def init (self):
+        global Cnf, projectB
+
+        Cnf = utils.get_conf()
+        arguments = [('h', "help", "Update-DB::Options::Help")]
+        for i in [ "help" ]:
+            if not Cnf.has_key("Update-DB::Options::%s" % (i)):
+                Cnf["Update-DB::Options::%s" % (i)] = ""
+
+        arguments = apt_pkg.ParseCommandLine(Cnf, arguments, sys.argv)
+
+        options = Cnf.SubTree("Update-DB::Options")
+        if options["Help"]:
+            self.usage()
+        elif arguments:
+            utils.warn("dak update-db takes no arguments.")
+            self.usage(exit_code=1)
+
+
+        self.update_db()
+
+        try:
+            lock_fd = os.open(Cnf["Dinstall::LockFile"], os.O_RDWR | os.O_CREAT)
+            fcntl.lockf(lock_fd, fcntl.LOCK_EX | fcntl.LOCK_NB)
+        except IOError, e:
+            if errno.errorcode[e.errno] == 'EACCES' or errno.errorcode[e.errno] == 'EAGAIN':
+                utils.fubar("Couldn't obtain lock; assuming another 'dak process-unchecked' is already running.")
+
+
+################################################################################
+
+if __name__ == '__main__':
+    app = UpdateDB()
+    app.init()
+
+def main():
+    app = UpdateDB()
+    app.init()
index 4e795461532e6b6284057b5a961ac88d329c83be..9404ee9e71138ceb8c18bf51547cdf98ce25c6f6 100644 (file)
@@ -29,6 +29,7 @@ class DakError(Exception):
     """
 
     def __init__(self, message=""):
+        Exception.__init__(self)
         self.args = str(message)
         self.message = str(message)
 
index 5c7bd8387240b328073b6641817afaa21aa8c768..e2c596a6feb89bf3d9fc367b11f71268fedca7ac 100755 (executable)
@@ -19,7 +19,9 @@
 
 ################################################################################
 
-import sys, time, types
+import sys
+import time
+import types
 
 ################################################################################
 
@@ -46,6 +48,7 @@ suite_version_cache = {}
 ################################################################################
 
 def init (config, sql):
+    """ database module init. Just sets two variables"""
     global Cnf, projectB
 
     Cnf = config
@@ -53,6 +56,11 @@ def init (config, sql):
 
 
 def do_query(q):
+    """
+    Executes a database query q. Writes statistics to stderr and returns
+    the result.
+
+    """
     sys.stderr.write("query: \"%s\" ... " % (q))
     before = time.time()
     r = projectB.query(q)
@@ -69,6 +77,7 @@ def do_query(q):
 ################################################################################
 
 def get_suite_id (suite):
+    """ Returns database suite_id for given suite, caches result. """
     global suite_id_cache
 
     if suite_id_cache.has_key(suite):
@@ -85,6 +94,7 @@ def get_suite_id (suite):
     return suite_id
 
 def get_section_id (section):
+    """ Returns database section_id for given section, caches result. """
     global section_id_cache
 
     if section_id_cache.has_key(section):
@@ -101,6 +111,7 @@ def get_section_id (section):
     return section_id
 
 def get_priority_id (priority):
+    """ Returns database priority_id for given priority, caches result. """
     global priority_id_cache
 
     if priority_id_cache.has_key(priority):
@@ -117,6 +128,7 @@ def get_priority_id (priority):
     return priority_id
 
 def get_override_type_id (type):
+    """ Returns database override_id for given override_type type, caches result. """
     global override_type_id_cache
 
     if override_type_id_cache.has_key(type):
@@ -133,6 +145,7 @@ def get_override_type_id (type):
     return override_type_id
 
 def get_architecture_id (architecture):
+    """ Returns database architecture_id for given architecture, caches result. """
     global architecture_id_cache
 
     if architecture_id_cache.has_key(architecture):
@@ -149,6 +162,7 @@ def get_architecture_id (architecture):
     return architecture_id
 
 def get_archive_id (archive):
+    """ Returns database archive_id for given archive, caches result. """
     global archive_id_cache
 
     archive = archive.lower()
@@ -167,6 +181,7 @@ def get_archive_id (archive):
     return archive_id
 
 def get_component_id (component):
+    """ Returns database component_id for given component, caches result. """
     global component_id_cache
 
     component = component.lower()
@@ -185,6 +200,18 @@ def get_component_id (component):
     return component_id
 
 def get_location_id (location, component, archive):
+    """
+    Returns database location_id for given combination of
+    location
+    component
+    archive.
+
+    The 3 parameters are the database ids returned by the respective
+    "get_foo_id" functions.
+
+    The result will be cached.
+
+    """
     global location_id_cache
 
     cache_key = location + '_' + component + '_' + location
@@ -208,6 +235,7 @@ def get_location_id (location, component, archive):
     return location_id
 
 def get_source_id (source, version):
+    """ Returns database source_id for given combination of source and version, caches result. """
     global source_id_cache
 
     cache_key = source + '_' + version + '_'
@@ -225,6 +253,7 @@ def get_source_id (source, version):
     return source_id
 
 def get_suite_version(source, suite):
+    """ Returns database version for a given source in a given suite, caches result. """
     global suite_version_cache
     cache_key = "%s_%s" % (source, suite)
 
@@ -250,6 +279,14 @@ def get_suite_version(source, suite):
 ################################################################################
 
 def get_or_set_maintainer_id (maintainer):
+    """
+    If maintainer does not have an entry in the maintainer table yet, create one
+    and return its id.
+    If maintainer already has an entry, simply return its id.
+
+    Result is cached.
+
+    """
     global maintainer_id_cache
 
     if maintainer_id_cache.has_key(maintainer):
@@ -267,6 +304,14 @@ def get_or_set_maintainer_id (maintainer):
 ################################################################################
 
 def get_or_set_keyring_id (keyring):
+    """
+    If keyring does not have an entry in the keyring table yet, create one
+    and return its id.
+    If keyring already has an entry, simply return its id.
+
+    Result is cached.
+
+    """
     global keyring_id_cache
 
     if keyring_id_cache.has_key(keyring):
@@ -284,6 +329,14 @@ def get_or_set_keyring_id (keyring):
 ################################################################################
 
 def get_or_set_uid_id (uid):
+    """
+    If uid does not have an entry in the uid table yet, create one
+    and return its id.
+    If uid already has an entry, simply return its id.
+
+    Result is cached.
+
+    """
     global uid_id_cache
 
     if uid_id_cache.has_key(uid):
@@ -301,6 +354,14 @@ def get_or_set_uid_id (uid):
 ################################################################################
 
 def get_or_set_fingerprint_id (fingerprint):
+    """
+    If fingerprintd does not have an entry in the fingerprint table yet, create one
+    and return its id.
+    If fingerprint already has an entry, simply return its id.
+
+    Result is cached.
+
+    """
     global fingerprint_id_cache
 
     if fingerprint_id_cache.has_key(fingerprint):
@@ -318,6 +379,25 @@ def get_or_set_fingerprint_id (fingerprint):
 ################################################################################
 
 def get_files_id (filename, size, md5sum, location_id):
+    """
+    Returns -1, -2 or the file_id for a given combination of
+    filename
+    size
+    md5sum
+    location_id.
+
+    The database is queried using filename and location_id, size and md5sum are for
+    extra checks.
+
+    Return values:
+    -1 - The given combination of arguments result in more (or less) than
+         one result from the database
+    -2 - The given size and md5sum do not match the values in the database
+    anything else is a file_id
+
+    Result is cached.
+
+    """
     global files_id_cache
 
     cache_key = "%s_%d" % (filename, location_id)
@@ -344,6 +424,14 @@ def get_files_id (filename, size, md5sum, location_id):
 ################################################################################
 
 def get_or_set_queue_id (queue):
+    """
+    If queue does not have an entry in the queue_name table yet, create one
+    and return its id.
+    If queue already has an entry, simply return its id.
+
+    Result is cached.
+
+    """
     global queue_id_cache
 
     if queue_id_cache.has_key(queue):
@@ -361,6 +449,12 @@ def get_or_set_queue_id (queue):
 ################################################################################
 
 def set_files_id (filename, size, md5sum, sha1sum, sha256sum, location_id):
+    """
+    Insert a new entry into the files table.
+
+    Returns the new file_id
+
+    """
     global files_id_cache
 
     projectB.query("INSERT INTO files (filename, size, md5sum, sha1sum, sha256sum, location) VALUES ('%s', %d, '%s', '%s', '%s', %d)" % (filename, long(size), md5sum, sha1sum, sha256sum, location_id))
@@ -380,6 +474,7 @@ def set_files_id (filename, size, md5sum, sha1sum, sha256sum, location_id):
 ################################################################################
 
 def get_maintainer (maintainer_id):
+    """ Return the name of the maintainer behind maintainer_id """
     global maintainer_cache
 
     if not maintainer_cache.has_key(maintainer_id):
@@ -391,9 +486,27 @@ def get_maintainer (maintainer_id):
 ################################################################################
 
 def get_suites(pkgname, src=False):
+    """ Return the suites in which pkgname is. If src is True, query for source package, else binary. """
     if src:
-        sql = "select suite_name from source, src_associations,suite where source.id=src_associations.source and source.source='%s' and src_associations.suite = suite.id"%pkgname
+        sql = """
+        SELECT suite_name
+        FROM source,
+             src_associations,
+             suite
+        WHERE source.id = src_associations.source
+        AND   source.source = '%s'
+        AND   src_associations.suite = suite.id
+        """ % (pkgname)
     else:
-        sql = "select suite_name from binaries, bin_associations,suite where binaries.id=bin_associations.bin and  package='%s' and bin_associations.suite = suite.id"%pkgname
+        sql = """
+        SELECT suite_name
+        FROM binaries,
+             bin_associations,
+             suite
+        WHERE binaries.id = bin_associations.bin
+        AND   package = '%s'
+        AND   bin_associations.suite = suite.id
+        """ % (pkgname)
+
     q = projectB.query(sql)
     return map(lambda x: x[0], q.getresult())
index 1fcfeaaf2e172e2761ddb06726245229c8ab4214..d7e813a972ff362a853f42f581ac99c6ac3f7ced 100755 (executable)
@@ -156,6 +156,7 @@ class Upload:
         self.Cnf = Cnf
         self.accept_count = 0
         self.accept_bytes = 0L
+        self.reject_message = ""
         self.pkg = Pkg(changes = {}, dsc = {}, dsc_files = {}, files = {},
                        legacy_source_untouchable = {})
 
@@ -344,7 +345,7 @@ class Upload:
         if not changes.has_key("distribution") or not isinstance(changes["distribution"], DictType):
             changes["distribution"] = {}
 
-        override_summary ="";
+        override_summary =""
         file_keys = files.keys()
         file_keys.sort()
         for file_entry in file_keys:
@@ -499,19 +500,18 @@ distribution."""
             if changes["architecture"].has_key("source") and \
                dsc.has_key("bts changelog"):
 
-                temp_filename = utils.temp_filename(Cnf["Dir::Queue::BTSVersionTrack"],
-                                                    dotprefix=1, perms=0644)
-                version_history = utils.open_file(temp_filename, 'w')
+                (fd, temp_filename) = utils.temp_filename(Cnf["Dir::Queue::BTSVersionTrack"], prefix=".")
+                version_history = os.fdopen(fd, 'w')
                 version_history.write(dsc["bts changelog"])
                 version_history.close()
                 filename = "%s/%s" % (Cnf["Dir::Queue::BTSVersionTrack"],
                                       changes_file[:-8]+".versions")
                 os.rename(temp_filename, filename)
+                os.chmod(filename, 0644)
 
             # Write out the binary -> source mapping.
-            temp_filename = utils.temp_filename(Cnf["Dir::Queue::BTSVersionTrack"],
-                                                dotprefix=1, perms=0644)
-            debinfo = utils.open_file(temp_filename, 'w')
+            (fd, temp_filename) = utils.temp_filename(Cnf["Dir::Queue::BTSVersionTrack"], prefix=".")
+            debinfo = os.fdopen(fd, 'w')
             for file_entry in file_keys:
                 f = files[file_entry]
                 if f["type"] == "deb":
@@ -523,6 +523,7 @@ distribution."""
             filename = "%s/%s" % (Cnf["Dir::Queue::BTSVersionTrack"],
                                   changes_file[:-8]+".debinfo")
             os.rename(temp_filename, filename)
+            os.chmod(filename, 0644)
 
         self.queue_build("accepted", Cnf["Dir::Queue::Accepted"])
 
@@ -670,7 +671,7 @@ distribution."""
         # If we weren't given a manual rejection message, spawn an
         # editor so the user can add one in...
         if manual and not reject_message:
-            temp_filename = utils.temp_filename()
+            (fd, temp_filename) = utils.temp_filename()
             editor = os.environ.get("EDITOR","vi")
             answer = 'E'
             while answer == 'E':
@@ -1032,7 +1033,8 @@ SELECT s.version, su.suite_name FROM source s, src_associations sa, suite su
                     # for example, the package was in potato but had an -sa
                     # upload in woody.  So we need to choose the right one.
 
-                    x = ql[0]; # default to something sane in case we don't match any or have only one
+                    # default to something sane in case we don't match any or have only one
+                    x = ql[0]
 
                     if len(ql) > 1:
                         for i in ql:
@@ -1053,7 +1055,8 @@ SELECT s.version, su.suite_name FROM source s, src_associations sa, suite su
                     actual_size = os.stat(old_file)[stat.ST_SIZE]
                     found = old_file
                     suite_type = x[2]
-                    dsc_files[dsc_file]["files id"] = x[3]; # need this for updating dsc_files in install()
+                    # need this for updating dsc_files in install()
+                    dsc_files[dsc_file]["files id"] = x[3]
                     # See install() in process-accepted...
                     self.pkg.orig_tar_id = x[3]
                     self.pkg.orig_tar_gz = old_file
index 47c80f3c137975468569f7b8cb354688448edfce..9e26e9e7f07c707a79b5ca08ef5f3f1661007f59 100755 (executable)
@@ -26,6 +26,7 @@ import codecs, commands, email.Header, os, pwd, re, select, socket, shutil, \
        sys, tempfile, traceback, stat
 import apt_pkg
 import database
+import time
 from dak_exceptions import *
 
 ################################################################################
@@ -397,25 +398,24 @@ def parse_checksums(where, files, manifest, hashname):
     field = 'checksums-%s' % hashname
     if not field in manifest:
         return rejmsg
-    input = manifest[field]
-    for line in input.split('\n'):
+    for line in manifest[field].split('\n'):
         if not line:
             break
-        hash, size, file = line.strip().split(' ')
-        if not files.has_key(file):
+        checksum, size, checkfile = line.strip().split(' ')
+        if not files.has_key(checkfile):
         # TODO: check for the file's entry in the original files dict, not
         # the one modified by (auto)byhand and other weird stuff
         #    rejmsg.append("%s: not present in files but in checksums-%s in %s" %
         #        (file, hashname, where))
             continue
-        if not files[file]["size"] == size:
+        if not files[checkfile]["size"] == size:
             rejmsg.append("%s: size differs for files and checksums-%s entry "\
-                "in %s" % (file, hashname, where))
+                "in %s" % (checkfile, hashname, where))
             continue
-        files[file][hash_key(hashname)] = hash
+        files[checkfile][hash_key(hashname)] = checksum
     for f in files.keys():
         if not files[f].has_key(hash_key(hashname)):
-            rejmsg.append("%s: no entry in checksums-%s in %s" % (file,
+            rejmsg.append("%s: no entry in checksums-%s in %s" % (checkfile,
                 hashname, where))
     return rejmsg
 
@@ -569,8 +569,7 @@ switched to 'email (name)' format."""
 def send_mail (message, filename=""):
         # If we've been passed a string dump it into a temporary file
     if message:
-        filename = tempfile.mktemp()
-        fd = os.open(filename, os.O_RDWR|os.O_CREAT|os.O_EXCL, 0700)
+        (fd, filename) = tempfile.mkstemp()
         os.write (fd, message)
         os.close (fd)
 
@@ -686,11 +685,11 @@ def regex_safe (s):
 
 # Perform a substition of template
 def TemplateSubst(map, filename):
-    file = open_file(filename)
-    template = file.read()
+    templatefile = open_file(filename)
+    template = templatefile.read()
     for x in map.keys():
         template = template.replace(x,map[x])
-    file.close()
+    templatefile.close()
     return template
 
 ################################################################################
@@ -786,13 +785,13 @@ def find_next_free (dest, too_many=100):
 ################################################################################
 
 def result_join (original, sep = '\t'):
-    list = []
+    resultlist = []
     for i in xrange(len(original)):
         if original[i] == None:
-            list.append("")
+            resultlist.append("")
         else:
-            list.append(original[i])
-    return sep.join(list)
+            resultlist.append(original[i])
+    return sep.join(resultlist)
 
 ################################################################################
 
@@ -1119,7 +1118,7 @@ on error."""
         return "%s: tainted filename" % (filename)
 
     # Invoke gpgv on the file
-    status_read, status_write = os.pipe();
+    status_read, status_write = os.pipe()
     cmd = "gpgv --status-fd %s --keyring /dev/null %s" % (status_write, filename)
     (_, status, _) = gpgv_get_status_output(cmd, status_read, status_write)
 
@@ -1191,7 +1190,7 @@ used."""
             return None
 
     # Build the command line
-    status_read, status_write = os.pipe();
+    status_read, status_write = os.pipe()
     cmd = "gpgv --status-fd %s %s %s %s" % (
         status_write, gpg_keyring_args(keyrings), sig_filename, data_filename)
 
@@ -1231,11 +1230,22 @@ used."""
     if keywords.has_key("NODATA"):
         reject("no signature found in %s." % (sig_filename))
         bad = 1
+    if keywords.has_key("EXPKEYSIG"):
+        args = keywords["EXPKEYSIG"]
+        if len(args) >= 1:
+            key = args[0]
+        reject("Signature made by expired key 0x%s" % (key))
+        bad = 1
     if keywords.has_key("KEYEXPIRED") and not keywords.has_key("GOODSIG"):
         args = keywords["KEYEXPIRED"]
+        expiredate=""
         if len(args) >= 1:
-            key = args[0]
-        reject("The key (0x%s) used to sign %s has expired." % (key, sig_filename))
+            timestamp = args[0]
+            if timestamp.count("T") == 0:
+                expiredate = time.strftime("%Y-%m-%d", time.gmtime(timestamp))
+            else:
+                expiredate = timestamp
+        reject("The key used to sign %s has expired on %s" % (sig_filename, expiredate))
         bad = 1
 
     if bad:
@@ -1348,26 +1358,16 @@ def clean_symlink (src, dest, root):
 
 ################################################################################
 
-def temp_filename(directory=None, dotprefix=None, perms=0700):
+def temp_filename(directory=None, prefix="dak", suffix=""):
     """Return a secure and unique filename by pre-creating it.
 If 'directory' is non-null, it will be the directory the file is pre-created in.
-If 'dotprefix' is non-null, the filename will be prefixed with a '.'."""
+If 'prefix' is non-null, the filename will be prefixed with it, default is dak.
+If 'suffix' is non-null, the filename will end with it.
 
-    if directory:
-        old_tempdir = tempfile.tempdir
-        tempfile.tempdir = directory
-
-    filename = tempfile.mktemp()
-
-    if dotprefix:
-        filename = "%s/.%s" % (os.path.dirname(filename), os.path.basename(filename))
-    fd = os.open(filename, os.O_RDWR|os.O_CREAT|os.O_EXCL, perms)
-    os.close(fd)
-
-    if directory:
-        tempfile.tempdir = old_tempdir
+Returns a pair (fd, name).
+"""
 
-    return filename
+    return tempfile.mkstemp(suffix, prefix, directory)
 
 ################################################################################
 
index a410f703e5a9365dfe2fbd160695ea0f886f70d3..da7ddd4497692fdd9cc38c89c1ead96694cb2687 100755 (executable)
@@ -41,7 +41,7 @@ echo "Authorised upload by $ID, copying into place"
 OUT=$(mktemp)
 
 cp "$BYHAND" "$DESTKR"
-dak import-keyring --generate-users "dm:%s" "$DESTKR" >$OUT
+dak import-keyring --generate-users "%s" "$DESTKR" >$OUT
 
 if [ -s "$OUT" ]; then
   /usr/sbin/sendmail -odq -oi -t <<EOF
index 87846b7009325efdbdf260f8fa9258f498953c6d..93e36472cf8e243f519b9c48dd7bd1f4481aa6a0 100755 (executable)
@@ -5,7 +5,7 @@ echo "Known debian maintainers:"
 psql --html projectb <<EOF
   SELECT uid.uid, uid.name, f.fingerprint
     FROM uid LEFT OUTER JOIN fingerprint f ON (uid.id = f.uid) 
-   WHERE uid.uid LIKE 'dm:%'
+   WHERE uid.uid LIKE '%@%'
 ORDER BY uid.uid;
 EOF
 
@@ -23,7 +23,7 @@ psql --html projectb <<EOF
                      JOIN uid u ON 
                       (m.name LIKE u.name || ' <%>' OR
                        m.name LIKE '% <' || substring(u.uid FROM 4) || '>')
-               WHERE u.uid LIKE 'dm:%' AND sa.suite = 5
+               WHERE u.uid LIKE '%@%' AND sa.suite = 5
          )
 ORDER BY uid.uid;
 EOF
@@ -31,13 +31,13 @@ EOF
 echo "Packages debian maintainers may update:"
 
 psql --html projectb <<EOF
-  SELECT s.source, s.version, u.uid
+  SELECT s.source, space_separated_list(s.version), u.uid
     FROM src_uploaders su JOIN source s ON (su.source = s.id) 
          JOIN src_associations sa ON (s.id = sa.source)
          JOIN maintainer m ON (su.maintainer = m.id)
          JOIN uid u ON (m.name LIKE u.name || ' <%>' OR
-                       m.name LIKE '% <' || substring(u.uid FROM 4) || '>')
-   WHERE u.uid LIKE 'dm:%' AND sa.suite = 5
+                m.name LIKE '% <' || substring(u.uid FROM 4) || '>')
+   WHERE s.dm_upload_allowed = 't' GROUP BY s.source, s.version, u.uid
 ORDER BY u.uid, s.source, s.version;
 EOF
 
@@ -47,7 +47,7 @@ psql --html projectb <<EOF
   SELECT s.source, s.version, s.install_date, u.uid
     FROM source s JOIN fingerprint f ON (s.sig_fpr = f.id) 
          JOIN uid u ON (f.uid = u.id)
-   WHERE u.uid LIKE 'dm:%'
+   WHERE u.uid LIKE '%@%'
 ORDER BY u.uid, s.source, s.version;
 EOF
 
@@ -58,7 +58,7 @@ psql --html projectb <<EOF
     FROM binaries b JOIN architecture a ON (b.architecture = a.id)
          JOIN fingerprint f ON (b.sig_fpr = f.id) 
          JOIN uid u ON (f.uid = u.id)
-   WHERE u.uid LIKE 'dm:%'
+   WHERE u.uid LIKE '%@%'
 ORDER BY u.uid, b.package, b.version;
 EOF
 
diff --git a/scripts/debian/moveftp.sh b/scripts/debian/moveftp.sh
new file mode 100755 (executable)
index 0000000..6aecc28
--- /dev/null
@@ -0,0 +1,9 @@
+#!/bin/bash
+
+set -e
+set -u
+
+FTPDIR="/org/upload.debian.org/ftp/pub/UploadQueue/"
+SSHDIR="/org/upload.debian.org/UploadQueue/"
+
+yes n | find ${FTPDIR} -type f -mmin +15 -print0 -exec mv -i --target-directory=${SSHDIR} "{}" +
diff --git a/src/Makefile b/src/Makefile
deleted file mode 100644 (file)
index b45b07d..0000000
+++ /dev/null
@@ -1,17 +0,0 @@
-#!/usr/bin/make -f
-
-CXXFLAGS       = -I/usr/include/postgresql/ -I/usr/include/postgresql/server/ -fPIC -Wall
-CFLAGS         = -fPIC -Wall
-LDFLAGS                = -fPIC
-LIBS           = -lapt-pkg
-
-C++            = g++
-
-all: sql-aptvc.so
-
-sql-aptvc.o: sql-aptvc.cpp
-sql-aptvc.so: sql-aptvc.o
-       $(CC) $(LDFLAGS) $(LIBS) -shared -o $@ $<
-clean:
-       rm -f sql-aptvc.so sql-aptvc.o
-
diff --git a/src/sql-aptvc.cpp b/src/sql-aptvc.cpp
deleted file mode 100644 (file)
index 54ba9e9..0000000
+++ /dev/null
@@ -1,56 +0,0 @@
-/* Wrapper round apt's version compare functions for PostgreSQL. */
-/* Copyright (C) 2001, James Troup <james@nocrew.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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA 
- */
-
-/* NB: do not try to use the VERSION-1 calling conventions for
-   C-Language functions; it works on i386 but segfaults the postgres
-   child backend on Sparc. */
-
-#include <apt-pkg/debversion.h>
-
-extern "C"
-{
-
-#include <postgres.h>
-
-  int versioncmp(text *A, text *B);
-
-  int
-  versioncmp (text *A, text *B)
-  {
-    int result, txt_size;
-    char *a, *b;
-
-    txt_size = VARSIZE(A)-VARHDRSZ;
-    a = (char *) palloc(txt_size+1);
-    memcpy(a, VARDATA(A), txt_size);
-    a[txt_size] = '\0';
-
-    txt_size = VARSIZE(B)-VARHDRSZ;
-    b = (char *) palloc(txt_size+1);
-    memcpy(b, VARDATA(B), txt_size);
-    b[txt_size] = '\0';
-
-    result = debVS.CmpVersion (a, b);
-
-    pfree (a);
-    pfree (b);
-
-    return (result);
-  }
-
-}
index 353d3ccb31104c426817c4f58d11dae640f3c850..725938d3e370b3f89ea227b9def5b9386da9920c 100644 (file)
@@ -34,6 +34,8 @@ was superseded by another one.
 Thank you for reporting the bug, which will now be closed.  If you
 have further comments please address them to __BUG_NUMBER__@__BUG_SERVER__.
 
+The full log for this bug can be viewed at http://__BUG_SERVER__/__BUG_NUMBER__
+
 This message was generated automatically; if you believe that there is
 a problem with it please contact the archive administrators by mailing
 __ADMIN_ADDRESS__.
index ec65f15c0519daa21527973f5adbecfdb5f741d5..b07845bf0c122d1e04b75b4d5070313ddae7a68d 100755 (executable)
@@ -55,14 +55,14 @@ $rss->channel(
                                         }
                         );
 
-for (0..15) {
-  my $i = $_;
+my $num_to_display = 16;
+for my $removal (@removals ) {
   my ($null, $date, $ftpmaster, $body, $reason);
-  $removals[$i] =~ s/=========================================================================//g;
-  $removals[$i] =~ m/\[Date: ([^]]+)\] \[ftpmaster: ([^]]+)\]/;
+  $removal =~ s/=========================================================================//g;
+  $removal =~ m/\[Date: ([^]]+)\] \[ftpmaster: ([^]]+)\]/;
   $date = $1;
   $ftpmaster = $2;
-  ($null, $body) = split /\n/, $removals[$i], 2;
+  ($null, $body) = split /\n/, $removal, 2;
   chomp $body;
   $body =~ m/---- Reason ---.*\n(.*)/;
   $reason = $1;
@@ -77,5 +77,7 @@ for (0..15) {
                                           }
                                );
 
+  $num_to_display -= 1;
+  last unless $num_to_display;
 }
 print $rss->as_string;
index 2d0f967fa9d9d94a85add71ab7adfa49c208a747..b919b185645d55d0f82964385730574d8ee60ac3 100644 (file)
@@ -23,8 +23,8 @@ dinstall.setUTCSeconds(00);
 function countdown()
 {
     var now = new Date();
-    var rest = Math.floor((dinstall - now)/1000) % 43200;
-    if(now>dinstall) rest+=43200;
+    var rest = Math.floor((dinstall - now)/1000) % 21600;
+    if(now>dinstall) rest+=21600;
     
     stunden = Math.floor(rest/3600);
     if (stunden < 10) stunden = "0" + stunden;
@@ -45,12 +45,13 @@ setInterval('countdown()',1000);
 
 <br><br>
 
-dinstall should run 07h 52min and 19h 52min or 07h 52min AM/PM (UTC)
+dinstall should run 4 times a day at 01:52, 07:52, 13:52, 19:52 (all times in UTC).
 
 <br><br>
 <font size="-2">Made by Eduard Bloch &lt;blade@debian.org&gt;
 <br>Small update to use 12h dinstall by Felipe Augusto van de Wiel (faw)
-<br>Please check this <a href="http://lists.debian.org/debian-cd/2006/11/msg00049.html">announcement</a> about dinstall twice daily.
+<br>Small update to use 6h dinstall by Mike O'Connor (stew)
+<br>Please check this <a href="http://lists.debian.org/debian-project/2008/12/msg00114.html">announcement</a> about dinstall every 6 hours.
 
 </BODY>