|
|
1.1 ! root 1: /* ! 2: * cron - clock daemon ! 3: * ! 4: * modified from Berkeley version 4.3 (7/5/81): ! 5: * ! 6: * place crontab in /etc/crontab ! 7: * new mandatory first field gives uid for command ! 8: */ ! 9: ! 10: #include <sys/types.h> ! 11: #include <stdio.h> ! 12: #include <ctype.h> ! 13: #include <signal.h> ! 14: #include <time.h> ! 15: #include <sys/stat.h> ! 16: #include <pwd.h> ! 17: ! 18: #define LISTS 1024 ! 19: ! 20: #define EXACT 100 ! 21: #define ANY 101 ! 22: #define LIST 102 ! 23: #define RANGE 103 ! 24: #define EOS 104 ! 25: #define BOL 105 ! 26: char crontab[] = "/etc/crontab"; ! 27: time_t itime; ! 28: struct tm *loct; ! 29: struct tm *localtime(); ! 30: char *malloc(); ! 31: char *realloc(); ! 32: int flag; ! 33: char *list; ! 34: unsigned listsize; ! 35: struct passwd *getpwnam(); ! 36: ! 37: main() ! 38: { ! 39: register char *cp; ! 40: char *cmp(), *getid(); ! 41: time_t filetime = 0; ! 42: ! 43: if (fork()) ! 44: exit(0); ! 45: chdir("/"); ! 46: freopen(crontab, "r", stdin); ! 47: freopen("/", "r", stdout); ! 48: freopen("/", "r", stderr); ! 49: signal(SIGHUP, SIG_IGN); ! 50: signal(SIGINT, SIG_IGN); ! 51: signal(SIGQUIT, SIG_IGN); ! 52: time(&itime); ! 53: itime -= localtime(&itime)->tm_sec; ! 54: fclose(stdin); ! 55: ! 56: for (;; itime+=60, slp()) { ! 57: struct stat cstat; ! 58: ! 59: if (stat(crontab, &cstat) == -1) ! 60: continue; ! 61: if (cstat.st_mtime > filetime) { ! 62: filetime = cstat.st_mtime; ! 63: init(); ! 64: } ! 65: loct = localtime(&itime); ! 66: loct->tm_mon++; /* 1-12 for month */ ! 67: for(cp = list; *cp != EOS;) { ! 68: int uid, gid; ! 69: cp++; /* skip start of line */ ! 70: cp = getid (cp, &uid); ! 71: cp = getid (cp, &gid); ! 72: flag = 0; ! 73: cp = cmp(cp, loct->tm_min); ! 74: cp = cmp(cp, loct->tm_hour); ! 75: cp = cmp(cp, loct->tm_mday); ! 76: cp = cmp(cp, loct->tm_mon); ! 77: cp = cmp(cp, loct->tm_wday); ! 78: if(flag == 0) ! 79: ex (cp, uid, gid); ! 80: while(*cp++ != 0) ! 81: ; ! 82: } ! 83: } ! 84: } ! 85: ! 86: /* ! 87: * getid and putid are somewhat machine-dependent. ! 88: * putid stores a uid or gid as some number of characters; ! 89: * getid retrieves the uid or gid. The number of characters ! 90: * and number of bits per character might be different ! 91: * on other machines. Each function returns a pointer to ! 92: * the char just past the last one it dealt with. ! 93: */ ! 94: char * ! 95: getid (p, v) ! 96: register char *p; ! 97: int *v; ! 98: { ! 99: *v = ((p[0] & 0xff) + (p[1] << 8)) & 0xffff; ! 100: return p + 2; ! 101: } ! 102: ! 103: char * ! 104: putid (p, v) ! 105: register char *p; ! 106: int v; ! 107: { ! 108: p[0] = v & 0xff; ! 109: p[1] = (v >> 8) & 0xff; ! 110: return p + 2; ! 111: } ! 112: ! 113: char * ! 114: cmp(p, v) ! 115: char *p; ! 116: { ! 117: register char *cp; ! 118: ! 119: cp = p; ! 120: switch(*cp++) { ! 121: ! 122: case EXACT: ! 123: if (*cp++ != v) ! 124: flag++; ! 125: return(cp); ! 126: ! 127: case ANY: ! 128: return(cp); ! 129: ! 130: case LIST: ! 131: while(*cp != LIST) ! 132: if(*cp++ == v) { ! 133: while(*cp++ != LIST) ! 134: ; ! 135: return(cp); ! 136: } ! 137: flag++; ! 138: return(cp+1); ! 139: ! 140: case RANGE: ! 141: if(*cp > v || cp[1] < v) ! 142: flag++; ! 143: return(cp+2); ! 144: } ! 145: if(cp[-1] != v) ! 146: flag++; ! 147: return(cp); ! 148: } ! 149: ! 150: slp() ! 151: { ! 152: register i; ! 153: time_t t; ! 154: ! 155: time(&t); ! 156: i = itime - t; ! 157: if(i < -60 * 60 || i > 60 * 60) { ! 158: itime = t; ! 159: i = 60 - localtime(&itime)->tm_sec; ! 160: itime += i; ! 161: } ! 162: if(i > 0) ! 163: sleep((unsigned) i); ! 164: } ! 165: ! 166: ex (s, uid, gid) ! 167: char *s; ! 168: int uid, gid; ! 169: { ! 170: int st; ! 171: ! 172: if(fork()) { ! 173: wait(&st); ! 174: return; ! 175: } ! 176: if(fork()) ! 177: exit(0); ! 178: setgid (gid); ! 179: setuid (uid); ! 180: freopen("/dev/null", "r", stdin); ! 181: execl("/bin/sh", "sh", "-c", s, 0); ! 182: exit(0); ! 183: } ! 184: ! 185: init() ! 186: { ! 187: register i, c; ! 188: register char *cp; ! 189: register char *ocp; ! 190: register int n; ! 191: char username[20]; ! 192: struct passwd *pw; ! 193: ! 194: freopen(crontab, "r", stdin); ! 195: if (list) { ! 196: free(list); ! 197: list = realloc(list, LISTS); ! 198: } else ! 199: list = malloc(LISTS); ! 200: listsize = LISTS; ! 201: cp = list; ! 202: ! 203: loop: ! 204: if(cp > list+listsize-500) { ! 205: char *olist; ! 206: listsize += LISTS; ! 207: olist = list; ! 208: free(list); ! 209: list = realloc(list, listsize); ! 210: cp = list + (cp - olist); ! 211: } ! 212: ocp = cp; ! 213: ! 214: /* skip leading white space on the line */ ! 215: do c = getchar(); ! 216: while (c == ' ' || c == '\t'); ! 217: ! 218: /* accumulate the user name into "username" */ ! 219: n = 0; ! 220: while (c != EOF && c != '\n' && c != ' ' && c != '\t') { ! 221: if (n < sizeof (username) - 1) ! 222: username[n++] = c; ! 223: c = getchar(); ! 224: } ! 225: username[n] = '\0'; ! 226: ! 227: /* look up the user name and store it */ ! 228: pw = getpwnam (username); ! 229: if (pw == NULL) ! 230: goto ignore; ! 231: *cp++ = BOL; ! 232: cp = putid (cp, pw->pw_uid); ! 233: cp = putid (cp, pw->pw_gid); ! 234: ! 235: ungetc (c, stdin); ! 236: ! 237: /* scan the time fields */ ! 238: for(i=0;; i++) { ! 239: do c = getchar(); ! 240: while(c == ' ' || c == '\t'); ! 241: if(c == EOF || c == '\n') ! 242: goto ignore; ! 243: if(i == 5) ! 244: break; ! 245: if(c == '*') { ! 246: *cp++ = ANY; ! 247: continue; ! 248: } ! 249: if ((n = number(c)) < 0) ! 250: goto ignore; ! 251: c = getchar(); ! 252: if(c == ',') ! 253: goto mlist; ! 254: if(c == '-') ! 255: goto mrange; ! 256: if(c != '\t' && c != ' ') ! 257: goto ignore; ! 258: *cp++ = EXACT; ! 259: *cp++ = n; ! 260: continue; ! 261: ! 262: mlist: ! 263: *cp++ = LIST; ! 264: *cp++ = n; ! 265: do { ! 266: if ((n = number(getchar())) < 0) ! 267: goto ignore; ! 268: *cp++ = n; ! 269: c = getchar(); ! 270: } while (c==','); ! 271: if(c != '\t' && c != ' ') ! 272: goto ignore; ! 273: *cp++ = LIST; ! 274: continue; ! 275: ! 276: mrange: ! 277: *cp++ = RANGE; ! 278: *cp++ = n; ! 279: if ((n = number(getchar())) < 0) ! 280: goto ignore; ! 281: c = getchar(); ! 282: if(c != '\t' && c != ' ') ! 283: goto ignore; ! 284: *cp++ = n; ! 285: } ! 286: while(c != '\n') { ! 287: if(c == EOF) ! 288: goto ignore; ! 289: if(c == '%') ! 290: c = '\n'; ! 291: *cp++ = c; ! 292: c = getchar(); ! 293: } ! 294: *cp++ = '\n'; ! 295: *cp++ = 0; ! 296: goto loop; ! 297: ! 298: ignore: ! 299: cp = ocp; ! 300: while(c != '\n') { ! 301: if(c == EOF) { ! 302: *cp++ = EOS; ! 303: *cp++ = EOS; ! 304: fclose(stdin); ! 305: return; ! 306: } ! 307: c = getchar(); ! 308: } ! 309: goto loop; ! 310: } ! 311: ! 312: number(c) ! 313: register c; ! 314: { ! 315: register n = 0; ! 316: ! 317: while (isdigit(c)) { ! 318: n = n*10 + c - '0'; ! 319: c = getchar(); ! 320: } ! 321: ungetc(c, stdin); ! 322: if (n>100) ! 323: return(-1); ! 324: return(n); ! 325: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.