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: }
Defined functions
abs
defined in line
88; used 1 times
main
defined in line
24;
never used
what
defined in line
125; used 1 times
who
defined in line
99; used 1 times
Defined variables
ms
defined in line
20; used 15 times
- in line 35,
45,
61,
80-81(2),
93-95(2),
104,
118,
127-131(2),
142,
154-157(2),
174
st
defined in line
22; used 2 times
um
defined in line
21; used 2 times
Defined macros
ALL
defined in line
12; used 2 times
EXEC
defined in line
16; used 2 times
GROUP
defined in line
10; used 2 times
OTHER
defined in line
11; used 2 times
READ
defined in line
14; used 2 times
SETID
defined in line
17; used 1 times
USER
defined in line
9; used 2 times
WRITE
defined in line
15; used 2 times