Annotation of 41BSD/cmd/chmod.c, revision 1.1.1.1

1.1       root        1: static char *sccsid = "@(#)chmod.c     4.1 (Berkeley) 10/1/80";
                      2: /*
                      3:  * chmod [ugoa][+-=][rwxstugo] files
                      4:  *  change mode of files
                      5:  */
                      6: #include <stdio.h>
                      7: #include <sys/types.h>
                      8: #include <sys/stat.h>
                      9: 
                     10: #define        USER    05700   /* user's bits */
                     11: #define        GROUP   02070   /* group's bits */
                     12: #define        OTHER   00007   /* other's bits */
                     13: #define        ALL     01777   /* all (note absence of setuid, etc) */
                     14: 
                     15: #define        READ    00444   /* read permit */
                     16: #define        WRITE   00222   /* write permit */
                     17: #define        EXEC    00111   /* exec permit */
                     18: #define        SETID   06000   /* set[ug]id */
                     19: #define        STICKY  01000   /* sticky bit */
                     20: 
                     21: char   *ms;
                     22: int    um;
                     23: struct stat st;
                     24: 
                     25: main(argc,argv)
                     26: char **argv;
                     27: {
                     28:        register i;
                     29:        register char *p;
                     30:        int status = 0;
                     31: 
                     32:        if (argc < 3) {
                     33:                fprintf(stderr, "Usage: chmod [ugoa][+-=][rwxstugo] file ...\n");
                     34:                exit(255);
                     35:        }
                     36:        ms = argv[1];
                     37:        um = umask(0);
                     38:        newmode(0);
                     39:        for (i = 2; i < argc; i++) {
                     40:                p = argv[i];
                     41:                if (stat(p, &st) < 0) {
                     42:                        fprintf(stderr, "chmod: can't access %s\n", p);
                     43:                        ++status;
                     44:                        continue;
                     45:                }
                     46:                ms = argv[1];
                     47:                if (chmod(p, newmode(st.st_mode)) < 0) {
                     48:                        fprintf(stderr, "chmod: can't change %s\n", p);
                     49:                        ++status;
                     50:                        continue;
                     51:                }
                     52:        }
                     53:        exit(status);
                     54: }
                     55: 
                     56: newmode(nm)
                     57: unsigned nm;
                     58: {
                     59:        register o, m, b;
                     60: 
                     61:        m = abs();
                     62:        if (!*ms)
                     63:                return(m);
                     64:        do {
                     65:                m = who();
                     66:                while (o = what()) {
                     67:                        b = where(nm);
                     68:                        switch (o) {
                     69:                        case '+':
                     70:                                nm |= b & m;
                     71:                                break;
                     72:                        case '-':
                     73:                                nm &= ~(b & m);
                     74:                                break;
                     75:                        case '=':
                     76:                                nm &= ~m;
                     77:                                nm |= b & m;
                     78:                                break;
                     79:                        }
                     80:                }
                     81:        } while (*ms++ == ',');
                     82:        if (*--ms) {
                     83:                fprintf(stderr, "chmod: invalid mode\n");
                     84:                exit(255);
                     85:        }
                     86:        return(nm);
                     87: }
                     88: 
                     89: abs()
                     90: {
                     91:        register c, i;
                     92: 
                     93:        i = 0;
                     94:        while ((c = *ms++) >= '0' && c <= '7')
                     95:                i = (i << 3) + (c - '0');
                     96:        ms--;
                     97:        return(i);
                     98: }
                     99: 
                    100: who()
                    101: {
                    102:        register m;
                    103: 
                    104:        m = 0;
                    105:        for (;;) switch (*ms++) {
                    106:        case 'u':
                    107:                m |= USER;
                    108:                continue;
                    109:        case 'g':
                    110:                m |= GROUP;
                    111:                continue;
                    112:        case 'o':
                    113:                m |= OTHER;
                    114:                continue;
                    115:        case 'a':
                    116:                m |= ALL;
                    117:                continue;
                    118:        default:
                    119:                ms--;
                    120:                if (m == 0)
                    121:                        m = ALL & ~um;
                    122:                return m;
                    123:        }
                    124: }
                    125: 
                    126: what()
                    127: {
                    128:        switch (*ms) {
                    129:        case '+':
                    130:        case '-':
                    131:        case '=':
                    132:                return *ms++;
                    133:        }
                    134:        return(0);
                    135: }
                    136: 
                    137: where(om)
                    138: register om;
                    139: {
                    140:        register m;
                    141: 
                    142:        m = 0;
                    143:        switch (*ms) {
                    144:        case 'u':
                    145:                m = (om & USER) >> 6;
                    146:                goto dup;
                    147:        case 'g':
                    148:                m = (om & GROUP) >> 3;
                    149:                goto dup;
                    150:        case 'o':
                    151:                m = (om & OTHER);
                    152:        dup:
                    153:                m &= (READ|WRITE|EXEC);
                    154:                m |= (m << 3) | (m << 6);
                    155:                ++ms;
                    156:                return m;
                    157:        }
                    158:        for (;;) switch (*ms++) {
                    159:        case 'r':
                    160:                m |= READ;
                    161:                continue;
                    162:        case 'w':
                    163:                m |= WRITE;
                    164:                continue;
                    165:        case 'x':
                    166:                m |= EXEC;
                    167:                continue;
                    168:        case 's':
                    169:                m |= SETID;
                    170:                continue;
                    171:        case 't':
                    172:                m |= STICKY;
                    173:                continue;
                    174:        default:
                    175:                ms--;
                    176:                return m;
                    177:        }
                    178: }

unix.superglobalmegacorp.com

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