Annotation of researchv10no/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:                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.