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