1: #ifndef lint
   2: static char *sccsid = "@(#)cron.c	4.12 (Berkeley) 5/27/86";
   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: #include <sys/wait.h>
  12: #include <sys/ioctl.h>
  13: #include <sys/file.h>
  14: #include <pwd.h>
  15: #include <fcntl.h>
  16: 
  17: #define LISTS   (2*BUFSIZ)
  18: #define MAXLIN  BUFSIZ
  19: 
  20: #ifndef CRONTAB
  21: #define CRONTAB "/usr/lib/crontab"
  22: #endif
  23: 
  24: #ifndef CRONTABLOC
  25: #define CRONTABLOC  "/usr/lib/crontab.local"
  26: #endif
  27: 
  28: #define EXACT   100
  29: #define ANY 101
  30: #define LIST    102
  31: #define RANGE   103
  32: #define EOS 104
  33: 
  34: char    crontab[]   = CRONTAB;
  35: char    loc_crontab[]   = CRONTABLOC;
  36: time_t  itime;
  37: struct  tm *loct;
  38: struct  tm *localtime();
  39: char    *malloc();
  40: char    *realloc();
  41: int reapchild();
  42: int flag;
  43: char    *list;
  44: char    *listend;
  45: unsigned listsize;
  46: 
  47: FILE    *debug;
  48: #define dprintf if (debug) fprintf
  49: 
  50: main(argc, argv)
  51:     int argc;
  52:     char **argv;
  53: {
  54:     register char *cp;
  55:     char *cmp();
  56:     time_t filetime = 0;
  57:     time_t lfiletime = 0;
  58:     char c;
  59:     extern char *optarg;
  60: 
  61:     if (fork())
  62:         exit(0);
  63:     c = getopt(argc, argv, "d:");
  64:     if (c == 'd') {
  65:         debug = fopen(optarg, "w");
  66:         if (debug == NULL)
  67:             exit(1);
  68:         fcntl(fileno(debug), F_SETFL, FAPPEND);
  69:     }
  70:     chdir("/");
  71:     freopen("/", "r", stdout);
  72:     freopen("/", "r", stderr);
  73:     untty();
  74:     signal(SIGHUP, SIG_IGN);
  75:     signal(SIGINT, SIG_IGN);
  76:     signal(SIGQUIT, SIG_IGN);
  77:     signal(SIGCHLD, reapchild);
  78:     time(&itime);
  79:     itime -= localtime(&itime)->tm_sec;
  80: 
  81:     for (;; itime+=60, slp()) {
  82:         struct stat cstat, lcstat;
  83:         int newcron, newloc;
  84: 
  85:         newcron = 0;
  86:         if (stat(crontab, &cstat) < 0)
  87:             cstat.st_mtime = 1;
  88:         if (cstat.st_mtime != filetime) {
  89:             filetime = cstat.st_mtime;
  90:             newcron++;
  91:         }
  92: 
  93:         newloc  = 0;
  94:         if (stat(loc_crontab, &lcstat) < 0)
  95:             lcstat.st_mtime = 1;
  96:         if (lcstat.st_mtime != lfiletime) {
  97:             lfiletime = lcstat.st_mtime;
  98:             newloc++;
  99:         }
 100: 
 101:         if (newcron || newloc) {
 102:             init();
 103:             append(crontab);
 104:             append(loc_crontab);
 105:             *listend++ = EOS;
 106:             *listend++ = EOS;
 107:         }
 108: 
 109:         loct = localtime(&itime);
 110:         loct->tm_mon++;      /* 1-12 for month */
 111:         if (loct->tm_wday == 0)
 112:             loct->tm_wday = 7;  /* sunday is 7, not 0 */
 113:         for(cp = list; *cp != EOS;) {
 114:             flag = 0;
 115:             cp = cmp(cp, loct->tm_min);
 116:             cp = cmp(cp, loct->tm_hour);
 117:             cp = cmp(cp, loct->tm_mday);
 118:             cp = cmp(cp, loct->tm_mon);
 119:             cp = cmp(cp, loct->tm_wday);
 120:             if(flag == 0)
 121:                 ex(cp);
 122:             while(*cp++ != 0)
 123:                 ;
 124:         }
 125:     }
 126: }
 127: 
 128: char *
 129: cmp(p, v)
 130: char *p;
 131: {
 132:     register char *cp;
 133: 
 134:     cp = p;
 135:     switch(*cp++) {
 136: 
 137:     case EXACT:
 138:         if (*cp++ != v)
 139:             flag++;
 140:         return(cp);
 141: 
 142:     case ANY:
 143:         return(cp);
 144: 
 145:     case LIST:
 146:         while(*cp != LIST)
 147:             if(*cp++ == v) {
 148:                 while(*cp++ != LIST)
 149:                     ;
 150:                 return(cp);
 151:             }
 152:         flag++;
 153:         return(cp+1);
 154: 
 155:     case RANGE:
 156:         if(*cp > v || cp[1] < v)
 157:             flag++;
 158:         return(cp+2);
 159:     }
 160:     if(cp[-1] != v)
 161:         flag++;
 162:     return(cp);
 163: }
 164: 
 165: slp()
 166: {
 167:     register i;
 168:     time_t t;
 169: 
 170:     time(&t);
 171:     i = itime - t;
 172:     if(i < -60 * 60 || i > 60 * 60) {
 173:         itime = t;
 174:         i = 60 - localtime(&itime)->tm_sec;
 175:         itime += i;
 176:     }
 177:     if(i > 0)
 178:         sleep(i);
 179: }
 180: 
 181: ex(s)
 182: char *s;
 183: {
 184:     int st;
 185:     register struct passwd *pwd;
 186:     char user[BUFSIZ];
 187:     char *c = user;
 188:     int pid;
 189: 
 190:     if (fork()) {
 191:         return;
 192:     }
 193: 
 194:     pid = getpid();
 195:     while(*s != ' ' && *s != '\t')
 196:         *c++ = *s++;
 197:     *c = '\0';
 198:     s++;
 199:     if ((pwd = getpwnam(user)) == NULL) {
 200:         dprintf(debug, "%d: cannot find %s\n", pid, user),
 201:             fflush(debug);
 202:         exit(1);
 203:     }
 204:     (void) setgid(pwd->pw_gid);
 205:     initgroups(pwd->pw_name, pwd->pw_gid);
 206:     (void) setuid(pwd->pw_uid);
 207:     freopen("/", "r", stdin);
 208:     dprintf(debug, "%d: executing %s", pid, s), fflush (debug);
 209:     execl("/bin/sh", "sh", "-c", s, 0);
 210:     dprintf(debug, "%d: cannot execute sh\n", pid), fflush (debug);
 211:     exit(0);
 212: }
 213: 
 214: init()
 215: {
 216:     /*
 217: 	 * Don't free in case was longer than LISTS.  Trades off
 218: 	 * the rare case of crontab shrinking vs. the common case of
 219: 	 * extra realloc's needed in append() for a large crontab.
 220: 	 */
 221:     if (list == 0) {
 222:         list = malloc(LISTS);
 223:         listsize = LISTS;
 224:     }
 225:     listend = list;
 226: }
 227: 
 228: append(fn)
 229: char *fn;
 230: {
 231:     register i, c;
 232:     register char *cp;
 233:     register char *ocp;
 234:     register int n;
 235: 
 236:     if (freopen(fn, "r", stdin) == NULL)
 237:         return;
 238:     cp = listend;
 239: loop:
 240:     if(cp > list+listsize-MAXLIN) {
 241:         int length = cp - list;
 242: 
 243:         listsize += LISTS;
 244:         list = realloc(list, listsize);
 245:         cp = list + length;
 246:     }
 247:     ocp = cp;
 248:     for(i=0;; i++) {
 249:         do
 250:             c = getchar();
 251:         while(c == ' ' || c == '\t')
 252:             ;
 253:         if(c == EOF || c == '\n')
 254:             goto ignore;
 255:         if(i == 5)
 256:             break;
 257:         if(c == '*') {
 258:             *cp++ = ANY;
 259:             continue;
 260:         }
 261:         if ((n = number(c)) < 0)
 262:             goto ignore;
 263:         c = getchar();
 264:         if(c == ',')
 265:             goto mlist;
 266:         if(c == '-')
 267:             goto mrange;
 268:         if(c != '\t' && c != ' ')
 269:             goto ignore;
 270:         *cp++ = EXACT;
 271:         *cp++ = n;
 272:         continue;
 273: 
 274:     mlist:
 275:         *cp++ = LIST;
 276:         *cp++ = n;
 277:         do {
 278:             if ((n = number(getchar())) < 0)
 279:                 goto ignore;
 280:             *cp++ = n;
 281:             c = getchar();
 282:         } while (c==',');
 283:         if(c != '\t' && c != ' ')
 284:             goto ignore;
 285:         *cp++ = LIST;
 286:         continue;
 287: 
 288:     mrange:
 289:         *cp++ = RANGE;
 290:         *cp++ = n;
 291:         if ((n = number(getchar())) < 0)
 292:             goto ignore;
 293:         c = getchar();
 294:         if(c != '\t' && c != ' ')
 295:             goto ignore;
 296:         *cp++ = n;
 297:     }
 298:     while(c != '\n') {
 299:         if(c == EOF)
 300:             goto ignore;
 301:         if(c == '%')
 302:             c = '\n';
 303:         *cp++ = c;
 304:         c = getchar();
 305:     }
 306:     *cp++ = '\n';
 307:     *cp++ = 0;
 308:     goto loop;
 309: 
 310: ignore:
 311:     cp = ocp;
 312:     while(c != '\n') {
 313:         if(c == EOF) {
 314:             fclose(stdin);
 315:             listend = cp;
 316:             return;
 317:         }
 318:         c = getchar();
 319:     }
 320:     goto loop;
 321: }
 322: 
 323: number(c)
 324: register c;
 325: {
 326:     register n = 0;
 327: 
 328:     while (isdigit(c)) {
 329:         n = n*10 + c - '0';
 330:         c = getchar();
 331:     }
 332:     ungetc(c, stdin);
 333:     if (n>=100)
 334:         return(-1);
 335:     return(n);
 336: }
 337: 
 338: reapchild()
 339: {
 340:     union wait status;
 341:     int pid;
 342: 
 343:     while ((pid = wait3(&status, WNOHANG, 0)) > 0)
 344:         dprintf(debug, "%d: child exits with signal %d status %d\n",
 345:             pid, status.w_termsig, status.w_retcode),
 346:             fflush (debug);
 347: }
 348: 
 349: untty()
 350: {
 351:     int i;
 352: 
 353:     i = open("/dev/tty", O_RDWR);
 354:     if (i >= 0) {
 355:         ioctl(i, TIOCNOTTY, (char *)0);
 356:         (void) close(i);
 357:     }
 358: }

Defined functions

append defined in line 228; used 2 times
cmp defined in line 128; used 6 times
ex defined in line 181; used 1 times
init defined in line 214; used 1 times
main defined in line 50; never used
number defined in line 323; used 3 times
reapchild defined in line 338; used 3 times
slp defined in line 165; used 1 times
  • in line 81
untty defined in line 349; used 1 times
  • in line 73

Defined variables

crontab defined in line 34; used 2 times
flag defined in line 42; used 6 times
list defined in line 43; used 9 times
listend defined in line 44; used 5 times
listsize defined in line 45; used 4 times
loc_crontab defined in line 35; used 2 times
loct defined in line 37; used 9 times
sccsid defined in line 2; never used

Defined macros

ANY defined in line 29; used 1 times
CRONTAB defined in line 21; used 2 times
CRONTABLOC defined in line 25; used 2 times
EOS defined in line 32; used 3 times
EXACT defined in line 28; used 1 times
LIST defined in line 30; used 4 times
LISTS defined in line 17; used 3 times
MAXLIN defined in line 18; used 1 times
RANGE defined in line 31; used 1 times
dprintf defined in line 48; used 4 times
Last modified: 1986-05-28
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 1989
Valid CSS Valid XHTML 1.0 Strict