Annotation of coherent/d/etc/SYSVcron/src/cron.new, revision 1.1

1.1     ! root        1: /* 
        !             2:  *     The information contained herein is a trade secret of Mark Williams
        !             3:  *     Company, and  is confidential information.  It is provided  under a
        !             4:  *     license agreement,  and may be  copied or disclosed  only under the
        !             5:  *     terms of  that agreement.  Any  reproduction or disclosure  of this
        !             6:  *     material without the express written authorization of Mark Williams
        !             7:  *     Company or persuant to the license agreement is unlawful.
        !             8:  *
        !             9:  *     An unpublished work by Mark Williams Company, Chicago.
        !            10:  *     All rights reserved.
        !            11:  */
        !            12: 
        !            13: /* cron.c
        !            14:  *
        !            15:  * Execute commands stored in /usr/lib/crontab if it exist (3.2.0 compatibility)
        !            16:  * as daemon.
        !            17:  * Otherwise execute crontabs from /usr/spool/cron/crontabs.
        !            18:  * It sets uid and gid to user which crontab is going to be executed.
        !            19:  *
        !            20:  * $ 12-10-1991 vlad (Vladimir Smelyansky)
        !            21:  *
        !            22:  */
        !            23: #include <stdio.h>
        !            24: #include <time.h>
        !            25: #include <signal.h>
        !            26: #include <sys/msig.h>
        !            27: #include <errno.h>
        !            28: #include <ctype.h>
        !            29: #include <pwd.h>
        !            30: #include <sys/types.h>
        !            31: #include <dirent.h>
        !            32: #include "cron.h"
        !            33: 
        !            34: /*
        !            35:  * Time field types.
        !            36:  */
        !            37: #define        MIN     0
        !            38: #define HOUR   1
        !            39: #define        MDAY    2
        !            40: #define        MON     3
        !            41: #define WDAY   4
        !            42: 
        !            43: /*
        !            44:  * (Finite) States in valid().
        !            45:  */
        !            46: #define START  0
        !            47: #define INT    1
        !            48: #define INTDASH        2
        !            49: #define RANGE  3
        !            50: #define STR    4
        !            51: #define STRPLUS        5
        !            52: #define ERR    6
        !            53: #define END    7
        !            54: #define GLOB   ('*')
        !            55: 
        !            56: /*
        !            57:  * Tokens returned by gettoken(). Tokens are integers. EOF is also a token.
        !            58:  * INT, STR and GLOB above are also tokens.
        !            59:  */
        !            60: #define DASH   ('-')
        !            61: #define COMMA  (',')
        !            62: #define WS     (' ')
        !            63: #define PERCENT        (-2)
        !            64: #define NEWLINE (-3)
        !            65: 
        !            66: extern DIR             *opendir();
        !            67: extern struct dirent   *readdir();
        !            68: extern char            *realloc();
        !            69: 
        !            70: extern int     set_uid();      /* Set UID */
        !            71: extern FILE    *fpOpenTable(); /* Open crintable */
        !            72: extern int     lock();         /* Write a lock file */
        !            73: extern FILE    *cronpipe();    /* Popen for cron */
        !            74: 
        !            75: extern void    mail_entry();   /* Send mail to user if command failed */
        !            76: extern child_id        *add_entry(),   /* Add an new entry to a link list */
        !            77:                *find_entry(),  /* Find an entry in the link list */
        !            78:                *del_entry();   /* Remove an entry from the link list */
        !            79: 
        !            80: int ifmail();
        !            81: 
        !            82: child_id       *current;       /* Pointer to the current structure */
        !            83: char   acRealUser[MAX_UNAME];  /* Real user name */
        !            84: 
        !            85: int    mailFlag = TRUE;
        !            86: int    flag320 = FALSE;
        !            87: 
        !            88: struct tm *tm;
        !            89: time_t clock;
        !            90: int    tmfield[5];
        !            91: FILE   *f;
        !            92: extern int     errno;
        !            93: 
        !            94: int    ugtokflag = FALSE;
        !            95: int    ugtoken;
        !            96: int    ufetflag = FALSE;
        !            97: int    ufetval;
        !            98: int    set_uid_flag = FALSE;
        !            99: 
        !           100: char   *tokbuf;
        !           101: int    buflen = MAX_STR_LEN;
        !           102: char   crontab[] = "/usr/lib/crontab";
        !           103: DIR    *dirp = NULL;
        !           104: struct dirent  *dp;
        !           105: 
        !           106: main()
        !           107: {
        !           108:        int     n;
        !           109:        int     child_pid;
        !           110: 
        !           111:        sigsetup();
        !           112: 
        !           113:        tokbuf = malloc(buflen);
        !           114:        /* Check if crond chould be into cron 320 mode */
        !           115:        if ((f = fopen(crontab, "r")) != NULL) {
        !           116:                fclose(f);
        !           117:                chdir("/bin");  /* Under 3.2.0 cron started from /bin. */
        !           118:                flag320 = TRUE;
        !           119:        }               
        !           120: 
        !           121:        if (flag320 == FALSE)   {
        !           122:                /* Check if cron was fired. Do it only for SV cron. */
        !           123:                if (lock(F_LOCK) == FALSE) {
        !           124:                        fprintf(stderr, "crond: locked.\n");
        !           125:                        exit(1);
        !           126:                }
        !           127:                /* Open dirp only once */
        !           128:                /*if ((dirp = opendir(D_SPOOL)) == NULL) {
        !           129:                        fprintf(stderr, 
        !           130:                                 "crond: cannot open directory %s.\n", D_SPOOL);
        !           131:                        exit(1);
        !           132:                }*/
        !           133:        }
        !           134: 
        !           135: #if !DEBUG
        !           136:        /* Disassociate from controling terminal and process
        !           137:         * group. Close all open files.
        !           138:         */
        !           139:        bedaemon();
        !           140: #endif                 
        !           141: 
        !           142:        time(&clock);
        !           143:        tm = localtime(&clock);
        !           144:        alarm(61 - tm->tm_sec);
        !           145: 
        !           146:        Dprint("Time is %s\n", ctime(&clock));
        !           147:        for (;;) {
        !           148:                system("echo Debug1 >/dev/console");
        !           149:                /* Put the time values into tmfield[] for easy reference.
        !           150:                 * localtime() gives tm_mon in the range 0-11, tm_wday, 0-6
        !           151:                 * (0=sunday). These are adjusted for cron's syntax.
        !           152:                 */
        !           153:                tmfield[MIN]    = tm->tm_min;
        !           154:                tmfield[HOUR]   = tm->tm_hour;
        !           155:                tmfield[MDAY]   = tm->tm_mday;
        !           156:                tmfield[MON]    = tm->tm_mon + 1;
        !           157:                tmfield[WDAY]   = tm->tm_wday;
        !           158: 
        !           159:                if (flag320 == TRUE) {          /* Run 320 mode */
        !           160:                        system("echo Debug1 286>/dev/console");
        !           161:                        if ((f = fopen(crontab, "r")) != NULL) {
        !           162:                                Dprint("File pointer is 0x%x\n", f);
        !           163:                                strcpy(acRealUser, DAEMON);
        !           164:                                while (tex() != EOF)
        !           165:                                        ;
        !           166:                                fclose(f);
        !           167:                                while (wait(&n) != -1) 
        !           168:                                        ;
        !           169:                                if (errno == ECHILD)
        !           170:                                        pause();
        !           171:                        } else
        !           172:                                fprintf(stderr, "crond: cannot open %s\n", 
        !           173:                                                crontab);
        !           174:                } else {                        /* Run SV mode */
        !           175:                        system("echo Debug1 386>/dev/console");
        !           176:                        /* Open dirp only once */
        !           177:                        if (dirp != NULL)
        !           178:                                if ((dirp = opendir(D_SPOOL)) == NULL) {
        !           179:                                        fprintf(stderr, 
        !           180:                                 "crond: cannot open directory %s.\n", D_SPOOL);
        !           181:                                        exit(1);
        !           182:                                }
        !           183: 
        !           184:                        while ((dp = readdir(dirp)) != NULL) {
        !           185:                                char    Dbuf[80];
        !           186: 
        !           187:                                /* Skip '.' and '..' */
        !           188:                                if (!strcmp(dp->d_name, ".") ||
        !           189:                                                !strcmp(dp->d_name, ".."))
        !           190:                                        continue;
        !           191:                
        !           192:                                strcpy(acRealUser, dp->d_name);
        !           193:                                Dprint("User name is %s\n", acRealUser);
        !           194:                                set_uid_flag = FALSE; 
        !           195: 
        !           196:                                if ((f = fpOpenTable("r")) == NULL) {
        !           197:                                        fprintf(stderr, 
        !           198:                                           "crond: cannot open table '%s'\n", 
        !           199:                                           acRealUser);
        !           200:                                        sprintf(Dbuf,"crond: cannot open table"
        !           201:                                           " '%s'\n", acRealUser);
        !           202:                                           /*exit(1);*/
        !           203:                                }
        !           204:                                system("echo Debug >/dev/console");
        !           205:                        sprintf(Dbuf, "echo %s > /dev/console", dp->d_name);
        !           206:                                system(Dbuf);
        !           207:                                while (tex() != EOF)
        !           208:                                        ;
        !           209:                                fclose(f);
        !           210:                        } /* while readdir */
        !           211:                        system("echo Debug after while >/dev/console");
        !           212:                        rewinddir(dirp);
        !           213:                        /* Wait for the children */
        !           214:                        while ((child_pid = wait(&n)) != -1) {
        !           215:                                static child_id *pstDone;
        !           216: 
        !           217:                                Dprint("\nmain: child id %d",child_pid);
        !           218:                                Dprint("\treturn is %d\n", n);
        !           219:                                pstDone = find_entry(child_pid);
        !           220:                                if (n && ifmail(pstDone))
        !           221:                                        mail_entry(pstDone);
        !           222: 
        !           223:                                current = del_entry(pstDone);
        !           224:                        } /* while wait */
        !           225:                        if (errno == ECHILD)
        !           226:                                pause();
        !           227:                        
        !           228:                } /* if 320 */
        !           229:        } /* for */
        !           230: } /* main */
        !           231: 
        !           232: /*
        !           233:  * Check do user want to have a mail messages. 
        !           234:  */
        !           235: int ifmail(entry)
        !           236: child_id       *entry;
        !           237: {
        !           238:        char    *cBuf;
        !           239:        int     fd;     /* Descriptor of lock file */
        !           240: 
        !           241:        if ((cBuf = malloc(sizeof(D_MAIN) + strlen(entry->name) + 1)) == NULL) {
        !           242:                fprintf(stderr, "crond: out of memory\n");
        !           243:                return(0);      
        !           244:        }
        !           245:        sprintf(cBuf, "%s/%s", D_MAIN, entry->name);
        !           246:        if ((fd = open(cBuf, 0)) == -1) 
        !           247:                return(1);
        !           248:        close(fd);
        !           249:        return(0);
        !           250: }
        !           251: 
        !           252: /*
        !           253:  * Test and Execute: tests a crontab entry against the time fields in `tm' to
        !           254:  * see if it should be executed, if so it executes. f is left pointing to the
        !           255:  * next entry (line). Returns EOF when encountered, something else otherwise.
        !           256:  */
        !           257: tex()
        !           258: {
        !           259:        register int fieldnum;
        !           260: 
        !           261:        for (fieldnum = MIN; fieldnum <= WDAY; ++fieldnum)
        !           262:                if (!valid(fieldnum))
        !           263:                        return (skip_it());
        !           264:        return (do_it());
        !           265: }
        !           266: 
        !           267: /*
        !           268:  * Valid(fieldnum) parses the next time field from the current line in crontab
        !           269:  * and checks whether tmfield[fieldnum] satisfies the constraints of that time
        !           270:  * field. Returns TRUE if so, FALSE if not. Leaves f at the next field.
        !           271:  * Detects syntax errors in the time fields.
        !           272:  */
        !           273: valid(fieldnum)
        !           274: int fieldnum;
        !           275: {
        !           276:        register int t;
        !           277:        register int ival;
        !           278:        register int state = START;
        !           279:        int ival2;
        !           280:        int tm_val = tmfield[fieldnum];
        !           281: 
        !           282:        if (fieldnum == MIN) {
        !           283:                while ((t = gettoken()) == WS  ||  t == NEWLINE)
        !           284:                        ;
        !           285:                ungettoken(t);
        !           286:        }
        !           287: 
        !           288:        for (;;) {
        !           289:                t = gettoken();
        !           290:                switch (state) {
        !           291:                case START:
        !           292:                        switch (t) {
        !           293:                        case INT:
        !           294:                                if (strlen(tokbuf) <= 2) {
        !           295:                                        ival = atoi(tokbuf);
        !           296:                                        state = INT;
        !           297:                                }
        !           298:                                else
        !           299:                                        state = ERR;
        !           300:                                break;
        !           301:                        case GLOB:
        !           302:                                state = GLOB;
        !           303:                                break;
        !           304:                        case WS:
        !           305:                                state = END;
        !           306:                                break;
        !           307:                        default:
        !           308:                                state = ERR;
        !           309:                                break;
        !           310:                        }
        !           311:                        break;
        !           312:                case INT:
        !           313:                        if (t == COMMA  ||  t == WS) {
        !           314:                                if (ival == tm_val) {
        !           315:                                        while (t != WS)
        !           316:                                                t = gettoken();
        !           317:                                        return (TRUE);
        !           318:                                }
        !           319:                                state = (t == WS) ? END : START;
        !           320:                        }
        !           321:                        else if (t == DASH)
        !           322:                                state = INTDASH;
        !           323:                        else
        !           324:                                state = ERR;
        !           325:                        break;
        !           326:                case INTDASH:
        !           327:                        if (t == INT  &&  strlen(tokbuf) <= 2) {
        !           328:                                ival2 = atoi(tokbuf);
        !           329:                                state = RANGE;
        !           330:                        }
        !           331:                        else
        !           332:                                state = ERR;
        !           333:                        break;
        !           334:                case RANGE:
        !           335:                        if (t == COMMA  ||  t == WS) {
        !           336:                                if (ival <= tm_val  &&  tm_val <= ival2) {
        !           337:                                        while (t != WS)
        !           338:                                                t = gettoken();
        !           339:                                        return (TRUE);
        !           340:                                }
        !           341:                                state = (t == WS) ? END : START;
        !           342:                        }
        !           343:                        else
        !           344:                                state = ERR;
        !           345:                        break;
        !           346:                case GLOB:
        !           347:                        if (t == COMMA  ||  t == WS) {
        !           348:                                while (t != WS)
        !           349:                                        t = gettoken();
        !           350:                                return (TRUE);
        !           351:                        }
        !           352:                        else
        !           353:                                state = ERR;
        !           354:                        break;
        !           355:                }               /* End switch on state */
        !           356: 
        !           357:                if (state == END)
        !           358:                        return (FALSE);
        !           359:                if (state == ERR) {
        !           360:                        ungettoken(t);
        !           361:                        ungettoken(skip_it());
        !           362:                        return (FALSE);
        !           363:                }
        !           364:        }
        !           365: }
        !           366: 
        !           367: 
        !           368: ungettoken(t)
        !           369: int t;
        !           370: {
        !           371:        ugtokflag = TRUE;
        !           372:        ugtoken = t;
        !           373: }
        !           374: 
        !           375: gettoken()
        !           376: {
        !           377:        register int c;
        !           378:        register char *sp = tokbuf;
        !           379:        register char *mark;
        !           380:        int posn;
        !           381: 
        !           382:        if (ugtokflag) {
        !           383:                ugtokflag = FALSE;
        !           384:                return (ugtoken);
        !           385:        }
        !           386: 
        !           387:        switch (c = fetch()) {
        !           388:        case NEWLINE:
        !           389:        case EOF:
        !           390:        case PERCENT:
        !           391:                return (c);
        !           392:        case ' ':
        !           393:        case '\t':
        !           394:                while ((c = fetch()) == ' '  ||  c == '\t')
        !           395:                        ;
        !           396:                unfetch(c);
        !           397:                return (WS);
        !           398:        case '-':
        !           399:                return (DASH);
        !           400:        case ',':
        !           401:                return (COMMA);
        !           402:        case '*':
        !           403:                return (GLOB);
        !           404:        }
        !           405: 
        !           406: 
        !           407:        /*
        !           408:         * Case of INT. Place ascii digit string into tokbuf.
        !           409:         */
        !           410:        if (isdigit(c)) {
        !           411:                *sp++ = c;
        !           412:                while (isdigit(c = fetch()))
        !           413:                        *sp++ = c;
        !           414:                unfetch(c);
        !           415:                *sp = '\0';
        !           416:                return (INT);
        !           417:        }
        !           418: 
        !           419:        /*
        !           420:         * The only remaining possibility is the token STR or STRPLUS.
        !           421:         */
        !           422:        *sp++ = c;
        !           423:        mark = tokbuf + buflen - 2;
        !           424:        while ((c = fetch()) != EOF  &&  c != NEWLINE  &&  c != PERCENT) {
        !           425:                if (sp == mark) {
        !           426:                        posn = sp - tokbuf;
        !           427:                        tokbuf = realloc(tokbuf, (buflen += 128));
        !           428:                        sp = tokbuf + posn;
        !           429:                        mark = sp + buflen;
        !           430:                }
        !           431:                *sp++ = c;
        !           432:        }
        !           433:        *sp = '\0';
        !           434:        if (c == PERCENT)
        !           435:                return (STRPLUS);
        !           436:        unfetch(c);
        !           437:        return (STR);
        !           438: }
        !           439: 
        !           440: 
        !           441: unfetch(c)
        !           442: int c;
        !           443: {
        !           444:        ufetval = c;
        !           445:        ufetflag = TRUE;
        !           446: }
        !           447: 
        !           448: fetch()
        !           449: {
        !           450:        register int c;
        !           451:        register int c2;
        !           452: 
        !           453:        if (ufetflag) {
        !           454:                ufetflag = FALSE;
        !           455:                return (ufetval);
        !           456:        }
        !           457: 
        !           458:        for (;;)
        !           459:                switch (c = getc(f)) {
        !           460:                case '%':
        !           461:                        return (PERCENT);
        !           462:                case '\n':
        !           463:                        return (NEWLINE);
        !           464:                case '\\':
        !           465:                        if ((c2 = getc(f)) == '%')
        !           466:                                return ('%');
        !           467:                        else if (c2 == '\n')
        !           468:                                continue;
        !           469:                        else {
        !           470:                                ungetc(c2, f);
        !           471:                                return ('\\');
        !           472:                        }
        !           473:                default:
        !           474:                        return (c);
        !           475:                }
        !           476: }
        !           477: 
        !           478: 
        !           479: skip_it()
        !           480: {
        !           481:        register int t;
        !           482: 
        !           483:        while ((t = gettoken()) != EOF  &&  t != NEWLINE)
        !           484:                ;
        !           485:        return (t);
        !           486: }
        !           487: 
        !           488: do_it()
        !           489: {
        !           490:        register int c;
        !           491:        register FILE *fp;
        !           492: 
        !           493:        if ((c = gettoken()) != STR  &&  c != STRPLUS) {
        !           494:                ungettoken(c);
        !           495:                return (skip_it());
        !           496:        }
        !           497:        
        !           498:        Dprint("Tokken is %s\n", tokbuf);
        !           499: 
        !           500:        if ((fp = cronpipe(tokbuf, "w")) == NULL) {
        !           501:                fprintf(stderr, "crond:\tCould not popen: %s\n\t\
        !           502:                                errno = %d: %s.\n", tokbuf, errno, perror());
        !           503:                return (skip_it());
        !           504:        }
        !           505: 
        !           506:        if (c == STR) {
        !           507:                fclose(fp);
        !           508:                return (gettoken());
        !           509:        }
        !           510:        while ((c = fetch()) != NEWLINE  &&  c != EOF)
        !           511:                if (c == PERCENT)
        !           512:                        putc('\n', fp);
        !           513:                else
        !           514:                        putc(c, fp);
        !           515:        putc('\n', fp);
        !           516:        fclose(fp);
        !           517:        return(c);
        !           518: }
        !           519: 
        !           520: /*
        !           521:  * We have to catch all signals.
        !           522:  * Ignore signals INT, HUP, & PIPE.
        !           523:  * Reset time on ALRM.
        !           524:  * Remove lock file and take default action on the rest of them.
        !           525:  */
        !           526: sigsetup()
        !           527: {
        !           528:        register int    i;
        !           529:        int             catchalarm();   /* Catch alarm signal */
        !           530:        int             catchsignals(); /* Catch all signals */
        !           531: 
        !           532:        for (i = 1; i < NSIG; i++)
        !           533:                signal(i, catchsignals);
        !           534: 
        !           535:        signal(SIGINT, SIG_IGN);
        !           536:        signal(SIGHUP, SIG_IGN);
        !           537:        signal(SIGPIPE, SIG_IGN);
        !           538:        signal(SIGALRM, catchalarm);
        !           539: }
        !           540: 
        !           541: /*
        !           542:  * Remove lock file. Restore default action. Send the catched signal to itself.
        !           543:  */
        !           544: int catchsignals(sig)
        !           545: int    sig;
        !           546: {
        !           547:        unlink(F_LOCK);         /* Remove lock FIFO. Do not care if unlink */
        !           548:                                /* failed (case cron 3.2.0) */
        !           549:        Dprint("Remove lock file %s\n", F_LOCK);
        !           550:        signal(sig, SIG_DFL);   /* Reset to default */
        !           551:        kill(getpid(), sig);    /* Send catched signal */
        !           552:        wait(); 
        !           553: }
        !           554: 
        !           555: /* 
        !           556:  * Catch alarm.
        !           557:  */
        !           558: int catchalarm()
        !           559: {
        !           560:        signal(SIGALRM, catchalarm);
        !           561:        time(&clock);
        !           562:        tm = localtime(&clock);
        !           563:        alarm(61 - tm->tm_sec);
        !           564: }
        !           565: 

unix.superglobalmegacorp.com

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