Home | History | Annotate | Download | only in toolbox
      1 #include <stdio.h>
      2 #include <stdlib.h>
      3 #include <string.h>
      4 #include <sys/types.h>
      5 #include <dirent.h>
      6 #include <errno.h>
      7 #include <sys/limits.h>
      8 #include <sys/stat.h>
      9 
     10 #include <unistd.h>
     11 #include <time.h>
     12 
     13 void recurse_chmod(char* path, int mode)
     14 {
     15     struct dirent *dp;
     16     DIR *dir = opendir(path);
     17     if (dir == NULL) {
     18         // not a directory, carry on
     19         return;
     20     }
     21     char *subpath = malloc(sizeof(char)*PATH_MAX);
     22     int pathlen = strlen(path);
     23 
     24     while ((dp = readdir(dir)) != NULL) {
     25         if (strcmp(dp->d_name, ".") == 0 ||
     26             strcmp(dp->d_name, "..") == 0) continue;
     27 
     28         if (strlen(dp->d_name) + pathlen + 2/*NUL and slash*/ > PATH_MAX) {
     29             fprintf(stderr, "Invalid path specified: too long\n");
     30             exit(1);
     31         }
     32 
     33         strcpy(subpath, path);
     34         strcat(subpath, "/");
     35         strcat(subpath, dp->d_name);
     36 
     37         if (chmod(subpath, mode) < 0) {
     38             fprintf(stderr, "Unable to chmod %s: %s\n", subpath, strerror(errno));
     39             exit(1);
     40         }
     41 
     42         recurse_chmod(subpath, mode);
     43     }
     44     free(subpath);
     45     closedir(dir);
     46 }
     47 
     48 static int usage()
     49 {
     50     fprintf(stderr, "Usage: chmod [OPTION] <MODE> <FILE>\n");
     51     fprintf(stderr, "  -R, --recursive         change files and directories recursively\n");
     52     fprintf(stderr, "  --help                  display this help and exit\n");
     53 
     54     return 10;
     55 }
     56 
     57 int chmod_main(int argc, char **argv)
     58 {
     59     int i;
     60 
     61     if (argc < 3 || strcmp(argv[1], "--help") == 0) {
     62         return usage();
     63     }
     64 
     65     int recursive = (strcmp(argv[1], "-R") == 0 ||
     66                      strcmp(argv[1], "--recursive") == 0) ? 1 : 0;
     67 
     68     if (recursive && argc < 4) {
     69         return usage();
     70     }
     71 
     72     if (recursive) {
     73         argc--;
     74         argv++;
     75     }
     76 
     77     int mode = 0;
     78     const char* s = argv[1];
     79     while (*s) {
     80         if (*s >= '0' && *s <= '7') {
     81             mode = (mode<<3) | (*s-'0');
     82         }
     83         else {
     84             fprintf(stderr, "Bad mode\n");
     85             return 10;
     86         }
     87         s++;
     88     }
     89 
     90     for (i = 2; i < argc; i++) {
     91         if (chmod(argv[i], mode) < 0) {
     92             fprintf(stderr, "Unable to chmod %s: %s\n", argv[i], strerror(errno));
     93             return 10;
     94         }
     95         if (recursive) {
     96             recurse_chmod(argv[i], mode);
     97         }
     98     }
     99     return 0;
    100 }
    101 
    102