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