Fixed chmod and friends.
No binary (build failed)
—
(log yok)
| @@ -5,7 +5,7 @@ BUILDTIME=$(shell date "+%Y%m%d-%H%M") | |
| # Comment out the following to make a debuggable build | |
| # Leave this off for production use. | |
| - | #DODEBUG=true |
| + | DODEBUG=true |
| #This will choke on a non-debian system | |
| ARCH=`uname -m | sed -e 's/i.86/i386/' | sed -e 's/sparc.*/sparc/'` | |
| @@ -19,7 +19,7 @@ ifeq ($(DODEBUG),true) | |
| else | |
| CFLAGS=-Wall -Os -fomit-frame-pointer -fno-builtin -D_GNU_SOURCE | |
| LDFLAGS= -s | |
| - | STRIP= strip --remove-section=.note --remove-section=.comment |
| + | STRIP= strip --remove-section=.note --remove-section=.comment $(PROG) |
| endif | |
| ifndef $(prefix) | |
| @@ -36,7 +36,7 @@ all: busybox links | |
| busybox: $(OBJECTS) | |
| $(CC) $(LDFLAGS) -o $(PROG) $(OBJECTS) $(LIBRARIES) | |
| - | $(STRIP) $(PROG) |
| + | $(STRIP) |
| links: | |
| - ./busybox.mkll | sort >busybox.links | |
| @@ -25,8 +25,8 @@ | |
| #include "internal.h" | |
| - | static int uid=-1; |
| - | static int gid=0; |
| + | static uid_t uid=-1; |
| + | static gid_t gid=-1; |
| static int whichApp; | |
| static char* invocationName=NULL; | |
| static mode_t mode=0644; | |
| @@ -48,18 +48,70 @@ static const char chmod_usage[] = "[-R] MODE[,MODE]... FILE...\n" | |
| "\t-R\tchange files and directories recursively.\n"; | |
| + | uid_t my_getid(const char *filename, const char *name) |
| + | { |
| + | FILE *stream; |
| + | char *rname, *start, *end, buf[128]; |
| + | uid_t rid; |
| + | |
| + | stream=fopen(filename,"r"); |
| + | |
| + | while (fgets (buf, 128, stream) != NULL) { |
| + | if (buf[0] == '#') |
| + | continue; |
| + | |
| + | start = buf; |
| + | end = strchr (start, ':'); |
| + | if (end == NULL) |
| + | continue; |
| + | *end = '\0'; |
| + | rname = start; |
| + | |
| + | start = end + 1; |
| + | end = strchr (start, ':'); |
| + | if (end == NULL) |
| + | continue; |
| + | |
| + | start = end + 1; |
| + | rid = (uid_t) strtol (start, &end, 10); |
| + | if (end == start) |
| + | continue; |
| + | |
| + | if (name) { |
| + | if (0 == strcmp(rname, name)) |
| + | return( rid); |
| + | } |
| + | } |
| + | fclose(stream); |
| + | return (-1); |
| + | } |
| + | |
| + | uid_t |
| + | my_getpwnam(char *name) |
| + | { |
| + | return my_getid("/etc/passwd", name); |
| + | } |
| + | |
| + | gid_t |
| + | my_getgrnam(char *name) |
| + | { |
| + | return my_getid("/etc/group", name); |
| + | } |
| static int fileAction(const char *fileName, struct stat* statbuf) | |
| { | |
| switch (whichApp) { | |
| case CHGRP_APP: | |
| case CHOWN_APP: | |
| - | if (chown(fileName, ((whichApp==CHOWN_APP)? uid: statbuf->st_uid), gid) < 0) |
| + | if (chown(fileName, (whichApp==CHOWN_APP)? uid : statbuf->st_uid, |
| + | (gid==-1)? statbuf->st_gid : gid) == 0) { |
| return( TRUE); | |
| + | } |
| + | break; |
| case CHMOD_APP: | |
| - | fprintf(stderr, "%s, %d\n", fileName, mode); |
| - | if (chmod(fileName, mode)) |
| + | if (chmod(fileName, mode) == 0) |
| return( TRUE); | |
| + | break; |
| } | |
| perror(fileName); | |
| return( FALSE); | |
| @@ -67,8 +119,6 @@ static int fileAction(const char *fileName, struct stat* statbuf) | |
| int chmod_chown_chgrp_main(int argc, char **argv) | |
| { | |
| - | struct group *grp; |
| - | struct passwd *pwd; |
| int recursiveFlag=FALSE; | |
| char *groupName; | |
| @@ -104,31 +154,33 @@ int chmod_chown_chgrp_main(int argc, char **argv) | |
| fprintf(stderr, "%s: Unknown mode: %s\n", invocationName, *argv); | |
| exit( FALSE); | |
| } | |
| - | //mode &= andWithMode; |
| - | fprintf(stderr, "mode %d\n", mode); |
| } else { | |
| /* Find the selected group */ | |
| - | groupName = strchr(*argv, '.'); |
| - | if ( whichApp==TRUE && groupName ) |
| - | *groupName++ = '\0'; |
| - | else |
| + | if ( whichApp==CHGRP_APP && groupName ) { |
| groupName = *argv; | |
| - | grp = getgrnam(groupName); |
| - | if (grp == NULL) { |
| - | fprintf(stderr, "%s: Unknown group name: %s\n", invocationName, groupName); |
| - | exit( FALSE); |
| + | gid = my_getgrnam(groupName); |
| + | if (gid == -1) |
| + | goto bad_group; |
| + | } else { |
| + | groupName = strchr(*argv, '.'); |
| + | if (groupName) { |
| + | *groupName++ = '\0'; |
| + | gid = my_getgrnam(groupName); |
| + | if (gid == -1) |
| + | goto bad_group; |
| + | } else |
| + | gid = -1; |
| } | |
| - | gid = grp->gr_gid; |
| + | |
| /* Find the selected user (if appropriate) */ | |
| - | if (whichApp==TRUE) { |
| - | pwd = getpwnam(*argv); |
| - | if (pwd == NULL) { |
| + | if (whichApp==CHOWN_APP) { |
| + | uid = my_getpwnam(*argv); |
| + | if (uid == -1) { |
| fprintf(stderr, "%s: Unknown user name: %s\n", invocationName, *argv); | |
| exit( FALSE); | |
| } | |
| - | uid = pwd->pw_uid; |
| } | |
| } | |
| @@ -142,173 +194,10 @@ int chmod_chown_chgrp_main(int argc, char **argv) | |
| exit( FALSE); | |
| } | |
| exit(TRUE); | |
| - | } |
| - | |
| - | |
| - | |
| - | |
| - | |
| - | |
| - | |
| - | |
| - | |
| - | |
| - | |
| - | #ifdef fooo |
| - | |
| - | |
| - | |
| - | |
| - | |
| - | |
| - | |
| - | |
| - | |
| - | |
| - | |
| - | |
| - | |
| - | |
| - | |
| - | #include "internal.h" |
| - | #include <pwd.h> |
| - | #include <grp.h> |
| - | #include <string.h> |
| - | #include <stdio.h> |
| - | |
| - | int my_getid(const char *filename, const char *name, uid_t *id) |
| - | { |
| - | FILE *stream; |
| - | uid_t rid; |
| - | char *rname, *start, *end, buf[128]; |
| - | |
| - | stream=fopen(filename,"r"); |
| - | |
| - | while (fgets (buf, 128, stream) != NULL) { |
| - | if (buf[0] == '#') |
| - | continue; |
| - | |
| - | start = buf; |
| - | end = strchr (start, ':'); |
| - | if (end == NULL) |
| - | continue; |
| - | *end = '\0'; |
| - | rname = start; |
| - | |
| - | start = end + 1; |
| - | end = strchr (start, ':'); |
| - | if (end == NULL) |
| - | continue; |
| - | |
| - | start = end + 1; |
| - | rid = (uid_t) strtol (start, &end, 10); |
| - | if (end == start) |
| - | continue; |
| - | |
| - | if (name) { |
| - | if (0 == strcmp(rname, name)) { |
| - | *id=rid; |
| - | return 0; |
| - | } |
| - | } else { |
| - | if ( *id == rid ) |
| - | return 0; |
| - | } |
| - | } |
| - | fclose(stream); |
| - | return -1; |
| + | bad_group: |
| + | fprintf(stderr, "%s: Unknown group name: %s\n", invocationName, groupName); |
| + | exit( FALSE); |
| } | |
| - | int |
| - | my_getpwuid(uid_t *uid) |
| - | { |
| - | return my_getid("/etc/passwd", NULL, uid); |
| - | } |
| - | |
| - | int |
| - | my_getpwnam(char *name, uid_t *uid) |
| - | { |
| - | return my_getid("/etc/passwd", name, uid); |
| - | } |
| - | |
| - | int |
| - | my_getgrgid(gid_t *gid) |
| - | { |
| - | return my_getid("/etc/group", NULL, gid); |
| - | } |
| - | |
| - | int |
| - | my_getgrnam(char *name, gid_t *gid) |
| - | { |
| - | return my_getid("/etc/group", name, gid); |
| - | } |
| - | |
| - | const char chown_usage[] = "chown [-R] user-name file [file ...]\n" |
| - | "\n\tThe group list is kept in the file /etc/groups.\n\n" |
| - | "\t-R:\tRecursively change the mode of all files and directories\n" |
| - | "\t\tunder the argument directory."; |
| - | |
| - | int |
| - | parse_user_name(const char * s, struct FileInfo * i) |
| - | { |
| - | char * dot = strchr(s, '.'); |
| - | char * end = NULL; |
| - | uid_t id = 0; |
| - | |
| - | if (! dot ) |
| - | dot = strchr(s, ':'); |
| - | |
| - | if ( dot ) |
| - | *dot = '\0'; |
| - | |
| - | if ( my_getpwnam(s,&id) == -1 ) { |
| - | id = strtol(s,&end,10); |
| - | if ((*end != '\0') || ( my_getpwuid(&id) == -1 )) { |
| - | fprintf(stderr, "%s: no such user.\n", s); |
| - | return 1; |
| - | } |
| - | } |
| - | i->userID = id; |
| - | |
| - | if ( dot ) { |
| - | if ( my_getgrnam(++dot,&id) == -1 ) { |
| - | id = strtol(dot,&end,10); |
| - | if ((*end != '\0') || ( my_getgrgid(&id) == -1 )) { |
| - | fprintf(stderr, "%s: no such group.\n", dot); |
| - | return 1; |
| - | } |
| - | } |
| - | i->groupID = id; |
| - | i->changeGroupID = 1; |
| - | } |
| - | return 0; |
| - | } |
| - | |
| - | extern int |
| - | chown_main(struct FileInfo * i, int argc, char * * argv) |
| - | { |
| - | int status; |
| - | |
| - | while ( argc >= 3 && strcmp("-R", argv[1]) == 0 ) { |
| - | i->recursive = 1; |
| - | argc--; |
| - | argv++; |
| - | } |
| - | |
| - | if ( (status = parse_user_name(argv[1], i)) != 0 ) |
| - | return status; |
| - | |
| - | argv++; |
| - | argc--; |
| - | |
| - | i->changeUserID = 1; |
| - | i->complainInPostProcess = 1; |
| - | |
| - | return monadic_main(i, argc, argv); |
| - | } |
| - | |
| - | |
| - | |
| - | #endif |
| @@ -32,7 +32,7 @@ | |
| #include <utime.h> | |
| #include <sys/stat.h> | |
| #include <unistd.h> | |
| - | |
| + | #include <ctype.h> |
| /* volatile so gcc knows this is the enod of the line */ | |
| volatile void usage(const char *usage) | |
| @@ -558,13 +558,17 @@ extern void createPath (const char *name, int mode) | |
| #if defined (BB_CHMOD_CHOWN_CHGRP) || defined (BB_MKDIR) | |
| - | /* [ugoa]{+|-|=}[rwxstl] */ |
| - | extern int parse_mode( const char* s, mode_t* theMode) |
| + | /* [ugoa]{+|-|=}[rwxst] */ |
| + | |
| + | |
| + | |
| + | extern int |
| + | parse_mode( const char* s, mode_t* theMode) |
| { | |
| - | mode_t or; |
| - | mode_t and; |
| + | mode_t andMode = S_ISVTX|S_ISUID|S_ISGID|S_IRWXU|S_IRWXG|S_IRWXO; |
| + | mode_t orMode = 0; |
| mode_t mode = 0; | |
| - | mode_t groups = S_ISVTX; |
| + | mode_t groups = 0; |
| char type; | |
| char c; | |
| @@ -572,7 +576,7 @@ extern int parse_mode( const char* s, mode_t* theMode) | |
| for ( ; ; ) { | |
| switch ( c = *s++ ) { | |
| case '\0': | |
| - | return (FALSE); |
| + | return -1; |
| case 'u': | |
| groups |= S_ISUID|S_IRWXU; | |
| continue; | |
| @@ -589,13 +593,15 @@ extern int parse_mode( const char* s, mode_t* theMode) | |
| case '=': | |
| case '-': | |
| type = c; | |
| - | if ( groups == S_ISVTX ) /* The default is "all" */ |
| + | if ( groups == 0 ) /* The default is "all" */ |
| groups |= S_ISUID|S_ISGID|S_IRWXU|S_IRWXG|S_IRWXO; | |
| break; | |
| default: | |
| - | if ( c >= '0' && c <= '7' && mode == 0 && groups == S_ISVTX ) { |
| - | and = 0; |
| - | or = strtol(--s, 0, 010); |
| + | if ( isdigit(c) && c >= '0' && c <= '7' && mode == 0 && groups == 0 ) { |
| + | andMode = 0; |
| + | orMode = strtol(--s, NULL, 8); |
| + | *theMode &= andMode; |
| + | *theMode |= orMode; |
| return (TRUE); | |
| } | |
| else | |
| @@ -621,28 +627,34 @@ extern int parse_mode( const char* s, mode_t* theMode) | |
| mode |= S_IXGRP|S_ISUID|S_ISGID; | |
| continue; | |
| case 't': | |
| - | mode |= S_ISVTX; |
| + | mode |= 0; |
| continue; | |
| default: | |
| - | return (FALSE); |
| + | *theMode &= andMode; |
| + | *theMode |= orMode; |
| + | return( TRUE); |
| } | |
| break; | |
| } | |
| switch ( type ) { | |
| case '=': | |
| - | and &= ~(groups); |
| + | andMode &= ~(groups); |
| /* fall through */ | |
| case '+': | |
| - | or |= mode & groups; |
| + | orMode |= mode & groups; |
| break; | |
| case '-': | |
| - | and &= ~(mode & groups); |
| - | or &= and; |
| + | andMode &= ~(mode & groups); |
| + | orMode &= andMode; |
| break; | |
| } | |
| } while ( c == ',' ); | |
| + | *theMode &= andMode; |
| + | *theMode |= orMode; |
| return (TRUE); | |
| } | |
| + | |
| + | |
| #endif | |