|
|
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.