diff options
author | Ron Yorston <rmy@pobox.com> | 2021-08-30 08:37:51 +0100 |
---|---|---|
committer | Ron Yorston <rmy@pobox.com> | 2021-08-30 08:37:51 +0100 |
commit | bdb10f66af52bbd4f9d9340f2cf8ca73adbaee91 (patch) | |
tree | 306810231da90fb758cacb38ee9f8a7c4adf0d7c | |
parent | 6a42f73dcac55a6b5dde810ad60cee7c120a2db7 (diff) | |
parent | a51d953b95a7cc6b40a6b3a5bfd95f3154acf5e2 (diff) | |
download | busybox-w32-bdb10f66af52bbd4f9d9340f2cf8ca73adbaee91.tar.gz busybox-w32-bdb10f66af52bbd4f9d9340f2cf8ca73adbaee91.tar.bz2 busybox-w32-bdb10f66af52bbd4f9d9340f2cf8ca73adbaee91.zip |
Merge branch 'busybox' into merge
-rw-r--r-- | archival/chksum_and_xwrite_tar_header.c | 2 | ||||
-rw-r--r-- | archival/cpio.c | 2 | ||||
-rw-r--r-- | archival/libarchive/bz/bzlib.c | 7 | ||||
-rw-r--r-- | archival/libarchive/bz/bzlib_private.h | 11 | ||||
-rw-r--r-- | coreutils/shuf.c | 76 | ||||
-rw-r--r-- | editors/vi.c | 132 | ||||
-rw-r--r-- | findutils/grep.c | 2 | ||||
-rw-r--r-- | findutils/xargs.c | 2 | ||||
-rw-r--r-- | util-linux/mount.c | 30 |
9 files changed, 165 insertions, 99 deletions
diff --git a/archival/chksum_and_xwrite_tar_header.c b/archival/chksum_and_xwrite_tar_header.c index 25934f898..f2d46b9ef 100644 --- a/archival/chksum_and_xwrite_tar_header.c +++ b/archival/chksum_and_xwrite_tar_header.c | |||
@@ -15,7 +15,7 @@ void FAST_FUNC chksum_and_xwrite_tar_header(int fd, struct tar_header_t *hp) | |||
15 | * (Sun and HP-UX gets it wrong... more details in | 15 | * (Sun and HP-UX gets it wrong... more details in |
16 | * GNU tar source) */ | 16 | * GNU tar source) */ |
17 | const unsigned char *cp; | 17 | const unsigned char *cp; |
18 | int chksum, size; | 18 | unsigned int chksum, size; |
19 | 19 | ||
20 | strcpy(hp->magic, "ustar "); | 20 | strcpy(hp->magic, "ustar "); |
21 | 21 | ||
diff --git a/archival/cpio.c b/archival/cpio.c index d84f6937d..f525419b8 100644 --- a/archival/cpio.c +++ b/archival/cpio.c | |||
@@ -74,7 +74,7 @@ | |||
74 | //usage: "\n -F FILE Input (-t,-i,-p) or output (-o) file" | 74 | //usage: "\n -F FILE Input (-t,-i,-p) or output (-o) file" |
75 | //usage: "\n -R USER[:GRP] Set owner of created files" | 75 | //usage: "\n -R USER[:GRP] Set owner of created files" |
76 | //usage: "\n -L Dereference symlinks" | 76 | //usage: "\n -L Dereference symlinks" |
77 | //usage: "\n -0 Input is separated by NULs" | 77 | //usage: "\n -0 NUL terminated input" |
78 | 78 | ||
79 | /* GNU cpio 2.9 --help (abridged): | 79 | /* GNU cpio 2.9 --help (abridged): |
80 | 80 | ||
diff --git a/archival/libarchive/bz/bzlib.c b/archival/libarchive/bz/bzlib.c index 9af2f026d..ef19ae165 100644 --- a/archival/libarchive/bz/bzlib.c +++ b/archival/libarchive/bz/bzlib.c | |||
@@ -99,9 +99,8 @@ void BZ2_bzCompressInit(bz_stream *strm, int blockSize100k) | |||
99 | s->ptr = (uint32_t*)s->arr1; | 99 | s->ptr = (uint32_t*)s->arr1; |
100 | s->arr2 = xmalloc((n + BZ_N_OVERSHOOT) * sizeof(uint32_t)); | 100 | s->arr2 = xmalloc((n + BZ_N_OVERSHOOT) * sizeof(uint32_t)); |
101 | s->block = (uint8_t*)s->arr2; | 101 | s->block = (uint8_t*)s->arr2; |
102 | s->ftab = xmalloc(65537 * sizeof(uint32_t)); | ||
103 | 102 | ||
104 | s->crc32table = crc32_filltable(NULL, 1); | 103 | crc32_filltable(s->crc32table, 1); |
105 | 104 | ||
106 | s->state = BZ_S_INPUT; | 105 | s->state = BZ_S_INPUT; |
107 | s->mode = BZ_M_RUNNING; | 106 | s->mode = BZ_M_RUNNING; |
@@ -369,8 +368,8 @@ void BZ2_bzCompressEnd(bz_stream *strm) | |||
369 | s = strm->state; | 368 | s = strm->state; |
370 | free(s->arr1); | 369 | free(s->arr1); |
371 | free(s->arr2); | 370 | free(s->arr2); |
372 | free(s->ftab); | 371 | //free(s->ftab); // made it array member of s |
373 | free(s->crc32table); | 372 | //free(s->crc32table); // ditto |
374 | free(s); | 373 | free(s); |
375 | } | 374 | } |
376 | 375 | ||
diff --git a/archival/libarchive/bz/bzlib_private.h b/archival/libarchive/bz/bzlib_private.h index ea0f29b7c..650444a5c 100644 --- a/archival/libarchive/bz/bzlib_private.h +++ b/archival/libarchive/bz/bzlib_private.h | |||
@@ -134,7 +134,7 @@ typedef struct EState { | |||
134 | /* for doing the block sorting */ | 134 | /* for doing the block sorting */ |
135 | uint32_t *arr1; | 135 | uint32_t *arr1; |
136 | uint32_t *arr2; | 136 | uint32_t *arr2; |
137 | uint32_t *ftab; | 137 | //uint32_t *ftab; //moved into this struct, see below |
138 | 138 | ||
139 | uint16_t *quadrant; | 139 | uint16_t *quadrant; |
140 | int32_t budget; | 140 | int32_t budget; |
@@ -160,9 +160,6 @@ typedef struct EState { | |||
160 | uint32_t bsBuff; | 160 | uint32_t bsBuff; |
161 | int32_t bsLive; | 161 | int32_t bsLive; |
162 | 162 | ||
163 | /* guess what */ | ||
164 | uint32_t *crc32table; | ||
165 | |||
166 | /* block and combined CRCs */ | 163 | /* block and combined CRCs */ |
167 | uint32_t blockCRC; | 164 | uint32_t blockCRC; |
168 | uint32_t combinedCRC; | 165 | uint32_t combinedCRC; |
@@ -185,6 +182,12 @@ typedef struct EState { | |||
185 | 182 | ||
186 | uint8_t len[BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE]; | 183 | uint8_t len[BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE]; |
187 | 184 | ||
185 | /* guess what */ | ||
186 | uint32_t crc32table[256]; | ||
187 | |||
188 | /* for doing the block sorting */ | ||
189 | uint32_t ftab[65537]; | ||
190 | |||
188 | /* stack-saving measures: these can be local, but they are too big */ | 191 | /* stack-saving measures: these can be local, but they are too big */ |
189 | int32_t sendMTFValues__code [BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE]; | 192 | int32_t sendMTFValues__code [BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE]; |
190 | int32_t sendMTFValues__rfreq[BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE]; | 193 | int32_t sendMTFValues__rfreq[BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE]; |
diff --git a/coreutils/shuf.c b/coreutils/shuf.c index fdbd3e9b2..77f8a8ff9 100644 --- a/coreutils/shuf.c +++ b/coreutils/shuf.c | |||
@@ -17,14 +17,14 @@ | |||
17 | //kbuild:lib-$(CONFIG_SHUF) += shuf.o | 17 | //kbuild:lib-$(CONFIG_SHUF) += shuf.o |
18 | 18 | ||
19 | //usage:#define shuf_trivial_usage | 19 | //usage:#define shuf_trivial_usage |
20 | //usage: "[-e|-i L-H] [-n NUM] [-o FILE] [-z] [FILE|ARG...]" | 20 | //usage: "[-n NUM] [-o FILE] [-z] [FILE | -e [ARG...] | -i L-H]" |
21 | //usage:#define shuf_full_usage "\n\n" | 21 | //usage:#define shuf_full_usage "\n\n" |
22 | //usage: "Randomly permute lines\n" | 22 | //usage: "Randomly permute lines\n" |
23 | //usage: "\n -e Treat ARGs as lines" | ||
24 | //usage: "\n -i L-H Treat numbers L-H as lines" | ||
25 | //usage: "\n -n NUM Output at most NUM lines" | 23 | //usage: "\n -n NUM Output at most NUM lines" |
26 | //usage: "\n -o FILE Write to FILE, not standard output" | 24 | //usage: "\n -o FILE Write to FILE, not standard output" |
27 | //usage: "\n -z End lines with zero byte, not newline" | 25 | //usage: "\n -z NUL terminated output" |
26 | //usage: "\n -e Treat ARGs as lines" | ||
27 | //usage: "\n -i L-H Treat numbers L-H as lines" | ||
28 | 28 | ||
29 | #include "libbb.h" | 29 | #include "libbb.h" |
30 | 30 | ||
@@ -39,8 +39,10 @@ | |||
39 | 39 | ||
40 | /* | 40 | /* |
41 | * Use the Fisher-Yates shuffle algorithm on an array of lines. | 41 | * Use the Fisher-Yates shuffle algorithm on an array of lines. |
42 | * If the required number of output lines is less than the total | ||
43 | * we can stop shuffling early. | ||
42 | */ | 44 | */ |
43 | static void shuffle_lines(char **lines, unsigned numlines) | 45 | static void shuffle_lines(char **lines, unsigned numlines, unsigned outlines) |
44 | { | 46 | { |
45 | unsigned i; | 47 | unsigned i; |
46 | unsigned r; | 48 | unsigned r; |
@@ -48,7 +50,7 @@ static void shuffle_lines(char **lines, unsigned numlines) | |||
48 | 50 | ||
49 | srand(monotonic_us()); | 51 | srand(monotonic_us()); |
50 | 52 | ||
51 | for (i = numlines-1; i > 0; i--) { | 53 | for (i = numlines - 1; outlines > 0; i--, outlines--) { |
52 | r = rand(); | 54 | r = rand(); |
53 | /* RAND_MAX can be as small as 32767 */ | 55 | /* RAND_MAX can be as small as 32767 */ |
54 | if (i > RAND_MAX) | 56 | if (i > RAND_MAX) |
@@ -67,7 +69,7 @@ int shuf_main(int argc, char **argv) | |||
67 | char *opt_i_str, *opt_n_str, *opt_o_str; | 69 | char *opt_i_str, *opt_n_str, *opt_o_str; |
68 | unsigned i; | 70 | unsigned i; |
69 | char **lines; | 71 | char **lines; |
70 | unsigned numlines; | 72 | unsigned numlines, outlines; |
71 | char eol; | 73 | char eol; |
72 | 74 | ||
73 | opts = getopt32(argv, "^" | 75 | opts = getopt32(argv, "^" |
@@ -88,15 +90,27 @@ int shuf_main(int argc, char **argv) | |||
88 | if (opts & OPT_i) { | 90 | if (opts & OPT_i) { |
89 | /* create a range of numbers */ | 91 | /* create a range of numbers */ |
90 | char *dash; | 92 | char *dash; |
91 | unsigned lo, hi; | 93 | uintptr_t lo, hi; |
94 | |||
95 | if (argv[0]) | ||
96 | bb_show_usage(); | ||
92 | 97 | ||
93 | dash = strchr(opt_i_str, '-'); | 98 | dash = strchr(opt_i_str, '-'); |
94 | if (!dash) { | 99 | if (!dash) { |
95 | bb_error_msg_and_die("bad range '%s'", opt_i_str); | 100 | bb_error_msg_and_die("bad range '%s'", opt_i_str); |
96 | } | 101 | } |
97 | *dash = '\0'; | 102 | *dash = '\0'; |
98 | lo = xatou(opt_i_str); | 103 | if (sizeof(lo) == sizeof(int)) { |
99 | hi = xatou(dash + 1); | 104 | lo = xatou(opt_i_str); |
105 | hi = xatou(dash + 1); | ||
106 | } else | ||
107 | if (sizeof(lo) == sizeof(long)) { | ||
108 | lo = xatoul(opt_i_str); | ||
109 | hi = xatoul(dash + 1); | ||
110 | } else { | ||
111 | lo = xatoull(opt_i_str); | ||
112 | hi = xatoull(dash + 1); | ||
113 | } | ||
100 | *dash = '-'; | 114 | *dash = '-'; |
101 | if (hi < lo) { | 115 | if (hi < lo) { |
102 | bb_error_msg_and_die("bad range '%s'", opt_i_str); | 116 | bb_error_msg_and_die("bad range '%s'", opt_i_str); |
@@ -105,17 +119,21 @@ int shuf_main(int argc, char **argv) | |||
105 | numlines = (hi+1) - lo; | 119 | numlines = (hi+1) - lo; |
106 | lines = xmalloc(numlines * sizeof(lines[0])); | 120 | lines = xmalloc(numlines * sizeof(lines[0])); |
107 | for (i = 0; i < numlines; i++) { | 121 | for (i = 0; i < numlines; i++) { |
108 | lines[i] = (char*)(uintptr_t)lo; | 122 | lines[i] = (char*)lo; |
109 | lo++; | 123 | lo++; |
110 | } | 124 | } |
111 | } else { | 125 | } else { |
112 | /* default - read lines from stdin or the input file */ | 126 | /* default - read lines from stdin or the input file */ |
113 | FILE *fp; | 127 | FILE *fp; |
128 | const char *fname = "-"; | ||
114 | 129 | ||
115 | if (argc > 1) | 130 | if (argv[0]) { |
116 | bb_show_usage(); | 131 | if (argv[1]) |
132 | bb_show_usage(); | ||
133 | fname = argv[0]; | ||
134 | } | ||
117 | 135 | ||
118 | fp = xfopen_stdin(argv[0] ? argv[0] : "-"); | 136 | fp = xfopen_stdin(fname); |
119 | lines = NULL; | 137 | lines = NULL; |
120 | numlines = 0; | 138 | numlines = 0; |
121 | for (;;) { | 139 | for (;;) { |
@@ -128,27 +146,31 @@ int shuf_main(int argc, char **argv) | |||
128 | fclose_if_not_stdin(fp); | 146 | fclose_if_not_stdin(fp); |
129 | } | 147 | } |
130 | 148 | ||
131 | if (numlines != 0) | 149 | outlines = numlines; |
132 | shuffle_lines(lines, numlines); | 150 | if (opts & OPT_n) { |
151 | outlines = xatou(opt_n_str); | ||
152 | if (outlines > numlines) | ||
153 | outlines = numlines; | ||
154 | } | ||
155 | |||
156 | shuffle_lines(lines, numlines, outlines); | ||
133 | 157 | ||
134 | if (opts & OPT_o) | 158 | if (opts & OPT_o) |
135 | xmove_fd(xopen(opt_o_str, O_WRONLY|O_CREAT|O_TRUNC), STDOUT_FILENO); | 159 | xmove_fd(xopen(opt_o_str, O_WRONLY|O_CREAT|O_TRUNC), STDOUT_FILENO); |
136 | 160 | ||
137 | if (opts & OPT_n) { | ||
138 | unsigned maxlines; | ||
139 | maxlines = xatou(opt_n_str); | ||
140 | if (numlines > maxlines) | ||
141 | numlines = maxlines; | ||
142 | } | ||
143 | |||
144 | eol = '\n'; | 161 | eol = '\n'; |
145 | if (opts & OPT_z) | 162 | if (opts & OPT_z) |
146 | eol = '\0'; | 163 | eol = '\0'; |
147 | 164 | ||
148 | for (i = 0; i < numlines; i++) { | 165 | for (i = numlines - outlines; i < numlines; i++) { |
149 | if (opts & OPT_i) | 166 | if (opts & OPT_i) { |
150 | printf("%u%c", (unsigned)(uintptr_t)lines[i], eol); | 167 | if (sizeof(lines[0]) == sizeof(int)) |
151 | else | 168 | printf("%u%c", (unsigned)(uintptr_t)lines[i], eol); |
169 | else if (sizeof(lines[0]) == sizeof(long)) | ||
170 | printf("%lu%c", (unsigned long)(uintptr_t)lines[i], eol); | ||
171 | else | ||
172 | printf("%llu%c", (unsigned long long)(uintptr_t)lines[i], eol); | ||
173 | } else | ||
152 | printf("%s%c", lines[i], eol); | 174 | printf("%s%c", lines[i], eol); |
153 | } | 175 | } |
154 | 176 | ||
diff --git a/editors/vi.c b/editors/vi.c index a0a046272..2c1048a4c 100644 --- a/editors/vi.c +++ b/editors/vi.c | |||
@@ -2524,26 +2524,38 @@ static char *char_search(char *p, const char *pat, int dir_and_range) | |||
2524 | 2524 | ||
2525 | //----- The Colon commands ------------------------------------- | 2525 | //----- The Colon commands ------------------------------------- |
2526 | #if ENABLE_FEATURE_VI_COLON | 2526 | #if ENABLE_FEATURE_VI_COLON |
2527 | static char *get_one_address(char *p, int *result) // get colon addr, if present | 2527 | // Evaluate colon address expression. Returns a pointer to the |
2528 | // next character or NULL on error. If 'result' contains a valid | ||
2529 | // address 'valid' is TRUE. | ||
2530 | static char *get_one_address(char *p, int *result, int *valid) | ||
2528 | { | 2531 | { |
2529 | int st, num, sign, addr, new_addr; | 2532 | int num, sign, addr, got_addr; |
2530 | # if ENABLE_FEATURE_VI_YANKMARK || ENABLE_FEATURE_VI_SEARCH | 2533 | # if ENABLE_FEATURE_VI_YANKMARK || ENABLE_FEATURE_VI_SEARCH |
2531 | char *q, c; | 2534 | char *q, c; |
2532 | # endif | 2535 | # endif |
2533 | IF_FEATURE_VI_SEARCH(int dir;) | 2536 | IF_FEATURE_VI_SEARCH(int dir;) |
2534 | 2537 | ||
2535 | addr = -1; // assume no addr | 2538 | got_addr = FALSE; |
2539 | addr = count_lines(text, dot); // default to current line | ||
2536 | sign = 0; | 2540 | sign = 0; |
2537 | for (;;) { | 2541 | for (;;) { |
2538 | new_addr = -1; | ||
2539 | if (isblank(*p)) { | 2542 | if (isblank(*p)) { |
2543 | if (got_addr) { | ||
2544 | addr += sign; | ||
2545 | sign = 0; | ||
2546 | } | ||
2547 | p++; | ||
2548 | } else if (!got_addr && *p == '.') { // the current line | ||
2540 | p++; | 2549 | p++; |
2541 | } else if (*p == '.') { // the current line | 2550 | //addr = count_lines(text, dot); |
2551 | got_addr = TRUE; | ||
2552 | } else if (!got_addr && *p == '$') { // the last line in file | ||
2542 | p++; | 2553 | p++; |
2543 | new_addr = count_lines(text, dot); | 2554 | addr = count_lines(text, end - 1); |
2555 | got_addr = TRUE; | ||
2544 | } | 2556 | } |
2545 | # if ENABLE_FEATURE_VI_YANKMARK | 2557 | # if ENABLE_FEATURE_VI_YANKMARK |
2546 | else if (*p == '\'') { // is this a mark addr | 2558 | else if (!got_addr && *p == '\'') { // is this a mark addr |
2547 | p++; | 2559 | p++; |
2548 | c = tolower(*p); | 2560 | c = tolower(*p); |
2549 | p++; | 2561 | p++; |
@@ -2553,13 +2565,16 @@ static char *get_one_address(char *p, int *result) // get colon addr, if present | |||
2553 | c = c - 'a'; | 2565 | c = c - 'a'; |
2554 | q = mark[(unsigned char) c]; | 2566 | q = mark[(unsigned char) c]; |
2555 | } | 2567 | } |
2556 | if (q == NULL) // is mark valid | 2568 | if (q == NULL) { // is mark valid |
2569 | status_line_bold("Mark not set"); | ||
2557 | return NULL; | 2570 | return NULL; |
2558 | new_addr = count_lines(text, q); | 2571 | } |
2572 | addr = count_lines(text, q); | ||
2573 | got_addr = TRUE; | ||
2559 | } | 2574 | } |
2560 | # endif | 2575 | # endif |
2561 | # if ENABLE_FEATURE_VI_SEARCH | 2576 | # if ENABLE_FEATURE_VI_SEARCH |
2562 | else if (*p == '/' || *p == '?') { // a search pattern | 2577 | else if (!got_addr && (*p == '/' || *p == '?')) { // a search pattern |
2563 | c = *p; | 2578 | c = *p; |
2564 | q = strchrnul(p + 1, c); | 2579 | q = strchrnul(p + 1, c); |
2565 | if (p + 1 != q) { | 2580 | if (p + 1 != q) { |
@@ -2582,40 +2597,41 @@ static char *get_one_address(char *p, int *result) // get colon addr, if present | |||
2582 | // no match, continue from other end of file | 2597 | // no match, continue from other end of file |
2583 | q = char_search(dir > 0 ? text : end - 1, | 2598 | q = char_search(dir > 0 ? text : end - 1, |
2584 | last_search_pattern + 1, dir); | 2599 | last_search_pattern + 1, dir); |
2585 | if (q == NULL) | 2600 | if (q == NULL) { |
2601 | status_line_bold("Pattern not found"); | ||
2586 | return NULL; | 2602 | return NULL; |
2603 | } | ||
2587 | } | 2604 | } |
2588 | new_addr = count_lines(text, q); | 2605 | addr = count_lines(text, q); |
2606 | got_addr = TRUE; | ||
2589 | } | 2607 | } |
2590 | # endif | 2608 | # endif |
2591 | else if (*p == '$') { // the last line in file | 2609 | else if (isdigit(*p)) { |
2592 | p++; | 2610 | num = 0; |
2593 | new_addr = count_lines(text, end - 1); | 2611 | while (isdigit(*p)) |
2594 | } else if (isdigit(*p)) { | 2612 | num = num * 10 + *p++ -'0'; |
2595 | sscanf(p, "%d%n", &num, &st); | 2613 | if (!got_addr) { // specific line number |
2596 | p += st; | ||
2597 | if (addr < 0) { // specific line number | ||
2598 | addr = num; | 2614 | addr = num; |
2615 | got_addr = TRUE; | ||
2599 | } else { // offset from current addr | 2616 | } else { // offset from current addr |
2600 | addr += sign >= 0 ? num : -num; | 2617 | addr += sign >= 0 ? num : -num; |
2601 | } | 2618 | } |
2602 | sign = 0; | 2619 | sign = 0; |
2603 | } else if (*p == '-' || *p == '+') { | 2620 | } else if (*p == '-' || *p == '+') { |
2604 | sign = *p++ == '-' ? -1 : 1; | 2621 | if (!got_addr) { // default address is dot |
2605 | if (addr < 0) { // default address is dot | 2622 | //addr = count_lines(text, dot); |
2606 | addr = count_lines(text, dot); | 2623 | got_addr = TRUE; |
2624 | } else { | ||
2625 | addr += sign; | ||
2607 | } | 2626 | } |
2627 | sign = *p++ == '-' ? -1 : 1; | ||
2608 | } else { | 2628 | } else { |
2609 | addr += sign; // consume unused trailing sign | 2629 | addr += sign; // consume unused trailing sign |
2610 | break; | 2630 | break; |
2611 | } | 2631 | } |
2612 | if (new_addr >= 0) { | ||
2613 | if (addr >= 0) // only one new address per expression | ||
2614 | return NULL; | ||
2615 | addr = new_addr; | ||
2616 | } | ||
2617 | } | 2632 | } |
2618 | *result = addr; | 2633 | *result = addr; |
2634 | *valid = got_addr; | ||
2619 | return p; | 2635 | return p; |
2620 | } | 2636 | } |
2621 | 2637 | ||
@@ -2624,34 +2640,40 @@ static char *get_one_address(char *p, int *result) // get colon addr, if present | |||
2624 | 2640 | ||
2625 | // Read line addresses for a colon command. The user can enter as | 2641 | // Read line addresses for a colon command. The user can enter as |
2626 | // many as they like but only the last two will be used. | 2642 | // many as they like but only the last two will be used. |
2627 | static char *get_address(char *p, int *b, int *e) | 2643 | static char *get_address(char *p, int *b, int *e, unsigned int *got) |
2628 | { | 2644 | { |
2629 | int state = GET_ADDRESS; | 2645 | int state = GET_ADDRESS; |
2646 | int valid; | ||
2647 | int addr; | ||
2630 | char *save_dot = dot; | 2648 | char *save_dot = dot; |
2631 | 2649 | ||
2632 | //----- get the address' i.e., 1,3 'a,'b ----- | 2650 | //----- get the address' i.e., 1,3 'a,'b ----- |
2633 | for (;;) { | 2651 | for (;;) { |
2634 | if (isblank(*p)) { | 2652 | if (isblank(*p)) { |
2635 | p++; | 2653 | p++; |
2636 | } else if (*p == '%' && state == GET_ADDRESS) { // alias for 1,$ | 2654 | } else if (state == GET_ADDRESS && *p == '%') { // alias for 1,$ |
2637 | p++; | 2655 | p++; |
2638 | *b = 1; | 2656 | *b = 1; |
2639 | *e = count_lines(text, end-1); | 2657 | *e = count_lines(text, end-1); |
2658 | *got = 3; | ||
2659 | state = GET_SEPARATOR; | ||
2660 | } else if (state == GET_ADDRESS) { | ||
2661 | valid = FALSE; | ||
2662 | p = get_one_address(p, &addr, &valid); | ||
2663 | // Quit on error or if the address is invalid and isn't of | ||
2664 | // the form ',$' or '1,' (in which case it defaults to dot). | ||
2665 | if (p == NULL || !(valid || *p == ',' || *p == ';' || *got & 1)) | ||
2666 | break; | ||
2667 | *b = *e; | ||
2668 | *e = addr; | ||
2669 | *got = (*got << 1) | 1; | ||
2640 | state = GET_SEPARATOR; | 2670 | state = GET_SEPARATOR; |
2641 | } else if (state == GET_SEPARATOR && (*p == ',' || *p == ';')) { | 2671 | } else if (state == GET_SEPARATOR && (*p == ',' || *p == ';')) { |
2642 | if (*p == ';') | 2672 | if (*p == ';') |
2643 | dot = find_line(*e); | 2673 | dot = find_line(*e); |
2644 | p++; | 2674 | p++; |
2645 | *b = *e; | ||
2646 | state = GET_ADDRESS; | 2675 | state = GET_ADDRESS; |
2647 | } else if (state == GET_ADDRESS) { | ||
2648 | p = get_one_address(p, e); | ||
2649 | if (p == NULL) | ||
2650 | break; | ||
2651 | state = GET_SEPARATOR; | ||
2652 | } else { | 2676 | } else { |
2653 | if (state == GET_SEPARATOR && *b >= 0 && *e < 0) | ||
2654 | *e = count_lines(text, dot); | ||
2655 | break; | 2677 | break; |
2656 | } | 2678 | } |
2657 | } | 2679 | } |
@@ -2865,9 +2887,14 @@ static void colon(char *buf) | |||
2865 | not_implemented(p); | 2887 | not_implemented(p); |
2866 | #else | 2888 | #else |
2867 | 2889 | ||
2890 | // check how many addresses we got | ||
2891 | # define GOT_ADDRESS (got & 1) | ||
2892 | # define GOT_RANGE ((got & 3) == 3) | ||
2893 | |||
2868 | char c, *buf1, *q, *r; | 2894 | char c, *buf1, *q, *r; |
2869 | char *fn, cmd[MAX_INPUT_LEN], *cmdend, *args, *exp = NULL; | 2895 | char *fn, cmd[MAX_INPUT_LEN], *cmdend, *args, *exp = NULL; |
2870 | int i, l, li, b, e; | 2896 | int i, l, li, b, e; |
2897 | unsigned int got; | ||
2871 | int useforce; | 2898 | int useforce; |
2872 | 2899 | ||
2873 | // :3154 // if (-e line 3154) goto it else stay put | 2900 | // :3154 // if (-e line 3154) goto it else stay put |
@@ -2894,14 +2921,13 @@ static void colon(char *buf) | |||
2894 | 2921 | ||
2895 | li = i = 0; | 2922 | li = i = 0; |
2896 | b = e = -1; | 2923 | b = e = -1; |
2924 | got = 0; | ||
2897 | li = count_lines(text, end - 1); | 2925 | li = count_lines(text, end - 1); |
2898 | fn = current_filename; | 2926 | fn = current_filename; |
2899 | 2927 | ||
2900 | // look for optional address(es) :. :1 :1,9 :'q,'a :% | 2928 | // look for optional address(es) :. :1 :1,9 :'q,'a :% |
2901 | buf1 = buf; | 2929 | buf = get_address(buf, &b, &e, &got); |
2902 | buf = get_address(buf, &b, &e); | ||
2903 | if (buf == NULL) { | 2930 | if (buf == NULL) { |
2904 | status_line_bold("Bad address: %s", buf1); | ||
2905 | goto ret; | 2931 | goto ret; |
2906 | } | 2932 | } |
2907 | 2933 | ||
@@ -2924,13 +2950,17 @@ static void colon(char *buf) | |||
2924 | } | 2950 | } |
2925 | // assume the command will want a range, certain commands | 2951 | // assume the command will want a range, certain commands |
2926 | // (read, substitute) need to adjust these assumptions | 2952 | // (read, substitute) need to adjust these assumptions |
2927 | if (e < 0) { | 2953 | if (!GOT_ADDRESS) { |
2928 | q = text; // no addr, use 1,$ for the range | 2954 | q = text; // no addr, use 1,$ for the range |
2929 | r = end - 1; | 2955 | r = end - 1; |
2930 | } else { | 2956 | } else { |
2931 | // at least one addr was given, get its details | 2957 | // at least one addr was given, get its details |
2958 | if (e < 0 || e > li) { | ||
2959 | status_line_bold("Invalid range"); | ||
2960 | goto ret; | ||
2961 | } | ||
2932 | q = r = find_line(e); | 2962 | q = r = find_line(e); |
2933 | if (b < 0) { | 2963 | if (!GOT_RANGE) { |
2934 | // if there is only one addr, then it's the line | 2964 | // if there is only one addr, then it's the line |
2935 | // number of the single line the user wants. | 2965 | // number of the single line the user wants. |
2936 | // Reset the end pointer to the end of that line. | 2966 | // Reset the end pointer to the end of that line. |
@@ -2939,6 +2969,10 @@ static void colon(char *buf) | |||
2939 | } else { | 2969 | } else { |
2940 | // we were given two addrs. change the | 2970 | // we were given two addrs. change the |
2941 | // start pointer to the addr given by user. | 2971 | // start pointer to the addr given by user. |
2972 | if (b < 0 || b > li || b > e) { | ||
2973 | status_line_bold("Invalid range"); | ||
2974 | goto ret; | ||
2975 | } | ||
2942 | q = find_line(b); // what line is #b | 2976 | q = find_line(b); // what line is #b |
2943 | r = end_line(r); | 2977 | r = end_line(r); |
2944 | li = e - b + 1; | 2978 | li = e - b + 1; |
@@ -2969,12 +3003,12 @@ static void colon(char *buf) | |||
2969 | } | 3003 | } |
2970 | # endif | 3004 | # endif |
2971 | else if (cmd[0] == '=' && !cmd[1]) { // where is the address | 3005 | else if (cmd[0] == '=' && !cmd[1]) { // where is the address |
2972 | if (e < 0) { // no addr given- use defaults | 3006 | if (!GOT_ADDRESS) { // no addr given- use defaults |
2973 | e = count_lines(text, dot); | 3007 | e = count_lines(text, dot); |
2974 | } | 3008 | } |
2975 | status_line("%d", e); | 3009 | status_line("%d", e); |
2976 | } else if (strncmp(cmd, "delete", i) == 0) { // delete lines | 3010 | } else if (strncmp(cmd, "delete", i) == 0) { // delete lines |
2977 | if (e < 0) { // no addr given- use defaults | 3011 | if (!GOT_ADDRESS) { // no addr given- use defaults |
2978 | q = begin_line(dot); // assume .,. for the range | 3012 | q = begin_line(dot); // assume .,. for the range |
2979 | r = end_line(dot); | 3013 | r = end_line(dot); |
2980 | } | 3014 | } |
@@ -3046,7 +3080,7 @@ static void colon(char *buf) | |||
3046 | rawmode(); | 3080 | rawmode(); |
3047 | Hit_Return(); | 3081 | Hit_Return(); |
3048 | } else if (strncmp(cmd, "list", i) == 0) { // literal print line | 3082 | } else if (strncmp(cmd, "list", i) == 0) { // literal print line |
3049 | if (e < 0) { // no addr given- use defaults | 3083 | if (!GOT_ADDRESS) { // no addr given- use defaults |
3050 | q = begin_line(dot); // assume .,. for the range | 3084 | q = begin_line(dot); // assume .,. for the range |
3051 | r = end_line(dot); | 3085 | r = end_line(dot); |
3052 | } | 3086 | } |
@@ -3129,7 +3163,7 @@ static void colon(char *buf) | |||
3129 | if (e == 0) { // user said ":0r foo" | 3163 | if (e == 0) { // user said ":0r foo" |
3130 | q = text; | 3164 | q = text; |
3131 | } else { // read after given line or current line if none given | 3165 | } else { // read after given line or current line if none given |
3132 | q = next_line(e > 0 ? find_line(e) : dot); | 3166 | q = next_line(GOT_ADDRESS ? find_line(e) : dot); |
3133 | // read after last line | 3167 | // read after last line |
3134 | if (q == end-1) | 3168 | if (q == end-1) |
3135 | ++q; | 3169 | ++q; |
@@ -3250,11 +3284,11 @@ static void colon(char *buf) | |||
3250 | len_F = strlen(F); | 3284 | len_F = strlen(F); |
3251 | } | 3285 | } |
3252 | 3286 | ||
3253 | if (e < 0) { // no addr given | 3287 | if (!GOT_ADDRESS) { // no addr given |
3254 | q = begin_line(dot); // start with cur line | 3288 | q = begin_line(dot); // start with cur line |
3255 | r = end_line(dot); | 3289 | r = end_line(dot); |
3256 | b = e = count_lines(text, q); // cur line number | 3290 | b = e = count_lines(text, q); // cur line number |
3257 | } else if (b < 0) { // one addr given | 3291 | } else if (!GOT_RANGE) { // one addr given |
3258 | b = e; | 3292 | b = e; |
3259 | } | 3293 | } |
3260 | 3294 | ||
@@ -3425,7 +3459,7 @@ static void colon(char *buf) | |||
3425 | } | 3459 | } |
3426 | # if ENABLE_FEATURE_VI_YANKMARK | 3460 | # if ENABLE_FEATURE_VI_YANKMARK |
3427 | } else if (strncmp(cmd, "yank", i) == 0) { // yank lines | 3461 | } else if (strncmp(cmd, "yank", i) == 0) { // yank lines |
3428 | if (b < 0) { // no addr given- use defaults | 3462 | if (!GOT_ADDRESS) { // no addr given- use defaults |
3429 | q = begin_line(dot); // assume .,. for the range | 3463 | q = begin_line(dot); // assume .,. for the range |
3430 | r = end_line(dot); | 3464 | r = end_line(dot); |
3431 | } | 3465 | } |
diff --git a/findutils/grep.c b/findutils/grep.c index be4362ed0..8600d72fa 100644 --- a/findutils/grep.c +++ b/findutils/grep.c | |||
@@ -83,7 +83,7 @@ | |||
83 | //usage: "\n -F PATTERN is a literal (not regexp)" | 83 | //usage: "\n -F PATTERN is a literal (not regexp)" |
84 | //usage: "\n -E PATTERN is an extended regexp" | 84 | //usage: "\n -E PATTERN is an extended regexp" |
85 | //usage: IF_EXTRA_COMPAT( | 85 | //usage: IF_EXTRA_COMPAT( |
86 | //usage: "\n -z Input is NUL terminated" | 86 | //usage: "\n -z NUL terminated input" |
87 | //usage: ) | 87 | //usage: ) |
88 | //usage: "\n -m N Match up to N times per file" | 88 | //usage: "\n -m N Match up to N times per file" |
89 | //usage: IF_FEATURE_GREP_CONTEXT( | 89 | //usage: IF_FEATURE_GREP_CONTEXT( |
diff --git a/findutils/xargs.c b/findutils/xargs.c index 1f8d95168..a0ba89c1e 100644 --- a/findutils/xargs.c +++ b/findutils/xargs.c | |||
@@ -623,7 +623,7 @@ static int xargs_ask_confirmation(void) | |||
623 | //usage:#define xargs_full_usage "\n\n" | 623 | //usage:#define xargs_full_usage "\n\n" |
624 | //usage: "Run PROG on every item given by stdin\n" | 624 | //usage: "Run PROG on every item given by stdin\n" |
625 | //usage: IF_FEATURE_XARGS_SUPPORT_ZERO_TERM( | 625 | //usage: IF_FEATURE_XARGS_SUPPORT_ZERO_TERM( |
626 | //usage: "\n -0 Input is separated by NULs" | 626 | //usage: "\n -0 NUL terminated input" |
627 | //usage: ) | 627 | //usage: ) |
628 | //usage: IF_FEATURE_XARGS_SUPPORT_ARGS_FILE( | 628 | //usage: IF_FEATURE_XARGS_SUPPORT_ARGS_FILE( |
629 | //usage: "\n -a FILE Read from FILE instead of stdin" | 629 | //usage: "\n -a FILE Read from FILE instead of stdin" |
diff --git a/util-linux/mount.c b/util-linux/mount.c index 831dab9e2..44afdbcff 100644 --- a/util-linux/mount.c +++ b/util-linux/mount.c | |||
@@ -562,9 +562,9 @@ static void append_mount_options(char **oldopts, const char *newopts) | |||
562 | // Do not insert options which are already there | 562 | // Do not insert options which are already there |
563 | while (newopts[0]) { | 563 | while (newopts[0]) { |
564 | char *p; | 564 | char *p; |
565 | int len = strlen(newopts); | 565 | int len; |
566 | p = strchr(newopts, ','); | 566 | |
567 | if (p) len = p - newopts; | 567 | len = strchrnul(newopts, ',') - newopts; |
568 | p = *oldopts; | 568 | p = *oldopts; |
569 | while (1) { | 569 | while (1) { |
570 | if (!strncmp(p, newopts, len) | 570 | if (!strncmp(p, newopts, len) |
@@ -579,7 +579,7 @@ static void append_mount_options(char **oldopts, const char *newopts) | |||
579 | *oldopts = p; | 579 | *oldopts = p; |
580 | skip: | 580 | skip: |
581 | newopts += len; | 581 | newopts += len; |
582 | while (newopts[0] == ',') newopts++; | 582 | while (*newopts == ',') newopts++; |
583 | } | 583 | } |
584 | } else { | 584 | } else { |
585 | if (ENABLE_FEATURE_CLEAN_UP) free(*oldopts); | 585 | if (ENABLE_FEATURE_CLEAN_UP) free(*oldopts); |
@@ -713,10 +713,12 @@ static int mount_it_now(struct mntent *mp, unsigned long vfsflags, char *filtero | |||
713 | errno = 0; | 713 | errno = 0; |
714 | rc = verbose_mount(mp->mnt_fsname, mp->mnt_dir, mp->mnt_type, | 714 | rc = verbose_mount(mp->mnt_fsname, mp->mnt_dir, mp->mnt_type, |
715 | vfsflags, filteropts); | 715 | vfsflags, filteropts); |
716 | if (rc == 0) | ||
717 | goto mtab; // success | ||
716 | 718 | ||
717 | // If mount failed, try | 719 | // mount failed, try helper program |
718 | // helper program mount.<mnt_type> | 720 | // mount.<mnt_type> |
719 | if (HELPERS_ALLOWED && rc && mp->mnt_type) { | 721 | if (HELPERS_ALLOWED && mp->mnt_type) { |
720 | char *args[8]; | 722 | char *args[8]; |
721 | int errno_save = errno; | 723 | int errno_save = errno; |
722 | args[0] = xasprintf("mount.%s", mp->mnt_type); | 724 | args[0] = xasprintf("mount.%s", mp->mnt_type); |
@@ -734,13 +736,19 @@ static int mount_it_now(struct mntent *mp, unsigned long vfsflags, char *filtero | |||
734 | args[rc] = NULL; | 736 | args[rc] = NULL; |
735 | rc = spawn_and_wait(args); | 737 | rc = spawn_and_wait(args); |
736 | free(args[0]); | 738 | free(args[0]); |
737 | if (!rc) | 739 | if (rc == 0) |
738 | break; | 740 | goto mtab; // success |
739 | errno = errno_save; | 741 | errno = errno_save; |
740 | } | 742 | } |
741 | 743 | ||
742 | if (!rc || (vfsflags & MS_RDONLY) || (errno != EACCES && errno != EROFS)) | 744 | // Should we retry read-only mount? |
743 | break; | 745 | if (vfsflags & MS_RDONLY) |
746 | break; // no, already was tried | ||
747 | if (option_mask32 & OPT_w) | ||
748 | break; // no, "mount -w" never falls back to RO | ||
749 | if (errno != EACCES && errno != EROFS) | ||
750 | break; // no, error isn't hinting that RO may work | ||
751 | |||
744 | if (!(vfsflags & MS_SILENT)) | 752 | if (!(vfsflags & MS_SILENT)) |
745 | bb_error_msg("%s is write-protected, mounting read-only", | 753 | bb_error_msg("%s is write-protected, mounting read-only", |
746 | mp->mnt_fsname); | 754 | mp->mnt_fsname); |