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