Annotation of researchv10no/cmd/uucp/expfile.c, revision 1.1.1.1

1.1       root        1: /*     /sccs/src/cmd/uucp/s.expfile.c
                      2:        expfile.c       1.4     8/30/84 17:37:18
                      3: */
                      4: #include "uucp.h"
                      5: VERSION(@(#)expfile.c  1.4);
                      6: 
                      7: /*
                      8:  * expand file name expansion is based on first characters
                      9:  *     /       -> fully qualified pathname. no
                     10:  *                processing necessary
                     11:  *     ~       -> prepended with login directory
                     12:  *     ~/      -> prepended with Pubdir
                     13:  *     default -> prepended with current directory
                     14:  *     file    -> filename to expand
                     15:  * returns: 
                     16:  *     0       -> ok
                     17:  *      FAIL   -> no Wrkdir name available
                     18:  */
                     19: expfile(file)
                     20: register char *file;
                     21: {
                     22:        register char *fpart, *up;
                     23:        int uid;
                     24:        char user[NAMESIZE], save[MAXFULLNAME];
                     25: 
                     26:        strcpy(save, file);
                     27:        if (*file == '/')
                     28:            ;
                     29:        else if (*file ==  '~') {
                     30:                /* find / and copy user part */
                     31:                for (fpart = save + 1, up = user; *fpart != '\0'
                     32:                        && *fpart != '/'; fpart++)
                     33:                                *up++ = *fpart;
                     34:                *up = '\0';
                     35:                if ((user[0]=='\0') || (gninfo(user, &uid, file) != 0)){
                     36:                        (void) strcpy(file, Pubdir);
                     37:                }
                     38:                (void) strcat(file, fpart);
                     39:        }
                     40:        else {
                     41:                if (Wrkdir[0] == 0)
                     42:                        gwd(Wrkdir);
                     43:                if (Wrkdir[0] == '\0')
                     44:                        return(FAIL);
                     45:                (void) sprintf(file, "%s/%s", Wrkdir, save);
                     46:        }
                     47: 
                     48:        if (canPath(file) != 0) { /* I don't think this will ever fail */
                     49:                (void) strcpy(file, CORRUPTDIR);
                     50:                return(FAIL);
                     51:        }
                     52:        else
                     53:                return(0);
                     54: }
                     55: 
                     56: 
                     57: /*
                     58:  * make all necessary directories
                     59:  *     name    -> directory to make
                     60:  * return: 
                     61:  *     0       -> success
                     62:  *     FAIL    -> failure
                     63:  */
                     64: mkdirs(name)
                     65: register char *name;
                     66: {
                     67:        register char *p;
                     68:        char dir[MAXFULLNAME];
                     69: 
                     70:        strcpy(dir, name);
                     71:        if (*LASTCHAR(dir) != '/')
                     72:                (void) strcat(dir, "/");
                     73:        p = dir + 1;
                     74:        while (1) {
                     75:            if ((p = strchr(p, '/')) == NULL)
                     76:                return(0);
                     77:            *p = '\0';
                     78:            DEBUG(4, "mkdir - %s\n", dir);
                     79:            if (mkdirs2(dir, 0) == FAIL)
                     80:                return (FAIL);
                     81:            *p++ = '/';
                     82:        }
                     83: }
                     84: 
                     85: 
                     86: #ifdef ATTSV
                     87: /*
                     88:  * Make name a directory if it is not already a directory
                     89:  * ATTSV handling of setuid is less than convenient ...
                     90:  * return:
                     91:  *     0 -> ok
                     92:  *     FAIL -> failed
                     93:  */
                     94: 
                     95: mkdirs2(name, mask)
                     96: register char  *name;
                     97: register int   mask;
                     98: {
                     99:        int     ret, pid, status;
                    100:        char    *tail, nmbuf[MAXFULLNAME], *parent;
                    101:        struct stat     statbuf;
                    102: 
                    103:        if (DIRECTORY(name))
                    104:                return(0);              /* directory exists */
                    105: 
                    106:        /* in ATTSV the parent directory has to be writeable by real uid */
                    107:        (void) strcpy(nmbuf, name);
                    108: 
                    109:        /* get pathname of parent */
                    110:        tail = nmbuf + strlen(nmbuf) - 1;       /* last char in nmbuf */
                    111:        while (*tail == '/' && tail > nmbuf)    /* kill trailing slashes */
                    112:                *tail-- = '\0';
                    113: 
                    114:        /* is parent "."? */
                    115:        if ((tail = strrchr(nmbuf, '/')) != NULL) {
                    116:                *tail = '\0';
                    117:                parent = nmbuf;
                    118:        } else
                    119:                parent = ".";
                    120: 
                    121:        /* save mode of parent */
                    122:        if (stat(parent, &statbuf) != 0) {
                    123:            DEBUG(5, "CAN'T STAT PARENT DIRECTORY %s ", parent);
                    124:            DEBUG(5, "errno %d\n", errno);
                    125:            return(FAIL);
                    126:        }
                    127: 
                    128:        /* if it's already 0xx7 we don't have to change it */
                    129:        if ((statbuf.st_mode & 0777) != 0777) {
                    130:          /* make parent writable by all (thus by real uid) */
                    131:            if (chmod(parent, 0777) != 0) {
                    132:                DEBUG(5, "CAN'T CHMOD PARENT DIRECTORY %s ", parent);
                    133:                DEBUG(5, "errno %d\n", errno);
                    134:                return(FAIL);
                    135:            }
                    136:        }
                    137: 
                    138:        switch (pid = fork()) {
                    139:        case 0:                 /* child */
                    140:                umask(0);
                    141:                /* close stdout and stderr to fail quietly */
                    142:                close(1);
                    143:                close(2);
                    144:                execl("/bin/mkdir", "mkdir", name, 0);
                    145:                _exit(1);
                    146: 
                    147:        case -1:                /* fork failed */
                    148:                ASSERT(pid != -1, Ct_FORK, "mkdir", errno);
                    149: 
                    150:        default:                /* parent */
                    151:                break;
                    152:        }
                    153:        status = 1;
                    154:        while ((ret = wait(&status)) != pid && ret > 0);
                    155: 
                    156:        if (status != 0) {
                    157:            errent(Ct_CREATE, name, ret, sccsid, __FILE__, __LINE__);
                    158:            return(FAIL);
                    159:        }
                    160: 
                    161: 
                    162:        if ((statbuf.st_mode & 0777) != 0777) {
                    163:          /* restore mode of parent directory */
                    164:            if (chmod(parent, statbuf.st_mode & 0777) != 0) {
                    165:                errent(Ct_CHMOD, parent, errno, sccsid, __FILE__, __LINE__);
                    166:                DEBUG(5, "CAN'T CHMOD PARENT %s\n", parent);
                    167:                return(FAIL);
                    168:            }
                    169:        }
                    170: 
                    171:        if (Uid != 0) {
                    172:                if (setuid(Uid) != 0) {
                    173:                    DEBUG(5, "CAN'T SETUID %d\n", Uid);
                    174:                    return(FAIL);
                    175:                }
                    176:                if ( chmod(name, (mask ^ 0777) & 0777) != 0) {
                    177:                    errent(Ct_CHMOD, name, errno, sccsid, __FILE__, __LINE__);
                    178:                    return(FAIL);
                    179:                };
                    180:                if (chown(name, UUCPUID, getgid()) != 0) {
                    181:                    DEBUG(5, "CHOWN FAILED %s  ", name);
                    182:                    DEBUG(5, "errno %d\n", errno);
                    183:                    errent(Ct_CHOWN, name, errno, sccsid, __FILE__, __LINE__);
                    184:                    setuid(Euid);
                    185:                    return(FAIL);
                    186:                }
                    187:                setuid(Euid);
                    188:        }
                    189:        return(0);
                    190: }
                    191: #endif ATTSV
                    192: 
                    193: #ifdef V7
                    194: mkdirs2(name, mask)
                    195: register char  *name;
                    196: register int   mask;
                    197: {
                    198:        int     ret;
                    199:        int pid, rpid;
                    200:        if (DIRECTORY(name))
                    201:                return(0);              /* directory exists */
                    202: 
                    203:        if ((pid = fork()) == 0) {
                    204:                setuid(Euid);   /* this makes it trivial in V7 */
                    205:                umask(mask);
                    206:                /* close stdout and stderr to fail quietly */
                    207:                close(1);
                    208:                close(2);
                    209:                execl("/bin/mkdir", "mkdir", name, 0);
                    210:                _exit(1);
                    211:        }
                    212:        ret = 1;
                    213:        while ((rpid = wait(&ret)) > 0 && rpid != pid)
                    214:                ;
                    215: 
                    216:        if (ret != 0)           /* why should we abort if some remote tries */
                    217:            return(FAIL);       /* to make a garbage directory */
                    218: 
                    219:        return(0);
                    220: }
                    221: #endif V7
                    222: 
                    223: /*
                    224:  * expand file name and check return
                    225:  * print error if it failed.
                    226:  *     file    -> file name to check
                    227:  * returns: 
                    228:  *      0      -> ok
                    229:  *      FAIL   -> if expfile failed
                    230:  */
                    231: ckexpf(file)
                    232: char *file;
                    233: {
                    234:        if (expfile(file) == 0)
                    235:                return(0);
                    236: 
                    237:        fprintf(stderr, "Illegal filename (%s).\n", file);
                    238:        return(FAIL);
                    239: }
                    240: 
                    241: 
                    242: /*
                    243:  * make canonical path out of path passed as argument.
                    244:  *
                    245:  * Eliminate redundant self-references like // or /./
                    246:  * (A single terminal / will be preserved, however.)
                    247:  * Dispose of references to .. in the path names.
                    248:  * In relative path names, this means that .. or a/../..
                    249:  * will be treated as an illegal reference.
                    250:  * In full paths, .. is always allowed, with /.. treated as /
                    251:  *
                    252:  * returns:
                    253:  *     0       -> path is now in canonical form
                    254:  *     FAIL    -> relative path contained illegal .. reference
                    255:  */
                    256: 
                    257: int
                    258: canPath(path)
                    259: register char *path;   /* path is modified in place */
                    260: {
                    261:     register char *to, *fr;
                    262: 
                    263:     to = fr = path;
                    264:     if (*fr == '/') *to++ = *fr++;
                    265:     for (;;) {
                    266:        /* skip past references to self and validate references to .. */
                    267:        for (;;) {
                    268:            if (*fr == '/') {
                    269:                fr++;
                    270:                continue;
                    271:            }
                    272:            if ((strncmp(fr, "./", 2) == SAME) || EQUALS(fr, ".")) {
                    273:                fr++;
                    274:                continue;
                    275:            }
                    276:            if ((strncmp(fr, "../", 3) == SAME) || EQUALS(fr, "..")) {
                    277:                fr += 2;
                    278:                /*      /.. is /        */
                    279:                if (((to - 1) == path) && (*path == '/')) continue;
                    280:                /* error if no previous component */
                    281:                if (to <= path) return (FAIL);
                    282:                /* back past previous component */
                    283:                while ((--to > path) && (to[-1] != '/'));
                    284:                continue;
                    285:            }
                    286:            break;
                    287:        }
                    288:        /*
                    289:         * What follows is a legitimate component,
                    290:         * terminated by a null or a /
                    291:         */
                    292:        if (*fr == '\0') break;
                    293:        while ((*to++ = *fr) && (*fr++ != '/'));
                    294:     }
                    295:     /* null path is . */
                    296:     if (to == path) *to++ = '.';
                    297:     *to = '\0';
                    298:     return (0);
                    299: }

unix.superglobalmegacorp.com

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