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