|
|
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.