Annotation of researchv9/cmd/cron.c, revision 1.1

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

unix.superglobalmegacorp.com

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