1 #ifndef lint 2 static char *sccsid = "@(#)cron.c 4.7 (Berkeley) 07/02/83"; 3 #endif 4 5 #include <sys/types.h> 6 #include <stdio.h> 7 #include <ctype.h> 8 #include <signal.h> 9 #include <sys/time.h> 10 #include <sys/stat.h> 11 12 #define LISTS (2*BUFSIZ) 13 #define MAXLIN BUFSIZ 14 15 #define EXACT 100 16 #define ANY 101 17 #define LIST 102 18 #define RANGE 103 19 #define EOS 104 20 char crontab[] = "/usr/lib/crontab"; 21 time_t itime; 22 struct tm *loct; 23 struct tm *localtime(); 24 char *malloc(); 25 char *realloc(); 26 int flag; 27 char *list; 28 unsigned listsize; 29 30 main() 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 */ 61 if (loct->tm_wday == 0) 62 loct->tm_wday == 7; /* sunday is 7, not 0 */ 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); 70 if(flag == 0) 71 ex(cp); 72 while(*cp++ != 0) 73 ; 74 } 75 } 76 } 77 78 char * 79 cmp(p, v) 80 char *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 115 slp() 116 { 117 register i; 118 time_t t; 119 120 time(&t); 121 i = itime - t; 122 if(i < -60 * 60 || i > 60 * 60) { 123 itime = t; 124 i = 60 - localtime(&itime)->tm_sec; 125 itime += i; 126 } 127 if(i > 0) 128 sleep(i); 129 } 130 131 ex(s) 132 char *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 147 init() 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 163 loop: 164 if(cp > list+listsize-MAXLIN) { 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 235 ignore: 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 249 number(c) 250 register 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 } 263