diff options
author | Ron Yorston <rmy@pobox.com> | 2016-02-22 10:00:45 +0000 |
---|---|---|
committer | Ron Yorston <rmy@pobox.com> | 2016-02-22 10:00:45 +0000 |
commit | 371c20c008254a36e7157df6c13dc2e4cf87d6fd (patch) | |
tree | a214c03f6617dffa60df2192b312a46c93b7c19f | |
parent | ab879a41ab674129ef1593cda181cc8b64d0dadf (diff) | |
parent | 3a5cc989025eefe03fda0552b253a4a8f015a761 (diff) | |
download | busybox-w32-371c20c008254a36e7157df6c13dc2e4cf87d6fd.tar.gz busybox-w32-371c20c008254a36e7157df6c13dc2e4cf87d6fd.tar.bz2 busybox-w32-371c20c008254a36e7157df6c13dc2e4cf87d6fd.zip |
Merge branch 'busybox' into merge
33 files changed, 530 insertions, 140 deletions
@@ -724,6 +724,16 @@ config DEBUG_PESSIMIZE | |||
724 | in a much bigger executable that more closely matches the source | 724 | in a much bigger executable that more closely matches the source |
725 | code. | 725 | code. |
726 | 726 | ||
727 | config DEBUG_SANITIZE | ||
728 | bool "Enable runtime sanitizers (ASAN/LSAN/USAN/etc...)" | ||
729 | default n | ||
730 | help | ||
731 | Say Y here if you want to enable runtime sanitizers. These help | ||
732 | catch bad memory accesses (e.g. buffer overflows), but will make | ||
733 | the executable larger and slow down runtime a bit. | ||
734 | |||
735 | If you aren't developing/testing busybox, say N here. | ||
736 | |||
727 | config UNIT_TEST | 737 | config UNIT_TEST |
728 | bool "Build unit tests" | 738 | bool "Build unit tests" |
729 | default n | 739 | default n |
diff --git a/Makefile.flags b/Makefile.flags index c3ac5b458..28034cb07 100644 --- a/Makefile.flags +++ b/Makefile.flags | |||
@@ -76,6 +76,11 @@ else | |||
76 | CFLAGS += $(call cc-option,-Os,$(call cc-option,-O2,)) | 76 | CFLAGS += $(call cc-option,-Os,$(call cc-option,-O2,)) |
77 | endif | 77 | endif |
78 | endif | 78 | endif |
79 | ifeq ($(CONFIG_DEBUG_SANITIZE),y) | ||
80 | CFLAGS += $(call cc-option,-fsanitize=address,) | ||
81 | CFLAGS += $(call cc-option,-fsanitize=leak,) | ||
82 | CFLAGS += $(call cc-option,-fsanitize=undefined,) | ||
83 | endif | ||
79 | 84 | ||
80 | # If arch/$(ARCH)/Makefile did not override it (with, say, -fPIC)... | 85 | # If arch/$(ARCH)/Makefile did not override it (with, say, -fPIC)... |
81 | ARCH_FPIC ?= -fpic | 86 | ARCH_FPIC ?= -fpic |
diff --git a/coreutils/dd.c b/coreutils/dd.c index ccb91f69d..7bd3e2084 100644 --- a/coreutils/dd.c +++ b/coreutils/dd.c | |||
@@ -55,7 +55,7 @@ | |||
55 | 55 | ||
56 | //usage:#define dd_trivial_usage | 56 | //usage:#define dd_trivial_usage |
57 | //usage: "[if=FILE] [of=FILE] " IF_FEATURE_DD_IBS_OBS("[ibs=N] [obs=N] ") "[bs=N] [count=N] [skip=N]\n" | 57 | //usage: "[if=FILE] [of=FILE] " IF_FEATURE_DD_IBS_OBS("[ibs=N] [obs=N] ") "[bs=N] [count=N] [skip=N]\n" |
58 | //usage: " [seek=N]" IF_FEATURE_DD_IBS_OBS(" [conv=notrunc|noerror|sync|fsync]") | 58 | //usage: " [seek=N]" IF_FEATURE_DD_IBS_OBS(" [conv=notrunc|noerror|sync|fsync] [iflag=skip_bytes]") |
59 | //usage:#define dd_full_usage "\n\n" | 59 | //usage:#define dd_full_usage "\n\n" |
60 | //usage: "Copy a file with converting and formatting\n" | 60 | //usage: "Copy a file with converting and formatting\n" |
61 | //usage: "\n if=FILE Read from FILE instead of stdin" | 61 | //usage: "\n if=FILE Read from FILE instead of stdin" |
@@ -76,6 +76,7 @@ | |||
76 | //usage: "\n conv=sync Pad blocks with zeros" | 76 | //usage: "\n conv=sync Pad blocks with zeros" |
77 | //usage: "\n conv=fsync Physically write data out before finishing" | 77 | //usage: "\n conv=fsync Physically write data out before finishing" |
78 | //usage: "\n conv=swab Swap every pair of bytes" | 78 | //usage: "\n conv=swab Swap every pair of bytes" |
79 | //usage: "\n iflag=skip_bytes skip=N is in bytes" | ||
79 | //usage: ) | 80 | //usage: ) |
80 | //usage: IF_FEATURE_DD_STATUS( | 81 | //usage: IF_FEATURE_DD_STATUS( |
81 | //usage: "\n status=noxfer Suppress rate output" | 82 | //usage: "\n status=noxfer Suppress rate output" |
@@ -122,11 +123,15 @@ enum { | |||
122 | FLAG_FSYNC = (1 << 3) * ENABLE_FEATURE_DD_IBS_OBS, | 123 | FLAG_FSYNC = (1 << 3) * ENABLE_FEATURE_DD_IBS_OBS, |
123 | FLAG_SWAB = (1 << 4) * ENABLE_FEATURE_DD_IBS_OBS, | 124 | FLAG_SWAB = (1 << 4) * ENABLE_FEATURE_DD_IBS_OBS, |
124 | /* end of conv flags */ | 125 | /* end of conv flags */ |
125 | FLAG_TWOBUFS = (1 << 5) * ENABLE_FEATURE_DD_IBS_OBS, | 126 | /* start of input flags */ |
126 | FLAG_COUNT = 1 << 6, | 127 | FLAG_IFLAG_SHIFT = 5, |
127 | FLAG_STATUS = 1 << 7, | 128 | FLAG_SKIP_BYTES = (1 << 5) * ENABLE_FEATURE_DD_IBS_OBS, |
128 | FLAG_STATUS_NONE = 1 << 7, | 129 | /* end of input flags */ |
129 | FLAG_STATUS_NOXFER = 1 << 8, | 130 | FLAG_TWOBUFS = (1 << 6) * ENABLE_FEATURE_DD_IBS_OBS, |
131 | FLAG_COUNT = 1 << 7, | ||
132 | FLAG_STATUS = 1 << 8, | ||
133 | FLAG_STATUS_NONE = 1 << 9, | ||
134 | FLAG_STATUS_NOXFER = 1 << 10, | ||
130 | }; | 135 | }; |
131 | 136 | ||
132 | static void dd_output_status(int UNUSED_PARAM cur_signal) | 137 | static void dd_output_status(int UNUSED_PARAM cur_signal) |
@@ -203,18 +208,47 @@ static bool write_and_stats(const void *buf, size_t len, size_t obs, | |||
203 | # define XATOU_SFX xatoul_sfx | 208 | # define XATOU_SFX xatoul_sfx |
204 | #endif | 209 | #endif |
205 | 210 | ||
211 | #if ENABLE_FEATURE_DD_IBS_OBS | ||
212 | static int parse_comma_flags(char *val, const char *words, const char *error_in) | ||
213 | { | ||
214 | int flags = 0; | ||
215 | while (1) { | ||
216 | int n; | ||
217 | char *arg; | ||
218 | /* find ',', replace them with NUL so we can use val for | ||
219 | * index_in_strings() without copying. | ||
220 | * We rely on val being non-null, else strchr would fault. | ||
221 | */ | ||
222 | arg = strchr(val, ','); | ||
223 | if (arg) | ||
224 | *arg = '\0'; | ||
225 | n = index_in_strings(words, val); | ||
226 | if (n < 0) | ||
227 | bb_error_msg_and_die(bb_msg_invalid_arg_to, val, error_in); | ||
228 | flags |= (1 << n); | ||
229 | if (!arg) /* no ',' left, so this was the last specifier */ | ||
230 | break; | ||
231 | *arg = ','; /* to preserve ps listing */ | ||
232 | val = arg + 1; /* skip this keyword and ',' */ | ||
233 | } | ||
234 | return flags; | ||
235 | } | ||
236 | #endif | ||
237 | |||
206 | int dd_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; | 238 | int dd_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; |
207 | int dd_main(int argc UNUSED_PARAM, char **argv) | 239 | int dd_main(int argc UNUSED_PARAM, char **argv) |
208 | { | 240 | { |
209 | static const char keywords[] ALIGN1 = | 241 | static const char keywords[] ALIGN1 = |
210 | "bs\0""count\0""seek\0""skip\0""if\0""of\0"IF_FEATURE_DD_STATUS("status\0") | 242 | "bs\0""count\0""seek\0""skip\0""if\0""of\0"IF_FEATURE_DD_STATUS("status\0") |
211 | #if ENABLE_FEATURE_DD_IBS_OBS | 243 | #if ENABLE_FEATURE_DD_IBS_OBS |
212 | "ibs\0""obs\0""conv\0" | 244 | "ibs\0""obs\0""conv\0""iflag\0" |
213 | #endif | 245 | #endif |
214 | ; | 246 | ; |
215 | #if ENABLE_FEATURE_DD_IBS_OBS | 247 | #if ENABLE_FEATURE_DD_IBS_OBS |
216 | static const char conv_words[] ALIGN1 = | 248 | static const char conv_words[] ALIGN1 = |
217 | "notrunc\0""sync\0""noerror\0""fsync\0""swab\0"; | 249 | "notrunc\0""sync\0""noerror\0""fsync\0""swab\0"; |
250 | static const char iflag_words[] ALIGN1 = | ||
251 | "skip_bytes\0"; | ||
218 | #endif | 252 | #endif |
219 | #if ENABLE_FEATURE_DD_STATUS | 253 | #if ENABLE_FEATURE_DD_STATUS |
220 | static const char status_words[] ALIGN1 = | 254 | static const char status_words[] ALIGN1 = |
@@ -232,6 +266,7 @@ int dd_main(int argc UNUSED_PARAM, char **argv) | |||
232 | OP_ibs, | 266 | OP_ibs, |
233 | OP_obs, | 267 | OP_obs, |
234 | OP_conv, | 268 | OP_conv, |
269 | OP_iflag, | ||
235 | /* Must be in the same order as FLAG_XXX! */ | 270 | /* Must be in the same order as FLAG_XXX! */ |
236 | OP_conv_notrunc = 0, | 271 | OP_conv_notrunc = 0, |
237 | OP_conv_sync, | 272 | OP_conv_sync, |
@@ -251,6 +286,7 @@ int dd_main(int argc UNUSED_PARAM, char **argv) | |||
251 | //ibm from ASCII to alternate EBCDIC | 286 | //ibm from ASCII to alternate EBCDIC |
252 | /* Partially implemented: */ | 287 | /* Partially implemented: */ |
253 | //swab swap every pair of input bytes: will abort on non-even reads | 288 | //swab swap every pair of input bytes: will abort on non-even reads |
289 | OP_iflag_skip_bytes, | ||
254 | #endif | 290 | #endif |
255 | }; | 291 | }; |
256 | smallint exitcode = EXIT_FAILURE; | 292 | smallint exitcode = EXIT_FAILURE; |
@@ -316,24 +352,11 @@ int dd_main(int argc UNUSED_PARAM, char **argv) | |||
316 | /*continue;*/ | 352 | /*continue;*/ |
317 | } | 353 | } |
318 | if (what == OP_conv) { | 354 | if (what == OP_conv) { |
319 | while (1) { | 355 | G.flags |= parse_comma_flags(val, conv_words, "conv"); |
320 | int n; | 356 | /*continue;*/ |
321 | /* find ',', replace them with NUL so we can use val for | 357 | } |
322 | * index_in_strings() without copying. | 358 | if (what == OP_iflag) { |
323 | * We rely on val being non-null, else strchr would fault. | 359 | G.flags |= parse_comma_flags(val, iflag_words, "iflag") << FLAG_IFLAG_SHIFT; |
324 | */ | ||
325 | arg = strchr(val, ','); | ||
326 | if (arg) | ||
327 | *arg = '\0'; | ||
328 | n = index_in_strings(conv_words, val); | ||
329 | if (n < 0) | ||
330 | bb_error_msg_and_die(bb_msg_invalid_arg_to, val, "conv"); | ||
331 | G.flags |= (1 << n); | ||
332 | if (!arg) /* no ',' left, so this was the last specifier */ | ||
333 | break; | ||
334 | /* *arg = ','; - to preserve ps listing? */ | ||
335 | val = arg + 1; /* skip this keyword and ',' */ | ||
336 | } | ||
337 | /*continue;*/ | 360 | /*continue;*/ |
338 | } | 361 | } |
339 | #endif | 362 | #endif |
@@ -427,9 +450,10 @@ int dd_main(int argc UNUSED_PARAM, char **argv) | |||
427 | outfile = bb_msg_standard_output; | 450 | outfile = bb_msg_standard_output; |
428 | } | 451 | } |
429 | if (skip && !devzero) { | 452 | if (skip && !devzero) { |
430 | if (lseek(ifd, skip * ibs, SEEK_CUR) < 0) { | 453 | size_t blocksz = (G.flags & FLAG_SKIP_BYTES) ? 1 : ibs; |
454 | if (lseek(ifd, skip * blocksz, SEEK_CUR) < 0) { | ||
431 | do { | 455 | do { |
432 | ssize_t n = safe_read(ifd, ibuf, ibs); | 456 | ssize_t n = safe_read(ifd, ibuf, blocksz); |
433 | if (n < 0) | 457 | if (n < 0) |
434 | goto die_infile; | 458 | goto die_infile; |
435 | if (n == 0) | 459 | if (n == 0) |
diff --git a/coreutils/dos2unix.c b/coreutils/dos2unix.c index 07398bdfa..ccb74a113 100644 --- a/coreutils/dos2unix.c +++ b/coreutils/dos2unix.c | |||
@@ -41,7 +41,7 @@ enum { | |||
41 | static void convert(char *fn, int conv_type) | 41 | static void convert(char *fn, int conv_type) |
42 | { | 42 | { |
43 | FILE *in, *out; | 43 | FILE *in, *out; |
44 | int i; | 44 | int ch; |
45 | char *temp_fn = temp_fn; /* for compiler */ | 45 | char *temp_fn = temp_fn; /* for compiler */ |
46 | char *resolved_fn = resolved_fn; | 46 | char *resolved_fn = resolved_fn; |
47 | 47 | ||
@@ -49,28 +49,30 @@ static void convert(char *fn, int conv_type) | |||
49 | out = stdout; | 49 | out = stdout; |
50 | if (fn != NULL) { | 50 | if (fn != NULL) { |
51 | struct stat st; | 51 | struct stat st; |
52 | int fd; | ||
52 | 53 | ||
53 | resolved_fn = xmalloc_follow_symlinks(fn); | 54 | resolved_fn = xmalloc_follow_symlinks(fn); |
54 | if (resolved_fn == NULL) | 55 | if (resolved_fn == NULL) |
55 | bb_simple_perror_msg_and_die(fn); | 56 | bb_simple_perror_msg_and_die(fn); |
56 | in = xfopen_for_read(resolved_fn); | 57 | in = xfopen_for_read(resolved_fn); |
57 | fstat(fileno(in), &st); | 58 | xfstat(fileno(in), &st, resolved_fn); |
58 | 59 | ||
59 | temp_fn = xasprintf("%sXXXXXX", resolved_fn); | 60 | temp_fn = xasprintf("%sXXXXXX", resolved_fn); |
60 | i = xmkstemp(temp_fn); | 61 | fd = xmkstemp(temp_fn); |
61 | if (fchmod(i, st.st_mode) == -1) | 62 | if (fchmod(fd, st.st_mode) == -1) |
62 | bb_simple_perror_msg_and_die(temp_fn); | 63 | bb_simple_perror_msg_and_die(temp_fn); |
64 | fchown(fd, st.st_uid, st.st_gid); | ||
63 | 65 | ||
64 | out = xfdopen_for_write(i); | 66 | out = xfdopen_for_write(fd); |
65 | } | 67 | } |
66 | 68 | ||
67 | while ((i = fgetc(in)) != EOF) { | 69 | while ((ch = fgetc(in)) != EOF) { |
68 | if (i == '\r') | 70 | if (ch == '\r') |
69 | continue; | 71 | continue; |
70 | if (i == '\n') | 72 | if (ch == '\n') |
71 | if (conv_type == CT_UNIX2DOS) | 73 | if (conv_type == CT_UNIX2DOS) |
72 | fputc('\r', out); | 74 | fputc('\r', out); |
73 | fputc(i, out); | 75 | fputc(ch, out); |
74 | } | 76 | } |
75 | 77 | ||
76 | if (fn != NULL) { | 78 | if (fn != NULL) { |
diff --git a/coreutils/printf.c b/coreutils/printf.c index 3dd43a978..9ee7350d0 100644 --- a/coreutils/printf.c +++ b/coreutils/printf.c | |||
@@ -131,8 +131,8 @@ static double my_xstrtod(const char *arg) | |||
131 | return result; | 131 | return result; |
132 | } | 132 | } |
133 | 133 | ||
134 | /* Handles %b */ | 134 | /* Handles %b; return 1 if output is to be short-circuited by \c */ |
135 | static void print_esc_string(const char *str) | 135 | static int print_esc_string(const char *str) |
136 | { | 136 | { |
137 | char c; | 137 | char c; |
138 | while ((c = *str) != '\0') { | 138 | while ((c = *str) != '\0') { |
@@ -145,6 +145,9 @@ static void print_esc_string(const char *str) | |||
145 | str++; | 145 | str++; |
146 | } | 146 | } |
147 | } | 147 | } |
148 | else if (*str == 'c') { | ||
149 | return 1; | ||
150 | } | ||
148 | { | 151 | { |
149 | /* optimization: don't force arg to be on-stack, | 152 | /* optimization: don't force arg to be on-stack, |
150 | * use another variable for that. */ | 153 | * use another variable for that. */ |
@@ -155,6 +158,8 @@ static void print_esc_string(const char *str) | |||
155 | } | 158 | } |
156 | putchar(c); | 159 | putchar(c); |
157 | } | 160 | } |
161 | |||
162 | return 0; | ||
158 | } | 163 | } |
159 | 164 | ||
160 | static void print_direc(char *format, unsigned fmt_length, | 165 | static void print_direc(char *format, unsigned fmt_length, |
@@ -280,7 +285,8 @@ static char **print_formatted(char *f, char **argv, int *conv_err) | |||
280 | } | 285 | } |
281 | if (*f == 'b') { | 286 | if (*f == 'b') { |
282 | if (*argv) { | 287 | if (*argv) { |
283 | print_esc_string(*argv); | 288 | if (print_esc_string(*argv)) |
289 | return saved_argv; /* causes main() to exit */ | ||
284 | ++argv; | 290 | ++argv; |
285 | } | 291 | } |
286 | break; | 292 | break; |
diff --git a/coreutils/truncate.c b/coreutils/truncate.c index e5fa656c8..8d845f218 100644 --- a/coreutils/truncate.c +++ b/coreutils/truncate.c | |||
@@ -40,7 +40,7 @@ int truncate_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; | |||
40 | int truncate_main(int argc UNUSED_PARAM, char **argv) | 40 | int truncate_main(int argc UNUSED_PARAM, char **argv) |
41 | { | 41 | { |
42 | unsigned opts; | 42 | unsigned opts; |
43 | int flags = O_RDWR; | 43 | int flags = O_WRONLY | O_NONBLOCK; |
44 | int ret = EXIT_SUCCESS; | 44 | int ret = EXIT_SUCCESS; |
45 | char *size_str; | 45 | char *size_str; |
46 | off_t size; | 46 | off_t size; |
@@ -64,7 +64,7 @@ int truncate_main(int argc UNUSED_PARAM, char **argv) | |||
64 | 64 | ||
65 | argv += optind; | 65 | argv += optind; |
66 | while (*argv) { | 66 | while (*argv) { |
67 | int fd = open(*argv, flags); | 67 | int fd = open(*argv, flags, 0666); |
68 | if (fd < 0) { | 68 | if (fd < 0) { |
69 | if (errno != ENOENT || !(opts & OPT_NOCREATE)) { | 69 | if (errno != ENOENT || !(opts & OPT_NOCREATE)) { |
70 | bb_perror_msg("%s: open", *argv); | 70 | bb_perror_msg("%s: open", *argv); |
diff --git a/docs/posix_conformance.txt b/docs/posix_conformance.txt index 5b616d701..c0582dc23 100644 --- a/docs/posix_conformance.txt +++ b/docs/posix_conformance.txt | |||
@@ -178,6 +178,7 @@ dd POSIX options: | |||
178 | conv=noerror | yes | | | 178 | conv=noerror | yes | | |
179 | conv=notrunc | yes | | | 179 | conv=notrunc | yes | | |
180 | conv=sync | yes | | | 180 | conv=sync | yes | | |
181 | iflag=skip_bytes| yes | | | ||
181 | dd Busybox specific options: | 182 | dd Busybox specific options: |
182 | conv=fsync | 183 | conv=fsync |
183 | 184 | ||
diff --git a/editors/patch.c b/editors/patch.c index cb25e4140..988021d77 100644 --- a/editors/patch.c +++ b/editors/patch.c | |||
@@ -372,10 +372,6 @@ int patch_main(int argc UNUSED_PARAM, char **argv) | |||
372 | xmove_fd(xopen_stdin(argv[1]), STDIN_FILENO); | 372 | xmove_fd(xopen_stdin(argv[1]), STDIN_FILENO); |
373 | } | 373 | } |
374 | } | 374 | } |
375 | if (argv[0]) { | ||
376 | oldname = xstrdup(argv[0]); | ||
377 | newname = xstrdup(argv[0]); | ||
378 | } | ||
379 | 375 | ||
380 | // Loop through the lines in the patch | 376 | // Loop through the lines in the patch |
381 | for(;;) { | 377 | for(;;) { |
@@ -486,10 +482,10 @@ int patch_main(int argc UNUSED_PARAM, char **argv) | |||
486 | // or if new hunk is empty (zero context) after patching | 482 | // or if new hunk is empty (zero context) after patching |
487 | if (!strcmp(name, "/dev/null") || !(reverse ? oldsum : newsum)) { | 483 | if (!strcmp(name, "/dev/null") || !(reverse ? oldsum : newsum)) { |
488 | name = reverse ? newname : oldname; | 484 | name = reverse ? newname : oldname; |
489 | empty++; | 485 | empty = 1; |
490 | } | 486 | } |
491 | 487 | ||
492 | // handle -p path truncation. | 488 | // Handle -p path truncation. |
493 | for (i = 0, s = name; *s;) { | 489 | for (i = 0, s = name; *s;) { |
494 | if ((option_mask32 & FLAG_PATHLEN) && TT.prefix == i) | 490 | if ((option_mask32 & FLAG_PATHLEN) && TT.prefix == i) |
495 | break; | 491 | break; |
@@ -500,6 +496,9 @@ int patch_main(int argc UNUSED_PARAM, char **argv) | |||
500 | i++; | 496 | i++; |
501 | name = s; | 497 | name = s; |
502 | } | 498 | } |
499 | // If "patch FILE_TO_PATCH", completely ignore name from patch | ||
500 | if (argv[0]) | ||
501 | name = argv[0]; | ||
503 | 502 | ||
504 | if (empty) { | 503 | if (empty) { |
505 | // File is empty after the patches have been applied | 504 | // File is empty after the patches have been applied |
diff --git a/editors/sed.c b/editors/sed.c index a8c35388b..4c7f75521 100644 --- a/editors/sed.c +++ b/editors/sed.c | |||
@@ -113,7 +113,7 @@ typedef struct sed_cmd_s { | |||
113 | int end_line; /* 'sed 1,3p' 0 == one line only. -1 = last line ($). -2-N = +N */ | 113 | int end_line; /* 'sed 1,3p' 0 == one line only. -1 = last line ($). -2-N = +N */ |
114 | int end_line_orig; | 114 | int end_line_orig; |
115 | 115 | ||
116 | FILE *sw_file; /* File (sw) command writes to, -1 for none. */ | 116 | FILE *sw_file; /* File (sw) command writes to, NULL for none. */ |
117 | char *string; /* Data string for (saicytb) commands. */ | 117 | char *string; /* Data string for (saicytb) commands. */ |
118 | 118 | ||
119 | unsigned which_match; /* (s) Which match to replace (0 for all) */ | 119 | unsigned which_match; /* (s) Which match to replace (0 for all) */ |
@@ -179,7 +179,7 @@ static void sed_free_and_close_stuff(void) | |||
179 | sed_cmd_t *sed_cmd_next = sed_cmd->next; | 179 | sed_cmd_t *sed_cmd_next = sed_cmd->next; |
180 | 180 | ||
181 | if (sed_cmd->sw_file) | 181 | if (sed_cmd->sw_file) |
182 | xprint_and_close_file(sed_cmd->sw_file); | 182 | fclose(sed_cmd->sw_file); |
183 | 183 | ||
184 | if (sed_cmd->beg_match) { | 184 | if (sed_cmd->beg_match) { |
185 | regfree(sed_cmd->beg_match); | 185 | regfree(sed_cmd->beg_match); |
@@ -426,8 +426,11 @@ static int parse_subst_cmd(sed_cmd_t *sed_cmd, const char *substr) | |||
426 | /* Write to file */ | 426 | /* Write to file */ |
427 | case 'w': | 427 | case 'w': |
428 | { | 428 | { |
429 | char *temp; | 429 | char *fname; |
430 | idx += parse_file_cmd(/*sed_cmd,*/ substr+idx, &temp); | 430 | idx += parse_file_cmd(/*sed_cmd,*/ substr+idx+1, &fname); |
431 | sed_cmd->sw_file = xfopen_for_write(fname); | ||
432 | sed_cmd->sw_last_char = '\n'; | ||
433 | free(fname); | ||
431 | break; | 434 | break; |
432 | } | 435 | } |
433 | /* Ignore case (gnu exension) */ | 436 | /* Ignore case (gnu exension) */ |
diff --git a/include/libbb.h b/include/libbb.h index 7959884e3..cb61faad9 100644 --- a/include/libbb.h +++ b/include/libbb.h | |||
@@ -20,6 +20,7 @@ | |||
20 | #include <netdb.h> | 20 | #include <netdb.h> |
21 | #include <setjmp.h> | 21 | #include <setjmp.h> |
22 | #include <signal.h> | 22 | #include <signal.h> |
23 | #include <paths.h> | ||
23 | #if defined __UCLIBC__ /* TODO: and glibc? */ | 24 | #if defined __UCLIBC__ /* TODO: and glibc? */ |
24 | /* use inlined versions of these: */ | 25 | /* use inlined versions of these: */ |
25 | # define sigfillset(s) __sigfillset(s) | 26 | # define sigfillset(s) __sigfillset(s) |
@@ -106,7 +107,11 @@ | |||
106 | # define updwtmpx updwtmp | 107 | # define updwtmpx updwtmp |
107 | # define _PATH_UTMPX _PATH_UTMP | 108 | # define _PATH_UTMPX _PATH_UTMP |
108 | # else | 109 | # else |
110 | # include <utmp.h> | ||
109 | # include <utmpx.h> | 111 | # include <utmpx.h> |
112 | # if defined _PATH_UTMP && !defined _PATH_UTMPX | ||
113 | # define _PATH_UTMPX _PATH_UTMP | ||
114 | # endif | ||
110 | # endif | 115 | # endif |
111 | #endif | 116 | #endif |
112 | #if ENABLE_LOCALE_SUPPORT | 117 | #if ENABLE_LOCALE_SUPPORT |
diff --git a/include/platform.h b/include/platform.h index 1cbffc102..94368539e 100644 --- a/include/platform.h +++ b/include/platform.h | |||
@@ -517,9 +517,13 @@ typedef unsigned smalluint; | |||
517 | 517 | ||
518 | #if defined(ANDROID) || defined(__ANDROID__) | 518 | #if defined(ANDROID) || defined(__ANDROID__) |
519 | # if __ANDROID_API__ < 8 | 519 | # if __ANDROID_API__ < 8 |
520 | /* ANDROID < 8 has no [f]dprintf at all */ | ||
520 | # undef HAVE_DPRINTF | 521 | # undef HAVE_DPRINTF |
521 | # else | 522 | # elif __ANDROID_API__ < 21 |
523 | /* ANDROID < 21 has fdprintf */ | ||
522 | # define dprintf fdprintf | 524 | # define dprintf fdprintf |
525 | # else | ||
526 | /* ANDROID >= 21 has standard dprintf */ | ||
523 | # endif | 527 | # endif |
524 | # if __ANDROID_API__ < 21 | 528 | # if __ANDROID_API__ < 21 |
525 | # undef HAVE_TTYNAME_R | 529 | # undef HAVE_TTYNAME_R |
diff --git a/init/init.c b/init/init.c index 80c5d0f74..25bfaec8c 100644 --- a/init/init.c +++ b/init/init.c | |||
@@ -102,6 +102,21 @@ | |||
102 | //config: | 102 | //config: |
103 | //config: Note that on Linux, init attempts to detect serial terminal and | 103 | //config: Note that on Linux, init attempts to detect serial terminal and |
104 | //config: sets TERM to "vt102" if one is found. | 104 | //config: sets TERM to "vt102" if one is found. |
105 | //config: | ||
106 | //config:config FEATURE_INIT_MODIFY_CMDLINE | ||
107 | //config: bool "Modify the command-line to \"init\"" | ||
108 | //config: default y | ||
109 | //config: depends on INIT | ||
110 | //config: help | ||
111 | //config: When launched as PID 1 and after parsing its arguments, init | ||
112 | //config: wipes all the arguments but argv[0] and rewrites argv[0] to | ||
113 | //config: contain only "init", so that its command-line appears solely as | ||
114 | //config: "init" in tools such as ps. | ||
115 | //config: If this option is set to Y, init will keep its original behavior, | ||
116 | //config: otherwise, all the arguments including argv[0] will be preserved, | ||
117 | //config: be they parsed or ignored by init. | ||
118 | //config: The original command-line used to launch init can then be | ||
119 | //config: retrieved in /proc/1/cmdline on Linux, for example. | ||
105 | 120 | ||
106 | //applet:IF_INIT(APPLET(init, BB_DIR_SBIN, BB_SUID_DROP)) | 121 | //applet:IF_INIT(APPLET(init, BB_DIR_SBIN, BB_SUID_DROP)) |
107 | //applet:IF_FEATURE_INITRD(APPLET_ODDNAME(linuxrc, init, BB_DIR_ROOT, BB_SUID_DROP, linuxrc)) | 122 | //applet:IF_FEATURE_INITRD(APPLET_ODDNAME(linuxrc, init, BB_DIR_ROOT, BB_SUID_DROP, linuxrc)) |
@@ -112,7 +127,6 @@ | |||
112 | 127 | ||
113 | #include "libbb.h" | 128 | #include "libbb.h" |
114 | #include <syslog.h> | 129 | #include <syslog.h> |
115 | #include <paths.h> | ||
116 | #include <sys/resource.h> | 130 | #include <sys/resource.h> |
117 | #ifdef __linux__ | 131 | #ifdef __linux__ |
118 | # include <linux/vt.h> | 132 | # include <linux/vt.h> |
@@ -1139,11 +1153,13 @@ int init_main(int argc UNUSED_PARAM, char **argv) | |||
1139 | } | 1153 | } |
1140 | #endif | 1154 | #endif |
1141 | 1155 | ||
1142 | /* Make the command line just say "init" - thats all, nothing else */ | 1156 | if (ENABLE_FEATURE_INIT_MODIFY_CMDLINE) { |
1143 | strncpy(argv[0], "init", strlen(argv[0])); | 1157 | /* Make the command line just say "init" - that's all, nothing else */ |
1144 | /* Wipe argv[1]-argv[N] so they don't clutter the ps listing */ | 1158 | strncpy(argv[0], "init", strlen(argv[0])); |
1145 | while (*++argv) | 1159 | /* Wipe argv[1]-argv[N] so they don't clutter the ps listing */ |
1146 | nuke_str(*argv); | 1160 | while (*++argv) |
1161 | nuke_str(*argv); | ||
1162 | } | ||
1147 | 1163 | ||
1148 | /* Set up signal handlers */ | 1164 | /* Set up signal handlers */ |
1149 | if (!DEBUG_INIT) { | 1165 | if (!DEBUG_INIT) { |
diff --git a/libbb/missing_syscalls.c b/libbb/missing_syscalls.c index e3c1e924b..093412811 100644 --- a/libbb/missing_syscalls.c +++ b/libbb/missing_syscalls.c | |||
@@ -40,8 +40,10 @@ int pivot_root(const char *new_root, const char *put_old) | |||
40 | return syscall(__NR_pivot_root, new_root, put_old); | 40 | return syscall(__NR_pivot_root, new_root, put_old); |
41 | } | 41 | } |
42 | 42 | ||
43 | # if __ANDROID_API__ < 21 | ||
43 | int tcdrain(int fd) | 44 | int tcdrain(int fd) |
44 | { | 45 | { |
45 | return ioctl(fd, TCSBRK, 1); | 46 | return ioctl(fd, TCSBRK, 1); |
46 | } | 47 | } |
48 | # endif | ||
47 | #endif | 49 | #endif |
diff --git a/libbb/pw_encrypt.c b/libbb/pw_encrypt.c index bfc7030a8..dbc15e5fc 100644 --- a/libbb/pw_encrypt.c +++ b/libbb/pw_encrypt.c | |||
@@ -52,14 +52,18 @@ char* FAST_FUNC crypt_make_pw_salt(char salt[MAX_PW_SALT_LEN], const char *algo) | |||
52 | { | 52 | { |
53 | int len = 2/2; | 53 | int len = 2/2; |
54 | char *salt_ptr = salt; | 54 | char *salt_ptr = salt; |
55 | if (algo[0] != 'd') { /* not des */ | 55 | |
56 | /* Standard chpasswd uses uppercase algos ("MD5", not "md5"). | ||
57 | * Need to be case-insensitive in the code below. | ||
58 | */ | ||
59 | if ((algo[0]|0x20) != 'd') { /* not des */ | ||
56 | len = 8/2; /* so far assuming md5 */ | 60 | len = 8/2; /* so far assuming md5 */ |
57 | *salt_ptr++ = '$'; | 61 | *salt_ptr++ = '$'; |
58 | *salt_ptr++ = '1'; | 62 | *salt_ptr++ = '1'; |
59 | *salt_ptr++ = '$'; | 63 | *salt_ptr++ = '$'; |
60 | #if !ENABLE_USE_BB_CRYPT || ENABLE_USE_BB_CRYPT_SHA | 64 | #if !ENABLE_USE_BB_CRYPT || ENABLE_USE_BB_CRYPT_SHA |
61 | if (algo[0] == 's') { /* sha */ | 65 | if ((algo[0]|0x20) == 's') { /* sha */ |
62 | salt[1] = '5' + (strcmp(algo, "sha512") == 0); | 66 | salt[1] = '5' + (strcasecmp(algo, "sha512") == 0); |
63 | len = 16/2; | 67 | len = 16/2; |
64 | } | 68 | } |
65 | #endif | 69 | #endif |
diff --git a/loginutils/chpasswd.c b/loginutils/chpasswd.c index 6c41d17be..a022a42d6 100644 --- a/loginutils/chpasswd.c +++ b/loginutils/chpasswd.c | |||
@@ -24,26 +24,27 @@ | |||
24 | //kbuild:lib-$(CONFIG_CHPASSWD) += chpasswd.o | 24 | //kbuild:lib-$(CONFIG_CHPASSWD) += chpasswd.o |
25 | 25 | ||
26 | //usage:#define chpasswd_trivial_usage | 26 | //usage:#define chpasswd_trivial_usage |
27 | //usage: IF_LONG_OPTS("[--md5|--encrypted]") IF_NOT_LONG_OPTS("[-m|-e]") | 27 | //usage: IF_LONG_OPTS("[--md5|--encrypted|--crypt-method]") IF_NOT_LONG_OPTS("[-m|-e|-c]") |
28 | //usage:#define chpasswd_full_usage "\n\n" | 28 | //usage:#define chpasswd_full_usage "\n\n" |
29 | //usage: "Read user:password from stdin and update /etc/passwd\n" | 29 | //usage: "Read user:password from stdin and update /etc/passwd\n" |
30 | //usage: IF_LONG_OPTS( | 30 | //usage: IF_LONG_OPTS( |
31 | //usage: "\n -e,--encrypted Supplied passwords are in encrypted form" | 31 | //usage: "\n -e,--encrypted Supplied passwords are in encrypted form" |
32 | //usage: "\n -m,--md5 Use MD5 encryption instead of DES" | 32 | //usage: "\n -m,--md5 Use MD5 encryption instead of DES" |
33 | //usage: "\n -c,--crypt-method Use the specified method to encrypt the passwords" | ||
33 | //usage: ) | 34 | //usage: ) |
34 | //usage: IF_NOT_LONG_OPTS( | 35 | //usage: IF_NOT_LONG_OPTS( |
35 | //usage: "\n -e Supplied passwords are in encrypted form" | 36 | //usage: "\n -e Supplied passwords are in encrypted form" |
36 | //usage: "\n -m Use MD5 encryption instead of DES" | 37 | //usage: "\n -m Use MD5 encryption instead of DES" |
38 | //usage: "\n -c Use the specified method to encrypt the passwords" | ||
37 | //usage: ) | 39 | //usage: ) |
38 | 40 | ||
39 | //TODO: implement -c ALGO | ||
40 | |||
41 | #include "libbb.h" | 41 | #include "libbb.h" |
42 | 42 | ||
43 | #if ENABLE_LONG_OPTS | 43 | #if ENABLE_LONG_OPTS |
44 | static const char chpasswd_longopts[] ALIGN1 = | 44 | static const char chpasswd_longopts[] ALIGN1 = |
45 | "encrypted\0" No_argument "e" | 45 | "encrypted\0" No_argument "e" |
46 | "md5\0" No_argument "m" | 46 | "md5\0" No_argument "m" |
47 | "crypt-method\0" Required_argument "c" | ||
47 | ; | 48 | ; |
48 | #endif | 49 | #endif |
49 | 50 | ||
@@ -54,14 +55,15 @@ int chpasswd_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; | |||
54 | int chpasswd_main(int argc UNUSED_PARAM, char **argv) | 55 | int chpasswd_main(int argc UNUSED_PARAM, char **argv) |
55 | { | 56 | { |
56 | char *name; | 57 | char *name; |
58 | const char *algo = CONFIG_FEATURE_DEFAULT_PASSWD_ALGO; | ||
57 | int opt; | 59 | int opt; |
58 | 60 | ||
59 | if (getuid() != 0) | 61 | if (getuid() != 0) |
60 | bb_error_msg_and_die(bb_msg_perm_denied_are_you_root); | 62 | bb_error_msg_and_die(bb_msg_perm_denied_are_you_root); |
61 | 63 | ||
62 | opt_complementary = "m--e:e--m"; | 64 | opt_complementary = "m--ec:e--mc:c--em"; |
63 | IF_LONG_OPTS(applet_long_options = chpasswd_longopts;) | 65 | IF_LONG_OPTS(applet_long_options = chpasswd_longopts;) |
64 | opt = getopt32(argv, "em"); | 66 | opt = getopt32(argv, "emc:", &algo); |
65 | 67 | ||
66 | while ((name = xmalloc_fgetline(stdin)) != NULL) { | 68 | while ((name = xmalloc_fgetline(stdin)) != NULL) { |
67 | char *free_me; | 69 | char *free_me; |
@@ -77,15 +79,14 @@ int chpasswd_main(int argc UNUSED_PARAM, char **argv) | |||
77 | 79 | ||
78 | free_me = NULL; | 80 | free_me = NULL; |
79 | if (!(opt & OPT_ENC)) { | 81 | if (!(opt & OPT_ENC)) { |
80 | char salt[sizeof("$N$XXXXXXXX")]; | 82 | char salt[MAX_PW_SALT_LEN]; |
81 | 83 | ||
82 | crypt_make_salt(salt, 1); | ||
83 | if (opt & OPT_MD5) { | 84 | if (opt & OPT_MD5) { |
84 | salt[0] = '$'; | 85 | /* Force MD5 if the -m flag is set */ |
85 | salt[1] = '1'; | 86 | algo = "md5"; |
86 | salt[2] = '$'; | ||
87 | crypt_make_salt(salt + 3, 4); | ||
88 | } | 87 | } |
88 | |||
89 | crypt_make_pw_salt(salt, algo); | ||
89 | free_me = pass = pw_encrypt(pass, salt, 0); | 90 | free_me = pass = pw_encrypt(pass, salt, 0); |
90 | } | 91 | } |
91 | 92 | ||
diff --git a/loginutils/login.c b/loginutils/login.c index 67fe82e86..4ebc18502 100644 --- a/loginutils/login.c +++ b/loginutils/login.c | |||
@@ -78,6 +78,49 @@ | |||
78 | * Apparently they like to confuse people. */ | 78 | * Apparently they like to confuse people. */ |
79 | # include <security/pam_appl.h> | 79 | # include <security/pam_appl.h> |
80 | # include <security/pam_misc.h> | 80 | # include <security/pam_misc.h> |
81 | |||
82 | # if 0 | ||
83 | /* This supposedly can be used to avoid double password prompt, | ||
84 | * if used instead of standard misc_conv(): | ||
85 | * | ||
86 | * "When we want to authenticate first with local method and then with tacacs for example, | ||
87 | * the password is asked for local method and if not good is asked a second time for tacacs. | ||
88 | * So if we want to authenticate a user with tacacs, and the user exists localy, the password is | ||
89 | * asked two times before authentication is accepted." | ||
90 | * | ||
91 | * However, code looks shaky. For example, why misc_conv() return value is ignored? | ||
92 | * Are msg[i] and resp[i] indexes handled correctly? | ||
93 | */ | ||
94 | static char *passwd = NULL; | ||
95 | static int my_conv(int num_msg, const struct pam_message **msg, | ||
96 | struct pam_response **resp, void *data) | ||
97 | { | ||
98 | int i; | ||
99 | for (i = 0; i < num_msg; i++) { | ||
100 | switch (msg[i]->msg_style) { | ||
101 | case PAM_PROMPT_ECHO_OFF: | ||
102 | if (passwd == NULL) { | ||
103 | misc_conv(num_msg, msg, resp, data); | ||
104 | passwd = xstrdup(resp[i]->resp); | ||
105 | return PAM_SUCCESS; | ||
106 | } | ||
107 | |||
108 | resp[0] = xzalloc(sizeof(struct pam_response)); | ||
109 | resp[0]->resp = passwd; | ||
110 | passwd = NULL; | ||
111 | resp[0]->resp_retcode = PAM_SUCCESS; | ||
112 | resp[1] = NULL; | ||
113 | return PAM_SUCCESS; | ||
114 | |||
115 | default: | ||
116 | break; | ||
117 | } | ||
118 | } | ||
119 | |||
120 | return PAM_SUCCESS; | ||
121 | } | ||
122 | # endif | ||
123 | |||
81 | static const struct pam_conv conv = { | 124 | static const struct pam_conv conv = { |
82 | misc_conv, | 125 | misc_conv, |
83 | NULL | 126 | NULL |
diff --git a/miscutils/nandwrite.c b/miscutils/nandwrite.c index 247fc72f4..c95cbb21e 100644 --- a/miscutils/nandwrite.c +++ b/miscutils/nandwrite.c | |||
@@ -29,16 +29,18 @@ | |||
29 | //kbuild:lib-$(CONFIG_NANDDUMP) += nandwrite.o | 29 | //kbuild:lib-$(CONFIG_NANDDUMP) += nandwrite.o |
30 | 30 | ||
31 | //usage:#define nandwrite_trivial_usage | 31 | //usage:#define nandwrite_trivial_usage |
32 | //usage: "[-p] [-s ADDR] MTD_DEVICE [FILE]" | 32 | //usage: "[-np] [-s ADDR] MTD_DEVICE [FILE]" |
33 | //usage:#define nandwrite_full_usage "\n\n" | 33 | //usage:#define nandwrite_full_usage "\n\n" |
34 | //usage: "Write to MTD_DEVICE\n" | 34 | //usage: "Write to MTD_DEVICE\n" |
35 | //usage: "\n -n Write without ecc" | ||
35 | //usage: "\n -p Pad to page size" | 36 | //usage: "\n -p Pad to page size" |
36 | //usage: "\n -s ADDR Start address" | 37 | //usage: "\n -s ADDR Start address" |
37 | 38 | ||
38 | //usage:#define nanddump_trivial_usage | 39 | //usage:#define nanddump_trivial_usage |
39 | //usage: "[-o]" IF_LONG_OPTS(" [--bb=padbad|skipbad]") " [-s ADDR] [-l LEN] [-f FILE] MTD_DEVICE" | 40 | //usage: "[-no]" IF_LONG_OPTS(" [--bb=padbad|skipbad]") " [-s ADDR] [-l LEN] [-f FILE] MTD_DEVICE" |
40 | //usage:#define nanddump_full_usage "\n\n" | 41 | //usage:#define nanddump_full_usage "\n\n" |
41 | //usage: "Dump MTD_DEVICE\n" | 42 | //usage: "Dump MTD_DEVICE\n" |
43 | //usage: "\n -n Read without ecc" | ||
42 | //usage: "\n -o Dump oob data" | 44 | //usage: "\n -o Dump oob data" |
43 | //usage: "\n -s ADDR Start address" | 45 | //usage: "\n -s ADDR Start address" |
44 | //usage: "\n -l LEN Length" | 46 | //usage: "\n -l LEN Length" |
@@ -57,10 +59,11 @@ | |||
57 | 59 | ||
58 | #define OPT_p (1 << 0) /* nandwrite only */ | 60 | #define OPT_p (1 << 0) /* nandwrite only */ |
59 | #define OPT_o (1 << 0) /* nanddump only */ | 61 | #define OPT_o (1 << 0) /* nanddump only */ |
60 | #define OPT_s (1 << 1) | 62 | #define OPT_n (1 << 1) |
61 | #define OPT_f (1 << 2) | 63 | #define OPT_s (1 << 2) |
62 | #define OPT_l (1 << 3) | 64 | #define OPT_f (1 << 3) |
63 | #define OPT_bb (1 << 4) /* must be the last one in the list */ | 65 | #define OPT_l (1 << 4) |
66 | #define OPT_bb (1 << 5) /* must be the last one in the list */ | ||
64 | 67 | ||
65 | #define BB_PADBAD (1 << 0) | 68 | #define BB_PADBAD (1 << 0) |
66 | #define BB_SKIPBAD (1 << 1) | 69 | #define BB_SKIPBAD (1 << 1) |
@@ -125,10 +128,10 @@ int nandwrite_main(int argc UNUSED_PARAM, char **argv) | |||
125 | applet_long_options = | 128 | applet_long_options = |
126 | "bb\0" Required_argument "\xff"; /* no short equivalent */ | 129 | "bb\0" Required_argument "\xff"; /* no short equivalent */ |
127 | #endif | 130 | #endif |
128 | opts = getopt32(argv, "os:f:l:", &opt_s, &opt_f, &opt_l, &opt_bb); | 131 | opts = getopt32(argv, "ons:f:l:", &opt_s, &opt_f, &opt_l, &opt_bb); |
129 | } else { /* nandwrite */ | 132 | } else { /* nandwrite */ |
130 | opt_complementary = "-1:?2"; | 133 | opt_complementary = "-1:?2"; |
131 | opts = getopt32(argv, "ps:", &opt_s); | 134 | opts = getopt32(argv, "pns:", &opt_s); |
132 | } | 135 | } |
133 | argv += optind; | 136 | argv += optind; |
134 | 137 | ||
@@ -144,6 +147,9 @@ int nandwrite_main(int argc UNUSED_PARAM, char **argv) | |||
144 | fd = xopen(argv[0], IS_NANDWRITE ? O_RDWR : O_RDONLY); | 147 | fd = xopen(argv[0], IS_NANDWRITE ? O_RDWR : O_RDONLY); |
145 | xioctl(fd, MEMGETINFO, &meminfo); | 148 | xioctl(fd, MEMGETINFO, &meminfo); |
146 | 149 | ||
150 | if (opts & OPT_n) | ||
151 | xioctl(fd, MTDFILEMODE, (void *)MTD_FILE_MODE_RAW); | ||
152 | |||
147 | mtdoffset = xstrtou(opt_s, 0); | 153 | mtdoffset = xstrtou(opt_s, 0); |
148 | if (IS_NANDDUMP && (opts & OPT_l)) { | 154 | if (IS_NANDDUMP && (opts & OPT_l)) { |
149 | unsigned length = xstrtou(opt_l, 0); | 155 | unsigned length = xstrtou(opt_l, 0); |
diff --git a/miscutils/setsid.c b/miscutils/setsid.c index 637081b6c..1b27377b2 100644 --- a/miscutils/setsid.c +++ b/miscutils/setsid.c | |||
@@ -15,19 +15,22 @@ | |||
15 | */ | 15 | */ |
16 | 16 | ||
17 | //usage:#define setsid_trivial_usage | 17 | //usage:#define setsid_trivial_usage |
18 | //usage: "PROG ARGS" | 18 | //usage: "[-c] PROG ARGS" |
19 | //usage:#define setsid_full_usage "\n\n" | 19 | //usage:#define setsid_full_usage "\n\n" |
20 | //usage: "Run PROG in a new session. PROG will have no controlling terminal\n" | 20 | //usage: "Run PROG in a new session. PROG will have no controlling terminal\n" |
21 | //usage: "and will not be affected by keyboard signals (Ctrl-C etc).\n" | 21 | //usage: "and will not be affected by keyboard signals (^C etc).\n" |
22 | //usage: "See setsid(2) for details." | 22 | //usage: "\n -c Set controlling terminal to stdin" |
23 | 23 | ||
24 | #include "libbb.h" | 24 | #include "libbb.h" |
25 | 25 | ||
26 | int setsid_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; | 26 | int setsid_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; |
27 | int setsid_main(int argc UNUSED_PARAM, char **argv) | 27 | int setsid_main(int argc UNUSED_PARAM, char **argv) |
28 | { | 28 | { |
29 | if (!argv[1]) | 29 | unsigned opt; |
30 | bb_show_usage(); | 30 | |
31 | opt_complementary = "-1"; /* at least one arg */ | ||
32 | opt = getopt32(argv, "c"); | ||
33 | argv += optind; | ||
31 | 34 | ||
32 | /* setsid() is allowed only when we are not a process group leader. | 35 | /* setsid() is allowed only when we are not a process group leader. |
33 | * Otherwise our PID serves as PGID of some existing process group | 36 | * Otherwise our PID serves as PGID of some existing process group |
@@ -61,6 +64,10 @@ int setsid_main(int argc UNUSED_PARAM, char **argv) | |||
61 | setsid(); | 64 | setsid(); |
62 | } | 65 | } |
63 | 66 | ||
64 | argv++; | 67 | if (opt) { |
68 | /* -c: set (with stealing) controlling tty */ | ||
69 | ioctl(0, TIOCSCTTY, 1); | ||
70 | } | ||
71 | |||
65 | BB_EXECVP_or_die(argv); | 72 | BB_EXECVP_or_die(argv); |
66 | } | 73 | } |
diff --git a/modutils/modprobe.c b/modutils/modprobe.c index ec490b74d..997ee3c67 100644 --- a/modutils/modprobe.c +++ b/modutils/modprobe.c | |||
@@ -220,8 +220,16 @@ static int FAST_FUNC config_file_action(const char *filename, | |||
220 | parser_t *p; | 220 | parser_t *p; |
221 | struct module_entry *m; | 221 | struct module_entry *m; |
222 | int rc = TRUE; | 222 | int rc = TRUE; |
223 | const char *base, *ext; | ||
223 | 224 | ||
224 | if (bb_basename(filename)[0] == '.') | 225 | /* Skip files that begin with a ".". */ |
226 | base = bb_basename(filename); | ||
227 | if (base[0] == '.') | ||
228 | goto error; | ||
229 | |||
230 | /* Skip files that do not end with a ".conf". */ | ||
231 | ext = strrchr(base, '.'); | ||
232 | if (ext == NULL || strcmp(ext + 1, "conf")) | ||
225 | goto error; | 233 | goto error; |
226 | 234 | ||
227 | p = config_open2(filename, fopen_for_read); | 235 | p = config_open2(filename, fopen_for_read); |
diff --git a/networking/interface.c b/networking/interface.c index 24bd13c57..e5723b428 100644 --- a/networking/interface.c +++ b/networking/interface.c | |||
@@ -881,6 +881,7 @@ static void ife_print6(struct interface *ptr) | |||
881 | sprintf(addr6, "%s:%s:%s:%s:%s:%s:%s:%s", | 881 | sprintf(addr6, "%s:%s:%s:%s:%s:%s:%s:%s", |
882 | addr6p[0], addr6p[1], addr6p[2], addr6p[3], | 882 | addr6p[0], addr6p[1], addr6p[2], addr6p[3], |
883 | addr6p[4], addr6p[5], addr6p[6], addr6p[7]); | 883 | addr6p[4], addr6p[5], addr6p[6], addr6p[7]); |
884 | memset(&sap, 0, sizeof(sap)); | ||
884 | inet_pton(AF_INET6, addr6, | 885 | inet_pton(AF_INET6, addr6, |
885 | (struct sockaddr *) &sap.sin6_addr); | 886 | (struct sockaddr *) &sap.sin6_addr); |
886 | sap.sin6_family = AF_INET6; | 887 | sap.sin6_family = AF_INET6; |
diff --git a/networking/libiproute/iproute.c b/networking/libiproute/iproute.c index d232ee6fd..82827488f 100644 --- a/networking/libiproute/iproute.c +++ b/networking/libiproute/iproute.c | |||
@@ -313,12 +313,13 @@ static int FAST_FUNC print_route(const struct sockaddr_nl *who UNUSED_PARAM, | |||
313 | static int iproute_modify(int cmd, unsigned flags, char **argv) | 313 | static int iproute_modify(int cmd, unsigned flags, char **argv) |
314 | { | 314 | { |
315 | static const char keywords[] ALIGN1 = | 315 | static const char keywords[] ALIGN1 = |
316 | "src\0""via\0""mtu\0""lock\0""protocol\0"IF_FEATURE_IP_RULE("table\0") | 316 | "src\0""via\0""mtu\0""lock\0""scope\0""protocol\0"IF_FEATURE_IP_RULE("table\0") |
317 | "dev\0""oif\0""to\0""metric\0""onlink\0"; | 317 | "dev\0""oif\0""to\0""metric\0""onlink\0"; |
318 | enum { | 318 | enum { |
319 | ARG_src, | 319 | ARG_src, |
320 | ARG_via, | 320 | ARG_via, |
321 | ARG_mtu, PARM_lock, | 321 | ARG_mtu, PARM_lock, |
322 | ARG_scope, | ||
322 | ARG_protocol, | 323 | ARG_protocol, |
323 | IF_FEATURE_IP_RULE(ARG_table,) | 324 | IF_FEATURE_IP_RULE(ARG_table,) |
324 | ARG_dev, | 325 | ARG_dev, |
@@ -344,6 +345,7 @@ IF_FEATURE_IP_RULE(ARG_table,) | |||
344 | unsigned mxlock = 0; | 345 | unsigned mxlock = 0; |
345 | char *d = NULL; | 346 | char *d = NULL; |
346 | smalluint ok = 0; | 347 | smalluint ok = 0; |
348 | smalluint scope_ok = 0; | ||
347 | int arg; | 349 | int arg; |
348 | 350 | ||
349 | memset(&req, 0, sizeof(req)); | 351 | memset(&req, 0, sizeof(req)); |
@@ -352,15 +354,18 @@ IF_FEATURE_IP_RULE(ARG_table,) | |||
352 | req.n.nlmsg_flags = NLM_F_REQUEST | flags; | 354 | req.n.nlmsg_flags = NLM_F_REQUEST | flags; |
353 | req.n.nlmsg_type = cmd; | 355 | req.n.nlmsg_type = cmd; |
354 | req.r.rtm_family = preferred_family; | 356 | req.r.rtm_family = preferred_family; |
355 | if (RT_TABLE_MAIN) /* if it is zero, memset already did it */ | 357 | if (RT_TABLE_MAIN != 0) /* if it is zero, memset already did it */ |
356 | req.r.rtm_table = RT_TABLE_MAIN; | 358 | req.r.rtm_table = RT_TABLE_MAIN; |
357 | if (RT_SCOPE_NOWHERE) | 359 | if (RT_SCOPE_NOWHERE != 0) |
358 | req.r.rtm_scope = RT_SCOPE_NOWHERE; | 360 | req.r.rtm_scope = RT_SCOPE_NOWHERE; |
359 | 361 | ||
360 | if (cmd != RTM_DELROUTE) { | 362 | if (cmd != RTM_DELROUTE) { |
361 | req.r.rtm_protocol = RTPROT_BOOT; | 363 | if (RTPROT_BOOT != 0) |
362 | req.r.rtm_scope = RT_SCOPE_UNIVERSE; | 364 | req.r.rtm_protocol = RTPROT_BOOT; |
363 | req.r.rtm_type = RTN_UNICAST; | 365 | if (RT_SCOPE_UNIVERSE != 0) |
366 | req.r.rtm_scope = RT_SCOPE_UNIVERSE; | ||
367 | if (RTN_UNICAST != 0) | ||
368 | req.r.rtm_type = RTN_UNICAST; | ||
364 | } | 369 | } |
365 | 370 | ||
366 | mxrta->rta_type = RTA_METRICS; | 371 | mxrta->rta_type = RTA_METRICS; |
@@ -393,6 +398,13 @@ IF_FEATURE_IP_RULE(ARG_table,) | |||
393 | } | 398 | } |
394 | mtu = get_unsigned(*argv, "mtu"); | 399 | mtu = get_unsigned(*argv, "mtu"); |
395 | rta_addattr32(mxrta, sizeof(mxbuf), RTAX_MTU, mtu); | 400 | rta_addattr32(mxrta, sizeof(mxbuf), RTAX_MTU, mtu); |
401 | } else if (arg == ARG_scope) { | ||
402 | uint32_t scope; | ||
403 | NEXT_ARG(); | ||
404 | if (rtnl_rtscope_a2n(&scope, *argv)) | ||
405 | invarg_1_to_2(*argv, "scope"); | ||
406 | req.r.rtm_scope = scope; | ||
407 | scope_ok = 1; | ||
396 | } else if (arg == ARG_protocol) { | 408 | } else if (arg == ARG_protocol) { |
397 | uint32_t prot; | 409 | uint32_t prot; |
398 | NEXT_ARG(); | 410 | NEXT_ARG(); |
@@ -469,20 +481,22 @@ IF_FEATURE_IP_RULE(ARG_table,) | |||
469 | addattr_l(&req.n, sizeof(req), RTA_METRICS, RTA_DATA(mxrta), RTA_PAYLOAD(mxrta)); | 481 | addattr_l(&req.n, sizeof(req), RTA_METRICS, RTA_DATA(mxrta), RTA_PAYLOAD(mxrta)); |
470 | } | 482 | } |
471 | 483 | ||
472 | if (req.r.rtm_type == RTN_LOCAL || req.r.rtm_type == RTN_NAT) | 484 | if (!scope_ok) { |
473 | req.r.rtm_scope = RT_SCOPE_HOST; | 485 | if (req.r.rtm_type == RTN_LOCAL || req.r.rtm_type == RTN_NAT) |
474 | else | 486 | req.r.rtm_scope = RT_SCOPE_HOST; |
475 | if (req.r.rtm_type == RTN_BROADCAST | 487 | else |
476 | || req.r.rtm_type == RTN_MULTICAST | 488 | if (req.r.rtm_type == RTN_BROADCAST |
477 | || req.r.rtm_type == RTN_ANYCAST | 489 | || req.r.rtm_type == RTN_MULTICAST |
478 | ) { | 490 | || req.r.rtm_type == RTN_ANYCAST |
479 | req.r.rtm_scope = RT_SCOPE_LINK; | 491 | ) { |
480 | } | ||
481 | else if (req.r.rtm_type == RTN_UNICAST || req.r.rtm_type == RTN_UNSPEC) { | ||
482 | if (cmd == RTM_DELROUTE) | ||
483 | req.r.rtm_scope = RT_SCOPE_NOWHERE; | ||
484 | else if (!(ok & gw_ok)) | ||
485 | req.r.rtm_scope = RT_SCOPE_LINK; | 492 | req.r.rtm_scope = RT_SCOPE_LINK; |
493 | } | ||
494 | else if (req.r.rtm_type == RTN_UNICAST || req.r.rtm_type == RTN_UNSPEC) { | ||
495 | if (cmd == RTM_DELROUTE) | ||
496 | req.r.rtm_scope = RT_SCOPE_NOWHERE; | ||
497 | else if (!(ok & gw_ok)) | ||
498 | req.r.rtm_scope = RT_SCOPE_LINK; | ||
499 | } | ||
486 | } | 500 | } |
487 | 501 | ||
488 | if (req.r.rtm_family == AF_UNSPEC) { | 502 | if (req.r.rtm_family == AF_UNSPEC) { |
diff --git a/networking/ntpd.c b/networking/ntpd.c index 9732c9b1a..1651670d9 100644 --- a/networking/ntpd.c +++ b/networking/ntpd.c | |||
@@ -112,7 +112,7 @@ | |||
112 | * | 112 | * |
113 | * Made some changes to speed up re-syncing after our clock goes bad | 113 | * Made some changes to speed up re-syncing after our clock goes bad |
114 | * (tested with suspending my laptop): | 114 | * (tested with suspending my laptop): |
115 | * - if largish offset (>= STEP_THRESHOLD * 8 == 1 sec) is seen | 115 | * - if largish offset (>= STEP_THRESHOLD == 1 sec) is seen |
116 | * from a peer, schedule next query for this peer soon | 116 | * from a peer, schedule next query for this peer soon |
117 | * without drastically lowering poll interval for everybody. | 117 | * without drastically lowering poll interval for everybody. |
118 | * This makes us collect enough data for step much faster: | 118 | * This makes us collect enough data for step much faster: |
@@ -131,11 +131,14 @@ | |||
131 | #define RESPONSE_INTERVAL 16 /* wait for reply up to N secs */ | 131 | #define RESPONSE_INTERVAL 16 /* wait for reply up to N secs */ |
132 | 132 | ||
133 | /* Step threshold (sec). std ntpd uses 0.128. | 133 | /* Step threshold (sec). std ntpd uses 0.128. |
134 | */ | ||
135 | #define STEP_THRESHOLD 1 | ||
136 | /* Slew threshold (sec): adjtimex() won't accept offsets larger than this. | ||
134 | * Using exact power of 2 (1/8) results in smaller code | 137 | * Using exact power of 2 (1/8) results in smaller code |
135 | */ | 138 | */ |
136 | #define STEP_THRESHOLD 0.125 | 139 | #define SLEW_THRESHOLD 0.125 |
137 | /* Stepout threshold (sec). std ntpd uses 900 (11 mins (!)) */ | 140 | /* Stepout threshold (sec). std ntpd uses 900 (11 mins (!)) */ |
138 | #define WATCH_THRESHOLD 128 | 141 | #define WATCH_THRESHOLD 128 |
139 | /* NB: set WATCH_THRESHOLD to ~60 when debugging to save time) */ | 142 | /* NB: set WATCH_THRESHOLD to ~60 when debugging to save time) */ |
140 | //UNUSED: #define PANIC_THRESHOLD 1000 /* panic threshold (sec) */ | 143 | //UNUSED: #define PANIC_THRESHOLD 1000 /* panic threshold (sec) */ |
141 | 144 | ||
@@ -143,7 +146,7 @@ | |||
143 | * If we got |offset| > BIGOFF from a peer, cap next query interval | 146 | * If we got |offset| > BIGOFF from a peer, cap next query interval |
144 | * for this peer by this many seconds: | 147 | * for this peer by this many seconds: |
145 | */ | 148 | */ |
146 | #define BIGOFF (STEP_THRESHOLD * 8) | 149 | #define BIGOFF STEP_THRESHOLD |
147 | #define BIGOFF_INTERVAL (1 << 7) /* 128 s */ | 150 | #define BIGOFF_INTERVAL (1 << 7) /* 128 s */ |
148 | 151 | ||
149 | #define FREQ_TOLERANCE 0.000015 /* frequency tolerance (15 PPM) */ | 152 | #define FREQ_TOLERANCE 0.000015 /* frequency tolerance (15 PPM) */ |
@@ -157,10 +160,10 @@ | |||
157 | #define MAXPOLL 12 /* maximum poll interval (12: 1.1h, 17: 36.4h). std ntpd uses 17 */ | 160 | #define MAXPOLL 12 /* maximum poll interval (12: 1.1h, 17: 36.4h). std ntpd uses 17 */ |
158 | /* | 161 | /* |
159 | * Actively lower poll when we see such big offsets. | 162 | * Actively lower poll when we see such big offsets. |
160 | * With STEP_THRESHOLD = 0.125, it means we try to sync more aggressively | 163 | * With SLEW_THRESHOLD = 0.125, it means we try to sync more aggressively |
161 | * if offset increases over ~0.04 sec | 164 | * if offset increases over ~0.04 sec |
162 | */ | 165 | */ |
163 | //#define POLLDOWN_OFFSET (STEP_THRESHOLD / 3) | 166 | //#define POLLDOWN_OFFSET (SLEW_THRESHOLD / 3) |
164 | #define MINDISP 0.01 /* minimum dispersion (sec) */ | 167 | #define MINDISP 0.01 /* minimum dispersion (sec) */ |
165 | #define MAXDISP 16 /* maximum dispersion (sec) */ | 168 | #define MAXDISP 16 /* maximum dispersion (sec) */ |
166 | #define MAXSTRAT 16 /* maximum stratum (infinity metric) */ | 169 | #define MAXSTRAT 16 /* maximum stratum (infinity metric) */ |
@@ -720,7 +723,7 @@ static void | |||
720 | reset_peer_stats(peer_t *p, double offset) | 723 | reset_peer_stats(peer_t *p, double offset) |
721 | { | 724 | { |
722 | int i; | 725 | int i; |
723 | bool small_ofs = fabs(offset) < 16 * STEP_THRESHOLD; | 726 | bool small_ofs = fabs(offset) < STEP_THRESHOLD; |
724 | 727 | ||
725 | /* Used to set p->filter_datapoint[i].d_dispersion = MAXDISP | 728 | /* Used to set p->filter_datapoint[i].d_dispersion = MAXDISP |
726 | * and clear reachable bits, but this proved to be too agressive: | 729 | * and clear reachable bits, but this proved to be too agressive: |
@@ -771,7 +774,7 @@ add_peers(const char *s) | |||
771 | p->p_fd = -1; | 774 | p->p_fd = -1; |
772 | p->p_xmt_msg.m_status = MODE_CLIENT | (NTP_VERSION << 3); | 775 | p->p_xmt_msg.m_status = MODE_CLIENT | (NTP_VERSION << 3); |
773 | p->next_action_time = G.cur_time; /* = set_next(p, 0); */ | 776 | p->next_action_time = G.cur_time; /* = set_next(p, 0); */ |
774 | reset_peer_stats(p, 16 * STEP_THRESHOLD); | 777 | reset_peer_stats(p, STEP_THRESHOLD); |
775 | 778 | ||
776 | llist_add_to(&G.ntp_peers, p); | 779 | llist_add_to(&G.ntp_peers, p); |
777 | G.peer_cnt++; | 780 | G.peer_cnt++; |
@@ -1638,14 +1641,7 @@ update_local_clock(peer_t *p) | |||
1638 | tmx.freq = G.discipline_freq_drift * 65536e6; | 1641 | tmx.freq = G.discipline_freq_drift * 65536e6; |
1639 | #endif | 1642 | #endif |
1640 | tmx.modes = ADJ_OFFSET | ADJ_STATUS | ADJ_TIMECONST;// | ADJ_MAXERROR | ADJ_ESTERROR; | 1643 | tmx.modes = ADJ_OFFSET | ADJ_STATUS | ADJ_TIMECONST;// | ADJ_MAXERROR | ADJ_ESTERROR; |
1641 | tmx.offset = (offset * 1000000); /* usec */ | 1644 | tmx.constant = (int)G.poll_exp - 4; |
1642 | tmx.status = STA_PLL; | ||
1643 | if (G.ntp_status & LI_PLUSSEC) | ||
1644 | tmx.status |= STA_INS; | ||
1645 | if (G.ntp_status & LI_MINUSSEC) | ||
1646 | tmx.status |= STA_DEL; | ||
1647 | |||
1648 | tmx.constant = (int)G.poll_exp - 4 > 0 ? (int)G.poll_exp - 4 : 0; | ||
1649 | /* EXPERIMENTAL. | 1645 | /* EXPERIMENTAL. |
1650 | * The below if statement should be unnecessary, but... | 1646 | * The below if statement should be unnecessary, but... |
1651 | * It looks like Linux kernel's PLL is far too gentle in changing | 1647 | * It looks like Linux kernel's PLL is far too gentle in changing |
@@ -1656,8 +1652,27 @@ update_local_clock(peer_t *p) | |||
1656 | * To be on a safe side, let's do it only if offset is significantly | 1652 | * To be on a safe side, let's do it only if offset is significantly |
1657 | * larger than jitter. | 1653 | * larger than jitter. |
1658 | */ | 1654 | */ |
1659 | if (tmx.constant > 0 && G.offset_to_jitter_ratio >= TIMECONST_HACK_GATE) | 1655 | if (G.offset_to_jitter_ratio >= TIMECONST_HACK_GATE) |
1660 | tmx.constant--; | 1656 | tmx.constant--; |
1657 | tmx.offset = (long)(offset * 1000000); /* usec */ | ||
1658 | if (SLEW_THRESHOLD < STEP_THRESHOLD) { | ||
1659 | if (tmx.offset > (long)(SLEW_THRESHOLD * 1000000)) { | ||
1660 | tmx.offset = (long)(SLEW_THRESHOLD * 1000000); | ||
1661 | tmx.constant--; | ||
1662 | } | ||
1663 | if (tmx.offset < -(long)(SLEW_THRESHOLD * 1000000)) { | ||
1664 | tmx.offset = -(long)(SLEW_THRESHOLD * 1000000); | ||
1665 | tmx.constant--; | ||
1666 | } | ||
1667 | } | ||
1668 | if (tmx.constant < 0) | ||
1669 | tmx.constant = 0; | ||
1670 | |||
1671 | tmx.status = STA_PLL; | ||
1672 | if (G.ntp_status & LI_PLUSSEC) | ||
1673 | tmx.status |= STA_INS; | ||
1674 | if (G.ntp_status & LI_MINUSSEC) | ||
1675 | tmx.status |= STA_DEL; | ||
1661 | 1676 | ||
1662 | //tmx.esterror = (uint32_t)(clock_jitter * 1e6); | 1677 | //tmx.esterror = (uint32_t)(clock_jitter * 1e6); |
1663 | //tmx.maxerror = (uint32_t)((sys_rootdelay / 2 + sys_rootdisp) * 1e6); | 1678 | //tmx.maxerror = (uint32_t)((sys_rootdelay / 2 + sys_rootdisp) * 1e6); |
@@ -1931,6 +1946,9 @@ recv_and_process_peer_pkt(peer_t *p) | |||
1931 | increase_interval: | 1946 | increase_interval: |
1932 | adjust_poll(MINPOLL); | 1947 | adjust_poll(MINPOLL); |
1933 | } else { | 1948 | } else { |
1949 | VERB3 if (rc > 0) | ||
1950 | bb_error_msg("want smaller poll interval: offset/jitter > %u", | ||
1951 | POLLADJ_GATE); | ||
1934 | adjust_poll(-G.poll_exp * 2); | 1952 | adjust_poll(-G.poll_exp * 2); |
1935 | } | 1953 | } |
1936 | } | 1954 | } |
@@ -1939,7 +1957,7 @@ recv_and_process_peer_pkt(peer_t *p) | |||
1939 | pick_normal_interval: | 1957 | pick_normal_interval: |
1940 | interval = poll_interval(INT_MAX); | 1958 | interval = poll_interval(INT_MAX); |
1941 | if (fabs(offset) >= BIGOFF && interval > BIGOFF_INTERVAL) { | 1959 | if (fabs(offset) >= BIGOFF && interval > BIGOFF_INTERVAL) { |
1942 | /* If we are synced, offsets are less than STEP_THRESHOLD, | 1960 | /* If we are synced, offsets are less than SLEW_THRESHOLD, |
1943 | * or at the very least not much larger than it. | 1961 | * or at the very least not much larger than it. |
1944 | * Now we see a largish one. | 1962 | * Now we see a largish one. |
1945 | * Either this peer is feeling bad, or packet got corrupted, | 1963 | * Either this peer is feeling bad, or packet got corrupted, |
diff --git a/networking/udhcp/dhcpc.c b/networking/udhcp/dhcpc.c index 915f65935..48097bc24 100644 --- a/networking/udhcp/dhcpc.c +++ b/networking/udhcp/dhcpc.c | |||
@@ -201,6 +201,8 @@ static int good_hostname(const char *name) | |||
201 | //Do we want this? | 201 | //Do we want this? |
202 | //return ((name - start) < 1025); /* NS_MAXDNAME */ | 202 | //return ((name - start) < 1025); /* NS_MAXDNAME */ |
203 | name++; | 203 | name++; |
204 | if (*name == '\0') | ||
205 | return 1; // We allow trailing dot too | ||
204 | } | 206 | } |
205 | } | 207 | } |
206 | #else | 208 | #else |
diff --git a/scripts/trylink b/scripts/trylink index 6e1187ed0..3c431edc3 100755 --- a/scripts/trylink +++ b/scripts/trylink | |||
@@ -54,7 +54,7 @@ check_cc() { | |||
54 | # "eval" may be needed if CFLAGS can contain | 54 | # "eval" may be needed if CFLAGS can contain |
55 | # '... -D"BB_VER=KBUILD_STR(1.N.M)" ...' | 55 | # '... -D"BB_VER=KBUILD_STR(1.N.M)" ...' |
56 | # and we need shell to process quotes! | 56 | # and we need shell to process quotes! |
57 | $CC $CFLAGS $1 "$tempname".c -o "$tempname" >/dev/null 2>&1 | 57 | $CC $CFLAGS $LDFLAGS $1 "$tempname".c -o "$tempname" >/dev/null 2>&1 |
58 | r=$? | 58 | r=$? |
59 | rm -f "$tempname" "$tempname".c "$tempname".o | 59 | rm -f "$tempname" "$tempname".c "$tempname".o |
60 | return $r | 60 | return $r |
diff --git a/shell/ash.c b/shell/ash.c index de5c44ead..57d192822 100644 --- a/shell/ash.c +++ b/shell/ash.c | |||
@@ -51,7 +51,6 @@ | |||
51 | 51 | ||
52 | #define JOBS ENABLE_ASH_JOB_CONTROL | 52 | #define JOBS ENABLE_ASH_JOB_CONTROL |
53 | 53 | ||
54 | #include <paths.h> | ||
55 | #include <setjmp.h> | 54 | #include <setjmp.h> |
56 | #include <fnmatch.h> | 55 | #include <fnmatch.h> |
57 | #include <sys/times.h> | 56 | #include <sys/times.h> |
@@ -8823,7 +8822,7 @@ evaltree(union node *n, int flags) | |||
8823 | n->nbinary.ch1, | 8822 | n->nbinary.ch1, |
8824 | (flags | ((is_or >> 1) - 1)) & EV_TESTED | 8823 | (flags | ((is_or >> 1) - 1)) & EV_TESTED |
8825 | ); | 8824 | ); |
8826 | if (!exitstatus == is_or) | 8825 | if ((!exitstatus) == is_or) |
8827 | break; | 8826 | break; |
8828 | if (!evalskip) { | 8827 | if (!evalskip) { |
8829 | n = n->nbinary.ch2; | 8828 | n = n->nbinary.ch2; |
diff --git a/sysklogd/klogd.c b/sysklogd/klogd.c index ca8b848bd..03d65b37f 100644 --- a/sysklogd/klogd.c +++ b/sysklogd/klogd.c | |||
@@ -98,7 +98,6 @@ static void klogd_close(void) | |||
98 | 98 | ||
99 | #else | 99 | #else |
100 | 100 | ||
101 | # include <paths.h> | ||
102 | # ifndef _PATH_KLOG | 101 | # ifndef _PATH_KLOG |
103 | # ifdef __GNU__ | 102 | # ifdef __GNU__ |
104 | # define _PATH_KLOG "/dev/klog" | 103 | # define _PATH_KLOG "/dev/klog" |
diff --git a/testsuite/sed.tests b/testsuite/sed.tests index 34479e55f..5d2356b64 100755 --- a/testsuite/sed.tests +++ b/testsuite/sed.tests | |||
@@ -365,6 +365,12 @@ testing "sed /regex/,+0<cmd> -i works" \ | |||
365 | "1\n2\n3\n4\n5\n6\n7\n8\n" \ | 365 | "1\n2\n3\n4\n5\n6\n7\n8\n" \ |
366 | "1\n2\n4\n5\n6\n7\n8\n" \ | 366 | "1\n2\n4\n5\n6\n7\n8\n" \ |
367 | 367 | ||
368 | testing "sed 's///w FILE'" \ | ||
369 | "sed 's/qwe/ZZZ/wz'; cat z; rm z" \ | ||
370 | "123\nZZZ\nasd\n""ZZZ\n" \ | ||
371 | "" \ | ||
372 | "123\nqwe\nasd\n" | ||
373 | |||
368 | # testing "description" "commands" "result" "infile" "stdin" | 374 | # testing "description" "commands" "result" "infile" "stdin" |
369 | 375 | ||
370 | exit $FAILCOUNT | 376 | exit $FAILCOUNT |
diff --git a/util-linux/blkdiscard.c b/util-linux/blkdiscard.c new file mode 100644 index 000000000..ace88a1f0 --- /dev/null +++ b/util-linux/blkdiscard.c | |||
@@ -0,0 +1,83 @@ | |||
1 | /* | ||
2 | * Mini blkdiscard implementation for busybox | ||
3 | * | ||
4 | * Copyright (C) 2015 by Ari Sundholm <ari@tuxera.com> and Tuxera Inc. | ||
5 | * | ||
6 | * Licensed under GPLv2 or later, see file LICENSE in this source tree. | ||
7 | */ | ||
8 | |||
9 | //config:config BLKDISCARD | ||
10 | //config: bool "blkdiscard" | ||
11 | //config: default y | ||
12 | //config: help | ||
13 | //config: blkdiscard discards sectors on a given device. | ||
14 | |||
15 | //kbuild:lib-$(CONFIG_BLKDISCARD) += blkdiscard.o | ||
16 | //applet:IF_BLKDISCARD(APPLET(blkdiscard, BB_DIR_USR_BIN, BB_SUID_DROP)) | ||
17 | |||
18 | //usage:#define blkdiscard_trivial_usage | ||
19 | //usage: "[-o OFS] [-l LEN] [-s] DEVICE" | ||
20 | //usage:#define blkdiscard_full_usage "\n\n" | ||
21 | //usage: "Discard sectors on DEVICE\n" | ||
22 | //usage: "\n -o OFS Byte offset into device" | ||
23 | //usage: "\n -l LEN Number of bytes to discard" | ||
24 | //usage: "\n -s Perform a secure discard" | ||
25 | //usage: | ||
26 | //usage:#define blkdiscard_example_usage | ||
27 | //usage: "$ blkdiscard -o 0 -l 1G /dev/sdb" | ||
28 | |||
29 | #include "libbb.h" | ||
30 | #include <linux/fs.h> | ||
31 | |||
32 | int blkdiscard_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; | ||
33 | int blkdiscard_main(int argc UNUSED_PARAM, char **argv) | ||
34 | { | ||
35 | unsigned opts; | ||
36 | const char *offset_str = "0"; | ||
37 | const char *length_str; | ||
38 | uint64_t offset; /* Leaving these two variables out does not */ | ||
39 | uint64_t length; /* shrink code size and hampers readability. */ | ||
40 | uint64_t range[2]; | ||
41 | // struct stat st; | ||
42 | int fd; | ||
43 | |||
44 | enum { | ||
45 | OPT_OFFSET = (1 << 0), | ||
46 | OPT_LENGTH = (1 << 1), | ||
47 | OPT_SECURE = (1 << 2), | ||
48 | }; | ||
49 | |||
50 | opt_complementary = "=1"; | ||
51 | opts = getopt32(argv, "o:l:s", &offset_str, &length_str); | ||
52 | argv += optind; | ||
53 | |||
54 | fd = xopen(argv[0], O_RDWR|O_EXCL); | ||
55 | //Why bother, BLK[SEC]DISCARD will fail on non-blockdevs anyway? | ||
56 | // xfstat(fd, &st); | ||
57 | // if (!S_ISBLK(st.st_mode)) | ||
58 | // bb_error_msg_and_die("%s: not a block device", argv[0]); | ||
59 | |||
60 | offset = xatoull_sfx(offset_str, kMG_suffixes); | ||
61 | |||
62 | if (opts & OPT_LENGTH) | ||
63 | length = xatoull_sfx(length_str, kMG_suffixes); | ||
64 | else { | ||
65 | xioctl(fd, BLKGETSIZE64, &length); | ||
66 | length -= offset; | ||
67 | } | ||
68 | |||
69 | range[0] = offset; | ||
70 | range[1] = length; | ||
71 | ioctl_or_perror_and_die(fd, | ||
72 | (opts & OPT_SECURE) ? BLKSECDISCARD : BLKDISCARD, | ||
73 | &range, | ||
74 | "%s: %s failed", | ||
75 | argv[0], | ||
76 | (opts & OPT_SECURE) ? "BLKSECDISCARD" : "BLKDISCARD" | ||
77 | ); | ||
78 | |||
79 | if (ENABLE_FEATURE_CLEAN_UP) | ||
80 | close(fd); | ||
81 | |||
82 | return EXIT_SUCCESS; | ||
83 | } | ||
diff --git a/util-linux/mount.c b/util-linux/mount.c index cb40c802d..c428f5827 100644 --- a/util-linux/mount.c +++ b/util-linux/mount.c | |||
@@ -259,9 +259,11 @@ static struct mntent *getmntent_r(FILE* stream, struct mntent* result, | |||
259 | 259 | ||
260 | // Not real flags, but we want to be able to check for this. | 260 | // Not real flags, but we want to be able to check for this. |
261 | enum { | 261 | enum { |
262 | MOUNT_USERS = (1 << 28) * ENABLE_DESKTOP, | 262 | MOUNT_USERS = (1 << 27) * ENABLE_DESKTOP, |
263 | MOUNT_NOFAIL = (1 << 28) * ENABLE_DESKTOP, | ||
263 | MOUNT_NOAUTO = (1 << 29), | 264 | MOUNT_NOAUTO = (1 << 29), |
264 | MOUNT_SWAP = (1 << 30), | 265 | MOUNT_SWAP = (1 << 30), |
266 | MOUNT_FAKEFLAGS = MOUNT_USERS | MOUNT_NOFAIL | MOUNT_NOAUTO | MOUNT_SWAP | ||
265 | }; | 267 | }; |
266 | 268 | ||
267 | 269 | ||
@@ -326,6 +328,7 @@ static const int32_t mount_options[] = { | |||
326 | /* "swap" */ MOUNT_SWAP, | 328 | /* "swap" */ MOUNT_SWAP, |
327 | IF_DESKTOP(/* "user" */ MOUNT_USERS,) | 329 | IF_DESKTOP(/* "user" */ MOUNT_USERS,) |
328 | IF_DESKTOP(/* "users" */ MOUNT_USERS,) | 330 | IF_DESKTOP(/* "users" */ MOUNT_USERS,) |
331 | IF_DESKTOP(/* "nofail" */ MOUNT_NOFAIL,) | ||
329 | /* "_netdev" */ 0, | 332 | /* "_netdev" */ 0, |
330 | IF_DESKTOP(/* "comment=" */ 0,) /* systemd uses this in fstab */ | 333 | IF_DESKTOP(/* "comment=" */ 0,) /* systemd uses this in fstab */ |
331 | ) | 334 | ) |
@@ -385,6 +388,7 @@ static const char mount_option_str[] = | |||
385 | "swap\0" | 388 | "swap\0" |
386 | IF_DESKTOP("user\0") | 389 | IF_DESKTOP("user\0") |
387 | IF_DESKTOP("users\0") | 390 | IF_DESKTOP("users\0") |
391 | IF_DESKTOP("nofail\0") | ||
388 | "_netdev\0" | 392 | "_netdev\0" |
389 | IF_DESKTOP("comment=\0") /* systemd uses this in fstab */ | 393 | IF_DESKTOP("comment=\0") /* systemd uses this in fstab */ |
390 | ) | 394 | ) |
@@ -672,6 +676,8 @@ static int mount_it_now(struct mntent *mp, unsigned long vfsflags, char *filtero | |||
672 | { | 676 | { |
673 | int rc = 0; | 677 | int rc = 0; |
674 | 678 | ||
679 | vfsflags &= ~(unsigned long)MOUNT_FAKEFLAGS; | ||
680 | |||
675 | if (FAKE_IT) { | 681 | if (FAKE_IT) { |
676 | if (verbose >= 2) | 682 | if (verbose >= 2) |
677 | bb_error_msg("would do mount('%s','%s','%s',0x%08lx,'%s')", | 683 | bb_error_msg("would do mount('%s','%s','%s',0x%08lx,'%s')", |
@@ -2061,6 +2067,8 @@ static int singlemount(struct mntent *mp, int ignore_busy) | |||
2061 | 2067 | ||
2062 | if (errno == EBUSY && ignore_busy) | 2068 | if (errno == EBUSY && ignore_busy) |
2063 | return 0; | 2069 | return 0; |
2070 | if (errno == ENOENT && (vfsflags & MOUNT_NOFAIL)) | ||
2071 | return 0; | ||
2064 | if (rc != 0) | 2072 | if (rc != 0) |
2065 | bb_perror_msg("mounting %s on %s failed", mp->mnt_fsname, mp->mnt_dir); | 2073 | bb_perror_msg("mounting %s on %s failed", mp->mnt_fsname, mp->mnt_dir); |
2066 | return rc; | 2074 | return rc; |
diff --git a/util-linux/swaponoff.c b/util-linux/swaponoff.c index 5cd1fbe70..c29dd3071 100644 --- a/util-linux/swaponoff.c +++ b/util-linux/swaponoff.c | |||
@@ -22,11 +22,10 @@ | |||
22 | //usage: ) | 22 | //usage: ) |
23 | //usage: | 23 | //usage: |
24 | //usage:#define swapoff_trivial_usage | 24 | //usage:#define swapoff_trivial_usage |
25 | //usage: "[-a] [-e] [DEVICE]" | 25 | //usage: "[-a] [DEVICE]" |
26 | //usage:#define swapoff_full_usage "\n\n" | 26 | //usage:#define swapoff_full_usage "\n\n" |
27 | //usage: "Stop swapping on DEVICE\n" | 27 | //usage: "Stop swapping on DEVICE\n" |
28 | //usage: "\n -a Stop swapping on all swap devices" | 28 | //usage: "\n -a Stop swapping on all swap devices" |
29 | //usage: "\n -e Silently skip devices that do not exist" | ||
30 | 29 | ||
31 | #include "libbb.h" | 30 | #include "libbb.h" |
32 | #include <mntent.h> | 31 | #include <mntent.h> |
@@ -97,11 +96,8 @@ static int swap_enable_disable(char *device) | |||
97 | { | 96 | { |
98 | int err = 0; | 97 | int err = 0; |
99 | int quiet = 0; | 98 | int quiet = 0; |
100 | struct stat st; | ||
101 | 99 | ||
102 | resolve_mount_spec(&device); | 100 | resolve_mount_spec(&device); |
103 | if (!OPT_IFEXISTS) | ||
104 | xstat(device, &st); | ||
105 | 101 | ||
106 | if (do_swapoff) { | 102 | if (do_swapoff) { |
107 | err = swapoff(device); | 103 | err = swapoff(device); |
@@ -109,6 +105,7 @@ static int swap_enable_disable(char *device) | |||
109 | quiet = (OPT_ALL && (errno == EINVAL || errno == ENOENT)); | 105 | quiet = (OPT_ALL && (errno == EINVAL || errno == ENOENT)); |
110 | } else { | 106 | } else { |
111 | /* swapon */ | 107 | /* swapon */ |
108 | struct stat st; | ||
112 | err = stat(device, &st); | 109 | err = stat(device, &st); |
113 | if (!err) { | 110 | if (!err) { |
114 | if (ENABLE_DESKTOP && S_ISREG(st.st_mode)) { | 111 | if (ENABLE_DESKTOP && S_ISREG(st.st_mode)) { |
@@ -119,9 +116,11 @@ static int swap_enable_disable(char *device) | |||
119 | } | 116 | } |
120 | err = swapon(device, g_flags); | 117 | err = swapon(device, g_flags); |
121 | /* Don't complain on swapon -a if device is already in use */ | 118 | /* Don't complain on swapon -a if device is already in use */ |
122 | /* Don't complain if file does not exist with -e option */ | 119 | quiet = (OPT_ALL && errno == EBUSY); |
123 | quiet = (OPT_ALL && errno == EBUSY) || (OPT_IFEXISTS && errno == ENOENT); | ||
124 | } | 120 | } |
121 | /* Don't complain if file does not exist with -e option */ | ||
122 | if (err && OPT_IFEXISTS && errno == ENOENT) | ||
123 | err = 0; | ||
125 | } | 124 | } |
126 | 125 | ||
127 | if (err && !quiet) { | 126 | if (err && !quiet) { |
diff --git a/util-linux/volume_id/bcache.c b/util-linux/volume_id/bcache.c new file mode 100644 index 000000000..648e44de5 --- /dev/null +++ b/util-linux/volume_id/bcache.c | |||
@@ -0,0 +1,110 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2013 Rolf Fokkens <rolf@fokkens.nl> | ||
3 | * | ||
4 | * This file may be redistributed under the terms of the | ||
5 | * GNU Lesser General Public License. | ||
6 | * | ||
7 | * Based on code fragments from bcache-tools by Kent Overstreet: | ||
8 | * http://evilpiepirate.org/git/bcache-tools.git | ||
9 | */ | ||
10 | |||
11 | //kbuild:lib-$(CONFIG_FEATURE_VOLUMEID_BCACHE) += bcache.o | ||
12 | |||
13 | //config: | ||
14 | //config:config FEATURE_VOLUMEID_BCACHE | ||
15 | //config: bool "bcache filesystem" | ||
16 | //config: default y | ||
17 | //config: depends on VOLUMEID | ||
18 | //config: help | ||
19 | //config: TODO | ||
20 | //config: | ||
21 | |||
22 | #include "volume_id_internal.h" | ||
23 | |||
24 | #define SB_LABEL_SIZE 32 | ||
25 | #define SB_JOURNAL_BUCKETS 256U | ||
26 | |||
27 | static const char bcache_magic[] = { | ||
28 | 0xc6, 0x85, 0x73, 0xf6, 0x4e, 0x1a, 0x45, 0xca, | ||
29 | 0x82, 0x65, 0xf5, 0x7f, 0x48, 0xba, 0x6d, 0x81 | ||
30 | }; | ||
31 | |||
32 | struct bcache_super_block { | ||
33 | uint64_t csum; | ||
34 | uint64_t offset; /* sector where this sb was written */ | ||
35 | uint64_t version; | ||
36 | |||
37 | uint8_t magic[16]; | ||
38 | |||
39 | uint8_t uuid[16]; | ||
40 | union { | ||
41 | uint8_t set_uuid[16]; | ||
42 | uint64_t set_magic; | ||
43 | }; | ||
44 | uint8_t label[SB_LABEL_SIZE]; | ||
45 | |||
46 | uint64_t flags; | ||
47 | uint64_t seq; | ||
48 | uint64_t pad[8]; | ||
49 | |||
50 | union { | ||
51 | struct { | ||
52 | /* Cache devices */ | ||
53 | uint64_t nbuckets; /* device size */ | ||
54 | |||
55 | uint16_t block_size; /* sectors */ | ||
56 | uint16_t bucket_size; /* sectors */ | ||
57 | |||
58 | uint16_t nr_in_set; | ||
59 | uint16_t nr_this_dev; | ||
60 | }; | ||
61 | struct { | ||
62 | /* Backing devices */ | ||
63 | uint64_t data_offset; | ||
64 | |||
65 | /* | ||
66 | * block_size from the cache device section is still used by | ||
67 | * backing devices, so don't add anything here until we fix | ||
68 | * things to not need it for backing devices anymore | ||
69 | */ | ||
70 | }; | ||
71 | }; | ||
72 | |||
73 | uint32_t last_mount; /* time_t */ | ||
74 | |||
75 | uint16_t first_bucket; | ||
76 | union { | ||
77 | uint16_t njournal_buckets; | ||
78 | uint16_t keys; | ||
79 | }; | ||
80 | uint64_t d[SB_JOURNAL_BUCKETS]; /* journal buckets */ | ||
81 | }; | ||
82 | |||
83 | /* magic string */ | ||
84 | #define BCACHE_SB_MAGIC bcache_magic | ||
85 | /* magic string len */ | ||
86 | #define BCACHE_SB_MAGIC_LEN sizeof (bcache_magic) | ||
87 | /* super block offset */ | ||
88 | #define BCACHE_SB_OFF 0x1000 | ||
89 | /* supper block offset in kB */ | ||
90 | #define BCACHE_SB_KBOFF (BCACHE_SB_OFF >> 10) | ||
91 | /* magic string offset within super block */ | ||
92 | #define BCACHE_SB_MAGIC_OFF offsetof (struct bcache_super_block, magic) | ||
93 | |||
94 | int FAST_FUNC volume_id_probe_bcache(struct volume_id *id /*,uint64_t off*/) | ||
95 | { | ||
96 | struct bcache_super_block *sb; | ||
97 | |||
98 | sb = volume_id_get_buffer(id, BCACHE_SB_OFF, sizeof(*sb)); | ||
99 | if (sb == NULL) | ||
100 | return -1; | ||
101 | |||
102 | if (memcmp(sb->magic, BCACHE_SB_MAGIC, BCACHE_SB_MAGIC_LEN) != 0) | ||
103 | return -1; | ||
104 | |||
105 | volume_id_set_label_string(id, sb->label, SB_LABEL_SIZE); | ||
106 | volume_id_set_uuid(id, sb->uuid, UUID_DCE); | ||
107 | IF_FEATURE_BLKID_TYPE(id->type = "bcache";) | ||
108 | |||
109 | return 0; | ||
110 | } | ||
diff --git a/util-linux/volume_id/volume_id.c b/util-linux/volume_id/volume_id.c index 5c459a0e2..3f71e0084 100644 --- a/util-linux/volume_id/volume_id.c +++ b/util-linux/volume_id/volume_id.c | |||
@@ -107,6 +107,9 @@ static const probe_fptr fs1[] = { | |||
107 | #if ENABLE_FEATURE_VOLUMEID_XFS | 107 | #if ENABLE_FEATURE_VOLUMEID_XFS |
108 | volume_id_probe_xfs, | 108 | volume_id_probe_xfs, |
109 | #endif | 109 | #endif |
110 | #if ENABLE_FEATURE_VOLUMEID_BCACHE | ||
111 | volume_id_probe_bcache, | ||
112 | #endif | ||
110 | }; | 113 | }; |
111 | 114 | ||
112 | /* fill buffer with maximum */ | 115 | /* fill buffer with maximum */ |
diff --git a/util-linux/volume_id/volume_id_internal.h b/util-linux/volume_id/volume_id_internal.h index 6e2dbd7bb..3061ac4d5 100644 --- a/util-linux/volume_id/volume_id_internal.h +++ b/util-linux/volume_id/volume_id_internal.h | |||
@@ -169,6 +169,8 @@ int FAST_FUNC volume_id_probe_linux_raid(struct volume_id *id /*,uint64_t off*/, | |||
169 | 169 | ||
170 | /* FS */ | 170 | /* FS */ |
171 | 171 | ||
172 | int FAST_FUNC volume_id_probe_bcache(struct volume_id *id /*,uint64_t off*/); | ||
173 | |||
172 | int FAST_FUNC volume_id_probe_btrfs(struct volume_id *id /*,uint64_t off*/); | 174 | int FAST_FUNC volume_id_probe_btrfs(struct volume_id *id /*,uint64_t off*/); |
173 | 175 | ||
174 | int FAST_FUNC volume_id_probe_cramfs(struct volume_id *id /*,uint64_t off*/); | 176 | int FAST_FUNC volume_id_probe_cramfs(struct volume_id *id /*,uint64_t off*/); |