Annotation of coherent/d/bin/chmod.c, revision 1.1.1.1

1.1       root        1: /*
                      2:  * Chmod -- change the mode of
                      3:  * files (both symbolic and octal)
                      4:  * I really don't like the syntax though.
                      5:  */
                      6: 
                      7: #include <stdio.h>
                      8: #include <sys/stat.h>
                      9: 
                     10: /* Masks by types of permissions */
                     11: #define        AEXEC   (S_IEXEC|(S_IEXEC>>3)|(S_IEXEC>>6))
                     12: #define        AREAD   (S_IREAD|(S_IREAD>>3)|(S_IREAD>>6))
                     13: #define        AWRITE  (S_IWRITE|(S_IWRITE>>3)|(S_IWRITE>>6))
                     14: #define        ASUID   (S_ISUID|S_ISGID)
                     15: #define        ATEXT   S_ISVTX
                     16: 
                     17: /* Masks by types of users */
                     18: #define        AOWN    (S_ISUID|S_ISVTX|S_IREAD|S_IWRITE|S_IEXEC)
                     19: #define        AGRP    (S_ISGID|S_ISVTX|(S_IREAD>>3)|(S_IWRITE>>3)|(S_IEXEC>>3))
                     20: #define        AOTH    (S_ISVTX|(S_IREAD>>6)|(S_IWRITE>>6)|(S_IEXEC>>6))
                     21: #define        AALL    (AOWN|AGRP|AOTH)
                     22: 
                     23: short  int     uid;
                     24: 
                     25: char   stickwarn[] = "\
                     26: chmod: Warning: non-super user may not set sticky bit\n\
                     27: ";
                     28: 
                     29: main(argc, argv)
                     30: char *argv[];
                     31: {
                     32:        register int i;
                     33:        register char *fn;
                     34:        int status = 0;
                     35: 
                     36:        if (argc < 3)
                     37:                usage();
                     38:        uid = getuid();
                     39:        for (i=2; i<argc; i++) {
                     40:                fn = argv[i];
                     41:                if (chmod(fn, readmode(argv[1], fn)) < 0) {
                     42:                        perror(fn);
                     43:                        status = 2;
                     44:                }
                     45:        }
                     46:        exit (status);
                     47: }
                     48: 
                     49: /*
                     50:  * Read in the symbolic mode and
                     51:  * set the variables `who', `op',
                     52:  * and `mode'.
                     53:  * Knows about the old octal modes as well.
                     54:  */
                     55: readmode(s, file)
                     56: register char *s;
                     57: char *file;
                     58: {
                     59:        register int c;
                     60:        register int mode;
                     61:        register int op;
                     62:        register int m1, m2;
                     63:        struct stat sb;
                     64: 
                     65:        mode = 0;
                     66:        if (*s>='0' && *s<='7') {
                     67:                while (*s != '\0') {
                     68:                        if (*s<'0' || *s>'7')
                     69:                                omusage();
                     70:                        mode = (mode<<3) | *s++-'0';
                     71:                }
                     72:                checkmode(mode);
                     73:                return (mode);
                     74:        }
                     75:        sb.st_mode = 0;
                     76:        stat(file, &sb);
                     77:        mode = sb.st_mode;
                     78: newsym:
                     79:        m1 = 0;
                     80:        for (;;) {
                     81:                switch (*s++) {
                     82:                case 'u':
                     83:                        m1 |= AOWN;
                     84:                        continue;
                     85: 
                     86:                case 'g':
                     87:                        m1 |= AGRP;
                     88:                        continue;
                     89: 
                     90:                case 'o':
                     91:                        m1 |= AOTH;
                     92:                        continue;
                     93: 
                     94:                case 'a':
                     95:                        m1 |= AALL;
                     96:                        continue;
                     97: 
                     98:                default:
                     99:                        s--;
                    100:                        break;
                    101:                }
                    102:                break;
                    103:        }
                    104:        if (m1 == 0) {
                    105:                m1 = AALL&~getumask();
                    106:        }
                    107: newop:
                    108:        if ((c = *s++)=='=' || c=='+' || c=='-')
                    109:                op = c;
                    110:        else
                    111:                smusage();
                    112:        m2 = 0;
                    113:        for (;;) {
                    114:                switch (*s++) {
                    115:                case 'r':
                    116:                        m2 |= AREAD;
                    117:                        continue;
                    118: 
                    119:                case 'w':
                    120:                        m2 |= AWRITE;
                    121:                        continue;
                    122: 
                    123:                case 'x':
                    124:                        m2 |= AEXEC;
                    125:                        continue;
                    126: 
                    127:                case 's':
                    128:                        m2 |= ASUID;
                    129:                        continue;
                    130: 
                    131:                case 't':
                    132:                        m2 |= ATEXT;
                    133:                        continue;
                    134: 
                    135:                case 'u':
                    136:                        m2 |= mrepl(mode&AOWN);
                    137:                        continue;
                    138: 
                    139:                case 'g':
                    140:                        m2 |= mrepl((mode&AGRP)<<3);
                    141:                        continue;
                    142: 
                    143:                case 'o':
                    144:                        m2 |= mrepl((mode&AOTH)<<6);
                    145:                        continue;
                    146: 
                    147:                default:
                    148:                        s--;
                    149:                        break;
                    150:                }
                    151:                break;
                    152:        }
                    153:        switch (op) {
                    154:        case '-':
                    155:                mode &= ~(m1&m2);
                    156:                break;
                    157: 
                    158:        case '+':
                    159:                mode |= m1&m2;
                    160:                break;
                    161: 
                    162:        case '=':
                    163:                mode = (mode&~m1) | (m1&m2);
                    164:                break;
                    165:        }
                    166:        if (*s == '\0') {
                    167:                checkmode(mode);
                    168:                return (mode);
                    169:        }
                    170:        if (*s=='+' || *s=='-' || *s=='=')
                    171:                goto newop;
                    172:        if (*s++ == ',')
                    173:                goto newsym;
                    174:        smusage();
                    175: }
                    176: 
                    177: /*
                    178:  * Get the value of the umask setting.
                    179:  */
                    180: getumask()
                    181: {
                    182:        register int omask;
                    183: 
                    184:        omask = umask(0);
                    185:        umask(omask);
                    186:        return (omask);
                    187: }
                    188: 
                    189: /*
                    190:  * Check the mode to see if any problem
                    191:  * bits are on.  For now, this is
                    192:  * S_ISVTX for non-super-users.
                    193:  */
                    194: checkmode(mode)
                    195: register int mode;
                    196: {
                    197:        static int beenhere;
                    198: 
                    199:        if (!beenhere && uid!=0 && mode&S_ISVTX) {
                    200:                fprintf(stderr, stickwarn);
                    201:                beenhere++;
                    202:        }
                    203: }
                    204: 
                    205: /*
                    206:  * Replicate the 3-bits of the mode from
                    207:  * the owner position to all positions.
                    208:  */
                    209: mrepl(m)
                    210: register int m;
                    211: {
                    212:        register int m1;
                    213: 
                    214:        m1 = m&AOWN;
                    215:        m = m1 | (m1>>3) | (m1>>6);
                    216:        if (m1 & S_ISUID)
                    217:                m |= S_ISGID;
                    218:        return (m);
                    219: }
                    220: 
                    221: usage()
                    222: {
                    223:        fprintf(stderr, "Usage: chmod mode file ...\n");
                    224:        exit(1);
                    225: }
                    226: 
                    227: smusage()
                    228: {
                    229:        fprintf(stderr, "chmod: badly formed symbolic mode\n");
                    230:        exit(1);
                    231: }
                    232: 
                    233: omusage()
                    234: {
                    235:        fprintf(stderr, "chmod: badly formed octal mode\n");
                    236:        exit(1);
                    237: }
                    238: 
                    239: 
                    240: 

unix.superglobalmegacorp.com

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