Annotation of 43BSDTahoe/bin/chmod.c, revision 1.1.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.