diff options
author | Ron Yorston <rmy@pobox.com> | 2020-11-12 08:27:51 +0000 |
---|---|---|
committer | Ron Yorston <rmy@pobox.com> | 2020-11-12 08:27:51 +0000 |
commit | ead8b92e3d66ab45235e137f85fb3a529dcc64ef (patch) | |
tree | af268270382dad969218063d4a8120fc91a9e631 /util-linux | |
parent | 567728c22dddea4ed33b8a69641ba2e0c3f1f600 (diff) | |
parent | 64981b4c8e88812c322bee3832f1d421ff670ed5 (diff) | |
download | busybox-w32-ead8b92e3d66ab45235e137f85fb3a529dcc64ef.tar.gz busybox-w32-ead8b92e3d66ab45235e137f85fb3a529dcc64ef.tar.bz2 busybox-w32-ead8b92e3d66ab45235e137f85fb3a529dcc64ef.zip |
Merge branch 'busybox' into merge
Diffstat (limited to 'util-linux')
-rw-r--r-- | util-linux/getopt.c | 5 | ||||
-rw-r--r-- | util-linux/hexdump.c | 61 | ||||
-rw-r--r-- | util-linux/hexdump_xxd.c | 77 | ||||
-rw-r--r-- | util-linux/losetup.c | 2 | ||||
-rw-r--r-- | util-linux/lspci.c | 11 | ||||
-rw-r--r-- | util-linux/lsusb.c | 10 | ||||
-rw-r--r-- | util-linux/mdev.c | 20 | ||||
-rw-r--r-- | util-linux/mount.c | 65 | ||||
-rw-r--r-- | util-linux/setpriv.c | 9 | ||||
-rw-r--r-- | util-linux/switch_root.c | 4 | ||||
-rw-r--r-- | util-linux/volume_id/get_devname.c | 14 |
11 files changed, 172 insertions, 106 deletions
diff --git a/util-linux/getopt.c b/util-linux/getopt.c index db7db6ff8..1fa402429 100644 --- a/util-linux/getopt.c +++ b/util-linux/getopt.c | |||
@@ -289,12 +289,13 @@ static struct option *add_long_options(struct option *long_options, char *option | |||
289 | { | 289 | { |
290 | int long_nr = 0; | 290 | int long_nr = 0; |
291 | int arg_opt, tlen; | 291 | int arg_opt, tlen; |
292 | char *tokptr = strtok(options, ", \t\n"); | 292 | char *tokptr; |
293 | 293 | ||
294 | if (long_options) | 294 | if (long_options) |
295 | while (long_options[long_nr].name) | 295 | while (long_options[long_nr].name) |
296 | long_nr++; | 296 | long_nr++; |
297 | 297 | ||
298 | tokptr = strtok_r(options, ", \t\n", &options); | ||
298 | while (tokptr) { | 299 | while (tokptr) { |
299 | arg_opt = no_argument; | 300 | arg_opt = no_argument; |
300 | tlen = strlen(tokptr); | 301 | tlen = strlen(tokptr); |
@@ -318,7 +319,7 @@ static struct option *add_long_options(struct option *long_options, char *option | |||
318 | long_nr++; | 319 | long_nr++; |
319 | /*memset(&long_options[long_nr], 0, sizeof(long_options[0])); - xrealloc_vector did it */ | 320 | /*memset(&long_options[long_nr], 0, sizeof(long_options[0])); - xrealloc_vector did it */ |
320 | } | 321 | } |
321 | tokptr = strtok(NULL, ", \t\n"); | 322 | tokptr = strtok_r(NULL, ", \t\n", &options); |
322 | } | 323 | } |
323 | return long_options; | 324 | return long_options; |
324 | } | 325 | } |
diff --git a/util-linux/hexdump.c b/util-linux/hexdump.c index 065b83980..2174c3008 100644 --- a/util-linux/hexdump.c +++ b/util-linux/hexdump.c | |||
@@ -15,16 +15,6 @@ | |||
15 | //config: The hexdump utility is used to display binary data in a readable | 15 | //config: The hexdump utility is used to display binary data in a readable |
16 | //config: way that is comparable to the output from most hex editors. | 16 | //config: way that is comparable to the output from most hex editors. |
17 | //config: | 17 | //config: |
18 | //config:config FEATURE_HEXDUMP_REVERSE | ||
19 | //config: bool "Support -R, reverse of 'hexdump -Cv'" | ||
20 | //config: default y | ||
21 | //config: depends on HEXDUMP | ||
22 | //config: help | ||
23 | //config: The hexdump utility is used to display binary data in an ascii | ||
24 | //config: readable way. This option creates binary data from an ascii input. | ||
25 | //config: NB: this option is non-standard. It's unwise to use it in scripts | ||
26 | //config: aimed to be portable. | ||
27 | //config: | ||
28 | //config:config HD | 18 | //config:config HD |
29 | //config: bool "hd (7.8 kb)" | 19 | //config: bool "hd (7.8 kb)" |
30 | //config: default y | 20 | //config: default y |
@@ -38,7 +28,7 @@ | |||
38 | //kbuild:lib-$(CONFIG_HD) += hexdump.o | 28 | //kbuild:lib-$(CONFIG_HD) += hexdump.o |
39 | 29 | ||
40 | //usage:#define hexdump_trivial_usage | 30 | //usage:#define hexdump_trivial_usage |
41 | //usage: "[-bcCdefnosvx" IF_FEATURE_HEXDUMP_REVERSE("R") "] [FILE]..." | 31 | //usage: "[-bcCdefnosvx] [FILE]..." |
42 | //usage:#define hexdump_full_usage "\n\n" | 32 | //usage:#define hexdump_full_usage "\n\n" |
43 | //usage: "Display FILEs (or stdin) in a user specified format\n" | 33 | //usage: "Display FILEs (or stdin) in a user specified format\n" |
44 | //usage: "\n -b 1-byte octal display" | 34 | //usage: "\n -b 1-byte octal display" |
@@ -53,9 +43,6 @@ | |||
53 | // exactly the same help text lines in hexdump and xxd: | 43 | // exactly the same help text lines in hexdump and xxd: |
54 | //usage: "\n -n LENGTH Show only first LENGTH bytes" | 44 | //usage: "\n -n LENGTH Show only first LENGTH bytes" |
55 | //usage: "\n -s OFFSET Skip OFFSET bytes" | 45 | //usage: "\n -s OFFSET Skip OFFSET bytes" |
56 | //usage: IF_FEATURE_HEXDUMP_REVERSE( | ||
57 | //usage: "\n -R Reverse of 'hexdump -Cv'") | ||
58 | // TODO: NONCOMPAT!!! move -R to xxd -r | ||
59 | //usage: | 46 | //usage: |
60 | //usage:#define hd_trivial_usage | 47 | //usage:#define hd_trivial_usage |
61 | //usage: "FILE..." | 48 | //usage: "FILE..." |
@@ -94,7 +81,7 @@ static const char *const add_strings[] = { | |||
94 | 81 | ||
95 | static const char add_first[] ALIGN1 = "\"%07.7_Ax\n\""; | 82 | static const char add_first[] ALIGN1 = "\"%07.7_Ax\n\""; |
96 | 83 | ||
97 | static const char hexdump_opts[] ALIGN1 = "bcdoxCe:f:n:s:v" IF_FEATURE_HEXDUMP_REVERSE("R"); | 84 | static const char hexdump_opts[] ALIGN1 = "bcdoxCe:f:n:s:v"; |
98 | 85 | ||
99 | int hexdump_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; | 86 | int hexdump_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; |
100 | int hexdump_main(int argc, char **argv) | 87 | int hexdump_main(int argc, char **argv) |
@@ -102,10 +89,6 @@ int hexdump_main(int argc, char **argv) | |||
102 | dumper_t *dumper = alloc_dumper(); | 89 | dumper_t *dumper = alloc_dumper(); |
103 | const char *p; | 90 | const char *p; |
104 | int ch; | 91 | int ch; |
105 | #if ENABLE_FEATURE_HEXDUMP_REVERSE | ||
106 | FILE *fp; | ||
107 | smallint rdump = 0; | ||
108 | #endif | ||
109 | 92 | ||
110 | if (ENABLE_HD | 93 | if (ENABLE_HD |
111 | && (!ENABLE_HEXDUMP || !applet_name[2]) | 94 | && (!ENABLE_HEXDUMP || !applet_name[2]) |
@@ -153,11 +136,6 @@ int hexdump_main(int argc, char **argv) | |||
153 | if (ch == 'v') { | 136 | if (ch == 'v') { |
154 | dumper->dump_vflag = ALL; | 137 | dumper->dump_vflag = ALL; |
155 | } | 138 | } |
156 | #if ENABLE_FEATURE_HEXDUMP_REVERSE | ||
157 | if (ch == 'R') { | ||
158 | rdump = 1; | ||
159 | } | ||
160 | #endif | ||
161 | } | 139 | } |
162 | 140 | ||
163 | if (!dumper->fshead) { | 141 | if (!dumper->fshead) { |
@@ -167,40 +145,5 @@ int hexdump_main(int argc, char **argv) | |||
167 | 145 | ||
168 | argv += optind; | 146 | argv += optind; |
169 | 147 | ||
170 | #if !ENABLE_FEATURE_HEXDUMP_REVERSE | ||
171 | return bb_dump_dump(dumper, argv); | 148 | return bb_dump_dump(dumper, argv); |
172 | #else | ||
173 | if (!rdump) { | ||
174 | return bb_dump_dump(dumper, argv); | ||
175 | } | ||
176 | |||
177 | /* -R: reverse of 'hexdump -Cv' */ | ||
178 | fp = stdin; | ||
179 | if (!*argv) { | ||
180 | argv--; | ||
181 | goto jump_in; | ||
182 | } | ||
183 | |||
184 | do { | ||
185 | char *buf; | ||
186 | fp = xfopen_for_read(*argv); | ||
187 | jump_in: | ||
188 | while ((buf = xmalloc_fgetline(fp)) != NULL) { | ||
189 | p = buf; | ||
190 | while (1) { | ||
191 | /* skip address or previous byte */ | ||
192 | while (isxdigit(*p)) p++; | ||
193 | while (*p == ' ') p++; | ||
194 | /* '|' char will break the line */ | ||
195 | if (!isxdigit(*p) || sscanf(p, "%x ", &ch) != 1) | ||
196 | break; | ||
197 | putchar(ch); | ||
198 | } | ||
199 | free(buf); | ||
200 | } | ||
201 | fclose(fp); | ||
202 | } while (*++argv); | ||
203 | |||
204 | fflush_stdout_and_exit(EXIT_SUCCESS); | ||
205 | #endif | ||
206 | } | 149 | } |
diff --git a/util-linux/hexdump_xxd.c b/util-linux/hexdump_xxd.c index 6cf6d0297..d2f4b6ed8 100644 --- a/util-linux/hexdump_xxd.c +++ b/util-linux/hexdump_xxd.c | |||
@@ -50,6 +50,7 @@ | |||
50 | // exactly the same help text lines in hexdump and xxd: | 50 | // exactly the same help text lines in hexdump and xxd: |
51 | //usage: "\n -l LENGTH Show only first LENGTH bytes" | 51 | //usage: "\n -l LENGTH Show only first LENGTH bytes" |
52 | //usage: "\n -s OFFSET Skip OFFSET bytes" | 52 | //usage: "\n -s OFFSET Skip OFFSET bytes" |
53 | //usage: "\n -r Reverse (with -p, assumes no offsets in input)" | ||
53 | // TODO: implement -r (see hexdump -R) | 54 | // TODO: implement -r (see hexdump -R) |
54 | 55 | ||
55 | #include "libbb.h" | 56 | #include "libbb.h" |
@@ -57,6 +58,71 @@ | |||
57 | 58 | ||
58 | /* This is a NOEXEC applet. Be very careful! */ | 59 | /* This is a NOEXEC applet. Be very careful! */ |
59 | 60 | ||
61 | #define OPT_l (1 << 0) | ||
62 | #define OPT_s (1 << 1) | ||
63 | #define OPT_a (1 << 2) | ||
64 | #define OPT_p (1 << 3) | ||
65 | #define OPT_r (1 << 4) | ||
66 | |||
67 | static void reverse(unsigned opt, unsigned cols, const char *filename) | ||
68 | { | ||
69 | FILE *fp; | ||
70 | char *buf; | ||
71 | |||
72 | fp = filename ? xfopen_for_read(filename) : stdin; | ||
73 | |||
74 | while ((buf = xmalloc_fgetline(fp)) != NULL) { | ||
75 | char *p = buf; | ||
76 | unsigned cnt = cols; | ||
77 | |||
78 | if (!(opt & OPT_p)) { | ||
79 | /* skip address */ | ||
80 | while (isxdigit(*p)) p++; | ||
81 | /* NB: for xxd -r, first hex portion is address even without colon */ | ||
82 | /* If it's there, skip it: */ | ||
83 | if (*p == ':') p++; | ||
84 | |||
85 | //TODO: seek (or zero-pad if unseekable) to the address position | ||
86 | //NOTE: -s SEEK value should be added to the address before seeking | ||
87 | } | ||
88 | |||
89 | /* Process hex bytes optionally separated by whitespace */ | ||
90 | do { | ||
91 | uint8_t val, c; | ||
92 | |||
93 | p = skip_whitespace(p); | ||
94 | |||
95 | c = *p++; | ||
96 | if (isdigit(c)) | ||
97 | val = c - '0'; | ||
98 | else if ((c|0x20) >= 'a' && (c|0x20) <= 'f') | ||
99 | val = (c|0x20) - ('a' - 10); | ||
100 | else | ||
101 | break; | ||
102 | val <<= 4; | ||
103 | |||
104 | /* Works the same with xxd V1.10: | ||
105 | * echo "31 09 32 0a" | xxd -r -p | ||
106 | * echo "31 0 9 32 0a" | xxd -r -p | ||
107 | * thus allow whitespace even within the byte: | ||
108 | */ | ||
109 | p = skip_whitespace(p); | ||
110 | |||
111 | c = *p++; | ||
112 | if (isdigit(c)) | ||
113 | val |= c - '0'; | ||
114 | else if ((c|0x20) >= 'a' && (c|0x20) <= 'f') | ||
115 | val |= (c|0x20) - ('a' - 10); | ||
116 | else | ||
117 | break; | ||
118 | putchar(val); | ||
119 | } while (!(opt & OPT_p) || --cnt != 0); | ||
120 | free(buf); | ||
121 | } | ||
122 | //fclose(fp); | ||
123 | fflush_stdout_and_exit(EXIT_SUCCESS); | ||
124 | } | ||
125 | |||
60 | int xxd_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; | 126 | int xxd_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; |
61 | int xxd_main(int argc UNUSED_PARAM, char **argv) | 127 | int xxd_main(int argc UNUSED_PARAM, char **argv) |
62 | { | 128 | { |
@@ -69,11 +135,7 @@ int xxd_main(int argc UNUSED_PARAM, char **argv) | |||
69 | 135 | ||
70 | dumper = alloc_dumper(); | 136 | dumper = alloc_dumper(); |
71 | 137 | ||
72 | #define OPT_l (1 << 0) | 138 | opt = getopt32(argv, "^" "l:s:aprg:+c:+" "\0" "?1" /* 1 argument max */, |
73 | #define OPT_s (1 << 1) | ||
74 | #define OPT_a (1 << 2) | ||
75 | #define OPT_p (1 << 3) | ||
76 | opt = getopt32(argv, "^" "l:s:apg:+c:+" "\0" "?1" /* 1 argument max */, | ||
77 | &opt_l, &opt_s, &bytes, &cols | 139 | &opt_l, &opt_s, &bytes, &cols |
78 | ); | 140 | ); |
79 | argv += optind; | 141 | argv += optind; |
@@ -107,6 +169,10 @@ int xxd_main(int argc UNUSED_PARAM, char **argv) | |||
107 | bb_dump_add(dumper, "\"%08.8_ax: \""); // "address: " | 169 | bb_dump_add(dumper, "\"%08.8_ax: \""); // "address: " |
108 | } | 170 | } |
109 | 171 | ||
172 | if (opt & OPT_r) { | ||
173 | reverse(opt, cols, argv[0]); | ||
174 | } | ||
175 | |||
110 | if (bytes < 1 || bytes >= cols) { | 176 | if (bytes < 1 || bytes >= cols) { |
111 | sprintf(buf, "%u/1 \"%%02x\"", cols); // cols * "xx" | 177 | sprintf(buf, "%u/1 \"%%02x\"", cols); // cols * "xx" |
112 | bb_dump_add(dumper, buf); | 178 | bb_dump_add(dumper, buf); |
@@ -141,6 +207,7 @@ int xxd_main(int argc UNUSED_PARAM, char **argv) | |||
141 | bb_dump_add(dumper, buf); | 207 | bb_dump_add(dumper, buf); |
142 | } else { | 208 | } else { |
143 | bb_dump_add(dumper, "\"\n\""); | 209 | bb_dump_add(dumper, "\"\n\""); |
210 | dumper->eofstring = "\n"; | ||
144 | } | 211 | } |
145 | 212 | ||
146 | return bb_dump_dump(dumper, argv); | 213 | return bb_dump_dump(dumper, argv); |
diff --git a/util-linux/losetup.c b/util-linux/losetup.c index ac8b79502..24f7a2349 100644 --- a/util-linux/losetup.c +++ b/util-linux/losetup.c | |||
@@ -150,7 +150,7 @@ int losetup_main(int argc UNUSED_PARAM, char **argv) | |||
150 | if (opt & OPT_P) { | 150 | if (opt & OPT_P) { |
151 | flags |= BB_LO_FLAGS_PARTSCAN; | 151 | flags |= BB_LO_FLAGS_PARTSCAN; |
152 | } | 152 | } |
153 | if (set_loop(&d, argv[0], offset, flags) < 0) | 153 | if (set_loop(&d, argv[0], offset, 0, flags) < 0) |
154 | bb_simple_perror_msg_and_die(argv[0]); | 154 | bb_simple_perror_msg_and_die(argv[0]); |
155 | return EXIT_SUCCESS; | 155 | return EXIT_SUCCESS; |
156 | } | 156 | } |
diff --git a/util-linux/lspci.c b/util-linux/lspci.c index 2f0b5fab9..c22cbcc1e 100644 --- a/util-linux/lspci.c +++ b/util-linux/lspci.c | |||
@@ -37,11 +37,9 @@ enum { | |||
37 | /* | 37 | /* |
38 | * PCI_SLOT_NAME PCI_CLASS: PCI_VID:PCI_DID [PCI_SUBSYS_VID:PCI_SUBSYS_DID] [DRIVER] | 38 | * PCI_SLOT_NAME PCI_CLASS: PCI_VID:PCI_DID [PCI_SUBSYS_VID:PCI_SUBSYS_DID] [DRIVER] |
39 | */ | 39 | */ |
40 | static int FAST_FUNC fileAction( | 40 | static int FAST_FUNC fileAction(struct recursive_state *state UNUSED_PARAM, |
41 | const char *fileName, | 41 | const char *fileName, |
42 | struct stat *statbuf UNUSED_PARAM, | 42 | struct stat *statbuf UNUSED_PARAM) |
43 | void *userData UNUSED_PARAM, | ||
44 | int depth UNUSED_PARAM) | ||
45 | { | 43 | { |
46 | parser_t *parser; | 44 | parser_t *parser; |
47 | char *tokens[3]; | 45 | char *tokens[3]; |
@@ -117,8 +115,7 @@ int lspci_main(int argc UNUSED_PARAM, char **argv) | |||
117 | ACTION_RECURSE, | 115 | ACTION_RECURSE, |
118 | fileAction, | 116 | fileAction, |
119 | NULL, /* dirAction */ | 117 | NULL, /* dirAction */ |
120 | NULL, /* userData */ | 118 | NULL /* userData */ |
121 | 0 /* depth */); | 119 | ); |
122 | |||
123 | return EXIT_SUCCESS; | 120 | return EXIT_SUCCESS; |
124 | } | 121 | } |
diff --git a/util-linux/lsusb.c b/util-linux/lsusb.c index 64a00eee2..9abb748ce 100644 --- a/util-linux/lsusb.c +++ b/util-linux/lsusb.c | |||
@@ -24,11 +24,9 @@ | |||
24 | 24 | ||
25 | #include "libbb.h" | 25 | #include "libbb.h" |
26 | 26 | ||
27 | static int FAST_FUNC fileAction( | 27 | static int FAST_FUNC fileAction(struct recursive_state *state UNUSED_PARAM, |
28 | const char *fileName, | 28 | const char *fileName, |
29 | struct stat *statbuf UNUSED_PARAM, | 29 | struct stat *statbuf UNUSED_PARAM) |
30 | void *userData UNUSED_PARAM, | ||
31 | int depth UNUSED_PARAM) | ||
32 | { | 30 | { |
33 | parser_t *parser; | 31 | parser_t *parser; |
34 | char *tokens[4]; | 32 | char *tokens[4]; |
@@ -80,8 +78,8 @@ int lsusb_main(int argc UNUSED_PARAM, char **argv UNUSED_PARAM) | |||
80 | ACTION_RECURSE, | 78 | ACTION_RECURSE, |
81 | fileAction, | 79 | fileAction, |
82 | NULL, /* dirAction */ | 80 | NULL, /* dirAction */ |
83 | NULL, /* userData */ | 81 | NULL /* userData */ |
84 | 0 /* depth */); | 82 | ); |
85 | 83 | ||
86 | return EXIT_SUCCESS; | 84 | return EXIT_SUCCESS; |
87 | } | 85 | } |
diff --git a/util-linux/mdev.c b/util-linux/mdev.c index f42bebc20..59dbcf0cd 100644 --- a/util-linux/mdev.c +++ b/util-linux/mdev.c | |||
@@ -845,13 +845,12 @@ static ssize_t readlink2(char *buf, size_t bufsize) | |||
845 | /* File callback for /sys/ traversal. | 845 | /* File callback for /sys/ traversal. |
846 | * We act only on "/sys/.../dev" (pseudo)file | 846 | * We act only on "/sys/.../dev" (pseudo)file |
847 | */ | 847 | */ |
848 | static int FAST_FUNC fileAction(const char *fileName, | 848 | static int FAST_FUNC fileAction(struct recursive_state *state, |
849 | struct stat *statbuf UNUSED_PARAM, | 849 | const char *fileName, |
850 | void *userData, | 850 | struct stat *statbuf UNUSED_PARAM) |
851 | int depth UNUSED_PARAM) | ||
852 | { | 851 | { |
853 | size_t len = strlen(fileName) - 4; /* can't underflow */ | 852 | size_t len = strlen(fileName) - 4; /* can't underflow */ |
854 | char *path = userData; /* char array[PATH_MAX + SCRATCH_SIZE] */ | 853 | char *path = state->userData; /* char array[PATH_MAX + SCRATCH_SIZE] */ |
855 | char subsys[PATH_MAX]; | 854 | char subsys[PATH_MAX]; |
856 | int res; | 855 | int res; |
857 | 856 | ||
@@ -888,12 +887,11 @@ static int FAST_FUNC fileAction(const char *fileName, | |||
888 | } | 887 | } |
889 | 888 | ||
890 | /* Directory callback for /sys/ traversal */ | 889 | /* Directory callback for /sys/ traversal */ |
891 | static int FAST_FUNC dirAction(const char *fileName UNUSED_PARAM, | 890 | static int FAST_FUNC dirAction(struct recursive_state *state, |
892 | struct stat *statbuf UNUSED_PARAM, | 891 | const char *fileName UNUSED_PARAM, |
893 | void *userData UNUSED_PARAM, | 892 | struct stat *statbuf UNUSED_PARAM) |
894 | int depth) | ||
895 | { | 893 | { |
896 | return (depth >= MAX_SYSFS_DEPTH ? SKIP : TRUE); | 894 | return (state->depth >= MAX_SYSFS_DEPTH ? SKIP : TRUE); |
897 | } | 895 | } |
898 | 896 | ||
899 | /* For the full gory details, see linux/Documentation/firmware_class/README | 897 | /* For the full gory details, see linux/Documentation/firmware_class/README |
@@ -1149,7 +1147,7 @@ static void initial_scan(char *temp) | |||
1149 | /* Create all devices from /sys/dev hierarchy */ | 1147 | /* Create all devices from /sys/dev hierarchy */ |
1150 | recursive_action("/sys/dev", | 1148 | recursive_action("/sys/dev", |
1151 | ACTION_RECURSE | ACTION_FOLLOWLINKS, | 1149 | ACTION_RECURSE | ACTION_FOLLOWLINKS, |
1152 | fileAction, dirAction, temp, 0); | 1150 | fileAction, dirAction, temp); |
1153 | } | 1151 | } |
1154 | 1152 | ||
1155 | #if ENABLE_FEATURE_MDEV_DAEMON | 1153 | #if ENABLE_FEATURE_MDEV_DAEMON |
diff --git a/util-linux/mount.c b/util-linux/mount.c index b92e2c297..fc5161d7f 100644 --- a/util-linux/mount.c +++ b/util-linux/mount.c | |||
@@ -1230,6 +1230,7 @@ static NOINLINE int nfsmount(struct mntent *mp, unsigned long vfsflags, char *fi | |||
1230 | * then data pointer is interpreted as a string. */ | 1230 | * then data pointer is interpreted as a string. */ |
1231 | struct nfs_mount_data data; | 1231 | struct nfs_mount_data data; |
1232 | char *opt; | 1232 | char *opt; |
1233 | char *tokstate; | ||
1233 | struct hostent *hp; | 1234 | struct hostent *hp; |
1234 | struct sockaddr_in server_addr; | 1235 | struct sockaddr_in server_addr; |
1235 | struct sockaddr_in mount_server_addr; | 1236 | struct sockaddr_in mount_server_addr; |
@@ -1348,7 +1349,7 @@ static NOINLINE int nfsmount(struct mntent *mp, unsigned long vfsflags, char *fi | |||
1348 | nfsvers = 0; | 1349 | nfsvers = 0; |
1349 | 1350 | ||
1350 | /* parse options */ | 1351 | /* parse options */ |
1351 | if (filteropts) for (opt = strtok(filteropts, ","); opt; opt = strtok(NULL, ",")) { | 1352 | if (filteropts) for (opt = strtok_r(filteropts, ",", &tokstate); opt; opt = strtok_r(NULL, ",", &tokstate)) { |
1352 | char *opteq = strchr(opt, '='); | 1353 | char *opteq = strchr(opt, '='); |
1353 | if (opteq) { | 1354 | if (opteq) { |
1354 | int val, idx; | 1355 | int val, idx; |
@@ -1886,6 +1887,58 @@ static int nfsmount(struct mntent *mp, unsigned long vfsflags, char *filteropts) | |||
1886 | 1887 | ||
1887 | #endif // !ENABLE_FEATURE_MOUNT_NFS | 1888 | #endif // !ENABLE_FEATURE_MOUNT_NFS |
1888 | 1889 | ||
1890 | // Find "...,NAME=NUM,..." in the option string, remove "NAME=NUM" option | ||
1891 | // and return NUM. | ||
1892 | // Return 0 if not found. | ||
1893 | // All instances must be parsed and removed (for example, since kernel 5.4 | ||
1894 | // squashfs: Unknown parameter 'sizelimit' | ||
1895 | // will result if loopback mount option "sizelimit=NNN" is not removed | ||
1896 | // and squashfs sees it in option string). | ||
1897 | static unsigned long long cut_out_ull_opt(char *opts, const char *name_eq) | ||
1898 | { | ||
1899 | unsigned long long ret = 0; | ||
1900 | |||
1901 | if (!opts) // allow NULL opts (simplifies callers' work) | ||
1902 | return ret; | ||
1903 | |||
1904 | for (;;) { | ||
1905 | char *end; | ||
1906 | char *opt; | ||
1907 | |||
1908 | // Find comma-delimited "NAME=" | ||
1909 | for (;;) { | ||
1910 | opt = strstr(opts, name_eq); | ||
1911 | if (!opt) | ||
1912 | return ret; | ||
1913 | if (opt == opts) | ||
1914 | break; // found it (it's first opt) | ||
1915 | if (opt[-1] == ',') { | ||
1916 | opts = opt - 1; | ||
1917 | break; // found it (it's not a first opt) | ||
1918 | } | ||
1919 | // False positive like "VNAME=", we are at "N". | ||
1920 | // - skip it, loop back to searching | ||
1921 | opts = opt + 1; | ||
1922 | } | ||
1923 | |||
1924 | ret = bb_strtoull(opt + strlen(name_eq), &end, 0); | ||
1925 | if (errno && errno != EINVAL) { | ||
1926 | err: | ||
1927 | bb_error_msg_and_die("bad option '%s'", opt); | ||
1928 | } | ||
1929 | if (*end == '\0') { | ||
1930 | // It is "[,]NAME=NUM\0" - truncate it and return | ||
1931 | *opts = '\0'; | ||
1932 | return ret; | ||
1933 | } | ||
1934 | if (*end != ',') | ||
1935 | goto err; | ||
1936 | // We are at trailing comma | ||
1937 | // Remove "NAME=NUM," and loop back to check for duplicate opts | ||
1938 | overlapping_strcpy(opt, end + 1); | ||
1939 | } | ||
1940 | } | ||
1941 | |||
1889 | // Mount one directory. Handles CIFS, NFS, loopback, autobind, and filesystem | 1942 | // Mount one directory. Handles CIFS, NFS, loopback, autobind, and filesystem |
1890 | // type detection. Returns 0 for success, nonzero for failure. | 1943 | // type detection. Returns 0 for success, nonzero for failure. |
1891 | // NB: mp->xxx fields may be trashed on exit | 1944 | // NB: mp->xxx fields may be trashed on exit |
@@ -2029,9 +2082,16 @@ static int singlemount(struct mntent *mp, int ignore_busy) | |||
2029 | ) { | 2082 | ) { |
2030 | // Do we need to allocate a loopback device for it? | 2083 | // Do we need to allocate a loopback device for it? |
2031 | if (ENABLE_FEATURE_MOUNT_LOOP && S_ISREG(st.st_mode)) { | 2084 | if (ENABLE_FEATURE_MOUNT_LOOP && S_ISREG(st.st_mode)) { |
2085 | unsigned long long offset; | ||
2086 | unsigned long long sizelimit; | ||
2087 | |||
2032 | loopFile = bb_simplify_path(mp->mnt_fsname); | 2088 | loopFile = bb_simplify_path(mp->mnt_fsname); |
2033 | mp->mnt_fsname = NULL; // will receive malloced loop dev name | 2089 | mp->mnt_fsname = NULL; // will receive malloced loop dev name |
2034 | 2090 | ||
2091 | // Parse and remove loopback options | ||
2092 | offset = cut_out_ull_opt(filteropts, "offset="); | ||
2093 | sizelimit = cut_out_ull_opt(filteropts, "sizelimit="); | ||
2094 | |||
2035 | // mount always creates AUTOCLEARed loopdevs, so that umounting | 2095 | // mount always creates AUTOCLEARed loopdevs, so that umounting |
2036 | // drops them without any code in the userspace. | 2096 | // drops them without any code in the userspace. |
2037 | // This happens since circa linux-2.6.25: | 2097 | // This happens since circa linux-2.6.25: |
@@ -2040,7 +2100,8 @@ static int singlemount(struct mntent *mp, int ignore_busy) | |||
2040 | // Subject: Allow auto-destruction of loop devices | 2100 | // Subject: Allow auto-destruction of loop devices |
2041 | loopfd = set_loop(&mp->mnt_fsname, | 2101 | loopfd = set_loop(&mp->mnt_fsname, |
2042 | loopFile, | 2102 | loopFile, |
2043 | 0, | 2103 | offset, |
2104 | sizelimit, | ||
2044 | ((vfsflags & MS_RDONLY) ? BB_LO_FLAGS_READ_ONLY : 0) | 2105 | ((vfsflags & MS_RDONLY) ? BB_LO_FLAGS_READ_ONLY : 0) |
2045 | | BB_LO_FLAGS_AUTOCLEAR | 2106 | | BB_LO_FLAGS_AUTOCLEAR |
2046 | ); | 2107 | ); |
diff --git a/util-linux/setpriv.c b/util-linux/setpriv.c index 37e8821a1..1e4b201ed 100644 --- a/util-linux/setpriv.c +++ b/util-linux/setpriv.c | |||
@@ -144,10 +144,11 @@ static unsigned parse_cap(const char *cap) | |||
144 | static void set_inh_caps(char *capstring) | 144 | static void set_inh_caps(char *capstring) |
145 | { | 145 | { |
146 | struct caps caps; | 146 | struct caps caps; |
147 | char *string; | ||
147 | 148 | ||
148 | getcaps(&caps); | 149 | getcaps(&caps); |
149 | 150 | ||
150 | capstring = strtok(capstring, ","); | 151 | capstring = strtok_r(capstring, ",", &string); |
151 | while (capstring) { | 152 | while (capstring) { |
152 | unsigned cap; | 153 | unsigned cap; |
153 | 154 | ||
@@ -159,7 +160,7 @@ static void set_inh_caps(char *capstring) | |||
159 | caps.data[CAP_TO_INDEX(cap)].inheritable |= CAP_TO_MASK(cap); | 160 | caps.data[CAP_TO_INDEX(cap)].inheritable |= CAP_TO_MASK(cap); |
160 | else | 161 | else |
161 | caps.data[CAP_TO_INDEX(cap)].inheritable &= ~CAP_TO_MASK(cap); | 162 | caps.data[CAP_TO_INDEX(cap)].inheritable &= ~CAP_TO_MASK(cap); |
162 | capstring = strtok(NULL, ","); | 163 | capstring = strtok_r(NULL, ",", &string); |
163 | } | 164 | } |
164 | 165 | ||
165 | if (capset(&caps.header, caps.data) != 0) | 166 | if (capset(&caps.header, caps.data) != 0) |
@@ -170,7 +171,7 @@ static void set_ambient_caps(char *string) | |||
170 | { | 171 | { |
171 | char *cap; | 172 | char *cap; |
172 | 173 | ||
173 | cap = strtok(string, ","); | 174 | cap = strtok_r(string, ",", &string); |
174 | while (cap) { | 175 | while (cap) { |
175 | unsigned idx; | 176 | unsigned idx; |
176 | 177 | ||
@@ -182,7 +183,7 @@ static void set_ambient_caps(char *string) | |||
182 | if (prctl(PR_CAP_AMBIENT, PR_CAP_AMBIENT_LOWER, idx, 0, 0) < 0) | 183 | if (prctl(PR_CAP_AMBIENT, PR_CAP_AMBIENT_LOWER, idx, 0, 0) < 0) |
183 | bb_simple_perror_msg("cap_ambient_lower"); | 184 | bb_simple_perror_msg("cap_ambient_lower"); |
184 | } | 185 | } |
185 | cap = strtok(NULL, ","); | 186 | cap = strtok_r(NULL, ",", &string); |
186 | } | 187 | } |
187 | } | 188 | } |
188 | #endif /* FEATURE_SETPRIV_CAPABILITIES */ | 189 | #endif /* FEATURE_SETPRIV_CAPABILITIES */ |
diff --git a/util-linux/switch_root.c b/util-linux/switch_root.c index c65096c27..f2674b5ac 100644 --- a/util-linux/switch_root.c +++ b/util-linux/switch_root.c | |||
@@ -164,7 +164,7 @@ static void drop_capabilities(char *string) | |||
164 | { | 164 | { |
165 | char *cap; | 165 | char *cap; |
166 | 166 | ||
167 | cap = strtok(string, ","); | 167 | cap = strtok_r(string, ",", &string); |
168 | while (cap) { | 168 | while (cap) { |
169 | unsigned cap_idx; | 169 | unsigned cap_idx; |
170 | 170 | ||
@@ -174,7 +174,7 @@ static void drop_capabilities(char *string) | |||
174 | drop_bounding_set(cap_idx); | 174 | drop_bounding_set(cap_idx); |
175 | drop_capset(cap_idx); | 175 | drop_capset(cap_idx); |
176 | bb_error_msg("dropped capability: %s", cap); | 176 | bb_error_msg("dropped capability: %s", cap); |
177 | cap = strtok(NULL, ","); | 177 | cap = strtok_r(NULL, ",", &string); |
178 | } | 178 | } |
179 | } | 179 | } |
180 | #endif | 180 | #endif |
diff --git a/util-linux/volume_id/get_devname.c b/util-linux/volume_id/get_devname.c index 34f5d119f..00cfb2826 100644 --- a/util-linux/volume_id/get_devname.c +++ b/util-linux/volume_id/get_devname.c | |||
@@ -102,10 +102,9 @@ uuidcache_addentry(char *device, /*int major, int minor,*/ char *label, char *uu | |||
102 | * add a cache entry for this device. | 102 | * add a cache entry for this device. |
103 | * If device node does not exist, it will be temporarily created. */ | 103 | * If device node does not exist, it will be temporarily created. */ |
104 | static int FAST_FUNC | 104 | static int FAST_FUNC |
105 | uuidcache_check_device(const char *device, | 105 | uuidcache_check_device(struct recursive_state *state UNUSED_PARAM, |
106 | struct stat *statbuf, | 106 | const char *device, |
107 | void *userData UNUSED_PARAM, | 107 | struct stat *statbuf) |
108 | int depth UNUSED_PARAM) | ||
109 | { | 108 | { |
110 | /* note: this check rejects links to devices, among other nodes */ | 109 | /* note: this check rejects links to devices, among other nodes */ |
111 | if (!S_ISBLK(statbuf->st_mode) | 110 | if (!S_ISBLK(statbuf->st_mode) |
@@ -145,12 +144,13 @@ uuidcache_init(int scan_devices) | |||
145 | * This is unacceptably complex. Let's just scan /dev. | 144 | * This is unacceptably complex. Let's just scan /dev. |
146 | * (Maybe add scanning of /sys/block/XXX/dev for devices | 145 | * (Maybe add scanning of /sys/block/XXX/dev for devices |
147 | * somehow not having their /dev/XXX entries created?) */ | 146 | * somehow not having their /dev/XXX entries created?) */ |
148 | if (scan_devices) | 147 | if (scan_devices) { |
149 | recursive_action("/dev", ACTION_RECURSE, | 148 | recursive_action("/dev", ACTION_RECURSE, |
150 | uuidcache_check_device, /* file_action */ | 149 | uuidcache_check_device, /* file_action */ |
151 | NULL, /* dir_action */ | 150 | NULL, /* dir_action */ |
152 | NULL, /* userData */ | 151 | NULL /* userData */ |
153 | 0 /* depth */); | 152 | ); |
153 | } | ||
154 | 154 | ||
155 | return uuidCache; | 155 | return uuidCache; |
156 | } | 156 | } |