diff options
231 files changed, 12695 insertions, 2708 deletions
@@ -36,7 +36,7 @@ config DESKTOP | |||
36 | 36 | ||
37 | If you are preparing your build to be used on an embedded box | 37 | If you are preparing your build to be used on an embedded box |
38 | where you have tighter control over the entire set of userspace | 38 | where you have tighter control over the entire set of userspace |
39 | tools, you can unselect this option for smaller code size. | 39 | tools, you can unselect this option for smaller code size. |
40 | 40 | ||
41 | config EXTRA_COMPAT | 41 | config EXTRA_COMPAT |
42 | bool "Provide compatible behavior for rare corner cases (bigger code)" | 42 | bool "Provide compatible behavior for rare corner cases (bigger code)" |
@@ -64,17 +64,6 @@ config USE_PORTABLE_CODE | |||
64 | compiler other than gcc. | 64 | compiler other than gcc. |
65 | If you do use gcc, this option may needlessly increase code size. | 65 | If you do use gcc, this option may needlessly increase code size. |
66 | 66 | ||
67 | config PLATFORM_LINUX | ||
68 | bool "Enable Linux-specific applets and features" | ||
69 | default y | ||
70 | help | ||
71 | For the most part, busybox requires only POSIX compatibility | ||
72 | from the target system, but some applets and features use | ||
73 | Linux-specific interfaces. | ||
74 | |||
75 | Answering 'N' here will disable such applets and hide the | ||
76 | corresponding configuration options. | ||
77 | |||
78 | config SHOW_USAGE | 67 | config SHOW_USAGE |
79 | bool "Show applet usage messages" | 68 | bool "Show applet usage messages" |
80 | default y | 69 | default y |
@@ -138,14 +127,14 @@ config INSTALL_NO_USR | |||
138 | never to /usr/bin or /usr/sbin. | 127 | never to /usr/bin or /usr/sbin. |
139 | 128 | ||
140 | config PAM | 129 | config PAM |
141 | bool "Support for PAM (Pluggable Authentication Modules)" | 130 | bool "Support PAM (Pluggable Authentication Modules)" |
142 | default n | 131 | default n |
143 | help | 132 | help |
144 | Use PAM in some busybox applets (currently login and httpd) instead | 133 | Use PAM in some busybox applets (currently login and httpd) instead |
145 | of direct access to password database. | 134 | of direct access to password database. |
146 | 135 | ||
147 | config LONG_OPTS | 136 | config LONG_OPTS |
148 | bool "Support for --long-options" | 137 | bool "Support --long-options" |
149 | default y | 138 | default y |
150 | help | 139 | help |
151 | Enable this if you want busybox applets to use the gnu --long-option | 140 | Enable this if you want busybox applets to use the gnu --long-option |
@@ -212,7 +201,7 @@ config PID_FILE_PATH | |||
212 | specify a pidfile path. | 201 | specify a pidfile path. |
213 | 202 | ||
214 | config FEATURE_SUID | 203 | config FEATURE_SUID |
215 | bool "Support for SUID/SGID handling" | 204 | bool "Support SUID/SGID handling" |
216 | default y | 205 | default y |
217 | help | 206 | help |
218 | With this option you can install the busybox binary belonging | 207 | With this option you can install the busybox binary belonging |
@@ -352,6 +341,17 @@ config FEATURE_HAVE_RPC | |||
352 | # This is automatically selected if any of enabled applets need it. | 341 | # This is automatically selected if any of enabled applets need it. |
353 | # You do not need to select it manually. | 342 | # You do not need to select it manually. |
354 | 343 | ||
344 | config PLATFORM_LINUX | ||
345 | bool #No description makes it a hidden option | ||
346 | default n | ||
347 | #help | ||
348 | # For the most part, busybox requires only POSIX compatibility | ||
349 | # from the target system, but some applets and features use | ||
350 | # Linux-specific interfaces. | ||
351 | # | ||
352 | # This is automatically selected if any applet or feature requires | ||
353 | # Linux-specific interfaces. You do not need to select it manually. | ||
354 | |||
355 | comment 'Build Options' | 355 | comment 'Build Options' |
356 | 356 | ||
357 | config STATIC | 357 | config STATIC |
@@ -647,6 +647,8 @@ config DEBUG_SANITIZE | |||
647 | catch bad memory accesses (e.g. buffer overflows), but will make | 647 | catch bad memory accesses (e.g. buffer overflows), but will make |
648 | the executable larger and slow down runtime a bit. | 648 | the executable larger and slow down runtime a bit. |
649 | 649 | ||
650 | This adds -fsanitize=foo options to gcc command line. | ||
651 | |||
650 | If you aren't developing/testing busybox, say N here. | 652 | If you aren't developing/testing busybox, say N here. |
651 | 653 | ||
652 | config UNIT_TEST | 654 | config UNIT_TEST |
@@ -661,7 +663,7 @@ config WERROR | |||
661 | bool "Abort compilation on any warning" | 663 | bool "Abort compilation on any warning" |
662 | default n | 664 | default n |
663 | help | 665 | help |
664 | Selecting this will add -Werror to gcc command line. | 666 | This adds -Werror to gcc command line. |
665 | 667 | ||
666 | Most people should answer N. | 668 | Most people should answer N. |
667 | 669 | ||
diff --git a/archival/Config.src b/archival/Config.src index 5e7cfc0a4..0c97f3d7c 100644 --- a/archival/Config.src +++ b/archival/Config.src | |||
@@ -8,32 +8,22 @@ menu "Archival Utilities" | |||
8 | config FEATURE_SEAMLESS_XZ | 8 | config FEATURE_SEAMLESS_XZ |
9 | bool "Make tar, rpm, modprobe etc understand .xz data" | 9 | bool "Make tar, rpm, modprobe etc understand .xz data" |
10 | default y | 10 | default y |
11 | help | ||
12 | Make tar, rpm, modprobe etc understand .xz data. | ||
13 | 11 | ||
14 | config FEATURE_SEAMLESS_LZMA | 12 | config FEATURE_SEAMLESS_LZMA |
15 | bool "Make tar, rpm, modprobe etc understand .lzma data" | 13 | bool "Make tar, rpm, modprobe etc understand .lzma data" |
16 | default y | 14 | default y |
17 | help | ||
18 | Make tar, rpm, modprobe etc understand .lzma data. | ||
19 | 15 | ||
20 | config FEATURE_SEAMLESS_BZ2 | 16 | config FEATURE_SEAMLESS_BZ2 |
21 | bool "Make tar, rpm, modprobe etc understand .bz2 data" | 17 | bool "Make tar, rpm, modprobe etc understand .bz2 data" |
22 | default y | 18 | default y |
23 | help | ||
24 | Make tar, rpm, modprobe etc understand .bz2 data. | ||
25 | 19 | ||
26 | config FEATURE_SEAMLESS_GZ | 20 | config FEATURE_SEAMLESS_GZ |
27 | bool "Make tar, rpm, modprobe etc understand .gz data" | 21 | bool "Make tar, rpm, modprobe etc understand .gz data" |
28 | default y | 22 | default y |
29 | help | ||
30 | Make tar, rpm, modprobe etc understand .gz data. | ||
31 | 23 | ||
32 | config FEATURE_SEAMLESS_Z | 24 | config FEATURE_SEAMLESS_Z |
33 | bool "Make tar, rpm, modprobe etc understand .Z data" | 25 | bool "Make tar, rpm, modprobe etc understand .Z data" |
34 | default n # it is ancient | 26 | default n # it is ancient |
35 | help | ||
36 | Make tar, rpm, modprobe etc understand .Z data. | ||
37 | 27 | ||
38 | INSERT | 28 | INSERT |
39 | 29 | ||
diff --git a/archival/ar.c b/archival/ar.c index a850868f6..f9f712fde 100644 --- a/archival/ar.c +++ b/archival/ar.c | |||
@@ -31,7 +31,7 @@ | |||
31 | //config: probably say N here: most compilers come with their own ar utility. | 31 | //config: probably say N here: most compilers come with their own ar utility. |
32 | //config: | 32 | //config: |
33 | //config:config FEATURE_AR_LONG_FILENAMES | 33 | //config:config FEATURE_AR_LONG_FILENAMES |
34 | //config: bool "Support for long filenames (not needed for debs)" | 34 | //config: bool "Support long filenames (not needed for debs)" |
35 | //config: default y | 35 | //config: default y |
36 | //config: depends on AR | 36 | //config: depends on AR |
37 | //config: help | 37 | //config: help |
diff --git a/archival/bbunzip.c b/archival/bbunzip.c index 343aec9bd..311c7333e 100644 --- a/archival/bbunzip.c +++ b/archival/bbunzip.c | |||
@@ -12,9 +12,9 @@ | |||
12 | //kbuild:lib-$(CONFIG_LZOPCAT) += bbunzip.o | 12 | //kbuild:lib-$(CONFIG_LZOPCAT) += bbunzip.o |
13 | //kbuild:lib-$(CONFIG_UNLZOP) += bbunzip.o | 13 | //kbuild:lib-$(CONFIG_UNLZOP) += bbunzip.o |
14 | /* bzip2_main() too: */ | 14 | /* bzip2_main() too: */ |
15 | //kbuild:lib-$(CONFIG_BZIP2) += bbunzip.o | 15 | //kbuild:lib-$(CONFIG_FEATURE_BZIP2_DECOMPRESS) += bbunzip.o |
16 | /* gzip_main() too: */ | 16 | /* gzip_main() too: */ |
17 | //kbuild:lib-$(CONFIG_GZIP) += bbunzip.o | 17 | //kbuild:lib-$(CONFIG_FEATURE_GZIP_DECOMPRESS) += bbunzip.o |
18 | 18 | ||
19 | /* Note: must be kept in sync with archival/lzop.c */ | 19 | /* Note: must be kept in sync with archival/lzop.c */ |
20 | enum { | 20 | enum { |
@@ -25,7 +25,7 @@ enum { | |||
25 | OPT_QUIET = 1 << 3, | 25 | OPT_QUIET = 1 << 3, |
26 | OPT_DECOMPRESS = 1 << 4, | 26 | OPT_DECOMPRESS = 1 << 4, |
27 | OPT_TEST = 1 << 5, | 27 | OPT_TEST = 1 << 5, |
28 | SEAMLESS_MAGIC = (1 << 31) * SEAMLESS_COMPRESSION, | 28 | SEAMLESS_MAGIC = (1 << 31) * ENABLE_ZCAT * SEAMLESS_COMPRESSION, |
29 | }; | 29 | }; |
30 | 30 | ||
31 | static | 31 | static |
@@ -127,7 +127,7 @@ int FAST_FUNC bbunpack(char **argv, | |||
127 | 127 | ||
128 | if (!(option_mask32 & SEAMLESS_MAGIC)) { | 128 | if (!(option_mask32 & SEAMLESS_MAGIC)) { |
129 | init_transformer_state(&xstate); | 129 | init_transformer_state(&xstate); |
130 | xstate.signature_skipped = 0; | 130 | /*xstate.signature_skipped = 0; - already is */ |
131 | /*xstate.src_fd = STDIN_FILENO; - already is */ | 131 | /*xstate.src_fd = STDIN_FILENO; - already is */ |
132 | xstate.dst_fd = STDOUT_FILENO; | 132 | xstate.dst_fd = STDOUT_FILENO; |
133 | status = unpacker(&xstate); | 133 | status = unpacker(&xstate); |
@@ -199,7 +199,7 @@ int FAST_FUNC bbunpack(char **argv, | |||
199 | } | 199 | } |
200 | 200 | ||
201 | #if ENABLE_UNCOMPRESS \ | 201 | #if ENABLE_UNCOMPRESS \ |
202 | || ENABLE_BUNZIP2 || ENABLE_BZCAT \ | 202 | || ENABLE_FEATURE_BZIP2_DECOMPRESS \ |
203 | || ENABLE_UNLZMA || ENABLE_LZCAT || ENABLE_LZMA \ | 203 | || ENABLE_UNLZMA || ENABLE_LZCAT || ENABLE_LZMA \ |
204 | || ENABLE_UNXZ || ENABLE_XZCAT || ENABLE_XZ | 204 | || ENABLE_UNXZ || ENABLE_XZCAT || ENABLE_XZ |
205 | static | 205 | static |
@@ -297,6 +297,7 @@ int uncompress_main(int argc UNUSED_PARAM, char **argv) | |||
297 | //config:config GUNZIP | 297 | //config:config GUNZIP |
298 | //config: bool "gunzip" | 298 | //config: bool "gunzip" |
299 | //config: default y | 299 | //config: default y |
300 | //config: select FEATURE_GZIP_DECOMPRESS | ||
300 | //config: help | 301 | //config: help |
301 | //config: gunzip is used to decompress archives created by gzip. | 302 | //config: gunzip is used to decompress archives created by gzip. |
302 | //config: You can use the `-t' option to test the integrity of | 303 | //config: You can use the `-t' option to test the integrity of |
@@ -305,6 +306,7 @@ int uncompress_main(int argc UNUSED_PARAM, char **argv) | |||
305 | //config:config ZCAT | 306 | //config:config ZCAT |
306 | //config: bool "zcat" | 307 | //config: bool "zcat" |
307 | //config: default y | 308 | //config: default y |
309 | //config: select FEATURE_GZIP_DECOMPRESS | ||
308 | //config: help | 310 | //config: help |
309 | //config: Alias to "gunzip -c". | 311 | //config: Alias to "gunzip -c". |
310 | //config: | 312 | //config: |
@@ -312,14 +314,11 @@ int uncompress_main(int argc UNUSED_PARAM, char **argv) | |||
312 | //config: bool "Enable long options" | 314 | //config: bool "Enable long options" |
313 | //config: default y | 315 | //config: default y |
314 | //config: depends on (GUNZIP || ZCAT) && LONG_OPTS | 316 | //config: depends on (GUNZIP || ZCAT) && LONG_OPTS |
315 | //config: help | ||
316 | //config: Enable use of long options. | ||
317 | 317 | ||
318 | //applet:IF_GUNZIP(APPLET(gunzip, BB_DIR_BIN, BB_SUID_DROP)) | 318 | //applet:IF_GUNZIP(APPLET(gunzip, BB_DIR_BIN, BB_SUID_DROP)) |
319 | // APPLET_ODDNAME:name main location suid_type help | ||
319 | //applet:IF_ZCAT(APPLET_ODDNAME(zcat, gunzip, BB_DIR_BIN, BB_SUID_DROP, zcat)) | 320 | //applet:IF_ZCAT(APPLET_ODDNAME(zcat, gunzip, BB_DIR_BIN, BB_SUID_DROP, zcat)) |
320 | //kbuild:lib-$(CONFIG_GUNZIP) += bbunzip.o | 321 | #if ENABLE_FEATURE_GZIP_DECOMPRESS |
321 | //kbuild:lib-$(CONFIG_ZCAT) += bbunzip.o | ||
322 | #if ENABLE_GUNZIP || ENABLE_ZCAT | ||
323 | static | 322 | static |
324 | char* FAST_FUNC make_new_name_gunzip(char *filename, const char *expected_ext UNUSED_PARAM) | 323 | char* FAST_FUNC make_new_name_gunzip(char *filename, const char *expected_ext UNUSED_PARAM) |
325 | { | 324 | { |
@@ -387,7 +386,7 @@ int gunzip_main(int argc UNUSED_PARAM, char **argv) | |||
387 | 386 | ||
388 | return bbunpack(argv, unpack_gz_stream, make_new_name_gunzip, /*unused:*/ NULL); | 387 | return bbunpack(argv, unpack_gz_stream, make_new_name_gunzip, /*unused:*/ NULL); |
389 | } | 388 | } |
390 | #endif | 389 | #endif /* FEATURE_GZIP_DECOMPRESS */ |
391 | 390 | ||
392 | 391 | ||
393 | /* | 392 | /* |
@@ -410,6 +409,7 @@ int gunzip_main(int argc UNUSED_PARAM, char **argv) | |||
410 | //config:config BUNZIP2 | 409 | //config:config BUNZIP2 |
411 | //config: bool "bunzip2" | 410 | //config: bool "bunzip2" |
412 | //config: default y | 411 | //config: default y |
412 | //config: select FEATURE_BZIP2_DECOMPRESS | ||
413 | //config: help | 413 | //config: help |
414 | //config: bunzip2 is a compression utility using the Burrows-Wheeler block | 414 | //config: bunzip2 is a compression utility using the Burrows-Wheeler block |
415 | //config: sorting text compression algorithm, and Huffman coding. Compression | 415 | //config: sorting text compression algorithm, and Huffman coding. Compression |
@@ -423,14 +423,14 @@ int gunzip_main(int argc UNUSED_PARAM, char **argv) | |||
423 | //config:config BZCAT | 423 | //config:config BZCAT |
424 | //config: bool "bzcat" | 424 | //config: bool "bzcat" |
425 | //config: default y | 425 | //config: default y |
426 | //config: select FEATURE_BZIP2_DECOMPRESS | ||
426 | //config: help | 427 | //config: help |
427 | //config: Alias to "bunzip2 -c". | 428 | //config: Alias to "bunzip2 -c". |
428 | 429 | ||
429 | //applet:IF_BUNZIP2(APPLET(bunzip2, BB_DIR_USR_BIN, BB_SUID_DROP)) | 430 | //applet:IF_BUNZIP2(APPLET(bunzip2, BB_DIR_USR_BIN, BB_SUID_DROP)) |
431 | // APPLET_ODDNAME:name main location suid_type help | ||
430 | //applet:IF_BZCAT(APPLET_ODDNAME(bzcat, bunzip2, BB_DIR_USR_BIN, BB_SUID_DROP, bzcat)) | 432 | //applet:IF_BZCAT(APPLET_ODDNAME(bzcat, bunzip2, BB_DIR_USR_BIN, BB_SUID_DROP, bzcat)) |
431 | //kbuild:lib-$(CONFIG_BUNZIP2) += bbunzip.o | 433 | #if ENABLE_FEATURE_BZIP2_DECOMPRESS |
432 | //kbuild:lib-$(CONFIG_BZCAT) += bbunzip.o | ||
433 | #if ENABLE_BUNZIP2 || ENABLE_BZCAT | ||
434 | int bunzip2_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; | 434 | int bunzip2_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; |
435 | int bunzip2_main(int argc UNUSED_PARAM, char **argv) | 435 | int bunzip2_main(int argc UNUSED_PARAM, char **argv) |
436 | { | 436 | { |
@@ -471,26 +471,6 @@ int bunzip2_main(int argc UNUSED_PARAM, char **argv) | |||
471 | //usage: "[FILE]..." | 471 | //usage: "[FILE]..." |
472 | //usage:#define lzcat_full_usage "\n\n" | 472 | //usage:#define lzcat_full_usage "\n\n" |
473 | //usage: "Decompress to stdout" | 473 | //usage: "Decompress to stdout" |
474 | //usage: | ||
475 | //usage:#define unxz_trivial_usage | ||
476 | //usage: "[-cf] [FILE]..." | ||
477 | //usage:#define unxz_full_usage "\n\n" | ||
478 | //usage: "Decompress FILE (or stdin)\n" | ||
479 | //usage: "\n -c Write to stdout" | ||
480 | //usage: "\n -f Force" | ||
481 | //usage: | ||
482 | //usage:#define xz_trivial_usage | ||
483 | //usage: "-d [-cf] [FILE]..." | ||
484 | //usage:#define xz_full_usage "\n\n" | ||
485 | //usage: "Decompress FILE (or stdin)\n" | ||
486 | //usage: "\n -d Decompress" | ||
487 | //usage: "\n -c Write to stdout" | ||
488 | //usage: "\n -f Force" | ||
489 | //usage: | ||
490 | //usage:#define xzcat_trivial_usage | ||
491 | //usage: "[FILE]..." | ||
492 | //usage:#define xzcat_full_usage "\n\n" | ||
493 | //usage: "Decompress to stdout" | ||
494 | 474 | ||
495 | //config:config UNLZMA | 475 | //config:config UNLZMA |
496 | //config: bool "unlzma" | 476 | //config: bool "unlzma" |
@@ -524,7 +504,7 @@ int bunzip2_main(int argc UNUSED_PARAM, char **argv) | |||
524 | //config: IOW: you'll get lzma applet, but it will always require -d option. | 504 | //config: IOW: you'll get lzma applet, but it will always require -d option. |
525 | //config: | 505 | //config: |
526 | //config:config FEATURE_LZMA_FAST | 506 | //config:config FEATURE_LZMA_FAST |
527 | //config: bool "Optimize unlzma for speed" | 507 | //config: bool "Optimize for speed" |
528 | //config: default n | 508 | //config: default n |
529 | //config: depends on UNLZMA || LZCAT || LZMA | 509 | //config: depends on UNLZMA || LZCAT || LZMA |
530 | //config: help | 510 | //config: help |
@@ -532,8 +512,9 @@ int bunzip2_main(int argc UNUSED_PARAM, char **argv) | |||
532 | //config: a 1K bigger binary. | 512 | //config: a 1K bigger binary. |
533 | 513 | ||
534 | //applet:IF_UNLZMA(APPLET(unlzma, BB_DIR_USR_BIN, BB_SUID_DROP)) | 514 | //applet:IF_UNLZMA(APPLET(unlzma, BB_DIR_USR_BIN, BB_SUID_DROP)) |
515 | // APPLET_ODDNAME:name main location suid_type help | ||
535 | //applet:IF_LZCAT(APPLET_ODDNAME(lzcat, unlzma, BB_DIR_USR_BIN, BB_SUID_DROP, lzcat)) | 516 | //applet:IF_LZCAT(APPLET_ODDNAME(lzcat, unlzma, BB_DIR_USR_BIN, BB_SUID_DROP, lzcat)) |
536 | //applet:IF_LZMA(APPLET_ODDNAME(lzma, unlzma, BB_DIR_USR_BIN, BB_SUID_DROP, lzma)) | 517 | //applet:IF_LZMA( APPLET_ODDNAME(lzma, unlzma, BB_DIR_USR_BIN, BB_SUID_DROP, lzma)) |
537 | //kbuild:lib-$(CONFIG_UNLZMA) += bbunzip.o | 518 | //kbuild:lib-$(CONFIG_UNLZMA) += bbunzip.o |
538 | //kbuild:lib-$(CONFIG_LZCAT) += bbunzip.o | 519 | //kbuild:lib-$(CONFIG_LZCAT) += bbunzip.o |
539 | //kbuild:lib-$(CONFIG_LZMA) += bbunzip.o | 520 | //kbuild:lib-$(CONFIG_LZMA) += bbunzip.o |
@@ -557,6 +538,26 @@ int unlzma_main(int argc UNUSED_PARAM, char **argv) | |||
557 | #endif | 538 | #endif |
558 | 539 | ||
559 | 540 | ||
541 | //usage:#define unxz_trivial_usage | ||
542 | //usage: "[-cf] [FILE]..." | ||
543 | //usage:#define unxz_full_usage "\n\n" | ||
544 | //usage: "Decompress FILE (or stdin)\n" | ||
545 | //usage: "\n -c Write to stdout" | ||
546 | //usage: "\n -f Force" | ||
547 | //usage: | ||
548 | //usage:#define xz_trivial_usage | ||
549 | //usage: "-d [-cf] [FILE]..." | ||
550 | //usage:#define xz_full_usage "\n\n" | ||
551 | //usage: "Decompress FILE (or stdin)\n" | ||
552 | //usage: "\n -d Decompress" | ||
553 | //usage: "\n -c Write to stdout" | ||
554 | //usage: "\n -f Force" | ||
555 | //usage: | ||
556 | //usage:#define xzcat_trivial_usage | ||
557 | //usage: "[FILE]..." | ||
558 | //usage:#define xzcat_full_usage "\n\n" | ||
559 | //usage: "Decompress to stdout" | ||
560 | |||
560 | //config:config UNXZ | 561 | //config:config UNXZ |
561 | //config: bool "unxz" | 562 | //config: bool "unxz" |
562 | //config: default y | 563 | //config: default y |
@@ -577,8 +578,9 @@ int unlzma_main(int argc UNUSED_PARAM, char **argv) | |||
577 | //config: IOW: you'll get xz applet, but it will always require -d option. | 578 | //config: IOW: you'll get xz applet, but it will always require -d option. |
578 | 579 | ||
579 | //applet:IF_UNXZ(APPLET(unxz, BB_DIR_USR_BIN, BB_SUID_DROP)) | 580 | //applet:IF_UNXZ(APPLET(unxz, BB_DIR_USR_BIN, BB_SUID_DROP)) |
581 | // APPLET_ODDNAME:name main location suid_type help | ||
580 | //applet:IF_XZCAT(APPLET_ODDNAME(xzcat, unxz, BB_DIR_USR_BIN, BB_SUID_DROP, xzcat)) | 582 | //applet:IF_XZCAT(APPLET_ODDNAME(xzcat, unxz, BB_DIR_USR_BIN, BB_SUID_DROP, xzcat)) |
581 | //applet:IF_XZ(APPLET_ODDNAME(xz, unxz, BB_DIR_USR_BIN, BB_SUID_DROP, xz)) | 583 | //applet:IF_XZ( APPLET_ODDNAME(xz, unxz, BB_DIR_USR_BIN, BB_SUID_DROP, xz)) |
582 | //kbuild:lib-$(CONFIG_UNXZ) += bbunzip.o | 584 | //kbuild:lib-$(CONFIG_UNXZ) += bbunzip.o |
583 | //kbuild:lib-$(CONFIG_XZCAT) += bbunzip.o | 585 | //kbuild:lib-$(CONFIG_XZCAT) += bbunzip.o |
584 | //kbuild:lib-$(CONFIG_XZ) += bbunzip.o | 586 | //kbuild:lib-$(CONFIG_XZ) += bbunzip.o |
diff --git a/archival/bzip2.c b/archival/bzip2.c index 47fa29af3..7e38e78b3 100644 --- a/archival/bzip2.c +++ b/archival/bzip2.c | |||
@@ -19,6 +19,15 @@ | |||
19 | //config: | 19 | //config: |
20 | //config: Unless you have a specific application which requires bzip2, you | 20 | //config: Unless you have a specific application which requires bzip2, you |
21 | //config: should probably say N here. | 21 | //config: should probably say N here. |
22 | //config: | ||
23 | //config:config FEATURE_BZIP2_DECOMPRESS | ||
24 | //config: bool "Enable decompression" | ||
25 | //config: default y | ||
26 | //config: depends on BZIP2 || BUNZIP2 || BZCAT | ||
27 | //config: help | ||
28 | //config: Enable -d (--decompress) and -t (--test) options for bzip2. | ||
29 | //config: This will be automatically selected if bunzip2 or bzcat is | ||
30 | //config: enabled. | ||
22 | 31 | ||
23 | //applet:IF_BZIP2(APPLET(bzip2, BB_DIR_USR_BIN, BB_SUID_DROP)) | 32 | //applet:IF_BZIP2(APPLET(bzip2, BB_DIR_USR_BIN, BB_SUID_DROP)) |
24 | //kbuild:lib-$(CONFIG_BZIP2) += bzip2.o | 33 | //kbuild:lib-$(CONFIG_BZIP2) += bzip2.o |
@@ -28,7 +37,10 @@ | |||
28 | //usage:#define bzip2_full_usage "\n\n" | 37 | //usage:#define bzip2_full_usage "\n\n" |
29 | //usage: "Compress FILEs (or stdin) with bzip2 algorithm\n" | 38 | //usage: "Compress FILEs (or stdin) with bzip2 algorithm\n" |
30 | //usage: "\n -1..9 Compression level" | 39 | //usage: "\n -1..9 Compression level" |
40 | //usage: IF_FEATURE_BZIP2_DECOMPRESS( | ||
31 | //usage: "\n -d Decompress" | 41 | //usage: "\n -d Decompress" |
42 | //usage: "\n -t Test file integrity" | ||
43 | //usage: ) | ||
32 | //usage: "\n -c Write to stdout" | 44 | //usage: "\n -c Write to stdout" |
33 | //usage: "\n -f Force" | 45 | //usage: "\n -f Force" |
34 | 46 | ||
@@ -184,8 +196,8 @@ int bzip2_main(int argc UNUSED_PARAM, char **argv) | |||
184 | 196 | ||
185 | opt_complementary = "s2"; /* -s means -2 (compatibility) */ | 197 | opt_complementary = "s2"; /* -s means -2 (compatibility) */ |
186 | /* Must match bbunzip's constants OPT_STDOUT, OPT_FORCE! */ | 198 | /* Must match bbunzip's constants OPT_STDOUT, OPT_FORCE! */ |
187 | opt = getopt32(argv, "cfv" IF_BUNZIP2("dt") "123456789qzs"); | 199 | opt = getopt32(argv, "cfv" IF_FEATURE_BZIP2_DECOMPRESS("dt") "123456789qzs"); |
188 | #if ENABLE_BUNZIP2 /* bunzip2_main may not be visible... */ | 200 | #if ENABLE_FEATURE_BZIP2_DECOMPRESS /* bunzip2_main may not be visible... */ |
189 | if (opt & 0x18) // -d and/or -t | 201 | if (opt & 0x18) // -d and/or -t |
190 | return bunzip2_main(argc, argv); | 202 | return bunzip2_main(argc, argv); |
191 | opt >>= 5; | 203 | opt >>= 5; |
diff --git a/archival/cpio.c b/archival/cpio.c index 540218cb2..683f0bb1f 100644 --- a/archival/cpio.c +++ b/archival/cpio.c | |||
@@ -29,7 +29,7 @@ | |||
29 | //config: should probably say N here. | 29 | //config: should probably say N here. |
30 | //config: | 30 | //config: |
31 | //config:config FEATURE_CPIO_O | 31 | //config:config FEATURE_CPIO_O |
32 | //config: bool "Support for archive creation" | 32 | //config: bool "Support archive creation" |
33 | //config: default y | 33 | //config: default y |
34 | //config: depends on CPIO | 34 | //config: depends on CPIO |
35 | //config: help | 35 | //config: help |
@@ -37,7 +37,7 @@ | |||
37 | //config: format only. | 37 | //config: format only. |
38 | //config: | 38 | //config: |
39 | //config:config FEATURE_CPIO_P | 39 | //config:config FEATURE_CPIO_P |
40 | //config: bool "Support for passthrough mode" | 40 | //config: bool "Support passthrough mode" |
41 | //config: default y | 41 | //config: default y |
42 | //config: depends on FEATURE_CPIO_O | 42 | //config: depends on FEATURE_CPIO_O |
43 | //config: help | 43 | //config: help |
diff --git a/archival/gzip.c b/archival/gzip.c index 9e0bee815..e698c26cd 100644 --- a/archival/gzip.c +++ b/archival/gzip.c | |||
@@ -48,11 +48,9 @@ aa: 85.1% -- replaced with aa.gz | |||
48 | //config: bool "Enable long options" | 48 | //config: bool "Enable long options" |
49 | //config: default y | 49 | //config: default y |
50 | //config: depends on GZIP && LONG_OPTS | 50 | //config: depends on GZIP && LONG_OPTS |
51 | //config: help | ||
52 | //config: Enable use of long options, increases size by about 106 Bytes | ||
53 | //config: | 51 | //config: |
54 | //config:config GZIP_FAST | 52 | //config:config GZIP_FAST |
55 | //config: int "Trade memory for gzip speed (0:small,slow - 2:fast,big)" | 53 | //config: int "Trade memory for speed (0:small,slow - 2:fast,big)" |
56 | //config: default 0 | 54 | //config: default 0 |
57 | //config: range 0 2 | 55 | //config: range 0 2 |
58 | //config: depends on GZIP | 56 | //config: depends on GZIP |
@@ -72,19 +70,29 @@ aa: 85.1% -- replaced with aa.gz | |||
72 | //config: is 6. If levels 1-3 are specified, 4 is used. | 70 | //config: is 6. If levels 1-3 are specified, 4 is used. |
73 | //config: If this option is not selected, -N options are ignored and -9 | 71 | //config: If this option is not selected, -N options are ignored and -9 |
74 | //config: is used. | 72 | //config: is used. |
73 | //config: | ||
74 | //config:config FEATURE_GZIP_DECOMPRESS | ||
75 | //config: bool "Enable decompression" | ||
76 | //config: default y | ||
77 | //config: depends on GZIP || GUNZIP || ZCAT | ||
78 | //config: help | ||
79 | //config: Enable -d (--decompress) and -t (--test) options for gzip. | ||
80 | //config: This will be automatically selected if gunzip or zcat is | ||
81 | //config: enabled. | ||
75 | 82 | ||
76 | //applet:IF_GZIP(APPLET(gzip, BB_DIR_BIN, BB_SUID_DROP)) | 83 | //applet:IF_GZIP(APPLET(gzip, BB_DIR_BIN, BB_SUID_DROP)) |
77 | //kbuild:lib-$(CONFIG_GZIP) += gzip.o | 84 | //kbuild:lib-$(CONFIG_GZIP) += gzip.o |
78 | 85 | ||
79 | //usage:#define gzip_trivial_usage | 86 | //usage:#define gzip_trivial_usage |
80 | //usage: "[-cf" IF_GUNZIP("d") IF_FEATURE_GZIP_LEVELS("123456789") "] [FILE]..." | 87 | //usage: "[-cf" IF_FEATURE_GZIP_DECOMPRESS("dt") IF_FEATURE_GZIP_LEVELS("123456789") "] [FILE]..." |
81 | //usage:#define gzip_full_usage "\n\n" | 88 | //usage:#define gzip_full_usage "\n\n" |
82 | //usage: "Compress FILEs (or stdin)\n" | 89 | //usage: "Compress FILEs (or stdin)\n" |
83 | //usage: IF_FEATURE_GZIP_LEVELS( | 90 | //usage: IF_FEATURE_GZIP_LEVELS( |
84 | //usage: "\n -1..9 Compression level" | 91 | //usage: "\n -1..9 Compression level" |
85 | //usage: ) | 92 | //usage: ) |
86 | //usage: IF_GUNZIP( | 93 | //usage: IF_FEATURE_GZIP_DECOMPRESS( |
87 | //usage: "\n -d Decompress" | 94 | //usage: "\n -d Decompress" |
95 | //usage: "\n -t Test file integrity" | ||
88 | //usage: ) | 96 | //usage: ) |
89 | //usage: "\n -c Write to stdout" | 97 | //usage: "\n -c Write to stdout" |
90 | //usage: "\n -f Force" | 98 | //usage: "\n -f Force" |
@@ -2154,7 +2162,7 @@ static const char gzip_longopts[] ALIGN1 = | |||
2154 | "to-stdout\0" No_argument "c" | 2162 | "to-stdout\0" No_argument "c" |
2155 | "force\0" No_argument "f" | 2163 | "force\0" No_argument "f" |
2156 | "verbose\0" No_argument "v" | 2164 | "verbose\0" No_argument "v" |
2157 | #if ENABLE_GUNZIP | 2165 | #if ENABLE_FEATURE_GZIP_DECOMPRESS |
2158 | "decompress\0" No_argument "d" | 2166 | "decompress\0" No_argument "d" |
2159 | "uncompress\0" No_argument "d" | 2167 | "uncompress\0" No_argument "d" |
2160 | "test\0" No_argument "t" | 2168 | "test\0" No_argument "t" |
@@ -2181,7 +2189,7 @@ static const char gzip_longopts[] ALIGN1 = | |||
2181 | */ | 2189 | */ |
2182 | 2190 | ||
2183 | int gzip_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; | 2191 | int gzip_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; |
2184 | #if ENABLE_GUNZIP | 2192 | #if ENABLE_FEATURE_GZIP_DECOMPRESS |
2185 | int gzip_main(int argc, char **argv) | 2193 | int gzip_main(int argc, char **argv) |
2186 | #else | 2194 | #else |
2187 | int gzip_main(int argc UNUSED_PARAM, char **argv) | 2195 | int gzip_main(int argc UNUSED_PARAM, char **argv) |
@@ -2211,13 +2219,13 @@ int gzip_main(int argc UNUSED_PARAM, char **argv) | |||
2211 | applet_long_options = gzip_longopts; | 2219 | applet_long_options = gzip_longopts; |
2212 | #endif | 2220 | #endif |
2213 | /* Must match bbunzip's constants OPT_STDOUT, OPT_FORCE! */ | 2221 | /* Must match bbunzip's constants OPT_STDOUT, OPT_FORCE! */ |
2214 | opt = getopt32(argv, "cfv" IF_GUNZIP("dt") "qn123456789"); | 2222 | opt = getopt32(argv, "cfv" IF_FEATURE_GZIP_DECOMPRESS("dt") "qn123456789"); |
2215 | #if ENABLE_GUNZIP /* gunzip_main may not be visible... */ | 2223 | #if ENABLE_FEATURE_GZIP_DECOMPRESS /* gunzip_main may not be visible... */ |
2216 | if (opt & 0x18) // -d and/or -t | 2224 | if (opt & 0x18) // -d and/or -t |
2217 | return gunzip_main(argc, argv); | 2225 | return gunzip_main(argc, argv); |
2218 | #endif | 2226 | #endif |
2219 | #ifdef ENABLE_FEATURE_GZIP_LEVELS | 2227 | #ifdef ENABLE_FEATURE_GZIP_LEVELS |
2220 | opt >>= ENABLE_GUNZIP ? 7 : 5; /* drop cfv[dt]qn bits */ | 2228 | opt >>= ENABLE_FEATURE_GZIP_DECOMPRESS ? 7 : 5; /* drop cfv[dt]qn bits */ |
2221 | if (opt == 0) | 2229 | if (opt == 0) |
2222 | opt = 1 << 6; /* default: 6 */ | 2230 | opt = 1 << 6; /* default: 6 */ |
2223 | opt = ffs(opt >> 4); /* Maps -1..-4 to [0], -5 to [1] ... -9 to [5] */ | 2231 | opt = ffs(opt >> 4); /* Maps -1..-4 to [0], -5 to [1] ... -9 to [5] */ |
diff --git a/archival/libarchive/Kbuild.src b/archival/libarchive/Kbuild.src index ad5c5c42d..eaf67451f 100644 --- a/archival/libarchive/Kbuild.src +++ b/archival/libarchive/Kbuild.src | |||
@@ -53,12 +53,15 @@ lib-$(CONFIG_LZOPCAT) += lzo1x_1.o lzo1x_1o.o lzo1x_d.o | |||
53 | lib-$(CONFIG_LZOP_COMPR_HIGH) += lzo1x_9x.o | 53 | lib-$(CONFIG_LZOP_COMPR_HIGH) += lzo1x_9x.o |
54 | lib-$(CONFIG_BUNZIP2) += open_transformer.o decompress_bunzip2.o | 54 | lib-$(CONFIG_BUNZIP2) += open_transformer.o decompress_bunzip2.o |
55 | lib-$(CONFIG_BZCAT) += open_transformer.o decompress_bunzip2.o | 55 | lib-$(CONFIG_BZCAT) += open_transformer.o decompress_bunzip2.o |
56 | lib-$(CONFIG_FEATURE_UNZIP_BZIP2) += open_transformer.o decompress_bunzip2.o | ||
56 | lib-$(CONFIG_UNLZMA) += open_transformer.o decompress_unlzma.o | 57 | lib-$(CONFIG_UNLZMA) += open_transformer.o decompress_unlzma.o |
57 | lib-$(CONFIG_LZCAT) += open_transformer.o decompress_unlzma.o | 58 | lib-$(CONFIG_LZCAT) += open_transformer.o decompress_unlzma.o |
58 | lib-$(CONFIG_LZMA) += open_transformer.o decompress_unlzma.o | 59 | lib-$(CONFIG_LZMA) += open_transformer.o decompress_unlzma.o |
60 | lib-$(CONFIG_FEATURE_UNZIP_LZMA) += open_transformer.o decompress_unlzma.o | ||
59 | lib-$(CONFIG_UNXZ) += open_transformer.o decompress_unxz.o | 61 | lib-$(CONFIG_UNXZ) += open_transformer.o decompress_unxz.o |
60 | lib-$(CONFIG_XZCAT) += open_transformer.o decompress_unxz.o | 62 | lib-$(CONFIG_XZCAT) += open_transformer.o decompress_unxz.o |
61 | lib-$(CONFIG_XZ) += open_transformer.o decompress_unxz.o | 63 | lib-$(CONFIG_XZ) += open_transformer.o decompress_unxz.o |
64 | lib-$(CONFIG_FEATURE_UNZIP_XZ) += open_transformer.o decompress_unxz.o | ||
62 | lib-$(CONFIG_GUNZIP) += open_transformer.o decompress_gunzip.o | 65 | lib-$(CONFIG_GUNZIP) += open_transformer.o decompress_gunzip.o |
63 | lib-$(CONFIG_ZCAT) += open_transformer.o decompress_gunzip.o | 66 | lib-$(CONFIG_ZCAT) += open_transformer.o decompress_gunzip.o |
64 | lib-$(CONFIG_UNCOMPRESS) += open_transformer.o decompress_uncompress.o | 67 | lib-$(CONFIG_UNCOMPRESS) += open_transformer.o decompress_uncompress.o |
diff --git a/archival/libarchive/data_extract_all.c b/archival/libarchive/data_extract_all.c index bd034afdc..1830ffb8d 100644 --- a/archival/libarchive/data_extract_all.c +++ b/archival/libarchive/data_extract_all.c | |||
@@ -127,8 +127,9 @@ void FAST_FUNC data_extract_all(archive_handle_t *archive_handle) | |||
127 | if (hard_link) { | 127 | if (hard_link) { |
128 | res = link(hard_link, dst_name); | 128 | res = link(hard_link, dst_name); |
129 | if (res != 0 && !(archive_handle->ah_flags & ARCHIVE_EXTRACT_QUIET)) { | 129 | if (res != 0 && !(archive_handle->ah_flags & ARCHIVE_EXTRACT_QUIET)) { |
130 | /* shared message */ | ||
130 | bb_perror_msg("can't create %slink " | 131 | bb_perror_msg("can't create %slink " |
131 | "from %s to %s", "hard", | 132 | "%s to %s", "hard", |
132 | dst_name, | 133 | dst_name, |
133 | hard_link); | 134 | hard_link); |
134 | } | 135 | } |
@@ -181,8 +182,9 @@ void FAST_FUNC data_extract_all(archive_handle_t *archive_handle) | |||
181 | if (res != 0 | 182 | if (res != 0 |
182 | && !(archive_handle->ah_flags & ARCHIVE_EXTRACT_QUIET) | 183 | && !(archive_handle->ah_flags & ARCHIVE_EXTRACT_QUIET) |
183 | ) { | 184 | ) { |
185 | /* shared message */ | ||
184 | bb_perror_msg("can't create %slink " | 186 | bb_perror_msg("can't create %slink " |
185 | "from %s to %s", "sym", | 187 | "%s to %s", "sym", |
186 | dst_name, | 188 | dst_name, |
187 | file_header->link_target); | 189 | file_header->link_target); |
188 | } | 190 | } |
diff --git a/archival/libarchive/decompress_bunzip2.c b/archival/libarchive/decompress_bunzip2.c index fe5953da2..4fb989c29 100644 --- a/archival/libarchive/decompress_bunzip2.c +++ b/archival/libarchive/decompress_bunzip2.c | |||
@@ -134,7 +134,7 @@ static unsigned get_bits(bunzip_data *bd, int bits_wanted) | |||
134 | 134 | ||
135 | /* Avoid 32-bit overflow (dump bit buffer to top of output) */ | 135 | /* Avoid 32-bit overflow (dump bit buffer to top of output) */ |
136 | if (bit_count >= 24) { | 136 | if (bit_count >= 24) { |
137 | bits = bd->inbufBits & ((1 << bit_count) - 1); | 137 | bits = bd->inbufBits & ((1U << bit_count) - 1); |
138 | bits_wanted -= bit_count; | 138 | bits_wanted -= bit_count; |
139 | bits <<= bits_wanted; | 139 | bits <<= bits_wanted; |
140 | bit_count = 0; | 140 | bit_count = 0; |
@@ -158,11 +158,11 @@ static int get_next_block(bunzip_data *bd) | |||
158 | { | 158 | { |
159 | struct group_data *hufGroup; | 159 | struct group_data *hufGroup; |
160 | int dbufCount, dbufSize, groupCount, *base, *limit, selector, | 160 | int dbufCount, dbufSize, groupCount, *base, *limit, selector, |
161 | i, j, t, runPos, symCount, symTotal, nSelectors, byteCount[256]; | 161 | i, j, runPos, symCount, symTotal, nSelectors, byteCount[256]; |
162 | int runCnt = runCnt; /* for compiler */ | 162 | int runCnt = runCnt; /* for compiler */ |
163 | uint8_t uc, symToByte[256], mtfSymbol[256], *selectors; | 163 | uint8_t uc, symToByte[256], mtfSymbol[256], *selectors; |
164 | uint32_t *dbuf; | 164 | uint32_t *dbuf; |
165 | unsigned origPtr; | 165 | unsigned origPtr, t; |
166 | 166 | ||
167 | dbuf = bd->dbuf; | 167 | dbuf = bd->dbuf; |
168 | dbufSize = bd->dbufSize; | 168 | dbufSize = bd->dbufSize; |
diff --git a/archival/libarchive/decompress_unlzma.c b/archival/libarchive/decompress_unlzma.c index c8622f97b..a9040877e 100644 --- a/archival/libarchive/decompress_unlzma.c +++ b/archival/libarchive/decompress_unlzma.c | |||
@@ -278,9 +278,10 @@ unpack_lzma_stream(transformer_state_t *xstate) | |||
278 | 278 | ||
279 | if (state >= LZMA_NUM_LIT_STATES) { | 279 | if (state >= LZMA_NUM_LIT_STATES) { |
280 | int match_byte; | 280 | int match_byte; |
281 | uint32_t pos = buffer_pos - rep0; | 281 | uint32_t pos; |
282 | 282 | ||
283 | while (pos >= header.dict_size) | 283 | pos = buffer_pos - rep0; |
284 | if ((int32_t)pos < 0) | ||
284 | pos += header.dict_size; | 285 | pos += header.dict_size; |
285 | match_byte = buffer[pos]; | 286 | match_byte = buffer[pos]; |
286 | do { | 287 | do { |
@@ -336,9 +337,11 @@ unpack_lzma_stream(transformer_state_t *xstate) | |||
336 | ); | 337 | ); |
337 | if (!rc_is_bit_1(rc, prob2)) { | 338 | if (!rc_is_bit_1(rc, prob2)) { |
338 | #if ENABLE_FEATURE_LZMA_FAST | 339 | #if ENABLE_FEATURE_LZMA_FAST |
339 | uint32_t pos = buffer_pos - rep0; | 340 | uint32_t pos; |
340 | state = state < LZMA_NUM_LIT_STATES ? 9 : 11; | 341 | state = state < LZMA_NUM_LIT_STATES ? 9 : 11; |
341 | while (pos >= header.dict_size) | 342 | |
343 | pos = buffer_pos - rep0; | ||
344 | if ((int32_t)pos < 0) | ||
342 | pos += header.dict_size; | 345 | pos += header.dict_size; |
343 | previous_byte = buffer[pos]; | 346 | previous_byte = buffer[pos]; |
344 | goto one_byte1; | 347 | goto one_byte1; |
@@ -429,10 +432,25 @@ unpack_lzma_stream(transformer_state_t *xstate) | |||
429 | } | 432 | } |
430 | 433 | ||
431 | len += LZMA_MATCH_MIN_LEN; | 434 | len += LZMA_MATCH_MIN_LEN; |
435 | /* | ||
436 | * LZMA SDK has this optimized: | ||
437 | * it precalculates size and copies many bytes | ||
438 | * in a loop with simpler checks, a-la: | ||
439 | * do | ||
440 | * *(dest) = *(dest + ofs); | ||
441 | * while (++dest != lim); | ||
442 | * and | ||
443 | * do { | ||
444 | * buffer[buffer_pos++] = buffer[pos]; | ||
445 | * if (++pos == header.dict_size) | ||
446 | * pos = 0; | ||
447 | * } while (--cur_len != 0); | ||
448 | * Our code is slower (more checks per byte copy): | ||
449 | */ | ||
432 | IF_NOT_FEATURE_LZMA_FAST(string:) | 450 | IF_NOT_FEATURE_LZMA_FAST(string:) |
433 | do { | 451 | do { |
434 | uint32_t pos = buffer_pos - rep0; | 452 | uint32_t pos = buffer_pos - rep0; |
435 | while (pos >= header.dict_size) | 453 | if ((int32_t)pos < 0) |
436 | pos += header.dict_size; | 454 | pos += header.dict_size; |
437 | previous_byte = buffer[pos]; | 455 | previous_byte = buffer[pos]; |
438 | IF_NOT_FEATURE_LZMA_FAST(one_byte2:) | 456 | IF_NOT_FEATURE_LZMA_FAST(one_byte2:) |
@@ -448,6 +466,9 @@ unpack_lzma_stream(transformer_state_t *xstate) | |||
448 | } while (len != 0 && buffer_pos < header.dst_size); | 466 | } while (len != 0 && buffer_pos < header.dst_size); |
449 | /* FIXME: ...........^^^^^ | 467 | /* FIXME: ...........^^^^^ |
450 | * shouldn't it be "global_pos + buffer_pos < header.dst_size"? | 468 | * shouldn't it be "global_pos + buffer_pos < header.dst_size"? |
469 | * It probably should, but it is a "do we accidentally | ||
470 | * unpack more bytes than expected?" check - which | ||
471 | * never happens for well-formed compression data... | ||
451 | */ | 472 | */ |
452 | } | 473 | } |
453 | } | 474 | } |
diff --git a/archival/lzop.c b/archival/lzop.c index e0e90ac6c..ca61add3c 100644 --- a/archival/lzop.c +++ b/archival/lzop.c | |||
@@ -53,7 +53,8 @@ | |||
53 | //config: and take up 3.2K of code. | 53 | //config: and take up 3.2K of code. |
54 | 54 | ||
55 | //applet:IF_LZOP(APPLET(lzop, BB_DIR_BIN, BB_SUID_DROP)) | 55 | //applet:IF_LZOP(APPLET(lzop, BB_DIR_BIN, BB_SUID_DROP)) |
56 | //applet:IF_UNLZOP(APPLET_ODDNAME(unlzop, lzop, BB_DIR_USR_BIN, BB_SUID_DROP, unlzop)) | 56 | // APPLET_ODDNAME:name main location suid_type help |
57 | //applet:IF_UNLZOP( APPLET_ODDNAME(unlzop, lzop, BB_DIR_USR_BIN, BB_SUID_DROP, unlzop)) | ||
57 | //applet:IF_LZOPCAT(APPLET_ODDNAME(lzopcat, lzop, BB_DIR_USR_BIN, BB_SUID_DROP, lzopcat)) | 58 | //applet:IF_LZOPCAT(APPLET_ODDNAME(lzopcat, lzop, BB_DIR_USR_BIN, BB_SUID_DROP, lzopcat)) |
58 | //kbuild:lib-$(CONFIG_LZOP) += lzop.o | 59 | //kbuild:lib-$(CONFIG_LZOP) += lzop.o |
59 | //kbuild:lib-$(CONFIG_UNLZOP) += lzop.o | 60 | //kbuild:lib-$(CONFIG_UNLZOP) += lzop.o |
diff --git a/archival/tar.c b/archival/tar.c index c87d23597..34e3052ce 100644 --- a/archival/tar.c +++ b/archival/tar.c | |||
@@ -49,13 +49,15 @@ | |||
49 | //config: create compressed archives. It's probably the most widely used | 49 | //config: create compressed archives. It's probably the most widely used |
50 | //config: UNIX archive program. | 50 | //config: UNIX archive program. |
51 | //config: | 51 | //config: |
52 | //config:config FEATURE_TAR_LONG_OPTIONS | ||
53 | //config: bool "Enable long options" | ||
54 | //config: default y | ||
55 | //config: depends on TAR && LONG_OPTS | ||
56 | //config: | ||
52 | //config:config FEATURE_TAR_CREATE | 57 | //config:config FEATURE_TAR_CREATE |
53 | //config: bool "Enable archive creation" | 58 | //config: bool "Enable -c (archive creation)" |
54 | //config: default y | 59 | //config: default y |
55 | //config: depends on TAR | 60 | //config: depends on TAR |
56 | //config: help | ||
57 | //config: If you enable this option you'll be able to create | ||
58 | //config: tar archives using the `-c' option. | ||
59 | //config: | 61 | //config: |
60 | //config:config FEATURE_TAR_AUTODETECT | 62 | //config:config FEATURE_TAR_AUTODETECT |
61 | //config: bool "Autodetect compressed tarballs" | 63 | //config: bool "Autodetect compressed tarballs" |
@@ -74,7 +76,7 @@ | |||
74 | //config: a list of files to include or exclude from an archive. | 76 | //config: a list of files to include or exclude from an archive. |
75 | //config: | 77 | //config: |
76 | //config:config FEATURE_TAR_OLDGNU_COMPATIBILITY | 78 | //config:config FEATURE_TAR_OLDGNU_COMPATIBILITY |
77 | //config: bool "Support for old tar header format" | 79 | //config: bool "Support old tar header format" |
78 | //config: default y | 80 | //config: default y |
79 | //config: depends on TAR || DPKG | 81 | //config: depends on TAR || DPKG |
80 | //config: help | 82 | //config: help |
@@ -93,22 +95,12 @@ | |||
93 | //config: tarballs still exist. | 95 | //config: tarballs still exist. |
94 | //config: | 96 | //config: |
95 | //config:config FEATURE_TAR_GNU_EXTENSIONS | 97 | //config:config FEATURE_TAR_GNU_EXTENSIONS |
96 | //config: bool "Support for GNU tar extensions (long filenames)" | 98 | //config: bool "Support GNU tar extensions (long filenames)" |
97 | //config: default y | 99 | //config: default y |
98 | //config: depends on TAR || DPKG | 100 | //config: depends on TAR || DPKG |
99 | //config: help | ||
100 | //config: With this option busybox supports GNU long filenames and | ||
101 | //config: linknames. | ||
102 | //config: | ||
103 | //config:config FEATURE_TAR_LONG_OPTIONS | ||
104 | //config: bool "Enable long options" | ||
105 | //config: default y | ||
106 | //config: depends on TAR && LONG_OPTS | ||
107 | //config: help | ||
108 | //config: Enable use of long options, increases size by about 400 Bytes | ||
109 | //config: | 101 | //config: |
110 | //config:config FEATURE_TAR_TO_COMMAND | 102 | //config:config FEATURE_TAR_TO_COMMAND |
111 | //config: bool "Support for writing to an external program" | 103 | //config: bool "Support writing to an external program (--to-command)" |
112 | //config: default y | 104 | //config: default y |
113 | //config: depends on TAR && FEATURE_TAR_LONG_OPTIONS | 105 | //config: depends on TAR && FEATURE_TAR_LONG_OPTIONS |
114 | //config: help | 106 | //config: help |
@@ -121,20 +113,17 @@ | |||
121 | //config: default y | 113 | //config: default y |
122 | //config: depends on TAR | 114 | //config: depends on TAR |
123 | //config: help | 115 | //config: help |
124 | //config: Enables use of user and group names in tar. This affects contents | 116 | //config: Enable use of user and group names in tar. This affects contents |
125 | //config: listings (-t) and preserving permissions when unpacking (-p). | 117 | //config: listings (-t) and preserving permissions when unpacking (-p). |
126 | //config: +200 bytes. | 118 | //config: +200 bytes. |
127 | //config: | 119 | //config: |
128 | //config:config FEATURE_TAR_NOPRESERVE_TIME | 120 | //config:config FEATURE_TAR_NOPRESERVE_TIME |
129 | //config: bool "Enable -m (do not preserve time) option" | 121 | //config: bool "Enable -m (do not preserve time) GNU option" |
130 | //config: default y | 122 | //config: default y |
131 | //config: depends on TAR | 123 | //config: depends on TAR |
132 | //config: help | ||
133 | //config: With this option busybox supports GNU tar -m | ||
134 | //config: (do not preserve time) option. | ||
135 | //config: | 124 | //config: |
136 | //config:config FEATURE_TAR_SELINUX | 125 | //config:config FEATURE_TAR_SELINUX |
137 | //config: bool "Support for extracting SELinux labels" | 126 | //config: bool "Support extracting SELinux labels" |
138 | //config: default n | 127 | //config: default n |
139 | //config: depends on TAR && SELINUX | 128 | //config: depends on TAR && SELINUX |
140 | //config: help | 129 | //config: help |
diff --git a/archival/unzip.c b/archival/unzip.c index 9ad03d0e2..56989fa0b 100644 --- a/archival/unzip.c +++ b/archival/unzip.c | |||
@@ -34,6 +34,23 @@ | |||
34 | //config: ZIP files without deleted/updated files, SFX archives etc, | 34 | //config: ZIP files without deleted/updated files, SFX archives etc, |
35 | //config: you can reduce code size by unselecting this option. | 35 | //config: you can reduce code size by unselecting this option. |
36 | //config: To support less trivial ZIPs, say Y. | 36 | //config: To support less trivial ZIPs, say Y. |
37 | //config: | ||
38 | //config:config FEATURE_UNZIP_BZIP2 | ||
39 | //config: bool "Support compression method 12 (bzip2)" | ||
40 | //config: default y | ||
41 | //config: depends on FEATURE_UNZIP_CDF && DESKTOP | ||
42 | // FEATURE_UNZIP_CDF is needed, otherwise we can't find start of next file | ||
43 | // DESKTOP is needed to get back uncompressed length | ||
44 | //config: | ||
45 | //config:config FEATURE_UNZIP_LZMA | ||
46 | //config: bool "Support compression method 14 (lzma)" | ||
47 | //config: default y | ||
48 | //config: depends on FEATURE_UNZIP_CDF && DESKTOP | ||
49 | //config: | ||
50 | //config:config FEATURE_UNZIP_XZ | ||
51 | //config: bool "Support compression method 95 (xz)" | ||
52 | //config: default y | ||
53 | //config: depends on FEATURE_UNZIP_CDF && DESKTOP | ||
37 | 54 | ||
38 | //applet:IF_UNZIP(APPLET(unzip, BB_DIR_USR_BIN, BB_SUID_DROP)) | 55 | //applet:IF_UNZIP(APPLET(unzip, BB_DIR_USR_BIN, BB_SUID_DROP)) |
39 | //kbuild:lib-$(CONFIG_UNZIP) += unzip.o | 56 | //kbuild:lib-$(CONFIG_UNZIP) += unzip.o |
@@ -65,8 +82,8 @@ | |||
65 | enum { | 82 | enum { |
66 | #if BB_BIG_ENDIAN | 83 | #if BB_BIG_ENDIAN |
67 | ZIP_FILEHEADER_MAGIC = 0x504b0304, | 84 | ZIP_FILEHEADER_MAGIC = 0x504b0304, |
68 | ZIP_CDF_MAGIC = 0x504b0102, /* central directory's file header */ | 85 | ZIP_CDF_MAGIC = 0x504b0102, /* CDF item */ |
69 | ZIP_CDE_MAGIC = 0x504b0506, /* "end of central directory" record */ | 86 | ZIP_CDE_MAGIC = 0x504b0506, /* End of CDF */ |
70 | ZIP_DD_MAGIC = 0x504b0708, | 87 | ZIP_DD_MAGIC = 0x504b0708, |
71 | #else | 88 | #else |
72 | ZIP_FILEHEADER_MAGIC = 0x04034b50, | 89 | ZIP_FILEHEADER_MAGIC = 0x04034b50, |
@@ -94,16 +111,16 @@ typedef union { | |||
94 | /* filename follows (not NUL terminated) */ | 111 | /* filename follows (not NUL terminated) */ |
95 | /* extra field follows */ | 112 | /* extra field follows */ |
96 | /* data follows */ | 113 | /* data follows */ |
97 | } formatted PACKED; | 114 | } fmt PACKED; |
98 | } zip_header_t; /* PACKED - gcc 4.2.1 doesn't like it (spews warning) */ | 115 | } zip_header_t; /* PACKED - gcc 4.2.1 doesn't like it (spews warning) */ |
99 | 116 | ||
100 | #define FIX_ENDIANNESS_ZIP(zip_header) \ | 117 | #define FIX_ENDIANNESS_ZIP(zip) \ |
101 | do { if (BB_BIG_ENDIAN) { \ | 118 | do { if (BB_BIG_ENDIAN) { \ |
102 | (zip_header).formatted.crc32 = SWAP_LE32((zip_header).formatted.crc32 ); \ | 119 | (zip).fmt.crc32 = SWAP_LE32((zip).fmt.crc32 ); \ |
103 | (zip_header).formatted.cmpsize = SWAP_LE32((zip_header).formatted.cmpsize ); \ | 120 | (zip).fmt.cmpsize = SWAP_LE32((zip).fmt.cmpsize ); \ |
104 | (zip_header).formatted.ucmpsize = SWAP_LE32((zip_header).formatted.ucmpsize ); \ | 121 | (zip).fmt.ucmpsize = SWAP_LE32((zip).fmt.ucmpsize ); \ |
105 | (zip_header).formatted.filename_len = SWAP_LE16((zip_header).formatted.filename_len); \ | 122 | (zip).fmt.filename_len = SWAP_LE16((zip).fmt.filename_len); \ |
106 | (zip_header).formatted.extra_len = SWAP_LE16((zip_header).formatted.extra_len ); \ | 123 | (zip).fmt.extra_len = SWAP_LE16((zip).fmt.extra_len ); \ |
107 | }} while (0) | 124 | }} while (0) |
108 | 125 | ||
109 | #define CDF_HEADER_LEN 42 | 126 | #define CDF_HEADER_LEN 42 |
@@ -121,39 +138,39 @@ typedef union { | |||
121 | uint32_t crc32; /* 12-15 */ | 138 | uint32_t crc32; /* 12-15 */ |
122 | uint32_t cmpsize; /* 16-19 */ | 139 | uint32_t cmpsize; /* 16-19 */ |
123 | uint32_t ucmpsize; /* 20-23 */ | 140 | uint32_t ucmpsize; /* 20-23 */ |
124 | uint16_t file_name_length; /* 24-25 */ | 141 | uint16_t filename_len; /* 24-25 */ |
125 | uint16_t extra_field_length; /* 26-27 */ | 142 | uint16_t extra_len; /* 26-27 */ |
126 | uint16_t file_comment_length; /* 28-29 */ | 143 | uint16_t file_comment_length; /* 28-29 */ |
127 | uint16_t disk_number_start; /* 30-31 */ | 144 | uint16_t disk_number_start; /* 30-31 */ |
128 | uint16_t internal_file_attributes; /* 32-33 */ | 145 | uint16_t internal_attributes; /* 32-33 */ |
129 | uint32_t external_file_attributes PACKED; /* 34-37 */ | 146 | uint32_t external_attributes PACKED; /* 34-37 */ |
130 | uint32_t relative_offset_of_local_header PACKED; /* 38-41 */ | 147 | uint32_t relative_offset_of_local_header PACKED; /* 38-41 */ |
131 | /* filename follows (not NUL terminated) */ | 148 | /* filename follows (not NUL terminated) */ |
132 | /* extra field follows */ | 149 | /* extra field follows */ |
133 | /* comment follows */ | 150 | /* file comment follows */ |
134 | } formatted PACKED; | 151 | } fmt PACKED; |
135 | } cdf_header_t; | 152 | } cdf_header_t; |
136 | 153 | ||
137 | #define FIX_ENDIANNESS_CDF(cdf_header) \ | 154 | #define FIX_ENDIANNESS_CDF(cdf) \ |
138 | do { if (BB_BIG_ENDIAN) { \ | 155 | do { if (BB_BIG_ENDIAN) { \ |
139 | (cdf_header).formatted.version_made_by = SWAP_LE16((cdf_header).formatted.version_made_by); \ | 156 | (cdf).fmt.version_made_by = SWAP_LE16((cdf).fmt.version_made_by); \ |
140 | (cdf_header).formatted.version_needed = SWAP_LE16((cdf_header).formatted.version_needed); \ | 157 | (cdf).fmt.version_needed = SWAP_LE16((cdf).fmt.version_needed); \ |
141 | (cdf_header).formatted.method = SWAP_LE16((cdf_header).formatted.method ); \ | 158 | (cdf).fmt.method = SWAP_LE16((cdf).fmt.method ); \ |
142 | (cdf_header).formatted.modtime = SWAP_LE16((cdf_header).formatted.modtime ); \ | 159 | (cdf).fmt.modtime = SWAP_LE16((cdf).fmt.modtime ); \ |
143 | (cdf_header).formatted.moddate = SWAP_LE16((cdf_header).formatted.moddate ); \ | 160 | (cdf).fmt.moddate = SWAP_LE16((cdf).fmt.moddate ); \ |
144 | (cdf_header).formatted.crc32 = SWAP_LE32((cdf_header).formatted.crc32 ); \ | 161 | (cdf).fmt.crc32 = SWAP_LE32((cdf).fmt.crc32 ); \ |
145 | (cdf_header).formatted.cmpsize = SWAP_LE32((cdf_header).formatted.cmpsize ); \ | 162 | (cdf).fmt.cmpsize = SWAP_LE32((cdf).fmt.cmpsize ); \ |
146 | (cdf_header).formatted.ucmpsize = SWAP_LE32((cdf_header).formatted.ucmpsize ); \ | 163 | (cdf).fmt.ucmpsize = SWAP_LE32((cdf).fmt.ucmpsize ); \ |
147 | (cdf_header).formatted.file_name_length = SWAP_LE16((cdf_header).formatted.file_name_length); \ | 164 | (cdf).fmt.filename_len = SWAP_LE16((cdf).fmt.filename_len); \ |
148 | (cdf_header).formatted.extra_field_length = SWAP_LE16((cdf_header).formatted.extra_field_length); \ | 165 | (cdf).fmt.extra_len = SWAP_LE16((cdf).fmt.extra_len ); \ |
149 | (cdf_header).formatted.file_comment_length = SWAP_LE16((cdf_header).formatted.file_comment_length); \ | 166 | (cdf).fmt.file_comment_length = SWAP_LE16((cdf).fmt.file_comment_length); \ |
150 | (cdf_header).formatted.external_file_attributes = SWAP_LE32((cdf_header).formatted.external_file_attributes); \ | 167 | (cdf).fmt.external_attributes = SWAP_LE32((cdf).fmt.external_attributes); \ |
151 | }} while (0) | 168 | }} while (0) |
152 | 169 | ||
153 | #define CDE_HEADER_LEN 16 | 170 | #define CDE_LEN 16 |
154 | 171 | ||
155 | typedef union { | 172 | typedef union { |
156 | uint8_t raw[CDE_HEADER_LEN]; | 173 | uint8_t raw[CDE_LEN]; |
157 | struct { | 174 | struct { |
158 | /* uint32_t signature; 50 4b 05 06 */ | 175 | /* uint32_t signature; 50 4b 05 06 */ |
159 | uint16_t this_disk_no; | 176 | uint16_t this_disk_no; |
@@ -162,14 +179,14 @@ typedef union { | |||
162 | uint16_t cdf_entries_total; | 179 | uint16_t cdf_entries_total; |
163 | uint32_t cdf_size; | 180 | uint32_t cdf_size; |
164 | uint32_t cdf_offset; | 181 | uint32_t cdf_offset; |
165 | /* uint16_t file_comment_length; */ | 182 | /* uint16_t archive_comment_length; */ |
166 | /* .ZIP file comment (variable size) */ | 183 | /* archive comment follows */ |
167 | } formatted PACKED; | 184 | } fmt PACKED; |
168 | } cde_header_t; | 185 | } cde_t; |
169 | 186 | ||
170 | #define FIX_ENDIANNESS_CDE(cde_header) \ | 187 | #define FIX_ENDIANNESS_CDE(cde) \ |
171 | do { if (BB_BIG_ENDIAN) { \ | 188 | do { if (BB_BIG_ENDIAN) { \ |
172 | (cde_header).formatted.cdf_offset = SWAP_LE32((cde_header).formatted.cdf_offset); \ | 189 | (cde).fmt.cdf_offset = SWAP_LE32((cde).fmt.cdf_offset); \ |
173 | }} while (0) | 190 | }} while (0) |
174 | 191 | ||
175 | struct BUG { | 192 | struct BUG { |
@@ -178,13 +195,13 @@ struct BUG { | |||
178 | * even though the elements are all in the right place. | 195 | * even though the elements are all in the right place. |
179 | */ | 196 | */ |
180 | char BUG_zip_header_must_be_26_bytes[ | 197 | char BUG_zip_header_must_be_26_bytes[ |
181 | offsetof(zip_header_t, formatted.extra_len) + 2 | 198 | offsetof(zip_header_t, fmt.extra_len) + 2 |
182 | == ZIP_HEADER_LEN ? 1 : -1]; | 199 | == ZIP_HEADER_LEN ? 1 : -1]; |
183 | char BUG_cdf_header_must_be_42_bytes[ | 200 | char BUG_cdf_header_must_be_42_bytes[ |
184 | offsetof(cdf_header_t, formatted.relative_offset_of_local_header) + 4 | 201 | offsetof(cdf_header_t, fmt.relative_offset_of_local_header) + 4 |
185 | == CDF_HEADER_LEN ? 1 : -1]; | 202 | == CDF_HEADER_LEN ? 1 : -1]; |
186 | char BUG_cde_header_must_be_16_bytes[ | 203 | char BUG_cde_must_be_16_bytes[ |
187 | sizeof(cde_header_t) == CDE_HEADER_LEN ? 1 : -1]; | 204 | sizeof(cde_t) == CDE_LEN ? 1 : -1]; |
188 | }; | 205 | }; |
189 | 206 | ||
190 | 207 | ||
@@ -210,7 +227,7 @@ enum { zip_fd = 3 }; | |||
210 | /* NB: does not preserve file position! */ | 227 | /* NB: does not preserve file position! */ |
211 | static uint32_t find_cdf_offset(void) | 228 | static uint32_t find_cdf_offset(void) |
212 | { | 229 | { |
213 | cde_header_t cde_header; | 230 | cde_t cde; |
214 | unsigned char *buf; | 231 | unsigned char *buf; |
215 | unsigned char *p; | 232 | unsigned char *p; |
216 | off_t end; | 233 | off_t end; |
@@ -231,7 +248,7 @@ static uint32_t find_cdf_offset(void) | |||
231 | 248 | ||
232 | found = BAD_CDF_OFFSET; | 249 | found = BAD_CDF_OFFSET; |
233 | p = buf; | 250 | p = buf; |
234 | while (p <= buf + PEEK_FROM_END - CDE_HEADER_LEN - 4) { | 251 | while (p <= buf + PEEK_FROM_END - CDE_LEN - 4) { |
235 | if (*p != 'P') { | 252 | if (*p != 'P') { |
236 | p++; | 253 | p++; |
237 | continue; | 254 | continue; |
@@ -243,19 +260,19 @@ static uint32_t find_cdf_offset(void) | |||
243 | if (*++p != 6) | 260 | if (*++p != 6) |
244 | continue; | 261 | continue; |
245 | /* we found CDE! */ | 262 | /* we found CDE! */ |
246 | memcpy(cde_header.raw, p + 1, CDE_HEADER_LEN); | 263 | memcpy(cde.raw, p + 1, CDE_LEN); |
247 | FIX_ENDIANNESS_CDE(cde_header); | 264 | FIX_ENDIANNESS_CDE(cde); |
248 | /* | 265 | /* |
249 | * I've seen .ZIP files with seemingly valid CDEs | 266 | * I've seen .ZIP files with seemingly valid CDEs |
250 | * where cdf_offset points past EOF - ?? | 267 | * where cdf_offset points past EOF - ?? |
251 | * This check ignores such CDEs: | 268 | * This check ignores such CDEs: |
252 | */ | 269 | */ |
253 | if (cde_header.formatted.cdf_offset < end + (p - buf)) { | 270 | if (cde.fmt.cdf_offset < end + (p - buf)) { |
254 | found = cde_header.formatted.cdf_offset; | 271 | found = cde.fmt.cdf_offset; |
255 | dbg("Possible cdf_offset:0x%x at 0x%"OFF_FMT"x", | 272 | dbg("Possible cdf_offset:0x%x at 0x%"OFF_FMT"x", |
256 | (unsigned)found, end + (p-3 - buf)); | 273 | (unsigned)found, end + (p-3 - buf)); |
257 | dbg(" cdf_offset+cdf_size:0x%x", | 274 | dbg(" cdf_offset+cdf_size:0x%x", |
258 | (unsigned)(found + SWAP_LE32(cde_header.formatted.cdf_size))); | 275 | (unsigned)(found + SWAP_LE32(cde.fmt.cdf_size))); |
259 | /* | 276 | /* |
260 | * We do not "break" here because only the last CDE is valid. | 277 | * We do not "break" here because only the last CDE is valid. |
261 | * I've seen a .zip archive which contained a .zip file, | 278 | * I've seen a .zip archive which contained a .zip file, |
@@ -269,7 +286,7 @@ static uint32_t find_cdf_offset(void) | |||
269 | return found; | 286 | return found; |
270 | }; | 287 | }; |
271 | 288 | ||
272 | static uint32_t read_next_cdf(uint32_t cdf_offset, cdf_header_t *cdf_ptr) | 289 | static uint32_t read_next_cdf(uint32_t cdf_offset, cdf_header_t *cdf) |
273 | { | 290 | { |
274 | uint32_t magic; | 291 | uint32_t magic; |
275 | 292 | ||
@@ -279,23 +296,25 @@ static uint32_t read_next_cdf(uint32_t cdf_offset, cdf_header_t *cdf_ptr) | |||
279 | dbg("Reading CDF at 0x%x", (unsigned)cdf_offset); | 296 | dbg("Reading CDF at 0x%x", (unsigned)cdf_offset); |
280 | xlseek(zip_fd, cdf_offset, SEEK_SET); | 297 | xlseek(zip_fd, cdf_offset, SEEK_SET); |
281 | xread(zip_fd, &magic, 4); | 298 | xread(zip_fd, &magic, 4); |
282 | /* Central Directory End? */ | 299 | /* Central Directory End? Assume CDF has ended. |
300 | * (more correct method is to use cde.cdf_entries_total counter) | ||
301 | */ | ||
283 | if (magic == ZIP_CDE_MAGIC) { | 302 | if (magic == ZIP_CDE_MAGIC) { |
284 | dbg("got ZIP_CDE_MAGIC"); | 303 | dbg("got ZIP_CDE_MAGIC"); |
285 | return 0; /* EOF */ | 304 | return 0; /* EOF */ |
286 | } | 305 | } |
287 | xread(zip_fd, cdf_ptr->raw, CDF_HEADER_LEN); | 306 | xread(zip_fd, cdf->raw, CDF_HEADER_LEN); |
288 | 307 | ||
289 | FIX_ENDIANNESS_CDF(*cdf_ptr); | 308 | FIX_ENDIANNESS_CDF(*cdf); |
290 | dbg(" file_name_length:%u extra_field_length:%u file_comment_length:%u", | 309 | dbg(" filename_len:%u extra_len:%u file_comment_length:%u", |
291 | (unsigned)cdf_ptr->formatted.file_name_length, | 310 | (unsigned)cdf->fmt.filename_len, |
292 | (unsigned)cdf_ptr->formatted.extra_field_length, | 311 | (unsigned)cdf->fmt.extra_len, |
293 | (unsigned)cdf_ptr->formatted.file_comment_length | 312 | (unsigned)cdf->fmt.file_comment_length |
294 | ); | 313 | ); |
295 | cdf_offset += 4 + CDF_HEADER_LEN | 314 | cdf_offset += 4 + CDF_HEADER_LEN |
296 | + cdf_ptr->formatted.file_name_length | 315 | + cdf->fmt.filename_len |
297 | + cdf_ptr->formatted.extra_field_length | 316 | + cdf->fmt.extra_len |
298 | + cdf_ptr->formatted.file_comment_length; | 317 | + cdf->fmt.file_comment_length; |
299 | 318 | ||
300 | return cdf_offset; | 319 | return cdf_offset; |
301 | }; | 320 | }; |
@@ -318,34 +337,67 @@ static void unzip_create_leading_dirs(const char *fn) | |||
318 | free(name); | 337 | free(name); |
319 | } | 338 | } |
320 | 339 | ||
321 | static void unzip_extract(zip_header_t *zip_header, int dst_fd) | 340 | static void unzip_extract(zip_header_t *zip, int dst_fd) |
322 | { | 341 | { |
323 | if (zip_header->formatted.method == 0) { | 342 | transformer_state_t xstate; |
343 | |||
344 | if (zip->fmt.method == 0) { | ||
324 | /* Method 0 - stored (not compressed) */ | 345 | /* Method 0 - stored (not compressed) */ |
325 | off_t size = zip_header->formatted.ucmpsize; | 346 | off_t size = zip->fmt.ucmpsize; |
326 | if (size) | 347 | if (size) |
327 | bb_copyfd_exact_size(zip_fd, dst_fd, size); | 348 | bb_copyfd_exact_size(zip_fd, dst_fd, size); |
328 | } else { | 349 | return; |
350 | } | ||
351 | |||
352 | init_transformer_state(&xstate); | ||
353 | xstate.bytes_in = zip->fmt.cmpsize; | ||
354 | xstate.src_fd = zip_fd; | ||
355 | xstate.dst_fd = dst_fd; | ||
356 | if (zip->fmt.method == 8) { | ||
329 | /* Method 8 - inflate */ | 357 | /* Method 8 - inflate */ |
330 | transformer_state_t xstate; | ||
331 | init_transformer_state(&xstate); | ||
332 | xstate.bytes_in = zip_header->formatted.cmpsize; | ||
333 | xstate.src_fd = zip_fd; | ||
334 | xstate.dst_fd = dst_fd; | ||
335 | if (inflate_unzip(&xstate) < 0) | 358 | if (inflate_unzip(&xstate) < 0) |
336 | bb_error_msg_and_die("inflate error"); | 359 | bb_error_msg_and_die("inflate error"); |
337 | /* Validate decompression - crc */ | 360 | /* Validate decompression - crc */ |
338 | if (zip_header->formatted.crc32 != (xstate.crc32 ^ 0xffffffffL)) { | 361 | if (zip->fmt.crc32 != (xstate.crc32 ^ 0xffffffffL)) { |
339 | bb_error_msg_and_die("crc error"); | 362 | bb_error_msg_and_die("crc error"); |
340 | } | 363 | } |
341 | /* Validate decompression - size */ | ||
342 | if (zip_header->formatted.ucmpsize != xstate.bytes_out) { | ||
343 | /* Don't die. Who knows, maybe len calculation | ||
344 | * was botched somewhere. After all, crc matched! */ | ||
345 | bb_error_msg("bad length"); | ||
346 | } | ||
347 | } | 364 | } |
348 | /* TODO? method 12: bzip2, method 14: LZMA */ | 365 | #if ENABLE_FEATURE_UNZIP_BZIP2 |
366 | else if (zip->fmt.method == 12) { | ||
367 | /* Tested. Unpacker reads too much, but we use CDF | ||
368 | * and will seek to the correct beginning of next file. | ||
369 | */ | ||
370 | xstate.bytes_out = unpack_bz2_stream(&xstate); | ||
371 | if (xstate.bytes_out < 0) | ||
372 | bb_error_msg_and_die("inflate error"); | ||
373 | } | ||
374 | #endif | ||
375 | #if ENABLE_FEATURE_UNZIP_LZMA | ||
376 | else if (zip->fmt.method == 14) { | ||
377 | /* Not tested yet */ | ||
378 | xstate.bytes_out = unpack_lzma_stream(&xstate); | ||
379 | if (xstate.bytes_out < 0) | ||
380 | bb_error_msg_and_die("inflate error"); | ||
381 | } | ||
382 | #endif | ||
383 | #if ENABLE_FEATURE_UNZIP_XZ | ||
384 | else if (zip->fmt.method == 95) { | ||
385 | /* Not tested yet */ | ||
386 | xstate.bytes_out = unpack_xz_stream(&xstate); | ||
387 | if (xstate.bytes_out < 0) | ||
388 | bb_error_msg_and_die("inflate error"); | ||
389 | } | ||
390 | #endif | ||
391 | else { | ||
392 | bb_error_msg_and_die("unsupported method %u", zip->fmt.method); | ||
393 | } | ||
394 | |||
395 | /* Validate decompression - size */ | ||
396 | if (zip->fmt.ucmpsize != xstate.bytes_out) { | ||
397 | /* Don't die. Who knows, maybe len calculation | ||
398 | * was botched somewhere. After all, crc matched! */ | ||
399 | bb_error_msg("bad length"); | ||
400 | } | ||
349 | } | 401 | } |
350 | 402 | ||
351 | static void my_fgets80(char *buf80) | 403 | static void my_fgets80(char *buf80) |
@@ -566,7 +618,7 @@ int unzip_main(int argc, char **argv) | |||
566 | total_entries = 0; | 618 | total_entries = 0; |
567 | cdf_offset = find_cdf_offset(); /* try to seek to the end, find CDE and CDF start */ | 619 | cdf_offset = find_cdf_offset(); /* try to seek to the end, find CDE and CDF start */ |
568 | while (1) { | 620 | while (1) { |
569 | zip_header_t zip_header; | 621 | zip_header_t zip; |
570 | mode_t dir_mode = 0777; | 622 | mode_t dir_mode = 0777; |
571 | #if ENABLE_FEATURE_UNZIP_CDF | 623 | #if ENABLE_FEATURE_UNZIP_CDF |
572 | mode_t file_mode = 0666; | 624 | mode_t file_mode = 0666; |
@@ -592,7 +644,7 @@ int unzip_main(int argc, char **argv) | |||
592 | 644 | ||
593 | /* Check magic number */ | 645 | /* Check magic number */ |
594 | xread(zip_fd, &magic, 4); | 646 | xread(zip_fd, &magic, 4); |
595 | /* Central directory? It's at the end, so exit */ | 647 | /* CDF item? Assume there are no more files, exit */ |
596 | if (magic == ZIP_CDF_MAGIC) { | 648 | if (magic == ZIP_CDF_MAGIC) { |
597 | dbg("got ZIP_CDF_MAGIC"); | 649 | dbg("got ZIP_CDF_MAGIC"); |
598 | break; | 650 | break; |
@@ -608,71 +660,70 @@ int unzip_main(int argc, char **argv) | |||
608 | bb_error_msg_and_die("invalid zip magic %08X", (int)magic); | 660 | bb_error_msg_and_die("invalid zip magic %08X", (int)magic); |
609 | dbg("got ZIP_FILEHEADER_MAGIC"); | 661 | dbg("got ZIP_FILEHEADER_MAGIC"); |
610 | 662 | ||
611 | xread(zip_fd, zip_header.raw, ZIP_HEADER_LEN); | 663 | xread(zip_fd, zip.raw, ZIP_HEADER_LEN); |
612 | FIX_ENDIANNESS_ZIP(zip_header); | 664 | FIX_ENDIANNESS_ZIP(zip); |
613 | if ((zip_header.formatted.method != 0) | 665 | if (zip.fmt.zip_flags & SWAP_LE16(0x0008)) { |
614 | && (zip_header.formatted.method != 8) | 666 | bb_error_msg_and_die("zip flag %s is not supported", |
615 | ) { | 667 | "8 (streaming)"); |
616 | /* TODO? method 12: bzip2, method 14: LZMA */ | ||
617 | bb_error_msg_and_die("unsupported method %d", zip_header.formatted.method); | ||
618 | } | ||
619 | if (zip_header.formatted.zip_flags & SWAP_LE16(0x0009)) { | ||
620 | bb_error_msg_and_die("zip flags 1 and 8 are not supported"); | ||
621 | } | 668 | } |
622 | } | 669 | } |
623 | #if ENABLE_FEATURE_UNZIP_CDF | 670 | #if ENABLE_FEATURE_UNZIP_CDF |
624 | else { | 671 | else { |
625 | /* cdf_offset is valid (and we know the file is seekable) */ | 672 | /* cdf_offset is valid (and we know the file is seekable) */ |
626 | cdf_header_t cdf_header; | 673 | cdf_header_t cdf; |
627 | cdf_offset = read_next_cdf(cdf_offset, &cdf_header); | 674 | cdf_offset = read_next_cdf(cdf_offset, &cdf); |
628 | if (cdf_offset == 0) /* EOF? */ | 675 | if (cdf_offset == 0) /* EOF? */ |
629 | break; | 676 | break; |
630 | # if 1 | 677 | # if 1 |
631 | xlseek(zip_fd, | 678 | xlseek(zip_fd, |
632 | SWAP_LE32(cdf_header.formatted.relative_offset_of_local_header) + 4, | 679 | SWAP_LE32(cdf.fmt.relative_offset_of_local_header) + 4, |
633 | SEEK_SET); | 680 | SEEK_SET); |
634 | xread(zip_fd, zip_header.raw, ZIP_HEADER_LEN); | 681 | xread(zip_fd, zip.raw, ZIP_HEADER_LEN); |
635 | FIX_ENDIANNESS_ZIP(zip_header); | 682 | FIX_ENDIANNESS_ZIP(zip); |
636 | if (zip_header.formatted.zip_flags & SWAP_LE16(0x0008)) { | 683 | if (zip.fmt.zip_flags & SWAP_LE16(0x0008)) { |
637 | /* 0x0008 - streaming. [u]cmpsize can be reliably gotten | 684 | /* 0x0008 - streaming. [u]cmpsize can be reliably gotten |
638 | * only from Central Directory. | 685 | * only from Central Directory. |
639 | */ | 686 | */ |
640 | zip_header.formatted.crc32 = cdf_header.formatted.crc32; | 687 | zip.fmt.crc32 = cdf.fmt.crc32; |
641 | zip_header.formatted.cmpsize = cdf_header.formatted.cmpsize; | 688 | zip.fmt.cmpsize = cdf.fmt.cmpsize; |
642 | zip_header.formatted.ucmpsize = cdf_header.formatted.ucmpsize; | 689 | zip.fmt.ucmpsize = cdf.fmt.ucmpsize; |
643 | } | 690 | } |
644 | # else | 691 | # else |
645 | /* CDF has the same data as local header, no need to read the latter */ | 692 | /* CDF has the same data as local header, no need to read the latter... |
646 | memcpy(&zip_header.formatted.version, | 693 | * ...not really. An archive was seen with cdf.extra_len == 6 but |
647 | &cdf_header.formatted.version_needed, ZIP_HEADER_LEN); | 694 | * zip.extra_len == 0. |
695 | */ | ||
696 | memcpy(&zip.fmt.version, | ||
697 | &cdf.fmt.version_needed, ZIP_HEADER_LEN); | ||
648 | xlseek(zip_fd, | 698 | xlseek(zip_fd, |
649 | SWAP_LE32(cdf_header.formatted.relative_offset_of_local_header) + 4 + ZIP_HEADER_LEN, | 699 | SWAP_LE32(cdf.fmt.relative_offset_of_local_header) + 4 + ZIP_HEADER_LEN, |
650 | SEEK_SET); | 700 | SEEK_SET); |
651 | # endif | 701 | # endif |
652 | if ((cdf_header.formatted.version_made_by >> 8) == 3) { | 702 | if ((cdf.fmt.version_made_by >> 8) == 3) { |
653 | /* This archive is created on Unix */ | 703 | /* This archive is created on Unix */ |
654 | dir_mode = file_mode = (cdf_header.formatted.external_file_attributes >> 16); | 704 | dir_mode = file_mode = (cdf.fmt.external_attributes >> 16); |
655 | } | 705 | } |
656 | } | 706 | } |
657 | #endif | 707 | #endif |
658 | 708 | ||
659 | if (zip_header.formatted.zip_flags & SWAP_LE16(0x0001)) { | 709 | if (zip.fmt.zip_flags & SWAP_LE16(0x0001)) { |
660 | /* 0x0001 - encrypted */ | 710 | /* 0x0001 - encrypted */ |
661 | bb_error_msg_and_die("zip flag 1 (encryption) is not supported"); | 711 | bb_error_msg_and_die("zip flag %s is not supported", |
712 | "1 (encryption)"); | ||
662 | } | 713 | } |
663 | dbg("File cmpsize:0x%x extra_len:0x%x ucmpsize:0x%x", | 714 | dbg("File cmpsize:0x%x extra_len:0x%x ucmpsize:0x%x", |
664 | (unsigned)zip_header.formatted.cmpsize, | 715 | (unsigned)zip.fmt.cmpsize, |
665 | (unsigned)zip_header.formatted.extra_len, | 716 | (unsigned)zip.fmt.extra_len, |
666 | (unsigned)zip_header.formatted.ucmpsize | 717 | (unsigned)zip.fmt.ucmpsize |
667 | ); | 718 | ); |
668 | 719 | ||
669 | /* Read filename */ | 720 | /* Read filename */ |
670 | free(dst_fn); | 721 | free(dst_fn); |
671 | dst_fn = xzalloc(zip_header.formatted.filename_len + 1); | 722 | dst_fn = xzalloc(zip.fmt.filename_len + 1); |
672 | xread(zip_fd, dst_fn, zip_header.formatted.filename_len); | 723 | xread(zip_fd, dst_fn, zip.fmt.filename_len); |
673 | 724 | ||
674 | /* Skip extra header bytes */ | 725 | /* Skip extra header bytes */ |
675 | unzip_skip(zip_header.formatted.extra_len); | 726 | unzip_skip(zip.fmt.extra_len); |
676 | 727 | ||
677 | /* Guard against "/abspath", "/../" and similar attacks */ | 728 | /* Guard against "/abspath", "/../" and similar attacks */ |
678 | overlapping_strcpy(dst_fn, strip_unsafe_prefix(dst_fn)); | 729 | overlapping_strcpy(dst_fn, strip_unsafe_prefix(dst_fn)); |
@@ -681,129 +732,129 @@ int unzip_main(int argc, char **argv) | |||
681 | if (find_list_entry(zreject, dst_fn) | 732 | if (find_list_entry(zreject, dst_fn) |
682 | || (zaccept && !find_list_entry(zaccept, dst_fn)) | 733 | || (zaccept && !find_list_entry(zaccept, dst_fn)) |
683 | ) { /* Skip entry */ | 734 | ) { /* Skip entry */ |
684 | i = 'n'; | 735 | goto skip_cmpsize; |
685 | } else { | 736 | } |
686 | if (listing) { | 737 | |
687 | /* List entry */ | 738 | if (listing) { |
688 | char dtbuf[sizeof("mm-dd-yyyy hh:mm")]; | 739 | /* List entry */ |
689 | sprintf(dtbuf, "%02u-%02u-%04u %02u:%02u", | 740 | char dtbuf[sizeof("mm-dd-yyyy hh:mm")]; |
690 | (zip_header.formatted.moddate >> 5) & 0xf, // mm: 0x01e0 | 741 | sprintf(dtbuf, "%02u-%02u-%04u %02u:%02u", |
691 | (zip_header.formatted.moddate) & 0x1f, // dd: 0x001f | 742 | (zip.fmt.moddate >> 5) & 0xf, // mm: 0x01e0 |
692 | (zip_header.formatted.moddate >> 9) + 1980, // yy: 0xfe00 | 743 | (zip.fmt.moddate) & 0x1f, // dd: 0x001f |
693 | (zip_header.formatted.modtime >> 11), // hh: 0xf800 | 744 | (zip.fmt.moddate >> 9) + 1980, // yy: 0xfe00 |
694 | (zip_header.formatted.modtime >> 5) & 0x3f // mm: 0x07e0 | 745 | (zip.fmt.modtime >> 11), // hh: 0xf800 |
695 | // seconds/2 are not shown, encoded in ----------- 0x001f | 746 | (zip.fmt.modtime >> 5) & 0x3f // mm: 0x07e0 |
696 | ); | 747 | // seconds/2 not shown, encoded in -- 0x001f |
697 | if (!verbose) { | 748 | ); |
698 | // " Length Date Time Name\n" | 749 | if (!verbose) { |
699 | // "--------- ---------- ----- ----" | 750 | // " Length Date Time Name\n" |
700 | printf( "%9u " "%s " "%s\n", | 751 | // "--------- ---------- ----- ----" |
701 | (unsigned)zip_header.formatted.ucmpsize, | 752 | printf( "%9u " "%s " "%s\n", |
702 | dtbuf, | 753 | (unsigned)zip.fmt.ucmpsize, |
703 | dst_fn); | 754 | dtbuf, |
704 | } else { | 755 | dst_fn); |
705 | unsigned long percents = zip_header.formatted.ucmpsize - zip_header.formatted.cmpsize; | 756 | } else { |
706 | if ((int32_t)percents < 0) | 757 | char method6[7]; |
707 | percents = 0; /* happens if ucmpsize < cmpsize */ | 758 | unsigned long percents; |
708 | percents = percents * 100; | 759 | |
709 | if (zip_header.formatted.ucmpsize) | 760 | sprintf(method6, "%6u", zip.fmt.method); |
710 | percents /= zip_header.formatted.ucmpsize; | 761 | if (zip.fmt.method == 0) { |
711 | // " Length Method Size Cmpr Date Time CRC-32 Name\n" | 762 | strcpy(method6, "Stored"); |
712 | // "-------- ------ ------- ---- ---------- ----- -------- ----" | 763 | } |
713 | printf( "%8u %s" "%9u%4u%% " "%s " "%08x " "%s\n", | 764 | if (zip.fmt.method == 8) { |
714 | (unsigned)zip_header.formatted.ucmpsize, | 765 | strcpy(method6, "Defl:N"); |
715 | zip_header.formatted.method == 0 ? "Stored" : "Defl:N", /* Defl is method 8 */ | 766 | /* normal, maximum, fast, superfast */ |
716 | /* TODO: show other methods? | 767 | IF_DESKTOP(method6[5] = "NXFS"[(zip.fmt.zip_flags >> 1) & 3];) |
717 | * 1 - Shrunk | ||
718 | * 2 - Reduced with compression factor 1 | ||
719 | * 3 - Reduced with compression factor 2 | ||
720 | * 4 - Reduced with compression factor 3 | ||
721 | * 5 - Reduced with compression factor 4 | ||
722 | * 6 - Imploded | ||
723 | * 7 - Reserved for Tokenizing compression algorithm | ||
724 | * 9 - Deflate64 | ||
725 | * 10 - PKWARE Data Compression Library Imploding | ||
726 | * 11 - Reserved by PKWARE | ||
727 | * 12 - BZIP2 | ||
728 | */ | ||
729 | (unsigned)zip_header.formatted.cmpsize, | ||
730 | (unsigned)percents, | ||
731 | dtbuf, | ||
732 | zip_header.formatted.crc32, | ||
733 | dst_fn); | ||
734 | total_size += zip_header.formatted.cmpsize; | ||
735 | } | 768 | } |
736 | total_usize += zip_header.formatted.ucmpsize; | 769 | percents = zip.fmt.ucmpsize - zip.fmt.cmpsize; |
737 | i = 'n'; | 770 | if ((int32_t)percents < 0) |
738 | } else if (dst_fd == STDOUT_FILENO) { | 771 | percents = 0; /* happens if ucmpsize < cmpsize */ |
739 | /* Extracting to STDOUT */ | 772 | percents = percents * 100; |
740 | i = -1; | 773 | if (zip.fmt.ucmpsize) |
741 | } else if (last_char_is(dst_fn, '/')) { | 774 | percents /= zip.fmt.ucmpsize; |
742 | /* Extract directory */ | 775 | // " Length Method Size Cmpr Date Time CRC-32 Name\n" |
743 | if (stat(dst_fn, &stat_buf) == -1) { | 776 | // "-------- ------ ------- ---- ---------- ----- -------- ----" |
744 | if (errno != ENOENT) { | 777 | printf( "%8u %s" "%9u%4u%% " "%s " "%08x " "%s\n", |
745 | bb_perror_msg_and_die("can't stat '%s'", dst_fn); | 778 | (unsigned)zip.fmt.ucmpsize, |
746 | } | 779 | method6, |
747 | if (!quiet) { | 780 | (unsigned)zip.fmt.cmpsize, |
748 | printf(" creating: %s\n", dst_fn); | 781 | (unsigned)percents, |
749 | } | 782 | dtbuf, |
750 | unzip_create_leading_dirs(dst_fn); | 783 | zip.fmt.crc32, |
751 | if (bb_make_directory(dst_fn, dir_mode, FILEUTILS_IGNORE_CHMOD_ERR)) { | 784 | dst_fn); |
752 | xfunc_die(); | 785 | total_size += zip.fmt.cmpsize; |
753 | } | 786 | } |
754 | } else { | 787 | total_usize += zip.fmt.ucmpsize; |
755 | if (!S_ISDIR(stat_buf.st_mode)) { | 788 | goto skip_cmpsize; |
756 | bb_error_msg_and_die("'%s' exists but is not a %s", | 789 | } |
757 | dst_fn, "directory"); | 790 | |
758 | } | 791 | if (dst_fd == STDOUT_FILENO) { |
792 | /* Extracting to STDOUT */ | ||
793 | goto do_extract; | ||
794 | } | ||
795 | if (last_char_is(dst_fn, '/')) { | ||
796 | /* Extract directory */ | ||
797 | if (stat(dst_fn, &stat_buf) == -1) { | ||
798 | if (errno != ENOENT) { | ||
799 | bb_perror_msg_and_die("can't stat '%s'", dst_fn); | ||
800 | } | ||
801 | if (!quiet) { | ||
802 | printf(" creating: %s\n", dst_fn); | ||
803 | } | ||
804 | unzip_create_leading_dirs(dst_fn); | ||
805 | if (bb_make_directory(dst_fn, dir_mode, FILEUTILS_IGNORE_CHMOD_ERR)) { | ||
806 | xfunc_die(); | ||
759 | } | 807 | } |
760 | i = 'n'; | ||
761 | } else { | 808 | } else { |
762 | /* Extract file */ | 809 | if (!S_ISDIR(stat_buf.st_mode)) { |
763 | check_file: | 810 | bb_error_msg_and_die("'%s' exists but is not a %s", |
764 | if (stat(dst_fn, &stat_buf) == -1) { | 811 | dst_fn, "directory"); |
765 | /* File does not exist */ | ||
766 | if (errno != ENOENT) { | ||
767 | bb_perror_msg_and_die("can't stat '%s'", dst_fn); | ||
768 | } | ||
769 | i = 'y'; | ||
770 | } else { | ||
771 | /* File already exists */ | ||
772 | if (overwrite == O_NEVER) { | ||
773 | i = 'n'; | ||
774 | } else if (S_ISREG(stat_buf.st_mode)) { | ||
775 | /* File is regular file */ | ||
776 | if (overwrite == O_ALWAYS) { | ||
777 | i = 'y'; | ||
778 | } else { | ||
779 | printf("replace %s? [y]es, [n]o, [A]ll, [N]one, [r]ename: ", dst_fn); | ||
780 | my_fgets80(key_buf); | ||
781 | i = key_buf[0]; | ||
782 | } | ||
783 | } else { | ||
784 | /* File is not regular file */ | ||
785 | bb_error_msg_and_die("'%s' exists but is not a %s", | ||
786 | dst_fn, "regular file"); | ||
787 | } | ||
788 | } | 812 | } |
789 | } | 813 | } |
814 | goto skip_cmpsize; | ||
815 | } | ||
816 | check_file: | ||
817 | /* Extract file */ | ||
818 | if (stat(dst_fn, &stat_buf) == -1) { | ||
819 | /* File does not exist */ | ||
820 | if (errno != ENOENT) { | ||
821 | bb_perror_msg_and_die("can't stat '%s'", dst_fn); | ||
822 | } | ||
823 | goto do_open_and_extract; | ||
824 | } | ||
825 | /* File already exists */ | ||
826 | if (overwrite == O_NEVER) { | ||
827 | goto skip_cmpsize; | ||
828 | } | ||
829 | if (!S_ISREG(stat_buf.st_mode)) { | ||
830 | /* File is not regular file */ | ||
831 | bb_error_msg_and_die("'%s' exists but is not a %s", | ||
832 | dst_fn, "regular file"); | ||
790 | } | 833 | } |
834 | /* File is regular file */ | ||
835 | if (overwrite == O_ALWAYS) | ||
836 | goto do_open_and_extract; | ||
837 | printf("replace %s? [y]es, [n]o, [A]ll, [N]one, [r]ename: ", dst_fn); | ||
838 | my_fgets80(key_buf); | ||
791 | 839 | ||
792 | switch (i) { | 840 | switch (key_buf[0]) { |
793 | case 'A': | 841 | case 'A': |
794 | overwrite = O_ALWAYS; | 842 | overwrite = O_ALWAYS; |
795 | case 'y': /* Open file and fall into unzip */ | 843 | case 'y': /* Open file and fall into unzip */ |
844 | do_open_and_extract: | ||
796 | unzip_create_leading_dirs(dst_fn); | 845 | unzip_create_leading_dirs(dst_fn); |
797 | #if ENABLE_FEATURE_UNZIP_CDF | 846 | #if ENABLE_FEATURE_UNZIP_CDF |
798 | dst_fd = xopen3(dst_fn, O_WRONLY | O_CREAT | O_TRUNC, file_mode); | 847 | dst_fd = xopen3(dst_fn, O_WRONLY | O_CREAT | O_TRUNC, file_mode); |
799 | #else | 848 | #else |
800 | dst_fd = xopen(dst_fn, O_WRONLY | O_CREAT | O_TRUNC); | 849 | dst_fd = xopen(dst_fn, O_WRONLY | O_CREAT | O_TRUNC); |
801 | #endif | 850 | #endif |
802 | case -1: /* Unzip */ | 851 | do_extract: |
803 | if (!quiet) { | 852 | if (!quiet) { |
804 | printf(" inflating: %s\n", dst_fn); | 853 | printf(/* zip.fmt.method == 0 |
854 | ? " extracting: %s\n" | ||
855 | : */ " inflating: %s\n", dst_fn); | ||
805 | } | 856 | } |
806 | unzip_extract(&zip_header, dst_fd); | 857 | unzip_extract(&zip, dst_fd); |
807 | if (dst_fd != STDOUT_FILENO) { | 858 | if (dst_fd != STDOUT_FILENO) { |
808 | /* closing STDOUT is potentially bad for future business */ | 859 | /* closing STDOUT is potentially bad for future business */ |
809 | close(dst_fd); | 860 | close(dst_fd); |
@@ -812,9 +863,9 @@ int unzip_main(int argc, char **argv) | |||
812 | 863 | ||
813 | case 'N': | 864 | case 'N': |
814 | overwrite = O_NEVER; | 865 | overwrite = O_NEVER; |
815 | case 'n': | 866 | case 'n': /* Skip entry data */ |
816 | /* Skip entry data */ | 867 | skip_cmpsize: |
817 | unzip_skip(zip_header.formatted.cmpsize); | 868 | unzip_skip(zip.fmt.cmpsize); |
818 | break; | 869 | break; |
819 | 870 | ||
820 | case 'r': | 871 | case 'r': |
@@ -827,7 +878,7 @@ int unzip_main(int argc, char **argv) | |||
827 | goto check_file; | 878 | goto check_file; |
828 | 879 | ||
829 | default: | 880 | default: |
830 | printf("error: invalid response [%c]\n", (char)i); | 881 | printf("error: invalid response [%c]\n", (char)key_buf[0]); |
831 | goto check_file; | 882 | goto check_file; |
832 | } | 883 | } |
833 | 884 | ||
diff --git a/configs/TEST_nommu_defconfig b/configs/TEST_nommu_defconfig index 08351a294..7fbbbecc7 100644 --- a/configs/TEST_nommu_defconfig +++ b/configs/TEST_nommu_defconfig | |||
@@ -266,11 +266,6 @@ CONFIG_YES=y | |||
266 | CONFIG_FEATURE_PRESERVE_HARDLINKS=y | 266 | CONFIG_FEATURE_PRESERVE_HARDLINKS=y |
267 | 267 | ||
268 | # | 268 | # |
269 | # Common options for ls, more and telnet | ||
270 | # | ||
271 | CONFIG_FEATURE_AUTOWIDTH=y | ||
272 | |||
273 | # | ||
274 | # Common options for df, du, ls | 269 | # Common options for df, du, ls |
275 | # | 270 | # |
276 | CONFIG_FEATURE_HUMAN_READABLE=y | 271 | CONFIG_FEATURE_HUMAN_READABLE=y |
@@ -387,7 +382,7 @@ CONFIG_FEATURE_KILL_REMOVED=y | |||
387 | CONFIG_FEATURE_KILL_DELAY=1 | 382 | CONFIG_FEATURE_KILL_DELAY=1 |
388 | CONFIG_FEATURE_INIT_SCTTY=y | 383 | CONFIG_FEATURE_INIT_SCTTY=y |
389 | CONFIG_FEATURE_INIT_SYSLOG=y | 384 | CONFIG_FEATURE_INIT_SYSLOG=y |
390 | CONFIG_FEATURE_EXTRA_QUIET=y | 385 | CONFIG_FEATURE_INIT_QUIET=y |
391 | CONFIG_FEATURE_INIT_COREDUMPS=y | 386 | CONFIG_FEATURE_INIT_COREDUMPS=y |
392 | CONFIG_LINUXRC=y | 387 | CONFIG_LINUXRC=y |
393 | CONFIG_HALT=y | 388 | CONFIG_HALT=y |
@@ -457,15 +452,12 @@ CONFIG_FEATURE_MODPROBE_SMALL_CHECK_ALREADY_LOADED=y | |||
457 | # Options common to multiple modutils | 452 | # Options common to multiple modutils |
458 | # | 453 | # |
459 | # CONFIG_FEATURE_2_4_MODULES is not set | 454 | # CONFIG_FEATURE_2_4_MODULES is not set |
460 | CONFIG_FEATURE_INSMOD_TRY_MMAP=y | ||
461 | # CONFIG_FEATURE_INSMOD_VERSION_CHECKING is not set | 455 | # CONFIG_FEATURE_INSMOD_VERSION_CHECKING is not set |
462 | # CONFIG_FEATURE_INSMOD_KSYMOOPS_SYMBOLS is not set | 456 | # CONFIG_FEATURE_INSMOD_KSYMOOPS_SYMBOLS is not set |
463 | # CONFIG_FEATURE_INSMOD_LOADINKMEM is not set | 457 | # CONFIG_FEATURE_INSMOD_LOADINKMEM is not set |
464 | # CONFIG_FEATURE_INSMOD_LOAD_MAP is not set | 458 | # CONFIG_FEATURE_INSMOD_LOAD_MAP is not set |
465 | # CONFIG_FEATURE_INSMOD_LOAD_MAP_FULL is not set | 459 | # CONFIG_FEATURE_INSMOD_LOAD_MAP_FULL is not set |
466 | # CONFIG_FEATURE_CHECK_TAINTED_MODULE is not set | 460 | # CONFIG_FEATURE_CHECK_TAINTED_MODULE is not set |
467 | # CONFIG_FEATURE_MODUTILS_ALIAS is not set | ||
468 | # CONFIG_FEATURE_MODUTILS_SYMBOLS is not set | ||
469 | CONFIG_DEFAULT_MODULES_DIR="/lib/modules" | 461 | CONFIG_DEFAULT_MODULES_DIR="/lib/modules" |
470 | CONFIG_DEFAULT_DEPMOD_FILE="modules.dep" | 462 | CONFIG_DEFAULT_DEPMOD_FILE="modules.dep" |
471 | 463 | ||
@@ -524,7 +516,6 @@ CONFIG_FEATURE_MDEV_LOAD_FIRMWARE=y | |||
524 | CONFIG_MKSWAP=y | 516 | CONFIG_MKSWAP=y |
525 | CONFIG_FEATURE_MKSWAP_UUID=y | 517 | CONFIG_FEATURE_MKSWAP_UUID=y |
526 | CONFIG_MORE=y | 518 | CONFIG_MORE=y |
527 | CONFIG_FEATURE_USE_TERMIOS=y | ||
528 | CONFIG_VOLUMEID=y | 519 | CONFIG_VOLUMEID=y |
529 | CONFIG_FEATURE_VOLUMEID_EXT=y | 520 | CONFIG_FEATURE_VOLUMEID_EXT=y |
530 | CONFIG_FEATURE_VOLUMEID_BTRFS=y | 521 | CONFIG_FEATURE_VOLUMEID_BTRFS=y |
@@ -879,9 +870,9 @@ CONFIG_FEATURE_SH_IS_HUSH=y | |||
879 | # CONFIG_ASH_JOB_CONTROL is not set | 870 | # CONFIG_ASH_JOB_CONTROL is not set |
880 | # CONFIG_ASH_ALIAS is not set | 871 | # CONFIG_ASH_ALIAS is not set |
881 | # CONFIG_ASH_GETOPTS is not set | 872 | # CONFIG_ASH_GETOPTS is not set |
882 | # CONFIG_ASH_BUILTIN_ECHO is not set | 873 | # CONFIG_ASH_ECHO is not set |
883 | # CONFIG_ASH_BUILTIN_PRINTF is not set | 874 | # CONFIG_ASH_PRINTF is not set |
884 | # CONFIG_ASH_BUILTIN_TEST is not set | 875 | # CONFIG_ASH_TEST is not set |
885 | # CONFIG_ASH_CMDCMD is not set | 876 | # CONFIG_ASH_CMDCMD is not set |
886 | # CONFIG_ASH_MAIL is not set | 877 | # CONFIG_ASH_MAIL is not set |
887 | # CONFIG_ASH_OPTIMIZE_FOR_SIZE is not set | 878 | # CONFIG_ASH_OPTIMIZE_FOR_SIZE is not set |
diff --git a/configs/TEST_noprintf_defconfig b/configs/TEST_noprintf_defconfig index 70dacece0..3f85ee1df 100644 --- a/configs/TEST_noprintf_defconfig +++ b/configs/TEST_noprintf_defconfig | |||
@@ -277,7 +277,6 @@ CONFIG_TRUE=y | |||
277 | # CONFIG_WHOAMI is not set | 277 | # CONFIG_WHOAMI is not set |
278 | # CONFIG_YES is not set | 278 | # CONFIG_YES is not set |
279 | # CONFIG_FEATURE_PRESERVE_HARDLINKS is not set | 279 | # CONFIG_FEATURE_PRESERVE_HARDLINKS is not set |
280 | # CONFIG_FEATURE_AUTOWIDTH is not set | ||
281 | # CONFIG_FEATURE_HUMAN_READABLE is not set | 280 | # CONFIG_FEATURE_HUMAN_READABLE is not set |
282 | # CONFIG_FEATURE_MD5_SHA1_SUM_CHECK is not set | 281 | # CONFIG_FEATURE_MD5_SHA1_SUM_CHECK is not set |
283 | 282 | ||
@@ -392,7 +391,7 @@ CONFIG_FEATURE_VI_MAX_LEN=0 | |||
392 | CONFIG_FEATURE_KILL_DELAY=0 | 391 | CONFIG_FEATURE_KILL_DELAY=0 |
393 | # CONFIG_FEATURE_INIT_SCTTY is not set | 392 | # CONFIG_FEATURE_INIT_SCTTY is not set |
394 | # CONFIG_FEATURE_INIT_SYSLOG is not set | 393 | # CONFIG_FEATURE_INIT_SYSLOG is not set |
395 | # CONFIG_FEATURE_EXTRA_QUIET is not set | 394 | # CONFIG_FEATURE_INIT_QUIET is not set |
396 | # CONFIG_FEATURE_INIT_COREDUMPS is not set | 395 | # CONFIG_FEATURE_INIT_COREDUMPS is not set |
397 | # CONFIG_LINUXRC is not set | 396 | # CONFIG_LINUXRC is not set |
398 | # CONFIG_HALT is not set | 397 | # CONFIG_HALT is not set |
@@ -527,7 +526,6 @@ CONFIG_FDISK_SUPPORT_LARGE_DISKS=y | |||
527 | # CONFIG_MKSWAP is not set | 526 | # CONFIG_MKSWAP is not set |
528 | # CONFIG_FEATURE_MKSWAP_UUID is not set | 527 | # CONFIG_FEATURE_MKSWAP_UUID is not set |
529 | # CONFIG_MORE is not set | 528 | # CONFIG_MORE is not set |
530 | # CONFIG_FEATURE_USE_TERMIOS is not set | ||
531 | CONFIG_VOLUMEID=y | 529 | CONFIG_VOLUMEID=y |
532 | # CONFIG_FEATURE_VOLUMEID_EXT is not set | 530 | # CONFIG_FEATURE_VOLUMEID_EXT is not set |
533 | # CONFIG_FEATURE_VOLUMEID_BTRFS is not set | 531 | # CONFIG_FEATURE_VOLUMEID_BTRFS is not set |
@@ -873,9 +871,9 @@ CONFIG_SV_DEFAULT_SERVICE_DIR="" | |||
873 | # CONFIG_ASH_JOB_CONTROL is not set | 871 | # CONFIG_ASH_JOB_CONTROL is not set |
874 | # CONFIG_ASH_ALIAS is not set | 872 | # CONFIG_ASH_ALIAS is not set |
875 | # CONFIG_ASH_GETOPTS is not set | 873 | # CONFIG_ASH_GETOPTS is not set |
876 | # CONFIG_ASH_BUILTIN_ECHO is not set | 874 | # CONFIG_ASH_ECHO is not set |
877 | # CONFIG_ASH_BUILTIN_PRINTF is not set | 875 | # CONFIG_ASH_PRINTF is not set |
878 | # CONFIG_ASH_BUILTIN_TEST is not set | 876 | # CONFIG_ASH_TEST is not set |
879 | # CONFIG_ASH_CMDCMD is not set | 877 | # CONFIG_ASH_CMDCMD is not set |
880 | # CONFIG_ASH_MAIL is not set | 878 | # CONFIG_ASH_MAIL is not set |
881 | # CONFIG_ASH_OPTIMIZE_FOR_SIZE is not set | 879 | # CONFIG_ASH_OPTIMIZE_FOR_SIZE is not set |
diff --git a/configs/TEST_rh9_defconfig b/configs/TEST_rh9_defconfig index 4a5fad324..34d8e31e2 100644 --- a/configs/TEST_rh9_defconfig +++ b/configs/TEST_rh9_defconfig | |||
@@ -277,11 +277,6 @@ CONFIG_YES=y | |||
277 | CONFIG_FEATURE_PRESERVE_HARDLINKS=y | 277 | CONFIG_FEATURE_PRESERVE_HARDLINKS=y |
278 | 278 | ||
279 | # | 279 | # |
280 | # Common options for ls, more and telnet | ||
281 | # | ||
282 | CONFIG_FEATURE_AUTOWIDTH=y | ||
283 | |||
284 | # | ||
285 | # Common options for df, du, ls | 280 | # Common options for df, du, ls |
286 | # | 281 | # |
287 | CONFIG_FEATURE_HUMAN_READABLE=y | 282 | CONFIG_FEATURE_HUMAN_READABLE=y |
@@ -404,7 +399,7 @@ CONFIG_FEATURE_USE_INITTAB=y | |||
404 | CONFIG_FEATURE_KILL_DELAY=0 | 399 | CONFIG_FEATURE_KILL_DELAY=0 |
405 | CONFIG_FEATURE_INIT_SCTTY=y | 400 | CONFIG_FEATURE_INIT_SCTTY=y |
406 | CONFIG_FEATURE_INIT_SYSLOG=y | 401 | CONFIG_FEATURE_INIT_SYSLOG=y |
407 | CONFIG_FEATURE_EXTRA_QUIET=y | 402 | CONFIG_FEATURE_INIT_QUIET=y |
408 | CONFIG_FEATURE_INIT_COREDUMPS=y | 403 | CONFIG_FEATURE_INIT_COREDUMPS=y |
409 | CONFIG_LINUXRC=y | 404 | CONFIG_LINUXRC=y |
410 | CONFIG_HALT=y | 405 | CONFIG_HALT=y |
@@ -472,15 +467,12 @@ CONFIG_FEATURE_MODPROBE_SMALL_CHECK_ALREADY_LOADED=y | |||
472 | # Options common to multiple modutils | 467 | # Options common to multiple modutils |
473 | # | 468 | # |
474 | # CONFIG_FEATURE_2_4_MODULES is not set | 469 | # CONFIG_FEATURE_2_4_MODULES is not set |
475 | # CONFIG_FEATURE_INSMOD_TRY_MMAP is not set | ||
476 | # CONFIG_FEATURE_INSMOD_VERSION_CHECKING is not set | 470 | # CONFIG_FEATURE_INSMOD_VERSION_CHECKING is not set |
477 | # CONFIG_FEATURE_INSMOD_KSYMOOPS_SYMBOLS is not set | 471 | # CONFIG_FEATURE_INSMOD_KSYMOOPS_SYMBOLS is not set |
478 | # CONFIG_FEATURE_INSMOD_LOADINKMEM is not set | 472 | # CONFIG_FEATURE_INSMOD_LOADINKMEM is not set |
479 | # CONFIG_FEATURE_INSMOD_LOAD_MAP is not set | 473 | # CONFIG_FEATURE_INSMOD_LOAD_MAP is not set |
480 | # CONFIG_FEATURE_INSMOD_LOAD_MAP_FULL is not set | 474 | # CONFIG_FEATURE_INSMOD_LOAD_MAP_FULL is not set |
481 | # CONFIG_FEATURE_CHECK_TAINTED_MODULE is not set | 475 | # CONFIG_FEATURE_CHECK_TAINTED_MODULE is not set |
482 | # CONFIG_FEATURE_MODUTILS_ALIAS is not set | ||
483 | # CONFIG_FEATURE_MODUTILS_SYMBOLS is not set | ||
484 | CONFIG_DEFAULT_MODULES_DIR="/lib/modules" | 476 | CONFIG_DEFAULT_MODULES_DIR="/lib/modules" |
485 | CONFIG_DEFAULT_DEPMOD_FILE="modules.dep" | 477 | CONFIG_DEFAULT_DEPMOD_FILE="modules.dep" |
486 | 478 | ||
@@ -540,7 +532,6 @@ CONFIG_FEATURE_MDEV_LOAD_FIRMWARE=y | |||
540 | CONFIG_MKSWAP=y | 532 | CONFIG_MKSWAP=y |
541 | CONFIG_FEATURE_MKSWAP_UUID=y | 533 | CONFIG_FEATURE_MKSWAP_UUID=y |
542 | CONFIG_MORE=y | 534 | CONFIG_MORE=y |
543 | CONFIG_FEATURE_USE_TERMIOS=y | ||
544 | CONFIG_VOLUMEID=y | 535 | CONFIG_VOLUMEID=y |
545 | CONFIG_FEATURE_VOLUMEID_EXT=y | 536 | CONFIG_FEATURE_VOLUMEID_EXT=y |
546 | CONFIG_FEATURE_VOLUMEID_BTRFS=y | 537 | CONFIG_FEATURE_VOLUMEID_BTRFS=y |
@@ -893,9 +884,9 @@ CONFIG_ASH_BASH_COMPAT=y | |||
893 | CONFIG_ASH_JOB_CONTROL=y | 884 | CONFIG_ASH_JOB_CONTROL=y |
894 | CONFIG_ASH_ALIAS=y | 885 | CONFIG_ASH_ALIAS=y |
895 | CONFIG_ASH_GETOPTS=y | 886 | CONFIG_ASH_GETOPTS=y |
896 | CONFIG_ASH_BUILTIN_ECHO=y | 887 | CONFIG_ASH_ECHO=y |
897 | CONFIG_ASH_BUILTIN_PRINTF=y | 888 | CONFIG_ASH_PRINTF=y |
898 | CONFIG_ASH_BUILTIN_TEST=y | 889 | CONFIG_ASH_TEST=y |
899 | CONFIG_ASH_CMDCMD=y | 890 | CONFIG_ASH_CMDCMD=y |
900 | # CONFIG_ASH_MAIL is not set | 891 | # CONFIG_ASH_MAIL is not set |
901 | CONFIG_ASH_OPTIMIZE_FOR_SIZE=y | 892 | CONFIG_ASH_OPTIMIZE_FOR_SIZE=y |
diff --git a/configs/android2_defconfig b/configs/android2_defconfig index 754f612c6..20866c32b 100644 --- a/configs/android2_defconfig +++ b/configs/android2_defconfig | |||
@@ -94,7 +94,6 @@ CONFIG_PASSWORD_MINLEN=6 | |||
94 | CONFIG_MD5_SMALL=1 | 94 | CONFIG_MD5_SMALL=1 |
95 | # CONFIG_FEATURE_FAST_TOP is not set | 95 | # CONFIG_FEATURE_FAST_TOP is not set |
96 | # CONFIG_FEATURE_ETC_NETWORKS is not set | 96 | # CONFIG_FEATURE_ETC_NETWORKS is not set |
97 | CONFIG_FEATURE_USE_TERMIOS=y | ||
98 | # CONFIG_FEATURE_EDITING is not set | 97 | # CONFIG_FEATURE_EDITING is not set |
99 | CONFIG_FEATURE_EDITING_MAX_LEN=0 | 98 | CONFIG_FEATURE_EDITING_MAX_LEN=0 |
100 | # CONFIG_FEATURE_EDITING_VI is not set | 99 | # CONFIG_FEATURE_EDITING_VI is not set |
@@ -290,11 +289,6 @@ CONFIG_YES=y | |||
290 | CONFIG_FEATURE_PRESERVE_HARDLINKS=y | 289 | CONFIG_FEATURE_PRESERVE_HARDLINKS=y |
291 | 290 | ||
292 | # | 291 | # |
293 | # Common options for ls, more and telnet | ||
294 | # | ||
295 | CONFIG_FEATURE_AUTOWIDTH=y | ||
296 | |||
297 | # | ||
298 | # Common options for df, du, ls | 292 | # Common options for df, du, ls |
299 | # | 293 | # |
300 | CONFIG_FEATURE_HUMAN_READABLE=y | 294 | CONFIG_FEATURE_HUMAN_READABLE=y |
@@ -422,7 +416,7 @@ CONFIG_FEATURE_USE_INITTAB=y | |||
422 | CONFIG_FEATURE_KILL_DELAY=0 | 416 | CONFIG_FEATURE_KILL_DELAY=0 |
423 | CONFIG_FEATURE_INIT_SCTTY=y | 417 | CONFIG_FEATURE_INIT_SCTTY=y |
424 | CONFIG_FEATURE_INIT_SYSLOG=y | 418 | CONFIG_FEATURE_INIT_SYSLOG=y |
425 | CONFIG_FEATURE_EXTRA_QUIET=y | 419 | CONFIG_FEATURE_INIT_QUIET=y |
426 | CONFIG_FEATURE_INIT_COREDUMPS=y | 420 | CONFIG_FEATURE_INIT_COREDUMPS=y |
427 | CONFIG_LINUXRC=y | 421 | CONFIG_LINUXRC=y |
428 | CONFIG_INIT_TERMINAL_TYPE="linux" | 422 | CONFIG_INIT_TERMINAL_TYPE="linux" |
@@ -493,15 +487,12 @@ CONFIG_FEATURE_MODPROBE_SMALL_CHECK_ALREADY_LOADED=y | |||
493 | # Options common to multiple modutils | 487 | # Options common to multiple modutils |
494 | # | 488 | # |
495 | # CONFIG_FEATURE_2_4_MODULES is not set | 489 | # CONFIG_FEATURE_2_4_MODULES is not set |
496 | # CONFIG_FEATURE_INSMOD_TRY_MMAP is not set | ||
497 | # CONFIG_FEATURE_INSMOD_VERSION_CHECKING is not set | 490 | # CONFIG_FEATURE_INSMOD_VERSION_CHECKING is not set |
498 | # CONFIG_FEATURE_INSMOD_KSYMOOPS_SYMBOLS is not set | 491 | # CONFIG_FEATURE_INSMOD_KSYMOOPS_SYMBOLS is not set |
499 | # CONFIG_FEATURE_INSMOD_LOADINKMEM is not set | 492 | # CONFIG_FEATURE_INSMOD_LOADINKMEM is not set |
500 | # CONFIG_FEATURE_INSMOD_LOAD_MAP is not set | 493 | # CONFIG_FEATURE_INSMOD_LOAD_MAP is not set |
501 | # CONFIG_FEATURE_INSMOD_LOAD_MAP_FULL is not set | 494 | # CONFIG_FEATURE_INSMOD_LOAD_MAP_FULL is not set |
502 | # CONFIG_FEATURE_CHECK_TAINTED_MODULE is not set | 495 | # CONFIG_FEATURE_CHECK_TAINTED_MODULE is not set |
503 | # CONFIG_FEATURE_MODUTILS_ALIAS is not set | ||
504 | # CONFIG_FEATURE_MODUTILS_SYMBOLS is not set | ||
505 | CONFIG_DEFAULT_MODULES_DIR="/lib/modules" | 496 | CONFIG_DEFAULT_MODULES_DIR="/lib/modules" |
506 | CONFIG_DEFAULT_DEPMOD_FILE="modules.dep" | 497 | CONFIG_DEFAULT_DEPMOD_FILE="modules.dep" |
507 | 498 | ||
@@ -936,9 +927,9 @@ CONFIG_SOFTLIMIT=y | |||
936 | # CONFIG_ASH_JOB_CONTROL is not set | 927 | # CONFIG_ASH_JOB_CONTROL is not set |
937 | # CONFIG_ASH_ALIAS is not set | 928 | # CONFIG_ASH_ALIAS is not set |
938 | # CONFIG_ASH_GETOPTS is not set | 929 | # CONFIG_ASH_GETOPTS is not set |
939 | # CONFIG_ASH_BUILTIN_ECHO is not set | 930 | # CONFIG_ASH_ECHO is not set |
940 | # CONFIG_ASH_BUILTIN_PRINTF is not set | 931 | # CONFIG_ASH_PRINTF is not set |
941 | # CONFIG_ASH_BUILTIN_TEST is not set | 932 | # CONFIG_ASH_TEST is not set |
942 | # CONFIG_ASH_CMDCMD is not set | 933 | # CONFIG_ASH_CMDCMD is not set |
943 | # CONFIG_ASH_MAIL is not set | 934 | # CONFIG_ASH_MAIL is not set |
944 | # CONFIG_ASH_OPTIMIZE_FOR_SIZE is not set | 935 | # CONFIG_ASH_OPTIMIZE_FOR_SIZE is not set |
diff --git a/configs/android_502_defconfig b/configs/android_502_defconfig index 8ea6c295d..bdca9eebb 100644 --- a/configs/android_502_defconfig +++ b/configs/android_502_defconfig | |||
@@ -174,7 +174,6 @@ CONFIG_MD5_SMALL=1 | |||
174 | CONFIG_SHA3_SMALL=1 | 174 | CONFIG_SHA3_SMALL=1 |
175 | # CONFIG_FEATURE_FAST_TOP is not set | 175 | # CONFIG_FEATURE_FAST_TOP is not set |
176 | # CONFIG_FEATURE_ETC_NETWORKS is not set | 176 | # CONFIG_FEATURE_ETC_NETWORKS is not set |
177 | CONFIG_FEATURE_USE_TERMIOS=y | ||
178 | CONFIG_FEATURE_EDITING=y | 177 | CONFIG_FEATURE_EDITING=y |
179 | CONFIG_FEATURE_EDITING_MAX_LEN=1024 | 178 | CONFIG_FEATURE_EDITING_MAX_LEN=1024 |
180 | # CONFIG_FEATURE_EDITING_VI is not set | 179 | # CONFIG_FEATURE_EDITING_VI is not set |
@@ -391,11 +390,6 @@ CONFIG_FEATURE_VERBOSE=y | |||
391 | CONFIG_FEATURE_PRESERVE_HARDLINKS=y | 390 | CONFIG_FEATURE_PRESERVE_HARDLINKS=y |
392 | 391 | ||
393 | # | 392 | # |
394 | # Common options for ls, more and telnet | ||
395 | # | ||
396 | CONFIG_FEATURE_AUTOWIDTH=y | ||
397 | |||
398 | # | ||
399 | # Common options for df, du, ls | 393 | # Common options for df, du, ls |
400 | # | 394 | # |
401 | CONFIG_FEATURE_HUMAN_READABLE=y | 395 | CONFIG_FEATURE_HUMAN_READABLE=y |
@@ -529,7 +523,7 @@ CONFIG_FEATURE_USE_INITTAB=y | |||
529 | CONFIG_FEATURE_KILL_DELAY=0 | 523 | CONFIG_FEATURE_KILL_DELAY=0 |
530 | CONFIG_FEATURE_INIT_SCTTY=y | 524 | CONFIG_FEATURE_INIT_SCTTY=y |
531 | CONFIG_FEATURE_INIT_SYSLOG=y | 525 | CONFIG_FEATURE_INIT_SYSLOG=y |
532 | CONFIG_FEATURE_EXTRA_QUIET=y | 526 | CONFIG_FEATURE_INIT_QUIET=y |
533 | CONFIG_FEATURE_INIT_COREDUMPS=y | 527 | CONFIG_FEATURE_INIT_COREDUMPS=y |
534 | CONFIG_LINUXRC=y | 528 | CONFIG_LINUXRC=y |
535 | CONFIG_INIT_TERMINAL_TYPE="linux" | 529 | CONFIG_INIT_TERMINAL_TYPE="linux" |
@@ -603,15 +597,12 @@ CONFIG_FEATURE_MODPROBE_SMALL_CHECK_ALREADY_LOADED=y | |||
603 | # Options common to multiple modutils | 597 | # Options common to multiple modutils |
604 | # | 598 | # |
605 | # CONFIG_FEATURE_2_4_MODULES is not set | 599 | # CONFIG_FEATURE_2_4_MODULES is not set |
606 | # CONFIG_FEATURE_INSMOD_TRY_MMAP is not set | ||
607 | # CONFIG_FEATURE_INSMOD_VERSION_CHECKING is not set | 600 | # CONFIG_FEATURE_INSMOD_VERSION_CHECKING is not set |
608 | # CONFIG_FEATURE_INSMOD_KSYMOOPS_SYMBOLS is not set | 601 | # CONFIG_FEATURE_INSMOD_KSYMOOPS_SYMBOLS is not set |
609 | # CONFIG_FEATURE_INSMOD_LOADINKMEM is not set | 602 | # CONFIG_FEATURE_INSMOD_LOADINKMEM is not set |
610 | # CONFIG_FEATURE_INSMOD_LOAD_MAP is not set | 603 | # CONFIG_FEATURE_INSMOD_LOAD_MAP is not set |
611 | # CONFIG_FEATURE_INSMOD_LOAD_MAP_FULL is not set | 604 | # CONFIG_FEATURE_INSMOD_LOAD_MAP_FULL is not set |
612 | # CONFIG_FEATURE_CHECK_TAINTED_MODULE is not set | 605 | # CONFIG_FEATURE_CHECK_TAINTED_MODULE is not set |
613 | # CONFIG_FEATURE_MODUTILS_ALIAS is not set | ||
614 | # CONFIG_FEATURE_MODUTILS_SYMBOLS is not set | ||
615 | CONFIG_DEFAULT_MODULES_DIR="/lib/modules" | 606 | CONFIG_DEFAULT_MODULES_DIR="/lib/modules" |
616 | CONFIG_DEFAULT_DEPMOD_FILE="modules.dep" | 607 | CONFIG_DEFAULT_DEPMOD_FILE="modules.dep" |
617 | 608 | ||
@@ -1081,9 +1072,9 @@ CONFIG_ASH_BASH_COMPAT=y | |||
1081 | CONFIG_ASH_JOB_CONTROL=y | 1072 | CONFIG_ASH_JOB_CONTROL=y |
1082 | CONFIG_ASH_ALIAS=y | 1073 | CONFIG_ASH_ALIAS=y |
1083 | CONFIG_ASH_GETOPTS=y | 1074 | CONFIG_ASH_GETOPTS=y |
1084 | CONFIG_ASH_BUILTIN_ECHO=y | 1075 | CONFIG_ASH_ECHO=y |
1085 | CONFIG_ASH_BUILTIN_PRINTF=y | 1076 | CONFIG_ASH_PRINTF=y |
1086 | CONFIG_ASH_BUILTIN_TEST=y | 1077 | CONFIG_ASH_TEST=y |
1087 | CONFIG_ASH_HELP=y | 1078 | CONFIG_ASH_HELP=y |
1088 | CONFIG_ASH_CMDCMD=y | 1079 | CONFIG_ASH_CMDCMD=y |
1089 | # CONFIG_ASH_MAIL is not set | 1080 | # CONFIG_ASH_MAIL is not set |
diff --git a/configs/android_defconfig b/configs/android_defconfig index 30e888ac7..6ef81750e 100644 --- a/configs/android_defconfig +++ b/configs/android_defconfig | |||
@@ -112,7 +112,6 @@ CONFIG_PASSWORD_MINLEN=6 | |||
112 | CONFIG_MD5_SMALL=1 | 112 | CONFIG_MD5_SMALL=1 |
113 | # CONFIG_FEATURE_FAST_TOP is not set | 113 | # CONFIG_FEATURE_FAST_TOP is not set |
114 | # CONFIG_FEATURE_ETC_NETWORKS is not set | 114 | # CONFIG_FEATURE_ETC_NETWORKS is not set |
115 | CONFIG_FEATURE_USE_TERMIOS=y | ||
116 | # CONFIG_FEATURE_EDITING is not set | 115 | # CONFIG_FEATURE_EDITING is not set |
117 | CONFIG_FEATURE_EDITING_MAX_LEN=0 | 116 | CONFIG_FEATURE_EDITING_MAX_LEN=0 |
118 | # CONFIG_FEATURE_EDITING_VI is not set | 117 | # CONFIG_FEATURE_EDITING_VI is not set |
@@ -313,11 +312,6 @@ CONFIG_YES=y | |||
313 | CONFIG_FEATURE_PRESERVE_HARDLINKS=y | 312 | CONFIG_FEATURE_PRESERVE_HARDLINKS=y |
314 | 313 | ||
315 | # | 314 | # |
316 | # Common options for ls, more and telnet | ||
317 | # | ||
318 | CONFIG_FEATURE_AUTOWIDTH=y | ||
319 | |||
320 | # | ||
321 | # Common options for df, du, ls | 315 | # Common options for df, du, ls |
322 | # | 316 | # |
323 | CONFIG_FEATURE_HUMAN_READABLE=y | 317 | CONFIG_FEATURE_HUMAN_READABLE=y |
@@ -445,7 +439,7 @@ CONFIG_FEATURE_USE_INITTAB=y | |||
445 | CONFIG_FEATURE_KILL_DELAY=0 | 439 | CONFIG_FEATURE_KILL_DELAY=0 |
446 | CONFIG_FEATURE_INIT_SCTTY=y | 440 | CONFIG_FEATURE_INIT_SCTTY=y |
447 | CONFIG_FEATURE_INIT_SYSLOG=y | 441 | CONFIG_FEATURE_INIT_SYSLOG=y |
448 | CONFIG_FEATURE_EXTRA_QUIET=y | 442 | CONFIG_FEATURE_INIT_QUIET=y |
449 | CONFIG_FEATURE_INIT_COREDUMPS=y | 443 | CONFIG_FEATURE_INIT_COREDUMPS=y |
450 | CONFIG_LINUXRC=y | 444 | CONFIG_LINUXRC=y |
451 | CONFIG_INIT_TERMINAL_TYPE="linux" | 445 | CONFIG_INIT_TERMINAL_TYPE="linux" |
@@ -517,15 +511,12 @@ CONFIG_FEATURE_MODPROBE_SMALL_CHECK_ALREADY_LOADED=y | |||
517 | # Options common to multiple modutils | 511 | # Options common to multiple modutils |
518 | # | 512 | # |
519 | # CONFIG_FEATURE_2_4_MODULES is not set | 513 | # CONFIG_FEATURE_2_4_MODULES is not set |
520 | # CONFIG_FEATURE_INSMOD_TRY_MMAP is not set | ||
521 | # CONFIG_FEATURE_INSMOD_VERSION_CHECKING is not set | 514 | # CONFIG_FEATURE_INSMOD_VERSION_CHECKING is not set |
522 | # CONFIG_FEATURE_INSMOD_KSYMOOPS_SYMBOLS is not set | 515 | # CONFIG_FEATURE_INSMOD_KSYMOOPS_SYMBOLS is not set |
523 | # CONFIG_FEATURE_INSMOD_LOADINKMEM is not set | 516 | # CONFIG_FEATURE_INSMOD_LOADINKMEM is not set |
524 | # CONFIG_FEATURE_INSMOD_LOAD_MAP is not set | 517 | # CONFIG_FEATURE_INSMOD_LOAD_MAP is not set |
525 | # CONFIG_FEATURE_INSMOD_LOAD_MAP_FULL is not set | 518 | # CONFIG_FEATURE_INSMOD_LOAD_MAP_FULL is not set |
526 | # CONFIG_FEATURE_CHECK_TAINTED_MODULE is not set | 519 | # CONFIG_FEATURE_CHECK_TAINTED_MODULE is not set |
527 | # CONFIG_FEATURE_MODUTILS_ALIAS is not set | ||
528 | # CONFIG_FEATURE_MODUTILS_SYMBOLS is not set | ||
529 | CONFIG_DEFAULT_MODULES_DIR="/lib/modules" | 520 | CONFIG_DEFAULT_MODULES_DIR="/lib/modules" |
530 | CONFIG_DEFAULT_DEPMOD_FILE="modules.dep" | 521 | CONFIG_DEFAULT_DEPMOD_FILE="modules.dep" |
531 | 522 | ||
@@ -968,9 +959,9 @@ CONFIG_SOFTLIMIT=y | |||
968 | # CONFIG_ASH_JOB_CONTROL is not set | 959 | # CONFIG_ASH_JOB_CONTROL is not set |
969 | # CONFIG_ASH_ALIAS is not set | 960 | # CONFIG_ASH_ALIAS is not set |
970 | # CONFIG_ASH_GETOPTS is not set | 961 | # CONFIG_ASH_GETOPTS is not set |
971 | # CONFIG_ASH_BUILTIN_ECHO is not set | 962 | # CONFIG_ASH_ECHO is not set |
972 | # CONFIG_ASH_BUILTIN_PRINTF is not set | 963 | # CONFIG_ASH_PRINTF is not set |
973 | # CONFIG_ASH_BUILTIN_TEST is not set | 964 | # CONFIG_ASH_TEST is not set |
974 | # CONFIG_ASH_CMDCMD is not set | 965 | # CONFIG_ASH_CMDCMD is not set |
975 | # CONFIG_ASH_MAIL is not set | 966 | # CONFIG_ASH_MAIL is not set |
976 | # CONFIG_ASH_OPTIMIZE_FOR_SIZE is not set | 967 | # CONFIG_ASH_OPTIMIZE_FOR_SIZE is not set |
diff --git a/configs/android_ndk_defconfig b/configs/android_ndk_defconfig index 716ec9a5d..35d03b42e 100644 --- a/configs/android_ndk_defconfig +++ b/configs/android_ndk_defconfig | |||
@@ -102,7 +102,6 @@ CONFIG_MD5_SMALL=1 | |||
102 | CONFIG_SHA3_SMALL=1 | 102 | CONFIG_SHA3_SMALL=1 |
103 | # CONFIG_FEATURE_FAST_TOP is not set | 103 | # CONFIG_FEATURE_FAST_TOP is not set |
104 | # CONFIG_FEATURE_ETC_NETWORKS is not set | 104 | # CONFIG_FEATURE_ETC_NETWORKS is not set |
105 | CONFIG_FEATURE_USE_TERMIOS=y | ||
106 | # CONFIG_FEATURE_EDITING is not set | 105 | # CONFIG_FEATURE_EDITING is not set |
107 | CONFIG_FEATURE_EDITING_MAX_LEN=0 | 106 | CONFIG_FEATURE_EDITING_MAX_LEN=0 |
108 | # CONFIG_FEATURE_EDITING_VI is not set | 107 | # CONFIG_FEATURE_EDITING_VI is not set |
@@ -317,11 +316,6 @@ CONFIG_FEATURE_VERBOSE=y | |||
317 | CONFIG_FEATURE_PRESERVE_HARDLINKS=y | 316 | CONFIG_FEATURE_PRESERVE_HARDLINKS=y |
318 | 317 | ||
319 | # | 318 | # |
320 | # Common options for ls, more and telnet | ||
321 | # | ||
322 | CONFIG_FEATURE_AUTOWIDTH=y | ||
323 | |||
324 | # | ||
325 | # Common options for df, du, ls | 319 | # Common options for df, du, ls |
326 | # | 320 | # |
327 | CONFIG_FEATURE_HUMAN_READABLE=y | 321 | CONFIG_FEATURE_HUMAN_READABLE=y |
@@ -455,7 +449,7 @@ CONFIG_FEATURE_USE_INITTAB=y | |||
455 | CONFIG_FEATURE_KILL_DELAY=0 | 449 | CONFIG_FEATURE_KILL_DELAY=0 |
456 | CONFIG_FEATURE_INIT_SCTTY=y | 450 | CONFIG_FEATURE_INIT_SCTTY=y |
457 | CONFIG_FEATURE_INIT_SYSLOG=y | 451 | CONFIG_FEATURE_INIT_SYSLOG=y |
458 | CONFIG_FEATURE_EXTRA_QUIET=y | 452 | CONFIG_FEATURE_INIT_QUIET=y |
459 | CONFIG_FEATURE_INIT_COREDUMPS=y | 453 | CONFIG_FEATURE_INIT_COREDUMPS=y |
460 | CONFIG_LINUXRC=y | 454 | CONFIG_LINUXRC=y |
461 | CONFIG_INIT_TERMINAL_TYPE="linux" | 455 | CONFIG_INIT_TERMINAL_TYPE="linux" |
@@ -528,15 +522,12 @@ CONFIG_FEATURE_MODPROBE_SMALL_CHECK_ALREADY_LOADED=y | |||
528 | # Options common to multiple modutils | 522 | # Options common to multiple modutils |
529 | # | 523 | # |
530 | # CONFIG_FEATURE_2_4_MODULES is not set | 524 | # CONFIG_FEATURE_2_4_MODULES is not set |
531 | # CONFIG_FEATURE_INSMOD_TRY_MMAP is not set | ||
532 | # CONFIG_FEATURE_INSMOD_VERSION_CHECKING is not set | 525 | # CONFIG_FEATURE_INSMOD_VERSION_CHECKING is not set |
533 | # CONFIG_FEATURE_INSMOD_KSYMOOPS_SYMBOLS is not set | 526 | # CONFIG_FEATURE_INSMOD_KSYMOOPS_SYMBOLS is not set |
534 | # CONFIG_FEATURE_INSMOD_LOADINKMEM is not set | 527 | # CONFIG_FEATURE_INSMOD_LOADINKMEM is not set |
535 | # CONFIG_FEATURE_INSMOD_LOAD_MAP is not set | 528 | # CONFIG_FEATURE_INSMOD_LOAD_MAP is not set |
536 | # CONFIG_FEATURE_INSMOD_LOAD_MAP_FULL is not set | 529 | # CONFIG_FEATURE_INSMOD_LOAD_MAP_FULL is not set |
537 | # CONFIG_FEATURE_CHECK_TAINTED_MODULE is not set | 530 | # CONFIG_FEATURE_CHECK_TAINTED_MODULE is not set |
538 | # CONFIG_FEATURE_MODUTILS_ALIAS is not set | ||
539 | # CONFIG_FEATURE_MODUTILS_SYMBOLS is not set | ||
540 | CONFIG_DEFAULT_MODULES_DIR="/system/lib/modules" | 531 | CONFIG_DEFAULT_MODULES_DIR="/system/lib/modules" |
541 | CONFIG_DEFAULT_DEPMOD_FILE="modules.dep" | 532 | CONFIG_DEFAULT_DEPMOD_FILE="modules.dep" |
542 | 533 | ||
@@ -996,9 +987,9 @@ CONFIG_SOFTLIMIT=y | |||
996 | # CONFIG_ASH_JOB_CONTROL is not set | 987 | # CONFIG_ASH_JOB_CONTROL is not set |
997 | # CONFIG_ASH_ALIAS is not set | 988 | # CONFIG_ASH_ALIAS is not set |
998 | # CONFIG_ASH_GETOPTS is not set | 989 | # CONFIG_ASH_GETOPTS is not set |
999 | # CONFIG_ASH_BUILTIN_ECHO is not set | 990 | # CONFIG_ASH_ECHO is not set |
1000 | # CONFIG_ASH_BUILTIN_PRINTF is not set | 991 | # CONFIG_ASH_PRINTF is not set |
1001 | # CONFIG_ASH_BUILTIN_TEST is not set | 992 | # CONFIG_ASH_TEST is not set |
1002 | # CONFIG_ASH_HELP is not set | 993 | # CONFIG_ASH_HELP is not set |
1003 | # CONFIG_ASH_CMDCMD is not set | 994 | # CONFIG_ASH_CMDCMD is not set |
1004 | # CONFIG_ASH_MAIL is not set | 995 | # CONFIG_ASH_MAIL is not set |
diff --git a/configs/cygwin_defconfig b/configs/cygwin_defconfig index b856482f6..6bfc973ef 100644 --- a/configs/cygwin_defconfig +++ b/configs/cygwin_defconfig | |||
@@ -94,7 +94,6 @@ CONFIG_PASSWORD_MINLEN=6 | |||
94 | CONFIG_MD5_SMALL=1 | 94 | CONFIG_MD5_SMALL=1 |
95 | CONFIG_FEATURE_FAST_TOP=y | 95 | CONFIG_FEATURE_FAST_TOP=y |
96 | # CONFIG_FEATURE_ETC_NETWORKS is not set | 96 | # CONFIG_FEATURE_ETC_NETWORKS is not set |
97 | CONFIG_FEATURE_USE_TERMIOS=y | ||
98 | CONFIG_FEATURE_EDITING=y | 97 | CONFIG_FEATURE_EDITING=y |
99 | CONFIG_FEATURE_EDITING_MAX_LEN=1024 | 98 | CONFIG_FEATURE_EDITING_MAX_LEN=1024 |
100 | # CONFIG_FEATURE_EDITING_VI is not set | 99 | # CONFIG_FEATURE_EDITING_VI is not set |
@@ -290,11 +289,6 @@ CONFIG_YES=y | |||
290 | CONFIG_FEATURE_PRESERVE_HARDLINKS=y | 289 | CONFIG_FEATURE_PRESERVE_HARDLINKS=y |
291 | 290 | ||
292 | # | 291 | # |
293 | # Common options for ls, more and telnet | ||
294 | # | ||
295 | CONFIG_FEATURE_AUTOWIDTH=y | ||
296 | |||
297 | # | ||
298 | # Common options for df, du, ls | 292 | # Common options for df, du, ls |
299 | # | 293 | # |
300 | CONFIG_FEATURE_HUMAN_READABLE=y | 294 | CONFIG_FEATURE_HUMAN_READABLE=y |
@@ -422,7 +416,7 @@ CONFIG_TELINIT_PATH="" | |||
422 | CONFIG_FEATURE_KILL_DELAY=0 | 416 | CONFIG_FEATURE_KILL_DELAY=0 |
423 | # CONFIG_FEATURE_INIT_SCTTY is not set | 417 | # CONFIG_FEATURE_INIT_SCTTY is not set |
424 | # CONFIG_FEATURE_INIT_SYSLOG is not set | 418 | # CONFIG_FEATURE_INIT_SYSLOG is not set |
425 | # CONFIG_FEATURE_EXTRA_QUIET is not set | 419 | # CONFIG_FEATURE_INIT_QUIET is not set |
426 | # CONFIG_FEATURE_INIT_COREDUMPS is not set | 420 | # CONFIG_FEATURE_INIT_COREDUMPS is not set |
427 | # CONFIG_LINUXRC is not set | 421 | # CONFIG_LINUXRC is not set |
428 | CONFIG_INIT_TERMINAL_TYPE="" | 422 | CONFIG_INIT_TERMINAL_TYPE="" |
@@ -936,9 +930,9 @@ CONFIG_ASH_BASH_COMPAT=y | |||
936 | CONFIG_ASH_JOB_CONTROL=y | 930 | CONFIG_ASH_JOB_CONTROL=y |
937 | CONFIG_ASH_ALIAS=y | 931 | CONFIG_ASH_ALIAS=y |
938 | CONFIG_ASH_GETOPTS=y | 932 | CONFIG_ASH_GETOPTS=y |
939 | CONFIG_ASH_BUILTIN_ECHO=y | 933 | CONFIG_ASH_ECHO=y |
940 | CONFIG_ASH_BUILTIN_PRINTF=y | 934 | CONFIG_ASH_PRINTF=y |
941 | CONFIG_ASH_BUILTIN_TEST=y | 935 | CONFIG_ASH_TEST=y |
942 | CONFIG_ASH_CMDCMD=y | 936 | CONFIG_ASH_CMDCMD=y |
943 | # CONFIG_ASH_MAIL is not set | 937 | # CONFIG_ASH_MAIL is not set |
944 | CONFIG_ASH_OPTIMIZE_FOR_SIZE=y | 938 | CONFIG_ASH_OPTIMIZE_FOR_SIZE=y |
diff --git a/configs/freebsd_defconfig b/configs/freebsd_defconfig index 4f14d3be9..e3d04aedc 100644 --- a/configs/freebsd_defconfig +++ b/configs/freebsd_defconfig | |||
@@ -93,7 +93,6 @@ CONFIG_PASSWORD_MINLEN=6 | |||
93 | CONFIG_MD5_SMALL=1 | 93 | CONFIG_MD5_SMALL=1 |
94 | CONFIG_FEATURE_FAST_TOP=y | 94 | CONFIG_FEATURE_FAST_TOP=y |
95 | # CONFIG_FEATURE_ETC_NETWORKS is not set | 95 | # CONFIG_FEATURE_ETC_NETWORKS is not set |
96 | CONFIG_FEATURE_USE_TERMIOS=y | ||
97 | CONFIG_FEATURE_EDITING=y | 96 | CONFIG_FEATURE_EDITING=y |
98 | CONFIG_FEATURE_EDITING_MAX_LEN=1024 | 97 | CONFIG_FEATURE_EDITING_MAX_LEN=1024 |
99 | # CONFIG_FEATURE_EDITING_VI is not set | 98 | # CONFIG_FEATURE_EDITING_VI is not set |
@@ -288,11 +287,6 @@ CONFIG_YES=y | |||
288 | CONFIG_FEATURE_PRESERVE_HARDLINKS=y | 287 | CONFIG_FEATURE_PRESERVE_HARDLINKS=y |
289 | 288 | ||
290 | # | 289 | # |
291 | # Common options for ls, more and telnet | ||
292 | # | ||
293 | CONFIG_FEATURE_AUTOWIDTH=y | ||
294 | |||
295 | # | ||
296 | # Common options for df, du, ls | 290 | # Common options for df, du, ls |
297 | # | 291 | # |
298 | CONFIG_FEATURE_HUMAN_READABLE=y | 292 | CONFIG_FEATURE_HUMAN_READABLE=y |
@@ -419,7 +413,7 @@ CONFIG_TELINIT_PATH="" | |||
419 | CONFIG_FEATURE_KILL_DELAY=0 | 413 | CONFIG_FEATURE_KILL_DELAY=0 |
420 | # CONFIG_FEATURE_INIT_SCTTY is not set | 414 | # CONFIG_FEATURE_INIT_SCTTY is not set |
421 | # CONFIG_FEATURE_INIT_SYSLOG is not set | 415 | # CONFIG_FEATURE_INIT_SYSLOG is not set |
422 | # CONFIG_FEATURE_EXTRA_QUIET is not set | 416 | # CONFIG_FEATURE_INIT_QUIET is not set |
423 | # CONFIG_FEATURE_INIT_COREDUMPS is not set | 417 | # CONFIG_FEATURE_INIT_COREDUMPS is not set |
424 | # CONFIG_LINUXRC is not set | 418 | # CONFIG_LINUXRC is not set |
425 | CONFIG_INIT_TERMINAL_TYPE="" | 419 | CONFIG_INIT_TERMINAL_TYPE="" |
@@ -912,9 +906,9 @@ CONFIG_ASH=y | |||
912 | # CONFIG_ASH_JOB_CONTROL is not set | 906 | # CONFIG_ASH_JOB_CONTROL is not set |
913 | # CONFIG_ASH_ALIAS is not set | 907 | # CONFIG_ASH_ALIAS is not set |
914 | # CONFIG_ASH_GETOPTS is not set | 908 | # CONFIG_ASH_GETOPTS is not set |
915 | # CONFIG_ASH_BUILTIN_ECHO is not set | 909 | # CONFIG_ASH_ECHO is not set |
916 | # CONFIG_ASH_BUILTIN_PRINTF is not set | 910 | # CONFIG_ASH_PRINTF is not set |
917 | # CONFIG_ASH_BUILTIN_TEST is not set | 911 | # CONFIG_ASH_TEST is not set |
918 | # CONFIG_ASH_CMDCMD is not set | 912 | # CONFIG_ASH_CMDCMD is not set |
919 | # CONFIG_ASH_MAIL is not set | 913 | # CONFIG_ASH_MAIL is not set |
920 | # CONFIG_ASH_OPTIMIZE_FOR_SIZE is not set | 914 | # CONFIG_ASH_OPTIMIZE_FOR_SIZE is not set |
diff --git a/console-tools/loadfont.c b/console-tools/loadfont.c index 52605baa1..29f723ec0 100644 --- a/console-tools/loadfont.c +++ b/console-tools/loadfont.c | |||
@@ -42,18 +42,14 @@ | |||
42 | //config: depends on LOADFONT || SETFONT | 42 | //config: depends on LOADFONT || SETFONT |
43 | //config: | 43 | //config: |
44 | //config:config FEATURE_LOADFONT_PSF2 | 44 | //config:config FEATURE_LOADFONT_PSF2 |
45 | //config: bool "Support for PSF2 console fonts" | 45 | //config: bool "Support PSF2 console fonts" |
46 | //config: default y | 46 | //config: default y |
47 | //config: depends on LOADFONT || SETFONT | 47 | //config: depends on LOADFONT || SETFONT |
48 | //config: help | ||
49 | //config: Support PSF2 console fonts. | ||
50 | //config: | 48 | //config: |
51 | //config:config FEATURE_LOADFONT_RAW | 49 | //config:config FEATURE_LOADFONT_RAW |
52 | //config: bool "Support for old (raw) console fonts" | 50 | //config: bool "Support old (raw) console fonts" |
53 | //config: default y | 51 | //config: default y |
54 | //config: depends on LOADFONT || SETFONT | 52 | //config: depends on LOADFONT || SETFONT |
55 | //config: help | ||
56 | //config: Support old (raw) console fonts. | ||
57 | 53 | ||
58 | //applet:IF_LOADFONT(APPLET(loadfont, BB_DIR_USR_SBIN, BB_SUID_DROP)) | 54 | //applet:IF_LOADFONT(APPLET(loadfont, BB_DIR_USR_SBIN, BB_SUID_DROP)) |
59 | //applet:IF_SETFONT(APPLET(setfont, BB_DIR_USR_SBIN, BB_SUID_DROP)) | 55 | //applet:IF_SETFONT(APPLET(setfont, BB_DIR_USR_SBIN, BB_SUID_DROP)) |
diff --git a/console-tools/setconsole.c b/console-tools/setconsole.c index 58057268d..d47a33d59 100644 --- a/console-tools/setconsole.c +++ b/console-tools/setconsole.c | |||
@@ -19,8 +19,6 @@ | |||
19 | //config: bool "Enable long options" | 19 | //config: bool "Enable long options" |
20 | //config: default y | 20 | //config: default y |
21 | //config: depends on SETCONSOLE && LONG_OPTS | 21 | //config: depends on SETCONSOLE && LONG_OPTS |
22 | //config: help | ||
23 | //config: Support long options for the setconsole applet. | ||
24 | 22 | ||
25 | //applet:IF_SETCONSOLE(APPLET(setconsole, BB_DIR_SBIN, BB_SUID_DROP)) | 23 | //applet:IF_SETCONSOLE(APPLET(setconsole, BB_DIR_SBIN, BB_SUID_DROP)) |
26 | 24 | ||
diff --git a/coreutils/Config.src b/coreutils/Config.src index c056320f8..1d2fea1fb 100644 --- a/coreutils/Config.src +++ b/coreutils/Config.src | |||
@@ -27,25 +27,11 @@ config FEATURE_PRESERVE_HARDLINKS | |||
27 | help | 27 | help |
28 | Allow cp and mv to preserve hard links. | 28 | Allow cp and mv to preserve hard links. |
29 | 29 | ||
30 | comment "Common options for ls, more and telnet" | ||
31 | depends on LS || MORE || TELNET | ||
32 | |||
33 | config FEATURE_AUTOWIDTH | ||
34 | bool "Calculate terminal & column widths" | ||
35 | default y | ||
36 | depends on LS || MORE || TELNET | ||
37 | help | ||
38 | This option allows utilities such as 'ls', 'more' and 'telnet' | ||
39 | to determine the width of the screen, which can allow them to | ||
40 | display additional text or avoid wrapping text onto the next line. | ||
41 | If you leave this disabled, your utilities will be especially | ||
42 | primitive and will be unable to determine the current screen width. | ||
43 | |||
44 | comment "Common options for df, du, ls" | 30 | comment "Common options for df, du, ls" |
45 | depends on DF || DU || LS | 31 | depends on DF || DU || LS |
46 | 32 | ||
47 | config FEATURE_HUMAN_READABLE | 33 | config FEATURE_HUMAN_READABLE |
48 | bool "Support for human readable output (example 13k, 23M, 235G)" | 34 | bool "Support human readable output (example 13k, 23M, 235G)" |
49 | default y | 35 | default y |
50 | depends on DF || DU || LS | 36 | depends on DF || DU || LS |
51 | help | 37 | help |
diff --git a/coreutils/Kbuild.src b/coreutils/Kbuild.src index d9a448781..a805b64fe 100644 --- a/coreutils/Kbuild.src +++ b/coreutils/Kbuild.src | |||
@@ -14,12 +14,5 @@ lib-$(CONFIG_MORE) += cat.o # more uses it if stdout isn't a tty | |||
14 | lib-$(CONFIG_LESS) += cat.o # less too | 14 | lib-$(CONFIG_LESS) += cat.o # less too |
15 | lib-$(CONFIG_CRONTAB) += cat.o # crontab -l | 15 | lib-$(CONFIG_CRONTAB) += cat.o # crontab -l |
16 | lib-$(CONFIG_ADDUSER) += chown.o # used by adduser | 16 | lib-$(CONFIG_ADDUSER) += chown.o # used by adduser |
17 | lib-$(CONFIG_ADDGROUP) += chown.o # used by adduser | 17 | lib-$(CONFIG_ADDGROUP) += chown.o # used by addgroup |
18 | lib-$(CONFIG_ASH) += echo.o # used by ash | ||
19 | lib-$(CONFIG_SH_IS_ASH) += echo.o # used by ash | ||
20 | lib-$(CONFIG_BASH_IS_ASH) += echo.o # used by ash | ||
21 | lib-$(CONFIG_HUSH) += echo.o # used by hush | ||
22 | lib-$(CONFIG_SH_IS_HUSH) += echo.o # used by hush | ||
23 | lib-$(CONFIG_BASH_IS_HUSH) += echo.o # used by hush | ||
24 | lib-$(CONFIG_FTPD) += ls.o # used by ftpd | 18 | lib-$(CONFIG_FTPD) += ls.o # used by ftpd |
25 | lib-$(CONFIG_ASH_BUILTIN_PRINTF) += printf.o | ||
diff --git a/coreutils/chown.c b/coreutils/chown.c index 50b06d73a..12cd0eacc 100644 --- a/coreutils/chown.c +++ b/coreutils/chown.c | |||
@@ -17,8 +17,6 @@ | |||
17 | //config: bool "Enable long options" | 17 | //config: bool "Enable long options" |
18 | //config: default y | 18 | //config: default y |
19 | //config: depends on CHOWN && LONG_OPTS | 19 | //config: depends on CHOWN && LONG_OPTS |
20 | //config: help | ||
21 | //config: Enable use of long options | ||
22 | 20 | ||
23 | //applet:IF_CHOWN(APPLET_NOEXEC(chown, chown, BB_DIR_BIN, BB_SUID_DROP, chown)) | 21 | //applet:IF_CHOWN(APPLET_NOEXEC(chown, chown, BB_DIR_BIN, BB_SUID_DROP, chown)) |
24 | 22 | ||
diff --git a/coreutils/cp.c b/coreutils/cp.c index 4ecdaafda..1e5f36d10 100644 --- a/coreutils/cp.c +++ b/coreutils/cp.c | |||
@@ -18,11 +18,11 @@ | |||
18 | //config: cp is used to copy files and directories. | 18 | //config: cp is used to copy files and directories. |
19 | //config: | 19 | //config: |
20 | //config:config FEATURE_CP_LONG_OPTIONS | 20 | //config:config FEATURE_CP_LONG_OPTIONS |
21 | //config: bool "Enable long options for cp" | 21 | //config: bool "Enable long options" |
22 | //config: default y | 22 | //config: default y |
23 | //config: depends on CP && LONG_OPTS | 23 | //config: depends on CP && LONG_OPTS |
24 | //config: help | 24 | //config: help |
25 | //config: Enable long options for cp. | 25 | //config: Enable long options. |
26 | //config: Also add support for --parents option. | 26 | //config: Also add support for --parents option. |
27 | 27 | ||
28 | //applet:IF_CP(APPLET_NOEXEC(cp, cp, BB_DIR_BIN, BB_SUID_DROP, cp)) | 28 | //applet:IF_CP(APPLET_NOEXEC(cp, cp, BB_DIR_BIN, BB_SUID_DROP, cp)) |
diff --git a/coreutils/dd.c b/coreutils/dd.c index 8c144cfd2..85152d8ce 100644 --- a/coreutils/dd.c +++ b/coreutils/dd.c | |||
@@ -41,7 +41,7 @@ | |||
41 | //config: default y | 41 | //config: default y |
42 | //config: depends on DD | 42 | //config: depends on DD |
43 | //config: help | 43 | //config: help |
44 | //config: Enables support for writing a certain number of bytes in and out, | 44 | //config: Enable support for writing a certain number of bytes in and out, |
45 | //config: at a time, and performing conversions on the data stream. | 45 | //config: at a time, and performing conversions on the data stream. |
46 | //config: | 46 | //config: |
47 | //config:config FEATURE_DD_STATUS | 47 | //config:config FEATURE_DD_STATUS |
@@ -49,7 +49,7 @@ | |||
49 | //config: default y | 49 | //config: default y |
50 | //config: depends on DD | 50 | //config: depends on DD |
51 | //config: help | 51 | //config: help |
52 | //config: Enables support for status=noxfer/none option. | 52 | //config: Enable support for status=noxfer/none option. |
53 | 53 | ||
54 | //applet:IF_DD(APPLET_NOEXEC(dd, dd, BB_DIR_BIN, BB_SUID_DROP, dd)) | 54 | //applet:IF_DD(APPLET_NOEXEC(dd, dd, BB_DIR_BIN, BB_SUID_DROP, dd)) |
55 | 55 | ||
diff --git a/coreutils/df.c b/coreutils/df.c index 79e4c4670..cf367161a 100644 --- a/coreutils/df.c +++ b/coreutils/df.c | |||
@@ -29,11 +29,9 @@ | |||
29 | //config: default y | 29 | //config: default y |
30 | //config: depends on DF | 30 | //config: depends on DF |
31 | //config: help | 31 | //config: help |
32 | //config: This option enables -a, -i and -B. | 32 | //config: -a Show all filesystems |
33 | //config: | 33 | //config: -i Inodes |
34 | //config: -a Show all filesystems | 34 | //config: -B <SIZE> Blocksize |
35 | //config: -i Inodes | ||
36 | //config: -B <SIZE> Blocksize | ||
37 | 35 | ||
38 | //applet:IF_DF(APPLET(df, BB_DIR_BIN, BB_SUID_DROP)) | 36 | //applet:IF_DF(APPLET(df, BB_DIR_BIN, BB_SUID_DROP)) |
39 | 37 | ||
diff --git a/coreutils/echo.c b/coreutils/echo.c index fd0d9b780..a7e4ca9ac 100644 --- a/coreutils/echo.c +++ b/coreutils/echo.c | |||
@@ -26,16 +26,17 @@ | |||
26 | //config: | 26 | //config: |
27 | //config:# this entry also appears in shell/Config.in, next to the echo builtin | 27 | //config:# this entry also appears in shell/Config.in, next to the echo builtin |
28 | //config:config FEATURE_FANCY_ECHO | 28 | //config:config FEATURE_FANCY_ECHO |
29 | //config: bool "Enable echo options (-n and -e)" | 29 | //config: bool "Enable -n and -e options" |
30 | //config: default y | 30 | //config: default y |
31 | //config: depends on ECHO || ASH_BUILTIN_ECHO || HUSH | 31 | //config: depends on ECHO || ASH_ECHO || HUSH_ECHO |
32 | //config: help | ||
33 | //config: This adds options (-n and -e) to echo. | ||
34 | 32 | ||
35 | //applet:IF_ECHO(APPLET_NOFORK(echo, echo, BB_DIR_BIN, BB_SUID_DROP, echo)) | 33 | //applet:IF_ECHO(APPLET_NOFORK(echo, echo, BB_DIR_BIN, BB_SUID_DROP, echo)) |
36 | 34 | ||
37 | //kbuild:lib-$(CONFIG_ECHO) += echo.o | 35 | //kbuild:lib-$(CONFIG_ECHO) += echo.o |
38 | 36 | ||
37 | //kbuild:lib-$(CONFIG_ASH_ECHO) += echo.o | ||
38 | //kbuild:lib-$(CONFIG_HUSH_ECHO) += echo.o | ||
39 | |||
39 | /* BB_AUDIT SUSv3 compliant -- unless configured as fancy echo. */ | 40 | /* BB_AUDIT SUSv3 compliant -- unless configured as fancy echo. */ |
40 | /* http://www.opengroup.org/onlinepubs/007904975/utilities/echo.html */ | 41 | /* http://www.opengroup.org/onlinepubs/007904975/utilities/echo.html */ |
41 | 42 | ||
diff --git a/coreutils/env.c b/coreutils/env.c index e91eddb5c..2bd5f41d0 100644 --- a/coreutils/env.c +++ b/coreutils/env.c | |||
@@ -35,8 +35,6 @@ | |||
35 | //config: bool "Enable long options" | 35 | //config: bool "Enable long options" |
36 | //config: default y | 36 | //config: default y |
37 | //config: depends on ENV && LONG_OPTS | 37 | //config: depends on ENV && LONG_OPTS |
38 | //config: help | ||
39 | //config: Support long options for the env applet. | ||
40 | 38 | ||
41 | //applet:IF_ENV(APPLET_NOEXEC(env, env, BB_DIR_USR_BIN, BB_SUID_DROP, env)) | 39 | //applet:IF_ENV(APPLET_NOEXEC(env, env, BB_DIR_USR_BIN, BB_SUID_DROP, env)) |
42 | 40 | ||
diff --git a/coreutils/expand.c b/coreutils/expand.c index bb59af46d..9ce86ebff 100644 --- a/coreutils/expand.c +++ b/coreutils/expand.c | |||
@@ -8,13 +8,13 @@ | |||
8 | * David MacKenzie <djm@gnu.ai.mit.edu> | 8 | * David MacKenzie <djm@gnu.ai.mit.edu> |
9 | * | 9 | * |
10 | * Options for expand: | 10 | * Options for expand: |
11 | * -t num --tabs=NUM Convert tabs to num spaces (default 8 spaces). | 11 | * -t num --tabs NUM Convert tabs to num spaces (default 8 spaces). |
12 | * -i --initial Only convert initial tabs on each line to spaces. | 12 | * -i --initial Only convert initial tabs on each line to spaces. |
13 | * | 13 | * |
14 | * Options for unexpand: | 14 | * Options for unexpand: |
15 | * -a --all Convert all blanks, instead of just initial blanks. | 15 | * -a --all Convert all blanks, instead of just initial blanks. |
16 | * -f --first-only Convert only leading sequences of blanks (default). | 16 | * -f --first-only Convert only leading sequences of blanks (default). |
17 | * -t num --tabs=NUM Have tabs num characters apart instead of 8. | 17 | * -t num --tabs NUM Have tabs num characters apart instead of 8. |
18 | * | 18 | * |
19 | * Busybox version (C) 2007 by Tito Ragusa <farmatito@tiscali.it> | 19 | * Busybox version (C) 2007 by Tito Ragusa <farmatito@tiscali.it> |
20 | * | 20 | * |
@@ -30,8 +30,6 @@ | |||
30 | //config: bool "Enable long options" | 30 | //config: bool "Enable long options" |
31 | //config: default y | 31 | //config: default y |
32 | //config: depends on EXPAND && LONG_OPTS | 32 | //config: depends on EXPAND && LONG_OPTS |
33 | //config: help | ||
34 | //config: Support long options for the expand applet. | ||
35 | //config: | 33 | //config: |
36 | //config:config UNEXPAND | 34 | //config:config UNEXPAND |
37 | //config: bool "unexpand" | 35 | //config: bool "unexpand" |
@@ -43,10 +41,9 @@ | |||
43 | //config: bool "Enable long options" | 41 | //config: bool "Enable long options" |
44 | //config: default y | 42 | //config: default y |
45 | //config: depends on UNEXPAND && LONG_OPTS | 43 | //config: depends on UNEXPAND && LONG_OPTS |
46 | //config: help | ||
47 | //config: Support long options for the unexpand applet. | ||
48 | 44 | ||
49 | //applet:IF_EXPAND(APPLET(expand, BB_DIR_USR_BIN, BB_SUID_DROP)) | 45 | //applet:IF_EXPAND(APPLET(expand, BB_DIR_USR_BIN, BB_SUID_DROP)) |
46 | // APPLET_ODDNAME:name main location suid_type help | ||
50 | //applet:IF_UNEXPAND(APPLET_ODDNAME(unexpand, expand, BB_DIR_USR_BIN, BB_SUID_DROP, unexpand)) | 47 | //applet:IF_UNEXPAND(APPLET_ODDNAME(unexpand, expand, BB_DIR_USR_BIN, BB_SUID_DROP, unexpand)) |
51 | 48 | ||
52 | //kbuild:lib-$(CONFIG_EXPAND) += expand.o | 49 | //kbuild:lib-$(CONFIG_EXPAND) += expand.o |
@@ -58,7 +55,7 @@ | |||
58 | //usage: "Convert tabs to spaces, writing to stdout\n" | 55 | //usage: "Convert tabs to spaces, writing to stdout\n" |
59 | //usage: IF_FEATURE_EXPAND_LONG_OPTIONS( | 56 | //usage: IF_FEATURE_EXPAND_LONG_OPTIONS( |
60 | //usage: "\n -i,--initial Don't convert tabs after non blanks" | 57 | //usage: "\n -i,--initial Don't convert tabs after non blanks" |
61 | //usage: "\n -t,--tabs=N Tabstops every N chars" | 58 | //usage: "\n -t,--tabs N Tabstops every N chars" |
62 | //usage: ) | 59 | //usage: ) |
63 | //usage: IF_NOT_FEATURE_EXPAND_LONG_OPTIONS( | 60 | //usage: IF_NOT_FEATURE_EXPAND_LONG_OPTIONS( |
64 | //usage: "\n -i Don't convert tabs after non blanks" | 61 | //usage: "\n -i Don't convert tabs after non blanks" |
@@ -72,7 +69,7 @@ | |||
72 | //usage: IF_FEATURE_UNEXPAND_LONG_OPTIONS( | 69 | //usage: IF_FEATURE_UNEXPAND_LONG_OPTIONS( |
73 | //usage: "\n -a,--all Convert all blanks" | 70 | //usage: "\n -a,--all Convert all blanks" |
74 | //usage: "\n -f,--first-only Convert only leading blanks" | 71 | //usage: "\n -f,--first-only Convert only leading blanks" |
75 | //usage: "\n -t,--tabs=N Tabstops every N chars" | 72 | //usage: "\n -t,--tabs N Tabstops every N chars" |
76 | //usage: ) | 73 | //usage: ) |
77 | //usage: IF_NOT_FEATURE_UNEXPAND_LONG_OPTIONS( | 74 | //usage: IF_NOT_FEATURE_UNEXPAND_LONG_OPTIONS( |
78 | //usage: "\n -a Convert all blanks" | 75 | //usage: "\n -a Convert all blanks" |
diff --git a/coreutils/head.c b/coreutils/head.c index 176e91e3a..d49113e7f 100644 --- a/coreutils/head.c +++ b/coreutils/head.c | |||
@@ -14,11 +14,9 @@ | |||
14 | //config: from files. | 14 | //config: from files. |
15 | //config: | 15 | //config: |
16 | //config:config FEATURE_FANCY_HEAD | 16 | //config:config FEATURE_FANCY_HEAD |
17 | //config: bool "Enable head options (-c, -q, and -v)" | 17 | //config: bool "Enable -c, -q, and -v" |
18 | //config: default y | 18 | //config: default y |
19 | //config: depends on HEAD | 19 | //config: depends on HEAD |
20 | //config: help | ||
21 | //config: This enables the head options (-c, -q, and -v). | ||
22 | 20 | ||
23 | //applet:IF_HEAD(APPLET_NOEXEC(head, head, BB_DIR_USR_BIN, BB_SUID_DROP, head)) | 21 | //applet:IF_HEAD(APPLET_NOEXEC(head, head, BB_DIR_USR_BIN, BB_SUID_DROP, head)) |
24 | 22 | ||
diff --git a/coreutils/install.c b/coreutils/install.c index 831f9b802..2a642bdb6 100644 --- a/coreutils/install.c +++ b/coreutils/install.c | |||
@@ -15,8 +15,6 @@ | |||
15 | //config: bool "Enable long options" | 15 | //config: bool "Enable long options" |
16 | //config: default y | 16 | //config: default y |
17 | //config: depends on INSTALL && LONG_OPTS | 17 | //config: depends on INSTALL && LONG_OPTS |
18 | //config: help | ||
19 | //config: Support long options for the install applet. | ||
20 | 18 | ||
21 | //applet:IF_INSTALL(APPLET(install, BB_DIR_USR_BIN, BB_SUID_DROP)) | 19 | //applet:IF_INSTALL(APPLET(install, BB_DIR_USR_BIN, BB_SUID_DROP)) |
22 | 20 | ||
diff --git a/coreutils/link.c b/coreutils/link.c new file mode 100644 index 000000000..ac3ef85d9 --- /dev/null +++ b/coreutils/link.c | |||
@@ -0,0 +1,41 @@ | |||
1 | /* | ||
2 | * link implementation for busybox | ||
3 | * | ||
4 | * Copyright (C) 2017 Denys Vlasenko <vda.linux@googlemail.com> | ||
5 | * | ||
6 | * Licensed under GPLv2, see file LICENSE in this source tree. | ||
7 | */ | ||
8 | //config:config LINK | ||
9 | //config: bool "link" | ||
10 | //config: default y | ||
11 | //config: help | ||
12 | //config: link creates hard links between files. | ||
13 | |||
14 | //applet:IF_LINK(APPLET_NOFORK(link, link, BB_DIR_BIN, BB_SUID_DROP, link)) | ||
15 | |||
16 | //kbuild:lib-$(CONFIG_LINK) += link.o | ||
17 | |||
18 | //usage:#define link_trivial_usage | ||
19 | //usage: "FILE LINK" | ||
20 | //usage:#define link_full_usage "\n\n" | ||
21 | //usage: "Create hard LINK to FILE" | ||
22 | |||
23 | #include "libbb.h" | ||
24 | |||
25 | /* This is a NOFORK applet. Be very careful! */ | ||
26 | |||
27 | int link_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; | ||
28 | int link_main(int argc UNUSED_PARAM, char **argv) | ||
29 | { | ||
30 | opt_complementary = "=2"; /* exactly 2 params */ | ||
31 | getopt32(argv, ""); | ||
32 | argv += optind; | ||
33 | if (link(argv[0], argv[1]) != 0) { | ||
34 | /* shared message */ | ||
35 | bb_perror_msg_and_die("can't create %slink " | ||
36 | "%s to %s", "hard", | ||
37 | argv[1], argv[0] | ||
38 | ); | ||
39 | } | ||
40 | return EXIT_SUCCESS; | ||
41 | } | ||
diff --git a/coreutils/ls.c b/coreutils/ls.c index 0f35c70d5..6e0a52d75 100644 --- a/coreutils/ls.c +++ b/coreutils/ls.c | |||
@@ -37,22 +37,21 @@ | |||
37 | //config: bool "Enable filetyping options (-p and -F)" | 37 | //config: bool "Enable filetyping options (-p and -F)" |
38 | //config: default y | 38 | //config: default y |
39 | //config: depends on LS | 39 | //config: depends on LS |
40 | //config: help | ||
41 | //config: Enable the ls options (-p and -F). | ||
42 | //config: | 40 | //config: |
43 | //config:config FEATURE_LS_FOLLOWLINKS | 41 | //config:config FEATURE_LS_FOLLOWLINKS |
44 | //config: bool "Enable symlinks dereferencing (-L)" | 42 | //config: bool "Enable symlinks dereferencing (-L)" |
45 | //config: default y | 43 | //config: default y |
46 | //config: depends on LS | 44 | //config: depends on LS |
47 | //config: help | ||
48 | //config: Enable the ls option (-L). | ||
49 | //config: | 45 | //config: |
50 | //config:config FEATURE_LS_RECURSIVE | 46 | //config:config FEATURE_LS_RECURSIVE |
51 | //config: bool "Enable recursion (-R)" | 47 | //config: bool "Enable recursion (-R)" |
52 | //config: default y | 48 | //config: default y |
53 | //config: depends on LS | 49 | //config: depends on LS |
54 | //config: help | 50 | //config: |
55 | //config: Enable the ls option (-R). | 51 | //config:config FEATURE_LS_WIDTH |
52 | //config: bool "Enable -w WIDTH and window size autodetection" | ||
53 | //config: default y | ||
54 | //config: depends on LS | ||
56 | //config: | 55 | //config: |
57 | //config:config FEATURE_LS_SORTFILES | 56 | //config:config FEATURE_LS_SORTFILES |
58 | //config: bool "Sort the file names" | 57 | //config: bool "Sort the file names" |
@@ -102,18 +101,17 @@ | |||
102 | //usage: IF_FEATURE_LS_FOLLOWLINKS("LH") | 101 | //usage: IF_FEATURE_LS_FOLLOWLINKS("LH") |
103 | //usage: IF_FEATURE_LS_RECURSIVE("R") | 102 | //usage: IF_FEATURE_LS_RECURSIVE("R") |
104 | //usage: IF_FEATURE_LS_FILETYPES("Fp") "lins" | 103 | //usage: IF_FEATURE_LS_FILETYPES("Fp") "lins" |
105 | //usage: IF_FEATURE_LS_TIMESTAMPS("e") | ||
106 | //usage: IF_FEATURE_HUMAN_READABLE("h") | 104 | //usage: IF_FEATURE_HUMAN_READABLE("h") |
107 | //usage: IF_FEATURE_LS_SORTFILES("rSXv") | 105 | //usage: IF_FEATURE_LS_SORTFILES("rSXv") |
108 | //usage: IF_FEATURE_LS_TIMESTAMPS("ctu") | 106 | //usage: IF_FEATURE_LS_TIMESTAMPS("ctu") |
109 | //usage: IF_SELINUX("kKZ") "]" | 107 | //usage: IF_SELINUX("kZ") "]" |
110 | //usage: IF_FEATURE_AUTOWIDTH(" [-w WIDTH]") " [FILE]..." | 108 | //usage: IF_FEATURE_LS_WIDTH(" [-w WIDTH]") " [FILE]..." |
111 | //usage:#define ls_full_usage "\n\n" | 109 | //usage:#define ls_full_usage "\n\n" |
112 | //usage: "List directory contents\n" | 110 | //usage: "List directory contents\n" |
113 | //usage: "\n -1 One column output" | 111 | //usage: "\n -1 One column output" |
114 | //usage: "\n -a Include entries which start with ." | 112 | //usage: "\n -a Include entries which start with ." |
115 | //usage: "\n -A Like -a, but exclude . and .." | 113 | //usage: "\n -A Like -a, but exclude . and .." |
116 | //usage: "\n -C List by columns" | 114 | ////usage: "\n -C List by columns" - don't show, this is a default anyway |
117 | //usage: "\n -x List by lines" | 115 | //usage: "\n -x List by lines" |
118 | //usage: "\n -d List directory entries instead of contents" | 116 | //usage: "\n -d List directory entries instead of contents" |
119 | //usage: IF_FEATURE_LS_FOLLOWLINKS( | 117 | //usage: IF_FEATURE_LS_FOLLOWLINKS( |
@@ -132,29 +130,34 @@ | |||
132 | //usage: "\n -n List numeric UIDs and GIDs instead of names" | 130 | //usage: "\n -n List numeric UIDs and GIDs instead of names" |
133 | //usage: "\n -s List allocated blocks" | 131 | //usage: "\n -s List allocated blocks" |
134 | //usage: IF_FEATURE_LS_TIMESTAMPS( | 132 | //usage: IF_FEATURE_LS_TIMESTAMPS( |
135 | //usage: "\n -e List full date and time" | 133 | //usage: "\n -lc List ctime" |
134 | //usage: "\n -lu List atime" | ||
136 | //usage: ) | 135 | //usage: ) |
136 | //usage: IF_FEATURE_LS_TIMESTAMPS(IF_LONG_OPTS( | ||
137 | //usage: "\n --full-time List full date and time" | ||
138 | //usage: )) | ||
137 | //usage: IF_FEATURE_HUMAN_READABLE( | 139 | //usage: IF_FEATURE_HUMAN_READABLE( |
138 | //usage: "\n -h List sizes in human readable format (1K 243M 2G)" | 140 | //usage: "\n -h Human readable sizes (1K 243M 2G)" |
139 | //usage: ) | 141 | //usage: ) |
140 | //usage: IF_FEATURE_LS_SORTFILES( | 142 | //usage: IF_FEATURE_LS_SORTFILES( |
141 | //usage: "\n -r Sort in reverse order" | 143 | //usage: IF_LONG_OPTS( |
144 | //usage: "\n --group-directories-first" | ||
145 | //usage: ) | ||
142 | //usage: "\n -S Sort by size" | 146 | //usage: "\n -S Sort by size" |
143 | //usage: "\n -X Sort by extension" | 147 | //usage: "\n -X Sort by extension" |
144 | //usage: "\n -v Sort by version" | 148 | //usage: "\n -v Sort by version" |
145 | //usage: ) | 149 | //usage: ) |
146 | //usage: IF_FEATURE_LS_TIMESTAMPS( | 150 | //usage: IF_FEATURE_LS_TIMESTAMPS( |
147 | //usage: "\n -c With -l: sort by ctime" | 151 | //usage: "\n -t Sort by mtime" |
148 | //usage: "\n -t With -l: sort by mtime" | 152 | //usage: "\n -tc Sort by ctime" |
149 | //usage: "\n -u With -l: sort by atime" | 153 | //usage: "\n -tu Sort by atime" |
150 | //usage: ) | 154 | //usage: ) |
155 | //usage: "\n -r Reverse sort order" | ||
151 | //usage: IF_SELINUX( | 156 | //usage: IF_SELINUX( |
152 | //usage: "\n -k List security context" | ||
153 | //usage: "\n -K List security context in long format" | ||
154 | //usage: "\n -Z List security context and permission" | 157 | //usage: "\n -Z List security context and permission" |
155 | //usage: ) | 158 | //usage: ) |
156 | //usage: IF_FEATURE_AUTOWIDTH( | 159 | //usage: IF_FEATURE_LS_WIDTH( |
157 | //usage: "\n -w N Assume the terminal is N columns wide" | 160 | //usage: "\n -w N Format N columns wide" |
158 | //usage: ) | 161 | //usage: ) |
159 | //usage: IF_FEATURE_LS_COLOR( | 162 | //usage: IF_FEATURE_LS_COLOR( |
160 | //usage: "\n --color[={always,never,auto}] Control coloring" | 163 | //usage: "\n --color[={always,never,auto}] Control coloring" |
@@ -189,187 +192,90 @@ TERMINAL_WIDTH = 80, /* use 79 if terminal has linefold bug */ | |||
189 | SPLIT_FILE = 0, | 192 | SPLIT_FILE = 0, |
190 | SPLIT_DIR = 1, | 193 | SPLIT_DIR = 1, |
191 | SPLIT_SUBDIR = 2, | 194 | SPLIT_SUBDIR = 2, |
192 | |||
193 | /* Bits in G.all_fmt: */ | ||
194 | |||
195 | /* 51306 lrwxrwxrwx 1 root root 2 May 11 01:43 /bin/view -> vi* */ | ||
196 | /* what file information will be listed */ | ||
197 | LIST_INO = 1 << 0, | ||
198 | LIST_BLOCKS = 1 << 1, | ||
199 | LIST_MODEBITS = 1 << 2, | ||
200 | LIST_NLINKS = 1 << 3, | ||
201 | LIST_ID_NAME = 1 << 4, | ||
202 | LIST_ID_NUMERIC = 1 << 5, | ||
203 | LIST_CONTEXT = 1 << 6, | ||
204 | LIST_SIZE = 1 << 7, | ||
205 | LIST_DATE_TIME = 1 << 8, | ||
206 | LIST_FULLTIME = 1 << 9, | ||
207 | LIST_SYMLINK = 1 << 10, | ||
208 | LIST_FILETYPE = 1 << 11, /* show / suffix for dirs */ | ||
209 | LIST_CLASSIFY = 1 << 12, /* requires LIST_FILETYPE, also show *,|,@,= suffixes */ | ||
210 | LIST_MASK = (LIST_CLASSIFY << 1) - 1, | ||
211 | |||
212 | /* what files will be displayed */ | ||
213 | DISP_DIRNAME = 1 << 13, /* 2 or more items? label directories */ | ||
214 | DISP_HIDDEN = 1 << 14, /* show filenames starting with . */ | ||
215 | DISP_DOT = 1 << 15, /* show . and .. */ | ||
216 | DISP_NOLIST = 1 << 16, /* show directory as itself, not contents */ | ||
217 | DISP_RECURSIVE = 1 << 17, /* show directory and everything below it */ | ||
218 | DISP_ROWS = 1 << 18, /* print across rows */ | ||
219 | DISP_MASK = ((DISP_ROWS << 1) - 1) & ~(DISP_DIRNAME - 1), | ||
220 | |||
221 | /* what is the overall style of the listing */ | ||
222 | STYLE_COLUMNAR = 1 << 19, /* many records per line */ | ||
223 | STYLE_LONG = 2 << 19, /* one record per line, extended info */ | ||
224 | STYLE_SINGLE = 3 << 19, /* one record per line */ | ||
225 | STYLE_MASK = STYLE_SINGLE, | ||
226 | |||
227 | /* which of the three times will be used */ | ||
228 | TIME_CHANGE = (1 << 21) * ENABLE_FEATURE_LS_TIMESTAMPS, | ||
229 | TIME_ACCESS = (2 << 21) * ENABLE_FEATURE_LS_TIMESTAMPS, | ||
230 | TIME_MASK = (3 << 21) * ENABLE_FEATURE_LS_TIMESTAMPS, | ||
231 | |||
232 | /* how will the files be sorted (CONFIG_FEATURE_LS_SORTFILES) */ | ||
233 | SORT_REVERSE = 1 << 23, | ||
234 | |||
235 | SORT_NAME = 0, /* sort by file name */ | ||
236 | SORT_SIZE = 1 << 24, /* sort by file size */ | ||
237 | SORT_ATIME = 2 << 24, /* sort by last access time */ | ||
238 | SORT_CTIME = 3 << 24, /* sort by last change time */ | ||
239 | SORT_MTIME = 4 << 24, /* sort by last modification time */ | ||
240 | SORT_VERSION = 5 << 24, /* sort by version */ | ||
241 | SORT_EXT = 6 << 24, /* sort by file name extension */ | ||
242 | SORT_DIR = 7 << 24, /* sort by file or directory */ | ||
243 | SORT_MASK = (7 << 24) * ENABLE_FEATURE_LS_SORTFILES, | ||
244 | |||
245 | LIST_LONG = LIST_MODEBITS | LIST_NLINKS | LIST_ID_NAME | LIST_SIZE | \ | ||
246 | LIST_DATE_TIME | LIST_SYMLINK, | ||
247 | }; | 195 | }; |
248 | 196 | ||
249 | /* -Cadil1 Std options, busybox always supports */ | 197 | /* -Cadi1l Std options, busybox always supports */ |
250 | /* -gnsxA Std options, busybox always supports */ | 198 | /* -gnsxA Std options, busybox always supports */ |
251 | /* -Q GNU option, busybox always supports */ | 199 | /* -Q GNU option, busybox always supports */ |
252 | /* -k SELinux option, busybox always supports (ignores if !SELinux) */ | 200 | /* -k Std option, busybox always supports (by ignoring) */ |
253 | /* Std has -k which means "show sizes in kbytes" */ | 201 | /* It means "for -s, show sizes in kbytes" */ |
202 | /* Seems to only affect "POSIXLY_CORRECT=1 ls -sk" */ | ||
203 | /* since otherwise -s shows kbytes anyway */ | ||
254 | /* -LHRctur Std options, busybox optionally supports */ | 204 | /* -LHRctur Std options, busybox optionally supports */ |
255 | /* -Fp Std options, busybox optionally supports */ | 205 | /* -Fp Std options, busybox optionally supports */ |
256 | /* -SXvhTw GNU options, busybox optionally supports */ | 206 | /* -SXvhTw GNU options, busybox optionally supports */ |
257 | /* -T WIDTH Ignored (we don't use tabs on output) */ | 207 | /* -T WIDTH Ignored (we don't use tabs on output) */ |
258 | /* -KZ SELinux mandated options, busybox optionally supports */ | 208 | /* -Z SELinux mandated option, busybox optionally supports */ |
259 | /* (coreutils 8.4 has no -K, remove it?) */ | ||
260 | /* -e I think we made this one up (looks similar to GNU --full-time) */ | ||
261 | /* We already used up all 32 bits, if we need to add more, candidates for removal: */ | ||
262 | /* -K, -T, -e (add --full-time instead) */ | ||
263 | static const char ls_options[] ALIGN1 = | 209 | static const char ls_options[] ALIGN1 = |
264 | "Cadil1gnsxQAk" /* 13 opts, total 13 */ | 210 | "Cadi1lgnsxAk" /* 12 opts, total 12 */ |
265 | IF_FEATURE_LS_TIMESTAMPS("cetu") /* 4, 17 */ | 211 | IF_FEATURE_LS_FILETYPES("Fp") /* 2, 14 */ |
266 | IF_FEATURE_LS_SORTFILES("SXrv") /* 4, 21 */ | 212 | IF_FEATURE_LS_RECURSIVE("R") /* 1, 15 */ |
267 | IF_FEATURE_LS_FILETYPES("Fp") /* 2, 23 */ | 213 | IF_SELINUX("Z") /* 1, 16 */ |
268 | IF_FEATURE_LS_RECURSIVE("R") /* 1, 24 */ | 214 | "Q" /* 1, 17 */ |
269 | IF_SELINUX("KZ") /* 2, 26 */ | 215 | IF_FEATURE_LS_TIMESTAMPS("ctu") /* 3, 20 */ |
270 | IF_FEATURE_LS_FOLLOWLINKS("LH") /* 2, 28 */ | 216 | IF_FEATURE_LS_SORTFILES("SXrv") /* 4, 24 */ |
271 | IF_FEATURE_HUMAN_READABLE("h") /* 1, 29 */ | 217 | IF_FEATURE_LS_FOLLOWLINKS("LH") /* 2, 26 */ |
272 | IF_FEATURE_AUTOWIDTH("T:w:") /* 2, 31 */ | 218 | IF_FEATURE_HUMAN_READABLE("h") /* 1, 27 */ |
273 | /* with --color, we use all 32 bits */; | 219 | IF_FEATURE_LS_WIDTH("T:w:") /* 2, 29 */ |
220 | ; | ||
274 | enum { | 221 | enum { |
275 | //OPT_C = (1 << 0), | 222 | OPT_C = (1 << 0), |
276 | //OPT_a = (1 << 1), | 223 | OPT_a = (1 << 1), |
277 | //OPT_d = (1 << 2), | 224 | OPT_d = (1 << 2), |
278 | //OPT_i = (1 << 3), | 225 | OPT_i = (1 << 3), |
279 | //OPT_l = (1 << 4), | 226 | OPT_1 = (1 << 4), |
280 | //OPT_1 = (1 << 5), | 227 | OPT_l = (1 << 5), |
281 | OPT_g = (1 << 6), | 228 | OPT_g = (1 << 6), |
282 | //OPT_n = (1 << 7), | 229 | OPT_n = (1 << 7), |
283 | //OPT_s = (1 << 8), | 230 | OPT_s = (1 << 8), |
284 | //OPT_x = (1 << 9), | 231 | OPT_x = (1 << 9), |
285 | OPT_Q = (1 << 10), | 232 | OPT_A = (1 << 10), |
286 | //OPT_A = (1 << 11), | 233 | //OPT_k = (1 << 11), |
287 | //OPT_k = (1 << 12), | 234 | |
288 | 235 | OPTBIT_F = 12, | |
289 | OPTBIT_c = 13, | 236 | OPTBIT_p, /* 13 */ |
290 | OPTBIT_e, | ||
291 | OPTBIT_t, | ||
292 | OPTBIT_u, | ||
293 | OPTBIT_S = OPTBIT_c + 4 * ENABLE_FEATURE_LS_TIMESTAMPS, | ||
294 | OPTBIT_X, /* 18 */ | ||
295 | OPTBIT_r, | ||
296 | OPTBIT_v, | ||
297 | OPTBIT_F = OPTBIT_S + 4 * ENABLE_FEATURE_LS_SORTFILES, | ||
298 | OPTBIT_p, /* 22 */ | ||
299 | OPTBIT_R = OPTBIT_F + 2 * ENABLE_FEATURE_LS_FILETYPES, | 237 | OPTBIT_R = OPTBIT_F + 2 * ENABLE_FEATURE_LS_FILETYPES, |
300 | OPTBIT_K = OPTBIT_R + 1 * ENABLE_FEATURE_LS_RECURSIVE, | 238 | OPTBIT_Z = OPTBIT_R + 1 * ENABLE_FEATURE_LS_RECURSIVE, |
301 | OPTBIT_Z, /* 25 */ | 239 | OPTBIT_Q = OPTBIT_Z + 1 * ENABLE_SELINUX, |
302 | OPTBIT_L = OPTBIT_K + 2 * ENABLE_SELINUX, | 240 | OPTBIT_c, /* 17 */ |
303 | OPTBIT_H, /* 27 */ | 241 | OPTBIT_t, /* 18 */ |
242 | OPTBIT_u, /* 19 */ | ||
243 | OPTBIT_S = OPTBIT_c + 3 * ENABLE_FEATURE_LS_TIMESTAMPS, | ||
244 | OPTBIT_X, /* 21 */ | ||
245 | OPTBIT_r, /* 22 */ | ||
246 | OPTBIT_v, /* 23 */ | ||
247 | OPTBIT_L = OPTBIT_S + 4 * ENABLE_FEATURE_LS_SORTFILES, | ||
248 | OPTBIT_H, /* 25 */ | ||
304 | OPTBIT_h = OPTBIT_L + 2 * ENABLE_FEATURE_LS_FOLLOWLINKS, | 249 | OPTBIT_h = OPTBIT_L + 2 * ENABLE_FEATURE_LS_FOLLOWLINKS, |
305 | OPTBIT_T = OPTBIT_h + 1 * ENABLE_FEATURE_HUMAN_READABLE, | 250 | OPTBIT_T = OPTBIT_h + 1 * ENABLE_FEATURE_HUMAN_READABLE, |
306 | OPTBIT_w, /* 30 */ | 251 | OPTBIT_w, /* 28 */ |
307 | OPTBIT_color = OPTBIT_T + 2 * ENABLE_FEATURE_AUTOWIDTH, | 252 | OPTBIT_full_time = OPTBIT_T + 2 * ENABLE_FEATURE_LS_WIDTH, |
253 | OPTBIT_dirs_first, | ||
254 | OPTBIT_color, /* 31 */ | ||
255 | /* with long opts, we use all 32 bits */ | ||
308 | 256 | ||
257 | OPT_F = (1 << OPTBIT_F) * ENABLE_FEATURE_LS_FILETYPES, | ||
258 | OPT_p = (1 << OPTBIT_p) * ENABLE_FEATURE_LS_FILETYPES, | ||
259 | OPT_R = (1 << OPTBIT_R) * ENABLE_FEATURE_LS_RECURSIVE, | ||
260 | OPT_Z = (1 << OPTBIT_Z) * ENABLE_SELINUX, | ||
261 | OPT_Q = (1 << OPTBIT_Q), | ||
309 | OPT_c = (1 << OPTBIT_c) * ENABLE_FEATURE_LS_TIMESTAMPS, | 262 | OPT_c = (1 << OPTBIT_c) * ENABLE_FEATURE_LS_TIMESTAMPS, |
310 | OPT_e = (1 << OPTBIT_e) * ENABLE_FEATURE_LS_TIMESTAMPS, | ||
311 | OPT_t = (1 << OPTBIT_t) * ENABLE_FEATURE_LS_TIMESTAMPS, | 263 | OPT_t = (1 << OPTBIT_t) * ENABLE_FEATURE_LS_TIMESTAMPS, |
312 | OPT_u = (1 << OPTBIT_u) * ENABLE_FEATURE_LS_TIMESTAMPS, | 264 | OPT_u = (1 << OPTBIT_u) * ENABLE_FEATURE_LS_TIMESTAMPS, |
313 | OPT_S = (1 << OPTBIT_S) * ENABLE_FEATURE_LS_SORTFILES, | 265 | OPT_S = (1 << OPTBIT_S) * ENABLE_FEATURE_LS_SORTFILES, |
314 | OPT_X = (1 << OPTBIT_X) * ENABLE_FEATURE_LS_SORTFILES, | 266 | OPT_X = (1 << OPTBIT_X) * ENABLE_FEATURE_LS_SORTFILES, |
315 | OPT_r = (1 << OPTBIT_r) * ENABLE_FEATURE_LS_SORTFILES, | 267 | OPT_r = (1 << OPTBIT_r) * ENABLE_FEATURE_LS_SORTFILES, |
316 | OPT_v = (1 << OPTBIT_v) * ENABLE_FEATURE_LS_SORTFILES, | 268 | OPT_v = (1 << OPTBIT_v) * ENABLE_FEATURE_LS_SORTFILES, |
317 | OPT_F = (1 << OPTBIT_F) * ENABLE_FEATURE_LS_FILETYPES, | ||
318 | OPT_p = (1 << OPTBIT_p) * ENABLE_FEATURE_LS_FILETYPES, | ||
319 | OPT_R = (1 << OPTBIT_R) * ENABLE_FEATURE_LS_RECURSIVE, | ||
320 | OPT_K = (1 << OPTBIT_K) * ENABLE_SELINUX, | ||
321 | OPT_Z = (1 << OPTBIT_Z) * ENABLE_SELINUX, | ||
322 | OPT_L = (1 << OPTBIT_L) * ENABLE_FEATURE_LS_FOLLOWLINKS, | 269 | OPT_L = (1 << OPTBIT_L) * ENABLE_FEATURE_LS_FOLLOWLINKS, |
323 | OPT_H = (1 << OPTBIT_H) * ENABLE_FEATURE_LS_FOLLOWLINKS, | 270 | OPT_H = (1 << OPTBIT_H) * ENABLE_FEATURE_LS_FOLLOWLINKS, |
324 | OPT_h = (1 << OPTBIT_h) * ENABLE_FEATURE_HUMAN_READABLE, | 271 | OPT_h = (1 << OPTBIT_h) * ENABLE_FEATURE_HUMAN_READABLE, |
325 | OPT_T = (1 << OPTBIT_T) * ENABLE_FEATURE_AUTOWIDTH, | 272 | OPT_T = (1 << OPTBIT_T) * ENABLE_FEATURE_LS_WIDTH, |
326 | OPT_w = (1 << OPTBIT_w) * ENABLE_FEATURE_AUTOWIDTH, | 273 | OPT_w = (1 << OPTBIT_w) * ENABLE_FEATURE_LS_WIDTH, |
327 | OPT_color = (1 << OPTBIT_color) * ENABLE_FEATURE_LS_COLOR, | 274 | OPT_full_time = (1 << OPTBIT_full_time ) * ENABLE_LONG_OPTS, |
328 | }; | 275 | OPT_dirs_first = (1 << OPTBIT_dirs_first) * ENABLE_LONG_OPTS, |
329 | 276 | OPT_color = (1 << OPTBIT_color ) * ENABLE_FEATURE_LS_COLOR, | |
330 | /* TODO: simple toggles may be stored as OPT_xxx bits instead */ | ||
331 | static const uint32_t opt_flags[] = { | ||
332 | STYLE_COLUMNAR, /* C */ | ||
333 | DISP_HIDDEN | DISP_DOT, /* a */ | ||
334 | DISP_NOLIST, /* d */ | ||
335 | LIST_INO, /* i */ | ||
336 | LIST_LONG | STYLE_LONG, /* l */ | ||
337 | STYLE_SINGLE, /* 1 */ | ||
338 | LIST_LONG | STYLE_LONG, /* g (don't show owner) - handled via OPT_g. assumes l */ | ||
339 | LIST_ID_NUMERIC | LIST_LONG | STYLE_LONG, /* n (assumes l) */ | ||
340 | LIST_BLOCKS, /* s */ | ||
341 | DISP_ROWS | STYLE_COLUMNAR, /* x */ | ||
342 | 0, /* Q (quote filename) - handled via OPT_Q */ | ||
343 | DISP_HIDDEN, /* A */ | ||
344 | ENABLE_SELINUX * (LIST_CONTEXT|STYLE_SINGLE), /* k (ignored if !SELINUX) */ | ||
345 | #if ENABLE_FEATURE_LS_TIMESTAMPS | ||
346 | TIME_CHANGE | (ENABLE_FEATURE_LS_SORTFILES * SORT_CTIME), /* c */ | ||
347 | LIST_FULLTIME, /* e */ | ||
348 | ENABLE_FEATURE_LS_SORTFILES * SORT_MTIME, /* t */ | ||
349 | TIME_ACCESS | (ENABLE_FEATURE_LS_SORTFILES * SORT_ATIME), /* u */ | ||
350 | #endif | ||
351 | #if ENABLE_FEATURE_LS_SORTFILES | ||
352 | SORT_SIZE, /* S */ | ||
353 | SORT_EXT, /* X */ | ||
354 | SORT_REVERSE, /* r */ | ||
355 | SORT_VERSION, /* v */ | ||
356 | #endif | ||
357 | #if ENABLE_FEATURE_LS_FILETYPES | ||
358 | LIST_FILETYPE | LIST_CLASSIFY, /* F */ | ||
359 | LIST_FILETYPE, /* p */ | ||
360 | #endif | ||
361 | #if ENABLE_FEATURE_LS_RECURSIVE | ||
362 | DISP_RECURSIVE, /* R */ | ||
363 | #endif | ||
364 | #if ENABLE_SELINUX | ||
365 | LIST_MODEBITS|LIST_NLINKS|LIST_CONTEXT|LIST_SIZE|LIST_DATE_TIME|STYLE_SINGLE, /* K */ | ||
366 | LIST_MODEBITS|LIST_ID_NAME|LIST_CONTEXT|STYLE_SINGLE, /* Z */ | ||
367 | #endif | ||
368 | (1U << 31) | ||
369 | /* options after Z are not processed through opt_flags */ | ||
370 | }; | 277 | }; |
371 | 278 | ||
372 | |||
373 | /* | 279 | /* |
374 | * a directory entry and its stat info | 280 | * a directory entry and its stat info |
375 | */ | 281 | */ |
@@ -399,9 +305,7 @@ struct dnode { | |||
399 | mode_t dn_mode; /* obtained with lstat OR stat, depending on -L etc */ | 305 | mode_t dn_mode; /* obtained with lstat OR stat, depending on -L etc */ |
400 | off_t dn_size; | 306 | off_t dn_size; |
401 | #if ENABLE_FEATURE_LS_TIMESTAMPS || ENABLE_FEATURE_LS_SORTFILES | 307 | #if ENABLE_FEATURE_LS_TIMESTAMPS || ENABLE_FEATURE_LS_SORTFILES |
402 | time_t dn_atime; | 308 | time_t dn_time; |
403 | time_t dn_mtime; | ||
404 | time_t dn_ctime; | ||
405 | #endif | 309 | #endif |
406 | ino_t dn_ino; | 310 | ino_t dn_ino; |
407 | blkcnt_t dn_blocks; | 311 | blkcnt_t dn_blocks; |
@@ -422,8 +326,8 @@ struct globals { | |||
422 | # define G_show_color 0 | 326 | # define G_show_color 0 |
423 | #endif | 327 | #endif |
424 | smallint exit_code; | 328 | smallint exit_code; |
425 | unsigned all_fmt; | 329 | smallint show_dirname; |
426 | #if ENABLE_FEATURE_AUTOWIDTH | 330 | #if ENABLE_FEATURE_LS_WIDTH |
427 | unsigned terminal_width; | 331 | unsigned terminal_width; |
428 | # define G_terminal_width (G.terminal_width) | 332 | # define G_terminal_width (G.terminal_width) |
429 | #else | 333 | #else |
@@ -439,7 +343,7 @@ struct globals { | |||
439 | setup_common_bufsiz(); \ | 343 | setup_common_bufsiz(); \ |
440 | /* we have to zero it out because of NOEXEC */ \ | 344 | /* we have to zero it out because of NOEXEC */ \ |
441 | memset(&G, 0, sizeof(G)); \ | 345 | memset(&G, 0, sizeof(G)); \ |
442 | IF_FEATURE_AUTOWIDTH(G_terminal_width = TERMINAL_WIDTH;) \ | 346 | IF_FEATURE_LS_WIDTH(G_terminal_width = TERMINAL_WIDTH;) \ |
443 | IF_FEATURE_LS_TIMESTAMPS(time(&G.current_time_t);) \ | 347 | IF_FEATURE_LS_TIMESTAMPS(time(&G.current_time_t);) \ |
444 | } while (0) | 348 | } while (0) |
445 | 349 | ||
@@ -496,11 +400,12 @@ static char bold(mode_t mode) | |||
496 | #if ENABLE_FEATURE_LS_FILETYPES | 400 | #if ENABLE_FEATURE_LS_FILETYPES |
497 | static char append_char(mode_t mode) | 401 | static char append_char(mode_t mode) |
498 | { | 402 | { |
499 | if (!(G.all_fmt & LIST_FILETYPE)) | 403 | if (!(option_mask32 & (OPT_F|OPT_p))) |
500 | return '\0'; | 404 | return '\0'; |
405 | |||
501 | if (S_ISDIR(mode)) | 406 | if (S_ISDIR(mode)) |
502 | return '/'; | 407 | return '/'; |
503 | if (!(G.all_fmt & LIST_CLASSIFY)) | 408 | if (!(option_mask32 & OPT_F)) |
504 | return '\0'; | 409 | return '\0'; |
505 | if (S_ISREG(mode) && (mode & (S_IXUSR | S_IXGRP | S_IXOTH))) | 410 | if (S_ISREG(mode) && (mode & (S_IXUSR | S_IXGRP | S_IXOTH))) |
506 | return '*'; | 411 | return '*'; |
@@ -531,8 +436,8 @@ static unsigned calc_name_len(const char *name) | |||
531 | } | 436 | } |
532 | 437 | ||
533 | /* Return the number of used columns. | 438 | /* Return the number of used columns. |
534 | * Note that only STYLE_COLUMNAR uses return value. | 439 | * Note that only columnar output uses return value. |
535 | * STYLE_SINGLE and STYLE_LONG don't care. | 440 | * -l and -1 modes don't care. |
536 | * coreutils 7.2 also supports: | 441 | * coreutils 7.2 also supports: |
537 | * ls -b (--escape) = octal escapes (although it doesn't look like working) | 442 | * ls -b (--escape) = octal escapes (although it doesn't look like working) |
538 | * ls -N (--literal) = not escape at all | 443 | * ls -N (--literal) = not escape at all |
@@ -565,13 +470,14 @@ static unsigned print_name(const char *name) | |||
565 | } | 470 | } |
566 | 471 | ||
567 | /* Return the number of used columns. | 472 | /* Return the number of used columns. |
568 | * Note that only STYLE_COLUMNAR uses return value, | 473 | * Note that only columnar output uses return value, |
569 | * STYLE_SINGLE and STYLE_LONG don't care. | 474 | * -l and -1 modes don't care. |
570 | */ | 475 | */ |
571 | static NOINLINE unsigned display_single(const struct dnode *dn) | 476 | static NOINLINE unsigned display_single(const struct dnode *dn) |
572 | { | 477 | { |
573 | unsigned column = 0; | 478 | unsigned column = 0; |
574 | char *lpath; | 479 | char *lpath; |
480 | int opt; | ||
575 | #if ENABLE_FEATURE_LS_FILETYPES || ENABLE_FEATURE_LS_COLOR | 481 | #if ENABLE_FEATURE_LS_FILETYPES || ENABLE_FEATURE_LS_COLOR |
576 | struct stat statbuf; | 482 | struct stat statbuf; |
577 | char append; | 483 | char append; |
@@ -580,50 +486,61 @@ static NOINLINE unsigned display_single(const struct dnode *dn) | |||
580 | #if ENABLE_FEATURE_LS_FILETYPES | 486 | #if ENABLE_FEATURE_LS_FILETYPES |
581 | append = append_char(dn->dn_mode); | 487 | append = append_char(dn->dn_mode); |
582 | #endif | 488 | #endif |
489 | opt = option_mask32; | ||
583 | 490 | ||
584 | /* Do readlink early, so that if it fails, error message | 491 | /* Do readlink early, so that if it fails, error message |
585 | * does not appear *inside* the "ls -l" line */ | 492 | * does not appear *inside* the "ls -l" line */ |
586 | lpath = NULL; | 493 | lpath = NULL; |
587 | if (G.all_fmt & LIST_SYMLINK) | 494 | if (opt & OPT_l) |
588 | if (S_ISLNK(dn->dn_mode)) | 495 | if (S_ISLNK(dn->dn_mode)) |
589 | lpath = xmalloc_readlink_or_warn(dn->fullname); | 496 | lpath = xmalloc_readlink_or_warn(dn->fullname); |
590 | 497 | ||
591 | if (G.all_fmt & LIST_INO) | 498 | if (opt & OPT_i) /* show inode# */ |
592 | column += printf("%7llu ", (long long) dn->dn_ino); | 499 | column += printf("%7llu ", (long long) dn->dn_ino); |
593 | //TODO: -h should affect -s too: | 500 | //TODO: -h should affect -s too: |
594 | if (G.all_fmt & LIST_BLOCKS) | 501 | if (opt & OPT_s) /* show allocated blocks */ |
595 | column += printf("%6"OFF_FMT"u ", (off_t) (dn->dn_blocks >> 1)); | 502 | column += printf("%6"OFF_FMT"u ", (off_t) (dn->dn_blocks >> 1)); |
596 | if (G.all_fmt & LIST_MODEBITS) | 503 | if (opt & OPT_l) { |
504 | /* long listing: show mode */ | ||
597 | column += printf("%-10s ", (char *) bb_mode_string(dn->dn_mode)); | 505 | column += printf("%-10s ", (char *) bb_mode_string(dn->dn_mode)); |
598 | if (G.all_fmt & LIST_NLINKS) | 506 | /* long listing: show number of links */ |
599 | column += printf("%4lu ", (long) dn->dn_nlink); | 507 | column += printf("%4lu ", (long) dn->dn_nlink); |
600 | if (G.all_fmt & LIST_ID_NUMERIC) { | 508 | /* long listing: show user/group */ |
601 | if (option_mask32 & OPT_g) | 509 | if (opt & OPT_n) { |
602 | column += printf("%-8u ", (int) dn->dn_gid); | 510 | if (opt & OPT_g) |
603 | else | 511 | column += printf("%-8u ", (int) dn->dn_gid); |
604 | column += printf("%-8u %-8u ", | 512 | else |
605 | (int) dn->dn_uid, | 513 | column += printf("%-8u %-8u ", |
606 | (int) dn->dn_gid); | 514 | (int) dn->dn_uid, |
607 | } | 515 | (int) dn->dn_gid); |
516 | } | ||
608 | #if ENABLE_FEATURE_LS_USERNAME | 517 | #if ENABLE_FEATURE_LS_USERNAME |
609 | else if (G.all_fmt & LIST_ID_NAME) { | 518 | else { |
610 | if (option_mask32 & OPT_g) { | 519 | if (opt & OPT_g) { |
611 | column += printf("%-8.8s ", | 520 | column += printf("%-8.8s ", |
612 | get_cached_groupname(dn->dn_gid)); | 521 | get_cached_groupname(dn->dn_gid)); |
613 | } else { | 522 | } else { |
614 | column += printf("%-8.8s %-8.8s ", | 523 | column += printf("%-8.8s %-8.8s ", |
615 | get_cached_username(dn->dn_uid), | 524 | get_cached_username(dn->dn_uid), |
616 | get_cached_groupname(dn->dn_gid)); | 525 | get_cached_groupname(dn->dn_gid)); |
526 | } | ||
617 | } | 527 | } |
528 | #endif | ||
529 | #if ENABLE_SELINUX | ||
530 | } | ||
531 | if (opt & OPT_Z) { | ||
532 | column += printf("%-32s ", dn->sid ? dn->sid : "?"); | ||
533 | freecon(dn->sid); | ||
618 | } | 534 | } |
535 | if (opt & OPT_l) { | ||
619 | #endif | 536 | #endif |
620 | if (G.all_fmt & LIST_SIZE) { | 537 | /* long listing: show size */ |
621 | if (S_ISBLK(dn->dn_mode) || S_ISCHR(dn->dn_mode)) { | 538 | if (S_ISBLK(dn->dn_mode) || S_ISCHR(dn->dn_mode)) { |
622 | column += printf("%4u, %3u ", | 539 | column += printf("%4u, %3u ", |
623 | dn->dn_rdev_maj, | 540 | dn->dn_rdev_maj, |
624 | dn->dn_rdev_min); | 541 | dn->dn_rdev_min); |
625 | } else { | 542 | } else { |
626 | if (option_mask32 & OPT_h) { | 543 | if (opt & OPT_h) { |
627 | column += printf("%"HUMAN_READABLE_MAX_WIDTH_STR"s ", | 544 | column += printf("%"HUMAN_READABLE_MAX_WIDTH_STR"s ", |
628 | /* print size, show one fractional, use suffixes */ | 545 | /* print size, show one fractional, use suffixes */ |
629 | make_human_readable_str(dn->dn_size, 1, 0) | 546 | make_human_readable_str(dn->dn_size, 1, 0) |
@@ -632,25 +549,22 @@ static NOINLINE unsigned display_single(const struct dnode *dn) | |||
632 | column += printf("%9"OFF_FMT"u ", dn->dn_size); | 549 | column += printf("%9"OFF_FMT"u ", dn->dn_size); |
633 | } | 550 | } |
634 | } | 551 | } |
635 | } | ||
636 | #if ENABLE_FEATURE_LS_TIMESTAMPS | 552 | #if ENABLE_FEATURE_LS_TIMESTAMPS |
637 | if (G.all_fmt & (LIST_FULLTIME|LIST_DATE_TIME)) { | 553 | /* long listing: show {m,c,a}time */ |
638 | char *filetime; | 554 | if (opt & OPT_full_time) { /* --full-time */ |
639 | const time_t *ttime = &dn->dn_mtime; | 555 | /* coreutils 8.4 ls --full-time prints: |
640 | if (G.all_fmt & TIME_ACCESS) | ||
641 | ttime = &dn->dn_atime; | ||
642 | if (G.all_fmt & TIME_CHANGE) | ||
643 | ttime = &dn->dn_ctime; | ||
644 | filetime = ctime(ttime); | ||
645 | /* filetime's format: "Wed Jun 30 21:49:08 1993\n" */ | ||
646 | if (G.all_fmt & LIST_FULLTIME) { /* -e */ | ||
647 | /* Note: coreutils 8.4 ls --full-time prints: | ||
648 | * 2009-07-13 17:49:27.000000000 +0200 | 556 | * 2009-07-13 17:49:27.000000000 +0200 |
557 | * we don't show fractional seconds. | ||
649 | */ | 558 | */ |
650 | column += printf("%.24s ", filetime); | 559 | char buf[sizeof("YYYY-mm-dd HH:MM:SS TIMEZONE")]; |
651 | } else { /* LIST_DATE_TIME */ | 560 | strftime(buf, sizeof(buf), "%Y-%m-%d %H:%M:%S %z", |
652 | /* G.current_time_t ~== time(NULL) */ | 561 | localtime(&dn->dn_time)); |
653 | time_t age = G.current_time_t - *ttime; | 562 | column += printf("%s ", buf); |
563 | } else { /* ordinary time format */ | ||
564 | /* G.current_time_t is ~== time(NULL) */ | ||
565 | char *filetime = ctime(&dn->dn_time); | ||
566 | /* filetime's format: "Wed Jun 30 21:49:08 1993\n" */ | ||
567 | time_t age = G.current_time_t - dn->dn_time; | ||
654 | if (age < 3600L * 24 * 365 / 2 && age > -15 * 60) { | 568 | if (age < 3600L * 24 * 365 / 2 && age > -15 * 60) { |
655 | /* less than 6 months old */ | 569 | /* less than 6 months old */ |
656 | /* "mmm dd hh:mm " */ | 570 | /* "mmm dd hh:mm " */ |
@@ -663,14 +577,8 @@ static NOINLINE unsigned display_single(const struct dnode *dn) | |||
663 | } | 577 | } |
664 | column += 13; | 578 | column += 13; |
665 | } | 579 | } |
666 | } | ||
667 | #endif | 580 | #endif |
668 | #if ENABLE_SELINUX | ||
669 | if (G.all_fmt & LIST_CONTEXT) { | ||
670 | column += printf("%-32s ", dn->sid ? dn->sid : "unknown"); | ||
671 | freecon(dn->sid); | ||
672 | } | 581 | } |
673 | #endif | ||
674 | 582 | ||
675 | #if ENABLE_FEATURE_LS_COLOR | 583 | #if ENABLE_FEATURE_LS_COLOR |
676 | if (G_show_color) { | 584 | if (G_show_color) { |
@@ -689,7 +597,9 @@ static NOINLINE unsigned display_single(const struct dnode *dn) | |||
689 | if (lpath) { | 597 | if (lpath) { |
690 | printf(" -> "); | 598 | printf(" -> "); |
691 | #if ENABLE_FEATURE_LS_FILETYPES || ENABLE_FEATURE_LS_COLOR | 599 | #if ENABLE_FEATURE_LS_FILETYPES || ENABLE_FEATURE_LS_COLOR |
692 | if ((G.all_fmt & LIST_FILETYPE) || G_show_color) { | 600 | if ((opt & (OPT_F|OPT_p)) |
601 | || G_show_color | ||
602 | ) { | ||
693 | mode_t mode = dn->dn_mode_stat; | 603 | mode_t mode = dn->dn_mode_stat; |
694 | if (!mode) | 604 | if (!mode) |
695 | if (stat(dn->fullname, &statbuf) == 0) | 605 | if (stat(dn->fullname, &statbuf) == 0) |
@@ -711,7 +621,7 @@ static NOINLINE unsigned display_single(const struct dnode *dn) | |||
711 | } | 621 | } |
712 | } | 622 | } |
713 | #if ENABLE_FEATURE_LS_FILETYPES | 623 | #if ENABLE_FEATURE_LS_FILETYPES |
714 | if (G.all_fmt & LIST_FILETYPE) { | 624 | if (opt & (OPT_F|OPT_p)) { |
715 | if (append) { | 625 | if (append) { |
716 | putchar(append); | 626 | putchar(append); |
717 | column++; | 627 | column++; |
@@ -727,9 +637,9 @@ static void display_files(struct dnode **dn, unsigned nfiles) | |||
727 | unsigned i, ncols, nrows, row, nc; | 637 | unsigned i, ncols, nrows, row, nc; |
728 | unsigned column; | 638 | unsigned column; |
729 | unsigned nexttab; | 639 | unsigned nexttab; |
730 | unsigned column_width = 0; /* used only by STYLE_COLUMNAR */ | 640 | unsigned column_width = 0; /* used only by coulmnal output */ |
731 | 641 | ||
732 | if (G.all_fmt & STYLE_LONG) { /* STYLE_LONG or STYLE_SINGLE */ | 642 | if (option_mask32 & (OPT_l|OPT_1)) { |
733 | ncols = 1; | 643 | ncols = 1; |
734 | } else { | 644 | } else { |
735 | /* find the longest file name, use that as the column width */ | 645 | /* find the longest file name, use that as the column width */ |
@@ -738,10 +648,11 @@ static void display_files(struct dnode **dn, unsigned nfiles) | |||
738 | if (column_width < len) | 648 | if (column_width < len) |
739 | column_width = len; | 649 | column_width = len; |
740 | } | 650 | } |
741 | column_width += 2 + | 651 | column_width += 2 |
742 | IF_SELINUX( ((G.all_fmt & LIST_CONTEXT) ? 33 : 0) + ) | 652 | + ((option_mask32 & OPT_Z) ? 33 : 0) /* context width */ |
743 | ((G.all_fmt & LIST_INO) ? 8 : 0) + | 653 | + ((option_mask32 & OPT_i) ? 8 : 0) /* inode# width */ |
744 | ((G.all_fmt & LIST_BLOCKS) ? 5 : 0); | 654 | + ((option_mask32 & OPT_s) ? 5 : 0) /* "alloc block" width */ |
655 | ; | ||
745 | ncols = (unsigned)G_terminal_width / column_width; | 656 | ncols = (unsigned)G_terminal_width / column_width; |
746 | } | 657 | } |
747 | 658 | ||
@@ -759,7 +670,7 @@ static void display_files(struct dnode **dn, unsigned nfiles) | |||
759 | for (row = 0; row < nrows; row++) { | 670 | for (row = 0; row < nrows; row++) { |
760 | for (nc = 0; nc < ncols; nc++) { | 671 | for (nc = 0; nc < ncols; nc++) { |
761 | /* reach into the array based on the column and row */ | 672 | /* reach into the array based on the column and row */ |
762 | if (G.all_fmt & DISP_ROWS) | 673 | if (option_mask32 & OPT_x) |
763 | i = (row * ncols) + nc; /* display across row */ | 674 | i = (row * ncols) + nc; /* display across row */ |
764 | else | 675 | else |
765 | i = (nc * nrows) + row; /* display by column */ | 676 | i = (nc * nrows) + row; /* display by column */ |
@@ -792,7 +703,7 @@ static struct dnode *my_stat(const char *fullname, const char *name, int force_f | |||
792 | 703 | ||
793 | if ((option_mask32 & OPT_L) || force_follow) { | 704 | if ((option_mask32 & OPT_L) || force_follow) { |
794 | #if ENABLE_SELINUX | 705 | #if ENABLE_SELINUX |
795 | if (is_selinux_enabled()) { | 706 | if (option_mask32 & OPT_Z) { |
796 | getfilecon(fullname, &cur->sid); | 707 | getfilecon(fullname, &cur->sid); |
797 | } | 708 | } |
798 | #endif | 709 | #endif |
@@ -805,7 +716,7 @@ static struct dnode *my_stat(const char *fullname, const char *name, int force_f | |||
805 | cur->dn_mode_stat = statbuf.st_mode; | 716 | cur->dn_mode_stat = statbuf.st_mode; |
806 | } else { | 717 | } else { |
807 | #if ENABLE_SELINUX | 718 | #if ENABLE_SELINUX |
808 | if (is_selinux_enabled()) { | 719 | if (option_mask32 & OPT_Z) { |
809 | lgetfilecon(fullname, &cur->sid); | 720 | lgetfilecon(fullname, &cur->sid); |
810 | } | 721 | } |
811 | #endif | 722 | #endif |
@@ -822,9 +733,11 @@ static struct dnode *my_stat(const char *fullname, const char *name, int force_f | |||
822 | cur->dn_mode = statbuf.st_mode ; | 733 | cur->dn_mode = statbuf.st_mode ; |
823 | cur->dn_size = statbuf.st_size ; | 734 | cur->dn_size = statbuf.st_size ; |
824 | #if ENABLE_FEATURE_LS_TIMESTAMPS || ENABLE_FEATURE_LS_SORTFILES | 735 | #if ENABLE_FEATURE_LS_TIMESTAMPS || ENABLE_FEATURE_LS_SORTFILES |
825 | cur->dn_atime = statbuf.st_atime ; | 736 | cur->dn_time = statbuf.st_mtime ; |
826 | cur->dn_mtime = statbuf.st_mtime ; | 737 | if (option_mask32 & OPT_u) |
827 | cur->dn_ctime = statbuf.st_ctime ; | 738 | cur->dn_time = statbuf.st_atime; |
739 | if (option_mask32 & OPT_c) | ||
740 | cur->dn_time = statbuf.st_ctime; | ||
828 | #endif | 741 | #endif |
829 | cur->dn_ino = statbuf.st_ino ; | 742 | cur->dn_ino = statbuf.st_ino ; |
830 | cur->dn_blocks = statbuf.st_blocks; | 743 | cur->dn_blocks = statbuf.st_blocks; |
@@ -938,33 +851,30 @@ static int sortcmp(const void *a, const void *b) | |||
938 | { | 851 | { |
939 | struct dnode *d1 = *(struct dnode **)a; | 852 | struct dnode *d1 = *(struct dnode **)a; |
940 | struct dnode *d2 = *(struct dnode **)b; | 853 | struct dnode *d2 = *(struct dnode **)b; |
941 | unsigned sort_opts = G.all_fmt & SORT_MASK; | 854 | unsigned opt = option_mask32; |
942 | off_t dif; | 855 | off_t dif; |
943 | 856 | ||
944 | dif = 0; /* assume SORT_NAME */ | 857 | dif = 0; /* assume sort by name */ |
945 | // TODO: use pre-initialized function pointer | 858 | // TODO: use pre-initialized function pointer |
946 | // instead of branch forest | 859 | // instead of branch forest |
947 | if (sort_opts == SORT_SIZE) { | 860 | if (opt & OPT_dirs_first) { |
861 | dif = S_ISDIR(d2->dn_mode) - S_ISDIR(d1->dn_mode); | ||
862 | if (dif != 0) | ||
863 | goto maybe_invert_and_ret; | ||
864 | } | ||
865 | |||
866 | if (opt & OPT_S) { /* sort by size */ | ||
948 | dif = (d2->dn_size - d1->dn_size); | 867 | dif = (d2->dn_size - d1->dn_size); |
949 | } else | 868 | } else |
950 | if (sort_opts == SORT_ATIME) { | 869 | if (opt & OPT_t) { /* sort by time */ |
951 | dif = (d2->dn_atime - d1->dn_atime); | 870 | dif = (d2->dn_time - d1->dn_time); |
952 | } else | ||
953 | if (sort_opts == SORT_CTIME) { | ||
954 | dif = (d2->dn_ctime - d1->dn_ctime); | ||
955 | } else | ||
956 | if (sort_opts == SORT_MTIME) { | ||
957 | dif = (d2->dn_mtime - d1->dn_mtime); | ||
958 | } else | ||
959 | if (sort_opts == SORT_DIR) { | ||
960 | dif = S_ISDIR(d2->dn_mode) - S_ISDIR(d1->dn_mode); | ||
961 | } else | 871 | } else |
962 | #if defined(HAVE_STRVERSCMP) && HAVE_STRVERSCMP == 1 | 872 | #if defined(HAVE_STRVERSCMP) && HAVE_STRVERSCMP == 1 |
963 | if (sort_opts == SORT_VERSION) { | 873 | if (opt & OPT_v) { /* sort by version */ |
964 | dif = strverscmp(d1->name, d2->name); | 874 | dif = strverscmp(d1->name, d2->name); |
965 | } else | 875 | } else |
966 | #endif | 876 | #endif |
967 | if (sort_opts == SORT_EXT) { | 877 | if (opt & OPT_X) { /* sort by extension */ |
968 | dif = strcmp(strchrnul(d1->name, '.'), strchrnul(d2->name, '.')); | 878 | dif = strcmp(strchrnul(d1->name, '.'), strchrnul(d2->name, '.')); |
969 | } | 879 | } |
970 | if (dif == 0) { | 880 | if (dif == 0) { |
@@ -973,18 +883,17 @@ static int sortcmp(const void *a, const void *b) | |||
973 | dif = strcoll(d1->name, d2->name); | 883 | dif = strcoll(d1->name, d2->name); |
974 | else | 884 | else |
975 | dif = strcmp(d1->name, d2->name); | 885 | dif = strcmp(d1->name, d2->name); |
976 | } | 886 | } else { |
977 | 887 | /* Make dif fit into an int */ | |
978 | /* Make dif fit into an int */ | 888 | if (sizeof(dif) > sizeof(int)) { |
979 | if (sizeof(dif) > sizeof(int)) { | 889 | enum { BITS_TO_SHIFT = 8 * (sizeof(dif) - sizeof(int)) }; |
980 | enum { BITS_TO_SHIFT = 8 * (sizeof(dif) - sizeof(int)) }; | 890 | /* shift leaving only "int" worth of bits */ |
981 | /* shift leaving only "int" worth of bits */ | 891 | /* (this requires dif != 0, and here it is nonzero) */ |
982 | if (dif != 0) { | ||
983 | dif = 1 | (int)((uoff_t)dif >> BITS_TO_SHIFT); | 892 | dif = 1 | (int)((uoff_t)dif >> BITS_TO_SHIFT); |
984 | } | 893 | } |
985 | } | 894 | } |
986 | 895 | maybe_invert_and_ret: | |
987 | return (G.all_fmt & SORT_REVERSE) ? -(int)dif : (int)dif; | 896 | return (opt & OPT_r) ? -(int)dif : (int)dif; |
988 | } | 897 | } |
989 | 898 | ||
990 | static void dnsort(struct dnode **dn, int size) | 899 | static void dnsort(struct dnode **dn, int size) |
@@ -1023,13 +932,13 @@ static struct dnode **scan_one_dir(const char *path, unsigned *nfiles_p) | |||
1023 | 932 | ||
1024 | /* are we going to list the file- it may be . or .. or a hidden file */ | 933 | /* are we going to list the file- it may be . or .. or a hidden file */ |
1025 | if (entry->d_name[0] == '.') { | 934 | if (entry->d_name[0] == '.') { |
1026 | if ((!entry->d_name[1] || (entry->d_name[1] == '.' && !entry->d_name[2])) | 935 | if (!(option_mask32 & (OPT_a|OPT_A))) |
1027 | && !(G.all_fmt & DISP_DOT) | 936 | continue; /* skip all dotfiles if no -a/-A */ |
937 | if (!(option_mask32 & OPT_a) | ||
938 | && (!entry->d_name[1] || (entry->d_name[1] == '.' && !entry->d_name[2])) | ||
1028 | ) { | 939 | ) { |
1029 | continue; | 940 | continue; /* if only -A, skip . and .. but show other dotfiles */ |
1030 | } | 941 | } |
1031 | if (!(G.all_fmt & DISP_HIDDEN)) | ||
1032 | continue; | ||
1033 | } | 942 | } |
1034 | fullname = concat_path_file(path, entry->d_name); | 943 | fullname = concat_path_file(path, entry->d_name); |
1035 | cur = my_stat(fullname, bb_basename(fullname), 0); | 944 | cur = my_stat(fullname, bb_basename(fullname), 0); |
@@ -1097,7 +1006,7 @@ static void scan_and_display_dirs_recur(struct dnode **dn, int first) | |||
1097 | struct dnode **subdnp; | 1006 | struct dnode **subdnp; |
1098 | 1007 | ||
1099 | for (; *dn; dn++) { | 1008 | for (; *dn; dn++) { |
1100 | if (G.all_fmt & (DISP_DIRNAME | DISP_RECURSIVE)) { | 1009 | if (G.show_dirname || (option_mask32 & OPT_R)) { |
1101 | if (!first) | 1010 | if (!first) |
1102 | bb_putchar('\n'); | 1011 | bb_putchar('\n'); |
1103 | first = 0; | 1012 | first = 0; |
@@ -1105,15 +1014,16 @@ static void scan_and_display_dirs_recur(struct dnode **dn, int first) | |||
1105 | } | 1014 | } |
1106 | subdnp = scan_one_dir((*dn)->fullname, &nfiles); | 1015 | subdnp = scan_one_dir((*dn)->fullname, &nfiles); |
1107 | #if ENABLE_DESKTOP | 1016 | #if ENABLE_DESKTOP |
1108 | if ((G.all_fmt & STYLE_MASK) == STYLE_LONG || (G.all_fmt & LIST_BLOCKS)) | 1017 | if (option_mask32 & (OPT_s|OPT_l)) { |
1109 | printf("total %"OFF_FMT"u\n", calculate_blocks(subdnp)); | 1018 | printf("total %"OFF_FMT"u\n", calculate_blocks(subdnp)); |
1019 | } | ||
1110 | #endif | 1020 | #endif |
1111 | if (nfiles > 0) { | 1021 | if (nfiles > 0) { |
1112 | /* list all files at this level */ | 1022 | /* list all files at this level */ |
1113 | sort_and_display_files(subdnp, nfiles); | 1023 | sort_and_display_files(subdnp, nfiles); |
1114 | 1024 | ||
1115 | if (ENABLE_FEATURE_LS_RECURSIVE | 1025 | if (ENABLE_FEATURE_LS_RECURSIVE |
1116 | && (G.all_fmt & DISP_RECURSIVE) | 1026 | && (option_mask32 & OPT_R) |
1117 | ) { | 1027 | ) { |
1118 | struct dnode **dnd; | 1028 | struct dnode **dnd; |
1119 | unsigned dndirs; | 1029 | unsigned dndirs; |
@@ -1135,7 +1045,7 @@ static void scan_and_display_dirs_recur(struct dnode **dn, int first) | |||
1135 | 1045 | ||
1136 | 1046 | ||
1137 | int ls_main(int argc UNUSED_PARAM, char **argv) | 1047 | int ls_main(int argc UNUSED_PARAM, char **argv) |
1138 | { | 1048 | { /* ^^^^^^^^^^^^^^^^^ note: if FTPD, argc can be wrong, see ftpd.c */ |
1139 | struct dnode **dnd; | 1049 | struct dnode **dnd; |
1140 | struct dnode **dnf; | 1050 | struct dnode **dnf; |
1141 | struct dnode **dnp; | 1051 | struct dnode **dnp; |
@@ -1158,7 +1068,10 @@ int ls_main(int argc UNUSED_PARAM, char **argv) | |||
1158 | * (and substrings: "--color=alwa" work too) | 1068 | * (and substrings: "--color=alwa" work too) |
1159 | */ | 1069 | */ |
1160 | static const char ls_longopts[] ALIGN1 = | 1070 | static const char ls_longopts[] ALIGN1 = |
1161 | "color\0" Optional_argument "\xff"; /* no short equivalent */ | 1071 | "full-time\0" No_argument "\xff" |
1072 | "group-directories-first\0" No_argument "\xfe" | ||
1073 | "color\0" Optional_argument "\xfd" | ||
1074 | ; | ||
1162 | static const char color_str[] ALIGN1 = | 1075 | static const char color_str[] ALIGN1 = |
1163 | "always\0""yes\0""force\0" | 1076 | "always\0""yes\0""force\0" |
1164 | "auto\0""tty\0""if-tty\0"; | 1077 | "auto\0""tty\0""if-tty\0"; |
@@ -1170,10 +1083,7 @@ int ls_main(int argc UNUSED_PARAM, char **argv) | |||
1170 | 1083 | ||
1171 | init_unicode(); | 1084 | init_unicode(); |
1172 | 1085 | ||
1173 | if (ENABLE_FEATURE_LS_SORTFILES) | 1086 | #if ENABLE_FEATURE_LS_WIDTH |
1174 | G.all_fmt = SORT_NAME; | ||
1175 | |||
1176 | #if ENABLE_FEATURE_AUTOWIDTH | ||
1177 | /* obtain the terminal width */ | 1087 | /* obtain the terminal width */ |
1178 | G_terminal_width = get_terminal_width(STDIN_FILENO); | 1088 | G_terminal_width = get_terminal_width(STDIN_FILENO); |
1179 | /* go one less... */ | 1089 | /* go one less... */ |
@@ -1183,8 +1093,10 @@ int ls_main(int argc UNUSED_PARAM, char **argv) | |||
1183 | /* process options */ | 1093 | /* process options */ |
1184 | IF_FEATURE_LS_COLOR(applet_long_options = ls_longopts;) | 1094 | IF_FEATURE_LS_COLOR(applet_long_options = ls_longopts;) |
1185 | opt_complementary = | 1095 | opt_complementary = |
1186 | /* -e implies -l */ | 1096 | /* -n and -g imply -l */ |
1187 | IF_FEATURE_LS_TIMESTAMPS("el") | 1097 | "nl:gl" |
1098 | /* --full-time implies -l */ | ||
1099 | IF_FEATURE_LS_TIMESTAMPS(IF_LONG_OPTS(":\xff""l")) | ||
1188 | /* http://pubs.opengroup.org/onlinepubs/9699919799/utilities/ls.html: | 1100 | /* http://pubs.opengroup.org/onlinepubs/9699919799/utilities/ls.html: |
1189 | * in some pairs of opts, only last one takes effect: | 1101 | * in some pairs of opts, only last one takes effect: |
1190 | */ | 1102 | */ |
@@ -1196,25 +1108,28 @@ int ls_main(int argc UNUSED_PARAM, char **argv) | |||
1196 | ":x-1:1-x" /* bylines/oneline (not in SuS, but in GNU coreutils 8.4) */ | 1108 | ":x-1:1-x" /* bylines/oneline (not in SuS, but in GNU coreutils 8.4) */ |
1197 | IF_FEATURE_LS_TIMESTAMPS(":c-u:u-c") /* mtime/atime */ | 1109 | IF_FEATURE_LS_TIMESTAMPS(":c-u:u-c") /* mtime/atime */ |
1198 | /* -w NUM: */ | 1110 | /* -w NUM: */ |
1199 | IF_FEATURE_AUTOWIDTH(":w+"); | 1111 | IF_FEATURE_LS_WIDTH(":w+"); |
1200 | opt = getopt32(argv, ls_options | 1112 | opt = getopt32(argv, ls_options |
1201 | IF_FEATURE_AUTOWIDTH(, NULL, &G_terminal_width) | 1113 | IF_FEATURE_LS_WIDTH(, /*-T*/ NULL, /*-w*/ &G_terminal_width) |
1202 | IF_FEATURE_LS_COLOR(, &color_opt) | 1114 | IF_FEATURE_LS_COLOR(, &color_opt) |
1203 | ); | 1115 | ); |
1204 | for (i = 0; opt_flags[i] != (1U << 31); i++) { | 1116 | #if 0 /* option bits debug */ |
1205 | if (opt & (1 << i)) { | 1117 | bb_error_msg("opt:0x%08x l:%x H:%x color:%x dirs:%x", opt, OPT_l, OPT_H, OPT_color, OPT_dirs_first); |
1206 | uint32_t flags = opt_flags[i]; | 1118 | if (opt & OPT_c ) bb_error_msg("-c"); |
1207 | 1119 | if (opt & OPT_l ) bb_error_msg("-l"); | |
1208 | if (flags & STYLE_MASK) | 1120 | if (opt & OPT_H ) bb_error_msg("-H"); |
1209 | G.all_fmt &= ~STYLE_MASK; | 1121 | if (opt & OPT_color ) bb_error_msg("--color"); |
1210 | if (flags & SORT_MASK) | 1122 | if (opt & OPT_dirs_first) bb_error_msg("--group-directories-first"); |
1211 | G.all_fmt &= ~SORT_MASK; | 1123 | if (opt & OPT_full_time ) bb_error_msg("--full-time"); |
1212 | if (flags & TIME_MASK) | 1124 | exit(0); |
1213 | G.all_fmt &= ~TIME_MASK; | 1125 | #endif |
1214 | 1126 | ||
1215 | G.all_fmt |= flags; | 1127 | #if ENABLE_SELINUX |
1216 | } | 1128 | if (opt & OPT_Z) { |
1129 | if (!is_selinux_enabled()) | ||
1130 | option_mask32 &= ~OPT_Z; | ||
1217 | } | 1131 | } |
1132 | #endif | ||
1218 | 1133 | ||
1219 | #if ENABLE_FEATURE_LS_COLOR | 1134 | #if ENABLE_FEATURE_LS_COLOR |
1220 | /* set G_show_color = 1/0 */ | 1135 | /* set G_show_color = 1/0 */ |
@@ -1242,27 +1157,35 @@ int ls_main(int argc UNUSED_PARAM, char **argv) | |||
1242 | #endif | 1157 | #endif |
1243 | 1158 | ||
1244 | /* sort out which command line options take precedence */ | 1159 | /* sort out which command line options take precedence */ |
1245 | if (ENABLE_FEATURE_LS_RECURSIVE && (G.all_fmt & DISP_NOLIST)) | 1160 | if (ENABLE_FEATURE_LS_RECURSIVE && (opt & OPT_d)) |
1246 | G.all_fmt &= ~DISP_RECURSIVE; /* no recurse if listing only dir */ | 1161 | option_mask32 &= ~OPT_R; /* no recurse if listing only dir */ |
1247 | if (ENABLE_FEATURE_LS_TIMESTAMPS && ENABLE_FEATURE_LS_SORTFILES) { | 1162 | if (!(opt & OPT_l)) { /* not -l? */ |
1248 | if (G.all_fmt & TIME_CHANGE) | 1163 | if (ENABLE_FEATURE_LS_TIMESTAMPS && ENABLE_FEATURE_LS_SORTFILES) { |
1249 | G.all_fmt = (G.all_fmt & ~SORT_MASK) | SORT_CTIME; | 1164 | /* when to sort by time? -t[cu] sorts by time even with -l */ |
1250 | if (G.all_fmt & TIME_ACCESS) | 1165 | /* (this is achieved by opt_flags[] element for -t) */ |
1251 | G.all_fmt = (G.all_fmt & ~SORT_MASK) | SORT_ATIME; | 1166 | /* without -l, bare -c or -u enable sort too */ |
1167 | /* (with -l, bare -c or -u just select which time to show) */ | ||
1168 | if (opt & (OPT_c|OPT_u)) { | ||
1169 | option_mask32 |= OPT_t; | ||
1170 | } | ||
1171 | } | ||
1252 | } | 1172 | } |
1253 | if ((G.all_fmt & STYLE_MASK) != STYLE_LONG) /* not -l? */ | ||
1254 | G.all_fmt &= ~(LIST_ID_NUMERIC|LIST_ID_NAME|LIST_FULLTIME); | ||
1255 | 1173 | ||
1256 | /* choose a display format if one was not already specified by an option */ | 1174 | /* choose a display format if one was not already specified by an option */ |
1257 | if (!(G.all_fmt & STYLE_MASK)) | 1175 | if (!(option_mask32 & (OPT_l|OPT_1|OPT_x|OPT_C))) |
1258 | G.all_fmt |= (isatty(STDOUT_FILENO) ? STYLE_COLUMNAR : STYLE_SINGLE); | 1176 | option_mask32 |= (isatty(STDOUT_FILENO) ? OPT_C : OPT_1); |
1177 | |||
1178 | if (ENABLE_FTPD && applet_name[0] == 'f') { | ||
1179 | /* ftpd secret backdoor. dirs first are much nicer */ | ||
1180 | option_mask32 |= OPT_dirs_first; | ||
1181 | } | ||
1259 | 1182 | ||
1260 | argv += optind; | 1183 | argv += optind; |
1261 | if (!argv[0]) | 1184 | if (!argv[0]) |
1262 | *--argv = (char*)"."; | 1185 | *--argv = (char*)"."; |
1263 | 1186 | ||
1264 | if (argv[1]) | 1187 | if (argv[1]) |
1265 | G.all_fmt |= DISP_DIRNAME; /* 2 or more items? label directories */ | 1188 | G.show_dirname = 1; /* 2 or more items? label directories */ |
1266 | 1189 | ||
1267 | /* stuff the command line file names into a dnode array */ | 1190 | /* stuff the command line file names into a dnode array */ |
1268 | dn = NULL; | 1191 | dn = NULL; |
@@ -1270,10 +1193,7 @@ int ls_main(int argc UNUSED_PARAM, char **argv) | |||
1270 | do { | 1193 | do { |
1271 | cur = my_stat(*argv, *argv, | 1194 | cur = my_stat(*argv, *argv, |
1272 | /* follow links on command line unless -l, -s or -F: */ | 1195 | /* follow links on command line unless -l, -s or -F: */ |
1273 | !((G.all_fmt & STYLE_MASK) == STYLE_LONG | 1196 | !(option_mask32 & (OPT_l|OPT_s|OPT_F)) |
1274 | || (G.all_fmt & LIST_BLOCKS) | ||
1275 | || (option_mask32 & OPT_F) | ||
1276 | ) | ||
1277 | /* ... or if -H: */ | 1197 | /* ... or if -H: */ |
1278 | || (option_mask32 & OPT_H) | 1198 | || (option_mask32 & OPT_H) |
1279 | /* ... or if -L, but my_stat always follows links if -L */ | 1199 | /* ... or if -L, but my_stat always follows links if -L */ |
@@ -1302,7 +1222,7 @@ int ls_main(int argc UNUSED_PARAM, char **argv) | |||
1302 | break; | 1222 | break; |
1303 | } | 1223 | } |
1304 | 1224 | ||
1305 | if (G.all_fmt & DISP_NOLIST) { | 1225 | if (option_mask32 & OPT_d) { |
1306 | sort_and_display_files(dnp, nfiles); | 1226 | sort_and_display_files(dnp, nfiles); |
1307 | } else { | 1227 | } else { |
1308 | dnd = splitdnarray(dnp, SPLIT_DIR); | 1228 | dnd = splitdnarray(dnp, SPLIT_DIR); |
diff --git a/coreutils/md5_sha1_sum.c b/coreutils/md5_sha1_sum.c index 783f44027..50111bd26 100644 --- a/coreutils/md5_sha1_sum.c +++ b/coreutils/md5_sha1_sum.c | |||
@@ -45,7 +45,6 @@ | |||
45 | //config: help | 45 | //config: help |
46 | //config: Enabling the -c options allows files to be checked | 46 | //config: Enabling the -c options allows files to be checked |
47 | //config: against pre-calculated hash values. | 47 | //config: against pre-calculated hash values. |
48 | //config: | ||
49 | //config: -s and -w are useful options when verifying checksums. | 48 | //config: -s and -w are useful options when verifying checksums. |
50 | 49 | ||
51 | //applet:IF_MD5SUM(APPLET_NOEXEC(md5sum, md5_sha1_sum, BB_DIR_USR_BIN, BB_SUID_DROP, md5sum)) | 50 | //applet:IF_MD5SUM(APPLET_NOEXEC(md5sum, md5_sha1_sum, BB_DIR_USR_BIN, BB_SUID_DROP, md5sum)) |
@@ -167,7 +166,7 @@ static uint8_t *hash_file(const char *filename, unsigned sha3_width) | |||
167 | } context; | 166 | } context; |
168 | uint8_t *hash_value; | 167 | uint8_t *hash_value; |
169 | void FAST_FUNC (*update)(void*, const void*, size_t); | 168 | void FAST_FUNC (*update)(void*, const void*, size_t); |
170 | void FAST_FUNC (*final)(void*, void*); | 169 | unsigned FAST_FUNC (*final)(void*, void*); |
171 | char hash_algo; | 170 | char hash_algo; |
172 | 171 | ||
173 | src_fd = open_or_warn_stdin(filename); | 172 | src_fd = open_or_warn_stdin(filename); |
diff --git a/coreutils/mkdir.c b/coreutils/mkdir.c index 3afe76c28..fcc34f1ad 100644 --- a/coreutils/mkdir.c +++ b/coreutils/mkdir.c | |||
@@ -23,8 +23,6 @@ | |||
23 | //config: bool "Enable long options" | 23 | //config: bool "Enable long options" |
24 | //config: default y | 24 | //config: default y |
25 | //config: depends on MKDIR && LONG_OPTS | 25 | //config: depends on MKDIR && LONG_OPTS |
26 | //config: help | ||
27 | //config: Support long options for the mkdir applet. | ||
28 | 26 | ||
29 | //applet:IF_MKDIR(APPLET_NOFORK(mkdir, mkdir, BB_DIR_BIN, BB_SUID_DROP, mkdir)) | 27 | //applet:IF_MKDIR(APPLET_NOFORK(mkdir, mkdir, BB_DIR_BIN, BB_SUID_DROP, mkdir)) |
30 | 28 | ||
diff --git a/coreutils/mv.c b/coreutils/mv.c index 1cc318fd1..df2ef0a52 100644 --- a/coreutils/mv.c +++ b/coreutils/mv.c | |||
@@ -21,8 +21,6 @@ | |||
21 | //config: bool "Enable long options" | 21 | //config: bool "Enable long options" |
22 | //config: default y | 22 | //config: default y |
23 | //config: depends on MV && LONG_OPTS | 23 | //config: depends on MV && LONG_OPTS |
24 | //config: help | ||
25 | //config: Support long options for the mv applet. | ||
26 | 24 | ||
27 | //applet:IF_MV(APPLET(mv, BB_DIR_BIN, BB_SUID_DROP)) | 25 | //applet:IF_MV(APPLET(mv, BB_DIR_BIN, BB_SUID_DROP)) |
28 | 26 | ||
diff --git a/coreutils/printf.c b/coreutils/printf.c index 6c8e115d8..bc22e0ee7 100644 --- a/coreutils/printf.c +++ b/coreutils/printf.c | |||
@@ -49,6 +49,9 @@ | |||
49 | 49 | ||
50 | //kbuild:lib-$(CONFIG_PRINTF) += printf.o | 50 | //kbuild:lib-$(CONFIG_PRINTF) += printf.o |
51 | 51 | ||
52 | //kbuild:lib-$(CONFIG_ASH_PRINTF) += printf.o | ||
53 | //kbuild:lib-$(CONFIG_HUSH_PRINTF) += printf.o | ||
54 | |||
52 | //usage:#define printf_trivial_usage | 55 | //usage:#define printf_trivial_usage |
53 | //usage: "FORMAT [ARG]..." | 56 | //usage: "FORMAT [ARG]..." |
54 | //usage:#define printf_full_usage "\n\n" | 57 | //usage:#define printf_full_usage "\n\n" |
@@ -417,7 +420,7 @@ int printf_main(int argc UNUSED_PARAM, char **argv) | |||
417 | if (argv[1] && argv[1][0] == '-' && argv[1][1] == '-' && !argv[1][2]) | 420 | if (argv[1] && argv[1][0] == '-' && argv[1][1] == '-' && !argv[1][2]) |
418 | argv++; | 421 | argv++; |
419 | if (!argv[1]) { | 422 | if (!argv[1]) { |
420 | if (ENABLE_ASH_BUILTIN_PRINTF | 423 | if (ENABLE_ASH_PRINTF |
421 | && applet_name[0] != 'p' | 424 | && applet_name[0] != 'p' |
422 | ) { | 425 | ) { |
423 | bb_error_msg("usage: printf FORMAT [ARGUMENT...]"); | 426 | bb_error_msg("usage: printf FORMAT [ARGUMENT...]"); |
diff --git a/coreutils/split.c b/coreutils/split.c index 50918a1ce..7af359d0e 100644 --- a/coreutils/split.c +++ b/coreutils/split.c | |||
@@ -9,7 +9,7 @@ | |||
9 | //config: bool "split" | 9 | //config: bool "split" |
10 | //config: default y | 10 | //config: default y |
11 | //config: help | 11 | //config: help |
12 | //config: split a file into pieces. | 12 | //config: Split a file into pieces. |
13 | //config: | 13 | //config: |
14 | //config:config FEATURE_SPLIT_FANCY | 14 | //config:config FEATURE_SPLIT_FANCY |
15 | //config: bool "Fancy extensions" | 15 | //config: bool "Fancy extensions" |
diff --git a/coreutils/tail.c b/coreutils/tail.c index 99f58ddd8..e7a24a7a8 100644 --- a/coreutils/tail.c +++ b/coreutils/tail.c | |||
@@ -26,13 +26,12 @@ | |||
26 | //config: from files. | 26 | //config: from files. |
27 | //config: | 27 | //config: |
28 | //config:config FEATURE_FANCY_TAIL | 28 | //config:config FEATURE_FANCY_TAIL |
29 | //config: bool "Enable extra tail options (-q, -s, -v, and -F)" | 29 | //config: bool "Enable -q, -s, -v, and -F options" |
30 | //config: default y | 30 | //config: default y |
31 | //config: depends on TAIL | 31 | //config: depends on TAIL |
32 | //config: help | 32 | //config: help |
33 | //config: The options (-q, -s, -v and -F) are provided by GNU tail, but | 33 | //config: These options are provided by GNU tail, but |
34 | //config: are not specific in the SUSv3 standard. | 34 | //config: are not specific in the SUSv3 standard: |
35 | //config: | ||
36 | //config: -q Never output headers giving file names | 35 | //config: -q Never output headers giving file names |
37 | //config: -s SEC Wait SEC seconds between reads with -f | 36 | //config: -s SEC Wait SEC seconds between reads with -f |
38 | //config: -v Always output headers giving file names | 37 | //config: -v Always output headers giving file names |
diff --git a/coreutils/test.c b/coreutils/test.c index 67fdfde4f..c949a3cc9 100644 --- a/coreutils/test.c +++ b/coreutils/test.c | |||
@@ -42,21 +42,20 @@ | |||
42 | //config:config FEATURE_TEST_64 | 42 | //config:config FEATURE_TEST_64 |
43 | //config: bool "Extend test to 64 bit" | 43 | //config: bool "Extend test to 64 bit" |
44 | //config: default y | 44 | //config: default y |
45 | //config: depends on TEST || TEST1 || TEST2 || ASH_BUILTIN_TEST || HUSH | 45 | //config: depends on TEST || TEST1 || TEST2 || ASH_TEST || HUSH_TEST |
46 | //config: help | 46 | //config: help |
47 | //config: Enable 64-bit support in test. | 47 | //config: Enable 64-bit support in test. |
48 | 48 | ||
49 | //applet:IF_TEST(APPLET_NOFORK(test, test, BB_DIR_USR_BIN, BB_SUID_DROP, test)) | 49 | //applet:IF_TEST(APPLET_NOFORK(test, test, BB_DIR_USR_BIN, BB_SUID_DROP, test)) |
50 | //applet:IF_TEST1(APPLET_NOFORK([, test, BB_DIR_USR_BIN, BB_SUID_DROP, test)) | 50 | //applet:IF_TEST1(APPLET_NOFORK([, test, BB_DIR_USR_BIN, BB_SUID_DROP, test)) |
51 | //applet:IF_TEST2(APPLET_NOFORK([[, test, BB_DIR_USR_BIN, BB_SUID_DROP, test)) | 51 | //applet:IF_TEST2(APPLET_NOFORK([[, test, BB_DIR_USR_BIN, BB_SUID_DROP, test)) |
52 | 52 | ||
53 | //kbuild:lib-$(CONFIG_TEST) += test.o test_ptr_hack.o | 53 | //kbuild:lib-$(CONFIG_TEST) += test.o test_ptr_hack.o |
54 | //kbuild:lib-$(CONFIG_TEST1) += test.o test_ptr_hack.o | 54 | //kbuild:lib-$(CONFIG_TEST1) += test.o test_ptr_hack.o |
55 | //kbuild:lib-$(CONFIG_TEST2) += test.o test_ptr_hack.o | 55 | //kbuild:lib-$(CONFIG_TEST2) += test.o test_ptr_hack.o |
56 | //kbuild:lib-$(CONFIG_ASH_BUILTIN_TEST) += test.o test_ptr_hack.o | 56 | |
57 | //kbuild:lib-$(CONFIG_HUSH) += test.o test_ptr_hack.o | 57 | //kbuild:lib-$(CONFIG_ASH_TEST) += test.o test_ptr_hack.o |
58 | //kbuild:lib-$(CONFIG_SH_IS_HUSH) += test.o test_ptr_hack.o | 58 | //kbuild:lib-$(CONFIG_HUSH_TEST) += test.o test_ptr_hack.o |
59 | //kbuild:lib-$(CONFIG_BASH_IS_HUSH) += test.o test_ptr_hack.o | ||
60 | 59 | ||
61 | /* "test --help" is special-cased to ignore --help */ | 60 | /* "test --help" is special-cased to ignore --help */ |
62 | //usage:#define test_trivial_usage NOUSAGE_STR | 61 | //usage:#define test_trivial_usage NOUSAGE_STR |
@@ -858,7 +857,7 @@ int test_main(int argc, char **argv) | |||
858 | const char *arg0; | 857 | const char *arg0; |
859 | 858 | ||
860 | arg0 = bb_basename(argv[0]); | 859 | arg0 = bb_basename(argv[0]); |
861 | if ((ENABLE_TEST1 || ENABLE_TEST2 || ENABLE_ASH_BUILTIN_TEST || ENABLE_HUSH) | 860 | if ((ENABLE_TEST1 || ENABLE_TEST2 || ENABLE_ASH_TEST || ENABLE_HUSH_TEST) |
862 | && (arg0[0] == '[') | 861 | && (arg0[0] == '[') |
863 | ) { | 862 | ) { |
864 | --argc; | 863 | --argc; |
diff --git a/coreutils/wc.c b/coreutils/wc.c index 73837141e..4c53049b0 100644 --- a/coreutils/wc.c +++ b/coreutils/wc.c | |||
@@ -40,11 +40,11 @@ | |||
40 | //config: in specified files. | 40 | //config: in specified files. |
41 | //config: | 41 | //config: |
42 | //config:config FEATURE_WC_LARGE | 42 | //config:config FEATURE_WC_LARGE |
43 | //config: bool "Support very large files in wc" | 43 | //config: bool "Support very large counts" |
44 | //config: default y | 44 | //config: default y |
45 | //config: depends on WC | 45 | //config: depends on WC |
46 | //config: help | 46 | //config: help |
47 | //config: Use "unsigned long long" in wc for counter variables. | 47 | //config: Use "unsigned long long" for counter variables. |
48 | 48 | ||
49 | //applet:IF_WC(APPLET(wc, BB_DIR_USR_BIN, BB_SUID_DROP)) | 49 | //applet:IF_WC(APPLET(wc, BB_DIR_USR_BIN, BB_SUID_DROP)) |
50 | 50 | ||
diff --git a/coreutils/who.c b/coreutils/who.c index ac19dc720..e6179bb00 100644 --- a/coreutils/who.c +++ b/coreutils/who.c | |||
@@ -30,6 +30,7 @@ | |||
30 | //config: help | 30 | //config: help |
31 | //config: Print users currently logged on. | 31 | //config: Print users currently logged on. |
32 | 32 | ||
33 | // APPLET_ODDNAME:name main location suid_type help | ||
33 | //applet:IF_USERS(APPLET_ODDNAME(users, who, BB_DIR_USR_BIN, BB_SUID_DROP, users)) | 34 | //applet:IF_USERS(APPLET_ODDNAME(users, who, BB_DIR_USR_BIN, BB_SUID_DROP, users)) |
34 | //applet:IF_WHO(APPLET(who, BB_DIR_USR_BIN, BB_SUID_DROP)) | 35 | //applet:IF_WHO(APPLET(who, BB_DIR_USR_BIN, BB_SUID_DROP)) |
35 | 36 | ||
diff --git a/debianutils/run_parts.c b/debianutils/run_parts.c index 0bb666abc..3ef28f1d4 100644 --- a/debianutils/run_parts.c +++ b/debianutils/run_parts.c | |||
@@ -41,8 +41,6 @@ | |||
41 | //config: bool "Enable long options" | 41 | //config: bool "Enable long options" |
42 | //config: default y | 42 | //config: default y |
43 | //config: depends on RUN_PARTS && LONG_OPTS | 43 | //config: depends on RUN_PARTS && LONG_OPTS |
44 | //config: help | ||
45 | //config: Support long options for the run-parts applet. | ||
46 | //config: | 44 | //config: |
47 | //config:config FEATURE_RUN_PARTS_FANCY | 45 | //config:config FEATURE_RUN_PARTS_FANCY |
48 | //config: bool "Support additional arguments" | 46 | //config: bool "Support additional arguments" |
diff --git a/debianutils/start_stop_daemon.c b/debianutils/start_stop_daemon.c index 3625ffee8..4a9e0653e 100644 --- a/debianutils/start_stop_daemon.c +++ b/debianutils/start_stop_daemon.c | |||
@@ -64,22 +64,19 @@ Misc options: | |||
64 | //config: termination of system-level processes, usually the ones | 64 | //config: termination of system-level processes, usually the ones |
65 | //config: started during the startup of the system. | 65 | //config: started during the startup of the system. |
66 | //config: | 66 | //config: |
67 | //config:config FEATURE_START_STOP_DAEMON_LONG_OPTIONS | ||
68 | //config: bool "Enable long options" | ||
69 | //config: default y | ||
70 | //config: depends on START_STOP_DAEMON && LONG_OPTS | ||
71 | //config: | ||
67 | //config:config FEATURE_START_STOP_DAEMON_FANCY | 72 | //config:config FEATURE_START_STOP_DAEMON_FANCY |
68 | //config: bool "Support additional arguments" | 73 | //config: bool "Support additional arguments" |
69 | //config: default y | 74 | //config: default y |
70 | //config: depends on START_STOP_DAEMON | 75 | //config: depends on START_STOP_DAEMON |
71 | //config: help | 76 | //config: help |
72 | //config: Support additional arguments. | ||
73 | //config: -o|--oknodo ignored since we exit with 0 anyway | 77 | //config: -o|--oknodo ignored since we exit with 0 anyway |
74 | //config: -v|--verbose | 78 | //config: -v|--verbose |
75 | //config: -N|--nicelevel N | 79 | //config: -N|--nicelevel N |
76 | //config: | ||
77 | //config:config FEATURE_START_STOP_DAEMON_LONG_OPTIONS | ||
78 | //config: bool "Enable long options" | ||
79 | //config: default y | ||
80 | //config: depends on START_STOP_DAEMON && LONG_OPTS | ||
81 | //config: help | ||
82 | //config: Support long options for the start-stop-daemon applet. | ||
83 | 80 | ||
84 | //applet:IF_START_STOP_DAEMON(APPLET_ODDNAME(start-stop-daemon, start_stop_daemon, BB_DIR_SBIN, BB_SUID_DROP, start_stop_daemon)) | 81 | //applet:IF_START_STOP_DAEMON(APPLET_ODDNAME(start-stop-daemon, start_stop_daemon, BB_DIR_SBIN, BB_SUID_DROP, start_stop_daemon)) |
85 | 82 | ||
diff --git a/docs/nofork_noexec.txt b/docs/nofork_noexec.txt index c58f5a83f..a24dd9c27 100644 --- a/docs/nofork_noexec.txt +++ b/docs/nofork_noexec.txt | |||
@@ -33,6 +33,7 @@ roughly are: | |||
33 | * do not expect shared global variables/buffers to be in their | 33 | * do not expect shared global variables/buffers to be in their |
34 | "initialized" state. Examples: xfunc_error_retval can be != 1, | 34 | "initialized" state. Examples: xfunc_error_retval can be != 1, |
35 | bb_common_bufsiz1 can be scribbled over, ... | 35 | bb_common_bufsiz1 can be scribbled over, ... |
36 | (although usually xfunc_error_retval's state is not a problem). | ||
36 | * do not expect that stdio wasn't used before. Calling set[v]buf() | 37 | * do not expect that stdio wasn't used before. Calling set[v]buf() |
37 | can be disastrous. | 38 | can be disastrous. |
38 | * ... | 39 | * ... |
@@ -81,18 +82,44 @@ are probably not worth the effort. | |||
81 | Any NOFORK applet is also a NOEXEC applet. | 82 | Any NOFORK applet is also a NOEXEC applet. |
82 | 83 | ||
83 | 84 | ||
85 | Calling NOFORK applets | ||
86 | |||
87 | API to call NOFORK applets is two functions: | ||
88 | |||
89 | run_nofork_applet(appno, argv) | ||
90 | spawn_and_wait(argv) // only if FEATURE_PREFER_APPLETS=y | ||
91 | |||
92 | First one is directly used by shells if FEATURE_SH_NOFORK=y. | ||
93 | Second one is used by many applets, but main users are xargs and find. | ||
94 | It itself calls run_nofork_applet(), if argv[0] turned out to be a name | ||
95 | of a NOFORK applet. | ||
96 | |||
97 | run_nofork_applet() saves/inits/restores option parsing, xfunc_error_retval, | ||
98 | applet_name. Thus, for example, caller does not need to worry about | ||
99 | option_mask32 getting trashed. | ||
100 | |||
101 | |||
102 | Calling NOEXEC applets | ||
103 | |||
104 | It's the same trusty spawn_and_wait(argv). If FEATURE_PREFER_APPLETS=y, | ||
105 | it does NOEXEC trick. It resets xfunc_error_retval = 1 and | ||
106 | logmode = LOGMODE_STDIO in the child. | ||
107 | |||
108 | |||
84 | Relevant CONFIG options | 109 | Relevant CONFIG options |
85 | 110 | ||
86 | FEATURE_PREFER_APPLETS | 111 | FEATURE_PREFER_APPLETS |
87 | BB_EXECVP(cmd, argv) will try to exec /proc/self/exe | 112 | BB_EXECVP(cmd, argv) will try to exec /proc/self/exe |
88 | if command's name matches some applet name | 113 | if command's name matches some applet name; |
89 | applet tables will contain NOFORK/NOEXEC bits | ||
90 | spawn_and_wait(argv) will do NOFORK/NOEXEC tricks | 114 | spawn_and_wait(argv) will do NOFORK/NOEXEC tricks |
91 | 115 | ||
92 | FEATURE_SH_STANDALONE (needs FEATURE_PREFER_APPLETS=y) | 116 | //TODO: the above two things probably should have separate options? |
117 | |||
118 | FEATURE_SH_STANDALONE | ||
93 | shells will try to exec /proc/self/exe if command's name matches | 119 | shells will try to exec /proc/self/exe if command's name matches |
94 | some applet name | 120 | some applet name; shells will do NOEXEC trick on NOEXEC applets |
95 | shells will do NOEXEC trick on NOEXEC applets | 121 | |
122 | //TODO: split (same as for PREFER_APPLETS) | ||
96 | 123 | ||
97 | FEATURE_SH_NOFORK (needs FEATURE_PREFER_APPLETS=y) | 124 | FEATURE_SH_NOFORK |
98 | shells will do NOFORK trick on NOFORK applets | 125 | shells will do NOFORK trick on NOFORK applets |
diff --git a/e2fsprogs/fsck.c b/e2fsprogs/fsck.c index 6414988b4..eb53002b1 100644 --- a/e2fsprogs/fsck.c +++ b/e2fsprogs/fsck.c | |||
@@ -1071,7 +1071,7 @@ int fsck_main(int argc UNUSED_PARAM, char **argv) | |||
1071 | new_args(); /* G.args[G.num_args - 1] is the last, NULL element */ | 1071 | new_args(); /* G.args[G.num_args - 1] is the last, NULL element */ |
1072 | 1072 | ||
1073 | if (!notitle) | 1073 | if (!notitle) |
1074 | puts("fsck (busybox "BB_VER", "BB_BT")"); | 1074 | puts("fsck (busybox "BB_VER")"); |
1075 | 1075 | ||
1076 | /* Even plain "fsck /dev/hda1" needs fstab to get fs type, | 1076 | /* Even plain "fsck /dev/hda1" needs fstab to get fs type, |
1077 | * so we are scanning it anyway */ | 1077 | * so we are scanning it anyway */ |
diff --git a/editors/Config.src b/editors/Config.src index c6e9d92af..8f2b265bd 100644 --- a/editors/Config.src +++ b/editors/Config.src | |||
@@ -12,7 +12,7 @@ config FEATURE_ALLOW_EXEC | |||
12 | default y | 12 | default y |
13 | depends on VI || AWK | 13 | depends on VI || AWK |
14 | help | 14 | help |
15 | Enables vi and awk features which allows user to execute | 15 | Enables vi and awk features which allow user to execute |
16 | shell commands (using system() C call). | 16 | shell commands (using system() C call). |
17 | 17 | ||
18 | endmenu | 18 | endmenu |
diff --git a/editors/diff.c b/editors/diff.c index 0ae7e20b3..f2eeb8257 100644 --- a/editors/diff.c +++ b/editors/diff.c | |||
@@ -88,8 +88,6 @@ | |||
88 | //config: bool "Enable long options" | 88 | //config: bool "Enable long options" |
89 | //config: default y | 89 | //config: default y |
90 | //config: depends on DIFF && LONG_OPTS | 90 | //config: depends on DIFF && LONG_OPTS |
91 | //config: help | ||
92 | //config: Enable use of long options. | ||
93 | //config: | 91 | //config: |
94 | //config:config FEATURE_DIFF_DIR | 92 | //config:config FEATURE_DIFF_DIR |
95 | //config: bool "Enable directory support" | 93 | //config: bool "Enable directory support" |
diff --git a/editors/vi.c b/editors/vi.c index b81f2b92d..e5ca3adfa 100644 --- a/editors/vi.c +++ b/editors/vi.c | |||
@@ -30,7 +30,7 @@ | |||
30 | //config: you may wish to use something else. | 30 | //config: you may wish to use something else. |
31 | //config: | 31 | //config: |
32 | //config:config FEATURE_VI_MAX_LEN | 32 | //config:config FEATURE_VI_MAX_LEN |
33 | //config: int "Maximum screen width in vi" | 33 | //config: int "Maximum screen width" |
34 | //config: range 256 16384 | 34 | //config: range 256 16384 |
35 | //config: default 4096 | 35 | //config: default 4096 |
36 | //config: depends on VI | 36 | //config: depends on VI |
@@ -39,7 +39,7 @@ | |||
39 | //config: Make it smaller than 4k only if you are very limited on memory. | 39 | //config: Make it smaller than 4k only if you are very limited on memory. |
40 | //config: | 40 | //config: |
41 | //config:config FEATURE_VI_8BIT | 41 | //config:config FEATURE_VI_8BIT |
42 | //config: bool "Allow vi to display 8-bit chars (otherwise shows dots)" | 42 | //config: bool "Allow to display 8-bit chars (otherwise shows dots)" |
43 | //config: default n | 43 | //config: default n |
44 | //config: depends on VI | 44 | //config: depends on VI |
45 | //config: help | 45 | //config: help |
@@ -53,7 +53,7 @@ | |||
53 | //config: default y | 53 | //config: default y |
54 | //config: depends on VI | 54 | //config: depends on VI |
55 | //config: help | 55 | //config: help |
56 | //config: Enable a limited set of colon commands for vi. This does not | 56 | //config: Enable a limited set of colon commands. This does not |
57 | //config: provide an "ex" mode. | 57 | //config: provide an "ex" mode. |
58 | //config: | 58 | //config: |
59 | //config:config FEATURE_VI_YANKMARK | 59 | //config:config FEATURE_VI_YANKMARK |
@@ -61,16 +61,14 @@ | |||
61 | //config: default y | 61 | //config: default y |
62 | //config: depends on VI | 62 | //config: depends on VI |
63 | //config: help | 63 | //config: help |
64 | //config: This will enable you to use yank and put, as well as mark in | 64 | //config: This will enable you to use yank and put, as well as mark. |
65 | //config: busybox vi. | ||
66 | //config: | 65 | //config: |
67 | //config:config FEATURE_VI_SEARCH | 66 | //config:config FEATURE_VI_SEARCH |
68 | //config: bool "Enable search and replace cmds" | 67 | //config: bool "Enable search and replace cmds" |
69 | //config: default y | 68 | //config: default y |
70 | //config: depends on VI | 69 | //config: depends on VI |
71 | //config: help | 70 | //config: help |
72 | //config: Select this if you wish to be able to do search and replace in | 71 | //config: Select this if you wish to be able to do search and replace. |
73 | //config: busybox vi. | ||
74 | //config: | 72 | //config: |
75 | //config:config FEATURE_VI_REGEX_SEARCH | 73 | //config:config FEATURE_VI_REGEX_SEARCH |
76 | //config: bool "Enable regex in search and replace" | 74 | //config: bool "Enable regex in search and replace" |
@@ -84,16 +82,15 @@ | |||
84 | //config: default y | 82 | //config: default y |
85 | //config: depends on VI | 83 | //config: depends on VI |
86 | //config: help | 84 | //config: help |
87 | //config: Selecting this option will make busybox vi signal aware. This will | 85 | //config: Selecting this option will make vi signal aware. This will support |
88 | //config: make busybox vi support SIGWINCH to deal with Window Changes, catch | 86 | //config: SIGWINCH to deal with Window Changes, catch ^Z and ^C and alarms. |
89 | //config: Ctrl-Z and Ctrl-C and alarms. | ||
90 | //config: | 87 | //config: |
91 | //config:config FEATURE_VI_DOT_CMD | 88 | //config:config FEATURE_VI_DOT_CMD |
92 | //config: bool "Remember previous cmd and \".\" cmd" | 89 | //config: bool "Remember previous cmd and \".\" cmd" |
93 | //config: default y | 90 | //config: default y |
94 | //config: depends on VI | 91 | //config: depends on VI |
95 | //config: help | 92 | //config: help |
96 | //config: Make busybox vi remember the last command and be able to repeat it. | 93 | //config: Make vi remember the last command and be able to repeat it. |
97 | //config: | 94 | //config: |
98 | //config:config FEATURE_VI_READONLY | 95 | //config:config FEATURE_VI_READONLY |
99 | //config: bool "Enable -R option and \"view\" mode" | 96 | //config: bool "Enable -R option and \"view\" mode" |
@@ -104,25 +101,23 @@ | |||
104 | //config: open a file in read-only mode. | 101 | //config: open a file in read-only mode. |
105 | //config: | 102 | //config: |
106 | //config:config FEATURE_VI_SETOPTS | 103 | //config:config FEATURE_VI_SETOPTS |
107 | //config: bool "Enable set-able options, ai ic showmatch" | 104 | //config: bool "Enable settable options, ai ic showmatch" |
108 | //config: default y | 105 | //config: default y |
109 | //config: depends on VI | 106 | //config: depends on VI |
110 | //config: help | 107 | //config: help |
111 | //config: Enable the editor to set some (ai, ic, showmatch) options. | 108 | //config: Enable the editor to set some (ai, ic, showmatch) options. |
112 | //config: | 109 | //config: |
113 | //config:config FEATURE_VI_SET | 110 | //config:config FEATURE_VI_SET |
114 | //config: bool "Support for :set" | 111 | //config: bool "Support :set" |
115 | //config: default y | 112 | //config: default y |
116 | //config: depends on VI | 113 | //config: depends on VI |
117 | //config: help | ||
118 | //config: Support for ":set". | ||
119 | //config: | 114 | //config: |
120 | //config:config FEATURE_VI_WIN_RESIZE | 115 | //config:config FEATURE_VI_WIN_RESIZE |
121 | //config: bool "Handle window resize" | 116 | //config: bool "Handle window resize" |
122 | //config: default y | 117 | //config: default y |
123 | //config: depends on VI | 118 | //config: depends on VI |
124 | //config: help | 119 | //config: help |
125 | //config: Make busybox vi behave nicely with terminals that get resized. | 120 | //config: Behave nicely with terminals that get resized. |
126 | //config: | 121 | //config: |
127 | //config:config FEATURE_VI_ASK_TERMINAL | 122 | //config:config FEATURE_VI_ASK_TERMINAL |
128 | //config: bool "Use 'tell me cursor position' ESC sequence to measure window" | 123 | //config: bool "Use 'tell me cursor position' ESC sequence to measure window" |
@@ -133,15 +128,16 @@ | |||
133 | //config: this option makes vi perform a last-ditch effort to find it: | 128 | //config: this option makes vi perform a last-ditch effort to find it: |
134 | //config: position cursor to 999,999 and ask terminal to report real | 129 | //config: position cursor to 999,999 and ask terminal to report real |
135 | //config: cursor position using "ESC [ 6 n" escape sequence, then read stdin. | 130 | //config: cursor position using "ESC [ 6 n" escape sequence, then read stdin. |
136 | //config: | ||
137 | //config: This is not clean but helps a lot on serial lines and such. | 131 | //config: This is not clean but helps a lot on serial lines and such. |
132 | //config: | ||
138 | //config:config FEATURE_VI_UNDO | 133 | //config:config FEATURE_VI_UNDO |
139 | //config: bool "Support undo command 'u'" | 134 | //config: bool "Support undo command \"u\"" |
140 | //config: default y | 135 | //config: default y |
141 | //config: depends on VI | 136 | //config: depends on VI |
142 | //config: help | 137 | //config: help |
143 | //config: Support the 'u' command to undo insertion, deletion, and replacement | 138 | //config: Support the 'u' command to undo insertion, deletion, and replacement |
144 | //config: of text. | 139 | //config: of text. |
140 | //config: | ||
145 | //config:config FEATURE_VI_UNDO_QUEUE | 141 | //config:config FEATURE_VI_UNDO_QUEUE |
146 | //config: bool "Enable undo operation queuing" | 142 | //config: bool "Enable undo operation queuing" |
147 | //config: default y | 143 | //config: default y |
@@ -152,6 +148,7 @@ | |||
152 | //config: reached, the contents of the queue are committed to the undo stack. | 148 | //config: reached, the contents of the queue are committed to the undo stack. |
153 | //config: This increases the size of the undo code and allows some undo | 149 | //config: This increases the size of the undo code and allows some undo |
154 | //config: operations (especially un-typing/backspacing) to be far more useful. | 150 | //config: operations (especially un-typing/backspacing) to be far more useful. |
151 | //config: | ||
155 | //config:config FEATURE_VI_UNDO_QUEUE_MAX | 152 | //config:config FEATURE_VI_UNDO_QUEUE_MAX |
156 | //config: int "Maximum undo character queue size" | 153 | //config: int "Maximum undo character queue size" |
157 | //config: default 256 | 154 | //config: default 256 |
@@ -357,7 +354,7 @@ struct globals { | |||
357 | #if ENABLE_FEATURE_VI_USE_SIGNALS | 354 | #if ENABLE_FEATURE_VI_USE_SIGNALS |
358 | sigjmp_buf restart; // catch_sig() | 355 | sigjmp_buf restart; // catch_sig() |
359 | #endif | 356 | #endif |
360 | struct termios term_orig, term_vi; // remember what the cooked mode was | 357 | struct termios term_orig; // remember what the cooked mode was |
361 | #if ENABLE_FEATURE_VI_COLON | 358 | #if ENABLE_FEATURE_VI_COLON |
362 | char *initial_cmds[3]; // currently 2 entries, NULL terminated | 359 | char *initial_cmds[3]; // currently 2 entries, NULL terminated |
363 | #endif | 360 | #endif |
@@ -465,7 +462,6 @@ struct globals { | |||
465 | #define context_end (G.context_end ) | 462 | #define context_end (G.context_end ) |
466 | #define restart (G.restart ) | 463 | #define restart (G.restart ) |
467 | #define term_orig (G.term_orig ) | 464 | #define term_orig (G.term_orig ) |
468 | #define term_vi (G.term_vi ) | ||
469 | #define initial_cmds (G.initial_cmds ) | 465 | #define initial_cmds (G.initial_cmds ) |
470 | #define readbuffer (G.readbuffer ) | 466 | #define readbuffer (G.readbuffer ) |
471 | #define scr_out_buf (G.scr_out_buf ) | 467 | #define scr_out_buf (G.scr_out_buf ) |
@@ -1461,7 +1457,7 @@ static void colon(char *buf) | |||
1461 | } | 1457 | } |
1462 | #endif /* FEATURE_VI_SEARCH */ | 1458 | #endif /* FEATURE_VI_SEARCH */ |
1463 | } else if (strncmp(cmd, "version", i) == 0) { // show software version | 1459 | } else if (strncmp(cmd, "version", i) == 0) { // show software version |
1464 | status_line(BB_VER " " BB_BT); | 1460 | status_line(BB_VER); |
1465 | } else if (strncmp(cmd, "write", i) == 0 // write text to file | 1461 | } else if (strncmp(cmd, "write", i) == 0 // write text to file |
1466 | || strncmp(cmd, "wq", i) == 0 | 1462 | || strncmp(cmd, "wq", i) == 0 |
1467 | || strncmp(cmd, "wn", i) == 0 | 1463 | || strncmp(cmd, "wn", i) == 0 |
@@ -2734,15 +2730,9 @@ static char *swap_context(char *p) // goto new context for '' command make this | |||
2734 | //----- Set terminal attributes -------------------------------- | 2730 | //----- Set terminal attributes -------------------------------- |
2735 | static void rawmode(void) | 2731 | static void rawmode(void) |
2736 | { | 2732 | { |
2737 | tcgetattr(0, &term_orig); | 2733 | // no TERMIOS_CLEAR_ISIG: leave ISIG on - allow signals |
2738 | term_vi = term_orig; | 2734 | set_termios_to_raw(STDIN_FILENO, &term_orig, TERMIOS_RAW_CRNL); |
2739 | term_vi.c_lflag &= (~ICANON & ~ECHO); // leave ISIG on - allow intr's | 2735 | erase_char = term_orig.c_cc[VERASE]; |
2740 | term_vi.c_iflag &= (~IXON & ~ICRNL); | ||
2741 | term_vi.c_oflag &= (~ONLCR); | ||
2742 | term_vi.c_cc[VMIN] = 1; | ||
2743 | term_vi.c_cc[VTIME] = 0; | ||
2744 | erase_char = term_vi.c_cc[VERASE]; | ||
2745 | tcsetattr_stdin_TCSANOW(&term_vi); | ||
2746 | } | 2736 | } |
2747 | 2737 | ||
2748 | static void cookmode(void) | 2738 | static void cookmode(void) |
diff --git a/examples/depmod b/examples/depmod index d769590d0..8d421c6ab 100755 --- a/examples/depmod +++ b/examples/depmod | |||
@@ -7,7 +7,7 @@ | |||
7 | # Licensed under GPLv2, see file LICENSE in this source tree. | 7 | # Licensed under GPLv2, see file LICENSE in this source tree. |
8 | # | 8 | # |
9 | 9 | ||
10 | local BASE="${1:-/usr/lib/modules}" | 10 | BASE="${1:-/usr/lib/modules}" |
11 | 11 | ||
12 | find "$BASE" -name '*.ko.gz' | while read I ; do | 12 | find "$BASE" -name '*.ko.gz' | while read I ; do |
13 | N=`basename "$I" '.ko.gz'` | 13 | N=`basename "$I" '.ko.gz'` |
diff --git a/findutils/find.c b/findutils/find.c index 27698e537..67aa40b21 100644 --- a/findutils/find.c +++ b/findutils/find.c | |||
@@ -89,8 +89,6 @@ | |||
89 | //config: bool "Enable -perm: permissions matching" | 89 | //config: bool "Enable -perm: permissions matching" |
90 | //config: default y | 90 | //config: default y |
91 | //config: depends on FIND | 91 | //config: depends on FIND |
92 | //config: help | ||
93 | //config: Enable searching based on file permissions. | ||
94 | //config: | 92 | //config: |
95 | //config:config FEATURE_FIND_TYPE | 93 | //config:config FEATURE_FIND_TYPE |
96 | //config: bool "Enable -type: file type matching (file/dir/link/...)" | 94 | //config: bool "Enable -type: file type matching (file/dir/link/...)" |
@@ -104,15 +102,11 @@ | |||
104 | //config: bool "Enable -xdev: 'stay in filesystem'" | 102 | //config: bool "Enable -xdev: 'stay in filesystem'" |
105 | //config: default y | 103 | //config: default y |
106 | //config: depends on FIND | 104 | //config: depends on FIND |
107 | //config: help | ||
108 | //config: This option allows find to restrict searches to a single filesystem. | ||
109 | //config: | 105 | //config: |
110 | //config:config FEATURE_FIND_MAXDEPTH | 106 | //config:config FEATURE_FIND_MAXDEPTH |
111 | //config: bool "Enable -mindepth N and -maxdepth N" | 107 | //config: bool "Enable -mindepth N and -maxdepth N" |
112 | //config: default y | 108 | //config: default y |
113 | //config: depends on FIND | 109 | //config: depends on FIND |
114 | //config: help | ||
115 | //config: This option enables -mindepth N and -maxdepth N option. | ||
116 | //config: | 110 | //config: |
117 | //config:config FEATURE_FIND_NEWER | 111 | //config:config FEATURE_FIND_NEWER |
118 | //config: bool "Enable -newer: compare file modification times" | 112 | //config: bool "Enable -newer: compare file modification times" |
@@ -126,8 +120,6 @@ | |||
126 | //config: bool "Enable -inum: inode number matching" | 120 | //config: bool "Enable -inum: inode number matching" |
127 | //config: default y | 121 | //config: default y |
128 | //config: depends on FIND | 122 | //config: depends on FIND |
129 | //config: help | ||
130 | //config: Support the 'find -inum' option for searching by inode number. | ||
131 | //config: | 123 | //config: |
132 | //config:config FEATURE_FIND_EXEC | 124 | //config:config FEATURE_FIND_EXEC |
133 | //config: bool "Enable -exec: execute commands" | 125 | //config: bool "Enable -exec: execute commands" |
@@ -151,15 +143,11 @@ | |||
151 | //config: bool "Enable -user: username/uid matching" | 143 | //config: bool "Enable -user: username/uid matching" |
152 | //config: default y | 144 | //config: default y |
153 | //config: depends on FIND | 145 | //config: depends on FIND |
154 | //config: help | ||
155 | //config: Support the 'find -user' option for searching by username or uid. | ||
156 | //config: | 146 | //config: |
157 | //config:config FEATURE_FIND_GROUP | 147 | //config:config FEATURE_FIND_GROUP |
158 | //config: bool "Enable -group: group/gid matching" | 148 | //config: bool "Enable -group: group/gid matching" |
159 | //config: default y | 149 | //config: default y |
160 | //config: depends on FIND | 150 | //config: depends on FIND |
161 | //config: help | ||
162 | //config: Support the 'find -group' option for searching by group name or gid. | ||
163 | //config: | 151 | //config: |
164 | //config:config FEATURE_FIND_NOT | 152 | //config:config FEATURE_FIND_NOT |
165 | //config: bool "Enable the 'not' (!) operator" | 153 | //config: bool "Enable the 'not' (!) operator" |
@@ -188,8 +176,6 @@ | |||
188 | //config: bool "Enable -size: file size matching" | 176 | //config: bool "Enable -size: file size matching" |
189 | //config: default y | 177 | //config: default y |
190 | //config: depends on FIND | 178 | //config: depends on FIND |
191 | //config: help | ||
192 | //config: Support the 'find -size' option for searching by file size. | ||
193 | //config: | 179 | //config: |
194 | //config:config FEATURE_FIND_PRUNE | 180 | //config:config FEATURE_FIND_PRUNE |
195 | //config: bool "Enable -prune: exclude subdirectories" | 181 | //config: bool "Enable -prune: exclude subdirectories" |
diff --git a/findutils/grep.c b/findutils/grep.c index 9f84d529b..8b6e29874 100644 --- a/findutils/grep.c +++ b/findutils/grep.c | |||
@@ -46,6 +46,7 @@ | |||
46 | //config: Print the specified number of context lines (-C). | 46 | //config: Print the specified number of context lines (-C). |
47 | 47 | ||
48 | //applet:IF_GREP(APPLET(grep, BB_DIR_BIN, BB_SUID_DROP)) | 48 | //applet:IF_GREP(APPLET(grep, BB_DIR_BIN, BB_SUID_DROP)) |
49 | // APPLET_ODDNAME:name main location suid_type help | ||
49 | //applet:IF_EGREP(APPLET_ODDNAME(egrep, grep, BB_DIR_BIN, BB_SUID_DROP, egrep)) | 50 | //applet:IF_EGREP(APPLET_ODDNAME(egrep, grep, BB_DIR_BIN, BB_SUID_DROP, egrep)) |
50 | //applet:IF_FGREP(APPLET_ODDNAME(fgrep, grep, BB_DIR_BIN, BB_SUID_DROP, fgrep)) | 51 | //applet:IF_FGREP(APPLET_ODDNAME(fgrep, grep, BB_DIR_BIN, BB_SUID_DROP, fgrep)) |
51 | 52 | ||
diff --git a/include/libbb.h b/include/libbb.h index 0b9cfb585..1f5b211c1 100644 --- a/include/libbb.h +++ b/include/libbb.h | |||
@@ -366,6 +366,27 @@ extern char *skip_dev_pfx(const char *tty_name) FAST_FUNC; | |||
366 | 366 | ||
367 | extern char *strrstr(const char *haystack, const char *needle) FAST_FUNC; | 367 | extern char *strrstr(const char *haystack, const char *needle) FAST_FUNC; |
368 | 368 | ||
369 | /* dmalloc will redefine these to it's own implementation. It is safe | ||
370 | * to have the prototypes here unconditionally. */ | ||
371 | void *malloc_or_warn(size_t size) FAST_FUNC RETURNS_MALLOC; | ||
372 | void *xmalloc(size_t size) FAST_FUNC RETURNS_MALLOC; | ||
373 | void *xzalloc(size_t size) FAST_FUNC RETURNS_MALLOC; | ||
374 | void *xrealloc(void *old, size_t size) FAST_FUNC; | ||
375 | /* After v = xrealloc_vector(v, SHIFT, idx) it's ok to use | ||
376 | * at least v[idx] and v[idx+1], for all idx values. | ||
377 | * SHIFT specifies how many new elements are added (1:2, 2:4, ..., 8:256...) | ||
378 | * when all elements are used up. New elements are zeroed out. | ||
379 | * xrealloc_vector(v, SHIFT, idx) *MUST* be called with consecutive IDXs - | ||
380 | * skipping an index is a bad bug - it may miss a realloc! | ||
381 | */ | ||
382 | #define xrealloc_vector(vector, shift, idx) \ | ||
383 | xrealloc_vector_helper((vector), (sizeof((vector)[0]) << 8) + (shift), (idx)) | ||
384 | void* xrealloc_vector_helper(void *vector, unsigned sizeof_and_shift, int idx) FAST_FUNC; | ||
385 | char *xstrdup(const char *s) FAST_FUNC RETURNS_MALLOC; | ||
386 | char *xstrndup(const char *s, int n) FAST_FUNC RETURNS_MALLOC; | ||
387 | void *xmemdup(const void *s, int n) FAST_FUNC RETURNS_MALLOC; | ||
388 | |||
389 | |||
369 | //TODO: supply a pointer to char[11] buffer (avoid statics)? | 390 | //TODO: supply a pointer to char[11] buffer (avoid statics)? |
370 | extern const char *bb_mode_string(mode_t mode) FAST_FUNC; | 391 | extern const char *bb_mode_string(mode_t mode) FAST_FUNC; |
371 | extern int is_directory(const char *name, int followLinks) FAST_FUNC; | 392 | extern int is_directory(const char *name, int followLinks) FAST_FUNC; |
@@ -709,6 +730,56 @@ struct hostent *xgethostbyname(const char *name) FAST_FUNC; | |||
709 | // + inet_common.c has additional IPv4-only stuff | 730 | // + inet_common.c has additional IPv4-only stuff |
710 | 731 | ||
711 | 732 | ||
733 | #define TLS_MAX_MAC_SIZE 32 | ||
734 | #define TLS_MAX_KEY_SIZE 32 | ||
735 | struct tls_handshake_data; /* opaque */ | ||
736 | typedef struct tls_state { | ||
737 | int ofd; | ||
738 | int ifd; | ||
739 | |||
740 | unsigned min_encrypted_len_on_read; | ||
741 | uint16_t cipher_id; | ||
742 | uint8_t encrypt_on_write; | ||
743 | unsigned MAC_size; | ||
744 | unsigned key_size; | ||
745 | |||
746 | uint8_t *outbuf; | ||
747 | int outbuf_size; | ||
748 | |||
749 | int inbuf_size; | ||
750 | int ofs_to_buffered; | ||
751 | int buffered_size; | ||
752 | uint8_t *inbuf; | ||
753 | |||
754 | struct tls_handshake_data *hsd; | ||
755 | |||
756 | // RFC 5246 | ||
757 | // sequence number | ||
758 | // Each connection state contains a sequence number, which is | ||
759 | // maintained separately for read and write states. The sequence | ||
760 | // number MUST be set to zero whenever a connection state is made the | ||
761 | // active state. Sequence numbers are of type uint64 and may not | ||
762 | // exceed 2^64-1. | ||
763 | /*uint64_t read_seq64_be;*/ | ||
764 | uint64_t write_seq64_be; | ||
765 | |||
766 | uint8_t *client_write_key; | ||
767 | uint8_t *server_write_key; | ||
768 | uint8_t client_write_MAC_key[TLS_MAX_MAC_SIZE]; | ||
769 | uint8_t server_write_MAC_k__[TLS_MAX_MAC_SIZE]; | ||
770 | uint8_t client_write_k__[TLS_MAX_KEY_SIZE]; | ||
771 | uint8_t server_write_k__[TLS_MAX_KEY_SIZE]; | ||
772 | } tls_state_t; | ||
773 | |||
774 | static inline tls_state_t *new_tls_state(void) | ||
775 | { | ||
776 | tls_state_t *tls = xzalloc(sizeof(*tls)); | ||
777 | return tls; | ||
778 | } | ||
779 | void tls_handshake(tls_state_t *tls, const char *sni) FAST_FUNC; | ||
780 | void tls_run_copy_loop(tls_state_t *tls) FAST_FUNC; | ||
781 | |||
782 | |||
712 | void socket_want_pktinfo(int fd) FAST_FUNC; | 783 | void socket_want_pktinfo(int fd) FAST_FUNC; |
713 | ssize_t send_to_from(int fd, void *buf, size_t len, int flags, | 784 | ssize_t send_to_from(int fd, void *buf, size_t len, int flags, |
714 | const struct sockaddr *to, | 785 | const struct sockaddr *to, |
@@ -721,9 +792,6 @@ ssize_t recv_from_to(int fd, void *buf, size_t len, int flags, | |||
721 | 792 | ||
722 | uint16_t inet_cksum(uint16_t *addr, int len) FAST_FUNC; | 793 | uint16_t inet_cksum(uint16_t *addr, int len) FAST_FUNC; |
723 | 794 | ||
724 | char *xstrdup(const char *s) FAST_FUNC RETURNS_MALLOC; | ||
725 | char *xstrndup(const char *s, int n) FAST_FUNC RETURNS_MALLOC; | ||
726 | void *xmemdup(const void *s, int n) FAST_FUNC RETURNS_MALLOC; | ||
727 | void overlapping_strcpy(char *dst, const char *src) FAST_FUNC; | 795 | void overlapping_strcpy(char *dst, const char *src) FAST_FUNC; |
728 | char *safe_strncpy(char *dst, const char *src, size_t size) FAST_FUNC; | 796 | char *safe_strncpy(char *dst, const char *src, size_t size) FAST_FUNC; |
729 | char *strncpy_IFNAMSIZ(char *dst, const char *src) FAST_FUNC; | 797 | char *strncpy_IFNAMSIZ(char *dst, const char *src) FAST_FUNC; |
@@ -769,24 +837,6 @@ enum { | |||
769 | }; | 837 | }; |
770 | void visible(unsigned ch, char *buf, int flags) FAST_FUNC; | 838 | void visible(unsigned ch, char *buf, int flags) FAST_FUNC; |
771 | 839 | ||
772 | /* dmalloc will redefine these to it's own implementation. It is safe | ||
773 | * to have the prototypes here unconditionally. */ | ||
774 | void *malloc_or_warn(size_t size) FAST_FUNC RETURNS_MALLOC; | ||
775 | void *xmalloc(size_t size) FAST_FUNC RETURNS_MALLOC; | ||
776 | void *xzalloc(size_t size) FAST_FUNC RETURNS_MALLOC; | ||
777 | void *xrealloc(void *old, size_t size) FAST_FUNC; | ||
778 | /* After v = xrealloc_vector(v, SHIFT, idx) it's ok to use | ||
779 | * at least v[idx] and v[idx+1], for all idx values. | ||
780 | * SHIFT specifies how many new elements are added (1:2, 2:4, ..., 8:256...) | ||
781 | * when all elements are used up. New elements are zeroed out. | ||
782 | * xrealloc_vector(v, SHIFT, idx) *MUST* be called with consecutive IDXs - | ||
783 | * skipping an index is a bad bug - it may miss a realloc! | ||
784 | */ | ||
785 | #define xrealloc_vector(vector, shift, idx) \ | ||
786 | xrealloc_vector_helper((vector), (sizeof((vector)[0]) << 8) + (shift), (idx)) | ||
787 | void* xrealloc_vector_helper(void *vector, unsigned sizeof_and_shift, int idx) FAST_FUNC; | ||
788 | |||
789 | |||
790 | extern ssize_t safe_read(int fd, void *buf, size_t count) FAST_FUNC; | 840 | extern ssize_t safe_read(int fd, void *buf, size_t count) FAST_FUNC; |
791 | extern ssize_t nonblock_immune_read(int fd, void *buf, size_t count) FAST_FUNC; | 841 | extern ssize_t nonblock_immune_read(int fd, void *buf, size_t count) FAST_FUNC; |
792 | // NB: will return short read on error, not -1, | 842 | // NB: will return short read on error, not -1, |
@@ -1062,10 +1112,19 @@ pid_t wait_any_nohang(int *wstat) FAST_FUNC; | |||
1062 | */ | 1112 | */ |
1063 | int wait4pid(pid_t pid) FAST_FUNC; | 1113 | int wait4pid(pid_t pid) FAST_FUNC; |
1064 | int wait_for_exitstatus(pid_t pid) FAST_FUNC; | 1114 | int wait_for_exitstatus(pid_t pid) FAST_FUNC; |
1115 | /************************************************************************/ | ||
1116 | /* spawn_and_wait/run_nofork_applet/run_applet_no_and_exit need to work */ | ||
1117 | /* carefully together to reinit some global state while not disturbing */ | ||
1118 | /* other. Be careful if you change them. Consult docs/nofork_noexec.txt */ | ||
1119 | /************************************************************************/ | ||
1065 | /* Same as wait4pid(spawn(argv)), but with NOFORK/NOEXEC if configured: */ | 1120 | /* Same as wait4pid(spawn(argv)), but with NOFORK/NOEXEC if configured: */ |
1066 | int spawn_and_wait(char **argv) FAST_FUNC; | 1121 | int spawn_and_wait(char **argv) FAST_FUNC; |
1067 | /* Does NOT check that applet is NOFORK, just blindly runs it */ | 1122 | /* Does NOT check that applet is NOFORK, just blindly runs it */ |
1068 | int run_nofork_applet(int applet_no, char **argv) FAST_FUNC; | 1123 | int run_nofork_applet(int applet_no, char **argv) FAST_FUNC; |
1124 | #ifndef BUILD_INDIVIDUAL | ||
1125 | extern int find_applet_by_name(const char *name) FAST_FUNC; | ||
1126 | extern void run_applet_no_and_exit(int a, char **argv) NORETURN FAST_FUNC; | ||
1127 | #endif | ||
1069 | 1128 | ||
1070 | /* Helpers for daemonization. | 1129 | /* Helpers for daemonization. |
1071 | * | 1130 | * |
@@ -1272,13 +1331,8 @@ const struct hwtype *get_hwtype(const char *name) FAST_FUNC; | |||
1272 | const struct hwtype *get_hwntype(int type) FAST_FUNC; | 1331 | const struct hwtype *get_hwntype(int type) FAST_FUNC; |
1273 | 1332 | ||
1274 | 1333 | ||
1275 | #ifndef BUILD_INDIVIDUAL | 1334 | extern int fstype_matches(const char *fstype, const char *comma_list) FAST_FUNC; |
1276 | extern int find_applet_by_name(const char *name) FAST_FUNC; | ||
1277 | extern void run_applet_no_and_exit(int a, char **argv) NORETURN FAST_FUNC; | ||
1278 | #endif | ||
1279 | |||
1280 | #ifdef HAVE_MNTENT_H | 1335 | #ifdef HAVE_MNTENT_H |
1281 | extern int match_fstype(const struct mntent *mt, const char *fstypes) FAST_FUNC; | ||
1282 | extern struct mntent *find_mount_point(const char *name, int subdir_too) FAST_FUNC; | 1336 | extern struct mntent *find_mount_point(const char *name, int subdir_too) FAST_FUNC; |
1283 | #endif | 1337 | #endif |
1284 | extern void erase_mtab(const char * name) FAST_FUNC; | 1338 | extern void erase_mtab(const char * name) FAST_FUNC; |
@@ -1457,6 +1511,10 @@ int get_terminal_width_height(int fd, unsigned *width, unsigned *height) FAST_FU | |||
1457 | int get_terminal_width(int fd) FAST_FUNC; | 1511 | int get_terminal_width(int fd) FAST_FUNC; |
1458 | 1512 | ||
1459 | int tcsetattr_stdin_TCSANOW(const struct termios *tp) FAST_FUNC; | 1513 | int tcsetattr_stdin_TCSANOW(const struct termios *tp) FAST_FUNC; |
1514 | #define TERMIOS_CLEAR_ISIG (1 << 0) | ||
1515 | #define TERMIOS_RAW_CRNL (1 << 1) | ||
1516 | #define TERMIOS_RAW_INPUT (1 << 2) | ||
1517 | int set_termios_to_raw(int fd, struct termios *oldterm, int flags) FAST_FUNC; | ||
1460 | 1518 | ||
1461 | /* NB: "unsigned request" is crucial! "int request" will break some arches! */ | 1519 | /* NB: "unsigned request" is crucial! "int request" will break some arches! */ |
1462 | int ioctl_or_perror(int fd, unsigned request, void *argp, const char *fmt,...) __attribute__ ((format (printf, 4, 5))) FAST_FUNC; | 1520 | int ioctl_or_perror(int fd, unsigned request, void *argp, const char *fmt,...) __attribute__ ((format (printf, 4, 5))) FAST_FUNC; |
@@ -1775,19 +1833,23 @@ typedef struct sha3_ctx_t { | |||
1775 | } sha3_ctx_t; | 1833 | } sha3_ctx_t; |
1776 | void md5_begin(md5_ctx_t *ctx) FAST_FUNC; | 1834 | void md5_begin(md5_ctx_t *ctx) FAST_FUNC; |
1777 | void md5_hash(md5_ctx_t *ctx, const void *buffer, size_t len) FAST_FUNC; | 1835 | void md5_hash(md5_ctx_t *ctx, const void *buffer, size_t len) FAST_FUNC; |
1778 | void md5_end(md5_ctx_t *ctx, void *resbuf) FAST_FUNC; | 1836 | unsigned md5_end(md5_ctx_t *ctx, void *resbuf) FAST_FUNC; |
1779 | void sha1_begin(sha1_ctx_t *ctx) FAST_FUNC; | 1837 | void sha1_begin(sha1_ctx_t *ctx) FAST_FUNC; |
1780 | #define sha1_hash md5_hash | 1838 | #define sha1_hash md5_hash |
1781 | void sha1_end(sha1_ctx_t *ctx, void *resbuf) FAST_FUNC; | 1839 | unsigned sha1_end(sha1_ctx_t *ctx, void *resbuf) FAST_FUNC; |
1782 | void sha256_begin(sha256_ctx_t *ctx) FAST_FUNC; | 1840 | void sha256_begin(sha256_ctx_t *ctx) FAST_FUNC; |
1783 | #define sha256_hash md5_hash | 1841 | #define sha256_hash md5_hash |
1784 | #define sha256_end sha1_end | 1842 | #define sha256_end sha1_end |
1785 | void sha512_begin(sha512_ctx_t *ctx) FAST_FUNC; | 1843 | void sha512_begin(sha512_ctx_t *ctx) FAST_FUNC; |
1786 | void sha512_hash(sha512_ctx_t *ctx, const void *buffer, size_t len) FAST_FUNC; | 1844 | void sha512_hash(sha512_ctx_t *ctx, const void *buffer, size_t len) FAST_FUNC; |
1787 | void sha512_end(sha512_ctx_t *ctx, void *resbuf) FAST_FUNC; | 1845 | unsigned sha512_end(sha512_ctx_t *ctx, void *resbuf) FAST_FUNC; |
1788 | void sha3_begin(sha3_ctx_t *ctx) FAST_FUNC; | 1846 | void sha3_begin(sha3_ctx_t *ctx) FAST_FUNC; |
1789 | void sha3_hash(sha3_ctx_t *ctx, const void *buffer, size_t len) FAST_FUNC; | 1847 | void sha3_hash(sha3_ctx_t *ctx, const void *buffer, size_t len) FAST_FUNC; |
1790 | void sha3_end(sha3_ctx_t *ctx, void *resbuf) FAST_FUNC; | 1848 | unsigned sha3_end(sha3_ctx_t *ctx, void *resbuf) FAST_FUNC; |
1849 | /* TLS benefits from knowing that sha1 and sha256 share these. Give them "agnostic" names too */ | ||
1850 | typedef struct md5_ctx_t md5sha_ctx_t; | ||
1851 | #define md5sha_hash md5_hash | ||
1852 | #define sha_end sha1_end | ||
1791 | 1853 | ||
1792 | extern uint32_t *global_crc32_table; | 1854 | extern uint32_t *global_crc32_table; |
1793 | uint32_t *crc32_filltable(uint32_t *tbl256, int endian) FAST_FUNC; | 1855 | uint32_t *crc32_filltable(uint32_t *tbl256, int endian) FAST_FUNC; |
diff --git a/include/platform.h b/include/platform.h index 94368539e..13f818202 100644 --- a/include/platform.h +++ b/include/platform.h | |||
@@ -117,13 +117,18 @@ | |||
117 | * and/or smaller by using modified ABI. It is usually only needed | 117 | * and/or smaller by using modified ABI. It is usually only needed |
118 | * on non-static, busybox internal functions. Recent versions of gcc | 118 | * on non-static, busybox internal functions. Recent versions of gcc |
119 | * optimize statics automatically. FAST_FUNC on static is required | 119 | * optimize statics automatically. FAST_FUNC on static is required |
120 | * only if you need to match a function pointer's type */ | 120 | * only if you need to match a function pointer's type. |
121 | #if __GNUC_PREREQ(3,0) && defined(i386) /* || defined(__x86_64__)? */ | 121 | * FAST_FUNC may not work well with -flto so allow user to disable this. |
122 | * (-DFAST_FUNC= ) | ||
123 | */ | ||
124 | #ifndef FAST_FUNC | ||
125 | # if __GNUC_PREREQ(3,0) && defined(i386) | ||
122 | /* stdcall makes callee to pop arguments from stack, not caller */ | 126 | /* stdcall makes callee to pop arguments from stack, not caller */ |
123 | # define FAST_FUNC __attribute__((regparm(3),stdcall)) | 127 | # define FAST_FUNC __attribute__((regparm(3),stdcall)) |
124 | /* #elif ... - add your favorite arch today! */ | 128 | /* #elif ... - add your favorite arch today! */ |
125 | #else | 129 | # else |
126 | # define FAST_FUNC | 130 | # define FAST_FUNC |
131 | # endif | ||
127 | #endif | 132 | #endif |
128 | 133 | ||
129 | /* Make all declarations hidden (-fvisibility flag only affects definitions) */ | 134 | /* Make all declarations hidden (-fvisibility flag only affects definitions) */ |
diff --git a/include/usage.src.h b/include/usage.src.h index 78beccf4d..00369dfb3 100644 --- a/include/usage.src.h +++ b/include/usage.src.h | |||
@@ -14,6 +14,14 @@ | |||
14 | 14 | ||
15 | #define NOUSAGE_STR "\b" | 15 | #define NOUSAGE_STR "\b" |
16 | 16 | ||
17 | #if !ENABLE_USE_BB_CRYPT || ENABLE_USE_BB_CRYPT_SHA | ||
18 | # define CRYPT_METHODS_HELP_STR "des,md5,sha256/512" \ | ||
19 | " (default "CONFIG_FEATURE_DEFAULT_PASSWD_ALGO")" | ||
20 | #else | ||
21 | # define CRYPT_METHODS_HELP_STR "des,md5" \ | ||
22 | " (default "CONFIG_FEATURE_DEFAULT_PASSWD_ALGO")" | ||
23 | #endif | ||
24 | |||
17 | INSERT | 25 | INSERT |
18 | 26 | ||
19 | #define busybox_notes_usage \ | 27 | #define busybox_notes_usage \ |
diff --git a/init/halt.c b/init/halt.c index b7fb10869..f69b89772 100644 --- a/init/halt.c +++ b/init/halt.c | |||
@@ -46,8 +46,9 @@ | |||
46 | //config: locating telinit executable. | 46 | //config: locating telinit executable. |
47 | 47 | ||
48 | //applet:IF_HALT(APPLET(halt, BB_DIR_SBIN, BB_SUID_DROP)) | 48 | //applet:IF_HALT(APPLET(halt, BB_DIR_SBIN, BB_SUID_DROP)) |
49 | // APPLET_ODDNAME:name main location suid_type help | ||
49 | //applet:IF_POWEROFF(APPLET_ODDNAME(poweroff, halt, BB_DIR_SBIN, BB_SUID_DROP, poweroff)) | 50 | //applet:IF_POWEROFF(APPLET_ODDNAME(poweroff, halt, BB_DIR_SBIN, BB_SUID_DROP, poweroff)) |
50 | //applet:IF_REBOOT(APPLET_ODDNAME(reboot, halt, BB_DIR_SBIN, BB_SUID_DROP, reboot)) | 51 | //applet:IF_REBOOT( APPLET_ODDNAME(reboot, halt, BB_DIR_SBIN, BB_SUID_DROP, reboot)) |
51 | 52 | ||
52 | //kbuild:lib-$(CONFIG_HALT) += halt.o | 53 | //kbuild:lib-$(CONFIG_HALT) += halt.o |
53 | //kbuild:lib-$(CONFIG_POWEROFF) += halt.o | 54 | //kbuild:lib-$(CONFIG_POWEROFF) += halt.o |
diff --git a/init/init.c b/init/init.c index 08cfa2f8c..833759341 100644 --- a/init/init.c +++ b/init/init.c | |||
@@ -17,7 +17,7 @@ | |||
17 | //config: init is the first program run when the system boots. | 17 | //config: init is the first program run when the system boots. |
18 | //config: | 18 | //config: |
19 | //config:config LINUXRC | 19 | //config:config LINUXRC |
20 | //config: bool "Support running init from within an initrd (not initramfs)" | 20 | //config: bool "linuxrc: support running init from initrd (not initramfs)" |
21 | //config: default y | 21 | //config: default y |
22 | //config: select FEATURE_SYSLOG | 22 | //config: select FEATURE_SYSLOG |
23 | //config: help | 23 | //config: help |
@@ -74,12 +74,10 @@ | |||
74 | //config: default y | 74 | //config: default y |
75 | //config: depends on INIT || LINUXRC | 75 | //config: depends on INIT || LINUXRC |
76 | //config: | 76 | //config: |
77 | //config:config FEATURE_EXTRA_QUIET | 77 | //config:config FEATURE_INIT_QUIET |
78 | //config: bool "Be _extra_ quiet on boot" | 78 | //config: bool "Be quiet on boot (no 'init started:' message)" |
79 | //config: default y | 79 | //config: default y |
80 | //config: depends on INIT || LINUXRC | 80 | //config: depends on INIT || LINUXRC |
81 | //config: help | ||
82 | //config: Prevent init from logging some messages to the console during boot. | ||
83 | //config: | 81 | //config: |
84 | //config:config FEATURE_INIT_COREDUMPS | 82 | //config:config FEATURE_INIT_COREDUMPS |
85 | //config: bool "Support dumping core for child processes (debugging only)" | 83 | //config: bool "Support dumping core for child processes (debugging only)" |
@@ -104,13 +102,13 @@ | |||
104 | //config: sets TERM to "vt102" if one is found. | 102 | //config: sets TERM to "vt102" if one is found. |
105 | //config: | 103 | //config: |
106 | //config:config FEATURE_INIT_MODIFY_CMDLINE | 104 | //config:config FEATURE_INIT_MODIFY_CMDLINE |
107 | //config: bool "Modify the command-line to \"init\"" | 105 | //config: bool "Clear init's command line" |
108 | //config: default y | 106 | //config: default y |
109 | //config: depends on INIT || LINUXRC | 107 | //config: depends on INIT || LINUXRC |
110 | //config: help | 108 | //config: help |
111 | //config: When launched as PID 1 and after parsing its arguments, init | 109 | //config: When launched as PID 1 and after parsing its arguments, init |
112 | //config: wipes all the arguments but argv[0] and rewrites argv[0] to | 110 | //config: wipes all the arguments but argv[0] and rewrites argv[0] to |
113 | //config: contain only "init", so that its command-line appears solely as | 111 | //config: contain only "init", so that its command line appears solely as |
114 | //config: "init" in tools such as ps. | 112 | //config: "init" in tools such as ps. |
115 | //config: If this option is set to Y, init will keep its original behavior, | 113 | //config: If this option is set to Y, init will keep its original behavior, |
116 | //config: otherwise, all the arguments including argv[0] will be preserved, | 114 | //config: otherwise, all the arguments including argv[0] will be preserved, |
@@ -1098,7 +1096,7 @@ int init_main(int argc UNUSED_PARAM, char **argv) | |||
1098 | if (argv[1]) | 1096 | if (argv[1]) |
1099 | xsetenv("RUNLEVEL", argv[1]); | 1097 | xsetenv("RUNLEVEL", argv[1]); |
1100 | 1098 | ||
1101 | #if !ENABLE_FEATURE_EXTRA_QUIET | 1099 | #if !ENABLE_FEATURE_INIT_QUIET |
1102 | /* Hello world */ | 1100 | /* Hello world */ |
1103 | message(L_CONSOLE | L_LOG, "init started: %s", bb_banner); | 1101 | message(L_CONSOLE | L_LOG, "init started: %s", bb_banner); |
1104 | #endif | 1102 | #endif |
diff --git a/libbb/Config.src b/libbb/Config.src index 172fbcc0e..c51640305 100644 --- a/libbb/Config.src +++ b/libbb/Config.src | |||
@@ -70,24 +70,13 @@ config FEATURE_FAST_TOP | |||
70 | but code size is slightly bigger. | 70 | but code size is slightly bigger. |
71 | 71 | ||
72 | config FEATURE_ETC_NETWORKS | 72 | config FEATURE_ETC_NETWORKS |
73 | bool "Support for /etc/networks" | 73 | bool "Support /etc/networks" |
74 | default n | 74 | default n |
75 | help | 75 | help |
76 | Enable support for network names in /etc/networks. This is | 76 | Enable support for network names in /etc/networks. This is |
77 | a rarely used feature which allows you to use names | 77 | a rarely used feature which allows you to use names |
78 | instead of IP/mask pairs in route command. | 78 | instead of IP/mask pairs in route command. |
79 | 79 | ||
80 | config FEATURE_USE_TERMIOS | ||
81 | bool "Use termios to manipulate the screen" | ||
82 | default y | ||
83 | depends on MORE || TOP || POWERTOP | ||
84 | help | ||
85 | This option allows utilities such as 'more' and 'top' to determine | ||
86 | the size of the screen. If you leave this disabled, your utilities | ||
87 | that display things on the screen will be especially primitive and | ||
88 | will be unable to determine the current screen size, and will be | ||
89 | unable to move the cursor. | ||
90 | |||
91 | config FEATURE_EDITING | 80 | config FEATURE_EDITING |
92 | bool "Command line editing" | 81 | bool "Command line editing" |
93 | default y | 82 | default y |
@@ -147,15 +136,11 @@ config FEATURE_TAB_COMPLETION | |||
147 | bool "Tab completion" | 136 | bool "Tab completion" |
148 | default y | 137 | default y |
149 | depends on FEATURE_EDITING | 138 | depends on FEATURE_EDITING |
150 | help | ||
151 | Enable tab completion. | ||
152 | 139 | ||
153 | config FEATURE_USERNAME_COMPLETION | 140 | config FEATURE_USERNAME_COMPLETION |
154 | bool "Username completion" | 141 | bool "Username completion" |
155 | default y | 142 | default y |
156 | depends on FEATURE_TAB_COMPLETION | 143 | depends on FEATURE_TAB_COMPLETION |
157 | help | ||
158 | Enable username completion. | ||
159 | 144 | ||
160 | config FEATURE_EDITING_FANCY_PROMPT | 145 | config FEATURE_EDITING_FANCY_PROMPT |
161 | bool "Fancy shell prompts" | 146 | bool "Fancy shell prompts" |
diff --git a/libbb/appletlib.c b/libbb/appletlib.c index 6732f89a9..a31a73e90 100644 --- a/libbb/appletlib.c +++ b/libbb/appletlib.c | |||
@@ -777,11 +777,7 @@ static int busybox_main(char **argv) | |||
777 | int col; | 777 | int col; |
778 | unsigned output_width; | 778 | unsigned output_width; |
779 | help: | 779 | help: |
780 | output_width = 80; | 780 | output_width = get_terminal_width(2); |
781 | if (ENABLE_FEATURE_AUTOWIDTH) { | ||
782 | /* Obtain the terminal width */ | ||
783 | output_width = get_terminal_width(2); | ||
784 | } | ||
785 | 781 | ||
786 | dup2(1, 2); | 782 | dup2(1, 2); |
787 | full_write2_str(bb_banner); /* reuse const string */ | 783 | full_write2_str(bb_banner); /* reuse const string */ |
diff --git a/libbb/crc32.c b/libbb/crc32.c index ac9836cc9..0711ca84e 100644 --- a/libbb/crc32.c +++ b/libbb/crc32.c | |||
@@ -24,7 +24,7 @@ uint32_t* FAST_FUNC crc32_filltable(uint32_t *crc_table, int endian) | |||
24 | { | 24 | { |
25 | uint32_t polynomial = endian ? 0x04c11db7 : 0xedb88320; | 25 | uint32_t polynomial = endian ? 0x04c11db7 : 0xedb88320; |
26 | uint32_t c; | 26 | uint32_t c; |
27 | int i, j; | 27 | unsigned i, j; |
28 | 28 | ||
29 | if (!crc_table) | 29 | if (!crc_table) |
30 | crc_table = xmalloc(256 * sizeof(uint32_t)); | 30 | crc_table = xmalloc(256 * sizeof(uint32_t)); |
diff --git a/libbb/dump.c b/libbb/dump.c index 154be5d80..87c1dce13 100644 --- a/libbb/dump.c +++ b/libbb/dump.c | |||
@@ -14,12 +14,12 @@ | |||
14 | #include "libbb.h" | 14 | #include "libbb.h" |
15 | #include "dump.h" | 15 | #include "dump.h" |
16 | 16 | ||
17 | static const char index_str[] ALIGN1 = ".#-+ 0123456789"; | 17 | static const char dot_flags_width_chars[] ALIGN1 = ".#-+ 0123456789"; |
18 | 18 | ||
19 | static const char size_conv_str[] ALIGN1 = | 19 | static const char size_conv_str[] ALIGN1 = |
20 | "\x1\x4\x4\x4\x4\x4\x4\x8\x8\x8\x8\010cdiouxXeEfgG"; | 20 | "\x1\x4\x4\x4\x4\x4\x4\x8\x8\x8\x8\010cdiouxXeEfgG"; |
21 | 21 | ||
22 | static const char lcc[] ALIGN1 = "diouxX"; | 22 | static const char int_convs[] ALIGN1 = "diouxX"; |
23 | 23 | ||
24 | 24 | ||
25 | typedef struct priv_dumper_t { | 25 | typedef struct priv_dumper_t { |
@@ -71,7 +71,7 @@ static NOINLINE int bb_dump_size(FS *fs) | |||
71 | * skip any special chars -- save precision in | 71 | * skip any special chars -- save precision in |
72 | * case it's a %s format. | 72 | * case it's a %s format. |
73 | */ | 73 | */ |
74 | while (strchr(index_str + 1, *++fmt)) | 74 | while (strchr(dot_flags_width_chars + 1, *++fmt)) |
75 | continue; | 75 | continue; |
76 | if (*fmt == '.' && isdigit(*++fmt)) { | 76 | if (*fmt == '.' && isdigit(*++fmt)) { |
77 | prec = atoi(fmt); | 77 | prec = atoi(fmt); |
@@ -82,14 +82,15 @@ static NOINLINE int bb_dump_size(FS *fs) | |||
82 | if (!p) { | 82 | if (!p) { |
83 | if (*fmt == 's') { | 83 | if (*fmt == 's') { |
84 | bcnt += prec; | 84 | bcnt += prec; |
85 | } else if (*fmt == '_') { | 85 | } |
86 | if (*fmt == '_') { | ||
86 | ++fmt; | 87 | ++fmt; |
87 | if ((*fmt == 'c') || (*fmt == 'p') || (*fmt == 'u')) { | 88 | if ((*fmt == 'c') || (*fmt == 'p') || (*fmt == 'u')) { |
88 | bcnt += 1; | 89 | bcnt += 1; |
89 | } | 90 | } |
90 | } | 91 | } |
91 | } else { | 92 | } else { |
92 | bcnt += size_conv_str[p - (size_conv_str + 12)]; | 93 | bcnt += p[-12]; |
93 | } | 94 | } |
94 | } | 95 | } |
95 | cur_size += bcnt * fu->reps; | 96 | cur_size += bcnt * fu->reps; |
@@ -99,32 +100,30 @@ static NOINLINE int bb_dump_size(FS *fs) | |||
99 | 100 | ||
100 | static NOINLINE void rewrite(priv_dumper_t *dumper, FS *fs) | 101 | static NOINLINE void rewrite(priv_dumper_t *dumper, FS *fs) |
101 | { | 102 | { |
102 | enum { NOTOKAY, USEBCNT, USEPREC } sokay; | ||
103 | FU *fu; | 103 | FU *fu; |
104 | PR *pr; | ||
105 | char *p1, *p2, *p3; | ||
106 | char savech, *fmtp; | ||
107 | const char *byte_count_str; | ||
108 | int nconv, prec = 0; | ||
109 | 104 | ||
110 | for (fu = fs->nextfu; fu; fu = fu->nextfu) { | 105 | for (fu = fs->nextfu; fu; fu = fu->nextfu) { |
106 | PR *pr; | ||
107 | char *p1, *p2, *p3; | ||
108 | char *fmtp; | ||
109 | int nconv = 0; | ||
111 | /* | 110 | /* |
112 | * break each format unit into print units; each | 111 | * break each format unit into print units; each |
113 | * conversion character gets its own. | 112 | * conversion character gets its own. |
114 | */ | 113 | */ |
115 | for (nconv = 0, fmtp = fu->fmt; *fmtp; ) { | 114 | for (fmtp = fu->fmt; *fmtp; ) { |
116 | /* NOSTRICT */ | 115 | unsigned len; |
117 | /* DBU:[dvae@cray.com] zalloc so that forward ptrs start out NULL*/ | 116 | const char *prec; |
118 | pr = xzalloc(sizeof(PR)); | 117 | const char *byte_count_str; |
118 | |||
119 | /* DBU:[dvae@cray.com] zalloc so that forward ptrs start out NULL */ | ||
120 | pr = xzalloc(sizeof(*pr)); | ||
119 | if (!fu->nextpr) | 121 | if (!fu->nextpr) |
120 | fu->nextpr = pr; | 122 | fu->nextpr = pr; |
121 | 123 | ||
122 | /* skip preceding text and up to the next % sign */ | 124 | /* skip preceding text and up to the next % sign */ |
123 | for (p1 = fmtp; *p1 && *p1 != '%'; ++p1) | 125 | p1 = strchr(fmtp, '%'); |
124 | continue; | 126 | if (!p1) { /* only text in the string */ |
125 | |||
126 | /* only text in the string */ | ||
127 | if (!*p1) { | ||
128 | pr->fmt = fmtp; | 127 | pr->fmt = fmtp; |
129 | pr->flags = F_TEXT; | 128 | pr->flags = F_TEXT; |
130 | break; | 129 | break; |
@@ -134,22 +133,20 @@ static NOINLINE void rewrite(priv_dumper_t *dumper, FS *fs) | |||
134 | * get precision for %s -- if have a byte count, don't | 133 | * get precision for %s -- if have a byte count, don't |
135 | * need it. | 134 | * need it. |
136 | */ | 135 | */ |
136 | prec = NULL; | ||
137 | if (fu->bcnt) { | 137 | if (fu->bcnt) { |
138 | sokay = USEBCNT; | ||
139 | /* skip to conversion character */ | 138 | /* skip to conversion character */ |
140 | for (++p1; strchr(index_str, *p1); ++p1) | 139 | while (strchr(dot_flags_width_chars, *++p1)) |
141 | continue; | 140 | continue; |
142 | } else { | 141 | } else { |
143 | /* skip any special chars, field width */ | 142 | /* skip any special chars, field width */ |
144 | while (strchr(index_str + 1, *++p1)) | 143 | while (strchr(dot_flags_width_chars + 1, *++p1)) |
145 | continue; | 144 | continue; |
146 | if (*p1 == '.' && isdigit(*++p1)) { | 145 | if (*p1 == '.' && isdigit(*++p1)) { |
147 | sokay = USEPREC; | 146 | prec = p1; |
148 | prec = atoi(p1); | ||
149 | while (isdigit(*++p1)) | 147 | while (isdigit(*++p1)) |
150 | continue; | 148 | continue; |
151 | } else | 149 | } |
152 | sokay = NOTOKAY; | ||
153 | } | 150 | } |
154 | 151 | ||
155 | p2 = p1 + 1; /* set end pointer */ | 152 | p2 = p1 + 1; /* set end pointer */ |
@@ -165,74 +162,72 @@ static NOINLINE void rewrite(priv_dumper_t *dumper, FS *fs) | |||
165 | byte_count_str = "\001"; | 162 | byte_count_str = "\001"; |
166 | DO_BYTE_COUNT: | 163 | DO_BYTE_COUNT: |
167 | if (fu->bcnt) { | 164 | if (fu->bcnt) { |
168 | do { | 165 | for (;;) { |
169 | if (fu->bcnt == *byte_count_str) { | 166 | if (fu->bcnt == *byte_count_str) |
170 | break; | 167 | break; |
171 | } | 168 | if (*++byte_count_str == 0) |
172 | } while (*++byte_count_str); | 169 | bb_error_msg_and_die("bad byte count for conversion character %s", p1); |
170 | } | ||
173 | } | 171 | } |
174 | /* Unlike the original, output the remainder of the format string. */ | 172 | /* Unlike the original, output the remainder of the format string. */ |
175 | if (!*byte_count_str) { | ||
176 | bb_error_msg_and_die("bad byte count for conversion character %s", p1); | ||
177 | } | ||
178 | pr->bcnt = *byte_count_str; | 173 | pr->bcnt = *byte_count_str; |
179 | } else if (*p1 == 'l') { | 174 | } else |
175 | if (*p1 == 'l') { /* %ld etc */ | ||
176 | const char *e; | ||
177 | |||
180 | ++p2; | 178 | ++p2; |
181 | ++p1; | 179 | ++p1; |
182 | DO_INT_CONV: | 180 | DO_INT_CONV: |
183 | { | 181 | e = strchr(int_convs, *p1); /* "diouxX"? */ |
184 | const char *e; | 182 | if (!e) |
185 | e = strchr(lcc, *p1); | 183 | goto DO_BAD_CONV_CHAR; |
186 | if (!e) { | 184 | pr->flags = F_INT; |
187 | goto DO_BAD_CONV_CHAR; | 185 | if (e > int_convs + 1) /* not d or i? */ |
188 | } | 186 | pr->flags = F_UINT; |
189 | pr->flags = F_INT; | 187 | byte_count_str = "\004\002\001"; |
190 | if (e > lcc + 1) { | 188 | goto DO_BYTE_COUNT; |
191 | pr->flags = F_UINT; | 189 | } else |
192 | } | 190 | if (strchr(int_convs, *p1)) { /* %d etc */ |
193 | byte_count_str = "\004\002\001"; | ||
194 | goto DO_BYTE_COUNT; | ||
195 | } | ||
196 | /* NOTREACHED */ | ||
197 | } else if (strchr(lcc, *p1)) { | ||
198 | goto DO_INT_CONV; | 191 | goto DO_INT_CONV; |
199 | } else if (strchr("eEfgG", *p1)) { | 192 | } else |
193 | if (strchr("eEfgG", *p1)) { /* floating point */ | ||
200 | pr->flags = F_DBL; | 194 | pr->flags = F_DBL; |
201 | byte_count_str = "\010\004"; | 195 | byte_count_str = "\010\004"; |
202 | goto DO_BYTE_COUNT; | 196 | goto DO_BYTE_COUNT; |
203 | } else if (*p1 == 's') { | 197 | } else |
198 | if (*p1 == 's') { | ||
204 | pr->flags = F_STR; | 199 | pr->flags = F_STR; |
205 | if (sokay == USEBCNT) { | 200 | pr->bcnt = fu->bcnt; |
206 | pr->bcnt = fu->bcnt; | 201 | if (fu->bcnt == 0) { |
207 | } else if (sokay == USEPREC) { | 202 | if (!prec) |
208 | pr->bcnt = prec; | 203 | bb_error_msg_and_die("%%s needs precision or byte count"); |
209 | } else { /* NOTOKAY */ | 204 | pr->bcnt = atoi(prec); |
210 | bb_error_msg_and_die("%%s requires a precision or a byte count"); | ||
211 | } | 205 | } |
212 | } else if (*p1 == '_') { | 206 | } else |
213 | ++p2; | 207 | if (*p1 == '_') { |
208 | p2++; /* move past a in "%_a" */ | ||
214 | switch (p1[1]) { | 209 | switch (p1[1]) { |
215 | case 'A': | 210 | case 'A': /* %_A[dox]: print address and the end */ |
216 | dumper->endfu = fu; | 211 | dumper->endfu = fu; |
217 | fu->flags |= F_IGNORE; | 212 | fu->flags |= F_IGNORE; |
218 | /* FALLTHROUGH */ | 213 | /* FALLTHROUGH */ |
219 | case 'a': | 214 | case 'a': /* %_a[dox]: current address */ |
220 | pr->flags = F_ADDRESS; | 215 | pr->flags = F_ADDRESS; |
221 | ++p2; | 216 | p2++; /* move past x in "%_ax" */ |
222 | if ((p1[2] != 'd') && (p1[2] != 'o') && (p1[2] != 'x')) { | 217 | if ((p1[2] != 'd') && (p1[2] != 'o') && (p1[2] != 'x')) { |
223 | goto DO_BAD_CONV_CHAR; | 218 | goto DO_BAD_CONV_CHAR; |
224 | } | 219 | } |
225 | *p1 = p1[2]; | 220 | *p1 = p1[2]; |
226 | break; | 221 | break; |
227 | case 'c': | 222 | case 'c': /* %_c: chars, \ooo, \n \r \t etc */ |
228 | pr->flags = F_C; | 223 | pr->flags = F_C; |
229 | /* *p1 = 'c'; set in conv_c */ | 224 | /* *p1 = 'c'; set in conv_c */ |
230 | goto DO_BYTE_COUNT_1; | 225 | goto DO_BYTE_COUNT_1; |
231 | case 'p': | 226 | case 'p': /* %_p: chars, dots for nonprintable */ |
232 | pr->flags = F_P; | 227 | pr->flags = F_P; |
233 | *p1 = 'c'; | 228 | *p1 = 'c'; |
234 | goto DO_BYTE_COUNT_1; | 229 | goto DO_BYTE_COUNT_1; |
235 | case 'u': | 230 | case 'u': /* %_p: chars, 'nul', 'esc' etc for nonprintable */ |
236 | pr->flags = F_U; | 231 | pr->flags = F_U; |
237 | /* *p1 = 'c'; set in conv_u */ | 232 | /* *p1 = 'c'; set in conv_u */ |
238 | goto DO_BYTE_COUNT_1; | 233 | goto DO_BYTE_COUNT_1; |
@@ -248,13 +243,8 @@ static NOINLINE void rewrite(priv_dumper_t *dumper, FS *fs) | |||
248 | * copy to PR format string, set conversion character | 243 | * copy to PR format string, set conversion character |
249 | * pointer, update original. | 244 | * pointer, update original. |
250 | */ | 245 | */ |
251 | savech = *p2; | 246 | len = (p1 - fmtp) + 1; |
252 | p1[1] = '\0'; | 247 | pr->fmt = xstrndup(fmtp, len); |
253 | pr->fmt = xstrdup(fmtp); | ||
254 | *p2 = savech; | ||
255 | //Too early! xrealloc can move pr->fmt! | ||
256 | //pr->cchar = pr->fmt + (p1 - fmtp); | ||
257 | |||
258 | /* DBU:[dave@cray.com] w/o this, trailing fmt text, space is lost. | 248 | /* DBU:[dave@cray.com] w/o this, trailing fmt text, space is lost. |
259 | * Skip subsequent text and up to the next % sign and tack the | 249 | * Skip subsequent text and up to the next % sign and tack the |
260 | * additional text onto fmt: eg. if fmt is "%x is a HEX number", | 250 | * additional text onto fmt: eg. if fmt is "%x is a HEX number", |
@@ -262,16 +252,17 @@ static NOINLINE void rewrite(priv_dumper_t *dumper, FS *fs) | |||
262 | */ | 252 | */ |
263 | for (p3 = p2; *p3 && *p3 != '%'; p3++) | 253 | for (p3 = p2; *p3 && *p3 != '%'; p3++) |
264 | continue; | 254 | continue; |
265 | if (p3 > p2) { | 255 | if ((p3 - p2) != 0) { |
266 | savech = *p3; | 256 | char *d; |
267 | *p3 = '\0'; | 257 | pr->fmt = d = xrealloc(pr->fmt, len + (p3 - p2) + 1); |
268 | pr->fmt = xrealloc(pr->fmt, strlen(pr->fmt) + (p3-p2) + 1); | 258 | d += len; |
269 | strcat(pr->fmt, p2); | 259 | do { |
270 | *p3 = savech; | 260 | *d++ = *p2++; |
271 | p2 = p3; | 261 | } while (p2 != p3); |
262 | *d = '\0'; | ||
263 | /* now p2 = p3 */ | ||
272 | } | 264 | } |
273 | 265 | pr->cchar = pr->fmt + len - 1; /* must be after realloc! */ | |
274 | pr->cchar = pr->fmt + (p1 - fmtp); | ||
275 | fmtp = p2; | 266 | fmtp = p2; |
276 | 267 | ||
277 | /* only one conversion character if byte count */ | 268 | /* only one conversion character if byte count */ |
@@ -283,7 +274,7 @@ static NOINLINE void rewrite(priv_dumper_t *dumper, FS *fs) | |||
283 | * if format unit byte count not specified, figure it out | 274 | * if format unit byte count not specified, figure it out |
284 | * so can adjust rep count later. | 275 | * so can adjust rep count later. |
285 | */ | 276 | */ |
286 | if (!fu->bcnt) | 277 | if (fu->bcnt == 0) |
287 | for (pr = fu->nextpr; pr; pr = pr->nextpr) | 278 | for (pr = fu->nextpr; pr; pr = pr->nextpr) |
288 | fu->bcnt += pr->bcnt; | 279 | fu->bcnt += pr->bcnt; |
289 | } | 280 | } |
@@ -305,16 +296,18 @@ static NOINLINE void rewrite(priv_dumper_t *dumper, FS *fs) | |||
305 | fu->reps += (dumper->blocksize - fs->bcnt) / fu->bcnt; | 296 | fu->reps += (dumper->blocksize - fs->bcnt) / fu->bcnt; |
306 | } | 297 | } |
307 | if (fu->reps > 1 && fu->nextpr) { | 298 | if (fu->reps > 1 && fu->nextpr) { |
299 | PR *pr; | ||
300 | char *p1, *p2; | ||
301 | |||
308 | for (pr = fu->nextpr;; pr = pr->nextpr) | 302 | for (pr = fu->nextpr;; pr = pr->nextpr) |
309 | if (!pr->nextpr) | 303 | if (!pr->nextpr) |
310 | break; | 304 | break; |
311 | for (p1 = pr->fmt, p2 = NULL; *p1; ++p1) | 305 | p2 = NULL; |
306 | for (p1 = pr->fmt; *p1; ++p1) | ||
312 | p2 = isspace(*p1) ? p1 : NULL; | 307 | p2 = isspace(*p1) ? p1 : NULL; |
313 | if (p2) | 308 | if (p2) |
314 | pr->nospace = p2; | 309 | pr->nospace = p2; |
315 | } | 310 | } |
316 | if (!fu->nextfu) | ||
317 | break; | ||
318 | } | 311 | } |
319 | } | 312 | } |
320 | 313 | ||
@@ -358,6 +351,7 @@ static NOINLINE int next(priv_dumper_t *dumper) | |||
358 | if (dumper->next__done) | 351 | if (dumper->next__done) |
359 | return 0; /* no next file */ | 352 | return 0; /* no next file */ |
360 | dumper->next__done = 1; | 353 | dumper->next__done = 1; |
354 | //why stat of stdin is specially prohibited? | ||
361 | statok = 0; | 355 | statok = 0; |
362 | } | 356 | } |
363 | if (dumper->pub.dump_skip) | 357 | if (dumper->pub.dump_skip) |
@@ -762,6 +756,11 @@ void FAST_FUNC bb_dump_add(dumper_t* pub_dumper, const char *fmt) | |||
762 | if (!isspace(*p)) { | 756 | if (!isspace(*p)) { |
763 | bb_error_msg_and_die("bad format {%s}", fmt); | 757 | bb_error_msg_and_die("bad format {%s}", fmt); |
764 | } | 758 | } |
759 | // Above check prohibits formats such as '/1"%02x"' - it requires space after 1. | ||
760 | // Other than this, formats can be pretty much jammed together: | ||
761 | // "%07_ax:"8/2 "%04x|""\n" | ||
762 | // but this space is required. The check *can* be removed, but | ||
763 | // keeping it to stay compat with util-linux hexdump. | ||
765 | tfu->bcnt = atoi(savep); | 764 | tfu->bcnt = atoi(savep); |
766 | /* skip trailing white space */ | 765 | /* skip trailing white space */ |
767 | p = skip_whitespace(p + 1); | 766 | p = skip_whitespace(p + 1); |
diff --git a/libbb/getopt32.c b/libbb/getopt32.c index ed9352191..03fca3493 100644 --- a/libbb/getopt32.c +++ b/libbb/getopt32.c | |||
@@ -404,7 +404,7 @@ getopt32(char **argv, const char *applet_opts, ...) | |||
404 | if (c >= 32) | 404 | if (c >= 32) |
405 | break; | 405 | break; |
406 | on_off->opt_char = *s; | 406 | on_off->opt_char = *s; |
407 | on_off->switch_on = (1 << c); | 407 | on_off->switch_on = (1U << c); |
408 | if (*++s == ':') { | 408 | if (*++s == ':') { |
409 | on_off->optarg = va_arg(p, void **); | 409 | on_off->optarg = va_arg(p, void **); |
410 | if (s[1] == '+' || s[1] == '*') { | 410 | if (s[1] == '+' || s[1] == '*') { |
@@ -454,7 +454,7 @@ getopt32(char **argv, const char *applet_opts, ...) | |||
454 | if (c >= 32) | 454 | if (c >= 32) |
455 | break; | 455 | break; |
456 | on_off->opt_char = l_o->val; | 456 | on_off->opt_char = l_o->val; |
457 | on_off->switch_on = (1 << c); | 457 | on_off->switch_on = (1U << c); |
458 | if (l_o->has_arg != no_argument) | 458 | if (l_o->has_arg != no_argument) |
459 | on_off->optarg = va_arg(p, void **); | 459 | on_off->optarg = va_arg(p, void **); |
460 | c++; | 460 | c++; |
diff --git a/libbb/hash_md5_sha.c b/libbb/hash_md5_sha.c index 7e7d8da2f..2a7247430 100644 --- a/libbb/hash_md5_sha.c +++ b/libbb/hash_md5_sha.c | |||
@@ -9,6 +9,8 @@ | |||
9 | 9 | ||
10 | #include "libbb.h" | 10 | #include "libbb.h" |
11 | 11 | ||
12 | #define NEED_SHA512 (ENABLE_SHA512SUM || ENABLE_USE_BB_CRYPT_SHA) | ||
13 | |||
12 | /* gcc 4.2.1 optimizes rotr64 better with inline than with macro | 14 | /* gcc 4.2.1 optimizes rotr64 better with inline than with macro |
13 | * (for rotX32, there is no difference). Why? My guess is that | 15 | * (for rotX32, there is no difference). Why? My guess is that |
14 | * macro requires clever common subexpression elimination heuristics | 16 | * macro requires clever common subexpression elimination heuristics |
@@ -456,7 +458,7 @@ void FAST_FUNC md5_hash(md5_ctx_t *ctx, const void *buffer, size_t len) | |||
456 | * endian byte order, so that a byte-wise output yields to the wanted | 458 | * endian byte order, so that a byte-wise output yields to the wanted |
457 | * ASCII representation of the message digest. | 459 | * ASCII representation of the message digest. |
458 | */ | 460 | */ |
459 | void FAST_FUNC md5_end(md5_ctx_t *ctx, void *resbuf) | 461 | unsigned FAST_FUNC md5_end(md5_ctx_t *ctx, void *resbuf) |
460 | { | 462 | { |
461 | /* MD5 stores total in LE, need to swap on BE arches: */ | 463 | /* MD5 stores total in LE, need to swap on BE arches: */ |
462 | common64_end(ctx, /*swap_needed:*/ BB_BIG_ENDIAN); | 464 | common64_end(ctx, /*swap_needed:*/ BB_BIG_ENDIAN); |
@@ -470,6 +472,7 @@ void FAST_FUNC md5_end(md5_ctx_t *ctx, void *resbuf) | |||
470 | } | 472 | } |
471 | 473 | ||
472 | memcpy(resbuf, ctx->hash, sizeof(ctx->hash[0]) * 4); | 474 | memcpy(resbuf, ctx->hash, sizeof(ctx->hash[0]) * 4); |
475 | return sizeof(ctx->hash[0]) * 4; | ||
473 | } | 476 | } |
474 | 477 | ||
475 | 478 | ||
@@ -564,48 +567,59 @@ static void FAST_FUNC sha1_process_block64(sha1_ctx_t *ctx) | |||
564 | * are the most significant half of first 64 elements | 567 | * are the most significant half of first 64 elements |
565 | * of the same array. | 568 | * of the same array. |
566 | */ | 569 | */ |
567 | static const uint64_t sha_K[80] = { | 570 | #undef K |
568 | 0x428a2f98d728ae22ULL, 0x7137449123ef65cdULL, | 571 | #if NEED_SHA512 |
569 | 0xb5c0fbcfec4d3b2fULL, 0xe9b5dba58189dbbcULL, | 572 | typedef uint64_t sha_K_int; |
570 | 0x3956c25bf348b538ULL, 0x59f111f1b605d019ULL, | 573 | # define K(v) v |
571 | 0x923f82a4af194f9bULL, 0xab1c5ed5da6d8118ULL, | 574 | #else |
572 | 0xd807aa98a3030242ULL, 0x12835b0145706fbeULL, | 575 | typedef uint32_t sha_K_int; |
573 | 0x243185be4ee4b28cULL, 0x550c7dc3d5ffb4e2ULL, | 576 | # define K(v) (uint32_t)(v >> 32) |
574 | 0x72be5d74f27b896fULL, 0x80deb1fe3b1696b1ULL, | 577 | #endif |
575 | 0x9bdc06a725c71235ULL, 0xc19bf174cf692694ULL, | 578 | static const sha_K_int sha_K[] = { |
576 | 0xe49b69c19ef14ad2ULL, 0xefbe4786384f25e3ULL, | 579 | K(0x428a2f98d728ae22ULL), K(0x7137449123ef65cdULL), |
577 | 0x0fc19dc68b8cd5b5ULL, 0x240ca1cc77ac9c65ULL, | 580 | K(0xb5c0fbcfec4d3b2fULL), K(0xe9b5dba58189dbbcULL), |
578 | 0x2de92c6f592b0275ULL, 0x4a7484aa6ea6e483ULL, | 581 | K(0x3956c25bf348b538ULL), K(0x59f111f1b605d019ULL), |
579 | 0x5cb0a9dcbd41fbd4ULL, 0x76f988da831153b5ULL, | 582 | K(0x923f82a4af194f9bULL), K(0xab1c5ed5da6d8118ULL), |
580 | 0x983e5152ee66dfabULL, 0xa831c66d2db43210ULL, | 583 | K(0xd807aa98a3030242ULL), K(0x12835b0145706fbeULL), |
581 | 0xb00327c898fb213fULL, 0xbf597fc7beef0ee4ULL, | 584 | K(0x243185be4ee4b28cULL), K(0x550c7dc3d5ffb4e2ULL), |
582 | 0xc6e00bf33da88fc2ULL, 0xd5a79147930aa725ULL, | 585 | K(0x72be5d74f27b896fULL), K(0x80deb1fe3b1696b1ULL), |
583 | 0x06ca6351e003826fULL, 0x142929670a0e6e70ULL, | 586 | K(0x9bdc06a725c71235ULL), K(0xc19bf174cf692694ULL), |
584 | 0x27b70a8546d22ffcULL, 0x2e1b21385c26c926ULL, | 587 | K(0xe49b69c19ef14ad2ULL), K(0xefbe4786384f25e3ULL), |
585 | 0x4d2c6dfc5ac42aedULL, 0x53380d139d95b3dfULL, | 588 | K(0x0fc19dc68b8cd5b5ULL), K(0x240ca1cc77ac9c65ULL), |
586 | 0x650a73548baf63deULL, 0x766a0abb3c77b2a8ULL, | 589 | K(0x2de92c6f592b0275ULL), K(0x4a7484aa6ea6e483ULL), |
587 | 0x81c2c92e47edaee6ULL, 0x92722c851482353bULL, | 590 | K(0x5cb0a9dcbd41fbd4ULL), K(0x76f988da831153b5ULL), |
588 | 0xa2bfe8a14cf10364ULL, 0xa81a664bbc423001ULL, | 591 | K(0x983e5152ee66dfabULL), K(0xa831c66d2db43210ULL), |
589 | 0xc24b8b70d0f89791ULL, 0xc76c51a30654be30ULL, | 592 | K(0xb00327c898fb213fULL), K(0xbf597fc7beef0ee4ULL), |
590 | 0xd192e819d6ef5218ULL, 0xd69906245565a910ULL, | 593 | K(0xc6e00bf33da88fc2ULL), K(0xd5a79147930aa725ULL), |
591 | 0xf40e35855771202aULL, 0x106aa07032bbd1b8ULL, | 594 | K(0x06ca6351e003826fULL), K(0x142929670a0e6e70ULL), |
592 | 0x19a4c116b8d2d0c8ULL, 0x1e376c085141ab53ULL, | 595 | K(0x27b70a8546d22ffcULL), K(0x2e1b21385c26c926ULL), |
593 | 0x2748774cdf8eeb99ULL, 0x34b0bcb5e19b48a8ULL, | 596 | K(0x4d2c6dfc5ac42aedULL), K(0x53380d139d95b3dfULL), |
594 | 0x391c0cb3c5c95a63ULL, 0x4ed8aa4ae3418acbULL, | 597 | K(0x650a73548baf63deULL), K(0x766a0abb3c77b2a8ULL), |
595 | 0x5b9cca4f7763e373ULL, 0x682e6ff3d6b2b8a3ULL, | 598 | K(0x81c2c92e47edaee6ULL), K(0x92722c851482353bULL), |
596 | 0x748f82ee5defb2fcULL, 0x78a5636f43172f60ULL, | 599 | K(0xa2bfe8a14cf10364ULL), K(0xa81a664bbc423001ULL), |
597 | 0x84c87814a1f0ab72ULL, 0x8cc702081a6439ecULL, | 600 | K(0xc24b8b70d0f89791ULL), K(0xc76c51a30654be30ULL), |
598 | 0x90befffa23631e28ULL, 0xa4506cebde82bde9ULL, | 601 | K(0xd192e819d6ef5218ULL), K(0xd69906245565a910ULL), |
599 | 0xbef9a3f7b2c67915ULL, 0xc67178f2e372532bULL, | 602 | K(0xf40e35855771202aULL), K(0x106aa07032bbd1b8ULL), |
600 | 0xca273eceea26619cULL, 0xd186b8c721c0c207ULL, /* [64]+ are used for sha512 only */ | 603 | K(0x19a4c116b8d2d0c8ULL), K(0x1e376c085141ab53ULL), |
601 | 0xeada7dd6cde0eb1eULL, 0xf57d4f7fee6ed178ULL, | 604 | K(0x2748774cdf8eeb99ULL), K(0x34b0bcb5e19b48a8ULL), |
602 | 0x06f067aa72176fbaULL, 0x0a637dc5a2c898a6ULL, | 605 | K(0x391c0cb3c5c95a63ULL), K(0x4ed8aa4ae3418acbULL), |
603 | 0x113f9804bef90daeULL, 0x1b710b35131c471bULL, | 606 | K(0x5b9cca4f7763e373ULL), K(0x682e6ff3d6b2b8a3ULL), |
604 | 0x28db77f523047d84ULL, 0x32caab7b40c72493ULL, | 607 | K(0x748f82ee5defb2fcULL), K(0x78a5636f43172f60ULL), |
605 | 0x3c9ebe0a15c9bebcULL, 0x431d67c49c100d4cULL, | 608 | K(0x84c87814a1f0ab72ULL), K(0x8cc702081a6439ecULL), |
606 | 0x4cc5d4becb3e42b6ULL, 0x597f299cfc657e2aULL, | 609 | K(0x90befffa23631e28ULL), K(0xa4506cebde82bde9ULL), |
607 | 0x5fcb6fab3ad6faecULL, 0x6c44198c4a475817ULL | 610 | K(0xbef9a3f7b2c67915ULL), K(0xc67178f2e372532bULL), |
611 | #if NEED_SHA512 /* [64]+ are used for sha512 only */ | ||
612 | K(0xca273eceea26619cULL), K(0xd186b8c721c0c207ULL), | ||
613 | K(0xeada7dd6cde0eb1eULL), K(0xf57d4f7fee6ed178ULL), | ||
614 | K(0x06f067aa72176fbaULL), K(0x0a637dc5a2c898a6ULL), | ||
615 | K(0x113f9804bef90daeULL), K(0x1b710b35131c471bULL), | ||
616 | K(0x28db77f523047d84ULL), K(0x32caab7b40c72493ULL), | ||
617 | K(0x3c9ebe0a15c9bebcULL), K(0x431d67c49c100d4cULL), | ||
618 | K(0x4cc5d4becb3e42b6ULL), K(0x597f299cfc657e2aULL), | ||
619 | K(0x5fcb6fab3ad6faecULL), K(0x6c44198c4a475817ULL), | ||
620 | #endif | ||
608 | }; | 621 | }; |
622 | #undef K | ||
609 | 623 | ||
610 | #undef Ch | 624 | #undef Ch |
611 | #undef Maj | 625 | #undef Maj |
@@ -649,7 +663,7 @@ static void FAST_FUNC sha256_process_block64(sha256_ctx_t *ctx) | |||
649 | * (I hope compiler is clever enough to just fetch | 663 | * (I hope compiler is clever enough to just fetch |
650 | * upper half) | 664 | * upper half) |
651 | */ | 665 | */ |
652 | uint32_t K_t = sha_K[t] >> 32; | 666 | uint32_t K_t = NEED_SHA512 ? (sha_K[t] >> 32) : sha_K[t]; |
653 | uint32_t T1 = h + S1(e) + Ch(e, f, g) + K_t + W[t]; | 667 | uint32_t T1 = h + S1(e) + Ch(e, f, g) + K_t + W[t]; |
654 | uint32_t T2 = S0(a) + Maj(a, b, c); | 668 | uint32_t T2 = S0(a) + Maj(a, b, c); |
655 | h = g; | 669 | h = g; |
@@ -679,6 +693,7 @@ static void FAST_FUNC sha256_process_block64(sha256_ctx_t *ctx) | |||
679 | ctx->hash[7] += h; | 693 | ctx->hash[7] += h; |
680 | } | 694 | } |
681 | 695 | ||
696 | #if NEED_SHA512 | ||
682 | static void FAST_FUNC sha512_process_block128(sha512_ctx_t *ctx) | 697 | static void FAST_FUNC sha512_process_block128(sha512_ctx_t *ctx) |
683 | { | 698 | { |
684 | unsigned t; | 699 | unsigned t; |
@@ -740,7 +755,7 @@ static void FAST_FUNC sha512_process_block128(sha512_ctx_t *ctx) | |||
740 | ctx->hash[6] += g; | 755 | ctx->hash[6] += g; |
741 | ctx->hash[7] += h; | 756 | ctx->hash[7] += h; |
742 | } | 757 | } |
743 | 758 | #endif /* NEED_SHA512 */ | |
744 | 759 | ||
745 | void FAST_FUNC sha1_begin(sha1_ctx_t *ctx) | 760 | void FAST_FUNC sha1_begin(sha1_ctx_t *ctx) |
746 | { | 761 | { |
@@ -765,6 +780,7 @@ static const uint32_t init256[] = { | |||
765 | 0x1f83d9ab, | 780 | 0x1f83d9ab, |
766 | 0x5be0cd19, | 781 | 0x5be0cd19, |
767 | }; | 782 | }; |
783 | #if NEED_SHA512 | ||
768 | static const uint32_t init512_lo[] = { | 784 | static const uint32_t init512_lo[] = { |
769 | 0, | 785 | 0, |
770 | 0, | 786 | 0, |
@@ -777,6 +793,7 @@ static const uint32_t init512_lo[] = { | |||
777 | 0xfb41bd6b, | 793 | 0xfb41bd6b, |
778 | 0x137e2179, | 794 | 0x137e2179, |
779 | }; | 795 | }; |
796 | #endif /* NEED_SHA512 */ | ||
780 | 797 | ||
781 | /* Initialize structure containing state of computation. | 798 | /* Initialize structure containing state of computation. |
782 | (FIPS 180-2:5.3.2) */ | 799 | (FIPS 180-2:5.3.2) */ |
@@ -787,6 +804,7 @@ void FAST_FUNC sha256_begin(sha256_ctx_t *ctx) | |||
787 | ctx->process_block = sha256_process_block64; | 804 | ctx->process_block = sha256_process_block64; |
788 | } | 805 | } |
789 | 806 | ||
807 | #if NEED_SHA512 | ||
790 | /* Initialize structure containing state of computation. | 808 | /* Initialize structure containing state of computation. |
791 | (FIPS 180-2:5.3.3) */ | 809 | (FIPS 180-2:5.3.3) */ |
792 | void FAST_FUNC sha512_begin(sha512_ctx_t *ctx) | 810 | void FAST_FUNC sha512_begin(sha512_ctx_t *ctx) |
@@ -810,7 +828,7 @@ void FAST_FUNC sha512_hash(sha512_ctx_t *ctx, const void *buffer, size_t len) | |||
810 | ctx->total64[0] += len; | 828 | ctx->total64[0] += len; |
811 | if (ctx->total64[0] < len) | 829 | if (ctx->total64[0] < len) |
812 | ctx->total64[1]++; | 830 | ctx->total64[1]++; |
813 | #if 0 | 831 | # if 0 |
814 | remaining = 128 - bufpos; | 832 | remaining = 128 - bufpos; |
815 | 833 | ||
816 | /* Hash whole blocks */ | 834 | /* Hash whole blocks */ |
@@ -825,7 +843,7 @@ void FAST_FUNC sha512_hash(sha512_ctx_t *ctx, const void *buffer, size_t len) | |||
825 | 843 | ||
826 | /* Save last, partial blosk */ | 844 | /* Save last, partial blosk */ |
827 | memcpy(ctx->wbuffer + bufpos, buffer, len); | 845 | memcpy(ctx->wbuffer + bufpos, buffer, len); |
828 | #else | 846 | # else |
829 | while (1) { | 847 | while (1) { |
830 | remaining = 128 - bufpos; | 848 | remaining = 128 - bufpos; |
831 | if (remaining > len) | 849 | if (remaining > len) |
@@ -843,11 +861,12 @@ void FAST_FUNC sha512_hash(sha512_ctx_t *ctx, const void *buffer, size_t len) | |||
843 | sha512_process_block128(ctx); | 861 | sha512_process_block128(ctx); |
844 | /*bufpos = 0; - already is */ | 862 | /*bufpos = 0; - already is */ |
845 | } | 863 | } |
846 | #endif | 864 | # endif |
847 | } | 865 | } |
866 | #endif /* NEED_SHA512 */ | ||
848 | 867 | ||
849 | /* Used also for sha256 */ | 868 | /* Used also for sha256 */ |
850 | void FAST_FUNC sha1_end(sha1_ctx_t *ctx, void *resbuf) | 869 | unsigned FAST_FUNC sha1_end(sha1_ctx_t *ctx, void *resbuf) |
851 | { | 870 | { |
852 | unsigned hash_size; | 871 | unsigned hash_size; |
853 | 872 | ||
@@ -861,10 +880,13 @@ void FAST_FUNC sha1_end(sha1_ctx_t *ctx, void *resbuf) | |||
861 | for (i = 0; i < hash_size; ++i) | 880 | for (i = 0; i < hash_size; ++i) |
862 | ctx->hash[i] = SWAP_BE32(ctx->hash[i]); | 881 | ctx->hash[i] = SWAP_BE32(ctx->hash[i]); |
863 | } | 882 | } |
864 | memcpy(resbuf, ctx->hash, sizeof(ctx->hash[0]) * hash_size); | 883 | hash_size *= sizeof(ctx->hash[0]); |
884 | memcpy(resbuf, ctx->hash, hash_size); | ||
885 | return hash_size; | ||
865 | } | 886 | } |
866 | 887 | ||
867 | void FAST_FUNC sha512_end(sha512_ctx_t *ctx, void *resbuf) | 888 | #if NEED_SHA512 |
889 | unsigned FAST_FUNC sha512_end(sha512_ctx_t *ctx, void *resbuf) | ||
868 | { | 890 | { |
869 | unsigned bufpos = ctx->total64[0] & 127; | 891 | unsigned bufpos = ctx->total64[0] & 127; |
870 | 892 | ||
@@ -896,7 +918,9 @@ void FAST_FUNC sha512_end(sha512_ctx_t *ctx, void *resbuf) | |||
896 | ctx->hash[i] = SWAP_BE64(ctx->hash[i]); | 918 | ctx->hash[i] = SWAP_BE64(ctx->hash[i]); |
897 | } | 919 | } |
898 | memcpy(resbuf, ctx->hash, sizeof(ctx->hash)); | 920 | memcpy(resbuf, ctx->hash, sizeof(ctx->hash)); |
921 | return sizeof(ctx->hash); | ||
899 | } | 922 | } |
923 | #endif /* NEED_SHA512 */ | ||
900 | 924 | ||
901 | 925 | ||
902 | /* | 926 | /* |
@@ -1430,7 +1454,7 @@ void FAST_FUNC sha3_hash(sha3_ctx_t *ctx, const void *buffer, size_t len) | |||
1430 | #endif | 1454 | #endif |
1431 | } | 1455 | } |
1432 | 1456 | ||
1433 | void FAST_FUNC sha3_end(sha3_ctx_t *ctx, void *resbuf) | 1457 | unsigned FAST_FUNC sha3_end(sha3_ctx_t *ctx, void *resbuf) |
1434 | { | 1458 | { |
1435 | /* Padding */ | 1459 | /* Padding */ |
1436 | uint8_t *buf = (uint8_t*)ctx->state; | 1460 | uint8_t *buf = (uint8_t*)ctx->state; |
@@ -1455,4 +1479,5 @@ void FAST_FUNC sha3_end(sha3_ctx_t *ctx, void *resbuf) | |||
1455 | 1479 | ||
1456 | /* Output */ | 1480 | /* Output */ |
1457 | memcpy(resbuf, ctx->state, 64); | 1481 | memcpy(resbuf, ctx->state, 64); |
1482 | return 64; | ||
1458 | } | 1483 | } |
diff --git a/libbb/hash_md5prime.c b/libbb/hash_md5prime.c index e089a15f5..4b58d37ff 100644 --- a/libbb/hash_md5prime.c +++ b/libbb/hash_md5prime.c | |||
@@ -437,7 +437,7 @@ void FAST_FUNC md5_hash(const void *buffer, size_t inputLen, md5_ctx_t *context) | |||
437 | * MD5 finalization. Ends an MD5 message-digest operation, | 437 | * MD5 finalization. Ends an MD5 message-digest operation, |
438 | * writing the message digest. | 438 | * writing the message digest. |
439 | */ | 439 | */ |
440 | void FAST_FUNC md5_end(void *digest, md5_ctx_t *context) | 440 | unsigned FAST_FUNC md5_end(void *digest, md5_ctx_t *context) |
441 | { | 441 | { |
442 | unsigned idx, padLen; | 442 | unsigned idx, padLen; |
443 | unsigned char bits[8]; | 443 | unsigned char bits[8]; |
@@ -457,4 +457,5 @@ void FAST_FUNC md5_end(void *digest, md5_ctx_t *context) | |||
457 | 457 | ||
458 | /* Store state in digest */ | 458 | /* Store state in digest */ |
459 | memcpy32_cpu2le(digest, context->state, 16); | 459 | memcpy32_cpu2le(digest, context->state, 16); |
460 | return 16; | ||
460 | } | 461 | } |
diff --git a/libbb/lineedit.c b/libbb/lineedit.c index 5d9080131..670a1b194 100644 --- a/libbb/lineedit.c +++ b/libbb/lineedit.c | |||
@@ -2402,7 +2402,7 @@ int FAST_FUNC read_line_input(line_input_t *st, const char *prompt, char *comman | |||
2402 | /* ~ECHO, ~ECHONL: turn off echoing, including newline echoing */ | 2402 | /* ~ECHO, ~ECHONL: turn off echoing, including newline echoing */ |
2403 | /* ~ISIG: turn off INTR (ctrl-C), QUIT, SUSP */ | 2403 | /* ~ISIG: turn off INTR (ctrl-C), QUIT, SUSP */ |
2404 | new_settings.c_lflag &= ~(ICANON | ECHO | ECHONL | ISIG); | 2404 | new_settings.c_lflag &= ~(ICANON | ECHO | ECHONL | ISIG); |
2405 | /* reads would block only if < 1 char is available */ | 2405 | /* reads will block only if < 1 char is available */ |
2406 | new_settings.c_cc[VMIN] = 1; | 2406 | new_settings.c_cc[VMIN] = 1; |
2407 | /* no timeout (reads block forever) */ | 2407 | /* no timeout (reads block forever) */ |
2408 | new_settings.c_cc[VTIME] = 0; | 2408 | new_settings.c_cc[VTIME] = 0; |
diff --git a/libbb/match_fstype.c b/libbb/match_fstype.c index b066b4211..6046bc6db 100644 --- a/libbb/match_fstype.c +++ b/libbb/match_fstype.c | |||
@@ -12,34 +12,30 @@ | |||
12 | 12 | ||
13 | #include "libbb.h" | 13 | #include "libbb.h" |
14 | 14 | ||
15 | #ifdef HAVE_MNTENT_H | 15 | int FAST_FUNC fstype_matches(const char *fstype, const char *comma_list) |
16 | |||
17 | int FAST_FUNC match_fstype(const struct mntent *mt, const char *t_fstype) | ||
18 | { | 16 | { |
19 | int match = 1; | 17 | int match = 1; |
20 | 18 | ||
21 | if (!t_fstype) | 19 | if (!comma_list) |
22 | return match; | 20 | return match; |
23 | 21 | ||
24 | if (t_fstype[0] == 'n' && t_fstype[1] == 'o') { | 22 | if (comma_list[0] == 'n' && comma_list[1] == 'o') { |
25 | match--; | 23 | match--; |
26 | t_fstype += 2; | 24 | comma_list += 2; |
27 | } | 25 | } |
28 | 26 | ||
29 | while (1) { | 27 | while (1) { |
30 | char *after_mnt_type = is_prefixed_with(t_fstype, mt->mnt_type); | 28 | char *after_mnt_type = is_prefixed_with(comma_list, fstype); |
31 | if (after_mnt_type | 29 | if (after_mnt_type |
32 | && (*after_mnt_type == '\0' || *after_mnt_type == ',') | 30 | && (*after_mnt_type == '\0' || *after_mnt_type == ',') |
33 | ) { | 31 | ) { |
34 | return match; | 32 | return match; |
35 | } | 33 | } |
36 | t_fstype = strchr(t_fstype, ','); | 34 | comma_list = strchr(comma_list, ','); |
37 | if (!t_fstype) | 35 | if (!comma_list) |
38 | break; | 36 | break; |
39 | t_fstype++; | 37 | comma_list++; |
40 | } | 38 | } |
41 | 39 | ||
42 | return !match; | 40 | return !match; |
43 | } | 41 | } |
44 | |||
45 | #endif /* HAVE_MNTENT_H */ | ||
diff --git a/libbb/procps.c b/libbb/procps.c index 452b50b82..6f971a116 100644 --- a/libbb/procps.c +++ b/libbb/procps.c | |||
@@ -371,6 +371,7 @@ procps_status_t* FAST_FUNC procps_scan(procps_status_t* sp, int flags) | |||
371 | | PSSCAN_TTY | PSSCAN_NICE | 371 | | PSSCAN_TTY | PSSCAN_NICE |
372 | | PSSCAN_CPU) | 372 | | PSSCAN_CPU) |
373 | ) { | 373 | ) { |
374 | int s_idx; | ||
374 | char *cp, *comm1; | 375 | char *cp, *comm1; |
375 | int tty; | 376 | int tty; |
376 | #if !ENABLE_FEATURE_FAST_TOP | 377 | #if !ENABLE_FEATURE_FAST_TOP |
@@ -469,17 +470,20 @@ procps_status_t* FAST_FUNC procps_scan(procps_status_t* sp, int flags) | |||
469 | #if ENABLE_FEATURE_PS_ADDITIONAL_COLUMNS | 470 | #if ENABLE_FEATURE_PS_ADDITIONAL_COLUMNS |
470 | sp->niceness = tasknice; | 471 | sp->niceness = tasknice; |
471 | #endif | 472 | #endif |
472 | 473 | sp->state[1] = ' '; | |
473 | if (sp->vsz == 0 && sp->state[0] != 'Z') | 474 | sp->state[2] = ' '; |
475 | s_idx = 1; | ||
476 | if (sp->vsz == 0 && sp->state[0] != 'Z') { | ||
477 | /* not sure what the purpose of this flag */ | ||
474 | sp->state[1] = 'W'; | 478 | sp->state[1] = 'W'; |
475 | else | 479 | s_idx = 2; |
476 | sp->state[1] = ' '; | 480 | } |
477 | if (tasknice < 0) | 481 | if (tasknice != 0) { |
478 | sp->state[2] = '<'; | 482 | if (tasknice < 0) |
479 | else if (tasknice) /* > 0 */ | 483 | sp->state[s_idx] = '<'; |
480 | sp->state[2] = 'N'; | 484 | else /* > 0 */ |
481 | else | 485 | sp->state[s_idx] = 'N'; |
482 | sp->state[2] = ' '; | 486 | } |
483 | } | 487 | } |
484 | 488 | ||
485 | #if ENABLE_FEATURE_TOPMEM | 489 | #if ENABLE_FEATURE_TOPMEM |
diff --git a/libbb/pw_encrypt.c b/libbb/pw_encrypt.c index 4cdc2de76..fe06a8fe6 100644 --- a/libbb/pw_encrypt.c +++ b/libbb/pw_encrypt.c | |||
@@ -30,7 +30,7 @@ static int i64c(int i) | |||
30 | int FAST_FUNC crypt_make_salt(char *p, int cnt /*, int x */) | 30 | int FAST_FUNC crypt_make_salt(char *p, int cnt /*, int x */) |
31 | { | 31 | { |
32 | /* was: x += ... */ | 32 | /* was: x += ... */ |
33 | int x = getpid() + monotonic_us(); | 33 | unsigned x = getpid() + monotonic_us(); |
34 | do { | 34 | do { |
35 | /* x = (x*1664525 + 1013904223) % 2^32 generator is lame | 35 | /* x = (x*1664525 + 1013904223) % 2^32 generator is lame |
36 | * (low-order bit is not "random", etc...), | 36 | * (low-order bit is not "random", etc...), |
diff --git a/libbb/pw_encrypt_sha.c b/libbb/pw_encrypt_sha.c index 8aeaacad6..5457d7ab6 100644 --- a/libbb/pw_encrypt_sha.c +++ b/libbb/pw_encrypt_sha.c | |||
@@ -18,9 +18,10 @@ static char * | |||
18 | NOINLINE | 18 | NOINLINE |
19 | sha_crypt(/*const*/ char *key_data, /*const*/ char *salt_data) | 19 | sha_crypt(/*const*/ char *key_data, /*const*/ char *salt_data) |
20 | { | 20 | { |
21 | #undef sha_end | ||
21 | void (*sha_begin)(void *ctx) FAST_FUNC; | 22 | void (*sha_begin)(void *ctx) FAST_FUNC; |
22 | void (*sha_hash)(void *ctx, const void *buffer, size_t len) FAST_FUNC; | 23 | void (*sha_hash)(void *ctx, const void *buffer, size_t len) FAST_FUNC; |
23 | void (*sha_end)(void *ctx, void *resbuf) FAST_FUNC; | 24 | unsigned (*sha_end)(void *ctx, void *resbuf) FAST_FUNC; |
24 | int _32or64; | 25 | int _32or64; |
25 | 26 | ||
26 | char *result, *resptr; | 27 | char *result, *resptr; |
@@ -47,16 +48,17 @@ sha_crypt(/*const*/ char *key_data, /*const*/ char *salt_data) | |||
47 | unsigned cnt; | 48 | unsigned cnt; |
48 | unsigned rounds; | 49 | unsigned rounds; |
49 | char *cp; | 50 | char *cp; |
50 | char is_sha512; | ||
51 | 51 | ||
52 | /* Analyze salt, construct already known part of result */ | 52 | /* Analyze salt, construct already known part of result */ |
53 | cnt = strlen(salt_data) + 1 + 43 + 1; | 53 | cnt = strlen(salt_data) + 1 + 43 + 1; |
54 | is_sha512 = salt_data[1]; | 54 | _32or64 = 32; |
55 | if (is_sha512 == '6') | 55 | if (salt_data[1] == '6') { /* sha512 */ |
56 | _32or64 *= 2; /*64*/ | ||
56 | cnt += 43; | 57 | cnt += 43; |
58 | } | ||
57 | result = resptr = xzalloc(cnt); /* will provide NUL terminator */ | 59 | result = resptr = xzalloc(cnt); /* will provide NUL terminator */ |
58 | *resptr++ = '$'; | 60 | *resptr++ = '$'; |
59 | *resptr++ = is_sha512; | 61 | *resptr++ = salt_data[1]; |
60 | *resptr++ = '$'; | 62 | *resptr++ = '$'; |
61 | rounds = ROUNDS_DEFAULT; | 63 | rounds = ROUNDS_DEFAULT; |
62 | salt_data += 3; | 64 | salt_data += 3; |
@@ -93,12 +95,10 @@ sha_crypt(/*const*/ char *key_data, /*const*/ char *salt_data) | |||
93 | sha_begin = (void*)sha256_begin; | 95 | sha_begin = (void*)sha256_begin; |
94 | sha_hash = (void*)sha256_hash; | 96 | sha_hash = (void*)sha256_hash; |
95 | sha_end = (void*)sha256_end; | 97 | sha_end = (void*)sha256_end; |
96 | _32or64 = 32; | 98 | if (_32or64 != 32) { |
97 | if (is_sha512 == '6') { | ||
98 | sha_begin = (void*)sha512_begin; | 99 | sha_begin = (void*)sha512_begin; |
99 | sha_hash = (void*)sha512_hash; | 100 | sha_hash = (void*)sha512_hash; |
100 | sha_end = (void*)sha512_end; | 101 | sha_end = (void*)sha512_end; |
101 | _32or64 = 64; | ||
102 | } | 102 | } |
103 | 103 | ||
104 | /* Add KEY, SALT. */ | 104 | /* Add KEY, SALT. */ |
@@ -200,7 +200,7 @@ do { \ | |||
200 | unsigned w = ((B2) << 16) | ((B1) << 8) | (B0); \ | 200 | unsigned w = ((B2) << 16) | ((B1) << 8) | (B0); \ |
201 | resptr = to64(resptr, w, N); \ | 201 | resptr = to64(resptr, w, N); \ |
202 | } while (0) | 202 | } while (0) |
203 | if (is_sha512 == '5') { | 203 | if (_32or64 == 32) { /* sha256 */ |
204 | unsigned i = 0; | 204 | unsigned i = 0; |
205 | while (1) { | 205 | while (1) { |
206 | unsigned j = i + 10; | 206 | unsigned j = i + 10; |
diff --git a/libbb/vfork_daemon_rexec.c b/libbb/vfork_daemon_rexec.c index 766a89e5f..a6d260a40 100644 --- a/libbb/vfork_daemon_rexec.c +++ b/libbb/vfork_daemon_rexec.c | |||
@@ -185,26 +185,30 @@ int FAST_FUNC spawn_and_wait(char **argv) | |||
185 | #if ENABLE_FEATURE_PREFER_APPLETS | 185 | #if ENABLE_FEATURE_PREFER_APPLETS |
186 | int a = find_applet_by_name(argv[0]); | 186 | int a = find_applet_by_name(argv[0]); |
187 | 187 | ||
188 | if (a >= 0 && (APPLET_IS_NOFORK(a) | 188 | if (a >= 0) { |
189 | # if BB_MMU | ||
190 | || APPLET_IS_NOEXEC(a) /* NOEXEC trick needs fork() */ | ||
191 | # endif | ||
192 | )) { | ||
193 | # if BB_MMU | ||
194 | if (APPLET_IS_NOFORK(a)) | 189 | if (APPLET_IS_NOFORK(a)) |
195 | # endif | ||
196 | { | ||
197 | return run_nofork_applet(a, argv); | 190 | return run_nofork_applet(a, argv); |
191 | # if BB_MMU /* NOEXEC needs fork(), thus this is done only on MMU machines: */ | ||
192 | # if !ENABLE_PLATFORM_MINGW32 /* and then only if not on Microsoft Windows */ | ||
193 | if (APPLET_IS_NOEXEC(a)) { | ||
194 | fflush_all(); | ||
195 | rc = fork(); | ||
196 | if (rc) /* parent or error */ | ||
197 | return wait4pid(rc); | ||
198 | |||
199 | /* child */ | ||
200 | /* reset some state and run without execing */ | ||
201 | |||
202 | /* msg_eol = "\n"; - no caller needs this reinited yet */ | ||
203 | logmode = LOGMODE_STDIO; | ||
204 | /* die_func = NULL; - needed if the caller is a shell, | ||
205 | * init, or a NOFORK applet. But none of those call us | ||
206 | * as of yet (and that should probably always stay true). | ||
207 | */ | ||
208 | /* xfunc_error_retval and applet_name are init by: */ | ||
209 | run_applet_no_and_exit(a, argv); | ||
198 | } | 210 | } |
199 | # if BB_MMU && !ENABLE_PLATFORM_MINGW32 | 211 | # endif |
200 | /* MMU only */ | ||
201 | /* a->noexec is true */ | ||
202 | rc = fork(); | ||
203 | if (rc) /* parent or error */ | ||
204 | return wait4pid(rc); | ||
205 | /* child */ | ||
206 | xfunc_error_retval = EXIT_FAILURE; | ||
207 | run_applet_no_and_exit(a, argv); | ||
208 | # endif | 212 | # endif |
209 | } | 213 | } |
210 | #endif /* FEATURE_PREFER_APPLETS */ | 214 | #endif /* FEATURE_PREFER_APPLETS */ |
diff --git a/libbb/xfuncs.c b/libbb/xfuncs.c index 45650edba..98d3531d6 100644 --- a/libbb/xfuncs.c +++ b/libbb/xfuncs.c | |||
@@ -311,6 +311,43 @@ int FAST_FUNC tcsetattr_stdin_TCSANOW(const struct termios *tp) | |||
311 | return tcsetattr(STDIN_FILENO, TCSANOW, tp); | 311 | return tcsetattr(STDIN_FILENO, TCSANOW, tp); |
312 | } | 312 | } |
313 | 313 | ||
314 | int FAST_FUNC set_termios_to_raw(int fd, struct termios *oldterm, int flags) | ||
315 | { | ||
316 | //TODO: lineedit, microcom and less might be adapted to use this too: | ||
317 | // grep for "tcsetattr" | ||
318 | |||
319 | struct termios newterm; | ||
320 | |||
321 | tcgetattr(fd, oldterm); | ||
322 | newterm = *oldterm; | ||
323 | |||
324 | /* Turn off buffered input (ICANON) | ||
325 | * Turn off echoing (ECHO) | ||
326 | * and separate echoing of newline (ECHONL, normally off anyway) | ||
327 | */ | ||
328 | newterm.c_lflag &= ~(ICANON | ECHO | ECHONL); | ||
329 | if (flags & TERMIOS_CLEAR_ISIG) { | ||
330 | /* dont recognize INT/QUIT/SUSP chars */ | ||
331 | newterm.c_lflag &= ~ISIG; | ||
332 | } | ||
333 | /* reads will block only if < 1 char is available */ | ||
334 | newterm.c_cc[VMIN] = 1; | ||
335 | /* no timeout (reads block forever) */ | ||
336 | newterm.c_cc[VTIME] = 0; | ||
337 | if (flags & TERMIOS_RAW_CRNL) { | ||
338 | /* dont convert CR to NL on input */ | ||
339 | newterm.c_iflag &= ~(IXON | ICRNL); | ||
340 | /* dont convert NL to CR on output */ | ||
341 | newterm.c_oflag &= ~(ONLCR); | ||
342 | } | ||
343 | if (flags & TERMIOS_RAW_INPUT) { | ||
344 | /* dont convert anything on input */ | ||
345 | newterm.c_iflag &= ~(BRKINT|INLCR|ICRNL|IXON|IXOFF|IUCLC|IXANY|IMAXBEL); | ||
346 | } | ||
347 | |||
348 | return tcsetattr(fd, TCSANOW, &newterm); | ||
349 | } | ||
350 | |||
314 | pid_t FAST_FUNC safe_waitpid(pid_t pid, int *wstat, int options) | 351 | pid_t FAST_FUNC safe_waitpid(pid_t pid, int *wstat, int options) |
315 | { | 352 | { |
316 | pid_t r; | 353 | pid_t r; |
diff --git a/loginutils/Config.src b/loginutils/Config.src index efb954b6c..beb4eb855 100644 --- a/loginutils/Config.src +++ b/loginutils/Config.src | |||
@@ -6,7 +6,7 @@ | |||
6 | menu "Login/Password Management Utilities" | 6 | menu "Login/Password Management Utilities" |
7 | 7 | ||
8 | config FEATURE_SHADOWPASSWDS | 8 | config FEATURE_SHADOWPASSWDS |
9 | bool "Support for shadow passwords" | 9 | bool "Support shadow passwords" |
10 | default y | 10 | default y |
11 | help | 11 | help |
12 | Build support for shadow password in /etc/shadow. This file is only | 12 | Build support for shadow password in /etc/shadow. This file is only |
diff --git a/loginutils/add-remove-shell.c b/loginutils/add-remove-shell.c index ce4a7bbd2..af7c31779 100644 --- a/loginutils/add-remove-shell.c +++ b/loginutils/add-remove-shell.c | |||
@@ -19,6 +19,7 @@ | |||
19 | //config: help | 19 | //config: help |
20 | //config: Remove shells from /etc/shells. | 20 | //config: Remove shells from /etc/shells. |
21 | 21 | ||
22 | // APPLET_ODDNAME:name main location suid_type help | ||
22 | //applet:IF_ADD_SHELL( APPLET_ODDNAME(add-shell , add_remove_shell, BB_DIR_USR_SBIN, BB_SUID_DROP, add_shell )) | 23 | //applet:IF_ADD_SHELL( APPLET_ODDNAME(add-shell , add_remove_shell, BB_DIR_USR_SBIN, BB_SUID_DROP, add_shell )) |
23 | //applet:IF_REMOVE_SHELL(APPLET_ODDNAME(remove-shell, add_remove_shell, BB_DIR_USR_SBIN, BB_SUID_DROP, remove_shell)) | 24 | //applet:IF_REMOVE_SHELL(APPLET_ODDNAME(remove-shell, add_remove_shell, BB_DIR_USR_SBIN, BB_SUID_DROP, remove_shell)) |
24 | 25 | ||
diff --git a/loginutils/addgroup.c b/loginutils/addgroup.c index 6b2fd7ba9..94da4efbb 100644 --- a/loginutils/addgroup.c +++ b/loginutils/addgroup.c | |||
@@ -19,15 +19,13 @@ | |||
19 | //config: bool "Enable long options" | 19 | //config: bool "Enable long options" |
20 | //config: default y | 20 | //config: default y |
21 | //config: depends on ADDGROUP && LONG_OPTS | 21 | //config: depends on ADDGROUP && LONG_OPTS |
22 | //config: help | ||
23 | //config: Support long options for the addgroup applet. | ||
24 | //config: | 22 | //config: |
25 | //config:config FEATURE_ADDUSER_TO_GROUP | 23 | //config:config FEATURE_ADDUSER_TO_GROUP |
26 | //config: bool "Support for adding users to groups" | 24 | //config: bool "Support adding users to groups" |
27 | //config: default y | 25 | //config: default y |
28 | //config: depends on ADDGROUP | 26 | //config: depends on ADDGROUP |
29 | //config: help | 27 | //config: help |
30 | //config: If called with two non-option arguments, | 28 | //config: If called with two non-option arguments, |
31 | //config: addgroup will add an existing user to an | 29 | //config: addgroup will add an existing user to an |
32 | //config: existing group. | 30 | //config: existing group. |
33 | 31 | ||
diff --git a/loginutils/adduser.c b/loginutils/adduser.c index 608fb8437..40bc816a1 100644 --- a/loginutils/adduser.c +++ b/loginutils/adduser.c | |||
@@ -17,8 +17,6 @@ | |||
17 | //config: bool "Enable long options" | 17 | //config: bool "Enable long options" |
18 | //config: default y | 18 | //config: default y |
19 | //config: depends on ADDUSER && LONG_OPTS | 19 | //config: depends on ADDUSER && LONG_OPTS |
20 | //config: help | ||
21 | //config: Support long options for the adduser applet. | ||
22 | //config: | 20 | //config: |
23 | //config:config FEATURE_CHECK_NAMES | 21 | //config:config FEATURE_CHECK_NAMES |
24 | //config: bool "Enable sanity check on user/group names in adduser and addgroup" | 22 | //config: bool "Enable sanity check on user/group names in adduser and addgroup" |
@@ -66,7 +64,7 @@ | |||
66 | //usage: "\n -h DIR Home directory" | 64 | //usage: "\n -h DIR Home directory" |
67 | //usage: "\n -g GECOS GECOS field" | 65 | //usage: "\n -g GECOS GECOS field" |
68 | //usage: "\n -s SHELL Login shell" | 66 | //usage: "\n -s SHELL Login shell" |
69 | //usage: "\n -G GRP Add user to existing group" | 67 | //usage: "\n -G GRP Group" |
70 | //usage: "\n -S Create a system user" | 68 | //usage: "\n -S Create a system user" |
71 | //usage: "\n -D Don't assign a password" | 69 | //usage: "\n -D Don't assign a password" |
72 | //usage: "\n -H Don't create home directory" | 70 | //usage: "\n -H Don't create home directory" |
diff --git a/loginutils/chpasswd.c b/loginutils/chpasswd.c index 2d268be67..baafd35c8 100644 --- a/loginutils/chpasswd.c +++ b/loginutils/chpasswd.c | |||
@@ -13,9 +13,9 @@ | |||
13 | //config: and uses this information to update a group of existing users. | 13 | //config: and uses this information to update a group of existing users. |
14 | //config: | 14 | //config: |
15 | //config:config FEATURE_DEFAULT_PASSWD_ALGO | 15 | //config:config FEATURE_DEFAULT_PASSWD_ALGO |
16 | //config: string "Default password encryption method (passwd -a, cryptpw -m parameter)" | 16 | //config: string "Default encryption method (passwd -a, cryptpw -m, chpasswd -c ALG)" |
17 | //config: default "des" | 17 | //config: default "des" |
18 | //config: depends on PASSWD || CRYPTPW | 18 | //config: depends on PASSWD || CRYPTPW || CHPASSWD |
19 | //config: help | 19 | //config: help |
20 | //config: Possible choices are "d[es]", "m[d5]", "s[ha256]" or "sha512". | 20 | //config: Possible choices are "d[es]", "m[d5]", "s[ha256]" or "sha512". |
21 | 21 | ||
@@ -29,13 +29,13 @@ | |||
29 | //usage: "Read user:password from stdin and update /etc/passwd\n" | 29 | //usage: "Read user:password from stdin and update /etc/passwd\n" |
30 | //usage: IF_LONG_OPTS( | 30 | //usage: IF_LONG_OPTS( |
31 | //usage: "\n -e,--encrypted Supplied passwords are in encrypted form" | 31 | //usage: "\n -e,--encrypted Supplied passwords are in encrypted form" |
32 | //usage: "\n -m,--md5 Use MD5 encryption instead of DES" | 32 | //usage: "\n -m,--md5 Eencrypt using md5, not des" |
33 | //usage: "\n -c,--crypt-method Use the specified method to encrypt the passwords" | 33 | //usage: "\n -c,--crypt-method ALG "CRYPT_METHODS_HELP_STR |
34 | //usage: ) | 34 | //usage: ) |
35 | //usage: IF_NOT_LONG_OPTS( | 35 | //usage: IF_NOT_LONG_OPTS( |
36 | //usage: "\n -e Supplied passwords are in encrypted form" | 36 | //usage: "\n -e Supplied passwords are in encrypted form" |
37 | //usage: "\n -m Use MD5 encryption instead of DES" | 37 | //usage: "\n -m Eencrypt using md5, not des" |
38 | //usage: "\n -c Use the specified method to encrypt the passwords" | 38 | //usage: "\n -c ALG "CRYPT_METHODS_HELP_STR |
39 | //usage: ) | 39 | //usage: ) |
40 | 40 | ||
41 | #include "libbb.h" | 41 | #include "libbb.h" |
diff --git a/loginutils/cryptpw.c b/loginutils/cryptpw.c index 9f5f40686..696e169fc 100644 --- a/loginutils/cryptpw.c +++ b/loginutils/cryptpw.c | |||
@@ -35,17 +35,17 @@ | |||
35 | //usage: "[OPTIONS] [PASSWORD] [SALT]" | 35 | //usage: "[OPTIONS] [PASSWORD] [SALT]" |
36 | /* We do support -s, we just don't mention it */ | 36 | /* We do support -s, we just don't mention it */ |
37 | //usage:#define cryptpw_full_usage "\n\n" | 37 | //usage:#define cryptpw_full_usage "\n\n" |
38 | //usage: "Crypt PASSWORD using crypt(3)\n" | 38 | //usage: "Print crypt(3) hashed PASSWORD\n" |
39 | //usage: IF_LONG_OPTS( | 39 | //usage: IF_LONG_OPTS( |
40 | //usage: "\n -P,--password-fd=N Read password from fd N" | 40 | //usage: "\n -P,--password-fd N Read password from fd N" |
41 | /* //usage: "\n -s,--stdin Use stdin; like -P0" */ | 41 | /* //usage: "\n -s,--stdin Use stdin; like -P0" */ |
42 | //usage: "\n -m,--method=TYPE Encryption method" | 42 | //usage: "\n -m,--method TYPE "CRYPT_METHODS_HELP_STR |
43 | //usage: "\n -S,--salt=SALT" | 43 | //usage: "\n -S,--salt SALT" |
44 | //usage: ) | 44 | //usage: ) |
45 | //usage: IF_NOT_LONG_OPTS( | 45 | //usage: IF_NOT_LONG_OPTS( |
46 | //usage: "\n -P N Read password from fd N" | 46 | //usage: "\n -P N Read password from fd N" |
47 | /* //usage: "\n -s Use stdin; like -P0" */ | 47 | /* //usage: "\n -s Use stdin; like -P0" */ |
48 | //usage: "\n -m TYPE Encryption method TYPE" | 48 | //usage: "\n -m TYPE "CRYPT_METHODS_HELP_STR |
49 | //usage: "\n -S SALT" | 49 | //usage: "\n -S SALT" |
50 | //usage: ) | 50 | //usage: ) |
51 | 51 | ||
@@ -92,7 +92,8 @@ to cryptpw. -a option (alias for -m) came from cryptpw. | |||
92 | int cryptpw_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; | 92 | int cryptpw_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; |
93 | int cryptpw_main(int argc UNUSED_PARAM, char **argv) | 93 | int cryptpw_main(int argc UNUSED_PARAM, char **argv) |
94 | { | 94 | { |
95 | char salt[MAX_PW_SALT_LEN]; | 95 | /* Supports: cryptpw -m sha256 PASS 'rounds=999999999$SALT' */ |
96 | char salt[MAX_PW_SALT_LEN + sizeof("rounds=999999999$")]; | ||
96 | char *salt_ptr; | 97 | char *salt_ptr; |
97 | char *password; | 98 | char *password; |
98 | const char *opt_m, *opt_S; | 99 | const char *opt_m, *opt_S; |
@@ -122,6 +123,7 @@ int cryptpw_main(int argc UNUSED_PARAM, char **argv) | |||
122 | 123 | ||
123 | salt_ptr = crypt_make_pw_salt(salt, opt_m); | 124 | salt_ptr = crypt_make_pw_salt(salt, opt_m); |
124 | if (opt_S) | 125 | if (opt_S) |
126 | /* put user's data after the "$N$" prefix */ | ||
125 | safe_strncpy(salt_ptr, opt_S, sizeof(salt) - (sizeof("$N$")-1)); | 127 | safe_strncpy(salt_ptr, opt_S, sizeof(salt) - (sizeof("$N$")-1)); |
126 | 128 | ||
127 | xmove_fd(fd, STDIN_FILENO); | 129 | xmove_fd(fd, STDIN_FILENO); |
diff --git a/loginutils/deluser.c b/loginutils/deluser.c index 7c3caf9e3..fbb1614fb 100644 --- a/loginutils/deluser.c +++ b/loginutils/deluser.c | |||
@@ -21,7 +21,7 @@ | |||
21 | //config: Utility for deleting a group account. | 21 | //config: Utility for deleting a group account. |
22 | //config: | 22 | //config: |
23 | //config:config FEATURE_DEL_USER_FROM_GROUP | 23 | //config:config FEATURE_DEL_USER_FROM_GROUP |
24 | //config: bool "Support for removing users from groups" | 24 | //config: bool "Support removing users from groups" |
25 | //config: default y | 25 | //config: default y |
26 | //config: depends on DELGROUP | 26 | //config: depends on DELGROUP |
27 | //config: help | 27 | //config: help |
diff --git a/loginutils/getty.c b/loginutils/getty.c index 162c1697e..ba6c784a3 100644 --- a/loginutils/getty.c +++ b/loginutils/getty.c | |||
@@ -316,7 +316,7 @@ static void init_tty_attrs(int speed) | |||
316 | /* non-raw output; add CR to each NL */ | 316 | /* non-raw output; add CR to each NL */ |
317 | G.tty_attrs.c_oflag = OPOST | ONLCR; | 317 | G.tty_attrs.c_oflag = OPOST | ONLCR; |
318 | 318 | ||
319 | /* reads would block only if < 1 char is available */ | 319 | /* reads will block only if < 1 char is available */ |
320 | G.tty_attrs.c_cc[VMIN] = 1; | 320 | G.tty_attrs.c_cc[VMIN] = 1; |
321 | /* no timeout (reads block forever) */ | 321 | /* no timeout (reads block forever) */ |
322 | G.tty_attrs.c_cc[VTIME] = 0; | 322 | G.tty_attrs.c_cc[VTIME] = 0; |
diff --git a/loginutils/login.c b/loginutils/login.c index 3ca8213bb..d1757a65d 100644 --- a/loginutils/login.c +++ b/loginutils/login.c | |||
@@ -24,7 +24,7 @@ | |||
24 | //config: will not be cleaned up. | 24 | //config: will not be cleaned up. |
25 | //config: | 25 | //config: |
26 | //config:config LOGIN_SCRIPTS | 26 | //config:config LOGIN_SCRIPTS |
27 | //config: bool "Support for login scripts" | 27 | //config: bool "Support login scripts" |
28 | //config: depends on LOGIN | 28 | //config: depends on LOGIN |
29 | //config: default y | 29 | //config: default y |
30 | //config: help | 30 | //config: help |
@@ -32,7 +32,7 @@ | |||
32 | //config: just prior to switching from root to logged-in user. | 32 | //config: just prior to switching from root to logged-in user. |
33 | //config: | 33 | //config: |
34 | //config:config FEATURE_NOLOGIN | 34 | //config:config FEATURE_NOLOGIN |
35 | //config: bool "Support for /etc/nologin" | 35 | //config: bool "Support /etc/nologin" |
36 | //config: default y | 36 | //config: default y |
37 | //config: depends on LOGIN | 37 | //config: depends on LOGIN |
38 | //config: help | 38 | //config: help |
@@ -40,7 +40,7 @@ | |||
40 | //config: If it exists, non-root logins are prohibited. | 40 | //config: If it exists, non-root logins are prohibited. |
41 | //config: | 41 | //config: |
42 | //config:config FEATURE_SECURETTY | 42 | //config:config FEATURE_SECURETTY |
43 | //config: bool "Support for /etc/securetty" | 43 | //config: bool "Support /etc/securetty" |
44 | //config: default y | 44 | //config: default y |
45 | //config: depends on LOGIN | 45 | //config: depends on LOGIN |
46 | //config: help | 46 | //config: help |
diff --git a/loginutils/passwd.c b/loginutils/passwd.c index 52b66ca50..b7b7423fd 100644 --- a/loginutils/passwd.c +++ b/loginutils/passwd.c | |||
@@ -32,7 +32,7 @@ | |||
32 | //usage:#define passwd_full_usage "\n\n" | 32 | //usage:#define passwd_full_usage "\n\n" |
33 | //usage: "Change USER's password (default: current user)" | 33 | //usage: "Change USER's password (default: current user)" |
34 | //usage: "\n" | 34 | //usage: "\n" |
35 | //usage: "\n -a ALG Encryption method" | 35 | //usage: "\n -a ALG "CRYPT_METHODS_HELP_STR |
36 | //usage: "\n -d Set password to ''" | 36 | //usage: "\n -d Set password to ''" |
37 | //usage: "\n -l Lock (disable) account" | 37 | //usage: "\n -l Lock (disable) account" |
38 | //usage: "\n -u Unlock (enable) account" | 38 | //usage: "\n -u Unlock (enable) account" |
diff --git a/loginutils/su.c b/loginutils/su.c index 24ffbde86..d04b85fb1 100644 --- a/loginutils/su.c +++ b/loginutils/su.c | |||
@@ -11,19 +11,18 @@ | |||
11 | //config: help | 11 | //config: help |
12 | //config: su is used to become another user during a login session. | 12 | //config: su is used to become another user during a login session. |
13 | //config: Invoked without a username, su defaults to becoming the super user. | 13 | //config: Invoked without a username, su defaults to becoming the super user. |
14 | //config: | 14 | //config: Note that busybox binary must be setuid root for this applet to |
15 | //config: Note that Busybox binary must be setuid root for this applet to | ||
16 | //config: work properly. | 15 | //config: work properly. |
17 | //config: | 16 | //config: |
18 | //config:config FEATURE_SU_SYSLOG | 17 | //config:config FEATURE_SU_SYSLOG |
19 | //config: bool "Enable su to write to syslog" | 18 | //config: bool "Log to syslog all attempts to use su" |
20 | //config: default y | 19 | //config: default y |
21 | //config: depends on SU | 20 | //config: depends on SU |
22 | //config: | 21 | //config: |
23 | //config:config FEATURE_SU_CHECKS_SHELLS | 22 | //config:config FEATURE_SU_CHECKS_SHELLS |
24 | //config: bool "Enable su to check user's shell to be listed in /etc/shells" | 23 | //config: bool "If user's shell is not in /etc/shells, disallow -s PROG" |
25 | //config: depends on SU | ||
26 | //config: default y | 24 | //config: default y |
25 | //config: depends on SU | ||
27 | 26 | ||
28 | //applet:/* Needs to be run by root or be suid root - needs to change uid and gid: */ | 27 | //applet:/* Needs to be run by root or be suid root - needs to change uid and gid: */ |
29 | //applet:IF_SU(APPLET(su, BB_DIR_BIN, BB_SUID_REQUIRE)) | 28 | //applet:IF_SU(APPLET(su, BB_DIR_BIN, BB_SUID_REQUIRE)) |
diff --git a/loginutils/vlock.c b/loginutils/vlock.c index 52ae607c9..5ba6a8780 100644 --- a/loginutils/vlock.c +++ b/loginutils/vlock.c | |||
@@ -105,12 +105,12 @@ int vlock_main(int argc UNUSED_PARAM, char **argv) | |||
105 | ioctl(STDIN_FILENO, VT_SETMODE, &vtm); | 105 | ioctl(STDIN_FILENO, VT_SETMODE, &vtm); |
106 | #endif | 106 | #endif |
107 | 107 | ||
108 | //TODO: use set_termios_to_raw() | ||
108 | tcgetattr(STDIN_FILENO, &oterm); | 109 | tcgetattr(STDIN_FILENO, &oterm); |
109 | term = oterm; | 110 | term = oterm; |
110 | term.c_iflag &= ~BRKINT; | 111 | term.c_iflag |= IGNBRK; /* ignore serial break (why? VTs don't have breaks, right?) */ |
111 | term.c_iflag |= IGNBRK; | 112 | term.c_iflag &= ~BRKINT; /* redundant? "dont translate break to SIGINT" */ |
112 | term.c_lflag &= ~ISIG; | 113 | term.c_lflag &= ~(ISIG | ECHO | ECHOCTL); /* ignore ^C ^Z, echo off */ |
113 | term.c_lflag &= ~(ECHO | ECHOCTL); | ||
114 | tcsetattr_stdin_TCSANOW(&term); | 114 | tcsetattr_stdin_TCSANOW(&term); |
115 | 115 | ||
116 | while (1) { | 116 | while (1) { |
diff --git a/make_single_applets.sh b/make_single_applets.sh index 00f502eda..8ad7a7406 100755 --- a/make_single_applets.sh +++ b/make_single_applets.sh | |||
@@ -28,9 +28,14 @@ for app in $apps; do | |||
28 | done | 28 | done |
29 | #echo "$allno" >.config_allno | 29 | #echo "$allno" >.config_allno |
30 | 30 | ||
31 | trap 'test -f .config.SV && mv .config.SV .config && touch .config' EXIT | ||
32 | |||
33 | |||
31 | # Turn on each applet individually and build single-applet executable | 34 | # Turn on each applet individually and build single-applet executable |
35 | # (give config names on command line to build only those) | ||
36 | test $# = 0 && set -- $apps | ||
32 | fail=0 | 37 | fail=0 |
33 | for app in $apps; do | 38 | for app; do |
34 | # Only if it was indeed originally enabled... | 39 | # Only if it was indeed originally enabled... |
35 | { echo "$cfg" | grep -q "^CONFIG_${app}=y\$"; } || continue | 40 | { echo "$cfg" | grep -q "^CONFIG_${app}=y\$"; } || continue |
36 | 41 | ||
@@ -54,16 +59,20 @@ for app in $apps; do | |||
54 | mv .config busybox_config_${app} | 59 | mv .config busybox_config_${app} |
55 | elif ! make $makeopts >>busybox_make_${app}.log 2>&1; then | 60 | elif ! make $makeopts >>busybox_make_${app}.log 2>&1; then |
56 | : $((fail++)) | 61 | : $((fail++)) |
62 | grep -i -e error: -e warning: busybox_make_${app}.log | ||
57 | echo "Build error for ${app}" | 63 | echo "Build error for ${app}" |
58 | mv .config busybox_config_${app} | 64 | mv .config busybox_config_${app} |
59 | elif ! grep -q '^#define NUM_APPLETS 1$' include/NUM_APPLETS.h; then | 65 | elif ! grep -q '^#define NUM_APPLETS 1$' include/NUM_APPLETS.h; then |
66 | grep -i -e error: -e warning: busybox_make_${app}.log | ||
60 | mv busybox busybox_${app} | 67 | mv busybox busybox_${app} |
61 | : $((fail++)) | 68 | : $((fail++)) |
62 | echo "NUM_APPLETS != 1 for ${app}: `cat include/NUM_APPLETS.h`" | 69 | echo "NUM_APPLETS != 1 for ${app}: `cat include/NUM_APPLETS.h`" |
63 | mv .config busybox_config_${app} | 70 | mv .config busybox_config_${app} |
64 | else | 71 | else |
72 | grep -i -e error: -e warning: busybox_make_${app}.log \ | ||
73 | || rm busybox_make_${app}.log | ||
65 | mv busybox busybox_${app} | 74 | mv busybox busybox_${app} |
66 | rm busybox_make_${app}.log | 75 | #mv .config busybox_config_${app} |
67 | fi | 76 | fi |
68 | mv .config.SV .config | 77 | mv .config.SV .config |
69 | #exit | 78 | #exit |
diff --git a/miscutils/chat.c b/miscutils/chat.c index dc85f82fb..8df194534 100644 --- a/miscutils/chat.c +++ b/miscutils/chat.c | |||
@@ -213,6 +213,7 @@ int chat_main(int argc UNUSED_PARAM, char **argv) | |||
213 | , signal_handler); | 213 | , signal_handler); |
214 | 214 | ||
215 | #if ENABLE_FEATURE_CHAT_TTY_HIFI | 215 | #if ENABLE_FEATURE_CHAT_TTY_HIFI |
216 | //TODO: use set_termios_to_raw() | ||
216 | tcgetattr(STDIN_FILENO, &tio); | 217 | tcgetattr(STDIN_FILENO, &tio); |
217 | tio0 = tio; | 218 | tio0 = tio; |
218 | cfmakeraw(&tio); | 219 | cfmakeraw(&tio); |
diff --git a/miscutils/conspy.c b/miscutils/conspy.c index d9d09d482..1f0278b47 100644 --- a/miscutils/conspy.c +++ b/miscutils/conspy.c | |||
@@ -363,7 +363,6 @@ int conspy_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; | |||
363 | int conspy_main(int argc UNUSED_PARAM, char **argv) | 363 | int conspy_main(int argc UNUSED_PARAM, char **argv) |
364 | { | 364 | { |
365 | char tty_name[sizeof(DEV_TTY "NN")]; | 365 | char tty_name[sizeof(DEV_TTY "NN")]; |
366 | struct termios termbuf; | ||
367 | unsigned opts; | 366 | unsigned opts; |
368 | unsigned ttynum; | 367 | unsigned ttynum; |
369 | int poll_timeout_ms; | 368 | int poll_timeout_ms; |
@@ -414,16 +413,14 @@ int conspy_main(int argc UNUSED_PARAM, char **argv) | |||
414 | 413 | ||
415 | bb_signals(BB_FATAL_SIGS, cleanup); | 414 | bb_signals(BB_FATAL_SIGS, cleanup); |
416 | 415 | ||
417 | // All characters must be passed through to us unaltered | ||
418 | G.kbd_fd = xopen(CURRENT_TTY, O_RDONLY); | 416 | G.kbd_fd = xopen(CURRENT_TTY, O_RDONLY); |
419 | tcgetattr(G.kbd_fd, &G.term_orig); | 417 | |
420 | termbuf = G.term_orig; | 418 | // All characters must be passed through to us unaltered |
421 | termbuf.c_iflag &= ~(BRKINT|INLCR|ICRNL|IXON|IXOFF|IUCLC|IXANY|IMAXBEL); | 419 | set_termios_to_raw(G.kbd_fd, &G.term_orig, 0 |
422 | //termbuf.c_oflag &= ~(OPOST); - no, we still want \n -> \r\n | 420 | | TERMIOS_CLEAR_ISIG // no signals on ^C ^Z etc |
423 | termbuf.c_lflag &= ~(ISIG|ICANON|ECHO); | 421 | | TERMIOS_RAW_INPUT // turn off all input conversions |
424 | termbuf.c_cc[VMIN] = 1; | 422 | ); |
425 | termbuf.c_cc[VTIME] = 0; | 423 | //Note: termios.c_oflag &= ~(OPOST); - no, we still want \n -> \r\n |
426 | tcsetattr(G.kbd_fd, TCSANOW, &termbuf); | ||
427 | 424 | ||
428 | poll_timeout_ms = 250; | 425 | poll_timeout_ms = 250; |
429 | while (1) { | 426 | while (1) { |
diff --git a/miscutils/crond.c b/miscutils/crond.c index f96c96ee7..88e7b47b3 100644 --- a/miscutils/crond.c +++ b/miscutils/crond.c | |||
@@ -52,7 +52,7 @@ | |||
52 | //usage: " -f Foreground" | 52 | //usage: " -f Foreground" |
53 | //usage: "\n -b Background (default)" | 53 | //usage: "\n -b Background (default)" |
54 | //usage: "\n -S Log to syslog (default)" | 54 | //usage: "\n -S Log to syslog (default)" |
55 | //usage: "\n -l N Set log level. Most verbose:0, default:8" | 55 | //usage: "\n -l N Set log level. Most verbose 0, default 8" |
56 | //usage: IF_FEATURE_CROND_D( | 56 | //usage: IF_FEATURE_CROND_D( |
57 | //usage: "\n -d N Set log level, log to stderr" | 57 | //usage: "\n -d N Set log level, log to stderr" |
58 | //usage: ) | 58 | //usage: ) |
diff --git a/miscutils/devfsd.c b/miscutils/devfsd.c index 99bdc72b8..334f1071b 100644 --- a/miscutils/devfsd.c +++ b/miscutils/devfsd.c | |||
@@ -82,7 +82,7 @@ | |||
82 | //config: the external modutils. | 82 | //config: the external modutils. |
83 | //config: | 83 | //config: |
84 | //config:config DEVFSD_FG_NP | 84 | //config:config DEVFSD_FG_NP |
85 | //config: bool "Enables the -fg and -np options" | 85 | //config: bool "Enable the -fg and -np options" |
86 | //config: default y | 86 | //config: default y |
87 | //config: depends on DEVFSD | 87 | //config: depends on DEVFSD |
88 | //config: help | 88 | //config: help |
diff --git a/miscutils/flash_lock_unlock.c b/miscutils/flash_lock_unlock.c index 2f698641f..003496d5b 100644 --- a/miscutils/flash_lock_unlock.c +++ b/miscutils/flash_lock_unlock.c | |||
@@ -17,7 +17,8 @@ | |||
17 | //config: The flash_unlock binary from mtd-utils as of git head 5ec0c10d0. This | 17 | //config: The flash_unlock binary from mtd-utils as of git head 5ec0c10d0. This |
18 | //config: utility unlocks part or all of the flash device. | 18 | //config: utility unlocks part or all of the flash device. |
19 | 19 | ||
20 | //applet:IF_FLASH_LOCK(APPLET_ODDNAME(flash_lock, flash_lock_unlock, BB_DIR_USR_SBIN, BB_SUID_DROP, flash_lock)) | 20 | // APPLET_ODDNAME:name main location suid_type help |
21 | //applet:IF_FLASH_LOCK( APPLET_ODDNAME(flash_lock, flash_lock_unlock, BB_DIR_USR_SBIN, BB_SUID_DROP, flash_lock)) | ||
21 | //applet:IF_FLASH_UNLOCK(APPLET_ODDNAME(flash_unlock, flash_lock_unlock, BB_DIR_USR_SBIN, BB_SUID_DROP, flash_unlock)) | 22 | //applet:IF_FLASH_UNLOCK(APPLET_ODDNAME(flash_unlock, flash_lock_unlock, BB_DIR_USR_SBIN, BB_SUID_DROP, flash_unlock)) |
22 | 23 | ||
23 | //kbuild:lib-$(CONFIG_FLASH_LOCK) += flash_lock_unlock.o | 24 | //kbuild:lib-$(CONFIG_FLASH_LOCK) += flash_lock_unlock.o |
diff --git a/miscutils/hdparm.c b/miscutils/hdparm.c index e43a0dec2..84675285a 100644 --- a/miscutils/hdparm.c +++ b/miscutils/hdparm.c | |||
@@ -25,7 +25,7 @@ | |||
25 | //config: default y | 25 | //config: default y |
26 | //config: depends on HDPARM | 26 | //config: depends on HDPARM |
27 | //config: help | 27 | //config: help |
28 | //config: Enables the -I and -i options to obtain detailed information | 28 | //config: Enable the -I and -i options to obtain detailed information |
29 | //config: directly from drives about their capabilities and supported ATA | 29 | //config: directly from drives about their capabilities and supported ATA |
30 | //config: feature set. If no device name is specified, hdparm will read | 30 | //config: feature set. If no device name is specified, hdparm will read |
31 | //config: identify data from stdin. Enabling this option will add about 16k... | 31 | //config: identify data from stdin. Enabling this option will add about 16k... |
@@ -35,7 +35,7 @@ | |||
35 | //config: default y | 35 | //config: default y |
36 | //config: depends on HDPARM | 36 | //config: depends on HDPARM |
37 | //config: help | 37 | //config: help |
38 | //config: Enables the 'hdparm -R' option to register an IDE interface. | 38 | //config: Enable the 'hdparm -R' option to register an IDE interface. |
39 | //config: This is dangerous stuff, so you should probably say N. | 39 | //config: This is dangerous stuff, so you should probably say N. |
40 | //config: | 40 | //config: |
41 | //config:config FEATURE_HDPARM_HDIO_UNREGISTER_HWIF | 41 | //config:config FEATURE_HDPARM_HDIO_UNREGISTER_HWIF |
@@ -43,7 +43,7 @@ | |||
43 | //config: default y | 43 | //config: default y |
44 | //config: depends on HDPARM | 44 | //config: depends on HDPARM |
45 | //config: help | 45 | //config: help |
46 | //config: Enables the 'hdparm -U' option to un-register an IDE interface. | 46 | //config: Enable the 'hdparm -U' option to un-register an IDE interface. |
47 | //config: This is dangerous stuff, so you should probably say N. | 47 | //config: This is dangerous stuff, so you should probably say N. |
48 | //config: | 48 | //config: |
49 | //config:config FEATURE_HDPARM_HDIO_DRIVE_RESET | 49 | //config:config FEATURE_HDPARM_HDIO_DRIVE_RESET |
@@ -51,7 +51,7 @@ | |||
51 | //config: default y | 51 | //config: default y |
52 | //config: depends on HDPARM | 52 | //config: depends on HDPARM |
53 | //config: help | 53 | //config: help |
54 | //config: Enables the 'hdparm -w' option to perform a device reset. | 54 | //config: Enable the 'hdparm -w' option to perform a device reset. |
55 | //config: This is dangerous stuff, so you should probably say N. | 55 | //config: This is dangerous stuff, so you should probably say N. |
56 | //config: | 56 | //config: |
57 | //config:config FEATURE_HDPARM_HDIO_TRISTATE_HWIF | 57 | //config:config FEATURE_HDPARM_HDIO_TRISTATE_HWIF |
@@ -59,7 +59,7 @@ | |||
59 | //config: default y | 59 | //config: default y |
60 | //config: depends on HDPARM | 60 | //config: depends on HDPARM |
61 | //config: help | 61 | //config: help |
62 | //config: Enables the 'hdparm -x' option to tristate device for hotswap, | 62 | //config: Enable the 'hdparm -x' option to tristate device for hotswap, |
63 | //config: and the '-b' option to get/set bus state. This is dangerous | 63 | //config: and the '-b' option to get/set bus state. This is dangerous |
64 | //config: stuff, so you should probably say N. | 64 | //config: stuff, so you should probably say N. |
65 | //config: | 65 | //config: |
@@ -68,7 +68,7 @@ | |||
68 | //config: default y | 68 | //config: default y |
69 | //config: depends on HDPARM | 69 | //config: depends on HDPARM |
70 | //config: help | 70 | //config: help |
71 | //config: Enables the 'hdparm -d' option to get/set using_dma flag. | 71 | //config: Enable the 'hdparm -d' option to get/set using_dma flag. |
72 | 72 | ||
73 | //applet:IF_HDPARM(APPLET(hdparm, BB_DIR_SBIN, BB_SUID_DROP)) | 73 | //applet:IF_HDPARM(APPLET(hdparm, BB_DIR_SBIN, BB_SUID_DROP)) |
74 | 74 | ||
diff --git a/miscutils/last.c b/miscutils/last.c index 67c1343f1..b3f125c3f 100644 --- a/miscutils/last.c +++ b/miscutils/last.c | |||
@@ -14,7 +14,7 @@ | |||
14 | //config: 'last' displays a list of the last users that logged into the system. | 14 | //config: 'last' displays a list of the last users that logged into the system. |
15 | //config: | 15 | //config: |
16 | //config:config FEATURE_LAST_FANCY | 16 | //config:config FEATURE_LAST_FANCY |
17 | //config: bool "Turn on output of extra information" | 17 | //config: bool "Output extra information" |
18 | //config: default y | 18 | //config: default y |
19 | //config: depends on LAST | 19 | //config: depends on LAST |
20 | //config: help | 20 | //config: help |
diff --git a/miscutils/less.c b/miscutils/less.c index 8f9b329ba..220e2c693 100644 --- a/miscutils/less.c +++ b/miscutils/less.c | |||
@@ -87,7 +87,6 @@ | |||
87 | //config: this option makes less perform a last-ditch effort to find it: | 87 | //config: this option makes less perform a last-ditch effort to find it: |
88 | //config: position cursor to 999,999 and ask terminal to report real | 88 | //config: position cursor to 999,999 and ask terminal to report real |
89 | //config: cursor position using "ESC [ 6 n" escape sequence, then read stdin. | 89 | //config: cursor position using "ESC [ 6 n" escape sequence, then read stdin. |
90 | //config: | ||
91 | //config: This is not clean but helps a lot on serial lines and such. | 90 | //config: This is not clean but helps a lot on serial lines and such. |
92 | //config: | 91 | //config: |
93 | //config:config FEATURE_LESS_DASHCMD | 92 | //config:config FEATURE_LESS_DASHCMD |
@@ -99,11 +98,9 @@ | |||
99 | //config: less itself ('-' keyboard command). | 98 | //config: less itself ('-' keyboard command). |
100 | //config: | 99 | //config: |
101 | //config:config FEATURE_LESS_LINENUMS | 100 | //config:config FEATURE_LESS_LINENUMS |
102 | //config: bool "Enable dynamic switching of line numbers" | 101 | //config: bool "Enable -N (dynamic switching of line numbers)" |
103 | //config: default y | 102 | //config: default y |
104 | //config: depends on FEATURE_LESS_DASHCMD | 103 | //config: depends on FEATURE_LESS_DASHCMD |
105 | //config: help | ||
106 | //config: Enables "-N" command. | ||
107 | 104 | ||
108 | //applet:IF_LESS(APPLET(less, BB_DIR_USR_BIN, BB_SUID_DROP)) | 105 | //applet:IF_LESS(APPLET(less, BB_DIR_USR_BIN, BB_SUID_DROP)) |
109 | 106 | ||
diff --git a/miscutils/microcom.c b/miscutils/microcom.c index 04605d883..5a4bbefa9 100644 --- a/miscutils/microcom.c +++ b/miscutils/microcom.c | |||
@@ -33,6 +33,7 @@ | |||
33 | // set raw tty mode | 33 | // set raw tty mode |
34 | static void xget1(int fd, struct termios *t, struct termios *oldt) | 34 | static void xget1(int fd, struct termios *t, struct termios *oldt) |
35 | { | 35 | { |
36 | //TODO: use set_termios_to_raw() | ||
36 | tcgetattr(fd, oldt); | 37 | tcgetattr(fd, oldt); |
37 | *t = *oldt; | 38 | *t = *oldt; |
38 | cfmakeraw(t); | 39 | cfmakeraw(t); |
diff --git a/miscutils/nandwrite.c b/miscutils/nandwrite.c index c95cbb21e..dbe9043f4 100644 --- a/miscutils/nandwrite.c +++ b/miscutils/nandwrite.c | |||
@@ -37,7 +37,7 @@ | |||
37 | //usage: "\n -s ADDR Start address" | 37 | //usage: "\n -s ADDR Start address" |
38 | 38 | ||
39 | //usage:#define nanddump_trivial_usage | 39 | //usage:#define nanddump_trivial_usage |
40 | //usage: "[-no]" IF_LONG_OPTS(" [--bb=padbad|skipbad]") " [-s ADDR] [-l LEN] [-f FILE] MTD_DEVICE" | 40 | //usage: "[-no]" IF_LONG_OPTS(" [--bb padbad|skipbad]") " [-s ADDR] [-l LEN] [-f FILE] MTD_DEVICE" |
41 | //usage:#define nanddump_full_usage "\n\n" | 41 | //usage:#define nanddump_full_usage "\n\n" |
42 | //usage: "Dump MTD_DEVICE\n" | 42 | //usage: "Dump MTD_DEVICE\n" |
43 | //usage: "\n -n Read without ecc" | 43 | //usage: "\n -n Read without ecc" |
@@ -46,7 +46,7 @@ | |||
46 | //usage: "\n -l LEN Length" | 46 | //usage: "\n -l LEN Length" |
47 | //usage: "\n -f FILE Dump to file ('-' for stdout)" | 47 | //usage: "\n -f FILE Dump to file ('-' for stdout)" |
48 | //usage: IF_LONG_OPTS( | 48 | //usage: IF_LONG_OPTS( |
49 | //usage: "\n --bb=METHOD:" | 49 | //usage: "\n --bb METHOD" |
50 | //usage: "\n skipbad: skip bad blocks" | 50 | //usage: "\n skipbad: skip bad blocks" |
51 | //usage: "\n padbad: substitute bad blocks by 0xff (default)" | 51 | //usage: "\n padbad: substitute bad blocks by 0xff (default)" |
52 | //usage: ) | 52 | //usage: ) |
diff --git a/miscutils/rx.c b/miscutils/rx.c index 660f66a89..1f6f2825c 100644 --- a/miscutils/rx.c +++ b/miscutils/rx.c | |||
@@ -94,7 +94,7 @@ static int receive(/*int read_fd, */int file_fd) | |||
94 | int blockBegin; | 94 | int blockBegin; |
95 | int blockNo, blockNoOnesCompl; | 95 | int blockNo, blockNoOnesCompl; |
96 | int cksum_or_crc; | 96 | int cksum_or_crc; |
97 | int expected; | 97 | unsigned expected; |
98 | int i, j; | 98 | int i, j; |
99 | 99 | ||
100 | blockBegin = read_byte(timeout); | 100 | blockBegin = read_byte(timeout); |
@@ -263,6 +263,7 @@ int rx_main(int argc UNUSED_PARAM, char **argv) | |||
263 | 263 | ||
264 | termios_err = tcgetattr(read_fd, &tty); | 264 | termios_err = tcgetattr(read_fd, &tty); |
265 | if (termios_err == 0) { | 265 | if (termios_err == 0) { |
266 | //TODO: use set_termios_to_raw() | ||
266 | orig_tty = tty; | 267 | orig_tty = tty; |
267 | cfmakeraw(&tty); | 268 | cfmakeraw(&tty); |
268 | tcsetattr(read_fd, TCSAFLUSH, &tty); | 269 | tcsetattr(read_fd, TCSAFLUSH, &tty); |
diff --git a/miscutils/taskset.c b/miscutils/taskset.c index fb352ab8d..94a07383a 100644 --- a/miscutils/taskset.c +++ b/miscutils/taskset.c | |||
@@ -8,7 +8,7 @@ | |||
8 | 8 | ||
9 | //config:config TASKSET | 9 | //config:config TASKSET |
10 | //config: bool "taskset" | 10 | //config: bool "taskset" |
11 | //config: default n # doesn't build on some non-x86 targets (m68k) | 11 | //config: default y |
12 | //config: help | 12 | //config: help |
13 | //config: Retrieve or set a processes's CPU affinity. | 13 | //config: Retrieve or set a processes's CPU affinity. |
14 | //config: This requires sched_{g,s}etaffinity support in your libc. | 14 | //config: This requires sched_{g,s}etaffinity support in your libc. |
@@ -18,15 +18,15 @@ | |||
18 | //config: default y | 18 | //config: default y |
19 | //config: depends on TASKSET | 19 | //config: depends on TASKSET |
20 | //config: help | 20 | //config: help |
21 | //config: Add code for fancy output. This merely silences a compiler-warning | 21 | //config: Needed for machines with more than 32-64 CPUs: |
22 | //config: and adds about 135 Bytes. May be needed for machines with alot | 22 | //config: affinity parameter 0xHHHHHHHHHHHHHHHHHHHH can be arbitrarily long |
23 | //config: of CPUs. | 23 | //config: in this case. Otherwise, it is limited to sizeof(long). |
24 | 24 | ||
25 | //applet:IF_TASKSET(APPLET(taskset, BB_DIR_USR_BIN, BB_SUID_DROP)) | 25 | //applet:IF_TASKSET(APPLET(taskset, BB_DIR_USR_BIN, BB_SUID_DROP)) |
26 | //kbuild:lib-$(CONFIG_TASKSET) += taskset.o | 26 | //kbuild:lib-$(CONFIG_TASKSET) += taskset.o |
27 | 27 | ||
28 | //usage:#define taskset_trivial_usage | 28 | //usage:#define taskset_trivial_usage |
29 | //usage: "[-p] [MASK] [PID | PROG ARGS]" | 29 | //usage: "[-p] [HEXMASK] PID | PROG ARGS" |
30 | //usage:#define taskset_full_usage "\n\n" | 30 | //usage:#define taskset_full_usage "\n\n" |
31 | //usage: "Set or get CPU affinity\n" | 31 | //usage: "Set or get CPU affinity\n" |
32 | //usage: "\n -p Operate on an existing PID" | 32 | //usage: "\n -p Operate on an existing PID" |
@@ -42,72 +42,81 @@ | |||
42 | //usage: "$ taskset -p 1\n" | 42 | //usage: "$ taskset -p 1\n" |
43 | //usage: "pid 1's current affinity mask: 3\n" | 43 | //usage: "pid 1's current affinity mask: 3\n" |
44 | /* | 44 | /* |
45 | Not yet implemented: | 45 | * Not yet implemented: |
46 | * -a/--all-tasks (affect all threads) | 46 | * -a/--all-tasks (affect all threads) |
47 | * needs to get TIDs from /proc/PID/task/ and use _them_ as "pid" in sched_setaffinity(pid) | ||
47 | * -c/--cpu-list (specify CPUs via "1,3,5-7") | 48 | * -c/--cpu-list (specify CPUs via "1,3,5-7") |
48 | */ | 49 | */ |
49 | 50 | ||
50 | #include <sched.h> | 51 | #include <sched.h> |
51 | #include "libbb.h" | 52 | #include "libbb.h" |
52 | 53 | ||
54 | typedef unsigned long ul; | ||
55 | #define SZOF_UL (unsigned)(sizeof(ul)) | ||
56 | #define BITS_UL (unsigned)(sizeof(ul)*8) | ||
57 | #define MASK_UL (unsigned)(sizeof(ul)*8 - 1) | ||
58 | |||
53 | #if ENABLE_FEATURE_TASKSET_FANCY | 59 | #if ENABLE_FEATURE_TASKSET_FANCY |
54 | #define TASKSET_PRINTF_MASK "%s" | 60 | #define TASKSET_PRINTF_MASK "%s" |
55 | /* craft a string from the mask */ | 61 | /* craft a string from the mask */ |
56 | static char *from_cpuset(cpu_set_t *mask) | 62 | static char *from_mask(const ul *mask, unsigned sz_in_bytes) |
57 | { | 63 | { |
58 | int i; | 64 | char *str = xzalloc((sz_in_bytes+1) * 2); /* we will leak it */ |
59 | char *ret = NULL; | 65 | char *p = str; |
60 | char *str = xzalloc((CPU_SETSIZE / 4) + 1); /* we will leak it */ | 66 | for (;;) { |
61 | 67 | ul v = *mask++; | |
62 | for (i = CPU_SETSIZE - 4; i >= 0; i -= 4) { | 68 | if (SZOF_UL == 4) |
63 | int val = 0; | 69 | p += sprintf(p, "%08lx", v); |
64 | int off; | 70 | if (SZOF_UL == 8) |
65 | for (off = 0; off <= 3; ++off) | 71 | p += sprintf(p, "%016lx", v); |
66 | if (CPU_ISSET(i + off, mask)) | 72 | if (SZOF_UL == 16) |
67 | val |= 1 << off; | 73 | p += sprintf(p, "%032lx", v); /* :) */ |
68 | if (!ret && val) | 74 | sz_in_bytes -= SZOF_UL; |
69 | ret = str; | 75 | if ((int)sz_in_bytes <= 0) |
70 | *str++ = bb_hexdigits_upcase[val] | 0x20; | 76 | break; |
71 | } | 77 | } |
72 | return ret; | 78 | while (str[0] == '0' && str[1]) |
79 | str++; | ||
80 | return str; | ||
73 | } | 81 | } |
74 | #else | 82 | #else |
75 | #define TASKSET_PRINTF_MASK "%llx" | 83 | #define TASKSET_PRINTF_MASK "%lx" |
76 | static unsigned long long from_cpuset(cpu_set_t *mask) | 84 | static unsigned long long from_mask(ul *mask, unsigned sz_in_bytes UNUSED_PARAM) |
77 | { | 85 | { |
78 | BUILD_BUG_ON(CPU_SETSIZE < 8*sizeof(int)); | 86 | return *mask; |
79 | |||
80 | /* Take the least significant bits. Assume cpu_set_t is | ||
81 | * implemented as an array of unsigned long or unsigned | ||
82 | * int. | ||
83 | */ | ||
84 | if (CPU_SETSIZE < 8*sizeof(long)) | ||
85 | return *(unsigned*)mask; | ||
86 | if (CPU_SETSIZE < 8*sizeof(long long)) | ||
87 | return *(unsigned long*)mask; | ||
88 | # if BB_BIG_ENDIAN | ||
89 | if (sizeof(long long) > sizeof(long)) { | ||
90 | /* We can put two long in the long long, but they have to | ||
91 | * be swapped: the least significant word comes first in the | ||
92 | * array */ | ||
93 | unsigned long *p = (void*)mask; | ||
94 | return p[0] + ((unsigned long long)p[1] << (8*sizeof(long))); | ||
95 | } | ||
96 | # endif | ||
97 | return *(unsigned long long*)mask; | ||
98 | } | 87 | } |
99 | #endif | 88 | #endif |
100 | 89 | ||
90 | static unsigned long *get_aff(int pid, unsigned *sz) | ||
91 | { | ||
92 | int r; | ||
93 | unsigned long *mask = NULL; | ||
94 | unsigned sz_in_bytes = *sz; | ||
95 | |||
96 | for (;;) { | ||
97 | mask = xrealloc(mask, sz_in_bytes); | ||
98 | r = sched_getaffinity(pid, sz_in_bytes, (void*)mask); | ||
99 | if (r == 0) | ||
100 | break; | ||
101 | sz_in_bytes *= 2; | ||
102 | if (errno == EINVAL && (int)sz_in_bytes > 0) | ||
103 | continue; | ||
104 | bb_perror_msg_and_die("can't %cet pid %d's affinity", 'g', pid); | ||
105 | } | ||
106 | //bb_error_msg("get mask[0]:%lx sz_in_bytes:%d", mask[0], sz_in_bytes); | ||
107 | *sz = sz_in_bytes; | ||
108 | return mask; | ||
109 | } | ||
101 | 110 | ||
102 | int taskset_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; | 111 | int taskset_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; |
103 | int taskset_main(int argc UNUSED_PARAM, char **argv) | 112 | int taskset_main(int argc UNUSED_PARAM, char **argv) |
104 | { | 113 | { |
105 | cpu_set_t mask; | 114 | ul *mask; |
115 | unsigned mask_size_in_bytes; | ||
106 | pid_t pid = 0; | 116 | pid_t pid = 0; |
107 | unsigned opt_p; | 117 | unsigned opt_p; |
108 | const char *current_new; | 118 | const char *current_new; |
109 | char *pid_str; | 119 | char *aff; |
110 | char *aff = aff; /* for compiler */ | ||
111 | 120 | ||
112 | /* NB: we mimic util-linux's taskset: -p does not take | 121 | /* NB: we mimic util-linux's taskset: -p does not take |
113 | * an argument, i.e., "-pN" is NOT valid, only "-p N"! | 122 | * an argument, i.e., "-pN" is NOT valid, only "-p N"! |
@@ -118,102 +127,92 @@ int taskset_main(int argc UNUSED_PARAM, char **argv) | |||
118 | opt_p = getopt32(argv, "+p"); | 127 | opt_p = getopt32(argv, "+p"); |
119 | argv += optind; | 128 | argv += optind; |
120 | 129 | ||
130 | aff = *argv++; | ||
121 | if (opt_p) { | 131 | if (opt_p) { |
122 | pid_str = *argv++; | 132 | char *pid_str = aff; |
123 | if (*argv) { /* "-p <aff> <pid> ...rest.is.ignored..." */ | 133 | if (*argv) { /* "-p <aff> <pid> ...rest.is.ignored..." */ |
124 | aff = pid_str; | ||
125 | pid_str = *argv; /* NB: *argv != NULL in this case */ | 134 | pid_str = *argv; /* NB: *argv != NULL in this case */ |
126 | } | 135 | } |
127 | /* else it was just "-p <pid>", and *argv == NULL */ | 136 | /* else it was just "-p <pid>", and *argv == NULL */ |
128 | pid = xatoul_range(pid_str, 1, ((unsigned)(pid_t)ULONG_MAX) >> 1); | 137 | pid = xatoul_range(pid_str, 1, ((unsigned)(pid_t)ULONG_MAX) >> 1); |
129 | } else { | 138 | } else { |
130 | aff = *argv++; /* <aff> <cmd...> */ | 139 | /* <aff> <cmd...> */ |
131 | if (!*argv) | 140 | if (!*argv) |
132 | bb_show_usage(); | 141 | bb_show_usage(); |
133 | } | 142 | } |
134 | 143 | ||
135 | current_new = "current\0new"; | 144 | mask_size_in_bytes = SZOF_UL; |
136 | if (opt_p) { | 145 | current_new = "current"; |
137 | print_aff: | 146 | print_aff: |
138 | if (sched_getaffinity(pid, sizeof(mask), &mask) < 0) | 147 | mask = get_aff(pid, &mask_size_in_bytes); |
139 | bb_perror_msg_and_die("can't %cet pid %d's affinity", 'g', pid); | 148 | if (opt_p) { |
140 | printf("pid %d's %s affinity mask: "TASKSET_PRINTF_MASK"\n", | 149 | printf("pid %d's %s affinity mask: "TASKSET_PRINTF_MASK"\n", |
141 | pid, current_new, from_cpuset(&mask)); | 150 | pid, current_new, from_mask(mask, mask_size_in_bytes)); |
142 | if (!*argv) { | 151 | if (*argv == NULL) { |
143 | /* Either it was just "-p <pid>", | 152 | /* Either it was just "-p <pid>", |
144 | * or it was "-p <aff> <pid>" and we came here | 153 | * or it was "-p <aff> <pid>" and we came here |
145 | * for the second time (see goto below) */ | 154 | * for the second time (see goto below) */ |
146 | return EXIT_SUCCESS; | 155 | return EXIT_SUCCESS; |
147 | } | 156 | } |
148 | *argv = NULL; | 157 | *argv = NULL; |
149 | current_new += 8; /* "new" */ | 158 | current_new = "new"; |
150 | } | 159 | } |
160 | memset(mask, 0, mask_size_in_bytes); | ||
161 | |||
162 | /* Affinity was specified, translate it into mask */ | ||
163 | /* it is always in hex, skip "0x" if it exists */ | ||
164 | if (aff[0] == '0' && (aff[1]|0x20) == 'x') | ||
165 | aff += 2; | ||
151 | 166 | ||
152 | /* Affinity was specified, translate it into cpu_set_t */ | ||
153 | CPU_ZERO(&mask); | ||
154 | if (!ENABLE_FEATURE_TASKSET_FANCY) { | 167 | if (!ENABLE_FEATURE_TASKSET_FANCY) { |
155 | unsigned i; | 168 | mask[0] = xstrtoul(aff, 16); |
156 | unsigned long long m; | ||
157 | |||
158 | /* Do not allow zero mask: */ | ||
159 | m = xstrtoull_range(aff, 0, 1, ULLONG_MAX); | ||
160 | i = 0; | ||
161 | do { | ||
162 | if (m & 1) | ||
163 | CPU_SET(i, &mask); | ||
164 | i++; | ||
165 | m >>= 1; | ||
166 | } while (m != 0); | ||
167 | } else { | 169 | } else { |
168 | unsigned i; | 170 | unsigned i; |
169 | char *last_byte; | 171 | char *last_char; |
170 | char *bin; | 172 | |
171 | uint8_t bit_in_byte; | 173 | i = 0; /* bit pos in mask[] */ |
172 | 174 | ||
173 | /* Cheap way to get "long enough" buffer */ | 175 | /* aff is ASCII hex string, accept very long masks in this form. |
174 | bin = xstrdup(aff); | 176 | * Process hex string AABBCCDD... to ulong mask[] |
175 | 177 | * from the rightmost nibble, which is least-significant. | |
176 | if (aff[0] != '0' || (aff[1]|0x20) != 'x') { | 178 | * Bits not fitting into mask[] are ignored: (example: 1234 |
177 | /* TODO: decimal/octal masks are still limited to 2^64 */ | 179 | * in 12340000000000000000000000000000000000000ff) |
178 | unsigned long long m = xstrtoull_range(aff, 0, 1, ULLONG_MAX); | 180 | */ |
179 | bin += strlen(bin); | 181 | last_char = strchrnul(aff, '\0'); |
180 | last_byte = bin - 1; | 182 | while (last_char > aff) { |
181 | while (m) { | 183 | char c; |
182 | *--bin = m & 0xff; | 184 | ul val; |
183 | m >>= 8; | 185 | |
184 | } | 186 | last_char--; |
185 | } else { | 187 | c = *last_char; |
186 | /* aff is "0x.....", we accept very long masks in this form */ | 188 | if (isdigit(c)) |
187 | last_byte = hex2bin(bin, aff + 2, INT_MAX); | 189 | val = c - '0'; |
188 | if (!last_byte) { | 190 | else if ((c|0x20) >= 'a' && (c|0x20) <= 'f') |
189 | bad_aff: | 191 | val = (c|0x20) - ('a' - 10); |
192 | else | ||
190 | bb_error_msg_and_die("bad affinity '%s'", aff); | 193 | bb_error_msg_and_die("bad affinity '%s'", aff); |
191 | } | ||
192 | last_byte--; /* now points to the last byte */ | ||
193 | } | ||
194 | 194 | ||
195 | i = 0; | 195 | if (i < mask_size_in_bytes * 8) { |
196 | bit_in_byte = 1; | 196 | mask[i / BITS_UL] |= val << (i & MASK_UL); |
197 | while (last_byte >= bin) { | ||
198 | if (bit_in_byte & *last_byte) { | ||
199 | if (i >= CPU_SETSIZE) | ||
200 | goto bad_aff; | ||
201 | CPU_SET(i, &mask); | ||
202 | //bb_error_msg("bit %d set", i); | 197 | //bb_error_msg("bit %d set", i); |
203 | } | 198 | } |
204 | i++; | 199 | /* else: |
205 | /* bit_in_byte is uint8_t! & 0xff is implied */ | 200 | * We can error out here, but we don't. |
206 | bit_in_byte = (bit_in_byte << 1); | 201 | * For one, kernel itself ignores bits in mask[] |
207 | if (!bit_in_byte) { | 202 | * which do not map to any CPUs: |
208 | bit_in_byte = 1; | 203 | * if mask[] has one 32-bit long element, |
209 | last_byte--; | 204 | * but you have only 8 CPUs, all bits beyond first 8 |
210 | } | 205 | * are ignored, silently. |
206 | * No point in making bits past 31th to be errors. | ||
207 | */ | ||
208 | i += 4; | ||
211 | } | 209 | } |
212 | } | 210 | } |
213 | 211 | ||
214 | /* Set pid's or our own (pid==0) affinity */ | 212 | /* Set pid's or our own (pid==0) affinity */ |
215 | if (sched_setaffinity(pid, sizeof(mask), &mask)) | 213 | if (sched_setaffinity(pid, mask_size_in_bytes, (void*)mask)) |
216 | bb_perror_msg_and_die("can't %cet pid %d's affinity", 's', pid); | 214 | bb_perror_msg_and_die("can't %cet pid %d's affinity", 's', pid); |
215 | //bb_error_msg("set mask[0]:%lx", mask[0]); | ||
217 | 216 | ||
218 | if (!argv[0]) /* "-p <aff> <pid> [...ignored...]" */ | 217 | if (!argv[0]) /* "-p <aff> <pid> [...ignored...]" */ |
219 | goto print_aff; /* print new affinity and exit */ | 218 | goto print_aff; /* print new affinity and exit */ |
diff --git a/miscutils/ubi_tools.c b/miscutils/ubi_tools.c index 8e55e9577..982e3e52a 100644 --- a/miscutils/ubi_tools.c +++ b/miscutils/ubi_tools.c | |||
@@ -45,11 +45,12 @@ | |||
45 | //config: help | 45 | //config: help |
46 | //config: Update a UBI volume. | 46 | //config: Update a UBI volume. |
47 | 47 | ||
48 | //applet:IF_UBIATTACH(APPLET_ODDNAME(ubiattach, ubi_tools, BB_DIR_USR_SBIN, BB_SUID_DROP, ubiattach)) | 48 | // APPLET_ODDNAME:name main location suid_type help |
49 | //applet:IF_UBIDETACH(APPLET_ODDNAME(ubidetach, ubi_tools, BB_DIR_USR_SBIN, BB_SUID_DROP, ubidetach)) | 49 | //applet:IF_UBIATTACH( APPLET_ODDNAME(ubiattach, ubi_tools, BB_DIR_USR_SBIN, BB_SUID_DROP, ubiattach)) |
50 | //applet:IF_UBIMKVOL(APPLET_ODDNAME(ubimkvol, ubi_tools, BB_DIR_USR_SBIN, BB_SUID_DROP, ubimkvol)) | 50 | //applet:IF_UBIDETACH( APPLET_ODDNAME(ubidetach, ubi_tools, BB_DIR_USR_SBIN, BB_SUID_DROP, ubidetach)) |
51 | //applet:IF_UBIRMVOL(APPLET_ODDNAME(ubirmvol, ubi_tools, BB_DIR_USR_SBIN, BB_SUID_DROP, ubirmvol)) | 51 | //applet:IF_UBIMKVOL( APPLET_ODDNAME(ubimkvol, ubi_tools, BB_DIR_USR_SBIN, BB_SUID_DROP, ubimkvol)) |
52 | //applet:IF_UBIRSVOL(APPLET_ODDNAME(ubirsvol, ubi_tools, BB_DIR_USR_SBIN, BB_SUID_DROP, ubirsvol)) | 52 | //applet:IF_UBIRMVOL( APPLET_ODDNAME(ubirmvol, ubi_tools, BB_DIR_USR_SBIN, BB_SUID_DROP, ubirmvol)) |
53 | //applet:IF_UBIRSVOL( APPLET_ODDNAME(ubirsvol, ubi_tools, BB_DIR_USR_SBIN, BB_SUID_DROP, ubirsvol)) | ||
53 | //applet:IF_UBIUPDATEVOL(APPLET_ODDNAME(ubiupdatevol, ubi_tools, BB_DIR_USR_SBIN, BB_SUID_DROP, ubiupdatevol)) | 54 | //applet:IF_UBIUPDATEVOL(APPLET_ODDNAME(ubiupdatevol, ubi_tools, BB_DIR_USR_SBIN, BB_SUID_DROP, ubiupdatevol)) |
54 | 55 | ||
55 | //kbuild:lib-$(CONFIG_UBIATTACH) += ubi_tools.o | 56 | //kbuild:lib-$(CONFIG_UBIATTACH) += ubi_tools.o |
diff --git a/modutils/Config.src b/modutils/Config.src index 84ff34a08..5f0b0cec4 100644 --- a/modutils/Config.src +++ b/modutils/Config.src | |||
@@ -8,9 +8,11 @@ menu "Linux Module Utilities" | |||
8 | config MODPROBE_SMALL | 8 | config MODPROBE_SMALL |
9 | bool "Simplified modutils" | 9 | bool "Simplified modutils" |
10 | default y | 10 | default y |
11 | select PLATFORM_LINUX | ||
12 | help | 11 | help |
13 | Simplified modutils. | 12 | Build smaller (~1.5 kbytes), simplified module tools. |
13 | |||
14 | This option by itself does not enable any applets - | ||
15 | you need to select applets individually below. | ||
14 | 16 | ||
15 | With this option modprobe does not require modules.dep file | 17 | With this option modprobe does not require modules.dep file |
16 | and does not use /etc/modules.conf file. | 18 | and does not use /etc/modules.conf file. |
@@ -31,47 +33,38 @@ config MODPROBE_SMALL | |||
31 | Additional module parameters can be stored in | 33 | Additional module parameters can be stored in |
32 | /etc/modules/$module_name files. | 34 | /etc/modules/$module_name files. |
33 | 35 | ||
34 | Apart from modprobe, other utilities are also provided: | ||
35 | - insmod is an alias to modprobe | ||
36 | - rmmod is an alias to modprobe -r | ||
37 | - depmod generates modules.dep.bb | ||
38 | |||
39 | INSERT | 36 | INSERT |
40 | 37 | ||
41 | comment "Options common to multiple modutils" | 38 | comment "Options common to multiple modutils" |
42 | 39 | ||
40 | config FEATURE_CMDLINE_MODULE_OPTIONS | ||
41 | bool "Accept module options on modprobe command line" | ||
42 | default y | ||
43 | depends on INSMOD || MODPROBE | ||
44 | help | ||
45 | Allow insmod and modprobe take module options from the applets' | ||
46 | command line. | ||
47 | |||
48 | config FEATURE_MODPROBE_SMALL_CHECK_ALREADY_LOADED | ||
49 | bool "Skip loading of already loaded modules" | ||
50 | default y | ||
51 | depends on MODPROBE_SMALL && (DEPMOD || INSMOD || MODPROBE) | ||
52 | help | ||
53 | Check if the module is already loaded. | ||
54 | |||
43 | config FEATURE_2_4_MODULES | 55 | config FEATURE_2_4_MODULES |
44 | bool "Support version 2.2/2.4 Linux kernels" | 56 | bool "Support version 2.2/2.4 Linux kernels" |
45 | default n | 57 | default n |
46 | depends on INSMOD || RMMOD || LSMOD | 58 | depends on (INSMOD || LSMOD || MODPROBE || RMMOD) && !MODPROBE_SMALL |
47 | select PLATFORM_LINUX | ||
48 | help | 59 | help |
49 | Support module loading for 2.2.x and 2.4.x Linux kernels. | 60 | Support module loading for 2.2.x and 2.4.x Linux kernels. |
50 | This increases size considerably. Say N unless you plan | 61 | This increases size considerably. Say N unless you plan |
51 | to run ancient kernels. | 62 | to run ancient kernels. |
52 | 63 | ||
53 | config FEATURE_INSMOD_TRY_MMAP | ||
54 | bool "Try to load module from a mmap'ed area" | ||
55 | default n | ||
56 | depends on INSMOD || MODPROBE_SMALL | ||
57 | select PLATFORM_LINUX | ||
58 | help | ||
59 | This option causes module loading code to try to mmap | ||
60 | module first. If it does not work (for example, | ||
61 | it does not work for compressed modules), module will be read | ||
62 | (and unpacked if needed) into a memory block allocated by malloc. | ||
63 | |||
64 | The only case when mmap works but malloc does not is when | ||
65 | you are trying to load a big module on a very memory-constrained | ||
66 | machine. Malloc will momentarily need 2x as much memory as mmap. | ||
67 | |||
68 | Choosing N saves about 250 bytes of code (on 32-bit x86). | ||
69 | |||
70 | config FEATURE_INSMOD_VERSION_CHECKING | 64 | config FEATURE_INSMOD_VERSION_CHECKING |
71 | bool "Enable module version checking" | 65 | bool "Enable module version checking" |
72 | default n | 66 | default n |
73 | depends on FEATURE_2_4_MODULES && (INSMOD || MODPROBE) | 67 | depends on FEATURE_2_4_MODULES && (INSMOD || MODPROBE) |
74 | select PLATFORM_LINUX | ||
75 | help | 68 | help |
76 | Support checking of versions for modules. This is used to | 69 | Support checking of versions for modules. This is used to |
77 | ensure that the kernel and module are made for each other. | 70 | ensure that the kernel and module are made for each other. |
@@ -80,7 +73,6 @@ config FEATURE_INSMOD_KSYMOOPS_SYMBOLS | |||
80 | bool "Add module symbols to kernel symbol table" | 73 | bool "Add module symbols to kernel symbol table" |
81 | default n | 74 | default n |
82 | depends on FEATURE_2_4_MODULES && (INSMOD || MODPROBE) | 75 | depends on FEATURE_2_4_MODULES && (INSMOD || MODPROBE) |
83 | select PLATFORM_LINUX | ||
84 | help | 76 | help |
85 | By adding module symbols to the kernel symbol table, Oops messages | 77 | By adding module symbols to the kernel symbol table, Oops messages |
86 | occuring within kernel modules can be properly debugged. By enabling | 78 | occuring within kernel modules can be properly debugged. By enabling |
@@ -92,7 +84,6 @@ config FEATURE_INSMOD_LOADINKMEM | |||
92 | bool "In kernel memory optimization (uClinux only)" | 84 | bool "In kernel memory optimization (uClinux only)" |
93 | default n | 85 | default n |
94 | depends on FEATURE_2_4_MODULES && (INSMOD || MODPROBE) | 86 | depends on FEATURE_2_4_MODULES && (INSMOD || MODPROBE) |
95 | select PLATFORM_LINUX | ||
96 | help | 87 | help |
97 | This is a special uClinux only memory optimization that lets insmod | 88 | This is a special uClinux only memory optimization that lets insmod |
98 | load the specified kernel module directly into kernel space, reducing | 89 | load the specified kernel module directly into kernel space, reducing |
@@ -103,7 +94,6 @@ config FEATURE_INSMOD_LOAD_MAP | |||
103 | bool "Enable insmod load map (-m) option" | 94 | bool "Enable insmod load map (-m) option" |
104 | default n | 95 | default n |
105 | depends on FEATURE_2_4_MODULES && INSMOD | 96 | depends on FEATURE_2_4_MODULES && INSMOD |
106 | select PLATFORM_LINUX | ||
107 | help | 97 | help |
108 | Enabling this, one would be able to get a load map | 98 | Enabling this, one would be able to get a load map |
109 | output on stdout. This makes kernel module debugging | 99 | output on stdout. This makes kernel module debugging |
@@ -114,8 +104,7 @@ config FEATURE_INSMOD_LOAD_MAP | |||
114 | config FEATURE_INSMOD_LOAD_MAP_FULL | 104 | config FEATURE_INSMOD_LOAD_MAP_FULL |
115 | bool "Symbols in load map" | 105 | bool "Symbols in load map" |
116 | default y | 106 | default y |
117 | depends on FEATURE_INSMOD_LOAD_MAP && !MODPROBE_SMALL | 107 | depends on FEATURE_INSMOD_LOAD_MAP |
118 | select PLATFORM_LINUX | ||
119 | help | 108 | help |
120 | Without this option, -m will only output section | 109 | Without this option, -m will only output section |
121 | load map. With this option, -m will also output | 110 | load map. With this option, -m will also output |
@@ -125,18 +114,32 @@ config FEATURE_CHECK_TAINTED_MODULE | |||
125 | bool "Support tainted module checking with new kernels" | 114 | bool "Support tainted module checking with new kernels" |
126 | default y | 115 | default y |
127 | depends on (LSMOD || FEATURE_2_4_MODULES) && !MODPROBE_SMALL | 116 | depends on (LSMOD || FEATURE_2_4_MODULES) && !MODPROBE_SMALL |
128 | select PLATFORM_LINUX | ||
129 | help | 117 | help |
130 | Support checking for tainted modules. These are usually binary | 118 | Support checking for tainted modules. These are usually binary |
131 | only modules that will make the linux-kernel list ignore your | 119 | only modules that will make the linux-kernel list ignore your |
132 | support request. | 120 | support request. |
133 | This option is required to support GPLONLY modules. | 121 | This option is required to support GPLONLY modules. |
134 | 122 | ||
123 | config FEATURE_INSMOD_TRY_MMAP | ||
124 | bool "Try to load module from a mmap'ed area" | ||
125 | default n | ||
126 | depends on (INSMOD || MODPROBE) && !MODPROBE_SMALL | ||
127 | help | ||
128 | This option causes module loading code to try to mmap | ||
129 | module first. If it does not work (for example, | ||
130 | it does not work for compressed modules), module will be read | ||
131 | (and unpacked if needed) into a memory block allocated by malloc. | ||
132 | |||
133 | The only case when mmap works but malloc does not is when | ||
134 | you are trying to load a big module on a very memory-constrained | ||
135 | machine. Malloc will momentarily need 2x as much memory as mmap. | ||
136 | |||
137 | Choosing N saves about 250 bytes of code (on 32-bit x86). | ||
138 | |||
135 | config FEATURE_MODUTILS_ALIAS | 139 | config FEATURE_MODUTILS_ALIAS |
136 | bool "Support for module.aliases file" | 140 | bool "Support module.aliases file" |
137 | default y | 141 | default y |
138 | depends on DEPMOD || MODPROBE | 142 | depends on (DEPMOD || MODPROBE) && !MODPROBE_SMALL |
139 | select PLATFORM_LINUX | ||
140 | help | 143 | help |
141 | Generate and parse modules.alias containing aliases for bus | 144 | Generate and parse modules.alias containing aliases for bus |
142 | identifiers: | 145 | identifiers: |
@@ -150,10 +153,9 @@ config FEATURE_MODUTILS_ALIAS | |||
150 | Say Y if unsure. | 153 | Say Y if unsure. |
151 | 154 | ||
152 | config FEATURE_MODUTILS_SYMBOLS | 155 | config FEATURE_MODUTILS_SYMBOLS |
153 | bool "Support for module.symbols file" | 156 | bool "Support module.symbols file" |
154 | default y | 157 | default y |
155 | depends on DEPMOD || MODPROBE | 158 | depends on (DEPMOD || MODPROBE) && !MODPROBE_SMALL |
156 | select PLATFORM_LINUX | ||
157 | help | 159 | help |
158 | Generate and parse modules.symbols containing aliases for | 160 | Generate and parse modules.symbols containing aliases for |
159 | symbol_request() kernel calls, such as: | 161 | symbol_request() kernel calls, such as: |
@@ -164,7 +166,7 @@ config FEATURE_MODUTILS_SYMBOLS | |||
164 | config DEFAULT_MODULES_DIR | 166 | config DEFAULT_MODULES_DIR |
165 | string "Default directory containing modules" | 167 | string "Default directory containing modules" |
166 | default "/lib/modules" | 168 | default "/lib/modules" |
167 | depends on DEPMOD || MODPROBE || MODPROBE_SMALL || MODINFO | 169 | depends on DEPMOD || MODPROBE || MODINFO |
168 | help | 170 | help |
169 | Directory that contains kernel modules. | 171 | Directory that contains kernel modules. |
170 | Defaults to "/lib/modules" | 172 | Defaults to "/lib/modules" |
@@ -172,9 +174,13 @@ config DEFAULT_MODULES_DIR | |||
172 | config DEFAULT_DEPMOD_FILE | 174 | config DEFAULT_DEPMOD_FILE |
173 | string "Default name of modules.dep" | 175 | string "Default name of modules.dep" |
174 | default "modules.dep" | 176 | default "modules.dep" |
175 | depends on DEPMOD || MODPROBE || MODPROBE_SMALL || MODINFO | 177 | depends on DEPMOD || MODPROBE || MODINFO |
176 | help | 178 | help |
177 | Filename that contains kernel modules dependencies. | 179 | Filename that contains kernel modules dependencies. |
178 | Defaults to "modules.dep" | 180 | Defaults to "modules.dep". |
181 | If you configured the "simplified modutils" (MODPROBE_SMALL), a | ||
182 | ".bb" suffix will be added after this name. Do not specify ".bb" | ||
183 | here unless you intend your depmod or modprobe to work on | ||
184 | "modules.dep.bb.bb" or such. | ||
179 | 185 | ||
180 | endmenu | 186 | endmenu |
diff --git a/modutils/insmod.c b/modutils/insmod.c index f2c70e16f..8526979eb 100644 --- a/modutils/insmod.c +++ b/modutils/insmod.c | |||
@@ -27,9 +27,9 @@ | |||
27 | 27 | ||
28 | //usage:#if !ENABLE_MODPROBE_SMALL | 28 | //usage:#if !ENABLE_MODPROBE_SMALL |
29 | //usage:#define insmod_trivial_usage | 29 | //usage:#define insmod_trivial_usage |
30 | //usage: IF_FEATURE_2_4_MODULES("[OPTIONS] MODULE ") | 30 | //usage: IF_FEATURE_2_4_MODULES("[OPTIONS] MODULE") |
31 | //usage: IF_NOT_FEATURE_2_4_MODULES("FILE ") | 31 | //usage: IF_NOT_FEATURE_2_4_MODULES("FILE") |
32 | //usage: "[SYMBOL=VALUE]..." | 32 | //usage: IF_FEATURE_CMDLINE_MODULE_OPTIONS(" [SYMBOL=VALUE]...") |
33 | //usage:#define insmod_full_usage "\n\n" | 33 | //usage:#define insmod_full_usage "\n\n" |
34 | //usage: "Load kernel module" | 34 | //usage: "Load kernel module" |
35 | //usage: IF_FEATURE_2_4_MODULES( "\n" | 35 | //usage: IF_FEATURE_2_4_MODULES( "\n" |
diff --git a/modutils/lsmod.c b/modutils/lsmod.c index 24589420a..24e5d35b9 100644 --- a/modutils/lsmod.c +++ b/modutils/lsmod.c | |||
@@ -18,7 +18,6 @@ | |||
18 | //config: bool "Pretty output" | 18 | //config: bool "Pretty output" |
19 | //config: default y | 19 | //config: default y |
20 | //config: depends on LSMOD && !MODPROBE_SMALL | 20 | //config: depends on LSMOD && !MODPROBE_SMALL |
21 | //config: select PLATFORM_LINUX | ||
22 | //config: help | 21 | //config: help |
23 | //config: This option makes output format of lsmod adjusted to | 22 | //config: This option makes output format of lsmod adjusted to |
24 | //config: the format of module-init-tools for Linux kernel 2.6. | 23 | //config: the format of module-init-tools for Linux kernel 2.6. |
@@ -34,7 +33,7 @@ | |||
34 | //usage:#define lsmod_trivial_usage | 33 | //usage:#define lsmod_trivial_usage |
35 | //usage: "" | 34 | //usage: "" |
36 | //usage:#define lsmod_full_usage "\n\n" | 35 | //usage:#define lsmod_full_usage "\n\n" |
37 | //usage: "List the currently loaded kernel modules" | 36 | //usage: "List loaded kernel modules" |
38 | //usage:#endif | 37 | //usage:#endif |
39 | 38 | ||
40 | #include "libbb.h" | 39 | #include "libbb.h" |
diff --git a/modutils/modprobe-small.c b/modutils/modprobe-small.c index 0fc9ea454..431b8aeb2 100644 --- a/modutils/modprobe-small.c +++ b/modutils/modprobe-small.c | |||
@@ -8,28 +8,15 @@ | |||
8 | * Licensed under GPLv2, see file LICENSE in this source tree. | 8 | * Licensed under GPLv2, see file LICENSE in this source tree. |
9 | */ | 9 | */ |
10 | 10 | ||
11 | /* config MODPROBE_SMALL is defined in Config.src to ensure better "make config" order */ | 11 | /* modprobe-small configs are defined in Config.src to ensure better |
12 | 12 | * "make config" order */ | |
13 | //config:config FEATURE_MODPROBE_SMALL_OPTIONS_ON_CMDLINE | ||
14 | //config: bool "Accept module options on modprobe command line" | ||
15 | //config: default y | ||
16 | //config: depends on MODPROBE_SMALL | ||
17 | //config: select PLATFORM_LINUX | ||
18 | //config: help | ||
19 | //config: Allow insmod and modprobe take module options from command line. | ||
20 | //config: | ||
21 | //config:config FEATURE_MODPROBE_SMALL_CHECK_ALREADY_LOADED | ||
22 | //config: bool "Skip loading of already loaded modules" | ||
23 | //config: default y | ||
24 | //config: depends on MODPROBE_SMALL | ||
25 | //config: help | ||
26 | //config: Check if the module is already loaded. | ||
27 | 13 | ||
14 | //applet:IF_LSMOD( IF_MODPROBE_SMALL(APPLET(lsmod, BB_DIR_SBIN, BB_SUID_DROP))) | ||
28 | //applet:IF_MODPROBE(IF_MODPROBE_SMALL(APPLET(modprobe, BB_DIR_SBIN, BB_SUID_DROP))) | 15 | //applet:IF_MODPROBE(IF_MODPROBE_SMALL(APPLET(modprobe, BB_DIR_SBIN, BB_SUID_DROP))) |
16 | // APPLET_ODDNAME:name main location suid_type help | ||
29 | //applet:IF_DEPMOD(IF_MODPROBE_SMALL(APPLET_ODDNAME(depmod, modprobe, BB_DIR_SBIN, BB_SUID_DROP, depmod))) | 17 | //applet:IF_DEPMOD(IF_MODPROBE_SMALL(APPLET_ODDNAME(depmod, modprobe, BB_DIR_SBIN, BB_SUID_DROP, depmod))) |
30 | //applet:IF_INSMOD(IF_MODPROBE_SMALL(APPLET_ODDNAME(insmod, modprobe, BB_DIR_SBIN, BB_SUID_DROP, insmod))) | 18 | //applet:IF_INSMOD(IF_MODPROBE_SMALL(APPLET_ODDNAME(insmod, modprobe, BB_DIR_SBIN, BB_SUID_DROP, insmod))) |
31 | //applet:IF_LSMOD(IF_MODPROBE_SMALL(APPLET_ODDNAME(lsmod, modprobe, BB_DIR_SBIN, BB_SUID_DROP, lsmod))) | 19 | //applet:IF_RMMOD( IF_MODPROBE_SMALL(APPLET_ODDNAME(rmmod, modprobe, BB_DIR_SBIN, BB_SUID_DROP, rmmod))) |
32 | //applet:IF_RMMOD(IF_MODPROBE_SMALL(APPLET_ODDNAME(rmmod, modprobe, BB_DIR_SBIN, BB_SUID_DROP, rmmod))) | ||
33 | 20 | ||
34 | //kbuild:lib-$(CONFIG_MODPROBE_SMALL) += modprobe-small.o | 21 | //kbuild:lib-$(CONFIG_MODPROBE_SMALL) += modprobe-small.o |
35 | 22 | ||
@@ -59,6 +46,38 @@ | |||
59 | 46 | ||
60 | #define DEPFILE_BB CONFIG_DEFAULT_DEPMOD_FILE".bb" | 47 | #define DEPFILE_BB CONFIG_DEFAULT_DEPMOD_FILE".bb" |
61 | 48 | ||
49 | //usage:#if ENABLE_MODPROBE_SMALL | ||
50 | |||
51 | //usage:#define lsmod_trivial_usage | ||
52 | //usage: "" | ||
53 | //usage:#define lsmod_full_usage "\n\n" | ||
54 | //usage: "List loaded kernel modules" | ||
55 | |||
56 | //usage:#endif | ||
57 | |||
58 | #if ENABLE_LSMOD | ||
59 | int lsmod_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; | ||
60 | int lsmod_main(int argc UNUSED_PARAM, char **argv UNUSED_PARAM) | ||
61 | { | ||
62 | xprint_and_close_file(xfopen_for_read("/proc/modules")); | ||
63 | return EXIT_SUCCESS; | ||
64 | } | ||
65 | #endif | ||
66 | |||
67 | /* Num of applets that use modprobe_main() entry point. */ | ||
68 | /* lsmod is not here. */ | ||
69 | #define MOD_APPLET_CNT (ENABLE_MODPROBE + ENABLE_DEPMOD + ENABLE_INSMOD + ENABLE_RMMOD) | ||
70 | |||
71 | /* Do not bother if MODPROBE_SMALL=y but no applets selected. */ | ||
72 | /* The rest of the file is in this if block. */ | ||
73 | #if MOD_APPLET_CNT > 0 | ||
74 | |||
75 | #define ONLY_APPLET (MOD_APPLET_CNT == 1) | ||
76 | #define is_modprobe (ENABLE_MODPROBE && (ONLY_APPLET || applet_name[0] == 'm')) | ||
77 | #define is_depmod (ENABLE_DEPMOD && (ONLY_APPLET || applet_name[0] == 'd')) | ||
78 | #define is_insmod (ENABLE_INSMOD && (ONLY_APPLET || applet_name[0] == 'i')) | ||
79 | #define is_rmmod (ENABLE_RMMOD && (ONLY_APPLET || applet_name[0] == 'r')) | ||
80 | |||
62 | enum { | 81 | enum { |
63 | OPT_q = (1 << 0), /* be quiet */ | 82 | OPT_q = (1 << 0), /* be quiet */ |
64 | OPT_r = (1 << 1), /* module removal instead of loading */ | 83 | OPT_r = (1 << 1), /* module removal instead of loading */ |
@@ -361,6 +380,8 @@ static FAST_FUNC int fileAction(const char *pathname, | |||
361 | { | 380 | { |
362 | int cur; | 381 | int cur; |
363 | const char *fname; | 382 | const char *fname; |
383 | bool is_remove = (ENABLE_RMMOD && ONLY_APPLET) | ||
384 | || ((ENABLE_RMMOD || ENABLE_MODPROBE) && (option_mask32 & OPT_r)); | ||
364 | 385 | ||
365 | pathname += 2; /* skip "./" */ | 386 | pathname += 2; /* skip "./" */ |
366 | fname = bb_get_last_path_component_nostrip(pathname); | 387 | fname = bb_get_last_path_component_nostrip(pathname); |
@@ -385,7 +406,7 @@ static FAST_FUNC int fileAction(const char *pathname, | |||
385 | if (parse_module(&modinfo[cur], pathname) != 0) | 406 | if (parse_module(&modinfo[cur], pathname) != 0) |
386 | return TRUE; /* failed to open/read it, no point in trying loading */ | 407 | return TRUE; /* failed to open/read it, no point in trying loading */ |
387 | 408 | ||
388 | if (!(option_mask32 & OPT_r)) { | 409 | if (!is_remove) { |
389 | if (load_module(pathname, module_load_options) == 0) { | 410 | if (load_module(pathname, module_load_options) == 0) { |
390 | /* Load was successful, there is nothing else to do. | 411 | /* Load was successful, there is nothing else to do. |
391 | * This can happen ONLY for "top-level" module load, | 412 | * This can happen ONLY for "top-level" module load, |
@@ -656,7 +677,7 @@ static int rmmod(const char *filename) | |||
656 | * NB: also called by depmod with bogus name "/", | 677 | * NB: also called by depmod with bogus name "/", |
657 | * just in order to force modprobe.dep.bb creation. | 678 | * just in order to force modprobe.dep.bb creation. |
658 | */ | 679 | */ |
659 | #if !ENABLE_FEATURE_MODPROBE_SMALL_OPTIONS_ON_CMDLINE | 680 | #if !ENABLE_FEATURE_CMDLINE_MODULE_OPTIONS |
660 | #define process_module(a,b) process_module(a) | 681 | #define process_module(a,b) process_module(a) |
661 | #define cmdline_options "" | 682 | #define cmdline_options "" |
662 | #endif | 683 | #endif |
@@ -666,7 +687,8 @@ static int process_module(char *name, const char *cmdline_options) | |||
666 | module_info **infovec; | 687 | module_info **infovec; |
667 | module_info *info; | 688 | module_info *info; |
668 | int infoidx; | 689 | int infoidx; |
669 | int is_remove = (option_mask32 & OPT_r) != 0; | 690 | bool is_remove = (ENABLE_RMMOD && ONLY_APPLET) |
691 | || ((ENABLE_RMMOD || ENABLE_MODPROBE) && (option_mask32 & OPT_r)); | ||
670 | int exitcode = EXIT_SUCCESS; | 692 | int exitcode = EXIT_SUCCESS; |
671 | 693 | ||
672 | dbg1_error_msg("process_module('%s','%s')", name, cmdline_options); | 694 | dbg1_error_msg("process_module('%s','%s')", name, cmdline_options); |
@@ -675,9 +697,8 @@ static int process_module(char *name, const char *cmdline_options) | |||
675 | 697 | ||
676 | dbg1_error_msg("already_loaded:%d is_remove:%d", already_loaded(name), is_remove); | 698 | dbg1_error_msg("already_loaded:%d is_remove:%d", already_loaded(name), is_remove); |
677 | 699 | ||
678 | if (applet_name[0] == 'r') { | 700 | if (is_rmmod) { |
679 | /* rmmod. | 701 | /* Does not remove dependencies, no need to scan, just remove. |
680 | * Does not remove dependencies, no need to scan, just remove. | ||
681 | * (compat note: this allows and strips .ko suffix) | 702 | * (compat note: this allows and strips .ko suffix) |
682 | */ | 703 | */ |
683 | rmmod(name); | 704 | rmmod(name); |
@@ -701,7 +722,7 @@ static int process_module(char *name, const char *cmdline_options) | |||
701 | options = xmalloc_open_read_close(opt_filename, NULL); | 722 | options = xmalloc_open_read_close(opt_filename, NULL); |
702 | if (options) | 723 | if (options) |
703 | replace(options, '\n', ' '); | 724 | replace(options, '\n', ' '); |
704 | #if ENABLE_FEATURE_MODPROBE_SMALL_OPTIONS_ON_CMDLINE | 725 | #if ENABLE_FEATURE_CMDLINE_MODULE_OPTIONS |
705 | if (cmdline_options) { | 726 | if (cmdline_options) { |
706 | /* NB: cmdline_options always have one leading ' ' | 727 | /* NB: cmdline_options always have one leading ' ' |
707 | * (see main()), we remove it here */ | 728 | * (see main()), we remove it here */ |
@@ -743,7 +764,7 @@ static int process_module(char *name, const char *cmdline_options) | |||
743 | 764 | ||
744 | if (!infovec) { | 765 | if (!infovec) { |
745 | /* both dirscan and find_alias found nothing */ | 766 | /* both dirscan and find_alias found nothing */ |
746 | if (!is_remove && applet_name[0] != 'd') /* it wasn't rmmod or depmod */ | 767 | if (!is_remove && !is_depmod) /* it wasn't rmmod or depmod */ |
747 | bb_error_msg("module '%s' not found", name); | 768 | bb_error_msg("module '%s' not found", name); |
748 | //TODO: _and_die()? or should we continue (un)loading modules listed on cmdline? | 769 | //TODO: _and_die()? or should we continue (un)loading modules listed on cmdline? |
749 | goto ret; | 770 | goto ret; |
@@ -875,79 +896,48 @@ The following options are useful for people managing distributions: | |||
875 | //usage:#define depmod_trivial_usage NOUSAGE_STR | 896 | //usage:#define depmod_trivial_usage NOUSAGE_STR |
876 | //usage:#define depmod_full_usage "" | 897 | //usage:#define depmod_full_usage "" |
877 | 898 | ||
878 | //usage:#define lsmod_trivial_usage | ||
879 | //usage: "" | ||
880 | //usage:#define lsmod_full_usage "\n\n" | ||
881 | //usage: "List the currently loaded kernel modules" | ||
882 | |||
883 | //usage:#define insmod_trivial_usage | 899 | //usage:#define insmod_trivial_usage |
884 | //usage: IF_FEATURE_2_4_MODULES("[OPTIONS] MODULE ") | 900 | //usage: "FILE" IF_FEATURE_CMDLINE_MODULE_OPTIONS(" [SYMBOL=VALUE]...") |
885 | //usage: IF_NOT_FEATURE_2_4_MODULES("FILE ") | ||
886 | //usage: "[SYMBOL=VALUE]..." | ||
887 | //usage:#define insmod_full_usage "\n\n" | 901 | //usage:#define insmod_full_usage "\n\n" |
888 | //usage: "Load kernel module" | 902 | //usage: "Load kernel module" |
889 | //usage: IF_FEATURE_2_4_MODULES( "\n" | ||
890 | //usage: "\n -f Force module to load into the wrong kernel version" | ||
891 | //usage: "\n -k Make module autoclean-able" | ||
892 | //usage: "\n -v Verbose" | ||
893 | //usage: "\n -q Quiet" | ||
894 | //usage: "\n -L Lock: prevent simultaneous loads" | ||
895 | //usage: IF_FEATURE_INSMOD_LOAD_MAP( | ||
896 | //usage: "\n -m Output load map to stdout" | ||
897 | //usage: ) | ||
898 | //usage: "\n -x Don't export externs" | ||
899 | //usage: ) | ||
900 | 903 | ||
901 | //usage:#define rmmod_trivial_usage | 904 | //usage:#define rmmod_trivial_usage |
902 | //usage: "[-wfa] [MODULE]..." | 905 | //usage: "MODULE..." |
903 | //usage:#define rmmod_full_usage "\n\n" | 906 | //usage:#define rmmod_full_usage "\n\n" |
904 | //usage: "Unload kernel modules\n" | 907 | //usage: "Unload kernel modules" |
905 | //usage: "\n -w Wait until the module is no longer used" | ||
906 | //usage: "\n -f Force unload" | ||
907 | //usage: "\n -a Remove all unused modules (recursively)" | ||
908 | //usage: | ||
909 | //usage:#define rmmod_example_usage | ||
910 | //usage: "$ rmmod tulip\n" | ||
911 | 908 | ||
912 | //usage:#define modprobe_trivial_usage | 909 | //usage:#define modprobe_trivial_usage |
913 | //usage: "[-qfwrsv] MODULE [SYMBOL=VALUE]..." | 910 | //usage: "[-rq] MODULE" IF_FEATURE_CMDLINE_MODULE_OPTIONS(" [SYMBOL=VALUE]...") |
914 | //usage:#define modprobe_full_usage "\n\n" | 911 | //usage:#define modprobe_full_usage "\n\n" |
915 | //usage: " -r Remove MODULE (stacks) or do autoclean" | 912 | //usage: " -r Remove MODULE" |
916 | //usage: "\n -q Quiet" | 913 | //usage: "\n -q Quiet" |
917 | //usage: "\n -v Verbose" | ||
918 | //usage: "\n -f Force" | ||
919 | //usage: "\n -w Wait for unload" | ||
920 | //usage: "\n -s Report via syslog instead of stderr" | ||
921 | 914 | ||
922 | //usage:#endif | 915 | //usage:#endif |
923 | 916 | ||
924 | int modprobe_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; | 917 | int modprobe_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; |
925 | int modprobe_main(int argc UNUSED_PARAM, char **argv) | 918 | int modprobe_main(int argc UNUSED_PARAM, char **argv) |
926 | { | 919 | { |
920 | #if ENABLE_MODPROBE || ENABLE_INSMOD || ENABLE_RMMOD | ||
927 | int exitcode; | 921 | int exitcode; |
922 | #endif | ||
928 | struct utsname uts; | 923 | struct utsname uts; |
929 | char applet0 = applet_name[0]; | 924 | IF_FEATURE_CMDLINE_MODULE_OPTIONS(char *options = NULL;) |
930 | IF_FEATURE_MODPROBE_SMALL_OPTIONS_ON_CMDLINE(char *options;) | ||
931 | |||
932 | /* are we lsmod? -> just dump /proc/modules */ | ||
933 | if (ENABLE_LSMOD && 'l' == applet0) { | ||
934 | xprint_and_close_file(xfopen_for_read("/proc/modules")); | ||
935 | return EXIT_SUCCESS; | ||
936 | } | ||
937 | 925 | ||
938 | INIT_G(); | 926 | INIT_G(); |
939 | 927 | ||
940 | /* Prevent ugly corner cases with no modules at all */ | 928 | /* Prevent ugly corner cases with no modules at all */ |
941 | modinfo = xzalloc(sizeof(modinfo[0])); | 929 | modinfo = xzalloc(sizeof(modinfo[0])); |
942 | 930 | ||
943 | if (!ENABLE_INSMOD || 'i' != applet0) { /* not insmod */ | 931 | if ((MOD_APPLET_CNT == 2 && ENABLE_DEPMOD && ENABLE_MODPROBE) |
932 | || is_depmod || is_modprobe | ||
933 | ) { | ||
944 | /* Goto modules directory */ | 934 | /* Goto modules directory */ |
945 | xchdir(CONFIG_DEFAULT_MODULES_DIR); | 935 | xchdir(CONFIG_DEFAULT_MODULES_DIR); |
936 | uname(&uts); /* never fails */ | ||
946 | } | 937 | } |
947 | uname(&uts); /* never fails */ | ||
948 | 938 | ||
949 | /* depmod? */ | 939 | /* depmod? */ |
950 | if (ENABLE_DEPMOD && 'd' == applet0) { | 940 | if (is_depmod) { |
951 | /* Supported: | 941 | /* Supported: |
952 | * -n: print result to stdout | 942 | * -n: print result to stdout |
953 | * -a: process all modules (default) | 943 | * -a: process all modules (default) |
@@ -978,28 +968,28 @@ int modprobe_main(int argc UNUSED_PARAM, char **argv) | |||
978 | return !wrote_dep_bb_ok; | 968 | return !wrote_dep_bb_ok; |
979 | } | 969 | } |
980 | 970 | ||
981 | /* insmod, modprobe, rmmod require at least one argument */ | 971 | #if ENABLE_MODPROBE || ENABLE_INSMOD || ENABLE_RMMOD |
972 | /* modprobe, insmod, rmmod require at least one argument */ | ||
982 | opt_complementary = "-1"; | 973 | opt_complementary = "-1"; |
983 | /* only -q (quiet) and -r (rmmod), | 974 | /* only -q (quiet) and -r (rmmod), |
984 | * the rest are accepted and ignored (compat) */ | 975 | * the rest are accepted and ignored (compat) */ |
985 | getopt32(argv, "qrfsvwb"); | 976 | getopt32(argv, "qrfsvwb"); |
986 | argv += optind; | 977 | argv += optind; |
987 | 978 | ||
988 | /* are we rmmod? -> simulate modprobe -r */ | 979 | if (is_modprobe) { |
989 | if (ENABLE_RMMOD && 'r' == applet0) { | ||
990 | option_mask32 |= OPT_r; | ||
991 | } | ||
992 | |||
993 | if (!ENABLE_INSMOD || 'i' != applet0) { /* not insmod */ | ||
994 | /* Goto $VERSION directory */ | 980 | /* Goto $VERSION directory */ |
995 | xchdir(uts.release); | 981 | xchdir(uts.release); |
996 | } | 982 | } |
997 | 983 | ||
998 | #if ENABLE_FEATURE_MODPROBE_SMALL_OPTIONS_ON_CMDLINE | 984 | /* are we rmmod? -> simulate modprobe -r, but don't bother the flag if |
985 | * there're no other applets here */ | ||
986 | if (is_rmmod) { | ||
987 | if (!ONLY_APPLET) | ||
988 | option_mask32 |= OPT_r; | ||
989 | } else if (!ENABLE_MODPROBE || !(option_mask32 & OPT_r)) { | ||
990 | # if ENABLE_FEATURE_CMDLINE_MODULE_OPTIONS | ||
999 | /* If not rmmod/-r, parse possible module options given on command line. | 991 | /* If not rmmod/-r, parse possible module options given on command line. |
1000 | * insmod/modprobe takes one module name, the rest are parameters. */ | 992 | * insmod/modprobe takes one module name, the rest are parameters. */ |
1001 | options = NULL; | ||
1002 | if (!(option_mask32 & OPT_r)) { | ||
1003 | char **arg = argv; | 993 | char **arg = argv; |
1004 | while (*++arg) { | 994 | while (*++arg) { |
1005 | /* Enclose options in quotes */ | 995 | /* Enclose options in quotes */ |
@@ -1008,13 +998,12 @@ int modprobe_main(int argc UNUSED_PARAM, char **argv) | |||
1008 | free(s); | 998 | free(s); |
1009 | *arg = NULL; | 999 | *arg = NULL; |
1010 | } | 1000 | } |
1011 | } | 1001 | # else |
1012 | #else | ||
1013 | if (!(option_mask32 & OPT_r)) | ||
1014 | argv[1] = NULL; | 1002 | argv[1] = NULL; |
1015 | #endif | 1003 | # endif |
1004 | } | ||
1016 | 1005 | ||
1017 | if (ENABLE_INSMOD && 'i' == applet0) { /* insmod */ | 1006 | if (is_insmod) { |
1018 | size_t len; | 1007 | size_t len; |
1019 | void *map; | 1008 | void *map; |
1020 | 1009 | ||
@@ -1023,8 +1012,7 @@ int modprobe_main(int argc UNUSED_PARAM, char **argv) | |||
1023 | if (!map) | 1012 | if (!map) |
1024 | bb_perror_msg_and_die("can't read '%s'", *argv); | 1013 | bb_perror_msg_and_die("can't read '%s'", *argv); |
1025 | if (init_module(map, len, | 1014 | if (init_module(map, len, |
1026 | IF_FEATURE_MODPROBE_SMALL_OPTIONS_ON_CMDLINE(options ? options : "") | 1015 | (IF_FEATURE_CMDLINE_MODULE_OPTIONS(options ? options : ) "") |
1027 | IF_NOT_FEATURE_MODPROBE_SMALL_OPTIONS_ON_CMDLINE("") | ||
1028 | ) != 0 | 1016 | ) != 0 |
1029 | ) { | 1017 | ) { |
1030 | bb_error_msg_and_die("can't insert '%s': %s", | 1018 | bb_error_msg_and_die("can't insert '%s': %s", |
@@ -1034,7 +1022,7 @@ int modprobe_main(int argc UNUSED_PARAM, char **argv) | |||
1034 | } | 1022 | } |
1035 | 1023 | ||
1036 | /* Try to load modprobe.dep.bb */ | 1024 | /* Try to load modprobe.dep.bb */ |
1037 | if (!ENABLE_RMMOD || 'r' != applet0) { /* not rmmod */ | 1025 | if (!is_rmmod) { |
1038 | load_dep_bb(); | 1026 | load_dep_bb(); |
1039 | } | 1027 | } |
1040 | 1028 | ||
@@ -1046,7 +1034,10 @@ int modprobe_main(int argc UNUSED_PARAM, char **argv) | |||
1046 | } while (*++argv); | 1034 | } while (*++argv); |
1047 | 1035 | ||
1048 | if (ENABLE_FEATURE_CLEAN_UP) { | 1036 | if (ENABLE_FEATURE_CLEAN_UP) { |
1049 | IF_FEATURE_MODPROBE_SMALL_OPTIONS_ON_CMDLINE(free(options);) | 1037 | IF_FEATURE_CMDLINE_MODULE_OPTIONS(free(options);) |
1050 | } | 1038 | } |
1051 | return exitcode; | 1039 | return exitcode; |
1040 | #endif /* MODPROBE || INSMOD || RMMOD */ | ||
1052 | } | 1041 | } |
1042 | |||
1043 | #endif /* MOD_APPLET_CNT > 0 */ | ||
diff --git a/modutils/modprobe.c b/modutils/modprobe.c index 09e3de6c3..a6224fa63 100644 --- a/modutils/modprobe.c +++ b/modutils/modprobe.c | |||
@@ -19,7 +19,6 @@ | |||
19 | //config: bool "Blacklist support" | 19 | //config: bool "Blacklist support" |
20 | //config: default y | 20 | //config: default y |
21 | //config: depends on MODPROBE && !MODPROBE_SMALL | 21 | //config: depends on MODPROBE && !MODPROBE_SMALL |
22 | //config: select PLATFORM_LINUX | ||
23 | //config: help | 22 | //config: help |
24 | //config: Say 'y' here to enable support for the 'blacklist' command in | 23 | //config: Say 'y' here to enable support for the 'blacklist' command in |
25 | //config: modprobe.conf. This prevents the alias resolver to resolve | 24 | //config: modprobe.conf. This prevents the alias resolver to resolve |
@@ -113,7 +112,7 @@ | |||
113 | //usage: | 112 | //usage: |
114 | //usage:#define modprobe_trivial_usage | 113 | //usage:#define modprobe_trivial_usage |
115 | //usage: "[-alrqvsD" IF_FEATURE_MODPROBE_BLACKLIST("b") "]" | 114 | //usage: "[-alrqvsD" IF_FEATURE_MODPROBE_BLACKLIST("b") "]" |
116 | //usage: " MODULE [SYMBOL=VALUE]..." | 115 | //usage: " MODULE" IF_FEATURE_CMDLINE_MODULE_OPTIONS(" [SYMBOL=VALUE]...") |
117 | //usage:#define modprobe_full_usage "\n\n" | 116 | //usage:#define modprobe_full_usage "\n\n" |
118 | //usage: " -a Load multiple MODULEs" | 117 | //usage: " -a Load multiple MODULEs" |
119 | //usage: "\n -l List (MODULE is a pattern)" | 118 | //usage: "\n -l List (MODULE is a pattern)" |
@@ -175,7 +174,9 @@ static const char modprobe_longopts[] ALIGN1 = | |||
175 | 174 | ||
176 | struct globals { | 175 | struct globals { |
177 | llist_t *probes; /* MEs of module(s) requested on cmdline */ | 176 | llist_t *probes; /* MEs of module(s) requested on cmdline */ |
177 | #if ENABLE_FEATURE_CMDLINE_MODULE_OPTIONS | ||
178 | char *cmdline_mopts; /* module options from cmdline */ | 178 | char *cmdline_mopts; /* module options from cmdline */ |
179 | #endif | ||
179 | int num_unresolved_deps; | 180 | int num_unresolved_deps; |
180 | /* bool. "Did we have 'symbol:FOO' requested on cmdline?" */ | 181 | /* bool. "Did we have 'symbol:FOO' requested on cmdline?" */ |
181 | smallint need_symbols; | 182 | smallint need_symbols; |
@@ -459,8 +460,10 @@ static int do_modprobe(struct module_entry *m) | |||
459 | options = m2->options; | 460 | options = m2->options; |
460 | m2->options = NULL; | 461 | m2->options = NULL; |
461 | options = parse_and_add_kcmdline_module_options(options, m2->modname); | 462 | options = parse_and_add_kcmdline_module_options(options, m2->modname); |
463 | #if ENABLE_FEATURE_CMDLINE_MODULE_OPTIONS | ||
462 | if (m == m2) | 464 | if (m == m2) |
463 | options = gather_options_str(options, G.cmdline_mopts); | 465 | options = gather_options_str(options, G.cmdline_mopts); |
466 | #endif | ||
464 | 467 | ||
465 | if (option_mask32 & OPT_SHOW_DEPS) { | 468 | if (option_mask32 & OPT_SHOW_DEPS) { |
466 | printf(options ? "insmod %s/%s/%s %s\n" | 469 | printf(options ? "insmod %s/%s/%s %s\n" |
@@ -627,7 +630,9 @@ int modprobe_main(int argc UNUSED_PARAM, char **argv) | |||
627 | /* First argument is module name, rest are parameters */ | 630 | /* First argument is module name, rest are parameters */ |
628 | DBG("probing just module %s", *argv); | 631 | DBG("probing just module %s", *argv); |
629 | add_probe(argv[0]); | 632 | add_probe(argv[0]); |
633 | #if ENABLE_FEATURE_CMDLINE_MODULE_OPTIONS | ||
630 | G.cmdline_mopts = parse_cmdline_module_options(argv, /*quote_spaces:*/ 1); | 634 | G.cmdline_mopts = parse_cmdline_module_options(argv, /*quote_spaces:*/ 1); |
635 | #endif | ||
631 | } | 636 | } |
632 | 637 | ||
633 | /* Happens if all requested modules are already loaded */ | 638 | /* Happens if all requested modules are already loaded */ |
diff --git a/modutils/modutils.c b/modutils/modutils.c index 4204f06fe..dae623ee4 100644 --- a/modutils/modutils.c +++ b/modutils/modutils.c | |||
@@ -120,6 +120,7 @@ char* FAST_FUNC filename2modname(const char *filename, char *modname) | |||
120 | return modname; | 120 | return modname; |
121 | } | 121 | } |
122 | 122 | ||
123 | #if ENABLE_FEATURE_CMDLINE_MODULE_OPTIONS | ||
123 | char* FAST_FUNC parse_cmdline_module_options(char **argv, int quote_spaces) | 124 | char* FAST_FUNC parse_cmdline_module_options(char **argv, int quote_spaces) |
124 | { | 125 | { |
125 | char *options; | 126 | char *options; |
@@ -155,6 +156,7 @@ char* FAST_FUNC parse_cmdline_module_options(char **argv, int quote_spaces) | |||
155 | /* if (optlen != 0) options[optlen-1] = '\0'; */ | 156 | /* if (optlen != 0) options[optlen-1] = '\0'; */ |
156 | return options; | 157 | return options; |
157 | } | 158 | } |
159 | #endif | ||
158 | 160 | ||
159 | #if ENABLE_FEATURE_INSMOD_TRY_MMAP | 161 | #if ENABLE_FEATURE_INSMOD_TRY_MMAP |
160 | void* FAST_FUNC try_to_mmap_module(const char *filename, size_t *image_size_p) | 162 | void* FAST_FUNC try_to_mmap_module(const char *filename, size_t *image_size_p) |
diff --git a/modutils/modutils.h b/modutils/modutils.h index 2cbd1448a..76ce242ba 100644 --- a/modutils/modutils.h +++ b/modutils/modutils.h | |||
@@ -51,7 +51,11 @@ void replace(char *s, char what, char with) FAST_FUNC; | |||
51 | char *replace_underscores(char *s) FAST_FUNC; | 51 | char *replace_underscores(char *s) FAST_FUNC; |
52 | int string_to_llist(char *string, llist_t **llist, const char *delim) FAST_FUNC; | 52 | int string_to_llist(char *string, llist_t **llist, const char *delim) FAST_FUNC; |
53 | char *filename2modname(const char *filename, char *modname) FAST_FUNC; | 53 | char *filename2modname(const char *filename, char *modname) FAST_FUNC; |
54 | #if ENABLE_FEATURE_CMDLINE_MODULE_OPTIONS | ||
54 | char *parse_cmdline_module_options(char **argv, int quote_spaces) FAST_FUNC; | 55 | char *parse_cmdline_module_options(char **argv, int quote_spaces) FAST_FUNC; |
56 | #else | ||
57 | # define parse_cmdline_module_options(argv, quote_spaces) "" | ||
58 | #endif | ||
55 | 59 | ||
56 | /* insmod for 2.4 and modprobe's options (insmod 2.6 has no options at all): */ | 60 | /* insmod for 2.4 and modprobe's options (insmod 2.6 has no options at all): */ |
57 | #define INSMOD_OPTS \ | 61 | #define INSMOD_OPTS \ |
diff --git a/networking/ftpd.c b/networking/ftpd.c index bcd60a2ad..439608ce6 100644 --- a/networking/ftpd.c +++ b/networking/ftpd.c | |||
@@ -15,7 +15,7 @@ | |||
15 | //config: bool "ftpd" | 15 | //config: bool "ftpd" |
16 | //config: default y | 16 | //config: default y |
17 | //config: help | 17 | //config: help |
18 | //config: simple FTP daemon. You have to run it via inetd. | 18 | //config: Simple FTP daemon. You have to run it via inetd. |
19 | //config: | 19 | //config: |
20 | //config:config FEATURE_FTPD_WRITE | 20 | //config:config FEATURE_FTPD_WRITE |
21 | //config: bool "Enable upload commands" | 21 | //config: bool "Enable upload commands" |
@@ -47,20 +47,26 @@ | |||
47 | //kbuild:lib-$(CONFIG_FTPD) += ftpd.o | 47 | //kbuild:lib-$(CONFIG_FTPD) += ftpd.o |
48 | 48 | ||
49 | //usage:#define ftpd_trivial_usage | 49 | //usage:#define ftpd_trivial_usage |
50 | //usage: "[-wvS] [-t N] [-T N] [DIR]" | 50 | //usage: "[-wvS]"IF_FEATURE_FTPD_AUTHENTICATION(" [-a USER]")" [-t N] [-T N] [DIR]" |
51 | //usage:#define ftpd_full_usage "\n\n" | 51 | //usage:#define ftpd_full_usage "\n\n" |
52 | //usage: "Anonymous FTP server\n" | 52 | //usage: IF_NOT_FEATURE_FTPD_AUTHENTICATION( |
53 | //usage: "\n" | 53 | //usage: "Anonymous FTP server. Accesses by clients occur under ftpd's UID.\n" |
54 | //usage: "ftpd should be used as an inetd service.\n" | 54 | //usage: ) |
55 | //usage: "ftpd's line for inetd.conf:\n" | 55 | //usage: IF_FEATURE_FTPD_AUTHENTICATION( |
56 | //usage: "FTP server. " | ||
57 | //usage: ) | ||
58 | //usage: "Chroots to DIR, if this fails (run by non-root), cds to it.\n" | ||
59 | //usage: "Should be used as inetd service, inetd.conf line:\n" | ||
56 | //usage: " 21 stream tcp nowait root ftpd ftpd /files/to/serve\n" | 60 | //usage: " 21 stream tcp nowait root ftpd ftpd /files/to/serve\n" |
57 | //usage: "It also can be ran from tcpsvd:\n" | 61 | //usage: "Can be run from tcpsvd:\n" |
58 | //usage: " tcpsvd -vE 0.0.0.0 21 ftpd /files/to/serve\n" | 62 | //usage: " tcpsvd -vE 0.0.0.0 21 ftpd /files/to/serve\n" |
59 | //usage: "\n -w Allow upload" | 63 | //usage: "\n -w Allow upload" |
64 | //usage: IF_FEATURE_FTPD_AUTHENTICATION( | ||
65 | //usage: "\n -a USER Enable 'anonymous' login and map it to USER" | ||
66 | //usage: ) | ||
60 | //usage: "\n -v Log errors to stderr. -vv: verbose log" | 67 | //usage: "\n -v Log errors to stderr. -vv: verbose log" |
61 | //usage: "\n -S Log errors to syslog. -SS: verbose log" | 68 | //usage: "\n -S Log errors to syslog. -SS: verbose log" |
62 | //usage: "\n -t,-T Idle and absolute timeouts" | 69 | //usage: "\n -t,-T N Idle and absolute timeout" |
63 | //usage: "\n DIR Change root to this directory" | ||
64 | 70 | ||
65 | #include "libbb.h" | 71 | #include "libbb.h" |
66 | #include "common_bufsiz.h" | 72 | #include "common_bufsiz.h" |
@@ -695,7 +701,7 @@ popen_ls(const char *opt) | |||
695 | dup(STDOUT_FILENO); /* copy will become STDIN_FILENO */ | 701 | dup(STDOUT_FILENO); /* copy will become STDIN_FILENO */ |
696 | #if BB_MMU | 702 | #if BB_MMU |
697 | /* memset(&G, 0, sizeof(G)); - ls_main does it */ | 703 | /* memset(&G, 0, sizeof(G)); - ls_main does it */ |
698 | exit(ls_main(ARRAY_SIZE(argv) - 1, (char**) argv)); | 704 | exit(ls_main(/*argc_unused*/ 0, (char**) argv)); |
699 | #else | 705 | #else |
700 | cur_fd = xopen(".", O_RDONLY | O_DIRECTORY); | 706 | cur_fd = xopen(".", O_RDONLY | O_DIRECTORY); |
701 | /* On NOMMU, we want to execute a child - copy of ourself | 707 | /* On NOMMU, we want to execute a child - copy of ourself |
@@ -1146,14 +1152,11 @@ enum { | |||
1146 | }; | 1152 | }; |
1147 | 1153 | ||
1148 | int ftpd_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; | 1154 | int ftpd_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; |
1149 | #if !BB_MMU | ||
1150 | int ftpd_main(int argc, char **argv) | ||
1151 | #else | ||
1152 | int ftpd_main(int argc UNUSED_PARAM, char **argv) | 1155 | int ftpd_main(int argc UNUSED_PARAM, char **argv) |
1153 | #endif | ||
1154 | { | 1156 | { |
1155 | #if ENABLE_FEATURE_FTPD_AUTHENTICATION | 1157 | #if ENABLE_FEATURE_FTPD_AUTHENTICATION |
1156 | struct passwd *pw = NULL; | 1158 | struct passwd *pw = NULL; |
1159 | char *anon_opt = NULL; | ||
1157 | #endif | 1160 | #endif |
1158 | unsigned abs_timeout; | 1161 | unsigned abs_timeout; |
1159 | unsigned verbose_S; | 1162 | unsigned verbose_S; |
@@ -1166,16 +1169,21 @@ int ftpd_main(int argc UNUSED_PARAM, char **argv) | |||
1166 | G.timeout = 2 * 60; | 1169 | G.timeout = 2 * 60; |
1167 | opt_complementary = "vv:SS"; | 1170 | opt_complementary = "vv:SS"; |
1168 | #if BB_MMU | 1171 | #if BB_MMU |
1169 | opts = getopt32(argv, "vS" IF_FEATURE_FTPD_WRITE("w") "t:+T:+", &G.timeout, &abs_timeout, &G.verbose, &verbose_S); | 1172 | opts = getopt32(argv, "vS" |
1173 | IF_FEATURE_FTPD_WRITE("w") "t:+T:+" IF_FEATURE_FTPD_AUTHENTICATION("a:"), | ||
1174 | &G.timeout, &abs_timeout, IF_FEATURE_FTPD_AUTHENTICATION(&anon_opt,) | ||
1175 | &G.verbose, &verbose_S); | ||
1170 | #else | 1176 | #else |
1171 | opts = getopt32(argv, "l1AvS" IF_FEATURE_FTPD_WRITE("w") "t:+T:+", &G.timeout, &abs_timeout, &G.verbose, &verbose_S); | 1177 | opts = getopt32(argv, "l1AvS" |
1178 | IF_FEATURE_FTPD_WRITE("w") "t:+T:+" IF_FEATURE_FTPD_AUTHENTICATION("a:"), | ||
1179 | &G.timeout, &abs_timeout, IF_FEATURE_FTPD_AUTHENTICATION(&anon_opt,) | ||
1180 | &G.verbose, &verbose_S); | ||
1172 | if (opts & (OPT_l|OPT_1)) { | 1181 | if (opts & (OPT_l|OPT_1)) { |
1173 | /* Our secret backdoor to ls */ | 1182 | /* Our secret backdoor to ls */ |
1174 | /* TODO: pass --group-directories-first? would be nice, but ls doesn't do that yet */ | ||
1175 | if (fchdir(3) != 0) | 1183 | if (fchdir(3) != 0) |
1176 | _exit(127); | 1184 | _exit(127); |
1177 | /* memset(&G, 0, sizeof(G)); - ls_main does it */ | 1185 | /* memset(&G, 0, sizeof(G)); - ls_main does it */ |
1178 | return ls_main(argc, argv); | 1186 | return ls_main(/*argc_unused*/ 0, argv); |
1179 | } | 1187 | } |
1180 | #endif | 1188 | #endif |
1181 | if (G.verbose < verbose_S) | 1189 | if (G.verbose < verbose_S) |
@@ -1234,7 +1242,12 @@ int ftpd_main(int argc UNUSED_PARAM, char **argv) | |||
1234 | #if ENABLE_FEATURE_FTPD_AUTHENTICATION | 1242 | #if ENABLE_FEATURE_FTPD_AUTHENTICATION |
1235 | while (1) { | 1243 | while (1) { |
1236 | uint32_t cmdval = cmdio_get_cmd_and_arg(); | 1244 | uint32_t cmdval = cmdio_get_cmd_and_arg(); |
1237 | if (cmdval == const_USER) { | 1245 | if (cmdval == const_USER) { |
1246 | if (anon_opt && strcmp(G.ftp_arg, "anonymous") == 0) { | ||
1247 | pw = getpwnam(anon_opt); | ||
1248 | if (pw) | ||
1249 | break; /* does not even ask for password */ | ||
1250 | } | ||
1238 | pw = getpwnam(G.ftp_arg); | 1251 | pw = getpwnam(G.ftp_arg); |
1239 | cmdio_write_raw(STR(FTP_GIVEPWORD)" Please specify password\r\n"); | 1252 | cmdio_write_raw(STR(FTP_GIVEPWORD)" Please specify password\r\n"); |
1240 | } else if (cmdval == const_PASS) { | 1253 | } else if (cmdval == const_PASS) { |
diff --git a/networking/ftpgetput.c b/networking/ftpgetput.c index 0b06f85b4..3eadd752d 100644 --- a/networking/ftpgetput.c +++ b/networking/ftpgetput.c | |||
@@ -28,8 +28,6 @@ | |||
28 | //config: bool "Enable long options in ftpget/ftpput" | 28 | //config: bool "Enable long options in ftpget/ftpput" |
29 | //config: default y | 29 | //config: default y |
30 | //config: depends on LONG_OPTS && (FTPGET || FTPPUT) | 30 | //config: depends on LONG_OPTS && (FTPGET || FTPPUT) |
31 | //config: help | ||
32 | //config: Support long options for the ftpget/ftpput applet. | ||
33 | 31 | ||
34 | //applet:IF_FTPGET(APPLET_ODDNAME(ftpget, ftpgetput, BB_DIR_USR_BIN, BB_SUID_DROP, ftpget)) | 32 | //applet:IF_FTPGET(APPLET_ODDNAME(ftpget, ftpgetput, BB_DIR_USR_BIN, BB_SUID_DROP, ftpget)) |
35 | //applet:IF_FTPPUT(APPLET_ODDNAME(ftpput, ftpgetput, BB_DIR_USR_BIN, BB_SUID_DROP, ftpput)) | 33 | //applet:IF_FTPPUT(APPLET_ODDNAME(ftpput, ftpgetput, BB_DIR_USR_BIN, BB_SUID_DROP, ftpput)) |
diff --git a/networking/hostname.c b/networking/hostname.c index 04a051ede..9f2418422 100644 --- a/networking/hostname.c +++ b/networking/hostname.c | |||
@@ -22,6 +22,7 @@ | |||
22 | //config: help | 22 | //config: help |
23 | //config: Alias to "hostname -d". | 23 | //config: Alias to "hostname -d". |
24 | 24 | ||
25 | // APPLET_ODDNAME:name main location suid_type help | ||
25 | //applet:IF_DNSDOMAINNAME(APPLET_ODDNAME(dnsdomainname, hostname, BB_DIR_BIN, BB_SUID_DROP, dnsdomainname)) | 26 | //applet:IF_DNSDOMAINNAME(APPLET_ODDNAME(dnsdomainname, hostname, BB_DIR_BIN, BB_SUID_DROP, dnsdomainname)) |
26 | //applet:IF_HOSTNAME(APPLET(hostname, BB_DIR_BIN, BB_SUID_DROP)) | 27 | //applet:IF_HOSTNAME(APPLET(hostname, BB_DIR_BIN, BB_SUID_DROP)) |
27 | 28 | ||
diff --git a/networking/httpd.c b/networking/httpd.c index d301d598d..e072f23c7 100644 --- a/networking/httpd.c +++ b/networking/httpd.c | |||
@@ -102,7 +102,7 @@ | |||
102 | //config: bool "httpd" | 102 | //config: bool "httpd" |
103 | //config: default y | 103 | //config: default y |
104 | //config: help | 104 | //config: help |
105 | //config: Serve web pages via an HTTP server. | 105 | //config: HTTP server. |
106 | //config: | 106 | //config: |
107 | //config:config FEATURE_HTTPD_RANGES | 107 | //config:config FEATURE_HTTPD_RANGES |
108 | //config: bool "Support 'Ranges:' header" | 108 | //config: bool "Support 'Ranges:' header" |
@@ -156,7 +156,7 @@ | |||
156 | //config: when specific URLs are requested. | 156 | //config: when specific URLs are requested. |
157 | //config: | 157 | //config: |
158 | //config:config FEATURE_HTTPD_CONFIG_WITH_SCRIPT_INTERPR | 158 | //config:config FEATURE_HTTPD_CONFIG_WITH_SCRIPT_INTERPR |
159 | //config: bool "Support for running scripts through an interpreter" | 159 | //config: bool "Support running scripts through an interpreter" |
160 | //config: default y | 160 | //config: default y |
161 | //config: depends on FEATURE_HTTPD_CGI | 161 | //config: depends on FEATURE_HTTPD_CGI |
162 | //config: help | 162 | //config: help |
@@ -185,7 +185,7 @@ | |||
185 | //config: "<Hello World>". | 185 | //config: "<Hello World>". |
186 | //config: | 186 | //config: |
187 | //config:config FEATURE_HTTPD_ERROR_PAGES | 187 | //config:config FEATURE_HTTPD_ERROR_PAGES |
188 | //config: bool "Support for custom error pages" | 188 | //config: bool "Support custom error pages" |
189 | //config: default y | 189 | //config: default y |
190 | //config: depends on HTTPD | 190 | //config: depends on HTTPD |
191 | //config: help | 191 | //config: help |
@@ -198,7 +198,7 @@ | |||
198 | //config: message. | 198 | //config: message. |
199 | //config: | 199 | //config: |
200 | //config:config FEATURE_HTTPD_PROXY | 200 | //config:config FEATURE_HTTPD_PROXY |
201 | //config: bool "Support for reverse proxy" | 201 | //config: bool "Support reverse proxy" |
202 | //config: default y | 202 | //config: default y |
203 | //config: depends on HTTPD | 203 | //config: depends on HTTPD |
204 | //config: help | 204 | //config: help |
@@ -210,7 +210,7 @@ | |||
210 | //config: http://hostname[:port]/new/path/myfile. | 210 | //config: http://hostname[:port]/new/path/myfile. |
211 | //config: | 211 | //config: |
212 | //config:config FEATURE_HTTPD_GZIP | 212 | //config:config FEATURE_HTTPD_GZIP |
213 | //config: bool "Support for GZIP content encoding" | 213 | //config: bool "Support GZIP content encoding" |
214 | //config: default y | 214 | //config: default y |
215 | //config: depends on HTTPD | 215 | //config: depends on HTTPD |
216 | //config: help | 216 | //config: help |
@@ -460,11 +460,6 @@ struct globals { | |||
460 | #define ip_a_d (G.ip_a_d ) | 460 | #define ip_a_d (G.ip_a_d ) |
461 | #define g_realm (G.g_realm ) | 461 | #define g_realm (G.g_realm ) |
462 | #define remoteuser (G.remoteuser ) | 462 | #define remoteuser (G.remoteuser ) |
463 | #define referer (G.referer ) | ||
464 | #define user_agent (G.user_agent ) | ||
465 | #define host (G.host ) | ||
466 | #define http_accept (G.http_accept ) | ||
467 | #define http_accept_language (G.http_accept_language) | ||
468 | #define file_size (G.file_size ) | 463 | #define file_size (G.file_size ) |
469 | #if ENABLE_FEATURE_HTTPD_RANGES | 464 | #if ENABLE_FEATURE_HTTPD_RANGES |
470 | #define range_start (G.range_start ) | 465 | #define range_start (G.range_start ) |
@@ -1152,7 +1147,7 @@ static void send_headers(int responseNum) | |||
1152 | "Last-Modified: %s\r\n" | 1147 | "Last-Modified: %s\r\n" |
1153 | "%s %"OFF_FMT"u\r\n", | 1148 | "%s %"OFF_FMT"u\r\n", |
1154 | date_str, | 1149 | date_str, |
1155 | content_gzip ? "Transfer-length:" : "Content-length:", | 1150 | content_gzip ? "Transfer-Length:" : "Content-Length:", |
1156 | file_size | 1151 | file_size |
1157 | ); | 1152 | ); |
1158 | } | 1153 | } |
@@ -1529,11 +1524,11 @@ static void send_cgi_and_exit( | |||
1529 | #endif | 1524 | #endif |
1530 | } | 1525 | } |
1531 | } | 1526 | } |
1532 | setenv1("HTTP_USER_AGENT", user_agent); | 1527 | setenv1("HTTP_USER_AGENT", G.user_agent); |
1533 | if (http_accept) | 1528 | if (G.http_accept) |
1534 | setenv1("HTTP_ACCEPT", http_accept); | 1529 | setenv1("HTTP_ACCEPT", G.http_accept); |
1535 | if (http_accept_language) | 1530 | if (G.http_accept_language) |
1536 | setenv1("HTTP_ACCEPT_LANGUAGE", http_accept_language); | 1531 | setenv1("HTTP_ACCEPT_LANGUAGE", G.http_accept_language); |
1537 | if (post_len) | 1532 | if (post_len) |
1538 | putenv(xasprintf("CONTENT_LENGTH=%d", post_len)); | 1533 | putenv(xasprintf("CONTENT_LENGTH=%d", post_len)); |
1539 | if (cookie) | 1534 | if (cookie) |
@@ -1546,9 +1541,9 @@ static void send_cgi_and_exit( | |||
1546 | putenv((char*)"AUTH_TYPE=Basic"); | 1541 | putenv((char*)"AUTH_TYPE=Basic"); |
1547 | } | 1542 | } |
1548 | #endif | 1543 | #endif |
1549 | if (referer) | 1544 | if (G.referer) |
1550 | setenv1("HTTP_REFERER", referer); | 1545 | setenv1("HTTP_REFERER", G.referer); |
1551 | setenv1("HTTP_HOST", host); /* set to "" if NULL */ | 1546 | setenv1("HTTP_HOST", G.host); /* set to "" if NULL */ |
1552 | /* setenv1("SERVER_NAME", safe_gethostname()); - don't do this, | 1547 | /* setenv1("SERVER_NAME", safe_gethostname()); - don't do this, |
1553 | * just run "env SERVER_NAME=xyz httpd ..." instead */ | 1548 | * just run "env SERVER_NAME=xyz httpd ..." instead */ |
1554 | 1549 | ||
@@ -2269,10 +2264,8 @@ static void handle_incoming_and_exit(const len_and_sockaddr *fromAddr) | |||
2269 | #if ENABLE_FEATURE_HTTPD_PROXY | 2264 | #if ENABLE_FEATURE_HTTPD_PROXY |
2270 | /* We need 2 more bytes for yet another "\r\n" - | 2265 | /* We need 2 more bytes for yet another "\r\n" - |
2271 | * see near fdprintf(proxy_fd...) further below */ | 2266 | * see near fdprintf(proxy_fd...) further below */ |
2272 | if (proxy_entry && (header_ptr - header_buf) < IOBUF_SIZE - 2) { | 2267 | if (proxy_entry && (header_ptr - header_buf) < IOBUF_SIZE - 4) { |
2273 | int len = strlen(iobuf); | 2268 | int len = strnlen(iobuf, IOBUF_SIZE - (header_ptr - header_buf) - 4); |
2274 | if (len > IOBUF_SIZE - (header_ptr - header_buf) - 4) | ||
2275 | len = IOBUF_SIZE - (header_ptr - header_buf) - 4; | ||
2276 | memcpy(header_ptr, iobuf, len); | 2269 | memcpy(header_ptr, iobuf, len); |
2277 | header_ptr += len; | 2270 | header_ptr += len; |
2278 | header_ptr[0] = '\r'; | 2271 | header_ptr[0] = '\r'; |
@@ -2283,14 +2276,14 @@ static void handle_incoming_and_exit(const len_and_sockaddr *fromAddr) | |||
2283 | 2276 | ||
2284 | #if ENABLE_FEATURE_HTTPD_CGI || ENABLE_FEATURE_HTTPD_PROXY | 2277 | #if ENABLE_FEATURE_HTTPD_CGI || ENABLE_FEATURE_HTTPD_PROXY |
2285 | /* Try and do our best to parse more lines */ | 2278 | /* Try and do our best to parse more lines */ |
2286 | if ((STRNCASECMP(iobuf, "Content-length:") == 0)) { | 2279 | if ((STRNCASECMP(iobuf, "Content-Length:") == 0)) { |
2287 | /* extra read only for POST */ | 2280 | /* extra read only for POST */ |
2288 | if (prequest != request_GET | 2281 | if (prequest != request_GET |
2289 | # if ENABLE_FEATURE_HTTPD_CGI | 2282 | # if ENABLE_FEATURE_HTTPD_CGI |
2290 | && prequest != request_HEAD | 2283 | && prequest != request_HEAD |
2291 | # endif | 2284 | # endif |
2292 | ) { | 2285 | ) { |
2293 | tptr = skip_whitespace(iobuf + sizeof("Content-length:") - 1); | 2286 | tptr = skip_whitespace(iobuf + sizeof("Content-Length:") - 1); |
2294 | if (!tptr[0]) | 2287 | if (!tptr[0]) |
2295 | send_headers_and_exit(HTTP_BAD_REQUEST); | 2288 | send_headers_and_exit(HTTP_BAD_REQUEST); |
2296 | /* not using strtoul: it ignores leading minus! */ | 2289 | /* not using strtoul: it ignores leading minus! */ |
@@ -2303,19 +2296,26 @@ static void handle_incoming_and_exit(const len_and_sockaddr *fromAddr) | |||
2303 | #endif | 2296 | #endif |
2304 | #if ENABLE_FEATURE_HTTPD_CGI | 2297 | #if ENABLE_FEATURE_HTTPD_CGI |
2305 | else if (STRNCASECMP(iobuf, "Cookie:") == 0) { | 2298 | else if (STRNCASECMP(iobuf, "Cookie:") == 0) { |
2306 | cookie = xstrdup(skip_whitespace(iobuf + sizeof("Cookie:")-1)); | 2299 | if (!cookie) /* in case they send millions of these, do not OOM */ |
2300 | cookie = xstrdup(skip_whitespace(iobuf + sizeof("Cookie:")-1)); | ||
2307 | } else if (STRNCASECMP(iobuf, "Content-Type:") == 0) { | 2301 | } else if (STRNCASECMP(iobuf, "Content-Type:") == 0) { |
2308 | content_type = xstrdup(skip_whitespace(iobuf + sizeof("Content-Type:")-1)); | 2302 | if (!content_type) |
2303 | content_type = xstrdup(skip_whitespace(iobuf + sizeof("Content-Type:")-1)); | ||
2309 | } else if (STRNCASECMP(iobuf, "Referer:") == 0) { | 2304 | } else if (STRNCASECMP(iobuf, "Referer:") == 0) { |
2310 | referer = xstrdup(skip_whitespace(iobuf + sizeof("Referer:")-1)); | 2305 | if (!G.referer) |
2306 | G.referer = xstrdup(skip_whitespace(iobuf + sizeof("Referer:")-1)); | ||
2311 | } else if (STRNCASECMP(iobuf, "User-Agent:") == 0) { | 2307 | } else if (STRNCASECMP(iobuf, "User-Agent:") == 0) { |
2312 | user_agent = xstrdup(skip_whitespace(iobuf + sizeof("User-Agent:")-1)); | 2308 | if (!G.user_agent) |
2309 | G.user_agent = xstrdup(skip_whitespace(iobuf + sizeof("User-Agent:")-1)); | ||
2313 | } else if (STRNCASECMP(iobuf, "Host:") == 0) { | 2310 | } else if (STRNCASECMP(iobuf, "Host:") == 0) { |
2314 | host = xstrdup(skip_whitespace(iobuf + sizeof("Host:")-1)); | 2311 | if (!G.host) |
2312 | G.host = xstrdup(skip_whitespace(iobuf + sizeof("Host:")-1)); | ||
2315 | } else if (STRNCASECMP(iobuf, "Accept:") == 0) { | 2313 | } else if (STRNCASECMP(iobuf, "Accept:") == 0) { |
2316 | http_accept = xstrdup(skip_whitespace(iobuf + sizeof("Accept:")-1)); | 2314 | if (!G.http_accept) |
2315 | G.http_accept = xstrdup(skip_whitespace(iobuf + sizeof("Accept:")-1)); | ||
2317 | } else if (STRNCASECMP(iobuf, "Accept-Language:") == 0) { | 2316 | } else if (STRNCASECMP(iobuf, "Accept-Language:") == 0) { |
2318 | http_accept_language = xstrdup(skip_whitespace(iobuf + sizeof("Accept-Language:")-1)); | 2317 | if (!G.http_accept_language) |
2318 | G.http_accept_language = xstrdup(skip_whitespace(iobuf + sizeof("Accept-Language:")-1)); | ||
2319 | } | 2319 | } |
2320 | #endif | 2320 | #endif |
2321 | #if ENABLE_FEATURE_HTTPD_BASIC_AUTH | 2321 | #if ENABLE_FEATURE_HTTPD_BASIC_AUTH |
@@ -2396,12 +2396,12 @@ static void handle_incoming_and_exit(const len_and_sockaddr *fromAddr) | |||
2396 | int proxy_fd; | 2396 | int proxy_fd; |
2397 | len_and_sockaddr *lsa; | 2397 | len_and_sockaddr *lsa; |
2398 | 2398 | ||
2399 | proxy_fd = socket(AF_INET, SOCK_STREAM, 0); | ||
2400 | if (proxy_fd < 0) | ||
2401 | send_headers_and_exit(HTTP_INTERNAL_SERVER_ERROR); | ||
2402 | lsa = host2sockaddr(proxy_entry->host_port, 80); | 2399 | lsa = host2sockaddr(proxy_entry->host_port, 80); |
2403 | if (lsa == NULL) | 2400 | if (lsa == NULL) |
2404 | send_headers_and_exit(HTTP_INTERNAL_SERVER_ERROR); | 2401 | send_headers_and_exit(HTTP_INTERNAL_SERVER_ERROR); |
2402 | proxy_fd = socket(lsa->u.sa.sa_family, SOCK_STREAM, 0); | ||
2403 | if (proxy_fd < 0) | ||
2404 | send_headers_and_exit(HTTP_INTERNAL_SERVER_ERROR); | ||
2405 | if (connect(proxy_fd, &lsa->u.sa, lsa->len) < 0) | 2405 | if (connect(proxy_fd, &lsa->u.sa, lsa->len) < 0) |
2406 | send_headers_and_exit(HTTP_INTERNAL_SERVER_ERROR); | 2406 | send_headers_and_exit(HTTP_INTERNAL_SERVER_ERROR); |
2407 | fdprintf(proxy_fd, "%s %s%s%s%s HTTP/%c.%c\r\n", | 2407 | fdprintf(proxy_fd, "%s %s%s%s%s HTTP/%c.%c\r\n", |
diff --git a/networking/ifupdown.c b/networking/ifupdown.c index 1806a6ccc..a76fe1021 100644 --- a/networking/ifupdown.c +++ b/networking/ifupdown.c | |||
@@ -66,14 +66,14 @@ | |||
66 | //config: utilities, or enable these applets in Busybox. | 66 | //config: utilities, or enable these applets in Busybox. |
67 | //config: | 67 | //config: |
68 | //config:config FEATURE_IFUPDOWN_IPV4 | 68 | //config:config FEATURE_IFUPDOWN_IPV4 |
69 | //config: bool "Support for IPv4" | 69 | //config: bool "Support IPv4" |
70 | //config: default y | 70 | //config: default y |
71 | //config: depends on IFUP || IFDOWN | 71 | //config: depends on IFUP || IFDOWN |
72 | //config: help | 72 | //config: help |
73 | //config: If you want ifup/ifdown to talk IPv4, leave this on. | 73 | //config: If you want ifup/ifdown to talk IPv4, leave this on. |
74 | //config: | 74 | //config: |
75 | //config:config FEATURE_IFUPDOWN_IPV6 | 75 | //config:config FEATURE_IFUPDOWN_IPV6 |
76 | //config: bool "Support for IPv6" | 76 | //config: bool "Support IPv6" |
77 | //config: default y | 77 | //config: default y |
78 | //config: depends on (IFUP || IFDOWN) && FEATURE_IPV6 | 78 | //config: depends on (IFUP || IFDOWN) && FEATURE_IPV6 |
79 | //config: help | 79 | //config: help |
@@ -81,7 +81,7 @@ | |||
81 | //config: | 81 | //config: |
82 | //UNUSED: | 82 | //UNUSED: |
83 | ////////:config FEATURE_IFUPDOWN_IPX | 83 | ////////:config FEATURE_IFUPDOWN_IPX |
84 | ////////: bool "Support for IPX" | 84 | ////////: bool "Support IPX" |
85 | ////////: default y | 85 | ////////: default y |
86 | ////////: depends on IFUP || IFDOWN | 86 | ////////: depends on IFUP || IFDOWN |
87 | ////////: help | 87 | ////////: help |
@@ -97,7 +97,7 @@ | |||
97 | //config: a weird network setup you don't need it. | 97 | //config: a weird network setup you don't need it. |
98 | //config: | 98 | //config: |
99 | //config:config FEATURE_IFUPDOWN_EXTERNAL_DHCP | 99 | //config:config FEATURE_IFUPDOWN_EXTERNAL_DHCP |
100 | //config: bool "Support for external dhcp clients" | 100 | //config: bool "Support external DHCP clients" |
101 | //config: default n | 101 | //config: default n |
102 | //config: depends on IFUP || IFDOWN | 102 | //config: depends on IFUP || IFDOWN |
103 | //config: help | 103 | //config: help |
@@ -106,7 +106,8 @@ | |||
106 | //config: Otherwise, if udhcpc applet is enabled, it is used. | 106 | //config: Otherwise, if udhcpc applet is enabled, it is used. |
107 | //config: Otherwise, ifup/ifdown will have no support for DHCP. | 107 | //config: Otherwise, ifup/ifdown will have no support for DHCP. |
108 | 108 | ||
109 | //applet:IF_IFUP(APPLET_ODDNAME(ifup, ifupdown, BB_DIR_SBIN, BB_SUID_DROP, ifup)) | 109 | // APPLET_ODDNAME:name main location suid_type help |
110 | //applet:IF_IFUP( APPLET_ODDNAME(ifup, ifupdown, BB_DIR_SBIN, BB_SUID_DROP, ifup)) | ||
110 | //applet:IF_IFDOWN(APPLET_ODDNAME(ifdown, ifupdown, BB_DIR_SBIN, BB_SUID_DROP, ifdown)) | 111 | //applet:IF_IFDOWN(APPLET_ODDNAME(ifdown, ifupdown, BB_DIR_SBIN, BB_SUID_DROP, ifdown)) |
111 | 112 | ||
112 | //kbuild:lib-$(CONFIG_IFUP) += ifupdown.o | 113 | //kbuild:lib-$(CONFIG_IFUP) += ifupdown.o |
diff --git a/networking/inetd.c b/networking/inetd.c index 4d0ab2e0d..01e659f13 100644 --- a/networking/inetd.c +++ b/networking/inetd.c | |||
@@ -213,9 +213,9 @@ | |||
213 | //usage: "Listen for network connections and launch programs\n" | 213 | //usage: "Listen for network connections and launch programs\n" |
214 | //usage: "\n -f Run in foreground" | 214 | //usage: "\n -f Run in foreground" |
215 | //usage: "\n -e Log to stderr" | 215 | //usage: "\n -e Log to stderr" |
216 | //usage: "\n -q N Socket listen queue (default: 128)" | 216 | //usage: "\n -q N Socket listen queue (default 128)" |
217 | //usage: "\n -R N Pause services after N connects/min" | 217 | //usage: "\n -R N Pause services after N connects/min" |
218 | //usage: "\n (default: 0 - disabled)" | 218 | //usage: "\n (default 0 - disabled)" |
219 | 219 | ||
220 | #include <syslog.h> | 220 | #include <syslog.h> |
221 | #include <sys/resource.h> /* setrlimit */ | 221 | #include <sys/resource.h> /* setrlimit */ |
@@ -1677,7 +1677,7 @@ static uint32_t machtime(void) | |||
1677 | struct timeval tv; | 1677 | struct timeval tv; |
1678 | 1678 | ||
1679 | gettimeofday(&tv, NULL); | 1679 | gettimeofday(&tv, NULL); |
1680 | return htonl((uint32_t)(tv.tv_sec + 2208988800)); | 1680 | return htonl((uint32_t)(tv.tv_sec + 2208988800U)); |
1681 | } | 1681 | } |
1682 | /* ARGSUSED */ | 1682 | /* ARGSUSED */ |
1683 | static void FAST_FUNC machtime_stream(int s, servtab_t *sep UNUSED_PARAM) | 1683 | static void FAST_FUNC machtime_stream(int s, servtab_t *sep UNUSED_PARAM) |
diff --git a/networking/ip.c b/networking/ip.c index 939721e46..0f52b19dd 100644 --- a/networking/ip.c +++ b/networking/ip.c | |||
@@ -140,84 +140,106 @@ | |||
140 | //kbuild:lib-$(CONFIG_IPTUNNEL) += ip.o | 140 | //kbuild:lib-$(CONFIG_IPTUNNEL) += ip.o |
141 | //kbuild:lib-$(CONFIG_IPNEIGH) += ip.o | 141 | //kbuild:lib-$(CONFIG_IPNEIGH) += ip.o |
142 | 142 | ||
143 | /* would need to make the " | " optional depending on more than one selected: */ | ||
144 | //usage:#define ip_trivial_usage | ||
145 | //usage: "[OPTIONS] {" | ||
146 | //usage: IF_FEATURE_IP_ADDRESS("address | ") | ||
147 | //usage: IF_FEATURE_IP_ROUTE("route | ") | ||
148 | //usage: IF_FEATURE_IP_LINK("link | ") | ||
149 | //usage: IF_FEATURE_IP_TUNNEL("tunnel | ") | ||
150 | //usage: IF_FEATURE_IP_NEIGH("neigh | ") | ||
151 | //usage: IF_FEATURE_IP_RULE("rule") | ||
152 | //usage: "} {COMMAND}" | ||
153 | //usage:#define ip_full_usage "\n\n" | ||
154 | //usage: "ip [OPTIONS] OBJECT {COMMAND}\n" | ||
155 | //usage: "where OBJECT := {" | ||
156 | //usage: IF_FEATURE_IP_ADDRESS("address | ") | ||
157 | //usage: IF_FEATURE_IP_ROUTE("route | ") | ||
158 | //usage: IF_FEATURE_IP_LINK("link | ") | ||
159 | //usage: IF_FEATURE_IP_TUNNEL("tunnel | ") | ||
160 | //usage: IF_FEATURE_IP_NEIGH("neigh | ") | ||
161 | //usage: IF_FEATURE_IP_RULE("rule") | ||
162 | //usage: "}\n" | ||
163 | //usage: "OPTIONS := { -f[amily] { inet | inet6 | link } | -o[neline] }" | ||
164 | //usage: | ||
165 | //usage:#define ipaddr_trivial_usage | 143 | //usage:#define ipaddr_trivial_usage |
166 | //usage: "{ {add|del} IFADDR dev STRING | {show|flush}\n" | 144 | //usage: "add|del IFADDR dev IFACE | show|flush [dev IFACE] [to PREFIX]" |
167 | //usage: " [dev STRING] [to PREFIX] }" | ||
168 | //usage:#define ipaddr_full_usage "\n\n" | 145 | //usage:#define ipaddr_full_usage "\n\n" |
169 | //usage: "ipaddr {add|change|replace|delete} IFADDR dev STRING\n" | 146 | //usage: "ipaddr add|change|replace|delete IFADDR dev IFACE\n" |
170 | //usage: "ipaddr {show|flush} [dev STRING] [scope SCOPE-ID]\n" | 147 | //usage: "ipaddr show|flush [dev IFACE] [scope SCOPE-ID]\n" |
171 | //usage: " [to PREFIX] [label PATTERN]\n" | 148 | //usage: " [to PREFIX] [label PATTERN]\n" |
172 | //usage: " IFADDR := PREFIX | ADDR peer PREFIX\n" | 149 | //usage: " IFADDR := PREFIX | ADDR peer PREFIX\n" |
173 | //usage: " [broadcast ADDR] [anycast ADDR]\n" | 150 | //usage: " [broadcast ADDR] [anycast ADDR]\n" |
174 | //usage: " [label STRING] [scope SCOPE-ID]\n" | 151 | //usage: " [label STRING] [scope SCOPE-ID]\n" |
175 | //usage: " SCOPE-ID := [host | link | global | NUMBER]" | 152 | //usage: " SCOPE-ID := [host|link|global|NUMBER]" |
176 | //usage: | 153 | //usage: |
177 | //usage:#define iplink_trivial_usage | 154 | //usage:#define iplink_trivial_usage |
178 | //usage: "{ set DEVICE { up | down | arp { on | off } | show [DEVICE] }" | 155 | //usage: "set IFACE [up|down] [arp on|off] | show [IFACE]" |
179 | //usage:#define iplink_full_usage "\n\n" | 156 | //usage:#define iplink_full_usage "\n\n" |
180 | //usage: "iplink set DEVICE { up | down | arp | multicast { on | off } |\n" | 157 | //usage: "iplink set IFACE [up|down]\n" |
181 | //usage: " dynamic { on | off } |\n" | 158 | //usage: " [arp on|off]\n" |
182 | //usage: " mtu MTU }\n" | 159 | //usage: " [dynamic on|off]\n" |
183 | //usage: "iplink show [DEVICE]" | 160 | //usage: " [multicast on|off]\n" |
161 | //usage: " [mtu MTU]\n" | ||
162 | //usage: "iplink show [IFACE]" | ||
184 | //usage: | 163 | //usage: |
185 | //usage:#define iproute_trivial_usage | 164 | //usage:#define iproute_trivial_usage |
186 | //usage: "{ list | flush | add | del | change | append |\n" | 165 | //usage: "list|flush|add|del|change|append|replace|test ROUTE" |
187 | //usage: " replace | test } ROUTE" | ||
188 | //usage:#define iproute_full_usage "\n\n" | 166 | //usage:#define iproute_full_usage "\n\n" |
189 | //usage: "iproute { list | flush } SELECTOR\n" | 167 | //usage: "iproute list|flush SELECTOR\n" |
190 | //usage: "iproute get ADDRESS [from ADDRESS iif STRING]\n" | 168 | //usage: "iproute get ADDRESS [from ADDRESS iif STRING]\n" |
191 | //usage: " [oif STRING] [tos TOS]\n" | 169 | //usage: " [oif STRING] [tos TOS]\n" |
192 | //usage: "iproute { add | del | change | append | replace | test } ROUTE\n" | 170 | //usage: "iproute add|del|change|append|replace|test ROUTE\n" |
193 | //usage: " SELECTOR := [root PREFIX] [match PREFIX] [proto RTPROTO]\n" | 171 | //usage: " SELECTOR := [root PREFIX] [match PREFIX] [proto RTPROTO]\n" |
194 | //usage: " ROUTE := [TYPE] PREFIX [tos TOS] [proto RTPROTO] [metric METRIC]" | 172 | //usage: " ROUTE := [TYPE] PREFIX [tos TOS] [proto RTPROTO] [metric METRIC]" |
195 | //usage: | 173 | //usage: |
196 | //usage:#define iprule_trivial_usage | 174 | //usage:#define iprule_trivial_usage |
197 | //usage: "{[list | add | del] RULE}" | 175 | //usage: "[list] | add|del SELECTOR ACTION" |
198 | //usage:#define iprule_full_usage "\n\n" | 176 | //usage:#define iprule_full_usage "\n\n" |
199 | //usage: "iprule [list | add | del] SELECTOR ACTION\n" | ||
200 | //usage: " SELECTOR := [from PREFIX] [to PREFIX] [tos TOS] [fwmark FWMARK]\n" | 177 | //usage: " SELECTOR := [from PREFIX] [to PREFIX] [tos TOS] [fwmark FWMARK]\n" |
201 | //usage: " [dev STRING] [pref NUMBER]\n" | 178 | //usage: " [dev IFACE] [pref NUMBER]\n" |
202 | //usage: " ACTION := [table TABLE_ID] [nat ADDRESS]\n" | 179 | //usage: " ACTION := [table TABLE_ID] [nat ADDRESS]\n" |
203 | //usage: " [prohibit | reject | unreachable]\n" | 180 | //usage: " [prohibit|reject|unreachable]\n" |
204 | //usage: " [realms [SRCREALM/]DSTREALM]\n" | 181 | //usage: " [realms [SRCREALM/]DSTREALM]\n" |
205 | //usage: " TABLE_ID := [local | main | default | NUMBER]" | 182 | //usage: " TABLE_ID := [local|main|default|NUMBER]" |
206 | //usage: | 183 | //usage: |
207 | //usage:#define iptunnel_trivial_usage | 184 | //usage:#define iptunnel_trivial_usage |
208 | //usage: "{ add | change | del | show } [NAME]\n" | 185 | //usage: "add|change|del|show [NAME]\n" |
209 | //usage: " [mode { ipip | gre | sit }]\n" | 186 | //usage: " [mode ipip|gre|sit]\n" |
210 | //usage: " [remote ADDR] [local ADDR] [ttl TTL]" | 187 | //usage: " [remote ADDR] [local ADDR] [ttl TTL]" |
211 | //usage:#define iptunnel_full_usage "\n\n" | 188 | //usage:#define iptunnel_full_usage "\n\n" |
212 | //usage: "iptunnel { add | change | del | show } [NAME]\n" | 189 | //usage: "iptunnel add|change|del|show [NAME]\n" |
213 | //usage: " [mode { ipip | gre | sit }] [remote ADDR] [local ADDR]\n" | 190 | //usage: " [mode ipip|gre|sit] [remote ADDR] [local ADDR]\n" |
214 | //usage: " [[i|o]seq] [[i|o]key KEY] [[i|o]csum]\n" | 191 | //usage: " [[i|o]seq] [[i|o]key KEY] [[i|o]csum]\n" |
215 | //usage: " [ttl TTL] [tos TOS] [[no]pmtudisc] [dev PHYS_DEV]" | 192 | //usage: " [ttl TTL] [tos TOS] [[no]pmtudisc] [dev PHYS_DEV]" |
216 | //usage: | 193 | //usage: |
217 | //usage:#define ipneigh_trivial_usage | 194 | //usage:#define ipneigh_trivial_usage |
218 | //usage: "{ show | flush} [ to PREFIX ] [ dev DEV ] [ nud STATE ]" | 195 | //usage: "show|flush [to PREFIX] [dev DEV] [nud STATE]" |
219 | //usage:#define ipneigh_full_usage "\n\n" | 196 | //usage:#define ipneigh_full_usage "" |
220 | //usage: "ipneigh { show | flush} [ to PREFIX ] [ dev DEV ] [ nud STATE ]" | 197 | //usage: |
198 | //usage:#if ENABLE_FEATURE_IP_ADDRESS || ENABLE_FEATURE_IP_ROUTE | ||
199 | //usage:# define IP_BAR_LINK "|" | ||
200 | //usage:#else | ||
201 | //usage:# define IP_BAR_LINK "" | ||
202 | //usage:#endif | ||
203 | //usage:#if ENABLE_FEATURE_IP_ADDRESS || ENABLE_FEATURE_IP_ROUTE || ENABLE_FEATURE_IP_LINK | ||
204 | //usage:# define IP_BAR_TUNNEL "|" | ||
205 | //usage:#else | ||
206 | //usage:# define IP_BAR_TUNNEL "" | ||
207 | //usage:#endif | ||
208 | //usage:#if ENABLE_FEATURE_IP_ADDRESS || ENABLE_FEATURE_IP_ROUTE || ENABLE_FEATURE_IP_LINK || ENABLE_FEATURE_IP_TUNNEL | ||
209 | //usage:# define IP_BAR_NEIGH "|" | ||
210 | //usage:#else | ||
211 | //usage:# define IP_BAR_NEIGH "" | ||
212 | //usage:#endif | ||
213 | //usage:#if ENABLE_FEATURE_IP_ADDRESS || ENABLE_FEATURE_IP_ROUTE || ENABLE_FEATURE_IP_LINK || ENABLE_FEATURE_IP_TUNNEL || ENABLE_FEATURE_IP_NEIGH | ||
214 | //usage:# define IP_BAR_RULE "|" | ||
215 | //usage:#else | ||
216 | //usage:# define IP_BAR_RULE "" | ||
217 | //usage:#endif | ||
218 | //usage: | ||
219 | //usage:#define ip_trivial_usage | ||
220 | //usage: "[OPTIONS] " | ||
221 | //usage: IF_FEATURE_IP_ADDRESS("address") | ||
222 | //usage: IF_FEATURE_IP_ROUTE( IF_FEATURE_IP_ADDRESS("|")"route") | ||
223 | //usage: IF_FEATURE_IP_LINK( IP_BAR_LINK "link") | ||
224 | //usage: IF_FEATURE_IP_TUNNEL( IP_BAR_TUNNEL"tunnel") | ||
225 | //usage: IF_FEATURE_IP_NEIGH( IP_BAR_NEIGH "neigh") | ||
226 | //usage: IF_FEATURE_IP_RULE( IP_BAR_RULE "rule") | ||
227 | //usage: " [COMMAND]" | ||
228 | //usage:#define ip_full_usage "\n\n" | ||
229 | //usage: "OPTIONS := -f[amily] inet|inet6|link | -o[neline]\n" | ||
230 | //usage: "COMMAND :=" | ||
231 | //usage: IF_FEATURE_IP_ADDRESS("\n" | ||
232 | //usage: "ip addr "ipaddr_trivial_usage) | ||
233 | //usage: IF_FEATURE_IP_ROUTE("\n" | ||
234 | //usage: "ip route "iproute_trivial_usage) | ||
235 | //usage: IF_FEATURE_IP_LINK("\n" | ||
236 | //usage: "ip link "iplink_trivial_usage) | ||
237 | //usage: IF_FEATURE_IP_TUNNEL("\n" | ||
238 | //usage: "ip tunnel "iptunnel_trivial_usage) | ||
239 | //usage: IF_FEATURE_IP_NEIGH("\n" | ||
240 | //usage: "ip neigh "ipneigh_trivial_usage) | ||
241 | //usage: IF_FEATURE_IP_RULE("\n" | ||
242 | //usage: "ip rule "iprule_trivial_usage) | ||
221 | 243 | ||
222 | #include "libbb.h" | 244 | #include "libbb.h" |
223 | 245 | ||
diff --git a/networking/ipcalc.c b/networking/ipcalc.c index 21219424f..9359f9016 100644 --- a/networking/ipcalc.c +++ b/networking/ipcalc.c | |||
@@ -18,6 +18,11 @@ | |||
18 | //config: ipcalc takes an IP address and netmask and calculates the | 18 | //config: ipcalc takes an IP address and netmask and calculates the |
19 | //config: resulting broadcast, network, and host range. | 19 | //config: resulting broadcast, network, and host range. |
20 | //config: | 20 | //config: |
21 | //config:config FEATURE_IPCALC_LONG_OPTIONS | ||
22 | //config: bool "Enable long options" | ||
23 | //config: default y | ||
24 | //config: depends on IPCALC && LONG_OPTS | ||
25 | //config: | ||
21 | //config:config FEATURE_IPCALC_FANCY | 26 | //config:config FEATURE_IPCALC_FANCY |
22 | //config: bool "Fancy IPCALC, more options, adds 1 kbyte" | 27 | //config: bool "Fancy IPCALC, more options, adds 1 kbyte" |
23 | //config: default y | 28 | //config: default y |
@@ -25,13 +30,6 @@ | |||
25 | //config: help | 30 | //config: help |
26 | //config: Adds the options hostname, prefix and silent to the output of | 31 | //config: Adds the options hostname, prefix and silent to the output of |
27 | //config: "ipcalc". | 32 | //config: "ipcalc". |
28 | //config: | ||
29 | //config:config FEATURE_IPCALC_LONG_OPTIONS | ||
30 | //config: bool "Enable long options" | ||
31 | //config: default y | ||
32 | //config: depends on IPCALC && LONG_OPTS | ||
33 | //config: help | ||
34 | //config: Support long options for the ipcalc applet. | ||
35 | 33 | ||
36 | //applet:IF_IPCALC(APPLET(ipcalc, BB_DIR_BIN, BB_SUID_DROP)) | 34 | //applet:IF_IPCALC(APPLET(ipcalc, BB_DIR_BIN, BB_SUID_DROP)) |
37 | 35 | ||
diff --git a/networking/netstat.c b/networking/netstat.c index 90da6cdb8..68e0c1a04 100644 --- a/networking/netstat.c +++ b/networking/netstat.c | |||
@@ -21,7 +21,7 @@ | |||
21 | //config: netstat prints information about the Linux networking subsystem. | 21 | //config: netstat prints information about the Linux networking subsystem. |
22 | //config: | 22 | //config: |
23 | //config:config FEATURE_NETSTAT_WIDE | 23 | //config:config FEATURE_NETSTAT_WIDE |
24 | //config: bool "Enable wide netstat output" | 24 | //config: bool "Enable wide output" |
25 | //config: default y | 25 | //config: default y |
26 | //config: depends on NETSTAT | 26 | //config: depends on NETSTAT |
27 | //config: help | 27 | //config: help |
diff --git a/networking/ntpd.c b/networking/ntpd.c index bfd5705fc..5cc71ca7a 100644 --- a/networking/ntpd.c +++ b/networking/ntpd.c | |||
@@ -757,7 +757,7 @@ reset_peer_stats(peer_t *p, double offset) | |||
757 | * and clear reachable bits, but this proved to be too agressive: | 757 | * and clear reachable bits, but this proved to be too agressive: |
758 | * after step (tested with suspending laptop for ~30 secs), | 758 | * after step (tested with suspending laptop for ~30 secs), |
759 | * this caused all previous data to be considered invalid, | 759 | * this caused all previous data to be considered invalid, |
760 | * making us needing to collect full ~8 datapoins per peer | 760 | * making us needing to collect full ~8 datapoints per peer |
761 | * after step in order to start trusting them. | 761 | * after step in order to start trusting them. |
762 | * In turn, this was making poll interval decrease even after | 762 | * In turn, this was making poll interval decrease even after |
763 | * step was done. (Poll interval decreases already before step | 763 | * step was done. (Poll interval decreases already before step |
@@ -800,6 +800,8 @@ resolve_peer_hostname(peer_t *p) | |||
800 | free(p->p_dotted); | 800 | free(p->p_dotted); |
801 | p->p_lsa = lsa; | 801 | p->p_lsa = lsa; |
802 | p->p_dotted = xmalloc_sockaddr2dotted_noport(&lsa->u.sa); | 802 | p->p_dotted = xmalloc_sockaddr2dotted_noport(&lsa->u.sa); |
803 | VERB1 if (strcmp(p->p_hostname, p->p_dotted) != 0) | ||
804 | bb_error_msg("'%s' is %s", p->p_hostname, p->p_dotted); | ||
803 | } else { | 805 | } else { |
804 | /* error message is emitted by host2sockaddr() */ | 806 | /* error message is emitted by host2sockaddr() */ |
805 | set_next(p, HOSTNAME_INTERVAL); | 807 | set_next(p, HOSTNAME_INTERVAL); |
diff --git a/networking/ping.c b/networking/ping.c index d0ef7ba62..ef31e000b 100644 --- a/networking/ping.c +++ b/networking/ping.c | |||
@@ -94,10 +94,10 @@ | |||
94 | //usage: "\n -4,-6 Force IP or IPv6 name resolution" | 94 | //usage: "\n -4,-6 Force IP or IPv6 name resolution" |
95 | //usage: ) | 95 | //usage: ) |
96 | //usage: "\n -c CNT Send only CNT pings" | 96 | //usage: "\n -c CNT Send only CNT pings" |
97 | //usage: "\n -s SIZE Send SIZE data bytes in packets (default:56)" | 97 | //usage: "\n -s SIZE Send SIZE data bytes in packets (default 56)" |
98 | //usage: "\n -t TTL Set TTL" | 98 | //usage: "\n -t TTL Set TTL" |
99 | //usage: "\n -I IFACE/IP Use interface or IP address as source" | 99 | //usage: "\n -I IFACE/IP Source interface or IP address" |
100 | //usage: "\n -W SEC Seconds to wait for the first response (default:10)" | 100 | //usage: "\n -W SEC Seconds to wait for the first response (default 10)" |
101 | //usage: "\n (after all -c CNT packets are sent)" | 101 | //usage: "\n (after all -c CNT packets are sent)" |
102 | //usage: "\n -w SEC Seconds until ping exits (default:infinite)" | 102 | //usage: "\n -w SEC Seconds until ping exits (default:infinite)" |
103 | //usage: "\n (can exit earlier with -c CNT)" | 103 | //usage: "\n (can exit earlier with -c CNT)" |
@@ -110,8 +110,8 @@ | |||
110 | //usage:# define ping6_full_usage "\n\n" | 110 | //usage:# define ping6_full_usage "\n\n" |
111 | //usage: "Send ICMP ECHO_REQUEST packets to network hosts\n" | 111 | //usage: "Send ICMP ECHO_REQUEST packets to network hosts\n" |
112 | //usage: "\n -c CNT Send only CNT pings" | 112 | //usage: "\n -c CNT Send only CNT pings" |
113 | //usage: "\n -s SIZE Send SIZE data bytes in packets (default:56)" | 113 | //usage: "\n -s SIZE Send SIZE data bytes in packets (default 56)" |
114 | //usage: "\n -I IFACE/IP Use interface or IP address as source" | 114 | //usage: "\n -I IFACE/IP Source interface or IP address" |
115 | //usage: "\n -q Quiet, only display output at start" | 115 | //usage: "\n -q Quiet, only display output at start" |
116 | //usage: "\n and when finished" | 116 | //usage: "\n and when finished" |
117 | //usage: "\n -p Pattern to use for payload" | 117 | //usage: "\n -p Pattern to use for payload" |
diff --git a/networking/ssl_client.c b/networking/ssl_client.c new file mode 100644 index 000000000..cfeae1587 --- /dev/null +++ b/networking/ssl_client.c | |||
@@ -0,0 +1,55 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2017 Denys Vlasenko | ||
3 | * | ||
4 | * Licensed under GPLv2, see file LICENSE in this source tree. | ||
5 | */ | ||
6 | //config:config SSL_CLIENT | ||
7 | //config: bool "ssl_client" | ||
8 | //config: default y | ||
9 | //config: select TLS | ||
10 | //config: help | ||
11 | //config: This tool pipes data to/from a socket, TLS-encrypting it. | ||
12 | |||
13 | //applet:IF_SSL_CLIENT(APPLET(ssl_client, BB_DIR_USR_BIN, BB_SUID_DROP)) | ||
14 | |||
15 | //kbuild:lib-$(CONFIG_SSL_CLIENT) += ssl_client.o | ||
16 | |||
17 | //usage:#define ssl_client_trivial_usage | ||
18 | //usage: "-s FD [-r FD] [-n SNI]" | ||
19 | //usage:#define ssl_client_full_usage "" | ||
20 | |||
21 | #include "libbb.h" | ||
22 | |||
23 | int ssl_client_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; | ||
24 | int ssl_client_main(int argc UNUSED_PARAM, char **argv) | ||
25 | { | ||
26 | tls_state_t *tls; | ||
27 | const char *sni = NULL; | ||
28 | int opt; | ||
29 | |||
30 | // INIT_G(); | ||
31 | |||
32 | tls = new_tls_state(); | ||
33 | opt = getopt32(argv, "s:#r:#n:", &tls->ofd, &tls->ifd, &sni); | ||
34 | if (!(opt & 2)) { | ||
35 | /* -r N defaults to -s N */ | ||
36 | tls->ifd = tls->ofd; | ||
37 | } | ||
38 | |||
39 | if (!(opt & 3)) { | ||
40 | if (!argv[1]) | ||
41 | bb_show_usage(); | ||
42 | /* Undocumented debug feature: without -s and -r, takes HOST arg and connects to it */ | ||
43 | // | ||
44 | // Talk to kernel.org: | ||
45 | // printf "GET / HTTP/1.1\r\nHost: kernel.org\r\n\r\n" | ./busybox ssl_client kernel.org | ||
46 | if (!sni) | ||
47 | sni = argv[1]; | ||
48 | tls->ifd = tls->ofd = create_and_connect_stream_or_die(argv[1], 443); | ||
49 | } | ||
50 | |||
51 | tls_handshake(tls, sni); | ||
52 | tls_run_copy_loop(tls); | ||
53 | |||
54 | return EXIT_SUCCESS; | ||
55 | } | ||
diff --git a/networking/tc.c b/networking/tc.c index 25875aa3e..23abf636c 100644 --- a/networking/tc.c +++ b/networking/tc.c | |||
@@ -27,22 +27,22 @@ | |||
27 | /* //usage: "[OPTIONS] OBJECT CMD [dev STRING]" */ | 27 | /* //usage: "[OPTIONS] OBJECT CMD [dev STRING]" */ |
28 | //usage: "OBJECT CMD [dev STRING]" | 28 | //usage: "OBJECT CMD [dev STRING]" |
29 | //usage:#define tc_full_usage "\n\n" | 29 | //usage:#define tc_full_usage "\n\n" |
30 | //usage: "OBJECT: {qdisc|class|filter}\n" | 30 | //usage: "OBJECT: qdisc|class|filter\n" |
31 | //usage: "CMD: {add|del|change|replace|show}\n" | 31 | //usage: "CMD: add|del|change|replace|show\n" |
32 | //usage: "\n" | 32 | //usage: "\n" |
33 | //usage: "qdisc [ handle QHANDLE ] [ root |"IF_FEATURE_TC_INGRESS(" ingress |")" parent CLASSID ]\n" | 33 | //usage: "qdisc [handle QHANDLE] [root|"IF_FEATURE_TC_INGRESS("ingress|")"parent CLASSID]\n" |
34 | /* //usage: "[ estimator INTERVAL TIME_CONSTANT ]\n" */ | 34 | /* //usage: "[estimator INTERVAL TIME_CONSTANT]\n" */ |
35 | //usage: " [ [ QDISC_KIND ] [ help | OPTIONS ] ]\n" | 35 | //usage: " [[QDISC_KIND] [help|OPTIONS]]\n" |
36 | //usage: " QDISC_KIND := { [p|b]fifo | tbf | prio | cbq | red | etc. }\n" | 36 | //usage: " QDISC_KIND := [p|b]fifo|tbf|prio|cbq|red|etc.\n" |
37 | //usage: "qdisc show [ dev STRING ]"IF_FEATURE_TC_INGRESS(" [ingress]")"\n" | 37 | //usage: "qdisc show [dev STRING]"IF_FEATURE_TC_INGRESS(" [ingress]")"\n" |
38 | //usage: "class [ classid CLASSID ] [ root | parent CLASSID ]\n" | 38 | //usage: "class [classid CLASSID] [root|parent CLASSID]\n" |
39 | //usage: " [ [ QDISC_KIND ] [ help | OPTIONS ] ]\n" | 39 | //usage: " [[QDISC_KIND] [help|OPTIONS] ]\n" |
40 | //usage: "class show [ dev STRING ] [ root | parent CLASSID ]\n" | 40 | //usage: "class show [ dev STRING ] [root|parent CLASSID]\n" |
41 | //usage: "filter [ pref PRIO ] [ protocol PROTO ]\n" | 41 | //usage: "filter [pref PRIO] [protocol PROTO]\n" |
42 | /* //usage: "\t[ estimator INTERVAL TIME_CONSTANT ]\n" */ | 42 | /* //usage: "\t[estimator INTERVAL TIME_CONSTANT]\n" */ |
43 | //usage: " [ root | classid CLASSID ] [ handle FILTERID ]\n" | 43 | //usage: " [root|classid CLASSID] [handle FILTERID]\n" |
44 | //usage: " [ [ FILTER_TYPE ] [ help | OPTIONS ] ]\n" | 44 | //usage: " [[FILTER_TYPE] [help|OPTIONS]]\n" |
45 | //usage: "filter show [ dev STRING ] [ root | parent CLASSID ]" | 45 | //usage: "filter show [dev STRING] [root|parent CLASSID]" |
46 | 46 | ||
47 | #include "libbb.h" | 47 | #include "libbb.h" |
48 | #include "common_bufsiz.h" | 48 | #include "common_bufsiz.h" |
diff --git a/networking/telnet.c b/networking/telnet.c index f520fe1dd..a70f74762 100644 --- a/networking/telnet.c +++ b/networking/telnet.c | |||
@@ -45,6 +45,11 @@ | |||
45 | //config: remote host you are connecting to. This is useful when you need to | 45 | //config: remote host you are connecting to. This is useful when you need to |
46 | //config: log into a machine without telling the username (autologin). This | 46 | //config: log into a machine without telling the username (autologin). This |
47 | //config: option enables `-a' and `-l USER' arguments. | 47 | //config: option enables `-a' and `-l USER' arguments. |
48 | //config: | ||
49 | //config:config FEATURE_TELNET_WIDTH | ||
50 | //config: bool "Enable window size autodetection" | ||
51 | //config: default y | ||
52 | //config: depends on TELNET | ||
48 | 53 | ||
49 | //applet:IF_TELNET(APPLET(telnet, BB_DIR_USR_BIN, BB_SUID_DROP)) | 54 | //applet:IF_TELNET(APPLET(telnet, BB_DIR_USR_BIN, BB_SUID_DROP)) |
50 | 55 | ||
@@ -128,7 +133,7 @@ struct globals { | |||
128 | #if ENABLE_FEATURE_TELNET_AUTOLOGIN | 133 | #if ENABLE_FEATURE_TELNET_AUTOLOGIN |
129 | const char *autologin; | 134 | const char *autologin; |
130 | #endif | 135 | #endif |
131 | #if ENABLE_FEATURE_AUTOWIDTH | 136 | #if ENABLE_FEATURE_TELNET_WIDTH |
132 | unsigned win_width, win_height; | 137 | unsigned win_width, win_height; |
133 | #endif | 138 | #endif |
134 | /* same buffer used both for network and console read/write */ | 139 | /* same buffer used both for network and console read/write */ |
@@ -401,7 +406,7 @@ static void put_iac_subopt_autologin(void) | |||
401 | } | 406 | } |
402 | #endif | 407 | #endif |
403 | 408 | ||
404 | #if ENABLE_FEATURE_AUTOWIDTH | 409 | #if ENABLE_FEATURE_TELNET_WIDTH |
405 | static void put_iac_naws(byte c, int x, int y) | 410 | static void put_iac_naws(byte c, int x, int y) |
406 | { | 411 | { |
407 | if (G.iaclen + 9 > IACBUFSIZE) | 412 | if (G.iaclen + 9 > IACBUFSIZE) |
@@ -538,7 +543,7 @@ static void to_new_environ(void) | |||
538 | } | 543 | } |
539 | #endif | 544 | #endif |
540 | 545 | ||
541 | #if ENABLE_FEATURE_AUTOWIDTH | 546 | #if ENABLE_FEATURE_TELNET_WIDTH |
542 | static void to_naws(void) | 547 | static void to_naws(void) |
543 | { | 548 | { |
544 | /* Tell server we will do NAWS */ | 549 | /* Tell server we will do NAWS */ |
@@ -561,7 +566,7 @@ static void telopt(byte c) | |||
561 | case TELOPT_NEW_ENVIRON: | 566 | case TELOPT_NEW_ENVIRON: |
562 | to_new_environ(); break; | 567 | to_new_environ(); break; |
563 | #endif | 568 | #endif |
564 | #if ENABLE_FEATURE_AUTOWIDTH | 569 | #if ENABLE_FEATURE_TELNET_WIDTH |
565 | case TELOPT_NAWS: | 570 | case TELOPT_NAWS: |
566 | to_naws(); | 571 | to_naws(); |
567 | put_iac_naws(c, G.win_width, G.win_height); | 572 | put_iac_naws(c, G.win_width, G.win_height); |
@@ -623,7 +628,7 @@ int telnet_main(int argc UNUSED_PARAM, char **argv) | |||
623 | 628 | ||
624 | INIT_G(); | 629 | INIT_G(); |
625 | 630 | ||
626 | #if ENABLE_FEATURE_AUTOWIDTH | 631 | #if ENABLE_FEATURE_TELNET_WIDTH |
627 | get_terminal_width_height(0, &G.win_width, &G.win_height); | 632 | get_terminal_width_height(0, &G.win_width, &G.win_height); |
628 | #endif | 633 | #endif |
629 | 634 | ||
diff --git a/networking/tftp.c b/networking/tftp.c index ed8672025..189364f0c 100644 --- a/networking/tftp.c +++ b/networking/tftp.c | |||
@@ -69,11 +69,9 @@ | |||
69 | //config: "blksize" and "tsize" options. | 69 | //config: "blksize" and "tsize" options. |
70 | //config: | 70 | //config: |
71 | //config:config FEATURE_TFTP_PROGRESS_BAR | 71 | //config:config FEATURE_TFTP_PROGRESS_BAR |
72 | //config: bool "Enable tftp progress meter" | 72 | //config: bool "Enable progress bar" |
73 | //config: default y | 73 | //config: default y |
74 | //config: depends on TFTP && FEATURE_TFTP_BLOCKSIZE | 74 | //config: depends on TFTP && FEATURE_TFTP_BLOCKSIZE |
75 | //config: help | ||
76 | //config: Show progress bar. | ||
77 | //config: | 75 | //config: |
78 | //config:config TFTP_DEBUG | 76 | //config:config TFTP_DEBUG |
79 | //config: bool "Enable debug" | 77 | //config: bool "Enable debug" |
diff --git a/networking/tls.c b/networking/tls.c new file mode 100644 index 000000000..30afd9ea9 --- /dev/null +++ b/networking/tls.c | |||
@@ -0,0 +1,1815 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2017 Denys Vlasenko | ||
3 | * | ||
4 | * Licensed under GPLv2, see file LICENSE in this source tree. | ||
5 | */ | ||
6 | //config:config TLS | ||
7 | //config: bool #No description makes it a hidden option | ||
8 | //config: default n | ||
9 | |||
10 | //kbuild:lib-$(CONFIG_TLS) += tls.o | ||
11 | //kbuild:lib-$(CONFIG_TLS) += tls_pstm.o | ||
12 | //kbuild:lib-$(CONFIG_TLS) += tls_pstm_montgomery_reduce.o | ||
13 | //kbuild:lib-$(CONFIG_TLS) += tls_pstm_mul_comba.o | ||
14 | //kbuild:lib-$(CONFIG_TLS) += tls_pstm_sqr_comba.o | ||
15 | //kbuild:lib-$(CONFIG_TLS) += tls_rsa.o | ||
16 | //kbuild:lib-$(CONFIG_TLS) += tls_aes.o | ||
17 | ////kbuild:lib-$(CONFIG_TLS) += tls_aes_gcm.o | ||
18 | |||
19 | #include "tls.h" | ||
20 | |||
21 | //Tested against kernel.org: | ||
22 | //TLS 1.2 | ||
23 | #define TLS_MAJ 3 | ||
24 | #define TLS_MIN 3 | ||
25 | //#define CIPHER_ID TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA // ok, recvs SERVER_KEY_EXCHANGE *** matrixssl uses this on my box | ||
26 | //#define CIPHER_ID TLS_RSA_WITH_AES_256_CBC_SHA256 // ok, no SERVER_KEY_EXCHANGE | ||
27 | //#define CIPHER_ID TLS_DH_anon_WITH_AES_256_CBC_SHA // SSL_ALERT_HANDSHAKE_FAILURE | ||
28 | //^^^^^^^^^^^^^^^^^^^^^^^ (tested b/c this one doesn't req server certs... no luck, server refuses it) | ||
29 | //#define CIPHER_ID TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 // SSL_ALERT_HANDSHAKE_FAILURE | ||
30 | //#define CIPHER_ID TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 // SSL_ALERT_HANDSHAKE_FAILURE | ||
31 | //#define CIPHER_ID TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 // ok, recvs SERVER_KEY_EXCHANGE | ||
32 | //#define CIPHER_ID TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 | ||
33 | //#define CIPHER_ID TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384 | ||
34 | //#define CIPHER_ID TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256 // SSL_ALERT_HANDSHAKE_FAILURE | ||
35 | //#define CIPHER_ID TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384 | ||
36 | //#define CIPHER_ID TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256 // SSL_ALERT_HANDSHAKE_FAILURE | ||
37 | //#define CIPHER_ID TLS_RSA_WITH_AES_256_GCM_SHA384 // ok, no SERVER_KEY_EXCHANGE | ||
38 | //#define CIPHER_ID TLS_RSA_WITH_AES_128_GCM_SHA256 // ok, no SERVER_KEY_EXCHANGE *** select this? | ||
39 | |||
40 | // works against "openssl s_server -cipher NULL" | ||
41 | // and against wolfssl-3.9.10-stable/examples/server/server.c: | ||
42 | //#define CIPHER_ID TLS_RSA_WITH_NULL_SHA256 // for testing (does everything except encrypting) | ||
43 | |||
44 | // works against wolfssl-3.9.10-stable/examples/server/server.c | ||
45 | // works for kernel.org | ||
46 | // does not work for cdn.kernel.org (e.g. downloading an actual tarball, not a web page) | ||
47 | // getting alert 40 "handshake failure" at once | ||
48 | // with GNU Wget 1.18, they agree on TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 (0xC02F) cipher | ||
49 | // fail: openssl s_client -connect cdn.kernel.org:443 -debug -tls1_2 -no_tls1 -no_tls1_1 -cipher AES256-SHA256 | ||
50 | // fail: openssl s_client -connect cdn.kernel.org:443 -debug -tls1_2 -no_tls1 -no_tls1_1 -cipher AES256-GCM-SHA384 | ||
51 | // fail: openssl s_client -connect cdn.kernel.org:443 -debug -tls1_2 -no_tls1 -no_tls1_1 -cipher AES128-SHA256 | ||
52 | // ok: openssl s_client -connect cdn.kernel.org:443 -debug -tls1_2 -no_tls1 -no_tls1_1 -cipher AES128-GCM-SHA256 | ||
53 | // ok: openssl s_client -connect cdn.kernel.org:443 -debug -tls1_2 -no_tls1 -no_tls1_1 -cipher AES128-SHA | ||
54 | // (TLS_RSA_WITH_AES_128_CBC_SHA - in TLS 1.2 it's mandated to be always supported) | ||
55 | #define CIPHER_ID1 TLS_RSA_WITH_AES_256_CBC_SHA256 // no SERVER_KEY_EXCHANGE from peer | ||
56 | // Works with "wget https://cdn.kernel.org/pub/linux/kernel/v4.x/linux-4.9.5.tar.xz" | ||
57 | #define CIPHER_ID2 TLS_RSA_WITH_AES_128_CBC_SHA | ||
58 | |||
59 | |||
60 | #define TLS_DEBUG 0 | ||
61 | #define TLS_DEBUG_HASH 0 | ||
62 | #define TLS_DEBUG_DER 0 | ||
63 | #define TLS_DEBUG_FIXED_SECRETS 0 | ||
64 | #if 0 | ||
65 | # define dump_raw_out(...) dump_hex(__VA_ARGS__) | ||
66 | #else | ||
67 | # define dump_raw_out(...) ((void)0) | ||
68 | #endif | ||
69 | #if 0 | ||
70 | # define dump_raw_in(...) dump_hex(__VA_ARGS__) | ||
71 | #else | ||
72 | # define dump_raw_in(...) ((void)0) | ||
73 | #endif | ||
74 | |||
75 | #if TLS_DEBUG | ||
76 | # define dbg(...) fprintf(stderr, __VA_ARGS__) | ||
77 | #else | ||
78 | # define dbg(...) ((void)0) | ||
79 | #endif | ||
80 | |||
81 | #if TLS_DEBUG_DER | ||
82 | # define dbg_der(...) fprintf(stderr, __VA_ARGS__) | ||
83 | #else | ||
84 | # define dbg_der(...) ((void)0) | ||
85 | #endif | ||
86 | |||
87 | #define RECORD_TYPE_CHANGE_CIPHER_SPEC 20 | ||
88 | #define RECORD_TYPE_ALERT 21 | ||
89 | #define RECORD_TYPE_HANDSHAKE 22 | ||
90 | #define RECORD_TYPE_APPLICATION_DATA 23 | ||
91 | |||
92 | #define HANDSHAKE_HELLO_REQUEST 0 | ||
93 | #define HANDSHAKE_CLIENT_HELLO 1 | ||
94 | #define HANDSHAKE_SERVER_HELLO 2 | ||
95 | #define HANDSHAKE_HELLO_VERIFY_REQUEST 3 | ||
96 | #define HANDSHAKE_NEW_SESSION_TICKET 4 | ||
97 | #define HANDSHAKE_CERTIFICATE 11 | ||
98 | #define HANDSHAKE_SERVER_KEY_EXCHANGE 12 | ||
99 | #define HANDSHAKE_CERTIFICATE_REQUEST 13 | ||
100 | #define HANDSHAKE_SERVER_HELLO_DONE 14 | ||
101 | #define HANDSHAKE_CERTIFICATE_VERIFY 15 | ||
102 | #define HANDSHAKE_CLIENT_KEY_EXCHANGE 16 | ||
103 | #define HANDSHAKE_FINISHED 20 | ||
104 | |||
105 | #define SSL_NULL_WITH_NULL_NULL 0x0000 | ||
106 | #define SSL_RSA_WITH_NULL_MD5 0x0001 | ||
107 | #define SSL_RSA_WITH_NULL_SHA 0x0002 | ||
108 | #define SSL_RSA_WITH_RC4_128_MD5 0x0004 | ||
109 | #define SSL_RSA_WITH_RC4_128_SHA 0x0005 | ||
110 | #define SSL_RSA_WITH_3DES_EDE_CBC_SHA 0x000A /* 10 */ | ||
111 | #define TLS_RSA_WITH_AES_128_CBC_SHA 0x002F /* 47 */ | ||
112 | #define TLS_RSA_WITH_AES_256_CBC_SHA 0x0035 /* 53 */ | ||
113 | #define TLS_RSA_WITH_NULL_SHA256 0x003B /* 59 */ | ||
114 | |||
115 | #define TLS_EMPTY_RENEGOTIATION_INFO_SCSV 0x00FF | ||
116 | |||
117 | #define TLS_RSA_WITH_IDEA_CBC_SHA 0x0007 /* 7 */ | ||
118 | #define SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA 0x0016 /* 22 */ | ||
119 | #define SSL_DH_anon_WITH_RC4_128_MD5 0x0018 /* 24 */ | ||
120 | #define SSL_DH_anon_WITH_3DES_EDE_CBC_SHA 0x001B /* 27 */ | ||
121 | #define TLS_DHE_RSA_WITH_AES_128_CBC_SHA 0x0033 /* 51 */ | ||
122 | #define TLS_DHE_RSA_WITH_AES_256_CBC_SHA 0x0039 /* 57 */ | ||
123 | #define TLS_DHE_RSA_WITH_AES_128_CBC_SHA256 0x0067 /* 103 */ | ||
124 | #define TLS_DHE_RSA_WITH_AES_256_CBC_SHA256 0x006B /* 107 */ | ||
125 | #define TLS_DH_anon_WITH_AES_128_CBC_SHA 0x0034 /* 52 */ | ||
126 | #define TLS_DH_anon_WITH_AES_256_CBC_SHA 0x003A /* 58 */ | ||
127 | #define TLS_RSA_WITH_AES_128_CBC_SHA256 0x003C /* 60 */ | ||
128 | #define TLS_RSA_WITH_AES_256_CBC_SHA256 0x003D /* 61 */ | ||
129 | #define TLS_RSA_WITH_SEED_CBC_SHA 0x0096 /* 150 */ | ||
130 | #define TLS_PSK_WITH_AES_128_CBC_SHA 0x008C /* 140 */ | ||
131 | #define TLS_PSK_WITH_AES_128_CBC_SHA256 0x00AE /* 174 */ | ||
132 | #define TLS_PSK_WITH_AES_256_CBC_SHA384 0x00AF /* 175 */ | ||
133 | #define TLS_PSK_WITH_AES_256_CBC_SHA 0x008D /* 141 */ | ||
134 | #define TLS_DHE_PSK_WITH_AES_128_CBC_SHA 0x0090 /* 144 */ | ||
135 | #define TLS_DHE_PSK_WITH_AES_256_CBC_SHA 0x0091 /* 145 */ | ||
136 | #define TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA 0xC004 /* 49156 */ | ||
137 | #define TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA 0xC005 /* 49157 */ | ||
138 | #define TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA 0xC009 /* 49161 */ | ||
139 | #define TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA 0xC00A /* 49162 */ | ||
140 | #define TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA 0xC012 /* 49170 */ | ||
141 | #define TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA 0xC013 /* 49171 */ | ||
142 | #define TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA 0xC014 /* 49172 */ | ||
143 | #define TLS_ECDH_RSA_WITH_AES_128_CBC_SHA 0xC00E /* 49166 */ | ||
144 | #define TLS_ECDH_RSA_WITH_AES_256_CBC_SHA 0xC00F /* 49167 */ | ||
145 | #define TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 0xC023 /* 49187 */ | ||
146 | #define TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384 0xC024 /* 49188 */ | ||
147 | #define TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256 0xC025 /* 49189 */ | ||
148 | #define TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384 0xC026 /* 49190 */ | ||
149 | #define TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 0xC027 /* 49191 */ | ||
150 | #define TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384 0xC028 /* 49192 */ | ||
151 | #define TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256 0xC029 /* 49193 */ | ||
152 | #define TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384 0xC02A /* 49194 */ | ||
153 | |||
154 | /* RFC 5288 "AES Galois Counter Mode (GCM) Cipher Suites for TLS" */ | ||
155 | #define TLS_RSA_WITH_AES_128_GCM_SHA256 0x009C /* 156 */ | ||
156 | #define TLS_RSA_WITH_AES_256_GCM_SHA384 0x009D /* 157 */ | ||
157 | #define TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 0xC02B /* 49195 */ | ||
158 | #define TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 0xC02C /* 49196 */ | ||
159 | #define TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256 0xC02D /* 49197 */ | ||
160 | #define TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384 0xC02E /* 49198 */ | ||
161 | #define TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 0xC02F /* 49199 */ | ||
162 | #define TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 0xC030 /* 49200 */ | ||
163 | #define TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256 0xC031 /* 49201 */ | ||
164 | #define TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384 0xC032 /* 49202 */ | ||
165 | |||
166 | /* Might go to libbb.h */ | ||
167 | #define TLS_MAX_CRYPTBLOCK_SIZE 16 | ||
168 | #define TLS_MAX_OUTBUF (1 << 14) | ||
169 | |||
170 | enum { | ||
171 | SHA_INSIZE = 64, | ||
172 | SHA1_OUTSIZE = 20, | ||
173 | SHA256_OUTSIZE = 32, | ||
174 | |||
175 | AES_BLOCKSIZE = 16, | ||
176 | AES128_KEYSIZE = 16, | ||
177 | AES256_KEYSIZE = 32, | ||
178 | |||
179 | RSA_PREMASTER_SIZE = 48, | ||
180 | |||
181 | RECHDR_LEN = 5, | ||
182 | |||
183 | /* 8 = 3+5. 3 extra bytes result in record data being 32-bit aligned */ | ||
184 | OUTBUF_PFX = 8 + AES_BLOCKSIZE, /* header + IV */ | ||
185 | OUTBUF_SFX = TLS_MAX_MAC_SIZE + TLS_MAX_CRYPTBLOCK_SIZE, /* MAC + padding */ | ||
186 | |||
187 | // RFC 5246 | ||
188 | // | 6.2.1. Fragmentation | ||
189 | // | The record layer fragments information blocks into TLSPlaintext | ||
190 | // | records carrying data in chunks of 2^14 bytes or less. Client | ||
191 | // | message boundaries are not preserved in the record layer (i.e., | ||
192 | // | multiple client messages of the same ContentType MAY be coalesced | ||
193 | // | into a single TLSPlaintext record, or a single message MAY be | ||
194 | // | fragmented across several records) | ||
195 | // |... | ||
196 | // | length | ||
197 | // | The length (in bytes) of the following TLSPlaintext.fragment. | ||
198 | // | The length MUST NOT exceed 2^14. | ||
199 | // |... | ||
200 | // | 6.2.2. Record Compression and Decompression | ||
201 | // |... | ||
202 | // | Compression must be lossless and may not increase the content length | ||
203 | // | by more than 1024 bytes. If the decompression function encounters a | ||
204 | // | TLSCompressed.fragment that would decompress to a length in excess of | ||
205 | // | 2^14 bytes, it MUST report a fatal decompression failure error. | ||
206 | // |... | ||
207 | // | length | ||
208 | // | The length (in bytes) of the following TLSCompressed.fragment. | ||
209 | // | The length MUST NOT exceed 2^14 + 1024. | ||
210 | // |... | ||
211 | // | 6.2.3. Record Payload Protection | ||
212 | // | The encryption and MAC functions translate a TLSCompressed | ||
213 | // | structure into a TLSCiphertext. The decryption functions reverse | ||
214 | // | the process. The MAC of the record also includes a sequence | ||
215 | // | number so that missing, extra, or repeated messages are | ||
216 | // | detectable. | ||
217 | // |... | ||
218 | // | length | ||
219 | // | The length (in bytes) of the following TLSCiphertext.fragment. | ||
220 | // | The length MUST NOT exceed 2^14 + 2048. | ||
221 | MAX_INBUF = RECHDR_LEN + (1 << 14) + 2048, | ||
222 | }; | ||
223 | |||
224 | struct record_hdr { | ||
225 | uint8_t type; | ||
226 | uint8_t proto_maj, proto_min; | ||
227 | uint8_t len16_hi, len16_lo; | ||
228 | }; | ||
229 | |||
230 | struct tls_handshake_data { | ||
231 | /* In bbox, md5/sha1/sha256 ctx's are the same structure */ | ||
232 | md5sha_ctx_t handshake_hash_ctx; | ||
233 | |||
234 | uint8_t client_and_server_rand32[2 * 32]; | ||
235 | uint8_t master_secret[48]; | ||
236 | //TODO: store just the DER key here, parse/use/delete it when sending client key | ||
237 | //this way it will stay key type agnostic here. | ||
238 | psRsaKey_t server_rsa_pub_key; | ||
239 | |||
240 | unsigned saved_client_hello_size; | ||
241 | uint8_t saved_client_hello[1]; | ||
242 | }; | ||
243 | |||
244 | |||
245 | static unsigned get24be(const uint8_t *p) | ||
246 | { | ||
247 | return 0x100*(0x100*p[0] + p[1]) + p[2]; | ||
248 | } | ||
249 | |||
250 | #if TLS_DEBUG | ||
251 | static void dump_hex(const char *fmt, const void *vp, int len) | ||
252 | { | ||
253 | char hexbuf[32 * 1024 + 4]; | ||
254 | const uint8_t *p = vp; | ||
255 | |||
256 | bin2hex(hexbuf, (void*)p, len)[0] = '\0'; | ||
257 | dbg(fmt, hexbuf); | ||
258 | } | ||
259 | |||
260 | static void dump_tls_record(const void *vp, int len) | ||
261 | { | ||
262 | const uint8_t *p = vp; | ||
263 | |||
264 | while (len > 0) { | ||
265 | unsigned xhdr_len; | ||
266 | if (len < RECHDR_LEN) { | ||
267 | dump_hex("< |%s|\n", p, len); | ||
268 | return; | ||
269 | } | ||
270 | xhdr_len = 0x100*p[3] + p[4]; | ||
271 | dbg("< hdr_type:%u ver:%u.%u len:%u", p[0], p[1], p[2], xhdr_len); | ||
272 | p += RECHDR_LEN; | ||
273 | len -= RECHDR_LEN; | ||
274 | if (len >= 4 && p[-RECHDR_LEN] == RECORD_TYPE_HANDSHAKE) { | ||
275 | unsigned len24 = get24be(p + 1); | ||
276 | dbg(" type:%u len24:%u", p[0], len24); | ||
277 | } | ||
278 | if (xhdr_len > len) | ||
279 | xhdr_len = len; | ||
280 | dump_hex(" |%s|\n", p, xhdr_len); | ||
281 | p += xhdr_len; | ||
282 | len -= xhdr_len; | ||
283 | } | ||
284 | } | ||
285 | #else | ||
286 | # define dump_hex(...) ((void)0) | ||
287 | # define dump_tls_record(...) ((void)0) | ||
288 | #endif | ||
289 | |||
290 | void tls_get_random(void *buf, unsigned len) | ||
291 | { | ||
292 | if (len != open_read_close("/dev/urandom", buf, len)) | ||
293 | xfunc_die(); | ||
294 | } | ||
295 | |||
296 | /* Nondestructively see the current hash value */ | ||
297 | static unsigned sha_peek(md5sha_ctx_t *ctx, void *buffer) | ||
298 | { | ||
299 | md5sha_ctx_t ctx_copy = *ctx; /* struct copy */ | ||
300 | return sha_end(&ctx_copy, buffer); | ||
301 | } | ||
302 | |||
303 | static ALWAYS_INLINE unsigned get_handshake_hash(tls_state_t *tls, void *buffer) | ||
304 | { | ||
305 | return sha_peek(&tls->hsd->handshake_hash_ctx, buffer); | ||
306 | } | ||
307 | |||
308 | #if !TLS_DEBUG_HASH | ||
309 | # define hash_handshake(tls, fmt, buffer, len) \ | ||
310 | hash_handshake(tls, buffer, len) | ||
311 | #endif | ||
312 | static void hash_handshake(tls_state_t *tls, const char *fmt, const void *buffer, unsigned len) | ||
313 | { | ||
314 | md5sha_hash(&tls->hsd->handshake_hash_ctx, buffer, len); | ||
315 | #if TLS_DEBUG_HASH | ||
316 | { | ||
317 | uint8_t h[TLS_MAX_MAC_SIZE]; | ||
318 | dump_hex(fmt, buffer, len); | ||
319 | dbg(" (%u bytes) ", (int)len); | ||
320 | len = sha_peek(&tls->hsd->handshake_hash_ctx, h); | ||
321 | if (len == SHA1_OUTSIZE) | ||
322 | dump_hex("sha1:%s\n", h, len); | ||
323 | else | ||
324 | if (len == SHA256_OUTSIZE) | ||
325 | dump_hex("sha256:%s\n", h, len); | ||
326 | else | ||
327 | dump_hex("sha???:%s\n", h, len); | ||
328 | } | ||
329 | #endif | ||
330 | } | ||
331 | |||
332 | // RFC 2104 | ||
333 | // HMAC(key, text) based on a hash H (say, sha256) is: | ||
334 | // ipad = [0x36 x INSIZE] | ||
335 | // opad = [0x5c x INSIZE] | ||
336 | // HMAC(key, text) = H((key XOR opad) + H((key XOR ipad) + text)) | ||
337 | // | ||
338 | // H(key XOR opad) and H(key XOR ipad) can be precomputed | ||
339 | // if we often need HMAC hmac with the same key. | ||
340 | // | ||
341 | // text is often given in disjoint pieces. | ||
342 | typedef struct hmac_precomputed { | ||
343 | md5sha_ctx_t hashed_key_xor_ipad; | ||
344 | md5sha_ctx_t hashed_key_xor_opad; | ||
345 | } hmac_precomputed_t; | ||
346 | |||
347 | static unsigned hmac_sha_precomputed_v( | ||
348 | hmac_precomputed_t *pre, | ||
349 | uint8_t *out, | ||
350 | va_list va) | ||
351 | { | ||
352 | uint8_t *text; | ||
353 | unsigned len; | ||
354 | |||
355 | /* pre->hashed_key_xor_ipad contains unclosed "H((key XOR ipad) +" state */ | ||
356 | /* pre->hashed_key_xor_opad contains unclosed "H((key XOR opad) +" state */ | ||
357 | |||
358 | /* calculate out = H((key XOR ipad) + text) */ | ||
359 | while ((text = va_arg(va, uint8_t*)) != NULL) { | ||
360 | unsigned text_size = va_arg(va, unsigned); | ||
361 | md5sha_hash(&pre->hashed_key_xor_ipad, text, text_size); | ||
362 | } | ||
363 | len = sha_end(&pre->hashed_key_xor_ipad, out); | ||
364 | |||
365 | /* out = H((key XOR opad) + out) */ | ||
366 | md5sha_hash(&pre->hashed_key_xor_opad, out, len); | ||
367 | return sha_end(&pre->hashed_key_xor_opad, out); | ||
368 | } | ||
369 | |||
370 | static void hmac_sha256_begin(hmac_precomputed_t *pre, uint8_t *key, unsigned key_size) | ||
371 | { | ||
372 | uint8_t key_xor_ipad[SHA_INSIZE]; | ||
373 | uint8_t key_xor_opad[SHA_INSIZE]; | ||
374 | uint8_t tempkey[SHA256_OUTSIZE]; | ||
375 | unsigned i; | ||
376 | |||
377 | // "The authentication key can be of any length up to INSIZE, the | ||
378 | // block length of the hash function. Applications that use keys longer | ||
379 | // than INSIZE bytes will first hash the key using H and then use the | ||
380 | // resultant OUTSIZE byte string as the actual key to HMAC." | ||
381 | if (key_size > SHA_INSIZE) { | ||
382 | md5sha_ctx_t ctx; | ||
383 | sha256_begin(&ctx); | ||
384 | md5sha_hash(&ctx, key, key_size); | ||
385 | key_size = sha_end(&ctx, tempkey); | ||
386 | } | ||
387 | |||
388 | for (i = 0; i < key_size; i++) { | ||
389 | key_xor_ipad[i] = key[i] ^ 0x36; | ||
390 | key_xor_opad[i] = key[i] ^ 0x5c; | ||
391 | } | ||
392 | for (; i < SHA_INSIZE; i++) { | ||
393 | key_xor_ipad[i] = 0x36; | ||
394 | key_xor_opad[i] = 0x5c; | ||
395 | } | ||
396 | |||
397 | sha256_begin(&pre->hashed_key_xor_ipad); | ||
398 | sha256_begin(&pre->hashed_key_xor_opad); | ||
399 | md5sha_hash(&pre->hashed_key_xor_ipad, key_xor_ipad, SHA_INSIZE); | ||
400 | md5sha_hash(&pre->hashed_key_xor_opad, key_xor_opad, SHA_INSIZE); | ||
401 | } | ||
402 | // TODO: ^^^ vvv merge? | ||
403 | static void hmac_sha1_begin(hmac_precomputed_t *pre, uint8_t *key, unsigned key_size) | ||
404 | { | ||
405 | uint8_t key_xor_ipad[SHA_INSIZE]; | ||
406 | uint8_t key_xor_opad[SHA_INSIZE]; | ||
407 | uint8_t tempkey[SHA1_OUTSIZE]; | ||
408 | unsigned i; | ||
409 | |||
410 | // "The authentication key can be of any length up to INSIZE, the | ||
411 | // block length of the hash function. Applications that use keys longer | ||
412 | // than INSIZE bytes will first hash the key using H and then use the | ||
413 | // resultant OUTSIZE byte string as the actual key to HMAC." | ||
414 | if (key_size > SHA_INSIZE) { | ||
415 | md5sha_ctx_t ctx; | ||
416 | sha1_begin(&ctx); | ||
417 | md5sha_hash(&ctx, key, key_size); | ||
418 | key_size = sha_end(&ctx, tempkey); | ||
419 | } | ||
420 | |||
421 | for (i = 0; i < key_size; i++) { | ||
422 | key_xor_ipad[i] = key[i] ^ 0x36; | ||
423 | key_xor_opad[i] = key[i] ^ 0x5c; | ||
424 | } | ||
425 | for (; i < SHA_INSIZE; i++) { | ||
426 | key_xor_ipad[i] = 0x36; | ||
427 | key_xor_opad[i] = 0x5c; | ||
428 | } | ||
429 | |||
430 | sha1_begin(&pre->hashed_key_xor_ipad); | ||
431 | sha1_begin(&pre->hashed_key_xor_opad); | ||
432 | md5sha_hash(&pre->hashed_key_xor_ipad, key_xor_ipad, SHA_INSIZE); | ||
433 | md5sha_hash(&pre->hashed_key_xor_opad, key_xor_opad, SHA_INSIZE); | ||
434 | } | ||
435 | |||
436 | static unsigned hmac(tls_state_t *tls, uint8_t *out, uint8_t *key, unsigned key_size, ...) | ||
437 | { | ||
438 | hmac_precomputed_t pre; | ||
439 | va_list va; | ||
440 | unsigned len; | ||
441 | |||
442 | va_start(va, key_size); | ||
443 | |||
444 | if (tls->MAC_size == SHA256_OUTSIZE) | ||
445 | hmac_sha256_begin(&pre, key, key_size); | ||
446 | else | ||
447 | hmac_sha1_begin(&pre, key, key_size); | ||
448 | |||
449 | len = hmac_sha_precomputed_v(&pre, out, va); | ||
450 | |||
451 | va_end(va); | ||
452 | return len; | ||
453 | } | ||
454 | |||
455 | static unsigned hmac_sha256(/*tls_state_t *tls,*/ uint8_t *out, uint8_t *key, unsigned key_size, ...) | ||
456 | { | ||
457 | hmac_precomputed_t pre; | ||
458 | va_list va; | ||
459 | unsigned len; | ||
460 | |||
461 | va_start(va, key_size); | ||
462 | |||
463 | hmac_sha256_begin(&pre, key, key_size); | ||
464 | len = hmac_sha_precomputed_v(&pre, out, va); | ||
465 | |||
466 | va_end(va); | ||
467 | return len; | ||
468 | } | ||
469 | |||
470 | // RFC 5246: | ||
471 | // 5. HMAC and the Pseudorandom Function | ||
472 | //... | ||
473 | // In this section, we define one PRF, based on HMAC. This PRF with the | ||
474 | // SHA-256 hash function is used for all cipher suites defined in this | ||
475 | // document and in TLS documents published prior to this document when | ||
476 | // TLS 1.2 is negotiated. | ||
477 | // ^^^^^^^^^^^^^ IMPORTANT! | ||
478 | // PRF uses sha256 regardless of cipher (at least for all ciphers | ||
479 | // defined by RFC5246). It's not sha1 for AES_128_CBC_SHA! | ||
480 | //... | ||
481 | // P_hash(secret, seed) = HMAC_hash(secret, A(1) + seed) + | ||
482 | // HMAC_hash(secret, A(2) + seed) + | ||
483 | // HMAC_hash(secret, A(3) + seed) + ... | ||
484 | // where + indicates concatenation. | ||
485 | // A() is defined as: | ||
486 | // A(0) = seed | ||
487 | // A(1) = HMAC_hash(secret, A(0)) = HMAC_hash(secret, seed) | ||
488 | // A(i) = HMAC_hash(secret, A(i-1)) | ||
489 | // P_hash can be iterated as many times as necessary to produce the | ||
490 | // required quantity of data. For example, if P_SHA256 is being used to | ||
491 | // create 80 bytes of data, it will have to be iterated three times | ||
492 | // (through A(3)), creating 96 bytes of output data; the last 16 bytes | ||
493 | // of the final iteration will then be discarded, leaving 80 bytes of | ||
494 | // output data. | ||
495 | // | ||
496 | // TLS's PRF is created by applying P_hash to the secret as: | ||
497 | // | ||
498 | // PRF(secret, label, seed) = P_<hash>(secret, label + seed) | ||
499 | // | ||
500 | // The label is an ASCII string. | ||
501 | static void prf_hmac_sha256(/*tls_state_t *tls,*/ | ||
502 | uint8_t *outbuf, unsigned outbuf_size, | ||
503 | uint8_t *secret, unsigned secret_size, | ||
504 | const char *label, | ||
505 | uint8_t *seed, unsigned seed_size) | ||
506 | { | ||
507 | uint8_t a[TLS_MAX_MAC_SIZE]; | ||
508 | uint8_t *out_p = outbuf; | ||
509 | unsigned label_size = strlen(label); | ||
510 | unsigned MAC_size = SHA256_OUTSIZE;///tls->MAC_size; | ||
511 | |||
512 | /* In P_hash() calculation, "seed" is "label + seed": */ | ||
513 | #define SEED label, label_size, seed, seed_size | ||
514 | #define SECRET secret, secret_size | ||
515 | #define A a, MAC_size | ||
516 | |||
517 | /* A(1) = HMAC_hash(secret, seed) */ | ||
518 | hmac_sha256(/*tls,*/ a, SECRET, SEED, NULL); | ||
519 | //TODO: convert hmac to precomputed | ||
520 | |||
521 | for(;;) { | ||
522 | /* HMAC_hash(secret, A(1) + seed) */ | ||
523 | if (outbuf_size <= MAC_size) { | ||
524 | /* Last, possibly incomplete, block */ | ||
525 | /* (use a[] as temp buffer) */ | ||
526 | hmac_sha256(/*tls,*/ a, SECRET, A, SEED, NULL); | ||
527 | memcpy(out_p, a, outbuf_size); | ||
528 | return; | ||
529 | } | ||
530 | /* Not last block. Store directly to result buffer */ | ||
531 | hmac_sha256(/*tls,*/ out_p, SECRET, A, SEED, NULL); | ||
532 | out_p += MAC_size; | ||
533 | outbuf_size -= MAC_size; | ||
534 | /* A(2) = HMAC_hash(secret, A(1)) */ | ||
535 | hmac_sha256(/*tls,*/ a, SECRET, A, NULL); | ||
536 | } | ||
537 | #undef A | ||
538 | #undef SECRET | ||
539 | #undef SEED | ||
540 | } | ||
541 | |||
542 | static void bad_record_die(tls_state_t *tls, const char *expected, int len) | ||
543 | { | ||
544 | bb_error_msg("got bad TLS record (len:%d) while expecting %s", len, expected); | ||
545 | if (len > 0) { | ||
546 | uint8_t *p = tls->inbuf; | ||
547 | while (len > 0) { | ||
548 | fprintf(stderr, " %02x", *p++); | ||
549 | len--; | ||
550 | } | ||
551 | fputc('\n', stderr); | ||
552 | } | ||
553 | xfunc_die(); | ||
554 | } | ||
555 | |||
556 | static void tls_error_die(tls_state_t *tls, int line) | ||
557 | { | ||
558 | dump_tls_record(tls->inbuf, tls->ofs_to_buffered + tls->buffered_size); | ||
559 | bb_error_msg_and_die("tls error at line %d cipher:%04x", line, tls->cipher_id); | ||
560 | } | ||
561 | #define tls_error_die(tls) tls_error_die(tls, __LINE__) | ||
562 | |||
563 | #if 0 //UNUSED | ||
564 | static void tls_free_inbuf(tls_state_t *tls) | ||
565 | { | ||
566 | if (tls->buffered_size == 0) { | ||
567 | free(tls->inbuf); | ||
568 | tls->inbuf_size = 0; | ||
569 | tls->inbuf = NULL; | ||
570 | } | ||
571 | } | ||
572 | #endif | ||
573 | |||
574 | static void tls_free_outbuf(tls_state_t *tls) | ||
575 | { | ||
576 | free(tls->outbuf); | ||
577 | tls->outbuf_size = 0; | ||
578 | tls->outbuf = NULL; | ||
579 | } | ||
580 | |||
581 | static void *tls_get_outbuf(tls_state_t *tls, int len) | ||
582 | { | ||
583 | if (len > TLS_MAX_OUTBUF) | ||
584 | xfunc_die(); | ||
585 | len += OUTBUF_PFX + OUTBUF_SFX; | ||
586 | if (tls->outbuf_size < len) { | ||
587 | tls->outbuf_size = len; | ||
588 | tls->outbuf = xrealloc(tls->outbuf, len); | ||
589 | } | ||
590 | return tls->outbuf + OUTBUF_PFX; | ||
591 | } | ||
592 | |||
593 | static void xwrite_encrypted(tls_state_t *tls, unsigned size, unsigned type) | ||
594 | { | ||
595 | uint8_t *buf = tls->outbuf + OUTBUF_PFX; | ||
596 | struct record_hdr *xhdr; | ||
597 | uint8_t padding_length; | ||
598 | |||
599 | xhdr = (void*)(buf - RECHDR_LEN); | ||
600 | if (tls->cipher_id != TLS_RSA_WITH_NULL_SHA256) | ||
601 | xhdr = (void*)(buf - RECHDR_LEN - AES_BLOCKSIZE); /* place for IV */ | ||
602 | |||
603 | xhdr->type = type; | ||
604 | xhdr->proto_maj = TLS_MAJ; | ||
605 | xhdr->proto_min = TLS_MIN; | ||
606 | /* fake unencrypted record len for MAC calculation */ | ||
607 | xhdr->len16_hi = size >> 8; | ||
608 | xhdr->len16_lo = size & 0xff; | ||
609 | |||
610 | /* Calculate MAC signature */ | ||
611 | hmac(tls, buf + size, /* result */ | ||
612 | tls->client_write_MAC_key, tls->MAC_size, | ||
613 | &tls->write_seq64_be, sizeof(tls->write_seq64_be), | ||
614 | xhdr, RECHDR_LEN, | ||
615 | buf, size, | ||
616 | NULL | ||
617 | ); | ||
618 | tls->write_seq64_be = SWAP_BE64(1 + SWAP_BE64(tls->write_seq64_be)); | ||
619 | |||
620 | size += tls->MAC_size; | ||
621 | |||
622 | // RFC 5246 | ||
623 | // 6.2.3.1. Null or Standard Stream Cipher | ||
624 | // | ||
625 | // Stream ciphers (including BulkCipherAlgorithm.null; see Appendix A.6) | ||
626 | // convert TLSCompressed.fragment structures to and from stream | ||
627 | // TLSCiphertext.fragment structures. | ||
628 | // | ||
629 | // stream-ciphered struct { | ||
630 | // opaque content[TLSCompressed.length]; | ||
631 | // opaque MAC[SecurityParameters.mac_length]; | ||
632 | // } GenericStreamCipher; | ||
633 | // | ||
634 | // The MAC is generated as: | ||
635 | // MAC(MAC_write_key, seq_num + | ||
636 | // TLSCompressed.type + | ||
637 | // TLSCompressed.version + | ||
638 | // TLSCompressed.length + | ||
639 | // TLSCompressed.fragment); | ||
640 | // where "+" denotes concatenation. | ||
641 | // seq_num | ||
642 | // The sequence number for this record. | ||
643 | // MAC | ||
644 | // The MAC algorithm specified by SecurityParameters.mac_algorithm. | ||
645 | // | ||
646 | // Note that the MAC is computed before encryption. The stream cipher | ||
647 | // encrypts the entire block, including the MAC. | ||
648 | //... | ||
649 | // Appendix C. Cipher Suite Definitions | ||
650 | //... | ||
651 | // MAC Algorithm mac_length mac_key_length | ||
652 | // -------- ----------- ---------- -------------- | ||
653 | // SHA HMAC-SHA1 20 20 | ||
654 | // SHA256 HMAC-SHA256 32 32 | ||
655 | if (tls->cipher_id == TLS_RSA_WITH_NULL_SHA256) { | ||
656 | /* No encryption, only signing */ | ||
657 | xhdr->len16_hi = size >> 8; | ||
658 | xhdr->len16_lo = size & 0xff; | ||
659 | dump_raw_out(">> %s\n", xhdr, RECHDR_LEN + size); | ||
660 | xwrite(tls->ofd, xhdr, RECHDR_LEN + size); | ||
661 | dbg("wrote %u bytes (NULL crypt, SHA256 hash)\n", size); | ||
662 | return; | ||
663 | } | ||
664 | |||
665 | // 6.2.3.2. CBC Block Cipher | ||
666 | // For block ciphers (such as 3DES or AES), the encryption and MAC | ||
667 | // functions convert TLSCompressed.fragment structures to and from block | ||
668 | // TLSCiphertext.fragment structures. | ||
669 | // struct { | ||
670 | // opaque IV[SecurityParameters.record_iv_length]; | ||
671 | // block-ciphered struct { | ||
672 | // opaque content[TLSCompressed.length]; | ||
673 | // opaque MAC[SecurityParameters.mac_length]; | ||
674 | // uint8 padding[GenericBlockCipher.padding_length]; | ||
675 | // uint8 padding_length; | ||
676 | // }; | ||
677 | // } GenericBlockCipher; | ||
678 | //... | ||
679 | // IV | ||
680 | // The Initialization Vector (IV) SHOULD be chosen at random, and | ||
681 | // MUST be unpredictable. Note that in versions of TLS prior to 1.1, | ||
682 | // there was no IV field (...). For block ciphers, the IV length is | ||
683 | // of length SecurityParameters.record_iv_length, which is equal to the | ||
684 | // SecurityParameters.block_size. | ||
685 | // padding | ||
686 | // Padding that is added to force the length of the plaintext to be | ||
687 | // an integral multiple of the block cipher's block length. | ||
688 | // padding_length | ||
689 | // The padding length MUST be such that the total size of the | ||
690 | // GenericBlockCipher structure is a multiple of the cipher's block | ||
691 | // length. Legal values range from zero to 255, inclusive. | ||
692 | //... | ||
693 | // Appendix C. Cipher Suite Definitions | ||
694 | //... | ||
695 | // Key IV Block | ||
696 | // Cipher Type Material Size Size | ||
697 | // ------------ ------ -------- ---- ----- | ||
698 | // AES_128_CBC Block 16 16 16 | ||
699 | // AES_256_CBC Block 32 16 16 | ||
700 | |||
701 | /* Fill IV and padding in outbuf */ | ||
702 | tls_get_random(buf - AES_BLOCKSIZE, AES_BLOCKSIZE); /* IV */ | ||
703 | dbg("before crypt: 5 hdr + %u data + %u hash bytes\n", size, tls->MAC_size); | ||
704 | // RFC is talking nonsense: | ||
705 | // "Padding that is added to force the length of the plaintext to be | ||
706 | // an integral multiple of the block cipher's block length." | ||
707 | // WRONG. _padding+padding_length_, not just _padding_, | ||
708 | // pads the data. | ||
709 | // IOW: padding_length is the last byte of padding[] array, | ||
710 | // contrary to what RFC depicts. | ||
711 | // | ||
712 | // What actually happens is that there is always padding. | ||
713 | // If you need one byte to reach BLOCKSIZE, this byte is 0x00. | ||
714 | // If you need two bytes, they are both 0x01. | ||
715 | // If you need three, they are 0x02,0x02,0x02. And so on. | ||
716 | // If you need no bytes to reach BLOCKSIZE, you have to pad a full | ||
717 | // BLOCKSIZE with bytes of value (BLOCKSIZE-1). | ||
718 | // It's ok to have more than minimum padding, but we do minimum. | ||
719 | padding_length = (~size) & (AES_BLOCKSIZE - 1); | ||
720 | do { | ||
721 | buf[size++] = padding_length; /* padding */ | ||
722 | } while ((size & (AES_BLOCKSIZE - 1)) != 0); | ||
723 | |||
724 | /* Encrypt content+MAC+padding in place */ | ||
725 | aes_cbc_encrypt( | ||
726 | tls->client_write_key, tls->key_size, /* selects 128/256 */ | ||
727 | buf - AES_BLOCKSIZE, /* IV */ | ||
728 | buf, size, /* plaintext */ | ||
729 | buf /* ciphertext */ | ||
730 | ); | ||
731 | |||
732 | /* Write out */ | ||
733 | dbg("writing 5 + %u IV + %u encrypted bytes, padding_length:0x%02x\n", | ||
734 | AES_BLOCKSIZE, size, padding_length); | ||
735 | size += AES_BLOCKSIZE; /* + IV */ | ||
736 | xhdr->len16_hi = size >> 8; | ||
737 | xhdr->len16_lo = size & 0xff; | ||
738 | dump_raw_out(">> %s\n", xhdr, RECHDR_LEN + size); | ||
739 | xwrite(tls->ofd, xhdr, RECHDR_LEN + size); | ||
740 | dbg("wrote %u bytes\n", (int)RECHDR_LEN + size); | ||
741 | } | ||
742 | |||
743 | static void xwrite_handshake_record(tls_state_t *tls, unsigned size) | ||
744 | { | ||
745 | //if (!tls->encrypt_on_write) { | ||
746 | uint8_t *buf = tls->outbuf + OUTBUF_PFX; | ||
747 | struct record_hdr *xhdr = (void*)(buf - RECHDR_LEN); | ||
748 | |||
749 | xhdr->type = RECORD_TYPE_HANDSHAKE; | ||
750 | xhdr->proto_maj = TLS_MAJ; | ||
751 | xhdr->proto_min = TLS_MIN; | ||
752 | xhdr->len16_hi = size >> 8; | ||
753 | xhdr->len16_lo = size & 0xff; | ||
754 | dump_raw_out(">> %s\n", xhdr, RECHDR_LEN + size); | ||
755 | xwrite(tls->ofd, xhdr, RECHDR_LEN + size); | ||
756 | dbg("wrote %u bytes\n", (int)RECHDR_LEN + size); | ||
757 | // return; | ||
758 | //} | ||
759 | //xwrite_encrypted(tls, size, RECORD_TYPE_HANDSHAKE); | ||
760 | } | ||
761 | |||
762 | static void xwrite_and_update_handshake_hash(tls_state_t *tls, unsigned size) | ||
763 | { | ||
764 | if (!tls->encrypt_on_write) { | ||
765 | uint8_t *buf; | ||
766 | |||
767 | xwrite_handshake_record(tls, size); | ||
768 | /* Handshake hash does not include record headers */ | ||
769 | buf = tls->outbuf + OUTBUF_PFX; | ||
770 | hash_handshake(tls, ">> hash:%s", buf, size); | ||
771 | return; | ||
772 | } | ||
773 | xwrite_encrypted(tls, size, RECORD_TYPE_HANDSHAKE); | ||
774 | } | ||
775 | |||
776 | static int tls_has_buffered_record(tls_state_t *tls) | ||
777 | { | ||
778 | int buffered = tls->buffered_size; | ||
779 | struct record_hdr *xhdr; | ||
780 | int rec_size; | ||
781 | |||
782 | if (buffered < RECHDR_LEN) | ||
783 | return 0; | ||
784 | xhdr = (void*)(tls->inbuf + tls->ofs_to_buffered); | ||
785 | rec_size = RECHDR_LEN + (0x100 * xhdr->len16_hi + xhdr->len16_lo); | ||
786 | if (buffered < rec_size) | ||
787 | return 0; | ||
788 | return rec_size; | ||
789 | } | ||
790 | |||
791 | static const char *alert_text(int code) | ||
792 | { | ||
793 | switch (code) { | ||
794 | case 20: return "bad MAC"; | ||
795 | case 50: return "decode error"; | ||
796 | case 51: return "decrypt error"; | ||
797 | case 40: return "handshake failure"; | ||
798 | case 112: return "unrecognized name"; | ||
799 | } | ||
800 | return itoa(code); | ||
801 | } | ||
802 | |||
803 | static int tls_xread_record(tls_state_t *tls) | ||
804 | { | ||
805 | struct record_hdr *xhdr; | ||
806 | int sz; | ||
807 | int total; | ||
808 | int target; | ||
809 | |||
810 | again: | ||
811 | dbg("ofs_to_buffered:%u buffered_size:%u\n", tls->ofs_to_buffered, tls->buffered_size); | ||
812 | total = tls->buffered_size; | ||
813 | if (total != 0) { | ||
814 | memmove(tls->inbuf, tls->inbuf + tls->ofs_to_buffered, total); | ||
815 | //dbg("<< remaining at %d [%d] ", tls->ofs_to_buffered, total); | ||
816 | //dump_raw_in("<< %s\n", tls->inbuf, total); | ||
817 | } | ||
818 | errno = 0; | ||
819 | target = MAX_INBUF; | ||
820 | for (;;) { | ||
821 | int rem; | ||
822 | |||
823 | if (total >= RECHDR_LEN && target == MAX_INBUF) { | ||
824 | xhdr = (void*)tls->inbuf; | ||
825 | target = RECHDR_LEN + (0x100 * xhdr->len16_hi + xhdr->len16_lo); | ||
826 | if (target > MAX_INBUF) { | ||
827 | /* malformed input (too long): yell and die */ | ||
828 | tls->buffered_size = 0; | ||
829 | tls->ofs_to_buffered = total; | ||
830 | tls_error_die(tls); | ||
831 | } | ||
832 | /* can also check type/proto_maj/proto_min here */ | ||
833 | dbg("xhdr type:%d ver:%d.%d len:%d\n", | ||
834 | xhdr->type, xhdr->proto_maj, xhdr->proto_min, | ||
835 | 0x100 * xhdr->len16_hi + xhdr->len16_lo | ||
836 | ); | ||
837 | } | ||
838 | /* if total >= target, we have a full packet (and possibly more)... */ | ||
839 | if (total - target >= 0) | ||
840 | break; | ||
841 | /* input buffer is grown only as needed */ | ||
842 | rem = tls->inbuf_size - total; | ||
843 | if (rem == 0) { | ||
844 | tls->inbuf_size += MAX_INBUF / 8; | ||
845 | if (tls->inbuf_size > MAX_INBUF) | ||
846 | tls->inbuf_size = MAX_INBUF; | ||
847 | dbg("inbuf_size:%d\n", tls->inbuf_size); | ||
848 | rem = tls->inbuf_size - total; | ||
849 | tls->inbuf = xrealloc(tls->inbuf, tls->inbuf_size); | ||
850 | } | ||
851 | sz = safe_read(tls->ifd, tls->inbuf + total, rem); | ||
852 | if (sz <= 0) { | ||
853 | if (sz == 0 && total == 0) { | ||
854 | /* "Abrupt" EOF, no TLS shutdown (seen from kernel.org) */ | ||
855 | dbg("EOF (without TLS shutdown) from peer\n"); | ||
856 | tls->buffered_size = 0; | ||
857 | goto end; | ||
858 | } | ||
859 | bb_perror_msg_and_die("short read, have only %d", total); | ||
860 | } | ||
861 | dump_raw_in("<< %s\n", tls->inbuf + total, sz); | ||
862 | total += sz; | ||
863 | } | ||
864 | tls->buffered_size = total - target; | ||
865 | tls->ofs_to_buffered = target; | ||
866 | //dbg("<< stashing at %d [%d] ", tls->ofs_to_buffered, tls->buffered_size); | ||
867 | //dump_hex("<< %s\n", tls->inbuf + tls->ofs_to_buffered, tls->buffered_size); | ||
868 | |||
869 | sz = target - RECHDR_LEN; | ||
870 | |||
871 | /* Needs to be decrypted? */ | ||
872 | if (tls->min_encrypted_len_on_read > tls->MAC_size) { | ||
873 | uint8_t *p = tls->inbuf + RECHDR_LEN; | ||
874 | int padding_len; | ||
875 | |||
876 | if (sz & (AES_BLOCKSIZE-1) | ||
877 | || sz < (int)tls->min_encrypted_len_on_read | ||
878 | ) { | ||
879 | bb_error_msg_and_die("bad encrypted len:%u < %u", | ||
880 | sz, tls->min_encrypted_len_on_read); | ||
881 | } | ||
882 | /* Decrypt content+MAC+padding, moving it over IV in the process */ | ||
883 | sz -= AES_BLOCKSIZE; /* we will overwrite IV now */ | ||
884 | aes_cbc_decrypt( | ||
885 | tls->server_write_key, tls->key_size, /* selects 128/256 */ | ||
886 | p, /* IV */ | ||
887 | p + AES_BLOCKSIZE, sz, /* ciphertext */ | ||
888 | p /* plaintext */ | ||
889 | ); | ||
890 | padding_len = p[sz - 1]; | ||
891 | dbg("encrypted size:%u type:0x%02x padding_length:0x%02x\n", sz, p[0], padding_len); | ||
892 | padding_len++; | ||
893 | sz -= tls->MAC_size + padding_len; /* drop MAC and padding */ | ||
894 | //if (sz < 0) | ||
895 | // bb_error_msg_and_die("bad padding size:%u", padding_len); | ||
896 | } else { | ||
897 | /* if nonzero, then it's TLS_RSA_WITH_NULL_SHA256: drop MAC */ | ||
898 | /* else: no encryption yet on input, subtract zero = NOP */ | ||
899 | sz -= tls->min_encrypted_len_on_read; | ||
900 | } | ||
901 | if (sz < 0) | ||
902 | bb_error_msg_and_die("encrypted data too short"); | ||
903 | |||
904 | //dump_hex("<< %s\n", tls->inbuf, RECHDR_LEN + sz); | ||
905 | |||
906 | xhdr = (void*)tls->inbuf; | ||
907 | if (xhdr->type == RECORD_TYPE_ALERT && sz >= 2) { | ||
908 | uint8_t *p = tls->inbuf + RECHDR_LEN; | ||
909 | dbg("ALERT size:%d level:%d description:%d\n", sz, p[0], p[1]); | ||
910 | if (p[0] == 2) { /* fatal */ | ||
911 | bb_error_msg_and_die("TLS %s from peer (alert code %d): %s", | ||
912 | "error", | ||
913 | p[1], alert_text(p[1]) | ||
914 | ); | ||
915 | } | ||
916 | if (p[0] == 1) { /* warning */ | ||
917 | if (p[1] == 0) { /* "close_notify" warning: it's EOF */ | ||
918 | dbg("EOF (TLS encoded) from peer\n"); | ||
919 | sz = 0; | ||
920 | goto end; | ||
921 | } | ||
922 | //This possibly needs to be cached and shown only if | ||
923 | //a fatal alert follows | ||
924 | // bb_error_msg("TLS %s from peer (alert code %d): %s", | ||
925 | // "warning", | ||
926 | // p[1], alert_text(p[1]) | ||
927 | // ); | ||
928 | /* discard it, get next record */ | ||
929 | goto again; | ||
930 | } | ||
931 | /* p[0] not 1 or 2: not defined in protocol */ | ||
932 | sz = 0; | ||
933 | goto end; | ||
934 | } | ||
935 | |||
936 | /* RFC 5246 is not saying it explicitly, but sha256 hash | ||
937 | * in our FINISHED record must include data of incoming packets too! | ||
938 | */ | ||
939 | if (tls->inbuf[0] == RECORD_TYPE_HANDSHAKE | ||
940 | && tls->MAC_size != 0 /* do we know which hash to use? (server_hello() does not!) */ | ||
941 | ) { | ||
942 | hash_handshake(tls, "<< hash:%s", tls->inbuf + RECHDR_LEN, sz); | ||
943 | } | ||
944 | end: | ||
945 | dbg("got block len:%u\n", sz); | ||
946 | return sz; | ||
947 | } | ||
948 | |||
949 | /* | ||
950 | * DER parsing routines | ||
951 | */ | ||
952 | static unsigned get_der_len(uint8_t **bodyp, uint8_t *der, uint8_t *end) | ||
953 | { | ||
954 | unsigned len, len1; | ||
955 | |||
956 | if (end - der < 2) | ||
957 | xfunc_die(); | ||
958 | // if ((der[0] & 0x1f) == 0x1f) /* not single-byte item code? */ | ||
959 | // xfunc_die(); | ||
960 | |||
961 | len = der[1]; /* maybe it's short len */ | ||
962 | if (len >= 0x80) { | ||
963 | /* no, it's long */ | ||
964 | |||
965 | if (len == 0x80 || end - der < (int)(len - 0x7e)) { | ||
966 | /* 0x80 is "0 bytes of len", invalid DER: must use short len if can */ | ||
967 | /* need 3 or 4 bytes for 81, 82 */ | ||
968 | xfunc_die(); | ||
969 | } | ||
970 | |||
971 | len1 = der[2]; /* if (len == 0x81) it's "ii 81 xx", fetch xx */ | ||
972 | if (len > 0x82) { | ||
973 | /* >0x82 is "3+ bytes of len", should not happen realistically */ | ||
974 | xfunc_die(); | ||
975 | } | ||
976 | if (len == 0x82) { /* it's "ii 82 xx yy" */ | ||
977 | len1 = 0x100*len1 + der[3]; | ||
978 | der += 1; /* skip [yy] */ | ||
979 | } | ||
980 | der += 1; /* skip [xx] */ | ||
981 | len = len1; | ||
982 | // if (len < 0x80) | ||
983 | // xfunc_die(); /* invalid DER: must use short len if can */ | ||
984 | } | ||
985 | der += 2; /* skip [code]+[1byte] */ | ||
986 | |||
987 | if (end - der < (int)len) | ||
988 | xfunc_die(); | ||
989 | *bodyp = der; | ||
990 | |||
991 | return len; | ||
992 | } | ||
993 | |||
994 | static uint8_t *enter_der_item(uint8_t *der, uint8_t **endp) | ||
995 | { | ||
996 | uint8_t *new_der; | ||
997 | unsigned len = get_der_len(&new_der, der, *endp); | ||
998 | dbg_der("entered der @%p:0x%02x len:%u inner_byte @%p:0x%02x\n", der, der[0], len, new_der, new_der[0]); | ||
999 | /* Move "end" position to cover only this item */ | ||
1000 | *endp = new_der + len; | ||
1001 | return new_der; | ||
1002 | } | ||
1003 | |||
1004 | static uint8_t *skip_der_item(uint8_t *der, uint8_t *end) | ||
1005 | { | ||
1006 | uint8_t *new_der; | ||
1007 | unsigned len = get_der_len(&new_der, der, end); | ||
1008 | /* Skip body */ | ||
1009 | new_der += len; | ||
1010 | dbg_der("skipped der 0x%02x, next byte 0x%02x\n", der[0], new_der[0]); | ||
1011 | return new_der; | ||
1012 | } | ||
1013 | |||
1014 | static void der_binary_to_pstm(pstm_int *pstm_n, uint8_t *der, uint8_t *end) | ||
1015 | { | ||
1016 | uint8_t *bin_ptr; | ||
1017 | unsigned len = get_der_len(&bin_ptr, der, end); | ||
1018 | |||
1019 | dbg_der("binary bytes:%u, first:0x%02x\n", len, bin_ptr[0]); | ||
1020 | pstm_init_for_read_unsigned_bin(/*pool:*/ NULL, pstm_n, len); | ||
1021 | pstm_read_unsigned_bin(pstm_n, bin_ptr, len); | ||
1022 | //return bin + len; | ||
1023 | } | ||
1024 | |||
1025 | static void find_key_in_der_cert(tls_state_t *tls, uint8_t *der, int len) | ||
1026 | { | ||
1027 | /* Certificate is a DER-encoded data structure. Each DER element has a length, | ||
1028 | * which makes it easy to skip over large compound elements of any complexity | ||
1029 | * without parsing them. Example: partial decode of kernel.org certificate: | ||
1030 | * SEQ 0x05ac/1452 bytes (Certificate): 308205ac | ||
1031 | * SEQ 0x0494/1172 bytes (tbsCertificate): 30820494 | ||
1032 | * [ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED | 0] 3 bytes: a003 | ||
1033 | * INTEGER (version): 0201 02 | ||
1034 | * INTEGER 0x11 bytes (serialNumber): 0211 00 9f85bf664b0cddafca508679501b2be4 | ||
1035 | * //^^^^^^note: matrixSSL also allows [ASN_CONTEXT_SPECIFIC | ASN_PRIMITIVE | 2] = 0x82 type | ||
1036 | * SEQ 0x0d bytes (signatureAlgo): 300d | ||
1037 | * OID 9 bytes: 0609 2a864886f70d01010b (OID_SHA256_RSA_SIG 42.134.72.134.247.13.1.1.11) | ||
1038 | * NULL: 0500 | ||
1039 | * SEQ 0x5f bytes (issuer): 305f | ||
1040 | * SET 11 bytes: 310b | ||
1041 | * SEQ 9 bytes: 3009 | ||
1042 | * OID 3 bytes: 0603 550406 | ||
1043 | * Printable string "FR": 1302 4652 | ||
1044 | * SET 14 bytes: 310e | ||
1045 | * SEQ 12 bytes: 300c | ||
1046 | * OID 3 bytes: 0603 550408 | ||
1047 | * Printable string "Paris": 1305 5061726973 | ||
1048 | * SET 14 bytes: 310e | ||
1049 | * SEQ 12 bytes: 300c | ||
1050 | * OID 3 bytes: 0603 550407 | ||
1051 | * Printable string "Paris": 1305 5061726973 | ||
1052 | * SET 14 bytes: 310e | ||
1053 | * SEQ 12 bytes: 300c | ||
1054 | * OID 3 bytes: 0603 55040a | ||
1055 | * Printable string "Gandi": 1305 47616e6469 | ||
1056 | * SET 32 bytes: 3120 | ||
1057 | * SEQ 30 bytes: 301e | ||
1058 | * OID 3 bytes: 0603 550403 | ||
1059 | * Printable string "Gandi Standard SSL CA 2": 1317 47616e6469205374616e646172642053534c2043412032 | ||
1060 | * SEQ 30 bytes (validity): 301e | ||
1061 | * TIME "161011000000Z": 170d 3136313031313030303030305a | ||
1062 | * TIME "191011235959Z": 170d 3139313031313233353935395a | ||
1063 | * SEQ 0x5b/91 bytes (subject): 305b //I did not decode this | ||
1064 | * 3121301f060355040b1318446f6d61696e20436f | ||
1065 | * 6e74726f6c2056616c6964617465643121301f06 | ||
1066 | * 0355040b1318506f73697469766553534c204d75 | ||
1067 | * 6c74692d446f6d61696e31133011060355040313 | ||
1068 | * 0a6b65726e656c2e6f7267 | ||
1069 | * SEQ 0x01a2/418 bytes (subjectPublicKeyInfo): 308201a2 | ||
1070 | * SEQ 13 bytes (algorithm): 300d | ||
1071 | * OID 9 bytes: 0609 2a864886f70d010101 (OID_RSA_KEY_ALG 42.134.72.134.247.13.1.1.1) | ||
1072 | * NULL: 0500 | ||
1073 | * BITSTRING 0x018f/399 bytes (publicKey): 0382018f | ||
1074 | * ????: 00 | ||
1075 | * //after the zero byte, it appears key itself uses DER encoding: | ||
1076 | * SEQ 0x018a/394 bytes: 3082018a | ||
1077 | * INTEGER 0x0181/385 bytes (modulus): 02820181 | ||
1078 | * 00b1ab2fc727a3bef76780c9349bf3 | ||
1079 | * ...24 more blocks of 15 bytes each... | ||
1080 | * 90e895291c6bc8693b65 | ||
1081 | * INTEGER 3 bytes (exponent): 0203 010001 | ||
1082 | * [ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED | 0x3] 0x01e5 bytes (X509v3 extensions): a38201e5 | ||
1083 | * SEQ 0x01e1 bytes: 308201e1 | ||
1084 | * ... | ||
1085 | * Certificate is a sequence of three elements: | ||
1086 | * tbsCertificate (SEQ) | ||
1087 | * signatureAlgorithm (AlgorithmIdentifier) | ||
1088 | * signatureValue (BIT STRING) | ||
1089 | * | ||
1090 | * In turn, tbsCertificate is a sequence of: | ||
1091 | * version | ||
1092 | * serialNumber | ||
1093 | * signatureAlgo (AlgorithmIdentifier) | ||
1094 | * issuer (Name, has complex structure) | ||
1095 | * validity (Validity, SEQ of two Times) | ||
1096 | * subject (Name) | ||
1097 | * subjectPublicKeyInfo (SEQ) | ||
1098 | * ... | ||
1099 | * | ||
1100 | * subjectPublicKeyInfo is a sequence of: | ||
1101 | * algorithm (AlgorithmIdentifier) | ||
1102 | * publicKey (BIT STRING) | ||
1103 | * | ||
1104 | * We need Certificate.tbsCertificate.subjectPublicKeyInfo.publicKey | ||
1105 | */ | ||
1106 | uint8_t *end = der + len; | ||
1107 | |||
1108 | /* enter "Certificate" item: [der, end) will be only Cert */ | ||
1109 | der = enter_der_item(der, &end); | ||
1110 | |||
1111 | /* enter "tbsCertificate" item: [der, end) will be only tbsCert */ | ||
1112 | der = enter_der_item(der, &end); | ||
1113 | |||
1114 | /* skip up to subjectPublicKeyInfo */ | ||
1115 | der = skip_der_item(der, end); /* version */ | ||
1116 | der = skip_der_item(der, end); /* serialNumber */ | ||
1117 | der = skip_der_item(der, end); /* signatureAlgo */ | ||
1118 | der = skip_der_item(der, end); /* issuer */ | ||
1119 | der = skip_der_item(der, end); /* validity */ | ||
1120 | der = skip_der_item(der, end); /* subject */ | ||
1121 | |||
1122 | /* enter subjectPublicKeyInfo */ | ||
1123 | der = enter_der_item(der, &end); | ||
1124 | { /* check subjectPublicKeyInfo.algorithm */ | ||
1125 | static const uint8_t expected[] = { | ||
1126 | 0x30,0x0d, // SEQ 13 bytes | ||
1127 | 0x06,0x09, 0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x01, // OID RSA_KEY_ALG 42.134.72.134.247.13.1.1.1 | ||
1128 | //0x05,0x00, // NULL | ||
1129 | }; | ||
1130 | if (memcmp(der, expected, sizeof(expected)) != 0) | ||
1131 | bb_error_msg_and_die("not RSA key"); | ||
1132 | } | ||
1133 | /* skip subjectPublicKeyInfo.algorithm */ | ||
1134 | der = skip_der_item(der, end); | ||
1135 | /* enter subjectPublicKeyInfo.publicKey */ | ||
1136 | // die_if_not_this_der_type(der, end, 0x03); /* must be BITSTRING */ | ||
1137 | der = enter_der_item(der, &end); | ||
1138 | |||
1139 | /* parse RSA key: */ | ||
1140 | //based on getAsnRsaPubKey(), pkcs1ParsePrivBin() is also of note | ||
1141 | dbg("key bytes:%u, first:0x%02x\n", (int)(end - der), der[0]); | ||
1142 | if (end - der < 14) xfunc_die(); | ||
1143 | /* example format: | ||
1144 | * ignore bits: 00 | ||
1145 | * SEQ 0x018a/394 bytes: 3082018a | ||
1146 | * INTEGER 0x0181/385 bytes (modulus): 02820181 XX...XXX | ||
1147 | * INTEGER 3 bytes (exponent): 0203 010001 | ||
1148 | */ | ||
1149 | if (*der != 0) /* "ignore bits", should be 0 */ | ||
1150 | xfunc_die(); | ||
1151 | der++; | ||
1152 | der = enter_der_item(der, &end); /* enter SEQ */ | ||
1153 | /* memset(tls->hsd->server_rsa_pub_key, 0, sizeof(tls->hsd->server_rsa_pub_key)); - already is */ | ||
1154 | der_binary_to_pstm(&tls->hsd->server_rsa_pub_key.N, der, end); /* modulus */ | ||
1155 | der = skip_der_item(der, end); | ||
1156 | der_binary_to_pstm(&tls->hsd->server_rsa_pub_key.e, der, end); /* exponent */ | ||
1157 | tls->hsd->server_rsa_pub_key.size = pstm_unsigned_bin_size(&tls->hsd->server_rsa_pub_key.N); | ||
1158 | dbg("server_rsa_pub_key.size:%d\n", tls->hsd->server_rsa_pub_key.size); | ||
1159 | } | ||
1160 | |||
1161 | /* | ||
1162 | * TLS Handshake routines | ||
1163 | */ | ||
1164 | static int tls_xread_handshake_block(tls_state_t *tls, int min_len) | ||
1165 | { | ||
1166 | struct record_hdr *xhdr; | ||
1167 | int len = tls_xread_record(tls); | ||
1168 | |||
1169 | xhdr = (void*)tls->inbuf; | ||
1170 | if (len < min_len | ||
1171 | || xhdr->type != RECORD_TYPE_HANDSHAKE | ||
1172 | || xhdr->proto_maj != TLS_MAJ | ||
1173 | || xhdr->proto_min != TLS_MIN | ||
1174 | ) { | ||
1175 | bad_record_die(tls, "handshake record", len); | ||
1176 | } | ||
1177 | dbg("got HANDSHAKE\n"); | ||
1178 | return len; | ||
1179 | } | ||
1180 | |||
1181 | static ALWAYS_INLINE void fill_handshake_record_hdr(void *buf, unsigned type, unsigned len) | ||
1182 | { | ||
1183 | struct handshake_hdr { | ||
1184 | uint8_t type; | ||
1185 | uint8_t len24_hi, len24_mid, len24_lo; | ||
1186 | } *h = buf; | ||
1187 | |||
1188 | len -= 4; | ||
1189 | h->type = type; | ||
1190 | h->len24_hi = len >> 16; | ||
1191 | h->len24_mid = len >> 8; | ||
1192 | h->len24_lo = len & 0xff; | ||
1193 | } | ||
1194 | |||
1195 | static void send_client_hello_and_alloc_hsd(tls_state_t *tls, const char *sni) | ||
1196 | { | ||
1197 | struct client_hello { | ||
1198 | uint8_t type; | ||
1199 | uint8_t len24_hi, len24_mid, len24_lo; | ||
1200 | uint8_t proto_maj, proto_min; | ||
1201 | uint8_t rand32[32]; | ||
1202 | uint8_t session_id_len; | ||
1203 | /* uint8_t session_id[]; */ | ||
1204 | uint8_t cipherid_len16_hi, cipherid_len16_lo; | ||
1205 | uint8_t cipherid[2 * (2 + !!CIPHER_ID2)]; /* actually variable */ | ||
1206 | uint8_t comprtypes_len; | ||
1207 | uint8_t comprtypes[1]; /* actually variable */ | ||
1208 | /* Extensions (SNI shown): | ||
1209 | * hi,lo // len of all extensions | ||
1210 | * 00,00 // extension_type: "Server Name" | ||
1211 | * 00,0e // list len (there can be more than one SNI) | ||
1212 | * 00,0c // len of 1st Server Name Indication | ||
1213 | * 00 // name type: host_name | ||
1214 | * 00,09 // name len | ||
1215 | * "localhost" // name | ||
1216 | */ | ||
1217 | // GNU Wget 1.18 to cdn.kernel.org sends these extensions: | ||
1218 | // 0055 | ||
1219 | // 0005 0005 0100000000 - status_request | ||
1220 | // 0000 0013 0011 00 000e 63646e 2e 6b65726e656c 2e 6f7267 - server_name | ||
1221 | // ff01 0001 00 - renegotiation_info | ||
1222 | // 0023 0000 - session_ticket | ||
1223 | // 000a 0008 0006001700180019 - supported_groups | ||
1224 | // 000b 0002 0100 - ec_point_formats | ||
1225 | // 000d 0016 00140401040305010503060106030301030302010203 - signature_algorithms | ||
1226 | }; | ||
1227 | struct client_hello *record; | ||
1228 | int len; | ||
1229 | int sni_len = sni ? strnlen(sni, 127) : 0; | ||
1230 | |||
1231 | len = sizeof(*record); | ||
1232 | if (sni_len) | ||
1233 | len += 11 + strlen(sni); | ||
1234 | record = tls_get_outbuf(tls, len); | ||
1235 | memset(record, 0, len); | ||
1236 | |||
1237 | fill_handshake_record_hdr(record, HANDSHAKE_CLIENT_HELLO, len); | ||
1238 | record->proto_maj = TLS_MAJ; /* the "requested" version of the protocol, */ | ||
1239 | record->proto_min = TLS_MIN; /* can be higher than one in record headers */ | ||
1240 | tls_get_random(record->rand32, sizeof(record->rand32)); | ||
1241 | if (TLS_DEBUG_FIXED_SECRETS) | ||
1242 | memset(record->rand32, 0x11, sizeof(record->rand32)); | ||
1243 | /* record->session_id_len = 0; - already is */ | ||
1244 | |||
1245 | /* record->cipherid_len16_hi = 0; */ | ||
1246 | record->cipherid_len16_lo = sizeof(record->cipherid); | ||
1247 | /* RFC 5746 Renegotiation Indication Extension - some servers will refuse to work with us otherwise */ | ||
1248 | /*record->cipherid[0] = TLS_EMPTY_RENEGOTIATION_INFO_SCSV >> 8; - zero */ | ||
1249 | record->cipherid[1] = TLS_EMPTY_RENEGOTIATION_INFO_SCSV & 0xff; | ||
1250 | if ((CIPHER_ID1 >> 8) != 0) record->cipherid[2] = CIPHER_ID1 >> 8; | ||
1251 | /*************************/ record->cipherid[3] = CIPHER_ID1 & 0xff; | ||
1252 | #if CIPHER_ID2 | ||
1253 | if ((CIPHER_ID2 >> 8) != 0) record->cipherid[4] = CIPHER_ID2 >> 8; | ||
1254 | /*************************/ record->cipherid[5] = CIPHER_ID2 & 0xff; | ||
1255 | #endif | ||
1256 | |||
1257 | record->comprtypes_len = 1; | ||
1258 | /* record->comprtypes[0] = 0; */ | ||
1259 | |||
1260 | if (sni_len) { | ||
1261 | uint8_t *p = (void*)(record + 1); | ||
1262 | //p[0] = 0; // | ||
1263 | p[1] = sni_len + 9; //ext_len | ||
1264 | //p[2] = 0; // | ||
1265 | //p[3] = 0; //extension_type | ||
1266 | //p[4] = 0; // | ||
1267 | p[5] = sni_len + 5; //list len | ||
1268 | //p[6] = 0; // | ||
1269 | p[7] = sni_len + 3; //len of 1st SNI | ||
1270 | //p[8] = 0; //name type | ||
1271 | //p[9] = 0; // | ||
1272 | p[10] = sni_len; //name len | ||
1273 | memcpy(&p[11], sni, sni_len); | ||
1274 | } | ||
1275 | |||
1276 | dbg(">> CLIENT_HELLO\n"); | ||
1277 | /* Can hash it only when we know which MAC hash to use */ | ||
1278 | /*xwrite_and_update_handshake_hash(tls, len); - WRONG! */ | ||
1279 | xwrite_handshake_record(tls, len); | ||
1280 | |||
1281 | tls->hsd = xzalloc(sizeof(*tls->hsd) + len); | ||
1282 | tls->hsd->saved_client_hello_size = len; | ||
1283 | memcpy(tls->hsd->saved_client_hello, record, len); | ||
1284 | memcpy(tls->hsd->client_and_server_rand32, record->rand32, sizeof(record->rand32)); | ||
1285 | } | ||
1286 | |||
1287 | static void get_server_hello(tls_state_t *tls) | ||
1288 | { | ||
1289 | struct server_hello { | ||
1290 | struct record_hdr xhdr; | ||
1291 | uint8_t type; | ||
1292 | uint8_t len24_hi, len24_mid, len24_lo; | ||
1293 | uint8_t proto_maj, proto_min; | ||
1294 | uint8_t rand32[32]; /* first 4 bytes are unix time in BE format */ | ||
1295 | uint8_t session_id_len; | ||
1296 | uint8_t session_id[32]; | ||
1297 | uint8_t cipherid_hi, cipherid_lo; | ||
1298 | uint8_t comprtype; | ||
1299 | /* extensions may follow, but only those which client offered in its Hello */ | ||
1300 | }; | ||
1301 | |||
1302 | struct server_hello *hp; | ||
1303 | uint8_t *cipherid; | ||
1304 | unsigned cipher; | ||
1305 | int len, len24; | ||
1306 | |||
1307 | len = tls_xread_handshake_block(tls, 74 - 32); | ||
1308 | |||
1309 | hp = (void*)tls->inbuf; | ||
1310 | // 74 bytes: | ||
1311 | // 02 000046 03|03 58|78|cf|c1 50|a5|49|ee|7e|29|48|71|fe|97|fa|e8|2d|19|87|72|90|84|9d|37|a3|f0|cb|6f|5f|e3|3c|2f |20 |d8|1a|78|96|52|d6|91|01|24|b3|d6|5b|b7|d0|6c|b3|e1|78|4e|3c|95|de|74|a0|ba|eb|a7|3a|ff|bd|a2|bf |00|9c |00| | ||
1312 | //SvHl len=70 maj.min unixtime^^^ 28randbytes^^^^^^^^^^^^^^^^^^^^^^^^^^^^_^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^_^^^ slen sid32bytes^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cipSel comprSel | ||
1313 | if (hp->type != HANDSHAKE_SERVER_HELLO | ||
1314 | || hp->len24_hi != 0 | ||
1315 | || hp->len24_mid != 0 | ||
1316 | /* hp->len24_lo checked later */ | ||
1317 | || hp->proto_maj != TLS_MAJ | ||
1318 | || hp->proto_min != TLS_MIN | ||
1319 | ) { | ||
1320 | bad_record_die(tls, "'server hello'", len); | ||
1321 | } | ||
1322 | |||
1323 | cipherid = &hp->cipherid_hi; | ||
1324 | len24 = hp->len24_lo; | ||
1325 | if (hp->session_id_len != 32) { | ||
1326 | if (hp->session_id_len != 0) | ||
1327 | bad_record_die(tls, "'server hello'", len); | ||
1328 | |||
1329 | // session_id_len == 0: no session id | ||
1330 | // "The server | ||
1331 | // may return an empty session_id to indicate that the session will | ||
1332 | // not be cached and therefore cannot be resumed." | ||
1333 | cipherid -= 32; | ||
1334 | len24 += 32; /* what len would be if session id would be present */ | ||
1335 | } | ||
1336 | |||
1337 | if (len24 < 70 | ||
1338 | // || cipherid[0] != (CIPHER_ID >> 8) | ||
1339 | // || cipherid[1] != (CIPHER_ID & 0xff) | ||
1340 | // || cipherid[2] != 0 /* comprtype */ | ||
1341 | ) { | ||
1342 | bad_record_die(tls, "'server hello'", len); | ||
1343 | } | ||
1344 | dbg("<< SERVER_HELLO\n"); | ||
1345 | |||
1346 | memcpy(tls->hsd->client_and_server_rand32 + 32, hp->rand32, sizeof(hp->rand32)); | ||
1347 | |||
1348 | tls->cipher_id = cipher = 0x100 * cipherid[0] + cipherid[1]; | ||
1349 | dbg("server chose cipher %04x\n", cipher); | ||
1350 | |||
1351 | if (cipher == TLS_RSA_WITH_AES_128_CBC_SHA) { | ||
1352 | tls->key_size = AES128_KEYSIZE; | ||
1353 | tls->MAC_size = SHA1_OUTSIZE; | ||
1354 | } | ||
1355 | else { /* TLS_RSA_WITH_AES_256_CBC_SHA256 */ | ||
1356 | tls->key_size = AES256_KEYSIZE; | ||
1357 | tls->MAC_size = SHA256_OUTSIZE; | ||
1358 | } | ||
1359 | /* Handshake hash eventually destined to FINISHED record | ||
1360 | * is sha256 regardless of cipher | ||
1361 | * (at least for all ciphers defined by RFC5246). | ||
1362 | * It's not sha1 for AES_128_CBC_SHA - only MAC is sha1, not this hash. | ||
1363 | */ | ||
1364 | sha256_begin(&tls->hsd->handshake_hash_ctx); | ||
1365 | hash_handshake(tls, ">> client hello hash:%s", | ||
1366 | tls->hsd->saved_client_hello, tls->hsd->saved_client_hello_size | ||
1367 | ); | ||
1368 | hash_handshake(tls, "<< server hello hash:%s", | ||
1369 | tls->inbuf + RECHDR_LEN, len | ||
1370 | ); | ||
1371 | } | ||
1372 | |||
1373 | static void get_server_cert(tls_state_t *tls) | ||
1374 | { | ||
1375 | struct record_hdr *xhdr; | ||
1376 | uint8_t *certbuf; | ||
1377 | int len, len1; | ||
1378 | |||
1379 | len = tls_xread_handshake_block(tls, 10); | ||
1380 | |||
1381 | xhdr = (void*)tls->inbuf; | ||
1382 | certbuf = (void*)(xhdr + 1); | ||
1383 | if (certbuf[0] != HANDSHAKE_CERTIFICATE) | ||
1384 | tls_error_die(tls); | ||
1385 | dbg("<< CERTIFICATE\n"); | ||
1386 | // 4392 bytes: | ||
1387 | // 0b 00|11|24 00|11|21 00|05|b0 30|82|05|ac|30|82|04|94|a0|03|02|01|02|02|11|00|9f|85|bf|66|4b|0c|dd|af|ca|50|86|79|50|1b|2b|e4|30|0d... | ||
1388 | //Cert len=4388 ChainLen CertLen^ DER encoded X509 starts here. openssl x509 -in FILE -inform DER -noout -text | ||
1389 | len1 = get24be(certbuf + 1); | ||
1390 | if (len1 > len - 4) tls_error_die(tls); | ||
1391 | len = len1; | ||
1392 | len1 = get24be(certbuf + 4); | ||
1393 | if (len1 > len - 3) tls_error_die(tls); | ||
1394 | len = len1; | ||
1395 | len1 = get24be(certbuf + 7); | ||
1396 | if (len1 > len - 3) tls_error_die(tls); | ||
1397 | len = len1; | ||
1398 | |||
1399 | if (len) | ||
1400 | find_key_in_der_cert(tls, certbuf + 10, len); | ||
1401 | } | ||
1402 | |||
1403 | static void send_empty_client_cert(tls_state_t *tls) | ||
1404 | { | ||
1405 | struct client_empty_cert { | ||
1406 | uint8_t type; | ||
1407 | uint8_t len24_hi, len24_mid, len24_lo; | ||
1408 | uint8_t cert_chain_len24_hi, cert_chain_len24_mid, cert_chain_len24_lo; | ||
1409 | }; | ||
1410 | struct client_empty_cert *record; | ||
1411 | |||
1412 | record = tls_get_outbuf(tls, sizeof(*record)); | ||
1413 | //FIXME: can just memcpy a ready-made one. | ||
1414 | fill_handshake_record_hdr(record, HANDSHAKE_CERTIFICATE, sizeof(*record)); | ||
1415 | record->cert_chain_len24_hi = 0; | ||
1416 | record->cert_chain_len24_mid = 0; | ||
1417 | record->cert_chain_len24_lo = 0; | ||
1418 | |||
1419 | dbg(">> CERTIFICATE\n"); | ||
1420 | xwrite_and_update_handshake_hash(tls, sizeof(*record)); | ||
1421 | } | ||
1422 | |||
1423 | static void send_client_key_exchange(tls_state_t *tls) | ||
1424 | { | ||
1425 | struct client_key_exchange { | ||
1426 | uint8_t type; | ||
1427 | uint8_t len24_hi, len24_mid, len24_lo; | ||
1428 | /* keylen16 exists for RSA (in TLS, not in SSL), but not for some other key types */ | ||
1429 | uint8_t keylen16_hi, keylen16_lo; | ||
1430 | uint8_t key[4 * 1024]; // size?? | ||
1431 | }; | ||
1432 | //FIXME: better size estimate | ||
1433 | struct client_key_exchange *record = tls_get_outbuf(tls, sizeof(*record)); | ||
1434 | uint8_t rsa_premaster[RSA_PREMASTER_SIZE]; | ||
1435 | int len; | ||
1436 | |||
1437 | tls_get_random(rsa_premaster, sizeof(rsa_premaster)); | ||
1438 | if (TLS_DEBUG_FIXED_SECRETS) | ||
1439 | memset(rsa_premaster, 0x44, sizeof(rsa_premaster)); | ||
1440 | // RFC 5246 | ||
1441 | // "Note: The version number in the PreMasterSecret is the version | ||
1442 | // offered by the client in the ClientHello.client_version, not the | ||
1443 | // version negotiated for the connection." | ||
1444 | rsa_premaster[0] = TLS_MAJ; | ||
1445 | rsa_premaster[1] = TLS_MIN; | ||
1446 | dump_hex("premaster:%s\n", rsa_premaster, sizeof(rsa_premaster)); | ||
1447 | len = psRsaEncryptPub(/*pool:*/ NULL, | ||
1448 | /* psRsaKey_t* */ &tls->hsd->server_rsa_pub_key, | ||
1449 | rsa_premaster, /*inlen:*/ sizeof(rsa_premaster), | ||
1450 | record->key, sizeof(record->key), | ||
1451 | data_param_ignored | ||
1452 | ); | ||
1453 | record->keylen16_hi = len >> 8; | ||
1454 | record->keylen16_lo = len & 0xff; | ||
1455 | len += 2; | ||
1456 | record->type = HANDSHAKE_CLIENT_KEY_EXCHANGE; | ||
1457 | record->len24_hi = 0; | ||
1458 | record->len24_mid = len >> 8; | ||
1459 | record->len24_lo = len & 0xff; | ||
1460 | len += 4; | ||
1461 | |||
1462 | dbg(">> CLIENT_KEY_EXCHANGE\n"); | ||
1463 | xwrite_and_update_handshake_hash(tls, len); | ||
1464 | |||
1465 | // RFC 5246 | ||
1466 | // For all key exchange methods, the same algorithm is used to convert | ||
1467 | // the pre_master_secret into the master_secret. The pre_master_secret | ||
1468 | // should be deleted from memory once the master_secret has been | ||
1469 | // computed. | ||
1470 | // master_secret = PRF(pre_master_secret, "master secret", | ||
1471 | // ClientHello.random + ServerHello.random) | ||
1472 | // [0..47]; | ||
1473 | // The master secret is always exactly 48 bytes in length. The length | ||
1474 | // of the premaster secret will vary depending on key exchange method. | ||
1475 | prf_hmac_sha256(/*tls,*/ | ||
1476 | tls->hsd->master_secret, sizeof(tls->hsd->master_secret), | ||
1477 | rsa_premaster, sizeof(rsa_premaster), | ||
1478 | "master secret", | ||
1479 | tls->hsd->client_and_server_rand32, sizeof(tls->hsd->client_and_server_rand32) | ||
1480 | ); | ||
1481 | dump_hex("master secret:%s\n", tls->hsd->master_secret, sizeof(tls->hsd->master_secret)); | ||
1482 | |||
1483 | // RFC 5246 | ||
1484 | // 6.3. Key Calculation | ||
1485 | // | ||
1486 | // The Record Protocol requires an algorithm to generate keys required | ||
1487 | // by the current connection state (see Appendix A.6) from the security | ||
1488 | // parameters provided by the handshake protocol. | ||
1489 | // | ||
1490 | // The master secret is expanded into a sequence of secure bytes, which | ||
1491 | // is then split to a client write MAC key, a server write MAC key, a | ||
1492 | // client write encryption key, and a server write encryption key. Each | ||
1493 | // of these is generated from the byte sequence in that order. Unused | ||
1494 | // values are empty. Some AEAD ciphers may additionally require a | ||
1495 | // client write IV and a server write IV (see Section 6.2.3.3). | ||
1496 | // | ||
1497 | // When keys and MAC keys are generated, the master secret is used as an | ||
1498 | // entropy source. | ||
1499 | // | ||
1500 | // To generate the key material, compute | ||
1501 | // | ||
1502 | // key_block = PRF(SecurityParameters.master_secret, | ||
1503 | // "key expansion", | ||
1504 | // SecurityParameters.server_random + | ||
1505 | // SecurityParameters.client_random); | ||
1506 | // | ||
1507 | // until enough output has been generated. Then, the key_block is | ||
1508 | // partitioned as follows: | ||
1509 | // | ||
1510 | // client_write_MAC_key[SecurityParameters.mac_key_length] | ||
1511 | // server_write_MAC_key[SecurityParameters.mac_key_length] | ||
1512 | // client_write_key[SecurityParameters.enc_key_length] | ||
1513 | // server_write_key[SecurityParameters.enc_key_length] | ||
1514 | // client_write_IV[SecurityParameters.fixed_iv_length] | ||
1515 | // server_write_IV[SecurityParameters.fixed_iv_length] | ||
1516 | { | ||
1517 | uint8_t tmp64[64]; | ||
1518 | |||
1519 | /* make "server_rand32 + client_rand32" */ | ||
1520 | memcpy(&tmp64[0] , &tls->hsd->client_and_server_rand32[32], 32); | ||
1521 | memcpy(&tmp64[32], &tls->hsd->client_and_server_rand32[0] , 32); | ||
1522 | |||
1523 | prf_hmac_sha256(/*tls,*/ | ||
1524 | tls->client_write_MAC_key, 2 * (tls->MAC_size + tls->key_size), | ||
1525 | // also fills: | ||
1526 | // server_write_MAC_key[] | ||
1527 | // client_write_key[] | ||
1528 | // server_write_key[] | ||
1529 | tls->hsd->master_secret, sizeof(tls->hsd->master_secret), | ||
1530 | "key expansion", | ||
1531 | tmp64, 64 | ||
1532 | ); | ||
1533 | tls->client_write_key = tls->client_write_MAC_key + (2 * tls->MAC_size); | ||
1534 | tls->server_write_key = tls->client_write_key + tls->key_size; | ||
1535 | dump_hex("client_write_MAC_key:%s\n", | ||
1536 | tls->client_write_MAC_key, tls->MAC_size | ||
1537 | ); | ||
1538 | dump_hex("client_write_key:%s\n", | ||
1539 | tls->client_write_key, tls->key_size | ||
1540 | ); | ||
1541 | } | ||
1542 | } | ||
1543 | |||
1544 | static const uint8_t rec_CHANGE_CIPHER_SPEC[] = { | ||
1545 | RECORD_TYPE_CHANGE_CIPHER_SPEC, TLS_MAJ, TLS_MIN, 00, 01, | ||
1546 | 01 | ||
1547 | }; | ||
1548 | |||
1549 | static void send_change_cipher_spec(tls_state_t *tls) | ||
1550 | { | ||
1551 | dbg(">> CHANGE_CIPHER_SPEC\n"); | ||
1552 | xwrite(tls->ofd, rec_CHANGE_CIPHER_SPEC, sizeof(rec_CHANGE_CIPHER_SPEC)); | ||
1553 | } | ||
1554 | |||
1555 | // 7.4.9. Finished | ||
1556 | // A Finished message is always sent immediately after a change | ||
1557 | // cipher spec message to verify that the key exchange and | ||
1558 | // authentication processes were successful. It is essential that a | ||
1559 | // change cipher spec message be received between the other handshake | ||
1560 | // messages and the Finished message. | ||
1561 | //... | ||
1562 | // The Finished message is the first one protected with the just | ||
1563 | // negotiated algorithms, keys, and secrets. Recipients of Finished | ||
1564 | // messages MUST verify that the contents are correct. Once a side | ||
1565 | // has sent its Finished message and received and validated the | ||
1566 | // Finished message from its peer, it may begin to send and receive | ||
1567 | // application data over the connection. | ||
1568 | //... | ||
1569 | // struct { | ||
1570 | // opaque verify_data[verify_data_length]; | ||
1571 | // } Finished; | ||
1572 | // | ||
1573 | // verify_data | ||
1574 | // PRF(master_secret, finished_label, Hash(handshake_messages)) | ||
1575 | // [0..verify_data_length-1]; | ||
1576 | // | ||
1577 | // finished_label | ||
1578 | // For Finished messages sent by the client, the string | ||
1579 | // "client finished". For Finished messages sent by the server, | ||
1580 | // the string "server finished". | ||
1581 | // | ||
1582 | // Hash denotes a Hash of the handshake messages. For the PRF | ||
1583 | // defined in Section 5, the Hash MUST be the Hash used as the basis | ||
1584 | // for the PRF. Any cipher suite which defines a different PRF MUST | ||
1585 | // also define the Hash to use in the Finished computation. | ||
1586 | // | ||
1587 | // In previous versions of TLS, the verify_data was always 12 octets | ||
1588 | // long. In the current version of TLS, it depends on the cipher | ||
1589 | // suite. Any cipher suite which does not explicitly specify | ||
1590 | // verify_data_length has a verify_data_length equal to 12. This | ||
1591 | // includes all existing cipher suites. | ||
1592 | static void send_client_finished(tls_state_t *tls) | ||
1593 | { | ||
1594 | struct finished { | ||
1595 | uint8_t type; | ||
1596 | uint8_t len24_hi, len24_mid, len24_lo; | ||
1597 | uint8_t prf_result[12]; | ||
1598 | }; | ||
1599 | struct finished *record = tls_get_outbuf(tls, sizeof(*record)); | ||
1600 | uint8_t handshake_hash[TLS_MAX_MAC_SIZE]; | ||
1601 | unsigned len; | ||
1602 | |||
1603 | fill_handshake_record_hdr(record, HANDSHAKE_FINISHED, sizeof(*record)); | ||
1604 | |||
1605 | len = get_handshake_hash(tls, handshake_hash); | ||
1606 | prf_hmac_sha256(/*tls,*/ | ||
1607 | record->prf_result, sizeof(record->prf_result), | ||
1608 | tls->hsd->master_secret, sizeof(tls->hsd->master_secret), | ||
1609 | "client finished", | ||
1610 | handshake_hash, len | ||
1611 | ); | ||
1612 | dump_hex("from secret: %s\n", tls->hsd->master_secret, sizeof(tls->hsd->master_secret)); | ||
1613 | dump_hex("from labelSeed: %s", "client finished", sizeof("client finished")-1); | ||
1614 | dump_hex("%s\n", handshake_hash, sizeof(handshake_hash)); | ||
1615 | dump_hex("=> digest: %s\n", record->prf_result, sizeof(record->prf_result)); | ||
1616 | |||
1617 | dbg(">> FINISHED\n"); | ||
1618 | xwrite_encrypted(tls, sizeof(*record), RECORD_TYPE_HANDSHAKE); | ||
1619 | } | ||
1620 | |||
1621 | void FAST_FUNC tls_handshake(tls_state_t *tls, const char *sni) | ||
1622 | { | ||
1623 | // Client RFC 5246 Server | ||
1624 | // (*) - optional messages, not always sent | ||
1625 | // | ||
1626 | // ClientHello -------> | ||
1627 | // ServerHello | ||
1628 | // Certificate* | ||
1629 | // ServerKeyExchange* | ||
1630 | // CertificateRequest* | ||
1631 | // <------- ServerHelloDone | ||
1632 | // Certificate* | ||
1633 | // ClientKeyExchange | ||
1634 | // CertificateVerify* | ||
1635 | // [ChangeCipherSpec] | ||
1636 | // Finished -------> | ||
1637 | // [ChangeCipherSpec] | ||
1638 | // <------- Finished | ||
1639 | // Application Data <------> Application Data | ||
1640 | int len; | ||
1641 | |||
1642 | send_client_hello_and_alloc_hsd(tls, sni); | ||
1643 | get_server_hello(tls); | ||
1644 | |||
1645 | // RFC 5246 | ||
1646 | // The server MUST send a Certificate message whenever the agreed- | ||
1647 | // upon key exchange method uses certificates for authentication | ||
1648 | // (this includes all key exchange methods defined in this document | ||
1649 | // except DH_anon). This message will always immediately follow the | ||
1650 | // ServerHello message. | ||
1651 | // | ||
1652 | // IOW: in practice, Certificate *always* follows. | ||
1653 | // (for example, kernel.org does not even accept DH_anon cipher id) | ||
1654 | get_server_cert(tls); | ||
1655 | |||
1656 | len = tls_xread_handshake_block(tls, 4); | ||
1657 | if (tls->inbuf[RECHDR_LEN] == HANDSHAKE_SERVER_KEY_EXCHANGE) { | ||
1658 | // 459 bytes: | ||
1659 | // 0c 00|01|c7 03|00|17|41|04|87|94|2e|2f|68|d0|c9|f4|97|a8|2d|ef|ed|67|ea|c6|f3|b3|56|47|5d|27|b6|bd|ee|70|25|30|5e|b0|8e|f6|21|5a... | ||
1660 | //SvKey len=455^ | ||
1661 | // with TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA: 461 bytes: | ||
1662 | // 0c 00|01|c9 03|00|17|41|04|cd|9b|b4|29|1f|f6|b0|c2|84|82|7f|29|6a|47|4e|ec|87|0b|c1|9c|69|e1|f8|c6|d0|53|e9|27|90|a5|c8|02|15|75... | ||
1663 | dbg("<< SERVER_KEY_EXCHANGE len:%u\n", len); | ||
1664 | //probably need to save it | ||
1665 | len = tls_xread_handshake_block(tls, 4); | ||
1666 | } | ||
1667 | |||
1668 | if (tls->inbuf[RECHDR_LEN] == HANDSHAKE_CERTIFICATE_REQUEST) { | ||
1669 | dbg("<< CERTIFICATE_REQUEST\n"); | ||
1670 | // RFC 5246: "If no suitable certificate is available, | ||
1671 | // the client MUST send a certificate message containing no | ||
1672 | // certificates. That is, the certificate_list structure has a | ||
1673 | // length of zero. ... | ||
1674 | // Client certificates are sent using the Certificate structure | ||
1675 | // defined in Section 7.4.2." | ||
1676 | // (i.e. the same format as server certs) | ||
1677 | send_empty_client_cert(tls); | ||
1678 | len = tls_xread_handshake_block(tls, 4); | ||
1679 | } | ||
1680 | |||
1681 | if (tls->inbuf[RECHDR_LEN] != HANDSHAKE_SERVER_HELLO_DONE) { | ||
1682 | bad_record_die(tls, "'server hello done'", len); | ||
1683 | } | ||
1684 | // 0e 000000 (len:0) | ||
1685 | dbg("<< SERVER_HELLO_DONE\n"); | ||
1686 | |||
1687 | send_client_key_exchange(tls); | ||
1688 | |||
1689 | send_change_cipher_spec(tls); | ||
1690 | /* from now on we should send encrypted */ | ||
1691 | /* tls->write_seq64_be = 0; - already is */ | ||
1692 | tls->encrypt_on_write = 1; | ||
1693 | |||
1694 | send_client_finished(tls); | ||
1695 | |||
1696 | /* Get CHANGE_CIPHER_SPEC */ | ||
1697 | len = tls_xread_record(tls); | ||
1698 | if (len != 1 || memcmp(tls->inbuf, rec_CHANGE_CIPHER_SPEC, 6) != 0) | ||
1699 | bad_record_die(tls, "switch to encrypted traffic", len); | ||
1700 | dbg("<< CHANGE_CIPHER_SPEC\n"); | ||
1701 | if (tls->cipher_id == TLS_RSA_WITH_NULL_SHA256) | ||
1702 | tls->min_encrypted_len_on_read = tls->MAC_size; | ||
1703 | else { | ||
1704 | unsigned mac_blocks = (unsigned)(tls->MAC_size + AES_BLOCKSIZE-1) / AES_BLOCKSIZE; | ||
1705 | /* all incoming packets now should be encrypted and have | ||
1706 | * at least IV + (MAC padded to blocksize): | ||
1707 | */ | ||
1708 | tls->min_encrypted_len_on_read = AES_BLOCKSIZE + (mac_blocks * AES_BLOCKSIZE); | ||
1709 | dbg("min_encrypted_len_on_read: %u", tls->min_encrypted_len_on_read); | ||
1710 | } | ||
1711 | |||
1712 | /* Get (encrypted) FINISHED from the server */ | ||
1713 | len = tls_xread_record(tls); | ||
1714 | if (len < 4 || tls->inbuf[RECHDR_LEN] != HANDSHAKE_FINISHED) | ||
1715 | tls_error_die(tls); | ||
1716 | dbg("<< FINISHED\n"); | ||
1717 | /* application data can be sent/received */ | ||
1718 | |||
1719 | /* free handshake data */ | ||
1720 | // if (PARANOIA) | ||
1721 | // memset(tls->hsd, 0, tls->hsd->hsd_size); | ||
1722 | free(tls->hsd); | ||
1723 | tls->hsd = NULL; | ||
1724 | } | ||
1725 | |||
1726 | static void tls_xwrite(tls_state_t *tls, int len) | ||
1727 | { | ||
1728 | dbg(">> DATA\n"); | ||
1729 | xwrite_encrypted(tls, len, RECORD_TYPE_APPLICATION_DATA); | ||
1730 | } | ||
1731 | |||
1732 | // To run a test server using openssl: | ||
1733 | // openssl req -x509 -newkey rsa:$((4096/4*3)) -keyout key.pem -out server.pem -nodes -days 99999 -subj '/CN=localhost' | ||
1734 | // openssl s_server -key key.pem -cert server.pem -debug -tls1_2 -no_tls1 -no_tls1_1 | ||
1735 | // | ||
1736 | // Unencryped SHA256 example: | ||
1737 | // openssl req -x509 -newkey rsa:$((4096/4*3)) -keyout key.pem -out server.pem -nodes -days 99999 -subj '/CN=localhost' | ||
1738 | // openssl s_server -key key.pem -cert server.pem -debug -tls1_2 -no_tls1 -no_tls1_1 -cipher NULL | ||
1739 | // openssl s_client -connect 127.0.0.1:4433 -debug -tls1_2 -no_tls1 -no_tls1_1 -cipher NULL-SHA256 | ||
1740 | |||
1741 | void FAST_FUNC tls_run_copy_loop(tls_state_t *tls) | ||
1742 | { | ||
1743 | fd_set readfds; | ||
1744 | int inbuf_size; | ||
1745 | const int INBUF_STEP = 4 * 1024; | ||
1746 | |||
1747 | //TODO: convert to poll | ||
1748 | /* Select loop copying stdin to ofd, and ifd to stdout */ | ||
1749 | FD_ZERO(&readfds); | ||
1750 | FD_SET(tls->ifd, &readfds); | ||
1751 | FD_SET(STDIN_FILENO, &readfds); | ||
1752 | |||
1753 | inbuf_size = INBUF_STEP; | ||
1754 | for (;;) { | ||
1755 | fd_set testfds; | ||
1756 | int nread; | ||
1757 | |||
1758 | testfds = readfds; | ||
1759 | if (select(tls->ifd + 1, &testfds, NULL, NULL, NULL) < 0) | ||
1760 | bb_perror_msg_and_die("select"); | ||
1761 | |||
1762 | if (FD_ISSET(STDIN_FILENO, &testfds)) { | ||
1763 | void *buf; | ||
1764 | |||
1765 | dbg("STDIN HAS DATA\n"); | ||
1766 | buf = tls_get_outbuf(tls, inbuf_size); | ||
1767 | nread = safe_read(STDIN_FILENO, buf, inbuf_size); | ||
1768 | if (nread < 1) { | ||
1769 | /* We'd want to do this: */ | ||
1770 | /* Close outgoing half-connection so they get EOF, | ||
1771 | * but leave incoming alone so we can see response | ||
1772 | */ | ||
1773 | //shutdown(tls->ofd, SHUT_WR); | ||
1774 | /* But TLS has no way to encode this, | ||
1775 | * doubt it's ok to do it "raw" | ||
1776 | */ | ||
1777 | FD_CLR(STDIN_FILENO, &readfds); | ||
1778 | tls_free_outbuf(tls); /* mem usage optimization */ | ||
1779 | } else { | ||
1780 | if (nread == inbuf_size) { | ||
1781 | /* TLS has per record overhead, if input comes fast, | ||
1782 | * read, encrypt and send bigger chunks | ||
1783 | */ | ||
1784 | inbuf_size += INBUF_STEP; | ||
1785 | if (inbuf_size > TLS_MAX_OUTBUF) | ||
1786 | inbuf_size = TLS_MAX_OUTBUF; | ||
1787 | } | ||
1788 | tls_xwrite(tls, nread); | ||
1789 | } | ||
1790 | } | ||
1791 | if (FD_ISSET(tls->ifd, &testfds)) { | ||
1792 | dbg("NETWORK HAS DATA\n"); | ||
1793 | read_record: | ||
1794 | nread = tls_xread_record(tls); | ||
1795 | if (nread < 1) { | ||
1796 | /* TLS protocol has no real concept of one-sided shutdowns: | ||
1797 | * if we get "TLS EOF" from the peer, writes will fail too | ||
1798 | */ | ||
1799 | //FD_CLR(tls->ifd, &readfds); | ||
1800 | //close(STDOUT_FILENO); | ||
1801 | //tls_free_inbuf(tls); /* mem usage optimization */ | ||
1802 | //continue; | ||
1803 | break; | ||
1804 | } | ||
1805 | if (tls->inbuf[0] != RECORD_TYPE_APPLICATION_DATA) | ||
1806 | bb_error_msg_and_die("unexpected record type %d", tls->inbuf[0]); | ||
1807 | xwrite(STDOUT_FILENO, tls->inbuf + RECHDR_LEN, nread); | ||
1808 | /* We may already have a complete next record buffered, | ||
1809 | * can process it without network reads (and possible blocking) | ||
1810 | */ | ||
1811 | if (tls_has_buffered_record(tls)) | ||
1812 | goto read_record; | ||
1813 | } | ||
1814 | } | ||
1815 | } | ||
diff --git a/networking/tls.h b/networking/tls.h new file mode 100644 index 000000000..d487f3810 --- /dev/null +++ b/networking/tls.h | |||
@@ -0,0 +1,99 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2017 Denys Vlasenko | ||
3 | * | ||
4 | * Licensed under GPLv2, see file LICENSE in this source tree. | ||
5 | */ | ||
6 | /* Interface glue between bbox code and minimally tweaked matrixssl | ||
7 | * code. All C files (matrixssl and bbox (ones which need TLS)) | ||
8 | * include this file, and guaranteed to see a consistent API, | ||
9 | * defines, types, etc. | ||
10 | */ | ||
11 | #include "libbb.h" | ||
12 | |||
13 | |||
14 | /* Config tweaks */ | ||
15 | #define HAVE_NATIVE_INT64 | ||
16 | #undef USE_1024_KEY_SPEED_OPTIMIZATIONS | ||
17 | #undef USE_2048_KEY_SPEED_OPTIMIZATIONS | ||
18 | #define USE_AES | ||
19 | #undef USE_AES_CBC_EXTERNAL | ||
20 | #undef USE_AES_CCM | ||
21 | #undef USE_AES_GCM | ||
22 | #undef USE_3DES | ||
23 | #undef USE_ARC4 | ||
24 | #undef USE_IDEA | ||
25 | #undef USE_RC2 | ||
26 | #undef USE_SEED | ||
27 | /* pstm: multiprecision numbers */ | ||
28 | #undef DISABLE_PSTM | ||
29 | #if defined(__GNUC__) && defined(__i386__) | ||
30 | /* PSTM_X86 works correctly. +25 bytes. */ | ||
31 | # define PSTM_32BIT | ||
32 | # define PSTM_X86 | ||
33 | #endif | ||
34 | //#if defined(__GNUC__) && defined(__x86_64__) | ||
35 | // /* PSTM_X86_64 works correctly, but +782 bytes. */ | ||
36 | // /* Looks like most of the growth is because of PSTM_64BIT. */ | ||
37 | //# define PSTM_64BIT | ||
38 | //# define PSTM_X86_64 | ||
39 | //#endif | ||
40 | //#if SOME_COND #define PSTM_MIPS, #define PSTM_32BIT | ||
41 | //#if SOME_COND #define PSTM_ARM, #define PSTM_32BIT | ||
42 | |||
43 | |||
44 | #define PS_SUCCESS 0 | ||
45 | #define PS_FAILURE -1 | ||
46 | #define PS_ARG_FAIL -6 /* Failure due to bad function param */ | ||
47 | #define PS_PLATFORM_FAIL -7 /* Failure as a result of system call error */ | ||
48 | #define PS_MEM_FAIL -8 /* Failure to allocate requested memory */ | ||
49 | #define PS_LIMIT_FAIL -9 /* Failure on sanity/limit tests */ | ||
50 | |||
51 | #define PS_TRUE 1 | ||
52 | #define PS_FALSE 0 | ||
53 | |||
54 | #if BB_BIG_ENDIAN | ||
55 | # define ENDIAN_BIG 1 | ||
56 | # undef ENDIAN_LITTLE | ||
57 | //#???? ENDIAN_32BITWORD | ||
58 | // controls only STORE32L, which we don't use | ||
59 | #else | ||
60 | # define ENDIAN_LITTLE 1 | ||
61 | # undef ENDIAN_BIG | ||
62 | #endif | ||
63 | |||
64 | typedef uint64_t uint64; | ||
65 | typedef int64_t int64; | ||
66 | typedef uint32_t uint32; | ||
67 | typedef int32_t int32; | ||
68 | typedef uint16_t uint16; | ||
69 | typedef int16_t int16; | ||
70 | |||
71 | //typedef char psPool_t; | ||
72 | |||
73 | //#ifdef PS_PUBKEY_OPTIMIZE_FOR_SMALLER_RAM | ||
74 | #define PS_EXPTMOD_WINSIZE 3 | ||
75 | //#ifdef PS_PUBKEY_OPTIMIZE_FOR_FASTER_SPEED | ||
76 | //#define PS_EXPTMOD_WINSIZE 5 | ||
77 | |||
78 | #define PUBKEY_TYPE 0x01 | ||
79 | #define PRIVKEY_TYPE 0x02 | ||
80 | |||
81 | void tls_get_random(void *buf, unsigned len); | ||
82 | |||
83 | #define matrixCryptoGetPrngData(buf, len, userPtr) (tls_get_random(buf, len), PS_SUCCESS) | ||
84 | |||
85 | #define psFree(p, pool) free(p) | ||
86 | #define psTraceCrypto(...) bb_error_msg_and_die(__VA_ARGS__) | ||
87 | |||
88 | /* Secure zerofill */ | ||
89 | #define memset_s(A,B,C,D) memset((A),(C),(D)) | ||
90 | /* Constant time memory comparison */ | ||
91 | #define memcmpct(s1, s2, len) memcmp((s1), (s2), (len)) | ||
92 | #undef min | ||
93 | #define min(x, y) ((x) < (y) ? (x) : (y)) | ||
94 | |||
95 | |||
96 | #include "tls_pstm.h" | ||
97 | #include "tls_rsa.h" | ||
98 | #include "tls_symmetric.h" | ||
99 | #include "tls_aes.h" | ||
diff --git a/networking/tls_aes.c b/networking/tls_aes.c new file mode 100644 index 000000000..ebaab15b1 --- /dev/null +++ b/networking/tls_aes.c | |||
@@ -0,0 +1,1776 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2017 Denys Vlasenko | ||
3 | * | ||
4 | * Licensed under GPLv2, see file LICENSE in this source tree. | ||
5 | */ | ||
6 | #include "tls.h" | ||
7 | |||
8 | static | ||
9 | int32 psAesInitKey(const unsigned char *key, uint32 keylen, psAesKey_t *skey); | ||
10 | static | ||
11 | void psAesEncryptBlock(const unsigned char *pt, unsigned char *ct, | ||
12 | psAesKey_t *skey); | ||
13 | static | ||
14 | void psAesDecryptBlock(const unsigned char *ct, unsigned char *pt, | ||
15 | psAesKey_t *skey); | ||
16 | static | ||
17 | int32 psAesInit(psCipherContext_t *ctx, unsigned char *IV, | ||
18 | const unsigned char *key, uint32 keylen); | ||
19 | static | ||
20 | int32 psAesEncrypt(psCipherContext_t *ctx, const unsigned char *pt, | ||
21 | unsigned char *ct, uint32 len); | ||
22 | static | ||
23 | int32 psAesDecrypt(psCipherContext_t *ctx, const unsigned char *ct, | ||
24 | unsigned char *pt, uint32 len); | ||
25 | |||
26 | void aes_cbc_encrypt(const void *key, int klen, void *iv, const void *data, size_t len, void *dst) | ||
27 | { | ||
28 | psCipherContext_t ctx; | ||
29 | psAesInit(&ctx, iv, key, klen); | ||
30 | psAesEncrypt(&ctx, | ||
31 | data, /* plaintext */ | ||
32 | dst, /* ciphertext */ | ||
33 | len | ||
34 | ); | ||
35 | } | ||
36 | |||
37 | void aes_cbc_decrypt(const void *key, int klen, void *iv, const void *data, size_t len, void *dst) | ||
38 | { | ||
39 | psCipherContext_t ctx; | ||
40 | psAesInit(&ctx, iv, key, klen); | ||
41 | psAesDecrypt(&ctx, | ||
42 | data, /* ciphertext */ | ||
43 | dst, /* plaintext */ | ||
44 | len | ||
45 | ); | ||
46 | } | ||
47 | |||
48 | /* The file is taken almost verbatim from matrixssl-3-7-2b-open/crypto/symmetric/. | ||
49 | * Changes are flagged with //bbox | ||
50 | */ | ||
51 | |||
52 | /** | ||
53 | * @file aes.c | ||
54 | * @version 33ef80f (HEAD, tag: MATRIXSSL-3-7-2-OPEN, tag: MATRIXSSL-3-7-2-COMM, origin/master, origin/HEAD, master) | ||
55 | * | ||
56 | * AES CBC block cipher implementation. | ||
57 | */ | ||
58 | /* | ||
59 | * Copyright (c) 2013-2015 INSIDE Secure Corporation | ||
60 | * Copyright (c) PeerSec Networks, 2002-2011 | ||
61 | * All Rights Reserved | ||
62 | * | ||
63 | * The latest version of this code is available at http://www.matrixssl.org | ||
64 | * | ||
65 | * This software is open source; you can redistribute it and/or modify | ||
66 | * it under the terms of the GNU General Public License as published by | ||
67 | * the Free Software Foundation; either version 2 of the License, or | ||
68 | * (at your option) any later version. | ||
69 | * | ||
70 | * This General Public License does NOT permit incorporating this software | ||
71 | * into proprietary programs. If you are unable to comply with the GPL, a | ||
72 | * commercial license for this software may be purchased from INSIDE at | ||
73 | * http://www.insidesecure.com/eng/Company/Locations | ||
74 | * | ||
75 | * This program is distributed in WITHOUT ANY WARRANTY; without even the | ||
76 | * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. | ||
77 | * See the GNU General Public License for more details. | ||
78 | * | ||
79 | * You should have received a copy of the GNU General Public License | ||
80 | * along with this program; if not, write to the Free Software | ||
81 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
82 | * http://www.gnu.org/copyleft/gpl.html | ||
83 | */ | ||
84 | /******************************************************************************/ | ||
85 | |||
86 | //bbox | ||
87 | //#include "../cryptoApi.h" | ||
88 | |||
89 | #ifdef USE_AES | ||
90 | #ifndef USE_AES_CBC_EXTERNAL | ||
91 | /******************************************************************************/ | ||
92 | |||
93 | /* The precomputed tables for AES */ | ||
94 | /* | ||
95 | Te0[x] = S [x].[02, 01, 01, 03]; | ||
96 | Te1[x] = S [x].[03, 02, 01, 01]; | ||
97 | Te2[x] = S [x].[01, 03, 02, 01]; | ||
98 | Te3[x] = S [x].[01, 01, 03, 02]; | ||
99 | Te4[x] = S [x].[01, 01, 01, 01]; | ||
100 | |||
101 | Td0[x] = Si[x].[0e, 09, 0d, 0b]; | ||
102 | Td1[x] = Si[x].[0b, 0e, 09, 0d]; | ||
103 | Td2[x] = Si[x].[0d, 0b, 0e, 09]; | ||
104 | Td3[x] = Si[x].[09, 0d, 0b, 0e]; | ||
105 | Td4[x] = Si[x].[01, 01, 01, 01]; | ||
106 | */ | ||
107 | |||
108 | static const uint32 TE0[] = { | ||
109 | 0xc66363a5UL, 0xf87c7c84UL, 0xee777799UL, 0xf67b7b8dUL, | ||
110 | 0xfff2f20dUL, 0xd66b6bbdUL, 0xde6f6fb1UL, 0x91c5c554UL, | ||
111 | 0x60303050UL, 0x02010103UL, 0xce6767a9UL, 0x562b2b7dUL, | ||
112 | 0xe7fefe19UL, 0xb5d7d762UL, 0x4dababe6UL, 0xec76769aUL, | ||
113 | 0x8fcaca45UL, 0x1f82829dUL, 0x89c9c940UL, 0xfa7d7d87UL, | ||
114 | 0xeffafa15UL, 0xb25959ebUL, 0x8e4747c9UL, 0xfbf0f00bUL, | ||
115 | 0x41adadecUL, 0xb3d4d467UL, 0x5fa2a2fdUL, 0x45afafeaUL, | ||
116 | 0x239c9cbfUL, 0x53a4a4f7UL, 0xe4727296UL, 0x9bc0c05bUL, | ||
117 | 0x75b7b7c2UL, 0xe1fdfd1cUL, 0x3d9393aeUL, 0x4c26266aUL, | ||
118 | 0x6c36365aUL, 0x7e3f3f41UL, 0xf5f7f702UL, 0x83cccc4fUL, | ||
119 | 0x6834345cUL, 0x51a5a5f4UL, 0xd1e5e534UL, 0xf9f1f108UL, | ||
120 | 0xe2717193UL, 0xabd8d873UL, 0x62313153UL, 0x2a15153fUL, | ||
121 | 0x0804040cUL, 0x95c7c752UL, 0x46232365UL, 0x9dc3c35eUL, | ||
122 | 0x30181828UL, 0x379696a1UL, 0x0a05050fUL, 0x2f9a9ab5UL, | ||
123 | 0x0e070709UL, 0x24121236UL, 0x1b80809bUL, 0xdfe2e23dUL, | ||
124 | 0xcdebeb26UL, 0x4e272769UL, 0x7fb2b2cdUL, 0xea75759fUL, | ||
125 | 0x1209091bUL, 0x1d83839eUL, 0x582c2c74UL, 0x341a1a2eUL, | ||
126 | 0x361b1b2dUL, 0xdc6e6eb2UL, 0xb45a5aeeUL, 0x5ba0a0fbUL, | ||
127 | 0xa45252f6UL, 0x763b3b4dUL, 0xb7d6d661UL, 0x7db3b3ceUL, | ||
128 | 0x5229297bUL, 0xdde3e33eUL, 0x5e2f2f71UL, 0x13848497UL, | ||
129 | 0xa65353f5UL, 0xb9d1d168UL, 0x00000000UL, 0xc1eded2cUL, | ||
130 | 0x40202060UL, 0xe3fcfc1fUL, 0x79b1b1c8UL, 0xb65b5bedUL, | ||
131 | 0xd46a6abeUL, 0x8dcbcb46UL, 0x67bebed9UL, 0x7239394bUL, | ||
132 | 0x944a4adeUL, 0x984c4cd4UL, 0xb05858e8UL, 0x85cfcf4aUL, | ||
133 | 0xbbd0d06bUL, 0xc5efef2aUL, 0x4faaaae5UL, 0xedfbfb16UL, | ||
134 | 0x864343c5UL, 0x9a4d4dd7UL, 0x66333355UL, 0x11858594UL, | ||
135 | 0x8a4545cfUL, 0xe9f9f910UL, 0x04020206UL, 0xfe7f7f81UL, | ||
136 | 0xa05050f0UL, 0x783c3c44UL, 0x259f9fbaUL, 0x4ba8a8e3UL, | ||
137 | 0xa25151f3UL, 0x5da3a3feUL, 0x804040c0UL, 0x058f8f8aUL, | ||
138 | 0x3f9292adUL, 0x219d9dbcUL, 0x70383848UL, 0xf1f5f504UL, | ||
139 | 0x63bcbcdfUL, 0x77b6b6c1UL, 0xafdada75UL, 0x42212163UL, | ||
140 | 0x20101030UL, 0xe5ffff1aUL, 0xfdf3f30eUL, 0xbfd2d26dUL, | ||
141 | 0x81cdcd4cUL, 0x180c0c14UL, 0x26131335UL, 0xc3ecec2fUL, | ||
142 | 0xbe5f5fe1UL, 0x359797a2UL, 0x884444ccUL, 0x2e171739UL, | ||
143 | 0x93c4c457UL, 0x55a7a7f2UL, 0xfc7e7e82UL, 0x7a3d3d47UL, | ||
144 | 0xc86464acUL, 0xba5d5de7UL, 0x3219192bUL, 0xe6737395UL, | ||
145 | 0xc06060a0UL, 0x19818198UL, 0x9e4f4fd1UL, 0xa3dcdc7fUL, | ||
146 | 0x44222266UL, 0x542a2a7eUL, 0x3b9090abUL, 0x0b888883UL, | ||
147 | 0x8c4646caUL, 0xc7eeee29UL, 0x6bb8b8d3UL, 0x2814143cUL, | ||
148 | 0xa7dede79UL, 0xbc5e5ee2UL, 0x160b0b1dUL, 0xaddbdb76UL, | ||
149 | 0xdbe0e03bUL, 0x64323256UL, 0x743a3a4eUL, 0x140a0a1eUL, | ||
150 | 0x924949dbUL, 0x0c06060aUL, 0x4824246cUL, 0xb85c5ce4UL, | ||
151 | 0x9fc2c25dUL, 0xbdd3d36eUL, 0x43acacefUL, 0xc46262a6UL, | ||
152 | 0x399191a8UL, 0x319595a4UL, 0xd3e4e437UL, 0xf279798bUL, | ||
153 | 0xd5e7e732UL, 0x8bc8c843UL, 0x6e373759UL, 0xda6d6db7UL, | ||
154 | 0x018d8d8cUL, 0xb1d5d564UL, 0x9c4e4ed2UL, 0x49a9a9e0UL, | ||
155 | 0xd86c6cb4UL, 0xac5656faUL, 0xf3f4f407UL, 0xcfeaea25UL, | ||
156 | 0xca6565afUL, 0xf47a7a8eUL, 0x47aeaee9UL, 0x10080818UL, | ||
157 | 0x6fbabad5UL, 0xf0787888UL, 0x4a25256fUL, 0x5c2e2e72UL, | ||
158 | 0x381c1c24UL, 0x57a6a6f1UL, 0x73b4b4c7UL, 0x97c6c651UL, | ||
159 | 0xcbe8e823UL, 0xa1dddd7cUL, 0xe874749cUL, 0x3e1f1f21UL, | ||
160 | 0x964b4bddUL, 0x61bdbddcUL, 0x0d8b8b86UL, 0x0f8a8a85UL, | ||
161 | 0xe0707090UL, 0x7c3e3e42UL, 0x71b5b5c4UL, 0xcc6666aaUL, | ||
162 | 0x904848d8UL, 0x06030305UL, 0xf7f6f601UL, 0x1c0e0e12UL, | ||
163 | 0xc26161a3UL, 0x6a35355fUL, 0xae5757f9UL, 0x69b9b9d0UL, | ||
164 | 0x17868691UL, 0x99c1c158UL, 0x3a1d1d27UL, 0x279e9eb9UL, | ||
165 | 0xd9e1e138UL, 0xebf8f813UL, 0x2b9898b3UL, 0x22111133UL, | ||
166 | 0xd26969bbUL, 0xa9d9d970UL, 0x078e8e89UL, 0x339494a7UL, | ||
167 | 0x2d9b9bb6UL, 0x3c1e1e22UL, 0x15878792UL, 0xc9e9e920UL, | ||
168 | 0x87cece49UL, 0xaa5555ffUL, 0x50282878UL, 0xa5dfdf7aUL, | ||
169 | 0x038c8c8fUL, 0x59a1a1f8UL, 0x09898980UL, 0x1a0d0d17UL, | ||
170 | 0x65bfbfdaUL, 0xd7e6e631UL, 0x844242c6UL, 0xd06868b8UL, | ||
171 | 0x824141c3UL, 0x299999b0UL, 0x5a2d2d77UL, 0x1e0f0f11UL, | ||
172 | 0x7bb0b0cbUL, 0xa85454fcUL, 0x6dbbbbd6UL, 0x2c16163aUL, | ||
173 | }; | ||
174 | |||
175 | static const uint32 Te4[] = { | ||
176 | 0x63636363UL, 0x7c7c7c7cUL, 0x77777777UL, 0x7b7b7b7bUL, | ||
177 | 0xf2f2f2f2UL, 0x6b6b6b6bUL, 0x6f6f6f6fUL, 0xc5c5c5c5UL, | ||
178 | 0x30303030UL, 0x01010101UL, 0x67676767UL, 0x2b2b2b2bUL, | ||
179 | 0xfefefefeUL, 0xd7d7d7d7UL, 0xababababUL, 0x76767676UL, | ||
180 | 0xcacacacaUL, 0x82828282UL, 0xc9c9c9c9UL, 0x7d7d7d7dUL, | ||
181 | 0xfafafafaUL, 0x59595959UL, 0x47474747UL, 0xf0f0f0f0UL, | ||
182 | 0xadadadadUL, 0xd4d4d4d4UL, 0xa2a2a2a2UL, 0xafafafafUL, | ||
183 | 0x9c9c9c9cUL, 0xa4a4a4a4UL, 0x72727272UL, 0xc0c0c0c0UL, | ||
184 | 0xb7b7b7b7UL, 0xfdfdfdfdUL, 0x93939393UL, 0x26262626UL, | ||
185 | 0x36363636UL, 0x3f3f3f3fUL, 0xf7f7f7f7UL, 0xccccccccUL, | ||
186 | 0x34343434UL, 0xa5a5a5a5UL, 0xe5e5e5e5UL, 0xf1f1f1f1UL, | ||
187 | 0x71717171UL, 0xd8d8d8d8UL, 0x31313131UL, 0x15151515UL, | ||
188 | 0x04040404UL, 0xc7c7c7c7UL, 0x23232323UL, 0xc3c3c3c3UL, | ||
189 | 0x18181818UL, 0x96969696UL, 0x05050505UL, 0x9a9a9a9aUL, | ||
190 | 0x07070707UL, 0x12121212UL, 0x80808080UL, 0xe2e2e2e2UL, | ||
191 | 0xebebebebUL, 0x27272727UL, 0xb2b2b2b2UL, 0x75757575UL, | ||
192 | 0x09090909UL, 0x83838383UL, 0x2c2c2c2cUL, 0x1a1a1a1aUL, | ||
193 | 0x1b1b1b1bUL, 0x6e6e6e6eUL, 0x5a5a5a5aUL, 0xa0a0a0a0UL, | ||
194 | 0x52525252UL, 0x3b3b3b3bUL, 0xd6d6d6d6UL, 0xb3b3b3b3UL, | ||
195 | 0x29292929UL, 0xe3e3e3e3UL, 0x2f2f2f2fUL, 0x84848484UL, | ||
196 | 0x53535353UL, 0xd1d1d1d1UL, 0x00000000UL, 0xededededUL, | ||
197 | 0x20202020UL, 0xfcfcfcfcUL, 0xb1b1b1b1UL, 0x5b5b5b5bUL, | ||
198 | 0x6a6a6a6aUL, 0xcbcbcbcbUL, 0xbebebebeUL, 0x39393939UL, | ||
199 | 0x4a4a4a4aUL, 0x4c4c4c4cUL, 0x58585858UL, 0xcfcfcfcfUL, | ||
200 | 0xd0d0d0d0UL, 0xefefefefUL, 0xaaaaaaaaUL, 0xfbfbfbfbUL, | ||
201 | 0x43434343UL, 0x4d4d4d4dUL, 0x33333333UL, 0x85858585UL, | ||
202 | 0x45454545UL, 0xf9f9f9f9UL, 0x02020202UL, 0x7f7f7f7fUL, | ||
203 | 0x50505050UL, 0x3c3c3c3cUL, 0x9f9f9f9fUL, 0xa8a8a8a8UL, | ||
204 | 0x51515151UL, 0xa3a3a3a3UL, 0x40404040UL, 0x8f8f8f8fUL, | ||
205 | 0x92929292UL, 0x9d9d9d9dUL, 0x38383838UL, 0xf5f5f5f5UL, | ||
206 | 0xbcbcbcbcUL, 0xb6b6b6b6UL, 0xdadadadaUL, 0x21212121UL, | ||
207 | 0x10101010UL, 0xffffffffUL, 0xf3f3f3f3UL, 0xd2d2d2d2UL, | ||
208 | 0xcdcdcdcdUL, 0x0c0c0c0cUL, 0x13131313UL, 0xececececUL, | ||
209 | 0x5f5f5f5fUL, 0x97979797UL, 0x44444444UL, 0x17171717UL, | ||
210 | 0xc4c4c4c4UL, 0xa7a7a7a7UL, 0x7e7e7e7eUL, 0x3d3d3d3dUL, | ||
211 | 0x64646464UL, 0x5d5d5d5dUL, 0x19191919UL, 0x73737373UL, | ||
212 | 0x60606060UL, 0x81818181UL, 0x4f4f4f4fUL, 0xdcdcdcdcUL, | ||
213 | 0x22222222UL, 0x2a2a2a2aUL, 0x90909090UL, 0x88888888UL, | ||
214 | 0x46464646UL, 0xeeeeeeeeUL, 0xb8b8b8b8UL, 0x14141414UL, | ||
215 | 0xdedededeUL, 0x5e5e5e5eUL, 0x0b0b0b0bUL, 0xdbdbdbdbUL, | ||
216 | 0xe0e0e0e0UL, 0x32323232UL, 0x3a3a3a3aUL, 0x0a0a0a0aUL, | ||
217 | 0x49494949UL, 0x06060606UL, 0x24242424UL, 0x5c5c5c5cUL, | ||
218 | 0xc2c2c2c2UL, 0xd3d3d3d3UL, 0xacacacacUL, 0x62626262UL, | ||
219 | 0x91919191UL, 0x95959595UL, 0xe4e4e4e4UL, 0x79797979UL, | ||
220 | 0xe7e7e7e7UL, 0xc8c8c8c8UL, 0x37373737UL, 0x6d6d6d6dUL, | ||
221 | 0x8d8d8d8dUL, 0xd5d5d5d5UL, 0x4e4e4e4eUL, 0xa9a9a9a9UL, | ||
222 | 0x6c6c6c6cUL, 0x56565656UL, 0xf4f4f4f4UL, 0xeaeaeaeaUL, | ||
223 | 0x65656565UL, 0x7a7a7a7aUL, 0xaeaeaeaeUL, 0x08080808UL, | ||
224 | 0xbabababaUL, 0x78787878UL, 0x25252525UL, 0x2e2e2e2eUL, | ||
225 | 0x1c1c1c1cUL, 0xa6a6a6a6UL, 0xb4b4b4b4UL, 0xc6c6c6c6UL, | ||
226 | 0xe8e8e8e8UL, 0xddddddddUL, 0x74747474UL, 0x1f1f1f1fUL, | ||
227 | 0x4b4b4b4bUL, 0xbdbdbdbdUL, 0x8b8b8b8bUL, 0x8a8a8a8aUL, | ||
228 | 0x70707070UL, 0x3e3e3e3eUL, 0xb5b5b5b5UL, 0x66666666UL, | ||
229 | 0x48484848UL, 0x03030303UL, 0xf6f6f6f6UL, 0x0e0e0e0eUL, | ||
230 | 0x61616161UL, 0x35353535UL, 0x57575757UL, 0xb9b9b9b9UL, | ||
231 | 0x86868686UL, 0xc1c1c1c1UL, 0x1d1d1d1dUL, 0x9e9e9e9eUL, | ||
232 | 0xe1e1e1e1UL, 0xf8f8f8f8UL, 0x98989898UL, 0x11111111UL, | ||
233 | 0x69696969UL, 0xd9d9d9d9UL, 0x8e8e8e8eUL, 0x94949494UL, | ||
234 | 0x9b9b9b9bUL, 0x1e1e1e1eUL, 0x87878787UL, 0xe9e9e9e9UL, | ||
235 | 0xcecececeUL, 0x55555555UL, 0x28282828UL, 0xdfdfdfdfUL, | ||
236 | 0x8c8c8c8cUL, 0xa1a1a1a1UL, 0x89898989UL, 0x0d0d0d0dUL, | ||
237 | 0xbfbfbfbfUL, 0xe6e6e6e6UL, 0x42424242UL, 0x68686868UL, | ||
238 | 0x41414141UL, 0x99999999UL, 0x2d2d2d2dUL, 0x0f0f0f0fUL, | ||
239 | 0xb0b0b0b0UL, 0x54545454UL, 0xbbbbbbbbUL, 0x16161616UL, | ||
240 | }; | ||
241 | |||
242 | static const uint32 TD0[] = { | ||
243 | 0x51f4a750UL, 0x7e416553UL, 0x1a17a4c3UL, 0x3a275e96UL, | ||
244 | 0x3bab6bcbUL, 0x1f9d45f1UL, 0xacfa58abUL, 0x4be30393UL, | ||
245 | 0x2030fa55UL, 0xad766df6UL, 0x88cc7691UL, 0xf5024c25UL, | ||
246 | 0x4fe5d7fcUL, 0xc52acbd7UL, 0x26354480UL, 0xb562a38fUL, | ||
247 | 0xdeb15a49UL, 0x25ba1b67UL, 0x45ea0e98UL, 0x5dfec0e1UL, | ||
248 | 0xc32f7502UL, 0x814cf012UL, 0x8d4697a3UL, 0x6bd3f9c6UL, | ||
249 | 0x038f5fe7UL, 0x15929c95UL, 0xbf6d7aebUL, 0x955259daUL, | ||
250 | 0xd4be832dUL, 0x587421d3UL, 0x49e06929UL, 0x8ec9c844UL, | ||
251 | 0x75c2896aUL, 0xf48e7978UL, 0x99583e6bUL, 0x27b971ddUL, | ||
252 | 0xbee14fb6UL, 0xf088ad17UL, 0xc920ac66UL, 0x7dce3ab4UL, | ||
253 | 0x63df4a18UL, 0xe51a3182UL, 0x97513360UL, 0x62537f45UL, | ||
254 | 0xb16477e0UL, 0xbb6bae84UL, 0xfe81a01cUL, 0xf9082b94UL, | ||
255 | 0x70486858UL, 0x8f45fd19UL, 0x94de6c87UL, 0x527bf8b7UL, | ||
256 | 0xab73d323UL, 0x724b02e2UL, 0xe31f8f57UL, 0x6655ab2aUL, | ||
257 | 0xb2eb2807UL, 0x2fb5c203UL, 0x86c57b9aUL, 0xd33708a5UL, | ||
258 | 0x302887f2UL, 0x23bfa5b2UL, 0x02036abaUL, 0xed16825cUL, | ||
259 | 0x8acf1c2bUL, 0xa779b492UL, 0xf307f2f0UL, 0x4e69e2a1UL, | ||
260 | 0x65daf4cdUL, 0x0605bed5UL, 0xd134621fUL, 0xc4a6fe8aUL, | ||
261 | 0x342e539dUL, 0xa2f355a0UL, 0x058ae132UL, 0xa4f6eb75UL, | ||
262 | 0x0b83ec39UL, 0x4060efaaUL, 0x5e719f06UL, 0xbd6e1051UL, | ||
263 | 0x3e218af9UL, 0x96dd063dUL, 0xdd3e05aeUL, 0x4de6bd46UL, | ||
264 | 0x91548db5UL, 0x71c45d05UL, 0x0406d46fUL, 0x605015ffUL, | ||
265 | 0x1998fb24UL, 0xd6bde997UL, 0x894043ccUL, 0x67d99e77UL, | ||
266 | 0xb0e842bdUL, 0x07898b88UL, 0xe7195b38UL, 0x79c8eedbUL, | ||
267 | 0xa17c0a47UL, 0x7c420fe9UL, 0xf8841ec9UL, 0x00000000UL, | ||
268 | 0x09808683UL, 0x322bed48UL, 0x1e1170acUL, 0x6c5a724eUL, | ||
269 | 0xfd0efffbUL, 0x0f853856UL, 0x3daed51eUL, 0x362d3927UL, | ||
270 | 0x0a0fd964UL, 0x685ca621UL, 0x9b5b54d1UL, 0x24362e3aUL, | ||
271 | 0x0c0a67b1UL, 0x9357e70fUL, 0xb4ee96d2UL, 0x1b9b919eUL, | ||
272 | 0x80c0c54fUL, 0x61dc20a2UL, 0x5a774b69UL, 0x1c121a16UL, | ||
273 | 0xe293ba0aUL, 0xc0a02ae5UL, 0x3c22e043UL, 0x121b171dUL, | ||
274 | 0x0e090d0bUL, 0xf28bc7adUL, 0x2db6a8b9UL, 0x141ea9c8UL, | ||
275 | 0x57f11985UL, 0xaf75074cUL, 0xee99ddbbUL, 0xa37f60fdUL, | ||
276 | 0xf701269fUL, 0x5c72f5bcUL, 0x44663bc5UL, 0x5bfb7e34UL, | ||
277 | 0x8b432976UL, 0xcb23c6dcUL, 0xb6edfc68UL, 0xb8e4f163UL, | ||
278 | 0xd731dccaUL, 0x42638510UL, 0x13972240UL, 0x84c61120UL, | ||
279 | 0x854a247dUL, 0xd2bb3df8UL, 0xaef93211UL, 0xc729a16dUL, | ||
280 | 0x1d9e2f4bUL, 0xdcb230f3UL, 0x0d8652ecUL, 0x77c1e3d0UL, | ||
281 | 0x2bb3166cUL, 0xa970b999UL, 0x119448faUL, 0x47e96422UL, | ||
282 | 0xa8fc8cc4UL, 0xa0f03f1aUL, 0x567d2cd8UL, 0x223390efUL, | ||
283 | 0x87494ec7UL, 0xd938d1c1UL, 0x8ccaa2feUL, 0x98d40b36UL, | ||
284 | 0xa6f581cfUL, 0xa57ade28UL, 0xdab78e26UL, 0x3fadbfa4UL, | ||
285 | 0x2c3a9de4UL, 0x5078920dUL, 0x6a5fcc9bUL, 0x547e4662UL, | ||
286 | 0xf68d13c2UL, 0x90d8b8e8UL, 0x2e39f75eUL, 0x82c3aff5UL, | ||
287 | 0x9f5d80beUL, 0x69d0937cUL, 0x6fd52da9UL, 0xcf2512b3UL, | ||
288 | 0xc8ac993bUL, 0x10187da7UL, 0xe89c636eUL, 0xdb3bbb7bUL, | ||
289 | 0xcd267809UL, 0x6e5918f4UL, 0xec9ab701UL, 0x834f9aa8UL, | ||
290 | 0xe6956e65UL, 0xaaffe67eUL, 0x21bccf08UL, 0xef15e8e6UL, | ||
291 | 0xbae79bd9UL, 0x4a6f36ceUL, 0xea9f09d4UL, 0x29b07cd6UL, | ||
292 | 0x31a4b2afUL, 0x2a3f2331UL, 0xc6a59430UL, 0x35a266c0UL, | ||
293 | 0x744ebc37UL, 0xfc82caa6UL, 0xe090d0b0UL, 0x33a7d815UL, | ||
294 | 0xf104984aUL, 0x41ecdaf7UL, 0x7fcd500eUL, 0x1791f62fUL, | ||
295 | 0x764dd68dUL, 0x43efb04dUL, 0xccaa4d54UL, 0xe49604dfUL, | ||
296 | 0x9ed1b5e3UL, 0x4c6a881bUL, 0xc12c1fb8UL, 0x4665517fUL, | ||
297 | 0x9d5eea04UL, 0x018c355dUL, 0xfa877473UL, 0xfb0b412eUL, | ||
298 | 0xb3671d5aUL, 0x92dbd252UL, 0xe9105633UL, 0x6dd64713UL, | ||
299 | 0x9ad7618cUL, 0x37a10c7aUL, 0x59f8148eUL, 0xeb133c89UL, | ||
300 | 0xcea927eeUL, 0xb761c935UL, 0xe11ce5edUL, 0x7a47b13cUL, | ||
301 | 0x9cd2df59UL, 0x55f2733fUL, 0x1814ce79UL, 0x73c737bfUL, | ||
302 | 0x53f7cdeaUL, 0x5ffdaa5bUL, 0xdf3d6f14UL, 0x7844db86UL, | ||
303 | 0xcaaff381UL, 0xb968c43eUL, 0x3824342cUL, 0xc2a3405fUL, | ||
304 | 0x161dc372UL, 0xbce2250cUL, 0x283c498bUL, 0xff0d9541UL, | ||
305 | 0x39a80171UL, 0x080cb3deUL, 0xd8b4e49cUL, 0x6456c190UL, | ||
306 | 0x7bcb8461UL, 0xd532b670UL, 0x486c5c74UL, 0xd0b85742UL, | ||
307 | }; | ||
308 | |||
309 | static const uint32 Td4[] = { | ||
310 | 0x52525252UL, 0x09090909UL, 0x6a6a6a6aUL, 0xd5d5d5d5UL, | ||
311 | 0x30303030UL, 0x36363636UL, 0xa5a5a5a5UL, 0x38383838UL, | ||
312 | 0xbfbfbfbfUL, 0x40404040UL, 0xa3a3a3a3UL, 0x9e9e9e9eUL, | ||
313 | 0x81818181UL, 0xf3f3f3f3UL, 0xd7d7d7d7UL, 0xfbfbfbfbUL, | ||
314 | 0x7c7c7c7cUL, 0xe3e3e3e3UL, 0x39393939UL, 0x82828282UL, | ||
315 | 0x9b9b9b9bUL, 0x2f2f2f2fUL, 0xffffffffUL, 0x87878787UL, | ||
316 | 0x34343434UL, 0x8e8e8e8eUL, 0x43434343UL, 0x44444444UL, | ||
317 | 0xc4c4c4c4UL, 0xdedededeUL, 0xe9e9e9e9UL, 0xcbcbcbcbUL, | ||
318 | 0x54545454UL, 0x7b7b7b7bUL, 0x94949494UL, 0x32323232UL, | ||
319 | 0xa6a6a6a6UL, 0xc2c2c2c2UL, 0x23232323UL, 0x3d3d3d3dUL, | ||
320 | 0xeeeeeeeeUL, 0x4c4c4c4cUL, 0x95959595UL, 0x0b0b0b0bUL, | ||
321 | 0x42424242UL, 0xfafafafaUL, 0xc3c3c3c3UL, 0x4e4e4e4eUL, | ||
322 | 0x08080808UL, 0x2e2e2e2eUL, 0xa1a1a1a1UL, 0x66666666UL, | ||
323 | 0x28282828UL, 0xd9d9d9d9UL, 0x24242424UL, 0xb2b2b2b2UL, | ||
324 | 0x76767676UL, 0x5b5b5b5bUL, 0xa2a2a2a2UL, 0x49494949UL, | ||
325 | 0x6d6d6d6dUL, 0x8b8b8b8bUL, 0xd1d1d1d1UL, 0x25252525UL, | ||
326 | 0x72727272UL, 0xf8f8f8f8UL, 0xf6f6f6f6UL, 0x64646464UL, | ||
327 | 0x86868686UL, 0x68686868UL, 0x98989898UL, 0x16161616UL, | ||
328 | 0xd4d4d4d4UL, 0xa4a4a4a4UL, 0x5c5c5c5cUL, 0xccccccccUL, | ||
329 | 0x5d5d5d5dUL, 0x65656565UL, 0xb6b6b6b6UL, 0x92929292UL, | ||
330 | 0x6c6c6c6cUL, 0x70707070UL, 0x48484848UL, 0x50505050UL, | ||
331 | 0xfdfdfdfdUL, 0xededededUL, 0xb9b9b9b9UL, 0xdadadadaUL, | ||
332 | 0x5e5e5e5eUL, 0x15151515UL, 0x46464646UL, 0x57575757UL, | ||
333 | 0xa7a7a7a7UL, 0x8d8d8d8dUL, 0x9d9d9d9dUL, 0x84848484UL, | ||
334 | 0x90909090UL, 0xd8d8d8d8UL, 0xababababUL, 0x00000000UL, | ||
335 | 0x8c8c8c8cUL, 0xbcbcbcbcUL, 0xd3d3d3d3UL, 0x0a0a0a0aUL, | ||
336 | 0xf7f7f7f7UL, 0xe4e4e4e4UL, 0x58585858UL, 0x05050505UL, | ||
337 | 0xb8b8b8b8UL, 0xb3b3b3b3UL, 0x45454545UL, 0x06060606UL, | ||
338 | 0xd0d0d0d0UL, 0x2c2c2c2cUL, 0x1e1e1e1eUL, 0x8f8f8f8fUL, | ||
339 | 0xcacacacaUL, 0x3f3f3f3fUL, 0x0f0f0f0fUL, 0x02020202UL, | ||
340 | 0xc1c1c1c1UL, 0xafafafafUL, 0xbdbdbdbdUL, 0x03030303UL, | ||
341 | 0x01010101UL, 0x13131313UL, 0x8a8a8a8aUL, 0x6b6b6b6bUL, | ||
342 | 0x3a3a3a3aUL, 0x91919191UL, 0x11111111UL, 0x41414141UL, | ||
343 | 0x4f4f4f4fUL, 0x67676767UL, 0xdcdcdcdcUL, 0xeaeaeaeaUL, | ||
344 | 0x97979797UL, 0xf2f2f2f2UL, 0xcfcfcfcfUL, 0xcecececeUL, | ||
345 | 0xf0f0f0f0UL, 0xb4b4b4b4UL, 0xe6e6e6e6UL, 0x73737373UL, | ||
346 | 0x96969696UL, 0xacacacacUL, 0x74747474UL, 0x22222222UL, | ||
347 | 0xe7e7e7e7UL, 0xadadadadUL, 0x35353535UL, 0x85858585UL, | ||
348 | 0xe2e2e2e2UL, 0xf9f9f9f9UL, 0x37373737UL, 0xe8e8e8e8UL, | ||
349 | 0x1c1c1c1cUL, 0x75757575UL, 0xdfdfdfdfUL, 0x6e6e6e6eUL, | ||
350 | 0x47474747UL, 0xf1f1f1f1UL, 0x1a1a1a1aUL, 0x71717171UL, | ||
351 | 0x1d1d1d1dUL, 0x29292929UL, 0xc5c5c5c5UL, 0x89898989UL, | ||
352 | 0x6f6f6f6fUL, 0xb7b7b7b7UL, 0x62626262UL, 0x0e0e0e0eUL, | ||
353 | 0xaaaaaaaaUL, 0x18181818UL, 0xbebebebeUL, 0x1b1b1b1bUL, | ||
354 | 0xfcfcfcfcUL, 0x56565656UL, 0x3e3e3e3eUL, 0x4b4b4b4bUL, | ||
355 | 0xc6c6c6c6UL, 0xd2d2d2d2UL, 0x79797979UL, 0x20202020UL, | ||
356 | 0x9a9a9a9aUL, 0xdbdbdbdbUL, 0xc0c0c0c0UL, 0xfefefefeUL, | ||
357 | 0x78787878UL, 0xcdcdcdcdUL, 0x5a5a5a5aUL, 0xf4f4f4f4UL, | ||
358 | 0x1f1f1f1fUL, 0xddddddddUL, 0xa8a8a8a8UL, 0x33333333UL, | ||
359 | 0x88888888UL, 0x07070707UL, 0xc7c7c7c7UL, 0x31313131UL, | ||
360 | 0xb1b1b1b1UL, 0x12121212UL, 0x10101010UL, 0x59595959UL, | ||
361 | 0x27272727UL, 0x80808080UL, 0xececececUL, 0x5f5f5f5fUL, | ||
362 | 0x60606060UL, 0x51515151UL, 0x7f7f7f7fUL, 0xa9a9a9a9UL, | ||
363 | 0x19191919UL, 0xb5b5b5b5UL, 0x4a4a4a4aUL, 0x0d0d0d0dUL, | ||
364 | 0x2d2d2d2dUL, 0xe5e5e5e5UL, 0x7a7a7a7aUL, 0x9f9f9f9fUL, | ||
365 | 0x93939393UL, 0xc9c9c9c9UL, 0x9c9c9c9cUL, 0xefefefefUL, | ||
366 | 0xa0a0a0a0UL, 0xe0e0e0e0UL, 0x3b3b3b3bUL, 0x4d4d4d4dUL, | ||
367 | 0xaeaeaeaeUL, 0x2a2a2a2aUL, 0xf5f5f5f5UL, 0xb0b0b0b0UL, | ||
368 | 0xc8c8c8c8UL, 0xebebebebUL, 0xbbbbbbbbUL, 0x3c3c3c3cUL, | ||
369 | 0x83838383UL, 0x53535353UL, 0x99999999UL, 0x61616161UL, | ||
370 | 0x17171717UL, 0x2b2b2b2bUL, 0x04040404UL, 0x7e7e7e7eUL, | ||
371 | 0xbabababaUL, 0x77777777UL, 0xd6d6d6d6UL, 0x26262626UL, | ||
372 | 0xe1e1e1e1UL, 0x69696969UL, 0x14141414UL, 0x63636363UL, | ||
373 | 0x55555555UL, 0x21212121UL, 0x0c0c0c0cUL, 0x7d7d7d7dUL, | ||
374 | 0xe1f27f3aUL, 0xf5710fb0UL, 0xada0e5c4UL, 0x98e4c919UL | ||
375 | }; | ||
376 | |||
377 | #ifndef PS_AES_IMPROVE_PERF_INCREASE_CODESIZE | ||
378 | |||
379 | #define Te0(x) TE0[x] | ||
380 | #define Te1(x) ROR(TE0[x], 8) | ||
381 | #define Te2(x) ROR(TE0[x], 16) | ||
382 | #define Te3(x) ROR(TE0[x], 24) | ||
383 | |||
384 | #define Td0(x) TD0[x] | ||
385 | #define Td1(x) ROR(TD0[x], 8) | ||
386 | #define Td2(x) ROR(TD0[x], 16) | ||
387 | #define Td3(x) ROR(TD0[x], 24) | ||
388 | |||
389 | #define Te4_0 0x000000FF & Te4 | ||
390 | #define Te4_1 0x0000FF00 & Te4 | ||
391 | #define Te4_2 0x00FF0000 & Te4 | ||
392 | #define Te4_3 0xFF000000 & Te4 | ||
393 | |||
394 | #else /* PS_AES_IMPROVE_PERF_INCREASE_CODESIZE */ | ||
395 | |||
396 | #define Te0(x) TE0[x] | ||
397 | #define Te1(x) TE1[x] | ||
398 | #define Te2(x) TE2[x] | ||
399 | #define Te3(x) TE3[x] | ||
400 | |||
401 | #define Td0(x) TD0[x] | ||
402 | #define Td1(x) TD1[x] | ||
403 | #define Td2(x) TD2[x] | ||
404 | #define Td3(x) TD3[x] | ||
405 | |||
406 | static const uint32 TE1[256] = { | ||
407 | 0xa5c66363UL, 0x84f87c7cUL, 0x99ee7777UL, 0x8df67b7bUL, | ||
408 | 0x0dfff2f2UL, 0xbdd66b6bUL, 0xb1de6f6fUL, 0x5491c5c5UL, | ||
409 | 0x50603030UL, 0x03020101UL, 0xa9ce6767UL, 0x7d562b2bUL, | ||
410 | 0x19e7fefeUL, 0x62b5d7d7UL, 0xe64dababUL, 0x9aec7676UL, | ||
411 | 0x458fcacaUL, 0x9d1f8282UL, 0x4089c9c9UL, 0x87fa7d7dUL, | ||
412 | 0x15effafaUL, 0xebb25959UL, 0xc98e4747UL, 0x0bfbf0f0UL, | ||
413 | 0xec41adadUL, 0x67b3d4d4UL, 0xfd5fa2a2UL, 0xea45afafUL, | ||
414 | 0xbf239c9cUL, 0xf753a4a4UL, 0x96e47272UL, 0x5b9bc0c0UL, | ||
415 | 0xc275b7b7UL, 0x1ce1fdfdUL, 0xae3d9393UL, 0x6a4c2626UL, | ||
416 | 0x5a6c3636UL, 0x417e3f3fUL, 0x02f5f7f7UL, 0x4f83ccccUL, | ||
417 | 0x5c683434UL, 0xf451a5a5UL, 0x34d1e5e5UL, 0x08f9f1f1UL, | ||
418 | 0x93e27171UL, 0x73abd8d8UL, 0x53623131UL, 0x3f2a1515UL, | ||
419 | 0x0c080404UL, 0x5295c7c7UL, 0x65462323UL, 0x5e9dc3c3UL, | ||
420 | 0x28301818UL, 0xa1379696UL, 0x0f0a0505UL, 0xb52f9a9aUL, | ||
421 | 0x090e0707UL, 0x36241212UL, 0x9b1b8080UL, 0x3ddfe2e2UL, | ||
422 | 0x26cdebebUL, 0x694e2727UL, 0xcd7fb2b2UL, 0x9fea7575UL, | ||
423 | 0x1b120909UL, 0x9e1d8383UL, 0x74582c2cUL, 0x2e341a1aUL, | ||
424 | 0x2d361b1bUL, 0xb2dc6e6eUL, 0xeeb45a5aUL, 0xfb5ba0a0UL, | ||
425 | 0xf6a45252UL, 0x4d763b3bUL, 0x61b7d6d6UL, 0xce7db3b3UL, | ||
426 | 0x7b522929UL, 0x3edde3e3UL, 0x715e2f2fUL, 0x97138484UL, | ||
427 | 0xf5a65353UL, 0x68b9d1d1UL, 0x00000000UL, 0x2cc1ededUL, | ||
428 | 0x60402020UL, 0x1fe3fcfcUL, 0xc879b1b1UL, 0xedb65b5bUL, | ||
429 | 0xbed46a6aUL, 0x468dcbcbUL, 0xd967bebeUL, 0x4b723939UL, | ||
430 | 0xde944a4aUL, 0xd4984c4cUL, 0xe8b05858UL, 0x4a85cfcfUL, | ||
431 | 0x6bbbd0d0UL, 0x2ac5efefUL, 0xe54faaaaUL, 0x16edfbfbUL, | ||
432 | 0xc5864343UL, 0xd79a4d4dUL, 0x55663333UL, 0x94118585UL, | ||
433 | 0xcf8a4545UL, 0x10e9f9f9UL, 0x06040202UL, 0x81fe7f7fUL, | ||
434 | 0xf0a05050UL, 0x44783c3cUL, 0xba259f9fUL, 0xe34ba8a8UL, | ||
435 | 0xf3a25151UL, 0xfe5da3a3UL, 0xc0804040UL, 0x8a058f8fUL, | ||
436 | 0xad3f9292UL, 0xbc219d9dUL, 0x48703838UL, 0x04f1f5f5UL, | ||
437 | 0xdf63bcbcUL, 0xc177b6b6UL, 0x75afdadaUL, 0x63422121UL, | ||
438 | 0x30201010UL, 0x1ae5ffffUL, 0x0efdf3f3UL, 0x6dbfd2d2UL, | ||
439 | 0x4c81cdcdUL, 0x14180c0cUL, 0x35261313UL, 0x2fc3ececUL, | ||
440 | 0xe1be5f5fUL, 0xa2359797UL, 0xcc884444UL, 0x392e1717UL, | ||
441 | 0x5793c4c4UL, 0xf255a7a7UL, 0x82fc7e7eUL, 0x477a3d3dUL, | ||
442 | 0xacc86464UL, 0xe7ba5d5dUL, 0x2b321919UL, 0x95e67373UL, | ||
443 | 0xa0c06060UL, 0x98198181UL, 0xd19e4f4fUL, 0x7fa3dcdcUL, | ||
444 | 0x66442222UL, 0x7e542a2aUL, 0xab3b9090UL, 0x830b8888UL, | ||
445 | 0xca8c4646UL, 0x29c7eeeeUL, 0xd36bb8b8UL, 0x3c281414UL, | ||
446 | 0x79a7dedeUL, 0xe2bc5e5eUL, 0x1d160b0bUL, 0x76addbdbUL, | ||
447 | 0x3bdbe0e0UL, 0x56643232UL, 0x4e743a3aUL, 0x1e140a0aUL, | ||
448 | 0xdb924949UL, 0x0a0c0606UL, 0x6c482424UL, 0xe4b85c5cUL, | ||
449 | 0x5d9fc2c2UL, 0x6ebdd3d3UL, 0xef43acacUL, 0xa6c46262UL, | ||
450 | 0xa8399191UL, 0xa4319595UL, 0x37d3e4e4UL, 0x8bf27979UL, | ||
451 | 0x32d5e7e7UL, 0x438bc8c8UL, 0x596e3737UL, 0xb7da6d6dUL, | ||
452 | 0x8c018d8dUL, 0x64b1d5d5UL, 0xd29c4e4eUL, 0xe049a9a9UL, | ||
453 | 0xb4d86c6cUL, 0xfaac5656UL, 0x07f3f4f4UL, 0x25cfeaeaUL, | ||
454 | 0xafca6565UL, 0x8ef47a7aUL, 0xe947aeaeUL, 0x18100808UL, | ||
455 | 0xd56fbabaUL, 0x88f07878UL, 0x6f4a2525UL, 0x725c2e2eUL, | ||
456 | 0x24381c1cUL, 0xf157a6a6UL, 0xc773b4b4UL, 0x5197c6c6UL, | ||
457 | 0x23cbe8e8UL, 0x7ca1ddddUL, 0x9ce87474UL, 0x213e1f1fUL, | ||
458 | 0xdd964b4bUL, 0xdc61bdbdUL, 0x860d8b8bUL, 0x850f8a8aUL, | ||
459 | 0x90e07070UL, 0x427c3e3eUL, 0xc471b5b5UL, 0xaacc6666UL, | ||
460 | 0xd8904848UL, 0x05060303UL, 0x01f7f6f6UL, 0x121c0e0eUL, | ||
461 | 0xa3c26161UL, 0x5f6a3535UL, 0xf9ae5757UL, 0xd069b9b9UL, | ||
462 | 0x91178686UL, 0x5899c1c1UL, 0x273a1d1dUL, 0xb9279e9eUL, | ||
463 | 0x38d9e1e1UL, 0x13ebf8f8UL, 0xb32b9898UL, 0x33221111UL, | ||
464 | 0xbbd26969UL, 0x70a9d9d9UL, 0x89078e8eUL, 0xa7339494UL, | ||
465 | 0xb62d9b9bUL, 0x223c1e1eUL, 0x92158787UL, 0x20c9e9e9UL, | ||
466 | 0x4987ceceUL, 0xffaa5555UL, 0x78502828UL, 0x7aa5dfdfUL, | ||
467 | 0x8f038c8cUL, 0xf859a1a1UL, 0x80098989UL, 0x171a0d0dUL, | ||
468 | 0xda65bfbfUL, 0x31d7e6e6UL, 0xc6844242UL, 0xb8d06868UL, | ||
469 | 0xc3824141UL, 0xb0299999UL, 0x775a2d2dUL, 0x111e0f0fUL, | ||
470 | 0xcb7bb0b0UL, 0xfca85454UL, 0xd66dbbbbUL, 0x3a2c1616UL, | ||
471 | }; | ||
472 | static const uint32 TE2[256] = { | ||
473 | 0x63a5c663UL, 0x7c84f87cUL, 0x7799ee77UL, 0x7b8df67bUL, | ||
474 | 0xf20dfff2UL, 0x6bbdd66bUL, 0x6fb1de6fUL, 0xc55491c5UL, | ||
475 | 0x30506030UL, 0x01030201UL, 0x67a9ce67UL, 0x2b7d562bUL, | ||
476 | 0xfe19e7feUL, 0xd762b5d7UL, 0xabe64dabUL, 0x769aec76UL, | ||
477 | 0xca458fcaUL, 0x829d1f82UL, 0xc94089c9UL, 0x7d87fa7dUL, | ||
478 | 0xfa15effaUL, 0x59ebb259UL, 0x47c98e47UL, 0xf00bfbf0UL, | ||
479 | 0xadec41adUL, 0xd467b3d4UL, 0xa2fd5fa2UL, 0xafea45afUL, | ||
480 | 0x9cbf239cUL, 0xa4f753a4UL, 0x7296e472UL, 0xc05b9bc0UL, | ||
481 | 0xb7c275b7UL, 0xfd1ce1fdUL, 0x93ae3d93UL, 0x266a4c26UL, | ||
482 | 0x365a6c36UL, 0x3f417e3fUL, 0xf702f5f7UL, 0xcc4f83ccUL, | ||
483 | 0x345c6834UL, 0xa5f451a5UL, 0xe534d1e5UL, 0xf108f9f1UL, | ||
484 | 0x7193e271UL, 0xd873abd8UL, 0x31536231UL, 0x153f2a15UL, | ||
485 | 0x040c0804UL, 0xc75295c7UL, 0x23654623UL, 0xc35e9dc3UL, | ||
486 | 0x18283018UL, 0x96a13796UL, 0x050f0a05UL, 0x9ab52f9aUL, | ||
487 | 0x07090e07UL, 0x12362412UL, 0x809b1b80UL, 0xe23ddfe2UL, | ||
488 | 0xeb26cdebUL, 0x27694e27UL, 0xb2cd7fb2UL, 0x759fea75UL, | ||
489 | 0x091b1209UL, 0x839e1d83UL, 0x2c74582cUL, 0x1a2e341aUL, | ||
490 | 0x1b2d361bUL, 0x6eb2dc6eUL, 0x5aeeb45aUL, 0xa0fb5ba0UL, | ||
491 | 0x52f6a452UL, 0x3b4d763bUL, 0xd661b7d6UL, 0xb3ce7db3UL, | ||
492 | 0x297b5229UL, 0xe33edde3UL, 0x2f715e2fUL, 0x84971384UL, | ||
493 | 0x53f5a653UL, 0xd168b9d1UL, 0x00000000UL, 0xed2cc1edUL, | ||
494 | 0x20604020UL, 0xfc1fe3fcUL, 0xb1c879b1UL, 0x5bedb65bUL, | ||
495 | 0x6abed46aUL, 0xcb468dcbUL, 0xbed967beUL, 0x394b7239UL, | ||
496 | 0x4ade944aUL, 0x4cd4984cUL, 0x58e8b058UL, 0xcf4a85cfUL, | ||
497 | 0xd06bbbd0UL, 0xef2ac5efUL, 0xaae54faaUL, 0xfb16edfbUL, | ||
498 | 0x43c58643UL, 0x4dd79a4dUL, 0x33556633UL, 0x85941185UL, | ||
499 | 0x45cf8a45UL, 0xf910e9f9UL, 0x02060402UL, 0x7f81fe7fUL, | ||
500 | 0x50f0a050UL, 0x3c44783cUL, 0x9fba259fUL, 0xa8e34ba8UL, | ||
501 | 0x51f3a251UL, 0xa3fe5da3UL, 0x40c08040UL, 0x8f8a058fUL, | ||
502 | 0x92ad3f92UL, 0x9dbc219dUL, 0x38487038UL, 0xf504f1f5UL, | ||
503 | 0xbcdf63bcUL, 0xb6c177b6UL, 0xda75afdaUL, 0x21634221UL, | ||
504 | 0x10302010UL, 0xff1ae5ffUL, 0xf30efdf3UL, 0xd26dbfd2UL, | ||
505 | 0xcd4c81cdUL, 0x0c14180cUL, 0x13352613UL, 0xec2fc3ecUL, | ||
506 | 0x5fe1be5fUL, 0x97a23597UL, 0x44cc8844UL, 0x17392e17UL, | ||
507 | 0xc45793c4UL, 0xa7f255a7UL, 0x7e82fc7eUL, 0x3d477a3dUL, | ||
508 | 0x64acc864UL, 0x5de7ba5dUL, 0x192b3219UL, 0x7395e673UL, | ||
509 | 0x60a0c060UL, 0x81981981UL, 0x4fd19e4fUL, 0xdc7fa3dcUL, | ||
510 | 0x22664422UL, 0x2a7e542aUL, 0x90ab3b90UL, 0x88830b88UL, | ||
511 | 0x46ca8c46UL, 0xee29c7eeUL, 0xb8d36bb8UL, 0x143c2814UL, | ||
512 | 0xde79a7deUL, 0x5ee2bc5eUL, 0x0b1d160bUL, 0xdb76addbUL, | ||
513 | 0xe03bdbe0UL, 0x32566432UL, 0x3a4e743aUL, 0x0a1e140aUL, | ||
514 | 0x49db9249UL, 0x060a0c06UL, 0x246c4824UL, 0x5ce4b85cUL, | ||
515 | 0xc25d9fc2UL, 0xd36ebdd3UL, 0xacef43acUL, 0x62a6c462UL, | ||
516 | 0x91a83991UL, 0x95a43195UL, 0xe437d3e4UL, 0x798bf279UL, | ||
517 | 0xe732d5e7UL, 0xc8438bc8UL, 0x37596e37UL, 0x6db7da6dUL, | ||
518 | 0x8d8c018dUL, 0xd564b1d5UL, 0x4ed29c4eUL, 0xa9e049a9UL, | ||
519 | 0x6cb4d86cUL, 0x56faac56UL, 0xf407f3f4UL, 0xea25cfeaUL, | ||
520 | 0x65afca65UL, 0x7a8ef47aUL, 0xaee947aeUL, 0x08181008UL, | ||
521 | 0xbad56fbaUL, 0x7888f078UL, 0x256f4a25UL, 0x2e725c2eUL, | ||
522 | 0x1c24381cUL, 0xa6f157a6UL, 0xb4c773b4UL, 0xc65197c6UL, | ||
523 | 0xe823cbe8UL, 0xdd7ca1ddUL, 0x749ce874UL, 0x1f213e1fUL, | ||
524 | 0x4bdd964bUL, 0xbddc61bdUL, 0x8b860d8bUL, 0x8a850f8aUL, | ||
525 | 0x7090e070UL, 0x3e427c3eUL, 0xb5c471b5UL, 0x66aacc66UL, | ||
526 | 0x48d89048UL, 0x03050603UL, 0xf601f7f6UL, 0x0e121c0eUL, | ||
527 | 0x61a3c261UL, 0x355f6a35UL, 0x57f9ae57UL, 0xb9d069b9UL, | ||
528 | 0x86911786UL, 0xc15899c1UL, 0x1d273a1dUL, 0x9eb9279eUL, | ||
529 | 0xe138d9e1UL, 0xf813ebf8UL, 0x98b32b98UL, 0x11332211UL, | ||
530 | 0x69bbd269UL, 0xd970a9d9UL, 0x8e89078eUL, 0x94a73394UL, | ||
531 | 0x9bb62d9bUL, 0x1e223c1eUL, 0x87921587UL, 0xe920c9e9UL, | ||
532 | 0xce4987ceUL, 0x55ffaa55UL, 0x28785028UL, 0xdf7aa5dfUL, | ||
533 | 0x8c8f038cUL, 0xa1f859a1UL, 0x89800989UL, 0x0d171a0dUL, | ||
534 | 0xbfda65bfUL, 0xe631d7e6UL, 0x42c68442UL, 0x68b8d068UL, | ||
535 | 0x41c38241UL, 0x99b02999UL, 0x2d775a2dUL, 0x0f111e0fUL, | ||
536 | 0xb0cb7bb0UL, 0x54fca854UL, 0xbbd66dbbUL, 0x163a2c16UL, | ||
537 | }; | ||
538 | static const uint32 TE3[256] = { | ||
539 | |||
540 | 0x6363a5c6UL, 0x7c7c84f8UL, 0x777799eeUL, 0x7b7b8df6UL, | ||
541 | 0xf2f20dffUL, 0x6b6bbdd6UL, 0x6f6fb1deUL, 0xc5c55491UL, | ||
542 | 0x30305060UL, 0x01010302UL, 0x6767a9ceUL, 0x2b2b7d56UL, | ||
543 | 0xfefe19e7UL, 0xd7d762b5UL, 0xababe64dUL, 0x76769aecUL, | ||
544 | 0xcaca458fUL, 0x82829d1fUL, 0xc9c94089UL, 0x7d7d87faUL, | ||
545 | 0xfafa15efUL, 0x5959ebb2UL, 0x4747c98eUL, 0xf0f00bfbUL, | ||
546 | 0xadadec41UL, 0xd4d467b3UL, 0xa2a2fd5fUL, 0xafafea45UL, | ||
547 | 0x9c9cbf23UL, 0xa4a4f753UL, 0x727296e4UL, 0xc0c05b9bUL, | ||
548 | 0xb7b7c275UL, 0xfdfd1ce1UL, 0x9393ae3dUL, 0x26266a4cUL, | ||
549 | 0x36365a6cUL, 0x3f3f417eUL, 0xf7f702f5UL, 0xcccc4f83UL, | ||
550 | 0x34345c68UL, 0xa5a5f451UL, 0xe5e534d1UL, 0xf1f108f9UL, | ||
551 | 0x717193e2UL, 0xd8d873abUL, 0x31315362UL, 0x15153f2aUL, | ||
552 | 0x04040c08UL, 0xc7c75295UL, 0x23236546UL, 0xc3c35e9dUL, | ||
553 | 0x18182830UL, 0x9696a137UL, 0x05050f0aUL, 0x9a9ab52fUL, | ||
554 | 0x0707090eUL, 0x12123624UL, 0x80809b1bUL, 0xe2e23ddfUL, | ||
555 | 0xebeb26cdUL, 0x2727694eUL, 0xb2b2cd7fUL, 0x75759feaUL, | ||
556 | 0x09091b12UL, 0x83839e1dUL, 0x2c2c7458UL, 0x1a1a2e34UL, | ||
557 | 0x1b1b2d36UL, 0x6e6eb2dcUL, 0x5a5aeeb4UL, 0xa0a0fb5bUL, | ||
558 | 0x5252f6a4UL, 0x3b3b4d76UL, 0xd6d661b7UL, 0xb3b3ce7dUL, | ||
559 | 0x29297b52UL, 0xe3e33eddUL, 0x2f2f715eUL, 0x84849713UL, | ||
560 | 0x5353f5a6UL, 0xd1d168b9UL, 0x00000000UL, 0xeded2cc1UL, | ||
561 | 0x20206040UL, 0xfcfc1fe3UL, 0xb1b1c879UL, 0x5b5bedb6UL, | ||
562 | 0x6a6abed4UL, 0xcbcb468dUL, 0xbebed967UL, 0x39394b72UL, | ||
563 | 0x4a4ade94UL, 0x4c4cd498UL, 0x5858e8b0UL, 0xcfcf4a85UL, | ||
564 | 0xd0d06bbbUL, 0xefef2ac5UL, 0xaaaae54fUL, 0xfbfb16edUL, | ||
565 | 0x4343c586UL, 0x4d4dd79aUL, 0x33335566UL, 0x85859411UL, | ||
566 | 0x4545cf8aUL, 0xf9f910e9UL, 0x02020604UL, 0x7f7f81feUL, | ||
567 | 0x5050f0a0UL, 0x3c3c4478UL, 0x9f9fba25UL, 0xa8a8e34bUL, | ||
568 | 0x5151f3a2UL, 0xa3a3fe5dUL, 0x4040c080UL, 0x8f8f8a05UL, | ||
569 | 0x9292ad3fUL, 0x9d9dbc21UL, 0x38384870UL, 0xf5f504f1UL, | ||
570 | 0xbcbcdf63UL, 0xb6b6c177UL, 0xdada75afUL, 0x21216342UL, | ||
571 | 0x10103020UL, 0xffff1ae5UL, 0xf3f30efdUL, 0xd2d26dbfUL, | ||
572 | 0xcdcd4c81UL, 0x0c0c1418UL, 0x13133526UL, 0xecec2fc3UL, | ||
573 | 0x5f5fe1beUL, 0x9797a235UL, 0x4444cc88UL, 0x1717392eUL, | ||
574 | 0xc4c45793UL, 0xa7a7f255UL, 0x7e7e82fcUL, 0x3d3d477aUL, | ||
575 | 0x6464acc8UL, 0x5d5de7baUL, 0x19192b32UL, 0x737395e6UL, | ||
576 | 0x6060a0c0UL, 0x81819819UL, 0x4f4fd19eUL, 0xdcdc7fa3UL, | ||
577 | 0x22226644UL, 0x2a2a7e54UL, 0x9090ab3bUL, 0x8888830bUL, | ||
578 | 0x4646ca8cUL, 0xeeee29c7UL, 0xb8b8d36bUL, 0x14143c28UL, | ||
579 | 0xdede79a7UL, 0x5e5ee2bcUL, 0x0b0b1d16UL, 0xdbdb76adUL, | ||
580 | 0xe0e03bdbUL, 0x32325664UL, 0x3a3a4e74UL, 0x0a0a1e14UL, | ||
581 | 0x4949db92UL, 0x06060a0cUL, 0x24246c48UL, 0x5c5ce4b8UL, | ||
582 | 0xc2c25d9fUL, 0xd3d36ebdUL, 0xacacef43UL, 0x6262a6c4UL, | ||
583 | 0x9191a839UL, 0x9595a431UL, 0xe4e437d3UL, 0x79798bf2UL, | ||
584 | 0xe7e732d5UL, 0xc8c8438bUL, 0x3737596eUL, 0x6d6db7daUL, | ||
585 | 0x8d8d8c01UL, 0xd5d564b1UL, 0x4e4ed29cUL, 0xa9a9e049UL, | ||
586 | 0x6c6cb4d8UL, 0x5656faacUL, 0xf4f407f3UL, 0xeaea25cfUL, | ||
587 | 0x6565afcaUL, 0x7a7a8ef4UL, 0xaeaee947UL, 0x08081810UL, | ||
588 | 0xbabad56fUL, 0x787888f0UL, 0x25256f4aUL, 0x2e2e725cUL, | ||
589 | 0x1c1c2438UL, 0xa6a6f157UL, 0xb4b4c773UL, 0xc6c65197UL, | ||
590 | 0xe8e823cbUL, 0xdddd7ca1UL, 0x74749ce8UL, 0x1f1f213eUL, | ||
591 | 0x4b4bdd96UL, 0xbdbddc61UL, 0x8b8b860dUL, 0x8a8a850fUL, | ||
592 | 0x707090e0UL, 0x3e3e427cUL, 0xb5b5c471UL, 0x6666aaccUL, | ||
593 | 0x4848d890UL, 0x03030506UL, 0xf6f601f7UL, 0x0e0e121cUL, | ||
594 | 0x6161a3c2UL, 0x35355f6aUL, 0x5757f9aeUL, 0xb9b9d069UL, | ||
595 | 0x86869117UL, 0xc1c15899UL, 0x1d1d273aUL, 0x9e9eb927UL, | ||
596 | 0xe1e138d9UL, 0xf8f813ebUL, 0x9898b32bUL, 0x11113322UL, | ||
597 | 0x6969bbd2UL, 0xd9d970a9UL, 0x8e8e8907UL, 0x9494a733UL, | ||
598 | 0x9b9bb62dUL, 0x1e1e223cUL, 0x87879215UL, 0xe9e920c9UL, | ||
599 | 0xcece4987UL, 0x5555ffaaUL, 0x28287850UL, 0xdfdf7aa5UL, | ||
600 | 0x8c8c8f03UL, 0xa1a1f859UL, 0x89898009UL, 0x0d0d171aUL, | ||
601 | 0xbfbfda65UL, 0xe6e631d7UL, 0x4242c684UL, 0x6868b8d0UL, | ||
602 | 0x4141c382UL, 0x9999b029UL, 0x2d2d775aUL, 0x0f0f111eUL, | ||
603 | 0xb0b0cb7bUL, 0x5454fca8UL, 0xbbbbd66dUL, 0x16163a2cUL, | ||
604 | }; | ||
605 | |||
606 | static const uint32 Te4_0[] = { | ||
607 | 0x00000063UL, 0x0000007cUL, 0x00000077UL, 0x0000007bUL, 0x000000f2UL, 0x0000006bUL, 0x0000006fUL, 0x000000c5UL, | ||
608 | 0x00000030UL, 0x00000001UL, 0x00000067UL, 0x0000002bUL, 0x000000feUL, 0x000000d7UL, 0x000000abUL, 0x00000076UL, | ||
609 | 0x000000caUL, 0x00000082UL, 0x000000c9UL, 0x0000007dUL, 0x000000faUL, 0x00000059UL, 0x00000047UL, 0x000000f0UL, | ||
610 | 0x000000adUL, 0x000000d4UL, 0x000000a2UL, 0x000000afUL, 0x0000009cUL, 0x000000a4UL, 0x00000072UL, 0x000000c0UL, | ||
611 | 0x000000b7UL, 0x000000fdUL, 0x00000093UL, 0x00000026UL, 0x00000036UL, 0x0000003fUL, 0x000000f7UL, 0x000000ccUL, | ||
612 | 0x00000034UL, 0x000000a5UL, 0x000000e5UL, 0x000000f1UL, 0x00000071UL, 0x000000d8UL, 0x00000031UL, 0x00000015UL, | ||
613 | 0x00000004UL, 0x000000c7UL, 0x00000023UL, 0x000000c3UL, 0x00000018UL, 0x00000096UL, 0x00000005UL, 0x0000009aUL, | ||
614 | 0x00000007UL, 0x00000012UL, 0x00000080UL, 0x000000e2UL, 0x000000ebUL, 0x00000027UL, 0x000000b2UL, 0x00000075UL, | ||
615 | 0x00000009UL, 0x00000083UL, 0x0000002cUL, 0x0000001aUL, 0x0000001bUL, 0x0000006eUL, 0x0000005aUL, 0x000000a0UL, | ||
616 | 0x00000052UL, 0x0000003bUL, 0x000000d6UL, 0x000000b3UL, 0x00000029UL, 0x000000e3UL, 0x0000002fUL, 0x00000084UL, | ||
617 | 0x00000053UL, 0x000000d1UL, 0x00000000UL, 0x000000edUL, 0x00000020UL, 0x000000fcUL, 0x000000b1UL, 0x0000005bUL, | ||
618 | 0x0000006aUL, 0x000000cbUL, 0x000000beUL, 0x00000039UL, 0x0000004aUL, 0x0000004cUL, 0x00000058UL, 0x000000cfUL, | ||
619 | 0x000000d0UL, 0x000000efUL, 0x000000aaUL, 0x000000fbUL, 0x00000043UL, 0x0000004dUL, 0x00000033UL, 0x00000085UL, | ||
620 | 0x00000045UL, 0x000000f9UL, 0x00000002UL, 0x0000007fUL, 0x00000050UL, 0x0000003cUL, 0x0000009fUL, 0x000000a8UL, | ||
621 | 0x00000051UL, 0x000000a3UL, 0x00000040UL, 0x0000008fUL, 0x00000092UL, 0x0000009dUL, 0x00000038UL, 0x000000f5UL, | ||
622 | 0x000000bcUL, 0x000000b6UL, 0x000000daUL, 0x00000021UL, 0x00000010UL, 0x000000ffUL, 0x000000f3UL, 0x000000d2UL, | ||
623 | 0x000000cdUL, 0x0000000cUL, 0x00000013UL, 0x000000ecUL, 0x0000005fUL, 0x00000097UL, 0x00000044UL, 0x00000017UL, | ||
624 | 0x000000c4UL, 0x000000a7UL, 0x0000007eUL, 0x0000003dUL, 0x00000064UL, 0x0000005dUL, 0x00000019UL, 0x00000073UL, | ||
625 | 0x00000060UL, 0x00000081UL, 0x0000004fUL, 0x000000dcUL, 0x00000022UL, 0x0000002aUL, 0x00000090UL, 0x00000088UL, | ||
626 | 0x00000046UL, 0x000000eeUL, 0x000000b8UL, 0x00000014UL, 0x000000deUL, 0x0000005eUL, 0x0000000bUL, 0x000000dbUL, | ||
627 | 0x000000e0UL, 0x00000032UL, 0x0000003aUL, 0x0000000aUL, 0x00000049UL, 0x00000006UL, 0x00000024UL, 0x0000005cUL, | ||
628 | 0x000000c2UL, 0x000000d3UL, 0x000000acUL, 0x00000062UL, 0x00000091UL, 0x00000095UL, 0x000000e4UL, 0x00000079UL, | ||
629 | 0x000000e7UL, 0x000000c8UL, 0x00000037UL, 0x0000006dUL, 0x0000008dUL, 0x000000d5UL, 0x0000004eUL, 0x000000a9UL, | ||
630 | 0x0000006cUL, 0x00000056UL, 0x000000f4UL, 0x000000eaUL, 0x00000065UL, 0x0000007aUL, 0x000000aeUL, 0x00000008UL, | ||
631 | 0x000000baUL, 0x00000078UL, 0x00000025UL, 0x0000002eUL, 0x0000001cUL, 0x000000a6UL, 0x000000b4UL, 0x000000c6UL, | ||
632 | 0x000000e8UL, 0x000000ddUL, 0x00000074UL, 0x0000001fUL, 0x0000004bUL, 0x000000bdUL, 0x0000008bUL, 0x0000008aUL, | ||
633 | 0x00000070UL, 0x0000003eUL, 0x000000b5UL, 0x00000066UL, 0x00000048UL, 0x00000003UL, 0x000000f6UL, 0x0000000eUL, | ||
634 | 0x00000061UL, 0x00000035UL, 0x00000057UL, 0x000000b9UL, 0x00000086UL, 0x000000c1UL, 0x0000001dUL, 0x0000009eUL, | ||
635 | 0x000000e1UL, 0x000000f8UL, 0x00000098UL, 0x00000011UL, 0x00000069UL, 0x000000d9UL, 0x0000008eUL, 0x00000094UL, | ||
636 | 0x0000009bUL, 0x0000001eUL, 0x00000087UL, 0x000000e9UL, 0x000000ceUL, 0x00000055UL, 0x00000028UL, 0x000000dfUL, | ||
637 | 0x0000008cUL, 0x000000a1UL, 0x00000089UL, 0x0000000dUL, 0x000000bfUL, 0x000000e6UL, 0x00000042UL, 0x00000068UL, | ||
638 | 0x00000041UL, 0x00000099UL, 0x0000002dUL, 0x0000000fUL, 0x000000b0UL, 0x00000054UL, 0x000000bbUL, 0x00000016UL | ||
639 | }; | ||
640 | |||
641 | static const uint32 Te4_1[] = { | ||
642 | 0x00006300UL, 0x00007c00UL, 0x00007700UL, 0x00007b00UL, 0x0000f200UL, 0x00006b00UL, 0x00006f00UL, 0x0000c500UL, | ||
643 | 0x00003000UL, 0x00000100UL, 0x00006700UL, 0x00002b00UL, 0x0000fe00UL, 0x0000d700UL, 0x0000ab00UL, 0x00007600UL, | ||
644 | 0x0000ca00UL, 0x00008200UL, 0x0000c900UL, 0x00007d00UL, 0x0000fa00UL, 0x00005900UL, 0x00004700UL, 0x0000f000UL, | ||
645 | 0x0000ad00UL, 0x0000d400UL, 0x0000a200UL, 0x0000af00UL, 0x00009c00UL, 0x0000a400UL, 0x00007200UL, 0x0000c000UL, | ||
646 | 0x0000b700UL, 0x0000fd00UL, 0x00009300UL, 0x00002600UL, 0x00003600UL, 0x00003f00UL, 0x0000f700UL, 0x0000cc00UL, | ||
647 | 0x00003400UL, 0x0000a500UL, 0x0000e500UL, 0x0000f100UL, 0x00007100UL, 0x0000d800UL, 0x00003100UL, 0x00001500UL, | ||
648 | 0x00000400UL, 0x0000c700UL, 0x00002300UL, 0x0000c300UL, 0x00001800UL, 0x00009600UL, 0x00000500UL, 0x00009a00UL, | ||
649 | 0x00000700UL, 0x00001200UL, 0x00008000UL, 0x0000e200UL, 0x0000eb00UL, 0x00002700UL, 0x0000b200UL, 0x00007500UL, | ||
650 | 0x00000900UL, 0x00008300UL, 0x00002c00UL, 0x00001a00UL, 0x00001b00UL, 0x00006e00UL, 0x00005a00UL, 0x0000a000UL, | ||
651 | 0x00005200UL, 0x00003b00UL, 0x0000d600UL, 0x0000b300UL, 0x00002900UL, 0x0000e300UL, 0x00002f00UL, 0x00008400UL, | ||
652 | 0x00005300UL, 0x0000d100UL, 0x00000000UL, 0x0000ed00UL, 0x00002000UL, 0x0000fc00UL, 0x0000b100UL, 0x00005b00UL, | ||
653 | 0x00006a00UL, 0x0000cb00UL, 0x0000be00UL, 0x00003900UL, 0x00004a00UL, 0x00004c00UL, 0x00005800UL, 0x0000cf00UL, | ||
654 | 0x0000d000UL, 0x0000ef00UL, 0x0000aa00UL, 0x0000fb00UL, 0x00004300UL, 0x00004d00UL, 0x00003300UL, 0x00008500UL, | ||
655 | 0x00004500UL, 0x0000f900UL, 0x00000200UL, 0x00007f00UL, 0x00005000UL, 0x00003c00UL, 0x00009f00UL, 0x0000a800UL, | ||
656 | 0x00005100UL, 0x0000a300UL, 0x00004000UL, 0x00008f00UL, 0x00009200UL, 0x00009d00UL, 0x00003800UL, 0x0000f500UL, | ||
657 | 0x0000bc00UL, 0x0000b600UL, 0x0000da00UL, 0x00002100UL, 0x00001000UL, 0x0000ff00UL, 0x0000f300UL, 0x0000d200UL, | ||
658 | 0x0000cd00UL, 0x00000c00UL, 0x00001300UL, 0x0000ec00UL, 0x00005f00UL, 0x00009700UL, 0x00004400UL, 0x00001700UL, | ||
659 | 0x0000c400UL, 0x0000a700UL, 0x00007e00UL, 0x00003d00UL, 0x00006400UL, 0x00005d00UL, 0x00001900UL, 0x00007300UL, | ||
660 | 0x00006000UL, 0x00008100UL, 0x00004f00UL, 0x0000dc00UL, 0x00002200UL, 0x00002a00UL, 0x00009000UL, 0x00008800UL, | ||
661 | 0x00004600UL, 0x0000ee00UL, 0x0000b800UL, 0x00001400UL, 0x0000de00UL, 0x00005e00UL, 0x00000b00UL, 0x0000db00UL, | ||
662 | 0x0000e000UL, 0x00003200UL, 0x00003a00UL, 0x00000a00UL, 0x00004900UL, 0x00000600UL, 0x00002400UL, 0x00005c00UL, | ||
663 | 0x0000c200UL, 0x0000d300UL, 0x0000ac00UL, 0x00006200UL, 0x00009100UL, 0x00009500UL, 0x0000e400UL, 0x00007900UL, | ||
664 | 0x0000e700UL, 0x0000c800UL, 0x00003700UL, 0x00006d00UL, 0x00008d00UL, 0x0000d500UL, 0x00004e00UL, 0x0000a900UL, | ||
665 | 0x00006c00UL, 0x00005600UL, 0x0000f400UL, 0x0000ea00UL, 0x00006500UL, 0x00007a00UL, 0x0000ae00UL, 0x00000800UL, | ||
666 | 0x0000ba00UL, 0x00007800UL, 0x00002500UL, 0x00002e00UL, 0x00001c00UL, 0x0000a600UL, 0x0000b400UL, 0x0000c600UL, | ||
667 | 0x0000e800UL, 0x0000dd00UL, 0x00007400UL, 0x00001f00UL, 0x00004b00UL, 0x0000bd00UL, 0x00008b00UL, 0x00008a00UL, | ||
668 | 0x00007000UL, 0x00003e00UL, 0x0000b500UL, 0x00006600UL, 0x00004800UL, 0x00000300UL, 0x0000f600UL, 0x00000e00UL, | ||
669 | 0x00006100UL, 0x00003500UL, 0x00005700UL, 0x0000b900UL, 0x00008600UL, 0x0000c100UL, 0x00001d00UL, 0x00009e00UL, | ||
670 | 0x0000e100UL, 0x0000f800UL, 0x00009800UL, 0x00001100UL, 0x00006900UL, 0x0000d900UL, 0x00008e00UL, 0x00009400UL, | ||
671 | 0x00009b00UL, 0x00001e00UL, 0x00008700UL, 0x0000e900UL, 0x0000ce00UL, 0x00005500UL, 0x00002800UL, 0x0000df00UL, | ||
672 | 0x00008c00UL, 0x0000a100UL, 0x00008900UL, 0x00000d00UL, 0x0000bf00UL, 0x0000e600UL, 0x00004200UL, 0x00006800UL, | ||
673 | 0x00004100UL, 0x00009900UL, 0x00002d00UL, 0x00000f00UL, 0x0000b000UL, 0x00005400UL, 0x0000bb00UL, 0x00001600UL | ||
674 | }; | ||
675 | |||
676 | static const uint32 Te4_2[] = { | ||
677 | 0x00630000UL, 0x007c0000UL, 0x00770000UL, 0x007b0000UL, 0x00f20000UL, 0x006b0000UL, 0x006f0000UL, 0x00c50000UL, | ||
678 | 0x00300000UL, 0x00010000UL, 0x00670000UL, 0x002b0000UL, 0x00fe0000UL, 0x00d70000UL, 0x00ab0000UL, 0x00760000UL, | ||
679 | 0x00ca0000UL, 0x00820000UL, 0x00c90000UL, 0x007d0000UL, 0x00fa0000UL, 0x00590000UL, 0x00470000UL, 0x00f00000UL, | ||
680 | 0x00ad0000UL, 0x00d40000UL, 0x00a20000UL, 0x00af0000UL, 0x009c0000UL, 0x00a40000UL, 0x00720000UL, 0x00c00000UL, | ||
681 | 0x00b70000UL, 0x00fd0000UL, 0x00930000UL, 0x00260000UL, 0x00360000UL, 0x003f0000UL, 0x00f70000UL, 0x00cc0000UL, | ||
682 | 0x00340000UL, 0x00a50000UL, 0x00e50000UL, 0x00f10000UL, 0x00710000UL, 0x00d80000UL, 0x00310000UL, 0x00150000UL, | ||
683 | 0x00040000UL, 0x00c70000UL, 0x00230000UL, 0x00c30000UL, 0x00180000UL, 0x00960000UL, 0x00050000UL, 0x009a0000UL, | ||
684 | 0x00070000UL, 0x00120000UL, 0x00800000UL, 0x00e20000UL, 0x00eb0000UL, 0x00270000UL, 0x00b20000UL, 0x00750000UL, | ||
685 | 0x00090000UL, 0x00830000UL, 0x002c0000UL, 0x001a0000UL, 0x001b0000UL, 0x006e0000UL, 0x005a0000UL, 0x00a00000UL, | ||
686 | 0x00520000UL, 0x003b0000UL, 0x00d60000UL, 0x00b30000UL, 0x00290000UL, 0x00e30000UL, 0x002f0000UL, 0x00840000UL, | ||
687 | 0x00530000UL, 0x00d10000UL, 0x00000000UL, 0x00ed0000UL, 0x00200000UL, 0x00fc0000UL, 0x00b10000UL, 0x005b0000UL, | ||
688 | 0x006a0000UL, 0x00cb0000UL, 0x00be0000UL, 0x00390000UL, 0x004a0000UL, 0x004c0000UL, 0x00580000UL, 0x00cf0000UL, | ||
689 | 0x00d00000UL, 0x00ef0000UL, 0x00aa0000UL, 0x00fb0000UL, 0x00430000UL, 0x004d0000UL, 0x00330000UL, 0x00850000UL, | ||
690 | 0x00450000UL, 0x00f90000UL, 0x00020000UL, 0x007f0000UL, 0x00500000UL, 0x003c0000UL, 0x009f0000UL, 0x00a80000UL, | ||
691 | 0x00510000UL, 0x00a30000UL, 0x00400000UL, 0x008f0000UL, 0x00920000UL, 0x009d0000UL, 0x00380000UL, 0x00f50000UL, | ||
692 | 0x00bc0000UL, 0x00b60000UL, 0x00da0000UL, 0x00210000UL, 0x00100000UL, 0x00ff0000UL, 0x00f30000UL, 0x00d20000UL, | ||
693 | 0x00cd0000UL, 0x000c0000UL, 0x00130000UL, 0x00ec0000UL, 0x005f0000UL, 0x00970000UL, 0x00440000UL, 0x00170000UL, | ||
694 | 0x00c40000UL, 0x00a70000UL, 0x007e0000UL, 0x003d0000UL, 0x00640000UL, 0x005d0000UL, 0x00190000UL, 0x00730000UL, | ||
695 | 0x00600000UL, 0x00810000UL, 0x004f0000UL, 0x00dc0000UL, 0x00220000UL, 0x002a0000UL, 0x00900000UL, 0x00880000UL, | ||
696 | 0x00460000UL, 0x00ee0000UL, 0x00b80000UL, 0x00140000UL, 0x00de0000UL, 0x005e0000UL, 0x000b0000UL, 0x00db0000UL, | ||
697 | 0x00e00000UL, 0x00320000UL, 0x003a0000UL, 0x000a0000UL, 0x00490000UL, 0x00060000UL, 0x00240000UL, 0x005c0000UL, | ||
698 | 0x00c20000UL, 0x00d30000UL, 0x00ac0000UL, 0x00620000UL, 0x00910000UL, 0x00950000UL, 0x00e40000UL, 0x00790000UL, | ||
699 | 0x00e70000UL, 0x00c80000UL, 0x00370000UL, 0x006d0000UL, 0x008d0000UL, 0x00d50000UL, 0x004e0000UL, 0x00a90000UL, | ||
700 | 0x006c0000UL, 0x00560000UL, 0x00f40000UL, 0x00ea0000UL, 0x00650000UL, 0x007a0000UL, 0x00ae0000UL, 0x00080000UL, | ||
701 | 0x00ba0000UL, 0x00780000UL, 0x00250000UL, 0x002e0000UL, 0x001c0000UL, 0x00a60000UL, 0x00b40000UL, 0x00c60000UL, | ||
702 | 0x00e80000UL, 0x00dd0000UL, 0x00740000UL, 0x001f0000UL, 0x004b0000UL, 0x00bd0000UL, 0x008b0000UL, 0x008a0000UL, | ||
703 | 0x00700000UL, 0x003e0000UL, 0x00b50000UL, 0x00660000UL, 0x00480000UL, 0x00030000UL, 0x00f60000UL, 0x000e0000UL, | ||
704 | 0x00610000UL, 0x00350000UL, 0x00570000UL, 0x00b90000UL, 0x00860000UL, 0x00c10000UL, 0x001d0000UL, 0x009e0000UL, | ||
705 | 0x00e10000UL, 0x00f80000UL, 0x00980000UL, 0x00110000UL, 0x00690000UL, 0x00d90000UL, 0x008e0000UL, 0x00940000UL, | ||
706 | 0x009b0000UL, 0x001e0000UL, 0x00870000UL, 0x00e90000UL, 0x00ce0000UL, 0x00550000UL, 0x00280000UL, 0x00df0000UL, | ||
707 | 0x008c0000UL, 0x00a10000UL, 0x00890000UL, 0x000d0000UL, 0x00bf0000UL, 0x00e60000UL, 0x00420000UL, 0x00680000UL, | ||
708 | 0x00410000UL, 0x00990000UL, 0x002d0000UL, 0x000f0000UL, 0x00b00000UL, 0x00540000UL, 0x00bb0000UL, 0x00160000UL | ||
709 | }; | ||
710 | |||
711 | static const uint32 Te4_3[] = { | ||
712 | 0x63000000UL, 0x7c000000UL, 0x77000000UL, 0x7b000000UL, 0xf2000000UL, 0x6b000000UL, 0x6f000000UL, 0xc5000000UL, | ||
713 | 0x30000000UL, 0x01000000UL, 0x67000000UL, 0x2b000000UL, 0xfe000000UL, 0xd7000000UL, 0xab000000UL, 0x76000000UL, | ||
714 | 0xca000000UL, 0x82000000UL, 0xc9000000UL, 0x7d000000UL, 0xfa000000UL, 0x59000000UL, 0x47000000UL, 0xf0000000UL, | ||
715 | 0xad000000UL, 0xd4000000UL, 0xa2000000UL, 0xaf000000UL, 0x9c000000UL, 0xa4000000UL, 0x72000000UL, 0xc0000000UL, | ||
716 | 0xb7000000UL, 0xfd000000UL, 0x93000000UL, 0x26000000UL, 0x36000000UL, 0x3f000000UL, 0xf7000000UL, 0xcc000000UL, | ||
717 | 0x34000000UL, 0xa5000000UL, 0xe5000000UL, 0xf1000000UL, 0x71000000UL, 0xd8000000UL, 0x31000000UL, 0x15000000UL, | ||
718 | 0x04000000UL, 0xc7000000UL, 0x23000000UL, 0xc3000000UL, 0x18000000UL, 0x96000000UL, 0x05000000UL, 0x9a000000UL, | ||
719 | 0x07000000UL, 0x12000000UL, 0x80000000UL, 0xe2000000UL, 0xeb000000UL, 0x27000000UL, 0xb2000000UL, 0x75000000UL, | ||
720 | 0x09000000UL, 0x83000000UL, 0x2c000000UL, 0x1a000000UL, 0x1b000000UL, 0x6e000000UL, 0x5a000000UL, 0xa0000000UL, | ||
721 | 0x52000000UL, 0x3b000000UL, 0xd6000000UL, 0xb3000000UL, 0x29000000UL, 0xe3000000UL, 0x2f000000UL, 0x84000000UL, | ||
722 | 0x53000000UL, 0xd1000000UL, 0x00000000UL, 0xed000000UL, 0x20000000UL, 0xfc000000UL, 0xb1000000UL, 0x5b000000UL, | ||
723 | 0x6a000000UL, 0xcb000000UL, 0xbe000000UL, 0x39000000UL, 0x4a000000UL, 0x4c000000UL, 0x58000000UL, 0xcf000000UL, | ||
724 | 0xd0000000UL, 0xef000000UL, 0xaa000000UL, 0xfb000000UL, 0x43000000UL, 0x4d000000UL, 0x33000000UL, 0x85000000UL, | ||
725 | 0x45000000UL, 0xf9000000UL, 0x02000000UL, 0x7f000000UL, 0x50000000UL, 0x3c000000UL, 0x9f000000UL, 0xa8000000UL, | ||
726 | 0x51000000UL, 0xa3000000UL, 0x40000000UL, 0x8f000000UL, 0x92000000UL, 0x9d000000UL, 0x38000000UL, 0xf5000000UL, | ||
727 | 0xbc000000UL, 0xb6000000UL, 0xda000000UL, 0x21000000UL, 0x10000000UL, 0xff000000UL, 0xf3000000UL, 0xd2000000UL, | ||
728 | 0xcd000000UL, 0x0c000000UL, 0x13000000UL, 0xec000000UL, 0x5f000000UL, 0x97000000UL, 0x44000000UL, 0x17000000UL, | ||
729 | 0xc4000000UL, 0xa7000000UL, 0x7e000000UL, 0x3d000000UL, 0x64000000UL, 0x5d000000UL, 0x19000000UL, 0x73000000UL, | ||
730 | 0x60000000UL, 0x81000000UL, 0x4f000000UL, 0xdc000000UL, 0x22000000UL, 0x2a000000UL, 0x90000000UL, 0x88000000UL, | ||
731 | 0x46000000UL, 0xee000000UL, 0xb8000000UL, 0x14000000UL, 0xde000000UL, 0x5e000000UL, 0x0b000000UL, 0xdb000000UL, | ||
732 | 0xe0000000UL, 0x32000000UL, 0x3a000000UL, 0x0a000000UL, 0x49000000UL, 0x06000000UL, 0x24000000UL, 0x5c000000UL, | ||
733 | 0xc2000000UL, 0xd3000000UL, 0xac000000UL, 0x62000000UL, 0x91000000UL, 0x95000000UL, 0xe4000000UL, 0x79000000UL, | ||
734 | 0xe7000000UL, 0xc8000000UL, 0x37000000UL, 0x6d000000UL, 0x8d000000UL, 0xd5000000UL, 0x4e000000UL, 0xa9000000UL, | ||
735 | 0x6c000000UL, 0x56000000UL, 0xf4000000UL, 0xea000000UL, 0x65000000UL, 0x7a000000UL, 0xae000000UL, 0x08000000UL, | ||
736 | 0xba000000UL, 0x78000000UL, 0x25000000UL, 0x2e000000UL, 0x1c000000UL, 0xa6000000UL, 0xb4000000UL, 0xc6000000UL, | ||
737 | 0xe8000000UL, 0xdd000000UL, 0x74000000UL, 0x1f000000UL, 0x4b000000UL, 0xbd000000UL, 0x8b000000UL, 0x8a000000UL, | ||
738 | 0x70000000UL, 0x3e000000UL, 0xb5000000UL, 0x66000000UL, 0x48000000UL, 0x03000000UL, 0xf6000000UL, 0x0e000000UL, | ||
739 | 0x61000000UL, 0x35000000UL, 0x57000000UL, 0xb9000000UL, 0x86000000UL, 0xc1000000UL, 0x1d000000UL, 0x9e000000UL, | ||
740 | 0xe1000000UL, 0xf8000000UL, 0x98000000UL, 0x11000000UL, 0x69000000UL, 0xd9000000UL, 0x8e000000UL, 0x94000000UL, | ||
741 | 0x9b000000UL, 0x1e000000UL, 0x87000000UL, 0xe9000000UL, 0xce000000UL, 0x55000000UL, 0x28000000UL, 0xdf000000UL, | ||
742 | 0x8c000000UL, 0xa1000000UL, 0x89000000UL, 0x0d000000UL, 0xbf000000UL, 0xe6000000UL, 0x42000000UL, 0x68000000UL, | ||
743 | 0x41000000UL, 0x99000000UL, 0x2d000000UL, 0x0f000000UL, 0xb0000000UL, 0x54000000UL, 0xbb000000UL, 0x16000000UL | ||
744 | }; | ||
745 | |||
746 | static const uint32 TD1[256] = { | ||
747 | 0x5051f4a7UL, 0x537e4165UL, 0xc31a17a4UL, 0x963a275eUL, | ||
748 | 0xcb3bab6bUL, 0xf11f9d45UL, 0xabacfa58UL, 0x934be303UL, | ||
749 | 0x552030faUL, 0xf6ad766dUL, 0x9188cc76UL, 0x25f5024cUL, | ||
750 | 0xfc4fe5d7UL, 0xd7c52acbUL, 0x80263544UL, 0x8fb562a3UL, | ||
751 | 0x49deb15aUL, 0x6725ba1bUL, 0x9845ea0eUL, 0xe15dfec0UL, | ||
752 | 0x02c32f75UL, 0x12814cf0UL, 0xa38d4697UL, 0xc66bd3f9UL, | ||
753 | 0xe7038f5fUL, 0x9515929cUL, 0xebbf6d7aUL, 0xda955259UL, | ||
754 | 0x2dd4be83UL, 0xd3587421UL, 0x2949e069UL, 0x448ec9c8UL, | ||
755 | 0x6a75c289UL, 0x78f48e79UL, 0x6b99583eUL, 0xdd27b971UL, | ||
756 | 0xb6bee14fUL, 0x17f088adUL, 0x66c920acUL, 0xb47dce3aUL, | ||
757 | 0x1863df4aUL, 0x82e51a31UL, 0x60975133UL, 0x4562537fUL, | ||
758 | 0xe0b16477UL, 0x84bb6baeUL, 0x1cfe81a0UL, 0x94f9082bUL, | ||
759 | 0x58704868UL, 0x198f45fdUL, 0x8794de6cUL, 0xb7527bf8UL, | ||
760 | 0x23ab73d3UL, 0xe2724b02UL, 0x57e31f8fUL, 0x2a6655abUL, | ||
761 | 0x07b2eb28UL, 0x032fb5c2UL, 0x9a86c57bUL, 0xa5d33708UL, | ||
762 | 0xf2302887UL, 0xb223bfa5UL, 0xba02036aUL, 0x5ced1682UL, | ||
763 | 0x2b8acf1cUL, 0x92a779b4UL, 0xf0f307f2UL, 0xa14e69e2UL, | ||
764 | 0xcd65daf4UL, 0xd50605beUL, 0x1fd13462UL, 0x8ac4a6feUL, | ||
765 | 0x9d342e53UL, 0xa0a2f355UL, 0x32058ae1UL, 0x75a4f6ebUL, | ||
766 | 0x390b83ecUL, 0xaa4060efUL, 0x065e719fUL, 0x51bd6e10UL, | ||
767 | 0xf93e218aUL, 0x3d96dd06UL, 0xaedd3e05UL, 0x464de6bdUL, | ||
768 | 0xb591548dUL, 0x0571c45dUL, 0x6f0406d4UL, 0xff605015UL, | ||
769 | 0x241998fbUL, 0x97d6bde9UL, 0xcc894043UL, 0x7767d99eUL, | ||
770 | 0xbdb0e842UL, 0x8807898bUL, 0x38e7195bUL, 0xdb79c8eeUL, | ||
771 | 0x47a17c0aUL, 0xe97c420fUL, 0xc9f8841eUL, 0x00000000UL, | ||
772 | 0x83098086UL, 0x48322bedUL, 0xac1e1170UL, 0x4e6c5a72UL, | ||
773 | 0xfbfd0effUL, 0x560f8538UL, 0x1e3daed5UL, 0x27362d39UL, | ||
774 | 0x640a0fd9UL, 0x21685ca6UL, 0xd19b5b54UL, 0x3a24362eUL, | ||
775 | 0xb10c0a67UL, 0x0f9357e7UL, 0xd2b4ee96UL, 0x9e1b9b91UL, | ||
776 | 0x4f80c0c5UL, 0xa261dc20UL, 0x695a774bUL, 0x161c121aUL, | ||
777 | 0x0ae293baUL, 0xe5c0a02aUL, 0x433c22e0UL, 0x1d121b17UL, | ||
778 | 0x0b0e090dUL, 0xadf28bc7UL, 0xb92db6a8UL, 0xc8141ea9UL, | ||
779 | 0x8557f119UL, 0x4caf7507UL, 0xbbee99ddUL, 0xfda37f60UL, | ||
780 | 0x9ff70126UL, 0xbc5c72f5UL, 0xc544663bUL, 0x345bfb7eUL, | ||
781 | 0x768b4329UL, 0xdccb23c6UL, 0x68b6edfcUL, 0x63b8e4f1UL, | ||
782 | 0xcad731dcUL, 0x10426385UL, 0x40139722UL, 0x2084c611UL, | ||
783 | 0x7d854a24UL, 0xf8d2bb3dUL, 0x11aef932UL, 0x6dc729a1UL, | ||
784 | 0x4b1d9e2fUL, 0xf3dcb230UL, 0xec0d8652UL, 0xd077c1e3UL, | ||
785 | 0x6c2bb316UL, 0x99a970b9UL, 0xfa119448UL, 0x2247e964UL, | ||
786 | 0xc4a8fc8cUL, 0x1aa0f03fUL, 0xd8567d2cUL, 0xef223390UL, | ||
787 | 0xc787494eUL, 0xc1d938d1UL, 0xfe8ccaa2UL, 0x3698d40bUL, | ||
788 | 0xcfa6f581UL, 0x28a57adeUL, 0x26dab78eUL, 0xa43fadbfUL, | ||
789 | 0xe42c3a9dUL, 0x0d507892UL, 0x9b6a5fccUL, 0x62547e46UL, | ||
790 | 0xc2f68d13UL, 0xe890d8b8UL, 0x5e2e39f7UL, 0xf582c3afUL, | ||
791 | 0xbe9f5d80UL, 0x7c69d093UL, 0xa96fd52dUL, 0xb3cf2512UL, | ||
792 | 0x3bc8ac99UL, 0xa710187dUL, 0x6ee89c63UL, 0x7bdb3bbbUL, | ||
793 | 0x09cd2678UL, 0xf46e5918UL, 0x01ec9ab7UL, 0xa8834f9aUL, | ||
794 | 0x65e6956eUL, 0x7eaaffe6UL, 0x0821bccfUL, 0xe6ef15e8UL, | ||
795 | 0xd9bae79bUL, 0xce4a6f36UL, 0xd4ea9f09UL, 0xd629b07cUL, | ||
796 | 0xaf31a4b2UL, 0x312a3f23UL, 0x30c6a594UL, 0xc035a266UL, | ||
797 | 0x37744ebcUL, 0xa6fc82caUL, 0xb0e090d0UL, 0x1533a7d8UL, | ||
798 | 0x4af10498UL, 0xf741ecdaUL, 0x0e7fcd50UL, 0x2f1791f6UL, | ||
799 | 0x8d764dd6UL, 0x4d43efb0UL, 0x54ccaa4dUL, 0xdfe49604UL, | ||
800 | 0xe39ed1b5UL, 0x1b4c6a88UL, 0xb8c12c1fUL, 0x7f466551UL, | ||
801 | 0x049d5eeaUL, 0x5d018c35UL, 0x73fa8774UL, 0x2efb0b41UL, | ||
802 | 0x5ab3671dUL, 0x5292dbd2UL, 0x33e91056UL, 0x136dd647UL, | ||
803 | 0x8c9ad761UL, 0x7a37a10cUL, 0x8e59f814UL, 0x89eb133cUL, | ||
804 | 0xeecea927UL, 0x35b761c9UL, 0xede11ce5UL, 0x3c7a47b1UL, | ||
805 | 0x599cd2dfUL, 0x3f55f273UL, 0x791814ceUL, 0xbf73c737UL, | ||
806 | 0xea53f7cdUL, 0x5b5ffdaaUL, 0x14df3d6fUL, 0x867844dbUL, | ||
807 | 0x81caaff3UL, 0x3eb968c4UL, 0x2c382434UL, 0x5fc2a340UL, | ||
808 | 0x72161dc3UL, 0x0cbce225UL, 0x8b283c49UL, 0x41ff0d95UL, | ||
809 | 0x7139a801UL, 0xde080cb3UL, 0x9cd8b4e4UL, 0x906456c1UL, | ||
810 | 0x617bcb84UL, 0x70d532b6UL, 0x74486c5cUL, 0x42d0b857UL, | ||
811 | }; | ||
812 | static const uint32 TD2[256] = { | ||
813 | 0xa75051f4UL, 0x65537e41UL, 0xa4c31a17UL, 0x5e963a27UL, | ||
814 | 0x6bcb3babUL, 0x45f11f9dUL, 0x58abacfaUL, 0x03934be3UL, | ||
815 | 0xfa552030UL, 0x6df6ad76UL, 0x769188ccUL, 0x4c25f502UL, | ||
816 | 0xd7fc4fe5UL, 0xcbd7c52aUL, 0x44802635UL, 0xa38fb562UL, | ||
817 | 0x5a49deb1UL, 0x1b6725baUL, 0x0e9845eaUL, 0xc0e15dfeUL, | ||
818 | 0x7502c32fUL, 0xf012814cUL, 0x97a38d46UL, 0xf9c66bd3UL, | ||
819 | 0x5fe7038fUL, 0x9c951592UL, 0x7aebbf6dUL, 0x59da9552UL, | ||
820 | 0x832dd4beUL, 0x21d35874UL, 0x692949e0UL, 0xc8448ec9UL, | ||
821 | 0x896a75c2UL, 0x7978f48eUL, 0x3e6b9958UL, 0x71dd27b9UL, | ||
822 | 0x4fb6bee1UL, 0xad17f088UL, 0xac66c920UL, 0x3ab47dceUL, | ||
823 | 0x4a1863dfUL, 0x3182e51aUL, 0x33609751UL, 0x7f456253UL, | ||
824 | 0x77e0b164UL, 0xae84bb6bUL, 0xa01cfe81UL, 0x2b94f908UL, | ||
825 | 0x68587048UL, 0xfd198f45UL, 0x6c8794deUL, 0xf8b7527bUL, | ||
826 | 0xd323ab73UL, 0x02e2724bUL, 0x8f57e31fUL, 0xab2a6655UL, | ||
827 | 0x2807b2ebUL, 0xc2032fb5UL, 0x7b9a86c5UL, 0x08a5d337UL, | ||
828 | 0x87f23028UL, 0xa5b223bfUL, 0x6aba0203UL, 0x825ced16UL, | ||
829 | 0x1c2b8acfUL, 0xb492a779UL, 0xf2f0f307UL, 0xe2a14e69UL, | ||
830 | 0xf4cd65daUL, 0xbed50605UL, 0x621fd134UL, 0xfe8ac4a6UL, | ||
831 | 0x539d342eUL, 0x55a0a2f3UL, 0xe132058aUL, 0xeb75a4f6UL, | ||
832 | 0xec390b83UL, 0xefaa4060UL, 0x9f065e71UL, 0x1051bd6eUL, | ||
833 | 0x8af93e21UL, 0x063d96ddUL, 0x05aedd3eUL, 0xbd464de6UL, | ||
834 | 0x8db59154UL, 0x5d0571c4UL, 0xd46f0406UL, 0x15ff6050UL, | ||
835 | 0xfb241998UL, 0xe997d6bdUL, 0x43cc8940UL, 0x9e7767d9UL, | ||
836 | 0x42bdb0e8UL, 0x8b880789UL, 0x5b38e719UL, 0xeedb79c8UL, | ||
837 | 0x0a47a17cUL, 0x0fe97c42UL, 0x1ec9f884UL, 0x00000000UL, | ||
838 | 0x86830980UL, 0xed48322bUL, 0x70ac1e11UL, 0x724e6c5aUL, | ||
839 | 0xfffbfd0eUL, 0x38560f85UL, 0xd51e3daeUL, 0x3927362dUL, | ||
840 | 0xd9640a0fUL, 0xa621685cUL, 0x54d19b5bUL, 0x2e3a2436UL, | ||
841 | 0x67b10c0aUL, 0xe70f9357UL, 0x96d2b4eeUL, 0x919e1b9bUL, | ||
842 | 0xc54f80c0UL, 0x20a261dcUL, 0x4b695a77UL, 0x1a161c12UL, | ||
843 | 0xba0ae293UL, 0x2ae5c0a0UL, 0xe0433c22UL, 0x171d121bUL, | ||
844 | 0x0d0b0e09UL, 0xc7adf28bUL, 0xa8b92db6UL, 0xa9c8141eUL, | ||
845 | 0x198557f1UL, 0x074caf75UL, 0xddbbee99UL, 0x60fda37fUL, | ||
846 | 0x269ff701UL, 0xf5bc5c72UL, 0x3bc54466UL, 0x7e345bfbUL, | ||
847 | 0x29768b43UL, 0xc6dccb23UL, 0xfc68b6edUL, 0xf163b8e4UL, | ||
848 | 0xdccad731UL, 0x85104263UL, 0x22401397UL, 0x112084c6UL, | ||
849 | 0x247d854aUL, 0x3df8d2bbUL, 0x3211aef9UL, 0xa16dc729UL, | ||
850 | 0x2f4b1d9eUL, 0x30f3dcb2UL, 0x52ec0d86UL, 0xe3d077c1UL, | ||
851 | 0x166c2bb3UL, 0xb999a970UL, 0x48fa1194UL, 0x642247e9UL, | ||
852 | 0x8cc4a8fcUL, 0x3f1aa0f0UL, 0x2cd8567dUL, 0x90ef2233UL, | ||
853 | 0x4ec78749UL, 0xd1c1d938UL, 0xa2fe8ccaUL, 0x0b3698d4UL, | ||
854 | 0x81cfa6f5UL, 0xde28a57aUL, 0x8e26dab7UL, 0xbfa43fadUL, | ||
855 | 0x9de42c3aUL, 0x920d5078UL, 0xcc9b6a5fUL, 0x4662547eUL, | ||
856 | 0x13c2f68dUL, 0xb8e890d8UL, 0xf75e2e39UL, 0xaff582c3UL, | ||
857 | 0x80be9f5dUL, 0x937c69d0UL, 0x2da96fd5UL, 0x12b3cf25UL, | ||
858 | 0x993bc8acUL, 0x7da71018UL, 0x636ee89cUL, 0xbb7bdb3bUL, | ||
859 | 0x7809cd26UL, 0x18f46e59UL, 0xb701ec9aUL, 0x9aa8834fUL, | ||
860 | 0x6e65e695UL, 0xe67eaaffUL, 0xcf0821bcUL, 0xe8e6ef15UL, | ||
861 | 0x9bd9bae7UL, 0x36ce4a6fUL, 0x09d4ea9fUL, 0x7cd629b0UL, | ||
862 | 0xb2af31a4UL, 0x23312a3fUL, 0x9430c6a5UL, 0x66c035a2UL, | ||
863 | 0xbc37744eUL, 0xcaa6fc82UL, 0xd0b0e090UL, 0xd81533a7UL, | ||
864 | 0x984af104UL, 0xdaf741ecUL, 0x500e7fcdUL, 0xf62f1791UL, | ||
865 | 0xd68d764dUL, 0xb04d43efUL, 0x4d54ccaaUL, 0x04dfe496UL, | ||
866 | 0xb5e39ed1UL, 0x881b4c6aUL, 0x1fb8c12cUL, 0x517f4665UL, | ||
867 | 0xea049d5eUL, 0x355d018cUL, 0x7473fa87UL, 0x412efb0bUL, | ||
868 | 0x1d5ab367UL, 0xd25292dbUL, 0x5633e910UL, 0x47136dd6UL, | ||
869 | 0x618c9ad7UL, 0x0c7a37a1UL, 0x148e59f8UL, 0x3c89eb13UL, | ||
870 | 0x27eecea9UL, 0xc935b761UL, 0xe5ede11cUL, 0xb13c7a47UL, | ||
871 | 0xdf599cd2UL, 0x733f55f2UL, 0xce791814UL, 0x37bf73c7UL, | ||
872 | 0xcdea53f7UL, 0xaa5b5ffdUL, 0x6f14df3dUL, 0xdb867844UL, | ||
873 | 0xf381caafUL, 0xc43eb968UL, 0x342c3824UL, 0x405fc2a3UL, | ||
874 | 0xc372161dUL, 0x250cbce2UL, 0x498b283cUL, 0x9541ff0dUL, | ||
875 | 0x017139a8UL, 0xb3de080cUL, 0xe49cd8b4UL, 0xc1906456UL, | ||
876 | 0x84617bcbUL, 0xb670d532UL, 0x5c74486cUL, 0x5742d0b8UL, | ||
877 | }; | ||
878 | static const uint32 TD3[256] = { | ||
879 | 0xf4a75051UL, 0x4165537eUL, 0x17a4c31aUL, 0x275e963aUL, | ||
880 | 0xab6bcb3bUL, 0x9d45f11fUL, 0xfa58abacUL, 0xe303934bUL, | ||
881 | 0x30fa5520UL, 0x766df6adUL, 0xcc769188UL, 0x024c25f5UL, | ||
882 | 0xe5d7fc4fUL, 0x2acbd7c5UL, 0x35448026UL, 0x62a38fb5UL, | ||
883 | 0xb15a49deUL, 0xba1b6725UL, 0xea0e9845UL, 0xfec0e15dUL, | ||
884 | 0x2f7502c3UL, 0x4cf01281UL, 0x4697a38dUL, 0xd3f9c66bUL, | ||
885 | 0x8f5fe703UL, 0x929c9515UL, 0x6d7aebbfUL, 0x5259da95UL, | ||
886 | 0xbe832dd4UL, 0x7421d358UL, 0xe0692949UL, 0xc9c8448eUL, | ||
887 | 0xc2896a75UL, 0x8e7978f4UL, 0x583e6b99UL, 0xb971dd27UL, | ||
888 | 0xe14fb6beUL, 0x88ad17f0UL, 0x20ac66c9UL, 0xce3ab47dUL, | ||
889 | 0xdf4a1863UL, 0x1a3182e5UL, 0x51336097UL, 0x537f4562UL, | ||
890 | 0x6477e0b1UL, 0x6bae84bbUL, 0x81a01cfeUL, 0x082b94f9UL, | ||
891 | 0x48685870UL, 0x45fd198fUL, 0xde6c8794UL, 0x7bf8b752UL, | ||
892 | 0x73d323abUL, 0x4b02e272UL, 0x1f8f57e3UL, 0x55ab2a66UL, | ||
893 | 0xeb2807b2UL, 0xb5c2032fUL, 0xc57b9a86UL, 0x3708a5d3UL, | ||
894 | 0x2887f230UL, 0xbfa5b223UL, 0x036aba02UL, 0x16825cedUL, | ||
895 | 0xcf1c2b8aUL, 0x79b492a7UL, 0x07f2f0f3UL, 0x69e2a14eUL, | ||
896 | 0xdaf4cd65UL, 0x05bed506UL, 0x34621fd1UL, 0xa6fe8ac4UL, | ||
897 | 0x2e539d34UL, 0xf355a0a2UL, 0x8ae13205UL, 0xf6eb75a4UL, | ||
898 | 0x83ec390bUL, 0x60efaa40UL, 0x719f065eUL, 0x6e1051bdUL, | ||
899 | 0x218af93eUL, 0xdd063d96UL, 0x3e05aeddUL, 0xe6bd464dUL, | ||
900 | 0x548db591UL, 0xc45d0571UL, 0x06d46f04UL, 0x5015ff60UL, | ||
901 | 0x98fb2419UL, 0xbde997d6UL, 0x4043cc89UL, 0xd99e7767UL, | ||
902 | 0xe842bdb0UL, 0x898b8807UL, 0x195b38e7UL, 0xc8eedb79UL, | ||
903 | 0x7c0a47a1UL, 0x420fe97cUL, 0x841ec9f8UL, 0x00000000UL, | ||
904 | 0x80868309UL, 0x2bed4832UL, 0x1170ac1eUL, 0x5a724e6cUL, | ||
905 | 0x0efffbfdUL, 0x8538560fUL, 0xaed51e3dUL, 0x2d392736UL, | ||
906 | 0x0fd9640aUL, 0x5ca62168UL, 0x5b54d19bUL, 0x362e3a24UL, | ||
907 | 0x0a67b10cUL, 0x57e70f93UL, 0xee96d2b4UL, 0x9b919e1bUL, | ||
908 | 0xc0c54f80UL, 0xdc20a261UL, 0x774b695aUL, 0x121a161cUL, | ||
909 | 0x93ba0ae2UL, 0xa02ae5c0UL, 0x22e0433cUL, 0x1b171d12UL, | ||
910 | 0x090d0b0eUL, 0x8bc7adf2UL, 0xb6a8b92dUL, 0x1ea9c814UL, | ||
911 | 0xf1198557UL, 0x75074cafUL, 0x99ddbbeeUL, 0x7f60fda3UL, | ||
912 | 0x01269ff7UL, 0x72f5bc5cUL, 0x663bc544UL, 0xfb7e345bUL, | ||
913 | 0x4329768bUL, 0x23c6dccbUL, 0xedfc68b6UL, 0xe4f163b8UL, | ||
914 | 0x31dccad7UL, 0x63851042UL, 0x97224013UL, 0xc6112084UL, | ||
915 | 0x4a247d85UL, 0xbb3df8d2UL, 0xf93211aeUL, 0x29a16dc7UL, | ||
916 | 0x9e2f4b1dUL, 0xb230f3dcUL, 0x8652ec0dUL, 0xc1e3d077UL, | ||
917 | 0xb3166c2bUL, 0x70b999a9UL, 0x9448fa11UL, 0xe9642247UL, | ||
918 | 0xfc8cc4a8UL, 0xf03f1aa0UL, 0x7d2cd856UL, 0x3390ef22UL, | ||
919 | 0x494ec787UL, 0x38d1c1d9UL, 0xcaa2fe8cUL, 0xd40b3698UL, | ||
920 | 0xf581cfa6UL, 0x7ade28a5UL, 0xb78e26daUL, 0xadbfa43fUL, | ||
921 | 0x3a9de42cUL, 0x78920d50UL, 0x5fcc9b6aUL, 0x7e466254UL, | ||
922 | 0x8d13c2f6UL, 0xd8b8e890UL, 0x39f75e2eUL, 0xc3aff582UL, | ||
923 | 0x5d80be9fUL, 0xd0937c69UL, 0xd52da96fUL, 0x2512b3cfUL, | ||
924 | 0xac993bc8UL, 0x187da710UL, 0x9c636ee8UL, 0x3bbb7bdbUL, | ||
925 | 0x267809cdUL, 0x5918f46eUL, 0x9ab701ecUL, 0x4f9aa883UL, | ||
926 | 0x956e65e6UL, 0xffe67eaaUL, 0xbccf0821UL, 0x15e8e6efUL, | ||
927 | 0xe79bd9baUL, 0x6f36ce4aUL, 0x9f09d4eaUL, 0xb07cd629UL, | ||
928 | 0xa4b2af31UL, 0x3f23312aUL, 0xa59430c6UL, 0xa266c035UL, | ||
929 | 0x4ebc3774UL, 0x82caa6fcUL, 0x90d0b0e0UL, 0xa7d81533UL, | ||
930 | 0x04984af1UL, 0xecdaf741UL, 0xcd500e7fUL, 0x91f62f17UL, | ||
931 | 0x4dd68d76UL, 0xefb04d43UL, 0xaa4d54ccUL, 0x9604dfe4UL, | ||
932 | 0xd1b5e39eUL, 0x6a881b4cUL, 0x2c1fb8c1UL, 0x65517f46UL, | ||
933 | 0x5eea049dUL, 0x8c355d01UL, 0x877473faUL, 0x0b412efbUL, | ||
934 | 0x671d5ab3UL, 0xdbd25292UL, 0x105633e9UL, 0xd647136dUL, | ||
935 | 0xd7618c9aUL, 0xa10c7a37UL, 0xf8148e59UL, 0x133c89ebUL, | ||
936 | 0xa927eeceUL, 0x61c935b7UL, 0x1ce5ede1UL, 0x47b13c7aUL, | ||
937 | 0xd2df599cUL, 0xf2733f55UL, 0x14ce7918UL, 0xc737bf73UL, | ||
938 | 0xf7cdea53UL, 0xfdaa5b5fUL, 0x3d6f14dfUL, 0x44db8678UL, | ||
939 | 0xaff381caUL, 0x68c43eb9UL, 0x24342c38UL, 0xa3405fc2UL, | ||
940 | 0x1dc37216UL, 0xe2250cbcUL, 0x3c498b28UL, 0x0d9541ffUL, | ||
941 | 0xa8017139UL, 0x0cb3de08UL, 0xb4e49cd8UL, 0x56c19064UL, | ||
942 | 0xcb84617bUL, 0x32b670d5UL, 0x6c5c7448UL, 0xb85742d0UL, | ||
943 | }; | ||
944 | |||
945 | static const uint32 Tks0[] = { | ||
946 | 0x00000000UL, 0x0e090d0bUL, 0x1c121a16UL, 0x121b171dUL, 0x3824342cUL, 0x362d3927UL, 0x24362e3aUL, 0x2a3f2331UL, | ||
947 | 0x70486858UL, 0x7e416553UL, 0x6c5a724eUL, 0x62537f45UL, 0x486c5c74UL, 0x4665517fUL, 0x547e4662UL, 0x5a774b69UL, | ||
948 | 0xe090d0b0UL, 0xee99ddbbUL, 0xfc82caa6UL, 0xf28bc7adUL, 0xd8b4e49cUL, 0xd6bde997UL, 0xc4a6fe8aUL, 0xcaaff381UL, | ||
949 | 0x90d8b8e8UL, 0x9ed1b5e3UL, 0x8ccaa2feUL, 0x82c3aff5UL, 0xa8fc8cc4UL, 0xa6f581cfUL, 0xb4ee96d2UL, 0xbae79bd9UL, | ||
950 | 0xdb3bbb7bUL, 0xd532b670UL, 0xc729a16dUL, 0xc920ac66UL, 0xe31f8f57UL, 0xed16825cUL, 0xff0d9541UL, 0xf104984aUL, | ||
951 | 0xab73d323UL, 0xa57ade28UL, 0xb761c935UL, 0xb968c43eUL, 0x9357e70fUL, 0x9d5eea04UL, 0x8f45fd19UL, 0x814cf012UL, | ||
952 | 0x3bab6bcbUL, 0x35a266c0UL, 0x27b971ddUL, 0x29b07cd6UL, 0x038f5fe7UL, 0x0d8652ecUL, 0x1f9d45f1UL, 0x119448faUL, | ||
953 | 0x4be30393UL, 0x45ea0e98UL, 0x57f11985UL, 0x59f8148eUL, 0x73c737bfUL, 0x7dce3ab4UL, 0x6fd52da9UL, 0x61dc20a2UL, | ||
954 | 0xad766df6UL, 0xa37f60fdUL, 0xb16477e0UL, 0xbf6d7aebUL, 0x955259daUL, 0x9b5b54d1UL, 0x894043ccUL, 0x87494ec7UL, | ||
955 | 0xdd3e05aeUL, 0xd33708a5UL, 0xc12c1fb8UL, 0xcf2512b3UL, 0xe51a3182UL, 0xeb133c89UL, 0xf9082b94UL, 0xf701269fUL, | ||
956 | 0x4de6bd46UL, 0x43efb04dUL, 0x51f4a750UL, 0x5ffdaa5bUL, 0x75c2896aUL, 0x7bcb8461UL, 0x69d0937cUL, 0x67d99e77UL, | ||
957 | 0x3daed51eUL, 0x33a7d815UL, 0x21bccf08UL, 0x2fb5c203UL, 0x058ae132UL, 0x0b83ec39UL, 0x1998fb24UL, 0x1791f62fUL, | ||
958 | 0x764dd68dUL, 0x7844db86UL, 0x6a5fcc9bUL, 0x6456c190UL, 0x4e69e2a1UL, 0x4060efaaUL, 0x527bf8b7UL, 0x5c72f5bcUL, | ||
959 | 0x0605bed5UL, 0x080cb3deUL, 0x1a17a4c3UL, 0x141ea9c8UL, 0x3e218af9UL, 0x302887f2UL, 0x223390efUL, 0x2c3a9de4UL, | ||
960 | 0x96dd063dUL, 0x98d40b36UL, 0x8acf1c2bUL, 0x84c61120UL, 0xaef93211UL, 0xa0f03f1aUL, 0xb2eb2807UL, 0xbce2250cUL, | ||
961 | 0xe6956e65UL, 0xe89c636eUL, 0xfa877473UL, 0xf48e7978UL, 0xdeb15a49UL, 0xd0b85742UL, 0xc2a3405fUL, 0xccaa4d54UL, | ||
962 | 0x41ecdaf7UL, 0x4fe5d7fcUL, 0x5dfec0e1UL, 0x53f7cdeaUL, 0x79c8eedbUL, 0x77c1e3d0UL, 0x65daf4cdUL, 0x6bd3f9c6UL, | ||
963 | 0x31a4b2afUL, 0x3fadbfa4UL, 0x2db6a8b9UL, 0x23bfa5b2UL, 0x09808683UL, 0x07898b88UL, 0x15929c95UL, 0x1b9b919eUL, | ||
964 | 0xa17c0a47UL, 0xaf75074cUL, 0xbd6e1051UL, 0xb3671d5aUL, 0x99583e6bUL, 0x97513360UL, 0x854a247dUL, 0x8b432976UL, | ||
965 | 0xd134621fUL, 0xdf3d6f14UL, 0xcd267809UL, 0xc32f7502UL, 0xe9105633UL, 0xe7195b38UL, 0xf5024c25UL, 0xfb0b412eUL, | ||
966 | 0x9ad7618cUL, 0x94de6c87UL, 0x86c57b9aUL, 0x88cc7691UL, 0xa2f355a0UL, 0xacfa58abUL, 0xbee14fb6UL, 0xb0e842bdUL, | ||
967 | 0xea9f09d4UL, 0xe49604dfUL, 0xf68d13c2UL, 0xf8841ec9UL, 0xd2bb3df8UL, 0xdcb230f3UL, 0xcea927eeUL, 0xc0a02ae5UL, | ||
968 | 0x7a47b13cUL, 0x744ebc37UL, 0x6655ab2aUL, 0x685ca621UL, 0x42638510UL, 0x4c6a881bUL, 0x5e719f06UL, 0x5078920dUL, | ||
969 | 0x0a0fd964UL, 0x0406d46fUL, 0x161dc372UL, 0x1814ce79UL, 0x322bed48UL, 0x3c22e043UL, 0x2e39f75eUL, 0x2030fa55UL, | ||
970 | 0xec9ab701UL, 0xe293ba0aUL, 0xf088ad17UL, 0xfe81a01cUL, 0xd4be832dUL, 0xdab78e26UL, 0xc8ac993bUL, 0xc6a59430UL, | ||
971 | 0x9cd2df59UL, 0x92dbd252UL, 0x80c0c54fUL, 0x8ec9c844UL, 0xa4f6eb75UL, 0xaaffe67eUL, 0xb8e4f163UL, 0xb6edfc68UL, | ||
972 | 0x0c0a67b1UL, 0x02036abaUL, 0x10187da7UL, 0x1e1170acUL, 0x342e539dUL, 0x3a275e96UL, 0x283c498bUL, 0x26354480UL, | ||
973 | 0x7c420fe9UL, 0x724b02e2UL, 0x605015ffUL, 0x6e5918f4UL, 0x44663bc5UL, 0x4a6f36ceUL, 0x587421d3UL, 0x567d2cd8UL, | ||
974 | 0x37a10c7aUL, 0x39a80171UL, 0x2bb3166cUL, 0x25ba1b67UL, 0x0f853856UL, 0x018c355dUL, 0x13972240UL, 0x1d9e2f4bUL, | ||
975 | 0x47e96422UL, 0x49e06929UL, 0x5bfb7e34UL, 0x55f2733fUL, 0x7fcd500eUL, 0x71c45d05UL, 0x63df4a18UL, 0x6dd64713UL, | ||
976 | 0xd731dccaUL, 0xd938d1c1UL, 0xcb23c6dcUL, 0xc52acbd7UL, 0xef15e8e6UL, 0xe11ce5edUL, 0xf307f2f0UL, 0xfd0efffbUL, | ||
977 | 0xa779b492UL, 0xa970b999UL, 0xbb6bae84UL, 0xb562a38fUL, 0x9f5d80beUL, 0x91548db5UL, 0x834f9aa8UL, 0x8d4697a3UL | ||
978 | }; | ||
979 | |||
980 | static const uint32 Tks1[] = { | ||
981 | 0x00000000UL, 0x0b0e090dUL, 0x161c121aUL, 0x1d121b17UL, 0x2c382434UL, 0x27362d39UL, 0x3a24362eUL, 0x312a3f23UL, | ||
982 | 0x58704868UL, 0x537e4165UL, 0x4e6c5a72UL, 0x4562537fUL, 0x74486c5cUL, 0x7f466551UL, 0x62547e46UL, 0x695a774bUL, | ||
983 | 0xb0e090d0UL, 0xbbee99ddUL, 0xa6fc82caUL, 0xadf28bc7UL, 0x9cd8b4e4UL, 0x97d6bde9UL, 0x8ac4a6feUL, 0x81caaff3UL, | ||
984 | 0xe890d8b8UL, 0xe39ed1b5UL, 0xfe8ccaa2UL, 0xf582c3afUL, 0xc4a8fc8cUL, 0xcfa6f581UL, 0xd2b4ee96UL, 0xd9bae79bUL, | ||
985 | 0x7bdb3bbbUL, 0x70d532b6UL, 0x6dc729a1UL, 0x66c920acUL, 0x57e31f8fUL, 0x5ced1682UL, 0x41ff0d95UL, 0x4af10498UL, | ||
986 | 0x23ab73d3UL, 0x28a57adeUL, 0x35b761c9UL, 0x3eb968c4UL, 0x0f9357e7UL, 0x049d5eeaUL, 0x198f45fdUL, 0x12814cf0UL, | ||
987 | 0xcb3bab6bUL, 0xc035a266UL, 0xdd27b971UL, 0xd629b07cUL, 0xe7038f5fUL, 0xec0d8652UL, 0xf11f9d45UL, 0xfa119448UL, | ||
988 | 0x934be303UL, 0x9845ea0eUL, 0x8557f119UL, 0x8e59f814UL, 0xbf73c737UL, 0xb47dce3aUL, 0xa96fd52dUL, 0xa261dc20UL, | ||
989 | 0xf6ad766dUL, 0xfda37f60UL, 0xe0b16477UL, 0xebbf6d7aUL, 0xda955259UL, 0xd19b5b54UL, 0xcc894043UL, 0xc787494eUL, | ||
990 | 0xaedd3e05UL, 0xa5d33708UL, 0xb8c12c1fUL, 0xb3cf2512UL, 0x82e51a31UL, 0x89eb133cUL, 0x94f9082bUL, 0x9ff70126UL, | ||
991 | 0x464de6bdUL, 0x4d43efb0UL, 0x5051f4a7UL, 0x5b5ffdaaUL, 0x6a75c289UL, 0x617bcb84UL, 0x7c69d093UL, 0x7767d99eUL, | ||
992 | 0x1e3daed5UL, 0x1533a7d8UL, 0x0821bccfUL, 0x032fb5c2UL, 0x32058ae1UL, 0x390b83ecUL, 0x241998fbUL, 0x2f1791f6UL, | ||
993 | 0x8d764dd6UL, 0x867844dbUL, 0x9b6a5fccUL, 0x906456c1UL, 0xa14e69e2UL, 0xaa4060efUL, 0xb7527bf8UL, 0xbc5c72f5UL, | ||
994 | 0xd50605beUL, 0xde080cb3UL, 0xc31a17a4UL, 0xc8141ea9UL, 0xf93e218aUL, 0xf2302887UL, 0xef223390UL, 0xe42c3a9dUL, | ||
995 | 0x3d96dd06UL, 0x3698d40bUL, 0x2b8acf1cUL, 0x2084c611UL, 0x11aef932UL, 0x1aa0f03fUL, 0x07b2eb28UL, 0x0cbce225UL, | ||
996 | 0x65e6956eUL, 0x6ee89c63UL, 0x73fa8774UL, 0x78f48e79UL, 0x49deb15aUL, 0x42d0b857UL, 0x5fc2a340UL, 0x54ccaa4dUL, | ||
997 | 0xf741ecdaUL, 0xfc4fe5d7UL, 0xe15dfec0UL, 0xea53f7cdUL, 0xdb79c8eeUL, 0xd077c1e3UL, 0xcd65daf4UL, 0xc66bd3f9UL, | ||
998 | 0xaf31a4b2UL, 0xa43fadbfUL, 0xb92db6a8UL, 0xb223bfa5UL, 0x83098086UL, 0x8807898bUL, 0x9515929cUL, 0x9e1b9b91UL, | ||
999 | 0x47a17c0aUL, 0x4caf7507UL, 0x51bd6e10UL, 0x5ab3671dUL, 0x6b99583eUL, 0x60975133UL, 0x7d854a24UL, 0x768b4329UL, | ||
1000 | 0x1fd13462UL, 0x14df3d6fUL, 0x09cd2678UL, 0x02c32f75UL, 0x33e91056UL, 0x38e7195bUL, 0x25f5024cUL, 0x2efb0b41UL, | ||
1001 | 0x8c9ad761UL, 0x8794de6cUL, 0x9a86c57bUL, 0x9188cc76UL, 0xa0a2f355UL, 0xabacfa58UL, 0xb6bee14fUL, 0xbdb0e842UL, | ||
1002 | 0xd4ea9f09UL, 0xdfe49604UL, 0xc2f68d13UL, 0xc9f8841eUL, 0xf8d2bb3dUL, 0xf3dcb230UL, 0xeecea927UL, 0xe5c0a02aUL, | ||
1003 | 0x3c7a47b1UL, 0x37744ebcUL, 0x2a6655abUL, 0x21685ca6UL, 0x10426385UL, 0x1b4c6a88UL, 0x065e719fUL, 0x0d507892UL, | ||
1004 | 0x640a0fd9UL, 0x6f0406d4UL, 0x72161dc3UL, 0x791814ceUL, 0x48322bedUL, 0x433c22e0UL, 0x5e2e39f7UL, 0x552030faUL, | ||
1005 | 0x01ec9ab7UL, 0x0ae293baUL, 0x17f088adUL, 0x1cfe81a0UL, 0x2dd4be83UL, 0x26dab78eUL, 0x3bc8ac99UL, 0x30c6a594UL, | ||
1006 | 0x599cd2dfUL, 0x5292dbd2UL, 0x4f80c0c5UL, 0x448ec9c8UL, 0x75a4f6ebUL, 0x7eaaffe6UL, 0x63b8e4f1UL, 0x68b6edfcUL, | ||
1007 | 0xb10c0a67UL, 0xba02036aUL, 0xa710187dUL, 0xac1e1170UL, 0x9d342e53UL, 0x963a275eUL, 0x8b283c49UL, 0x80263544UL, | ||
1008 | 0xe97c420fUL, 0xe2724b02UL, 0xff605015UL, 0xf46e5918UL, 0xc544663bUL, 0xce4a6f36UL, 0xd3587421UL, 0xd8567d2cUL, | ||
1009 | 0x7a37a10cUL, 0x7139a801UL, 0x6c2bb316UL, 0x6725ba1bUL, 0x560f8538UL, 0x5d018c35UL, 0x40139722UL, 0x4b1d9e2fUL, | ||
1010 | 0x2247e964UL, 0x2949e069UL, 0x345bfb7eUL, 0x3f55f273UL, 0x0e7fcd50UL, 0x0571c45dUL, 0x1863df4aUL, 0x136dd647UL, | ||
1011 | 0xcad731dcUL, 0xc1d938d1UL, 0xdccb23c6UL, 0xd7c52acbUL, 0xe6ef15e8UL, 0xede11ce5UL, 0xf0f307f2UL, 0xfbfd0effUL, | ||
1012 | 0x92a779b4UL, 0x99a970b9UL, 0x84bb6baeUL, 0x8fb562a3UL, 0xbe9f5d80UL, 0xb591548dUL, 0xa8834f9aUL, 0xa38d4697UL | ||
1013 | }; | ||
1014 | |||
1015 | static const uint32 Tks2[] = { | ||
1016 | 0x00000000UL, 0x0d0b0e09UL, 0x1a161c12UL, 0x171d121bUL, 0x342c3824UL, 0x3927362dUL, 0x2e3a2436UL, 0x23312a3fUL, | ||
1017 | 0x68587048UL, 0x65537e41UL, 0x724e6c5aUL, 0x7f456253UL, 0x5c74486cUL, 0x517f4665UL, 0x4662547eUL, 0x4b695a77UL, | ||
1018 | 0xd0b0e090UL, 0xddbbee99UL, 0xcaa6fc82UL, 0xc7adf28bUL, 0xe49cd8b4UL, 0xe997d6bdUL, 0xfe8ac4a6UL, 0xf381caafUL, | ||
1019 | 0xb8e890d8UL, 0xb5e39ed1UL, 0xa2fe8ccaUL, 0xaff582c3UL, 0x8cc4a8fcUL, 0x81cfa6f5UL, 0x96d2b4eeUL, 0x9bd9bae7UL, | ||
1020 | 0xbb7bdb3bUL, 0xb670d532UL, 0xa16dc729UL, 0xac66c920UL, 0x8f57e31fUL, 0x825ced16UL, 0x9541ff0dUL, 0x984af104UL, | ||
1021 | 0xd323ab73UL, 0xde28a57aUL, 0xc935b761UL, 0xc43eb968UL, 0xe70f9357UL, 0xea049d5eUL, 0xfd198f45UL, 0xf012814cUL, | ||
1022 | 0x6bcb3babUL, 0x66c035a2UL, 0x71dd27b9UL, 0x7cd629b0UL, 0x5fe7038fUL, 0x52ec0d86UL, 0x45f11f9dUL, 0x48fa1194UL, | ||
1023 | 0x03934be3UL, 0x0e9845eaUL, 0x198557f1UL, 0x148e59f8UL, 0x37bf73c7UL, 0x3ab47dceUL, 0x2da96fd5UL, 0x20a261dcUL, | ||
1024 | 0x6df6ad76UL, 0x60fda37fUL, 0x77e0b164UL, 0x7aebbf6dUL, 0x59da9552UL, 0x54d19b5bUL, 0x43cc8940UL, 0x4ec78749UL, | ||
1025 | 0x05aedd3eUL, 0x08a5d337UL, 0x1fb8c12cUL, 0x12b3cf25UL, 0x3182e51aUL, 0x3c89eb13UL, 0x2b94f908UL, 0x269ff701UL, | ||
1026 | 0xbd464de6UL, 0xb04d43efUL, 0xa75051f4UL, 0xaa5b5ffdUL, 0x896a75c2UL, 0x84617bcbUL, 0x937c69d0UL, 0x9e7767d9UL, | ||
1027 | 0xd51e3daeUL, 0xd81533a7UL, 0xcf0821bcUL, 0xc2032fb5UL, 0xe132058aUL, 0xec390b83UL, 0xfb241998UL, 0xf62f1791UL, | ||
1028 | 0xd68d764dUL, 0xdb867844UL, 0xcc9b6a5fUL, 0xc1906456UL, 0xe2a14e69UL, 0xefaa4060UL, 0xf8b7527bUL, 0xf5bc5c72UL, | ||
1029 | 0xbed50605UL, 0xb3de080cUL, 0xa4c31a17UL, 0xa9c8141eUL, 0x8af93e21UL, 0x87f23028UL, 0x90ef2233UL, 0x9de42c3aUL, | ||
1030 | 0x063d96ddUL, 0x0b3698d4UL, 0x1c2b8acfUL, 0x112084c6UL, 0x3211aef9UL, 0x3f1aa0f0UL, 0x2807b2ebUL, 0x250cbce2UL, | ||
1031 | 0x6e65e695UL, 0x636ee89cUL, 0x7473fa87UL, 0x7978f48eUL, 0x5a49deb1UL, 0x5742d0b8UL, 0x405fc2a3UL, 0x4d54ccaaUL, | ||
1032 | 0xdaf741ecUL, 0xd7fc4fe5UL, 0xc0e15dfeUL, 0xcdea53f7UL, 0xeedb79c8UL, 0xe3d077c1UL, 0xf4cd65daUL, 0xf9c66bd3UL, | ||
1033 | 0xb2af31a4UL, 0xbfa43fadUL, 0xa8b92db6UL, 0xa5b223bfUL, 0x86830980UL, 0x8b880789UL, 0x9c951592UL, 0x919e1b9bUL, | ||
1034 | 0x0a47a17cUL, 0x074caf75UL, 0x1051bd6eUL, 0x1d5ab367UL, 0x3e6b9958UL, 0x33609751UL, 0x247d854aUL, 0x29768b43UL, | ||
1035 | 0x621fd134UL, 0x6f14df3dUL, 0x7809cd26UL, 0x7502c32fUL, 0x5633e910UL, 0x5b38e719UL, 0x4c25f502UL, 0x412efb0bUL, | ||
1036 | 0x618c9ad7UL, 0x6c8794deUL, 0x7b9a86c5UL, 0x769188ccUL, 0x55a0a2f3UL, 0x58abacfaUL, 0x4fb6bee1UL, 0x42bdb0e8UL, | ||
1037 | 0x09d4ea9fUL, 0x04dfe496UL, 0x13c2f68dUL, 0x1ec9f884UL, 0x3df8d2bbUL, 0x30f3dcb2UL, 0x27eecea9UL, 0x2ae5c0a0UL, | ||
1038 | 0xb13c7a47UL, 0xbc37744eUL, 0xab2a6655UL, 0xa621685cUL, 0x85104263UL, 0x881b4c6aUL, 0x9f065e71UL, 0x920d5078UL, | ||
1039 | 0xd9640a0fUL, 0xd46f0406UL, 0xc372161dUL, 0xce791814UL, 0xed48322bUL, 0xe0433c22UL, 0xf75e2e39UL, 0xfa552030UL, | ||
1040 | 0xb701ec9aUL, 0xba0ae293UL, 0xad17f088UL, 0xa01cfe81UL, 0x832dd4beUL, 0x8e26dab7UL, 0x993bc8acUL, 0x9430c6a5UL, | ||
1041 | 0xdf599cd2UL, 0xd25292dbUL, 0xc54f80c0UL, 0xc8448ec9UL, 0xeb75a4f6UL, 0xe67eaaffUL, 0xf163b8e4UL, 0xfc68b6edUL, | ||
1042 | 0x67b10c0aUL, 0x6aba0203UL, 0x7da71018UL, 0x70ac1e11UL, 0x539d342eUL, 0x5e963a27UL, 0x498b283cUL, 0x44802635UL, | ||
1043 | 0x0fe97c42UL, 0x02e2724bUL, 0x15ff6050UL, 0x18f46e59UL, 0x3bc54466UL, 0x36ce4a6fUL, 0x21d35874UL, 0x2cd8567dUL, | ||
1044 | 0x0c7a37a1UL, 0x017139a8UL, 0x166c2bb3UL, 0x1b6725baUL, 0x38560f85UL, 0x355d018cUL, 0x22401397UL, 0x2f4b1d9eUL, | ||
1045 | 0x642247e9UL, 0x692949e0UL, 0x7e345bfbUL, 0x733f55f2UL, 0x500e7fcdUL, 0x5d0571c4UL, 0x4a1863dfUL, 0x47136dd6UL, | ||
1046 | 0xdccad731UL, 0xd1c1d938UL, 0xc6dccb23UL, 0xcbd7c52aUL, 0xe8e6ef15UL, 0xe5ede11cUL, 0xf2f0f307UL, 0xfffbfd0eUL, | ||
1047 | 0xb492a779UL, 0xb999a970UL, 0xae84bb6bUL, 0xa38fb562UL, 0x80be9f5dUL, 0x8db59154UL, 0x9aa8834fUL, 0x97a38d46UL | ||
1048 | }; | ||
1049 | |||
1050 | static const uint32 Tks3[] = { | ||
1051 | 0x00000000UL, 0x090d0b0eUL, 0x121a161cUL, 0x1b171d12UL, 0x24342c38UL, 0x2d392736UL, 0x362e3a24UL, 0x3f23312aUL, | ||
1052 | 0x48685870UL, 0x4165537eUL, 0x5a724e6cUL, 0x537f4562UL, 0x6c5c7448UL, 0x65517f46UL, 0x7e466254UL, 0x774b695aUL, | ||
1053 | 0x90d0b0e0UL, 0x99ddbbeeUL, 0x82caa6fcUL, 0x8bc7adf2UL, 0xb4e49cd8UL, 0xbde997d6UL, 0xa6fe8ac4UL, 0xaff381caUL, | ||
1054 | 0xd8b8e890UL, 0xd1b5e39eUL, 0xcaa2fe8cUL, 0xc3aff582UL, 0xfc8cc4a8UL, 0xf581cfa6UL, 0xee96d2b4UL, 0xe79bd9baUL, | ||
1055 | 0x3bbb7bdbUL, 0x32b670d5UL, 0x29a16dc7UL, 0x20ac66c9UL, 0x1f8f57e3UL, 0x16825cedUL, 0x0d9541ffUL, 0x04984af1UL, | ||
1056 | 0x73d323abUL, 0x7ade28a5UL, 0x61c935b7UL, 0x68c43eb9UL, 0x57e70f93UL, 0x5eea049dUL, 0x45fd198fUL, 0x4cf01281UL, | ||
1057 | 0xab6bcb3bUL, 0xa266c035UL, 0xb971dd27UL, 0xb07cd629UL, 0x8f5fe703UL, 0x8652ec0dUL, 0x9d45f11fUL, 0x9448fa11UL, | ||
1058 | 0xe303934bUL, 0xea0e9845UL, 0xf1198557UL, 0xf8148e59UL, 0xc737bf73UL, 0xce3ab47dUL, 0xd52da96fUL, 0xdc20a261UL, | ||
1059 | 0x766df6adUL, 0x7f60fda3UL, 0x6477e0b1UL, 0x6d7aebbfUL, 0x5259da95UL, 0x5b54d19bUL, 0x4043cc89UL, 0x494ec787UL, | ||
1060 | 0x3e05aeddUL, 0x3708a5d3UL, 0x2c1fb8c1UL, 0x2512b3cfUL, 0x1a3182e5UL, 0x133c89ebUL, 0x082b94f9UL, 0x01269ff7UL, | ||
1061 | 0xe6bd464dUL, 0xefb04d43UL, 0xf4a75051UL, 0xfdaa5b5fUL, 0xc2896a75UL, 0xcb84617bUL, 0xd0937c69UL, 0xd99e7767UL, | ||
1062 | 0xaed51e3dUL, 0xa7d81533UL, 0xbccf0821UL, 0xb5c2032fUL, 0x8ae13205UL, 0x83ec390bUL, 0x98fb2419UL, 0x91f62f17UL, | ||
1063 | 0x4dd68d76UL, 0x44db8678UL, 0x5fcc9b6aUL, 0x56c19064UL, 0x69e2a14eUL, 0x60efaa40UL, 0x7bf8b752UL, 0x72f5bc5cUL, | ||
1064 | 0x05bed506UL, 0x0cb3de08UL, 0x17a4c31aUL, 0x1ea9c814UL, 0x218af93eUL, 0x2887f230UL, 0x3390ef22UL, 0x3a9de42cUL, | ||
1065 | 0xdd063d96UL, 0xd40b3698UL, 0xcf1c2b8aUL, 0xc6112084UL, 0xf93211aeUL, 0xf03f1aa0UL, 0xeb2807b2UL, 0xe2250cbcUL, | ||
1066 | 0x956e65e6UL, 0x9c636ee8UL, 0x877473faUL, 0x8e7978f4UL, 0xb15a49deUL, 0xb85742d0UL, 0xa3405fc2UL, 0xaa4d54ccUL, | ||
1067 | 0xecdaf741UL, 0xe5d7fc4fUL, 0xfec0e15dUL, 0xf7cdea53UL, 0xc8eedb79UL, 0xc1e3d077UL, 0xdaf4cd65UL, 0xd3f9c66bUL, | ||
1068 | 0xa4b2af31UL, 0xadbfa43fUL, 0xb6a8b92dUL, 0xbfa5b223UL, 0x80868309UL, 0x898b8807UL, 0x929c9515UL, 0x9b919e1bUL, | ||
1069 | 0x7c0a47a1UL, 0x75074cafUL, 0x6e1051bdUL, 0x671d5ab3UL, 0x583e6b99UL, 0x51336097UL, 0x4a247d85UL, 0x4329768bUL, | ||
1070 | 0x34621fd1UL, 0x3d6f14dfUL, 0x267809cdUL, 0x2f7502c3UL, 0x105633e9UL, 0x195b38e7UL, 0x024c25f5UL, 0x0b412efbUL, | ||
1071 | 0xd7618c9aUL, 0xde6c8794UL, 0xc57b9a86UL, 0xcc769188UL, 0xf355a0a2UL, 0xfa58abacUL, 0xe14fb6beUL, 0xe842bdb0UL, | ||
1072 | 0x9f09d4eaUL, 0x9604dfe4UL, 0x8d13c2f6UL, 0x841ec9f8UL, 0xbb3df8d2UL, 0xb230f3dcUL, 0xa927eeceUL, 0xa02ae5c0UL, | ||
1073 | 0x47b13c7aUL, 0x4ebc3774UL, 0x55ab2a66UL, 0x5ca62168UL, 0x63851042UL, 0x6a881b4cUL, 0x719f065eUL, 0x78920d50UL, | ||
1074 | 0x0fd9640aUL, 0x06d46f04UL, 0x1dc37216UL, 0x14ce7918UL, 0x2bed4832UL, 0x22e0433cUL, 0x39f75e2eUL, 0x30fa5520UL, | ||
1075 | 0x9ab701ecUL, 0x93ba0ae2UL, 0x88ad17f0UL, 0x81a01cfeUL, 0xbe832dd4UL, 0xb78e26daUL, 0xac993bc8UL, 0xa59430c6UL, | ||
1076 | 0xd2df599cUL, 0xdbd25292UL, 0xc0c54f80UL, 0xc9c8448eUL, 0xf6eb75a4UL, 0xffe67eaaUL, 0xe4f163b8UL, 0xedfc68b6UL, | ||
1077 | 0x0a67b10cUL, 0x036aba02UL, 0x187da710UL, 0x1170ac1eUL, 0x2e539d34UL, 0x275e963aUL, 0x3c498b28UL, 0x35448026UL, | ||
1078 | 0x420fe97cUL, 0x4b02e272UL, 0x5015ff60UL, 0x5918f46eUL, 0x663bc544UL, 0x6f36ce4aUL, 0x7421d358UL, 0x7d2cd856UL, | ||
1079 | 0xa10c7a37UL, 0xa8017139UL, 0xb3166c2bUL, 0xba1b6725UL, 0x8538560fUL, 0x8c355d01UL, 0x97224013UL, 0x9e2f4b1dUL, | ||
1080 | 0xe9642247UL, 0xe0692949UL, 0xfb7e345bUL, 0xf2733f55UL, 0xcd500e7fUL, 0xc45d0571UL, 0xdf4a1863UL, 0xd647136dUL, | ||
1081 | 0x31dccad7UL, 0x38d1c1d9UL, 0x23c6dccbUL, 0x2acbd7c5UL, 0x15e8e6efUL, 0x1ce5ede1UL, 0x07f2f0f3UL, 0x0efffbfdUL, | ||
1082 | 0x79b492a7UL, 0x70b999a9UL, 0x6bae84bbUL, 0x62a38fb5UL, 0x5d80be9fUL, 0x548db591UL, 0x4f9aa883UL, 0x4697a38dUL | ||
1083 | }; | ||
1084 | |||
1085 | #endif /* PS_AES_IMPROVE_PERF_INCREASE_CODESIZE */ | ||
1086 | |||
1087 | static const uint32 rcon[] = { | ||
1088 | 0x01000000UL, 0x02000000UL, 0x04000000UL, 0x08000000UL, | ||
1089 | 0x10000000UL, 0x20000000UL, 0x40000000UL, 0x80000000UL, | ||
1090 | 0x1B000000UL, 0x36000000UL, /* for 128-bit blocks, AES never uses more than 10 rcon values */ | ||
1091 | }; | ||
1092 | |||
1093 | #ifdef USE_BURN_STACK | ||
1094 | static void _aes_ecb_decrypt(const unsigned char *ct, unsigned char *pt, | ||
1095 | psAesKey_t *skey); | ||
1096 | static void _aes_ecb_encrypt(const unsigned char *pt, unsigned char *ct, | ||
1097 | psAesKey_t *skey); | ||
1098 | #endif | ||
1099 | |||
1100 | static uint32 setup_mix(uint32 temp) | ||
1101 | { | ||
1102 | return (Te4_3[byte(temp, 2)]) ^ | ||
1103 | (Te4_2[byte(temp, 1)]) ^ | ||
1104 | (Te4_1[byte(temp, 0)]) ^ | ||
1105 | (Te4_0[byte(temp, 3)]); | ||
1106 | } | ||
1107 | |||
1108 | #ifndef PS_AES_IMPROVE_PERF_INCREASE_CODESIZE | ||
1109 | static uint32 setup_mix2(uint32 temp) | ||
1110 | { | ||
1111 | return Td0(255 & Te4[byte(temp, 3)]) ^ | ||
1112 | Td1(255 & Te4[byte(temp, 2)]) ^ | ||
1113 | Td2(255 & Te4[byte(temp, 1)]) ^ | ||
1114 | Td3(255 & Te4[byte(temp, 0)]); | ||
1115 | } | ||
1116 | #endif /* PS_AES_IMPROVE_PERF_INCREASE_CODESIZE */ | ||
1117 | |||
1118 | /* | ||
1119 | Software implementation of AES CBC APIs | ||
1120 | */ | ||
1121 | #ifndef USE_AES_CBC_EXTERNAL | ||
1122 | static //bbox | ||
1123 | int32 psAesInit(psCipherContext_t *ctx, unsigned char *IV, | ||
1124 | const unsigned char *key, uint32 keylen) | ||
1125 | { | ||
1126 | int32 x, err; | ||
1127 | |||
1128 | //bbox | ||
1129 | // if (IV == NULL || key == NULL || ctx == NULL) { | ||
1130 | // psTraceCrypto("psAesInit arg fail\n"); | ||
1131 | // return PS_ARG_FAIL; | ||
1132 | // } | ||
1133 | memset(ctx, 0x0, sizeof(psCipherContext_t)); | ||
1134 | /* | ||
1135 | setup cipher | ||
1136 | */ | ||
1137 | if ((err = psAesInitKey(key, keylen, &ctx->aes.key)) != PS_SUCCESS) { | ||
1138 | return err; | ||
1139 | } | ||
1140 | /* | ||
1141 | copy IV | ||
1142 | */ | ||
1143 | ctx->aes.blocklen = 16; | ||
1144 | for (x = 0; x < ctx->aes.blocklen; x++) { | ||
1145 | ctx->aes.IV[x] = IV[x]; | ||
1146 | } | ||
1147 | return PS_SUCCESS; | ||
1148 | } | ||
1149 | |||
1150 | static //bbox | ||
1151 | int32 psAesEncrypt(psCipherContext_t *ctx, const unsigned char *pt, | ||
1152 | unsigned char *ct, uint32 len) | ||
1153 | { | ||
1154 | int32 x; | ||
1155 | uint32 i; | ||
1156 | unsigned char tmp[MAXBLOCKSIZE]; | ||
1157 | |||
1158 | //bbox | ||
1159 | // if (pt == NULL || ct == NULL || ctx == NULL || (len & 0x7) != 0) { | ||
1160 | // psTraceCrypto("Bad parameters to psAesEncrypt\n"); | ||
1161 | // return PS_ARG_FAIL; | ||
1162 | // } | ||
1163 | if ((len & 0x7) != 0) | ||
1164 | bb_error_msg_and_die("AES len:%d", len); | ||
1165 | |||
1166 | /* | ||
1167 | is blocklen valid? | ||
1168 | */ | ||
1169 | if (ctx->aes.blocklen < 0 || (ctx->aes.blocklen > | ||
1170 | (int32)sizeof(ctx->aes.IV))) { | ||
1171 | psTraceCrypto("Bad blocklen in psAesEncrypt\n"); | ||
1172 | return PS_LIMIT_FAIL; | ||
1173 | } | ||
1174 | |||
1175 | for (i = 0; i < len; i += ctx->aes.blocklen) { | ||
1176 | /* | ||
1177 | xor IV against plaintext | ||
1178 | */ | ||
1179 | for (x = 0; x < ctx->aes.blocklen; x++) { | ||
1180 | tmp[x] = pt[x] ^ ctx->aes.IV[x]; | ||
1181 | } | ||
1182 | /* | ||
1183 | encrypt | ||
1184 | */ | ||
1185 | psAesEncryptBlock(tmp, ct, &ctx->aes.key); | ||
1186 | |||
1187 | /* | ||
1188 | store IV [ciphertext] for a future block | ||
1189 | */ | ||
1190 | for (x = 0; x < ctx->aes.blocklen; x++) { | ||
1191 | ctx->aes.IV[x] = ct[x]; | ||
1192 | } | ||
1193 | ct += ctx->aes.blocklen; | ||
1194 | pt += ctx->aes.blocklen; | ||
1195 | } | ||
1196 | |||
1197 | memset_s(tmp, sizeof(tmp), 0x0, sizeof(tmp)); | ||
1198 | return len; | ||
1199 | } | ||
1200 | |||
1201 | static //bbox | ||
1202 | int32 psAesDecrypt(psCipherContext_t *ctx, const unsigned char *ct, | ||
1203 | unsigned char *pt, uint32 len) | ||
1204 | { | ||
1205 | int32 x; | ||
1206 | uint32 i; | ||
1207 | unsigned char tmp[MAXBLOCKSIZE], tmp2[MAXBLOCKSIZE]; | ||
1208 | |||
1209 | //bbox | ||
1210 | // if (pt == NULL || ct == NULL || ctx == NULL || (len & 0x7) != 0) { | ||
1211 | // psTraceCrypto("Bad parameters to psAesDecrypt\n"); | ||
1212 | // return PS_ARG_FAIL; | ||
1213 | // } | ||
1214 | if ((len & 0x7) != 0) | ||
1215 | bb_error_msg_and_die("AES len:%d", len); | ||
1216 | |||
1217 | /* | ||
1218 | is blocklen valid? | ||
1219 | */ | ||
1220 | if (ctx->aes.blocklen < 0 || (ctx->aes.blocklen > | ||
1221 | (int32)sizeof(ctx->aes.IV))) { | ||
1222 | psTraceCrypto("Bad blocklen in psAesDecrypt\n"); | ||
1223 | return PS_LIMIT_FAIL; | ||
1224 | } | ||
1225 | for (i = 0; i < len; i += ctx->aes.blocklen) { | ||
1226 | /* | ||
1227 | decrypt the block from ct into tmp | ||
1228 | */ | ||
1229 | psAesDecryptBlock(ct, tmp, &ctx->aes.key); | ||
1230 | /* | ||
1231 | xor IV against the plaintext of the previous step | ||
1232 | */ | ||
1233 | for (x = 0; x < ctx->aes.blocklen; x++) { | ||
1234 | /* | ||
1235 | copy CT in case ct == pt | ||
1236 | */ | ||
1237 | tmp2[x] = ct[x]; | ||
1238 | /* | ||
1239 | actually decrypt the byte | ||
1240 | */ | ||
1241 | pt[x] = tmp[x] ^ ctx->aes.IV[x]; | ||
1242 | } | ||
1243 | /* | ||
1244 | replace IV with this current ciphertext | ||
1245 | */ | ||
1246 | for (x = 0; x < ctx->aes.blocklen; x++) { | ||
1247 | ctx->aes.IV[x] = tmp2[x]; | ||
1248 | } | ||
1249 | ct += ctx->aes.blocklen; | ||
1250 | pt += ctx->aes.blocklen; | ||
1251 | } | ||
1252 | memset_s(tmp, sizeof(tmp), 0x0, sizeof(tmp)); | ||
1253 | memset_s(tmp2, sizeof(tmp2), 0x0, sizeof(tmp2)); | ||
1254 | |||
1255 | return len; | ||
1256 | } | ||
1257 | |||
1258 | #endif /* USE_AES_CBC_EXTERNAL */ | ||
1259 | |||
1260 | /******************************************************************************/ | ||
1261 | /* | ||
1262 | Initialize the AES (Rijndael) block cipher | ||
1263 | |||
1264 | key: The symmetric key you wish to pass | ||
1265 | keylen: The key length in bytes | ||
1266 | skey: The key in as scheduled by this function. | ||
1267 | */ | ||
1268 | |||
1269 | static //bbox | ||
1270 | int32 psAesInitKey(const unsigned char *key, uint32 keylen, psAesKey_t *skey) | ||
1271 | { | ||
1272 | int32 i, j; | ||
1273 | uint32 temp, *rk, *rrk; | ||
1274 | |||
1275 | //bbox | ||
1276 | // if (key == NULL || skey == NULL) { | ||
1277 | // psTraceCrypto("Bad args to psAesInitKey\n"); | ||
1278 | // return PS_ARG_FAIL; | ||
1279 | // } | ||
1280 | |||
1281 | if (keylen != 16 && keylen != 24 && keylen != 32) { | ||
1282 | psTraceCrypto("Invalid AES key length\n"); | ||
1283 | //bbox return CRYPT_INVALID_KEYSIZE; | ||
1284 | //unreachable anyway | ||
1285 | return PS_ARG_FAIL; | ||
1286 | } | ||
1287 | |||
1288 | memset(skey, 0x0, sizeof(psAesKey_t)); | ||
1289 | skey->Nr = 10 + ((keylen/8)-2)*2; | ||
1290 | |||
1291 | /* | ||
1292 | setup the forward key | ||
1293 | */ | ||
1294 | i = 0; | ||
1295 | rk = skey->eK; | ||
1296 | LOAD32H(rk[0], key ); | ||
1297 | LOAD32H(rk[1], key + 4); | ||
1298 | LOAD32H(rk[2], key + 8); | ||
1299 | LOAD32H(rk[3], key + 12); | ||
1300 | if (keylen == 16) { | ||
1301 | j = 44; | ||
1302 | for (;;) { | ||
1303 | temp = rk[3]; | ||
1304 | rk[4] = rk[0] ^ setup_mix(temp) ^ rcon[i]; | ||
1305 | rk[5] = rk[1] ^ rk[4]; | ||
1306 | rk[6] = rk[2] ^ rk[5]; | ||
1307 | rk[7] = rk[3] ^ rk[6]; | ||
1308 | if (++i == 10) { | ||
1309 | break; | ||
1310 | } | ||
1311 | rk += 4; | ||
1312 | } | ||
1313 | } else if (keylen == 24) { | ||
1314 | j = 52; | ||
1315 | LOAD32H(rk[4], key + 16); | ||
1316 | LOAD32H(rk[5], key + 20); | ||
1317 | for (;;) { | ||
1318 | #ifdef _MSC_VER | ||
1319 | temp = skey->eK[rk - skey->eK + 5]; | ||
1320 | #else | ||
1321 | temp = rk[5]; | ||
1322 | #endif /* _MSC_VER */ | ||
1323 | rk[ 6] = rk[ 0] ^ setup_mix(temp) ^ rcon[i]; | ||
1324 | rk[ 7] = rk[ 1] ^ rk[ 6]; | ||
1325 | rk[ 8] = rk[ 2] ^ rk[ 7]; | ||
1326 | rk[ 9] = rk[ 3] ^ rk[ 8]; | ||
1327 | if (++i == 8) { | ||
1328 | break; | ||
1329 | } | ||
1330 | rk[10] = rk[ 4] ^ rk[ 9]; | ||
1331 | rk[11] = rk[ 5] ^ rk[10]; | ||
1332 | rk += 6; | ||
1333 | } | ||
1334 | } else if (keylen == 32) { | ||
1335 | j = 60; | ||
1336 | LOAD32H(rk[4], key + 16); | ||
1337 | LOAD32H(rk[5], key + 20); | ||
1338 | LOAD32H(rk[6], key + 24); | ||
1339 | LOAD32H(rk[7], key + 28); | ||
1340 | for (;;) { | ||
1341 | #ifdef _MSC_VER | ||
1342 | temp = skey->eK[rk - skey->eK + 7]; | ||
1343 | #else | ||
1344 | temp = rk[7]; | ||
1345 | #endif /* _MSC_VER */ | ||
1346 | rk[ 8] = rk[ 0] ^ setup_mix(temp) ^ rcon[i]; | ||
1347 | rk[ 9] = rk[ 1] ^ rk[ 8]; | ||
1348 | rk[10] = rk[ 2] ^ rk[ 9]; | ||
1349 | rk[11] = rk[ 3] ^ rk[10]; | ||
1350 | if (++i == 7) { | ||
1351 | break; | ||
1352 | } | ||
1353 | temp = rk[11]; | ||
1354 | rk[12] = rk[ 4] ^ setup_mix(ROR(temp, 8)); | ||
1355 | rk[13] = rk[ 5] ^ rk[12]; | ||
1356 | rk[14] = rk[ 6] ^ rk[13]; | ||
1357 | rk[15] = rk[ 7] ^ rk[14]; | ||
1358 | rk += 8; | ||
1359 | } | ||
1360 | } else { | ||
1361 | /* | ||
1362 | this can't happen | ||
1363 | */ | ||
1364 | return PS_FAILURE; | ||
1365 | } | ||
1366 | |||
1367 | /* | ||
1368 | setup the inverse key now | ||
1369 | */ | ||
1370 | rk = skey->dK; | ||
1371 | rrk = skey->eK + j - 4; | ||
1372 | |||
1373 | /* | ||
1374 | apply the inverse MixColumn transform to all round keys but | ||
1375 | the first and the last: | ||
1376 | */ | ||
1377 | /* copy first */ | ||
1378 | *rk++ = *rrk++; | ||
1379 | *rk++ = *rrk++; | ||
1380 | *rk++ = *rrk++; | ||
1381 | *rk = *rrk; | ||
1382 | rk -= 3; rrk -= 3; | ||
1383 | |||
1384 | for (i = 1; i < skey->Nr; i++) { | ||
1385 | rrk -= 4; | ||
1386 | rk += 4; | ||
1387 | #ifndef PS_AES_IMPROVE_PERF_INCREASE_CODESIZE | ||
1388 | temp = rrk[0]; | ||
1389 | rk[0] = setup_mix2(temp); | ||
1390 | temp = rrk[1]; | ||
1391 | rk[1] = setup_mix2(temp); | ||
1392 | temp = rrk[2]; | ||
1393 | rk[2] = setup_mix2(temp); | ||
1394 | temp = rrk[3]; | ||
1395 | rk[3] = setup_mix2(temp); | ||
1396 | #else /* PS_AES_IMPROVE_PERF_INCREASE_CODESIZE */ | ||
1397 | temp = rrk[0]; | ||
1398 | rk[0] = | ||
1399 | Tks0[byte(temp, 3)] ^ | ||
1400 | Tks1[byte(temp, 2)] ^ | ||
1401 | Tks2[byte(temp, 1)] ^ | ||
1402 | Tks3[byte(temp, 0)]; | ||
1403 | temp = rrk[1]; | ||
1404 | rk[1] = | ||
1405 | Tks0[byte(temp, 3)] ^ | ||
1406 | Tks1[byte(temp, 2)] ^ | ||
1407 | Tks2[byte(temp, 1)] ^ | ||
1408 | Tks3[byte(temp, 0)]; | ||
1409 | temp = rrk[2]; | ||
1410 | rk[2] = | ||
1411 | Tks0[byte(temp, 3)] ^ | ||
1412 | Tks1[byte(temp, 2)] ^ | ||
1413 | Tks2[byte(temp, 1)] ^ | ||
1414 | Tks3[byte(temp, 0)]; | ||
1415 | temp = rrk[3]; | ||
1416 | rk[3] = | ||
1417 | Tks0[byte(temp, 3)] ^ | ||
1418 | Tks1[byte(temp, 2)] ^ | ||
1419 | Tks2[byte(temp, 1)] ^ | ||
1420 | Tks3[byte(temp, 0)]; | ||
1421 | #endif /* PS_AES_IMPROVE_PERF_INCREASE_CODESIZE */ | ||
1422 | } | ||
1423 | |||
1424 | /* copy last */ | ||
1425 | rrk -= 4; | ||
1426 | rk += 4; | ||
1427 | *rk++ = *rrk++; | ||
1428 | *rk++ = *rrk++; | ||
1429 | *rk++ = *rrk++; | ||
1430 | *rk = *rrk; | ||
1431 | |||
1432 | return PS_SUCCESS; | ||
1433 | } | ||
1434 | |||
1435 | |||
1436 | #ifdef USE_BURN_STACK | ||
1437 | static //bbox | ||
1438 | void psAesEncryptBlock(const unsigned char *pt, unsigned char *ct, | ||
1439 | psAesKey_t *skey) | ||
1440 | { | ||
1441 | _aes_ecb_encrypt(pt, ct, skey); | ||
1442 | psBurnStack(sizeof(uint32)*8 + sizeof(uint32*) + sizeof(int32)*2); | ||
1443 | } | ||
1444 | static void _aes_ecb_encrypt(const unsigned char *pt, unsigned char *ct, | ||
1445 | psAesKey_t *skey) | ||
1446 | #else | ||
1447 | static //bbox | ||
1448 | void psAesEncryptBlock(const unsigned char *pt, unsigned char *ct, | ||
1449 | psAesKey_t *skey) | ||
1450 | #endif /* USE_BURN_STACK */ | ||
1451 | { | ||
1452 | uint32 s0, s1, s2, s3, t0, t1, t2, t3, *rk; | ||
1453 | int32 Nr, r; | ||
1454 | |||
1455 | //bbox | ||
1456 | // if (pt == NULL || ct == NULL || skey == NULL) { | ||
1457 | // return; | ||
1458 | // } | ||
1459 | |||
1460 | Nr = skey->Nr; | ||
1461 | rk = skey->eK; | ||
1462 | |||
1463 | /* | ||
1464 | map byte array block to cipher state | ||
1465 | and add initial round key: | ||
1466 | */ | ||
1467 | LOAD32H(s0, pt ); s0 ^= rk[0]; | ||
1468 | LOAD32H(s1, pt + 4); s1 ^= rk[1]; | ||
1469 | LOAD32H(s2, pt + 8); s2 ^= rk[2]; | ||
1470 | LOAD32H(s3, pt + 12); s3 ^= rk[3]; | ||
1471 | |||
1472 | #ifndef PS_AES_IMPROVE_PERF_INCREASE_CODESIZE | ||
1473 | for (r = 0; ; r++) { | ||
1474 | rk += 4; | ||
1475 | t0 = | ||
1476 | Te0(byte(s0, 3)) ^ | ||
1477 | Te1(byte(s1, 2)) ^ | ||
1478 | Te2(byte(s2, 1)) ^ | ||
1479 | Te3(byte(s3, 0)) ^ | ||
1480 | rk[0]; | ||
1481 | t1 = | ||
1482 | Te0(byte(s1, 3)) ^ | ||
1483 | Te1(byte(s2, 2)) ^ | ||
1484 | Te2(byte(s3, 1)) ^ | ||
1485 | Te3(byte(s0, 0)) ^ | ||
1486 | rk[1]; | ||
1487 | t2 = | ||
1488 | Te0(byte(s2, 3)) ^ | ||
1489 | Te1(byte(s3, 2)) ^ | ||
1490 | Te2(byte(s0, 1)) ^ | ||
1491 | Te3(byte(s1, 0)) ^ | ||
1492 | rk[2]; | ||
1493 | t3 = | ||
1494 | Te0(byte(s3, 3)) ^ | ||
1495 | Te1(byte(s0, 2)) ^ | ||
1496 | Te2(byte(s1, 1)) ^ | ||
1497 | Te3(byte(s2, 0)) ^ | ||
1498 | rk[3]; | ||
1499 | if (r == Nr-2) { | ||
1500 | break; | ||
1501 | } | ||
1502 | s0 = t0; s1 = t1; s2 = t2; s3 = t3; | ||
1503 | } | ||
1504 | rk += 4; | ||
1505 | #else /* PS_AES_IMPROVE_PERF_INCREASE_CODESIZE */ | ||
1506 | |||
1507 | /* | ||
1508 | Nr - 1 full rounds: | ||
1509 | */ | ||
1510 | r = Nr >> 1; | ||
1511 | for (;;) { | ||
1512 | |||
1513 | t0 = | ||
1514 | Te0(byte(s0, 3)) ^ | ||
1515 | Te1(byte(s1, 2)) ^ | ||
1516 | Te2(byte(s2, 1)) ^ | ||
1517 | Te3(byte(s3, 0)) ^ | ||
1518 | rk[4]; | ||
1519 | t1 = | ||
1520 | Te0(byte(s1, 3)) ^ | ||
1521 | Te1(byte(s2, 2)) ^ | ||
1522 | Te2(byte(s3, 1)) ^ | ||
1523 | Te3(byte(s0, 0)) ^ | ||
1524 | rk[5]; | ||
1525 | t2 = | ||
1526 | Te0(byte(s2, 3)) ^ | ||
1527 | Te1(byte(s3, 2)) ^ | ||
1528 | Te2(byte(s0, 1)) ^ | ||
1529 | Te3(byte(s1, 0)) ^ | ||
1530 | rk[6]; | ||
1531 | t3 = | ||
1532 | Te0(byte(s3, 3)) ^ | ||
1533 | Te1(byte(s0, 2)) ^ | ||
1534 | Te2(byte(s1, 1)) ^ | ||
1535 | Te3(byte(s2, 0)) ^ | ||
1536 | rk[7]; | ||
1537 | |||
1538 | rk += 8; | ||
1539 | if (--r == 0) { | ||
1540 | break; | ||
1541 | } | ||
1542 | |||
1543 | s0 = | ||
1544 | Te0(byte(t0, 3)) ^ | ||
1545 | Te1(byte(t1, 2)) ^ | ||
1546 | Te2(byte(t2, 1)) ^ | ||
1547 | Te3(byte(t3, 0)) ^ | ||
1548 | rk[0]; | ||
1549 | s1 = | ||
1550 | Te0(byte(t1, 3)) ^ | ||
1551 | Te1(byte(t2, 2)) ^ | ||
1552 | Te2(byte(t3, 1)) ^ | ||
1553 | Te3(byte(t0, 0)) ^ | ||
1554 | rk[1]; | ||
1555 | s2 = | ||
1556 | Te0(byte(t2, 3)) ^ | ||
1557 | Te1(byte(t3, 2)) ^ | ||
1558 | Te2(byte(t0, 1)) ^ | ||
1559 | Te3(byte(t1, 0)) ^ | ||
1560 | rk[2]; | ||
1561 | s3 = | ||
1562 | Te0(byte(t3, 3)) ^ | ||
1563 | Te1(byte(t0, 2)) ^ | ||
1564 | Te2(byte(t1, 1)) ^ | ||
1565 | Te3(byte(t2, 0)) ^ | ||
1566 | rk[3]; | ||
1567 | } | ||
1568 | #endif /* PS_AES_IMPROVE_PERF_INCREASE_CODESIZE */ | ||
1569 | |||
1570 | /* | ||
1571 | apply last round and map cipher state to byte array block: | ||
1572 | */ | ||
1573 | s0 = | ||
1574 | (Te4_3[byte(t0, 3)]) ^ | ||
1575 | (Te4_2[byte(t1, 2)]) ^ | ||
1576 | (Te4_1[byte(t2, 1)]) ^ | ||
1577 | (Te4_0[byte(t3, 0)]) ^ | ||
1578 | rk[0]; | ||
1579 | STORE32H(s0, ct); | ||
1580 | s1 = | ||
1581 | (Te4_3[byte(t1, 3)]) ^ | ||
1582 | (Te4_2[byte(t2, 2)]) ^ | ||
1583 | (Te4_1[byte(t3, 1)]) ^ | ||
1584 | (Te4_0[byte(t0, 0)]) ^ | ||
1585 | rk[1]; | ||
1586 | STORE32H(s1, ct+4); | ||
1587 | s2 = | ||
1588 | (Te4_3[byte(t2, 3)]) ^ | ||
1589 | (Te4_2[byte(t3, 2)]) ^ | ||
1590 | (Te4_1[byte(t0, 1)]) ^ | ||
1591 | (Te4_0[byte(t1, 0)]) ^ | ||
1592 | rk[2]; | ||
1593 | STORE32H(s2, ct+8); | ||
1594 | s3 = | ||
1595 | (Te4_3[byte(t3, 3)]) ^ | ||
1596 | (Te4_2[byte(t0, 2)]) ^ | ||
1597 | (Te4_1[byte(t1, 1)]) ^ | ||
1598 | (Te4_0[byte(t2, 0)]) ^ | ||
1599 | rk[3]; | ||
1600 | STORE32H(s3, ct+12); | ||
1601 | } | ||
1602 | |||
1603 | #ifdef USE_BURN_STACK | ||
1604 | static //bbox | ||
1605 | void psAesDecryptBlock(const unsigned char *ct, unsigned char *pt, | ||
1606 | psAesKey_t *skey) | ||
1607 | { | ||
1608 | _aes_ecb_decrypt(ct, pt, skey); | ||
1609 | psBurnStack(sizeof(uint32)*8 + sizeof(uint32*) + sizeof(int32)*2); | ||
1610 | } | ||
1611 | static void _aes_ecb_decrypt(const unsigned char *ct, unsigned char *pt, | ||
1612 | psAesKey_t *skey) | ||
1613 | #else | ||
1614 | static //bbox | ||
1615 | void psAesDecryptBlock(const unsigned char *ct, unsigned char *pt, | ||
1616 | psAesKey_t *skey) | ||
1617 | #endif /* USE_BURN_STACK */ | ||
1618 | { | ||
1619 | uint32 s0, s1, s2, s3, t0, t1, t2, t3, *rk; | ||
1620 | int32 Nr, r; | ||
1621 | |||
1622 | //bbox | ||
1623 | // if (pt == NULL || ct == NULL || skey == NULL) { | ||
1624 | // return; | ||
1625 | // } | ||
1626 | |||
1627 | Nr = skey->Nr; | ||
1628 | rk = skey->dK; | ||
1629 | |||
1630 | /* | ||
1631 | map byte array block to cipher state and add initial round key: | ||
1632 | */ | ||
1633 | LOAD32H(s0, ct ); s0 ^= rk[0]; | ||
1634 | LOAD32H(s1, ct + 4); s1 ^= rk[1]; | ||
1635 | LOAD32H(s2, ct + 8); s2 ^= rk[2]; | ||
1636 | LOAD32H(s3, ct + 12); s3 ^= rk[3]; | ||
1637 | |||
1638 | #ifndef PS_AES_IMPROVE_PERF_INCREASE_CODESIZE | ||
1639 | for (r = 0; ; r++) { | ||
1640 | rk += 4; | ||
1641 | t0 = | ||
1642 | Td0(byte(s0, 3)) ^ | ||
1643 | Td1(byte(s3, 2)) ^ | ||
1644 | Td2(byte(s2, 1)) ^ | ||
1645 | Td3(byte(s1, 0)) ^ | ||
1646 | rk[0]; | ||
1647 | t1 = | ||
1648 | Td0(byte(s1, 3)) ^ | ||
1649 | Td1(byte(s0, 2)) ^ | ||
1650 | Td2(byte(s3, 1)) ^ | ||
1651 | Td3(byte(s2, 0)) ^ | ||
1652 | rk[1]; | ||
1653 | t2 = | ||
1654 | Td0(byte(s2, 3)) ^ | ||
1655 | Td1(byte(s1, 2)) ^ | ||
1656 | Td2(byte(s0, 1)) ^ | ||
1657 | Td3(byte(s3, 0)) ^ | ||
1658 | rk[2]; | ||
1659 | t3 = | ||
1660 | Td0(byte(s3, 3)) ^ | ||
1661 | Td1(byte(s2, 2)) ^ | ||
1662 | Td2(byte(s1, 1)) ^ | ||
1663 | Td3(byte(s0, 0)) ^ | ||
1664 | rk[3]; | ||
1665 | if (r == Nr-2) { | ||
1666 | break; | ||
1667 | } | ||
1668 | s0 = t0; s1 = t1; s2 = t2; s3 = t3; | ||
1669 | } | ||
1670 | rk += 4; | ||
1671 | |||
1672 | #else /* PS_AES_IMPROVE_PERF_INCREASE_CODESIZE */ | ||
1673 | |||
1674 | /* | ||
1675 | Nr - 1 full rounds: | ||
1676 | */ | ||
1677 | r = Nr >> 1; | ||
1678 | for (;;) { | ||
1679 | |||
1680 | t0 = | ||
1681 | Td0(byte(s0, 3)) ^ | ||
1682 | Td1(byte(s3, 2)) ^ | ||
1683 | Td2(byte(s2, 1)) ^ | ||
1684 | Td3(byte(s1, 0)) ^ | ||
1685 | rk[4]; | ||
1686 | t1 = | ||
1687 | Td0(byte(s1, 3)) ^ | ||
1688 | Td1(byte(s0, 2)) ^ | ||
1689 | Td2(byte(s3, 1)) ^ | ||
1690 | Td3(byte(s2, 0)) ^ | ||
1691 | rk[5]; | ||
1692 | t2 = | ||
1693 | Td0(byte(s2, 3)) ^ | ||
1694 | Td1(byte(s1, 2)) ^ | ||
1695 | Td2(byte(s0, 1)) ^ | ||
1696 | Td3(byte(s3, 0)) ^ | ||
1697 | rk[6]; | ||
1698 | t3 = | ||
1699 | Td0(byte(s3, 3)) ^ | ||
1700 | Td1(byte(s2, 2)) ^ | ||
1701 | Td2(byte(s1, 1)) ^ | ||
1702 | Td3(byte(s0, 0)) ^ | ||
1703 | rk[7]; | ||
1704 | |||
1705 | rk += 8; | ||
1706 | if (--r == 0) { | ||
1707 | break; | ||
1708 | } | ||
1709 | |||
1710 | s0 = | ||
1711 | Td0(byte(t0, 3)) ^ | ||
1712 | Td1(byte(t3, 2)) ^ | ||
1713 | Td2(byte(t2, 1)) ^ | ||
1714 | Td3(byte(t1, 0)) ^ | ||
1715 | rk[0]; | ||
1716 | s1 = | ||
1717 | Td0(byte(t1, 3)) ^ | ||
1718 | Td1(byte(t0, 2)) ^ | ||
1719 | Td2(byte(t3, 1)) ^ | ||
1720 | Td3(byte(t2, 0)) ^ | ||
1721 | rk[1]; | ||
1722 | s2 = | ||
1723 | Td0(byte(t2, 3)) ^ | ||
1724 | Td1(byte(t1, 2)) ^ | ||
1725 | Td2(byte(t0, 1)) ^ | ||
1726 | Td3(byte(t3, 0)) ^ | ||
1727 | rk[2]; | ||
1728 | s3 = | ||
1729 | Td0(byte(t3, 3)) ^ | ||
1730 | Td1(byte(t2, 2)) ^ | ||
1731 | Td2(byte(t1, 1)) ^ | ||
1732 | Td3(byte(t0, 0)) ^ | ||
1733 | rk[3]; | ||
1734 | } | ||
1735 | #endif /* PS_AES_IMPROVE_PERF_INCREASE_CODESIZE */ | ||
1736 | |||
1737 | /* | ||
1738 | apply last round and map cipher state to byte array block: | ||
1739 | */ | ||
1740 | s0 = | ||
1741 | (Td4[byte(t0, 3)] & 0xff000000) ^ | ||
1742 | (Td4[byte(t3, 2)] & 0x00ff0000) ^ | ||
1743 | (Td4[byte(t2, 1)] & 0x0000ff00) ^ | ||
1744 | (Td4[byte(t1, 0)] & 0x000000ff) ^ | ||
1745 | rk[0]; | ||
1746 | STORE32H(s0, pt); | ||
1747 | s1 = | ||
1748 | (Td4[byte(t1, 3)] & 0xff000000) ^ | ||
1749 | (Td4[byte(t0, 2)] & 0x00ff0000) ^ | ||
1750 | (Td4[byte(t3, 1)] & 0x0000ff00) ^ | ||
1751 | (Td4[byte(t2, 0)] & 0x000000ff) ^ | ||
1752 | rk[1]; | ||
1753 | STORE32H(s1, pt+4); | ||
1754 | s2 = | ||
1755 | (Td4[byte(t2, 3)] & 0xff000000) ^ | ||
1756 | (Td4[byte(t1, 2)] & 0x00ff0000) ^ | ||
1757 | (Td4[byte(t0, 1)] & 0x0000ff00) ^ | ||
1758 | (Td4[byte(t3, 0)] & 0x000000ff) ^ | ||
1759 | rk[2]; | ||
1760 | STORE32H(s2, pt+8); | ||
1761 | s3 = | ||
1762 | (Td4[byte(t3, 3)] & 0xff000000) ^ | ||
1763 | (Td4[byte(t2, 2)] & 0x00ff0000) ^ | ||
1764 | (Td4[byte(t1, 1)] & 0x0000ff00) ^ | ||
1765 | (Td4[byte(t0, 0)] & 0x000000ff) ^ | ||
1766 | rk[3]; | ||
1767 | STORE32H(s3, pt+12); | ||
1768 | } | ||
1769 | |||
1770 | |||
1771 | /******************************************************************************/ | ||
1772 | /******************************************************************************/ | ||
1773 | #endif /* !USE_AES_CBC_EXTERNAL */ | ||
1774 | #endif /* USE_AES */ | ||
1775 | /******************************************************************************/ | ||
1776 | |||
diff --git a/networking/tls_aes.h b/networking/tls_aes.h new file mode 100644 index 000000000..c6791866a --- /dev/null +++ b/networking/tls_aes.h | |||
@@ -0,0 +1,10 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2017 Denys Vlasenko | ||
3 | * | ||
4 | * Licensed under GPLv2, see file LICENSE in this source tree. | ||
5 | * | ||
6 | * Selected few declarations for AES. | ||
7 | */ | ||
8 | |||
9 | void aes_cbc_encrypt(const void *key, int klen, void *iv, const void *data, size_t len, void *dst); | ||
10 | void aes_cbc_decrypt(const void *key, int klen, void *iv, const void *data, size_t len, void *dst); | ||
diff --git a/networking/tls_pstm.c b/networking/tls_pstm.c new file mode 100644 index 000000000..acd800307 --- /dev/null +++ b/networking/tls_pstm.c | |||
@@ -0,0 +1,2263 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2017 Denys Vlasenko | ||
3 | * | ||
4 | * Licensed under GPLv2, see file LICENSE in this source tree. | ||
5 | */ | ||
6 | #include "tls.h" | ||
7 | |||
8 | /* The file is taken almost verbatim from matrixssl-3-7-2b-open/crypto/math/. | ||
9 | * Changes are flagged with //bbox | ||
10 | */ | ||
11 | |||
12 | /** | ||
13 | * @file pstm.c | ||
14 | * @version 33ef80f (HEAD, tag: MATRIXSSL-3-7-2-OPEN, tag: MATRIXSSL-3-7-2-COMM, origin/master, origin/HEAD, master) | ||
15 | * | ||
16 | * Multiprecision number implementation. | ||
17 | */ | ||
18 | /* | ||
19 | * Copyright (c) 2013-2015 INSIDE Secure Corporation | ||
20 | * Copyright (c) PeerSec Networks, 2002-2011 | ||
21 | * All Rights Reserved | ||
22 | * | ||
23 | * The latest version of this code is available at http://www.matrixssl.org | ||
24 | * | ||
25 | * This software is open source; you can redistribute it and/or modify | ||
26 | * it under the terms of the GNU General Public License as published by | ||
27 | * the Free Software Foundation; either version 2 of the License, or | ||
28 | * (at your option) any later version. | ||
29 | * | ||
30 | * This General Public License does NOT permit incorporating this software | ||
31 | * into proprietary programs. If you are unable to comply with the GPL, a | ||
32 | * commercial license for this software may be purchased from INSIDE at | ||
33 | * http://www.insidesecure.com/eng/Company/Locations | ||
34 | * | ||
35 | * This program is distributed in WITHOUT ANY WARRANTY; without even the | ||
36 | * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. | ||
37 | * See the GNU General Public License for more details. | ||
38 | * | ||
39 | * You should have received a copy of the GNU General Public License | ||
40 | * along with this program; if not, write to the Free Software | ||
41 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
42 | * http://www.gnu.org/copyleft/gpl.html | ||
43 | */ | ||
44 | /******************************************************************************/ | ||
45 | |||
46 | //bbox | ||
47 | //#include "../cryptoApi.h" | ||
48 | #ifndef DISABLE_PSTM | ||
49 | |||
50 | static int32 pstm_mul_2d(pstm_int *a, int16 b, pstm_int *c); | ||
51 | |||
52 | /******************************************************************************/ | ||
53 | /* | ||
54 | init an pstm_int for a given size | ||
55 | */ | ||
56 | int32 pstm_init_size(psPool_t *pool, pstm_int * a, uint32 size) | ||
57 | { | ||
58 | //bbox | ||
59 | // uint16 x; | ||
60 | |||
61 | /* | ||
62 | alloc mem | ||
63 | */ | ||
64 | a->dp = xzalloc(sizeof (pstm_digit) * size);//bbox | ||
65 | //bbox a->pool = pool; | ||
66 | a->used = 0; | ||
67 | a->alloc = (int16)size; | ||
68 | a->sign = PSTM_ZPOS; | ||
69 | /* | ||
70 | zero the digits | ||
71 | */ | ||
72 | //bbox | ||
73 | // for (x = 0; x < size; x++) { | ||
74 | // a->dp[x] = 0; | ||
75 | // } | ||
76 | return PSTM_OKAY; | ||
77 | } | ||
78 | |||
79 | /******************************************************************************/ | ||
80 | /* | ||
81 | Init a new pstm_int. | ||
82 | */ | ||
83 | int32 pstm_init(psPool_t *pool, pstm_int * a) | ||
84 | { | ||
85 | //bbox | ||
86 | // int32 i; | ||
87 | /* | ||
88 | allocate memory required and clear it | ||
89 | */ | ||
90 | a->dp = xzalloc(sizeof (pstm_digit) * PSTM_DEFAULT_INIT);//bbox | ||
91 | /* | ||
92 | set the digits to zero | ||
93 | */ | ||
94 | //bbox | ||
95 | // for (i = 0; i < PSTM_DEFAULT_INIT; i++) { | ||
96 | // a->dp[i] = 0; | ||
97 | // } | ||
98 | /* | ||
99 | set the used to zero, allocated digits to the default precision and sign | ||
100 | to positive | ||
101 | */ | ||
102 | //bbox a->pool = pool; | ||
103 | a->used = 0; | ||
104 | a->alloc = PSTM_DEFAULT_INIT; | ||
105 | a->sign = PSTM_ZPOS; | ||
106 | |||
107 | return PSTM_OKAY; | ||
108 | } | ||
109 | |||
110 | /******************************************************************************/ | ||
111 | /* | ||
112 | Grow as required | ||
113 | */ | ||
114 | int32 pstm_grow(pstm_int * a, int16 size) | ||
115 | { | ||
116 | int16 i; | ||
117 | pstm_digit *tmp; | ||
118 | |||
119 | /* | ||
120 | If the alloc size is smaller alloc more ram. | ||
121 | */ | ||
122 | if (a->alloc < size) { | ||
123 | /* | ||
124 | Reallocate the array a->dp | ||
125 | |||
126 | We store the return in a temporary variable in case the operation | ||
127 | failed we don't want to overwrite the dp member of a. | ||
128 | */ | ||
129 | tmp = xrealloc(a->dp, sizeof (pstm_digit) * size);//bbox | ||
130 | /* | ||
131 | reallocation succeeded so set a->dp | ||
132 | */ | ||
133 | a->dp = tmp; | ||
134 | /* | ||
135 | zero excess digits | ||
136 | */ | ||
137 | i = a->alloc; | ||
138 | a->alloc = size; | ||
139 | for (; i < a->alloc; i++) { | ||
140 | a->dp[i] = 0; | ||
141 | } | ||
142 | } | ||
143 | return PSTM_OKAY; | ||
144 | } | ||
145 | |||
146 | /******************************************************************************/ | ||
147 | /* | ||
148 | copy, b = a (b must be pre-allocated) | ||
149 | */ | ||
150 | int32 pstm_copy(pstm_int * a, pstm_int * b) | ||
151 | { | ||
152 | int32 res, n; | ||
153 | |||
154 | /* | ||
155 | If dst == src do nothing | ||
156 | */ | ||
157 | if (a == b) { | ||
158 | return PSTM_OKAY; | ||
159 | } | ||
160 | /* | ||
161 | Grow dest | ||
162 | */ | ||
163 | if (b->alloc < a->used) { | ||
164 | if ((res = pstm_grow (b, a->used)) != PSTM_OKAY) { | ||
165 | return res; | ||
166 | } | ||
167 | } | ||
168 | /* | ||
169 | Zero b and copy the parameters over | ||
170 | */ | ||
171 | { | ||
172 | register pstm_digit *tmpa, *tmpb; | ||
173 | |||
174 | /* pointer aliases */ | ||
175 | /* source */ | ||
176 | tmpa = a->dp; | ||
177 | |||
178 | /* destination */ | ||
179 | tmpb = b->dp; | ||
180 | |||
181 | /* copy all the digits */ | ||
182 | for (n = 0; n < a->used; n++) { | ||
183 | *tmpb++ = *tmpa++; | ||
184 | } | ||
185 | |||
186 | /* clear high digits */ | ||
187 | for (; n < b->used; n++) { | ||
188 | *tmpb++ = 0; | ||
189 | } | ||
190 | } | ||
191 | /* | ||
192 | copy used count and sign | ||
193 | */ | ||
194 | b->used = a->used; | ||
195 | b->sign = a->sign; | ||
196 | return PSTM_OKAY; | ||
197 | } | ||
198 | |||
199 | /******************************************************************************/ | ||
200 | /* | ||
201 | Trim unused digits | ||
202 | |||
203 | This is used to ensure that leading zero digits are trimed and the | ||
204 | leading "used" digit will be non-zero. Typically very fast. Also fixes | ||
205 | the sign if there are no more leading digits | ||
206 | */ | ||
207 | void pstm_clamp(pstm_int * a) | ||
208 | { | ||
209 | /* decrease used while the most significant digit is zero. */ | ||
210 | while (a->used > 0 && a->dp[a->used - 1] == 0) { | ||
211 | --(a->used); | ||
212 | } | ||
213 | /* reset the sign flag if used == 0 */ | ||
214 | if (a->used == 0) { | ||
215 | a->sign = PSTM_ZPOS; | ||
216 | } | ||
217 | } | ||
218 | |||
219 | /******************************************************************************/ | ||
220 | /* | ||
221 | clear one (frees). | ||
222 | */ | ||
223 | void pstm_clear(pstm_int * a) | ||
224 | { | ||
225 | int32 i; | ||
226 | /* | ||
227 | only do anything if a hasn't been freed previously | ||
228 | */ | ||
229 | if (a != NULL && a->dp != NULL) { | ||
230 | /* | ||
231 | first zero the digits | ||
232 | */ | ||
233 | for (i = 0; i < a->used; i++) { | ||
234 | a->dp[i] = 0; | ||
235 | } | ||
236 | |||
237 | psFree (a->dp, a->pool); | ||
238 | /* | ||
239 | reset members to make debugging easier | ||
240 | */ | ||
241 | a->dp = NULL; | ||
242 | a->alloc = a->used = 0; | ||
243 | a->sign = PSTM_ZPOS; | ||
244 | } | ||
245 | } | ||
246 | |||
247 | /******************************************************************************/ | ||
248 | /* | ||
249 | clear many (frees). | ||
250 | */ | ||
251 | void pstm_clear_multi(pstm_int *mp0, pstm_int *mp1, pstm_int *mp2, | ||
252 | pstm_int *mp3, pstm_int *mp4, pstm_int *mp5, | ||
253 | pstm_int *mp6, pstm_int *mp7) | ||
254 | { | ||
255 | int32 n; /* Number of ok inits */ | ||
256 | |||
257 | pstm_int *tempArray[9]; | ||
258 | |||
259 | tempArray[0] = mp0; | ||
260 | tempArray[1] = mp1; | ||
261 | tempArray[2] = mp2; | ||
262 | tempArray[3] = mp3; | ||
263 | tempArray[4] = mp4; | ||
264 | tempArray[5] = mp5; | ||
265 | tempArray[6] = mp6; | ||
266 | tempArray[7] = mp7; | ||
267 | tempArray[8] = NULL; | ||
268 | |||
269 | for (n = 0; tempArray[n] != NULL; n++) { | ||
270 | if ((tempArray[n] != NULL) && (tempArray[n]->dp != NULL)) { | ||
271 | pstm_clear(tempArray[n]); | ||
272 | } | ||
273 | } | ||
274 | } | ||
275 | |||
276 | /******************************************************************************/ | ||
277 | /* | ||
278 | Set to zero. | ||
279 | */ | ||
280 | void pstm_zero(pstm_int * a) | ||
281 | { | ||
282 | int32 n; | ||
283 | pstm_digit *tmp; | ||
284 | |||
285 | a->sign = PSTM_ZPOS; | ||
286 | a->used = 0; | ||
287 | |||
288 | tmp = a->dp; | ||
289 | for (n = 0; n < a->alloc; n++) { | ||
290 | *tmp++ = 0; | ||
291 | } | ||
292 | } | ||
293 | |||
294 | |||
295 | /******************************************************************************/ | ||
296 | /* | ||
297 | Compare maginitude of two ints (unsigned). | ||
298 | */ | ||
299 | int32 pstm_cmp_mag(pstm_int * a, pstm_int * b) | ||
300 | { | ||
301 | int16 n; | ||
302 | pstm_digit *tmpa, *tmpb; | ||
303 | |||
304 | /* | ||
305 | compare based on # of non-zero digits | ||
306 | */ | ||
307 | if (a->used > b->used) { | ||
308 | return PSTM_GT; | ||
309 | } | ||
310 | |||
311 | if (a->used < b->used) { | ||
312 | return PSTM_LT; | ||
313 | } | ||
314 | |||
315 | /* alias for a */ | ||
316 | tmpa = a->dp + (a->used - 1); | ||
317 | |||
318 | /* alias for b */ | ||
319 | tmpb = b->dp + (a->used - 1); | ||
320 | |||
321 | /* | ||
322 | compare based on digits | ||
323 | */ | ||
324 | for (n = 0; n < a->used; ++n, --tmpa, --tmpb) { | ||
325 | if (*tmpa > *tmpb) { | ||
326 | return PSTM_GT; | ||
327 | } | ||
328 | if (*tmpa < *tmpb) { | ||
329 | return PSTM_LT; | ||
330 | } | ||
331 | } | ||
332 | return PSTM_EQ; | ||
333 | } | ||
334 | |||
335 | /******************************************************************************/ | ||
336 | /* | ||
337 | Compare two ints (signed) | ||
338 | */ | ||
339 | int32 pstm_cmp(pstm_int * a, pstm_int * b) | ||
340 | { | ||
341 | /* | ||
342 | compare based on sign | ||
343 | */ | ||
344 | if (a->sign != b->sign) { | ||
345 | if (a->sign == PSTM_NEG) { | ||
346 | return PSTM_LT; | ||
347 | } else { | ||
348 | return PSTM_GT; | ||
349 | } | ||
350 | } | ||
351 | /* | ||
352 | compare digits | ||
353 | */ | ||
354 | if (a->sign == PSTM_NEG) { | ||
355 | /* if negative compare opposite direction */ | ||
356 | return pstm_cmp_mag(b, a); | ||
357 | } else { | ||
358 | return pstm_cmp_mag(a, b); | ||
359 | } | ||
360 | } | ||
361 | |||
362 | /******************************************************************************/ | ||
363 | /* | ||
364 | pstm_ints can be initialized more precisely when they will populated | ||
365 | using pstm_read_unsigned_bin since the length of the byte stream is known | ||
366 | */ | ||
367 | int32 pstm_init_for_read_unsigned_bin(psPool_t *pool, pstm_int *a, uint32 len) | ||
368 | { | ||
369 | int32 size; | ||
370 | /* | ||
371 | Need to set this based on how many words max it will take to store the bin. | ||
372 | The magic + 2: | ||
373 | 1 to round up for the remainder of this integer math | ||
374 | 1 for the initial carry of '1' bits that fall between DIGIT_BIT and 8 | ||
375 | */ | ||
376 | size = (((len / sizeof(pstm_digit)) * (sizeof(pstm_digit) * CHAR_BIT)) | ||
377 | / DIGIT_BIT) + 2; | ||
378 | return pstm_init_size(pool, a, size); | ||
379 | } | ||
380 | |||
381 | |||
382 | /******************************************************************************/ | ||
383 | /* | ||
384 | Reads a unsigned char array into pstm_int format. User should have | ||
385 | called pstm_init_for_read_unsigned_bin first. There is some grow logic | ||
386 | here if the default pstm_init was used but we don't really want to hit it. | ||
387 | */ | ||
388 | int32 pstm_read_unsigned_bin(pstm_int *a, unsigned char *b, int32 c) | ||
389 | { | ||
390 | /* zero the int */ | ||
391 | pstm_zero (a); | ||
392 | |||
393 | /* | ||
394 | If we know the endianness of this architecture, and we're using | ||
395 | 32-bit pstm_digits, we can optimize this | ||
396 | */ | ||
397 | #if (defined(ENDIAN_LITTLE) || defined(ENDIAN_BIG)) && !defined(PSTM_64BIT) | ||
398 | /* But not for both simultaneously */ | ||
399 | #if defined(ENDIAN_LITTLE) && defined(ENDIAN_BIG) | ||
400 | #error Both ENDIAN_LITTLE and ENDIAN_BIG defined. | ||
401 | #endif | ||
402 | { | ||
403 | unsigned char *pd; | ||
404 | if ((unsigned)c > (PSTM_MAX_SIZE * sizeof(pstm_digit))) { | ||
405 | uint32 excess = c - (PSTM_MAX_SIZE * sizeof(pstm_digit)); | ||
406 | c -= excess; | ||
407 | b += excess; | ||
408 | } | ||
409 | a->used = (int16)((c + sizeof(pstm_digit) - 1)/sizeof(pstm_digit)); | ||
410 | if (a->alloc < a->used) { | ||
411 | if (pstm_grow(a, a->used) != PSTM_OKAY) { | ||
412 | return PSTM_MEM; | ||
413 | } | ||
414 | } | ||
415 | pd = (unsigned char *)a->dp; | ||
416 | /* read the bytes in */ | ||
417 | #ifdef ENDIAN_BIG | ||
418 | { | ||
419 | /* Use Duff's device to unroll the loop. */ | ||
420 | int32 idx = (c - 1) & ~3; | ||
421 | switch (c % 4) { | ||
422 | case 0: do { pd[idx+0] = *b++; | ||
423 | case 3: pd[idx+1] = *b++; | ||
424 | case 2: pd[idx+2] = *b++; | ||
425 | case 1: pd[idx+3] = *b++; | ||
426 | idx -= 4; | ||
427 | } while ((c -= 4) > 0); | ||
428 | } | ||
429 | } | ||
430 | #else | ||
431 | for (c -= 1; c >= 0; c -= 1) { | ||
432 | pd[c] = *b++; | ||
433 | } | ||
434 | #endif | ||
435 | } | ||
436 | #else | ||
437 | /* Big enough based on the len? */ | ||
438 | a->used = (((c / sizeof(pstm_digit)) * (sizeof(pstm_digit) * CHAR_BIT)) | ||
439 | / DIGIT_BIT) + 2; | ||
440 | |||
441 | if (a->alloc < a->used) { | ||
442 | if (pstm_grow(a, a->used) != PSTM_OKAY) { | ||
443 | return PSTM_MEM; | ||
444 | } | ||
445 | } | ||
446 | /* read the bytes in */ | ||
447 | for (; c > 0; c--) { | ||
448 | if (pstm_mul_2d (a, 8, a) != PSTM_OKAY) { | ||
449 | return PS_MEM_FAIL; | ||
450 | } | ||
451 | a->dp[0] |= *b++; | ||
452 | a->used += 1; | ||
453 | } | ||
454 | #endif | ||
455 | |||
456 | pstm_clamp (a); | ||
457 | return PS_SUCCESS; | ||
458 | } | ||
459 | |||
460 | /******************************************************************************/ | ||
461 | /* | ||
462 | */ | ||
463 | int16 pstm_count_bits (pstm_int * a) | ||
464 | { | ||
465 | int16 r; | ||
466 | pstm_digit q; | ||
467 | |||
468 | if (a->used == 0) { | ||
469 | return 0; | ||
470 | } | ||
471 | |||
472 | /* get number of digits and add that */ | ||
473 | r = (a->used - 1) * DIGIT_BIT; | ||
474 | |||
475 | /* take the last digit and count the bits in it */ | ||
476 | q = a->dp[a->used - 1]; | ||
477 | while (q > ((pstm_digit) 0)) { | ||
478 | ++r; | ||
479 | q >>= ((pstm_digit) 1); | ||
480 | } | ||
481 | return r; | ||
482 | } | ||
483 | |||
484 | /******************************************************************************/ | ||
485 | int32 pstm_unsigned_bin_size(pstm_int *a) | ||
486 | { | ||
487 | int32 size = pstm_count_bits (a); | ||
488 | return (size / 8 + ((size & 7) != 0 ? 1 : 0)); | ||
489 | } | ||
490 | |||
491 | /******************************************************************************/ | ||
492 | void pstm_set(pstm_int *a, pstm_digit b) | ||
493 | { | ||
494 | pstm_zero(a); | ||
495 | a->dp[0] = b; | ||
496 | a->used = a->dp[0] ? 1 : 0; | ||
497 | } | ||
498 | |||
499 | /******************************************************************************/ | ||
500 | /* | ||
501 | Right shift | ||
502 | */ | ||
503 | void pstm_rshd(pstm_int *a, int16 x) | ||
504 | { | ||
505 | int16 y; | ||
506 | |||
507 | /* too many digits just zero and return */ | ||
508 | if (x >= a->used) { | ||
509 | pstm_zero(a); | ||
510 | return; | ||
511 | } | ||
512 | |||
513 | /* shift */ | ||
514 | for (y = 0; y < a->used - x; y++) { | ||
515 | a->dp[y] = a->dp[y+x]; | ||
516 | } | ||
517 | |||
518 | /* zero rest */ | ||
519 | for (; y < a->used; y++) { | ||
520 | a->dp[y] = 0; | ||
521 | } | ||
522 | |||
523 | /* decrement count */ | ||
524 | a->used -= x; | ||
525 | pstm_clamp(a); | ||
526 | } | ||
527 | |||
528 | /******************************************************************************/ | ||
529 | /* | ||
530 | Shift left a certain amount of digits. | ||
531 | */ | ||
532 | int32 pstm_lshd(pstm_int * a, int16 b) | ||
533 | { | ||
534 | int16 x; | ||
535 | int32 res; | ||
536 | |||
537 | /* | ||
538 | If its less than zero return. | ||
539 | */ | ||
540 | if (b <= 0) { | ||
541 | return PSTM_OKAY; | ||
542 | } | ||
543 | /* | ||
544 | Grow to fit the new digits. | ||
545 | */ | ||
546 | if (a->alloc < a->used + b) { | ||
547 | if ((res = pstm_grow (a, a->used + b)) != PSTM_OKAY) { | ||
548 | return res; | ||
549 | } | ||
550 | } | ||
551 | |||
552 | { | ||
553 | register pstm_digit *top, *bottom; | ||
554 | /* | ||
555 | Increment the used by the shift amount then copy upwards. | ||
556 | */ | ||
557 | a->used += b; | ||
558 | |||
559 | /* top */ | ||
560 | top = a->dp + a->used - 1; | ||
561 | |||
562 | /* base */ | ||
563 | bottom = a->dp + a->used - 1 - b; | ||
564 | /* | ||
565 | This is implemented using a sliding window except the window goes the | ||
566 | other way around. Copying from the bottom to the top. | ||
567 | */ | ||
568 | for (x = a->used - 1; x >= b; x--) { | ||
569 | *top-- = *bottom--; | ||
570 | } | ||
571 | |||
572 | /* zero the lower digits */ | ||
573 | top = a->dp; | ||
574 | for (x = 0; x < b; x++) { | ||
575 | *top++ = 0; | ||
576 | } | ||
577 | } | ||
578 | return PSTM_OKAY; | ||
579 | } | ||
580 | |||
581 | /******************************************************************************/ | ||
582 | /* | ||
583 | computes a = 2**b | ||
584 | */ | ||
585 | int32 pstm_2expt(pstm_int *a, int16 b) | ||
586 | { | ||
587 | int16 z; | ||
588 | |||
589 | /* zero a as per default */ | ||
590 | pstm_zero (a); | ||
591 | |||
592 | if (b < 0) { | ||
593 | return PSTM_OKAY; | ||
594 | } | ||
595 | |||
596 | z = b / DIGIT_BIT; | ||
597 | if (z >= PSTM_MAX_SIZE) { | ||
598 | return PS_LIMIT_FAIL; | ||
599 | } | ||
600 | |||
601 | /* set the used count of where the bit will go */ | ||
602 | a->used = z + 1; | ||
603 | |||
604 | if (a->used > a->alloc) { | ||
605 | if (pstm_grow(a, a->used) != PSTM_OKAY) { | ||
606 | return PS_MEM_FAIL; | ||
607 | } | ||
608 | } | ||
609 | |||
610 | /* put the single bit in its place */ | ||
611 | a->dp[z] = ((pstm_digit)1) << (b % DIGIT_BIT); | ||
612 | return PSTM_OKAY; | ||
613 | } | ||
614 | |||
615 | /******************************************************************************/ | ||
616 | /* | ||
617 | |||
618 | */ | ||
619 | int32 pstm_mul_2(pstm_int * a, pstm_int * b) | ||
620 | { | ||
621 | int32 res; | ||
622 | int16 x, oldused; | ||
623 | |||
624 | /* | ||
625 | grow to accomodate result | ||
626 | */ | ||
627 | if (b->alloc < a->used + 1) { | ||
628 | if ((res = pstm_grow (b, a->used + 1)) != PSTM_OKAY) { | ||
629 | return res; | ||
630 | } | ||
631 | } | ||
632 | oldused = b->used; | ||
633 | b->used = a->used; | ||
634 | |||
635 | { | ||
636 | register pstm_digit r, rr, *tmpa, *tmpb; | ||
637 | |||
638 | /* alias for source */ | ||
639 | tmpa = a->dp; | ||
640 | |||
641 | /* alias for dest */ | ||
642 | tmpb = b->dp; | ||
643 | |||
644 | /* carry */ | ||
645 | r = 0; | ||
646 | for (x = 0; x < a->used; x++) { | ||
647 | /* | ||
648 | get what will be the *next* carry bit from the | ||
649 | MSB of the current digit | ||
650 | */ | ||
651 | rr = *tmpa >> ((pstm_digit)(DIGIT_BIT - 1)); | ||
652 | /* | ||
653 | now shift up this digit, add in the carry [from the previous] | ||
654 | */ | ||
655 | *tmpb++ = ((*tmpa++ << ((pstm_digit)1)) | r); | ||
656 | /* | ||
657 | copy the carry that would be from the source | ||
658 | digit into the next iteration | ||
659 | */ | ||
660 | r = rr; | ||
661 | } | ||
662 | |||
663 | /* new leading digit? */ | ||
664 | if (r != 0 && b->used != (PSTM_MAX_SIZE-1)) { | ||
665 | /* add a MSB which is always 1 at this point */ | ||
666 | *tmpb = 1; | ||
667 | ++(b->used); | ||
668 | } | ||
669 | /* | ||
670 | now zero any excess digits on the destination that we didn't write to | ||
671 | */ | ||
672 | tmpb = b->dp + b->used; | ||
673 | for (x = b->used; x < oldused; x++) { | ||
674 | *tmpb++ = 0; | ||
675 | } | ||
676 | } | ||
677 | b->sign = a->sign; | ||
678 | return PSTM_OKAY; | ||
679 | } | ||
680 | |||
681 | /******************************************************************************/ | ||
682 | /* | ||
683 | unsigned subtraction ||a|| >= ||b|| ALWAYS! | ||
684 | */ | ||
685 | int32 s_pstm_sub(pstm_int *a, pstm_int *b, pstm_int *c) | ||
686 | { | ||
687 | int16 oldbused, oldused; | ||
688 | int32 x; | ||
689 | pstm_word t; | ||
690 | |||
691 | if (b->used > a->used) { | ||
692 | return PS_LIMIT_FAIL; | ||
693 | } | ||
694 | if (c->alloc < a->used) { | ||
695 | if ((x = pstm_grow (c, a->used)) != PSTM_OKAY) { | ||
696 | return x; | ||
697 | } | ||
698 | } | ||
699 | oldused = c->used; | ||
700 | oldbused = b->used; | ||
701 | c->used = a->used; | ||
702 | t = 0; | ||
703 | |||
704 | for (x = 0; x < oldbused; x++) { | ||
705 | t = ((pstm_word)a->dp[x]) - (((pstm_word)b->dp[x]) + t); | ||
706 | c->dp[x] = (pstm_digit)t; | ||
707 | t = (t >> DIGIT_BIT)&1; | ||
708 | } | ||
709 | for (; x < a->used; x++) { | ||
710 | t = ((pstm_word)a->dp[x]) - t; | ||
711 | c->dp[x] = (pstm_digit)t; | ||
712 | t = (t >> DIGIT_BIT); | ||
713 | } | ||
714 | for (; x < oldused; x++) { | ||
715 | c->dp[x] = 0; | ||
716 | } | ||
717 | pstm_clamp(c); | ||
718 | return PSTM_OKAY; | ||
719 | } | ||
720 | |||
721 | /******************************************************************************/ | ||
722 | /* | ||
723 | unsigned addition | ||
724 | */ | ||
725 | static int32 s_pstm_add(pstm_int *a, pstm_int *b, pstm_int *c) | ||
726 | { | ||
727 | int16 x, y, oldused; | ||
728 | register pstm_word t, adp, bdp; | ||
729 | |||
730 | y = a->used; | ||
731 | if (b->used > y) { | ||
732 | y = b->used; | ||
733 | } | ||
734 | oldused = c->used; | ||
735 | c->used = y; | ||
736 | |||
737 | if (c->used > c->alloc) { | ||
738 | if (pstm_grow(c, c->used) != PSTM_OKAY) { | ||
739 | return PS_MEM_FAIL; | ||
740 | } | ||
741 | } | ||
742 | |||
743 | t = 0; | ||
744 | for (x = 0; x < y; x++) { | ||
745 | if (a->used < x) { | ||
746 | adp = 0; | ||
747 | } else { | ||
748 | adp = (pstm_word)a->dp[x]; | ||
749 | } | ||
750 | if (b->used < x) { | ||
751 | bdp = 0; | ||
752 | } else { | ||
753 | bdp = (pstm_word)b->dp[x]; | ||
754 | } | ||
755 | t += (adp) + (bdp); | ||
756 | c->dp[x] = (pstm_digit)t; | ||
757 | t >>= DIGIT_BIT; | ||
758 | } | ||
759 | if (t != 0 && x < PSTM_MAX_SIZE) { | ||
760 | if (c->used == c->alloc) { | ||
761 | if (pstm_grow(c, c->alloc + 1) != PSTM_OKAY) { | ||
762 | return PS_MEM_FAIL; | ||
763 | } | ||
764 | } | ||
765 | c->dp[c->used++] = (pstm_digit)t; | ||
766 | ++x; | ||
767 | } | ||
768 | |||
769 | c->used = x; | ||
770 | for (; x < oldused; x++) { | ||
771 | c->dp[x] = 0; | ||
772 | } | ||
773 | pstm_clamp(c); | ||
774 | return PSTM_OKAY; | ||
775 | } | ||
776 | |||
777 | |||
778 | /******************************************************************************/ | ||
779 | /* | ||
780 | |||
781 | */ | ||
782 | int32 pstm_sub(pstm_int *a, pstm_int *b, pstm_int *c) | ||
783 | { | ||
784 | int32 res; | ||
785 | int16 sa, sb; | ||
786 | |||
787 | sa = a->sign; | ||
788 | sb = b->sign; | ||
789 | |||
790 | if (sa != sb) { | ||
791 | /* | ||
792 | subtract a negative from a positive, OR a positive from a negative. | ||
793 | For both, ADD their magnitudes, and use the sign of the first number. | ||
794 | */ | ||
795 | c->sign = sa; | ||
796 | if ((res = s_pstm_add (a, b, c)) != PSTM_OKAY) { | ||
797 | return res; | ||
798 | } | ||
799 | } else { | ||
800 | /* | ||
801 | subtract a positive from a positive, OR a negative from a negative. | ||
802 | First, take the difference between their magnitudes, then... | ||
803 | */ | ||
804 | if (pstm_cmp_mag (a, b) != PSTM_LT) { | ||
805 | /* Copy the sign from the first */ | ||
806 | c->sign = sa; | ||
807 | /* The first has a larger or equal magnitude */ | ||
808 | if ((res = s_pstm_sub (a, b, c)) != PSTM_OKAY) { | ||
809 | return res; | ||
810 | } | ||
811 | } else { | ||
812 | /* The result has the _opposite_ sign from the first number. */ | ||
813 | c->sign = (sa == PSTM_ZPOS) ? PSTM_NEG : PSTM_ZPOS; | ||
814 | /* The second has a larger magnitude */ | ||
815 | if ((res = s_pstm_sub (b, a, c)) != PSTM_OKAY) { | ||
816 | return res; | ||
817 | } | ||
818 | } | ||
819 | } | ||
820 | return PS_SUCCESS; | ||
821 | } | ||
822 | |||
823 | /******************************************************************************/ | ||
824 | /* | ||
825 | c = a - b | ||
826 | */ | ||
827 | int32 pstm_sub_d(psPool_t *pool, pstm_int *a, pstm_digit b, pstm_int *c) | ||
828 | { | ||
829 | pstm_int tmp; | ||
830 | int32 res; | ||
831 | |||
832 | if (pstm_init_size(pool, &tmp, sizeof(pstm_digit)) != PSTM_OKAY) { | ||
833 | return PS_MEM_FAIL; | ||
834 | } | ||
835 | pstm_set(&tmp, b); | ||
836 | res = pstm_sub(a, &tmp, c); | ||
837 | pstm_clear(&tmp); | ||
838 | return res; | ||
839 | } | ||
840 | |||
841 | /******************************************************************************/ | ||
842 | /* | ||
843 | setups the montgomery reduction | ||
844 | */ | ||
845 | int32 pstm_montgomery_setup(pstm_int *a, pstm_digit *rho) | ||
846 | { | ||
847 | pstm_digit x, b; | ||
848 | |||
849 | /* | ||
850 | fast inversion mod 2**k | ||
851 | Based on the fact that | ||
852 | XA = 1 (mod 2**n) => (X(2-XA)) A = 1 (mod 2**2n) | ||
853 | => 2*X*A - X*X*A*A = 1 | ||
854 | => 2*(1) - (1) = 1 | ||
855 | */ | ||
856 | b = a->dp[0]; | ||
857 | |||
858 | if ((b & 1) == 0) { | ||
859 | psTraceCrypto("pstm_montogomery_setup failure\n"); | ||
860 | return PS_ARG_FAIL; | ||
861 | } | ||
862 | |||
863 | x = (((b + 2) & 4) << 1) + b; /* here x*a==1 mod 2**4 */ | ||
864 | x *= 2 - b * x; /* here x*a==1 mod 2**8 */ | ||
865 | x *= 2 - b * x; /* here x*a==1 mod 2**16 */ | ||
866 | x *= 2 - b * x; /* here x*a==1 mod 2**32 */ | ||
867 | #ifdef PSTM_64BIT | ||
868 | x *= 2 - b * x; /* here x*a==1 mod 2**64 */ | ||
869 | #endif | ||
870 | /* rho = -1/m mod b */ | ||
871 | *rho = (pstm_digit)(((pstm_word) 1 << ((pstm_word) DIGIT_BIT)) - | ||
872 | ((pstm_word)x)); | ||
873 | return PSTM_OKAY; | ||
874 | } | ||
875 | |||
876 | /******************************************************************************/ | ||
877 | /* | ||
878 | * computes a = B**n mod b without division or multiplication useful for | ||
879 | * normalizing numbers in a Montgomery system. | ||
880 | */ | ||
881 | int32 pstm_montgomery_calc_normalization(pstm_int *a, pstm_int *b) | ||
882 | { | ||
883 | int32 x; | ||
884 | int16 bits; | ||
885 | |||
886 | /* how many bits of last digit does b use */ | ||
887 | bits = pstm_count_bits (b) % DIGIT_BIT; | ||
888 | if (!bits) bits = DIGIT_BIT; | ||
889 | |||
890 | /* compute A = B^(n-1) * 2^(bits-1) */ | ||
891 | if (b->used > 1) { | ||
892 | if ((x = pstm_2expt (a, (b->used - 1) * DIGIT_BIT + bits - 1)) != | ||
893 | PSTM_OKAY) { | ||
894 | return x; | ||
895 | } | ||
896 | } else { | ||
897 | pstm_set(a, 1); | ||
898 | bits = 1; | ||
899 | } | ||
900 | |||
901 | /* now compute C = A * B mod b */ | ||
902 | for (x = bits - 1; x < (int32)DIGIT_BIT; x++) { | ||
903 | if (pstm_mul_2 (a, a) != PSTM_OKAY) { | ||
904 | return PS_MEM_FAIL; | ||
905 | } | ||
906 | if (pstm_cmp_mag (a, b) != PSTM_LT) { | ||
907 | if (s_pstm_sub (a, b, a) != PSTM_OKAY) { | ||
908 | return PS_MEM_FAIL; | ||
909 | } | ||
910 | } | ||
911 | } | ||
912 | return PSTM_OKAY; | ||
913 | } | ||
914 | |||
915 | /******************************************************************************/ | ||
916 | /* | ||
917 | c = a * 2**d | ||
918 | */ | ||
919 | static int32 pstm_mul_2d(pstm_int *a, int16 b, pstm_int *c) | ||
920 | { | ||
921 | pstm_digit carry, carrytmp, shift; | ||
922 | int16 x; | ||
923 | |||
924 | /* copy it */ | ||
925 | if (pstm_copy(a, c) != PSTM_OKAY) { | ||
926 | return PS_MEM_FAIL; | ||
927 | } | ||
928 | |||
929 | /* handle whole digits */ | ||
930 | if (b >= DIGIT_BIT) { | ||
931 | if (pstm_lshd(c, b/DIGIT_BIT) != PSTM_OKAY) { | ||
932 | return PS_MEM_FAIL; | ||
933 | } | ||
934 | } | ||
935 | b %= DIGIT_BIT; | ||
936 | |||
937 | /* shift the digits */ | ||
938 | if (b != 0) { | ||
939 | carry = 0; | ||
940 | shift = DIGIT_BIT - b; | ||
941 | for (x = 0; x < c->used; x++) { | ||
942 | carrytmp = c->dp[x] >> shift; | ||
943 | c->dp[x] = (c->dp[x] << b) + carry; | ||
944 | carry = carrytmp; | ||
945 | } | ||
946 | /* store last carry if room */ | ||
947 | if (carry && x < PSTM_MAX_SIZE) { | ||
948 | if (c->used == c->alloc) { | ||
949 | if (pstm_grow(c, c->alloc + 1) != PSTM_OKAY) { | ||
950 | return PS_MEM_FAIL; | ||
951 | } | ||
952 | } | ||
953 | c->dp[c->used++] = carry; | ||
954 | } | ||
955 | } | ||
956 | pstm_clamp(c); | ||
957 | return PSTM_OKAY; | ||
958 | } | ||
959 | |||
960 | /******************************************************************************/ | ||
961 | /* | ||
962 | c = a mod 2**d | ||
963 | */ | ||
964 | static int32 pstm_mod_2d(pstm_int *a, int16 b, pstm_int *c) | ||
965 | { | ||
966 | int16 x; | ||
967 | |||
968 | /* zero if count less than or equal to zero */ | ||
969 | if (b <= 0) { | ||
970 | pstm_zero(c); | ||
971 | return PSTM_OKAY; | ||
972 | } | ||
973 | |||
974 | /* get copy of input */ | ||
975 | if (pstm_copy(a, c) != PSTM_OKAY) { | ||
976 | return PS_MEM_FAIL; | ||
977 | } | ||
978 | |||
979 | /* if 2**d is larger than we just return */ | ||
980 | if (b >= (DIGIT_BIT * a->used)) { | ||
981 | return PSTM_OKAY; | ||
982 | } | ||
983 | |||
984 | /* zero digits above the last digit of the modulus */ | ||
985 | for (x = (b / DIGIT_BIT) + ((b % DIGIT_BIT) == 0 ? 0 : 1); x < c->used; x++) | ||
986 | { | ||
987 | c->dp[x] = 0; | ||
988 | } | ||
989 | /* clear the digit that is not completely outside/inside the modulus */ | ||
990 | c->dp[b / DIGIT_BIT] &= ~((pstm_digit)0) >> (DIGIT_BIT - b); | ||
991 | pstm_clamp (c); | ||
992 | return PSTM_OKAY; | ||
993 | } | ||
994 | |||
995 | |||
996 | /******************************************************************************/ | ||
997 | /* | ||
998 | c = a * b | ||
999 | */ | ||
1000 | int32 pstm_mul_d(pstm_int *a, pstm_digit b, pstm_int *c) | ||
1001 | { | ||
1002 | pstm_word w; | ||
1003 | int32 res; | ||
1004 | int16 x, oldused; | ||
1005 | |||
1006 | if (c->alloc < a->used + 1) { | ||
1007 | if ((res = pstm_grow (c, a->used + 1)) != PSTM_OKAY) { | ||
1008 | return res; | ||
1009 | } | ||
1010 | } | ||
1011 | oldused = c->used; | ||
1012 | c->used = a->used; | ||
1013 | c->sign = a->sign; | ||
1014 | w = 0; | ||
1015 | for (x = 0; x < a->used; x++) { | ||
1016 | w = ((pstm_word)a->dp[x]) * ((pstm_word)b) + w; | ||
1017 | c->dp[x] = (pstm_digit)w; | ||
1018 | w = w >> DIGIT_BIT; | ||
1019 | } | ||
1020 | if (w != 0 && (a->used != PSTM_MAX_SIZE)) { | ||
1021 | c->dp[c->used++] = (pstm_digit)w; | ||
1022 | ++x; | ||
1023 | } | ||
1024 | for (; x < oldused; x++) { | ||
1025 | c->dp[x] = 0; | ||
1026 | } | ||
1027 | pstm_clamp(c); | ||
1028 | return PSTM_OKAY; | ||
1029 | } | ||
1030 | |||
1031 | /******************************************************************************/ | ||
1032 | /* | ||
1033 | c = a / 2**b | ||
1034 | */ | ||
1035 | int32 pstm_div_2d(psPool_t *pool, pstm_int *a, int16 b, pstm_int *c, | ||
1036 | pstm_int *d) | ||
1037 | { | ||
1038 | pstm_digit D, r, rr; | ||
1039 | int32 res; | ||
1040 | int16 x; | ||
1041 | pstm_int t; | ||
1042 | |||
1043 | /* if the shift count is <= 0 then we do no work */ | ||
1044 | if (b <= 0) { | ||
1045 | if (pstm_copy (a, c) != PSTM_OKAY) { | ||
1046 | return PS_MEM_FAIL; | ||
1047 | } | ||
1048 | if (d != NULL) { | ||
1049 | pstm_zero (d); | ||
1050 | } | ||
1051 | return PSTM_OKAY; | ||
1052 | } | ||
1053 | |||
1054 | /* get the remainder */ | ||
1055 | if (d != NULL) { | ||
1056 | if (pstm_init(pool, &t) != PSTM_OKAY) { | ||
1057 | return PS_MEM_FAIL; | ||
1058 | } | ||
1059 | if (pstm_mod_2d (a, b, &t) != PSTM_OKAY) { | ||
1060 | res = PS_MEM_FAIL; | ||
1061 | goto LBL_DONE; | ||
1062 | } | ||
1063 | } | ||
1064 | |||
1065 | /* copy */ | ||
1066 | if (pstm_copy(a, c) != PSTM_OKAY) { | ||
1067 | res = PS_MEM_FAIL; | ||
1068 | goto LBL_DONE; | ||
1069 | } | ||
1070 | |||
1071 | /* shift by as many digits in the bit count */ | ||
1072 | if (b >= (int32)DIGIT_BIT) { | ||
1073 | pstm_rshd (c, b / DIGIT_BIT); | ||
1074 | } | ||
1075 | |||
1076 | /* shift any bit count < DIGIT_BIT */ | ||
1077 | D = (pstm_digit) (b % DIGIT_BIT); | ||
1078 | if (D != 0) { | ||
1079 | register pstm_digit *tmpc, mask, shift; | ||
1080 | |||
1081 | /* mask */ | ||
1082 | mask = (((pstm_digit)1) << D) - 1; | ||
1083 | |||
1084 | /* shift for lsb */ | ||
1085 | shift = DIGIT_BIT - D; | ||
1086 | |||
1087 | /* alias */ | ||
1088 | tmpc = c->dp + (c->used - 1); | ||
1089 | |||
1090 | /* carry */ | ||
1091 | r = 0; | ||
1092 | for (x = c->used - 1; x >= 0; x--) { | ||
1093 | /* get the lower bits of this word in a temp */ | ||
1094 | rr = *tmpc & mask; | ||
1095 | |||
1096 | /* shift the current word and mix in the carry bits from previous */ | ||
1097 | *tmpc = (*tmpc >> D) | (r << shift); | ||
1098 | --tmpc; | ||
1099 | |||
1100 | /* set the carry to the carry bits of the current word above */ | ||
1101 | r = rr; | ||
1102 | } | ||
1103 | } | ||
1104 | pstm_clamp (c); | ||
1105 | |||
1106 | res = PSTM_OKAY; | ||
1107 | LBL_DONE: | ||
1108 | if (d != NULL) { | ||
1109 | if (pstm_copy(&t, d) != PSTM_OKAY) { | ||
1110 | res = PS_MEM_FAIL; | ||
1111 | } | ||
1112 | pstm_clear(&t); | ||
1113 | } | ||
1114 | return res; | ||
1115 | } | ||
1116 | |||
1117 | /******************************************************************************/ | ||
1118 | /* | ||
1119 | b = a/2 | ||
1120 | */ | ||
1121 | int32 pstm_div_2(pstm_int * a, pstm_int * b) | ||
1122 | { | ||
1123 | int16 x, oldused; | ||
1124 | |||
1125 | if (b->alloc < a->used) { | ||
1126 | if (pstm_grow(b, a->used) != PSTM_OKAY) { | ||
1127 | return PS_MEM_FAIL; | ||
1128 | } | ||
1129 | } | ||
1130 | oldused = b->used; | ||
1131 | b->used = a->used; | ||
1132 | { | ||
1133 | register pstm_digit r, rr, *tmpa, *tmpb; | ||
1134 | |||
1135 | /* source alias */ | ||
1136 | tmpa = a->dp + b->used - 1; | ||
1137 | |||
1138 | /* dest alias */ | ||
1139 | tmpb = b->dp + b->used - 1; | ||
1140 | |||
1141 | /* carry */ | ||
1142 | r = 0; | ||
1143 | for (x = b->used - 1; x >= 0; x--) { | ||
1144 | /* get the carry for the next iteration */ | ||
1145 | rr = *tmpa & 1; | ||
1146 | |||
1147 | /* shift the current digit, add in carry and store */ | ||
1148 | *tmpb-- = (*tmpa-- >> 1) | (r << (DIGIT_BIT - 1)); | ||
1149 | |||
1150 | /* forward carry to next iteration */ | ||
1151 | r = rr; | ||
1152 | } | ||
1153 | |||
1154 | /* zero excess digits */ | ||
1155 | tmpb = b->dp + b->used; | ||
1156 | for (x = b->used; x < oldused; x++) { | ||
1157 | *tmpb++ = 0; | ||
1158 | } | ||
1159 | } | ||
1160 | b->sign = a->sign; | ||
1161 | pstm_clamp (b); | ||
1162 | return PSTM_OKAY; | ||
1163 | } | ||
1164 | |||
1165 | /******************************************************************************/ | ||
1166 | /* | ||
1167 | Creates "a" then copies b into it | ||
1168 | */ | ||
1169 | int32 pstm_init_copy(psPool_t *pool, pstm_int * a, pstm_int * b, int16 toSqr) | ||
1170 | { | ||
1171 | int16 x; | ||
1172 | int32 res; | ||
1173 | |||
1174 | if (a == b) { | ||
1175 | return PSTM_OKAY; | ||
1176 | } | ||
1177 | x = b->alloc; | ||
1178 | |||
1179 | if (toSqr) { | ||
1180 | /* | ||
1181 | Smart-size: Increasing size of a if b->used is roughly half | ||
1182 | of b->alloc because usage has shown that a lot of these copies | ||
1183 | go on to be squared and need these extra digits | ||
1184 | */ | ||
1185 | if ((b->used * 2) + 2 >= x) { | ||
1186 | x = (b->used * 2) + 3; | ||
1187 | } | ||
1188 | } | ||
1189 | if ((res = pstm_init_size(pool, a, x)) != PSTM_OKAY) { | ||
1190 | return res; | ||
1191 | } | ||
1192 | return pstm_copy(b, a); | ||
1193 | } | ||
1194 | |||
1195 | /******************************************************************************/ | ||
1196 | /* | ||
1197 | With some compilers, we have seen issues linking with the builtin | ||
1198 | 64 bit division routine. The issues with either manifest in a failure | ||
1199 | to find 'udivdi3' at link time, or a runtime invalid instruction fault | ||
1200 | during an RSA operation. | ||
1201 | The routine below divides a 64 bit unsigned int by a 32 bit unsigned int | ||
1202 | explicitly, rather than using the division operation | ||
1203 | The 64 bit result is placed in the 'numerator' parameter | ||
1204 | The 32 bit mod (remainder) of the division is the return parameter | ||
1205 | Based on implementations by: | ||
1206 | Copyright (C) 2003 Bernardo Innocenti <bernie@develer.com> | ||
1207 | Copyright (C) 1999 Hewlett-Packard Co | ||
1208 | Copyright (C) 1999 David Mosberger-Tang <davidm@hpl.hp.com> | ||
1209 | */ | ||
1210 | #if defined(USE_MATRIX_DIV64) && defined(PSTM_32BIT) | ||
1211 | static uint32 psDiv64(uint64 *numerator, uint32 denominator) | ||
1212 | { | ||
1213 | uint64 rem = *numerator; | ||
1214 | uint64 b = denominator; | ||
1215 | uint64 res = 0; | ||
1216 | uint64 d = 1; | ||
1217 | uint32 high = rem >> 32; | ||
1218 | |||
1219 | if (high >= denominator) { | ||
1220 | high /= denominator; | ||
1221 | res = (uint64) high << 32; | ||
1222 | rem -= (uint64) (high * denominator) << 32; | ||
1223 | } | ||
1224 | while ((int64)b > 0 && b < rem) { | ||
1225 | b = b+b; | ||
1226 | d = d+d; | ||
1227 | } | ||
1228 | do { | ||
1229 | if (rem >= b) { | ||
1230 | rem -= b; | ||
1231 | res += d; | ||
1232 | } | ||
1233 | b >>= 1; | ||
1234 | d >>= 1; | ||
1235 | } while (d); | ||
1236 | *numerator = res; | ||
1237 | return rem; | ||
1238 | } | ||
1239 | #endif /* USE_MATRIX_DIV64 */ | ||
1240 | |||
1241 | #if defined(USE_MATRIX_DIV128) && defined(PSTM_64BIT) | ||
1242 | typedef unsigned long uint128 __attribute__ ((mode(TI))); | ||
1243 | static uint64 psDiv128(uint128 *numerator, uint64 denominator) | ||
1244 | { | ||
1245 | uint128 rem = *numerator; | ||
1246 | uint128 b = denominator; | ||
1247 | uint128 res = 0; | ||
1248 | uint128 d = 1; | ||
1249 | uint64 high = rem >> 64; | ||
1250 | |||
1251 | if (high >= denominator) { | ||
1252 | high /= denominator; | ||
1253 | res = (uint128) high << 64; | ||
1254 | rem -= (uint128) (high * denominator) << 64; | ||
1255 | } | ||
1256 | while ((uint128)b > 0 && b < rem) { | ||
1257 | b = b+b; | ||
1258 | d = d+d; | ||
1259 | } | ||
1260 | do { | ||
1261 | if (rem >= b) { | ||
1262 | rem -= b; | ||
1263 | res += d; | ||
1264 | } | ||
1265 | b >>= 1; | ||
1266 | d >>= 1; | ||
1267 | } while (d); | ||
1268 | *numerator = res; | ||
1269 | return rem; | ||
1270 | } | ||
1271 | #endif /* USE_MATRIX_DIV128 */ | ||
1272 | |||
1273 | /******************************************************************************/ | ||
1274 | /* | ||
1275 | a/b => cb + d == a | ||
1276 | */ | ||
1277 | int32 pstm_div(psPool_t *pool, pstm_int *a, pstm_int *b, pstm_int *c, | ||
1278 | pstm_int *d) | ||
1279 | { | ||
1280 | pstm_int q, x, y, t1, t2; | ||
1281 | int32 res; | ||
1282 | int16 n, t, i, norm, neg; | ||
1283 | |||
1284 | /* is divisor zero ? */ | ||
1285 | if (pstm_iszero (b) == 1) { | ||
1286 | return PS_LIMIT_FAIL; | ||
1287 | } | ||
1288 | |||
1289 | /* if a < b then q=0, r = a */ | ||
1290 | if (pstm_cmp_mag (a, b) == PSTM_LT) { | ||
1291 | if (d != NULL) { | ||
1292 | if (pstm_copy(a, d) != PSTM_OKAY) { | ||
1293 | return PS_MEM_FAIL; | ||
1294 | } | ||
1295 | } | ||
1296 | if (c != NULL) { | ||
1297 | pstm_zero (c); | ||
1298 | } | ||
1299 | return PSTM_OKAY; | ||
1300 | } | ||
1301 | /* | ||
1302 | Smart-size inits | ||
1303 | */ | ||
1304 | if ((res = pstm_init_size(pool, &t1, a->alloc)) != PSTM_OKAY) { | ||
1305 | return res; | ||
1306 | } | ||
1307 | if ((res = pstm_init_size(pool, &t2, 3)) != PSTM_OKAY) { | ||
1308 | goto LBL_T1; | ||
1309 | } | ||
1310 | if ((res = pstm_init_copy(pool, &x, a, 0)) != PSTM_OKAY) { | ||
1311 | goto LBL_T2; | ||
1312 | } | ||
1313 | /* | ||
1314 | Used to be an init_copy on b but pstm_grow was always hit with triple size | ||
1315 | */ | ||
1316 | if ((res = pstm_init_size(pool, &y, b->used * 3)) != PSTM_OKAY) { | ||
1317 | goto LBL_X; | ||
1318 | } | ||
1319 | if ((res = pstm_copy(b, &y)) != PSTM_OKAY) { | ||
1320 | goto LBL_Y; | ||
1321 | } | ||
1322 | |||
1323 | /* fix the sign */ | ||
1324 | neg = (a->sign == b->sign) ? PSTM_ZPOS : PSTM_NEG; | ||
1325 | x.sign = y.sign = PSTM_ZPOS; | ||
1326 | |||
1327 | /* normalize both x and y, ensure that y >= b/2, [b == 2**DIGIT_BIT] */ | ||
1328 | norm = pstm_count_bits(&y) % DIGIT_BIT; | ||
1329 | if (norm < (int32)(DIGIT_BIT-1)) { | ||
1330 | norm = (DIGIT_BIT-1) - norm; | ||
1331 | if ((res = pstm_mul_2d(&x, norm, &x)) != PSTM_OKAY) { | ||
1332 | goto LBL_Y; | ||
1333 | } | ||
1334 | if ((res = pstm_mul_2d(&y, norm, &y)) != PSTM_OKAY) { | ||
1335 | goto LBL_Y; | ||
1336 | } | ||
1337 | } else { | ||
1338 | norm = 0; | ||
1339 | } | ||
1340 | |||
1341 | /* note hac does 0 based, so if used==5 then its 0,1,2,3,4, e.g. use 4 */ | ||
1342 | n = x.used - 1; | ||
1343 | t = y.used - 1; | ||
1344 | |||
1345 | if ((res = pstm_init_size(pool, &q, n - t + 1)) != PSTM_OKAY) { | ||
1346 | goto LBL_Y; | ||
1347 | } | ||
1348 | q.used = n - t + 1; | ||
1349 | |||
1350 | /* while (x >= y*b**n-t) do { q[n-t] += 1; x -= y*b**{n-t} } */ | ||
1351 | if ((res = pstm_lshd(&y, n - t)) != PSTM_OKAY) { /* y = y*b**{n-t} */ | ||
1352 | goto LBL_Q; | ||
1353 | } | ||
1354 | |||
1355 | while (pstm_cmp (&x, &y) != PSTM_LT) { | ||
1356 | ++(q.dp[n - t]); | ||
1357 | if ((res = pstm_sub(&x, &y, &x)) != PSTM_OKAY) { | ||
1358 | goto LBL_Q; | ||
1359 | } | ||
1360 | } | ||
1361 | |||
1362 | /* reset y by shifting it back down */ | ||
1363 | pstm_rshd (&y, n - t); | ||
1364 | |||
1365 | /* step 3. for i from n down to (t + 1) */ | ||
1366 | for (i = n; i >= (t + 1); i--) { | ||
1367 | if (i > x.used) { | ||
1368 | continue; | ||
1369 | } | ||
1370 | |||
1371 | /* step 3.1 if xi == yt then set q{i-t-1} to b-1, | ||
1372 | * otherwise set q{i-t-1} to (xi*b + x{i-1})/yt */ | ||
1373 | if (x.dp[i] == y.dp[t]) { | ||
1374 | q.dp[i - t - 1] = (pstm_digit)((((pstm_word)1) << DIGIT_BIT) - 1); | ||
1375 | } else { | ||
1376 | pstm_word tmp; | ||
1377 | tmp = ((pstm_word) x.dp[i]) << ((pstm_word) DIGIT_BIT); | ||
1378 | tmp |= ((pstm_word) x.dp[i - 1]); | ||
1379 | #if defined(USE_MATRIX_DIV64) && defined(PSTM_32BIT) | ||
1380 | psDiv64(&tmp, y.dp[t]); | ||
1381 | #elif defined(USE_MATRIX_DIV128) && defined(PSTM_64BIT) | ||
1382 | psDiv128(&tmp, y.dp[t]); | ||
1383 | #else | ||
1384 | tmp /= ((pstm_word) y.dp[t]); | ||
1385 | #endif /* USE_MATRIX_DIV64 */ | ||
1386 | q.dp[i - t - 1] = (pstm_digit) (tmp); | ||
1387 | } | ||
1388 | |||
1389 | /* while (q{i-t-1} * (yt * b + y{t-1})) > | ||
1390 | xi * b**2 + xi-1 * b + xi-2 | ||
1391 | |||
1392 | do q{i-t-1} -= 1; | ||
1393 | */ | ||
1394 | q.dp[i - t - 1] = (q.dp[i - t - 1] + 1); | ||
1395 | do { | ||
1396 | q.dp[i - t - 1] = (q.dp[i - t - 1] - 1); | ||
1397 | |||
1398 | /* find left hand */ | ||
1399 | pstm_zero (&t1); | ||
1400 | t1.dp[0] = (t - 1 < 0) ? 0 : y.dp[t - 1]; | ||
1401 | t1.dp[1] = y.dp[t]; | ||
1402 | t1.used = 2; | ||
1403 | if ((res = pstm_mul_d (&t1, q.dp[i - t - 1], &t1)) != PSTM_OKAY) { | ||
1404 | goto LBL_Q; | ||
1405 | } | ||
1406 | |||
1407 | /* find right hand */ | ||
1408 | t2.dp[0] = (i - 2 < 0) ? 0 : x.dp[i - 2]; | ||
1409 | t2.dp[1] = (i - 1 < 0) ? 0 : x.dp[i - 1]; | ||
1410 | t2.dp[2] = x.dp[i]; | ||
1411 | t2.used = 3; | ||
1412 | } while (pstm_cmp_mag(&t1, &t2) == PSTM_GT); | ||
1413 | |||
1414 | /* step 3.3 x = x - q{i-t-1} * y * b**{i-t-1} */ | ||
1415 | if ((res = pstm_mul_d(&y, q.dp[i - t - 1], &t1)) != PSTM_OKAY) { | ||
1416 | goto LBL_Q; | ||
1417 | } | ||
1418 | |||
1419 | if ((res = pstm_lshd(&t1, i - t - 1)) != PSTM_OKAY) { | ||
1420 | goto LBL_Q; | ||
1421 | } | ||
1422 | |||
1423 | if ((res = pstm_sub(&x, &t1, &x)) != PSTM_OKAY) { | ||
1424 | goto LBL_Q; | ||
1425 | } | ||
1426 | |||
1427 | /* if x < 0 then { x = x + y*b**{i-t-1}; q{i-t-1} -= 1; } */ | ||
1428 | if (x.sign == PSTM_NEG) { | ||
1429 | if ((res = pstm_copy(&y, &t1)) != PSTM_OKAY) { | ||
1430 | goto LBL_Q; | ||
1431 | } | ||
1432 | if ((res = pstm_lshd (&t1, i - t - 1)) != PSTM_OKAY) { | ||
1433 | goto LBL_Q; | ||
1434 | } | ||
1435 | if ((res = pstm_add (&x, &t1, &x)) != PSTM_OKAY) { | ||
1436 | goto LBL_Q; | ||
1437 | } | ||
1438 | q.dp[i - t - 1] = q.dp[i - t - 1] - 1; | ||
1439 | } | ||
1440 | } | ||
1441 | /* | ||
1442 | now q is the quotient and x is the remainder (which we have to normalize) | ||
1443 | */ | ||
1444 | /* get sign before writing to c */ | ||
1445 | x.sign = x.used == 0 ? PSTM_ZPOS : a->sign; | ||
1446 | |||
1447 | if (c != NULL) { | ||
1448 | pstm_clamp (&q); | ||
1449 | if (pstm_copy (&q, c) != PSTM_OKAY) { | ||
1450 | res = PS_MEM_FAIL; | ||
1451 | goto LBL_Q; | ||
1452 | } | ||
1453 | c->sign = neg; | ||
1454 | } | ||
1455 | |||
1456 | if (d != NULL) { | ||
1457 | if ((res = pstm_div_2d (pool, &x, norm, &x, NULL)) != PSTM_OKAY) { | ||
1458 | goto LBL_Q; | ||
1459 | } | ||
1460 | /* | ||
1461 | the following is a kludge, essentially we were seeing the right | ||
1462 | remainder but with excess digits that should have been zero | ||
1463 | */ | ||
1464 | for (i = b->used; i < x.used; i++) { | ||
1465 | x.dp[i] = 0; | ||
1466 | } | ||
1467 | pstm_clamp(&x); | ||
1468 | if (pstm_copy (&x, d) != PSTM_OKAY) { | ||
1469 | res = PS_MEM_FAIL; | ||
1470 | goto LBL_Q; | ||
1471 | } | ||
1472 | } | ||
1473 | |||
1474 | res = PSTM_OKAY; | ||
1475 | |||
1476 | LBL_Q:pstm_clear (&q); | ||
1477 | LBL_Y:pstm_clear (&y); | ||
1478 | LBL_X:pstm_clear (&x); | ||
1479 | LBL_T2:pstm_clear (&t2); | ||
1480 | LBL_T1:pstm_clear (&t1); | ||
1481 | |||
1482 | return res; | ||
1483 | } | ||
1484 | |||
1485 | /******************************************************************************/ | ||
1486 | /* | ||
1487 | Swap the elements of two integers, for cases where you can't simply swap | ||
1488 | the pstm_int pointers around | ||
1489 | */ | ||
1490 | void pstm_exch(pstm_int * a, pstm_int * b) | ||
1491 | { | ||
1492 | pstm_int t; | ||
1493 | |||
1494 | t = *a; | ||
1495 | *a = *b; | ||
1496 | *b = t; | ||
1497 | } | ||
1498 | |||
1499 | /******************************************************************************/ | ||
1500 | /* | ||
1501 | c = a mod b, 0 <= c < b | ||
1502 | */ | ||
1503 | int32 pstm_mod(psPool_t *pool, pstm_int *a, pstm_int *b, pstm_int *c) | ||
1504 | { | ||
1505 | pstm_int t; | ||
1506 | int32 err; | ||
1507 | /* | ||
1508 | Smart-size | ||
1509 | */ | ||
1510 | if ((err = pstm_init_size(pool, &t, b->alloc)) != PSTM_OKAY) { | ||
1511 | return err; | ||
1512 | } | ||
1513 | if ((err = pstm_div(pool, a, b, NULL, &t)) != PSTM_OKAY) { | ||
1514 | pstm_clear (&t); | ||
1515 | return err; | ||
1516 | } | ||
1517 | if (t.sign != b->sign) { | ||
1518 | err = pstm_add(&t, b, c); | ||
1519 | } else { | ||
1520 | pstm_exch (&t, c); | ||
1521 | } | ||
1522 | pstm_clear (&t); | ||
1523 | return err; | ||
1524 | } | ||
1525 | |||
1526 | /******************************************************************************/ | ||
1527 | /* | ||
1528 | d = a * b (mod c) | ||
1529 | */ | ||
1530 | int32 pstm_mulmod(psPool_t *pool, pstm_int *a, pstm_int *b, pstm_int *c, | ||
1531 | pstm_int *d) | ||
1532 | { | ||
1533 | int32 res; | ||
1534 | int16 size; | ||
1535 | pstm_int tmp; | ||
1536 | |||
1537 | /* | ||
1538 | Smart-size pstm_inits. d is an output that is influenced by this local 't' | ||
1539 | so don't shrink 'd' if it wants to becuase this will lead to an pstm_grow | ||
1540 | in RSA operations | ||
1541 | */ | ||
1542 | size = a->used + b->used + 1; | ||
1543 | if ((a == d) && (size < a->alloc)) { | ||
1544 | size = a->alloc; | ||
1545 | } | ||
1546 | if ((res = pstm_init_size(pool, &tmp, size)) != PSTM_OKAY) { | ||
1547 | return res; | ||
1548 | } | ||
1549 | if ((res = pstm_mul_comba(pool, a, b, &tmp, NULL, 0)) != PSTM_OKAY) { | ||
1550 | pstm_clear(&tmp); | ||
1551 | return res; | ||
1552 | } | ||
1553 | res = pstm_mod(pool, &tmp, c, d); | ||
1554 | pstm_clear(&tmp); | ||
1555 | return res; | ||
1556 | } | ||
1557 | |||
1558 | /******************************************************************************/ | ||
1559 | /* | ||
1560 | * y = g**x (mod b) | ||
1561 | * Some restrictions... x must be positive and < b | ||
1562 | */ | ||
1563 | int32 pstm_exptmod(psPool_t *pool, pstm_int *G, pstm_int *X, pstm_int *P, | ||
1564 | pstm_int *Y) | ||
1565 | { | ||
1566 | pstm_int M[32], res; /* Keep this winsize based: (1 << max_winsize) */ | ||
1567 | pstm_digit buf, mp; | ||
1568 | pstm_digit *paD; | ||
1569 | int32 err, bitbuf; | ||
1570 | int16 bitcpy, bitcnt, mode, digidx, x, y, winsize; | ||
1571 | uint32 paDlen; | ||
1572 | |||
1573 | /* set window size from what user set as optimization */ | ||
1574 | x = pstm_count_bits(X); | ||
1575 | if (x < 50) { | ||
1576 | winsize = 2; | ||
1577 | } else { | ||
1578 | winsize = PS_EXPTMOD_WINSIZE; | ||
1579 | } | ||
1580 | |||
1581 | /* now setup montgomery */ | ||
1582 | if ((err = pstm_montgomery_setup (P, &mp)) != PSTM_OKAY) { | ||
1583 | return err; | ||
1584 | } | ||
1585 | |||
1586 | /* setup result */ | ||
1587 | if ((err = pstm_init_size(pool, &res, (P->used * 2) + 1)) != PSTM_OKAY) { | ||
1588 | return err; | ||
1589 | } | ||
1590 | /* | ||
1591 | create M table | ||
1592 | The M table contains powers of the input base, e.g. M[x] = G^x mod P | ||
1593 | The first half of the table is not computed though except for M[0] and M[1] | ||
1594 | */ | ||
1595 | /* now we need R mod m */ | ||
1596 | if ((err = pstm_montgomery_calc_normalization (&res, P)) != PSTM_OKAY) { | ||
1597 | goto LBL_RES; | ||
1598 | } | ||
1599 | /* | ||
1600 | init M array | ||
1601 | init first cell | ||
1602 | */ | ||
1603 | if ((err = pstm_init_size(pool, &M[1], res.used)) != PSTM_OKAY) { | ||
1604 | goto LBL_RES; | ||
1605 | } | ||
1606 | |||
1607 | /* now set M[1] to G * R mod m */ | ||
1608 | if (pstm_cmp_mag(P, G) != PSTM_GT) { | ||
1609 | /* G > P so we reduce it first */ | ||
1610 | if ((err = pstm_mod(pool, G, P, &M[1])) != PSTM_OKAY) { | ||
1611 | goto LBL_M; | ||
1612 | } | ||
1613 | } else { | ||
1614 | if ((err = pstm_copy(G, &M[1])) != PSTM_OKAY) { | ||
1615 | goto LBL_M; | ||
1616 | } | ||
1617 | } | ||
1618 | if ((err = pstm_mulmod (pool, &M[1], &res, P, &M[1])) != PSTM_OKAY) { | ||
1619 | goto LBL_M; | ||
1620 | } | ||
1621 | /* | ||
1622 | Pre-allocated digit. Used for mul, sqr, AND reduce | ||
1623 | */ | ||
1624 | paDlen = ((M[1].used + 3) * 2) * sizeof(pstm_digit); | ||
1625 | paD = xzalloc(paDlen);//bbox | ||
1626 | /* | ||
1627 | compute the value at M[1<<(winsize-1)] by squaring M[1] (winsize-1) times | ||
1628 | */ | ||
1629 | if (pstm_init_copy(pool, &M[1 << (winsize - 1)], &M[1], 1) != PSTM_OKAY) { | ||
1630 | err = PS_MEM_FAIL; | ||
1631 | goto LBL_PAD; | ||
1632 | } | ||
1633 | for (x = 0; x < (winsize - 1); x++) { | ||
1634 | if ((err = pstm_sqr_comba (pool, &M[1 << (winsize - 1)], | ||
1635 | &M[1 << (winsize - 1)], paD, paDlen)) != PSTM_OKAY) { | ||
1636 | goto LBL_PAD; | ||
1637 | } | ||
1638 | if ((err = pstm_montgomery_reduce(pool, &M[1 << (winsize - 1)], P, mp, | ||
1639 | paD, paDlen)) != PSTM_OKAY) { | ||
1640 | goto LBL_PAD; | ||
1641 | } | ||
1642 | } | ||
1643 | /* | ||
1644 | now init the second half of the array | ||
1645 | */ | ||
1646 | for (x = (1<<(winsize-1)) + 1; x < (1 << winsize); x++) { | ||
1647 | if ((err = pstm_init_size(pool, &M[x], M[1<<(winsize-1)].alloc + 1)) | ||
1648 | != PSTM_OKAY) { | ||
1649 | for (y = 1<<(winsize-1); y < x; y++) { | ||
1650 | pstm_clear(&M[y]); | ||
1651 | } | ||
1652 | goto LBL_PAD; | ||
1653 | } | ||
1654 | } | ||
1655 | |||
1656 | /* create upper table */ | ||
1657 | for (x = (1 << (winsize - 1)) + 1; x < (1 << winsize); x++) { | ||
1658 | if ((err = pstm_mul_comba(pool, &M[x - 1], &M[1], &M[x], paD, paDlen)) | ||
1659 | != PSTM_OKAY) { | ||
1660 | goto LBL_MARRAY; | ||
1661 | } | ||
1662 | if ((err = pstm_montgomery_reduce(pool, &M[x], P, mp, paD, paDlen)) != | ||
1663 | PSTM_OKAY) { | ||
1664 | goto LBL_MARRAY; | ||
1665 | } | ||
1666 | } | ||
1667 | |||
1668 | /* set initial mode and bit cnt */ | ||
1669 | mode = 0; | ||
1670 | bitcnt = 1; | ||
1671 | buf = 0; | ||
1672 | digidx = X->used - 1; | ||
1673 | bitcpy = 0; | ||
1674 | bitbuf = 0; | ||
1675 | |||
1676 | for (;;) { | ||
1677 | /* grab next digit as required */ | ||
1678 | if (--bitcnt == 0) { | ||
1679 | /* if digidx == -1 we are out of digits so break */ | ||
1680 | if (digidx == -1) { | ||
1681 | break; | ||
1682 | } | ||
1683 | /* read next digit and reset bitcnt */ | ||
1684 | buf = X->dp[digidx--]; | ||
1685 | bitcnt = (int32)DIGIT_BIT; | ||
1686 | } | ||
1687 | |||
1688 | /* grab the next msb from the exponent */ | ||
1689 | y = (pstm_digit)(buf >> (DIGIT_BIT - 1)) & 1; | ||
1690 | buf <<= (pstm_digit)1; | ||
1691 | /* | ||
1692 | If the bit is zero and mode == 0 then we ignore it. | ||
1693 | These represent the leading zero bits before the first 1 bit | ||
1694 | in the exponent. Technically this opt is not required but it | ||
1695 | does lower the # of trivial squaring/reductions used | ||
1696 | */ | ||
1697 | if (mode == 0 && y == 0) { | ||
1698 | continue; | ||
1699 | } | ||
1700 | |||
1701 | /* if the bit is zero and mode == 1 then we square */ | ||
1702 | if (mode == 1 && y == 0) { | ||
1703 | if ((err = pstm_sqr_comba(pool, &res, &res, paD, paDlen)) != | ||
1704 | PSTM_OKAY) { | ||
1705 | goto LBL_MARRAY; | ||
1706 | } | ||
1707 | if ((err = pstm_montgomery_reduce(pool, &res, P, mp, paD, paDlen)) | ||
1708 | != PSTM_OKAY) { | ||
1709 | goto LBL_MARRAY; | ||
1710 | } | ||
1711 | continue; | ||
1712 | } | ||
1713 | |||
1714 | /* else we add it to the window */ | ||
1715 | bitbuf |= (y << (winsize - ++bitcpy)); | ||
1716 | mode = 2; | ||
1717 | |||
1718 | if (bitcpy == winsize) { | ||
1719 | /* ok window is filled so square as required and mul square first */ | ||
1720 | for (x = 0; x < winsize; x++) { | ||
1721 | if ((err = pstm_sqr_comba(pool, &res, &res, paD, paDlen)) != | ||
1722 | PSTM_OKAY) { | ||
1723 | goto LBL_MARRAY; | ||
1724 | } | ||
1725 | if ((err = pstm_montgomery_reduce(pool, &res, P, mp, paD, | ||
1726 | paDlen)) != PSTM_OKAY) { | ||
1727 | goto LBL_MARRAY; | ||
1728 | } | ||
1729 | } | ||
1730 | |||
1731 | /* then multiply */ | ||
1732 | if ((err = pstm_mul_comba(pool, &res, &M[bitbuf], &res, paD, | ||
1733 | paDlen)) != PSTM_OKAY) { | ||
1734 | goto LBL_MARRAY; | ||
1735 | } | ||
1736 | if ((err = pstm_montgomery_reduce(pool, &res, P, mp, paD, paDlen)) | ||
1737 | != PSTM_OKAY) { | ||
1738 | goto LBL_MARRAY; | ||
1739 | } | ||
1740 | |||
1741 | /* empty window and reset */ | ||
1742 | bitcpy = 0; | ||
1743 | bitbuf = 0; | ||
1744 | mode = 1; | ||
1745 | } | ||
1746 | } | ||
1747 | |||
1748 | /* if bits remain then square/multiply */ | ||
1749 | if (mode == 2 && bitcpy > 0) { | ||
1750 | /* square then multiply if the bit is set */ | ||
1751 | for (x = 0; x < bitcpy; x++) { | ||
1752 | if ((err = pstm_sqr_comba(pool, &res, &res, paD, paDlen)) != | ||
1753 | PSTM_OKAY) { | ||
1754 | goto LBL_MARRAY; | ||
1755 | } | ||
1756 | if ((err = pstm_montgomery_reduce(pool, &res, P, mp, paD, paDlen)) | ||
1757 | != PSTM_OKAY) { | ||
1758 | goto LBL_MARRAY; | ||
1759 | } | ||
1760 | |||
1761 | /* get next bit of the window */ | ||
1762 | bitbuf <<= 1; | ||
1763 | if ((bitbuf & (1 << winsize)) != 0) { | ||
1764 | /* then multiply */ | ||
1765 | if ((err = pstm_mul_comba(pool, &res, &M[1], &res, paD, paDlen)) | ||
1766 | != PSTM_OKAY) { | ||
1767 | goto LBL_MARRAY; | ||
1768 | } | ||
1769 | if ((err = pstm_montgomery_reduce(pool, &res, P, mp, paD, | ||
1770 | paDlen)) != PSTM_OKAY) { | ||
1771 | goto LBL_MARRAY; | ||
1772 | } | ||
1773 | } | ||
1774 | } | ||
1775 | } | ||
1776 | /* | ||
1777 | Fix up result if Montgomery reduction is used recall that any value in a | ||
1778 | Montgomery system is actually multiplied by R mod n. So we have to reduce | ||
1779 | one more time to cancel out the factor of R. | ||
1780 | */ | ||
1781 | if ((err = pstm_montgomery_reduce(pool, &res, P, mp, paD, paDlen)) != | ||
1782 | PSTM_OKAY) { | ||
1783 | goto LBL_MARRAY; | ||
1784 | } | ||
1785 | /* swap res with Y */ | ||
1786 | if ((err = pstm_copy (&res, Y)) != PSTM_OKAY) { | ||
1787 | goto LBL_MARRAY; | ||
1788 | } | ||
1789 | err = PSTM_OKAY; | ||
1790 | LBL_MARRAY: | ||
1791 | for (x = 1<<(winsize-1); x < (1 << winsize); x++) { | ||
1792 | pstm_clear(&M[x]); | ||
1793 | } | ||
1794 | LBL_PAD:psFree(paD, pool); | ||
1795 | LBL_M: pstm_clear(&M[1]); | ||
1796 | LBL_RES:pstm_clear(&res); | ||
1797 | return err; | ||
1798 | } | ||
1799 | |||
1800 | /******************************************************************************/ | ||
1801 | /* | ||
1802 | |||
1803 | */ | ||
1804 | int32 pstm_add(pstm_int *a, pstm_int *b, pstm_int *c) | ||
1805 | { | ||
1806 | int32 res; | ||
1807 | int16 sa, sb; | ||
1808 | |||
1809 | /* get sign of both inputs */ | ||
1810 | sa = a->sign; | ||
1811 | sb = b->sign; | ||
1812 | |||
1813 | /* handle two cases, not four */ | ||
1814 | if (sa == sb) { | ||
1815 | /* both positive or both negative, add their mags, copy the sign */ | ||
1816 | c->sign = sa; | ||
1817 | if ((res = s_pstm_add (a, b, c)) != PSTM_OKAY) { | ||
1818 | return res; | ||
1819 | } | ||
1820 | } else { | ||
1821 | /* | ||
1822 | one positive, the other negative | ||
1823 | subtract the one with the greater magnitude from the one of the lesser | ||
1824 | magnitude. The result gets the sign of the one with the greater mag. | ||
1825 | */ | ||
1826 | if (pstm_cmp_mag (a, b) == PSTM_LT) { | ||
1827 | c->sign = sb; | ||
1828 | if ((res = s_pstm_sub (b, a, c)) != PSTM_OKAY) { | ||
1829 | return res; | ||
1830 | } | ||
1831 | } else { | ||
1832 | c->sign = sa; | ||
1833 | if ((res = s_pstm_sub (a, b, c)) != PSTM_OKAY) { | ||
1834 | return res; | ||
1835 | } | ||
1836 | } | ||
1837 | } | ||
1838 | return PS_SUCCESS; | ||
1839 | } | ||
1840 | |||
1841 | /******************************************************************************/ | ||
1842 | /* | ||
1843 | reverse an array, used for radix code | ||
1844 | */ | ||
1845 | static void pstm_reverse (unsigned char *s, int16 len) | ||
1846 | { | ||
1847 | int32 ix, iy; | ||
1848 | unsigned char t; | ||
1849 | |||
1850 | ix = 0; | ||
1851 | iy = len - 1; | ||
1852 | while (ix < iy) { | ||
1853 | t = s[ix]; | ||
1854 | s[ix] = s[iy]; | ||
1855 | s[iy] = t; | ||
1856 | ++ix; | ||
1857 | --iy; | ||
1858 | } | ||
1859 | } | ||
1860 | /******************************************************************************/ | ||
1861 | /* | ||
1862 | No reverse. Useful in some of the EIP-154 PKA stuff where special byte | ||
1863 | order seems to come into play more often | ||
1864 | */ | ||
1865 | int32 pstm_to_unsigned_bin_nr(psPool_t *pool, pstm_int *a, unsigned char *b) | ||
1866 | { | ||
1867 | int32 res; | ||
1868 | int16 x; | ||
1869 | pstm_int t = { 0 }; | ||
1870 | |||
1871 | if ((res = pstm_init_copy(pool, &t, a, 0)) != PSTM_OKAY) { | ||
1872 | return res; | ||
1873 | } | ||
1874 | |||
1875 | x = 0; | ||
1876 | while (pstm_iszero (&t) == 0) { | ||
1877 | b[x++] = (unsigned char) (t.dp[0] & 255); | ||
1878 | if ((res = pstm_div_2d (pool, &t, 8, &t, NULL)) != PSTM_OKAY) { | ||
1879 | pstm_clear(&t); | ||
1880 | return res; | ||
1881 | } | ||
1882 | } | ||
1883 | pstm_clear(&t); | ||
1884 | return PS_SUCCESS; | ||
1885 | } | ||
1886 | /******************************************************************************/ | ||
1887 | /* | ||
1888 | |||
1889 | */ | ||
1890 | int32 pstm_to_unsigned_bin(psPool_t *pool, pstm_int *a, unsigned char *b) | ||
1891 | { | ||
1892 | int32 res; | ||
1893 | int16 x; | ||
1894 | pstm_int t = { 0 }; | ||
1895 | |||
1896 | if ((res = pstm_init_copy(pool, &t, a, 0)) != PSTM_OKAY) { | ||
1897 | return res; | ||
1898 | } | ||
1899 | |||
1900 | x = 0; | ||
1901 | while (pstm_iszero (&t) == 0) { | ||
1902 | b[x++] = (unsigned char) (t.dp[0] & 255); | ||
1903 | if ((res = pstm_div_2d (pool, &t, 8, &t, NULL)) != PSTM_OKAY) { | ||
1904 | pstm_clear(&t); | ||
1905 | return res; | ||
1906 | } | ||
1907 | } | ||
1908 | pstm_reverse (b, x); | ||
1909 | pstm_clear(&t); | ||
1910 | return PS_SUCCESS; | ||
1911 | } | ||
1912 | |||
1913 | /******************************************************************************/ | ||
1914 | /* | ||
1915 | compare against a single digit | ||
1916 | */ | ||
1917 | int32 pstm_cmp_d(pstm_int *a, pstm_digit b) | ||
1918 | { | ||
1919 | /* compare based on sign */ | ||
1920 | if ((b && a->used == 0) || a->sign == PSTM_NEG) { | ||
1921 | return PSTM_LT; | ||
1922 | } | ||
1923 | |||
1924 | /* compare based on magnitude */ | ||
1925 | if (a->used > 1) { | ||
1926 | return PSTM_GT; | ||
1927 | } | ||
1928 | |||
1929 | /* compare the only digit of a to b */ | ||
1930 | if (a->dp[0] > b) { | ||
1931 | return PSTM_GT; | ||
1932 | } else if (a->dp[0] < b) { | ||
1933 | return PSTM_LT; | ||
1934 | } else { | ||
1935 | return PSTM_EQ; | ||
1936 | } | ||
1937 | } | ||
1938 | |||
1939 | /* | ||
1940 | Need invmod for ECC and also private key loading for hardware crypto | ||
1941 | in cases where dQ > dP. The values must be switched and a new qP must be | ||
1942 | calculated using this function | ||
1943 | */ | ||
1944 | //bbox: pool unused | ||
1945 | #define pstm_invmod_slow(pool, a, b, c) \ | ||
1946 | pstm_invmod_slow( a, b, c) | ||
1947 | static int32 pstm_invmod_slow(psPool_t *pool, pstm_int * a, pstm_int * b, | ||
1948 | pstm_int * c) | ||
1949 | { | ||
1950 | pstm_int x, y, u, v, A, B, C, D; | ||
1951 | int32 res; | ||
1952 | |||
1953 | /* b cannot be negative */ | ||
1954 | if (b->sign == PSTM_NEG || pstm_iszero(b) == 1) { | ||
1955 | return PS_LIMIT_FAIL; | ||
1956 | } | ||
1957 | |||
1958 | /* init temps */ | ||
1959 | if (pstm_init_size(pool, &x, b->used) != PSTM_OKAY) { | ||
1960 | return PS_MEM_FAIL; | ||
1961 | } | ||
1962 | |||
1963 | /* x = a, y = b */ | ||
1964 | if ((res = pstm_mod(pool, a, b, &x)) != PSTM_OKAY) { | ||
1965 | goto LBL_X; | ||
1966 | } | ||
1967 | |||
1968 | if (pstm_init_copy(pool, &y, b, 0) != PSTM_OKAY) { | ||
1969 | goto LBL_X; | ||
1970 | } | ||
1971 | |||
1972 | /* 2. [modified] if x,y are both even then return an error! */ | ||
1973 | if (pstm_iseven (&x) == 1 && pstm_iseven (&y) == 1) { | ||
1974 | res = PS_FAILURE; | ||
1975 | goto LBL_Y; | ||
1976 | } | ||
1977 | |||
1978 | /* 3. u=x, v=y, A=1, B=0, C=0,D=1 */ | ||
1979 | if ((res = pstm_init_copy(pool, &u, &x, 0)) != PSTM_OKAY) { | ||
1980 | goto LBL_Y; | ||
1981 | } | ||
1982 | if ((res = pstm_init_copy(pool, &v, &y, 0)) != PSTM_OKAY) { | ||
1983 | goto LBL_U; | ||
1984 | } | ||
1985 | |||
1986 | if ((res = pstm_init_size(pool, &A, sizeof(pstm_digit))) != PSTM_OKAY) { | ||
1987 | goto LBL_V; | ||
1988 | } | ||
1989 | |||
1990 | if ((res = pstm_init_size(pool, &D, sizeof(pstm_digit))) != PSTM_OKAY) { | ||
1991 | goto LBL_A; | ||
1992 | } | ||
1993 | pstm_set (&A, 1); | ||
1994 | pstm_set (&D, 1); | ||
1995 | |||
1996 | if ((res = pstm_init(pool, &B)) != PSTM_OKAY) { | ||
1997 | goto LBL_D; | ||
1998 | } | ||
1999 | if ((res = pstm_init(pool, &C)) != PSTM_OKAY) { | ||
2000 | goto LBL_B; | ||
2001 | } | ||
2002 | |||
2003 | top: | ||
2004 | /* 4. while u is even do */ | ||
2005 | while (pstm_iseven (&u) == 1) { | ||
2006 | /* 4.1 u = u/2 */ | ||
2007 | if ((res = pstm_div_2 (&u, &u)) != PSTM_OKAY) { | ||
2008 | goto LBL_C; | ||
2009 | } | ||
2010 | |||
2011 | /* 4.2 if A or B is odd then */ | ||
2012 | if (pstm_isodd (&A) == 1 || pstm_isodd (&B) == 1) { | ||
2013 | /* A = (A+y)/2, B = (B-x)/2 */ | ||
2014 | if ((res = pstm_add (&A, &y, &A)) != PSTM_OKAY) { | ||
2015 | goto LBL_C; | ||
2016 | } | ||
2017 | if ((res = pstm_sub (&B, &x, &B)) != PSTM_OKAY) { | ||
2018 | goto LBL_C; | ||
2019 | } | ||
2020 | } | ||
2021 | /* A = A/2, B = B/2 */ | ||
2022 | if ((res = pstm_div_2 (&A, &A)) != PSTM_OKAY) { | ||
2023 | goto LBL_C; | ||
2024 | } | ||
2025 | if ((res = pstm_div_2 (&B, &B)) != PSTM_OKAY) { | ||
2026 | goto LBL_C; | ||
2027 | } | ||
2028 | } | ||
2029 | |||
2030 | /* 5. while v is even do */ | ||
2031 | while (pstm_iseven (&v) == 1) { | ||
2032 | /* 5.1 v = v/2 */ | ||
2033 | if ((res = pstm_div_2 (&v, &v)) != PSTM_OKAY) { | ||
2034 | goto LBL_C; | ||
2035 | } | ||
2036 | |||
2037 | /* 5.2 if C or D is odd then */ | ||
2038 | if (pstm_isodd (&C) == 1 || pstm_isodd (&D) == 1) { | ||
2039 | /* C = (C+y)/2, D = (D-x)/2 */ | ||
2040 | if ((res = pstm_add (&C, &y, &C)) != PSTM_OKAY) { | ||
2041 | goto LBL_C; | ||
2042 | } | ||
2043 | if ((res = pstm_sub (&D, &x, &D)) != PSTM_OKAY) { | ||
2044 | goto LBL_C; | ||
2045 | } | ||
2046 | } | ||
2047 | /* C = C/2, D = D/2 */ | ||
2048 | if ((res = pstm_div_2 (&C, &C)) != PSTM_OKAY) { | ||
2049 | goto LBL_C; | ||
2050 | } | ||
2051 | if ((res = pstm_div_2 (&D, &D)) != PSTM_OKAY) { | ||
2052 | goto LBL_C; | ||
2053 | } | ||
2054 | } | ||
2055 | |||
2056 | /* 6. if u >= v then */ | ||
2057 | if (pstm_cmp (&u, &v) != PSTM_LT) { | ||
2058 | /* u = u - v, A = A - C, B = B - D */ | ||
2059 | if ((res = pstm_sub (&u, &v, &u)) != PSTM_OKAY) { | ||
2060 | goto LBL_C; | ||
2061 | } | ||
2062 | if ((res = pstm_sub (&A, &C, &A)) != PSTM_OKAY) { | ||
2063 | goto LBL_C; | ||
2064 | } | ||
2065 | if ((res = pstm_sub (&B, &D, &B)) != PSTM_OKAY) { | ||
2066 | goto LBL_C; | ||
2067 | } | ||
2068 | } else { | ||
2069 | /* v - v - u, C = C - A, D = D - B */ | ||
2070 | if ((res = pstm_sub (&v, &u, &v)) != PSTM_OKAY) { | ||
2071 | goto LBL_C; | ||
2072 | } | ||
2073 | if ((res = pstm_sub (&C, &A, &C)) != PSTM_OKAY) { | ||
2074 | goto LBL_C; | ||
2075 | } | ||
2076 | if ((res = pstm_sub (&D, &B, &D)) != PSTM_OKAY) { | ||
2077 | goto LBL_C; | ||
2078 | } | ||
2079 | } | ||
2080 | |||
2081 | /* if not zero goto step 4 */ | ||
2082 | if (pstm_iszero (&u) == 0) | ||
2083 | goto top; | ||
2084 | |||
2085 | /* now a = C, b = D, gcd == g*v */ | ||
2086 | |||
2087 | /* if v != 1 then there is no inverse */ | ||
2088 | if (pstm_cmp_d (&v, 1) != PSTM_EQ) { | ||
2089 | res = PS_FAILURE; | ||
2090 | goto LBL_C; | ||
2091 | } | ||
2092 | |||
2093 | /* if its too low */ | ||
2094 | while (pstm_cmp_d(&C, 0) == PSTM_LT) { | ||
2095 | if ((res = pstm_add(&C, b, &C)) != PSTM_OKAY) { | ||
2096 | goto LBL_C; | ||
2097 | } | ||
2098 | } | ||
2099 | |||
2100 | /* too big */ | ||
2101 | while (pstm_cmp_mag(&C, b) != PSTM_LT) { | ||
2102 | if ((res = pstm_sub(&C, b, &C)) != PSTM_OKAY) { | ||
2103 | goto LBL_C; | ||
2104 | } | ||
2105 | } | ||
2106 | |||
2107 | /* C is now the inverse */ | ||
2108 | if ((res = pstm_copy(&C, c)) != PSTM_OKAY) { | ||
2109 | goto LBL_C; | ||
2110 | } | ||
2111 | res = PSTM_OKAY; | ||
2112 | |||
2113 | LBL_C: pstm_clear(&C); | ||
2114 | LBL_D: pstm_clear(&D); | ||
2115 | LBL_B: pstm_clear(&B); | ||
2116 | LBL_A: pstm_clear(&A); | ||
2117 | LBL_V: pstm_clear(&v); | ||
2118 | LBL_U: pstm_clear(&u); | ||
2119 | LBL_Y: pstm_clear(&y); | ||
2120 | LBL_X: pstm_clear(&x); | ||
2121 | |||
2122 | return res; | ||
2123 | } | ||
2124 | |||
2125 | /* c = 1/a (mod b) for odd b only */ | ||
2126 | int32 pstm_invmod(psPool_t *pool, pstm_int *a, pstm_int *b, pstm_int *c) | ||
2127 | { | ||
2128 | pstm_int x, y, u, v, B, D; | ||
2129 | int32 res; | ||
2130 | uint16 neg, sanity; | ||
2131 | |||
2132 | /* 2. [modified] b must be odd */ | ||
2133 | if (pstm_iseven (b) == 1) { | ||
2134 | return pstm_invmod_slow(pool, a,b,c); | ||
2135 | } | ||
2136 | |||
2137 | /* x == modulus, y == value to invert */ | ||
2138 | if ((res = pstm_init_copy(pool, &x, b, 0)) != PSTM_OKAY) { | ||
2139 | return res; | ||
2140 | } | ||
2141 | |||
2142 | if ((res = pstm_init_size(pool, &y, a->alloc)) != PSTM_OKAY) { | ||
2143 | goto LBL_X; | ||
2144 | } | ||
2145 | |||
2146 | /* we need y = |a| */ | ||
2147 | pstm_abs(a, &y); | ||
2148 | |||
2149 | /* 3. u=x, v=y, A=1, B=0, C=0,D=1 */ | ||
2150 | if ((res = pstm_init_copy(pool, &u, &x, 0)) != PSTM_OKAY) { | ||
2151 | goto LBL_Y; | ||
2152 | } | ||
2153 | if ((res = pstm_init_copy(pool, &v, &y, 0)) != PSTM_OKAY) { | ||
2154 | goto LBL_U; | ||
2155 | } | ||
2156 | if ((res = pstm_init(pool, &B)) != PSTM_OKAY) { | ||
2157 | goto LBL_V; | ||
2158 | } | ||
2159 | if ((res = pstm_init(pool, &D)) != PSTM_OKAY) { | ||
2160 | goto LBL_B; | ||
2161 | } | ||
2162 | |||
2163 | pstm_set (&D, 1); | ||
2164 | |||
2165 | sanity = 0; | ||
2166 | top: | ||
2167 | /* 4. while u is even do */ | ||
2168 | while (pstm_iseven (&u) == 1) { | ||
2169 | /* 4.1 u = u/2 */ | ||
2170 | if ((res = pstm_div_2 (&u, &u)) != PSTM_OKAY) { | ||
2171 | goto LBL_D; | ||
2172 | } | ||
2173 | |||
2174 | /* 4.2 if B is odd then */ | ||
2175 | if (pstm_isodd (&B) == 1) { | ||
2176 | if ((res = pstm_sub (&B, &x, &B)) != PSTM_OKAY) { | ||
2177 | goto LBL_D; | ||
2178 | } | ||
2179 | } | ||
2180 | /* B = B/2 */ | ||
2181 | if ((res = pstm_div_2 (&B, &B)) != PSTM_OKAY) { | ||
2182 | goto LBL_D; | ||
2183 | } | ||
2184 | } | ||
2185 | |||
2186 | /* 5. while v is even do */ | ||
2187 | while (pstm_iseven (&v) == 1) { | ||
2188 | /* 5.1 v = v/2 */ | ||
2189 | if ((res = pstm_div_2 (&v, &v)) != PSTM_OKAY) { | ||
2190 | goto LBL_D; | ||
2191 | } | ||
2192 | /* 5.2 if D is odd then */ | ||
2193 | if (pstm_isodd (&D) == 1) { | ||
2194 | /* D = (D-x)/2 */ | ||
2195 | if ((res = pstm_sub (&D, &x, &D)) != PSTM_OKAY) { | ||
2196 | goto LBL_D; | ||
2197 | } | ||
2198 | } | ||
2199 | /* D = D/2 */ | ||
2200 | if ((res = pstm_div_2 (&D, &D)) != PSTM_OKAY) { | ||
2201 | goto LBL_D; | ||
2202 | } | ||
2203 | } | ||
2204 | |||
2205 | /* 6. if u >= v then */ | ||
2206 | if (pstm_cmp (&u, &v) != PSTM_LT) { | ||
2207 | /* u = u - v, B = B - D */ | ||
2208 | if ((res = pstm_sub (&u, &v, &u)) != PSTM_OKAY) { | ||
2209 | goto LBL_D; | ||
2210 | } | ||
2211 | if ((res = pstm_sub (&B, &D, &B)) != PSTM_OKAY) { | ||
2212 | goto LBL_D; | ||
2213 | } | ||
2214 | } else { | ||
2215 | /* v - v - u, D = D - B */ | ||
2216 | if ((res = pstm_sub (&v, &u, &v)) != PSTM_OKAY) { | ||
2217 | goto LBL_D; | ||
2218 | } | ||
2219 | if ((res = pstm_sub (&D, &B, &D)) != PSTM_OKAY) { | ||
2220 | goto LBL_D; | ||
2221 | } | ||
2222 | } | ||
2223 | |||
2224 | /* if not zero goto step 4 */ | ||
2225 | if (sanity++ > 1000) { | ||
2226 | res = PS_LIMIT_FAIL; | ||
2227 | goto LBL_D; | ||
2228 | } | ||
2229 | if (pstm_iszero (&u) == 0) { | ||
2230 | goto top; | ||
2231 | } | ||
2232 | |||
2233 | /* now a = C, b = D, gcd == g*v */ | ||
2234 | |||
2235 | /* if v != 1 then there is no inverse */ | ||
2236 | if (pstm_cmp_d (&v, 1) != PSTM_EQ) { | ||
2237 | res = PS_FAILURE; | ||
2238 | goto LBL_D; | ||
2239 | } | ||
2240 | |||
2241 | /* b is now the inverse */ | ||
2242 | neg = a->sign; | ||
2243 | while (D.sign == PSTM_NEG) { | ||
2244 | if ((res = pstm_add (&D, b, &D)) != PSTM_OKAY) { | ||
2245 | goto LBL_D; | ||
2246 | } | ||
2247 | } | ||
2248 | if ((res = pstm_copy (&D, c)) != PSTM_OKAY) { | ||
2249 | goto LBL_D; | ||
2250 | } | ||
2251 | c->sign = neg; | ||
2252 | res = PSTM_OKAY; | ||
2253 | |||
2254 | LBL_D: pstm_clear(&D); | ||
2255 | LBL_B: pstm_clear(&B); | ||
2256 | LBL_V: pstm_clear(&v); | ||
2257 | LBL_U: pstm_clear(&u); | ||
2258 | LBL_Y: pstm_clear(&y); | ||
2259 | LBL_X: pstm_clear(&x); | ||
2260 | return res; | ||
2261 | } | ||
2262 | #endif /* !DISABLE_PSTM */ | ||
2263 | /******************************************************************************/ | ||
diff --git a/networking/tls_pstm.h b/networking/tls_pstm.h new file mode 100644 index 000000000..3a0fd8ce6 --- /dev/null +++ b/networking/tls_pstm.h | |||
@@ -0,0 +1,286 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2017 Denys Vlasenko | ||
3 | * | ||
4 | * Licensed under GPLv2, see file LICENSE in this source tree. | ||
5 | */ | ||
6 | /* The file is taken almost verbatim from matrixssl-3-7-2b-open/crypto/math/. | ||
7 | * Changes are flagged with //bbox | ||
8 | */ | ||
9 | |||
10 | /** | ||
11 | * @file pstm.h | ||
12 | * @version 33ef80f (HEAD, tag: MATRIXSSL-3-7-2-OPEN, tag: MATRIXSSL-3-7-2-COMM, origin/master, origin/HEAD, master) | ||
13 | * | ||
14 | * multiple-precision integer library. | ||
15 | */ | ||
16 | /* | ||
17 | * Copyright (c) 2013-2015 INSIDE Secure Corporation | ||
18 | * Copyright (c) PeerSec Networks, 2002-2011 | ||
19 | * All Rights Reserved | ||
20 | * | ||
21 | * The latest version of this code is available at http://www.matrixssl.org | ||
22 | * | ||
23 | * This software is open source; you can redistribute it and/or modify | ||
24 | * it under the terms of the GNU General Public License as published by | ||
25 | * the Free Software Foundation; either version 2 of the License, or | ||
26 | * (at your option) any later version. | ||
27 | * | ||
28 | * This General Public License does NOT permit incorporating this software | ||
29 | * into proprietary programs. If you are unable to comply with the GPL, a | ||
30 | * commercial license for this software may be purchased from INSIDE at | ||
31 | * http://www.insidesecure.com/eng/Company/Locations | ||
32 | * | ||
33 | * This program is distributed in WITHOUT ANY WARRANTY; without even the | ||
34 | * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. | ||
35 | * See the GNU General Public License for more details. | ||
36 | * | ||
37 | * You should have received a copy of the GNU General Public License | ||
38 | * along with this program; if not, write to the Free Software | ||
39 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
40 | * http://www.gnu.org/copyleft/gpl.html | ||
41 | */ | ||
42 | /******************************************************************************/ | ||
43 | |||
44 | #ifndef _h_PSTMATH | ||
45 | #define _h_PSTMATH | ||
46 | #ifndef DISABLE_PSTM | ||
47 | |||
48 | /* Define this here to avoid including circular limits.h on some platforms */ | ||
49 | #ifndef CHAR_BIT | ||
50 | #define CHAR_BIT 8 | ||
51 | #endif | ||
52 | |||
53 | /******************************************************************************/ | ||
54 | /* | ||
55 | If native 64 bit integers are not supported, we do not support 32x32->64 | ||
56 | in hardware, so we must set the 16 bit flag to produce 16x16->32 products. | ||
57 | */ | ||
58 | #ifndef HAVE_NATIVE_INT64 | ||
59 | #define PSTM_16BIT | ||
60 | #endif /* ! HAVE_NATIVE_INT64 */ | ||
61 | |||
62 | /******************************************************************************/ | ||
63 | /* | ||
64 | Some default configurations. | ||
65 | |||
66 | pstm_word should be the largest value the processor can hold as the product | ||
67 | of a multiplication. Most platforms support a 32x32->64 MAC instruction, | ||
68 | so 64bits is the default pstm_word size. | ||
69 | pstm_digit should be half the size of pstm_word | ||
70 | */ | ||
71 | #ifdef PSTM_8BIT | ||
72 | /* 8-bit digits, 16-bit word products */ | ||
73 | typedef unsigned char pstm_digit; | ||
74 | typedef unsigned short pstm_word; | ||
75 | #define DIGIT_BIT 8 | ||
76 | |||
77 | #elif defined(PSTM_16BIT) | ||
78 | /* 16-bit digits, 32-bit word products */ | ||
79 | typedef unsigned short pstm_digit; | ||
80 | typedef unsigned long pstm_word; | ||
81 | #define DIGIT_BIT 16 | ||
82 | |||
83 | #elif defined(PSTM_64BIT) | ||
84 | /* 64-bit digits, 128-bit word products */ | ||
85 | #ifndef __GNUC__ | ||
86 | #error "64bit digits requires GCC" | ||
87 | #endif | ||
88 | typedef unsigned long pstm_digit; | ||
89 | typedef unsigned long pstm_word __attribute__ ((mode(TI))); | ||
90 | #define DIGIT_BIT 64 | ||
91 | |||
92 | #else | ||
93 | /* This is the default case, 32-bit digits, 64-bit word products */ | ||
94 | typedef uint32 pstm_digit; | ||
95 | typedef uint64 pstm_word; | ||
96 | #define DIGIT_BIT 32 | ||
97 | #define PSTM_32BIT | ||
98 | #endif /* digit and word size */ | ||
99 | |||
100 | #define PSTM_MASK (pstm_digit)(-1) | ||
101 | #define PSTM_DIGIT_MAX PSTM_MASK | ||
102 | |||
103 | /******************************************************************************/ | ||
104 | /* | ||
105 | equalities | ||
106 | */ | ||
107 | #define PSTM_LT -1 /* less than */ | ||
108 | #define PSTM_EQ 0 /* equal to */ | ||
109 | #define PSTM_GT 1 /* greater than */ | ||
110 | |||
111 | #define PSTM_ZPOS 0 /* positive integer */ | ||
112 | #define PSTM_NEG 1 /* negative */ | ||
113 | |||
114 | #define PSTM_OKAY PS_SUCCESS | ||
115 | #define PSTM_MEM PS_MEM_FAIL | ||
116 | |||
117 | /******************************************************************************/ | ||
118 | /* | ||
119 | Various build options | ||
120 | */ | ||
121 | #define PSTM_DEFAULT_INIT 64 /* default (64) digits of allocation */ | ||
122 | #define PSTM_MAX_SIZE 4096 | ||
123 | |||
124 | typedef struct { | ||
125 | int16 used, alloc, sign; | ||
126 | pstm_digit *dp; | ||
127 | //bbox psPool_t *pool; | ||
128 | } pstm_int; | ||
129 | |||
130 | /******************************************************************************/ | ||
131 | /* | ||
132 | Operations on large integers | ||
133 | */ | ||
134 | #define pstm_iszero(a) (((a)->used == 0) ? PS_TRUE : PS_FALSE) | ||
135 | #define pstm_iseven(a) (((a)->used > 0 && (((a)->dp[0] & 1) == 0)) ? PS_TRUE : PS_FALSE) | ||
136 | #define pstm_isodd(a) (((a)->used > 0 && (((a)->dp[0] & 1) == 1)) ? PS_TRUE : PS_FALSE) | ||
137 | #define pstm_abs(a, b) { pstm_copy(a, b); (b)->sign = 0; } | ||
138 | |||
139 | extern void pstm_set(pstm_int *a, pstm_digit b); | ||
140 | |||
141 | extern void pstm_zero(pstm_int * a); | ||
142 | |||
143 | //bbox: pool unused | ||
144 | #define pstm_init(pool, a) \ | ||
145 | pstm_init( a) | ||
146 | extern int32 pstm_init(psPool_t *pool, pstm_int * a); | ||
147 | |||
148 | //bbox: pool unused | ||
149 | #define pstm_init_size(pool, a, size) \ | ||
150 | pstm_init_size( a, size) | ||
151 | extern int32 pstm_init_size(psPool_t *pool, pstm_int * a, uint32 size); | ||
152 | |||
153 | //bbox: pool unused | ||
154 | #define pstm_init_copy(pool, a, b, toSqr) \ | ||
155 | pstm_init_copy( a, b, toSqr) | ||
156 | extern int32 pstm_init_copy(psPool_t *pool, pstm_int * a, pstm_int * b, | ||
157 | int16 toSqr); | ||
158 | |||
159 | extern int16 pstm_count_bits (pstm_int * a); | ||
160 | |||
161 | //bbox: pool unused | ||
162 | #define pstm_init_for_read_unsigned_bin(pool, a, len) \ | ||
163 | pstm_init_for_read_unsigned_bin( a, len) | ||
164 | extern int32 pstm_init_for_read_unsigned_bin(psPool_t *pool, pstm_int *a, | ||
165 | uint32 len); | ||
166 | |||
167 | extern int32 pstm_read_unsigned_bin(pstm_int *a, unsigned char *b, int32 c); | ||
168 | |||
169 | extern int32 pstm_unsigned_bin_size(pstm_int *a); | ||
170 | |||
171 | extern int32 pstm_copy(pstm_int * a, pstm_int * b); | ||
172 | |||
173 | extern void pstm_exch(pstm_int * a, pstm_int * b); | ||
174 | |||
175 | extern void pstm_clear(pstm_int * a); | ||
176 | |||
177 | extern void pstm_clear_multi(pstm_int *mp0, pstm_int *mp1, pstm_int *mp2, | ||
178 | pstm_int *mp3, pstm_int *mp4, pstm_int *mp5, pstm_int *mp6, | ||
179 | pstm_int *mp7); | ||
180 | |||
181 | extern int32 pstm_grow(pstm_int * a, int16 size); | ||
182 | |||
183 | extern void pstm_clamp(pstm_int * a); | ||
184 | |||
185 | extern int32 pstm_cmp(pstm_int * a, pstm_int * b); | ||
186 | |||
187 | extern int32 pstm_cmp_mag(pstm_int * a, pstm_int * b); | ||
188 | |||
189 | extern void pstm_rshd(pstm_int *a, int16 x); | ||
190 | |||
191 | extern int32 pstm_lshd(pstm_int * a, int16 b); | ||
192 | |||
193 | //bbox: pool unused | ||
194 | #define pstm_div(pool, a, b, c, d) \ | ||
195 | pstm_div( a, b, c, d) | ||
196 | extern int32 pstm_div(psPool_t *pool, pstm_int *a, pstm_int *b, pstm_int *c, | ||
197 | pstm_int *d); | ||
198 | |||
199 | //bbox: pool unused | ||
200 | #define pstm_div_2d(pool, a, b, c, d) \ | ||
201 | pstm_div_2d( a, b, c, d) | ||
202 | extern int32 pstm_div_2d(psPool_t *pool, pstm_int *a, int16 b, pstm_int *c, | ||
203 | pstm_int *d); | ||
204 | |||
205 | extern int32 pstm_div_2(pstm_int * a, pstm_int * b); | ||
206 | |||
207 | extern int32 s_pstm_sub(pstm_int *a, pstm_int *b, pstm_int *c); | ||
208 | |||
209 | extern int32 pstm_sub(pstm_int *a, pstm_int *b, pstm_int *c); | ||
210 | |||
211 | //bbox: pool unused | ||
212 | #define pstm_sub_d(pool, a, b, c) \ | ||
213 | pstm_sub_d( a, b, c) | ||
214 | extern int32 pstm_sub_d(psPool_t *pool, pstm_int *a, pstm_digit b, pstm_int *c); | ||
215 | |||
216 | extern int32 pstm_mul_2(pstm_int * a, pstm_int * b); | ||
217 | |||
218 | //bbox: pool unused | ||
219 | #define pstm_mod(pool, a, b, c) \ | ||
220 | pstm_mod( a, b, c) | ||
221 | extern int32 pstm_mod(psPool_t *pool, pstm_int *a, pstm_int *b, pstm_int *c); | ||
222 | |||
223 | //bbox: pool unused | ||
224 | #define pstm_mulmod(pool, a, b, c, d) \ | ||
225 | pstm_mulmod( a, b, c, d) | ||
226 | extern int32 pstm_mulmod(psPool_t *pool, pstm_int *a, pstm_int *b, pstm_int *c, | ||
227 | pstm_int *d); | ||
228 | |||
229 | //bbox: pool unused | ||
230 | #define pstm_exptmod(pool, G, X, P, Y) \ | ||
231 | pstm_exptmod( G, X, P, Y) | ||
232 | extern int32 pstm_exptmod(psPool_t *pool, pstm_int *G, pstm_int *X, pstm_int *P, | ||
233 | pstm_int *Y); | ||
234 | |||
235 | extern int32 pstm_2expt(pstm_int *a, int16 b); | ||
236 | |||
237 | extern int32 pstm_add(pstm_int *a, pstm_int *b, pstm_int *c); | ||
238 | |||
239 | //bbox: pool unused | ||
240 | #define pstm_to_unsigned_bin(pool, a, b) \ | ||
241 | pstm_to_unsigned_bin( a, b) | ||
242 | extern int32 pstm_to_unsigned_bin(psPool_t *pool, pstm_int *a, | ||
243 | unsigned char *b); | ||
244 | |||
245 | //bbox: pool unused | ||
246 | #define pstm_to_unsigned_bin_nr(pool, a, b) \ | ||
247 | pstm_to_unsigned_bin_nr( a, b) | ||
248 | extern int32 pstm_to_unsigned_bin_nr(psPool_t *pool, pstm_int *a, | ||
249 | unsigned char *b); | ||
250 | |||
251 | extern int32 pstm_montgomery_setup(pstm_int *a, pstm_digit *rho); | ||
252 | |||
253 | //bbox: pool unused | ||
254 | #define pstm_montgomery_reduce(pool, a, m, mp, paD, paDlen) \ | ||
255 | pstm_montgomery_reduce( a, m, mp, paD, paDlen) | ||
256 | extern int32 pstm_montgomery_reduce(psPool_t *pool, pstm_int *a, pstm_int *m, | ||
257 | pstm_digit mp, pstm_digit *paD, uint32 paDlen); | ||
258 | |||
259 | #define pstm_mul_comba(pool, A, B, C, paD, paDlen) \ | ||
260 | pstm_mul_comba( A, B, C, paD, paDlen) | ||
261 | extern int32 pstm_mul_comba(psPool_t *pool, pstm_int *A, pstm_int *B, | ||
262 | pstm_int *C, pstm_digit *paD, uint32 paDlen); | ||
263 | |||
264 | //bbox: pool unused | ||
265 | #define pstm_sqr_comba(pool, A, B, paD, paDlen) \ | ||
266 | pstm_sqr_comba( A, B, paD, paDlen) | ||
267 | extern int32 pstm_sqr_comba(psPool_t *pool, pstm_int *A, pstm_int *B, | ||
268 | pstm_digit *paD, uint32 paDlen); | ||
269 | |||
270 | extern int32 pstm_cmp_d(pstm_int *a, pstm_digit b); | ||
271 | |||
272 | extern int32 pstm_montgomery_calc_normalization(pstm_int *a, pstm_int *b); | ||
273 | |||
274 | extern int32 pstm_mul_d(pstm_int *a, pstm_digit b, pstm_int *c); | ||
275 | |||
276 | //bbox: pool unused | ||
277 | #define pstm_invmod(pool, a, b, c) \ | ||
278 | pstm_invmod( a, b, c) | ||
279 | extern int32 pstm_invmod(psPool_t *pool, pstm_int * a, pstm_int * b, | ||
280 | pstm_int * c); | ||
281 | |||
282 | #else /* DISABLE_PSTM */ | ||
283 | typedef int32 pstm_int; | ||
284 | #endif /* !DISABLE_PSTM */ | ||
285 | #endif /* _h_PSTMATH */ | ||
286 | |||
diff --git a/networking/tls_pstm_montgomery_reduce.c b/networking/tls_pstm_montgomery_reduce.c new file mode 100644 index 000000000..dc2fe0a48 --- /dev/null +++ b/networking/tls_pstm_montgomery_reduce.c | |||
@@ -0,0 +1,427 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2017 Denys Vlasenko | ||
3 | * | ||
4 | * Licensed under GPLv2, see file LICENSE in this source tree. | ||
5 | */ | ||
6 | #include "tls.h" | ||
7 | |||
8 | /* The file is taken almost verbatim from matrixssl-3-7-2b-open/crypto/math/. | ||
9 | * Changes are flagged with //bbox | ||
10 | */ | ||
11 | |||
12 | /** | ||
13 | * @file pstm_montgomery_reduce.c | ||
14 | * @version 33ef80f (HEAD, tag: MATRIXSSL-3-7-2-OPEN, tag: MATRIXSSL-3-7-2-COMM, origin/master, origin/HEAD, master) | ||
15 | * | ||
16 | * Multiprecision Montgomery Reduction. | ||
17 | */ | ||
18 | /* | ||
19 | * Copyright (c) 2013-2015 INSIDE Secure Corporation | ||
20 | * Copyright (c) PeerSec Networks, 2002-2011 | ||
21 | * All Rights Reserved | ||
22 | * | ||
23 | * The latest version of this code is available at http://www.matrixssl.org | ||
24 | * | ||
25 | * This software is open source; you can redistribute it and/or modify | ||
26 | * it under the terms of the GNU General Public License as published by | ||
27 | * the Free Software Foundation; either version 2 of the License, or | ||
28 | * (at your option) any later version. | ||
29 | * | ||
30 | * This General Public License does NOT permit incorporating this software | ||
31 | * into proprietary programs. If you are unable to comply with the GPL, a | ||
32 | * commercial license for this software may be purchased from INSIDE at | ||
33 | * http://www.insidesecure.com/eng/Company/Locations | ||
34 | * | ||
35 | * This program is distributed in WITHOUT ANY WARRANTY; without even the | ||
36 | * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. | ||
37 | * See the GNU General Public License for more details. | ||
38 | * | ||
39 | * You should have received a copy of the GNU General Public License | ||
40 | * along with this program; if not, write to the Free Software | ||
41 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
42 | * http://www.gnu.org/copyleft/gpl.html | ||
43 | */ | ||
44 | /******************************************************************************/ | ||
45 | |||
46 | //bbox | ||
47 | //#include "../cryptoApi.h" | ||
48 | #ifndef DISABLE_PSTM | ||
49 | |||
50 | /******************************************************************************/ | ||
51 | |||
52 | #if defined(PSTM_X86) | ||
53 | /* x86-32 optimized for 32 bit platforms. For 64 bit mode use X86_64 instead */ | ||
54 | #if !defined(__GNUC__) || !defined(__i386__) || !defined(PSTM_32BIT) | ||
55 | #error "PSTM_X86 option requires GCC and 32 bit mode x86 processor" | ||
56 | #endif | ||
57 | //#pragma message ("Using 32 bit x86 Assembly Optimizations") | ||
58 | |||
59 | #define MONT_START | ||
60 | #define MONT_FINI | ||
61 | #define LOOP_END | ||
62 | #define LOOP_START \ | ||
63 | mu = c[x] * mp | ||
64 | |||
65 | #define INNERMUL \ | ||
66 | asm( \ | ||
67 | "movl %5,%%eax \n\t" \ | ||
68 | "mull %4 \n\t" \ | ||
69 | "addl %1,%%eax \n\t" \ | ||
70 | "adcl $0,%%edx \n\t" \ | ||
71 | "addl %%eax,%0 \n\t" \ | ||
72 | "adcl $0,%%edx \n\t" \ | ||
73 | "movl %%edx,%1 \n\t" \ | ||
74 | :"=g"(_c[LO]), "=r"(cy) \ | ||
75 | :"0"(_c[LO]), "1"(cy), "g"(mu), "g"(*tmpm++) \ | ||
76 | : "%eax", "%edx", "%cc") | ||
77 | |||
78 | #define PROPCARRY \ | ||
79 | asm( \ | ||
80 | "addl %1,%0 \n\t" \ | ||
81 | "setb %%al \n\t" \ | ||
82 | "movzbl %%al,%1 \n\t" \ | ||
83 | :"=g"(_c[LO]), "=r"(cy) \ | ||
84 | :"0"(_c[LO]), "1"(cy) \ | ||
85 | : "%eax", "%cc") | ||
86 | |||
87 | /******************************************************************************/ | ||
88 | #elif defined(PSTM_X86_64) | ||
89 | /* x86-64 optimized */ | ||
90 | #if !defined(__GNUC__) || !defined(__x86_64__) || !defined(PSTM_64BIT) | ||
91 | #error "PSTM_X86_64 option requires PSTM_64BIT, GCC and 64 bit mode x86 processor" | ||
92 | #endif | ||
93 | //#pragma message ("Using 64 bit x86_64 Assembly Optimizations") | ||
94 | |||
95 | #define MONT_START | ||
96 | #define MONT_FINI | ||
97 | #define LOOP_END | ||
98 | #define LOOP_START \ | ||
99 | mu = c[x] * mp | ||
100 | |||
101 | #define INNERMUL \ | ||
102 | asm( \ | ||
103 | "movq %5,%%rax \n\t" \ | ||
104 | "mulq %4 \n\t" \ | ||
105 | "addq %1,%%rax \n\t" \ | ||
106 | "adcq $0,%%rdx \n\t" \ | ||
107 | "addq %%rax,%0 \n\t" \ | ||
108 | "adcq $0,%%rdx \n\t" \ | ||
109 | "movq %%rdx,%1 \n\t" \ | ||
110 | :"=g"(_c[LO]), "=r"(cy) \ | ||
111 | :"0"(_c[LO]), "1"(cy), "r"(mu), "r"(*tmpm++) \ | ||
112 | : "%rax", "%rdx", "cc") | ||
113 | |||
114 | #define INNERMUL8 \ | ||
115 | asm( \ | ||
116 | "movq 0(%5),%%rax \n\t" \ | ||
117 | "movq 0(%2),%%r10 \n\t" \ | ||
118 | "movq 0x8(%5),%%r11 \n\t" \ | ||
119 | "mulq %4 \n\t" \ | ||
120 | "addq %%r10,%%rax \n\t" \ | ||
121 | "adcq $0,%%rdx \n\t" \ | ||
122 | "movq 0x8(%2),%%r10 \n\t" \ | ||
123 | "addq %3,%%rax \n\t" \ | ||
124 | "adcq $0,%%rdx \n\t" \ | ||
125 | "movq %%rax,0(%0) \n\t" \ | ||
126 | "movq %%rdx,%1 \n\t" \ | ||
127 | \ | ||
128 | "movq %%r11,%%rax \n\t" \ | ||
129 | "movq 0x10(%5),%%r11 \n\t" \ | ||
130 | "mulq %4 \n\t" \ | ||
131 | "addq %%r10,%%rax \n\t" \ | ||
132 | "adcq $0,%%rdx \n\t" \ | ||
133 | "movq 0x10(%2),%%r10 \n\t" \ | ||
134 | "addq %3,%%rax \n\t" \ | ||
135 | "adcq $0,%%rdx \n\t" \ | ||
136 | "movq %%rax,0x8(%0) \n\t" \ | ||
137 | "movq %%rdx,%1 \n\t" \ | ||
138 | \ | ||
139 | "movq %%r11,%%rax \n\t" \ | ||
140 | "movq 0x18(%5),%%r11 \n\t" \ | ||
141 | "mulq %4 \n\t" \ | ||
142 | "addq %%r10,%%rax \n\t" \ | ||
143 | "adcq $0,%%rdx \n\t" \ | ||
144 | "movq 0x18(%2),%%r10 \n\t" \ | ||
145 | "addq %3,%%rax \n\t" \ | ||
146 | "adcq $0,%%rdx \n\t" \ | ||
147 | "movq %%rax,0x10(%0) \n\t" \ | ||
148 | "movq %%rdx,%1 \n\t" \ | ||
149 | \ | ||
150 | "movq %%r11,%%rax \n\t" \ | ||
151 | "movq 0x20(%5),%%r11 \n\t" \ | ||
152 | "mulq %4 \n\t" \ | ||
153 | "addq %%r10,%%rax \n\t" \ | ||
154 | "adcq $0,%%rdx \n\t" \ | ||
155 | "movq 0x20(%2),%%r10 \n\t" \ | ||
156 | "addq %3,%%rax \n\t" \ | ||
157 | "adcq $0,%%rdx \n\t" \ | ||
158 | "movq %%rax,0x18(%0) \n\t" \ | ||
159 | "movq %%rdx,%1 \n\t" \ | ||
160 | \ | ||
161 | "movq %%r11,%%rax \n\t" \ | ||
162 | "movq 0x28(%5),%%r11 \n\t" \ | ||
163 | "mulq %4 \n\t" \ | ||
164 | "addq %%r10,%%rax \n\t" \ | ||
165 | "adcq $0,%%rdx \n\t" \ | ||
166 | "movq 0x28(%2),%%r10 \n\t" \ | ||
167 | "addq %3,%%rax \n\t" \ | ||
168 | "adcq $0,%%rdx \n\t" \ | ||
169 | "movq %%rax,0x20(%0) \n\t" \ | ||
170 | "movq %%rdx,%1 \n\t" \ | ||
171 | \ | ||
172 | "movq %%r11,%%rax \n\t" \ | ||
173 | "movq 0x30(%5),%%r11 \n\t" \ | ||
174 | "mulq %4 \n\t" \ | ||
175 | "addq %%r10,%%rax \n\t" \ | ||
176 | "adcq $0,%%rdx \n\t" \ | ||
177 | "movq 0x30(%2),%%r10 \n\t" \ | ||
178 | "addq %3,%%rax \n\t" \ | ||
179 | "adcq $0,%%rdx \n\t" \ | ||
180 | "movq %%rax,0x28(%0) \n\t" \ | ||
181 | "movq %%rdx,%1 \n\t" \ | ||
182 | \ | ||
183 | "movq %%r11,%%rax \n\t" \ | ||
184 | "movq 0x38(%5),%%r11 \n\t" \ | ||
185 | "mulq %4 \n\t" \ | ||
186 | "addq %%r10,%%rax \n\t" \ | ||
187 | "adcq $0,%%rdx \n\t" \ | ||
188 | "movq 0x38(%2),%%r10 \n\t" \ | ||
189 | "addq %3,%%rax \n\t" \ | ||
190 | "adcq $0,%%rdx \n\t" \ | ||
191 | "movq %%rax,0x30(%0) \n\t" \ | ||
192 | "movq %%rdx,%1 \n\t" \ | ||
193 | \ | ||
194 | "movq %%r11,%%rax \n\t" \ | ||
195 | "mulq %4 \n\t" \ | ||
196 | "addq %%r10,%%rax \n\t" \ | ||
197 | "adcq $0,%%rdx \n\t" \ | ||
198 | "addq %3,%%rax \n\t" \ | ||
199 | "adcq $0,%%rdx \n\t" \ | ||
200 | "movq %%rax,0x38(%0) \n\t" \ | ||
201 | "movq %%rdx,%1 \n\t" \ | ||
202 | \ | ||
203 | :"=r"(_c), "=r"(cy) \ | ||
204 | : "0"(_c), "1"(cy), "g"(mu), "r"(tmpm)\ | ||
205 | : "%rax", "%rdx", "%r10", "%r11", "cc") | ||
206 | |||
207 | #define PROPCARRY \ | ||
208 | asm( \ | ||
209 | "addq %1,%0 \n\t" \ | ||
210 | "setb %%al \n\t" \ | ||
211 | "movzbq %%al,%1 \n\t" \ | ||
212 | :"=g"(_c[LO]), "=r"(cy) \ | ||
213 | :"0"(_c[LO]), "1"(cy) \ | ||
214 | : "%rax", "cc") | ||
215 | |||
216 | /******************************************************************************/ | ||
217 | #elif defined(PSTM_ARM) | ||
218 | |||
219 | #define MONT_START | ||
220 | #define MONT_FINI | ||
221 | #define LOOP_END | ||
222 | #define LOOP_START \ | ||
223 | mu = c[x] * mp | ||
224 | |||
225 | #ifdef __thumb2__ | ||
226 | //#pragma message ("Using 32 bit ARM Thumb2 Assembly Optimizations") | ||
227 | #define INNERMUL \ | ||
228 | asm( \ | ||
229 | " LDR r0,%1 \n\t" \ | ||
230 | " ADDS r0,r0,%0 \n\t" \ | ||
231 | " ITE CS \n\t" \ | ||
232 | " MOVCS %0,#1 \n\t" \ | ||
233 | " MOVCC %0,#0 \n\t" \ | ||
234 | " UMLAL r0,%0,%3,%4 \n\t" \ | ||
235 | " STR r0,%1 \n\t" \ | ||
236 | :"=r"(cy),"=m"(_c[0])\ | ||
237 | :"0"(cy),"r"(mu),"r"(*tmpm++),"m"(_c[0])\ | ||
238 | :"r0","%cc"); | ||
239 | #define PROPCARRY \ | ||
240 | asm( \ | ||
241 | " LDR r0,%1 \n\t" \ | ||
242 | " ADDS r0,r0,%0 \n\t" \ | ||
243 | " STR r0,%1 \n\t" \ | ||
244 | " ITE CS \n\t" \ | ||
245 | " MOVCS %0,#1 \n\t" \ | ||
246 | " MOVCC %0,#0 \n\t" \ | ||
247 | :"=r"(cy),"=m"(_c[0])\ | ||
248 | :"0"(cy),"m"(_c[0])\ | ||
249 | :"r0","%cc"); | ||
250 | #else /* Non-Thumb2 code */ | ||
251 | //#pragma message ("Using 32 bit ARM Assembly Optimizations") | ||
252 | #define INNERMUL \ | ||
253 | asm( \ | ||
254 | " LDR r0,%1 \n\t" \ | ||
255 | " ADDS r0,r0,%0 \n\t" \ | ||
256 | " MOVCS %0,#1 \n\t" \ | ||
257 | " MOVCC %0,#0 \n\t" \ | ||
258 | " UMLAL r0,%0,%3,%4 \n\t" \ | ||
259 | " STR r0,%1 \n\t" \ | ||
260 | :"=r"(cy),"=m"(_c[0])\ | ||
261 | :"0"(cy),"r"(mu),"r"(*tmpm++),"m"(_c[0])\ | ||
262 | :"r0","%cc"); | ||
263 | #define PROPCARRY \ | ||
264 | asm( \ | ||
265 | " LDR r0,%1 \n\t" \ | ||
266 | " ADDS r0,r0,%0 \n\t" \ | ||
267 | " STR r0,%1 \n\t" \ | ||
268 | " MOVCS %0,#1 \n\t" \ | ||
269 | " MOVCC %0,#0 \n\t" \ | ||
270 | :"=r"(cy),"=m"(_c[0])\ | ||
271 | :"0"(cy),"m"(_c[0])\ | ||
272 | :"r0","%cc"); | ||
273 | #endif /* __thumb2__ */ | ||
274 | |||
275 | |||
276 | /******************************************************************************/ | ||
277 | #elif defined(PSTM_MIPS) | ||
278 | /* MIPS32 */ | ||
279 | //#pragma message ("Using 32 bit MIPS Assembly Optimizations") | ||
280 | #define MONT_START | ||
281 | #define MONT_FINI | ||
282 | #define LOOP_END | ||
283 | #define LOOP_START \ | ||
284 | mu = c[x] * mp | ||
285 | |||
286 | #define INNERMUL \ | ||
287 | asm( \ | ||
288 | " multu %3,%4 \n\t" \ | ||
289 | " mflo $12 \n\t" \ | ||
290 | " mfhi $13 \n\t" \ | ||
291 | " addu $12,$12,%0 \n\t" \ | ||
292 | " sltu $10,$12,%0 \n\t" \ | ||
293 | " addu $13,$13,$10 \n\t" \ | ||
294 | " lw $10,%1 \n\t" \ | ||
295 | " addu $12,$12,$10 \n\t" \ | ||
296 | " sltu $10,$12,$10 \n\t" \ | ||
297 | " addu %0,$13,$10 \n\t" \ | ||
298 | " sw $12,%1 \n\t" \ | ||
299 | :"=r"(cy),"=m"(_c[0])\ | ||
300 | :"r"(cy),"r"(mu),"r"(tmpm[0]),"r"(_c[0])\ | ||
301 | :"$10","$12","$13")\ | ||
302 | ; ++tmpm; | ||
303 | |||
304 | #define PROPCARRY \ | ||
305 | asm( \ | ||
306 | " lw $10,%1 \n\t" \ | ||
307 | " addu $10,$10,%0 \n\t" \ | ||
308 | " sw $10,%1 \n\t" \ | ||
309 | " sltu %0,$10,%0 \n\t" \ | ||
310 | :"=r"(cy),"=m"(_c[0])\ | ||
311 | :"r"(cy),"r"(_c[0])\ | ||
312 | :"$10"); | ||
313 | |||
314 | |||
315 | /******************************************************************************/ | ||
316 | #else | ||
317 | |||
318 | /* ISO C code */ | ||
319 | #define MONT_START | ||
320 | #define MONT_FINI | ||
321 | #define LOOP_END | ||
322 | #define LOOP_START \ | ||
323 | mu = c[x] * mp | ||
324 | |||
325 | #define INNERMUL \ | ||
326 | do { pstm_word t; \ | ||
327 | t = ((pstm_word)_c[0] + (pstm_word)cy) + \ | ||
328 | (((pstm_word)mu) * ((pstm_word)*tmpm++)); \ | ||
329 | _c[0] = (pstm_digit)t; \ | ||
330 | cy = (pstm_digit)(t >> DIGIT_BIT); \ | ||
331 | } while (0) | ||
332 | |||
333 | #define PROPCARRY \ | ||
334 | do { pstm_digit t = _c[0] += cy; cy = (t < cy); } while (0) | ||
335 | |||
336 | #endif | ||
337 | |||
338 | /******************************************************************************/ | ||
339 | |||
340 | #define LO 0 | ||
341 | |||
342 | /* computes x/R == x (mod N) via Montgomery Reduction */ | ||
343 | int32 pstm_montgomery_reduce(psPool_t *pool, pstm_int *a, pstm_int *m, | ||
344 | pstm_digit mp, pstm_digit *paD, uint32 paDlen) | ||
345 | { | ||
346 | pstm_digit *c, *_c, *tmpm, mu; | ||
347 | int32 oldused, x, y; | ||
348 | int16 pa; | ||
349 | |||
350 | pa = m->used; | ||
351 | if (pa > a->alloc) { | ||
352 | /* Sanity test for bad numbers. This will confirm no buffer overruns */ | ||
353 | return PS_LIMIT_FAIL; | ||
354 | } | ||
355 | |||
356 | if (paD && paDlen >= (uint32)2*pa+1) { | ||
357 | c = paD; | ||
358 | memset(c, 0x0, paDlen); | ||
359 | } else { | ||
360 | c = xzalloc(2*pa+1);//bbox | ||
361 | } | ||
362 | /* copy the input */ | ||
363 | oldused = a->used; | ||
364 | for (x = 0; x < oldused; x++) { | ||
365 | c[x] = a->dp[x]; | ||
366 | } | ||
367 | |||
368 | MONT_START; | ||
369 | |||
370 | for (x = 0; x < pa; x++) { | ||
371 | pstm_digit cy = 0; | ||
372 | /* get Mu for this round */ | ||
373 | LOOP_START; | ||
374 | _c = c + x; | ||
375 | tmpm = m->dp; | ||
376 | y = 0; | ||
377 | #ifdef PSTM_X86_64 | ||
378 | for (; y < (pa & ~7); y += 8) { | ||
379 | INNERMUL8; | ||
380 | _c += 8; | ||
381 | tmpm += 8; | ||
382 | } | ||
383 | #endif /* PSTM_X86_64 */ | ||
384 | for (; y < pa; y++) { | ||
385 | INNERMUL; | ||
386 | ++_c; | ||
387 | } | ||
388 | LOOP_END; | ||
389 | while (cy) { | ||
390 | PROPCARRY; | ||
391 | ++_c; | ||
392 | } | ||
393 | } | ||
394 | |||
395 | /* now copy out */ | ||
396 | _c = c + pa; | ||
397 | tmpm = a->dp; | ||
398 | for (x = 0; x < pa+1; x++) { | ||
399 | *tmpm++ = *_c++; | ||
400 | } | ||
401 | |||
402 | for (; x < oldused; x++) { | ||
403 | *tmpm++ = 0; | ||
404 | } | ||
405 | |||
406 | MONT_FINI; | ||
407 | |||
408 | a->used = pa+1; | ||
409 | pstm_clamp(a); | ||
410 | |||
411 | /* reuse x as return code */ | ||
412 | x = PSTM_OKAY; | ||
413 | |||
414 | /* if A >= m then A = A - m */ | ||
415 | if (pstm_cmp_mag (a, m) != PSTM_LT) { | ||
416 | if (s_pstm_sub (a, m, a) != PSTM_OKAY) { | ||
417 | x = PS_MEM_FAIL; | ||
418 | } | ||
419 | } | ||
420 | if (paDlen < (uint32)2*pa+1) { | ||
421 | psFree(c, pool); | ||
422 | } | ||
423 | return x; | ||
424 | } | ||
425 | |||
426 | #endif /* !DISABLE_PSTM */ | ||
427 | /******************************************************************************/ | ||
diff --git a/networking/tls_pstm_mul_comba.c b/networking/tls_pstm_mul_comba.c new file mode 100644 index 000000000..47cbb9618 --- /dev/null +++ b/networking/tls_pstm_mul_comba.c | |||
@@ -0,0 +1,781 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2017 Denys Vlasenko | ||
3 | * | ||
4 | * Licensed under GPLv2, see file LICENSE in this source tree. | ||
5 | */ | ||
6 | #include "tls.h" | ||
7 | |||
8 | /* The file is taken almost verbatim from matrixssl-3-7-2b-open/crypto/math/. | ||
9 | * Changes are flagged with //bbox | ||
10 | */ | ||
11 | |||
12 | /** | ||
13 | * @file pstm_mul_comba.c | ||
14 | * @version 33ef80f (HEAD, tag: MATRIXSSL-3-7-2-OPEN, tag: MATRIXSSL-3-7-2-COMM, origin/master, origin/HEAD, master) | ||
15 | * | ||
16 | * Multiprecision multiplication with Comba technique. | ||
17 | */ | ||
18 | /* | ||
19 | * Copyright (c) 2013-2015 INSIDE Secure Corporation | ||
20 | * Copyright (c) PeerSec Networks, 2002-2011 | ||
21 | * All Rights Reserved | ||
22 | * | ||
23 | * The latest version of this code is available at http://www.matrixssl.org | ||
24 | * | ||
25 | * This software is open source; you can redistribute it and/or modify | ||
26 | * it under the terms of the GNU General Public License as published by | ||
27 | * the Free Software Foundation; either version 2 of the License, or | ||
28 | * (at your option) any later version. | ||
29 | * | ||
30 | * This General Public License does NOT permit incorporating this software | ||
31 | * into proprietary programs. If you are unable to comply with the GPL, a | ||
32 | * commercial license for this software may be purchased from INSIDE at | ||
33 | * http://www.insidesecure.com/eng/Company/Locations | ||
34 | * | ||
35 | * This program is distributed in WITHOUT ANY WARRANTY; without even the | ||
36 | * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. | ||
37 | * See the GNU General Public License for more details. | ||
38 | * | ||
39 | * You should have received a copy of the GNU General Public License | ||
40 | * along with this program; if not, write to the Free Software | ||
41 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
42 | * http://www.gnu.org/copyleft/gpl.html | ||
43 | */ | ||
44 | /******************************************************************************/ | ||
45 | |||
46 | //bbox | ||
47 | //#include "../cryptoApi.h" | ||
48 | #ifndef DISABLE_PSTM | ||
49 | |||
50 | /******************************************************************************/ | ||
51 | #if defined(PSTM_X86) | ||
52 | /* x86-32 optimized for 32 bit platforms. For 64 bit mode use X86_64 instead */ | ||
53 | #if !defined(__GNUC__) || !defined(__i386__) || !defined(PSTM_32BIT) | ||
54 | #error "PSTM_X86 option requires GCC and 32 bit mode x86 processor" | ||
55 | #endif | ||
56 | //#pragma message ("Using 32 bit x86 Assembly Optimizations") | ||
57 | |||
58 | /* anything you need at the start */ | ||
59 | #define COMBA_START | ||
60 | |||
61 | /* clear the chaining variables */ | ||
62 | #define COMBA_CLEAR \ | ||
63 | c0 = c1 = c2 = 0; | ||
64 | |||
65 | /* forward the carry to the next digit */ | ||
66 | #define COMBA_FORWARD \ | ||
67 | do { c0 = c1; c1 = c2; c2 = 0; } while (0); | ||
68 | |||
69 | /* store the first sum */ | ||
70 | #define COMBA_STORE(x) \ | ||
71 | x = c0; | ||
72 | |||
73 | /* store the second sum [carry] */ | ||
74 | #define COMBA_STORE2(x) \ | ||
75 | x = c1; | ||
76 | |||
77 | /* anything you need at the end */ | ||
78 | #define COMBA_FINI | ||
79 | |||
80 | /* this should multiply i and j */ | ||
81 | #define MULADD(i, j) \ | ||
82 | asm( \ | ||
83 | "movl %6,%%eax \n\t" \ | ||
84 | "mull %7 \n\t" \ | ||
85 | "addl %%eax,%0 \n\t" \ | ||
86 | "adcl %%edx,%1 \n\t" \ | ||
87 | "adcl $0,%2 \n\t" \ | ||
88 | :"=r"(c0), "=r"(c1), "=r"(c2): "0"(c0), "1"(c1), "2"(c2), "m"(i), "m"(j) :"%eax","%edx","%cc"); | ||
89 | |||
90 | /******************************************************************************/ | ||
91 | #elif defined(PSTM_X86_64) | ||
92 | /* x86-64 optimized */ | ||
93 | #if !defined(__GNUC__) || !defined(__x86_64__) || !defined(PSTM_64BIT) | ||
94 | #error "PSTM_X86_64 option requires PSTM_64BIT, GCC and 64 bit mode x86 processor" | ||
95 | #endif | ||
96 | //#pragma message ("Using 64 bit x86_64 Assembly Optimizations") | ||
97 | |||
98 | /* anything you need at the start */ | ||
99 | #define COMBA_START | ||
100 | |||
101 | /* clear the chaining variables */ | ||
102 | #define COMBA_CLEAR \ | ||
103 | c0 = c1 = c2 = 0; | ||
104 | |||
105 | /* forward the carry to the next digit */ | ||
106 | #define COMBA_FORWARD \ | ||
107 | do { c0 = c1; c1 = c2; c2 = 0; } while (0); | ||
108 | |||
109 | /* store the first sum */ | ||
110 | #define COMBA_STORE(x) \ | ||
111 | x = c0; | ||
112 | |||
113 | /* store the second sum [carry] */ | ||
114 | #define COMBA_STORE2(x) \ | ||
115 | x = c1; | ||
116 | |||
117 | /* anything you need at the end */ | ||
118 | #define COMBA_FINI | ||
119 | |||
120 | /* this should multiply i and j */ | ||
121 | #define MULADD(i, j) \ | ||
122 | asm ( \ | ||
123 | "movq %6,%%rax \n\t" \ | ||
124 | "mulq %7 \n\t" \ | ||
125 | "addq %%rax,%0 \n\t" \ | ||
126 | "adcq %%rdx,%1 \n\t" \ | ||
127 | "adcq $0,%2 \n\t" \ | ||
128 | :"=r"(c0), "=r"(c1), "=r"(c2): "0"(c0), "1"(c1), "2"(c2), "g"(i), "g"(j) :"%rax","%rdx","cc"); | ||
129 | |||
130 | /******************************************************************************/ | ||
131 | #elif defined(PSTM_ARM) | ||
132 | /* ARM code */ | ||
133 | //#pragma message ("Using 32 bit ARM Assembly Optimizations") | ||
134 | |||
135 | #define COMBA_START | ||
136 | |||
137 | #define COMBA_CLEAR \ | ||
138 | c0 = c1 = c2 = 0; | ||
139 | |||
140 | #define COMBA_FORWARD \ | ||
141 | do { c0 = c1; c1 = c2; c2 = 0; } while (0); | ||
142 | |||
143 | #define COMBA_STORE(x) \ | ||
144 | x = c0; | ||
145 | |||
146 | #define COMBA_STORE2(x) \ | ||
147 | x = c1; | ||
148 | |||
149 | #define COMBA_FINI | ||
150 | |||
151 | #define MULADD(i, j) \ | ||
152 | asm( \ | ||
153 | " UMULL r0,r1,%6,%7 \n\t" \ | ||
154 | " ADDS %0,%0,r0 \n\t" \ | ||
155 | " ADCS %1,%1,r1 \n\t" \ | ||
156 | " ADC %2,%2,#0 \n\t" \ | ||
157 | :"=r"(c0), "=r"(c1), "=r"(c2) : "0"(c0), "1"(c1), "2"(c2), "r"(i), "r"(j) : "r0", "r1", "%cc"); | ||
158 | |||
159 | /******************************************************************************/ | ||
160 | #elif defined(PSTM_MIPS) | ||
161 | /* MIPS32 code */ | ||
162 | //#pragma message ("Using 32 bit MIPS Assembly Optimizations") | ||
163 | |||
164 | #define COMBA_START | ||
165 | |||
166 | #define COMBA_CLEAR \ | ||
167 | c0 = c1 = c2 = 0; | ||
168 | |||
169 | #define COMBA_FORWARD \ | ||
170 | do { c0 = c1; c1 = c2; c2 = 0; } while (0); | ||
171 | |||
172 | #define COMBA_STORE(x) \ | ||
173 | x = c0; | ||
174 | |||
175 | #define COMBA_STORE2(x) \ | ||
176 | x = c1; | ||
177 | |||
178 | #define COMBA_FINI | ||
179 | |||
180 | #define MULADD(i, j) \ | ||
181 | asm( \ | ||
182 | " multu %6,%7 \n\t" \ | ||
183 | " mflo $12 \n\t" \ | ||
184 | " mfhi $13 \n\t" \ | ||
185 | " addu %0,%0,$12 \n\t" \ | ||
186 | " sltu $12,%0,$12 \n\t" \ | ||
187 | " addu %1,%1,$13 \n\t" \ | ||
188 | " sltu $13,%1,$13 \n\t" \ | ||
189 | " addu %1,%1,$12 \n\t" \ | ||
190 | " sltu $12,%1,$12 \n\t" \ | ||
191 | " addu %2,%2,$13 \n\t" \ | ||
192 | " addu %2,%2,$12 \n\t" \ | ||
193 | :"=r"(c0), "=r"(c1), "=r"(c2):"0"(c0), "1"(c1), "2"(c2), "r"(i), "r"(j):"$12","$13"); | ||
194 | |||
195 | /******************************************************************************/ | ||
196 | #else | ||
197 | |||
198 | #define COMBA_START | ||
199 | |||
200 | #define COMBA_CLEAR \ | ||
201 | c0 = c1 = c2 = 0; | ||
202 | |||
203 | #define COMBA_FORWARD \ | ||
204 | do { c0 = c1; c1 = c2; c2 = 0; } while (0); | ||
205 | |||
206 | #define COMBA_STORE(x) \ | ||
207 | x = c0; | ||
208 | |||
209 | #define COMBA_STORE2(x) \ | ||
210 | x = c1; | ||
211 | |||
212 | #define COMBA_FINI | ||
213 | |||
214 | #define MULADD(i, j) \ | ||
215 | do { pstm_word t; \ | ||
216 | t = (pstm_word)c0 + ((pstm_word)i) * ((pstm_word)j); c0 = (pstm_digit)t; \ | ||
217 | t = (pstm_word)c1 + (t >> DIGIT_BIT); \ | ||
218 | c1 = (pstm_digit)t; c2 += (pstm_digit)(t >> DIGIT_BIT); \ | ||
219 | } while (0); | ||
220 | |||
221 | #endif | ||
222 | |||
223 | /******************************************************************************/ | ||
224 | /* generic PxQ multiplier */ | ||
225 | //bbox: pool unused | ||
226 | #define pstm_mul_comba_gen(pool, A, B, C, paD, paDlen) \ | ||
227 | pstm_mul_comba_gen( A, B, C, paD, paDlen) | ||
228 | static int32 pstm_mul_comba_gen(psPool_t *pool, pstm_int *A, pstm_int *B, | ||
229 | pstm_int *C, pstm_digit *paD, uint32 paDlen) | ||
230 | { | ||
231 | int16 paDfail, pa; | ||
232 | int32 ix, iy, iz, tx, ty; | ||
233 | pstm_digit c0, c1, c2, *tmpx, *tmpy, *dst; | ||
234 | |||
235 | COMBA_START; | ||
236 | COMBA_CLEAR; | ||
237 | |||
238 | paDfail = 0; | ||
239 | /* get size of output and trim */ | ||
240 | pa = A->used + B->used; | ||
241 | |||
242 | /* | ||
243 | If c is not large enough grow it and continue | ||
244 | */ | ||
245 | if (C->alloc < pa) { | ||
246 | if (pstm_grow(C, pa) != PSTM_OKAY) { | ||
247 | return PS_MEM_FAIL; | ||
248 | } | ||
249 | } | ||
250 | if (paD != NULL) { | ||
251 | if (paDlen < (sizeof(pstm_digit) * pa)) { | ||
252 | paDfail = 1; /* have a paD but it's not large enough */ | ||
253 | dst = xzalloc(sizeof(pstm_digit) * pa);//bbox | ||
254 | } else { | ||
255 | dst = paD; | ||
256 | memset(dst, 0x0, paDlen); | ||
257 | } | ||
258 | } else { | ||
259 | dst = xzalloc(sizeof(pstm_digit) * pa);//bbox | ||
260 | } | ||
261 | |||
262 | for (ix = 0; ix < pa; ix++) { | ||
263 | /* get offsets into the two bignums */ | ||
264 | ty = min(ix, B->used-1); | ||
265 | tx = ix - ty; | ||
266 | |||
267 | /* setup temp aliases */ | ||
268 | tmpx = A->dp + tx; | ||
269 | tmpy = B->dp + ty; | ||
270 | /* | ||
271 | This is the number of times the loop will iterate, essentially it's | ||
272 | while (tx++ < a->used && ty-- >= 0) { ... } | ||
273 | */ | ||
274 | iy = min(A->used-tx, ty+1); | ||
275 | |||
276 | /* execute loop */ | ||
277 | COMBA_FORWARD; | ||
278 | for (iz = 0; iz < iy; ++iz) { | ||
279 | MULADD(*tmpx++, *tmpy--); | ||
280 | } | ||
281 | |||
282 | /* store term */ | ||
283 | COMBA_STORE(dst[ix]); | ||
284 | } | ||
285 | COMBA_FINI; | ||
286 | /* | ||
287 | setup dest | ||
288 | */ | ||
289 | iy = C->used; | ||
290 | C->used = pa; | ||
291 | C->sign = A->sign ^ B->sign; | ||
292 | { | ||
293 | pstm_digit *tmpc; | ||
294 | tmpc = C->dp; | ||
295 | for (ix = 0; ix < pa; ix++) { | ||
296 | *tmpc++ = dst[ix]; | ||
297 | } | ||
298 | /* | ||
299 | clear unused digits [that existed in the old copy of c] | ||
300 | */ | ||
301 | for (; ix < iy; ix++) { | ||
302 | *tmpc++ = 0; | ||
303 | } | ||
304 | } | ||
305 | pstm_clamp(C); | ||
306 | |||
307 | if ((paD == NULL) || (paDfail == 1)) { | ||
308 | psFree(dst, pool); | ||
309 | } | ||
310 | |||
311 | return PS_SUCCESS; | ||
312 | } | ||
313 | |||
314 | /******************************************************************************/ | ||
315 | #ifdef USE_1024_KEY_SPEED_OPTIMIZATIONS | ||
316 | static int32 pstm_mul_comba16(pstm_int *A, pstm_int *B, pstm_int *C) | ||
317 | { | ||
318 | pstm_digit c0, c1, c2, at[32]; | ||
319 | |||
320 | if (C->alloc < 32) { | ||
321 | if (pstm_grow(C, 32) != PSTM_OKAY) { | ||
322 | return PS_MEM_FAIL; | ||
323 | } | ||
324 | } | ||
325 | memcpy(at, A->dp, 16 * sizeof(pstm_digit)); | ||
326 | memcpy(at+16, B->dp, 16 * sizeof(pstm_digit)); | ||
327 | |||
328 | COMBA_START; | ||
329 | |||
330 | COMBA_CLEAR; | ||
331 | /* 0 */ | ||
332 | MULADD(at[0], at[16]); | ||
333 | COMBA_STORE(C->dp[0]); | ||
334 | /* 1 */ | ||
335 | COMBA_FORWARD; | ||
336 | MULADD(at[0], at[17]); MULADD(at[1], at[16]); | ||
337 | COMBA_STORE(C->dp[1]); | ||
338 | /* 2 */ | ||
339 | COMBA_FORWARD; | ||
340 | MULADD(at[0], at[18]); MULADD(at[1], at[17]); MULADD(at[2], at[16]); | ||
341 | COMBA_STORE(C->dp[2]); | ||
342 | /* 3 */ | ||
343 | COMBA_FORWARD; | ||
344 | MULADD(at[0], at[19]); MULADD(at[1], at[18]); MULADD(at[2], at[17]); MULADD(at[3], at[16]); | ||
345 | COMBA_STORE(C->dp[3]); | ||
346 | /* 4 */ | ||
347 | COMBA_FORWARD; | ||
348 | MULADD(at[0], at[20]); MULADD(at[1], at[19]); MULADD(at[2], at[18]); MULADD(at[3], at[17]); MULADD(at[4], at[16]); | ||
349 | COMBA_STORE(C->dp[4]); | ||
350 | /* 5 */ | ||
351 | COMBA_FORWARD; | ||
352 | MULADD(at[0], at[21]); MULADD(at[1], at[20]); MULADD(at[2], at[19]); MULADD(at[3], at[18]); MULADD(at[4], at[17]); MULADD(at[5], at[16]); | ||
353 | COMBA_STORE(C->dp[5]); | ||
354 | /* 6 */ | ||
355 | COMBA_FORWARD; | ||
356 | MULADD(at[0], at[22]); MULADD(at[1], at[21]); MULADD(at[2], at[20]); MULADD(at[3], at[19]); MULADD(at[4], at[18]); MULADD(at[5], at[17]); MULADD(at[6], at[16]); | ||
357 | COMBA_STORE(C->dp[6]); | ||
358 | /* 7 */ | ||
359 | COMBA_FORWARD; | ||
360 | MULADD(at[0], at[23]); MULADD(at[1], at[22]); MULADD(at[2], at[21]); MULADD(at[3], at[20]); MULADD(at[4], at[19]); MULADD(at[5], at[18]); MULADD(at[6], at[17]); MULADD(at[7], at[16]); | ||
361 | COMBA_STORE(C->dp[7]); | ||
362 | /* 8 */ | ||
363 | COMBA_FORWARD; | ||
364 | MULADD(at[0], at[24]); MULADD(at[1], at[23]); MULADD(at[2], at[22]); MULADD(at[3], at[21]); MULADD(at[4], at[20]); MULADD(at[5], at[19]); MULADD(at[6], at[18]); MULADD(at[7], at[17]); MULADD(at[8], at[16]); | ||
365 | COMBA_STORE(C->dp[8]); | ||
366 | /* 9 */ | ||
367 | COMBA_FORWARD; | ||
368 | MULADD(at[0], at[25]); MULADD(at[1], at[24]); MULADD(at[2], at[23]); MULADD(at[3], at[22]); MULADD(at[4], at[21]); MULADD(at[5], at[20]); MULADD(at[6], at[19]); MULADD(at[7], at[18]); MULADD(at[8], at[17]); MULADD(at[9], at[16]); | ||
369 | COMBA_STORE(C->dp[9]); | ||
370 | /* 10 */ | ||
371 | COMBA_FORWARD; | ||
372 | MULADD(at[0], at[26]); MULADD(at[1], at[25]); MULADD(at[2], at[24]); MULADD(at[3], at[23]); MULADD(at[4], at[22]); MULADD(at[5], at[21]); MULADD(at[6], at[20]); MULADD(at[7], at[19]); MULADD(at[8], at[18]); MULADD(at[9], at[17]); MULADD(at[10], at[16]); | ||
373 | COMBA_STORE(C->dp[10]); | ||
374 | /* 11 */ | ||
375 | COMBA_FORWARD; | ||
376 | MULADD(at[0], at[27]); MULADD(at[1], at[26]); MULADD(at[2], at[25]); MULADD(at[3], at[24]); MULADD(at[4], at[23]); MULADD(at[5], at[22]); MULADD(at[6], at[21]); MULADD(at[7], at[20]); MULADD(at[8], at[19]); MULADD(at[9], at[18]); MULADD(at[10], at[17]); MULADD(at[11], at[16]); | ||
377 | COMBA_STORE(C->dp[11]); | ||
378 | /* 12 */ | ||
379 | COMBA_FORWARD; | ||
380 | MULADD(at[0], at[28]); MULADD(at[1], at[27]); MULADD(at[2], at[26]); MULADD(at[3], at[25]); MULADD(at[4], at[24]); MULADD(at[5], at[23]); MULADD(at[6], at[22]); MULADD(at[7], at[21]); MULADD(at[8], at[20]); MULADD(at[9], at[19]); MULADD(at[10], at[18]); MULADD(at[11], at[17]); MULADD(at[12], at[16]); | ||
381 | COMBA_STORE(C->dp[12]); | ||
382 | /* 13 */ | ||
383 | COMBA_FORWARD; | ||
384 | MULADD(at[0], at[29]); MULADD(at[1], at[28]); MULADD(at[2], at[27]); MULADD(at[3], at[26]); MULADD(at[4], at[25]); MULADD(at[5], at[24]); MULADD(at[6], at[23]); MULADD(at[7], at[22]); MULADD(at[8], at[21]); MULADD(at[9], at[20]); MULADD(at[10], at[19]); MULADD(at[11], at[18]); MULADD(at[12], at[17]); MULADD(at[13], at[16]); | ||
385 | COMBA_STORE(C->dp[13]); | ||
386 | /* 14 */ | ||
387 | COMBA_FORWARD; | ||
388 | MULADD(at[0], at[30]); MULADD(at[1], at[29]); MULADD(at[2], at[28]); MULADD(at[3], at[27]); MULADD(at[4], at[26]); MULADD(at[5], at[25]); MULADD(at[6], at[24]); MULADD(at[7], at[23]); MULADD(at[8], at[22]); MULADD(at[9], at[21]); MULADD(at[10], at[20]); MULADD(at[11], at[19]); MULADD(at[12], at[18]); MULADD(at[13], at[17]); MULADD(at[14], at[16]); | ||
389 | COMBA_STORE(C->dp[14]); | ||
390 | /* 15 */ | ||
391 | COMBA_FORWARD; | ||
392 | MULADD(at[0], at[31]); MULADD(at[1], at[30]); MULADD(at[2], at[29]); MULADD(at[3], at[28]); MULADD(at[4], at[27]); MULADD(at[5], at[26]); MULADD(at[6], at[25]); MULADD(at[7], at[24]); MULADD(at[8], at[23]); MULADD(at[9], at[22]); MULADD(at[10], at[21]); MULADD(at[11], at[20]); MULADD(at[12], at[19]); MULADD(at[13], at[18]); MULADD(at[14], at[17]); MULADD(at[15], at[16]); | ||
393 | COMBA_STORE(C->dp[15]); | ||
394 | /* 16 */ | ||
395 | COMBA_FORWARD; | ||
396 | MULADD(at[1], at[31]); MULADD(at[2], at[30]); MULADD(at[3], at[29]); MULADD(at[4], at[28]); MULADD(at[5], at[27]); MULADD(at[6], at[26]); MULADD(at[7], at[25]); MULADD(at[8], at[24]); MULADD(at[9], at[23]); MULADD(at[10], at[22]); MULADD(at[11], at[21]); MULADD(at[12], at[20]); MULADD(at[13], at[19]); MULADD(at[14], at[18]); MULADD(at[15], at[17]); | ||
397 | COMBA_STORE(C->dp[16]); | ||
398 | /* 17 */ | ||
399 | COMBA_FORWARD; | ||
400 | MULADD(at[2], at[31]); MULADD(at[3], at[30]); MULADD(at[4], at[29]); MULADD(at[5], at[28]); MULADD(at[6], at[27]); MULADD(at[7], at[26]); MULADD(at[8], at[25]); MULADD(at[9], at[24]); MULADD(at[10], at[23]); MULADD(at[11], at[22]); MULADD(at[12], at[21]); MULADD(at[13], at[20]); MULADD(at[14], at[19]); MULADD(at[15], at[18]); | ||
401 | COMBA_STORE(C->dp[17]); | ||
402 | /* 18 */ | ||
403 | COMBA_FORWARD; | ||
404 | MULADD(at[3], at[31]); MULADD(at[4], at[30]); MULADD(at[5], at[29]); MULADD(at[6], at[28]); MULADD(at[7], at[27]); MULADD(at[8], at[26]); MULADD(at[9], at[25]); MULADD(at[10], at[24]); MULADD(at[11], at[23]); MULADD(at[12], at[22]); MULADD(at[13], at[21]); MULADD(at[14], at[20]); MULADD(at[15], at[19]); | ||
405 | COMBA_STORE(C->dp[18]); | ||
406 | /* 19 */ | ||
407 | COMBA_FORWARD; | ||
408 | MULADD(at[4], at[31]); MULADD(at[5], at[30]); MULADD(at[6], at[29]); MULADD(at[7], at[28]); MULADD(at[8], at[27]); MULADD(at[9], at[26]); MULADD(at[10], at[25]); MULADD(at[11], at[24]); MULADD(at[12], at[23]); MULADD(at[13], at[22]); MULADD(at[14], at[21]); MULADD(at[15], at[20]); | ||
409 | COMBA_STORE(C->dp[19]); | ||
410 | /* 20 */ | ||
411 | COMBA_FORWARD; | ||
412 | MULADD(at[5], at[31]); MULADD(at[6], at[30]); MULADD(at[7], at[29]); MULADD(at[8], at[28]); MULADD(at[9], at[27]); MULADD(at[10], at[26]); MULADD(at[11], at[25]); MULADD(at[12], at[24]); MULADD(at[13], at[23]); MULADD(at[14], at[22]); MULADD(at[15], at[21]); | ||
413 | COMBA_STORE(C->dp[20]); | ||
414 | /* 21 */ | ||
415 | COMBA_FORWARD; | ||
416 | MULADD(at[6], at[31]); MULADD(at[7], at[30]); MULADD(at[8], at[29]); MULADD(at[9], at[28]); MULADD(at[10], at[27]); MULADD(at[11], at[26]); MULADD(at[12], at[25]); MULADD(at[13], at[24]); MULADD(at[14], at[23]); MULADD(at[15], at[22]); | ||
417 | COMBA_STORE(C->dp[21]); | ||
418 | /* 22 */ | ||
419 | COMBA_FORWARD; | ||
420 | MULADD(at[7], at[31]); MULADD(at[8], at[30]); MULADD(at[9], at[29]); MULADD(at[10], at[28]); MULADD(at[11], at[27]); MULADD(at[12], at[26]); MULADD(at[13], at[25]); MULADD(at[14], at[24]); MULADD(at[15], at[23]); | ||
421 | COMBA_STORE(C->dp[22]); | ||
422 | /* 23 */ | ||
423 | COMBA_FORWARD; | ||
424 | MULADD(at[8], at[31]); MULADD(at[9], at[30]); MULADD(at[10], at[29]); MULADD(at[11], at[28]); MULADD(at[12], at[27]); MULADD(at[13], at[26]); MULADD(at[14], at[25]); MULADD(at[15], at[24]); | ||
425 | COMBA_STORE(C->dp[23]); | ||
426 | /* 24 */ | ||
427 | COMBA_FORWARD; | ||
428 | MULADD(at[9], at[31]); MULADD(at[10], at[30]); MULADD(at[11], at[29]); MULADD(at[12], at[28]); MULADD(at[13], at[27]); MULADD(at[14], at[26]); MULADD(at[15], at[25]); | ||
429 | COMBA_STORE(C->dp[24]); | ||
430 | /* 25 */ | ||
431 | COMBA_FORWARD; | ||
432 | MULADD(at[10], at[31]); MULADD(at[11], at[30]); MULADD(at[12], at[29]); MULADD(at[13], at[28]); MULADD(at[14], at[27]); MULADD(at[15], at[26]); | ||
433 | COMBA_STORE(C->dp[25]); | ||
434 | /* 26 */ | ||
435 | COMBA_FORWARD; | ||
436 | MULADD(at[11], at[31]); MULADD(at[12], at[30]); MULADD(at[13], at[29]); MULADD(at[14], at[28]); MULADD(at[15], at[27]); | ||
437 | COMBA_STORE(C->dp[26]); | ||
438 | /* 27 */ | ||
439 | COMBA_FORWARD; | ||
440 | MULADD(at[12], at[31]); MULADD(at[13], at[30]); MULADD(at[14], at[29]); MULADD(at[15], at[28]); | ||
441 | COMBA_STORE(C->dp[27]); | ||
442 | /* 28 */ | ||
443 | COMBA_FORWARD; | ||
444 | MULADD(at[13], at[31]); MULADD(at[14], at[30]); MULADD(at[15], at[29]); | ||
445 | COMBA_STORE(C->dp[28]); | ||
446 | /* 29 */ | ||
447 | COMBA_FORWARD; | ||
448 | MULADD(at[14], at[31]); MULADD(at[15], at[30]); | ||
449 | COMBA_STORE(C->dp[29]); | ||
450 | /* 30 */ | ||
451 | COMBA_FORWARD; | ||
452 | MULADD(at[15], at[31]); | ||
453 | COMBA_STORE(C->dp[30]); | ||
454 | COMBA_STORE2(C->dp[31]); | ||
455 | C->used = 32; | ||
456 | C->sign = A->sign ^ B->sign; | ||
457 | pstm_clamp(C); | ||
458 | COMBA_FINI; | ||
459 | return PSTM_OKAY; | ||
460 | } | ||
461 | #endif /* USE_1024_KEY_SPEED_OPTIMIZATIONS */ | ||
462 | |||
463 | |||
464 | #ifdef USE_2048_KEY_SPEED_OPTIMIZATIONS | ||
465 | static int32 pstm_mul_comba32(pstm_int *A, pstm_int *B, pstm_int *C) | ||
466 | { | ||
467 | pstm_digit c0, c1, c2, at[64]; | ||
468 | int32 out_size; | ||
469 | |||
470 | if (C->alloc < 64) { | ||
471 | if (pstm_grow(C, 64) != PSTM_OKAY) { | ||
472 | return PS_MEM_FAIL; | ||
473 | } | ||
474 | } | ||
475 | |||
476 | out_size = A->used + B->used; | ||
477 | memcpy(at, A->dp, 32 * sizeof(pstm_digit)); | ||
478 | memcpy(at+32, B->dp, 32 * sizeof(pstm_digit)); | ||
479 | COMBA_START; | ||
480 | |||
481 | COMBA_CLEAR; | ||
482 | /* 0 */ | ||
483 | MULADD(at[0], at[32]); | ||
484 | COMBA_STORE(C->dp[0]); | ||
485 | /* 1 */ | ||
486 | COMBA_FORWARD; | ||
487 | MULADD(at[0], at[33]); MULADD(at[1], at[32]); | ||
488 | COMBA_STORE(C->dp[1]); | ||
489 | /* 2 */ | ||
490 | COMBA_FORWARD; | ||
491 | MULADD(at[0], at[34]); MULADD(at[1], at[33]); MULADD(at[2], at[32]); | ||
492 | COMBA_STORE(C->dp[2]); | ||
493 | /* 3 */ | ||
494 | COMBA_FORWARD; | ||
495 | MULADD(at[0], at[35]); MULADD(at[1], at[34]); MULADD(at[2], at[33]); MULADD(at[3], at[32]); | ||
496 | COMBA_STORE(C->dp[3]); | ||
497 | /* 4 */ | ||
498 | COMBA_FORWARD; | ||
499 | MULADD(at[0], at[36]); MULADD(at[1], at[35]); MULADD(at[2], at[34]); MULADD(at[3], at[33]); MULADD(at[4], at[32]); | ||
500 | COMBA_STORE(C->dp[4]); | ||
501 | /* 5 */ | ||
502 | COMBA_FORWARD; | ||
503 | MULADD(at[0], at[37]); MULADD(at[1], at[36]); MULADD(at[2], at[35]); MULADD(at[3], at[34]); MULADD(at[4], at[33]); MULADD(at[5], at[32]); | ||
504 | COMBA_STORE(C->dp[5]); | ||
505 | /* 6 */ | ||
506 | COMBA_FORWARD; | ||
507 | MULADD(at[0], at[38]); MULADD(at[1], at[37]); MULADD(at[2], at[36]); MULADD(at[3], at[35]); MULADD(at[4], at[34]); MULADD(at[5], at[33]); MULADD(at[6], at[32]); | ||
508 | COMBA_STORE(C->dp[6]); | ||
509 | /* 7 */ | ||
510 | COMBA_FORWARD; | ||
511 | MULADD(at[0], at[39]); MULADD(at[1], at[38]); MULADD(at[2], at[37]); MULADD(at[3], at[36]); MULADD(at[4], at[35]); MULADD(at[5], at[34]); MULADD(at[6], at[33]); MULADD(at[7], at[32]); | ||
512 | COMBA_STORE(C->dp[7]); | ||
513 | /* 8 */ | ||
514 | COMBA_FORWARD; | ||
515 | MULADD(at[0], at[40]); MULADD(at[1], at[39]); MULADD(at[2], at[38]); MULADD(at[3], at[37]); MULADD(at[4], at[36]); MULADD(at[5], at[35]); MULADD(at[6], at[34]); MULADD(at[7], at[33]); MULADD(at[8], at[32]); | ||
516 | COMBA_STORE(C->dp[8]); | ||
517 | /* 9 */ | ||
518 | COMBA_FORWARD; | ||
519 | MULADD(at[0], at[41]); MULADD(at[1], at[40]); MULADD(at[2], at[39]); MULADD(at[3], at[38]); MULADD(at[4], at[37]); MULADD(at[5], at[36]); MULADD(at[6], at[35]); MULADD(at[7], at[34]); MULADD(at[8], at[33]); MULADD(at[9], at[32]); | ||
520 | COMBA_STORE(C->dp[9]); | ||
521 | /* 10 */ | ||
522 | COMBA_FORWARD; | ||
523 | MULADD(at[0], at[42]); MULADD(at[1], at[41]); MULADD(at[2], at[40]); MULADD(at[3], at[39]); MULADD(at[4], at[38]); MULADD(at[5], at[37]); MULADD(at[6], at[36]); MULADD(at[7], at[35]); MULADD(at[8], at[34]); MULADD(at[9], at[33]); MULADD(at[10], at[32]); | ||
524 | COMBA_STORE(C->dp[10]); | ||
525 | /* 11 */ | ||
526 | COMBA_FORWARD; | ||
527 | MULADD(at[0], at[43]); MULADD(at[1], at[42]); MULADD(at[2], at[41]); MULADD(at[3], at[40]); MULADD(at[4], at[39]); MULADD(at[5], at[38]); MULADD(at[6], at[37]); MULADD(at[7], at[36]); MULADD(at[8], at[35]); MULADD(at[9], at[34]); MULADD(at[10], at[33]); MULADD(at[11], at[32]); | ||
528 | COMBA_STORE(C->dp[11]); | ||
529 | /* 12 */ | ||
530 | COMBA_FORWARD; | ||
531 | MULADD(at[0], at[44]); MULADD(at[1], at[43]); MULADD(at[2], at[42]); MULADD(at[3], at[41]); MULADD(at[4], at[40]); MULADD(at[5], at[39]); MULADD(at[6], at[38]); MULADD(at[7], at[37]); MULADD(at[8], at[36]); MULADD(at[9], at[35]); MULADD(at[10], at[34]); MULADD(at[11], at[33]); MULADD(at[12], at[32]); | ||
532 | COMBA_STORE(C->dp[12]); | ||
533 | /* 13 */ | ||
534 | COMBA_FORWARD; | ||
535 | MULADD(at[0], at[45]); MULADD(at[1], at[44]); MULADD(at[2], at[43]); MULADD(at[3], at[42]); MULADD(at[4], at[41]); MULADD(at[5], at[40]); MULADD(at[6], at[39]); MULADD(at[7], at[38]); MULADD(at[8], at[37]); MULADD(at[9], at[36]); MULADD(at[10], at[35]); MULADD(at[11], at[34]); MULADD(at[12], at[33]); MULADD(at[13], at[32]); | ||
536 | COMBA_STORE(C->dp[13]); | ||
537 | /* 14 */ | ||
538 | COMBA_FORWARD; | ||
539 | MULADD(at[0], at[46]); MULADD(at[1], at[45]); MULADD(at[2], at[44]); MULADD(at[3], at[43]); MULADD(at[4], at[42]); MULADD(at[5], at[41]); MULADD(at[6], at[40]); MULADD(at[7], at[39]); MULADD(at[8], at[38]); MULADD(at[9], at[37]); MULADD(at[10], at[36]); MULADD(at[11], at[35]); MULADD(at[12], at[34]); MULADD(at[13], at[33]); MULADD(at[14], at[32]); | ||
540 | COMBA_STORE(C->dp[14]); | ||
541 | /* 15 */ | ||
542 | COMBA_FORWARD; | ||
543 | MULADD(at[0], at[47]); MULADD(at[1], at[46]); MULADD(at[2], at[45]); MULADD(at[3], at[44]); MULADD(at[4], at[43]); MULADD(at[5], at[42]); MULADD(at[6], at[41]); MULADD(at[7], at[40]); MULADD(at[8], at[39]); MULADD(at[9], at[38]); MULADD(at[10], at[37]); MULADD(at[11], at[36]); MULADD(at[12], at[35]); MULADD(at[13], at[34]); MULADD(at[14], at[33]); MULADD(at[15], at[32]); | ||
544 | COMBA_STORE(C->dp[15]); | ||
545 | /* 16 */ | ||
546 | COMBA_FORWARD; | ||
547 | MULADD(at[0], at[48]); MULADD(at[1], at[47]); MULADD(at[2], at[46]); MULADD(at[3], at[45]); MULADD(at[4], at[44]); MULADD(at[5], at[43]); MULADD(at[6], at[42]); MULADD(at[7], at[41]); MULADD(at[8], at[40]); MULADD(at[9], at[39]); MULADD(at[10], at[38]); MULADD(at[11], at[37]); MULADD(at[12], at[36]); MULADD(at[13], at[35]); MULADD(at[14], at[34]); MULADD(at[15], at[33]); MULADD(at[16], at[32]); | ||
548 | COMBA_STORE(C->dp[16]); | ||
549 | /* 17 */ | ||
550 | COMBA_FORWARD; | ||
551 | MULADD(at[0], at[49]); MULADD(at[1], at[48]); MULADD(at[2], at[47]); MULADD(at[3], at[46]); MULADD(at[4], at[45]); MULADD(at[5], at[44]); MULADD(at[6], at[43]); MULADD(at[7], at[42]); MULADD(at[8], at[41]); MULADD(at[9], at[40]); MULADD(at[10], at[39]); MULADD(at[11], at[38]); MULADD(at[12], at[37]); MULADD(at[13], at[36]); MULADD(at[14], at[35]); MULADD(at[15], at[34]); MULADD(at[16], at[33]); MULADD(at[17], at[32]); | ||
552 | COMBA_STORE(C->dp[17]); | ||
553 | /* 18 */ | ||
554 | COMBA_FORWARD; | ||
555 | MULADD(at[0], at[50]); MULADD(at[1], at[49]); MULADD(at[2], at[48]); MULADD(at[3], at[47]); MULADD(at[4], at[46]); MULADD(at[5], at[45]); MULADD(at[6], at[44]); MULADD(at[7], at[43]); MULADD(at[8], at[42]); MULADD(at[9], at[41]); MULADD(at[10], at[40]); MULADD(at[11], at[39]); MULADD(at[12], at[38]); MULADD(at[13], at[37]); MULADD(at[14], at[36]); MULADD(at[15], at[35]); MULADD(at[16], at[34]); MULADD(at[17], at[33]); MULADD(at[18], at[32]); | ||
556 | COMBA_STORE(C->dp[18]); | ||
557 | /* 19 */ | ||
558 | COMBA_FORWARD; | ||
559 | MULADD(at[0], at[51]); MULADD(at[1], at[50]); MULADD(at[2], at[49]); MULADD(at[3], at[48]); MULADD(at[4], at[47]); MULADD(at[5], at[46]); MULADD(at[6], at[45]); MULADD(at[7], at[44]); MULADD(at[8], at[43]); MULADD(at[9], at[42]); MULADD(at[10], at[41]); MULADD(at[11], at[40]); MULADD(at[12], at[39]); MULADD(at[13], at[38]); MULADD(at[14], at[37]); MULADD(at[15], at[36]); MULADD(at[16], at[35]); MULADD(at[17], at[34]); MULADD(at[18], at[33]); MULADD(at[19], at[32]); | ||
560 | COMBA_STORE(C->dp[19]); | ||
561 | /* 20 */ | ||
562 | COMBA_FORWARD; | ||
563 | MULADD(at[0], at[52]); MULADD(at[1], at[51]); MULADD(at[2], at[50]); MULADD(at[3], at[49]); MULADD(at[4], at[48]); MULADD(at[5], at[47]); MULADD(at[6], at[46]); MULADD(at[7], at[45]); MULADD(at[8], at[44]); MULADD(at[9], at[43]); MULADD(at[10], at[42]); MULADD(at[11], at[41]); MULADD(at[12], at[40]); MULADD(at[13], at[39]); MULADD(at[14], at[38]); MULADD(at[15], at[37]); MULADD(at[16], at[36]); MULADD(at[17], at[35]); MULADD(at[18], at[34]); MULADD(at[19], at[33]); MULADD(at[20], at[32]); | ||
564 | COMBA_STORE(C->dp[20]); | ||
565 | /* 21 */ | ||
566 | COMBA_FORWARD; | ||
567 | MULADD(at[0], at[53]); MULADD(at[1], at[52]); MULADD(at[2], at[51]); MULADD(at[3], at[50]); MULADD(at[4], at[49]); MULADD(at[5], at[48]); MULADD(at[6], at[47]); MULADD(at[7], at[46]); MULADD(at[8], at[45]); MULADD(at[9], at[44]); MULADD(at[10], at[43]); MULADD(at[11], at[42]); MULADD(at[12], at[41]); MULADD(at[13], at[40]); MULADD(at[14], at[39]); MULADD(at[15], at[38]); MULADD(at[16], at[37]); MULADD(at[17], at[36]); MULADD(at[18], at[35]); MULADD(at[19], at[34]); MULADD(at[20], at[33]); MULADD(at[21], at[32]); | ||
568 | COMBA_STORE(C->dp[21]); | ||
569 | /* 22 */ | ||
570 | COMBA_FORWARD; | ||
571 | MULADD(at[0], at[54]); MULADD(at[1], at[53]); MULADD(at[2], at[52]); MULADD(at[3], at[51]); MULADD(at[4], at[50]); MULADD(at[5], at[49]); MULADD(at[6], at[48]); MULADD(at[7], at[47]); MULADD(at[8], at[46]); MULADD(at[9], at[45]); MULADD(at[10], at[44]); MULADD(at[11], at[43]); MULADD(at[12], at[42]); MULADD(at[13], at[41]); MULADD(at[14], at[40]); MULADD(at[15], at[39]); MULADD(at[16], at[38]); MULADD(at[17], at[37]); MULADD(at[18], at[36]); MULADD(at[19], at[35]); MULADD(at[20], at[34]); MULADD(at[21], at[33]); MULADD(at[22], at[32]); | ||
572 | COMBA_STORE(C->dp[22]); | ||
573 | /* 23 */ | ||
574 | COMBA_FORWARD; | ||
575 | MULADD(at[0], at[55]); MULADD(at[1], at[54]); MULADD(at[2], at[53]); MULADD(at[3], at[52]); MULADD(at[4], at[51]); MULADD(at[5], at[50]); MULADD(at[6], at[49]); MULADD(at[7], at[48]); MULADD(at[8], at[47]); MULADD(at[9], at[46]); MULADD(at[10], at[45]); MULADD(at[11], at[44]); MULADD(at[12], at[43]); MULADD(at[13], at[42]); MULADD(at[14], at[41]); MULADD(at[15], at[40]); MULADD(at[16], at[39]); MULADD(at[17], at[38]); MULADD(at[18], at[37]); MULADD(at[19], at[36]); MULADD(at[20], at[35]); MULADD(at[21], at[34]); MULADD(at[22], at[33]); MULADD(at[23], at[32]); | ||
576 | COMBA_STORE(C->dp[23]); | ||
577 | /* 24 */ | ||
578 | COMBA_FORWARD; | ||
579 | MULADD(at[0], at[56]); MULADD(at[1], at[55]); MULADD(at[2], at[54]); MULADD(at[3], at[53]); MULADD(at[4], at[52]); MULADD(at[5], at[51]); MULADD(at[6], at[50]); MULADD(at[7], at[49]); MULADD(at[8], at[48]); MULADD(at[9], at[47]); MULADD(at[10], at[46]); MULADD(at[11], at[45]); MULADD(at[12], at[44]); MULADD(at[13], at[43]); MULADD(at[14], at[42]); MULADD(at[15], at[41]); MULADD(at[16], at[40]); MULADD(at[17], at[39]); MULADD(at[18], at[38]); MULADD(at[19], at[37]); MULADD(at[20], at[36]); MULADD(at[21], at[35]); MULADD(at[22], at[34]); MULADD(at[23], at[33]); MULADD(at[24], at[32]); | ||
580 | COMBA_STORE(C->dp[24]); | ||
581 | /* 25 */ | ||
582 | COMBA_FORWARD; | ||
583 | MULADD(at[0], at[57]); MULADD(at[1], at[56]); MULADD(at[2], at[55]); MULADD(at[3], at[54]); MULADD(at[4], at[53]); MULADD(at[5], at[52]); MULADD(at[6], at[51]); MULADD(at[7], at[50]); MULADD(at[8], at[49]); MULADD(at[9], at[48]); MULADD(at[10], at[47]); MULADD(at[11], at[46]); MULADD(at[12], at[45]); MULADD(at[13], at[44]); MULADD(at[14], at[43]); MULADD(at[15], at[42]); MULADD(at[16], at[41]); MULADD(at[17], at[40]); MULADD(at[18], at[39]); MULADD(at[19], at[38]); MULADD(at[20], at[37]); MULADD(at[21], at[36]); MULADD(at[22], at[35]); MULADD(at[23], at[34]); MULADD(at[24], at[33]); MULADD(at[25], at[32]); | ||
584 | COMBA_STORE(C->dp[25]); | ||
585 | /* 26 */ | ||
586 | COMBA_FORWARD; | ||
587 | MULADD(at[0], at[58]); MULADD(at[1], at[57]); MULADD(at[2], at[56]); MULADD(at[3], at[55]); MULADD(at[4], at[54]); MULADD(at[5], at[53]); MULADD(at[6], at[52]); MULADD(at[7], at[51]); MULADD(at[8], at[50]); MULADD(at[9], at[49]); MULADD(at[10], at[48]); MULADD(at[11], at[47]); MULADD(at[12], at[46]); MULADD(at[13], at[45]); MULADD(at[14], at[44]); MULADD(at[15], at[43]); MULADD(at[16], at[42]); MULADD(at[17], at[41]); MULADD(at[18], at[40]); MULADD(at[19], at[39]); MULADD(at[20], at[38]); MULADD(at[21], at[37]); MULADD(at[22], at[36]); MULADD(at[23], at[35]); MULADD(at[24], at[34]); MULADD(at[25], at[33]); MULADD(at[26], at[32]); | ||
588 | COMBA_STORE(C->dp[26]); | ||
589 | /* 27 */ | ||
590 | COMBA_FORWARD; | ||
591 | MULADD(at[0], at[59]); MULADD(at[1], at[58]); MULADD(at[2], at[57]); MULADD(at[3], at[56]); MULADD(at[4], at[55]); MULADD(at[5], at[54]); MULADD(at[6], at[53]); MULADD(at[7], at[52]); MULADD(at[8], at[51]); MULADD(at[9], at[50]); MULADD(at[10], at[49]); MULADD(at[11], at[48]); MULADD(at[12], at[47]); MULADD(at[13], at[46]); MULADD(at[14], at[45]); MULADD(at[15], at[44]); MULADD(at[16], at[43]); MULADD(at[17], at[42]); MULADD(at[18], at[41]); MULADD(at[19], at[40]); MULADD(at[20], at[39]); MULADD(at[21], at[38]); MULADD(at[22], at[37]); MULADD(at[23], at[36]); MULADD(at[24], at[35]); MULADD(at[25], at[34]); MULADD(at[26], at[33]); MULADD(at[27], at[32]); | ||
592 | COMBA_STORE(C->dp[27]); | ||
593 | /* 28 */ | ||
594 | COMBA_FORWARD; | ||
595 | MULADD(at[0], at[60]); MULADD(at[1], at[59]); MULADD(at[2], at[58]); MULADD(at[3], at[57]); MULADD(at[4], at[56]); MULADD(at[5], at[55]); MULADD(at[6], at[54]); MULADD(at[7], at[53]); MULADD(at[8], at[52]); MULADD(at[9], at[51]); MULADD(at[10], at[50]); MULADD(at[11], at[49]); MULADD(at[12], at[48]); MULADD(at[13], at[47]); MULADD(at[14], at[46]); MULADD(at[15], at[45]); MULADD(at[16], at[44]); MULADD(at[17], at[43]); MULADD(at[18], at[42]); MULADD(at[19], at[41]); MULADD(at[20], at[40]); MULADD(at[21], at[39]); MULADD(at[22], at[38]); MULADD(at[23], at[37]); MULADD(at[24], at[36]); MULADD(at[25], at[35]); MULADD(at[26], at[34]); MULADD(at[27], at[33]); MULADD(at[28], at[32]); | ||
596 | COMBA_STORE(C->dp[28]); | ||
597 | /* 29 */ | ||
598 | COMBA_FORWARD; | ||
599 | MULADD(at[0], at[61]); MULADD(at[1], at[60]); MULADD(at[2], at[59]); MULADD(at[3], at[58]); MULADD(at[4], at[57]); MULADD(at[5], at[56]); MULADD(at[6], at[55]); MULADD(at[7], at[54]); MULADD(at[8], at[53]); MULADD(at[9], at[52]); MULADD(at[10], at[51]); MULADD(at[11], at[50]); MULADD(at[12], at[49]); MULADD(at[13], at[48]); MULADD(at[14], at[47]); MULADD(at[15], at[46]); MULADD(at[16], at[45]); MULADD(at[17], at[44]); MULADD(at[18], at[43]); MULADD(at[19], at[42]); MULADD(at[20], at[41]); MULADD(at[21], at[40]); MULADD(at[22], at[39]); MULADD(at[23], at[38]); MULADD(at[24], at[37]); MULADD(at[25], at[36]); MULADD(at[26], at[35]); MULADD(at[27], at[34]); MULADD(at[28], at[33]); MULADD(at[29], at[32]); | ||
600 | COMBA_STORE(C->dp[29]); | ||
601 | /* 30 */ | ||
602 | COMBA_FORWARD; | ||
603 | MULADD(at[0], at[62]); MULADD(at[1], at[61]); MULADD(at[2], at[60]); MULADD(at[3], at[59]); MULADD(at[4], at[58]); MULADD(at[5], at[57]); MULADD(at[6], at[56]); MULADD(at[7], at[55]); MULADD(at[8], at[54]); MULADD(at[9], at[53]); MULADD(at[10], at[52]); MULADD(at[11], at[51]); MULADD(at[12], at[50]); MULADD(at[13], at[49]); MULADD(at[14], at[48]); MULADD(at[15], at[47]); MULADD(at[16], at[46]); MULADD(at[17], at[45]); MULADD(at[18], at[44]); MULADD(at[19], at[43]); MULADD(at[20], at[42]); MULADD(at[21], at[41]); MULADD(at[22], at[40]); MULADD(at[23], at[39]); MULADD(at[24], at[38]); MULADD(at[25], at[37]); MULADD(at[26], at[36]); MULADD(at[27], at[35]); MULADD(at[28], at[34]); MULADD(at[29], at[33]); MULADD(at[30], at[32]); | ||
604 | COMBA_STORE(C->dp[30]); | ||
605 | /* 31 */ | ||
606 | COMBA_FORWARD; | ||
607 | MULADD(at[0], at[63]); MULADD(at[1], at[62]); MULADD(at[2], at[61]); MULADD(at[3], at[60]); MULADD(at[4], at[59]); MULADD(at[5], at[58]); MULADD(at[6], at[57]); MULADD(at[7], at[56]); MULADD(at[8], at[55]); MULADD(at[9], at[54]); MULADD(at[10], at[53]); MULADD(at[11], at[52]); MULADD(at[12], at[51]); MULADD(at[13], at[50]); MULADD(at[14], at[49]); MULADD(at[15], at[48]); MULADD(at[16], at[47]); MULADD(at[17], at[46]); MULADD(at[18], at[45]); MULADD(at[19], at[44]); MULADD(at[20], at[43]); MULADD(at[21], at[42]); MULADD(at[22], at[41]); MULADD(at[23], at[40]); MULADD(at[24], at[39]); MULADD(at[25], at[38]); MULADD(at[26], at[37]); MULADD(at[27], at[36]); MULADD(at[28], at[35]); MULADD(at[29], at[34]); MULADD(at[30], at[33]); MULADD(at[31], at[32]); | ||
608 | COMBA_STORE(C->dp[31]); | ||
609 | /* 32 */ | ||
610 | COMBA_FORWARD; | ||
611 | MULADD(at[1], at[63]); MULADD(at[2], at[62]); MULADD(at[3], at[61]); MULADD(at[4], at[60]); MULADD(at[5], at[59]); MULADD(at[6], at[58]); MULADD(at[7], at[57]); MULADD(at[8], at[56]); MULADD(at[9], at[55]); MULADD(at[10], at[54]); MULADD(at[11], at[53]); MULADD(at[12], at[52]); MULADD(at[13], at[51]); MULADD(at[14], at[50]); MULADD(at[15], at[49]); MULADD(at[16], at[48]); MULADD(at[17], at[47]); MULADD(at[18], at[46]); MULADD(at[19], at[45]); MULADD(at[20], at[44]); MULADD(at[21], at[43]); MULADD(at[22], at[42]); MULADD(at[23], at[41]); MULADD(at[24], at[40]); MULADD(at[25], at[39]); MULADD(at[26], at[38]); MULADD(at[27], at[37]); MULADD(at[28], at[36]); MULADD(at[29], at[35]); MULADD(at[30], at[34]); MULADD(at[31], at[33]); | ||
612 | COMBA_STORE(C->dp[32]); | ||
613 | /* 33 */ | ||
614 | COMBA_FORWARD; | ||
615 | MULADD(at[2], at[63]); MULADD(at[3], at[62]); MULADD(at[4], at[61]); MULADD(at[5], at[60]); MULADD(at[6], at[59]); MULADD(at[7], at[58]); MULADD(at[8], at[57]); MULADD(at[9], at[56]); MULADD(at[10], at[55]); MULADD(at[11], at[54]); MULADD(at[12], at[53]); MULADD(at[13], at[52]); MULADD(at[14], at[51]); MULADD(at[15], at[50]); MULADD(at[16], at[49]); MULADD(at[17], at[48]); MULADD(at[18], at[47]); MULADD(at[19], at[46]); MULADD(at[20], at[45]); MULADD(at[21], at[44]); MULADD(at[22], at[43]); MULADD(at[23], at[42]); MULADD(at[24], at[41]); MULADD(at[25], at[40]); MULADD(at[26], at[39]); MULADD(at[27], at[38]); MULADD(at[28], at[37]); MULADD(at[29], at[36]); MULADD(at[30], at[35]); MULADD(at[31], at[34]); | ||
616 | COMBA_STORE(C->dp[33]); | ||
617 | /* 34 */ | ||
618 | COMBA_FORWARD; | ||
619 | MULADD(at[3], at[63]); MULADD(at[4], at[62]); MULADD(at[5], at[61]); MULADD(at[6], at[60]); MULADD(at[7], at[59]); MULADD(at[8], at[58]); MULADD(at[9], at[57]); MULADD(at[10], at[56]); MULADD(at[11], at[55]); MULADD(at[12], at[54]); MULADD(at[13], at[53]); MULADD(at[14], at[52]); MULADD(at[15], at[51]); MULADD(at[16], at[50]); MULADD(at[17], at[49]); MULADD(at[18], at[48]); MULADD(at[19], at[47]); MULADD(at[20], at[46]); MULADD(at[21], at[45]); MULADD(at[22], at[44]); MULADD(at[23], at[43]); MULADD(at[24], at[42]); MULADD(at[25], at[41]); MULADD(at[26], at[40]); MULADD(at[27], at[39]); MULADD(at[28], at[38]); MULADD(at[29], at[37]); MULADD(at[30], at[36]); MULADD(at[31], at[35]); | ||
620 | COMBA_STORE(C->dp[34]); | ||
621 | /* 35 */ | ||
622 | COMBA_FORWARD; | ||
623 | MULADD(at[4], at[63]); MULADD(at[5], at[62]); MULADD(at[6], at[61]); MULADD(at[7], at[60]); MULADD(at[8], at[59]); MULADD(at[9], at[58]); MULADD(at[10], at[57]); MULADD(at[11], at[56]); MULADD(at[12], at[55]); MULADD(at[13], at[54]); MULADD(at[14], at[53]); MULADD(at[15], at[52]); MULADD(at[16], at[51]); MULADD(at[17], at[50]); MULADD(at[18], at[49]); MULADD(at[19], at[48]); MULADD(at[20], at[47]); MULADD(at[21], at[46]); MULADD(at[22], at[45]); MULADD(at[23], at[44]); MULADD(at[24], at[43]); MULADD(at[25], at[42]); MULADD(at[26], at[41]); MULADD(at[27], at[40]); MULADD(at[28], at[39]); MULADD(at[29], at[38]); MULADD(at[30], at[37]); MULADD(at[31], at[36]); | ||
624 | COMBA_STORE(C->dp[35]); | ||
625 | /* 36 */ | ||
626 | COMBA_FORWARD; | ||
627 | MULADD(at[5], at[63]); MULADD(at[6], at[62]); MULADD(at[7], at[61]); MULADD(at[8], at[60]); MULADD(at[9], at[59]); MULADD(at[10], at[58]); MULADD(at[11], at[57]); MULADD(at[12], at[56]); MULADD(at[13], at[55]); MULADD(at[14], at[54]); MULADD(at[15], at[53]); MULADD(at[16], at[52]); MULADD(at[17], at[51]); MULADD(at[18], at[50]); MULADD(at[19], at[49]); MULADD(at[20], at[48]); MULADD(at[21], at[47]); MULADD(at[22], at[46]); MULADD(at[23], at[45]); MULADD(at[24], at[44]); MULADD(at[25], at[43]); MULADD(at[26], at[42]); MULADD(at[27], at[41]); MULADD(at[28], at[40]); MULADD(at[29], at[39]); MULADD(at[30], at[38]); MULADD(at[31], at[37]); | ||
628 | COMBA_STORE(C->dp[36]); | ||
629 | /* 37 */ | ||
630 | COMBA_FORWARD; | ||
631 | MULADD(at[6], at[63]); MULADD(at[7], at[62]); MULADD(at[8], at[61]); MULADD(at[9], at[60]); MULADD(at[10], at[59]); MULADD(at[11], at[58]); MULADD(at[12], at[57]); MULADD(at[13], at[56]); MULADD(at[14], at[55]); MULADD(at[15], at[54]); MULADD(at[16], at[53]); MULADD(at[17], at[52]); MULADD(at[18], at[51]); MULADD(at[19], at[50]); MULADD(at[20], at[49]); MULADD(at[21], at[48]); MULADD(at[22], at[47]); MULADD(at[23], at[46]); MULADD(at[24], at[45]); MULADD(at[25], at[44]); MULADD(at[26], at[43]); MULADD(at[27], at[42]); MULADD(at[28], at[41]); MULADD(at[29], at[40]); MULADD(at[30], at[39]); MULADD(at[31], at[38]); | ||
632 | COMBA_STORE(C->dp[37]); | ||
633 | /* 38 */ | ||
634 | COMBA_FORWARD; | ||
635 | MULADD(at[7], at[63]); MULADD(at[8], at[62]); MULADD(at[9], at[61]); MULADD(at[10], at[60]); MULADD(at[11], at[59]); MULADD(at[12], at[58]); MULADD(at[13], at[57]); MULADD(at[14], at[56]); MULADD(at[15], at[55]); MULADD(at[16], at[54]); MULADD(at[17], at[53]); MULADD(at[18], at[52]); MULADD(at[19], at[51]); MULADD(at[20], at[50]); MULADD(at[21], at[49]); MULADD(at[22], at[48]); MULADD(at[23], at[47]); MULADD(at[24], at[46]); MULADD(at[25], at[45]); MULADD(at[26], at[44]); MULADD(at[27], at[43]); MULADD(at[28], at[42]); MULADD(at[29], at[41]); MULADD(at[30], at[40]); MULADD(at[31], at[39]); | ||
636 | COMBA_STORE(C->dp[38]); | ||
637 | |||
638 | /* early out at 40 digits, 40*32==1280, or two 640 bit operands */ | ||
639 | if (out_size <= 40) { COMBA_STORE2(C->dp[39]); C->used = 40; C->sign = A->sign ^ B->sign; pstm_clamp(C); COMBA_FINI; return PSTM_OKAY; } | ||
640 | |||
641 | /* 39 */ | ||
642 | COMBA_FORWARD; | ||
643 | MULADD(at[8], at[63]); MULADD(at[9], at[62]); MULADD(at[10], at[61]); MULADD(at[11], at[60]); MULADD(at[12], at[59]); MULADD(at[13], at[58]); MULADD(at[14], at[57]); MULADD(at[15], at[56]); MULADD(at[16], at[55]); MULADD(at[17], at[54]); MULADD(at[18], at[53]); MULADD(at[19], at[52]); MULADD(at[20], at[51]); MULADD(at[21], at[50]); MULADD(at[22], at[49]); MULADD(at[23], at[48]); MULADD(at[24], at[47]); MULADD(at[25], at[46]); MULADD(at[26], at[45]); MULADD(at[27], at[44]); MULADD(at[28], at[43]); MULADD(at[29], at[42]); MULADD(at[30], at[41]); MULADD(at[31], at[40]); | ||
644 | COMBA_STORE(C->dp[39]); | ||
645 | /* 40 */ | ||
646 | COMBA_FORWARD; | ||
647 | MULADD(at[9], at[63]); MULADD(at[10], at[62]); MULADD(at[11], at[61]); MULADD(at[12], at[60]); MULADD(at[13], at[59]); MULADD(at[14], at[58]); MULADD(at[15], at[57]); MULADD(at[16], at[56]); MULADD(at[17], at[55]); MULADD(at[18], at[54]); MULADD(at[19], at[53]); MULADD(at[20], at[52]); MULADD(at[21], at[51]); MULADD(at[22], at[50]); MULADD(at[23], at[49]); MULADD(at[24], at[48]); MULADD(at[25], at[47]); MULADD(at[26], at[46]); MULADD(at[27], at[45]); MULADD(at[28], at[44]); MULADD(at[29], at[43]); MULADD(at[30], at[42]); MULADD(at[31], at[41]); | ||
648 | COMBA_STORE(C->dp[40]); | ||
649 | /* 41 */ | ||
650 | COMBA_FORWARD; | ||
651 | MULADD(at[10], at[63]); MULADD(at[11], at[62]); MULADD(at[12], at[61]); MULADD(at[13], at[60]); MULADD(at[14], at[59]); MULADD(at[15], at[58]); MULADD(at[16], at[57]); MULADD(at[17], at[56]); MULADD(at[18], at[55]); MULADD(at[19], at[54]); MULADD(at[20], at[53]); MULADD(at[21], at[52]); MULADD(at[22], at[51]); MULADD(at[23], at[50]); MULADD(at[24], at[49]); MULADD(at[25], at[48]); MULADD(at[26], at[47]); MULADD(at[27], at[46]); MULADD(at[28], at[45]); MULADD(at[29], at[44]); MULADD(at[30], at[43]); MULADD(at[31], at[42]); | ||
652 | COMBA_STORE(C->dp[41]); | ||
653 | /* 42 */ | ||
654 | COMBA_FORWARD; | ||
655 | MULADD(at[11], at[63]); MULADD(at[12], at[62]); MULADD(at[13], at[61]); MULADD(at[14], at[60]); MULADD(at[15], at[59]); MULADD(at[16], at[58]); MULADD(at[17], at[57]); MULADD(at[18], at[56]); MULADD(at[19], at[55]); MULADD(at[20], at[54]); MULADD(at[21], at[53]); MULADD(at[22], at[52]); MULADD(at[23], at[51]); MULADD(at[24], at[50]); MULADD(at[25], at[49]); MULADD(at[26], at[48]); MULADD(at[27], at[47]); MULADD(at[28], at[46]); MULADD(at[29], at[45]); MULADD(at[30], at[44]); MULADD(at[31], at[43]); | ||
656 | COMBA_STORE(C->dp[42]); | ||
657 | /* 43 */ | ||
658 | COMBA_FORWARD; | ||
659 | MULADD(at[12], at[63]); MULADD(at[13], at[62]); MULADD(at[14], at[61]); MULADD(at[15], at[60]); MULADD(at[16], at[59]); MULADD(at[17], at[58]); MULADD(at[18], at[57]); MULADD(at[19], at[56]); MULADD(at[20], at[55]); MULADD(at[21], at[54]); MULADD(at[22], at[53]); MULADD(at[23], at[52]); MULADD(at[24], at[51]); MULADD(at[25], at[50]); MULADD(at[26], at[49]); MULADD(at[27], at[48]); MULADD(at[28], at[47]); MULADD(at[29], at[46]); MULADD(at[30], at[45]); MULADD(at[31], at[44]); | ||
660 | COMBA_STORE(C->dp[43]); | ||
661 | /* 44 */ | ||
662 | COMBA_FORWARD; | ||
663 | MULADD(at[13], at[63]); MULADD(at[14], at[62]); MULADD(at[15], at[61]); MULADD(at[16], at[60]); MULADD(at[17], at[59]); MULADD(at[18], at[58]); MULADD(at[19], at[57]); MULADD(at[20], at[56]); MULADD(at[21], at[55]); MULADD(at[22], at[54]); MULADD(at[23], at[53]); MULADD(at[24], at[52]); MULADD(at[25], at[51]); MULADD(at[26], at[50]); MULADD(at[27], at[49]); MULADD(at[28], at[48]); MULADD(at[29], at[47]); MULADD(at[30], at[46]); MULADD(at[31], at[45]); | ||
664 | COMBA_STORE(C->dp[44]); | ||
665 | /* 45 */ | ||
666 | COMBA_FORWARD; | ||
667 | MULADD(at[14], at[63]); MULADD(at[15], at[62]); MULADD(at[16], at[61]); MULADD(at[17], at[60]); MULADD(at[18], at[59]); MULADD(at[19], at[58]); MULADD(at[20], at[57]); MULADD(at[21], at[56]); MULADD(at[22], at[55]); MULADD(at[23], at[54]); MULADD(at[24], at[53]); MULADD(at[25], at[52]); MULADD(at[26], at[51]); MULADD(at[27], at[50]); MULADD(at[28], at[49]); MULADD(at[29], at[48]); MULADD(at[30], at[47]); MULADD(at[31], at[46]); | ||
668 | COMBA_STORE(C->dp[45]); | ||
669 | /* 46 */ | ||
670 | COMBA_FORWARD; | ||
671 | MULADD(at[15], at[63]); MULADD(at[16], at[62]); MULADD(at[17], at[61]); MULADD(at[18], at[60]); MULADD(at[19], at[59]); MULADD(at[20], at[58]); MULADD(at[21], at[57]); MULADD(at[22], at[56]); MULADD(at[23], at[55]); MULADD(at[24], at[54]); MULADD(at[25], at[53]); MULADD(at[26], at[52]); MULADD(at[27], at[51]); MULADD(at[28], at[50]); MULADD(at[29], at[49]); MULADD(at[30], at[48]); MULADD(at[31], at[47]); | ||
672 | COMBA_STORE(C->dp[46]); | ||
673 | |||
674 | /* early out at 48 digits, 48*32==1536, or two 768 bit operands */ | ||
675 | if (out_size <= 48) { COMBA_STORE2(C->dp[47]); C->used = 48; C->sign = A->sign ^ B->sign; pstm_clamp(C); COMBA_FINI; return PSTM_OKAY; } | ||
676 | |||
677 | /* 47 */ | ||
678 | COMBA_FORWARD; | ||
679 | MULADD(at[16], at[63]); MULADD(at[17], at[62]); MULADD(at[18], at[61]); MULADD(at[19], at[60]); MULADD(at[20], at[59]); MULADD(at[21], at[58]); MULADD(at[22], at[57]); MULADD(at[23], at[56]); MULADD(at[24], at[55]); MULADD(at[25], at[54]); MULADD(at[26], at[53]); MULADD(at[27], at[52]); MULADD(at[28], at[51]); MULADD(at[29], at[50]); MULADD(at[30], at[49]); MULADD(at[31], at[48]); | ||
680 | COMBA_STORE(C->dp[47]); | ||
681 | /* 48 */ | ||
682 | COMBA_FORWARD; | ||
683 | MULADD(at[17], at[63]); MULADD(at[18], at[62]); MULADD(at[19], at[61]); MULADD(at[20], at[60]); MULADD(at[21], at[59]); MULADD(at[22], at[58]); MULADD(at[23], at[57]); MULADD(at[24], at[56]); MULADD(at[25], at[55]); MULADD(at[26], at[54]); MULADD(at[27], at[53]); MULADD(at[28], at[52]); MULADD(at[29], at[51]); MULADD(at[30], at[50]); MULADD(at[31], at[49]); | ||
684 | COMBA_STORE(C->dp[48]); | ||
685 | /* 49 */ | ||
686 | COMBA_FORWARD; | ||
687 | MULADD(at[18], at[63]); MULADD(at[19], at[62]); MULADD(at[20], at[61]); MULADD(at[21], at[60]); MULADD(at[22], at[59]); MULADD(at[23], at[58]); MULADD(at[24], at[57]); MULADD(at[25], at[56]); MULADD(at[26], at[55]); MULADD(at[27], at[54]); MULADD(at[28], at[53]); MULADD(at[29], at[52]); MULADD(at[30], at[51]); MULADD(at[31], at[50]); | ||
688 | COMBA_STORE(C->dp[49]); | ||
689 | /* 50 */ | ||
690 | COMBA_FORWARD; | ||
691 | MULADD(at[19], at[63]); MULADD(at[20], at[62]); MULADD(at[21], at[61]); MULADD(at[22], at[60]); MULADD(at[23], at[59]); MULADD(at[24], at[58]); MULADD(at[25], at[57]); MULADD(at[26], at[56]); MULADD(at[27], at[55]); MULADD(at[28], at[54]); MULADD(at[29], at[53]); MULADD(at[30], at[52]); MULADD(at[31], at[51]); | ||
692 | COMBA_STORE(C->dp[50]); | ||
693 | /* 51 */ | ||
694 | COMBA_FORWARD; | ||
695 | MULADD(at[20], at[63]); MULADD(at[21], at[62]); MULADD(at[22], at[61]); MULADD(at[23], at[60]); MULADD(at[24], at[59]); MULADD(at[25], at[58]); MULADD(at[26], at[57]); MULADD(at[27], at[56]); MULADD(at[28], at[55]); MULADD(at[29], at[54]); MULADD(at[30], at[53]); MULADD(at[31], at[52]); | ||
696 | COMBA_STORE(C->dp[51]); | ||
697 | /* 52 */ | ||
698 | COMBA_FORWARD; | ||
699 | MULADD(at[21], at[63]); MULADD(at[22], at[62]); MULADD(at[23], at[61]); MULADD(at[24], at[60]); MULADD(at[25], at[59]); MULADD(at[26], at[58]); MULADD(at[27], at[57]); MULADD(at[28], at[56]); MULADD(at[29], at[55]); MULADD(at[30], at[54]); MULADD(at[31], at[53]); | ||
700 | COMBA_STORE(C->dp[52]); | ||
701 | /* 53 */ | ||
702 | COMBA_FORWARD; | ||
703 | MULADD(at[22], at[63]); MULADD(at[23], at[62]); MULADD(at[24], at[61]); MULADD(at[25], at[60]); MULADD(at[26], at[59]); MULADD(at[27], at[58]); MULADD(at[28], at[57]); MULADD(at[29], at[56]); MULADD(at[30], at[55]); MULADD(at[31], at[54]); | ||
704 | COMBA_STORE(C->dp[53]); | ||
705 | /* 54 */ | ||
706 | COMBA_FORWARD; | ||
707 | MULADD(at[23], at[63]); MULADD(at[24], at[62]); MULADD(at[25], at[61]); MULADD(at[26], at[60]); MULADD(at[27], at[59]); MULADD(at[28], at[58]); MULADD(at[29], at[57]); MULADD(at[30], at[56]); MULADD(at[31], at[55]); | ||
708 | COMBA_STORE(C->dp[54]); | ||
709 | |||
710 | /* early out at 56 digits, 56*32==1792, or two 896 bit operands */ | ||
711 | if (out_size <= 56) { COMBA_STORE2(C->dp[55]); C->used = 56; C->sign = A->sign ^ B->sign; pstm_clamp(C); COMBA_FINI; return PSTM_OKAY; } | ||
712 | |||
713 | /* 55 */ | ||
714 | COMBA_FORWARD; | ||
715 | MULADD(at[24], at[63]); MULADD(at[25], at[62]); MULADD(at[26], at[61]); MULADD(at[27], at[60]); MULADD(at[28], at[59]); MULADD(at[29], at[58]); MULADD(at[30], at[57]); MULADD(at[31], at[56]); | ||
716 | COMBA_STORE(C->dp[55]); | ||
717 | /* 56 */ | ||
718 | COMBA_FORWARD; | ||
719 | MULADD(at[25], at[63]); MULADD(at[26], at[62]); MULADD(at[27], at[61]); MULADD(at[28], at[60]); MULADD(at[29], at[59]); MULADD(at[30], at[58]); MULADD(at[31], at[57]); | ||
720 | COMBA_STORE(C->dp[56]); | ||
721 | /* 57 */ | ||
722 | COMBA_FORWARD; | ||
723 | MULADD(at[26], at[63]); MULADD(at[27], at[62]); MULADD(at[28], at[61]); MULADD(at[29], at[60]); MULADD(at[30], at[59]); MULADD(at[31], at[58]); | ||
724 | COMBA_STORE(C->dp[57]); | ||
725 | /* 58 */ | ||
726 | COMBA_FORWARD; | ||
727 | MULADD(at[27], at[63]); MULADD(at[28], at[62]); MULADD(at[29], at[61]); MULADD(at[30], at[60]); MULADD(at[31], at[59]); | ||
728 | COMBA_STORE(C->dp[58]); | ||
729 | /* 59 */ | ||
730 | COMBA_FORWARD; | ||
731 | MULADD(at[28], at[63]); MULADD(at[29], at[62]); MULADD(at[30], at[61]); MULADD(at[31], at[60]); | ||
732 | COMBA_STORE(C->dp[59]); | ||
733 | /* 60 */ | ||
734 | COMBA_FORWARD; | ||
735 | MULADD(at[29], at[63]); MULADD(at[30], at[62]); MULADD(at[31], at[61]); | ||
736 | COMBA_STORE(C->dp[60]); | ||
737 | /* 61 */ | ||
738 | COMBA_FORWARD; | ||
739 | MULADD(at[30], at[63]); MULADD(at[31], at[62]); | ||
740 | COMBA_STORE(C->dp[61]); | ||
741 | /* 62 */ | ||
742 | COMBA_FORWARD; | ||
743 | MULADD(at[31], at[63]); | ||
744 | COMBA_STORE(C->dp[62]); | ||
745 | COMBA_STORE2(C->dp[63]); | ||
746 | C->used = 64; | ||
747 | C->sign = A->sign ^ B->sign; | ||
748 | pstm_clamp(C); | ||
749 | COMBA_FINI; | ||
750 | return PSTM_OKAY; | ||
751 | } | ||
752 | #endif /* USE_2048_KEY_SPEED_OPTIMIZATIONS */ | ||
753 | |||
754 | /******************************************************************************/ | ||
755 | |||
756 | int32 pstm_mul_comba(psPool_t *pool, pstm_int *A, pstm_int *B, pstm_int *C, | ||
757 | pstm_digit *paD, uint32 paDlen) | ||
758 | { | ||
759 | #ifdef USE_1024_KEY_SPEED_OPTIMIZATIONS | ||
760 | if (A->used == 16 && B->used == 16) { | ||
761 | return pstm_mul_comba16(A, B, C); | ||
762 | } else { | ||
763 | #ifdef USE_2048_KEY_SPEED_OPTIMIZATIONS | ||
764 | if (A->used == 32 && B->used == 32) { | ||
765 | return pstm_mul_comba32(A, B, C); | ||
766 | } | ||
767 | #endif /* USE_2048_KEY_SPEED_OPTIMIZATIONS */ | ||
768 | return pstm_mul_comba_gen(pool, A, B, C, paD, paDlen); | ||
769 | } | ||
770 | #else | ||
771 | #ifdef USE_2048_KEY_SPEED_OPTIMIZATIONS | ||
772 | if (A->used == 32 && B->used == 32) { | ||
773 | return pstm_mul_comba32(A, B, C); | ||
774 | } | ||
775 | #endif /* USE_2048_KEY_SPEED_OPTIMIZATIONS */ | ||
776 | return pstm_mul_comba_gen(pool, A, B, C, paD, paDlen); | ||
777 | #endif | ||
778 | } | ||
779 | |||
780 | #endif /* !DISABLE_PSTM */ | ||
781 | /******************************************************************************/ | ||
diff --git a/networking/tls_pstm_sqr_comba.c b/networking/tls_pstm_sqr_comba.c new file mode 100644 index 000000000..36cb9ea97 --- /dev/null +++ b/networking/tls_pstm_sqr_comba.c | |||
@@ -0,0 +1,1111 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2017 Denys Vlasenko | ||
3 | * | ||
4 | * Licensed under GPLv2, see file LICENSE in this source tree. | ||
5 | */ | ||
6 | #include "tls.h" | ||
7 | |||
8 | /* The file is taken almost verbatim from matrixssl-3-7-2b-open/crypto/math/. | ||
9 | * Changes are flagged with //bbox | ||
10 | */ | ||
11 | |||
12 | /** | ||
13 | * @file pstm_sqr_comba.c | ||
14 | * @version 33ef80f (HEAD, tag: MATRIXSSL-3-7-2-OPEN, tag: MATRIXSSL-3-7-2-COMM, origin/master, origin/HEAD, master) | ||
15 | * | ||
16 | * Multiprecision Squaring with Comba technique. | ||
17 | */ | ||
18 | /* | ||
19 | * Copyright (c) 2013-2015 INSIDE Secure Corporation | ||
20 | * Copyright (c) PeerSec Networks, 2002-2011 | ||
21 | * All Rights Reserved | ||
22 | * | ||
23 | * The latest version of this code is available at http://www.matrixssl.org | ||
24 | * | ||
25 | * This software is open source; you can redistribute it and/or modify | ||
26 | * it under the terms of the GNU General Public License as published by | ||
27 | * the Free Software Foundation; either version 2 of the License, or | ||
28 | * (at your option) any later version. | ||
29 | * | ||
30 | * This General Public License does NOT permit incorporating this software | ||
31 | * into proprietary programs. If you are unable to comply with the GPL, a | ||
32 | * commercial license for this software may be purchased from INSIDE at | ||
33 | * http://www.insidesecure.com/eng/Company/Locations | ||
34 | * | ||
35 | * This program is distributed in WITHOUT ANY WARRANTY; without even the | ||
36 | * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. | ||
37 | * See the GNU General Public License for more details. | ||
38 | * | ||
39 | * You should have received a copy of the GNU General Public License | ||
40 | * along with this program; if not, write to the Free Software | ||
41 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
42 | * http://www.gnu.org/copyleft/gpl.html | ||
43 | */ | ||
44 | /******************************************************************************/ | ||
45 | |||
46 | //bbox | ||
47 | //#include "../cryptoApi.h" | ||
48 | #ifndef DISABLE_PSTM | ||
49 | |||
50 | /******************************************************************************/ | ||
51 | #if defined(PSTM_X86) | ||
52 | /* x86-32 optimized for 32 bit platforms. For 64 bit mode use X86_64 instead */ | ||
53 | #if !defined(__GNUC__) || !defined(__i386__) | ||
54 | #error "PSTM_X86 option requires GCC and 32 bit mode x86 processor" | ||
55 | #endif | ||
56 | //#pragma message ("Using 32 bit x86 Assembly Optimizations") | ||
57 | |||
58 | #define COMBA_START | ||
59 | |||
60 | #define CLEAR_CARRY \ | ||
61 | c0 = c1 = c2 = 0; | ||
62 | |||
63 | #define COMBA_STORE(x) \ | ||
64 | x = c0; | ||
65 | |||
66 | #define COMBA_STORE2(x) \ | ||
67 | x = c1; | ||
68 | |||
69 | #define CARRY_FORWARD \ | ||
70 | do { c0 = c1; c1 = c2; c2 = 0; } while (0); | ||
71 | |||
72 | #define COMBA_FINI | ||
73 | |||
74 | #define SQRADD(i, j) \ | ||
75 | asm( \ | ||
76 | "movl %6,%%eax \n\t" \ | ||
77 | "mull %%eax \n\t" \ | ||
78 | "addl %%eax,%0 \n\t" \ | ||
79 | "adcl %%edx,%1 \n\t" \ | ||
80 | "adcl $0,%2 \n\t" \ | ||
81 | :"=r"(c0), "=r"(c1), "=r"(c2): "0"(c0), "1"(c1), "2"(c2), "m"(i) :"%eax","%edx","%cc"); | ||
82 | |||
83 | #define SQRADD2(i, j) \ | ||
84 | asm( \ | ||
85 | "movl %6,%%eax \n\t" \ | ||
86 | "mull %7 \n\t" \ | ||
87 | "addl %%eax,%0 \n\t" \ | ||
88 | "adcl %%edx,%1 \n\t" \ | ||
89 | "adcl $0,%2 \n\t" \ | ||
90 | "addl %%eax,%0 \n\t" \ | ||
91 | "adcl %%edx,%1 \n\t" \ | ||
92 | "adcl $0,%2 \n\t" \ | ||
93 | :"=r"(c0), "=r"(c1), "=r"(c2): "0"(c0), "1"(c1), "2"(c2), "m"(i), "m"(j) :"%eax","%edx","%cc"); | ||
94 | |||
95 | #define SQRADDSC(i, j) \ | ||
96 | asm( \ | ||
97 | "movl %6,%%eax \n\t" \ | ||
98 | "mull %7 \n\t" \ | ||
99 | "movl %%eax,%0 \n\t" \ | ||
100 | "movl %%edx,%1 \n\t" \ | ||
101 | "xorl %2,%2 \n\t" \ | ||
102 | :"=r"(sc0), "=r"(sc1), "=r"(sc2): "0"(sc0), "1"(sc1), "2"(sc2), "g"(i), "g"(j) :"%eax","%edx","%cc"); | ||
103 | |||
104 | #define SQRADDAC(i, j) \ | ||
105 | asm( \ | ||
106 | "movl %6,%%eax \n\t" \ | ||
107 | "mull %7 \n\t" \ | ||
108 | "addl %%eax,%0 \n\t" \ | ||
109 | "adcl %%edx,%1 \n\t" \ | ||
110 | "adcl $0,%2 \n\t" \ | ||
111 | :"=r"(sc0), "=r"(sc1), "=r"(sc2): "0"(sc0), "1"(sc1), "2"(sc2), "g"(i), "g"(j) :"%eax","%edx","%cc"); | ||
112 | |||
113 | #define SQRADDDB \ | ||
114 | asm( \ | ||
115 | "addl %6,%0 \n\t" \ | ||
116 | "adcl %7,%1 \n\t" \ | ||
117 | "adcl %8,%2 \n\t" \ | ||
118 | "addl %6,%0 \n\t" \ | ||
119 | "adcl %7,%1 \n\t" \ | ||
120 | "adcl %8,%2 \n\t" \ | ||
121 | :"=r"(c0), "=r"(c1), "=r"(c2) : "0"(c0), "1"(c1), "2"(c2), "r"(sc0), "r"(sc1), "r"(sc2) : "%cc"); | ||
122 | |||
123 | /******************************************************************************/ | ||
124 | #elif defined(PSTM_X86_64) | ||
125 | /* x86-64 optimized */ | ||
126 | #if !defined(__GNUC__) || !defined(__x86_64__) || !defined(PSTM_64BIT) | ||
127 | #error "PSTM_X86_64 option requires PSTM_64BIT, GCC and 64 bit mode x86 processor" | ||
128 | #endif | ||
129 | //#pragma message ("Using 64 bit x86_64 Assembly Optimizations") | ||
130 | |||
131 | #define COMBA_START | ||
132 | |||
133 | #define CLEAR_CARRY \ | ||
134 | c0 = c1 = c2 = 0; | ||
135 | |||
136 | #define COMBA_STORE(x) \ | ||
137 | x = c0; | ||
138 | |||
139 | #define COMBA_STORE2(x) \ | ||
140 | x = c1; | ||
141 | |||
142 | #define CARRY_FORWARD \ | ||
143 | do { c0 = c1; c1 = c2; c2 = 0; } while (0); | ||
144 | |||
145 | #define COMBA_FINI | ||
146 | |||
147 | #define SQRADD(i, j) \ | ||
148 | asm( \ | ||
149 | "movq %6,%%rax \n\t" \ | ||
150 | "mulq %%rax \n\t" \ | ||
151 | "addq %%rax,%0 \n\t" \ | ||
152 | "adcq %%rdx,%1 \n\t" \ | ||
153 | "adcq $0,%2 \n\t" \ | ||
154 | :"=r"(c0), "=r"(c1), "=r"(c2): "0"(c0), "1"(c1), "2"(c2), "g"(i) :"%rax","%rdx","cc"); | ||
155 | |||
156 | #define SQRADD2(i, j) \ | ||
157 | asm( \ | ||
158 | "movq %6,%%rax \n\t" \ | ||
159 | "mulq %7 \n\t" \ | ||
160 | "addq %%rax,%0 \n\t" \ | ||
161 | "adcq %%rdx,%1 \n\t" \ | ||
162 | "adcq $0,%2 \n\t" \ | ||
163 | "addq %%rax,%0 \n\t" \ | ||
164 | "adcq %%rdx,%1 \n\t" \ | ||
165 | "adcq $0,%2 \n\t" \ | ||
166 | :"=r"(c0), "=r"(c1), "=r"(c2): "0"(c0), "1"(c1), "2"(c2), "g"(i), "g"(j) :"%rax","%rdx","cc"); | ||
167 | |||
168 | #define SQRADDSC(i, j) \ | ||
169 | asm( \ | ||
170 | "movq %6,%%rax \n\t" \ | ||
171 | "mulq %7 \n\t" \ | ||
172 | "movq %%rax,%0 \n\t" \ | ||
173 | "movq %%rdx,%1 \n\t" \ | ||
174 | "xorq %2,%2 \n\t" \ | ||
175 | :"=r"(sc0), "=r"(sc1), "=r"(sc2): "0"(sc0), "1"(sc1), "2"(sc2), "g"(i), "g"(j) :"%rax","%rdx","cc"); | ||
176 | |||
177 | #define SQRADDAC(i, j) \ | ||
178 | asm( \ | ||
179 | "movq %6,%%rax \n\t" \ | ||
180 | "mulq %7 \n\t" \ | ||
181 | "addq %%rax,%0 \n\t" \ | ||
182 | "adcq %%rdx,%1 \n\t" \ | ||
183 | "adcq $0,%2 \n\t" \ | ||
184 | :"=r"(sc0), "=r"(sc1), "=r"(sc2): "0"(sc0), "1"(sc1), "2"(sc2), "g"(i), "g"(j) :"%rax","%rdx","cc"); | ||
185 | |||
186 | #define SQRADDDB \ | ||
187 | asm( \ | ||
188 | "addq %6,%0 \n\t" \ | ||
189 | "adcq %7,%1 \n\t" \ | ||
190 | "adcq %8,%2 \n\t" \ | ||
191 | "addq %6,%0 \n\t" \ | ||
192 | "adcq %7,%1 \n\t" \ | ||
193 | "adcq %8,%2 \n\t" \ | ||
194 | :"=r"(c0), "=r"(c1), "=r"(c2) : "0"(c0), "1"(c1), "2"(c2), "r"(sc0), "r"(sc1), "r"(sc2) : "cc"); | ||
195 | |||
196 | /******************************************************************************/ | ||
197 | #elif defined(PSTM_ARM) | ||
198 | /* ARM code */ | ||
199 | //#pragma message ("Using 32 bit ARM Assembly Optimizations") | ||
200 | |||
201 | #define COMBA_START | ||
202 | |||
203 | #define CLEAR_CARRY \ | ||
204 | c0 = c1 = c2 = 0; | ||
205 | |||
206 | #define COMBA_STORE(x) \ | ||
207 | x = c0; | ||
208 | |||
209 | #define COMBA_STORE2(x) \ | ||
210 | x = c1; | ||
211 | |||
212 | #define CARRY_FORWARD \ | ||
213 | do { c0 = c1; c1 = c2; c2 = 0; } while (0); | ||
214 | |||
215 | #define COMBA_FINI | ||
216 | |||
217 | /* multiplies point i and j, updates carry "c1" and digit c2 */ | ||
218 | #define SQRADD(i, j) \ | ||
219 | asm( \ | ||
220 | " UMULL r0,r1,%6,%6 \n\t" \ | ||
221 | " ADDS %0,%0,r0 \n\t" \ | ||
222 | " ADCS %1,%1,r1 \n\t" \ | ||
223 | " ADC %2,%2,#0 \n\t" \ | ||
224 | :"=r"(c0), "=r"(c1), "=r"(c2) : "0"(c0), "1"(c1), "2"(c2), "r"(i) : "r0", "r1", "%cc"); | ||
225 | |||
226 | /* for squaring some of the terms are doubled... */ | ||
227 | #define SQRADD2(i, j) \ | ||
228 | asm( \ | ||
229 | " UMULL r0,r1,%6,%7 \n\t" \ | ||
230 | " ADDS %0,%0,r0 \n\t" \ | ||
231 | " ADCS %1,%1,r1 \n\t" \ | ||
232 | " ADC %2,%2,#0 \n\t" \ | ||
233 | " ADDS %0,%0,r0 \n\t" \ | ||
234 | " ADCS %1,%1,r1 \n\t" \ | ||
235 | " ADC %2,%2,#0 \n\t" \ | ||
236 | :"=r"(c0), "=r"(c1), "=r"(c2) : "0"(c0), "1"(c1), "2"(c2), "r"(i), "r"(j) : "r0", "r1", "%cc"); | ||
237 | |||
238 | #define SQRADDSC(i, j) \ | ||
239 | asm( \ | ||
240 | " UMULL %0,%1,%6,%7 \n\t" \ | ||
241 | " SUB %2,%2,%2 \n\t" \ | ||
242 | :"=r"(sc0), "=r"(sc1), "=r"(sc2) : "0"(sc0), "1"(sc1), "2"(sc2), "r"(i), "r"(j) : "%cc"); | ||
243 | |||
244 | #define SQRADDAC(i, j) \ | ||
245 | asm( \ | ||
246 | " UMULL r0,r1,%6,%7 \n\t" \ | ||
247 | " ADDS %0,%0,r0 \n\t" \ | ||
248 | " ADCS %1,%1,r1 \n\t" \ | ||
249 | " ADC %2,%2,#0 \n\t" \ | ||
250 | :"=r"(sc0), "=r"(sc1), "=r"(sc2) : "0"(sc0), "1"(sc1), "2"(sc2), "r"(i), "r"(j) : "r0", "r1", "%cc"); | ||
251 | |||
252 | #define SQRADDDB \ | ||
253 | asm( \ | ||
254 | " ADDS %0,%0,%3 \n\t" \ | ||
255 | " ADCS %1,%1,%4 \n\t" \ | ||
256 | " ADC %2,%2,%5 \n\t" \ | ||
257 | " ADDS %0,%0,%3 \n\t" \ | ||
258 | " ADCS %1,%1,%4 \n\t" \ | ||
259 | " ADC %2,%2,%5 \n\t" \ | ||
260 | :"=r"(c0), "=r"(c1), "=r"(c2) : "r"(sc0), "r"(sc1), "r"(sc2), "0"(c0), "1"(c1), "2"(c2) : "%cc"); | ||
261 | |||
262 | /******************************************************************************/ | ||
263 | #elif defined(PSTM_MIPS) | ||
264 | /* MIPS32 */ | ||
265 | //#pragma message ("Using 32 bit MIPS Assembly Optimizations") | ||
266 | |||
267 | #define COMBA_START | ||
268 | |||
269 | #define CLEAR_CARRY \ | ||
270 | c0 = c1 = c2 = 0; | ||
271 | |||
272 | #define COMBA_STORE(x) \ | ||
273 | x = c0; | ||
274 | |||
275 | #define COMBA_STORE2(x) \ | ||
276 | x = c1; | ||
277 | |||
278 | #define CARRY_FORWARD \ | ||
279 | do { c0 = c1; c1 = c2; c2 = 0; } while (0); | ||
280 | |||
281 | #define COMBA_FINI | ||
282 | |||
283 | /* multiplies point i and j, updates carry "c1" and digit c2 */ | ||
284 | #define SQRADD(i, j) \ | ||
285 | asm( \ | ||
286 | " multu %6,%6 \n\t" \ | ||
287 | " mflo $12 \n\t" \ | ||
288 | " mfhi $13 \n\t" \ | ||
289 | " addu %0,%0,$12 \n\t" \ | ||
290 | " sltu $12,%0,$12 \n\t" \ | ||
291 | " addu %1,%1,$13 \n\t" \ | ||
292 | " sltu $13,%1,$13 \n\t" \ | ||
293 | " addu %1,%1,$12 \n\t" \ | ||
294 | " sltu $12,%1,$12 \n\t" \ | ||
295 | " addu %2,%2,$13 \n\t" \ | ||
296 | " addu %2,%2,$12 \n\t" \ | ||
297 | :"=r"(c0), "=r"(c1), "=r"(c2):"0"(c0), "1"(c1), "2"(c2), "r"(i):"$12","$13"); | ||
298 | |||
299 | /* for squaring some of the terms are doubled... */ | ||
300 | #define SQRADD2(i, j) \ | ||
301 | asm( \ | ||
302 | " multu %6,%7 \n\t" \ | ||
303 | " mflo $12 \n\t" \ | ||
304 | " mfhi $13 \n\t" \ | ||
305 | \ | ||
306 | " addu %0,%0,$12 \n\t" \ | ||
307 | " sltu $14,%0,$12 \n\t" \ | ||
308 | " addu %1,%1,$13 \n\t" \ | ||
309 | " sltu $15,%1,$13 \n\t" \ | ||
310 | " addu %1,%1,$14 \n\t" \ | ||
311 | " sltu $14,%1,$14 \n\t" \ | ||
312 | " addu %2,%2,$15 \n\t" \ | ||
313 | " addu %2,%2,$14 \n\t" \ | ||
314 | \ | ||
315 | " addu %0,%0,$12 \n\t" \ | ||
316 | " sltu $14,%0,$12 \n\t" \ | ||
317 | " addu %1,%1,$13 \n\t" \ | ||
318 | " sltu $15,%1,$13 \n\t" \ | ||
319 | " addu %1,%1,$14 \n\t" \ | ||
320 | " sltu $14,%1,$14 \n\t" \ | ||
321 | " addu %2,%2,$15 \n\t" \ | ||
322 | " addu %2,%2,$14 \n\t" \ | ||
323 | :"=r"(c0), "=r"(c1), "=r"(c2):"0"(c0), "1"(c1), "2"(c2), "r"(i), "r"(j):"$12", "$13", "$14", "$15"); | ||
324 | |||
325 | #define SQRADDSC(i, j) \ | ||
326 | asm( \ | ||
327 | " multu %6,%7 \n\t" \ | ||
328 | " mflo %0 \n\t" \ | ||
329 | " mfhi %1 \n\t" \ | ||
330 | " xor %2,%2,%2 \n\t" \ | ||
331 | :"=r"(sc0), "=r"(sc1), "=r"(sc2):"0"(sc0), "1"(sc1), "2"(sc2), "r"(i),"r"(j) : "%cc"); | ||
332 | |||
333 | #define SQRADDAC(i, j) \ | ||
334 | asm( \ | ||
335 | " multu %6,%7 \n\t" \ | ||
336 | " mflo $12 \n\t" \ | ||
337 | " mfhi $13 \n\t" \ | ||
338 | " addu %0,%0,$12 \n\t" \ | ||
339 | " sltu $12,%0,$12 \n\t" \ | ||
340 | " addu %1,%1,$13 \n\t" \ | ||
341 | " sltu $13,%1,$13 \n\t" \ | ||
342 | " addu %1,%1,$12 \n\t" \ | ||
343 | " sltu $12,%1,$12 \n\t" \ | ||
344 | " addu %2,%2,$13 \n\t" \ | ||
345 | " addu %2,%2,$12 \n\t" \ | ||
346 | :"=r"(sc0), "=r"(sc1), "=r"(sc2):"0"(sc0), "1"(sc1), "2"(sc2), "r"(i), "r"(j):"$12", "$13", "$14"); | ||
347 | |||
348 | #define SQRADDDB \ | ||
349 | asm( \ | ||
350 | " addu %0,%0,%3 \n\t" \ | ||
351 | " sltu $10,%0,%3 \n\t" \ | ||
352 | " addu %1,%1,$10 \n\t" \ | ||
353 | " sltu $10,%1,$10 \n\t" \ | ||
354 | " addu %1,%1,%4 \n\t" \ | ||
355 | " sltu $11,%1,%4 \n\t" \ | ||
356 | " addu %2,%2,$10 \n\t" \ | ||
357 | " addu %2,%2,$11 \n\t" \ | ||
358 | " addu %2,%2,%5 \n\t" \ | ||
359 | \ | ||
360 | " addu %0,%0,%3 \n\t" \ | ||
361 | " sltu $10,%0,%3 \n\t" \ | ||
362 | " addu %1,%1,$10 \n\t" \ | ||
363 | " sltu $10,%1,$10 \n\t" \ | ||
364 | " addu %1,%1,%4 \n\t" \ | ||
365 | " sltu $11,%1,%4 \n\t" \ | ||
366 | " addu %2,%2,$10 \n\t" \ | ||
367 | " addu %2,%2,$11 \n\t" \ | ||
368 | " addu %2,%2,%5 \n\t" \ | ||
369 | :"=r"(c0), "=r"(c1), "=r"(c2) : "r"(sc0), "r"(sc1), "r"(sc2), "0"(c0), "1"(c1), "2"(c2) : "$10", "$11"); | ||
370 | |||
371 | #else | ||
372 | /******************************************************************************/ | ||
373 | #define PSTM_ISO | ||
374 | /* ISO C portable code */ | ||
375 | |||
376 | #define COMBA_START | ||
377 | |||
378 | #define CLEAR_CARRY \ | ||
379 | c0 = c1 = c2 = 0; | ||
380 | |||
381 | #define COMBA_STORE(x) \ | ||
382 | x = c0; | ||
383 | |||
384 | #define COMBA_STORE2(x) \ | ||
385 | x = c1; | ||
386 | |||
387 | #define CARRY_FORWARD \ | ||
388 | do { c0 = c1; c1 = c2; c2 = 0; } while (0); | ||
389 | |||
390 | #define COMBA_FINI | ||
391 | |||
392 | /* multiplies point i and j, updates carry "c1" and digit c2 */ | ||
393 | #define SQRADD(i, j) \ | ||
394 | do { pstm_word t; \ | ||
395 | t = c0 + ((pstm_word)i) * ((pstm_word)j); c0 = (pstm_digit)t; \ | ||
396 | t = c1 + (t >> DIGIT_BIT); \ | ||
397 | c1 = (pstm_digit)t; c2 += (pstm_digit)(t >> DIGIT_BIT); \ | ||
398 | } while (0); | ||
399 | |||
400 | |||
401 | /* for squaring some of the terms are doubled... */ | ||
402 | #define SQRADD2(i, j) \ | ||
403 | do { pstm_word t; \ | ||
404 | t = ((pstm_word)i) * ((pstm_word)j); \ | ||
405 | tt = (pstm_word)c0 + t; c0 = (pstm_digit)tt; \ | ||
406 | tt = (pstm_word)c1 + (tt >> DIGIT_BIT); \ | ||
407 | c1 = (pstm_digit)tt; c2 += (pstm_digit)(tt >> DIGIT_BIT); \ | ||
408 | tt = (pstm_word)c0 + t; c0 = (pstm_digit)tt; \ | ||
409 | tt = (pstm_word)c1 + (tt >> DIGIT_BIT); \ | ||
410 | c1 = (pstm_digit)tt; c2 += (pstm_digit)(tt >> DIGIT_BIT); \ | ||
411 | } while (0); | ||
412 | |||
413 | #define SQRADDSC(i, j) \ | ||
414 | do { pstm_word t; \ | ||
415 | t = ((pstm_word)i) * ((pstm_word)j); \ | ||
416 | sc0 = (pstm_digit)t; sc1 = (pstm_digit)(t >> DIGIT_BIT); sc2 = 0; \ | ||
417 | } while (0); | ||
418 | |||
419 | #define SQRADDAC(i, j) \ | ||
420 | do { pstm_word t; \ | ||
421 | t = ((pstm_word)sc0) + ((pstm_word)i) * ((pstm_word)j); \ | ||
422 | sc0 = (pstm_digit)t; \ | ||
423 | t = ((pstm_word)sc1) + (t >> DIGIT_BIT); sc1 = (pstm_digit)t; \ | ||
424 | sc2 += (pstm_digit)(t >> DIGIT_BIT); \ | ||
425 | } while (0); | ||
426 | |||
427 | #define SQRADDDB \ | ||
428 | do { pstm_word t; \ | ||
429 | t = ((pstm_word)sc0) + ((pstm_word)sc0) + ((pstm_word)c0); \ | ||
430 | c0 = (pstm_digit)t; \ | ||
431 | t = ((pstm_word)sc1) + ((pstm_word)sc1) + c1 + (t >> DIGIT_BIT); \ | ||
432 | c1 = (pstm_digit)t; \ | ||
433 | c2 = c2 + sc2 + sc2 + (pstm_digit)(t >> DIGIT_BIT); \ | ||
434 | } while (0); | ||
435 | |||
436 | #endif /* ISO_C */ | ||
437 | |||
438 | /******************************************************************************/ | ||
439 | /* | ||
440 | Non-unrolled comba squarer | ||
441 | */ | ||
442 | //bbox: pool unused | ||
443 | #define pstm_sqr_comba_gen(pool, A, B, paD, paDlen) \ | ||
444 | pstm_sqr_comba_gen( A, B, paD, paDlen) | ||
445 | static int32 pstm_sqr_comba_gen(psPool_t *pool, pstm_int *A, pstm_int *B, | ||
446 | pstm_digit *paD, uint32 paDlen) | ||
447 | { | ||
448 | int16 paDfail, pa; | ||
449 | int32 ix, iz; | ||
450 | pstm_digit c0, c1, c2, *dst; | ||
451 | #ifdef PSTM_ISO | ||
452 | pstm_word tt; | ||
453 | #endif | ||
454 | |||
455 | paDfail = 0; | ||
456 | /* get size of output and trim */ | ||
457 | pa = A->used + A->used; | ||
458 | |||
459 | /* number of output digits to produce */ | ||
460 | COMBA_START; | ||
461 | CLEAR_CARRY; | ||
462 | /* | ||
463 | If b is not large enough grow it and continue | ||
464 | */ | ||
465 | if (B->alloc < pa) { | ||
466 | if (pstm_grow(B, pa) != PSTM_OKAY) { | ||
467 | return PS_MEM_FAIL; | ||
468 | } | ||
469 | } | ||
470 | if (paD != NULL) { | ||
471 | if (paDlen < (sizeof(pstm_digit) * pa)) { | ||
472 | paDfail = 1; /* have a paD, but it's not big enough */ | ||
473 | dst = xzalloc(sizeof(pstm_digit) * pa);//bbox | ||
474 | } else { | ||
475 | dst = paD; | ||
476 | memset(dst, 0x0, paDlen); | ||
477 | } | ||
478 | } else { | ||
479 | dst = xzalloc(sizeof(pstm_digit) * pa);//bbox | ||
480 | } | ||
481 | |||
482 | for (ix = 0; ix < pa; ix++) { | ||
483 | int32 tx, ty, iy; | ||
484 | pstm_digit *tmpy, *tmpx; | ||
485 | |||
486 | /* get offsets into the two bignums */ | ||
487 | ty = min(A->used-1, ix); | ||
488 | tx = ix - ty; | ||
489 | |||
490 | /* setup temp aliases */ | ||
491 | tmpx = A->dp + tx; | ||
492 | tmpy = A->dp + ty; | ||
493 | |||
494 | /* | ||
495 | This is the number of times the loop will iterate, | ||
496 | while (tx++ < a->used && ty-- >= 0) { ... } | ||
497 | */ | ||
498 | iy = min(A->used-tx, ty+1); | ||
499 | |||
500 | /* | ||
501 | now for squaring tx can never equal ty. We halve the distance since | ||
502 | they approach at a rate of 2x and we have to round because odd cases | ||
503 | need to be executed | ||
504 | */ | ||
505 | iy = min(iy, (ty-tx+1)>>1); | ||
506 | |||
507 | /* forward carries */ | ||
508 | CARRY_FORWARD; | ||
509 | |||
510 | /* execute loop */ | ||
511 | for (iz = 0; iz < iy; iz++) { | ||
512 | SQRADD2(*tmpx++, *tmpy--); | ||
513 | } | ||
514 | |||
515 | /* even columns have the square term in them */ | ||
516 | if ((ix&1) == 0) { | ||
517 | SQRADD(A->dp[ix>>1], A->dp[ix>>1]); | ||
518 | } | ||
519 | |||
520 | /* store it */ | ||
521 | COMBA_STORE(dst[ix]); | ||
522 | } | ||
523 | |||
524 | COMBA_FINI; | ||
525 | /* | ||
526 | setup dest | ||
527 | */ | ||
528 | iz = B->used; | ||
529 | B->used = pa; | ||
530 | { | ||
531 | pstm_digit *tmpc; | ||
532 | tmpc = B->dp; | ||
533 | for (ix = 0; ix < pa; ix++) { | ||
534 | *tmpc++ = dst[ix]; | ||
535 | } | ||
536 | /* clear unused digits (that existed in the old copy of c) */ | ||
537 | for (; ix < iz; ix++) { | ||
538 | *tmpc++ = 0; | ||
539 | } | ||
540 | } | ||
541 | pstm_clamp(B); | ||
542 | |||
543 | if ((paD == NULL) || paDfail == 1) { | ||
544 | psFree(dst, pool); | ||
545 | } | ||
546 | return PS_SUCCESS; | ||
547 | } | ||
548 | |||
549 | /******************************************************************************/ | ||
550 | /* | ||
551 | Unrolled Comba loop for 1024 bit keys | ||
552 | */ | ||
553 | #ifdef USE_1024_KEY_SPEED_OPTIMIZATIONS | ||
554 | static int32 pstm_sqr_comba16(pstm_int *A, pstm_int *B) | ||
555 | { | ||
556 | pstm_digit *a, b[32], c0, c1, c2, sc0, sc1, sc2; | ||
557 | #ifdef PSTM_ISO | ||
558 | pstm_word tt; | ||
559 | #endif | ||
560 | |||
561 | if (B->alloc < 32) { | ||
562 | if (pstm_grow(B, 32) != PSTM_OKAY) { | ||
563 | return PS_MEM_FAIL; | ||
564 | } | ||
565 | } | ||
566 | a = A->dp; | ||
567 | sc0 = sc1 = sc2 = 0; | ||
568 | |||
569 | COMBA_START; | ||
570 | |||
571 | /* clear carries */ | ||
572 | CLEAR_CARRY; | ||
573 | |||
574 | /* output 0 */ | ||
575 | SQRADD(a[0],a[0]); | ||
576 | COMBA_STORE(b[0]); | ||
577 | |||
578 | /* output 1 */ | ||
579 | CARRY_FORWARD; | ||
580 | SQRADD2(a[0], a[1]); | ||
581 | COMBA_STORE(b[1]); | ||
582 | |||
583 | /* output 2 */ | ||
584 | CARRY_FORWARD; | ||
585 | SQRADD2(a[0], a[2]); SQRADD(a[1], a[1]); | ||
586 | COMBA_STORE(b[2]); | ||
587 | |||
588 | /* output 3 */ | ||
589 | CARRY_FORWARD; | ||
590 | SQRADD2(a[0], a[3]); SQRADD2(a[1], a[2]); | ||
591 | COMBA_STORE(b[3]); | ||
592 | |||
593 | /* output 4 */ | ||
594 | CARRY_FORWARD; | ||
595 | SQRADD2(a[0], a[4]); SQRADD2(a[1], a[3]); SQRADD(a[2], a[2]); | ||
596 | COMBA_STORE(b[4]); | ||
597 | |||
598 | /* output 5 */ | ||
599 | CARRY_FORWARD; | ||
600 | SQRADDSC(a[0], a[5]); SQRADDAC(a[1], a[4]); SQRADDAC(a[2], a[3]); SQRADDDB; | ||
601 | COMBA_STORE(b[5]); | ||
602 | |||
603 | /* output 6 */ | ||
604 | CARRY_FORWARD; | ||
605 | SQRADDSC(a[0], a[6]); SQRADDAC(a[1], a[5]); SQRADDAC(a[2], a[4]); SQRADDDB; SQRADD(a[3], a[3]); | ||
606 | COMBA_STORE(b[6]); | ||
607 | |||
608 | /* output 7 */ | ||
609 | CARRY_FORWARD; | ||
610 | SQRADDSC(a[0], a[7]); SQRADDAC(a[1], a[6]); SQRADDAC(a[2], a[5]); SQRADDAC(a[3], a[4]); SQRADDDB; | ||
611 | COMBA_STORE(b[7]); | ||
612 | |||
613 | /* output 8 */ | ||
614 | CARRY_FORWARD; | ||
615 | SQRADDSC(a[0], a[8]); SQRADDAC(a[1], a[7]); SQRADDAC(a[2], a[6]); SQRADDAC(a[3], a[5]); SQRADDDB; SQRADD(a[4], a[4]); | ||
616 | COMBA_STORE(b[8]); | ||
617 | |||
618 | /* output 9 */ | ||
619 | CARRY_FORWARD; | ||
620 | SQRADDSC(a[0], a[9]); SQRADDAC(a[1], a[8]); SQRADDAC(a[2], a[7]); SQRADDAC(a[3], a[6]); SQRADDAC(a[4], a[5]); SQRADDDB; | ||
621 | COMBA_STORE(b[9]); | ||
622 | |||
623 | /* output 10 */ | ||
624 | CARRY_FORWARD; | ||
625 | SQRADDSC(a[0], a[10]); SQRADDAC(a[1], a[9]); SQRADDAC(a[2], a[8]); SQRADDAC(a[3], a[7]); SQRADDAC(a[4], a[6]); SQRADDDB; SQRADD(a[5], a[5]); | ||
626 | COMBA_STORE(b[10]); | ||
627 | |||
628 | /* output 11 */ | ||
629 | CARRY_FORWARD; | ||
630 | SQRADDSC(a[0], a[11]); SQRADDAC(a[1], a[10]); SQRADDAC(a[2], a[9]); SQRADDAC(a[3], a[8]); SQRADDAC(a[4], a[7]); SQRADDAC(a[5], a[6]); SQRADDDB; | ||
631 | COMBA_STORE(b[11]); | ||
632 | |||
633 | /* output 12 */ | ||
634 | CARRY_FORWARD; | ||
635 | SQRADDSC(a[0], a[12]); SQRADDAC(a[1], a[11]); SQRADDAC(a[2], a[10]); SQRADDAC(a[3], a[9]); SQRADDAC(a[4], a[8]); SQRADDAC(a[5], a[7]); SQRADDDB; SQRADD(a[6], a[6]); | ||
636 | COMBA_STORE(b[12]); | ||
637 | |||
638 | /* output 13 */ | ||
639 | CARRY_FORWARD; | ||
640 | SQRADDSC(a[0], a[13]); SQRADDAC(a[1], a[12]); SQRADDAC(a[2], a[11]); SQRADDAC(a[3], a[10]); SQRADDAC(a[4], a[9]); SQRADDAC(a[5], a[8]); SQRADDAC(a[6], a[7]); SQRADDDB; | ||
641 | COMBA_STORE(b[13]); | ||
642 | |||
643 | /* output 14 */ | ||
644 | CARRY_FORWARD; | ||
645 | SQRADDSC(a[0], a[14]); SQRADDAC(a[1], a[13]); SQRADDAC(a[2], a[12]); SQRADDAC(a[3], a[11]); SQRADDAC(a[4], a[10]); SQRADDAC(a[5], a[9]); SQRADDAC(a[6], a[8]); SQRADDDB; SQRADD(a[7], a[7]); | ||
646 | COMBA_STORE(b[14]); | ||
647 | |||
648 | /* output 15 */ | ||
649 | CARRY_FORWARD; | ||
650 | SQRADDSC(a[0], a[15]); SQRADDAC(a[1], a[14]); SQRADDAC(a[2], a[13]); SQRADDAC(a[3], a[12]); SQRADDAC(a[4], a[11]); SQRADDAC(a[5], a[10]); SQRADDAC(a[6], a[9]); SQRADDAC(a[7], a[8]); SQRADDDB; | ||
651 | COMBA_STORE(b[15]); | ||
652 | |||
653 | /* output 16 */ | ||
654 | CARRY_FORWARD; | ||
655 | SQRADDSC(a[1], a[15]); SQRADDAC(a[2], a[14]); SQRADDAC(a[3], a[13]); SQRADDAC(a[4], a[12]); SQRADDAC(a[5], a[11]); SQRADDAC(a[6], a[10]); SQRADDAC(a[7], a[9]); SQRADDDB; SQRADD(a[8], a[8]); | ||
656 | COMBA_STORE(b[16]); | ||
657 | |||
658 | /* output 17 */ | ||
659 | CARRY_FORWARD; | ||
660 | SQRADDSC(a[2], a[15]); SQRADDAC(a[3], a[14]); SQRADDAC(a[4], a[13]); SQRADDAC(a[5], a[12]); SQRADDAC(a[6], a[11]); SQRADDAC(a[7], a[10]); SQRADDAC(a[8], a[9]); SQRADDDB; | ||
661 | COMBA_STORE(b[17]); | ||
662 | |||
663 | /* output 18 */ | ||
664 | CARRY_FORWARD; | ||
665 | SQRADDSC(a[3], a[15]); SQRADDAC(a[4], a[14]); SQRADDAC(a[5], a[13]); SQRADDAC(a[6], a[12]); SQRADDAC(a[7], a[11]); SQRADDAC(a[8], a[10]); SQRADDDB; SQRADD(a[9], a[9]); | ||
666 | COMBA_STORE(b[18]); | ||
667 | |||
668 | /* output 19 */ | ||
669 | CARRY_FORWARD; | ||
670 | SQRADDSC(a[4], a[15]); SQRADDAC(a[5], a[14]); SQRADDAC(a[6], a[13]); SQRADDAC(a[7], a[12]); SQRADDAC(a[8], a[11]); SQRADDAC(a[9], a[10]); SQRADDDB; | ||
671 | COMBA_STORE(b[19]); | ||
672 | |||
673 | /* output 20 */ | ||
674 | CARRY_FORWARD; | ||
675 | SQRADDSC(a[5], a[15]); SQRADDAC(a[6], a[14]); SQRADDAC(a[7], a[13]); SQRADDAC(a[8], a[12]); SQRADDAC(a[9], a[11]); SQRADDDB; SQRADD(a[10], a[10]); | ||
676 | COMBA_STORE(b[20]); | ||
677 | |||
678 | /* output 21 */ | ||
679 | CARRY_FORWARD; | ||
680 | SQRADDSC(a[6], a[15]); SQRADDAC(a[7], a[14]); SQRADDAC(a[8], a[13]); SQRADDAC(a[9], a[12]); SQRADDAC(a[10], a[11]); SQRADDDB; | ||
681 | COMBA_STORE(b[21]); | ||
682 | |||
683 | /* output 22 */ | ||
684 | CARRY_FORWARD; | ||
685 | SQRADDSC(a[7], a[15]); SQRADDAC(a[8], a[14]); SQRADDAC(a[9], a[13]); SQRADDAC(a[10], a[12]); SQRADDDB; SQRADD(a[11], a[11]); | ||
686 | COMBA_STORE(b[22]); | ||
687 | |||
688 | /* output 23 */ | ||
689 | CARRY_FORWARD; | ||
690 | SQRADDSC(a[8], a[15]); SQRADDAC(a[9], a[14]); SQRADDAC(a[10], a[13]); SQRADDAC(a[11], a[12]); SQRADDDB; | ||
691 | COMBA_STORE(b[23]); | ||
692 | |||
693 | /* output 24 */ | ||
694 | CARRY_FORWARD; | ||
695 | SQRADDSC(a[9], a[15]); SQRADDAC(a[10], a[14]); SQRADDAC(a[11], a[13]); SQRADDDB; SQRADD(a[12], a[12]); | ||
696 | COMBA_STORE(b[24]); | ||
697 | |||
698 | /* output 25 */ | ||
699 | CARRY_FORWARD; | ||
700 | SQRADDSC(a[10], a[15]); SQRADDAC(a[11], a[14]); SQRADDAC(a[12], a[13]); SQRADDDB; | ||
701 | COMBA_STORE(b[25]); | ||
702 | |||
703 | /* output 26 */ | ||
704 | CARRY_FORWARD; | ||
705 | SQRADD2(a[11], a[15]); SQRADD2(a[12], a[14]); SQRADD(a[13], a[13]); | ||
706 | COMBA_STORE(b[26]); | ||
707 | |||
708 | /* output 27 */ | ||
709 | CARRY_FORWARD; | ||
710 | SQRADD2(a[12], a[15]); SQRADD2(a[13], a[14]); | ||
711 | COMBA_STORE(b[27]); | ||
712 | |||
713 | /* output 28 */ | ||
714 | CARRY_FORWARD; | ||
715 | SQRADD2(a[13], a[15]); SQRADD(a[14], a[14]); | ||
716 | COMBA_STORE(b[28]); | ||
717 | |||
718 | /* output 29 */ | ||
719 | CARRY_FORWARD; | ||
720 | SQRADD2(a[14], a[15]); | ||
721 | COMBA_STORE(b[29]); | ||
722 | |||
723 | /* output 30 */ | ||
724 | CARRY_FORWARD; | ||
725 | SQRADD(a[15], a[15]); | ||
726 | COMBA_STORE(b[30]); | ||
727 | COMBA_STORE2(b[31]); | ||
728 | COMBA_FINI; | ||
729 | |||
730 | B->used = 32; | ||
731 | B->sign = PSTM_ZPOS; | ||
732 | memcpy(B->dp, b, 32 * sizeof(pstm_digit)); | ||
733 | pstm_clamp(B); | ||
734 | return PSTM_OKAY; | ||
735 | } | ||
736 | #endif /* USE_1024_KEY_SPEED_OPTIMIZATIONS */ | ||
737 | |||
738 | |||
739 | #ifdef USE_2048_KEY_SPEED_OPTIMIZATIONS | ||
740 | static int32 pstm_sqr_comba32(pstm_int *A, pstm_int *B) | ||
741 | { | ||
742 | pstm_digit *a, b[64], c0, c1, c2, sc0, sc1, sc2; | ||
743 | #ifdef PSTM_ISO | ||
744 | pstm_word tt; | ||
745 | #endif | ||
746 | |||
747 | if (B->alloc < 64) { | ||
748 | if (pstm_grow(B, 64) != PSTM_OKAY) { | ||
749 | return PS_MEM_FAIL; | ||
750 | } | ||
751 | } | ||
752 | sc0 = sc1 = sc2 = 0; | ||
753 | a = A->dp; | ||
754 | COMBA_START; | ||
755 | |||
756 | /* clear carries */ | ||
757 | CLEAR_CARRY; | ||
758 | |||
759 | /* output 0 */ | ||
760 | SQRADD(a[0],a[0]); | ||
761 | COMBA_STORE(b[0]); | ||
762 | |||
763 | /* output 1 */ | ||
764 | CARRY_FORWARD; | ||
765 | SQRADD2(a[0], a[1]); | ||
766 | COMBA_STORE(b[1]); | ||
767 | |||
768 | /* output 2 */ | ||
769 | CARRY_FORWARD; | ||
770 | SQRADD2(a[0], a[2]); SQRADD(a[1], a[1]); | ||
771 | COMBA_STORE(b[2]); | ||
772 | |||
773 | /* output 3 */ | ||
774 | CARRY_FORWARD; | ||
775 | SQRADD2(a[0], a[3]); SQRADD2(a[1], a[2]); | ||
776 | COMBA_STORE(b[3]); | ||
777 | |||
778 | /* output 4 */ | ||
779 | CARRY_FORWARD; | ||
780 | SQRADD2(a[0], a[4]); SQRADD2(a[1], a[3]); SQRADD(a[2], a[2]); | ||
781 | COMBA_STORE(b[4]); | ||
782 | |||
783 | /* output 5 */ | ||
784 | CARRY_FORWARD; | ||
785 | SQRADDSC(a[0], a[5]); SQRADDAC(a[1], a[4]); SQRADDAC(a[2], a[3]); SQRADDDB; | ||
786 | COMBA_STORE(b[5]); | ||
787 | |||
788 | /* output 6 */ | ||
789 | CARRY_FORWARD; | ||
790 | SQRADDSC(a[0], a[6]); SQRADDAC(a[1], a[5]); SQRADDAC(a[2], a[4]); SQRADDDB; SQRADD(a[3], a[3]); | ||
791 | COMBA_STORE(b[6]); | ||
792 | |||
793 | /* output 7 */ | ||
794 | CARRY_FORWARD; | ||
795 | SQRADDSC(a[0], a[7]); SQRADDAC(a[1], a[6]); SQRADDAC(a[2], a[5]); SQRADDAC(a[3], a[4]); SQRADDDB; | ||
796 | COMBA_STORE(b[7]); | ||
797 | |||
798 | /* output 8 */ | ||
799 | CARRY_FORWARD; | ||
800 | SQRADDSC(a[0], a[8]); SQRADDAC(a[1], a[7]); SQRADDAC(a[2], a[6]); SQRADDAC(a[3], a[5]); SQRADDDB; SQRADD(a[4], a[4]); | ||
801 | COMBA_STORE(b[8]); | ||
802 | |||
803 | /* output 9 */ | ||
804 | CARRY_FORWARD; | ||
805 | SQRADDSC(a[0], a[9]); SQRADDAC(a[1], a[8]); SQRADDAC(a[2], a[7]); SQRADDAC(a[3], a[6]); SQRADDAC(a[4], a[5]); SQRADDDB; | ||
806 | COMBA_STORE(b[9]); | ||
807 | |||
808 | /* output 10 */ | ||
809 | CARRY_FORWARD; | ||
810 | SQRADDSC(a[0], a[10]); SQRADDAC(a[1], a[9]); SQRADDAC(a[2], a[8]); SQRADDAC(a[3], a[7]); SQRADDAC(a[4], a[6]); SQRADDDB; SQRADD(a[5], a[5]); | ||
811 | COMBA_STORE(b[10]); | ||
812 | |||
813 | /* output 11 */ | ||
814 | CARRY_FORWARD; | ||
815 | SQRADDSC(a[0], a[11]); SQRADDAC(a[1], a[10]); SQRADDAC(a[2], a[9]); SQRADDAC(a[3], a[8]); SQRADDAC(a[4], a[7]); SQRADDAC(a[5], a[6]); SQRADDDB; | ||
816 | COMBA_STORE(b[11]); | ||
817 | |||
818 | /* output 12 */ | ||
819 | CARRY_FORWARD; | ||
820 | SQRADDSC(a[0], a[12]); SQRADDAC(a[1], a[11]); SQRADDAC(a[2], a[10]); SQRADDAC(a[3], a[9]); SQRADDAC(a[4], a[8]); SQRADDAC(a[5], a[7]); SQRADDDB; SQRADD(a[6], a[6]); | ||
821 | COMBA_STORE(b[12]); | ||
822 | |||
823 | /* output 13 */ | ||
824 | CARRY_FORWARD; | ||
825 | SQRADDSC(a[0], a[13]); SQRADDAC(a[1], a[12]); SQRADDAC(a[2], a[11]); SQRADDAC(a[3], a[10]); SQRADDAC(a[4], a[9]); SQRADDAC(a[5], a[8]); SQRADDAC(a[6], a[7]); SQRADDDB; | ||
826 | COMBA_STORE(b[13]); | ||
827 | |||
828 | /* output 14 */ | ||
829 | CARRY_FORWARD; | ||
830 | SQRADDSC(a[0], a[14]); SQRADDAC(a[1], a[13]); SQRADDAC(a[2], a[12]); SQRADDAC(a[3], a[11]); SQRADDAC(a[4], a[10]); SQRADDAC(a[5], a[9]); SQRADDAC(a[6], a[8]); SQRADDDB; SQRADD(a[7], a[7]); | ||
831 | COMBA_STORE(b[14]); | ||
832 | |||
833 | /* output 15 */ | ||
834 | CARRY_FORWARD; | ||
835 | SQRADDSC(a[0], a[15]); SQRADDAC(a[1], a[14]); SQRADDAC(a[2], a[13]); SQRADDAC(a[3], a[12]); SQRADDAC(a[4], a[11]); SQRADDAC(a[5], a[10]); SQRADDAC(a[6], a[9]); SQRADDAC(a[7], a[8]); SQRADDDB; | ||
836 | COMBA_STORE(b[15]); | ||
837 | |||
838 | /* output 16 */ | ||
839 | CARRY_FORWARD; | ||
840 | SQRADDSC(a[0], a[16]); SQRADDAC(a[1], a[15]); SQRADDAC(a[2], a[14]); SQRADDAC(a[3], a[13]); SQRADDAC(a[4], a[12]); SQRADDAC(a[5], a[11]); SQRADDAC(a[6], a[10]); SQRADDAC(a[7], a[9]); SQRADDDB; SQRADD(a[8], a[8]); | ||
841 | COMBA_STORE(b[16]); | ||
842 | |||
843 | /* output 17 */ | ||
844 | CARRY_FORWARD; | ||
845 | SQRADDSC(a[0], a[17]); SQRADDAC(a[1], a[16]); SQRADDAC(a[2], a[15]); SQRADDAC(a[3], a[14]); SQRADDAC(a[4], a[13]); SQRADDAC(a[5], a[12]); SQRADDAC(a[6], a[11]); SQRADDAC(a[7], a[10]); SQRADDAC(a[8], a[9]); SQRADDDB; | ||
846 | COMBA_STORE(b[17]); | ||
847 | |||
848 | /* output 18 */ | ||
849 | CARRY_FORWARD; | ||
850 | SQRADDSC(a[0], a[18]); SQRADDAC(a[1], a[17]); SQRADDAC(a[2], a[16]); SQRADDAC(a[3], a[15]); SQRADDAC(a[4], a[14]); SQRADDAC(a[5], a[13]); SQRADDAC(a[6], a[12]); SQRADDAC(a[7], a[11]); SQRADDAC(a[8], a[10]); SQRADDDB; SQRADD(a[9], a[9]); | ||
851 | COMBA_STORE(b[18]); | ||
852 | |||
853 | /* output 19 */ | ||
854 | CARRY_FORWARD; | ||
855 | SQRADDSC(a[0], a[19]); SQRADDAC(a[1], a[18]); SQRADDAC(a[2], a[17]); SQRADDAC(a[3], a[16]); SQRADDAC(a[4], a[15]); SQRADDAC(a[5], a[14]); SQRADDAC(a[6], a[13]); SQRADDAC(a[7], a[12]); SQRADDAC(a[8], a[11]); SQRADDAC(a[9], a[10]); SQRADDDB; | ||
856 | COMBA_STORE(b[19]); | ||
857 | |||
858 | /* output 20 */ | ||
859 | CARRY_FORWARD; | ||
860 | SQRADDSC(a[0], a[20]); SQRADDAC(a[1], a[19]); SQRADDAC(a[2], a[18]); SQRADDAC(a[3], a[17]); SQRADDAC(a[4], a[16]); SQRADDAC(a[5], a[15]); SQRADDAC(a[6], a[14]); SQRADDAC(a[7], a[13]); SQRADDAC(a[8], a[12]); SQRADDAC(a[9], a[11]); SQRADDDB; SQRADD(a[10], a[10]); | ||
861 | COMBA_STORE(b[20]); | ||
862 | |||
863 | /* output 21 */ | ||
864 | CARRY_FORWARD; | ||
865 | SQRADDSC(a[0], a[21]); SQRADDAC(a[1], a[20]); SQRADDAC(a[2], a[19]); SQRADDAC(a[3], a[18]); SQRADDAC(a[4], a[17]); SQRADDAC(a[5], a[16]); SQRADDAC(a[6], a[15]); SQRADDAC(a[7], a[14]); SQRADDAC(a[8], a[13]); SQRADDAC(a[9], a[12]); SQRADDAC(a[10], a[11]); SQRADDDB; | ||
866 | COMBA_STORE(b[21]); | ||
867 | |||
868 | /* output 22 */ | ||
869 | CARRY_FORWARD; | ||
870 | SQRADDSC(a[0], a[22]); SQRADDAC(a[1], a[21]); SQRADDAC(a[2], a[20]); SQRADDAC(a[3], a[19]); SQRADDAC(a[4], a[18]); SQRADDAC(a[5], a[17]); SQRADDAC(a[6], a[16]); SQRADDAC(a[7], a[15]); SQRADDAC(a[8], a[14]); SQRADDAC(a[9], a[13]); SQRADDAC(a[10], a[12]); SQRADDDB; SQRADD(a[11], a[11]); | ||
871 | COMBA_STORE(b[22]); | ||
872 | |||
873 | /* output 23 */ | ||
874 | CARRY_FORWARD; | ||
875 | SQRADDSC(a[0], a[23]); SQRADDAC(a[1], a[22]); SQRADDAC(a[2], a[21]); SQRADDAC(a[3], a[20]); SQRADDAC(a[4], a[19]); SQRADDAC(a[5], a[18]); SQRADDAC(a[6], a[17]); SQRADDAC(a[7], a[16]); SQRADDAC(a[8], a[15]); SQRADDAC(a[9], a[14]); SQRADDAC(a[10], a[13]); SQRADDAC(a[11], a[12]); SQRADDDB; | ||
876 | COMBA_STORE(b[23]); | ||
877 | |||
878 | /* output 24 */ | ||
879 | CARRY_FORWARD; | ||
880 | SQRADDSC(a[0], a[24]); SQRADDAC(a[1], a[23]); SQRADDAC(a[2], a[22]); SQRADDAC(a[3], a[21]); SQRADDAC(a[4], a[20]); SQRADDAC(a[5], a[19]); SQRADDAC(a[6], a[18]); SQRADDAC(a[7], a[17]); SQRADDAC(a[8], a[16]); SQRADDAC(a[9], a[15]); SQRADDAC(a[10], a[14]); SQRADDAC(a[11], a[13]); SQRADDDB; SQRADD(a[12], a[12]); | ||
881 | COMBA_STORE(b[24]); | ||
882 | |||
883 | /* output 25 */ | ||
884 | CARRY_FORWARD; | ||
885 | SQRADDSC(a[0], a[25]); SQRADDAC(a[1], a[24]); SQRADDAC(a[2], a[23]); SQRADDAC(a[3], a[22]); SQRADDAC(a[4], a[21]); SQRADDAC(a[5], a[20]); SQRADDAC(a[6], a[19]); SQRADDAC(a[7], a[18]); SQRADDAC(a[8], a[17]); SQRADDAC(a[9], a[16]); SQRADDAC(a[10], a[15]); SQRADDAC(a[11], a[14]); SQRADDAC(a[12], a[13]); SQRADDDB; | ||
886 | COMBA_STORE(b[25]); | ||
887 | |||
888 | /* output 26 */ | ||
889 | CARRY_FORWARD; | ||
890 | SQRADDSC(a[0], a[26]); SQRADDAC(a[1], a[25]); SQRADDAC(a[2], a[24]); SQRADDAC(a[3], a[23]); SQRADDAC(a[4], a[22]); SQRADDAC(a[5], a[21]); SQRADDAC(a[6], a[20]); SQRADDAC(a[7], a[19]); SQRADDAC(a[8], a[18]); SQRADDAC(a[9], a[17]); SQRADDAC(a[10], a[16]); SQRADDAC(a[11], a[15]); SQRADDAC(a[12], a[14]); SQRADDDB; SQRADD(a[13], a[13]); | ||
891 | COMBA_STORE(b[26]); | ||
892 | |||
893 | /* output 27 */ | ||
894 | CARRY_FORWARD; | ||
895 | SQRADDSC(a[0], a[27]); SQRADDAC(a[1], a[26]); SQRADDAC(a[2], a[25]); SQRADDAC(a[3], a[24]); SQRADDAC(a[4], a[23]); SQRADDAC(a[5], a[22]); SQRADDAC(a[6], a[21]); SQRADDAC(a[7], a[20]); SQRADDAC(a[8], a[19]); SQRADDAC(a[9], a[18]); SQRADDAC(a[10], a[17]); SQRADDAC(a[11], a[16]); SQRADDAC(a[12], a[15]); SQRADDAC(a[13], a[14]); SQRADDDB; | ||
896 | COMBA_STORE(b[27]); | ||
897 | |||
898 | /* output 28 */ | ||
899 | CARRY_FORWARD; | ||
900 | SQRADDSC(a[0], a[28]); SQRADDAC(a[1], a[27]); SQRADDAC(a[2], a[26]); SQRADDAC(a[3], a[25]); SQRADDAC(a[4], a[24]); SQRADDAC(a[5], a[23]); SQRADDAC(a[6], a[22]); SQRADDAC(a[7], a[21]); SQRADDAC(a[8], a[20]); SQRADDAC(a[9], a[19]); SQRADDAC(a[10], a[18]); SQRADDAC(a[11], a[17]); SQRADDAC(a[12], a[16]); SQRADDAC(a[13], a[15]); SQRADDDB; SQRADD(a[14], a[14]); | ||
901 | COMBA_STORE(b[28]); | ||
902 | |||
903 | /* output 29 */ | ||
904 | CARRY_FORWARD; | ||
905 | SQRADDSC(a[0], a[29]); SQRADDAC(a[1], a[28]); SQRADDAC(a[2], a[27]); SQRADDAC(a[3], a[26]); SQRADDAC(a[4], a[25]); SQRADDAC(a[5], a[24]); SQRADDAC(a[6], a[23]); SQRADDAC(a[7], a[22]); SQRADDAC(a[8], a[21]); SQRADDAC(a[9], a[20]); SQRADDAC(a[10], a[19]); SQRADDAC(a[11], a[18]); SQRADDAC(a[12], a[17]); SQRADDAC(a[13], a[16]); SQRADDAC(a[14], a[15]); SQRADDDB; | ||
906 | COMBA_STORE(b[29]); | ||
907 | |||
908 | /* output 30 */ | ||
909 | CARRY_FORWARD; | ||
910 | SQRADDSC(a[0], a[30]); SQRADDAC(a[1], a[29]); SQRADDAC(a[2], a[28]); SQRADDAC(a[3], a[27]); SQRADDAC(a[4], a[26]); SQRADDAC(a[5], a[25]); SQRADDAC(a[6], a[24]); SQRADDAC(a[7], a[23]); SQRADDAC(a[8], a[22]); SQRADDAC(a[9], a[21]); SQRADDAC(a[10], a[20]); SQRADDAC(a[11], a[19]); SQRADDAC(a[12], a[18]); SQRADDAC(a[13], a[17]); SQRADDAC(a[14], a[16]); SQRADDDB; SQRADD(a[15], a[15]); | ||
911 | COMBA_STORE(b[30]); | ||
912 | |||
913 | /* output 31 */ | ||
914 | CARRY_FORWARD; | ||
915 | SQRADDSC(a[0], a[31]); SQRADDAC(a[1], a[30]); SQRADDAC(a[2], a[29]); SQRADDAC(a[3], a[28]); SQRADDAC(a[4], a[27]); SQRADDAC(a[5], a[26]); SQRADDAC(a[6], a[25]); SQRADDAC(a[7], a[24]); SQRADDAC(a[8], a[23]); SQRADDAC(a[9], a[22]); SQRADDAC(a[10], a[21]); SQRADDAC(a[11], a[20]); SQRADDAC(a[12], a[19]); SQRADDAC(a[13], a[18]); SQRADDAC(a[14], a[17]); SQRADDAC(a[15], a[16]); SQRADDDB; | ||
916 | COMBA_STORE(b[31]); | ||
917 | |||
918 | /* output 32 */ | ||
919 | CARRY_FORWARD; | ||
920 | SQRADDSC(a[1], a[31]); SQRADDAC(a[2], a[30]); SQRADDAC(a[3], a[29]); SQRADDAC(a[4], a[28]); SQRADDAC(a[5], a[27]); SQRADDAC(a[6], a[26]); SQRADDAC(a[7], a[25]); SQRADDAC(a[8], a[24]); SQRADDAC(a[9], a[23]); SQRADDAC(a[10], a[22]); SQRADDAC(a[11], a[21]); SQRADDAC(a[12], a[20]); SQRADDAC(a[13], a[19]); SQRADDAC(a[14], a[18]); SQRADDAC(a[15], a[17]); SQRADDDB; SQRADD(a[16], a[16]); | ||
921 | COMBA_STORE(b[32]); | ||
922 | |||
923 | /* output 33 */ | ||
924 | CARRY_FORWARD; | ||
925 | SQRADDSC(a[2], a[31]); SQRADDAC(a[3], a[30]); SQRADDAC(a[4], a[29]); SQRADDAC(a[5], a[28]); SQRADDAC(a[6], a[27]); SQRADDAC(a[7], a[26]); SQRADDAC(a[8], a[25]); SQRADDAC(a[9], a[24]); SQRADDAC(a[10], a[23]); SQRADDAC(a[11], a[22]); SQRADDAC(a[12], a[21]); SQRADDAC(a[13], a[20]); SQRADDAC(a[14], a[19]); SQRADDAC(a[15], a[18]); SQRADDAC(a[16], a[17]); SQRADDDB; | ||
926 | COMBA_STORE(b[33]); | ||
927 | |||
928 | /* output 34 */ | ||
929 | CARRY_FORWARD; | ||
930 | SQRADDSC(a[3], a[31]); SQRADDAC(a[4], a[30]); SQRADDAC(a[5], a[29]); SQRADDAC(a[6], a[28]); SQRADDAC(a[7], a[27]); SQRADDAC(a[8], a[26]); SQRADDAC(a[9], a[25]); SQRADDAC(a[10], a[24]); SQRADDAC(a[11], a[23]); SQRADDAC(a[12], a[22]); SQRADDAC(a[13], a[21]); SQRADDAC(a[14], a[20]); SQRADDAC(a[15], a[19]); SQRADDAC(a[16], a[18]); SQRADDDB; SQRADD(a[17], a[17]); | ||
931 | COMBA_STORE(b[34]); | ||
932 | |||
933 | /* output 35 */ | ||
934 | CARRY_FORWARD; | ||
935 | SQRADDSC(a[4], a[31]); SQRADDAC(a[5], a[30]); SQRADDAC(a[6], a[29]); SQRADDAC(a[7], a[28]); SQRADDAC(a[8], a[27]); SQRADDAC(a[9], a[26]); SQRADDAC(a[10], a[25]); SQRADDAC(a[11], a[24]); SQRADDAC(a[12], a[23]); SQRADDAC(a[13], a[22]); SQRADDAC(a[14], a[21]); SQRADDAC(a[15], a[20]); SQRADDAC(a[16], a[19]); SQRADDAC(a[17], a[18]); SQRADDDB; | ||
936 | COMBA_STORE(b[35]); | ||
937 | |||
938 | /* output 36 */ | ||
939 | CARRY_FORWARD; | ||
940 | SQRADDSC(a[5], a[31]); SQRADDAC(a[6], a[30]); SQRADDAC(a[7], a[29]); SQRADDAC(a[8], a[28]); SQRADDAC(a[9], a[27]); SQRADDAC(a[10], a[26]); SQRADDAC(a[11], a[25]); SQRADDAC(a[12], a[24]); SQRADDAC(a[13], a[23]); SQRADDAC(a[14], a[22]); SQRADDAC(a[15], a[21]); SQRADDAC(a[16], a[20]); SQRADDAC(a[17], a[19]); SQRADDDB; SQRADD(a[18], a[18]); | ||
941 | COMBA_STORE(b[36]); | ||
942 | |||
943 | /* output 37 */ | ||
944 | CARRY_FORWARD; | ||
945 | SQRADDSC(a[6], a[31]); SQRADDAC(a[7], a[30]); SQRADDAC(a[8], a[29]); SQRADDAC(a[9], a[28]); SQRADDAC(a[10], a[27]); SQRADDAC(a[11], a[26]); SQRADDAC(a[12], a[25]); SQRADDAC(a[13], a[24]); SQRADDAC(a[14], a[23]); SQRADDAC(a[15], a[22]); SQRADDAC(a[16], a[21]); SQRADDAC(a[17], a[20]); SQRADDAC(a[18], a[19]); SQRADDDB; | ||
946 | COMBA_STORE(b[37]); | ||
947 | |||
948 | /* output 38 */ | ||
949 | CARRY_FORWARD; | ||
950 | SQRADDSC(a[7], a[31]); SQRADDAC(a[8], a[30]); SQRADDAC(a[9], a[29]); SQRADDAC(a[10], a[28]); SQRADDAC(a[11], a[27]); SQRADDAC(a[12], a[26]); SQRADDAC(a[13], a[25]); SQRADDAC(a[14], a[24]); SQRADDAC(a[15], a[23]); SQRADDAC(a[16], a[22]); SQRADDAC(a[17], a[21]); SQRADDAC(a[18], a[20]); SQRADDDB; SQRADD(a[19], a[19]); | ||
951 | COMBA_STORE(b[38]); | ||
952 | |||
953 | /* output 39 */ | ||
954 | CARRY_FORWARD; | ||
955 | SQRADDSC(a[8], a[31]); SQRADDAC(a[9], a[30]); SQRADDAC(a[10], a[29]); SQRADDAC(a[11], a[28]); SQRADDAC(a[12], a[27]); SQRADDAC(a[13], a[26]); SQRADDAC(a[14], a[25]); SQRADDAC(a[15], a[24]); SQRADDAC(a[16], a[23]); SQRADDAC(a[17], a[22]); SQRADDAC(a[18], a[21]); SQRADDAC(a[19], a[20]); SQRADDDB; | ||
956 | COMBA_STORE(b[39]); | ||
957 | |||
958 | /* output 40 */ | ||
959 | CARRY_FORWARD; | ||
960 | SQRADDSC(a[9], a[31]); SQRADDAC(a[10], a[30]); SQRADDAC(a[11], a[29]); SQRADDAC(a[12], a[28]); SQRADDAC(a[13], a[27]); SQRADDAC(a[14], a[26]); SQRADDAC(a[15], a[25]); SQRADDAC(a[16], a[24]); SQRADDAC(a[17], a[23]); SQRADDAC(a[18], a[22]); SQRADDAC(a[19], a[21]); SQRADDDB; SQRADD(a[20], a[20]); | ||
961 | COMBA_STORE(b[40]); | ||
962 | |||
963 | /* output 41 */ | ||
964 | CARRY_FORWARD; | ||
965 | SQRADDSC(a[10], a[31]); SQRADDAC(a[11], a[30]); SQRADDAC(a[12], a[29]); SQRADDAC(a[13], a[28]); SQRADDAC(a[14], a[27]); SQRADDAC(a[15], a[26]); SQRADDAC(a[16], a[25]); SQRADDAC(a[17], a[24]); SQRADDAC(a[18], a[23]); SQRADDAC(a[19], a[22]); SQRADDAC(a[20], a[21]); SQRADDDB; | ||
966 | COMBA_STORE(b[41]); | ||
967 | |||
968 | /* output 42 */ | ||
969 | CARRY_FORWARD; | ||
970 | SQRADDSC(a[11], a[31]); SQRADDAC(a[12], a[30]); SQRADDAC(a[13], a[29]); SQRADDAC(a[14], a[28]); SQRADDAC(a[15], a[27]); SQRADDAC(a[16], a[26]); SQRADDAC(a[17], a[25]); SQRADDAC(a[18], a[24]); SQRADDAC(a[19], a[23]); SQRADDAC(a[20], a[22]); SQRADDDB; SQRADD(a[21], a[21]); | ||
971 | COMBA_STORE(b[42]); | ||
972 | |||
973 | /* output 43 */ | ||
974 | CARRY_FORWARD; | ||
975 | SQRADDSC(a[12], a[31]); SQRADDAC(a[13], a[30]); SQRADDAC(a[14], a[29]); SQRADDAC(a[15], a[28]); SQRADDAC(a[16], a[27]); SQRADDAC(a[17], a[26]); SQRADDAC(a[18], a[25]); SQRADDAC(a[19], a[24]); SQRADDAC(a[20], a[23]); SQRADDAC(a[21], a[22]); SQRADDDB; | ||
976 | COMBA_STORE(b[43]); | ||
977 | |||
978 | /* output 44 */ | ||
979 | CARRY_FORWARD; | ||
980 | SQRADDSC(a[13], a[31]); SQRADDAC(a[14], a[30]); SQRADDAC(a[15], a[29]); SQRADDAC(a[16], a[28]); SQRADDAC(a[17], a[27]); SQRADDAC(a[18], a[26]); SQRADDAC(a[19], a[25]); SQRADDAC(a[20], a[24]); SQRADDAC(a[21], a[23]); SQRADDDB; SQRADD(a[22], a[22]); | ||
981 | COMBA_STORE(b[44]); | ||
982 | |||
983 | /* output 45 */ | ||
984 | CARRY_FORWARD; | ||
985 | SQRADDSC(a[14], a[31]); SQRADDAC(a[15], a[30]); SQRADDAC(a[16], a[29]); SQRADDAC(a[17], a[28]); SQRADDAC(a[18], a[27]); SQRADDAC(a[19], a[26]); SQRADDAC(a[20], a[25]); SQRADDAC(a[21], a[24]); SQRADDAC(a[22], a[23]); SQRADDDB; | ||
986 | COMBA_STORE(b[45]); | ||
987 | |||
988 | /* output 46 */ | ||
989 | CARRY_FORWARD; | ||
990 | SQRADDSC(a[15], a[31]); SQRADDAC(a[16], a[30]); SQRADDAC(a[17], a[29]); SQRADDAC(a[18], a[28]); SQRADDAC(a[19], a[27]); SQRADDAC(a[20], a[26]); SQRADDAC(a[21], a[25]); SQRADDAC(a[22], a[24]); SQRADDDB; SQRADD(a[23], a[23]); | ||
991 | COMBA_STORE(b[46]); | ||
992 | |||
993 | /* output 47 */ | ||
994 | CARRY_FORWARD; | ||
995 | SQRADDSC(a[16], a[31]); SQRADDAC(a[17], a[30]); SQRADDAC(a[18], a[29]); SQRADDAC(a[19], a[28]); SQRADDAC(a[20], a[27]); SQRADDAC(a[21], a[26]); SQRADDAC(a[22], a[25]); SQRADDAC(a[23], a[24]); SQRADDDB; | ||
996 | COMBA_STORE(b[47]); | ||
997 | |||
998 | /* output 48 */ | ||
999 | CARRY_FORWARD; | ||
1000 | SQRADDSC(a[17], a[31]); SQRADDAC(a[18], a[30]); SQRADDAC(a[19], a[29]); SQRADDAC(a[20], a[28]); SQRADDAC(a[21], a[27]); SQRADDAC(a[22], a[26]); SQRADDAC(a[23], a[25]); SQRADDDB; SQRADD(a[24], a[24]); | ||
1001 | COMBA_STORE(b[48]); | ||
1002 | |||
1003 | /* output 49 */ | ||
1004 | CARRY_FORWARD; | ||
1005 | SQRADDSC(a[18], a[31]); SQRADDAC(a[19], a[30]); SQRADDAC(a[20], a[29]); SQRADDAC(a[21], a[28]); SQRADDAC(a[22], a[27]); SQRADDAC(a[23], a[26]); SQRADDAC(a[24], a[25]); SQRADDDB; | ||
1006 | COMBA_STORE(b[49]); | ||
1007 | |||
1008 | /* output 50 */ | ||
1009 | CARRY_FORWARD; | ||
1010 | SQRADDSC(a[19], a[31]); SQRADDAC(a[20], a[30]); SQRADDAC(a[21], a[29]); SQRADDAC(a[22], a[28]); SQRADDAC(a[23], a[27]); SQRADDAC(a[24], a[26]); SQRADDDB; SQRADD(a[25], a[25]); | ||
1011 | COMBA_STORE(b[50]); | ||
1012 | |||
1013 | /* output 51 */ | ||
1014 | CARRY_FORWARD; | ||
1015 | SQRADDSC(a[20], a[31]); SQRADDAC(a[21], a[30]); SQRADDAC(a[22], a[29]); SQRADDAC(a[23], a[28]); SQRADDAC(a[24], a[27]); SQRADDAC(a[25], a[26]); SQRADDDB; | ||
1016 | COMBA_STORE(b[51]); | ||
1017 | |||
1018 | /* output 52 */ | ||
1019 | CARRY_FORWARD; | ||
1020 | SQRADDSC(a[21], a[31]); SQRADDAC(a[22], a[30]); SQRADDAC(a[23], a[29]); SQRADDAC(a[24], a[28]); SQRADDAC(a[25], a[27]); SQRADDDB; SQRADD(a[26], a[26]); | ||
1021 | COMBA_STORE(b[52]); | ||
1022 | |||
1023 | /* output 53 */ | ||
1024 | CARRY_FORWARD; | ||
1025 | SQRADDSC(a[22], a[31]); SQRADDAC(a[23], a[30]); SQRADDAC(a[24], a[29]); SQRADDAC(a[25], a[28]); SQRADDAC(a[26], a[27]); SQRADDDB; | ||
1026 | COMBA_STORE(b[53]); | ||
1027 | |||
1028 | /* output 54 */ | ||
1029 | CARRY_FORWARD; | ||
1030 | SQRADDSC(a[23], a[31]); SQRADDAC(a[24], a[30]); SQRADDAC(a[25], a[29]); SQRADDAC(a[26], a[28]); SQRADDDB; SQRADD(a[27], a[27]); | ||
1031 | COMBA_STORE(b[54]); | ||
1032 | |||
1033 | /* output 55 */ | ||
1034 | CARRY_FORWARD; | ||
1035 | SQRADDSC(a[24], a[31]); SQRADDAC(a[25], a[30]); SQRADDAC(a[26], a[29]); SQRADDAC(a[27], a[28]); SQRADDDB; | ||
1036 | COMBA_STORE(b[55]); | ||
1037 | |||
1038 | /* output 56 */ | ||
1039 | CARRY_FORWARD; | ||
1040 | SQRADDSC(a[25], a[31]); SQRADDAC(a[26], a[30]); SQRADDAC(a[27], a[29]); SQRADDDB; SQRADD(a[28], a[28]); | ||
1041 | COMBA_STORE(b[56]); | ||
1042 | |||
1043 | /* output 57 */ | ||
1044 | CARRY_FORWARD; | ||
1045 | SQRADDSC(a[26], a[31]); SQRADDAC(a[27], a[30]); SQRADDAC(a[28], a[29]); SQRADDDB; | ||
1046 | COMBA_STORE(b[57]); | ||
1047 | |||
1048 | /* output 58 */ | ||
1049 | CARRY_FORWARD; | ||
1050 | SQRADD2(a[27], a[31]); SQRADD2(a[28], a[30]); SQRADD(a[29], a[29]); | ||
1051 | COMBA_STORE(b[58]); | ||
1052 | |||
1053 | /* output 59 */ | ||
1054 | CARRY_FORWARD; | ||
1055 | SQRADD2(a[28], a[31]); SQRADD2(a[29], a[30]); | ||
1056 | COMBA_STORE(b[59]); | ||
1057 | |||
1058 | /* output 60 */ | ||
1059 | CARRY_FORWARD; | ||
1060 | SQRADD2(a[29], a[31]); SQRADD(a[30], a[30]); | ||
1061 | COMBA_STORE(b[60]); | ||
1062 | |||
1063 | /* output 61 */ | ||
1064 | CARRY_FORWARD; | ||
1065 | SQRADD2(a[30], a[31]); | ||
1066 | COMBA_STORE(b[61]); | ||
1067 | |||
1068 | /* output 62 */ | ||
1069 | CARRY_FORWARD; | ||
1070 | SQRADD(a[31], a[31]); | ||
1071 | COMBA_STORE(b[62]); | ||
1072 | COMBA_STORE2(b[63]); | ||
1073 | COMBA_FINI; | ||
1074 | |||
1075 | B->used = 64; | ||
1076 | B->sign = PSTM_ZPOS; | ||
1077 | memcpy(B->dp, b, 64 * sizeof(pstm_digit)); | ||
1078 | pstm_clamp(B); | ||
1079 | return PSTM_OKAY; | ||
1080 | } | ||
1081 | #endif /* USE_2048_KEY_SPEED_OPTIMIZATIONS */ | ||
1082 | |||
1083 | /******************************************************************************/ | ||
1084 | /* | ||
1085 | */ | ||
1086 | int32 pstm_sqr_comba(psPool_t *pool, pstm_int *A, pstm_int *B, pstm_digit *paD, | ||
1087 | uint32 paDlen) | ||
1088 | { | ||
1089 | #ifdef USE_1024_KEY_SPEED_OPTIMIZATIONS | ||
1090 | if (A->used == 16) { | ||
1091 | return pstm_sqr_comba16(A, B); | ||
1092 | } else { | ||
1093 | #ifdef USE_2048_KEY_SPEED_OPTIMIZATIONS | ||
1094 | if (A->used == 32) { | ||
1095 | return pstm_sqr_comba32(A, B); | ||
1096 | } | ||
1097 | #endif /* USE_2048_KEY_SPEED_OPTIMIZATIONS */ | ||
1098 | return pstm_sqr_comba_gen(pool, A, B, paD, paDlen); | ||
1099 | } | ||
1100 | #else | ||
1101 | #ifdef USE_2048_KEY_SPEED_OPTIMIZATIONS | ||
1102 | if (A->used == 32) { | ||
1103 | return pstm_sqr_comba32(A, B); | ||
1104 | } | ||
1105 | #endif /* USE_2048_KEY_SPEED_OPTIMIZATIONS */ | ||
1106 | return pstm_sqr_comba_gen(pool, A, B, paD, paDlen); | ||
1107 | #endif | ||
1108 | } | ||
1109 | |||
1110 | #endif /* DISABLE_PSTM */ | ||
1111 | /******************************************************************************/ | ||
diff --git a/networking/tls_rsa.c b/networking/tls_rsa.c new file mode 100644 index 000000000..60c54248e --- /dev/null +++ b/networking/tls_rsa.c | |||
@@ -0,0 +1,211 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2017 Denys Vlasenko | ||
3 | * | ||
4 | * Licensed under GPLv2, see file LICENSE in this source tree. | ||
5 | */ | ||
6 | #include "tls.h" | ||
7 | |||
8 | /* The code below is taken from parts of | ||
9 | * matrixssl-3-7-2b-open/crypto/pubkey/pkcs.c | ||
10 | * matrixssl-3-7-2b-open/crypto/pubkey/rsa.c | ||
11 | * and (so far) almost not modified. Changes are flagged with //bbox | ||
12 | */ | ||
13 | |||
14 | #define pkcs1Pad(in, inlen, out, outlen, cryptType, userPtr) \ | ||
15 | pkcs1Pad(in, inlen, out, outlen, cryptType) | ||
16 | static //bbox | ||
17 | int32 pkcs1Pad(unsigned char *in, uint32 inlen, unsigned char *out, | ||
18 | uint32 outlen, int32 cryptType, void *userPtr) | ||
19 | { | ||
20 | unsigned char *c; | ||
21 | int32 randomLen; | ||
22 | |||
23 | randomLen = outlen - 3 - inlen; | ||
24 | if (randomLen < 8) { | ||
25 | psTraceCrypto("pkcs1Pad failure\n"); | ||
26 | return PS_LIMIT_FAIL; | ||
27 | } | ||
28 | c = out; | ||
29 | *c = 0x00; | ||
30 | c++; | ||
31 | *c = (unsigned char)cryptType; | ||
32 | c++; | ||
33 | if (cryptType == PUBKEY_TYPE) { | ||
34 | while (randomLen-- > 0) { | ||
35 | *c++ = 0xFF; | ||
36 | } | ||
37 | } else { | ||
38 | if (matrixCryptoGetPrngData(c, (uint32)randomLen, userPtr) < 0) { | ||
39 | return PS_PLATFORM_FAIL; | ||
40 | } | ||
41 | /* | ||
42 | SECURITY: Read through the random data and change all 0x0 to 0x01. | ||
43 | This is per spec that no random bytes should be 0 | ||
44 | */ | ||
45 | while (randomLen-- > 0) { | ||
46 | if (*c == 0x0) { | ||
47 | *c = 0x01; | ||
48 | } | ||
49 | c++; | ||
50 | } | ||
51 | } | ||
52 | *c = 0x00; | ||
53 | c++; | ||
54 | memcpy(c, in, inlen); | ||
55 | |||
56 | return outlen; | ||
57 | } | ||
58 | |||
59 | #define psRsaCrypt(pool, in, inlen, out, outlen, key, type, data) \ | ||
60 | psRsaCrypt( in, inlen, out, outlen, key, type) | ||
61 | static //bbox | ||
62 | int32 psRsaCrypt(psPool_t *pool, const unsigned char *in, uint32 inlen, | ||
63 | unsigned char *out, uint32 *outlen, psRsaKey_t *key, int32 type, | ||
64 | void *data) | ||
65 | { | ||
66 | pstm_int tmp, tmpa, tmpb; | ||
67 | int32 res; | ||
68 | uint32 x; | ||
69 | |||
70 | //bbox | ||
71 | // if (in == NULL || out == NULL || outlen == NULL || key == NULL) { | ||
72 | // psTraceCrypto("NULL parameter error in psRsaCrypt\n"); | ||
73 | // return PS_ARG_FAIL; | ||
74 | // } | ||
75 | |||
76 | tmp.dp = tmpa.dp = tmpb.dp = NULL; | ||
77 | |||
78 | /* Init and copy into tmp */ | ||
79 | if (pstm_init_for_read_unsigned_bin(pool, &tmp, inlen + sizeof(pstm_digit)) | ||
80 | != PS_SUCCESS) { | ||
81 | return PS_FAILURE; | ||
82 | } | ||
83 | if (pstm_read_unsigned_bin(&tmp, (unsigned char *)in, inlen) != PS_SUCCESS){ | ||
84 | pstm_clear(&tmp); | ||
85 | return PS_FAILURE; | ||
86 | } | ||
87 | /* Sanity check on the input */ | ||
88 | if (pstm_cmp(&key->N, &tmp) == PSTM_LT) { | ||
89 | res = PS_LIMIT_FAIL; | ||
90 | goto done; | ||
91 | } | ||
92 | if (type == PRIVKEY_TYPE) { | ||
93 | if (key->optimized) { | ||
94 | if (pstm_init_size(pool, &tmpa, key->p.alloc) != PS_SUCCESS) { | ||
95 | res = PS_FAILURE; | ||
96 | goto done; | ||
97 | } | ||
98 | if (pstm_init_size(pool, &tmpb, key->q.alloc) != PS_SUCCESS) { | ||
99 | pstm_clear(&tmpa); | ||
100 | res = PS_FAILURE; | ||
101 | goto done; | ||
102 | } | ||
103 | if (pstm_exptmod(pool, &tmp, &key->dP, &key->p, &tmpa) != | ||
104 | PS_SUCCESS) { | ||
105 | psTraceCrypto("decrypt error: pstm_exptmod dP, p\n"); | ||
106 | goto error; | ||
107 | } | ||
108 | if (pstm_exptmod(pool, &tmp, &key->dQ, &key->q, &tmpb) != | ||
109 | PS_SUCCESS) { | ||
110 | psTraceCrypto("decrypt error: pstm_exptmod dQ, q\n"); | ||
111 | goto error; | ||
112 | } | ||
113 | if (pstm_sub(&tmpa, &tmpb, &tmp) != PS_SUCCESS) { | ||
114 | psTraceCrypto("decrypt error: sub tmpb, tmp\n"); | ||
115 | goto error; | ||
116 | } | ||
117 | if (pstm_mulmod(pool, &tmp, &key->qP, &key->p, &tmp) != PS_SUCCESS) { | ||
118 | psTraceCrypto("decrypt error: pstm_mulmod qP, p\n"); | ||
119 | goto error; | ||
120 | } | ||
121 | if (pstm_mul_comba(pool, &tmp, &key->q, &tmp, NULL, 0) | ||
122 | != PS_SUCCESS){ | ||
123 | psTraceCrypto("decrypt error: pstm_mul q \n"); | ||
124 | goto error; | ||
125 | } | ||
126 | if (pstm_add(&tmp, &tmpb, &tmp) != PS_SUCCESS) { | ||
127 | psTraceCrypto("decrypt error: pstm_add tmp \n"); | ||
128 | goto error; | ||
129 | } | ||
130 | } else { | ||
131 | if (pstm_exptmod(pool, &tmp, &key->d, &key->N, &tmp) != | ||
132 | PS_SUCCESS) { | ||
133 | psTraceCrypto("psRsaCrypt error: pstm_exptmod\n"); | ||
134 | goto error; | ||
135 | } | ||
136 | } | ||
137 | } else if (type == PUBKEY_TYPE) { | ||
138 | if (pstm_exptmod(pool, &tmp, &key->e, &key->N, &tmp) != PS_SUCCESS) { | ||
139 | psTraceCrypto("psRsaCrypt error: pstm_exptmod\n"); | ||
140 | goto error; | ||
141 | } | ||
142 | } else { | ||
143 | psTraceCrypto("psRsaCrypt error: invalid type param\n"); | ||
144 | goto error; | ||
145 | } | ||
146 | /* Read it back */ | ||
147 | x = pstm_unsigned_bin_size(&key->N); | ||
148 | |||
149 | if ((uint32)x > *outlen) { | ||
150 | res = -1; | ||
151 | psTraceCrypto("psRsaCrypt error: pstm_unsigned_bin_size\n"); | ||
152 | goto done; | ||
153 | } | ||
154 | /* We want the encrypted value to always be the key size. Pad with 0x0 */ | ||
155 | while ((uint32)x < (unsigned long)key->size) { | ||
156 | *out++ = 0x0; | ||
157 | x++; | ||
158 | } | ||
159 | |||
160 | *outlen = x; | ||
161 | /* Convert it */ | ||
162 | memset(out, 0x0, x); | ||
163 | |||
164 | if (pstm_to_unsigned_bin(pool, &tmp, out+(x-pstm_unsigned_bin_size(&tmp))) | ||
165 | != PS_SUCCESS) { | ||
166 | psTraceCrypto("psRsaCrypt error: pstm_to_unsigned_bin\n"); | ||
167 | goto error; | ||
168 | } | ||
169 | /* Clean up and return */ | ||
170 | res = PS_SUCCESS; | ||
171 | goto done; | ||
172 | error: | ||
173 | res = PS_FAILURE; | ||
174 | done: | ||
175 | if (type == PRIVKEY_TYPE && key->optimized) { | ||
176 | pstm_clear_multi(&tmpa, &tmpb, NULL, NULL, NULL, NULL, NULL, NULL); | ||
177 | } | ||
178 | pstm_clear(&tmp); | ||
179 | return res; | ||
180 | } | ||
181 | |||
182 | int32 psRsaEncryptPub(psPool_t *pool, psRsaKey_t *key, | ||
183 | unsigned char *in, uint32 inlen, | ||
184 | unsigned char *out, uint32 outlen, void *data) | ||
185 | { | ||
186 | int32 err; | ||
187 | uint32 size; | ||
188 | |||
189 | size = key->size; | ||
190 | if (outlen < size) { | ||
191 | //bbox psTraceCrypto("Error on bad outlen parameter to psRsaEncryptPub\n"); | ||
192 | bb_error_msg_and_die("RSA crypt outlen:%d < size:%d", outlen, size); | ||
193 | return PS_ARG_FAIL; | ||
194 | } | ||
195 | |||
196 | if ((err = pkcs1Pad(in, inlen, out, size, PRIVKEY_TYPE, data)) | ||
197 | < PS_SUCCESS) { | ||
198 | psTraceCrypto("Error padding psRsaEncryptPub. Likely data too long\n"); | ||
199 | return err; | ||
200 | } | ||
201 | if ((err = psRsaCrypt(pool, out, size, out, (uint32*)&outlen, key, | ||
202 | PUBKEY_TYPE, data)) < PS_SUCCESS) { | ||
203 | psTraceCrypto("Error performing psRsaEncryptPub\n"); | ||
204 | return err; | ||
205 | } | ||
206 | if (outlen != size) { | ||
207 | psTraceCrypto("Encrypted size error in psRsaEncryptPub\n"); | ||
208 | return PS_FAILURE; | ||
209 | } | ||
210 | return size; | ||
211 | } | ||
diff --git a/networking/tls_rsa.h b/networking/tls_rsa.h new file mode 100644 index 000000000..c464ed552 --- /dev/null +++ b/networking/tls_rsa.h | |||
@@ -0,0 +1,20 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2017 Denys Vlasenko | ||
3 | * | ||
4 | * Licensed under GPLv2, see file LICENSE in this source tree. | ||
5 | * | ||
6 | * Selected few declarations for RSA. | ||
7 | */ | ||
8 | |||
9 | typedef struct { | ||
10 | pstm_int e, d, N, qP, dP, dQ, p, q; | ||
11 | uint32 size; /* Size of the key in bytes */ | ||
12 | int32 optimized; /* 1 for optimized */ | ||
13 | //bbox psPool_t *pool; | ||
14 | } psRsaKey_t; | ||
15 | |||
16 | #define psRsaEncryptPub(pool, key, in, inlen, out, outlen, data) \ | ||
17 | psRsaEncryptPub( key, in, inlen, out, outlen) | ||
18 | int32 psRsaEncryptPub(psPool_t *pool, psRsaKey_t *key, | ||
19 | unsigned char *in, uint32 inlen, | ||
20 | unsigned char *out, uint32 outlen, void *data); | ||
diff --git a/networking/tls_symmetric.h b/networking/tls_symmetric.h new file mode 100644 index 000000000..5e0e4b6d8 --- /dev/null +++ b/networking/tls_symmetric.h | |||
@@ -0,0 +1,511 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2017 Denys Vlasenko | ||
3 | * | ||
4 | * Licensed under GPLv2, see file LICENSE in this source tree. | ||
5 | */ | ||
6 | |||
7 | |||
8 | /* The part below is a section of matrixssl-3-7-2b-open/crypto/cryptolib.h | ||
9 | * Changes are flagged with //bbox | ||
10 | */ | ||
11 | |||
12 | /******************************************************************************/ | ||
13 | /* 32-bit Rotates */ | ||
14 | /******************************************************************************/ | ||
15 | #if defined(_MSC_VER) | ||
16 | /******************************************************************************/ | ||
17 | |||
18 | /* instrinsic rotate */ | ||
19 | #include <stdlib.h> | ||
20 | #pragma intrinsic(_lrotr,_lrotl) | ||
21 | #define ROR(x,n) _lrotr(x,n) | ||
22 | #define ROL(x,n) _lrotl(x,n) | ||
23 | |||
24 | /******************************************************************************/ | ||
25 | #elif defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__)) && \ | ||
26 | !defined(INTEL_CC) && !defined(PS_NO_ASM) | ||
27 | |||
28 | static ALWAYS_INLINE unsigned ROL(unsigned word, int i) | ||
29 | { | ||
30 | if (__builtin_constant_p(i)) { //box | ||
31 | // Rotates by constant use fewer registers, | ||
32 | // and on many Intel CPUs rotates by %cl take 2 cycles, not 1. | ||
33 | asm ("roll %2,%0" | ||
34 | :"=r" (word) | ||
35 | :"0" (word),"i" (i)); | ||
36 | return word; | ||
37 | } //box | ||
38 | asm ("roll %%cl,%0" | ||
39 | :"=r" (word) | ||
40 | :"0" (word),"c" (i)); | ||
41 | return word; | ||
42 | } | ||
43 | |||
44 | static ALWAYS_INLINE unsigned ROR(unsigned word, int i) | ||
45 | { | ||
46 | if (__builtin_constant_p(i)) { //box | ||
47 | asm ("rorl %2,%0" | ||
48 | :"=r" (word) | ||
49 | :"0" (word),"i" (i)); | ||
50 | return word; | ||
51 | } //box | ||
52 | asm ("rorl %%cl,%0" | ||
53 | :"=r" (word) | ||
54 | :"0" (word),"c" (i)); | ||
55 | return word; | ||
56 | } | ||
57 | |||
58 | /******************************************************************************/ | ||
59 | #else | ||
60 | |||
61 | /* rotates the hard way */ | ||
62 | #define ROL(x, y) \ | ||
63 | ( (((unsigned long)(x)<<(unsigned long)((y)&31)) | \ | ||
64 | (((unsigned long)(x)&0xFFFFFFFFUL)>>(unsigned long)(32-((y)&31)))) & \ | ||
65 | 0xFFFFFFFFUL) | ||
66 | #define ROR(x, y) \ | ||
67 | ( ((((unsigned long)(x)&0xFFFFFFFFUL)>>(unsigned long)((y)&31)) | \ | ||
68 | ((unsigned long)(x)<<(unsigned long)(32-((y)&31)))) & 0xFFFFFFFFUL) | ||
69 | |||
70 | #endif /* 32-bit Rotates */ | ||
71 | /******************************************************************************/ | ||
72 | |||
73 | #ifdef HAVE_NATIVE_INT64 | ||
74 | #ifdef _MSC_VER | ||
75 | #define CONST64(n) n ## ui64 | ||
76 | #else | ||
77 | #define CONST64(n) n ## ULL | ||
78 | #endif | ||
79 | #endif | ||
80 | |||
81 | /******************************************************************************/ | ||
82 | /* | ||
83 | Endian helper macros | ||
84 | */ | ||
85 | #if defined (ENDIAN_NEUTRAL) | ||
86 | #define STORE32L(x, y) { \ | ||
87 | (y)[3] = (unsigned char)(((x)>>24)&255); \ | ||
88 | (y)[2] = (unsigned char)(((x)>>16)&255); \ | ||
89 | (y)[1] = (unsigned char)(((x)>>8)&255); \ | ||
90 | (y)[0] = (unsigned char)((x)&255); \ | ||
91 | } | ||
92 | |||
93 | #define LOAD32L(x, y) { \ | ||
94 | x = ((unsigned long)((y)[3] & 255)<<24) | \ | ||
95 | ((unsigned long)((y)[2] & 255)<<16) | \ | ||
96 | ((unsigned long)((y)[1] & 255)<<8) | \ | ||
97 | ((unsigned long)((y)[0] & 255)); \ | ||
98 | } | ||
99 | |||
100 | #define STORE64L(x, y) { \ | ||
101 | (y)[7] = (unsigned char)(((x)>>56)&255); \ | ||
102 | (y)[6] = (unsigned char)(((x)>>48)&255); \ | ||
103 | (y)[5] = (unsigned char)(((x)>>40)&255); \ | ||
104 | (y)[4] = (unsigned char)(((x)>>32)&255); \ | ||
105 | (y)[3] = (unsigned char)(((x)>>24)&255); \ | ||
106 | (y)[2] = (unsigned char)(((x)>>16)&255); \ | ||
107 | (y)[1] = (unsigned char)(((x)>>8)&255); \ | ||
108 | (y)[0] = (unsigned char)((x)&255); \ | ||
109 | } | ||
110 | |||
111 | #define LOAD64L(x, y) { \ | ||
112 | x = (((uint64)((y)[7] & 255))<<56)|(((uint64)((y)[6] & 255))<<48)| \ | ||
113 | (((uint64)((y)[5] & 255))<<40)|(((uint64)((y)[4] & 255))<<32)| \ | ||
114 | (((uint64)((y)[3] & 255))<<24)|(((uint64)((y)[2] & 255))<<16)| \ | ||
115 | (((uint64)((y)[1] & 255))<<8)|(((uint64)((y)[0] & 255))); \ | ||
116 | } | ||
117 | |||
118 | #define STORE32H(x, y) { \ | ||
119 | (y)[0] = (unsigned char)(((x)>>24)&255); \ | ||
120 | (y)[1] = (unsigned char)(((x)>>16)&255); \ | ||
121 | (y)[2] = (unsigned char)(((x)>>8)&255); \ | ||
122 | (y)[3] = (unsigned char)((x)&255); \ | ||
123 | } | ||
124 | |||
125 | #define LOAD32H(x, y) { \ | ||
126 | x = ((unsigned long)((y)[0] & 255)<<24) | \ | ||
127 | ((unsigned long)((y)[1] & 255)<<16) | \ | ||
128 | ((unsigned long)((y)[2] & 255)<<8) | \ | ||
129 | ((unsigned long)((y)[3] & 255)); \ | ||
130 | } | ||
131 | |||
132 | #define STORE64H(x, y) { \ | ||
133 | (y)[0] = (unsigned char)(((x)>>56)&255); \ | ||
134 | (y)[1] = (unsigned char)(((x)>>48)&255); \ | ||
135 | (y)[2] = (unsigned char)(((x)>>40)&255); \ | ||
136 | (y)[3] = (unsigned char)(((x)>>32)&255); \ | ||
137 | (y)[4] = (unsigned char)(((x)>>24)&255); \ | ||
138 | (y)[5] = (unsigned char)(((x)>>16)&255); \ | ||
139 | (y)[6] = (unsigned char)(((x)>>8)&255); \ | ||
140 | (y)[7] = (unsigned char)((x)&255); \ | ||
141 | } | ||
142 | |||
143 | #define LOAD64H(x, y) { \ | ||
144 | x = (((uint64)((y)[0] & 255))<<56)|(((uint64)((y)[1] & 255))<<48) | \ | ||
145 | (((uint64)((y)[2] & 255))<<40)|(((uint64)((y)[3] & 255))<<32) | \ | ||
146 | (((uint64)((y)[4] & 255))<<24)|(((uint64)((y)[5] & 255))<<16) | \ | ||
147 | (((uint64)((y)[6] & 255))<<8)|(((uint64)((y)[7] & 255))); \ | ||
148 | } | ||
149 | |||
150 | #endif /* ENDIAN_NEUTRAL */ | ||
151 | |||
152 | #ifdef ENDIAN_LITTLE | ||
153 | #define STORE32H(x, y) { \ | ||
154 | (y)[0] = (unsigned char)(((x)>>24)&255); \ | ||
155 | (y)[1] = (unsigned char)(((x)>>16)&255); \ | ||
156 | (y)[2] = (unsigned char)(((x)>>8)&255); \ | ||
157 | (y)[3] = (unsigned char)((x)&255); \ | ||
158 | } | ||
159 | |||
160 | #define LOAD32H(x, y) { \ | ||
161 | x = ((unsigned long)((y)[0] & 255)<<24) | \ | ||
162 | ((unsigned long)((y)[1] & 255)<<16) | \ | ||
163 | ((unsigned long)((y)[2] & 255)<<8) | \ | ||
164 | ((unsigned long)((y)[3] & 255)); \ | ||
165 | } | ||
166 | |||
167 | #define STORE64H(x, y) { \ | ||
168 | (y)[0] = (unsigned char)(((x)>>56)&255); \ | ||
169 | (y)[1] = (unsigned char)(((x)>>48)&255); \ | ||
170 | (y)[2] = (unsigned char)(((x)>>40)&255); \ | ||
171 | (y)[3] = (unsigned char)(((x)>>32)&255); \ | ||
172 | (y)[4] = (unsigned char)(((x)>>24)&255); \ | ||
173 | (y)[5] = (unsigned char)(((x)>>16)&255); \ | ||
174 | (y)[6] = (unsigned char)(((x)>>8)&255); \ | ||
175 | (y)[7] = (unsigned char)((x)&255); \ | ||
176 | } | ||
177 | |||
178 | #define LOAD64H(x, y) { \ | ||
179 | x = (((uint64)((y)[0] & 255))<<56)|(((uint64)((y)[1] & 255))<<48) | \ | ||
180 | (((uint64)((y)[2] & 255))<<40)|(((uint64)((y)[3] & 255))<<32) | \ | ||
181 | (((uint64)((y)[4] & 255))<<24)|(((uint64)((y)[5] & 255))<<16) | \ | ||
182 | (((uint64)((y)[6] & 255))<<8)|(((uint64)((y)[7] & 255))); } | ||
183 | |||
184 | #ifdef ENDIAN_32BITWORD | ||
185 | #define STORE32L(x, y) { \ | ||
186 | unsigned long __t = (x); memcpy(y, &__t, 4); \ | ||
187 | } | ||
188 | |||
189 | #define LOAD32L(x, y) memcpy(&(x), y, 4); | ||
190 | |||
191 | #define STORE64L(x, y) { \ | ||
192 | (y)[7] = (unsigned char)(((x)>>56)&255); \ | ||
193 | (y)[6] = (unsigned char)(((x)>>48)&255); \ | ||
194 | (y)[5] = (unsigned char)(((x)>>40)&255); \ | ||
195 | (y)[4] = (unsigned char)(((x)>>32)&255); \ | ||
196 | (y)[3] = (unsigned char)(((x)>>24)&255); \ | ||
197 | (y)[2] = (unsigned char)(((x)>>16)&255); \ | ||
198 | (y)[1] = (unsigned char)(((x)>>8)&255); \ | ||
199 | (y)[0] = (unsigned char)((x)&255); \ | ||
200 | } | ||
201 | |||
202 | #define LOAD64L(x, y) { \ | ||
203 | x = (((uint64)((y)[7] & 255))<<56)|(((uint64)((y)[6] & 255))<<48)| \ | ||
204 | (((uint64)((y)[5] & 255))<<40)|(((uint64)((y)[4] & 255))<<32)| \ | ||
205 | (((uint64)((y)[3] & 255))<<24)|(((uint64)((y)[2] & 255))<<16)| \ | ||
206 | (((uint64)((y)[1] & 255))<<8)|(((uint64)((y)[0] & 255))); \ | ||
207 | } | ||
208 | |||
209 | #else /* 64-bit words then */ | ||
210 | #define STORE32L(x, y) \ | ||
211 | { unsigned long __t = (x); memcpy(y, &__t, 4); } | ||
212 | |||
213 | #define LOAD32L(x, y) \ | ||
214 | { memcpy(&(x), y, 4); x &= 0xFFFFFFFF; } | ||
215 | |||
216 | #define STORE64L(x, y) \ | ||
217 | { uint64 __t = (x); memcpy(y, &__t, 8); } | ||
218 | |||
219 | #define LOAD64L(x, y) \ | ||
220 | { memcpy(&(x), y, 8); } | ||
221 | |||
222 | #endif /* ENDIAN_64BITWORD */ | ||
223 | #endif /* ENDIAN_LITTLE */ | ||
224 | |||
225 | #ifdef ENDIAN_BIG | ||
226 | #define STORE32L(x, y) { \ | ||
227 | (y)[3] = (unsigned char)(((x)>>24)&255); \ | ||
228 | (y)[2] = (unsigned char)(((x)>>16)&255); \ | ||
229 | (y)[1] = (unsigned char)(((x)>>8)&255); \ | ||
230 | (y)[0] = (unsigned char)((x)&255); \ | ||
231 | } | ||
232 | |||
233 | #define LOAD32L(x, y) { \ | ||
234 | x = ((unsigned long)((y)[3] & 255)<<24) | \ | ||
235 | ((unsigned long)((y)[2] & 255)<<16) | \ | ||
236 | ((unsigned long)((y)[1] & 255)<<8) | \ | ||
237 | ((unsigned long)((y)[0] & 255)); \ | ||
238 | } | ||
239 | |||
240 | #define STORE64L(x, y) { \ | ||
241 | (y)[7] = (unsigned char)(((x)>>56)&255); \ | ||
242 | (y)[6] = (unsigned char)(((x)>>48)&255); \ | ||
243 | (y)[5] = (unsigned char)(((x)>>40)&255); \ | ||
244 | (y)[4] = (unsigned char)(((x)>>32)&255); \ | ||
245 | (y)[3] = (unsigned char)(((x)>>24)&255); \ | ||
246 | (y)[2] = (unsigned char)(((x)>>16)&255); \ | ||
247 | (y)[1] = (unsigned char)(((x)>>8)&255); \ | ||
248 | (y)[0] = (unsigned char)((x)&255); \ | ||
249 | } | ||
250 | |||
251 | #define LOAD64L(x, y) { \ | ||
252 | x = (((uint64)((y)[7] & 255))<<56)|(((uint64)((y)[6] & 255))<<48) | \ | ||
253 | (((uint64)((y)[5] & 255))<<40)|(((uint64)((y)[4] & 255))<<32) | \ | ||
254 | (((uint64)((y)[3] & 255))<<24)|(((uint64)((y)[2] & 255))<<16) | \ | ||
255 | (((uint64)((y)[1] & 255))<<8)|(((uint64)((y)[0] & 255))); \ | ||
256 | } | ||
257 | |||
258 | #ifdef ENDIAN_32BITWORD | ||
259 | #define STORE32H(x, y) \ | ||
260 | { unsigned int __t = (x); memcpy(y, &__t, 4); } | ||
261 | |||
262 | #define LOAD32H(x, y) memcpy(&(x), y, 4); | ||
263 | |||
264 | #define STORE64H(x, y) { \ | ||
265 | (y)[0] = (unsigned char)(((x)>>56)&255); \ | ||
266 | (y)[1] = (unsigned char)(((x)>>48)&255); \ | ||
267 | (y)[2] = (unsigned char)(((x)>>40)&255); \ | ||
268 | (y)[3] = (unsigned char)(((x)>>32)&255); \ | ||
269 | (y)[4] = (unsigned char)(((x)>>24)&255); \ | ||
270 | (y)[5] = (unsigned char)(((x)>>16)&255); \ | ||
271 | (y)[6] = (unsigned char)(((x)>>8)&255); \ | ||
272 | (y)[7] = (unsigned char)((x)&255); \ | ||
273 | } | ||
274 | |||
275 | #define LOAD64H(x, y) { \ | ||
276 | x = (((uint64)((y)[0] & 255))<<56)|(((uint64)((y)[1] & 255))<<48)| \ | ||
277 | (((uint64)((y)[2] & 255))<<40)|(((uint64)((y)[3] & 255))<<32)| \ | ||
278 | (((uint64)((y)[4] & 255))<<24)|(((uint64)((y)[5] & 255))<<16)| \ | ||
279 | (((uint64)((y)[6] & 255))<<8)| (((uint64)((y)[7] & 255))); \ | ||
280 | } | ||
281 | |||
282 | #else /* 64-bit words then */ | ||
283 | |||
284 | #define STORE32H(x, y) \ | ||
285 | { unsigned long __t = (x); memcpy(y, &__t, 4); } | ||
286 | |||
287 | #define LOAD32H(x, y) \ | ||
288 | { memcpy(&(x), y, 4); x &= 0xFFFFFFFF; } | ||
289 | |||
290 | #define STORE64H(x, y) \ | ||
291 | { uint64 __t = (x); memcpy(y, &__t, 8); } | ||
292 | |||
293 | #define LOAD64H(x, y) \ | ||
294 | { memcpy(&(x), y, 8); } | ||
295 | |||
296 | #endif /* ENDIAN_64BITWORD */ | ||
297 | #endif /* ENDIAN_BIG */ | ||
298 | |||
299 | #ifdef HAVE_NATIVE_INT64 | ||
300 | #define ROL64c(x, y) \ | ||
301 | ( (((x)<<((uint64)(y)&63)) | \ | ||
302 | (((x)&CONST64(0xFFFFFFFFFFFFFFFF))>>((uint64)64-((y)&63)))) & CONST64(0xFFFFFFFFFFFFFFFF)) | ||
303 | |||
304 | #define ROR64c(x, y) \ | ||
305 | ( ((((x)&CONST64(0xFFFFFFFFFFFFFFFF))>>((uint64)(y)&CONST64(63))) | \ | ||
306 | ((x)<<((uint64)(64-((y)&CONST64(63)))))) & CONST64(0xFFFFFFFFFFFFFFFF)) | ||
307 | #endif /* HAVE_NATIVE_INT64 */ | ||
308 | /******************************************************************************/ | ||
309 | |||
310 | |||
311 | |||
312 | /* The part below is taken almost verbatim from matrixssl-3-7-2b-open/crypto/symmetric/. | ||
313 | * Changes are flagged with //bbox | ||
314 | */ | ||
315 | |||
316 | /** | ||
317 | * @file symmetric.h | ||
318 | * @version 33ef80f (HEAD, tag: MATRIXSSL-3-7-2-OPEN, tag: MATRIXSSL-3-7-2-COMM, origin/master, origin/HEAD, master) | ||
319 | * | ||
320 | * Header for internal symmetric key cryptography support. | ||
321 | */ | ||
322 | /* | ||
323 | * Copyright (c) 2013-2015 INSIDE Secure Corporation | ||
324 | * Copyright (c) PeerSec Networks, 2002-2011 | ||
325 | * All Rights Reserved | ||
326 | * | ||
327 | * The latest version of this code is available at http://www.matrixssl.org | ||
328 | * | ||
329 | * This software is open source; you can redistribute it and/or modify | ||
330 | * it under the terms of the GNU General Public License as published by | ||
331 | * the Free Software Foundation; either version 2 of the License, or | ||
332 | * (at your option) any later version. | ||
333 | * | ||
334 | * This General Public License does NOT permit incorporating this software | ||
335 | * into proprietary programs. If you are unable to comply with the GPL, a | ||
336 | * commercial license for this software may be purchased from INSIDE at | ||
337 | * http://www.insidesecure.com/eng/Company/Locations | ||
338 | * | ||
339 | * This program is distributed in WITHOUT ANY WARRANTY; without even the | ||
340 | * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. | ||
341 | * See the GNU General Public License for more details. | ||
342 | * | ||
343 | * You should have received a copy of the GNU General Public License | ||
344 | * along with this program; if not, write to the Free Software | ||
345 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
346 | * http://www.gnu.org/copyleft/gpl.html | ||
347 | */ | ||
348 | /******************************************************************************/ | ||
349 | |||
350 | #ifndef _h_PS_SYMMETRIC | ||
351 | #define _h_PS_SYMMETRIC | ||
352 | |||
353 | /******************************************************************************/ | ||
354 | #ifdef USE_AES | ||
355 | /******************************************************************************/ | ||
356 | |||
357 | |||
358 | #ifndef USE_AES_CBC_EXTERNAL | ||
359 | typedef struct { | ||
360 | uint32 eK[64], dK[64]; | ||
361 | int32 Nr; | ||
362 | } psAesKey_t; | ||
363 | |||
364 | typedef struct { | ||
365 | int32 blocklen; | ||
366 | unsigned char IV[16]; | ||
367 | psAesKey_t key; | ||
368 | #if defined(USE_AES_GCM) || defined(USE_AES_CCM) | ||
369 | unsigned char EncCtr[16]; | ||
370 | unsigned char CtrBlock[16]; | ||
371 | #endif | ||
372 | #ifdef USE_AES_GCM | ||
373 | unsigned char gInit[16]; | ||
374 | uint32 TagTemp[4]; | ||
375 | unsigned char Hash_SubKey[16]; | ||
376 | uint32 ProcessedBitCount[4]; | ||
377 | uint32 InputBufferCount; | ||
378 | uint32 OutputBufferCount; | ||
379 | union | ||
380 | { | ||
381 | unsigned char Buffer[128]; | ||
382 | uint32 BufferAlignment; | ||
383 | } Input; | ||
384 | #endif /* USE_AES_GCM */ | ||
385 | #ifdef USE_AES_CCM | ||
386 | uint32_t ccmTagTemp[16 / sizeof(uint32_t)]; /* 32 */ | ||
387 | union | ||
388 | { | ||
389 | /* Used for formatting IV. */ | ||
390 | uint8_t Temporary[16]; | ||
391 | /* Used for processing Mac. */ | ||
392 | uint8_t Y0[16]; | ||
393 | } u; /* 48 */ | ||
394 | #endif /* USE_AES_CCM */ | ||
395 | } psAesCipher_t; | ||
396 | #endif /* USE_AES_CBC_EXTERNAL */ | ||
397 | |||
398 | #endif /* USE_AES */ | ||
399 | |||
400 | #ifdef USE_IDEA | ||
401 | #define SSL_IDEA_KEY_LEN 16 | ||
402 | #define SSL_IDEA_IV_LEN 8 | ||
403 | #define SSL_IDEA_BLOCK_LEN 8 | ||
404 | |||
405 | typedef struct { | ||
406 | uint16 key_schedule[52]; | ||
407 | } psIdeaKey_t; | ||
408 | |||
409 | typedef struct { | ||
410 | psIdeaKey_t key; | ||
411 | uint32 IV[2]; | ||
412 | short for_encryption; | ||
413 | short inverted; | ||
414 | } idea_CBC; | ||
415 | #endif | ||
416 | /******************************************************************************/ | ||
417 | |||
418 | /******************************************************************************/ | ||
419 | #ifdef USE_SEED | ||
420 | /******************************************************************************/ | ||
421 | #define SSL_SEED_KEY_LEN 16 | ||
422 | #define SSL_SEED_IV_LEN 16 | ||
423 | |||
424 | |||
425 | typedef struct { | ||
426 | uint32 K[32], dK[32]; | ||
427 | } psSeedKey_t; | ||
428 | |||
429 | typedef struct { | ||
430 | int32 blocklen; | ||
431 | unsigned char IV[16]; | ||
432 | psSeedKey_t key; | ||
433 | } seed_CBC; | ||
434 | |||
435 | #endif /* USE_SEED */ | ||
436 | /******************************************************************************/ | ||
437 | |||
438 | /******************************************************************************/ | ||
439 | #if defined(USE_3DES) || defined(USE_DES) | ||
440 | /******************************************************************************/ | ||
441 | #define DES3_KEY_LEN 24 | ||
442 | #define DES3_IV_LEN 8 | ||
443 | #define DES_KEY_LEN 8 | ||
444 | |||
445 | typedef struct { | ||
446 | uint32 ek[3][32], dk[3][32]; | ||
447 | } psDes3Key_t; | ||
448 | |||
449 | /* | ||
450 | A block cipher CBC structure | ||
451 | */ | ||
452 | typedef struct { | ||
453 | int32 blocklen; | ||
454 | unsigned char IV[8]; | ||
455 | psDes3Key_t key; | ||
456 | } des3_CBC; | ||
457 | |||
458 | #endif /* USE_3DES || USE_DES */ | ||
459 | /******************************************************************************/ | ||
460 | |||
461 | /******************************************************************************/ | ||
462 | #ifdef USE_ARC4 | ||
463 | typedef struct { | ||
464 | unsigned char state[256]; | ||
465 | uint32 byteCount; | ||
466 | unsigned char x; | ||
467 | unsigned char y; | ||
468 | } psRc4Key_t; | ||
469 | #endif /* USE_ARC4 */ | ||
470 | /******************************************************************************/ | ||
471 | #ifdef USE_RC2 | ||
472 | typedef struct { | ||
473 | unsigned xkey[64]; | ||
474 | } psRc2Key_t; | ||
475 | |||
476 | typedef struct { | ||
477 | int32 blocklen; | ||
478 | unsigned char IV[8]; | ||
479 | psRc2Key_t key; | ||
480 | } rc2_CBC; | ||
481 | #endif /* USE_RC2 */ | ||
482 | /******************************************************************************/ | ||
483 | /* Universal types and defines */ | ||
484 | /******************************************************************************/ | ||
485 | #define MAXBLOCKSIZE 24 | ||
486 | |||
487 | typedef union { | ||
488 | #ifdef USE_RC2 | ||
489 | rc2_CBC rc2; | ||
490 | #endif | ||
491 | #ifdef USE_ARC4 | ||
492 | psRc4Key_t arc4; | ||
493 | #endif | ||
494 | #ifdef USE_3DES | ||
495 | des3_CBC des3; | ||
496 | #endif | ||
497 | #ifdef USE_AES | ||
498 | psAesCipher_t aes; | ||
499 | #endif | ||
500 | #ifdef USE_SEED | ||
501 | seed_CBC seed; | ||
502 | #endif | ||
503 | #ifdef USE_IDEA | ||
504 | idea_CBC idea; | ||
505 | #endif | ||
506 | } psCipherContext_t; | ||
507 | |||
508 | #define byte(x, n) (((x) >> (8 * (n))) & 255) | ||
509 | |||
510 | #endif /* _h_PS_SYMMETRIC */ | ||
511 | /******************************************************************************/ | ||
diff --git a/networking/traceroute.c b/networking/traceroute.c index a463b0faa..6817861ef 100644 --- a/networking/traceroute.c +++ b/networking/traceroute.c | |||
@@ -235,8 +235,6 @@ | |||
235 | //config: bool "Enable -I option (use ICMP instead of UDP)" | 235 | //config: bool "Enable -I option (use ICMP instead of UDP)" |
236 | //config: default y | 236 | //config: default y |
237 | //config: depends on TRACEROUTE || TRACEROUTE6 | 237 | //config: depends on TRACEROUTE || TRACEROUTE6 |
238 | //config: help | ||
239 | //config: Add option -I to use ICMP ECHO instead of UDP datagrams. | ||
240 | 238 | ||
241 | /* Needs socket(AF_INET, SOCK_RAW, IPPROTO_ICMP), therefore BB_SUID_MAYBE: */ | 239 | /* Needs socket(AF_INET, SOCK_RAW, IPPROTO_ICMP), therefore BB_SUID_MAYBE: */ |
242 | //applet:IF_TRACEROUTE(APPLET(traceroute, BB_DIR_USR_BIN, BB_SUID_MAYBE)) | 240 | //applet:IF_TRACEROUTE(APPLET(traceroute, BB_DIR_USR_BIN, BB_SUID_MAYBE)) |
diff --git a/networking/udhcp/Config.src b/networking/udhcp/Config.src index 7bc13a719..5c068441a 100644 --- a/networking/udhcp/Config.src +++ b/networking/udhcp/Config.src | |||
@@ -123,7 +123,7 @@ config UDHCP_DEBUG | |||
123 | are very verbose and useful for debugging only. | 123 | are very verbose and useful for debugging only. |
124 | 124 | ||
125 | config FEATURE_UDHCP_RFC3397 | 125 | config FEATURE_UDHCP_RFC3397 |
126 | bool "Support for RFC3397 domain search (experimental)" | 126 | bool "Support RFC3397 domain search (experimental)" |
127 | default y | 127 | default y |
128 | depends on UDHCPD || UDHCPC | 128 | depends on UDHCPD || UDHCPC |
129 | help | 129 | help |
@@ -132,7 +132,7 @@ config FEATURE_UDHCP_RFC3397 | |||
132 | and SIP servers option 120, specified in RFC 3361. | 132 | and SIP servers option 120, specified in RFC 3361. |
133 | 133 | ||
134 | config FEATURE_UDHCP_8021Q | 134 | config FEATURE_UDHCP_8021Q |
135 | bool "Support for 802.1Q VLAN parameters" | 135 | bool "Support 802.1Q VLAN parameters" |
136 | default y | 136 | default y |
137 | depends on UDHCPD || UDHCPC | 137 | depends on UDHCPD || UDHCPC |
138 | help | 138 | help |
diff --git a/networking/udhcp/common.c b/networking/udhcp/common.c index 1aaf5255c..420695a20 100644 --- a/networking/udhcp/common.c +++ b/networking/udhcp/common.c | |||
@@ -86,7 +86,7 @@ const struct dhcp_optflag dhcp_optflags[] = { | |||
86 | }; | 86 | }; |
87 | 87 | ||
88 | /* Used for converting options from incoming packets to env variables | 88 | /* Used for converting options from incoming packets to env variables |
89 | * for udhcpc stript, and for setting options for udhcpd via | 89 | * for udhcpc script, and for setting options for udhcpd via |
90 | * "opt OPTION_NAME OPTION_VALUE" directives in udhcpd.conf file. | 90 | * "opt OPTION_NAME OPTION_VALUE" directives in udhcpd.conf file. |
91 | */ | 91 | */ |
92 | /* Must match dhcp_optflags[] order */ | 92 | /* Must match dhcp_optflags[] order */ |
diff --git a/networking/udhcp/dumpleases.c b/networking/udhcp/dumpleases.c index d83344a8d..dce9084b3 100644 --- a/networking/udhcp/dumpleases.c +++ b/networking/udhcp/dumpleases.c | |||
@@ -11,7 +11,7 @@ | |||
11 | //usage:#define dumpleases_full_usage "\n\n" | 11 | //usage:#define dumpleases_full_usage "\n\n" |
12 | //usage: "Display DHCP leases granted by udhcpd\n" | 12 | //usage: "Display DHCP leases granted by udhcpd\n" |
13 | //usage: IF_LONG_OPTS( | 13 | //usage: IF_LONG_OPTS( |
14 | //usage: "\n -f,--file=FILE Lease file" | 14 | //usage: "\n -f,--file FILE Lease file" |
15 | //usage: "\n -r,--remaining Show remaining time" | 15 | //usage: "\n -r,--remaining Show remaining time" |
16 | //usage: "\n -a,--absolute Show expiration time" | 16 | //usage: "\n -a,--absolute Show expiration time" |
17 | //usage: "\n -d,--decimal Show time in seconds" | 17 | //usage: "\n -d,--decimal Show time in seconds" |
diff --git a/networking/wget.c b/networking/wget.c index 460b4b833..b9d840328 100644 --- a/networking/wget.c +++ b/networking/wget.c | |||
@@ -16,12 +16,15 @@ | |||
16 | //config: wget is a utility for non-interactive download of files from HTTP | 16 | //config: wget is a utility for non-interactive download of files from HTTP |
17 | //config: and FTP servers. | 17 | //config: and FTP servers. |
18 | //config: | 18 | //config: |
19 | //config:config FEATURE_WGET_LONG_OPTIONS | ||
20 | //config: bool "Enable long options" | ||
21 | //config: default y | ||
22 | //config: depends on WGET && LONG_OPTS | ||
23 | //config: | ||
19 | //config:config FEATURE_WGET_STATUSBAR | 24 | //config:config FEATURE_WGET_STATUSBAR |
20 | //config: bool "Enable a nifty process meter (+2k)" | 25 | //config: bool "Enable progress bar (+2k)" |
21 | //config: default y | 26 | //config: default y |
22 | //config: depends on WGET | 27 | //config: depends on WGET |
23 | //config: help | ||
24 | //config: Enable the transfer progress bar for wget transfers. | ||
25 | //config: | 28 | //config: |
26 | //config:config FEATURE_WGET_AUTHENTICATION | 29 | //config:config FEATURE_WGET_AUTHENTICATION |
27 | //config: bool "Enable HTTP authentication" | 30 | //config: bool "Enable HTTP authentication" |
@@ -30,13 +33,6 @@ | |||
30 | //config: help | 33 | //config: help |
31 | //config: Support authenticated HTTP transfers. | 34 | //config: Support authenticated HTTP transfers. |
32 | //config: | 35 | //config: |
33 | //config:config FEATURE_WGET_LONG_OPTIONS | ||
34 | //config: bool "Enable long options" | ||
35 | //config: default y | ||
36 | //config: depends on WGET && LONG_OPTS | ||
37 | //config: help | ||
38 | //config: Support long options for the wget applet. | ||
39 | //config: | ||
40 | //config:config FEATURE_WGET_TIMEOUT | 36 | //config:config FEATURE_WGET_TIMEOUT |
41 | //config: bool "Enable timeout option -T SEC" | 37 | //config: bool "Enable timeout option -T SEC" |
42 | //config: default y | 38 | //config: default y |
@@ -51,18 +47,59 @@ | |||
51 | //config: FEATURE_WGET_LONG_OPTIONS is also enabled, the --timeout option | 47 | //config: FEATURE_WGET_LONG_OPTIONS is also enabled, the --timeout option |
52 | //config: will work in addition to -T. | 48 | //config: will work in addition to -T. |
53 | //config: | 49 | //config: |
50 | //config:config FEATURE_WGET_HTTPS | ||
51 | //config: bool "Support HTTPS using internal TLS code" | ||
52 | //config: default y | ||
53 | //config: depends on WGET | ||
54 | //config: select TLS | ||
55 | //config: help | ||
56 | //config: wget will use internal TLS code to connect to https:// URLs. | ||
57 | //config: Note: | ||
58 | //config: On NOMMU machines, ssl_helper applet should be available | ||
59 | //config: in the $PATH for this to work. Make sure to select that applet. | ||
60 | //config: | ||
61 | //config: Note: currently, TLS code only makes TLS I/O work, it | ||
62 | //config: does *not* check that the peer is who it claims to be, etc. | ||
63 | //config: IOW: it uses peer-supplied public keys to establish encryption | ||
64 | //config: and signing keys, then encrypts and signs outgoing data and | ||
65 | //config: decrypts incoming data. | ||
66 | //config: It does not check signature hashes on the incoming data: | ||
67 | //config: this means that attackers manipulating TCP packets can | ||
68 | //config: send altered data and we unknowingly receive garbage. | ||
69 | //config: (This check might be relatively easy to add). | ||
70 | //config: It does not check public key's certificate: | ||
71 | //config: this means that the peer may be an attacker impersonating | ||
72 | //config: the server we think we are talking to. | ||
73 | //config: | ||
74 | //config: If you think this is unacceptable, consider this. As more and more | ||
75 | //config: servers switch to HTTPS-only operation, without such "crippled" | ||
76 | //config: TLS code it is *impossible* to simply download a kernel source | ||
77 | //config: from kernel.org. Which can in real world translate into | ||
78 | //config: "my small automatic tooling to build cross-compilers from sources | ||
79 | //config: no longer works, I need to additionally keep a local copy | ||
80 | //config: of ~4 megabyte source tarball of a SSL library and ~2 megabyte | ||
81 | //config: source of wget, need to compile and built both before I can | ||
82 | //config: download anything. All this despite the fact that the build | ||
83 | //config: is done in a QEMU sandbox on a machine with absolutely nothing | ||
84 | //config: worth stealing, so I don't care if someone would go to a lot | ||
85 | //config: of trouble to intercept my HTTPS download to send me an altered | ||
86 | //config: kernel tarball". | ||
87 | //config: | ||
88 | //config: If you still think this is unacceptable, send patches. | ||
89 | //config: | ||
90 | //config: If you still think this is unacceptable, do not want to send | ||
91 | //config: patches, but do want to waste bandwidth expaining how wrong | ||
92 | //config: it is, you will be ignored. | ||
93 | //config: | ||
54 | //config:config FEATURE_WGET_OPENSSL | 94 | //config:config FEATURE_WGET_OPENSSL |
55 | //config: bool "Try to connect to HTTPS using openssl" | 95 | //config: bool "Try to connect to HTTPS using openssl" |
56 | //config: default y | 96 | //config: default y |
57 | //config: depends on WGET | 97 | //config: depends on WGET |
58 | //config: help | 98 | //config: help |
59 | //config: Choose how wget establishes SSL connection for https:// URLs. | 99 | //config: Try to use openssl to handle HTTPS. |
60 | //config: | ||
61 | //config: Busybox itself contains no SSL code. wget will spawn | ||
62 | //config: a helper program to talk over HTTPS. | ||
63 | //config: | 100 | //config: |
64 | //config: OpenSSL has a simple SSL client for debug purposes. | 101 | //config: OpenSSL has a simple SSL client for debug purposes. |
65 | //config: If you select "openssl" helper, wget will effectively run: | 102 | //config: If you select this option, wget will effectively run: |
66 | //config: "openssl s_client -quiet -connect hostname:443 | 103 | //config: "openssl s_client -quiet -connect hostname:443 |
67 | //config: -servername hostname 2>/dev/null" and pipe its data | 104 | //config: -servername hostname 2>/dev/null" and pipe its data |
68 | //config: through it. -servername is not used if hostname is numeric. | 105 | //config: through it. -servername is not used if hostname is numeric. |
@@ -75,24 +112,9 @@ | |||
75 | //config: openssl is also a big binary, often dynamically linked | 112 | //config: openssl is also a big binary, often dynamically linked |
76 | //config: against ~15 libraries. | 113 | //config: against ~15 libraries. |
77 | //config: | 114 | //config: |
78 | //config:config FEATURE_WGET_SSL_HELPER | 115 | //config: If openssl can't be executed, internal TLS code will be used |
79 | //config: bool "Try to connect to HTTPS using ssl_helper" | 116 | //config: (if you enabled it); if openssl can be executed but fails later, |
80 | //config: default y | 117 | //config: wget can't detect this, and download will fail. |
81 | //config: depends on WGET | ||
82 | //config: help | ||
83 | //config: Choose how wget establishes SSL connection for https:// URLs. | ||
84 | //config: | ||
85 | //config: Busybox itself contains no SSL code. wget will spawn | ||
86 | //config: a helper program to talk over HTTPS. | ||
87 | //config: | ||
88 | //config: ssl_helper is a tool which can be built statically | ||
89 | //config: from busybox sources against a small embedded SSL library. | ||
90 | //config: Please see networking/ssl_helper/README. | ||
91 | //config: It does not require double host resolution and emits | ||
92 | //config: error messages to stderr. | ||
93 | //config: | ||
94 | //config: Precompiled static binary may be available at | ||
95 | //config: http://busybox.net/downloads/binaries/ | ||
96 | 118 | ||
97 | //applet:IF_WGET(APPLET(wget, BB_DIR_USR_BIN, BB_SUID_DROP)) | 119 | //applet:IF_WGET(APPLET(wget, BB_DIR_USR_BIN, BB_SUID_DROP)) |
98 | 120 | ||
@@ -105,20 +127,21 @@ | |||
105 | /* Since we ignore these opts, we don't show them in --help */ | 127 | /* Since we ignore these opts, we don't show them in --help */ |
106 | /* //usage: " [--no-check-certificate] [--no-cache] [--passive-ftp] [-t TRIES]" */ | 128 | /* //usage: " [--no-check-certificate] [--no-cache] [--passive-ftp] [-t TRIES]" */ |
107 | /* //usage: " [-nv] [-nc] [-nH] [-np]" */ | 129 | /* //usage: " [-nv] [-nc] [-nH] [-np]" */ |
108 | //usage: " [-U|--user-agent AGENT]" IF_FEATURE_WGET_TIMEOUT(" [-T SEC]") " URL..." | 130 | //usage: " [-S|--server-response] [-U|--user-agent AGENT]" IF_FEATURE_WGET_TIMEOUT(" [-T SEC]") " URL..." |
109 | //usage: ) | 131 | //usage: ) |
110 | //usage: IF_NOT_FEATURE_WGET_LONG_OPTIONS( | 132 | //usage: IF_NOT_FEATURE_WGET_LONG_OPTIONS( |
111 | //usage: "[-cq] [-O FILE] [-Y on/off] [-P DIR] [-U AGENT]" | 133 | //usage: "[-cq] [-O FILE] [-Y on/off] [-P DIR] [-S] [-U AGENT]" |
112 | //usage: IF_FEATURE_WGET_TIMEOUT(" [-T SEC]") " URL..." | 134 | //usage: IF_FEATURE_WGET_TIMEOUT(" [-T SEC]") " URL..." |
113 | //usage: ) | 135 | //usage: ) |
114 | //usage:#define wget_full_usage "\n\n" | 136 | //usage:#define wget_full_usage "\n\n" |
115 | //usage: "Retrieve files via HTTP or FTP\n" | 137 | //usage: "Retrieve files via HTTP or FTP\n" |
116 | //usage: IF_FEATURE_WGET_LONG_OPTIONS( | 138 | //usage: IF_FEATURE_WGET_LONG_OPTIONS( |
117 | //usage: "\n --spider Spider mode - only check file existence" | 139 | //usage: "\n --spider Only check URL existence: $? is 0 if exists" |
118 | //usage: ) | 140 | //usage: ) |
119 | //usage: "\n -c Continue retrieval of aborted transfer" | 141 | //usage: "\n -c Continue retrieval of aborted transfer" |
120 | //usage: "\n -q Quiet" | 142 | //usage: "\n -q Quiet" |
121 | //usage: "\n -P DIR Save to DIR (default .)" | 143 | //usage: "\n -P DIR Save to DIR (default .)" |
144 | //usage: "\n -S Show server response" | ||
122 | //usage: IF_FEATURE_WGET_TIMEOUT( | 145 | //usage: IF_FEATURE_WGET_TIMEOUT( |
123 | //usage: "\n -T SEC Network read timeout is SEC seconds" | 146 | //usage: "\n -T SEC Network read timeout is SEC seconds" |
124 | //usage: ) | 147 | //usage: ) |
@@ -141,6 +164,8 @@ | |||
141 | #endif | 164 | #endif |
142 | 165 | ||
143 | 166 | ||
167 | #define SSL_SUPPORTED (ENABLE_FEATURE_WGET_OPENSSL || ENABLE_FEATURE_WGET_HTTPS) | ||
168 | |||
144 | struct host_info { | 169 | struct host_info { |
145 | char *allocated; | 170 | char *allocated; |
146 | const char *path; | 171 | const char *path; |
@@ -151,7 +176,7 @@ struct host_info { | |||
151 | }; | 176 | }; |
152 | static const char P_FTP[] ALIGN1 = "ftp"; | 177 | static const char P_FTP[] ALIGN1 = "ftp"; |
153 | static const char P_HTTP[] ALIGN1 = "http"; | 178 | static const char P_HTTP[] ALIGN1 = "http"; |
154 | #if ENABLE_FEATURE_WGET_OPENSSL || ENABLE_FEATURE_WGET_SSL_HELPER | 179 | #if SSL_SUPPORTED |
155 | static const char P_HTTPS[] ALIGN1 = "https"; | 180 | static const char P_HTTPS[] ALIGN1 = "https"; |
156 | #endif | 181 | #endif |
157 | 182 | ||
@@ -232,16 +257,17 @@ struct globals { | |||
232 | enum { | 257 | enum { |
233 | WGET_OPT_CONTINUE = (1 << 0), | 258 | WGET_OPT_CONTINUE = (1 << 0), |
234 | WGET_OPT_QUIET = (1 << 1), | 259 | WGET_OPT_QUIET = (1 << 1), |
235 | WGET_OPT_OUTNAME = (1 << 2), | 260 | WGET_OPT_SERVER_RESPONSE = (1 << 2), |
236 | WGET_OPT_PREFIX = (1 << 3), | 261 | WGET_OPT_OUTNAME = (1 << 3), |
237 | WGET_OPT_PROXY = (1 << 4), | 262 | WGET_OPT_PREFIX = (1 << 4), |
238 | WGET_OPT_USER_AGENT = (1 << 5), | 263 | WGET_OPT_PROXY = (1 << 5), |
239 | WGET_OPT_NETWORK_READ_TIMEOUT = (1 << 6), | 264 | WGET_OPT_USER_AGENT = (1 << 6), |
240 | WGET_OPT_RETRIES = (1 << 7), | 265 | WGET_OPT_NETWORK_READ_TIMEOUT = (1 << 7), |
241 | WGET_OPT_nsomething = (1 << 8), | 266 | WGET_OPT_RETRIES = (1 << 8), |
242 | WGET_OPT_HEADER = (1 << 9) * ENABLE_FEATURE_WGET_LONG_OPTIONS, | 267 | WGET_OPT_nsomething = (1 << 9), |
243 | WGET_OPT_POST_DATA = (1 << 10) * ENABLE_FEATURE_WGET_LONG_OPTIONS, | 268 | WGET_OPT_HEADER = (1 << 10) * ENABLE_FEATURE_WGET_LONG_OPTIONS, |
244 | WGET_OPT_SPIDER = (1 << 11) * ENABLE_FEATURE_WGET_LONG_OPTIONS, | 269 | WGET_OPT_POST_DATA = (1 << 11) * ENABLE_FEATURE_WGET_LONG_OPTIONS, |
270 | WGET_OPT_SPIDER = (1 << 12) * ENABLE_FEATURE_WGET_LONG_OPTIONS, | ||
245 | }; | 271 | }; |
246 | 272 | ||
247 | enum { | 273 | enum { |
@@ -395,7 +421,7 @@ static FILE *open_socket(len_and_sockaddr *lsa) | |||
395 | } | 421 | } |
396 | 422 | ||
397 | /* Returns '\n' if it was seen, else '\0'. Trims at first '\r' or '\n' */ | 423 | /* Returns '\n' if it was seen, else '\0'. Trims at first '\r' or '\n' */ |
398 | static char fgets_and_trim(FILE *fp) | 424 | static char fgets_and_trim(FILE *fp, const char *fmt) |
399 | { | 425 | { |
400 | char c; | 426 | char c; |
401 | char *buf_ptr; | 427 | char *buf_ptr; |
@@ -413,6 +439,9 @@ static char fgets_and_trim(FILE *fp) | |||
413 | 439 | ||
414 | log_io("< %s", G.wget_buf); | 440 | log_io("< %s", G.wget_buf); |
415 | 441 | ||
442 | if (fmt && (option_mask32 & WGET_OPT_SERVER_RESPONSE)) | ||
443 | fprintf(stderr, fmt, G.wget_buf); | ||
444 | |||
416 | return c; | 445 | return c; |
417 | } | 446 | } |
418 | 447 | ||
@@ -423,6 +452,9 @@ static int ftpcmd(const char *s1, const char *s2, FILE *fp) | |||
423 | if (!s2) | 452 | if (!s2) |
424 | s2 = ""; | 453 | s2 = ""; |
425 | fprintf(fp, "%s%s\r\n", s1, s2); | 454 | fprintf(fp, "%s%s\r\n", s1, s2); |
455 | /* With --server-response, wget also shows its ftp commands */ | ||
456 | if (option_mask32 & WGET_OPT_SERVER_RESPONSE) | ||
457 | fprintf(stderr, "--> %s%s\n\n", s1, s2); | ||
426 | fflush(fp); | 458 | fflush(fp); |
427 | log_io("> %s%s", s1, s2); | 459 | log_io("> %s%s", s1, s2); |
428 | #if ENABLE_PLATFORM_MINGW32 | 460 | #if ENABLE_PLATFORM_MINGW32 |
@@ -431,7 +463,7 @@ static int ftpcmd(const char *s1, const char *s2, FILE *fp) | |||
431 | } | 463 | } |
432 | 464 | ||
433 | do { | 465 | do { |
434 | fgets_and_trim(fp); | 466 | fgets_and_trim(fp, "%s\n"); |
435 | } while (!isdigit(G.wget_buf[0]) || G.wget_buf[3] != ' '); | 467 | } while (!isdigit(G.wget_buf[0]) || G.wget_buf[3] != ' '); |
436 | #if ENABLE_PLATFORM_MINGW32 | 468 | #if ENABLE_PLATFORM_MINGW32 |
437 | fseek(fp, 0L, SEEK_CUR); | 469 | fseek(fp, 0L, SEEK_CUR); |
@@ -458,7 +490,7 @@ static void parse_url(const char *src_url, struct host_info *h) | |||
458 | if (strcmp(url, P_FTP) == 0) { | 490 | if (strcmp(url, P_FTP) == 0) { |
459 | h->port = bb_lookup_port(P_FTP, "tcp", 21); | 491 | h->port = bb_lookup_port(P_FTP, "tcp", 21); |
460 | } else | 492 | } else |
461 | #if ENABLE_FEATURE_WGET_OPENSSL || ENABLE_FEATURE_WGET_SSL_HELPER | 493 | #if SSL_SUPPORTED |
462 | if (strcmp(url, P_HTTPS) == 0) { | 494 | if (strcmp(url, P_HTTPS) == 0) { |
463 | h->port = bb_lookup_port(P_HTTPS, "tcp", 443); | 495 | h->port = bb_lookup_port(P_HTTPS, "tcp", 443); |
464 | h->protocol = P_HTTPS; | 496 | h->protocol = P_HTTPS; |
@@ -480,7 +512,7 @@ static void parse_url(const char *src_url, struct host_info *h) | |||
480 | 512 | ||
481 | // FYI: | 513 | // FYI: |
482 | // "Real" wget 'http://busybox.net?var=a/b' sends this request: | 514 | // "Real" wget 'http://busybox.net?var=a/b' sends this request: |
483 | // 'GET /?var=a/b HTTP 1.0' | 515 | // 'GET /?var=a/b HTTP/1.0' |
484 | // and saves 'index.html?var=a%2Fb' (we save 'b') | 516 | // and saves 'index.html?var=a%2Fb' (we save 'b') |
485 | // wget 'http://busybox.net?login=john@doe': | 517 | // wget 'http://busybox.net?login=john@doe': |
486 | // request: 'GET /?login=john@doe HTTP/1.0' | 518 | // request: 'GET /?login=john@doe HTTP/1.0' |
@@ -531,7 +563,7 @@ static char *gethdr(FILE *fp) | |||
531 | int c; | 563 | int c; |
532 | 564 | ||
533 | /* retrieve header line */ | 565 | /* retrieve header line */ |
534 | c = fgets_and_trim(fp); | 566 | c = fgets_and_trim(fp, " %s\n"); |
535 | 567 | ||
536 | /* end of the headers? */ | 568 | /* end of the headers? */ |
537 | if (G.wget_buf[0] == '\0') | 569 | if (G.wget_buf[0] == '\0') |
@@ -665,7 +697,7 @@ static int spawn_https_helper_openssl(const char *host, unsigned port) | |||
665 | char *servername; | 697 | char *servername; |
666 | int sp[2]; | 698 | int sp[2]; |
667 | int pid; | 699 | int pid; |
668 | IF_FEATURE_WGET_SSL_HELPER(volatile int child_failed = 0;) | 700 | IF_FEATURE_WGET_HTTPS(volatile int child_failed = 0;) |
669 | 701 | ||
670 | if (socketpair(AF_UNIX, SOCK_STREAM, 0, sp) != 0) | 702 | if (socketpair(AF_UNIX, SOCK_STREAM, 0, sp) != 0) |
671 | /* Kernel can have AF_UNIX support disabled */ | 703 | /* Kernel can have AF_UNIX support disabled */ |
@@ -710,7 +742,7 @@ static int spawn_https_helper_openssl(const char *host, unsigned port) | |||
710 | 742 | ||
711 | BB_EXECVP(argv[0], argv); | 743 | BB_EXECVP(argv[0], argv); |
712 | xmove_fd(3, 2); | 744 | xmove_fd(3, 2); |
713 | # if ENABLE_FEATURE_WGET_SSL_HELPER | 745 | # if ENABLE_FEATURE_WGET_HTTPS |
714 | child_failed = 1; | 746 | child_failed = 1; |
715 | xfunc_die(); | 747 | xfunc_die(); |
716 | # else | 748 | # else |
@@ -723,7 +755,7 @@ static int spawn_https_helper_openssl(const char *host, unsigned port) | |||
723 | free(servername); | 755 | free(servername); |
724 | free(allocated); | 756 | free(allocated); |
725 | close(sp[1]); | 757 | close(sp[1]); |
726 | # if ENABLE_FEATURE_WGET_SSL_HELPER | 758 | # if ENABLE_FEATURE_WGET_HTTPS |
727 | if (child_failed) { | 759 | if (child_failed) { |
728 | close(sp[0]); | 760 | close(sp[0]); |
729 | return -1; | 761 | return -1; |
@@ -733,38 +765,51 @@ static int spawn_https_helper_openssl(const char *host, unsigned port) | |||
733 | } | 765 | } |
734 | #endif | 766 | #endif |
735 | 767 | ||
736 | /* See networking/ssl_helper/README how to build one */ | 768 | #if ENABLE_FEATURE_WGET_HTTPS |
737 | #if ENABLE_FEATURE_WGET_SSL_HELPER | 769 | static void spawn_ssl_client(const char *host, int network_fd) |
738 | static void spawn_https_helper_small(int network_fd) | ||
739 | { | 770 | { |
740 | int sp[2]; | 771 | int sp[2]; |
741 | int pid; | 772 | int pid; |
773 | char *servername, *p; | ||
774 | |||
775 | servername = xstrdup(host); | ||
776 | p = strrchr(servername, ':'); | ||
777 | if (p) *p = '\0'; | ||
742 | 778 | ||
743 | if (socketpair(AF_UNIX, SOCK_STREAM, 0, sp) != 0) | 779 | if (socketpair(AF_UNIX, SOCK_STREAM, 0, sp) != 0) |
744 | /* Kernel can have AF_UNIX support disabled */ | 780 | /* Kernel can have AF_UNIX support disabled */ |
745 | bb_perror_msg_and_die("socketpair"); | 781 | bb_perror_msg_and_die("socketpair"); |
746 | 782 | ||
783 | fflush_all(); | ||
747 | pid = BB_MMU ? xfork() : xvfork(); | 784 | pid = BB_MMU ? xfork() : xvfork(); |
748 | if (pid == 0) { | 785 | if (pid == 0) { |
749 | /* Child */ | 786 | /* Child */ |
750 | char *argv[3]; | ||
751 | |||
752 | close(sp[0]); | 787 | close(sp[0]); |
753 | xmove_fd(sp[1], 0); | 788 | xmove_fd(sp[1], 0); |
754 | xdup2(0, 1); | 789 | xdup2(0, 1); |
755 | xmove_fd(network_fd, 3); | 790 | if (BB_MMU) { |
756 | /* | 791 | tls_state_t *tls = new_tls_state(); |
757 | * A simple ssl/tls helper | 792 | tls->ifd = tls->ofd = network_fd; |
758 | */ | 793 | tls_handshake(tls, servername); |
759 | argv[0] = (char*)"ssl_helper"; | 794 | tls_run_copy_loop(tls); |
760 | argv[1] = (char*)"-d3"; | 795 | exit(0); |
761 | argv[2] = NULL; | 796 | } else { |
762 | BB_EXECVP(argv[0], argv); | 797 | char *argv[5]; |
763 | bb_perror_msg_and_die("can't execute '%s'", argv[0]); | 798 | xmove_fd(network_fd, 3); |
799 | argv[0] = (char*)"ssl_client"; | ||
800 | argv[1] = (char*)"-s3"; | ||
801 | //TODO: if (!is_ip_address(servername))... | ||
802 | argv[2] = (char*)"-n"; | ||
803 | argv[3] = servername; | ||
804 | argv[4] = NULL; | ||
805 | BB_EXECVP(argv[0], argv); | ||
806 | bb_perror_msg_and_die("can't execute '%s'", argv[0]); | ||
807 | } | ||
764 | /* notreached */ | 808 | /* notreached */ |
765 | } | 809 | } |
766 | 810 | ||
767 | /* Parent */ | 811 | /* Parent */ |
812 | free(servername); | ||
768 | close(sp[1]); | 813 | close(sp[1]); |
769 | xmove_fd(sp[0], network_fd); | 814 | xmove_fd(sp[0], network_fd); |
770 | } | 815 | } |
@@ -886,9 +931,9 @@ static void NOINLINE retrieve_file_data(FILE *dfp) | |||
886 | if (!G.chunked) | 931 | if (!G.chunked) |
887 | break; | 932 | break; |
888 | 933 | ||
889 | fgets_and_trim(dfp); /* Eat empty line */ | 934 | fgets_and_trim(dfp, NULL); /* Eat empty line */ |
890 | get_clen: | 935 | get_clen: |
891 | fgets_and_trim(dfp); | 936 | fgets_and_trim(dfp, NULL); |
892 | G.content_len = STRTOOFF(G.wget_buf, NULL, 16); | 937 | G.content_len = STRTOOFF(G.wget_buf, NULL, 16); |
893 | /* FIXME: error check? */ | 938 | /* FIXME: error check? */ |
894 | if (G.content_len == 0) | 939 | if (G.content_len == 0) |
@@ -1013,16 +1058,16 @@ static void download_one_url(const char *url) | |||
1013 | 1058 | ||
1014 | /* Open socket to http(s) server */ | 1059 | /* Open socket to http(s) server */ |
1015 | #if ENABLE_FEATURE_WGET_OPENSSL | 1060 | #if ENABLE_FEATURE_WGET_OPENSSL |
1016 | /* openssl (and maybe ssl_helper) support is configured */ | 1061 | /* openssl (and maybe internal TLS) support is configured */ |
1017 | if (target.protocol == P_HTTPS) { | 1062 | if (target.protocol == P_HTTPS) { |
1018 | /* openssl-based helper | 1063 | /* openssl-based helper |
1019 | * Inconvenient API since we can't give it an open fd | 1064 | * Inconvenient API since we can't give it an open fd |
1020 | */ | 1065 | */ |
1021 | int fd = spawn_https_helper_openssl(server.host, server.port); | 1066 | int fd = spawn_https_helper_openssl(server.host, server.port); |
1022 | # if ENABLE_FEATURE_WGET_SSL_HELPER | 1067 | # if ENABLE_FEATURE_WGET_HTTPS |
1023 | if (fd < 0) { /* no openssl? try ssl_helper */ | 1068 | if (fd < 0) { /* no openssl? try internal */ |
1024 | sfp = open_socket(lsa); | 1069 | sfp = open_socket(lsa); |
1025 | spawn_https_helper_small(fileno(sfp)); | 1070 | spawn_ssl_client(server.host, fileno(sfp)); |
1026 | goto socket_opened; | 1071 | goto socket_opened; |
1027 | } | 1072 | } |
1028 | # else | 1073 | # else |
@@ -1035,11 +1080,11 @@ static void download_one_url(const char *url) | |||
1035 | } | 1080 | } |
1036 | sfp = open_socket(lsa); | 1081 | sfp = open_socket(lsa); |
1037 | socket_opened: | 1082 | socket_opened: |
1038 | #elif ENABLE_FEATURE_WGET_SSL_HELPER | 1083 | #elif ENABLE_FEATURE_WGET_HTTPS |
1039 | /* Only ssl_helper support is configured */ | 1084 | /* Only internal TLS support is configured */ |
1040 | sfp = open_socket(lsa); | 1085 | sfp = open_socket(lsa); |
1041 | if (target.protocol == P_HTTPS) | 1086 | if (target.protocol == P_HTTPS) |
1042 | spawn_https_helper_small(fileno(sfp)); | 1087 | spawn_ssl_client(server.host, fileno(sfp)); |
1043 | #else | 1088 | #else |
1044 | /* ssl (https) support is not configured */ | 1089 | /* ssl (https) support is not configured */ |
1045 | sfp = open_socket(lsa); | 1090 | sfp = open_socket(lsa); |
@@ -1099,18 +1144,26 @@ static void download_one_url(const char *url) | |||
1099 | } | 1144 | } |
1100 | 1145 | ||
1101 | fflush(sfp); | 1146 | fflush(sfp); |
1102 | /* If we use SSL helper, keeping our end of the socket open for writing | 1147 | |
1103 | * makes our end (i.e. the same fd!) readable (EAGAIN instead of EOF) | 1148 | /* Tried doing this unconditionally. |
1104 | * even after child closes its copy of the fd. | 1149 | * Cloudflare and nginx/1.11.5 are shocked to see SHUT_WR on non-HTTPS. |
1105 | * This helps: | 1150 | */ |
1106 | */ | 1151 | #if SSL_SUPPORTED |
1107 | shutdown(fileno(sfp), SHUT_WR); | 1152 | if (target.protocol == P_HTTPS) { |
1153 | /* If we use SSL helper, keeping our end of the socket open for writing | ||
1154 | * makes our end (i.e. the same fd!) readable (EAGAIN instead of EOF) | ||
1155 | * even after child closes its copy of the fd. | ||
1156 | * This helps: | ||
1157 | */ | ||
1158 | shutdown(fileno(sfp), SHUT_WR); | ||
1159 | } | ||
1160 | #endif | ||
1108 | 1161 | ||
1109 | /* | 1162 | /* |
1110 | * Retrieve HTTP response line and check for "200" status code. | 1163 | * Retrieve HTTP response line and check for "200" status code. |
1111 | */ | 1164 | */ |
1112 | read_response: | 1165 | read_response: |
1113 | fgets_and_trim(sfp); | 1166 | fgets_and_trim(sfp, " %s\n"); |
1114 | 1167 | ||
1115 | str = G.wget_buf; | 1168 | str = G.wget_buf; |
1116 | str = skip_non_whitespace(str); | 1169 | str = skip_non_whitespace(str); |
@@ -1295,6 +1348,7 @@ int wget_main(int argc UNUSED_PARAM, char **argv) | |||
1295 | /* name, has_arg, val */ | 1348 | /* name, has_arg, val */ |
1296 | "continue\0" No_argument "c" | 1349 | "continue\0" No_argument "c" |
1297 | "quiet\0" No_argument "q" | 1350 | "quiet\0" No_argument "q" |
1351 | "server-response\0" No_argument "S" | ||
1298 | "output-document\0" Required_argument "O" | 1352 | "output-document\0" Required_argument "O" |
1299 | "directory-prefix\0" Required_argument "P" | 1353 | "directory-prefix\0" Required_argument "P" |
1300 | "proxy\0" Required_argument "Y" | 1354 | "proxy\0" Required_argument "Y" |
@@ -1337,7 +1391,7 @@ IF_DESKTOP( "no-parent\0" No_argument "\xf0") | |||
1337 | #endif | 1391 | #endif |
1338 | opt_complementary = "-1" /* at least one URL */ | 1392 | opt_complementary = "-1" /* at least one URL */ |
1339 | IF_FEATURE_WGET_LONG_OPTIONS(":\xff::"); /* --header is a list */ | 1393 | IF_FEATURE_WGET_LONG_OPTIONS(":\xff::"); /* --header is a list */ |
1340 | getopt32(argv, "cqO:P:Y:U:T:+" | 1394 | getopt32(argv, "cqSO:P:Y:U:T:+" |
1341 | /*ignored:*/ "t:" | 1395 | /*ignored:*/ "t:" |
1342 | /*ignored:*/ "n::" | 1396 | /*ignored:*/ "n::" |
1343 | /* wget has exactly four -n<letter> opts, all of which we can ignore: | 1397 | /* wget has exactly four -n<letter> opts, all of which we can ignore: |
diff --git a/printutils/lpr.c b/printutils/lpr.c index ed6a84a93..8cc87d167 100644 --- a/printutils/lpr.c +++ b/printutils/lpr.c | |||
@@ -23,6 +23,7 @@ | |||
23 | //config: help | 23 | //config: help |
24 | //config: lpq is a print spool queue examination and manipulation program. | 24 | //config: lpq is a print spool queue examination and manipulation program. |
25 | 25 | ||
26 | // APPLET_ODDNAME:name main location suid_type help | ||
26 | //applet:IF_LPQ(APPLET_ODDNAME(lpq, lpqr, BB_DIR_USR_BIN, BB_SUID_DROP, lpq)) | 27 | //applet:IF_LPQ(APPLET_ODDNAME(lpq, lpqr, BB_DIR_USR_BIN, BB_SUID_DROP, lpq)) |
27 | //applet:IF_LPR(APPLET_ODDNAME(lpr, lpqr, BB_DIR_USR_BIN, BB_SUID_DROP, lpr)) | 28 | //applet:IF_LPR(APPLET_ODDNAME(lpr, lpqr, BB_DIR_USR_BIN, BB_SUID_DROP, lpr)) |
28 | 29 | ||
diff --git a/procps/Config.src b/procps/Config.src index eb4760752..35fef2eda 100644 --- a/procps/Config.src +++ b/procps/Config.src | |||
@@ -8,7 +8,7 @@ menu "Process Utilities" | |||
8 | INSERT | 8 | INSERT |
9 | 9 | ||
10 | config FEATURE_SHOW_THREADS | 10 | config FEATURE_SHOW_THREADS |
11 | bool "Support for showing threads in ps/pstree/top" | 11 | bool "Support thread display in ps/pstree/top" |
12 | default y | 12 | default y |
13 | depends on PS || TOP || PSTREE | 13 | depends on PS || TOP || PSTREE |
14 | help | 14 | help |
diff --git a/procps/Kbuild.src b/procps/Kbuild.src index e7adc7340..6b4fb7470 100644 --- a/procps/Kbuild.src +++ b/procps/Kbuild.src | |||
@@ -7,7 +7,3 @@ | |||
7 | lib-y:= | 7 | lib-y:= |
8 | 8 | ||
9 | INSERT | 9 | INSERT |
10 | |||
11 | lib-$(CONFIG_ASH) += kill.o # used for built-in kill by ash | ||
12 | lib-$(CONFIG_SH_IS_ASH) += kill.o # used for built-in kill by ash | ||
13 | lib-$(CONFIG_BASH_IS_ASH) += kill.o # used for built-in kill by ash | ||
diff --git a/procps/kill.c b/procps/kill.c index 57a33bcaa..7ae5beead 100644 --- a/procps/kill.c +++ b/procps/kill.c | |||
@@ -33,7 +33,8 @@ | |||
33 | //config: the script it was called from. | 33 | //config: the script it was called from. |
34 | 34 | ||
35 | //applet:IF_KILL(APPLET(kill, BB_DIR_BIN, BB_SUID_DROP)) | 35 | //applet:IF_KILL(APPLET(kill, BB_DIR_BIN, BB_SUID_DROP)) |
36 | //applet:IF_KILLALL(APPLET_ODDNAME(killall, kill, BB_DIR_USR_BIN, BB_SUID_DROP, killall)) | 36 | // APPLET_ODDNAME:name main location suid_type help |
37 | //applet:IF_KILLALL( APPLET_ODDNAME(killall, kill, BB_DIR_USR_BIN, BB_SUID_DROP, killall)) | ||
37 | //applet:IF_KILLALL5(APPLET_ODDNAME(killall5, kill, BB_DIR_USR_SBIN, BB_SUID_DROP, killall5)) | 38 | //applet:IF_KILLALL5(APPLET_ODDNAME(killall5, kill, BB_DIR_USR_SBIN, BB_SUID_DROP, killall5)) |
38 | 39 | ||
39 | //kbuild:lib-$(CONFIG_KILL) += kill.o | 40 | //kbuild:lib-$(CONFIG_KILL) += kill.o |
@@ -92,28 +93,34 @@ | |||
92 | * This is needed to avoid collision with kill -9 ... syntax | 93 | * This is needed to avoid collision with kill -9 ... syntax |
93 | */ | 94 | */ |
94 | 95 | ||
96 | //kbuild:lib-$(CONFIG_ASH_JOB_CONTROL) += kill.o | ||
97 | //kbuild:lib-$(CONFIG_HUSH_KILL) += kill.o | ||
98 | |||
99 | #define SH_KILL (ENABLE_ASH_JOB_CONTROL || ENABLE_HUSH_KILL) | ||
100 | /* If shells want to have "kill", for ifdefs it's like ENABLE_KILL=1 */ | ||
101 | #if SH_KILL | ||
102 | # undef ENABLE_KILL | ||
103 | # define ENABLE_KILL 1 | ||
104 | #endif | ||
105 | #define KILL_APPLET_CNT (ENABLE_KILL + ENABLE_KILLALL + ENABLE_KILLALL5) | ||
106 | |||
95 | int kill_main(int argc UNUSED_PARAM, char **argv) | 107 | int kill_main(int argc UNUSED_PARAM, char **argv) |
96 | { | 108 | { |
97 | char *arg; | 109 | char *arg; |
98 | pid_t pid; | 110 | pid_t pid; |
99 | int signo = SIGTERM, errors = 0, quiet = 0; | 111 | int signo = SIGTERM, errors = 0, quiet = 0; |
100 | #if ENABLE_KILL && !ENABLE_KILLALL && !ENABLE_KILLALL5 | 112 | |
101 | # define killall 0 | 113 | #if KILL_APPLET_CNT == 1 |
102 | # define killall5 0 | 114 | # define is_killall ENABLE_KILLALL |
103 | #elif !ENABLE_KILL && ENABLE_KILLALL && !ENABLE_KILLALL5 | 115 | # define is_killall5 ENABLE_KILLALL5 |
104 | # define killall 1 | ||
105 | # define killall5 0 | ||
106 | #elif !ENABLE_KILL && !ENABLE_KILLALL && ENABLE_KILLALL5 | ||
107 | # define killall 0 | ||
108 | # define killall5 1 | ||
109 | #else | 116 | #else |
110 | /* How to determine who we are? find 3rd char from the end: | 117 | /* How to determine who we are? find 3rd char from the end: |
111 | * kill, killall, killall5 | 118 | * kill, killall, killall5 |
112 | * ^i ^a ^l - it's unique | 119 | * ^i ^a ^l - it's unique |
113 | * (checking from the start is complicated by /bin/kill... case) */ | 120 | * (checking from the start is complicated by /bin/kill... case) */ |
114 | const char char3 = argv[0][strlen(argv[0]) - 3]; | 121 | const char char3 = argv[0][strlen(argv[0]) - 3]; |
115 | # define killall (ENABLE_KILLALL && char3 == 'a') | 122 | # define is_killall (ENABLE_KILLALL && char3 == 'a') |
116 | # define killall5 (ENABLE_KILLALL5 && char3 == 'l') | 123 | # define is_killall5 (ENABLE_KILLALL5 && char3 == 'l') |
117 | #endif | 124 | #endif |
118 | 125 | ||
119 | /* Parse any options */ | 126 | /* Parse any options */ |
@@ -162,7 +169,7 @@ int kill_main(int argc UNUSED_PARAM, char **argv) | |||
162 | } | 169 | } |
163 | 170 | ||
164 | /* The -q quiet option */ | 171 | /* The -q quiet option */ |
165 | if (killall && arg[1] == 'q' && arg[2] == '\0') { | 172 | if (is_killall && arg[1] == 'q' && arg[2] == '\0') { |
166 | quiet = 1; | 173 | quiet = 1; |
167 | arg = *++argv; | 174 | arg = *++argv; |
168 | if (!arg) | 175 | if (!arg) |
@@ -174,7 +181,7 @@ int kill_main(int argc UNUSED_PARAM, char **argv) | |||
174 | arg++; /* skip '-' */ | 181 | arg++; /* skip '-' */ |
175 | 182 | ||
176 | /* -o PID? (if present, it always is at the end of command line) */ | 183 | /* -o PID? (if present, it always is at the end of command line) */ |
177 | if (killall5 && arg[0] == 'o') | 184 | if (is_killall5 && arg[0] == 'o') |
178 | goto do_it_now; | 185 | goto do_it_now; |
179 | 186 | ||
180 | if (argv[1] && arg[0] == 's' && arg[1] == '\0') { /* -s SIG? */ | 187 | if (argv[1] && arg[0] == 's' && arg[1] == '\0') { /* -s SIG? */ |
@@ -190,7 +197,7 @@ int kill_main(int argc UNUSED_PARAM, char **argv) | |||
190 | do_it_now: | 197 | do_it_now: |
191 | pid = getpid(); | 198 | pid = getpid(); |
192 | 199 | ||
193 | if (killall5) { | 200 | if (is_killall5) { |
194 | pid_t sid; | 201 | pid_t sid; |
195 | procps_status_t* p = NULL; | 202 | procps_status_t* p = NULL; |
196 | /* compat: exitcode 2 is "no one was signaled" */ | 203 | /* compat: exitcode 2 is "no one was signaled" */ |
@@ -248,13 +255,14 @@ int kill_main(int argc UNUSED_PARAM, char **argv) | |||
248 | return ret; | 255 | return ret; |
249 | } | 256 | } |
250 | 257 | ||
258 | #if ENABLE_KILL || ENABLE_KILLALL | ||
251 | /* Pid or name is required for kill/killall */ | 259 | /* Pid or name is required for kill/killall */ |
252 | if (!arg) { | 260 | if (!arg) { |
253 | bb_error_msg("you need to specify whom to kill"); | 261 | bb_error_msg("you need to specify whom to kill"); |
254 | return EXIT_FAILURE; | 262 | return EXIT_FAILURE; |
255 | } | 263 | } |
256 | 264 | ||
257 | if (killall) { | 265 | if (!ENABLE_KILL || is_killall) { |
258 | /* Looks like they want to do a killall. Do that */ | 266 | /* Looks like they want to do a killall. Do that */ |
259 | do { | 267 | do { |
260 | pid_t* pidList; | 268 | pid_t* pidList; |
@@ -282,10 +290,12 @@ int kill_main(int argc UNUSED_PARAM, char **argv) | |||
282 | } while (arg); | 290 | } while (arg); |
283 | return errors; | 291 | return errors; |
284 | } | 292 | } |
293 | #endif | ||
285 | 294 | ||
295 | #if ENABLE_KILL | ||
286 | /* Looks like they want to do a kill. Do that */ | 296 | /* Looks like they want to do a kill. Do that */ |
287 | while (arg) { | 297 | while (arg) { |
288 | #if ENABLE_ASH || ENABLE_HUSH | 298 | # if SH_KILL |
289 | /* | 299 | /* |
290 | * We need to support shell's "hack formats" of | 300 | * We need to support shell's "hack formats" of |
291 | * " -PRGP_ID" (yes, with a leading space) | 301 | * " -PRGP_ID" (yes, with a leading space) |
@@ -307,7 +317,7 @@ int kill_main(int argc UNUSED_PARAM, char **argv) | |||
307 | } | 317 | } |
308 | arg = end; /* can only point to ' ' or '\0' now */ | 318 | arg = end; /* can only point to ' ' or '\0' now */ |
309 | } | 319 | } |
310 | #else | 320 | # else /* ENABLE_KILL but !SH_KILL */ |
311 | pid = bb_strtoi(arg, NULL, 10); | 321 | pid = bb_strtoi(arg, NULL, 10); |
312 | if (errno) { | 322 | if (errno) { |
313 | bb_error_msg("invalid number '%s'", arg); | 323 | bb_error_msg("invalid number '%s'", arg); |
@@ -316,8 +326,9 @@ int kill_main(int argc UNUSED_PARAM, char **argv) | |||
316 | bb_perror_msg("can't kill pid %d", (int)pid); | 326 | bb_perror_msg("can't kill pid %d", (int)pid); |
317 | errors++; | 327 | errors++; |
318 | } | 328 | } |
319 | #endif | 329 | # endif |
320 | arg = *++argv; | 330 | arg = *++argv; |
321 | } | 331 | } |
322 | return errors; | 332 | return errors; |
333 | #endif | ||
323 | } | 334 | } |
diff --git a/procps/nmeter.c b/procps/nmeter.c index 3eac2d3b2..05bf0a08c 100644 --- a/procps/nmeter.c +++ b/procps/nmeter.c | |||
@@ -24,7 +24,7 @@ | |||
24 | //usage: "\n -d MSEC Milliseconds between updates, default:1000, none:-1" | 24 | //usage: "\n -d MSEC Milliseconds between updates, default:1000, none:-1" |
25 | //usage: "\n" | 25 | //usage: "\n" |
26 | //usage: "\nFormat specifiers:" | 26 | //usage: "\nFormat specifiers:" |
27 | //usage: "\n %Nc or %[cN] CPU. N - bar size (default:10)" | 27 | //usage: "\n %Nc or %[cN] CPU. N - bar size (default 10)" |
28 | //usage: "\n (displays: S:system U:user N:niced D:iowait I:irq i:softirq)" | 28 | //usage: "\n (displays: S:system U:user N:niced D:iowait I:irq i:softirq)" |
29 | //usage: "\n %[nINTERFACE] Network INTERFACE" | 29 | //usage: "\n %[nINTERFACE] Network INTERFACE" |
30 | //usage: "\n %m Allocated memory" | 30 | //usage: "\n %m Allocated memory" |
diff --git a/procps/pgrep.c b/procps/pgrep.c index ac82b5156..e932a32bc 100644 --- a/procps/pgrep.c +++ b/procps/pgrep.c | |||
@@ -19,6 +19,7 @@ | |||
19 | //config: Send signals to processes by name. | 19 | //config: Send signals to processes by name. |
20 | 20 | ||
21 | //applet:IF_PGREP(APPLET(pgrep, BB_DIR_USR_BIN, BB_SUID_DROP)) | 21 | //applet:IF_PGREP(APPLET(pgrep, BB_DIR_USR_BIN, BB_SUID_DROP)) |
22 | // APPLET_ODDNAME:name main location suid_type help | ||
22 | //applet:IF_PKILL(APPLET_ODDNAME(pkill, pgrep, BB_DIR_USR_BIN, BB_SUID_DROP, pkill)) | 23 | //applet:IF_PKILL(APPLET_ODDNAME(pkill, pgrep, BB_DIR_USR_BIN, BB_SUID_DROP, pkill)) |
23 | 24 | ||
24 | //kbuild:lib-$(CONFIG_PGREP) += pgrep.o | 25 | //kbuild:lib-$(CONFIG_PGREP) += pgrep.o |
diff --git a/procps/pidof.c b/procps/pidof.c index 069adb7a4..b64f0cbd6 100644 --- a/procps/pidof.c +++ b/procps/pidof.c | |||
@@ -14,18 +14,18 @@ | |||
14 | //config: those id's on the standard output. | 14 | //config: those id's on the standard output. |
15 | //config: | 15 | //config: |
16 | //config:config FEATURE_PIDOF_SINGLE | 16 | //config:config FEATURE_PIDOF_SINGLE |
17 | //config: bool "Enable argument for single shot (-s)" | 17 | //config: bool "Enable single shot (-s)" |
18 | //config: default y | 18 | //config: default y |
19 | //config: depends on PIDOF | 19 | //config: depends on PIDOF |
20 | //config: help | 20 | //config: help |
21 | //config: Support argument '-s' for returning only the first pid found. | 21 | //config: Support '-s' for returning only the first pid found. |
22 | //config: | 22 | //config: |
23 | //config:config FEATURE_PIDOF_OMIT | 23 | //config:config FEATURE_PIDOF_OMIT |
24 | //config: bool "Enable argument for omitting pids (-o)" | 24 | //config: bool "Enable omitting pids (-o PID)" |
25 | //config: default y | 25 | //config: default y |
26 | //config: depends on PIDOF | 26 | //config: depends on PIDOF |
27 | //config: help | 27 | //config: help |
28 | //config: Support argument '-o' for omitting the given pids in output. | 28 | //config: Support '-o PID' for omitting the given pid(s) in output. |
29 | //config: The special pid %PPID can be used to name the parent process | 29 | //config: The special pid %PPID can be used to name the parent process |
30 | //config: of the pidof, in other words the calling shell or shell script. | 30 | //config: of the pidof, in other words the calling shell or shell script. |
31 | 31 | ||
diff --git a/procps/powertop.c b/procps/powertop.c index ce85f4191..413806836 100644 --- a/procps/powertop.c +++ b/procps/powertop.c | |||
@@ -18,6 +18,14 @@ | |||
18 | //config: default y | 18 | //config: default y |
19 | //config: help | 19 | //config: help |
20 | //config: Analyze power consumption on Intel-based laptops | 20 | //config: Analyze power consumption on Intel-based laptops |
21 | //config: | ||
22 | //config:config FEATURE_POWERTOP_INTERACTIVE | ||
23 | //config: bool "Accept keyboard commands" | ||
24 | //config: default y | ||
25 | //config: depends on POWERTOP | ||
26 | //config: help | ||
27 | //config: Without this, powertop will only refresh display every 10 seconds. | ||
28 | //config: No keyboard commands will work, only ^C to terminate. | ||
21 | 29 | ||
22 | // XXX This should be configurable | 30 | // XXX This should be configurable |
23 | #define ENABLE_FEATURE_POWERTOP_PROCIRQ 1 | 31 | #define ENABLE_FEATURE_POWERTOP_PROCIRQ 1 |
@@ -82,7 +90,7 @@ struct globals { | |||
82 | ullong last_usage[MAX_CSTATE_COUNT]; | 90 | ullong last_usage[MAX_CSTATE_COUNT]; |
83 | ullong start_duration[MAX_CSTATE_COUNT]; | 91 | ullong start_duration[MAX_CSTATE_COUNT]; |
84 | ullong last_duration[MAX_CSTATE_COUNT]; | 92 | ullong last_duration[MAX_CSTATE_COUNT]; |
85 | #if ENABLE_FEATURE_USE_TERMIOS | 93 | #if ENABLE_FEATURE_POWERTOP_INTERACTIVE |
86 | struct termios init_settings; | 94 | struct termios init_settings; |
87 | #endif | 95 | #endif |
88 | }; | 96 | }; |
@@ -91,7 +99,7 @@ struct globals { | |||
91 | SET_PTR_TO_GLOBALS(xzalloc(sizeof(G))); \ | 99 | SET_PTR_TO_GLOBALS(xzalloc(sizeof(G))); \ |
92 | } while (0) | 100 | } while (0) |
93 | 101 | ||
94 | #if ENABLE_FEATURE_USE_TERMIOS | 102 | #if ENABLE_FEATURE_POWERTOP_INTERACTIVE |
95 | static void reset_term(void) | 103 | static void reset_term(void) |
96 | { | 104 | { |
97 | tcsetattr_stdin_TCSANOW(&G.init_settings); | 105 | tcsetattr_stdin_TCSANOW(&G.init_settings); |
@@ -682,8 +690,7 @@ int powertop_main(int UNUSED_PARAM argc, char UNUSED_PARAM **argv) | |||
682 | ullong cur_usage[MAX_CSTATE_COUNT]; | 690 | ullong cur_usage[MAX_CSTATE_COUNT]; |
683 | ullong cur_duration[MAX_CSTATE_COUNT]; | 691 | ullong cur_duration[MAX_CSTATE_COUNT]; |
684 | char cstate_lines[MAX_CSTATE_COUNT + 2][64]; | 692 | char cstate_lines[MAX_CSTATE_COUNT + 2][64]; |
685 | #if ENABLE_FEATURE_USE_TERMIOS | 693 | #if ENABLE_FEATURE_POWERTOP_INTERACTIVE |
686 | struct termios new_settings; | ||
687 | struct pollfd pfd[1]; | 694 | struct pollfd pfd[1]; |
688 | 695 | ||
689 | pfd[0].fd = 0; | 696 | pfd[0].fd = 0; |
@@ -706,15 +713,12 @@ int powertop_main(int UNUSED_PARAM argc, char UNUSED_PARAM **argv) | |||
706 | 713 | ||
707 | puts("Collecting data for "DEFAULT_SLEEP_STR" seconds"); | 714 | puts("Collecting data for "DEFAULT_SLEEP_STR" seconds"); |
708 | 715 | ||
709 | #if ENABLE_FEATURE_USE_TERMIOS | 716 | #if ENABLE_FEATURE_POWERTOP_INTERACTIVE |
710 | tcgetattr(0, (void *)&G.init_settings); | 717 | /* Turn on unbuffered input; turn off echoing, ^C ^Z etc */ |
711 | memcpy(&new_settings, &G.init_settings, sizeof(new_settings)); | 718 | set_termios_to_raw(STDIN_FILENO, &G.init_settings, TERMIOS_CLEAR_ISIG); |
712 | /* Turn on unbuffered input, turn off echoing */ | 719 | bb_signals(BB_FATAL_SIGS, sig_handler); |
713 | new_settings.c_lflag &= ~(ISIG | ICANON | ECHO | ECHONL); | ||
714 | /* So we don't forget to reset term settings */ | 720 | /* So we don't forget to reset term settings */ |
715 | atexit(reset_term); | 721 | atexit(reset_term); |
716 | bb_signals(BB_FATAL_SIGS, sig_handler); | ||
717 | tcsetattr_stdin_TCSANOW(&new_settings); | ||
718 | #endif | 722 | #endif |
719 | 723 | ||
720 | /* Collect initial data */ | 724 | /* Collect initial data */ |
@@ -739,7 +743,7 @@ int powertop_main(int UNUSED_PARAM argc, char UNUSED_PARAM **argv) | |||
739 | int i; | 743 | int i; |
740 | 744 | ||
741 | G.cant_enable_timer_stats |= start_timer(); /* 1 on error */ | 745 | G.cant_enable_timer_stats |= start_timer(); /* 1 on error */ |
742 | #if !ENABLE_FEATURE_USE_TERMIOS | 746 | #if !ENABLE_FEATURE_POWERTOP_INTERACTIVE |
743 | sleep(DEFAULT_SLEEP); | 747 | sleep(DEFAULT_SLEEP); |
744 | #else | 748 | #else |
745 | if (safe_poll(pfd, 1, DEFAULT_SLEEP * 1000) > 0) { | 749 | if (safe_poll(pfd, 1, DEFAULT_SLEEP * 1000) > 0) { |
diff --git a/procps/ps.c b/procps/ps.c index 902811f31..f7242f2d5 100644 --- a/procps/ps.c +++ b/procps/ps.c | |||
@@ -32,19 +32,10 @@ | |||
32 | //config: Adds fields PPID, RSS, START, TIME & TTY | 32 | //config: Adds fields PPID, RSS, START, TIME & TTY |
33 | //config: | 33 | //config: |
34 | //config:config FEATURE_PS_TIME | 34 | //config:config FEATURE_PS_TIME |
35 | //config: bool "Enable time and elapsed time output" | 35 | //config: bool "Support -o time and -o etime output specifiers" |
36 | //config: default y | 36 | //config: default y |
37 | //config: depends on PS && DESKTOP | 37 | //config: depends on PS && DESKTOP |
38 | //config: select PLATFORM_LINUX | 38 | //config: select PLATFORM_LINUX |
39 | //config: help | ||
40 | //config: Support -o time and -o etime output specifiers. | ||
41 | //config: | ||
42 | //config:config FEATURE_PS_ADDITIONAL_COLUMNS | ||
43 | //config: bool "Enable additional ps columns" | ||
44 | //config: default y | ||
45 | //config: depends on PS && DESKTOP | ||
46 | //config: help | ||
47 | //config: Support -o rgroup, -o ruser, -o nice output specifiers. | ||
48 | //config: | 39 | //config: |
49 | //config:config FEATURE_PS_UNUSUAL_SYSTEMS | 40 | //config:config FEATURE_PS_UNUSUAL_SYSTEMS |
50 | //config: bool "Support Linux prior to 2.4.0 and non-ELF systems" | 41 | //config: bool "Support Linux prior to 2.4.0 and non-ELF systems" |
@@ -53,6 +44,11 @@ | |||
53 | //config: help | 44 | //config: help |
54 | //config: Include support for measuring HZ on old kernels and non-ELF systems | 45 | //config: Include support for measuring HZ on old kernels and non-ELF systems |
55 | //config: (if you are on Linux 2.4.0+ and use ELF, you don't need this) | 46 | //config: (if you are on Linux 2.4.0+ and use ELF, you don't need this) |
47 | //config: | ||
48 | //config:config FEATURE_PS_ADDITIONAL_COLUMNS | ||
49 | //config: bool "Support -o rgroup, -o ruser, -o nice specifiers" | ||
50 | //config: default y | ||
51 | //config: depends on PS && DESKTOP | ||
56 | 52 | ||
57 | //applet:IF_PS(APPLET(ps, BB_DIR_BIN, BB_SUID_DROP)) | 53 | //applet:IF_PS(APPLET(ps, BB_DIR_BIN, BB_SUID_DROP)) |
58 | 54 | ||
@@ -628,7 +624,9 @@ int ps_main(int argc UNUSED_PARAM, char **argv) | |||
628 | procps_status_t *p; | 624 | procps_status_t *p; |
629 | llist_t* opt_o = NULL; | 625 | llist_t* opt_o = NULL; |
630 | char default_o[sizeof(DEFAULT_O_STR)]; | 626 | char default_o[sizeof(DEFAULT_O_STR)]; |
627 | #if ENABLE_SELINUX || ENABLE_FEATURE_SHOW_THREADS | ||
631 | int opt; | 628 | int opt; |
629 | #endif | ||
632 | enum { | 630 | enum { |
633 | OPT_Z = (1 << 0), | 631 | OPT_Z = (1 << 0), |
634 | OPT_o = (1 << 1), | 632 | OPT_o = (1 << 1), |
@@ -658,7 +656,11 @@ int ps_main(int argc UNUSED_PARAM, char **argv) | |||
658 | * procps v3.2.7 supports -T and shows tids as SPID column, | 656 | * procps v3.2.7 supports -T and shows tids as SPID column, |
659 | * it also supports -L where it shows tids as LWP column. | 657 | * it also supports -L where it shows tids as LWP column. |
660 | */ | 658 | */ |
661 | opt = getopt32(argv, "Zo:*aAdefl"IF_FEATURE_SHOW_THREADS("T"), &opt_o); | 659 | #if ENABLE_SELINUX || ENABLE_FEATURE_SHOW_THREADS |
660 | opt = | ||
661 | #endif | ||
662 | getopt32(argv, "Zo:*aAdefl"IF_FEATURE_SHOW_THREADS("T"), &opt_o); | ||
663 | |||
662 | if (opt_o) { | 664 | if (opt_o) { |
663 | do { | 665 | do { |
664 | parse_o(llist_pop(&opt_o)); | 666 | parse_o(llist_pop(&opt_o)); |
diff --git a/procps/pstree.c b/procps/pstree.c index c5fb83688..f97e99639 100644 --- a/procps/pstree.c +++ b/procps/pstree.c | |||
@@ -357,7 +357,9 @@ static void handle_thread(const char *comm, pid_t pid, pid_t ppid, uid_t uid) | |||
357 | static void mread_proc(void) | 357 | static void mread_proc(void) |
358 | { | 358 | { |
359 | procps_status_t *p = NULL; | 359 | procps_status_t *p = NULL; |
360 | #if ENABLE_FEATURE_SHOW_THREADS | ||
360 | pid_t parent = 0; | 361 | pid_t parent = 0; |
362 | #endif | ||
361 | int flags = PSSCAN_COMM | PSSCAN_PID | PSSCAN_PPID | PSSCAN_UIDGID | PSSCAN_TASKS; | 363 | int flags = PSSCAN_COMM | PSSCAN_PID | PSSCAN_PPID | PSSCAN_UIDGID | PSSCAN_TASKS; |
362 | 364 | ||
363 | while ((p = procps_scan(p, flags)) != NULL) { | 365 | while ((p = procps_scan(p, flags)) != NULL) { |
@@ -368,7 +370,9 @@ static void mread_proc(void) | |||
368 | #endif | 370 | #endif |
369 | { | 371 | { |
370 | add_proc(p->comm, p->pid, p->ppid, p->uid/*, 0*/); | 372 | add_proc(p->comm, p->pid, p->ppid, p->uid/*, 0*/); |
373 | #if ENABLE_FEATURE_SHOW_THREADS | ||
371 | parent = p->pid; | 374 | parent = p->pid; |
375 | #endif | ||
372 | } | 376 | } |
373 | } | 377 | } |
374 | } | 378 | } |
diff --git a/procps/top.c b/procps/top.c index 71207bac1..ff2fddeea 100644 --- a/procps/top.c +++ b/procps/top.c | |||
@@ -56,6 +56,14 @@ | |||
56 | //config: The top program provides a dynamic real-time view of a running | 56 | //config: The top program provides a dynamic real-time view of a running |
57 | //config: system. | 57 | //config: system. |
58 | //config: | 58 | //config: |
59 | //config:config FEATURE_TOP_INTERACTIVE | ||
60 | //config: bool "Accept keyboard commands" | ||
61 | //config: default y | ||
62 | //config: depends on TOP | ||
63 | //config: help | ||
64 | //config: Without this, top will only refresh display every 5 seconds. | ||
65 | //config: No keyboard commands will work, only ^C to terminate. | ||
66 | //config: | ||
59 | //config:config FEATURE_TOP_CPU_USAGE_PERCENTAGE | 67 | //config:config FEATURE_TOP_CPU_USAGE_PERCENTAGE |
60 | //config: bool "Show CPU per-process usage percentage" | 68 | //config: bool "Show CPU per-process usage percentage" |
61 | //config: default y | 69 | //config: default y |
@@ -158,7 +166,7 @@ struct globals { | |||
158 | smallint smp_cpu_info; /* one/many cpu info lines? */ | 166 | smallint smp_cpu_info; /* one/many cpu info lines? */ |
159 | #endif | 167 | #endif |
160 | unsigned lines; /* screen height */ | 168 | unsigned lines; /* screen height */ |
161 | #if ENABLE_FEATURE_USE_TERMIOS | 169 | #if ENABLE_FEATURE_TOP_INTERACTIVE |
162 | struct termios initial_settings; | 170 | struct termios initial_settings; |
163 | int scroll_ofs; | 171 | int scroll_ofs; |
164 | #define G_scroll_ofs G.scroll_ofs | 172 | #define G_scroll_ofs G.scroll_ofs |
@@ -181,7 +189,7 @@ struct globals { | |||
181 | jiffy_counts_t *cpu_jif, *cpu_prev_jif; | 189 | jiffy_counts_t *cpu_jif, *cpu_prev_jif; |
182 | int num_cpus; | 190 | int num_cpus; |
183 | #endif | 191 | #endif |
184 | #if ENABLE_FEATURE_USE_TERMIOS | 192 | #if ENABLE_FEATURE_TOP_INTERACTIVE |
185 | char kbd_input[KEYCODE_BUFFER_SIZE]; | 193 | char kbd_input[KEYCODE_BUFFER_SIZE]; |
186 | #endif | 194 | #endif |
187 | char line_buf[80]; | 195 | char line_buf[80]; |
@@ -220,7 +228,7 @@ enum { | |||
220 | #define OPT_BATCH_MODE (option_mask32 & OPT_b) | 228 | #define OPT_BATCH_MODE (option_mask32 & OPT_b) |
221 | 229 | ||
222 | 230 | ||
223 | #if ENABLE_FEATURE_USE_TERMIOS | 231 | #if ENABLE_FEATURE_TOP_INTERACTIVE |
224 | static int pid_sort(top_status_t *P, top_status_t *Q) | 232 | static int pid_sort(top_status_t *P, top_status_t *Q) |
225 | { | 233 | { |
226 | /* Buggy wrt pids with high bit set */ | 234 | /* Buggy wrt pids with high bit set */ |
@@ -725,8 +733,7 @@ static void clearmems(void) | |||
725 | top = NULL; | 733 | top = NULL; |
726 | } | 734 | } |
727 | 735 | ||
728 | #if ENABLE_FEATURE_USE_TERMIOS | 736 | #if ENABLE_FEATURE_TOP_INTERACTIVE |
729 | |||
730 | static void reset_term(void) | 737 | static void reset_term(void) |
731 | { | 738 | { |
732 | if (!OPT_BATCH_MODE) | 739 | if (!OPT_BATCH_MODE) |
@@ -738,8 +745,7 @@ static void sig_catcher(int sig) | |||
738 | reset_term(); | 745 | reset_term(); |
739 | kill_myself_with_sig(sig); | 746 | kill_myself_with_sig(sig); |
740 | } | 747 | } |
741 | 748 | #endif /* FEATURE_TOP_INTERACTIVE */ | |
742 | #endif /* FEATURE_USE_TERMIOS */ | ||
743 | 749 | ||
744 | /* | 750 | /* |
745 | * TOPMEM support | 751 | * TOPMEM support |
@@ -894,7 +900,7 @@ enum { | |||
894 | EXIT_MASK = (unsigned)-1, | 900 | EXIT_MASK = (unsigned)-1, |
895 | }; | 901 | }; |
896 | 902 | ||
897 | #if ENABLE_FEATURE_USE_TERMIOS | 903 | #if ENABLE_FEATURE_TOP_INTERACTIVE |
898 | static unsigned handle_input(unsigned scan_mask, unsigned interval) | 904 | static unsigned handle_input(unsigned scan_mask, unsigned interval) |
899 | { | 905 | { |
900 | if (option_mask32 & OPT_EOF) { | 906 | if (option_mask32 & OPT_EOF) { |
@@ -1043,7 +1049,7 @@ static unsigned handle_input(unsigned scan_mask, unsigned interval) | |||
1043 | //usage: "\n""Read the status of all processes from /proc each SECONDS" | 1049 | //usage: "\n""Read the status of all processes from /proc each SECONDS" |
1044 | //usage: "\n""and display a screenful of them." | 1050 | //usage: "\n""and display a screenful of them." |
1045 | //usage: "\n" | 1051 | //usage: "\n" |
1046 | //usage: IF_FEATURE_USE_TERMIOS( | 1052 | //usage: IF_FEATURE_TOP_INTERACTIVE( |
1047 | //usage: "Keys:" | 1053 | //usage: "Keys:" |
1048 | //usage: "\n"" N/M" | 1054 | //usage: "\n"" N/M" |
1049 | //usage: IF_FEATURE_TOP_CPU_USAGE_PERCENTAGE("/P") | 1055 | //usage: IF_FEATURE_TOP_CPU_USAGE_PERCENTAGE("/P") |
@@ -1091,9 +1097,6 @@ int top_main(int argc UNUSED_PARAM, char **argv) | |||
1091 | unsigned interval; | 1097 | unsigned interval; |
1092 | char *str_interval, *str_iterations; | 1098 | char *str_interval, *str_iterations; |
1093 | unsigned scan_mask = TOP_MASK; | 1099 | unsigned scan_mask = TOP_MASK; |
1094 | #if ENABLE_FEATURE_USE_TERMIOS | ||
1095 | struct termios new_settings; | ||
1096 | #endif | ||
1097 | 1100 | ||
1098 | INIT_G(); | 1101 | INIT_G(); |
1099 | 1102 | ||
@@ -1141,13 +1144,10 @@ int top_main(int argc UNUSED_PARAM, char **argv) | |||
1141 | if (OPT_BATCH_MODE) { | 1144 | if (OPT_BATCH_MODE) { |
1142 | option_mask32 |= OPT_EOF; | 1145 | option_mask32 |= OPT_EOF; |
1143 | } | 1146 | } |
1144 | #if ENABLE_FEATURE_USE_TERMIOS | 1147 | #if ENABLE_FEATURE_TOP_INTERACTIVE |
1145 | else { | 1148 | else { |
1146 | tcgetattr(0, (void *) &initial_settings); | 1149 | /* Turn on unbuffered input; turn off echoing, ^C ^Z etc */ |
1147 | memcpy(&new_settings, &initial_settings, sizeof(new_settings)); | 1150 | set_termios_to_raw(STDIN_FILENO, &initial_settings, TERMIOS_CLEAR_ISIG); |
1148 | /* unbuffered input, turn off echo */ | ||
1149 | new_settings.c_lflag &= ~(ISIG | ICANON | ECHO | ECHONL); | ||
1150 | tcsetattr_stdin_TCSANOW(&new_settings); | ||
1151 | } | 1151 | } |
1152 | 1152 | ||
1153 | bb_signals(BB_FATAL_SIGS, sig_catcher); | 1153 | bb_signals(BB_FATAL_SIGS, sig_catcher); |
@@ -1165,14 +1165,12 @@ int top_main(int argc UNUSED_PARAM, char **argv) | |||
1165 | } else { | 1165 | } else { |
1166 | G.lines = 24; /* default */ | 1166 | G.lines = 24; /* default */ |
1167 | col = 79; | 1167 | col = 79; |
1168 | #if ENABLE_FEATURE_USE_TERMIOS | ||
1169 | /* We output to stdout, we need size of stdout (not stdin)! */ | 1168 | /* We output to stdout, we need size of stdout (not stdin)! */ |
1170 | get_terminal_width_height(STDOUT_FILENO, &col, &G.lines); | 1169 | get_terminal_width_height(STDOUT_FILENO, &col, &G.lines); |
1171 | if (G.lines < 5 || col < 10) { | 1170 | if (G.lines < 5 || col < 10) { |
1172 | sleep(interval); | 1171 | sleep(interval); |
1173 | continue; | 1172 | continue; |
1174 | } | 1173 | } |
1175 | #endif | ||
1176 | if (col > LINE_BUF_SIZE - 2) | 1174 | if (col > LINE_BUF_SIZE - 2) |
1177 | col = LINE_BUF_SIZE - 2; | 1175 | col = LINE_BUF_SIZE - 2; |
1178 | } | 1176 | } |
@@ -1247,7 +1245,7 @@ int top_main(int argc UNUSED_PARAM, char **argv) | |||
1247 | clearmems(); | 1245 | clearmems(); |
1248 | if (iterations >= 0 && !--iterations) | 1246 | if (iterations >= 0 && !--iterations) |
1249 | break; | 1247 | break; |
1250 | #if !ENABLE_FEATURE_USE_TERMIOS | 1248 | #if !ENABLE_FEATURE_TOP_INTERACTIVE |
1251 | sleep(interval); | 1249 | sleep(interval); |
1252 | #else | 1250 | #else |
1253 | scan_mask = handle_input(scan_mask, interval); | 1251 | scan_mask = handle_input(scan_mask, interval); |
@@ -1255,7 +1253,7 @@ int top_main(int argc UNUSED_PARAM, char **argv) | |||
1255 | } /* end of "while (not Q)" */ | 1253 | } /* end of "while (not Q)" */ |
1256 | 1254 | ||
1257 | bb_putchar('\n'); | 1255 | bb_putchar('\n'); |
1258 | #if ENABLE_FEATURE_USE_TERMIOS | 1256 | #if ENABLE_FEATURE_TOP_INTERACTIVE |
1259 | reset_term(); | 1257 | reset_term(); |
1260 | #endif | 1258 | #endif |
1261 | if (ENABLE_FEATURE_CLEAN_UP) { | 1259 | if (ENABLE_FEATURE_CLEAN_UP) { |
diff --git a/procps/uptime.c b/procps/uptime.c index 436193925..8e8956c0f 100644 --- a/procps/uptime.c +++ b/procps/uptime.c | |||
@@ -21,11 +21,11 @@ | |||
21 | //config: on, and the system load averages for the past 1, 5, and 15 minutes. | 21 | //config: on, and the system load averages for the past 1, 5, and 15 minutes. |
22 | //config: | 22 | //config: |
23 | //config:config FEATURE_UPTIME_UTMP_SUPPORT | 23 | //config:config FEATURE_UPTIME_UTMP_SUPPORT |
24 | //config: bool "Support for showing the number of users" | 24 | //config: bool "Show the number of users" |
25 | //config: default y | 25 | //config: default y |
26 | //config: depends on UPTIME && FEATURE_UTMP | 26 | //config: depends on UPTIME && FEATURE_UTMP |
27 | //config: help | 27 | //config: help |
28 | //config: Makes uptime display the number of users currently logged on. | 28 | //config: Display the number of users currently logged on. |
29 | 29 | ||
30 | //applet:IF_UPTIME(APPLET(uptime, BB_DIR_USR_BIN, BB_SUID_DROP)) | 30 | //applet:IF_UPTIME(APPLET(uptime, BB_DIR_USR_BIN, BB_SUID_DROP)) |
31 | 31 | ||
diff --git a/runit/chpst.c b/runit/chpst.c index 3769af25e..846c846d3 100644 --- a/runit/chpst.c +++ b/runit/chpst.c | |||
@@ -60,7 +60,8 @@ ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |||
60 | //config: Sets soft resource limits as specified by options | 60 | //config: Sets soft resource limits as specified by options |
61 | 61 | ||
62 | //applet:IF_CHPST(APPLET(chpst, BB_DIR_USR_BIN, BB_SUID_DROP)) | 62 | //applet:IF_CHPST(APPLET(chpst, BB_DIR_USR_BIN, BB_SUID_DROP)) |
63 | //applet:IF_ENVDIR(APPLET_ODDNAME(envdir, chpst, BB_DIR_USR_BIN, BB_SUID_DROP, envdir)) | 63 | // APPLET_ODDNAME:name main location suid_type help |
64 | //applet:IF_ENVDIR( APPLET_ODDNAME(envdir, chpst, BB_DIR_USR_BIN, BB_SUID_DROP, envdir)) | ||
64 | //applet:IF_ENVUIDGID(APPLET_ODDNAME(envuidgid, chpst, BB_DIR_USR_BIN, BB_SUID_DROP, envuidgid)) | 65 | //applet:IF_ENVUIDGID(APPLET_ODDNAME(envuidgid, chpst, BB_DIR_USR_BIN, BB_SUID_DROP, envuidgid)) |
65 | //applet:IF_SETUIDGID(APPLET_ODDNAME(setuidgid, chpst, BB_DIR_USR_BIN, BB_SUID_DROP, setuidgid)) | 66 | //applet:IF_SETUIDGID(APPLET_ODDNAME(setuidgid, chpst, BB_DIR_USR_BIN, BB_SUID_DROP, setuidgid)) |
66 | //applet:IF_SOFTLIMIT(APPLET_ODDNAME(softlimit, chpst, BB_DIR_USR_BIN, BB_SUID_DROP, softlimit)) | 67 | //applet:IF_SOFTLIMIT(APPLET_ODDNAME(softlimit, chpst, BB_DIR_USR_BIN, BB_SUID_DROP, softlimit)) |
diff --git a/scripts/gen_build_files.sh b/scripts/gen_build_files.sh index ebee17c64..f79fa2f83 100755 --- a/scripts/gen_build_files.sh +++ b/scripts/gen_build_files.sh | |||
@@ -20,7 +20,9 @@ chk() { status "CHK" "$@"; } | |||
20 | generate() | 20 | generate() |
21 | { | 21 | { |
22 | # NB: data to be inserted at INSERT line is coming on stdin | 22 | # NB: data to be inserted at INSERT line is coming on stdin |
23 | local src="$1" dst="$2" header="$3" | 23 | src="$1" |
24 | dst="$2" | ||
25 | header="$3" | ||
24 | #chk "${dst}" | 26 | #chk "${dst}" |
25 | { | 27 | { |
26 | # Need to use printf: different shells have inconsistent | 28 | # Need to use printf: different shells have inconsistent |
diff --git a/scripts/trylink b/scripts/trylink index c2a431626..9f288c141 100755 --- a/scripts/trylink +++ b/scripts/trylink | |||
@@ -46,8 +46,7 @@ try() { | |||
46 | } | 46 | } |
47 | 47 | ||
48 | check_cc() { | 48 | check_cc() { |
49 | local tempname="$(mktemp tmp.XXXXXXXXXX)" | 49 | tempname="$(mktemp tmp.XXXXXXXXXX)" |
50 | local r | ||
51 | echo "int main(int argc,char**argv){return argv?argc:0;}" >"$tempname".c | 50 | echo "int main(int argc,char**argv){return argv?argc:0;}" >"$tempname".c |
52 | # Can use "-o /dev/null", but older gcc tend to *unlink it* on failure! :( | 51 | # Can use "-o /dev/null", but older gcc tend to *unlink it* on failure! :( |
53 | # Was using "-xc /dev/null", but we need a valid C program. | 52 | # Was using "-xc /dev/null", but we need a valid C program. |
@@ -55,14 +54,13 @@ check_cc() { | |||
55 | # '... -D"BB_VER=KBUILD_STR(1.N.M)" ...' | 54 | # '... -D"BB_VER=KBUILD_STR(1.N.M)" ...' |
56 | # and we need shell to process quotes! | 55 | # and we need shell to process quotes! |
57 | $CC $CFLAGS $LDFLAGS $1 "$tempname".c -o "$tempname" >/dev/null 2>&1 | 56 | $CC $CFLAGS $LDFLAGS $1 "$tempname".c -o "$tempname" >/dev/null 2>&1 |
58 | r=$? | 57 | exitcode=$? |
59 | rm -f "$tempname" "$tempname".c "$tempname".o | 58 | rm -f "$tempname" "$tempname".c "$tempname".o |
60 | return $r | 59 | return $exitcode |
61 | } | 60 | } |
62 | 61 | ||
63 | check_libc_is_glibc() { | 62 | check_libc_is_glibc() { |
64 | local tempname="$(mktemp tmp.XXXXXXXXXX)" | 63 | tempname="$(mktemp tmp.XXXXXXXXXX)" |
65 | local r | ||
66 | echo "\ | 64 | echo "\ |
67 | #include <stdlib.h> | 65 | #include <stdlib.h> |
68 | /* Apparently uclibc defines __GLIBC__ (compat trick?). Oh well. */ | 66 | /* Apparently uclibc defines __GLIBC__ (compat trick?). Oh well. */ |
@@ -71,9 +69,9 @@ check_libc_is_glibc() { | |||
71 | #endif | 69 | #endif |
72 | " >"$tempname".c | 70 | " >"$tempname".c |
73 | ! $CC $CFLAGS "$tempname".c -c -o "$tempname".o >/dev/null 2>&1 | 71 | ! $CC $CFLAGS "$tempname".c -c -o "$tempname".o >/dev/null 2>&1 |
74 | r=$? | 72 | exitcode=$? |
75 | rm -f "$tempname" "$tempname".c "$tempname".o | 73 | rm -f "$tempname" "$tempname".c "$tempname".o |
76 | return $r | 74 | return $exitcode |
77 | } | 75 | } |
78 | 76 | ||
79 | EXE="$1" | 77 | EXE="$1" |
diff --git a/selinux/chcon.c b/selinux/chcon.c index c743013ce..ba9b08638 100644 --- a/selinux/chcon.c +++ b/selinux/chcon.c | |||
@@ -18,8 +18,6 @@ | |||
18 | //config: bool "Enable long options" | 18 | //config: bool "Enable long options" |
19 | //config: default y | 19 | //config: default y |
20 | //config: depends on CHCON && LONG_OPTS | 20 | //config: depends on CHCON && LONG_OPTS |
21 | //config: help | ||
22 | //config: Support long options for the chcon applet. | ||
23 | 21 | ||
24 | //applet:IF_CHCON(APPLET(chcon, BB_DIR_USR_BIN, BB_SUID_DROP)) | 22 | //applet:IF_CHCON(APPLET(chcon, BB_DIR_USR_BIN, BB_SUID_DROP)) |
25 | 23 | ||
@@ -38,11 +36,11 @@ | |||
38 | //usage: "\n -c,--changes Report changes made" | 36 | //usage: "\n -c,--changes Report changes made" |
39 | //usage: "\n -h,--no-dereference Affect symlinks instead of their targets" | 37 | //usage: "\n -h,--no-dereference Affect symlinks instead of their targets" |
40 | //usage: "\n -f,--silent,--quiet Suppress most error messages" | 38 | //usage: "\n -f,--silent,--quiet Suppress most error messages" |
41 | //usage: "\n --reference=RFILE Use RFILE's group instead of using a CONTEXT value" | 39 | //usage: "\n --reference RFILE Use RFILE's group instead of using a CONTEXT value" |
42 | //usage: "\n -u,--user=USER Set user/role/type/range in the target" | 40 | //usage: "\n -u,--user USER Set user/role/type/range in the target" |
43 | //usage: "\n -r,--role=ROLE security context" | 41 | //usage: "\n -r,--role ROLE security context" |
44 | //usage: "\n -t,--type=TYPE" | 42 | //usage: "\n -t,--type TYPE" |
45 | //usage: "\n -l,--range=RANGE" | 43 | //usage: "\n -l,--range RANGE" |
46 | //usage: "\n -R,--recursive Recurse" | 44 | //usage: "\n -R,--recursive Recurse" |
47 | //usage: ) | 45 | //usage: ) |
48 | //usage: IF_NOT_FEATURE_CHCON_LONG_OPTIONS( | 46 | //usage: IF_NOT_FEATURE_CHCON_LONG_OPTIONS( |
diff --git a/selinux/runcon.c b/selinux/runcon.c index 16f171101..82f4d50d3 100644 --- a/selinux/runcon.c +++ b/selinux/runcon.c | |||
@@ -39,8 +39,6 @@ | |||
39 | //config: bool "Enable long options" | 39 | //config: bool "Enable long options" |
40 | //config: default y | 40 | //config: default y |
41 | //config: depends on RUNCON && LONG_OPTS | 41 | //config: depends on RUNCON && LONG_OPTS |
42 | //config: help | ||
43 | //config: Support long options for the runcon applet. | ||
44 | 42 | ||
45 | //applet:IF_RUNCON(APPLET(runcon, BB_DIR_USR_BIN, BB_SUID_DROP)) | 43 | //applet:IF_RUNCON(APPLET(runcon, BB_DIR_USR_BIN, BB_SUID_DROP)) |
46 | 44 | ||
@@ -54,10 +52,10 @@ | |||
54 | //usage: "\n CONTEXT Complete security context\n" | 52 | //usage: "\n CONTEXT Complete security context\n" |
55 | //usage: IF_FEATURE_RUNCON_LONG_OPTIONS( | 53 | //usage: IF_FEATURE_RUNCON_LONG_OPTIONS( |
56 | //usage: "\n -c,--compute Compute process transition context before modifying" | 54 | //usage: "\n -c,--compute Compute process transition context before modifying" |
57 | //usage: "\n -t,--type=TYPE Type (for same role as parent)" | 55 | //usage: "\n -t,--type TYPE Type (for same role as parent)" |
58 | //usage: "\n -u,--user=USER User identity" | 56 | //usage: "\n -u,--user USER User identity" |
59 | //usage: "\n -r,--role=ROLE Role" | 57 | //usage: "\n -r,--role ROLE Role" |
60 | //usage: "\n -l,--range=RNG Levelrange" | 58 | //usage: "\n -l,--range RNG Levelrange" |
61 | //usage: ) | 59 | //usage: ) |
62 | //usage: IF_NOT_FEATURE_RUNCON_LONG_OPTIONS( | 60 | //usage: IF_NOT_FEATURE_RUNCON_LONG_OPTIONS( |
63 | //usage: "\n -c Compute process transition context before modifying" | 61 | //usage: "\n -c Compute process transition context before modifying" |
diff --git a/selinux/setfiles.c b/selinux/setfiles.c index 9fa5d3f30..c14a67be5 100644 --- a/selinux/setfiles.c +++ b/selinux/setfiles.c | |||
@@ -30,6 +30,7 @@ | |||
30 | //config: the same as setfiles, but usage is a little different. | 30 | //config: the same as setfiles, but usage is a little different. |
31 | 31 | ||
32 | //applet:IF_SETFILES(APPLET(setfiles, BB_DIR_SBIN, BB_SUID_DROP)) | 32 | //applet:IF_SETFILES(APPLET(setfiles, BB_DIR_SBIN, BB_SUID_DROP)) |
33 | // APPLET_ODDNAME:name main location suid_type help | ||
33 | //applet:IF_RESTORECON(APPLET_ODDNAME(restorecon, setfiles, BB_DIR_SBIN, BB_SUID_DROP, restorecon)) | 34 | //applet:IF_RESTORECON(APPLET_ODDNAME(restorecon, setfiles, BB_DIR_SBIN, BB_SUID_DROP, restorecon)) |
34 | 35 | ||
35 | //kbuild:lib-$(CONFIG_SETFILES) += setfiles.o | 36 | //kbuild:lib-$(CONFIG_SETFILES) += setfiles.o |
diff --git a/shell/Config.src b/shell/Config.src index 3545f05dd..ccb1b15fe 100644 --- a/shell/Config.src +++ b/shell/Config.src | |||
@@ -121,23 +121,11 @@ config FEATURE_SH_STANDALONE | |||
121 | for use as a rescue shell, in the event that you screw up your system. | 121 | for use as a rescue shell, in the event that you screw up your system. |
122 | 122 | ||
123 | This is implemented by re-execing /proc/self/exe (typically) | 123 | This is implemented by re-execing /proc/self/exe (typically) |
124 | with right parameters. Some selected applets ("NOFORK" applets) | 124 | with right parameters. |
125 | can even be executed without creating new process. | 125 | |
126 | Instead, busybox will call <applet>_main() internally. | 126 | However, there are drawbacks: it is problematic in chroot jails |
127 | 127 | without mounted /proc, and ps/top may show command name as 'exe' | |
128 | However, this causes problems in chroot jails without mounted /proc | 128 | for applets started this way. |
129 | and with ps/top (command name can be shown as 'exe' for applets | ||
130 | started this way). | ||
131 | # untrue? | ||
132 | # Note that this will *also* cause applets to take precedence | ||
133 | # over shell builtins of the same name. So turning this on will | ||
134 | # eliminate any performance gained by turning on the builtin "echo" | ||
135 | # and "test" commands in ash. | ||
136 | # untrue? | ||
137 | # Note that when using this option, the shell will attempt to directly | ||
138 | # run '/bin/busybox'. If you do not have the busybox binary sitting in | ||
139 | # that exact location with that exact name, this option will not work at | ||
140 | # all. | ||
141 | 129 | ||
142 | config FEATURE_SH_NOFORK | 130 | config FEATURE_SH_NOFORK |
143 | bool "Run 'nofork' applets directly" | 131 | bool "Run 'nofork' applets directly" |
diff --git a/shell/ash.c b/shell/ash.c index e21c4433d..0325a325c 100644 --- a/shell/ash.c +++ b/shell/ash.c | |||
@@ -50,8 +50,6 @@ | |||
50 | //config: bool "Optimize for size instead of speed" | 50 | //config: bool "Optimize for size instead of speed" |
51 | //config: default y | 51 | //config: default y |
52 | //config: depends on ASH || SH_IS_ASH || BASH_IS_ASH | 52 | //config: depends on ASH || SH_IS_ASH || BASH_IS_ASH |
53 | //config: help | ||
54 | //config: Compile ash for reduced size at the price of speed. | ||
55 | //config: | 53 | //config: |
56 | //config:config ASH_INTERNAL_GLOB | 54 | //config:config ASH_INTERNAL_GLOB |
57 | //config: bool "Use internal glob() implementation" | 55 | //config: bool "Use internal glob() implementation" |
@@ -61,6 +59,23 @@ | |||
61 | //config: Do not use glob() function from libc, use internal implementation. | 59 | //config: Do not use glob() function from libc, use internal implementation. |
62 | //config: Use this if you are getting "glob.h: No such file or directory" | 60 | //config: Use this if you are getting "glob.h: No such file or directory" |
63 | //config: or similar build errors. | 61 | //config: or similar build errors. |
62 | //config: Note that as of now (2017-01), uclibc and musl glob() both have bugs | ||
63 | //config: which would break ash if you select N here. | ||
64 | //config: | ||
65 | //config:config ASH_BASH_COMPAT | ||
66 | //config: bool "bash-compatible extensions" | ||
67 | //config: default y | ||
68 | //config: depends on ASH || SH_IS_ASH || BASH_IS_ASH | ||
69 | //config: | ||
70 | //config:config ASH_JOB_CONTROL | ||
71 | //config: bool "Job control" | ||
72 | //config: default y | ||
73 | //config: depends on ASH || SH_IS_ASH || BASH_IS_ASH | ||
74 | //config: | ||
75 | //config:config ASH_ALIAS | ||
76 | //config: bool "Alias support" | ||
77 | //config: default y | ||
78 | //config: depends on ASH || SH_IS_ASH || BASH_IS_ASH | ||
64 | //config: | 79 | //config: |
65 | //config:config ASH_RANDOM_SUPPORT | 80 | //config:config ASH_RANDOM_SUPPORT |
66 | //config: bool "Pseudorandom generator and $RANDOM variable" | 81 | //config: bool "Pseudorandom generator and $RANDOM variable" |
@@ -78,88 +93,60 @@ | |||
78 | //config: default y | 93 | //config: default y |
79 | //config: depends on ASH || SH_IS_ASH || BASH_IS_ASH | 94 | //config: depends on ASH || SH_IS_ASH || BASH_IS_ASH |
80 | //config: help | 95 | //config: help |
81 | //config: "PS#" may contain volatile content, such as backquote commands. | 96 | //config: $PS# may contain volatile content, such as backquote commands. |
82 | //config: This option recreates the prompt string from the environment | 97 | //config: This option recreates the prompt string from the environment |
83 | //config: variable each time it is displayed. | 98 | //config: variable each time it is displayed. |
84 | //config: | 99 | //config: |
85 | //config:config ASH_BASH_COMPAT | ||
86 | //config: bool "bash-compatible extensions" | ||
87 | //config: default y | ||
88 | //config: depends on ASH || SH_IS_ASH || BASH_IS_ASH | ||
89 | //config: help | ||
90 | //config: Enable bash-compatible extensions. | ||
91 | //config: | ||
92 | //config:config ASH_IDLE_TIMEOUT | 100 | //config:config ASH_IDLE_TIMEOUT |
93 | //config: bool "Idle timeout variable" | 101 | //config: bool "Idle timeout variable $TMOUT" |
94 | //config: default n | ||
95 | //config: depends on ASH || SH_IS_ASH || BASH_IS_ASH | ||
96 | //config: help | ||
97 | //config: Enables bash-like auto-logout after $TMOUT seconds of idle time. | ||
98 | //config: | ||
99 | //config:config ASH_JOB_CONTROL | ||
100 | //config: bool "Job control" | ||
101 | //config: default y | ||
102 | //config: depends on ASH || SH_IS_ASH || BASH_IS_ASH | ||
103 | //config: help | ||
104 | //config: Enable job control in the ash shell. | ||
105 | //config: | ||
106 | //config:config ASH_ALIAS | ||
107 | //config: bool "Alias support" | ||
108 | //config: default y | 102 | //config: default y |
109 | //config: depends on ASH || SH_IS_ASH || BASH_IS_ASH | 103 | //config: depends on ASH || SH_IS_ASH || BASH_IS_ASH |
110 | //config: help | 104 | //config: help |
111 | //config: Enable alias support in the ash shell. | 105 | //config: Enable bash-like auto-logout after $TMOUT seconds of idle time. |
112 | //config: | 106 | //config: |
113 | //config:config ASH_GETOPTS | 107 | //config:config ASH_MAIL |
114 | //config: bool "Builtin getopt to parse positional parameters" | 108 | //config: bool "Check for new mail in interactive shell" |
115 | //config: default y | 109 | //config: default y |
116 | //config: depends on ASH || SH_IS_ASH || BASH_IS_ASH | 110 | //config: depends on ASH || SH_IS_ASH || BASH_IS_ASH |
117 | //config: help | 111 | //config: help |
118 | //config: Enable support for getopts builtin in ash. | 112 | //config: Enable "check for new mail" function: |
113 | //config: if set, $MAIL file and $MAILPATH list of files | ||
114 | //config: are checked for mtime changes, and "you have mail" | ||
115 | //config: message is printed if change is detected. | ||
119 | //config: | 116 | //config: |
120 | //config:config ASH_BUILTIN_ECHO | 117 | //config:config ASH_ECHO |
121 | //config: bool "Builtin version of 'echo'" | 118 | //config: bool "echo builtin" |
122 | //config: default y | 119 | //config: default y |
123 | //config: depends on ASH || SH_IS_ASH || BASH_IS_ASH | 120 | //config: depends on ASH || SH_IS_ASH || BASH_IS_ASH |
124 | //config: help | ||
125 | //config: Enable support for echo builtin in ash. | ||
126 | //config: | 121 | //config: |
127 | //config:config ASH_BUILTIN_PRINTF | 122 | //config:config ASH_PRINTF |
128 | //config: bool "Builtin version of 'printf'" | 123 | //config: bool "printf builtin" |
129 | //config: default y | 124 | //config: default y |
130 | //config: depends on ASH || SH_IS_ASH || BASH_IS_ASH | 125 | //config: depends on ASH || SH_IS_ASH || BASH_IS_ASH |
131 | //config: help | ||
132 | //config: Enable support for printf builtin in ash. | ||
133 | //config: | 126 | //config: |
134 | //config:config ASH_BUILTIN_TEST | 127 | //config:config ASH_TEST |
135 | //config: bool "Builtin version of 'test'" | 128 | //config: bool "test builtin" |
136 | //config: default y | 129 | //config: default y |
137 | //config: depends on ASH || SH_IS_ASH || BASH_IS_ASH | 130 | //config: depends on ASH || SH_IS_ASH || BASH_IS_ASH |
138 | //config: help | ||
139 | //config: Enable support for test builtin in ash. | ||
140 | //config: | 131 | //config: |
141 | //config:config ASH_HELP | 132 | //config:config ASH_HELP |
142 | //config: bool "help builtin" | 133 | //config: bool "help builtin" |
143 | //config: default y | 134 | //config: default y |
144 | //config: depends on ASH || SH_IS_ASH || BASH_IS_ASH | 135 | //config: depends on ASH || SH_IS_ASH || BASH_IS_ASH |
145 | //config: help | ||
146 | //config: Enable help builtin in ash. | ||
147 | //config: | 136 | //config: |
148 | //config:config ASH_CMDCMD | 137 | //config:config ASH_GETOPTS |
149 | //config: bool "'command' command to override shell builtins" | 138 | //config: bool "getopts builtin" |
150 | //config: default y | 139 | //config: default y |
151 | //config: depends on ASH || SH_IS_ASH || BASH_IS_ASH | 140 | //config: depends on ASH || SH_IS_ASH || BASH_IS_ASH |
152 | //config: help | ||
153 | //config: Enable support for the ash 'command' builtin, which allows | ||
154 | //config: you to run the specified command with the specified arguments, | ||
155 | //config: even when there is an ash builtin command with the same name. | ||
156 | //config: | 141 | //config: |
157 | //config:config ASH_MAIL | 142 | //config:config ASH_CMDCMD |
158 | //config: bool "Check for new mail on interactive shells" | 143 | //config: bool "command builtin" |
159 | //config: default y | 144 | //config: default y |
160 | //config: depends on ASH || SH_IS_ASH || BASH_IS_ASH | 145 | //config: depends on ASH || SH_IS_ASH || BASH_IS_ASH |
161 | //config: help | 146 | //config: help |
162 | //config: Enable "check for new mail" function in the ash shell. | 147 | //config: Enable support for the 'command' builtin, which allows |
148 | //config: you to run the specified command or builtin, | ||
149 | //config: even when there is a function with the same name. | ||
163 | //config: | 150 | //config: |
164 | //config: | 151 | //config: |
165 | //config:config ASH_NOCONSOLE | 152 | //config:config ASH_NOCONSOLE |
@@ -176,7 +163,8 @@ | |||
176 | //config:endif # ash options | 163 | //config:endif # ash options |
177 | 164 | ||
178 | //applet:IF_ASH(APPLET(ash, BB_DIR_BIN, BB_SUID_DROP)) | 165 | //applet:IF_ASH(APPLET(ash, BB_DIR_BIN, BB_SUID_DROP)) |
179 | //applet:IF_SH_IS_ASH(APPLET_ODDNAME(sh, ash, BB_DIR_BIN, BB_SUID_DROP, ash)) | 166 | // APPLET_ODDNAME:name main location suid_type help |
167 | //applet:IF_SH_IS_ASH( APPLET_ODDNAME(sh, ash, BB_DIR_BIN, BB_SUID_DROP, ash)) | ||
180 | //applet:IF_BASH_IS_ASH(APPLET_ODDNAME(bash, ash, BB_DIR_BIN, BB_SUID_DROP, ash)) | 168 | //applet:IF_BASH_IS_ASH(APPLET_ODDNAME(bash, ash, BB_DIR_BIN, BB_SUID_DROP, ash)) |
181 | 169 | ||
182 | //kbuild:lib-$(CONFIG_ASH) += ash.o ash_ptr_hack.o shell_common.o | 170 | //kbuild:lib-$(CONFIG_ASH) += ash.o ash_ptr_hack.o shell_common.o |
@@ -185,15 +173,10 @@ | |||
185 | //kbuild:lib-$(CONFIG_ASH_RANDOM_SUPPORT) += random.o | 173 | //kbuild:lib-$(CONFIG_ASH_RANDOM_SUPPORT) += random.o |
186 | 174 | ||
187 | /* | 175 | /* |
188 | * The following should be set to reflect the type of system you have: | 176 | * DEBUG=1 to compile in debugging ('set -o debug' turns on) |
189 | * JOBS -> 1 if you have Berkeley job control, 0 otherwise. | 177 | * DEBUG=2 to compile in and turn on debugging. |
190 | * define SYSV if you are running under System V. | 178 | * When debugging is on ("set -o debug" was executed, or DEBUG=2), |
191 | * define DEBUG=1 to compile in debugging ('set -o debug' to turn on) | 179 | * debugging info is written to ./trace, quit signal generates core dump. |
192 | * define DEBUG=2 to compile in and turn on debugging. | ||
193 | * | ||
194 | * When debugging is on (DEBUG is 1 and "set -o debug" was executed), | ||
195 | * debugging info will be written to ./trace and a quit signal | ||
196 | * will generate a core dump. | ||
197 | */ | 180 | */ |
198 | #define DEBUG 0 | 181 | #define DEBUG 0 |
199 | /* Tweak debug output verbosity here */ | 182 | /* Tweak debug output verbosity here */ |
@@ -210,9 +193,30 @@ | |||
210 | #include <fnmatch.h> | 193 | #include <fnmatch.h> |
211 | #include <sys/times.h> | 194 | #include <sys/times.h> |
212 | #include <sys/utsname.h> /* for setting $HOSTNAME */ | 195 | #include <sys/utsname.h> /* for setting $HOSTNAME */ |
213 | |||
214 | #include "busybox.h" /* for applet_names */ | 196 | #include "busybox.h" /* for applet_names */ |
215 | 197 | ||
198 | /* So far, all bash compat is controlled by one config option */ | ||
199 | /* Separate defines document which part of code implements what */ | ||
200 | /* function keyword */ | ||
201 | #define BASH_FUNCTION ENABLE_ASH_BASH_COMPAT | ||
202 | #define IF_BASH_FUNCTION IF_ASH_BASH_COMPAT | ||
203 | /* &>file */ | ||
204 | #define BASH_REDIR_OUTPUT ENABLE_ASH_BASH_COMPAT | ||
205 | #define IF_BASH_REDIR_OUTPUT IF_ASH_BASH_COMPAT | ||
206 | /* $'...' */ | ||
207 | #define BASH_DOLLAR_SQUOTE ENABLE_ASH_BASH_COMPAT | ||
208 | #define IF_BASH_DOLLAR_SQUOTE IF_ASH_BASH_COMPAT | ||
209 | #define BASH_PATTERN_SUBST ENABLE_ASH_BASH_COMPAT | ||
210 | #define IF_BASH_PATTERN_SUBST IF_ASH_BASH_COMPAT | ||
211 | #define BASH_SUBSTR ENABLE_ASH_BASH_COMPAT | ||
212 | #define IF_BASH_SUBSTR IF_ASH_BASH_COMPAT | ||
213 | /* [[ EXPR ]] */ | ||
214 | #define BASH_TEST2 (ENABLE_ASH_BASH_COMPAT * ENABLE_ASH_TEST) | ||
215 | #define BASH_SOURCE ENABLE_ASH_BASH_COMPAT | ||
216 | #define BASH_PIPEFAIL ENABLE_ASH_BASH_COMPAT | ||
217 | #define BASH_HOSTNAME_VAR ENABLE_ASH_BASH_COMPAT | ||
218 | #define BASH_SHLVL_VAR ENABLE_ASH_BASH_COMPAT | ||
219 | |||
216 | #if defined(__ANDROID_API__) && __ANDROID_API__ <= 24 | 220 | #if defined(__ANDROID_API__) && __ANDROID_API__ <= 24 |
217 | /* Bionic at least up to version 24 has no glob() */ | 221 | /* Bionic at least up to version 24 has no glob() */ |
218 | # undef ENABLE_ASH_INTERNAL_GLOB | 222 | # undef ENABLE_ASH_INTERNAL_GLOB |
@@ -338,7 +342,7 @@ static const char *const optletters_optnames[] = { | |||
338 | "b" "notify", | 342 | "b" "notify", |
339 | "u" "nounset", | 343 | "u" "nounset", |
340 | "\0" "vi" | 344 | "\0" "vi" |
341 | #if ENABLE_ASH_BASH_COMPAT | 345 | #if BASH_PIPEFAIL |
342 | ,"\0" "pipefail" | 346 | ,"\0" "pipefail" |
343 | #endif | 347 | #endif |
344 | #if DEBUG | 348 | #if DEBUG |
@@ -421,14 +425,14 @@ struct globals_misc { | |||
421 | #define bflag optlist[11] | 425 | #define bflag optlist[11] |
422 | #define uflag optlist[12] | 426 | #define uflag optlist[12] |
423 | #define viflag optlist[13] | 427 | #define viflag optlist[13] |
424 | #if ENABLE_ASH_BASH_COMPAT | 428 | #if BASH_PIPEFAIL |
425 | # define pipefail optlist[14] | 429 | # define pipefail optlist[14] |
426 | #else | 430 | #else |
427 | # define pipefail 0 | 431 | # define pipefail 0 |
428 | #endif | 432 | #endif |
429 | #if DEBUG | 433 | #if DEBUG |
430 | # define nolog optlist[14 + ENABLE_ASH_BASH_COMPAT] | 434 | # define nolog optlist[14 + BASH_PIPEFAIL] |
431 | # define debug optlist[15 + ENABLE_ASH_BASH_COMPAT] | 435 | # define debug optlist[15 + BASH_PIPEFAIL] |
432 | #endif | 436 | #endif |
433 | #if ENABLE_PLATFORM_MINGW32 | 437 | #if ENABLE_PLATFORM_MINGW32 |
434 | # define winxp optlist[14 + ENABLE_ASH_BASH_COMPAT + 2*DEBUG] | 438 | # define winxp optlist[14 + ENABLE_ASH_BASH_COMPAT + 2*DEBUG] |
@@ -755,8 +759,10 @@ out2str(const char *p) | |||
755 | #define VSTRIMLEFT 0x8 /* ${var#pattern} */ | 759 | #define VSTRIMLEFT 0x8 /* ${var#pattern} */ |
756 | #define VSTRIMLEFTMAX 0x9 /* ${var##pattern} */ | 760 | #define VSTRIMLEFTMAX 0x9 /* ${var##pattern} */ |
757 | #define VSLENGTH 0xa /* ${#var} */ | 761 | #define VSLENGTH 0xa /* ${#var} */ |
758 | #if ENABLE_ASH_BASH_COMPAT | 762 | #if BASH_SUBSTR |
759 | #define VSSUBSTR 0xc /* ${var:position:length} */ | 763 | #define VSSUBSTR 0xc /* ${var:position:length} */ |
764 | #endif | ||
765 | #if BASH_PATTERN_SUBST | ||
760 | #define VSREPLACE 0xd /* ${var/pattern/replacement} */ | 766 | #define VSREPLACE 0xd /* ${var/pattern/replacement} */ |
761 | #define VSREPLACEALL 0xe /* ${var//pattern/replacement} */ | 767 | #define VSREPLACEALL 0xe /* ${var//pattern/replacement} */ |
762 | #endif | 768 | #endif |
@@ -783,7 +789,7 @@ static const char dolatstr[] ALIGN1 = { | |||
783 | #define NDEFUN 14 | 789 | #define NDEFUN 14 |
784 | #define NARG 15 | 790 | #define NARG 15 |
785 | #define NTO 16 | 791 | #define NTO 16 |
786 | #if ENABLE_ASH_BASH_COMPAT | 792 | #if BASH_REDIR_OUTPUT |
787 | #define NTO2 17 | 793 | #define NTO2 17 |
788 | #endif | 794 | #endif |
789 | #define NCLOBBER 18 | 795 | #define NCLOBBER 18 |
@@ -1193,7 +1199,7 @@ shcmd(union node *cmd, FILE *fp) | |||
1193 | case NTO: s = ">>"+1; dftfd = 1; break; | 1199 | case NTO: s = ">>"+1; dftfd = 1; break; |
1194 | case NCLOBBER: s = ">|"; dftfd = 1; break; | 1200 | case NCLOBBER: s = ">|"; dftfd = 1; break; |
1195 | case NAPPEND: s = ">>"; dftfd = 1; break; | 1201 | case NAPPEND: s = ">>"; dftfd = 1; break; |
1196 | #if ENABLE_ASH_BASH_COMPAT | 1202 | #if BASH_REDIR_OUTPUT |
1197 | case NTO2: | 1203 | case NTO2: |
1198 | #endif | 1204 | #endif |
1199 | case NTOFD: s = ">&"; dftfd = 1; break; | 1205 | case NTOFD: s = ">&"; dftfd = 1; break; |
@@ -3599,12 +3605,13 @@ struct job { | |||
3599 | #if JOBS | 3605 | #if JOBS |
3600 | int stopstatus; /* status of a stopped job */ | 3606 | int stopstatus; /* status of a stopped job */ |
3601 | #endif | 3607 | #endif |
3602 | uint32_t | 3608 | unsigned nprocs; /* number of processes */ |
3603 | nprocs: 16, /* number of processes */ | 3609 | |
3604 | state: 8, | ||
3605 | #define JOBRUNNING 0 /* at least one proc running */ | 3610 | #define JOBRUNNING 0 /* at least one proc running */ |
3606 | #define JOBSTOPPED 1 /* all procs are stopped */ | 3611 | #define JOBSTOPPED 1 /* all procs are stopped */ |
3607 | #define JOBDONE 2 /* all procs are completed */ | 3612 | #define JOBDONE 2 /* all procs are completed */ |
3613 | unsigned | ||
3614 | state: 8, | ||
3608 | #if JOBS | 3615 | #if JOBS |
3609 | sigint: 1, /* job was killed by SIGINT */ | 3616 | sigint: 1, /* job was killed by SIGINT */ |
3610 | jobctl: 1, /* job running under job control */ | 3617 | jobctl: 1, /* job running under job control */ |
@@ -3791,6 +3798,72 @@ static struct job *curjob; //lots | |||
3791 | /* number of presumed living untracked jobs */ | 3798 | /* number of presumed living untracked jobs */ |
3792 | static int jobless; //4 | 3799 | static int jobless; //4 |
3793 | 3800 | ||
3801 | #if 0 | ||
3802 | /* Bash has a feature: it restores termios after a successful wait for | ||
3803 | * a foreground job which had at least one stopped or sigkilled member. | ||
3804 | * The probable rationale is that SIGSTOP and SIGKILL can preclude task from | ||
3805 | * properly restoring tty state. Should we do this too? | ||
3806 | * A reproducer: ^Z an interactive python: | ||
3807 | * | ||
3808 | * # python | ||
3809 | * Python 2.7.12 (...) | ||
3810 | * >>> ^Z | ||
3811 | * { python leaves tty in -icanon -echo state. We do survive that... } | ||
3812 | * [1]+ Stopped python | ||
3813 | * { ...however, next program (python #2) does not survive it well: } | ||
3814 | * # python | ||
3815 | * Python 2.7.12 (...) | ||
3816 | * >>> Traceback (most recent call last): | ||
3817 | * { above, I typed "qwerty<CR>", but -echo state is still in effect } | ||
3818 | * File "<stdin>", line 1, in <module> | ||
3819 | * NameError: name 'qwerty' is not defined | ||
3820 | * | ||
3821 | * The implementation below is modeled on bash code and seems to work. | ||
3822 | * However, I'm not sure we should do this. For one: what if I'd fg | ||
3823 | * the stopped python instead? It'll be confused by "restored" tty state. | ||
3824 | */ | ||
3825 | static struct termios shell_tty_info; | ||
3826 | static void | ||
3827 | get_tty_state(void) | ||
3828 | { | ||
3829 | if (rootshell && ttyfd >= 0) | ||
3830 | tcgetattr(ttyfd, &shell_tty_info); | ||
3831 | } | ||
3832 | static void | ||
3833 | set_tty_state(void) | ||
3834 | { | ||
3835 | /* if (rootshell) - caller ensures this */ | ||
3836 | if (ttyfd >= 0) | ||
3837 | tcsetattr(ttyfd, TCSADRAIN, &shell_tty_info); | ||
3838 | } | ||
3839 | static int | ||
3840 | job_signal_status(struct job *jp) | ||
3841 | { | ||
3842 | int status; | ||
3843 | unsigned i; | ||
3844 | struct procstat *ps = jp->ps; | ||
3845 | for (i = 0; i < jp->nprocs; i++) { | ||
3846 | status = ps[i].ps_status; | ||
3847 | if (WIFSIGNALED(status) || WIFSTOPPED(status)) | ||
3848 | return status; | ||
3849 | } | ||
3850 | return 0; | ||
3851 | } | ||
3852 | static void | ||
3853 | restore_tty_if_stopped_or_signaled(struct job *jp) | ||
3854 | { | ||
3855 | //TODO: check what happens if we come from waitforjob() in expbackq() | ||
3856 | if (rootshell) { | ||
3857 | int s = job_signal_status(jp); | ||
3858 | if (s) /* WIFSIGNALED(s) || WIFSTOPPED(s) */ | ||
3859 | set_tty_state(); | ||
3860 | } | ||
3861 | } | ||
3862 | #else | ||
3863 | # define get_tty_state() ((void)0) | ||
3864 | # define restore_tty_if_stopped_or_signaled(jp) ((void)0) | ||
3865 | #endif | ||
3866 | |||
3794 | static void | 3867 | static void |
3795 | set_curjob(struct job *jp, unsigned mode) | 3868 | set_curjob(struct job *jp, unsigned mode) |
3796 | { | 3869 | { |
@@ -4122,8 +4195,10 @@ restartjob(struct job *jp, int mode) | |||
4122 | goto out; | 4195 | goto out; |
4123 | jp->state = JOBRUNNING; | 4196 | jp->state = JOBRUNNING; |
4124 | pgid = jp->ps[0].ps_pid; | 4197 | pgid = jp->ps[0].ps_pid; |
4125 | if (mode == FORK_FG) | 4198 | if (mode == FORK_FG) { |
4199 | get_tty_state(); | ||
4126 | xtcsetpgrp(ttyfd, pgid); | 4200 | xtcsetpgrp(ttyfd, pgid); |
4201 | } | ||
4127 | killpg(pgid, SIGCONT); | 4202 | killpg(pgid, SIGCONT); |
4128 | ps = jp->ps; | 4203 | ps = jp->ps; |
4129 | i = jp->nprocs; | 4204 | i = jp->nprocs; |
@@ -4754,7 +4829,7 @@ makejob(/*union node *node,*/ int nprocs) | |||
4754 | memset(jp, 0, sizeof(*jp)); | 4829 | memset(jp, 0, sizeof(*jp)); |
4755 | #if JOBS | 4830 | #if JOBS |
4756 | /* jp->jobctl is a bitfield. | 4831 | /* jp->jobctl is a bitfield. |
4757 | * "jp->jobctl |= jobctl" likely to give awful code */ | 4832 | * "jp->jobctl |= doing_jobctl" likely to give awful code */ |
4758 | if (doing_jobctl) | 4833 | if (doing_jobctl) |
4759 | jp->jobctl = 1; | 4834 | jp->jobctl = 1; |
4760 | #endif | 4835 | #endif |
@@ -4783,7 +4858,8 @@ cmdputs(const char *s) | |||
4783 | static const char vstype[VSTYPE + 1][3] = { | 4858 | static const char vstype[VSTYPE + 1][3] = { |
4784 | "", "}", "-", "+", "?", "=", | 4859 | "", "}", "-", "+", "?", "=", |
4785 | "%", "%%", "#", "##" | 4860 | "%", "%%", "#", "##" |
4786 | IF_ASH_BASH_COMPAT(, ":", "/", "//") | 4861 | IF_BASH_SUBSTR(, ":") |
4862 | IF_BASH_PATTERN_SUBST(, "/", "//") | ||
4787 | }; | 4863 | }; |
4788 | 4864 | ||
4789 | const char *p, *str; | 4865 | const char *p, *str; |
@@ -5010,7 +5086,7 @@ cmdtxt(union node *n) | |||
5010 | case NAPPEND: | 5086 | case NAPPEND: |
5011 | p = ">>"; | 5087 | p = ">>"; |
5012 | goto redir; | 5088 | goto redir; |
5013 | #if ENABLE_ASH_BASH_COMPAT | 5089 | #if BASH_REDIR_OUTPUT |
5014 | case NTO2: | 5090 | case NTO2: |
5015 | #endif | 5091 | #endif |
5016 | case NTOFD: | 5092 | case NTOFD: |
@@ -5362,6 +5438,8 @@ waitforjob(struct job *jp) | |||
5362 | #if JOBS | 5438 | #if JOBS |
5363 | if (jp->jobctl) { | 5439 | if (jp->jobctl) { |
5364 | xtcsetpgrp(ttyfd, rootpid); | 5440 | xtcsetpgrp(ttyfd, rootpid); |
5441 | restore_tty_if_stopped_or_signaled(jp); | ||
5442 | |||
5365 | /* | 5443 | /* |
5366 | * This is truly gross. | 5444 | * This is truly gross. |
5367 | * If we're doing job control, then we did a TIOCSPGRP which | 5445 | * If we're doing job control, then we did a TIOCSPGRP which |
@@ -5587,7 +5665,7 @@ openredirect(union node *redir) | |||
5587 | goto ecreate; | 5665 | goto ecreate; |
5588 | break; | 5666 | break; |
5589 | case NTO: | 5667 | case NTO: |
5590 | #if ENABLE_ASH_BASH_COMPAT | 5668 | #if BASH_REDIR_OUTPUT |
5591 | case NTO2: | 5669 | case NTO2: |
5592 | #endif | 5670 | #endif |
5593 | /* Take care of noclobber mode. */ | 5671 | /* Take care of noclobber mode. */ |
@@ -5751,7 +5829,7 @@ redirect(union node *redir, int flags) | |||
5751 | union node *tmp = redir; | 5829 | union node *tmp = redir; |
5752 | do { | 5830 | do { |
5753 | sv_pos++; | 5831 | sv_pos++; |
5754 | #if ENABLE_ASH_BASH_COMPAT | 5832 | #if BASH_REDIR_OUTPUT |
5755 | if (tmp->nfile.type == NTO2) | 5833 | if (tmp->nfile.type == NTO2) |
5756 | sv_pos++; | 5834 | sv_pos++; |
5757 | #endif | 5835 | #endif |
@@ -5793,7 +5871,7 @@ redirect(union node *redir, int flags) | |||
5793 | continue; | 5871 | continue; |
5794 | } | 5872 | } |
5795 | } | 5873 | } |
5796 | #if ENABLE_ASH_BASH_COMPAT | 5874 | #if BASH_REDIR_OUTPUT |
5797 | redirect_more: | 5875 | redirect_more: |
5798 | #endif | 5876 | #endif |
5799 | if (need_to_remember(sv, fd)) { | 5877 | if (need_to_remember(sv, fd)) { |
@@ -5846,12 +5924,12 @@ redirect(union node *redir, int flags) | |||
5846 | } | 5924 | } |
5847 | } else if (fd != newfd) { /* move newfd to fd */ | 5925 | } else if (fd != newfd) { /* move newfd to fd */ |
5848 | dup2_or_raise(newfd, fd); | 5926 | dup2_or_raise(newfd, fd); |
5849 | #if ENABLE_ASH_BASH_COMPAT | 5927 | #if BASH_REDIR_OUTPUT |
5850 | if (!(redir->nfile.type == NTO2 && fd == 2)) | 5928 | if (!(redir->nfile.type == NTO2 && fd == 2)) |
5851 | #endif | 5929 | #endif |
5852 | close(newfd); | 5930 | close(newfd); |
5853 | } | 5931 | } |
5854 | #if ENABLE_ASH_BASH_COMPAT | 5932 | #if BASH_REDIR_OUTPUT |
5855 | if (redir->nfile.type == NTO2 && fd == 1) { | 5933 | if (redir->nfile.type == NTO2 && fd == 1) { |
5856 | /* We already redirected it to fd 1, now copy it to 2 */ | 5934 | /* We already redirected it to fd 1, now copy it to 2 */ |
5857 | newfd = 1; | 5935 | newfd = 1; |
@@ -6168,15 +6246,15 @@ static char * | |||
6168 | rmescapes(char *str, int flag) | 6246 | rmescapes(char *str, int flag) |
6169 | { | 6247 | { |
6170 | static const char qchars[] ALIGN1 = { | 6248 | static const char qchars[] ALIGN1 = { |
6171 | IF_ASH_BASH_COMPAT('/',) CTLESC, CTLQUOTEMARK, '\0' }; | 6249 | IF_BASH_PATTERN_SUBST('/',) CTLESC, CTLQUOTEMARK, '\0' }; |
6172 | 6250 | ||
6173 | char *p, *q, *r; | 6251 | char *p, *q, *r; |
6174 | unsigned inquotes; | 6252 | unsigned inquotes; |
6175 | unsigned protect_against_glob; | 6253 | unsigned protect_against_glob; |
6176 | unsigned globbing; | 6254 | unsigned globbing; |
6177 | IF_ASH_BASH_COMPAT(unsigned slash = flag & RMESCAPE_SLASH;) | 6255 | IF_BASH_PATTERN_SUBST(unsigned slash = flag & RMESCAPE_SLASH;) |
6178 | 6256 | ||
6179 | p = strpbrk(str, qchars IF_ASH_BASH_COMPAT(+ !slash)); | 6257 | p = strpbrk(str, qchars IF_BASH_PATTERN_SUBST(+ !slash)); |
6180 | if (!p) | 6258 | if (!p) |
6181 | return str; | 6259 | return str; |
6182 | 6260 | ||
@@ -6228,7 +6306,7 @@ rmescapes(char *str, int flag) | |||
6228 | protect_against_glob = 0; | 6306 | protect_against_glob = 0; |
6229 | goto copy; | 6307 | goto copy; |
6230 | } | 6308 | } |
6231 | #if ENABLE_ASH_BASH_COMPAT | 6309 | #if BASH_PATTERN_SUBST |
6232 | else if (*p == '/' && slash) { | 6310 | else if (*p == '/' && slash) { |
6233 | /* stop handling globbing and mark location of slash */ | 6311 | /* stop handling globbing and mark location of slash */ |
6234 | globbing = slash = 0; | 6312 | globbing = slash = 0; |
@@ -6887,10 +6965,10 @@ subevalvar(char *p, char *varname, int strloc, int subtype, | |||
6887 | char *loc; | 6965 | char *loc; |
6888 | char *rmesc, *rmescend; | 6966 | char *rmesc, *rmescend; |
6889 | char *str; | 6967 | char *str; |
6890 | IF_ASH_BASH_COMPAT(char *repl = NULL;) | 6968 | IF_BASH_SUBSTR(int pos, len, orig_len;) |
6891 | IF_ASH_BASH_COMPAT(int pos, len, orig_len;) | ||
6892 | int amount, resetloc; | 6969 | int amount, resetloc; |
6893 | IF_ASH_BASH_COMPAT(int workloc;) | 6970 | IF_BASH_PATTERN_SUBST(int workloc;) |
6971 | IF_BASH_PATTERN_SUBST(char *repl = NULL;) | ||
6894 | int zero; | 6972 | int zero; |
6895 | char *(*scan)(char*, char*, char*, char*, int, int); | 6973 | char *(*scan)(char*, char*, char*, char*, int, int); |
6896 | 6974 | ||
@@ -6915,7 +6993,7 @@ subevalvar(char *p, char *varname, int strloc, int subtype, | |||
6915 | varunset(p, varname, startp, varflags); | 6993 | varunset(p, varname, startp, varflags); |
6916 | /* NOTREACHED */ | 6994 | /* NOTREACHED */ |
6917 | 6995 | ||
6918 | #if ENABLE_ASH_BASH_COMPAT | 6996 | #if BASH_SUBSTR |
6919 | case VSSUBSTR: | 6997 | case VSSUBSTR: |
6920 | //TODO: support more general format ${v:EXPR:EXPR}, | 6998 | //TODO: support more general format ${v:EXPR:EXPR}, |
6921 | // where EXPR follows $(()) rules | 6999 | // where EXPR follows $(()) rules |
@@ -6984,17 +7062,19 @@ subevalvar(char *p, char *varname, int strloc, int subtype, | |||
6984 | amount = loc - expdest; | 7062 | amount = loc - expdest; |
6985 | STADJUST(amount, expdest); | 7063 | STADJUST(amount, expdest); |
6986 | return loc; | 7064 | return loc; |
6987 | #endif | 7065 | #endif /* BASH_SUBSTR */ |
6988 | } | 7066 | } |
6989 | 7067 | ||
6990 | resetloc = expdest - (char *)stackblock(); | 7068 | resetloc = expdest - (char *)stackblock(); |
6991 | 7069 | ||
7070 | #if BASH_PATTERN_SUBST | ||
6992 | /* We'll comeback here if we grow the stack while handling | 7071 | /* We'll comeback here if we grow the stack while handling |
6993 | * a VSREPLACE or VSREPLACEALL, since our pointers into the | 7072 | * a VSREPLACE or VSREPLACEALL, since our pointers into the |
6994 | * stack will need rebasing, and we'll need to remove our work | 7073 | * stack will need rebasing, and we'll need to remove our work |
6995 | * areas each time | 7074 | * areas each time |
6996 | */ | 7075 | */ |
6997 | IF_ASH_BASH_COMPAT(restart:) | 7076 | restart: |
7077 | #endif | ||
6998 | 7078 | ||
6999 | amount = expdest - ((char *)stackblock() + resetloc); | 7079 | amount = expdest - ((char *)stackblock() + resetloc); |
7000 | STADJUST(-amount, expdest); | 7080 | STADJUST(-amount, expdest); |
@@ -7019,11 +7099,11 @@ subevalvar(char *p, char *varname, int strloc, int subtype, | |||
7019 | * RMESCAPE_SLASH causes preglob to work differently on the pattern | 7099 | * RMESCAPE_SLASH causes preglob to work differently on the pattern |
7020 | * and string. It's only used on the first call. | 7100 | * and string. It's only used on the first call. |
7021 | */ | 7101 | */ |
7022 | preglob(str, IF_ASH_BASH_COMPAT( | 7102 | preglob(str, IF_BASH_PATTERN_SUBST( |
7023 | (subtype == VSREPLACE || subtype == VSREPLACEALL) && !repl ? | 7103 | (subtype == VSREPLACE || subtype == VSREPLACEALL) && !repl ? |
7024 | RMESCAPE_SLASH :) 0); | 7104 | RMESCAPE_SLASH : ) 0); |
7025 | 7105 | ||
7026 | #if ENABLE_ASH_BASH_COMPAT | 7106 | #if BASH_PATTERN_SUBST |
7027 | workloc = expdest - (char *)stackblock(); | 7107 | workloc = expdest - (char *)stackblock(); |
7028 | if (subtype == VSREPLACE || subtype == VSREPLACEALL) { | 7108 | if (subtype == VSREPLACE || subtype == VSREPLACEALL) { |
7029 | char *idx, *end; | 7109 | char *idx, *end; |
@@ -7124,7 +7204,7 @@ subevalvar(char *p, char *varname, int strloc, int subtype, | |||
7124 | STADJUST(-amount, expdest); | 7204 | STADJUST(-amount, expdest); |
7125 | return startp; | 7205 | return startp; |
7126 | } | 7206 | } |
7127 | #endif /* ENABLE_ASH_BASH_COMPAT */ | 7207 | #endif /* BASH_PATTERN_SUBST */ |
7128 | 7208 | ||
7129 | subtype -= VSTRIMRIGHT; | 7209 | subtype -= VSTRIMRIGHT; |
7130 | #if DEBUG | 7210 | #if DEBUG |
@@ -7392,8 +7472,10 @@ evalvar(char *p, int flag, struct strlist *var_str_list) | |||
7392 | case VSTRIMLEFTMAX: | 7472 | case VSTRIMLEFTMAX: |
7393 | case VSTRIMRIGHT: | 7473 | case VSTRIMRIGHT: |
7394 | case VSTRIMRIGHTMAX: | 7474 | case VSTRIMRIGHTMAX: |
7395 | #if ENABLE_ASH_BASH_COMPAT | 7475 | #if BASH_SUBSTR |
7396 | case VSSUBSTR: | 7476 | case VSSUBSTR: |
7477 | #endif | ||
7478 | #if BASH_PATTERN_SUBST | ||
7397 | case VSREPLACE: | 7479 | case VSREPLACE: |
7398 | case VSREPLACEALL: | 7480 | case VSREPLACEALL: |
7399 | #endif | 7481 | #endif |
@@ -7458,6 +7540,57 @@ addfname(const char *name) | |||
7458 | exparg.lastp = &sp->next; | 7540 | exparg.lastp = &sp->next; |
7459 | } | 7541 | } |
7460 | 7542 | ||
7543 | /* Avoid glob() (and thus, stat() et al) for words like "echo" */ | ||
7544 | static int | ||
7545 | hasmeta(const char *p) | ||
7546 | { | ||
7547 | static const char chars[] ALIGN1 = { | ||
7548 | '*', '?', '[', '\\', CTLQUOTEMARK, CTLESC, 0 | ||
7549 | }; | ||
7550 | |||
7551 | for (;;) { | ||
7552 | p = strpbrk(p, chars); | ||
7553 | if (!p) | ||
7554 | break; | ||
7555 | switch ((unsigned char) *p) { | ||
7556 | case CTLQUOTEMARK: | ||
7557 | for (;;) { | ||
7558 | p++; | ||
7559 | if (*p == CTLQUOTEMARK) | ||
7560 | break; | ||
7561 | if (*p == CTLESC) | ||
7562 | p++; | ||
7563 | if (*p == '\0') /* huh? */ | ||
7564 | return 0; | ||
7565 | } | ||
7566 | break; | ||
7567 | case '\\': | ||
7568 | case CTLESC: | ||
7569 | p++; | ||
7570 | if (*p == '\0') | ||
7571 | return 0; | ||
7572 | break; | ||
7573 | case '[': | ||
7574 | if (!strchr(p + 1, ']')) { | ||
7575 | /* It's not a properly closed [] pattern, | ||
7576 | * but other metas may follow. Continue checking. | ||
7577 | * my[file* _is_ globbed by bash | ||
7578 | * and matches filenames like "my[file1". | ||
7579 | */ | ||
7580 | break; | ||
7581 | } | ||
7582 | /* fallthrough */ | ||
7583 | default: | ||
7584 | /* case '*': */ | ||
7585 | /* case '?': */ | ||
7586 | return 1; | ||
7587 | } | ||
7588 | p++; | ||
7589 | } | ||
7590 | |||
7591 | return 0; | ||
7592 | } | ||
7593 | |||
7461 | /* If we want to use glob() from libc... */ | 7594 | /* If we want to use glob() from libc... */ |
7462 | #if !ENABLE_ASH_INTERNAL_GLOB | 7595 | #if !ENABLE_ASH_INTERNAL_GLOB |
7463 | 7596 | ||
@@ -7484,20 +7617,9 @@ expandmeta(struct strlist *str /*, int flag*/) | |||
7484 | if (fflag) | 7617 | if (fflag) |
7485 | goto nometa; | 7618 | goto nometa; |
7486 | 7619 | ||
7487 | /* Avoid glob() (and thus, stat() et al) for words like "echo" */ | 7620 | if (!hasmeta(str->text)) |
7488 | p = str->text; | 7621 | goto nometa; |
7489 | while (*p) { | ||
7490 | if (*p == '*') | ||
7491 | goto need_glob; | ||
7492 | if (*p == '?') | ||
7493 | goto need_glob; | ||
7494 | if (*p == '[') | ||
7495 | goto need_glob; | ||
7496 | p++; | ||
7497 | } | ||
7498 | goto nometa; | ||
7499 | 7622 | ||
7500 | need_glob: | ||
7501 | INT_OFF; | 7623 | INT_OFF; |
7502 | p = preglob(str->text, RMESCAPE_ALLOC | RMESCAPE_HEAP); | 7624 | p = preglob(str->text, RMESCAPE_ALLOC | RMESCAPE_HEAP); |
7503 | // GLOB_NOMAGIC (GNU): if no *?[ chars in pattern, return it even if no match | 7625 | // GLOB_NOMAGIC (GNU): if no *?[ chars in pattern, return it even if no match |
@@ -7734,9 +7856,6 @@ expsort(struct strlist *str) | |||
7734 | static void | 7856 | static void |
7735 | expandmeta(struct strlist *str /*, int flag*/) | 7857 | expandmeta(struct strlist *str /*, int flag*/) |
7736 | { | 7858 | { |
7737 | static const char metachars[] ALIGN1 = { | ||
7738 | '*', '?', '[', 0 | ||
7739 | }; | ||
7740 | /* TODO - EXP_REDIR */ | 7859 | /* TODO - EXP_REDIR */ |
7741 | 7860 | ||
7742 | while (str) { | 7861 | while (str) { |
@@ -7747,7 +7866,7 @@ expandmeta(struct strlist *str /*, int flag*/) | |||
7747 | 7866 | ||
7748 | if (fflag) | 7867 | if (fflag) |
7749 | goto nometa; | 7868 | goto nometa; |
7750 | if (!strpbrk(str->text, metachars)) | 7869 | if (!hasmeta(str->text)) |
7751 | goto nometa; | 7870 | goto nometa; |
7752 | savelastp = exparg.lastp; | 7871 | savelastp = exparg.lastp; |
7753 | 7872 | ||
@@ -8322,7 +8441,7 @@ enum { | |||
8322 | TESAC, | 8441 | TESAC, |
8323 | TFI, | 8442 | TFI, |
8324 | TFOR, | 8443 | TFOR, |
8325 | #if ENABLE_ASH_BASH_COMPAT | 8444 | #if BASH_FUNCTION |
8326 | TFUNCTION, | 8445 | TFUNCTION, |
8327 | #endif | 8446 | #endif |
8328 | TIF, | 8447 | TIF, |
@@ -8360,7 +8479,7 @@ enum { | |||
8360 | /* 19 */ | (1u << TESAC) | 8479 | /* 19 */ | (1u << TESAC) |
8361 | /* 20 */ | (1u << TFI) | 8480 | /* 20 */ | (1u << TFI) |
8362 | /* 21 */ | (0u << TFOR) | 8481 | /* 21 */ | (0u << TFOR) |
8363 | #if ENABLE_ASH_BASH_COMPAT | 8482 | #if BASH_FUNCTION |
8364 | /* 22 */ | (0u << TFUNCTION) | 8483 | /* 22 */ | (0u << TFUNCTION) |
8365 | #endif | 8484 | #endif |
8366 | /* 23 */ | (0u << TIF) | 8485 | /* 23 */ | (0u << TIF) |
@@ -8398,7 +8517,7 @@ static const char *const tokname_array[] = { | |||
8398 | "esac", | 8517 | "esac", |
8399 | "fi", | 8518 | "fi", |
8400 | "for", | 8519 | "for", |
8401 | #if ENABLE_ASH_BASH_COMPAT | 8520 | #if BASH_FUNCTION |
8402 | "function", | 8521 | "function", |
8403 | #endif | 8522 | #endif |
8404 | "if", | 8523 | "if", |
@@ -8646,7 +8765,7 @@ static const uint8_t nodesize[N_NUMBER] ALIGN1 = { | |||
8646 | [NDEFUN ] = SHELL_ALIGN(sizeof(struct narg)), | 8765 | [NDEFUN ] = SHELL_ALIGN(sizeof(struct narg)), |
8647 | [NARG ] = SHELL_ALIGN(sizeof(struct narg)), | 8766 | [NARG ] = SHELL_ALIGN(sizeof(struct narg)), |
8648 | [NTO ] = SHELL_ALIGN(sizeof(struct nfile)), | 8767 | [NTO ] = SHELL_ALIGN(sizeof(struct nfile)), |
8649 | #if ENABLE_ASH_BASH_COMPAT | 8768 | #if BASH_REDIR_OUTPUT |
8650 | [NTO2 ] = SHELL_ALIGN(sizeof(struct nfile)), | 8769 | [NTO2 ] = SHELL_ALIGN(sizeof(struct nfile)), |
8651 | #endif | 8770 | #endif |
8652 | [NCLOBBER ] = SHELL_ALIGN(sizeof(struct nfile)), | 8771 | [NCLOBBER ] = SHELL_ALIGN(sizeof(struct nfile)), |
@@ -8737,7 +8856,7 @@ calcsize(union node *n) | |||
8737 | IF_PLATFORM_MINGW32(nodeptrsize += 3); | 8856 | IF_PLATFORM_MINGW32(nodeptrsize += 3); |
8738 | break; | 8857 | break; |
8739 | case NTO: | 8858 | case NTO: |
8740 | #if ENABLE_ASH_BASH_COMPAT | 8859 | #if BASH_REDIR_OUTPUT |
8741 | case NTO2: | 8860 | case NTO2: |
8742 | #endif | 8861 | #endif |
8743 | case NCLOBBER: | 8862 | case NCLOBBER: |
@@ -8881,7 +9000,7 @@ copynode(union node *n) | |||
8881 | SAVE_PTR3(new->narg.backquote,new->narg.text,new->narg.next); | 9000 | SAVE_PTR3(new->narg.backquote,new->narg.text,new->narg.next); |
8882 | break; | 9001 | break; |
8883 | case NTO: | 9002 | case NTO: |
8884 | #if ENABLE_ASH_BASH_COMPAT | 9003 | #if BASH_REDIR_OUTPUT |
8885 | case NTO2: | 9004 | case NTO2: |
8886 | #endif | 9005 | #endif |
8887 | case NCLOBBER: | 9006 | case NCLOBBER: |
@@ -9277,13 +9396,15 @@ evalsubshell(union node *n, int flags) | |||
9277 | { | 9396 | { |
9278 | IF_PLATFORM_MINGW32(struct forkshell fs;) | 9397 | IF_PLATFORM_MINGW32(struct forkshell fs;) |
9279 | struct job *jp; | 9398 | struct job *jp; |
9280 | int backgnd = (n->type == NBACKGND); | 9399 | int backgnd = (n->type == NBACKGND); /* FORK_BG(1) if yes, else FORK_FG(0) */ |
9281 | int status; | 9400 | int status; |
9282 | 9401 | ||
9283 | expredir(n->nredir.redirect); | 9402 | expredir(n->nredir.redirect); |
9284 | if (!backgnd && (flags & EV_EXIT) && !may_have_traps) | 9403 | if (!backgnd && (flags & EV_EXIT) && !may_have_traps) |
9285 | goto nofork; | 9404 | goto nofork; |
9286 | INT_OFF; | 9405 | INT_OFF; |
9406 | if (backgnd == FORK_FG) | ||
9407 | get_tty_state(); | ||
9287 | jp = makejob(/*n,*/ 1); | 9408 | jp = makejob(/*n,*/ 1); |
9288 | #if ENABLE_PLATFORM_MINGW32 | 9409 | #if ENABLE_PLATFORM_MINGW32 |
9289 | memset(&fs, 0, sizeof(fs)); | 9410 | memset(&fs, 0, sizeof(fs)); |
@@ -9308,7 +9429,7 @@ evalsubshell(union node *n, int flags) | |||
9308 | } | 9429 | } |
9309 | /* parent */ | 9430 | /* parent */ |
9310 | status = 0; | 9431 | status = 0; |
9311 | if (!backgnd) | 9432 | if (backgnd == FORK_FG) |
9312 | status = waitforjob(jp); | 9433 | status = waitforjob(jp); |
9313 | INT_ON; | 9434 | INT_ON; |
9314 | return status; | 9435 | return status; |
@@ -9332,14 +9453,14 @@ expredir(union node *n) | |||
9332 | case NFROMTO: | 9453 | case NFROMTO: |
9333 | case NFROM: | 9454 | case NFROM: |
9334 | case NTO: | 9455 | case NTO: |
9335 | #if ENABLE_ASH_BASH_COMPAT | 9456 | #if BASH_REDIR_OUTPUT |
9336 | case NTO2: | 9457 | case NTO2: |
9337 | #endif | 9458 | #endif |
9338 | case NCLOBBER: | 9459 | case NCLOBBER: |
9339 | case NAPPEND: | 9460 | case NAPPEND: |
9340 | expandarg(redir->nfile.fname, &fn, EXP_TILDE | EXP_REDIR); | 9461 | expandarg(redir->nfile.fname, &fn, EXP_TILDE | EXP_REDIR); |
9341 | TRACE(("expredir expanded to '%s'\n", fn.list->text)); | 9462 | TRACE(("expredir expanded to '%s'\n", fn.list->text)); |
9342 | #if ENABLE_ASH_BASH_COMPAT | 9463 | #if BASH_REDIR_OUTPUT |
9343 | store_expfname: | 9464 | store_expfname: |
9344 | #endif | 9465 | #endif |
9345 | #if 0 | 9466 | #if 0 |
@@ -9361,7 +9482,7 @@ expredir(union node *n) | |||
9361 | expandarg(redir->ndup.vname, &fn, EXP_FULL | EXP_TILDE); | 9482 | expandarg(redir->ndup.vname, &fn, EXP_FULL | EXP_TILDE); |
9362 | if (fn.list == NULL) | 9483 | if (fn.list == NULL) |
9363 | ash_msg_and_raise_error("redir error"); | 9484 | ash_msg_and_raise_error("redir error"); |
9364 | #if ENABLE_ASH_BASH_COMPAT | 9485 | #if BASH_REDIR_OUTPUT |
9365 | //FIXME: we used expandarg with different args! | 9486 | //FIXME: we used expandarg with different args! |
9366 | if (!isdigit_str9(fn.list->text)) { | 9487 | if (!isdigit_str9(fn.list->text)) { |
9367 | /* >&file, not >&fd */ | 9488 | /* >&file, not >&fd */ |
@@ -9401,6 +9522,8 @@ evalpipe(union node *n, int flags) | |||
9401 | pipelen++; | 9522 | pipelen++; |
9402 | flags |= EV_EXIT; | 9523 | flags |= EV_EXIT; |
9403 | INT_OFF; | 9524 | INT_OFF; |
9525 | if (n->npipe.pipe_backgnd == 0) | ||
9526 | get_tty_state(); | ||
9404 | jp = makejob(/*n,*/ pipelen); | 9527 | jp = makejob(/*n,*/ pipelen); |
9405 | prevfd = -1; | 9528 | prevfd = -1; |
9406 | for (lp = n->npipe.cmdlist; lp; lp = lp->next) { | 9529 | for (lp = n->npipe.cmdlist; lp; lp = lp->next) { |
@@ -9764,13 +9887,13 @@ static int ulimitcmd(int, char **) FAST_FUNC; | |||
9764 | #define BUILTIN_SPEC_REG_ASSG "7" | 9887 | #define BUILTIN_SPEC_REG_ASSG "7" |
9765 | 9888 | ||
9766 | /* Stubs for calling non-FAST_FUNC's */ | 9889 | /* Stubs for calling non-FAST_FUNC's */ |
9767 | #if ENABLE_ASH_BUILTIN_ECHO | 9890 | #if ENABLE_ASH_ECHO |
9768 | static int FAST_FUNC echocmd(int argc, char **argv) { return echo_main(argc, argv); } | 9891 | static int FAST_FUNC echocmd(int argc, char **argv) { return echo_main(argc, argv); } |
9769 | #endif | 9892 | #endif |
9770 | #if ENABLE_ASH_BUILTIN_PRINTF | 9893 | #if ENABLE_ASH_PRINTF |
9771 | static int FAST_FUNC printfcmd(int argc, char **argv) { return printf_main(argc, argv); } | 9894 | static int FAST_FUNC printfcmd(int argc, char **argv) { return printf_main(argc, argv); } |
9772 | #endif | 9895 | #endif |
9773 | #if ENABLE_ASH_BUILTIN_TEST | 9896 | #if ENABLE_ASH_TEST || BASH_TEST2 |
9774 | static int FAST_FUNC testcmd(int argc, char **argv) { return test_main(argc, argv); } | 9897 | static int FAST_FUNC testcmd(int argc, char **argv) { return test_main(argc, argv); } |
9775 | #endif | 9898 | #endif |
9776 | 9899 | ||
@@ -9778,11 +9901,11 @@ static int FAST_FUNC testcmd(int argc, char **argv) { return test_main(argc, a | |||
9778 | static const struct builtincmd builtintab[] = { | 9901 | static const struct builtincmd builtintab[] = { |
9779 | { BUILTIN_SPEC_REG "." , dotcmd }, | 9902 | { BUILTIN_SPEC_REG "." , dotcmd }, |
9780 | { BUILTIN_SPEC_REG ":" , truecmd }, | 9903 | { BUILTIN_SPEC_REG ":" , truecmd }, |
9781 | #if ENABLE_ASH_BUILTIN_TEST | 9904 | #if ENABLE_ASH_TEST |
9782 | { BUILTIN_REGULAR "[" , testcmd }, | 9905 | { BUILTIN_REGULAR "[" , testcmd }, |
9783 | # if ENABLE_ASH_BASH_COMPAT | 9906 | #endif |
9907 | #if BASH_TEST2 | ||
9784 | { BUILTIN_REGULAR "[[" , testcmd }, | 9908 | { BUILTIN_REGULAR "[[" , testcmd }, |
9785 | # endif | ||
9786 | #endif | 9909 | #endif |
9787 | #if ENABLE_ASH_ALIAS | 9910 | #if ENABLE_ASH_ALIAS |
9788 | { BUILTIN_REG_ASSG "alias" , aliascmd }, | 9911 | { BUILTIN_REG_ASSG "alias" , aliascmd }, |
@@ -9797,7 +9920,7 @@ static const struct builtincmd builtintab[] = { | |||
9797 | { BUILTIN_REGULAR "command" , commandcmd }, | 9920 | { BUILTIN_REGULAR "command" , commandcmd }, |
9798 | #endif | 9921 | #endif |
9799 | { BUILTIN_SPEC_REG "continue", breakcmd }, | 9922 | { BUILTIN_SPEC_REG "continue", breakcmd }, |
9800 | #if ENABLE_ASH_BUILTIN_ECHO | 9923 | #if ENABLE_ASH_ECHO |
9801 | { BUILTIN_REGULAR "echo" , echocmd }, | 9924 | { BUILTIN_REGULAR "echo" , echocmd }, |
9802 | #endif | 9925 | #endif |
9803 | { BUILTIN_SPEC_REG "eval" , NULL }, /*evalcmd() has a differing prototype*/ | 9926 | { BUILTIN_SPEC_REG "eval" , NULL }, /*evalcmd() has a differing prototype*/ |
@@ -9826,7 +9949,7 @@ static const struct builtincmd builtintab[] = { | |||
9826 | { BUILTIN_NOSPEC "let" , letcmd }, | 9949 | { BUILTIN_NOSPEC "let" , letcmd }, |
9827 | #endif | 9950 | #endif |
9828 | { BUILTIN_ASSIGN "local" , localcmd }, | 9951 | { BUILTIN_ASSIGN "local" , localcmd }, |
9829 | #if ENABLE_ASH_BUILTIN_PRINTF | 9952 | #if ENABLE_ASH_PRINTF |
9830 | { BUILTIN_REGULAR "printf" , printfcmd }, | 9953 | { BUILTIN_REGULAR "printf" , printfcmd }, |
9831 | #endif | 9954 | #endif |
9832 | { BUILTIN_NOSPEC "pwd" , pwdcmd }, | 9955 | { BUILTIN_NOSPEC "pwd" , pwdcmd }, |
@@ -9835,10 +9958,10 @@ static const struct builtincmd builtintab[] = { | |||
9835 | { BUILTIN_SPEC_REG "return" , returncmd }, | 9958 | { BUILTIN_SPEC_REG "return" , returncmd }, |
9836 | { BUILTIN_SPEC_REG "set" , setcmd }, | 9959 | { BUILTIN_SPEC_REG "set" , setcmd }, |
9837 | { BUILTIN_SPEC_REG "shift" , shiftcmd }, | 9960 | { BUILTIN_SPEC_REG "shift" , shiftcmd }, |
9838 | #if ENABLE_ASH_BASH_COMPAT | 9961 | #if BASH_SOURCE |
9839 | { BUILTIN_SPEC_REG "source" , dotcmd }, | 9962 | { BUILTIN_SPEC_REG "source" , dotcmd }, |
9840 | #endif | 9963 | #endif |
9841 | #if ENABLE_ASH_BUILTIN_TEST | 9964 | #if ENABLE_ASH_TEST |
9842 | { BUILTIN_REGULAR "test" , testcmd }, | 9965 | { BUILTIN_REGULAR "test" , testcmd }, |
9843 | #endif | 9966 | #endif |
9844 | { BUILTIN_SPEC_REG "times" , timescmd }, | 9967 | { BUILTIN_SPEC_REG "times" , timescmd }, |
@@ -9857,15 +9980,15 @@ static const struct builtincmd builtintab[] = { | |||
9857 | /* Should match the above table! */ | 9980 | /* Should match the above table! */ |
9858 | #define COMMANDCMD (builtintab + \ | 9981 | #define COMMANDCMD (builtintab + \ |
9859 | /* . : */ 2 + \ | 9982 | /* . : */ 2 + \ |
9860 | /* [ */ 1 * ENABLE_ASH_BUILTIN_TEST + \ | 9983 | /* [ */ 1 * ENABLE_ASH_TEST + \ |
9861 | /* [[ */ 1 * ENABLE_ASH_BUILTIN_TEST * ENABLE_ASH_BASH_COMPAT + \ | 9984 | /* [[ */ 1 * BASH_TEST2 + \ |
9862 | /* alias */ 1 * ENABLE_ASH_ALIAS + \ | 9985 | /* alias */ 1 * ENABLE_ASH_ALIAS + \ |
9863 | /* bg */ 1 * ENABLE_ASH_JOB_CONTROL + \ | 9986 | /* bg */ 1 * ENABLE_ASH_JOB_CONTROL + \ |
9864 | /* break cd cddir */ 3) | 9987 | /* break cd cddir */ 3) |
9865 | #define EVALCMD (COMMANDCMD + \ | 9988 | #define EVALCMD (COMMANDCMD + \ |
9866 | /* command */ 1 * ENABLE_ASH_CMDCMD + \ | 9989 | /* command */ 1 * ENABLE_ASH_CMDCMD + \ |
9867 | /* continue */ 1 + \ | 9990 | /* continue */ 1 + \ |
9868 | /* echo */ 1 * ENABLE_ASH_BUILTIN_ECHO + \ | 9991 | /* echo */ 1 * ENABLE_ASH_ECHO + \ |
9869 | 0) | 9992 | 0) |
9870 | #define EXECCMD (EVALCMD + \ | 9993 | #define EXECCMD (EVALCMD + \ |
9871 | /* eval */ 1) | 9994 | /* eval */ 1) |
@@ -10117,6 +10240,7 @@ evalcommand(union node *cmd, int flags) | |||
10117 | if (!(flags & EV_EXIT) || may_have_traps) { | 10240 | if (!(flags & EV_EXIT) || may_have_traps) { |
10118 | /* No, forking off a child is necessary */ | 10241 | /* No, forking off a child is necessary */ |
10119 | INT_OFF; | 10242 | INT_OFF; |
10243 | get_tty_state(); | ||
10120 | jp = makejob(/*cmd,*/ 1); | 10244 | jp = makejob(/*cmd,*/ 1); |
10121 | if (forkshell(jp, cmd, FORK_FG) != 0) { | 10245 | if (forkshell(jp, cmd, FORK_FG) != 0) { |
10122 | /* parent */ | 10246 | /* parent */ |
@@ -11505,10 +11629,10 @@ simplecmd(void) | |||
11505 | union node *vars, **vpp; | 11629 | union node *vars, **vpp; |
11506 | union node **rpp, *redir; | 11630 | union node **rpp, *redir; |
11507 | int savecheckkwd; | 11631 | int savecheckkwd; |
11508 | #if ENABLE_ASH_BASH_COMPAT | 11632 | #if BASH_TEST2 |
11509 | smallint double_brackets_flag = 0; | 11633 | smallint double_brackets_flag = 0; |
11510 | smallint function_flag = 0; | ||
11511 | #endif | 11634 | #endif |
11635 | IF_BASH_FUNCTION(smallint function_flag = 0;) | ||
11512 | 11636 | ||
11513 | args = NULL; | 11637 | args = NULL; |
11514 | app = &args; | 11638 | app = &args; |
@@ -11523,12 +11647,14 @@ simplecmd(void) | |||
11523 | checkkwd = savecheckkwd; | 11647 | checkkwd = savecheckkwd; |
11524 | t = readtoken(); | 11648 | t = readtoken(); |
11525 | switch (t) { | 11649 | switch (t) { |
11526 | #if ENABLE_ASH_BASH_COMPAT | 11650 | #if BASH_FUNCTION |
11527 | case TFUNCTION: | 11651 | case TFUNCTION: |
11528 | if (peektoken() != TWORD) | 11652 | if (peektoken() != TWORD) |
11529 | raise_error_unexpected_syntax(TWORD); | 11653 | raise_error_unexpected_syntax(TWORD); |
11530 | function_flag = 1; | 11654 | function_flag = 1; |
11531 | break; | 11655 | break; |
11656 | #endif | ||
11657 | #if BASH_TEST2 | ||
11532 | case TAND: /* "&&" */ | 11658 | case TAND: /* "&&" */ |
11533 | case TOR: /* "||" */ | 11659 | case TOR: /* "||" */ |
11534 | if (!double_brackets_flag) { | 11660 | if (!double_brackets_flag) { |
@@ -11542,7 +11668,7 @@ simplecmd(void) | |||
11542 | n->type = NARG; | 11668 | n->type = NARG; |
11543 | /*n->narg.next = NULL; - stzalloc did it */ | 11669 | /*n->narg.next = NULL; - stzalloc did it */ |
11544 | n->narg.text = wordtext; | 11670 | n->narg.text = wordtext; |
11545 | #if ENABLE_ASH_BASH_COMPAT | 11671 | #if BASH_TEST2 |
11546 | if (strcmp("[[", wordtext) == 0) | 11672 | if (strcmp("[[", wordtext) == 0) |
11547 | double_brackets_flag = 1; | 11673 | double_brackets_flag = 1; |
11548 | else if (strcmp("]]", wordtext) == 0) | 11674 | else if (strcmp("]]", wordtext) == 0) |
@@ -11557,7 +11683,7 @@ simplecmd(void) | |||
11557 | app = &n->narg.next; | 11683 | app = &n->narg.next; |
11558 | savecheckkwd = 0; | 11684 | savecheckkwd = 0; |
11559 | } | 11685 | } |
11560 | #if ENABLE_ASH_BASH_COMPAT | 11686 | #if BASH_FUNCTION |
11561 | if (function_flag) { | 11687 | if (function_flag) { |
11562 | checkkwd = CHKNL | CHKKWD; | 11688 | checkkwd = CHKNL | CHKKWD; |
11563 | switch (peektoken()) { | 11689 | switch (peektoken()) { |
@@ -11587,7 +11713,7 @@ simplecmd(void) | |||
11587 | parsefname(); /* read name of redirection file */ | 11713 | parsefname(); /* read name of redirection file */ |
11588 | break; | 11714 | break; |
11589 | case TLP: | 11715 | case TLP: |
11590 | IF_ASH_BASH_COMPAT(do_func:) | 11716 | IF_BASH_FUNCTION(do_func:) |
11591 | if (args && app == &args->narg.next | 11717 | if (args && app == &args->narg.next |
11592 | && !vars && !redir | 11718 | && !vars && !redir |
11593 | ) { | 11719 | ) { |
@@ -11595,7 +11721,7 @@ simplecmd(void) | |||
11595 | const char *name; | 11721 | const char *name; |
11596 | 11722 | ||
11597 | /* We have a function */ | 11723 | /* We have a function */ |
11598 | if (IF_ASH_BASH_COMPAT(!function_flag &&) readtoken() != TRP) | 11724 | if (IF_BASH_FUNCTION(!function_flag &&) readtoken() != TRP) |
11599 | raise_error_unexpected_syntax(TRP); | 11725 | raise_error_unexpected_syntax(TRP); |
11600 | name = n->narg.text; | 11726 | name = n->narg.text; |
11601 | if (!goodname(name) | 11727 | if (!goodname(name) |
@@ -11608,7 +11734,7 @@ simplecmd(void) | |||
11608 | n->narg.next = parse_command(); | 11734 | n->narg.next = parse_command(); |
11609 | return n; | 11735 | return n; |
11610 | } | 11736 | } |
11611 | IF_ASH_BASH_COMPAT(function_flag = 0;) | 11737 | IF_BASH_FUNCTION(function_flag = 0;) |
11612 | /* fall through */ | 11738 | /* fall through */ |
11613 | default: | 11739 | default: |
11614 | tokpushback = 1; | 11740 | tokpushback = 1; |
@@ -11789,7 +11915,7 @@ parse_command(void) | |||
11789 | n1 = list(0); | 11915 | n1 = list(0); |
11790 | t = TEND; | 11916 | t = TEND; |
11791 | break; | 11917 | break; |
11792 | IF_ASH_BASH_COMPAT(case TFUNCTION:) | 11918 | IF_BASH_FUNCTION(case TFUNCTION:) |
11793 | case TWORD: | 11919 | case TWORD: |
11794 | case TREDIR: | 11920 | case TREDIR: |
11795 | tokpushback = 1; | 11921 | tokpushback = 1; |
@@ -11822,7 +11948,7 @@ parse_command(void) | |||
11822 | return n1; | 11948 | return n1; |
11823 | } | 11949 | } |
11824 | 11950 | ||
11825 | #if ENABLE_ASH_BASH_COMPAT | 11951 | #if BASH_DOLLAR_SQUOTE |
11826 | static int | 11952 | static int |
11827 | decode_dollar_squote(void) | 11953 | decode_dollar_squote(void) |
11828 | { | 11954 | { |
@@ -11907,7 +12033,7 @@ readtoken1(int c, int syntax, char *eofmark, int striptabs) | |||
11907 | IF_FEATURE_SH_MATH(int parenlevel;) /* levels of parens in arithmetic */ | 12033 | IF_FEATURE_SH_MATH(int parenlevel;) /* levels of parens in arithmetic */ |
11908 | int dqvarnest; /* levels of variables expansion within double quotes */ | 12034 | int dqvarnest; /* levels of variables expansion within double quotes */ |
11909 | 12035 | ||
11910 | IF_ASH_BASH_COMPAT(smallint bash_dollar_squote = 0;) | 12036 | IF_BASH_DOLLAR_SQUOTE(smallint bash_dollar_squote = 0;) |
11911 | 12037 | ||
11912 | startlinno = g_parsefile->linno; | 12038 | startlinno = g_parsefile->linno; |
11913 | bqlist = NULL; | 12039 | bqlist = NULL; |
@@ -11942,7 +12068,7 @@ readtoken1(int c, int syntax, char *eofmark, int striptabs) | |||
11942 | USTPUTC(c, out); | 12068 | USTPUTC(c, out); |
11943 | break; | 12069 | break; |
11944 | case CCTL: | 12070 | case CCTL: |
11945 | #if ENABLE_ASH_BASH_COMPAT | 12071 | #if BASH_DOLLAR_SQUOTE |
11946 | if (c == '\\' && bash_dollar_squote) { | 12072 | if (c == '\\' && bash_dollar_squote) { |
11947 | c = decode_dollar_squote(); | 12073 | c = decode_dollar_squote(); |
11948 | if (c == '\0') { | 12074 | if (c == '\0') { |
@@ -12003,7 +12129,7 @@ readtoken1(int c, int syntax, char *eofmark, int striptabs) | |||
12003 | dblquote = 1; | 12129 | dblquote = 1; |
12004 | goto quotemark; | 12130 | goto quotemark; |
12005 | case CENDQUOTE: | 12131 | case CENDQUOTE: |
12006 | IF_ASH_BASH_COMPAT(bash_dollar_squote = 0;) | 12132 | IF_BASH_DOLLAR_SQUOTE(bash_dollar_squote = 0;) |
12007 | if (eofmark != NULL && varnest == 0) { | 12133 | if (eofmark != NULL && varnest == 0) { |
12008 | USTPUTC(c, out); | 12134 | USTPUTC(c, out); |
12009 | } else { | 12135 | } else { |
@@ -12062,7 +12188,7 @@ readtoken1(int c, int syntax, char *eofmark, int striptabs) | |||
12062 | break; | 12188 | break; |
12063 | default: | 12189 | default: |
12064 | if (varnest == 0) { | 12190 | if (varnest == 0) { |
12065 | #if ENABLE_ASH_BASH_COMPAT | 12191 | #if BASH_REDIR_OUTPUT |
12066 | if (c == '&') { | 12192 | if (c == '&') { |
12067 | //Can't call pgetc_eatbnl() here, this requires three-deep pungetc() | 12193 | //Can't call pgetc_eatbnl() here, this requires three-deep pungetc() |
12068 | if (pgetc() == '>') | 12194 | if (pgetc() == '>') |
@@ -12094,7 +12220,7 @@ readtoken1(int c, int syntax, char *eofmark, int striptabs) | |||
12094 | len = out - (char *)stackblock(); | 12220 | len = out - (char *)stackblock(); |
12095 | out = stackblock(); | 12221 | out = stackblock(); |
12096 | if (eofmark == NULL) { | 12222 | if (eofmark == NULL) { |
12097 | if ((c == '>' || c == '<' IF_ASH_BASH_COMPAT( || c == 0x100 + '>')) | 12223 | if ((c == '>' || c == '<' IF_BASH_REDIR_OUTPUT( || c == 0x100 + '>')) |
12098 | && quotef == 0 | 12224 | && quotef == 0 |
12099 | ) { | 12225 | ) { |
12100 | if (isdigit_str9(out)) { | 12226 | if (isdigit_str9(out)) { |
@@ -12182,7 +12308,7 @@ parseredir: { | |||
12182 | pungetc(); | 12308 | pungetc(); |
12183 | } | 12309 | } |
12184 | } | 12310 | } |
12185 | #if ENABLE_ASH_BASH_COMPAT | 12311 | #if BASH_REDIR_OUTPUT |
12186 | else if (c == 0x100 + '>') { /* this flags &> redirection */ | 12312 | else if (c == 0x100 + '>') { /* this flags &> redirection */ |
12187 | np->nfile.fd = 1; | 12313 | np->nfile.fd = 1; |
12188 | pgetc(); /* this is '>', no need to check */ | 12314 | pgetc(); /* this is '>', no need to check */ |
@@ -12248,7 +12374,7 @@ parsesub: { | |||
12248 | if (c > 255 /* PEOA or PEOF */ | 12374 | if (c > 255 /* PEOA or PEOF */ |
12249 | || (c != '(' && c != '{' && !is_name(c) && !is_special(c)) | 12375 | || (c != '(' && c != '{' && !is_name(c) && !is_special(c)) |
12250 | ) { | 12376 | ) { |
12251 | #if ENABLE_ASH_BASH_COMPAT | 12377 | #if BASH_DOLLAR_SQUOTE |
12252 | if (syntax != DQSYNTAX && c == '\'') | 12378 | if (syntax != DQSYNTAX && c == '\'') |
12253 | bash_dollar_squote = 1; | 12379 | bash_dollar_squote = 1; |
12254 | else | 12380 | else |
@@ -12324,7 +12450,7 @@ parsesub: { | |||
12324 | switch (c) { | 12450 | switch (c) { |
12325 | case ':': | 12451 | case ':': |
12326 | c = pgetc_eatbnl(); | 12452 | c = pgetc_eatbnl(); |
12327 | #if ENABLE_ASH_BASH_COMPAT | 12453 | #if BASH_SUBSTR |
12328 | /* This check is only needed to not misinterpret | 12454 | /* This check is only needed to not misinterpret |
12329 | * ${VAR:-WORD}, ${VAR:+WORD}, ${VAR:=WORD}, ${VAR:?WORD} | 12455 | * ${VAR:-WORD}, ${VAR:+WORD}, ${VAR:=WORD}, ${VAR:?WORD} |
12330 | * constructs. | 12456 | * constructs. |
@@ -12354,7 +12480,7 @@ parsesub: { | |||
12354 | subtype++; | 12480 | subtype++; |
12355 | break; | 12481 | break; |
12356 | } | 12482 | } |
12357 | #if ENABLE_ASH_BASH_COMPAT | 12483 | #if BASH_PATTERN_SUBST |
12358 | case '/': | 12484 | case '/': |
12359 | /* ${v/[/]pattern/repl} */ | 12485 | /* ${v/[/]pattern/repl} */ |
12360 | //TODO: encode pattern and repl separately. | 12486 | //TODO: encode pattern and repl separately. |
@@ -12609,7 +12735,7 @@ xxreadtoken(void) | |||
12609 | p += xxreadtoken_doubles + 1; | 12735 | p += xxreadtoken_doubles + 1; |
12610 | } else { | 12736 | } else { |
12611 | pungetc(); | 12737 | pungetc(); |
12612 | #if ENABLE_ASH_BASH_COMPAT | 12738 | #if BASH_REDIR_OUTPUT |
12613 | if (c == '&' && cc == '>') /* &> */ | 12739 | if (c == '&' && cc == '>') /* &> */ |
12614 | break; /* return readtoken1(...) */ | 12740 | break; /* return readtoken1(...) */ |
12615 | #endif | 12741 | #endif |
@@ -12999,16 +13125,7 @@ find_dot_file(char *name) | |||
12999 | if (strchr(name, '/') || (ENABLE_PLATFORM_MINGW32 && strchr(name, '\\'))) | 13125 | if (strchr(name, '/') || (ENABLE_PLATFORM_MINGW32 && strchr(name, '\\'))) |
13000 | return name; | 13126 | return name; |
13001 | 13127 | ||
13002 | /* IIRC standards do not say whether . is to be searched. | ||
13003 | * And it is even smaller this way, making it unconditional for now: | ||
13004 | */ | ||
13005 | if (1) { /* ENABLE_ASH_BASH_COMPAT */ | ||
13006 | fullname = name; | ||
13007 | goto try_cur_dir; | ||
13008 | } | ||
13009 | |||
13010 | while ((fullname = path_advance(&path, name)) != NULL) { | 13128 | while ((fullname = path_advance(&path, name)) != NULL) { |
13011 | try_cur_dir: | ||
13012 | if ((stat(fullname, &statb) == 0) && S_ISREG(statb.st_mode)) { | 13129 | if ((stat(fullname, &statb) == 0) && S_ISREG(statb.st_mode)) { |
13013 | /* | 13130 | /* |
13014 | * Don't bother freeing here, since it will | 13131 | * Don't bother freeing here, since it will |
@@ -13032,6 +13149,7 @@ dotcmd(int argc_ UNUSED_PARAM, char **argv_ UNUSED_PARAM) | |||
13032 | int status = 0; | 13149 | int status = 0; |
13033 | char *fullname; | 13150 | char *fullname; |
13034 | char **argv; | 13151 | char **argv; |
13152 | char *args_need_save; | ||
13035 | struct strlist *sp; | 13153 | struct strlist *sp; |
13036 | volatile struct shparam saveparam; | 13154 | volatile struct shparam saveparam; |
13037 | 13155 | ||
@@ -13051,7 +13169,8 @@ dotcmd(int argc_ UNUSED_PARAM, char **argv_ UNUSED_PARAM) | |||
13051 | */ | 13169 | */ |
13052 | fullname = find_dot_file(argv[0]); | 13170 | fullname = find_dot_file(argv[0]); |
13053 | argv++; | 13171 | argv++; |
13054 | if (argv[0]) { /* . FILE ARGS, ARGS exist */ | 13172 | args_need_save = argv[0]; |
13173 | if (args_need_save) { /* ". FILE ARGS", and ARGS are not empty */ | ||
13055 | int argc; | 13174 | int argc; |
13056 | saveparam = shellparam; | 13175 | saveparam = shellparam; |
13057 | shellparam.malloced = 0; | 13176 | shellparam.malloced = 0; |
@@ -13070,7 +13189,7 @@ dotcmd(int argc_ UNUSED_PARAM, char **argv_ UNUSED_PARAM) | |||
13070 | status = cmdloop(0); | 13189 | status = cmdloop(0); |
13071 | popfile(); | 13190 | popfile(); |
13072 | 13191 | ||
13073 | if (argv[0]) { | 13192 | if (args_need_save) { |
13074 | freeparam(&shellparam); | 13193 | freeparam(&shellparam); |
13075 | shellparam = saveparam; | 13194 | shellparam = saveparam; |
13076 | }; | 13195 | }; |
@@ -13902,9 +14021,11 @@ init(void) | |||
13902 | setvareq((char*)defoptindvar, VTEXTFIXED); | 14021 | setvareq((char*)defoptindvar, VTEXTFIXED); |
13903 | 14022 | ||
13904 | setvar0("PPID", utoa(getppid())); | 14023 | setvar0("PPID", utoa(getppid())); |
13905 | #if ENABLE_ASH_BASH_COMPAT | 14024 | #if BASH_SHLVL_VAR |
13906 | p = lookupvar("SHLVL"); | 14025 | p = lookupvar("SHLVL"); |
13907 | setvar("SHLVL", utoa((p ? atoi(p) : 0) + 1), VEXPORT); | 14026 | setvar("SHLVL", utoa((p ? atoi(p) : 0) + 1), VEXPORT); |
14027 | #endif | ||
14028 | #if BASH_HOSTNAME_VAR | ||
13908 | if (!lookupvar("HOSTNAME")) { | 14029 | if (!lookupvar("HOSTNAME")) { |
13909 | struct utsname uts; | 14030 | struct utsname uts; |
13910 | uname(&uts); | 14031 | uname(&uts); |
@@ -13967,7 +14088,7 @@ procargs(char **argv) | |||
13967 | #if DEBUG == 2 | 14088 | #if DEBUG == 2 |
13968 | debug = 1; | 14089 | debug = 1; |
13969 | #endif | 14090 | #endif |
13970 | /* POSIX 1003.2: first arg after -c cmd is $0, remainder $1... */ | 14091 | /* POSIX 1003.2: first arg after "-c CMD" is $0, remainder $1... */ |
13971 | if (xminusc) { | 14092 | if (xminusc) { |
13972 | minusc = *xargv++; | 14093 | minusc = *xargv++; |
13973 | if (*xargv) | 14094 | if (*xargv) |
@@ -14174,9 +14295,11 @@ int ash_main(int argc UNUSED_PARAM, char **argv) | |||
14174 | if (!hp) { | 14295 | if (!hp) { |
14175 | hp = lookupvar("HOME"); | 14296 | hp = lookupvar("HOME"); |
14176 | if (hp) { | 14297 | if (hp) { |
14298 | INT_OFF; | ||
14177 | hp = concat_path_file(hp, ".ash_history"); | 14299 | hp = concat_path_file(hp, ".ash_history"); |
14178 | setvar0("HISTFILE", hp); | 14300 | setvar0("HISTFILE", hp); |
14179 | free((char*)hp); | 14301 | free((char*)hp); |
14302 | INT_ON; | ||
14180 | hp = lookupvar("HISTFILE"); | 14303 | hp = lookupvar("HISTFILE"); |
14181 | } | 14304 | } |
14182 | } | 14305 | } |
diff --git a/shell/ash_test/ash-misc/source_argv_and_shift.right b/shell/ash_test/ash-misc/source_argv_and_shift.right new file mode 100644 index 000000000..b15cc96e7 --- /dev/null +++ b/shell/ash_test/ash-misc/source_argv_and_shift.right | |||
@@ -0,0 +1,4 @@ | |||
1 | sourced_arg1:1 | ||
2 | arg1: | ||
3 | sourced_arg1:a | ||
4 | arg1:1 | ||
diff --git a/shell/ash_test/ash-misc/source_argv_and_shift.tests b/shell/ash_test/ash-misc/source_argv_and_shift.tests new file mode 100755 index 000000000..66353f3d7 --- /dev/null +++ b/shell/ash_test/ash-misc/source_argv_and_shift.tests | |||
@@ -0,0 +1,12 @@ | |||
1 | echo 'echo sourced_arg1:$1' >sourced1 | ||
2 | echo 'shift' >>sourced1 | ||
3 | |||
4 | set -- 1 | ||
5 | . ./sourced1 | ||
6 | echo arg1:$1 | ||
7 | |||
8 | set -- 1 | ||
9 | . ./sourced1 a | ||
10 | echo arg1:$1 | ||
11 | |||
12 | rm sourced1 | ||
diff --git a/shell/hush.c b/shell/hush.c index a56d3b280..4123cc19e 100644 --- a/shell/hush.c +++ b/shell/hush.c | |||
@@ -44,7 +44,6 @@ | |||
44 | * special variables (done: PWD, PPID, RANDOM) | 44 | * special variables (done: PWD, PPID, RANDOM) |
45 | * tilde expansion | 45 | * tilde expansion |
46 | * aliases | 46 | * aliases |
47 | * kill %jobspec | ||
48 | * follow IFS rules more precisely, including update semantics | 47 | * follow IFS rules more precisely, including update semantics |
49 | * builtins mandated by standards we don't support: | 48 | * builtins mandated by standards we don't support: |
50 | * [un]alias, command, fc, getopts, newgrp, readonly, times | 49 | * [un]alias, command, fc, getopts, newgrp, readonly, times |
@@ -100,8 +99,6 @@ | |||
100 | //config: bool "bash-compatible extensions" | 99 | //config: bool "bash-compatible extensions" |
101 | //config: default y | 100 | //config: default y |
102 | //config: depends on HUSH || SH_IS_HUSH || BASH_IS_HUSH | 101 | //config: depends on HUSH || SH_IS_HUSH || BASH_IS_HUSH |
103 | //config: help | ||
104 | //config: Enable bash-compatible extensions. | ||
105 | //config: | 102 | //config: |
106 | //config:config HUSH_BRACE_EXPANSION | 103 | //config:config HUSH_BRACE_EXPANSION |
107 | //config: bool "Brace expansion" | 104 | //config: bool "Brace expansion" |
@@ -110,13 +107,6 @@ | |||
110 | //config: help | 107 | //config: help |
111 | //config: Enable {abc,def} extension. | 108 | //config: Enable {abc,def} extension. |
112 | //config: | 109 | //config: |
113 | //config:config HUSH_HELP | ||
114 | //config: bool "help builtin" | ||
115 | //config: default y | ||
116 | //config: depends on HUSH || SH_IS_HUSH || BASH_IS_HUSH | ||
117 | //config: help | ||
118 | //config: Enable help builtin in hush. Code size + ~1 kbyte. | ||
119 | //config: | ||
120 | //config:config HUSH_INTERACTIVE | 110 | //config:config HUSH_INTERACTIVE |
121 | //config: bool "Interactive mode" | 111 | //config: bool "Interactive mode" |
122 | //config: default y | 112 | //config: default y |
@@ -131,8 +121,6 @@ | |||
131 | //config: bool "Save command history to .hush_history" | 121 | //config: bool "Save command history to .hush_history" |
132 | //config: default y | 122 | //config: default y |
133 | //config: depends on HUSH_INTERACTIVE && FEATURE_EDITING_SAVEHISTORY | 123 | //config: depends on HUSH_INTERACTIVE && FEATURE_EDITING_SAVEHISTORY |
134 | //config: help | ||
135 | //config: Enable history saving in hush. | ||
136 | //config: | 124 | //config: |
137 | //config:config HUSH_JOB | 125 | //config:config HUSH_JOB |
138 | //config: bool "Job control" | 126 | //config: bool "Job control" |
@@ -146,42 +134,38 @@ | |||
146 | //config: but no separate process group is formed. | 134 | //config: but no separate process group is formed. |
147 | //config: | 135 | //config: |
148 | //config:config HUSH_TICK | 136 | //config:config HUSH_TICK |
149 | //config: bool "Process substitution" | 137 | //config: bool "Support process substitution" |
150 | //config: default y | 138 | //config: default y |
151 | //config: depends on HUSH || SH_IS_HUSH || BASH_IS_HUSH | 139 | //config: depends on HUSH || SH_IS_HUSH || BASH_IS_HUSH |
152 | //config: help | 140 | //config: help |
153 | //config: Enable process substitution `command` and $(command) in hush. | 141 | //config: Enable `command` and $(command). |
154 | //config: | 142 | //config: |
155 | //config:config HUSH_IF | 143 | //config:config HUSH_IF |
156 | //config: bool "Support if/then/elif/else/fi" | 144 | //config: bool "Support if/then/elif/else/fi" |
157 | //config: default y | 145 | //config: default y |
158 | //config: depends on HUSH || SH_IS_HUSH || BASH_IS_HUSH | 146 | //config: depends on HUSH || SH_IS_HUSH || BASH_IS_HUSH |
159 | //config: help | ||
160 | //config: Enable if/then/elif/else/fi in hush. | ||
161 | //config: | 147 | //config: |
162 | //config:config HUSH_LOOPS | 148 | //config:config HUSH_LOOPS |
163 | //config: bool "Support for, while and until loops" | 149 | //config: bool "Support for, while and until loops" |
164 | //config: default y | 150 | //config: default y |
165 | //config: depends on HUSH || SH_IS_HUSH || BASH_IS_HUSH | 151 | //config: depends on HUSH || SH_IS_HUSH || BASH_IS_HUSH |
166 | //config: help | ||
167 | //config: Enable for, while and until loops in hush. | ||
168 | //config: | 152 | //config: |
169 | //config:config HUSH_CASE | 153 | //config:config HUSH_CASE |
170 | //config: bool "Support case ... esac statement" | 154 | //config: bool "Support case ... esac statement" |
171 | //config: default y | 155 | //config: default y |
172 | //config: depends on HUSH || SH_IS_HUSH || BASH_IS_HUSH | 156 | //config: depends on HUSH || SH_IS_HUSH || BASH_IS_HUSH |
173 | //config: help | 157 | //config: help |
174 | //config: Enable case ... esac statement in hush. +400 bytes. | 158 | //config: Enable case ... esac statement. +400 bytes. |
175 | //config: | 159 | //config: |
176 | //config:config HUSH_FUNCTIONS | 160 | //config:config HUSH_FUNCTIONS |
177 | //config: bool "Support funcname() { commands; } syntax" | 161 | //config: bool "Support funcname() { commands; } syntax" |
178 | //config: default y | 162 | //config: default y |
179 | //config: depends on HUSH || SH_IS_HUSH || BASH_IS_HUSH | 163 | //config: depends on HUSH || SH_IS_HUSH || BASH_IS_HUSH |
180 | //config: help | 164 | //config: help |
181 | //config: Enable support for shell functions in hush. +800 bytes. | 165 | //config: Enable support for shell functions. +800 bytes. |
182 | //config: | 166 | //config: |
183 | //config:config HUSH_LOCAL | 167 | //config:config HUSH_LOCAL |
184 | //config: bool "Support local builtin" | 168 | //config: bool "local builtin" |
185 | //config: default y | 169 | //config: default y |
186 | //config: depends on HUSH_FUNCTIONS | 170 | //config: depends on HUSH_FUNCTIONS |
187 | //config: help | 171 | //config: help |
@@ -195,20 +179,95 @@ | |||
195 | //config: Enable pseudorandom generator and dynamic variable "$RANDOM". | 179 | //config: Enable pseudorandom generator and dynamic variable "$RANDOM". |
196 | //config: Each read of "$RANDOM" will generate a new pseudorandom value. | 180 | //config: Each read of "$RANDOM" will generate a new pseudorandom value. |
197 | //config: | 181 | //config: |
182 | //config:config HUSH_MODE_X | ||
183 | //config: bool "Support 'hush -x' option and 'set -x' command" | ||
184 | //config: default y | ||
185 | //config: depends on HUSH || SH_IS_HUSH || BASH_IS_HUSH | ||
186 | //config: help | ||
187 | //config: This instructs hush to print commands before execution. | ||
188 | //config: Adds ~300 bytes. | ||
189 | //config: | ||
190 | //config:config HUSH_ECHO | ||
191 | //config: bool "echo builtin" | ||
192 | //config: default y | ||
193 | //config: depends on HUSH || SH_IS_HUSH || BASH_IS_HUSH | ||
194 | //config: | ||
195 | //config:config HUSH_PRINTF | ||
196 | //config: bool "printf builtin" | ||
197 | //config: default y | ||
198 | //config: depends on HUSH || SH_IS_HUSH || BASH_IS_HUSH | ||
199 | //config: | ||
200 | //config:config HUSH_TEST | ||
201 | //config: bool "test builtin" | ||
202 | //config: default y | ||
203 | //config: depends on HUSH || SH_IS_HUSH || BASH_IS_HUSH | ||
204 | //config: | ||
205 | //config:config HUSH_HELP | ||
206 | //config: bool "help builtin" | ||
207 | //config: default y | ||
208 | //config: depends on HUSH || SH_IS_HUSH || BASH_IS_HUSH | ||
209 | //config: | ||
210 | //config:config HUSH_EXPORT | ||
211 | //config: bool "export builtin" | ||
212 | //config: default y | ||
213 | //config: depends on HUSH || SH_IS_HUSH || BASH_IS_HUSH | ||
214 | //config: | ||
198 | //config:config HUSH_EXPORT_N | 215 | //config:config HUSH_EXPORT_N |
199 | //config: bool "Support 'export -n' option" | 216 | //config: bool "Support 'export -n' option" |
200 | //config: default y | 217 | //config: default y |
201 | //config: depends on HUSH || SH_IS_HUSH || BASH_IS_HUSH | 218 | //config: depends on HUSH_EXPORT |
202 | //config: help | 219 | //config: help |
203 | //config: export -n unexports variables. It is a bash extension. | 220 | //config: export -n unexports variables. It is a bash extension. |
204 | //config: | 221 | //config: |
205 | //config:config HUSH_MODE_X | 222 | //config:config HUSH_KILL |
206 | //config: bool "Support 'hush -x' option and 'set -x' command" | 223 | //config: bool "kill builtin (supports kill %jobspec)" |
224 | //config: default y | ||
225 | //config: depends on HUSH || SH_IS_HUSH || BASH_IS_HUSH | ||
226 | //config: | ||
227 | //config:config HUSH_WAIT | ||
228 | //config: bool "wait builtin" | ||
229 | //config: default y | ||
230 | //config: depends on HUSH || SH_IS_HUSH || BASH_IS_HUSH | ||
231 | //config: | ||
232 | //config:config HUSH_TRAP | ||
233 | //config: bool "trap builtin" | ||
234 | //config: default y | ||
235 | //config: depends on HUSH || SH_IS_HUSH || BASH_IS_HUSH | ||
236 | //config: | ||
237 | //config:config HUSH_TYPE | ||
238 | //config: bool "type builtin" | ||
239 | //config: default y | ||
240 | //config: depends on HUSH || SH_IS_HUSH || BASH_IS_HUSH | ||
241 | //config: | ||
242 | //config:config HUSH_READ | ||
243 | //config: bool "read builtin" | ||
244 | //config: default y | ||
245 | //config: depends on HUSH || SH_IS_HUSH || BASH_IS_HUSH | ||
246 | //config: | ||
247 | //config:config HUSH_SET | ||
248 | //config: bool "set builtin" | ||
207 | //config: default y | 249 | //config: default y |
208 | //config: depends on HUSH || SH_IS_HUSH || BASH_IS_HUSH | 250 | //config: depends on HUSH || SH_IS_HUSH || BASH_IS_HUSH |
209 | //config: help | 251 | //config: |
210 | //config: This instructs hush to print commands before execution. | 252 | //config:config HUSH_UNSET |
211 | //config: Adds ~300 bytes. | 253 | //config: bool "unset builtin" |
254 | //config: default y | ||
255 | //config: depends on HUSH || SH_IS_HUSH || BASH_IS_HUSH | ||
256 | //config: | ||
257 | //config:config HUSH_ULIMIT | ||
258 | //config: bool "ulimit builtin" | ||
259 | //config: default y | ||
260 | //config: depends on HUSH || SH_IS_HUSH || BASH_IS_HUSH | ||
261 | //config: | ||
262 | //config:config HUSH_UMASK | ||
263 | //config: bool "umask builtin" | ||
264 | //config: default y | ||
265 | //config: depends on HUSH || SH_IS_HUSH || BASH_IS_HUSH | ||
266 | //config: | ||
267 | //config:config HUSH_MEMLEAK | ||
268 | //config: bool "memleak builtin (debugging)" | ||
269 | //config: default n | ||
270 | //config: depends on HUSH || SH_IS_HUSH || BASH_IS_HUSH | ||
212 | //config: | 271 | //config: |
213 | //config:config MSH | 272 | //config:config MSH |
214 | //config: bool "msh (deprecated: aliased to hush)" | 273 | //config: bool "msh (deprecated: aliased to hush)" |
@@ -218,8 +277,9 @@ | |||
218 | //config: msh is deprecated and will be removed, please migrate to hush. | 277 | //config: msh is deprecated and will be removed, please migrate to hush. |
219 | 278 | ||
220 | //applet:IF_HUSH(APPLET(hush, BB_DIR_BIN, BB_SUID_DROP)) | 279 | //applet:IF_HUSH(APPLET(hush, BB_DIR_BIN, BB_SUID_DROP)) |
221 | //applet:IF_MSH(APPLET_ODDNAME(msh, hush, BB_DIR_BIN, BB_SUID_DROP, hush)) | 280 | // APPLET_ODDNAME:name main location suid_type help |
222 | //applet:IF_SH_IS_HUSH(APPLET_ODDNAME(sh, hush, BB_DIR_BIN, BB_SUID_DROP, hush)) | 281 | //applet:IF_MSH( APPLET_ODDNAME(msh, hush, BB_DIR_BIN, BB_SUID_DROP, hush)) |
282 | //applet:IF_SH_IS_HUSH( APPLET_ODDNAME(sh, hush, BB_DIR_BIN, BB_SUID_DROP, hush)) | ||
223 | //applet:IF_BASH_IS_HUSH(APPLET_ODDNAME(bash, hush, BB_DIR_BIN, BB_SUID_DROP, hush)) | 283 | //applet:IF_BASH_IS_HUSH(APPLET_ODDNAME(bash, hush, BB_DIR_BIN, BB_SUID_DROP, hush)) |
224 | 284 | ||
225 | //kbuild:lib-$(CONFIG_HUSH) += hush.o match.o shell_common.o | 285 | //kbuild:lib-$(CONFIG_HUSH) += hush.o match.o shell_common.o |
@@ -267,6 +327,15 @@ | |||
267 | #endif | 327 | #endif |
268 | 328 | ||
269 | 329 | ||
330 | /* So far, all bash compat is controlled by one config option */ | ||
331 | /* Separate defines document which part of code implements what */ | ||
332 | #define BASH_PATTERN_SUBST ENABLE_HUSH_BASH_COMPAT | ||
333 | #define BASH_SUBSTR ENABLE_HUSH_BASH_COMPAT | ||
334 | #define BASH_TEST2 ENABLE_HUSH_BASH_COMPAT | ||
335 | #define BASH_SOURCE ENABLE_HUSH_BASH_COMPAT | ||
336 | #define BASH_HOSTNAME_VAR ENABLE_HUSH_BASH_COMPAT | ||
337 | |||
338 | |||
270 | /* Build knobs */ | 339 | /* Build knobs */ |
271 | #define LEAK_HUNTING 0 | 340 | #define LEAK_HUNTING 0 |
272 | #define BUILD_AS_NOMMU 0 | 341 | #define BUILD_AS_NOMMU 0 |
@@ -347,12 +416,12 @@ | |||
347 | 416 | ||
348 | #define ERR_PTR ((void*)(long)1) | 417 | #define ERR_PTR ((void*)(long)1) |
349 | 418 | ||
350 | #define JOB_STATUS_FORMAT "[%d] %-22s %.40s\n" | 419 | #define JOB_STATUS_FORMAT "[%u] %-22s %.40s\n" |
351 | 420 | ||
352 | #define _SPECIAL_VARS_STR "_*@$!?#" | 421 | #define _SPECIAL_VARS_STR "_*@$!?#" |
353 | #define SPECIAL_VARS_STR ("_*@$!?#" + 1) | 422 | #define SPECIAL_VARS_STR ("_*@$!?#" + 1) |
354 | #define NUMERIC_SPECVARS_STR ("_*@$!?#" + 3) | 423 | #define NUMERIC_SPECVARS_STR ("_*@$!?#" + 3) |
355 | #if ENABLE_HUSH_BASH_COMPAT | 424 | #if BASH_PATTERN_SUBST |
356 | /* Support / and // replace ops */ | 425 | /* Support / and // replace ops */ |
357 | /* Note that // is stored as \ in "encoded" string representation */ | 426 | /* Note that // is stored as \ in "encoded" string representation */ |
358 | # define VAR_ENCODED_SUBST_OPS "\\/%#:-=+?" | 427 | # define VAR_ENCODED_SUBST_OPS "\\/%#:-=+?" |
@@ -513,7 +582,7 @@ struct command { | |||
513 | smallint cmd_type; /* CMD_xxx */ | 582 | smallint cmd_type; /* CMD_xxx */ |
514 | #define CMD_NORMAL 0 | 583 | #define CMD_NORMAL 0 |
515 | #define CMD_SUBSHELL 1 | 584 | #define CMD_SUBSHELL 1 |
516 | #if ENABLE_HUSH_BASH_COMPAT | 585 | #if BASH_TEST2 |
517 | /* used for "[[ EXPR ]]" */ | 586 | /* used for "[[ EXPR ]]" */ |
518 | # define CMD_SINGLEWORD_NOGLOB 2 | 587 | # define CMD_SINGLEWORD_NOGLOB 2 |
519 | #endif | 588 | #endif |
@@ -563,7 +632,7 @@ struct pipe { | |||
563 | int alive_cmds; /* number of commands running (not exited) */ | 632 | int alive_cmds; /* number of commands running (not exited) */ |
564 | int stopped_cmds; /* number of commands alive, but stopped */ | 633 | int stopped_cmds; /* number of commands alive, but stopped */ |
565 | #if ENABLE_HUSH_JOB | 634 | #if ENABLE_HUSH_JOB |
566 | int jobid; /* job number */ | 635 | unsigned jobid; /* job number */ |
567 | pid_t pgrp; /* process group ID for the job */ | 636 | pid_t pgrp; /* process group ID for the job */ |
568 | char *cmdtext; /* name of job */ | 637 | char *cmdtext; /* name of job */ |
569 | #endif | 638 | #endif |
@@ -740,7 +809,7 @@ struct globals { | |||
740 | #endif | 809 | #endif |
741 | #if ENABLE_HUSH_JOB | 810 | #if ENABLE_HUSH_JOB |
742 | int run_list_level; | 811 | int run_list_level; |
743 | int last_jobid; | 812 | unsigned last_jobid; |
744 | pid_t saved_tty_pgrp; | 813 | pid_t saved_tty_pgrp; |
745 | struct pipe *job_list; | 814 | struct pipe *job_list; |
746 | # define G_saved_tty_pgrp (G.saved_tty_pgrp) | 815 | # define G_saved_tty_pgrp (G.saved_tty_pgrp) |
@@ -770,8 +839,13 @@ struct globals { | |||
770 | smallint exiting; /* used to prevent EXIT trap recursion */ | 839 | smallint exiting; /* used to prevent EXIT trap recursion */ |
771 | /* These four support $?, $#, and $1 */ | 840 | /* These four support $?, $#, and $1 */ |
772 | smalluint last_exitcode; | 841 | smalluint last_exitcode; |
842 | #if ENABLE_HUSH_SET | ||
773 | /* are global_argv and global_argv[1..n] malloced? (note: not [0]) */ | 843 | /* are global_argv and global_argv[1..n] malloced? (note: not [0]) */ |
774 | smalluint global_args_malloced; | 844 | smalluint global_args_malloced; |
845 | # define G_global_args_malloced (G.global_args_malloced) | ||
846 | #else | ||
847 | # define G_global_args_malloced 0 | ||
848 | #endif | ||
775 | /* how many non-NULL argv's we have. NB: $# + 1 */ | 849 | /* how many non-NULL argv's we have. NB: $# + 1 */ |
776 | int global_argc; | 850 | int global_argc; |
777 | char **global_argv; | 851 | char **global_argv; |
@@ -810,14 +884,21 @@ struct globals { | |||
810 | unsigned special_sig_mask; | 884 | unsigned special_sig_mask; |
811 | #if ENABLE_HUSH_JOB | 885 | #if ENABLE_HUSH_JOB |
812 | unsigned fatal_sig_mask; | 886 | unsigned fatal_sig_mask; |
813 | # define G_fatal_sig_mask G.fatal_sig_mask | 887 | # define G_fatal_sig_mask (G.fatal_sig_mask) |
814 | #else | 888 | #else |
815 | # define G_fatal_sig_mask 0 | 889 | # define G_fatal_sig_mask 0 |
816 | #endif | 890 | #endif |
891 | #if ENABLE_HUSH_TRAP | ||
817 | char **traps; /* char *traps[NSIG] */ | 892 | char **traps; /* char *traps[NSIG] */ |
893 | # define G_traps G.traps | ||
894 | #else | ||
895 | # define G_traps ((char**)NULL) | ||
896 | #endif | ||
818 | sigset_t pending_set; | 897 | sigset_t pending_set; |
819 | #if HUSH_DEBUG | 898 | #if ENABLE_HUSH_MEMLEAK |
820 | unsigned long memleak_value; | 899 | unsigned long memleak_value; |
900 | #endif | ||
901 | #if HUSH_DEBUG | ||
821 | int debug_indent; | 902 | int debug_indent; |
822 | #endif | 903 | #endif |
823 | struct sigaction sa; | 904 | struct sigaction sa; |
@@ -839,11 +920,15 @@ struct globals { | |||
839 | 920 | ||
840 | /* Function prototypes for builtins */ | 921 | /* Function prototypes for builtins */ |
841 | static int builtin_cd(char **argv) FAST_FUNC; | 922 | static int builtin_cd(char **argv) FAST_FUNC; |
923 | #if ENABLE_HUSH_ECHO | ||
842 | static int builtin_echo(char **argv) FAST_FUNC; | 924 | static int builtin_echo(char **argv) FAST_FUNC; |
925 | #endif | ||
843 | static int builtin_eval(char **argv) FAST_FUNC; | 926 | static int builtin_eval(char **argv) FAST_FUNC; |
844 | static int builtin_exec(char **argv) FAST_FUNC; | 927 | static int builtin_exec(char **argv) FAST_FUNC; |
845 | static int builtin_exit(char **argv) FAST_FUNC; | 928 | static int builtin_exit(char **argv) FAST_FUNC; |
929 | #if ENABLE_HUSH_EXPORT | ||
846 | static int builtin_export(char **argv) FAST_FUNC; | 930 | static int builtin_export(char **argv) FAST_FUNC; |
931 | #endif | ||
847 | #if ENABLE_HUSH_JOB | 932 | #if ENABLE_HUSH_JOB |
848 | static int builtin_fg_bg(char **argv) FAST_FUNC; | 933 | static int builtin_fg_bg(char **argv) FAST_FUNC; |
849 | static int builtin_jobs(char **argv) FAST_FUNC; | 934 | static int builtin_jobs(char **argv) FAST_FUNC; |
@@ -857,24 +942,43 @@ static int builtin_history(char **argv) FAST_FUNC; | |||
857 | #if ENABLE_HUSH_LOCAL | 942 | #if ENABLE_HUSH_LOCAL |
858 | static int builtin_local(char **argv) FAST_FUNC; | 943 | static int builtin_local(char **argv) FAST_FUNC; |
859 | #endif | 944 | #endif |
860 | #if HUSH_DEBUG | 945 | #if ENABLE_HUSH_MEMLEAK |
861 | static int builtin_memleak(char **argv) FAST_FUNC; | 946 | static int builtin_memleak(char **argv) FAST_FUNC; |
862 | #endif | 947 | #endif |
863 | #if ENABLE_PRINTF | 948 | #if ENABLE_HUSH_PRINTF |
864 | static int builtin_printf(char **argv) FAST_FUNC; | 949 | static int builtin_printf(char **argv) FAST_FUNC; |
865 | #endif | 950 | #endif |
866 | static int builtin_pwd(char **argv) FAST_FUNC; | 951 | static int builtin_pwd(char **argv) FAST_FUNC; |
952 | #if ENABLE_HUSH_READ | ||
867 | static int builtin_read(char **argv) FAST_FUNC; | 953 | static int builtin_read(char **argv) FAST_FUNC; |
954 | #endif | ||
955 | #if ENABLE_HUSH_SET | ||
868 | static int builtin_set(char **argv) FAST_FUNC; | 956 | static int builtin_set(char **argv) FAST_FUNC; |
957 | #endif | ||
869 | static int builtin_shift(char **argv) FAST_FUNC; | 958 | static int builtin_shift(char **argv) FAST_FUNC; |
870 | static int builtin_source(char **argv) FAST_FUNC; | 959 | static int builtin_source(char **argv) FAST_FUNC; |
960 | #if ENABLE_HUSH_TEST || BASH_TEST2 | ||
871 | static int builtin_test(char **argv) FAST_FUNC; | 961 | static int builtin_test(char **argv) FAST_FUNC; |
962 | #endif | ||
963 | #if ENABLE_HUSH_TRAP | ||
872 | static int builtin_trap(char **argv) FAST_FUNC; | 964 | static int builtin_trap(char **argv) FAST_FUNC; |
965 | #endif | ||
966 | #if ENABLE_HUSH_TYPE | ||
873 | static int builtin_type(char **argv) FAST_FUNC; | 967 | static int builtin_type(char **argv) FAST_FUNC; |
968 | #endif | ||
874 | static int builtin_true(char **argv) FAST_FUNC; | 969 | static int builtin_true(char **argv) FAST_FUNC; |
970 | #if ENABLE_HUSH_UMASK | ||
875 | static int builtin_umask(char **argv) FAST_FUNC; | 971 | static int builtin_umask(char **argv) FAST_FUNC; |
972 | #endif | ||
973 | #if ENABLE_HUSH_UNSET | ||
876 | static int builtin_unset(char **argv) FAST_FUNC; | 974 | static int builtin_unset(char **argv) FAST_FUNC; |
975 | #endif | ||
976 | #if ENABLE_HUSH_KILL | ||
977 | static int builtin_kill(char **argv) FAST_FUNC; | ||
978 | #endif | ||
979 | #if ENABLE_HUSH_WAIT | ||
877 | static int builtin_wait(char **argv) FAST_FUNC; | 980 | static int builtin_wait(char **argv) FAST_FUNC; |
981 | #endif | ||
878 | #if ENABLE_HUSH_LOOPS | 982 | #if ENABLE_HUSH_LOOPS |
879 | static int builtin_break(char **argv) FAST_FUNC; | 983 | static int builtin_break(char **argv) FAST_FUNC; |
880 | static int builtin_continue(char **argv) FAST_FUNC; | 984 | static int builtin_continue(char **argv) FAST_FUNC; |
@@ -901,13 +1005,13 @@ struct built_in_command { | |||
901 | }; | 1005 | }; |
902 | 1006 | ||
903 | static const struct built_in_command bltins1[] = { | 1007 | static const struct built_in_command bltins1[] = { |
904 | BLTIN("." , builtin_source , "Run commands in a file"), | 1008 | BLTIN("." , builtin_source , "Run commands in file"), |
905 | BLTIN(":" , builtin_true , NULL), | 1009 | BLTIN(":" , builtin_true , NULL), |
906 | #if ENABLE_HUSH_JOB | 1010 | #if ENABLE_HUSH_JOB |
907 | BLTIN("bg" , builtin_fg_bg , "Resume a job in the background"), | 1011 | BLTIN("bg" , builtin_fg_bg , "Resume job in background"), |
908 | #endif | 1012 | #endif |
909 | #if ENABLE_HUSH_LOOPS | 1013 | #if ENABLE_HUSH_LOOPS |
910 | BLTIN("break" , builtin_break , "Exit from a loop"), | 1014 | BLTIN("break" , builtin_break , "Exit loop"), |
911 | #endif | 1015 | #endif |
912 | BLTIN("cd" , builtin_cd , "Change directory"), | 1016 | BLTIN("cd" , builtin_cd , "Change directory"), |
913 | #if ENABLE_HUSH_LOOPS | 1017 | #if ENABLE_HUSH_LOOPS |
@@ -915,53 +1019,84 @@ static const struct built_in_command bltins1[] = { | |||
915 | #endif | 1019 | #endif |
916 | BLTIN("eval" , builtin_eval , "Construct and run shell command"), | 1020 | BLTIN("eval" , builtin_eval , "Construct and run shell command"), |
917 | BLTIN("exec" , builtin_exec , "Execute command, don't return to shell"), | 1021 | BLTIN("exec" , builtin_exec , "Execute command, don't return to shell"), |
918 | BLTIN("exit" , builtin_exit , "Exit"), | 1022 | BLTIN("exit" , builtin_exit , NULL), |
1023 | #if ENABLE_HUSH_EXPORT | ||
919 | BLTIN("export" , builtin_export , "Set environment variables"), | 1024 | BLTIN("export" , builtin_export , "Set environment variables"), |
1025 | #endif | ||
920 | #if ENABLE_HUSH_JOB | 1026 | #if ENABLE_HUSH_JOB |
921 | BLTIN("fg" , builtin_fg_bg , "Bring job into the foreground"), | 1027 | BLTIN("fg" , builtin_fg_bg , "Bring job into foreground"), |
922 | #endif | 1028 | #endif |
923 | #if ENABLE_HUSH_HELP | 1029 | #if ENABLE_HUSH_HELP |
924 | BLTIN("help" , builtin_help , NULL), | 1030 | BLTIN("help" , builtin_help , NULL), |
925 | #endif | 1031 | #endif |
926 | #if MAX_HISTORY && ENABLE_FEATURE_EDITING | 1032 | #if MAX_HISTORY && ENABLE_FEATURE_EDITING |
927 | BLTIN("history" , builtin_history , "Show command history"), | 1033 | BLTIN("history" , builtin_history , "Show history"), |
928 | #endif | 1034 | #endif |
929 | #if ENABLE_HUSH_JOB | 1035 | #if ENABLE_HUSH_JOB |
930 | BLTIN("jobs" , builtin_jobs , "List jobs"), | 1036 | BLTIN("jobs" , builtin_jobs , "List jobs"), |
931 | #endif | 1037 | #endif |
1038 | #if ENABLE_HUSH_KILL | ||
1039 | BLTIN("kill" , builtin_kill , "Send signals to processes"), | ||
1040 | #endif | ||
932 | #if ENABLE_HUSH_LOCAL | 1041 | #if ENABLE_HUSH_LOCAL |
933 | BLTIN("local" , builtin_local , "Set local variables"), | 1042 | BLTIN("local" , builtin_local , "Set local variables"), |
934 | #endif | 1043 | #endif |
935 | #if HUSH_DEBUG | 1044 | #if ENABLE_HUSH_MEMLEAK |
936 | BLTIN("memleak" , builtin_memleak , NULL), | 1045 | BLTIN("memleak" , builtin_memleak , NULL), |
937 | #endif | 1046 | #endif |
1047 | #if ENABLE_HUSH_READ | ||
938 | BLTIN("read" , builtin_read , "Input into variable"), | 1048 | BLTIN("read" , builtin_read , "Input into variable"), |
1049 | #endif | ||
939 | #if ENABLE_HUSH_FUNCTIONS | 1050 | #if ENABLE_HUSH_FUNCTIONS |
940 | BLTIN("return" , builtin_return , "Return from a function"), | 1051 | BLTIN("return" , builtin_return , "Return from function"), |
1052 | #endif | ||
1053 | #if ENABLE_HUSH_SET | ||
1054 | BLTIN("set" , builtin_set , "Set positional parameters"), | ||
941 | #endif | 1055 | #endif |
942 | BLTIN("set" , builtin_set , "Set/unset positional parameters"), | ||
943 | BLTIN("shift" , builtin_shift , "Shift positional parameters"), | 1056 | BLTIN("shift" , builtin_shift , "Shift positional parameters"), |
944 | #if ENABLE_HUSH_BASH_COMPAT | 1057 | #if BASH_SOURCE |
945 | BLTIN("source" , builtin_source , "Run commands in a file"), | 1058 | BLTIN("source" , builtin_source , NULL), |
946 | #endif | 1059 | #endif |
1060 | #if ENABLE_HUSH_TRAP | ||
947 | BLTIN("trap" , builtin_trap , "Trap signals"), | 1061 | BLTIN("trap" , builtin_trap , "Trap signals"), |
1062 | #endif | ||
948 | BLTIN("true" , builtin_true , NULL), | 1063 | BLTIN("true" , builtin_true , NULL), |
1064 | #if ENABLE_HUSH_TYPE | ||
949 | BLTIN("type" , builtin_type , "Show command type"), | 1065 | BLTIN("type" , builtin_type , "Show command type"), |
950 | BLTIN("ulimit" , shell_builtin_ulimit , "Control resource limits"), | 1066 | #endif |
1067 | #if ENABLE_HUSH_ULIMIT | ||
1068 | BLTIN("ulimit" , shell_builtin_ulimit, "Control resource limits"), | ||
1069 | #endif | ||
1070 | #if ENABLE_HUSH_UMASK | ||
951 | BLTIN("umask" , builtin_umask , "Set file creation mask"), | 1071 | BLTIN("umask" , builtin_umask , "Set file creation mask"), |
1072 | #endif | ||
1073 | #if ENABLE_HUSH_UNSET | ||
952 | BLTIN("unset" , builtin_unset , "Unset variables"), | 1074 | BLTIN("unset" , builtin_unset , "Unset variables"), |
1075 | #endif | ||
1076 | #if ENABLE_HUSH_WAIT | ||
953 | BLTIN("wait" , builtin_wait , "Wait for process"), | 1077 | BLTIN("wait" , builtin_wait , "Wait for process"), |
1078 | #endif | ||
954 | }; | 1079 | }; |
955 | /* For now, echo and test are unconditionally enabled. | 1080 | /* These builtins won't be used if we are on NOMMU and need to re-exec |
956 | * Maybe make it configurable? */ | 1081 | * (it's cheaper to run an external program in this case): |
1082 | */ | ||
957 | static const struct built_in_command bltins2[] = { | 1083 | static const struct built_in_command bltins2[] = { |
1084 | #if ENABLE_HUSH_TEST | ||
958 | BLTIN("[" , builtin_test , NULL), | 1085 | BLTIN("[" , builtin_test , NULL), |
1086 | #endif | ||
1087 | #if BASH_TEST2 | ||
1088 | BLTIN("[[" , builtin_test , NULL), | ||
1089 | #endif | ||
1090 | #if ENABLE_HUSH_ECHO | ||
959 | BLTIN("echo" , builtin_echo , NULL), | 1091 | BLTIN("echo" , builtin_echo , NULL), |
960 | #if ENABLE_PRINTF | 1092 | #endif |
1093 | #if ENABLE_HUSH_PRINTF | ||
961 | BLTIN("printf" , builtin_printf , NULL), | 1094 | BLTIN("printf" , builtin_printf , NULL), |
962 | #endif | 1095 | #endif |
963 | BLTIN("pwd" , builtin_pwd , NULL), | 1096 | BLTIN("pwd" , builtin_pwd , NULL), |
1097 | #if ENABLE_HUSH_TEST | ||
964 | BLTIN("test" , builtin_test , NULL), | 1098 | BLTIN("test" , builtin_test , NULL), |
1099 | #endif | ||
965 | }; | 1100 | }; |
966 | 1101 | ||
967 | 1102 | ||
@@ -1346,7 +1481,7 @@ typedef struct save_arg_t { | |||
1346 | char *sv_argv0; | 1481 | char *sv_argv0; |
1347 | char **sv_g_argv; | 1482 | char **sv_g_argv; |
1348 | int sv_g_argc; | 1483 | int sv_g_argc; |
1349 | smallint sv_g_malloced; | 1484 | IF_HUSH_SET(smallint sv_g_malloced;) |
1350 | } save_arg_t; | 1485 | } save_arg_t; |
1351 | 1486 | ||
1352 | static void save_and_replace_G_args(save_arg_t *sv, char **argv) | 1487 | static void save_and_replace_G_args(save_arg_t *sv, char **argv) |
@@ -1356,11 +1491,11 @@ static void save_and_replace_G_args(save_arg_t *sv, char **argv) | |||
1356 | sv->sv_argv0 = argv[0]; | 1491 | sv->sv_argv0 = argv[0]; |
1357 | sv->sv_g_argv = G.global_argv; | 1492 | sv->sv_g_argv = G.global_argv; |
1358 | sv->sv_g_argc = G.global_argc; | 1493 | sv->sv_g_argc = G.global_argc; |
1359 | sv->sv_g_malloced = G.global_args_malloced; | 1494 | IF_HUSH_SET(sv->sv_g_malloced = G.global_args_malloced;) |
1360 | 1495 | ||
1361 | argv[0] = G.global_argv[0]; /* retain $0 */ | 1496 | argv[0] = G.global_argv[0]; /* retain $0 */ |
1362 | G.global_argv = argv; | 1497 | G.global_argv = argv; |
1363 | G.global_args_malloced = 0; | 1498 | IF_HUSH_SET(G.global_args_malloced = 0;) |
1364 | 1499 | ||
1365 | n = 1; | 1500 | n = 1; |
1366 | while (*++argv) | 1501 | while (*++argv) |
@@ -1370,19 +1505,19 @@ static void save_and_replace_G_args(save_arg_t *sv, char **argv) | |||
1370 | 1505 | ||
1371 | static void restore_G_args(save_arg_t *sv, char **argv) | 1506 | static void restore_G_args(save_arg_t *sv, char **argv) |
1372 | { | 1507 | { |
1373 | char **pp; | 1508 | #if ENABLE_HUSH_SET |
1374 | |||
1375 | if (G.global_args_malloced) { | 1509 | if (G.global_args_malloced) { |
1376 | /* someone ran "set -- arg1 arg2 ...", undo */ | 1510 | /* someone ran "set -- arg1 arg2 ...", undo */ |
1377 | pp = G.global_argv; | 1511 | char **pp = G.global_argv; |
1378 | while (*++pp) /* note: does not free $0 */ | 1512 | while (*++pp) /* note: does not free $0 */ |
1379 | free(*pp); | 1513 | free(*pp); |
1380 | free(G.global_argv); | 1514 | free(G.global_argv); |
1381 | } | 1515 | } |
1516 | #endif | ||
1382 | argv[0] = sv->sv_argv0; | 1517 | argv[0] = sv->sv_argv0; |
1383 | G.global_argv = sv->sv_g_argv; | 1518 | G.global_argv = sv->sv_g_argv; |
1384 | G.global_argc = sv->sv_g_argc; | 1519 | G.global_argc = sv->sv_g_argc; |
1385 | G.global_args_malloced = sv->sv_g_malloced; | 1520 | IF_HUSH_SET(G.global_args_malloced = sv->sv_g_malloced;) |
1386 | } | 1521 | } |
1387 | 1522 | ||
1388 | 1523 | ||
@@ -1670,13 +1805,13 @@ static void hush_exit(int exitcode) | |||
1670 | #endif | 1805 | #endif |
1671 | 1806 | ||
1672 | fflush_all(); | 1807 | fflush_all(); |
1673 | if (G.exiting <= 0 && G.traps && G.traps[0] && G.traps[0][0]) { | 1808 | if (G.exiting <= 0 && G_traps && G_traps[0] && G_traps[0][0]) { |
1674 | char *argv[3]; | 1809 | char *argv[3]; |
1675 | /* argv[0] is unused */ | 1810 | /* argv[0] is unused */ |
1676 | argv[1] = G.traps[0]; | 1811 | argv[1] = G_traps[0]; |
1677 | argv[2] = NULL; | 1812 | argv[2] = NULL; |
1678 | G.exiting = 1; /* prevent EXIT trap recursion */ | 1813 | G.exiting = 1; /* prevent EXIT trap recursion */ |
1679 | /* Note: G.traps[0] is not cleared! | 1814 | /* Note: G_traps[0] is not cleared! |
1680 | * "trap" will still show it, if executed | 1815 | * "trap" will still show it, if executed |
1681 | * in the handler */ | 1816 | * in the handler */ |
1682 | builtin_eval(argv); | 1817 | builtin_eval(argv); |
@@ -1727,14 +1862,14 @@ static int check_and_run_traps(void) | |||
1727 | } while (sig < NSIG); | 1862 | } while (sig < NSIG); |
1728 | break; | 1863 | break; |
1729 | got_sig: | 1864 | got_sig: |
1730 | if (G.traps && G.traps[sig]) { | 1865 | if (G_traps && G_traps[sig]) { |
1731 | debug_printf_exec("%s: sig:%d handler:'%s'\n", __func__, sig, G.traps[sig]); | 1866 | debug_printf_exec("%s: sig:%d handler:'%s'\n", __func__, sig, G.traps[sig]); |
1732 | if (G.traps[sig][0]) { | 1867 | if (G_traps[sig][0]) { |
1733 | /* We have user-defined handler */ | 1868 | /* We have user-defined handler */ |
1734 | smalluint save_rcode; | 1869 | smalluint save_rcode; |
1735 | char *argv[3]; | 1870 | char *argv[3]; |
1736 | /* argv[0] is unused */ | 1871 | /* argv[0] is unused */ |
1737 | argv[1] = G.traps[sig]; | 1872 | argv[1] = G_traps[sig]; |
1738 | argv[2] = NULL; | 1873 | argv[2] = NULL; |
1739 | save_rcode = G.last_exitcode; | 1874 | save_rcode = G.last_exitcode; |
1740 | builtin_eval(argv); | 1875 | builtin_eval(argv); |
@@ -2030,10 +2165,12 @@ static int unset_local_var_len(const char *name, int name_len) | |||
2030 | return EXIT_SUCCESS; | 2165 | return EXIT_SUCCESS; |
2031 | } | 2166 | } |
2032 | 2167 | ||
2168 | #if ENABLE_HUSH_UNSET | ||
2033 | static int unset_local_var(const char *name) | 2169 | static int unset_local_var(const char *name) |
2034 | { | 2170 | { |
2035 | return unset_local_var_len(name, strlen(name)); | 2171 | return unset_local_var_len(name, strlen(name)); |
2036 | } | 2172 | } |
2173 | #endif | ||
2037 | 2174 | ||
2038 | static void unset_vars(char **strings) | 2175 | static void unset_vars(char **strings) |
2039 | { | 2176 | { |
@@ -2050,11 +2187,13 @@ static void unset_vars(char **strings) | |||
2050 | free(strings); | 2187 | free(strings); |
2051 | } | 2188 | } |
2052 | 2189 | ||
2190 | #if BASH_HOSTNAME_VAR || ENABLE_FEATURE_SH_MATH || ENABLE_HUSH_READ | ||
2053 | static void FAST_FUNC set_local_var_from_halves(const char *name, const char *val) | 2191 | static void FAST_FUNC set_local_var_from_halves(const char *name, const char *val) |
2054 | { | 2192 | { |
2055 | char *var = xasprintf("%s=%s", name, val); | 2193 | char *var = xasprintf("%s=%s", name, val); |
2056 | set_local_var(var, /*flags:*/ 0, /*lvl:*/ 0, /*ro:*/ 0); | 2194 | set_local_var(var, /*flags:*/ 0, /*lvl:*/ 0, /*ro:*/ 0); |
2057 | } | 2195 | } |
2196 | #endif | ||
2058 | 2197 | ||
2059 | 2198 | ||
2060 | /* | 2199 | /* |
@@ -3507,7 +3646,7 @@ static int done_word(o_string *word, struct parse_context *ctx) | |||
3507 | (ctx->ctx_res_w == RES_SNTX)); | 3646 | (ctx->ctx_res_w == RES_SNTX)); |
3508 | return (ctx->ctx_res_w == RES_SNTX); | 3647 | return (ctx->ctx_res_w == RES_SNTX); |
3509 | } | 3648 | } |
3510 | # if ENABLE_HUSH_BASH_COMPAT | 3649 | # if BASH_TEST2 |
3511 | if (strcmp(word->data, "[[") == 0) { | 3650 | if (strcmp(word->data, "[[") == 0) { |
3512 | command->cmd_type = CMD_SINGLEWORD_NOGLOB; | 3651 | command->cmd_type = CMD_SINGLEWORD_NOGLOB; |
3513 | } | 3652 | } |
@@ -4105,7 +4244,7 @@ static int add_till_closing_bracket(o_string *dest, struct in_str *input, unsign | |||
4105 | { | 4244 | { |
4106 | int ch; | 4245 | int ch; |
4107 | char dbl = end_ch & DOUBLE_CLOSE_CHAR_FLAG; | 4246 | char dbl = end_ch & DOUBLE_CLOSE_CHAR_FLAG; |
4108 | # if ENABLE_HUSH_BASH_COMPAT | 4247 | # if BASH_SUBSTR || BASH_PATTERN_SUBST |
4109 | char end_char2 = end_ch >> 8; | 4248 | char end_char2 = end_ch >> 8; |
4110 | # endif | 4249 | # endif |
4111 | end_ch &= (DOUBLE_CLOSE_CHAR_FLAG - 1); | 4250 | end_ch &= (DOUBLE_CLOSE_CHAR_FLAG - 1); |
@@ -4116,7 +4255,11 @@ static int add_till_closing_bracket(o_string *dest, struct in_str *input, unsign | |||
4116 | syntax_error_unterm_ch(end_ch); | 4255 | syntax_error_unterm_ch(end_ch); |
4117 | return 0; | 4256 | return 0; |
4118 | } | 4257 | } |
4119 | if (ch == end_ch IF_HUSH_BASH_COMPAT( || ch == end_char2)) { | 4258 | if (ch == end_ch |
4259 | # if BASH_SUBSTR || BASH_PATTERN_SUBST | ||
4260 | || ch == end_char2 | ||
4261 | # endif | ||
4262 | ) { | ||
4120 | if (!dbl) | 4263 | if (!dbl) |
4121 | break; | 4264 | break; |
4122 | /* we look for closing )) of $((EXPR)) */ | 4265 | /* we look for closing )) of $((EXPR)) */ |
@@ -4269,14 +4412,14 @@ static int parse_dollar(o_string *as_string, | |||
4269 | 4412 | ||
4270 | /* Eat everything until closing '}' (or ':') */ | 4413 | /* Eat everything until closing '}' (or ':') */ |
4271 | end_ch = '}'; | 4414 | end_ch = '}'; |
4272 | if (ENABLE_HUSH_BASH_COMPAT | 4415 | if (BASH_SUBSTR |
4273 | && ch == ':' | 4416 | && ch == ':' |
4274 | && !strchr(MINUS_PLUS_EQUAL_QUESTION, i_peek(input)) | 4417 | && !strchr(MINUS_PLUS_EQUAL_QUESTION, i_peek(input)) |
4275 | ) { | 4418 | ) { |
4276 | /* It's ${var:N[:M]} thing */ | 4419 | /* It's ${var:N[:M]} thing */ |
4277 | end_ch = '}' * 0x100 + ':'; | 4420 | end_ch = '}' * 0x100 + ':'; |
4278 | } | 4421 | } |
4279 | if (ENABLE_HUSH_BASH_COMPAT | 4422 | if (BASH_PATTERN_SUBST |
4280 | && ch == '/' | 4423 | && ch == '/' |
4281 | ) { | 4424 | ) { |
4282 | /* It's ${var/[/]pattern[/repl]} thing */ | 4425 | /* It's ${var/[/]pattern[/repl]} thing */ |
@@ -4303,7 +4446,9 @@ static int parse_dollar(o_string *as_string, | |||
4303 | o_addchr(as_string, last_ch); | 4446 | o_addchr(as_string, last_ch); |
4304 | } | 4447 | } |
4305 | 4448 | ||
4306 | if (ENABLE_HUSH_BASH_COMPAT && (end_ch & 0xff00)) { | 4449 | if ((BASH_SUBSTR || BASH_PATTERN_SUBST) |
4450 | && (end_ch & 0xff00) | ||
4451 | ) { | ||
4307 | /* close the first block: */ | 4452 | /* close the first block: */ |
4308 | o_addchr(dest, SPECIAL_VAR_SYMBOL); | 4453 | o_addchr(dest, SPECIAL_VAR_SYMBOL); |
4309 | /* while parsing N from ${var:N[:M]} | 4454 | /* while parsing N from ${var:N[:M]} |
@@ -4314,7 +4459,7 @@ static int parse_dollar(o_string *as_string, | |||
4314 | goto again; | 4459 | goto again; |
4315 | } | 4460 | } |
4316 | /* got '}' */ | 4461 | /* got '}' */ |
4317 | if (end_ch == '}' * 0x100 + ':') { | 4462 | if (BASH_SUBSTR && end_ch == '}' * 0x100 + ':') { |
4318 | /* it's ${var:N} - emulate :999999999 */ | 4463 | /* it's ${var:N} - emulate :999999999 */ |
4319 | o_addstr(dest, "999999999"); | 4464 | o_addstr(dest, "999999999"); |
4320 | } /* else: it's ${var/[/]pattern} */ | 4465 | } /* else: it's ${var/[/]pattern} */ |
@@ -4389,7 +4534,7 @@ static int parse_dollar(o_string *as_string, | |||
4389 | } | 4534 | } |
4390 | 4535 | ||
4391 | #if BB_MMU | 4536 | #if BB_MMU |
4392 | # if ENABLE_HUSH_BASH_COMPAT | 4537 | # if BASH_PATTERN_SUBST |
4393 | #define encode_string(as_string, dest, input, dquote_end, process_bkslash) \ | 4538 | #define encode_string(as_string, dest, input, dquote_end, process_bkslash) \ |
4394 | encode_string(dest, input, dquote_end, process_bkslash) | 4539 | encode_string(dest, input, dquote_end, process_bkslash) |
4395 | # else | 4540 | # else |
@@ -4401,7 +4546,7 @@ static int parse_dollar(o_string *as_string, | |||
4401 | 4546 | ||
4402 | #else /* !MMU */ | 4547 | #else /* !MMU */ |
4403 | 4548 | ||
4404 | # if ENABLE_HUSH_BASH_COMPAT | 4549 | # if BASH_PATTERN_SUBST |
4405 | /* all parameters are needed, no macro tricks */ | 4550 | /* all parameters are needed, no macro tricks */ |
4406 | # else | 4551 | # else |
4407 | #define encode_string(as_string, dest, input, dquote_end, process_bkslash) \ | 4552 | #define encode_string(as_string, dest, input, dquote_end, process_bkslash) \ |
@@ -4414,7 +4559,7 @@ static int encode_string(o_string *as_string, | |||
4414 | int dquote_end, | 4559 | int dquote_end, |
4415 | int process_bkslash) | 4560 | int process_bkslash) |
4416 | { | 4561 | { |
4417 | #if !ENABLE_HUSH_BASH_COMPAT | 4562 | #if !BASH_PATTERN_SUBST |
4418 | const int process_bkslash = 1; | 4563 | const int process_bkslash = 1; |
4419 | #endif | 4564 | #endif |
4420 | int ch; | 4565 | int ch; |
@@ -5057,7 +5202,7 @@ static struct pipe *parse_stream(char **pstring, | |||
5057 | /*** Execution routines ***/ | 5202 | /*** Execution routines ***/ |
5058 | 5203 | ||
5059 | /* Expansion can recurse, need forward decls: */ | 5204 | /* Expansion can recurse, need forward decls: */ |
5060 | #if !ENABLE_HUSH_BASH_COMPAT | 5205 | #if !BASH_PATTERN_SUBST |
5061 | /* only ${var/pattern/repl} (its pattern part) needs additional mode */ | 5206 | /* only ${var/pattern/repl} (its pattern part) needs additional mode */ |
5062 | #define expand_string_to_string(str, do_unbackslash) \ | 5207 | #define expand_string_to_string(str, do_unbackslash) \ |
5063 | expand_string_to_string(str) | 5208 | expand_string_to_string(str) |
@@ -5178,7 +5323,7 @@ static int expand_on_ifs(int *ended_with_ifs, o_string *output, int n, const cha | |||
5178 | * Returns malloced string. | 5323 | * Returns malloced string. |
5179 | * As an optimization, we return NULL if expansion is not needed. | 5324 | * As an optimization, we return NULL if expansion is not needed. |
5180 | */ | 5325 | */ |
5181 | #if !ENABLE_HUSH_BASH_COMPAT | 5326 | #if !BASH_PATTERN_SUBST |
5182 | /* only ${var/pattern/repl} (its pattern part) needs additional mode */ | 5327 | /* only ${var/pattern/repl} (its pattern part) needs additional mode */ |
5183 | #define encode_then_expand_string(str, process_bkslash, do_unbackslash) \ | 5328 | #define encode_then_expand_string(str, process_bkslash, do_unbackslash) \ |
5184 | encode_then_expand_string(str) | 5329 | encode_then_expand_string(str) |
@@ -5232,7 +5377,7 @@ static arith_t expand_and_evaluate_arith(const char *arg, const char **errmsg_p) | |||
5232 | } | 5377 | } |
5233 | #endif | 5378 | #endif |
5234 | 5379 | ||
5235 | #if ENABLE_HUSH_BASH_COMPAT | 5380 | #if BASH_PATTERN_SUBST |
5236 | /* ${var/[/]pattern[/repl]} helpers */ | 5381 | /* ${var/[/]pattern[/repl]} helpers */ |
5237 | static char *strstr_pattern(char *val, const char *pattern, int *size) | 5382 | static char *strstr_pattern(char *val, const char *pattern, int *size) |
5238 | { | 5383 | { |
@@ -5284,7 +5429,7 @@ static char *replace_pattern(char *val, const char *pattern, const char *repl, c | |||
5284 | debug_printf_varexp("result:'%s'\n", result); | 5429 | debug_printf_varexp("result:'%s'\n", result); |
5285 | return result; | 5430 | return result; |
5286 | } | 5431 | } |
5287 | #endif | 5432 | #endif /* BASH_PATTERN_SUBST */ |
5288 | 5433 | ||
5289 | /* Helper: | 5434 | /* Helper: |
5290 | * Handles <SPECIAL_VAR_SYMBOL>varname...<SPECIAL_VAR_SYMBOL> construct. | 5435 | * Handles <SPECIAL_VAR_SYMBOL>varname...<SPECIAL_VAR_SYMBOL> construct. |
@@ -5332,7 +5477,7 @@ static NOINLINE const char *expand_one_var(char **to_be_freed_pp, char *arg, cha | |||
5332 | if (exp_op == ':') { | 5477 | if (exp_op == ':') { |
5333 | exp_op = *exp_word++; | 5478 | exp_op = *exp_word++; |
5334 | //TODO: try ${var:} and ${var:bogus} in non-bash config | 5479 | //TODO: try ${var:} and ${var:bogus} in non-bash config |
5335 | if (ENABLE_HUSH_BASH_COMPAT | 5480 | if (BASH_SUBSTR |
5336 | && (!exp_op || !strchr(MINUS_PLUS_EQUAL_QUESTION, exp_op)) | 5481 | && (!exp_op || !strchr(MINUS_PLUS_EQUAL_QUESTION, exp_op)) |
5337 | ) { | 5482 | ) { |
5338 | /* oops... it's ${var:N[:M]}, not ${var:?xxx} or some such */ | 5483 | /* oops... it's ${var:N[:M]}, not ${var:?xxx} or some such */ |
@@ -5414,7 +5559,7 @@ static NOINLINE const char *expand_one_var(char **to_be_freed_pp, char *arg, cha | |||
5414 | } | 5559 | } |
5415 | } | 5560 | } |
5416 | } | 5561 | } |
5417 | #if ENABLE_HUSH_BASH_COMPAT | 5562 | #if BASH_PATTERN_SUBST |
5418 | else if (exp_op == '/' || exp_op == '\\') { | 5563 | else if (exp_op == '/' || exp_op == '\\') { |
5419 | /* It's ${var/[/]pattern[/repl]} thing. | 5564 | /* It's ${var/[/]pattern[/repl]} thing. |
5420 | * Note that in encoded form it has TWO parts: | 5565 | * Note that in encoded form it has TWO parts: |
@@ -5461,9 +5606,9 @@ static NOINLINE const char *expand_one_var(char **to_be_freed_pp, char *arg, cha | |||
5461 | free(repl); | 5606 | free(repl); |
5462 | } | 5607 | } |
5463 | } | 5608 | } |
5464 | #endif | 5609 | #endif /* BASH_PATTERN_SUBST */ |
5465 | else if (exp_op == ':') { | 5610 | else if (exp_op == ':') { |
5466 | #if ENABLE_HUSH_BASH_COMPAT && ENABLE_FEATURE_SH_MATH | 5611 | #if BASH_SUBSTR && ENABLE_FEATURE_SH_MATH |
5467 | /* It's ${var:N[:M]} bashism. | 5612 | /* It's ${var:N[:M]} bashism. |
5468 | * Note that in encoded form it has TWO parts: | 5613 | * Note that in encoded form it has TWO parts: |
5469 | * var:N<SPECIAL_VAR_SYMBOL>M<SPECIAL_VAR_SYMBOL> | 5614 | * var:N<SPECIAL_VAR_SYMBOL>M<SPECIAL_VAR_SYMBOL> |
@@ -5499,7 +5644,7 @@ static NOINLINE const char *expand_one_var(char **to_be_freed_pp, char *arg, cha | |||
5499 | } | 5644 | } |
5500 | debug_printf_varexp("val:'%s'\n", val); | 5645 | debug_printf_varexp("val:'%s'\n", val); |
5501 | } else | 5646 | } else |
5502 | #endif | 5647 | #endif /* HUSH_SUBSTR_EXPANSION && FEATURE_SH_MATH */ |
5503 | { | 5648 | { |
5504 | die_if_script("malformed ${%s:...}", var); | 5649 | die_if_script("malformed ${%s:...}", var); |
5505 | val = NULL; | 5650 | val = NULL; |
@@ -5789,7 +5934,7 @@ static char **expand_strvec_to_strvec(char **argv) | |||
5789 | return expand_variables(argv, EXP_FLAG_GLOB | EXP_FLAG_ESC_GLOB_CHARS); | 5934 | return expand_variables(argv, EXP_FLAG_GLOB | EXP_FLAG_ESC_GLOB_CHARS); |
5790 | } | 5935 | } |
5791 | 5936 | ||
5792 | #if ENABLE_HUSH_BASH_COMPAT | 5937 | #if BASH_TEST2 |
5793 | static char **expand_strvec_to_strvec_singleword_noglob(char **argv) | 5938 | static char **expand_strvec_to_strvec_singleword_noglob(char **argv) |
5794 | { | 5939 | { |
5795 | return expand_variables(argv, EXP_FLAG_SINGLEWORD); | 5940 | return expand_variables(argv, EXP_FLAG_SINGLEWORD); |
@@ -5804,7 +5949,7 @@ static char **expand_strvec_to_strvec_singleword_noglob(char **argv) | |||
5804 | */ | 5949 | */ |
5805 | static char *expand_string_to_string(const char *str, int do_unbackslash) | 5950 | static char *expand_string_to_string(const char *str, int do_unbackslash) |
5806 | { | 5951 | { |
5807 | #if !ENABLE_HUSH_BASH_COMPAT | 5952 | #if !BASH_PATTERN_SUBST |
5808 | const int do_unbackslash = 1; | 5953 | const int do_unbackslash = 1; |
5809 | #endif | 5954 | #endif |
5810 | char *argv[2], **list; | 5955 | char *argv[2], **list; |
@@ -5882,13 +6027,15 @@ static void switch_off_special_sigs(unsigned mask) | |||
5882 | sig++; | 6027 | sig++; |
5883 | if (!(mask & 1)) | 6028 | if (!(mask & 1)) |
5884 | continue; | 6029 | continue; |
5885 | if (G.traps) { | 6030 | #if ENABLE_HUSH_TRAP |
5886 | if (G.traps[sig] && !G.traps[sig][0]) | 6031 | if (G_traps) { |
6032 | if (G_traps[sig] && !G_traps[sig][0]) | ||
5887 | /* trap is '', has to remain SIG_IGN */ | 6033 | /* trap is '', has to remain SIG_IGN */ |
5888 | continue; | 6034 | continue; |
5889 | free(G.traps[sig]); | 6035 | free(G_traps[sig]); |
5890 | G.traps[sig] = NULL; | 6036 | G_traps[sig] = NULL; |
5891 | } | 6037 | } |
6038 | #endif | ||
5892 | /* We are here only if no trap or trap was not '' */ | 6039 | /* We are here only if no trap or trap was not '' */ |
5893 | install_sighandler(sig, SIG_DFL); | 6040 | install_sighandler(sig, SIG_DFL); |
5894 | } | 6041 | } |
@@ -5905,7 +6052,7 @@ static void reset_traps_to_defaults(void) | |||
5905 | /* This function is always called in a child shell | 6052 | /* This function is always called in a child shell |
5906 | * after fork (not vfork, NOMMU doesn't use this function). | 6053 | * after fork (not vfork, NOMMU doesn't use this function). |
5907 | */ | 6054 | */ |
5908 | unsigned sig; | 6055 | IF_HUSH_TRAP(unsigned sig;) |
5909 | unsigned mask; | 6056 | unsigned mask; |
5910 | 6057 | ||
5911 | /* Child shells are not interactive. | 6058 | /* Child shells are not interactive. |
@@ -5914,35 +6061,37 @@ static void reset_traps_to_defaults(void) | |||
5914 | * Same goes for SIGTERM, SIGHUP, SIGINT. | 6061 | * Same goes for SIGTERM, SIGHUP, SIGINT. |
5915 | */ | 6062 | */ |
5916 | mask = (G.special_sig_mask & SPECIAL_INTERACTIVE_SIGS) | G_fatal_sig_mask; | 6063 | mask = (G.special_sig_mask & SPECIAL_INTERACTIVE_SIGS) | G_fatal_sig_mask; |
5917 | if (!G.traps && !mask) | 6064 | if (!G_traps && !mask) |
5918 | return; /* already no traps and no special sigs */ | 6065 | return; /* already no traps and no special sigs */ |
5919 | 6066 | ||
5920 | /* Switch off special sigs */ | 6067 | /* Switch off special sigs */ |
5921 | switch_off_special_sigs(mask); | 6068 | switch_off_special_sigs(mask); |
5922 | #if ENABLE_HUSH_JOB | 6069 | # if ENABLE_HUSH_JOB |
5923 | G_fatal_sig_mask = 0; | 6070 | G_fatal_sig_mask = 0; |
5924 | #endif | 6071 | # endif |
5925 | G.special_sig_mask &= ~SPECIAL_INTERACTIVE_SIGS; | 6072 | G.special_sig_mask &= ~SPECIAL_INTERACTIVE_SIGS; |
5926 | /* SIGQUIT,SIGCHLD and maybe SPECIAL_JOBSTOP_SIGS | 6073 | /* SIGQUIT,SIGCHLD and maybe SPECIAL_JOBSTOP_SIGS |
5927 | * remain set in G.special_sig_mask */ | 6074 | * remain set in G.special_sig_mask */ |
5928 | 6075 | ||
5929 | if (!G.traps) | 6076 | # if ENABLE_HUSH_TRAP |
6077 | if (!G_traps) | ||
5930 | return; | 6078 | return; |
5931 | 6079 | ||
5932 | /* Reset all sigs to default except ones with empty traps */ | 6080 | /* Reset all sigs to default except ones with empty traps */ |
5933 | for (sig = 0; sig < NSIG; sig++) { | 6081 | for (sig = 0; sig < NSIG; sig++) { |
5934 | if (!G.traps[sig]) | 6082 | if (!G_traps[sig]) |
5935 | continue; /* no trap: nothing to do */ | 6083 | continue; /* no trap: nothing to do */ |
5936 | if (!G.traps[sig][0]) | 6084 | if (!G_traps[sig][0]) |
5937 | continue; /* empty trap: has to remain SIG_IGN */ | 6085 | continue; /* empty trap: has to remain SIG_IGN */ |
5938 | /* sig has non-empty trap, reset it: */ | 6086 | /* sig has non-empty trap, reset it: */ |
5939 | free(G.traps[sig]); | 6087 | free(G_traps[sig]); |
5940 | G.traps[sig] = NULL; | 6088 | G_traps[sig] = NULL; |
5941 | /* There is no signal for trap 0 (EXIT) */ | 6089 | /* There is no signal for trap 0 (EXIT) */ |
5942 | if (sig == 0) | 6090 | if (sig == 0) |
5943 | continue; | 6091 | continue; |
5944 | install_sighandler(sig, pick_sighandler(sig)); | 6092 | install_sighandler(sig, pick_sighandler(sig)); |
5945 | } | 6093 | } |
6094 | # endif | ||
5946 | } | 6095 | } |
5947 | 6096 | ||
5948 | #else /* !BB_MMU */ | 6097 | #else /* !BB_MMU */ |
@@ -5982,10 +6131,10 @@ static void re_execute_shell(char ***to_free, const char *s, | |||
5982 | cnt++; | 6131 | cnt++; |
5983 | 6132 | ||
5984 | empty_trap_mask = 0; | 6133 | empty_trap_mask = 0; |
5985 | if (G.traps) { | 6134 | if (G_traps) { |
5986 | int sig; | 6135 | int sig; |
5987 | for (sig = 1; sig < NSIG; sig++) { | 6136 | for (sig = 1; sig < NSIG; sig++) { |
5988 | if (G.traps[sig] && !G.traps[sig][0]) | 6137 | if (G_traps[sig] && !G_traps[sig][0]) |
5989 | empty_trap_mask |= 1LL << sig; | 6138 | empty_trap_mask |= 1LL << sig; |
5990 | } | 6139 | } |
5991 | } | 6140 | } |
@@ -6178,6 +6327,7 @@ static FILE *generate_stream_from_string(const char *s, pid_t *pid_p) | |||
6178 | xmove_fd(channel[1], 1); | 6327 | xmove_fd(channel[1], 1); |
6179 | /* Prevent it from trying to handle ctrl-z etc */ | 6328 | /* Prevent it from trying to handle ctrl-z etc */ |
6180 | IF_HUSH_JOB(G.run_list_level = 1;) | 6329 | IF_HUSH_JOB(G.run_list_level = 1;) |
6330 | # if ENABLE_HUSH_TRAP | ||
6181 | /* Awful hack for `trap` or $(trap). | 6331 | /* Awful hack for `trap` or $(trap). |
6182 | * | 6332 | * |
6183 | * http://www.opengroup.org/onlinepubs/009695399/utilities/trap.html | 6333 | * http://www.opengroup.org/onlinepubs/009695399/utilities/trap.html |
@@ -6221,6 +6371,7 @@ static FILE *generate_stream_from_string(const char *s, pid_t *pid_p) | |||
6221 | fflush_all(); /* important */ | 6371 | fflush_all(); /* important */ |
6222 | _exit(0); | 6372 | _exit(0); |
6223 | } | 6373 | } |
6374 | # endif | ||
6224 | # if BB_MMU | 6375 | # if BB_MMU |
6225 | reset_traps_to_defaults(); | 6376 | reset_traps_to_defaults(); |
6226 | parse_and_run_string(s); | 6377 | parse_and_run_string(s); |
@@ -6629,6 +6780,7 @@ static struct function *new_function(char *name) | |||
6629 | return funcp; | 6780 | return funcp; |
6630 | } | 6781 | } |
6631 | 6782 | ||
6783 | # if ENABLE_HUSH_UNSET | ||
6632 | static void unset_func(const char *name) | 6784 | static void unset_func(const char *name) |
6633 | { | 6785 | { |
6634 | struct function **funcpp = find_function_slot(name); | 6786 | struct function **funcpp = find_function_slot(name); |
@@ -6644,13 +6796,14 @@ static void unset_func(const char *name) | |||
6644 | if (funcp->body) { | 6796 | if (funcp->body) { |
6645 | free_pipe_list(funcp->body); | 6797 | free_pipe_list(funcp->body); |
6646 | free(funcp->name); | 6798 | free(funcp->name); |
6647 | # if !BB_MMU | 6799 | # if !BB_MMU |
6648 | free(funcp->body_as_string); | 6800 | free(funcp->body_as_string); |
6649 | # endif | 6801 | # endif |
6650 | } | 6802 | } |
6651 | free(funcp); | 6803 | free(funcp); |
6652 | } | 6804 | } |
6653 | } | 6805 | } |
6806 | # endif | ||
6654 | 6807 | ||
6655 | # if BB_MMU | 6808 | # if BB_MMU |
6656 | #define exec_function(to_free, funcp, argv) \ | 6809 | #define exec_function(to_free, funcp, argv) \ |
@@ -7043,7 +7196,7 @@ static void insert_bg_job(struct pipe *pi) | |||
7043 | job->cmdtext = xstrdup(get_cmdtext(pi)); | 7196 | job->cmdtext = xstrdup(get_cmdtext(pi)); |
7044 | 7197 | ||
7045 | if (G_interactive_fd) | 7198 | if (G_interactive_fd) |
7046 | printf("[%d] %d %s\n", job->jobid, job->cmds[0].pid, job->cmdtext); | 7199 | printf("[%u] %u %s\n", job->jobid, (unsigned)job->cmds[0].pid, job->cmdtext); |
7047 | G.last_jobid = job->jobid; | 7200 | G.last_jobid = job->jobid; |
7048 | } | 7201 | } |
7049 | 7202 | ||
@@ -7518,7 +7671,7 @@ static NOINLINE int run_pipe(struct pipe *pi) | |||
7518 | } | 7671 | } |
7519 | 7672 | ||
7520 | /* Expand the rest into (possibly) many strings each */ | 7673 | /* Expand the rest into (possibly) many strings each */ |
7521 | #if ENABLE_HUSH_BASH_COMPAT | 7674 | #if BASH_TEST2 |
7522 | if (command->cmd_type == CMD_SINGLEWORD_NOGLOB) { | 7675 | if (command->cmd_type == CMD_SINGLEWORD_NOGLOB) { |
7523 | argv_expanded = expand_strvec_to_strvec_singleword_noglob(argv + command->assignment_cnt); | 7676 | argv_expanded = expand_strvec_to_strvec_singleword_noglob(argv + command->assignment_cnt); |
7524 | } else | 7677 | } else |
@@ -8118,10 +8271,12 @@ static void install_sighandlers(unsigned mask) | |||
8118 | if (old_handler == SIG_IGN) { | 8271 | if (old_handler == SIG_IGN) { |
8119 | /* oops... restore back to IGN, and record this fact */ | 8272 | /* oops... restore back to IGN, and record this fact */ |
8120 | install_sighandler(sig, old_handler); | 8273 | install_sighandler(sig, old_handler); |
8121 | if (!G.traps) | 8274 | #if ENABLE_HUSH_TRAP |
8122 | G.traps = xzalloc(sizeof(G.traps[0]) * NSIG); | 8275 | if (!G_traps) |
8123 | free(G.traps[sig]); | 8276 | G_traps = xzalloc(sizeof(G_traps[0]) * NSIG); |
8124 | G.traps[sig] = xzalloc(1); /* == xstrdup(""); */ | 8277 | free(G_traps[sig]); |
8278 | G_traps[sig] = xzalloc(1); /* == xstrdup(""); */ | ||
8279 | #endif | ||
8125 | } | 8280 | } |
8126 | } | 8281 | } |
8127 | } | 8282 | } |
@@ -8272,7 +8427,7 @@ int hush_main(int argc, char **argv) | |||
8272 | /* Export PWD */ | 8427 | /* Export PWD */ |
8273 | set_pwd_var(/*exp:*/ 1); | 8428 | set_pwd_var(/*exp:*/ 1); |
8274 | 8429 | ||
8275 | #if ENABLE_HUSH_BASH_COMPAT | 8430 | #if BASH_HOSTNAME_VAR |
8276 | /* Set (but not export) HOSTNAME unless already set */ | 8431 | /* Set (but not export) HOSTNAME unless already set */ |
8277 | if (!get_local_var_value("HOSTNAME")) { | 8432 | if (!get_local_var_value("HOSTNAME")) { |
8278 | struct utsname uts; | 8433 | struct utsname uts; |
@@ -8422,10 +8577,10 @@ int hush_main(int argc, char **argv) | |||
8422 | if (empty_trap_mask != 0) { | 8577 | if (empty_trap_mask != 0) { |
8423 | int sig; | 8578 | int sig; |
8424 | install_special_sighandlers(); | 8579 | install_special_sighandlers(); |
8425 | G.traps = xzalloc(sizeof(G.traps[0]) * NSIG); | 8580 | G_traps = xzalloc(sizeof(G_traps[0]) * NSIG); |
8426 | for (sig = 1; sig < NSIG; sig++) { | 8581 | for (sig = 1; sig < NSIG; sig++) { |
8427 | if (empty_trap_mask & (1LL << sig)) { | 8582 | if (empty_trap_mask & (1LL << sig)) { |
8428 | G.traps[sig] = xzalloc(1); /* == xstrdup(""); */ | 8583 | G_traps[sig] = xzalloc(1); /* == xstrdup(""); */ |
8429 | install_sighandler(sig, SIG_IGN); | 8584 | install_sighandler(sig, SIG_IGN); |
8430 | } | 8585 | } |
8431 | } | 8586 | } |
@@ -8669,6 +8824,7 @@ static int FAST_FUNC builtin_true(char **argv UNUSED_PARAM) | |||
8669 | return 0; | 8824 | return 0; |
8670 | } | 8825 | } |
8671 | 8826 | ||
8827 | #if ENABLE_HUSH_TEST || ENABLE_HUSH_ECHO || ENABLE_HUSH_PRINTF || ENABLE_HUSH_KILL | ||
8672 | static int run_applet_main(char **argv, int (*applet_main_func)(int argc, char **argv)) | 8828 | static int run_applet_main(char **argv, int (*applet_main_func)(int argc, char **argv)) |
8673 | { | 8829 | { |
8674 | int argc = 0; | 8830 | int argc = 0; |
@@ -8678,24 +8834,50 @@ static int run_applet_main(char **argv, int (*applet_main_func)(int argc, char * | |||
8678 | } | 8834 | } |
8679 | return applet_main_func(argc, argv - argc); | 8835 | return applet_main_func(argc, argv - argc); |
8680 | } | 8836 | } |
8681 | 8837 | #endif | |
8838 | #if ENABLE_HUSH_TEST || BASH_TEST2 | ||
8682 | static int FAST_FUNC builtin_test(char **argv) | 8839 | static int FAST_FUNC builtin_test(char **argv) |
8683 | { | 8840 | { |
8684 | return run_applet_main(argv, test_main); | 8841 | return run_applet_main(argv, test_main); |
8685 | } | 8842 | } |
8686 | 8843 | #endif | |
8844 | #if ENABLE_HUSH_ECHO | ||
8687 | static int FAST_FUNC builtin_echo(char **argv) | 8845 | static int FAST_FUNC builtin_echo(char **argv) |
8688 | { | 8846 | { |
8689 | return run_applet_main(argv, echo_main); | 8847 | return run_applet_main(argv, echo_main); |
8690 | } | 8848 | } |
8691 | 8849 | #endif | |
8692 | #if ENABLE_PRINTF | 8850 | #if ENABLE_HUSH_PRINTF |
8693 | static int FAST_FUNC builtin_printf(char **argv) | 8851 | static int FAST_FUNC builtin_printf(char **argv) |
8694 | { | 8852 | { |
8695 | return run_applet_main(argv, printf_main); | 8853 | return run_applet_main(argv, printf_main); |
8696 | } | 8854 | } |
8697 | #endif | 8855 | #endif |
8698 | 8856 | ||
8857 | #if ENABLE_HUSH_HELP | ||
8858 | static int FAST_FUNC builtin_help(char **argv UNUSED_PARAM) | ||
8859 | { | ||
8860 | const struct built_in_command *x; | ||
8861 | |||
8862 | printf( | ||
8863 | "Built-in commands:\n" | ||
8864 | "------------------\n"); | ||
8865 | for (x = bltins1; x != &bltins1[ARRAY_SIZE(bltins1)]; x++) { | ||
8866 | if (x->b_descr) | ||
8867 | printf("%-10s%s\n", x->b_cmd, x->b_descr); | ||
8868 | } | ||
8869 | return EXIT_SUCCESS; | ||
8870 | } | ||
8871 | #endif | ||
8872 | |||
8873 | #if MAX_HISTORY && ENABLE_FEATURE_EDITING | ||
8874 | static int FAST_FUNC builtin_history(char **argv UNUSED_PARAM) | ||
8875 | { | ||
8876 | show_history(G.line_input_state); | ||
8877 | return EXIT_SUCCESS; | ||
8878 | } | ||
8879 | #endif | ||
8880 | |||
8699 | static char **skip_dash_dash(char **argv) | 8881 | static char **skip_dash_dash(char **argv) |
8700 | { | 8882 | { |
8701 | argv++; | 8883 | argv++; |
@@ -8704,24 +8886,6 @@ static char **skip_dash_dash(char **argv) | |||
8704 | return argv; | 8886 | return argv; |
8705 | } | 8887 | } |
8706 | 8888 | ||
8707 | static int FAST_FUNC builtin_eval(char **argv) | ||
8708 | { | ||
8709 | int rcode = EXIT_SUCCESS; | ||
8710 | |||
8711 | argv = skip_dash_dash(argv); | ||
8712 | if (*argv) { | ||
8713 | char *str = expand_strvec_to_string(argv); | ||
8714 | /* bash: | ||
8715 | * eval "echo Hi; done" ("done" is syntax error): | ||
8716 | * "echo Hi" will not execute too. | ||
8717 | */ | ||
8718 | parse_and_run_string(str); | ||
8719 | free(str); | ||
8720 | rcode = G.last_exitcode; | ||
8721 | } | ||
8722 | return rcode; | ||
8723 | } | ||
8724 | |||
8725 | static int FAST_FUNC builtin_cd(char **argv) | 8889 | static int FAST_FUNC builtin_cd(char **argv) |
8726 | { | 8890 | { |
8727 | const char *newdir; | 8891 | const char *newdir; |
@@ -8749,6 +8913,30 @@ static int FAST_FUNC builtin_cd(char **argv) | |||
8749 | return EXIT_SUCCESS; | 8913 | return EXIT_SUCCESS; |
8750 | } | 8914 | } |
8751 | 8915 | ||
8916 | static int FAST_FUNC builtin_pwd(char **argv UNUSED_PARAM) | ||
8917 | { | ||
8918 | puts(get_cwd(0)); | ||
8919 | return EXIT_SUCCESS; | ||
8920 | } | ||
8921 | |||
8922 | static int FAST_FUNC builtin_eval(char **argv) | ||
8923 | { | ||
8924 | int rcode = EXIT_SUCCESS; | ||
8925 | |||
8926 | argv = skip_dash_dash(argv); | ||
8927 | if (*argv) { | ||
8928 | char *str = expand_strvec_to_string(argv); | ||
8929 | /* bash: | ||
8930 | * eval "echo Hi; done" ("done" is syntax error): | ||
8931 | * "echo Hi" will not execute too. | ||
8932 | */ | ||
8933 | parse_and_run_string(str); | ||
8934 | free(str); | ||
8935 | rcode = G.last_exitcode; | ||
8936 | } | ||
8937 | return rcode; | ||
8938 | } | ||
8939 | |||
8752 | static int FAST_FUNC builtin_exec(char **argv) | 8940 | static int FAST_FUNC builtin_exec(char **argv) |
8753 | { | 8941 | { |
8754 | argv = skip_dash_dash(argv); | 8942 | argv = skip_dash_dash(argv); |
@@ -8794,6 +8982,148 @@ static int FAST_FUNC builtin_exit(char **argv) | |||
8794 | hush_exit(xatoi(argv[0]) & 0xff); | 8982 | hush_exit(xatoi(argv[0]) & 0xff); |
8795 | } | 8983 | } |
8796 | 8984 | ||
8985 | #if ENABLE_HUSH_TYPE | ||
8986 | /* http://www.opengroup.org/onlinepubs/9699919799/utilities/type.html */ | ||
8987 | static int FAST_FUNC builtin_type(char **argv) | ||
8988 | { | ||
8989 | int ret = EXIT_SUCCESS; | ||
8990 | |||
8991 | while (*++argv) { | ||
8992 | const char *type; | ||
8993 | char *path = NULL; | ||
8994 | |||
8995 | if (0) {} /* make conditional compile easier below */ | ||
8996 | /*else if (find_alias(*argv)) | ||
8997 | type = "an alias";*/ | ||
8998 | #if ENABLE_HUSH_FUNCTIONS | ||
8999 | else if (find_function(*argv)) | ||
9000 | type = "a function"; | ||
9001 | #endif | ||
9002 | else if (find_builtin(*argv)) | ||
9003 | type = "a shell builtin"; | ||
9004 | else if ((path = find_in_path(*argv)) != NULL) | ||
9005 | type = path; | ||
9006 | else { | ||
9007 | bb_error_msg("type: %s: not found", *argv); | ||
9008 | ret = EXIT_FAILURE; | ||
9009 | continue; | ||
9010 | } | ||
9011 | |||
9012 | printf("%s is %s\n", *argv, type); | ||
9013 | free(path); | ||
9014 | } | ||
9015 | |||
9016 | return ret; | ||
9017 | } | ||
9018 | #endif | ||
9019 | |||
9020 | #if ENABLE_HUSH_READ | ||
9021 | /* Interruptibility of read builtin in bash | ||
9022 | * (tested on bash-4.2.8 by sending signals (not by ^C)): | ||
9023 | * | ||
9024 | * Empty trap makes read ignore corresponding signal, for any signal. | ||
9025 | * | ||
9026 | * SIGINT: | ||
9027 | * - terminates non-interactive shell; | ||
9028 | * - interrupts read in interactive shell; | ||
9029 | * if it has non-empty trap: | ||
9030 | * - executes trap and returns to command prompt in interactive shell; | ||
9031 | * - executes trap and returns to read in non-interactive shell; | ||
9032 | * SIGTERM: | ||
9033 | * - is ignored (does not interrupt) read in interactive shell; | ||
9034 | * - terminates non-interactive shell; | ||
9035 | * if it has non-empty trap: | ||
9036 | * - executes trap and returns to read; | ||
9037 | * SIGHUP: | ||
9038 | * - terminates shell (regardless of interactivity); | ||
9039 | * if it has non-empty trap: | ||
9040 | * - executes trap and returns to read; | ||
9041 | */ | ||
9042 | static int FAST_FUNC builtin_read(char **argv) | ||
9043 | { | ||
9044 | const char *r; | ||
9045 | char *opt_n = NULL; | ||
9046 | char *opt_p = NULL; | ||
9047 | char *opt_t = NULL; | ||
9048 | char *opt_u = NULL; | ||
9049 | const char *ifs; | ||
9050 | int read_flags; | ||
9051 | |||
9052 | /* "!": do not abort on errors. | ||
9053 | * Option string must start with "sr" to match BUILTIN_READ_xxx | ||
9054 | */ | ||
9055 | read_flags = getopt32(argv, "!srn:p:t:u:", &opt_n, &opt_p, &opt_t, &opt_u); | ||
9056 | if (read_flags == (uint32_t)-1) | ||
9057 | return EXIT_FAILURE; | ||
9058 | argv += optind; | ||
9059 | ifs = get_local_var_value("IFS"); /* can be NULL */ | ||
9060 | |||
9061 | again: | ||
9062 | r = shell_builtin_read(set_local_var_from_halves, | ||
9063 | argv, | ||
9064 | ifs, | ||
9065 | read_flags, | ||
9066 | opt_n, | ||
9067 | opt_p, | ||
9068 | opt_t, | ||
9069 | opt_u | ||
9070 | ); | ||
9071 | |||
9072 | if ((uintptr_t)r == 1 && errno == EINTR) { | ||
9073 | unsigned sig = check_and_run_traps(); | ||
9074 | if (sig && sig != SIGINT) | ||
9075 | goto again; | ||
9076 | } | ||
9077 | |||
9078 | if ((uintptr_t)r > 1) { | ||
9079 | bb_error_msg("%s", r); | ||
9080 | r = (char*)(uintptr_t)1; | ||
9081 | } | ||
9082 | |||
9083 | return (uintptr_t)r; | ||
9084 | } | ||
9085 | #endif | ||
9086 | |||
9087 | #if ENABLE_HUSH_UMASK | ||
9088 | static int FAST_FUNC builtin_umask(char **argv) | ||
9089 | { | ||
9090 | int rc; | ||
9091 | mode_t mask; | ||
9092 | |||
9093 | rc = 1; | ||
9094 | mask = umask(0); | ||
9095 | argv = skip_dash_dash(argv); | ||
9096 | if (argv[0]) { | ||
9097 | mode_t old_mask = mask; | ||
9098 | |||
9099 | /* numeric umasks are taken as-is */ | ||
9100 | /* symbolic umasks are inverted: "umask a=rx" calls umask(222) */ | ||
9101 | if (!isdigit(argv[0][0])) | ||
9102 | mask ^= 0777; | ||
9103 | mask = bb_parse_mode(argv[0], mask); | ||
9104 | if (!isdigit(argv[0][0])) | ||
9105 | mask ^= 0777; | ||
9106 | if ((unsigned)mask > 0777) { | ||
9107 | mask = old_mask; | ||
9108 | /* bash messages: | ||
9109 | * bash: umask: 'q': invalid symbolic mode operator | ||
9110 | * bash: umask: 999: octal number out of range | ||
9111 | */ | ||
9112 | bb_error_msg("%s: invalid mode '%s'", "umask", argv[0]); | ||
9113 | rc = 0; | ||
9114 | } | ||
9115 | } else { | ||
9116 | /* Mimic bash */ | ||
9117 | printf("%04o\n", (unsigned) mask); | ||
9118 | /* fall through and restore mask which we set to 0 */ | ||
9119 | } | ||
9120 | umask(mask); | ||
9121 | |||
9122 | return !rc; /* rc != 0 - success */ | ||
9123 | } | ||
9124 | #endif | ||
9125 | |||
9126 | #if ENABLE_HUSH_EXPORT || ENABLE_HUSH_TRAP | ||
8797 | static void print_escaped(const char *s) | 9127 | static void print_escaped(const char *s) |
8798 | { | 9128 | { |
8799 | if (*s == '\'') | 9129 | if (*s == '\'') |
@@ -8812,11 +9142,13 @@ static void print_escaped(const char *s) | |||
8812 | putchar('"'); | 9142 | putchar('"'); |
8813 | } while (*s); | 9143 | } while (*s); |
8814 | } | 9144 | } |
9145 | #endif | ||
8815 | 9146 | ||
8816 | #if !ENABLE_HUSH_LOCAL | 9147 | #if ENABLE_HUSH_EXPORT || ENABLE_HUSH_LOCAL |
9148 | # if !ENABLE_HUSH_LOCAL | ||
8817 | #define helper_export_local(argv, exp, lvl) \ | 9149 | #define helper_export_local(argv, exp, lvl) \ |
8818 | helper_export_local(argv, exp) | 9150 | helper_export_local(argv, exp) |
8819 | #endif | 9151 | # endif |
8820 | static void helper_export_local(char **argv, int exp, int lvl) | 9152 | static void helper_export_local(char **argv, int exp, int lvl) |
8821 | { | 9153 | { |
8822 | do { | 9154 | do { |
@@ -8849,14 +9181,14 @@ static void helper_export_local(char **argv, int exp, int lvl) | |||
8849 | continue; | 9181 | continue; |
8850 | } | 9182 | } |
8851 | } | 9183 | } |
8852 | #if ENABLE_HUSH_LOCAL | 9184 | # if ENABLE_HUSH_LOCAL |
8853 | if (exp == 0 /* local? */ | 9185 | if (exp == 0 /* local? */ |
8854 | && var && var->func_nest_level == lvl | 9186 | && var && var->func_nest_level == lvl |
8855 | ) { | 9187 | ) { |
8856 | /* "local x=abc; ...; local x" - ignore second local decl */ | 9188 | /* "local x=abc; ...; local x" - ignore second local decl */ |
8857 | continue; | 9189 | continue; |
8858 | } | 9190 | } |
8859 | #endif | 9191 | # endif |
8860 | /* Exporting non-existing variable. | 9192 | /* Exporting non-existing variable. |
8861 | * bash does not put it in environment, | 9193 | * bash does not put it in environment, |
8862 | * but remembers that it is exported, | 9194 | * but remembers that it is exported, |
@@ -8872,7 +9204,9 @@ static void helper_export_local(char **argv, int exp, int lvl) | |||
8872 | set_local_var(name, /*exp:*/ exp, /*lvl:*/ lvl, /*ro:*/ 0); | 9204 | set_local_var(name, /*exp:*/ exp, /*lvl:*/ lvl, /*ro:*/ 0); |
8873 | } while (*++argv); | 9205 | } while (*++argv); |
8874 | } | 9206 | } |
9207 | #endif | ||
8875 | 9208 | ||
9209 | #if ENABLE_HUSH_EXPORT | ||
8876 | static int FAST_FUNC builtin_export(char **argv) | 9210 | static int FAST_FUNC builtin_export(char **argv) |
8877 | { | 9211 | { |
8878 | unsigned opt_unexport; | 9212 | unsigned opt_unexport; |
@@ -8918,6 +9252,7 @@ static int FAST_FUNC builtin_export(char **argv) | |||
8918 | 9252 | ||
8919 | return EXIT_SUCCESS; | 9253 | return EXIT_SUCCESS; |
8920 | } | 9254 | } |
9255 | #endif | ||
8921 | 9256 | ||
8922 | #if ENABLE_HUSH_LOCAL | 9257 | #if ENABLE_HUSH_LOCAL |
8923 | static int FAST_FUNC builtin_local(char **argv) | 9258 | static int FAST_FUNC builtin_local(char **argv) |
@@ -8931,6 +9266,7 @@ static int FAST_FUNC builtin_local(char **argv) | |||
8931 | } | 9266 | } |
8932 | #endif | 9267 | #endif |
8933 | 9268 | ||
9269 | #if ENABLE_HUSH_UNSET | ||
8934 | /* http://www.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#unset */ | 9270 | /* http://www.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#unset */ |
8935 | static int FAST_FUNC builtin_unset(char **argv) | 9271 | static int FAST_FUNC builtin_unset(char **argv) |
8936 | { | 9272 | { |
@@ -8958,16 +9294,18 @@ static int FAST_FUNC builtin_unset(char **argv) | |||
8958 | ret = EXIT_FAILURE; | 9294 | ret = EXIT_FAILURE; |
8959 | } | 9295 | } |
8960 | } | 9296 | } |
8961 | #if ENABLE_HUSH_FUNCTIONS | 9297 | # if ENABLE_HUSH_FUNCTIONS |
8962 | else { | 9298 | else { |
8963 | unset_func(*argv); | 9299 | unset_func(*argv); |
8964 | } | 9300 | } |
8965 | #endif | 9301 | # endif |
8966 | argv++; | 9302 | argv++; |
8967 | } | 9303 | } |
8968 | return ret; | 9304 | return ret; |
8969 | } | 9305 | } |
9306 | #endif | ||
8970 | 9307 | ||
9308 | #if ENABLE_HUSH_SET | ||
8971 | /* http://www.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#set | 9309 | /* http://www.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#set |
8972 | * built-in 'set' handler | 9310 | * built-in 'set' handler |
8973 | * SUSv3 says: | 9311 | * SUSv3 says: |
@@ -9050,6 +9388,7 @@ static int FAST_FUNC builtin_set(char **argv) | |||
9050 | bb_error_msg("set: %s: invalid option", arg); | 9388 | bb_error_msg("set: %s: invalid option", arg); |
9051 | return EXIT_FAILURE; | 9389 | return EXIT_FAILURE; |
9052 | } | 9390 | } |
9391 | #endif | ||
9053 | 9392 | ||
9054 | static int FAST_FUNC builtin_shift(char **argv) | 9393 | static int FAST_FUNC builtin_shift(char **argv) |
9055 | { | 9394 | { |
@@ -9059,7 +9398,7 @@ static int FAST_FUNC builtin_shift(char **argv) | |||
9059 | n = atoi(argv[0]); | 9398 | n = atoi(argv[0]); |
9060 | } | 9399 | } |
9061 | if (n >= 0 && n < G.global_argc) { | 9400 | if (n >= 0 && n < G.global_argc) { |
9062 | if (G.global_args_malloced) { | 9401 | if (G_global_args_malloced) { |
9063 | int m = 1; | 9402 | int m = 1; |
9064 | while (m <= n) | 9403 | while (m <= n) |
9065 | free(G.global_argv[m++]); | 9404 | free(G.global_argv[m++]); |
@@ -9072,87 +9411,78 @@ static int FAST_FUNC builtin_shift(char **argv) | |||
9072 | return EXIT_FAILURE; | 9411 | return EXIT_FAILURE; |
9073 | } | 9412 | } |
9074 | 9413 | ||
9075 | /* Interruptibility of read builtin in bash | 9414 | static int FAST_FUNC builtin_source(char **argv) |
9076 | * (tested on bash-4.2.8 by sending signals (not by ^C)): | ||
9077 | * | ||
9078 | * Empty trap makes read ignore corresponding signal, for any signal. | ||
9079 | * | ||
9080 | * SIGINT: | ||
9081 | * - terminates non-interactive shell; | ||
9082 | * - interrupts read in interactive shell; | ||
9083 | * if it has non-empty trap: | ||
9084 | * - executes trap and returns to command prompt in interactive shell; | ||
9085 | * - executes trap and returns to read in non-interactive shell; | ||
9086 | * SIGTERM: | ||
9087 | * - is ignored (does not interrupt) read in interactive shell; | ||
9088 | * - terminates non-interactive shell; | ||
9089 | * if it has non-empty trap: | ||
9090 | * - executes trap and returns to read; | ||
9091 | * SIGHUP: | ||
9092 | * - terminates shell (regardless of interactivity); | ||
9093 | * if it has non-empty trap: | ||
9094 | * - executes trap and returns to read; | ||
9095 | */ | ||
9096 | static int FAST_FUNC builtin_read(char **argv) | ||
9097 | { | 9415 | { |
9098 | const char *r; | 9416 | char *arg_path, *filename; |
9099 | char *opt_n = NULL; | 9417 | FILE *input; |
9100 | char *opt_p = NULL; | 9418 | save_arg_t sv; |
9101 | char *opt_t = NULL; | 9419 | char *args_need_save; |
9102 | char *opt_u = NULL; | 9420 | #if ENABLE_HUSH_FUNCTIONS |
9103 | const char *ifs; | 9421 | smallint sv_flg; |
9104 | int read_flags; | 9422 | #endif |
9105 | 9423 | ||
9106 | /* "!": do not abort on errors. | 9424 | argv = skip_dash_dash(argv); |
9107 | * Option string must start with "sr" to match BUILTIN_READ_xxx | 9425 | filename = argv[0]; |
9108 | */ | 9426 | if (!filename) { |
9109 | read_flags = getopt32(argv, "!srn:p:t:u:", &opt_n, &opt_p, &opt_t, &opt_u); | 9427 | /* bash says: "bash: .: filename argument required" */ |
9110 | if (read_flags == (uint32_t)-1) | 9428 | return 2; /* bash compat */ |
9429 | } | ||
9430 | arg_path = NULL; | ||
9431 | if (!strchr(filename, '/')) { | ||
9432 | arg_path = find_in_path(filename); | ||
9433 | if (arg_path) | ||
9434 | filename = arg_path; | ||
9435 | } | ||
9436 | input = remember_FILE(fopen_or_warn(filename, "r")); | ||
9437 | free(arg_path); | ||
9438 | if (!input) { | ||
9439 | /* bb_perror_msg("%s", *argv); - done by fopen_or_warn */ | ||
9440 | /* POSIX: non-interactive shell should abort here, | ||
9441 | * not merely fail. So far no one complained :) | ||
9442 | */ | ||
9111 | return EXIT_FAILURE; | 9443 | return EXIT_FAILURE; |
9112 | argv += optind; | 9444 | } |
9113 | ifs = get_local_var_value("IFS"); /* can be NULL */ | ||
9114 | 9445 | ||
9115 | again: | 9446 | #if ENABLE_HUSH_FUNCTIONS |
9116 | r = shell_builtin_read(set_local_var_from_halves, | 9447 | sv_flg = G_flag_return_in_progress; |
9117 | argv, | 9448 | /* "we are inside sourced file, ok to use return" */ |
9118 | ifs, | 9449 | G_flag_return_in_progress = -1; |
9119 | read_flags, | 9450 | #endif |
9120 | opt_n, | 9451 | args_need_save = argv[1]; /* used as a boolean variable */ |
9121 | opt_p, | 9452 | if (args_need_save) |
9122 | opt_t, | 9453 | save_and_replace_G_args(&sv, argv); |
9123 | opt_u | ||
9124 | ); | ||
9125 | 9454 | ||
9126 | if ((uintptr_t)r == 1 && errno == EINTR) { | 9455 | /* "false; . ./empty_line; echo Zero:$?" should print 0 */ |
9127 | unsigned sig = check_and_run_traps(); | 9456 | G.last_exitcode = 0; |
9128 | if (sig && sig != SIGINT) | 9457 | parse_and_run_file(input); |
9129 | goto again; | 9458 | fclose_and_forget(input); |
9130 | } | ||
9131 | 9459 | ||
9132 | if ((uintptr_t)r > 1) { | 9460 | if (args_need_save) /* can't use argv[1] instead: "shift" can mangle it */ |
9133 | bb_error_msg("%s", r); | 9461 | restore_G_args(&sv, argv); |
9134 | r = (char*)(uintptr_t)1; | 9462 | #if ENABLE_HUSH_FUNCTIONS |
9135 | } | 9463 | G_flag_return_in_progress = sv_flg; |
9464 | #endif | ||
9136 | 9465 | ||
9137 | return (uintptr_t)r; | 9466 | return G.last_exitcode; |
9138 | } | 9467 | } |
9139 | 9468 | ||
9469 | #if ENABLE_HUSH_TRAP | ||
9140 | static int FAST_FUNC builtin_trap(char **argv) | 9470 | static int FAST_FUNC builtin_trap(char **argv) |
9141 | { | 9471 | { |
9142 | int sig; | 9472 | int sig; |
9143 | char *new_cmd; | 9473 | char *new_cmd; |
9144 | 9474 | ||
9145 | if (!G.traps) | 9475 | if (!G_traps) |
9146 | G.traps = xzalloc(sizeof(G.traps[0]) * NSIG); | 9476 | G_traps = xzalloc(sizeof(G_traps[0]) * NSIG); |
9147 | 9477 | ||
9148 | argv++; | 9478 | argv++; |
9149 | if (!*argv) { | 9479 | if (!*argv) { |
9150 | int i; | 9480 | int i; |
9151 | /* No args: print all trapped */ | 9481 | /* No args: print all trapped */ |
9152 | for (i = 0; i < NSIG; ++i) { | 9482 | for (i = 0; i < NSIG; ++i) { |
9153 | if (G.traps[i]) { | 9483 | if (G_traps[i]) { |
9154 | printf("trap -- "); | 9484 | printf("trap -- "); |
9155 | print_escaped(G.traps[i]); | 9485 | print_escaped(G_traps[i]); |
9156 | /* note: bash adds "SIG", but only if invoked | 9486 | /* note: bash adds "SIG", but only if invoked |
9157 | * as "bash". If called as "sh", or if set -o posix, | 9487 | * as "bash". If called as "sh", or if set -o posix, |
9158 | * then it prints short signal names. | 9488 | * then it prints short signal names. |
@@ -9182,11 +9512,11 @@ static int FAST_FUNC builtin_trap(char **argv) | |||
9182 | continue; | 9512 | continue; |
9183 | } | 9513 | } |
9184 | 9514 | ||
9185 | free(G.traps[sig]); | 9515 | free(G_traps[sig]); |
9186 | G.traps[sig] = xstrdup(new_cmd); | 9516 | G_traps[sig] = xstrdup(new_cmd); |
9187 | 9517 | ||
9188 | debug_printf("trap: setting SIG%s (%i) to '%s'\n", | 9518 | debug_printf("trap: setting SIG%s (%i) to '%s'\n", |
9189 | get_signame(sig), sig, G.traps[sig]); | 9519 | get_signame(sig), sig, G_traps[sig]); |
9190 | 9520 | ||
9191 | /* There is no signal for 0 (EXIT) */ | 9521 | /* There is no signal for 0 (EXIT) */ |
9192 | if (sig == 0) | 9522 | if (sig == 0) |
@@ -9226,59 +9556,54 @@ static int FAST_FUNC builtin_trap(char **argv) | |||
9226 | argv++; | 9556 | argv++; |
9227 | goto process_sig_list; | 9557 | goto process_sig_list; |
9228 | } | 9558 | } |
9229 | |||
9230 | /* http://www.opengroup.org/onlinepubs/9699919799/utilities/type.html */ | ||
9231 | static int FAST_FUNC builtin_type(char **argv) | ||
9232 | { | ||
9233 | int ret = EXIT_SUCCESS; | ||
9234 | |||
9235 | while (*++argv) { | ||
9236 | const char *type; | ||
9237 | char *path = NULL; | ||
9238 | |||
9239 | if (0) {} /* make conditional compile easier below */ | ||
9240 | /*else if (find_alias(*argv)) | ||
9241 | type = "an alias";*/ | ||
9242 | #if ENABLE_HUSH_FUNCTIONS | ||
9243 | else if (find_function(*argv)) | ||
9244 | type = "a function"; | ||
9245 | #endif | 9559 | #endif |
9246 | else if (find_builtin(*argv)) | ||
9247 | type = "a shell builtin"; | ||
9248 | else if ((path = find_in_path(*argv)) != NULL) | ||
9249 | type = path; | ||
9250 | else { | ||
9251 | bb_error_msg("type: %s: not found", *argv); | ||
9252 | ret = EXIT_FAILURE; | ||
9253 | continue; | ||
9254 | } | ||
9255 | |||
9256 | printf("%s is %s\n", *argv, type); | ||
9257 | free(path); | ||
9258 | } | ||
9259 | |||
9260 | return ret; | ||
9261 | } | ||
9262 | 9560 | ||
9263 | #if ENABLE_HUSH_JOB | 9561 | #if ENABLE_HUSH_JOB |
9264 | static struct pipe *parse_jobspec(const char *str) | 9562 | static struct pipe *parse_jobspec(const char *str) |
9265 | { | 9563 | { |
9266 | struct pipe *pi; | 9564 | struct pipe *pi; |
9267 | int jobnum; | 9565 | unsigned jobnum; |
9268 | 9566 | ||
9269 | if (sscanf(str, "%%%d", &jobnum) != 1) { | 9567 | if (sscanf(str, "%%%u", &jobnum) != 1) { |
9270 | bb_error_msg("bad argument '%s'", str); | 9568 | if (str[0] != '%' |
9271 | return NULL; | 9569 | || (str[1] != '%' && str[1] != '+' && str[1] != '\0') |
9570 | ) { | ||
9571 | bb_error_msg("bad argument '%s'", str); | ||
9572 | return NULL; | ||
9573 | } | ||
9574 | /* It is "%%", "%+" or "%" - current job */ | ||
9575 | jobnum = G.last_jobid; | ||
9576 | if (jobnum == 0) { | ||
9577 | bb_error_msg("no current job"); | ||
9578 | return NULL; | ||
9579 | } | ||
9272 | } | 9580 | } |
9273 | for (pi = G.job_list; pi; pi = pi->next) { | 9581 | for (pi = G.job_list; pi; pi = pi->next) { |
9274 | if (pi->jobid == jobnum) { | 9582 | if (pi->jobid == jobnum) { |
9275 | return pi; | 9583 | return pi; |
9276 | } | 9584 | } |
9277 | } | 9585 | } |
9278 | bb_error_msg("%d: no such job", jobnum); | 9586 | bb_error_msg("%u: no such job", jobnum); |
9279 | return NULL; | 9587 | return NULL; |
9280 | } | 9588 | } |
9281 | 9589 | ||
9590 | static int FAST_FUNC builtin_jobs(char **argv UNUSED_PARAM) | ||
9591 | { | ||
9592 | struct pipe *job; | ||
9593 | const char *status_string; | ||
9594 | |||
9595 | checkjobs(NULL, 0 /*(no pid to wait for)*/); | ||
9596 | for (job = G.job_list; job; job = job->next) { | ||
9597 | if (job->alive_cmds == job->stopped_cmds) | ||
9598 | status_string = "Stopped"; | ||
9599 | else | ||
9600 | status_string = "Running"; | ||
9601 | |||
9602 | printf(JOB_STATUS_FORMAT, job->jobid, status_string, job->cmdtext); | ||
9603 | } | ||
9604 | return EXIT_SUCCESS; | ||
9605 | } | ||
9606 | |||
9282 | /* built-in 'fg' and 'bg' handler */ | 9607 | /* built-in 'fg' and 'bg' handler */ |
9283 | static int FAST_FUNC builtin_fg_bg(char **argv) | 9608 | static int FAST_FUNC builtin_fg_bg(char **argv) |
9284 | { | 9609 | { |
@@ -9334,188 +9659,81 @@ static int FAST_FUNC builtin_fg_bg(char **argv) | |||
9334 | } | 9659 | } |
9335 | #endif | 9660 | #endif |
9336 | 9661 | ||
9337 | #if ENABLE_HUSH_HELP | 9662 | #if ENABLE_HUSH_KILL |
9338 | static int FAST_FUNC builtin_help(char **argv UNUSED_PARAM) | 9663 | static int FAST_FUNC builtin_kill(char **argv) |
9339 | { | ||
9340 | const struct built_in_command *x; | ||
9341 | |||
9342 | printf( | ||
9343 | "Built-in commands:\n" | ||
9344 | "------------------\n"); | ||
9345 | for (x = bltins1; x != &bltins1[ARRAY_SIZE(bltins1)]; x++) { | ||
9346 | if (x->b_descr) | ||
9347 | printf("%-10s%s\n", x->b_cmd, x->b_descr); | ||
9348 | } | ||
9349 | return EXIT_SUCCESS; | ||
9350 | } | ||
9351 | #endif | ||
9352 | |||
9353 | #if MAX_HISTORY && ENABLE_FEATURE_EDITING | ||
9354 | static int FAST_FUNC builtin_history(char **argv UNUSED_PARAM) | ||
9355 | { | 9664 | { |
9356 | show_history(G.line_input_state); | 9665 | int ret = 0; |
9357 | return EXIT_SUCCESS; | ||
9358 | } | ||
9359 | #endif | ||
9360 | 9666 | ||
9361 | #if ENABLE_HUSH_JOB | 9667 | # if ENABLE_HUSH_JOB |
9362 | static int FAST_FUNC builtin_jobs(char **argv UNUSED_PARAM) | 9668 | if (argv[1] && strcmp(argv[1], "-l") != 0) { |
9363 | { | 9669 | int i = 1; |
9364 | struct pipe *job; | ||
9365 | const char *status_string; | ||
9366 | 9670 | ||
9367 | checkjobs(NULL, 0 /*(no pid to wait for)*/); | 9671 | do { |
9368 | for (job = G.job_list; job; job = job->next) { | 9672 | struct pipe *pi; |
9369 | if (job->alive_cmds == job->stopped_cmds) | 9673 | char *dst; |
9370 | status_string = "Stopped"; | 9674 | int j, n; |
9371 | else | ||
9372 | status_string = "Running"; | ||
9373 | 9675 | ||
9374 | printf(JOB_STATUS_FORMAT, job->jobid, status_string, job->cmdtext); | 9676 | if (argv[i][0] != '%') |
9677 | continue; | ||
9678 | /* | ||
9679 | * "kill %N" - job kill | ||
9680 | * Converting to pgrp / pid kill | ||
9681 | */ | ||
9682 | pi = parse_jobspec(argv[i]); | ||
9683 | if (!pi) { | ||
9684 | /* Eat bad jobspec */ | ||
9685 | j = i; | ||
9686 | do { | ||
9687 | j++; | ||
9688 | argv[j - 1] = argv[j]; | ||
9689 | } while (argv[j]); | ||
9690 | ret = 1; | ||
9691 | i--; | ||
9692 | continue; | ||
9693 | } | ||
9694 | /* | ||
9695 | * In jobs started under job control, we signal | ||
9696 | * entire process group by kill -PGRP_ID. | ||
9697 | * This happens, f.e., in interactive shell. | ||
9698 | * | ||
9699 | * Otherwise, we signal each child via | ||
9700 | * kill PID1 PID2 PID3. | ||
9701 | * Testcases: | ||
9702 | * sh -c 'sleep 1|sleep 1 & kill %1' | ||
9703 | * sh -c 'true|sleep 2 & sleep 1; kill %1' | ||
9704 | * sh -c 'true|sleep 1 & sleep 2; kill %1' | ||
9705 | */ | ||
9706 | n = G_interactive_fd ? 1 : pi->num_cmds; | ||
9707 | dst = alloca(n * sizeof(int)*4); | ||
9708 | argv[i] = dst; | ||
9709 | if (G_interactive_fd) | ||
9710 | dst += sprintf(dst, " -%u", (int)pi->pgrp); | ||
9711 | else for (j = 0; j < n; j++) { | ||
9712 | struct command *cmd = &pi->cmds[j]; | ||
9713 | /* Skip exited members of the job */ | ||
9714 | if (cmd->pid == 0) | ||
9715 | continue; | ||
9716 | /* | ||
9717 | * kill_main has matching code to expect | ||
9718 | * leading space. Needed to not confuse | ||
9719 | * negative pids with "kill -SIGNAL_NO" syntax | ||
9720 | */ | ||
9721 | dst += sprintf(dst, " %u", (int)cmd->pid); | ||
9722 | } | ||
9723 | *dst = '\0'; | ||
9724 | } while (argv[++i]); | ||
9375 | } | 9725 | } |
9376 | return EXIT_SUCCESS; | ||
9377 | } | ||
9378 | #endif | ||
9379 | |||
9380 | #if HUSH_DEBUG | ||
9381 | static int FAST_FUNC builtin_memleak(char **argv UNUSED_PARAM) | ||
9382 | { | ||
9383 | void *p; | ||
9384 | unsigned long l; | ||
9385 | |||
9386 | # ifdef M_TRIM_THRESHOLD | ||
9387 | /* Optional. Reduces probability of false positives */ | ||
9388 | malloc_trim(0); | ||
9389 | # endif | 9726 | # endif |
9390 | /* Crude attempt to find where "free memory" starts, | ||
9391 | * sans fragmentation. */ | ||
9392 | p = malloc(240); | ||
9393 | l = (unsigned long)p; | ||
9394 | free(p); | ||
9395 | p = malloc(3400); | ||
9396 | if (l < (unsigned long)p) l = (unsigned long)p; | ||
9397 | free(p); | ||
9398 | 9727 | ||
9399 | 9728 | if (argv[1] || ret == 0) { | |
9400 | # if 0 /* debug */ | 9729 | ret = run_applet_main(argv, kill_main); |
9401 | { | ||
9402 | struct mallinfo mi = mallinfo(); | ||
9403 | printf("top alloc:0x%lx malloced:%d+%d=%d\n", l, | ||
9404 | mi.arena, mi.hblkhd, mi.arena + mi.hblkhd); | ||
9405 | } | 9730 | } |
9406 | # endif | 9731 | /* else: ret = 1, "kill %bad_jobspec" case */ |
9407 | 9732 | return ret; | |
9408 | if (!G.memleak_value) | ||
9409 | G.memleak_value = l; | ||
9410 | |||
9411 | l -= G.memleak_value; | ||
9412 | if ((long)l < 0) | ||
9413 | l = 0; | ||
9414 | l /= 1024; | ||
9415 | if (l > 127) | ||
9416 | l = 127; | ||
9417 | |||
9418 | /* Exitcode is "how many kilobytes we leaked since 1st call" */ | ||
9419 | return l; | ||
9420 | } | ||
9421 | #endif | ||
9422 | |||
9423 | static int FAST_FUNC builtin_pwd(char **argv UNUSED_PARAM) | ||
9424 | { | ||
9425 | puts(get_cwd(0)); | ||
9426 | return EXIT_SUCCESS; | ||
9427 | } | 9733 | } |
9428 | |||
9429 | static int FAST_FUNC builtin_source(char **argv) | ||
9430 | { | ||
9431 | char *arg_path, *filename; | ||
9432 | FILE *input; | ||
9433 | save_arg_t sv; | ||
9434 | #if ENABLE_HUSH_FUNCTIONS | ||
9435 | smallint sv_flg; | ||
9436 | #endif | ||
9437 | |||
9438 | argv = skip_dash_dash(argv); | ||
9439 | filename = argv[0]; | ||
9440 | if (!filename) { | ||
9441 | /* bash says: "bash: .: filename argument required" */ | ||
9442 | return 2; /* bash compat */ | ||
9443 | } | ||
9444 | arg_path = NULL; | ||
9445 | if (!strchr(filename, '/')) { | ||
9446 | arg_path = find_in_path(filename); | ||
9447 | if (arg_path) | ||
9448 | filename = arg_path; | ||
9449 | } | ||
9450 | input = remember_FILE(fopen_or_warn(filename, "r")); | ||
9451 | free(arg_path); | ||
9452 | if (!input) { | ||
9453 | /* bb_perror_msg("%s", *argv); - done by fopen_or_warn */ | ||
9454 | /* POSIX: non-interactive shell should abort here, | ||
9455 | * not merely fail. So far no one complained :) | ||
9456 | */ | ||
9457 | return EXIT_FAILURE; | ||
9458 | } | ||
9459 | |||
9460 | #if ENABLE_HUSH_FUNCTIONS | ||
9461 | sv_flg = G_flag_return_in_progress; | ||
9462 | /* "we are inside sourced file, ok to use return" */ | ||
9463 | G_flag_return_in_progress = -1; | ||
9464 | #endif | 9734 | #endif |
9465 | if (argv[1]) | ||
9466 | save_and_replace_G_args(&sv, argv); | ||
9467 | |||
9468 | /* "false; . ./empty_line; echo Zero:$?" should print 0 */ | ||
9469 | G.last_exitcode = 0; | ||
9470 | parse_and_run_file(input); | ||
9471 | fclose_and_forget(input); | ||
9472 | |||
9473 | if (argv[1]) | ||
9474 | restore_G_args(&sv, argv); | ||
9475 | #if ENABLE_HUSH_FUNCTIONS | ||
9476 | G_flag_return_in_progress = sv_flg; | ||
9477 | #endif | ||
9478 | |||
9479 | return G.last_exitcode; | ||
9480 | } | ||
9481 | |||
9482 | static int FAST_FUNC builtin_umask(char **argv) | ||
9483 | { | ||
9484 | int rc; | ||
9485 | mode_t mask; | ||
9486 | |||
9487 | rc = 1; | ||
9488 | mask = umask(0); | ||
9489 | argv = skip_dash_dash(argv); | ||
9490 | if (argv[0]) { | ||
9491 | mode_t old_mask = mask; | ||
9492 | |||
9493 | /* numeric umasks are taken as-is */ | ||
9494 | /* symbolic umasks are inverted: "umask a=rx" calls umask(222) */ | ||
9495 | if (!isdigit(argv[0][0])) | ||
9496 | mask ^= 0777; | ||
9497 | mask = bb_parse_mode(argv[0], mask); | ||
9498 | if (!isdigit(argv[0][0])) | ||
9499 | mask ^= 0777; | ||
9500 | if ((unsigned)mask > 0777) { | ||
9501 | mask = old_mask; | ||
9502 | /* bash messages: | ||
9503 | * bash: umask: 'q': invalid symbolic mode operator | ||
9504 | * bash: umask: 999: octal number out of range | ||
9505 | */ | ||
9506 | bb_error_msg("%s: invalid mode '%s'", "umask", argv[0]); | ||
9507 | rc = 0; | ||
9508 | } | ||
9509 | } else { | ||
9510 | /* Mimic bash */ | ||
9511 | printf("%04o\n", (unsigned) mask); | ||
9512 | /* fall through and restore mask which we set to 0 */ | ||
9513 | } | ||
9514 | umask(mask); | ||
9515 | |||
9516 | return !rc; /* rc != 0 - success */ | ||
9517 | } | ||
9518 | 9735 | ||
9736 | #if ENABLE_HUSH_WAIT | ||
9519 | /* http://www.opengroup.org/onlinepubs/9699919799/utilities/wait.html */ | 9737 | /* http://www.opengroup.org/onlinepubs/9699919799/utilities/wait.html */ |
9520 | #if !ENABLE_HUSH_JOB | 9738 | #if !ENABLE_HUSH_JOB |
9521 | # define wait_for_child_or_signal(pipe,pid) wait_for_child_or_signal(pid) | 9739 | # define wait_for_child_or_signal(pipe,pid) wait_for_child_or_signal(pid) |
@@ -9622,13 +9840,15 @@ static int FAST_FUNC builtin_wait(char **argv) | |||
9622 | #if ENABLE_HUSH_JOB | 9840 | #if ENABLE_HUSH_JOB |
9623 | if (argv[0][0] == '%') { | 9841 | if (argv[0][0] == '%') { |
9624 | struct pipe *wait_pipe; | 9842 | struct pipe *wait_pipe; |
9843 | ret = 127; /* bash compat for bad jobspecs */ | ||
9625 | wait_pipe = parse_jobspec(*argv); | 9844 | wait_pipe = parse_jobspec(*argv); |
9626 | if (wait_pipe) { | 9845 | if (wait_pipe) { |
9627 | ret = job_exited_or_stopped(wait_pipe); | 9846 | ret = job_exited_or_stopped(wait_pipe); |
9628 | if (ret < 0) | 9847 | if (ret < 0) |
9629 | ret = wait_for_child_or_signal(wait_pipe, 0); | 9848 | ret = wait_for_child_or_signal(wait_pipe, 0); |
9630 | continue; | ||
9631 | } | 9849 | } |
9850 | /* else: parse_jobspec() already emitted error msg */ | ||
9851 | continue; | ||
9632 | } | 9852 | } |
9633 | #endif | 9853 | #endif |
9634 | /* mimic bash message */ | 9854 | /* mimic bash message */ |
@@ -9674,6 +9894,7 @@ static int FAST_FUNC builtin_wait(char **argv) | |||
9674 | 9894 | ||
9675 | return ret; | 9895 | return ret; |
9676 | } | 9896 | } |
9897 | #endif | ||
9677 | 9898 | ||
9678 | #if ENABLE_HUSH_LOOPS || ENABLE_HUSH_FUNCTIONS | 9899 | #if ENABLE_HUSH_LOOPS || ENABLE_HUSH_FUNCTIONS |
9679 | static unsigned parse_numeric_argv1(char **argv, unsigned def, unsigned def_min) | 9900 | static unsigned parse_numeric_argv1(char **argv, unsigned def, unsigned def_min) |
@@ -9740,3 +9961,46 @@ static int FAST_FUNC builtin_return(char **argv) | |||
9740 | return rc; | 9961 | return rc; |
9741 | } | 9962 | } |
9742 | #endif | 9963 | #endif |
9964 | |||
9965 | #if ENABLE_HUSH_MEMLEAK | ||
9966 | static int FAST_FUNC builtin_memleak(char **argv UNUSED_PARAM) | ||
9967 | { | ||
9968 | void *p; | ||
9969 | unsigned long l; | ||
9970 | |||
9971 | # ifdef M_TRIM_THRESHOLD | ||
9972 | /* Optional. Reduces probability of false positives */ | ||
9973 | malloc_trim(0); | ||
9974 | # endif | ||
9975 | /* Crude attempt to find where "free memory" starts, | ||
9976 | * sans fragmentation. */ | ||
9977 | p = malloc(240); | ||
9978 | l = (unsigned long)p; | ||
9979 | free(p); | ||
9980 | p = malloc(3400); | ||
9981 | if (l < (unsigned long)p) l = (unsigned long)p; | ||
9982 | free(p); | ||
9983 | |||
9984 | |||
9985 | # if 0 /* debug */ | ||
9986 | { | ||
9987 | struct mallinfo mi = mallinfo(); | ||
9988 | printf("top alloc:0x%lx malloced:%d+%d=%d\n", l, | ||
9989 | mi.arena, mi.hblkhd, mi.arena + mi.hblkhd); | ||
9990 | } | ||
9991 | # endif | ||
9992 | |||
9993 | if (!G.memleak_value) | ||
9994 | G.memleak_value = l; | ||
9995 | |||
9996 | l -= G.memleak_value; | ||
9997 | if ((long)l < 0) | ||
9998 | l = 0; | ||
9999 | l /= 1024; | ||
10000 | if (l > 127) | ||
10001 | l = 127; | ||
10002 | |||
10003 | /* Exitcode is "how many kilobytes we leaked since 1st call" */ | ||
10004 | return l; | ||
10005 | } | ||
10006 | #endif | ||
diff --git a/shell/hush_test/hush-misc/source_argv_and_shift.right b/shell/hush_test/hush-misc/source_argv_and_shift.right new file mode 100644 index 000000000..b15cc96e7 --- /dev/null +++ b/shell/hush_test/hush-misc/source_argv_and_shift.right | |||
@@ -0,0 +1,4 @@ | |||
1 | sourced_arg1:1 | ||
2 | arg1: | ||
3 | sourced_arg1:a | ||
4 | arg1:1 | ||
diff --git a/shell/hush_test/hush-misc/source_argv_and_shift.tests b/shell/hush_test/hush-misc/source_argv_and_shift.tests new file mode 100755 index 000000000..66353f3d7 --- /dev/null +++ b/shell/hush_test/hush-misc/source_argv_and_shift.tests | |||
@@ -0,0 +1,12 @@ | |||
1 | echo 'echo sourced_arg1:$1' >sourced1 | ||
2 | echo 'shift' >>sourced1 | ||
3 | |||
4 | set -- 1 | ||
5 | . ./sourced1 | ||
6 | echo arg1:$1 | ||
7 | |||
8 | set -- 1 | ||
9 | . ./sourced1 a | ||
10 | echo arg1:$1 | ||
11 | |||
12 | rm sourced1 | ||
diff --git a/shell/shell_common.c b/shell/shell_common.c index 5a5b1780d..653154e34 100644 --- a/shell/shell_common.c +++ b/shell/shell_common.c | |||
@@ -147,7 +147,7 @@ shell_builtin_read(void FAST_FUNC (*setvar)(const char *name, const char *val), | |||
147 | // Setting it to more than 1 breaks poll(): | 147 | // Setting it to more than 1 breaks poll(): |
148 | // it blocks even if there's data. !?? | 148 | // it blocks even if there's data. !?? |
149 | //tty.c_cc[VMIN] = nchars < 256 ? nchars : 255; | 149 | //tty.c_cc[VMIN] = nchars < 256 ? nchars : 255; |
150 | /* reads would block only if < 1 char is available */ | 150 | /* reads will block only if < 1 char is available */ |
151 | tty.c_cc[VMIN] = 1; | 151 | tty.c_cc[VMIN] = 1; |
152 | /* no timeout (reads block forever) */ | 152 | /* no timeout (reads block forever) */ |
153 | tty.c_cc[VTIME] = 0; | 153 | tty.c_cc[VTIME] = 0; |
diff --git a/sysklogd/syslogd.c b/sysklogd/syslogd.c index ae0840bff..d64ff278f 100644 --- a/sysklogd/syslogd.c +++ b/sysklogd/syslogd.c | |||
@@ -135,8 +135,8 @@ | |||
135 | //usage: ) | 135 | //usage: ) |
136 | //usage: "\n -O FILE Log to FILE (default: /var/log/messages, stdout if -)" | 136 | //usage: "\n -O FILE Log to FILE (default: /var/log/messages, stdout if -)" |
137 | //usage: IF_FEATURE_ROTATE_LOGFILE( | 137 | //usage: IF_FEATURE_ROTATE_LOGFILE( |
138 | //usage: "\n -s SIZE Max size (KB) before rotation (default:200KB, 0=off)" | 138 | //usage: "\n -s SIZE Max size (KB) before rotation (default 200KB, 0=off)" |
139 | //usage: "\n -b N N rotated logs to keep (default:1, max=99, 0=purge)" | 139 | //usage: "\n -b N N rotated logs to keep (default 1, max 99, 0=purge)" |
140 | //usage: ) | 140 | //usage: ) |
141 | //usage: "\n -l N Log only messages more urgent than prio N (1-8)" | 141 | //usage: "\n -l N Log only messages more urgent than prio N (1-8)" |
142 | //usage: "\n -S Smaller output" | 142 | //usage: "\n -S Smaller output" |
@@ -146,7 +146,7 @@ | |||
146 | //usage: IF_FEATURE_SYSLOGD_CFG( | 146 | //usage: IF_FEATURE_SYSLOGD_CFG( |
147 | //usage: "\n -f FILE Use FILE as config (default:/etc/syslog.conf)" | 147 | //usage: "\n -f FILE Use FILE as config (default:/etc/syslog.conf)" |
148 | //usage: ) | 148 | //usage: ) |
149 | /* //usage: "\n -m MIN Minutes between MARK lines (default:20, 0=off)" */ | 149 | /* //usage: "\n -m MIN Minutes between MARK lines (default 20, 0=off)" */ |
150 | //usage: | 150 | //usage: |
151 | //usage:#define syslogd_example_usage | 151 | //usage:#define syslogd_example_usage |
152 | //usage: "$ syslogd -R masterlog:514\n" | 152 | //usage: "$ syslogd -R masterlog:514\n" |
diff --git a/testsuite/cryptpw.tests b/testsuite/cryptpw.tests new file mode 100755 index 000000000..8ec476c9f --- /dev/null +++ b/testsuite/cryptpw.tests | |||
@@ -0,0 +1,28 @@ | |||
1 | #!/bin/sh | ||
2 | |||
3 | # Copyright 2017 by Denys Vlasenko <vda.linux@googlemail.com> | ||
4 | # Licensed under GPLv2, see file LICENSE in this source tree. | ||
5 | |||
6 | . ./testing.sh | ||
7 | |||
8 | # testing "description" "command" "result" "infile" "stdin" | ||
9 | |||
10 | optional USE_BB_CRYPT_SHA | ||
11 | testing "cryptpw sha256" \ | ||
12 | "cryptpw -m sha256 QWErty '123456789012345678901234567890'" \ | ||
13 | '$5$1234567890123456$5DxfOCmU4vRhtzfsbdK.6wSGMwwVbac7ZkWwusb8Si7\n' "" "" | ||
14 | |||
15 | testing "cryptpw sha256 rounds=99999" \ | ||
16 | "cryptpw -m sha256 QWErty 'rounds=99999\$123456789012345678901234567890'" \ | ||
17 | '$5$rounds=99999$1234567890123456$aYellycJGZM6AKyVzaQsSrDBdTixubtMnM6J.MN0xM8\n' "" "" | ||
18 | |||
19 | testing "cryptpw sha512" \ | ||
20 | "cryptpw -m sha512 QWErty '123456789012345678901234567890'" \ | ||
21 | '$6$1234567890123456$KB7QqxFyqmJSWyQYcCuGeFukgz1bPQoipWZf7.9L7z3k8UNTXa6UikbKcUGDc2ANn7DOGmDaroxDgpK16w/RE0\n' "" "" | ||
22 | |||
23 | testing "cryptpw sha512 rounds=99999" \ | ||
24 | "cryptpw -m sha512 QWErty 'rounds=99999\$123456789012345678901234567890'" \ | ||
25 | '$6$rounds=99999$1234567890123456$BfF6gD6ZjUmwawH5QaAglYAxtU./yvsz0fcQ464l49aMI2DZW3j5ri28CrxK7riPWNpLuUpfaIdY751SBYKUH.\n' "" "" | ||
26 | SKIP= | ||
27 | |||
28 | exit $FAILCOUNT | ||
diff --git a/testsuite/mdev.tests b/testsuite/mdev.tests index 59873011a..8515aff31 100755 --- a/testsuite/mdev.tests +++ b/testsuite/mdev.tests | |||
@@ -168,7 +168,7 @@ SKIP= | |||
168 | # continuing to use directory structure from prev test | 168 | # continuing to use directory structure from prev test |
169 | rm -rf mdev.testdir/dev/* | 169 | rm -rf mdev.testdir/dev/* |
170 | echo "sda 0:0 644 @echo @echo TEST" >mdev.testdir/etc/mdev.conf | 170 | echo "sda 0:0 644 @echo @echo TEST" >mdev.testdir/etc/mdev.conf |
171 | optional STATIC FEATURE_MDEV_CONF FEATURE_MDEV_EXEC FEATURE_LS_RECURSIVE FEATURE_LS_TIMESTAMPS FEATURE_LS_USERNAME FEATURE_SH_IS_ASH ASH_BUILTIN_ECHO | 171 | optional STATIC FEATURE_MDEV_CONF FEATURE_MDEV_EXEC FEATURE_LS_RECURSIVE FEATURE_LS_TIMESTAMPS FEATURE_LS_USERNAME FEATURE_SH_IS_ASH ASH_ECHO |
172 | testing "mdev command" \ | 172 | testing "mdev command" \ |
173 | "env - PATH=$PATH ACTION=add DEVPATH=/block/sda chroot mdev.testdir /mdev 2>&1; | 173 | "env - PATH=$PATH ACTION=add DEVPATH=/block/sda chroot mdev.testdir /mdev 2>&1; |
174 | ls -lnR mdev.testdir/dev | $FILTER_LS" \ | 174 | ls -lnR mdev.testdir/dev | $FILTER_LS" \ |
diff --git a/testsuite/runtest b/testsuite/runtest index 51575d926..44f9cd1a1 100755 --- a/testsuite/runtest +++ b/testsuite/runtest | |||
@@ -12,12 +12,12 @@ total_failed=0 | |||
12 | # Option -e will make testcase stop on the first failed command. | 12 | # Option -e will make testcase stop on the first failed command. |
13 | run_applet_testcase() | 13 | run_applet_testcase() |
14 | { | 14 | { |
15 | local applet="$1" | 15 | applet="$1" |
16 | local testcase="$2" | 16 | testcase="$2" |
17 | 17 | ||
18 | local status=0 | 18 | status=0 |
19 | local uc_applet=$(echo "$applet" | tr a-z A-Z) | 19 | uc_applet=$(echo "$applet" | tr a-z A-Z) |
20 | local testname="$testcase" | 20 | testname="$testcase" |
21 | 21 | ||
22 | testname="${testname##*/}" # take basename | 22 | testname="${testname##*/}" # take basename |
23 | if grep "^# CONFIG_$uc_applet is not set$" "$bindir/.config" >/dev/null; then | 23 | if grep "^# CONFIG_$uc_applet is not set$" "$bindir/.config" >/dev/null; then |
diff --git a/testsuite/unzip.tests b/testsuite/unzip.tests index d9c45242c..2e4becdb8 100755 --- a/testsuite/unzip.tests +++ b/testsuite/unzip.tests | |||
@@ -34,7 +34,9 @@ rm foo.zip | |||
34 | optional FEATURE_UNZIP_CDF | 34 | optional FEATURE_UNZIP_CDF |
35 | testing "unzip (bad archive)" "uudecode; unzip bad.zip 2>&1; echo \$?" \ | 35 | testing "unzip (bad archive)" "uudecode; unzip bad.zip 2>&1; echo \$?" \ |
36 | "Archive: bad.zip | 36 | "Archive: bad.zip |
37 | unzip: short read | 37 | inflating: ]3j½r«IK-%Ix |
38 | unzip: corrupted data | ||
39 | unzip: inflate error | ||
38 | 1 | 40 | 1 |
39 | " \ | 41 | " \ |
40 | "" "\ | 42 | "" "\ |
diff --git a/util-linux/Config.src b/util-linux/Config.src index 3c522f948..0971d714a 100644 --- a/util-linux/Config.src +++ b/util-linux/Config.src | |||
@@ -40,7 +40,7 @@ config FEATURE_MOUNT_LOOP_CREATE | |||
40 | if it does not find a free one. | 40 | if it does not find a free one. |
41 | 41 | ||
42 | config FEATURE_MTAB_SUPPORT | 42 | config FEATURE_MTAB_SUPPORT |
43 | bool "Support for the old /etc/mtab file" | 43 | bool "Support old /etc/mtab file" |
44 | default n | 44 | default n |
45 | depends on MOUNT || UMOUNT | 45 | depends on MOUNT || UMOUNT |
46 | select FEATURE_MOUNT_FAKE | 46 | select FEATURE_MOUNT_FAKE |
diff --git a/util-linux/dmesg.c b/util-linux/dmesg.c index b7b2c6924..c3574f8f5 100644 --- a/util-linux/dmesg.c +++ b/util-linux/dmesg.c | |||
@@ -22,7 +22,7 @@ | |||
22 | //config: wish to enable the 'dmesg' utility. | 22 | //config: wish to enable the 'dmesg' utility. |
23 | //config: | 23 | //config: |
24 | //config:config FEATURE_DMESG_PRETTY | 24 | //config:config FEATURE_DMESG_PRETTY |
25 | //config: bool "Pretty dmesg output" | 25 | //config: bool "Pretty output" |
26 | //config: default y | 26 | //config: default y |
27 | //config: depends on DMESG | 27 | //config: depends on DMESG |
28 | //config: help | 28 | //config: help |
diff --git a/util-linux/fbset.c b/util-linux/fbset.c index 8a78c1ef9..673bf9aa4 100644 --- a/util-linux/fbset.c +++ b/util-linux/fbset.c | |||
@@ -22,7 +22,7 @@ | |||
22 | //config: if you wish to enable the 'fbset' utility. | 22 | //config: if you wish to enable the 'fbset' utility. |
23 | //config: | 23 | //config: |
24 | //config:config FEATURE_FBSET_FANCY | 24 | //config:config FEATURE_FBSET_FANCY |
25 | //config: bool "Turn on extra fbset options" | 25 | //config: bool "Enable extra options" |
26 | //config: default y | 26 | //config: default y |
27 | //config: depends on FBSET | 27 | //config: depends on FBSET |
28 | //config: help | 28 | //config: help |
@@ -32,7 +32,7 @@ | |||
32 | //config: options. | 32 | //config: options. |
33 | //config: | 33 | //config: |
34 | //config:config FEATURE_FBSET_READMODE | 34 | //config:config FEATURE_FBSET_READMODE |
35 | //config: bool "Turn on fbset readmode support" | 35 | //config: bool "Enable readmode support" |
36 | //config: default y | 36 | //config: default y |
37 | //config: depends on FBSET | 37 | //config: depends on FBSET |
38 | //config: help | 38 | //config: help |
diff --git a/util-linux/fdisk.c b/util-linux/fdisk.c index b988e65a9..916d4e30e 100644 --- a/util-linux/fdisk.c +++ b/util-linux/fdisk.c | |||
@@ -21,8 +21,6 @@ | |||
21 | //config: default y | 21 | //config: default y |
22 | //config: depends on FDISK | 22 | //config: depends on FDISK |
23 | //config: depends on !LFS # with LFS no special code is needed | 23 | //config: depends on !LFS # with LFS no special code is needed |
24 | //config: help | ||
25 | //config: Enable this option to support large disks > 4GB. | ||
26 | //config: | 24 | //config: |
27 | //config:config FEATURE_FDISK_WRITABLE | 25 | //config:config FEATURE_FDISK_WRITABLE |
28 | //config: bool "Write support" | 26 | //config: bool "Write support" |
@@ -105,8 +103,8 @@ | |||
105 | //usage: ) | 103 | //usage: ) |
106 | //usage: "\n -b 2048 (for certain MO disks) use 2048-byte sectors" | 104 | //usage: "\n -b 2048 (for certain MO disks) use 2048-byte sectors" |
107 | //usage: "\n -C CYLINDERS Set number of cylinders/heads/sectors" | 105 | //usage: "\n -C CYLINDERS Set number of cylinders/heads/sectors" |
108 | //usage: "\n -H HEADS" | 106 | //usage: "\n -H HEADS Typically 255" |
109 | //usage: "\n -S SECTORS" | 107 | //usage: "\n -S SECTORS Typically 63" |
110 | 108 | ||
111 | #ifndef _LARGEFILE64_SOURCE | 109 | #ifndef _LARGEFILE64_SOURCE |
112 | /* For lseek64 */ | 110 | /* For lseek64 */ |
diff --git a/util-linux/freeramdisk.c b/util-linux/freeramdisk.c index 8bc2c443b..28148fcbe 100644 --- a/util-linux/freeramdisk.c +++ b/util-linux/freeramdisk.c | |||
@@ -33,6 +33,7 @@ | |||
33 | //config: ramdisk. If you have no use for freeing memory from a ramdisk, leave | 33 | //config: ramdisk. If you have no use for freeing memory from a ramdisk, leave |
34 | //config: this disabled. | 34 | //config: this disabled. |
35 | 35 | ||
36 | // APPLET_ODDNAME:name main location suid_type help | ||
36 | //applet:IF_FDFLUSH(APPLET_ODDNAME(fdflush, freeramdisk, BB_DIR_BIN, BB_SUID_DROP, fdflush)) | 37 | //applet:IF_FDFLUSH(APPLET_ODDNAME(fdflush, freeramdisk, BB_DIR_BIN, BB_SUID_DROP, fdflush)) |
37 | //applet:IF_FREERAMDISK(APPLET(freeramdisk, BB_DIR_SBIN, BB_SUID_DROP)) | 38 | //applet:IF_FREERAMDISK(APPLET(freeramdisk, BB_DIR_SBIN, BB_SUID_DROP)) |
38 | 39 | ||
diff --git a/util-linux/fsck_minix.c b/util-linux/fsck_minix.c index 0eaac17c0..2ab7530ea 100644 --- a/util-linux/fsck_minix.c +++ b/util-linux/fsck_minix.c | |||
@@ -1226,7 +1226,6 @@ void check2(void); | |||
1226 | int fsck_minix_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; | 1226 | int fsck_minix_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; |
1227 | int fsck_minix_main(int argc UNUSED_PARAM, char **argv) | 1227 | int fsck_minix_main(int argc UNUSED_PARAM, char **argv) |
1228 | { | 1228 | { |
1229 | struct termios tmp; | ||
1230 | int retcode = 0; | 1229 | int retcode = 0; |
1231 | 1230 | ||
1232 | xfunc_error_retval = 8; | 1231 | xfunc_error_retval = 8; |
@@ -1271,10 +1270,7 @@ int fsck_minix_main(int argc UNUSED_PARAM, char **argv) | |||
1271 | read_tables(); | 1270 | read_tables(); |
1272 | 1271 | ||
1273 | if (OPT_manual) { | 1272 | if (OPT_manual) { |
1274 | tcgetattr(0, &sv_termios); | 1273 | set_termios_to_raw(STDIN_FILENO, &sv_termios, 0); |
1275 | tmp = sv_termios; | ||
1276 | tmp.c_lflag &= ~(ICANON | ECHO); | ||
1277 | tcsetattr_stdin_TCSANOW(&tmp); | ||
1278 | termios_set = 1; | 1274 | termios_set = 1; |
1279 | } | 1275 | } |
1280 | 1276 | ||
diff --git a/util-linux/fstrim.c b/util-linux/fstrim.c index fc51878b6..563aa9720 100644 --- a/util-linux/fstrim.c +++ b/util-linux/fstrim.c | |||
@@ -23,9 +23,9 @@ | |||
23 | //usage: "[OPTIONS] MOUNTPOINT" | 23 | //usage: "[OPTIONS] MOUNTPOINT" |
24 | //usage:#define fstrim_full_usage "\n\n" | 24 | //usage:#define fstrim_full_usage "\n\n" |
25 | //usage: IF_LONG_OPTS( | 25 | //usage: IF_LONG_OPTS( |
26 | //usage: " -o,--offset=OFFSET Offset in bytes to discard from" | 26 | //usage: " -o,--offset OFFSET Offset in bytes to discard from" |
27 | //usage: "\n -l,--length=LEN Bytes to discard" | 27 | //usage: "\n -l,--length LEN Bytes to discard" |
28 | //usage: "\n -m,--minimum=MIN Minimum extent length" | 28 | //usage: "\n -m,--minimum MIN Minimum extent length" |
29 | //usage: "\n -v,--verbose Print number of discarded bytes" | 29 | //usage: "\n -v,--verbose Print number of discarded bytes" |
30 | //usage: ) | 30 | //usage: ) |
31 | //usage: IF_NOT_LONG_OPTS( | 31 | //usage: IF_NOT_LONG_OPTS( |
diff --git a/util-linux/getopt.c b/util-linux/getopt.c index f6ecc3dde..63294c520 100644 --- a/util-linux/getopt.c +++ b/util-linux/getopt.c | |||
@@ -57,13 +57,13 @@ | |||
57 | //usage: IF_LONG_OPTS( | 57 | //usage: IF_LONG_OPTS( |
58 | //usage: IF_FEATURE_GETOPT_LONG( | 58 | //usage: IF_FEATURE_GETOPT_LONG( |
59 | //usage: " -a,--alternative Allow long options starting with single -\n" | 59 | //usage: " -a,--alternative Allow long options starting with single -\n" |
60 | //usage: " -l,--longoptions=LOPT[,...] Long options to recognize\n" | 60 | //usage: " -l,--longoptions LOPT[,...] Long options to recognize\n" |
61 | //usage: ) | 61 | //usage: ) |
62 | //usage: " -n,--name=PROGNAME The name under which errors are reported" | 62 | //usage: " -n,--name PROGNAME The name under which errors are reported" |
63 | //usage: "\n -o,--options=OPTSTRING Short options to recognize" | 63 | //usage: "\n -o,--options OPTSTRING Short options to recognize" |
64 | //usage: "\n -q,--quiet No error messages on unrecognized options" | 64 | //usage: "\n -q,--quiet No error messages on unrecognized options" |
65 | //usage: "\n -Q,--quiet-output No normal output" | 65 | //usage: "\n -Q,--quiet-output No normal output" |
66 | //usage: "\n -s,--shell=SHELL Set shell quoting conventions" | 66 | //usage: "\n -s,--shell SHELL Set shell quoting conventions" |
67 | //usage: "\n -T,--test Version test (exits with 4)" | 67 | //usage: "\n -T,--test Version test (exits with 4)" |
68 | //usage: "\n -u,--unquoted Don't quote output" | 68 | //usage: "\n -u,--unquoted Don't quote output" |
69 | //usage: ) | 69 | //usage: ) |
diff --git a/util-linux/hexdump.c b/util-linux/hexdump.c index 4a7f641db..25f771201 100644 --- a/util-linux/hexdump.c +++ b/util-linux/hexdump.c | |||
@@ -41,19 +41,21 @@ | |||
41 | //usage: "[-bcCdefnosvx" IF_FEATURE_HEXDUMP_REVERSE("R") "] [FILE]..." | 41 | //usage: "[-bcCdefnosvx" IF_FEATURE_HEXDUMP_REVERSE("R") "] [FILE]..." |
42 | //usage:#define hexdump_full_usage "\n\n" | 42 | //usage:#define hexdump_full_usage "\n\n" |
43 | //usage: "Display FILEs (or stdin) in a user specified format\n" | 43 | //usage: "Display FILEs (or stdin) in a user specified format\n" |
44 | //usage: "\n -b One-byte octal display" | 44 | //usage: "\n -b 1-byte octal display" |
45 | //usage: "\n -c One-byte character display" | 45 | //usage: "\n -c 1-byte character display" |
46 | //usage: "\n -C Canonical hex+ASCII, 16 bytes per line" | 46 | //usage: "\n -d 2-byte decimal display" |
47 | //usage: "\n -d Two-byte decimal display" | 47 | //usage: "\n -o 2-byte octal display" |
48 | //usage: "\n -e FORMAT_STRING" | 48 | //usage: "\n -x 2-byte hex display" |
49 | //usage: "\n -C hex+ASCII 16 bytes per line" | ||
50 | //usage: "\n -v Show all (no dup folding)" | ||
51 | //usage: "\n -e FORMAT_STR Example: '16/1 \"%02x|\"\"\\n\"'" | ||
49 | //usage: "\n -f FORMAT_FILE" | 52 | //usage: "\n -f FORMAT_FILE" |
50 | //usage: "\n -n LENGTH Interpret only LENGTH bytes of input" | 53 | // exactly the same help text lines in hexdump and xxd: |
51 | //usage: "\n -o Two-byte octal display" | 54 | //usage: "\n -n LENGTH Show only first LENGTH bytes" |
52 | //usage: "\n -s OFFSET Skip OFFSET bytes" | 55 | //usage: "\n -s OFFSET Skip OFFSET bytes" |
53 | //usage: "\n -v Display all input data" | ||
54 | //usage: "\n -x Two-byte hexadecimal display" | ||
55 | //usage: IF_FEATURE_HEXDUMP_REVERSE( | 56 | //usage: IF_FEATURE_HEXDUMP_REVERSE( |
56 | //usage: "\n -R Reverse of 'hexdump -Cv'") | 57 | //usage: "\n -R Reverse of 'hexdump -Cv'") |
58 | // TODO: NONCOMPAT!!! move -R to xxd -r | ||
57 | //usage: | 59 | //usage: |
58 | //usage:#define hd_trivial_usage | 60 | //usage:#define hd_trivial_usage |
59 | //usage: "FILE..." | 61 | //usage: "FILE..." |
@@ -83,11 +85,11 @@ static void bb_dump_addfile(dumper_t *dumper, char *name) | |||
83 | } | 85 | } |
84 | 86 | ||
85 | static const char *const add_strings[] = { | 87 | static const char *const add_strings[] = { |
86 | "\"%07.7_ax \" 16/1 \"%03o \" \"\\n\"", /* b */ | 88 | "\"%07.7_ax \"16/1 \"%03o \"\"\n\"", /* b */ |
87 | "\"%07.7_ax \" 16/1 \"%3_c \" \"\\n\"", /* c */ | 89 | "\"%07.7_ax \"16/1 \"%3_c \"\"\n\"", /* c */ |
88 | "\"%07.7_ax \" 8/2 \" %05u \" \"\\n\"", /* d */ | 90 | "\"%07.7_ax \"8/2 \" %05u \"\"\n\"", /* d */ |
89 | "\"%07.7_ax \" 8/2 \" %06o \" \"\\n\"", /* o */ | 91 | "\"%07.7_ax \"8/2 \" %06o \"\"\n\"", /* o */ |
90 | "\"%07.7_ax \" 8/2 \" %04x \" \"\\n\"", /* x */ | 92 | "\"%07.7_ax \"8/2 \" %04x \"\"\n\"", /* x */ |
91 | }; | 93 | }; |
92 | 94 | ||
93 | static const char add_first[] ALIGN1 = "\"%07.7_Ax\n\""; | 95 | static const char add_first[] ALIGN1 = "\"%07.7_Ax\n\""; |
@@ -125,9 +127,11 @@ int hexdump_main(int argc, char **argv) | |||
125 | /* Save a little bit of space below by omitting the 'else's. */ | 127 | /* Save a little bit of space below by omitting the 'else's. */ |
126 | if (ch == 'C') { | 128 | if (ch == 'C') { |
127 | hd_applet: | 129 | hd_applet: |
128 | bb_dump_add(dumper, "\"%08.8_Ax\n\""); | 130 | bb_dump_add(dumper, "\"%08.8_Ax\n\""); // final address line after dump |
129 | bb_dump_add(dumper, "\"%08.8_ax \" 8/1 \"%02x \" \" \" 8/1 \"%02x \" "); | 131 | //------------------- "address " 8 * "xx " " " 8 * "xx " |
130 | bb_dump_add(dumper, "\" |\" 16/1 \"%_p\" \"|\\n\""); | 132 | bb_dump_add(dumper, "\"%08.8_ax \"8/1 \"%02x \"\" \"8/1 \"%02x \""); |
133 | //------------------- " |ASCII...........|\n" | ||
134 | bb_dump_add(dumper, "\" |\"16/1 \"%_p\"\"|\n\""); | ||
131 | } | 135 | } |
132 | if (ch == 'e') { | 136 | if (ch == 'e') { |
133 | bb_dump_add(dumper, optarg); | 137 | bb_dump_add(dumper, optarg); |
@@ -158,7 +162,7 @@ int hexdump_main(int argc, char **argv) | |||
158 | 162 | ||
159 | if (!dumper->fshead) { | 163 | if (!dumper->fshead) { |
160 | bb_dump_add(dumper, add_first); | 164 | bb_dump_add(dumper, add_first); |
161 | bb_dump_add(dumper, "\"%07.7_ax \" 8/2 \"%04x \" \"\\n\""); | 165 | bb_dump_add(dumper, "\"%07.7_ax \"8/2 \"%04x \"\"\n\""); |
162 | } | 166 | } |
163 | 167 | ||
164 | argv += optind; | 168 | argv += optind; |
diff --git a/util-linux/hexdump_xxd.c b/util-linux/hexdump_xxd.c new file mode 100644 index 000000000..be4b4f354 --- /dev/null +++ b/util-linux/hexdump_xxd.c | |||
@@ -0,0 +1,146 @@ | |||
1 | /* vi: set sw=4 ts=4: */ | ||
2 | /* | ||
3 | * xxd implementation for busybox | ||
4 | * | ||
5 | * Copyright (c) 2017 Denys Vlasenko <vda.linux@gmail.com> | ||
6 | * | ||
7 | * Licensed under GPLv2, see file LICENSE in this source tree. | ||
8 | */ | ||
9 | //config:config XXD | ||
10 | //config: bool "xxd" | ||
11 | //config: default y | ||
12 | //config: help | ||
13 | //config: The xxd utility is used to display binary data in a readable | ||
14 | //config: way that is comparable to the output from most hex editors. | ||
15 | |||
16 | //applet:IF_XXD(APPLET_NOEXEC(xxd, xxd, BB_DIR_USR_BIN, BB_SUID_DROP, xxd)) | ||
17 | |||
18 | //kbuild:lib-$(CONFIG_XXD) += hexdump_xxd.o | ||
19 | |||
20 | // $ xxd --version | ||
21 | // xxd V1.10 27oct98 by Juergen Weigert | ||
22 | // $ xxd --help | ||
23 | // Usage: | ||
24 | // xxd [options] [infile [outfile]] | ||
25 | // or | ||
26 | // xxd -r [-s [-]offset] [-c cols] [-ps] [infile [outfile]] | ||
27 | // Options: | ||
28 | // -a toggle autoskip: A single '*' replaces nul-lines. Default off. | ||
29 | // -b binary digit dump (incompatible with -ps,-i,-r). Default hex. | ||
30 | // -c cols format <cols> octets per line. Default 16 (-i: 12, -ps: 30). | ||
31 | // -E show characters in EBCDIC. Default ASCII. | ||
32 | // -e little-endian dump (incompatible with -ps,-i,-r). | ||
33 | // -g number of octets per group in normal output. Default 2 (-e: 4). | ||
34 | // -i output in C include file style. | ||
35 | // -l len stop after <len> octets. | ||
36 | // -o off add <off> to the displayed file position. | ||
37 | // -ps output in postscript plain hexdump style. | ||
38 | // -r reverse operation: convert (or patch) hexdump into binary. | ||
39 | // -r -s off revert with <off> added to file positions found in hexdump. | ||
40 | // -s [+][-]seek start at <seek> bytes abs. (or +: rel.) infile offset. | ||
41 | // -u use upper case hex letters. | ||
42 | |||
43 | //usage:#define xxd_trivial_usage | ||
44 | //usage: "[OPTIONS] [FILE]" | ||
45 | //usage:#define xxd_full_usage "\n\n" | ||
46 | //usage: "Hex dump FILE (or stdin)\n" | ||
47 | //usage: "\n -g N Bytes per group" | ||
48 | //usage: "\n -c N Bytes per line" | ||
49 | //usage: "\n -p Show only hex bytes, assumes -c30" | ||
50 | // exactly the same help text lines in hexdump and xxd: | ||
51 | //usage: "\n -l LENGTH Show only first LENGTH bytes" | ||
52 | //usage: "\n -s OFFSET Skip OFFSET bytes" | ||
53 | // TODO: implement -r (see hexdump -R) | ||
54 | |||
55 | #include "libbb.h" | ||
56 | #include "dump.h" | ||
57 | |||
58 | /* This is a NOEXEC applet. Be very careful! */ | ||
59 | |||
60 | int xxd_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; | ||
61 | int xxd_main(int argc UNUSED_PARAM, char **argv) | ||
62 | { | ||
63 | char buf[80]; | ||
64 | dumper_t *dumper; | ||
65 | char *opt_l, *opt_s; | ||
66 | unsigned bytes = 2; | ||
67 | unsigned cols = 0; | ||
68 | unsigned opt; | ||
69 | |||
70 | dumper = alloc_dumper(); | ||
71 | |||
72 | #define OPT_l (1 << 0) | ||
73 | #define OPT_s (1 << 1) | ||
74 | #define OPT_a (1 << 2) | ||
75 | #define OPT_p (1 << 3) | ||
76 | opt_complementary = "?1"; /* 1 argument max */ | ||
77 | opt = getopt32(argv, "l:s:apg:+c:+", &opt_l, &opt_s, &bytes, &cols); | ||
78 | argv += optind; | ||
79 | |||
80 | dumper->dump_vflag = ALL; | ||
81 | // if (opt & OPT_a) | ||
82 | // dumper->dump_vflag = SKIPNUL; ..does not exist | ||
83 | if (opt & OPT_l) { | ||
84 | dumper->dump_length = xstrtou_range( | ||
85 | opt_l, | ||
86 | /*base:*/ 0, | ||
87 | /*lo:*/ 0, /*hi:*/ INT_MAX | ||
88 | ); | ||
89 | } | ||
90 | if (opt & OPT_s) { | ||
91 | dumper->dump_skip = xstrtoull_range( | ||
92 | opt_s, | ||
93 | /*base:*/ 0, | ||
94 | /*lo:*/ 0, /*hi:*/ OFF_T_MAX | ||
95 | ); | ||
96 | //BUGGY for /proc/version (unseekable?) | ||
97 | } | ||
98 | |||
99 | if (opt & OPT_p) { | ||
100 | if (cols == 0) | ||
101 | cols = 30; | ||
102 | bytes = cols; /* -p ignores -gN */ | ||
103 | } else { | ||
104 | if (cols == 0) | ||
105 | cols = 16; | ||
106 | bb_dump_add(dumper, "\"%08.8_ax: \""); // "address: " | ||
107 | } | ||
108 | |||
109 | if (bytes < 1 || bytes >= cols) { | ||
110 | sprintf(buf, "%u/1 \"%%02x\"", cols); // cols * "xx" | ||
111 | bb_dump_add(dumper, buf); | ||
112 | } | ||
113 | else if (bytes == 1) { | ||
114 | sprintf(buf, "%u/1 \"%%02x \"", cols); // cols * "xx " | ||
115 | bb_dump_add(dumper, buf); | ||
116 | } | ||
117 | else { | ||
118 | /* Format "print byte" with and without trailing space */ | ||
119 | #define BS "/1 \"%02x \"" | ||
120 | #define B "/1 \"%02x\"" | ||
121 | unsigned i; | ||
122 | char *bigbuf = xmalloc(cols * (sizeof(BS)-1)); | ||
123 | char *p = bigbuf; | ||
124 | for (i = 1; i <= cols; i++) { | ||
125 | if (i == cols || i % bytes) | ||
126 | p = stpcpy(p, B); | ||
127 | else | ||
128 | p = stpcpy(p, BS); | ||
129 | } | ||
130 | // for -g3, this results in B B BS B B BS... B = "xxxxxx xxxxxx .....xx" | ||
131 | // todo: can be more clever and use | ||
132 | // one 'bytes-1/1 "%02x"' format instead of many "B B B..." formats | ||
133 | //bb_error_msg("ADDED:'%s'", bigbuf); | ||
134 | bb_dump_add(dumper, bigbuf); | ||
135 | free(bigbuf); | ||
136 | } | ||
137 | |||
138 | if (!(opt & OPT_p)) { | ||
139 | sprintf(buf, "\" \"%u/1 \"%%_p\"\"\n\"", cols); // " ASCII\n" | ||
140 | bb_dump_add(dumper, buf); | ||
141 | } else { | ||
142 | bb_dump_add(dumper, "\"\n\""); | ||
143 | } | ||
144 | |||
145 | return bb_dump_dump(dumper, argv); | ||
146 | } | ||
diff --git a/util-linux/hwclock.c b/util-linux/hwclock.c index 084a7f1e9..d65011a71 100644 --- a/util-linux/hwclock.c +++ b/util-linux/hwclock.c | |||
@@ -20,10 +20,6 @@ | |||
20 | //config: bool "Support long options (--hctosys,...)" | 20 | //config: bool "Support long options (--hctosys,...)" |
21 | //config: default y | 21 | //config: default y |
22 | //config: depends on HWCLOCK && LONG_OPTS | 22 | //config: depends on HWCLOCK && LONG_OPTS |
23 | //config: help | ||
24 | //config: By default, the hwclock utility only uses short options. If you | ||
25 | //config: are overly fond of its long options, such as --hctosys, --utc, etc) | ||
26 | //config: then enable this option. | ||
27 | //config: | 23 | //config: |
28 | //config:config FEATURE_HWCLOCK_ADJTIME_FHS | 24 | //config:config FEATURE_HWCLOCK_ADJTIME_FHS |
29 | //config: bool "Use FHS /var/lib/hwclock/adjtime" | 25 | //config: bool "Use FHS /var/lib/hwclock/adjtime" |
diff --git a/util-linux/mkfs_ext2.c b/util-linux/mkfs_ext2.c index 5816a208e..4a7a878ac 100644 --- a/util-linux/mkfs_ext2.c +++ b/util-linux/mkfs_ext2.c | |||
@@ -21,7 +21,8 @@ | |||
21 | //config: help | 21 | //config: help |
22 | //config: Alias to "mke2fs". | 22 | //config: Alias to "mke2fs". |
23 | 23 | ||
24 | //applet:IF_MKE2FS(APPLET_ODDNAME(mke2fs, mkfs_ext2, BB_DIR_SBIN, BB_SUID_DROP, mkfs_ext2)) | 24 | // APPLET_ODDNAME:name main location suid_type help |
25 | //applet:IF_MKE2FS( APPLET_ODDNAME(mke2fs, mkfs_ext2, BB_DIR_SBIN, BB_SUID_DROP, mkfs_ext2)) | ||
25 | //applet:IF_MKFS_EXT2(APPLET_ODDNAME(mkfs.ext2, mkfs_ext2, BB_DIR_SBIN, BB_SUID_DROP, mkfs_ext2)) | 26 | //applet:IF_MKFS_EXT2(APPLET_ODDNAME(mkfs.ext2, mkfs_ext2, BB_DIR_SBIN, BB_SUID_DROP, mkfs_ext2)) |
26 | ////////:IF_MKFS_EXT3(APPLET_ODDNAME(mkfs.ext3, mkfs_ext2, BB_DIR_SBIN, BB_SUID_DROP, mkfs_ext2)) | 27 | ////////:IF_MKFS_EXT3(APPLET_ODDNAME(mkfs.ext3, mkfs_ext2, BB_DIR_SBIN, BB_SUID_DROP, mkfs_ext2)) |
27 | 28 | ||
diff --git a/util-linux/mkfs_minix.c b/util-linux/mkfs_minix.c index 912246b93..0dfe34705 100644 --- a/util-linux/mkfs_minix.c +++ b/util-linux/mkfs_minix.c | |||
@@ -80,6 +80,7 @@ | |||
80 | //config: this. If you enabled 'mkfs_minix' then you almost certainly want to | 80 | //config: this. If you enabled 'mkfs_minix' then you almost certainly want to |
81 | //config: be using the version 2 filesystem support. | 81 | //config: be using the version 2 filesystem support. |
82 | 82 | ||
83 | // APPLET_ODDNAME:name main location suid_type help | ||
83 | //applet:IF_MKFS_MINIX(APPLET_ODDNAME(mkfs.minix, mkfs_minix, BB_DIR_SBIN, BB_SUID_DROP, mkfs_minix)) | 84 | //applet:IF_MKFS_MINIX(APPLET_ODDNAME(mkfs.minix, mkfs_minix, BB_DIR_SBIN, BB_SUID_DROP, mkfs_minix)) |
84 | 85 | ||
85 | //kbuild:lib-$(CONFIG_MKFS_MINIX) += mkfs_minix.o | 86 | //kbuild:lib-$(CONFIG_MKFS_MINIX) += mkfs_minix.o |
diff --git a/util-linux/mkfs_vfat.c b/util-linux/mkfs_vfat.c index ab70853a1..1fc943430 100644 --- a/util-linux/mkfs_vfat.c +++ b/util-linux/mkfs_vfat.c | |||
@@ -21,7 +21,8 @@ | |||
21 | //config: help | 21 | //config: help |
22 | //config: Alias to "mkdosfs". | 22 | //config: Alias to "mkdosfs". |
23 | 23 | ||
24 | //applet:IF_MKDOSFS(APPLET_ODDNAME(mkdosfs, mkfs_vfat, BB_DIR_SBIN, BB_SUID_DROP, mkfs_vfat)) | 24 | // APPLET_ODDNAME:name main location suid_type help |
25 | //applet:IF_MKDOSFS( APPLET_ODDNAME(mkdosfs, mkfs_vfat, BB_DIR_SBIN, BB_SUID_DROP, mkfs_vfat)) | ||
25 | //applet:IF_MKFS_VFAT(APPLET_ODDNAME(mkfs.vfat, mkfs_vfat, BB_DIR_SBIN, BB_SUID_DROP, mkfs_vfat)) | 26 | //applet:IF_MKFS_VFAT(APPLET_ODDNAME(mkfs.vfat, mkfs_vfat, BB_DIR_SBIN, BB_SUID_DROP, mkfs_vfat)) |
26 | 27 | ||
27 | //kbuild:lib-$(CONFIG_MKDOSFS) += mkfs_vfat.o | 28 | //kbuild:lib-$(CONFIG_MKDOSFS) += mkfs_vfat.o |
diff --git a/util-linux/more.c b/util-linux/more.c index d04c17f90..a032a1e7f 100644 --- a/util-linux/more.c +++ b/util-linux/more.c | |||
@@ -41,32 +41,33 @@ | |||
41 | #include "libbb.h" | 41 | #include "libbb.h" |
42 | #include "common_bufsiz.h" | 42 | #include "common_bufsiz.h" |
43 | 43 | ||
44 | /* Support for FEATURE_USE_TERMIOS */ | ||
45 | |||
46 | struct globals { | 44 | struct globals { |
47 | int cin_fileno; | 45 | int tty_fileno; |
46 | unsigned terminal_width; | ||
47 | unsigned terminal_height; | ||
48 | struct termios initial_settings; | 48 | struct termios initial_settings; |
49 | struct termios new_settings; | ||
50 | } FIX_ALIASING; | 49 | } FIX_ALIASING; |
51 | #define G (*(struct globals*)bb_common_bufsiz1) | 50 | #define G (*(struct globals*)bb_common_bufsiz1) |
52 | #define initial_settings (G.initial_settings) | ||
53 | #define new_settings (G.new_settings ) | ||
54 | #define cin_fileno (G.cin_fileno ) | ||
55 | #define INIT_G() do { setup_common_bufsiz(); } while (0) | 51 | #define INIT_G() do { setup_common_bufsiz(); } while (0) |
56 | 52 | ||
57 | #define setTermSettings(fd, argp) \ | 53 | static void get_wh(void) |
58 | do { \ | 54 | { |
59 | if (ENABLE_FEATURE_USE_TERMIOS) \ | 55 | /* never returns w, h <= 1 */ |
60 | tcsetattr(fd, TCSANOW, argp); \ | 56 | get_terminal_width_height(G.tty_fileno, &G.terminal_width, &G.terminal_height); |
61 | } while (0) | 57 | G.terminal_height -= 1; |
62 | #define getTermSettings(fd, argp) tcgetattr(fd, argp) | 58 | } |
59 | |||
60 | static void tcsetattr_tty_TCSANOW(struct termios *settings) | ||
61 | { | ||
62 | tcsetattr(G.tty_fileno, TCSANOW, settings); | ||
63 | } | ||
63 | 64 | ||
64 | static void gotsig(int sig UNUSED_PARAM) | 65 | static void gotsig(int sig UNUSED_PARAM) |
65 | { | 66 | { |
66 | /* bb_putchar_stderr doesn't use stdio buffering, | 67 | /* bb_putchar_stderr doesn't use stdio buffering, |
67 | * therefore it is safe in signal handler */ | 68 | * therefore it is safe in signal handler */ |
68 | bb_putchar_stderr('\n'); | 69 | bb_putchar_stderr('\n'); |
69 | setTermSettings(cin_fileno, &initial_settings); | 70 | tcsetattr_tty_TCSANOW(&G.initial_settings); |
70 | _exit(EXIT_FAILURE); | 71 | _exit(EXIT_FAILURE); |
71 | } | 72 | } |
72 | 73 | ||
@@ -76,22 +77,16 @@ int more_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; | |||
76 | int more_main(int argc UNUSED_PARAM, char **argv) | 77 | int more_main(int argc UNUSED_PARAM, char **argv) |
77 | { | 78 | { |
78 | int c = c; /* for compiler */ | 79 | int c = c; /* for compiler */ |
79 | int lines; | ||
80 | int input = 0; | 80 | int input = 0; |
81 | int spaces = 0; | 81 | int spaces = 0; |
82 | int please_display_more_prompt; | 82 | int please_display_more_prompt; |
83 | struct stat st; | 83 | FILE *tty; |
84 | FILE *file; | ||
85 | FILE *cin; | ||
86 | int len; | ||
87 | unsigned terminal_width; | ||
88 | unsigned terminal_height; | ||
89 | 84 | ||
90 | INIT_G(); | 85 | INIT_G(); |
91 | 86 | ||
92 | /* Parse options */ | 87 | /* Parse options */ |
93 | /* Accepted but ignored: */ | 88 | /* Accepted but ignored: */ |
94 | /* -d Display help instead of ringing bell is pressed */ | 89 | /* -d Display help instead of ringing bell */ |
95 | /* -f Count logical lines (IOW: long lines are not folded) */ | 90 | /* -f Count logical lines (IOW: long lines are not folded) */ |
96 | /* -l Do not pause after any line containing a ^L (form feed) */ | 91 | /* -l Do not pause after any line containing a ^L (form feed) */ |
97 | /* -s Squeeze blank lines into one */ | 92 | /* -s Squeeze blank lines into one */ |
@@ -104,29 +99,25 @@ int more_main(int argc UNUSED_PARAM, char **argv) | |||
104 | if (!isatty(STDOUT_FILENO)) | 99 | if (!isatty(STDOUT_FILENO)) |
105 | return bb_cat(argv); | 100 | return bb_cat(argv); |
106 | #if !ENABLE_PLATFORM_MINGW32 | 101 | #if !ENABLE_PLATFORM_MINGW32 |
107 | cin = fopen_for_read(CURRENT_TTY); | 102 | tty = fopen_for_read(CURRENT_TTY); |
108 | if (!cin) | 103 | if (!tty) |
109 | return bb_cat(argv); | 104 | return bb_cat(argv); |
110 | #else | 105 | #else |
111 | cin = stdin; | 106 | tty = stdin; |
112 | #endif | 107 | #endif |
113 | 108 | ||
114 | if (ENABLE_FEATURE_USE_TERMIOS) { | 109 | G.tty_fileno = fileno(tty); |
115 | cin_fileno = fileno(cin); | 110 | |
116 | getTermSettings(cin_fileno, &initial_settings); | 111 | /* Turn on unbuffered input; turn off echoing */ |
117 | new_settings = initial_settings; | 112 | set_termios_to_raw(G.tty_fileno, &G.initial_settings, 0); |
118 | new_settings.c_lflag &= ~(ICANON | ECHO); | 113 | bb_signals(BB_FATAL_SIGS, gotsig); |
119 | new_settings.c_cc[VMIN] = 1; | ||
120 | new_settings.c_cc[VTIME] = 0; | ||
121 | setTermSettings(cin_fileno, &new_settings); | ||
122 | bb_signals(0 | ||
123 | + (1 << SIGINT) | ||
124 | + (1 << SIGQUIT) | ||
125 | + (1 << SIGTERM) | ||
126 | , gotsig); | ||
127 | } | ||
128 | 114 | ||
129 | do { | 115 | do { |
116 | struct stat st; | ||
117 | FILE *file; | ||
118 | int len; | ||
119 | int lines; | ||
120 | |||
130 | file = stdin; | 121 | file = stdin; |
131 | if (*argv) { | 122 | if (*argv) { |
132 | file = fopen_or_warn(*argv, "r"); | 123 | file = fopen_or_warn(*argv, "r"); |
@@ -136,17 +127,20 @@ int more_main(int argc UNUSED_PARAM, char **argv) | |||
136 | st.st_size = 0; | 127 | st.st_size = 0; |
137 | fstat(fileno(file), &st); | 128 | fstat(fileno(file), &st); |
138 | 129 | ||
139 | please_display_more_prompt = 0; | 130 | get_wh(); |
140 | /* never returns w, h <= 1 */ | ||
141 | get_terminal_width_height(fileno(cin), &terminal_width, &terminal_height); | ||
142 | terminal_height -= 1; | ||
143 | 131 | ||
132 | please_display_more_prompt = 0; | ||
144 | len = 0; | 133 | len = 0; |
145 | lines = 0; | 134 | lines = 0; |
146 | while (spaces || (c = getc(file)) != EOF) { | 135 | for (;;) { |
147 | int wrap; | 136 | int wrap; |
137 | |||
148 | if (spaces) | 138 | if (spaces) |
149 | spaces--; | 139 | spaces--; |
140 | else { | ||
141 | c = getc(file); | ||
142 | if (c == EOF) break; | ||
143 | } | ||
150 | loop_top: | 144 | loop_top: |
151 | if (input != 'r' && please_display_more_prompt) { | 145 | if (input != 'r' && please_display_more_prompt) { |
152 | len = printf("--More-- "); | 146 | len = printf("--More-- "); |
@@ -158,7 +152,6 @@ int more_main(int argc UNUSED_PARAM, char **argv) | |||
158 | (int) ((uoff_t)ftello(file) / d), | 152 | (int) ((uoff_t)ftello(file) / d), |
159 | st.st_size); | 153 | st.st_size); |
160 | } | 154 | } |
161 | fflush_all(); | ||
162 | 155 | ||
163 | /* | 156 | /* |
164 | * We've just displayed the "--More--" prompt, so now we need | 157 | * We've just displayed the "--More--" prompt, so now we need |
@@ -166,22 +159,23 @@ int more_main(int argc UNUSED_PARAM, char **argv) | |||
166 | */ | 159 | */ |
167 | for (;;) { | 160 | for (;;) { |
168 | #if !ENABLE_PLATFORM_MINGW32 | 161 | #if !ENABLE_PLATFORM_MINGW32 |
169 | input = getc(cin); | 162 | fflush_all(); |
163 | input = getc(tty); | ||
170 | #else | 164 | #else |
171 | input = _getch(); | 165 | input = _getch(); |
172 | #endif | 166 | #endif |
173 | input = tolower(input); | 167 | input = tolower(input); |
174 | if (!ENABLE_FEATURE_USE_TERMIOS) | ||
175 | printf("\033[A"); /* cursor up */ | ||
176 | /* Erase the last message */ | 168 | /* Erase the last message */ |
177 | printf("\r%*s\r", len, ""); | 169 | printf("\r%*s\r", len, ""); |
178 | 170 | ||
171 | if (input == 'q') | ||
172 | goto end; | ||
179 | /* Due to various multibyte escape | 173 | /* Due to various multibyte escape |
180 | * sequences, it's not ok to accept | 174 | * sequences, it's not ok to accept |
181 | * any input as a command to scroll | 175 | * any input as a command to scroll |
182 | * the screen. We only allow known | 176 | * the screen. We only allow known |
183 | * commands, else we show help msg. */ | 177 | * commands, else we show help msg. */ |
184 | if (input == ' ' || input == '\n' || input == 'q' || input == 'r') | 178 | if (input == ' ' || input == '\n' || input == 'r') |
185 | break; | 179 | break; |
186 | #if ENABLE_PLATFORM_MINGW32 | 180 | #if ENABLE_PLATFORM_MINGW32 |
187 | if (input == '\r') | 181 | if (input == '\r') |
@@ -193,15 +187,9 @@ int more_main(int argc UNUSED_PARAM, char **argv) | |||
193 | lines = 0; | 187 | lines = 0; |
194 | please_display_more_prompt = 0; | 188 | please_display_more_prompt = 0; |
195 | 189 | ||
196 | if (input == 'q') | ||
197 | goto end; | ||
198 | |||
199 | /* The user may have resized the terminal. | 190 | /* The user may have resized the terminal. |
200 | * Re-read the dimensions. */ | 191 | * Re-read the dimensions. */ |
201 | if (ENABLE_FEATURE_USE_TERMIOS) { | 192 | get_wh(); |
202 | get_terminal_width_height(cin_fileno, &terminal_width, &terminal_height); | ||
203 | terminal_height -= 1; | ||
204 | } | ||
205 | } | 193 | } |
206 | 194 | ||
207 | /* Crudely convert tabs into spaces, which are | 195 | /* Crudely convert tabs into spaces, which are |
@@ -221,11 +209,11 @@ int more_main(int argc UNUSED_PARAM, char **argv) | |||
221 | * see if any characters have been hit in the _input_ stream. This | 209 | * see if any characters have been hit in the _input_ stream. This |
222 | * allows the user to quit while in the middle of a file. | 210 | * allows the user to quit while in the middle of a file. |
223 | */ | 211 | */ |
224 | wrap = (++len > terminal_width); | 212 | wrap = (++len > G.terminal_width); |
225 | if (c == '\n' || wrap) { | 213 | if (c == '\n' || wrap) { |
226 | /* Then outputting this character | 214 | /* Then outputting this character |
227 | * will move us to a new line. */ | 215 | * will move us to a new line. */ |
228 | if (++lines >= terminal_height || input == '\n') | 216 | if (++lines >= G.terminal_height || input == '\n') |
229 | please_display_more_prompt = 1; | 217 | please_display_more_prompt = 1; |
230 | #if ENABLE_PLATFORM_MINGW32 | 218 | #if ENABLE_PLATFORM_MINGW32 |
231 | if (input == '\r') | 219 | if (input == '\r') |
@@ -249,6 +237,6 @@ int more_main(int argc UNUSED_PARAM, char **argv) | |||
249 | fflush_all(); | 237 | fflush_all(); |
250 | } while (*argv && *++argv); | 238 | } while (*argv && *++argv); |
251 | end: | 239 | end: |
252 | setTermSettings(cin_fileno, &initial_settings); | 240 | tcsetattr_tty_TCSANOW(&G.initial_settings); |
253 | return 0; | 241 | return 0; |
254 | } | 242 | } |
diff --git a/util-linux/mount.c b/util-linux/mount.c index 42962b859..f0245f714 100644 --- a/util-linux/mount.c +++ b/util-linux/mount.c | |||
@@ -90,7 +90,7 @@ | |||
90 | //config: | 90 | //config: |
91 | //config:config FEATURE_MOUNT_FLAGS | 91 | //config:config FEATURE_MOUNT_FLAGS |
92 | //config: depends on MOUNT | 92 | //config: depends on MOUNT |
93 | //config: bool "Support lots of -o flags in mount" | 93 | //config: bool "Support lots of -o flags" |
94 | //config: default y | 94 | //config: default y |
95 | //config: help | 95 | //config: help |
96 | //config: Without this, mount only supports ro/rw/remount. With this, it | 96 | //config: Without this, mount only supports ro/rw/remount. With this, it |
@@ -2312,7 +2312,7 @@ int mount_main(int argc UNUSED_PARAM, char **argv) | |||
2312 | bb_error_msg_and_die(bb_msg_you_must_be_root); | 2312 | bb_error_msg_and_die(bb_msg_you_must_be_root); |
2313 | 2313 | ||
2314 | // Does type match? (NULL matches always) | 2314 | // Does type match? (NULL matches always) |
2315 | if (!match_fstype(mtcur, fstype)) | 2315 | if (!fstype_matches(mtcur->mnt_type, fstype)) |
2316 | continue; | 2316 | continue; |
2317 | 2317 | ||
2318 | // Skip noauto and swap anyway | 2318 | // Skip noauto and swap anyway |
diff --git a/util-linux/nsenter.c b/util-linux/nsenter.c index 6834292da..57b218dab 100644 --- a/util-linux/nsenter.c +++ b/util-linux/nsenter.c | |||
@@ -30,19 +30,19 @@ | |||
30 | //usage: "[OPTIONS] [PROG [ARGS]]" | 30 | //usage: "[OPTIONS] [PROG [ARGS]]" |
31 | //usage:#if ENABLE_FEATURE_NSENTER_LONG_OPTS | 31 | //usage:#if ENABLE_FEATURE_NSENTER_LONG_OPTS |
32 | //usage:#define nsenter_full_usage "\n" | 32 | //usage:#define nsenter_full_usage "\n" |
33 | //usage: "\n -t, --target=PID Target process to get namespaces from" | 33 | //usage: "\n -t,--target PID Target process to get namespaces from" |
34 | //usage: "\n -m, --mount[=FILE] Enter mount namespace" | 34 | //usage: "\n -m,--mount[=FILE] Enter mount namespace" |
35 | //usage: "\n -u, --uts[=FILE] Enter UTS namespace (hostname etc)" | 35 | //usage: "\n -u,--uts[=FILE] Enter UTS namespace (hostname etc)" |
36 | //usage: "\n -i, --ipc[=FILE] Enter System V IPC namespace" | 36 | //usage: "\n -i,--ipc[=FILE] Enter System V IPC namespace" |
37 | //usage: "\n -n, --net[=FILE] Enter network namespace" | 37 | //usage: "\n -n,--net[=FILE] Enter network namespace" |
38 | //usage: "\n -p, --pid[=FILE] Enter pid namespace" | 38 | //usage: "\n -p,--pid[=FILE] Enter pid namespace" |
39 | //usage: "\n -U, --user[=FILE] Enter user namespace" | 39 | //usage: "\n -U,--user[=FILE] Enter user namespace" |
40 | //usage: "\n -S, --setuid=UID Set uid in entered namespace" | 40 | //usage: "\n -S,--setuid UID Set uid in entered namespace" |
41 | //usage: "\n -G, --setgid=GID Set gid in entered namespace" | 41 | //usage: "\n -G,--setgid GID Set gid in entered namespace" |
42 | //usage: "\n --preserve-credentials Don't touch uids or gids" | 42 | //usage: "\n --preserve-credentials Don't touch uids or gids" |
43 | //usage: "\n -r, --root[=DIR] Set root directory" | 43 | //usage: "\n -r,--root[=DIR] Set root directory" |
44 | //usage: "\n -w, --wd[=DIR] Set working directory" | 44 | //usage: "\n -w,--wd[=DIR] Set working directory" |
45 | //usage: "\n -F, --no-fork Don't fork before exec'ing PROG" | 45 | //usage: "\n -F,--no-fork Don't fork before exec'ing PROG" |
46 | //usage:#else | 46 | //usage:#else |
47 | //usage:#define nsenter_full_usage "\n" | 47 | //usage:#define nsenter_full_usage "\n" |
48 | //usage: "\n -t PID Target process to get namespaces from" | 48 | //usage: "\n -t PID Target process to get namespaces from" |
diff --git a/util-linux/rdate.c b/util-linux/rdate.c index 8dd784d3d..960df25d2 100644 --- a/util-linux/rdate.c +++ b/util-linux/rdate.c | |||
@@ -21,11 +21,11 @@ | |||
21 | //kbuild:lib-$(CONFIG_RDATE) += rdate.o | 21 | //kbuild:lib-$(CONFIG_RDATE) += rdate.o |
22 | 22 | ||
23 | //usage:#define rdate_trivial_usage | 23 | //usage:#define rdate_trivial_usage |
24 | //usage: "[-sp] HOST" | 24 | //usage: "[-s/-p] HOST" |
25 | //usage:#define rdate_full_usage "\n\n" | 25 | //usage:#define rdate_full_usage "\n\n" |
26 | //usage: "Get and possibly set system time from a remote HOST\n" | 26 | //usage: "Set and print time from HOST using RFC 868\n" |
27 | //usage: "\n -s Set system time (default)" | 27 | //usage: "\n -s Only set system time" |
28 | //usage: "\n -p Print time" | 28 | //usage: "\n -p Only print time" |
29 | 29 | ||
30 | #include "libbb.h" | 30 | #include "libbb.h" |
31 | 31 | ||
@@ -58,8 +58,22 @@ static time_t askremotedate(const char *host) | |||
58 | * the RFC 868 time 2,208,988,800 corresponds to 00:00 1 Jan 1970 GMT | 58 | * the RFC 868 time 2,208,988,800 corresponds to 00:00 1 Jan 1970 GMT |
59 | * Subtract the RFC 868 time to get Linux epoch. | 59 | * Subtract the RFC 868 time to get Linux epoch. |
60 | */ | 60 | */ |
61 | 61 | nett = ntohl(nett) - RFC_868_BIAS; | |
62 | return ntohl(nett) - RFC_868_BIAS; | 62 | |
63 | if (sizeof(time_t) > 4) { | ||
64 | /* Now we have 32-bit lsb of a wider time_t | ||
65 | * Imagine that nett = 0x00000001, | ||
66 | * current time cur = 0x123ffffffff. | ||
67 | * Assuming our time is not some 40 years off, | ||
68 | * remote time must be 0x12400000001. | ||
69 | * Need to adjust out time by (int32_t)(nett - cur). | ||
70 | */ | ||
71 | time_t cur = time(NULL); | ||
72 | int32_t adjust = (int32_t)(nett - (uint32_t)cur); | ||
73 | return cur + adjust; | ||
74 | } | ||
75 | /* This is not going to work, but what can we do */ | ||
76 | return (time_t)nett; | ||
63 | } | 77 | } |
64 | 78 | ||
65 | int rdate_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; | 79 | int rdate_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; |
@@ -73,11 +87,15 @@ int rdate_main(int argc UNUSED_PARAM, char **argv) | |||
73 | 87 | ||
74 | remote_time = askremotedate(argv[optind]); | 88 | remote_time = askremotedate(argv[optind]); |
75 | 89 | ||
76 | if (!(flags & 2)) { /* no -p (-s may be present) */ | 90 | /* Manpages of various Unixes are confusing. What happens is: |
77 | time_t current_time; | 91 | * (no opts) set and print time |
92 | * -s: set time ("do not print the time") | ||
93 | * -p: print time ("do not set, just print the remote time") | ||
94 | * -sp: print time (that's what we do, not sure this is right) | ||
95 | */ | ||
78 | 96 | ||
79 | time(¤t_time); | 97 | if (!(flags & 2)) { /* no -p (-s may be present) */ |
80 | if (current_time == remote_time) | 98 | if (time(NULL) == remote_time) |
81 | bb_error_msg("current time matches remote time"); | 99 | bb_error_msg("current time matches remote time"); |
82 | else | 100 | else |
83 | if (stime(&remote_time) < 0) | 101 | if (stime(&remote_time) < 0) |
diff --git a/util-linux/rtcwake.c b/util-linux/rtcwake.c index 54fc70583..b63164588 100644 --- a/util-linux/rtcwake.c +++ b/util-linux/rtcwake.c | |||
@@ -41,10 +41,10 @@ | |||
41 | //usage: "\n -a,--auto Read clock mode from adjtime" | 41 | //usage: "\n -a,--auto Read clock mode from adjtime" |
42 | //usage: "\n -l,--local Clock is set to local time" | 42 | //usage: "\n -l,--local Clock is set to local time" |
43 | //usage: "\n -u,--utc Clock is set to UTC time" | 43 | //usage: "\n -u,--utc Clock is set to UTC time" |
44 | //usage: "\n -d,--device=DEV Specify the RTC device" | 44 | //usage: "\n -d,--device DEV Specify the RTC device" |
45 | //usage: "\n -m,--mode=MODE Set sleep state (default: standby)" | 45 | //usage: "\n -m,--mode MODE Set sleep state (default: standby)" |
46 | //usage: "\n -s,--seconds=SEC Set timeout in SEC seconds from now" | 46 | //usage: "\n -s,--seconds SEC Set timeout in SEC seconds from now" |
47 | //usage: "\n -t,--time=TIME Set timeout to TIME seconds from epoch" | 47 | //usage: "\n -t,--time TIME Set timeout to TIME seconds from epoch" |
48 | //usage: ) | 48 | //usage: ) |
49 | //usage: IF_NOT_LONG_OPTS( | 49 | //usage: IF_NOT_LONG_OPTS( |
50 | //usage: "\n -a Read clock mode from adjtime" | 50 | //usage: "\n -a Read clock mode from adjtime" |
diff --git a/util-linux/setarch.c b/util-linux/setarch.c index ec473e9cb..e4124b044 100644 --- a/util-linux/setarch.c +++ b/util-linux/setarch.c | |||
@@ -31,6 +31,7 @@ | |||
31 | //config: Alias to "setarch linux64". | 31 | //config: Alias to "setarch linux64". |
32 | 32 | ||
33 | //applet:IF_SETARCH(APPLET(setarch, BB_DIR_BIN, BB_SUID_DROP)) | 33 | //applet:IF_SETARCH(APPLET(setarch, BB_DIR_BIN, BB_SUID_DROP)) |
34 | // APPLET_ODDNAME:name main location suid_type help | ||
34 | //applet:IF_LINUX32(APPLET_ODDNAME(linux32, setarch, BB_DIR_BIN, BB_SUID_DROP, linux32)) | 35 | //applet:IF_LINUX32(APPLET_ODDNAME(linux32, setarch, BB_DIR_BIN, BB_SUID_DROP, linux32)) |
35 | //applet:IF_LINUX64(APPLET_ODDNAME(linux64, setarch, BB_DIR_BIN, BB_SUID_DROP, linux64)) | 36 | //applet:IF_LINUX64(APPLET_ODDNAME(linux64, setarch, BB_DIR_BIN, BB_SUID_DROP, linux64)) |
36 | 37 | ||
diff --git a/util-linux/swaponoff.c b/util-linux/swaponoff.c index b8f4e9447..313ea0ef9 100644 --- a/util-linux/swaponoff.c +++ b/util-linux/swaponoff.c | |||
@@ -41,7 +41,8 @@ | |||
41 | //config: help | 41 | //config: help |
42 | //config: This option enables the 'swapoff' utility. | 42 | //config: This option enables the 'swapoff' utility. |
43 | 43 | ||
44 | //applet:IF_SWAPON(APPLET_ODDNAME(swapon, swap_on_off, BB_DIR_SBIN, BB_SUID_DROP, swapon)) | 44 | // APPLET_ODDNAME:name main location suid_type help |
45 | //applet:IF_SWAPON( APPLET_ODDNAME(swapon, swap_on_off, BB_DIR_SBIN, BB_SUID_DROP, swapon)) | ||
45 | //applet:IF_SWAPOFF(APPLET_ODDNAME(swapoff, swap_on_off, BB_DIR_SBIN, BB_SUID_DROP, swapoff)) | 46 | //applet:IF_SWAPOFF(APPLET_ODDNAME(swapoff, swap_on_off, BB_DIR_SBIN, BB_SUID_DROP, swapoff)) |
46 | 47 | ||
47 | //kbuild:lib-$(CONFIG_SWAPON) += swaponoff.o | 48 | //kbuild:lib-$(CONFIG_SWAPON) += swaponoff.o |
diff --git a/util-linux/umount.c b/util-linux/umount.c index 78eef57a5..c958fd552 100644 --- a/util-linux/umount.c +++ b/util-linux/umount.c | |||
@@ -125,8 +125,8 @@ int umount_main(int argc UNUSED_PARAM, char **argv) | |||
125 | } else { | 125 | } else { |
126 | setup_common_bufsiz(); | 126 | setup_common_bufsiz(); |
127 | while (getmntent_r(fp, &me, bb_common_bufsiz1, COMMON_BUFSIZE)) { | 127 | while (getmntent_r(fp, &me, bb_common_bufsiz1, COMMON_BUFSIZE)) { |
128 | /* Match fstype if passed */ | 128 | /* Match fstype (fstype==NULL matches always) */ |
129 | if (!match_fstype(&me, fstype)) | 129 | if (!fstype_matches(me.mnt_type, fstype)) |
130 | continue; | 130 | continue; |
131 | m = xzalloc(sizeof(*m)); | 131 | m = xzalloc(sizeof(*m)); |
132 | m->next = mtl; | 132 | m->next = mtl; |
diff --git a/util-linux/unshare.c b/util-linux/unshare.c index bbabeef55..52e8f1421 100644 --- a/util-linux/unshare.c +++ b/util-linux/unshare.c | |||
@@ -25,14 +25,14 @@ | |||
25 | //usage:#define unshare_trivial_usage | 25 | //usage:#define unshare_trivial_usage |
26 | //usage: "[OPTIONS] [PROG [ARGS]]" | 26 | //usage: "[OPTIONS] [PROG [ARGS]]" |
27 | //usage:#define unshare_full_usage "\n" | 27 | //usage:#define unshare_full_usage "\n" |
28 | //usage: "\n -m, --mount[=FILE] Unshare mount namespace" | 28 | //usage: "\n -m,--mount[=FILE] Unshare mount namespace" |
29 | //usage: "\n -u, --uts[=FILE] Unshare UTS namespace (hostname etc.)" | 29 | //usage: "\n -u,--uts[=FILE] Unshare UTS namespace (hostname etc.)" |
30 | //usage: "\n -i, --ipc[=FILE] Unshare System V IPC namespace" | 30 | //usage: "\n -i,--ipc[=FILE] Unshare System V IPC namespace" |
31 | //usage: "\n -n, --net[=FILE] Unshare network namespace" | 31 | //usage: "\n -n,--net[=FILE] Unshare network namespace" |
32 | //usage: "\n -p, --pid[=FILE] Unshare PID namespace" | 32 | //usage: "\n -p,--pid[=FILE] Unshare PID namespace" |
33 | //usage: "\n -U, --user[=FILE} Unshare user namespace" | 33 | //usage: "\n -U,--user[=FILE] Unshare user namespace" |
34 | //usage: "\n -f, --fork Fork before execing PROG" | 34 | //usage: "\n -f,--fork Fork before execing PROG" |
35 | //usage: "\n -r, --map-root-user Map current user to root (implies -u)" | 35 | //usage: "\n -r,--map-root-user Map current user to root (implies -u)" |
36 | //usage: "\n --mount-proc[=DIR] Mount /proc filesystem first (implies -m)" | 36 | //usage: "\n --mount-proc[=DIR] Mount /proc filesystem first (implies -m)" |
37 | //usage: "\n --propagation slave|shared|private|unchanged" | 37 | //usage: "\n --propagation slave|shared|private|unchanged" |
38 | //usage: "\n Modify mount propagation in mount namespace" | 38 | //usage: "\n Modify mount propagation in mount namespace" |
diff --git a/util-linux/volume_id/bcache.c b/util-linux/volume_id/bcache.c index fd40eb081..334a341c3 100644 --- a/util-linux/volume_id/bcache.c +++ b/util-linux/volume_id/bcache.c | |||
@@ -10,14 +10,10 @@ | |||
10 | 10 | ||
11 | //kbuild:lib-$(CONFIG_FEATURE_VOLUMEID_BCACHE) += bcache.o | 11 | //kbuild:lib-$(CONFIG_FEATURE_VOLUMEID_BCACHE) += bcache.o |
12 | 12 | ||
13 | //config: | ||
14 | //config:config FEATURE_VOLUMEID_BCACHE | 13 | //config:config FEATURE_VOLUMEID_BCACHE |
15 | //config: bool "bcache filesystem" | 14 | //config: bool "bcache filesystem" |
16 | //config: default y | 15 | //config: default y |
17 | //config: depends on VOLUMEID | 16 | //config: depends on VOLUMEID |
18 | //config: help | ||
19 | //config: TODO | ||
20 | //config: | ||
21 | 17 | ||
22 | #include "volume_id_internal.h" | 18 | #include "volume_id_internal.h" |
23 | 19 | ||
diff --git a/util-linux/volume_id/btrfs.c b/util-linux/volume_id/btrfs.c index e4dddf26d..338a48762 100644 --- a/util-linux/volume_id/btrfs.c +++ b/util-linux/volume_id/btrfs.c | |||
@@ -21,14 +21,10 @@ | |||
21 | 21 | ||
22 | //kbuild:lib-$(CONFIG_FEATURE_VOLUMEID_BTRFS) += btrfs.o | 22 | //kbuild:lib-$(CONFIG_FEATURE_VOLUMEID_BTRFS) += btrfs.o |
23 | 23 | ||
24 | //config: | ||
25 | //config:config FEATURE_VOLUMEID_BTRFS | 24 | //config:config FEATURE_VOLUMEID_BTRFS |
26 | //config: bool "btrfs filesystem" | 25 | //config: bool "btrfs filesystem" |
27 | //config: default y | 26 | //config: default y |
28 | //config: depends on VOLUMEID | 27 | //config: depends on VOLUMEID |
29 | //config: help | ||
30 | //config: TODO | ||
31 | //config: | ||
32 | 28 | ||
33 | #include "volume_id_internal.h" | 29 | #include "volume_id_internal.h" |
34 | 30 | ||
diff --git a/util-linux/volume_id/cramfs.c b/util-linux/volume_id/cramfs.c index aeb7f20ac..c63223e2b 100644 --- a/util-linux/volume_id/cramfs.c +++ b/util-linux/volume_id/cramfs.c | |||
@@ -20,14 +20,10 @@ | |||
20 | 20 | ||
21 | //kbuild:lib-$(CONFIG_FEATURE_VOLUMEID_CRAMFS) += cramfs.o | 21 | //kbuild:lib-$(CONFIG_FEATURE_VOLUMEID_CRAMFS) += cramfs.o |
22 | 22 | ||
23 | //config: | ||
24 | //config:config FEATURE_VOLUMEID_CRAMFS | 23 | //config:config FEATURE_VOLUMEID_CRAMFS |
25 | //config: bool "cramfs filesystem" | 24 | //config: bool "cramfs filesystem" |
26 | //config: default y | 25 | //config: default y |
27 | //config: depends on VOLUMEID | 26 | //config: depends on VOLUMEID |
28 | //config: help | ||
29 | //config: TODO | ||
30 | //config: | ||
31 | 27 | ||
32 | #include "volume_id_internal.h" | 28 | #include "volume_id_internal.h" |
33 | 29 | ||
diff --git a/util-linux/volume_id/exfat.c b/util-linux/volume_id/exfat.c index c3aa36804..7ed13a70e 100644 --- a/util-linux/volume_id/exfat.c +++ b/util-linux/volume_id/exfat.c | |||
@@ -20,7 +20,6 @@ | |||
20 | 20 | ||
21 | //kbuild:lib-$(CONFIG_FEATURE_VOLUMEID_EXFAT) += exfat.o | 21 | //kbuild:lib-$(CONFIG_FEATURE_VOLUMEID_EXFAT) += exfat.o |
22 | 22 | ||
23 | //config: | ||
24 | //config:config FEATURE_VOLUMEID_EXFAT | 23 | //config:config FEATURE_VOLUMEID_EXFAT |
25 | //config: bool "exFAT filesystem" | 24 | //config: bool "exFAT filesystem" |
26 | //config: default y | 25 | //config: default y |
@@ -29,7 +28,6 @@ | |||
29 | //config: exFAT (extended FAT) is a proprietary file system designed especially | 28 | //config: exFAT (extended FAT) is a proprietary file system designed especially |
30 | //config: for flash drives. It has many features from NTFS, but with less | 29 | //config: for flash drives. It has many features from NTFS, but with less |
31 | //config: overhead. exFAT is used on most SDXC cards for consumer electronics. | 30 | //config: overhead. exFAT is used on most SDXC cards for consumer electronics. |
32 | //config: | ||
33 | 31 | ||
34 | #include "volume_id_internal.h" | 32 | #include "volume_id_internal.h" |
35 | 33 | ||
diff --git a/util-linux/volume_id/ext.c b/util-linux/volume_id/ext.c index df39d9342..473b3229a 100644 --- a/util-linux/volume_id/ext.c +++ b/util-linux/volume_id/ext.c | |||
@@ -20,14 +20,10 @@ | |||
20 | 20 | ||
21 | //kbuild:lib-$(CONFIG_FEATURE_VOLUMEID_EXT) += ext.o | 21 | //kbuild:lib-$(CONFIG_FEATURE_VOLUMEID_EXT) += ext.o |
22 | 22 | ||
23 | //config: | ||
24 | //config:config FEATURE_VOLUMEID_EXT | 23 | //config:config FEATURE_VOLUMEID_EXT |
25 | //config: bool "Ext filesystem" | 24 | //config: bool "Ext filesystem" |
26 | //config: default y | 25 | //config: default y |
27 | //config: depends on VOLUMEID | 26 | //config: depends on VOLUMEID |
28 | //config: help | ||
29 | //config: TODO | ||
30 | //config: | ||
31 | 27 | ||
32 | #include "volume_id_internal.h" | 28 | #include "volume_id_internal.h" |
33 | #include "bb_e2fs_defs.h" | 29 | #include "bb_e2fs_defs.h" |
diff --git a/util-linux/volume_id/f2fs.c b/util-linux/volume_id/f2fs.c index bf0b66278..1d3bdae36 100644 --- a/util-linux/volume_id/f2fs.c +++ b/util-linux/volume_id/f2fs.c | |||
@@ -8,7 +8,6 @@ | |||
8 | 8 | ||
9 | //kbuild:lib-$(CONFIG_FEATURE_VOLUMEID_F2FS) += f2fs.o | 9 | //kbuild:lib-$(CONFIG_FEATURE_VOLUMEID_F2FS) += f2fs.o |
10 | 10 | ||
11 | //config: | ||
12 | //config:config FEATURE_VOLUMEID_F2FS | 11 | //config:config FEATURE_VOLUMEID_F2FS |
13 | //config: bool "f2fs filesystem" | 12 | //config: bool "f2fs filesystem" |
14 | //config: default y | 13 | //config: default y |
@@ -18,7 +17,6 @@ | |||
18 | //config: which is adapted to newer forms of storage. F2FS also remedies some | 17 | //config: which is adapted to newer forms of storage. F2FS also remedies some |
19 | //config: known issues of the older log structured file systems, such as high | 18 | //config: known issues of the older log structured file systems, such as high |
20 | //config: cleaning overhead. | 19 | //config: cleaning overhead. |
21 | //config: | ||
22 | 20 | ||
23 | #include "volume_id_internal.h" | 21 | #include "volume_id_internal.h" |
24 | 22 | ||
diff --git a/util-linux/volume_id/fat.c b/util-linux/volume_id/fat.c index 476d500a6..bc3433daf 100644 --- a/util-linux/volume_id/fat.c +++ b/util-linux/volume_id/fat.c | |||
@@ -20,14 +20,10 @@ | |||
20 | 20 | ||
21 | //kbuild:lib-$(CONFIG_FEATURE_VOLUMEID_FAT) += fat.o | 21 | //kbuild:lib-$(CONFIG_FEATURE_VOLUMEID_FAT) += fat.o |
22 | 22 | ||
23 | //config: | ||
24 | //config:config FEATURE_VOLUMEID_FAT | 23 | //config:config FEATURE_VOLUMEID_FAT |
25 | //config: bool "fat filesystem" | 24 | //config: bool "fat filesystem" |
26 | //config: default y | 25 | //config: default y |
27 | //config: depends on VOLUMEID | 26 | //config: depends on VOLUMEID |
28 | //config: help | ||
29 | //config: TODO | ||
30 | //config: | ||
31 | 27 | ||
32 | #include "volume_id_internal.h" | 28 | #include "volume_id_internal.h" |
33 | 29 | ||
diff --git a/util-linux/volume_id/hfs.c b/util-linux/volume_id/hfs.c index 8d34aaf68..78dae0790 100644 --- a/util-linux/volume_id/hfs.c +++ b/util-linux/volume_id/hfs.c | |||
@@ -20,14 +20,10 @@ | |||
20 | 20 | ||
21 | //kbuild:lib-$(CONFIG_FEATURE_VOLUMEID_HFS) += hfs.o | 21 | //kbuild:lib-$(CONFIG_FEATURE_VOLUMEID_HFS) += hfs.o |
22 | 22 | ||
23 | //config: | ||
24 | //config:config FEATURE_VOLUMEID_HFS | 23 | //config:config FEATURE_VOLUMEID_HFS |
25 | //config: bool "hfs filesystem" | 24 | //config: bool "hfs filesystem" |
26 | //config: default y | 25 | //config: default y |
27 | //config: depends on VOLUMEID | 26 | //config: depends on VOLUMEID |
28 | //config: help | ||
29 | //config: TODO | ||
30 | //config: | ||
31 | 27 | ||
32 | #include "volume_id_internal.h" | 28 | #include "volume_id_internal.h" |
33 | 29 | ||
diff --git a/util-linux/volume_id/iso9660.c b/util-linux/volume_id/iso9660.c index 3848de453..23072f87c 100644 --- a/util-linux/volume_id/iso9660.c +++ b/util-linux/volume_id/iso9660.c | |||
@@ -20,14 +20,10 @@ | |||
20 | 20 | ||
21 | //kbuild:lib-$(CONFIG_FEATURE_VOLUMEID_ISO9660) += iso9660.o | 21 | //kbuild:lib-$(CONFIG_FEATURE_VOLUMEID_ISO9660) += iso9660.o |
22 | 22 | ||
23 | //config: | ||
24 | //config:config FEATURE_VOLUMEID_ISO9660 | 23 | //config:config FEATURE_VOLUMEID_ISO9660 |
25 | //config: bool "iso9660 filesystem" | 24 | //config: bool "iso9660 filesystem" |
26 | //config: default y | 25 | //config: default y |
27 | //config: depends on VOLUMEID | 26 | //config: depends on VOLUMEID |
28 | //config: help | ||
29 | //config: TODO | ||
30 | //config: | ||
31 | 27 | ||
32 | #include "volume_id_internal.h" | 28 | #include "volume_id_internal.h" |
33 | 29 | ||
diff --git a/util-linux/volume_id/jfs.c b/util-linux/volume_id/jfs.c index a6eaff45b..543d90fe5 100644 --- a/util-linux/volume_id/jfs.c +++ b/util-linux/volume_id/jfs.c | |||
@@ -20,14 +20,10 @@ | |||
20 | 20 | ||
21 | //kbuild:lib-$(CONFIG_FEATURE_VOLUMEID_JFS) += jfs.o | 21 | //kbuild:lib-$(CONFIG_FEATURE_VOLUMEID_JFS) += jfs.o |
22 | 22 | ||
23 | //config: | ||
24 | //config:config FEATURE_VOLUMEID_JFS | 23 | //config:config FEATURE_VOLUMEID_JFS |
25 | //config: bool "jfs filesystem" | 24 | //config: bool "jfs filesystem" |
26 | //config: default y | 25 | //config: default y |
27 | //config: depends on VOLUMEID | 26 | //config: depends on VOLUMEID |
28 | //config: help | ||
29 | //config: TODO | ||
30 | //config: | ||
31 | 27 | ||
32 | #include "volume_id_internal.h" | 28 | #include "volume_id_internal.h" |
33 | 29 | ||
diff --git a/util-linux/volume_id/linux_raid.c b/util-linux/volume_id/linux_raid.c index f20823a6e..0db6e8662 100644 --- a/util-linux/volume_id/linux_raid.c +++ b/util-linux/volume_id/linux_raid.c | |||
@@ -20,14 +20,10 @@ | |||
20 | 20 | ||
21 | //kbuild:lib-$(CONFIG_FEATURE_VOLUMEID_LINUXRAID) += linux_raid.o | 21 | //kbuild:lib-$(CONFIG_FEATURE_VOLUMEID_LINUXRAID) += linux_raid.o |
22 | 22 | ||
23 | //config: | ||
24 | //config:config FEATURE_VOLUMEID_LINUXRAID | 23 | //config:config FEATURE_VOLUMEID_LINUXRAID |
25 | //config: bool "linuxraid" | 24 | //config: bool "linuxraid" |
26 | //config: default y | 25 | //config: default y |
27 | //config: depends on VOLUMEID | 26 | //config: depends on VOLUMEID |
28 | //config: help | ||
29 | //config: TODO | ||
30 | //config: | ||
31 | 27 | ||
32 | #include "volume_id_internal.h" | 28 | #include "volume_id_internal.h" |
33 | 29 | ||
diff --git a/util-linux/volume_id/linux_swap.c b/util-linux/volume_id/linux_swap.c index 39470d48c..a35769dfc 100644 --- a/util-linux/volume_id/linux_swap.c +++ b/util-linux/volume_id/linux_swap.c | |||
@@ -20,14 +20,10 @@ | |||
20 | 20 | ||
21 | //kbuild:lib-$(CONFIG_FEATURE_VOLUMEID_LINUXSWAP) += linux_swap.o | 21 | //kbuild:lib-$(CONFIG_FEATURE_VOLUMEID_LINUXSWAP) += linux_swap.o |
22 | 22 | ||
23 | //config: | ||
24 | //config:config FEATURE_VOLUMEID_LINUXSWAP | 23 | //config:config FEATURE_VOLUMEID_LINUXSWAP |
25 | //config: bool "linux swap filesystem" | 24 | //config: bool "linux swap filesystem" |
26 | //config: default y | 25 | //config: default y |
27 | //config: depends on VOLUMEID | 26 | //config: depends on VOLUMEID |
28 | //config: help | ||
29 | //config: TODO | ||
30 | //config: | ||
31 | 27 | ||
32 | #include "volume_id_internal.h" | 28 | #include "volume_id_internal.h" |
33 | 29 | ||
diff --git a/util-linux/volume_id/luks.c b/util-linux/volume_id/luks.c index 21cb26f51..4b80b7a6d 100644 --- a/util-linux/volume_id/luks.c +++ b/util-linux/volume_id/luks.c | |||
@@ -20,14 +20,10 @@ | |||
20 | 20 | ||
21 | //kbuild:lib-$(CONFIG_FEATURE_VOLUMEID_LUKS) += luks.o | 21 | //kbuild:lib-$(CONFIG_FEATURE_VOLUMEID_LUKS) += luks.o |
22 | 22 | ||
23 | //config: | ||
24 | //config:config FEATURE_VOLUMEID_LUKS | 23 | //config:config FEATURE_VOLUMEID_LUKS |
25 | //config: bool "luks filesystem" | 24 | //config: bool "luks filesystem" |
26 | //config: default y | 25 | //config: default y |
27 | //config: depends on VOLUMEID | 26 | //config: depends on VOLUMEID |
28 | //config: help | ||
29 | //config: TODO | ||
30 | //config: | ||
31 | 27 | ||
32 | #include "volume_id_internal.h" | 28 | #include "volume_id_internal.h" |
33 | 29 | ||
diff --git a/util-linux/volume_id/nilfs.c b/util-linux/volume_id/nilfs.c index f3a9ef58d..ffe919f36 100644 --- a/util-linux/volume_id/nilfs.c +++ b/util-linux/volume_id/nilfs.c | |||
@@ -21,7 +21,6 @@ | |||
21 | 21 | ||
22 | //kbuild:lib-$(CONFIG_FEATURE_VOLUMEID_NILFS) += nilfs.o | 22 | //kbuild:lib-$(CONFIG_FEATURE_VOLUMEID_NILFS) += nilfs.o |
23 | 23 | ||
24 | //config: | ||
25 | //config:config FEATURE_VOLUMEID_NILFS | 24 | //config:config FEATURE_VOLUMEID_NILFS |
26 | //config: bool "nilfs filesystem" | 25 | //config: bool "nilfs filesystem" |
27 | //config: default y | 26 | //config: default y |
@@ -37,7 +36,6 @@ | |||
37 | //config: SOX compliance logging, and so forth. It can serve as an alternative | 36 | //config: SOX compliance logging, and so forth. It can serve as an alternative |
38 | //config: filesystem for Linux desktop environment, or as a basis of advanced | 37 | //config: filesystem for Linux desktop environment, or as a basis of advanced |
39 | //config: storage appliances. | 38 | //config: storage appliances. |
40 | //config: | ||
41 | 39 | ||
42 | #include "volume_id_internal.h" | 40 | #include "volume_id_internal.h" |
43 | 41 | ||
diff --git a/util-linux/volume_id/ntfs.c b/util-linux/volume_id/ntfs.c index 46f687a56..bf85f7ed3 100644 --- a/util-linux/volume_id/ntfs.c +++ b/util-linux/volume_id/ntfs.c | |||
@@ -20,14 +20,10 @@ | |||
20 | 20 | ||
21 | //kbuild:lib-$(CONFIG_FEATURE_VOLUMEID_NTFS) += ntfs.o | 21 | //kbuild:lib-$(CONFIG_FEATURE_VOLUMEID_NTFS) += ntfs.o |
22 | 22 | ||
23 | //config: | ||
24 | //config:config FEATURE_VOLUMEID_NTFS | 23 | //config:config FEATURE_VOLUMEID_NTFS |
25 | //config: bool "ntfs filesystem" | 24 | //config: bool "ntfs filesystem" |
26 | //config: default y | 25 | //config: default y |
27 | //config: depends on VOLUMEID | 26 | //config: depends on VOLUMEID |
28 | //config: help | ||
29 | //config: TODO | ||
30 | //config: | ||
31 | 27 | ||
32 | #include "volume_id_internal.h" | 28 | #include "volume_id_internal.h" |
33 | 29 | ||
diff --git a/util-linux/volume_id/ocfs2.c b/util-linux/volume_id/ocfs2.c index 415e0bf61..2dedac98b 100644 --- a/util-linux/volume_id/ocfs2.c +++ b/util-linux/volume_id/ocfs2.c | |||
@@ -20,14 +20,10 @@ | |||
20 | 20 | ||
21 | //kbuild:lib-$(CONFIG_FEATURE_VOLUMEID_OCFS2) += ocfs2.o | 21 | //kbuild:lib-$(CONFIG_FEATURE_VOLUMEID_OCFS2) += ocfs2.o |
22 | 22 | ||
23 | //config: | ||
24 | //config:config FEATURE_VOLUMEID_OCFS2 | 23 | //config:config FEATURE_VOLUMEID_OCFS2 |
25 | //config: bool "ocfs2 filesystem" | 24 | //config: bool "ocfs2 filesystem" |
26 | //config: default y | 25 | //config: default y |
27 | //config: depends on VOLUMEID | 26 | //config: depends on VOLUMEID |
28 | //config: help | ||
29 | //config: TODO | ||
30 | //config: | ||
31 | 27 | ||
32 | #include "volume_id_internal.h" | 28 | #include "volume_id_internal.h" |
33 | 29 | ||
diff --git a/util-linux/volume_id/reiserfs.c b/util-linux/volume_id/reiserfs.c index 24979fb1c..369d4d9bb 100644 --- a/util-linux/volume_id/reiserfs.c +++ b/util-linux/volume_id/reiserfs.c | |||
@@ -21,14 +21,10 @@ | |||
21 | 21 | ||
22 | //kbuild:lib-$(CONFIG_FEATURE_VOLUMEID_REISERFS) += reiserfs.o | 22 | //kbuild:lib-$(CONFIG_FEATURE_VOLUMEID_REISERFS) += reiserfs.o |
23 | 23 | ||
24 | //config: | ||
25 | //config:config FEATURE_VOLUMEID_REISERFS | 24 | //config:config FEATURE_VOLUMEID_REISERFS |
26 | //config: bool "Reiser filesystem" | 25 | //config: bool "Reiser filesystem" |
27 | //config: default y | 26 | //config: default y |
28 | //config: depends on VOLUMEID | 27 | //config: depends on VOLUMEID |
29 | //config: help | ||
30 | //config: TODO | ||
31 | //config: | ||
32 | 28 | ||
33 | #include "volume_id_internal.h" | 29 | #include "volume_id_internal.h" |
34 | 30 | ||
diff --git a/util-linux/volume_id/romfs.c b/util-linux/volume_id/romfs.c index 4754fdb37..95a65f9ef 100644 --- a/util-linux/volume_id/romfs.c +++ b/util-linux/volume_id/romfs.c | |||
@@ -20,14 +20,10 @@ | |||
20 | 20 | ||
21 | //kbuild:lib-$(CONFIG_FEATURE_VOLUMEID_ROMFS) += romfs.o | 21 | //kbuild:lib-$(CONFIG_FEATURE_VOLUMEID_ROMFS) += romfs.o |
22 | 22 | ||
23 | //config: | ||
24 | //config:config FEATURE_VOLUMEID_ROMFS | 23 | //config:config FEATURE_VOLUMEID_ROMFS |
25 | //config: bool "romfs filesystem" | 24 | //config: bool "romfs filesystem" |
26 | //config: default y | 25 | //config: default y |
27 | //config: depends on VOLUMEID | 26 | //config: depends on VOLUMEID |
28 | //config: help | ||
29 | //config: TODO | ||
30 | //config: | ||
31 | 27 | ||
32 | #include "volume_id_internal.h" | 28 | #include "volume_id_internal.h" |
33 | 29 | ||
diff --git a/util-linux/volume_id/squashfs.c b/util-linux/volume_id/squashfs.c index 079b6cc31..6bba199cd 100644 --- a/util-linux/volume_id/squashfs.c +++ b/util-linux/volume_id/squashfs.c | |||
@@ -8,7 +8,6 @@ | |||
8 | 8 | ||
9 | //kbuild:lib-$(CONFIG_FEATURE_VOLUMEID_SQUASHFS) += squashfs.o | 9 | //kbuild:lib-$(CONFIG_FEATURE_VOLUMEID_SQUASHFS) += squashfs.o |
10 | 10 | ||
11 | //config: | ||
12 | //config:config FEATURE_VOLUMEID_SQUASHFS | 11 | //config:config FEATURE_VOLUMEID_SQUASHFS |
13 | //config: bool "SquashFS filesystem" | 12 | //config: bool "SquashFS filesystem" |
14 | //config: default y | 13 | //config: default y |
@@ -18,7 +17,6 @@ | |||
18 | //config: intended for general read-only filesystem use and in constrained block | 17 | //config: intended for general read-only filesystem use and in constrained block |
19 | //config: device/memory systems (e.g. embedded systems) where low overhead is | 18 | //config: device/memory systems (e.g. embedded systems) where low overhead is |
20 | //config: needed. | 19 | //config: needed. |
21 | //config: | ||
22 | 20 | ||
23 | #include "volume_id_internal.h" | 21 | #include "volume_id_internal.h" |
24 | 22 | ||
diff --git a/util-linux/volume_id/sysv.c b/util-linux/volume_id/sysv.c index 7b4b5360b..cd4cd906b 100644 --- a/util-linux/volume_id/sysv.c +++ b/util-linux/volume_id/sysv.c | |||
@@ -20,14 +20,10 @@ | |||
20 | 20 | ||
21 | //kbuild:lib-$(CONFIG_FEATURE_VOLUMEID_SYSV) += sysv.o | 21 | //kbuild:lib-$(CONFIG_FEATURE_VOLUMEID_SYSV) += sysv.o |
22 | 22 | ||
23 | //config: | ||
24 | //config:config FEATURE_VOLUMEID_SYSV | 23 | //config:config FEATURE_VOLUMEID_SYSV |
25 | //config: bool "sysv filesystem" | 24 | //config: bool "sysv filesystem" |
26 | //config: default y | 25 | //config: default y |
27 | //config: depends on VOLUMEID | 26 | //config: depends on VOLUMEID |
28 | //config: help | ||
29 | //config: TODO | ||
30 | //config: | ||
31 | 27 | ||
32 | #include "volume_id_internal.h" | 28 | #include "volume_id_internal.h" |
33 | 29 | ||
diff --git a/util-linux/volume_id/ubifs.c b/util-linux/volume_id/ubifs.c index 13604ec35..99b0aa830 100644 --- a/util-linux/volume_id/ubifs.c +++ b/util-linux/volume_id/ubifs.c | |||
@@ -8,7 +8,6 @@ | |||
8 | 8 | ||
9 | //kbuild:lib-$(CONFIG_FEATURE_VOLUMEID_UBIFS) += ubifs.o | 9 | //kbuild:lib-$(CONFIG_FEATURE_VOLUMEID_UBIFS) += ubifs.o |
10 | 10 | ||
11 | //config: | ||
12 | //config:config FEATURE_VOLUMEID_UBIFS | 11 | //config:config FEATURE_VOLUMEID_UBIFS |
13 | //config: bool "UBIFS filesystem" | 12 | //config: bool "UBIFS filesystem" |
14 | //config: default y | 13 | //config: default y |
@@ -16,7 +15,6 @@ | |||
16 | //config: help | 15 | //config: help |
17 | //config: UBIFS (Unsorted Block Image File System) is a file | 16 | //config: UBIFS (Unsorted Block Image File System) is a file |
18 | //config: system for use with raw flash memory media. | 17 | //config: system for use with raw flash memory media. |
19 | //config: | ||
20 | 18 | ||
21 | #include "volume_id_internal.h" | 19 | #include "volume_id_internal.h" |
22 | 20 | ||
diff --git a/util-linux/volume_id/udf.c b/util-linux/volume_id/udf.c index 921454503..613c80c86 100644 --- a/util-linux/volume_id/udf.c +++ b/util-linux/volume_id/udf.c | |||
@@ -20,14 +20,10 @@ | |||
20 | 20 | ||
21 | //kbuild:lib-$(CONFIG_FEATURE_VOLUMEID_UDF) += udf.o | 21 | //kbuild:lib-$(CONFIG_FEATURE_VOLUMEID_UDF) += udf.o |
22 | 22 | ||
23 | //config: | ||
24 | //config:config FEATURE_VOLUMEID_UDF | 23 | //config:config FEATURE_VOLUMEID_UDF |
25 | //config: bool "udf filesystem" | 24 | //config: bool "udf filesystem" |
26 | //config: default y | 25 | //config: default y |
27 | //config: depends on VOLUMEID | 26 | //config: depends on VOLUMEID |
28 | //config: help | ||
29 | //config: TODO | ||
30 | //config: | ||
31 | 27 | ||
32 | #include "volume_id_internal.h" | 28 | #include "volume_id_internal.h" |
33 | 29 | ||
diff --git a/util-linux/volume_id/unused_highpoint.c b/util-linux/volume_id/unused_highpoint.c index 7231a1db2..4afa6d927 100644 --- a/util-linux/volume_id/unused_highpoint.c +++ b/util-linux/volume_id/unused_highpoint.c | |||
@@ -20,14 +20,10 @@ | |||
20 | 20 | ||
21 | //kbuild:### lib-$(CONFIG_FEATURE_VOLUMEID_HIGHPOINTRAID) += highpoint.o | 21 | //kbuild:### lib-$(CONFIG_FEATURE_VOLUMEID_HIGHPOINTRAID) += highpoint.o |
22 | 22 | ||
23 | //config: | ||
24 | //config:### config FEATURE_VOLUMEID_HIGHPOINTRAID | 23 | //config:### config FEATURE_VOLUMEID_HIGHPOINTRAID |
25 | //config:### bool "highpoint raid" | 24 | //config:### bool "highpoint raid" |
26 | //config:### default y | 25 | //config:### default y |
27 | //config:### depends on VOLUMEID | 26 | //config:### depends on VOLUMEID |
28 | //config:### help | ||
29 | //config:### TODO | ||
30 | //config: | ||
31 | 27 | ||
32 | #include "volume_id_internal.h" | 28 | #include "volume_id_internal.h" |
33 | 29 | ||
diff --git a/util-linux/volume_id/unused_hpfs.c b/util-linux/volume_id/unused_hpfs.c index a87c89fb3..3e16dedbd 100644 --- a/util-linux/volume_id/unused_hpfs.c +++ b/util-linux/volume_id/unused_hpfs.c | |||
@@ -20,14 +20,10 @@ | |||
20 | 20 | ||
21 | //kbuild:### lib-$(CONFIG_FEATURE_VOLUMEID_HPFS) += hpfs.o | 21 | //kbuild:### lib-$(CONFIG_FEATURE_VOLUMEID_HPFS) += hpfs.o |
22 | 22 | ||
23 | //config: | ||
24 | //config:### config FEATURE_VOLUMEID_HPFS | 23 | //config:### config FEATURE_VOLUMEID_HPFS |
25 | //config:### bool "hpfs filesystem" | 24 | //config:### bool "hpfs filesystem" |
26 | //config:### default y | 25 | //config:### default y |
27 | //config:### depends on VOLUMEID | 26 | //config:### depends on VOLUMEID |
28 | //config:### help | ||
29 | //config:### TODO | ||
30 | //config: | ||
31 | 27 | ||
32 | #include "volume_id_internal.h" | 28 | #include "volume_id_internal.h" |
33 | 29 | ||
diff --git a/util-linux/volume_id/unused_isw_raid.c b/util-linux/volume_id/unused_isw_raid.c index 851bd2f8f..fba99be58 100644 --- a/util-linux/volume_id/unused_isw_raid.c +++ b/util-linux/volume_id/unused_isw_raid.c | |||
@@ -20,14 +20,10 @@ | |||
20 | 20 | ||
21 | //kbuild:### lib-$(CONFIG_FEATURE_VOLUMEID_ISWRAID) += isw_raid.o | 21 | //kbuild:### lib-$(CONFIG_FEATURE_VOLUMEID_ISWRAID) += isw_raid.o |
22 | 22 | ||
23 | //config: | ||
24 | //config:### config FEATURE_VOLUMEID_ISWRAID | 23 | //config:### config FEATURE_VOLUMEID_ISWRAID |
25 | //config:### bool "intel raid" | 24 | //config:### bool "intel raid" |
26 | //config:### default y | 25 | //config:### default y |
27 | //config:### depends on VOLUMEID | 26 | //config:### depends on VOLUMEID |
28 | //config:### help | ||
29 | //config:### TODO | ||
30 | //config: | ||
31 | 27 | ||
32 | #include "volume_id_internal.h" | 28 | #include "volume_id_internal.h" |
33 | 29 | ||
diff --git a/util-linux/volume_id/unused_lsi_raid.c b/util-linux/volume_id/unused_lsi_raid.c index 52d68deab..9dd2b409c 100644 --- a/util-linux/volume_id/unused_lsi_raid.c +++ b/util-linux/volume_id/unused_lsi_raid.c | |||
@@ -20,14 +20,10 @@ | |||
20 | 20 | ||
21 | //kbuild:### lib-$(CONFIG_FEATURE_VOLUMEID_LSIRAID) += lsi_raid.o | 21 | //kbuild:### lib-$(CONFIG_FEATURE_VOLUMEID_LSIRAID) += lsi_raid.o |
22 | 22 | ||
23 | //config: | ||
24 | //config:### config FEATURE_VOLUMEID_LSIRAID | 23 | //config:### config FEATURE_VOLUMEID_LSIRAID |
25 | //config:### bool "lsi raid" | 24 | //config:### bool "lsi raid" |
26 | //config:### default y | 25 | //config:### default y |
27 | //config:### depends on VOLUMEID | 26 | //config:### depends on VOLUMEID |
28 | //config:### help | ||
29 | //config:### TODO | ||
30 | //config: | ||
31 | 27 | ||
32 | #include "volume_id_internal.h" | 28 | #include "volume_id_internal.h" |
33 | 29 | ||
diff --git a/util-linux/volume_id/unused_lvm.c b/util-linux/volume_id/unused_lvm.c index 08fa05243..5ad6d585c 100644 --- a/util-linux/volume_id/unused_lvm.c +++ b/util-linux/volume_id/unused_lvm.c | |||
@@ -20,14 +20,10 @@ | |||
20 | 20 | ||
21 | //kbuild:### lib-$(CONFIG_FEATURE_VOLUMEID_LVM) += lvm.o | 21 | //kbuild:### lib-$(CONFIG_FEATURE_VOLUMEID_LVM) += lvm.o |
22 | 22 | ||
23 | //config: | ||
24 | //config:### config FEATURE_VOLUMEID_LVM | 23 | //config:### config FEATURE_VOLUMEID_LVM |
25 | //config:### bool "lvm" | 24 | //config:### bool "lvm" |
26 | //config:### default y | 25 | //config:### default y |
27 | //config:### depends on VOLUMEID | 26 | //config:### depends on VOLUMEID |
28 | //config:### help | ||
29 | //config:### TODO | ||
30 | //config: | ||
31 | 27 | ||
32 | #include "volume_id_internal.h" | 28 | #include "volume_id_internal.h" |
33 | 29 | ||
diff --git a/util-linux/volume_id/unused_mac.c b/util-linux/volume_id/unused_mac.c index a1a53d1fb..997d330a4 100644 --- a/util-linux/volume_id/unused_mac.c +++ b/util-linux/volume_id/unused_mac.c | |||
@@ -20,14 +20,10 @@ | |||
20 | 20 | ||
21 | //kbuild:### lib-$(CONFIG_FEATURE_VOLUMEID_MAC) += mac.o | 21 | //kbuild:### lib-$(CONFIG_FEATURE_VOLUMEID_MAC) += mac.o |
22 | 22 | ||
23 | //config: | ||
24 | //config:### config FEATURE_VOLUMEID_MAC | 23 | //config:### config FEATURE_VOLUMEID_MAC |
25 | //config:### bool "mac filesystem" | 24 | //config:### bool "mac filesystem" |
26 | //config:### default y | 25 | //config:### default y |
27 | //config:### depends on VOLUMEID | 26 | //config:### depends on VOLUMEID |
28 | //config:### help | ||
29 | //config:### TODO | ||
30 | //config: | ||
31 | 27 | ||
32 | #include "volume_id_internal.h" | 28 | #include "volume_id_internal.h" |
33 | 29 | ||
diff --git a/util-linux/volume_id/unused_minix.c b/util-linux/volume_id/unused_minix.c index 50afd5c3e..443dbc272 100644 --- a/util-linux/volume_id/unused_minix.c +++ b/util-linux/volume_id/unused_minix.c | |||
@@ -20,14 +20,10 @@ | |||
20 | 20 | ||
21 | //kbuild:### lib-$(CONFIG_FEATURE_VOLUMEID_MINIX) += minix.o | 21 | //kbuild:### lib-$(CONFIG_FEATURE_VOLUMEID_MINIX) += minix.o |
22 | 22 | ||
23 | //config: | ||
24 | //config:### config FEATURE_VOLUMEID_MINIX | 23 | //config:### config FEATURE_VOLUMEID_MINIX |
25 | //config:### bool "minix filesystem" | 24 | //config:### bool "minix filesystem" |
26 | //config:### default y | 25 | //config:### default y |
27 | //config:### depends on VOLUMEID | 26 | //config:### depends on VOLUMEID |
28 | //config:### help | ||
29 | //config:### TODO | ||
30 | //config: | ||
31 | 27 | ||
32 | #include "volume_id_internal.h" | 28 | #include "volume_id_internal.h" |
33 | 29 | ||
diff --git a/util-linux/volume_id/unused_msdos.c b/util-linux/volume_id/unused_msdos.c index 5ebaa3eef..f84c0f06f 100644 --- a/util-linux/volume_id/unused_msdos.c +++ b/util-linux/volume_id/unused_msdos.c | |||
@@ -20,14 +20,10 @@ | |||
20 | 20 | ||
21 | //kbuild:### lib-$(CONFIG_FEATURE_VOLUMEID_MSDOS) += msdos.o | 21 | //kbuild:### lib-$(CONFIG_FEATURE_VOLUMEID_MSDOS) += msdos.o |
22 | 22 | ||
23 | //config: | ||
24 | //config:### config FEATURE_VOLUMEID_MSDOS | 23 | //config:### config FEATURE_VOLUMEID_MSDOS |
25 | //config:### bool "msdos filesystem" | 24 | //config:### bool "msdos filesystem" |
26 | //config:### default y | 25 | //config:### default y |
27 | //config:### depends on VOLUMEID | 26 | //config:### depends on VOLUMEID |
28 | //config:### help | ||
29 | //config:### TODO | ||
30 | //config: | ||
31 | 27 | ||
32 | #include "volume_id_internal.h" | 28 | #include "volume_id_internal.h" |
33 | 29 | ||
diff --git a/util-linux/volume_id/unused_nvidia_raid.c b/util-linux/volume_id/unused_nvidia_raid.c index d99a108f3..dfb54fa9d 100644 --- a/util-linux/volume_id/unused_nvidia_raid.c +++ b/util-linux/volume_id/unused_nvidia_raid.c | |||
@@ -20,14 +20,10 @@ | |||
20 | 20 | ||
21 | //kbuild:### lib-$(CONFIG_FEATURE_VOLUMEID_NVIDIARAID) += nvidia_raid.o | 21 | //kbuild:### lib-$(CONFIG_FEATURE_VOLUMEID_NVIDIARAID) += nvidia_raid.o |
22 | 22 | ||
23 | //config: | ||
24 | //config:### config FEATURE_VOLUMEID_NVIDIARAID | 23 | //config:### config FEATURE_VOLUMEID_NVIDIARAID |
25 | //config:### bool "nvidia raid" | 24 | //config:### bool "nvidia raid" |
26 | //config:### default y | 25 | //config:### default y |
27 | //config:### depends on VOLUMEID | 26 | //config:### depends on VOLUMEID |
28 | //config:### help | ||
29 | //config:### TODO | ||
30 | //config: | ||
31 | 27 | ||
32 | #include "volume_id_internal.h" | 28 | #include "volume_id_internal.h" |
33 | 29 | ||
diff --git a/util-linux/volume_id/unused_promise_raid.c b/util-linux/volume_id/unused_promise_raid.c index cebebe35f..d594de39c 100644 --- a/util-linux/volume_id/unused_promise_raid.c +++ b/util-linux/volume_id/unused_promise_raid.c | |||
@@ -20,14 +20,10 @@ | |||
20 | 20 | ||
21 | //kbuild:### lib-$(CONFIG_FEATURE_VOLUMEID_PROMISERAID) += promise_raid.o | 21 | //kbuild:### lib-$(CONFIG_FEATURE_VOLUMEID_PROMISERAID) += promise_raid.o |
22 | 22 | ||
23 | //config: | ||
24 | //config:### config FEATURE_VOLUMEID_PROMISERAID | 23 | //config:### config FEATURE_VOLUMEID_PROMISERAID |
25 | //config:### bool "promise raid" | 24 | //config:### bool "promise raid" |
26 | //config:### default y | 25 | //config:### default y |
27 | //config:### depends on VOLUMEID | 26 | //config:### depends on VOLUMEID |
28 | //config:### help | ||
29 | //config:### TODO | ||
30 | //config: | ||
31 | 27 | ||
32 | #include "volume_id_internal.h" | 28 | #include "volume_id_internal.h" |
33 | 29 | ||
diff --git a/util-linux/volume_id/unused_silicon_raid.c b/util-linux/volume_id/unused_silicon_raid.c index 40c8faa9e..886721b61 100644 --- a/util-linux/volume_id/unused_silicon_raid.c +++ b/util-linux/volume_id/unused_silicon_raid.c | |||
@@ -20,14 +20,10 @@ | |||
20 | 20 | ||
21 | //kbuild:### lib-$(CONFIG_FEATURE_VOLUMEID_SILICONRAID) += silicon_raid.o | 21 | //kbuild:### lib-$(CONFIG_FEATURE_VOLUMEID_SILICONRAID) += silicon_raid.o |
22 | 22 | ||
23 | //config: | ||
24 | //config:### config FEATURE_VOLUMEID_SILICONRAID | 23 | //config:### config FEATURE_VOLUMEID_SILICONRAID |
25 | //config:### bool "silicon raid" | 24 | //config:### bool "silicon raid" |
26 | //config:### default y | 25 | //config:### default y |
27 | //config:### depends on VOLUMEID | 26 | //config:### depends on VOLUMEID |
28 | //config:### help | ||
29 | //config:### TODO | ||
30 | //config: | ||
31 | 27 | ||
32 | #include "volume_id_internal.h" | 28 | #include "volume_id_internal.h" |
33 | 29 | ||
diff --git a/util-linux/volume_id/unused_ufs.c b/util-linux/volume_id/unused_ufs.c index d33c10fc4..78ef26ad4 100644 --- a/util-linux/volume_id/unused_ufs.c +++ b/util-linux/volume_id/unused_ufs.c | |||
@@ -20,14 +20,10 @@ | |||
20 | 20 | ||
21 | //kbuild:### lib-$(CONFIG_FEATURE_VOLUMEID_UFS) += ufs.o | 21 | //kbuild:### lib-$(CONFIG_FEATURE_VOLUMEID_UFS) += ufs.o |
22 | 22 | ||
23 | //config: | ||
24 | //config:### config FEATURE_VOLUMEID_UFS | 23 | //config:### config FEATURE_VOLUMEID_UFS |
25 | //config:### bool "ufs filesystem" | 24 | //config:### bool "ufs filesystem" |
26 | //config:### default y | 25 | //config:### default y |
27 | //config:### depends on VOLUMEID | 26 | //config:### depends on VOLUMEID |
28 | //config:### help | ||
29 | //config:### TODO | ||
30 | //config: | ||
31 | 27 | ||
32 | #include "volume_id_internal.h" | 28 | #include "volume_id_internal.h" |
33 | 29 | ||
diff --git a/util-linux/volume_id/unused_via_raid.c b/util-linux/volume_id/unused_via_raid.c index 258f93a4f..f82626655 100644 --- a/util-linux/volume_id/unused_via_raid.c +++ b/util-linux/volume_id/unused_via_raid.c | |||
@@ -20,14 +20,10 @@ | |||
20 | 20 | ||
21 | //kbuild:### lib-$(CONFIG_FEATURE_VOLUMEID_VIARAID) += via_raid.o | 21 | //kbuild:### lib-$(CONFIG_FEATURE_VOLUMEID_VIARAID) += via_raid.o |
22 | 22 | ||
23 | //config: | ||
24 | //config:### config FEATURE_VOLUMEID_VIARAID | 23 | //config:### config FEATURE_VOLUMEID_VIARAID |
25 | //config:### bool "via raid" | 24 | //config:### bool "via raid" |
26 | //config:### default y | 25 | //config:### default y |
27 | //config:### depends on VOLUMEID | 26 | //config:### depends on VOLUMEID |
28 | //config:### help | ||
29 | //config:### TODO | ||
30 | //config: | ||
31 | 27 | ||
32 | #include "volume_id_internal.h" | 28 | #include "volume_id_internal.h" |
33 | 29 | ||
diff --git a/util-linux/volume_id/xfs.c b/util-linux/volume_id/xfs.c index 5eefc201d..656d5bfcf 100644 --- a/util-linux/volume_id/xfs.c +++ b/util-linux/volume_id/xfs.c | |||
@@ -20,14 +20,10 @@ | |||
20 | 20 | ||
21 | //kbuild:lib-$(CONFIG_FEATURE_VOLUMEID_XFS) += xfs.o | 21 | //kbuild:lib-$(CONFIG_FEATURE_VOLUMEID_XFS) += xfs.o |
22 | 22 | ||
23 | //config: | ||
24 | //config:config FEATURE_VOLUMEID_XFS | 23 | //config:config FEATURE_VOLUMEID_XFS |
25 | //config: bool "xfs filesystem" | 24 | //config: bool "xfs filesystem" |
26 | //config: default y | 25 | //config: default y |
27 | //config: depends on VOLUMEID | 26 | //config: depends on VOLUMEID |
28 | //config: help | ||
29 | //config: TODO | ||
30 | //config: | ||
31 | 27 | ||
32 | #include "volume_id_internal.h" | 28 | #include "volume_id_internal.h" |
33 | 29 | ||