Annotation of 43BSDTahoe/bin/chmod.c, revision 1.1

1.1     ! root        1: /*
        !             2:  * Copyright (c) 1980, 1988 Regents of the University of California.
        !             3:  * All rights reserved.  The Berkeley software License Agreement
        !             4:  * specifies the terms and conditions for redistribution.
        !             5:  */
        !             6: 
        !             7: #ifndef lint
        !             8: char copyright[] =
        !             9: "@(#) Copyright (c) 1980, 1988 Regents of the University of California.\n\
        !            10:  All rights reserved.\n";
        !            11: #endif /* not lint */
        !            12: 
        !            13: #ifndef lint
        !            14: static char sccsid[] = "@(#)chmod.c    5.7 (Berkeley) 4/21/88";
        !            15: #endif /* not lint */
        !            16: 
        !            17: /*
        !            18:  * chmod options mode files
        !            19:  * where
        !            20:  *     mode is [ugoa][+-=][rwxXstugo] or an octal number
        !            21:  *     options are -Rf
        !            22:  */
        !            23: #include <stdio.h>
        !            24: #include <sys/types.h>
        !            25: #include <sys/stat.h>
        !            26: #include <sys/dir.h>
        !            27: 
        !            28: static int     fflag, rflag, retval, um;
        !            29: static char    *modestring, *ms;
        !            30: 
        !            31: main(argc, argv)
        !            32:        int argc;
        !            33:        char **argv;
        !            34: {
        !            35:        extern char *optarg;
        !            36:        extern int optind, opterr;
        !            37:        int ch;
        !            38: 
        !            39:        /*
        !            40:         * since "-[rwx]" etc. are valid file modes, we don't let getopt(3)
        !            41:         * print error messages, and we mess around with optind as necessary.
        !            42:         */
        !            43:        opterr = 0;
        !            44:        while ((ch = getopt(argc, argv, "Rf")) != EOF)
        !            45:                switch((char)ch) {
        !            46:                case 'R':
        !            47:                        rflag++;
        !            48:                        break;
        !            49:                case 'f':
        !            50:                        fflag++;
        !            51:                        break;
        !            52:                case '?':
        !            53:                default:
        !            54:                        --optind;
        !            55:                        goto done;
        !            56:                }
        !            57: done:  argv += optind;
        !            58:        argc -= optind;
        !            59: 
        !            60:        if (argc < 2) {
        !            61:                fputs("usage: chmod [-Rf] [ugoa][+-=][rwxXstugo] file ...\n",
        !            62:                    stderr);
        !            63:                exit(-1);
        !            64:        }
        !            65: 
        !            66:        modestring = *argv;
        !            67:        um = umask(0);
        !            68:        (void)newmode((u_short)0);
        !            69: 
        !            70:        while (*++argv)
        !            71:                change(*argv);
        !            72:        exit(retval);
        !            73: }
        !            74: 
        !            75: change(file)
        !            76:        char *file;
        !            77: {
        !            78:        register DIR *dirp;
        !            79:        register struct direct *dp;
        !            80:        struct stat buf;
        !            81: 
        !            82:        if (lstat(file, &buf) || chmod(file, newmode(buf.st_mode))) {
        !            83:                err(file);
        !            84:                return;
        !            85:        }
        !            86:        if (rflag && ((buf.st_mode & S_IFMT) == S_IFDIR)) {
        !            87:                if (chdir(file) < 0 || !(dirp = opendir("."))) {
        !            88:                        err(file);
        !            89:                        return;
        !            90:                }
        !            91:                for (dp = readdir(dirp); dp; dp = readdir(dirp)) {
        !            92:                        if (dp->d_name[0] == '.' && (!dp->d_name[1] ||
        !            93:                            dp->d_name[1] == '.' && !dp->d_name[2]))
        !            94:                                continue;
        !            95:                        change(dp->d_name);
        !            96:                }
        !            97:                closedir(dirp);
        !            98:                if (chdir("..")) {
        !            99:                        err("..");
        !           100:                        exit(fflag ? 0 : -1);
        !           101:                }
        !           102:        }
        !           103: }
        !           104: 
        !           105: err(s)
        !           106:        char *s;
        !           107: {
        !           108:        if (fflag)
        !           109:                return;
        !           110:        fputs("chmod: ", stderr);
        !           111:        perror(s);
        !           112:        retval = -1;
        !           113: }
        !           114: 
        !           115: newmode(nm)
        !           116:        u_short nm;
        !           117: {
        !           118:        register int o, m, b;
        !           119: 
        !           120:        ms = modestring;
        !           121:        m = abs();
        !           122:        if (*ms == '\0')
        !           123:                return (m);
        !           124:        do {
        !           125:                m = who();
        !           126:                while (o = what()) {
        !           127:                        b = where((int)nm);
        !           128:                        switch (o) {
        !           129:                        case '+':
        !           130:                                nm |= b & m;
        !           131:                                break;
        !           132:                        case '-':
        !           133:                                nm &= ~(b & m);
        !           134:                                break;
        !           135:                        case '=':
        !           136:                                nm &= ~m;
        !           137:                                nm |= b & m;
        !           138:                                break;
        !           139:                        }
        !           140:                }
        !           141:        } while (*ms++ == ',');
        !           142:        if (*--ms) {
        !           143:                fputs("chmod: invalid mode.\n", stderr);
        !           144:                exit(-1);
        !           145:        }
        !           146:        return ((int)nm);
        !           147: }
        !           148: 
        !           149: abs()
        !           150: {
        !           151:        register int c, i;
        !           152: 
        !           153:        i = 0;
        !           154:        while ((c = *ms++) >= '0' && c <= '7')
        !           155:                i = (i << 3) + (c - '0');
        !           156:        ms--;
        !           157:        return (i);
        !           158: }
        !           159: 
        !           160: #define        USER    05700   /* user's bits */
        !           161: #define        GROUP   02070   /* group's bits */
        !           162: #define        OTHER   00007   /* other's bits */
        !           163: #define        ALL     01777   /* all (note absence of setuid, etc) */
        !           164: 
        !           165: #define        READ    00444   /* read permit */
        !           166: #define        WRITE   00222   /* write permit */
        !           167: #define        EXEC    00111   /* exec permit */
        !           168: #define        SETID   06000   /* set[ug]id */
        !           169: #define        STICKY  01000   /* sticky bit */
        !           170: 
        !           171: who()
        !           172: {
        !           173:        register int m;
        !           174: 
        !           175:        m = 0;
        !           176:        for (;;) switch (*ms++) {
        !           177:        case 'u':
        !           178:                m |= USER;
        !           179:                continue;
        !           180:        case 'g':
        !           181:                m |= GROUP;
        !           182:                continue;
        !           183:        case 'o':
        !           184:                m |= OTHER;
        !           185:                continue;
        !           186:        case 'a':
        !           187:                m |= ALL;
        !           188:                continue;
        !           189:        default:
        !           190:                ms--;
        !           191:                if (m == 0)
        !           192:                        m = ALL & ~um;
        !           193:                return (m);
        !           194:        }
        !           195: }
        !           196: 
        !           197: what()
        !           198: {
        !           199:        switch (*ms) {
        !           200:        case '+':
        !           201:        case '-':
        !           202:        case '=':
        !           203:                return (*ms++);
        !           204:        }
        !           205:        return (0);
        !           206: }
        !           207: 
        !           208: where(om)
        !           209:        register int om;
        !           210: {
        !           211:        register int m;
        !           212: 
        !           213:        m = 0;
        !           214:        switch (*ms) {
        !           215:        case 'u':
        !           216:                m = (om & USER) >> 6;
        !           217:                goto dup;
        !           218:        case 'g':
        !           219:                m = (om & GROUP) >> 3;
        !           220:                goto dup;
        !           221:        case 'o':
        !           222:                m = (om & OTHER);
        !           223:        dup:
        !           224:                m &= (READ|WRITE|EXEC);
        !           225:                m |= (m << 3) | (m << 6);
        !           226:                ++ms;
        !           227:                return (m);
        !           228:        }
        !           229:        for (;;) switch (*ms++) {
        !           230:        case 'r':
        !           231:                m |= READ;
        !           232:                continue;
        !           233:        case 'w':
        !           234:                m |= WRITE;
        !           235:                continue;
        !           236:        case 'x':
        !           237:                m |= EXEC;
        !           238:                continue;
        !           239:        case 'X':
        !           240:                if ((om & S_IFDIR) || (om & EXEC))
        !           241:                        m |= EXEC;
        !           242:                continue;
        !           243:        case 's':
        !           244:                m |= SETID;
        !           245:                continue;
        !           246:        case 't':
        !           247:                m |= STICKY;
        !           248:                continue;
        !           249:        default:
        !           250:                ms--;
        !           251:                return (m);
        !           252:        }
        !           253: }

unix.superglobalmegacorp.com

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