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

unix.superglobalmegacorp.com

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