2010-09-28 20:34:15 +00:00
|
|
|
--- at.1.in.orig
|
2006-12-18 17:51:26 +00:00
|
|
|
+++ at.1.in
|
2010-09-28 20:34:15 +00:00
|
|
|
@@ -9,7 +9,7 @@ at, batch, atq, atrm \- queue, examine o
|
2006-12-18 17:51:26 +00:00
|
|
|
.IR queue ]
|
|
|
|
.RB [ -f
|
|
|
|
.IR file ]
|
|
|
|
-.RB [ -mldrbv ]
|
|
|
|
+.RB [ -mldrbvt ]
|
|
|
|
.B TIME
|
|
|
|
.br
|
|
|
|
.B "at -c"
|
2010-09-28 20:34:15 +00:00
|
|
|
@@ -235,6 +235,9 @@ is set; then, it will be "Thu Feb 20 14:
|
2006-12-18 17:51:26 +00:00
|
|
|
.B
|
|
|
|
\-c
|
|
|
|
cats the jobs listed on the command line to standard output.
|
|
|
|
+.TP
|
|
|
|
+.B \-t time_arg
|
|
|
|
+Specify the time to run in a format compatible with the touch -t time command.
|
|
|
|
.SH FILES
|
|
|
|
.I @ATJBD@
|
|
|
|
.br
|
2010-09-28 20:34:15 +00:00
|
|
|
--- at.c.orig
|
2006-12-18 17:51:26 +00:00
|
|
|
+++ at.c
|
|
|
|
@@ -28,6 +28,7 @@
|
|
|
|
|
|
|
|
#include <sys/types.h>
|
|
|
|
#include <sys/stat.h>
|
|
|
|
+#include <sys/time.h>
|
|
|
|
|
|
|
|
#ifdef HAVE_SYS_WAIT_H
|
|
|
|
#include <sys/wait.h>
|
2010-09-28 20:34:15 +00:00
|
|
|
@@ -133,6 +134,7 @@ static void alarmc(int signo);
|
2006-12-18 17:51:26 +00:00
|
|
|
static char *cwdname(void);
|
|
|
|
static void writefile(time_t runtimer, char queue);
|
|
|
|
static void list_jobs(void);
|
|
|
|
+static time_t ttime(const char *arg);
|
|
|
|
|
|
|
|
/* Signal catching functions */
|
|
|
|
|
2010-09-28 20:34:15 +00:00
|
|
|
@@ -670,6 +672,78 @@ process_jobs(int argc, char **argv, int
|
2006-12-18 17:51:26 +00:00
|
|
|
}
|
|
|
|
} /* delete_jobs */
|
|
|
|
|
|
|
|
+#define ATOI2(ar) ((ar)[0] - '0') * 10 + ((ar)[1] - '0'); (ar) += 2;
|
|
|
|
+
|
|
|
|
+static time_t
|
|
|
|
+ttime(const char *arg)
|
|
|
|
+{
|
|
|
|
+ /*
|
|
|
|
+ * This is pretty much a copy of stime_arg1() from touch.c. I changed
|
|
|
|
+ * the return value and the argument list because it's more convenient
|
|
|
|
+ * (IMO) to do everything in one place. - Joe Halpin
|
|
|
|
+ */
|
|
|
|
+ struct timeval tv[2];
|
|
|
|
+ time_t now;
|
|
|
|
+ struct tm *t;
|
|
|
|
+ int yearset;
|
|
|
|
+ char *p;
|
|
|
|
+
|
|
|
|
+ if (gettimeofday(&tv[0], NULL))
|
|
|
|
+ panic("Cannot get current time");
|
|
|
|
+
|
|
|
|
+ /* Start with the current time. */
|
|
|
|
+ now = tv[0].tv_sec;
|
|
|
|
+ if ((t = localtime(&now)) == NULL)
|
|
|
|
+ panic("localtime");
|
|
|
|
+ /* [[CC]YY]MMDDhhmm[.SS] */
|
|
|
|
+ if ((p = strchr(arg, '.')) == NULL)
|
|
|
|
+ t->tm_sec = 0; /* Seconds defaults to 0. */
|
|
|
|
+ else {
|
|
|
|
+ if (strlen(p + 1) != 2)
|
|
|
|
+ goto terr;
|
|
|
|
+ *p++ = '\0';
|
|
|
|
+ t->tm_sec = ATOI2(p);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ yearset = 0;
|
|
|
|
+ switch(strlen(arg)) {
|
|
|
|
+ case 12: /* CCYYMMDDhhmm */
|
|
|
|
+ t->tm_year = ATOI2(arg);
|
|
|
|
+ t->tm_year *= 100;
|
|
|
|
+ yearset = 1;
|
|
|
|
+ /* FALLTHROUGH */
|
|
|
|
+ case 10: /* YYMMDDhhmm */
|
|
|
|
+ if (yearset) {
|
|
|
|
+ yearset = ATOI2(arg);
|
|
|
|
+ t->tm_year += yearset;
|
|
|
|
+ } else {
|
|
|
|
+ yearset = ATOI2(arg);
|
|
|
|
+ t->tm_year = yearset + 2000;
|
|
|
|
+ }
|
|
|
|
+ t->tm_year -= 1900; /* Convert to UNIX time. */
|
|
|
|
+ /* FALLTHROUGH */
|
|
|
|
+ case 8: /* MMDDhhmm */
|
|
|
|
+ t->tm_mon = ATOI2(arg);
|
|
|
|
+ --t->tm_mon; /* Convert from 01-12 to 00-11 */
|
|
|
|
+ t->tm_mday = ATOI2(arg);
|
|
|
|
+ t->tm_hour = ATOI2(arg);
|
|
|
|
+ t->tm_min = ATOI2(arg);
|
|
|
|
+ break;
|
|
|
|
+ default:
|
|
|
|
+ goto terr;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ t->tm_isdst = -1; /* Figure out DST. */
|
|
|
|
+ tv[0].tv_sec = tv[1].tv_sec = mktime(t);
|
|
|
|
+ if (tv[0].tv_sec != -1)
|
|
|
|
+ return tv[0].tv_sec;
|
|
|
|
+ else
|
|
|
|
+terr:
|
|
|
|
+ panic(
|
|
|
|
+ "out of range or illegal time specification: [[CC]YY]MMDDhhmm[.SS]");
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+
|
|
|
|
/* Global functions */
|
|
|
|
|
|
|
|
void *
|
2010-09-28 20:34:15 +00:00
|
|
|
@@ -692,12 +766,13 @@ main(int argc, char **argv)
|
2006-12-18 17:51:26 +00:00
|
|
|
char *pgm;
|
|
|
|
|
|
|
|
int program = AT; /* our default program */
|
|
|
|
- char *options = "q:f:MmvldrhVc"; /* default options for at */
|
|
|
|
+ char *options = "q:f:t:MmvldrhVc"; /* default options for at */
|
|
|
|
int disp_version = 0;
|
|
|
|
time_t timer;
|
|
|
|
struct passwd *pwe;
|
|
|
|
struct group *ge;
|
|
|
|
|
|
|
|
+ timer = -1;
|
|
|
|
RELINQUISH_PRIVS
|
|
|
|
|
|
|
|
if ((pwe = getpwnam(DAEMON_USERNAME)) == NULL)
|
2010-09-28 20:34:15 +00:00
|
|
|
@@ -781,6 +856,13 @@ main(int argc, char **argv)
|
2006-12-18 17:51:26 +00:00
|
|
|
options = "q:V";
|
|
|
|
break;
|
|
|
|
|
|
|
|
+ case 't':
|
|
|
|
+ if (program != AT)
|
|
|
|
+ usage();
|
|
|
|
+
|
|
|
|
+ timer = ttime(optarg);
|
|
|
|
+ break;
|
|
|
|
+
|
|
|
|
case 'b':
|
|
|
|
if (program != AT)
|
|
|
|
usage();
|
2010-09-28 20:34:15 +00:00
|
|
|
@@ -834,10 +916,16 @@ main(int argc, char **argv)
|
2006-12-18 17:51:26 +00:00
|
|
|
break;
|
|
|
|
|
|
|
|
case AT:
|
|
|
|
- if (argc > optind) {
|
|
|
|
- timer = parsetime(argc - optind, argv + optind);
|
|
|
|
- } else {
|
|
|
|
- timer = 0;
|
|
|
|
+ /*
|
|
|
|
+ * If timer is > -1, then the user gave the time with -t. In that
|
|
|
|
+ * case, it's already been set. If not, set it now.
|
|
|
|
+ */
|
|
|
|
+ if (timer == -1) {
|
|
|
|
+ if (argc > optind) {
|
|
|
|
+ timer = parsetime(argc - optind, argv + optind);
|
|
|
|
+ } else {
|
|
|
|
+ timer = 0;
|
|
|
|
+ }
|
|
|
|
}
|
|
|
|
|
|
|
|
if (timer == 0) {
|
2010-09-28 20:34:15 +00:00
|
|
|
--- panic.c.orig
|
2006-12-18 17:51:26 +00:00
|
|
|
+++ panic.c
|
2010-09-28 20:34:15 +00:00
|
|
|
@@ -92,7 +92,9 @@ usage(void)
|
2006-12-18 17:51:26 +00:00
|
|
|
/* Print usage and exit.
|
|
|
|
*/
|
|
|
|
fprintf(stderr, "Usage: at [-V] [-q x] [-f file] [-m] time\n"
|
|
|
|
+ " at [-V] -c job [job ...]\n"
|
|
|
|
" at [-V] -r job [job ...]\n"
|
|
|
|
+ " at [-V] [-f file] -t [[CC]YY]MMDDhhmm[.SS]\n"
|
|
|
|
" atq [-V] [-q x]\n"
|
|
|
|
" atrm [-V] [-q x] job ...\n"
|
|
|
|
" batch [-V] [-f file] [-m]\n");
|