From 2624e483f082b443613da8ffb57521327188691e Mon Sep 17 00:00:00 2001 From: mike Date: Sun, 13 Jan 2002 20:21:08 +0000 Subject: Implement the POSIX 1003.1-2001 -r and -t options in at(1). Fix some minor issues in the rest of the source and manual. Submitted by: Joe Halpin Obtained from: touch(1) (partially) MFC after: 1 month --- usr.bin/at/at.c | 97 +++++++++++++++++++++++++++++++++++++++++++++++++++--- usr.bin/at/at.man | 62 ++++++++++++++++++++++++++++++++-- usr.bin/at/panic.c | 2 ++ usr.bin/at/panic.h | 22 +++---------- 4 files changed, 157 insertions(+), 26 deletions(-) (limited to 'usr.bin') diff --git a/usr.bin/at/at.c b/usr.bin/at/at.c index a9749ce..84198d9 100644 --- a/usr.bin/at/at.c +++ b/usr.bin/at/at.c @@ -121,6 +121,7 @@ static char *cwdname(void); static void writefile(time_t runtimer, char queue); static void list_jobs(void); static long nextjob(void); +static time_t ttime(const char *arg); /* Signal catching functions */ @@ -592,6 +593,77 @@ process_jobs(int argc, char **argv, int what) } } /* 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]"); +} + int main(int argc, char **argv) { @@ -601,10 +673,11 @@ main(int argc, char **argv) char *pgm; int program = AT; /* our default program */ - const char *options = "q:f:mvldbVc";/* default options for at */ + const char *options = "q:f:t:rmvldbVc"; /* default options for at */ int disp_version = 0; time_t timer; + timer = -1; RELINQUISH_PRIVS /* Eat any leading paths @@ -660,6 +733,10 @@ main(int argc, char **argv) break; case 'd': + warnx("-d is deprecated; use -r instead"); + /* fall through to 'r' */ + + case 'r': if (program != AT) usage(); @@ -667,6 +744,12 @@ main(int argc, char **argv) options = "V"; break; + case 't': + if (program != AT) + usage(); + timer = ttime(optarg); + break; + case 'l': if (program != AT) usage(); @@ -700,9 +783,7 @@ main(int argc, char **argv) */ if (disp_version) - fprintf(stderr, "%s version " VERSION "\n" - "Bug reports to: ig25@rz.uni-karlsruhe.de (Thomas Koenig)\n", - namep); + fprintf(stderr, "%s version " VERSION "\n", namep); /* select our program */ @@ -729,7 +810,13 @@ main(int argc, char **argv) break; case AT: - timer = parsetime(argc, argv); + /* + * 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) + timer = parsetime(argc, argv); + if (atverify) { struct tm *tm = localtime(&timer); diff --git a/usr.bin/at/at.man b/usr.bin/at/at.man index b8fc994..771cce0 100644 --- a/usr.bin/at/at.man +++ b/usr.bin/at/at.man @@ -1,5 +1,5 @@ .\" $FreeBSD$ -.Dd April 12, 1995 +.Dd January 13, 2002 .Dt "AT" 1 .Os .Sh NAME @@ -17,7 +17,16 @@ .Ar time .Nm at .Op Fl V +.Op Fl q Ar queue +.Op Fl f Ar file +.Op Fl mldbv +.Fl t Ar [[CC]YY]MMDDhhmm[.SS] +.Nm at +.Op Fl V .Fl c Ar job Op Ar job ... +.Nm at +.Op Fl V +.Fl r Ar job Op Ar job ... .Pp .Nm atq .Op Fl V @@ -116,6 +125,12 @@ to run a job at 10:00am on July 31, you would do and to run a job at 1am tomorrow, you would do .Nm at Ar 1am tomorrow . .Pp +The +.Nm at +utility also supports the POSIX time format (see +.Fl t +option). +.Pp For both .Nm and @@ -215,7 +230,10 @@ Is an alias for .Nm atq . .It Fl d Is an alias for -.Nm atrm . +.Nm atrm +(this option is deprecated; use +.Fl r +instead). .It Fl b Is an alias for .Nm batch . @@ -226,6 +244,40 @@ shows completed but not yet deleted jobs in the queue; otherwise shows the time the job will be executed. .It Fl c Cat the jobs listed on the command line to standard output. +.It Fl r +Remove specified job(s). +.It Fl t +Specify the job time using the POSIX time format. +The argument should be in the form +.Dq [[CC]YY]MMDDhhmm[.SS] +where each pair of letters represents the following: +.Pp +.Bl -tag -width Ds -compact -offset indent +.It Ar CC +The first two digits of the year (the century). +.It Ar YY +The second two digits of the year. +.It Ar MM +The month of the year, from 1 to 12. +.It Ar DD +the day of the month, from 1 to 31. +.It Ar hh +The hour of the day, from 0 to 23. +.It Ar mm +The minute of the hour, from 0 to 59. +.It Ar SS +The second of the minute, from 0 to 61. +.El +.Pp +If the +.Dq CC +and +.Dq YY +letter pairs are not specified, the values default to the current +year. +If the +.Dq SS +letter pair is not specified, the value defaults to 0. .El .Sh FILES .Bl -tag -width _ATJOB_DIR/_LOCKFILE -compact @@ -268,8 +320,12 @@ resources. If this is the case for your site, you might want to consider another batch system, such as .Em nqs . +.Pp +Specificing a date past 2038 may not work on some systems. .Sh AUTHORS At was mostly written by .An Thomas Koenig Aq ig25@rz.uni-karlsruhe.de . The time parsing routines are by -.An David Parsons Aq orc@pell.chi.il.us . +.An David Parsons Aq orc@pell.chi.il.us , +with minor enhancements by +.An Joe Halpin Aq joe.halpin@attbi.com . diff --git a/usr.bin/at/panic.c b/usr.bin/at/panic.c index 8921e11..99cf512 100644 --- a/usr.bin/at/panic.c +++ b/usr.bin/at/panic.c @@ -81,6 +81,8 @@ usage(void) /* Print usage and exit. */ fprintf(stderr, "usage: at [-V] [-q x] [-f file] [-m] time\n" " at [-V] -c job [job ...]\n" + " at [-V] [-f file] -t [[CC]YY]MMDDhhmm[.SS]\n" + " at [-V] -r job [job ...]\n" " atq [-V] [-q x] [-v]\n" " atrm [-V] job [job ...]\n" " batch [-V] [-f file] [-m]\n"); diff --git a/usr.bin/at/panic.h b/usr.bin/at/panic.h index ff6c110..832de83 100644 --- a/usr.bin/at/panic.h +++ b/usr.bin/at/panic.h @@ -25,22 +25,8 @@ * $FreeBSD$ */ -#ifdef __FreeBSD__ -#define __NORETURN -#endif +#include -void -#ifdef __GNUC__ -__NORETURN -#endif -panic(const char *a); -void -#ifdef __GNUC__ -__NORETURN -#endif -perr(const char *a); -void -#ifdef __GNUC__ -__NORETURN -#endif -usage(void); +void panic(const char *a) __dead2; +void perr(const char *a) __dead2; +void usage(void) __dead2; -- cgit v1.1