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