diff options
133 files changed, 3349 insertions, 2815 deletions
@@ -178,3 +178,6 @@ Mike Frysinger <vapier@gentoo.org> | |||
178 | 178 | ||
179 | Jie Zhang <jie.zhang@analog.com> | 179 | Jie Zhang <jie.zhang@analog.com> |
180 | fixed two bugs in msh and hush (exitcode of killed processes) | 180 | fixed two bugs in msh and hush (exitcode of killed processes) |
181 | |||
182 | Maxime Coste <mawww@kakoune.org> | ||
183 | paste implementation | ||
diff --git a/archival/dpkg.c b/archival/dpkg.c index f133299e3..1cd45eda4 100644 --- a/archival/dpkg.c +++ b/archival/dpkg.c | |||
@@ -18,7 +18,7 @@ | |||
18 | * known difference between busybox dpkg and the official dpkg that i don't | 18 | * known difference between busybox dpkg and the official dpkg that i don't |
19 | * consider important, its worth keeping a note of differences anyway, just to | 19 | * consider important, its worth keeping a note of differences anyway, just to |
20 | * make it easier to maintain. | 20 | * make it easier to maintain. |
21 | * - the first value for the confflile: field isnt placed on a new line. | 21 | * - the first value for the confflile: field isn't placed on a new line. |
22 | * - when installing a package the status: field is placed at the end of the | 22 | * - when installing a package the status: field is placed at the end of the |
23 | * section, rather than just after the package: field. | 23 | * section, rather than just after the package: field. |
24 | * | 24 | * |
@@ -110,7 +110,7 @@ typedef struct common_node_s { | |||
110 | edge_t **edge; | 110 | edge_t **edge; |
111 | } common_node_t; | 111 | } common_node_t; |
112 | 112 | ||
113 | /* Currently it doesnt store packages that have state-status of not-installed | 113 | /* Currently it doesn't store packages that have state-status of not-installed |
114 | * So it only really has to be the size of the maximum number of packages | 114 | * So it only really has to be the size of the maximum number of packages |
115 | * likely to be installed at any one time, so there is a bit of leeway here */ | 115 | * likely to be installed at any one time, so there is a bit of leeway here */ |
116 | #define STATUS_HASH_PRIME 8191 | 116 | #define STATUS_HASH_PRIME 8191 |
@@ -205,7 +205,7 @@ static int search_name_hashtable(const char *key) | |||
205 | return probe_address; | 205 | return probe_address; |
206 | } | 206 | } |
207 | 207 | ||
208 | /* this DOESNT add the key to the hashtable | 208 | /* this DOESN'T add the key to the hashtable |
209 | * TODO make it consistent with search_name_hashtable | 209 | * TODO make it consistent with search_name_hashtable |
210 | */ | 210 | */ |
211 | static unsigned search_status_hashtable(const char *key) | 211 | static unsigned search_status_hashtable(const char *key) |
@@ -467,7 +467,7 @@ static void add_split_dependencies(common_node_t *parent_node, const char *whole | |||
467 | version = strchr(field2, '('); | 467 | version = strchr(field2, '('); |
468 | if (version == NULL) { | 468 | if (version == NULL) { |
469 | edge->operator = VER_ANY; | 469 | edge->operator = VER_ANY; |
470 | /* Get the versions hash number, adding it if the number isnt already in there */ | 470 | /* Get the versions hash number, adding it if the number isn't already in there */ |
471 | edge->version = search_name_hashtable("ANY"); | 471 | edge->version = search_name_hashtable("ANY"); |
472 | } else { | 472 | } else { |
473 | /* Skip leading ' ' or '(' */ | 473 | /* Skip leading ' ' or '(' */ |
@@ -496,7 +496,7 @@ static void add_split_dependencies(common_node_t *parent_node, const char *whole | |||
496 | 496 | ||
497 | /* Truncate version at trailing ' ' or ')' */ | 497 | /* Truncate version at trailing ' ' or ')' */ |
498 | version[strcspn(version, " )")] = '\0'; | 498 | version[strcspn(version, " )")] = '\0'; |
499 | /* Get the versions hash number, adding it if the number isnt already in there */ | 499 | /* Get the versions hash number, adding it if the number isn't already in there */ |
500 | edge->version = search_name_hashtable(version); | 500 | edge->version = search_name_hashtable(version); |
501 | } | 501 | } |
502 | 502 | ||
@@ -562,7 +562,7 @@ static int read_package_field(const char *package_buffer, char **field_name, cha | |||
562 | offset_name_end = offset; | 562 | offset_name_end = offset; |
563 | offset_value_start = next_offset; | 563 | offset_value_start = next_offset; |
564 | } | 564 | } |
565 | /* TODO: Name might still have trailing spaces if ':' isnt | 565 | /* TODO: Name might still have trailing spaces if ':' isn't |
566 | * immediately after name */ | 566 | * immediately after name */ |
567 | break; | 567 | break; |
568 | case '\n': | 568 | case '\n': |
@@ -776,7 +776,7 @@ static void index_status_file(const char *filename) | |||
776 | const unsigned package_num = fill_package_struct(control_buffer); | 776 | const unsigned package_num = fill_package_struct(control_buffer); |
777 | if (package_num != -1) { | 777 | if (package_num != -1) { |
778 | status_node = xmalloc(sizeof(status_node_t)); | 778 | status_node = xmalloc(sizeof(status_node_t)); |
779 | /* fill_package_struct doesnt handle the status field */ | 779 | /* fill_package_struct doesn't handle the status field */ |
780 | status_line = strstr(control_buffer, "Status:"); | 780 | status_line = strstr(control_buffer, "Status:"); |
781 | if (status_line != NULL) { | 781 | if (status_line != NULL) { |
782 | status_line += 7; | 782 | status_line += 7; |
@@ -850,7 +850,7 @@ static void write_status_file(deb_file_t **deb_file) | |||
850 | if (status_hashtable[status_num] != NULL) { | 850 | if (status_hashtable[status_num] != NULL) { |
851 | const char *status_from_hashtable = name_hashtable[status_hashtable[status_num]->status]; | 851 | const char *status_from_hashtable = name_hashtable[status_hashtable[status_num]->status]; |
852 | if (strcmp(status_from_file, status_from_hashtable) != 0) { | 852 | if (strcmp(status_from_file, status_from_hashtable) != 0) { |
853 | /* New status isnt exactly the same as old status */ | 853 | /* New status isn't exactly the same as old status */ |
854 | const int state_status = get_status(status_num, 3); | 854 | const int state_status = get_status(status_num, 3); |
855 | if ((strcmp("installed", name_hashtable[state_status]) == 0) | 855 | if ((strcmp("installed", name_hashtable[state_status]) == 0) |
856 | || (strcmp("unpacked", name_hashtable[state_status]) == 0) | 856 | || (strcmp("unpacked", name_hashtable[state_status]) == 0) |
@@ -919,7 +919,7 @@ static void write_status_file(deb_file_t **deb_file) | |||
919 | } | 919 | } |
920 | } | 920 | } |
921 | } | 921 | } |
922 | /* If the package from the status file wasnt handle above, do it now*/ | 922 | /* If the package from the status file wasn't handle above, do it now*/ |
923 | if (!write_flag) { | 923 | if (!write_flag) { |
924 | fprintf(new_status_file, "%s\n\n", control_buffer); | 924 | fprintf(new_status_file, "%s\n\n", control_buffer); |
925 | } | 925 | } |
@@ -946,7 +946,7 @@ static void write_status_file(deb_file_t **deb_file) | |||
946 | if (errno != ENOENT) | 946 | if (errno != ENOENT) |
947 | bb_error_msg_and_die("can't create backup status file"); | 947 | bb_error_msg_and_die("can't create backup status file"); |
948 | /* Its ok if renaming the status file fails because status | 948 | /* Its ok if renaming the status file fails because status |
949 | * file doesnt exist, maybe we are starting from scratch */ | 949 | * file doesn't exist, maybe we are starting from scratch */ |
950 | bb_error_msg("no status file found, creating new one"); | 950 | bb_error_msg("no status file found, creating new one"); |
951 | } | 951 | } |
952 | 952 | ||
@@ -1061,7 +1061,7 @@ static int check_deps(deb_file_t **deb_file, int deb_start /*, int dep_max_count | |||
1061 | } | 1061 | } |
1062 | 1062 | ||
1063 | 1063 | ||
1064 | /* Check dependendcies */ | 1064 | /* Check dependentcies */ |
1065 | for (i = 0; i < PACKAGE_HASH_PRIME; i++) { | 1065 | for (i = 0; i < PACKAGE_HASH_PRIME; i++) { |
1066 | int status_num = 0; | 1066 | int status_num = 0; |
1067 | int number_of_alternatives = 0; | 1067 | int number_of_alternatives = 0; |
@@ -1244,7 +1244,7 @@ static void run_package_script_or_die(const char *package_name, const char *scri | |||
1244 | 1244 | ||
1245 | script_path = xasprintf("/var/lib/dpkg/info/%s.%s", package_name, script_type); | 1245 | script_path = xasprintf("/var/lib/dpkg/info/%s.%s", package_name, script_type); |
1246 | 1246 | ||
1247 | /* If the file doesnt exist is isnt fatal */ | 1247 | /* If the file doesn't exist it isn't fatal */ |
1248 | result = access(script_path, F_OK) ? EXIT_SUCCESS : system(script_path); | 1248 | result = access(script_path, F_OK) ? EXIT_SUCCESS : system(script_path); |
1249 | free(script_path); | 1249 | free(script_path); |
1250 | if (result) | 1250 | if (result) |
@@ -1839,7 +1839,7 @@ int dpkg_main(int argc UNUSED_PARAM, char **argv) | |||
1839 | ) { | 1839 | ) { |
1840 | status_node = xmalloc(sizeof(status_node_t)); | 1840 | status_node = xmalloc(sizeof(status_node_t)); |
1841 | status_node->package = deb_file[deb_count]->package; | 1841 | status_node->package = deb_file[deb_count]->package; |
1842 | /* reinstreq isnt changed to "ok" until the package control info | 1842 | /* reinstreq isn't changed to "ok" until the package control info |
1843 | * is written to the status file*/ | 1843 | * is written to the status file*/ |
1844 | status_node->status = search_name_hashtable("install reinstreq not-installed"); | 1844 | status_node->status = search_name_hashtable("install reinstreq not-installed"); |
1845 | status_hashtable[status_num] = status_node; | 1845 | status_hashtable[status_num] = status_node; |
diff --git a/archival/libarchive/Kbuild.src b/archival/libarchive/Kbuild.src index eaf67451f..942e755b9 100644 --- a/archival/libarchive/Kbuild.src +++ b/archival/libarchive/Kbuild.src | |||
@@ -51,8 +51,8 @@ lib-$(CONFIG_LZOP) += lzo1x_1.o lzo1x_1o.o lzo1x_d.o | |||
51 | lib-$(CONFIG_UNLZOP) += lzo1x_1.o lzo1x_1o.o lzo1x_d.o | 51 | lib-$(CONFIG_UNLZOP) += lzo1x_1.o lzo1x_1o.o lzo1x_d.o |
52 | lib-$(CONFIG_LZOPCAT) += lzo1x_1.o lzo1x_1o.o lzo1x_d.o | 52 | 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 | # 'bzip2 -d', bunzip2 or bzcat selects FEATURE_BZIP2_DECOMPRESS |
55 | lib-$(CONFIG_BZCAT) += open_transformer.o decompress_bunzip2.o | 55 | lib-$(CONFIG_FEATURE_BZIP2_DECOMPRESS) += open_transformer.o decompress_bunzip2.o |
56 | lib-$(CONFIG_FEATURE_UNZIP_BZIP2) += open_transformer.o decompress_bunzip2.o | 56 | lib-$(CONFIG_FEATURE_UNZIP_BZIP2) += open_transformer.o decompress_bunzip2.o |
57 | lib-$(CONFIG_UNLZMA) += open_transformer.o decompress_unlzma.o | 57 | lib-$(CONFIG_UNLZMA) += open_transformer.o decompress_unlzma.o |
58 | lib-$(CONFIG_LZCAT) += open_transformer.o decompress_unlzma.o | 58 | lib-$(CONFIG_LZCAT) += open_transformer.o decompress_unlzma.o |
@@ -62,8 +62,8 @@ lib-$(CONFIG_UNXZ) += open_transformer.o decompress_unxz.o | |||
62 | lib-$(CONFIG_XZCAT) += open_transformer.o decompress_unxz.o | 62 | lib-$(CONFIG_XZCAT) += open_transformer.o decompress_unxz.o |
63 | 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 | 64 | lib-$(CONFIG_FEATURE_UNZIP_XZ) += open_transformer.o decompress_unxz.o |
65 | lib-$(CONFIG_GUNZIP) += open_transformer.o decompress_gunzip.o | 65 | # 'gzip -d', gunzip or zcat selects FEATURE_GZIP_DECOMPRESS |
66 | lib-$(CONFIG_ZCAT) += open_transformer.o decompress_gunzip.o | 66 | lib-$(CONFIG_FEATURE_GZIP_DECOMPRESS) += open_transformer.o decompress_gunzip.o |
67 | lib-$(CONFIG_UNCOMPRESS) += open_transformer.o decompress_uncompress.o | 67 | lib-$(CONFIG_UNCOMPRESS) += open_transformer.o decompress_uncompress.o |
68 | lib-$(CONFIG_UNZIP) += open_transformer.o decompress_gunzip.o unsafe_prefix.o | 68 | lib-$(CONFIG_UNZIP) += open_transformer.o decompress_gunzip.o unsafe_prefix.o |
69 | lib-$(CONFIG_RPM2CPIO) += open_transformer.o decompress_gunzip.o get_header_cpio.o | 69 | lib-$(CONFIG_RPM2CPIO) += open_transformer.o decompress_gunzip.o get_header_cpio.o |
diff --git a/archival/libarchive/decompress_bunzip2.c b/archival/libarchive/decompress_bunzip2.c index 4fb989c29..803702f75 100644 --- a/archival/libarchive/decompress_bunzip2.c +++ b/archival/libarchive/decompress_bunzip2.c | |||
@@ -308,7 +308,7 @@ static int get_next_block(bunzip_data *bd) | |||
308 | base = hufGroup->base - 1; | 308 | base = hufGroup->base - 1; |
309 | limit = hufGroup->limit - 1; | 309 | limit = hufGroup->limit - 1; |
310 | 310 | ||
311 | /* Calculate permute[]. Concurently, initialize temp[] and limit[]. */ | 311 | /* Calculate permute[]. Concurrently, initialize temp[] and limit[]. */ |
312 | pp = 0; | 312 | pp = 0; |
313 | for (i = minLen; i <= maxLen; i++) { | 313 | for (i = minLen; i <= maxLen; i++) { |
314 | int k; | 314 | int k; |
diff --git a/archival/libarchive/unxz/xz_dec_lzma2.c b/archival/libarchive/unxz/xz_dec_lzma2.c index 351251f7c..bca41e705 100644 --- a/archival/libarchive/unxz/xz_dec_lzma2.c +++ b/archival/libarchive/unxz/xz_dec_lzma2.c | |||
@@ -486,11 +486,11 @@ static __always_inline void XZ_FUNC rc_normalize(struct rc_dec *rc) | |||
486 | } | 486 | } |
487 | 487 | ||
488 | /* | 488 | /* |
489 | * Decode one bit. In some versions, this function has been splitted in three | 489 | * Decode one bit. In some versions, this function has been split in three |
490 | * functions so that the compiler is supposed to be able to more easily avoid | 490 | * functions so that the compiler is supposed to be able to more easily avoid |
491 | * an extra branch. In this particular version of the LZMA decoder, this | 491 | * an extra branch. In this particular version of the LZMA decoder, this |
492 | * doesn't seem to be a good idea (tested with GCC 3.3.6, 3.4.6, and 4.3.3 | 492 | * doesn't seem to be a good idea (tested with GCC 3.3.6, 3.4.6, and 4.3.3 |
493 | * on x86). Using a non-splitted version results in nicer looking code too. | 493 | * on x86). Using a non-split version results in nicer looking code too. |
494 | * | 494 | * |
495 | * NOTE: This must return an int. Do not make it return a bool or the speed | 495 | * NOTE: This must return an int. Do not make it return a bool or the speed |
496 | * of the code generated by GCC 3.x decreases 10-15 %. (GCC 4.3 doesn't care, | 496 | * of the code generated by GCC 3.x decreases 10-15 %. (GCC 4.3 doesn't care, |
diff --git a/archival/tar.c b/archival/tar.c index 34e3052ce..be5838d0d 100644 --- a/archival/tar.c +++ b/archival/tar.c | |||
@@ -529,8 +529,8 @@ static int FAST_FUNC writeFileToTarball(const char *fileName, struct stat *statb | |||
529 | /* | 529 | /* |
530 | * Check to see if we are dealing with a hard link. | 530 | * Check to see if we are dealing with a hard link. |
531 | * If so - | 531 | * If so - |
532 | * Treat the first occurance of a given dev/inode as a file while | 532 | * Treat the first occurrence of a given dev/inode as a file while |
533 | * treating any additional occurances as hard links. This is done | 533 | * treating any additional occurrences as hard links. This is done |
534 | * by adding the file information to the HardLinkInfo linked list. | 534 | * by adding the file information to the HardLinkInfo linked list. |
535 | */ | 535 | */ |
536 | tbInfo->hlInfo = NULL; | 536 | tbInfo->hlInfo = NULL; |
diff --git a/archival/unzip.c b/archival/unzip.c index 56989fa0b..986145d0f 100644 --- a/archival/unzip.c +++ b/archival/unzip.c | |||
@@ -242,7 +242,7 @@ static uint32_t find_cdf_offset(void) | |||
242 | end = 0; | 242 | end = 0; |
243 | 243 | ||
244 | dbg("Looking for cdf_offset starting from 0x%"OFF_FMT"x", end); | 244 | dbg("Looking for cdf_offset starting from 0x%"OFF_FMT"x", end); |
245 | xlseek(zip_fd, end, SEEK_SET); | 245 | xlseek(zip_fd, end, SEEK_SET); |
246 | buf = xzalloc(PEEK_FROM_END); | 246 | buf = xzalloc(PEEK_FROM_END); |
247 | full_read(zip_fd, buf, PEEK_FROM_END); | 247 | full_read(zip_fd, buf, PEEK_FROM_END); |
248 | 248 | ||
diff --git a/console-tools/reset.c b/console-tools/reset.c index 57cebb4ea..587c0d11a 100644 --- a/console-tools/reset.c +++ b/console-tools/reset.c | |||
@@ -56,6 +56,8 @@ int reset_main(int argc UNUSED_PARAM, char **argv UNUSED_PARAM) | |||
56 | #if ENABLE_STTY | 56 | #if ENABLE_STTY |
57 | return stty_main(2, (char**)args); | 57 | return stty_main(2, (char**)args); |
58 | #else | 58 | #else |
59 | /* Make sure stdout gets drained before we execvp */ | ||
60 | fflush_all(); | ||
59 | execvp("stty", (char**)args); | 61 | execvp("stty", (char**)args); |
60 | #endif | 62 | #endif |
61 | } | 63 | } |
diff --git a/coreutils/cat.c b/coreutils/cat.c index 65978887e..4d9147f8a 100644 --- a/coreutils/cat.c +++ b/coreutils/cat.c | |||
@@ -12,56 +12,168 @@ | |||
12 | //config: help | 12 | //config: help |
13 | //config: cat is used to concatenate files and print them to the standard | 13 | //config: cat is used to concatenate files and print them to the standard |
14 | //config: output. Enable this option if you wish to enable the 'cat' utility. | 14 | //config: output. Enable this option if you wish to enable the 'cat' utility. |
15 | //config: | ||
16 | //config:config FEATURE_CATV | ||
17 | //config: bool "cat -v[etA]" | ||
18 | //config: default y | ||
19 | //config: depends on CAT | ||
20 | //config: help | ||
21 | //config: Display nonprinting characters as escape sequences | ||
15 | 22 | ||
16 | //applet:IF_CAT(APPLET_NOFORK(cat, cat, BB_DIR_BIN, BB_SUID_DROP, cat)) | 23 | //applet:IF_CAT(APPLET(cat, BB_DIR_BIN, BB_SUID_DROP)) |
17 | 24 | ||
18 | //kbuild:lib-$(CONFIG_CAT) += cat.o | 25 | //kbuild:lib-$(CONFIG_CAT) += cat.o |
19 | 26 | ||
20 | /* BB_AUDIT SUSv3 compliant */ | 27 | /* BB_AUDIT SUSv3 compliant */ |
21 | /* http://www.opengroup.org/onlinepubs/007904975/utilities/cat.html */ | 28 | /* http://www.opengroup.org/onlinepubs/007904975/utilities/cat.html */ |
22 | 29 | ||
23 | //usage:#define cat_trivial_usage | 30 | //usage:#define cat_trivial_usage |
24 | //usage: "[FILE]..." | 31 | //usage: "[-nb"IF_FEATURE_CATV("vteA")"] [FILE]..." |
25 | //usage:#define cat_full_usage "\n\n" | 32 | //usage:#define cat_full_usage "\n\n" |
26 | //usage: "Concatenate FILEs and print them to stdout" | 33 | //usage: "Print FILEs to stdout\n" |
34 | //usage: "\n -n Number output lines" | ||
35 | //usage: "\n -b Number nonempty lines" | ||
36 | //usage: IF_FEATURE_CATV( | ||
37 | //usage: "\n -v Show nonprinting characters as ^x or M-x" | ||
38 | //usage: "\n -t ...and tabs as ^I" | ||
39 | //usage: "\n -e ...and end lines with $" | ||
40 | //usage: "\n -A Same as -vte" | ||
41 | //usage: ) | ||
42 | /* | ||
43 | Longopts not implemented yet: | ||
44 | --number-nonblank number nonempty output lines, overrides -n | ||
45 | --number number all output lines | ||
46 | --show-nonprinting use ^ and M- notation, except for LFD and TAB | ||
47 | --show-all equivalent to -vet | ||
48 | Not implemented yet: | ||
49 | -E, --show-ends display $ at end of each line (-e sans -v) | ||
50 | -T, --show-tabs display TAB characters as ^I (-t sans -v) | ||
51 | -s, --squeeze-blank suppress repeated empty output lines | ||
52 | */ | ||
27 | //usage: | 53 | //usage: |
28 | //usage:#define cat_example_usage | 54 | //usage:#define cat_example_usage |
29 | //usage: "$ cat /proc/uptime\n" | 55 | //usage: "$ cat /proc/uptime\n" |
30 | //usage: "110716.72 17.67" | 56 | //usage: "110716.72 17.67" |
31 | 57 | ||
32 | #include "libbb.h" | 58 | #include "libbb.h" |
59 | #include "common_bufsiz.h" | ||
33 | 60 | ||
34 | /* This is a NOFORK applet. Be very careful! */ | 61 | #if ENABLE_FEATURE_CATV |
35 | 62 | /* | |
36 | 63 | * cat -v implementation for busybox | |
37 | int bb_cat(char **argv) | 64 | * |
65 | * Copyright (C) 2006 Rob Landley <rob@landley.net> | ||
66 | * | ||
67 | * Licensed under GPLv2 or later, see file LICENSE in this source tree. | ||
68 | */ | ||
69 | /* Rob had "cat -v" implemented as a separate applet, catv. | ||
70 | * See "cat -v considered harmful" at | ||
71 | * http://cm.bell-labs.com/cm/cs/doc/84/kp.ps.gz | ||
72 | * From USENIX Summer Conference Proceedings, 1983 | ||
73 | * """ | ||
74 | * The talk reviews reasons for UNIX's popularity and shows, using UCB cat | ||
75 | * as a primary example, how UNIX has grown fat. cat isn't for printing | ||
76 | * files with line numbers, it isn't for compressing multiple blank lines, | ||
77 | * it's not for looking at non-printing ASCII characters, it's for | ||
78 | * concatenating files. | ||
79 | * We are reminded that ls isn't the place for code to break a single column | ||
80 | * into multiple ones, and that mailnews shouldn't have its own more | ||
81 | * processing or joke encryption code. | ||
82 | * """ | ||
83 | * | ||
84 | * I agree with the argument. Unfortunately, this ship has sailed (1983...). | ||
85 | * There are dozens of Linux distros and each of them has "cat" which supports -v. | ||
86 | * It's unrealistic for us to "reeducate" them to use our, incompatible way | ||
87 | * to achieve "cat -v" effect. The actuall effect would be "users pissed off | ||
88 | * by gratuitous incompatibility". | ||
89 | */ | ||
90 | #define CATV_OPT_e (1<<0) | ||
91 | #define CATV_OPT_t (1<<1) | ||
92 | #define CATV_OPT_v (1<<2) | ||
93 | static int catv(unsigned opts, char **argv) | ||
38 | { | 94 | { |
39 | int fd; | ||
40 | int retval = EXIT_SUCCESS; | 95 | int retval = EXIT_SUCCESS; |
96 | int fd; | ||
41 | 97 | ||
42 | if (!*argv) | 98 | BUILD_BUG_ON(CATV_OPT_e != VISIBLE_ENDLINE); |
43 | argv = (char**) &bb_argv_dash; | 99 | BUILD_BUG_ON(CATV_OPT_t != VISIBLE_SHOW_TABS); |
100 | #if 0 /* These consts match, we can just pass "opts" to visible() */ | ||
101 | if (opts & CATV_OPT_e) | ||
102 | flags |= VISIBLE_ENDLINE; | ||
103 | if (opts & CATV_OPT_t) | ||
104 | flags |= VISIBLE_SHOW_TABS; | ||
105 | #endif | ||
106 | |||
107 | /* Read from stdin if there's nothing else to do. */ | ||
108 | if (!argv[0]) | ||
109 | *--argv = (char*)"-"; | ||
44 | 110 | ||
111 | #define read_buf bb_common_bufsiz1 | ||
112 | setup_common_bufsiz(); | ||
45 | do { | 113 | do { |
46 | fd = open_or_warn_stdin(*argv); | 114 | fd = open_or_warn_stdin(*argv); |
47 | if (fd >= 0) { | 115 | if (fd < 0) { |
48 | /* This is not a xfunc - never exits */ | 116 | retval = EXIT_FAILURE; |
49 | off_t r = bb_copyfd_eof(fd, STDOUT_FILENO); | 117 | continue; |
50 | if (fd != STDIN_FILENO) | ||
51 | close(fd); | ||
52 | if (r >= 0) | ||
53 | continue; | ||
54 | } | 118 | } |
55 | retval = EXIT_FAILURE; | 119 | for (;;) { |
120 | int i, res; | ||
121 | |||
122 | res = read(fd, read_buf, COMMON_BUFSIZE); | ||
123 | if (res < 0) | ||
124 | retval = EXIT_FAILURE; | ||
125 | if (res <= 0) | ||
126 | break; | ||
127 | for (i = 0; i < res; i++) { | ||
128 | unsigned char c = read_buf[i]; | ||
129 | char buf[sizeof("M-^c")]; | ||
130 | visible(c, buf, opts); | ||
131 | fputs(buf, stdout); | ||
132 | } | ||
133 | } | ||
134 | if (ENABLE_FEATURE_CLEAN_UP && fd) | ||
135 | close(fd); | ||
56 | } while (*++argv); | 136 | } while (*++argv); |
57 | 137 | ||
58 | return retval; | 138 | fflush_stdout_and_exit(retval); |
59 | } | 139 | } |
140 | #endif | ||
60 | 141 | ||
61 | int cat_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; | 142 | int cat_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; |
62 | int cat_main(int argc UNUSED_PARAM, char **argv) | 143 | int cat_main(int argc UNUSED_PARAM, char **argv) |
63 | { | 144 | { |
64 | getopt32(argv, "u"); | 145 | struct number_state ns; |
146 | unsigned opts; | ||
147 | |||
148 | IF_FEATURE_CATV(opt_complementary = "Aetv"; /* -A == -vet */) | ||
149 | /* -u is ignored ("unbuffered") */ | ||
150 | opts = getopt32(argv, IF_FEATURE_CATV("etvA")"nbu"); | ||
65 | argv += optind; | 151 | argv += optind; |
66 | return bb_cat(argv); | 152 | |
153 | #if ENABLE_FEATURE_CATV | ||
154 | if (opts & 7) | ||
155 | return catv(opts, argv); | ||
156 | //BUG: -v,-e,-t,-A ignore -nb | ||
157 | opts >>= 4; | ||
158 | #endif | ||
159 | |||
160 | #define CAT_OPT_n (1<<0) | ||
161 | #define CAT_OPT_b (1<<1) | ||
162 | #define CAT_OPT_u (1<<2) | ||
163 | if (!(opts & (CAT_OPT_n|CAT_OPT_b))) /* no -n or -b */ | ||
164 | return bb_cat(argv); | ||
165 | |||
166 | if (!*argv) | ||
167 | *--argv = (char*)"-"; | ||
168 | ns.width = 6; | ||
169 | ns.start = 1; | ||
170 | ns.inc = 1; | ||
171 | ns.sep = "\t"; | ||
172 | ns.empty_str = "\n"; | ||
173 | ns.all = !(opts & CAT_OPT_b); /* -n without -b */ | ||
174 | ns.nonempty = (opts & CAT_OPT_b); /* -b (with or without -n) */ | ||
175 | do { | ||
176 | print_numbered_lines(&ns, *argv); | ||
177 | } while (*++argv); | ||
178 | fflush_stdout_and_exit(EXIT_SUCCESS); | ||
67 | } | 179 | } |
diff --git a/coreutils/catv.c b/coreutils/catv.c deleted file mode 100644 index 1aeebe1d9..000000000 --- a/coreutils/catv.c +++ /dev/null | |||
@@ -1,96 +0,0 @@ | |||
1 | /* vi: set sw=4 ts=4: */ | ||
2 | /* | ||
3 | * cat -v implementation for busybox | ||
4 | * | ||
5 | * Copyright (C) 2006 Rob Landley <rob@landley.net> | ||
6 | * | ||
7 | * Licensed under GPLv2 or later, see file LICENSE in this source tree. | ||
8 | */ | ||
9 | |||
10 | /* See "Cat -v considered harmful" at | ||
11 | * http://cm.bell-labs.com/cm/cs/doc/84/kp.ps.gz */ | ||
12 | |||
13 | //config:config CATV | ||
14 | //config: bool "catv" | ||
15 | //config: default y | ||
16 | //config: help | ||
17 | //config: Display nonprinting characters as escape sequences (like some | ||
18 | //config: implementations' cat -v option). | ||
19 | |||
20 | //applet:IF_CATV(APPLET(catv, BB_DIR_BIN, BB_SUID_DROP)) | ||
21 | |||
22 | //kbuild:lib-$(CONFIG_CATV) += catv.o | ||
23 | |||
24 | //usage:#define catv_trivial_usage | ||
25 | //usage: "[-etv] [FILE]..." | ||
26 | //usage:#define catv_full_usage "\n\n" | ||
27 | //usage: "Display nonprinting characters as ^x or M-x\n" | ||
28 | //usage: "\n -e End each line with $" | ||
29 | //usage: "\n -t Show tabs as ^I" | ||
30 | //usage: "\n -v Don't use ^x or M-x escapes" | ||
31 | |||
32 | #include "libbb.h" | ||
33 | #include "common_bufsiz.h" | ||
34 | |||
35 | #define CATV_OPT_e (1<<0) | ||
36 | #define CATV_OPT_t (1<<1) | ||
37 | #define CATV_OPT_v (1<<2) | ||
38 | struct BUG_const_mismatch { | ||
39 | char BUG_const_mismatch[ | ||
40 | CATV_OPT_e == VISIBLE_ENDLINE && CATV_OPT_t == VISIBLE_SHOW_TABS | ||
41 | ? 1 : -1 | ||
42 | ]; | ||
43 | }; | ||
44 | |||
45 | int catv_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; | ||
46 | int catv_main(int argc UNUSED_PARAM, char **argv) | ||
47 | { | ||
48 | int retval = EXIT_SUCCESS; | ||
49 | int fd; | ||
50 | unsigned opts; | ||
51 | opts = getopt32(argv, "etv"); | ||
52 | argv += optind; | ||
53 | #if 0 /* These consts match, we can just pass "opts" to visible() */ | ||
54 | if (opts & CATV_OPT_e) | ||
55 | flags |= VISIBLE_ENDLINE; | ||
56 | if (opts & CATV_OPT_t) | ||
57 | flags |= VISIBLE_SHOW_TABS; | ||
58 | #endif | ||
59 | |||
60 | /* Read from stdin if there's nothing else to do. */ | ||
61 | if (!argv[0]) | ||
62 | *--argv = (char*)"-"; | ||
63 | |||
64 | #define read_buf bb_common_bufsiz1 | ||
65 | setup_common_bufsiz(); | ||
66 | do { | ||
67 | fd = open_or_warn_stdin(*argv); | ||
68 | if (fd < 0) { | ||
69 | retval = EXIT_FAILURE; | ||
70 | continue; | ||
71 | } | ||
72 | for (;;) { | ||
73 | int i, res; | ||
74 | |||
75 | res = read(fd, read_buf, COMMON_BUFSIZE); | ||
76 | if (res < 0) | ||
77 | retval = EXIT_FAILURE; | ||
78 | if (res <= 0) | ||
79 | break; | ||
80 | for (i = 0; i < res; i++) { | ||
81 | unsigned char c = read_buf[i]; | ||
82 | if (opts & CATV_OPT_v) { | ||
83 | putchar(c); | ||
84 | } else { | ||
85 | char buf[sizeof("M-^c")]; | ||
86 | visible(c, buf, opts); | ||
87 | fputs(buf, stdout); | ||
88 | } | ||
89 | } | ||
90 | } | ||
91 | if (ENABLE_FEATURE_CLEAN_UP && fd) | ||
92 | close(fd); | ||
93 | } while (*++argv); | ||
94 | |||
95 | fflush_stdout_and_exit(retval); | ||
96 | } | ||
diff --git a/coreutils/cksum.c b/coreutils/cksum.c index aeec0188d..9034fc19a 100644 --- a/coreutils/cksum.c +++ b/coreutils/cksum.c | |||
@@ -17,9 +17,9 @@ | |||
17 | //kbuild:lib-$(CONFIG_CKSUM) += cksum.o | 17 | //kbuild:lib-$(CONFIG_CKSUM) += cksum.o |
18 | 18 | ||
19 | //usage:#define cksum_trivial_usage | 19 | //usage:#define cksum_trivial_usage |
20 | //usage: "FILES..." | 20 | //usage: "FILE..." |
21 | //usage:#define cksum_full_usage "\n\n" | 21 | //usage:#define cksum_full_usage "\n\n" |
22 | //usage: "Calculate the CRC32 checksums of FILES" | 22 | //usage: "Calculate the CRC32 checksums of FILEs" |
23 | 23 | ||
24 | #include "libbb.h" | 24 | #include "libbb.h" |
25 | #include "common_bufsiz.h" | 25 | #include "common_bufsiz.h" |
diff --git a/coreutils/dd.c b/coreutils/dd.c index 85152d8ce..2fccf9d8e 100644 --- a/coreutils/dd.c +++ b/coreutils/dd.c | |||
@@ -543,11 +543,11 @@ int dd_main(int argc UNUSED_PARAM, char **argv) | |||
543 | if (write_and_stats(ibuf, n, obs, outfile)) | 543 | if (write_and_stats(ibuf, n, obs, outfile)) |
544 | goto out_status; | 544 | goto out_status; |
545 | } | 545 | } |
546 | } | ||
546 | 547 | ||
547 | if (G.flags & FLAG_FSYNC) { | 548 | if (G.flags & FLAG_FSYNC) { |
548 | if (fsync(ofd) < 0) | 549 | if (fsync(ofd) < 0) |
549 | goto die_outfile; | 550 | goto die_outfile; |
550 | } | ||
551 | } | 551 | } |
552 | 552 | ||
553 | if (ENABLE_FEATURE_DD_IBS_OBS && oc) { | 553 | if (ENABLE_FEATURE_DD_IBS_OBS && oc) { |
diff --git a/coreutils/dos2unix.c b/coreutils/dos2unix.c index 6d2347163..9d81ccca6 100644 --- a/coreutils/dos2unix.c +++ b/coreutils/dos2unix.c | |||
@@ -2,7 +2,7 @@ | |||
2 | /* | 2 | /* |
3 | * dos2unix for BusyBox | 3 | * dos2unix for BusyBox |
4 | * | 4 | * |
5 | * dos2unix '\n' convertor 0.5.0 | 5 | * dos2unix '\n' converter 0.5.0 |
6 | * based on Unix2Dos 0.9.0 by Peter Hanecak (made 19.2.1997) | 6 | * based on Unix2Dos 0.9.0 by Peter Hanecak (made 19.2.1997) |
7 | * Copyright 1997,.. by Peter Hanecak <hanecak@megaloman.sk>. | 7 | * Copyright 1997,.. by Peter Hanecak <hanecak@megaloman.sk>. |
8 | * All rights reserved. | 8 | * All rights reserved. |
diff --git a/coreutils/factor.c b/coreutils/factor.c new file mode 100644 index 000000000..205cdc053 --- /dev/null +++ b/coreutils/factor.c | |||
@@ -0,0 +1,219 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2017 Denys Vlasenko <vda.linux@googlemail.com> | ||
3 | * | ||
4 | * Licensed under GPLv2, see file LICENSE in this source tree. | ||
5 | */ | ||
6 | //config:config FACTOR | ||
7 | //config: bool "factor" | ||
8 | //config: default y | ||
9 | //config: help | ||
10 | //config: factor factorizes integers | ||
11 | |||
12 | //applet:IF_FACTOR(APPLET(factor, BB_DIR_USR_BIN, BB_SUID_DROP)) | ||
13 | |||
14 | //kbuild:lib-$(CONFIG_FACTOR) += factor.o | ||
15 | |||
16 | //usage:#define factor_trivial_usage | ||
17 | //usage: "[NUMBER]..." | ||
18 | //usage:#define factor_full_usage "\n\n" | ||
19 | //usage: "Print prime factors" | ||
20 | |||
21 | #include "libbb.h" | ||
22 | |||
23 | #if 0 | ||
24 | # define dbg(...) bb_error_msg(__VA_ARGS__) | ||
25 | #else | ||
26 | # define dbg(...) ((void)0) | ||
27 | #endif | ||
28 | |||
29 | typedef unsigned long long wide_t; | ||
30 | |||
31 | #if ULLONG_MAX == (UINT_MAX * UINT_MAX + 2 * UINT_MAX) | ||
32 | /* "unsigned" is half as wide as ullong */ | ||
33 | typedef unsigned half_t; | ||
34 | #define HALF_MAX UINT_MAX | ||
35 | #define HALF_FMT "" | ||
36 | #elif ULLONG_MAX == (ULONG_MAX * ULONG_MAX + 2 * ULONG_MAX) | ||
37 | /* long is half as wide as ullong */ | ||
38 | typedef unsigned long half_t; | ||
39 | #define HALF_MAX ULONG_MAX | ||
40 | #define HALF_FMT "l" | ||
41 | #else | ||
42 | #error Cant find an integer type which is half as wide as ullong | ||
43 | #endif | ||
44 | |||
45 | static half_t isqrt_odd(wide_t N) | ||
46 | { | ||
47 | half_t s = isqrt(N); | ||
48 | /* Subtract 1 from even s, odd s won't change: */ | ||
49 | /* (doesnt work for zero, but we know that s != 0 here) */ | ||
50 | s = (s - 1) | 1; | ||
51 | return s; | ||
52 | } | ||
53 | |||
54 | static NOINLINE void factorize(wide_t N) | ||
55 | { | ||
56 | half_t factor; | ||
57 | half_t max_factor; | ||
58 | // unsigned count3; | ||
59 | // unsigned count5; | ||
60 | // unsigned count7; | ||
61 | // ^^^^^^^^^^^^^^^ commented-out simple sieving code (easier to grasp). | ||
62 | // Faster sieving, using one word for potentially up to 6 counters: | ||
63 | // count upwards in each mask, counter "triggers" when it sets its mask to "100[0]..." | ||
64 | // 10987654321098765432109876543210 - bits 31-0 in 32-bit word | ||
65 | // 17777713333311111777775555333 - bit masks for counters for primes 3,5,7,11,13,17 | ||
66 | // 100000100001000010001001 - value for adding 1 to each mask | ||
67 | // 10000010000010000100001000100 - value for checking that any mask reached msb | ||
68 | enum { | ||
69 | SHIFT_3 = 1 << 0, | ||
70 | SHIFT_5 = 1 << 3, | ||
71 | SHIFT_7 = 1 << 7, | ||
72 | INCREMENT_EACH = SHIFT_3 | SHIFT_5 | SHIFT_7, | ||
73 | MULTIPLE_OF_3 = 1 << 2, | ||
74 | MULTIPLE_OF_5 = 1 << 6, | ||
75 | MULTIPLE_OF_7 = 1 << 11, | ||
76 | MULTIPLE_DETECTED = MULTIPLE_OF_3 | MULTIPLE_OF_5 | MULTIPLE_OF_7, | ||
77 | }; | ||
78 | unsigned sieve_word; | ||
79 | |||
80 | if (N < 4) | ||
81 | goto end; | ||
82 | |||
83 | while (!(N & 1)) { | ||
84 | printf(" 2"); | ||
85 | N >>= 1; | ||
86 | } | ||
87 | |||
88 | /* The code needs to be optimized for the case where | ||
89 | * there are large prime factors. For example, | ||
90 | * this is not hard: | ||
91 | * 8262075252869367027 = 3 7 17 23 47 101 113 127 131 137 823 | ||
92 | * (the largest factor to test is only ~sqrt(823) = 28) | ||
93 | * but this is: | ||
94 | * 18446744073709551601 = 53 348051774975651917 | ||
95 | * the last factor requires testing up to | ||
96 | * 589959129 - about 100 million iterations. | ||
97 | * The slowest case (largest prime) for N < 2^64 is | ||
98 | * factor 18446744073709551557 (0xffffffffffffffc5). | ||
99 | */ | ||
100 | max_factor = isqrt_odd(N); | ||
101 | // count3 = 3; | ||
102 | // count5 = 6; | ||
103 | // count7 = 9; | ||
104 | sieve_word = 0 | ||
105 | /* initial count for SHIFT_n is (n-1)/2*3: */ | ||
106 | + (MULTIPLE_OF_3 - 3 * SHIFT_3) | ||
107 | + (MULTIPLE_OF_5 - 6 * SHIFT_5) | ||
108 | + (MULTIPLE_OF_7 - 9 * SHIFT_7) | ||
109 | //+ (MULTIPLE_OF_11 - 15 * SHIFT_11) | ||
110 | //+ (MULTIPLE_OF_13 - 18 * SHIFT_13) | ||
111 | //+ (MULTIPLE_OF_17 - 24 * SHIFT_17) | ||
112 | ; | ||
113 | factor = 3; | ||
114 | for (;;) { | ||
115 | /* The division is the most costly part of the loop. | ||
116 | * On 64bit CPUs, takes at best 12 cycles, often ~20. | ||
117 | */ | ||
118 | while ((N % factor) == 0) { /* not likely */ | ||
119 | N = N / factor; | ||
120 | printf(" %"HALF_FMT"u", factor); | ||
121 | max_factor = isqrt_odd(N); | ||
122 | } | ||
123 | next_factor: | ||
124 | if (factor >= max_factor) | ||
125 | break; | ||
126 | factor += 2; | ||
127 | /* Rudimentary wheel sieving: skip multiples of 3, 5 and 7: | ||
128 | * Every third odd number is divisible by three and thus isn't a prime: | ||
129 | * 5 7 9 11 13 15 17 19 21 23 25 27 29 31 33 35 37 39 41 43 45 47... | ||
130 | * ^ ^ ^ ^ ^ ^ ^ _ ^ ^ _ ^ ^ ^ ^ | ||
131 | * (^ = primes, _ = would-be-primes-if-not-divisible-by-5) | ||
132 | * The numbers with space under them are excluded by sieve 3. | ||
133 | */ | ||
134 | // count7--; | ||
135 | // count5--; | ||
136 | // count3--; | ||
137 | // if (count3 && count5 && count7) | ||
138 | // continue; | ||
139 | sieve_word += INCREMENT_EACH; | ||
140 | if (!(sieve_word & MULTIPLE_DETECTED)) | ||
141 | continue; | ||
142 | /* | ||
143 | * "factor" is multiple of 3 33% of the time (count3 reached 0), | ||
144 | * else, multiple of 5 13% of the time, | ||
145 | * else, multiple of 7 7.6% of the time. | ||
146 | * Cumulatively, with 3,5,7 sieving we are here 54.3% of the time. | ||
147 | */ | ||
148 | // if (count3 == 0) | ||
149 | // count3 = 3; | ||
150 | if (sieve_word & MULTIPLE_OF_3) | ||
151 | sieve_word -= SHIFT_3 * 3; | ||
152 | // if (count5 == 0) | ||
153 | // count5 = 5; | ||
154 | if (sieve_word & MULTIPLE_OF_5) | ||
155 | sieve_word -= SHIFT_5 * 5; | ||
156 | // if (count7 == 0) | ||
157 | // count7 = 7; | ||
158 | if (sieve_word & MULTIPLE_OF_7) | ||
159 | sieve_word -= SHIFT_7 * 7; | ||
160 | goto next_factor; | ||
161 | } | ||
162 | end: | ||
163 | if (N > 1) | ||
164 | printf(" %llu", N); | ||
165 | bb_putchar('\n'); | ||
166 | } | ||
167 | |||
168 | static void factorize_numstr(const char *numstr) | ||
169 | { | ||
170 | wide_t N; | ||
171 | |||
172 | /* Leading + is ok (coreutils compat) */ | ||
173 | if (*numstr == '+') | ||
174 | numstr++; | ||
175 | N = bb_strtoull(numstr, NULL, 10); | ||
176 | if (errno) | ||
177 | bb_show_usage(); | ||
178 | printf("%llu:", N); | ||
179 | factorize(N); | ||
180 | } | ||
181 | |||
182 | int factor_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; | ||
183 | int factor_main(int argc UNUSED_PARAM, char **argv) | ||
184 | { | ||
185 | //// coreutils has undocumented option ---debug (three dashes) | ||
186 | //getopt32(argv, ""); | ||
187 | //argv += optind; | ||
188 | argv++; | ||
189 | |||
190 | if (!*argv) { | ||
191 | /* Read from stdin, several numbers per line are accepted */ | ||
192 | for (;;) { | ||
193 | char *numstr, *line; | ||
194 | line = xmalloc_fgetline(stdin); | ||
195 | if (!line) | ||
196 | return EXIT_SUCCESS; | ||
197 | numstr = line; | ||
198 | for (;;) { | ||
199 | char *end; | ||
200 | numstr = skip_whitespace(numstr); | ||
201 | if (!numstr[0]) | ||
202 | break; | ||
203 | end = skip_non_whitespace(numstr); | ||
204 | if (*end != '\0') | ||
205 | *end++ = '\0'; | ||
206 | factorize_numstr(numstr); | ||
207 | numstr = end; | ||
208 | } | ||
209 | free(line); | ||
210 | } | ||
211 | } | ||
212 | |||
213 | do { | ||
214 | /* Leading spaces are ok (coreutils compat) */ | ||
215 | factorize_numstr(skip_whitespace(*argv)); | ||
216 | } while (*++argv); | ||
217 | |||
218 | return EXIT_SUCCESS; | ||
219 | } | ||
diff --git a/coreutils/ls.c b/coreutils/ls.c index 6e0a52d75..6780057da 100644 --- a/coreutils/ls.c +++ b/coreutils/ls.c | |||
@@ -1067,17 +1067,19 @@ int ls_main(int argc UNUSED_PARAM, char **argv) | |||
1067 | * 'auto', 'tty', 'if-tty' | 1067 | * 'auto', 'tty', 'if-tty' |
1068 | * (and substrings: "--color=alwa" work too) | 1068 | * (and substrings: "--color=alwa" work too) |
1069 | */ | 1069 | */ |
1070 | static const char ls_longopts[] ALIGN1 = | ||
1071 | "full-time\0" No_argument "\xff" | ||
1072 | "group-directories-first\0" No_argument "\xfe" | ||
1073 | "color\0" Optional_argument "\xfd" | ||
1074 | ; | ||
1075 | static const char color_str[] ALIGN1 = | 1070 | static const char color_str[] ALIGN1 = |
1076 | "always\0""yes\0""force\0" | 1071 | "always\0""yes\0""force\0" |
1077 | "auto\0""tty\0""if-tty\0"; | 1072 | "auto\0""tty\0""if-tty\0"; |
1078 | /* need to initialize since --color has _an optional_ argument */ | 1073 | /* need to initialize since --color has _an optional_ argument */ |
1079 | const char *color_opt = color_str; /* "always" */ | 1074 | const char *color_opt = color_str; /* "always" */ |
1080 | #endif | 1075 | #endif |
1076 | #if ENABLE_LONG_OPTS | ||
1077 | static const char ls_longopts[] ALIGN1 = | ||
1078 | "full-time\0" No_argument "\xff" | ||
1079 | "group-directories-first\0" No_argument "\xfe" | ||
1080 | "color\0" Optional_argument "\xfd" | ||
1081 | ; | ||
1082 | #endif | ||
1081 | 1083 | ||
1082 | INIT_G(); | 1084 | INIT_G(); |
1083 | 1085 | ||
@@ -1091,7 +1093,7 @@ int ls_main(int argc UNUSED_PARAM, char **argv) | |||
1091 | #endif | 1093 | #endif |
1092 | 1094 | ||
1093 | /* process options */ | 1095 | /* process options */ |
1094 | IF_FEATURE_LS_COLOR(applet_long_options = ls_longopts;) | 1096 | IF_LONG_OPTS(applet_long_options = ls_longopts;) |
1095 | opt_complementary = | 1097 | opt_complementary = |
1096 | /* -n and -g imply -l */ | 1098 | /* -n and -g imply -l */ |
1097 | "nl:gl" | 1099 | "nl:gl" |
diff --git a/debianutils/mktemp.c b/coreutils/mktemp.c index 65353697a..65353697a 100644 --- a/debianutils/mktemp.c +++ b/coreutils/mktemp.c | |||
diff --git a/coreutils/nl.c b/coreutils/nl.c new file mode 100644 index 000000000..5c64923bb --- /dev/null +++ b/coreutils/nl.c | |||
@@ -0,0 +1,101 @@ | |||
1 | /* vi: set sw=4 ts=4: */ | ||
2 | /* | ||
3 | * Copyright (C) 2017 Denys Vlasenko <vda.linux@googlemail.com> | ||
4 | * | ||
5 | * Licensed under GPLv2, see file LICENSE in this source tree. | ||
6 | */ | ||
7 | //config:config NL | ||
8 | //config: bool "nl" | ||
9 | //config: default y | ||
10 | //config: help | ||
11 | //config: nl is used to number lines of files. | ||
12 | |||
13 | //applet:IF_NL(APPLET(nl, BB_DIR_USR_BIN, BB_SUID_DROP)) | ||
14 | |||
15 | //kbuild:lib-$(CONFIG_NL) += nl.o | ||
16 | |||
17 | //usage:#define nl_trivial_usage | ||
18 | //usage: "[OPTIONS] [FILE]..." | ||
19 | //usage:#define nl_full_usage "\n\n" | ||
20 | //usage: "Write FILEs to standard output with line numbers added\n" | ||
21 | //usage: "\n -b STYLE Which lines to number - a: all, t: nonempty, n: none" | ||
22 | //^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^TODO: support "pBRE": number only lines thatmatch regexp BRE" | ||
23 | ////usage: "\n -f STYLE footer lines" | ||
24 | ////usage: "\n -h STYLE header lines" | ||
25 | ////usage: "\n -d CC use CC for separating logical pages" | ||
26 | //usage: "\n -i N Line number increment" | ||
27 | ////usage: "\n -l NUMBER group of NUMBER empty lines counted as one" | ||
28 | ////usage: "\n -n FORMAT lneft justified, no leading zeros; rn or rz" | ||
29 | ////usage: "\n -p do not reset line numbers at logical pages (huh?)" | ||
30 | //usage: "\n -s STRING Use STRING as line number separator" | ||
31 | //usage: "\n -v N Start from N" | ||
32 | //usage: "\n -w N Width of line numbers" | ||
33 | |||
34 | /* By default, selects -v1 -i1 -l1 -sTAB -w6 -nrn -hn -bt -fn */ | ||
35 | |||
36 | #include "libbb.h" | ||
37 | |||
38 | void FAST_FUNC print_numbered_lines(struct number_state *ns, const char *filename) | ||
39 | { | ||
40 | FILE *fp = fopen_or_warn_stdin(filename); | ||
41 | unsigned N = ns->start; | ||
42 | char *line; | ||
43 | |||
44 | while ((line = xmalloc_fgetline(fp)) != NULL) { | ||
45 | if (ns->all | ||
46 | || (ns->nonempty && line[0]) | ||
47 | ) { | ||
48 | printf("%*u%s%s\n", ns->width, N, ns->sep, line); | ||
49 | N += ns->inc; | ||
50 | } else if (ns->empty_str) | ||
51 | fputs(ns->empty_str, stdout); | ||
52 | free(line); | ||
53 | } | ||
54 | |||
55 | fclose(fp); | ||
56 | } | ||
57 | |||
58 | int nl_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; | ||
59 | int nl_main(int argc UNUSED_PARAM, char **argv) | ||
60 | { | ||
61 | struct number_state ns; | ||
62 | const char *opt_b = "t"; | ||
63 | enum { | ||
64 | OPT_p = (1 << 0), | ||
65 | }; | ||
66 | #if ENABLE_LONG_OPTS | ||
67 | static const char nl_longopts[] ALIGN1 = | ||
68 | "body-numbering\0" Required_argument "b" | ||
69 | // "footer-numbering\0" Required_argument "f" - not implemented yet | ||
70 | // "header-numbering\0" Required_argument "h" - not implemented yet | ||
71 | // "section-delimiter\0" Required_argument "d" - not implemented yet | ||
72 | "line-increment\0" Required_argument "i" | ||
73 | // "join-blank-lines\0" Required_argument "l" - not implemented yet | ||
74 | // "number-format\0" Required_argument "n" - not implemented yet | ||
75 | "no-renumber\0" No_argument "p" // no-op so far | ||
76 | "number-separator\0" Required_argument "s" | ||
77 | "starting-line-number\0"Required_argument "v" | ||
78 | "number-width\0" Required_argument "w" | ||
79 | ; | ||
80 | |||
81 | applet_long_options = nl_longopts; | ||
82 | #endif | ||
83 | ns.width = 6; | ||
84 | ns.start = 1; | ||
85 | ns.inc = 1; | ||
86 | ns.sep = "\t"; | ||
87 | getopt32(argv, "pw:+s:v:+i:+b:", &ns.width, &ns.sep, &ns.start, &ns.inc, &opt_b); | ||
88 | ns.all = (opt_b[0] == 'a'); | ||
89 | ns.nonempty = (opt_b[0] == 't'); | ||
90 | ns.empty_str = xasprintf("%*s\n", ns.width + (int)strlen(ns.sep), ""); | ||
91 | |||
92 | argv += optind; | ||
93 | if (!*argv) | ||
94 | *--argv = (char*)"-"; | ||
95 | |||
96 | do { | ||
97 | print_numbered_lines(&ns, *argv); | ||
98 | } while (*++argv); | ||
99 | |||
100 | fflush_stdout_and_exit(EXIT_SUCCESS); | ||
101 | } | ||
diff --git a/coreutils/nproc.c b/coreutils/nproc.c new file mode 100644 index 000000000..d7c6a4ba1 --- /dev/null +++ b/coreutils/nproc.c | |||
@@ -0,0 +1,51 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2017 Denys Vlasenko <vda.linux@googlemail.com> | ||
3 | * | ||
4 | * Licensed under GPLv2, see LICENSE in this source tree | ||
5 | */ | ||
6 | //config:config NPROC | ||
7 | //config: bool "nproc" | ||
8 | //config: default y | ||
9 | //config: help | ||
10 | //config: Print number of CPUs | ||
11 | |||
12 | //applet:IF_NPROC(APPLET(nproc, BB_DIR_USR_BIN, BB_SUID_DROP)) | ||
13 | |||
14 | //kbuild:lib-$(CONFIG_NPROC) += nproc.o | ||
15 | |||
16 | //usage:#define nproc_trivial_usage | ||
17 | //usage: "" | ||
18 | //TODO: "[--all] [--ignore=N]" | ||
19 | //usage:#define nproc_full_usage "\n\n" | ||
20 | //usage: "Print number of CPUs" | ||
21 | |||
22 | #include <sched.h> | ||
23 | #include "libbb.h" | ||
24 | |||
25 | int nproc_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; | ||
26 | int nproc_main(int argc UNUSED_PARAM, char **argv UNUSED_PARAM) | ||
27 | { | ||
28 | unsigned long mask[1024]; | ||
29 | unsigned i, count = 0; | ||
30 | |||
31 | //applet_long_options = ...; | ||
32 | //getopt32(argv, ""); | ||
33 | |||
34 | //if --all, count /sys/devices/system/cpu/cpuN dirs, else: | ||
35 | |||
36 | if (sched_getaffinity(0, sizeof(mask), (void*)mask) == 0) { | ||
37 | for (i = 0; i < ARRAY_SIZE(mask); i++) { | ||
38 | unsigned long m = mask[i]; | ||
39 | while (m) { | ||
40 | if (m & 1) | ||
41 | count++; | ||
42 | m >>= 1; | ||
43 | } | ||
44 | } | ||
45 | } | ||
46 | if (count == 0) | ||
47 | count++; | ||
48 | printf("%u\n", count); | ||
49 | |||
50 | return 0; | ||
51 | } | ||
diff --git a/coreutils/paste.c b/coreutils/paste.c new file mode 100644 index 000000000..3920859d6 --- /dev/null +++ b/coreutils/paste.c | |||
@@ -0,0 +1,140 @@ | |||
1 | /* vi: set sw=4 ts=4: */ | ||
2 | /* | ||
3 | * paste.c - implementation of the posix paste command | ||
4 | * | ||
5 | * Written by Maxime Coste <mawww@kakoune.org> | ||
6 | * | ||
7 | * Licensed under GPLv2 or later, see file LICENSE in this source tree. | ||
8 | */ | ||
9 | //config:config PASTE | ||
10 | //config: bool "paste" | ||
11 | //config: default y | ||
12 | //config: help | ||
13 | //config: paste is used to paste lines of different files together | ||
14 | //config: and write the result to stdout | ||
15 | |||
16 | //applet:IF_PASTE(APPLET_NOEXEC(paste, paste, BB_DIR_USR_BIN, BB_SUID_DROP, paste)) | ||
17 | |||
18 | //kbuild:lib-$(CONFIG_PASTE) += paste.o | ||
19 | |||
20 | //usage:#define paste_trivial_usage | ||
21 | //usage: "[OPTIONS] [FILE]..." | ||
22 | //usage:#define paste_full_usage "\n\n" | ||
23 | //usage: "Paste lines from each input file, separated with tab\n" | ||
24 | //usage: "\n -d LIST Use delimiters from LIST, not tab" | ||
25 | //usage: "\n -s Serial: one file at a time" | ||
26 | //usage: | ||
27 | //usage:#define paste_example_usage | ||
28 | //usage: "# write out directory in four columns\n" | ||
29 | //usage: "$ ls | paste - - - -\n" | ||
30 | //usage: "# combine pairs of lines from a file into single lines\n" | ||
31 | //usage: "$ paste -s -d '\\t\\n' file\n" | ||
32 | |||
33 | #include "libbb.h" | ||
34 | |||
35 | static void paste_files(FILE** files, int file_cnt, char* delims, int del_cnt) | ||
36 | { | ||
37 | char *line; | ||
38 | char delim; | ||
39 | int active_files = file_cnt; | ||
40 | int i; | ||
41 | |||
42 | while (active_files > 0) { | ||
43 | int del_idx = 0; | ||
44 | |||
45 | for (i = 0; i < file_cnt; ++i) { | ||
46 | if (files[i] == NULL) | ||
47 | continue; | ||
48 | |||
49 | line = xmalloc_fgetline(files[i]); | ||
50 | if (!line) { | ||
51 | fclose_if_not_stdin(files[i]); | ||
52 | files[i] = NULL; | ||
53 | --active_files; | ||
54 | continue; | ||
55 | } | ||
56 | fputs(line, stdout); | ||
57 | free(line); | ||
58 | delim = '\n'; | ||
59 | if (i != file_cnt - 1) { | ||
60 | delim = delims[del_idx++]; | ||
61 | if (del_idx == del_cnt) | ||
62 | del_idx = 0; | ||
63 | } | ||
64 | if (delim != '\0') | ||
65 | fputc(delim, stdout); | ||
66 | } | ||
67 | } | ||
68 | } | ||
69 | |||
70 | static void paste_files_separate(FILE** files, char* delims, int del_cnt) | ||
71 | { | ||
72 | char *line, *next_line; | ||
73 | char delim; | ||
74 | int i; | ||
75 | |||
76 | for (i = 0; files[i]; ++i) { | ||
77 | int del_idx = 0; | ||
78 | |||
79 | line = NULL; | ||
80 | while ((next_line = xmalloc_fgetline(files[i])) != NULL) { | ||
81 | if (line) { | ||
82 | fputs(line, stdout); | ||
83 | free(line); | ||
84 | delim = delims[del_idx++]; | ||
85 | if (del_idx == del_cnt) | ||
86 | del_idx = 0; | ||
87 | if (delim != '\0') | ||
88 | fputc(delim, stdout); | ||
89 | } | ||
90 | line = next_line; | ||
91 | } | ||
92 | if (line) { | ||
93 | /* coreutils adds \n even if this is a final line | ||
94 | * of the last file and it was not \n-terminated. | ||
95 | */ | ||
96 | printf("%s\n", line); | ||
97 | free(line); | ||
98 | } | ||
99 | fclose_if_not_stdin(files[i]); | ||
100 | } | ||
101 | } | ||
102 | |||
103 | #define PASTE_OPT_DELIMITERS (1 << 0) | ||
104 | #define PASTE_OPT_SEPARATE (1 << 1) | ||
105 | |||
106 | int paste_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; | ||
107 | int paste_main(int argc UNUSED_PARAM, char **argv) | ||
108 | { | ||
109 | char *delims = (char*)"\t"; | ||
110 | int del_cnt = 1; | ||
111 | unsigned opt; | ||
112 | int i; | ||
113 | |||
114 | opt = getopt32(argv, "d:s", &delims); | ||
115 | argv += optind; | ||
116 | |||
117 | if (opt & PASTE_OPT_DELIMITERS) { | ||
118 | if (!delims[0]) | ||
119 | bb_error_msg_and_die("-d '' is not supported"); | ||
120 | /* unknown mappings are not changed: "\z" -> '\\' 'z' */ | ||
121 | /* trailing backslash, if any, is preserved */ | ||
122 | del_cnt = strcpy_and_process_escape_sequences(delims, delims) - delims; | ||
123 | /* note: handle NUL properly (do not stop at it!): try -d'\t\0\t' */ | ||
124 | } | ||
125 | |||
126 | if (!argv[0]) | ||
127 | (--argv)[0] = (char*) "-"; | ||
128 | for (i = 0; argv[i]; ++i) { | ||
129 | argv[i] = (void*) fopen_or_warn_stdin(argv[i]); | ||
130 | if (!argv[i]) | ||
131 | xfunc_die(); | ||
132 | } | ||
133 | |||
134 | if (opt & PASTE_OPT_SEPARATE) | ||
135 | paste_files_separate((FILE**)argv, delims, del_cnt); | ||
136 | else | ||
137 | paste_files((FILE**)argv, i, delims, del_cnt); | ||
138 | |||
139 | fflush_stdout_and_exit(0); | ||
140 | } | ||
diff --git a/coreutils/shred.c b/coreutils/shred.c new file mode 100644 index 000000000..b3c009539 --- /dev/null +++ b/coreutils/shred.c | |||
@@ -0,0 +1,106 @@ | |||
1 | /* vi: set sw=4 ts=4: */ | ||
2 | /* | ||
3 | * Copyright (C) 2017 Denys Vlasenko <vda.linux@googlemail.com> | ||
4 | * | ||
5 | * Licensed under GPLv2, see file LICENSE in this source tree. | ||
6 | */ | ||
7 | //config:config SHRED | ||
8 | //config: bool "shred" | ||
9 | //config: default y | ||
10 | //config: help | ||
11 | //config: Overwrite a file to hide its contents, and optionally delete it | ||
12 | |||
13 | //applet:IF_SHRED(APPLET(shred, BB_DIR_USR_BIN, BB_SUID_DROP)) | ||
14 | |||
15 | //kbuild:lib-$(CONFIG_SHRED) += shred.o | ||
16 | |||
17 | //usage:#define shred_trivial_usage | ||
18 | //usage: "FILE..." | ||
19 | //usage:#define shred_full_usage "\n\n" | ||
20 | //usage: "Overwrite/delete FILEs\n" | ||
21 | //usage: "\n -f Chmod to ensure writability" | ||
22 | //usage: "\n -n N Overwrite N times (default 3)" | ||
23 | //usage: "\n -z Final overwrite with zeros" | ||
24 | //usage: "\n -u Remove file" | ||
25 | //-x and -v are accepted but have no effect | ||
26 | |||
27 | /* shred (GNU coreutils) 8.25: | ||
28 | -f, --force change permissions to allow writing if necessary | ||
29 | -u truncate and remove file after overwriting | ||
30 | -z, --zero add a final overwrite with zeros to hide shredding | ||
31 | -n, --iterations=N overwrite N times instead of the default (3) | ||
32 | -v, --verbose show progress | ||
33 | -x, --exact do not round file sizes up to the next full block; this is the default for non-regular files | ||
34 | --random-source=FILE get random bytes from FILE | ||
35 | -s, --size=N shred this many bytes (suffixes like K, M, G accepted) | ||
36 | --remove[=HOW] like -u but give control on HOW to delete; See below | ||
37 | */ | ||
38 | |||
39 | #include "libbb.h" | ||
40 | |||
41 | int shred_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; | ||
42 | int shred_main(int argc UNUSED_PARAM, char **argv) | ||
43 | { | ||
44 | int rand_fd = rand_fd; /* for compiler */ | ||
45 | int zero_fd; | ||
46 | unsigned num_iter = 3; | ||
47 | unsigned opt; | ||
48 | enum { | ||
49 | OPT_f = (1 << 0), | ||
50 | OPT_u = (1 << 1), | ||
51 | OPT_z = (1 << 2), | ||
52 | OPT_n = (1 << 3), | ||
53 | OPT_v = (1 << 4), | ||
54 | OPT_x = (1 << 5), | ||
55 | }; | ||
56 | |||
57 | opt = getopt32(argv, "fuzn:+vx", &num_iter); | ||
58 | argv += optind; | ||
59 | |||
60 | zero_fd = xopen("/dev/zero", O_RDONLY); | ||
61 | if (num_iter != 0) | ||
62 | rand_fd = xopen("/dev/urandom", O_RDONLY); | ||
63 | |||
64 | if (!*argv) | ||
65 | bb_show_usage(); | ||
66 | |||
67 | for (;;) { | ||
68 | struct stat sb; | ||
69 | const char *fname; | ||
70 | unsigned i; | ||
71 | int fd; | ||
72 | |||
73 | fname = *argv++; | ||
74 | if (!fname) | ||
75 | break; | ||
76 | fd = -1; | ||
77 | if (opt & OPT_f) { | ||
78 | fd = open(fname, O_WRONLY); | ||
79 | if (fd < 0) | ||
80 | chmod(fname, 0666); | ||
81 | } | ||
82 | if (fd < 0) | ||
83 | fd = xopen(fname, O_WRONLY); | ||
84 | |||
85 | if (fstat(fd, &sb) == 0 && sb.st_size > 0) { | ||
86 | off_t size = sb.st_size; | ||
87 | |||
88 | for (i = 0; i < num_iter; i++) { | ||
89 | bb_copyfd_size(rand_fd, fd, size); | ||
90 | fdatasync(fd); | ||
91 | xlseek(fd, 0, SEEK_SET); | ||
92 | } | ||
93 | if (opt & OPT_z) { | ||
94 | bb_copyfd_size(zero_fd, fd, size); | ||
95 | fdatasync(fd); | ||
96 | } | ||
97 | if (opt & OPT_u) { | ||
98 | ftruncate(fd, 0); | ||
99 | xunlink(fname); | ||
100 | } | ||
101 | xclose(fd); | ||
102 | } | ||
103 | } | ||
104 | |||
105 | return EXIT_SUCCESS; | ||
106 | } | ||
diff --git a/miscutils/timeout.c b/coreutils/timeout.c index f29dc8a9c..f29dc8a9c 100644 --- a/miscutils/timeout.c +++ b/coreutils/timeout.c | |||
diff --git a/coreutils/uniq.c b/coreutils/uniq.c index be550b5cd..2b62ad3ae 100644 --- a/coreutils/uniq.c +++ b/coreutils/uniq.c | |||
@@ -26,6 +26,7 @@ | |||
26 | //usage: "\n -c Prefix lines by the number of occurrences" | 26 | //usage: "\n -c Prefix lines by the number of occurrences" |
27 | //usage: "\n -d Only print duplicate lines" | 27 | //usage: "\n -d Only print duplicate lines" |
28 | //usage: "\n -u Only print unique lines" | 28 | //usage: "\n -u Only print unique lines" |
29 | //usage: "\n -i Ignore case" | ||
29 | //usage: "\n -f N Skip first N fields" | 30 | //usage: "\n -f N Skip first N fields" |
30 | //usage: "\n -s N Skip first N chars (after any skipped fields)" | 31 | //usage: "\n -s N Skip first N chars (after any skipped fields)" |
31 | //usage: "\n -w N Compare N characters in line" | 32 | //usage: "\n -w N Compare N characters in line" |
@@ -54,12 +55,13 @@ int uniq_main(int argc UNUSED_PARAM, char **argv) | |||
54 | OPT_f = 0x8, | 55 | OPT_f = 0x8, |
55 | OPT_s = 0x10, | 56 | OPT_s = 0x10, |
56 | OPT_w = 0x20, | 57 | OPT_w = 0x20, |
58 | OPT_i = 0x40, | ||
57 | }; | 59 | }; |
58 | 60 | ||
59 | skip_fields = skip_chars = 0; | 61 | skip_fields = skip_chars = 0; |
60 | max_chars = INT_MAX; | 62 | max_chars = INT_MAX; |
61 | 63 | ||
62 | opt = getopt32(argv, "cduf:+s:+w:+", &skip_fields, &skip_chars, &max_chars); | 64 | opt = getopt32(argv, "cduf:+s:+w:+i", &skip_fields, &skip_chars, &max_chars); |
63 | argv += optind; | 65 | argv += optind; |
64 | 66 | ||
65 | input_filename = argv[0]; | 67 | input_filename = argv[0]; |
@@ -106,7 +108,12 @@ int uniq_main(int argc UNUSED_PARAM, char **argv) | |||
106 | ++cur_compare; | 108 | ++cur_compare; |
107 | } | 109 | } |
108 | 110 | ||
109 | if (!old_line || strncmp(old_compare, cur_compare, max_chars)) { | 111 | if (!old_line) |
112 | break; | ||
113 | if ((opt & OPT_i) | ||
114 | ? strncasecmp(old_compare, cur_compare, max_chars) | ||
115 | : strncmp(old_compare, cur_compare, max_chars) | ||
116 | ) { | ||
110 | break; | 117 | break; |
111 | } | 118 | } |
112 | 119 | ||
diff --git a/coreutils/who.c b/coreutils/who.c index e6179bb00..4adead77e 100644 --- a/coreutils/who.c +++ b/coreutils/who.c | |||
@@ -23,6 +23,14 @@ | |||
23 | //config: help | 23 | //config: help |
24 | //config: who is used to show who is logged on. | 24 | //config: who is used to show who is logged on. |
25 | //config: | 25 | //config: |
26 | // procps-ng has this variation of "who": | ||
27 | //config:config W | ||
28 | //config: bool "w" | ||
29 | //config: default y | ||
30 | //config: depends on FEATURE_UTMP | ||
31 | //config: help | ||
32 | //config: w is used to show who is logged on. | ||
33 | //config: | ||
26 | //config:config USERS | 34 | //config:config USERS |
27 | //config: bool "users" | 35 | //config: bool "users" |
28 | //config: default y | 36 | //config: default y |
@@ -32,10 +40,12 @@ | |||
32 | 40 | ||
33 | // APPLET_ODDNAME:name main location suid_type help | 41 | // APPLET_ODDNAME:name main location suid_type help |
34 | //applet:IF_USERS(APPLET_ODDNAME(users, who, BB_DIR_USR_BIN, BB_SUID_DROP, users)) | 42 | //applet:IF_USERS(APPLET_ODDNAME(users, who, BB_DIR_USR_BIN, BB_SUID_DROP, users)) |
35 | //applet:IF_WHO(APPLET(who, BB_DIR_USR_BIN, BB_SUID_DROP)) | 43 | //applet:IF_W( APPLET_ODDNAME(w, who, BB_DIR_USR_BIN, BB_SUID_DROP, w)) |
44 | //applet:IF_WHO( APPLET( who, BB_DIR_USR_BIN, BB_SUID_DROP)) | ||
36 | 45 | ||
37 | //kbuild:lib-$(CONFIG_USERS) += who.o | 46 | //kbuild:lib-$(CONFIG_USERS) += who.o |
38 | //kbuild:lib-$(CONFIG_WHO) += who.o | 47 | //kbuild:lib-$(CONFIG_W) += who.o |
48 | //kbuild:lib-$(CONFIG_WHO) += who.o | ||
39 | 49 | ||
40 | /* BB_AUDIT SUSv3 _NOT_ compliant -- missing options -b, -d, -l, -m, -p, -q, -r, -s, -t, -T, -u; Missing argument 'file'. */ | 50 | /* BB_AUDIT SUSv3 _NOT_ compliant -- missing options -b, -d, -l, -m, -p, -q, -r, -s, -t, -T, -u; Missing argument 'file'. */ |
41 | 51 | ||
@@ -44,6 +54,31 @@ | |||
44 | //usage:#define users_full_usage "\n\n" | 54 | //usage:#define users_full_usage "\n\n" |
45 | //usage: "Print the users currently logged on" | 55 | //usage: "Print the users currently logged on" |
46 | 56 | ||
57 | //usage:#define w_trivial_usage | ||
58 | //usage: "" | ||
59 | //usage:#define w_full_usage "\n\n" | ||
60 | //usage: "Show who is logged on" | ||
61 | // | ||
62 | // procps-ng 3.3.10: | ||
63 | // "\n -h, --no-header" | ||
64 | // "\n -u, --no-current" | ||
65 | // Ignores the username while figuring out the current process | ||
66 | // and cpu times. To demonstrate this, do a "su" and do a "w" and a "w -u". | ||
67 | // "\n -s, --short" | ||
68 | // Short format. Don't print the login time, JCPU or PCPU times. | ||
69 | // "\n -f, --from" | ||
70 | // Toggle printing the from (remote hostname) field. | ||
71 | // The default is for the from field to not be printed | ||
72 | // "\n -i, --ip-addr" | ||
73 | // Display IP address instead of hostname for from field. | ||
74 | // "\n -o, --old-style" | ||
75 | // Old style output. Prints blank space for idle times less than one minute. | ||
76 | // Example output: | ||
77 | // 17:28:00 up 4 days, 22:41, 4 users, load average: 0.84, 0.97, 0.90 | ||
78 | // USER TTY LOGIN@ IDLE JCPU PCPU WHAT | ||
79 | // root tty1 Thu18 4days 4:33m 0.07s /bin/sh /etc/xdg/xfce4/xinitrc -- vt | ||
80 | // root pts/1 Mon13 3:24m 1:01 0.01s w | ||
81 | |||
47 | //usage:#define who_trivial_usage | 82 | //usage:#define who_trivial_usage |
48 | //usage: "[-a]" | 83 | //usage: "[-a]" |
49 | //usage:#define who_full_usage "\n\n" | 84 | //usage:#define who_full_usage "\n\n" |
@@ -74,14 +109,17 @@ static void idle_string(char *str6, time_t t) | |||
74 | int who_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; | 109 | int who_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; |
75 | int who_main(int argc UNUSED_PARAM, char **argv) | 110 | int who_main(int argc UNUSED_PARAM, char **argv) |
76 | { | 111 | { |
112 | #define CNT_APPLET (ENABLE_USERS + ENABLE_W + ENABLE_WHO) | ||
113 | int do_users = (ENABLE_USERS && (CNT_APPLET == 1 || applet_name[0] == 'u')); | ||
114 | int do_w = (ENABLE_W && (CNT_APPLET == 1 || applet_name[1] == '\0')); | ||
115 | int do_who = (ENABLE_WHO && (CNT_APPLET == 1 || applet_name[1] == 'h')); | ||
77 | struct utmpx *ut; | 116 | struct utmpx *ut; |
78 | unsigned opt; | 117 | unsigned opt; |
79 | int do_users = (ENABLE_USERS && (!ENABLE_WHO || applet_name[0] == 'u')); | ||
80 | const char *fmt = "%s"; | 118 | const char *fmt = "%s"; |
81 | 119 | ||
82 | opt_complementary = "=0"; | 120 | opt_complementary = "=0"; |
83 | opt = getopt32(argv, do_users ? "" : "aH"); | 121 | opt = getopt32(argv, do_who ? "aH" : ""); |
84 | if (opt & 2) // -H | 122 | if ((opt & 2) || do_w) /* -H or we are w */ |
85 | puts("USER\t\tTTY\t\tIDLE\tTIME\t\t HOST"); | 123 | puts("USER\t\tTTY\t\tIDLE\tTIME\t\t HOST"); |
86 | 124 | ||
87 | setutxent(); | 125 | setutxent(); |
@@ -115,6 +153,9 @@ int who_main(int argc UNUSED_PARAM, char **argv) | |||
115 | (int)sizeof(ut->ut_user), ut->ut_user, | 153 | (int)sizeof(ut->ut_user), ut->ut_user, |
116 | (int)sizeof(ut->ut_line), ut->ut_line, | 154 | (int)sizeof(ut->ut_line), ut->ut_line, |
117 | str6, | 155 | str6, |
156 | // TODO: with LANG=en_US.UTF-8, who from coreutils 8.25 shows | ||
157 | // TIME col as "2017-04-06 18:47" (the default format is "Apr 6 18:47"). | ||
158 | // The former format looks saner to me. Switch to it unconditionally? | ||
118 | ctime(&seconds) + 4, | 159 | ctime(&seconds) + 4, |
119 | (int)sizeof(ut->ut_host), ut->ut_host | 160 | (int)sizeof(ut->ut_host), ut->ut_host |
120 | ); | 161 | ); |
diff --git a/docs/posix_conformance.txt b/docs/posix_conformance.txt index c0582dc23..8b9112020 100644 --- a/docs/posix_conformance.txt +++ b/docs/posix_conformance.txt | |||
@@ -22,7 +22,7 @@ POSIX Tools supported only as shell built-ins (ash shell): | |||
22 | POSIX Tools not supported: | 22 | POSIX Tools not supported: |
23 | asa, at, batch, bc, c99, command, compress, csplit, ex, fc, file, | 23 | asa, at, batch, bc, c99, command, compress, csplit, ex, fc, file, |
24 | gencat, getconf, iconv, join, link, locale, localedef, lp, m4, | 24 | gencat, getconf, iconv, join, link, locale, localedef, lp, m4, |
25 | mailx, newgrp, nl, paste, pathchk, pax, pr, qalter, qdel, qhold, qmove, | 25 | mailx, newgrp, nl, pathchk, pax, pr, qalter, qdel, qhold, qmove, |
26 | qmsg, qrerun, qrls, qselect, qsig, qstat, qsub, tabs, talk, tput, | 26 | qmsg, qrerun, qrls, qselect, qsig, qstat, qsub, tabs, talk, tput, |
27 | tsort, unlink, uucp, uustat, uux | 27 | tsort, unlink, uucp, uustat, uux |
28 | 28 | ||
@@ -469,6 +469,12 @@ od POSIX options | |||
469 | -x | no | no | | 469 | -x | no | no | |
470 | od Busybox specific options: None | 470 | od Busybox specific options: None |
471 | 471 | ||
472 | paste POSIX options | ||
473 | option | exists | compliant | remarks | ||
474 | -d list | yes | yes | | ||
475 | -s | yes | yes | | ||
476 | paste Busybox specific options: None | ||
477 | |||
472 | patch POSIX options | 478 | patch POSIX options |
473 | option | exists | compliant | remarks | 479 | option | exists | compliant | remarks |
474 | -D define | no | no | | 480 | -D define | no | no | |
diff --git a/docs/sigint.htm b/docs/sigint.htm index e230f4df7..d656aeb8c 100644 --- a/docs/sigint.htm +++ b/docs/sigint.htm | |||
@@ -45,7 +45,7 @@ intention. | |||
45 | 45 | ||
46 | </td></tr><tr><th valign=top align=left>Required knowledge: </th> | 46 | </td></tr><tr><th valign=top align=left>Required knowledge: </th> |
47 | <td valign=top align=left>You have to know what it means to catch SIGINT or SIGQUIT and how | 47 | <td valign=top align=left>You have to know what it means to catch SIGINT or SIGQUIT and how |
48 | processes are waiting for other processes (childs) they spawned. | 48 | processes are waiting for other processes (children) they spawned. |
49 | 49 | ||
50 | 50 | ||
51 | </td></tr></table> | 51 | </td></tr></table> |
@@ -366,7 +366,7 @@ signal, it has to take care of communicating the signal status | |||
366 | itself. | 366 | itself. |
367 | 367 | ||
368 | <p>Some programs don't do this. On SIGINT, they do cleanup and exit | 368 | <p>Some programs don't do this. On SIGINT, they do cleanup and exit |
369 | immediatly, but the calling shell isn't told about the non-normal exit | 369 | immediately, but the calling shell isn't told about the non-normal exit |
370 | and it will call the next program in the script. | 370 | and it will call the next program in the script. |
371 | 371 | ||
372 | <p>As a result, the user hits SIGINT and while one program exits, the | 372 | <p>As a result, the user hits SIGINT and while one program exits, the |
@@ -446,7 +446,7 @@ handlers, so it is portable. | |||
446 | <code>trap</code> command. Here, the same as for C programs apply. If | 446 | <code>trap</code> command. Here, the same as for C programs apply. If |
447 | the intention of SIGINT is to end your program, you have to exit in a | 447 | the intention of SIGINT is to end your program, you have to exit in a |
448 | way that the calling programs "sees" that you have been killed. If | 448 | way that the calling programs "sees" that you have been killed. If |
449 | you don't catch SIGINT, this happend automatically, but of you catch | 449 | you don't catch SIGINT, this happened automatically, but of you catch |
450 | SIGINT, i.e. to do cleanup work, you have to end the program by | 450 | SIGINT, i.e. to do cleanup work, you have to end the program by |
451 | killing yourself, not by calling exit. | 451 | killing yourself, not by calling exit. |
452 | 452 | ||
@@ -466,7 +466,7 @@ files (which isn't really portable in C, though). | |||
466 | bourne shell. Every language implementation that lets you catch SIGINT | 466 | bourne shell. Every language implementation that lets you catch SIGINT |
467 | should also give you the option to reset the signal and kill yourself. | 467 | should also give you the option to reset the signal and kill yourself. |
468 | 468 | ||
469 | <P>It is always desireable to exit the right way, even if you don't | 469 | <P>It is always desirable to exit the right way, even if you don't |
470 | expect your usual callers to depend on it, some unusual one will come | 470 | expect your usual callers to depend on it, some unusual one will come |
471 | along. This proper exit status will be needed for WCE and will not | 471 | along. This proper exit status will be needed for WCE and will not |
472 | hurt when the calling shell uses IUE or WUE. | 472 | hurt when the calling shell uses IUE or WUE. |
@@ -565,7 +565,7 @@ comments the scripts echo. | |||
565 | <th>What happens when a shellscript called emacs, the user did not use | 565 | <th>What happens when a shellscript called emacs, the user did not use |
566 | <code>C-c</code> and the script has additional commands in it?</th> | 566 | <code>C-c</code> and the script has additional commands in it?</th> |
567 | <th>What happens if a non-interactive child catches SIGINT?</th> | 567 | <th>What happens if a non-interactive child catches SIGINT?</th> |
568 | <th>To behave properly, childs must do what?</th> | 568 | <th>To behave properly, children must do what?</th> |
569 | </tr> | 569 | </tr> |
570 | 570 | ||
571 | <tr valign=top align=left> | 571 | <tr valign=top align=left> |
diff --git a/docs/style-guide.txt b/docs/style-guide.txt index 10ed893dc..9eed7f125 100644 --- a/docs/style-guide.txt +++ b/docs/style-guide.txt | |||
@@ -329,7 +329,7 @@ With "const int" compiler may fail to optimize it out and will reserve | |||
329 | a real storage in rodata for it! (Hopefully, newer gcc will get better | 329 | a real storage in rodata for it! (Hopefully, newer gcc will get better |
330 | at it...). With "define", you have slight risk of polluting namespace | 330 | at it...). With "define", you have slight risk of polluting namespace |
331 | (#define doesn't allow you to redefine the name in the inner scopes), | 331 | (#define doesn't allow you to redefine the name in the inner scopes), |
332 | and complex "define" are evaluated each time they uesd, not once | 332 | and complex "define" are evaluated each time they used, not once |
333 | at declarations like enums. Also, the preprocessor does _no_ type checking | 333 | at declarations like enums. Also, the preprocessor does _no_ type checking |
334 | whatsoever, making it much more error prone. | 334 | whatsoever, making it much more error prone. |
335 | 335 | ||
diff --git a/editors/diff.c b/editors/diff.c index f2eeb8257..975bc4603 100644 --- a/editors/diff.c +++ b/editors/diff.c | |||
@@ -295,17 +295,6 @@ static int search(const int *c, int k, int y, const struct cand *list) | |||
295 | } | 295 | } |
296 | } | 296 | } |
297 | 297 | ||
298 | static unsigned isqrt(unsigned n) | ||
299 | { | ||
300 | unsigned x = 1; | ||
301 | while (1) { | ||
302 | const unsigned y = x; | ||
303 | x = ((n / x) + x) >> 1; | ||
304 | if (x <= (y + 1) && x >= (y - 1)) | ||
305 | return x; | ||
306 | } | ||
307 | } | ||
308 | |||
309 | static void stone(const int *a, int n, const int *b, int *J, int pref) | 298 | static void stone(const int *a, int n, const int *b, int *J, int pref) |
310 | { | 299 | { |
311 | const unsigned isq = isqrt(n); | 300 | const unsigned isq = isqrt(n); |
@@ -730,9 +719,19 @@ static int diffreg(char *file[2]) | |||
730 | fp[0] = stdin; | 719 | fp[0] = stdin; |
731 | fp[1] = stdin; | 720 | fp[1] = stdin; |
732 | for (i = 0; i < 2; i++) { | 721 | for (i = 0; i < 2; i++) { |
733 | int fd = open_or_warn_stdin(file[i]); | 722 | int fd = STDIN_FILENO; |
734 | if (fd == -1) | 723 | if (!LONE_DASH(file[i])) { |
735 | goto out; | 724 | if (!(option_mask32 & FLAG(N))) { |
725 | fd = open_or_warn(file[i], O_RDONLY); | ||
726 | if (fd == -1) | ||
727 | goto out; | ||
728 | } else { | ||
729 | /* -N: if some file does not exist compare it like empty */ | ||
730 | fd = open(file[i], O_RDONLY); | ||
731 | if (fd == -1) | ||
732 | fd = xopen("/dev/null", O_RDONLY); | ||
733 | } | ||
734 | } | ||
736 | /* Our diff implementation is using seek. | 735 | /* Our diff implementation is using seek. |
737 | * When we meet non-seekable file, we must make a temp copy. | 736 | * When we meet non-seekable file, we must make a temp copy. |
738 | */ | 737 | */ |
@@ -1010,17 +1009,23 @@ int diff_main(int argc UNUSED_PARAM, char **argv) | |||
1010 | argv += optind; | 1009 | argv += optind; |
1011 | while (L_arg) | 1010 | while (L_arg) |
1012 | label[!!label[0]] = llist_pop(&L_arg); | 1011 | label[!!label[0]] = llist_pop(&L_arg); |
1012 | |||
1013 | /* Compat: "diff file name_which_doesnt_exist" exits with 2 */ | ||
1013 | xfunc_error_retval = 2; | 1014 | xfunc_error_retval = 2; |
1014 | for (i = 0; i < 2; i++) { | 1015 | for (i = 0; i < 2; i++) { |
1015 | file[i] = argv[i]; | 1016 | file[i] = argv[i]; |
1016 | /* Compat: "diff file name_which_doesnt_exist" exits with 2 */ | ||
1017 | if (LONE_DASH(file[i])) { | 1017 | if (LONE_DASH(file[i])) { |
1018 | fstat(STDIN_FILENO, &stb[i]); | 1018 | fstat(STDIN_FILENO, &stb[i]); |
1019 | gotstdin++; | 1019 | gotstdin++; |
1020 | } else | 1020 | } else if (option_mask32 & FLAG(N)) { |
1021 | if (stat(file[i], &stb[i])) | ||
1022 | xstat("/dev/null", &stb[i]); | ||
1023 | } else { | ||
1021 | xstat(file[i], &stb[i]); | 1024 | xstat(file[i], &stb[i]); |
1025 | } | ||
1022 | } | 1026 | } |
1023 | xfunc_error_retval = 1; | 1027 | xfunc_error_retval = 1; |
1028 | |||
1024 | if (gotstdin && (S_ISDIR(stb[0].st_mode) || S_ISDIR(stb[1].st_mode))) | 1029 | if (gotstdin && (S_ISDIR(stb[0].st_mode) || S_ISDIR(stb[1].st_mode))) |
1025 | bb_error_msg_and_die("can't compare stdin to a directory"); | 1030 | bb_error_msg_and_die("can't compare stdin to a directory"); |
1026 | 1031 | ||
diff --git a/editors/sed.c b/editors/sed.c index 86230ea42..b2c7ba829 100644 --- a/editors/sed.c +++ b/editors/sed.c | |||
@@ -337,7 +337,7 @@ static int get_address(const char *my_str, int *linenum, regex_t ** regex) | |||
337 | 337 | ||
338 | if (isdigit(*my_str)) { | 338 | if (isdigit(*my_str)) { |
339 | *linenum = strtol(my_str, (char**)&pos, 10); | 339 | *linenum = strtol(my_str, (char**)&pos, 10); |
340 | /* endstr shouldnt ever equal NULL */ | 340 | /* endstr shouldn't ever equal NULL */ |
341 | } else if (*my_str == '$') { | 341 | } else if (*my_str == '$') { |
342 | *linenum = -1; | 342 | *linenum = -1; |
343 | pos++; | 343 | pos++; |
@@ -444,7 +444,7 @@ static int parse_subst_cmd(sed_cmd_t *sed_cmd, const char *substr) | |||
444 | free(fname); | 444 | free(fname); |
445 | break; | 445 | break; |
446 | } | 446 | } |
447 | /* Ignore case (gnu exension) */ | 447 | /* Ignore case (gnu extension) */ |
448 | case 'i': | 448 | case 'i': |
449 | case 'I': | 449 | case 'I': |
450 | cflags |= REG_ICASE; | 450 | cflags |= REG_ICASE; |
@@ -587,7 +587,7 @@ static const char *parse_cmd_args(sed_cmd_t *sed_cmd, const char *cmdstr) | |||
587 | free(match); | 587 | free(match); |
588 | free(replace); | 588 | free(replace); |
589 | } | 589 | } |
590 | /* if it wasnt a single-letter command that takes no arguments | 590 | /* if it wasn't a single-letter command that takes no arguments |
591 | * then it must be an invalid command. | 591 | * then it must be an invalid command. |
592 | */ | 592 | */ |
593 | else if (idx >= IDX_nul) { /* not d,D,g,G,h,H,l,n,N,p,P,q,x,=,{,} */ | 593 | else if (idx >= IDX_nul) { /* not d,D,g,G,h,H,l,n,N,p,P,q,x,=,{,} */ |
@@ -751,7 +751,7 @@ static void do_subst_w_backrefs(char *line, char *replace) | |||
751 | continue; | 751 | continue; |
752 | } | 752 | } |
753 | /* I _think_ it is impossible to get '\' to be | 753 | /* I _think_ it is impossible to get '\' to be |
754 | * the last char in replace string. Thus we dont check | 754 | * the last char in replace string. Thus we don't check |
755 | * for replace[i] == NUL. (counterexample anyone?) */ | 755 | * for replace[i] == NUL. (counterexample anyone?) */ |
756 | /* if we find a backslash escaped character, print the character */ | 756 | /* if we find a backslash escaped character, print the character */ |
757 | pipe_putc(replace[i]); | 757 | pipe_putc(replace[i]); |
diff --git a/editors/vi.c b/editors/vi.c index e5ca3adfa..900b41cb5 100644 --- a/editors/vi.c +++ b/editors/vi.c | |||
@@ -715,14 +715,6 @@ static int init_text_buffer(char *fn) | |||
715 | { | 715 | { |
716 | int rc; | 716 | int rc; |
717 | 717 | ||
718 | flush_undo_data(); | ||
719 | modified_count = 0; | ||
720 | last_modified_count = -1; | ||
721 | #if ENABLE_FEATURE_VI_YANKMARK | ||
722 | /* init the marks */ | ||
723 | memset(mark, 0, sizeof(mark)); | ||
724 | #endif | ||
725 | |||
726 | /* allocate/reallocate text buffer */ | 718 | /* allocate/reallocate text buffer */ |
727 | free(text); | 719 | free(text); |
728 | text_size = 10240; | 720 | text_size = 10240; |
@@ -737,6 +729,14 @@ static int init_text_buffer(char *fn) | |||
737 | // file doesnt exist. Start empty buf with dummy line | 729 | // file doesnt exist. Start empty buf with dummy line |
738 | char_insert(text, '\n', NO_UNDO); | 730 | char_insert(text, '\n', NO_UNDO); |
739 | } | 731 | } |
732 | |||
733 | flush_undo_data(); | ||
734 | modified_count = 0; | ||
735 | last_modified_count = -1; | ||
736 | #if ENABLE_FEATURE_VI_YANKMARK | ||
737 | /* init the marks */ | ||
738 | memset(mark, 0, sizeof(mark)); | ||
739 | #endif | ||
740 | return rc; | 740 | return rc; |
741 | } | 741 | } |
742 | 742 | ||
@@ -1034,7 +1034,9 @@ static void colon(char *buf) | |||
1034 | || strncmp(p, "wn", cnt) == 0 | 1034 | || strncmp(p, "wn", cnt) == 0 |
1035 | || (p[0] == 'x' && !p[1]) | 1035 | || (p[0] == 'x' && !p[1]) |
1036 | ) { | 1036 | ) { |
1037 | cnt = file_write(current_filename, text, end - 1); | 1037 | if (modified_count != 0 || p[0] != 'x') { |
1038 | cnt = file_write(current_filename, text, end - 1); | ||
1039 | } | ||
1038 | if (cnt < 0) { | 1040 | if (cnt < 0) { |
1039 | if (cnt == -1) | 1041 | if (cnt == -1) |
1040 | status_line_bold("Write error: %s", strerror(errno)); | 1042 | status_line_bold("Write error: %s", strerror(errno)); |
@@ -1045,8 +1047,9 @@ static void colon(char *buf) | |||
1045 | current_filename, | 1047 | current_filename, |
1046 | count_lines(text, end - 1), cnt | 1048 | count_lines(text, end - 1), cnt |
1047 | ); | 1049 | ); |
1048 | if (p[0] == 'x' || p[1] == 'q' || p[1] == 'n' | 1050 | if (p[0] == 'x' |
1049 | || p[0] == 'X' || p[1] == 'Q' || p[1] == 'N' | 1051 | || p[1] == 'q' || p[1] == 'n' |
1052 | || p[1] == 'Q' || p[1] == 'N' | ||
1050 | ) { | 1053 | ) { |
1051 | editing = 0; | 1054 | editing = 0; |
1052 | } | 1055 | } |
@@ -1476,16 +1479,19 @@ static void colon(char *buf) | |||
1476 | goto ret; | 1479 | goto ret; |
1477 | } | 1480 | } |
1478 | #endif | 1481 | #endif |
1479 | // how many lines in text[]? | ||
1480 | li = count_lines(q, r); | ||
1481 | size = r - q + 1; | ||
1482 | //if (useforce) { | 1482 | //if (useforce) { |
1483 | // if "fn" is not write-able, chmod u+w | 1483 | // if "fn" is not write-able, chmod u+w |
1484 | // sprintf(syscmd, "chmod u+w %s", fn); | 1484 | // sprintf(syscmd, "chmod u+w %s", fn); |
1485 | // system(syscmd); | 1485 | // system(syscmd); |
1486 | // forced = TRUE; | 1486 | // forced = TRUE; |
1487 | //} | 1487 | //} |
1488 | l = file_write(fn, q, r); | 1488 | if (modified_count != 0 || cmd[0] != 'x') { |
1489 | size = r - q + 1; | ||
1490 | l = file_write(fn, q, r); | ||
1491 | } else { | ||
1492 | size = 0; | ||
1493 | l = 0; | ||
1494 | } | ||
1489 | //if (useforce && forced) { | 1495 | //if (useforce && forced) { |
1490 | // chmod u-w | 1496 | // chmod u-w |
1491 | // sprintf(syscmd, "chmod u-w %s", fn); | 1497 | // sprintf(syscmd, "chmod u-w %s", fn); |
@@ -1496,17 +1502,20 @@ static void colon(char *buf) | |||
1496 | if (l == -1) | 1502 | if (l == -1) |
1497 | status_line_bold_errno(fn); | 1503 | status_line_bold_errno(fn); |
1498 | } else { | 1504 | } else { |
1505 | // how many lines written | ||
1506 | li = count_lines(q, q + l - 1); | ||
1499 | status_line("'%s' %dL, %dC", fn, li, l); | 1507 | status_line("'%s' %dL, %dC", fn, li, l); |
1500 | if (q == text && r == end - 1 && l == size) { | 1508 | if (l == size) { |
1501 | modified_count = 0; | 1509 | if (q == text && q + l == end) { |
1502 | last_modified_count = -1; | 1510 | modified_count = 0; |
1503 | } | 1511 | last_modified_count = -1; |
1504 | if ((cmd[0] == 'x' || cmd[1] == 'q' || cmd[1] == 'n' | 1512 | } |
1505 | || cmd[0] == 'X' || cmd[1] == 'Q' || cmd[1] == 'N' | 1513 | if (cmd[0] == 'x' |
1506 | ) | 1514 | || cmd[1] == 'q' || cmd[1] == 'n' |
1507 | && l == size | 1515 | || cmd[1] == 'Q' || cmd[1] == 'N' |
1508 | ) { | 1516 | ) { |
1509 | editing = 0; | 1517 | editing = 0; |
1518 | } | ||
1510 | } | 1519 | } |
1511 | } | 1520 | } |
1512 | #if ENABLE_FEATURE_VI_YANKMARK | 1521 | #if ENABLE_FEATURE_VI_YANKMARK |
@@ -2816,8 +2825,15 @@ static int readit(void) // read (maybe cursor) key from stdin | |||
2816 | int c; | 2825 | int c; |
2817 | 2826 | ||
2818 | fflush_all(); | 2827 | fflush_all(); |
2819 | c = read_key(STDIN_FILENO, readbuffer, /*timeout off:*/ -2); | 2828 | |
2829 | // Wait for input. TIMEOUT = -1 makes read_key wait even | ||
2830 | // on nonblocking stdin. | ||
2831 | // Note: read_key sets errno to 0 on success. | ||
2832 | again: | ||
2833 | c = read_key(STDIN_FILENO, readbuffer, /*timeout:*/ -1); | ||
2820 | if (c == -1) { // EOF/error | 2834 | if (c == -1) { // EOF/error |
2835 | if (errno == EAGAIN) // paranoia | ||
2836 | goto again; | ||
2821 | go_bottom_and_clear_to_eol(); | 2837 | go_bottom_and_clear_to_eol(); |
2822 | cookmode(); // terminal to "cooked" | 2838 | cookmode(); // terminal to "cooked" |
2823 | bb_error_msg_and_die("can't read user input"); | 2839 | bb_error_msg_and_die("can't read user input"); |
diff --git a/examples/udhcp/sample.bound b/examples/udhcp/sample.bound index 7c9d857e0..efd98cf15 100755 --- a/examples/udhcp/sample.bound +++ b/examples/udhcp/sample.bound | |||
@@ -18,11 +18,18 @@ then | |||
18 | metric=0 | 18 | metric=0 |
19 | for i in $router | 19 | for i in $router |
20 | do | 20 | do |
21 | if [ "$subnet" = "255.255.255.255" ]; then | ||
22 | # special case for /32 subnets: | ||
23 | # /32 instructs kernel to always use routing for all outgoing packets | ||
24 | # (they can never be sent to local subnet - there is no local subnet for /32). | ||
25 | # Used in datacenters, avoids the need for private ip-addresses between two hops. | ||
26 | /sbin/ip route add $i dev $interface | ||
27 | fi | ||
21 | /sbin/route add default gw $i dev $interface metric $((metric++)) | 28 | /sbin/route add default gw $i dev $interface metric $((metric++)) |
22 | done | 29 | done |
23 | fi | 30 | fi |
24 | 31 | ||
25 | # Only replace resolv.conf is we have at least one DNS server | 32 | # Only replace resolv.conf if we have at least one DNS server |
26 | if [ -n "$dns" ] | 33 | if [ -n "$dns" ] |
27 | then | 34 | then |
28 | echo -n > $RESOLV_CONF | 35 | echo -n > $RESOLV_CONF |
diff --git a/examples/udhcp/sample.renew b/examples/udhcp/sample.renew index 4dce8486a..efd98cf15 100755 --- a/examples/udhcp/sample.renew +++ b/examples/udhcp/sample.renew | |||
@@ -1,5 +1,5 @@ | |||
1 | #!/bin/sh | 1 | #!/bin/sh |
2 | # Sample udhcpc bound script | 2 | # Sample udhcpc renew script |
3 | 3 | ||
4 | RESOLV_CONF="/etc/udhcpc/resolv.conf" | 4 | RESOLV_CONF="/etc/udhcpc/resolv.conf" |
5 | 5 | ||
@@ -18,11 +18,18 @@ then | |||
18 | metric=0 | 18 | metric=0 |
19 | for i in $router | 19 | for i in $router |
20 | do | 20 | do |
21 | if [ "$subnet" = "255.255.255.255" ]; then | ||
22 | # special case for /32 subnets: | ||
23 | # /32 instructs kernel to always use routing for all outgoing packets | ||
24 | # (they can never be sent to local subnet - there is no local subnet for /32). | ||
25 | # Used in datacenters, avoids the need for private ip-addresses between two hops. | ||
26 | /sbin/ip route add $i dev $interface | ||
27 | fi | ||
21 | /sbin/route add default gw $i dev $interface metric $((metric++)) | 28 | /sbin/route add default gw $i dev $interface metric $((metric++)) |
22 | done | 29 | done |
23 | fi | 30 | fi |
24 | 31 | ||
25 | # Only replace resolv.conf is we have at least one DNS server | 32 | # Only replace resolv.conf if we have at least one DNS server |
26 | if [ -n "$dns" ] | 33 | if [ -n "$dns" ] |
27 | then | 34 | then |
28 | echo -n > $RESOLV_CONF | 35 | echo -n > $RESOLV_CONF |
diff --git a/examples/udhcp/simple.script b/examples/udhcp/simple.script index 2a917eb6c..e4c1f2d76 100755 --- a/examples/udhcp/simple.script +++ b/examples/udhcp/simple.script | |||
@@ -29,8 +29,14 @@ case "$1" in | |||
29 | metric=0 | 29 | metric=0 |
30 | for i in $router ; do | 30 | for i in $router ; do |
31 | echo "Adding router $i" | 31 | echo "Adding router $i" |
32 | route add default gw $i dev $interface metric $metric | 32 | if [ "$subnet" = "255.255.255.255" ]; then |
33 | : $(( metric += 1 )) | 33 | # special case for /32 subnets: |
34 | # /32 instructs kernel to always use routing for all outgoing packets | ||
35 | # (they can never be sent to local subnet - there is no local subnet for /32). | ||
36 | # Used in datacenters, avoids the need for private ip-addresses between two hops. | ||
37 | ip route add $i dev $interface | ||
38 | fi | ||
39 | route add default gw $i dev $interface metric $((metric++)) | ||
34 | done | 40 | done |
35 | fi | 41 | fi |
36 | 42 | ||
diff --git a/examples/var_service/dhcp_if/dhcp_handler b/examples/var_service/dhcp_if/dhcp_handler index 3d2a5cb79..3d44a6022 100755 --- a/examples/var_service/dhcp_if/dhcp_handler +++ b/examples/var_service/dhcp_if/dhcp_handler | |||
@@ -21,7 +21,7 @@ | |||
21 | # ntpsrv=10.34.32.125 10.34.255.7 | 21 | # ntpsrv=10.34.32.125 10.34.255.7 |
22 | # | 22 | # |
23 | # renew: lease is renewed. Environment is similar to "bound". | 23 | # renew: lease is renewed. Environment is similar to "bound". |
24 | # The IP address does not change, however, the other DHCP paramaters, | 24 | # The IP address does not change, however, the other DHCP parameters, |
25 | # such as the default gateway, subnet mask, and dns server may change. | 25 | # such as the default gateway, subnet mask, and dns server may change. |
26 | # | 26 | # |
27 | # nak: udhcpc received a NAK message. | 27 | # nak: udhcpc received a NAK message. |
diff --git a/findutils/find.c b/findutils/find.c index 67aa40b21..0596c0059 100644 --- a/findutils/find.c +++ b/findutils/find.c | |||
@@ -182,7 +182,7 @@ | |||
182 | //config: default y | 182 | //config: default y |
183 | //config: depends on FIND | 183 | //config: depends on FIND |
184 | //config: help | 184 | //config: help |
185 | //config: If the file is a directory, dont descend into it. Useful for | 185 | //config: If the file is a directory, don't descend into it. Useful for |
186 | //config: exclusion .svn and CVS directories. | 186 | //config: exclusion .svn and CVS directories. |
187 | //config: | 187 | //config: |
188 | //config:config FEATURE_FIND_DELETE | 188 | //config:config FEATURE_FIND_DELETE |
diff --git a/findutils/grep.c b/findutils/grep.c index 8b6e29874..b115d9a1d 100644 --- a/findutils/grep.c +++ b/findutils/grep.c | |||
@@ -39,7 +39,7 @@ | |||
39 | //config:config FEATURE_GREP_CONTEXT | 39 | //config:config FEATURE_GREP_CONTEXT |
40 | //config: bool "Enable before and after context flags (-A, -B and -C)" | 40 | //config: bool "Enable before and after context flags (-A, -B and -C)" |
41 | //config: default y | 41 | //config: default y |
42 | //config: depends on GREP || EGREP | 42 | //config: depends on GREP || EGREP || FGREP |
43 | //config: help | 43 | //config: help |
44 | //config: Print the specified number of leading (-B) and/or trailing (-A) | 44 | //config: Print the specified number of leading (-B) and/or trailing (-A) |
45 | //config: context surrounding our matching lines. | 45 | //config: context surrounding our matching lines. |
@@ -523,7 +523,7 @@ static int grep_file(FILE *file) | |||
523 | if (option_mask32 & OPT_o) { | 523 | if (option_mask32 & OPT_o) { |
524 | if (FGREP_FLAG) { | 524 | if (FGREP_FLAG) { |
525 | /* -Fo just prints the pattern | 525 | /* -Fo just prints the pattern |
526 | * (unless -v: -Fov doesnt print anything at all) */ | 526 | * (unless -v: -Fov doesn't print anything at all) */ |
527 | if (found) | 527 | if (found) |
528 | print_line(gl->pattern, strlen(gl->pattern), linenum, ':'); | 528 | print_line(gl->pattern, strlen(gl->pattern), linenum, ':'); |
529 | } else while (1) { | 529 | } else while (1) { |
@@ -831,7 +831,7 @@ int grep_main(int argc UNUSED_PARAM, char **argv) | |||
831 | grep_done: ; | 831 | grep_done: ; |
832 | } while (*argv && *++argv); | 832 | } while (*argv && *++argv); |
833 | 833 | ||
834 | /* destroy all the elments in the pattern list */ | 834 | /* destroy all the elements in the pattern list */ |
835 | if (ENABLE_FEATURE_CLEAN_UP) { | 835 | if (ENABLE_FEATURE_CLEAN_UP) { |
836 | while (pattern_head) { | 836 | while (pattern_head) { |
837 | llist_t *pattern_head_ptr = pattern_head; | 837 | llist_t *pattern_head_ptr = pattern_head; |
diff --git a/include/libbb.h b/include/libbb.h index 1f5b211c1..9313a557a 100644 --- a/include/libbb.h +++ b/include/libbb.h | |||
@@ -353,6 +353,8 @@ extern int *const bb_errno; | |||
353 | uint64_t bb_bswap_64(uint64_t x) FAST_FUNC; | 353 | uint64_t bb_bswap_64(uint64_t x) FAST_FUNC; |
354 | #endif | 354 | #endif |
355 | 355 | ||
356 | unsigned long FAST_FUNC isqrt(unsigned long long N); | ||
357 | |||
356 | unsigned long long monotonic_ns(void) FAST_FUNC; | 358 | unsigned long long monotonic_ns(void) FAST_FUNC; |
357 | unsigned long long monotonic_us(void) FAST_FUNC; | 359 | unsigned long long monotonic_us(void) FAST_FUNC; |
358 | unsigned long long monotonic_ms(void) FAST_FUNC; | 360 | unsigned long long monotonic_ms(void) FAST_FUNC; |
@@ -1193,6 +1195,26 @@ extern const char *applet_long_options; | |||
1193 | #endif | 1195 | #endif |
1194 | extern uint32_t option_mask32; | 1196 | extern uint32_t option_mask32; |
1195 | extern uint32_t getopt32(char **argv, const char *applet_opts, ...) FAST_FUNC; | 1197 | extern uint32_t getopt32(char **argv, const char *applet_opts, ...) FAST_FUNC; |
1198 | /* BSD-derived getopt() functions require that optind be set to 1 in | ||
1199 | * order to reset getopt() state. This used to be generally accepted | ||
1200 | * way of resetting getopt(). However, glibc's getopt() | ||
1201 | * has additional getopt() state beyond optind (specifically, glibc | ||
1202 | * extensions such as '+' and '-' at the start of the string), and requires | ||
1203 | * that optind be set to zero to reset its state. BSD-derived versions | ||
1204 | * of getopt() misbehaved if optind is set to 0 in order to reset getopt(), | ||
1205 | * and glibc's getopt() used to coredump if optind is set 1 in order | ||
1206 | * to reset getopt(). | ||
1207 | * Then BSD introduced additional variable "optreset" which should be | ||
1208 | * set to 1 in order to reset getopt(). Sigh. Standards, anyone? | ||
1209 | * | ||
1210 | * By ~2008, OpenBSD 3.4 was changed to survive glibc-like optind = 0 | ||
1211 | * (to interpret it as if optreset was set). | ||
1212 | */ | ||
1213 | #if defined(__GLIBC__) || ENABLE_PLATFORM_MINGW32 | ||
1214 | #define GETOPT_RESET() (optind = 0) | ||
1215 | #else /* BSD style */ | ||
1216 | #define GETOPT_RESET() (optind = 1) | ||
1217 | #endif | ||
1196 | 1218 | ||
1197 | 1219 | ||
1198 | /* Having next pointer as a first member allows easy creation | 1220 | /* Having next pointer as a first member allows easy creation |
@@ -1264,7 +1286,7 @@ extern void bb_logenv_override(void) FAST_FUNC; | |||
1264 | 1286 | ||
1265 | 1287 | ||
1266 | /* Applets which are useful from another applets */ | 1288 | /* Applets which are useful from another applets */ |
1267 | int bb_cat(char** argv); | 1289 | int bb_cat(char** argv) FAST_FUNC; |
1268 | /* If shell needs them, they exist even if not enabled as applets */ | 1290 | /* If shell needs them, they exist even if not enabled as applets */ |
1269 | int echo_main(int argc, char** argv) IF_ECHO(MAIN_EXTERNALLY_VISIBLE); | 1291 | int echo_main(int argc, char** argv) IF_ECHO(MAIN_EXTERNALLY_VISIBLE); |
1270 | int printf_main(int argc, char **argv) IF_PRINTF(MAIN_EXTERNALLY_VISIBLE); | 1292 | int printf_main(int argc, char **argv) IF_PRINTF(MAIN_EXTERNALLY_VISIBLE); |
@@ -1290,6 +1312,16 @@ int bunzip2_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; | |||
1290 | void bb_displayroutes(int noresolve, int netstatfmt) FAST_FUNC; | 1312 | void bb_displayroutes(int noresolve, int netstatfmt) FAST_FUNC; |
1291 | #endif | 1313 | #endif |
1292 | 1314 | ||
1315 | struct number_state { | ||
1316 | unsigned width; | ||
1317 | unsigned start; | ||
1318 | unsigned inc; | ||
1319 | const char *sep; | ||
1320 | const char *empty_str; | ||
1321 | smallint all, nonempty; | ||
1322 | }; | ||
1323 | void print_numbered_lines(struct number_state *ns, const char *filename) FAST_FUNC; | ||
1324 | |||
1293 | 1325 | ||
1294 | /* Networking */ | 1326 | /* Networking */ |
1295 | /* This structure defines protocol families and their handlers. */ | 1327 | /* This structure defines protocol families and their handlers. */ |
@@ -1348,10 +1380,15 @@ extern int get_linux_version_code(void) FAST_FUNC; | |||
1348 | 1380 | ||
1349 | extern char *query_loop(const char *device) FAST_FUNC; | 1381 | extern char *query_loop(const char *device) FAST_FUNC; |
1350 | extern int del_loop(const char *device) FAST_FUNC; | 1382 | extern int del_loop(const char *device) FAST_FUNC; |
1351 | /* If *devname is not NULL, use that name, otherwise try to find free one, | 1383 | /* |
1384 | * If *devname is not NULL, use that name, otherwise try to find free one, | ||
1352 | * malloc and return it in *devname. | 1385 | * malloc and return it in *devname. |
1353 | * return value: 1: read-only loopdev was setup, 0: rw, < 0: error */ | 1386 | * return value is the opened fd to the loop device, or < on error |
1354 | extern int set_loop(char **devname, const char *file, unsigned long long offset, int ro) FAST_FUNC; | 1387 | */ |
1388 | extern int set_loop(char **devname, const char *file, unsigned long long offset, unsigned flags) FAST_FUNC; | ||
1389 | /* These constants match linux/loop.h (without BB_ prefix): */ | ||
1390 | #define BB_LO_FLAGS_READ_ONLY 1 | ||
1391 | #define BB_LO_FLAGS_AUTOCLEAR 4 | ||
1355 | 1392 | ||
1356 | /* Like bb_ask below, but asks on stdin with no timeout. */ | 1393 | /* Like bb_ask below, but asks on stdin with no timeout. */ |
1357 | char *bb_ask_stdin(const char * prompt) FAST_FUNC; | 1394 | char *bb_ask_stdin(const char * prompt) FAST_FUNC; |
@@ -1463,6 +1500,12 @@ extern void selinux_or_die(void) FAST_FUNC; | |||
1463 | #define SETUP_ENV_NO_CHDIR (1 << 4) | 1500 | #define SETUP_ENV_NO_CHDIR (1 << 4) |
1464 | void setup_environment(const char *shell, int flags, const struct passwd *pw) FAST_FUNC; | 1501 | void setup_environment(const char *shell, int flags, const struct passwd *pw) FAST_FUNC; |
1465 | void nuke_str(char *str) FAST_FUNC; | 1502 | void nuke_str(char *str) FAST_FUNC; |
1503 | #if ENABLE_FEATURE_SECURETTY && !ENABLE_PAM | ||
1504 | int is_tty_secure(const char *short_tty) FAST_FUNC; | ||
1505 | #else | ||
1506 | static ALWAYS_INLINE int is_tty_secure(const char *short_tty UNUSED_PARAM) { return 1; } | ||
1507 | #endif | ||
1508 | #define CHECKPASS_PW_HAS_EMPTY_PASSWORD 2 | ||
1466 | int check_password(const struct passwd *pw, const char *plaintext) FAST_FUNC; | 1509 | int check_password(const struct passwd *pw, const char *plaintext) FAST_FUNC; |
1467 | int ask_and_check_password_extended(const struct passwd *pw, int timeout, const char *prompt) FAST_FUNC; | 1510 | int ask_and_check_password_extended(const struct passwd *pw, int timeout, const char *prompt) FAST_FUNC; |
1468 | int ask_and_check_password(const struct passwd *pw) FAST_FUNC; | 1511 | int ask_and_check_password(const struct passwd *pw) FAST_FUNC; |
diff --git a/init/init.c b/init/init.c index 833759341..4d6355167 100644 --- a/init/init.c +++ b/init/init.c | |||
@@ -73,6 +73,10 @@ | |||
73 | //config: bool "Enable init to write to syslog" | 73 | //config: bool "Enable init to write to syslog" |
74 | //config: default y | 74 | //config: default y |
75 | //config: depends on INIT || LINUXRC | 75 | //config: depends on INIT || LINUXRC |
76 | //config: help | ||
77 | //config: If selected, some init messages are sent to syslog. | ||
78 | //config: Otherwise, they are sent to VT #5 if linux virtual tty is detected | ||
79 | //config: (if not, no separate logging is done). | ||
76 | //config: | 80 | //config: |
77 | //config:config FEATURE_INIT_QUIET | 81 | //config:config FEATURE_INIT_QUIET |
78 | //config: bool "Be quiet on boot (no 'init started:' message)" | 82 | //config: bool "Be quiet on boot (no 'init started:' message)" |
@@ -212,7 +216,9 @@ struct init_action { | |||
212 | 216 | ||
213 | static struct init_action *init_action_list = NULL; | 217 | static struct init_action *init_action_list = NULL; |
214 | 218 | ||
219 | #if !ENABLE_FEATURE_INIT_SYSLOG | ||
215 | static const char *log_console = VC_5; | 220 | static const char *log_console = VC_5; |
221 | #endif | ||
216 | 222 | ||
217 | enum { | 223 | enum { |
218 | L_LOG = 0x1, | 224 | L_LOG = 0x1, |
@@ -251,17 +257,16 @@ static void message(int where, const char *fmt, ...) | |||
251 | msg[l++] = '\n'; | 257 | msg[l++] = '\n'; |
252 | msg[l] = '\0'; | 258 | msg[l] = '\0'; |
253 | #else | 259 | #else |
254 | { | 260 | msg[l++] = '\n'; |
255 | static int log_fd = -1; | 261 | msg[l] = '\0'; |
256 | 262 | if (where & L_LOG) { | |
257 | msg[l++] = '\n'; | ||
258 | msg[l] = '\0'; | ||
259 | /* Take full control of the log tty, and never close it. | 263 | /* Take full control of the log tty, and never close it. |
260 | * It's mine, all mine! Muhahahaha! */ | 264 | * It's mine, all mine! Muhahahaha! */ |
265 | static int log_fd = -1; | ||
266 | |||
261 | if (log_fd < 0) { | 267 | if (log_fd < 0) { |
262 | if (!log_console) { | 268 | log_fd = STDERR_FILENO; |
263 | log_fd = STDERR_FILENO; | 269 | if (log_console) { |
264 | } else { | ||
265 | log_fd = device_open(log_console, O_WRONLY | O_NONBLOCK | O_NOCTTY); | 270 | log_fd = device_open(log_console, O_WRONLY | O_NONBLOCK | O_NOCTTY); |
266 | if (log_fd < 0) { | 271 | if (log_fd < 0) { |
267 | bb_error_msg("can't log to %s", log_console); | 272 | bb_error_msg("can't log to %s", log_console); |
@@ -271,11 +276,9 @@ static void message(int where, const char *fmt, ...) | |||
271 | } | 276 | } |
272 | } | 277 | } |
273 | } | 278 | } |
274 | if (where & L_LOG) { | 279 | full_write(log_fd, msg, l); |
275 | full_write(log_fd, msg, l); | 280 | if (log_fd == STDERR_FILENO) |
276 | if (log_fd == STDERR_FILENO) | 281 | return; /* don't print dup messages */ |
277 | return; /* don't print dup messages */ | ||
278 | } | ||
279 | } | 282 | } |
280 | #endif | 283 | #endif |
281 | 284 | ||
@@ -325,8 +328,9 @@ static void console_init(void) | |||
325 | * if TERM is set to linux (the default) */ | 328 | * if TERM is set to linux (the default) */ |
326 | if (!s || strcmp(s, "linux") == 0) | 329 | if (!s || strcmp(s, "linux") == 0) |
327 | putenv((char*)"TERM=vt102"); | 330 | putenv((char*)"TERM=vt102"); |
328 | if (!ENABLE_FEATURE_INIT_SYSLOG) | 331 | # if !ENABLE_FEATURE_INIT_SYSLOG |
329 | log_console = NULL; | 332 | log_console = NULL; |
333 | # endif | ||
330 | } else | 334 | } else |
331 | #endif | 335 | #endif |
332 | if (!s) | 336 | if (!s) |
@@ -541,8 +545,8 @@ static pid_t run(const struct init_action *a) | |||
541 | } | 545 | } |
542 | 546 | ||
543 | /* Log the process name and args */ | 547 | /* Log the process name and args */ |
544 | message(L_LOG, "starting pid %d, tty '%s': '%s'", | 548 | message(L_LOG, "starting pid %u, tty '%s': '%s'", |
545 | getpid(), a->terminal, a->command); | 549 | (int)getpid(), a->terminal, a->command); |
546 | 550 | ||
547 | /* Now run it. The new program will take over this PID, | 551 | /* Now run it. The new program will take over this PID, |
548 | * so nothing further in init.c should be run. */ | 552 | * so nothing further in init.c should be run. */ |
@@ -757,7 +761,7 @@ static void run_shutdown_and_kill_processes(void) | |||
757 | 761 | ||
758 | /* Send signals to every process _except_ pid 1 */ | 762 | /* Send signals to every process _except_ pid 1 */ |
759 | kill(-1, SIGTERM); | 763 | kill(-1, SIGTERM); |
760 | message(L_CONSOLE | L_LOG, "Sent SIG%s to all processes", "TERM"); | 764 | message(L_CONSOLE, "Sent SIG%s to all processes", "TERM"); |
761 | sync(); | 765 | sync(); |
762 | sleep(1); | 766 | sleep(1); |
763 | 767 | ||
diff --git a/libbb/Kbuild.src b/libbb/Kbuild.src index fc9371db1..0d7dd2a2c 100644 --- a/libbb/Kbuild.src +++ b/libbb/Kbuild.src | |||
@@ -77,6 +77,7 @@ lib-y += safe_gethostname.o | |||
77 | lib-y += safe_poll.o | 77 | lib-y += safe_poll.o |
78 | lib-y += safe_strncpy.o | 78 | lib-y += safe_strncpy.o |
79 | lib-y += safe_write.o | 79 | lib-y += safe_write.o |
80 | lib-y += securetty.o | ||
80 | lib-y += setup_environment.o | 81 | lib-y += setup_environment.o |
81 | lib-y += simplify_path.o | 82 | lib-y += simplify_path.o |
82 | lib-y += single_argv.o | 83 | lib-y += single_argv.o |
diff --git a/libbb/bb_cat.c b/libbb/bb_cat.c new file mode 100644 index 000000000..0a4a350fb --- /dev/null +++ b/libbb/bb_cat.c | |||
@@ -0,0 +1,33 @@ | |||
1 | /* vi: set sw=4 ts=4: */ | ||
2 | /* | ||
3 | * Copyright (C) 2003 Manuel Novoa III <mjn3@codepoet.org> | ||
4 | * | ||
5 | * Licensed under GPLv2, see file LICENSE in this source tree. | ||
6 | */ | ||
7 | //kbuild:lib-y += bb_cat.o | ||
8 | |||
9 | #include "libbb.h" | ||
10 | |||
11 | int FAST_FUNC bb_cat(char **argv) | ||
12 | { | ||
13 | int fd; | ||
14 | int retval = EXIT_SUCCESS; | ||
15 | |||
16 | if (!*argv) | ||
17 | argv = (char**) &bb_argv_dash; | ||
18 | |||
19 | do { | ||
20 | fd = open_or_warn_stdin(*argv); | ||
21 | if (fd >= 0) { | ||
22 | /* This is not a xfunc - never exits */ | ||
23 | off_t r = bb_copyfd_eof(fd, STDOUT_FILENO); | ||
24 | if (fd != STDIN_FILENO) | ||
25 | close(fd); | ||
26 | if (r >= 0) | ||
27 | continue; | ||
28 | } | ||
29 | retval = EXIT_FAILURE; | ||
30 | } while (*++argv); | ||
31 | |||
32 | return retval; | ||
33 | } | ||
diff --git a/libbb/correct_password.c b/libbb/correct_password.c index 513c93028..f4635a5bc 100644 --- a/libbb/correct_password.c +++ b/libbb/correct_password.c | |||
@@ -63,7 +63,7 @@ static const char *get_passwd(const struct passwd *pw, char buffer[SHADOW_BUFSIZ | |||
63 | } | 63 | } |
64 | 64 | ||
65 | /* | 65 | /* |
66 | * Return 1 if PW has an empty password. | 66 | * Return CHECKPASS_PW_HAS_EMPTY_PASSWORD if PW has an empty password. |
67 | * Return 1 if the user gives the correct password for entry PW, | 67 | * Return 1 if the user gives the correct password for entry PW, |
68 | * 0 if not. | 68 | * 0 if not. |
69 | * NULL pw means "just fake it for login with bad username" | 69 | * NULL pw means "just fake it for login with bad username" |
@@ -77,7 +77,7 @@ int FAST_FUNC check_password(const struct passwd *pw, const char *plaintext) | |||
77 | 77 | ||
78 | pw_pass = get_passwd(pw, buffer); | 78 | pw_pass = get_passwd(pw, buffer); |
79 | if (!pw_pass[0]) { /* empty password field? */ | 79 | if (!pw_pass[0]) { /* empty password field? */ |
80 | return 1; | 80 | return CHECKPASS_PW_HAS_EMPTY_PASSWORD; |
81 | } | 81 | } |
82 | 82 | ||
83 | encrypted = pw_encrypt(plaintext, /*salt:*/ pw_pass, 1); | 83 | encrypted = pw_encrypt(plaintext, /*salt:*/ pw_pass, 1); |
@@ -88,7 +88,7 @@ int FAST_FUNC check_password(const struct passwd *pw, const char *plaintext) | |||
88 | 88 | ||
89 | 89 | ||
90 | /* Ask the user for a password. | 90 | /* Ask the user for a password. |
91 | * Return 1 without asking if PW has an empty password. | 91 | * Return CHECKPASS_PW_HAS_EMPTY_PASSWORD without asking if PW has an empty password. |
92 | * Return -1 on EOF, error while reading input, or timeout. | 92 | * Return -1 on EOF, error while reading input, or timeout. |
93 | * Return 1 if the user gives the correct password for entry PW, | 93 | * Return 1 if the user gives the correct password for entry PW, |
94 | * 0 if not. | 94 | * 0 if not. |
@@ -105,7 +105,7 @@ int FAST_FUNC ask_and_check_password_extended(const struct passwd *pw, | |||
105 | 105 | ||
106 | pw_pass = get_passwd(pw, buffer); | 106 | pw_pass = get_passwd(pw, buffer); |
107 | if (!pw_pass[0]) /* empty password field? */ | 107 | if (!pw_pass[0]) /* empty password field? */ |
108 | return 1; | 108 | return CHECKPASS_PW_HAS_EMPTY_PASSWORD; |
109 | 109 | ||
110 | plaintext = bb_ask(STDIN_FILENO, timeout, prompt); | 110 | plaintext = bb_ask(STDIN_FILENO, timeout, prompt); |
111 | if (!plaintext) { | 111 | if (!plaintext) { |
diff --git a/libbb/getopt32.c b/libbb/getopt32.c index 03fca3493..b87b83538 100644 --- a/libbb/getopt32.c +++ b/libbb/getopt32.c | |||
@@ -128,7 +128,7 @@ const char *opt_complementary | |||
128 | "abc" If groups of two or more chars are specified, the first char | 128 | "abc" If groups of two or more chars are specified, the first char |
129 | is the main option and the other chars are secondary options. | 129 | is the main option and the other chars are secondary options. |
130 | Their flags will be turned on if the main option is found even | 130 | Their flags will be turned on if the main option is found even |
131 | if they are not specifed on the command line. For example: | 131 | if they are not specified on the command line. For example: |
132 | 132 | ||
133 | opt_complementary = "abc"; | 133 | opt_complementary = "abc"; |
134 | flags = getopt32(argv, "abcd") | 134 | flags = getopt32(argv, "abcd") |
@@ -576,13 +576,7 @@ getopt32(char **argv, const char *applet_opts, ...) | |||
576 | * run_nofork_applet() does this, but we might end up here | 576 | * run_nofork_applet() does this, but we might end up here |
577 | * also via gunzip_main() -> gzip_main(). Play safe. | 577 | * also via gunzip_main() -> gzip_main(). Play safe. |
578 | */ | 578 | */ |
579 | #if defined(__GLIBC__) || ENABLE_PLATFORM_MINGW32 | 579 | GETOPT_RESET(); |
580 | optind = 0; | ||
581 | #else /* BSD style */ | ||
582 | optind = 1; | ||
583 | /* optreset = 1; */ | ||
584 | #endif | ||
585 | /* optarg = NULL; opterr = 0; optopt = 0; - do we need this?? */ | ||
586 | 580 | ||
587 | /* Note: just "getopt() <= 0" will not work well for | 581 | /* Note: just "getopt() <= 0" will not work well for |
588 | * "fake" short options, like this one: | 582 | * "fake" short options, like this one: |
diff --git a/libbb/isqrt.c b/libbb/isqrt.c new file mode 100644 index 000000000..817b7d036 --- /dev/null +++ b/libbb/isqrt.c | |||
@@ -0,0 +1,60 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2017 Denys Vlasenko <vda.linux@googlemail.com> | ||
3 | * | ||
4 | * Licensed under GPLv2, see file LICENSE in this source tree. | ||
5 | */ | ||
6 | |||
7 | //kbuild:lib-y += isqrt.o | ||
8 | |||
9 | #ifndef ISQRT_TEST | ||
10 | # include "libbb.h" | ||
11 | #else | ||
12 | /* gcc -DISQRT_TEST -Wall -O2 isqrt.c -oisqrt && ./isqrt $((RANDOM*RANDOM)) */ | ||
13 | # include <stdlib.h> | ||
14 | # include <stdio.h> | ||
15 | # include <time.h> | ||
16 | # define FAST_FUNC /* nothing */ | ||
17 | #endif | ||
18 | |||
19 | /* Returns such x that x+1 > sqrt(N) */ | ||
20 | unsigned long FAST_FUNC isqrt(unsigned long long N) | ||
21 | { | ||
22 | unsigned long x; | ||
23 | unsigned shift; | ||
24 | #define LL_WIDTH_BITS (unsigned)(sizeof(N)*8) | ||
25 | |||
26 | shift = LL_WIDTH_BITS - 2; | ||
27 | x = 0; | ||
28 | do { | ||
29 | x = (x << 1) + 1; | ||
30 | if ((unsigned long long)x * x > (N >> shift)) | ||
31 | x--; /* whoops, that +1 was too much */ | ||
32 | shift -= 2; | ||
33 | } while ((int)shift >= 0); | ||
34 | return x; | ||
35 | } | ||
36 | |||
37 | #ifdef ISQRT_TEST | ||
38 | int main(int argc, char **argv) | ||
39 | { | ||
40 | unsigned long long n = argv[1] ? strtoull(argv[1], NULL, 0) : time(NULL); | ||
41 | for (;;) { | ||
42 | unsigned long h; | ||
43 | n--; | ||
44 | h = isqrt(n); | ||
45 | if (!(n & 0xffff)) | ||
46 | printf("isqrt(%llx)=%lx\n", n, h); | ||
47 | if ((unsigned long long)h * h > n) { | ||
48 | printf("BAD1: isqrt(%llx)=%lx\n", n, h); | ||
49 | return 1; | ||
50 | } | ||
51 | h++; | ||
52 | if ((unsigned long long)h * h != 0 /* this can overflow to 0 - not a bug */ | ||
53 | && (unsigned long long)h * h <= n) | ||
54 | { | ||
55 | printf("BAD2: isqrt(%llx)=%lx\n", n, h); | ||
56 | return 1; | ||
57 | } | ||
58 | } | ||
59 | } | ||
60 | #endif | ||
diff --git a/libbb/loop.c b/libbb/loop.c index d30b378d7..f0d4296ae 100644 --- a/libbb/loop.c +++ b/libbb/loop.c | |||
@@ -78,22 +78,24 @@ int FAST_FUNC del_loop(const char *device) | |||
78 | return rc; | 78 | return rc; |
79 | } | 79 | } |
80 | 80 | ||
81 | /* Returns 0 if mounted RW, 1 if mounted read-only, <0 for error. | 81 | /* Returns opened fd to the loop device, <0 on error. |
82 | *device is loop device to use, or if *device==NULL finds a loop device to | 82 | * *device is loop device to use, or if *device==NULL finds a loop device to |
83 | mount it on and sets *device to a strdup of that loop device name. This | 83 | * mount it on and sets *device to a strdup of that loop device name. This |
84 | search will re-use an existing loop device already bound to that | 84 | * search will re-use an existing loop device already bound to that |
85 | file/offset if it finds one. | 85 | * file/offset if it finds one. |
86 | */ | 86 | */ |
87 | int FAST_FUNC set_loop(char **device, const char *file, unsigned long long offset, int ro) | 87 | int FAST_FUNC set_loop(char **device, const char *file, unsigned long long offset, unsigned flags) |
88 | { | 88 | { |
89 | char dev[LOOP_NAMESIZE]; | 89 | char dev[LOOP_NAMESIZE]; |
90 | char *try; | 90 | char *try; |
91 | bb_loop_info loopinfo; | 91 | bb_loop_info loopinfo; |
92 | struct stat statbuf; | 92 | struct stat statbuf; |
93 | int i, dfd, ffd, mode, rc = -1; | 93 | int i, dfd, ffd, mode, rc; |
94 | |||
95 | rc = dfd = -1; | ||
94 | 96 | ||
95 | /* Open the file. Barf if this doesn't work. */ | 97 | /* Open the file. Barf if this doesn't work. */ |
96 | mode = ro ? O_RDONLY : O_RDWR; | 98 | mode = (flags & BB_LO_FLAGS_READ_ONLY) ? O_RDONLY : O_RDWR; |
97 | open_ffd: | 99 | open_ffd: |
98 | ffd = open(file, mode); | 100 | ffd = open(file, mode); |
99 | if (ffd < 0) { | 101 | if (ffd < 0) { |
@@ -144,20 +146,35 @@ int FAST_FUNC set_loop(char **device, const char *file, unsigned long long offse | |||
144 | 146 | ||
145 | /* If device is free, claim it. */ | 147 | /* If device is free, claim it. */ |
146 | if (rc && errno == ENXIO) { | 148 | if (rc && errno == ENXIO) { |
147 | memset(&loopinfo, 0, sizeof(loopinfo)); | ||
148 | safe_strncpy((char *)loopinfo.lo_file_name, file, LO_NAME_SIZE); | ||
149 | loopinfo.lo_offset = offset; | ||
150 | /* Associate free loop device with file. */ | 149 | /* Associate free loop device with file. */ |
151 | if (ioctl(dfd, LOOP_SET_FD, ffd) == 0) { | 150 | if (ioctl(dfd, LOOP_SET_FD, ffd) == 0) { |
152 | if (ioctl(dfd, BB_LOOP_SET_STATUS, &loopinfo) == 0) | 151 | memset(&loopinfo, 0, sizeof(loopinfo)); |
153 | rc = 0; | 152 | safe_strncpy((char *)loopinfo.lo_file_name, file, LO_NAME_SIZE); |
154 | else | 153 | loopinfo.lo_offset = offset; |
154 | /* | ||
155 | * Used by mount to set LO_FLAGS_AUTOCLEAR. | ||
156 | * LO_FLAGS_READ_ONLY is not set because RO is controlled by open type of the file. | ||
157 | * Note that closing LO_FLAGS_AUTOCLEARed dfd before mount | ||
158 | * is wrong (would free the loop device!) | ||
159 | */ | ||
160 | loopinfo.lo_flags = (flags & ~BB_LO_FLAGS_READ_ONLY); | ||
161 | rc = ioctl(dfd, BB_LOOP_SET_STATUS, &loopinfo); | ||
162 | if (rc != 0 && (loopinfo.lo_flags & BB_LO_FLAGS_AUTOCLEAR)) { | ||
163 | /* Old kernel, does not support LO_FLAGS_AUTOCLEAR? */ | ||
164 | /* (this code path is not tested) */ | ||
165 | loopinfo.lo_flags -= BB_LO_FLAGS_AUTOCLEAR; | ||
166 | rc = ioctl(dfd, BB_LOOP_SET_STATUS, &loopinfo); | ||
167 | } | ||
168 | if (rc != 0) { | ||
155 | ioctl(dfd, LOOP_CLR_FD, 0); | 169 | ioctl(dfd, LOOP_CLR_FD, 0); |
170 | } | ||
156 | } | 171 | } |
157 | } else { | 172 | } else { |
158 | rc = -1; | 173 | rc = -1; |
159 | } | 174 | } |
160 | close(dfd); | 175 | if (rc != 0) { |
176 | close(dfd); | ||
177 | } | ||
161 | try_again: | 178 | try_again: |
162 | if (*device) break; | 179 | if (*device) break; |
163 | } | 180 | } |
@@ -165,7 +182,7 @@ int FAST_FUNC set_loop(char **device, const char *file, unsigned long long offse | |||
165 | if (rc == 0) { | 182 | if (rc == 0) { |
166 | if (!*device) | 183 | if (!*device) |
167 | *device = xstrdup(dev); | 184 | *device = xstrdup(dev); |
168 | return (mode == O_RDONLY); /* 1:ro, 0:rw */ | 185 | return dfd; |
169 | } | 186 | } |
170 | return rc; | 187 | return rc; |
171 | } | 188 | } |
diff --git a/libbb/print_numbered_lines.c b/libbb/print_numbered_lines.c new file mode 100644 index 000000000..702aed1ea --- /dev/null +++ b/libbb/print_numbered_lines.c | |||
@@ -0,0 +1,29 @@ | |||
1 | /* vi: set sw=4 ts=4: */ | ||
2 | /* | ||
3 | * Copyright (C) 2017 Denys Vlasenko <vda.linux@googlemail.com> | ||
4 | * | ||
5 | * Licensed under GPLv2, see file LICENSE in this source tree. | ||
6 | */ | ||
7 | //kbuild:lib-y += print_numbered_lines.o | ||
8 | |||
9 | #include "libbb.h" | ||
10 | |||
11 | void FAST_FUNC print_numbered_lines(struct number_state *ns, const char *filename) | ||
12 | { | ||
13 | FILE *fp = fopen_or_warn_stdin(filename); | ||
14 | unsigned N = ns->start; | ||
15 | char *line; | ||
16 | |||
17 | while ((line = xmalloc_fgetline(fp)) != NULL) { | ||
18 | if (ns->all | ||
19 | || (ns->nonempty && line[0]) | ||
20 | ) { | ||
21 | printf("%*u%s%s\n", ns->width, N, ns->sep, line); | ||
22 | N += ns->inc; | ||
23 | } else if (ns->empty_str) | ||
24 | fputs(ns->empty_str, stdout); | ||
25 | free(line); | ||
26 | } | ||
27 | |||
28 | fclose(fp); | ||
29 | } | ||
diff --git a/libbb/recursive_action.c b/libbb/recursive_action.c index b5cf7c0ab..8f2b8b932 100644 --- a/libbb/recursive_action.c +++ b/libbb/recursive_action.c | |||
@@ -30,24 +30,37 @@ static int FAST_FUNC true_action(const char *fileName UNUSED_PARAM, | |||
30 | return TRUE; | 30 | return TRUE; |
31 | } | 31 | } |
32 | 32 | ||
33 | /* fileAction return value of 0 on any file in directory will make | 33 | /* fileName is (l)stat'ed (depending on ACTION_FOLLOWLINKS[_L0]). |
34 | * recursive_action() return 0, but it doesn't stop directory traversal | 34 | * |
35 | * If it is a file: fileAction in run on it, its return value is returned. | ||
36 | * | ||
37 | * In case we are in a recursive invocation (see below): | ||
38 | * normally, fileAction should return 1 (TRUE) to indicate that | ||
39 | * everything is okay and processing should continue. | ||
40 | * fileAction return value of 0 (FALSE) on any file in directory will make | ||
41 | * recursive_action() also return 0, but it doesn't stop directory traversal | ||
35 | * (fileAction/dirAction will be called on each file). | 42 | * (fileAction/dirAction will be called on each file). |
36 | * | 43 | * |
37 | * If !ACTION_RECURSE, dirAction is called on the directory and its | 44 | * [TODO: maybe introduce -1 to mean "stop traversal NOW and return"] |
45 | * | ||
46 | * If it is a directory: | ||
47 | * | ||
48 | * If !ACTION_RECURSE, dirAction is called and its | ||
38 | * return value is returned from recursive_action(). No recursion. | 49 | * return value is returned from recursive_action(). No recursion. |
39 | * | 50 | * |
40 | * If ACTION_RECURSE, recursive_action() is called on each directory. | 51 | * If ACTION_RECURSE, directory is opened, and recursive_action() is called |
52 | * on each file/subdirectory. | ||
41 | * If any one of these calls returns 0, current recursive_action() returns 0. | 53 | * If any one of these calls returns 0, current recursive_action() returns 0. |
42 | * | 54 | * |
55 | * If !ACTION_DEPTHFIRST, dirAction is called before recurse. | ||
56 | * Return value of 0 (FALSE) is an error: prevents recursion, | ||
57 | * the warning is printed (unless ACTION_QUIET) and recursive_action() returns 0. | ||
58 | * Return value of 2 (SKIP) prevents recursion, instead recursive_action() | ||
59 | * returns 1 (TRUE, no error). | ||
60 | * | ||
43 | * If ACTION_DEPTHFIRST, dirAction is called after recurse. | 61 | * If ACTION_DEPTHFIRST, dirAction is called after recurse. |
44 | * If it returns 0, the warning is printed and recursive_action() returns 0. | 62 | * If it returns 0, the warning is printed and recursive_action() returns 0. |
45 | * | 63 | * |
46 | * If !ACTION_DEPTHFIRST, dirAction is called before we recurse. | ||
47 | * Return value of 0 (FALSE) or 2 (SKIP) prevents recursion | ||
48 | * into that directory, instead recursive_action() returns 0 (if FALSE) | ||
49 | * or 1 (if SKIP) | ||
50 | * | ||
51 | * ACTION_FOLLOWLINKS mainly controls handling of links to dirs. | 64 | * ACTION_FOLLOWLINKS mainly controls handling of links to dirs. |
52 | * 0: lstat(statbuf). Calls fileAction on link name even if points to dir. | 65 | * 0: lstat(statbuf). Calls fileAction on link name even if points to dir. |
53 | * 1: stat(statbuf). Calls dirAction and optionally recurse on link to dir. | 66 | * 1: stat(statbuf). Calls dirAction and optionally recurse on link to dir. |
@@ -105,7 +118,7 @@ int FAST_FUNC recursive_action(const char *fileName, | |||
105 | 118 | ||
106 | if (!(flags & ACTION_DEPTHFIRST)) { | 119 | if (!(flags & ACTION_DEPTHFIRST)) { |
107 | status = dirAction(fileName, &statbuf, userData, depth); | 120 | status = dirAction(fileName, &statbuf, userData, depth); |
108 | if (!status) | 121 | if (status == FALSE) |
109 | goto done_nak_warn; | 122 | goto done_nak_warn; |
110 | if (status == SKIP) | 123 | if (status == SKIP) |
111 | return TRUE; | 124 | return TRUE; |
@@ -121,24 +134,23 @@ int FAST_FUNC recursive_action(const char *fileName, | |||
121 | status = TRUE; | 134 | status = TRUE; |
122 | while ((next = readdir(dir)) != NULL) { | 135 | while ((next = readdir(dir)) != NULL) { |
123 | char *nextFile; | 136 | char *nextFile; |
137 | int s; | ||
124 | 138 | ||
125 | nextFile = concat_subpath_file(fileName, next->d_name); | 139 | nextFile = concat_subpath_file(fileName, next->d_name); |
126 | if (nextFile == NULL) | 140 | if (nextFile == NULL) |
127 | continue; | 141 | continue; |
142 | |||
128 | /* process every file (NB: ACTION_RECURSE is set in flags) */ | 143 | /* process every file (NB: ACTION_RECURSE is set in flags) */ |
129 | if (!recursive_action(nextFile, flags, fileAction, dirAction, | 144 | s = recursive_action(nextFile, flags, fileAction, dirAction, |
130 | userData, depth + 1)) | 145 | userData, depth + 1); |
146 | if (s == FALSE) | ||
131 | status = FALSE; | 147 | status = FALSE; |
132 | // s = recursive_action(nextFile, flags, fileAction, dirAction, | ||
133 | // userData, depth + 1); | ||
134 | free(nextFile); | 148 | free(nextFile); |
135 | //#define RECURSE_RESULT_ABORT 3 | 149 | //#define RECURSE_RESULT_ABORT -1 |
136 | // if (s == RECURSE_RESULT_ABORT) { | 150 | // if (s == RECURSE_RESULT_ABORT) { |
137 | // closedir(dir); | 151 | // closedir(dir); |
138 | // return s; | 152 | // return s; |
139 | // } | 153 | // } |
140 | // if (s == FALSE) | ||
141 | // status = FALSE; | ||
142 | } | 154 | } |
143 | closedir(dir); | 155 | closedir(dir); |
144 | 156 | ||
diff --git a/libbb/securetty.c b/libbb/securetty.c new file mode 100644 index 000000000..21354e2fa --- /dev/null +++ b/libbb/securetty.c | |||
@@ -0,0 +1,26 @@ | |||
1 | /* vi: set sw=4 ts=4: */ | ||
2 | /* | ||
3 | * /etc/securetty checking. | ||
4 | * | ||
5 | * Licensed under GPLv2, see file LICENSE in this source tree. | ||
6 | */ | ||
7 | #include "libbb.h" | ||
8 | |||
9 | #if ENABLE_FEATURE_SECURETTY && !ENABLE_PAM | ||
10 | int FAST_FUNC is_tty_secure(const char *short_tty) | ||
11 | { | ||
12 | char *buf = (char*)"/etc/securetty"; /* any non-NULL is ok */ | ||
13 | parser_t *parser = config_open2("/etc/securetty", fopen_for_read); | ||
14 | while (config_read(parser, &buf, 1, 1, "# \t", PARSE_NORMAL)) { | ||
15 | if (strcmp(buf, short_tty) == 0) | ||
16 | break; | ||
17 | buf = NULL; | ||
18 | } | ||
19 | config_close(parser); | ||
20 | /* buf != NULL here if config file was not found, empty | ||
21 | * or line was found which equals short_tty. | ||
22 | * In all these cases, we report "this tty is secure". | ||
23 | */ | ||
24 | return buf != NULL; | ||
25 | } | ||
26 | #endif | ||
diff --git a/libbb/vfork_daemon_rexec.c b/libbb/vfork_daemon_rexec.c index a6d260a40..9ab49d0a1 100644 --- a/libbb/vfork_daemon_rexec.c +++ b/libbb/vfork_daemon_rexec.c | |||
@@ -123,28 +123,8 @@ int FAST_FUNC run_nofork_applet(int applet_no, char **argv) | |||
123 | 123 | ||
124 | /* In case getopt() or getopt32() was already called: | 124 | /* In case getopt() or getopt32() was already called: |
125 | * reset the libc getopt() function, which keeps internal state. | 125 | * reset the libc getopt() function, which keeps internal state. |
126 | * | ||
127 | * BSD-derived getopt() functions require that optind be set to 1 in | ||
128 | * order to reset getopt() state. This used to be generally accepted | ||
129 | * way of resetting getopt(). However, glibc's getopt() | ||
130 | * has additional getopt() state beyond optind, and requires that | ||
131 | * optind be set to zero to reset its state. So the unfortunate state of | ||
132 | * affairs is that BSD-derived versions of getopt() misbehave if | ||
133 | * optind is set to 0 in order to reset getopt(), and glibc's getopt() | ||
134 | * will core dump if optind is set 1 in order to reset getopt(). | ||
135 | * | ||
136 | * More modern versions of BSD require that optreset be set to 1 in | ||
137 | * order to reset getopt(). Sigh. Standards, anyone? | ||
138 | */ | 126 | */ |
139 | #ifdef __GLIBC__ | 127 | GETOPT_RESET(); |
140 | optind = 0; | ||
141 | #else /* BSD style */ | ||
142 | optind = 1; | ||
143 | /* optreset = 1; */ | ||
144 | #endif | ||
145 | /* optarg = NULL; opterr = 1; optopt = 63; - do we need this too? */ | ||
146 | /* (values above are what they initialized to in glibc and uclibc) */ | ||
147 | /* option_mask32 = 0; - not needed, no applet depends on it being 0 */ | ||
148 | 128 | ||
149 | argc = 1; | 129 | argc = 1; |
150 | while (argv[argc]) | 130 | while (argv[argc]) |
@@ -169,11 +149,7 @@ int FAST_FUNC run_nofork_applet(int applet_no, char **argv) | |||
169 | restore_nofork_data(&old); | 149 | restore_nofork_data(&old); |
170 | 150 | ||
171 | /* Other globals can be simply reset to defaults */ | 151 | /* Other globals can be simply reset to defaults */ |
172 | #ifdef __GLIBC__ | 152 | GETOPT_RESET(); |
173 | optind = 0; | ||
174 | #else /* BSD style */ | ||
175 | optind = 1; | ||
176 | #endif | ||
177 | 153 | ||
178 | return rc & 0xff; /* don't confuse people with "exitcodes" >255 */ | 154 | return rc & 0xff; /* don't confuse people with "exitcodes" >255 */ |
179 | } | 155 | } |
diff --git a/libpwdgrp/pwd_grp.c b/libpwdgrp/pwd_grp.c index cefbc8a7e..c9bbc8bda 100644 --- a/libpwdgrp/pwd_grp.c +++ b/libpwdgrp/pwd_grp.c | |||
@@ -14,7 +14,7 @@ | |||
14 | * exit using the atexit function to make valgrind happy. | 14 | * exit using the atexit function to make valgrind happy. |
15 | * 2) the passwd/group files: | 15 | * 2) the passwd/group files: |
16 | * a) must contain the expected number of fields (as per count of field | 16 | * a) must contain the expected number of fields (as per count of field |
17 | * delimeters ":") or we will complain with a error message. | 17 | * delimiters ":") or we will complain with a error message. |
18 | * b) leading and trailing whitespace in fields is stripped. | 18 | * b) leading and trailing whitespace in fields is stripped. |
19 | * c) some fields are not allowed to be empty (e.g. username, uid/gid), | 19 | * c) some fields are not allowed to be empty (e.g. username, uid/gid), |
20 | * and in this case NULL is returned and errno is set to EINVAL. | 20 | * and in this case NULL is returned and errno is set to EINVAL. |
@@ -149,7 +149,7 @@ static struct statics *get_S(void) | |||
149 | /* Internal functions */ | 149 | /* Internal functions */ |
150 | 150 | ||
151 | /* Divide the passwd/group/shadow record in fields | 151 | /* Divide the passwd/group/shadow record in fields |
152 | * by substituting the given delimeter | 152 | * by substituting the given delimiter |
153 | * e.g. ':' or ',' with '\0'. | 153 | * e.g. ':' or ',' with '\0'. |
154 | * Returns the number of fields found. | 154 | * Returns the number of fields found. |
155 | * Strips leading and trailing whitespace in fields. | 155 | * Strips leading and trailing whitespace in fields. |
diff --git a/loginutils/add-remove-shell.c b/loginutils/add-remove-shell.c index af7c31779..922b3333d 100644 --- a/loginutils/add-remove-shell.c +++ b/loginutils/add-remove-shell.c | |||
@@ -43,10 +43,7 @@ | |||
43 | #define REMOVE_SHELL (ENABLE_REMOVE_SHELL && (!ENABLE_ADD_SHELL || applet_name[0] == 'r')) | 43 | #define REMOVE_SHELL (ENABLE_REMOVE_SHELL && (!ENABLE_ADD_SHELL || applet_name[0] == 'r')) |
44 | #define ADD_SHELL (ENABLE_ADD_SHELL && (!ENABLE_REMOVE_SHELL || applet_name[0] == 'a')) | 44 | #define ADD_SHELL (ENABLE_ADD_SHELL && (!ENABLE_REMOVE_SHELL || applet_name[0] == 'a')) |
45 | 45 | ||
46 | /* NB: we use the _address_, not the value, of this string | 46 | #define dont_add ((char*)(uintptr_t)1) |
47 | * as a "special value of pointer" in the code. | ||
48 | */ | ||
49 | static const char dont_add[] ALIGN1 = "\n"; | ||
50 | 47 | ||
51 | int add_remove_shell_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; | 48 | int add_remove_shell_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; |
52 | int add_remove_shell_main(int argc UNUSED_PARAM, char **argv) | 49 | int add_remove_shell_main(int argc UNUSED_PARAM, char **argv) |
@@ -54,6 +51,9 @@ int add_remove_shell_main(int argc UNUSED_PARAM, char **argv) | |||
54 | FILE *orig_fp; | 51 | FILE *orig_fp; |
55 | char *orig_fn; | 52 | char *orig_fn; |
56 | char *new_fn; | 53 | char *new_fn; |
54 | struct stat sb; | ||
55 | |||
56 | sb.st_mode = 0666; | ||
57 | 57 | ||
58 | argv++; | 58 | argv++; |
59 | 59 | ||
@@ -61,6 +61,8 @@ int add_remove_shell_main(int argc UNUSED_PARAM, char **argv) | |||
61 | if (!orig_fn) | 61 | if (!orig_fn) |
62 | return EXIT_FAILURE; | 62 | return EXIT_FAILURE; |
63 | orig_fp = fopen_for_read(orig_fn); | 63 | orig_fp = fopen_for_read(orig_fn); |
64 | if (orig_fp) | ||
65 | xfstat(fileno(orig_fp), &sb, orig_fn); | ||
64 | 66 | ||
65 | new_fn = xasprintf("%s.tmp", orig_fn); | 67 | new_fn = xasprintf("%s.tmp", orig_fn); |
66 | /* | 68 | /* |
@@ -71,13 +73,9 @@ int add_remove_shell_main(int argc UNUSED_PARAM, char **argv) | |||
71 | * after which it should revert to O_TRUNC. | 73 | * after which it should revert to O_TRUNC. |
72 | * For now, I settle for O_TRUNC instead. | 74 | * For now, I settle for O_TRUNC instead. |
73 | */ | 75 | */ |
74 | xmove_fd(xopen(new_fn, O_WRONLY | O_CREAT | O_TRUNC), STDOUT_FILENO); | 76 | xmove_fd(xopen3(new_fn, O_WRONLY | O_CREAT | O_TRUNC, sb.st_mode), STDOUT_FILENO); |
75 | 77 | /* TODO? | |
76 | /* TODO: | ||
77 | struct stat sb; | ||
78 | xfstat(fileno(orig_fp), &sb); | ||
79 | xfchown(STDOUT_FILENO, sb.st_uid, sb.st_gid); | 78 | xfchown(STDOUT_FILENO, sb.st_uid, sb.st_gid); |
80 | xfchmod(STDOUT_FILENO, sb.st_mode); | ||
81 | */ | 79 | */ |
82 | 80 | ||
83 | if (orig_fp) { | 81 | if (orig_fp) { |
@@ -95,7 +93,7 @@ int add_remove_shell_main(int argc UNUSED_PARAM, char **argv) | |||
95 | } | 93 | } |
96 | /* we are add-shell */ | 94 | /* we are add-shell */ |
97 | /* mark this name as "do not add" */ | 95 | /* mark this name as "do not add" */ |
98 | *cpp = (char*)dont_add; | 96 | *cpp = dont_add; |
99 | } | 97 | } |
100 | cpp++; | 98 | cpp++; |
101 | } | 99 | } |
diff --git a/loginutils/cryptpw.c b/loginutils/cryptpw.c index 696e169fc..3dc8232e0 100644 --- a/loginutils/cryptpw.c +++ b/loginutils/cryptpw.c | |||
@@ -64,7 +64,7 @@ OPTIONS | |||
64 | $1$. | 64 | $1$. |
65 | -R, --rounds=NUMBER | 65 | -R, --rounds=NUMBER |
66 | Use NUMBER rounds. This argument is ignored if the method | 66 | Use NUMBER rounds. This argument is ignored if the method |
67 | choosen does not support variable rounds. For the OpenBSD Blowfish | 67 | chosen does not support variable rounds. For the OpenBSD Blowfish |
68 | method this is the logarithm of the number of rounds. | 68 | method this is the logarithm of the number of rounds. |
69 | -m, --method=TYPE | 69 | -m, --method=TYPE |
70 | Compute the password using the TYPE method. If TYPE is 'help' | 70 | Compute the password using the TYPE method. If TYPE is 'help' |
diff --git a/loginutils/login.c b/loginutils/login.c index d1757a65d..be05def09 100644 --- a/loginutils/login.c +++ b/loginutils/login.c | |||
@@ -175,25 +175,6 @@ static void die_if_nologin(void) | |||
175 | # define die_if_nologin() ((void)0) | 175 | # define die_if_nologin() ((void)0) |
176 | #endif | 176 | #endif |
177 | 177 | ||
178 | #if ENABLE_FEATURE_SECURETTY && !ENABLE_PAM | ||
179 | static int check_securetty(const char *short_tty) | ||
180 | { | ||
181 | char *buf = (char*)"/etc/securetty"; /* any non-NULL is ok */ | ||
182 | parser_t *parser = config_open2("/etc/securetty", fopen_for_read); | ||
183 | while (config_read(parser, &buf, 1, 1, "# \t", PARSE_NORMAL)) { | ||
184 | if (strcmp(buf, short_tty) == 0) | ||
185 | break; | ||
186 | buf = NULL; | ||
187 | } | ||
188 | config_close(parser); | ||
189 | /* buf != NULL here if config file was not found, empty | ||
190 | * or line was found which equals short_tty */ | ||
191 | return buf != NULL; | ||
192 | } | ||
193 | #else | ||
194 | static ALWAYS_INLINE int check_securetty(const char *short_tty UNUSED_PARAM) { return 1; } | ||
195 | #endif | ||
196 | |||
197 | #if ENABLE_SELINUX | 178 | #if ENABLE_SELINUX |
198 | static void initselinux(char *username, char *full_tty, | 179 | static void initselinux(char *username, char *full_tty, |
199 | security_context_t *user_sid) | 180 | security_context_t *user_sid) |
@@ -505,7 +486,7 @@ int login_main(int argc UNUSED_PARAM, char **argv) | |||
505 | if (opt & LOGIN_OPT_f) | 486 | if (opt & LOGIN_OPT_f) |
506 | break; /* -f USER: success without asking passwd */ | 487 | break; /* -f USER: success without asking passwd */ |
507 | 488 | ||
508 | if (pw->pw_uid == 0 && !check_securetty(short_tty)) | 489 | if (pw->pw_uid == 0 && !is_tty_secure(short_tty)) |
509 | goto auth_failed; | 490 | goto auth_failed; |
510 | 491 | ||
511 | /* Don't check the password if password entry is empty (!) */ | 492 | /* Don't check the password if password entry is empty (!) */ |
diff --git a/loginutils/su.c b/loginutils/su.c index d04b85fb1..4cce82405 100644 --- a/loginutils/su.c +++ b/loginutils/su.c | |||
@@ -23,6 +23,11 @@ | |||
23 | //config: bool "If user's shell is not in /etc/shells, disallow -s PROG" | 23 | //config: bool "If user's shell is not in /etc/shells, disallow -s PROG" |
24 | //config: default y | 24 | //config: default y |
25 | //config: depends on SU | 25 | //config: depends on SU |
26 | //config: | ||
27 | //config:config FEATURE_SU_BLANK_PW_NEEDS_SECURE_TTY | ||
28 | //config: bool "Allow blank passwords only on TTYs in /etc/securetty" | ||
29 | //config: default n | ||
30 | //config: depends on SU | ||
26 | 31 | ||
27 | //applet:/* Needs to be run by root or be suid root - needs to change uid and gid: */ | 32 | //applet:/* Needs to be run by root or be suid root - needs to change uid and gid: */ |
28 | //applet:IF_SU(APPLET(su, BB_DIR_BIN, BB_SUID_REQUIRE)) | 33 | //applet:IF_SU(APPLET(su, BB_DIR_BIN, BB_SUID_REQUIRE)) |
@@ -79,6 +84,7 @@ int su_main(int argc UNUSED_PARAM, char **argv) | |||
79 | char user_buf[64]; | 84 | char user_buf[64]; |
80 | #endif | 85 | #endif |
81 | const char *old_user; | 86 | const char *old_user; |
87 | int r; | ||
82 | 88 | ||
83 | /* Note: we don't use "'+': stop at first non-option" idiom here. | 89 | /* Note: we don't use "'+': stop at first non-option" idiom here. |
84 | * For su, "SCRIPT ARGS" or "-c CMD ARGS" do not stop option parsing: | 90 | * For su, "SCRIPT ARGS" or "-c CMD ARGS" do not stop option parsing: |
@@ -99,6 +105,11 @@ int su_main(int argc UNUSED_PARAM, char **argv) | |||
99 | argv++; | 105 | argv++; |
100 | } | 106 | } |
101 | 107 | ||
108 | tty = xmalloc_ttyname(STDIN_FILENO); | ||
109 | if (!tty) | ||
110 | tty = "none"; | ||
111 | tty = skip_dev_pfx(tty); | ||
112 | |||
102 | if (ENABLE_FEATURE_SU_SYSLOG) { | 113 | if (ENABLE_FEATURE_SU_SYSLOG) { |
103 | /* The utmp entry (via getlogin) is probably the best way to | 114 | /* The utmp entry (via getlogin) is probably the best way to |
104 | * identify the user, especially if someone su's from a su-shell. | 115 | * identify the user, especially if someone su's from a su-shell. |
@@ -112,20 +123,26 @@ int su_main(int argc UNUSED_PARAM, char **argv) | |||
112 | pw = getpwuid(cur_uid); | 123 | pw = getpwuid(cur_uid); |
113 | old_user = pw ? xstrdup(pw->pw_name) : ""; | 124 | old_user = pw ? xstrdup(pw->pw_name) : ""; |
114 | } | 125 | } |
115 | tty = xmalloc_ttyname(2); | ||
116 | if (!tty) { | ||
117 | tty = "none"; | ||
118 | } | ||
119 | openlog(applet_name, 0, LOG_AUTH); | 126 | openlog(applet_name, 0, LOG_AUTH); |
120 | } | 127 | } |
121 | 128 | ||
122 | pw = xgetpwnam(opt_username); | 129 | pw = xgetpwnam(opt_username); |
123 | 130 | ||
124 | if (cur_uid == 0 || ask_and_check_password(pw) > 0) { | 131 | r = 1; |
132 | if (cur_uid != 0) | ||
133 | r = ask_and_check_password(pw); | ||
134 | if (r > 0) { | ||
135 | if (ENABLE_FEATURE_SU_BLANK_PW_NEEDS_SECURE_TTY | ||
136 | && r == CHECKPASS_PW_HAS_EMPTY_PASSWORD | ||
137 | && !is_tty_secure(tty) | ||
138 | ) { | ||
139 | goto fail; | ||
140 | } | ||
125 | if (ENABLE_FEATURE_SU_SYSLOG) | 141 | if (ENABLE_FEATURE_SU_SYSLOG) |
126 | syslog(LOG_NOTICE, "%c %s %s:%s", | 142 | syslog(LOG_NOTICE, "%c %s %s:%s", |
127 | '+', tty, old_user, opt_username); | 143 | '+', tty, old_user, opt_username); |
128 | } else { | 144 | } else { |
145 | fail: | ||
129 | if (ENABLE_FEATURE_SU_SYSLOG) | 146 | if (ENABLE_FEATURE_SU_SYSLOG) |
130 | syslog(LOG_NOTICE, "%c %s %s:%s", | 147 | syslog(LOG_NOTICE, "%c %s %s:%s", |
131 | '-', tty, old_user, opt_username); | 148 | '-', tty, old_user, opt_username); |
diff --git a/mailutils/sendmail.c b/mailutils/sendmail.c index 8ddb7826b..b542099fd 100644 --- a/mailutils/sendmail.c +++ b/mailutils/sendmail.c | |||
@@ -150,7 +150,7 @@ static char *sane_address(char *str) | |||
150 | trim(str); | 150 | trim(str); |
151 | s = str; | 151 | s = str; |
152 | while (*s) { | 152 | while (*s) { |
153 | if (!isalnum(*s) && !strchr("_-.@", *s)) { | 153 | if (!isalnum(*s) && !strchr("+_-.@", *s)) { |
154 | bb_error_msg("bad address '%s'", str); | 154 | bb_error_msg("bad address '%s'", str); |
155 | /* returning "": */ | 155 | /* returning "": */ |
156 | str[0] = '\0'; | 156 | str[0] = '\0'; |
diff --git a/miscutils/inotifyd.c b/miscutils/inotifyd.c index 601df6465..db8ddce92 100644 --- a/miscutils/inotifyd.c +++ b/miscutils/inotifyd.c | |||
@@ -12,7 +12,7 @@ | |||
12 | * Use as follows: | 12 | * Use as follows: |
13 | * # inotifyd /user/space/agent dir/or/file/being/watched[:mask] ... | 13 | * # inotifyd /user/space/agent dir/or/file/being/watched[:mask] ... |
14 | * | 14 | * |
15 | * When a filesystem event matching the specified mask is occured on specified file (or directory) | 15 | * When a filesystem event matching the specified mask is occurred on specified file (or directory) |
16 | * a userspace agent is spawned and given the following parameters: | 16 | * a userspace agent is spawned and given the following parameters: |
17 | * $1. actual event(s) | 17 | * $1. actual event(s) |
18 | * $2. file (or directory) name | 18 | * $2. file (or directory) name |
diff --git a/miscutils/less.c b/miscutils/less.c index 220e2c693..16be1447e 100644 --- a/miscutils/less.c +++ b/miscutils/less.c | |||
@@ -271,7 +271,7 @@ struct globals { | |||
271 | /* flines[] are lines read from stdin, each in malloc'ed buffer. | 271 | /* flines[] are lines read from stdin, each in malloc'ed buffer. |
272 | * Line numbers are stored as uint32_t prepended to each line. | 272 | * Line numbers are stored as uint32_t prepended to each line. |
273 | * Pointer is adjusted so that flines[i] points directly past | 273 | * Pointer is adjusted so that flines[i] points directly past |
274 | * line number. Accesor: */ | 274 | * line number. Accessor: */ |
275 | #define MEMPTR(p) ((char*)(p) - 4) | 275 | #define MEMPTR(p) ((char*)(p) - 4) |
276 | #define LINENO(p) (*(uint32_t*)((p) - 4)) | 276 | #define LINENO(p) (*(uint32_t*)((p) - 4)) |
277 | 277 | ||
diff --git a/miscutils/lsscsi.c b/miscutils/lsscsi.c new file mode 100644 index 000000000..1521680ac --- /dev/null +++ b/miscutils/lsscsi.c | |||
@@ -0,0 +1,123 @@ | |||
1 | /* vi: set sw=4 ts=4: */ | ||
2 | /* | ||
3 | * lsscsi implementation for busybox | ||
4 | * | ||
5 | * Copyright (C) 2017 Markus Gothe <nietzsche@lysator.liu.se> | ||
6 | * | ||
7 | * Licensed under GPLv2 or later, see file LICENSE in this source tree. | ||
8 | */ | ||
9 | //config:config LSSCSI | ||
10 | //config: bool "lsscsi" | ||
11 | //config: default y | ||
12 | //config: #select PLATFORM_LINUX | ||
13 | //config: help | ||
14 | //config: lsscsi is a utility for displaying information about SCSI buses in the | ||
15 | //config: system and devices connected to them. | ||
16 | //config: | ||
17 | //config: This version uses sysfs (/sys/bus/scsi/devices) only. | ||
18 | |||
19 | //applet:IF_LSSCSI(APPLET(lsscsi, BB_DIR_USR_BIN, BB_SUID_DROP)) | ||
20 | |||
21 | //kbuild:lib-$(CONFIG_LSSCSI) += lsscsi.o | ||
22 | |||
23 | //usage:#define lsscsi_trivial_usage NOUSAGE_STR | ||
24 | //usage:#define lsscsi_full_usage "" | ||
25 | |||
26 | #include "libbb.h" | ||
27 | |||
28 | static char *get_line(const char *filename, char *buf, unsigned *bufsize_p) | ||
29 | { | ||
30 | unsigned bufsize = *bufsize_p; | ||
31 | ssize_t sz; | ||
32 | |||
33 | if ((int)(bufsize - 2) <= 0) | ||
34 | return buf; | ||
35 | |||
36 | sz = open_read_close(filename, buf, bufsize - 2); | ||
37 | if (sz < 0) | ||
38 | sz = 0; | ||
39 | buf[sz] = '\0'; | ||
40 | trim(buf); | ||
41 | |||
42 | sz = strlen(buf) + 1; | ||
43 | bufsize -= sz; | ||
44 | buf += sz; | ||
45 | buf[0] = '\0'; | ||
46 | |||
47 | *bufsize_p = bufsize; | ||
48 | return buf; | ||
49 | } | ||
50 | |||
51 | int lsscsi_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; | ||
52 | int lsscsi_main(int argc UNUSED_PARAM, char **argv UNUSED_PARAM) | ||
53 | { | ||
54 | struct dirent *de; | ||
55 | DIR *dir; | ||
56 | |||
57 | xchdir("/sys/bus/scsi/devices"); | ||
58 | |||
59 | dir = xopendir("."); | ||
60 | while ((de = readdir(dir)) != NULL) { | ||
61 | char buf[256]; | ||
62 | char *ptr; | ||
63 | unsigned bufsize; | ||
64 | const char *vendor; | ||
65 | const char *type_str; | ||
66 | const char *type_name; | ||
67 | const char *model; | ||
68 | const char *rev; | ||
69 | unsigned type; | ||
70 | |||
71 | if (!isdigit(de->d_name[0])) | ||
72 | continue; | ||
73 | if (!strchr(de->d_name, ':')) | ||
74 | continue; | ||
75 | if (chdir(de->d_name) != 0) | ||
76 | continue; | ||
77 | |||
78 | bufsize = sizeof(buf); | ||
79 | vendor = buf; | ||
80 | ptr = get_line("vendor", buf, &bufsize); | ||
81 | type_str = ptr; | ||
82 | ptr = get_line("type", ptr, &bufsize); | ||
83 | model = ptr; | ||
84 | ptr = get_line("model", ptr, &bufsize); | ||
85 | rev = ptr; | ||
86 | ptr = get_line("rev", ptr, &bufsize); | ||
87 | |||
88 | printf("[%s]\t", de->d_name); | ||
89 | |||
90 | #define scsi_device_types \ | ||
91 | "disk\0" "tape\0" "printer\0" "process\0" \ | ||
92 | "worm\0" "\0" "scanner\0" "optical\0" \ | ||
93 | "mediumx\0" "comms\0" "\0" "\0" \ | ||
94 | "storage\0" "enclosu\0" "sim dsk\0" "opti rd\0" \ | ||
95 | "bridge\0" "osd\0" "adi\0" "\0" \ | ||
96 | "\0" "\0" "\0" "\0" \ | ||
97 | "\0" "\0" "\0" "\0" \ | ||
98 | "\0" "\0" "wlun\0" "no dev" | ||
99 | type = bb_strtou(type_str, NULL, 10); | ||
100 | if (errno | ||
101 | || type >= 0x20 | ||
102 | || (type_name = nth_string(scsi_device_types, type))[0] == '\0' | ||
103 | ) { | ||
104 | printf("(%s)\t", type_str); | ||
105 | } else { | ||
106 | printf("%s\t", type_name); | ||
107 | } | ||
108 | |||
109 | printf("%s\t""%s\t""%s\n", | ||
110 | vendor, | ||
111 | model, | ||
112 | rev | ||
113 | ); | ||
114 | /* TODO: also output device column, e.g. "/dev/sdX" */ | ||
115 | |||
116 | xchdir(".."); | ||
117 | } | ||
118 | |||
119 | if (ENABLE_FEATURE_CLEAN_UP) | ||
120 | closedir(dir); | ||
121 | |||
122 | return EXIT_SUCCESS; | ||
123 | } | ||
diff --git a/miscutils/partprobe.c b/miscutils/partprobe.c new file mode 100644 index 000000000..38831598d --- /dev/null +++ b/miscutils/partprobe.c | |||
@@ -0,0 +1,56 @@ | |||
1 | /* vi: set sw=4 ts=4: */ | ||
2 | /* | ||
3 | * Copyright (C) 2017 Denys Vlasenko <vda.linux@googlemail.com> | ||
4 | * | ||
5 | * Licensed under GPLv2, see file LICENSE in this source tree. | ||
6 | */ | ||
7 | //config:config PARTPROBE | ||
8 | //config: bool "partprobe" | ||
9 | //config: default y | ||
10 | //config: select PLATFORM_LINUX | ||
11 | //config: help | ||
12 | //config: Ask kernel to rescan partition table. | ||
13 | |||
14 | //applet:IF_PARTPROBE(APPLET(partprobe, BB_DIR_USR_SBIN, BB_SUID_DROP)) | ||
15 | |||
16 | //kbuild:lib-$(CONFIG_PARTPROBE) += partprobe.o | ||
17 | |||
18 | #include <linux/fs.h> | ||
19 | #include "libbb.h" | ||
20 | #ifndef BLKRRPART | ||
21 | # define BLKRRPART _IO(0x12,95) | ||
22 | #endif | ||
23 | |||
24 | //usage:#define partprobe_trivial_usage | ||
25 | //usage: "DEVICE..." | ||
26 | //usage:#define partprobe_full_usage "\n\n" | ||
27 | //usage: "Ask kernel to rescan partition table" | ||
28 | // | ||
29 | // partprobe (GNU parted) 3.2: | ||
30 | // -d, --dry-run Don't update the kernel | ||
31 | // -s, --summary Show a summary of devices and their partitions | ||
32 | |||
33 | int partprobe_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; | ||
34 | int partprobe_main(int argc UNUSED_PARAM, char **argv) | ||
35 | { | ||
36 | getopt32(argv, ""); | ||
37 | argv += optind; | ||
38 | |||
39 | /* "partprobe" with no arguments just does nothing */ | ||
40 | |||
41 | while (*argv) { | ||
42 | int fd = xopen(*argv, O_RDONLY); | ||
43 | /* | ||
44 | * Newer versions of parted scan partition tables themselves and | ||
45 | * use BLKPG ioctl (BLKPG_DEL_PARTITION / BLKPG_ADD_PARTITION) | ||
46 | * since this way kernel does not need to know | ||
47 | * partition table formats. | ||
48 | * We use good old BLKRRPART: | ||
49 | */ | ||
50 | ioctl_or_perror_and_die(fd, BLKRRPART, NULL, "%s", *argv); | ||
51 | close(fd); | ||
52 | argv++; | ||
53 | } | ||
54 | |||
55 | return EXIT_SUCCESS; | ||
56 | } | ||
diff --git a/miscutils/time.c b/miscutils/time.c index a73a837d8..e377bb6b7 100644 --- a/miscutils/time.c +++ b/miscutils/time.c | |||
@@ -21,10 +21,14 @@ | |||
21 | //kbuild:lib-$(CONFIG_TIME) += time.o | 21 | //kbuild:lib-$(CONFIG_TIME) += time.o |
22 | 22 | ||
23 | //usage:#define time_trivial_usage | 23 | //usage:#define time_trivial_usage |
24 | //usage: "[-v] PROG ARGS" | 24 | //usage: "[-vpa] [-o FILE] PROG ARGS" |
25 | //usage:#define time_full_usage "\n\n" | 25 | //usage:#define time_full_usage "\n\n" |
26 | //usage: "Run PROG, display resource usage when it exits\n" | 26 | //usage: "Run PROG, display resource usage when it exits\n" |
27 | //usage: "\n -v Verbose" | 27 | //usage: "\n -v Verbose" |
28 | //usage: "\n -p POSIX output format" | ||
29 | //usage: "\n -f FMT Custom format" | ||
30 | //usage: "\n -o FILE Write result to FILE" | ||
31 | //usage: "\n -a Append (else overwrite)" | ||
28 | 32 | ||
29 | #include "libbb.h" | 33 | #include "libbb.h" |
30 | #include <sys/resource.h> /* getrusage */ | 34 | #include <sys/resource.h> /* getrusage */ |
@@ -397,7 +401,7 @@ static void run_command(char *const *cmd, resource_t *resp) | |||
397 | } | 401 | } |
398 | 402 | ||
399 | /* Have signals kill the child but not self (if possible). */ | 403 | /* Have signals kill the child but not self (if possible). */ |
400 | //TODO: just block all sigs? and reenable them in the very end in main? | 404 | //TODO: just block all sigs? and re-enable them in the very end in main? |
401 | interrupt_signal = signal(SIGINT, SIG_IGN); | 405 | interrupt_signal = signal(SIGINT, SIG_IGN); |
402 | quit_signal = signal(SIGQUIT, SIG_IGN); | 406 | quit_signal = signal(SIGQUIT, SIG_IGN); |
403 | 407 | ||
@@ -412,29 +416,50 @@ int time_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; | |||
412 | int time_main(int argc UNUSED_PARAM, char **argv) | 416 | int time_main(int argc UNUSED_PARAM, char **argv) |
413 | { | 417 | { |
414 | resource_t res; | 418 | resource_t res; |
415 | const char *output_format = default_format; | 419 | /* $TIME has lowest prio (-v,-p,-f FMT overrride it) */ |
420 | const char *output_format = getenv("TIME") ? : default_format; | ||
421 | char *output_filename; | ||
422 | int output_fd; | ||
416 | int opt; | 423 | int opt; |
424 | int ex; | ||
425 | enum { | ||
426 | OPT_v = (1 << 0), | ||
427 | OPT_p = (1 << 1), | ||
428 | OPT_a = (1 << 2), | ||
429 | OPT_o = (1 << 3), | ||
430 | OPT_f = (1 << 4), | ||
431 | }; | ||
417 | 432 | ||
418 | opt_complementary = "-1"; /* at least one arg */ | 433 | opt_complementary = "-1"; /* at least one arg */ |
419 | /* "+": stop on first non-option */ | 434 | /* "+": stop on first non-option */ |
420 | opt = getopt32(argv, "+vp"); | 435 | opt = getopt32(argv, "+vpao:f:", &output_filename, &output_format); |
421 | argv += optind; | 436 | argv += optind; |
422 | if (opt & 1) | 437 | if (opt & OPT_v) |
423 | output_format = long_format; | 438 | output_format = long_format; |
424 | if (opt & 2) | 439 | if (opt & OPT_p) |
425 | output_format = posix_format; | 440 | output_format = posix_format; |
441 | output_fd = STDERR_FILENO; | ||
442 | if (opt & OPT_o) { | ||
443 | output_fd = xopen(output_filename, | ||
444 | (opt & OPT_a) /* append? */ | ||
445 | ? (O_CREAT | O_WRONLY | O_CLOEXEC | O_APPEND) | ||
446 | : (O_CREAT | O_WRONLY | O_CLOEXEC | O_TRUNC) | ||
447 | ); | ||
448 | } | ||
426 | 449 | ||
427 | run_command(argv, &res); | 450 | run_command(argv, &res); |
428 | 451 | ||
429 | /* Cheat. printf's are shorter :) */ | 452 | /* Cheat. printf's are shorter :) */ |
430 | xdup2(STDERR_FILENO, STDOUT_FILENO); | 453 | xdup2(output_fd, STDOUT_FILENO); |
431 | summarize(output_format, argv, &res); | 454 | summarize(output_format, argv, &res); |
432 | 455 | ||
456 | ex = WEXITSTATUS(res.waitstatus); | ||
457 | /* Impossible: we do not use WUNTRACED flag in wait()... | ||
433 | if (WIFSTOPPED(res.waitstatus)) | 458 | if (WIFSTOPPED(res.waitstatus)) |
434 | return WSTOPSIG(res.waitstatus); | 459 | ex = WSTOPSIG(res.waitstatus); |
460 | */ | ||
435 | if (WIFSIGNALED(res.waitstatus)) | 461 | if (WIFSIGNALED(res.waitstatus)) |
436 | return WTERMSIG(res.waitstatus); | 462 | ex = WTERMSIG(res.waitstatus); |
437 | if (WIFEXITED(res.waitstatus)) | 463 | |
438 | return WEXITSTATUS(res.waitstatus); | 464 | fflush_stdout_and_exit(ex); |
439 | fflush_stdout_and_exit(EXIT_SUCCESS); | ||
440 | } | 465 | } |
diff --git a/modutils/Config.src b/modutils/Config.src index 5f0b0cec4..9b76c83d2 100644 --- a/modutils/Config.src +++ b/modutils/Config.src | |||
@@ -75,7 +75,7 @@ config FEATURE_INSMOD_KSYMOOPS_SYMBOLS | |||
75 | depends on FEATURE_2_4_MODULES && (INSMOD || MODPROBE) | 75 | depends on FEATURE_2_4_MODULES && (INSMOD || MODPROBE) |
76 | help | 76 | help |
77 | By adding module symbols to the kernel symbol table, Oops messages | 77 | By adding module symbols to the kernel symbol table, Oops messages |
78 | occuring within kernel modules can be properly debugged. By enabling | 78 | occurring within kernel modules can be properly debugged. By enabling |
79 | this feature, module symbols will always be added to the kernel symbol | 79 | this feature, module symbols will always be added to the kernel symbol |
80 | table for proper debugging support. If you are not interested in | 80 | table for proper debugging support. If you are not interested in |
81 | Oops messages from kernel modules, say N. | 81 | Oops messages from kernel modules, say N. |
diff --git a/modutils/modinfo.c b/modutils/modinfo.c index aa641ad54..ead2cf16f 100644 --- a/modutils/modinfo.c +++ b/modutils/modinfo.c | |||
@@ -104,7 +104,7 @@ static void modinfo(const char *path, const char *version, | |||
104 | char *after_pattern; | 104 | char *after_pattern; |
105 | 105 | ||
106 | ptr = memchr(ptr, *pattern, len - (ptr - (char*)the_module)); | 106 | ptr = memchr(ptr, *pattern, len - (ptr - (char*)the_module)); |
107 | if (ptr == NULL) /* no occurance left, done */ | 107 | if (ptr == NULL) /* no occurrence left, done */ |
108 | break; | 108 | break; |
109 | after_pattern = is_prefixed_with(ptr, pattern); | 109 | after_pattern = is_prefixed_with(ptr, pattern); |
110 | if (after_pattern && *after_pattern == '=') { | 110 | if (after_pattern && *after_pattern == '=') { |
diff --git a/modutils/modprobe-small.c b/modutils/modprobe-small.c index 431b8aeb2..053a7df89 100644 --- a/modutils/modprobe-small.c +++ b/modutils/modprobe-small.c | |||
@@ -79,6 +79,7 @@ int lsmod_main(int argc UNUSED_PARAM, char **argv UNUSED_PARAM) | |||
79 | #define is_rmmod (ENABLE_RMMOD && (ONLY_APPLET || applet_name[0] == 'r')) | 79 | #define is_rmmod (ENABLE_RMMOD && (ONLY_APPLET || applet_name[0] == 'r')) |
80 | 80 | ||
81 | enum { | 81 | enum { |
82 | DEPMOD_OPT_n = (1 << 0), /* dry-run, print to stdout */ | ||
82 | OPT_q = (1 << 0), /* be quiet */ | 83 | OPT_q = (1 << 0), /* be quiet */ |
83 | OPT_r = (1 << 1), /* module removal instead of loading */ | 84 | OPT_r = (1 << 1), /* module removal instead of loading */ |
84 | }; | 85 | }; |
@@ -168,7 +169,7 @@ static char* find_keyword(char *ptr, size_t len, const char *word) | |||
168 | 169 | ||
169 | /* search for the first char in word */ | 170 | /* search for the first char in word */ |
170 | ptr = memchr(ptr, word[0], len); | 171 | ptr = memchr(ptr, word[0], len); |
171 | if (ptr == NULL) /* no occurance left, done */ | 172 | if (ptr == NULL) /* no occurrence left, done */ |
172 | break; | 173 | break; |
173 | after_word = is_prefixed_with(ptr, word); | 174 | after_word = is_prefixed_with(ptr, word); |
174 | if (after_word) | 175 | if (after_word) |
@@ -410,7 +411,7 @@ static FAST_FUNC int fileAction(const char *pathname, | |||
410 | if (load_module(pathname, module_load_options) == 0) { | 411 | if (load_module(pathname, module_load_options) == 0) { |
411 | /* Load was successful, there is nothing else to do. | 412 | /* Load was successful, there is nothing else to do. |
412 | * This can happen ONLY for "top-level" module load, | 413 | * This can happen ONLY for "top-level" module load, |
413 | * not a dep, because deps dont do dirscan. */ | 414 | * not a dep, because deps don't do dirscan. */ |
414 | exit(EXIT_SUCCESS); | 415 | exit(EXIT_SUCCESS); |
415 | } | 416 | } |
416 | } | 417 | } |
@@ -477,7 +478,7 @@ static int start_dep_bb_writeout(void) | |||
477 | int fd; | 478 | int fd; |
478 | 479 | ||
479 | /* depmod -n: write result to stdout */ | 480 | /* depmod -n: write result to stdout */ |
480 | if (applet_name[0] == 'd' && (option_mask32 & 1)) | 481 | if (is_depmod && (option_mask32 & DEPMOD_OPT_n)) |
481 | return STDOUT_FILENO; | 482 | return STDOUT_FILENO; |
482 | 483 | ||
483 | fd = open(DEPFILE_BB".new", O_WRONLY | O_CREAT | O_TRUNC | O_EXCL, 0644); | 484 | fd = open(DEPFILE_BB".new", O_WRONLY | O_CREAT | O_TRUNC | O_EXCL, 0644); |
@@ -764,9 +765,12 @@ static int process_module(char *name, const char *cmdline_options) | |||
764 | 765 | ||
765 | if (!infovec) { | 766 | if (!infovec) { |
766 | /* both dirscan and find_alias found nothing */ | 767 | /* both dirscan and find_alias found nothing */ |
767 | if (!is_remove && !is_depmod) /* it wasn't rmmod or depmod */ | 768 | if (!is_remove && !is_depmod) { /* it wasn't rmmod or depmod */ |
768 | bb_error_msg("module '%s' not found", name); | 769 | bb_error_msg("module '%s' not found", name); |
769 | //TODO: _and_die()? or should we continue (un)loading modules listed on cmdline? | 770 | //TODO: _and_die()? or should we continue (un)loading modules listed on cmdline? |
771 | /* "modprobe non-existing-module; echo $?" must print 1 */ | ||
772 | exitcode = EXIT_FAILURE; | ||
773 | } | ||
770 | goto ret; | 774 | goto ret; |
771 | } | 775 | } |
772 | 776 | ||
@@ -862,25 +866,28 @@ Usage: rmmod [-fhswvV] modulename ... | |||
862 | should eventually fall to zero). | 866 | should eventually fall to zero). |
863 | 867 | ||
864 | # modprobe | 868 | # modprobe |
865 | Usage: modprobe [-v] [-V] [-C config-file] [-n] [-i] [-q] [-b] | 869 | Usage: modprobe [-v] [-V] [-C config-file] [-d <dirname> ] [-n] [-i] [-q] |
866 | [-o <modname>] [ --dump-modversions ] <modname> [parameters...] | 870 | [-b] [-o <modname>] [ --dump-modversions ] <modname> [parameters...] |
867 | modprobe -r [-n] [-i] [-v] <modulename> ... | 871 | modprobe -r [-n] [-i] [-v] <modulename> ... |
868 | modprobe -l -t <dirname> [ -a <modulename> ...] | 872 | modprobe -l -t <dirname> [ -a <modulename> ...] |
869 | 873 | ||
870 | # depmod --help | 874 | # depmod --help |
871 | depmod 3.4 -- part of module-init-tools | 875 | depmod 3.13 -- part of module-init-tools |
872 | depmod -[aA] [-n -e -v -q -V -r -u] | 876 | depmod -[aA] [-n -e -v -q -V -r -u -w -m] |
873 | [-b basedirectory] [forced_version] | 877 | [-b basedirectory] [forced_version] |
874 | depmod [-n -e -v -q -r -u] [-F kernelsyms] module1.ko module2.ko ... | 878 | depmod [-n -e -v -q -r -u -w] [-F kernelsyms] module1.ko module2.ko ... |
875 | If no arguments (except options) are given, "depmod -a" is assumed. | 879 | If no arguments (except options) are given, "depmod -a" is assumed. |
876 | depmod will output a dependency list suitable for the modprobe utility. | 880 | depmod will output a dependency list suitable for the modprobe utility. |
877 | Options: | 881 | Options: |
878 | -a, --all Probe all modules | 882 | -a, --all Probe all modules |
879 | -A, --quick Only does the work if there's a new module | 883 | -A, --quick Only does the work if there's a new module |
880 | -n, --show Write the dependency file on stdout only | ||
881 | -e, --errsyms Report not supplied symbols | 884 | -e, --errsyms Report not supplied symbols |
885 | -m, --map Create the legacy map files | ||
886 | -n, --show Write the dependency file on stdout only | ||
887 | -P, --symbol-prefix Architecture symbol prefix | ||
882 | -V, --version Print the release version | 888 | -V, --version Print the release version |
883 | -v, --verbose Enable verbose mode | 889 | -v, --verbose Enable verbose mode |
890 | -w, --warn Warn on duplicates | ||
884 | -h, --help Print this usage message | 891 | -h, --help Print this usage message |
885 | The following options are useful for people managing distributions: | 892 | The following options are useful for people managing distributions: |
886 | -b basedirectory | 893 | -b basedirectory |
@@ -889,12 +896,18 @@ The following options are useful for people managing distributions: | |||
889 | -F kernelsyms | 896 | -F kernelsyms |
890 | --filesyms kernelsyms | 897 | --filesyms kernelsyms |
891 | Use the file instead of the current kernel symbols | 898 | Use the file instead of the current kernel symbols |
899 | -E Module.symvers | ||
900 | --symvers Module.symvers | ||
901 | Use Module.symvers file to check symbol versions | ||
892 | */ | 902 | */ |
893 | 903 | ||
894 | //usage:#if ENABLE_MODPROBE_SMALL | 904 | //usage:#if ENABLE_MODPROBE_SMALL |
895 | 905 | ||
896 | //usage:#define depmod_trivial_usage NOUSAGE_STR | 906 | //usage:#define depmod_trivial_usage "[-n]" |
897 | //usage:#define depmod_full_usage "" | 907 | //usage:#define depmod_full_usage "\n\n" |
908 | //usage: "Generate modules.dep.bb" | ||
909 | //usage: "\n" | ||
910 | //usage: "\n -n Dry run: print file to stdout" | ||
898 | 911 | ||
899 | //usage:#define insmod_trivial_usage | 912 | //usage:#define insmod_trivial_usage |
900 | //usage: "FILE" IF_FEATURE_CMDLINE_MODULE_OPTIONS(" [SYMBOL=VALUE]...") | 913 | //usage: "FILE" IF_FEATURE_CMDLINE_MODULE_OPTIONS(" [SYMBOL=VALUE]...") |
@@ -947,10 +960,12 @@ int modprobe_main(int argc UNUSED_PARAM, char **argv) | |||
947 | * -e: report any symbols which a module needs | 960 | * -e: report any symbols which a module needs |
948 | * which are not supplied by other modules or the kernel | 961 | * which are not supplied by other modules or the kernel |
949 | * -F FILE: System.map (symbols for -e) | 962 | * -F FILE: System.map (symbols for -e) |
950 | * -q, -r, -u: noop? | 963 | * -q, -r, -u: noop |
951 | * Not supported: | 964 | * Not supported: |
952 | * -b BASEDIR: (TODO!) modules are in | 965 | * -b BASEDIR: (TODO!) modules are in |
953 | * $BASEDIR/lib/modules/$VERSION | 966 | * $BASEDIR/lib/modules/$VERSION |
967 | * -m: create legacy "modules.*map" files (deprecated; in | ||
968 | * kmod's depmod, prints a warning message and continues) | ||
954 | * -v: human readable deps to stdout | 969 | * -v: human readable deps to stdout |
955 | * -V: version (don't want to support it - people may depend | 970 | * -V: version (don't want to support it - people may depend |
956 | * on it as an indicator of "standard" depmod) | 971 | * on it as an indicator of "standard" depmod) |
diff --git a/modutils/modprobe.c b/modutils/modprobe.c index a6224fa63..51ede9204 100644 --- a/modutils/modprobe.c +++ b/modutils/modprobe.c | |||
@@ -171,6 +171,7 @@ static const char modprobe_longopts[] ALIGN1 = | |||
171 | /* "was seen in modules.dep": */ | 171 | /* "was seen in modules.dep": */ |
172 | #define MODULE_FLAG_FOUND_IN_MODDEP 0x0004 | 172 | #define MODULE_FLAG_FOUND_IN_MODDEP 0x0004 |
173 | #define MODULE_FLAG_BLACKLISTED 0x0008 | 173 | #define MODULE_FLAG_BLACKLISTED 0x0008 |
174 | #define MODULE_FLAG_BUILTIN 0x0010 | ||
174 | 175 | ||
175 | struct globals { | 176 | struct globals { |
176 | llist_t *probes; /* MEs of module(s) requested on cmdline */ | 177 | llist_t *probes; /* MEs of module(s) requested on cmdline */ |
@@ -217,7 +218,7 @@ static void add_probe(const char *name) | |||
217 | 218 | ||
218 | m = get_or_add_modentry(name); | 219 | m = get_or_add_modentry(name); |
219 | if (!(option_mask32 & (OPT_REMOVE | OPT_SHOW_DEPS)) | 220 | if (!(option_mask32 & (OPT_REMOVE | OPT_SHOW_DEPS)) |
220 | && (m->flags & MODULE_FLAG_LOADED) | 221 | && (m->flags & (MODULE_FLAG_LOADED | MODULE_FLAG_BUILTIN)) |
221 | ) { | 222 | ) { |
222 | DBG("skipping %s, it is already loaded", name); | 223 | DBG("skipping %s, it is already loaded", name); |
223 | return; | 224 | return; |
@@ -251,6 +252,15 @@ static int FAST_FUNC config_file_action(const char *filename, | |||
251 | if (base[0] == '.') | 252 | if (base[0] == '.') |
252 | goto error; | 253 | goto error; |
253 | 254 | ||
255 | /* "man modprobe.d" from kmod version 22 suggests | ||
256 | * that we shouldn't recurse into /etc/modprobe.d/dir/ | ||
257 | * _subdirectories_: | ||
258 | */ | ||
259 | if (depth > 1) | ||
260 | return SKIP; /* stop recursing */ | ||
261 | //TODO: instead, can use dirAction in recursive_action() to SKIP dirs | ||
262 | //on depth == 1 level. But that's more code... | ||
263 | |||
254 | /* In dir recursion, skip files that do not end with a ".conf" | 264 | /* In dir recursion, skip files that do not end with a ".conf" |
255 | * depth==0: read_config("modules.{symbols,alias}") must work, | 265 | * depth==0: read_config("modules.{symbols,alias}") must work, |
256 | * "include FILE_NOT_ENDING_IN_CONF" must work too. | 266 | * "include FILE_NOT_ENDING_IN_CONF" must work too. |
@@ -413,8 +423,10 @@ static int do_modprobe(struct module_entry *m) | |||
413 | 423 | ||
414 | if (!(m->flags & MODULE_FLAG_FOUND_IN_MODDEP)) { | 424 | if (!(m->flags & MODULE_FLAG_FOUND_IN_MODDEP)) { |
415 | if (!(option_mask32 & INSMOD_OPT_SILENT)) | 425 | if (!(option_mask32 & INSMOD_OPT_SILENT)) |
416 | bb_error_msg("module %s not found in modules.dep", | 426 | bb_error_msg((m->flags & MODULE_FLAG_BUILTIN) ? |
417 | humanly_readable_name(m)); | 427 | "module %s is builtin" : |
428 | "module %s not found in modules.dep", | ||
429 | humanly_readable_name(m)); | ||
418 | return -ENOENT; | 430 | return -ENOENT; |
419 | } | 431 | } |
420 | DBG("do_modprob'ing %s", m->modname); | 432 | DBG("do_modprob'ing %s", m->modname); |
@@ -618,6 +630,11 @@ int modprobe_main(int argc UNUSED_PARAM, char **argv) | |||
618 | while (config_read(parser, &s, 1, 1, "# \t", PARSE_NORMAL & ~PARSE_GREEDY)) | 630 | while (config_read(parser, &s, 1, 1, "# \t", PARSE_NORMAL & ~PARSE_GREEDY)) |
619 | get_or_add_modentry(s)->flags |= MODULE_FLAG_LOADED; | 631 | get_or_add_modentry(s)->flags |= MODULE_FLAG_LOADED; |
620 | config_close(parser); | 632 | config_close(parser); |
633 | |||
634 | parser = config_open2("modules.builtin", fopen_for_read); | ||
635 | while (config_read(parser, &s, 1, 1, "# \t", PARSE_NORMAL)) | ||
636 | get_or_add_modentry(s)->flags |= MODULE_FLAG_BUILTIN; | ||
637 | config_close(parser); | ||
621 | } | 638 | } |
622 | 639 | ||
623 | if (opt & (OPT_INSERT_ALL | OPT_REMOVE)) { | 640 | if (opt & (OPT_INSERT_ALL | OPT_REMOVE)) { |
diff --git a/networking/dnsd.c b/networking/dnsd.c index 7be90018d..1b85618c6 100644 --- a/networking/dnsd.c +++ b/networking/dnsd.c | |||
@@ -360,7 +360,7 @@ RDATA a variable length string of octets that describes the resource. | |||
360 | 360 | ||
361 | In order to reduce the size of messages, domain names coan be compressed. | 361 | In order to reduce the size of messages, domain names coan be compressed. |
362 | An entire domain name or a list of labels at the end of a domain name | 362 | An entire domain name or a list of labels at the end of a domain name |
363 | is replaced with a pointer to a prior occurance of the same name. | 363 | is replaced with a pointer to a prior occurrence of the same name. |
364 | 364 | ||
365 | The pointer takes the form of a two octet sequence: | 365 | The pointer takes the form of a two octet sequence: |
366 | +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ | 366 | +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ |
diff --git a/networking/ifenslave.c b/networking/ifenslave.c index 1cb765e23..070931209 100644 --- a/networking/ifenslave.c +++ b/networking/ifenslave.c | |||
@@ -55,7 +55,7 @@ | |||
55 | * | 55 | * |
56 | * - 2003/03/18 - Tsippy Mendelson <tsippy.mendelson at intel dot com> and | 56 | * - 2003/03/18 - Tsippy Mendelson <tsippy.mendelson at intel dot com> and |
57 | * Shmulik Hen <shmulik.hen at intel dot com> | 57 | * Shmulik Hen <shmulik.hen at intel dot com> |
58 | * - Moved setting the slave's mac address and openning it, from | 58 | * - Moved setting the slave's mac address and opening it, from |
59 | * the application to the driver. This enables support of modes | 59 | * the application to the driver. This enables support of modes |
60 | * that need to use the unique mac address of each slave. | 60 | * that need to use the unique mac address of each slave. |
61 | * The driver also takes care of closing the slave and restoring its | 61 | * The driver also takes care of closing the slave and restoring its |
diff --git a/networking/ip.c b/networking/ip.c index 0f52b19dd..3cf52cdd7 100644 --- a/networking/ip.c +++ b/networking/ip.c | |||
@@ -140,47 +140,79 @@ | |||
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 | //--------------123456789.123456789.123456789.123456789.123456789.123456789.123456789.123....79 | ||
143 | //usage:#define ipaddr_trivial_usage | 144 | //usage:#define ipaddr_trivial_usage |
144 | //usage: "add|del IFADDR dev IFACE | show|flush [dev IFACE] [to PREFIX]" | 145 | //usage: "add|del IFADDR dev IFACE | show|flush [dev IFACE] [to PREFIX]" |
145 | //usage:#define ipaddr_full_usage "\n\n" | 146 | //usage:#define ipaddr_full_usage "\n\n" |
146 | //usage: "ipaddr add|change|replace|delete IFADDR dev IFACE\n" | 147 | //usage: "ipaddr add|change|replace|delete dev IFACE IFADDR\n" |
147 | //usage: "ipaddr show|flush [dev IFACE] [scope SCOPE-ID]\n" | 148 | //usage: " IFADDR := PREFIX | ADDR peer PREFIX [broadcast ADDR|+|-]\n" |
148 | //usage: " [to PREFIX] [label PATTERN]\n" | 149 | //usage: " [anycast ADDR] [label STRING] [scope SCOPE]\n" |
149 | //usage: " IFADDR := PREFIX | ADDR peer PREFIX\n" | 150 | //usage: " PREFIX := ADDR[/MASK]\n" |
150 | //usage: " [broadcast ADDR] [anycast ADDR]\n" | 151 | //usage: " SCOPE := [host|link|global|NUMBER]\n" |
151 | //usage: " [label STRING] [scope SCOPE-ID]\n" | 152 | //usage: "ipaddr show|flush [dev IFACE] [scope SCOPE] [to PREFIX] [label PATTERN]" |
152 | //usage: " SCOPE-ID := [host|link|global|NUMBER]" | ||
153 | //usage: | 153 | //usage: |
154 | //--------------123456789.123456789.123456789.123456789.123456789.123456789.123456789.123....79 | ||
154 | //usage:#define iplink_trivial_usage | 155 | //usage:#define iplink_trivial_usage |
155 | //usage: "set IFACE [up|down] [arp on|off] | show [IFACE]" | 156 | //usage: "set IFACE [up|down] [arp on|off] | show [IFACE]" |
156 | //usage:#define iplink_full_usage "\n\n" | 157 | //usage:#define iplink_full_usage "\n\n" |
157 | //usage: "iplink set IFACE [up|down]\n" | 158 | //usage: "iplink set IFACE [up|down] [arp on|off] [multicast on|off] [promisc on|off]\n" |
158 | //usage: " [arp on|off]\n" | 159 | //usage: " [mtu NUM] [name NAME] [qlen NUM] [address MAC]\n" |
159 | //usage: " [dynamic on|off]\n" | ||
160 | //usage: " [multicast on|off]\n" | ||
161 | //usage: " [mtu MTU]\n" | ||
162 | //usage: "iplink show [IFACE]" | 160 | //usage: "iplink show [IFACE]" |
163 | //usage: | 161 | //usage: |
162 | //--------------123456789.123456789.123456789.123456789.123456789.123456789.123456789.123....79 | ||
164 | //usage:#define iproute_trivial_usage | 163 | //usage:#define iproute_trivial_usage |
165 | //usage: "list|flush|add|del|change|append|replace|test ROUTE" | 164 | //usage: "list|flush|add|del|change|append|replace|test ROUTE" |
166 | //usage:#define iproute_full_usage "\n\n" | 165 | //usage:#define iproute_full_usage "\n\n" |
167 | //usage: "iproute list|flush SELECTOR\n" | 166 | //usage: "iproute list|flush SELECTOR\n" |
168 | //usage: "iproute get ADDRESS [from ADDRESS iif STRING]\n" | ||
169 | //usage: " [oif STRING] [tos TOS]\n" | ||
170 | //usage: "iproute add|del|change|append|replace|test ROUTE\n" | ||
171 | //usage: " SELECTOR := [root PREFIX] [match PREFIX] [proto RTPROTO]\n" | 167 | //usage: " SELECTOR := [root PREFIX] [match PREFIX] [proto RTPROTO]\n" |
172 | //usage: " ROUTE := [TYPE] PREFIX [tos TOS] [proto RTPROTO] [metric METRIC]" | 168 | //usage: " PREFIX := default|ADDR[/MASK]\n" |
169 | //usage: "iproute get ADDR [from ADDR iif IFACE]\n" | ||
170 | //usage: " [oif IFACE] [tos TOS]\n" | ||
171 | //usage: "iproute add|del|change|append|replace|test ROUTE\n" | ||
172 | //usage: " ROUTE := NODE_SPEC [INFO_SPEC]\n" | ||
173 | //usage: " NODE_SPEC := PREFIX"IF_FEATURE_IP_RULE(" [table TABLE_ID]")" [proto RTPROTO] [scope SCOPE] [metric METRIC]\n" | ||
174 | //usage: " INFO_SPEC := NH OPTIONS\n" | ||
175 | //usage: " NH := [via [inet|inet6] ADDR] [dev IFACE] [src ADDR] [onlink]\n" | ||
176 | //usage: " OPTIONS := [mtu [lock] NUM] [advmss [lock] NUM]" | ||
177 | //upstream man ip-route: | ||
178 | //====================== | ||
179 | //ip route { show | flush } SELECTOR | ||
180 | //ip route save SELECTOR | ||
181 | //ip route restore | ||
182 | //ip route get ADDRESS [ from ADDRESS iif STRING ] [ oif STRING ] [ tos TOS ] | ||
183 | //ip route { add | del | change | append | replace } ROUTE | ||
184 | //SELECTOR := [ root PREFIX ] [ match PREFIX ] [ exact PREFIX ] [ table TABLE_ID ] [ proto RTPROTO ] [ type TYPE ] [ scope SCOPE ] | ||
185 | //ROUTE := NODE_SPEC [ INFO_SPEC ] | ||
186 | //NODE_SPEC := [ TYPE ] PREFIX [ tos TOS ] [ table TABLE_ID ] [ proto RTPROTO ] [ scope SCOPE ] [ metric METRIC ] | ||
187 | //INFO_SPEC := NH OPTIONS FLAGS [ nexthop NH ] ... | ||
188 | //NH := [ encap ENCAP ] [ via [ FAMILY ] ADDRESS ] [ dev STRING ] [ weight NUMBER ] NHFLAGS | ||
189 | // ..............................................................^ I guess [src ADDRESS] should be here | ||
190 | //FAMILY := [ inet | inet6 | ipx | dnet | mpls | bridge | link ] | ||
191 | //OPTIONS := FLAGS [ mtu NUMBER ] [ advmss NUMBER ] [ as [ to ] ADDRESS ] rtt TIME ] [ rttvar TIME ] [ reordering NUMBER ] [ window NUMBER ] [ cwnd NUMBER ] [ ssthresh REALM ] [ realms REALM ] | ||
192 | // [ rto_min TIME ] [ initcwnd NUMBER ] [ initrwnd NUMBER ] [ features FEATURES ] [ quickack BOOL ] [ congctl NAME ] [ pref PREF ] [ expires TIME ] | ||
193 | //TYPE := [ unicast | local | broadcast | multicast | throw | unreachable | prohibit | blackhole | nat ] | ||
194 | //TABLE_ID := [ local | main | default | all | NUMBER ] | ||
195 | //SCOPE := [ host | link | global | NUMBER ] | ||
196 | //NHFLAGS := [ onlink | pervasive ] | ||
197 | //RTPROTO := [ kernel | boot | static | NUMBER ] | ||
198 | //FEATURES := [ ecn | ] | ||
199 | //PREF := [ low | medium | high ] | ||
200 | //ENCAP := [ MPLS | IP ] | ||
201 | //ENCAP_MPLS := mpls [ LABEL ] | ||
202 | //ENCAP_IP := ip id TUNNEL_ID dst REMOTE_IP [ tos TOS ] [ ttl TTL ] | ||
173 | //usage: | 203 | //usage: |
204 | //--------------123456789.123456789.123456789.123456789.123456789.123456789.123456789.123....79 | ||
174 | //usage:#define iprule_trivial_usage | 205 | //usage:#define iprule_trivial_usage |
175 | //usage: "[list] | add|del SELECTOR ACTION" | 206 | //usage: "[list] | add|del SELECTOR ACTION" |
176 | //usage:#define iprule_full_usage "\n\n" | 207 | //usage:#define iprule_full_usage "\n\n" |
177 | //usage: " SELECTOR := [from PREFIX] [to PREFIX] [tos TOS] [fwmark FWMARK]\n" | 208 | //usage: " SELECTOR := [from PREFIX] [to PREFIX] [tos TOS] [fwmark FWMARK]\n" |
178 | //usage: " [dev IFACE] [pref NUMBER]\n" | 209 | //usage: " [dev IFACE] [pref NUMBER]\n" |
179 | //usage: " ACTION := [table TABLE_ID] [nat ADDRESS]\n" | 210 | //usage: " ACTION := [table TABLE_ID] [nat ADDR]\n" |
180 | //usage: " [prohibit|reject|unreachable]\n" | 211 | //usage: " [prohibit|reject|unreachable]\n" |
181 | //usage: " [realms [SRCREALM/]DSTREALM]\n" | 212 | //usage: " [realms [SRCREALM/]DSTREALM]\n" |
182 | //usage: " TABLE_ID := [local|main|default|NUMBER]" | 213 | //usage: " TABLE_ID := [local|main|default|NUMBER]" |
183 | //usage: | 214 | //usage: |
215 | //--------------123456789.123456789.123456789.123456789.123456789.123456789.123456789.123....79 | ||
184 | //usage:#define iptunnel_trivial_usage | 216 | //usage:#define iptunnel_trivial_usage |
185 | //usage: "add|change|del|show [NAME]\n" | 217 | //usage: "add|change|del|show [NAME]\n" |
186 | //usage: " [mode ipip|gre|sit]\n" | 218 | //usage: " [mode ipip|gre|sit]\n" |
diff --git a/networking/isrv.c b/networking/isrv.c index 3673db715..97f5c6d4e 100644 --- a/networking/isrv.c +++ b/networking/isrv.c | |||
@@ -191,7 +191,7 @@ static void handle_accept(isrv_state_t *state, int fd) | |||
191 | DPRINTF("new_peer(%d)", newfd); | 191 | DPRINTF("new_peer(%d)", newfd); |
192 | n = state->new_peer(state, newfd); | 192 | n = state->new_peer(state, newfd); |
193 | if (n) | 193 | if (n) |
194 | remove_peer(state, n); /* unsuccesful peer start */ | 194 | remove_peer(state, n); /* unsuccessful peer start */ |
195 | } | 195 | } |
196 | 196 | ||
197 | static void handle_fd_set(isrv_state_t *state, fd_set *fds, int (*h)(int, void **)) | 197 | static void handle_fd_set(isrv_state_t *state, fd_set *fds, int (*h)(int, void **)) |
diff --git a/networking/libiproute/ipaddress.c b/networking/libiproute/ipaddress.c index d9e099607..36d6b65c6 100644 --- a/networking/libiproute/ipaddress.c +++ b/networking/libiproute/ipaddress.c | |||
@@ -593,9 +593,13 @@ static int default_scope(inet_prefix *lcl) | |||
593 | /* Return value becomes exitcode. It's okay to not return at all */ | 593 | /* Return value becomes exitcode. It's okay to not return at all */ |
594 | static int ipaddr_modify(int cmd, int flags, char **argv) | 594 | static int ipaddr_modify(int cmd, int flags, char **argv) |
595 | { | 595 | { |
596 | /* If you add stuff here, update ipaddr_full_usage */ | ||
596 | static const char option[] ALIGN1 = | 597 | static const char option[] ALIGN1 = |
597 | "peer\0""remote\0""broadcast\0""brd\0" | 598 | "peer\0""remote\0""broadcast\0""brd\0" |
598 | "anycast\0""scope\0""dev\0""label\0""local\0"; | 599 | "anycast\0""scope\0""dev\0""label\0""local\0"; |
600 | #define option_peer option | ||
601 | #define option_broadcast (option + sizeof("peer") + sizeof("remote")) | ||
602 | #define option_anycast (option_broadcast + sizeof("broadcast") + sizeof("brd")) | ||
599 | struct rtnl_handle rth; | 603 | struct rtnl_handle rth; |
600 | struct { | 604 | struct { |
601 | struct nlmsghdr n; | 605 | struct nlmsghdr n; |
@@ -627,7 +631,7 @@ static int ipaddr_modify(int cmd, int flags, char **argv) | |||
627 | 631 | ||
628 | if (arg <= 1) { /* peer, remote */ | 632 | if (arg <= 1) { /* peer, remote */ |
629 | if (peer_len) { | 633 | if (peer_len) { |
630 | duparg("peer", *argv); | 634 | duparg(option_peer, *argv); |
631 | } | 635 | } |
632 | get_prefix(&peer, *argv, req.ifa.ifa_family); | 636 | get_prefix(&peer, *argv, req.ifa.ifa_family); |
633 | peer_len = peer.bytelen; | 637 | peer_len = peer.bytelen; |
@@ -639,7 +643,7 @@ static int ipaddr_modify(int cmd, int flags, char **argv) | |||
639 | } else if (arg <= 3) { /* broadcast, brd */ | 643 | } else if (arg <= 3) { /* broadcast, brd */ |
640 | inet_prefix addr; | 644 | inet_prefix addr; |
641 | if (brd_len) { | 645 | if (brd_len) { |
642 | duparg("broadcast", *argv); | 646 | duparg(option_broadcast, *argv); |
643 | } | 647 | } |
644 | if (LONE_CHAR(*argv, '+')) { | 648 | if (LONE_CHAR(*argv, '+')) { |
645 | brd_len = -1; | 649 | brd_len = -1; |
@@ -655,7 +659,7 @@ static int ipaddr_modify(int cmd, int flags, char **argv) | |||
655 | } else if (arg == 4) { /* anycast */ | 659 | } else if (arg == 4) { /* anycast */ |
656 | inet_prefix addr; | 660 | inet_prefix addr; |
657 | if (any_len) { | 661 | if (any_len) { |
658 | duparg("anycast", *argv); | 662 | duparg(option_anycast, *argv); |
659 | } | 663 | } |
660 | get_addr(&addr, *argv, req.ifa.ifa_family); | 664 | get_addr(&addr, *argv, req.ifa.ifa_family); |
661 | if (req.ifa.ifa_family == AF_UNSPEC) { | 665 | if (req.ifa.ifa_family == AF_UNSPEC) { |
diff --git a/networking/libiproute/iplink.c b/networking/libiproute/iplink.c index ae3ef0ceb..aef5f6490 100644 --- a/networking/libiproute/iplink.c +++ b/networking/libiproute/iplink.c | |||
@@ -52,6 +52,9 @@ struct ifla_vlan_flags { | |||
52 | # define dbg(...) ((void)0) | 52 | # define dbg(...) ((void)0) |
53 | #endif | 53 | #endif |
54 | 54 | ||
55 | |||
56 | #define str_on_off "on\0""off\0" | ||
57 | |||
55 | /* Exits on error */ | 58 | /* Exits on error */ |
56 | static int get_ctl_fd(void) | 59 | static int get_ctl_fd(void) |
57 | { | 60 | { |
@@ -204,12 +207,14 @@ static int do_set(char **argv) | |||
204 | struct ifreq ifr0, ifr1; | 207 | struct ifreq ifr0, ifr1; |
205 | char *newname = NULL; | 208 | char *newname = NULL; |
206 | int htype, halen; | 209 | int htype, halen; |
210 | /* If you add stuff here, update iplink_full_usage */ | ||
207 | static const char keywords[] ALIGN1 = | 211 | static const char keywords[] ALIGN1 = |
208 | "up\0""down\0""name\0""mtu\0""qlen\0""multicast\0" | 212 | "up\0""down\0""name\0""mtu\0""qlen\0""multicast\0" |
209 | "arp\0""address\0""dev\0"; | 213 | "arp\0""promisc\0""address\0" |
214 | "dev\0" /* must be last */; | ||
210 | enum { ARG_up = 0, ARG_down, ARG_name, ARG_mtu, ARG_qlen, ARG_multicast, | 215 | enum { ARG_up = 0, ARG_down, ARG_name, ARG_mtu, ARG_qlen, ARG_multicast, |
211 | ARG_arp, ARG_addr, ARG_dev }; | 216 | ARG_arp, ARG_promisc, ARG_addr, |
212 | static const char str_on_off[] ALIGN1 = "on\0""off\0"; | 217 | ARG_dev }; |
213 | enum { PARM_on = 0, PARM_off }; | 218 | enum { PARM_on = 0, PARM_off }; |
214 | smalluint key; | 219 | smalluint key; |
215 | 220 | ||
@@ -232,6 +237,7 @@ static int do_set(char **argv) | |||
232 | duparg("mtu", *argv); | 237 | duparg("mtu", *argv); |
233 | mtu = get_unsigned(*argv, "mtu"); | 238 | mtu = get_unsigned(*argv, "mtu"); |
234 | } else if (key == ARG_qlen) { | 239 | } else if (key == ARG_qlen) { |
240 | //TODO: txqueuelen, txqlen are synonyms to qlen | ||
235 | NEXT_ARG(); | 241 | NEXT_ARG(); |
236 | if (qlen != -1) | 242 | if (qlen != -1) |
237 | duparg("qlen", *argv); | 243 | duparg("qlen", *argv); |
@@ -240,6 +246,7 @@ static int do_set(char **argv) | |||
240 | NEXT_ARG(); | 246 | NEXT_ARG(); |
241 | newaddr = *argv; | 247 | newaddr = *argv; |
242 | } else if (key >= ARG_dev) { | 248 | } else if (key >= ARG_dev) { |
249 | /* ^^^^^^ ">=" here results in "dev IFACE" treated as default */ | ||
243 | if (key == ARG_dev) { | 250 | if (key == ARG_dev) { |
244 | NEXT_ARG(); | 251 | NEXT_ARG(); |
245 | } | 252 | } |
@@ -247,6 +254,7 @@ static int do_set(char **argv) | |||
247 | duparg2("dev", *argv); | 254 | duparg2("dev", *argv); |
248 | dev = *argv; | 255 | dev = *argv; |
249 | } else { | 256 | } else { |
257 | /* "on|off" options */ | ||
250 | int param; | 258 | int param; |
251 | NEXT_ARG(); | 259 | NEXT_ARG(); |
252 | param = index_in_strings(str_on_off, *argv); | 260 | param = index_in_strings(str_on_off, *argv); |
@@ -266,8 +274,132 @@ static int do_set(char **argv) | |||
266 | flags &= ~IFF_NOARP; | 274 | flags &= ~IFF_NOARP; |
267 | else | 275 | else |
268 | flags |= IFF_NOARP; | 276 | flags |= IFF_NOARP; |
277 | } else if (key == ARG_promisc) { | ||
278 | if (param < 0) | ||
279 | die_must_be_on_off("promisc"); | ||
280 | mask |= IFF_PROMISC; | ||
281 | if (param == PARM_on) | ||
282 | flags |= IFF_PROMISC; | ||
283 | else | ||
284 | flags &= ~IFF_PROMISC; | ||
269 | } | 285 | } |
270 | } | 286 | } |
287 | |||
288 | /* Other keywords recognized by iproute2-3.12.0: */ | ||
289 | #if 0 | ||
290 | } else if (matches(*argv, "broadcast") == 0 || | ||
291 | strcmp(*argv, "brd") == 0) { | ||
292 | NEXT_ARG(); | ||
293 | len = ll_addr_a2n(abuf, sizeof(abuf), *argv); | ||
294 | if (len < 0) | ||
295 | return -1; | ||
296 | addattr_l(&req->n, sizeof(*req), IFLA_BROADCAST, abuf, len); | ||
297 | } else if (strcmp(*argv, "netns") == 0) { | ||
298 | NEXT_ARG(); | ||
299 | if (netns != -1) | ||
300 | duparg("netns", *argv); | ||
301 | if ((netns = get_netns_fd(*argv)) >= 0) | ||
302 | addattr_l(&req->n, sizeof(*req), IFLA_NET_NS_FD, &netns, 4); | ||
303 | else if (get_integer(&netns, *argv, 0) == 0) | ||
304 | addattr_l(&req->n, sizeof(*req), IFLA_NET_NS_PID, &netns, 4); | ||
305 | else | ||
306 | invarg_1_to_2(*argv, "netns"); | ||
307 | } else if (strcmp(*argv, "allmulticast") == 0) { | ||
308 | NEXT_ARG(); | ||
309 | req->i.ifi_change |= IFF_ALLMULTI; | ||
310 | if (strcmp(*argv, "on") == 0) { | ||
311 | req->i.ifi_flags |= IFF_ALLMULTI; | ||
312 | } else if (strcmp(*argv, "off") == 0) { | ||
313 | req->i.ifi_flags &= ~IFF_ALLMULTI; | ||
314 | } else | ||
315 | return on_off("allmulticast", *argv); | ||
316 | } else if (strcmp(*argv, "trailers") == 0) { | ||
317 | NEXT_ARG(); | ||
318 | req->i.ifi_change |= IFF_NOTRAILERS; | ||
319 | if (strcmp(*argv, "off") == 0) { | ||
320 | req->i.ifi_flags |= IFF_NOTRAILERS; | ||
321 | } else if (strcmp(*argv, "on") == 0) { | ||
322 | req->i.ifi_flags &= ~IFF_NOTRAILERS; | ||
323 | } else | ||
324 | return on_off("trailers", *argv); | ||
325 | } else if (strcmp(*argv, "vf") == 0) { | ||
326 | struct rtattr *vflist; | ||
327 | NEXT_ARG(); | ||
328 | if (get_integer(&vf, *argv, 0)) { | ||
329 | invarg_1_to_2(*argv, "vf"); | ||
330 | } | ||
331 | vflist = addattr_nest(&req->n, sizeof(*req), | ||
332 | IFLA_VFINFO_LIST); | ||
333 | len = iplink_parse_vf(vf, &argc, &argv, req); | ||
334 | if (len < 0) | ||
335 | return -1; | ||
336 | addattr_nest_end(&req->n, vflist); | ||
337 | } else if (matches(*argv, "master") == 0) { | ||
338 | int ifindex; | ||
339 | NEXT_ARG(); | ||
340 | ifindex = ll_name_to_index(*argv); | ||
341 | if (!ifindex) | ||
342 | invarg_1_to_2(*argv, "master"); | ||
343 | addattr_l(&req->n, sizeof(*req), IFLA_MASTER, | ||
344 | &ifindex, 4); | ||
345 | } else if (matches(*argv, "nomaster") == 0) { | ||
346 | int ifindex = 0; | ||
347 | addattr_l(&req->n, sizeof(*req), IFLA_MASTER, | ||
348 | &ifindex, 4); | ||
349 | } else if (matches(*argv, "dynamic") == 0) { | ||
350 | NEXT_ARG(); | ||
351 | req->i.ifi_change |= IFF_DYNAMIC; | ||
352 | if (strcmp(*argv, "on") == 0) { | ||
353 | req->i.ifi_flags |= IFF_DYNAMIC; | ||
354 | } else if (strcmp(*argv, "off") == 0) { | ||
355 | req->i.ifi_flags &= ~IFF_DYNAMIC; | ||
356 | } else | ||
357 | return on_off("dynamic", *argv); | ||
358 | } else if (matches(*argv, "alias") == 0) { | ||
359 | NEXT_ARG(); | ||
360 | addattr_l(&req->n, sizeof(*req), IFLA_IFALIAS, | ||
361 | *argv, strlen(*argv)); | ||
362 | argc--; argv++; | ||
363 | break; | ||
364 | } else if (strcmp(*argv, "group") == 0) { | ||
365 | NEXT_ARG(); | ||
366 | if (*group != -1) | ||
367 | duparg("group", *argv); | ||
368 | if (rtnl_group_a2n(group, *argv)) | ||
369 | invarg_1_to_2(*argv, "group"); | ||
370 | } else if (strcmp(*argv, "mode") == 0) { | ||
371 | int mode; | ||
372 | NEXT_ARG(); | ||
373 | mode = get_link_mode(*argv); | ||
374 | if (mode < 0) | ||
375 | invarg_1_to_2(*argv, "mode"); | ||
376 | addattr8(&req->n, sizeof(*req), IFLA_LINKMODE, mode); | ||
377 | } else if (strcmp(*argv, "state") == 0) { | ||
378 | int state; | ||
379 | NEXT_ARG(); | ||
380 | state = get_operstate(*argv); | ||
381 | if (state < 0) | ||
382 | invarg_1_to_2(*argv, "state"); | ||
383 | addattr8(&req->n, sizeof(*req), IFLA_OPERSTATE, state); | ||
384 | } else if (matches(*argv, "numtxqueues") == 0) { | ||
385 | NEXT_ARG(); | ||
386 | if (numtxqueues != -1) | ||
387 | duparg("numtxqueues", *argv); | ||
388 | if (get_integer(&numtxqueues, *argv, 0)) | ||
389 | invarg_1_to_2(*argv, "numtxqueues"); | ||
390 | addattr_l(&req->n, sizeof(*req), IFLA_NUM_TX_QUEUES, | ||
391 | &numtxqueues, 4); | ||
392 | } else if (matches(*argv, "numrxqueues") == 0) { | ||
393 | NEXT_ARG(); | ||
394 | if (numrxqueues != -1) | ||
395 | duparg("numrxqueues", *argv); | ||
396 | if (get_integer(&numrxqueues, *argv, 0)) | ||
397 | invarg_1_to_2(*argv, "numrxqueues"); | ||
398 | addattr_l(&req->n, sizeof(*req), IFLA_NUM_RX_QUEUES, | ||
399 | &numrxqueues, 4); | ||
400 | } | ||
401 | #endif | ||
402 | |||
271 | argv++; | 403 | argv++; |
272 | } | 404 | } |
273 | 405 | ||
@@ -322,10 +454,6 @@ static void vlan_parse_opt(char **argv, struct nlmsghdr *n, unsigned int size) | |||
322 | "802.1q\0" | 454 | "802.1q\0" |
323 | "802.1ad\0" | 455 | "802.1ad\0" |
324 | ; | 456 | ; |
325 | static const char str_on_off[] ALIGN1 = | ||
326 | "on\0" | ||
327 | "off\0" | ||
328 | ; | ||
329 | enum { | 457 | enum { |
330 | ARG_id = 0, | 458 | ARG_id = 0, |
331 | ARG_reorder_hdr, | 459 | ARG_reorder_hdr, |
@@ -520,164 +648,6 @@ static int do_add_or_delete(char **argv, const unsigned rtm) | |||
520 | return 0; | 648 | return 0; |
521 | } | 649 | } |
522 | 650 | ||
523 | /* Other keywords recognized by iproute2-3.12.0: */ | ||
524 | #if 0 | ||
525 | } else if (matches(*argv, "broadcast") == 0 || | ||
526 | strcmp(*argv, "brd") == 0) { | ||
527 | NEXT_ARG(); | ||
528 | len = ll_addr_a2n(abuf, sizeof(abuf), *argv); | ||
529 | if (len < 0) | ||
530 | return -1; | ||
531 | addattr_l(&req->n, sizeof(*req), IFLA_BROADCAST, abuf, len); | ||
532 | } else if (matches(*argv, "txqueuelen") == 0 || | ||
533 | strcmp(*argv, "qlen") == 0 || | ||
534 | matches(*argv, "txqlen") == 0) { | ||
535 | NEXT_ARG(); | ||
536 | if (qlen != -1) | ||
537 | duparg("txqueuelen", *argv); | ||
538 | if (get_integer(&qlen, *argv, 0)) | ||
539 | invarg_1_to_2(*argv, "txqueuelen"); | ||
540 | addattr_l(&req->n, sizeof(*req), IFLA_TXQLEN, &qlen, 4); | ||
541 | } else if (strcmp(*argv, "mtu") == 0) { | ||
542 | NEXT_ARG(); | ||
543 | if (mtu != -1) | ||
544 | duparg("mtu", *argv); | ||
545 | if (get_integer(&mtu, *argv, 0)) | ||
546 | invarg_1_to_2(*argv, "mtu"); | ||
547 | addattr_l(&req->n, sizeof(*req), IFLA_MTU, &mtu, 4); | ||
548 | } else if (strcmp(*argv, "netns") == 0) { | ||
549 | NEXT_ARG(); | ||
550 | if (netns != -1) | ||
551 | duparg("netns", *argv); | ||
552 | if ((netns = get_netns_fd(*argv)) >= 0) | ||
553 | addattr_l(&req->n, sizeof(*req), IFLA_NET_NS_FD, &netns, 4); | ||
554 | else if (get_integer(&netns, *argv, 0) == 0) | ||
555 | addattr_l(&req->n, sizeof(*req), IFLA_NET_NS_PID, &netns, 4); | ||
556 | else | ||
557 | invarg_1_to_2(*argv, "netns"); | ||
558 | } else if (strcmp(*argv, "multicast") == 0) { | ||
559 | NEXT_ARG(); | ||
560 | req->i.ifi_change |= IFF_MULTICAST; | ||
561 | if (strcmp(*argv, "on") == 0) { | ||
562 | req->i.ifi_flags |= IFF_MULTICAST; | ||
563 | } else if (strcmp(*argv, "off") == 0) { | ||
564 | req->i.ifi_flags &= ~IFF_MULTICAST; | ||
565 | } else | ||
566 | return on_off("multicast", *argv); | ||
567 | } else if (strcmp(*argv, "allmulticast") == 0) { | ||
568 | NEXT_ARG(); | ||
569 | req->i.ifi_change |= IFF_ALLMULTI; | ||
570 | if (strcmp(*argv, "on") == 0) { | ||
571 | req->i.ifi_flags |= IFF_ALLMULTI; | ||
572 | } else if (strcmp(*argv, "off") == 0) { | ||
573 | req->i.ifi_flags &= ~IFF_ALLMULTI; | ||
574 | } else | ||
575 | return on_off("allmulticast", *argv); | ||
576 | } else if (strcmp(*argv, "promisc") == 0) { | ||
577 | NEXT_ARG(); | ||
578 | req->i.ifi_change |= IFF_PROMISC; | ||
579 | if (strcmp(*argv, "on") == 0) { | ||
580 | req->i.ifi_flags |= IFF_PROMISC; | ||
581 | } else if (strcmp(*argv, "off") == 0) { | ||
582 | req->i.ifi_flags &= ~IFF_PROMISC; | ||
583 | } else | ||
584 | return on_off("promisc", *argv); | ||
585 | } else if (strcmp(*argv, "trailers") == 0) { | ||
586 | NEXT_ARG(); | ||
587 | req->i.ifi_change |= IFF_NOTRAILERS; | ||
588 | if (strcmp(*argv, "off") == 0) { | ||
589 | req->i.ifi_flags |= IFF_NOTRAILERS; | ||
590 | } else if (strcmp(*argv, "on") == 0) { | ||
591 | req->i.ifi_flags &= ~IFF_NOTRAILERS; | ||
592 | } else | ||
593 | return on_off("trailers", *argv); | ||
594 | } else if (strcmp(*argv, "arp") == 0) { | ||
595 | NEXT_ARG(); | ||
596 | req->i.ifi_change |= IFF_NOARP; | ||
597 | if (strcmp(*argv, "on") == 0) { | ||
598 | req->i.ifi_flags &= ~IFF_NOARP; | ||
599 | } else if (strcmp(*argv, "off") == 0) { | ||
600 | req->i.ifi_flags |= IFF_NOARP; | ||
601 | } else | ||
602 | return on_off("noarp", *argv); | ||
603 | } else if (strcmp(*argv, "vf") == 0) { | ||
604 | struct rtattr *vflist; | ||
605 | NEXT_ARG(); | ||
606 | if (get_integer(&vf, *argv, 0)) { | ||
607 | invarg_1_to_2(*argv, "vf"); | ||
608 | } | ||
609 | vflist = addattr_nest(&req->n, sizeof(*req), | ||
610 | IFLA_VFINFO_LIST); | ||
611 | len = iplink_parse_vf(vf, &argc, &argv, req); | ||
612 | if (len < 0) | ||
613 | return -1; | ||
614 | addattr_nest_end(&req->n, vflist); | ||
615 | } else if (matches(*argv, "master") == 0) { | ||
616 | int ifindex; | ||
617 | NEXT_ARG(); | ||
618 | ifindex = ll_name_to_index(*argv); | ||
619 | if (!ifindex) | ||
620 | invarg_1_to_2(*argv, "master"); | ||
621 | addattr_l(&req->n, sizeof(*req), IFLA_MASTER, | ||
622 | &ifindex, 4); | ||
623 | } else if (matches(*argv, "nomaster") == 0) { | ||
624 | int ifindex = 0; | ||
625 | addattr_l(&req->n, sizeof(*req), IFLA_MASTER, | ||
626 | &ifindex, 4); | ||
627 | } else if (matches(*argv, "dynamic") == 0) { | ||
628 | NEXT_ARG(); | ||
629 | req->i.ifi_change |= IFF_DYNAMIC; | ||
630 | if (strcmp(*argv, "on") == 0) { | ||
631 | req->i.ifi_flags |= IFF_DYNAMIC; | ||
632 | } else if (strcmp(*argv, "off") == 0) { | ||
633 | req->i.ifi_flags &= ~IFF_DYNAMIC; | ||
634 | } else | ||
635 | return on_off("dynamic", *argv); | ||
636 | } else if (matches(*argv, "alias") == 0) { | ||
637 | NEXT_ARG(); | ||
638 | addattr_l(&req->n, sizeof(*req), IFLA_IFALIAS, | ||
639 | *argv, strlen(*argv)); | ||
640 | argc--; argv++; | ||
641 | break; | ||
642 | } else if (strcmp(*argv, "group") == 0) { | ||
643 | NEXT_ARG(); | ||
644 | if (*group != -1) | ||
645 | duparg("group", *argv); | ||
646 | if (rtnl_group_a2n(group, *argv)) | ||
647 | invarg_1_to_2(*argv, "group"); | ||
648 | } else if (strcmp(*argv, "mode") == 0) { | ||
649 | int mode; | ||
650 | NEXT_ARG(); | ||
651 | mode = get_link_mode(*argv); | ||
652 | if (mode < 0) | ||
653 | invarg_1_to_2(*argv, "mode"); | ||
654 | addattr8(&req->n, sizeof(*req), IFLA_LINKMODE, mode); | ||
655 | } else if (strcmp(*argv, "state") == 0) { | ||
656 | int state; | ||
657 | NEXT_ARG(); | ||
658 | state = get_operstate(*argv); | ||
659 | if (state < 0) | ||
660 | invarg_1_to_2(*argv, "state"); | ||
661 | addattr8(&req->n, sizeof(*req), IFLA_OPERSTATE, state); | ||
662 | } else if (matches(*argv, "numtxqueues") == 0) { | ||
663 | NEXT_ARG(); | ||
664 | if (numtxqueues != -1) | ||
665 | duparg("numtxqueues", *argv); | ||
666 | if (get_integer(&numtxqueues, *argv, 0)) | ||
667 | invarg_1_to_2(*argv, "numtxqueues"); | ||
668 | addattr_l(&req->n, sizeof(*req), IFLA_NUM_TX_QUEUES, | ||
669 | &numtxqueues, 4); | ||
670 | } else if (matches(*argv, "numrxqueues") == 0) { | ||
671 | NEXT_ARG(); | ||
672 | if (numrxqueues != -1) | ||
673 | duparg("numrxqueues", *argv); | ||
674 | if (get_integer(&numrxqueues, *argv, 0)) | ||
675 | invarg_1_to_2(*argv, "numrxqueues"); | ||
676 | addattr_l(&req->n, sizeof(*req), IFLA_NUM_RX_QUEUES, | ||
677 | &numrxqueues, 4); | ||
678 | } | ||
679 | #endif | ||
680 | |||
681 | /* Return value becomes exitcode. It's okay to not return at all */ | 651 | /* Return value becomes exitcode. It's okay to not return at all */ |
682 | int FAST_FUNC do_iplink(char **argv) | 652 | int FAST_FUNC do_iplink(char **argv) |
683 | { | 653 | { |
diff --git a/networking/libiproute/iproute.c b/networking/libiproute/iproute.c index 0f2b89682..cc3443a92 100644 --- a/networking/libiproute/iproute.c +++ b/networking/libiproute/iproute.c | |||
@@ -322,16 +322,31 @@ static int FAST_FUNC print_route(const struct sockaddr_nl *who UNUSED_PARAM, | |||
322 | return 0; | 322 | return 0; |
323 | } | 323 | } |
324 | 324 | ||
325 | static int str_is_lock(const char *str) | ||
326 | { | ||
327 | return strcmp(str, "lock") == 0; | ||
328 | } | ||
329 | |||
325 | /* Return value becomes exitcode. It's okay to not return at all */ | 330 | /* Return value becomes exitcode. It's okay to not return at all */ |
326 | static int iproute_modify(int cmd, unsigned flags, char **argv) | 331 | static int iproute_modify(int cmd, unsigned flags, char **argv) |
327 | { | 332 | { |
333 | /* If you add stuff here, update iproute_full_usage */ | ||
328 | static const char keywords[] ALIGN1 = | 334 | static const char keywords[] ALIGN1 = |
329 | "src\0""via\0""mtu\0""lock\0""scope\0""protocol\0"IF_FEATURE_IP_RULE("table\0") | 335 | "src\0""via\0" |
336 | "mtu\0""advmss\0" | ||
337 | "scope\0""protocol\0"IF_FEATURE_IP_RULE("table\0") | ||
330 | "dev\0""oif\0""to\0""metric\0""onlink\0"; | 338 | "dev\0""oif\0""to\0""metric\0""onlink\0"; |
339 | #define keyword_via (keywords + sizeof("src")) | ||
340 | #define keyword_mtu (keyword_via + sizeof("via")) | ||
341 | #define keyword_advmss (keyword_mtu + sizeof("mtu")) | ||
342 | #define keyword_scope (keyword_advmss + sizeof("advmss")) | ||
343 | #define keyword_proto (keyword_scope + sizeof("scope")) | ||
344 | #define keyword_table (keyword_proto + sizeof("protocol")) | ||
331 | enum { | 345 | enum { |
332 | ARG_src, | 346 | ARG_src, |
333 | ARG_via, | 347 | ARG_via, |
334 | ARG_mtu, PARM_lock, | 348 | ARG_mtu, |
349 | ARG_advmss, | ||
335 | ARG_scope, | 350 | ARG_scope, |
336 | ARG_protocol, | 351 | ARG_protocol, |
337 | IF_FEATURE_IP_RULE(ARG_table,) | 352 | IF_FEATURE_IP_RULE(ARG_table,) |
@@ -404,24 +419,33 @@ IF_FEATURE_IP_RULE(ARG_table,) | |||
404 | } else if (arg == ARG_mtu) { | 419 | } else if (arg == ARG_mtu) { |
405 | unsigned mtu; | 420 | unsigned mtu; |
406 | NEXT_ARG(); | 421 | NEXT_ARG(); |
407 | if (index_in_strings(keywords, *argv) == PARM_lock) { | 422 | if (str_is_lock(*argv)) { |
408 | mxlock |= (1 << RTAX_MTU); | 423 | mxlock |= (1 << RTAX_MTU); |
409 | NEXT_ARG(); | 424 | NEXT_ARG(); |
410 | } | 425 | } |
411 | mtu = get_unsigned(*argv, "mtu"); | 426 | mtu = get_unsigned(*argv, keyword_mtu); |
412 | rta_addattr32(mxrta, sizeof(mxbuf), RTAX_MTU, mtu); | 427 | rta_addattr32(mxrta, sizeof(mxbuf), RTAX_MTU, mtu); |
428 | } else if (arg == ARG_advmss) { | ||
429 | unsigned mss; | ||
430 | NEXT_ARG(); | ||
431 | if (str_is_lock(*argv)) { | ||
432 | mxlock |= (1 << RTAX_ADVMSS); | ||
433 | NEXT_ARG(); | ||
434 | } | ||
435 | mss = get_unsigned(*argv, keyword_advmss); | ||
436 | rta_addattr32(mxrta, sizeof(mxbuf), RTAX_ADVMSS, mss); | ||
413 | } else if (arg == ARG_scope) { | 437 | } else if (arg == ARG_scope) { |
414 | uint32_t scope; | 438 | uint32_t scope; |
415 | NEXT_ARG(); | 439 | NEXT_ARG(); |
416 | if (rtnl_rtscope_a2n(&scope, *argv)) | 440 | if (rtnl_rtscope_a2n(&scope, *argv)) |
417 | invarg_1_to_2(*argv, "scope"); | 441 | invarg_1_to_2(*argv, keyword_scope); |
418 | req.r.rtm_scope = scope; | 442 | req.r.rtm_scope = scope; |
419 | scope_ok = 1; | 443 | scope_ok = 1; |
420 | } else if (arg == ARG_protocol) { | 444 | } else if (arg == ARG_protocol) { |
421 | uint32_t prot; | 445 | uint32_t prot; |
422 | NEXT_ARG(); | 446 | NEXT_ARG(); |
423 | if (rtnl_rtprot_a2n(&prot, *argv)) | 447 | if (rtnl_rtprot_a2n(&prot, *argv)) |
424 | invarg_1_to_2(*argv, "protocol"); | 448 | invarg_1_to_2(*argv, keyword_proto); |
425 | req.r.rtm_protocol = prot; | 449 | req.r.rtm_protocol = prot; |
426 | ok |= proto_ok; | 450 | ok |= proto_ok; |
427 | #if ENABLE_FEATURE_IP_RULE | 451 | #if ENABLE_FEATURE_IP_RULE |
@@ -429,7 +453,7 @@ IF_FEATURE_IP_RULE(ARG_table,) | |||
429 | uint32_t tid; | 453 | uint32_t tid; |
430 | NEXT_ARG(); | 454 | NEXT_ARG(); |
431 | if (rtnl_rttable_a2n(&tid, *argv)) | 455 | if (rtnl_rttable_a2n(&tid, *argv)) |
432 | invarg_1_to_2(*argv, "table"); | 456 | invarg_1_to_2(*argv, keyword_table); |
433 | if (tid < 256) | 457 | if (tid < 256) |
434 | req.r.rtm_table = tid; | 458 | req.r.rtm_table = tid; |
435 | else { | 459 | else { |
@@ -441,6 +465,7 @@ IF_FEATURE_IP_RULE(ARG_table,) | |||
441 | NEXT_ARG(); | 465 | NEXT_ARG(); |
442 | d = *argv; | 466 | d = *argv; |
443 | } else if (arg == ARG_metric) { | 467 | } else if (arg == ARG_metric) { |
468 | //TODO: "metric", "priority" and "preference" are synonyms | ||
444 | uint32_t metric; | 469 | uint32_t metric; |
445 | NEXT_ARG(); | 470 | NEXT_ARG(); |
446 | metric = get_u32(*argv, "metric"); | 471 | metric = get_u32(*argv, "metric"); |
@@ -475,6 +500,158 @@ IF_FEATURE_IP_RULE(ARG_table,) | |||
475 | addattr_l(&req.n, sizeof(req), RTA_DST, &dst.data, dst.bytelen); | 500 | addattr_l(&req.n, sizeof(req), RTA_DST, &dst.data, dst.bytelen); |
476 | } | 501 | } |
477 | } | 502 | } |
503 | /* Other keywords recognized by iproute2-3.19.0: */ | ||
504 | #if 0 | ||
505 | } else if (strcmp(*argv, "from") == 0) { | ||
506 | inet_prefix addr; | ||
507 | NEXT_ARG(); | ||
508 | get_prefix(&addr, *argv, req.r.rtm_family); | ||
509 | if (req.r.rtm_family == AF_UNSPEC) | ||
510 | req.r.rtm_family = addr.family; | ||
511 | if (addr.bytelen) | ||
512 | addattr_l(&req.n, sizeof(req), RTA_SRC, &addr.data, addr.bytelen); | ||
513 | req.r.rtm_src_len = addr.bitlen; | ||
514 | } else if (strcmp(*argv, "tos") == 0 || | ||
515 | matches(*argv, "dsfield") == 0) { | ||
516 | __u32 tos; | ||
517 | NEXT_ARG(); | ||
518 | if (rtnl_dsfield_a2n(&tos, *argv)) | ||
519 | invarg("\"tos\" value is invalid\n", *argv); | ||
520 | req.r.rtm_tos = tos; | ||
521 | } else if (strcmp(*argv, "hoplimit") == 0) { | ||
522 | unsigned hoplimit; | ||
523 | NEXT_ARG(); | ||
524 | if (strcmp(*argv, "lock") == 0) { | ||
525 | mxlock |= (1<<RTAX_HOPLIMIT); | ||
526 | NEXT_ARG(); | ||
527 | } | ||
528 | if (get_unsigned(&hoplimit, *argv, 0)) | ||
529 | invarg("\"hoplimit\" value is invalid\n", *argv); | ||
530 | rta_addattr32(mxrta, sizeof(mxbuf), RTAX_HOPLIMIT, hoplimit); | ||
531 | } else if (matches(*argv, "reordering") == 0) { | ||
532 | unsigned reord; | ||
533 | NEXT_ARG(); | ||
534 | if (strcmp(*argv, "lock") == 0) { | ||
535 | mxlock |= (1<<RTAX_REORDERING); | ||
536 | NEXT_ARG(); | ||
537 | } | ||
538 | if (get_unsigned(&reord, *argv, 0)) | ||
539 | invarg("\"reordering\" value is invalid\n", *argv); | ||
540 | rta_addattr32(mxrta, sizeof(mxbuf), RTAX_REORDERING, reord); | ||
541 | } else if (strcmp(*argv, "rtt") == 0) { | ||
542 | unsigned rtt; | ||
543 | NEXT_ARG(); | ||
544 | if (strcmp(*argv, "lock") == 0) { | ||
545 | mxlock |= (1<<RTAX_RTT); | ||
546 | NEXT_ARG(); | ||
547 | } | ||
548 | if (get_time_rtt(&rtt, *argv, &raw)) | ||
549 | invarg("\"rtt\" value is invalid\n", *argv); | ||
550 | rta_addattr32(mxrta, sizeof(mxbuf), RTAX_RTT, | ||
551 | (raw) ? rtt : rtt * 8); | ||
552 | } else if (strcmp(*argv, "rto_min") == 0) { | ||
553 | unsigned rto_min; | ||
554 | NEXT_ARG(); | ||
555 | mxlock |= (1<<RTAX_RTO_MIN); | ||
556 | if (get_time_rtt(&rto_min, *argv, &raw)) | ||
557 | invarg("\"rto_min\" value is invalid\n", | ||
558 | *argv); | ||
559 | rta_addattr32(mxrta, sizeof(mxbuf), RTAX_RTO_MIN, | ||
560 | rto_min); | ||
561 | } else if (matches(*argv, "window") == 0) { | ||
562 | unsigned win; | ||
563 | NEXT_ARG(); | ||
564 | if (strcmp(*argv, "lock") == 0) { | ||
565 | mxlock |= (1<<RTAX_WINDOW); | ||
566 | NEXT_ARG(); | ||
567 | } | ||
568 | if (get_unsigned(&win, *argv, 0)) | ||
569 | invarg("\"window\" value is invalid\n", *argv); | ||
570 | rta_addattr32(mxrta, sizeof(mxbuf), RTAX_WINDOW, win); | ||
571 | } else if (matches(*argv, "cwnd") == 0) { | ||
572 | unsigned win; | ||
573 | NEXT_ARG(); | ||
574 | if (strcmp(*argv, "lock") == 0) { | ||
575 | mxlock |= (1<<RTAX_CWND); | ||
576 | NEXT_ARG(); | ||
577 | } | ||
578 | if (get_unsigned(&win, *argv, 0)) | ||
579 | invarg("\"cwnd\" value is invalid\n", *argv); | ||
580 | rta_addattr32(mxrta, sizeof(mxbuf), RTAX_CWND, win); | ||
581 | } else if (matches(*argv, "initcwnd") == 0) { | ||
582 | unsigned win; | ||
583 | NEXT_ARG(); | ||
584 | if (strcmp(*argv, "lock") == 0) { | ||
585 | mxlock |= (1<<RTAX_INITCWND); | ||
586 | NEXT_ARG(); | ||
587 | } | ||
588 | if (get_unsigned(&win, *argv, 0)) | ||
589 | invarg("\"initcwnd\" value is invalid\n", *argv); | ||
590 | rta_addattr32(mxrta, sizeof(mxbuf), RTAX_INITCWND, win); | ||
591 | } else if (matches(*argv, "initrwnd") == 0) { | ||
592 | unsigned win; | ||
593 | NEXT_ARG(); | ||
594 | if (strcmp(*argv, "lock") == 0) { | ||
595 | mxlock |= (1<<RTAX_INITRWND); | ||
596 | NEXT_ARG(); | ||
597 | } | ||
598 | if (get_unsigned(&win, *argv, 0)) | ||
599 | invarg("\"initrwnd\" value is invalid\n", *argv); | ||
600 | rta_addattr32(mxrta, sizeof(mxbuf), RTAX_INITRWND, win); | ||
601 | } else if (matches(*argv, "features") == 0) { | ||
602 | unsigned int features = 0; | ||
603 | |||
604 | while (argc > 0) { | ||
605 | NEXT_ARG(); | ||
606 | |||
607 | if (strcmp(*argv, "ecn") == 0) | ||
608 | features |= RTAX_FEATURE_ECN; | ||
609 | else | ||
610 | invarg("\"features\" value not valid\n", *argv); | ||
611 | break; | ||
612 | } | ||
613 | |||
614 | rta_addattr32(mxrta, sizeof(mxbuf), RTAX_FEATURES, features); | ||
615 | } else if (matches(*argv, "quickack") == 0) { | ||
616 | unsigned quickack; | ||
617 | NEXT_ARG(); | ||
618 | if (get_unsigned(&quickack, *argv, 0)) | ||
619 | invarg("\"quickack\" value is invalid\n", *argv); | ||
620 | if (quickack != 1 && quickack != 0) | ||
621 | invarg("\"quickack\" value should be 0 or 1\n", *argv); | ||
622 | rta_addattr32(mxrta, sizeof(mxbuf), RTAX_QUICKACK, quickack); | ||
623 | } else if (matches(*argv, "rttvar") == 0) { | ||
624 | unsigned win; | ||
625 | NEXT_ARG(); | ||
626 | if (strcmp(*argv, "lock") == 0) { | ||
627 | mxlock |= (1<<RTAX_RTTVAR); | ||
628 | NEXT_ARG(); | ||
629 | } | ||
630 | if (get_time_rtt(&win, *argv, &raw)) | ||
631 | invarg("\"rttvar\" value is invalid\n", *argv); | ||
632 | rta_addattr32(mxrta, sizeof(mxbuf), RTAX_RTTVAR, | ||
633 | (raw) ? win : win * 4); | ||
634 | } else if (matches(*argv, "ssthresh") == 0) { | ||
635 | unsigned win; | ||
636 | NEXT_ARG(); | ||
637 | if (strcmp(*argv, "lock") == 0) { | ||
638 | mxlock |= (1<<RTAX_SSTHRESH); | ||
639 | NEXT_ARG(); | ||
640 | } | ||
641 | if (get_unsigned(&win, *argv, 0)) | ||
642 | invarg("\"ssthresh\" value is invalid\n", *argv); | ||
643 | rta_addattr32(mxrta, sizeof(mxbuf), RTAX_SSTHRESH, win); | ||
644 | } else if (matches(*argv, "realms") == 0) { | ||
645 | __u32 realm; | ||
646 | NEXT_ARG(); | ||
647 | if (get_rt_realms(&realm, *argv)) | ||
648 | invarg("\"realm\" value is invalid\n", *argv); | ||
649 | addattr32(&req.n, sizeof(req), RTA_FLOW, realm); | ||
650 | } else if (strcmp(*argv, "nexthop") == 0) { | ||
651 | nhs_ok = 1; | ||
652 | break; | ||
653 | } | ||
654 | #endif | ||
478 | argv++; | 655 | argv++; |
479 | } | 656 | } |
480 | 657 | ||
@@ -912,9 +1089,15 @@ static int iproute_get(char **argv) | |||
912 | int FAST_FUNC do_iproute(char **argv) | 1089 | int FAST_FUNC do_iproute(char **argv) |
913 | { | 1090 | { |
914 | static const char ip_route_commands[] ALIGN1 = | 1091 | static const char ip_route_commands[] ALIGN1 = |
915 | /*0-3*/ "add\0""append\0""change\0""chg\0" | 1092 | "a\0""add\0""append\0""change\0""chg\0" |
916 | /*4-7*/ "delete\0""get\0""list\0""show\0" | 1093 | "delete\0""get\0""list\0""show\0" |
917 | /*8..*/ "prepend\0""replace\0""test\0""flush\0"; | 1094 | "prepend\0""replace\0""test\0""flush\0" |
1095 | ; | ||
1096 | enum { | ||
1097 | CMD_a = 0, CMD_add, CMD_append, CMD_change, CMD_chg, | ||
1098 | CMD_delete, CMD_get, CMD_list, CMD_show, | ||
1099 | CMD_prepend, CMD_replace, CMD_test, CMD_flush, | ||
1100 | }; | ||
918 | int command_num; | 1101 | int command_num; |
919 | unsigned flags = 0; | 1102 | unsigned flags = 0; |
920 | int cmd = RTM_NEWROUTE; | 1103 | int cmd = RTM_NEWROUTE; |
@@ -929,38 +1112,39 @@ int FAST_FUNC do_iproute(char **argv) | |||
929 | command_num = index_in_substrings(ip_route_commands, *argv); | 1112 | command_num = index_in_substrings(ip_route_commands, *argv); |
930 | 1113 | ||
931 | switch (command_num) { | 1114 | switch (command_num) { |
932 | case 0: /* add */ | 1115 | case CMD_a: |
1116 | case CMD_add: | ||
933 | flags = NLM_F_CREATE|NLM_F_EXCL; | 1117 | flags = NLM_F_CREATE|NLM_F_EXCL; |
934 | break; | 1118 | break; |
935 | case 1: /* append */ | 1119 | case CMD_append: |
936 | flags = NLM_F_CREATE|NLM_F_APPEND; | 1120 | flags = NLM_F_CREATE|NLM_F_APPEND; |
937 | break; | 1121 | break; |
938 | case 2: /* change */ | 1122 | case CMD_change: |
939 | case 3: /* chg */ | 1123 | case CMD_chg: |
940 | flags = NLM_F_REPLACE; | 1124 | flags = NLM_F_REPLACE; |
941 | break; | 1125 | break; |
942 | case 4: /* delete */ | 1126 | case CMD_delete: |
943 | cmd = RTM_DELROUTE; | 1127 | cmd = RTM_DELROUTE; |
944 | break; | 1128 | break; |
945 | case 5: /* get */ | 1129 | case CMD_get: |
946 | return iproute_get(argv+1); | 1130 | return iproute_get(argv + 1); |
947 | case 6: /* list */ | 1131 | case CMD_list: |
948 | case 7: /* show */ | 1132 | case CMD_show: |
949 | return iproute_list_or_flush(argv+1, 0); | 1133 | return iproute_list_or_flush(argv + 1, 0); |
950 | case 8: /* prepend */ | 1134 | case CMD_prepend: |
951 | flags = NLM_F_CREATE; | 1135 | flags = NLM_F_CREATE; |
952 | break; | 1136 | break; |
953 | case 9: /* replace */ | 1137 | case CMD_replace: |
954 | flags = NLM_F_CREATE|NLM_F_REPLACE; | 1138 | flags = NLM_F_CREATE|NLM_F_REPLACE; |
955 | break; | 1139 | break; |
956 | case 10: /* test */ | 1140 | case CMD_test: |
957 | flags = NLM_F_EXCL; | 1141 | flags = NLM_F_EXCL; |
958 | break; | 1142 | break; |
959 | case 11: /* flush */ | 1143 | case CMD_flush: |
960 | return iproute_list_or_flush(argv+1, 1); | 1144 | return iproute_list_or_flush(argv + 1, 1); |
961 | default: | 1145 | default: |
962 | invarg_1_to_2(*argv, applet_name); | 1146 | invarg_1_to_2(*argv, applet_name); |
963 | } | 1147 | } |
964 | 1148 | ||
965 | return iproute_modify(cmd, flags, argv+1); | 1149 | return iproute_modify(cmd, flags, argv + 1); |
966 | } | 1150 | } |
diff --git a/networking/libiproute/utils.c b/networking/libiproute/utils.c index 42025bc66..fca167ac6 100644 --- a/networking/libiproute/utils.c +++ b/networking/libiproute/utils.c | |||
@@ -13,7 +13,7 @@ | |||
13 | #include "utils.h" | 13 | #include "utils.h" |
14 | #include "inet_common.h" | 14 | #include "inet_common.h" |
15 | 15 | ||
16 | unsigned get_hz(void) | 16 | unsigned FAST_FUNC get_hz(void) |
17 | { | 17 | { |
18 | static unsigned hz_internal; | 18 | static unsigned hz_internal; |
19 | FILE *fp; | 19 | FILE *fp; |
@@ -35,7 +35,7 @@ unsigned get_hz(void) | |||
35 | return hz_internal; | 35 | return hz_internal; |
36 | } | 36 | } |
37 | 37 | ||
38 | unsigned get_unsigned(char *arg, const char *errmsg) | 38 | unsigned FAST_FUNC get_unsigned(char *arg, const char *errmsg) |
39 | { | 39 | { |
40 | unsigned long res; | 40 | unsigned long res; |
41 | char *ptr; | 41 | char *ptr; |
@@ -50,7 +50,7 @@ unsigned get_unsigned(char *arg, const char *errmsg) | |||
50 | invarg_1_to_2(arg, errmsg); /* does not return */ | 50 | invarg_1_to_2(arg, errmsg); /* does not return */ |
51 | } | 51 | } |
52 | 52 | ||
53 | uint32_t get_u32(char *arg, const char *errmsg) | 53 | uint32_t FAST_FUNC get_u32(char *arg, const char *errmsg) |
54 | { | 54 | { |
55 | unsigned long res; | 55 | unsigned long res; |
56 | char *ptr; | 56 | char *ptr; |
@@ -65,7 +65,7 @@ uint32_t get_u32(char *arg, const char *errmsg) | |||
65 | invarg_1_to_2(arg, errmsg); /* does not return */ | 65 | invarg_1_to_2(arg, errmsg); /* does not return */ |
66 | } | 66 | } |
67 | 67 | ||
68 | uint16_t get_u16(char *arg, const char *errmsg) | 68 | uint16_t FAST_FUNC get_u16(char *arg, const char *errmsg) |
69 | { | 69 | { |
70 | unsigned long res; | 70 | unsigned long res; |
71 | char *ptr; | 71 | char *ptr; |
@@ -80,7 +80,7 @@ uint16_t get_u16(char *arg, const char *errmsg) | |||
80 | invarg_1_to_2(arg, errmsg); /* does not return */ | 80 | invarg_1_to_2(arg, errmsg); /* does not return */ |
81 | } | 81 | } |
82 | 82 | ||
83 | int get_addr_1(inet_prefix *addr, char *name, int family) | 83 | int FAST_FUNC get_addr_1(inet_prefix *addr, char *name, int family) |
84 | { | 84 | { |
85 | memset(addr, 0, sizeof(*addr)); | 85 | memset(addr, 0, sizeof(*addr)); |
86 | 86 | ||
@@ -199,7 +199,7 @@ static void get_prefix_1(inet_prefix *dst, char *arg, int family) | |||
199 | bb_error_msg_and_die("an %s %s is expected rather than \"%s\"", "inet", "prefix", arg); | 199 | bb_error_msg_and_die("an %s %s is expected rather than \"%s\"", "inet", "prefix", arg); |
200 | } | 200 | } |
201 | 201 | ||
202 | int get_addr(inet_prefix *dst, char *arg, int family) | 202 | int FAST_FUNC get_addr(inet_prefix *dst, char *arg, int family) |
203 | { | 203 | { |
204 | if (family == AF_PACKET) { | 204 | if (family == AF_PACKET) { |
205 | bb_error_msg_and_die("\"%s\" may be inet %s, but it is not allowed in this context", arg, "address"); | 205 | bb_error_msg_and_die("\"%s\" may be inet %s, but it is not allowed in this context", arg, "address"); |
@@ -210,7 +210,7 @@ int get_addr(inet_prefix *dst, char *arg, int family) | |||
210 | return 0; | 210 | return 0; |
211 | } | 211 | } |
212 | 212 | ||
213 | void get_prefix(inet_prefix *dst, char *arg, int family) | 213 | void FAST_FUNC get_prefix(inet_prefix *dst, char *arg, int family) |
214 | { | 214 | { |
215 | if (family == AF_PACKET) { | 215 | if (family == AF_PACKET) { |
216 | bb_error_msg_and_die("\"%s\" may be inet %s, but it is not allowed in this context", arg, "prefix"); | 216 | bb_error_msg_and_die("\"%s\" may be inet %s, but it is not allowed in this context", arg, "prefix"); |
@@ -218,7 +218,7 @@ void get_prefix(inet_prefix *dst, char *arg, int family) | |||
218 | get_prefix_1(dst, arg, family); | 218 | get_prefix_1(dst, arg, family); |
219 | } | 219 | } |
220 | 220 | ||
221 | uint32_t get_addr32(char *name) | 221 | uint32_t FAST_FUNC get_addr32(char *name) |
222 | { | 222 | { |
223 | inet_prefix addr; | 223 | inet_prefix addr; |
224 | 224 | ||
@@ -228,27 +228,29 @@ uint32_t get_addr32(char *name) | |||
228 | return addr.data[0]; | 228 | return addr.data[0]; |
229 | } | 229 | } |
230 | 230 | ||
231 | void incomplete_command(void) | 231 | char** FAST_FUNC next_arg(char **argv) |
232 | { | 232 | { |
233 | bb_error_msg_and_die("command line is not complete, try \"help\""); | 233 | if (!*++argv) |
234 | bb_error_msg_and_die("command line is not complete, try \"help\""); | ||
235 | return argv; | ||
234 | } | 236 | } |
235 | 237 | ||
236 | void invarg_1_to_2(const char *arg, const char *opt) | 238 | void FAST_FUNC invarg_1_to_2(const char *arg, const char *opt) |
237 | { | 239 | { |
238 | bb_error_msg_and_die(bb_msg_invalid_arg_to, arg, opt); | 240 | bb_error_msg_and_die(bb_msg_invalid_arg_to, arg, opt); |
239 | } | 241 | } |
240 | 242 | ||
241 | void duparg(const char *key, const char *arg) | 243 | void FAST_FUNC duparg(const char *key, const char *arg) |
242 | { | 244 | { |
243 | bb_error_msg_and_die("duplicate \"%s\": \"%s\" is the second value", key, arg); | 245 | bb_error_msg_and_die("duplicate \"%s\": \"%s\" is the second value", key, arg); |
244 | } | 246 | } |
245 | 247 | ||
246 | void duparg2(const char *key, const char *arg) | 248 | void FAST_FUNC duparg2(const char *key, const char *arg) |
247 | { | 249 | { |
248 | bb_error_msg_and_die("either \"%s\" is duplicate, or \"%s\" is garbage", key, arg); | 250 | bb_error_msg_and_die("either \"%s\" is duplicate, or \"%s\" is garbage", key, arg); |
249 | } | 251 | } |
250 | 252 | ||
251 | int inet_addr_match(const inet_prefix *a, const inet_prefix *b, int bits) | 253 | int FAST_FUNC inet_addr_match(const inet_prefix *a, const inet_prefix *b, int bits) |
252 | { | 254 | { |
253 | const uint32_t *a1 = a->data; | 255 | const uint32_t *a1 = a->data; |
254 | const uint32_t *a2 = b->data; | 256 | const uint32_t *a2 = b->data; |
@@ -276,7 +278,7 @@ int inet_addr_match(const inet_prefix *a, const inet_prefix *b, int bits) | |||
276 | return 0; | 278 | return 0; |
277 | } | 279 | } |
278 | 280 | ||
279 | const char *rt_addr_n2a(int af, void *addr) | 281 | const char* FAST_FUNC rt_addr_n2a(int af, void *addr) |
280 | { | 282 | { |
281 | switch (af) { | 283 | switch (af) { |
282 | case AF_INET: | 284 | case AF_INET: |
@@ -290,7 +292,7 @@ const char *rt_addr_n2a(int af, void *addr) | |||
290 | } | 292 | } |
291 | 293 | ||
292 | #ifdef RESOLVE_HOSTNAMES | 294 | #ifdef RESOLVE_HOSTNAMES |
293 | const char *format_host(int af, int len, void *addr) | 295 | const char* FAST_FUNC format_host(int af, int len, void *addr) |
294 | { | 296 | { |
295 | if (resolve_hosts) { | 297 | if (resolve_hosts) { |
296 | struct hostent *h_ent; | 298 | struct hostent *h_ent; |
diff --git a/networking/libiproute/utils.h b/networking/libiproute/utils.h index 408d5f65f..55490980d 100644 --- a/networking/libiproute/utils.h +++ b/networking/libiproute/utils.h | |||
@@ -26,10 +26,6 @@ extern char _SL_; | |||
26 | #define SPRINT_BSIZE 64 | 26 | #define SPRINT_BSIZE 64 |
27 | #define SPRINT_BUF(x) char x[SPRINT_BSIZE] | 27 | #define SPRINT_BUF(x) char x[SPRINT_BSIZE] |
28 | 28 | ||
29 | extern void incomplete_command(void) NORETURN; | ||
30 | |||
31 | #define NEXT_ARG() do { if (!*++argv) incomplete_command(); } while (0) | ||
32 | |||
33 | typedef struct { | 29 | typedef struct { |
34 | uint8_t family; | 30 | uint8_t family; |
35 | uint8_t bytelen; | 31 | uint8_t bytelen; |
@@ -56,36 +52,40 @@ struct ipx_addr { | |||
56 | uint8_t ipx_node[IPX_NODE_LEN]; | 52 | uint8_t ipx_node[IPX_NODE_LEN]; |
57 | }; | 53 | }; |
58 | 54 | ||
59 | extern uint32_t get_addr32(char *name); | 55 | char** next_arg(char **argv) FAST_FUNC; |
60 | extern int get_addr_1(inet_prefix *dst, char *arg, int family); | 56 | #define NEXT_ARG() do { argv = next_arg(argv); } while (0) |
61 | /*extern void get_prefix_1(inet_prefix *dst, char *arg, int family);*/ | ||
62 | extern int get_addr(inet_prefix *dst, char *arg, int family); | ||
63 | extern void get_prefix(inet_prefix *dst, char *arg, int family); | ||
64 | 57 | ||
65 | extern unsigned get_unsigned(char *arg, const char *errmsg); | 58 | uint32_t get_addr32(char *name) FAST_FUNC; |
66 | extern uint32_t get_u32(char *arg, const char *errmsg); | 59 | int get_addr_1(inet_prefix *dst, char *arg, int family) FAST_FUNC; |
67 | extern uint16_t get_u16(char *arg, const char *errmsg); | 60 | /*void get_prefix_1(inet_prefix *dst, char *arg, int family) FAST_FUNC;*/ |
61 | int get_addr(inet_prefix *dst, char *arg, int family) FAST_FUNC; | ||
62 | void get_prefix(inet_prefix *dst, char *arg, int family) FAST_FUNC; | ||
68 | 63 | ||
69 | extern const char *rt_addr_n2a(int af, void *addr); | 64 | unsigned get_unsigned(char *arg, const char *errmsg) FAST_FUNC; |
65 | uint32_t get_u32(char *arg, const char *errmsg) FAST_FUNC; | ||
66 | uint16_t get_u16(char *arg, const char *errmsg) FAST_FUNC; | ||
67 | |||
68 | const char *rt_addr_n2a(int af, void *addr) FAST_FUNC; | ||
70 | #ifdef RESOLVE_HOSTNAMES | 69 | #ifdef RESOLVE_HOSTNAMES |
71 | extern const char *format_host(int af, int len, void *addr); | 70 | const char *format_host(int af, int len, void *addr) FAST_FUNC; |
72 | #else | 71 | #else |
73 | #define format_host(af, len, addr) \ | 72 | #define format_host(af, len, addr) \ |
74 | rt_addr_n2a(af, addr) | 73 | rt_addr_n2a(af, addr) |
75 | #endif | 74 | #endif |
76 | 75 | ||
77 | void invarg_1_to_2(const char *, const char *) NORETURN; | 76 | void invarg_1_to_2(const char *, const char *) FAST_FUNC NORETURN; |
78 | void duparg(const char *, const char *) NORETURN; | 77 | void duparg(const char *, const char *) FAST_FUNC NORETURN; |
79 | void duparg2(const char *, const char *) NORETURN; | 78 | void duparg2(const char *, const char *) FAST_FUNC NORETURN; |
80 | int inet_addr_match(const inet_prefix *a, const inet_prefix *b, int bits); | 79 | |
80 | int inet_addr_match(const inet_prefix *a, const inet_prefix *b, int bits) FAST_FUNC; | ||
81 | 81 | ||
82 | const char *dnet_ntop(int af, const void *addr, char *str, size_t len); | 82 | //const char *dnet_ntop(int af, const void *addr, char *str, size_t len); |
83 | int dnet_pton(int af, const char *src, void *addr); | 83 | //int dnet_pton(int af, const char *src, void *addr); |
84 | 84 | ||
85 | const char *ipx_ntop(int af, const void *addr, char *str, size_t len); | 85 | //const char *ipx_ntop(int af, const void *addr, char *str, size_t len); |
86 | int ipx_pton(int af, const char *src, void *addr); | 86 | //int ipx_pton(int af, const char *src, void *addr); |
87 | 87 | ||
88 | unsigned get_hz(void); | 88 | unsigned get_hz(void) FAST_FUNC; |
89 | 89 | ||
90 | POP_SAVED_FUNCTION_VISIBILITY | 90 | POP_SAVED_FUNCTION_VISIBILITY |
91 | 91 | ||
diff --git a/networking/nc.c b/networking/nc.c index 1b70434ac..d2b1ddcce 100644 --- a/networking/nc.c +++ b/networking/nc.c | |||
@@ -117,7 +117,7 @@ int nc_main(int argc, char **argv) | |||
117 | IF_NOT_NC_EXTRA (const) unsigned delay = 0; | 117 | IF_NOT_NC_EXTRA (const) unsigned delay = 0; |
118 | IF_NOT_NC_EXTRA (const int execparam = 0;) | 118 | IF_NOT_NC_EXTRA (const int execparam = 0;) |
119 | IF_NC_EXTRA (char **execparam = NULL;) | 119 | IF_NC_EXTRA (char **execparam = NULL;) |
120 | fd_set readfds, testfds; | 120 | struct pollfd pfds[2]; |
121 | int opt; /* must be signed (getopt returns -1) */ | 121 | int opt; /* must be signed (getopt returns -1) */ |
122 | 122 | ||
123 | if (ENABLE_NC_SERVER || ENABLE_NC_EXTRA) { | 123 | if (ENABLE_NC_SERVER || ENABLE_NC_EXTRA) { |
@@ -235,29 +235,28 @@ int nc_main(int argc, char **argv) | |||
235 | IF_NC_EXTRA(bb_perror_msg_and_die("can't execute '%s'", execparam[0]);) | 235 | IF_NC_EXTRA(bb_perror_msg_and_die("can't execute '%s'", execparam[0]);) |
236 | } | 236 | } |
237 | 237 | ||
238 | /* Select loop copying stdin to cfd, and cfd to stdout */ | 238 | /* loop copying stdin to cfd, and cfd to stdout */ |
239 | 239 | ||
240 | FD_ZERO(&readfds); | 240 | pfds[0].fd = STDIN_FILENO; |
241 | FD_SET(cfd, &readfds); | 241 | pfds[0].events = POLLIN; |
242 | FD_SET(STDIN_FILENO, &readfds); | 242 | pfds[1].fd = cfd; |
243 | pfds[1].events = POLLIN; | ||
243 | 244 | ||
244 | #define iobuf bb_common_bufsiz1 | 245 | #define iobuf bb_common_bufsiz1 |
245 | setup_common_bufsiz(); | 246 | setup_common_bufsiz(); |
246 | for (;;) { | 247 | for (;;) { |
247 | int fd; | 248 | int fdidx; |
248 | int ofd; | 249 | int ofd; |
249 | int nread; | 250 | int nread; |
250 | 251 | ||
251 | testfds = readfds; | 252 | if (safe_poll(pfds, 2, -1) < 0) |
253 | bb_perror_msg_and_die("poll"); | ||
252 | 254 | ||
253 | if (select(cfd + 1, &testfds, NULL, NULL, NULL) < 0) | 255 | fdidx = 0; |
254 | bb_perror_msg_and_die("select"); | ||
255 | |||
256 | fd = STDIN_FILENO; | ||
257 | while (1) { | 256 | while (1) { |
258 | if (FD_ISSET(fd, &testfds)) { | 257 | if (pfds[fdidx].revents) { |
259 | nread = safe_read(fd, iobuf, COMMON_BUFSIZE); | 258 | nread = safe_read(pfds[fdidx].fd, iobuf, COMMON_BUFSIZE); |
260 | if (fd == cfd) { | 259 | if (fdidx != 0) { |
261 | if (nread < 1) | 260 | if (nread < 1) |
262 | exit(EXIT_SUCCESS); | 261 | exit(EXIT_SUCCESS); |
263 | ofd = STDOUT_FILENO; | 262 | ofd = STDOUT_FILENO; |
@@ -266,7 +265,7 @@ int nc_main(int argc, char **argv) | |||
266 | /* Close outgoing half-connection so they get EOF, | 265 | /* Close outgoing half-connection so they get EOF, |
267 | * but leave incoming alone so we can see response */ | 266 | * but leave incoming alone so we can see response */ |
268 | shutdown(cfd, SHUT_WR); | 267 | shutdown(cfd, SHUT_WR); |
269 | FD_CLR(STDIN_FILENO, &readfds); | 268 | pfds[0].fd = -1; |
270 | } | 269 | } |
271 | ofd = cfd; | 270 | ofd = cfd; |
272 | } | 271 | } |
@@ -274,9 +273,9 @@ int nc_main(int argc, char **argv) | |||
274 | if (delay > 0) | 273 | if (delay > 0) |
275 | sleep(delay); | 274 | sleep(delay); |
276 | } | 275 | } |
277 | if (fd == cfd) | 276 | if (fdidx == 1) |
278 | break; | 277 | break; |
279 | fd = cfd; | 278 | fdidx++; |
280 | } | 279 | } |
281 | } | 280 | } |
282 | } | 281 | } |
diff --git a/networking/nc_bloaty.c b/networking/nc_bloaty.c index 192e42fe5..3db784982 100644 --- a/networking/nc_bloaty.c +++ b/networking/nc_bloaty.c | |||
@@ -459,7 +459,7 @@ create new one, and bind() it. TODO */ | |||
459 | so I don't feel bad. | 459 | so I don't feel bad. |
460 | The *real* question is why BFD sockets wasn't designed to allow listens for | 460 | The *real* question is why BFD sockets wasn't designed to allow listens for |
461 | connections *from* specific hosts/ports, instead of requiring the caller to | 461 | connections *from* specific hosts/ports, instead of requiring the caller to |
462 | accept the connection and then reject undesireable ones by closing. | 462 | accept the connection and then reject undesirable ones by closing. |
463 | In other words, we need a TCP MSG_PEEK. */ | 463 | In other words, we need a TCP MSG_PEEK. */ |
464 | /* bbox: removed most of it */ | 464 | /* bbox: removed most of it */ |
465 | lcladdr = xmalloc_sockaddr2dotted(&ouraddr->u.sa); | 465 | lcladdr = xmalloc_sockaddr2dotted(&ouraddr->u.sa); |
@@ -502,7 +502,7 @@ static int udptest(void) | |||
502 | /* use the tcp-ping trick: try connecting to a normally refused port, which | 502 | /* use the tcp-ping trick: try connecting to a normally refused port, which |
503 | causes us to block for the time that SYN gets there and RST gets back. | 503 | causes us to block for the time that SYN gets there and RST gets back. |
504 | Not completely reliable, but it *does* mostly work. */ | 504 | Not completely reliable, but it *does* mostly work. */ |
505 | /* Set a temporary connect timeout, so packet filtration doesnt cause | 505 | /* Set a temporary connect timeout, so packet filtration doesn't cause |
506 | us to hang forever, and hit it */ | 506 | us to hang forever, and hit it */ |
507 | o_wait = 5; /* enough that we'll notice?? */ | 507 | o_wait = 5; /* enough that we'll notice?? */ |
508 | rr = xsocket(ouraddr->u.sa.sa_family, SOCK_STREAM, 0); | 508 | rr = xsocket(ouraddr->u.sa.sa_family, SOCK_STREAM, 0); |
@@ -582,11 +582,10 @@ void oprint(int direction, unsigned char *p, unsigned bc); | |||
582 | #endif | 582 | #endif |
583 | 583 | ||
584 | /* readwrite: | 584 | /* readwrite: |
585 | handle stdin/stdout/network I/O. Bwahaha!! -- the select loop from hell. | 585 | handle stdin/stdout/network I/O. Bwahaha!! -- the i/o loop from hell. |
586 | In this instance, return what might become our exit status. */ | 586 | In this instance, return what might become our exit status. */ |
587 | static int readwrite(void) | 587 | static int readwrite(void) |
588 | { | 588 | { |
589 | int rr; | ||
590 | char *zp = zp; /* gcc */ /* stdin buf ptr */ | 589 | char *zp = zp; /* gcc */ /* stdin buf ptr */ |
591 | char *np = np; /* net-in buf ptr */ | 590 | char *np = np; /* net-in buf ptr */ |
592 | unsigned rzleft; | 591 | unsigned rzleft; |
@@ -594,45 +593,41 @@ static int readwrite(void) | |||
594 | unsigned netretry; /* net-read retry counter */ | 593 | unsigned netretry; /* net-read retry counter */ |
595 | unsigned fds_open; | 594 | unsigned fds_open; |
596 | 595 | ||
597 | /* if you don't have all this FD_* macro hair in sys/types.h, you'll have to | 596 | struct pollfd pfds[2]; |
598 | either find it or do your own bit-bashing: *ding1 |= (1 << fd), etc... */ | 597 | pfds[0].fd = STDIN_FILENO; |
599 | fd_set ding1; /* for select loop */ | 598 | pfds[0].events = POLLIN; |
600 | fd_set ding2; | 599 | pfds[1].fd = netfd; |
601 | FD_ZERO(&ding1); | 600 | pfds[1].events = POLLIN; |
602 | FD_SET(netfd, &ding1); | ||
603 | FD_SET(STDIN_FILENO, &ding1); | ||
604 | fds_open = 2; | ||
605 | 601 | ||
602 | fds_open = 2; | ||
606 | netretry = 2; | 603 | netretry = 2; |
607 | rzleft = rnleft = 0; | 604 | rzleft = rnleft = 0; |
608 | if (o_interval) | 605 | if (o_interval) |
609 | sleep(o_interval); /* pause *before* sending stuff, too */ | 606 | sleep(o_interval); /* pause *before* sending stuff, too */ |
610 | 607 | ||
611 | /* and now the big ol' select shoveling loop ... */ | 608 | /* and now the big ol' shoveling loop ... */ |
612 | /* nc 1.10 has "while (FD_ISSET(netfd)" here */ | 609 | /* nc 1.10 has "while (FD_ISSET(netfd)" here */ |
613 | while (fds_open) { | 610 | while (fds_open) { |
611 | int rr; | ||
612 | int poll_tmout_ms; | ||
614 | unsigned wretry = 8200; /* net-write sanity counter */ | 613 | unsigned wretry = 8200; /* net-write sanity counter */ |
615 | 614 | ||
616 | ding2 = ding1; /* FD_COPY ain't portable... */ | 615 | poll_tmout_ms = -1; |
617 | /* some systems, notably linux, crap into their select timers on return, so | ||
618 | we create a expendable copy and give *that* to select. */ | ||
619 | if (o_wait) { | 616 | if (o_wait) { |
620 | struct timeval tmp_timer; | 617 | poll_tmout_ms = INT_MAX; |
621 | tmp_timer.tv_sec = o_wait; | 618 | if (o_wait < INT_MAX / 1000) |
622 | tmp_timer.tv_usec = 0; | 619 | poll_tmout_ms = o_wait * 1000; |
623 | /* highest possible fd is netfd (3) */ | 620 | } |
624 | rr = select(netfd+1, &ding2, NULL, NULL, &tmp_timer); | 621 | rr = poll(pfds, 2, poll_tmout_ms); |
625 | } else | ||
626 | rr = select(netfd+1, &ding2, NULL, NULL, NULL); | ||
627 | if (rr < 0 && errno != EINTR) { /* might have gotten ^Zed, etc */ | 622 | if (rr < 0 && errno != EINTR) { /* might have gotten ^Zed, etc */ |
628 | holler_perror("select"); | 623 | holler_perror("poll"); |
629 | close(netfd); | 624 | close(netfd); |
630 | return 1; | 625 | return 1; |
631 | } | 626 | } |
632 | /* if we have a timeout AND stdin is closed AND we haven't heard anything | 627 | /* if we have a timeout AND stdin is closed AND we haven't heard anything |
633 | from the net during that time, assume it's dead and close it too. */ | 628 | from the net during that time, assume it's dead and close it too. */ |
634 | if (rr == 0) { | 629 | if (rr == 0) { |
635 | if (!FD_ISSET(STDIN_FILENO, &ding1)) { | 630 | if (!pfds[0].revents) { |
636 | netretry--; /* we actually try a coupla times. */ | 631 | netretry--; /* we actually try a coupla times. */ |
637 | if (!netretry) { | 632 | if (!netretry) { |
638 | if (o_verbose > 1) /* normally we don't care */ | 633 | if (o_verbose > 1) /* normally we don't care */ |
@@ -641,19 +636,17 @@ static int readwrite(void) | |||
641 | return 0; /* not an error! */ | 636 | return 0; /* not an error! */ |
642 | } | 637 | } |
643 | } | 638 | } |
644 | } /* select timeout */ | 639 | } /* timeout */ |
645 | /* xxx: should we check the exception fds too? The read fds seem to give | ||
646 | us the right info, and none of the examples I found bothered. */ | ||
647 | 640 | ||
648 | /* Ding!! Something arrived, go check all the incoming hoppers, net first */ | 641 | /* Ding!! Something arrived, go check all the incoming hoppers, net first */ |
649 | if (FD_ISSET(netfd, &ding2)) { /* net: ding! */ | 642 | if (pfds[1].revents) { /* net: ding! */ |
650 | rr = read(netfd, bigbuf_net, BIGSIZ); | 643 | rr = read(netfd, bigbuf_net, BIGSIZ); |
651 | if (rr <= 0) { | 644 | if (rr <= 0) { |
652 | if (rr < 0 && o_verbose > 1) { | 645 | if (rr < 0 && o_verbose > 1) { |
653 | /* nc 1.10 doesn't do this */ | 646 | /* nc 1.10 doesn't do this */ |
654 | bb_perror_msg("net read"); | 647 | bb_perror_msg("net read"); |
655 | } | 648 | } |
656 | FD_CLR(netfd, &ding1); /* net closed */ | 649 | pfds[1].fd = -1; /* don't poll for netfd anymore */ |
657 | fds_open--; | 650 | fds_open--; |
658 | rzleft = 0; /* can't write anymore: broken pipe */ | 651 | rzleft = 0; /* can't write anymore: broken pipe */ |
659 | } else { | 652 | } else { |
@@ -669,12 +662,12 @@ Debug("got %d from the net, errno %d", rr, errno); | |||
669 | goto shovel; | 662 | goto shovel; |
670 | 663 | ||
671 | /* okay, suck more stdin */ | 664 | /* okay, suck more stdin */ |
672 | if (FD_ISSET(STDIN_FILENO, &ding2)) { /* stdin: ding! */ | 665 | if (pfds[0].revents) { /* stdin: ding! */ |
673 | rr = read(STDIN_FILENO, bigbuf_in, BIGSIZ); | 666 | rr = read(STDIN_FILENO, bigbuf_in, BIGSIZ); |
674 | /* Considered making reads here smaller for UDP mode, but 8192-byte | 667 | /* Considered making reads here smaller for UDP mode, but 8192-byte |
675 | mobygrams are kinda fun and exercise the reassembler. */ | 668 | mobygrams are kinda fun and exercise the reassembler. */ |
676 | if (rr <= 0) { /* at end, or fukt, or ... */ | 669 | if (rr <= 0) { /* at end, or fukt, or ... */ |
677 | FD_CLR(STDIN_FILENO, &ding1); /* disable stdin */ | 670 | pfds[0].fd = -1; /* disable stdin */ |
678 | /*close(STDIN_FILENO); - not really necessary */ | 671 | /*close(STDIN_FILENO); - not really necessary */ |
679 | /* Let peer know we have no more data */ | 672 | /* Let peer know we have no more data */ |
680 | /* nc 1.10 doesn't do this: */ | 673 | /* nc 1.10 doesn't do this: */ |
@@ -718,7 +711,7 @@ Debug("wrote %d to net, errno %d", rr, errno); | |||
718 | } /* rzleft */ | 711 | } /* rzleft */ |
719 | if (o_interval) { /* cycle between slow lines, or ... */ | 712 | if (o_interval) { /* cycle between slow lines, or ... */ |
720 | sleep(o_interval); | 713 | sleep(o_interval); |
721 | continue; /* ...with hairy select loop... */ | 714 | continue; /* ...with hairy loop... */ |
722 | } | 715 | } |
723 | if (rzleft || rnleft) { /* shovel that shit till they ain't */ | 716 | if (rzleft || rnleft) { /* shovel that shit till they ain't */ |
724 | wretry--; /* none left, and get another load */ | 717 | wretry--; /* none left, and get another load */ |
diff --git a/networking/ntpd.c b/networking/ntpd.c index 5cc71ca7a..73d27ac20 100644 --- a/networking/ntpd.c +++ b/networking/ntpd.c | |||
@@ -393,7 +393,7 @@ struct globals { | |||
393 | * too big and we will step. I observed it with -6. | 393 | * too big and we will step. I observed it with -6. |
394 | * | 394 | * |
395 | * OTOH, setting precision_sec far too small would result in futile | 395 | * OTOH, setting precision_sec far too small would result in futile |
396 | * attempts to syncronize to an unachievable precision. | 396 | * attempts to synchronize to an unachievable precision. |
397 | * | 397 | * |
398 | * -6 is 1/64 sec, -7 is 1/128 sec and so on. | 398 | * -6 is 1/64 sec, -7 is 1/128 sec and so on. |
399 | * -8 is 1/256 ~= 0.003906 (worked well for me --vda) | 399 | * -8 is 1/256 ~= 0.003906 (worked well for me --vda) |
@@ -754,7 +754,7 @@ reset_peer_stats(peer_t *p, double offset) | |||
754 | bool small_ofs = fabs(offset) < STEP_THRESHOLD; | 754 | bool small_ofs = fabs(offset) < STEP_THRESHOLD; |
755 | 755 | ||
756 | /* Used to set p->filter_datapoint[i].d_dispersion = MAXDISP | 756 | /* Used to set p->filter_datapoint[i].d_dispersion = MAXDISP |
757 | * and clear reachable bits, but this proved to be too agressive: | 757 | * and clear reachable bits, but this proved to be too aggressive: |
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 datapoints per peer | 760 | * making us needing to collect full ~8 datapoints per peer |
@@ -1715,7 +1715,7 @@ update_local_clock(peer_t *p) | |||
1715 | * It looks like Linux kernel's PLL is far too gentle in changing | 1715 | * It looks like Linux kernel's PLL is far too gentle in changing |
1716 | * tmx.freq in response to clock offset. Offset keeps growing | 1716 | * tmx.freq in response to clock offset. Offset keeps growing |
1717 | * and eventually we fall back to smaller poll intervals. | 1717 | * and eventually we fall back to smaller poll intervals. |
1718 | * We can make correction more agressive (about x2) by supplying | 1718 | * We can make correction more aggressive (about x2) by supplying |
1719 | * PLL time constant which is one less than the real one. | 1719 | * PLL time constant which is one less than the real one. |
1720 | * To be on a safe side, let's do it only if offset is significantly | 1720 | * To be on a safe side, let's do it only if offset is significantly |
1721 | * larger than jitter. | 1721 | * larger than jitter. |
diff --git a/networking/ping.c b/networking/ping.c index ef31e000b..94fb007f5 100644 --- a/networking/ping.c +++ b/networking/ping.c | |||
@@ -478,7 +478,7 @@ static void sendping_tail(void (*sp)(int), int size_pkt) | |||
478 | } else { /* -c NN, and all NN are sent (and no deadline) */ | 478 | } else { /* -c NN, and all NN are sent (and no deadline) */ |
479 | /* Wait for the last ping to come back. | 479 | /* Wait for the last ping to come back. |
480 | * -W timeout: wait for a response in seconds. | 480 | * -W timeout: wait for a response in seconds. |
481 | * Affects only timeout in absense of any responses, | 481 | * Affects only timeout in absence of any responses, |
482 | * otherwise ping waits for two RTTs. */ | 482 | * otherwise ping waits for two RTTs. */ |
483 | unsigned expire = timeout; | 483 | unsigned expire = timeout; |
484 | 484 | ||
@@ -712,7 +712,7 @@ static void ping4(len_and_sockaddr *lsa) | |||
712 | 712 | ||
713 | if (opt_ttl != 0) { | 713 | if (opt_ttl != 0) { |
714 | setsockopt_int(pingsock, IPPROTO_IP, IP_TTL, opt_ttl); | 714 | setsockopt_int(pingsock, IPPROTO_IP, IP_TTL, opt_ttl); |
715 | /* above doesnt affect packets sent to bcast IP, so... */ | 715 | /* above doesn't affect packets sent to bcast IP, so... */ |
716 | setsockopt_int(pingsock, IPPROTO_IP, IP_MULTICAST_TTL, opt_ttl); | 716 | setsockopt_int(pingsock, IPPROTO_IP, IP_MULTICAST_TTL, opt_ttl); |
717 | } | 717 | } |
718 | 718 | ||
diff --git a/networking/tcpudp.c b/networking/tcpudp.c index 3a6c68646..3ebe7d5fc 100644 --- a/networking/tcpudp.c +++ b/networking/tcpudp.c | |||
@@ -683,7 +683,7 @@ prog | |||
683 | -E | 683 | -E |
684 | no special environment. Do not set up TCP-related environment variables. | 684 | no special environment. Do not set up TCP-related environment variables. |
685 | -v | 685 | -v |
686 | verbose. Print verbose messsages to standard output. | 686 | verbose. Print verbose messages to standard output. |
687 | -vv | 687 | -vv |
688 | more verbose. Print more verbose messages to standard output. | 688 | more verbose. Print more verbose messages to standard output. |
689 | * no difference between -v and -vv in busyboxed version | 689 | * no difference between -v and -vv in busyboxed version |
diff --git a/networking/tls.c b/networking/tls.c index 30afd9ea9..db518bf90 100644 --- a/networking/tls.c +++ b/networking/tls.c | |||
@@ -39,7 +39,7 @@ | |||
39 | 39 | ||
40 | // works against "openssl s_server -cipher NULL" | 40 | // works against "openssl s_server -cipher NULL" |
41 | // and against wolfssl-3.9.10-stable/examples/server/server.c: | 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) | 42 | //#define CIPHER_ID1 TLS_RSA_WITH_NULL_SHA256 // for testing (does everything except encrypting) |
43 | 43 | ||
44 | // works against wolfssl-3.9.10-stable/examples/server/server.c | 44 | // works against wolfssl-3.9.10-stable/examples/server/server.c |
45 | // works for kernel.org | 45 | // works for kernel.org |
@@ -367,11 +367,12 @@ static unsigned hmac_sha_precomputed_v( | |||
367 | return sha_end(&pre->hashed_key_xor_opad, out); | 367 | return sha_end(&pre->hashed_key_xor_opad, out); |
368 | } | 368 | } |
369 | 369 | ||
370 | static void hmac_sha256_begin(hmac_precomputed_t *pre, uint8_t *key, unsigned key_size) | 370 | typedef void md5sha_begin_func(md5sha_ctx_t *ctx) FAST_FUNC; |
371 | static void hmac_begin(hmac_precomputed_t *pre, uint8_t *key, unsigned key_size, md5sha_begin_func *begin) | ||
371 | { | 372 | { |
372 | uint8_t key_xor_ipad[SHA_INSIZE]; | 373 | uint8_t key_xor_ipad[SHA_INSIZE]; |
373 | uint8_t key_xor_opad[SHA_INSIZE]; | 374 | uint8_t key_xor_opad[SHA_INSIZE]; |
374 | uint8_t tempkey[SHA256_OUTSIZE]; | 375 | uint8_t tempkey[SHA1_OUTSIZE < SHA256_OUTSIZE ? SHA256_OUTSIZE : SHA1_OUTSIZE]; |
375 | unsigned i; | 376 | unsigned i; |
376 | 377 | ||
377 | // "The authentication key can be of any length up to INSIZE, the | 378 | // "The authentication key can be of any length up to INSIZE, the |
@@ -380,7 +381,7 @@ static void hmac_sha256_begin(hmac_precomputed_t *pre, uint8_t *key, unsigned ke | |||
380 | // resultant OUTSIZE byte string as the actual key to HMAC." | 381 | // resultant OUTSIZE byte string as the actual key to HMAC." |
381 | if (key_size > SHA_INSIZE) { | 382 | if (key_size > SHA_INSIZE) { |
382 | md5sha_ctx_t ctx; | 383 | md5sha_ctx_t ctx; |
383 | sha256_begin(&ctx); | 384 | begin(&ctx); |
384 | md5sha_hash(&ctx, key, key_size); | 385 | md5sha_hash(&ctx, key, key_size); |
385 | key_size = sha_end(&ctx, tempkey); | 386 | key_size = sha_end(&ctx, tempkey); |
386 | } | 387 | } |
@@ -394,41 +395,8 @@ static void hmac_sha256_begin(hmac_precomputed_t *pre, uint8_t *key, unsigned ke | |||
394 | key_xor_opad[i] = 0x5c; | 395 | key_xor_opad[i] = 0x5c; |
395 | } | 396 | } |
396 | 397 | ||
397 | sha256_begin(&pre->hashed_key_xor_ipad); | 398 | begin(&pre->hashed_key_xor_ipad); |
398 | sha256_begin(&pre->hashed_key_xor_opad); | 399 | 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); | 400 | 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); | 401 | md5sha_hash(&pre->hashed_key_xor_opad, key_xor_opad, SHA_INSIZE); |
434 | } | 402 | } |
@@ -441,11 +409,11 @@ static unsigned hmac(tls_state_t *tls, uint8_t *out, uint8_t *key, unsigned key_ | |||
441 | 409 | ||
442 | va_start(va, key_size); | 410 | va_start(va, key_size); |
443 | 411 | ||
444 | if (tls->MAC_size == SHA256_OUTSIZE) | 412 | hmac_begin(&pre, key, key_size, |
445 | hmac_sha256_begin(&pre, key, key_size); | 413 | (tls->MAC_size == SHA256_OUTSIZE) |
446 | else | 414 | ? sha256_begin |
447 | hmac_sha1_begin(&pre, key, key_size); | 415 | : sha1_begin |
448 | 416 | ); | |
449 | len = hmac_sha_precomputed_v(&pre, out, va); | 417 | len = hmac_sha_precomputed_v(&pre, out, va); |
450 | 418 | ||
451 | va_end(va); | 419 | va_end(va); |
@@ -460,7 +428,7 @@ static unsigned hmac_sha256(/*tls_state_t *tls,*/ uint8_t *out, uint8_t *key, un | |||
460 | 428 | ||
461 | va_start(va, key_size); | 429 | va_start(va, key_size); |
462 | 430 | ||
463 | hmac_sha256_begin(&pre, key, key_size); | 431 | hmac_begin(&pre, key, key_size, sha256_begin); |
464 | len = hmac_sha_precomputed_v(&pre, out, va); | 432 | len = hmac_sha_precomputed_v(&pre, out, va); |
465 | 433 | ||
466 | va_end(va); | 434 | va_end(va); |
@@ -507,7 +475,7 @@ static void prf_hmac_sha256(/*tls_state_t *tls,*/ | |||
507 | uint8_t a[TLS_MAX_MAC_SIZE]; | 475 | uint8_t a[TLS_MAX_MAC_SIZE]; |
508 | uint8_t *out_p = outbuf; | 476 | uint8_t *out_p = outbuf; |
509 | unsigned label_size = strlen(label); | 477 | unsigned label_size = strlen(label); |
510 | unsigned MAC_size = SHA256_OUTSIZE;///tls->MAC_size; | 478 | unsigned MAC_size = SHA256_OUTSIZE; |
511 | 479 | ||
512 | /* In P_hash() calculation, "seed" is "label + seed": */ | 480 | /* In P_hash() calculation, "seed" is "label + seed": */ |
513 | #define SEED label, label_size, seed, seed_size | 481 | #define SEED label, label_size, seed, seed_size |
@@ -518,7 +486,7 @@ static void prf_hmac_sha256(/*tls_state_t *tls,*/ | |||
518 | hmac_sha256(/*tls,*/ a, SECRET, SEED, NULL); | 486 | hmac_sha256(/*tls,*/ a, SECRET, SEED, NULL); |
519 | //TODO: convert hmac to precomputed | 487 | //TODO: convert hmac to precomputed |
520 | 488 | ||
521 | for(;;) { | 489 | for (;;) { |
522 | /* HMAC_hash(secret, A(1) + seed) */ | 490 | /* HMAC_hash(secret, A(1) + seed) */ |
523 | if (outbuf_size <= MAC_size) { | 491 | if (outbuf_size <= MAC_size) { |
524 | /* Last, possibly incomplete, block */ | 492 | /* Last, possibly incomplete, block */ |
@@ -597,8 +565,11 @@ static void xwrite_encrypted(tls_state_t *tls, unsigned size, unsigned type) | |||
597 | uint8_t padding_length; | 565 | uint8_t padding_length; |
598 | 566 | ||
599 | xhdr = (void*)(buf - RECHDR_LEN); | 567 | xhdr = (void*)(buf - RECHDR_LEN); |
600 | if (tls->cipher_id != TLS_RSA_WITH_NULL_SHA256) | 568 | if (CIPHER_ID1 != TLS_RSA_WITH_NULL_SHA256 /* if "no encryption" can't be selected */ |
569 | || tls->cipher_id != TLS_RSA_WITH_NULL_SHA256 /* or if it wasn't selected */ | ||
570 | ) { | ||
601 | xhdr = (void*)(buf - RECHDR_LEN - AES_BLOCKSIZE); /* place for IV */ | 571 | xhdr = (void*)(buf - RECHDR_LEN - AES_BLOCKSIZE); /* place for IV */ |
572 | } | ||
602 | 573 | ||
603 | xhdr->type = type; | 574 | xhdr->type = type; |
604 | xhdr->proto_maj = TLS_MAJ; | 575 | xhdr->proto_maj = TLS_MAJ; |
@@ -652,7 +623,9 @@ static void xwrite_encrypted(tls_state_t *tls, unsigned size, unsigned type) | |||
652 | // -------- ----------- ---------- -------------- | 623 | // -------- ----------- ---------- -------------- |
653 | // SHA HMAC-SHA1 20 20 | 624 | // SHA HMAC-SHA1 20 20 |
654 | // SHA256 HMAC-SHA256 32 32 | 625 | // SHA256 HMAC-SHA256 32 32 |
655 | if (tls->cipher_id == TLS_RSA_WITH_NULL_SHA256) { | 626 | if (CIPHER_ID1 == TLS_RSA_WITH_NULL_SHA256 |
627 | && tls->cipher_id == TLS_RSA_WITH_NULL_SHA256 | ||
628 | ) { | ||
656 | /* No encryption, only signing */ | 629 | /* No encryption, only signing */ |
657 | xhdr->len16_hi = size >> 8; | 630 | xhdr->len16_hi = size >> 8; |
658 | xhdr->len16_lo = size & 0xff; | 631 | xhdr->len16_lo = size & 0xff; |
@@ -1698,9 +1671,11 @@ void FAST_FUNC tls_handshake(tls_state_t *tls, const char *sni) | |||
1698 | if (len != 1 || memcmp(tls->inbuf, rec_CHANGE_CIPHER_SPEC, 6) != 0) | 1671 | if (len != 1 || memcmp(tls->inbuf, rec_CHANGE_CIPHER_SPEC, 6) != 0) |
1699 | bad_record_die(tls, "switch to encrypted traffic", len); | 1672 | bad_record_die(tls, "switch to encrypted traffic", len); |
1700 | dbg("<< CHANGE_CIPHER_SPEC\n"); | 1673 | dbg("<< CHANGE_CIPHER_SPEC\n"); |
1701 | if (tls->cipher_id == TLS_RSA_WITH_NULL_SHA256) | 1674 | if (CIPHER_ID1 == TLS_RSA_WITH_NULL_SHA256 |
1675 | && tls->cipher_id == TLS_RSA_WITH_NULL_SHA256 | ||
1676 | ) { | ||
1702 | tls->min_encrypted_len_on_read = tls->MAC_size; | 1677 | tls->min_encrypted_len_on_read = tls->MAC_size; |
1703 | else { | 1678 | } else { |
1704 | unsigned mac_blocks = (unsigned)(tls->MAC_size + AES_BLOCKSIZE-1) / AES_BLOCKSIZE; | 1679 | unsigned mac_blocks = (unsigned)(tls->MAC_size + AES_BLOCKSIZE-1) / AES_BLOCKSIZE; |
1705 | /* all incoming packets now should be encrypted and have | 1680 | /* all incoming packets now should be encrypted and have |
1706 | * at least IV + (MAC padded to blocksize): | 1681 | * at least IV + (MAC padded to blocksize): |
@@ -1740,26 +1715,23 @@ static void tls_xwrite(tls_state_t *tls, int len) | |||
1740 | 1715 | ||
1741 | void FAST_FUNC tls_run_copy_loop(tls_state_t *tls) | 1716 | void FAST_FUNC tls_run_copy_loop(tls_state_t *tls) |
1742 | { | 1717 | { |
1743 | fd_set readfds; | ||
1744 | int inbuf_size; | 1718 | int inbuf_size; |
1745 | const int INBUF_STEP = 4 * 1024; | 1719 | const int INBUF_STEP = 4 * 1024; |
1720 | struct pollfd pfds[2]; | ||
1746 | 1721 | ||
1747 | //TODO: convert to poll | 1722 | pfds[0].fd = STDIN_FILENO; |
1748 | /* Select loop copying stdin to ofd, and ifd to stdout */ | 1723 | pfds[0].events = POLLIN; |
1749 | FD_ZERO(&readfds); | 1724 | pfds[1].fd = tls->ifd; |
1750 | FD_SET(tls->ifd, &readfds); | 1725 | pfds[1].events = POLLIN; |
1751 | FD_SET(STDIN_FILENO, &readfds); | ||
1752 | 1726 | ||
1753 | inbuf_size = INBUF_STEP; | 1727 | inbuf_size = INBUF_STEP; |
1754 | for (;;) { | 1728 | for (;;) { |
1755 | fd_set testfds; | ||
1756 | int nread; | 1729 | int nread; |
1757 | 1730 | ||
1758 | testfds = readfds; | 1731 | if (safe_poll(pfds, 2, -1) < 0) |
1759 | if (select(tls->ifd + 1, &testfds, NULL, NULL, NULL) < 0) | 1732 | bb_perror_msg_and_die("poll"); |
1760 | bb_perror_msg_and_die("select"); | ||
1761 | 1733 | ||
1762 | if (FD_ISSET(STDIN_FILENO, &testfds)) { | 1734 | if (pfds[0].revents) { |
1763 | void *buf; | 1735 | void *buf; |
1764 | 1736 | ||
1765 | dbg("STDIN HAS DATA\n"); | 1737 | dbg("STDIN HAS DATA\n"); |
@@ -1774,7 +1746,7 @@ void FAST_FUNC tls_run_copy_loop(tls_state_t *tls) | |||
1774 | /* But TLS has no way to encode this, | 1746 | /* But TLS has no way to encode this, |
1775 | * doubt it's ok to do it "raw" | 1747 | * doubt it's ok to do it "raw" |
1776 | */ | 1748 | */ |
1777 | FD_CLR(STDIN_FILENO, &readfds); | 1749 | pfds[0].fd = -1; |
1778 | tls_free_outbuf(tls); /* mem usage optimization */ | 1750 | tls_free_outbuf(tls); /* mem usage optimization */ |
1779 | } else { | 1751 | } else { |
1780 | if (nread == inbuf_size) { | 1752 | if (nread == inbuf_size) { |
@@ -1788,7 +1760,7 @@ void FAST_FUNC tls_run_copy_loop(tls_state_t *tls) | |||
1788 | tls_xwrite(tls, nread); | 1760 | tls_xwrite(tls, nread); |
1789 | } | 1761 | } |
1790 | } | 1762 | } |
1791 | if (FD_ISSET(tls->ifd, &testfds)) { | 1763 | if (pfds[1].revents) { |
1792 | dbg("NETWORK HAS DATA\n"); | 1764 | dbg("NETWORK HAS DATA\n"); |
1793 | read_record: | 1765 | read_record: |
1794 | nread = tls_xread_record(tls); | 1766 | nread = tls_xread_record(tls); |
@@ -1796,7 +1768,7 @@ void FAST_FUNC tls_run_copy_loop(tls_state_t *tls) | |||
1796 | /* TLS protocol has no real concept of one-sided shutdowns: | 1768 | /* TLS protocol has no real concept of one-sided shutdowns: |
1797 | * if we get "TLS EOF" from the peer, writes will fail too | 1769 | * if we get "TLS EOF" from the peer, writes will fail too |
1798 | */ | 1770 | */ |
1799 | //FD_CLR(tls->ifd, &readfds); | 1771 | //pfds[1].fd = -1; |
1800 | //close(STDOUT_FILENO); | 1772 | //close(STDOUT_FILENO); |
1801 | //tls_free_inbuf(tls); /* mem usage optimization */ | 1773 | //tls_free_inbuf(tls); /* mem usage optimization */ |
1802 | //continue; | 1774 | //continue; |
diff --git a/networking/tls_aes.c b/networking/tls_aes.c index ebaab15b1..6992f1c90 100644 --- a/networking/tls_aes.c +++ b/networking/tls_aes.c | |||
@@ -3,1774 +3,458 @@ | |||
3 | * | 3 | * |
4 | * Licensed under GPLv2, see file LICENSE in this source tree. | 4 | * Licensed under GPLv2, see file LICENSE in this source tree. |
5 | */ | 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 | 6 | ||
52 | /** | 7 | /* This AES implementation is derived from tiny-AES128-C code, |
53 | * @file aes.c | 8 | * which was put by its author into public domain: |
54 | * @version 33ef80f (HEAD, tag: MATRIXSSL-3-7-2-OPEN, tag: MATRIXSSL-3-7-2-COMM, origin/master, origin/HEAD, master) | ||
55 | * | 9 | * |
56 | * AES CBC block cipher implementation. | 10 | * tiny-AES128-C/unlicense.txt, Dec 8, 2014 |
57 | */ | 11 | * """ |
58 | /* | 12 | * This is free and unencumbered software released into the public domain. |
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 | * | 13 | * |
65 | * This software is open source; you can redistribute it and/or modify | 14 | * Anyone is free to copy, modify, publish, use, compile, sell, or |
66 | * it under the terms of the GNU General Public License as published by | 15 | * distribute this software, either in source code form or as a compiled |
67 | * the Free Software Foundation; either version 2 of the License, or | 16 | * binary, for any purpose, commercial or non-commercial, and by any |
68 | * (at your option) any later version. | 17 | * means. |
69 | * | 18 | * |
70 | * This General Public License does NOT permit incorporating this software | 19 | * In jurisdictions that recognize copyright laws, the author or authors |
71 | * into proprietary programs. If you are unable to comply with the GPL, a | 20 | * of this software dedicate any and all copyright interest in the |
72 | * commercial license for this software may be purchased from INSIDE at | 21 | * software to the public domain. We make this dedication for the benefit |
73 | * http://www.insidesecure.com/eng/Company/Locations | 22 | * of the public at large and to the detriment of our heirs and |
23 | * successors. We intend this dedication to be an overt act of | ||
24 | * relinquishment in perpetuity of all present and future rights to this | ||
25 | * software under copyright law. | ||
74 | * | 26 | * |
75 | * This program is distributed in WITHOUT ANY WARRANTY; without even the | 27 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, |
76 | * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. | 28 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF |
77 | * See the GNU General Public License for more details. | 29 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. |
78 | * | 30 | * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR |
79 | * You should have received a copy of the GNU General Public License | 31 | * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, |
80 | * along with this program; if not, write to the Free Software | 32 | * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR |
81 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | 33 | * OTHER DEALINGS IN THE SOFTWARE. |
82 | * http://www.gnu.org/copyleft/gpl.html | 34 | * """ |
83 | */ | 35 | */ |
84 | /******************************************************************************/ | 36 | /* Note that only original tiny-AES128-C code is public domain. |
85 | 37 | * The derived code in this file has been expanded to also implement aes192 | |
86 | //bbox | 38 | * and aes256 and use more efficient word-sized operations in many places, |
87 | //#include "../cryptoApi.h" | 39 | * and put under GPLv2 license. |
88 | 40 | */ | |
89 | #ifdef USE_AES | 41 | #include "tls.h" |
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 | 42 | ||
1050 | static const uint32 Tks3[] = { | 43 | /* TODO: grep for this and move to libbb */ |
1051 | 0x00000000UL, 0x090d0b0eUL, 0x121a161cUL, 0x1b171d12UL, 0x24342c38UL, 0x2d392736UL, 0x362e3a24UL, 0x3f23312aUL, | 44 | #define get_unaligned_be32(buf) ({ uint32_t v; move_from_unaligned32(v, buf); SWAP_BE32(v); }) |
1052 | 0x48685870UL, 0x4165537eUL, 0x5a724e6cUL, 0x537f4562UL, 0x6c5c7448UL, 0x65517f46UL, 0x7e466254UL, 0x774b695aUL, | 45 | |
1053 | 0x90d0b0e0UL, 0x99ddbbeeUL, 0x82caa6fcUL, 0x8bc7adf2UL, 0xb4e49cd8UL, 0xbde997d6UL, 0xa6fe8ac4UL, 0xaff381caUL, | 46 | |
1054 | 0xd8b8e890UL, 0xd1b5e39eUL, 0xcaa2fe8cUL, 0xc3aff582UL, 0xfc8cc4a8UL, 0xf581cfa6UL, 0xee96d2b4UL, 0xe79bd9baUL, | 47 | // The lookup-tables are marked const so they can be placed in read-only storage instead of RAM |
1055 | 0x3bbb7bdbUL, 0x32b670d5UL, 0x29a16dc7UL, 0x20ac66c9UL, 0x1f8f57e3UL, 0x16825cedUL, 0x0d9541ffUL, 0x04984af1UL, | 48 | // The numbers below can be computed dynamically trading ROM for RAM - |
1056 | 0x73d323abUL, 0x7ade28a5UL, 0x61c935b7UL, 0x68c43eb9UL, 0x57e70f93UL, 0x5eea049dUL, 0x45fd198fUL, 0x4cf01281UL, | 49 | // This can be useful in (embedded) bootloader applications, where ROM is often limited. |
1057 | 0xab6bcb3bUL, 0xa266c035UL, 0xb971dd27UL, 0xb07cd629UL, 0x8f5fe703UL, 0x8652ec0dUL, 0x9d45f11fUL, 0x9448fa11UL, | 50 | static const uint8_t sbox[] = { |
1058 | 0xe303934bUL, 0xea0e9845UL, 0xf1198557UL, 0xf8148e59UL, 0xc737bf73UL, 0xce3ab47dUL, 0xd52da96fUL, 0xdc20a261UL, | 51 | 0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, |
1059 | 0x766df6adUL, 0x7f60fda3UL, 0x6477e0b1UL, 0x6d7aebbfUL, 0x5259da95UL, 0x5b54d19bUL, 0x4043cc89UL, 0x494ec787UL, | 52 | 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76, |
1060 | 0x3e05aeddUL, 0x3708a5d3UL, 0x2c1fb8c1UL, 0x2512b3cfUL, 0x1a3182e5UL, 0x133c89ebUL, 0x082b94f9UL, 0x01269ff7UL, | 53 | 0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0, |
1061 | 0xe6bd464dUL, 0xefb04d43UL, 0xf4a75051UL, 0xfdaa5b5fUL, 0xc2896a75UL, 0xcb84617bUL, 0xd0937c69UL, 0xd99e7767UL, | 54 | 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0, |
1062 | 0xaed51e3dUL, 0xa7d81533UL, 0xbccf0821UL, 0xb5c2032fUL, 0x8ae13205UL, 0x83ec390bUL, 0x98fb2419UL, 0x91f62f17UL, | 55 | 0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc, |
1063 | 0x4dd68d76UL, 0x44db8678UL, 0x5fcc9b6aUL, 0x56c19064UL, 0x69e2a14eUL, 0x60efaa40UL, 0x7bf8b752UL, 0x72f5bc5cUL, | 56 | 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15, |
1064 | 0x05bed506UL, 0x0cb3de08UL, 0x17a4c31aUL, 0x1ea9c814UL, 0x218af93eUL, 0x2887f230UL, 0x3390ef22UL, 0x3a9de42cUL, | 57 | 0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a, |
1065 | 0xdd063d96UL, 0xd40b3698UL, 0xcf1c2b8aUL, 0xc6112084UL, 0xf93211aeUL, 0xf03f1aa0UL, 0xeb2807b2UL, 0xe2250cbcUL, | 58 | 0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75, |
1066 | 0x956e65e6UL, 0x9c636ee8UL, 0x877473faUL, 0x8e7978f4UL, 0xb15a49deUL, 0xb85742d0UL, 0xa3405fc2UL, 0xaa4d54ccUL, | 59 | 0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0, |
1067 | 0xecdaf741UL, 0xe5d7fc4fUL, 0xfec0e15dUL, 0xf7cdea53UL, 0xc8eedb79UL, 0xc1e3d077UL, 0xdaf4cd65UL, 0xd3f9c66bUL, | 60 | 0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84, |
1068 | 0xa4b2af31UL, 0xadbfa43fUL, 0xb6a8b92dUL, 0xbfa5b223UL, 0x80868309UL, 0x898b8807UL, 0x929c9515UL, 0x9b919e1bUL, | 61 | 0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b, |
1069 | 0x7c0a47a1UL, 0x75074cafUL, 0x6e1051bdUL, 0x671d5ab3UL, 0x583e6b99UL, 0x51336097UL, 0x4a247d85UL, 0x4329768bUL, | 62 | 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf, |
1070 | 0x34621fd1UL, 0x3d6f14dfUL, 0x267809cdUL, 0x2f7502c3UL, 0x105633e9UL, 0x195b38e7UL, 0x024c25f5UL, 0x0b412efbUL, | 63 | 0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85, |
1071 | 0xd7618c9aUL, 0xde6c8794UL, 0xc57b9a86UL, 0xcc769188UL, 0xf355a0a2UL, 0xfa58abacUL, 0xe14fb6beUL, 0xe842bdb0UL, | 64 | 0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8, |
1072 | 0x9f09d4eaUL, 0x9604dfe4UL, 0x8d13c2f6UL, 0x841ec9f8UL, 0xbb3df8d2UL, 0xb230f3dcUL, 0xa927eeceUL, 0xa02ae5c0UL, | 65 | 0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5, |
1073 | 0x47b13c7aUL, 0x4ebc3774UL, 0x55ab2a66UL, 0x5ca62168UL, 0x63851042UL, 0x6a881b4cUL, 0x719f065eUL, 0x78920d50UL, | 66 | 0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2, |
1074 | 0x0fd9640aUL, 0x06d46f04UL, 0x1dc37216UL, 0x14ce7918UL, 0x2bed4832UL, 0x22e0433cUL, 0x39f75e2eUL, 0x30fa5520UL, | 67 | 0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17, |
1075 | 0x9ab701ecUL, 0x93ba0ae2UL, 0x88ad17f0UL, 0x81a01cfeUL, 0xbe832dd4UL, 0xb78e26daUL, 0xac993bc8UL, 0xa59430c6UL, | 68 | 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73, |
1076 | 0xd2df599cUL, 0xdbd25292UL, 0xc0c54f80UL, 0xc9c8448eUL, 0xf6eb75a4UL, 0xffe67eaaUL, 0xe4f163b8UL, 0xedfc68b6UL, | 69 | 0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88, |
1077 | 0x0a67b10cUL, 0x036aba02UL, 0x187da710UL, 0x1170ac1eUL, 0x2e539d34UL, 0x275e963aUL, 0x3c498b28UL, 0x35448026UL, | 70 | 0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb, |
1078 | 0x420fe97cUL, 0x4b02e272UL, 0x5015ff60UL, 0x5918f46eUL, 0x663bc544UL, 0x6f36ce4aUL, 0x7421d358UL, 0x7d2cd856UL, | 71 | 0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c, |
1079 | 0xa10c7a37UL, 0xa8017139UL, 0xb3166c2bUL, 0xba1b6725UL, 0x8538560fUL, 0x8c355d01UL, 0x97224013UL, 0x9e2f4b1dUL, | 72 | 0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79, |
1080 | 0xe9642247UL, 0xe0692949UL, 0xfb7e345bUL, 0xf2733f55UL, 0xcd500e7fUL, 0xc45d0571UL, 0xdf4a1863UL, 0xd647136dUL, | 73 | 0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9, |
1081 | 0x31dccad7UL, 0x38d1c1d9UL, 0x23c6dccbUL, 0x2acbd7c5UL, 0x15e8e6efUL, 0x1ce5ede1UL, 0x07f2f0f3UL, 0x0efffbfdUL, | 74 | 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08, |
1082 | 0x79b492a7UL, 0x70b999a9UL, 0x6bae84bbUL, 0x62a38fb5UL, 0x5d80be9fUL, 0x548db591UL, 0x4f9aa883UL, 0x4697a38dUL | 75 | 0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6, |
76 | 0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a, | ||
77 | 0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e, | ||
78 | 0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e, | ||
79 | 0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94, | ||
80 | 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf, | ||
81 | 0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68, | ||
82 | 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16, | ||
1083 | }; | 83 | }; |
1084 | 84 | ||
1085 | #endif /* PS_AES_IMPROVE_PERF_INCREASE_CODESIZE */ | 85 | static const uint8_t rsbox[] = { |
1086 | 86 | 0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38, | |
1087 | static const uint32 rcon[] = { | 87 | 0xbf, 0x40, 0xa3, 0x9e, 0x81, 0xf3, 0xd7, 0xfb, |
1088 | 0x01000000UL, 0x02000000UL, 0x04000000UL, 0x08000000UL, | 88 | 0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87, |
1089 | 0x10000000UL, 0x20000000UL, 0x40000000UL, 0x80000000UL, | 89 | 0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb, |
1090 | 0x1B000000UL, 0x36000000UL, /* for 128-bit blocks, AES never uses more than 10 rcon values */ | 90 | 0x54, 0x7b, 0x94, 0x32, 0xa6, 0xc2, 0x23, 0x3d, |
91 | 0xee, 0x4c, 0x95, 0x0b, 0x42, 0xfa, 0xc3, 0x4e, | ||
92 | 0x08, 0x2e, 0xa1, 0x66, 0x28, 0xd9, 0x24, 0xb2, | ||
93 | 0x76, 0x5b, 0xa2, 0x49, 0x6d, 0x8b, 0xd1, 0x25, | ||
94 | 0x72, 0xf8, 0xf6, 0x64, 0x86, 0x68, 0x98, 0x16, | ||
95 | 0xd4, 0xa4, 0x5c, 0xcc, 0x5d, 0x65, 0xb6, 0x92, | ||
96 | 0x6c, 0x70, 0x48, 0x50, 0xfd, 0xed, 0xb9, 0xda, | ||
97 | 0x5e, 0x15, 0x46, 0x57, 0xa7, 0x8d, 0x9d, 0x84, | ||
98 | 0x90, 0xd8, 0xab, 0x00, 0x8c, 0xbc, 0xd3, 0x0a, | ||
99 | 0xf7, 0xe4, 0x58, 0x05, 0xb8, 0xb3, 0x45, 0x06, | ||
100 | 0xd0, 0x2c, 0x1e, 0x8f, 0xca, 0x3f, 0x0f, 0x02, | ||
101 | 0xc1, 0xaf, 0xbd, 0x03, 0x01, 0x13, 0x8a, 0x6b, | ||
102 | 0x3a, 0x91, 0x11, 0x41, 0x4f, 0x67, 0xdc, 0xea, | ||
103 | 0x97, 0xf2, 0xcf, 0xce, 0xf0, 0xb4, 0xe6, 0x73, | ||
104 | 0x96, 0xac, 0x74, 0x22, 0xe7, 0xad, 0x35, 0x85, | ||
105 | 0xe2, 0xf9, 0x37, 0xe8, 0x1c, 0x75, 0xdf, 0x6e, | ||
106 | 0x47, 0xf1, 0x1a, 0x71, 0x1d, 0x29, 0xc5, 0x89, | ||
107 | 0x6f, 0xb7, 0x62, 0x0e, 0xaa, 0x18, 0xbe, 0x1b, | ||
108 | 0xfc, 0x56, 0x3e, 0x4b, 0xc6, 0xd2, 0x79, 0x20, | ||
109 | 0x9a, 0xdb, 0xc0, 0xfe, 0x78, 0xcd, 0x5a, 0xf4, | ||
110 | 0x1f, 0xdd, 0xa8, 0x33, 0x88, 0x07, 0xc7, 0x31, | ||
111 | 0xb1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xec, 0x5f, | ||
112 | 0x60, 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d, | ||
113 | 0x2d, 0xe5, 0x7a, 0x9f, 0x93, 0xc9, 0x9c, 0xef, | ||
114 | 0xa0, 0xe0, 0x3b, 0x4d, 0xae, 0x2a, 0xf5, 0xb0, | ||
115 | 0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61, | ||
116 | 0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26, | ||
117 | 0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0c, 0x7d, | ||
1091 | }; | 118 | }; |
1092 | 119 | ||
1093 | #ifdef USE_BURN_STACK | 120 | // SubWord() is a function that takes a four-byte input word and |
1094 | static void _aes_ecb_decrypt(const unsigned char *ct, unsigned char *pt, | 121 | // applies the S-box to each of the four bytes to produce an output word. |
1095 | psAesKey_t *skey); | 122 | static uint32_t Subword(uint32_t x) |
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 | { | 123 | { |
1102 | return (Te4_3[byte(temp, 2)]) ^ | 124 | return (sbox[(x >> 24) ] << 24) |
1103 | (Te4_2[byte(temp, 1)]) ^ | 125 | | (sbox[(x >> 16) & 255] << 16) |
1104 | (Te4_1[byte(temp, 0)]) ^ | 126 | | (sbox[(x >> 8 ) & 255] << 8 ) |
1105 | (Te4_0[byte(temp, 3)]); | 127 | | (sbox[(x ) & 255] ); |
1106 | } | 128 | } |
1107 | 129 | ||
1108 | #ifndef PS_AES_IMPROVE_PERF_INCREASE_CODESIZE | 130 | // This function produces Nb(Nr+1) round keys. |
1109 | static uint32 setup_mix2(uint32 temp) | 131 | // The round keys are used in each round to decrypt the states. |
132 | static int KeyExpansion(uint32_t *RoundKey, const void *key, unsigned key_len) | ||
1110 | { | 133 | { |
1111 | return Td0(255 & Te4[byte(temp, 3)]) ^ | 134 | // The round constant word array, Rcon[i], contains the values given by |
1112 | Td1(255 & Te4[byte(temp, 2)]) ^ | 135 | // x to th e power (i-1) being powers of x (x is denoted as {02}) in the field GF(2^8). |
1113 | Td2(255 & Te4[byte(temp, 1)]) ^ | 136 | // Note that i starts at 2, not 0. |
1114 | Td3(255 & Te4[byte(temp, 0)]); | 137 | static const uint8_t Rcon[] = { |
138 | 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36 | ||
139 | //..... 0x6c, 0xd8, 0xab, 0x4d, 0x9a, 0x2f, 0x5e, 0xbc, 0x63, 0xc6,... | ||
140 | // but aes256 only uses values up to 0x36 | ||
141 | }; | ||
142 | int rounds, words_key, words_RoundKey; | ||
143 | int i, j, k; | ||
144 | |||
145 | // key_len 16: aes128, rounds 10, words_key 4, words_RoundKey 44 | ||
146 | // key_len 24: aes192, rounds 12, words_key 6, words_RoundKey 52 | ||
147 | // key_len 32: aes256, rounds 14, words_key 8, words_RoundKey 60 | ||
148 | words_key = key_len / 4; | ||
149 | rounds = 6 + (key_len / 4); | ||
150 | words_RoundKey = 28 + key_len; | ||
151 | |||
152 | // The first round key is the key itself. | ||
153 | for (i = 0; i < words_key; i++) | ||
154 | RoundKey[i] = get_unaligned_be32((uint32_t*)key + i); | ||
155 | // i == words_key now | ||
156 | |||
157 | // All other round keys are found from the previous round keys. | ||
158 | j = k = 0; | ||
159 | for (; i < words_RoundKey; i++) { | ||
160 | uint32_t tempa; | ||
161 | |||
162 | tempa = RoundKey[i - 1]; | ||
163 | if (j == 0) { | ||
164 | // RotWord(): rotates the 4 bytes in a word to the left once. | ||
165 | tempa = (tempa << 8) | (tempa >> 24); | ||
166 | tempa = Subword(tempa); | ||
167 | tempa ^= (uint32_t)Rcon[k] << 24; | ||
168 | } else if (words_key > 6 && j == 4) { | ||
169 | tempa = Subword(tempa); | ||
170 | } | ||
171 | RoundKey[i] = RoundKey[i - words_key] ^ tempa; | ||
172 | j++; | ||
173 | if (j == words_key) { | ||
174 | j = 0; | ||
175 | k++; | ||
176 | } | ||
177 | } | ||
178 | return rounds; | ||
1115 | } | 179 | } |
1116 | #endif /* PS_AES_IMPROVE_PERF_INCREASE_CODESIZE */ | ||
1117 | 180 | ||
1118 | /* | 181 | // This function adds the round key to state. |
1119 | Software implementation of AES CBC APIs | 182 | // The round key is added to the state by an XOR function. |
1120 | */ | 183 | static void AddRoundKey(unsigned astate[16], const uint32_t *RoundKeys) |
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 | { | 184 | { |
1126 | int32 x, err; | 185 | int i; |
1127 | 186 | ||
1128 | //bbox | 187 | for (i = 0; i < 16; i += 4) { |
1129 | // if (IV == NULL || key == NULL || ctx == NULL) { | 188 | uint32_t n = *RoundKeys++; |
1130 | // psTraceCrypto("psAesInit arg fail\n"); | 189 | astate[i + 0] ^= (n >> 24); |
1131 | // return PS_ARG_FAIL; | 190 | astate[i + 1] ^= (n >> 16) & 255; |
1132 | // } | 191 | astate[i + 2] ^= (n >> 8) & 255; |
1133 | memset(ctx, 0x0, sizeof(psCipherContext_t)); | 192 | astate[i + 3] ^= n & 255; |
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 | } | 193 | } |
1147 | return PS_SUCCESS; | ||
1148 | } | 194 | } |
1149 | 195 | ||
1150 | static //bbox | 196 | // The SubBytes Function Substitutes the values in the |
1151 | int32 psAesEncrypt(psCipherContext_t *ctx, const unsigned char *pt, | 197 | // state matrix with values in an S-box. |
1152 | unsigned char *ct, uint32 len) | 198 | static void SubBytes(unsigned astate[16]) |
1153 | { | 199 | { |
1154 | int32 x; | 200 | int i; |
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 | 201 | ||
1166 | /* | 202 | for (i = 0; i < 16; i++) |
1167 | is blocklen valid? | 203 | astate[i] = sbox[astate[i]]; |
1168 | */ | 204 | } |
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 | 205 | ||
1187 | /* | 206 | // Our code actually stores "columns" (in aes encryption terminology) |
1188 | store IV [ciphertext] for a future block | 207 | // of state in rows: first 4 elements are "row 0, col 0", "row 1, col 0". |
1189 | */ | 208 | // "row 2, col 0", "row 3, col 0". The fifth element is "row 0, col 1", |
1190 | for (x = 0; x < ctx->aes.blocklen; x++) { | 209 | // and so on. |
1191 | ctx->aes.IV[x] = ct[x]; | 210 | #define ASTATE(col,row) astate[(col)*4 + (row)] |
1192 | } | ||
1193 | ct += ctx->aes.blocklen; | ||
1194 | pt += ctx->aes.blocklen; | ||
1195 | } | ||
1196 | 211 | ||
1197 | memset_s(tmp, sizeof(tmp), 0x0, sizeof(tmp)); | 212 | // The ShiftRows() function shifts the rows in the state to the left. |
1198 | return len; | 213 | // Each row is shifted with different offset. |
214 | // Offset = Row number. So the first row is not shifted. | ||
215 | static void ShiftRows(unsigned astate[16]) | ||
216 | { | ||
217 | unsigned v; | ||
218 | |||
219 | // Rotate first row 1 columns to left | ||
220 | v = ASTATE(0,1); | ||
221 | ASTATE(0,1) = ASTATE(1,1); | ||
222 | ASTATE(1,1) = ASTATE(2,1); | ||
223 | ASTATE(2,1) = ASTATE(3,1); | ||
224 | ASTATE(3,1) = v; | ||
225 | |||
226 | // Rotate second row 2 columns to left | ||
227 | v = ASTATE(0,2); ASTATE(0,2) = ASTATE(2,2); ASTATE(2,2) = v; | ||
228 | v = ASTATE(1,2); ASTATE(1,2) = ASTATE(3,2); ASTATE(3,2) = v; | ||
229 | |||
230 | // Rotate third row 3 columns to left | ||
231 | v = ASTATE(3,3); | ||
232 | ASTATE(3,3) = ASTATE(2,3); | ||
233 | ASTATE(2,3) = ASTATE(1,3); | ||
234 | ASTATE(1,3) = ASTATE(0,3); | ||
235 | ASTATE(0,3) = v; | ||
1199 | } | 236 | } |
1200 | 237 | ||
1201 | static //bbox | 238 | // MixColumns function mixes the columns of the state matrix |
1202 | int32 psAesDecrypt(psCipherContext_t *ctx, const unsigned char *ct, | 239 | static void MixColumns(unsigned astate[16]) |
1203 | unsigned char *pt, uint32 len) | ||
1204 | { | 240 | { |
1205 | int32 x; | 241 | int i; |
1206 | uint32 i; | 242 | |
1207 | unsigned char tmp[MAXBLOCKSIZE], tmp2[MAXBLOCKSIZE]; | 243 | for (i = 0; i < 16; i += 4) { |
1208 | 244 | unsigned a, b, c, d; | |
1209 | //bbox | 245 | unsigned x, y, z, t; |
1210 | // if (pt == NULL || ct == NULL || ctx == NULL || (len & 0x7) != 0) { | 246 | |
1211 | // psTraceCrypto("Bad parameters to psAesDecrypt\n"); | 247 | a = astate[i + 0]; |
1212 | // return PS_ARG_FAIL; | 248 | b = astate[i + 1]; |
1213 | // } | 249 | c = astate[i + 2]; |
1214 | if ((len & 0x7) != 0) | 250 | d = astate[i + 3]; |
1215 | bb_error_msg_and_die("AES len:%d", len); | 251 | x = (a << 1) ^ b ^ (b << 1) ^ c ^ d; |
1216 | 252 | y = a ^ (b << 1) ^ c ^ (c << 1) ^ d; | |
1217 | /* | 253 | z = a ^ b ^ (c << 1) ^ d ^ (d << 1); |
1218 | is blocklen valid? | 254 | t = a ^ (a << 1) ^ b ^ c ^ (d << 1); |
1219 | */ | 255 | astate[i + 0] = x ^ ((-(int)(x >> 8)) & 0x11b); |
1220 | if (ctx->aes.blocklen < 0 || (ctx->aes.blocklen > | 256 | astate[i + 1] = y ^ ((-(int)(y >> 8)) & 0x11b); |
1221 | (int32)sizeof(ctx->aes.IV))) { | 257 | astate[i + 2] = z ^ ((-(int)(z >> 8)) & 0x11b); |
1222 | psTraceCrypto("Bad blocklen in psAesDecrypt\n"); | 258 | astate[i + 3] = t ^ ((-(int)(t >> 8)) & 0x11b); |
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 | } | 259 | } |
1252 | memset_s(tmp, sizeof(tmp), 0x0, sizeof(tmp)); | ||
1253 | memset_s(tmp2, sizeof(tmp2), 0x0, sizeof(tmp2)); | ||
1254 | |||
1255 | return len; | ||
1256 | } | 260 | } |
1257 | 261 | ||
1258 | #endif /* USE_AES_CBC_EXTERNAL */ | 262 | // The SubBytes Function Substitutes the values in the |
1259 | 263 | // state matrix with values in an S-box. | |
1260 | /******************************************************************************/ | 264 | static void InvSubBytes(unsigned astate[16]) |
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 | { | 265 | { |
1272 | int32 i, j; | 266 | int i; |
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 | 267 | ||
1291 | /* | 268 | for (i = 0; i < 16; i++) |
1292 | setup the forward key | 269 | astate[i] = rsbox[astate[i]]; |
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 | } | 270 | } |
1434 | 271 | ||
1435 | 272 | static void InvShiftRows(unsigned astate[16]) | |
1436 | #ifdef USE_BURN_STACK | ||
1437 | static //bbox | ||
1438 | void psAesEncryptBlock(const unsigned char *pt, unsigned char *ct, | ||
1439 | psAesKey_t *skey) | ||
1440 | { | 273 | { |
1441 | _aes_ecb_encrypt(pt, ct, skey); | 274 | unsigned v; |
1442 | psBurnStack(sizeof(uint32)*8 + sizeof(uint32*) + sizeof(int32)*2); | 275 | |
276 | // Rotate first row 1 columns to right | ||
277 | v = ASTATE(3,1); | ||
278 | ASTATE(3,1) = ASTATE(2,1); | ||
279 | ASTATE(2,1) = ASTATE(1,1); | ||
280 | ASTATE(1,1) = ASTATE(0,1); | ||
281 | ASTATE(0,1) = v; | ||
282 | |||
283 | // Rotate second row 2 columns to right | ||
284 | v = ASTATE(0,2); ASTATE(0,2) = ASTATE(2,2); ASTATE(2,2) = v; | ||
285 | v = ASTATE(1,2); ASTATE(1,2) = ASTATE(3,2); ASTATE(3,2) = v; | ||
286 | |||
287 | // Rotate third row 3 columns to right | ||
288 | v = ASTATE(0,3); | ||
289 | ASTATE(0,3) = ASTATE(1,3); | ||
290 | ASTATE(1,3) = ASTATE(2,3); | ||
291 | ASTATE(2,3) = ASTATE(3,3); | ||
292 | ASTATE(3,3) = v; | ||
1443 | } | 293 | } |
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 | 294 | ||
1460 | Nr = skey->Nr; | 295 | static ALWAYS_INLINE unsigned Multiply(unsigned x) |
1461 | rk = skey->eK; | 296 | { |
297 | unsigned y; | ||
1462 | 298 | ||
1463 | /* | 299 | y = x >> 8; |
1464 | map byte array block to cipher state | 300 | return (x ^ y ^ (y << 1) ^ (y << 3) ^ (y << 4)) & 255; |
1465 | and add initial round key: | 301 | } |
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 | 302 | ||
1472 | #ifndef PS_AES_IMPROVE_PERF_INCREASE_CODESIZE | 303 | // MixColumns function mixes the columns of the state matrix. |
1473 | for (r = 0; ; r++) { | 304 | // The method used to multiply may be difficult to understand for the inexperienced. |
1474 | rk += 4; | 305 | // Please use the references to gain more information. |
1475 | t0 = | 306 | static void InvMixColumns(unsigned astate[16]) |
1476 | Te0(byte(s0, 3)) ^ | 307 | { |
1477 | Te1(byte(s1, 2)) ^ | 308 | int i; |
1478 | Te2(byte(s2, 1)) ^ | 309 | |
1479 | Te3(byte(s3, 0)) ^ | 310 | for (i = 0; i < 16; i += 4) { |
1480 | rk[0]; | 311 | unsigned a, b, c, d; |
1481 | t1 = | 312 | unsigned x, y, z, t; |
1482 | Te0(byte(s1, 3)) ^ | 313 | |
1483 | Te1(byte(s2, 2)) ^ | 314 | a = astate[i + 0]; |
1484 | Te2(byte(s3, 1)) ^ | 315 | b = astate[i + 1]; |
1485 | Te3(byte(s0, 0)) ^ | 316 | c = astate[i + 2]; |
1486 | rk[1]; | 317 | d = astate[i + 3]; |
1487 | t2 = | 318 | x = (a << 1) ^ (a << 2) ^ (a << 3) ^ b ^ (b << 1) ^ (b << 3) |
1488 | Te0(byte(s2, 3)) ^ | 319 | /***/ ^ c ^ (c << 2) ^ (c << 3) ^ d ^ (d << 3); |
1489 | Te1(byte(s3, 2)) ^ | 320 | y = a ^ (a << 3) ^ (b << 1) ^ (b << 2) ^ (b << 3) |
1490 | Te2(byte(s0, 1)) ^ | 321 | /***/ ^ c ^ (c << 1) ^ (c << 3) ^ d ^ (d << 2) ^ (d << 3); |
1491 | Te3(byte(s1, 0)) ^ | 322 | z = a ^ (a << 2) ^ (a << 3) ^ b ^ (b << 3) |
1492 | rk[2]; | 323 | /***/ ^ (c << 1) ^ (c << 2) ^ (c << 3) ^ d ^ (d << 1) ^ (d << 3); |
1493 | t3 = | 324 | t = a ^ (a << 1) ^ (a << 3) ^ b ^ (b << 2) ^ (b << 3) |
1494 | Te0(byte(s3, 3)) ^ | 325 | /***/ ^ c ^ (c << 3) ^ (d << 1) ^ (d << 2) ^ (d << 3); |
1495 | Te1(byte(s0, 2)) ^ | 326 | astate[i + 0] = Multiply(x); |
1496 | Te2(byte(s1, 1)) ^ | 327 | astate[i + 1] = Multiply(y); |
1497 | Te3(byte(s2, 0)) ^ | 328 | astate[i + 2] = Multiply(z); |
1498 | rk[3]; | 329 | astate[i + 3] = Multiply(t); |
1499 | if (r == Nr-2) { | ||
1500 | break; | ||
1501 | } | ||
1502 | s0 = t0; s1 = t1; s2 = t2; s3 = t3; | ||
1503 | } | 330 | } |
1504 | rk += 4; | 331 | } |
1505 | #else /* PS_AES_IMPROVE_PERF_INCREASE_CODESIZE */ | ||
1506 | 332 | ||
1507 | /* | 333 | static void aes_encrypt_1(unsigned astate[16], unsigned rounds, const uint32_t *RoundKey) |
1508 | Nr - 1 full rounds: | 334 | { |
1509 | */ | ||
1510 | r = Nr >> 1; | ||
1511 | for (;;) { | 335 | for (;;) { |
1512 | 336 | AddRoundKey(astate, RoundKey); | |
1513 | t0 = | 337 | RoundKey += 4; |
1514 | Te0(byte(s0, 3)) ^ | 338 | SubBytes(astate); |
1515 | Te1(byte(s1, 2)) ^ | 339 | ShiftRows(astate); |
1516 | Te2(byte(s2, 1)) ^ | 340 | if (--rounds == 0) |
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; | 341 | break; |
1541 | } | 342 | MixColumns(astate); |
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 | } | 343 | } |
1568 | #endif /* PS_AES_IMPROVE_PERF_INCREASE_CODESIZE */ | 344 | AddRoundKey(astate, RoundKey); |
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 | } | 345 | } |
1602 | 346 | ||
1603 | #ifdef USE_BURN_STACK | 347 | #if 0 // UNUSED |
1604 | static //bbox | 348 | static void aes_encrypt_one_block(unsigned rounds, const uint32_t *RoundKey, const void *data, void *dst) |
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 | { | 349 | { |
1619 | uint32 s0, s1, s2, s3, t0, t1, t2, t3, *rk; | 350 | unsigned astate[16]; |
1620 | int32 Nr, r; | 351 | unsigned i; |
1621 | 352 | ||
1622 | //bbox | 353 | const uint8_t *pt = data; |
1623 | // if (pt == NULL || ct == NULL || skey == NULL) { | 354 | uint8_t *ct = dst; |
1624 | // return; | ||
1625 | // } | ||
1626 | 355 | ||
1627 | Nr = skey->Nr; | 356 | for (i = 0; i < 16; i++) |
1628 | rk = skey->dK; | 357 | astate[i] = pt[i]; |
358 | aes_encrypt_1(astate, rounds, RoundKey); | ||
359 | for (i = 0; i < 16; i++) | ||
360 | ct[i] = astate[i]; | ||
361 | } | ||
362 | #endif | ||
1629 | 363 | ||
1630 | /* | 364 | void aes_cbc_encrypt(const void *key, int klen, void *iv, const void *data, size_t len, void *dst) |
1631 | map byte array block to cipher state and add initial round key: | 365 | { |
1632 | */ | 366 | uint32_t RoundKey[60]; |
1633 | LOAD32H(s0, ct ); s0 ^= rk[0]; | 367 | uint8_t iv2[16]; |
1634 | LOAD32H(s1, ct + 4); s1 ^= rk[1]; | 368 | unsigned rounds; |
1635 | LOAD32H(s2, ct + 8); s2 ^= rk[2]; | 369 | |
1636 | LOAD32H(s3, ct + 12); s3 ^= rk[3]; | 370 | const uint8_t *pt = data; |
371 | uint8_t *ct = dst; | ||
372 | |||
373 | memcpy(iv2, iv, 16); | ||
374 | rounds = KeyExpansion(RoundKey, key, klen); | ||
375 | while (len > 0) { | ||
376 | { | ||
377 | /* almost aes_encrypt_one_block(rounds, RoundKey, pt, ct); | ||
378 | * but xor'ing of IV with plaintext[] is combined | ||
379 | * with plaintext[] -> astate[] | ||
380 | */ | ||
381 | int i; | ||
382 | unsigned astate[16]; | ||
383 | for (i = 0; i < 16; i++) | ||
384 | astate[i] = pt[i] ^ iv2[i]; | ||
385 | aes_encrypt_1(astate, rounds, RoundKey); | ||
386 | for (i = 0; i < 16; i++) | ||
387 | iv2[i] = ct[i] = astate[i]; | ||
388 | } | ||
389 | ct += 16; | ||
390 | pt += 16; | ||
391 | len -= 16; | ||
392 | } | ||
393 | } | ||
1637 | 394 | ||
1638 | #ifndef PS_AES_IMPROVE_PERF_INCREASE_CODESIZE | 395 | static void aes_decrypt_1(unsigned astate[16], unsigned rounds, const uint32_t *RoundKey) |
1639 | for (r = 0; ; r++) { | 396 | { |
1640 | rk += 4; | 397 | RoundKey += rounds * 4; |
1641 | t0 = | 398 | AddRoundKey(astate, RoundKey); |
1642 | Td0(byte(s0, 3)) ^ | 399 | for (;;) { |
1643 | Td1(byte(s3, 2)) ^ | 400 | InvShiftRows(astate); |
1644 | Td2(byte(s2, 1)) ^ | 401 | InvSubBytes(astate); |
1645 | Td3(byte(s1, 0)) ^ | 402 | RoundKey -= 4; |
1646 | rk[0]; | 403 | AddRoundKey(astate, RoundKey); |
1647 | t1 = | 404 | if (--rounds == 0) |
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; | 405 | break; |
1667 | } | 406 | InvMixColumns(astate); |
1668 | s0 = t0; s1 = t1; s2 = t2; s3 = t3; | ||
1669 | } | 407 | } |
1670 | rk += 4; | 408 | } |
1671 | 409 | ||
1672 | #else /* PS_AES_IMPROVE_PERF_INCREASE_CODESIZE */ | 410 | #if 0 //UNUSED |
411 | static void aes_decrypt_one_block(unsigned rounds, const uint32_t *RoundKey, const void *data, void *dst) | ||
412 | { | ||
413 | unsigned astate[16]; | ||
414 | unsigned i; | ||
1673 | 415 | ||
1674 | /* | 416 | const uint8_t *ct = data; |
1675 | Nr - 1 full rounds: | 417 | uint8_t *pt = dst; |
1676 | */ | ||
1677 | r = Nr >> 1; | ||
1678 | for (;;) { | ||
1679 | 418 | ||
1680 | t0 = | 419 | for (i = 0; i < 16; i++) |
1681 | Td0(byte(s0, 3)) ^ | 420 | astate[i] = ct[i]; |
1682 | Td1(byte(s3, 2)) ^ | 421 | aes_decrypt_1(astate, rounds, RoundKey); |
1683 | Td2(byte(s2, 1)) ^ | 422 | for (i = 0; i < 16; i++) |
1684 | Td3(byte(s1, 0)) ^ | 423 | pt[i] = astate[i]; |
1685 | rk[4]; | 424 | } |
1686 | t1 = | 425 | #endif |
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 | 426 | ||
1705 | rk += 8; | 427 | void aes_cbc_decrypt(const void *key, int klen, void *iv, const void *data, size_t len, void *dst) |
1706 | if (--r == 0) { | 428 | { |
1707 | break; | 429 | uint32_t RoundKey[60]; |
430 | uint8_t iv2[16]; | ||
431 | uint8_t iv3[16]; | ||
432 | unsigned rounds; | ||
433 | uint8_t *ivbuf; | ||
434 | uint8_t *ivnext; | ||
435 | |||
436 | const uint8_t *ct = data; | ||
437 | uint8_t *pt = dst; | ||
438 | |||
439 | rounds = KeyExpansion(RoundKey, key, klen); | ||
440 | ivbuf = memcpy(iv2, iv, 16); | ||
441 | while (len) { | ||
442 | ivnext = (ivbuf==iv2) ? iv3 : iv2; | ||
443 | { | ||
444 | /* almost aes_decrypt_one_block(rounds, RoundKey, ct, pt) | ||
445 | * but xor'ing of ivbuf is combined with astate[] -> plaintext[] | ||
446 | */ | ||
447 | int i; | ||
448 | unsigned astate[16]; | ||
449 | for (i = 0; i < 16; i++) | ||
450 | ivnext[i] = astate[i] = ct[i]; | ||
451 | aes_decrypt_1(astate, rounds, RoundKey); | ||
452 | for (i = 0; i < 16; i++) | ||
453 | pt[i] = astate[i] ^ ivbuf[i]; | ||
1708 | } | 454 | } |
1709 | 455 | ivbuf = ivnext; | |
1710 | s0 = | 456 | ct += 16; |
1711 | Td0(byte(t0, 3)) ^ | 457 | pt += 16; |
1712 | Td1(byte(t3, 2)) ^ | 458 | len -= 16; |
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 | } | 459 | } |
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 | } | 460 | } |
1769 | |||
1770 | |||
1771 | /******************************************************************************/ | ||
1772 | /******************************************************************************/ | ||
1773 | #endif /* !USE_AES_CBC_EXTERNAL */ | ||
1774 | #endif /* USE_AES */ | ||
1775 | /******************************************************************************/ | ||
1776 | |||
diff --git a/networking/tls_pstm.c b/networking/tls_pstm.c index acd800307..bd5bae0b7 100644 --- a/networking/tls_pstm.c +++ b/networking/tls_pstm.c | |||
@@ -47,7 +47,7 @@ | |||
47 | //#include "../cryptoApi.h" | 47 | //#include "../cryptoApi.h" |
48 | #ifndef DISABLE_PSTM | 48 | #ifndef DISABLE_PSTM |
49 | 49 | ||
50 | static int32 pstm_mul_2d(pstm_int *a, int16 b, pstm_int *c); | 50 | static int32 pstm_mul_2d(pstm_int *a, int b, pstm_int *c); //bbox: was int16 b |
51 | 51 | ||
52 | /******************************************************************************/ | 52 | /******************************************************************************/ |
53 | /* | 53 | /* |
@@ -64,7 +64,7 @@ int32 pstm_init_size(psPool_t *pool, pstm_int * a, uint32 size) | |||
64 | a->dp = xzalloc(sizeof (pstm_digit) * size);//bbox | 64 | a->dp = xzalloc(sizeof (pstm_digit) * size);//bbox |
65 | //bbox a->pool = pool; | 65 | //bbox a->pool = pool; |
66 | a->used = 0; | 66 | a->used = 0; |
67 | a->alloc = (int16)size; | 67 | a->alloc = size; |
68 | a->sign = PSTM_ZPOS; | 68 | a->sign = PSTM_ZPOS; |
69 | /* | 69 | /* |
70 | zero the digits | 70 | zero the digits |
@@ -111,9 +111,9 @@ int32 pstm_init(psPool_t *pool, pstm_int * a) | |||
111 | /* | 111 | /* |
112 | Grow as required | 112 | Grow as required |
113 | */ | 113 | */ |
114 | int32 pstm_grow(pstm_int * a, int16 size) | 114 | int32 pstm_grow(pstm_int * a, int size) |
115 | { | 115 | { |
116 | int16 i; | 116 | int i; //bbox: was int16 |
117 | pstm_digit *tmp; | 117 | pstm_digit *tmp; |
118 | 118 | ||
119 | /* | 119 | /* |
@@ -298,7 +298,7 @@ void pstm_zero(pstm_int * a) | |||
298 | */ | 298 | */ |
299 | int32 pstm_cmp_mag(pstm_int * a, pstm_int * b) | 299 | int32 pstm_cmp_mag(pstm_int * a, pstm_int * b) |
300 | { | 300 | { |
301 | int16 n; | 301 | int n; //bbox: was int16 |
302 | pstm_digit *tmpa, *tmpb; | 302 | pstm_digit *tmpa, *tmpb; |
303 | 303 | ||
304 | /* | 304 | /* |
@@ -406,7 +406,7 @@ int32 pstm_read_unsigned_bin(pstm_int *a, unsigned char *b, int32 c) | |||
406 | c -= excess; | 406 | c -= excess; |
407 | b += excess; | 407 | b += excess; |
408 | } | 408 | } |
409 | a->used = (int16)((c + sizeof(pstm_digit) - 1)/sizeof(pstm_digit)); | 409 | a->used = ((c + sizeof(pstm_digit) - 1)/sizeof(pstm_digit)); |
410 | if (a->alloc < a->used) { | 410 | if (a->alloc < a->used) { |
411 | if (pstm_grow(a, a->used) != PSTM_OKAY) { | 411 | if (pstm_grow(a, a->used) != PSTM_OKAY) { |
412 | return PSTM_MEM; | 412 | return PSTM_MEM; |
@@ -460,9 +460,9 @@ int32 pstm_read_unsigned_bin(pstm_int *a, unsigned char *b, int32 c) | |||
460 | /******************************************************************************/ | 460 | /******************************************************************************/ |
461 | /* | 461 | /* |
462 | */ | 462 | */ |
463 | int16 pstm_count_bits (pstm_int * a) | 463 | int pstm_count_bits (pstm_int * a) |
464 | { | 464 | { |
465 | int16 r; | 465 | int r; //bbox: was int16 |
466 | pstm_digit q; | 466 | pstm_digit q; |
467 | 467 | ||
468 | if (a->used == 0) { | 468 | if (a->used == 0) { |
@@ -500,9 +500,9 @@ void pstm_set(pstm_int *a, pstm_digit b) | |||
500 | /* | 500 | /* |
501 | Right shift | 501 | Right shift |
502 | */ | 502 | */ |
503 | void pstm_rshd(pstm_int *a, int16 x) | 503 | void pstm_rshd(pstm_int *a, int x) |
504 | { | 504 | { |
505 | int16 y; | 505 | int y; //bbox: was int16 |
506 | 506 | ||
507 | /* too many digits just zero and return */ | 507 | /* too many digits just zero and return */ |
508 | if (x >= a->used) { | 508 | if (x >= a->used) { |
@@ -529,9 +529,9 @@ void pstm_rshd(pstm_int *a, int16 x) | |||
529 | /* | 529 | /* |
530 | Shift left a certain amount of digits. | 530 | Shift left a certain amount of digits. |
531 | */ | 531 | */ |
532 | int32 pstm_lshd(pstm_int * a, int16 b) | 532 | int32 pstm_lshd(pstm_int * a, int b) |
533 | { | 533 | { |
534 | int16 x; | 534 | int x; //bbox: was int16 |
535 | int32 res; | 535 | int32 res; |
536 | 536 | ||
537 | /* | 537 | /* |
@@ -582,9 +582,9 @@ int32 pstm_lshd(pstm_int * a, int16 b) | |||
582 | /* | 582 | /* |
583 | computes a = 2**b | 583 | computes a = 2**b |
584 | */ | 584 | */ |
585 | int32 pstm_2expt(pstm_int *a, int16 b) | 585 | int32 pstm_2expt(pstm_int *a, int b) |
586 | { | 586 | { |
587 | int16 z; | 587 | int z; //bbox: was int16 |
588 | 588 | ||
589 | /* zero a as per default */ | 589 | /* zero a as per default */ |
590 | pstm_zero (a); | 590 | pstm_zero (a); |
@@ -619,7 +619,7 @@ int32 pstm_2expt(pstm_int *a, int16 b) | |||
619 | int32 pstm_mul_2(pstm_int * a, pstm_int * b) | 619 | int32 pstm_mul_2(pstm_int * a, pstm_int * b) |
620 | { | 620 | { |
621 | int32 res; | 621 | int32 res; |
622 | int16 x, oldused; | 622 | int x, oldused; //bbox: was int16 |
623 | 623 | ||
624 | /* | 624 | /* |
625 | grow to accomodate result | 625 | grow to accomodate result |
@@ -684,7 +684,7 @@ int32 pstm_mul_2(pstm_int * a, pstm_int * b) | |||
684 | */ | 684 | */ |
685 | int32 s_pstm_sub(pstm_int *a, pstm_int *b, pstm_int *c) | 685 | int32 s_pstm_sub(pstm_int *a, pstm_int *b, pstm_int *c) |
686 | { | 686 | { |
687 | int16 oldbused, oldused; | 687 | int oldbused, oldused; //bbox: was int16 |
688 | int32 x; | 688 | int32 x; |
689 | pstm_word t; | 689 | pstm_word t; |
690 | 690 | ||
@@ -724,7 +724,7 @@ int32 s_pstm_sub(pstm_int *a, pstm_int *b, pstm_int *c) | |||
724 | */ | 724 | */ |
725 | static int32 s_pstm_add(pstm_int *a, pstm_int *b, pstm_int *c) | 725 | static int32 s_pstm_add(pstm_int *a, pstm_int *b, pstm_int *c) |
726 | { | 726 | { |
727 | int16 x, y, oldused; | 727 | int x, y, oldused; //bbox: was int16 |
728 | register pstm_word t, adp, bdp; | 728 | register pstm_word t, adp, bdp; |
729 | 729 | ||
730 | y = a->used; | 730 | y = a->used; |
@@ -781,8 +781,8 @@ static int32 s_pstm_add(pstm_int *a, pstm_int *b, pstm_int *c) | |||
781 | */ | 781 | */ |
782 | int32 pstm_sub(pstm_int *a, pstm_int *b, pstm_int *c) | 782 | int32 pstm_sub(pstm_int *a, pstm_int *b, pstm_int *c) |
783 | { | 783 | { |
784 | int32 res; | 784 | int32 res; |
785 | int16 sa, sb; | 785 | int sa, sb; //bbox: was int16 |
786 | 786 | ||
787 | sa = a->sign; | 787 | sa = a->sign; |
788 | sb = b->sign; | 788 | sb = b->sign; |
@@ -881,7 +881,7 @@ int32 pstm_montgomery_setup(pstm_int *a, pstm_digit *rho) | |||
881 | int32 pstm_montgomery_calc_normalization(pstm_int *a, pstm_int *b) | 881 | int32 pstm_montgomery_calc_normalization(pstm_int *a, pstm_int *b) |
882 | { | 882 | { |
883 | int32 x; | 883 | int32 x; |
884 | int16 bits; | 884 | int bits; //bbox: was int16 |
885 | 885 | ||
886 | /* how many bits of last digit does b use */ | 886 | /* how many bits of last digit does b use */ |
887 | bits = pstm_count_bits (b) % DIGIT_BIT; | 887 | bits = pstm_count_bits (b) % DIGIT_BIT; |
@@ -916,10 +916,10 @@ int32 pstm_montgomery_calc_normalization(pstm_int *a, pstm_int *b) | |||
916 | /* | 916 | /* |
917 | c = a * 2**d | 917 | c = a * 2**d |
918 | */ | 918 | */ |
919 | static int32 pstm_mul_2d(pstm_int *a, int16 b, pstm_int *c) | 919 | static int32 pstm_mul_2d(pstm_int *a, int b, pstm_int *c) |
920 | { | 920 | { |
921 | pstm_digit carry, carrytmp, shift; | 921 | pstm_digit carry, carrytmp, shift; |
922 | int16 x; | 922 | int x; //bbox: was int16 |
923 | 923 | ||
924 | /* copy it */ | 924 | /* copy it */ |
925 | if (pstm_copy(a, c) != PSTM_OKAY) { | 925 | if (pstm_copy(a, c) != PSTM_OKAY) { |
@@ -961,9 +961,9 @@ static int32 pstm_mul_2d(pstm_int *a, int16 b, pstm_int *c) | |||
961 | /* | 961 | /* |
962 | c = a mod 2**d | 962 | c = a mod 2**d |
963 | */ | 963 | */ |
964 | static int32 pstm_mod_2d(pstm_int *a, int16 b, pstm_int *c) | 964 | static int32 pstm_mod_2d(pstm_int *a, int b, pstm_int *c) //bbox: was int16 b |
965 | { | 965 | { |
966 | int16 x; | 966 | int x; //bbox: was int16 |
967 | 967 | ||
968 | /* zero if count less than or equal to zero */ | 968 | /* zero if count less than or equal to zero */ |
969 | if (b <= 0) { | 969 | if (b <= 0) { |
@@ -1001,7 +1001,7 @@ int32 pstm_mul_d(pstm_int *a, pstm_digit b, pstm_int *c) | |||
1001 | { | 1001 | { |
1002 | pstm_word w; | 1002 | pstm_word w; |
1003 | int32 res; | 1003 | int32 res; |
1004 | int16 x, oldused; | 1004 | int x, oldused; //bbox: was int16 |
1005 | 1005 | ||
1006 | if (c->alloc < a->used + 1) { | 1006 | if (c->alloc < a->used + 1) { |
1007 | if ((res = pstm_grow (c, a->used + 1)) != PSTM_OKAY) { | 1007 | if ((res = pstm_grow (c, a->used + 1)) != PSTM_OKAY) { |
@@ -1032,12 +1032,12 @@ int32 pstm_mul_d(pstm_int *a, pstm_digit b, pstm_int *c) | |||
1032 | /* | 1032 | /* |
1033 | c = a / 2**b | 1033 | c = a / 2**b |
1034 | */ | 1034 | */ |
1035 | int32 pstm_div_2d(psPool_t *pool, pstm_int *a, int16 b, pstm_int *c, | 1035 | int32 pstm_div_2d(psPool_t *pool, pstm_int *a, int b, pstm_int *c, |
1036 | pstm_int *d) | 1036 | pstm_int *d) |
1037 | { | 1037 | { |
1038 | pstm_digit D, r, rr; | 1038 | pstm_digit D, r, rr; |
1039 | int32 res; | 1039 | int32 res; |
1040 | int16 x; | 1040 | int x; //bbox: was int16 |
1041 | pstm_int t; | 1041 | pstm_int t; |
1042 | 1042 | ||
1043 | /* if the shift count is <= 0 then we do no work */ | 1043 | /* if the shift count is <= 0 then we do no work */ |
@@ -1120,7 +1120,7 @@ LBL_DONE: | |||
1120 | */ | 1120 | */ |
1121 | int32 pstm_div_2(pstm_int * a, pstm_int * b) | 1121 | int32 pstm_div_2(pstm_int * a, pstm_int * b) |
1122 | { | 1122 | { |
1123 | int16 x, oldused; | 1123 | int x, oldused; //bbox: was int16 |
1124 | 1124 | ||
1125 | if (b->alloc < a->used) { | 1125 | if (b->alloc < a->used) { |
1126 | if (pstm_grow(b, a->used) != PSTM_OKAY) { | 1126 | if (pstm_grow(b, a->used) != PSTM_OKAY) { |
@@ -1166,9 +1166,9 @@ int32 pstm_div_2(pstm_int * a, pstm_int * b) | |||
1166 | /* | 1166 | /* |
1167 | Creates "a" then copies b into it | 1167 | Creates "a" then copies b into it |
1168 | */ | 1168 | */ |
1169 | int32 pstm_init_copy(psPool_t *pool, pstm_int * a, pstm_int * b, int16 toSqr) | 1169 | int32 pstm_init_copy(psPool_t *pool, pstm_int * a, pstm_int * b, int toSqr) |
1170 | { | 1170 | { |
1171 | int16 x; | 1171 | int x; //bbox: was int16 |
1172 | int32 res; | 1172 | int32 res; |
1173 | 1173 | ||
1174 | if (a == b) { | 1174 | if (a == b) { |
@@ -1279,7 +1279,7 @@ int32 pstm_div(psPool_t *pool, pstm_int *a, pstm_int *b, pstm_int *c, | |||
1279 | { | 1279 | { |
1280 | pstm_int q, x, y, t1, t2; | 1280 | pstm_int q, x, y, t1, t2; |
1281 | int32 res; | 1281 | int32 res; |
1282 | int16 n, t, i, norm, neg; | 1282 | int n, t, i, norm, neg; //bbox: was int16 |
1283 | 1283 | ||
1284 | /* is divisor zero ? */ | 1284 | /* is divisor zero ? */ |
1285 | if (pstm_iszero (b) == 1) { | 1285 | if (pstm_iszero (b) == 1) { |
@@ -1531,7 +1531,7 @@ int32 pstm_mulmod(psPool_t *pool, pstm_int *a, pstm_int *b, pstm_int *c, | |||
1531 | pstm_int *d) | 1531 | pstm_int *d) |
1532 | { | 1532 | { |
1533 | int32 res; | 1533 | int32 res; |
1534 | int16 size; | 1534 | int size; //bbox: was int16 |
1535 | pstm_int tmp; | 1535 | pstm_int tmp; |
1536 | 1536 | ||
1537 | /* | 1537 | /* |
@@ -1567,7 +1567,7 @@ int32 pstm_exptmod(psPool_t *pool, pstm_int *G, pstm_int *X, pstm_int *P, | |||
1567 | pstm_digit buf, mp; | 1567 | pstm_digit buf, mp; |
1568 | pstm_digit *paD; | 1568 | pstm_digit *paD; |
1569 | int32 err, bitbuf; | 1569 | int32 err, bitbuf; |
1570 | int16 bitcpy, bitcnt, mode, digidx, x, y, winsize; | 1570 | int bitcpy, bitcnt, mode, digidx, x, y, winsize; //bbox: was int16 |
1571 | uint32 paDlen; | 1571 | uint32 paDlen; |
1572 | 1572 | ||
1573 | /* set window size from what user set as optimization */ | 1573 | /* set window size from what user set as optimization */ |
@@ -1624,7 +1624,7 @@ int32 pstm_exptmod(psPool_t *pool, pstm_int *G, pstm_int *X, pstm_int *P, | |||
1624 | paDlen = ((M[1].used + 3) * 2) * sizeof(pstm_digit); | 1624 | paDlen = ((M[1].used + 3) * 2) * sizeof(pstm_digit); |
1625 | paD = xzalloc(paDlen);//bbox | 1625 | paD = xzalloc(paDlen);//bbox |
1626 | /* | 1626 | /* |
1627 | compute the value at M[1<<(winsize-1)] by squaring M[1] (winsize-1) times | 1627 | compute the value at M[1<<(winsize-1)] by squaring M[1] (winsize-1) times |
1628 | */ | 1628 | */ |
1629 | if (pstm_init_copy(pool, &M[1 << (winsize - 1)], &M[1], 1) != PSTM_OKAY) { | 1629 | if (pstm_init_copy(pool, &M[1 << (winsize - 1)], &M[1], 1) != PSTM_OKAY) { |
1630 | err = PS_MEM_FAIL; | 1630 | err = PS_MEM_FAIL; |
@@ -1804,7 +1804,7 @@ LBL_RES:pstm_clear(&res); | |||
1804 | int32 pstm_add(pstm_int *a, pstm_int *b, pstm_int *c) | 1804 | int32 pstm_add(pstm_int *a, pstm_int *b, pstm_int *c) |
1805 | { | 1805 | { |
1806 | int32 res; | 1806 | int32 res; |
1807 | int16 sa, sb; | 1807 | int sa, sb; //bbox: was int16 |
1808 | 1808 | ||
1809 | /* get sign of both inputs */ | 1809 | /* get sign of both inputs */ |
1810 | sa = a->sign; | 1810 | sa = a->sign; |
@@ -1817,7 +1817,7 @@ int32 pstm_add(pstm_int *a, pstm_int *b, pstm_int *c) | |||
1817 | if ((res = s_pstm_add (a, b, c)) != PSTM_OKAY) { | 1817 | if ((res = s_pstm_add (a, b, c)) != PSTM_OKAY) { |
1818 | return res; | 1818 | return res; |
1819 | } | 1819 | } |
1820 | } else { | 1820 | } else { |
1821 | /* | 1821 | /* |
1822 | one positive, the other negative | 1822 | one positive, the other negative |
1823 | subtract the one with the greater magnitude from the one of the lesser | 1823 | subtract the one with the greater magnitude from the one of the lesser |
@@ -1842,7 +1842,7 @@ int32 pstm_add(pstm_int *a, pstm_int *b, pstm_int *c) | |||
1842 | /* | 1842 | /* |
1843 | reverse an array, used for radix code | 1843 | reverse an array, used for radix code |
1844 | */ | 1844 | */ |
1845 | static void pstm_reverse (unsigned char *s, int16 len) | 1845 | static void pstm_reverse (unsigned char *s, int len) //bbox: was int16 len |
1846 | { | 1846 | { |
1847 | int32 ix, iy; | 1847 | int32 ix, iy; |
1848 | unsigned char t; | 1848 | unsigned char t; |
@@ -1865,7 +1865,7 @@ static void pstm_reverse (unsigned char *s, int16 len) | |||
1865 | int32 pstm_to_unsigned_bin_nr(psPool_t *pool, pstm_int *a, unsigned char *b) | 1865 | int32 pstm_to_unsigned_bin_nr(psPool_t *pool, pstm_int *a, unsigned char *b) |
1866 | { | 1866 | { |
1867 | int32 res; | 1867 | int32 res; |
1868 | int16 x; | 1868 | int x; //bbox: was int16 |
1869 | pstm_int t = { 0 }; | 1869 | pstm_int t = { 0 }; |
1870 | 1870 | ||
1871 | if ((res = pstm_init_copy(pool, &t, a, 0)) != PSTM_OKAY) { | 1871 | if ((res = pstm_init_copy(pool, &t, a, 0)) != PSTM_OKAY) { |
@@ -1890,7 +1890,7 @@ int32 pstm_to_unsigned_bin_nr(psPool_t *pool, pstm_int *a, unsigned char *b) | |||
1890 | int32 pstm_to_unsigned_bin(psPool_t *pool, pstm_int *a, unsigned char *b) | 1890 | int32 pstm_to_unsigned_bin(psPool_t *pool, pstm_int *a, unsigned char *b) |
1891 | { | 1891 | { |
1892 | int32 res; | 1892 | int32 res; |
1893 | int16 x; | 1893 | int x; //bbox: was int16 |
1894 | pstm_int t = { 0 }; | 1894 | pstm_int t = { 0 }; |
1895 | 1895 | ||
1896 | if ((res = pstm_init_copy(pool, &t, a, 0)) != PSTM_OKAY) { | 1896 | if ((res = pstm_init_copy(pool, &t, a, 0)) != PSTM_OKAY) { |
diff --git a/networking/tls_pstm.h b/networking/tls_pstm.h index 3a0fd8ce6..df705adce 100644 --- a/networking/tls_pstm.h +++ b/networking/tls_pstm.h | |||
@@ -122,7 +122,7 @@ | |||
122 | #define PSTM_MAX_SIZE 4096 | 122 | #define PSTM_MAX_SIZE 4096 |
123 | 123 | ||
124 | typedef struct { | 124 | typedef struct { |
125 | int16 used, alloc, sign; | 125 | int used, alloc, sign; //bbox: was int16 |
126 | pstm_digit *dp; | 126 | pstm_digit *dp; |
127 | //bbox psPool_t *pool; | 127 | //bbox psPool_t *pool; |
128 | } pstm_int; | 128 | } pstm_int; |
@@ -154,9 +154,9 @@ extern int32 pstm_init_size(psPool_t *pool, pstm_int * a, uint32 size); | |||
154 | #define pstm_init_copy(pool, a, b, toSqr) \ | 154 | #define pstm_init_copy(pool, a, b, toSqr) \ |
155 | pstm_init_copy( 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, | 156 | extern int32 pstm_init_copy(psPool_t *pool, pstm_int * a, pstm_int * b, |
157 | int16 toSqr); | 157 | int toSqr); //bbox: was int16 toSqr |
158 | 158 | ||
159 | extern int16 pstm_count_bits (pstm_int * a); | 159 | extern int pstm_count_bits (pstm_int * a); //bbox: was returning int16 |
160 | 160 | ||
161 | //bbox: pool unused | 161 | //bbox: pool unused |
162 | #define pstm_init_for_read_unsigned_bin(pool, a, len) \ | 162 | #define pstm_init_for_read_unsigned_bin(pool, a, len) \ |
@@ -178,7 +178,7 @@ 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, | 178 | pstm_int *mp3, pstm_int *mp4, pstm_int *mp5, pstm_int *mp6, |
179 | pstm_int *mp7); | 179 | pstm_int *mp7); |
180 | 180 | ||
181 | extern int32 pstm_grow(pstm_int * a, int16 size); | 181 | extern int32 pstm_grow(pstm_int * a, int size); //bbox: was int16 size |
182 | 182 | ||
183 | extern void pstm_clamp(pstm_int * a); | 183 | extern void pstm_clamp(pstm_int * a); |
184 | 184 | ||
@@ -186,9 +186,9 @@ extern int32 pstm_cmp(pstm_int * a, pstm_int * b); | |||
186 | 186 | ||
187 | extern int32 pstm_cmp_mag(pstm_int * a, pstm_int * b); | 187 | extern int32 pstm_cmp_mag(pstm_int * a, pstm_int * b); |
188 | 188 | ||
189 | extern void pstm_rshd(pstm_int *a, int16 x); | 189 | extern void pstm_rshd(pstm_int *a, int x); //bbox: was int16 x |
190 | 190 | ||
191 | extern int32 pstm_lshd(pstm_int * a, int16 b); | 191 | extern int32 pstm_lshd(pstm_int * a, int b); //bbox: was int16 b |
192 | 192 | ||
193 | //bbox: pool unused | 193 | //bbox: pool unused |
194 | #define pstm_div(pool, a, b, c, d) \ | 194 | #define pstm_div(pool, a, b, c, d) \ |
@@ -199,8 +199,8 @@ extern int32 pstm_div(psPool_t *pool, pstm_int *a, pstm_int *b, pstm_int *c, | |||
199 | //bbox: pool unused | 199 | //bbox: pool unused |
200 | #define pstm_div_2d(pool, a, b, c, d) \ | 200 | #define pstm_div_2d(pool, a, b, c, d) \ |
201 | pstm_div_2d( 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, | 202 | extern int32 pstm_div_2d(psPool_t *pool, pstm_int *a, int b, pstm_int *c, |
203 | pstm_int *d); | 203 | pstm_int *d); //bbox: was int16 b |
204 | 204 | ||
205 | extern int32 pstm_div_2(pstm_int * a, pstm_int * b); | 205 | extern int32 pstm_div_2(pstm_int * a, pstm_int * b); |
206 | 206 | ||
@@ -232,7 +232,7 @@ extern int32 pstm_mulmod(psPool_t *pool, pstm_int *a, pstm_int *b, pstm_int *c, | |||
232 | extern int32 pstm_exptmod(psPool_t *pool, pstm_int *G, pstm_int *X, pstm_int *P, | 232 | extern int32 pstm_exptmod(psPool_t *pool, pstm_int *G, pstm_int *X, pstm_int *P, |
233 | pstm_int *Y); | 233 | pstm_int *Y); |
234 | 234 | ||
235 | extern int32 pstm_2expt(pstm_int *a, int16 b); | 235 | extern int32 pstm_2expt(pstm_int *a, int b); //bbox: was int16 b |
236 | 236 | ||
237 | extern int32 pstm_add(pstm_int *a, pstm_int *b, pstm_int *c); | 237 | extern int32 pstm_add(pstm_int *a, pstm_int *b, pstm_int *c); |
238 | 238 | ||
diff --git a/networking/udhcp/common.h b/networking/udhcp/common.h index a526494d7..ee12cf91b 100644 --- a/networking/udhcp/common.h +++ b/networking/udhcp/common.h | |||
@@ -300,8 +300,8 @@ int udhcp_send_kernel_packet(struct dhcp_packet *dhcp_pkt, | |||
300 | uint32_t dest_nip, int dest_port) FAST_FUNC; | 300 | uint32_t dest_nip, int dest_port) FAST_FUNC; |
301 | 301 | ||
302 | void udhcp_sp_setup(void) FAST_FUNC; | 302 | void udhcp_sp_setup(void) FAST_FUNC; |
303 | int udhcp_sp_fd_set(fd_set *rfds, int extra_fd) FAST_FUNC; | 303 | void udhcp_sp_fd_set(struct pollfd *pfds, int extra_fd) FAST_FUNC; |
304 | int udhcp_sp_read(const fd_set *rfds) FAST_FUNC; | 304 | int udhcp_sp_read(struct pollfd *pfds) FAST_FUNC; |
305 | 305 | ||
306 | int udhcp_read_interface(const char *interface, int *ifindex, uint32_t *nip, uint8_t *mac) FAST_FUNC; | 306 | int udhcp_read_interface(const char *interface, int *ifindex, uint32_t *nip, uint8_t *mac) FAST_FUNC; |
307 | 307 | ||
diff --git a/networking/udhcp/d6_common.h b/networking/udhcp/d6_common.h index eb211ea0f..fcec8c15a 100644 --- a/networking/udhcp/d6_common.h +++ b/networking/udhcp/d6_common.h | |||
@@ -81,9 +81,14 @@ struct d6_option { | |||
81 | #define D6_OPT_RECONF_MSG 19 | 81 | #define D6_OPT_RECONF_MSG 19 |
82 | #define D6_OPT_RECONF_ACCEPT 20 | 82 | #define D6_OPT_RECONF_ACCEPT 20 |
83 | 83 | ||
84 | #define D6_OPT_DNS_SERVERS 23 | ||
85 | #define D6_OPT_DOMAIN_LIST 24 | ||
86 | |||
84 | #define D6_OPT_IA_PD 25 | 87 | #define D6_OPT_IA_PD 25 |
85 | #define D6_OPT_IAPREFIX 26 | 88 | #define D6_OPT_IAPREFIX 26 |
86 | 89 | ||
90 | #define D6_OPT_CLIENT_FQDN 39 | ||
91 | |||
87 | /*** Other shared functions ***/ | 92 | /*** Other shared functions ***/ |
88 | 93 | ||
89 | struct client6_data_t { | 94 | struct client6_data_t { |
@@ -91,10 +96,14 @@ struct client6_data_t { | |||
91 | struct d6_option *ia_na; | 96 | struct d6_option *ia_na; |
92 | char **env_ptr; | 97 | char **env_ptr; |
93 | unsigned env_idx; | 98 | unsigned env_idx; |
99 | /* link-local IPv6 address */ | ||
100 | struct in6_addr ll_ip6; | ||
94 | }; | 101 | }; |
95 | 102 | ||
96 | #define client6_data (*(struct client6_data_t*)(&bb_common_bufsiz1[COMMON_BUFSIZE - sizeof(struct client6_data_t)])) | 103 | #define client6_data (*(struct client6_data_t*)(&bb_common_bufsiz1[COMMON_BUFSIZE - sizeof(struct client6_data_t)])) |
97 | 104 | ||
105 | int FAST_FUNC d6_read_interface(const char *interface, int *ifindex, struct in6_addr *nip6, uint8_t *mac); | ||
106 | |||
98 | int FAST_FUNC d6_listen_socket(int port, const char *inf); | 107 | int FAST_FUNC d6_listen_socket(int port, const char *inf); |
99 | 108 | ||
100 | int FAST_FUNC d6_recv_kernel_packet( | 109 | int FAST_FUNC d6_recv_kernel_packet( |
@@ -112,7 +121,8 @@ int FAST_FUNC d6_send_raw_packet( | |||
112 | int FAST_FUNC d6_send_kernel_packet( | 121 | int FAST_FUNC d6_send_kernel_packet( |
113 | struct d6_packet *d6_pkt, unsigned d6_pkt_size, | 122 | struct d6_packet *d6_pkt, unsigned d6_pkt_size, |
114 | struct in6_addr *src_ipv6, int source_port, | 123 | struct in6_addr *src_ipv6, int source_port, |
115 | struct in6_addr *dst_ipv6, int dest_port | 124 | struct in6_addr *dst_ipv6, int dest_port, |
125 | int ifindex | ||
116 | ); | 126 | ); |
117 | 127 | ||
118 | #if defined CONFIG_UDHCP_DEBUG && CONFIG_UDHCP_DEBUG >= 2 | 128 | #if defined CONFIG_UDHCP_DEBUG && CONFIG_UDHCP_DEBUG >= 2 |
diff --git a/networking/udhcp/d6_dhcpc.c b/networking/udhcp/d6_dhcpc.c index 64339c9b5..18a104c61 100644 --- a/networking/udhcp/d6_dhcpc.c +++ b/networking/udhcp/d6_dhcpc.c | |||
@@ -54,7 +54,9 @@ static const char udhcpc6_longopts[] ALIGN1 = | |||
54 | "request-option\0" Required_argument "O" | 54 | "request-option\0" Required_argument "O" |
55 | "no-default-options\0" No_argument "o" | 55 | "no-default-options\0" No_argument "o" |
56 | "foreground\0" No_argument "f" | 56 | "foreground\0" No_argument "f" |
57 | USE_FOR_MMU( | ||
57 | "background\0" No_argument "b" | 58 | "background\0" No_argument "b" |
59 | ) | ||
58 | /// IF_FEATURE_UDHCPC_ARPING("arping\0" No_argument "a") | 60 | /// IF_FEATURE_UDHCPC_ARPING("arping\0" No_argument "a") |
59 | IF_FEATURE_UDHCP_PORT("client-port\0" Required_argument "P") | 61 | IF_FEATURE_UDHCP_PORT("client-port\0" Required_argument "P") |
60 | ; | 62 | ; |
@@ -86,6 +88,19 @@ enum { | |||
86 | IF_FEATURE_UDHCP_PORT( OPT_P = 1 << OPTBIT_P,) | 88 | IF_FEATURE_UDHCP_PORT( OPT_P = 1 << OPTBIT_P,) |
87 | }; | 89 | }; |
88 | 90 | ||
91 | static const char opt_req[] = { | ||
92 | (D6_OPT_ORO >> 8), (D6_OPT_ORO & 0xff), | ||
93 | 0, 6, | ||
94 | (D6_OPT_DNS_SERVERS >> 8), (D6_OPT_DNS_SERVERS & 0xff), | ||
95 | (D6_OPT_DOMAIN_LIST >> 8), (D6_OPT_DOMAIN_LIST & 0xff), | ||
96 | (D6_OPT_CLIENT_FQDN >> 8), (D6_OPT_CLIENT_FQDN & 0xff) | ||
97 | }; | ||
98 | |||
99 | static const char opt_fqdn_req[] = { | ||
100 | (D6_OPT_CLIENT_FQDN >> 8), (D6_OPT_CLIENT_FQDN & 0xff), | ||
101 | 0, 2, | ||
102 | 0, 0 | ||
103 | }; | ||
89 | 104 | ||
90 | /*** Utility functions ***/ | 105 | /*** Utility functions ***/ |
91 | 106 | ||
@@ -107,8 +122,8 @@ static void *d6_find_option(uint8_t *option, uint8_t *option_end, unsigned code) | |||
107 | /* Does its code match? */ | 122 | /* Does its code match? */ |
108 | if (option[1] == code) | 123 | if (option[1] == code) |
109 | return option; /* yes! */ | 124 | return option; /* yes! */ |
110 | option += option[3] + 4; | ||
111 | len_m4 -= option[3] + 4; | 125 | len_m4 -= option[3] + 4; |
126 | option += option[3] + 4; | ||
112 | } | 127 | } |
113 | return NULL; | 128 | return NULL; |
114 | } | 129 | } |
@@ -139,8 +154,10 @@ static char** new_env(void) | |||
139 | /* put all the parameters into the environment */ | 154 | /* put all the parameters into the environment */ |
140 | static void option_to_env(uint8_t *option, uint8_t *option_end) | 155 | static void option_to_env(uint8_t *option, uint8_t *option_end) |
141 | { | 156 | { |
157 | char *dlist, *ptr; | ||
142 | /* "length minus 4" */ | 158 | /* "length minus 4" */ |
143 | int len_m4 = option_end - option - 4; | 159 | int len_m4 = option_end - option - 4; |
160 | int olen, ooff; | ||
144 | while (len_m4 >= 0) { | 161 | while (len_m4 >= 0) { |
145 | uint32_t v32; | 162 | uint32_t v32; |
146 | char ipv6str[sizeof("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff")]; | 163 | char ipv6str[sizeof("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff")]; |
@@ -217,9 +234,54 @@ static void option_to_env(uint8_t *option, uint8_t *option_end) | |||
217 | 234 | ||
218 | sprint_nip6(ipv6str, option + 4 + 4 + 1); | 235 | sprint_nip6(ipv6str, option + 4 + 4 + 1); |
219 | *new_env() = xasprintf("ipv6prefix=%s/%u", ipv6str, (unsigned)(option[4 + 4])); | 236 | *new_env() = xasprintf("ipv6prefix=%s/%u", ipv6str, (unsigned)(option[4 + 4])); |
237 | break; | ||
238 | case D6_OPT_DNS_SERVERS: | ||
239 | olen = ((option[2] << 8) | option[3]) / 16; | ||
240 | dlist = ptr = malloc (4 + olen * 40 - 1); | ||
241 | |||
242 | memcpy (ptr, "dns=", 4); | ||
243 | ptr += 4; | ||
244 | ooff = 0; | ||
245 | |||
246 | while (olen--) { | ||
247 | sprint_nip6(ptr, option + 4 + ooff); | ||
248 | ptr += 39; | ||
249 | ooff += 16; | ||
250 | if (olen) | ||
251 | *ptr++ = ' '; | ||
252 | } | ||
253 | |||
254 | *new_env() = dlist; | ||
255 | |||
256 | break; | ||
257 | case D6_OPT_DOMAIN_LIST: | ||
258 | dlist = dname_dec(option + 4, (option[2] << 8) | option[3], "search="); | ||
259 | if (!dlist) | ||
260 | break; | ||
261 | *new_env() = dlist; | ||
262 | break; | ||
263 | case D6_OPT_CLIENT_FQDN: | ||
264 | // Work around broken ISC DHCPD6 | ||
265 | if (option[4] & 0xf8) { | ||
266 | olen = ((option[2] << 8) | option[3]); | ||
267 | dlist = xmalloc(olen); | ||
268 | //fixme: | ||
269 | //- explain | ||
270 | //- add len error check | ||
271 | //- merge two allocs into one | ||
272 | memcpy(dlist, option + 4, olen); | ||
273 | *new_env() = xasprintf("fqdn=%s", dlist); | ||
274 | free(dlist); | ||
275 | break; | ||
276 | } | ||
277 | dlist = dname_dec(option + 5, ((option[2] << 8) | option[3]) - 1, "fqdn="); | ||
278 | if (!dlist) | ||
279 | break; | ||
280 | *new_env() = dlist; | ||
281 | break; | ||
220 | } | 282 | } |
221 | option += 4 + option[3]; | ||
222 | len_m4 -= 4 + option[3]; | 283 | len_m4 -= 4 + option[3]; |
284 | option += 4 + option[3]; | ||
223 | } | 285 | } |
224 | } | 286 | } |
225 | 287 | ||
@@ -311,7 +373,7 @@ static int d6_mcast_from_client_config_ifindex(struct d6_packet *packet, uint8_t | |||
311 | 373 | ||
312 | return d6_send_raw_packet( | 374 | return d6_send_raw_packet( |
313 | packet, (end - (uint8_t*) packet), | 375 | packet, (end - (uint8_t*) packet), |
314 | /*src*/ NULL, CLIENT_PORT6, | 376 | /*src*/ &client6_data.ll_ip6, CLIENT_PORT6, |
315 | /*dst*/ (struct in6_addr*)FF02__1_2, SERVER_PORT6, MAC_BCAST_ADDR, | 377 | /*dst*/ (struct in6_addr*)FF02__1_2, SERVER_PORT6, MAC_BCAST_ADDR, |
316 | client_config.ifindex | 378 | client_config.ifindex |
317 | ); | 379 | ); |
@@ -423,6 +485,10 @@ static NOINLINE int send_d6_discover(uint32_t xid, struct in6_addr *requested_ip | |||
423 | } | 485 | } |
424 | opt_ptr = d6_store_blob(opt_ptr, client6_data.ia_na, len); | 486 | opt_ptr = d6_store_blob(opt_ptr, client6_data.ia_na, len); |
425 | 487 | ||
488 | /* Request additional options */ | ||
489 | opt_ptr = d6_store_blob(opt_ptr, &opt_req, sizeof(opt_req)); | ||
490 | opt_ptr = d6_store_blob(opt_ptr, &opt_fqdn_req, sizeof(opt_fqdn_req)); | ||
491 | |||
426 | /* Add options: | 492 | /* Add options: |
427 | * "param req" option according to -O, options specified with -x | 493 | * "param req" option according to -O, options specified with -x |
428 | */ | 494 | */ |
@@ -476,6 +542,10 @@ static NOINLINE int send_d6_select(uint32_t xid) | |||
476 | /* IA NA (contains requested IP) */ | 542 | /* IA NA (contains requested IP) */ |
477 | opt_ptr = d6_store_blob(opt_ptr, client6_data.ia_na, client6_data.ia_na->len + 2+2); | 543 | opt_ptr = d6_store_blob(opt_ptr, client6_data.ia_na, client6_data.ia_na->len + 2+2); |
478 | 544 | ||
545 | /* Request additional options */ | ||
546 | opt_ptr = d6_store_blob(opt_ptr, &opt_req, sizeof(opt_req)); | ||
547 | opt_ptr = d6_store_blob(opt_ptr, &opt_fqdn_req, sizeof(opt_fqdn_req)); | ||
548 | |||
479 | /* Add options: | 549 | /* Add options: |
480 | * "param req" option according to -O, options specified with -x | 550 | * "param req" option according to -O, options specified with -x |
481 | */ | 551 | */ |
@@ -555,7 +625,8 @@ static NOINLINE int send_d6_renew(uint32_t xid, struct in6_addr *server_ipv6, st | |||
555 | return d6_send_kernel_packet( | 625 | return d6_send_kernel_packet( |
556 | &packet, (opt_ptr - (uint8_t*) &packet), | 626 | &packet, (opt_ptr - (uint8_t*) &packet), |
557 | our_cur_ipv6, CLIENT_PORT6, | 627 | our_cur_ipv6, CLIENT_PORT6, |
558 | server_ipv6, SERVER_PORT6 | 628 | server_ipv6, SERVER_PORT6, |
629 | client_config.ifindex | ||
559 | ); | 630 | ); |
560 | return d6_mcast_from_client_config_ifindex(&packet, opt_ptr); | 631 | return d6_mcast_from_client_config_ifindex(&packet, opt_ptr); |
561 | } | 632 | } |
@@ -577,15 +648,14 @@ static int send_d6_release(struct in6_addr *server_ipv6, struct in6_addr *our_cu | |||
577 | return d6_send_kernel_packet( | 648 | return d6_send_kernel_packet( |
578 | &packet, (opt_ptr - (uint8_t*) &packet), | 649 | &packet, (opt_ptr - (uint8_t*) &packet), |
579 | our_cur_ipv6, CLIENT_PORT6, | 650 | our_cur_ipv6, CLIENT_PORT6, |
580 | server_ipv6, SERVER_PORT6 | 651 | server_ipv6, SERVER_PORT6, |
652 | client_config.ifindex | ||
581 | ); | 653 | ); |
582 | } | 654 | } |
583 | 655 | ||
584 | /* Returns -1 on errors that are fatal for the socket, -2 for those that aren't */ | 656 | /* Returns -1 on errors that are fatal for the socket, -2 for those that aren't */ |
585 | /* NOINLINE: limit stack usage in caller */ | 657 | /* NOINLINE: limit stack usage in caller */ |
586 | static NOINLINE int d6_recv_raw_packet(struct in6_addr *peer_ipv6 | 658 | static NOINLINE int d6_recv_raw_packet(struct in6_addr *peer_ipv6, struct d6_packet *d6_pkt, int fd) |
587 | UNUSED_PARAM | ||
588 | , struct d6_packet *d6_pkt, int fd) | ||
589 | { | 659 | { |
590 | int bytes; | 660 | int bytes; |
591 | struct ip6_udp_d6_packet packet; | 661 | struct ip6_udp_d6_packet packet; |
@@ -634,6 +704,9 @@ static NOINLINE int d6_recv_raw_packet(struct in6_addr *peer_ipv6 | |||
634 | // return -2; | 704 | // return -2; |
635 | // } | 705 | // } |
636 | 706 | ||
707 | if (peer_ipv6) | ||
708 | *peer_ipv6 = packet.ip6.ip6_src; /* struct copy */ | ||
709 | |||
637 | log1("received %s", "a packet"); | 710 | log1("received %s", "a packet"); |
638 | d6_dump_packet(&packet.data); | 711 | d6_dump_packet(&packet.data); |
639 | 712 | ||
@@ -935,9 +1008,7 @@ int udhcpc6_main(int argc UNUSED_PARAM, char **argv) | |||
935 | int timeout; /* must be signed */ | 1008 | int timeout; /* must be signed */ |
936 | unsigned already_waited_sec; | 1009 | unsigned already_waited_sec; |
937 | unsigned opt; | 1010 | unsigned opt; |
938 | int max_fd; | ||
939 | int retval; | 1011 | int retval; |
940 | fd_set rfds; | ||
941 | 1012 | ||
942 | setup_common_bufsiz(); | 1013 | setup_common_bufsiz(); |
943 | 1014 | ||
@@ -1003,11 +1074,13 @@ int udhcpc6_main(int argc UNUSED_PARAM, char **argv) | |||
1003 | /* now it looks similar to udhcpd's config file line: | 1074 | /* now it looks similar to udhcpd's config file line: |
1004 | * "optname optval", using the common routine: */ | 1075 | * "optname optval", using the common routine: */ |
1005 | udhcp_str2optset(optstr, &client_config.options); | 1076 | udhcp_str2optset(optstr, &client_config.options); |
1077 | if (colon) | ||
1078 | *colon = ':'; /* restore it for NOMMU reexec */ | ||
1006 | } | 1079 | } |
1007 | 1080 | ||
1008 | if (udhcp_read_interface(client_config.interface, | 1081 | if (d6_read_interface(client_config.interface, |
1009 | &client_config.ifindex, | 1082 | &client_config.ifindex, |
1010 | NULL, | 1083 | &client6_data.ll_ip6, |
1011 | client_config.client_mac) | 1084 | client_config.client_mac) |
1012 | ) { | 1085 | ) { |
1013 | return 1; | 1086 | return 1; |
@@ -1063,7 +1136,8 @@ int udhcpc6_main(int argc UNUSED_PARAM, char **argv) | |||
1063 | * "continue" statements in code below jump to the top of the loop. | 1136 | * "continue" statements in code below jump to the top of the loop. |
1064 | */ | 1137 | */ |
1065 | for (;;) { | 1138 | for (;;) { |
1066 | struct timeval tv; | 1139 | int tv; |
1140 | struct pollfd pfds[2]; | ||
1067 | struct d6_packet packet; | 1141 | struct d6_packet packet; |
1068 | uint8_t *packet_end; | 1142 | uint8_t *packet_end; |
1069 | /* silence "uninitialized!" warning */ | 1143 | /* silence "uninitialized!" warning */ |
@@ -1078,16 +1152,15 @@ int udhcpc6_main(int argc UNUSED_PARAM, char **argv) | |||
1078 | * to change_listen_mode(). Thus we open listen socket | 1152 | * to change_listen_mode(). Thus we open listen socket |
1079 | * BEFORE we send renew request (see "case BOUND:"). */ | 1153 | * BEFORE we send renew request (see "case BOUND:"). */ |
1080 | 1154 | ||
1081 | max_fd = udhcp_sp_fd_set(&rfds, sockfd); | 1155 | udhcp_sp_fd_set(pfds, sockfd); |
1082 | 1156 | ||
1083 | tv.tv_sec = timeout - already_waited_sec; | 1157 | tv = timeout - already_waited_sec; |
1084 | tv.tv_usec = 0; | ||
1085 | retval = 0; | 1158 | retval = 0; |
1086 | /* If we already timed out, fall through with retval = 0, else... */ | 1159 | /* If we already timed out, fall through with retval = 0, else... */ |
1087 | if ((int)tv.tv_sec > 0) { | 1160 | if (tv > 0) { |
1088 | log1("waiting on select %u seconds", (int)tv.tv_sec); | 1161 | log1("waiting on select %u seconds", tv); |
1089 | timestamp_before_wait = (unsigned)monotonic_sec(); | 1162 | timestamp_before_wait = (unsigned)monotonic_sec(); |
1090 | retval = select(max_fd + 1, &rfds, NULL, NULL, &tv); | 1163 | retval = poll(pfds, 2, tv < INT_MAX/1000 ? tv * 1000 : INT_MAX); |
1091 | if (retval < 0) { | 1164 | if (retval < 0) { |
1092 | /* EINTR? A signal was caught, don't panic */ | 1165 | /* EINTR? A signal was caught, don't panic */ |
1093 | if (errno == EINTR) { | 1166 | if (errno == EINTR) { |
@@ -1108,13 +1181,14 @@ int udhcpc6_main(int argc UNUSED_PARAM, char **argv) | |||
1108 | * or if the status of the bridge changed). | 1181 | * or if the status of the bridge changed). |
1109 | * Refresh ifindex and client_mac: | 1182 | * Refresh ifindex and client_mac: |
1110 | */ | 1183 | */ |
1111 | if (udhcp_read_interface(client_config.interface, | 1184 | if (d6_read_interface(client_config.interface, |
1112 | &client_config.ifindex, | 1185 | &client_config.ifindex, |
1113 | NULL, | 1186 | &client6_data.ll_ip6, |
1114 | client_config.client_mac) | 1187 | client_config.client_mac) |
1115 | ) { | 1188 | ) { |
1116 | goto ret0; /* iface is gone? */ | 1189 | goto ret0; /* iface is gone? */ |
1117 | } | 1190 | } |
1191 | |||
1118 | memcpy(clientid_mac_ptr, client_config.client_mac, 6); | 1192 | memcpy(clientid_mac_ptr, client_config.client_mac, 6); |
1119 | 1193 | ||
1120 | /* We will restart the wait in any case */ | 1194 | /* We will restart the wait in any case */ |
@@ -1222,8 +1296,8 @@ int udhcpc6_main(int argc UNUSED_PARAM, char **argv) | |||
1222 | /* select() didn't timeout, something happened */ | 1296 | /* select() didn't timeout, something happened */ |
1223 | 1297 | ||
1224 | /* Is it a signal? */ | 1298 | /* Is it a signal? */ |
1225 | /* note: udhcp_sp_read checks FD_ISSET before reading */ | 1299 | /* note: udhcp_sp_read checks poll result before reading */ |
1226 | switch (udhcp_sp_read(&rfds)) { | 1300 | switch (udhcp_sp_read(pfds)) { |
1227 | case SIGUSR1: | 1301 | case SIGUSR1: |
1228 | client_config.first_secs = 0; /* make secs field count from 0 */ | 1302 | client_config.first_secs = 0; /* make secs field count from 0 */ |
1229 | already_waited_sec = 0; | 1303 | already_waited_sec = 0; |
@@ -1258,7 +1332,7 @@ int udhcpc6_main(int argc UNUSED_PARAM, char **argv) | |||
1258 | } | 1332 | } |
1259 | 1333 | ||
1260 | /* Is it a packet? */ | 1334 | /* Is it a packet? */ |
1261 | if (listen_mode == LISTEN_NONE || !FD_ISSET(sockfd, &rfds)) | 1335 | if (listen_mode == LISTEN_NONE || !pfds[1].revents) |
1262 | continue; /* no */ | 1336 | continue; /* no */ |
1263 | 1337 | ||
1264 | { | 1338 | { |
@@ -1307,7 +1381,7 @@ int udhcpc6_main(int argc UNUSED_PARAM, char **argv) | |||
1307 | struct d6_option *option, *iaaddr; | 1381 | struct d6_option *option, *iaaddr; |
1308 | type_is_ok: | 1382 | type_is_ok: |
1309 | option = d6_find_option(packet.d6_options, packet_end, D6_OPT_STATUS_CODE); | 1383 | option = d6_find_option(packet.d6_options, packet_end, D6_OPT_STATUS_CODE); |
1310 | if (option && option->data[4] != 0) { | 1384 | if (option && (option->data[0] | option->data[1]) != 0) { |
1311 | /* return to init state */ | 1385 | /* return to init state */ |
1312 | bb_error_msg("received DHCP NAK (%u)", option->data[4]); | 1386 | bb_error_msg("received DHCP NAK (%u)", option->data[4]); |
1313 | d6_run_script(&packet, "nak"); | 1387 | d6_run_script(&packet, "nak"); |
@@ -1460,8 +1534,8 @@ int udhcpc6_main(int argc UNUSED_PARAM, char **argv) | |||
1460 | if (lease_seconds < 0x10) | 1534 | if (lease_seconds < 0x10) |
1461 | lease_seconds = 0x10; | 1535 | lease_seconds = 0x10; |
1462 | /// TODO: check for 0 lease time? | 1536 | /// TODO: check for 0 lease time? |
1463 | if (lease_seconds >= 0x10000000) | 1537 | if (lease_seconds > 0x7fffffff / 1000) |
1464 | lease_seconds = 0x0fffffff; | 1538 | lease_seconds = 0x7fffffff / 1000; |
1465 | /* enter bound state */ | 1539 | /* enter bound state */ |
1466 | timeout = lease_seconds / 2; | 1540 | timeout = lease_seconds / 2; |
1467 | bb_error_msg("lease obtained, lease time %u", | 1541 | bb_error_msg("lease obtained, lease time %u", |
diff --git a/networking/udhcp/d6_packet.c b/networking/udhcp/d6_packet.c index e166f520d..79a0ac8a8 100644 --- a/networking/udhcp/d6_packet.c +++ b/networking/udhcp/d6_packet.c | |||
@@ -127,7 +127,8 @@ int FAST_FUNC d6_send_raw_packet( | |||
127 | int FAST_FUNC d6_send_kernel_packet( | 127 | int FAST_FUNC d6_send_kernel_packet( |
128 | struct d6_packet *d6_pkt, unsigned d6_pkt_size, | 128 | struct d6_packet *d6_pkt, unsigned d6_pkt_size, |
129 | struct in6_addr *src_ipv6, int source_port, | 129 | struct in6_addr *src_ipv6, int source_port, |
130 | struct in6_addr *dst_ipv6, int dest_port) | 130 | struct in6_addr *dst_ipv6, int dest_port, |
131 | int ifindex) | ||
131 | { | 132 | { |
132 | struct sockaddr_in6 sa; | 133 | struct sockaddr_in6 sa; |
133 | int fd; | 134 | int fd; |
@@ -154,6 +155,7 @@ int FAST_FUNC d6_send_kernel_packet( | |||
154 | sa.sin6_family = AF_INET6; | 155 | sa.sin6_family = AF_INET6; |
155 | sa.sin6_port = htons(dest_port); | 156 | sa.sin6_port = htons(dest_port); |
156 | sa.sin6_addr = *dst_ipv6; /* struct copy */ | 157 | sa.sin6_addr = *dst_ipv6; /* struct copy */ |
158 | sa.sin6_scope_id = ifindex; | ||
157 | if (connect(fd, (struct sockaddr *)&sa, sizeof(sa)) == -1) { | 159 | if (connect(fd, (struct sockaddr *)&sa, sizeof(sa)) == -1) { |
158 | msg = "connect"; | 160 | msg = "connect"; |
159 | goto ret_close; | 161 | goto ret_close; |
diff --git a/networking/udhcp/d6_socket.c b/networking/udhcp/d6_socket.c index 910f296a3..930e5e4f5 100644 --- a/networking/udhcp/d6_socket.c +++ b/networking/udhcp/d6_socket.c | |||
@@ -7,6 +7,67 @@ | |||
7 | #include "common.h" | 7 | #include "common.h" |
8 | #include "d6_common.h" | 8 | #include "d6_common.h" |
9 | #include <net/if.h> | 9 | #include <net/if.h> |
10 | #include <ifaddrs.h> | ||
11 | #include <netpacket/packet.h> | ||
12 | |||
13 | int FAST_FUNC d6_read_interface(const char *interface, int *ifindex, struct in6_addr *nip6, uint8_t *mac) | ||
14 | { | ||
15 | int retval = 3; | ||
16 | struct ifaddrs *ifap, *ifa; | ||
17 | |||
18 | getifaddrs(&ifap); | ||
19 | |||
20 | for (ifa = ifap; ifa; ifa = ifa->ifa_next) { | ||
21 | struct sockaddr_in6 *sip6; | ||
22 | |||
23 | if (!ifa->ifa_addr || (strcmp(ifa->ifa_name, interface) != 0)) | ||
24 | continue; | ||
25 | |||
26 | sip6 = (struct sockaddr_in6*)(ifa->ifa_addr); | ||
27 | |||
28 | if (ifa->ifa_addr->sa_family == AF_PACKET) { | ||
29 | struct sockaddr_ll *sll = (struct sockaddr_ll*)(ifa->ifa_addr); | ||
30 | memcpy(mac, sll->sll_addr, 6); | ||
31 | log1("MAC %02x:%02x:%02x:%02x:%02x:%02x", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); | ||
32 | log1("adapter index %d", sll->sll_ifindex); | ||
33 | *ifindex = sll->sll_ifindex; | ||
34 | retval &= (0xf - (1<<0)); | ||
35 | } | ||
36 | #if 0 | ||
37 | if (ifa->ifa_addr->sa_family == AF_INET) { | ||
38 | *nip = ((struct sockaddr_in *)ifa->ifa_addr)->sin_addr.s_addr; | ||
39 | log1("IP %s", inet_ntoa(((struct sockaddr_in *)ifa->ifa_addr)->sin_addr)); | ||
40 | } | ||
41 | #endif | ||
42 | if (ifa->ifa_addr->sa_family == AF_INET6 | ||
43 | && IN6_IS_ADDR_LINKLOCAL(&sip6->sin6_addr) | ||
44 | ) { | ||
45 | *nip6 = sip6->sin6_addr; /* struct copy */ | ||
46 | log1( | ||
47 | "IPv6 %02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x", | ||
48 | nip6->s6_addr[0], nip6->s6_addr[1], | ||
49 | nip6->s6_addr[2], nip6->s6_addr[3], | ||
50 | nip6->s6_addr[4], nip6->s6_addr[5], | ||
51 | nip6->s6_addr[6], nip6->s6_addr[7], | ||
52 | nip6->s6_addr[8], nip6->s6_addr[9], | ||
53 | nip6->s6_addr[10], nip6->s6_addr[11], | ||
54 | nip6->s6_addr[12], nip6->s6_addr[13], | ||
55 | nip6->s6_addr[14], nip6->s6_addr[15] | ||
56 | ); | ||
57 | retval &= (0xf - (1<<1)); | ||
58 | } | ||
59 | } | ||
60 | |||
61 | freeifaddrs(ifap); | ||
62 | if (retval == 0) | ||
63 | return retval; | ||
64 | |||
65 | if (retval & (1<<0)) | ||
66 | bb_error_msg("can't get %s", "MAC"); | ||
67 | if (retval & (1<<1)) | ||
68 | bb_error_msg("can't get %s", "link-local IPv6 address"); | ||
69 | return -1; | ||
70 | } | ||
10 | 71 | ||
11 | int FAST_FUNC d6_listen_socket(int port, const char *inf) | 72 | int FAST_FUNC d6_listen_socket(int port, const char *inf) |
12 | { | 73 | { |
diff --git a/networking/udhcp/dhcpc.c b/networking/udhcp/dhcpc.c index 0e236261b..6aa6731fb 100644 --- a/networking/udhcp/dhcpc.c +++ b/networking/udhcp/dhcpc.c | |||
@@ -73,7 +73,9 @@ static const char udhcpc_longopts[] ALIGN1 = | |||
73 | "request-option\0" Required_argument "O" | 73 | "request-option\0" Required_argument "O" |
74 | "no-default-options\0" No_argument "o" | 74 | "no-default-options\0" No_argument "o" |
75 | "foreground\0" No_argument "f" | 75 | "foreground\0" No_argument "f" |
76 | USE_FOR_MMU( | ||
76 | "background\0" No_argument "b" | 77 | "background\0" No_argument "b" |
78 | ) | ||
77 | "broadcast\0" No_argument "B" | 79 | "broadcast\0" No_argument "B" |
78 | IF_FEATURE_UDHCPC_ARPING("arping\0" Optional_argument "a") | 80 | IF_FEATURE_UDHCPC_ARPING("arping\0" Optional_argument "a") |
79 | IF_FEATURE_UDHCP_PORT("client-port\0" Required_argument "P") | 81 | IF_FEATURE_UDHCP_PORT("client-port\0" Required_argument "P") |
@@ -1281,9 +1283,7 @@ int udhcpc_main(int argc UNUSED_PARAM, char **argv) | |||
1281 | unsigned already_waited_sec; | 1283 | unsigned already_waited_sec; |
1282 | unsigned opt; | 1284 | unsigned opt; |
1283 | IF_FEATURE_UDHCPC_ARPING(unsigned arpping_ms;) | 1285 | IF_FEATURE_UDHCPC_ARPING(unsigned arpping_ms;) |
1284 | int max_fd; | ||
1285 | int retval; | 1286 | int retval; |
1286 | fd_set rfds; | ||
1287 | 1287 | ||
1288 | setup_common_bufsiz(); | 1288 | setup_common_bufsiz(); |
1289 | 1289 | ||
@@ -1367,6 +1367,8 @@ int udhcpc_main(int argc UNUSED_PARAM, char **argv) | |||
1367 | /* now it looks similar to udhcpd's config file line: | 1367 | /* now it looks similar to udhcpd's config file line: |
1368 | * "optname optval", using the common routine: */ | 1368 | * "optname optval", using the common routine: */ |
1369 | udhcp_str2optset(optstr, &client_config.options); | 1369 | udhcp_str2optset(optstr, &client_config.options); |
1370 | if (colon) | ||
1371 | *colon = ':'; /* restore it for NOMMU reexec */ | ||
1370 | } | 1372 | } |
1371 | 1373 | ||
1372 | if (udhcp_read_interface(client_config.interface, | 1374 | if (udhcp_read_interface(client_config.interface, |
@@ -1432,7 +1434,8 @@ int udhcpc_main(int argc UNUSED_PARAM, char **argv) | |||
1432 | * "continue" statements in code below jump to the top of the loop. | 1434 | * "continue" statements in code below jump to the top of the loop. |
1433 | */ | 1435 | */ |
1434 | for (;;) { | 1436 | for (;;) { |
1435 | struct timeval tv; | 1437 | int tv; |
1438 | struct pollfd pfds[2]; | ||
1436 | struct dhcp_packet packet; | 1439 | struct dhcp_packet packet; |
1437 | /* silence "uninitialized!" warning */ | 1440 | /* silence "uninitialized!" warning */ |
1438 | unsigned timestamp_before_wait = timestamp_before_wait; | 1441 | unsigned timestamp_before_wait = timestamp_before_wait; |
@@ -1446,23 +1449,22 @@ int udhcpc_main(int argc UNUSED_PARAM, char **argv) | |||
1446 | * to change_listen_mode(). Thus we open listen socket | 1449 | * to change_listen_mode(). Thus we open listen socket |
1447 | * BEFORE we send renew request (see "case BOUND:"). */ | 1450 | * BEFORE we send renew request (see "case BOUND:"). */ |
1448 | 1451 | ||
1449 | max_fd = udhcp_sp_fd_set(&rfds, sockfd); | 1452 | udhcp_sp_fd_set(pfds, sockfd); |
1450 | 1453 | ||
1451 | tv.tv_sec = timeout - already_waited_sec; | 1454 | tv = timeout - already_waited_sec; |
1452 | tv.tv_usec = 0; | ||
1453 | retval = 0; | 1455 | retval = 0; |
1454 | /* If we already timed out, fall through with retval = 0, else... */ | 1456 | /* If we already timed out, fall through with retval = 0, else... */ |
1455 | if ((int)tv.tv_sec > 0) { | 1457 | if (tv > 0) { |
1456 | log1("waiting on select %u seconds", (int)tv.tv_sec); | 1458 | log1("waiting on select %u seconds", tv); |
1457 | timestamp_before_wait = (unsigned)monotonic_sec(); | 1459 | timestamp_before_wait = (unsigned)monotonic_sec(); |
1458 | retval = select(max_fd + 1, &rfds, NULL, NULL, &tv); | 1460 | retval = poll(pfds, 2, tv < INT_MAX/1000 ? tv * 1000 : INT_MAX); |
1459 | if (retval < 0) { | 1461 | if (retval < 0) { |
1460 | /* EINTR? A signal was caught, don't panic */ | 1462 | /* EINTR? A signal was caught, don't panic */ |
1461 | if (errno == EINTR) { | 1463 | if (errno == EINTR) { |
1462 | already_waited_sec += (unsigned)monotonic_sec() - timestamp_before_wait; | 1464 | already_waited_sec += (unsigned)monotonic_sec() - timestamp_before_wait; |
1463 | continue; | 1465 | continue; |
1464 | } | 1466 | } |
1465 | /* Else: an error occured, panic! */ | 1467 | /* Else: an error occurred, panic! */ |
1466 | bb_perror_msg_and_die("select"); | 1468 | bb_perror_msg_and_die("select"); |
1467 | } | 1469 | } |
1468 | } | 1470 | } |
@@ -1591,8 +1593,8 @@ int udhcpc_main(int argc UNUSED_PARAM, char **argv) | |||
1591 | /* select() didn't timeout, something happened */ | 1593 | /* select() didn't timeout, something happened */ |
1592 | 1594 | ||
1593 | /* Is it a signal? */ | 1595 | /* Is it a signal? */ |
1594 | /* note: udhcp_sp_read checks FD_ISSET before reading */ | 1596 | /* note: udhcp_sp_read checks poll result before reading */ |
1595 | switch (udhcp_sp_read(&rfds)) { | 1597 | switch (udhcp_sp_read(pfds)) { |
1596 | case SIGUSR1: | 1598 | case SIGUSR1: |
1597 | client_config.first_secs = 0; /* make secs field count from 0 */ | 1599 | client_config.first_secs = 0; /* make secs field count from 0 */ |
1598 | already_waited_sec = 0; | 1600 | already_waited_sec = 0; |
@@ -1627,7 +1629,7 @@ int udhcpc_main(int argc UNUSED_PARAM, char **argv) | |||
1627 | } | 1629 | } |
1628 | 1630 | ||
1629 | /* Is it a packet? */ | 1631 | /* Is it a packet? */ |
1630 | if (listen_mode == LISTEN_NONE || !FD_ISSET(sockfd, &rfds)) | 1632 | if (listen_mode == LISTEN_NONE || !pfds[1].revents) |
1631 | continue; /* no */ | 1633 | continue; /* no */ |
1632 | 1634 | ||
1633 | { | 1635 | { |
@@ -1742,8 +1744,8 @@ int udhcpc_main(int argc UNUSED_PARAM, char **argv) | |||
1742 | /* paranoia: must not be too small and not prone to overflows */ | 1744 | /* paranoia: must not be too small and not prone to overflows */ |
1743 | if (lease_seconds < 0x10) | 1745 | if (lease_seconds < 0x10) |
1744 | lease_seconds = 0x10; | 1746 | lease_seconds = 0x10; |
1745 | if (lease_seconds >= 0x10000000) | 1747 | if (lease_seconds > 0x7fffffff / 1000) |
1746 | lease_seconds = 0x0fffffff; | 1748 | lease_seconds = 0x7fffffff / 1000; |
1747 | } | 1749 | } |
1748 | #if ENABLE_FEATURE_UDHCPC_ARPING | 1750 | #if ENABLE_FEATURE_UDHCPC_ARPING |
1749 | if (opt & OPT_a) { | 1751 | if (opt & OPT_a) { |
diff --git a/networking/udhcp/dhcpd.c b/networking/udhcp/dhcpd.c index e116ba3af..5eff026bc 100644 --- a/networking/udhcp/dhcpd.c +++ b/networking/udhcp/dhcpd.c | |||
@@ -794,7 +794,7 @@ static NOINLINE void send_inform(struct dhcp_packet *oldpacket) | |||
794 | int udhcpd_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; | 794 | int udhcpd_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; |
795 | int udhcpd_main(int argc UNUSED_PARAM, char **argv) | 795 | int udhcpd_main(int argc UNUSED_PARAM, char **argv) |
796 | { | 796 | { |
797 | int server_socket = -1, retval, max_sock; | 797 | int server_socket = -1, retval; |
798 | uint8_t *state; | 798 | uint8_t *state; |
799 | unsigned timeout_end; | 799 | unsigned timeout_end; |
800 | unsigned num_ips; | 800 | unsigned num_ips; |
@@ -891,10 +891,10 @@ int udhcpd_main(int argc UNUSED_PARAM, char **argv) | |||
891 | continue_with_autotime: | 891 | continue_with_autotime: |
892 | timeout_end = monotonic_sec() + server_config.auto_time; | 892 | timeout_end = monotonic_sec() + server_config.auto_time; |
893 | while (1) { /* loop until universe collapses */ | 893 | while (1) { /* loop until universe collapses */ |
894 | fd_set rfds; | 894 | struct pollfd pfds[2]; |
895 | struct dhcp_packet packet; | 895 | struct dhcp_packet packet; |
896 | int bytes; | 896 | int bytes; |
897 | struct timeval tv; | 897 | int tv; |
898 | uint8_t *server_id_opt; | 898 | uint8_t *server_id_opt; |
899 | uint8_t *requested_ip_opt; | 899 | uint8_t *requested_ip_opt; |
900 | uint32_t requested_nip = requested_nip; /* for compiler */ | 900 | uint32_t requested_nip = requested_nip; /* for compiler */ |
@@ -906,16 +906,11 @@ int udhcpd_main(int argc UNUSED_PARAM, char **argv) | |||
906 | server_config.interface); | 906 | server_config.interface); |
907 | } | 907 | } |
908 | 908 | ||
909 | max_sock = udhcp_sp_fd_set(&rfds, server_socket); | 909 | udhcp_sp_fd_set(pfds, server_socket); |
910 | if (server_config.auto_time) { | 910 | tv = timeout_end - monotonic_sec(); |
911 | /* cast to signed is essential if tv_sec is wider than int */ | ||
912 | tv.tv_sec = (int)(timeout_end - monotonic_sec()); | ||
913 | tv.tv_usec = 0; | ||
914 | } | ||
915 | retval = 0; | 911 | retval = 0; |
916 | if (!server_config.auto_time || tv.tv_sec > 0) { | 912 | if (!server_config.auto_time || tv > 0) { |
917 | retval = select(max_sock + 1, &rfds, NULL, NULL, | 913 | retval = poll(pfds, 2, server_config.auto_time ? tv * 1000 : -1); |
918 | server_config.auto_time ? &tv : NULL); | ||
919 | } | 914 | } |
920 | if (retval == 0) { | 915 | if (retval == 0) { |
921 | write_leases(); | 916 | write_leases(); |
@@ -926,7 +921,7 @@ int udhcpd_main(int argc UNUSED_PARAM, char **argv) | |||
926 | continue; | 921 | continue; |
927 | } | 922 | } |
928 | 923 | ||
929 | switch (udhcp_sp_read(&rfds)) { | 924 | switch (udhcp_sp_read(pfds)) { |
930 | case SIGUSR1: | 925 | case SIGUSR1: |
931 | bb_error_msg("received %s", "SIGUSR1"); | 926 | bb_error_msg("received %s", "SIGUSR1"); |
932 | write_leases(); | 927 | write_leases(); |
diff --git a/networking/udhcp/dhcprelay.c b/networking/udhcp/dhcprelay.c index 7cb19b14e..ea84c0dd7 100644 --- a/networking/udhcp/dhcprelay.c +++ b/networking/udhcp/dhcprelay.c | |||
@@ -361,7 +361,7 @@ int dhcprelay_main(int argc, char **argv) | |||
361 | // which the reply must be sent (i.e., the host or router interface | 361 | // which the reply must be sent (i.e., the host or router interface |
362 | // connected to the same network as the BOOTP client). If the content | 362 | // connected to the same network as the BOOTP client). If the content |
363 | // of the 'giaddr' field does not match one of the relay agent's | 363 | // of the 'giaddr' field does not match one of the relay agent's |
364 | // directly-connected logical interfaces, the BOOTREPLY messsage MUST be | 364 | // directly-connected logical interfaces, the BOOTREPLY message MUST be |
365 | // silently discarded. | 365 | // silently discarded. |
366 | if (udhcp_read_interface(iface_list[i], NULL, &dhcp_msg.gateway_nip, NULL)) { | 366 | if (udhcp_read_interface(iface_list[i], NULL, &dhcp_msg.gateway_nip, NULL)) { |
367 | /* Fall back to our IP on server iface */ | 367 | /* Fall back to our IP on server iface */ |
diff --git a/networking/udhcp/signalpipe.c b/networking/udhcp/signalpipe.c index 6355c5e90..b101b4ce4 100644 --- a/networking/udhcp/signalpipe.c +++ b/networking/udhcp/signalpipe.c | |||
@@ -25,9 +25,11 @@ static struct fd_pair signal_pipe; | |||
25 | 25 | ||
26 | static void signal_handler(int sig) | 26 | static void signal_handler(int sig) |
27 | { | 27 | { |
28 | int sv = errno; | ||
28 | unsigned char ch = sig; /* use char, avoid dealing with partial writes */ | 29 | unsigned char ch = sig; /* use char, avoid dealing with partial writes */ |
29 | if (write(signal_pipe.wr, &ch, 1) != 1) | 30 | if (write(signal_pipe.wr, &ch, 1) != 1) |
30 | bb_perror_msg("can't send signal"); | 31 | bb_perror_msg("can't send signal"); |
32 | errno = sv; | ||
31 | } | 33 | } |
32 | 34 | ||
33 | /* Call this before doing anything else. Sets up the socket pair | 35 | /* Call this before doing anything else. Sets up the socket pair |
@@ -46,28 +48,29 @@ void FAST_FUNC udhcp_sp_setup(void) | |||
46 | , signal_handler); | 48 | , signal_handler); |
47 | } | 49 | } |
48 | 50 | ||
49 | /* Quick little function to setup the rfds. Will return the | 51 | /* Quick little function to setup the pfds. |
50 | * max_fd for use with select. Limited in that you can only pass | 52 | * Limited in that you can only pass one extra fd. |
51 | * one extra fd */ | 53 | */ |
52 | int FAST_FUNC udhcp_sp_fd_set(fd_set *rfds, int extra_fd) | 54 | void FAST_FUNC udhcp_sp_fd_set(struct pollfd pfds[2], int extra_fd) |
53 | { | 55 | { |
54 | FD_ZERO(rfds); | 56 | pfds[0].fd = signal_pipe.rd; |
55 | FD_SET(signal_pipe.rd, rfds); | 57 | pfds[0].events = POLLIN; |
58 | pfds[1].fd = -1; | ||
56 | if (extra_fd >= 0) { | 59 | if (extra_fd >= 0) { |
57 | close_on_exec_on(extra_fd); | 60 | close_on_exec_on(extra_fd); |
58 | FD_SET(extra_fd, rfds); | 61 | pfds[1].fd = extra_fd; |
62 | pfds[1].events = POLLIN; | ||
59 | } | 63 | } |
60 | return signal_pipe.rd > extra_fd ? signal_pipe.rd : extra_fd; | ||
61 | } | 64 | } |
62 | 65 | ||
63 | /* Read a signal from the signal pipe. Returns 0 if there is | 66 | /* Read a signal from the signal pipe. Returns 0 if there is |
64 | * no signal, -1 on error (and sets errno appropriately), and | 67 | * no signal, -1 on error (and sets errno appropriately), and |
65 | * your signal on success */ | 68 | * your signal on success */ |
66 | int FAST_FUNC udhcp_sp_read(const fd_set *rfds) | 69 | int FAST_FUNC udhcp_sp_read(struct pollfd pfds[2]) |
67 | { | 70 | { |
68 | unsigned char sig; | 71 | unsigned char sig; |
69 | 72 | ||
70 | if (!FD_ISSET(signal_pipe.rd, rfds)) | 73 | if (!pfds[0].revents) |
71 | return 0; | 74 | return 0; |
72 | 75 | ||
73 | if (safe_read(signal_pipe.rd, &sig, 1) != 1) | 76 | if (safe_read(signal_pipe.rd, &sig, 1) != 1) |
diff --git a/networking/vconfig.c b/networking/vconfig.c index f3020409a..854eca0a1 100644 --- a/networking/vconfig.c +++ b/networking/vconfig.c | |||
@@ -138,7 +138,7 @@ int vconfig_main(int argc, char **argv) | |||
138 | /* I suppose one could try to combine some of the function calls below, | 138 | /* I suppose one could try to combine some of the function calls below, |
139 | * since ifr.u.flag, ifr.u.VID, and ifr.u.skb_priority are all same-sized | 139 | * since ifr.u.flag, ifr.u.VID, and ifr.u.skb_priority are all same-sized |
140 | * (unsigned) int members of a unions. But because of the range checking, | 140 | * (unsigned) int members of a unions. But because of the range checking, |
141 | * doing so wouldn't save that much space and would also make maintainence | 141 | * doing so wouldn't save that much space and would also make maintenance |
142 | * more of a pain. | 142 | * more of a pain. |
143 | */ | 143 | */ |
144 | if (ifr.cmd == SET_VLAN_FLAG_CMD) { | 144 | if (ifr.cmd == SET_VLAN_FLAG_CMD) { |
diff --git a/procps/kill.c b/procps/kill.c index 7ae5beead..975a3e8c5 100644 --- a/procps/kill.c +++ b/procps/kill.c | |||
@@ -201,7 +201,7 @@ int kill_main(int argc UNUSED_PARAM, char **argv) | |||
201 | pid_t sid; | 201 | pid_t sid; |
202 | procps_status_t* p = NULL; | 202 | procps_status_t* p = NULL; |
203 | /* compat: exitcode 2 is "no one was signaled" */ | 203 | /* compat: exitcode 2 is "no one was signaled" */ |
204 | int ret = 2; | 204 | errors = 2; |
205 | 205 | ||
206 | /* Find out our session id */ | 206 | /* Find out our session id */ |
207 | sid = getsid(pid); | 207 | sid = getsid(pid); |
@@ -229,7 +229,7 @@ int kill_main(int argc UNUSED_PARAM, char **argv) | |||
229 | arg = *args++; | 229 | arg = *args++; |
230 | if (arg[0] != '-' || arg[1] != 'o') { | 230 | if (arg[0] != '-' || arg[1] != 'o') { |
231 | bb_error_msg("bad option '%s'", arg); | 231 | bb_error_msg("bad option '%s'", arg); |
232 | ret = 1; | 232 | errors = 1; |
233 | goto resume; | 233 | goto resume; |
234 | } | 234 | } |
235 | arg += 2; | 235 | arg += 2; |
@@ -238,21 +238,21 @@ int kill_main(int argc UNUSED_PARAM, char **argv) | |||
238 | omit = bb_strtoi(arg, NULL, 10); | 238 | omit = bb_strtoi(arg, NULL, 10); |
239 | if (errno) { | 239 | if (errno) { |
240 | bb_error_msg("invalid number '%s'", arg); | 240 | bb_error_msg("invalid number '%s'", arg); |
241 | ret = 1; | 241 | errors = 1; |
242 | goto resume; | 242 | goto resume; |
243 | } | 243 | } |
244 | if (p->pid == omit) | 244 | if (p->pid == omit) |
245 | goto dont_kill; | 245 | goto dont_kill; |
246 | } | 246 | } |
247 | kill(p->pid, signo); | 247 | kill(p->pid, signo); |
248 | ret = 0; | 248 | errors = 0; |
249 | dont_kill: ; | 249 | dont_kill: ; |
250 | } | 250 | } |
251 | resume: | 251 | resume: |
252 | /* And let them continue */ | 252 | /* And let them continue */ |
253 | if (signo != SIGSTOP && signo != SIGCONT) | 253 | if (signo != SIGSTOP && signo != SIGCONT) |
254 | kill(-1, SIGCONT); | 254 | kill(-1, SIGCONT); |
255 | return ret; | 255 | return errors; |
256 | } | 256 | } |
257 | 257 | ||
258 | #if ENABLE_KILL || ENABLE_KILLALL | 258 | #if ENABLE_KILL || ENABLE_KILLALL |
diff --git a/runit/chpst.c b/runit/chpst.c index 846c846d3..ee3a33153 100644 --- a/runit/chpst.c +++ b/runit/chpst.c | |||
@@ -463,6 +463,13 @@ int chpst_main(int argc UNUSED_PARAM, char **argv) | |||
463 | xchroot(root); | 463 | xchroot(root); |
464 | } | 464 | } |
465 | 465 | ||
466 | /* nice should be done before xsetuid */ | ||
467 | if (opt & OPT_n) { | ||
468 | errno = 0; | ||
469 | if (nice(xatoi(nicestr)) == -1) | ||
470 | bb_perror_msg_and_die("nice"); | ||
471 | } | ||
472 | |||
466 | if (opt & OPT_u) { | 473 | if (opt & OPT_u) { |
467 | if (setgroups(1, &ugid.gid) == -1) | 474 | if (setgroups(1, &ugid.gid) == -1) |
468 | bb_perror_msg_and_die("setgroups"); | 475 | bb_perror_msg_and_die("setgroups"); |
@@ -470,12 +477,6 @@ int chpst_main(int argc UNUSED_PARAM, char **argv) | |||
470 | xsetuid(ugid.uid); | 477 | xsetuid(ugid.uid); |
471 | } | 478 | } |
472 | 479 | ||
473 | if (opt & OPT_n) { | ||
474 | errno = 0; | ||
475 | if (nice(xatoi(nicestr)) == -1) | ||
476 | bb_perror_msg_and_die("nice"); | ||
477 | } | ||
478 | |||
479 | if (opt & OPT_0) | 480 | if (opt & OPT_0) |
480 | close(STDIN_FILENO); | 481 | close(STDIN_FILENO); |
481 | if (opt & OPT_1) | 482 | if (opt & OPT_1) |
diff --git a/runit/runsv.c b/runit/runsv.c index e0e31508a..939653d12 100644 --- a/runit/runsv.c +++ b/runit/runsv.c | |||
@@ -134,9 +134,13 @@ static void fatal2x_cannot(const char *m1, const char *m2) | |||
134 | bb_error_msg_and_die("%s: fatal: can't %s%s", dir, m1, m2); | 134 | bb_error_msg_and_die("%s: fatal: can't %s%s", dir, m1, m2); |
135 | /* was exiting 111 */ | 135 | /* was exiting 111 */ |
136 | } | 136 | } |
137 | static void warn2_cannot(const char *m1, const char *m2) | ||
138 | { | ||
139 | bb_perror_msg("%s: warning: can't %s%s", dir, m1, m2); | ||
140 | } | ||
137 | static void warn_cannot(const char *m) | 141 | static void warn_cannot(const char *m) |
138 | { | 142 | { |
139 | bb_perror_msg("%s: warning: cannot %s", dir, m); | 143 | warn2_cannot(m, ""); |
140 | } | 144 | } |
141 | 145 | ||
142 | static void s_child(int sig_no UNUSED_PARAM) | 146 | static void s_child(int sig_no UNUSED_PARAM) |
@@ -165,10 +169,25 @@ static void update_status(struct svdir *s) | |||
165 | ssize_t sz; | 169 | ssize_t sz; |
166 | int fd; | 170 | int fd; |
167 | svstatus_t status; | 171 | svstatus_t status; |
172 | const char *fstatus ="log/supervise/status"; | ||
173 | const char *fstatusnew ="log/supervise/status.new"; | ||
174 | const char *f_stat ="log/supervise/stat"; | ||
175 | const char *fstatnew ="log/supervise/stat.new"; | ||
176 | const char *fpid ="log/supervise/pid"; | ||
177 | const char *fpidnew ="log/supervise/pid.new"; | ||
178 | |||
179 | if (!s->islog) { | ||
180 | fstatus += 4; | ||
181 | fstatusnew += 4; | ||
182 | f_stat += 4; | ||
183 | fstatnew += 4; | ||
184 | fpid += 4; | ||
185 | fpidnew += 4; | ||
186 | } | ||
168 | 187 | ||
169 | /* pid */ | 188 | /* pid */ |
170 | if (pidchanged) { | 189 | if (pidchanged) { |
171 | fd = open_trunc_or_warn("supervise/pid.new"); | 190 | fd = open_trunc_or_warn(fpidnew); |
172 | if (fd < 0) | 191 | if (fd < 0) |
173 | return; | 192 | return; |
174 | if (s->pid) { | 193 | if (s->pid) { |
@@ -177,14 +196,13 @@ static void update_status(struct svdir *s) | |||
177 | write(fd, spid, size); | 196 | write(fd, spid, size); |
178 | } | 197 | } |
179 | close(fd); | 198 | close(fd); |
180 | if (rename_or_warn("supervise/pid.new", | 199 | if (rename_or_warn(fpidnew, fpid)) |
181 | s->islog ? "log/supervise/pid" : "log/supervise/pid"+4)) | ||
182 | return; | 200 | return; |
183 | pidchanged = 0; | 201 | pidchanged = 0; |
184 | } | 202 | } |
185 | 203 | ||
186 | /* stat */ | 204 | /* stat */ |
187 | fd = open_trunc_or_warn("supervise/stat.new"); | 205 | fd = open_trunc_or_warn(fstatnew); |
188 | if (fd < -1) | 206 | if (fd < -1) |
189 | return; | 207 | return; |
190 | 208 | ||
@@ -220,8 +238,7 @@ static void update_status(struct svdir *s) | |||
220 | close(fd); | 238 | close(fd); |
221 | } | 239 | } |
222 | 240 | ||
223 | rename_or_warn("supervise/stat.new", | 241 | rename_or_warn(fstatnew, f_stat); |
224 | s->islog ? "log/supervise/stat" : "log/supervise/stat"+4); | ||
225 | 242 | ||
226 | /* supervise compatibility */ | 243 | /* supervise compatibility */ |
227 | memset(&status, 0, sizeof(status)); | 244 | memset(&status, 0, sizeof(status)); |
@@ -237,18 +254,17 @@ static void update_status(struct svdir *s) | |||
237 | if (s->ctrl & C_TERM) | 254 | if (s->ctrl & C_TERM) |
238 | status.got_term = 1; | 255 | status.got_term = 1; |
239 | status.run_or_finish = s->state; | 256 | status.run_or_finish = s->state; |
240 | fd = open_trunc_or_warn("supervise/status.new"); | 257 | fd = open_trunc_or_warn(fstatusnew); |
241 | if (fd < 0) | 258 | if (fd < 0) |
242 | return; | 259 | return; |
243 | sz = write(fd, &status, sizeof(status)); | 260 | sz = write(fd, &status, sizeof(status)); |
244 | close(fd); | 261 | close(fd); |
245 | if (sz != sizeof(status)) { | 262 | if (sz != sizeof(status)) { |
246 | warn_cannot("write supervise/status.new"); | 263 | warn2_cannot("write ", fstatusnew); |
247 | unlink("supervise/status.new"); | 264 | unlink(fstatusnew); |
248 | return; | 265 | return; |
249 | } | 266 | } |
250 | rename_or_warn("supervise/status.new", | 267 | rename_or_warn(fstatusnew, fstatus); |
251 | s->islog ? "log/supervise/status" : "log/supervise/status"+4); | ||
252 | } | 268 | } |
253 | 269 | ||
254 | static unsigned custom(struct svdir *s, char c) | 270 | static unsigned custom(struct svdir *s, char c) |
@@ -266,26 +282,26 @@ static unsigned custom(struct svdir *s, char c) | |||
266 | if (st.st_mode & S_IXUSR) { | 282 | if (st.st_mode & S_IXUSR) { |
267 | pid = vfork(); | 283 | pid = vfork(); |
268 | if (pid == -1) { | 284 | if (pid == -1) { |
269 | warn_cannot("vfork for control/?"); | 285 | warn2_cannot("vfork for ", a); |
270 | return 0; | 286 | return 0; |
271 | } | 287 | } |
272 | if (pid == 0) { | 288 | if (pid == 0) { |
273 | /* child */ | 289 | /* child */ |
274 | if (haslog && dup2(logpipe.wr, 1) == -1) | 290 | if (haslog && dup2(logpipe.wr, 1) == -1) |
275 | warn_cannot("setup stdout for control/?"); | 291 | warn2_cannot("setup stdout for ", a); |
276 | execl(a, a, (char *) NULL); | 292 | execl(a, a, (char *) NULL); |
277 | fatal_cannot("run control/?"); | 293 | fatal2_cannot("run ", a); |
278 | } | 294 | } |
279 | /* parent */ | 295 | /* parent */ |
280 | if (safe_waitpid(pid, &w, 0) == -1) { | 296 | if (safe_waitpid(pid, &w, 0) == -1) { |
281 | warn_cannot("wait for child control/?"); | 297 | warn2_cannot("wait for child ", a); |
282 | return 0; | 298 | return 0; |
283 | } | 299 | } |
284 | return WEXITSTATUS(w) == 0; | 300 | return WEXITSTATUS(w) == 0; |
285 | } | 301 | } |
286 | } else { | 302 | } else { |
287 | if (errno != ENOENT) | 303 | if (errno != ENOENT) |
288 | warn_cannot("stat control/?"); | 304 | warn2_cannot("stat ", a); |
289 | } | 305 | } |
290 | return 0; | 306 | return 0; |
291 | } | 307 | } |
@@ -387,13 +403,13 @@ static int ctrl(struct svdir *s, char c) | |||
387 | case 'd': /* down */ | 403 | case 'd': /* down */ |
388 | s->sd_want = W_DOWN; | 404 | s->sd_want = W_DOWN; |
389 | update_status(s); | 405 | update_status(s); |
390 | if (s->pid && s->state != S_FINISH) | 406 | if (s->state == S_RUN) |
391 | stopservice(s); | 407 | stopservice(s); |
392 | break; | 408 | break; |
393 | case 'u': /* up */ | 409 | case 'u': /* up */ |
394 | s->sd_want = W_UP; | 410 | s->sd_want = W_UP; |
395 | update_status(s); | 411 | update_status(s); |
396 | if (s->pid == 0) | 412 | if (s->state == S_DOWN) |
397 | startservice(s); | 413 | startservice(s); |
398 | break; | 414 | break; |
399 | case 'x': /* exit */ | 415 | case 'x': /* exit */ |
@@ -403,22 +419,22 @@ static int ctrl(struct svdir *s, char c) | |||
403 | update_status(s); | 419 | update_status(s); |
404 | /* FALLTHROUGH */ | 420 | /* FALLTHROUGH */ |
405 | case 't': /* sig term */ | 421 | case 't': /* sig term */ |
406 | if (s->pid && s->state != S_FINISH) | 422 | if (s->state == S_RUN) |
407 | stopservice(s); | 423 | stopservice(s); |
408 | break; | 424 | break; |
409 | case 'k': /* sig kill */ | 425 | case 'k': /* sig kill */ |
410 | if (s->pid && !custom(s, c)) | 426 | if ((s->state == S_RUN) && !custom(s, c)) |
411 | kill(s->pid, SIGKILL); | 427 | kill(s->pid, SIGKILL); |
412 | s->state = S_DOWN; | 428 | s->state = S_DOWN; |
413 | break; | 429 | break; |
414 | case 'p': /* sig pause */ | 430 | case 'p': /* sig pause */ |
415 | if (s->pid && !custom(s, c)) | 431 | if ((s->state == S_RUN) && !custom(s, c)) |
416 | kill(s->pid, SIGSTOP); | 432 | kill(s->pid, SIGSTOP); |
417 | s->ctrl |= C_PAUSE; | 433 | s->ctrl |= C_PAUSE; |
418 | update_status(s); | 434 | update_status(s); |
419 | break; | 435 | break; |
420 | case 'c': /* sig cont */ | 436 | case 'c': /* sig cont */ |
421 | if (s->pid && !custom(s, c)) | 437 | if ((s->state == S_RUN) && !custom(s, c)) |
422 | kill(s->pid, SIGCONT); | 438 | kill(s->pid, SIGCONT); |
423 | s->ctrl &= ~C_PAUSE; | 439 | s->ctrl &= ~C_PAUSE; |
424 | update_status(s); | 440 | update_status(s); |
@@ -426,7 +442,7 @@ static int ctrl(struct svdir *s, char c) | |||
426 | case 'o': /* once */ | 442 | case 'o': /* once */ |
427 | s->sd_want = W_DOWN; | 443 | s->sd_want = W_DOWN; |
428 | update_status(s); | 444 | update_status(s); |
429 | if (!s->pid) | 445 | if (s->state == S_DOWN) |
430 | startservice(s); | 446 | startservice(s); |
431 | break; | 447 | break; |
432 | case 'a': /* sig alarm */ | 448 | case 'a': /* sig alarm */ |
@@ -450,11 +466,26 @@ static int ctrl(struct svdir *s, char c) | |||
450 | } | 466 | } |
451 | return 1; | 467 | return 1; |
452 | sendsig: | 468 | sendsig: |
453 | if (s->pid && !custom(s, c)) | 469 | if ((s->state == S_RUN) && !custom(s, c)) |
454 | kill(s->pid, sig); | 470 | kill(s->pid, sig); |
455 | return 1; | 471 | return 1; |
456 | } | 472 | } |
457 | 473 | ||
474 | static void open_control(const char *f, struct svdir *s) | ||
475 | { | ||
476 | struct stat st; | ||
477 | mkfifo(f, 0600); | ||
478 | if (stat(f, &st) == -1) | ||
479 | fatal2_cannot("stat ", f); | ||
480 | if (!S_ISFIFO(st.st_mode)) | ||
481 | bb_error_msg_and_die("%s: fatal: %s exists but is not a fifo", dir, f); | ||
482 | s->fdcontrol = xopen(f, O_RDONLY|O_NDELAY); | ||
483 | close_on_exec_on(s->fdcontrol); | ||
484 | s->fdcontrolwrite = xopen(f, O_WRONLY|O_NDELAY); | ||
485 | close_on_exec_on(s->fdcontrolwrite); | ||
486 | update_status(s); | ||
487 | } | ||
488 | |||
458 | int runsv_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; | 489 | int runsv_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; |
459 | int runsv_main(int argc UNUSED_PARAM, char **argv) | 490 | int runsv_main(int argc UNUSED_PARAM, char **argv) |
460 | { | 491 | { |
@@ -554,19 +585,9 @@ int runsv_main(int argc UNUSED_PARAM, char **argv) | |||
554 | close_on_exec_on(svd[1].fdlock); | 585 | close_on_exec_on(svd[1].fdlock); |
555 | } | 586 | } |
556 | 587 | ||
557 | mkfifo("log/supervise/control"+4, 0600); | 588 | open_control("log/supervise/control"+4, &svd[0]); |
558 | svd[0].fdcontrol = xopen("log/supervise/control"+4, O_RDONLY|O_NDELAY); | ||
559 | close_on_exec_on(svd[0].fdcontrol); | ||
560 | svd[0].fdcontrolwrite = xopen("log/supervise/control"+4, O_WRONLY|O_NDELAY); | ||
561 | close_on_exec_on(svd[0].fdcontrolwrite); | ||
562 | update_status(&svd[0]); | ||
563 | if (haslog) { | 589 | if (haslog) { |
564 | mkfifo("log/supervise/control", 0600); | 590 | open_control("log/supervise/control", &svd[1]); |
565 | svd[1].fdcontrol = xopen("log/supervise/control", O_RDONLY|O_NDELAY); | ||
566 | close_on_exec_on(svd[1].fdcontrol); | ||
567 | svd[1].fdcontrolwrite = xopen("log/supervise/control", O_WRONLY|O_NDELAY); | ||
568 | close_on_exec_on(svd[1].fdcontrolwrite); | ||
569 | update_status(&svd[1]); | ||
570 | } | 591 | } |
571 | mkfifo("log/supervise/ok"+4, 0600); | 592 | mkfifo("log/supervise/ok"+4, 0600); |
572 | fd = xopen("log/supervise/ok"+4, O_RDONLY|O_NDELAY); | 593 | fd = xopen("log/supervise/ok"+4, O_RDONLY|O_NDELAY); |
diff --git a/runit/sv.c b/runit/sv.c index 9e2132259..faa31d4fa 100644 --- a/runit/sv.c +++ b/runit/sv.c | |||
@@ -25,7 +25,7 @@ OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF | |||
25 | ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 25 | ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
26 | */ | 26 | */ |
27 | 27 | ||
28 | /* Taken from http://smarden.sunsite.dk/runit/sv.8.html: | 28 | /* Taken from http://smarden.org/runit/sv.8.html: |
29 | 29 | ||
30 | sv - control and manage services monitored by runsv | 30 | sv - control and manage services monitored by runsv |
31 | 31 | ||
@@ -36,17 +36,13 @@ The sv program reports the current status and controls the state of services | |||
36 | monitored by the runsv(8) supervisor. | 36 | monitored by the runsv(8) supervisor. |
37 | 37 | ||
38 | services consists of one or more arguments, each argument naming a directory | 38 | services consists of one or more arguments, each argument naming a directory |
39 | service used by runsv(8). If service doesn't start with a dot or slash, | 39 | service used by runsv(8). If service doesn't start with a dot or slash and |
40 | it is searched in the default services directory /var/service/, otherwise | 40 | doesn't end with a slash, it is searched in the default services directory |
41 | relative to the current directory. | 41 | /var/service/, otherwise relative to the current directory. |
42 | 42 | ||
43 | command is one of up, down, status, once, pause, cont, hup, alarm, interrupt, | 43 | command is one of up, down, status, once, pause, cont, hup, alarm, interrupt, |
44 | 1, 2, term, kill, or exit, or start, stop, restart, shutdown, force-stop, | 44 | 1, 2, term, kill, or exit, or start, stop, reload, restart, shutdown, |
45 | force-reload, force-restart, force-shutdown. | 45 | force-stop, force-reload, force-restart, force-shutdown, try-restart. |
46 | |||
47 | The sv program can be sym-linked to /etc/init.d/ to provide an LSB init | ||
48 | script interface. The service to be controlled then is specified by the | ||
49 | base name of the "init script". | ||
50 | 46 | ||
51 | status | 47 | status |
52 | Report the current status of the service, and the appendant log service | 48 | Report the current status of the service, and the appendant log service |
@@ -66,9 +62,9 @@ exit | |||
66 | If the service is running, send it the TERM signal, and the CONT signal. | 62 | If the service is running, send it the TERM signal, and the CONT signal. |
67 | Do not restart the service. If the service is down, and no log service | 63 | Do not restart the service. If the service is down, and no log service |
68 | exists, runsv(8) exits. If the service is down and a log service exists, | 64 | exists, runsv(8) exits. If the service is down and a log service exists, |
69 | send the TERM signal to the log service. If the log service is down, | 65 | runsv(8) closes the standard input of the log service and waits for it to |
70 | runsv(8) exits. This command is ignored if it is given to an appendant | 66 | terminate. If the log service is down, runsv(8) exits. This command is |
71 | log service. | 67 | ignored if it is given to an appendant log service. |
72 | 68 | ||
73 | sv actually looks only at the first character of above commands. | 69 | sv actually looks only at the first character of above commands. |
74 | 70 | ||
@@ -85,6 +81,8 @@ start | |||
85 | stop | 81 | stop |
86 | Same as down, but wait up to 7 seconds for the service to become down. | 82 | Same as down, but wait up to 7 seconds for the service to become down. |
87 | Then report the status or timeout. | 83 | Then report the status or timeout. |
84 | reload | ||
85 | Same as hup, and additionally report the status afterwards. | ||
88 | restart | 86 | restart |
89 | Send the commands term, cont, and up to the service, and wait up to | 87 | Send the commands term, cont, and up to the service, and wait up to |
90 | 7 seconds for the service to restart. Then report the status or timeout. | 88 | 7 seconds for the service to restart. Then report the status or timeout. |
@@ -112,6 +110,9 @@ force-shutdown | |||
112 | Same as exit, but wait up to 7 seconds for the runsv(8) process to | 110 | Same as exit, but wait up to 7 seconds for the runsv(8) process to |
113 | terminate. Then report the status, and on timeout send the service | 111 | terminate. Then report the status, and on timeout send the service |
114 | the kill command. | 112 | the kill command. |
113 | try-restart | ||
114 | if the service is running, send it the term and cont commands, and wait up to | ||
115 | 7 seconds for the service to restart. Then report the status or timeout. | ||
115 | 116 | ||
116 | Additional Commands | 117 | Additional Commands |
117 | 118 | ||
@@ -126,8 +127,8 @@ check | |||
126 | Options | 127 | Options |
127 | 128 | ||
128 | -v | 129 | -v |
129 | wait up to 7 seconds for the command to take effect. | 130 | If the command is up, down, term, once, cont, or exit, then wait up to 7 |
130 | Then report the status or timeout. | 131 | seconds for the command to take effect. Then report the status or timeout. |
131 | -w sec | 132 | -w sec |
132 | Override the default timeout of 7 seconds with sec seconds. Implies -v. | 133 | Override the default timeout of 7 seconds with sec seconds. Implies -v. |
133 | 134 | ||
@@ -192,6 +193,7 @@ struct globals { | |||
192 | /* "Bernstein" time format: unix + 0x400000000000000aULL */ | 193 | /* "Bernstein" time format: unix + 0x400000000000000aULL */ |
193 | uint64_t tstart, tnow; | 194 | uint64_t tstart, tnow; |
194 | svstatus_t svstatus; | 195 | svstatus_t svstatus; |
196 | unsigned islog; | ||
195 | } FIX_ALIASING; | 197 | } FIX_ALIASING; |
196 | #define G (*(struct globals*)bb_common_bufsiz1) | 198 | #define G (*(struct globals*)bb_common_bufsiz1) |
197 | #define acts (G.acts ) | 199 | #define acts (G.acts ) |
@@ -200,6 +202,7 @@ struct globals { | |||
200 | #define tstart (G.tstart ) | 202 | #define tstart (G.tstart ) |
201 | #define tnow (G.tnow ) | 203 | #define tnow (G.tnow ) |
202 | #define svstatus (G.svstatus ) | 204 | #define svstatus (G.svstatus ) |
205 | #define islog (G.islog ) | ||
203 | #define INIT_G() do { setup_common_bufsiz(); } while (0) | 206 | #define INIT_G() do { setup_common_bufsiz(); } while (0) |
204 | 207 | ||
205 | 208 | ||
@@ -215,7 +218,7 @@ static void fatal_cannot(const char *m1) | |||
215 | 218 | ||
216 | static void out(const char *p, const char *m1) | 219 | static void out(const char *p, const char *m1) |
217 | { | 220 | { |
218 | printf("%s%s: %s", p, *service, m1); | 221 | printf("%s%s%s: %s", p, *service, islog ? "/log" : "", m1); |
219 | if (errno) { | 222 | if (errno) { |
220 | printf(": %s", strerror(errno)); | 223 | printf(": %s", strerror(errno)); |
221 | } | 224 | } |
@@ -300,15 +303,14 @@ static unsigned svstatus_print(const char *m) | |||
300 | } | 303 | } |
301 | pid = SWAP_LE32(svstatus.pid_le32); | 304 | pid = SWAP_LE32(svstatus.pid_le32); |
302 | timestamp = SWAP_BE64(svstatus.time_be64); | 305 | timestamp = SWAP_BE64(svstatus.time_be64); |
303 | if (pid) { | 306 | switch (svstatus.run_or_finish) { |
304 | switch (svstatus.run_or_finish) { | 307 | case 0: printf("down: "); break; |
305 | case 1: printf("run: "); break; | 308 | case 1: printf("run: "); break; |
306 | case 2: printf("finish: "); break; | 309 | case 2: printf("finish: "); break; |
307 | } | ||
308 | printf("%s: (pid %d) ", m, pid); | ||
309 | } else { | ||
310 | printf("down: %s: ", m); | ||
311 | } | 310 | } |
311 | printf("%s: ", m); | ||
312 | if (svstatus.run_or_finish) | ||
313 | printf("(pid %d) ", pid); | ||
312 | diff = tnow - timestamp; | 314 | diff = tnow - timestamp; |
313 | printf("%us", (diff < 0 ? 0 : diff)); | 315 | printf("%us", (diff < 0 ? 0 : diff)); |
314 | if (pid) { | 316 | if (pid) { |
@@ -331,16 +333,21 @@ static int status(const char *unused UNUSED_PARAM) | |||
331 | return 0; | 333 | return 0; |
332 | 334 | ||
333 | r = svstatus_print(*service); | 335 | r = svstatus_print(*service); |
336 | islog = 1; | ||
334 | if (chdir("log") == -1) { | 337 | if (chdir("log") == -1) { |
335 | if (errno != ENOENT) { | 338 | if (errno != ENOENT) { |
336 | printf("; log: "WARN"can't change to log service directory: %s", | 339 | printf("; "); |
337 | strerror(errno)); | 340 | warn("can't change directory"); |
338 | } | 341 | } else |
339 | } else if (svstatus_get()) { | 342 | bb_putchar('\n'); |
343 | } else { | ||
340 | printf("; "); | 344 | printf("; "); |
341 | svstatus_print("log"); | 345 | if (svstatus_get()) { |
346 | r = svstatus_print("log"); | ||
347 | bb_putchar('\n'); | ||
348 | } | ||
342 | } | 349 | } |
343 | bb_putchar('\n'); /* will also flush the output */ | 350 | islog = 0; |
344 | return r; | 351 | return r; |
345 | } | 352 | } |
346 | 353 | ||
@@ -379,35 +386,53 @@ static int check(const char *a) | |||
379 | r = svstatus_get(); | 386 | r = svstatus_get(); |
380 | if (r == -1) | 387 | if (r == -1) |
381 | return -1; | 388 | return -1; |
382 | if (r == 0) { | 389 | while (*a) { |
383 | if (*a == 'x') | 390 | if (r == 0) { |
384 | return 1; | 391 | if (*a == 'x') |
385 | return -1; | 392 | return 1; |
386 | } | 393 | return -1; |
387 | pid_le32 = svstatus.pid_le32; | 394 | } |
388 | switch (*a) { | 395 | pid_le32 = svstatus.pid_le32; |
389 | case 'x': | 396 | switch (*a) { |
390 | return 0; | 397 | case 'x': |
391 | case 'u': | ||
392 | if (!pid_le32 || svstatus.run_or_finish != 1) return 0; | ||
393 | if (!checkscript()) return 0; | ||
394 | break; | ||
395 | case 'd': | ||
396 | if (pid_le32) return 0; | ||
397 | break; | ||
398 | case 'c': | ||
399 | if (pid_le32 && !checkscript()) return 0; | ||
400 | break; | ||
401 | case 't': | ||
402 | if (!pid_le32 && svstatus.want == 'd') break; | ||
403 | timestamp = SWAP_BE64(svstatus.time_be64); | ||
404 | if ((tstart > timestamp) || !pid_le32 || svstatus.got_term || !checkscript()) | ||
405 | return 0; | ||
406 | break; | ||
407 | case 'o': | ||
408 | timestamp = SWAP_BE64(svstatus.time_be64); | ||
409 | if ((!pid_le32 && tstart > timestamp) || (pid_le32 && svstatus.want != 'd')) | ||
410 | return 0; | 398 | return 0; |
399 | case 'u': | ||
400 | if (!pid_le32 || svstatus.run_or_finish != 1) | ||
401 | return 0; | ||
402 | if (!checkscript()) | ||
403 | return 0; | ||
404 | break; | ||
405 | case 'd': | ||
406 | if (pid_le32 || svstatus.run_or_finish != 0) | ||
407 | return 0; | ||
408 | break; | ||
409 | case 'C': | ||
410 | if (pid_le32 && !checkscript()) | ||
411 | return 0; | ||
412 | break; | ||
413 | case 't': | ||
414 | case 'k': | ||
415 | if (!pid_le32 && svstatus.want == 'd') | ||
416 | break; | ||
417 | timestamp = SWAP_BE64(svstatus.time_be64); | ||
418 | if ((tstart > timestamp) || !pid_le32 || svstatus.got_term || !checkscript()) | ||
419 | return 0; | ||
420 | break; | ||
421 | case 'o': | ||
422 | timestamp = SWAP_BE64(svstatus.time_be64); | ||
423 | if ((!pid_le32 && tstart > timestamp) || (pid_le32 && svstatus.want != 'd')) | ||
424 | return 0; | ||
425 | break; | ||
426 | case 'p': | ||
427 | if (pid_le32 && !svstatus.paused) | ||
428 | return 0; | ||
429 | break; | ||
430 | case 'c': | ||
431 | if (pid_le32 && svstatus.paused) | ||
432 | return 0; | ||
433 | break; | ||
434 | } | ||
435 | ++a; | ||
411 | } | 436 | } |
412 | printf(OK); | 437 | printf(OK); |
413 | svstatus_print(*service); | 438 | svstatus_print(*service); |
@@ -419,14 +444,10 @@ static int control(const char *a) | |||
419 | { | 444 | { |
420 | int fd, r, l; | 445 | int fd, r, l; |
421 | 446 | ||
422 | /* Is it an optimization? | ||
423 | It causes problems with "sv o SRV; ...; sv d SRV" | ||
424 | ('d' is not passed to SRV because its .want == 'd'): | ||
425 | if (svstatus_get() <= 0) | 447 | if (svstatus_get() <= 0) |
426 | return -1; | 448 | return -1; |
427 | if (svstatus.want == *a) | 449 | if (svstatus.want == *a && (*a != 'd' || svstatus.got_term == 1)) |
428 | return 0; | 450 | return 0; |
429 | */ | ||
430 | fd = open("supervise/control", O_WRONLY|O_NDELAY); | 451 | fd = open("supervise/control", O_WRONLY|O_NDELAY); |
431 | if (fd == -1) { | 452 | if (fd == -1) { |
432 | if (errno != ENODEV) | 453 | if (errno != ENODEV) |
@@ -516,17 +537,23 @@ static int sv(char **argv) | |||
516 | acts = "tc"; | 537 | acts = "tc"; |
517 | kll = 1; | 538 | kll = 1; |
518 | break; | 539 | break; |
540 | case 't': | ||
541 | if (str_equal(action, "try-restart")) { | ||
542 | acts = "tc"; | ||
543 | break; | ||
544 | } | ||
519 | case 'c': | 545 | case 'c': |
520 | if (str_equal(action, "check")) { | 546 | if (str_equal(action, "check")) { |
521 | act = NULL; | 547 | act = NULL; |
522 | acts = "c"; | 548 | acts = "C"; |
523 | break; | 549 | break; |
524 | } | 550 | } |
525 | case 'u': case 'd': case 'o': case 't': case 'p': case 'h': | 551 | case 'u': case 'd': case 'o': case 'p': case 'h': |
526 | case 'a': case 'i': case 'k': case 'q': case '1': case '2': | 552 | case 'a': case 'i': case 'k': case 'q': case '1': case '2': |
527 | action[1] = '\0'; | 553 | action[1] = '\0'; |
528 | acts = action; | 554 | acts = action; |
529 | if (!verbose) cbk = NULL; | 555 | if (!verbose) |
556 | cbk = NULL; | ||
530 | break; | 557 | break; |
531 | case 's': | 558 | case 's': |
532 | if (str_equal(action, "shutdown")) { | 559 | if (str_equal(action, "shutdown")) { |
@@ -550,6 +577,10 @@ static int sv(char **argv) | |||
550 | acts = "tcu"; | 577 | acts = "tcu"; |
551 | break; | 578 | break; |
552 | } | 579 | } |
580 | if (str_equal(action, "reload")) { | ||
581 | acts = "h"; | ||
582 | break; | ||
583 | } | ||
553 | bb_show_usage(); | 584 | bb_show_usage(); |
554 | case 'f': | 585 | case 'f': |
555 | if (str_equal(action, "force-reload")) { | 586 | if (str_equal(action, "force-reload")) { |
@@ -578,7 +609,9 @@ static int sv(char **argv) | |||
578 | 609 | ||
579 | service = argv; | 610 | service = argv; |
580 | while ((x = *service) != NULL) { | 611 | while ((x = *service) != NULL) { |
581 | if (x[0] != '/' && x[0] != '.') { | 612 | if (x[0] != '/' && x[0] != '.' |
613 | && x[0] != '\0' && x[strlen(x) - 1] != '/' | ||
614 | ) { | ||
582 | if (chdir(varservice) == -1) | 615 | if (chdir(varservice) == -1) |
583 | goto chdir_failed_0; | 616 | goto chdir_failed_0; |
584 | } | 617 | } |
@@ -688,12 +721,7 @@ int svc_main(int argc UNUSED_PARAM, char **argv) | |||
688 | /* getopt32() was already called: | 721 | /* getopt32() was already called: |
689 | * reset the libc getopt() function, which keeps internal state. | 722 | * reset the libc getopt() function, which keeps internal state. |
690 | */ | 723 | */ |
691 | #ifdef __GLIBC__ | 724 | GETOPT_RESET(); |
692 | optind = 0; | ||
693 | #else /* BSD style */ | ||
694 | optind = 1; | ||
695 | /* optreset = 1; */ | ||
696 | #endif | ||
697 | 725 | ||
698 | do { | 726 | do { |
699 | if (opts & 1) { | 727 | if (opts & 1) { |
diff --git a/runit/svlogd.c b/runit/svlogd.c index 3ed13b67b..795bf48bb 100644 --- a/runit/svlogd.c +++ b/runit/svlogd.c | |||
@@ -137,9 +137,9 @@ log message, you can use a pattern like this instead | |||
137 | //kbuild:lib-$(CONFIG_SVLOGD) += svlogd.o | 137 | //kbuild:lib-$(CONFIG_SVLOGD) += svlogd.o |
138 | 138 | ||
139 | //usage:#define svlogd_trivial_usage | 139 | //usage:#define svlogd_trivial_usage |
140 | //usage: "[-ttv] [-r C] [-R CHARS] [-l MATCHLEN] [-b BUFLEN] DIR..." | 140 | //usage: "[-tttv] [-r C] [-R CHARS] [-l MATCHLEN] [-b BUFLEN] DIR..." |
141 | //usage:#define svlogd_full_usage "\n\n" | 141 | //usage:#define svlogd_full_usage "\n\n" |
142 | //usage: "Continuously read log data from stdin and write to rotated log files in DIRs" | 142 | //usage: "Read log data from stdin and write to rotated log files in DIRs" |
143 | //usage: "\n" | 143 | //usage: "\n" |
144 | //usage: "\n""DIR/config file modifies behavior:" | 144 | //usage: "\n""DIR/config file modifies behavior:" |
145 | //usage: "\n""sSIZE - when to rotate logs" | 145 | //usage: "\n""sSIZE - when to rotate logs" |
@@ -339,17 +339,18 @@ static unsigned pmatch(const char *p, const char *s, unsigned len) | |||
339 | /*** ex fmt_ptime.[ch] ***/ | 339 | /*** ex fmt_ptime.[ch] ***/ |
340 | 340 | ||
341 | /* NUL terminated */ | 341 | /* NUL terminated */ |
342 | static void fmt_time_human_30nul(char *s) | 342 | static void fmt_time_human_30nul(char *s, char dt_delim) |
343 | { | 343 | { |
344 | struct tm *ptm; | 344 | struct tm *ptm; |
345 | struct timeval tv; | 345 | struct timeval tv; |
346 | 346 | ||
347 | gettimeofday(&tv, NULL); | 347 | gettimeofday(&tv, NULL); |
348 | ptm = gmtime(&tv.tv_sec); | 348 | ptm = gmtime(&tv.tv_sec); |
349 | sprintf(s, "%04u-%02u-%02u_%02u:%02u:%02u.%06u000", | 349 | sprintf(s, "%04u-%02u-%02u%c%02u:%02u:%02u.%06u000", |
350 | (unsigned)(1900 + ptm->tm_year), | 350 | (unsigned)(1900 + ptm->tm_year), |
351 | (unsigned)(ptm->tm_mon + 1), | 351 | (unsigned)(ptm->tm_mon + 1), |
352 | (unsigned)(ptm->tm_mday), | 352 | (unsigned)(ptm->tm_mday), |
353 | dt_delim, | ||
353 | (unsigned)(ptm->tm_hour), | 354 | (unsigned)(ptm->tm_hour), |
354 | (unsigned)(ptm->tm_min), | 355 | (unsigned)(ptm->tm_min), |
355 | (unsigned)(ptm->tm_sec), | 356 | (unsigned)(ptm->tm_sec), |
@@ -1160,8 +1161,8 @@ int svlogd_main(int argc, char **argv) | |||
1160 | if (timestamp) { | 1161 | if (timestamp) { |
1161 | if (timestamp == 1) | 1162 | if (timestamp == 1) |
1162 | fmt_time_bernstein_25(stamp); | 1163 | fmt_time_bernstein_25(stamp); |
1163 | else /* 2: */ | 1164 | else /* 2+: */ |
1164 | fmt_time_human_30nul(stamp); | 1165 | fmt_time_human_30nul(stamp, timestamp == 2 ? '_' : 'T'); |
1165 | printlen += 26; | 1166 | printlen += 26; |
1166 | printptr -= 26; | 1167 | printptr -= 26; |
1167 | memcpy(printptr, stamp, 25); | 1168 | memcpy(printptr, stamp, 25); |
diff --git a/shell/ash.c b/shell/ash.c index 0325a325c..bdbcd6987 100644 --- a/shell/ash.c +++ b/shell/ash.c | |||
@@ -3554,11 +3554,9 @@ unaliascmd(int argc UNUSED_PARAM, char **argv UNUSED_PARAM) | |||
3554 | { | 3554 | { |
3555 | int i; | 3555 | int i; |
3556 | 3556 | ||
3557 | while ((i = nextopt("a")) != '\0') { | 3557 | while (nextopt("a") != '\0') { |
3558 | if (i == 'a') { | 3558 | rmaliases(); |
3559 | rmaliases(); | 3559 | return 0; |
3560 | return 0; | ||
3561 | } | ||
3562 | } | 3560 | } |
3563 | for (i = 0; *argptr; argptr++) { | 3561 | for (i = 0; *argptr; argptr++) { |
3564 | if (unalias(*argptr)) { | 3562 | if (unalias(*argptr)) { |
@@ -4069,7 +4067,7 @@ setjobctl(int on) | |||
4069 | } | 4067 | } |
4070 | /* fd is a tty at this point */ | 4068 | /* fd is a tty at this point */ |
4071 | fd = fcntl(fd, F_DUPFD, 10); | 4069 | fd = fcntl(fd, F_DUPFD, 10); |
4072 | if (ofd >= 0) /* if it is "/dev/tty", close. If 0/1/2, dont */ | 4070 | if (ofd >= 0) /* if it is "/dev/tty", close. If 0/1/2, don't */ |
4073 | close(ofd); | 4071 | close(ofd); |
4074 | if (fd < 0) | 4072 | if (fd < 0) |
4075 | goto out; /* F_DUPFD failed */ | 4073 | goto out; /* F_DUPFD failed */ |
@@ -6692,7 +6690,7 @@ static char *evalvar(char *p, int flags, struct strlist *var_str_list); | |||
6692 | * $@ like $* since no splitting will be performed. | 6690 | * $@ like $* since no splitting will be performed. |
6693 | * | 6691 | * |
6694 | * var_str_list (can be NULL) is a list of "VAR=val" strings which take precedence | 6692 | * var_str_list (can be NULL) is a list of "VAR=val" strings which take precedence |
6695 | * over shell varables. Needed for "A=a B=$A; echo $B" case - we use it | 6693 | * over shell variables. Needed for "A=a B=$A; echo $B" case - we use it |
6696 | * for correct expansion of "B=$A" word. | 6694 | * for correct expansion of "B=$A" word. |
6697 | */ | 6695 | */ |
6698 | static void | 6696 | static void |
@@ -6902,8 +6900,8 @@ scanright(char *startp, char *rmesc, char *rmescend, | |||
6902 | if (try2optimize) { | 6900 | if (try2optimize) { |
6903 | /* Maybe we can optimize this: | 6901 | /* Maybe we can optimize this: |
6904 | * if pattern ends with unescaped *, we can avoid checking | 6902 | * if pattern ends with unescaped *, we can avoid checking |
6905 | * shorter strings: if "foo*" doesnt match "raw_value_of_v", | 6903 | * shorter strings: if "foo*" doesn't match "raw_value_of_v", |
6906 | * it wont match truncated "raw_value_of_" strings too. | 6904 | * it won't match truncated "raw_value_of_" strings too. |
6907 | */ | 6905 | */ |
6908 | unsigned plen = strlen(pattern); | 6906 | unsigned plen = strlen(pattern); |
6909 | /* Does it end with "*"? */ | 6907 | /* Does it end with "*"? */ |
@@ -7630,7 +7628,7 @@ expandmeta(struct strlist *str /*, int flag*/) | |||
7630 | // Which means you need to unescape the string, right? Not so fast: | 7628 | // Which means you need to unescape the string, right? Not so fast: |
7631 | // if there _is_ a file named "file\?" (with backslash), it is returned | 7629 | // if there _is_ a file named "file\?" (with backslash), it is returned |
7632 | // as "file\?" too (whichever pattern you used to find it, say, "file*"). | 7630 | // as "file\?" too (whichever pattern you used to find it, say, "file*"). |
7633 | // You DONT KNOW by looking at the result whether you need to unescape it. | 7631 | // You DON'T KNOW by looking at the result whether you need to unescape it. |
7634 | // | 7632 | // |
7635 | // Worse, globbing of "file\?" in a directory with two files, "file?" and "file\?", | 7633 | // Worse, globbing of "file\?" in a directory with two files, "file?" and "file\?", |
7636 | // returns "file\?" - which is WRONG: "file\?" pattern matches "file?" file. | 7634 | // returns "file\?" - which is WRONG: "file\?" pattern matches "file?" file. |
@@ -8124,9 +8122,8 @@ tryexec(IF_FEATURE_SH_STANDALONE(int applet_no,) char *cmd, char **argv, char ** | |||
8124 | * have to change the find_command routine as well. | 8122 | * have to change the find_command routine as well. |
8125 | * argv[-1] must exist and be writable! See tryexec() for why. | 8123 | * argv[-1] must exist and be writable! See tryexec() for why. |
8126 | */ | 8124 | */ |
8127 | static void shellexec(char **, const char *, int) NORETURN; | 8125 | static void shellexec(char *prog, char **argv, const char *path, int idx) NORETURN; |
8128 | static void | 8126 | static void shellexec(char *prog, char **argv, const char *path, int idx) |
8129 | shellexec(char **argv, const char *path, int idx) | ||
8130 | { | 8127 | { |
8131 | char *cmdname; | 8128 | char *cmdname; |
8132 | int e; | 8129 | int e; |
@@ -8135,12 +8132,12 @@ shellexec(char **argv, const char *path, int idx) | |||
8135 | int applet_no = -1; /* used only by FEATURE_SH_STANDALONE */ | 8132 | int applet_no = -1; /* used only by FEATURE_SH_STANDALONE */ |
8136 | 8133 | ||
8137 | envp = listvars(VEXPORT, VUNSET, /*end:*/ NULL); | 8134 | envp = listvars(VEXPORT, VUNSET, /*end:*/ NULL); |
8138 | if ((strchr(argv[0], '/') || (ENABLE_PLATFORM_MINGW32 && strchr(argv[0], '\\'))) | 8135 | if ((strchr(prog, '/') || (ENABLE_PLATFORM_MINGW32 && strchr(prog, '\\'))) |
8139 | #if ENABLE_FEATURE_SH_STANDALONE | 8136 | #if ENABLE_FEATURE_SH_STANDALONE |
8140 | || (applet_no = find_applet_by_name(argv[0])) >= 0 | 8137 | || (applet_no = find_applet_by_name(prog)) >= 0 |
8141 | #endif | 8138 | #endif |
8142 | ) { | 8139 | ) { |
8143 | tryexec(IF_FEATURE_SH_STANDALONE(applet_no,) argv[0], argv, envp); | 8140 | tryexec(IF_FEATURE_SH_STANDALONE(applet_no,) prog, argv, envp); |
8144 | if (applet_no >= 0) { | 8141 | if (applet_no >= 0) { |
8145 | /* We tried execing ourself, but it didn't work. | 8142 | /* We tried execing ourself, but it didn't work. |
8146 | * Maybe /proc/self/exe doesn't exist? | 8143 | * Maybe /proc/self/exe doesn't exist? |
@@ -8157,7 +8154,7 @@ shellexec(char **argv, const char *path, int idx) | |||
8157 | } else { | 8154 | } else { |
8158 | try_PATH: | 8155 | try_PATH: |
8159 | e = ENOENT; | 8156 | e = ENOENT; |
8160 | while ((cmdname = path_advance(&path, argv[0])) != NULL) { | 8157 | while ((cmdname = path_advance(&path, prog)) != NULL) { |
8161 | if (--idx < 0 && pathopt == NULL) { | 8158 | if (--idx < 0 && pathopt == NULL) { |
8162 | tryexec(IF_FEATURE_SH_STANDALONE(-1,) cmdname, argv, envp); | 8159 | tryexec(IF_FEATURE_SH_STANDALONE(-1,) cmdname, argv, envp); |
8163 | if (errno != ENOENT && errno != ENOTDIR) | 8160 | if (errno != ENOENT && errno != ENOTDIR) |
@@ -8181,8 +8178,8 @@ shellexec(char **argv, const char *path, int idx) | |||
8181 | } | 8178 | } |
8182 | exitstatus = exerrno; | 8179 | exitstatus = exerrno; |
8183 | TRACE(("shellexec failed for %s, errno %d, suppress_int %d\n", | 8180 | TRACE(("shellexec failed for %s, errno %d, suppress_int %d\n", |
8184 | argv[0], e, suppress_int)); | 8181 | prog, e, suppress_int)); |
8185 | ash_msg_and_raise(EXEXIT, "%s: %s", argv[0], errmsg(e, "not found")); | 8182 | ash_msg_and_raise(EXEXIT, "%s: %s", prog, errmsg(e, "not found")); |
8186 | /* NOTREACHED */ | 8183 | /* NOTREACHED */ |
8187 | } | 8184 | } |
8188 | 8185 | ||
@@ -8551,7 +8548,6 @@ static int | |||
8551 | describe_command(char *command, const char *path, int describe_command_verbose) | 8548 | describe_command(char *command, const char *path, int describe_command_verbose) |
8552 | { | 8549 | { |
8553 | struct cmdentry entry; | 8550 | struct cmdentry entry; |
8554 | struct tblentry *cmdp; | ||
8555 | #if ENABLE_ASH_ALIAS | 8551 | #if ENABLE_ASH_ALIAS |
8556 | const struct alias *ap; | 8552 | const struct alias *ap; |
8557 | #endif | 8553 | #endif |
@@ -8581,15 +8577,8 @@ describe_command(char *command, const char *path, int describe_command_verbose) | |||
8581 | goto out; | 8577 | goto out; |
8582 | } | 8578 | } |
8583 | #endif | 8579 | #endif |
8584 | /* Then check if it is a tracked alias */ | 8580 | /* Brute force */ |
8585 | cmdp = cmdlookup(command, 0); | 8581 | find_command(command, &entry, DO_ABS, path); |
8586 | if (cmdp != NULL) { | ||
8587 | entry.cmdtype = cmdp->cmdtype; | ||
8588 | entry.u = cmdp->param; | ||
8589 | } else { | ||
8590 | /* Finally use brute force */ | ||
8591 | find_command(command, &entry, DO_ABS, path); | ||
8592 | } | ||
8593 | 8582 | ||
8594 | switch (entry.cmdtype) { | 8583 | switch (entry.cmdtype) { |
8595 | case CMDNORMAL: { | 8584 | case CMDNORMAL: { |
@@ -8604,9 +8593,7 @@ describe_command(char *command, const char *path, int describe_command_verbose) | |||
8604 | } while (--j >= 0); | 8593 | } while (--j >= 0); |
8605 | } | 8594 | } |
8606 | if (describe_command_verbose) { | 8595 | if (describe_command_verbose) { |
8607 | out1fmt(" is%s %s", | 8596 | out1fmt(" is %s", p); |
8608 | (cmdp ? " a tracked alias for" : nullstr), p | ||
8609 | ); | ||
8610 | } else { | 8597 | } else { |
8611 | out1str(p); | 8598 | out1str(p); |
8612 | } | 8599 | } |
@@ -9814,7 +9801,14 @@ truecmd(int argc UNUSED_PARAM, char **argv UNUSED_PARAM) | |||
9814 | static int FAST_FUNC | 9801 | static int FAST_FUNC |
9815 | execcmd(int argc UNUSED_PARAM, char **argv) | 9802 | execcmd(int argc UNUSED_PARAM, char **argv) |
9816 | { | 9803 | { |
9817 | if (argv[1]) { | 9804 | optionarg = NULL; |
9805 | while (nextopt("a:") != '\0') | ||
9806 | /* nextopt() sets optionarg to "-a ARGV0" */; | ||
9807 | |||
9808 | argv = argptr; | ||
9809 | if (argv[0]) { | ||
9810 | char *prog; | ||
9811 | |||
9818 | iflag = 0; /* exit on error */ | 9812 | iflag = 0; /* exit on error */ |
9819 | mflag = 0; | 9813 | mflag = 0; |
9820 | optschanged(); | 9814 | optschanged(); |
@@ -9830,7 +9824,10 @@ execcmd(int argc UNUSED_PARAM, char **argv) | |||
9830 | /*setsignal(SIGTSTP); - unnecessary because of mflag=0 */ | 9824 | /*setsignal(SIGTSTP); - unnecessary because of mflag=0 */ |
9831 | /*setsignal(SIGTTOU); - unnecessary because of mflag=0 */ | 9825 | /*setsignal(SIGTTOU); - unnecessary because of mflag=0 */ |
9832 | 9826 | ||
9833 | shellexec(argv + 1, pathval(), 0); | 9827 | prog = argv[0]; |
9828 | if (optionarg) | ||
9829 | argv[0] = optionarg; | ||
9830 | shellexec(prog, argv, pathval(), 0); | ||
9834 | /* NOTREACHED */ | 9831 | /* NOTREACHED */ |
9835 | } | 9832 | } |
9836 | return 0; | 9833 | return 0; |
@@ -10255,7 +10252,7 @@ evalcommand(union node *cmd, int flags) | |||
10255 | } | 10252 | } |
10256 | #endif | 10253 | #endif |
10257 | listsetvar(varlist.list, VEXPORT|VSTACK); | 10254 | listsetvar(varlist.list, VEXPORT|VSTACK); |
10258 | shellexec(argv, path, cmdentry.u.index); | 10255 | shellexec(argv[0], argv, path, cmdentry.u.index); |
10259 | /* NOTREACHED */ | 10256 | /* NOTREACHED */ |
10260 | } /* default */ | 10257 | } /* default */ |
10261 | case CMDBUILTIN: | 10258 | case CMDBUILTIN: |
@@ -13605,7 +13602,7 @@ exportcmd(int argc UNUSED_PARAM, char **argv) | |||
13605 | } | 13602 | } |
13606 | flag_off = ~flag_off; | 13603 | flag_off = ~flag_off; |
13607 | 13604 | ||
13608 | /*if (opt_p_not_specified) - bash doesnt check this. Try "export -p NAME" */ | 13605 | /*if (opt_p_not_specified) - bash doesn't check this. Try "export -p NAME" */ |
13609 | { | 13606 | { |
13610 | aptr = argptr; | 13607 | aptr = argptr; |
13611 | name = *aptr; | 13608 | name = *aptr; |
@@ -13785,6 +13782,7 @@ readcmd(int argc UNUSED_PARAM, char **argv UNUSED_PARAM) | |||
13785 | /* "read -s" needs to save/restore termios, can't allow ^C | 13782 | /* "read -s" needs to save/restore termios, can't allow ^C |
13786 | * to jump out of it. | 13783 | * to jump out of it. |
13787 | */ | 13784 | */ |
13785 | again: | ||
13788 | INT_OFF; | 13786 | INT_OFF; |
13789 | r = shell_builtin_read(setvar0, | 13787 | r = shell_builtin_read(setvar0, |
13790 | argptr, | 13788 | argptr, |
@@ -13797,6 +13795,12 @@ readcmd(int argc UNUSED_PARAM, char **argv UNUSED_PARAM) | |||
13797 | ); | 13795 | ); |
13798 | INT_ON; | 13796 | INT_ON; |
13799 | 13797 | ||
13798 | if ((uintptr_t)r == 1 && errno == EINTR) { | ||
13799 | /* to get SIGCHLD: sleep 1 & read x; echo $x */ | ||
13800 | if (pending_sig == 0) | ||
13801 | goto again; | ||
13802 | } | ||
13803 | |||
13800 | if ((uintptr_t)r > 1) | 13804 | if ((uintptr_t)r > 1) |
13801 | ash_msg_and_raise_error(r); | 13805 | ash_msg_and_raise_error(r); |
13802 | 13806 | ||
@@ -14420,7 +14424,7 @@ forkshell_shellexec(struct forkshell *fs) | |||
14420 | char *path = fs->string; | 14424 | char *path = fs->string; |
14421 | 14425 | ||
14422 | listsetvar(varlist, VEXPORT|VSTACK); | 14426 | listsetvar(varlist, VEXPORT|VSTACK); |
14423 | shellexec(argv, path, idx); | 14427 | shellexec(argv[0], argv, path, idx); |
14424 | } | 14428 | } |
14425 | 14429 | ||
14426 | static void | 14430 | static void |
diff --git a/shell/ash_test/ash-misc/unicode1.tests b/shell/ash_test/ash-misc/unicode1.tests index 8788ba910..b8479cb41 100755 --- a/shell/ash_test/ash-misc/unicode1.tests +++ b/shell/ash_test/ash-misc/unicode1.tests | |||
@@ -5,7 +5,7 @@ a=`printf "\xcc\x80"` | |||
5 | # Should print 1 | 5 | # Should print 1 |
6 | echo ${#a} | 6 | echo ${#a} |
7 | 7 | ||
8 | # A Japanese katakana charachter U+30a3 | 8 | # A Japanese katakana character U+30a3 |
9 | a=`printf "\xe3\x82\xa3"` | 9 | a=`printf "\xe3\x82\xa3"` |
10 | # Should print 1 | 10 | # Should print 1 |
11 | echo ${#a} | 11 | echo ${#a} |
diff --git a/shell/ash_test/ash-read/read_SIGCHLD.right b/shell/ash_test/ash-read/read_SIGCHLD.right new file mode 100644 index 000000000..b3dc7ab0c --- /dev/null +++ b/shell/ash_test/ash-read/read_SIGCHLD.right | |||
@@ -0,0 +1,2 @@ | |||
1 | x='Ok' | ||
2 | exitcode:0 | ||
diff --git a/shell/ash_test/ash-read/read_SIGCHLD.tests b/shell/ash_test/ash-read/read_SIGCHLD.tests new file mode 100755 index 000000000..c5f673aff --- /dev/null +++ b/shell/ash_test/ash-read/read_SIGCHLD.tests | |||
@@ -0,0 +1,4 @@ | |||
1 | x=BAD | ||
2 | { sleep 0.4; echo Ok; } | { sleep 0.2 & read x; echo "x='$x'"; } | ||
3 | echo "exitcode:$?" | ||
4 | |||
diff --git a/shell/hush.c b/shell/hush.c index 4123cc19e..125463a56 100644 --- a/shell/hush.c +++ b/shell/hush.c | |||
@@ -1908,7 +1908,7 @@ static int check_and_run_traps(void) | |||
1908 | G.count_SIGCHLD++; | 1908 | G.count_SIGCHLD++; |
1909 | //bb_error_msg("[%d] check_and_run_traps: G.count_SIGCHLD:%d G.handled_SIGCHLD:%d", getpid(), G.count_SIGCHLD, G.handled_SIGCHLD); | 1909 | //bb_error_msg("[%d] check_and_run_traps: G.count_SIGCHLD:%d G.handled_SIGCHLD:%d", getpid(), G.count_SIGCHLD, G.handled_SIGCHLD); |
1910 | /* Note: | 1910 | /* Note: |
1911 | * We dont do 'last_sig = sig' here -> NOT returning this sig. | 1911 | * We don't do 'last_sig = sig' here -> NOT returning this sig. |
1912 | * This simplifies wait builtin a bit. | 1912 | * This simplifies wait builtin a bit. |
1913 | */ | 1913 | */ |
1914 | break; | 1914 | break; |
@@ -1917,7 +1917,7 @@ static int check_and_run_traps(void) | |||
1917 | debug_printf_exec("%s: sig:%d default handling is to ignore\n", __func__, sig); | 1917 | debug_printf_exec("%s: sig:%d default handling is to ignore\n", __func__, sig); |
1918 | /* SIGTERM, SIGQUIT, SIGTTIN, SIGTTOU, SIGTSTP */ | 1918 | /* SIGTERM, SIGQUIT, SIGTTIN, SIGTTOU, SIGTSTP */ |
1919 | /* Note: | 1919 | /* Note: |
1920 | * We dont do 'last_sig = sig' here -> NOT returning this sig. | 1920 | * We don't do 'last_sig = sig' here -> NOT returning this sig. |
1921 | * Example: wait is not interrupted by TERM | 1921 | * Example: wait is not interrupted by TERM |
1922 | * in interactive shell, because TERM is ignored. | 1922 | * in interactive shell, because TERM is ignored. |
1923 | */ | 1923 | */ |
@@ -2280,7 +2280,7 @@ static void reinit_unicode_for_hush(void) | |||
2280 | * AT\ | 2280 | * AT\ |
2281 | * H\ | 2281 | * H\ |
2282 | * \ | 2282 | * \ |
2283 | * It excercises a lot of corner cases. | 2283 | * It exercises a lot of corner cases. |
2284 | */ | 2284 | */ |
2285 | static void cmdedit_update_prompt(void) | 2285 | static void cmdedit_update_prompt(void) |
2286 | { | 2286 | { |
@@ -5235,7 +5235,7 @@ static void o_addblock_duplicate_backslash(o_string *o, const char *str, int len | |||
5235 | /* And now we want to add { or } and continue: | 5235 | /* And now we want to add { or } and continue: |
5236 | * o_addchr(o, c); | 5236 | * o_addchr(o, c); |
5237 | * continue; | 5237 | * continue; |
5238 | * luckily, just falling throught achieves this. | 5238 | * luckily, just falling through achieves this. |
5239 | */ | 5239 | */ |
5240 | } | 5240 | } |
5241 | #endif | 5241 | #endif |
@@ -5830,7 +5830,7 @@ static NOINLINE int expand_vars_to_list(o_string *output, int n, char *arg) | |||
5830 | arg++; | 5830 | arg++; |
5831 | /* Can't just stuff it into output o_string, | 5831 | /* Can't just stuff it into output o_string, |
5832 | * expanded result may need to be globbed | 5832 | * expanded result may need to be globbed |
5833 | * and $IFS-splitted */ | 5833 | * and $IFS-split */ |
5834 | debug_printf_subst("SUBST '%s' first_ch %x\n", arg, first_ch); | 5834 | debug_printf_subst("SUBST '%s' first_ch %x\n", arg, first_ch); |
5835 | G.last_exitcode = process_command_subs(&subst_result, arg); | 5835 | G.last_exitcode = process_command_subs(&subst_result, arg); |
5836 | debug_printf_subst("SUBST RES:%d '%s'\n", G.last_exitcode, subst_result.data); | 5836 | debug_printf_subst("SUBST RES:%d '%s'\n", G.last_exitcode, subst_result.data); |
@@ -7320,7 +7320,7 @@ static int process_wait_result(struct pipe *fg_pipe, pid_t childpid, int status) | |||
7320 | /* There are still running processes in the fg_pipe */ | 7320 | /* There are still running processes in the fg_pipe */ |
7321 | return -1; | 7321 | return -1; |
7322 | } | 7322 | } |
7323 | /* It wasnt in fg_pipe, look for process in bg pipes */ | 7323 | /* It wasn't in fg_pipe, look for process in bg pipes */ |
7324 | } | 7324 | } |
7325 | 7325 | ||
7326 | #if ENABLE_HUSH_JOB | 7326 | #if ENABLE_HUSH_JOB |
@@ -9038,6 +9038,9 @@ static int FAST_FUNC builtin_type(char **argv) | |||
9038 | * - terminates shell (regardless of interactivity); | 9038 | * - terminates shell (regardless of interactivity); |
9039 | * if it has non-empty trap: | 9039 | * if it has non-empty trap: |
9040 | * - executes trap and returns to read; | 9040 | * - executes trap and returns to read; |
9041 | * SIGCHLD from children: | ||
9042 | * - does not interrupt read regardless of interactivity: | ||
9043 | * try: sleep 1 & read x; echo $x | ||
9041 | */ | 9044 | */ |
9042 | static int FAST_FUNC builtin_read(char **argv) | 9045 | static int FAST_FUNC builtin_read(char **argv) |
9043 | { | 9046 | { |
@@ -9071,7 +9074,7 @@ static int FAST_FUNC builtin_read(char **argv) | |||
9071 | 9074 | ||
9072 | if ((uintptr_t)r == 1 && errno == EINTR) { | 9075 | if ((uintptr_t)r == 1 && errno == EINTR) { |
9073 | unsigned sig = check_and_run_traps(); | 9076 | unsigned sig = check_and_run_traps(); |
9074 | if (sig && sig != SIGINT) | 9077 | if (sig != SIGINT) |
9075 | goto again; | 9078 | goto again; |
9076 | } | 9079 | } |
9077 | 9080 | ||
diff --git a/shell/hush_test/hush-misc/unicode1.tests b/shell/hush_test/hush-misc/unicode1.tests index 8788ba910..b8479cb41 100755 --- a/shell/hush_test/hush-misc/unicode1.tests +++ b/shell/hush_test/hush-misc/unicode1.tests | |||
@@ -5,7 +5,7 @@ a=`printf "\xcc\x80"` | |||
5 | # Should print 1 | 5 | # Should print 1 |
6 | echo ${#a} | 6 | echo ${#a} |
7 | 7 | ||
8 | # A Japanese katakana charachter U+30a3 | 8 | # A Japanese katakana character U+30a3 |
9 | a=`printf "\xe3\x82\xa3"` | 9 | a=`printf "\xe3\x82\xa3"` |
10 | # Should print 1 | 10 | # Should print 1 |
11 | echo ${#a} | 11 | echo ${#a} |
diff --git a/shell/hush_test/hush-read/read_SIGCHLD.right b/shell/hush_test/hush-read/read_SIGCHLD.right new file mode 100644 index 000000000..b3dc7ab0c --- /dev/null +++ b/shell/hush_test/hush-read/read_SIGCHLD.right | |||
@@ -0,0 +1,2 @@ | |||
1 | x='Ok' | ||
2 | exitcode:0 | ||
diff --git a/shell/hush_test/hush-read/read_SIGCHLD.tests b/shell/hush_test/hush-read/read_SIGCHLD.tests new file mode 100755 index 000000000..c5f673aff --- /dev/null +++ b/shell/hush_test/hush-read/read_SIGCHLD.tests | |||
@@ -0,0 +1,4 @@ | |||
1 | x=BAD | ||
2 | { sleep 0.4; echo Ok; } | { sleep 0.2 & read x; echo "x='$x'"; } | ||
3 | echo "exitcode:$?" | ||
4 | |||
diff --git a/shell/shell_common.c b/shell/shell_common.c index 653154e34..55617b167 100644 --- a/shell/shell_common.c +++ b/shell/shell_common.c | |||
@@ -210,15 +210,17 @@ shell_builtin_read(void FAST_FUNC (*setvar)(const char *name, const char *val), | |||
210 | c = buffer[bufpos]; | 210 | c = buffer[bufpos]; |
211 | if (c == '\0' || (ENABLE_PLATFORM_MINGW32 && c == '\r')) | 211 | if (c == '\0' || (ENABLE_PLATFORM_MINGW32 && c == '\r')) |
212 | continue; | 212 | continue; |
213 | if (backslash) { | 213 | if (!(read_flags & BUILTIN_READ_RAW)) { |
214 | backslash = 0; | 214 | if (backslash) { |
215 | if (c != '\n') | 215 | backslash = 0; |
216 | goto put; | 216 | if (c != '\n') |
217 | continue; | 217 | goto put; |
218 | } | 218 | continue; |
219 | if (!(read_flags & BUILTIN_READ_RAW) && c == '\\') { | 219 | } |
220 | backslash = 1; | 220 | if (c == '\\') { |
221 | continue; | 221 | backslash = 1; |
222 | continue; | ||
223 | } | ||
222 | } | 224 | } |
223 | if (c == '\n') | 225 | if (c == '\n') |
224 | break; | 226 | break; |
@@ -408,13 +410,7 @@ shell_builtin_ulimit(char **argv) | |||
408 | /* In case getopt was already called: | 410 | /* In case getopt was already called: |
409 | * reset the libc getopt() function, which keeps internal state. | 411 | * reset the libc getopt() function, which keeps internal state. |
410 | */ | 412 | */ |
411 | #ifdef __GLIBC__ | 413 | GETOPT_RESET(); |
412 | optind = 0; | ||
413 | #else /* BSD style */ | ||
414 | optind = 1; | ||
415 | /* optreset = 1; */ | ||
416 | #endif | ||
417 | /* optarg = NULL; opterr = 0; optopt = 0; - do we need this?? */ | ||
418 | 414 | ||
419 | argc = 1; | 415 | argc = 1; |
420 | while (argv[argc]) | 416 | while (argv[argc]) |
diff --git a/sysklogd/logread.c b/sysklogd/logread.c index 1f0c6252d..71459941e 100644 --- a/sysklogd/logread.c +++ b/sysklogd/logread.c | |||
@@ -24,7 +24,7 @@ | |||
24 | //config: default y | 24 | //config: default y |
25 | //config: depends on LOGREAD | 25 | //config: depends on LOGREAD |
26 | //config: help | 26 | //config: help |
27 | //config: 'logread' ouput to slow serial terminals can have | 27 | //config: 'logread' output to slow serial terminals can have |
28 | //config: side effects on syslog because of the semaphore. | 28 | //config: side effects on syslog because of the semaphore. |
29 | //config: This option make logread to double buffer copy | 29 | //config: This option make logread to double buffer copy |
30 | //config: from circular buffer, minimizing semaphore | 30 | //config: from circular buffer, minimizing semaphore |
@@ -159,7 +159,7 @@ int logread_main(int argc UNUSED_PARAM, char **argv) | |||
159 | cur, shbuf_tail, shbuf_size); | 159 | cur, shbuf_tail, shbuf_size); |
160 | 160 | ||
161 | if (!(follow & 1)) { /* not -f */ | 161 | if (!(follow & 1)) { /* not -f */ |
162 | /* if -F, "convert" it to -f, so that we dont | 162 | /* if -F, "convert" it to -f, so that we don't |
163 | * dump the entire buffer on each iteration | 163 | * dump the entire buffer on each iteration |
164 | */ | 164 | */ |
165 | follow >>= 1; | 165 | follow >>= 1; |
diff --git a/testsuite/factor.tests b/testsuite/factor.tests new file mode 100755 index 000000000..2cf4a54ce --- /dev/null +++ b/testsuite/factor.tests | |||
@@ -0,0 +1,48 @@ | |||
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 "test name" "command" "expected result" "file input" "stdin" | ||
9 | # file input will be file called "input" | ||
10 | # test can create a file "actual" instead of writing to stdout | ||
11 | |||
12 | testing "factor ' 0'" \ | ||
13 | "factor ' 0'" \ | ||
14 | "0:\n" \ | ||
15 | "" "" | ||
16 | testing "factor +1" \ | ||
17 | "factor +1" \ | ||
18 | "1:\n" \ | ||
19 | "" "" | ||
20 | testing "factor ' +2'" \ | ||
21 | "factor ' +2'" \ | ||
22 | "2: 2\n" \ | ||
23 | "" "" | ||
24 | |||
25 | testing "factor 1024" \ | ||
26 | "factor 1024" \ | ||
27 | "1024: 2 2 2 2 2 2 2 2 2 2\n" \ | ||
28 | "" "" | ||
29 | |||
30 | testing "factor 2^61-1" \ | ||
31 | "factor 2305843009213693951" \ | ||
32 | "2305843009213693951: 2305843009213693951\n" \ | ||
33 | "" "" | ||
34 | testing "factor 2^62-1" \ | ||
35 | "factor 4611686018427387903" \ | ||
36 | "4611686018427387903: 3 715827883 2147483647\n" \ | ||
37 | "" "" | ||
38 | testing "factor 2^64-1" \ | ||
39 | "factor 18446744073709551615" \ | ||
40 | "18446744073709551615: 3 5 17 257 641 65537 6700417\n" \ | ||
41 | "" "" | ||
42 | # This is a 60-bit number (0x888 86ff db34 4692): first few primes multiplied together: | ||
43 | testing "factor \$((2*3*5*7*11*13*17*19*23*29*31*37*41*43*47))" \ | ||
44 | "factor \$((2*3*5*7*11*13*17*19*23*29*31*37*41*43*47))" \ | ||
45 | "614889782588491410: 2 3 5 7 11 13 17 19 23 29 31 37 41 43 47\n" \ | ||
46 | "" "" | ||
47 | |||
48 | exit $FAILCOUNT | ||
diff --git a/testsuite/paste/paste b/testsuite/paste/paste new file mode 100644 index 000000000..349b49d49 --- /dev/null +++ b/testsuite/paste/paste | |||
@@ -0,0 +1,20 @@ | |||
1 | cat > foo <<EOF | ||
2 | foo1 | ||
3 | foo2 | ||
4 | foo3 | ||
5 | EOF | ||
6 | |||
7 | cat > bar <<EOF | ||
8 | bar1 | ||
9 | bar2 | ||
10 | bar3 | ||
11 | EOF | ||
12 | |||
13 | cat > baz <<EOF | ||
14 | foo1 bar1 | ||
15 | foo2 bar2 | ||
16 | foo3 bar3 | ||
17 | EOF | ||
18 | |||
19 | busybox paste foo bar > qux | ||
20 | diff -u baz qux | ||
diff --git a/testsuite/paste/paste-back-cuted-lines b/testsuite/paste/paste-back-cuted-lines new file mode 100644 index 000000000..a8171bf1e --- /dev/null +++ b/testsuite/paste/paste-back-cuted-lines | |||
@@ -0,0 +1,9 @@ | |||
1 | cat > foo <<EOF | ||
2 | this is the first line | ||
3 | this is the second line | ||
4 | this is the third line | ||
5 | EOF | ||
6 | cut -b 1-13 -n foo > foo1 | ||
7 | cut -b 14- -n foo > foo2 | ||
8 | busybox paste -d '\0' foo1 foo2 > bar | ||
9 | cmp foo bar | ||
diff --git a/testsuite/paste/paste-multi-stdin b/testsuite/paste/paste-multi-stdin new file mode 100644 index 000000000..fee543058 --- /dev/null +++ b/testsuite/paste/paste-multi-stdin | |||
@@ -0,0 +1,16 @@ | |||
1 | cat > foo <<EOF | ||
2 | line1 | ||
3 | line2 | ||
4 | line3 | ||
5 | line4 | ||
6 | line5 | ||
7 | line6 | ||
8 | EOF | ||
9 | |||
10 | cat > bar <<EOF | ||
11 | line1 line2 line3 | ||
12 | line4 line5 line6 | ||
13 | EOF | ||
14 | |||
15 | busybox paste - - - < foo > baz | ||
16 | cmp bar baz | ||
diff --git a/testsuite/paste/paste-pairs b/testsuite/paste/paste-pairs new file mode 100644 index 000000000..90725fa87 --- /dev/null +++ b/testsuite/paste/paste-pairs | |||
@@ -0,0 +1,16 @@ | |||
1 | cat > foo <<EOF | ||
2 | foo1 | ||
3 | bar1 | ||
4 | foo2 | ||
5 | bar2 | ||
6 | foo3 | ||
7 | EOF | ||
8 | |||
9 | cat > bar <<EOF | ||
10 | foo1 bar1 | ||
11 | foo2 bar2 | ||
12 | foo3 | ||
13 | EOF | ||
14 | |||
15 | busybox paste -s -d "\t\n" foo > baz | ||
16 | cmp bar baz | ||
diff --git a/testsuite/paste/paste-separate b/testsuite/paste/paste-separate new file mode 100644 index 000000000..40793fb31 --- /dev/null +++ b/testsuite/paste/paste-separate | |||
@@ -0,0 +1,19 @@ | |||
1 | cat > foo <<EOF | ||
2 | foo1 | ||
3 | foo2 | ||
4 | foo3 | ||
5 | EOF | ||
6 | |||
7 | cat > bar <<EOF | ||
8 | bar1 | ||
9 | bar2 | ||
10 | bar3 | ||
11 | EOF | ||
12 | |||
13 | cat > baz <<EOF | ||
14 | foo1 foo2 foo3 | ||
15 | bar1 bar2 bar3 | ||
16 | EOF | ||
17 | |||
18 | busybox paste -s foo bar > qux | ||
19 | cmp baz qux | ||
diff --git a/testsuite/readlink.tests b/testsuite/readlink.tests index e9d8da0fc..27b52f6c4 100755 --- a/testsuite/readlink.tests +++ b/testsuite/readlink.tests | |||
@@ -29,7 +29,7 @@ pwd=`$pwd` | |||
29 | testing "readlink -f on a file" "readlink -f ./$TESTFILE" "$pwd/$TESTFILE\n" "" "" | 29 | testing "readlink -f on a file" "readlink -f ./$TESTFILE" "$pwd/$TESTFILE\n" "" "" |
30 | testing "readlink -f on a link" "readlink -f ./$TESTLINK" "$pwd/$TESTFILE\n" "" "" | 30 | testing "readlink -f on a link" "readlink -f ./$TESTLINK" "$pwd/$TESTFILE\n" "" "" |
31 | testing "readlink -f on an invalid link" "readlink -f ./$FAILLINK" "" "" "" | 31 | testing "readlink -f on an invalid link" "readlink -f ./$FAILLINK" "" "" "" |
32 | testing "readlink -f on a wierd dir" "readlink -f $TESTDIR/../$TESTFILE" "$pwd/$TESTFILE\n" "" "" | 32 | testing "readlink -f on a weird dir" "readlink -f $TESTDIR/../$TESTFILE" "$pwd/$TESTFILE\n" "" "" |
33 | 33 | ||
34 | 34 | ||
35 | # clean up | 35 | # clean up |
diff --git a/coreutils/cal.c b/util-linux/cal.c index af02608f0..8196619b0 100644 --- a/coreutils/cal.c +++ b/util-linux/cal.c | |||
@@ -35,7 +35,7 @@ | |||
35 | #include "libbb.h" | 35 | #include "libbb.h" |
36 | #include "unicode.h" | 36 | #include "unicode.h" |
37 | 37 | ||
38 | /* We often use "unsigned" intead of "int", it's easier to div on most CPUs */ | 38 | /* We often use "unsigned" instead of "int", it's easier to div on most CPUs */ |
39 | 39 | ||
40 | #define THURSDAY 4 /* for reformation */ | 40 | #define THURSDAY 4 /* for reformation */ |
41 | #define SATURDAY 6 /* 1 Jan 1 was a Saturday */ | 41 | #define SATURDAY 6 /* 1 Jan 1 was a Saturday */ |
diff --git a/miscutils/chrt.c b/util-linux/chrt.c index 1604a6890..1604a6890 100644 --- a/miscutils/chrt.c +++ b/util-linux/chrt.c | |||
diff --git a/miscutils/eject.c b/util-linux/eject.c index 667932f6c..667932f6c 100644 --- a/miscutils/eject.c +++ b/util-linux/eject.c | |||
diff --git a/util-linux/fallocate.c b/util-linux/fallocate.c new file mode 100644 index 000000000..1cd851bde --- /dev/null +++ b/util-linux/fallocate.c | |||
@@ -0,0 +1,104 @@ | |||
1 | /* vi: set sw=4 ts=4: */ | ||
2 | /* | ||
3 | * Copyright (C) 2017 Denys Vlasenko <vda.linux@googlemail.com> | ||
4 | * | ||
5 | * Licensed under GPLv2, see file LICENSE in this source tree. | ||
6 | */ | ||
7 | |||
8 | //config:config FALLOCATE | ||
9 | //config: bool "fallocate" | ||
10 | //config: default y | ||
11 | //config: help | ||
12 | //config: Preallocate space for files. | ||
13 | |||
14 | //applet:IF_FALLOCATE(APPLET(fallocate, BB_DIR_USR_BIN, BB_SUID_DROP)) | ||
15 | |||
16 | //kbuild:lib-$(CONFIG_FALLOCATE) += fallocate.o | ||
17 | |||
18 | //usage:#define fallocate_trivial_usage | ||
19 | //usage: "[-o OFS] -l LEN FILE" | ||
20 | // fallocate [-c|-p|-z] [-n] [-o OFS] -l LEN FILE | ||
21 | // fallocate -d [-o OFS] [-l LEN] FILE | ||
22 | //usage:#define fallocate_full_usage "\n\n" | ||
23 | //usage: "Preallocate space for FILE\n" | ||
24 | // "\n -c Remove range" | ||
25 | // "\n -p Make hole" | ||
26 | // "\n -z Zero and allocate range" | ||
27 | // "\n -d Convert zeros to holes" | ||
28 | // "\n -n Keep size" | ||
29 | //usage: "\n -o OFS Offset of range" | ||
30 | //usage: "\n -l LEN Length of range" | ||
31 | |||
32 | //Upstream options: | ||
33 | //The options --collapse-range, --dig-holes, --punch-hole and --zero-range | ||
34 | //are mutually exclusive. | ||
35 | //-c, --collapse-range | ||
36 | // Removes a byte range from a file, without leaving a hole. The byte range | ||
37 | // to be collapsed starts at offset and continues for length bytes. | ||
38 | // At the completion of the operation, the contents of the file starting | ||
39 | // at the location offset+length will be appended at the location offset, | ||
40 | // and the file will be length bytes smaller. The option --keep-size may | ||
41 | // not be specified for the collapse-range operation. | ||
42 | //-d, --dig-holes | ||
43 | // Detect and dig holes. This makes the file sparse in-place, without using | ||
44 | // extra disk space. The minimum size of the hole depends on filesystem I/O | ||
45 | // block size (usually 4096 bytes). Also, | ||
46 | //-l, --length length | ||
47 | // Specifies the length of the range, in bytes. | ||
48 | //-n, --keep-size | ||
49 | // Do not modify the apparent length of the file. This may effectively | ||
50 | // allocate blocks past EOF, which can be removed with a truncate. | ||
51 | //-o, --offset offset | ||
52 | // Specifies the beginning offset of the range, in bytes. | ||
53 | //-p, --punch-hole | ||
54 | // Deallocates space (i.e., creates a hole) in the byte range starting | ||
55 | // at offset and continuing for length bytes. Within the specified range, | ||
56 | // partial filesystem blocks are zeroed, and whole | ||
57 | // filesystem blocks are removed from the file. After a successful call, | ||
58 | // subsequent reads from this range will return zeroes. This option may not | ||
59 | // be specified at the same time as the | ||
60 | // --zero-range option. Also, when using this option, --keep-size is implied. | ||
61 | //-z, --zero-range | ||
62 | // Zeroes space in the byte range starting at offset and continuing for | ||
63 | // length bytes. Within the specified range, blocks are preallocated for | ||
64 | // the regions that span the holes in the file. After | ||
65 | // a successful call, subsequent reads from this range will return zeroes. | ||
66 | // Zeroing is done within the filesystem preferably by converting the range | ||
67 | // into unwritten extents. This approach means that the specified range | ||
68 | // will not be physically zeroed out on the device (except for partial | ||
69 | // blocks at the either end of the range), and I/O is (otherwise) required | ||
70 | // only to update metadata. | ||
71 | // Option --keep-size can be specified to prevent file length modification. | ||
72 | |||
73 | #include "libbb.h" | ||
74 | |||
75 | int fallocate_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; | ||
76 | int fallocate_main(int argc UNUSED_PARAM, char **argv) | ||
77 | { | ||
78 | const char *str_l; | ||
79 | const char *str_o = "0"; | ||
80 | off_t ofs, len; | ||
81 | unsigned opts; | ||
82 | int fd; | ||
83 | |||
84 | /* exactly one non-option arg */ | ||
85 | opt_complementary = "=1"; | ||
86 | opts = getopt32(argv, "l:o:", &str_l, &str_o); | ||
87 | if (!(opts & 1)) | ||
88 | bb_show_usage(); | ||
89 | |||
90 | ofs = xatoull_sfx(str_o, kmg_i_suffixes); | ||
91 | len = xatoull_sfx(str_l, kmg_i_suffixes); | ||
92 | |||
93 | argv += optind; | ||
94 | fd = xopen3(*argv, O_RDWR | O_CREAT, 0666); | ||
95 | |||
96 | /* posix_fallocate has unusual method of returning error */ | ||
97 | /* maybe use Linux-specific fallocate(int fd, int mode, off_t offset, off_t len) instead? */ | ||
98 | if ((errno = posix_fallocate(fd, ofs, len)) != 0) | ||
99 | bb_perror_msg_and_die("fallocate '%s'", *argv); | ||
100 | |||
101 | /* util-linux also performs fsync(fd); */ | ||
102 | |||
103 | return EXIT_SUCCESS; | ||
104 | } | ||
diff --git a/util-linux/fsfreeze.c b/util-linux/fsfreeze.c new file mode 100644 index 000000000..70dec24ec --- /dev/null +++ b/util-linux/fsfreeze.c | |||
@@ -0,0 +1,54 @@ | |||
1 | /* vi: set sw=4 ts=4: */ | ||
2 | /* | ||
3 | * Copyright (C) 2017 Denys Vlasenko <vda.linux@googlemail.com> | ||
4 | * | ||
5 | * Licensed under GPLv2, see file LICENSE in this source tree. | ||
6 | */ | ||
7 | |||
8 | //config:config FSFREEZE | ||
9 | //config: bool "fsfreeze" | ||
10 | //config: default y | ||
11 | //config: select PLATFORM_LINUX | ||
12 | //config: select LONG_OPTS | ||
13 | //config: help | ||
14 | //config: Halt new accesses and flush writes on a mounted filesystem. | ||
15 | |||
16 | //applet:IF_FSFREEZE(APPLET(fsfreeze, BB_DIR_USR_SBIN, BB_SUID_DROP)) | ||
17 | |||
18 | //kbuild:lib-$(CONFIG_FSFREEZE) += fsfreeze.o | ||
19 | |||
20 | //usage:#define fsfreeze_trivial_usage | ||
21 | //usage: "--[un]freeze MOUNTPOINT" | ||
22 | //usage:#define fsfreeze_full_usage "\n\n" | ||
23 | //usage: "Flush and halt writes to MOUNTPOINT" | ||
24 | |||
25 | #include "libbb.h" | ||
26 | #include <linux/fs.h> | ||
27 | |||
28 | #ifndef FIFREEZE | ||
29 | # define FIFREEZE _IOWR('X', 119, int) | ||
30 | # define FITHAW _IOWR('X', 120, int) | ||
31 | #endif | ||
32 | |||
33 | int fsfreeze_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; | ||
34 | int fsfreeze_main(int argc UNUSED_PARAM, char **argv) | ||
35 | { | ||
36 | unsigned opts; | ||
37 | int fd; | ||
38 | |||
39 | applet_long_options = | ||
40 | "freeze\0" No_argument "\xff" | ||
41 | "unfreeze\0" No_argument "\xfe" | ||
42 | ; | ||
43 | /* exactly one non-option arg: the mountpoint */ | ||
44 | /* one of opts is required */ | ||
45 | /* opts are mutually exclusive */ | ||
46 | opt_complementary = "=1:""\xff:\xfe:""\xff--\xfe:\xfe--\xff"; | ||
47 | opts = getopt32(argv, ""); | ||
48 | |||
49 | fd = xopen(argv[optind], O_RDONLY); | ||
50 | /* Works with NULL arg on linux-4.8.0 */ | ||
51 | xioctl(fd, (opts & 1) ? FIFREEZE : FITHAW, NULL); | ||
52 | |||
53 | return EXIT_SUCCESS; | ||
54 | } | ||
diff --git a/util-linux/getopt.c b/util-linux/getopt.c index 63294c520..79d54854b 100644 --- a/util-linux/getopt.c +++ b/util-linux/getopt.c | |||
@@ -246,12 +246,7 @@ static int generate_output(char **argv, int argc, const char *optstr, const stru | |||
246 | 246 | ||
247 | /* We used it already in main() in getopt32(), | 247 | /* We used it already in main() in getopt32(), |
248 | * we *must* reset getopt(3): */ | 248 | * we *must* reset getopt(3): */ |
249 | #ifdef __GLIBC__ | 249 | GETOPT_RESET(); |
250 | optind = 0; | ||
251 | #else /* BSD style */ | ||
252 | optind = 1; | ||
253 | /* optreset = 1; */ | ||
254 | #endif | ||
255 | 250 | ||
256 | while (1) { | 251 | while (1) { |
257 | #if ENABLE_FEATURE_GETOPT_LONG | 252 | #if ENABLE_FEATURE_GETOPT_LONG |
diff --git a/util-linux/hwclock.c b/util-linux/hwclock.c index d65011a71..8cb908cb3 100644 --- a/util-linux/hwclock.c +++ b/util-linux/hwclock.c | |||
@@ -167,7 +167,7 @@ static void from_sys_clock(const char **pp_rtcname, int utc) | |||
167 | * On x86, even though code does set hw clock within <1ms of exact | 167 | * On x86, even though code does set hw clock within <1ms of exact |
168 | * whole seconds, apparently hw clock (at least on some machines) | 168 | * whole seconds, apparently hw clock (at least on some machines) |
169 | * doesn't reset internal fractional seconds to 0, | 169 | * doesn't reset internal fractional seconds to 0, |
170 | * making all this a pointless excercise. | 170 | * making all this a pointless exercise. |
171 | */ | 171 | */ |
172 | /* If we see that we are N usec away from whole second, | 172 | /* If we see that we are N usec away from whole second, |
173 | * we'll sleep for N-ADJ usecs. ADJ corrects for the fact | 173 | * we'll sleep for N-ADJ usecs. ADJ corrects for the fact |
diff --git a/miscutils/ionice.c b/util-linux/ionice.c index c54b3a6e1..c54b3a6e1 100644 --- a/miscutils/ionice.c +++ b/util-linux/ionice.c | |||
diff --git a/miscutils/last.c b/util-linux/last.c index b3f125c3f..b3f125c3f 100644 --- a/miscutils/last.c +++ b/util-linux/last.c | |||
diff --git a/miscutils/last_fancy.c b/util-linux/last_fancy.c index e56e0ba85..e56e0ba85 100644 --- a/miscutils/last_fancy.c +++ b/util-linux/last_fancy.c | |||
diff --git a/util-linux/losetup.c b/util-linux/losetup.c index 4424d9cbb..d356f49c2 100644 --- a/util-linux/losetup.c +++ b/util-linux/losetup.c | |||
@@ -127,12 +127,37 @@ int losetup_main(int argc UNUSED_PARAM, char **argv) | |||
127 | d = *argv++; | 127 | d = *argv++; |
128 | 128 | ||
129 | if (argv[0]) { | 129 | if (argv[0]) { |
130 | if (set_loop(&d, argv[0], offset, (opt & OPT_r)) < 0) | 130 | if (set_loop(&d, argv[0], offset, (opt & OPT_r) ? BB_LO_FLAGS_READ_ONLY : 0) < 0) |
131 | bb_simple_perror_msg_and_die(argv[0]); | 131 | bb_simple_perror_msg_and_die(argv[0]); |
132 | return EXIT_SUCCESS; | 132 | return EXIT_SUCCESS; |
133 | } | 133 | } |
134 | } | 134 | } |
135 | 135 | ||
136 | /* TODO: util-linux 2.28 shows this when run w/o params: | ||
137 | * NAME SIZELIMIT OFFSET AUTOCLEAR RO BACK-FILE DIO | ||
138 | * /dev/loop0 0 0 1 0 /PATH/TO/FILE 0 | ||
139 | * | ||
140 | * implemented by reading /sys: | ||
141 | * | ||
142 | * open("/sys/block", O_RDONLY|O_NONBLOCK|O_DIRECTORY|O_CLOEXEC) = 3 | ||
143 | * newfstatat(3, "loop0/loop/backing_file", {st_mode=S_IFREG|0444, st_size=4096, ...}, 0) = 0 | ||
144 | * stat("/dev/loop0", {st_mode=S_IFBLK|0660, st_rdev=makedev(7, 0), ...}) = 0 | ||
145 | * open("/sys/dev/block/7:0/loop/offset", O_RDONLY|O_CLOEXEC) = 5 | ||
146 | * read(5, "0\n", 4096) = 2 | ||
147 | * open("/sys/dev/block/7:0/loop/sizelimit", O_RDONLY|O_CLOEXEC) = 5 | ||
148 | * read(5, "0\n", 4096) = 2 | ||
149 | * open("/sys/dev/block/7:0/loop/offset", O_RDONLY|O_CLOEXEC) = 5 | ||
150 | * read(5, "0\n", 4096) = 2 | ||
151 | * open("/sys/dev/block/7:0/loop/autoclear", O_RDONLY|O_CLOEXEC) = 5 | ||
152 | * read(5, "1\n", 4096) = 2 | ||
153 | * open("/sys/dev/block/7:0/ro", O_RDONLY|O_CLOEXEC) = 5 | ||
154 | * read(5, "0\n", 4096) = 2 | ||
155 | * open("/sys/dev/block/7:0/loop/backing_file", O_RDONLY|O_CLOEXEC) = 5 | ||
156 | * read(5, "/PATH/TO/FILE", 4096) = 37 | ||
157 | * open("/sys/dev/block/7:0/loop/dio", O_RDONLY|O_CLOEXEC) = 5 | ||
158 | * read(5, "0\n", 4096) = 2 | ||
159 | */ | ||
160 | |||
136 | bb_show_usage(); /* does not return */ | 161 | bb_show_usage(); /* does not return */ |
137 | /*return EXIT_FAILURE;*/ | 162 | /*return EXIT_FAILURE;*/ |
138 | } | 163 | } |
diff --git a/init/mesg.c b/util-linux/mesg.c index 45c13b8e0..45c13b8e0 100644 --- a/init/mesg.c +++ b/util-linux/mesg.c | |||
diff --git a/util-linux/mount.c b/util-linux/mount.c index f0245f714..6bb18524d 100644 --- a/util-linux/mount.c +++ b/util-linux/mount.c | |||
@@ -1887,6 +1887,7 @@ static int nfsmount(struct mntent *mp, unsigned long vfsflags, char *filteropts) | |||
1887 | // NB: mp->xxx fields may be trashed on exit | 1887 | // NB: mp->xxx fields may be trashed on exit |
1888 | static int singlemount(struct mntent *mp, int ignore_busy) | 1888 | static int singlemount(struct mntent *mp, int ignore_busy) |
1889 | { | 1889 | { |
1890 | int loopfd = -1; | ||
1890 | int rc = -1; | 1891 | int rc = -1; |
1891 | unsigned long vfsflags; | 1892 | unsigned long vfsflags; |
1892 | char *loopFile = NULL, *filteropts = NULL; | 1893 | char *loopFile = NULL, *filteropts = NULL; |
@@ -2026,7 +2027,20 @@ static int singlemount(struct mntent *mp, int ignore_busy) | |||
2026 | if (ENABLE_FEATURE_MOUNT_LOOP && S_ISREG(st.st_mode)) { | 2027 | if (ENABLE_FEATURE_MOUNT_LOOP && S_ISREG(st.st_mode)) { |
2027 | loopFile = bb_simplify_path(mp->mnt_fsname); | 2028 | loopFile = bb_simplify_path(mp->mnt_fsname); |
2028 | mp->mnt_fsname = NULL; // will receive malloced loop dev name | 2029 | mp->mnt_fsname = NULL; // will receive malloced loop dev name |
2029 | if (set_loop(&mp->mnt_fsname, loopFile, 0, /*ro:*/ (vfsflags & MS_RDONLY)) < 0) { | 2030 | |
2031 | // mount always creates AUTOCLEARed loopdevs, so that umounting | ||
2032 | // drops them without any code in the userspace. | ||
2033 | // This happens since circa linux-2.6.25: | ||
2034 | // commit 96c5865559cee0f9cbc5173f3c949f6ce3525581 | ||
2035 | // Date: Wed Feb 6 01:36:27 2008 -0800 | ||
2036 | // Subject: Allow auto-destruction of loop devices | ||
2037 | loopfd = set_loop(&mp->mnt_fsname, | ||
2038 | loopFile, | ||
2039 | 0, | ||
2040 | ((vfsflags & MS_RDONLY) ? BB_LO_FLAGS_READ_ONLY : 0) | ||
2041 | | BB_LO_FLAGS_AUTOCLEAR | ||
2042 | ); | ||
2043 | if (loopfd < 0) { | ||
2030 | if (errno == EPERM || errno == EACCES) | 2044 | if (errno == EPERM || errno == EACCES) |
2031 | bb_error_msg(bb_msg_perm_denied_are_you_root); | 2045 | bb_error_msg(bb_msg_perm_denied_are_you_root); |
2032 | else | 2046 | else |
@@ -2074,6 +2088,8 @@ static int singlemount(struct mntent *mp, int ignore_busy) | |||
2074 | } | 2088 | } |
2075 | 2089 | ||
2076 | // If mount failed, clean up loop file (if any). | 2090 | // If mount failed, clean up loop file (if any). |
2091 | // (Newer kernels which support LO_FLAGS_AUTOCLEAR should not need this, | ||
2092 | // merely "close(loopfd)" should do it?) | ||
2077 | if (ENABLE_FEATURE_MOUNT_LOOP && rc && loopFile) { | 2093 | if (ENABLE_FEATURE_MOUNT_LOOP && rc && loopFile) { |
2078 | del_loop(mp->mnt_fsname); | 2094 | del_loop(mp->mnt_fsname); |
2079 | if (ENABLE_FEATURE_CLEAN_UP) { | 2095 | if (ENABLE_FEATURE_CLEAN_UP) { |
@@ -2086,6 +2102,9 @@ static int singlemount(struct mntent *mp, int ignore_busy) | |||
2086 | if (ENABLE_FEATURE_CLEAN_UP) | 2102 | if (ENABLE_FEATURE_CLEAN_UP) |
2087 | free(filteropts); | 2103 | free(filteropts); |
2088 | 2104 | ||
2105 | if (loopfd >= 0) | ||
2106 | close(loopfd); | ||
2107 | |||
2089 | if (errno == EBUSY && ignore_busy) | 2108 | if (errno == EBUSY && ignore_busy) |
2090 | return 0; | 2109 | return 0; |
2091 | if (errno == ENOENT && (vfsflags & MOUNT_NOFAIL)) | 2110 | if (errno == ENOENT && (vfsflags & MOUNT_NOFAIL)) |
diff --git a/miscutils/mountpoint.c b/util-linux/mountpoint.c index 8b9e1d779..8b9e1d779 100644 --- a/miscutils/mountpoint.c +++ b/util-linux/mountpoint.c | |||
diff --git a/procps/renice.c b/util-linux/renice.c index 64213c680..4da3394a8 100644 --- a/procps/renice.c +++ b/util-linux/renice.c | |||
@@ -141,7 +141,7 @@ int renice_main(int argc UNUSED_PARAM, char **argv) | |||
141 | retval = EXIT_FAILURE; | 141 | retval = EXIT_FAILURE; |
142 | } | 142 | } |
143 | 143 | ||
144 | /* No need to check for errors outputing to stderr since, if it | 144 | /* No need to check for errors outputting to stderr since, if it |
145 | * was used, the HAD_ERROR label was reached and retval was set. */ | 145 | * was used, the HAD_ERROR label was reached and retval was set. */ |
146 | 146 | ||
147 | return retval; | 147 | return retval; |
diff --git a/miscutils/setsid.c b/util-linux/setsid.c index 143a8f8fa..143a8f8fa 100644 --- a/miscutils/setsid.c +++ b/util-linux/setsid.c | |||
diff --git a/util-linux/switch_root.c b/util-linux/switch_root.c index 6034485d7..f18e8a5ce 100644 --- a/util-linux/switch_root.c +++ b/util-linux/switch_root.c | |||
@@ -141,10 +141,12 @@ int switch_root_main(int argc UNUSED_PARAM, char **argv) | |||
141 | 141 | ||
142 | // If a new console specified, redirect stdin/stdout/stderr to it | 142 | // If a new console specified, redirect stdin/stdout/stderr to it |
143 | if (console) { | 143 | if (console) { |
144 | close(0); | 144 | int fd = open_or_warn(console, O_RDWR); |
145 | xopen(console, O_RDWR); | 145 | if (fd >= 0) { |
146 | xdup2(0, 1); | 146 | xmove_fd(fd, 0); |
147 | xdup2(0, 2); | 147 | xdup2(0, 1); |
148 | xdup2(0, 2); | ||
149 | } | ||
148 | } | 150 | } |
149 | 151 | ||
150 | // Exec real init | 152 | // Exec real init |
@@ -181,7 +183,7 @@ So there's a step that needs to be sort of atomic but can't be as a shell | |||
181 | script. (You can work around this with static linking or very carefully laid | 183 | script. (You can work around this with static linking or very carefully laid |
182 | out paths and sequencing, but it's brittle, ugly, and non-obvious.) | 184 | out paths and sequencing, but it's brittle, ugly, and non-obvious.) |
183 | 185 | ||
184 | 2) The "find | rm" bit will acually delete everything because the mount points | 186 | 2) The "find | rm" bit will actually delete everything because the mount points |
185 | still show up (even if their contents don't), and rm -rf will then happily zap | 187 | still show up (even if their contents don't), and rm -rf will then happily zap |
186 | that. So the first line is an oversimplification of what you need to do _not_ | 188 | that. So the first line is an oversimplification of what you need to do _not_ |
187 | to descend into other filesystems and delete their contents. | 189 | to descend into other filesystems and delete their contents. |
diff --git a/miscutils/taskset.c b/util-linux/taskset.c index 94a07383a..94a07383a 100644 --- a/miscutils/taskset.c +++ b/util-linux/taskset.c | |||
diff --git a/util-linux/umount.c b/util-linux/umount.c index c958fd552..0c50dc9ee 100644 --- a/util-linux/umount.c +++ b/util-linux/umount.c | |||
@@ -42,7 +42,7 @@ | |||
42 | //usage: "\n -l Lazy umount (detach filesystem)" | 42 | //usage: "\n -l Lazy umount (detach filesystem)" |
43 | //usage: "\n -f Force umount (i.e., unreachable NFS server)" | 43 | //usage: "\n -f Force umount (i.e., unreachable NFS server)" |
44 | //usage: IF_FEATURE_MOUNT_LOOP( | 44 | //usage: IF_FEATURE_MOUNT_LOOP( |
45 | //usage: "\n -D Don't free loop device even if it has been used" | 45 | //usage: "\n -d Free loop device if it has been used" |
46 | //usage: ) | 46 | //usage: ) |
47 | //usage: | 47 | //usage: |
48 | //usage:#define umount_example_usage | 48 | //usage:#define umount_example_usage |
@@ -68,22 +68,14 @@ static struct mntent *getmntent_r(FILE* stream, struct mntent* result, | |||
68 | } | 68 | } |
69 | #endif | 69 | #endif |
70 | 70 | ||
71 | /* Ignored: -v -t -i | 71 | /* ignored: -v -t -i */ |
72 | * bbox always acts as if -d is present. | 72 | #define OPTION_STRING "fldnra" "vt:i" |
73 | * -D can be used to suppress it (bbox extension). | ||
74 | * Rationale: | ||
75 | * (1) util-linux's umount does it if "loop=..." is seen in /etc/mtab: | ||
76 | * thus, on many systems, bare umount _does_ drop loop devices. | ||
77 | * (2) many users request this feature. | ||
78 | */ | ||
79 | #define OPTION_STRING "fldDnra" "vt:i" | ||
80 | #define OPT_FORCE (1 << 0) // Same as MNT_FORCE | 73 | #define OPT_FORCE (1 << 0) // Same as MNT_FORCE |
81 | #define OPT_LAZY (1 << 1) // Same as MNT_DETACH | 74 | #define OPT_LAZY (1 << 1) // Same as MNT_DETACH |
82 | //#define OPT_FREE_LOOP (1 << 2) // -d is assumed always present | 75 | #define OPT_FREELOOP (1 << 2) |
83 | #define OPT_DONT_FREE_LOOP (1 << 3) | 76 | #define OPT_NO_MTAB (1 << 3) |
84 | #define OPT_NO_MTAB (1 << 4) | 77 | #define OPT_REMOUNT (1 << 4) |
85 | #define OPT_REMOUNT (1 << 5) | 78 | #define OPT_ALL (ENABLE_FEATURE_UMOUNT_ALL ? (1 << 5) : 0) |
86 | #define OPT_ALL (ENABLE_FEATURE_UMOUNT_ALL ? (1 << 6) : 0) | ||
87 | 79 | ||
88 | int umount_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; | 80 | int umount_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; |
89 | int umount_main(int argc UNUSED_PARAM, char **argv) | 81 | int umount_main(int argc UNUSED_PARAM, char **argv) |
@@ -206,7 +198,7 @@ int umount_main(int argc UNUSED_PARAM, char **argv) | |||
206 | } else { | 198 | } else { |
207 | // De-allocate the loop device. This ioctl should be ignored on | 199 | // De-allocate the loop device. This ioctl should be ignored on |
208 | // any non-loop block devices. | 200 | // any non-loop block devices. |
209 | if (ENABLE_FEATURE_MOUNT_LOOP && !(opt & OPT_DONT_FREE_LOOP) && m) | 201 | if (ENABLE_FEATURE_MOUNT_LOOP && (opt & OPT_FREELOOP) && m) |
210 | del_loop(m->device); | 202 | del_loop(m->device); |
211 | if (ENABLE_FEATURE_MTAB_SUPPORT && !(opt & OPT_NO_MTAB) && m) | 203 | if (ENABLE_FEATURE_MTAB_SUPPORT && !(opt & OPT_NO_MTAB) && m) |
212 | erase_mtab(m->dir); | 204 | erase_mtab(m->dir); |
diff --git a/util-linux/volume_id/udf.c b/util-linux/volume_id/udf.c index 613c80c86..fa5dccee7 100644 --- a/util-linux/volume_id/udf.c +++ b/util-linux/volume_id/udf.c | |||
@@ -137,7 +137,7 @@ anchor: | |||
137 | if (type != 2) /* TAG_ID_AVDP */ | 137 | if (type != 2) /* TAG_ID_AVDP */ |
138 | goto found; | 138 | goto found; |
139 | 139 | ||
140 | /* get desriptor list address and block count */ | 140 | /* get descriptor list address and block count */ |
141 | count = le32_to_cpu(vd->type.anchor.length) / bs; | 141 | count = le32_to_cpu(vd->type.anchor.length) / bs; |
142 | loc = le32_to_cpu(vd->type.anchor.location); | 142 | loc = le32_to_cpu(vd->type.anchor.location); |
143 | dbg("0x%x descriptors starting at logical secor 0x%x", count, loc); | 143 | dbg("0x%x descriptors starting at logical secor 0x%x", count, loc); |
diff --git a/miscutils/wall.c b/util-linux/wall.c index 50658f457..50658f457 100644 --- a/miscutils/wall.c +++ b/util-linux/wall.c | |||