From 769e1e4079dc1027c93b02399a4bbc9f42fd9c61 Mon Sep 17 00:00:00 2001 From: millert Date: Mon, 13 Jan 2014 23:18:57 +0000 Subject: [PATCH] Add the "next" keyword as an alias for "+ 1" for relative times. Also support "months" and "years" keywords when specified as relative time units. All as per POSIX. Man page changes OK jmc@ sobrado@ --- usr.bin/at/at.1 | 22 +++++++++------ usr.bin/at/parsetime.c | 63 +++++++++++++++++++++++++++++------------- 2 files changed, 58 insertions(+), 27 deletions(-) diff --git a/usr.bin/at/at.1 b/usr.bin/at/at.1 index 30147734d64..02e9644b88d 100644 --- a/usr.bin/at/at.1 +++ b/usr.bin/at/at.1 @@ -1,4 +1,4 @@ -.\" $OpenBSD: at.1,v 1.47 2014/01/09 21:22:49 jmc Exp $ +.\" $OpenBSD: at.1,v 1.48 2014/01/13 23:18:57 millert Exp $ .\" .\" Copyright (C) 1993, 1994 Thomas Koenig .\" Copyright (C) 1993 David Parsons @@ -24,7 +24,7 @@ .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. .\" -.Dd $Mdocdate: January 9 2014 $ +.Dd $Mdocdate: January 13 2014 $ .Dt AT 1 .Os .Sh NAME @@ -210,14 +210,21 @@ where the time-units can be .Sy minutes , .Sy hours , .Sy days , +.Sy weeks , +.Sy months , or -.Sy weeks -and you can tell +.Sy years +(the singular forms are also accepted). +You can tell .Nm at to run the job today by suffixing the time with .Sy today and to run the job tomorrow by suffixing the time with .Sy tomorrow . +The +.Sy next +keyword may be used as an alias for +.Sy + 1 . .Pp For example, to run a job at 4pm three days from now, you would do .Ic at 4pm + 3 days . @@ -225,6 +232,8 @@ To run a job at 10:00am on July 31, you would do .Ic at 10am Jul 31 . To run a job at 1am tomorrow, you would do .Ic at 1am tomorrow . +To run a job at midnight in one week's time, you would do +.Ic at midnight next week . .Pp The .Nm at @@ -358,10 +367,7 @@ this implementation permits a argument. The .Sy teatime -keyword is an extension to the specification, -and this implementation does not support the -.Sy next -keyword. +keyword is an extension to the specification. .Sh AUTHORS .An -nosplit .Nm at diff --git a/usr.bin/at/parsetime.c b/usr.bin/at/parsetime.c index e489e53d487..f4208345166 100644 --- a/usr.bin/at/parsetime.c +++ b/usr.bin/at/parsetime.c @@ -1,4 +1,4 @@ -/* $OpenBSD: parsetime.c,v 1.19 2013/11/25 18:02:50 deraadt Exp $ */ +/* $OpenBSD: parsetime.c,v 1.20 2014/01/13 23:18:57 millert Exp $ */ /* * parsetime.c - parse time for at(1) @@ -27,12 +27,12 @@ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * - * at [NOW] PLUS NUMBER MINUTES|HOURS|DAYS|WEEKS + * at [NOW] PLUS NUMBER MINUTES|HOURS|DAYS|WEEKS|MONTHS|YEARS * /NUMBER [DOT NUMBER] [AM|PM]\ /[MONTH NUMBER [NUMBER]] \ * |NOON | |[TOMORROW] | * |MIDNIGHT | |[DAY OF WEEK] | * \TEATIME / |NUMBER [SLASH NUMBER [SLASH NUMBER]]| - * \PLUS NUMBER MINUTES|HOURS|DAYS|WEEKS/ + * \PLUS NUMBER MINUTES|HOURS|DAYS|WEEKS|MONTHS|YEARS/ */ #include @@ -53,8 +53,8 @@ enum { /* symbols */ MIDNIGHT, NOON, TEATIME, PM, AM, TOMORROW, TODAY, NOW, - MINUTES, HOURS, DAYS, WEEKS, - NUMBER, PLUS, DOT, SLASH, ID, JUNK, + MINUTES, HOURS, DAYS, WEEKS, MONTHS, YEARS, + NUMBER, NEXT, PLUS, DOT, SLASH, ID, JUNK, JAN, FEB, MAR, APR, MAY, JUN, JUL, AUG, SEP, OCT, NOV, DEC, SUN, MON, TUE, WED, THU, FRI, SAT @@ -76,6 +76,7 @@ struct { { "tomorrow", TOMORROW, 0 }, /* execute 24 hours from time */ { "today", TODAY, 0 }, /* execute today - don't advance time */ { "now", NOW, 0 }, /* opt prefix for PLUS */ + { "next", NEXT, 0 }, /* opt prefix for + 1 */ { "minute", MINUTES, 0 }, /* minutes multiplier */ { "min", MINUTES, 0 }, @@ -91,6 +92,13 @@ struct { { "week", WEEKS, 0 }, /* week ... */ { "w", WEEKS, 0 }, { "weeks", WEEKS, 1 }, /* (pluralized) */ + { "month", MONTHS, 0 }, /* month ... */ + { "mo", MONTHS, 0 }, + { "mth", MONTHS, 0 }, + { "months", MONTHS, 1 }, /* (pluralized) */ + { "year", YEARS, 0 }, /* year ... */ + { "y", YEARS, 0 }, + { "years", YEARS, 1 }, /* (pluralized) */ { "jan", JAN, 0 }, { "feb", FEB, 0 }, { "mar", MAR, 0 }, @@ -319,36 +327,50 @@ dateadd(int minutes, struct tm *tm) /* * plus() parses a now + time * - * at [NOW] PLUS NUMBER [MINUTES|HOURS|DAYS|WEEKS] + * at [NOW] PLUS NUMBER [MINUTES|HOURS|DAYS|WEEKS|MONTHS|YEARS] * */ static int plus(struct tm *tm) { - int delay; + int increment; int expectplur; - if (expect(NUMBER) != 0) - return (-1); - - delay = atoi(sc_token); - expectplur = (delay != 1) ? 1 : 0; + if (sc_tokid == NEXT) { + increment = 1; + expectplur = 0; + } else { + if (expect(NUMBER) != 0) + return (-1); + increment = atoi(sc_token); + expectplur = (increment != 1) ? 1 : 0; + } switch (token()) { + case YEARS: + tm->tm_year += increment; + return (0); + case MONTHS: + tm->tm_mon += increment; + while (tm->tm_mon >= 12) { + tm->tm_year++; + tm->tm_mon -= 12; + } + return (0); case WEEKS: - delay *= 7; + increment *= 7; /* FALLTHROUGH */ case DAYS: - delay *= 24; + increment *= 24; /* FALLTHROUGH */ case HOURS: - delay *= 60; + increment *= 60; /* FALLTHROUGH */ case MINUTES: if (expectplur != sc_tokplur) fprintf(stderr, "%s: pluralization is wrong\n", ProgramName); - dateadd(delay, tm); + dateadd(increment, tm); return (0); } @@ -411,7 +433,8 @@ tod(struct tm *tm) * if we've gone past that time - but if we're specifying a time plus * a relative offset, it's okay to bump things */ - if ((sc_tokid == EOF || sc_tokid == PLUS) && tm->tm_hour > hour) { + if ((sc_tokid == EOF || sc_tokid == PLUS || sc_tokid == NEXT) && + tm->tm_hour > hour) { tm->tm_mday++; tm->tm_wday++; } @@ -473,7 +496,7 @@ assign_date(struct tm *tm, int mday, int mon, int year) * |[TOMORROW] | * |[DAY OF WEEK] | * |NUMBER [SLASH NUMBER [SLASH NUMBER]]| - * \PLUS NUMBER MINUTES|HOURS|DAYS|WEEKS/ + * \PLUS NUMBER MINUTES|HOURS|DAYS|WEEKS|MONTHS|YEARS/ */ static int month(struct tm *tm) @@ -483,6 +506,7 @@ month(struct tm *tm) size_t tlen; switch (sc_tokid) { + case NEXT: case PLUS: if (plus(tm) != 0) return (-1); @@ -621,8 +645,9 @@ parsetime(int argc, char **argv) runtime = nowtime; break; } - else if (sc_tokid != PLUS) + else if (sc_tokid != PLUS && sc_tokid != NEXT) plonk(sc_tokid); + case NEXT: case PLUS: if (plus(&runtime) != 0) return (-1); -- 2.20.1