Annotation of researchv9/cmd/cron.c, revision 1.1.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.