aboutsummaryrefslogtreecommitdiff
path: root/e2fsprogs/chattr.c
diff options
context:
space:
mode:
Diffstat (limited to 'e2fsprogs/chattr.c')
-rw-r--r--e2fsprogs/chattr.c58
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
63struct globals { 86struct 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
155static void change_attributes(const char *name, struct globals *gp) 190static 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);