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