Bell 32V development
[unix-history] / usr / src / cmd / cron.c
CommitLineData
3b600ead
TL
1#include <sys/types.h>
2#include <stdio.h>
3#include <ctype.h>
4#include <signal.h>
5#include <time.h>
6#include <sys/stat.h>
7
8#define LISTS 512
9
10#define EXACT 0
11#define ANY 1
12#define LIST 2
13#define RANGE 3
14#define EOS 4
15char crontab[] = "/usr/lib/crontab";
16time_t itime;
17struct tm *loct;
18struct tm *localtime();
19char *malloc();
20char *realloc();
21int flag;
22char *list;
23unsigned listsize;
24
25main()
26{
27 register char *cp;
28 char *cmp();
29 time_t filetime = 0;
30
31 setuid(1);
32 if (fork())
33 exit(0);
34 chdir("/");
35 freopen(crontab, "r", stdin);
36 freopen("/", "r", stdout);
37 freopen("/", "r", stderr);
38 signal(SIGHUP, SIG_IGN);
39 signal(SIGINT, SIG_IGN);
40 signal(SIGQUIT, SIG_IGN);
41 time(&itime);
42 itime -= localtime(&itime)->tm_sec;
43 fclose(stdin);
44
45 for (;; itime+=60, slp()) {
46 struct stat cstat;
47
48 if (stat(crontab, &cstat) == -1)
49 continue;
50 if (cstat.st_mtime > filetime) {
51 filetime = cstat.st_mtime;
52 init();
53 }
54 loct = localtime(&itime);
55 loct->tm_mon++; /* 1-12 for month */
56 for(cp = list; *cp != EOS;) {
57 flag = 0;
58 cp = cmp(cp, loct->tm_min);
59 cp = cmp(cp, loct->tm_hour);
60 cp = cmp(cp, loct->tm_mday);
61 cp = cmp(cp, loct->tm_mon);
62 cp = cmp(cp, loct->tm_wday);
63 if(flag == 0) {
64 slp();
65 ex(cp);
66 }
67 while(*cp++ != 0)
68 ;
69 }
70 }
71}
72
73char *
74cmp(p, v)
75char *p;
76{
77 register char *cp;
78
79 cp = p;
80 switch(*cp++) {
81
82 case EXACT:
83 if (*cp++ != v)
84 flag++;
85 return(cp);
86
87 case ANY:
88 return(cp);
89
90 case LIST:
91 while(*cp != LIST)
92 if(*cp++ == v) {
93 while(*cp++ != LIST)
94 ;
95 return(cp);
96 }
97 flag++;
98 return(cp+1);
99
100 case RANGE:
101 if(*cp > v || cp[1] < v)
102 flag++;
103 return(cp+2);
104 }
105 if(cp[-1] != v)
106 flag++;
107 return(cp);
108}
109
110slp()
111{
112 register i;
113 time_t t;
114
115 time(&t);
116 i = itime - t;
117 if(i > 0)
118 sleep(i);
119}
120
121ex(s)
122char *s;
123{
124 int st;
125
126 if(fork()) {
127 wait(&st);
128 return;
129 }
130 if(fork())
131 exit(0);
132 freopen("/", "r", stdin);
133 execl("/bin/sh", "sh", "-c", s, 0);
134 exit(0);
135}
136
137init()
138{
139 register i, c;
140 register char *cp;
141 register char *ocp;
142 register int n;
143
144 freopen(crontab, "r", stdin);
145 if (list) {
146 free(list);
147 list = realloc(list, LISTS);
148 } else
149 list = malloc(LISTS);
150 listsize = LISTS;
151 cp = list;
152
153loop:
154 if(cp > list+listsize-100) {
155 char *olist;
156 listsize += LISTS;
157 olist = list;
158 free(list);
159 list = realloc(list, listsize);
160 cp = list + (cp - olist);
161 }
162 ocp = cp;
163 for(i=0;; i++) {
164 do
165 c = getchar();
166 while(c == ' ' || c == '\t')
167 ;
168 if(c == EOF || c == '\n')
169 goto ignore;
170 if(i == 5)
171 break;
172 if(c == '*') {
173 *cp++ = ANY;
174 continue;
175 }
176 if ((n = number(c)) < 0)
177 goto ignore;
178 c = getchar();
179 if(c == ',')
180 goto mlist;
181 if(c == '-')
182 goto mrange;
183 if(c != '\t' && c != ' ')
184 goto ignore;
185 *cp++ = EXACT;
186 *cp++ = n;
187 continue;
188
189 mlist:
190 *cp++ = LIST;
191 *cp++ = n;
192 do {
193 if ((n = number(getchar())) < 0)
194 goto ignore;
195 *cp++ = n;
196 c = getchar();
197 } while (c==',');
198 if(c != '\t' && c != ' ')
199 goto ignore;
200 *cp++ = LIST;
201 continue;
202
203 mrange:
204 *cp++ = RANGE;
205 *cp++ = n;
206 if ((n = number(getchar())) < 0)
207 goto ignore;
208 c = getchar();
209 if(c != '\t' && c != ' ')
210 goto ignore;
211 *cp++ = n;
212 }
213 while(c != '\n') {
214 if(c == EOF)
215 goto ignore;
216 if(c == '%')
217 c = '\n';
218 *cp++ = c;
219 c = getchar();
220 }
221 *cp++ = '\n';
222 *cp++ = 0;
223 goto loop;
224
225ignore:
226 cp = ocp;
227 while(c != '\n') {
228 if(c == EOF) {
229 *cp++ = EOS;
230 *cp++ = EOS;
231 fclose(stdin);
232 return;
233 }
234 c = getchar();
235 }
236 goto loop;
237}
238
239number(c)
240register c;
241{
242 register n = 0;
243
244 while (isdigit(c)) {
245 n = n*10 + c - '0';
246 c = getchar();
247 }
248 ungetc(c, stdin);
249 if (n>100)
250 return(-1);
251 return(n);
252}