aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEric Andersen <andersen@codepoet.org>1999-10-20 07:03:36 +0000
committerEric Andersen <andersen@codepoet.org>1999-10-20 07:03:36 +0000
commitce8f3b99339fb954204329971ed25efc950fed26 (patch)
tree1f7509e6b8604061a688adb4d8299c3a4b79bdc9
parentb9b421c186cf6a9e575770a1c5fb46b6bdd3424a (diff)
downloadbusybox-w32-ce8f3b99339fb954204329971ed25efc950fed26.tar.gz
busybox-w32-ce8f3b99339fb954204329971ed25efc950fed26.tar.bz2
busybox-w32-ce8f3b99339fb954204329971ed25efc950fed26.zip
Fixed chmod and friends.
-rw-r--r--Makefile6
-rw-r--r--chmod_chown_chgrp.c265
-rw-r--r--utility.c46
3 files changed, 109 insertions, 208 deletions
diff --git a/Makefile b/Makefile
index 3ee292a82..5f8970669 100644
--- a/Makefile
+++ b/Makefile
@@ -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 8DODEBUG=true
9 9
10#This will choke on a non-debian system 10#This will choke on a non-debian system
11ARCH=`uname -m | sed -e 's/i.86/i386/' | sed -e 's/sparc.*/sparc/'` 11ARCH=`uname -m | sed -e 's/i.86/i386/' | sed -e 's/sparc.*/sparc/'`
@@ -19,7 +19,7 @@ ifeq ($(DODEBUG),true)
19else 19else
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)
23endif 23endif
24 24
25ifndef $(prefix) 25ifndef $(prefix)
@@ -36,7 +36,7 @@ all: busybox links
36 36
37busybox: $(OBJECTS) 37busybox: $(OBJECTS)
38 $(CC) $(LDFLAGS) -o $(PROG) $(OBJECTS) $(LIBRARIES) 38 $(CC) $(LDFLAGS) -o $(PROG) $(OBJECTS) $(LIBRARIES)
39 $(STRIP) $(PROG) 39 $(STRIP)
40 40
41links: 41links:
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
28static int uid=-1; 28static uid_t uid=-1;
29static int gid=0; 29static gid_t gid=-1;
30static int whichApp; 30static int whichApp;
31static char* invocationName=NULL; 31static char* invocationName=NULL;
32static mode_t mode=0644; 32static 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
51uid_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
89uid_t
90my_getpwnam(char *name)
91{
92 return my_getid("/etc/passwd", name);
93}
94
95gid_t
96my_getgrnam(char *name)
97{
98 return my_getid("/etc/group", name);
99}
51 100
52static int fileAction(const char *fileName, struct stat* statbuf) 101static 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
68int chmod_chown_chgrp_main(int argc, char **argv) 120int 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 198bad_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
180int 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
223int
224my_getpwuid(uid_t *uid)
225{
226 return my_getid("/etc/passwd", NULL, uid);
227}
228
229int
230my_getpwnam(char *name, uid_t *uid)
231{
232 return my_getid("/etc/passwd", name, uid);
233}
234
235int
236my_getgrgid(gid_t *gid)
237{
238 return my_getid("/etc/group", NULL, gid);
239}
240
241int
242my_getgrnam(char *name, gid_t *gid)
243{
244 return my_getid("/etc/group", name, gid);
245}
246
247const 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
252int
253parse_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
288extern int
289chown_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
diff --git a/utility.c b/utility.c
index 826cfbfee..fa9849160 100644
--- a/utility.c
+++ b/utility.c
@@ -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 */
38volatile void usage(const char *usage) 38volatile 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] */
562extern int parse_mode( const char* s, mode_t* theMode) 562
563
564
565extern int
566parse_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