diff options
author | Jean-Baptiste Queru <jbq@google.com> | 2010-07-14 15:17:47 -0700 |
---|---|---|
committer | Android Code Review <code-review@android.com> | 2010-07-14 15:17:47 -0700 |
commit | 6cebee264761cf9ed3a9b8b1ec939baf6e446afd (patch) | |
tree | 91d9d534fb612c2573c3ce212c8fc14826cc0d17 /toolbox | |
parent | 34225919abe715f9ac34acfbb6eba88a282628b2 (diff) | |
parent | 365a09e817e919c491a1e8abce0b734af14d3e5f (diff) | |
download | system_core-6cebee264761cf9ed3a9b8b1ec939baf6e446afd.zip system_core-6cebee264761cf9ed3a9b8b1ec939baf6e446afd.tar.gz system_core-6cebee264761cf9ed3a9b8b1ec939baf6e446afd.tar.bz2 |
Merge "Add -R to chmod"
Diffstat (limited to 'toolbox')
-rw-r--r-- | toolbox/chmod.c | 67 |
1 files changed, 64 insertions, 3 deletions
diff --git a/toolbox/chmod.c b/toolbox/chmod.c index 31a53bf..2a524e9 100644 --- a/toolbox/chmod.c +++ b/toolbox/chmod.c @@ -4,17 +4,74 @@ #include <sys/types.h> #include <dirent.h> #include <errno.h> +#include <sys/limits.h> +#include <sys/stat.h> #include <unistd.h> #include <time.h> +void recurse_chmod(char* path, int mode) +{ + struct dirent *dp; + DIR *dir = opendir(path); + if (dir == NULL) { + // not a directory, carry on + return; + } + char *subpath = malloc(sizeof(char)*PATH_MAX); + int pathlen = strlen(path); + + while ((dp = readdir(dir)) != NULL) { + if (strcmp(dp->d_name, ".") == 0 || + strcmp(dp->d_name, "..") == 0) continue; + + if (strlen(dp->d_name) + pathlen + 2/*NUL and slash*/ > PATH_MAX) { + fprintf(stderr, "Invalid path specified: too long\n"); + exit(1); + } + + strcpy(subpath, path); + strcat(subpath, "/"); + strcat(subpath, dp->d_name); + + if (chmod(subpath, mode) < 0) { + fprintf(stderr, "Unable to chmod %s: %s\n", subpath, strerror(errno)); + exit(1); + } + + recurse_chmod(subpath, mode); + } + free(subpath); + closedir(dir); +} + +static int usage() +{ + fprintf(stderr, "Usage: chmod [OPTION] <MODE> <FILE>\n"); + fprintf(stderr, " -R, --recursive change files and directories recursively\n"); + fprintf(stderr, " --help display this help and exit\n"); + + return 10; +} + int chmod_main(int argc, char **argv) { int i; - if (argc < 3) { - fprintf(stderr, "Usage: chmod <MODE> <FILE>\n"); - return 10; + if (argc < 3 || strcmp(argv[1], "--help") == 0) { + return usage(); + } + + int recursive = (strcmp(argv[1], "-R") == 0 || + strcmp(argv[1], "--recursive") == 0) ? 1 : 0; + + if (recursive && argc < 4) { + return usage(); + } + + if (recursive) { + argc--; + argv++; } int mode = 0; @@ -29,11 +86,15 @@ int chmod_main(int argc, char **argv) } s++; } + for (i = 2; i < argc; i++) { if (chmod(argv[i], mode) < 0) { fprintf(stderr, "Unable to chmod %s: %s\n", argv[i], strerror(errno)); return 10; } + if (recursive) { + recurse_chmod(argv[i], mode); + } } return 0; } |