|
|
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 04700 /* 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: ! 20: #define CONC 01000 /* concurrency control */ ! 21: ! 22: char *ms; ! 23: struct stat st; ! 24: int cc; /* type of concurrency control requested */ ! 25: ! 26: main(argc,argv) ! 27: char **argv; ! 28: { ! 29: register i; ! 30: register char *p; ! 31: int status = 0; ! 32: ! 33: if (argc < 3) { ! 34: fprintf(stderr, "Usage: chmod [ugoa][+-=][rwxstugo] file ...\n"); ! 35: exit(255); ! 36: } ! 37: ms = argv[1]; ! 38: newmode(0); ! 39: for (i = 2; i < argc; i++) { ! 40: p = argv[i]; ! 41: if (stat(p, &st) < 0) { ! 42: fprintf(stderr, "chmod: "); ! 43: perror(p); ! 44: ++status; ! 45: continue; ! 46: } ! 47: ms = argv[1]; ! 48: if (chmod(p, newmode(st.st_mode)) < 0) { ! 49: fprintf(stderr, "chmod: "); ! 50: perror(p); ! 51: ++status; ! 52: continue; ! 53: } ! 54: } ! 55: exit(status); ! 56: } ! 57: ! 58: newmode(nm) ! 59: unsigned nm; ! 60: { ! 61: register o, m, b; ! 62: ! 63: m = abs(); ! 64: if (!*ms) ! 65: return(m); ! 66: do { ! 67: m = who(); ! 68: while (o = what()) { ! 69: b = where(nm); ! 70: if (cc || (b&SETID) && (nm&CONC)) ! 71: nm &= ~S_ICCTYP; ! 72: switch (o) { ! 73: case '+': ! 74: nm |= (b & m) | cc; ! 75: break; ! 76: case '-': ! 77: nm &= ~(b & m); ! 78: break; ! 79: case '=': ! 80: nm &= ~m; ! 81: nm |= (b & m) | cc; ! 82: break; ! 83: } ! 84: } ! 85: } while (*ms++ == ','); ! 86: if (*--ms) { ! 87: fprintf(stderr, "chmod: invalid mode\n"); ! 88: exit(255); ! 89: } ! 90: return(nm); ! 91: } ! 92: ! 93: abs() ! 94: { ! 95: register c, i; ! 96: ! 97: i = 0; ! 98: while ((c = *ms++) >= '0' && c <= '7') ! 99: i = (i << 3) + (c - '0'); ! 100: ms--; ! 101: return(i); ! 102: } ! 103: ! 104: who() ! 105: { ! 106: register m; ! 107: ! 108: m = 0; ! 109: for (;;) switch (*ms++) { ! 110: case 'u': ! 111: m |= USER; ! 112: continue; ! 113: case 'g': ! 114: m |= GROUP; ! 115: continue; ! 116: case 'o': ! 117: m |= OTHER; ! 118: continue; ! 119: case 'a': ! 120: m |= ALL; ! 121: continue; ! 122: default: ! 123: ms--; ! 124: if (m == 0) ! 125: m = ALL; ! 126: return m; ! 127: } ! 128: } ! 129: ! 130: what() ! 131: { ! 132: switch (*ms) { ! 133: case '+': ! 134: case '-': ! 135: case '=': ! 136: return *ms++; ! 137: } ! 138: return(0); ! 139: } ! 140: ! 141: where(om) ! 142: register om; ! 143: { ! 144: register m; ! 145: ! 146: m = 0; ! 147: switch (*ms) { ! 148: case 'u': ! 149: m = (om & USER) >> 6; ! 150: goto dup; ! 151: case 'g': ! 152: m = (om & GROUP) >> 3; ! 153: goto dup; ! 154: case 'o': ! 155: m = (om & OTHER); ! 156: dup: ! 157: m &= (READ|WRITE|EXEC); ! 158: m |= (m << 3) | (m << 6); ! 159: ++ms; ! 160: return m; ! 161: } ! 162: for (;;) switch (*ms++) { ! 163: case 'y': ! 164: cc = S_ISYNC; ! 165: continue; ! 166: case 'e': ! 167: cc = S_IEXCL; ! 168: continue; ! 169: case 'r': ! 170: m |= READ; ! 171: continue; ! 172: case 'w': ! 173: m |= WRITE; ! 174: continue; ! 175: case 'x': ! 176: m |= EXEC; ! 177: continue; ! 178: case 's': ! 179: m |= SETID; ! 180: continue; ! 181: default: ! 182: ms--; ! 183: return m; ! 184: } ! 185: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.