|
|
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: 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: if (cc || (b&SETID) && (nm&CONC)) ! 69: nm &= ~S_ICCTYP; ! 70: switch (o) { ! 71: case '+': ! 72: nm |= (b & m) | cc; ! 73: break; ! 74: case '-': ! 75: nm &= ~(b & m); ! 76: break; ! 77: case '=': ! 78: nm &= ~m; ! 79: nm |= (b & m) | cc; ! 80: break; ! 81: } ! 82: } ! 83: } while (*ms++ == ','); ! 84: if (*--ms) { ! 85: fprintf(stderr, "chmod: invalid mode\n"); ! 86: exit(255); ! 87: } ! 88: return(nm); ! 89: } ! 90: ! 91: abs() ! 92: { ! 93: register c, i; ! 94: ! 95: i = 0; ! 96: while ((c = *ms++) >= '0' && c <= '7') ! 97: i = (i << 3) + (c - '0'); ! 98: ms--; ! 99: return(i); ! 100: } ! 101: ! 102: who() ! 103: { ! 104: register m; ! 105: ! 106: m = 0; ! 107: for (;;) switch (*ms++) { ! 108: case 'u': ! 109: m |= USER; ! 110: continue; ! 111: case 'g': ! 112: m |= GROUP; ! 113: continue; ! 114: case 'o': ! 115: m |= OTHER; ! 116: continue; ! 117: case 'a': ! 118: m |= ALL; ! 119: continue; ! 120: default: ! 121: ms--; ! 122: if (m == 0) ! 123: m = ALL; ! 124: return m; ! 125: } ! 126: } ! 127: ! 128: what() ! 129: { ! 130: switch (*ms) { ! 131: case '+': ! 132: case '-': ! 133: case '=': ! 134: return *ms++; ! 135: } ! 136: return(0); ! 137: } ! 138: ! 139: where(om) ! 140: register om; ! 141: { ! 142: register m; ! 143: ! 144: m = 0; ! 145: switch (*ms) { ! 146: case 'u': ! 147: m = (om & USER) >> 6; ! 148: goto dup; ! 149: case 'g': ! 150: m = (om & GROUP) >> 3; ! 151: goto dup; ! 152: case 'o': ! 153: m = (om & OTHER); ! 154: dup: ! 155: m &= (READ|WRITE|EXEC); ! 156: m |= (m << 3) | (m << 6); ! 157: ++ms; ! 158: return m; ! 159: } ! 160: for (;;) switch (*ms++) { ! 161: case 'y': ! 162: cc = S_ISYNC; ! 163: continue; ! 164: case 'e': ! 165: cc = S_IEXCL; ! 166: continue; ! 167: case 'r': ! 168: m |= READ; ! 169: continue; ! 170: case 'w': ! 171: m |= WRITE; ! 172: continue; ! 173: case 'x': ! 174: m |= EXEC; ! 175: continue; ! 176: case 's': ! 177: m |= SETID; ! 178: continue; ! 179: default: ! 180: ms--; ! 181: return m; ! 182: } ! 183: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.