1: /*
   2:  * at time mon day
   3:  * at time wday
   4:  * at time wday 'week'
   5:  *
   6:  */
   7: /*! Modified by PLWard, USGS 10/30/80 for csh and mail options */
   8: 
   9: #include <stdio.h>
  10: #include <ctype.h>
  11: #include <time.h>
  12: #include <signal.h>
  13: #include <pwd.h>
  14: 
  15: #define MAIL    "Mail"
  16: #define CD      "cd"
  17: #define RM      "/bin/rm"
  18: #define PWD     "/bin/pwd"
  19: #define PAST    "/usr/spool/at/past"
  20: #define THISDAY "/usr/spool/at"
  21: #define HOUR    100
  22: #define HALFDAY (12*HOUR)
  23: #define DAY (24*HOUR)
  24: 
  25: int sendmail = 1;   /* default to send mail = 1, else = 0. */
  26: 
  27: char *days[] = {
  28:     "sunday",
  29:     "monday",
  30:     "tuesday",
  31:     "wednesday",
  32:     "thursday",
  33:     "friday",
  34:     "saturday",
  35: };
  36: 
  37: struct monstr {
  38:     char *mname;
  39:     int mlen;
  40: } months[] = {
  41:     { "january", 31 },
  42:     { "february", 28 },
  43:     { "march", 31 },
  44:     { "april", 30 },
  45:     { "may", 31 },
  46:     { "june", 30 },
  47:     { "july", 31 },
  48:     { "august", 31 },
  49:     { "september", 30 },
  50:     { "october", 31 },
  51:     { "november", 30 },
  52:     { "december", 31 },
  53:     { 0, 0 },
  54: };
  55: 
  56: char    fname[100];
  57: char    fileout[100];
  58: char    temp[15];
  59: int utime;          /* requested time in grains */
  60: int now;            /* when is it */
  61: int uday;           /* day of year to be done */
  62: int uyear;          /* year */
  63: int today;          /* day of year today */
  64: FILE    *file;
  65: FILE    *ifile;
  66: char    **environ;
  67: char    *prefix();
  68: FILE    *popen();
  69: struct  passwd *user;
  70: 
  71: main(argc, argv)
  72: char **argv;
  73: {
  74:     extern onintr();
  75:     register c;
  76:     char pwbuf[100];
  77:     FILE *pwfil;
  78:     int larg;
  79:     int csh;
  80:     int i,eq;
  81:     char *tmp;
  82:     char **ep;
  83:     char *cp;
  84: 
  85:     if(argv[1][0] == '-'){
  86:         sendmail=sendmail ? 0 : 1;
  87:         for(i=2;i<=argc;i++)argv[i-1]=argv[i];
  88:         argc--;
  89:     }
  90:     /* argv[1] is the user's time: e.g.,  3AM */
  91:     /* argv[2] is a month name or day of week */
  92:     /* argv[3] is day of month or 'week' */
  93:     /* another argument might be an input file */
  94:     if (argc < 2) {
  95:         fprintf(stderr, "at: arg count\n");
  96:         exit(1);
  97:     }
  98:     makeutime(argv[1]);
  99:     larg = makeuday(argc,argv)+1;
 100:     if (uday==today && larg<=2 && utime<=now)
 101:         uday++;
 102:     c = uyear%4==0? 366: 365;
 103:     if (uday >= c) {
 104:         uday -= c;
 105:         uyear++;
 106:     }
 107:     filename(THISDAY, uyear, uday, utime);
 108:     /* Create file and then change uids */
 109:     close(creat(fname,0755));
 110:     chown(fname,getuid(),getgid());
 111: /*	fix so that root can use at */
 112:     setuid(getuid());
 113:     user=getpwuid(getuid());
 114:     ifile = stdin;
 115:     if (argc > larg)
 116:         ifile = fopen(argv[larg], "r");
 117:     else argv[larg]="from stdin";
 118:     if (ifile == NULL) {
 119:         fprintf(stderr, "at: cannot open input: %s\n", argv[larg]);
 120:         exit(1);
 121:     }
 122:     if (signal(SIGINT, SIG_IGN) != SIG_IGN)
 123:         signal(SIGINT, onintr);
 124:     file = fopen(fname, "w");
 125:     if (file == NULL) {
 126:         fprintf(stderr, "at: cannot open file in %s.\n",THISDAY);
 127:         exit(1);
 128:     }
 129:     /* Decide if this is a cshell file */
 130:     if(ifile == stdin){
 131:         tmp=getenv("SHELL");
 132:         csh = (strcmp(tmp+strlen(tmp)-3,"csh")==0) ? 1 : 0;
 133:     }
 134:     else {
 135:         csh = ((c=getc(ifile)) == '#') ? 1 : 0;
 136:         fseek(ifile,0,0);
 137:     }
 138:     if (csh) fprintf(file,"#at:cshell\n");
 139:     if ((pwfil = popen(PWD, "r")) == NULL) {
 140:         fprintf(stderr, "at: can't execute pwd\n");
 141:         exit(1);
 142:     }
 143:     fgets(pwbuf, 100, pwfil);
 144:     pclose(pwfil);
 145:     fprintf(file, "%s %s",CD, pwbuf);
 146:     c=umask(0);
 147:     umask(c);
 148:     fprintf(file,"umask %.1o\n",c);
 149:     if (environ) {
 150:         ep = environ;
 151:         while (*ep){
 152:             for (tmp = *ep, cp = "TERMCAP"; *tmp==*cp; tmp++,cp++);
 153:             if (*cp == 0 && *tmp== '=') {
 154:                 ep++;
 155:                 continue;
 156:             }
 157:             if (csh) fprintf(file,"setenv ");
 158:             for(tmp = *ep ; *tmp != '=' ; tmp++) putc(*tmp,file);
 159:             if (csh) putc(' ', file);
 160:             else putc(*tmp,file);
 161:             putc('\'', file);
 162:             for (tmp++; *tmp; tmp++) {
 163:                 if (*tmp == '\'')
 164:                     putc('\\', file);
 165:                 putc(*tmp, file);
 166:             }
 167:             putc('\'', file);
 168:             putc('\n',file);
 169:             ep++;
 170:         }
 171:     if (csh) fprintf(file,"source %s/.cshrc\n",getenv("HOME"));
 172:     }
 173:     fprintf(file,"echo 'Began executing at' `date`\n");
 174:     while((c = getc(ifile)) != EOF) {
 175:         putc(c, file);
 176:     }
 177:     fprintf(file,"%s %s\n",CD,PAST);
 178:     fprintf(file,"echo 'Done  executing at' `date`\n");
 179:     if(sendmail)fprintf(file,"%s -s 'at: ran program %s.' %s < %s\n",
 180:         MAIL,argv[larg],user->pw_name,fileout);
 181:     fprintf(file,"%s %s\n",RM,fileout);
 182:     exit(0);
 183: }
 184: 
 185: makeutime(pp)
 186: char *pp;
 187: {
 188:     register val;
 189:     register char *p;
 190: 
 191:     /* p points to a user time */
 192:     p = pp;
 193:     val = 0;
 194:     while(isdigit(*p)) {
 195:         val = val*10+(*p++ -'0');
 196:     }
 197:     if (p-pp < 3)
 198:         val *= HOUR;
 199: 
 200:     for (;;) {
 201:         switch(*p) {
 202: 
 203:         case ':':
 204:             ++p;
 205:             if (isdigit(*p)) {
 206:                 if (isdigit(p[1])) {
 207:                     val +=(10* *p + p[1] - 11*'0');
 208:                     p += 2;
 209:                     continue;
 210:                 }
 211:             }
 212:             fprintf(stderr, "at: bad time format:\n");
 213:             exit(1);
 214: 
 215:         case 'A':
 216:         case 'a':
 217:             if (val >= HALFDAY+HOUR)
 218:                 val = DAY+1;  /* illegal */
 219:             if (val >= HALFDAY && val <(HALFDAY+HOUR))
 220:                 val -= HALFDAY;
 221:             break;
 222: 
 223:         case 'P':
 224:         case 'p':
 225:             if (val >= HALFDAY+HOUR)
 226:                 val = DAY+1;  /* illegal */
 227:             if (val < HALFDAY)
 228:                 val += HALFDAY;
 229:             break;
 230: 
 231:         case 'n':
 232:         case 'N':
 233:             val = HALFDAY;
 234:             break;
 235: 
 236:         case 'M':
 237:         case 'm':
 238:             val = 0;
 239:             break;
 240: 
 241: 
 242:         case '\0':
 243:         case ' ':
 244:             /* 24 hour time */
 245:             if (val == DAY)
 246:                 val -= DAY;
 247:             break;
 248: 
 249:         default:
 250:             fprintf(stderr, "at: bad time format\n");
 251:             exit(1);
 252: 
 253:         }
 254:         break;
 255:     }
 256:     if (val < 0 || val >= DAY) {
 257:         fprintf(stderr, "at: time out of range\n");
 258:         exit(1);
 259:     }
 260:     if (val%HOUR >= 60) {
 261:         fprintf(stderr, "at: illegal minute field\n");
 262:         exit(1);
 263:     }
 264:     utime = val;
 265: }
 266: 
 267: 
 268: makeuday(argc,argv)
 269: char **argv;
 270: {
 271:     /* the presumption is that argv[2], argv[3] are either
 272: 	   month day OR weekday [week].  Returns either 2 or 3 as last
 273: 	   argument used */
 274:     /* first of all, what's today */
 275:     long tm;
 276:     int found = -1;
 277:     char **ps;
 278:     struct tm *detail, *localtime();
 279:     struct monstr *pt;
 280: 
 281:     time(&tm);
 282:     detail = localtime(&tm);
 283:     uday = today = detail->tm_yday;
 284:     uyear = detail->tm_year;
 285:     now = detail->tm_hour*100+detail->tm_min;
 286:     if (argc<=2)
 287:         return(1);
 288:     /* is the next argument a month name ? */
 289:     for (pt=months; pt->mname; pt++) {
 290:         if (prefix(argv[2], pt->mname)) {
 291:             if (found<0)
 292:                 found = pt-months;
 293:             else {
 294:                 fprintf(stderr, "at: ambiguous month\n");
 295:                 exit(1);
 296:             }
 297:         }
 298:     }
 299:     if (found>=0) {
 300:         if (argc<=3)
 301:             return(2);
 302:         uday = atoi(argv[3]) - 1;
 303:         if (uday<0) {
 304:             fprintf(stderr, "at: illegal day\n");
 305:             exit(1);
 306:         }
 307:         while(--found>=0)
 308:             uday += months[found].mlen;
 309:         if (detail->tm_year%4==0 && uday>59)
 310:             uday += 1;
 311:         return(3);
 312:     }
 313:     /* not a month, try day of week */
 314:     found = -1;
 315:     for (ps=days; ps<days+7; ps++) {
 316:         if (prefix(argv[2], *ps)) {
 317:             if (found<0)
 318:                 found = ps-days;
 319:             else {
 320:                 fprintf(stderr, "at: ambiguous day of week\n");
 321:                 exit(1);
 322:             }
 323:         }
 324:     }
 325:     if (found<0)
 326:         return(1);
 327:     /* find next day of this sort */
 328:     uday = found - detail->tm_wday;
 329:     if (uday<=0)
 330:         uday += 7;
 331:     uday += today;
 332:     if (argc>3 && strcmp("week", argv[3])==0) {
 333:         uday += 7;
 334:         return(3);
 335:     }
 336:     return(2);
 337: }
 338: 
 339: char *
 340: prefix(begin, full)
 341: char *begin, *full;
 342: {
 343:     int c;
 344:     while (c = *begin++) {
 345:         if (isupper(c))
 346:             c = tolower(c);
 347:         if (*full != c)
 348:             return(0);
 349:         else
 350:             full++;
 351:     }
 352:     return(full);
 353: }
 354: 
 355: filename(dir, y, d, t)
 356: char *dir;
 357: {
 358:     register i;
 359: 
 360:     for (i=0; ; i += 53) {
 361:         sprintf(temp,"%02d.%03d.%04d.%02d",y,d,t,(getpid()+i)%100);
 362:         sprintf(fname,"%s/%s",dir,temp);
 363:         temp[0]='M';
 364:         sprintf(fileout,"%s/%s",PAST,temp);
 365:         if (access(fname, 0) == -1)
 366:             return;
 367:     }
 368: }
 369: 
 370: onintr()
 371: {
 372:     unlink(fname);
 373:     exit(1);
 374: }

Defined functions

filename defined in line 355; used 1 times
main defined in line 71; never used
makeuday defined in line 268; used 1 times
  • in line 99
makeutime defined in line 185; used 1 times
  • in line 98
onintr defined in line 370; used 2 times
prefix defined in line 339; used 3 times

Defined variables

days defined in line 27; used 3 times
environ defined in line 66; used 2 times
fileout defined in line 57; used 3 times
fname defined in line 56; used 6 times
months defined in line 40; used 3 times
now defined in line 60; used 2 times
sendmail defined in line 25; used 3 times
temp defined in line 58; used 4 times
today defined in line 63; used 3 times
uday defined in line 61; used 16 times
user defined in line 69; used 2 times
utime defined in line 59; used 3 times
uyear defined in line 62; used 4 times

Defined struct's

monstr defined in line 37; used 2 times
  • in line 279(2)

Defined macros

CD defined in line 16; used 2 times
DAY defined in line 23; used 5 times
HALFDAY defined in line 22; used 8 times
HOUR defined in line 21; used 7 times
MAIL defined in line 15; used 1 times
PAST defined in line 19; used 2 times
PWD defined in line 18; used 1 times
RM defined in line 17; used 1 times
THISDAY defined in line 20; used 2 times
Last modified: 1983-03-24
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 1387
Valid CSS Valid XHTML 1.0 Strict