|
|
1.1 root 1: /*
2: * cron - clock daemon
3: *
4: * modified from Berkeley version 4.3 (7/5/81):
5: *
6: * place crontab in /etc/crontab
7: * new mandatory first field gives uid for command
8: */
9:
10: #include <sys/types.h>
11: #include <stdio.h>
12: #include <ctype.h>
13: #include <signal.h>
14: #include <time.h>
15: #include <sys/stat.h>
16: #include <pwd.h>
17:
18: #define LISTS 1024
19:
20: #define EXACT 100
21: #define ANY 101
22: #define LIST 102
23: #define RANGE 103
24: #define EOS 104
25: #define BOL 105
26: char crontab[] = "/etc/crontab";
27: time_t itime;
28: struct tm *loct;
29: struct tm *localtime();
30: char *malloc();
31: char *realloc();
32: int flag;
33: char *list;
34: unsigned listsize;
35: struct passwd *getpwnam();
36:
37: main()
38: {
39: register char *cp;
40: char *cmp(), *getid();
41: time_t filetime = 0;
42:
43: if (fork())
44: exit(0);
45: chdir("/");
46: freopen(crontab, "r", stdin);
47: freopen("/", "r", stdout);
48: freopen("/", "r", stderr);
49: signal(SIGHUP, SIG_IGN);
50: signal(SIGINT, SIG_IGN);
51: signal(SIGQUIT, SIG_IGN);
52: time(&itime);
53: itime -= localtime(&itime)->tm_sec;
54: fclose(stdin);
55:
56: for (;; itime+=60, slp()) {
57: struct stat cstat;
58:
59: if (stat(crontab, &cstat) == -1)
60: continue;
61: if (cstat.st_mtime > filetime) {
62: filetime = cstat.st_mtime;
63: init();
64: }
65: loct = localtime(&itime);
66: loct->tm_mon++; /* 1-12 for month */
67: for(cp = list; *cp != EOS;) {
68: int uid, gid;
69: cp++; /* skip start of line */
70: cp = getid (cp, &uid);
71: cp = getid (cp, &gid);
72: flag = 0;
73: cp = cmp(cp, loct->tm_min);
74: cp = cmp(cp, loct->tm_hour);
75: cp = cmp(cp, loct->tm_mday);
76: cp = cmp(cp, loct->tm_mon);
77: cp = cmp(cp, loct->tm_wday);
78: if(flag == 0)
79: ex (cp, uid, gid);
80: while(*cp++ != 0)
81: ;
82: }
83: }
84: }
85:
86: /*
87: * getid and putid are somewhat machine-dependent.
88: * putid stores a uid or gid as some number of characters;
89: * getid retrieves the uid or gid. The number of characters
90: * and number of bits per character might be different
91: * on other machines. Each function returns a pointer to
92: * the char just past the last one it dealt with.
93: */
94: char *
95: getid (p, v)
96: register char *p;
97: int *v;
98: {
99: *v = ((p[0] & 0xff) + (p[1] << 8)) & 0xffff;
100: return p + 2;
101: }
102:
103: char *
104: putid (p, v)
105: register char *p;
106: int v;
107: {
108: p[0] = v & 0xff;
109: p[1] = (v >> 8) & 0xff;
110: return p + 2;
111: }
112:
113: char *
114: cmp(p, v)
115: char *p;
116: {
117: register char *cp;
118:
119: cp = p;
120: switch(*cp++) {
121:
122: case EXACT:
123: if (*cp++ != v)
124: flag++;
125: return(cp);
126:
127: case ANY:
128: return(cp);
129:
130: case LIST:
131: while(*cp != LIST)
132: if(*cp++ == v) {
133: while(*cp++ != LIST)
134: ;
135: return(cp);
136: }
137: flag++;
138: return(cp+1);
139:
140: case RANGE:
141: if(*cp > v || cp[1] < v)
142: flag++;
143: return(cp+2);
144: }
145: if(cp[-1] != v)
146: flag++;
147: return(cp);
148: }
149:
150: slp()
151: {
152: register i;
153: time_t t;
154:
155: time(&t);
156: i = itime - t;
157: if(i < -60 * 60 || i > 60 * 60) {
158: itime = t;
159: i = 60 - localtime(&itime)->tm_sec;
160: itime += i;
161: }
162: if(i > 0)
163: sleep((unsigned) i);
164: }
165:
166: ex (s, uid, gid)
167: char *s;
168: int uid, gid;
169: {
170: int st;
171:
172: if(fork()) {
173: wait(&st);
174: return;
175: }
176: if(fork())
177: exit(0);
178: setgid (gid);
179: setuid (uid);
180: freopen("/dev/null", "r", stdin);
181: execl("/bin/sh", "sh", "-c", s, 0);
182: exit(0);
183: }
184:
185: init()
186: {
187: register i, c;
188: register char *cp;
189: register char *ocp;
190: register int n;
191: char username[20];
192: struct passwd *pw;
193:
194: freopen(crontab, "r", stdin);
195: if (list) {
196: free(list);
197: list = realloc(list, LISTS);
198: } else
199: list = malloc(LISTS);
200: listsize = LISTS;
201: cp = list;
202:
203: loop:
204: if(cp > list+listsize-500) {
205: char *olist;
206: listsize += LISTS;
207: olist = list;
208: free(list);
209: list = realloc(list, listsize);
210: cp = list + (cp - olist);
211: }
212: ocp = cp;
213:
214: /* skip leading white space on the line */
215: do c = getchar();
216: while (c == ' ' || c == '\t');
217:
218: /* accumulate the user name into "username" */
219: n = 0;
220: while (c != EOF && c != '\n' && c != ' ' && c != '\t') {
221: if (n < sizeof (username) - 1)
222: username[n++] = c;
223: c = getchar();
224: }
225: username[n] = '\0';
226:
227: /* look up the user name and store it */
228: pw = getpwnam (username);
229: if (pw == NULL)
230: goto ignore;
231: *cp++ = BOL;
232: cp = putid (cp, pw->pw_uid);
233: cp = putid (cp, pw->pw_gid);
234:
235: ungetc (c, stdin);
236:
237: /* scan the time fields */
238: for(i=0;; i++) {
239: do c = getchar();
240: while(c == ' ' || c == '\t');
241: if(c == EOF || c == '\n')
242: goto ignore;
243: if(i == 5)
244: break;
245: if(c == '*') {
246: *cp++ = ANY;
247: continue;
248: }
249: if ((n = number(c)) < 0)
250: goto ignore;
251: c = getchar();
252: if(c == ',')
253: goto mlist;
254: if(c == '-')
255: goto mrange;
256: if(c != '\t' && c != ' ')
257: goto ignore;
258: *cp++ = EXACT;
259: *cp++ = n;
260: continue;
261:
262: mlist:
263: *cp++ = LIST;
264: *cp++ = n;
265: do {
266: if ((n = number(getchar())) < 0)
267: goto ignore;
268: *cp++ = n;
269: c = getchar();
270: } while (c==',');
271: if(c != '\t' && c != ' ')
272: goto ignore;
273: *cp++ = LIST;
274: continue;
275:
276: mrange:
277: *cp++ = RANGE;
278: *cp++ = n;
279: if ((n = number(getchar())) < 0)
280: goto ignore;
281: c = getchar();
282: if(c != '\t' && c != ' ')
283: goto ignore;
284: *cp++ = n;
285: }
286: while(c != '\n') {
287: if(c == EOF)
288: goto ignore;
289: if(c == '%')
290: c = '\n';
291: *cp++ = c;
292: c = getchar();
293: }
294: *cp++ = '\n';
295: *cp++ = 0;
296: goto loop;
297:
298: ignore:
299: cp = ocp;
300: while(c != '\n') {
301: if(c == EOF) {
302: *cp++ = EOS;
303: *cp++ = EOS;
304: fclose(stdin);
305: return;
306: }
307: c = getchar();
308: }
309: goto loop;
310: }
311:
312: number(c)
313: register c;
314: {
315: register n = 0;
316:
317: while (isdigit(c)) {
318: n = n*10 + c - '0';
319: c = getchar();
320: }
321: ungetc(c, stdin);
322: if (n>100)
323: return(-1);
324: return(n);
325: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.