--- at-3.1.10/at.c.t_option 2007-07-04 11:12:10.000000000 +0200 +++ at-3.1.10/at.c 2007-07-04 11:13:19.000000000 +0200 @@ -396,8 +396,9 @@ unsigned int i; for (i = 0; i < sizeof(no_export) / sizeof(no_export[0]); i++) { export = export - && (strncmp(*atenv, no_export[i], - (size_t) (eqp - *atenv)) != 0); + && ( (((size_t) (eqp - *atenv)) != strlen(no_export[i])) + ||(strncmp(*atenv, no_export[i],(size_t) (eqp - *atenv)) != 0) + ); } eqp++; } @@ -752,6 +753,102 @@ return p; } +/* Handle POSIX.2 '-t' option : + * Parses time string in "touch(1)" format: + * [[CC]YY]MMDDhhmm[.ss] + * and returns time_t . + */ +time_t +t_option(char *s) +{ + time_t t=time(0L); + struct tm tm, tm_now=*localtime(&t); + int l; + + if((s == 0L) || (*s == '\0')) + { + return 0L; + }; + memset(&tm,'\0',sizeof(tm)); + l = strnlen(s,15); + switch(l) + { + case 15: + /* CCYYMMDDhhmm.ss */ + sscanf(s, "%4d%2d%2d%2d%2d.%2d", + &tm.tm_year, &tm.tm_mon, &tm.tm_mday, &tm.tm_hour, &tm.tm_min, &tm.tm_sec + ); + if(tm.tm_year) + tm.tm_year -= 1900 ; + + break; + + case 13: + /* YYMMDDhhmm.ss */ + sscanf(s, "%2d%2d%2d%2d%2d.%2d", + &tm.tm_year, &tm.tm_mon, &tm.tm_mday, &tm.tm_hour, &tm.tm_min, &tm.tm_sec + ); + if(tm.tm_year) + tm.tm_year += 100 ; /* Y2.1K+ bug! */ + + break; + + case 11: + /* MMDDhhmm.ss */ + sscanf(s, "%2d%2d%2d%2d.%2d", + &tm.tm_mon, &tm.tm_mday, &tm.tm_hour, &tm.tm_min, &tm.tm_sec + ); + + tm.tm_year = tm_now.tm_year; + + if(tm.tm_mon) + tm.tm_mon -= 1; + break; + + case 12: + /* CCYYMMDDhhmm */ + sscanf(s, "%4d%2d%2d%2d%2d", + &tm.tm_year, &tm.tm_mon, &tm.tm_mday, &tm.tm_hour, &tm.tm_min + ); + if(tm.tm_year) + tm.tm_year -= 1900 ; + break; + + case 10: + /* YYMMDDhhmm */ + sscanf(s, "%2d%2d%2d%2d%2d", + &tm.tm_year, &tm.tm_mon, &tm.tm_mday, &tm.tm_hour, &tm.tm_min + ); + if(tm.tm_year) + tm.tm_year += 100 ; /* Y2.1K+ bug! */ + break; + + case 8: + /* MMDDhhmm */ + sscanf(s, "%2d%2d%2d%2d", + &tm.tm_mon, &tm.tm_mday, &tm.tm_hour, &tm.tm_min + ); + if( tm.tm_mday ) + tm.tm_year = tm_now.tm_year; + break; + default: + break; + } + + if( tm.tm_mon ) + tm.tm_mon -= 1; + + if( tm.tm_mday ) + { + tm.tm_isdst = -1; + t = mktime(&tm); + return t; + } else + return 0L; +} + + + int main(int argc, char **argv) { @@ -761,9 +858,9 @@ char *pgm; int program = AT; /* our default program */ - char *options = "q:f:MmvldhVc"; /* default options for at */ + char *options = "q:f:MmvldhVct:"; /* default options for at */ int disp_version = 0; - time_t timer; + time_t timer=0L; struct passwd *pwe; struct group *ge; @@ -866,7 +963,9 @@ program = CAT; options = ""; break; - + case 't': + timer = t_option(optarg); + break; default: usage(); break; @@ -923,10 +1022,12 @@ break; case AT: - if (argc > optind) { - timer = parsetime(argc - optind, argv + optind); - } else { - timer = 0; + if (timer == 0) { + if (argc > optind) { + timer = parsetime(argc - optind, argv + optind); + } else { + timer = 0; + } } if (timer == 0) { @@ -955,10 +1056,12 @@ else queue = DEFAULT_BATCH_QUEUE; - if (argc > optind) - timer = parsetime(argc, argv); - else - timer = time(NULL); + if( timer == 0L ) { + if (argc > optind) + timer = parsetime(argc, argv); + else + timer = time(NULL); + } if (atverify) { struct tm *tm = localtime(&timer); --- at-3.1.10/at.1.in.t_option 2007-07-04 11:12:10.000000000 +0200 +++ at-3.1.10/at.1.in 2007-07-04 11:12:10.000000000 +0200 @@ -12,6 +12,16 @@ .RB [ -mldbv ] .B TIME .br +.B at +.RB [ -V ] +.RB [ -q +.IR queue ] +.RB [ -f +.IR file ] +.RB [ -mldbv ] +.RB -t +.IR time_arg +.br .B "at -c" .I job .RI [ job... ] @@ -32,8 +42,7 @@ and .B batch read commands from standard input or a specified file which are to -be executed at a later time, using -.BR /bin/sh . +be executed at a later time. .TP 8 .BR at executes commands at a specified time. @@ -227,6 +236,63 @@ .B \-c cats the jobs listed on the command line to standard output. +.TP +.BI \-t " time_arg" +Submit the job to be run at the time specified by the +.BI time_arg +option argument, which must have the same format as specified for the +.BR touch(1) +utility's +.B \-t +time option argument ([[CC]YY]MMDDhhmm). +.SH ENVIRONMENT +.P +.TP 8 +.B SHELL +The value of the SHELL environment variable at the time of +.B at +invocation will determine which shell is used to execute the +.B at +job commands. If SHELL is unset when +.B at +is invoked, the user's login shell will be used; otherwise, +if SHELL is set when +.B at +is invoked, it must contain the path of a shell interpreter +executable that will be used to run the commands at the specified time. +.P +.B at +will record the values of +environment variables present at time of +.B at +invocation. When the commands are run at the specified time, +.B at +will restore these variables to their recorded values . +These variables are excluded from this processing and are never +set by +.B at +when the commands are run : +.br +.BI TERM, +.BI DISPLAY, +.BI SHELLOPTS, +.BI _, +.BI PPID, +.BI BASH_VERSINFO, +.BI EUID, +.BI UID, +.BI GROUPS. +.br +If the user submitting the +.B at +job is not the super-user, variables that alter the behaviour of the +loader +.BR ld.so(8), +such as +.B LD_LIBRARY_PATH +, cannot be recorded and restored by +.B at . +.P .SH FILES .I @ATJBD@ .br