Annotation of coherent/d/usr/lib/atrun.c, revision 1.1.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.