Annotation of 43BSDReno/usr.sbin/cron/cron.c, revision 1.1

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

unix.superglobalmegacorp.com

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