diff options
Diffstat (limited to 'e2fsprogs/chattr.c')
-rw-r--r-- | e2fsprogs/chattr.c | 58 |
1 files changed, 58 insertions, 0 deletions
diff --git a/e2fsprogs/chattr.c b/e2fsprogs/chattr.c index 5dec3253b..d8f92137e 100644 --- a/e2fsprogs/chattr.c +++ b/e2fsprogs/chattr.c | |||
@@ -20,13 +20,26 @@ | |||
20 | //kbuild:lib-$(CONFIG_CHATTR) += chattr.o e2fs_lib.o | 20 | //kbuild:lib-$(CONFIG_CHATTR) += chattr.o e2fs_lib.o |
21 | 21 | ||
22 | //usage:#define chattr_trivial_usage | 22 | //usage:#define chattr_trivial_usage |
23 | //usage: IF_NOT_PLATFORM_MINGW32( | ||
23 | //usage: "[-R] [-v VERSION] [-p PROJID] [-+=AacDdijsStTu] FILE..." | 24 | //usage: "[-R] [-v VERSION] [-p PROJID] [-+=AacDdijsStTu] FILE..." |
25 | //usage: ) | ||
26 | //usage: IF_PLATFORM_MINGW32( | ||
27 | //usage: "[-R] [-+rhsatn] FILE..." | ||
28 | //usage: ) | ||
24 | //usage:#define chattr_full_usage "\n\n" | 29 | //usage:#define chattr_full_usage "\n\n" |
30 | //usage: IF_NOT_PLATFORM_MINGW32( | ||
25 | //usage: "Change ext2 file attributes\n" | 31 | //usage: "Change ext2 file attributes\n" |
32 | //usage: ) | ||
33 | //usage: IF_PLATFORM_MINGW32( | ||
34 | //usage: "Change file attributes\n" | ||
35 | //usage: ) | ||
26 | //usage: "\n -R Recurse" | 36 | //usage: "\n -R Recurse" |
37 | //usage: IF_NOT_PLATFORM_MINGW32( | ||
27 | //usage: "\n -v NUM Set version/generation number" | 38 | //usage: "\n -v NUM Set version/generation number" |
28 | //usage: "\n -p NUM Set project number" | 39 | //usage: "\n -p NUM Set project number" |
40 | //usage: ) | ||
29 | //-V, -f accepted but ignored | 41 | //-V, -f accepted but ignored |
42 | //usage: IF_NOT_PLATFORM_MINGW32( | ||
30 | //usage: "\nModifiers:" | 43 | //usage: "\nModifiers:" |
31 | //usage: "\n -,+,= Remove/add/set attributes" | 44 | //usage: "\n -,+,= Remove/add/set attributes" |
32 | //usage: "\nAttributes:" | 45 | //usage: "\nAttributes:" |
@@ -50,6 +63,16 @@ | |||
50 | //usage: "\n t Don't tail-merge with other files" | 63 | //usage: "\n t Don't tail-merge with other files" |
51 | //usage: "\n u Allow undelete" | 64 | //usage: "\n u Allow undelete" |
52 | //usage: "\n V Verity" | 65 | //usage: "\n V Verity" |
66 | //usage: ) | ||
67 | //usage: IF_PLATFORM_MINGW32( | ||
68 | //usage: "\n -,+ Remove/add attributes" | ||
69 | //usage: "\n r Read only" | ||
70 | //usage: "\n h Hidden" | ||
71 | //usage: "\n s System" | ||
72 | //usage: "\n a Archive" | ||
73 | //usage: "\n t Temporary" | ||
74 | //usage: "\n n Not indexed" | ||
75 | //usage: ) | ||
53 | 76 | ||
54 | #include "libbb.h" | 77 | #include "libbb.h" |
55 | #include "e2fs_lib.h" | 78 | #include "e2fs_lib.h" |
@@ -61,11 +84,15 @@ | |||
61 | #define OPT_SET_PROJ (1 << 4) | 84 | #define OPT_SET_PROJ (1 << 4) |
62 | 85 | ||
63 | struct globals { | 86 | struct globals { |
87 | #if !ENABLE_PLATFORM_MINGW32 | ||
64 | unsigned version; | 88 | unsigned version; |
89 | #endif | ||
65 | unsigned af; | 90 | unsigned af; |
66 | unsigned rf; | 91 | unsigned rf; |
67 | int flags; | 92 | int flags; |
93 | #if !ENABLE_PLATFORM_MINGW32 | ||
68 | uint32_t projid; | 94 | uint32_t projid; |
95 | #endif | ||
69 | smallint recursive; | 96 | smallint recursive; |
70 | }; | 97 | }; |
71 | 98 | ||
@@ -89,11 +116,17 @@ static char** decode_arg(char **argv, struct globals *gp) | |||
89 | /* testcase: chattr =ae -R FILE should not complain "= is incompatible with - and +" */ | 116 | /* testcase: chattr =ae -R FILE should not complain "= is incompatible with - and +" */ |
90 | /* (and should not read flags, with =FLAGS they can be just set directly) */ | 117 | /* (and should not read flags, with =FLAGS they can be just set directly) */ |
91 | fl = &gp->rf; | 118 | fl = &gp->rf; |
119 | #if ENABLE_PLATFORM_MINGW32 | ||
120 | } else { /* if (opt == '+') */ | ||
121 | gp->flags |= OPT_ADD; | ||
122 | } | ||
123 | #else | ||
92 | } else if (opt == '+') { | 124 | } else if (opt == '+') { |
93 | gp->flags |= OPT_ADD; | 125 | gp->flags |= OPT_ADD; |
94 | } else { /* if (opt == '=') */ | 126 | } else { /* if (opt == '=') */ |
95 | gp->flags |= OPT_SET; | 127 | gp->flags |= OPT_SET; |
96 | } | 128 | } |
129 | #endif | ||
97 | 130 | ||
98 | while (*++arg) { | 131 | while (*++arg) { |
99 | if (opt == '-') { | 132 | if (opt == '-') { |
@@ -106,6 +139,7 @@ static char** decode_arg(char **argv, struct globals *gp) | |||
106 | gp->recursive = 1; | 139 | gp->recursive = 1; |
107 | continue; | 140 | continue; |
108 | } | 141 | } |
142 | #if !ENABLE_PLATFORM_MINGW32 | ||
109 | if (*arg == 'V') { | 143 | if (*arg == 'V') { |
110 | /*"verbose and print program version" (nop for now) */; | 144 | /*"verbose and print program version" (nop for now) */; |
111 | continue; | 145 | continue; |
@@ -128,6 +162,7 @@ static char** decode_arg(char **argv, struct globals *gp) | |||
128 | gp->flags |= OPT_SET_PROJ; | 162 | gp->flags |= OPT_SET_PROJ; |
129 | continue; | 163 | continue; |
130 | } | 164 | } |
165 | #endif | ||
131 | /* not a known option, try as an attribute */ | 166 | /* not a known option, try as an attribute */ |
132 | gp->flags |= OPT_REM; | 167 | gp->flags |= OPT_REM; |
133 | } | 168 | } |
@@ -154,8 +189,10 @@ static int FAST_FUNC chattr_dir_proc(const char *dir_name, struct dirent *de, vo | |||
154 | 189 | ||
155 | static void change_attributes(const char *name, struct globals *gp) | 190 | static void change_attributes(const char *name, struct globals *gp) |
156 | { | 191 | { |
192 | #if !ENABLE_PLATFORM_MINGW32 | ||
157 | unsigned fsflags; | 193 | unsigned fsflags; |
158 | int fd; | 194 | int fd; |
195 | #endif | ||
159 | struct stat st; | 196 | struct stat st; |
160 | 197 | ||
161 | if (lstat(name, &st) != 0) { | 198 | if (lstat(name, &st) != 0) { |
@@ -170,6 +207,7 @@ static void change_attributes(const char *name, struct globals *gp) | |||
170 | if (!S_ISREG(st.st_mode) && !S_ISLNK(st.st_mode) && !S_ISDIR(st.st_mode)) | 207 | if (!S_ISREG(st.st_mode) && !S_ISLNK(st.st_mode) && !S_ISDIR(st.st_mode)) |
171 | return; | 208 | return; |
172 | 209 | ||
210 | #if !ENABLE_PLATFORM_MINGW32 | ||
173 | /* There is no way to run needed ioctls on a symlink. | 211 | /* There is no way to run needed ioctls on a symlink. |
174 | * open(O_PATH | O_NOFOLLOW) _can_ be used to get a fd referring to the symlink, | 212 | * open(O_PATH | O_NOFOLLOW) _can_ be used to get a fd referring to the symlink, |
175 | * but ioctls fail on such a fd (tried on 4.12.0 kernel). | 213 | * but ioctls fail on such a fd (tried on 4.12.0 kernel). |
@@ -221,6 +259,16 @@ static void change_attributes(const char *name, struct globals *gp) | |||
221 | skip_setflags: | 259 | skip_setflags: |
222 | close(fd); | 260 | close(fd); |
223 | } | 261 | } |
262 | #else /* ENABLE_PLATFORM_MINGW32 */ | ||
263 | /*if (gp->flags & OPT_REM) - not needed, rf is zero otherwise */ | ||
264 | st.st_attr &= ~gp->rf; | ||
265 | /*if (gp->flags & OPT_ADD) - not needed, af is zero otherwise */ | ||
266 | st.st_attr |= gp->af; | ||
267 | if (!SetFileAttributes(name, st.st_attr & CHATTR_MASK)) { | ||
268 | errno = err_win_to_posix(); | ||
269 | bb_perror_msg("setting flags on %s", name); | ||
270 | } | ||
271 | #endif | ||
224 | 272 | ||
225 | if (gp->recursive && S_ISDIR(st.st_mode)) | 273 | if (gp->recursive && S_ISDIR(st.st_mode)) |
226 | iterate_on_dir(name, chattr_dir_proc, gp); | 274 | iterate_on_dir(name, chattr_dir_proc, gp); |
@@ -238,7 +286,11 @@ int chattr_main(int argc UNUSED_PARAM, char **argv) | |||
238 | char *arg = *++argv; | 286 | char *arg = *++argv; |
239 | if (!arg) | 287 | if (!arg) |
240 | bb_show_usage(); | 288 | bb_show_usage(); |
289 | #if ENABLE_PLATFORM_MINGW32 | ||
290 | if (arg[0] != '-' && arg[0] != '+') | ||
291 | #else | ||
241 | if (arg[0] != '-' && arg[0] != '+' && arg[0] != '=') | 292 | if (arg[0] != '-' && arg[0] != '+' && arg[0] != '=') |
293 | #endif | ||
242 | break; | 294 | break; |
243 | 295 | ||
244 | argv = decode_arg(argv, &g); | 296 | argv = decode_arg(argv, &g); |
@@ -246,12 +298,18 @@ int chattr_main(int argc UNUSED_PARAM, char **argv) | |||
246 | /* note: on loop exit, remaining argv[] is never empty */ | 298 | /* note: on loop exit, remaining argv[] is never empty */ |
247 | 299 | ||
248 | /* run sanity checks on all the arguments given us */ | 300 | /* run sanity checks on all the arguments given us */ |
301 | #if !ENABLE_PLATFORM_MINGW32 | ||
249 | if ((g.flags & OPT_SET) && (g.flags & (OPT_ADD|OPT_REM))) | 302 | if ((g.flags & OPT_SET) && (g.flags & (OPT_ADD|OPT_REM))) |
250 | bb_simple_error_msg_and_die("= is incompatible with - and +"); | 303 | bb_simple_error_msg_and_die("= is incompatible with - and +"); |
304 | #endif | ||
251 | if (g.rf & g.af) | 305 | if (g.rf & g.af) |
252 | bb_simple_error_msg_and_die("can't set and unset a flag"); | 306 | bb_simple_error_msg_and_die("can't set and unset a flag"); |
253 | if (!g.flags) | 307 | if (!g.flags) |
308 | #if ENABLE_PLATFORM_MINGW32 | ||
309 | bb_simple_error_msg_and_die("must use - or +"); | ||
310 | #else | ||
254 | bb_simple_error_msg_and_die("must use -v, -p, =, - or +"); | 311 | bb_simple_error_msg_and_die("must use -v, -p, =, - or +"); |
312 | #endif | ||
255 | 313 | ||
256 | /* now run chattr on all the files passed to us */ | 314 | /* now run chattr on all the files passed to us */ |
257 | do change_attributes(*argv, &g); while (*++argv); | 315 | do change_attributes(*argv, &g); while (*++argv); |