Mercurial > hg > toybox
comparison toys/chmod.c @ 590:7becb497c3c4
Update chmod to work with new dirtree, and fix bugs in string_to_mode().
author | Rob Landley <rob@landley.net> |
---|---|
date | Sun, 03 Jun 2012 00:32:12 -0500 |
parents | 4a91ede70548 |
children | 051dffe00b99 |
comparison
equal
deleted
inserted
replaced
589:7013fd450ff4 | 590:7becb497c3c4 |
---|---|
1 /* vi: set sw=4 ts=4: | 1 /* vi: set sw=4 ts=4: |
2 * | 2 * |
3 * chmod.c - Change file mode bits | 3 * chmod.c - Change file mode bits |
4 * | 4 * |
5 * Copyright 2012 Georgi Chorbadzhiyski <georgi@unixsol.org> | 5 * Copyright 2012 Rob Landley <rob@landley.net> |
6 * | 6 * |
7 * See http://pubs.opengroup.org/onlinepubs/009695399/utilities/chmod.html | 7 * See http://pubs.opengroup.org/onlinepubs/009695399/utilities/chmod.html |
8 * | 8 * |
9 | 9 |
10 USE_CHMOD(NEWTOY(chmod, "<2Rfv", TOYFLAG_BIN)) | 10 USE_CHMOD(NEWTOY(chmod, "<2?R", TOYFLAG_BIN)) |
11 | 11 |
12 config CHMOD | 12 config CHMOD |
13 bool "chmod" | 13 bool "chmod" |
14 default n | 14 default y |
15 help | 15 help |
16 usage: chmod [-R] [-f] [-v] mode file... | 16 usage: chmod [-R] MODE FILE... |
17 Change mode bits of one or more files. | |
18 | 17 |
19 -R recurse into subdirectories. | 18 Change mode of listed file[s] (recursively with -R). |
20 -f suppress most error messages. | 19 |
21 -v verbose output. | 20 MODE can be (comma-separated) stanzas: [ugoa][+-=][rwxstXugo] |
21 | |
22 Stanzas are applied in order: For each category (u = user, | |
23 g = group, o = other, a = all three, if none specified default is a), | |
24 set (+), clear (-), or copy (=), r = read, w = write, x = execute. | |
25 s = u+s = suid, g+s = sgid, o+s = sticky. (+t is an alias for o+s). | |
26 suid/sgid: execute as the user/group who owns the file. | |
27 sticky: can't delete files you don't own out of this directory | |
28 X = x for directories or if any category already has x set. | |
29 | |
30 Or MODE can be an octal value up to 7777 ug uuugggooo top + | |
31 bit 1 = o+x, bit 1<<8 = u+w, 1<<11 = g+1 sstrwxrwxrwx bottom | |
32 | |
33 Examples: | |
34 chmod u+w file - allow owner of "file" to write to it. | |
35 chmod 744 file - user can read/write/execute, everyone else read only | |
22 */ | 36 */ |
23 | 37 |
24 #include "toys.h" | 38 #include "toys.h" |
25 | 39 |
26 #define FLAG_R 4 | |
27 #define FLAG_f 2 | |
28 #define FLAG_v 1 | |
29 | |
30 DEFINE_GLOBALS( | 40 DEFINE_GLOBALS( |
31 long mode; | 41 char *mode; |
32 ) | 42 ) |
33 | 43 |
34 #define TT this.chmod | 44 #define TT this.chmod |
35 | 45 |
36 static int do_chmod(const char *path) { | 46 #define FLAG_R 1 |
37 int ret = chmod(path, TT.mode); | |
38 if (toys.optflags & FLAG_v) | |
39 xprintf("chmod(%04o, %s)\n", TT.mode, path); | |
40 if (ret == -1 && !(toys.optflags & FLAG_f)) | |
41 perror_msg("changing perms of '%s' to %04o", path, TT.mode); | |
42 toys.exitval |= ret; | |
43 return ret; | |
44 } | |
45 | 47 |
46 // Copied from toys/cp.c:cp_node() | 48 int do_chmod(struct dirtree *try) |
47 int chmod_node(char *path, struct dirtree *node) | |
48 { | 49 { |
49 char *s = path + strlen(path); | 50 mode_t mode; |
50 struct dirtree *n = node; | |
51 | 51 |
52 for ( ; ; n = n->parent) { | 52 if (!dirtree_notdotdot(try)) return 0; |
53 while (s!=path) { | |
54 if (*(--s) == '/') break; | |
55 } | |
56 if (!n) break; | |
57 } | |
58 if (s != path) s++; | |
59 | 53 |
60 do_chmod(s); | 54 mode = string_to_mode(TT.mode, try->st.st_mode); |
55 wfchmodat(try->parent ? try->parent->data : AT_FDCWD, try->name, mode); | |
61 | 56 |
62 return 0; | 57 return (toys.optflags & FLAG_R) ? DIRTREE_RECURSE : 0; |
63 } | 58 } |
64 | 59 |
65 void chmod_main(void) | 60 void chmod_main(void) |
66 { | 61 { |
67 char **s; | 62 TT.mode = *toys.optargs; |
68 TT.mode = strtoul(*toys.optargs, NULL, 8); | 63 char **file; |
69 | 64 |
70 if (toys.optflags & FLAG_R) { | 65 for (file = toys.optargs+1; *file; file++) dirtree_read(*file, do_chmod); |
71 // Recurse into subdirectories | |
72 for (s=toys.optargs + 1; *s; s++) { | |
73 struct stat sb; | |
74 if (stat(*s, &sb) == -1) { | |
75 if (!(toys.optflags & FLAG_f)) | |
76 perror_msg("%s", *s); | |
77 continue; | |
78 } | |
79 do_chmod(*s); | |
80 if (S_ISDIR(sb.st_mode)) { | |
81 strncpy(toybuf, *s, sizeof(toybuf) - 1); | |
82 toybuf[sizeof(toybuf) - 1] = 0; | |
83 dirtree_read(toybuf, NULL, chmod_node); | |
84 } | |
85 } | |
86 } else { | |
87 // Do not recurse | |
88 for (s=toys.optargs + 1; *s; s++) { | |
89 do_chmod(*s); | |
90 } | |
91 } | |
92 } | 66 } |