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); |
