diff options
author | Eric Andersen <andersen@codepoet.org> | 1999-10-20 07:03:36 +0000 |
---|---|---|
committer | Eric Andersen <andersen@codepoet.org> | 1999-10-20 07:03:36 +0000 |
commit | ce8f3b99339fb954204329971ed25efc950fed26 (patch) | |
tree | 1f7509e6b8604061a688adb4d8299c3a4b79bdc9 | |
parent | b9b421c186cf6a9e575770a1c5fb46b6bdd3424a (diff) | |
download | busybox-w32-ce8f3b99339fb954204329971ed25efc950fed26.tar.gz busybox-w32-ce8f3b99339fb954204329971ed25efc950fed26.tar.bz2 busybox-w32-ce8f3b99339fb954204329971ed25efc950fed26.zip |
Fixed chmod and friends.
-rw-r--r-- | Makefile | 6 | ||||
-rw-r--r-- | chmod_chown_chgrp.c | 265 | ||||
-rw-r--r-- | utility.c | 46 |
3 files changed, 109 insertions, 208 deletions
@@ -5,7 +5,7 @@ BUILDTIME=$(shell date "+%Y%m%d-%H%M") | |||
5 | 5 | ||
6 | # Comment out the following to make a debuggable build | 6 | # Comment out the following to make a debuggable build |
7 | # Leave this off for production use. | 7 | # Leave this off for production use. |
8 | #DODEBUG=true | 8 | DODEBUG=true |
9 | 9 | ||
10 | #This will choke on a non-debian system | 10 | #This will choke on a non-debian system |
11 | ARCH=`uname -m | sed -e 's/i.86/i386/' | sed -e 's/sparc.*/sparc/'` | 11 | ARCH=`uname -m | sed -e 's/i.86/i386/' | sed -e 's/sparc.*/sparc/'` |
@@ -19,7 +19,7 @@ ifeq ($(DODEBUG),true) | |||
19 | else | 19 | else |
20 | CFLAGS=-Wall -Os -fomit-frame-pointer -fno-builtin -D_GNU_SOURCE | 20 | CFLAGS=-Wall -Os -fomit-frame-pointer -fno-builtin -D_GNU_SOURCE |
21 | LDFLAGS= -s | 21 | LDFLAGS= -s |
22 | STRIP= strip --remove-section=.note --remove-section=.comment | 22 | STRIP= strip --remove-section=.note --remove-section=.comment $(PROG) |
23 | endif | 23 | endif |
24 | 24 | ||
25 | ifndef $(prefix) | 25 | ifndef $(prefix) |
@@ -36,7 +36,7 @@ all: busybox links | |||
36 | 36 | ||
37 | busybox: $(OBJECTS) | 37 | busybox: $(OBJECTS) |
38 | $(CC) $(LDFLAGS) -o $(PROG) $(OBJECTS) $(LIBRARIES) | 38 | $(CC) $(LDFLAGS) -o $(PROG) $(OBJECTS) $(LIBRARIES) |
39 | $(STRIP) $(PROG) | 39 | $(STRIP) |
40 | 40 | ||
41 | links: | 41 | links: |
42 | - ./busybox.mkll | sort >busybox.links | 42 | - ./busybox.mkll | sort >busybox.links |
diff --git a/chmod_chown_chgrp.c b/chmod_chown_chgrp.c index e76050022..faebbbe10 100644 --- a/chmod_chown_chgrp.c +++ b/chmod_chown_chgrp.c | |||
@@ -25,8 +25,8 @@ | |||
25 | #include "internal.h" | 25 | #include "internal.h" |
26 | 26 | ||
27 | 27 | ||
28 | static int uid=-1; | 28 | static uid_t uid=-1; |
29 | static int gid=0; | 29 | static gid_t gid=-1; |
30 | static int whichApp; | 30 | static int whichApp; |
31 | static char* invocationName=NULL; | 31 | static char* invocationName=NULL; |
32 | static mode_t mode=0644; | 32 | static mode_t mode=0644; |
@@ -48,18 +48,70 @@ static const char chmod_usage[] = "[-R] MODE[,MODE]... FILE...\n" | |||
48 | "\t-R\tchange files and directories recursively.\n"; | 48 | "\t-R\tchange files and directories recursively.\n"; |
49 | 49 | ||
50 | 50 | ||
51 | uid_t my_getid(const char *filename, const char *name) | ||
52 | { | ||
53 | FILE *stream; | ||
54 | char *rname, *start, *end, buf[128]; | ||
55 | uid_t rid; | ||
56 | |||
57 | stream=fopen(filename,"r"); | ||
58 | |||
59 | while (fgets (buf, 128, stream) != NULL) { | ||
60 | if (buf[0] == '#') | ||
61 | continue; | ||
62 | |||
63 | start = buf; | ||
64 | end = strchr (start, ':'); | ||
65 | if (end == NULL) | ||
66 | continue; | ||
67 | *end = '\0'; | ||
68 | rname = start; | ||
69 | |||
70 | start = end + 1; | ||
71 | end = strchr (start, ':'); | ||
72 | if (end == NULL) | ||
73 | continue; | ||
74 | |||
75 | start = end + 1; | ||
76 | rid = (uid_t) strtol (start, &end, 10); | ||
77 | if (end == start) | ||
78 | continue; | ||
79 | |||
80 | if (name) { | ||
81 | if (0 == strcmp(rname, name)) | ||
82 | return( rid); | ||
83 | } | ||
84 | } | ||
85 | fclose(stream); | ||
86 | return (-1); | ||
87 | } | ||
88 | |||
89 | uid_t | ||
90 | my_getpwnam(char *name) | ||
91 | { | ||
92 | return my_getid("/etc/passwd", name); | ||
93 | } | ||
94 | |||
95 | gid_t | ||
96 | my_getgrnam(char *name) | ||
97 | { | ||
98 | return my_getid("/etc/group", name); | ||
99 | } | ||
51 | 100 | ||
52 | static int fileAction(const char *fileName, struct stat* statbuf) | 101 | static int fileAction(const char *fileName, struct stat* statbuf) |
53 | { | 102 | { |
54 | switch (whichApp) { | 103 | switch (whichApp) { |
55 | case CHGRP_APP: | 104 | case CHGRP_APP: |
56 | case CHOWN_APP: | 105 | case CHOWN_APP: |
57 | if (chown(fileName, ((whichApp==CHOWN_APP)? uid: statbuf->st_uid), gid) < 0) | 106 | if (chown(fileName, (whichApp==CHOWN_APP)? uid : statbuf->st_uid, |
107 | (gid==-1)? statbuf->st_gid : gid) == 0) { | ||
58 | return( TRUE); | 108 | return( TRUE); |
109 | } | ||
110 | break; | ||
59 | case CHMOD_APP: | 111 | case CHMOD_APP: |
60 | fprintf(stderr, "%s, %d\n", fileName, mode); | 112 | if (chmod(fileName, mode) == 0) |
61 | if (chmod(fileName, mode)) | ||
62 | return( TRUE); | 113 | return( TRUE); |
114 | break; | ||
63 | } | 115 | } |
64 | perror(fileName); | 116 | perror(fileName); |
65 | return( FALSE); | 117 | return( FALSE); |
@@ -67,8 +119,6 @@ static int fileAction(const char *fileName, struct stat* statbuf) | |||
67 | 119 | ||
68 | int chmod_chown_chgrp_main(int argc, char **argv) | 120 | int chmod_chown_chgrp_main(int argc, char **argv) |
69 | { | 121 | { |
70 | struct group *grp; | ||
71 | struct passwd *pwd; | ||
72 | int recursiveFlag=FALSE; | 122 | int recursiveFlag=FALSE; |
73 | char *groupName; | 123 | char *groupName; |
74 | 124 | ||
@@ -104,31 +154,33 @@ int chmod_chown_chgrp_main(int argc, char **argv) | |||
104 | fprintf(stderr, "%s: Unknown mode: %s\n", invocationName, *argv); | 154 | fprintf(stderr, "%s: Unknown mode: %s\n", invocationName, *argv); |
105 | exit( FALSE); | 155 | exit( FALSE); |
106 | } | 156 | } |
107 | //mode &= andWithMode; | ||
108 | fprintf(stderr, "mode %d\n", mode); | ||
109 | } else { | 157 | } else { |
110 | 158 | ||
111 | /* Find the selected group */ | 159 | /* Find the selected group */ |
112 | groupName = strchr(*argv, '.'); | 160 | if ( whichApp==CHGRP_APP && groupName ) { |
113 | if ( whichApp==TRUE && groupName ) | ||
114 | *groupName++ = '\0'; | ||
115 | else | ||
116 | groupName = *argv; | 161 | groupName = *argv; |
117 | grp = getgrnam(groupName); | 162 | gid = my_getgrnam(groupName); |
118 | if (grp == NULL) { | 163 | if (gid == -1) |
119 | fprintf(stderr, "%s: Unknown group name: %s\n", invocationName, groupName); | 164 | goto bad_group; |
120 | exit( FALSE); | 165 | } else { |
166 | groupName = strchr(*argv, '.'); | ||
167 | if (groupName) { | ||
168 | *groupName++ = '\0'; | ||
169 | gid = my_getgrnam(groupName); | ||
170 | if (gid == -1) | ||
171 | goto bad_group; | ||
172 | } else | ||
173 | gid = -1; | ||
121 | } | 174 | } |
122 | gid = grp->gr_gid; | 175 | |
123 | 176 | ||
124 | /* Find the selected user (if appropriate) */ | 177 | /* Find the selected user (if appropriate) */ |
125 | if (whichApp==TRUE) { | 178 | if (whichApp==CHOWN_APP) { |
126 | pwd = getpwnam(*argv); | 179 | uid = my_getpwnam(*argv); |
127 | if (pwd == NULL) { | 180 | if (uid == -1) { |
128 | fprintf(stderr, "%s: Unknown user name: %s\n", invocationName, *argv); | 181 | fprintf(stderr, "%s: Unknown user name: %s\n", invocationName, *argv); |
129 | exit( FALSE); | 182 | exit( FALSE); |
130 | } | 183 | } |
131 | uid = pwd->pw_uid; | ||
132 | } | 184 | } |
133 | } | 185 | } |
134 | 186 | ||
@@ -142,173 +194,10 @@ int chmod_chown_chgrp_main(int argc, char **argv) | |||
142 | exit( FALSE); | 194 | exit( FALSE); |
143 | } | 195 | } |
144 | exit(TRUE); | 196 | exit(TRUE); |
145 | } | ||
146 | |||
147 | |||
148 | |||
149 | |||
150 | |||
151 | |||
152 | |||
153 | |||
154 | |||
155 | |||
156 | |||
157 | 197 | ||
158 | #ifdef fooo | 198 | bad_group: |
159 | 199 | fprintf(stderr, "%s: Unknown group name: %s\n", invocationName, groupName); | |
160 | 200 | exit( FALSE); | |
161 | |||
162 | |||
163 | |||
164 | |||
165 | |||
166 | |||
167 | |||
168 | |||
169 | |||
170 | |||
171 | |||
172 | |||
173 | |||
174 | #include "internal.h" | ||
175 | #include <pwd.h> | ||
176 | #include <grp.h> | ||
177 | #include <string.h> | ||
178 | #include <stdio.h> | ||
179 | |||
180 | int my_getid(const char *filename, const char *name, uid_t *id) | ||
181 | { | ||
182 | FILE *stream; | ||
183 | uid_t rid; | ||
184 | char *rname, *start, *end, buf[128]; | ||
185 | |||
186 | stream=fopen(filename,"r"); | ||
187 | |||
188 | while (fgets (buf, 128, stream) != NULL) { | ||
189 | if (buf[0] == '#') | ||
190 | continue; | ||
191 | |||
192 | start = buf; | ||
193 | end = strchr (start, ':'); | ||
194 | if (end == NULL) | ||
195 | continue; | ||
196 | *end = '\0'; | ||
197 | rname = start; | ||
198 | |||
199 | start = end + 1; | ||
200 | end = strchr (start, ':'); | ||
201 | if (end == NULL) | ||
202 | continue; | ||
203 | |||
204 | start = end + 1; | ||
205 | rid = (uid_t) strtol (start, &end, 10); | ||
206 | if (end == start) | ||
207 | continue; | ||
208 | |||
209 | if (name) { | ||
210 | if (0 == strcmp(rname, name)) { | ||
211 | *id=rid; | ||
212 | return 0; | ||
213 | } | ||
214 | } else { | ||
215 | if ( *id == rid ) | ||
216 | return 0; | ||
217 | } | ||
218 | } | ||
219 | fclose(stream); | ||
220 | return -1; | ||
221 | } | 201 | } |
222 | 202 | ||
223 | int | ||
224 | my_getpwuid(uid_t *uid) | ||
225 | { | ||
226 | return my_getid("/etc/passwd", NULL, uid); | ||
227 | } | ||
228 | |||
229 | int | ||
230 | my_getpwnam(char *name, uid_t *uid) | ||
231 | { | ||
232 | return my_getid("/etc/passwd", name, uid); | ||
233 | } | ||
234 | |||
235 | int | ||
236 | my_getgrgid(gid_t *gid) | ||
237 | { | ||
238 | return my_getid("/etc/group", NULL, gid); | ||
239 | } | ||
240 | |||
241 | int | ||
242 | my_getgrnam(char *name, gid_t *gid) | ||
243 | { | ||
244 | return my_getid("/etc/group", name, gid); | ||
245 | } | ||
246 | |||
247 | const char chown_usage[] = "chown [-R] user-name file [file ...]\n" | ||
248 | "\n\tThe group list is kept in the file /etc/groups.\n\n" | ||
249 | "\t-R:\tRecursively change the mode of all files and directories\n" | ||
250 | "\t\tunder the argument directory."; | ||
251 | |||
252 | int | ||
253 | parse_user_name(const char * s, struct FileInfo * i) | ||
254 | { | ||
255 | char * dot = strchr(s, '.'); | ||
256 | char * end = NULL; | ||
257 | uid_t id = 0; | ||
258 | |||
259 | if (! dot ) | ||
260 | dot = strchr(s, ':'); | ||
261 | |||
262 | if ( dot ) | ||
263 | *dot = '\0'; | ||
264 | |||
265 | if ( my_getpwnam(s,&id) == -1 ) { | ||
266 | id = strtol(s,&end,10); | ||
267 | if ((*end != '\0') || ( my_getpwuid(&id) == -1 )) { | ||
268 | fprintf(stderr, "%s: no such user.\n", s); | ||
269 | return 1; | ||
270 | } | ||
271 | } | ||
272 | i->userID = id; | ||
273 | |||
274 | if ( dot ) { | ||
275 | if ( my_getgrnam(++dot,&id) == -1 ) { | ||
276 | id = strtol(dot,&end,10); | ||
277 | if ((*end != '\0') || ( my_getgrgid(&id) == -1 )) { | ||
278 | fprintf(stderr, "%s: no such group.\n", dot); | ||
279 | return 1; | ||
280 | } | ||
281 | } | ||
282 | i->groupID = id; | ||
283 | i->changeGroupID = 1; | ||
284 | } | ||
285 | return 0; | ||
286 | } | ||
287 | |||
288 | extern int | ||
289 | chown_main(struct FileInfo * i, int argc, char * * argv) | ||
290 | { | ||
291 | int status; | ||
292 | |||
293 | while ( argc >= 3 && strcmp("-R", argv[1]) == 0 ) { | ||
294 | i->recursive = 1; | ||
295 | argc--; | ||
296 | argv++; | ||
297 | } | ||
298 | |||
299 | if ( (status = parse_user_name(argv[1], i)) != 0 ) | ||
300 | return status; | ||
301 | |||
302 | argv++; | ||
303 | argc--; | ||
304 | |||
305 | i->changeUserID = 1; | ||
306 | i->complainInPostProcess = 1; | ||
307 | |||
308 | return monadic_main(i, argc, argv); | ||
309 | } | ||
310 | |||
311 | |||
312 | |||
313 | 203 | ||
314 | #endif | ||
@@ -32,7 +32,7 @@ | |||
32 | #include <utime.h> | 32 | #include <utime.h> |
33 | #include <sys/stat.h> | 33 | #include <sys/stat.h> |
34 | #include <unistd.h> | 34 | #include <unistd.h> |
35 | 35 | #include <ctype.h> | |
36 | 36 | ||
37 | /* volatile so gcc knows this is the enod of the line */ | 37 | /* volatile so gcc knows this is the enod of the line */ |
38 | volatile void usage(const char *usage) | 38 | volatile void usage(const char *usage) |
@@ -558,13 +558,17 @@ extern void createPath (const char *name, int mode) | |||
558 | 558 | ||
559 | 559 | ||
560 | #if defined (BB_CHMOD_CHOWN_CHGRP) || defined (BB_MKDIR) | 560 | #if defined (BB_CHMOD_CHOWN_CHGRP) || defined (BB_MKDIR) |
561 | /* [ugoa]{+|-|=}[rwxstl] */ | 561 | /* [ugoa]{+|-|=}[rwxst] */ |
562 | extern int parse_mode( const char* s, mode_t* theMode) | 562 | |
563 | |||
564 | |||
565 | extern int | ||
566 | parse_mode( const char* s, mode_t* theMode) | ||
563 | { | 567 | { |
564 | mode_t or; | 568 | mode_t andMode = S_ISVTX|S_ISUID|S_ISGID|S_IRWXU|S_IRWXG|S_IRWXO; |
565 | mode_t and; | 569 | mode_t orMode = 0; |
566 | mode_t mode = 0; | 570 | mode_t mode = 0; |
567 | mode_t groups = S_ISVTX; | 571 | mode_t groups = 0; |
568 | char type; | 572 | char type; |
569 | char c; | 573 | char c; |
570 | 574 | ||
@@ -572,7 +576,7 @@ extern int parse_mode( const char* s, mode_t* theMode) | |||
572 | for ( ; ; ) { | 576 | for ( ; ; ) { |
573 | switch ( c = *s++ ) { | 577 | switch ( c = *s++ ) { |
574 | case '\0': | 578 | case '\0': |
575 | return (FALSE); | 579 | return -1; |
576 | case 'u': | 580 | case 'u': |
577 | groups |= S_ISUID|S_IRWXU; | 581 | groups |= S_ISUID|S_IRWXU; |
578 | continue; | 582 | continue; |
@@ -589,13 +593,15 @@ extern int parse_mode( const char* s, mode_t* theMode) | |||
589 | case '=': | 593 | case '=': |
590 | case '-': | 594 | case '-': |
591 | type = c; | 595 | type = c; |
592 | if ( groups == S_ISVTX ) /* The default is "all" */ | 596 | if ( groups == 0 ) /* The default is "all" */ |
593 | groups |= S_ISUID|S_ISGID|S_IRWXU|S_IRWXG|S_IRWXO; | 597 | groups |= S_ISUID|S_ISGID|S_IRWXU|S_IRWXG|S_IRWXO; |
594 | break; | 598 | break; |
595 | default: | 599 | default: |
596 | if ( c >= '0' && c <= '7' && mode == 0 && groups == S_ISVTX ) { | 600 | if ( isdigit(c) && c >= '0' && c <= '7' && mode == 0 && groups == 0 ) { |
597 | and = 0; | 601 | andMode = 0; |
598 | or = strtol(--s, 0, 010); | 602 | orMode = strtol(--s, NULL, 8); |
603 | *theMode &= andMode; | ||
604 | *theMode |= orMode; | ||
599 | return (TRUE); | 605 | return (TRUE); |
600 | } | 606 | } |
601 | else | 607 | else |
@@ -621,28 +627,34 @@ extern int parse_mode( const char* s, mode_t* theMode) | |||
621 | mode |= S_IXGRP|S_ISUID|S_ISGID; | 627 | mode |= S_IXGRP|S_ISUID|S_ISGID; |
622 | continue; | 628 | continue; |
623 | case 't': | 629 | case 't': |
624 | mode |= S_ISVTX; | 630 | mode |= 0; |
625 | continue; | 631 | continue; |
626 | default: | 632 | default: |
627 | return (FALSE); | 633 | *theMode &= andMode; |
634 | *theMode |= orMode; | ||
635 | return( TRUE); | ||
628 | } | 636 | } |
629 | break; | 637 | break; |
630 | } | 638 | } |
631 | switch ( type ) { | 639 | switch ( type ) { |
632 | case '=': | 640 | case '=': |
633 | and &= ~(groups); | 641 | andMode &= ~(groups); |
634 | /* fall through */ | 642 | /* fall through */ |
635 | case '+': | 643 | case '+': |
636 | or |= mode & groups; | 644 | orMode |= mode & groups; |
637 | break; | 645 | break; |
638 | case '-': | 646 | case '-': |
639 | and &= ~(mode & groups); | 647 | andMode &= ~(mode & groups); |
640 | or &= and; | 648 | orMode &= andMode; |
641 | break; | 649 | break; |
642 | } | 650 | } |
643 | } while ( c == ',' ); | 651 | } while ( c == ',' ); |
652 | *theMode &= andMode; | ||
653 | *theMode |= orMode; | ||
644 | return (TRUE); | 654 | return (TRUE); |
645 | } | 655 | } |
656 | |||
657 | |||
646 | #endif | 658 | #endif |
647 | 659 | ||
648 | 660 | ||