Annotation of researchv10no/cmd/odist/ape/tryperm.c, revision 1.1

1.1     ! root        1: #include <ctype.h>
        !             2: #include <stddef.h>
        !             3: #include <stdlib.h>
        !             4: #include <stdio.h>
        !             5: #include <string.h>
        !             6: #include <sys/types.h>
        !             7: #include <sys/stat.h>
        !             8: #include <fcntl.h>
        !             9: #include <unistd.h>
        !            10: #include "../pkg/ar.h"
        !            11: #include "dist.h"
        !            12: 
        !            13: /* determine if we can create the given pathname.  not a generally useful
        !            14:    function since it destroys the pathname in the process... */
        !            15: static int
        !            16: cancreate(char *path, int recurse)
        !            17: {
        !            18:        char *slash;
        !            19: 
        !            20:        for (;;) {
        !            21:                slash = strrchr(path, '/');
        !            22:                if (! slash)
        !            23:                        return 0;       /* supposed to be absolute */
        !            24:                *slash = '\0';
        !            25:                if (!*path)
        !            26:                        break;
        !            27:                if (access(path, W_OK) == 0)
        !            28:                        return 1;
        !            29:                if (!recurse)           /* for remove we check only one directory */
        !            30:                        return 0;
        !            31:                if (access(path, F_OK) == 0)
        !            32:                        return 0;
        !            33:        }
        !            34:        return access("/", W_OK) == 0;
        !            35: }
        !            36:                
        !            37: /*
        !            38:  * try the instructions of the package on the given fd against the
        !            39:  * permissions currently in the file system.  return 1 if we think we
        !            40:  * ought to go ahead and try inspkg.
        !            41:  */
        !            42: int
        !            43: tryperm(int fd)
        !            44: {
        !            45:        char armag[SARMAG];
        !            46:        struct ar_hdr arhdr;
        !            47:        long size;
        !            48:        char temp[L_tmpnam];
        !            49:        int tfd;
        !            50:        FILE *tfp;
        !            51:        int cmd, c, nf, retval;
        !            52:        char *path;
        !            53: 
        !            54:        /* return 1 so inspkg will be called and barf for us */
        !            55:        if (read(fd, armag, sizeof armag) != SARMAG || strncmp(armag, ARMAG, SARMAG))
        !            56:                return 1;
        !            57:        if (read(fd, (char *) &arhdr, sizeof arhdr) != sizeof arhdr)
        !            58:                return 1;
        !            59:        size = strtol(arhdr.ar_size, 0, 10);
        !            60:        tmpnam(temp);
        !            61:        close(creat(temp, 0600));       /* ape deficiency */
        !            62:        tfd = open(temp, O_RDWR);
        !            63:        if (tfd < 0) {
        !            64:                eprintf("can't create temp file %s for tryperm", temp);
        !            65:                remove(temp);           /* just in case something's *real* weird */
        !            66:                exit(1);
        !            67:        }
        !            68:        if (fdcopy(tfd, fd, size, 0) != size) {
        !            69:                close(tfd);
        !            70:                remove(temp);
        !            71:                eprintf("can't extract Instructions in tryperm");
        !            72:                return 1;               /* inspkg will (presumably) barf for us */
        !            73:        }
        !            74:        lseek(tfd, 0L, 0);
        !            75:        tfp = fdopen(tfd, "r");
        !            76: 
        !            77:        /* now that we have the instructions file, do the real meat.  */
        !            78:        retval = 1;
        !            79:        while ((cmd = getc(tfp)) != EOF) {
        !            80:                switch (cmd) {
        !            81:                case 'b':       /* b <mode> <dmaj> <dmin> <uid> <gid> <path> */
        !            82:                case 'c':       /* c <mode> <dmaj> <dmin> <uid> <gid> <path> */
        !            83:                        nf = 6;
        !            84:                        break;
        !            85:                case 'd':       /* d <mode> <uid> <gid> <path> */
        !            86:                case 'f':       /* f <component> <uid> <gid> <path> */
        !            87:                        nf = 4;
        !            88:                        break;
        !            89:                case 'l':       /* l <path1> <path2> */
        !            90:                case 's':       /* s <path1> <path2> */
        !            91:                        nf = 2;
        !            92:                        break;
        !            93:                case 'r':       /* r <path> */
        !            94:                case 'x':       /* x <command> */
        !            95:                case 'X':       /* X <path> */
        !            96:                        nf = 1;
        !            97:                        break;
        !            98:                default:
        !            99:                        goto reterr;
        !           100:                }
        !           101: 
        !           102:                /* get the last field of the line */
        !           103:                while (nf--) {
        !           104:                        while ((c = getc(tfp)) != EOF)
        !           105:                                if (!isspace(c))
        !           106:                                        break;
        !           107:                        if (c == EOF)
        !           108:                                goto reterr;
        !           109:                        ungetc(c, tfp);
        !           110:                        path = getpath(tfp);
        !           111:                }
        !           112: 
        !           113:                /* eat the newline */
        !           114:                if (getc(tfp) != '\n')
        !           115:                        goto reterr;
        !           116: 
        !           117:                switch (cmd) {
        !           118:                case 'X':
        !           119:                case 'x':
        !           120:                        break;
        !           121: 
        !           122:                case 'r':
        !           123:                        if (access(path, F_OK) != 0)
        !           124:                                break;
        !           125:                        if (cancreate(path, 0))
        !           126:                                break;
        !           127:                        retval = 0;
        !           128:                        goto out;
        !           129: 
        !           130:                default:
        !           131:                        if (cancreate(path, 1))
        !           132:                                break;
        !           133:                        retval = 0;
        !           134:                        goto out;
        !           135:                }
        !           136:        }
        !           137: 
        !           138:  out:
        !           139:        fclose(tfp);
        !           140:        remove(temp);
        !           141:        return retval;
        !           142: 
        !           143:  reterr:
        !           144:        /* there was some kind of bug in the format of the package.  return 1
        !           145:           and later on inspkg will generate an appropriate error message to
        !           146:           be returned to the remote system */
        !           147:        fclose(tfp);    
        !           148:        remove(temp);
        !           149:        return 1;
        !           150: }

unix.superglobalmegacorp.com

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