Research V7 development
[unix-history] / usr / src / cmd / chmod.c
CommitLineData
34ba1ef9
KT
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
20char *ms;
21int um;
22struct stat st;
23
24main(argc,argv)
25char **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
55newmode(nm)
56unsigned 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
88abs()
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
99who()
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
125what()
126{
127 switch (*ms) {
128 case '+':
129 case '-':
130 case '=':
131 return *ms++;
132 }
133 return(0);
134}
135
136where(om)
137register 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}