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