diff options
author | Denys Vlasenko <vda.linux@googlemail.com> | 2021-06-20 10:57:24 +0200 |
---|---|---|
committer | Denys Vlasenko <vda.linux@googlemail.com> | 2021-06-20 11:02:49 +0200 |
commit | 526b8347906a18d756386092fafa0b42ba0b4563 (patch) | |
tree | aafe396ff964a194f183bead405b5f1045f67a61 /e2fsprogs | |
parent | 9c291f2cc0e0e76869c315b5c7e7883827b5ae95 (diff) | |
download | busybox-w32-526b8347906a18d756386092fafa0b42ba0b4563.tar.gz busybox-w32-526b8347906a18d756386092fafa0b42ba0b4563.tar.bz2 busybox-w32-526b8347906a18d756386092fafa0b42ba0b4563.zip |
lsattr,chattr: support -p
function old new delta
fgetsetprojid - 107 +107
list_attributes 169 222 +53
change_attributes 277 326 +49
chattr_main 272 307 +35
close_silently - 22 +22
.rodata 103378 103393 +15
packed_usage 33658 33666 +8
fgetsetversion 88 74 -14
fgetsetflags 162 148 -14
------------------------------------------------------------------------------
(add/remove: 2/0 grow/shrink: 5/2 up/down: 289/-28) Total: 261 bytes
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
Diffstat (limited to 'e2fsprogs')
-rw-r--r-- | e2fsprogs/chattr.c | 28 | ||||
-rw-r--r-- | e2fsprogs/e2fs_lib.c | 34 | ||||
-rw-r--r-- | e2fsprogs/e2fs_lib.h | 5 | ||||
-rw-r--r-- | e2fsprogs/lsattr.c | 32 |
4 files changed, 76 insertions, 23 deletions
diff --git a/e2fsprogs/chattr.c b/e2fsprogs/chattr.c index 1d267f7a4..5a7545e09 100644 --- a/e2fsprogs/chattr.c +++ b/e2fsprogs/chattr.c | |||
@@ -20,12 +20,12 @@ | |||
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: "[-R] [-v VERSION] [-+=AacDdijsStTu] FILE..." | 23 | //usage: "[-R] [-v VERSION] [-p PROJID] [-+=AacDdijsStTu] FILE..." |
24 | //usage:#define chattr_full_usage "\n\n" | 24 | //usage:#define chattr_full_usage "\n\n" |
25 | //usage: "Change ext2 file attributes\n" | 25 | //usage: "Change ext2 file attributes\n" |
26 | //usage: "\n -R Recurse" | 26 | //usage: "\n -R Recurse" |
27 | //TODD? "\n -p NUM Set project number" | ||
28 | //usage: "\n -v NUM Set version/generation number" | 27 | //usage: "\n -v NUM Set version/generation number" |
28 | //usage: "\n -p NUM Set project number" | ||
29 | //-V, -f accepted but ignored | 29 | //-V, -f accepted but ignored |
30 | //usage: "\nModifiers:" | 30 | //usage: "\nModifiers:" |
31 | //usage: "\n -,+,= Remove/add/set attributes" | 31 | //usage: "\n -,+,= Remove/add/set attributes" |
@@ -45,16 +45,18 @@ | |||
45 | #include "libbb.h" | 45 | #include "libbb.h" |
46 | #include "e2fs_lib.h" | 46 | #include "e2fs_lib.h" |
47 | 47 | ||
48 | #define OPT_ADD 1 | 48 | #define OPT_ADD (1 << 0) |
49 | #define OPT_REM 2 | 49 | #define OPT_REM (1 << 1) |
50 | #define OPT_SET 4 | 50 | #define OPT_SET (1 << 2) |
51 | #define OPT_SET_VER 8 | 51 | #define OPT_SET_VER (1 << 3) |
52 | #define OPT_SET_PROJ (1 << 4) | ||
52 | 53 | ||
53 | struct globals { | 54 | struct globals { |
54 | unsigned long version; | 55 | unsigned long version; |
55 | unsigned long af; | 56 | unsigned long af; |
56 | unsigned long rf; | 57 | unsigned long rf; |
57 | int flags; | 58 | int flags; |
59 | uint32_t projid; | ||
58 | smallint recursive; | 60 | smallint recursive; |
59 | }; | 61 | }; |
60 | 62 | ||
@@ -108,7 +110,13 @@ static char** decode_arg(char **argv, struct globals *gp) | |||
108 | gp->flags |= OPT_SET_VER; | 110 | gp->flags |= OPT_SET_VER; |
109 | continue; | 111 | continue; |
110 | } | 112 | } |
111 | //TODO: "-p PROJECT_NUM" ? | 113 | if (*arg == 'p') { |
114 | if (!*++argv) | ||
115 | bb_show_usage(); | ||
116 | gp->projid = xatou32(*argv); | ||
117 | gp->flags |= OPT_SET_PROJ; | ||
118 | continue; | ||
119 | } | ||
112 | /* not a known option, try as an attribute */ | 120 | /* not a known option, try as an attribute */ |
113 | } | 121 | } |
114 | *fl |= get_flag(*arg); | 122 | *fl |= get_flag(*arg); |
@@ -151,7 +159,11 @@ static void change_attributes(const char *name, struct globals *gp) | |||
151 | 159 | ||
152 | if (gp->flags & OPT_SET_VER) | 160 | if (gp->flags & OPT_SET_VER) |
153 | if (fsetversion(name, gp->version) != 0) | 161 | if (fsetversion(name, gp->version) != 0) |
154 | bb_perror_msg("setting version on %s", name); | 162 | bb_perror_msg("setting %s on %s", "version", name); |
163 | |||
164 | if (gp->flags & OPT_SET_PROJ) | ||
165 | if (fsetprojid(name, gp->projid) != 0) | ||
166 | bb_perror_msg("setting %s on %s", "project ID", name); | ||
155 | 167 | ||
156 | if (gp->flags & OPT_SET) { | 168 | if (gp->flags & OPT_SET) { |
157 | fsflags = gp->af; | 169 | fsflags = gp->af; |
diff --git a/e2fsprogs/e2fs_lib.c b/e2fsprogs/e2fs_lib.c index 8bd4da622..bc9aa53e5 100644 --- a/e2fsprogs/e2fs_lib.c +++ b/e2fsprogs/e2fs_lib.c | |||
@@ -51,14 +51,14 @@ int fgetsetversion(const char *name, unsigned long *get_version, unsigned long s | |||
51 | { | 51 | { |
52 | #if HAVE_EXT2_IOCTLS | 52 | #if HAVE_EXT2_IOCTLS |
53 | int fd, r; | 53 | int fd, r; |
54 | IF_LONG_IS_WIDER(int ver;) | 54 | IF_LONG_IS_WIDER(unsigned ver;) |
55 | 55 | ||
56 | fd = open(name, O_RDONLY | O_NONBLOCK); | 56 | fd = open(name, O_RDONLY | O_NONBLOCK); |
57 | if (fd == -1) | 57 | if (fd == -1) |
58 | return -1; | 58 | return -1; |
59 | if (!get_version) { | 59 | if (!get_version) { |
60 | IF_LONG_IS_WIDER( | 60 | IF_LONG_IS_WIDER( |
61 | ver = (int) set_version; | 61 | ver = (unsigned) set_version; |
62 | r = ioctl(fd, EXT2_IOC_SETVERSION, &ver); | 62 | r = ioctl(fd, EXT2_IOC_SETVERSION, &ver); |
63 | ) | 63 | ) |
64 | IF_LONG_IS_SAME( | 64 | IF_LONG_IS_SAME( |
@@ -81,6 +81,32 @@ int fgetsetversion(const char *name, unsigned long *get_version, unsigned long s | |||
81 | #endif /* ! HAVE_EXT2_IOCTLS */ | 81 | #endif /* ! HAVE_EXT2_IOCTLS */ |
82 | } | 82 | } |
83 | 83 | ||
84 | int fgetsetprojid(const char *name, uint32_t *get, uint32_t set) | ||
85 | { | ||
86 | #if HAVE_EXT2_IOCTLS | ||
87 | struct ext2_fsxattr fsxattr; | ||
88 | int fd, r; | ||
89 | |||
90 | fd = open(name, O_RDONLY | O_NONBLOCK); | ||
91 | if (fd == -1) | ||
92 | return -1; | ||
93 | r = ioctl(fd, EXT2_IOC_FSGETXATTR, &fsxattr); | ||
94 | /* note: ^^^ may fail in 32-bit userspace on 64-bit kernel (seen on 4.12.0) */ | ||
95 | if (r == 0) { | ||
96 | if (get) { | ||
97 | *get = fsxattr.fsx_projid; | ||
98 | } else { | ||
99 | fsxattr.fsx_projid = set; | ||
100 | r = ioctl(fd, EXT2_IOC_FSSETXATTR, &fsxattr); | ||
101 | } | ||
102 | } | ||
103 | close_silently(fd); | ||
104 | return r; | ||
105 | #else /* ! HAVE_EXT2_IOCTLS */ | ||
106 | errno = EOPNOTSUPP; | ||
107 | return -1; | ||
108 | #endif /* ! HAVE_EXT2_IOCTLS */ | ||
109 | } | ||
84 | 110 | ||
85 | /* Get/set a file flags on an ext2 file system */ | 111 | /* Get/set a file flags on an ext2 file system */ |
86 | int fgetsetflags(const char *name, unsigned long *get_flags, unsigned long set_flags) | 112 | int fgetsetflags(const char *name, unsigned long *get_flags, unsigned long set_flags) |
@@ -88,7 +114,7 @@ int fgetsetflags(const char *name, unsigned long *get_flags, unsigned long set_f | |||
88 | #if HAVE_EXT2_IOCTLS | 114 | #if HAVE_EXT2_IOCTLS |
89 | struct stat buf; | 115 | struct stat buf; |
90 | int fd, r; | 116 | int fd, r; |
91 | IF_LONG_IS_WIDER(int f;) | 117 | IF_LONG_IS_WIDER(unsigned f;) |
92 | 118 | ||
93 | if (stat(name, &buf) == 0 /* stat is ok */ | 119 | if (stat(name, &buf) == 0 /* stat is ok */ |
94 | && !S_ISREG(buf.st_mode) && !S_ISDIR(buf.st_mode) | 120 | && !S_ISREG(buf.st_mode) && !S_ISDIR(buf.st_mode) |
@@ -101,7 +127,7 @@ int fgetsetflags(const char *name, unsigned long *get_flags, unsigned long set_f | |||
101 | 127 | ||
102 | if (!get_flags) { | 128 | if (!get_flags) { |
103 | IF_LONG_IS_WIDER( | 129 | IF_LONG_IS_WIDER( |
104 | f = (int) set_flags; | 130 | f = (unsigned) set_flags; |
105 | r = ioctl(fd, EXT2_IOC_SETFLAGS, &f); | 131 | r = ioctl(fd, EXT2_IOC_SETFLAGS, &f); |
106 | ) | 132 | ) |
107 | IF_LONG_IS_SAME( | 133 | IF_LONG_IS_SAME( |
diff --git a/e2fsprogs/e2fs_lib.h b/e2fsprogs/e2fs_lib.h index ae28c353b..82a1581cb 100644 --- a/e2fsprogs/e2fs_lib.h +++ b/e2fsprogs/e2fs_lib.h | |||
@@ -21,6 +21,11 @@ int fgetsetversion(const char *name, unsigned long *get_version, unsigned long s | |||
21 | #define fgetversion(name, version) fgetsetversion(name, version, 0) | 21 | #define fgetversion(name, version) fgetsetversion(name, version, 0) |
22 | #define fsetversion(name, version) fgetsetversion(name, NULL, version) | 22 | #define fsetversion(name, version) fgetsetversion(name, NULL, version) |
23 | 23 | ||
24 | /* Get/set a file project ID on an ext2 file system */ | ||
25 | int fgetsetprojid(const char *name, uint32_t *get, uint32_t set); | ||
26 | #define fgetprojid(name, projid) fgetsetprojid(name, projid, 0) | ||
27 | #define fsetprojid(name, projid) fgetsetprojid(name, NULL, projid) | ||
28 | |||
24 | /* Get/set a file flags on an ext2 file system */ | 29 | /* Get/set a file flags on an ext2 file system */ |
25 | int fgetsetflags(const char *name, unsigned long *get_flags, unsigned long set_flags); | 30 | int fgetsetflags(const char *name, unsigned long *get_flags, unsigned long set_flags); |
26 | #define fgetflags(name, flags) fgetsetflags(name, flags, 0) | 31 | #define fgetflags(name, flags) fgetsetflags(name, flags, 0) |
diff --git a/e2fsprogs/lsattr.c b/e2fsprogs/lsattr.c index 91205ff65..9b035f584 100644 --- a/e2fsprogs/lsattr.c +++ b/e2fsprogs/lsattr.c | |||
@@ -21,38 +21,48 @@ | |||
21 | //kbuild:lib-$(CONFIG_LSATTR) += lsattr.o e2fs_lib.o | 21 | //kbuild:lib-$(CONFIG_LSATTR) += lsattr.o e2fs_lib.o |
22 | 22 | ||
23 | //usage:#define lsattr_trivial_usage | 23 | //usage:#define lsattr_trivial_usage |
24 | //usage: "[-Radlv] [FILE]..." | 24 | //usage: "[-Radlpv] [FILE]..." |
25 | //usage:#define lsattr_full_usage "\n\n" | 25 | //usage:#define lsattr_full_usage "\n\n" |
26 | //usage: "List ext2 file attributes\n" | 26 | //usage: "List ext2 file attributes\n" |
27 | //usage: "\n -R Recurse" | 27 | //usage: "\n -R Recurse" |
28 | //usage: "\n -a Don't hide entries starting with ." | 28 | //usage: "\n -a Include names starting with ." |
29 | //usage: "\n -d List directory entries instead of contents" | 29 | //usage: "\n -d List directory names, not contents" |
30 | // -a,-d text should match ls --help | ||
30 | //usage: "\n -l List long flag names" | 31 | //usage: "\n -l List long flag names" |
32 | //usage: "\n -p List project ID" | ||
31 | //usage: "\n -v List version/generation number" | 33 | //usage: "\n -v List version/generation number" |
32 | 34 | ||
33 | #include "libbb.h" | 35 | #include "libbb.h" |
34 | #include "e2fs_lib.h" | 36 | #include "e2fs_lib.h" |
35 | 37 | ||
36 | enum { | 38 | enum { |
37 | OPT_RECUR = 0x1, | 39 | OPT_RECUR = 1 << 0, |
38 | OPT_ALL = 0x2, | 40 | OPT_ALL = 1 << 1, |
39 | OPT_DIRS_OPT = 0x4, | 41 | OPT_DIRS_OPT = 1 << 2, |
40 | OPT_PF_LONG = 0x8, | 42 | OPT_PF_LONG = 1 << 3, |
41 | OPT_GENERATION = 0x10, | 43 | OPT_GENERATION = 1 << 4, |
44 | OPT_PROJID = 1 << 5, | ||
42 | }; | 45 | }; |
43 | 46 | ||
44 | static void list_attributes(const char *name) | 47 | static void list_attributes(const char *name) |
45 | { | 48 | { |
46 | unsigned long fsflags; | 49 | unsigned long fsflags; |
47 | unsigned long generation; | ||
48 | 50 | ||
49 | if (fgetflags(name, &fsflags) != 0) | 51 | if (fgetflags(name, &fsflags) != 0) |
50 | goto read_err; | 52 | goto read_err; |
51 | 53 | ||
54 | if (option_mask32 & OPT_PROJID) { | ||
55 | uint32_t p; | ||
56 | if (fgetprojid(name, &p) != 0) | ||
57 | goto read_err; | ||
58 | printf("%5lu ", (unsigned long)p); | ||
59 | } | ||
60 | |||
52 | if (option_mask32 & OPT_GENERATION) { | 61 | if (option_mask32 & OPT_GENERATION) { |
62 | unsigned long generation; | ||
53 | if (fgetversion(name, &generation) != 0) | 63 | if (fgetversion(name, &generation) != 0) |
54 | goto read_err; | 64 | goto read_err; |
55 | printf("%5lu ", generation); | 65 | printf("%-10lu ", generation); |
56 | } | 66 | } |
57 | 67 | ||
58 | if (option_mask32 & OPT_PF_LONG) { | 68 | if (option_mask32 & OPT_PF_LONG) { |
@@ -111,7 +121,7 @@ static void lsattr_args(const char *name) | |||
111 | int lsattr_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; | 121 | int lsattr_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; |
112 | int lsattr_main(int argc UNUSED_PARAM, char **argv) | 122 | int lsattr_main(int argc UNUSED_PARAM, char **argv) |
113 | { | 123 | { |
114 | getopt32(argv, "Radlv"); | 124 | getopt32(argv, "Radlvp"); |
115 | argv += optind; | 125 | argv += optind; |
116 | 126 | ||
117 | if (!*argv) | 127 | if (!*argv) |