1 static char *sccsid = "@(#)cron.c 4.1 (Berkeley) 10/01/80"; 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 16 char crontab[] = "/usr/lib/crontab"; 17 time_t itime; 18 struct tm *loct; 19 struct tm *localtime(); 20 char *malloc(); 21 char *realloc(); 22 int flag; 23 char *list; 24 unsigned listsize; 25 26 main() 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 74 char * 75 cmp(p, v) 76 char *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 111 slp() 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 122 ex(s) 123 char *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 138 init() 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 154 loop: 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 226 ignore: 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 240 number(c) 241 register 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 } 254