diff options
author | Ron Yorston <rmy@pobox.com> | 2022-10-12 10:43:26 +0100 |
---|---|---|
committer | Ron Yorston <rmy@pobox.com> | 2022-10-12 10:43:26 +0100 |
commit | 49c6f079acb4edae84b4496bd941cdbb5048ba01 (patch) | |
tree | ac54ecaad45050f7bfe274a11db29882aa32a9a8 | |
parent | a55cf07365ec2ff51749a77e09ae9edac79a99fe (diff) | |
parent | c8c1fcdba163f264a503380bc63485aacd09214c (diff) | |
download | busybox-w32-49c6f079acb4edae84b4496bd941cdbb5048ba01.tar.gz busybox-w32-49c6f079acb4edae84b4496bd941cdbb5048ba01.tar.bz2 busybox-w32-49c6f079acb4edae84b4496bd941cdbb5048ba01.zip |
Merge branch 'busybox' into merge
46 files changed, 678 insertions, 186 deletions
@@ -181,3 +181,6 @@ Jie Zhang <jie.zhang@analog.com> | |||
181 | 181 | ||
182 | Maxime Coste <mawww@kakoune.org> | 182 | Maxime Coste <mawww@kakoune.org> |
183 | paste implementation | 183 | paste implementation |
184 | |||
185 | Roger Knecht <rknecht@pm.me> | ||
186 | tree | ||
diff --git a/archival/dpkg.c b/archival/dpkg.c index 8e1f9431d..a6a8333a8 100644 --- a/archival/dpkg.c +++ b/archival/dpkg.c | |||
@@ -1120,7 +1120,7 @@ static int check_deps(deb_file_t **deb_file, int deb_start /*, int dep_max_count | |||
1120 | if (package_edge->type == EDGE_PRE_DEPENDS | 1120 | if (package_edge->type == EDGE_PRE_DEPENDS |
1121 | || package_edge->type == EDGE_DEPENDS | 1121 | || package_edge->type == EDGE_DEPENDS |
1122 | ) { | 1122 | ) { |
1123 | int result=1; | 1123 | int result = 1; |
1124 | status_num = 0; | 1124 | status_num = 0; |
1125 | 1125 | ||
1126 | /* If we are inside an alternative then check | 1126 | /* If we are inside an alternative then check |
diff --git a/coreutils/cut.c b/coreutils/cut.c index 7009e74cf..55bdd9386 100644 --- a/coreutils/cut.c +++ b/coreutils/cut.c | |||
@@ -167,7 +167,7 @@ static void cut_file(FILE *file, const char *delim, const char *odelim, | |||
167 | if (!cl_pos && !dcount && !shoe) { | 167 | if (!cl_pos && !dcount && !shoe) { |
168 | if (option_mask32 & CUT_OPT_SUPPRESS_FLGS) | 168 | if (option_mask32 & CUT_OPT_SUPPRESS_FLGS) |
169 | goto next_line; | 169 | goto next_line; |
170 | } else if (dcount<cut_lists[cl_pos].startpos) | 170 | } else if (dcount < cut_lists[cl_pos].startpos) |
171 | start = linelen; | 171 | start = linelen; |
172 | end = linelen; | 172 | end = linelen; |
173 | } else { | 173 | } else { |
diff --git a/coreutils/md5_sha1_sum.c b/coreutils/md5_sha1_sum.c index 0e57673f1..b4bdc262c 100644 --- a/coreutils/md5_sha1_sum.c +++ b/coreutils/md5_sha1_sum.c | |||
@@ -301,9 +301,7 @@ int md5_sha1_sum_main(int argc UNUSED_PARAM, char **argv) | |||
301 | 301 | ||
302 | count_total++; | 302 | count_total++; |
303 | filename_ptr = strchr(line, ' '); | 303 | filename_ptr = strchr(line, ' '); |
304 | if (filename_ptr == NULL | 304 | if (!filename_ptr) { |
305 | || (filename_ptr[1] != ' ' && filename_ptr[1] != '*') | ||
306 | ) { | ||
307 | if (flags & FLAG_WARN) { | 305 | if (flags & FLAG_WARN) { |
308 | bb_simple_error_msg("invalid format"); | 306 | bb_simple_error_msg("invalid format"); |
309 | } | 307 | } |
@@ -312,8 +310,13 @@ int md5_sha1_sum_main(int argc UNUSED_PARAM, char **argv) | |||
312 | free(line); | 310 | free(line); |
313 | continue; | 311 | continue; |
314 | } | 312 | } |
315 | *filename_ptr = '\0'; | 313 | *filename_ptr++ = '\0'; |
316 | filename_ptr += 2; | 314 | /* coreutils 9.1 allows "HASH FILENAME" format, |
315 | * with only one space. Skip the 'correct' | ||
316 | * " " or " *" delimiter if it is there: | ||
317 | */ | ||
318 | if (*filename_ptr == ' ' || *filename_ptr == '*') | ||
319 | filename_ptr++; | ||
317 | 320 | ||
318 | hash_value = hash_file(in_buf, filename_ptr, sha3_width); | 321 | hash_value = hash_file(in_buf, filename_ptr, sha3_width); |
319 | 322 | ||
diff --git a/coreutils/sleep.c b/coreutils/sleep.c index 2658e84df..442841210 100644 --- a/coreutils/sleep.c +++ b/coreutils/sleep.c | |||
@@ -37,6 +37,7 @@ | |||
37 | //applet:IF_SLEEP(APPLET(sleep, BB_DIR_BIN, BB_SUID_DROP)) | 37 | //applet:IF_SLEEP(APPLET(sleep, BB_DIR_BIN, BB_SUID_DROP)) |
38 | 38 | ||
39 | //kbuild:lib-$(CONFIG_SLEEP) += sleep.o | 39 | //kbuild:lib-$(CONFIG_SLEEP) += sleep.o |
40 | //kbuild:lib-$(CONFIG_ASH_SLEEP) += sleep.o | ||
40 | 41 | ||
41 | /* BB_AUDIT SUSv3 compliant */ | 42 | /* BB_AUDIT SUSv3 compliant */ |
42 | /* BB_AUDIT GNU issues -- fancy version matches except args must be ints. */ | 43 | /* BB_AUDIT GNU issues -- fancy version matches except args must be ints. */ |
diff --git a/coreutils/sort.c b/coreutils/sort.c index 9aac656fe..01b7c44e5 100644 --- a/coreutils/sort.c +++ b/coreutils/sort.c | |||
@@ -357,9 +357,9 @@ static int compare_keys(const void *xarg, const void *yarg) | |||
357 | int dx; | 357 | int dx; |
358 | char *xx, *yy; | 358 | char *xx, *yy; |
359 | 359 | ||
360 | xx = strptime(x, "%b", &thyme); | 360 | xx = strptime(skip_whitespace(x), "%b", &thyme); |
361 | dx = thyme.tm_mon; | 361 | dx = thyme.tm_mon; |
362 | yy = strptime(y, "%b", &thyme); | 362 | yy = strptime(skip_whitespace(y), "%b", &thyme); |
363 | if (!xx) | 363 | if (!xx) |
364 | retval = (!yy) ? 0 : -1; | 364 | retval = (!yy) ? 0 : -1; |
365 | else if (!yy) | 365 | else if (!yy) |
@@ -652,11 +652,12 @@ int sort_main(int argc UNUSED_PARAM, char **argv) | |||
652 | /* Handle -u */ | 652 | /* Handle -u */ |
653 | if (option_mask32 & FLAG_u) { | 653 | if (option_mask32 & FLAG_u) { |
654 | int j = 0; | 654 | int j = 0; |
655 | /* coreutils 6.3 drop lines for which only key is the same | 655 | /* coreutils 6.3 drop lines for which only key is the same: |
656 | * -- disabling last-resort compare, or else compare_keys() | 656 | * - disabling last-resort compare, or else compare_keys() |
657 | * will be the same only for completely identical lines. | 657 | * will be the same only for completely identical lines |
658 | * - disabling -s (same reasons) | ||
658 | */ | 659 | */ |
659 | option_mask32 |= FLAG_no_tie_break; | 660 | option_mask32 = (option_mask32 | FLAG_no_tie_break) & (~FLAG_s); |
660 | for (i = 1; i < linecount; i++) { | 661 | for (i = 1; i < linecount; i++) { |
661 | if (compare_keys(&lines[j], &lines[i]) == 0) | 662 | if (compare_keys(&lines[j], &lines[i]) == 0) |
662 | free(lines[i]); | 663 | free(lines[i]); |
diff --git a/coreutils/test.c b/coreutils/test.c index 840a0daaf..1d1e6d18b 100644 --- a/coreutils/test.c +++ b/coreutils/test.c | |||
@@ -859,7 +859,7 @@ static number_t primary(enum token n) | |||
859 | if (check_operator(args[1]) != EOI) { /* if args[1] != NULL */ | 859 | if (check_operator(args[1]) != EOI) { /* if args[1] != NULL */ |
860 | if (args[2]) { | 860 | if (args[2]) { |
861 | // coreutils also does this: | 861 | // coreutils also does this: |
862 | // if (args[3] && args[0]="-l" && args[2] is BINOP) | 862 | // if (args[3] && args[0] = "-l" && args[2] is BINOP) |
863 | // return binop(1 /* prepended by -l */); | 863 | // return binop(1 /* prepended by -l */); |
864 | if (last_operator->op_type == BINOP) | 864 | if (last_operator->op_type == BINOP) |
865 | unnest_msg_and_return(binop(), "<primary: binop:%lld\n"); | 865 | unnest_msg_and_return(binop(), "<primary: binop:%lld\n"); |
diff --git a/editors/awk.c b/editors/awk.c index 9b4d4dc3d..eedb7aa84 100644 --- a/editors/awk.c +++ b/editors/awk.c | |||
@@ -3147,6 +3147,9 @@ static var *evaluate(node *op, var *res) | |||
3147 | 3147 | ||
3148 | case XC( OC_MOVE ): | 3148 | case XC( OC_MOVE ): |
3149 | debug_printf_eval("MOVE\n"); | 3149 | debug_printf_eval("MOVE\n"); |
3150 | /* make sure that we never return a temp var */ | ||
3151 | if (L.v == TMPVAR0) | ||
3152 | L.v = res; | ||
3150 | /* if source is a temporary string, jusk relink it to dest */ | 3153 | /* if source is a temporary string, jusk relink it to dest */ |
3151 | if (R.v == TMPVAR1 | 3154 | if (R.v == TMPVAR1 |
3152 | && !(R.v->type & VF_NUMBER) | 3155 | && !(R.v->type & VF_NUMBER) |
diff --git a/editors/patch.c b/editors/patch.c index aebb5073e..f90d6854d 100644 --- a/editors/patch.c +++ b/editors/patch.c | |||
@@ -138,9 +138,9 @@ static void do_line(void *data) | |||
138 | { | 138 | { |
139 | struct double_list *dlist = data; | 139 | struct double_list *dlist = data; |
140 | 140 | ||
141 | if (TT.state>1 && *dlist->data != TT.state) | 141 | if (TT.state > 1 && *dlist->data != TT.state) |
142 | fdprintf(TT.state == 2 ? 2 : TT.fileout, | 142 | fdprintf(TT.state == 2 ? 2 : TT.fileout, |
143 | "%s\n", dlist->data+(TT.state>3 ? 1 : 0)); | 143 | "%s\n", dlist->data + (TT.state > 3 ? 1 : 0)); |
144 | 144 | ||
145 | if (PATCH_DEBUG) fdprintf(2, "DO %d: %s\n", TT.state, dlist->data); | 145 | if (PATCH_DEBUG) fdprintf(2, "DO %d: %s\n", TT.state, dlist->data); |
146 | 146 | ||
@@ -221,7 +221,7 @@ static int apply_one_hunk(void) | |||
221 | 221 | ||
222 | // Match EOF if there aren't as many ending context lines as beginning | 222 | // Match EOF if there aren't as many ending context lines as beginning |
223 | for (plist = TT.current_hunk; plist; plist = plist->next) { | 223 | for (plist = TT.current_hunk; plist; plist = plist->next) { |
224 | if (plist->data[0]==' ') matcheof++; | 224 | if (plist->data[0] == ' ') matcheof++; |
225 | else matcheof = 0; | 225 | else matcheof = 0; |
226 | if (PATCH_DEBUG) fdprintf(2, "HUNK:%s\n", plist->data); | 226 | if (PATCH_DEBUG) fdprintf(2, "HUNK:%s\n", plist->data); |
227 | } | 227 | } |
@@ -433,15 +433,15 @@ int patch_main(int argc UNUSED_PARAM, char **argv) | |||
433 | 433 | ||
434 | // Are we assembling a hunk? | 434 | // Are we assembling a hunk? |
435 | if (state >= 2) { | 435 | if (state >= 2) { |
436 | if (*patchline==' ' || *patchline=='+' || *patchline=='-') { | 436 | if (*patchline == ' ' || *patchline == '+' || *patchline == '-') { |
437 | dlist_add(&TT.current_hunk, patchline); | 437 | dlist_add(&TT.current_hunk, patchline); |
438 | 438 | ||
439 | if (*patchline != '+') oldlen--; | 439 | if (*patchline != '+') oldlen--; |
440 | if (*patchline != '-') newlen--; | 440 | if (*patchline != '-') newlen--; |
441 | 441 | ||
442 | // Context line? | 442 | // Context line? |
443 | if (*patchline==' ' && state==2) TT.context++; | 443 | if (*patchline == ' ' && state == 2) TT.context++; |
444 | else state=3; | 444 | else state = 3; |
445 | 445 | ||
446 | // If we've consumed all expected hunk lines, apply the hunk. | 446 | // If we've consumed all expected hunk lines, apply the hunk. |
447 | 447 | ||
@@ -469,9 +469,9 @@ int patch_main(int argc UNUSED_PARAM, char **argv) | |||
469 | free(*name); | 469 | free(*name); |
470 | // Trim date from end of filename (if any). We don't care. | 470 | // Trim date from end of filename (if any). We don't care. |
471 | for (s = patchline+4; *s && *s!='\t'; s++) | 471 | for (s = patchline+4; *s && *s!='\t'; s++) |
472 | if (*s=='\\' && s[1]) s++; | 472 | if (*s == '\\' && s[1]) s++; |
473 | i = atoi(s); | 473 | i = atoi(s); |
474 | if (i>1900 && i<=1970) | 474 | if (i > 1900 && i <= 1970) |
475 | *name = xstrdup("/dev/null"); | 475 | *name = xstrdup("/dev/null"); |
476 | else { | 476 | else { |
477 | *s = 0; | 477 | *s = 0; |
diff --git a/editors/patch_toybox.c b/editors/patch_toybox.c index 69a508b2e..5478ece7d 100644 --- a/editors/patch_toybox.c +++ b/editors/patch_toybox.c | |||
@@ -79,7 +79,7 @@ void TOY_llist_free(void *list, void (*freeit)(void *data)) | |||
79 | else free(pop); | 79 | else free(pop); |
80 | 80 | ||
81 | // End doubly linked list too. | 81 | // End doubly linked list too. |
82 | if (list==pop) break; | 82 | if (list == pop) break; |
83 | } | 83 | } |
84 | } | 84 | } |
85 | 85 | ||
@@ -137,11 +137,11 @@ char *get_rawline(int fd, long *plen, char end) | |||
137 | long len = 0; | 137 | long len = 0; |
138 | 138 | ||
139 | for (;;) { | 139 | for (;;) { |
140 | if (1>read(fd, &c, 1)) break; | 140 | if (1 > read(fd, &c, 1)) break; |
141 | if (!(len & 63)) buf=xrealloc(buf, len+65); | 141 | if (!(len & 63)) buf=xrealloc(buf, len+65); |
142 | if ((buf[len++]=c) == end) break; | 142 | if ((buf[len++] = c) == end) break; |
143 | } | 143 | } |
144 | if (buf) buf[len]=0; | 144 | if (buf) buf[len] = 0; |
145 | if (plen) *plen = len; | 145 | if (plen) *plen = len; |
146 | 146 | ||
147 | return buf; | 147 | return buf; |
@@ -153,7 +153,7 @@ char *get_line(int fd) | |||
153 | long len; | 153 | long len; |
154 | char *buf = get_rawline(fd, &len, '\n'); | 154 | char *buf = get_rawline(fd, &len, '\n'); |
155 | 155 | ||
156 | if (buf && buf[--len]=='\n') buf[len]=0; | 156 | if (buf && buf[--len] == '\n') buf[len] = 0; |
157 | 157 | ||
158 | return buf; | 158 | return buf; |
159 | } | 159 | } |
@@ -165,10 +165,10 @@ void xsendfile(int in, int out) | |||
165 | long len; | 165 | long len; |
166 | char buf[4096]; | 166 | char buf[4096]; |
167 | 167 | ||
168 | if (in<0) return; | 168 | if (in < 0) return; |
169 | for (;;) { | 169 | for (;;) { |
170 | len = safe_read(in, buf, 4096); | 170 | len = safe_read(in, buf, 4096); |
171 | if (len<1) break; | 171 | if (len < 1) break; |
172 | xwrite(out, buf, len); | 172 | xwrite(out, buf, len); |
173 | } | 173 | } |
174 | } | 174 | } |
@@ -179,7 +179,7 @@ void replace_tempfile(int fdin, int fdout, char **tempname) | |||
179 | { | 179 | { |
180 | char *temp = xstrdup(*tempname); | 180 | char *temp = xstrdup(*tempname); |
181 | 181 | ||
182 | temp[strlen(temp)-6]=0; | 182 | temp[strlen(temp)-6] = 0; |
183 | if (fdin != -1) { | 183 | if (fdin != -1) { |
184 | xsendfile(fdin, fdout); | 184 | xsendfile(fdin, fdout); |
185 | xclose(fdin); | 185 | xclose(fdin); |
@@ -263,9 +263,9 @@ static void do_line(void *data) | |||
263 | { | 263 | { |
264 | struct double_list *dlist = (struct double_list *)data; | 264 | struct double_list *dlist = (struct double_list *)data; |
265 | 265 | ||
266 | if (TT.state>1 && *dlist->data != TT.state) | 266 | if (TT.state > 1 && *dlist->data != TT.state) |
267 | fdprintf(TT.state == 2 ? 2 : TT.fileout, | 267 | fdprintf(TT.state == 2 ? 2 : TT.fileout, |
268 | "%s\n", dlist->data+(TT.state>3 ? 1 : 0)); | 268 | "%s\n", dlist->data + (TT.state > 3 ? 1 : 0)); |
269 | 269 | ||
270 | if (PATCH_DEBUG) fdprintf(2, "DO %d: %s\n", TT.state, dlist->data); | 270 | if (PATCH_DEBUG) fdprintf(2, "DO %d: %s\n", TT.state, dlist->data); |
271 | 271 | ||
@@ -314,7 +314,7 @@ static int apply_one_hunk(void) | |||
314 | 314 | ||
315 | // Match EOF if there aren't as many ending context lines as beginning | 315 | // Match EOF if there aren't as many ending context lines as beginning |
316 | for (plist = TT.current_hunk; plist; plist = plist->next) { | 316 | for (plist = TT.current_hunk; plist; plist = plist->next) { |
317 | if (plist->data[0]==' ') matcheof++; | 317 | if (plist->data[0] == ' ') matcheof++; |
318 | else matcheof = 0; | 318 | else matcheof = 0; |
319 | if (PATCH_DEBUG) fdprintf(2, "HUNK:%s\n", plist->data); | 319 | if (PATCH_DEBUG) fdprintf(2, "HUNK:%s\n", plist->data); |
320 | } | 320 | } |
@@ -385,7 +385,7 @@ static int apply_one_hunk(void) | |||
385 | 385 | ||
386 | // If we've reached the end of the buffer without confirming a | 386 | // If we've reached the end of the buffer without confirming a |
387 | // match, read more lines. | 387 | // match, read more lines. |
388 | if (check==buf) { | 388 | if (check == buf) { |
389 | buf = 0; | 389 | buf = 0; |
390 | break; | 390 | break; |
391 | } | 391 | } |
@@ -456,15 +456,15 @@ int patch_main(int argc UNUSED_PARAM, char **argv) | |||
456 | 456 | ||
457 | // Are we assembling a hunk? | 457 | // Are we assembling a hunk? |
458 | if (state >= 2) { | 458 | if (state >= 2) { |
459 | if (*patchline==' ' || *patchline=='+' || *patchline=='-') { | 459 | if (*patchline == ' ' || *patchline == '+' || *patchline == '-') { |
460 | dlist_add(&TT.current_hunk, patchline); | 460 | dlist_add(&TT.current_hunk, patchline); |
461 | 461 | ||
462 | if (*patchline != '+') TT.oldlen--; | 462 | if (*patchline != '+') TT.oldlen--; |
463 | if (*patchline != '-') TT.newlen--; | 463 | if (*patchline != '-') TT.newlen--; |
464 | 464 | ||
465 | // Context line? | 465 | // Context line? |
466 | if (*patchline==' ' && state==2) TT.context++; | 466 | if (*patchline == ' ' && state == 2) TT.context++; |
467 | else state=3; | 467 | else state = 3; |
468 | 468 | ||
469 | // If we've consumed all expected hunk lines, apply the hunk. | 469 | // If we've consumed all expected hunk lines, apply the hunk. |
470 | 470 | ||
@@ -491,9 +491,9 @@ int patch_main(int argc UNUSED_PARAM, char **argv) | |||
491 | 491 | ||
492 | // Trim date from end of filename (if any). We don't care. | 492 | // Trim date from end of filename (if any). We don't care. |
493 | for (s = patchline+4; *s && *s!='\t'; s++) | 493 | for (s = patchline+4; *s && *s!='\t'; s++) |
494 | if (*s=='\\' && s[1]) s++; | 494 | if (*s == '\\' && s[1]) s++; |
495 | i = atoi(s); | 495 | i = atoi(s); |
496 | if (i>1900 && i<=1970) | 496 | if (i > 1900 && i <= 1970) |
497 | *name = xstrdup("/dev/null"); | 497 | *name = xstrdup("/dev/null"); |
498 | else { | 498 | else { |
499 | *s = 0; | 499 | *s = 0; |
@@ -537,7 +537,7 @@ int patch_main(int argc UNUSED_PARAM, char **argv) | |||
537 | // handle -p path truncation. | 537 | // handle -p path truncation. |
538 | for (i=0, s = name; *s;) { | 538 | for (i=0, s = name; *s;) { |
539 | if ((option_mask32 & FLAG_PATHLEN) && TT.prefix == i) break; | 539 | if ((option_mask32 & FLAG_PATHLEN) && TT.prefix == i) break; |
540 | if (*(s++)=='/') { | 540 | if (*(s++) == '/') { |
541 | name = s; | 541 | name = s; |
542 | i++; | 542 | i++; |
543 | } | 543 | } |
diff --git a/editors/vi.c b/editors/vi.c index b813747d1..574feb465 100644 --- a/editors/vi.c +++ b/editors/vi.c | |||
@@ -4480,8 +4480,14 @@ static void do_cmd(int c) | |||
4480 | goto dc_i; // start inserting | 4480 | goto dc_i; // start inserting |
4481 | break; | 4481 | break; |
4482 | case 'Z': // Z- if modified, {write}; exit | 4482 | case 'Z': // Z- if modified, {write}; exit |
4483 | // ZZ means to save file (if necessary), then exit | ||
4484 | c1 = get_one_char(); | 4483 | c1 = get_one_char(); |
4484 | // ZQ means to exit without saving | ||
4485 | if (c1 == 'Q') { | ||
4486 | editing = 0; | ||
4487 | optind = cmdline_filecnt; | ||
4488 | break; | ||
4489 | } | ||
4490 | // ZZ means to save file (if necessary), then exit | ||
4485 | if (c1 != 'Z') { | 4491 | if (c1 != 'Z') { |
4486 | indicate_error(); | 4492 | indicate_error(); |
4487 | break; | 4493 | break; |
diff --git a/examples/shutdown-1.0/script/hardshutdown.c b/examples/shutdown-1.0/script/hardshutdown.c index b4af26f0f..c90f55396 100644 --- a/examples/shutdown-1.0/script/hardshutdown.c +++ b/examples/shutdown-1.0/script/hardshutdown.c | |||
@@ -115,7 +115,7 @@ int main(int argc, char **argv) | |||
115 | if (ptr) | 115 | if (ptr) |
116 | prog = ptr+1; | 116 | prog = ptr+1; |
117 | 117 | ||
118 | for (c=1; c < argc; c++) { | 118 | for (c = 1; c < argc; c++) { |
119 | if (argv[c][0] >= '0' && argv[c][0] <= '9') { | 119 | if (argv[c][0] >= '0' && argv[c][0] <= '9') { |
120 | t.tv_sec = strtol(argv[c], NULL, 10); | 120 | t.tv_sec = strtol(argv[c], NULL, 10); |
121 | continue; | 121 | continue; |
@@ -124,7 +124,7 @@ int main(int argc, char **argv) | |||
124 | usage(); | 124 | usage(); |
125 | return 1; | 125 | return 1; |
126 | } | 126 | } |
127 | for (i=1; argv[c][i]; i++) { | 127 | for (i = 1; argv[c][i]; i++) { |
128 | switch (argv[c][i]) { | 128 | switch (argv[c][i]) { |
129 | case 'h': | 129 | case 'h': |
130 | action = HALT; | 130 | action = HALT; |
diff --git a/include/libbb.h b/include/libbb.h index c5691c76d..1b1e5cab1 100644 --- a/include/libbb.h +++ b/include/libbb.h | |||
@@ -1568,6 +1568,7 @@ int ash_main(int argc, char** argv) IF_SHELL_ASH(MAIN_EXTERNALLY_VISIBLE); | |||
1568 | int hush_main(int argc, char** argv) IF_SHELL_HUSH(MAIN_EXTERNALLY_VISIBLE); | 1568 | int hush_main(int argc, char** argv) IF_SHELL_HUSH(MAIN_EXTERNALLY_VISIBLE); |
1569 | /* If shell needs them, they exist even if not enabled as applets */ | 1569 | /* If shell needs them, they exist even if not enabled as applets */ |
1570 | int echo_main(int argc, char** argv) IF_ECHO(MAIN_EXTERNALLY_VISIBLE); | 1570 | int echo_main(int argc, char** argv) IF_ECHO(MAIN_EXTERNALLY_VISIBLE); |
1571 | int sleep_main(int argc, char **argv) IF_SLEEP(MAIN_EXTERNALLY_VISIBLE); | ||
1571 | int printf_main(int argc, char **argv) IF_PRINTF(MAIN_EXTERNALLY_VISIBLE); | 1572 | int printf_main(int argc, char **argv) IF_PRINTF(MAIN_EXTERNALLY_VISIBLE); |
1572 | int test_main(int argc, char **argv) | 1573 | int test_main(int argc, char **argv) |
1573 | #if ENABLE_TEST || ENABLE_TEST1 || ENABLE_TEST2 | 1574 | #if ENABLE_TEST || ENABLE_TEST1 || ENABLE_TEST2 |
diff --git a/libbb/appletlib.c b/libbb/appletlib.c index 99f0cb89c..a90d0cdb5 100644 --- a/libbb/appletlib.c +++ b/libbb/appletlib.c | |||
@@ -319,7 +319,6 @@ void lbb_prepare(const char *applet | |||
319 | /* Redundant for busybox (run_applet_and_exit covers that case) | 319 | /* Redundant for busybox (run_applet_and_exit covers that case) |
320 | * but needed for "individual applet" mode */ | 320 | * but needed for "individual applet" mode */ |
321 | if (argv[1] | 321 | if (argv[1] |
322 | && !argv[2] | ||
323 | && strcmp(argv[1], "--help") == 0 | 322 | && strcmp(argv[1], "--help") == 0 |
324 | && !is_prefixed_with(applet, "busybox") | 323 | && !is_prefixed_with(applet, "busybox") |
325 | ) { | 324 | ) { |
@@ -1115,12 +1114,15 @@ void FAST_FUNC show_usage_if_dash_dash_help(int applet_no, char **argv) | |||
1115 | # if defined APPLET_NO_echo | 1114 | # if defined APPLET_NO_echo |
1116 | && applet_no != APPLET_NO_echo | 1115 | && applet_no != APPLET_NO_echo |
1117 | # endif | 1116 | # endif |
1117 | # if ENABLE_TEST1 || ENABLE_TEST2 | ||
1118 | && argv[0][0] != '[' /* exclude [ --help ] and [[ --help ]] too */ | ||
1119 | # endif | ||
1118 | # if ENABLE_PLATFORM_MINGW32 && defined APPLET_NO_busybox | 1120 | # if ENABLE_PLATFORM_MINGW32 && defined APPLET_NO_busybox |
1119 | && applet_no != APPLET_NO_busybox | 1121 | && applet_no != APPLET_NO_busybox |
1120 | # endif | 1122 | # endif |
1121 | ) { | 1123 | ) { |
1122 | if (argv[1] && !argv[2] && strcmp(argv[1], "--help") == 0) { | 1124 | if (argv[1] && strcmp(argv[1], "--help") == 0) { |
1123 | /* Make "foo --help" exit with 0: */ | 1125 | /* Make "foo --help [...]" exit with 0: */ |
1124 | xfunc_error_retval = 0; | 1126 | xfunc_error_retval = 0; |
1125 | bb_show_usage(); | 1127 | bb_show_usage(); |
1126 | } | 1128 | } |
diff --git a/libbb/duration.c b/libbb/duration.c index a6a29ddae..793d02f42 100644 --- a/libbb/duration.c +++ b/libbb/duration.c | |||
@@ -76,6 +76,12 @@ void FAST_FUNC sleep_for_duration(duration_t duration) | |||
76 | ts.tv_sec = duration; | 76 | ts.tv_sec = duration; |
77 | ts.tv_nsec = (duration - ts.tv_sec) * 1000000000; | 77 | ts.tv_nsec = (duration - ts.tv_sec) * 1000000000; |
78 | } | 78 | } |
79 | /* NB: if ENABLE_ASH_SLEEP, we end up here if "sleep N" | ||
80 | * is run in ash. ^C will still work, because ash's signal handler | ||
81 | * does not return (it longjumps), the below loop | ||
82 | * will not continue looping. | ||
83 | * (This wouldn't work in hush) | ||
84 | */ | ||
79 | do { | 85 | do { |
80 | errno = 0; | 86 | errno = 0; |
81 | nanosleep(&ts, &ts); | 87 | nanosleep(&ts, &ts); |
diff --git a/libbb/hash_md5_sha256_x86-32_shaNI.S b/libbb/hash_md5_sha256_x86-32_shaNI.S index 3905bad9a..a0e4a571a 100644 --- a/libbb/hash_md5_sha256_x86-32_shaNI.S +++ b/libbb/hash_md5_sha256_x86-32_shaNI.S | |||
@@ -19,6 +19,9 @@ | |||
19 | // We do not check SSSE3 in cpuid, | 19 | // We do not check SSSE3 in cpuid, |
20 | // all SHA-capable CPUs support it as well. | 20 | // all SHA-capable CPUs support it as well. |
21 | 21 | ||
22 | #ifdef __linux__ | ||
23 | .section .note.GNU-stack, "", @progbits | ||
24 | #endif | ||
22 | .section .text.sha256_process_block64_shaNI, "ax", @progbits | 25 | .section .text.sha256_process_block64_shaNI, "ax", @progbits |
23 | .globl sha256_process_block64_shaNI | 26 | .globl sha256_process_block64_shaNI |
24 | .hidden sha256_process_block64_shaNI | 27 | .hidden sha256_process_block64_shaNI |
diff --git a/libbb/hash_md5_sha256_x86-64_shaNI.S b/libbb/hash_md5_sha256_x86-64_shaNI.S index 082ceafe4..172c2eae2 100644 --- a/libbb/hash_md5_sha256_x86-64_shaNI.S +++ b/libbb/hash_md5_sha256_x86-64_shaNI.S | |||
@@ -19,6 +19,9 @@ | |||
19 | // We do not check SSSE3 in cpuid, | 19 | // We do not check SSSE3 in cpuid, |
20 | // all SHA-capable CPUs support it as well. | 20 | // all SHA-capable CPUs support it as well. |
21 | 21 | ||
22 | #ifdef __linux__ | ||
23 | .section .note.GNU-stack, "", @progbits | ||
24 | #endif | ||
22 | .section .text.sha256_process_block64_shaNI, "ax", @progbits | 25 | .section .text.sha256_process_block64_shaNI, "ax", @progbits |
23 | .globl sha256_process_block64_shaNI | 26 | .globl sha256_process_block64_shaNI |
24 | .hidden sha256_process_block64_shaNI | 27 | .hidden sha256_process_block64_shaNI |
diff --git a/libbb/hash_md5_sha_x86-32_shaNI.S b/libbb/hash_md5_sha_x86-32_shaNI.S index 2366b046a..7455a29f0 100644 --- a/libbb/hash_md5_sha_x86-32_shaNI.S +++ b/libbb/hash_md5_sha_x86-32_shaNI.S | |||
@@ -25,6 +25,9 @@ | |||
25 | // We do not check SSSE3/SSE4.1 in cpuid, | 25 | // We do not check SSSE3/SSE4.1 in cpuid, |
26 | // all SHA-capable CPUs support them as well. | 26 | // all SHA-capable CPUs support them as well. |
27 | 27 | ||
28 | #ifdef __linux__ | ||
29 | .section .note.GNU-stack, "", @progbits | ||
30 | #endif | ||
28 | .section .text.sha1_process_block64_shaNI, "ax", @progbits | 31 | .section .text.sha1_process_block64_shaNI, "ax", @progbits |
29 | .globl sha1_process_block64_shaNI | 32 | .globl sha1_process_block64_shaNI |
30 | .hidden sha1_process_block64_shaNI | 33 | .hidden sha1_process_block64_shaNI |
diff --git a/libbb/hash_md5_sha_x86-64.S b/libbb/hash_md5_sha_x86-64.S index 1d55b91f8..2cdd22015 100644 --- a/libbb/hash_md5_sha_x86-64.S +++ b/libbb/hash_md5_sha_x86-64.S | |||
@@ -1,6 +1,9 @@ | |||
1 | ### Generated by hash_md5_sha_x86-64.S.sh ### | 1 | ### Generated by hash_md5_sha_x86-64.S.sh ### |
2 | 2 | ||
3 | #if CONFIG_SHA1_SMALL == 0 && defined(__GNUC__) && defined(__x86_64__) | 3 | #if CONFIG_SHA1_SMALL == 0 && defined(__GNUC__) && defined(__x86_64__) |
4 | #ifdef __linux__ | ||
5 | .section .note.GNU-stack, "", @progbits | ||
6 | #endif | ||
4 | .section .text.sha1_process_block64, "ax", @progbits | 7 | .section .text.sha1_process_block64, "ax", @progbits |
5 | .globl sha1_process_block64 | 8 | .globl sha1_process_block64 |
6 | .hidden sha1_process_block64 | 9 | .hidden sha1_process_block64 |
diff --git a/libbb/hash_md5_sha_x86-64.S.sh b/libbb/hash_md5_sha_x86-64.S.sh index 40c979d35..653fe4989 100755 --- a/libbb/hash_md5_sha_x86-64.S.sh +++ b/libbb/hash_md5_sha_x86-64.S.sh | |||
@@ -127,6 +127,9 @@ echo \ | |||
127 | "### Generated by hash_md5_sha_x86-64.S.sh ### | 127 | "### Generated by hash_md5_sha_x86-64.S.sh ### |
128 | 128 | ||
129 | #if CONFIG_SHA1_SMALL == 0 && defined(__GNUC__) && defined(__x86_64__) | 129 | #if CONFIG_SHA1_SMALL == 0 && defined(__GNUC__) && defined(__x86_64__) |
130 | #ifdef __linux__ | ||
131 | .section .note.GNU-stack, \"\", @progbits | ||
132 | #endif | ||
130 | .section .text.sha1_process_block64, \"ax\", @progbits | 133 | .section .text.sha1_process_block64, \"ax\", @progbits |
131 | .globl sha1_process_block64 | 134 | .globl sha1_process_block64 |
132 | .hidden sha1_process_block64 | 135 | .hidden sha1_process_block64 |
diff --git a/libbb/hash_md5_sha_x86-64_shaNI.S b/libbb/hash_md5_sha_x86-64_shaNI.S index 794e97040..2f03e1ce4 100644 --- a/libbb/hash_md5_sha_x86-64_shaNI.S +++ b/libbb/hash_md5_sha_x86-64_shaNI.S | |||
@@ -25,6 +25,9 @@ | |||
25 | // We do not check SSSE3/SSE4.1 in cpuid, | 25 | // We do not check SSSE3/SSE4.1 in cpuid, |
26 | // all SHA-capable CPUs support them as well. | 26 | // all SHA-capable CPUs support them as well. |
27 | 27 | ||
28 | #ifdef __linux__ | ||
29 | .section .note.GNU-stack, "", @progbits | ||
30 | #endif | ||
28 | .section .text.sha1_process_block64_shaNI, "ax", @progbits | 31 | .section .text.sha1_process_block64_shaNI, "ax", @progbits |
29 | .globl sha1_process_block64_shaNI | 32 | .globl sha1_process_block64_shaNI |
30 | .hidden sha1_process_block64_shaNI | 33 | .hidden sha1_process_block64_shaNI |
diff --git a/libbb/lineedit.c b/libbb/lineedit.c index 6994d1da7..c5d5808f5 100644 --- a/libbb/lineedit.c +++ b/libbb/lineedit.c | |||
@@ -2154,7 +2154,13 @@ static void parse_and_put_prompt(const char *prmt_ptr) | |||
2154 | case 'W': /* basename of cur dir */ | 2154 | case 'W': /* basename of cur dir */ |
2155 | if (!cwd_buf) { | 2155 | if (!cwd_buf) { |
2156 | const char *home; | 2156 | const char *home; |
2157 | #if ENABLE_SHELL_ASH | ||
2158 | cwd_buf = state->sh_get_var | ||
2159 | ? xstrdup(state->sh_get_var("PWD")) | ||
2160 | : xrealloc_getcwd_or_warn(NULL); | ||
2161 | #else | ||
2157 | cwd_buf = xrealloc_getcwd_or_warn(NULL); | 2162 | cwd_buf = xrealloc_getcwd_or_warn(NULL); |
2163 | #endif | ||
2158 | if (!cwd_buf) | 2164 | if (!cwd_buf) |
2159 | cwd_buf = (char *)bb_msg_unknown; | 2165 | cwd_buf = (char *)bb_msg_unknown; |
2160 | else if ((home = get_homedir_or_NULL()) != NULL && home[0]) { | 2166 | else if ((home = get_homedir_or_NULL()) != NULL && home[0]) { |
diff --git a/miscutils/bc.c b/miscutils/bc.c index fe555d018..01402b311 100644 --- a/miscutils/bc.c +++ b/miscutils/bc.c | |||
@@ -2892,6 +2892,8 @@ static char peek_inbuf(void) | |||
2892 | ) { | 2892 | ) { |
2893 | xc_read_line(&G.input_buffer, G.prs.lex_input_fp); | 2893 | xc_read_line(&G.input_buffer, G.prs.lex_input_fp); |
2894 | G.prs.lex_inbuf = G.input_buffer.v; | 2894 | G.prs.lex_inbuf = G.input_buffer.v; |
2895 | // lex_next_at may point to now-freed data, update it: | ||
2896 | G.prs.lex_next_at = G.prs.lex_inbuf; | ||
2895 | if (G.input_buffer.len <= 1) // on EOF, len is 1 (NUL byte) | 2897 | if (G.input_buffer.len <= 1) // on EOF, len is 1 (NUL byte) |
2896 | G.prs.lex_input_fp = NULL; | 2898 | G.prs.lex_input_fp = NULL; |
2897 | } | 2899 | } |
@@ -3103,7 +3105,7 @@ static BC_STATUS zbc_lex_identifier(void) | |||
3103 | continue; | 3105 | continue; |
3104 | match: | 3106 | match: |
3105 | // buf starts with keyword bc_lex_kws[i] | 3107 | // buf starts with keyword bc_lex_kws[i] |
3106 | if (isalnum(buf[j]) || buf[j]=='_') | 3108 | if (isalnum(buf[j]) || buf[j] == '_') |
3107 | continue; // "ifz" does not match "if" keyword, "if." does | 3109 | continue; // "ifz" does not match "if" keyword, "if." does |
3108 | p->lex = BC_LEX_KEY_1st_keyword + i; | 3110 | p->lex = BC_LEX_KEY_1st_keyword + i; |
3109 | if (!keyword_is_POSIX(i)) { | 3111 | if (!keyword_is_POSIX(i)) { |
diff --git a/miscutils/devfsd.c b/miscutils/devfsd.c index fb9ebcf60..297693f8c 100644 --- a/miscutils/devfsd.c +++ b/miscutils/devfsd.c | |||
@@ -976,7 +976,7 @@ static void action_compat(const struct devfsd_notify_struct *info, unsigned int | |||
976 | rewind_ = info->devname[info->namelen - 1]; | 976 | rewind_ = info->devname[info->namelen - 1]; |
977 | if (rewind_ != 'n') | 977 | if (rewind_ != 'n') |
978 | rewind_ = '\0'; | 978 | rewind_ = '\0'; |
979 | mode=0; | 979 | mode = 0; |
980 | if (ptr[2] == 'l' /*108*/ || ptr[2] == 'm'/*109*/) | 980 | if (ptr[2] == 'l' /*108*/ || ptr[2] == 'm'/*109*/) |
981 | mode = ptr[2] - 107; /* 1 or 2 */ | 981 | mode = ptr[2] - 107; /* 1 or 2 */ |
982 | if (ptr[2] == 'a') | 982 | if (ptr[2] == 'a') |
@@ -1595,11 +1595,11 @@ static char *write_old_sd_name(char *buffer, | |||
1595 | return buffer; | 1595 | return buffer; |
1596 | } | 1596 | } |
1597 | if ((major > 64) && (major < 72)) { | 1597 | if ((major > 64) && (major < 72)) { |
1598 | disc_index = ((major - 64) << 4) +(minor >> 4); | 1598 | disc_index = ((major - 64) << 4) + (minor >> 4); |
1599 | if (disc_index < 26) | 1599 | if (disc_index < 26) |
1600 | sprintf(buffer, "sd%c%s", 'a' + disc_index, part); | 1600 | sprintf(buffer, "sd%c%s", 'a' + disc_index, part); |
1601 | else | 1601 | else |
1602 | sprintf(buffer, "sd%c%c%s", 'a' +(disc_index / 26) - 1, 'a' + disc_index % 26, part); | 1602 | sprintf(buffer, "sd%c%c%s", 'a' + (disc_index / 26) - 1, 'a' + disc_index % 26, part); |
1603 | return buffer; | 1603 | return buffer; |
1604 | } | 1604 | } |
1605 | return NULL; | 1605 | return NULL; |
diff --git a/miscutils/devmem.c b/miscutils/devmem.c index f9f0276bc..f21621bd6 100644 --- a/miscutils/devmem.c +++ b/miscutils/devmem.c | |||
@@ -29,7 +29,6 @@ int devmem_main(int argc UNUSED_PARAM, char **argv) | |||
29 | { | 29 | { |
30 | void *map_base, *virt_addr; | 30 | void *map_base, *virt_addr; |
31 | uint64_t read_result; | 31 | uint64_t read_result; |
32 | uint64_t writeval = writeval; /* for compiler */ | ||
33 | off_t target; | 32 | off_t target; |
34 | unsigned page_size, mapped_size, offset_in_page; | 33 | unsigned page_size, mapped_size, offset_in_page; |
35 | int fd; | 34 | int fd; |
@@ -64,9 +63,6 @@ int devmem_main(int argc UNUSED_PARAM, char **argv) | |||
64 | width = strchrnul(bhwl, (argv[2][0] | 0x20)) - bhwl; | 63 | width = strchrnul(bhwl, (argv[2][0] | 0x20)) - bhwl; |
65 | width = sizes[width]; | 64 | width = sizes[width]; |
66 | } | 65 | } |
67 | /* VALUE */ | ||
68 | if (argv[3]) | ||
69 | writeval = bb_strtoull(argv[3], NULL, 0); | ||
70 | } else { /* argv[2] == NULL */ | 66 | } else { /* argv[2] == NULL */ |
71 | /* make argv[3] to be a valid thing to fetch */ | 67 | /* make argv[3] to be a valid thing to fetch */ |
72 | argv--; | 68 | argv--; |
@@ -96,28 +92,46 @@ int devmem_main(int argc UNUSED_PARAM, char **argv) | |||
96 | virt_addr = (char*)map_base + offset_in_page; | 92 | virt_addr = (char*)map_base + offset_in_page; |
97 | 93 | ||
98 | if (!argv[3]) { | 94 | if (!argv[3]) { |
99 | switch (width) { | 95 | #ifdef __SIZEOF_INT128__ |
100 | case 8: | 96 | if (width == 128) { |
101 | read_result = *(volatile uint8_t*)virt_addr; | 97 | unsigned __int128 rd = |
102 | break; | 98 | *(volatile unsigned __int128 *)virt_addr; |
103 | case 16: | 99 | printf("0x%016llX%016llX\n", |
104 | read_result = *(volatile uint16_t*)virt_addr; | 100 | (unsigned long long)(uint64_t)(rd >> 64), |
105 | break; | 101 | (unsigned long long)(uint64_t)rd |
106 | case 32: | 102 | ); |
107 | read_result = *(volatile uint32_t*)virt_addr; | 103 | } else |
108 | break; | 104 | #endif |
109 | case 64: | 105 | { |
110 | read_result = *(volatile uint64_t*)virt_addr; | 106 | switch (width) { |
111 | break; | 107 | case 8: |
112 | default: | 108 | read_result = *(volatile uint8_t*)virt_addr; |
113 | bb_simple_error_msg_and_die("bad width"); | 109 | break; |
110 | case 16: | ||
111 | read_result = *(volatile uint16_t*)virt_addr; | ||
112 | break; | ||
113 | case 32: | ||
114 | read_result = *(volatile uint32_t*)virt_addr; | ||
115 | break; | ||
116 | case 64: | ||
117 | read_result = *(volatile uint64_t*)virt_addr; | ||
118 | break; | ||
119 | default: | ||
120 | bb_simple_error_msg_and_die("bad width"); | ||
121 | } | ||
122 | // printf("Value at address 0x%"OFF_FMT"X (%p): 0x%llX\n", | ||
123 | // target, virt_addr, | ||
124 | // (unsigned long long)read_result); | ||
125 | /* Zero-padded output shows the width of access just done */ | ||
126 | printf("0x%0*llX\n", (width >> 2), (unsigned long long)read_result); | ||
114 | } | 127 | } |
115 | // printf("Value at address 0x%"OFF_FMT"X (%p): 0x%llX\n", | ||
116 | // target, virt_addr, | ||
117 | // (unsigned long long)read_result); | ||
118 | /* Zero-padded output shows the width of access just done */ | ||
119 | printf("0x%0*llX\n", (width >> 2), (unsigned long long)read_result); | ||
120 | } else { | 128 | } else { |
129 | /* parse VALUE */ | ||
130 | #ifdef __SIZEOF_INT128__ | ||
131 | unsigned __int128 writeval = strtoumax(argv[3], NULL, 0); | ||
132 | #else | ||
133 | uint64_t writeval = bb_strtoull(argv[3], NULL, 0); | ||
134 | #endif | ||
121 | switch (width) { | 135 | switch (width) { |
122 | case 8: | 136 | case 8: |
123 | *(volatile uint8_t*)virt_addr = writeval; | 137 | *(volatile uint8_t*)virt_addr = writeval; |
@@ -135,6 +149,12 @@ int devmem_main(int argc UNUSED_PARAM, char **argv) | |||
135 | *(volatile uint64_t*)virt_addr = writeval; | 149 | *(volatile uint64_t*)virt_addr = writeval; |
136 | // read_result = *(volatile uint64_t*)virt_addr; | 150 | // read_result = *(volatile uint64_t*)virt_addr; |
137 | break; | 151 | break; |
152 | #ifdef __SIZEOF_INT128__ | ||
153 | case 128: | ||
154 | *(volatile unsigned __int128 *)virt_addr = writeval; | ||
155 | // read_result = *(volatile uint64_t*)virt_addr; | ||
156 | break; | ||
157 | #endif | ||
138 | default: | 158 | default: |
139 | bb_simple_error_msg_and_die("bad width"); | 159 | bb_simple_error_msg_and_die("bad width"); |
140 | } | 160 | } |
diff --git a/miscutils/hdparm.c b/miscutils/hdparm.c index d8d8f6166..83e2f8d53 100644 --- a/miscutils/hdparm.c +++ b/miscutils/hdparm.c | |||
@@ -798,7 +798,7 @@ static void identify(uint16_t *val) | |||
798 | if (!(val[GEN_CONFIG] & NOT_ATA)) { | 798 | if (!(val[GEN_CONFIG] & NOT_ATA)) { |
799 | dev = ATA_DEV; | 799 | dev = ATA_DEV; |
800 | printf("ATA device, with "); | 800 | printf("ATA device, with "); |
801 | } else if (val[GEN_CONFIG]==CFA_SUPPORT_VAL) { | 801 | } else if (val[GEN_CONFIG] == CFA_SUPPORT_VAL) { |
802 | dev = ATA_DEV; | 802 | dev = ATA_DEV; |
803 | like_std = 4; | 803 | like_std = 4; |
804 | printf("CompactFlash ATA device, with "); | 804 | printf("CompactFlash ATA device, with "); |
@@ -819,13 +819,13 @@ static void identify(uint16_t *val) | |||
819 | * specific, it should be safe to check it now, even though we don't | 819 | * specific, it should be safe to check it now, even though we don't |
820 | * know yet what standard this device is using. | 820 | * know yet what standard this device is using. |
821 | */ | 821 | */ |
822 | if ((val[CONFIG]==STBY_NID_VAL) || (val[CONFIG]==STBY_ID_VAL) | 822 | if ((val[CONFIG] == STBY_NID_VAL) || (val[CONFIG] == STBY_ID_VAL) |
823 | || (val[CONFIG]==PWRD_NID_VAL) || (val[CONFIG]==PWRD_ID_VAL) | 823 | || (val[CONFIG] == PWRD_NID_VAL) || (val[CONFIG] == PWRD_ID_VAL) |
824 | ) { | 824 | ) { |
825 | like_std = 5; | 825 | like_std = 5; |
826 | if ((val[CONFIG]==STBY_NID_VAL) || (val[CONFIG]==STBY_ID_VAL)) | 826 | if ((val[CONFIG] == STBY_NID_VAL) || (val[CONFIG] == STBY_ID_VAL)) |
827 | puts("powers-up in standby; SET FEATURES subcmd spins-up."); | 827 | puts("powers-up in standby; SET FEATURES subcmd spins-up."); |
828 | if (((val[CONFIG]==STBY_NID_VAL) || (val[CONFIG]==PWRD_NID_VAL)) && (val[GEN_CONFIG] & INCOMPLETE)) | 828 | if (((val[CONFIG] == STBY_NID_VAL) || (val[CONFIG] == PWRD_NID_VAL)) && (val[GEN_CONFIG] & INCOMPLETE)) |
829 | puts("\n\tWARNING: ID response incomplete.\n\tFollowing data may be incorrect.\n"); | 829 | puts("\n\tWARNING: ID response incomplete.\n\tFollowing data may be incorrect.\n"); |
830 | } | 830 | } |
831 | 831 | ||
@@ -853,7 +853,7 @@ static void identify(uint16_t *val) | |||
853 | printf("\n\tSupported: "); | 853 | printf("\n\tSupported: "); |
854 | jj = val[MAJOR] << 1; | 854 | jj = val[MAJOR] << 1; |
855 | kk = like_std >4 ? like_std-4: 0; | 855 | kk = like_std >4 ? like_std-4: 0; |
856 | for (ii = 14; (ii >0)&&(ii>kk); ii--) { | 856 | for (ii = 14; (ii > 0) && (ii > kk); ii--) { |
857 | if (jj & 0x8000) { | 857 | if (jj & 0x8000) { |
858 | printf("%u ", ii); | 858 | printf("%u ", ii); |
859 | if (like_std < ii) { | 859 | if (like_std < ii) { |
@@ -943,7 +943,7 @@ static void identify(uint16_t *val) | |||
943 | for (ii = 1; ii < 15; ii++) { | 943 | for (ii = 1; ii < 15; ii++) { |
944 | if (jj & 0x0001) | 944 | if (jj & 0x0001) |
945 | printf("\t%s\n", nth_string(ata1_cfg_str, ii)); | 945 | printf("\t%s\n", nth_string(ata1_cfg_str, ii)); |
946 | jj >>=1; | 946 | jj >>= 1; |
947 | } | 947 | } |
948 | } | 948 | } |
949 | if (dev == ATAPI_DEV) { | 949 | if (dev == ATAPI_DEV) { |
@@ -952,7 +952,7 @@ static void identify(uint16_t *val) | |||
952 | else if ((val[GEN_CONFIG] & DRQ_RESPONSE_TIME) == DRQ_INTR_VAL) | 952 | else if ((val[GEN_CONFIG] & DRQ_RESPONSE_TIME) == DRQ_INTR_VAL) |
953 | strng = "<=10ms with INTRQ"; | 953 | strng = "<=10ms with INTRQ"; |
954 | else if ((val[GEN_CONFIG] & DRQ_RESPONSE_TIME) == DRQ_50US_VAL) | 954 | else if ((val[GEN_CONFIG] & DRQ_RESPONSE_TIME) == DRQ_50US_VAL) |
955 | strng ="50us"; | 955 | strng = "50us"; |
956 | else | 956 | else |
957 | strng = "unknown"; | 957 | strng = "unknown"; |
958 | printf("\tDRQ response: %s\n\tPacket size: ", strng); /* Data Request (DRQ) */ | 958 | printf("\tDRQ response: %s\n\tPacket size: ", strng); /* Data Request (DRQ) */ |
@@ -1014,7 +1014,7 @@ static void identify(uint16_t *val) | |||
1014 | } | 1014 | } |
1015 | 1015 | ||
1016 | if (!bbbig) | 1016 | if (!bbbig) |
1017 | bbbig = (uint64_t)(ll>mm ? ll : mm); /* # 512 byte blocks */ | 1017 | bbbig = (uint64_t)(ll > mm ? ll : mm); /* # 512 byte blocks */ |
1018 | printf("\tdevice size with M = 1024*1024: %11"PRIu64" MBytes\n", bbbig>>11); | 1018 | printf("\tdevice size with M = 1024*1024: %11"PRIu64" MBytes\n", bbbig>>11); |
1019 | bbbig = (bbbig << 9) / 1000000; | 1019 | bbbig = (bbbig << 9) / 1000000; |
1020 | printf("\tdevice size with M = 1000*1000: %11"PRIu64" MBytes ", bbbig); | 1020 | printf("\tdevice size with M = 1000*1000: %11"PRIu64" MBytes ", bbbig); |
@@ -1160,7 +1160,7 @@ static void identify(uint16_t *val) | |||
1160 | jj = ((val[ADV_PIO_MODES] & PIO_SUP) << 3) | 0x0007; | 1160 | jj = ((val[ADV_PIO_MODES] & PIO_SUP) << 3) | 0x0007; |
1161 | for (ii = 0; ii <= PIO_MODE_MAX; ii++) { | 1161 | for (ii = 0; ii <= PIO_MODE_MAX; ii++) { |
1162 | if (jj & 0x0001) printf("pio%d ", ii); | 1162 | if (jj & 0x0001) printf("pio%d ", ii); |
1163 | jj >>=1; | 1163 | jj >>= 1; |
1164 | } | 1164 | } |
1165 | bb_putchar('\n'); | 1165 | bb_putchar('\n'); |
1166 | } else if (((min_std < 5) || (eqpt == CDROM)) && (val[PIO_MODE] & MODE)) { | 1166 | } else if (((min_std < 5) || (eqpt == CDROM)) && (val[PIO_MODE] & MODE)) { |
@@ -1199,7 +1199,7 @@ static void identify(uint16_t *val) | |||
1199 | } | 1199 | } |
1200 | if (ii == 31) { | 1200 | if (ii == 31) { |
1201 | if ((val[CMDS_SUPP_2] & VALID) != VALID_VAL) | 1201 | if ((val[CMDS_SUPP_2] & VALID) != VALID_VAL) |
1202 | ii +=16; | 1202 | ii += 16; |
1203 | } | 1203 | } |
1204 | } | 1204 | } |
1205 | } | 1205 | } |
@@ -1220,7 +1220,7 @@ static void identify(uint16_t *val) | |||
1220 | printf("\t%s\t%s\n", | 1220 | printf("\t%s\t%s\n", |
1221 | (!(jj & 0x0001)) ? "not" : "", | 1221 | (!(jj & 0x0001)) ? "not" : "", |
1222 | nth_string(secu_str, ii)); | 1222 | nth_string(secu_str, ii)); |
1223 | jj >>=1; | 1223 | jj >>= 1; |
1224 | } | 1224 | } |
1225 | if (val[SECU_STATUS] & SECU_ENABLED) { | 1225 | if (val[SECU_STATUS] & SECU_ENABLED) { |
1226 | printf("\tSecurity level %s\n", | 1226 | printf("\tSecurity level %s\n", |
diff --git a/miscutils/tree.c b/miscutils/tree.c new file mode 100644 index 000000000..fa55696c6 --- /dev/null +++ b/miscutils/tree.c | |||
@@ -0,0 +1,131 @@ | |||
1 | /* vi: set sw=4 ts=4: */ | ||
2 | /* | ||
3 | * Copyright (C) 2022 Roger Knecht <rknecht@pm.me> | ||
4 | * | ||
5 | * Licensed under GPLv2, see file LICENSE in this source tree. | ||
6 | */ | ||
7 | //config:config TREE | ||
8 | //config: bool "tree (0.6 kb)" | ||
9 | //config: default y | ||
10 | //config: help | ||
11 | //config: List files and directories in a tree structure. | ||
12 | |||
13 | //applet:IF_TREE(APPLET(tree, BB_DIR_USR_BIN, BB_SUID_DROP)) | ||
14 | |||
15 | //kbuild:lib-$(CONFIG_TREE) += tree.o | ||
16 | |||
17 | //usage:#define tree_trivial_usage NOUSAGE_STR | ||
18 | //usage:#define tree_full_usage "" | ||
19 | |||
20 | #include "libbb.h" | ||
21 | #include "common_bufsiz.h" | ||
22 | #include "unicode.h" | ||
23 | |||
24 | #define prefix_buf bb_common_bufsiz1 | ||
25 | |||
26 | static void tree_print(unsigned count[2], const char* directory_name, char* prefix_pos) | ||
27 | { | ||
28 | struct dirent **entries; | ||
29 | int index, size; | ||
30 | const char *bar = "| "; | ||
31 | const char *mid = "|-- "; | ||
32 | const char *end = "`-- "; | ||
33 | |||
34 | #if ENABLE_UNICODE_SUPPORT | ||
35 | if (unicode_status == UNICODE_ON) { | ||
36 | bar = "│ "; | ||
37 | mid = "├── "; | ||
38 | end = "└── "; | ||
39 | } | ||
40 | #endif | ||
41 | |||
42 | // read directory entries | ||
43 | size = scandir(directory_name, &entries, NULL, alphasort); | ||
44 | |||
45 | if (size < 0) { | ||
46 | fputs_stdout(directory_name); | ||
47 | puts(" [error opening dir]"); | ||
48 | return; | ||
49 | } | ||
50 | |||
51 | // print directory name | ||
52 | puts(directory_name); | ||
53 | |||
54 | // switch to sub directory | ||
55 | xchdir(directory_name); | ||
56 | |||
57 | // print all directory entries | ||
58 | for (index = 0; index < size;) { | ||
59 | struct dirent *dirent = entries[index++]; | ||
60 | |||
61 | // filter hidden files and directories | ||
62 | if (dirent->d_name[0] != '.') { | ||
63 | int status; | ||
64 | struct stat statBuf; | ||
65 | |||
66 | //TODO: when -l is implemented, use stat, not lstat, if -l | ||
67 | status = lstat(dirent->d_name, &statBuf); | ||
68 | |||
69 | if (index == size) { | ||
70 | strcpy(prefix_pos, end); | ||
71 | } else { | ||
72 | strcpy(prefix_pos, mid); | ||
73 | } | ||
74 | fputs_stdout(prefix_buf); | ||
75 | |||
76 | if (status == 0 && S_ISLNK(statBuf.st_mode)) { | ||
77 | // handle symlink | ||
78 | char* symlink_path = xmalloc_readlink(dirent->d_name); | ||
79 | printf("%s -> %s\n", dirent->d_name, symlink_path); | ||
80 | free(symlink_path); | ||
81 | count[1]++; | ||
82 | } else if (status == 0 && S_ISDIR(statBuf.st_mode) | ||
83 | && (prefix_pos - prefix_buf) < (COMMON_BUFSIZE - 16) | ||
84 | ) { | ||
85 | // handle directory | ||
86 | char* pos; | ||
87 | if (index == size) { | ||
88 | pos = stpcpy(prefix_pos, " "); | ||
89 | } else { | ||
90 | pos = stpcpy(prefix_pos, bar); | ||
91 | } | ||
92 | tree_print(count, dirent->d_name, pos); | ||
93 | count[0]++; | ||
94 | } else { | ||
95 | // handle file | ||
96 | puts(dirent->d_name); | ||
97 | count[1]++; | ||
98 | } | ||
99 | } | ||
100 | |||
101 | // release directory entry | ||
102 | free(dirent); | ||
103 | } | ||
104 | |||
105 | // release directory array | ||
106 | free(entries); | ||
107 | |||
108 | // switch to parent directory | ||
109 | xchdir(".."); | ||
110 | } | ||
111 | |||
112 | int tree_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; | ||
113 | int tree_main(int argc UNUSED_PARAM, char **argv) | ||
114 | { | ||
115 | unsigned count[2] = { 0, 0 }; | ||
116 | |||
117 | setup_common_bufsiz(); | ||
118 | init_unicode(); | ||
119 | |||
120 | if (!argv[1]) | ||
121 | *argv-- = (char*)"."; | ||
122 | |||
123 | // list directories given as command line arguments | ||
124 | while (*(++argv)) | ||
125 | tree_print(count, *argv, prefix_buf); | ||
126 | |||
127 | // print statistic | ||
128 | printf("\n%u directories, %u files\n", count[0], count[1]); | ||
129 | |||
130 | return EXIT_SUCCESS; | ||
131 | } | ||
diff --git a/modutils/modutils-24.c b/modutils/modutils-24.c index d0bc2a6ef..37c303f90 100644 --- a/modutils/modutils-24.c +++ b/modutils/modutils-24.c | |||
@@ -981,7 +981,7 @@ arch_apply_relocation(struct obj_file *f, | |||
981 | (loc[1] & 0xFFFF); | 981 | (loc[1] & 0xFFFF); |
982 | 982 | ||
983 | /* Add reloc offset */ | 983 | /* Add reloc offset */ |
984 | temp1+=v; | 984 | temp1 += v; |
985 | 985 | ||
986 | /* Store back into code */ | 986 | /* Store back into code */ |
987 | loc[0] = (loc[0] & 0xFFFF0000) | temp1 >> 16; | 987 | loc[0] = (loc[0] & 0xFFFF0000) | temp1 >> 16; |
diff --git a/networking/ping.c b/networking/ping.c index 86d8088de..9805695a1 100644 --- a/networking/ping.c +++ b/networking/ping.c | |||
@@ -74,7 +74,7 @@ | |||
74 | //usage: "\n -c CNT Send only CNT pings" | 74 | //usage: "\n -c CNT Send only CNT pings" |
75 | //usage: "\n -s SIZE Send SIZE data bytes in packets (default 56)" | 75 | //usage: "\n -s SIZE Send SIZE data bytes in packets (default 56)" |
76 | //usage: "\n -i SECS Interval" | 76 | //usage: "\n -i SECS Interval" |
77 | //usage: "\n -A Ping as soon as reply is recevied" | 77 | //usage: "\n -A Ping as soon as reply is received" |
78 | //usage: "\n -t TTL Set TTL" | 78 | //usage: "\n -t TTL Set TTL" |
79 | //usage: "\n -I IFACE/IP Source interface or IP address" | 79 | //usage: "\n -I IFACE/IP Source interface or IP address" |
80 | //usage: "\n -W SEC Seconds to wait for the first response (default 10)" | 80 | //usage: "\n -W SEC Seconds to wait for the first response (default 10)" |
@@ -91,7 +91,7 @@ | |||
91 | //usage: "\n -c CNT Send only CNT pings" | 91 | //usage: "\n -c CNT Send only CNT pings" |
92 | //usage: "\n -s SIZE Send SIZE data bytes in packets (default 56)" | 92 | //usage: "\n -s SIZE Send SIZE data bytes in packets (default 56)" |
93 | //usage: "\n -i SECS Interval" | 93 | //usage: "\n -i SECS Interval" |
94 | //usage: "\n -A Ping as soon as reply is recevied" | 94 | //usage: "\n -A Ping as soon as reply is received" |
95 | ///////: "\n -t TTL Set TTL" | 95 | ///////: "\n -t TTL Set TTL" |
96 | ///////^^^^^ -t not tested for IPv6, might be not working | 96 | ///////^^^^^ -t not tested for IPv6, might be not working |
97 | //usage: "\n -I IFACE/IP Source interface or IP address" | 97 | //usage: "\n -I IFACE/IP Source interface or IP address" |
diff --git a/networking/tc.c b/networking/tc.c index 46ad23d8b..43187f7ee 100644 --- a/networking/tc.c +++ b/networking/tc.c | |||
@@ -214,7 +214,7 @@ static int prio_print_opt(struct rtattr *opt) | |||
214 | return 0; | 214 | return 0; |
215 | parse_rtattr_nested_compat(tb, TCA_PRIO_MAX, opt, qopt, sizeof(*qopt)); | 215 | parse_rtattr_nested_compat(tb, TCA_PRIO_MAX, opt, qopt, sizeof(*qopt)); |
216 | printf("bands %u priomap ", qopt->bands); | 216 | printf("bands %u priomap ", qopt->bands); |
217 | for (i=0; i<=TC_PRIO_MAX; i++) | 217 | for (i = 0; i <= TC_PRIO_MAX; i++) |
218 | printf(" %d", qopt->priomap[i]); | 218 | printf(" %d", qopt->priomap[i]); |
219 | 219 | ||
220 | if (tb[TCA_PRIO_MQ]) | 220 | if (tb[TCA_PRIO_MQ]) |
diff --git a/networking/tls.c b/networking/tls.c index 5f40aec70..9f1dd67ec 100644 --- a/networking/tls.c +++ b/networking/tls.c | |||
@@ -948,11 +948,46 @@ static int tls_has_buffered_record(tls_state_t *tls) | |||
948 | 948 | ||
949 | static const char *alert_text(int code) | 949 | static const char *alert_text(int code) |
950 | { | 950 | { |
951 | //10 unexpected_message | ||
952 | //20 bad_record_mac | ||
953 | //21 decryption_failed | ||
954 | //22 record_overflow | ||
955 | //30 decompression_failure | ||
956 | //40 handshake_failure | ||
957 | //41 no_certificate | ||
958 | //42 bad_certificate | ||
959 | //43 unsupported_certificate | ||
960 | //44 certificate_revoked | ||
961 | //45 certificate_expired | ||
962 | //46 certificate_unknown | ||
963 | //47 illegal_parameter | ||
964 | //48 unknown_ca | ||
965 | //49 access_denied | ||
966 | //50 decode_error | ||
967 | //51 decrypt_error | ||
968 | //52 too_many_cids_requested | ||
969 | //60 export_restriction | ||
970 | //70 protocol_version | ||
971 | //71 insufficient_security | ||
972 | //80 internal_error | ||
973 | //86 inappropriate_fallback | ||
974 | //90 user_canceled | ||
975 | //100 no_renegotiation | ||
976 | //109 missing_extension | ||
977 | //110 unsupported_extension | ||
978 | //111 certificate_unobtainable | ||
979 | //112 unrecognized_name | ||
980 | //113 bad_certificate_status_response | ||
981 | //114 bad_certificate_hash_value | ||
982 | //115 unknown_psk_identity | ||
983 | //116 certificate_required | ||
984 | //120 no_application_protocol | ||
951 | switch (code) { | 985 | switch (code) { |
952 | case 20: return "bad MAC"; | 986 | case 20: return "bad MAC"; |
953 | case 50: return "decode error"; | 987 | case 50: return "decode error"; |
954 | case 51: return "decrypt error"; | ||
955 | case 40: return "handshake failure"; | 988 | case 40: return "handshake failure"; |
989 | case 51: return "decrypt error"; | ||
990 | case 80: return "internal error"; | ||
956 | case 112: return "unrecognized name"; | 991 | case 112: return "unrecognized name"; |
957 | } | 992 | } |
958 | return itoa(code); | 993 | return itoa(code); |
@@ -1531,27 +1566,6 @@ static void send_client_hello_and_alloc_hsd(tls_state_t *tls, const char *sni) | |||
1531 | #endif | 1566 | #endif |
1532 | 0x01,0x00, //not a cipher - comprtypes_len, comprtype | 1567 | 0x01,0x00, //not a cipher - comprtypes_len, comprtype |
1533 | }; | 1568 | }; |
1534 | static const uint8_t supported_groups[] = { | ||
1535 | 0x00,0x0a, //extension_type: "supported_groups" | ||
1536 | 0x00,2 * (1 + ALLOW_CURVE_P256 + ALLOW_CURVE_X25519), //ext len | ||
1537 | 0x00,2 * (0 + ALLOW_CURVE_P256 + ALLOW_CURVE_X25519), //list len | ||
1538 | #if ALLOW_CURVE_P256 | ||
1539 | 0x00,0x17, //curve_secp256r1 (aka P256, aka prime256v1) | ||
1540 | #endif | ||
1541 | //0x00,0x18, //curve_secp384r1 | ||
1542 | //0x00,0x19, //curve_secp521r1 | ||
1543 | #if ALLOW_CURVE_X25519 | ||
1544 | 0x00,0x1d, //curve_x25519 (RFC 7748) | ||
1545 | #endif | ||
1546 | //0x00,0x1e, //curve_x448 (RFC 7748) | ||
1547 | }; | ||
1548 | //static const uint8_t signature_algorithms[] = { | ||
1549 | // 000d | ||
1550 | // 0020 | ||
1551 | // 001e | ||
1552 | // 0601 0602 0603 0501 0502 0503 0401 0402 0403 0301 0302 0303 0201 0202 0203 | ||
1553 | //}; | ||
1554 | |||
1555 | struct client_hello { | 1569 | struct client_hello { |
1556 | uint8_t type; | 1570 | uint8_t type; |
1557 | uint8_t len24_hi, len24_mid, len24_lo; | 1571 | uint8_t len24_hi, len24_mid, len24_lo; |
@@ -1563,15 +1577,47 @@ static void send_client_hello_and_alloc_hsd(tls_state_t *tls, const char *sni) | |||
1563 | uint8_t cipherid[2 * (1 + NUM_CIPHERS)]; /* actually variable */ | 1577 | uint8_t cipherid[2 * (1 + NUM_CIPHERS)]; /* actually variable */ |
1564 | uint8_t comprtypes_len; | 1578 | uint8_t comprtypes_len; |
1565 | uint8_t comprtypes[1]; /* actually variable */ | 1579 | uint8_t comprtypes[1]; /* actually variable */ |
1566 | /* Extensions (SNI shown): | 1580 | }; |
1567 | * hi,lo // len of all extensions | 1581 | // https://www.iana.org/assignments/tls-extensiontype-values/tls-extensiontype-values.xhtml |
1568 | * 00,00 // extension_type: "Server Name" | 1582 | static const uint8_t extensions[] = { |
1569 | * 00,0e // list len (there can be more than one SNI) | 1583 | // is.gd responds with "handshake failure" to our hello if there's no supported_groups |
1570 | * 00,0c // len of 1st Server Name Indication | 1584 | 0x00,0x0a, //extension_type: "supported_groups" |
1571 | * 00 // name type: host_name | 1585 | 0x00,2 * (1 + ALLOW_CURVE_P256 + ALLOW_CURVE_X25519), //ext len |
1572 | * 00,09 // name len | 1586 | 0x00,2 * (0 + ALLOW_CURVE_P256 + ALLOW_CURVE_X25519), //list len |
1573 | * "localhost" // name | 1587 | #if ALLOW_CURVE_P256 |
1574 | */ | 1588 | 0x00,0x17, //curve_secp256r1 (aka P256, aka prime256v1) |
1589 | #endif | ||
1590 | //0x00,0x18, //curve_secp384r1 | ||
1591 | //0x00,0x19, //curve_secp521r1 | ||
1592 | #if ALLOW_CURVE_X25519 | ||
1593 | 0x00,0x1d, //curve_x25519 (RFC 7748) | ||
1594 | #endif | ||
1595 | //0x00,0x1e, //curve_x448 (RFC 7748) | ||
1596 | |||
1597 | //0x00,0x0b,0x00,0x04,0x03,0x00,0x01,0x02, //extension_type: "ec_point_formats" | ||
1598 | //0x00,0x16,0x00,0x00, //extension_type: "encrpypt-then-mac" | ||
1599 | //0x00,0x17,0x00,0x00, //extension_type: "extended_master" | ||
1600 | //0x00,0x23,0x00,0x00, //extension_type: "session_ticket" | ||
1601 | |||
1602 | // kojipkgs.fedoraproject.org responds with alert code 80 ("internal error") | ||
1603 | // to our hello without signature_algorithms. | ||
1604 | // It is satisfied with just 0x04,0x01. | ||
1605 | 0x00,0x0d, //extension_type: "signature_algorithms" (RFC5246 section 7.4.1.4.1): | ||
1606 | #define SIGALGS (3 + 3 * ENABLE_FEATURE_TLS_SHA1) | ||
1607 | 0x00,2 * (1 + SIGALGS), //ext len | ||
1608 | 0x00,2 * (0 + SIGALGS), //list len | ||
1609 | //Format: two bytes | ||
1610 | // byte 1: 0:none,1:md5,2:sha1,3:sha224,4:sha256,5:sha384,6:sha512 | ||
1611 | // byte 2: 1:rsa,2:dsa,3:ecdsa | ||
1612 | // (note that TLS 1.3 changes this, see RFC8446 section 4.2.3) | ||
1613 | #if ENABLE_FEATURE_TLS_SHA1 | ||
1614 | 0x02,0x01, //sha1 + rsa | ||
1615 | 0x02,0x02, //sha1 + dsa | ||
1616 | 0x02,0x03, //sha1 + ecdsa | ||
1617 | #endif | ||
1618 | 0x04,0x01, //sha256 + rsa - kojipkgs.fedoraproject.org wants this | ||
1619 | 0x04,0x02, //sha256 + dsa | ||
1620 | 0x04,0x03, //sha256 + ecdsa | ||
1575 | // GNU Wget 1.18 to cdn.kernel.org sends these extensions: | 1621 | // GNU Wget 1.18 to cdn.kernel.org sends these extensions: |
1576 | // 0055 | 1622 | // 0055 |
1577 | // 0005 0005 0100000000 - status_request | 1623 | // 0005 0005 0100000000 - status_request |
@@ -1591,8 +1637,7 @@ static void send_client_hello_and_alloc_hsd(tls_state_t *tls, const char *sni) | |||
1591 | int sni_len = sni ? strnlen(sni, 127 - 5) : 0; | 1637 | int sni_len = sni ? strnlen(sni, 127 - 5) : 0; |
1592 | 1638 | ||
1593 | ext_len = 0; | 1639 | ext_len = 0; |
1594 | /* is.gd responds with "handshake failure" to our hello if there's no supported_groups element */ | 1640 | ext_len += sizeof(extensions); |
1595 | ext_len += sizeof(supported_groups); | ||
1596 | if (sni_len) | 1641 | if (sni_len) |
1597 | ext_len += 9 + sni_len; | 1642 | ext_len += 9 + sni_len; |
1598 | 1643 | ||
@@ -1626,7 +1671,7 @@ static void send_client_hello_and_alloc_hsd(tls_state_t *tls, const char *sni) | |||
1626 | ptr[8] = sni_len; //name len | 1671 | ptr[8] = sni_len; //name len |
1627 | ptr = mempcpy(&ptr[9], sni, sni_len); | 1672 | ptr = mempcpy(&ptr[9], sni, sni_len); |
1628 | } | 1673 | } |
1629 | memcpy(ptr, supported_groups, sizeof(supported_groups)); | 1674 | memcpy(ptr, extensions, sizeof(extensions)); |
1630 | 1675 | ||
1631 | tls->hsd = xzalloc(sizeof(*tls->hsd)); | 1676 | tls->hsd = xzalloc(sizeof(*tls->hsd)); |
1632 | /* HANDSHAKE HASH: ^^^ + len if need to save saved_client_hello */ | 1677 | /* HANDSHAKE HASH: ^^^ + len if need to save saved_client_hello */ |
diff --git a/networking/tls_sp_c32.c b/networking/tls_sp_c32.c index 292dda24e..a593c5c40 100644 --- a/networking/tls_sp_c32.c +++ b/networking/tls_sp_c32.c | |||
@@ -68,9 +68,6 @@ static const sp_digit p256_mod[8] ALIGNED(8) = { | |||
68 | 68 | ||
69 | #define p256_mp_mod ((sp_digit)0x000001) | 69 | #define p256_mp_mod ((sp_digit)0x000001) |
70 | 70 | ||
71 | /* Normalize the values in each word to 32 bits - NOP */ | ||
72 | #define sp_256_norm_8(a) ((void)0) | ||
73 | |||
74 | /* Write r as big endian to byte array. | 71 | /* Write r as big endian to byte array. |
75 | * Fixed length number of bytes written: 32 | 72 | * Fixed length number of bytes written: 32 |
76 | * | 73 | * |
@@ -83,8 +80,6 @@ static void sp_256_to_bin_8(const sp_digit* rr, uint8_t* a) | |||
83 | int i; | 80 | int i; |
84 | const uint64_t* r = (void*)rr; | 81 | const uint64_t* r = (void*)rr; |
85 | 82 | ||
86 | sp_256_norm_8(rr); | ||
87 | |||
88 | r += 4; | 83 | r += 4; |
89 | for (i = 0; i < 4; i++) { | 84 | for (i = 0; i < 4; i++) { |
90 | r--; | 85 | r--; |
@@ -97,8 +92,6 @@ static void sp_256_to_bin_8(const sp_digit* r, uint8_t* a) | |||
97 | { | 92 | { |
98 | int i; | 93 | int i; |
99 | 94 | ||
100 | sp_256_norm_8(r); | ||
101 | |||
102 | r += 8; | 95 | r += 8; |
103 | for (i = 0; i < 8; i++) { | 96 | for (i = 0; i < 8; i++) { |
104 | r--; | 97 | r--; |
@@ -641,7 +634,6 @@ static void sp_256_div2_8(sp_digit* r /*, const sp_digit* m*/) | |||
641 | int carry = 0; | 634 | int carry = 0; |
642 | if (r[0] & 1) | 635 | if (r[0] & 1) |
643 | carry = sp_256_add_8(r, r, m); | 636 | carry = sp_256_add_8(r, r, m); |
644 | sp_256_norm_8(r); | ||
645 | sp_256_rshift1_8(r, carry); | 637 | sp_256_rshift1_8(r, carry); |
646 | } | 638 | } |
647 | 639 | ||
@@ -652,10 +644,8 @@ static void sp_256_mont_add_8(sp_digit* r, const sp_digit* a, const sp_digit* b | |||
652 | // const sp_digit* m = p256_mod; | 644 | // const sp_digit* m = p256_mod; |
653 | 645 | ||
654 | int carry = sp_256_add_8(r, a, b); | 646 | int carry = sp_256_add_8(r, a, b); |
655 | sp_256_norm_8(r); | ||
656 | if (carry) { | 647 | if (carry) { |
657 | sp_256_sub_8_p256_mod(r); | 648 | sp_256_sub_8_p256_mod(r); |
658 | sp_256_norm_8(r); | ||
659 | } | 649 | } |
660 | } | 650 | } |
661 | 651 | ||
@@ -667,10 +657,8 @@ static void sp_256_mont_sub_8(sp_digit* r, const sp_digit* a, const sp_digit* b | |||
667 | 657 | ||
668 | int borrow; | 658 | int borrow; |
669 | borrow = sp_256_sub_8(r, a, b); | 659 | borrow = sp_256_sub_8(r, a, b); |
670 | sp_256_norm_8(r); | ||
671 | if (borrow) { | 660 | if (borrow) { |
672 | sp_256_add_8(r, r, m); | 661 | sp_256_add_8(r, r, m); |
673 | sp_256_norm_8(r); | ||
674 | } | 662 | } |
675 | } | 663 | } |
676 | 664 | ||
@@ -680,10 +668,8 @@ static void sp_256_mont_dbl_8(sp_digit* r, const sp_digit* a /*, const sp_digit* | |||
680 | // const sp_digit* m = p256_mod; | 668 | // const sp_digit* m = p256_mod; |
681 | 669 | ||
682 | int carry = sp_256_add_8(r, a, a); | 670 | int carry = sp_256_add_8(r, a, a); |
683 | sp_256_norm_8(r); | ||
684 | if (carry) | 671 | if (carry) |
685 | sp_256_sub_8_p256_mod(r); | 672 | sp_256_sub_8_p256_mod(r); |
686 | sp_256_norm_8(r); | ||
687 | } | 673 | } |
688 | 674 | ||
689 | /* Triple a Montgomery form number (r = a + a + a % m) */ | 675 | /* Triple a Montgomery form number (r = a + a + a % m) */ |
@@ -692,16 +678,12 @@ static void sp_256_mont_tpl_8(sp_digit* r, const sp_digit* a /*, const sp_digit* | |||
692 | // const sp_digit* m = p256_mod; | 678 | // const sp_digit* m = p256_mod; |
693 | 679 | ||
694 | int carry = sp_256_add_8(r, a, a); | 680 | int carry = sp_256_add_8(r, a, a); |
695 | sp_256_norm_8(r); | ||
696 | if (carry) { | 681 | if (carry) { |
697 | sp_256_sub_8_p256_mod(r); | 682 | sp_256_sub_8_p256_mod(r); |
698 | sp_256_norm_8(r); | ||
699 | } | 683 | } |
700 | carry = sp_256_add_8(r, r, a); | 684 | carry = sp_256_add_8(r, r, a); |
701 | sp_256_norm_8(r); | ||
702 | if (carry) { | 685 | if (carry) { |
703 | sp_256_sub_8_p256_mod(r); | 686 | sp_256_sub_8_p256_mod(r); |
704 | sp_256_norm_8(r); | ||
705 | } | 687 | } |
706 | } | 688 | } |
707 | 689 | ||
@@ -844,7 +826,6 @@ static void sp_512to256_mont_reduce_8(sp_digit* r, sp_digit* aa/*, const sp_digi | |||
844 | sp_512to256_mont_shift_8(r, aa); | 826 | sp_512to256_mont_shift_8(r, aa); |
845 | if (carry != 0) | 827 | if (carry != 0) |
846 | sp_256_sub_8_p256_mod(r); | 828 | sp_256_sub_8_p256_mod(r); |
847 | sp_256_norm_8(r); | ||
848 | } | 829 | } |
849 | 830 | ||
850 | #else /* Generic 32-bit version */ | 831 | #else /* Generic 32-bit version */ |
@@ -1003,8 +984,6 @@ static int sp_256_mul_add_8(sp_digit* r /*, const sp_digit* a, sp_digit b*/) | |||
1003 | * [In our case, it is (p256_mp_mod * a[1]) << 32.] | 984 | * [In our case, it is (p256_mp_mod * a[1]) << 32.] |
1004 | * And so on. Eventually T is divisible by R, and after division by R | 985 | * And so on. Eventually T is divisible by R, and after division by R |
1005 | * the algorithm is in the same place as the usual Montgomery reduction. | 986 | * the algorithm is in the same place as the usual Montgomery reduction. |
1006 | * | ||
1007 | * TODO: Can conditionally use 64-bit (if bit-little-endian arch) logic? | ||
1008 | */ | 987 | */ |
1009 | static void sp_512to256_mont_reduce_8(sp_digit* r, sp_digit* a/*, const sp_digit* m, sp_digit mp*/) | 988 | static void sp_512to256_mont_reduce_8(sp_digit* r, sp_digit* a/*, const sp_digit* m, sp_digit mp*/) |
1010 | { | 989 | { |
@@ -1032,7 +1011,6 @@ static void sp_512to256_mont_reduce_8(sp_digit* r, sp_digit* a/*, const sp_digit | |||
1032 | sp_512to256_mont_shift_8(r, a); | 1011 | sp_512to256_mont_shift_8(r, a); |
1033 | if (word16th != 0) | 1012 | if (word16th != 0) |
1034 | sp_256_sub_8_p256_mod(r); | 1013 | sp_256_sub_8_p256_mod(r); |
1035 | sp_256_norm_8(r); | ||
1036 | } | 1014 | } |
1037 | else { /* Same code for explicit mp == 1 (which is always the case for P256) */ | 1015 | else { /* Same code for explicit mp == 1 (which is always the case for P256) */ |
1038 | sp_digit word16th = 0; | 1016 | sp_digit word16th = 0; |
@@ -1052,7 +1030,6 @@ static void sp_512to256_mont_reduce_8(sp_digit* r, sp_digit* a/*, const sp_digit | |||
1052 | sp_512to256_mont_shift_8(r, a); | 1030 | sp_512to256_mont_shift_8(r, a); |
1053 | if (word16th != 0) | 1031 | if (word16th != 0) |
1054 | sp_256_sub_8_p256_mod(r); | 1032 | sp_256_sub_8_p256_mod(r); |
1055 | sp_256_norm_8(r); | ||
1056 | } | 1033 | } |
1057 | } | 1034 | } |
1058 | #endif | 1035 | #endif |
@@ -1208,14 +1185,12 @@ static void sp_256_map_8(sp_point* r, sp_point* p) | |||
1208 | /* Reduce x to less than modulus */ | 1185 | /* Reduce x to less than modulus */ |
1209 | if (sp_256_cmp_8(r->x, p256_mod) >= 0) | 1186 | if (sp_256_cmp_8(r->x, p256_mod) >= 0) |
1210 | sp_256_sub_8_p256_mod(r->x); | 1187 | sp_256_sub_8_p256_mod(r->x); |
1211 | sp_256_norm_8(r->x); | ||
1212 | 1188 | ||
1213 | /* y /= z^3 */ | 1189 | /* y /= z^3 */ |
1214 | sp_256_mont_mul_and_reduce_8(r->y, p->y, t1 /*, p256_mod, p256_mp_mod*/); | 1190 | sp_256_mont_mul_and_reduce_8(r->y, p->y, t1 /*, p256_mod, p256_mp_mod*/); |
1215 | /* Reduce y to less than modulus */ | 1191 | /* Reduce y to less than modulus */ |
1216 | if (sp_256_cmp_8(r->y, p256_mod) >= 0) | 1192 | if (sp_256_cmp_8(r->y, p256_mod) >= 0) |
1217 | sp_256_sub_8_p256_mod(r->y); | 1193 | sp_256_sub_8_p256_mod(r->y); |
1218 | sp_256_norm_8(r->y); | ||
1219 | 1194 | ||
1220 | memset(r->z, 0, sizeof(r->z)); | 1195 | memset(r->z, 0, sizeof(r->z)); |
1221 | r->z[0] = 1; | 1196 | r->z[0] = 1; |
@@ -1300,7 +1275,6 @@ static NOINLINE void sp_256_proj_point_add_8(sp_point* r, sp_point* p, sp_point* | |||
1300 | 1275 | ||
1301 | /* Check double */ | 1276 | /* Check double */ |
1302 | sp_256_sub_8(t1, p256_mod, q->y); | 1277 | sp_256_sub_8(t1, p256_mod, q->y); |
1303 | sp_256_norm_8(t1); | ||
1304 | if (sp_256_cmp_equal_8(p->x, q->x) | 1278 | if (sp_256_cmp_equal_8(p->x, q->x) |
1305 | && sp_256_cmp_equal_8(p->z, q->z) | 1279 | && sp_256_cmp_equal_8(p->z, q->z) |
1306 | && (sp_256_cmp_equal_8(p->y, q->y) || sp_256_cmp_equal_8(p->y, t1)) | 1280 | && (sp_256_cmp_equal_8(p->y, q->y) || sp_256_cmp_equal_8(p->y, t1)) |
@@ -1422,14 +1396,15 @@ static void sp_256_ecc_mulmod_8(sp_point* r, const sp_point* g, const sp_digit* | |||
1422 | static void sp_256_ecc_mulmod_base_8(sp_point* r, sp_digit* k /*, int map*/) | 1396 | static void sp_256_ecc_mulmod_base_8(sp_point* r, sp_digit* k /*, int map*/) |
1423 | { | 1397 | { |
1424 | /* Since this function is called only once, save space: | 1398 | /* Since this function is called only once, save space: |
1425 | * don't have "static const sp_point p256_base = {...}", | 1399 | * don't have "static const sp_point p256_base = {...}". |
1426 | * it would have more zeros than data. | ||
1427 | */ | 1400 | */ |
1428 | static const uint8_t p256_base_bin[] = { | 1401 | static const uint8_t p256_base_bin[] = { |
1429 | /* x (big-endian) */ | 1402 | /* x (big-endian) */ |
1430 | 0x6b,0x17,0xd1,0xf2,0xe1,0x2c,0x42,0x47,0xf8,0xbc,0xe6,0xe5,0x63,0xa4,0x40,0xf2,0x77,0x03,0x7d,0x81,0x2d,0xeb,0x33,0xa0,0xf4,0xa1,0x39,0x45,0xd8,0x98,0xc2,0x96, | 1403 | 0x6b,0x17,0xd1,0xf2,0xe1,0x2c,0x42,0x47,0xf8,0xbc,0xe6,0xe5,0x63,0xa4,0x40,0xf2, |
1404 | 0x77,0x03,0x7d,0x81,0x2d,0xeb,0x33,0xa0,0xf4,0xa1,0x39,0x45,0xd8,0x98,0xc2,0x96, | ||
1431 | /* y */ | 1405 | /* y */ |
1432 | 0x4f,0xe3,0x42,0xe2,0xfe,0x1a,0x7f,0x9b,0x8e,0xe7,0xeb,0x4a,0x7c,0x0f,0x9e,0x16,0x2b,0xce,0x33,0x57,0x6b,0x31,0x5e,0xce,0xcb,0xb6,0x40,0x68,0x37,0xbf,0x51,0xf5, | 1406 | 0x4f,0xe3,0x42,0xe2,0xfe,0x1a,0x7f,0x9b,0x8e,0xe7,0xeb,0x4a,0x7c,0x0f,0x9e,0x16, |
1407 | 0x2b,0xce,0x33,0x57,0x6b,0x31,0x5e,0xce,0xcb,0xb6,0x40,0x68,0x37,0xbf,0x51,0xf5, | ||
1433 | /* z will be set to 1, infinity flag to "false" */ | 1408 | /* z will be set to 1, infinity flag to "false" */ |
1434 | }; | 1409 | }; |
1435 | sp_point p256_base; | 1410 | sp_point p256_base; |
diff --git a/networking/udhcp/d6_dhcpc.c b/networking/udhcp/d6_dhcpc.c index 9fc690315..c7f130a70 100644 --- a/networking/udhcp/d6_dhcpc.c +++ b/networking/udhcp/d6_dhcpc.c | |||
@@ -295,6 +295,7 @@ static void option_to_env(const uint8_t *option, const uint8_t *option_end) | |||
295 | *new_env() = xasprintf("ipv6=%s", ipv6str); | 295 | *new_env() = xasprintf("ipv6=%s", ipv6str); |
296 | 296 | ||
297 | move_from_unaligned32(v32, option + 4 + 16 + 4); | 297 | move_from_unaligned32(v32, option + 4 + 16 + 4); |
298 | v32 = ntohl(v32); | ||
298 | *new_env() = xasprintf("lease=%u", (unsigned)v32); | 299 | *new_env() = xasprintf("lease=%u", (unsigned)v32); |
299 | break; | 300 | break; |
300 | 301 | ||
@@ -332,6 +333,7 @@ static void option_to_env(const uint8_t *option, const uint8_t *option_end) | |||
332 | * +-+-+-+-+-+-+-+-+ | 333 | * +-+-+-+-+-+-+-+-+ |
333 | */ | 334 | */ |
334 | move_from_unaligned32(v32, option + 4 + 4); | 335 | move_from_unaligned32(v32, option + 4 + 4); |
336 | v32 = ntohl(v32); | ||
335 | *new_env() = xasprintf("ipv6prefix_lease=%u", (unsigned)v32); | 337 | *new_env() = xasprintf("ipv6prefix_lease=%u", (unsigned)v32); |
336 | 338 | ||
337 | sprint_nip6(ipv6str, option + 4 + 4 + 4 + 1); | 339 | sprint_nip6(ipv6str, option + 4 + 4 + 4 + 1); |
@@ -842,7 +844,7 @@ static NOINLINE int send_d6_renew(struct in6_addr *server_ipv6, struct in6_addr | |||
842 | uint8_t *opt_ptr; | 844 | uint8_t *opt_ptr; |
843 | 845 | ||
844 | /* Fill in: msg type, xid, ELAPSED_TIME */ | 846 | /* Fill in: msg type, xid, ELAPSED_TIME */ |
845 | opt_ptr = init_d6_packet(&packet, DHCPREQUEST); | 847 | opt_ptr = init_d6_packet(&packet, D6_MSG_RENEW); |
846 | 848 | ||
847 | /* server id */ | 849 | /* server id */ |
848 | opt_ptr = mempcpy(opt_ptr, client6_data.server_id, client6_data.server_id->len + 2+2); | 850 | opt_ptr = mempcpy(opt_ptr, client6_data.server_id, client6_data.server_id->len + 2+2); |
@@ -1081,7 +1083,7 @@ static void change_listen_mode(int new_mode) | |||
1081 | client_data.sockfd = -1; | 1083 | client_data.sockfd = -1; |
1082 | } | 1084 | } |
1083 | if (new_mode == LISTEN_KERNEL) | 1085 | if (new_mode == LISTEN_KERNEL) |
1084 | client_data.sockfd = udhcp_listen_socket(/*INADDR_ANY,*/ CLIENT_PORT6, client_data.interface); | 1086 | client_data.sockfd = d6_listen_socket(CLIENT_PORT6, client_data.interface); |
1085 | else if (new_mode != LISTEN_NONE) | 1087 | else if (new_mode != LISTEN_NONE) |
1086 | client_data.sockfd = d6_raw_socket(client_data.ifindex); | 1088 | client_data.sockfd = d6_raw_socket(client_data.ifindex); |
1087 | /* else LISTEN_NONE: client_data.sockfd stays closed */ | 1089 | /* else LISTEN_NONE: client_data.sockfd stays closed */ |
@@ -1487,6 +1489,7 @@ int udhcpc6_main(int argc UNUSED_PARAM, char **argv) | |||
1487 | if (opt & OPT_l) | 1489 | if (opt & OPT_l) |
1488 | send_d6_info_request(); | 1490 | send_d6_info_request(); |
1489 | else /* send a broadcast renew request */ | 1491 | else /* send a broadcast renew request */ |
1492 | //TODO: send_d6_renew uses D6_MSG_RENEW message, should we use D6_MSG_REBIND here instead? | ||
1490 | send_d6_renew(/*server_ipv6:*/ NULL, requested_ipv6); | 1493 | send_d6_renew(/*server_ipv6:*/ NULL, requested_ipv6); |
1491 | timeout = discover_timeout; | 1494 | timeout = discover_timeout; |
1492 | packet_num++; | 1495 | packet_num++; |
diff --git a/networking/udhcp/d6_socket.c b/networking/udhcp/d6_socket.c index 8ddee5a8e..21cf61c6e 100644 --- a/networking/udhcp/d6_socket.c +++ b/networking/udhcp/d6_socket.c | |||
@@ -110,7 +110,7 @@ int FAST_FUNC d6_listen_socket(int port, const char *inf) | |||
110 | int fd; | 110 | int fd; |
111 | struct sockaddr_in6 addr; | 111 | struct sockaddr_in6 addr; |
112 | 112 | ||
113 | log1("opening listen socket on *:%d %s", port, inf); | 113 | log2("opening listen socket on *:%d %s", port, inf); |
114 | fd = xsocket(PF_INET6, SOCK_DGRAM, IPPROTO_UDP); | 114 | fd = xsocket(PF_INET6, SOCK_DGRAM, IPPROTO_UDP); |
115 | 115 | ||
116 | setsockopt_reuseaddr(fd); | 116 | setsockopt_reuseaddr(fd); |
diff --git a/procps/nmeter.c b/procps/nmeter.c index 088d366bf..68e6f3325 100644 --- a/procps/nmeter.c +++ b/procps/nmeter.c | |||
@@ -515,7 +515,7 @@ static void FAST_FUNC collect_blk(blk_stat *s) | |||
515 | return; | 515 | return; |
516 | } | 516 | } |
517 | 517 | ||
518 | for (i=0; i<2; i++) { | 518 | for (i = 0; i < 2; i++) { |
519 | ullong old = s->old[i]; | 519 | ullong old = s->old[i]; |
520 | if (data[i] < old) old = data[i]; //sanitize | 520 | if (data[i] < old) old = data[i]; //sanitize |
521 | s->old[i] = data[i]; | 521 | s->old[i] = data[i]; |
@@ -597,7 +597,7 @@ static void FAST_FUNC collect_if(if_stat *s) | |||
597 | return; | 597 | return; |
598 | } | 598 | } |
599 | 599 | ||
600 | for (i=0; i<4; i++) { | 600 | for (i = 0; i < 4; i++) { |
601 | ullong old = s->old[i]; | 601 | ullong old = s->old[i]; |
602 | if (data[i] < old) old = data[i]; //sanitize | 602 | if (data[i] < old) old = data[i]; //sanitize |
603 | s->old[i] = data[i]; | 603 | s->old[i] = data[i]; |
diff --git a/shell/ash.c b/shell/ash.c index 28c7fe2db..8497538b1 100644 --- a/shell/ash.c +++ b/shell/ash.c | |||
@@ -149,6 +149,11 @@ | |||
149 | //config: default y | 149 | //config: default y |
150 | //config: depends on SHELL_ASH | 150 | //config: depends on SHELL_ASH |
151 | //config: | 151 | //config: |
152 | //config:config ASH_SLEEP | ||
153 | //config: bool "sleep builtin" | ||
154 | //config: default y | ||
155 | //config: depends on SHELL_ASH | ||
156 | //config: | ||
152 | //config:config ASH_HELP | 157 | //config:config ASH_HELP |
153 | //config: bool "help builtin" | 158 | //config: bool "help builtin" |
154 | //config: default y | 159 | //config: default y |
@@ -7702,6 +7707,7 @@ varunset(const char *end, const char *var, const char *umsg, int varflags) | |||
7702 | msg = umsg; | 7707 | msg = umsg; |
7703 | } | 7708 | } |
7704 | } | 7709 | } |
7710 | ifsfree(); | ||
7705 | ash_msg_and_raise_error("%.*s: %s%s", (int)(end - var - 1), var, msg, tail); | 7711 | ash_msg_and_raise_error("%.*s: %s%s", (int)(end - var - 1), var, msg, tail); |
7706 | } | 7712 | } |
7707 | 7713 | ||
@@ -7997,13 +8003,15 @@ subevalvar(char *start, char *str, int strloc, | |||
7997 | if (idx >= end) | 8003 | if (idx >= end) |
7998 | break; | 8004 | break; |
7999 | STPUTC(*idx, expdest); | 8005 | STPUTC(*idx, expdest); |
8006 | if (stackblock() != restart_detect) | ||
8007 | goto restart; | ||
8000 | if (quotes && (unsigned char)*idx == CTLESC) { | 8008 | if (quotes && (unsigned char)*idx == CTLESC) { |
8001 | idx++; | 8009 | idx++; |
8002 | len++; | 8010 | len++; |
8003 | STPUTC(*idx, expdest); | 8011 | STPUTC(*idx, expdest); |
8012 | if (stackblock() != restart_detect) | ||
8013 | goto restart; | ||
8004 | } | 8014 | } |
8005 | if (stackblock() != restart_detect) | ||
8006 | goto restart; | ||
8007 | idx++; | 8015 | idx++; |
8008 | len++; | 8016 | len++; |
8009 | rmesc++; | 8017 | rmesc++; |
@@ -8028,6 +8036,13 @@ subevalvar(char *start, char *str, int strloc, | |||
8028 | idx = loc; | 8036 | idx = loc; |
8029 | } | 8037 | } |
8030 | 8038 | ||
8039 | /* The STPUTC invocations above may resize and move the | ||
8040 | * stack via realloc(3). Since repl is a pointer into the | ||
8041 | * stack, we need to reconstruct it relative to stackblock(). | ||
8042 | */ | ||
8043 | if (slash_pos >= 0) | ||
8044 | repl = (char *)stackblock() + strloc + slash_pos + 1; | ||
8045 | |||
8031 | //bb_error_msg("repl:'%s'", repl); | 8046 | //bb_error_msg("repl:'%s'", repl); |
8032 | for (loc = (char*)repl; *loc; loc++) { | 8047 | for (loc = (char*)repl; *loc; loc++) { |
8033 | char *restart_detect = stackblock(); | 8048 | char *restart_detect = stackblock(); |
@@ -8127,6 +8142,7 @@ varvalue(char *name, int varflags, int flags, int quoted) | |||
8127 | if (discard) | 8142 | if (discard) |
8128 | return -1; | 8143 | return -1; |
8129 | 8144 | ||
8145 | ifsfree(); | ||
8130 | raise_error_syntax("bad substitution"); | 8146 | raise_error_syntax("bad substitution"); |
8131 | } | 8147 | } |
8132 | 8148 | ||
@@ -11039,6 +11055,9 @@ static int FAST_FUNC printfcmd(int argc, char **argv) { return printf_main(argc, | |||
11039 | #if ENABLE_ASH_TEST || BASH_TEST2 | 11055 | #if ENABLE_ASH_TEST || BASH_TEST2 |
11040 | static int FAST_FUNC testcmd(int argc, char **argv) { return test_main(argc, argv); } | 11056 | static int FAST_FUNC testcmd(int argc, char **argv) { return test_main(argc, argv); } |
11041 | #endif | 11057 | #endif |
11058 | #if ENABLE_ASH_SLEEP | ||
11059 | static int FAST_FUNC sleepcmd(int argc, char **argv) { return sleep_main(argc, argv); } | ||
11060 | #endif | ||
11042 | 11061 | ||
11043 | /* Keep these in proper order since it is searched via bsearch() */ | 11062 | /* Keep these in proper order since it is searched via bsearch() */ |
11044 | static const struct builtincmd builtintab[] = { | 11063 | static const struct builtincmd builtintab[] = { |
@@ -11101,6 +11120,9 @@ static const struct builtincmd builtintab[] = { | |||
11101 | { BUILTIN_SPEC_REG "return" , returncmd }, | 11120 | { BUILTIN_SPEC_REG "return" , returncmd }, |
11102 | { BUILTIN_SPEC_REG "set" , setcmd }, | 11121 | { BUILTIN_SPEC_REG "set" , setcmd }, |
11103 | { BUILTIN_SPEC_REG "shift" , shiftcmd }, | 11122 | { BUILTIN_SPEC_REG "shift" , shiftcmd }, |
11123 | #if ENABLE_ASH_SLEEP | ||
11124 | { BUILTIN_REGULAR "sleep" , sleepcmd }, | ||
11125 | #endif | ||
11104 | #if BASH_SOURCE | 11126 | #if BASH_SOURCE |
11105 | { BUILTIN_SPEC_REG "source" , dotcmd }, | 11127 | { BUILTIN_SPEC_REG "source" , dotcmd }, |
11106 | #endif | 11128 | #endif |
diff --git a/shell/ash_test/ash-heredoc/heredoc_and_cmd.right b/shell/ash_test/ash-heredoc/heredoc_and_cmd.right new file mode 100644 index 000000000..25ae70561 --- /dev/null +++ b/shell/ash_test/ash-heredoc/heredoc_and_cmd.right | |||
@@ -0,0 +1,2 @@ | |||
1 | ./heredoc_and_cmd.tests: line 4: D: AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA | ||
2 | Y | ||
diff --git a/shell/ash_test/ash-heredoc/heredoc_and_cmd.tests b/shell/ash_test/ash-heredoc/heredoc_and_cmd.tests new file mode 100755 index 000000000..197542de7 --- /dev/null +++ b/shell/ash_test/ash-heredoc/heredoc_and_cmd.tests | |||
@@ -0,0 +1,8 @@ | |||
1 | # The bug was only happening with <<REDIR;CMD form below: | ||
2 | M='AAAAAAAAAAAAAAAAA' | ||
3 | fff(){ | ||
4 | date <<000; echo Y | ||
5 | ${D?$M$M$M$M$M$M} | ||
6 | 000 | ||
7 | } | ||
8 | fff | ||
diff --git a/shell/hush_test/hush-heredoc/heredoc_and_cmd.right b/shell/hush_test/hush-heredoc/heredoc_and_cmd.right new file mode 100644 index 000000000..5c19a0621 --- /dev/null +++ b/shell/hush_test/hush-heredoc/heredoc_and_cmd.right | |||
@@ -0,0 +1,2 @@ | |||
1 | hush: D: AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA | ||
2 | Y | ||
diff --git a/shell/hush_test/hush-heredoc/heredoc_and_cmd.tests b/shell/hush_test/hush-heredoc/heredoc_and_cmd.tests new file mode 100755 index 000000000..197542de7 --- /dev/null +++ b/shell/hush_test/hush-heredoc/heredoc_and_cmd.tests | |||
@@ -0,0 +1,8 @@ | |||
1 | # The bug was only happening with <<REDIR;CMD form below: | ||
2 | M='AAAAAAAAAAAAAAAAA' | ||
3 | fff(){ | ||
4 | date <<000; echo Y | ||
5 | ${D?$M$M$M$M$M$M} | ||
6 | 000 | ||
7 | } | ||
8 | fff | ||
diff --git a/testsuite/awk.tests b/testsuite/awk.tests index 93e25d8c1..bbf0fbff1 100755 --- a/testsuite/awk.tests +++ b/testsuite/awk.tests | |||
@@ -479,4 +479,10 @@ testing 'awk backslash+newline eaten with no trace' \ | |||
479 | "Hello world\n" \ | 479 | "Hello world\n" \ |
480 | '' '' | 480 | '' '' |
481 | 481 | ||
482 | testing 'awk assign while test' \ | ||
483 | "awk '\$1==\$1=\"foo\" {print \$1}'" \ | ||
484 | "foo\n" \ | ||
485 | "" \ | ||
486 | "foo" | ||
487 | |||
482 | exit $FAILCOUNT | 488 | exit $FAILCOUNT |
diff --git a/testsuite/sha1sum.tests b/testsuite/sha1sum.tests index a968fa87c..7ad1334c3 100755 --- a/testsuite/sha1sum.tests +++ b/testsuite/sha1sum.tests | |||
@@ -1,3 +1,13 @@ | |||
1 | #!/bin/sh | 1 | #!/bin/sh |
2 | 2 | ||
3 | . ./testing.sh | ||
4 | |||
5 | # testing "test name" "cmd" "expected result" "file input" "stdin" | ||
6 | >EMPTY | ||
7 | testing "sha1sum: one-space separated input for -c" \ | ||
8 | 'echo "da39a3ee5e6b4b0d3255bfef95601890afd80709 EMPTY" | sha1sum -c' \ | ||
9 | "EMPTY: OK\n" \ | ||
10 | "" "" | ||
11 | rm EMPTY | ||
12 | |||
3 | . ./md5sum.tests sha1sum d41337e834377140ae7f98460d71d908598ef04f | 13 | . ./md5sum.tests sha1sum d41337e834377140ae7f98460d71d908598ef04f |
diff --git a/testsuite/sort.tests b/testsuite/sort.tests index ff33e21b4..8dbadbdae 100755 --- a/testsuite/sort.tests +++ b/testsuite/sort.tests | |||
@@ -219,4 +219,25 @@ testing "sort -h" \ | |||
219 | 219 | ||
220 | # testing "description" "command(s)" "result" "infile" "stdin" | 220 | # testing "description" "command(s)" "result" "infile" "stdin" |
221 | 221 | ||
222 | testing "sort -k2,2M" \ | ||
223 | "sort -k2,2M input" "\ | ||
224 | 3 March | ||
225 | 2 April | ||
226 | 1 May | ||
227 | " "\ | ||
228 | 2 April | ||
229 | 1 May | ||
230 | 3 March | ||
231 | " "" | ||
232 | |||
233 | testing "sort -s -u" \ | ||
234 | "sort -s -u -k 2 input" "\ | ||
235 | z a | ||
236 | z b | ||
237 | " "\ | ||
238 | z b | ||
239 | a b | ||
240 | z a | ||
241 | a a" "" | ||
242 | |||
222 | exit $FAILCOUNT | 243 | exit $FAILCOUNT |
diff --git a/testsuite/tree.tests b/testsuite/tree.tests new file mode 100755 index 000000000..4f4a9e30b --- /dev/null +++ b/testsuite/tree.tests | |||
@@ -0,0 +1,100 @@ | |||
1 | #!/bin/sh | ||
2 | |||
3 | # Copyright 2022 by Roger Knecht <rknecht@pm.me> | ||
4 | # Licensed under GPLv2, see file LICENSE in this source tree. | ||
5 | |||
6 | . ./testing.sh -v | ||
7 | |||
8 | # testing "description" "command" "result" "infile" "stdin" | ||
9 | |||
10 | testing "tree error opening dir" \ | ||
11 | "tree tree.tempdir" \ | ||
12 | "\ | ||
13 | tree.tempdir [error opening dir]\n\ | ||
14 | \n\ | ||
15 | 0 directories, 0 files\n" \ | ||
16 | "" "" | ||
17 | |||
18 | mkdir -p tree2.tempdir | ||
19 | touch tree2.tempdir/testfile | ||
20 | |||
21 | testing "tree single file" \ | ||
22 | "cd tree2.tempdir && tree" \ | ||
23 | "\ | ||
24 | .\n\ | ||
25 | └── testfile\n\ | ||
26 | \n\ | ||
27 | 0 directories, 1 files\n" \ | ||
28 | "" "" | ||
29 | |||
30 | mkdir -p tree3.tempdir/test1 \ | ||
31 | tree3.tempdir/test2/a \ | ||
32 | tree3.tempdir/test2/b \ | ||
33 | tree3.tempdir/test3/c \ | ||
34 | tree3.tempdir/test3/d | ||
35 | |||
36 | touch tree3.tempdir/test2/a/testfile1 \ | ||
37 | tree3.tempdir/test2/a/testfile2 \ | ||
38 | tree3.tempdir/test2/a/testfile3 \ | ||
39 | tree3.tempdir/test2/b/testfile4 \ | ||
40 | tree3.tempdir/test3/c/testfile5 \ | ||
41 | tree3.tempdir/test3/d/testfile6 \ | ||
42 | tree3.tempdir/test3/d/.testfile7 | ||
43 | |||
44 | (cd tree3.tempdir/test2/a && ln -s ../b/testfile4 .) | ||
45 | (cd tree3.tempdir/test2/b && ln -s ../../test3 .) | ||
46 | |||
47 | testing "tree nested directories and files" \ | ||
48 | "cd tree3.tempdir && tree" \ | ||
49 | "\ | ||
50 | .\n\ | ||
51 | ├── test1\n\ | ||
52 | ├── test2\n\ | ||
53 | │  ├── a\n\ | ||
54 | │  │  ├── testfile1\n\ | ||
55 | │  │  ├── testfile2\n\ | ||
56 | │  │  ├── testfile3\n\ | ||
57 | │  │  └── testfile4 -> ../b/testfile4\n\ | ||
58 | │  └── b\n\ | ||
59 | │  ├── test3 -> ../../test3\n\ | ||
60 | │  └── testfile4\n\ | ||
61 | └── test3\n\ | ||
62 | ├── c\n\ | ||
63 | │  └── testfile5\n\ | ||
64 | └── d\n\ | ||
65 | └── testfile6\n\ | ||
66 | \n\ | ||
67 | 7 directories, 8 files\n" \ | ||
68 | "" "" | ||
69 | #note: tree v2.0.1 says "8 directories, 7 files": | ||
70 | #it counts "test3 -> ../../test3" as a directory, even though it does not follow this symlink | ||
71 | |||
72 | testing "tree multiple directories" \ | ||
73 | "tree tree2.tempdir tree3.tempdir" \ | ||
74 | "\ | ||
75 | tree2.tempdir\n\ | ||
76 | └── testfile\n\ | ||
77 | tree3.tempdir\n\ | ||
78 | ├── test1\n\ | ||
79 | ├── test2\n\ | ||
80 | │  ├── a\n\ | ||
81 | │  │  ├── testfile1\n\ | ||
82 | │  │  ├── testfile2\n\ | ||
83 | │  │  ├── testfile3\n\ | ||
84 | │  │  └── testfile4 -> ../b/testfile4\n\ | ||
85 | │  └── b\n\ | ||
86 | │  ├── test3 -> ../../test3\n\ | ||
87 | │  └── testfile4\n\ | ||
88 | └── test3\n\ | ||
89 | ├── c\n\ | ||
90 | │  └── testfile5\n\ | ||
91 | └── d\n\ | ||
92 | └── testfile6\n\ | ||
93 | \n\ | ||
94 | 7 directories, 9 files\n" \ | ||
95 | "" "" | ||
96 | #note: tree v2.0.1 says "8 directories, 7 files" (not "8 files", probably a/testfile4 -> ../b/testfile4 and b/testfile4 are counted as one file, not 2?) | ||
97 | |||
98 | rm -rf tree.tempdir tree2.tempdir tree3.tempdir | ||
99 | |||
100 | exit $FAILCOUNT | ||
diff --git a/testsuite/xxd.tests b/testsuite/xxd.tests index 76fa96af9..2c740abc8 100755 --- a/testsuite/xxd.tests +++ b/testsuite/xxd.tests | |||
@@ -37,4 +37,27 @@ testing 'xxd -p -r' \ | |||
37 | '' \ | 37 | '' \ |
38 | '30313233343536373736353433323130 30313233343536373736353433323130' | 38 | '30313233343536373736353433323130 30313233343536373736353433323130' |
39 | 39 | ||
40 | testing 'xxd -r skips leading whitespace and truncates at two spaces' \ | ||
41 | 'xxd -r' \ | ||
42 | '0123456789:;<=>?@' \ | ||
43 | '' "\ | ||
44 | 00000000: 3031 3233 3435 3637 3839 3a3b 3c3d 3e3f 0123456789:;<=>? | ||
45 | 00000010: 40 @ | ||
46 | " | ||
47 | |||
48 | testing 'xxd -p -r skips one bad char, truncates at two bad chars' \ | ||
49 | 'xxd -p -r' \ | ||
50 | '01' \ | ||
51 | '' "\ | ||
52 | 30 !31 !!32 | ||
53 | " | ||
54 | |||
55 | testing 'xxd -p -r ignores the nibble with 2nd char bad' \ | ||
56 | 'xxd -p -r' \ | ||
57 | '3C6' \ | ||
58 | '' "\ | ||
59 | 33 3!4 3!!5 | ||
60 | 36 | ||
61 | " | ||
62 | |||
40 | exit $FAILCOUNT | 63 | exit $FAILCOUNT |
diff --git a/util-linux/hexdump_xxd.c b/util-linux/hexdump_xxd.c index 4372ac770..6629407de 100644 --- a/util-linux/hexdump_xxd.c +++ b/util-linux/hexdump_xxd.c | |||
@@ -55,6 +55,7 @@ | |||
55 | //usage: "\n -r Reverse (with -p, assumes no offsets in input)" | 55 | //usage: "\n -r Reverse (with -p, assumes no offsets in input)" |
56 | 56 | ||
57 | #include "libbb.h" | 57 | #include "libbb.h" |
58 | #include "common_bufsiz.h" | ||
58 | #include "dump.h" | 59 | #include "dump.h" |
59 | 60 | ||
60 | /* This is a NOEXEC applet. Be very careful! */ | 61 | /* This is a NOEXEC applet. Be very careful! */ |
@@ -69,61 +70,110 @@ | |||
69 | #define OPT_c (1 << 7) | 70 | #define OPT_c (1 << 7) |
70 | #define OPT_o (1 << 8) | 71 | #define OPT_o (1 << 8) |
71 | 72 | ||
72 | static void reverse(unsigned opt, const char *filename) | 73 | #define fillbuf bb_common_bufsiz1 |
74 | |||
75 | static void write_zeros(off_t count) | ||
76 | { | ||
77 | errno = 0; | ||
78 | do { | ||
79 | unsigned sz = count < COMMON_BUFSIZE ? (unsigned)count : COMMON_BUFSIZE; | ||
80 | if (fwrite(fillbuf, 1, sz, stdout) != sz) | ||
81 | bb_perror_msg_and_die("write error"); | ||
82 | count -= sz; | ||
83 | } while (count != 0); | ||
84 | } | ||
85 | |||
86 | static void reverse(unsigned opt, const char *filename, char *opt_s) | ||
73 | { | 87 | { |
74 | FILE *fp; | 88 | FILE *fp; |
75 | char *buf; | 89 | char *buf; |
90 | off_t cur, opt_s_ofs; | ||
91 | |||
92 | memset(fillbuf, 0, COMMON_BUFSIZE); | ||
93 | opt_s_ofs = cur = 0; | ||
94 | if (opt_s) { | ||
95 | opt_s_ofs = BB_STRTOOFF(opt_s, NULL, 0); | ||
96 | if (errno || opt_s_ofs < 0) | ||
97 | bb_error_msg_and_die("invalid number '%s'", opt_s); | ||
98 | } | ||
76 | 99 | ||
77 | fp = filename ? xfopen_for_read(filename) : stdin; | 100 | fp = filename ? xfopen_for_read(filename) : stdin; |
78 | 101 | ||
102 | get_new_line: | ||
79 | while ((buf = xmalloc_fgetline(fp)) != NULL) { | 103 | while ((buf = xmalloc_fgetline(fp)) != NULL) { |
80 | char *p; | 104 | char *p; |
81 | 105 | ||
82 | p = buf; | 106 | p = buf; |
83 | if (!(opt & OPT_p)) { | 107 | if (!(opt & OPT_p)) { |
84 | /* skip address */ | 108 | char *end; |
85 | while (isxdigit(*p)) p++; | 109 | off_t ofs; |
110 | skip_address: | ||
111 | p = skip_whitespace(p); | ||
112 | ofs = BB_STRTOOFF(p, &end, 16); | ||
113 | if ((errno && errno != EINVAL) | ||
114 | || ofs < 0 | ||
115 | /* -s SEEK value should be added before seeking */ | ||
116 | || (ofs += opt_s_ofs) < 0 | ||
117 | ) { | ||
118 | bb_error_msg_and_die("invalid number '%s'", p); | ||
119 | } | ||
120 | if (ofs != cur) { | ||
121 | if (fseeko(stdout, ofs, SEEK_SET) != 0) { | ||
122 | if (ofs < cur) | ||
123 | bb_perror_msg_and_die("cannot seek"); | ||
124 | write_zeros(ofs - cur); | ||
125 | } | ||
126 | cur = ofs; | ||
127 | } | ||
128 | p = end; | ||
86 | /* NB: for xxd -r, first hex portion is address even without colon */ | 129 | /* NB: for xxd -r, first hex portion is address even without colon */ |
87 | /* If it's there, skip it: */ | 130 | /* But if colon is there, skip it: */ |
88 | if (*p == ':') p++; | 131 | if (*p == ':') |
89 | 132 | p++; | |
90 | //TODO: seek (or zero-pad if unseekable) to the address position | ||
91 | //NOTE: -s SEEK value should be added to the address before seeking | ||
92 | } | 133 | } |
93 | 134 | ||
94 | /* Process hex bytes optionally separated by whitespace */ | 135 | /* Process hex bytes optionally separated by whitespace */ |
95 | for (;;) { | 136 | for (;;) { |
96 | uint8_t val, c; | 137 | uint8_t val, c; |
138 | int badchar = 0; | ||
97 | nibble1: | 139 | nibble1: |
98 | p = skip_whitespace(p); | 140 | if (opt & OPT_p) |
99 | 141 | p = skip_whitespace(p); | |
100 | c = *p++; | 142 | c = *p++; |
101 | if (isdigit(c)) | 143 | if (isdigit(c)) |
102 | val = c - '0'; | 144 | val = c - '0'; |
103 | else if ((c|0x20) >= 'a' && (c|0x20) <= 'f') | 145 | else if ((c|0x20) >= 'a' && (c|0x20) <= 'f') |
104 | val = (c|0x20) - ('a' - 10); | 146 | val = (c|0x20) - ('a' - 10); |
105 | else { | 147 | else { |
106 | /* xxd V1.10 is inconsistent here. | 148 | /* xxd V1.10 allows one non-hexnum char: |
107 | * echo -e "31 !3 0a 0a" | xxd -r -p | 149 | * echo -e "31 !3 0a 0a" | xxd -r -p |
108 | * is "10<a0>" (no <cr>) - "!" is ignored, | 150 | * is "10<a0>" (no <cr>) - "!" is ignored, |
109 | * but | 151 | * but stops for more than one: |
110 | * echo -e "31 !!343434\n30 0a" | xxd -r -p | 152 | * echo -e "31 !!343434\n30 0a" | xxd -r -p |
111 | * is "10<cr>" - "!!" drops rest of the line. | 153 | * is "10<cr>" - "!!" drops rest of the line. |
112 | * We will ignore all invalid chars: | 154 | * Note: this also covers whitespace chars: |
155 | * xxxxxxxx: 3031 3233 3435 3637 3839 3a3b 3c3d 3e3f 0123456789:;<=>? | ||
156 | * detects this ^ - skips this one space | ||
157 | * xxxxxxxx: 3031 3233 3435 3637 3839 3a3b 3c3d 3e3f 0123456789:;<=>? | ||
158 | * detects this ^^ - skips the rest | ||
113 | */ | 159 | */ |
114 | if (c != '\0') | 160 | if (c == '\0' || badchar) |
115 | goto nibble1; | 161 | break; |
116 | break; | 162 | badchar++; |
163 | goto nibble1; | ||
117 | } | 164 | } |
118 | val <<= 4; | 165 | val <<= 4; |
119 | 166 | ||
120 | /* Works the same with xxd V1.10: | ||
121 | * echo "31 09 32 0a" | xxd -r -p | ||
122 | * echo "31 0 9 32 0a" | xxd -r -p | ||
123 | * thus allow whitespace even within the byte: | ||
124 | */ | ||
125 | nibble2: | 167 | nibble2: |
126 | p = skip_whitespace(p); | 168 | if (opt & OPT_p) { |
169 | /* Works the same with xxd V1.10: | ||
170 | * echo "31 09 32 0a" | xxd -r -p | ||
171 | * echo "31 0 9 32 0a" | xxd -r -p | ||
172 | * thus allow whitespace (even multiple chars) | ||
173 | * after byte's 1st char: | ||
174 | */ | ||
175 | p = skip_whitespace(p); | ||
176 | } | ||
127 | 177 | ||
128 | c = *p++; | 178 | c = *p++; |
129 | if (isdigit(c)) | 179 | if (isdigit(c)) |
@@ -132,7 +182,16 @@ static void reverse(unsigned opt, const char *filename) | |||
132 | val |= (c|0x20) - ('a' - 10); | 182 | val |= (c|0x20) - ('a' - 10); |
133 | else { | 183 | else { |
134 | if (c != '\0') { | 184 | if (c != '\0') { |
135 | /* "...3<not_hex_char>..." ignores both chars */ | 185 | /* "...3<not_hex_char>...": ignore "3", |
186 | * skip everything up to next hexchar or newline: | ||
187 | */ | ||
188 | while (!isxdigit(*p)) { | ||
189 | if (*p == '\0') { | ||
190 | free(buf); | ||
191 | goto get_new_line; | ||
192 | } | ||
193 | p++; | ||
194 | } | ||
136 | goto nibble1; | 195 | goto nibble1; |
137 | } | 196 | } |
138 | /* Nibbles can join even through newline: | 197 | /* Nibbles can join even through newline: |
@@ -143,10 +202,13 @@ static void reverse(unsigned opt, const char *filename) | |||
143 | p = buf = xmalloc_fgetline(fp); | 202 | p = buf = xmalloc_fgetline(fp); |
144 | if (!buf) | 203 | if (!buf) |
145 | break; | 204 | break; |
205 | if (!(opt & OPT_p)) /* -p and !-p: different behavior */ | ||
206 | goto skip_address; | ||
146 | goto nibble2; | 207 | goto nibble2; |
147 | } | 208 | } |
148 | putchar(val); | 209 | putchar(val); |
149 | } | 210 | cur++; |
211 | } /* for(;;) */ | ||
150 | free(buf); | 212 | free(buf); |
151 | } | 213 | } |
152 | //fclose(fp); | 214 | //fclose(fp); |
@@ -173,6 +235,8 @@ int xxd_main(int argc UNUSED_PARAM, char **argv) | |||
173 | unsigned opt; | 235 | unsigned opt; |
174 | int r; | 236 | int r; |
175 | 237 | ||
238 | setup_common_bufsiz(); | ||
239 | |||
176 | dumper = alloc_dumper(); | 240 | dumper = alloc_dumper(); |
177 | 241 | ||
178 | opt = getopt32(argv, "^" "l:s:apirg:+c:+o:" "\0" "?1" /* 1 argument max */, | 242 | opt = getopt32(argv, "^" "l:s:apirg:+c:+o:" "\0" "?1" /* 1 argument max */, |
@@ -200,7 +264,7 @@ int xxd_main(int argc UNUSED_PARAM, char **argv) | |||
200 | } | 264 | } |
201 | 265 | ||
202 | if (opt & OPT_r) { | 266 | if (opt & OPT_r) { |
203 | reverse(opt, argv[0]); | 267 | reverse(opt, argv[0], opt_s); |
204 | } | 268 | } |
205 | 269 | ||
206 | if (opt & OPT_o) { | 270 | if (opt & OPT_o) { |