• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
recurse_chmod(char * path,int mode)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 
usage()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 
chmod_main(int argc,char ** argv)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