diff -ruN at-2.9a.orig/atrun.c at-2.9a/atrun.c
--- at-2.9a.orig/atrun.c	Thu Aug 17 23:19:28 1995
+++ at-2.9a/atrun.c	Sat Oct 28 16:10:07 1995
@@ -389,6 +389,9 @@
     if (chdir(ATJOB_DIR) != 0)
 	perr("Cannot change to " ATJOB_DIR);
 
+    if (optind < argc)
+	perr("non-option arguments - not allowed");
+
     /* Main loop. Open spool directory for reading and look over all the
      * files in there. If the filename indicates that the job should be run
      * and the x bit is set, fork off a child which sets its user and group
diff -ruN at-2.9a.orig/debian.Changelog at-2.9a/debian.Changelog
--- at-2.9a.orig/debian.Changelog	Thu Jan  1 01:00:00 1970
+++ at-2.9a/debian.Changelog	Sat Oct 28 16:25:52 1995
@@ -0,0 +1,39 @@
+at (2.9a-1); priority=LOW
+
+  * Upgraded to upstream version 2.9a:
+   - Should fix segfault in `at' date parsing.  (Bug#1743, 1756.)
+   - Output mail messages use `mail' rather than `rmail'.
+  * Recommended field entries to do with mail fixed.  (Bug#1423.)
+  * Changed atrun entry in crontab to use -l and `atrun' to complain
+    about non-option arguments rather than ignoring them.  (Bug#1736.)
+
+ -- Ian Jackson <iwj10@cus.cam.ac.uk>  Sat, 28 Oct 1995 16:23:44 +0000
+
+at (2.8a-2); priority=LOW
+
+  * Added extended description.
+  * Fixed $(IROOT) occurrences in manpages.
+  * Fixed minor security misfeature (atrun runs with gid 0 instead
+    of gid daemon).
+
+ -- Ian Jackson <iwj10@cus.cam.ac.uk>  Wed, 28 Jun 1995 13:10:33 +0100
+
+at (2.8a-1); priority=MEDIUM
+
+  * Upgraded to upstream version 2.8a from 2.7a - fixes security
+    hole that enables `daemon' to become `root', and adds some
+    very minor features.
+
+ -- Ian Jackson <iwj10@cus.cam.ac.uk>  Fri, 2 Jun 1995 19:41:53 +0100
+
+At 2.7a Debian 5 - iwj
+
+* DAEMON_UID and DAEMON_GID changed to 1.
+* MAIL_CMD changed from /bin/rmail to /usr/sbin/rmail.
+
+At 2.7a Debian 4 - iwj
+
+No Changelog entries recorded.
+
+At 2.7a Debian 3 - iwj
+Package first taken over by me, Ian Jackson.
diff -ruN at-2.9a.orig/debian.README at-2.9a/debian.README
--- at-2.9a.orig/debian.README	Thu Jan  1 01:00:00 1970
+++ at-2.9a/debian.README	Sat Oct 28 16:12:34 1995
@@ -0,0 +1,28 @@
+This is Debian/GNU Linux's prepackaged version of Thomas Koenig's at package.
+
+This package was put together by me, Ian Jackson <ijackson@nyx.cs.du.edu>, from
+the Linux-specific sources to 2.7a, as distributed on sunsite.unc.edu in
+/pub/Linux/system/Daemons.
+
+The changes are essentially the configuration for Debian GNU/Linux and the
+addition of support for the Debian package maintenance scheme in the form of
+various debian.* files and directories.  The configuration was not done by
+using the provided Configure script - instead, a separate handwritten sed file
+is provided in debian.subs.
+
+Copyright (C) 1993, 1994 Thomas Koenig; Copyright (C) 1993 David Parsons;
+Modifications for Debian GNU/Linux Copyright 1994 Ian Jackson.
+
+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 with
+your Debian GNU/Linux system, in /usr/doc/copyright/GPL.  If not,
+write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge,
+MA 02139, USA.
diff -ruN at-2.9a.orig/debian.atdeny at-2.9a/debian.atdeny
--- at-2.9a.orig/debian.atdeny	Thu Jan  1 01:00:00 1970
+++ at-2.9a/debian.atdeny	Sat Oct 28 16:12:34 1995
@@ -0,0 +1,13 @@
+nobody
+bin
+daemon
+sys
+lp
+sync
+mail
+news
+uucp
+games
+man
+guest
+ftp
diff -ruN at-2.9a.orig/debian.conffiles at-2.9a/debian.conffiles
--- at-2.9a.orig/debian.conffiles	Thu Jan  1 01:00:00 1970
+++ at-2.9a/debian.conffiles	Sat Oct 28 16:12:34 1995
@@ -0,0 +1,2 @@
+/etc/at.allow
+/etc/at.deny
diff -ruN at-2.9a.orig/debian.control at-2.9a/debian.control
--- at-2.9a.orig/debian.control	Thu Jan  1 01:00:00 1970
+++ at-2.9a/debian.control	Sat Oct 28 16:23:55 1995
@@ -0,0 +1,14 @@
+Package: at
+Version: =
+Package_Revision: =
+Maintainer: Ian Jackson <iwj10@cus.cam.ac.uk>
+Depends: cron, bsdutils
+Recommended: smail | sendmail | mail-transfer-agent, mailx
+Description: delayed job execution and batch processing
+ at and batch read commands which are to be executed later.
+ .
+ at is used to run a command at some specified future time,
+ and batch is used to run a command when system load levels permit.
+ .
+ The at system uses cron to get the commands executed, so you
+ need cron to use at.
diff -ruN at-2.9a.orig/debian.postinst at-2.9a/debian.postinst
--- at-2.9a.orig/debian.postinst	Thu Jan  1 01:00:00 1970
+++ at-2.9a/debian.postinst	Sat Oct 28 16:14:38 1995
@@ -0,0 +1,42 @@
+#!/usr/bin/perl --
+
+$|=1;
+
+$etc='/etc';
+
+$re='(\*\s+){4}(\*|\d+)\s+root\s+atrun\s';
+
+open(OI,"$etc/crontab") || die "Opening $etc/crontab to deinstall atrun: $!\n";
+@crontab=<OI>;
+close(OI);
+$newentry="* *\t* * *\troot\tatrun -d -l 0.5\n";
+
+$mod=0; $found=0; # 0:none 1:one-commented 2:more-commented 3:uncommented
+for ($i=0; $i<=$#crontab; $i++) {
+    $_= $crontab[$i];
+    if (m/^#\s*$re/o && $found<3) {
+        $at=$i; $found++ if $found<2;
+    } elsif (m/^$re/o) {
+        print STDERR "Warning - found existing `atrun' entry in $etc/crontab;\n".
+                     " `at' may have once been improperly deinstalled.\n";
+        exit(0);
+    }
+}
+if ($found==0) {
+    push(@crontab, $newentry);
+} else {    
+    $crontab[$at] =~ s/^#\s*//;
+    if ($found==2) {
+        print STDERR "Warning - found several commented out `atrun' entries,\n".
+                     " using the last one found, which was:\n".
+                     "  $crontab[$at]";
+    }
+}
+
+open(N,">$etc/crontab.postinstnew") || die "Error creating new crontab: $!\n";
+print(N @crontab) || die "Error writing new crontab: $!\n";
+close(N) || die "Error closing new crontab: $!\n";
+rename("$etc/crontab.postinstnew","$etc/crontab") ||
+    die "Error installing new $etc/crontab: $!\n";
+
+exit 0;
diff -ruN at-2.9a.orig/debian.prerm at-2.9a/debian.prerm
--- at-2.9a.orig/debian.prerm	Thu Jan  1 01:00:00 1970
+++ at-2.9a/debian.prerm	Sat Oct 28 16:16:29 1995
@@ -0,0 +1,24 @@
+#!/usr/bin/perl --
+
+$etc='/etc';
+
+$re='(\*\s+){4}(\*|\d+)\s+root\s+atrun\s';
+
+open(OI,"$etc/crontab") || die "Opening $etc/crontab to deinstall atrun: $!\n";
+open(NI,">$etc/crontab.prermnew") || die "Creating new crontab: $!\n";
+while(<OI>) {
+    if (m/^#\s*$re/o) { $mod=1; s/^#\s*/#was:#/; s/\s*\t\s*/ /;}
+    elsif (m/^$re/o) { $mod=1; s/^/#/; s/ -d (\d+(\.\d+))/ -d -l $1/; }
+    print NI || die "Writing new crontab: $!\n";
+}
+close(NI) || die "Closing new crontab: $!\n";
+if ($mod) {
+    rename("$etc/crontab.prermnew","$etc/crontab") ||
+        die "Installing new crontab: $!\n"; # 
+} else {
+    unlink("$etc/crontab.prermnew") || die "Aborting new crontab: $!\n";
+    print STDERR "Warning - no `atrun' entry found in system crontab.\n".
+        " `at' package may not have been properly deinstalled.\n";
+}
+
+exit 0;
diff -ruN at-2.9a.orig/debian.rules at-2.9a/debian.rules
--- at-2.9a.orig/debian.rules	Thu Jan  1 01:00:00 1970
+++ at-2.9a/debian.rules	Sat Oct 28 16:26:35 1995
@@ -0,0 +1,62 @@
+#!/usr/bin/make -f
+
+package=at
+version=2.9a
+debian=1
+
+build:
+	$(checkdir)
+	sed -f debian.subs Makefile.in > Makefile.debian-tmp
+	$(MAKE) -f Makefile.debian-tmp
+	touch build
+
+clean:
+	$(checkdir)
+	-rm -f build
+	$(MAKE) -f Makefile.in clean
+	-rm -rf debian-tmp ./#*# Makefile.debian-tmp
+
+binary:		checkroot build
+	-rm -rf debian-tmp
+	mkdir debian-tmp debian-tmp/DEBIAN
+	install -d debian-tmp/usr/{doc/copyright,sbin,bin}
+	install -d debian-tmp/usr/man/{man1,man8} debian-tmp/etc
+	sed -e '2s/=/$(version)/; 3s/=/$(debian)/' \
+		debian.control > debian-tmp/DEBIAN/control
+	cp debian.postinst debian-tmp/DEBIAN/postinst
+	cp debian.prerm debian-tmp/DEBIAN/prerm
+	cp debian.conffiles debian-tmp/DEBIAN/conffiles
+	chmod +x debian-tmp/DEBIAN/{postinst,prerm}
+	$(MAKE) -f Makefile.debian-tmp IROOT=debian-tmp install
+	install -m 644 debian.atdeny debian-tmp/etc/at.deny
+	cp debian.README debian-tmp/usr/doc/copyright/at
+	for f in batch atq atrm; do ln -sf at debian-tmp/usr/bin/$$f; done
+	chown -R root.root debian-tmp
+	chmod -R g-ws,u+w,a+r debian-tmp
+	find debian-tmp -type d | xargs chmod a+x
+	chmod 700 debian-tmp/var/spool/cron/at{jobs,spool}
+	chown daemon.daemon debian-tmp/var/spool/cron/at{jobs,spool}
+	dpkg --build debian-tmp
+	mv debian-tmp.deb ../at-$(version)-$(debian).deb
+
+define checkdir
+	test -f at.c
+endef
+
+source:		clean
+	chmod +x debian.rules
+	cd .. && \
+	tar cf $(package)-$(version)-$(debian).tar $(package)-$(version) && \
+	gzip -9vf $(package)-$(version)-$(debian).tar
+ 
+diff:		clean
+	cd .. && \
+	(diff -ruN $(package)-$(version).orig $(package)-$(version) \
+	 >$(package)-$(version)-$(debian).diff; [ $$? = 1 ]) && \
+	gzip -9vf $(package)-$(version)-$(debian).diff
+
+checkroot:
+	$(checkdir)
+	test root = "`whoami`"
+
+.PHONY: binary source diff clean checkroot
diff -ruN at-2.9a.orig/debian.subs at-2.9a/debian.subs
--- at-2.9a.orig/debian.subs	Thu Jan  1 01:00:00 1970
+++ at-2.9a/debian.subs	Sat Oct 28 16:12:34 1995
@@ -0,0 +1,26 @@
+s:_LOADAVG_MX:0.5:g
+s:_DEFAULT_AT_QUEUE:c:g
+s:_DEFAULT_BATCH_QUEUE:E:g
+
+s:^CC = cc:CC=gcc:
+s:_DEBUG::g
+s:_SYMB:-s:g
+
+s:_UID_STRING:daemon:g
+s:_GID_STRING:daemon:g
+s:_DAEMON_UID:1:g
+s:_DAEMON_GID:1:g
+
+s:_MAIL_CMD:/usr/sbin/rmail:g
+s:_PROC_DIR:/proc:g
+
+s:_PERM_PATH:$(IROOT)/etc:g
+s:_BIN_DIR:$(IROOT)/usr/bin:g
+s:_MAN_DIR:$(IROOT)/usr/man:g
+s:_ATLIB_DIR:$(IROOT)/usr/sbin:g
+s:_ATJOB_DIR:$(IROOT)/var/spool/cron/atjobs:g
+s:_ATSPOOL_DIR:$(IROOT)/var/spool/cron/atspool:g
+
+s:-g bin:-g root:g
+s:subs\.sed:debian.subs -e 's/$$(IROOT)//':g
+s: -O -Wall : -O2 -Wall -s :g
diff -ruN at-2.9a.orig/privs.h at-2.9a/privs.h
--- at-2.9a.orig/privs.h	Tue Aug  8 16:24:55 1995
+++ at-2.9a/privs.h	Sat Oct 28 16:12:41 1995
@@ -72,8 +72,8 @@
 			      effective_uid = geteuid(); \
 			      real_gid = getgid(); \
 			      effective_gid = getegid(); \
-			      setreuid(effective_uid, real_uid); \
 			      setregid(effective_gid, real_gid); \
+			      setreuid(effective_uid, real_uid); \
 		          }
 
 #define RELINQUISH_PRIVS_ROOT(a,b) { \
diff -ruN at-2.9a.orig/privs.h.orig at-2.9a/privs.h.orig
--- at-2.9a.orig/privs.h.orig	Thu Jan  1 01:00:00 1970
+++ at-2.9a/privs.h.orig	Tue Aug  8 16:24:55 1995
@@ -0,0 +1,105 @@
+/* 
+ *  privs.h - header for privileged operations 
+ *  Copyright (C) 1993  Thomas Koenig
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#ifndef _PRIVS_H
+#define _PRIVS_H
+
+#ifndef _USE_BSD
+#define _USE_BSD 1
+#include <unistd.h>
+#undef _USE_BSD
+#else
+#include <unistd.h>
+#endif
+
+/* Relinquish privileges temporarily for a setuid or setgid program
+ * with the option of getting them back later.  This is done by swapping
+ * the real and effective userid BSD style.  Call RELINQUISH_PRIVS once
+ * at the beginning of the main program.  This will cause all operatons
+ * to be executed with the real userid.  When you need the privileges
+ * of the setuid/setgid invocation, call PRIV_START; when you no longer
+ * need it, call PRIV_END.  Note that it is an error to call PRIV_START
+ * and not PRIV_END within the same function.
+ *
+ * Use RELINQUISH_PRIVS_ROOT(a,b) if your program started out running
+ * as root, and you want to drop back the effective userid to a
+ * and the effective group id to b, with the option to get them back
+ * later.
+ *
+ * If you no longer need root privileges, but those of some other
+ * userid/groupid, you can call REDUCE_PRIV(a,b) when your effective
+ * is the user's.
+ *
+ * Problems: Do not use return between PRIV_START and PRIV_END; this
+ * will cause the program to continue running in an unprivileged
+ * state.
+ *
+ * It is NOT safe to call exec(), system() or popen() with a user-
+ * supplied program (i.e. without carefully checking PATH and any
+ * library load paths) with relinquished privileges; the called program
+ * can aquire them just as easily.  Set both effective and real userid
+ * to the real userid before calling any of them.
+ */
+
+#ifndef MAIN
+extern
+#endif
+uid_t real_uid, effective_uid;
+
+#ifndef MAIN 
+extern
+#endif
+gid_t real_gid, effective_gid;
+
+#define RELINQUISH_PRIVS { \
+			      real_uid = getuid(); \
+			      effective_uid = geteuid(); \
+			      real_gid = getgid(); \
+			      effective_gid = getegid(); \
+			      setreuid(effective_uid, real_uid); \
+			      setregid(effective_gid, real_gid); \
+		          }
+
+#define RELINQUISH_PRIVS_ROOT(a,b) { \
+			      real_uid = (a); \
+			      effective_uid = geteuid(); \
+			      real_gid = (b); \
+			      effective_gid = getegid(); \
+			      setregid(effective_gid, real_gid); \
+			      setreuid(effective_uid, real_uid); \
+		          }
+
+#define PRIV_START {\
+		    setreuid(real_uid, effective_uid); \
+		    setregid(real_gid, effective_gid);
+
+#define PRIV_END \
+		    setregid(effective_gid, real_gid); \
+		    setreuid(effective_uid, real_uid); \
+		    }
+
+#define REDUCE_PRIV(a,b) {\
+			setreuid(real_uid, effective_uid); \
+			setregid(real_gid, effective_gid); \
+			effective_uid = (a); \
+			effective_gid = (b); \
+			setregid(effective_gid, real_gid); \
+			setreuid(effective_uid, real_uid); \
+		    }
+#endif
