From: Colin Watson
Date: Sun, 18 Aug 2002 02:05:11 +0000 (+0000)
Subject: Initial import of $HOME/bin.
X-Git-Url: https://www.chiark.greenend.org.uk/ucgi/~cjwatson/git?a=commitdiff_plain;h=88c7e302a60194f68bc1b6d20c1547b62e1436d3;p=bin.git
Initial import of $HOME/bin.
---
88c7e302a60194f68bc1b6d20c1547b62e1436d3
diff --git a/6to4 b/6to4
new file mode 100644
index 0000000..6a2765b
--- /dev/null
+++ b/6to4
@@ -0,0 +1,42 @@
+#!/bin/bash -e
+
+VERBOSE=1
+LOCAL_IF=ppp0
+
+case "$1" in
+ start)
+ if [ -z "$LOCAL4" ]; then
+ [ "$LOCAL_IF" ] || LOCAL_IF=ppp0
+ LOCAL4=$(ip -o addr show $LOCAL_IF | awk '/inet/ { print $4 }')
+ if [ -z "$LOCAL4" ]; then
+ echo "Cannot find the IP assigned to $LOCAL_IF"
+ exit 1
+ fi
+ fi
+
+ LOCAL6=$(printf "%x%02x:%x%02x\n" $(echo $LOCAL4 | sed -e 's/\./ /g'))
+ LOCAL6="2002:$LOCAL6::1/48"
+
+ [ "$RELAY" ] || RELAY=192.88.99.1
+
+ if [ "$VERBOSE" ]; then
+ echo "Local v4 address: $LOCAL4"
+ echo "Local v6 address: $LOCAL6"
+ echo "6to4 Relay address: $RELAY"
+ fi
+
+ ip link set sit0 up
+ ip addr add $LOCAL6 dev sit0
+ ip route add 2000::/3 via ::$RELAY
+ ;;
+ stop)
+ ip link set sit0 down
+ ;;
+ *)
+ echo "Usage: $0 {start|stop}"
+ exit 1
+ ;;
+esac
+
+exit 0
+
diff --git a/Pnews-wrapper b/Pnews-wrapper
new file mode 100644
index 0000000..e2c1265
--- /dev/null
+++ b/Pnews-wrapper
@@ -0,0 +1,30 @@
+#! /bin/sh
+
+if grep '^Newsgroups:.*alt\.fan\.eddings\.creative' $2; then
+ get-sig afec > ~/.news_sig
+elif grep '^Newsgroups:.*alt\.fan\.eddings' $2; then
+ get-sig afe > ~/.news_sig
+else
+ get-sig general > ~/.news_sig
+fi
+
+if grep '^Newsgroups:.*riva.lists' $2; then
+ cat < /dev/null; then
+ echo ""
+ echo -n "Remove original poster's .signature (if present)? [yn] "
+ read ans
+ case $ans in
+ n*) ;;
+ *) sed -n -e "/^\($QUOTECHARS\)\?-- \$/q" -e p $2 | sponge $2
+ ;;
+ esac
+fi
+
+exec Pnews "$@"
diff --git a/Rnmail-wrapper b/Rnmail-wrapper
new file mode 100644
index 0000000..3fca7d6
--- /dev/null
+++ b/Rnmail-wrapper
@@ -0,0 +1,20 @@
+#! /bin/sh
+
+if grep '^From:.*Kamion' $2; then
+ get-sig afe > ~/.mail_sig
+else
+ get-sig general > ~/.mail_sig
+fi
+
+if [ "X$1" = X-h ] && grep '^In-Reply-To: ' $2 > /dev/null; then
+ echo ""
+ echo -n "Remove original poster's .signature (if present)? [yn] "
+ read ans
+ case $ans in
+ n*) ;;
+ *) sed -n -e "/^$QUOTECHARS-- \$/q" -e p $2 | sponge $2
+ ;;
+ esac
+fi
+
+exec /usr/bin/Rnmail "$@"
diff --git a/afe-stats b/afe-stats
new file mode 100644
index 0000000..669ff97
--- /dev/null
+++ b/afe-stats
@@ -0,0 +1,2 @@
+#! /bin/sh
+statnews --from=`date -d '1 week ago' +%d/%m/%Y` --nocapitalize alt.fan.eddings
diff --git a/afec-faq b/afec-faq
new file mode 100644
index 0000000..a234904
--- /dev/null
+++ b/afec-faq
@@ -0,0 +1,5 @@
+#! /bin/sh
+
+# Post the alt.fan.eddings.creative FAQ every fortnight
+cd $HOME/afe/daemons
+$HOME/bin/crondiv 2 afec-faq.log inews -hS afec-faq.txt
diff --git a/afeweb-backup b/afeweb-backup
new file mode 100644
index 0000000..d836c52
--- /dev/null
+++ b/afeweb-backup
@@ -0,0 +1,40 @@
+#! /bin/sh
+
+YEARTHISWEEK=`date +%Y-w%V`
+YEARLASTWEEK=`date -d '1 week ago' +%Y-w%V`
+DAY=`date +%w | sed 's/0/7/'`
+
+LABDIR=/tmp/afeweb.$YEARTHISWEEK-$DAY
+if [ $DAY -eq 1 ]; then
+ OLDTAR=$HOME/backups/afeweb-$YEARLASTWEEK.tar.gz
+ NEWTAR=$HOME/backups/afeweb-$YEARTHISWEEK.tar.gz
+else
+ OLDTAR=$HOME/backups/afeweb-$YEARTHISWEEK.tar.gz
+ unset NEWTAR
+fi
+DIFFGZ=$HOME/backups/afeweb-$YEARTHISWEEK-$DAY.diff.gz
+TOPDIR=tolhoneth
+SOURCEPARENT=/var/www
+SOURCEDIR=tolhoneth
+
+if [ -f $OLDTAR ]; then
+ # Extract old tarball and set up diffing environment
+ mkdir $LABDIR
+ cd $LABDIR
+ tar xzf $OLDTAR
+ mv $TOPDIR $TOPDIR.orig
+ ln -s $SOURCEPARENT/$SOURCEDIR $TOPDIR
+
+ # Do the diff and clean up
+ diff -Naru $TOPDIR.orig $TOPDIR | gzip > $DIFFGZ
+ cd -
+ rm -rf $LABDIR
+fi
+
+if [ "$NEWTAR" ]; then
+ # First day of the week, so build a new tarball
+ cd $SOURCEPARENT
+ tar czf $NEWTAR $SOURCEDIR
+ cd -
+fi
+
diff --git a/alarm-clock b/alarm-clock
new file mode 100644
index 0000000..c1a9d21
--- /dev/null
+++ b/alarm-clock
@@ -0,0 +1,6 @@
+#! /bin/sh
+mpg123 -q /home/cjwatson/mp3/OMWF---01---*.mp3
+mpg123 -q /home/cjwatson/mp3/OMWF---02---*.mp3
+mpg123 -q /home/cjwatson/mp3/OMWF---03---*.mp3
+mpg123 -q /home/cjwatson/mp3/OMWF---13---*.mp3
+mpg123 -q /home/cjwatson/mp3/OMWF---14---*.mp3
diff --git a/archive-news.pl b/archive-news.pl
new file mode 100644
index 0000000..4f6f44b
--- /dev/null
+++ b/archive-news.pl
@@ -0,0 +1,62 @@
+#! /usr/bin/perl -w
+use diagnostics;
+use strict;
+
+use Net::NNTP;
+
+my $nntp;
+
+sub usage ()
+{
+ print STDERR <<"EOF";
+Usage: $0 hostname newsgroup-name archive-directory
+EOF
+ exit 1;
+}
+
+sub bail ($)
+{
+ my $msg = shift;
+ $nntp->quit;
+ print STDERR "$msg\n";
+ exit 1;
+}
+
+my $host = shift or usage;
+my $group = shift or usage;
+my $archive = shift or usage;
+-d $archive or usage;
+
+opendir ARCHIVE, $archive or die "can't opendir $archive: $!";
+my @list = grep m/^\d+$/, readdir ARCHIVE;
+closedir ARCHIVE;
+
+@list = sort { $a <=> $b } @list;
+my $start = scalar @list ? $list[$#list] + 1 : 0;
+
+$nntp = Net::NNTP->new($host);
+# Bah, password in clear, oh well, it's only passworded to keep the
+# howling masses out anyway ...
+#$nntp->authinfo('afe', 'MyTest');
+
+my ($narticles, $first, $last, $name) = $nntp->group($group);
+(defined $first and defined $last) or bail "Couldn't set group to $group";
+
+exit if $last <= $start;
+$start = $first if $first > $start;
+
+for my $index ($start..$last)
+{
+ my $article = $nntp->article($index);
+ if (defined $article)
+ {
+ open ARTICLE, ">$archive/$index"
+ or die "can't open $archive/$index for writing: $!";
+ print ARTICLE join '', @$article;
+ close ARTICLE;
+ }
+ #print STDERR "$group $index\n";
+}
+
+$nntp->quit;
+
diff --git a/authstartx b/authstartx
new file mode 100644
index 0000000..2a2929e
--- /dev/null
+++ b/authstartx
@@ -0,0 +1,9 @@
+#!/bin/sh
+set -e
+if [ -n "$XAUTHORITY" ]; then
+ export XAUTHORITY=$HOME/.Xauthority
+fi
+auth=`mcookie`
+xauth add :0 . $auth
+xauth add `hostname -f`:0 . $auth
+startx -- :0 -auth $XAUTHORITY
diff --git a/backupnewsrc b/backupnewsrc
new file mode 100644
index 0000000..3e04579
--- /dev/null
+++ b/backupnewsrc
@@ -0,0 +1,2 @@
+#! /bin/sh
+cp ~/.newsrc ~/.newsrc-backup
diff --git a/build-sig b/build-sig
new file mode 100644
index 0000000..3e46ad9
--- /dev/null
+++ b/build-sig
@@ -0,0 +1,8 @@
+#!/bin/sh
+
+for s in $(find ~/.signatures -mindepth 2 -path '*/old/*' -prune -o \
+ -type f ! -name '*.dat' ! -name static -print | \
+ sort); do
+ strfile $s
+done | perl -ne \
+ '$s += $1 if /There.*?([0-9]+)/; print; END { print "Total: $s\n"; }'
diff --git a/buildd-logs b/buildd-logs
new file mode 100644
index 0000000..001e353
--- /dev/null
+++ b/buildd-logs
@@ -0,0 +1,8 @@
+#! /bin/sh
+set -e
+
+if [ -z "$1" ]; then
+ ${BROWSER:-lynx} http://buildd.debian.org/build.php
+else
+ ${BROWSER:-lynx} "http://buildd.debian.org/build.php?pkg=$1"
+fi
diff --git a/cancel-this b/cancel-this
new file mode 100644
index 0000000..1009b35
--- /dev/null
+++ b/cancel-this
@@ -0,0 +1,7 @@
+#! /bin/sh
+
+MSGID=`grep -i '^Message-ID: ' | sed 's/^Message-ID: //' | head -1`
+
+echo 'Locally cancelling a post with the following Message-ID:'
+echo " $MSGID"
+[ "$1" = "test" ] || ctlinnd cancel "$MSGID"
diff --git a/catylog.pl b/catylog.pl
new file mode 100644
index 0000000..61e1861
--- /dev/null
+++ b/catylog.pl
@@ -0,0 +1,2 @@
+#! /usr/bin/perl -p
+s/(?:^|.)\xfe// while /\xfe/;
diff --git a/check-characters.pl b/check-characters.pl
new file mode 100644
index 0000000..eed4859
--- /dev/null
+++ b/check-characters.pl
@@ -0,0 +1,16 @@
+#! /usr/bin/perl -w
+use diagnostics;
+use strict;
+
+local $/ = undef;
+my $file = <>;
+while ($file =~ /(.*?)<\/A>/gs)
+{
+ if ($1 ne $2 || "$2$3" ne lc $4)
+ {
+ my $name = $4;
+ $name =~ y/\n/ /;
+ print "$name\n";
+ }
+}
+
diff --git a/command-args b/command-args
new file mode 100644
index 0000000..32fc111
--- /dev/null
+++ b/command-args
@@ -0,0 +1,15 @@
+#! /bin/bash
+
+echo $COMP_CWORD
+
+if [ "$COMP_CWORD" = 1 ]; then
+ compgen -c $2
+else
+ case ${2:0:1} in
+ $) compgen -v $2;;
+ ~) compgen -u $2;;
+ @) compgen -A hostname $2;;
+ *) compgen -f $2;;
+ esac
+fi
+
diff --git a/countafe b/countafe
new file mode 100644
index 0000000..b2ea8a9
--- /dev/null
+++ b/countafe
@@ -0,0 +1,3 @@
+#! /bin/sh -e
+echo -n "$* "
+grep -c "$*" afe-posters
diff --git a/crondiv b/crondiv
new file mode 100644
index 0000000..666171c
--- /dev/null
+++ b/crondiv
@@ -0,0 +1,28 @@
+#! /bin/bash
+
+# "Divide" a crontab frequency down by the first argument on the command line,
+# logging to the second argument, and executing the remainder.
+
+if [ "X$1" = "X" -o "X$2" = "X" -o "X$3" = "X" ]; then
+ echo "Usage: $0 frequency logfile command [ arguments ]" >&2
+ exit 1
+fi
+
+FREQUENCY=$1
+LOGFILE=$2
+shift 2
+
+if [ -f $LOGFILE ]; then
+ LASTEXEC=$(($(tail -n 1 $LOGFILE)+1))
+else
+ LASTEXEC=1
+fi
+
+if [ $LASTEXEC -ge $FREQUENCY ]; then
+ echo "$*" executed at $(date) >> $LOGFILE
+ echo 0 >> $LOGFILE
+ eval "$*"
+else
+ echo $LASTEXEC >> $LOGFILE
+fi
+
diff --git a/dctrl-mailbox.pl b/dctrl-mailbox.pl
new file mode 100644
index 0000000..c5c65d7
--- /dev/null
+++ b/dctrl-mailbox.pl
@@ -0,0 +1,36 @@
+#! /usr/bin/perl -w
+use diagnostics;
+use strict;
+use Date::Format;
+
+my $fromdate = time2str("%a %b %e %T %Y %z", time, 'GMT');
+my $headerdate = time2str("%a, %e %b %Y %T %z", time, 'GMT');
+
+local $/ = "\n\n";
+
+while (<>)
+{
+ /^Package: (.*)/m;
+ my $package = $1;
+ /^Section: (.*)/m;
+ my $section = $1;
+ $section =~ s|/|.|g;
+ /^Maintainer: (.*)/m;
+ my $maintainer = $1;
+ $maintainer =~ /<(.*)>/;
+ my $maintaddr = $1;
+ /^Description: (.*)/m;
+ my $shortdesc = $1;
+ s/^ (.*)//ms;
+ my $longdesc = $1;
+ $longdesc =~ s/^ //gm;
+ $longdesc =~ s/^\.$//gm;
+ $_ = "From $maintaddr $fromdate\n" .
+ "From: $maintainer\n" .
+ "Date: $headerdate\n" .
+ "Subject: $package - $shortdesc\n" .
+ "Newsgroups: $section\n" .
+ "$_\n$longdesc";
+ print $_;
+}
+
diff --git a/debian-mirror b/debian-mirror
new file mode 100644
index 0000000..58e4678
--- /dev/null
+++ b/debian-mirror
@@ -0,0 +1,153 @@
+#!/bin/sh -e
+# Anon rsync partial mirror of Debian with package pool support.
+# Copyright 1999, 2000 by Joey Hess , GPL'd.
+# Beaten on by Colin Watson .
+
+# Flags to pass to rsync. More can be specified on the command line.
+# These flags are always passed to rsync:
+FLAGS="$@ -rLpt --partial"
+# These flags are not passed in when we are getting files from pools.
+# In particular, --delete is a horrid idea at that point, but good here.
+FLAGS_NOPOOL="$FLAGS --exclude Packages --delete"
+# And these flags are passed in only when we are getting files from pools.
+# Remember, do _not_ include --delete.
+FLAGS_POOL="$FLAGS"
+# The host to connect to. Currently must carry both non-us and main
+# and support anon rsync, which limits the options somewhat.
+HOST=ftp.uk.debian.org
+# Where to put the mirror (absolute path, please):
+DEST=/mirror/debian
+# The distribution to mirror:
+DIST=unstable
+# Architecture to mirror:
+ARCH=i386
+# Should source be mirrored too?
+SOURCE=yes
+# The sections to mirror (main, non-free, etc):
+SECTIONS="main contrib non-free"
+# Should a contents file kept up to date?
+CONTENTS=yes
+# Should symlinks be generated to every deb, in an "all" directory?
+# I find this is very handy to ease looking up deb filenames.
+SYMLINK_FARM=no
+
+###############################################################################
+
+mkdir -p $DEST/dists $DEST/pool $DEST/non-US/pool
+
+# Snarf the contents file.
+if [ "$CONTENTS" = yes ]; then
+ mkdir -p $DEST/misc
+ rsync $FLAGS_NOPOOL \
+ $HOST::debian/dists/$DIST/Contents-${ARCH}.gz \
+ $DEST/misc/
+fi
+
+if [ "$SOURCE" = yes ]; then
+ SOURCE=source
+else
+ SOURCE=""
+fi
+
+# Download packages files (and .debs and sources too, until we move fully
+# to pools).
+for type in binary-${ARCH} $SOURCE; do
+ for section in $SECTIONS; do
+ mkdir -p $DEST/non-US/dists/$DIST/non-US/$section/$type
+ rsync $FLAGS_NOPOOL \
+ $HOST::debian/non-US/dists/$DIST/non-US/$section/$type \
+ $DEST/non-US/dists/$DIST/non-US/$section/
+ mkdir -p $DEST/dists/$DIST/$section/$type
+ rsync $FLAGS_NOPOOL \
+ $HOST::debian/dists/$DIST/$section/$type \
+ $DEST/dists/$DIST/$section/
+ done
+done
+
+# Update the non-US package pool.
+# TODO: probably needs to be optimized, we'll see as time goes by..
+cd $DEST/non-US/pool || exit 1
+rm -f .filelist
+
+# Get a list of all the files that are in the pool based on the Packages
+# files that were already updated. Thanks to aj for the awk-fu.
+for file in `find $DEST/non-US -name Packages.gz | \
+ xargs -r zgrep -i ^Filename: | cut -d ' ' -f 2 | grep ^pool/` \
+ `find $DEST/non-US -name Sources.gz | xargs -r zcat | \
+ awk '/^Directory:/ {D=$2} /Files:/,/^$/ { \
+ if ($1 != "Files:" && $0 != "") print D "/" $3; \
+ }' | grep ^pool/`
+do
+ DIRS="`dirname $file` $DIRS"
+ echo $file >> .filelist
+done
+
+# Remove leading "pool" from all files in the file list.
+# The "./" we change it to is there so the file names
+# exactly match in the delete step and the files that get downloaded
+# are not deleted.
+sed 's!^pool/!./!' .filelist > .filelist.new
+mv -f .filelist.new .filelist
+
+(cd .. && mkdir -p $DIRS)
+# Tell rsync to download only the files in the list. The exclude is here
+# to make the recursion not get anything else.
+# TODO: main pool needs to be donwloaded from too, once there is one.
+rsync $FLAGS_POOL \
+ $HOST::debian/non-US/pool/ --include-from .filelist --exclude '*' .
+echo non-US pool rsynced
+exit 0
+# Delete all files that are not in the list, then any empty directories.
+# This also kills the filelist.
+find -type f | fgrep -vxf .filelist | xargs -r rm -f
+find -type d -empty | xargs -r rmdir -p --ignore-fail-on-non-empty
+# End of non-US package pool update.
+
+# Update the package pool.
+# TODO: probably needs to be optimized, we'll see as time goes by..
+cd $DEST/pool || exit 1
+rm -f .filelist
+
+# Get a list of all the files that are in the pool based on the Packages
+# files that were already updated. Thanks to aj for the awk-fu.
+for file in `find $DEST -name non-US -prune -o -name Packages.gz | \
+ xargs -r zgrep -i ^Filename: | cut -d ' ' -f 2 | grep ^pool/` \
+ `find $DEST -name non-US -prune -o -name Sources.gz | \
+ xargs -r zcat | \
+ awk '/^Directory:/ {D=$2} /Files:/,/^$/ { \
+ if ($1 != "Files:" && $0 != "") print D "/" $3; \
+ }' | grep ^pool/`
+do
+ DIRS="`dirname $file` $DIRS"
+ echo $file >> .filelist
+done
+
+# Remove leading "pool" from all files in the file list.
+# The "./" we change it to is there so the file names
+# exactly match in the delete step and the files that get downloaded
+# are not deleted.
+sed 's!^pool/!./!' .filelist > .filelist.new
+mv -f .filelist.new .filelist
+
+(cd .. && mkdir -p $DIRS)
+# Tell rsync to download only the files in the list. The exclude is here
+# to make the recursion not get anything else.
+# TODO: main pool needs to be donwloaded from too, once there is one.
+rsync $FLAGS_POOL \
+ $HOST::debian/pool/ --include-from .filelist --exclude '*' .
+# Delete all files that are not in the list, then any empty directories.
+# This also kills the filelist.
+find -type f | fgrep -vxf .filelist | xargs -r rm -f
+find -type d -empty | xargs -r rmdir -p --ignore-fail-on-non-empty
+# End of package pool update.
+
+# Update symlinks (I like to have a link to every .deb in one directory).
+if [ "$SYMLINK_FARM" = yes ]; then
+ install -d $DEST/all
+ cd $DEST/all || exit 1
+ find -name \*.deb | xargs -r rm -f
+ find .. -name "*.deb" -type f | grep -v ^../all | \
+ xargs -r -i ln -sf {} .
+fi
+
+# Waste bandwidth. Put a partial mirror on your laptop today!
diff --git a/deja-check-votes b/deja-check-votes
new file mode 100644
index 0000000..c8e3c50
--- /dev/null
+++ b/deja-check-votes
@@ -0,0 +1,8 @@
+#! /bin/sh
+
+for x in `cat $1`; do
+ dejasearch -format classic -max 1 ~a $x;
+ if [ ! -s summary.html ]; then
+ echo $x >> possible-fraud
+ fi
+done
diff --git a/desymlink b/desymlink
new file mode 100644
index 0000000..a1a40ee
--- /dev/null
+++ b/desymlink
@@ -0,0 +1,16 @@
+#! /usr/bin/perl -w
+use strict;
+
+for (@ARGV) {
+ my $source = $_;
+ next unless -l $source;
+ my $target = readlink $source or die "readlink: $!";
+ my $trap = sub { unlink $source;
+ symlink $target, $source;
+ print "Caught a SIG$_[0]!\n";
+ exit; };
+ local ($SIG{HUP}, $SIG{INT}, $SIG{TERM}, $SIG{QUIT}, $SIG{__DIE__}) =
+ ($trap, $trap, $trap, $trap, $trap);
+ unlink $source;
+ system '/bin/cp', $target, $source;
+}
diff --git a/dinstall-private b/dinstall-private
new file mode 100644
index 0000000..7b0c879
--- /dev/null
+++ b/dinstall-private
@@ -0,0 +1,120 @@
+#! /bin/sh
+# The name is a deliberate echo of the "real" Debian dinstall; it moves
+# packages into /usr/src/debian, removes any old versions of those packages
+# there, and re-runs dpkg-myscan {packages,sources}.
+
+if [ $# -lt 2 ]; then
+ echo "Usage: $0 package-name version-number" >&2
+ exit 1
+fi
+
+PACKAGE=$1
+VERSION=$2
+UPSTREAM=`echo $VERSION | sed -e 's/-[^-]*$//'`
+
+echo -n "Dinstalling package $PACKAGE, "
+echo -n "version $VERSION, "
+echo "upstream version $UPSTREAM"
+
+ARCH=i386
+DEB=$PWD/${PACKAGE}_${VERSION}_${ARCH}.deb
+ORIG=$PWD/${PACKAGE}_$UPSTREAM.orig.tar.gz
+DIFF=$PWD/${PACKAGE}_${VERSION}.diff.gz
+DSC=$PWD/${PACKAGE}_${VERSION}.dsc
+CHANGES=$PWD/${PACKAGE}_${VERSION}_${ARCH}.changes
+
+# Sanity checks
+
+ERROR=
+if [ ! -f $DEB ]; then echo $DEB 'not found' >&2; ERROR=1; fi
+if [ ! -f $ORIG ]; then echo $ORIG 'not found' >&2; ERROR=1; fi
+if [ ! -f $DIFF ]; then echo $DIFF 'not found' >&2; ERROR=1; fi
+if [ ! -f $DSC ]; then echo $DSC 'not found' >&2; ERROR=1; fi
+if [ ! -f $CHANGES ]; then echo $CHANGES 'not found' >&2; ERROR=1; fi
+[ "$ERROR" ] && exit 1
+
+SECTION=`dpkg -f $DEB Section`
+if [ "$SECTION" ]; then
+ echo "Section: $SECTION"
+else
+ echo "Section not found." >&2
+ exit 1
+fi
+
+if echo $SECTION | egrep -q '^(contrib|non-free)/'; then
+ BINARYDIR=`echo $SECTION | sed -e "s|/|/binary-$ARCH/|"`
+ SOURCEDIR=`echo $SECTION | sed -e "s|/|/source/|"`
+elif echo $SECTION | egrep -q '^non-US/'; then
+ BINARYDIR=$SECTION/binary-$ARCH
+ SOURCEDIR=$SECTION/source
+else
+ BINARYDIR=main/binary-$ARCH/$SECTION
+ SOURCEDIR=main/source/$SECTION
+fi
+
+echo "Binaries in $BINARYDIR, sources in $SOURCEDIR"
+
+cd /usr/src/debian/dists/unstable
+
+ERROR=
+if [ ! -d $BINARYDIR ]; then echo 'Binary dir not found.' >&2; ERROR=1; fi
+if [ ! -d $SOURCEDIR ]; then echo 'Source dir not found.' >&2; ERROR=1; fi
+[ "$ERROR" ] && exit 1
+
+shopt -s nullglob
+
+BINARIES=`echo $BINARYDIR/${PACKAGE}_*`
+if [ "$BINARIES" ]; then
+ echo 'Binaries found in binary dir:'
+ echo $BINARIES | xargs -n1
+ read -n1 -esp 'Remove: (y/N) ' REMOVE
+ if [ "$REMOVE" == y ]; then
+ echo -n 'Removing ... '
+ echo $BINARIES | xargs rm
+ echo 'done.'
+ else
+ echo 'Aborting.'
+ exit
+ fi
+fi
+
+SOURCES=`echo $SOURCEDIR/${PACKAGE}_*`
+if [ "$SOURCES" ]; then
+ echo 'Sources found in source dir:'
+ echo $SOURCES | xargs -n1
+ read -n1 -esp 'Remove: (y/N) ' REMOVE
+ if [ "$REMOVE" == y ]; then
+ echo -n 'Removing ... '
+ echo $SOURCES | xargs rm
+ echo 'done.'
+ else
+ echo 'Aborting.'
+ exit
+ fi
+fi
+
+echo "Moving $DEB to $BINARYDIR ..."
+mv -f $DEB $BINARYDIR
+echo "Copying $ORIG to $SOURCEDIR ..."
+cp -f $ORIG $SOURCEDIR
+echo "Copying $DIFF to $SOURCEDIR ..."
+cp -f $DIFF $SOURCEDIR
+echo "Moving $DSC to $SOURCEDIR ..."
+mv -f $DSC $SOURCEDIR
+echo "Moving $CHANGES to $SOURCEDIR ..."
+mv -f $CHANGES $SOURCEDIR
+
+echo
+
+cd ../..
+
+dpkg-myscan packages
+
+echo
+
+dpkg-myscan sources
+
+echo
+
+echo "Dinstallation of $PACKAGE-$VERSION complete."
+
diff --git a/dinstall-riva b/dinstall-riva
new file mode 100644
index 0000000..86a9f91
--- /dev/null
+++ b/dinstall-riva
@@ -0,0 +1,157 @@
+#! /bin/sh
+# The name is a deliberate echo of the "real" Debian dinstall; it moves
+# packages into http://riva.ucam.org/~cjw44/debian/, removes any old versions
+# of those packages there, and re-runs dpkg-myscan {packages,sources}.
+
+if [ $# -lt 2 ]; then
+ echo "Usage: $0 package-name version-number" >&2
+ exit 1
+fi
+
+PACKAGE=$1
+VERSION=$2
+UPSTREAM=`echo $VERSION | sed -e 's/-[^-]*$//'`
+NATIVE=
+if [ "$VERSION" = "$UPSTREAM" ]; then
+ NATIVE=y
+fi
+
+echo -n "Dinstalling package $PACKAGE, "
+echo -n "version $VERSION, "
+echo "upstream version $UPSTREAM"
+[ "$NATIVE" ] && echo "Native Debian package"
+
+ARCH=i386
+BINARCH=i386
+DEB=$PWD/${PACKAGE}_${VERSION}_${BINARCH}.deb
+if [ ! -f $DEB ]; then
+ BINARCH=all
+ ALLDEB=$PWD/${PACKAGE}_${VERSION}_${BINARCH}.deb
+else
+ ALLDEB=$DEB
+fi
+if [ "$NATIVE" ]; then
+ ORIG=$PWD/${PACKAGE}_${VERSION}.tar.gz
+ DIFF=
+else
+ ORIG=$PWD/${PACKAGE}_${UPSTREAM}.orig.tar.gz
+ DIFF=$PWD/${PACKAGE}_${VERSION}.diff.gz
+fi
+DSC=$PWD/${PACKAGE}_${VERSION}.dsc
+CHANGES=$PWD/${PACKAGE}_${VERSION}_${ARCH}.changes
+
+# Sanity checks
+
+ERROR=
+if [ ! -f $DEB -a ! -f $ALLDEB ]; then
+ echo $DEB 'not found' >&2
+ [ $BINARCH = all ] && echo $ALLDEB 'not found' >&2
+ ERROR=1
+fi
+DEB=$ALLDEB
+if [ ! -f $ORIG ]; then echo $ORIG 'not found' >&2; ERROR=1; fi
+if [ "$DIFF" -a ! -f "$DIFF" ]; then
+ echo $DIFF 'not found' >&2
+ ERROR=1
+fi
+if [ ! -f $DSC ]; then echo $DSC 'not found' >&2; ERROR=1; fi
+if [ ! -f $CHANGES ]; then echo $CHANGES 'not found' >&2; ERROR=1; fi
+[ "$ERROR" ] && exit 1
+
+SECTION=`dpkg -f $DEB Section`
+if [ "$SECTION" ]; then
+ echo "Section: $SECTION"
+else
+ echo "Section not found." >&2
+ exit 1
+fi
+
+if echo $SECTION | egrep -q '^(contrib|non-free)/'; then
+ BINARYDIR=`echo $SECTION | sed -e "s|/|/binary-$BINARCH/|"`
+ SOURCEDIR=`echo $SECTION | sed -e "s|/|/source/|"`
+elif echo $SECTION | egrep -q '^non-US/'; then
+ BINARYDIR=$SECTION/binary-$BINARCH
+ SOURCEDIR=$SECTION/source
+else
+ BINARYDIR=main/binary-$BINARCH/$SECTION
+ SOURCEDIR=main/source/$SECTION
+fi
+
+echo "Binaries in $BINARYDIR, sources in $SOURCEDIR"
+
+cd /home/httpd/users/$USER/debian
+
+ERROR=
+if [ ! -d $BINARYDIR ]; then echo 'Binary dir not found.' >&2; ERROR=1; fi
+if [ ! -d $SOURCEDIR ]; then echo 'Source dir not found.' >&2; ERROR=1; fi
+[ "$ERROR" ] && exit 1
+
+shopt -s nullglob
+
+BINARIES=`echo $BINARYDIR/${PACKAGE}_*`
+if [ "$BINARIES" ]; then
+ echo 'Binaries found in binary dir:'
+ echo $BINARIES | xargs -n1
+ read -n1 -esp 'Remove: (y/N) ' REMOVE
+ if [ "$REMOVE" = y ]; then
+ echo -n 'Removing ... '
+ echo $BINARIES | xargs rm
+ echo 'done.'
+ else
+ echo 'Aborting.'
+ exit
+ fi
+fi
+
+SOURCES=`echo $SOURCEDIR/${PACKAGE}_*`
+if [ "$SOURCES" ]; then
+ echo 'Sources found in source dir:'
+ echo $SOURCES | xargs -n1
+ read -n1 -esp 'Remove: (y/N) ' REMOVE
+ if [ "$REMOVE" = y ]; then
+ echo -n 'Removing ... '
+ echo $SOURCES | xargs rm
+ echo 'done.'
+ else
+ echo 'Aborting.'
+ exit
+ fi
+fi
+
+echo "Moving $DEB to $BINARYDIR ..."
+mv -f $DEB $BINARYDIR
+echo "Copying $ORIG to $SOURCEDIR ..."
+cp -f $ORIG $SOURCEDIR
+if [ "$DIFF" ]; then
+ echo "Copying $DIFF to $SOURCEDIR ..."
+ cp -f $DIFF $SOURCEDIR
+fi
+echo "Moving $DSC to $SOURCEDIR ..."
+mv -f $DSC $SOURCEDIR
+echo "Moving $CHANGES to $SOURCEDIR ..."
+mv -f $CHANGES $SOURCEDIR
+
+echo
+
+dpkg-myscan packages
+
+echo
+
+dpkg-myscan sources
+
+echo
+
+echo -n 'Updating index.html ...'
+if [ "$NATIVE" ]; then
+ perl -pi -l \
+ -e 's/('$PACKAGE'_).*?(_|\.dsc)/${1}'$VERSION'$2/;' \
+ -e 's/('$PACKAGE'_).*?(\.tar\.gz)/${1}'$VERSION'$2/;' index.html
+else
+ perl -pi -l \
+ -e 's/('$PACKAGE'_).*?(_|\.diff\.gz|\.dsc)/${1}'$VERSION'$2/;' \
+ -e 's/('$PACKAGE'_).*?(\.orig\.tar\.gz)/${1}'$UPSTREAM'$2/;' index.html
+fi
+echo ' done.'
+
+echo "Dinstallation of $PACKAGE-$VERSION complete."
+
diff --git a/dpkg-myscan b/dpkg-myscan
new file mode 100644
index 0000000..b9d980a
--- /dev/null
+++ b/dpkg-myscan
@@ -0,0 +1,27 @@
+#! /bin/sh
+
+if [ "$1" = packages -o -z "$1" ]; then
+ type=packages
+ topdir=binary-i386
+ outfile=Packages
+elif [ "$1" = sources ]; then
+ type=sources
+ topdir=source
+ outfile=Sources
+else
+ echo "Usage: $0 packages|sources" >&2
+ exit 1
+fi
+
+echo Searching for $type ...
+
+for x in main non-US/main non-free; do
+ echo Scanning $x ...
+ dir=dists/unstable/$x/$topdir
+ if [ -e $dir ]; then
+ dpkg-scan$type $dir override > $dir/$outfile
+ gzip -c $dir/$outfile > $dir/$outfile.gz
+ else
+ echo $x not found.
+ fi
+done
diff --git a/expandvars.pl b/expandvars.pl
new file mode 100644
index 0000000..a7ea667
--- /dev/null
+++ b/expandvars.pl
@@ -0,0 +1,98 @@
+#! /usr/bin/perl -w
+use diagnostics;
+use strict;
+use Getopt::Long;
+
+sub usage ()
+{
+ print STDERR <<"EOF";
+Usage: $0 [options] source-filename
+EOF
+ print STDERR <<'EOF';
+where options are:
+
+ -h, -?, --help print this message
+ -c, --conf FILENAME use FILENAME as configuration file, default
+ '.headers'
+ -d, --directory DIR change to directory DIR
+ -s, --suffix SUFFIX use SUFFIX for all output filenames, default null
+
+The configuration file is of the following form:
+
+# Comments are preceded by hashes and extend to the end of the line.
+# List of names of parameters to be substituted (as $param1$, $param2$,
+# etc.) in order.
+param1 param2 ...
+
+# Multiple records, one per line.
+# Each record consists of an output filename (automatically used as the value
+# of the name parameter; suffix will be added if present) followed by a list of
+# parameter values. Fields are space-separated. Double quotes (") may be used
+# to delimit fields containing spaces, and double quotes themselves may be
+# escaped with backslashes.
+
+EOF
+ exit;
+}
+
+my %opts = (conf => '.headers', directory => '', suffix => '');
+GetOptions(\%opts, 'help|h|?', 'conf|c=s', 'directory|d=s', 'suffix|s=s');
+my $source = shift;
+usage unless defined $source;
+
+usage if $opts{'help'};
+chdir $opts{'directory'} if $opts{'directory'};
+open CONF, $opts{'conf'} or
+ die "Can't open configuration file " . $opts{'conf'} . ": $!";
+-r $source or die "Can't read source file $source: $!";
+
+my @params;
+while ()
+{
+ next if /^#/ || /^\s+/;
+ @params = split;
+ last;
+}
+
+usage unless defined @params && $#params >= 0;
+
+# Eek. This matches the next (optionally double-quoted) string on the line.
+my $stringre = qr/\s*("(?:[^\\]|\\.)*?"|(?:[^\\]|\\.)+?)(?:\s|$)/;
+while ()
+{
+ next if /^#/ || /^\s+/;
+ my $confline = $_;
+ next unless $confline =~ /$stringre/g;
+ my $target = $1;
+ my %values = (name => $target);
+ my @conffields = ($confline =~ /\G$stringre/g);
+ my $offset = 0;
+ for (my $i = 0; $i + $offset <= $#params && $i <= $#conffields; $i++)
+ {
+ $offset++ while $params[$i + $offset] eq 'name';
+ last if $i + $offset > $#params;
+ my $value = $conffields[$i];
+ $value =~ s/^"(.*)"$/$1/;
+ $value =~ s/\\(.)/$1/g;
+ $values{$params[$i + $offset]} = $value;
+ }
+
+ # Do the substitution in the source file.
+ open SOURCE, $source or die "Can't open source file $source: $!";
+ open TARGET, ">$target" . $opts{'suffix'} or
+ die "Can't open target file $target" . $opts{'suffix'} . ": $!";
+ select TARGET;
+ while ()
+ {
+ foreach my $param (keys %values)
+ {
+ my $value = $values{$param};
+ s/\$\Q$param\E\$/$value/g;
+ }
+ s/\$\$/\$/g;
+ print;
+ }
+ select STDOUT;
+ close TARGET;
+}
+
diff --git a/faq-pointer b/faq-pointer
new file mode 100644
index 0000000..cbd76f3
--- /dev/null
+++ b/faq-pointer
@@ -0,0 +1,5 @@
+#! /bin/sh
+
+# Post the alt.fan.eddings FAQ pointer every six days
+cd $HOME/afe/daemons
+$HOME/bin/crondiv 6 faq-pointer.log inews -hS faq-pointer.txt
diff --git a/faq2html.pl b/faq2html.pl
new file mode 100644
index 0000000..15305de
--- /dev/null
+++ b/faq2html.pl
@@ -0,0 +1,445 @@
+#! /usr/bin/perl -w
+use strict;
+require 5.000;
+use lib qw(.);
+use Style qw(html_header html_footer);
+
+# The AFE FAQ HTMLizer
+# Perl version written by Kamion; based on a sed script by Aquarius
+
+sub usage ()
+{
+ print STDERR <<"EOF";
+Usage: $0 index-filename [up-URL] < faq-document
+
+URLs may be absolute or relative.
+
+EOF
+ exit 1;
+}
+
+sub html_escape (\$)
+{
+ my $line = shift;
+ return unless defined $$line;
+ $$line =~ s/\&/&/g;
+ $$line =~ s/</g;
+ $$line =~ s/>/>/g;
+ $$line =~ s/"/"/g;
+ $$line =~ s/æ/æ/g;
+ return $$line;
+}
+
+#my $sts_link = "http://riva.ucam.org/~kamion/archive-bin/" .
+# "article.pl?msgid=5n0qq5\$d9p\@mercury.dur.ac.uk";
+my $sts_link = 'http://groups.google.com/groups?' .
+ 'q=Easter+Egg&ic=1&selm=5n0qq5%24d9p%40mercury.dur.ac.uk';
+
+# Paragraph to format and undefine, followed optionally by open and close tags.
+sub print_paragraph (\$;$$)
+{
+ my $para = shift;
+ return unless defined $$para && $$para !~ /^\s*$/;
+ my $open_tags = shift;
+ my $close_tags = shift;
+
+ # Make URLs links
+ $$para =~ s#(http:(?:[^\ \&<]|\&(?!gt;))*)
+ #$1#gx;
+
+ # Make all text within pairs of underscores outside URLs emphasized
+ $$para =~ s[_((?:[^_.-])+\.?)_
+ (?![^"]*">|[^<]*)][$1]gx;
+
+ # Similarly, strengthen bold text within asterisks
+ $$para =~ s[\*((?:[^*.])+\.?)\*
+ (?![^"]*">|[^<]*)][$1]gx;
+
+ # Easter egg
+ $$para =~ s|(Sephrenia the Styric)|$1|g;
+
+ $$para = "$open_tags$$para" if defined $open_tags;
+ $$para .= $close_tags if defined $close_tags;
+
+ print "$$para\n";
+ undef $$para;
+}
+
+my $index_file = shift or usage;
+my $up_url = shift;
+
+open CONTROL, ">control.html" or die "Can't write to control.html: $!";
+select CONTROL;
+
+html_header "Revision information", $index_file;
+print "\n";
+
+my $changes_done = 0;
+
+print "\n";
+while (<>)
+{
+ $changes_done = 1 if (/^Archive-name:/);
+ next unless $changes_done;
+ chomp;
+ html_escape $_;
+ last if (/^\s*$/);
+ unless (/^([^:]+:)\s*(.+)$/)
+ {
+ warn "Non-header line found in control section: $_";
+ next;
+ }
+ print "$_\n";
+}
+print "
\n\n";
+
+html_footer $index_file;
+
+open INDEX, ">$index_file" or die "Can't write to $index_file: $!";
+select INDEX;
+
+html_header "Contents", $up_url;
+print "\n";
+
+print "\n";
+while (<>)
+{
+ last if /^\s*$/;
+ html_escape $_;
+ print;
+}
+print "
\n\n";
+
+print "Revision information
\n";
+
+my $paragraph;
+my $listentry = 0;
+my $level = 0;
+my @lastvalues = ();
+
+while (<>)
+{
+ chomp;
+ s/^\s*//;
+ html_escape $_;
+ # Stop at TOC-body separator
+ if (/--------/)
+ {
+ print_paragraph $paragraph, "", $listentry ? "" : "";
+ last;
+ }
+ # Convert headings to links
+ my $line = $_;
+ if ($line =~ /([0-9]+)((?:.[0-9]+)*)[\)\s]/)
+ {
+ my $firstcomp = $1;
+ my $heading = "$1$2";
+ my @components = split /\./, $heading;
+ if (@components > 0)
+ {
+ $line =~ /\s+(.*)$/g;
+ my $linetail = $1;
+ print_paragraph $paragraph, "", $listentry ? "" : "";
+
+ # Change level of ordered list if necessary
+ if (@components > $level)
+ {
+ print "\n" x (@components - $level);
+ }
+ elsif (@components < $level)
+ {
+ print "
\n" x ($level - @components);
+ }
+ #print "
\n\n" if @components == 1 && $level > 0;
+ print "\n
\n\n" if @components == 1 && $level > 0;
+ $level = @components;
+ $#lastvalues = $level;
+ #print "\n" if $level == 1;
+
+ # Reformat the current line
+ my $value = $components[$#components];
+ if (defined $lastvalues[$level] &&
+ $lastvalues[$level] + 1 != $value)
+ {
+ warn "Missing item in contents before $heading";
+ print "
";
+ }
+ elsif ($value != 1)
+ {
+ print "";
+ }
+ else
+ {
+ print "";
+ }
+ $lastvalues[$level] = $value;
+ print "\n";
+ $paragraph = $linetail;
+ $listentry = 1;
+ next;
+ }
+ }
+ elsif (/^[A-Z][^a-z]+$/)
+ {
+ print_paragraph $paragraph, "", $listentry ? "" : "";
+ if ($level == 0)
+ {
+ print "\n$_
\n\n";
+ }
+ else
+ {
+ #print "\n\n";
+ print "\n\n" x ($level - 1);
+ print "\n" if $level == 1;
+ print "$_
\n\n";
+ print "\n" x ($level - 1);
+ #print "\n";
+ $#lastvalues = 0;
+ }
+ $listentry = 0;
+ next;
+ }
+ elsif (/^$/)
+ {
+ print_paragraph $paragraph, "", $listentry ? "" : "";
+ $listentry = 0;
+ next;
+ }
+ print_paragraph $paragraph;
+ $paragraph = $_;
+}
+
+# Do all the necessary end tags
+#print "
\n" if $level > 0;
+print "\n
\n" if $level > 0;
+print "\n";
+print "
\n\n" x $level;
+
+html_footer $up_url;
+select STDOUT;
+close INDEX;
+
+$paragraph = <>;
+my $oldsection;
+my $section;
+my $section_open = 0;
+my $num_sections = $lastvalues[1];
+my $in_heading = 0;
+my $in_h2 = 0;
+$level = 0;
+$#lastvalues = -1;
+
+my $heading_pat = qr/^\s*([0-9]+(?:.[0-9]+)*)\)\s+/;
+
+while (<>)
+{
+ s/\s+\n/\n/;
+ html_escape $_;
+
+ if (/^\s*([0-9]+)\)\s/)
+ {
+ chomp $paragraph if defined $paragraph;
+ if ($section_open)
+ {
+ if ($in_heading)
+ {
+ print_paragraph $paragraph, "", "";
+ }
+ else
+ {
+ print_paragraph $paragraph, "\n", "\n
";
+ }
+ }
+ $in_heading = $in_h2 = 0;
+ $oldsection = $section;
+ $section = $1;
+ print "\n" if $section_open;
+ print "\n\n" x $level if $section_open;
+ html_footer $index_file,
+ ($oldsection > 1) ?
+ ("part" . ($oldsection - 1) . ".html") :
+ undef,
+ "part" . ($oldsection + 1) . ".html"
+ if $section_open;
+ open SECTION, ">part$section.html" or
+ die "Couldn't write to part$section.html: $!";
+ select SECTION;
+ html_header "section $section",
+ $index_file,
+ "part" . ($section - 1) . ".html",
+ ($section < $num_sections) ?
+ ("part" . ($section + 1) . ".html") :
+ undef;
+ $section_open = 1;
+ $level = 0;
+ $#lastvalues = -1;
+ }
+
+ # Convert headings to anchors in list items
+ if (/$heading_pat/)
+ {
+ my $heading = $1;
+ my @components = split /\./, $heading;
+ chomp $paragraph if defined $paragraph;
+ if ($in_heading)
+ {
+ print_paragraph $paragraph, "", "\n";
+ }
+ else
+ {
+ print_paragraph $paragraph, "\n", "\n
\n";
+ }
+ $in_h2 = 0;
+
+ # Change level of ordered list if necessary
+ if (@components > $level)
+ {
+ print "\n\n" x (@components - $level);
+ }
+ elsif (@components < $level)
+ {
+ print "
\n\n" x ($level - @components);
+ }
+ $level = @components;
+ $#lastvalues = $level;
+
+ my $value = $components[$#components];
+ if (@components == 1)
+ {
+ chomp;
+ s|$heading_pat|\n";
+ $in_h2 = 0;
+ }
+ else
+ {
+ if ($in_heading)
+ {
+ print_paragraph $paragraph, "", "";
+ }
+ else
+ {
+ print_paragraph $paragraph, "\n", "\n
";
+ }
+ }
+ $in_heading = 0;
+ $paragraph = "$_" unless /^\n?$/;
+ }
+ elsif (defined $paragraph)
+ {
+ $paragraph .= "$_";
+ }
+ else
+ {
+ $paragraph = "$_" unless /^\n?$/;
+ }
+}
+
+if ($section_open)
+{
+ chomp $paragraph if defined $paragraph;
+ if ($in_heading)
+ {
+ print_paragraph $paragraph, "", "";
+ }
+ else
+ {
+ print_paragraph $paragraph, "\n", "\n
";
+ }
+ print "\n";
+ print "\n\n" x $level;
+
+ html_footer $index_file,
+ ($section > 1) ? ("part" . ($section - 1) . ".html") : undef,
+ undef;
+ close SECTION if $section_open;
+}
+else
+{
+ warn "No sections encountered";
+}
+
diff --git a/find-package b/find-package
new file mode 100644
index 0000000..713a67c
--- /dev/null
+++ b/find-package
@@ -0,0 +1,4 @@
+#! /bin/sh
+zcat /mirror/debian/dists/unstable/*/binary-$1/Packages.gz \
+ /mirror/debian/non-US/dists/unstable/non-US/*/binary-$1/Packages.gz \
+ | grep-dctrl -nsFilename -PX $2
diff --git a/find-visible b/find-visible
new file mode 100644
index 0000000..a1dc244
--- /dev/null
+++ b/find-visible
@@ -0,0 +1,2 @@
+#! /bin/sh
+find ! -perm -004 -prune -o -type f -perm -004 -print
diff --git a/find-zlib b/find-zlib
new file mode 100644
index 0000000..5999d34
--- /dev/null
+++ b/find-zlib
@@ -0,0 +1,100 @@
+#!/usr/bin/perl
+
+# find-zlib - scan for zlib tables in compiled code
+# Copyright (C) 2002 RUS-CERT, University of Stuttgart.
+# Written by Florian Weimer .
+#
+# 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.
+
+if (@ARGV == 0) {
+ print "usage: find-zlib filename...\n";
+ exit 1;
+}
+
+use strict;
+
+$/ = undef;
+
+my @inflate_table = (3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31,
+ 35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227,
+ 258, 0, 0);
+
+sub table_to_re (@) {
+ my $be = "";
+ my $le = "";
+ my $e;
+ foreach $e (@_) {
+ $be .= pack "N", $e;
+ $le .= pack "V", $e;
+ }
+ return (quotemeta($be), quotemeta($le));
+}
+
+sub table_to_re_config (@) {
+ my $be = "";
+ my $le = "";
+ my $e;
+ foreach $e (@_) {
+ $be .= pack "n", $e;
+ $le .= pack "v", $e;
+ }
+ return (quotemeta($be), quotemeta($le));
+}
+
+my ($inflate_table_be, $inflate_table_le) = table_to_re (@inflate_table);
+
+my $line;
+my (@config_table_le, @config_table_be) = ();
+foreach $line ([8, 32, 128, 256],
+ [32, 128, 258, 1024],
+ [32, 258, 258, 4096]) {
+ my ($be, $le) = table_to_re_config(@$line);
+ push @config_table_be, $be;
+ push @config_table_le, $le;
+}
+my ($config_table_be_32,
+ $config_table_be_64,
+ $config_table_le_32,
+ $config_table_le_64)
+ = (join("....", @config_table_be),
+ join("........", @config_table_be),
+ join("....", @config_table_le),
+ join("........", @config_table_le));
+
+my $file;
+my $found = 1;
+for $file (@ARGV) {
+ open (FILE, "<$file");
+ my $data = ;
+ close FILE;
+
+ if ($data =~ /$config_table_le_32/o) {
+ print "$file: zlib configuration table, little endian, 32 bit\n";
+ $found = 0;
+ }
+
+ if ($data =~ /$config_table_be_32/o) {
+ print "$file: zlib configuration table, big endian, 32 bit\n";
+ $found = 0;
+ }
+ if ($data =~ /$config_table_le_64/o) {
+ print "$file: zlib configuration table, little endian, 64 bit\n";
+ $found = 0;
+ }
+
+ if ($data =~ /$config_table_be_64/o) {
+ print "$file: zlib configuration table, big endian, 64bit\n";
+ }
+ if ($data =~ /$inflate_table_le/o) {
+ print "$file: zlib inflate table, little endian\n";
+ $found = 0;
+ }
+ if ($data =~ /$inflate_table_be/o) {
+ print "$file: zlib inflate table, big endian\n";
+ $found = 0;
+ }
+}
+exit $found;
diff --git a/format b/format
new file mode 100644
index 0000000..08a9d45
--- /dev/null
+++ b/format
@@ -0,0 +1,29 @@
+#!/bin/bash
+
+# Parameterizes a document.
+# Input arguments Param1 Value1 Param2 Value2 ... will replace
+# $Param1$ with Value1, $Param2$ with Value2, and so on.
+
+# Arguments with spaces in must be quoted.
+
+function getargs ()
+{
+ while [ $# != 0 -a $# != 1 ]; do
+ SUBST=${2//\'/\'\\\'\'};
+ SUBST=${SUBST//\//\\\/};
+ echo -n -;
+ echo -n e \'s/\\\$$1\\\$/$SUBST/g\'\ ;
+ shift 2;
+ done
+ echo -n -;
+ echo -n e \'s/\\\$\%/\$/g\' -e \'s/\\\$\\\$/\$/g\'\ ;
+ echo -n $1;
+}
+
+if [ "$1" == "-v" ]; then
+ shift;
+ bash --norc -vc "sed `getargs \"$@\"`";
+else
+ bash --norc -c "sed `getargs \"$@\"`";
+fi
+
diff --git a/ftp-removals b/ftp-removals
new file mode 100644
index 0000000..2a0837d
--- /dev/null
+++ b/ftp-removals
@@ -0,0 +1,8 @@
+#! /bin/sh
+set -e
+
+if [ -z "$1" -o "$1" = main ]; then
+ ${BROWSER:-lynx} http://ftp-master.debian.org/removals.txt
+else
+ ${BROWSER:-lynx} http://non-us.debian.org/~troup/removals.txt
+fi
diff --git a/genheaders b/genheaders
new file mode 100644
index 0000000..8c8073c
--- /dev/null
+++ b/genheaders
@@ -0,0 +1,2 @@
+#! /bin/sh
+expandvars.pl -s .header.ssi header.ssi
diff --git a/get-bugs b/get-bugs
new file mode 100644
index 0000000..a53e0b8
--- /dev/null
+++ b/get-bugs
@@ -0,0 +1,2 @@
+#! /bin/sh -e
+ssh master grep "^$1 " /var/lib/debbugs/spool/index.db
diff --git a/get-corr b/get-corr
new file mode 100644
index 0000000..a1edfda
--- /dev/null
+++ b/get-corr
@@ -0,0 +1,54 @@
+#! /usr/bin/perl -w
+use diagnostics;
+use strict;
+
+use Mail::Util qw(read_mbox);
+
+sub recurse ($)
+{
+ my $file = shift;
+ -d $file or return ($file);
+ opendir DIR, $file or return ($file);
+ my @contents = map { recurse("$file/$_") } grep !/^\.\.?$/, readdir DIR;
+ closedir DIR;
+ return @contents;
+}
+
+my @folders = recurse "$ENV{HOME}/mail";
+
+foreach my $folder (@folders)
+{
+ my @messages = read_mbox($folder);
+ foreach my $message (@messages)
+ {
+ my $from;
+ my $print_from = 0;
+ my $scan = 0;
+ foreach my $line (@$message)
+ {
+ last if $line =~ /^$/;
+ if ($line =~ /^From:[ \t](.*)/)
+ {
+ $from = $1;
+ }
+ if ($line =~ /^(?:To|Cc)/)
+ {
+ $scan = 1;
+ }
+ elsif ($line !~ /^[ \t]/)
+ {
+ $scan = 0;
+ }
+ if ($scan)
+ {
+ if ($line =~ /cjw44/)
+ {
+ $print_from = 1;
+ last;
+ }
+ }
+ }
+ print "$from\n" if $print_from and defined $from;
+ }
+}
+
diff --git a/get-deb b/get-deb
new file mode 100644
index 0000000..517b44c
--- /dev/null
+++ b/get-deb
@@ -0,0 +1,12 @@
+#! /bin/sh
+set -e
+
+FILENAME=$(grep-available -PXnsFilename $1)
+
+if [ -n "$FILENAME" ]; then
+ if echo "$FILENAME" | grep non-US; then
+ lftpget "ftp://ftp.uk.debian.org/debian-non-US/$FILENAME"
+ else
+ lftpget "ftp://ftp.uk.debian.org/debian/$FILENAME"
+ fi
+fi
diff --git a/get-kernel b/get-kernel
new file mode 100644
index 0000000..c4d9b92
--- /dev/null
+++ b/get-kernel
@@ -0,0 +1,11 @@
+#! /bin/sh -e
+
+VERSION=$1
+MAJOR=`expr $1 : '\(^[0-9]*\.[0-9]*\)'`
+
+rm -f linux
+wget -c ftp://ftp.kernel.org/pub/linux/kernel/v$MAJOR/linux-$VERSION.tar.bz2
+tar xjvf linux-$VERSION.tar.bz2
+rm -f linux-$VERSION.tar.bz2
+mv linux linux-$VERSION
+ln -s linux-$VERSION linux
diff --git a/get-newgroup b/get-newgroup
new file mode 100644
index 0000000..2385e6f
--- /dev/null
+++ b/get-newgroup
@@ -0,0 +1,3 @@
+#! /bin/sh
+wget ftp://ftp.isc.org/pub/usenet/control/`echo $1 | cut -d. -f1`/$1.Z
+if [ -f $1.Z ]; then uncompress -f $1.Z; fi
diff --git a/get-news-ntlworld b/get-news-ntlworld
new file mode 100644
index 0000000..5d6ba72
--- /dev/null
+++ b/get-news-ntlworld
@@ -0,0 +1,2 @@
+#! /bin/sh
+sudo su - news -c '/etc/news/scripts/ntlworld -v'
diff --git a/get-rfc b/get-rfc
new file mode 100644
index 0000000..ca7c2aa
--- /dev/null
+++ b/get-rfc
@@ -0,0 +1,2 @@
+#! /bin/sh
+wget --passive http://www.ietf.org/rfc/rfc$1.txt
diff --git a/get-sig b/get-sig
new file mode 100644
index 0000000..f15776b
--- /dev/null
+++ b/get-sig
@@ -0,0 +1,20 @@
+#! /bin/bash
+
+if [ "X$1" == "X" ]; then
+ NAME=$(grep '^\*' ~/.siglist | head -1 | tr -s '\t' ' ' | cut -d' ' -f2)
+ if [ "X$NAME" == "X" ]; then
+ echo "Usage: $0 signature-name [pattern]" 2>&1
+ exit 1
+ fi
+else
+ NAME=$1
+fi
+
+ARGS=$(grep ^$NAME'\>' ~/.siglist | head -1 | tr -s '\t' ' ' | cut -d' ' -f2-)
+BASEDIR=$(eval echo $(echo $ARGS | cut -d' ' -f1))
+STATICFILE=$(eval echo $(echo $ARGS | cut -d' ' -f2))
+FORTUNEARGS=$(eval echo $(echo $ARGS | cut -d' ' -f3-))
+
+cd $BASEDIR
+cat $STATICFILE
+if [ "$2" ]; then fortune $FORTUNEARGS -m $2; else fortune $FORTUNEARGS; fi
diff --git a/get-var.pl b/get-var.pl
new file mode 100644
index 0000000..9b8f930
--- /dev/null
+++ b/get-var.pl
@@ -0,0 +1,20 @@
+#! /usr/bin/perl -wn
+BEGIN {
+ unless (defined ($var = shift)) {
+ print STDERR "Usage: $0 var-name\n";
+ exit 1;
+ }
+}
+if (/^\Q$var\E=/) {
+ s/^\Q$var\E=//;
+ print, last unless /^'/;
+ do {
+ $quotes = (grep /'/g, (split //, $_)) % 3;
+ $inside = $quotes ... $quotes;
+ s/^'// if $inside == 1;
+ s/'$// if $quotes == 2 || $inside =~ /E0$/;
+ s/'\\''/'/g;
+ print;
+ last if $quotes == 2 || $inside =~ /E0$/;
+ } while (<>);
+}
diff --git a/get-with-referrer b/get-with-referrer
new file mode 100644
index 0000000..09a9cfb
--- /dev/null
+++ b/get-with-referrer
@@ -0,0 +1,14 @@
+#! /usr/bin/perl -w
+use strict;
+use LWP::UserAgent;
+
+my $url = <>;
+my $referrer = <>;
+my $target = <>;
+
+my $ua = new LWP::UserAgent;
+
+my $req = new HTTP::Request(GET => $url);
+$req->header(Referer => $referrer);
+my $res = $ua->request($req, $target);
+
diff --git a/grep-services b/grep-services
new file mode 100644
index 0000000..cf6615a
--- /dev/null
+++ b/grep-services
@@ -0,0 +1,28 @@
+#! /usr/bin/perl -ws
+use strict;
+use vars qw($f);
+
+sub getservice ($)
+{
+ (my $search) = @_;
+
+ open SERVICES, "/etc/services" or die "Couldn't open /etc/services";
+ while () { print if /\b\Q$search\E\b/; }
+ close SERVICES;
+}
+
+if ($f)
+{
+ while (<>)
+ {
+ chomp;
+ getservice $_;
+ }
+}
+else
+{
+ while (defined (my $arg = shift))
+ {
+ getservice $arg;
+ }
+}
diff --git a/hermes-unread b/hermes-unread
new file mode 100644
index 0000000..d69cf0d
--- /dev/null
+++ b/hermes-unread
@@ -0,0 +1,18 @@
+#! /usr/bin/perl -w
+use diagnostics;
+use strict;
+use Socket;
+
+my $sin = sockaddr_in 2345, inet_aton 'hermes.cam.ac.uk';
+for (@ARGV)
+{
+ socket HERMES, PF_INET, SOCK_STREAM, getprotobyname 'tcp' or
+ die "Couldn't create socket: $!";
+ connect HERMES, $sin or die "Couldn't connect: $!";
+ send HERMES, "$_\015\012", 0;
+ my $text;
+ recv HERMES, $text, 256, MSG_WAITALL;
+ print((split /\n/, $text, 2)[1]);
+ close HERMES;
+}
+
diff --git a/horja b/horja
new file mode 100644
index 0000000..e56129d
--- /dev/null
+++ b/horja
@@ -0,0 +1,4 @@
+grep -v ^# birthdays.txt | grep '[^/]*'/$(date +%m/%d) | tr '\t' ' ' | sed \
+'s|/../.. *|\\|'|awk -F\\ '{A='$(date +%Y)'-$1; gsub("['\''\"( ]","\\\\&", \
+$2);srand();system("sed "($1=="XXXX"?"/AGE/,/^/d":"s/AGE/"A"/")" message." \
+"txt | sed s/NAME/"$2"/|cat - horja"(rand()>10?"":".sig")" | inews -hOS");}'
diff --git a/httpclient b/httpclient
new file mode 100644
index 0000000..4898815
Binary files /dev/null and b/httpclient differ
diff --git a/iSilo386 b/iSilo386
new file mode 100644
index 0000000..0fd097d
Binary files /dev/null and b/iSilo386 differ
diff --git a/irccat b/irccat
new file mode 100644
index 0000000..5febfb0
--- /dev/null
+++ b/irccat
@@ -0,0 +1,87 @@
+#! /usr/bin/perl -w
+use strict;
+
+use Getopt::Long;
+use Net::IRC;
+
+sub usage ()
+{
+ print <<"EOF";
+Usage: $0 [options] command [arguments]
+EOF
+ print <<'EOF';
+
+Options are as follows, with defaults in brackets:
+
+ -n, --nick=[$IRCNICK] IRC nickname.
+ -s, --server=[$IRCSERVER] IRC server.
+
+Available commands (with arguments) are:
+
+ who #channel List the visible users on a channel.
+ whois username ... Query information about particular users.
+
+EOF
+ exit 1;
+}
+
+my %options = (
+ nick => $ENV{IRCNICK},
+ server => $ENV{IRCSERVER},
+);
+
+GetOptions(\%options,
+ 'help|h|?',
+ 'nick|n=s',
+ 'server|s=s',
+);
+
+usage if $options{help};
+
+my $command = shift or usage;
+$command = lc $command;
+
+if ($command eq 'who')
+{
+ scalar @ARGV == 1 or usage;
+}
+elsif ($command eq 'whois')
+{
+ scalar @ARGV > 0 or usage;
+}
+else
+{
+ usage;
+}
+
+my $irc = new Net::IRC;
+
+my $conn = $irc->newconn(Nick => $mynick, Server => $server)
+ or die "$0: can't connect to IRC server";
+
+sub on_connect
+{
+ my $self = shift;
+ $self->who($targetchannel);
+}
+
+sub on_whoreply
+{
+ my ($self, $event) = @_;
+ my ($me, $channel, $user, $host,
+ $server, $nick, $status, $realname) = $event->args;
+ printf "\%-12s \%s\n", $nick, $realname;
+}
+
+sub on_endofwho
+{
+ my $self = shift;
+ $self->quit;
+ exit;
+}
+
+$conn->add_handler('376', \&on_connect);
+$conn->add_handler('352', \&on_whoreply);
+$conn->add_handler('315', \&on_endofwho);
+
+$irc->start;
diff --git a/ircnotify b/ircnotify
new file mode 100644
index 0000000..c1684b4
--- /dev/null
+++ b/ircnotify
@@ -0,0 +1,3 @@
+#! /bin/sh
+export IRCSERVER=excalibur.esper.net
+xargs -n 1 ircwhois < ~/.ircnotify
diff --git a/ircnotify.debian b/ircnotify.debian
new file mode 100644
index 0000000..85456cd
--- /dev/null
+++ b/ircnotify.debian
@@ -0,0 +1,3 @@
+#! /bin/sh
+export IRCSERVER=irc.openprojects.net
+xargs -n 1 ircwhois < ~/.ircnotify.debian
diff --git a/ircwho b/ircwho
new file mode 100644
index 0000000..bed689b
--- /dev/null
+++ b/ircwho
@@ -0,0 +1,2 @@
+#! /bin/sh
+ircwho.pl $IRCSERVER Col $1
diff --git a/ircwho.pl b/ircwho.pl
new file mode 100644
index 0000000..67355e3
--- /dev/null
+++ b/ircwho.pl
@@ -0,0 +1,48 @@
+#! /usr/bin/perl -w
+use strict;
+
+use Net::IRC;
+
+sub usage ()
+{
+ print <<"EOF";
+Usage: $0 server my-nick target-channel
+EOF
+ exit 1;
+}
+
+my $server = shift or usage;
+my $mynick = shift or usage;
+my $targetchannel = shift or usage;
+
+my $irc = new Net::IRC;
+
+my $conn = $irc->newconn(Nick => $mynick, Server => $server)
+ or die "$0: can't connect to IRC server";
+
+sub on_connect
+{
+ my $self = shift;
+ $self->who($targetchannel);
+}
+
+sub on_whoreply
+{
+ my ($self, $event) = @_;
+ my ($me, $channel, $user, $host,
+ $server, $nick, $status, $realname) = $event->args;
+ printf "\%-12s \%s\n", $nick, $realname;
+}
+
+sub on_endofwho
+{
+ my $self = shift;
+ $self->quit;
+ exit;
+}
+
+$conn->add_handler('376', \&on_connect);
+$conn->add_handler('352', \&on_whoreply);
+$conn->add_handler('315', \&on_endofwho);
+
+$irc->start;
diff --git a/ircwhois b/ircwhois
new file mode 100644
index 0000000..07c25cc
--- /dev/null
+++ b/ircwhois
@@ -0,0 +1,2 @@
+#! /bin/sh
+ircwhois.pl $IRCSERVER Col $*
diff --git a/ircwhois.pl b/ircwhois.pl
new file mode 100644
index 0000000..c7376e1
--- /dev/null
+++ b/ircwhois.pl
@@ -0,0 +1,47 @@
+#! /usr/bin/perl -w
+use strict;
+
+use Net::IRC;
+
+sub usage ()
+{
+ die <<"EOF";
+Usage: $0 server my-nick target-nick [target-nick ...]
+EOF
+}
+
+my $server = shift or usage;
+my $mynick = shift or usage;
+my @targetnicks = @ARGV;
+usage if $#targetnicks == -1;
+
+my $irc = new Net::IRC;
+
+my $conn = $irc->newconn(Nick => $mynick, Server => $server)
+ or die "$0: can't connect to IRC server";
+
+sub on_connect
+{
+ my $self = shift;
+ $self->whois(@targetnicks);
+}
+
+sub on_whoisuser
+{
+ my ($self, $event) = @_;
+ my $nick = ($event->args)[1];
+ print "$nick is online\n";
+}
+
+sub on_endofwhois
+{
+ my $self = shift;
+ $self->quit;
+ exit;
+}
+
+$conn->add_handler('376', \&on_connect);
+$conn->add_handler('311', \&on_whoisuser);
+$conn->add_handler('318', \&on_endofwhois);
+
+$irc->start;
diff --git a/kill-netscape b/kill-netscape
new file mode 100644
index 0000000..665861a
--- /dev/null
+++ b/kill-netscape
@@ -0,0 +1,4 @@
+#! /bin/sh
+killall -9 communicator-smotif.real
+killall -9 navigator-smotif.real
+rm ~/.netscape/lock
diff --git a/kill-wine b/kill-wine
new file mode 100644
index 0000000..639cce4
--- /dev/null
+++ b/kill-wine
@@ -0,0 +1 @@
+kill `ps ax | grep '^......?.*wine' | cut -d' ' -f1`
diff --git a/m2n b/m2n
new file mode 100644
index 0000000..5d3786b
--- /dev/null
+++ b/m2n
@@ -0,0 +1,5 @@
+#! /bin/sh
+
+/home/cjw44/bin/m2n.pl -n $1 -a cjw44@riva.ucam.org >> /home/cjw44/.m2n-errors 2>&1
+exit 0
+
diff --git a/m2n.pl b/m2n.pl
new file mode 100644
index 0000000..50fc3aa
--- /dev/null
+++ b/m2n.pl
@@ -0,0 +1,222 @@
+#! /usr/bin/perl -w
+
+=head1 NAME
+
+m2n - a mail2news(1) replacement
+
+=head1 SYNOPSIS
+
+m2n.pl [I]
+
+=head1 DESCRIPTION
+
+A replacement for I from the newsgate package. Uses I instead
+of I by default, and is much less insistent on removing useful headers.
+
+=head1 OPTIONS
+
+Long option names may be abbreviated to uniqueness.
+
+=over 8
+
+=item B<--stdout>
+
+Send output to standard output rather than directly to I.
+
+=item B<-a>, B<--approved>=I
+
+Approved: line, if none is specified.
+
+=item B<-d>, B<--distribution>=I
+
+Distribution: line, if none is specified.
+
+=item B<-n>, B<--newsgroups>=I
+
+Newsgroups: line, overriding any such provided. Newsgroups: lines in the input
+will be saved in X-Mail2News-Newsgroups: lines.
+
+=item B<-o>, B<--organization>=I
+
+Organization: line, if none is specified.
+
+=item B<-s>, B<--subject>=I
+
+Subject: line, if none is specified; the default is "no subject".
+
+=item B<-x>, B<--path>=I
+
+Path: prefix, if none is specified; the default is "gateway".
+
+=back
+
+=head1 ERROR REPORTING
+
+Errors will be logged using syslog(3).
+
+=head1 SEE ALSO
+
+mail2news(1).
+
+=head1 AUTHOR
+
+I and this manual page were written by Colin Watson .
+
+=cut
+
+use strict;
+
+use Date::Format;
+use Digest::MD5 qw(md5_base64);
+use Getopt::Long;
+use Sys::Syslog qw(:DEFAULT setlogsock);
+
+$ENV{PATH} = '/usr/bin:/bin';
+
+# Use syslog(3) for error output.
+
+setlogsock 'unix';
+openlog 'mail2news', 'pid', 'news';
+
+sub syslogdie(@)
+{
+ syslog 'err', @_;
+ closelog;
+ exit;
+}
+
+# Option processing.
+
+my $tostdout = 0;
+my ($approved, $distribution, $newsgroups, $organization);
+my $subject = 'no subject';
+my $path = 'gateway';
+
+Getopt::Long::Configure qw(bundling bundling_override);
+GetOptions(
+ "stdout" => \$tostdout,
+ "approved|a=s" => \$approved,
+ "distribution|d=s" => \$distribution,
+ "newsgroups|n=s" => \$newsgroups,
+ "organization|o=s" => \$organization,
+ "subject|s=s" => \$subject,
+ "path|x=s" => \$path);
+
+# Read headers.
+
+my $headerblock = '';
+my $extra = '';
+my %headers = ();
+my ($hname, $hvalue);
+my $overridden = 0;
+
+while (<>)
+{
+ if (/^$/)
+ {
+ syslogdie 'No headers found, aborting' unless defined $hname;
+ $headers{lc $hname} = $hvalue;
+ last;
+ }
+ elsif (/From /)
+ {
+ next;
+ }
+ elsif (/^(\s.*)/)
+ {
+ my $line = $1;
+ syslogdie "Continuation line at start of headers: '$line'"
+ unless defined $hvalue;
+ $hvalue .= $line;
+ }
+ elsif (/^(.*?):[ \t](.*)/)
+ {
+ $headers{lc $hname} = $hvalue if defined $hname;
+ $overridden = 0;
+ $hname = $1;
+ $hvalue = $2;
+ if ($hname =~ /newsgroups/i && defined $newsgroups)
+ {
+ $hname = 'X-Mail2News-Newsgroups';
+ $headerblock .= "Newsgroups: $newsgroups\n";
+ $headers{newsgroups} = $newsgroups;
+ $overridden = 1;
+ }
+ elsif ($hname =~ /path/i && defined $path)
+ {
+ $hvalue = "$path!$hvalue";
+ }
+ $_ = "$hname: $hvalue\n";
+ }
+ elsif (/^(.*?):\n/)
+ {
+ $headers{lc $hname} = $hvalue if defined $hname;
+ $overridden = 0;
+ $hname = $1;
+ $hvalue = '';
+ if ($hname =~ /newsgroups/i && defined $newsgroups)
+ {
+ $hname = 'X-Mail2News-Newsgroups';
+ $headerblock .= "Newsgroups: $newsgroups\n";
+ $headers{newsgroups} = $newsgroups;
+ $overridden = 1;
+ }
+ elsif ($hname =~ /path/i && defined $path)
+ {
+ $hvalue = $path;
+ }
+ $_ = "$hname: $hvalue\n";
+ }
+ else
+ {
+ my $line = $_;
+ syslogdie "Invalid header line: '$line'";
+ }
+
+ if ($overridden) { $extra .= $_; }
+ else { $headerblock .= $_; }
+}
+
+local $/ = undef;
+my $body .= <>;
+
+# Headers from command line
+
+$extra .= "Approved: $approved\n"
+ if defined $approved and not defined $headers{approved};
+$extra .= "Distribution: $distribution\n"
+ if defined $distribution and not defined $headers{distribution};
+$extra .= "Newsgroups: $newsgroups\n"
+ if defined $newsgroups and not defined $headers{newsgroups};
+$extra .= "Organization: $organization\n"
+ if defined $organization and not defined $headers{organization};
+$extra .= "Subject: $subject\n"
+ if defined $subject and not defined $headers{subject};
+$headerblock = "Path: $path\n$headerblock"
+ if defined $path and not defined $headers{path};
+
+# Other required header checks
+
+syslogdie 'No From: line, aborting' unless defined $headers{from};
+$extra .= time2str 'Date: %a, %e %h %Y %T GMT' . "\n", time, 'GMT'
+ unless defined $headers{date};
+$extra .= sprintf "Message-ID: \n",
+ time, md5_base64($body) unless defined $headers{'message-id'};
+
+# Output to stdout or rnews.
+
+if ($tostdout)
+{
+ print $headerblock, $extra, "\n", $body;
+}
+else
+{
+ $SIG{PIPE} = 'IGNORE';
+ open RNEWS, '| rnews -v 2>/dev/null' or syslogdie "can't fork: \%m";
+ print RNEWS $headerblock, $extra, "\n", $body
+ or syslogdie "can't write: \%m";
+ close RNEWS or syslogdie "can't close: \%m";
+}
+
+closelog;
+
diff --git a/mailkill b/mailkill
new file mode 100644
index 0000000..9dd24f7
--- /dev/null
+++ b/mailkill
@@ -0,0 +1,2 @@
+#!/bin/sh
+echo $1 >> $HOME/.killfile
diff --git a/mailsort.pl b/mailsort.pl
new file mode 100644
index 0000000..e13bc17
--- /dev/null
+++ b/mailsort.pl
@@ -0,0 +1,46 @@
+#! /usr/bin/perl -w
+use diagnostics;
+use strict;
+use Date::Parse;
+
+my $message;
+my ($fromdate, $date);
+my @messages;
+my %dates;
+
+while (<>)
+{
+ chomp;
+ if (/^From /)
+ {
+ if (defined $message)
+ {
+ push @messages, ($message);
+ $dates{$message} = defined $date ? $date : $fromdate;
+ }
+ $message = "$_\n";
+ /^From [^ ]* (.*)/;
+ $fromdate = $1;
+ $fromdate =~ s/ +/ /g;
+ $fromdate = str2time $fromdate;
+ $date = undef;
+ }
+ elsif (!(defined $date) && /^Date: (.*)/)
+ {
+ $message .= "$_\n";
+ $date = str2time $1;
+ }
+ else
+ {
+ $message .= "$_\n";
+ }
+}
+
+if (defined $message)
+{
+ push @messages, ($message);
+ $dates{$message} = defined $date ? $date : $fromdate;
+}
+
+print (sort { $dates{$a} <=> $dates{$b} } @messages);
+
diff --git a/mailsplit b/mailsplit
new file mode 100644
index 0000000..b0f7c1f
--- /dev/null
+++ b/mailsplit
@@ -0,0 +1,34 @@
+#! /usr/bin/perl -w
+use strict;
+
+sub usage ()
+{
+ print < $directory/$message";
+my $empty = 1;
+while (<>)
+{
+ if (/^From /)
+ {
+ next if $empty;
+ $message++;
+ open MESSAGE, "> $directory/$message";
+ $empty = 1;
+ }
+ else
+ {
+ print MESSAGE $_;
+ $empty = 0;
+ }
+}
+close MESSAGE;
+
diff --git a/mailtonews.wrapper b/mailtonews.wrapper
new file mode 100644
index 0000000..9b45b8a
--- /dev/null
+++ b/mailtonews.wrapper
@@ -0,0 +1,3 @@
+#! /bin/sh
+mailtonews >> /home/cjw44/.m2n-errors 2>&1
+exit 0
diff --git a/mesghere b/mesghere
new file mode 100644
index 0000000..3294123
--- /dev/null
+++ b/mesghere
@@ -0,0 +1,27 @@
+#! /bin/sh
+
+TTYS=`who | grep $USER | tr -s ' ' | cut -d' ' -f2 | grep -v :`
+
+if [ -z "$1" ]; then
+ if ! tty > /dev/null; then
+ echo "stdin is not a tty" >&2
+ exit 1
+ fi
+ HERE=`tty`
+elif [ -c "$1" ]; then
+ HERE=$1
+elif [ -c "/dev/$1" ]; then
+ HERE=/dev/$1
+else
+ echo "No such device: $1"
+ exit 1
+fi
+
+BASEHERE=`echo $HERE | sed 's|^/dev/||'`
+
+if [ -c $HERE ] && echo $TTYS | grep '\<'$BASEHERE'\>' > /dev/null; then
+ for tty in $TTYS; do [ "$BASEHERE" != "$tty" -a -c /dev/$tty ] && chmod g-w /dev/$tty; done
+ chmod g+w $HERE
+else
+ echo "You are not logged in on $BASEHERE" >&2
+fi
diff --git a/mordja b/mordja
new file mode 100644
index 0000000..10a1755
--- /dev/null
+++ b/mordja
@@ -0,0 +1,9 @@
+#! /bin/sh -e
+
+# Usage: mordja to-address subject file
+
+export PATH=/usr/bin:/bin
+
+cd ~/afe/daemons/mordja
+{ cat "$3"; echo '-- '; cat .signature; } | mutt -F .muttrc -s "Re: $2" "$1"
+
diff --git a/mordja-zip b/mordja-zip
new file mode 100644
index 0000000..4542b2b
--- /dev/null
+++ b/mordja-zip
@@ -0,0 +1,9 @@
+#! /bin/sh -e
+
+# Usage: mordja to-address subject file
+
+export PATH=/usr/bin:/bin
+
+cd ~/afe/daemons/mordja
+{ echo '-- '; cat .signature; } | mutt -F .muttrc -s "Re: $2" "$1" -a "$3"
+
diff --git a/my-debmirror b/my-debmirror
new file mode 100644
index 0000000..bd2cc6f
--- /dev/null
+++ b/my-debmirror
@@ -0,0 +1,7 @@
+#! /bin/sh -e
+DEB_MIRROR=${DEB_MIRROR:-ftp.de.debian.org}
+debmirror /mirror/debian -h "$DEB_MIRROR" --passive \
+ --nosource --section=main,main/debian-installer --getcontents \
+ --ignore=non-US/ "$@"
+debmirror /mirror/debian/non-US -h "$DEB_MIRROR" -r /debian-non-US --passive \
+ --nosource --section=main -d unstable/non-US --getcontents "$@"
diff --git a/my-debmirror-riva b/my-debmirror-riva
new file mode 100644
index 0000000..e0ea329
--- /dev/null
+++ b/my-debmirror-riva
@@ -0,0 +1,5 @@
+#! /bin/sh -e
+debmirror /mirror/debian -h riva \
+ --nosource --section=main --getcontents --ignore=non-US/ "$@"
+debmirror /mirror/debian/non-US -h riva -r /debian/non-US \
+ --nosource --section=main -d unstable/non-US --getcontents "$@"
diff --git a/nmu-announce b/nmu-announce
new file mode 100644
index 0000000..5368074
--- /dev/null
+++ b/nmu-announce
@@ -0,0 +1,36 @@
+#! /bin/sh
+set -e
+
+DRAFT=`tempfile`
+
+cat >$DRAFT <
+To: $2@bugs.debian.org
+Cc: control@bugs.debian.org
+Subject: $1: Proposed NMU diff
+Fcc: =debian/nmus
+
+tags $2 patch
+thanks
+
+Here's a patch fixing this bug. If I don't hear anything, I'll upload
+this as an NMU in a week or so.
+
+EOF
+
+if [ -n "$4" ]; then
+ debdiff $3 $4 >>$DRAFT
+else
+ cat $3 >>$DRAFT
+fi
+
+cat >>$DRAFT <&2 # Everything goes to standard error
+
+if [ "X$1" == "X" -o "X$2" == "X" ]; then
+ echo "Usage: $0 victim newsgroup [ time-spec ]"
+ exit 1
+fi
+
+VICTIM=$1
+NEWSGROUP=$2
+KILLFILE="$HOME/News/`echo $NEWSGROUP | tr . /`/KILL"
+
+if [ ! -f $KILLFILE ]; then
+ echo "Killfile for $NEWSGROUP not found"
+ exit 1
+fi
+
+echo "/$VICTIM/f:j" >> $KILLFILE
+
+shift 2
+
+if [ "X$1" != "X" ]; then
+ echo "$HOME/bin/reprieve \"$VICTIM\" $NEWSGROUP \"`date`\"" | /usr/bin/at "$*" 2>/dev/null
+fi
diff --git a/print-calendar b/print-calendar
new file mode 100644
index 0000000..c5b9396
--- /dev/null
+++ b/print-calendar
@@ -0,0 +1,16 @@
+#! /usr/bin/perl -w
+use strict;
+use Time::ParseDate;
+
+my $days = shift;
+my $unixend = parsedate("now + $days days");
+die "Usage: $0 days calendar-file" if not defined($unixend);
+
+while (<>)
+{
+ chomp;
+ (my $when) = split /[^0-9\/-]/;
+ my $unixwhen = parsedate($when, UK => 1);
+ last if $unixwhen > $unixend;
+ print "$_\n";
+}
diff --git a/proto-address b/proto-address
new file mode 100644
index 0000000..18a56bd
--- /dev/null
+++ b/proto-address
@@ -0,0 +1,2 @@
+#! /bin/sh
+perl -ne '(print, last) if s/^alias '$1' //gi' ~/.mutt_aliases
diff --git a/prune-history b/prune-history
new file mode 100644
index 0000000..432a15c
--- /dev/null
+++ b/prune-history
@@ -0,0 +1,15 @@
+#! /usr/bin/perl -wi
+use strict;
+
+my @last;
+
+while (defined (my $line = <>))
+{
+ unless ($line =~ /^(fg|ls|l|s|sl|cd -|cd ..)$/
+ or grep { $line eq $_ } @last)
+ {
+ print $line;
+ $last[1] = $last[0] if defined $last[0];
+ $last[0] = $line;
+ }
+}
diff --git a/prune-sessions b/prune-sessions
new file mode 100644
index 0000000..215d96a
--- /dev/null
+++ b/prune-sessions
@@ -0,0 +1,3 @@
+#! /bin/sh
+cd $HOME/public_html/kamion/archive-bin
+exec ./prune-sessions.pl 96
diff --git a/query-hermes.pl b/query-hermes.pl
new file mode 100644
index 0000000..5f9991e
--- /dev/null
+++ b/query-hermes.pl
@@ -0,0 +1,50 @@
+#! /usr/bin/perl -w
+use diagnostics;
+use strict;
+
+my $arg = shift;
+
+print "Querying hermes for $arg ... ";
+
+my $pid = open FINGER, "-|";
+if (!defined $pid)
+{
+ print "can't fork: $!\n";
+ exit 2;
+}
+elsif (!$pid)
+{
+ if (not exec 'finger', "$arg\@hermes")
+ {
+ print "can't exec finger: $!\n";
+ exit 2;
+ }
+}
+else
+{
+ ;
+ ;
+ $/ = undef;
+ my $finger = ;
+ close FINGER;
+
+ unless (defined $finger)
+ {
+ print "no matches\n";
+ exit 1;
+ }
+
+ my @people = split /\n/, $finger;
+ foreach my $person (@people)
+ {
+ $person =~ s/^([^ ]*) *(.{1,20}[^ ]).*$/$1\t$2/ or $person = '';
+ }
+ @people = grep /./, @people;
+
+ if (@people == 0) { print "no matches\n"; exit 1; }
+ elsif (@people == 1) { print "1 match\n"; }
+ else { print scalar(@people), " matches\n"; }
+
+ print "$_\n" foreach @people;
+}
+
diff --git a/read-newsrc b/read-newsrc
new file mode 100644
index 0000000..0adf6d2
--- /dev/null
+++ b/read-newsrc
@@ -0,0 +1,2 @@
+#! /bin/sh
+cut -d' ' -f2 | sed 's/,/ /g' | xargs -n1 | sed 's/-/ /' | sed 's/^\([0-9]*\)$/\1 \1/' | xargs -l1 seq
diff --git a/reprieve b/reprieve
new file mode 100644
index 0000000..abfd94f
--- /dev/null
+++ b/reprieve
@@ -0,0 +1,32 @@
+#! /bin/bash
+
+# Give a luser a chance at a reprieve from a killfiling by mailing
+# the current user.
+
+exec 1>&2 # Everything goes to standard error
+
+if [ "X$1" == "X" -o "X$2" == "X" -o "X$3" == "X" ]; then
+ echo "Usage: $0 victim newsgroup killfile-date"
+ exit 1
+fi
+
+/usr/lib/sendmail $LOGNAME <<-ENDMAIL
+ From: The Rivan Court of Appeal <${LOGNAME}@riva.ucam.org>
+ Subject: $1 is eligible for a reprieve
+
+ A certain luser, $1, has been killfiled in the newsgroup
+ $2 since $3.
+
+ You elected to give this luser a chance at a reprieve. Please
+ consider your verdict carefully, and run
+
+ delkill "$1" $2
+
+ if you consider that he or she still deserves another chance.
+
+ Thank you,
+
+ --
+ The Rivan Court of Appeal
+ENDMAIL
+
diff --git a/riva-moderate b/riva-moderate
new file mode 100644
index 0000000..165c1e4
--- /dev/null
+++ b/riva-moderate
@@ -0,0 +1,3 @@
+#! /bin/sh
+
+/usr/bin/formail -bf -I Received -I "To: $1" -I Path -I Newsgroups | /bin/sed '$d' | /usr/lib/sendmail -bm $1
diff --git a/run-horja b/run-horja
new file mode 100644
index 0000000..069fea4
--- /dev/null
+++ b/run-horja
@@ -0,0 +1,6 @@
+#! /bin/bash
+
+# Run the alt.fan.eddings Birthday Daemon
+cd $HOME/afe/daemons
+export PATH=$HOME/bin:$PATH
+$HOME/bin/horja
diff --git a/silver-suggestions b/silver-suggestions
new file mode 100644
index 0000000..2657001
--- /dev/null
+++ b/silver-suggestions
@@ -0,0 +1,5 @@
+#! /bin/sh
+
+# Post the Silver Suggestions every fortnight
+cd $HOME/afe/daemons
+$HOME/bin/crondiv 2 silver-suggestions.log inews -hS silver-suggestions.txt
diff --git a/sops-virginizer b/sops-virginizer
new file mode 100644
index 0000000..ee7be17
--- /dev/null
+++ b/sops-virginizer
@@ -0,0 +1,129 @@
+Article: 37376 of riva.lists.debian.user
+Path: riva.ucam.org!gateway
+X-Envelope-Sender: kmself@ix.netcom.com
+From: kmself@ix.netcom.com
+Date: Tue, 28 Nov 2000 19:37:02 -0800
+To: debian-user@lists.debian.org
+Subject: Re: mpage & PS docs -- 1-up => 2-up fsckups. StarOffice?
+Message-ID: <20001128193702.D19274@ix.netcom.com>
+References: <20001128170849.B16364@ix.netcom.com>
+Mime-Version: 1.0
+Content-Type: multipart/signed; micalg=pgp-sha1;
+ protocol="application/pgp-signature"; boundary="9crTWz/Z+Zyzu20v"
+Content-Disposition: inline
+User-Agent: Mutt/1.2.5i
+In-Reply-To: ; from cjw44@flatline.org.uk on Wed, Nov 29, 2000 at 01:32:49AM +0000
+X-Debian-GNU-Linux: Rocks
+X-Kuro5hin-cabal: There is no K5 cabal
+X-GPG-Fingerprint: F932 8B25 5FDD 2528 D595 DC61 3847 889F 55F2 B9B0
+Resent-Message-ID:
+Resent-From: debian-user@lists.debian.org
+X-Mailing-List: archive/latest/119890
+X-Loop: debian-user@lists.debian.org
+Precedence: list
+Resent-Sender: debian-user-request@lists.debian.org
+Resent-Bcc:
+Resent-Date: Wed, 29 Nov 2000 03:50:06 +0000
+Newsgroups: riva.lists.debian.user
+Approved: cjw44@riva.ucam.org
+Lines: 96
+Xref: riva.ucam.org riva.lists.debian.user:37376
+
+
+--9crTWz/Z+Zyzu20v
+Content-Type: multipart/mixed; boundary="uxuisgdDHaNETlh8"
+Content-Disposition: inline
+
+
+--uxuisgdDHaNETlh8
+Content-Type: text/plain; charset=us-ascii
+Content-Disposition: inline
+Content-Transfer-Encoding: quoted-printable
+
+on Wed, Nov 29, 2000 at 01:32:49AM +0000, Colin Watson (cjw44@flatline.org.=
+uk) wrote:
+> kmself@ix.netcom.com wrote:
+> >Specific instance is an Excel spreadsheet, printed to file from
+> >StarOffice (that bloated stuck pig of an office suite), then attempting
+> >to convert the file with mpage to a two-pages-per-sheet with:
+> >
+> > mpage -dp -2 < soffice.ps > soffice-2up.ps
+> >
+> >Viewing (or printing) the results with gv flashes up the rendered
+> >content for a moment, then blanks the page. 'gs' has similar results.
+> >This appears to be a problem noted by others (Google, Deja turn up some
+> >references), but I can't seem to find a fix.
+>=20
+> Hm. I can't help with mpage, I'm afraid. As a workaround, have you tried
+> psnup (from the psutils package)? Of course, you'll have to cause the
+> PostScript file to contain its original self twice, perhaps using
+> psmerge. Sorry if a workaround wasn't what you were after.
+
+Thanks, psnup *does* do the trick. I've been using mpage for a few
+years, so it's going to tough to kick the habit, but that's a good one
+to know.
+
+The problem, according to web searches, is broken PS output by
+StarOffice. One fix is to use a set of ps2ps commands to produce
+rectified, Level-1 postscript. From a set of commands found online,
+I've created the attached 'sopsvirginizer' script -- it un-fscks
+StarOffice postscript output.=20
+
+--=20
+Karsten M. Self http://www.netcom.com/~kmself
+ Evangelist, Zelerate, Inc. http://www.zelerate.org
+ What part of "Gestalt" don't you understand? There is no K5 cabal
+ http://gestalt-system.sourceforge.net/ http://www.kuro5hin.org
+
+--uxuisgdDHaNETlh8
+Content-Type: text/plain; charset=us-ascii
+Content-Disposition: attachment; filename=sopsvirginizer
+
+#!/bin/sh
+
+# This script virginizes (de-fucks) StarOffice postscript, for use in
+# mpage and other tools.
+# Author: Karsten M. Self
+# Date: Tuesday, November 28, 2000
+# Credits: George Smiley (georgesmiley@my-deja.com) for the idea
+# License: This work is public domain
+# ----------------------------------------
+# Arguments: $1= infile, $2= outfile
+# ----------------------------------------
+
+if [ X$1 = "X" -o X$2 = "X" ]; then
+ echo "usage: $( basename $0 ) infile outfile" 1>&2; exit 1
+fi
+
+export PATH=/usr/bin:/bin
+TMPFILE=$( mktemp /tmp/sops1.XXXXXX ) || exit 1
+trap 'rm -f $TMPFILE; exit 1' 1 2 3 13 15
+
+ps2ps $1 $TMPFILE && ps2ps -dLanguageLevel=1 $TMPFILE $2
+rm -f $TMPFILE
+
+--uxuisgdDHaNETlh8--
+
+--9crTWz/Z+Zyzu20v
+Content-Type: application/pgp-signature
+Content-Disposition: inline
+
+-----BEGIN PGP SIGNATURE-----
+Version: GnuPG v1.0.4 (GNU/Linux)
+Comment: For info see http://www.gnupg.org
+
+iD8DBQE6JHncOEeIn1XyubARAn4OAJ9SJctkxOTl64vF3fMOkWzJScToCgCfa4KK
+3zCwRibuVRWTOZPNVhiLwbA=
+=RPmJ
+-----END PGP SIGNATURE-----
+
+--9crTWz/Z+Zyzu20v--
+
+
+--
+To UNSUBSCRIBE, email to debian-user-request@lists.debian.org
+with a subject of "unsubscribe". Trouble? Contact listmaster@lists.debian.org
+
+
+
+
diff --git a/sponge b/sponge
new file mode 100644
index 0000000..4d207bc
Binary files /dev/null and b/sponge differ
diff --git a/ssh-chiark b/ssh-chiark
new file mode 100644
index 0000000..cc15562
--- /dev/null
+++ b/ssh-chiark
@@ -0,0 +1,2 @@
+#! /bin/sh
+ssh -L 6670:chiark:6667 chiark
diff --git a/ssh-v b/ssh-v
new file mode 100644
index 0000000..0032ca5
--- /dev/null
+++ b/ssh-v
@@ -0,0 +1,2 @@
+#! /bin/sh -e
+/usr/bin/ssh -v -v -v "$@"
diff --git a/ssize.pl b/ssize.pl
new file mode 100644
index 0000000..2278255
--- /dev/null
+++ b/ssize.pl
@@ -0,0 +1,23 @@
+#! /usr/bin/perl -w
+use diagnostics;
+use strict;
+
+my $body = 0;
+my $filename = shift;
+
+while (<>)
+{
+ if (/^;
+ $_ = <>;
+ print "\n";
+ }
+ next unless $body;
+ last if /^<\/BODY/;
+ print;
+}
+
+print "\n";
+
diff --git a/start-ssh b/start-ssh
new file mode 100644
index 0000000..a04b3b8
--- /dev/null
+++ b/start-ssh
@@ -0,0 +1,3 @@
+#!/bin/sh
+eval $(ssh-agent)
+ssh-add
diff --git a/stop-ssh b/stop-ssh
new file mode 100644
index 0000000..7ca134e
--- /dev/null
+++ b/stop-ssh
@@ -0,0 +1,2 @@
+#!/bin/sh
+eval $(ssh-agent -k)
diff --git a/tabulateafe b/tabulateafe
new file mode 100644
index 0000000..1178433
--- /dev/null
+++ b/tabulateafe
@@ -0,0 +1 @@
+cut -d' ' -f2- afe-posters | sort | uniq | sed -e 's/"/\\"/g' | sed -e 's/ /\\ /g' | sed -e s/\'/\\\\\'/g | xargs -n 1 countafe
diff --git a/taskbot.pl b/taskbot.pl
new file mode 100644
index 0000000..c17621f
--- /dev/null
+++ b/taskbot.pl
@@ -0,0 +1,116 @@
+#! /usr/bin/perl -w
+use diagnostics;
+use strict;
+
+use Net::IRC;
+
+sub usage ()
+{
+ die <<"EOF";
+Usage: $0 server bot-name target-channel
+EOF
+}
+
+my %tasks = ();
+
+my $server = shift or usage;
+my $botname = shift or usage;
+my $channel = shift or usage;
+
+my $irc = new Net::IRC;
+
+my $conn = $irc->newconn(Nick => $botname, Server => $server)
+ or die "$0: can't connect to IRC server";
+
+my $joined = 0;
+
+sub on_connect
+{
+ my $self = shift;
+ $self->join($channel);
+}
+
+sub on_topic
+{
+ my $self = shift;
+ $joined = 1;
+}
+
+sub on_public
+{
+ my ($self, $event) = @_;
+ my ($args) = $event->args;
+ my $from = $event->from;
+ $from =~ s/!.*//;
+ if ($args =~ s/^$botname:?\s*//io)
+ {
+ my ($victim, $task, $tasksref);
+ (my $command, $args) = split ' ', $args, 2;
+ $command = lc $command;
+ if ($command eq 'add' && $args =~ /^([^ \t]+)\s+(.*[^ \t])/)
+ {
+ ($victim, $task) = ($1, $2);
+ $tasksref = $tasks{$victim};
+ $tasksref = $tasks{$victim} = [] if not defined $tasksref;
+ $$tasksref[scalar @$tasksref] = $task;
+ $self->privmsg($channel, "cheers, added task for $victim:");
+ $self->privmsg($channel, " $task");
+ }
+ elsif ($command eq 'delete' && $args =~ /^([^ \t]+)\s+(.*[^ \t])/)
+ {
+ ($victim, $task) = ($1, $2);
+ $tasksref = $tasks{$victim};
+ if (defined $tasksref && scalar grep {$_ eq $task} @$tasksref)
+ {
+ @$tasksref = grep {$_ ne $task} @$tasksref;
+ $self->privmsg($channel, "cheers, deleted task for $victim:");
+ $self->privmsg($channel, " $task");
+ }
+ else
+ {
+ $self->privmsg($channel,
+ "sorry, never heard of that task for $victim:");
+ $self->privmsg($channel, " $task");
+ }
+ }
+ elsif ($command eq 'deleteall' && $args =~ /^([^ \t]+)/)
+ {
+ $victim = $1;
+ undef $tasks{$victim};
+ $self->privmsg($channel, "$victim is free! For a short time ...");
+ }
+ elsif ($command eq 'help')
+ {
+ $self->privmsg($channel, "No.");
+ }
+ elsif ($command eq 'list' && $args =~ /^([^ \t]+)/)
+ {
+ $victim = $1;
+ $tasksref = $tasks{$victim};
+ if (defined $tasksref && scalar @{$tasks{$victim}})
+ {
+ $self->privmsg($channel, "$victim is supposed to be doing:");
+ }
+ else
+ {
+ $self->privmsg($channel, "No tasks for $victim.");
+ }
+ foreach my $task (@{$tasks{$victim}})
+ {
+ $self->privmsg($channel, " $task");
+ }
+ }
+ elsif ($command eq 'quit')
+ {
+ $self->privmsg($channel, "They killed $botname! The bastards ...");
+ $self->quit;
+ exit;
+ }
+ }
+}
+
+$conn->add_handler('376', \&on_connect);
+$conn->add_handler('332', \&on_topic);
+$conn->add_handler('public', \&on_public);
+
+$irc->start;
diff --git a/unknown-package b/unknown-package
new file mode 100644
index 0000000..1c20276
--- /dev/null
+++ b/unknown-package
@@ -0,0 +1,2 @@
+#! /bin/sh
+${BROWSER:-lynx} http://bugs.debian.org/cgi-bin/pkgreport.cgi?maint=
diff --git a/validate-directory b/validate-directory
new file mode 100644
index 0000000..4ecbc67
--- /dev/null
+++ b/validate-directory
@@ -0,0 +1,10 @@
+#! /bin/bash
+
+set -e
+[ "$1" ] && cd $1
+BASE_URL=`pwd -P | sed 's|/home/httpd/users/|http://riva.ucam.org/~|'`
+set +e
+
+shopt -s nullglob
+for x in *.html; do echo $BASE_URL/$x; nsgmls -s $BASE_URL/$x; done
+
diff --git a/validate-tree b/validate-tree
new file mode 100644
index 0000000..d8c5766
--- /dev/null
+++ b/validate-tree
@@ -0,0 +1,7 @@
+#! /bin/bash
+
+set -e
+[ "$1" ] && cd $1
+set +e
+
+find -type d -perm -0755 | sort | xargs -n 1 validate-directory
diff --git a/verify-status.pl b/verify-status.pl
new file mode 100644
index 0000000..0b98045
--- /dev/null
+++ b/verify-status.pl
@@ -0,0 +1,50 @@
+#! /usr/bin/perl -w
+use diagnostics;
+use strict;
+
+local (*AVAILABLE, *STATUS);
+open AVAILABLE, ')
+{
+ if (/^Package: (.*)/)
+ {
+ $package = $1;
+ }
+ elsif (/^Version: (.*)/)
+ {
+ $available{$package} = $1;
+ undef $package;
+ }
+}
+
+while ()
+{
+ if (/^Package: (.*)/)
+ {
+ $package = $1;
+ }
+ elsif (/^Version: (.*)/)
+ {
+ $status{$package} = $1;
+ undef $package;
+ }
+}
+
+close STATUS;
+close AVAILABLE;
+
+foreach my $package (sort keys %available)
+{
+ if (defined $status{$package})
+ {
+ print "!!! " if $available{$package} ne $status{$package};
+ print "$package $available{$package} $status{$package}\n";
+ }
+}
+
diff --git a/when-dinstall b/when-dinstall
new file mode 100644
index 0000000..e7bfb17
--- /dev/null
+++ b/when-dinstall
@@ -0,0 +1,2 @@
+#! /bin/sh -e
+date -d '01/01/1970 00:00:'"$((($(TZ=US/Eastern date -d 14:52:00 +%s) - $(date +%s) + 86400) % 86400))" +%T
diff --git a/wnpp b/wnpp
new file mode 100644
index 0000000..61be547
--- /dev/null
+++ b/wnpp
@@ -0,0 +1,2 @@
+#! /bin/sh
+${BROWSER:-lynx} http://www.debian.org/devel/wnpp/
diff --git a/write-newsrc b/write-newsrc
new file mode 100644
index 0000000..2b34d28
--- /dev/null
+++ b/write-newsrc
@@ -0,0 +1,43 @@
+#! /usr/bin/perl -w
+use strict;
+
+my $start = <>;
+chomp $start;
+my $end = <>;
+chomp $end;
+
+while (defined $start)
+{
+ if (not defined $end)
+ {
+ print $start;
+ undef $start;
+ }
+ elsif ($start + 1 != $end)
+ {
+ print "$start,";
+ $start = $end;
+ $end = <>;
+ chomp $end if defined $end;
+ }
+ else
+ {
+ my $newend = $end;
+ do
+ {
+ $end = $newend;
+ $newend = <>;
+ chomp $newend if defined $newend;
+ } while defined $newend and $newend == $end + 1;
+ print "$start-$end";
+ print "," if defined $newend;
+ $start = $newend;
+ if (defined $start)
+ {
+ $end = <>;
+ chomp $end if defined $end;
+ }
+ }
+}
+
+print "\n";
diff --git a/write-sig b/write-sig
new file mode 100644
index 0000000..7de37e7
--- /dev/null
+++ b/write-sig
@@ -0,0 +1,32 @@
+#! /bin/sh
+
+# Get name of signature group
+NAME=
+
+# .signature file
+SIGFILE=~/.signature
+
+# Process arguments
+while [ $# -ne 0 ]; do
+ case $1 in
+ -n|--name)
+ NAME=$2
+ shift 2
+ ;;
+ -s|--sigfile)
+ SIGFILE=$2
+ shift 2
+ ;;
+ *) shift
+ ;;
+ esac
+done
+
+# Clean up and exit on SIGHUP, SIGINT, SIGQUIT, or SIGTERM
+trap "rm -f $SIGFILE; get-sig $NAME > $SIGFILE; exit 1" 1 2 3 15
+
+rm -f $SIGFILE
+mkfifo $SIGFILE
+while :; do
+ get-sig $NAME > $SIGFILE
+done
diff --git a/xauthhere b/xauthhere
new file mode 100644
index 0000000..991cdc8
--- /dev/null
+++ b/xauthhere
@@ -0,0 +1 @@
+xauth extract - $DISPLAY | rsh $1 xauth merge -
diff --git a/xterm-title b/xterm-title
new file mode 100644
index 0000000..7a6a536
--- /dev/null
+++ b/xterm-title
@@ -0,0 +1,2 @@
+#! /bin/sh
+echo -en '\e]2;'"$*"'\e\\'
diff --git a/xterm-wrapper b/xterm-wrapper
new file mode 100644
index 0000000..8383742
--- /dev/null
+++ b/xterm-wrapper
@@ -0,0 +1,6 @@
+#! /bin/sh
+
+TITLE=$1
+shift
+xterm -title $TITLE -e "$@" &
+