From 82d1c1f84ae23793d81b50aa0a753ad7c4db4f51 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Sun, 31 Dec 2017 17:30:02 +0100 Subject: randomconfig fixes Signed-off-by: Denys Vlasenko --- libbb/Kbuild.src | 1 + libbb/lineedit.c | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-) (limited to 'libbb') diff --git a/libbb/Kbuild.src b/libbb/Kbuild.src index 73201a6bd..6e6d71ad5 100644 --- a/libbb/Kbuild.src +++ b/libbb/Kbuild.src @@ -124,6 +124,7 @@ lib-$(CONFIG_UNICODE_SUPPORT) += unicode.o lib-$(CONFIG_FEATURE_CHECK_NAMES) += die_if_bad_username.o lib-$(CONFIG_NC) += udp_io.o +lib-$(CONFIG_NETCAT) += udp_io.o lib-$(CONFIG_DNSD) += udp_io.o lib-$(CONFIG_NTPD) += udp_io.o lib-$(CONFIG_TFTP) += udp_io.o diff --git a/libbb/lineedit.c b/libbb/lineedit.c index 5624a7fc3..896bbc88c 100644 --- a/libbb/lineedit.c +++ b/libbb/lineedit.c @@ -90,7 +90,8 @@ static bool BB_ispunct(CHAR_T c) { return ((unsigned)c < 256 && ispunct(c)); } # define CHAR_T char # define BB_isspace(c) isspace(c) # if ENABLE_FEATURE_EDITING_VI -static bool BB_isalnum_or_underscore(CHAR_T c) { +static bool BB_isalnum_or_underscore(CHAR_T c) +{ return ((unsigned)c < 256 && isalnum(c)) || c == '_'; } # endif -- cgit v1.2.3-55-g6feb From 7367a949a6a81d71d524f0635a212371120df4e0 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Thu, 4 Jan 2018 15:21:25 +0100 Subject: libbb: compile obscure() only if FEATURE_PASSWD_WEAK_CHECK=y Signed-off-by: Denys Vlasenko --- libbb/Kbuild.src | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'libbb') diff --git a/libbb/Kbuild.src b/libbb/Kbuild.src index 6e6d71ad5..8c9ba8cca 100644 --- a/libbb/Kbuild.src +++ b/libbb/Kbuild.src @@ -143,7 +143,8 @@ lib-$(CONFIG_DELGROUP) += update_passwd.o lib-$(CONFIG_DELUSER) += update_passwd.o lib-$(CONFIG_FTPD) += pw_encrypt.o correct_password.o -lib-$(CONFIG_PASSWD) += pw_encrypt.o update_passwd.o obscure.o +lib-$(CONFIG_PASSWD) += pw_encrypt.o update_passwd.o +lib-$(CONFIG_FEATURE_PASSWD_WEAK_CHECK) += obscure.o lib-$(CONFIG_CHPASSWD) += pw_encrypt.o update_passwd.o lib-$(CONFIG_CRYPTPW) += pw_encrypt.o lib-$(CONFIG_MKPASSWD) += pw_encrypt.o -- cgit v1.2.3-55-g6feb From cca7c611f26d98415c0f986e5a5e731ab5e379ff Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Fri, 12 Jan 2018 13:21:33 +0100 Subject: which: fix TODO with NOFORK+malloc_failure misbehaving function old new delta find_executable 86 104 +18 which_main 202 194 -8 executable_exists 66 51 -15 ------------------------------------------------------------------------------ (add/remove: 0/0 grow/shrink: 1/2 up/down: 18/-23) Total: -5 bytes Signed-off-by: Denys Vlasenko --- debianutils/which.c | 16 ++++++++-------- include/libbb.h | 12 +++++++++--- libbb/executable.c | 18 ++++++++++-------- libbb/messages.c | 8 +------- 4 files changed, 28 insertions(+), 26 deletions(-) (limited to 'libbb') diff --git a/debianutils/which.c b/debianutils/which.c index 3bd54ac42..02f77a216 100644 --- a/debianutils/which.c +++ b/debianutils/which.c @@ -30,12 +30,15 @@ int which_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; int which_main(int argc UNUSED_PARAM, char **argv) { - const char *env_path; + char *env_path; int status = 0; + /* This sizeof(): bb_default_root_path is shorter than BB_PATH_ROOT_PATH */ + char buf[sizeof(BB_PATH_ROOT_PATH)]; env_path = getenv("PATH"); if (!env_path) - env_path = bb_default_root_path; + /* env_path must be writable, and must not alloc, so... */ + env_path = strcpy(buf, bb_default_root_path); getopt32(argv, "^" "a" "\0" "-1"/*at least one arg*/); argv += optind; @@ -51,20 +54,17 @@ int which_main(int argc UNUSED_PARAM, char **argv) } } else { char *path; - char *tmp; char *p; - path = tmp = xstrdup(env_path); -//NOFORK FIXME: nested xmallocs (one is inside find_executable()) -//can leak memory on failure - while ((p = find_executable(*argv, &tmp)) != NULL) { + path = env_path; + /* NOFORK NB: xmalloc inside find_executable(), must have no allocs above! */ + while ((p = find_executable(*argv, &path)) != NULL) { missing = 0; puts(p); free(p); if (!option_mask32) /* -a not set */ break; } - free(path); } status |= missing; } while (*++argv); diff --git a/include/libbb.h b/include/libbb.h index daccf154a..5f25b5dde 100644 --- a/include/libbb.h +++ b/include/libbb.h @@ -2005,10 +2005,16 @@ extern const char bb_path_wtmp_file[] ALIGN1; #define bb_dev_null "/dev/null" extern const char bb_busybox_exec_path[] ALIGN1; -/* util-linux manpage says /sbin:/bin:/usr/sbin:/usr/bin, - * but I want to save a few bytes here */ -extern const char bb_PATH_root_path[] ALIGN1; /* "PATH=/sbin:/usr/sbin:/bin:/usr/bin" */ +/* allow default system PATH to be extended via CFLAGS */ +#ifndef BB_ADDITIONAL_PATH +#define BB_ADDITIONAL_PATH "" +#endif +#define BB_PATH_ROOT_PATH "PATH=/sbin:/usr/sbin:/bin:/usr/bin" BB_ADDITIONAL_PATH +extern const char bb_PATH_root_path[] ALIGN1; /* BB_PATH_ROOT_PATH */ #define bb_default_root_path (bb_PATH_root_path + sizeof("PATH")) +/* util-linux manpage says /sbin:/bin:/usr/sbin:/usr/bin, + * but I want to save a few bytes here: + */ #define bb_default_path (bb_PATH_root_path + sizeof("PATH=/sbin:/usr/sbin")) extern const int const_int_0; diff --git a/libbb/executable.c b/libbb/executable.c index 325dd0107..29d2a2c85 100644 --- a/libbb/executable.c +++ b/libbb/executable.c @@ -25,7 +25,8 @@ int FAST_FUNC file_is_executable(const char *name) * you may call find_executable again with this PATHp to continue * (if it's not NULL). * return NULL otherwise; (PATHp is undefined) - * in all cases (*PATHp) contents will be trashed (s/:/NUL/). + * in all cases (*PATHp) contents are temporarily modified + * but are restored on return (s/:/NUL/ and back). */ char* FAST_FUNC find_executable(const char *filename, char **PATHp) { @@ -41,14 +42,17 @@ char* FAST_FUNC find_executable(const char *filename, char **PATHp) p = *PATHp; while (p) { + int ex; + n = strchr(p, ':'); - if (n) - *n++ = '\0'; + if (n) *n = '\0'; p = concat_path_file( p[0] ? p : ".", /* handle "::" case */ filename ); - if (file_is_executable(p)) { + ex = file_is_executable(p); + if (n) *n++ = ':'; + if (ex) { *PATHp = n; return p; } @@ -64,10 +68,8 @@ char* FAST_FUNC find_executable(const char *filename, char **PATHp) */ int FAST_FUNC executable_exists(const char *filename) { - char *path = xstrdup(getenv("PATH")); - char *tmp = path; - char *ret = find_executable(filename, &tmp); - free(path); + char *path = getenv("PATH"); + char *ret = find_executable(filename, &path); free(ret); return ret != NULL; } diff --git a/libbb/messages.c b/libbb/messages.c index 0a6cf3bf8..6914d5701 100644 --- a/libbb/messages.c +++ b/libbb/messages.c @@ -6,11 +6,6 @@ */ #include "libbb.h" -/* allow default system PATH to be extended via CFLAGS */ -#ifndef BB_ADDITIONAL_PATH -#define BB_ADDITIONAL_PATH "" -#endif - /* allow version to be extended, via CFLAGS */ #ifndef BB_EXTRA_VERSION #define BB_EXTRA_VERSION " ("AUTOCONF_TIMESTAMP")" @@ -36,8 +31,7 @@ const char bb_busybox_exec_path[] ALIGN1 = CONFIG_BUSYBOX_EXEC_PATH; const char bb_default_login_shell[] ALIGN1 = LIBBB_DEFAULT_LOGIN_SHELL; /* util-linux manpage says /sbin:/bin:/usr/sbin:/usr/bin, * but I want to save a few bytes here. Check libbb.h before changing! */ -const char bb_PATH_root_path[] ALIGN1 = - "PATH=/sbin:/usr/sbin:/bin:/usr/bin" BB_ADDITIONAL_PATH; +const char bb_PATH_root_path[] ALIGN1 = BB_PATH_ROOT_PATH; //const int const_int_1 = 1; -- cgit v1.2.3-55-g6feb From ddacb03e875dd4c1a79421d030da9cdc4f081e6e Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Thu, 1 Feb 2018 10:56:19 +0100 Subject: libbb: commonalize a bit of little-endian CRC32 table generation code function old new delta global_crc32_new_table_le - 11 +11 crc32_new_table_le - 9 +9 inflate_unzip_internal 560 556 -4 flash_eraseall_main 823 819 -4 unpack_xz_stream 2403 2394 -9 lzop_main 121 112 -9 gzip_main 187 178 -9 ------------------------------------------------------------------------------ (add/remove: 2/0 grow/shrink: 0/5 up/down: 20/-35) Total: -15 bytes Signed-off-by: Denys Vlasenko --- archival/gzip.c | 2 +- archival/libarchive/decompress_gunzip.c | 2 +- archival/libarchive/decompress_unxz.c | 2 +- archival/lzop.c | 2 +- include/libbb.h | 2 ++ libbb/crc32.c | 10 ++++++++++ miscutils/flash_eraseall.c | 2 +- util-linux/fdisk_gpt.c | 2 +- 8 files changed, 18 insertions(+), 6 deletions(-) (limited to 'libbb') diff --git a/archival/gzip.c b/archival/gzip.c index e3dd79291..c5a1fe9b4 100644 --- a/archival/gzip.c +++ b/archival/gzip.c @@ -2239,7 +2239,7 @@ int gzip_main(int argc UNUSED_PARAM, char **argv) ALLOC(ush, G1.prev, 1L << BITS); /* Initialize the CRC32 table */ - global_crc32_table = crc32_filltable(NULL, 0); + global_crc32_new_table_le(); argv += optind; return bbunpack(argv, pack_gzip, append_ext, "gz"); diff --git a/archival/libarchive/decompress_gunzip.c b/archival/libarchive/decompress_gunzip.c index c8245d736..edff7e0e5 100644 --- a/archival/libarchive/decompress_gunzip.c +++ b/archival/libarchive/decompress_gunzip.c @@ -1000,7 +1000,7 @@ inflate_unzip_internal(STATE_PARAM transformer_state_t *xstate) gunzip_bb = 0; /* Create the crc table */ - gunzip_crc_table = crc32_filltable(NULL, 0); + gunzip_crc_table = crc32_new_table_le(); gunzip_crc = ~0; error_msg = "corrupted data"; diff --git a/archival/libarchive/decompress_unxz.c b/archival/libarchive/decompress_unxz.c index 0be85500c..8ae7a275b 100644 --- a/archival/libarchive/decompress_unxz.c +++ b/archival/libarchive/decompress_unxz.c @@ -52,7 +52,7 @@ unpack_xz_stream(transformer_state_t *xstate) IF_DESKTOP(long long) int total = 0; if (!global_crc32_table) - global_crc32_table = crc32_filltable(NULL, /*endian:*/ 0); + global_crc32_new_table_le(); memset(&iobuf, 0, sizeof(iobuf)); membuf = xmalloc(2 * BUFSIZ); diff --git a/archival/lzop.c b/archival/lzop.c index ba27aeff0..fef8cdba3 100644 --- a/archival/lzop.c +++ b/archival/lzop.c @@ -1148,6 +1148,6 @@ int lzop_main(int argc UNUSED_PARAM, char **argv) if (ENABLE_UNLZOP && applet_name[4] == 'o') option_mask32 |= OPT_DECOMPRESS; - global_crc32_table = crc32_filltable(NULL, 0); + global_crc32_new_table_le(); return bbunpack(argv, pack_lzop, make_new_name_lzop, /*unused:*/ NULL); } diff --git a/include/libbb.h b/include/libbb.h index a93864020..2bb364366 100644 --- a/include/libbb.h +++ b/include/libbb.h @@ -1928,6 +1928,8 @@ typedef struct md5_ctx_t md5sha_ctx_t; extern uint32_t *global_crc32_table; uint32_t *crc32_filltable(uint32_t *tbl256, int endian) FAST_FUNC; +uint32_t *crc32_new_table_le(void) FAST_FUNC; +uint32_t *global_crc32_new_table_le(void) FAST_FUNC; uint32_t crc32_block_endian1(uint32_t val, const void *buf, unsigned len, uint32_t *crc_table) FAST_FUNC; uint32_t crc32_block_endian0(uint32_t val, const void *buf, unsigned len, uint32_t *crc_table) FAST_FUNC; diff --git a/libbb/crc32.c b/libbb/crc32.c index b00b580d0..728bcb736 100644 --- a/libbb/crc32.c +++ b/libbb/crc32.c @@ -41,6 +41,16 @@ uint32_t* FAST_FUNC crc32_filltable(uint32_t *crc_table, int endian) return crc_table - 256; } +/* Common uses: */ +uint32_t* FAST_FUNC crc32_new_table_le(void) +{ + return crc32_filltable(NULL, 0); +} +uint32_t* FAST_FUNC global_crc32_new_table_le(void) +{ + global_crc32_table = crc32_new_table_le(); + return global_crc32_table; +} uint32_t FAST_FUNC crc32_block_endian1(uint32_t val, const void *buf, unsigned len, uint32_t *crc_table) { diff --git a/miscutils/flash_eraseall.c b/miscutils/flash_eraseall.c index fab21291c..8e93060ca 100644 --- a/miscutils/flash_eraseall.c +++ b/miscutils/flash_eraseall.c @@ -101,7 +101,7 @@ int flash_eraseall_main(int argc UNUSED_PARAM, char **argv) if (flags & OPTION_J) { uint32_t *crc32_table; - crc32_table = crc32_filltable(NULL, 0); + crc32_table = crc32_new_table_le(); cleanmarker.magic = cpu_to_je16(JFFS2_MAGIC_BITMASK); cleanmarker.nodetype = cpu_to_je16(JFFS2_NODETYPE_CLEANMARKER); diff --git a/util-linux/fdisk_gpt.c b/util-linux/fdisk_gpt.c index 45d2aa6e7..cdb90627d 100644 --- a/util-linux/fdisk_gpt.c +++ b/util-linux/fdisk_gpt.c @@ -177,7 +177,7 @@ check_gpt_label(void) init_unicode(); if (!global_crc32_table) { - global_crc32_table = crc32_filltable(NULL, 0); + global_crc32_new_table_le(); } crc = SWAP_LE32(gpt_hdr->hdr_crc32); -- cgit v1.2.3-55-g6feb From 5cdd120f0c6423a42fa2eec2311126142a9a49f0 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Tue, 6 Feb 2018 17:59:32 +0100 Subject: unzip: do not set directory mode to 0777 https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=882177 Signed-off-by: Denys Vlasenko --- archival/unzip.c | 4 +++- libbb/make_directory.c | 16 ++++++++++------ 2 files changed, 13 insertions(+), 7 deletions(-) (limited to 'libbb') diff --git a/archival/unzip.c b/archival/unzip.c index 653fdd10f..da4b2a544 100644 --- a/archival/unzip.c +++ b/archival/unzip.c @@ -336,7 +336,9 @@ static void unzip_create_leading_dirs(const char *fn) { /* Create all leading directories */ char *name = xstrdup(fn); - if (bb_make_directory(dirname(name), 0777, FILEUTILS_RECUR)) { + + /* mode of -1: set mode according to umask */ + if (bb_make_directory(dirname(name), -1, FILEUTILS_RECUR)) { xfunc_die(); /* bb_make_directory is noisy */ } free(name); diff --git a/libbb/make_directory.c b/libbb/make_directory.c index b9916d165..64736efbe 100644 --- a/libbb/make_directory.c +++ b/libbb/make_directory.c @@ -92,6 +92,7 @@ int FAST_FUNC bb_make_directory(char *path, long mode, int flags) } } + //bb_error_msg("mkdir '%s'", path); if (mkdir(path, 0777) < 0) { /* If we failed for any other reason than the directory * already exists, output a diagnostic and return -1 */ @@ -118,13 +119,16 @@ int FAST_FUNC bb_make_directory(char *path, long mode, int flags) /* Done. If necessary, update perms on the newly * created directory. Failure to update here _is_ * an error. */ - if ((mode != -1) && (chmod(path, mode) < 0)) { - fail_msg = "set permissions of"; - if (flags & FILEUTILS_IGNORE_CHMOD_ERR) { - flags = 0; - goto print_err; + if (mode != -1) { + //bb_error_msg("chmod 0%03lo mkdir '%s'", mode, path); + if (chmod(path, mode) < 0)) { + fail_msg = "set permissions of"; + if (flags & FILEUTILS_IGNORE_CHMOD_ERR) { + flags = 0; + goto print_err; + } + break; } - break; } goto ret0; } -- cgit v1.2.3-55-g6feb From 1267770a9db90b2a29553e682e3b63aa86b0b34d Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Tue, 6 Feb 2018 18:01:39 +0100 Subject: fix compile failure in previous commit Signed-off-by: Denys Vlasenko --- libbb/make_directory.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'libbb') diff --git a/libbb/make_directory.c b/libbb/make_directory.c index 64736efbe..9b03bb8d0 100644 --- a/libbb/make_directory.c +++ b/libbb/make_directory.c @@ -121,7 +121,7 @@ int FAST_FUNC bb_make_directory(char *path, long mode, int flags) * an error. */ if (mode != -1) { //bb_error_msg("chmod 0%03lo mkdir '%s'", mode, path); - if (chmod(path, mode) < 0)) { + if (chmod(path, mode) < 0) { fail_msg = "set permissions of"; if (flags & FILEUTILS_IGNORE_CHMOD_ERR) { flags = 0; -- cgit v1.2.3-55-g6feb From ab843e3244e98f92e16b9c9c1f06dbab87e97175 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Wed, 7 Feb 2018 17:47:39 +0100 Subject: libbb: shrink wget/tftp progress indicator code for 32-bit function old new delta bb_progress_update 756 654 -102 Signed-off-by: Denys Vlasenko --- libbb/progress.c | 78 +++++++++++++++++++++++++++----------------------------- 1 file changed, 38 insertions(+), 40 deletions(-) (limited to 'libbb') diff --git a/libbb/progress.c b/libbb/progress.c index 64e6529ac..17272fd17 100644 --- a/libbb/progress.c +++ b/libbb/progress.c @@ -71,7 +71,7 @@ void FAST_FUNC bb_progress_update(bb_progress_t *p, uoff_t transferred, uoff_t totalsize) { - uoff_t beg_and_transferred; + unsigned beg_and_transferred; /* does not need uoff_t, see scaling code below */ unsigned since_last_update, elapsed; int notty; int kiloscale; @@ -102,33 +102,24 @@ void FAST_FUNC bb_progress_update(bb_progress_t *p, * without risking overflow: we guarantee 10 highest bits to be 0. * Introduced error is less than 1 / 2^12 ~= 0.025% */ - if (ULONG_MAX > 0xffffffff || sizeof(off_t) == 4 || sizeof(off_t) != 8) { - /* - * 64-bit CPU || small off_t: in either case, - * >> is cheap, single-word operation. - * ... || strange off_t: also use this code - * (it is safe, just suboptimal wrt code size), - * because 32/64 optimized one works only for 64-bit off_t. - */ - if (totalsize >= (1 << 22)) { - totalsize >>= 10; - beg_size >>= 10; - transferred >>= 10; - kiloscale = 1; - } - } else { - /* 32-bit CPU and 64-bit off_t. - * Use a 40-bit shift, it is easier to do on 32-bit CPU. - */ -/* ONE suppresses "warning: shift count >= width of type" */ -#define ONE (sizeof(off_t) > 4) - if (totalsize >= (uoff_t)(1ULL << 54*ONE)) { - totalsize = (uint32_t)(totalsize >> 32*ONE) >> 8; - beg_size = (uint32_t)(beg_size >> 32*ONE) >> 8; - transferred = (uint32_t)(transferred >> 32*ONE) >> 8; - kiloscale = 4; - } + while (totalsize >= (1 << 22)) { + totalsize >>= 10; + beg_size >>= 10; + transferred >>= 10; + kiloscale++; } + /* If they were huge, now they are scaled down to [4194303,4096] range. + * (N * totalsize) won't overflow 32 bits for N up to 1024. + * The downside is that files larger than 4194303 kbytes (>4GB) + * never show kbytes download size, they show "0M","1M"... right away + * since kiloscale is already >1. + */ +#if ULONG_MAX == 0xffffffff +/* 32-bit CPU, uoff_t arithmetic is complex on it, cast variables to narrower types */ +# define totalsize ((unsigned)totalsize) +# define beg_size ((unsigned)beg_size) +# define transferred ((unsigned)transferred) +#endif notty = !isatty(STDERR_FILENO); @@ -146,13 +137,18 @@ void FAST_FUNC bb_progress_update(bb_progress_t *p, barlength = get_terminal_width(2) - 49; if (barlength > 0) { - /* god bless gcc for variable arrays :) */ - char buf[barlength + 1]; - unsigned stars = (unsigned)barlength * beg_and_transferred / totalsize; - memset(buf, ' ', barlength); - buf[barlength] = '\0'; - memset(buf, '*', stars); - fprintf(stderr, " |%s|", buf); + if (barlength > 999) + barlength = 999; + { + /* god bless gcc for variable arrays :) */ + char buf[barlength + 1]; + unsigned stars = (unsigned)barlength * beg_and_transferred / totalsize; + /* can't overflow ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ */ + memset(buf, ' ', barlength); + buf[barlength] = '\0'; + memset(buf, '*', stars); + fprintf(stderr, " |%s|", buf); + } } } @@ -184,16 +180,18 @@ void FAST_FUNC bb_progress_update(bb_progress_t *p, fprintf(stderr, " --:--:-- ETA"); } else { unsigned eta, secs, hours; + unsigned bytes; - totalsize -= beg_size; /* now it's "total to upload" */ + bytes = totalsize - beg_size; /* Estimated remaining time = - * estimated_sec_to_dl_totalsize_bytes - elapsed_sec = - * totalsize / average_bytes_sec_so_far - elapsed = - * totalsize / (transferred/elapsed) - elapsed = - * totalsize * elapsed / transferred - elapsed + * estimated_sec_to_dl_bytes - elapsed_sec = + * bytes / average_bytes_sec_so_far - elapsed = + * bytes / (transferred/elapsed) - elapsed = + * bytes * elapsed / transferred - elapsed */ - eta = totalsize * elapsed / transferred - elapsed; + eta = (unsigned long)bytes * elapsed / transferred - elapsed; + /* if 32bit, can overflow ^^^^^^^^^^, but this would only show bad ETA */ if (eta >= 1000*60*60) eta = 1000*60*60 - 1; secs = eta % 3600; -- cgit v1.2.3-55-g6feb From 47529d3f165c06bd0c3be751fdd4b743b4bddedb Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Wed, 7 Feb 2018 23:48:34 +0100 Subject: libbb: shrink wget/tftp progress indicator code a bit more This makes size display 5-char wide instead of 6-char, but now it's smarter (can show sizes in "12.3M" format). function old new delta bb_progress_update 654 622 -32 Signed-off-by: Denys Vlasenko --- libbb/progress.c | 56 +++++++++++++++++++++++++++----------------------------- 1 file changed, 27 insertions(+), 29 deletions(-) (limited to 'libbb') diff --git a/libbb/progress.c b/libbb/progress.c index 17272fd17..f1d980d68 100644 --- a/libbb/progress.c +++ b/libbb/progress.c @@ -71,10 +71,9 @@ void FAST_FUNC bb_progress_update(bb_progress_t *p, uoff_t transferred, uoff_t totalsize) { - unsigned beg_and_transferred; /* does not need uoff_t, see scaling code below */ + char numbuf5[6]; /* 5 + 1 for NUL */ unsigned since_last_update, elapsed; int notty; - int kiloscale; //transferred = 1234; /* use for stall detection testing */ //totalsize = 0; /* use for unknown size download testing */ @@ -95,24 +94,22 @@ void FAST_FUNC bb_progress_update(bb_progress_t *p, return; } - kiloscale = 0; + /* Before we lose real, unscaled sizes, produce human-readable size string */ + smart_ulltoa5(beg_size + transferred, numbuf5, " kMGTPEZY")[0] = '\0'; + /* * Scale sizes down if they are close to overflowing. * This allows calculations like (100 * transferred / totalsize) * without risking overflow: we guarantee 10 highest bits to be 0. * Introduced error is less than 1 / 2^12 ~= 0.025% */ - while (totalsize >= (1 << 22)) { - totalsize >>= 10; - beg_size >>= 10; - transferred >>= 10; - kiloscale++; + while (totalsize >= (1 << 20)) { + totalsize >>= 8; + beg_size >>= 8; + transferred >>= 8; } - /* If they were huge, now they are scaled down to [4194303,4096] range. - * (N * totalsize) won't overflow 32 bits for N up to 1024. - * The downside is that files larger than 4194303 kbytes (>4GB) - * never show kbytes download size, they show "0M","1M"... right away - * since kiloscale is already >1. + /* If they were huge, now they are scaled down to [1048575,4096] range. + * (N * totalsize) won't overflow 32 bits for N up to 4096. */ #if ULONG_MAX == 0xffffffff /* 32-bit CPU, uoff_t arithmetic is complex on it, cast variables to narrower types */ @@ -124,19 +121,26 @@ void FAST_FUNC bb_progress_update(bb_progress_t *p, notty = !isatty(STDERR_FILENO); if (ENABLE_UNICODE_SUPPORT) - fprintf(stderr, "\r%s" + notty, p->curfile); + fprintf(stderr, "\r%s " + notty, p->curfile); else - fprintf(stderr, "\r%-20.20s" + notty, p->curfile); - - beg_and_transferred = beg_size + transferred; + fprintf(stderr, "\r%-20.20s " + notty, p->curfile); if (totalsize != 0) { int barlength; - unsigned ratio = 100 * beg_and_transferred / totalsize; - fprintf(stderr, "%4u%%", ratio); + unsigned beg_and_transferred; /* does not need uoff_t, see scaling code */ + unsigned ratio; + + beg_and_transferred = beg_size + transferred; + ratio = 100 * beg_and_transferred / totalsize; + /* can't overflow ^^^^^^^^^^^^^^^ */ + fprintf(stderr, "%3u%% ", ratio); - barlength = get_terminal_width(2) - 49; - if (barlength > 0) { + barlength = get_terminal_width(2) - 48; + /* + * Must reject barlength <= 0 (terminal too narrow). While at it, + * also reject: 1-char bar (useless), 2-char bar (ridiculous). + */ + if (barlength > 2) { if (barlength > 999) barlength = 999; { @@ -147,18 +151,12 @@ void FAST_FUNC bb_progress_update(bb_progress_t *p, memset(buf, ' ', barlength); buf[barlength] = '\0'; memset(buf, '*', stars); - fprintf(stderr, " |%s|", buf); + fprintf(stderr, "|%s| ", buf); } } } - while (beg_and_transferred >= 100000) { - beg_and_transferred >>= 10; - kiloscale++; - } - /* see http://en.wikipedia.org/wiki/Tera */ - fprintf(stderr, "%6u%c", (unsigned)beg_and_transferred, " kMGTPEZY"[kiloscale]); -#define beg_and_transferred dont_use_beg_and_transferred_below() + fputs(numbuf5, stderr); /* "NNNNk" */ since_last_update = elapsed - p->last_change_sec; if ((unsigned)transferred != p->last_size) { -- cgit v1.2.3-55-g6feb From ba3b9dbf065438402d89655d7baefb0ccc6f0663 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Sun, 11 Feb 2018 14:55:46 +0100 Subject: libbb: introduce and use bb_getsockname() function old new delta bb_getsockname - 18 +18 xrtnl_open 88 83 -5 do_iplink 1216 1209 -7 arping_main 1686 1668 -18 ------------------------------------------------------------------------------ (add/remove: 2/0 grow/shrink: 0/3 up/down: 18/-30) Total: -12 bytes Signed-off-by: Denys Vlasenko --- include/libbb.h | 1 + libbb/bb_getsockname.c | 19 +++++++++++++++++++ networking/arping.c | 15 +++++---------- networking/inetd.c | 5 ++--- networking/libiproute/iplink.c | 4 +--- networking/libiproute/libnetlink.c | 5 +---- 6 files changed, 29 insertions(+), 20 deletions(-) create mode 100644 libbb/bb_getsockname.c (limited to 'libbb') diff --git a/include/libbb.h b/include/libbb.h index e2bedaf41..2c34859a2 100644 --- a/include/libbb.h +++ b/include/libbb.h @@ -636,6 +636,7 @@ void setsockopt_reuseaddr(int fd) FAST_FUNC; /* On Linux this never fails. */ int setsockopt_keepalive(int fd) FAST_FUNC; int setsockopt_broadcast(int fd) FAST_FUNC; int setsockopt_bindtodevice(int fd, const char *iface) FAST_FUNC; +int bb_getsockname(int sockfd, void *addr, socklen_t addrlen) FAST_FUNC; /* NB: returns port in host byte order */ unsigned bb_lookup_port(const char *port, const char *protocol, unsigned default_port) FAST_FUNC; typedef struct len_and_sockaddr { diff --git a/libbb/bb_getsockname.c b/libbb/bb_getsockname.c new file mode 100644 index 000000000..1af9b39b9 --- /dev/null +++ b/libbb/bb_getsockname.c @@ -0,0 +1,19 @@ +/* vi: set sw=4 ts=4: */ +/* + * Utility routines. + * + * Licensed under GPLv2, see file LICENSE in this source tree. + */ +//kbuild:lib-y += bb_getsockname.o + +#include "libbb.h" + +int FAST_FUNC bb_getsockname(int sockfd, void *addr, socklen_t addrlen) +{ + /* The usefullness of this function is that for getsockname(), + * addrlen must go on stack (to _have_ an address to be passed), + * but many callers do not need its modified value. + * By using this shim, they can avoid unnecessary stack spillage. + */ + return getsockname(sockfd, (struct sockaddr *)addr, &addrlen); +} diff --git a/networking/arping.c b/networking/arping.c index a16f04b9f..59092a7d7 100644 --- a/networking/arping.c +++ b/networking/arping.c @@ -363,15 +363,13 @@ int arping_main(int argc UNUSED_PARAM, char **argv) xbind(probe_fd, (struct sockaddr *) &saddr, sizeof(saddr)); } else { /* !(option_mask32 & DAD) case */ /* Find IP address on this iface */ - socklen_t alen = sizeof(saddr); - saddr.sin_port = htons(1025); saddr.sin_addr = dst; if (setsockopt_SOL_SOCKET_1(probe_fd, SO_DONTROUTE) != 0) bb_perror_msg("setsockopt(%s)", "SO_DONTROUTE"); xconnect(probe_fd, (struct sockaddr *) &saddr, sizeof(saddr)); - getsockname(probe_fd, (struct sockaddr *) &saddr, &alen); + bb_getsockname(probe_fd, (struct sockaddr *) &saddr, sizeof(saddr)); //never happens: //if (getsockname(probe_fd, (struct sockaddr *) &saddr, &alen) == -1) // bb_perror_msg_and_die("getsockname"); @@ -387,13 +385,10 @@ int arping_main(int argc UNUSED_PARAM, char **argv) me.sll_protocol = htons(ETH_P_ARP); xbind(sock_fd, (struct sockaddr *) &me, sizeof(me)); - { - socklen_t alen = sizeof(me); - getsockname(sock_fd, (struct sockaddr *) &me, &alen); - //never happens: - //if (getsockname(sock_fd, (struct sockaddr *) &me, &alen) == -1) - // bb_perror_msg_and_die("getsockname"); - } + bb_getsockname(sock_fd, (struct sockaddr *) &me, sizeof(me)); + //never happens: + //if (getsockname(sock_fd, (struct sockaddr *) &me, &alen) == -1) + // bb_perror_msg_and_die("getsockname"); if (me.sll_halen == 0) { bb_error_msg(err_str, "is not ARPable (no ll address)"); BUILD_BUG_ON(DAD != 2); diff --git a/networking/inetd.c b/networking/inetd.c index 4dfa0089a..6843845fb 100644 --- a/networking/inetd.c +++ b/networking/inetd.c @@ -497,10 +497,9 @@ static void register_rpc(servtab_t *sep) { int n; struct sockaddr_in ir_sin; - socklen_t size; - size = sizeof(ir_sin); - if (getsockname(sep->se_fd, (struct sockaddr *) &ir_sin, &size) < 0) { + if (bb_getsockname(sep->se_fd, (struct sockaddr *) &ir_sin, sizeof(ir_sin)) < 0) { +//TODO: verify that such failure is even possible in Linux kernel bb_perror_msg("getsockname"); return; } diff --git a/networking/libiproute/iplink.c b/networking/libiproute/iplink.c index aef5f6490..f38fba055 100644 --- a/networking/libiproute/iplink.c +++ b/networking/libiproute/iplink.c @@ -132,7 +132,6 @@ static int get_address(char *dev, int *htype) { struct ifreq ifr; struct sockaddr_ll me; - socklen_t alen; int s; s = xsocket(PF_PACKET, SOCK_DGRAM, 0); @@ -146,8 +145,7 @@ static int get_address(char *dev, int *htype) me.sll_ifindex = ifr.ifr_ifindex; me.sll_protocol = htons(ETH_P_LOOP); xbind(s, (struct sockaddr*)&me, sizeof(me)); - alen = sizeof(me); - getsockname(s, (struct sockaddr*)&me, &alen); + bb_getsockname(s, (struct sockaddr*)&me, sizeof(me)); //never happens: //if (getsockname(s, (struct sockaddr*)&me, &alen) == -1) // bb_perror_msg_and_die("getsockname"); diff --git a/networking/libiproute/libnetlink.c b/networking/libiproute/libnetlink.c index f08d862d0..40955fcae 100644 --- a/networking/libiproute/libnetlink.c +++ b/networking/libiproute/libnetlink.c @@ -15,16 +15,13 @@ void FAST_FUNC xrtnl_open(struct rtnl_handle *rth/*, unsigned subscriptions*/) { - socklen_t addr_len; - memset(rth, 0, sizeof(*rth)); rth->fd = xsocket(AF_NETLINK, SOCK_RAW, NETLINK_ROUTE); rth->local.nl_family = AF_NETLINK; /*rth->local.nl_groups = subscriptions;*/ xbind(rth->fd, (struct sockaddr*)&rth->local, sizeof(rth->local)); - addr_len = sizeof(rth->local); - getsockname(rth->fd, (struct sockaddr*)&rth->local, &addr_len); + bb_getsockname(rth->fd, (struct sockaddr*)&rth->local, sizeof(rth->local)); /* too much paranoia if (getsockname(rth->fd, (struct sockaddr*)&rth->local, &addr_len) < 0) -- cgit v1.2.3-55-g6feb