|
|
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 05700 /* 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: #define STICKY 01000 /* sticky bit */ ! 20: ! 21: char *ms; ! 22: int um; ! 23: struct stat st; ! 24: ! 25: main(argc,argv) ! 26: char **argv; ! 27: { ! 28: register i; ! 29: register char *p; ! 30: int status = 0; ! 31: ! 32: if (argc < 3) { ! 33: fprintf(stderr, "Usage: chmod [ugoa][+-=][rwxstugo] file ...\n"); ! 34: exit(255); ! 35: } ! 36: ms = argv[1]; ! 37: um = umask(0); ! 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: switch (o) { ! 69: case '+': ! 70: nm |= b & m; ! 71: break; ! 72: case '-': ! 73: nm &= ~(b & m); ! 74: break; ! 75: case '=': ! 76: nm &= ~m; ! 77: nm |= b & m; ! 78: break; ! 79: } ! 80: } ! 81: } while (*ms++ == ','); ! 82: if (*--ms) { ! 83: fprintf(stderr, "chmod: invalid mode\n"); ! 84: exit(255); ! 85: } ! 86: return(nm); ! 87: } ! 88: ! 89: abs() ! 90: { ! 91: register c, i; ! 92: ! 93: i = 0; ! 94: while ((c = *ms++) >= '0' && c <= '7') ! 95: i = (i << 3) + (c - '0'); ! 96: ms--; ! 97: return(i); ! 98: } ! 99: ! 100: who() ! 101: { ! 102: register m; ! 103: ! 104: m = 0; ! 105: for (;;) switch (*ms++) { ! 106: case 'u': ! 107: m |= USER; ! 108: continue; ! 109: case 'g': ! 110: m |= GROUP; ! 111: continue; ! 112: case 'o': ! 113: m |= OTHER; ! 114: continue; ! 115: case 'a': ! 116: m |= ALL; ! 117: continue; ! 118: default: ! 119: ms--; ! 120: if (m == 0) ! 121: m = ALL & ~um; ! 122: return m; ! 123: } ! 124: } ! 125: ! 126: what() ! 127: { ! 128: switch (*ms) { ! 129: case '+': ! 130: case '-': ! 131: case '=': ! 132: return *ms++; ! 133: } ! 134: return(0); ! 135: } ! 136: ! 137: where(om) ! 138: register om; ! 139: { ! 140: register m; ! 141: ! 142: m = 0; ! 143: switch (*ms) { ! 144: case 'u': ! 145: m = (om & USER) >> 6; ! 146: goto dup; ! 147: case 'g': ! 148: m = (om & GROUP) >> 3; ! 149: goto dup; ! 150: case 'o': ! 151: m = (om & OTHER); ! 152: dup: ! 153: m &= (READ|WRITE|EXEC); ! 154: m |= (m << 3) | (m << 6); ! 155: ++ms; ! 156: return m; ! 157: } ! 158: for (;;) switch (*ms++) { ! 159: case 'r': ! 160: m |= READ; ! 161: continue; ! 162: case 'w': ! 163: m |= WRITE; ! 164: continue; ! 165: case 'x': ! 166: m |= EXEC; ! 167: continue; ! 168: case 's': ! 169: m |= SETID; ! 170: continue; ! 171: case 't': ! 172: m |= STICKY; ! 173: continue; ! 174: default: ! 175: ms--; ! 176: return m; ! 177: } ! 178: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.