diff options
author | Ron Yorston <rmy@pobox.com> | 2021-03-01 11:48:04 +0000 |
---|---|---|
committer | Ron Yorston <rmy@pobox.com> | 2021-03-01 11:48:04 +0000 |
commit | e2e8e16b465d34759678b8170c44ce62c5b74eb0 (patch) | |
tree | abc31e3e2c1d0de089ae5e1e6d37672394757af9 | |
parent | b5cd41cdf4e6afd475fe34b755f99578e20b08ca (diff) | |
parent | 9b6bcfda0e11c0e73a966a77110f6c68425cff34 (diff) | |
download | busybox-w32-e2e8e16b465d34759678b8170c44ce62c5b74eb0.tar.gz busybox-w32-e2e8e16b465d34759678b8170c44ce62c5b74eb0.tar.bz2 busybox-w32-e2e8e16b465d34759678b8170c44ce62c5b74eb0.zip |
Merge branch 'busybox' into merge
-rw-r--r-- | Makefile | 1 | ||||
-rw-r--r-- | Makefile.flags | 7 | ||||
-rw-r--r-- | applets/usage_pod.c | 2 | ||||
-rw-r--r-- | coreutils/echo.c | 10 | ||||
-rw-r--r-- | editors/diff.c | 2 | ||||
-rw-r--r-- | include/libbb.h | 1 | ||||
-rw-r--r-- | include/platform.h | 8 | ||||
-rw-r--r-- | libbb/appletlib.c | 70 | ||||
-rw-r--r-- | libbb/lineedit.c | 19 | ||||
-rw-r--r-- | libbb/platform.c | 12 | ||||
-rw-r--r-- | libbb/vfork_daemon_rexec.c | 5 | ||||
-rw-r--r-- | miscutils/bc.c | 64 | ||||
-rw-r--r-- | networking/dnsd.c | 17 | ||||
-rw-r--r-- | networking/ntpd.c | 280 | ||||
-rw-r--r-- | networking/udhcp/d6_dhcpc.c | 14 | ||||
-rw-r--r-- | networking/udhcp/dhcpc.c | 36 | ||||
-rw-r--r-- | networking/udhcp/dhcpd.c | 4 | ||||
-rwxr-xr-x | scripts/trylink | 17 | ||||
-rw-r--r-- | shell/ash.c | 4 | ||||
-rwxr-xr-x | testsuite/bc.tests | 5 | ||||
-rwxr-xr-x | testsuite/dc.tests | 5 |
21 files changed, 253 insertions, 330 deletions
@@ -625,6 +625,7 @@ quiet_cmd_busybox__ ?= LINK $@ | |||
625 | "$(core-y)" \ | 625 | "$(core-y)" \ |
626 | "$(libs-y)" \ | 626 | "$(libs-y)" \ |
627 | "$(LDLIBS)" \ | 627 | "$(LDLIBS)" \ |
628 | "$(CONFIG_EXTRA_LDLIBS)" \ | ||
628 | && $(srctree)/scripts/generate_BUFSIZ.sh --post include/common_bufsiz.h | 629 | && $(srctree)/scripts/generate_BUFSIZ.sh --post include/common_bufsiz.h |
629 | 630 | ||
630 | # Generate System.map | 631 | # Generate System.map |
diff --git a/Makefile.flags b/Makefile.flags index 94ed4e40e..8ea0687c7 100644 --- a/Makefile.flags +++ b/Makefile.flags | |||
@@ -190,7 +190,7 @@ LDLIBS += $(if $(SELINUX_LIBS),$(SELINUX_LIBS:-l%=%),$(SELINUX_PC_MODULES:lib%=% | |||
190 | endif | 190 | endif |
191 | 191 | ||
192 | ifeq ($(CONFIG_FEATURE_NSLOOKUP_BIG),y) | 192 | ifeq ($(CONFIG_FEATURE_NSLOOKUP_BIG),y) |
193 | ifeq ($(CONFIG_UNAME_OSNAME),Linux) | 193 | ifneq (,$(findstring linux,$(shell $(CC) $(CFLAGS) -dumpmachine))) |
194 | LDLIBS += resolv | 194 | LDLIBS += resolv |
195 | endif | 195 | endif |
196 | endif | 196 | endif |
@@ -218,11 +218,6 @@ LDFLAGS += $(strip $(subst ",,$(CONFIG_EXTRA_LDFLAGS))) | |||
218 | #")) | 218 | #")) |
219 | endif | 219 | endif |
220 | 220 | ||
221 | ifneq ($(CONFIG_EXTRA_LDLIBS),) | ||
222 | LDLIBS += $(strip $(subst ",,$(CONFIG_EXTRA_LDLIBS))) | ||
223 | #")) | ||
224 | endif | ||
225 | |||
226 | # Busybox is a stack-fatty so make sure we increase default size | 221 | # Busybox is a stack-fatty so make sure we increase default size |
227 | # TODO: use "make stksizes" to find & fix big stack users | 222 | # TODO: use "make stksizes" to find & fix big stack users |
228 | # (we stole scripts/checkstack.pl from the kernel... thanks guys!) | 223 | # (we stole scripts/checkstack.pl from the kernel... thanks guys!) |
diff --git a/applets/usage_pod.c b/applets/usage_pod.c index ccc166aed..9e6d3f0ee 100644 --- a/applets/usage_pod.c +++ b/applets/usage_pod.c | |||
@@ -71,7 +71,7 @@ int main(void) | |||
71 | } else { | 71 | } else { |
72 | printf(", "); | 72 | printf(", "); |
73 | } | 73 | } |
74 | printf(usage_array[i].aname); | 74 | printf("%s", usage_array[i].aname); |
75 | col += len2; | 75 | col += len2; |
76 | } | 76 | } |
77 | printf("\n\n"); | 77 | printf("\n\n"); |
diff --git a/coreutils/echo.c b/coreutils/echo.c index b3828894c..61ba060ec 100644 --- a/coreutils/echo.c +++ b/coreutils/echo.c | |||
@@ -97,6 +97,7 @@ int echo_main(int argc UNUSED_PARAM, char **argv) | |||
97 | #else | 97 | #else |
98 | char nflag = 1; | 98 | char nflag = 1; |
99 | char eflag = 0; | 99 | char eflag = 0; |
100 | int err; | ||
100 | 101 | ||
101 | while ((arg = *++argv) != NULL) { | 102 | while ((arg = *++argv) != NULL) { |
102 | char n, e; | 103 | char n, e; |
@@ -185,13 +186,12 @@ int echo_main(int argc UNUSED_PARAM, char **argv) | |||
185 | do_write: | 186 | do_write: |
186 | /* Careful to error out on partial writes too (think ENOSPC!) */ | 187 | /* Careful to error out on partial writes too (think ENOSPC!) */ |
187 | errno = 0; | 188 | errno = 0; |
188 | /*r =*/ full_write(STDOUT_FILENO, buffer, out - buffer); | 189 | err = full_write(STDOUT_FILENO, buffer, out - buffer) != out - buffer; |
189 | free(buffer); | 190 | if (err) { |
190 | if (/*WRONG:r < 0*/ errno) { | ||
191 | bb_simple_perror_msg(bb_msg_write_error); | 191 | bb_simple_perror_msg(bb_msg_write_error); |
192 | return 1; | ||
193 | } | 192 | } |
194 | return 0; | 193 | free(buffer); |
194 | return err; | ||
195 | } | 195 | } |
196 | 196 | ||
197 | /* | 197 | /* |
diff --git a/editors/diff.c b/editors/diff.c index a1c51ebb9..17d41af8d 100644 --- a/editors/diff.c +++ b/editors/diff.c | |||
@@ -1076,7 +1076,7 @@ int diff_main(int argc UNUSED_PARAM, char **argv) | |||
1076 | /* diffreg can get non-regular files here */ | 1076 | /* diffreg can get non-regular files here */ |
1077 | print_status(gotstdin > 1 ? STATUS_SAME : diffreg(file), file); | 1077 | print_status(gotstdin > 1 ? STATUS_SAME : diffreg(file), file); |
1078 | 1078 | ||
1079 | if (dirfile) | 1079 | if (ENABLE_FEATURE_CLEAN_UP && dirfile) |
1080 | free(file[dir]); | 1080 | free(file[dir]); |
1081 | } | 1081 | } |
1082 | 1082 | ||
diff --git a/include/libbb.h b/include/libbb.h index 5e1d1fc5b..63e99cfe2 100644 --- a/include/libbb.h +++ b/include/libbb.h | |||
@@ -1262,6 +1262,7 @@ void run_noexec_applet_and_exit(int a, const char *name, char **argv) NORETURN F | |||
1262 | int find_applet_by_name(const char *name) FAST_FUNC; | 1262 | int find_applet_by_name(const char *name) FAST_FUNC; |
1263 | void run_applet_no_and_exit(int a, const char *name, char **argv) NORETURN FAST_FUNC; | 1263 | void run_applet_no_and_exit(int a, const char *name, char **argv) NORETURN FAST_FUNC; |
1264 | #endif | 1264 | #endif |
1265 | void show_usage_if_dash_dash_help(int applet_no, char **argv) FAST_FUNC; | ||
1265 | #if defined(__linux__) | 1266 | #if defined(__linux__) |
1266 | void set_task_comm(const char *comm) FAST_FUNC; | 1267 | void set_task_comm(const char *comm) FAST_FUNC; |
1267 | #else | 1268 | #else |
diff --git a/include/platform.h b/include/platform.h index 0fc270fab..dc4a63ed4 100644 --- a/include/platform.h +++ b/include/platform.h | |||
@@ -428,6 +428,7 @@ typedef unsigned smalluint; | |||
428 | #define HAVE_SETBIT 1 | 428 | #define HAVE_SETBIT 1 |
429 | #define HAVE_SIGHANDLER_T 1 | 429 | #define HAVE_SIGHANDLER_T 1 |
430 | #define HAVE_STPCPY 1 | 430 | #define HAVE_STPCPY 1 |
431 | #define HAVE_STPNCPY 1 | ||
431 | #define HAVE_MEMPCPY 1 | 432 | #define HAVE_MEMPCPY 1 |
432 | #define HAVE_STRCASESTR 1 | 433 | #define HAVE_STRCASESTR 1 |
433 | #define HAVE_STRCHRNUL 1 | 434 | #define HAVE_STRCHRNUL 1 |
@@ -484,6 +485,7 @@ typedef unsigned smalluint; | |||
484 | # undef HAVE_MKDTEMP | 485 | # undef HAVE_MKDTEMP |
485 | # undef HAVE_SETBIT | 486 | # undef HAVE_SETBIT |
486 | # undef HAVE_STPCPY | 487 | # undef HAVE_STPCPY |
488 | # undef HAVE_STPNCPY | ||
487 | # undef HAVE_STRCASESTR | 489 | # undef HAVE_STRCASESTR |
488 | # undef HAVE_STRCHRNUL | 490 | # undef HAVE_STRCHRNUL |
489 | # undef HAVE_STRSEP | 491 | # undef HAVE_STRSEP |
@@ -556,6 +558,7 @@ typedef unsigned smalluint; | |||
556 | 558 | ||
557 | #if defined(__digital__) && defined(__unix__) | 559 | #if defined(__digital__) && defined(__unix__) |
558 | # undef HAVE_STPCPY | 560 | # undef HAVE_STPCPY |
561 | # undef HAVE_STPNCPY | ||
559 | #endif | 562 | #endif |
560 | 563 | ||
561 | #if defined(ANDROID) || defined(__ANDROID__) | 564 | #if defined(ANDROID) || defined(__ANDROID__) |
@@ -572,6 +575,7 @@ typedef unsigned smalluint; | |||
572 | # undef HAVE_TTYNAME_R | 575 | # undef HAVE_TTYNAME_R |
573 | # undef HAVE_GETLINE | 576 | # undef HAVE_GETLINE |
574 | # undef HAVE_STPCPY | 577 | # undef HAVE_STPCPY |
578 | # undef HAVE_STPNCPY | ||
575 | # endif | 579 | # endif |
576 | # undef HAVE_MEMPCPY | 580 | # undef HAVE_MEMPCPY |
577 | # undef HAVE_STRCHRNUL | 581 | # undef HAVE_STRCHRNUL |
@@ -617,6 +621,10 @@ typedef void (*sighandler_t)(int); | |||
617 | extern char *stpcpy(char *p, const char *to_add) FAST_FUNC; | 621 | extern char *stpcpy(char *p, const char *to_add) FAST_FUNC; |
618 | #endif | 622 | #endif |
619 | 623 | ||
624 | #ifndef HAVE_STPNCPY | ||
625 | extern char *stpncpy(char *p, const char *to_add, size_t n) FAST_FUNC; | ||
626 | #endif | ||
627 | |||
620 | #ifndef HAVE_MEMPCPY | 628 | #ifndef HAVE_MEMPCPY |
621 | #include <string.h> | 629 | #include <string.h> |
622 | /* In case we are wrong about !HAVE_MEMPCPY, and toolchain _does_ have | 630 | /* In case we are wrong about !HAVE_MEMPCPY, and toolchain _does_ have |
diff --git a/libbb/appletlib.c b/libbb/appletlib.c index 1587cf36f..846417d59 100644 --- a/libbb/appletlib.c +++ b/libbb/appletlib.c | |||
@@ -1034,6 +1034,34 @@ int busybox_main(int argc UNUSED_PARAM, char **argv) | |||
1034 | # endif | 1034 | # endif |
1035 | 1035 | ||
1036 | # if NUM_APPLETS > 0 | 1036 | # if NUM_APPLETS > 0 |
1037 | void FAST_FUNC show_usage_if_dash_dash_help(int applet_no, char **argv) | ||
1038 | { | ||
1039 | /* Special case. POSIX says "test --help" | ||
1040 | * should be no different from e.g. "test --foo". | ||
1041 | * Thus for "test", we skip --help check. | ||
1042 | * "true" and "false" are also special. | ||
1043 | */ | ||
1044 | if (1 | ||
1045 | # if defined APPLET_NO_test | ||
1046 | && applet_no != APPLET_NO_test | ||
1047 | # endif | ||
1048 | # if defined APPLET_NO_true | ||
1049 | && applet_no != APPLET_NO_true | ||
1050 | # endif | ||
1051 | # if defined APPLET_NO_false | ||
1052 | && applet_no != APPLET_NO_false | ||
1053 | # endif | ||
1054 | # if defined APPLET_NO_busybox | ||
1055 | && applet_no != APPLET_NO_busybox | ||
1056 | # endif | ||
1057 | ) { | ||
1058 | if (argv[1] && !argv[2] && strcmp(argv[1], "--help") == 0) { | ||
1059 | /* Make "foo --help" exit with 0: */ | ||
1060 | xfunc_error_retval = 0; | ||
1061 | bb_show_usage(); | ||
1062 | } | ||
1063 | } | ||
1064 | } | ||
1037 | 1065 | ||
1038 | # if ENABLE_PLATFORM_MINGW32 | 1066 | # if ENABLE_PLATFORM_MINGW32 |
1039 | static int interp = 0; | 1067 | static int interp = 0; |
@@ -1043,11 +1071,13 @@ char bb_command_line[128]; | |||
1043 | 1071 | ||
1044 | void FAST_FUNC run_applet_no_and_exit(int applet_no, const char *name, char **argv) | 1072 | void FAST_FUNC run_applet_no_and_exit(int applet_no, const char *name, char **argv) |
1045 | { | 1073 | { |
1046 | int argc = string_array_len(argv); | ||
1047 | # if ENABLE_PLATFORM_MINGW32 | 1074 | # if ENABLE_PLATFORM_MINGW32 |
1075 | int argc = string_array_len(argv); | ||
1048 | int i; | 1076 | int i; |
1049 | const char *vmask; | 1077 | const char *vmask; |
1050 | unsigned int mask; | 1078 | unsigned int mask; |
1079 | # else | ||
1080 | int argc; | ||
1051 | # endif | 1081 | # endif |
1052 | 1082 | ||
1053 | /* | 1083 | /* |
@@ -1055,6 +1085,12 @@ void FAST_FUNC run_applet_no_and_exit(int applet_no, const char *name, char **ar | |||
1055 | * "-/sbin/halt" -> "halt", for example. | 1085 | * "-/sbin/halt" -> "halt", for example. |
1056 | */ | 1086 | */ |
1057 | applet_name = name; | 1087 | applet_name = name; |
1088 | |||
1089 | show_usage_if_dash_dash_help(applet_no, argv); | ||
1090 | |||
1091 | if (ENABLE_FEATURE_SUID) | ||
1092 | check_suid(applet_no); | ||
1093 | |||
1058 | # if ENABLE_PLATFORM_MINGW32 | 1094 | # if ENABLE_PLATFORM_MINGW32 |
1059 | safe_strncpy(bb_comm, | 1095 | safe_strncpy(bb_comm, |
1060 | interp ? bb_basename(argv[interp]) : applet_name, | 1096 | interp ? bb_basename(argv[interp]) : applet_name, |
@@ -1069,37 +1105,11 @@ void FAST_FUNC run_applet_no_and_exit(int applet_no, const char *name, char **ar | |||
1069 | vmask = getenv("BB_UMASK"); | 1105 | vmask = getenv("BB_UMASK"); |
1070 | if (vmask && sscanf(vmask, "%o", &mask) == 1) | 1106 | if (vmask && sscanf(vmask, "%o", &mask) == 1) |
1071 | umask((mode_t)(mask&0777)); | 1107 | umask((mode_t)(mask&0777)); |
1108 | # else | ||
1109 | argc = string_array_len(argv); | ||
1072 | # endif | 1110 | # endif |
1073 | |||
1074 | /* Special case. POSIX says "test --help" | ||
1075 | * should be no different from e.g. "test --foo". | ||
1076 | * Thus for "test", we skip --help check. | ||
1077 | * "true" and "false" are also special. | ||
1078 | */ | ||
1079 | if (1 | ||
1080 | # if defined APPLET_NO_test | ||
1081 | && applet_no != APPLET_NO_test | ||
1082 | # endif | ||
1083 | # if defined APPLET_NO_true | ||
1084 | && applet_no != APPLET_NO_true | ||
1085 | # endif | ||
1086 | # if defined APPLET_NO_false | ||
1087 | && applet_no != APPLET_NO_false | ||
1088 | # endif | ||
1089 | # if defined APPLET_NO_busybox | ||
1090 | && applet_no != APPLET_NO_busybox | ||
1091 | # endif | ||
1092 | ) { | ||
1093 | if (argc == 2 && strcmp(argv[1], "--help") == 0) { | ||
1094 | /* Make "foo --help" exit with 0: */ | ||
1095 | xfunc_error_retval = 0; | ||
1096 | bb_show_usage(); | ||
1097 | } | ||
1098 | } | ||
1099 | if (ENABLE_FEATURE_SUID) | ||
1100 | check_suid(applet_no); | ||
1101 | |||
1102 | xfunc_error_retval = applet_main[applet_no](argc, argv); | 1111 | xfunc_error_retval = applet_main[applet_no](argc, argv); |
1112 | |||
1103 | /* Note: applet_main() may also not return (die on a xfunc or such) */ | 1113 | /* Note: applet_main() may also not return (die on a xfunc or such) */ |
1104 | xfunc_die(); | 1114 | xfunc_die(); |
1105 | } | 1115 | } |
diff --git a/libbb/lineedit.c b/libbb/lineedit.c index 55141e141..205044630 100644 --- a/libbb/lineedit.c +++ b/libbb/lineedit.c | |||
@@ -829,8 +829,6 @@ static unsigned path_parse(char ***p) | |||
829 | if (!tmp) | 829 | if (!tmp) |
830 | break; | 830 | break; |
831 | tmp++; | 831 | tmp++; |
832 | if (*tmp == '\0') | ||
833 | break; /* :<empty> */ | ||
834 | npth++; | 832 | npth++; |
835 | } | 833 | } |
836 | 834 | ||
@@ -842,8 +840,6 @@ static unsigned path_parse(char ***p) | |||
842 | if (!tmp) | 840 | if (!tmp) |
843 | break; | 841 | break; |
844 | *tmp++ = '\0'; /* ':' -> '\0' */ | 842 | *tmp++ = '\0'; /* ':' -> '\0' */ |
845 | if (*tmp == '\0') | ||
846 | break; /* :<empty> */ | ||
847 | res[npth++] = tmp; | 843 | res[npth++] = tmp; |
848 | } | 844 | } |
849 | /* special case: "match subdirectories of the current directory" */ | 845 | /* special case: "match subdirectories of the current directory" */ |
@@ -925,9 +921,7 @@ static NOINLINE unsigned complete_cmd_dir_file(const char *command, int type) | |||
925 | struct dirent *next; | 921 | struct dirent *next; |
926 | struct stat st; | 922 | struct stat st; |
927 | char *found; | 923 | char *found; |
928 | #if ENABLE_PLATFORM_MINGW32 | 924 | const char *lpath; |
929 | char *lpath; | ||
930 | #endif | ||
931 | 925 | ||
932 | if (paths[i] == NULL) { /* path_parse()'s last component? */ | 926 | if (paths[i] == NULL) { /* path_parse()'s last component? */ |
933 | /* in PATH completion, current dir's subdir names | 927 | /* in PATH completion, current dir's subdir names |
@@ -937,12 +931,11 @@ static NOINLINE unsigned complete_cmd_dir_file(const char *command, int type) | |||
937 | paths[i] = (char *)"."; | 931 | paths[i] = (char *)"."; |
938 | } | 932 | } |
939 | 933 | ||
934 | lpath = *paths[i] ? paths[i] : "."; | ||
940 | #if ENABLE_PLATFORM_MINGW32 | 935 | #if ENABLE_PLATFORM_MINGW32 |
941 | lpath = auto_string(alloc_system_drive(paths[i])); | 936 | lpath = auto_string(alloc_system_drive(lpath)); |
942 | dir = opendir(lpath); | ||
943 | #else | ||
944 | dir = opendir(paths[i]); | ||
945 | #endif | 937 | #endif |
938 | dir = opendir(lpath); | ||
946 | if (!dir) | 939 | if (!dir) |
947 | continue; /* don't print an error */ | 940 | continue; /* don't print an error */ |
948 | 941 | ||
@@ -957,11 +950,7 @@ static NOINLINE unsigned complete_cmd_dir_file(const char *command, int type) | |||
957 | if (strncmp(basecmd, name_found, baselen) != 0) | 950 | if (strncmp(basecmd, name_found, baselen) != 0) |
958 | continue; /* no */ | 951 | continue; /* no */ |
959 | 952 | ||
960 | #if ENABLE_PLATFORM_MINGW32 | ||
961 | found = concat_path_file(lpath, name_found); | 953 | found = concat_path_file(lpath, name_found); |
962 | #else | ||
963 | found = concat_path_file(paths[i], name_found); | ||
964 | #endif | ||
965 | /* NB: stat() first so that we see is it a directory; | 954 | /* NB: stat() first so that we see is it a directory; |
966 | * but if that fails, use lstat() so that | 955 | * but if that fails, use lstat() so that |
967 | * we still match dangling links */ | 956 | * we still match dangling links */ |
diff --git a/libbb/platform.c b/libbb/platform.c index 329b0237e..7913353e2 100644 --- a/libbb/platform.c +++ b/libbb/platform.c | |||
@@ -166,6 +166,18 @@ char* FAST_FUNC stpcpy(char *p, const char *to_add) | |||
166 | } | 166 | } |
167 | #endif | 167 | #endif |
168 | 168 | ||
169 | #ifndef HAVE_STPNCPY | ||
170 | char* FAST_FUNC stpncpy(char *p, const char *to_add, size_t n) | ||
171 | { | ||
172 | while (n != 0 && (*p = *to_add) != '\0') { | ||
173 | p++; | ||
174 | to_add++; | ||
175 | n--; | ||
176 | } | ||
177 | return p; | ||
178 | } | ||
179 | #endif | ||
180 | |||
169 | #ifndef HAVE_GETLINE | 181 | #ifndef HAVE_GETLINE |
170 | ssize_t FAST_FUNC getline(char **lineptr, size_t *n, FILE *stream) | 182 | ssize_t FAST_FUNC getline(char **lineptr, size_t *n, FILE *stream) |
171 | { | 183 | { |
diff --git a/libbb/vfork_daemon_rexec.c b/libbb/vfork_daemon_rexec.c index 26e1776a4..885c19f1a 100644 --- a/libbb/vfork_daemon_rexec.c +++ b/libbb/vfork_daemon_rexec.c | |||
@@ -109,8 +109,13 @@ int FAST_FUNC run_nofork_applet(int applet_no, char **argv) | |||
109 | char *tmp_argv[argc+1]; | 109 | char *tmp_argv[argc+1]; |
110 | memcpy(tmp_argv, argv, (argc+1) * sizeof(tmp_argv[0])); | 110 | memcpy(tmp_argv, argv, (argc+1) * sizeof(tmp_argv[0])); |
111 | applet_name = tmp_argv[0]; | 111 | applet_name = tmp_argv[0]; |
112 | |||
113 | /* longjmp's (instead of returning) if --help is seen */ | ||
114 | show_usage_if_dash_dash_help(applet_no, argv); | ||
115 | |||
112 | /* Finally we can call NOFORK applet's main() */ | 116 | /* Finally we can call NOFORK applet's main() */ |
113 | rc = applet_main[applet_no](argc, tmp_argv); | 117 | rc = applet_main[applet_no](argc, tmp_argv); |
118 | |||
114 | /* Important for shells: `which CMD` was failing */ | 119 | /* Important for shells: `which CMD` was failing */ |
115 | fflush_all(); | 120 | fflush_all(); |
116 | } else { | 121 | } else { |
diff --git a/miscutils/bc.c b/miscutils/bc.c index 38ae7f7d1..4eb0f2d30 100644 --- a/miscutils/bc.c +++ b/miscutils/bc.c | |||
@@ -138,11 +138,54 @@ | |||
138 | //usage: | 138 | //usage: |
139 | //usage:#define dc_full_usage "\n" | 139 | //usage:#define dc_full_usage "\n" |
140 | //usage: "\nTiny RPN calculator. Operations:" | 140 | //usage: "\nTiny RPN calculator. Operations:" |
141 | //usage: "\n+, -, *, /, %, ~, ^," IF_FEATURE_DC_BIG(" |,") | 141 | //usage: "\nArithmetic: + - * / % ^" |
142 | //usage: IF_FEATURE_DC_BIG( | ||
143 | //usage: "\n~ - divide with remainder" | ||
144 | //usage: "\n| - modular exponentiation" | ||
145 | //usage: "\nv - square root" | ||
146 | //////// "\nA-F - digits 10..15 | ||
147 | //////// "\n_NNN - push negative number -NNN | ||
148 | //////// "\n[string] - push string (in FreeBSD, \[, \] and \\ are escapes, not implemented here and in GNU) | ||
149 | //////// "\nR - DC_LEX_POP pop and discard | ||
150 | //////// "\nc - DC_LEX_CLEAR_STACK clear stack | ||
151 | //////// "\nd - DC_LEX_DUPLICATE duplicate top-of-stack | ||
152 | //////// "\nr - DC_LEX_SWAP swap top-of-stack | ||
153 | //////// "\n:r - DC_LEX_COLON pop index, pop value, store to array 'r' | ||
154 | //////// "\n;r - DC_LEX_SCOLON pop index, fetch from array 'r', push | ||
155 | //////// "\nLr - DC_LEX_LOAD_POP pop register 'r', push | ||
156 | //////// "\nSr - DC_LEX_STORE_PUSH pop, push to register 'r' | ||
157 | //////// "\nlr - DC_LEX_LOAD read register 'r', push | ||
158 | //////// "\nsr - DC_LEX_OP_ASSIGN pop, assign to register 'r' | ||
159 | //////// "\n? - DC_LEX_READ read line and execute | ||
160 | //////// "\nx - DC_LEX_EXECUTE pop string and execute | ||
161 | //////// "\n<r - XC_LEX_OP_REL_GT pop, pop, execute register 'r' if top-of-stack was less | ||
162 | //////// "\n>r - XC_LEX_OP_REL_LT pop, pop, execute register 'r' if top-of-stack was greater | ||
163 | //////// "\n=r - XC_LEX_OP_REL_EQ pop, pop, execute register 'r' if equal | ||
164 | //////// "\n !<r !>r !=r - negated forms | ||
165 | //////// "\n >tef - "if greater execute register 't' else execute 'f'" | ||
166 | //////// "\nQ - DC_LEX_NQUIT pop, "break N" from macro invocations | ||
167 | //////// "\nq - DC_LEX_QUIT "break 2" (if less than 2 levels of macros, exit dc) | ||
168 | //////// "\nX - DC_LEX_SCALE_FACTOR pop, push number of fractional digits | ||
169 | //////// "\nZ - DC_LEX_LENGTH pop, push number of digits it has (or number of characters in string) | ||
170 | //////// "\na - DC_LEX_ASCIIFY pop, push low-order byte as char or 1st char of string | ||
171 | //////// "\n( - DC_LEX_LPAREN (FreeBSD, not in GNU) pop, pop, if top-of-stack was less push 1 else push 0 | ||
172 | //////// "\n{ - DC_LEX_LBRACE (FreeBSD, not in GNU) pop, pop, if top-of-stack was less-or-equal push 1 else push 0 | ||
173 | //////// "\nG - DC_LEX_EQ_NO_REG (FreeBSD, not in GNU) pop, pop, if equal push 1 else push 0 | ||
174 | //////// "\nN - DC_LEX_OP_BOOL_NOT (FreeBSD, not in GNU) pop, if 0 push 1 else push 0 | ||
175 | //////// FreeBSD also has J and M commands, used internally by bc | ||
176 | //////// "\nn - DC_LEX_PRINT_POP pop, print without newline | ||
177 | //////// "\nP - DC_LEX_PRINT_STREAM pop, print string or hex bytes | ||
178 | //usage: ) | ||
142 | //usage: "\np - print top of the stack without popping" | 179 | //usage: "\np - print top of the stack without popping" |
143 | //usage: "\nf - print entire stack" | 180 | //usage: "\nf - print entire stack" |
144 | //usage: "\nk - pop the value and set the precision" | 181 | //////// "\nz - DC_LEX_STACK_LEVEL push stack depth |
182 | //////// "\nK - DC_LEX_SCALE push precision | ||
183 | //////// "\nI - DC_LEX_IBASE push input radix | ||
184 | //////// "\nO - DC_LEX_OBASE push output radix | ||
185 | //usage: IF_FEATURE_DC_BIG( | ||
186 | //usage: "\nk - pop the value and set precision" | ||
145 | //usage: "\ni - pop the value and set input radix" | 187 | //usage: "\ni - pop the value and set input radix" |
188 | //usage: ) | ||
146 | //usage: "\no - pop the value and set output radix" | 189 | //usage: "\no - pop the value and set output radix" |
147 | //usage: "\nExamples: dc -e'2 2 + p' -> 4, dc -e'8 8 * 2 2 + / p' -> 16" | 190 | //usage: "\nExamples: dc -e'2 2 + p' -> 4, dc -e'8 8 * 2 2 + / p' -> 16" |
148 | //usage: | 191 | //usage: |
@@ -6217,13 +6260,20 @@ static unsigned long xc_program_len(BcNum *n) | |||
6217 | { | 6260 | { |
6218 | size_t len = n->len; | 6261 | size_t len = n->len; |
6219 | 6262 | ||
6220 | if (n->rdx != len) return len; | 6263 | if (n->rdx != len) |
6264 | // length(100): rdx 0 len 3, return 3 | ||
6265 | // length(0.01-0.01): rdx 2 len 0, return 2 | ||
6266 | // dc: 0.01 0.01 - Zp: rdx 2 len 0, return 1 | ||
6267 | return len != 0 ? len : (IS_BC ? n->rdx : 1); | ||
6268 | |||
6269 | // length(0): return 1 | ||
6270 | // length(0.000nnn): count nnn | ||
6221 | for (;;) { | 6271 | for (;;) { |
6222 | if (len == 0) break; | 6272 | if (len == 0) break; |
6223 | len--; | 6273 | len--; |
6224 | if (n->num[len] != 0) break; | 6274 | if (n->num[len] != 0) break; |
6225 | } | 6275 | } |
6226 | return len; | 6276 | return len + 1; |
6227 | } | 6277 | } |
6228 | 6278 | ||
6229 | static BC_STATUS zxc_program_builtin(char inst) | 6279 | static BC_STATUS zxc_program_builtin(char inst) |
@@ -6251,12 +6301,12 @@ static BC_STATUS zxc_program_builtin(char inst) | |||
6251 | if (inst == XC_INST_SQRT) | 6301 | if (inst == XC_INST_SQRT) |
6252 | s = zbc_num_sqrt(num, &res.d.n, G.prog.scale); | 6302 | s = zbc_num_sqrt(num, &res.d.n, G.prog.scale); |
6253 | #if ENABLE_BC | 6303 | #if ENABLE_BC |
6254 | else if (len != 0 && opnd->t == XC_RESULT_ARRAY) { | 6304 | else if (len && opnd->t == XC_RESULT_ARRAY) { |
6255 | bc_num_ulong2num(&res.d.n, (unsigned long) ((BcVec *) num)->len); | 6305 | bc_num_ulong2num(&res.d.n, (unsigned long) ((BcVec *) num)->len); |
6256 | } | 6306 | } |
6257 | #endif | 6307 | #endif |
6258 | #if ENABLE_DC | 6308 | #if ENABLE_DC |
6259 | else if (len != 0 && !BC_PROG_NUM(opnd, num)) { | 6309 | else if (len && !BC_PROG_NUM(opnd, num)) { |
6260 | char **str; | 6310 | char **str; |
6261 | size_t idx = opnd->t == XC_RESULT_STR ? opnd->d.id.idx : num->rdx; | 6311 | size_t idx = opnd->t == XC_RESULT_STR ? opnd->d.id.idx : num->rdx; |
6262 | 6312 | ||
@@ -6265,6 +6315,8 @@ static BC_STATUS zxc_program_builtin(char inst) | |||
6265 | } | 6315 | } |
6266 | #endif | 6316 | #endif |
6267 | else { | 6317 | else { |
6318 | //TODO: length(.00) and scale(.00) should return 2, they return 1 and 0 now | ||
6319 | //(don't forget to check that dc Z and X commands do not break) | ||
6268 | bc_num_ulong2num(&res.d.n, len ? xc_program_len(num) : xc_program_scale(num)); | 6320 | bc_num_ulong2num(&res.d.n, len ? xc_program_len(num) : xc_program_scale(num)); |
6269 | } | 6321 | } |
6270 | 6322 | ||
diff --git a/networking/dnsd.c b/networking/dnsd.c index 0ff0290fb..a0f320c6c 100644 --- a/networking/dnsd.c +++ b/networking/dnsd.c | |||
@@ -379,7 +379,8 @@ Domain name in a message can be represented as either: | |||
379 | */ | 379 | */ |
380 | static int process_packet(struct dns_entry *conf_data, | 380 | static int process_packet(struct dns_entry *conf_data, |
381 | uint32_t conf_ttl, | 381 | uint32_t conf_ttl, |
382 | uint8_t *buf) | 382 | uint8_t *buf, |
383 | unsigned buflen) | ||
383 | { | 384 | { |
384 | struct dns_head *head; | 385 | struct dns_head *head; |
385 | struct type_and_class *unaligned_type_class; | 386 | struct type_and_class *unaligned_type_class; |
@@ -402,9 +403,6 @@ static int process_packet(struct dns_entry *conf_data, | |||
402 | bb_simple_error_msg("response packet, ignored"); | 403 | bb_simple_error_msg("response packet, ignored"); |
403 | return 0; /* don't reply */ | 404 | return 0; /* don't reply */ |
404 | } | 405 | } |
405 | /* QR = 1 "response", RCODE = 4 "Not Implemented" */ | ||
406 | outr_flags = htons(0x8000 | 4); | ||
407 | err_msg = NULL; | ||
408 | 406 | ||
409 | /* start of query string */ | 407 | /* start of query string */ |
410 | query_string = (void *)(head + 1); | 408 | query_string = (void *)(head + 1); |
@@ -416,6 +414,15 @@ static int process_packet(struct dns_entry *conf_data, | |||
416 | /* where to append answer block */ | 414 | /* where to append answer block */ |
417 | answb = (void *)(unaligned_type_class + 1); | 415 | answb = (void *)(unaligned_type_class + 1); |
418 | 416 | ||
417 | if (buflen < answb - buf) { | ||
418 | bb_simple_error_msg("packet too short"); | ||
419 | return 0; /* don't reply */ | ||
420 | } | ||
421 | |||
422 | /* QR = 1 "response", RCODE = 4 "Not Implemented" */ | ||
423 | outr_flags = htons(0x8000 | 4); | ||
424 | err_msg = NULL; | ||
425 | |||
419 | /* OPCODE != 0 "standard query"? */ | 426 | /* OPCODE != 0 "standard query"? */ |
420 | if ((head->flags & htons(0x7800)) != 0) { | 427 | if ((head->flags & htons(0x7800)) != 0) { |
421 | err_msg = "opcode != 0"; | 428 | err_msg = "opcode != 0"; |
@@ -559,7 +566,7 @@ int dnsd_main(int argc UNUSED_PARAM, char **argv) | |||
559 | if (OPT_verbose) | 566 | if (OPT_verbose) |
560 | bb_simple_info_msg("got UDP packet"); | 567 | bb_simple_info_msg("got UDP packet"); |
561 | buf[r] = '\0'; /* paranoia */ | 568 | buf[r] = '\0'; /* paranoia */ |
562 | r = process_packet(conf_data, conf_ttl, buf); | 569 | r = process_packet(conf_data, conf_ttl, buf, r); |
563 | if (r <= 0) | 570 | if (r <= 0) |
564 | continue; | 571 | continue; |
565 | send_to_from(udps, buf, r, 0, &from->u.sa, &to->u.sa, lsa->len); | 572 | send_to_from(udps, buf, r, 0, &from->u.sa, &to->u.sa, lsa->len); |
diff --git a/networking/ntpd.c b/networking/ntpd.c index 1f17b08ef..9c15999f3 100644 --- a/networking/ntpd.c +++ b/networking/ntpd.c | |||
@@ -373,8 +373,7 @@ typedef struct { | |||
373 | } peer_t; | 373 | } peer_t; |
374 | 374 | ||
375 | 375 | ||
376 | #define USING_KERNEL_PLL_LOOP 1 | 376 | #define USING_KERNEL_PLL_LOOP 1 |
377 | #define USING_INITIAL_FREQ_ESTIMATION 0 | ||
378 | 377 | ||
379 | enum { | 378 | enum { |
380 | OPT_n = (1 << 0), | 379 | OPT_n = (1 << 0), |
@@ -462,12 +461,7 @@ struct globals { | |||
462 | #define G_precision_sec 0.002 | 461 | #define G_precision_sec 0.002 |
463 | uint8_t stratum; | 462 | uint8_t stratum; |
464 | 463 | ||
465 | #define STATE_NSET 0 /* initial state, "nothing is set" */ | 464 | //uint8_t discipline_state; // doc calls it c.state |
466 | //#define STATE_FSET 1 /* frequency set from file */ | ||
467 | //#define STATE_SPIK 2 /* spike detected */ | ||
468 | //#define STATE_FREQ 3 /* initial frequency */ | ||
469 | #define STATE_SYNC 4 /* clock synchronized (normal operation) */ | ||
470 | uint8_t discipline_state; // doc calls it c.state | ||
471 | uint8_t poll_exp; // s.poll | 465 | uint8_t poll_exp; // s.poll |
472 | int polladj_count; // c.count | 466 | int polladj_count; // c.count |
473 | int FREQHOLD_cnt; | 467 | int FREQHOLD_cnt; |
@@ -657,104 +651,11 @@ filter_datapoints(peer_t *p) | |||
657 | double sum, wavg; | 651 | double sum, wavg; |
658 | datapoint_t *fdp; | 652 | datapoint_t *fdp; |
659 | 653 | ||
660 | #if 0 | ||
661 | /* Simulations have shown that use of *averaged* offset for p->filter_offset | 654 | /* Simulations have shown that use of *averaged* offset for p->filter_offset |
662 | * is in fact worse than simply using last received one: with large poll intervals | 655 | * is in fact worse than simply using last received one: with large poll intervals |
663 | * (>= 2048) averaging code uses offset values which are outdated by hours, | 656 | * (>= 2048) averaging code uses offset values which are outdated by hours, |
664 | * and time/frequency correction goes totally wrong when fed essentially bogus offsets. | 657 | * and time/frequency correction goes totally wrong when fed essentially bogus offsets. |
665 | */ | 658 | */ |
666 | int got_newest; | ||
667 | double minoff, maxoff, w; | ||
668 | double x = x; /* for compiler */ | ||
669 | double oldest_off = oldest_off; | ||
670 | double oldest_age = oldest_age; | ||
671 | double newest_off = newest_off; | ||
672 | double newest_age = newest_age; | ||
673 | |||
674 | fdp = p->filter_datapoint; | ||
675 | |||
676 | minoff = maxoff = fdp[0].d_offset; | ||
677 | for (i = 1; i < NUM_DATAPOINTS; i++) { | ||
678 | if (minoff > fdp[i].d_offset) | ||
679 | minoff = fdp[i].d_offset; | ||
680 | if (maxoff < fdp[i].d_offset) | ||
681 | maxoff = fdp[i].d_offset; | ||
682 | } | ||
683 | |||
684 | idx = p->datapoint_idx; /* most recent datapoint's index */ | ||
685 | /* Average offset: | ||
686 | * Drop two outliers and take weighted average of the rest: | ||
687 | * most_recent/2 + older1/4 + older2/8 ... + older5/32 + older6/32 | ||
688 | * we use older6/32, not older6/64 since sum of weights should be 1: | ||
689 | * 1/2 + 1/4 + 1/8 + 1/16 + 1/32 + 1/32 = 1 | ||
690 | */ | ||
691 | wavg = 0; | ||
692 | w = 0.5; | ||
693 | /* n-1 | ||
694 | * --- dispersion(i) | ||
695 | * filter_dispersion = \ ------------- | ||
696 | * / (i+1) | ||
697 | * --- 2 | ||
698 | * i=0 | ||
699 | */ | ||
700 | got_newest = 0; | ||
701 | sum = 0; | ||
702 | for (i = 0; i < NUM_DATAPOINTS; i++) { | ||
703 | VERB5 { | ||
704 | bb_error_msg("datapoint[%d]: off:%f disp:%f(%f) age:%f%s", | ||
705 | i, | ||
706 | fdp[idx].d_offset, | ||
707 | fdp[idx].d_dispersion, dispersion(&fdp[idx]), | ||
708 | G.cur_time - fdp[idx].d_recv_time, | ||
709 | (minoff == fdp[idx].d_offset || maxoff == fdp[idx].d_offset) | ||
710 | ? " (outlier by offset)" : "" | ||
711 | ); | ||
712 | } | ||
713 | |||
714 | sum += dispersion(&fdp[idx]) / (2 << i); | ||
715 | |||
716 | if (minoff == fdp[idx].d_offset) { | ||
717 | minoff -= 1; /* so that we don't match it ever again */ | ||
718 | } else | ||
719 | if (maxoff == fdp[idx].d_offset) { | ||
720 | maxoff += 1; | ||
721 | } else { | ||
722 | oldest_off = fdp[idx].d_offset; | ||
723 | oldest_age = G.cur_time - fdp[idx].d_recv_time; | ||
724 | if (!got_newest) { | ||
725 | got_newest = 1; | ||
726 | newest_off = oldest_off; | ||
727 | newest_age = oldest_age; | ||
728 | } | ||
729 | x = oldest_off * w; | ||
730 | wavg += x; | ||
731 | w /= 2; | ||
732 | } | ||
733 | |||
734 | idx = (idx - 1) & (NUM_DATAPOINTS - 1); | ||
735 | } | ||
736 | p->filter_dispersion = sum; | ||
737 | wavg += x; /* add another older6/64 to form older6/32 */ | ||
738 | /* Fix systematic underestimation with large poll intervals. | ||
739 | * Imagine that we still have a bit of uncorrected drift, | ||
740 | * and poll interval is big (say, 100 sec). Offsets form a progression: | ||
741 | * 0.0 0.1 0.2 0.3 0.4 0.5 0.6 0.7 - 0.7 is most recent. | ||
742 | * The algorithm above drops 0.0 and 0.7 as outliers, | ||
743 | * and then we have this estimation, ~25% off from 0.7: | ||
744 | * 0.1/32 + 0.2/32 + 0.3/16 + 0.4/8 + 0.5/4 + 0.6/2 = 0.503125 | ||
745 | */ | ||
746 | x = oldest_age - newest_age; | ||
747 | if (x != 0) { | ||
748 | x = newest_age / x; /* in above example, 100 / (600 - 100) */ | ||
749 | if (x < 1) { /* paranoia check */ | ||
750 | x = (newest_off - oldest_off) * x; /* 0.5 * 100/500 = 0.1 */ | ||
751 | wavg += x; | ||
752 | } | ||
753 | } | ||
754 | p->filter_offset = wavg; | ||
755 | |||
756 | #else | ||
757 | |||
758 | fdp = p->filter_datapoint; | 659 | fdp = p->filter_datapoint; |
759 | idx = p->datapoint_idx; /* most recent datapoint's index */ | 660 | idx = p->datapoint_idx; /* most recent datapoint's index */ |
760 | 661 | ||
@@ -777,7 +678,6 @@ filter_datapoints(peer_t *p) | |||
777 | } | 678 | } |
778 | wavg /= NUM_DATAPOINTS; | 679 | wavg /= NUM_DATAPOINTS; |
779 | p->filter_dispersion = sum; | 680 | p->filter_dispersion = sum; |
780 | #endif | ||
781 | 681 | ||
782 | /* +----- -----+ ^ 1/2 | 682 | /* +----- -----+ ^ 1/2 |
783 | * | n-1 | | 683 | * | n-1 | |
@@ -1548,15 +1448,14 @@ select_and_cluster(void) | |||
1548 | * Local clock discipline and its helpers | 1448 | * Local clock discipline and its helpers |
1549 | */ | 1449 | */ |
1550 | static void | 1450 | static void |
1551 | set_new_values(int disc_state, double offset, double recv_time) | 1451 | set_new_values(double offset, double recv_time) |
1552 | { | 1452 | { |
1553 | /* Enter new state and set state variables. Note we use the time | 1453 | /* Enter new state and set state variables. Note we use the time |
1554 | * of the last clock filter sample, which must be earlier than | 1454 | * of the last clock filter sample, which must be earlier than |
1555 | * the current time. | 1455 | * the current time. |
1556 | */ | 1456 | */ |
1557 | VERB4 bb_error_msg("disc_state=%d last update offset=%f recv_time=%f", | 1457 | VERB4 bb_error_msg("last update offset=%f recv_time=%f", |
1558 | disc_state, offset, recv_time); | 1458 | offset, recv_time); |
1559 | G.discipline_state = disc_state; | ||
1560 | G.last_update_offset = offset; | 1459 | G.last_update_offset = offset; |
1561 | G.last_update_recv_time = recv_time; | 1460 | G.last_update_recv_time = recv_time; |
1562 | } | 1461 | } |
@@ -1572,8 +1471,6 @@ update_local_clock(peer_t *p) | |||
1572 | double abs_offset; | 1471 | double abs_offset; |
1573 | #if !USING_KERNEL_PLL_LOOP | 1472 | #if !USING_KERNEL_PLL_LOOP |
1574 | double freq_drift; | 1473 | double freq_drift; |
1575 | #endif | ||
1576 | #if !USING_KERNEL_PLL_LOOP || USING_INITIAL_FREQ_ESTIMATION | ||
1577 | double since_last_update; | 1474 | double since_last_update; |
1578 | #endif | 1475 | #endif |
1579 | double etemp, dtemp; | 1476 | double etemp, dtemp; |
@@ -1603,63 +1500,15 @@ update_local_clock(peer_t *p) | |||
1603 | * action is and defines how the system reacts to large time | 1500 | * action is and defines how the system reacts to large time |
1604 | * and frequency errors. | 1501 | * and frequency errors. |
1605 | */ | 1502 | */ |
1606 | #if !USING_KERNEL_PLL_LOOP || USING_INITIAL_FREQ_ESTIMATION | ||
1607 | since_last_update = recv_time - G.reftime; | ||
1608 | #endif | ||
1609 | #if !USING_KERNEL_PLL_LOOP | 1503 | #if !USING_KERNEL_PLL_LOOP |
1504 | since_last_update = recv_time - G.reftime; | ||
1610 | freq_drift = 0; | 1505 | freq_drift = 0; |
1611 | #endif | 1506 | #endif |
1612 | #if USING_INITIAL_FREQ_ESTIMATION | ||
1613 | if (G.discipline_state == STATE_FREQ) { | ||
1614 | /* Ignore updates until the stepout threshold */ | ||
1615 | if (since_last_update < WATCH_THRESHOLD) { | ||
1616 | VERB4 bb_error_msg("measuring drift, datapoint ignored, %f sec remains", | ||
1617 | WATCH_THRESHOLD - since_last_update); | ||
1618 | return 0; /* "leave poll interval as is" */ | ||
1619 | } | ||
1620 | # if !USING_KERNEL_PLL_LOOP | ||
1621 | freq_drift = (offset - G.last_update_offset) / since_last_update; | ||
1622 | # endif | ||
1623 | } | ||
1624 | #endif | ||
1625 | 1507 | ||
1626 | /* There are two main regimes: when the | 1508 | /* There are two main regimes: when the |
1627 | * offset exceeds the step threshold and when it does not. | 1509 | * offset exceeds the step threshold and when it does not. |
1628 | */ | 1510 | */ |
1629 | if (abs_offset > STEP_THRESHOLD) { | 1511 | if (abs_offset > STEP_THRESHOLD) { |
1630 | #if 0 | ||
1631 | double remains; | ||
1632 | |||
1633 | // This "spike state" seems to be useless, peer selection already drops | ||
1634 | // occassional "bad" datapoints. If we are here, there were _many_ | ||
1635 | // large offsets. When a few first large offsets are seen, | ||
1636 | // we end up in "no valid datapoints, no peer selected" state. | ||
1637 | // Only when enough of them are seen (which means it's not a fluke), | ||
1638 | // we end up here. Looks like _our_ clock is off. | ||
1639 | switch (G.discipline_state) { | ||
1640 | case STATE_SYNC: | ||
1641 | /* The first outlyer: ignore it, switch to SPIK state */ | ||
1642 | VERB3 bb_error_msg("update from %s: offset:%+f, spike%s", | ||
1643 | p->p_dotted, offset, | ||
1644 | ""); | ||
1645 | G.discipline_state = STATE_SPIK; | ||
1646 | return -1; /* "decrease poll interval" */ | ||
1647 | |||
1648 | case STATE_SPIK: | ||
1649 | /* Ignore succeeding outlyers until either an inlyer | ||
1650 | * is found or the stepout threshold is exceeded. | ||
1651 | */ | ||
1652 | remains = WATCH_THRESHOLD - since_last_update; | ||
1653 | if (remains > 0) { | ||
1654 | VERB3 bb_error_msg("update from %s: offset:%+f, spike%s", | ||
1655 | p->p_dotted, offset, | ||
1656 | ", datapoint ignored"); | ||
1657 | return -1; /* "decrease poll interval" */ | ||
1658 | } | ||
1659 | /* fall through: we need to step */ | ||
1660 | } /* switch */ | ||
1661 | #endif | ||
1662 | |||
1663 | /* Step the time and clamp down the poll interval. | 1512 | /* Step the time and clamp down the poll interval. |
1664 | * | 1513 | * |
1665 | * In NSET state an initial frequency correction is | 1514 | * In NSET state an initial frequency correction is |
@@ -1694,16 +1543,17 @@ update_local_clock(peer_t *p) | |||
1694 | 1543 | ||
1695 | recv_time += offset; | 1544 | recv_time += offset; |
1696 | 1545 | ||
1697 | #if USING_INITIAL_FREQ_ESTIMATION | ||
1698 | if (G.discipline_state == STATE_NSET) { | ||
1699 | set_new_values(STATE_FREQ, /*offset:*/ 0, recv_time); | ||
1700 | return 1; /* "ok to increase poll interval" */ | ||
1701 | } | ||
1702 | #endif | ||
1703 | abs_offset = offset = 0; | 1546 | abs_offset = offset = 0; |
1704 | set_new_values(STATE_SYNC, offset, recv_time); | 1547 | set_new_values(offset, recv_time); |
1705 | } else { /* abs_offset <= STEP_THRESHOLD */ | 1548 | } else { /* abs_offset <= STEP_THRESHOLD */ |
1706 | 1549 | ||
1550 | if (option_mask32 & OPT_q) { | ||
1551 | /* We were only asked to set time once. | ||
1552 | * The clock is precise enough, no need to step. | ||
1553 | */ | ||
1554 | exit(0); | ||
1555 | } | ||
1556 | |||
1707 | /* The ratio is calculated before jitter is updated to make | 1557 | /* The ratio is calculated before jitter is updated to make |
1708 | * poll adjust code more sensitive to large offsets. | 1558 | * poll adjust code more sensitive to large offsets. |
1709 | */ | 1559 | */ |
@@ -1718,75 +1568,31 @@ update_local_clock(peer_t *p) | |||
1718 | if (G.discipline_jitter < G_precision_sec) | 1568 | if (G.discipline_jitter < G_precision_sec) |
1719 | G.discipline_jitter = G_precision_sec; | 1569 | G.discipline_jitter = G_precision_sec; |
1720 | 1570 | ||
1721 | switch (G.discipline_state) { | ||
1722 | case STATE_NSET: | ||
1723 | if (option_mask32 & OPT_q) { | ||
1724 | /* We were only asked to set time once. | ||
1725 | * The clock is precise enough, no need to step. | ||
1726 | */ | ||
1727 | exit(0); | ||
1728 | } | ||
1729 | #if USING_INITIAL_FREQ_ESTIMATION | ||
1730 | /* This is the first update received and the frequency | ||
1731 | * has not been initialized. The first thing to do | ||
1732 | * is directly measure the oscillator frequency. | ||
1733 | */ | ||
1734 | set_new_values(STATE_FREQ, offset, recv_time); | ||
1735 | #else | ||
1736 | set_new_values(STATE_SYNC, offset, recv_time); | ||
1737 | #endif | ||
1738 | VERB4 bb_simple_error_msg("transitioning to FREQ, datapoint ignored"); | ||
1739 | return 0; /* "leave poll interval as is" */ | ||
1740 | |||
1741 | #if 0 /* this is dead code for now */ | ||
1742 | case STATE_FSET: | ||
1743 | /* This is the first update and the frequency | ||
1744 | * has been initialized. Adjust the phase, but | ||
1745 | * don't adjust the frequency until the next update. | ||
1746 | */ | ||
1747 | set_new_values(STATE_SYNC, offset, recv_time); | ||
1748 | /* freq_drift remains 0 */ | ||
1749 | break; | ||
1750 | #endif | ||
1751 | |||
1752 | #if USING_INITIAL_FREQ_ESTIMATION | ||
1753 | case STATE_FREQ: | ||
1754 | /* since_last_update >= WATCH_THRESHOLD, we waited enough. | ||
1755 | * Correct the phase and frequency and switch to SYNC state. | ||
1756 | * freq_drift was already estimated (see code above) | ||
1757 | */ | ||
1758 | set_new_values(STATE_SYNC, offset, recv_time); | ||
1759 | break; | ||
1760 | #endif | ||
1761 | |||
1762 | default: | ||
1763 | #if !USING_KERNEL_PLL_LOOP | 1571 | #if !USING_KERNEL_PLL_LOOP |
1764 | /* Compute freq_drift due to PLL and FLL contributions. | 1572 | /* Compute freq_drift due to PLL and FLL contributions. |
1765 | * | 1573 | * |
1766 | * The FLL and PLL frequency gain constants | 1574 | * The FLL and PLL frequency gain constants |
1767 | * depend on the poll interval and Allan | 1575 | * depend on the poll interval and Allan |
1768 | * intercept. The FLL is not used below one-half | 1576 | * intercept. The FLL is not used below one-half |
1769 | * the Allan intercept. Above that the loop gain | 1577 | * the Allan intercept. Above that the loop gain |
1770 | * increases in steps to 1 / AVG. | 1578 | * increases in steps to 1 / AVG. |
1771 | */ | 1579 | */ |
1772 | if ((1 << G.poll_exp) > ALLAN / 2) { | 1580 | if ((1 << G.poll_exp) > ALLAN / 2) { |
1773 | etemp = FLL - G.poll_exp; | 1581 | etemp = FLL - G.poll_exp; |
1774 | if (etemp < AVG) | 1582 | if (etemp < AVG) |
1775 | etemp = AVG; | 1583 | etemp = AVG; |
1776 | freq_drift += (offset - G.last_update_offset) / (MAXD(since_last_update, ALLAN) * etemp); | 1584 | freq_drift += (offset - G.last_update_offset) / (MAXD(since_last_update, ALLAN) * etemp); |
1777 | } | ||
1778 | /* For the PLL the integration interval | ||
1779 | * (numerator) is the minimum of the update | ||
1780 | * interval and poll interval. This allows | ||
1781 | * oversampling, but not undersampling. | ||
1782 | */ | ||
1783 | etemp = MIND(since_last_update, (1 << G.poll_exp)); | ||
1784 | dtemp = (4 * PLL) << G.poll_exp; | ||
1785 | freq_drift += offset * etemp / SQUARE(dtemp); | ||
1786 | #endif | ||
1787 | set_new_values(STATE_SYNC, offset, recv_time); | ||
1788 | break; | ||
1789 | } | 1585 | } |
1586 | /* For the PLL the integration interval | ||
1587 | * (numerator) is the minimum of the update | ||
1588 | * interval and poll interval. This allows | ||
1589 | * oversampling, but not undersampling. | ||
1590 | */ | ||
1591 | etemp = MIND(since_last_update, (1 << G.poll_exp)); | ||
1592 | dtemp = (4 * PLL) << G.poll_exp; | ||
1593 | freq_drift += offset * etemp / SQUARE(dtemp); | ||
1594 | #endif | ||
1595 | set_new_values(offset, recv_time); | ||
1790 | if (G.stratum != p->lastpkt_stratum + 1) { | 1596 | if (G.stratum != p->lastpkt_stratum + 1) { |
1791 | G.stratum = p->lastpkt_stratum + 1; | 1597 | G.stratum = p->lastpkt_stratum + 1; |
1792 | run_script("stratum", offset); | 1598 | run_script("stratum", offset); |
@@ -1805,9 +1611,7 @@ update_local_clock(peer_t *p) | |||
1805 | G.rootdisp = p->lastpkt_rootdisp + dtemp; | 1611 | G.rootdisp = p->lastpkt_rootdisp + dtemp; |
1806 | VERB4 bb_error_msg("updating leap/refid/reftime/rootdisp from peer %s", p->p_dotted); | 1612 | VERB4 bb_error_msg("updating leap/refid/reftime/rootdisp from peer %s", p->p_dotted); |
1807 | 1613 | ||
1808 | /* We are in STATE_SYNC now, but did not do adjtimex yet. | 1614 | /* By this time, freq_drift and offset are set |
1809 | * (Any other state does not reach this, they all return earlier) | ||
1810 | * By this time, freq_drift and offset are set | ||
1811 | * to values suitable for adjtimex. | 1615 | * to values suitable for adjtimex. |
1812 | */ | 1616 | */ |
1813 | #if !USING_KERNEL_PLL_LOOP | 1617 | #if !USING_KERNEL_PLL_LOOP |
@@ -2349,6 +2153,12 @@ recv_and_process_client_pkt(void /*int fd*/) | |||
2349 | do_sendto(G_listen_fd, | 2153 | do_sendto(G_listen_fd, |
2350 | /*from:*/ &to->u.sa, /*to:*/ from, /*addrlen:*/ to->len, | 2154 | /*from:*/ &to->u.sa, /*to:*/ from, /*addrlen:*/ to->len, |
2351 | &msg, size); | 2155 | &msg, size); |
2156 | VERB3 { | ||
2157 | char *addr; | ||
2158 | addr = xmalloc_sockaddr2dotted_noport(from); | ||
2159 | bb_error_msg("responded to query from %s", addr); | ||
2160 | free(addr); | ||
2161 | } | ||
2352 | 2162 | ||
2353 | bail: | 2163 | bail: |
2354 | free(to); | 2164 | free(to); |
@@ -2767,7 +2577,7 @@ int ntpd_main(int argc UNUSED_PARAM, char **argv) | |||
2767 | timeout++; /* (nextaction - G.cur_time) rounds down, compensating */ | 2577 | timeout++; /* (nextaction - G.cur_time) rounds down, compensating */ |
2768 | 2578 | ||
2769 | /* Here we may block */ | 2579 | /* Here we may block */ |
2770 | VERB2 { | 2580 | VERB3 { |
2771 | if (i > (ENABLE_FEATURE_NTPD_SERVER && G_listen_fd != -1)) { | 2581 | if (i > (ENABLE_FEATURE_NTPD_SERVER && G_listen_fd != -1)) { |
2772 | /* We wait for at least one reply. | 2582 | /* We wait for at least one reply. |
2773 | * Poll for it, without wasting time for message. | 2583 | * Poll for it, without wasting time for message. |
diff --git a/networking/udhcp/d6_dhcpc.c b/networking/udhcp/d6_dhcpc.c index fbdaa99bd..76b087b92 100644 --- a/networking/udhcp/d6_dhcpc.c +++ b/networking/udhcp/d6_dhcpc.c | |||
@@ -1589,8 +1589,10 @@ int udhcpc6_main(int argc UNUSED_PARAM, char **argv) | |||
1589 | } | 1589 | } |
1590 | 1590 | ||
1591 | if ((packet.d6_xid32 & htonl(0x00ffffff)) != xid) { | 1591 | if ((packet.d6_xid32 & htonl(0x00ffffff)) != xid) { |
1592 | log1("xid %x (our is %x), ignoring packet", | 1592 | log1("xid %x (our is %x)%s", |
1593 | (unsigned)(packet.d6_xid32 & htonl(0x00ffffff)), (unsigned)xid); | 1593 | (unsigned)(packet.d6_xid32 & htonl(0x00ffffff)), (unsigned)xid, |
1594 | ", ignoring packet" | ||
1595 | ); | ||
1594 | continue; | 1596 | continue; |
1595 | } | 1597 | } |
1596 | 1598 | ||
@@ -1743,7 +1745,7 @@ int udhcpc6_main(int argc UNUSED_PARAM, char **argv) | |||
1743 | free(client6_data.ia_na); | 1745 | free(client6_data.ia_na); |
1744 | client6_data.ia_na = d6_copy_option(packet.d6_options, packet_end, D6_OPT_IA_NA); | 1746 | client6_data.ia_na = d6_copy_option(packet.d6_options, packet_end, D6_OPT_IA_NA); |
1745 | if (!client6_data.ia_na) { | 1747 | if (!client6_data.ia_na) { |
1746 | bb_info_msg("no %s option, ignoring packet", "IA_NA"); | 1748 | bb_info_msg("no %s option%s", "IA_NA", ", ignoring packet"); |
1747 | continue; | 1749 | continue; |
1748 | } | 1750 | } |
1749 | if (client6_data.ia_na->len < (4 + 4 + 4) + (2 + 2 + 16 + 4 + 4)) { | 1751 | if (client6_data.ia_na->len < (4 + 4 + 4) + (2 + 2 + 16 + 4 + 4)) { |
@@ -1756,7 +1758,7 @@ int udhcpc6_main(int argc UNUSED_PARAM, char **argv) | |||
1756 | D6_OPT_IAADDR | 1758 | D6_OPT_IAADDR |
1757 | ); | 1759 | ); |
1758 | if (!iaaddr) { | 1760 | if (!iaaddr) { |
1759 | bb_info_msg("no %s option, ignoring packet", "IAADDR"); | 1761 | bb_info_msg("no %s option%s", "IAADDR", ", ignoring packet"); |
1760 | continue; | 1762 | continue; |
1761 | } | 1763 | } |
1762 | if (iaaddr->len < (16 + 4 + 4)) { | 1764 | if (iaaddr->len < (16 + 4 + 4)) { |
@@ -1781,7 +1783,7 @@ int udhcpc6_main(int argc UNUSED_PARAM, char **argv) | |||
1781 | free(client6_data.ia_pd); | 1783 | free(client6_data.ia_pd); |
1782 | client6_data.ia_pd = d6_copy_option(packet.d6_options, packet_end, D6_OPT_IA_PD); | 1784 | client6_data.ia_pd = d6_copy_option(packet.d6_options, packet_end, D6_OPT_IA_PD); |
1783 | if (!client6_data.ia_pd) { | 1785 | if (!client6_data.ia_pd) { |
1784 | bb_info_msg("no %s option, ignoring packet", "IA_PD"); | 1786 | bb_info_msg("no %s option%s", "IA_PD", ", ignoring packet"); |
1785 | continue; | 1787 | continue; |
1786 | } | 1788 | } |
1787 | if (client6_data.ia_pd->len < (4 + 4 + 4) + (2 + 2 + 4 + 4 + 1 + 16)) { | 1789 | if (client6_data.ia_pd->len < (4 + 4 + 4) + (2 + 2 + 4 + 4 + 1 + 16)) { |
@@ -1794,7 +1796,7 @@ int udhcpc6_main(int argc UNUSED_PARAM, char **argv) | |||
1794 | D6_OPT_IAPREFIX | 1796 | D6_OPT_IAPREFIX |
1795 | ); | 1797 | ); |
1796 | if (!iaprefix) { | 1798 | if (!iaprefix) { |
1797 | bb_info_msg("no %s option, ignoring packet", "IAPREFIX"); | 1799 | bb_info_msg("no %s option%s", "IAPREFIX", ", ignoring packet"); |
1798 | continue; | 1800 | continue; |
1799 | } | 1801 | } |
1800 | if (iaprefix->len < (4 + 4 + 1 + 16)) { | 1802 | if (iaprefix->len < (4 + 4 + 1 + 16)) { |
diff --git a/networking/udhcp/dhcpc.c b/networking/udhcp/dhcpc.c index 922c71ebd..bbcbd1fca 100644 --- a/networking/udhcp/dhcpc.c +++ b/networking/udhcp/dhcpc.c | |||
@@ -729,7 +729,7 @@ static NOINLINE int send_discover(uint32_t xid, uint32_t requested) | |||
729 | */ | 729 | */ |
730 | add_client_options(&packet); | 730 | add_client_options(&packet); |
731 | 731 | ||
732 | bb_info_msg("sending %s", "discover"); | 732 | bb_simple_info_msg("broadcasting discover"); |
733 | return raw_bcast_from_client_data_ifindex(&packet, INADDR_ANY); | 733 | return raw_bcast_from_client_data_ifindex(&packet, INADDR_ANY); |
734 | } | 734 | } |
735 | 735 | ||
@@ -742,6 +742,7 @@ static NOINLINE int send_select(uint32_t xid, uint32_t server, uint32_t requeste | |||
742 | { | 742 | { |
743 | struct dhcp_packet packet; | 743 | struct dhcp_packet packet; |
744 | struct in_addr temp_addr; | 744 | struct in_addr temp_addr; |
745 | char server_str[sizeof("255.255.255.255")]; | ||
745 | 746 | ||
746 | /* | 747 | /* |
747 | * RFC 2131 4.3.2 DHCPREQUEST message | 748 | * RFC 2131 4.3.2 DHCPREQUEST message |
@@ -772,8 +773,13 @@ static NOINLINE int send_select(uint32_t xid, uint32_t server, uint32_t requeste | |||
772 | */ | 773 | */ |
773 | add_client_options(&packet); | 774 | add_client_options(&packet); |
774 | 775 | ||
776 | temp_addr.s_addr = server; | ||
777 | strcpy(server_str, inet_ntoa(temp_addr)); | ||
775 | temp_addr.s_addr = requested; | 778 | temp_addr.s_addr = requested; |
776 | bb_info_msg("sending select for %s", inet_ntoa(temp_addr)); | 779 | bb_info_msg("broadcasting select for %s, server %s", |
780 | inet_ntoa(temp_addr), | ||
781 | server_str | ||
782 | ); | ||
777 | return raw_bcast_from_client_data_ifindex(&packet, INADDR_ANY); | 783 | return raw_bcast_from_client_data_ifindex(&packet, INADDR_ANY); |
778 | } | 784 | } |
779 | 785 | ||
@@ -782,7 +788,6 @@ static NOINLINE int send_select(uint32_t xid, uint32_t server, uint32_t requeste | |||
782 | static NOINLINE int send_renew(uint32_t xid, uint32_t server, uint32_t ciaddr) | 788 | static NOINLINE int send_renew(uint32_t xid, uint32_t server, uint32_t ciaddr) |
783 | { | 789 | { |
784 | struct dhcp_packet packet; | 790 | struct dhcp_packet packet; |
785 | struct in_addr temp_addr; | ||
786 | 791 | ||
787 | /* | 792 | /* |
788 | * RFC 2131 4.3.2 DHCPREQUEST message | 793 | * RFC 2131 4.3.2 DHCPREQUEST message |
@@ -813,8 +818,14 @@ static NOINLINE int send_renew(uint32_t xid, uint32_t server, uint32_t ciaddr) | |||
813 | */ | 818 | */ |
814 | add_client_options(&packet); | 819 | add_client_options(&packet); |
815 | 820 | ||
816 | temp_addr.s_addr = server; | 821 | if (server) { |
817 | bb_info_msg("sending renew to %s", inet_ntoa(temp_addr)); | 822 | struct in_addr temp_addr; |
823 | temp_addr.s_addr = server; | ||
824 | bb_info_msg("sending renew to server %s", inet_ntoa(temp_addr)); | ||
825 | } else { | ||
826 | bb_simple_info_msg("broadcasting renew"); | ||
827 | } | ||
828 | |||
818 | return bcast_or_ucast(&packet, ciaddr, server); | 829 | return bcast_or_ucast(&packet, ciaddr, server); |
819 | } | 830 | } |
820 | 831 | ||
@@ -843,7 +854,7 @@ static NOINLINE int send_decline(/*uint32_t xid,*/ uint32_t server, uint32_t req | |||
843 | 854 | ||
844 | udhcp_add_simple_option(&packet, DHCP_SERVER_ID, server); | 855 | udhcp_add_simple_option(&packet, DHCP_SERVER_ID, server); |
845 | 856 | ||
846 | bb_info_msg("sending %s", "decline"); | 857 | bb_simple_info_msg("broadcasting decline"); |
847 | return raw_bcast_from_client_data_ifindex(&packet, INADDR_ANY); | 858 | return raw_bcast_from_client_data_ifindex(&packet, INADDR_ANY); |
848 | } | 859 | } |
849 | #endif | 860 | #endif |
@@ -1644,8 +1655,10 @@ int udhcpc_main(int argc UNUSED_PARAM, char **argv) | |||
1644 | } | 1655 | } |
1645 | 1656 | ||
1646 | if (packet.xid != xid) { | 1657 | if (packet.xid != xid) { |
1647 | log1("xid %x (our is %x), ignoring packet", | 1658 | log1("xid %x (our is %x)%s", |
1648 | (unsigned)packet.xid, (unsigned)xid); | 1659 | (unsigned)packet.xid, (unsigned)xid, |
1660 | ", ignoring packet" | ||
1661 | ); | ||
1649 | continue; | 1662 | continue; |
1650 | } | 1663 | } |
1651 | 1664 | ||
@@ -1720,6 +1733,7 @@ int udhcpc_main(int argc UNUSED_PARAM, char **argv) | |||
1720 | unsigned start; | 1733 | unsigned start; |
1721 | uint32_t lease_seconds; | 1734 | uint32_t lease_seconds; |
1722 | struct in_addr temp_addr; | 1735 | struct in_addr temp_addr; |
1736 | char server_str[sizeof("255.255.255.255")]; | ||
1723 | uint8_t *temp; | 1737 | uint8_t *temp; |
1724 | 1738 | ||
1725 | temp = udhcp_get_option32(&packet, DHCP_LEASE_TIME); | 1739 | temp = udhcp_get_option32(&packet, DHCP_LEASE_TIME); |
@@ -1775,9 +1789,11 @@ int udhcpc_main(int argc UNUSED_PARAM, char **argv) | |||
1775 | } | 1789 | } |
1776 | #endif | 1790 | #endif |
1777 | /* enter bound state */ | 1791 | /* enter bound state */ |
1792 | temp_addr.s_addr = server_addr; | ||
1793 | strcpy(server_str, inet_ntoa(temp_addr)); | ||
1778 | temp_addr.s_addr = packet.yiaddr; | 1794 | temp_addr.s_addr = packet.yiaddr; |
1779 | bb_info_msg("lease of %s obtained, lease time %u", | 1795 | bb_info_msg("lease of %s obtained from %s, lease time %u", |
1780 | inet_ntoa(temp_addr), (unsigned)lease_seconds); | 1796 | inet_ntoa(temp_addr), server_str, (unsigned)lease_seconds); |
1781 | requested_ip = packet.yiaddr; | 1797 | requested_ip = packet.yiaddr; |
1782 | 1798 | ||
1783 | start = monotonic_sec(); | 1799 | start = monotonic_sec(); |
diff --git a/networking/udhcp/dhcpd.c b/networking/udhcp/dhcpd.c index cd32cb437..260130507 100644 --- a/networking/udhcp/dhcpd.c +++ b/networking/udhcp/dhcpd.c | |||
@@ -1048,7 +1048,7 @@ int udhcpd_main(int argc UNUSED_PARAM, char **argv) | |||
1048 | move_from_unaligned32(server_id_network_order, server_id_opt); | 1048 | move_from_unaligned32(server_id_network_order, server_id_opt); |
1049 | if (server_id_network_order != server_data.server_nip) { | 1049 | if (server_id_network_order != server_data.server_nip) { |
1050 | /* client talks to somebody else */ | 1050 | /* client talks to somebody else */ |
1051 | log1("server ID doesn't match%s", ", ignoring"); | 1051 | log1("server ID doesn't match%s", ", ignoring packet"); |
1052 | continue; | 1052 | continue; |
1053 | } | 1053 | } |
1054 | } | 1054 | } |
@@ -1171,7 +1171,7 @@ o DHCPREQUEST generated during REBINDING state: | |||
1171 | if (!requested_ip_opt) { | 1171 | if (!requested_ip_opt) { |
1172 | requested_nip = packet.ciaddr; | 1172 | requested_nip = packet.ciaddr; |
1173 | if (requested_nip == 0) { | 1173 | if (requested_nip == 0) { |
1174 | log1("no requested IP and no ciaddr%s", ", ignoring"); | 1174 | log1("no requested IP and no ciaddr%s", ", ignoring packet"); |
1175 | break; | 1175 | break; |
1176 | } | 1176 | } |
1177 | } | 1177 | } |
diff --git a/scripts/trylink b/scripts/trylink index 6b74f092d..2255deee7 100755 --- a/scripts/trylink +++ b/scripts/trylink | |||
@@ -1,5 +1,6 @@ | |||
1 | #!/bin/sh | 1 | #!/bin/sh |
2 | 2 | ||
3 | #debug=true | ||
3 | debug=false | 4 | debug=false |
4 | 5 | ||
5 | # Linker flags used: | 6 | # Linker flags used: |
@@ -77,7 +78,13 @@ CFLAGS="$3" | |||
77 | LDFLAGS="$4" | 78 | LDFLAGS="$4" |
78 | O_FILES="$5" | 79 | O_FILES="$5" |
79 | A_FILES="$6" | 80 | A_FILES="$6" |
81 | # We try to drop libraries from LDLIBS if build works without them, | ||
82 | # but ones from CONFIG_EXTRA_LDLIBS are always linked in. | ||
83 | # (For example, musl has stub utmp implementation, and if you link with | ||
84 | # a real utmp library in LDLIBS, dropping it "works" but resulting binary | ||
85 | # does not work properly). | ||
80 | LDLIBS="$7" | 86 | LDLIBS="$7" |
87 | CONFIG_EXTRA_LDLIBS="$8" | ||
81 | 88 | ||
82 | # The --sort-section option is not supported by older versions of ld | 89 | # The --sort-section option is not supported by older versions of ld |
83 | SORT_SECTION="-Wl,--sort-section,alignment" | 90 | SORT_SECTION="-Wl,--sort-section,alignment" |
@@ -125,8 +132,8 @@ LDLIBS=`echo "$LDLIBS" | xargs -n1 | sort | uniq | xargs` | |||
125 | # First link with all libs. If it fails, bail out | 132 | # First link with all libs. If it fails, bail out |
126 | echo "Trying libraries: $LDLIBS" | 133 | echo "Trying libraries: $LDLIBS" |
127 | # "lib1 lib2 lib3" -> "-llib1 -llib2 -llib3" | 134 | # "lib1 lib2 lib3" -> "-llib1 -llib2 -llib3" |
128 | l_list=`echo " $LDLIBS " | sed -e 's: \([^- ][^ ]*\): -l\1:g'` | 135 | l_list=`echo " $LDLIBS $CONFIG_EXTRA_LDLIBS " | sed -e 's: \([^- ][^ ]*\): -l\1:g' -e 's/^ *//'` |
129 | test "x$l_list" != "x" && l_list="$START_GROUP $l_list $END_GROUP" | 136 | test x"$l_list" != x"" && l_list="$START_GROUP $l_list $END_GROUP" |
130 | try $CC $CFLAGS $LDFLAGS \ | 137 | try $CC $CFLAGS $LDFLAGS \ |
131 | -o $EXE \ | 138 | -o $EXE \ |
132 | $SORT_COMMON \ | 139 | $SORT_COMMON \ |
@@ -151,7 +158,7 @@ while test "$LDLIBS"; do | |||
151 | for one in $LDLIBS; do | 158 | for one in $LDLIBS; do |
152 | without_one=`echo " $LDLIBS " | sed "s/ $one / /g" | xargs` | 159 | without_one=`echo " $LDLIBS " | sed "s/ $one / /g" | xargs` |
153 | # "lib1 lib2 lib3" -> "-llib1 -llib2 -llib3" | 160 | # "lib1 lib2 lib3" -> "-llib1 -llib2 -llib3" |
154 | l_list=`echo " $without_one " | sed -e 's: \([^- ][^ ]*\): -l\1:g'` | 161 | l_list=`echo " $without_one $CONFIG_EXTRA_LDLIBS " | sed -e 's: \([^- ][^ ]*\): -l\1:g' -e 's/^ *//'` |
155 | test x"$l_list" != x"" && l_list="$START_GROUP $l_list $END_GROUP" | 162 | test x"$l_list" != x"" && l_list="$START_GROUP $l_list $END_GROUP" |
156 | $debug && echo "Trying -l options: '$l_list'" | 163 | $debug && echo "Trying -l options: '$l_list'" |
157 | try $CC $CFLAGS $LDFLAGS \ | 164 | try $CC $CFLAGS $LDFLAGS \ |
@@ -179,8 +186,8 @@ done | |||
179 | 186 | ||
180 | # Make the binary with final, minimal list of libs | 187 | # Make the binary with final, minimal list of libs |
181 | echo "Final link with: ${LDLIBS:-<none>}" | 188 | echo "Final link with: ${LDLIBS:-<none>}" |
182 | l_list=`echo " $LDLIBS " | sed -e 's: \([^- ][^ ]*\): -l\1:g'` | 189 | l_list=`echo " $LDLIBS $CONFIG_EXTRA_LDLIBS " | sed -e 's: \([^- ][^ ]*\): -l\1:g' -e 's/^ *//'` |
183 | test "x$l_list" != "x" && l_list="$START_GROUP $l_list $END_GROUP" | 190 | test x"$l_list" != x"" && l_list="$START_GROUP $l_list $END_GROUP" |
184 | # --verbose gives us gobs of info to stdout (e.g. linker script used) | 191 | # --verbose gives us gobs of info to stdout (e.g. linker script used) |
185 | if ! test -f busybox_ldscript; then | 192 | if ! test -f busybox_ldscript; then |
186 | try $CC $CFLAGS $LDFLAGS \ | 193 | try $CC $CFLAGS $LDFLAGS \ |
diff --git a/shell/ash.c b/shell/ash.c index 2c99c3ead..8cc7a5c75 100644 --- a/shell/ash.c +++ b/shell/ash.c | |||
@@ -4702,9 +4702,7 @@ sprint_status48(char *os, int status, int sigonly) | |||
4702 | #endif | 4702 | #endif |
4703 | } | 4703 | } |
4704 | st &= 0x7f; | 4704 | st &= 0x7f; |
4705 | //TODO: use bbox's get_signame? strsignal adds ~600 bytes to text+rodata | 4705 | s = stpncpy(s, strsignal(st), 32); |
4706 | //s = stpncpy(s, strsignal(st), 32); //not all libc have stpncpy() | ||
4707 | s += fmtstr(s, 32, strsignal(st)); | ||
4708 | if (WCOREDUMP(status)) { | 4706 | if (WCOREDUMP(status)) { |
4709 | s = stpcpy(s, " (core dumped)"); | 4707 | s = stpcpy(s, " (core dumped)"); |
4710 | } | 4708 | } |
diff --git a/testsuite/bc.tests b/testsuite/bc.tests index 179d5d2a2..1c748727a 100755 --- a/testsuite/bc.tests +++ b/testsuite/bc.tests | |||
@@ -182,6 +182,11 @@ testing "bc print 1,2,3" \ | |||
182 | "123" \ | 182 | "123" \ |
183 | "" "print 1,2,3" | 183 | "" "print 1,2,3" |
184 | 184 | ||
185 | testing "bc length" \ | ||
186 | "bc" \ | ||
187 | "1\n3\n1\n3\n3\n" \ | ||
188 | "" "length(0); length(100); length(0.01); length(0.00120); length(0.012-0.012);" | ||
189 | |||
185 | testing "bc { print 1 }" \ | 190 | testing "bc { print 1 }" \ |
186 | "bc" \ | 191 | "bc" \ |
187 | "1" \ | 192 | "1" \ |
diff --git a/testsuite/dc.tests b/testsuite/dc.tests index 361bc8459..ad0099354 100755 --- a/testsuite/dc.tests +++ b/testsuite/dc.tests | |||
@@ -114,6 +114,11 @@ testing "dc newline can be a register" \ | |||
114 | "2\n9\n" \ | 114 | "2\n9\n" \ |
115 | "" "[2p]s\n[3p]l\nx\n9p" | 115 | "" "[2p]s\n[3p]l\nx\n9p" |
116 | 116 | ||
117 | testing "dc Z (length) for numbers" \ | ||
118 | "dc" \ | ||
119 | "1\n1\n3\n1\n3\n1\n" \ | ||
120 | "" "0Zp\n0.000Zp\n100Zp\n0.01Zp\n0.00120Zp\n0.0012 0.0012 - Zp\n" | ||
121 | |||
117 | for f in dc_*.dc; do | 122 | for f in dc_*.dc; do |
118 | r="`basename "$f" .dc`_results.txt" | 123 | r="`basename "$f" .dc`_results.txt" |
119 | test -f "$r" || continue | 124 | test -f "$r" || continue |