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