|
|
1.1 ! root 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: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.