summaryrefslogtreecommitdiffstats
path: root/toolbox
diff options
context:
space:
mode:
authorJean-Baptiste Queru <jbq@google.com>2010-07-14 15:17:47 -0700
committerAndroid Code Review <code-review@android.com>2010-07-14 15:17:47 -0700
commit6cebee264761cf9ed3a9b8b1ec939baf6e446afd (patch)
tree91d9d534fb612c2573c3ce212c8fc14826cc0d17 /toolbox
parent34225919abe715f9ac34acfbb6eba88a282628b2 (diff)
parent365a09e817e919c491a1e8abce0b734af14d3e5f (diff)
downloadsystem_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.c67
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;
}