-.\" $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
.\" (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
.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 .
.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
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
-/* $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)
* (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 <sys/types.h>
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
{ "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 },
{ "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 },
/*
* 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);
}
* 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++;
}
* |[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)
size_t tlen;
switch (sc_tokid) {
+ case NEXT:
case PLUS:
if (plus(tm) != 0)
return (-1);
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);