Annotation of 43BSD/etc/cron.c, revision 1.1.1.1

1.1       root        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: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.