Annotation of coherent/d/usr/lib/atrun.c, revision 1.1

1.1     ! root        1: static char Copyright[] =      "$Copyright: (c) 1985, INETCO Systems, Ltd.$";
        !             2: static char Release[] =                "$Release: INETCO COHERENT V8.0$";
        !             3: static char Date[] =           "$Date: 91/04/19 12:26:17 $";
        !             4: 
        !             5: /* $Header: /newbits/usr/lib/RCS/atrun.c,v 1.1 91/04/19 12:26:17 bin Exp $
        !             6:  *
        !             7:  *     The information contained herein is a trade secret of Mark Williams
        !             8:  *     Company, and  is confidential information.  It is provided  under a
        !             9:  *     license agreement,  and may be  copied or disclosed  only under the
        !            10:  *     terms of  that agreement.  Any  reproduction or disclosure  of this
        !            11:  *     material without the express written authorization of Mark Williams
        !            12:  *     Company or persuant to the license agreement is unlawful.
        !            13:  * 
        !            14:  *     Coherent Version 2.3.38
        !            15:  *     Copyright (c) 1982, 1983, 1984.
        !            16:  *     An unpublished work by Mark Williams Company, Chicago.
        !            17:  *     All rights reserved.
        !            18:  */
        !            19: 
        !            20: /*
        !            21:  * Atrun is the daemon which is regularly invoked by cron inorder
        !            22:  * to run scripts saved by at.  It runs the files by changeing its
        !            23:  * uid and gid to the owner and then running a shell on them.
        !            24:  * In order to have the ability to set its uid and group id, it
        !            25:  * must be set uid to root.
        !            26:  * Since anyone can write into the at spooling directory, for a
        !            27:  * script to be run, it must have the set uid, set gid and owner
        !            28:  * execute bits set.
        !            29:  *
        !            30:  * $Log:       /newbits/usr/lib/RCS/atrun.c,v $
        !            31:  * Revision 1.1        91/04/19  12:26:17      bin
        !            32:  * Initial revision
        !            33:  * 
        !            34:  * Revision 1.1        89/04/03  13:02:41      src
        !            35:  * Initial revision
        !            36:  * 
        !            37:  *     85/02/11        Allan Cornish   eliminated stdio functions.
        !            38:  */
        !            39: 
        !            40: #include <stdio.h>
        !            41: #include <sys/types.h>
        !            42: #include <ctype.h>
        !            43: #include <sys/dir.h>
        !            44: #include <time.h>
        !            45: #include <setjmp.h>
        !            46: #include <sys/stat.h>
        !            47: 
        !            48: 
        !            49: #define        MODE    06100                   /* set uid, set gid, owner exec */
        !            50: #define        TRUE    (0 == 0)
        !            51: #define FALSE  (0 != 0)
        !            52: #define        STDIN   0                       /* standard input file descriptor */
        !            53: #define        STDOUT  1                       /* standard output file descriptor */
        !            54: #define        STDERR  2                       /* standard error file descriptor */
        !            55: #define        RW      2                       /* open code for read and write */
        !            56: 
        !            57: 
        !            58: struct tm      *now;                   /* current time */
        !            59: char           atdir[] = "/usr/spool/at";
        !            60: jmp_buf                cerror;                 /* where to go if file is strange */
        !            61: int            atfd;                   /* stream for file atdir */
        !            62: 
        !            63: 
        !            64: main()
        !            65: {
        !            66:        register struct direct *dp;
        !            67:        register int n;
        !            68:        time_t          ct;
        !            69:        time_t          time();
        !            70:        static char dbuf[BUFSIZ];
        !            71: 
        !            72:        if (chdir(atdir) < 0)
        !            73:                exit(1);
        !            74: 
        !            75:        time(&ct);
        !            76:        now = localtime(&ct);
        !            77:        if ((atfd = open(".", 0)) < 0)
        !            78:                exit(1);
        !            79: 
        !            80:        while ((n = read( atfd, dbuf, sizeof dbuf)) > 0) {
        !            81: 
        !            82:                dp = (struct direct *) &dbuf[n];
        !            83: 
        !            84:                while (--dp >= dbuf)
        !            85:                        if (dp->d_ino)
        !            86:                                check(dp);
        !            87:        }
        !            88:        return (0);
        !            89: }
        !            90: 
        !            91: 
        !            92: /*
        !            93:  * Check checks to see if the file with directory entry `dent'
        !            94:  * should be executed.
        !            95:  */
        !            96: check(dent)
        !            97: register struct direct *dent;
        !            98: {
        !            99:        struct tm       dot;
        !           100: 
        !           101:        if (dent->d_ino == 0 || setjmp(cerror))
        !           102:                return;
        !           103:        gettime(&dot, dent->d_name);
        !           104:        if (cmptime(&dot, now) <= 0)
        !           105:                docmd(dent->d_name);
        !           106: }
        !           107: 
        !           108: 
        !           109: /*
        !           110:  * Gettime fills in certain fields in the struct tm `time' according to
        !           111:  * the file name `name'.  The file name is assumed to be of the form
        !           112:  * yymmddhhmm.xx where
        !           113:  *     yy is the last two digits of the year
        !           114:  *     mm is the month number (1 - 12)
        !           115:  *     dd is the day of the month (1 - 31)
        !           116:  *     hh is the hour
        !           117:  *     mm is the minute
        !           118:  * Only the corresponding fields of `time' are filled in.
        !           119:  */
        !           120: gettime(time, name)
        !           121: register struct tm     *time;
        !           122: register char          *name;
        !           123: {
        !           124:        time->tm_year = cnum2(name);
        !           125:        name += 2;
        !           126: 
        !           127:        /*
        !           128:         * This kludge will fail in 2070.
        !           129:         */
        !           130:        if (time->tm_year < 70)
        !           131:                time->tm_year += 100;
        !           132: 
        !           133:        time->tm_mon = cnum2(name) - 1;
        !           134:        name += 2;
        !           135:        time->tm_mday = cnum2(name);
        !           136:        name += 2;
        !           137:        time->tm_hour = cnum2(name);
        !           138:        name += 2;
        !           139:        time->tm_min = cnum2(name);
        !           140:        if (name[2] != '.')
        !           141:                longjmp(cerror, TRUE);
        !           142: }
        !           143: 
        !           144: 
        !           145: /*
        !           146:  * Cnum2 converts the first two characters of the string `str'
        !           147:  * to a number.
        !           148:  */
        !           149: cnum2(str)
        !           150: register char  *str;
        !           151: {
        !           152:        register int    res,
        !           153:                        i;
        !           154: 
        !           155:        for (res=0, i=2; --i >= 0; ++str) {
        !           156:                if (!isascii(*str) || !isdigit(*str))
        !           157:                        longjmp(cerror, TRUE);
        !           158:                res *= 10;
        !           159:                res += *str - '0';
        !           160:        }
        !           161:        return (res);
        !           162: }
        !           163: 
        !           164: 
        !           165: /*
        !           166:  * Cmptime compares the two struct tm's `a' and `b'.  It returns
        !           167:  * a number which compares to zero in the same way that `a' compares
        !           168:  * to `b'.
        !           169:  */
        !           170: cmptime(a, b)
        !           171: register struct tm     *a,
        !           172:                        *b;
        !           173: {
        !           174:        register int    res;
        !           175: 
        !           176:        if ((res = a->tm_year - b->tm_year) != 0)
        !           177:                return (res);
        !           178:        if ((res = a->tm_mon - b->tm_mon) != 0)
        !           179:                return (res);
        !           180:        if ((res = a->tm_mday - b->tm_mday) != 0)
        !           181:                return (res);
        !           182:        if ((res = a->tm_hour - b->tm_hour) != 0)
        !           183:                return (res);
        !           184:        return (a->tm_min - b->tm_min);
        !           185: }
        !           186: 
        !           187: 
        !           188: /*
        !           189:  * Docmd executes the shell command file `file'.  This entails
        !           190:  * forking of a child which changes its user and group id and
        !           191:  * then calls the shell.
        !           192:  */
        !           193: docmd(file)
        !           194: char   *file;
        !           195: {
        !           196:        register int    fd;
        !           197:        char            cbuf[DIRSIZ + 2];
        !           198:        struct stat     sbuf;
        !           199: 
        !           200:        if (fork() != 0)
        !           201:                return;
        !           202:        close(atfd);
        !           203:        strncpy(cbuf, file, DIRSIZ+1);
        !           204:        if (stat(cbuf, &sbuf) != 0)
        !           205:                exit(1);
        !           206:        if ((MODE & ~sbuf.st_mode) != 0)
        !           207:                exit(1);
        !           208:        if (setgid(sbuf.st_gid) != 0)
        !           209:                exit(1);
        !           210:        if (setuid(sbuf.st_uid) != 0)
        !           211:                exit(1);
        !           212:        if ((fd = open("/dev/null", RW)) == EOF)
        !           213:                exit(1);
        !           214:        dup2(fd, STDIN);
        !           215:        dup2(fd, STDOUT);
        !           216:        dup2(fd, STDERR);
        !           217:        close(fd);
        !           218:        strcat(cbuf, "&");
        !           219:        execle("/bin/sh", "sh", "-c", cbuf, NULL, NULL);
        !           220:        exit(1);
        !           221: }

unix.superglobalmegacorp.com

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