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