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

Defined functions

abs defined in line 88; used 1 times
  • in line 60
main defined in line 24; never used
newmode defined in line 55; used 2 times
what defined in line 125; used 1 times
  • in line 65
where defined in line 136; used 1 times
  • in line 66
who defined in line 99; used 1 times
  • in line 64

Defined variables

ms defined in line 20; used 15 times
st defined in line 22; used 2 times
um defined in line 21; used 2 times

Defined macros

ALL defined in line 12; used 2 times
EXEC defined in line 16; used 2 times
GROUP defined in line 10; used 2 times
OTHER defined in line 11; used 2 times
READ defined in line 14; used 2 times
SETID defined in line 17; used 1 times
STICKY defined in line 18; used 1 times
USER defined in line 9; used 2 times
WRITE defined in line 15; used 2 times
Last modified: 1981-07-10
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 830
Valid CSS Valid XHTML 1.0 Strict