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