diff options
Diffstat (limited to 'coreutils/chmod.c')
-rw-r--r-- | coreutils/chmod.c | 161 |
1 files changed, 98 insertions, 63 deletions
diff --git a/coreutils/chmod.c b/coreutils/chmod.c index 225c92d..9f84d0d 100644 --- a/coreutils/chmod.c +++ b/coreutils/chmod.c @@ -1,41 +1,54 @@ -#include <stdlib.h> +/* + * Mini chmod implementation for busybox + * + * Copyright (C) 1998 by Erik Andersen <andersee@debian.org> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + #include <stdio.h> -#include <unistd.h> -#include <sys/stat.h> +#include <grp.h> +#include <pwd.h> #include "internal.h" -const char chmod_usage[] = "chmod [-R] mode file [file ...]\n" -"\nmode may be an octal integer representing the bit pattern for the\n" -"\tnew mode, or a symbolic value matching the pattern\n" -"\t[ugoa]{+|-|=}[rwxst] .\n" -"\t\tu:\tUser\n" -"\t\tg:\tGroup\n" -"\t\to:\tOthers\n" -"\t\ta:\tAll\n" -"\n" -"\n+:\tAdd privilege\n" -"\n-:\tRemove privilege\n" -"\n=:\tSet privilege\n" -"\n" -"\t\tr:\tRead\n" -"\t\tw:\tWrite\n" -"\t\tx:\tExecute\n" -"\t\ts:\tSet User ID\n" -"\t\tt:\t\"Sticky\" Text\n" -"\n" -"\tModes may be concatenated, as in \"u=rwx,g=rx,o=rx,-t,-s\n" -"\n" -"\t-R:\tRecursively change the mode of all files and directories\n" -"\t\tunder the argument directory."; - -int -parse_mode( - const char * s -,mode_t * or -,mode_t * and -,int * group_execute) + +static mode_t mode=7777; + + +static const char chmod_usage[] = "[-R] MODE[,MODE]... FILE...\n" +"Each MODE is one or more of the letters ugoa, one of the symbols +-= and\n" +"one or more of the letters rwxst.\n\n" + "\t-R\tchange files and directories recursively.\n"; + + + +static int fileAction(const char *fileName) +{ + struct stat statBuf; + if ((stat(fileName, &statBuf) < 0) || + (chmod(fileName, mode)) < 0) { + perror(fileName); + return( FALSE); + } + return( TRUE); +} + +/* [ugoa]{+|-|=}[rwxstl] */ +int parse_mode( const char* s, mode_t* or, mode_t* and, int* group_execute) { - /* [ugoa]{+|-|=}[rwxstl] */ mode_t mode = 0; mode_t groups = S_ISVTX; char type; @@ -45,7 +58,7 @@ parse_mode( for ( ; ; ) { switch ( c = *s++ ) { case '\0': - return -1; + return (FALSE); case 'u': groups |= S_ISUID|S_IRWXU; continue; @@ -69,10 +82,10 @@ parse_mode( if ( c >= '0' && c <= '7' && mode == 0 && groups == S_ISVTX ) { *and = 0; *or = strtol(--s, 0, 010); - return 0; + return (TRUE); } else - return -1; + return (FALSE); } break; } @@ -93,7 +106,7 @@ parse_mode( case 's': if ( group_execute != 0 && (groups & S_IRWXG) ) { if ( *group_execute < 0 ) - return -1; + return (FALSE); if ( type != '-' ) { mode |= S_IXGRP; *group_execute = 1; @@ -103,7 +116,7 @@ parse_mode( continue; case 'l': if ( *group_execute > 0 ) - return -1; + return (FALSE); if ( type != '-' ) { *and &= ~S_IXGRP; *group_execute = -1; @@ -115,7 +128,7 @@ parse_mode( mode |= S_ISVTX; continue; default: - return -1; + return (FALSE); } break; } @@ -132,32 +145,54 @@ parse_mode( break; } } while ( c == ',' ); - return 0; + return (TRUE); } -extern int -chmod_main(struct FileInfo * i, int argc, char * * argv) + +int chmod_main(int argc, char **argv) { - i->andWithMode = S_ISVTX|S_ISUID|S_ISGID|S_IRWXU|S_IRWXG|S_IRWXO; - i->orWithMode = 0; - - while ( argc >= 3 ) { - if ( parse_mode(argv[1], &i->orWithMode, &i->andWithMode, 0) - == 0 ) { - argc--; - argv++; - } - else if ( strcmp(argv[1], "-R") == 0 ) { - i->recursive = 1; - argc--; - argv++; - } - else - break; - } + int recursiveFlag=FALSE; + mode_t andWithMode = S_ISVTX|S_ISUID|S_ISGID|S_IRWXU|S_IRWXG|S_IRWXO; + mode_t orWithMode = 0; + char *invocationName=*argv; - i->changeMode = 1; - i->complainInPostProcess = 1; + if (argc < 3) { + fprintf(stderr, "Usage: %s %s", invocationName, chmod_usage); + exit( FALSE); + } + argc--; + argv++; + + /* Parse options */ + while (**argv == '-') { + while (*++(*argv)) switch (**argv) { + case 'R': + recursiveFlag = TRUE; + break; + default: + fprintf(stderr, "Unknown option: %c\n", **argv); + exit( FALSE); + } + argc--; + argv++; + } + + /* Find the selected group */ + if ( parse_mode(*argv, &orWithMode, &andWithMode, 0) == FALSE ) { + fprintf(stderr, "%s: Unknown mode: %s\n", invocationName, *argv); + exit( FALSE); + } + mode &= andWithMode; + mode |= orWithMode; - return monadic_main(i, argc, argv); + /* Ok, ready to do the deed now */ + if (argc <= 1) { + fprintf(stderr, "%s: too few arguments", invocationName); + exit( FALSE); + } + while (argc-- > 1) { + argv++; + recursiveAction( *argv, recursiveFlag, TRUE, fileAction, fileAction); + } + exit(TRUE); } |