From fa6ab56353e84057bf1b2f740bc1e1a99af686ce Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Tue, 21 Jan 2014 13:44:21 +0100 Subject: libbb: if opening /dev/loopN returns ENXIO, don't try N++. function old new delta set_loop 639 635 -4 Signed-off-by: Denys Vlasenko --- libbb/loop.c | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/libbb/loop.c b/libbb/loop.c index 823fba079..c96c5e070 100644 --- a/libbb/loop.c +++ b/libbb/loop.c @@ -94,19 +94,19 @@ int FAST_FUNC set_loop(char **device, const char *file, unsigned long long offse /* Open the file. Barf if this doesn't work. */ mode = ro ? O_RDONLY : O_RDWR; + open_ffd: ffd = open(file, mode); if (ffd < 0) { if (mode != O_RDONLY) { mode = O_RDONLY; - ffd = open(file, mode); + goto open_ffd; } - if (ffd < 0) - return -errno; + return -errno; } /* Find a loop device. */ try = *device ? *device : dev; - /* 1048575 is a max possible minor number in Linux circa 2010 */ + /* 1048575 (0xfffff) is a max possible minor number in Linux circa 2010 */ for (i = 0; rc && i < 1048576; i++) { sprintf(dev, LOOP_FORMAT, i); @@ -121,7 +121,7 @@ int FAST_FUNC set_loop(char **device, const char *file, unsigned long long offse goto try_to_open; } /* Ran out of block devices, return failure. */ - rc = -ENOENT; + rc = -1; break; } try_to_open: @@ -131,8 +131,14 @@ int FAST_FUNC set_loop(char **device, const char *file, unsigned long long offse mode = O_RDONLY; dfd = open(try, mode); } - if (dfd < 0) + if (dfd < 0) { + if (errno == ENXIO) { + /* Happens if loop module is not loaded */ + rc = -1; + break; + } goto try_again; + } rc = ioctl(dfd, BB_LOOP_GET_STATUS, &loopinfo); -- cgit v1.2.3-55-g6feb From 731f59617582d24ea5bd613e2a5448fd4027a3aa Mon Sep 17 00:00:00 2001 From: Eugene Rudoy Date: Wed, 22 Jan 2014 11:49:46 +0100 Subject: iplink: fix build with kernel versions prior to 2.6.23 Signed-off-by: Eugene Rudoy Signed-off-by: Denys Vlasenko --- networking/libiproute/iplink.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/networking/libiproute/iplink.c b/networking/libiproute/iplink.c index 286e59ebf..506fb3c7e 100644 --- a/networking/libiproute/iplink.c +++ b/networking/libiproute/iplink.c @@ -31,6 +31,16 @@ #ifndef IFLA_LINKINFO # define IFLA_LINKINFO 18 # define IFLA_INFO_KIND 1 +# define IFLA_INFO_DATA 2 +#endif + +#ifndef IFLA_VLAN_MAX +# define IFLA_VLAN_ID 1 +# define IFLA_VLAN_FLAGS 2 +struct ifla_vlan_flags { + uint32_t flags; + uint32_t mask; +}; #endif /* taken from linux/sockios.h */ -- cgit v1.2.3-55-g6feb From ff6506131152ee383685047c19bc420ed4de030e Mon Sep 17 00:00:00 2001 From: John Spencer Date: Wed, 22 Jan 2014 15:31:10 +0100 Subject: man: parse "DEFINE pager" in config function old new delta man_main 789 844 +55 Signed-off-by: John Spencer Signed-off-by: Denys Vlasenko --- miscutils/man.c | 22 +++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/miscutils/man.c b/miscutils/man.c index d3e832bd7..51baceb16 100644 --- a/miscutils/man.c +++ b/miscutils/man.c @@ -150,7 +150,7 @@ int man_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; int man_main(int argc UNUSED_PARAM, char **argv) { parser_t *parser; - const char *pager; + const char *pager = ENABLE_LESS ? "less" : "more"; char **man_path_list; char *sec_list; char *cur_path, *cur_sect; @@ -171,12 +171,6 @@ int man_main(int argc UNUSED_PARAM, char **argv) man_path_list[0] = (char*)"/usr/man"; else count_mp++; - pager = getenv("MANPAGER"); - if (!pager) { - pager = getenv("PAGER"); - if (!pager) - pager = "more"; - } /* Parse man.conf[ig] or man_db.conf */ /* man version 1.6f uses man.config */ @@ -190,6 +184,11 @@ int man_main(int argc UNUSED_PARAM, char **argv) while (config_read(parser, token, 2, 0, "# \t", PARSE_NORMAL)) { if (!token[1]) continue; + if (strcmp("DEFINE", token[0]) == 0) { + if (strncmp("pager", token[1], 5) == 0) { + pager = xstrdup(skip_whitespace(token[1]) + 5); + } + } else if (strcmp("MANDATORY_MANPATH"+10, token[0]) == 0 /* "MANPATH"? */ || strcmp("MANDATORY_MANPATH", token[0]) == 0 ) { @@ -230,6 +229,15 @@ int man_main(int argc UNUSED_PARAM, char **argv) } config_close(parser); + { + /* environment overrides setting from man.config */ + char *env_pager = getenv("MANPAGER"); + if (!env_pager) + env_pager = getenv("PAGER"); + if (env_pager) + pager = env_pager; + } + not_found = 0; do { /* for each argv[] */ int found = 0; -- cgit v1.2.3-55-g6feb From 821e64316a93d2760ad60c326e1a59aabc3e6441 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Wed, 22 Jan 2014 16:36:22 +0100 Subject: less: accept and ignore -s Signed-off-by: Denys Vlasenko --- miscutils/less.c | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/miscutils/less.c b/miscutils/less.c index 60105f42b..574f222e0 100644 --- a/miscutils/less.c +++ b/miscutils/less.c @@ -98,16 +98,18 @@ //config: Enables "-N" command. //usage:#define less_trivial_usage -//usage: "[-E" IF_FEATURE_LESS_FLAGS("Mm") "Nh~I?] [FILE]..." +//usage: "[-E" IF_FEATURE_LESS_REGEXP("I")IF_FEATURE_LESS_FLAGS("Mm") "Nh~] [FILE]..." //usage:#define less_full_usage "\n\n" //usage: "View FILE (or stdin) one screenful at a time\n" //usage: "\n -E Quit once the end of a file is reached" +//usage: IF_FEATURE_LESS_REGEXP( +//usage: "\n -I Ignore case in all searches" +//usage: ) //usage: IF_FEATURE_LESS_FLAGS( //usage: "\n -M,-m Display status line with line numbers" //usage: "\n and percentage through the file" //usage: ) //usage: "\n -N Prefix line number to each line" -//usage: "\n -I Ignore case in all searches" //usage: "\n -~ Suppress ~s displayed past EOF" #include /* sched_yield() */ @@ -1613,10 +1615,13 @@ int less_main(int argc, char **argv) INIT_G(); - /* TODO: -x: do not interpret backspace, -xx: tab also */ - /* -xxx: newline also */ - /* -w N: assume width N (-xxx -w 32: hex viewer of sorts) */ - getopt32(argv, "EMmN~I" IF_FEATURE_LESS_DASHCMD("S")); + /* TODO: -x: do not interpret backspace, -xx: tab also + * -xxx: newline also + * -w N: assume width N (-xxx -w 32: hex viewer of sorts) + * -s: condense many empty lines to one + * (used by some setups for manpage display) + */ + getopt32(argv, "EMmN~I" IF_FEATURE_LESS_DASHCMD("S") /*ignored:*/"s"); argc -= optind; argv += optind; num_files = argc; -- cgit v1.2.3-55-g6feb From bf2f2229bb108a7bdd39326eb4e886e2f47df960 Mon Sep 17 00:00:00 2001 From: Michael Tokarev Date: Thu, 23 Jan 2014 14:41:53 +0100 Subject: testsuite: fix last "which" change In commit afa63b2dcdc9b9 I replaced `type -p' with `command -pv'. But actually it is wrong, the right substitution is `command -v'. We need to find our busybox which is in the first directory in $PATH, so `command -p' should not be used because it uses default PATH, not current value of PATH where our busybox binary resides. Signed-off-by: Michael Tokarev Signed-off-by: Denys Vlasenko --- testsuite/which/which-uses-default-path | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/testsuite/which/which-uses-default-path b/testsuite/which/which-uses-default-path index 349583dcc..92b6018c9 100644 --- a/testsuite/which/which-uses-default-path +++ b/testsuite/which/which-uses-default-path @@ -1,4 +1,4 @@ -BUSYBOX=$(command -pv busybox) +BUSYBOX=$(command -v busybox) SAVED_PATH=$PATH unset PATH $BUSYBOX which ls -- cgit v1.2.3-55-g6feb From b664f740d90880560ce46b11f766625341342e80 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Mon, 27 Jan 2014 13:02:18 +0100 Subject: libbb: open_zipped() should not fail on non-compressed files Signed-off-by: Denys Vlasenko --- archival/libarchive/open_transformer.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/archival/libarchive/open_transformer.c b/archival/libarchive/open_transformer.c index 1aeba13bc..27854af21 100644 --- a/archival/libarchive/open_transformer.c +++ b/archival/libarchive/open_transformer.c @@ -200,7 +200,16 @@ int FAST_FUNC open_zipped(const char *fname) || (ENABLE_FEATURE_SEAMLESS_BZ2) || (ENABLE_FEATURE_SEAMLESS_XZ) ) { - setup_unzip_on_fd(fd, /*fail_if_not_detected:*/ 1); + /* + * Do we want to fail_if_not_detected? + * In most cases, no: think "insmod non_compressed_module". + * A case which would like to fail is "zcat uncompressed_file": + * otherwise, it happily outputs uncompressed_file as-is, + * which is, strictly speaking, not what is expected. + * If this ever becomes a problem, we can add + * fail_if_not_detected bool argument to open_zipped(). + */ + setup_unzip_on_fd(fd, /*fail_if_not_detected:*/ 0); } return fd; -- cgit v1.2.3-55-g6feb From 922fdf65273f3047c1f60edee6af555cea1dd499 Mon Sep 17 00:00:00 2001 From: Michael Tokarev Date: Wed, 29 Jan 2014 12:40:32 +0400 Subject: init: do not fail build if SIGPWR is not defined Apparently, some *BSD variants (and maybe some other OSes) does not define SIGPWR signal. So since commit 760fc6debcba8c, busybox fails to build on such platforms. Fix this. Signed-off-by: Michael Tokarev Signed-off-by: Denys Vlasenko --- init/init.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/init/init.c b/init/init.c index d29328c36..de438be20 100644 --- a/init/init.c +++ b/init/init.c @@ -1135,7 +1135,9 @@ int init_main(int argc UNUSED_PARAM, char **argv) struct sigaction sa; bb_signals(0 +#ifdef SIGPWR + (1 << SIGPWR) /* halt */ +#endif + (1 << SIGUSR1) /* halt */ + (1 << SIGTERM) /* reboot */ + (1 << SIGUSR2) /* poweroff */ -- cgit v1.2.3-55-g6feb From 29ed580668865d68ab8c1020bf3a79e2f2ceaa55 Mon Sep 17 00:00:00 2001 From: Mike Frysinger Date: Fri, 31 Jan 2014 00:28:42 -0500 Subject: uname: fix up usage documentation The -i/-o options were missing, and the -r/-s/-v options were incorrectly labeled as "OS" instead of "kernel". Signed-off-by: Mike Frysinger --- coreutils/uname.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/coreutils/uname.c b/coreutils/uname.c index b96d76b6c..1c6aa5f79 100644 --- a/coreutils/uname.c +++ b/coreutils/uname.c @@ -49,16 +49,18 @@ */ //usage:#define uname_trivial_usage -//usage: "[-amnrspv]" +//usage: "[-amnrspvio]" //usage:#define uname_full_usage "\n\n" //usage: "Print system information\n" //usage: "\n -a Print all" //usage: "\n -m The machine (hardware) type" //usage: "\n -n Hostname" -//usage: "\n -r OS release" -//usage: "\n -s OS name (default)" +//usage: "\n -r Kernel release" +//usage: "\n -s Kernel name (default)" //usage: "\n -p Processor type" -//usage: "\n -v OS version" +//usage: "\n -v Kernel version" +//usage: "\n -i The hardware platform" +//usage: "\n -o OS name" //usage: //usage:#define uname_example_usage //usage: "$ uname -a\n" -- cgit v1.2.3-55-g6feb From f1999b5a9d2788cdc120b1ee2ab1de18e95b38f2 Mon Sep 17 00:00:00 2001 From: Mike Frysinger Date: Fri, 31 Jan 2014 00:29:47 -0500 Subject: appletlib: fix set-but-unused warning When you build with FEATURE_INSTALLER disabled, you get a build warning like so: libbb/appletlib.c: In function 'busybox_main': libbb/appletlib.c:691:7: warning: variable 'use_symbolic_links' set but not used [-Wunused-but-set-variable] int use_symbolic_links; ^ Signed-off-by: Mike Frysinger --- libbb/appletlib.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/libbb/appletlib.c b/libbb/appletlib.c index 8f3a8a10b..f7c416ece 100644 --- a/libbb/appletlib.c +++ b/libbb/appletlib.c @@ -606,7 +606,11 @@ static void install_links(const char *busybox, int use_symbolic_links, } } # else -# define install_links(x,y,z) ((void)0) +static void install_links(const char *busybox UNUSED_PARAM, + int use_symbolic_links UNUSED_PARAM, + char *custom_install_dir UNUSED_PARAM) +{ +} # endif /* If we were called as "busybox..." */ -- cgit v1.2.3-55-g6feb From 640ce3de07807133796bccd0bdfa146bbfc788c7 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Sun, 2 Feb 2014 02:06:38 +0100 Subject: zcat: complain if input is not compressed function old new delta buffer_fill_and_print 178 191 +13 varvalue 735 743 +8 bbunpack 747 755 +8 open_zipped 85 89 +4 xmalloc_open_zipped_read_close 61 63 +2 get_addr_1 240 242 +2 fbsplash_main 1228 1230 +2 pstree_main 322 321 -1 builtin_type 121 119 -2 do_load 954 926 -28 ------------------------------------------------------------------------------ (add/remove: 0/0 grow/shrink: 7/3 up/down: 39/-31) Total: 8 bytes Signed-off-by: Denys Vlasenko --- archival/bbunzip.c | 5 +++-- archival/libarchive/get_header_tar.c | 2 +- archival/libarchive/open_transformer.c | 19 +++++-------------- archival/rpm.c | 2 +- archival/rpm2cpio.c | 2 +- archival/tar.c | 2 +- include/libbb.h | 6 +++--- miscutils/fbsplash.c | 2 +- miscutils/man.c | 2 +- 9 files changed, 17 insertions(+), 25 deletions(-) diff --git a/archival/bbunzip.c b/archival/bbunzip.c index b3fb90f31..fce5ab9e1 100644 --- a/archival/bbunzip.c +++ b/archival/bbunzip.c @@ -72,7 +72,8 @@ int FAST_FUNC bbunpack(char **argv, goto err; } else { /* "clever zcat" with FILE */ - int fd = open_zipped(filename); + /* fail_if_not_compressed because zcat refuses uncompressed input */ + int fd = open_zipped(filename, /*fail_if_not_compressed:*/ 1); if (fd < 0) goto err_name; xmove_fd(fd, STDIN_FILENO); @@ -80,7 +81,7 @@ int FAST_FUNC bbunpack(char **argv, } else if (option_mask32 & SEAMLESS_MAGIC) { /* "clever zcat" on stdin */ - if (setup_unzip_on_fd(STDIN_FILENO, /*fail_if_not_detected*/ 0)) + if (setup_unzip_on_fd(STDIN_FILENO, /*fail_if_not_compressed*/ 1)) goto err; } diff --git a/archival/libarchive/get_header_tar.c b/archival/libarchive/get_header_tar.c index 54d910431..ba43bb073 100644 --- a/archival/libarchive/get_header_tar.c +++ b/archival/libarchive/get_header_tar.c @@ -243,7 +243,7 @@ char FAST_FUNC get_header_tar(archive_handle_t *archive_handle) * or not first block (false positive, it's not .gz/.bz2!) */ if (lseek(archive_handle->src_fd, -i, SEEK_CUR) != 0) goto err; - if (setup_unzip_on_fd(archive_handle->src_fd, /*fail_if_not_detected:*/ 0) != 0) + if (setup_unzip_on_fd(archive_handle->src_fd, /*fail_if_not_compressed:*/ 0) != 0) err: bb_error_msg_and_die("invalid tar magic"); archive_handle->offset = 0; diff --git a/archival/libarchive/open_transformer.c b/archival/libarchive/open_transformer.c index 27854af21..198663041 100644 --- a/archival/libarchive/open_transformer.c +++ b/archival/libarchive/open_transformer.c @@ -118,7 +118,7 @@ void FAST_FUNC open_transformer(int fd, const char *transform_prog) /* Used by e.g. rpm which gives us a fd without filename, * thus we can't guess the format from filename's extension. */ -int FAST_FUNC setup_unzip_on_fd(int fd, int fail_if_not_detected) +int FAST_FUNC setup_unzip_on_fd(int fd, int fail_if_not_compressed) { union { uint8_t b[4]; @@ -159,7 +159,7 @@ int FAST_FUNC setup_unzip_on_fd(int fd, int fail_if_not_detected) } /* No known magic seen */ - if (fail_if_not_detected) + if (fail_if_not_compressed) bb_error_msg_and_die("no gzip" IF_FEATURE_SEAMLESS_BZ2("/bzip2") IF_FEATURE_SEAMLESS_XZ("/xz") @@ -180,7 +180,7 @@ int FAST_FUNC setup_unzip_on_fd(int fd, int fail_if_not_detected) return 0; } -int FAST_FUNC open_zipped(const char *fname) +int FAST_FUNC open_zipped(const char *fname, int fail_if_not_compressed) { int fd; @@ -200,16 +200,7 @@ int FAST_FUNC open_zipped(const char *fname) || (ENABLE_FEATURE_SEAMLESS_BZ2) || (ENABLE_FEATURE_SEAMLESS_XZ) ) { - /* - * Do we want to fail_if_not_detected? - * In most cases, no: think "insmod non_compressed_module". - * A case which would like to fail is "zcat uncompressed_file": - * otherwise, it happily outputs uncompressed_file as-is, - * which is, strictly speaking, not what is expected. - * If this ever becomes a problem, we can add - * fail_if_not_detected bool argument to open_zipped(). - */ - setup_unzip_on_fd(fd, /*fail_if_not_detected:*/ 0); + setup_unzip_on_fd(fd, fail_if_not_compressed); } return fd; @@ -222,7 +213,7 @@ void* FAST_FUNC xmalloc_open_zipped_read_close(const char *fname, size_t *maxsz_ int fd; char *image; - fd = open_zipped(fname); + fd = open_zipped(fname, /*fail_if_not_compressed:*/ 0); if (fd < 0) return NULL; diff --git a/archival/rpm.c b/archival/rpm.c index 885eddd64..105394481 100644 --- a/archival/rpm.c +++ b/archival/rpm.c @@ -122,7 +122,7 @@ static void extract_cpio(int fd, const char *source_rpm) archive_handle->src_fd = fd; /*archive_handle->offset = 0; - init_handle() did it */ - setup_unzip_on_fd(archive_handle->src_fd, /*fail_if_not_detected:*/ 1); + setup_unzip_on_fd(archive_handle->src_fd, /*fail_if_not_compressed:*/ 1); while (get_header_cpio(archive_handle) == EXIT_SUCCESS) continue; } diff --git a/archival/rpm2cpio.c b/archival/rpm2cpio.c index 61adde795..7057570f5 100644 --- a/archival/rpm2cpio.c +++ b/archival/rpm2cpio.c @@ -80,7 +80,7 @@ int rpm2cpio_main(int argc UNUSED_PARAM, char **argv) // signal(SIGCHLD, check_errors_in_children); /* This works, but doesn't report uncompress errors (they happen in child) */ - setup_unzip_on_fd(rpm_fd, /*fail_if_not_detected:*/ 1); + setup_unzip_on_fd(rpm_fd, /*fail_if_not_compressed:*/ 1); if (bb_copyfd_eof(rpm_fd, STDOUT_FILENO) < 0) bb_error_msg_and_die("error unpacking"); diff --git a/archival/tar.c b/archival/tar.c index bd61abd57..aa02d3512 100644 --- a/archival/tar.c +++ b/archival/tar.c @@ -1137,7 +1137,7 @@ int tar_main(int argc UNUSED_PARAM, char **argv) && flags == O_RDONLY && !(opt & OPT_ANY_COMPRESS) ) { - tar_handle->src_fd = open_zipped(tar_filename); + tar_handle->src_fd = open_zipped(tar_filename, /*fail_if_not_compressed:*/ 0); if (tar_handle->src_fd < 0) bb_perror_msg_and_die("can't open '%s'", tar_filename); } else { diff --git a/include/libbb.h b/include/libbb.h index 64167bba3..96f33340e 100644 --- a/include/libbb.h +++ b/include/libbb.h @@ -736,12 +736,12 @@ extern void *xmalloc_xopen_read_close(const char *filename, size_t *maxsz_p) FAS #if SEAMLESS_COMPRESSION /* Autodetects gzip/bzip2 formats. fd may be in the middle of the file! */ -extern int setup_unzip_on_fd(int fd, int fail_if_not_detected) FAST_FUNC; +extern int setup_unzip_on_fd(int fd, int fail_if_not_compressed) FAST_FUNC; /* Autodetects .gz etc */ -extern int open_zipped(const char *fname) FAST_FUNC; +extern int open_zipped(const char *fname, int fail_if_not_compressed) FAST_FUNC; #else # define setup_unzip_on_fd(...) (0) -# define open_zipped(fname) open((fname), O_RDONLY); +# define open_zipped(fname, fail_if_not_compressed) open((fname), O_RDONLY); #endif extern void *xmalloc_open_zipped_read_close(const char *fname, size_t *maxsz_p) FAST_FUNC RETURNS_MALLOC; diff --git a/miscutils/fbsplash.c b/miscutils/fbsplash.c index 12a77b70f..7b695b26f 100644 --- a/miscutils/fbsplash.c +++ b/miscutils/fbsplash.c @@ -353,7 +353,7 @@ static void fb_drawimage(void) if (LONE_DASH(G.image_filename)) { theme_file = stdin; } else { - int fd = open_zipped(G.image_filename); + int fd = open_zipped(G.image_filename, /*fail_if_not_compressed:*/ 0); if (fd < 0) bb_simple_perror_msg_and_die(G.image_filename); theme_file = xfdopen_for_read(fd); diff --git a/miscutils/man.c b/miscutils/man.c index 51baceb16..f046e24f3 100644 --- a/miscutils/man.c +++ b/miscutils/man.c @@ -102,7 +102,7 @@ static int run_pipe(const char *pager, char *man_filename, int man, int level) ordinary_manpage: close(STDIN_FILENO); - open_zipped(man_filename); /* guaranteed to use fd 0 (STDIN_FILENO) */ + open_zipped(man_filename, /*fail_if_not_compressed:*/ 0); /* guaranteed to use fd 0 (STDIN_FILENO) */ /* "2>&1" is added so that nroff errors are shown in pager too. * Otherwise it may show just empty screen */ cmd = xasprintf( -- cgit v1.2.3-55-g6feb From 69a12fa7906d2dcdb5d8e124643a4e0f7865417a Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Mon, 3 Feb 2014 03:27:53 +0100 Subject: catv: suppress compiler warning The warning was: warning: typedef 'BUG_const_mismatch' locally defined but not used [-Wunused-local-typedefs] Signed-off-by: Denys Vlasenko --- coreutils/catv.c | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/coreutils/catv.c b/coreutils/catv.c index e3499c597..6bb73ba63 100644 --- a/coreutils/catv.c +++ b/coreutils/catv.c @@ -20,20 +20,22 @@ #include "libbb.h" -int catv_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; -int catv_main(int argc UNUSED_PARAM, char **argv) -{ - int retval = EXIT_SUCCESS; - int fd; - unsigned opts; #define CATV_OPT_e (1<<0) #define CATV_OPT_t (1<<1) #define CATV_OPT_v (1<<2) - typedef char BUG_const_mismatch[ +struct BUG_const_mismatch { + char BUG_const_mismatch[ CATV_OPT_e == VISIBLE_ENDLINE && CATV_OPT_t == VISIBLE_SHOW_TABS ? 1 : -1 ]; +}; +int catv_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; +int catv_main(int argc UNUSED_PARAM, char **argv) +{ + int retval = EXIT_SUCCESS; + int fd; + unsigned opts; opts = getopt32(argv, "etv"); argv += optind; #if 0 /* These consts match, we can just pass "opts" to visible() */ -- cgit v1.2.3-55-g6feb From d353bfff467517608af7468198431d32406bb943 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Mon, 3 Feb 2014 14:09:42 +0100 Subject: wget: fix use-after-free of ->user. Closes 6836 function old new delta wget_main 2207 2223 +16 parse_url 339 353 +14 Signed-off-by: Denys Vlasenko --- networking/wget.c | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/networking/wget.c b/networking/wget.c index d6c509edc..7ca947aec 100644 --- a/networking/wget.c +++ b/networking/wget.c @@ -46,7 +46,7 @@ struct host_info { char *allocated; const char *path; - const char *user; + char *user; char *host; int port; smallint is_ftp; @@ -322,9 +322,6 @@ static void parse_url(const char *src_url, struct host_info *h) h->path = sp; } - // We used to set h->user to NULL here, but this interferes - // with handling of code 302 ("object was moved") - sp = strrchr(h->host, '@'); if (sp != NULL) { // URL-decode "user:password" string before base64-encoding: @@ -333,11 +330,13 @@ static void parse_url(const char *src_url, struct host_info *h) // which decodes to "test:my pass". // Standard wget and curl do this too. *sp = '\0'; - h->user = percent_decode_in_place(h->host, /*strict:*/ 0); + free(h->user); + h->user = xstrdup(percent_decode_in_place(h->host, /*strict:*/ 0)); h->host = sp + 1; } - - sp = h->host; + /* else: h->user remains NULL, or as set by original request + * before redirect (if we are here after a redirect). + */ } static char *gethdr(FILE *fp) @@ -880,6 +879,7 @@ However, in real world it was observed that some web servers } else { parse_url(str, &target); if (!use_proxy) { + /* server.user remains untouched */ free(server.allocated); server.allocated = NULL; server.host = target.host; @@ -929,6 +929,8 @@ However, in real world it was observed that some web servers free(server.allocated); free(target.allocated); + free(server.user); + free(target.user); free(fname_out_alloc); free(redirected_path); } -- cgit v1.2.3-55-g6feb From fe8390e0fe7106aed9f586b3cf08215effc4450b Mon Sep 17 00:00:00 2001 From: Kaarle Ritvanen Date: Mon, 3 Feb 2014 15:56:20 +0100 Subject: ifupdown: support 'link' address family Does not configure anything. L2 configuration hook scripts should do their job on receiving ADDRFAM=link. Configuration will be done only once, irrespective of L3 protocols used. Using the 'link' family in the interfaces file conforms to the Debian implementation: http://sources.debian.net/src/ifupdown/0.7.47.1/link.defn function old new delta link_methods - 12 +12 addr_link - 12 +12 link_up_down - 6 +6 static.addr_fams 12 16 +4 ------------------------------------------------------------------------------ (add/remove: 3/0 grow/shrink: 1/0 up/down: 34/0) Total: 34 bytes Signed-off-by: Kaarle Ritvanen Signed-off-by: Denys Vlasenko --- networking/ifupdown.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/networking/ifupdown.c b/networking/ifupdown.c index 0f0857cb4..e1ea351a4 100644 --- a/networking/ifupdown.c +++ b/networking/ifupdown.c @@ -685,6 +685,18 @@ static const struct address_family_t addr_inet = { #endif /* FEATURE_IFUPDOWN_IPV4 */ +static int FAST_FUNC link_up_down(struct interface_defn_t *ifd UNUSED_PARAM, execfn *exec UNUSED_PARAM) +{ + return 1; +} + +static const struct method_t link_methods[] = { + { "none", link_up_down, link_up_down } +}; + +static const struct address_family_t addr_link = { + "link", ARRAY_SIZE(link_methods), link_methods +}; /* Returns pointer to the next word, or NULL. * In 1st case, advances *buf to the word after this one. @@ -831,6 +843,7 @@ static struct interfaces_file_t *read_interfaces(const char *filename, struct in #if ENABLE_FEATURE_IFUPDOWN_IPV6 &addr_inet6, #endif + &addr_link, NULL }; char *iface_name; -- cgit v1.2.3-55-g6feb From e4785ca653d0e219926692c229673b2c1b8d6ac4 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Mon, 3 Feb 2014 18:03:42 +0100 Subject: udhcpc: don't use BPF filter, users report problems (bugs 4598, 6746) Signed-off-by: Denys Vlasenko --- networking/udhcp/dhcpc.c | 93 ++++++++++++++++++++++++------------------------ 1 file changed, 46 insertions(+), 47 deletions(-) diff --git a/networking/udhcp/dhcpc.c b/networking/udhcp/dhcpc.c index 8dee916d9..ee19f5578 100644 --- a/networking/udhcp/dhcpc.c +++ b/networking/udhcp/dhcpc.c @@ -976,53 +976,6 @@ static int udhcp_raw_socket(int ifindex) int fd; struct sockaddr_ll sock; - /* - * Comment: - * - * I've selected not to see LL header, so BPF doesn't see it, too. - * The filter may also pass non-IP and non-ARP packets, but we do - * a more complete check when receiving the message in userspace. - * - * and filter shamelessly stolen from: - * - * http://www.flamewarmaster.de/software/dhcpclient/ - * - * There are a few other interesting ideas on that page (look under - * "Motivation"). Use of netlink events is most interesting. Think - * of various network servers listening for events and reconfiguring. - * That would obsolete sending HUP signals and/or make use of restarts. - * - * Copyright: 2006, 2007 Stefan Rompf . - * License: GPL v2. - * - * TODO: make conditional? - */ - static const struct sock_filter filter_instr[] = { - /* load 9th byte (protocol) */ - BPF_STMT(BPF_LD|BPF_B|BPF_ABS, 9), - /* jump to L1 if it is IPPROTO_UDP, else to L4 */ - BPF_JUMP(BPF_JMP|BPF_JEQ|BPF_K, IPPROTO_UDP, 0, 6), - /* L1: load halfword from offset 6 (flags and frag offset) */ - BPF_STMT(BPF_LD|BPF_H|BPF_ABS, 6), - /* jump to L4 if any bits in frag offset field are set, else to L2 */ - BPF_JUMP(BPF_JMP|BPF_JSET|BPF_K, 0x1fff, 4, 0), - /* L2: skip IP header (load index reg with header len) */ - BPF_STMT(BPF_LDX|BPF_B|BPF_MSH, 0), - /* load udp destination port from halfword[header_len + 2] */ - BPF_STMT(BPF_LD|BPF_H|BPF_IND, 2), - /* jump to L3 if udp dport is CLIENT_PORT, else to L4 */ - BPF_JUMP(BPF_JMP|BPF_JEQ|BPF_K, 68, 0, 1), - /* L3: accept packet */ - BPF_STMT(BPF_RET|BPF_K, 0xffffffff), - /* L4: discard packet */ - BPF_STMT(BPF_RET|BPF_K, 0), - }; - static const struct sock_fprog filter_prog = { - .len = sizeof(filter_instr) / sizeof(filter_instr[0]), - /* casting const away: */ - .filter = (struct sock_filter *) filter_instr, - }; - log1("Opening raw socket on ifindex %d", ifindex); //log2? fd = xsocket(PF_PACKET, SOCK_DGRAM, htons(ETH_P_IP)); @@ -1033,13 +986,59 @@ static int udhcp_raw_socket(int ifindex) sock.sll_ifindex = ifindex; xbind(fd, (struct sockaddr *) &sock, sizeof(sock)); +#if 0 /* Several users reported breakage when BPF filter is used */ if (CLIENT_PORT == 68) { /* Use only if standard port is in use */ + /* + * I've selected not to see LL header, so BPF doesn't see it, too. + * The filter may also pass non-IP and non-ARP packets, but we do + * a more complete check when receiving the message in userspace. + * + * and filter shamelessly stolen from: + * + * http://www.flamewarmaster.de/software/dhcpclient/ + * + * There are a few other interesting ideas on that page (look under + * "Motivation"). Use of netlink events is most interesting. Think + * of various network servers listening for events and reconfiguring. + * That would obsolete sending HUP signals and/or make use of restarts. + * + * Copyright: 2006, 2007 Stefan Rompf . + * License: GPL v2. + * + * TODO: make conditional? + */ + static const struct sock_filter filter_instr[] = { + /* load 9th byte (protocol) */ + BPF_STMT(BPF_LD|BPF_B|BPF_ABS, 9), + /* jump to L1 if it is IPPROTO_UDP, else to L4 */ + BPF_JUMP(BPF_JMP|BPF_JEQ|BPF_K, IPPROTO_UDP, 0, 6), + /* L1: load halfword from offset 6 (flags and frag offset) */ + BPF_STMT(BPF_LD|BPF_H|BPF_ABS, 6), + /* jump to L4 if any bits in frag offset field are set, else to L2 */ + BPF_JUMP(BPF_JMP|BPF_JSET|BPF_K, 0x1fff, 4, 0), + /* L2: skip IP header (load index reg with header len) */ + BPF_STMT(BPF_LDX|BPF_B|BPF_MSH, 0), + /* load udp destination port from halfword[header_len + 2] */ + BPF_STMT(BPF_LD|BPF_H|BPF_IND, 2), + /* jump to L3 if udp dport is CLIENT_PORT, else to L4 */ + BPF_JUMP(BPF_JMP|BPF_JEQ|BPF_K, 68, 0, 1), + /* L3: accept packet */ + BPF_STMT(BPF_RET|BPF_K, 0xffffffff), + /* L4: discard packet */ + BPF_STMT(BPF_RET|BPF_K, 0), + }; + static const struct sock_fprog filter_prog = { + .len = sizeof(filter_instr) / sizeof(filter_instr[0]), + /* casting const away: */ + .filter = (struct sock_filter *) filter_instr, + }; /* Ignoring error (kernel may lack support for this) */ if (setsockopt(fd, SOL_SOCKET, SO_ATTACH_FILTER, &filter_prog, sizeof(filter_prog)) >= 0) log1("Attached filter to raw socket fd"); // log? } +#endif if (setsockopt(fd, SOL_PACKET, PACKET_AUXDATA, &const_int_1, sizeof(int)) < 0 -- cgit v1.2.3-55-g6feb From 07f417b6ab92e0429f302ff6783bb9681b60120e Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Wed, 5 Feb 2014 15:01:39 +0100 Subject: sendmail: make -f optional, document its default value Signed-off-by: Denys Vlasenko --- mailutils/sendmail.c | 67 +++++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 56 insertions(+), 11 deletions(-) diff --git a/mailutils/sendmail.c b/mailutils/sendmail.c index b5aa1d17b..824109d99 100644 --- a/mailutils/sendmail.c +++ b/mailutils/sendmail.c @@ -15,7 +15,8 @@ //usage: "Read email from stdin and send it\n" //usage: "\nStandard options:" //usage: "\n -t Read additional recipients from message body" -//usage: "\n -f SENDER Sender (required)" +//usage: "\n -f SENDER For use in MAIL FROM:. Can be empty string" +//usage: "\n Default: -auUSER, or username of current UID" //usage: "\n -o OPTIONS Various options. -oi implied, others are ignored" //usage: "\n -i -oi synonym. implied and ignored" //usage: "\n" @@ -40,6 +41,52 @@ //usage: "\nUse makemime to create emails with attachments" //usage: ) +/* Currently we don't sanitize or escape user-supplied SENDER and RECIPIENT_EMAILs. + * We may need to do so. For one, '.' in usernames seems to require escaping! + * + * From http://cr.yp.to/smtp/address.html: + * + * SMTP offers three ways to encode a character inside an address: + * + * "safe": the character, if it is not <>()[].,;:@, backslash, + * double-quote, space, or an ASCII control character; + * "quoted": the character, if it is not \012, \015, backslash, + * or double-quote; or + * "slashed": backslash followed by the character. + * + * An encoded box part is either (1) a sequence of one or more slashed + * or safe characters or (2) a double quote, a sequence of zero or more + * slashed or quoted characters, and a double quote. It represents + * the concatenation of the characters encoded inside it. + * + * For example, the encoded box parts + * angels + * \a\n\g\e\l\s + * "\a\n\g\e\l\s" + * "angels" + * "ang\els" + * all represent the 6-byte string "angels", and the encoded box parts + * a\,comma + * \a\,\c\o\m\m\a + * "a,comma" + * all represent the 7-byte string "a,comma". + * + * An encoded address contains + * the byte <; + * optionally, a route followed by a colon; + * an encoded box part, the byte @, and a domain; and + * the byte >. + * + * It represents an Internet mail address, given by concatenating + * the string represented by the encoded box part, the byte @, + * and the domain. For example, the encoded addresses + * + * <\God@heaven.af.mil> + * <"God"@heaven.af.mil> + * <@gateway.af.mil,@uucp.local:"\G\o\d"@heaven.af.mil> + * all represent the Internet mail address "God@heaven.af.mil". + */ + #include "libbb.h" #include "mail.h" @@ -163,7 +210,7 @@ int sendmail_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; int sendmail_main(int argc UNUSED_PARAM, char **argv) { char *opt_connect = opt_connect; - char *opt_from; + char *opt_from = NULL; char *s; llist_t *list = NULL; char *host = sane_address(safe_gethostname()); @@ -199,8 +246,8 @@ int sendmail_main(int argc UNUSED_PARAM, char **argv) G.fp0 = xfdopen_for_read(3); // parse options - // -v is a counter, -f is required. -H and -S are mutually exclusive, -a is a list - opt_complementary = "vv:f:w+:H--S:S--H:a::"; + // -v is a counter, -H and -S are mutually exclusive, -a is a list + opt_complementary = "vv:w+:H--S:S--H:a::"; // N.B. since -H and -S are mutually exclusive they do not interfere in opt_connect // -a is for ssmtp (http://downloads.openwrt.org/people/nico/man/man8/ssmtp.8.html) compatibility, // it is still under development. @@ -304,13 +351,11 @@ int sendmail_main(int argc UNUSED_PARAM, char **argv) // Since reading from console may defeat usability, the solution is either to read from a predefined // file descriptor (e.g. 4), or again from a secured file. - // got no sender address? -> use system username as a resort - // N.B. we marked -f as required option! - //if (!G.user) { - // // N.B. IMHO getenv("USER") can be way easily spoofed! - // G.user = xuid2uname(getuid()); - // opt_from = xasprintf("%s@%s", G.user, domain); - //} + // got no sender address? use auth name, then UID username as a last resort + if (!opt_from) { + opt_from = G.user ? G.user : xuid2uname(getuid()); + } + smtp_checkp("MAIL FROM:<%s>", opt_from, 250); // process message -- cgit v1.2.3-55-g6feb From 3ba2df874ca27f075a0897210d8dce6c56646e60 Mon Sep 17 00:00:00 2001 From: Bartosz Golaszewski Date: Fri, 7 Feb 2014 17:14:37 +0100 Subject: grep: properly handle grep -w "^str" in !EXTRA_COMPAT case too function old new delta grep_file 1267 1288 +21 Signed-off-by: Bartosz Golaszewski Signed-off-by: Denys Vlasenko --- findutils/grep.c | 8 ++++++-- testsuite/grep.tests | 6 ++++++ 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/findutils/grep.c b/findutils/grep.c index a7bc4ca9e..76859464f 100644 --- a/findutils/grep.c +++ b/findutils/grep.c @@ -375,6 +375,8 @@ static int grep_file(FILE *file) } else { #if ENABLE_EXTRA_COMPAT unsigned start_pos; +#else + int match_flg; #endif char *match_at; @@ -392,6 +394,7 @@ static int grep_file(FILE *file) #if !ENABLE_EXTRA_COMPAT gl->matched_range.rm_so = 0; gl->matched_range.rm_eo = 0; + match_flg = 0; #else start_pos = 0; #endif @@ -400,7 +403,7 @@ static int grep_file(FILE *file) //bb_error_msg("'%s' start_pos:%d line_len:%d", match_at, start_pos, line_len); if ( #if !ENABLE_EXTRA_COMPAT - regexec(&gl->compiled_regex, match_at, 1, &gl->matched_range, 0) == 0 + regexec(&gl->compiled_regex, match_at, 1, &gl->matched_range, match_flg) == 0 #else re_search(&gl->compiled_regex, match_at, line_len, start_pos, /*range:*/ line_len, @@ -415,7 +418,7 @@ static int grep_file(FILE *file) found = 1; } else { char c = ' '; - if (gl->matched_range.rm_so) + if (match_at > line || gl->matched_range.rm_so != 0) c = match_at[gl->matched_range.rm_so - 1]; if (!isalnum(c) && c != '_') { c = match_at[gl->matched_range.rm_eo]; @@ -432,6 +435,7 @@ static int grep_file(FILE *file) #if !ENABLE_EXTRA_COMPAT if (gl->matched_range.rm_eo != 0) { match_at += gl->matched_range.rm_eo; + match_flg |= REG_NOTBOL; goto opt_w_again; } #else diff --git a/testsuite/grep.tests b/testsuite/grep.tests index 412efffbb..74b0eb63f 100755 --- a/testsuite/grep.tests +++ b/testsuite/grep.tests @@ -159,6 +159,12 @@ testing "grep -w ^ doesn't hang" \ "anything\n" \ "" +testing "grep -w word doesn't match wordword" \ + "grep -w word input" \ + "" \ + "wordword\n" \ + "" + # testing "test name" "commands" "expected result" "file input" "stdin" # file input will be file called "input" # test can create a file "actual" instead of writing to stdout -- cgit v1.2.3-55-g6feb From 744ee5db1c2d6c34c1988343728b2fc37a908f83 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Fri, 7 Feb 2014 17:38:52 +0100 Subject: udhcpc: in comments, explain the kind of raw socket we create Signed-off-by: Denys Vlasenko --- networking/udhcp/dhcpc.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/networking/udhcp/dhcpc.c b/networking/udhcp/dhcpc.c index ee19f5578..bdb1e2b9b 100644 --- a/networking/udhcp/dhcpc.c +++ b/networking/udhcp/dhcpc.c @@ -979,6 +979,10 @@ static int udhcp_raw_socket(int ifindex) log1("Opening raw socket on ifindex %d", ifindex); //log2? fd = xsocket(PF_PACKET, SOCK_DGRAM, htons(ETH_P_IP)); + /* ^^^^^ + * SOCK_DGRAM: remove link-layer headers on input (SOCK_RAW keeps them) + * ETH_P_IP: want to receive only packets with IPv4 eth type + */ log1("Got raw socket fd"); //log2? sock.sll_family = AF_PACKET; @@ -1005,8 +1009,6 @@ static int udhcp_raw_socket(int ifindex) * * Copyright: 2006, 2007 Stefan Rompf . * License: GPL v2. - * - * TODO: make conditional? */ static const struct sock_filter filter_instr[] = { /* load 9th byte (protocol) */ -- cgit v1.2.3-55-g6feb From 4e03d4134202b117a29ecf5933a7a55e2a8532a4 Mon Sep 17 00:00:00 2001 From: Kaarle Ritvanen Date: Sun, 9 Feb 2014 09:49:36 +0100 Subject: sendmail: use FQDN in default envelope sender RFC 5321 requires the return path to be supplied with a proper domain name. Signed-off-by: Kaarle Ritvanen Signed-off-by: Denys Vlasenko --- mailutils/sendmail.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/mailutils/sendmail.c b/mailutils/sendmail.c index 824109d99..9455b4e7a 100644 --- a/mailutils/sendmail.c +++ b/mailutils/sendmail.c @@ -326,7 +326,6 @@ int sendmail_main(int argc UNUSED_PARAM, char **argv) // we should start with modern EHLO if (250 != smtp_checkp("EHLO %s", host, -1)) smtp_checkp("HELO %s", host, 250); - free(host); // perform authentication if (opts & OPT_a) { @@ -353,8 +352,11 @@ int sendmail_main(int argc UNUSED_PARAM, char **argv) // got no sender address? use auth name, then UID username as a last resort if (!opt_from) { - opt_from = G.user ? G.user : xuid2uname(getuid()); + opt_from = xasprintf("%s@%s", + G.user ? G.user : xuid2uname(getuid()), + xgethostbyname(host)->h_name); } + free(host); smtp_checkp("MAIL FROM:<%s>", opt_from, 250); -- cgit v1.2.3-55-g6feb From 8ed96726603a59969b99e4ea30dbd9b06955084b Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Sun, 9 Feb 2014 14:38:03 +0100 Subject: libbb: don't die if crypt() returns NULL Signed-off-by: Denys Vlasenko --- libbb/pw_encrypt.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/libbb/pw_encrypt.c b/libbb/pw_encrypt.c index 39ffa084f..bfc7030a8 100644 --- a/libbb/pw_encrypt.c +++ b/libbb/pw_encrypt.c @@ -142,7 +142,14 @@ char* FAST_FUNC pw_encrypt(const char *clear, const char *salt, int cleanup) char* FAST_FUNC pw_encrypt(const char *clear, const char *salt, int cleanup) { - return xstrdup(crypt(clear, salt)); + char *s; + + s = crypt(clear, salt); + /* + * glibc used to return "" on malformed salts (for example, ""), + * but since 2.17 it returns NULL. + */ + return xstrdup(s ? s : ""); } #endif -- cgit v1.2.3-55-g6feb From 3e78f6f955ebdc010bb0b8f78622bf701e594b69 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Sun, 9 Feb 2014 15:35:04 +0100 Subject: htpd: trivial simplification in random interval selection function old new delta poll_interval 57 52 -5 Signed-off-by: Denys Vlasenko --- networking/ntpd.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/networking/ntpd.c b/networking/ntpd.c index 03fe448ca..bf8ef0a89 100644 --- a/networking/ntpd.c +++ b/networking/ntpd.c @@ -1660,13 +1660,14 @@ retry_interval(void) static unsigned poll_interval(int exponent) { - unsigned interval, r; + unsigned interval, r, mask; exponent = G.poll_exp + exponent; if (exponent < 0) exponent = 0; interval = 1 << exponent; + mask = ((interval-1) >> 4) | 1; r = random(); - interval += ((r & (interval-1)) >> 4) + ((r >> 8) & 1); /* + 1/16 of interval, max */ + interval += r & mask; /* ~ random(0..1) * interval/16 */ VERB4 bb_error_msg("chose poll interval:%u (poll_exp:%d exp:%d)", interval, G.poll_exp, exponent); return interval; } -- cgit v1.2.3-55-g6feb From 50e4cc29f56b5401579cddaf42d0404320b9efa7 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Mon, 10 Feb 2014 09:44:25 +0100 Subject: ifplugd: code shrink function old new delta ifplugd_main 1161 1144 -17 Signed-off-by: Denys Vlasenko --- networking/ifplugd.c | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/networking/ifplugd.c b/networking/ifplugd.c index b578f4c61..fef7a5ac9 100644 --- a/networking/ifplugd.c +++ b/networking/ifplugd.c @@ -289,8 +289,6 @@ static const struct { { "IFF_RUNNING" , &detect_link_iff }, }; - - static const char *strstatus(int status) { if (status == IFSTATUS_ERR) @@ -652,7 +650,6 @@ int ifplugd_main(int argc UNUSED_PARAM, char **argv) delay_time = 0; while (1) { int iface_status_old; - int iface_exists_old; switch (bb_got_signal) { case SIGINT: @@ -678,12 +675,12 @@ int ifplugd_main(int argc UNUSED_PARAM, char **argv) goto exiting; } - iface_status_old = iface_status; - iface_exists_old = G.iface_exists; - if ((opts & FLAG_MONITOR) && (netlink_pollfd[0].revents & POLLIN) ) { + int iface_exists_old; + + iface_exists_old = G.iface_exists; G.iface_exists = check_existence_through_netlink(); if (G.iface_exists < 0) /* error */ goto exiting; @@ -696,6 +693,7 @@ int ifplugd_main(int argc UNUSED_PARAM, char **argv) } /* note: if !G.iface_exists, returns DOWN */ + iface_status_old = iface_status; iface_status = detect_link(); if (iface_status == IFSTATUS_ERR) { if (!(opts & FLAG_MONITOR)) @@ -709,7 +707,7 @@ int ifplugd_main(int argc UNUSED_PARAM, char **argv) if (delay_time) { /* link restored its old status before - * we run script. don't run the script: */ + * we ran script. don't run the script: */ delay_time = 0; } else { delay_time = monotonic_sec(); @@ -717,15 +715,19 @@ int ifplugd_main(int argc UNUSED_PARAM, char **argv) delay_time += G.delay_up; if (iface_status == IFSTATUS_DOWN) delay_time += G.delay_down; - if (delay_time == 0) - delay_time++; +#if 0 /* if you are back in 1970... */ + if (delay_time == 0) { + sleep(1); + delay_time = 1; + } +#endif } } if (delay_time && (int)(monotonic_sec() - delay_time) >= 0) { - delay_time = 0; if (run_script(iface_status_str) != 0) goto exiting; + delay_time = 0; } } /* while (1) */ -- cgit v1.2.3-55-g6feb From ffc3a93d0dbf4ac887f528c0495cd586a092d88f Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Wed, 19 Feb 2014 14:17:11 +0100 Subject: udhcpc: fix BPF filter. Hopefully fixes the root cause of 4598 and 6746 Use a *signed* large positive value in BPF filter to indicate success. Signed-off-by: Denys Vlasenko --- networking/udhcp/d6_dhcpc.c | 2 +- networking/udhcp/dhcpc.c | 7 ++++--- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/networking/udhcp/d6_dhcpc.c b/networking/udhcp/d6_dhcpc.c index b0f0798e5..044f04673 100644 --- a/networking/udhcp/d6_dhcpc.c +++ b/networking/udhcp/d6_dhcpc.c @@ -711,7 +711,7 @@ static int d6_raw_socket(int ifindex) /* jump to L3 if udp dport is CLIENT_PORT6, else to L4 */ BPF_JUMP(BPF_JMP|BPF_JEQ|BPF_K, 68, 0, 1), /* L3: accept packet */ - BPF_STMT(BPF_RET|BPF_K, 0xffffffff), + BPF_STMT(BPF_RET|BPF_K, 0x7fffffff), /* L4: discard packet */ BPF_STMT(BPF_RET|BPF_K, 0), }; diff --git a/networking/udhcp/dhcpc.c b/networking/udhcp/dhcpc.c index bdb1e2b9b..25f18b35d 100644 --- a/networking/udhcp/dhcpc.c +++ b/networking/udhcp/dhcpc.c @@ -1025,9 +1025,10 @@ static int udhcp_raw_socket(int ifindex) BPF_STMT(BPF_LD|BPF_H|BPF_IND, 2), /* jump to L3 if udp dport is CLIENT_PORT, else to L4 */ BPF_JUMP(BPF_JMP|BPF_JEQ|BPF_K, 68, 0, 1), - /* L3: accept packet */ - BPF_STMT(BPF_RET|BPF_K, 0xffffffff), - /* L4: discard packet */ + /* L3: accept packet ("accept 0x7fffffff bytes") */ + /* Accepting 0xffffffff works too but kernel 2.6.19 is buggy */ + BPF_STMT(BPF_RET|BPF_K, 0x7fffffff), + /* L4: discard packet ("accept zero bytes") */ BPF_STMT(BPF_RET|BPF_K, 0), }; static const struct sock_fprog filter_prog = { -- cgit v1.2.3-55-g6feb From 265a74b9834cfe8a9d25ce1cf4d4db509f9a44f2 Mon Sep 17 00:00:00 2001 From: Bartosz Golaszewski Date: Tue, 11 Feb 2014 21:31:42 +0100 Subject: Kbuild: move CONFIG_PAM to general configuration Currently CONFIG_PAM depends on CONFIG_LOGIN, but is used by the httpd applet too. This patch moves said option to general configuration, thus allowing to compile httpd with PAM support independently from login. Signed-off-by: Bartosz Golaszewski Signed-off-by: Denys Vlasenko --- Config.in | 7 +++++++ loginutils/Config.src | 7 ------- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/Config.in b/Config.in index 2c4be2e9f..38d4ebc26 100644 --- a/Config.in +++ b/Config.in @@ -257,6 +257,13 @@ config UNICODE_PRESERVE_BROKEN at shell prompt will list file named 0xff (single char name with char value 255), not file named '?'. +config PAM + bool "Support for PAM (Pluggable Authentication Modules)" + default n + help + Use PAM in some busybox applets (currently login and httpd) instead + of direct access to password database. + config LONG_OPTS bool "Support for --long-options" default y diff --git a/loginutils/Config.src b/loginutils/Config.src index b78d7c38e..fa2b4f8c0 100644 --- a/loginutils/Config.src +++ b/loginutils/Config.src @@ -223,13 +223,6 @@ config LOGIN_SESSION_AS_CHILD almost always would want this to be set to Y, else PAM session will not be cleaned up. -config PAM - bool "Support for PAM (Pluggable Authentication Modules)" - default n - depends on LOGIN - help - Use PAM in login(1) instead of direct access to password database. - config LOGIN_SCRIPTS bool "Support for login scripts" depends on LOGIN -- cgit v1.2.3-55-g6feb From 192c14bd87aa2ea930bc4a3954a07c1cab46a3cc Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Fri, 21 Feb 2014 12:55:43 +0100 Subject: Improve examples/var_service READMEs Signed-off-by: Denys Vlasenko --- examples/var_service/README | 13 +++++++++++-- examples/var_service/dhcp_if/README | 5 +++++ examples/var_service/dhcp_if_pinger/README | 5 +++++ examples/var_service/ftpd/README | 5 +++++ examples/var_service/fw/README | 5 +++++ examples/var_service/getty_tty1/README | 5 +++++ examples/var_service/gpm/README | 5 +++++ examples/var_service/httpd/README | 5 +++++ examples/var_service/ifplugd_if/README | 5 +++++ examples/var_service/inetd/README | 5 +++++ examples/var_service/nmeter/README | 5 +++++ examples/var_service/ntpd/README | 5 +++++ examples/var_service/tftpd/README | 5 +++++ 13 files changed, 71 insertions(+), 2 deletions(-) create mode 100644 examples/var_service/dhcp_if/README create mode 100644 examples/var_service/dhcp_if_pinger/README create mode 100644 examples/var_service/ftpd/README create mode 100644 examples/var_service/fw/README create mode 100644 examples/var_service/getty_tty1/README create mode 100644 examples/var_service/gpm/README create mode 100644 examples/var_service/httpd/README create mode 100644 examples/var_service/ifplugd_if/README create mode 100644 examples/var_service/inetd/README create mode 100644 examples/var_service/nmeter/README create mode 100644 examples/var_service/ntpd/README create mode 100644 examples/var_service/tftpd/README diff --git a/examples/var_service/README b/examples/var_service/README index 06817c8bc..9ad1b2581 100644 --- a/examples/var_service/README +++ b/examples/var_service/README @@ -9,6 +9,15 @@ env - PATH=... runsvdir /var/service & from one of system startup scripts. (Google "man runsvdir" and "man runsv" for more info about these tools). +You can try or debug an individual service by running its SERVICE_DIR/run script. +In this case, its stdout and stderr go to your terminal. + +You can also run "runsv SERVICE_DIR", which runs both the service +and its logger service (SERVICE_DIR/log/run) if logger service exists. +If logger service exists, the output will go to it instead of the terminal. + +"runsvdir DIR" merely runs "runsv SERVICE_DIR" for every subdirectory in DIR. + Some existing examples: var_service/dhcp_if - @@ -47,8 +56,8 @@ This even works while fw service runs: if dhcp signals fw to (re)start while fw runs, fw will not stop after its execution, but will re-execute once, picking up dhcp's new configuration. This is achieved very simply by having -# Make ourself one-shot -sv o . + # Make ourself one-shot + sv o . at the very beginning of fw/run script, not at the end. Therefore, any "sv u /var/run/service/fw" command by any other script "undoes" o(ne-shot) command if fw still runs, thus diff --git a/examples/var_service/dhcp_if/README b/examples/var_service/dhcp_if/README new file mode 100644 index 000000000..4ddccb22d --- /dev/null +++ b/examples/var_service/dhcp_if/README @@ -0,0 +1,5 @@ +The real README file is one directory up. + +This directory's run script can have useful comments. +If it doesn't but you feel it should, please send a patch +to busybox's mailing list. diff --git a/examples/var_service/dhcp_if_pinger/README b/examples/var_service/dhcp_if_pinger/README new file mode 100644 index 000000000..4ddccb22d --- /dev/null +++ b/examples/var_service/dhcp_if_pinger/README @@ -0,0 +1,5 @@ +The real README file is one directory up. + +This directory's run script can have useful comments. +If it doesn't but you feel it should, please send a patch +to busybox's mailing list. diff --git a/examples/var_service/ftpd/README b/examples/var_service/ftpd/README new file mode 100644 index 000000000..4ddccb22d --- /dev/null +++ b/examples/var_service/ftpd/README @@ -0,0 +1,5 @@ +The real README file is one directory up. + +This directory's run script can have useful comments. +If it doesn't but you feel it should, please send a patch +to busybox's mailing list. diff --git a/examples/var_service/fw/README b/examples/var_service/fw/README new file mode 100644 index 000000000..4ddccb22d --- /dev/null +++ b/examples/var_service/fw/README @@ -0,0 +1,5 @@ +The real README file is one directory up. + +This directory's run script can have useful comments. +If it doesn't but you feel it should, please send a patch +to busybox's mailing list. diff --git a/examples/var_service/getty_tty1/README b/examples/var_service/getty_tty1/README new file mode 100644 index 000000000..4ddccb22d --- /dev/null +++ b/examples/var_service/getty_tty1/README @@ -0,0 +1,5 @@ +The real README file is one directory up. + +This directory's run script can have useful comments. +If it doesn't but you feel it should, please send a patch +to busybox's mailing list. diff --git a/examples/var_service/gpm/README b/examples/var_service/gpm/README new file mode 100644 index 000000000..4ddccb22d --- /dev/null +++ b/examples/var_service/gpm/README @@ -0,0 +1,5 @@ +The real README file is one directory up. + +This directory's run script can have useful comments. +If it doesn't but you feel it should, please send a patch +to busybox's mailing list. diff --git a/examples/var_service/httpd/README b/examples/var_service/httpd/README new file mode 100644 index 000000000..4ddccb22d --- /dev/null +++ b/examples/var_service/httpd/README @@ -0,0 +1,5 @@ +The real README file is one directory up. + +This directory's run script can have useful comments. +If it doesn't but you feel it should, please send a patch +to busybox's mailing list. diff --git a/examples/var_service/ifplugd_if/README b/examples/var_service/ifplugd_if/README new file mode 100644 index 000000000..4ddccb22d --- /dev/null +++ b/examples/var_service/ifplugd_if/README @@ -0,0 +1,5 @@ +The real README file is one directory up. + +This directory's run script can have useful comments. +If it doesn't but you feel it should, please send a patch +to busybox's mailing list. diff --git a/examples/var_service/inetd/README b/examples/var_service/inetd/README new file mode 100644 index 000000000..4ddccb22d --- /dev/null +++ b/examples/var_service/inetd/README @@ -0,0 +1,5 @@ +The real README file is one directory up. + +This directory's run script can have useful comments. +If it doesn't but you feel it should, please send a patch +to busybox's mailing list. diff --git a/examples/var_service/nmeter/README b/examples/var_service/nmeter/README new file mode 100644 index 000000000..4ddccb22d --- /dev/null +++ b/examples/var_service/nmeter/README @@ -0,0 +1,5 @@ +The real README file is one directory up. + +This directory's run script can have useful comments. +If it doesn't but you feel it should, please send a patch +to busybox's mailing list. diff --git a/examples/var_service/ntpd/README b/examples/var_service/ntpd/README new file mode 100644 index 000000000..4ddccb22d --- /dev/null +++ b/examples/var_service/ntpd/README @@ -0,0 +1,5 @@ +The real README file is one directory up. + +This directory's run script can have useful comments. +If it doesn't but you feel it should, please send a patch +to busybox's mailing list. diff --git a/examples/var_service/tftpd/README b/examples/var_service/tftpd/README new file mode 100644 index 000000000..4ddccb22d --- /dev/null +++ b/examples/var_service/tftpd/README @@ -0,0 +1,5 @@ +The real README file is one directory up. + +This directory's run script can have useful comments. +If it doesn't but you feel it should, please send a patch +to busybox's mailing list. -- cgit v1.2.3-55-g6feb From 8b7e8ae2249ffd9aa2c67536554eb9f6b6636ba5 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Sat, 22 Feb 2014 14:12:29 +0100 Subject: wget: add support for https using "openssl s_client" as a helper www.kernel.org started redirecting http:// to https:// making https support mandatory for any auto build scripts. function old new delta wget_main 2631 2971 +340 parse_url 409 471 +62 .rodata 115607 115626 +19 P_HTTPS - 6 +6 P_HTTP - 5 +5 P_FTP - 4 +4 ------------------------------------------------------------------------------ (add/remove: 3/0 grow/shrink: 3/0 up/down: 436/0) Total: 436 bytes Signed-off-by: Denys Vlasenko --- networking/wget.c | 118 ++++++++++++++++++++++++++++++++++++++++++------------ 1 file changed, 92 insertions(+), 26 deletions(-) diff --git a/networking/wget.c b/networking/wget.c index 7ca947aec..dfea3d4d2 100644 --- a/networking/wget.c +++ b/networking/wget.c @@ -47,10 +47,13 @@ struct host_info { char *allocated; const char *path; char *user; + const char *protocol; char *host; int port; - smallint is_ftp; }; +static const char P_FTP[] = "ftp"; +static const char P_HTTP[] = "http"; +static const char P_HTTPS[] = "https"; /* Globals */ @@ -219,7 +222,7 @@ static FILE *open_socket(len_and_sockaddr *lsa) /* glibc 2.4 seems to try seeking on it - ??! */ /* hopefully it understands what ESPIPE means... */ fp = fdopen(fd, "r+"); - if (fp == NULL) + if (!fp) bb_perror_msg_and_die(bb_msg_memory_exhausted); return fp; @@ -274,23 +277,31 @@ static void parse_url(const char *src_url, struct host_info *h) free(h->allocated); h->allocated = url = xstrdup(src_url); - if (strncmp(url, "ftp://", 6) == 0) { - h->port = bb_lookup_port("ftp", "tcp", 21); - h->host = url + 6; - h->is_ftp = 1; - } else - if (strncmp(url, "http://", 7) == 0) { - h->host = url + 7; + h->protocol = P_FTP; + p = strstr(url, "://"); + if (p) { + *p = '\0'; + h->host = p + 3; + if (strcmp(url, P_FTP) == 0) { + h->port = bb_lookup_port(P_FTP, "tcp", 21); + } else + if (strcmp(url, P_HTTPS) == 0) { + h->port = bb_lookup_port(P_HTTPS, "tcp", 443); + h->protocol = P_HTTPS; + } else + if (strcmp(url, P_HTTP) == 0) { http: - h->port = bb_lookup_port("http", "tcp", 80); - h->is_ftp = 0; - } else - if (!strstr(url, "//")) { + h->port = bb_lookup_port(P_HTTP, "tcp", 80); + h->protocol = P_HTTP; + } else { + *p = ':'; + bb_error_msg_and_die("not an http or ftp url: %s", sanitize_string(url)); + } + } else { // GNU wget is user-friendly and falls back to http:// h->host = url; goto http; - } else - bb_error_msg_and_die("not an http or ftp url: %s", sanitize_string(url)); + } // FYI: // "Real" wget 'http://busybox.net?var=a/b' sends this request: @@ -472,6 +483,56 @@ static FILE* prepare_ftp_session(FILE **dfpp, struct host_info *target, len_and_ return sfp; } +static int spawn_https_helper(const char *host, unsigned port) +{ + char *allocated = NULL; + int sp[2]; + int pid; + + if (socketpair(AF_UNIX, SOCK_STREAM, 0, sp) != 0) + /* Kernel can have AF_UNIX support disabled */ + bb_perror_msg_and_die("socketpair"); + + if (!strchr(host, ':')) + host = allocated = xasprintf("%s:%u", host, port); + + pid = BB_MMU ? xfork() : xvfork(); + if (pid == 0) { + /* Child */ + char *argv[6]; + + close(sp[0]); + xmove_fd(sp[1], 0); + xdup2(0, 1); + /* + * TODO: develop a tiny ssl/tls helper (using matrixssl?), + * try to exec it here before falling back to big fat openssl. + */ + /* + * openssl s_client -quiet -connect www.kernel.org:443 2>/dev/null + * It prints some debug stuff on stderr, don't know how to suppress it. + * Work around by dev-nulling stderr. We lose all error messages :( + */ + xmove_fd(2, 3); + xopen("/dev/null", O_RDWR); + argv[0] = (char*)"openssl"; + argv[1] = (char*)"s_client"; + argv[2] = (char*)"-quiet"; + argv[3] = (char*)"-connect"; + argv[4] = (char*)host; + argv[5] = NULL; + BB_EXECVP(argv[0], argv); + xmove_fd(3, 2); + bb_perror_msg_and_die("can't execute '%s'", argv[0]); + /* notreached */ + } + + /* parent process */ + free(allocated); + close(sp[1]); + return sp[0]; +} + static void NOINLINE retrieve_file_data(FILE *dfp) { #if ENABLE_FEATURE_WGET_STATUSBAR || ENABLE_FEATURE_WGET_TIMEOUT @@ -644,7 +705,8 @@ static void download_one_url(const char *url) /* Use the proxy if necessary */ use_proxy = (strcmp(G.proxy_flag, "off") != 0); if (use_proxy) { - proxy = getenv(target.is_ftp ? "ftp_proxy" : "http_proxy"); + proxy = getenv(target.protocol == P_FTP ? "ftp_proxy" : "http_proxy"); +//FIXME: what if protocol is https? Ok to use http_proxy? use_proxy = (proxy && proxy[0]); if (use_proxy) parse_url(proxy, &server); @@ -704,27 +766,31 @@ static void download_one_url(const char *url) /*G.content_len = 0; - redundant, got_clen = 0 is enough */ G.got_clen = 0; G.chunked = 0; - if (use_proxy || !target.is_ftp) { + if (use_proxy || target.protocol != P_FTP) { /* * HTTP session */ char *str; int status; - - /* Open socket to http server */ - sfp = open_socket(lsa); + /* Open socket to http(s) server */ + if (target.protocol == P_HTTPS) { + int fd = spawn_https_helper(server.host, server.port); + sfp = fdopen(fd, "r+"); + if (!sfp) + bb_perror_msg_and_die(bb_msg_memory_exhausted); + } else + sfp = open_socket(lsa); /* Send HTTP request */ if (use_proxy) { - fprintf(sfp, "GET %stp://%s/%s HTTP/1.1\r\n", - target.is_ftp ? "f" : "ht", target.host, + fprintf(sfp, "GET %s://%s/%s HTTP/1.1\r\n", + target.protocol, target.host, target.path); } else { - if (option_mask32 & WGET_OPT_POST_DATA) - fprintf(sfp, "POST /%s HTTP/1.1\r\n", target.path); - else - fprintf(sfp, "GET /%s HTTP/1.1\r\n", target.path); + fprintf(sfp, "%s /%s HTTP/1.1\r\n", + (option_mask32 & WGET_OPT_POST_DATA) ? "POST" : "GET", + target.path); } fprintf(sfp, "Host: %s\r\nUser-Agent: %s\r\n", -- cgit v1.2.3-55-g6feb From d82046f59f8b3d338bcfe6aa3b786e13c5c54ee3 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Sun, 23 Feb 2014 23:31:13 +0100 Subject: networking/ssl_helper: experimental matrixssl-based ssl helper Signed-off-by: Denys Vlasenko --- networking/ssl_helper/README | 16 ++ networking/ssl_helper/ssl_helper.c | 406 ++++++++++++++++++++++++++++++++++++ networking/ssl_helper/ssl_helper.sh | 11 + 3 files changed, 433 insertions(+) create mode 100644 networking/ssl_helper/README create mode 100644 networking/ssl_helper/ssl_helper.c create mode 100755 networking/ssl_helper/ssl_helper.sh diff --git a/networking/ssl_helper/README b/networking/ssl_helper/README new file mode 100644 index 000000000..4d0508fbb --- /dev/null +++ b/networking/ssl_helper/README @@ -0,0 +1,16 @@ +Build instructions: + +* Unpack matrixssl-3-4-2-open.tgz. +* Build it: "make" +* Drop this directory into matrixssl-3-4-2-open/ssl_helper +* Run ssl_helper.sh to compile and link the helper + +Usage: "ssl_helper -d " where FILE_DESCRIPTOR is open to the peer. + +In bash, you can do it this way: +$ ssl_helper -d3 3<>/dev/tcp/HOST/PORT + +Stdin will be SSL-encrypted and sent to FILE_DESCRIPTOR. +Data from FILE_DESCRIPTOR will be decrypted and sent to stdout. + +The plan is to adapt it for wget https helper, and for ssl support in nc. diff --git a/networking/ssl_helper/ssl_helper.c b/networking/ssl_helper/ssl_helper.c new file mode 100644 index 000000000..d840b1b88 --- /dev/null +++ b/networking/ssl_helper/ssl_helper.c @@ -0,0 +1,406 @@ +/* + * Copyright (c) 2013 INSIDE Secure Corporation + * Copyright (c) PeerSec Networks, 2002-2011 + * All Rights Reserved + * + * The latest version of this code is available at http://www.matrixssl.org + * + * This software is open source; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in WITHOUT ANY WARRANTY; without even the + * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * http://www.gnu.org/copyleft/gpl.html + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "matrixssl/matrixsslApi.h" + +//#warning "DO NOT USE THESE DEFAULT KEYS IN PRODUCTION ENVIRONMENTS." + +/* + * If supporting client authentication, pick ONE identity to auto select a + * certificate and private key that support desired algorithms. + */ +#define ID_RSA /* RSA Certificate and Key */ + +#define USE_HEADER_KEYS + +/* If the algorithm type is supported, load a CA for it */ +#ifdef USE_HEADER_KEYS +/* CAs */ +# include "sampleCerts/RSA/ALL_RSA_CAS.h" +/* Identity Certs and Keys for use with Client Authentication */ +# ifdef ID_RSA +# define EXAMPLE_RSA_KEYS +# include "sampleCerts/RSA/2048_RSA.h" +# include "sampleCerts/RSA/2048_RSA_KEY.h" +# endif +#endif + +static ssize_t safe_write(int fd, const void *buf, size_t count) +{ + ssize_t n; + + do { + n = write(fd, buf, count); + } while (n < 0 && errno == EINTR); + + return n; +} + +static ssize_t full_write(int fd, const void *buf, size_t len) +{ + ssize_t cc; + ssize_t total; + + total = 0; + + while (len) { + cc = safe_write(fd, buf, len); + + if (cc < 0) { + if (total) { + /* we already wrote some! */ + /* user can do another write to know the error code */ + return total; + } + return cc; /* write() returns -1 on failure. */ + } + + total += cc; + buf = ((const char *)buf) + cc; + len -= cc; + } + + return total; +} + +static void say(const char *s, ...) +{ + char buf[256]; + va_list p; + int sz; + + va_start(p, s); + sz = vsnprintf(buf, sizeof(buf), s, p); + full_write(STDERR_FILENO, buf, sz >= 0 && sz < sizeof(buf) ? sz : strlen(buf)); + va_end(p); +} + +static void die(const char *s, ...) +{ + char buf[256]; + va_list p; + int sz; + + va_start(p, s); + sz = vsnprintf(buf, sizeof(buf), s, p); + full_write(STDERR_FILENO, buf, sz >= 0 && sz < sizeof(buf) ? sz : strlen(buf)); + exit(1); + va_end(p); +} + +#if 0 +# define dbg(...) say(__VA_ARGS__) +#else +# define dbg(...) ((void)0) +#endif + +static struct pollfd pfd[2] = { + { -1, POLLIN|POLLERR|POLLHUP, 0 }, + { -1, POLLIN|POLLERR|POLLHUP, 0 }, +}; +#define STDIN pfd[0] +#define NETWORK pfd[1] +#define STDIN_READY() (pfd[0].revents & (POLLIN|POLLERR|POLLHUP)) +#define NETWORK_READY() (pfd[1].revents & (POLLIN|POLLERR|POLLHUP)) + +static int wait_for_input(void) +{ + if (STDIN.fd == NETWORK.fd) /* means both are -1 */ + exit(0); + dbg("polling\n"); + STDIN.revents = NETWORK.revents = 0; + return poll(pfd, 2, -1); +} + +static int32 certCb(ssl_t *ssl, psX509Cert_t *cert, int32 alert) +{ + /* Example to allow anonymous connections based on a define */ + if (alert > 0) { + return SSL_ALLOW_ANON_CONNECTION; // = 254 + } +#if 0 + /* Validate the 'not before' and 'not after' dates, etc */ + return PS_FAILURE; /* if we don't like this cert */ +#endif + return PS_SUCCESS; +} + +static void close_conn_and_exit(ssl_t *ssl, int fd) +{ + unsigned char *buf; + int len; + + fcntl(fd, F_SETFL, fcntl(fd, F_GETFL) | O_NONBLOCK); + /* Quick attempt to send a closure alert, don't worry about failure */ + if (matrixSslEncodeClosureAlert(ssl) >= 0) { + len = matrixSslGetOutdata(ssl, &buf); + if (len > 0) { + len = safe_write(fd, buf, len); + //if (len > 0) { + // matrixSslSentData(ssl, len); + //} + } + } + //matrixSslDeleteSession(ssl); + shutdown(fd, SHUT_WR); + exit(0); +} + +static int encode_data(ssl_t *ssl, const void *data, int len) +{ + unsigned char *buf; + int available; + + available = matrixSslGetWritebuf(ssl, &buf, len); + if (available < 0) + die("matrixSslGetWritebuf\n"); + if (len > available) + die("len > available\n"); + memcpy(buf, data, len); + if (matrixSslEncodeWritebuf(ssl, len) < 0) + die("matrixSslEncodeWritebuf\n"); + return len; +} + +static void flush_to_net(ssl_t *ssl, int fd) +{ + int rc; + int len; + unsigned char *buf; + + while ((len = matrixSslGetOutdata(ssl, &buf)) > 0) { + dbg("writing net %d bytes\n", len); + if (full_write(fd, buf, len) != len) + die("write to network\n"); + rc = matrixSslSentData(ssl, len); + if (rc < 0) + die("matrixSslSentData\n"); + } +} + +static void do_io_until_eof_and_exit(int fd, sslKeys_t *keys) +{ + int rc; + int len; + uint32_t len32u; + sslSessionId_t *sid; + ssl_t *ssl; + unsigned char *buf; + + NETWORK.fd = fd; + /* Note! STDIN.fd is disabled (-1) until SSL handshake is over: + * we do not attempt to feed any user data to MatrixSSL + * before it is ready. + */ + + matrixSslNewSessionId(&sid); + rc = matrixSslNewClientSession(&ssl, keys, sid, 0, certCb, NULL, NULL, 0); +dbg("matrixSslNewClientSession:rc=%d\n", rc); + if (rc != MATRIXSSL_REQUEST_SEND) + die("matrixSslNewClientSession\n"); + + len = 0; /* only to suppress compiler warning */ + again: + switch (rc) { + case MATRIXSSL_REQUEST_SEND: + dbg("MATRIXSSL_REQUEST_SEND\n"); + flush_to_net(ssl, fd); + goto poll_input; + + case 0: + dbg("rc==0\n"); + flush_to_net(ssl, fd); + goto poll_input; + + case MATRIXSSL_REQUEST_CLOSE: + /* what does this mean if we are here? */ + dbg("MATRIXSSL_REQUEST_CLOSE\n"); + close_conn_and_exit(ssl, fd); + + case MATRIXSSL_HANDSHAKE_COMPLETE: + dbg("MATRIXSSL_HANDSHAKE_COMPLETE\n"); + /* Init complete, can start reading local user's data: */ + STDIN.fd = STDIN_FILENO; + poll_input: + wait_for_input(); + if (STDIN_READY()) { + char ibuf[4 * 1024]; + dbg("reading stdin\n"); + len = read(STDIN_FILENO, ibuf, sizeof(ibuf)); + if (len < 0) + die("read error on stdin\n"); + if (len == 0) + STDIN.fd = -1; + else { + len = encode_data(ssl, ibuf, len); + if (len) { + rc = MATRIXSSL_REQUEST_SEND; +dbg("rc=%d\n", rc); + goto again; + } + } + } + read_network: + if (NETWORK_READY()) { + dbg("%s%s%s\n", + (pfd[1].revents & POLLIN) ? "POLLIN" : "", + (pfd[1].revents & POLLERR) ? "|POLLERR" : "", + (pfd[1].revents & POLLHUP) ? "|POLLHUP" : "" + ); + len = matrixSslGetReadbuf(ssl, &buf); + if (len <= 0) + die("matrixSslGetReadbuf\n"); + dbg("reading net up to %d\n", len); + len = read(fd, buf, len); + dbg("reading net:%d\n", len); + if (len < 0) + die("read error on network\n"); + if (len == 0) /*eof*/ + NETWORK.fd = -1; + len32u = len; + rc = matrixSslReceivedData(ssl, len, &buf, &len32u); +dbg("matrixSslReceivedData:rc=%d\n", rc); + len = len32u; + if (rc < 0) + die("matrixSslReceivedData\n"); + } + goto again; + + case MATRIXSSL_APP_DATA: + dbg("MATRIXSSL_APP_DATA: writing stdout\n"); + do { + if (full_write(STDOUT_FILENO, buf, len) != len) + die("write to stdout\n"); + len32u = len; + rc = matrixSslProcessedData(ssl, &buf, &len32u); +//this was seen returning rc=0: +dbg("matrixSslProcessedData:rc=%d\n", rc); + len = len32u; + } while (rc == MATRIXSSL_APP_DATA); + if (pfd[1].fd == -1) { + /* Already saw EOF on network, and we processed + * and wrote out all ssl data. Signal it: + */ + close(STDOUT_FILENO); + } + goto again; + + case MATRIXSSL_REQUEST_RECV: + dbg("MATRIXSSL_REQUEST_RECV\n"); + wait_for_input(); + goto read_network; + + case MATRIXSSL_RECEIVED_ALERT: + dbg("MATRIXSSL_RECEIVED_ALERT\n"); + /* The first byte of the buffer is the level */ + /* The second byte is the description */ + if (buf[0] == SSL_ALERT_LEVEL_FATAL) + die("Fatal alert\n"); + /* Closure alert is normal (and best) way to close */ + if (buf[1] == SSL_ALERT_CLOSE_NOTIFY) + close_conn_and_exit(ssl, fd); + die("Warning alert\n"); + len32u = len; + rc = matrixSslProcessedData(ssl, &buf, &len32u); +dbg("matrixSslProcessedData:rc=%d\n", rc); + len = len32u; + goto again; + + default: + /* If rc < 0 it is an error */ + die("bad rc:%d\n", rc); + } +} + +static sslKeys_t* make_keys(void) +{ + int rc, CAstreamLen; + char *CAstream; + sslKeys_t *keys; + + if (matrixSslNewKeys(&keys) < 0) + die("matrixSslNewKeys\n"); + +#ifdef USE_HEADER_KEYS + /* + * In-memory based keys + * Build the CA list first for potential client auth usage + */ + CAstream = NULL; + CAstreamLen = sizeof(RSACAS); + if (CAstreamLen > 0) { + CAstream = psMalloc(NULL, CAstreamLen); + memcpy(CAstream, RSACAS, sizeof(RSACAS)); + } + + #ifdef ID_RSA + rc = matrixSslLoadRsaKeysMem(keys, RSA2048, sizeof(RSA2048), + RSA2048KEY, sizeof(RSA2048KEY), (unsigned char*)CAstream, + CAstreamLen); + if (rc < 0) + die("matrixSslLoadRsaKeysMem\n"); + #endif + + if (CAstream) + psFree(CAstream); +#endif /* USE_HEADER_KEYS */ + return keys; +} + +int main(int argc, char **argv) +{ + int fd; + char *fd_str; + + if (!argv[1]) + die("Syntax error\n"); + if (argv[1][0] != '-') + die("Syntax error\n"); + if (argv[1][1] != 'd') + die("Syntax error\n"); + fd_str = argv[1] + 2; + if (!fd_str[0]) + fd_str = argv[2]; + if (!fd_str || fd_str[0] < '0' || fd_str[0] > '9') + die("Syntax error\n"); + + fd = atoi(fd_str); + if (fd < 3) + die("Syntax error\n"); + + if (matrixSslOpen() < 0) + die("matrixSslOpen\n"); + + do_io_until_eof_and_exit(fd, make_keys()); + /* does not return */ + + return 0; +} diff --git a/networking/ssl_helper/ssl_helper.sh b/networking/ssl_helper/ssl_helper.sh new file mode 100755 index 000000000..dc52de778 --- /dev/null +++ b/networking/ssl_helper/ssl_helper.sh @@ -0,0 +1,11 @@ +#!/bin/sh + +# I use this to build static uclibc based binary using Aboriginal Linux toolchain: +PREFIX=x86_64- +STATIC=-static +# Standard build: +PREFIX="" +STATIC="" + +${PREFIX}gcc -Os -DPOSIX -I.. -I../sampleCerts -Wall -c ssl_helper.c -o ssl_helper.o +${PREFIX}gcc $STATIC ssl_helper.o ../libmatrixssl.a -lc ../libmatrixssl.a -o ssl_helper -- cgit v1.2.3-55-g6feb From 53315570bb77534d828b3cf1f06b2ca286da4962 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Sun, 23 Feb 2014 23:39:47 +0100 Subject: wget: add commented-out code to use ssl_helper instead of openssl Signed-off-by: Denys Vlasenko --- networking/wget.c | 49 +++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 47 insertions(+), 2 deletions(-) diff --git a/networking/wget.c b/networking/wget.c index dfea3d4d2..3d9a1b333 100644 --- a/networking/wget.c +++ b/networking/wget.c @@ -527,12 +527,51 @@ static int spawn_https_helper(const char *host, unsigned port) /* notreached */ } - /* parent process */ + /* Parent */ free(allocated); close(sp[1]); return sp[0]; } +/* See networking/ssl_helper/README */ +#define SSL_HELPER 0 + +#if SSL_HELPER +static void spawn_https_helper1(int network_fd) +{ + int sp[2]; + int pid; + + if (socketpair(AF_UNIX, SOCK_STREAM, 0, sp) != 0) + /* Kernel can have AF_UNIX support disabled */ + bb_perror_msg_and_die("socketpair"); + + pid = BB_MMU ? xfork() : xvfork(); + if (pid == 0) { + /* Child */ + char *argv[3]; + + close(sp[0]); + xmove_fd(sp[1], 0); + xdup2(0, 1); + xmove_fd(network_fd, 3); + /* + * A simple ssl/tls helper + */ + argv[0] = (char*)"ssl_helper"; + argv[1] = (char*)"-d3"; + argv[2] = NULL; + BB_EXECVP(argv[0], argv); + bb_perror_msg_and_die("can't execute '%s'", argv[0]); + /* notreached */ + } + + /* Parent */ + close(sp[1]); + xmove_fd(sp[0], network_fd); +} +#endif + static void NOINLINE retrieve_file_data(FILE *dfp) { #if ENABLE_FEATURE_WGET_STATUSBAR || ENABLE_FEATURE_WGET_TIMEOUT @@ -775,13 +814,19 @@ static void download_one_url(const char *url) /* Open socket to http(s) server */ if (target.protocol == P_HTTPS) { +/* openssl-based helper + * Inconvenient API since we can't give it an open fd, + */ int fd = spawn_https_helper(server.host, server.port); sfp = fdopen(fd, "r+"); if (!sfp) bb_perror_msg_and_die(bb_msg_memory_exhausted); } else sfp = open_socket(lsa); - +#if SSL_HELPER + if (target.protocol == P_HTTPS) + spawn_https_helper1(fileno(sfp)); +#endif /* Send HTTP request */ if (use_proxy) { fprintf(sfp, "GET %s://%s/%s HTTP/1.1\r\n", -- cgit v1.2.3-55-g6feb From a2796223cb1ffce77fdf75754b6052be32425692 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Mon, 24 Feb 2014 17:20:40 +0100 Subject: wget: fix comment Signed-off-by: Denys Vlasenko --- networking/wget.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/networking/wget.c b/networking/wget.c index 3d9a1b333..62a5fcc02 100644 --- a/networking/wget.c +++ b/networking/wget.c @@ -815,7 +815,7 @@ static void download_one_url(const char *url) /* Open socket to http(s) server */ if (target.protocol == P_HTTPS) { /* openssl-based helper - * Inconvenient API since we can't give it an open fd, + * Inconvenient API since we can't give it an open fd */ int fd = spawn_https_helper(server.host, server.port); sfp = fdopen(fd, "r+"); -- cgit v1.2.3-55-g6feb From 6554d03735e394c613ebacfe6b8d7b239e164310 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Mon, 24 Feb 2014 17:28:43 +0100 Subject: sysctl: do not error out showing write-only data. Closes 6386 Signed-off-by: Denys Vlasenko --- procps/sysctl.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/procps/sysctl.c b/procps/sysctl.c index c6a1de21d..f0883f054 100644 --- a/procps/sysctl.c +++ b/procps/sysctl.c @@ -129,6 +129,9 @@ static int sysctl_act_on_setting(char *setting) if (fd < 0) { switch (errno) { + case EACCES: + /* Happens for write-only settings, e.g. net.ipv6.route.flush */ + goto end; case ENOENT: if (option_mask32 & FLAG_SHOW_KEY_ERRORS) bb_error_msg("error: '%s' is an unknown key", outname); -- cgit v1.2.3-55-g6feb From 12916b922065f452a5b6c043200ac0863853c7a3 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Tue, 25 Feb 2014 15:09:01 +0100 Subject: libbb: trivial code shrink function old new delta reset_ino_dev_hashtable 84 74 -10 Signed-off-by: Denys Vlasenko --- libbb/inode_hash.c | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/libbb/inode_hash.c b/libbb/inode_hash.c index 715535ef5..2f02d0746 100644 --- a/libbb/inode_hash.c +++ b/libbb/inode_hash.c @@ -72,13 +72,18 @@ void FAST_FUNC add_to_ino_dev_hashtable(const struct stat *statbuf, const char * void FAST_FUNC reset_ino_dev_hashtable(void) { int i; - ino_dev_hashtable_bucket_t *bucket; + ino_dev_hashtable_bucket_t *bucket, *next; + + if (!ino_dev_hashtable) + return; + + for (i = 0; i < HASH_SIZE; i++) { + bucket = ino_dev_hashtable[i]; - for (i = 0; ino_dev_hashtable && i < HASH_SIZE; i++) { - while (ino_dev_hashtable[i] != NULL) { - bucket = ino_dev_hashtable[i]->next; - free(ino_dev_hashtable[i]); - ino_dev_hashtable[i] = bucket; + while (bucket != NULL) { + next = bucket->next; + free(bucket); + bucket = next; } } free(ino_dev_hashtable); -- cgit v1.2.3-55-g6feb From 83bc4332e7d6d74293c1c41e047d2681a8350e1a Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Tue, 25 Feb 2014 15:27:58 +0100 Subject: du, copy_file: fix file matching on cramfs. Closes 5456 function old new delta is_in_ino_dev_hashtable 88 108 +20 add_to_ino_dev_hashtable 150 142 -8 reset_ino_dev_hashtable 84 75 -9 ------------------------------------------------------------------------------ (add/remove: 0/0 grow/shrink: 1/2 up/down: 20/-17) Total: 3 bytes Signed-off-by: Denys Vlasenko --- libbb/inode_hash.c | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/libbb/inode_hash.c b/libbb/inode_hash.c index 2f02d0746..f11c2afb2 100644 --- a/libbb/inode_hash.c +++ b/libbb/inode_hash.c @@ -11,14 +11,23 @@ #include "libbb.h" typedef struct ino_dev_hash_bucket_struct { - struct ino_dev_hash_bucket_struct *next; ino_t ino; dev_t dev; + /* + * Above fields can be 64-bit, while pointer may be 32-bit. + * Putting "next" field here may reduce size of this struct: + */ + struct ino_dev_hash_bucket_struct *next; + /* + * Reportedly, on cramfs a file and a dir can have same ino. + * Need to also remember "file/dir" bit: + */ + char isdir; /* bool */ char name[1]; } ino_dev_hashtable_bucket_t; -#define HASH_SIZE 311 /* Should be prime */ -#define hash_inode(i) ((i) % HASH_SIZE) +#define HASH_SIZE 311u /* Should be prime */ +#define hash_inode(i) ((unsigned)(i) % HASH_SIZE) /* array of [HASH_SIZE] elements */ static ino_dev_hashtable_bucket_t **ino_dev_hashtable; @@ -38,6 +47,7 @@ char* FAST_FUNC is_in_ino_dev_hashtable(const struct stat *statbuf) while (bucket != NULL) { if ((bucket->ino == statbuf->st_ino) && (bucket->dev == statbuf->st_dev) + && (bucket->isdir == !!S_ISDIR(statbuf->st_mode)) ) { return bucket->name; } @@ -52,17 +62,18 @@ void FAST_FUNC add_to_ino_dev_hashtable(const struct stat *statbuf, const char * int i; ino_dev_hashtable_bucket_t *bucket; - i = hash_inode(statbuf->st_ino); if (!name) name = ""; bucket = xmalloc(sizeof(ino_dev_hashtable_bucket_t) + strlen(name)); bucket->ino = statbuf->st_ino; bucket->dev = statbuf->st_dev; + bucket->isdir = !!S_ISDIR(statbuf->st_mode); strcpy(bucket->name, name); if (!ino_dev_hashtable) ino_dev_hashtable = xzalloc(HASH_SIZE * sizeof(*ino_dev_hashtable)); + i = hash_inode(statbuf->st_ino); bucket->next = ino_dev_hashtable[i]; ino_dev_hashtable[i] = bucket; } -- cgit v1.2.3-55-g6feb From 18b699c30f1cd2d55bd094c10c44cfc3102f895c Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Tue, 25 Feb 2014 17:31:22 +0100 Subject: build system: remove a dead link from Config help text Signed-off-by: Denys Vlasenko --- Config.in | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/Config.in b/Config.in index 38d4ebc26..b6eaea541 100644 --- a/Config.in +++ b/Config.in @@ -423,10 +423,7 @@ config SELINUX the option of compiling in SELinux applets. If you do not have a complete SELinux userland installed, this stuff - will not compile. Go visit - http://www.nsa.gov/selinux/index.html - to download the necessary stuff to allow busybox to compile with - this option enabled. Specifially, libselinux 1.28 or better is + will not compile. Specifially, libselinux 1.28 or better is directly required by busybox. If the installation is located in a non-standard directory, provide it by invoking make as follows: CFLAGS=-I \ -- cgit v1.2.3-55-g6feb From 589051b56553788546c757a0b38996a1a8c49a11 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Tue, 25 Feb 2014 17:52:10 +0100 Subject: hwclock: fix setting of tz_minuteswest. Closes 5414 Signed-off-by: Denys Vlasenko --- util-linux/hwclock.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/util-linux/hwclock.c b/util-linux/hwclock.c index 379eeb253..3f531555b 100644 --- a/util-linux/hwclock.c +++ b/util-linux/hwclock.c @@ -97,7 +97,11 @@ static void to_sys_clock(const char **pp_rtcname, int utc) struct timeval tv; struct timezone tz; - tz.tz_minuteswest = timezone/60 - 60*daylight; + tz.tz_minuteswest = timezone/60; + /* ^^^ used to also subtract 60*daylight, but it's wrong: + * daylight!=0 means "this timezone has some DST + * during the year", not "DST is in effect now". + */ tz.tz_dsttime = 0; tv.tv_sec = read_rtc(pp_rtcname, NULL, utc); @@ -248,7 +252,7 @@ static void set_system_clock_timezone(int utc) gettimeofday(&tv, NULL); broken = localtime(&tv.tv_sec); tz.tz_minuteswest = timezone / 60; - if (broken->tm_isdst) + if (broken->tm_isdst > 0) tz.tz_minuteswest -= 60; tz.tz_dsttime = 0; gettimeofday(&tv, NULL); @@ -305,6 +309,10 @@ int hwclock_main(int argc UNUSED_PARAM, char **argv) ; applet_long_options = hwclock_longopts; #endif + + /* Initialize "timezone" (libc global variable) */ + tzset(); + opt_complementary = "r--wst:w--rst:s--wrt:t--rsw:l--u:u--l"; opt = getopt32(argv, "lurswtf:", &rtcname); -- cgit v1.2.3-55-g6feb From c472898eaa0ccc1d4d787ae1917a8f40d18889cb Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Wed, 26 Feb 2014 13:58:59 +0100 Subject: nc: fix option bit positions. Closes 6926 Signed-off-by: Denys Vlasenko --- networking/nc_bloaty.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/networking/nc_bloaty.c b/networking/nc_bloaty.c index b9eff3da4..b28d05f51 100644 --- a/networking/nc_bloaty.c +++ b/networking/nc_bloaty.c @@ -175,9 +175,9 @@ enum { OPT_w = (1 << 5), OPT_l = (1 << 6) * ENABLE_NC_SERVER, OPT_k = (1 << 7) * ENABLE_NC_SERVER, - OPT_i = (1 << (7+2*ENABLE_NC_SERVER)) * ENABLE_NC_EXTRA, - OPT_o = (1 << (8+2*ENABLE_NC_SERVER)) * ENABLE_NC_EXTRA, - OPT_z = (1 << (9+2*ENABLE_NC_SERVER)) * ENABLE_NC_EXTRA, + OPT_i = (1 << (6+2*ENABLE_NC_SERVER)) * ENABLE_NC_EXTRA, + OPT_o = (1 << (7+2*ENABLE_NC_SERVER)) * ENABLE_NC_EXTRA, + OPT_z = (1 << (8+2*ENABLE_NC_SERVER)) * ENABLE_NC_EXTRA, }; #define o_nflag (option_mask32 & OPT_n) -- cgit v1.2.3-55-g6feb From 6885e49ba596239a0b0d3631fd72fc2692fbb65c Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Wed, 26 Feb 2014 15:27:10 +0100 Subject: find: code shrink function old new delta func_exec 306 285 -21 Signed-off-by: Denys Vlasenko --- findutils/find.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/findutils/find.c b/findutils/find.c index 5d5e24bfb..044f010b0 100644 --- a/findutils/find.c +++ b/findutils/find.c @@ -420,12 +420,10 @@ static char* subst(const char *src, unsigned count, const char* filename) size_t flen = strlen(filename); /* we replace each '{}' with filename: growth by strlen-2 */ buf = dst = xmalloc(strlen(src) + count*(flen-2) + 1); - while ((end = strstr(src, "{}"))) { - memcpy(dst, src, end - src); - dst += end - src; + while ((end = strstr(src, "{}")) != NULL) { + dst = mempcpy(dst, src, end - src); + dst = mempcpy(dst, filename, flen); src = end + 2; - memcpy(dst, filename, flen); - dst += flen; } strcpy(dst, src); return buf; -- cgit v1.2.3-55-g6feb From 6f068904dc142657bb596f91196f9113f1838cbe Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Thu, 27 Feb 2014 11:17:06 +0100 Subject: xargs: add support for -I and -i. Closes 493 function old new delta process_stdin_with_replace - 195 +195 xmalloc_substitute_string - 145 +145 xargs_main 808 884 +76 count_strstr - 45 +45 packed_usage 29580 29571 -9 parse_params 1445 1416 -29 func_exec 285 138 -147 ------------------------------------------------------------------------------ (add/remove: 4/0 grow/shrink: 1/3 up/down: 461/-185) Total: 276 bytes text data bss dec hex filename 922156 932 17692 940780 e5aec busybox_old 922440 932 17692 941064 e5c08 busybox_unstripped Signed-off-by: Denys Vlasenko --- findutils/find.c | 32 +----------- findutils/xargs.c | 153 ++++++++++++++++++++++++++++++++++++++++++++---------- include/libbb.h | 2 + libbb/replace.c | 45 ++++++++++++++++ 4 files changed, 176 insertions(+), 56 deletions(-) create mode 100644 libbb/replace.c diff --git a/findutils/find.c b/findutils/find.c index 044f010b0..6d34f4d68 100644 --- a/findutils/find.c +++ b/findutils/find.c @@ -402,34 +402,6 @@ struct globals { G.recurse_flags = ACTION_RECURSE; \ } while (0) -#if ENABLE_FEATURE_FIND_EXEC -static unsigned count_subst(const char *str) -{ - unsigned count = 0; - while ((str = strstr(str, "{}")) != NULL) { - count++; - str++; - } - return count; -} - - -static char* subst(const char *src, unsigned count, const char* filename) -{ - char *buf, *dst, *end; - size_t flen = strlen(filename); - /* we replace each '{}' with filename: growth by strlen-2 */ - buf = dst = xmalloc(strlen(src) + count*(flen-2) + 1); - while ((end = strstr(src, "{}")) != NULL) { - dst = mempcpy(dst, src, end - src); - dst = mempcpy(dst, filename, flen); - src = end + 2; - } - strcpy(dst, src); - return buf; -} -#endif - /* Return values of ACTFs ('action functions') are a bit mask: * bit 1=1: prune (use SKIP constant for setting it) * bit 0=1: matched successfully (TRUE) @@ -613,7 +585,7 @@ ACTF(exec) char *argv[ap->exec_argc + 1]; #endif for (i = 0; i < ap->exec_argc; i++) - argv[i] = subst(ap->exec_argv[i], ap->subst_count[i], fileName); + argv[i] = xmalloc_substitute_string(ap->exec_argv[i], ap->subst_count[i], "{}", fileName); argv[i] = NULL; /* terminate the list */ rc = spawn_and_wait(argv); @@ -1091,7 +1063,7 @@ static action*** parse_params(char **argv) ap->subst_count = xmalloc(ap->exec_argc * sizeof(int)); i = ap->exec_argc; while (i--) - ap->subst_count[i] = count_subst(ap->exec_argv[i]); + ap->subst_count[i] = count_strstr(ap->exec_argv[i], "{}"); } #endif #if ENABLE_FEATURE_FIND_PAREN diff --git a/findutils/xargs.c b/findutils/xargs.c index 0d1bb43fc..ed6dbd33e 100644 --- a/findutils/xargs.c +++ b/findutils/xargs.c @@ -53,6 +53,13 @@ //config: Support -0: input items are terminated by a NUL character //config: instead of whitespace, and the quotes and backslash //config: are not special. +//config: +//config:config FEATURE_XARGS_SUPPORT_REPL_STR +//config: bool "Enable -I STR: string to replace" +//config: default y +//config: depends on XARGS +//config: help +//config: Support -I STR and -i[STR] options. //applet:IF_XARGS(APPLET_NOEXEC(xargs, xargs, BB_DIR_USR_BIN, BB_SUID_DROP, xargs)) @@ -85,19 +92,22 @@ struct globals { char **args; +#if ENABLE_FEATURE_XARGS_SUPPORT_REPL_STR + char **argv; + const char *repl_str; + char eol_ch; +#endif const char *eof_str; int idx; } FIX_ALIASING; #define G (*(struct globals*)&bb_common_bufsiz1) #define INIT_G() do { \ G.eof_str = NULL; /* need to clear by hand because we are NOEXEC applet */ \ + IF_FEATURE_XARGS_SUPPORT_REPL_STR(G.repl_str = "{}";) \ + IF_FEATURE_XARGS_SUPPORT_REPL_STR(G.eol_ch = '\n';) \ } while (0) -/* - * This function has special algorithm. - * Don't use fork and include to main! - */ static int xargs_exec(void) { int status; @@ -301,7 +311,7 @@ static char* FAST_FUNC process0_stdin(int n_max_chars, int n_max_arg, char *buf) c = '\0'; } *p++ = c; - if (c == '\0') { /* word's delimiter or EOF detected */ + if (c == '\0') { /* NUL or EOF detected */ /* A full word is loaded */ store_param(s); dbg_msg("args[]:'%s'", s); @@ -323,10 +333,71 @@ static char* FAST_FUNC process0_stdin(int n_max_chars, int n_max_arg, char *buf) } #endif /* FEATURE_XARGS_SUPPORT_ZERO_TERM */ +#if ENABLE_FEATURE_XARGS_SUPPORT_REPL_STR +/* + * Used if -I was specified. + * In this mode, words aren't appended to PROG ARGS. + * Instead, entire input line is read, then string + * in every PROG and ARG is replaced with the line: + * echo -e "ho ho\nhi" | xargs -I_ cmd __ _ + * results in "cmd 'ho hoho ho' 'ho ho'"; "cmd 'hihi' 'hi'". + * -n MAX_ARGS seems to be ignored. + * Tested with GNU findutils 4.5.10. + */ +//FIXME: n_max_chars is not handled the same way as in GNU findutils. +//FIXME: quoting is not implemented. +static char* FAST_FUNC process_stdin_with_replace(int n_max_chars, int n_max_arg UNUSED_PARAM, char *buf) +{ + int i; + char *end, *p; + + /* Free strings from last invocation, if any */ + for (i = 0; G.args && G.args[i]; i++) + if (G.args[i] != G.argv[i]) + free(G.args[i]); + + end = buf + n_max_chars; + p = buf; + + while (1) { + int c = getchar(); + if (c == EOF || c == G.eol_ch) { + if (p == buf) + goto ret; /* empty line */ + c = '\0'; + } + *p++ = c; + if (c == '\0') { /* EOL or EOF detected */ + i = 0; + while (G.argv[i]) { + char *arg = G.argv[i]; + int count = count_strstr(arg, G.repl_str); + if (count != 0) + arg = xmalloc_substitute_string(arg, count, G.repl_str, s); + store_param(arg); + dbg_msg("args[]:'%s'", arg); + i++; + } + p = buf; + goto ret; + } + if (p == end) { + goto ret; + } + } + ret: + *p = '\0'; + /* store_param(NULL) - caller will do it */ + dbg_msg("return:'%s'", buf); + return buf; +} +#endif + #if ENABLE_FEATURE_XARGS_SUPPORT_CONFIRMATION /* Prompt the user for a response, and - if the user responds affirmatively, return true; - otherwise, return false. Uses "/dev/tty", not stdin. */ + * if user responds affirmatively, return true; + * otherwise, return false. Uses "/dev/tty", not stdin. + */ static int xargs_ask_confirmation(void) { FILE *tty_stream; @@ -360,6 +431,9 @@ static int xargs_ask_confirmation(void) //usage: "\n -e[STR] STR stops input processing" //usage: "\n -n N Pass no more than N args to PROG" //usage: "\n -s N Pass command line of no more than N bytes" +//usage: IF_FEATURE_XARGS_SUPPORT_REPL_STR( +//usage: "\n -I STR Replace STR within PROG ARGS with input line" +//usage: ) //usage: IF_FEATURE_XARGS_SUPPORT_TERMOPT( //usage: "\n -x Exit if size is exceeded" //usage: ) @@ -378,6 +452,8 @@ enum { IF_FEATURE_XARGS_SUPPORT_CONFIRMATION(OPTBIT_INTERACTIVE,) IF_FEATURE_XARGS_SUPPORT_TERMOPT( OPTBIT_TERMINATE ,) IF_FEATURE_XARGS_SUPPORT_ZERO_TERM( OPTBIT_ZEROTERM ,) + IF_FEATURE_XARGS_SUPPORT_REPL_STR( OPTBIT_REPLSTR ,) + IF_FEATURE_XARGS_SUPPORT_REPL_STR( OPTBIT_REPLSTR1 ,) OPT_VERBOSE = 1 << OPTBIT_VERBOSE , OPT_NO_EMPTY = 1 << OPTBIT_NO_EMPTY , @@ -388,11 +464,14 @@ enum { OPT_INTERACTIVE = IF_FEATURE_XARGS_SUPPORT_CONFIRMATION((1 << OPTBIT_INTERACTIVE)) + 0, OPT_TERMINATE = IF_FEATURE_XARGS_SUPPORT_TERMOPT( (1 << OPTBIT_TERMINATE )) + 0, OPT_ZEROTERM = IF_FEATURE_XARGS_SUPPORT_ZERO_TERM( (1 << OPTBIT_ZEROTERM )) + 0, + OPT_REPLSTR = IF_FEATURE_XARGS_SUPPORT_REPL_STR( (1 << OPTBIT_REPLSTR )) + 0, + OPT_REPLSTR1 = IF_FEATURE_XARGS_SUPPORT_REPL_STR( (1 << OPTBIT_REPLSTR1 )) + 0, }; #define OPTION_STR "+trn:s:e::E:" \ IF_FEATURE_XARGS_SUPPORT_CONFIRMATION("p") \ IF_FEATURE_XARGS_SUPPORT_TERMOPT( "x") \ - IF_FEATURE_XARGS_SUPPORT_ZERO_TERM( "0") + IF_FEATURE_XARGS_SUPPORT_ZERO_TERM( "0") \ + IF_FEATURE_XARGS_SUPPORT_REPL_STR( "I:i::") int xargs_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; int xargs_main(int argc, char **argv) @@ -405,7 +484,8 @@ int xargs_main(int argc, char **argv) unsigned opt; int n_max_chars; int n_max_arg; -#if ENABLE_FEATURE_XARGS_SUPPORT_ZERO_TERM +#if ENABLE_FEATURE_XARGS_SUPPORT_ZERO_TERM \ + || ENABLE_FEATURE_XARGS_SUPPORT_REPL_STR char* FAST_FUNC (*read_args)(int, int, char*) = process_stdin; #else #define read_args process_stdin @@ -419,7 +499,10 @@ int xargs_main(int argc, char **argv) "no-run-if-empty\0" No_argument "r" ; #endif - opt = getopt32(argv, OPTION_STR, &max_args, &max_chars, &G.eof_str, &G.eof_str); + opt = getopt32(argv, OPTION_STR, + &max_args, &max_chars, &G.eof_str, &G.eof_str + IF_FEATURE_XARGS_SUPPORT_REPL_STR(, &G.repl_str, &G.repl_str) + ); /* -E ""? You may wonder why not just omit -E? * This is used for portability: @@ -427,8 +510,10 @@ int xargs_main(int argc, char **argv) if ((opt & OPT_EOF_STRING1) && G.eof_str[0] == '\0') G.eof_str = NULL; - if (opt & OPT_ZEROTERM) - IF_FEATURE_XARGS_SUPPORT_ZERO_TERM(read_args = process0_stdin); + if (opt & OPT_ZEROTERM) { + IF_FEATURE_XARGS_SUPPORT_ZERO_TERM(read_args = process0_stdin;) + IF_FEATURE_XARGS_SUPPORT_REPL_STR(G.eol_ch = '\0';) + } argv += optind; argc -= optind; @@ -486,20 +571,36 @@ int xargs_main(int argc, char **argv) /* if (n_max_arg > n_max_chars) n_max_arg = n_max_chars */ } - /* Allocate pointers for execvp */ - /* We can statically allocate (argc + n_max_arg + 1) elements - * and do not bother with resizing args[], but on 64-bit machines - * this results in args[] vector which is ~8 times bigger - * than n_max_chars! That is, with n_max_chars == 20k, - * args[] will take 160k (!), which will most likely be - * almost entirely unused. - */ - /* See store_param() for matching 256-step growth logic */ - G.args = xmalloc(sizeof(G.args[0]) * ((argc + 0xff) & ~0xff)); - - /* Store the command to be executed, part 1 */ - for (i = 0; argv[i]; i++) - G.args[i] = argv[i]; +#if ENABLE_FEATURE_XARGS_SUPPORT_REPL_STR + if (opt & (OPT_REPLSTR | OPT_REPLSTR1)) { + /* + * -I: + * Unmodified args are kept in G.argv[i], + * G.args[i] receives malloced G.argv[i] with replaced + * with input line. Setting this up: + */ + G.args = NULL; + G.argv = argv; + argc = 0; + read_args = process_stdin_with_replace; + } else +#endif + { + /* Allocate pointers for execvp. + * We can statically allocate (argc + n_max_arg + 1) elements + * and do not bother with resizing args[], but on 64-bit machines + * this results in args[] vector which is ~8 times bigger + * than n_max_chars! That is, with n_max_chars == 20k, + * args[] will take 160k (!), which will most likely be + * almost entirely unused. + * + * See store_param() for matching 256-step growth logic + */ + G.args = xmalloc(sizeof(G.args[0]) * ((argc + 0xff) & ~0xff)); + /* Store the command to be executed, part 1 */ + for (i = 0; argv[i]; i++) + G.args[i] = argv[i]; + } while (1) { char *rem; diff --git a/include/libbb.h b/include/libbb.h index 96f33340e..1cbe2c8b4 100644 --- a/include/libbb.h +++ b/include/libbb.h @@ -650,6 +650,8 @@ char *xstrndup(const char *s, int n) FAST_FUNC RETURNS_MALLOC; void overlapping_strcpy(char *dst, const char *src) FAST_FUNC; char *safe_strncpy(char *dst, const char *src, size_t size) FAST_FUNC; char *strncpy_IFNAMSIZ(char *dst, const char *src) FAST_FUNC; +unsigned count_strstr(const char *str, const char *sub) FAST_FUNC; +char *xmalloc_substitute_string(const char *src, int count, const char *sub, const char *repl) FAST_FUNC; /* Guaranteed to NOT be a macro (smallest code). Saves nearly 2k on uclibc. * But potentially slow, don't use in one-billion-times loops */ int bb_putchar(int ch) FAST_FUNC; diff --git a/libbb/replace.c b/libbb/replace.c new file mode 100644 index 000000000..8711f957d --- /dev/null +++ b/libbb/replace.c @@ -0,0 +1,45 @@ +/* vi: set sw=4 ts=4: */ +/* + * Utility routines. + * + * Copyright (C) 1999-2004 by Erik Andersen + * + * Licensed under GPLv2 or later, see file LICENSE in this source tree. + */ + +//kbuild:lib-y += replace.o + +#include "libbb.h" + +unsigned FAST_FUNC count_strstr(const char *str, const char *sub) +{ + size_t sub_len = strlen(sub); + unsigned count = 0; + + while ((str = strstr(str, sub)) != NULL) { + count++; + str += sub_len; + } + return count; +} + +char* FAST_FUNC xmalloc_substitute_string(const char *src, int count, const char *sub, const char *repl) +{ + char *buf, *dst, *end; + size_t sub_len = strlen(sub); + size_t repl_len = strlen(repl); + + //dbg_msg("subst(s:'%s',count:%d,sub:'%s',repl:'%s'", src, count, sub, repl); + + buf = dst = xmalloc(strlen(src) + count * ((int)repl_len - (int)sub_len) + 1); + /* we replace each sub with repl */ + while ((end = strstr(src, sub)) != NULL) { + dst = mempcpy(dst, src, end - src); + dst = mempcpy(dst, repl, repl_len); + /*src = end + 1; - GNU findutils 4.5.10 doesn't do this... */ + src = end + sub_len; /* but this. Try "xargs -Iaa echo aaa" */ + } + strcpy(dst, src); + //dbg_msg("subst9:'%s'", buf); + return buf; +} -- cgit v1.2.3-55-g6feb From 83e49ade5724f5b3744660e45179461fe2a1b0f8 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Thu, 27 Feb 2014 14:56:12 +0100 Subject: grep: fix -w match if first match isn't a word, but second is. Closes 4520 Signed-off-by: Denys Vlasenko --- findutils/grep.c | 29 +++++++++++++++-------------- testsuite/grep.tests | 6 ++++++ 2 files changed, 21 insertions(+), 14 deletions(-) diff --git a/findutils/grep.c b/findutils/grep.c index 76859464f..f1b6dc694 100644 --- a/findutils/grep.c +++ b/findutils/grep.c @@ -418,13 +418,15 @@ static int grep_file(FILE *file) found = 1; } else { char c = ' '; - if (match_at > line || gl->matched_range.rm_so != 0) + if (match_at > line || gl->matched_range.rm_so != 0) { c = match_at[gl->matched_range.rm_so - 1]; + } if (!isalnum(c) && c != '_') { c = match_at[gl->matched_range.rm_eo]; - if (!c || (!isalnum(c) && c != '_')) { - found = 1; - } else { + } + if (!isalnum(c) && c != '_') { + found = 1; + } else { /* * Why check gl->matched_range.rm_eo? * Zero-length match makes -w skip the line: @@ -433,18 +435,17 @@ static int grep_file(FILE *file) * Without such check, we can loop forever. */ #if !ENABLE_EXTRA_COMPAT - if (gl->matched_range.rm_eo != 0) { - match_at += gl->matched_range.rm_eo; - match_flg |= REG_NOTBOL; - goto opt_w_again; - } + if (gl->matched_range.rm_eo != 0) { + match_at += gl->matched_range.rm_eo; + match_flg |= REG_NOTBOL; + goto opt_w_again; + } #else - if (gl->matched_range.rm_eo > start_pos) { - start_pos = gl->matched_range.rm_eo; - goto opt_w_again; - } -#endif + if (gl->matched_range.rm_eo > start_pos) { + start_pos = gl->matched_range.rm_eo; + goto opt_w_again; } +#endif } } } diff --git a/testsuite/grep.tests b/testsuite/grep.tests index 74b0eb63f..323b3849d 100755 --- a/testsuite/grep.tests +++ b/testsuite/grep.tests @@ -165,6 +165,12 @@ testing "grep -w word doesn't match wordword" \ "wordword\n" \ "" +testing "grep -w word match second word" \ + "grep -w word input" \ + "bword,word\n""wordb,word\n""bwordb,word\n" \ + "bword,word\n""wordb,word\n""bwordb,word\n" \ + "" + # testing "test name" "commands" "expected result" "file input" "stdin" # file input will be file called "input" # test can create a file "actual" instead of writing to stdout -- cgit v1.2.3-55-g6feb From 3795266841393c9d1cd34c62ccaecded6d7c3dfb Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Thu, 27 Feb 2014 15:02:36 +0100 Subject: xargs: fix compilation breakage Signed-off-by: Denys Vlasenko --- findutils/xargs.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/findutils/xargs.c b/findutils/xargs.c index ed6dbd33e..0ba5b566d 100644 --- a/findutils/xargs.c +++ b/findutils/xargs.c @@ -373,7 +373,7 @@ static char* FAST_FUNC process_stdin_with_replace(int n_max_chars, int n_max_arg char *arg = G.argv[i]; int count = count_strstr(arg, G.repl_str); if (count != 0) - arg = xmalloc_substitute_string(arg, count, G.repl_str, s); + arg = xmalloc_substitute_string(arg, count, G.repl_str, buf); store_param(arg); dbg_msg("args[]:'%s'", arg); i++; -- cgit v1.2.3-55-g6feb From fca0ee5959f212e46b9a5bb324a1482899172750 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Thu, 27 Feb 2014 15:40:26 +0100 Subject: ls: make "ls -s DIR" show total too. Clases 4946 Signed-off-by: Denys Vlasenko --- coreutils/ls.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/coreutils/ls.c b/coreutils/ls.c index 166473d4d..1b63be56d 100644 --- a/coreutils/ls.c +++ b/coreutils/ls.c @@ -1032,7 +1032,7 @@ static void scan_and_display_dirs_recur(struct dnode **dn, int first) } subdnp = scan_one_dir((*dn)->fullname, &nfiles); #if ENABLE_DESKTOP - if ((G.all_fmt & STYLE_MASK) == STYLE_LONG) + if ((G.all_fmt & STYLE_MASK) == STYLE_LONG || (G.all_fmt & LIST_BLOCKS)) printf("total %"OFF_FMT"u\n", calculate_blocks(subdnp)); #endif if (nfiles > 0) { -- cgit v1.2.3-55-g6feb From e2318bbad786d6f9ebff704490246bfe52e588c0 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Thu, 27 Feb 2014 18:15:50 +0100 Subject: udhcpc: ignore NAKs from "wrong" servers. Closes 4267 function old new delta udhcpc_main 2716 2814 +98 Signed-off-by: Denys Vlasenko --- networking/udhcp/dhcpc.c | 25 ++++++++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) diff --git a/networking/udhcp/dhcpc.c b/networking/udhcp/dhcpc.c index 25f18b35d..7dfc160e2 100644 --- a/networking/udhcp/dhcpc.c +++ b/networking/udhcp/dhcpc.c @@ -1232,7 +1232,7 @@ static void client_background(void) int udhcpc_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; int udhcpc_main(int argc UNUSED_PARAM, char **argv) { - uint8_t *temp, *message; + uint8_t *message; const char *str_V, *str_h, *str_F, *str_r; IF_FEATURE_UDHCP_PORT(char *str_P;) void *clientid_mac_ptr; @@ -1640,6 +1640,8 @@ int udhcpc_main(int argc UNUSED_PARAM, char **argv) case INIT_SELECTING: /* Must be a DHCPOFFER */ if (*message == DHCPOFFER) { + uint8_t *temp; + /* What exactly is server's IP? There are several values. * Example DHCP offer captured with tchdump: * @@ -1689,6 +1691,7 @@ int udhcpc_main(int argc UNUSED_PARAM, char **argv) if (*message == DHCPACK) { uint32_t lease_seconds; struct in_addr temp_addr; + uint8_t *temp; temp = udhcp_get_option(&packet, DHCP_LEASE_TIME); if (!temp) { @@ -1766,6 +1769,26 @@ int udhcpc_main(int argc UNUSED_PARAM, char **argv) continue; /* back to main loop */ } if (*message == DHCPNAK) { + /* If network has more than one DHCP server, + * "wrong" server can reply first, with a NAK. + * Do not interpret it as a NAK from "our" server. + */ + if (server_addr != 0) { + uint32_t svid; + uint8_t *temp; + + temp = udhcp_get_option(&packet, DHCP_SERVER_ID); + if (!temp) { + non_matching_svid: + log1("%s with wrong server ID, ignoring packet", + "Received DHCP NAK" + ); + continue; + } + move_from_unaligned32(svid, temp); + if (svid != server_addr) + goto non_matching_svid; + } /* return to init state */ bb_info_msg("Received DHCP NAK"); udhcp_run_script(&packet, "nak"); -- cgit v1.2.3-55-g6feb From 2108a6f0b56633fba1e70af406da147c02b11765 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Fri, 28 Feb 2014 15:05:43 +0100 Subject: unlzma: move some variables in "more local" scope No code changes as verified by objdump Signed-off-by: Denys Vlasenko --- archival/libarchive/decompress_unlzma.c | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/archival/libarchive/decompress_unlzma.c b/archival/libarchive/decompress_unlzma.c index ca32bd82c..a89b846a0 100644 --- a/archival/libarchive/decompress_unlzma.c +++ b/archival/libarchive/decompress_unlzma.c @@ -214,8 +214,6 @@ unpack_lzma_stream(transformer_aux_data_t *aux UNUSED_PARAM, int src_fd, int dst uint32_t pos_state_mask; uint32_t literal_pos_mask; uint16_t *p; - int num_bits; - int num_probs; rc_t *rc; int i; uint8_t *buffer; @@ -247,11 +245,15 @@ unpack_lzma_stream(transformer_aux_data_t *aux UNUSED_PARAM, int src_fd, int dst buffer = xmalloc(MIN(header.dst_size, header.dict_size)); - num_probs = LZMA_BASE_SIZE + (LZMA_LIT_SIZE << (lc + lp)); - p = xmalloc(num_probs * sizeof(*p)); - num_probs += LZMA_LITERAL - LZMA_BASE_SIZE; - for (i = 0; i < num_probs; i++) - p[i] = (1 << RC_MODEL_TOTAL_BITS) >> 1; + { + int num_probs; + + num_probs = LZMA_BASE_SIZE + (LZMA_LIT_SIZE << (lc + lp)); + p = xmalloc(num_probs * sizeof(*p)); + num_probs += LZMA_LITERAL - LZMA_BASE_SIZE; + for (i = 0; i < num_probs; i++) + p[i] = (1 << RC_MODEL_TOTAL_BITS) >> 1; + } rc = rc_init(src_fd); /*, RC_BUFFER_SIZE); */ @@ -310,6 +312,7 @@ unpack_lzma_stream(transformer_aux_data_t *aux UNUSED_PARAM, int src_fd, int dst goto one_byte2; #endif } else { + int num_bits; int offset; uint16_t *prob2; #define prob_len prob2 -- cgit v1.2.3-55-g6feb From 81071e6872eeb9e47b938d5d6fd82056aaebdd2e Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Fri, 28 Feb 2014 15:42:10 +0100 Subject: unlzma: add comments about possible bug from BZ 2689 Signed-off-by: Denys Vlasenko --- archival/libarchive/decompress_unlzma.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/archival/libarchive/decompress_unlzma.c b/archival/libarchive/decompress_unlzma.c index a89b846a0..3d99e1388 100644 --- a/archival/libarchive/decompress_unlzma.c +++ b/archival/libarchive/decompress_unlzma.c @@ -237,6 +237,9 @@ unpack_lzma_stream(transformer_aux_data_t *aux UNUSED_PARAM, int src_fd, int dst pos_state_mask = (1 << pb) - 1; literal_pos_mask = (1 << lp) - 1; + /* Example values from linux-3.3.4.tar.lzma: + * dict_size: 64M, dst_size: 2^64-1 + */ header.dict_size = SWAP_LE32(header.dict_size); header.dst_size = SWAP_LE64(header.dst_size); @@ -443,6 +446,9 @@ unpack_lzma_stream(transformer_aux_data_t *aux UNUSED_PARAM, int src_fd, int dst } len--; } while (len != 0 && buffer_pos < header.dst_size); + /* FIXME: ...........^^^^^ + * shouldn't it be "global_pos + buffer_pos < header.dst_size"? + */ } } -- cgit v1.2.3-55-g6feb From ecd8c3affcbf39de2bdbfe347ae014abb709ab5d Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Sat, 1 Mar 2014 17:38:41 +0100 Subject: ip link: add support for "address ETHADDR". Closes 4862 function old new delta do_iplink 2175 2289 +114 Signed-off-by: Denys Vlasenko --- networking/libiproute/iplink.c | 190 ++++++++++++++++++++++++++++++++++++++++- 1 file changed, 188 insertions(+), 2 deletions(-) diff --git a/networking/libiproute/iplink.c b/networking/libiproute/iplink.c index 506fb3c7e..5c27c2de3 100644 --- a/networking/libiproute/iplink.c +++ b/networking/libiproute/iplink.c @@ -46,6 +46,12 @@ struct ifla_vlan_flags { /* taken from linux/sockios.h */ #define SIOCSIFNAME 0x8923 /* set interface name */ +#if 0 +# define dbg(...) bb_error_msg(__VA_ARGS__) +#else +# define dbg(...) ((void)0) +#endif + /* Exits on error */ static int get_ctl_fd(void) { @@ -401,12 +407,13 @@ static void vlan_parse_opt(char **argv, struct nlmsghdr *n, unsigned int size) static int do_add_or_delete(char **argv, const unsigned rtm) { static const char keywords[] ALIGN1 = - "link\0""name\0""type\0""dev\0"; + "link\0""name\0""type\0""dev\0""address\0"; enum { ARG_link, ARG_name, ARG_type, ARG_dev, + ARG_address, }; struct rtnl_handle rth; struct { @@ -415,7 +422,11 @@ static int do_add_or_delete(char **argv, const unsigned rtm) char buf[1024]; } req; smalluint arg; - char *name_str = NULL, *link_str = NULL, *type_str = NULL, *dev_str = NULL; + char *name_str = NULL; + char *link_str = NULL; + char *type_str = NULL; + char *dev_str = NULL; + char *address_str = NULL; memset(&req, 0, sizeof(req)); @@ -431,14 +442,21 @@ static int do_add_or_delete(char **argv, const unsigned rtm) if (arg == ARG_type) { NEXT_ARG(); type_str = *argv++; + dbg("type_str:'%s'", type_str); break; } if (arg == ARG_link) { NEXT_ARG(); link_str = *argv; + dbg("link_str:'%s'", link_str); } else if (arg == ARG_name) { NEXT_ARG(); name_str = *argv; + dbg("name_str:'%s'", name_str); + } else if (arg == ARG_address) { + NEXT_ARG(); + address_str = *argv; + dbg("address_str:'%s'", name_str); } else { if (arg == ARG_dev) { if (dev_str) @@ -446,6 +464,7 @@ static int do_add_or_delete(char **argv, const unsigned rtm) NEXT_ARG(); } dev_str = *argv; + dbg("dev_str:'%s'", dev_str); } argv++; } @@ -481,6 +500,14 @@ static int do_add_or_delete(char **argv, const unsigned rtm) int idx = xll_name_to_index(link_str); addattr_l(&req.n, sizeof(req), IFLA_LINK, &idx, 4); } + if (address_str) { + unsigned char abuf[32]; + int len = ll_addr_a2n(abuf, sizeof(abuf), address_str); + dbg("address len:%d", len); + if (len < 0) + return -1; + addattr_l(&req.n, sizeof(req), IFLA_ADDRESS, abuf, len); + } } if (name_str) { const size_t name_len = strlen(name_str) + 1; @@ -493,6 +520,165 @@ static int do_add_or_delete(char **argv, const unsigned rtm) return 0; } +/* Other keywords recognized by iproute2-3.12.0: */ +#if 0 + } else if (matches(*argv, "broadcast") == 0 || + strcmp(*argv, "brd") == 0) { + NEXT_ARG(); + len = ll_addr_a2n(abuf, sizeof(abuf), *argv); + if (len < 0) + return -1; + addattr_l(&req->n, sizeof(*req), IFLA_BROADCAST, abuf, len); + } else if (matches(*argv, "txqueuelen") == 0 || + strcmp(*argv, "qlen") == 0 || + matches(*argv, "txqlen") == 0) { + NEXT_ARG(); + if (qlen != -1) + duparg("txqueuelen", *argv); + if (get_integer(&qlen, *argv, 0)) + invarg("Invalid \"txqueuelen\" value\n", *argv); + addattr_l(&req->n, sizeof(*req), IFLA_TXQLEN, &qlen, 4); + } else if (strcmp(*argv, "mtu") == 0) { + NEXT_ARG(); + if (mtu != -1) + duparg("mtu", *argv); + if (get_integer(&mtu, *argv, 0)) + invarg("Invalid \"mtu\" value\n", *argv); + addattr_l(&req->n, sizeof(*req), IFLA_MTU, &mtu, 4); + } else if (strcmp(*argv, "netns") == 0) { + NEXT_ARG(); + if (netns != -1) + duparg("netns", *argv); + if ((netns = get_netns_fd(*argv)) >= 0) + addattr_l(&req->n, sizeof(*req), IFLA_NET_NS_FD, &netns, 4); + else if (get_integer(&netns, *argv, 0) == 0) + addattr_l(&req->n, sizeof(*req), IFLA_NET_NS_PID, &netns, 4); + else + invarg("Invalid \"netns\" value\n", *argv); + } else if (strcmp(*argv, "multicast") == 0) { + NEXT_ARG(); + req->i.ifi_change |= IFF_MULTICAST; + if (strcmp(*argv, "on") == 0) { + req->i.ifi_flags |= IFF_MULTICAST; + } else if (strcmp(*argv, "off") == 0) { + req->i.ifi_flags &= ~IFF_MULTICAST; + } else + return on_off("multicast", *argv); + } else if (strcmp(*argv, "allmulticast") == 0) { + NEXT_ARG(); + req->i.ifi_change |= IFF_ALLMULTI; + if (strcmp(*argv, "on") == 0) { + req->i.ifi_flags |= IFF_ALLMULTI; + } else if (strcmp(*argv, "off") == 0) { + req->i.ifi_flags &= ~IFF_ALLMULTI; + } else + return on_off("allmulticast", *argv); + } else if (strcmp(*argv, "promisc") == 0) { + NEXT_ARG(); + req->i.ifi_change |= IFF_PROMISC; + if (strcmp(*argv, "on") == 0) { + req->i.ifi_flags |= IFF_PROMISC; + } else if (strcmp(*argv, "off") == 0) { + req->i.ifi_flags &= ~IFF_PROMISC; + } else + return on_off("promisc", *argv); + } else if (strcmp(*argv, "trailers") == 0) { + NEXT_ARG(); + req->i.ifi_change |= IFF_NOTRAILERS; + if (strcmp(*argv, "off") == 0) { + req->i.ifi_flags |= IFF_NOTRAILERS; + } else if (strcmp(*argv, "on") == 0) { + req->i.ifi_flags &= ~IFF_NOTRAILERS; + } else + return on_off("trailers", *argv); + } else if (strcmp(*argv, "arp") == 0) { + NEXT_ARG(); + req->i.ifi_change |= IFF_NOARP; + if (strcmp(*argv, "on") == 0) { + req->i.ifi_flags &= ~IFF_NOARP; + } else if (strcmp(*argv, "off") == 0) { + req->i.ifi_flags |= IFF_NOARP; + } else + return on_off("noarp", *argv); + } else if (strcmp(*argv, "vf") == 0) { + struct rtattr *vflist; + NEXT_ARG(); + if (get_integer(&vf, *argv, 0)) { + invarg("Invalid \"vf\" value\n", *argv); + } + vflist = addattr_nest(&req->n, sizeof(*req), + IFLA_VFINFO_LIST); + len = iplink_parse_vf(vf, &argc, &argv, req); + if (len < 0) + return -1; + addattr_nest_end(&req->n, vflist); + } else if (matches(*argv, "master") == 0) { + int ifindex; + NEXT_ARG(); + ifindex = ll_name_to_index(*argv); + if (!ifindex) + invarg("Device does not exist\n", *argv); + addattr_l(&req->n, sizeof(*req), IFLA_MASTER, + &ifindex, 4); + } else if (matches(*argv, "nomaster") == 0) { + int ifindex = 0; + addattr_l(&req->n, sizeof(*req), IFLA_MASTER, + &ifindex, 4); + } else if (matches(*argv, "dynamic") == 0) { + NEXT_ARG(); + req->i.ifi_change |= IFF_DYNAMIC; + if (strcmp(*argv, "on") == 0) { + req->i.ifi_flags |= IFF_DYNAMIC; + } else if (strcmp(*argv, "off") == 0) { + req->i.ifi_flags &= ~IFF_DYNAMIC; + } else + return on_off("dynamic", *argv); + } else if (matches(*argv, "alias") == 0) { + NEXT_ARG(); + addattr_l(&req->n, sizeof(*req), IFLA_IFALIAS, + *argv, strlen(*argv)); + argc--; argv++; + break; + } else if (strcmp(*argv, "group") == 0) { + NEXT_ARG(); + if (*group != -1) + duparg("group", *argv); + if (rtnl_group_a2n(group, *argv)) + invarg("Invalid \"group\" value\n", *argv); + } else if (strcmp(*argv, "mode") == 0) { + int mode; + NEXT_ARG(); + mode = get_link_mode(*argv); + if (mode < 0) + invarg("Invalid link mode\n", *argv); + addattr8(&req->n, sizeof(*req), IFLA_LINKMODE, mode); + } else if (strcmp(*argv, "state") == 0) { + int state; + NEXT_ARG(); + state = get_operstate(*argv); + if (state < 0) + invarg("Invalid operstate\n", *argv); + + addattr8(&req->n, sizeof(*req), IFLA_OPERSTATE, state); + } else if (matches(*argv, "numtxqueues") == 0) { + NEXT_ARG(); + if (numtxqueues != -1) + duparg("numtxqueues", *argv); + if (get_integer(&numtxqueues, *argv, 0)) + invarg("Invalid \"numtxqueues\" value\n", *argv); + addattr_l(&req->n, sizeof(*req), IFLA_NUM_TX_QUEUES, + &numtxqueues, 4); + } else if (matches(*argv, "numrxqueues") == 0) { + NEXT_ARG(); + if (numrxqueues != -1) + duparg("numrxqueues", *argv); + if (get_integer(&numrxqueues, *argv, 0)) + invarg("Invalid \"numrxqueues\" value\n", *argv); + addattr_l(&req->n, sizeof(*req), IFLA_NUM_RX_QUEUES, + &numrxqueues, 4); + } +#endif + /* Return value becomes exitcode. It's okay to not return at all */ int FAST_FUNC do_iplink(char **argv) { -- cgit v1.2.3-55-g6feb From 30f17e9556e9a415616515db738c063159d662a8 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Mon, 3 Mar 2014 15:13:37 +0100 Subject: man: default to ascii Default to ascii instead of latin1. Otherwise man pages can be displayed incorrectly. E.g. bullets show as "". Signed-off-by: Aaro Koskinen Signed-off-by: Denys Vlasenko --- miscutils/man.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/miscutils/man.c b/miscutils/man.c index f046e24f3..5c1fa2c9d 100644 --- a/miscutils/man.c +++ b/miscutils/man.c @@ -106,7 +106,8 @@ static int run_pipe(const char *pager, char *man_filename, int man, int level) /* "2>&1" is added so that nroff errors are shown in pager too. * Otherwise it may show just empty screen */ cmd = xasprintf( - man ? "gtbl | nroff -Tlatin1 -mandoc 2>&1 | %s" + /* replaced -Tlatin1 with -Tascii for non-UTF8 displays */ + man ? "gtbl | nroff -Tascii -mandoc 2>&1 | %s" : "%s", pager); system(cmd); -- cgit v1.2.3-55-g6feb From 2cdcb1082c3de109eef564795feb5e8a368a88cf Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Wed, 5 Mar 2014 18:56:20 +0100 Subject: shuf: new applet function old new delta shuf_main - 478 +478 packed_usage 29571 29719 +148 applet_names 2460 2465 +5 applet_main 1428 1432 +4 applet_nameofs 714 716 +2 ------------------------------------------------------------------------------ (add/remove: 2/0 grow/shrink: 4/0 up/down: 637/0) Total: 637 bytes Based on the code by Bartosz Golaszewski Signed-off-by: Denys Vlasenko --- coreutils/shuf.c | 150 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 150 insertions(+) create mode 100644 coreutils/shuf.c diff --git a/coreutils/shuf.c b/coreutils/shuf.c new file mode 100644 index 000000000..f213d6759 --- /dev/null +++ b/coreutils/shuf.c @@ -0,0 +1,150 @@ +/* vi: set sw=4 ts=4: */ +/* + * shuf: Write a random permutation of the input lines to standard output. + * + * Copyright (C) 2014 by Bartosz Golaszewski + * + * Licensed under GPLv2 or later, see file LICENSE in this source tree. + */ + +//config:config SHUF +//config: bool "shuf" +//config: default y +//config: help +//config: Generate random permutations + +//kbuild:lib-$(CONFIG_SHUF) += shuf.o +//applet:IF_SHUF(APPLET_NOEXEC(shuf, shuf, BB_DIR_USR_BIN, BB_SUID_DROP, shuf)) + +//usage:#define shuf_trivial_usage +//usage: "[-e|-i LO-HI] [-n NUM] [-o FILE] [-z] [FILE|ARG...]" +//usage:#define shuf_full_usage "\n\n" +//usage: "Write a random permutation of the input lines to standard output\n" +//usage: "\n -e Treat each ARG as an input line" +//usage: "\n -i L-H Treat each number L through H as an input line" +//usage: "\n -n NUM Output at most NUM lines" +//usage: "\n -o Write result to FILE instead of standard output" +//usage: "\n -z End lines with zero byte, not newline" + +#include "libbb.h" + +/* This is a NOEXEC applet. Be very careful! */ + +#define OPT_e (1 << 0) +#define OPT_i (1 << 1) +#define OPT_n (1 << 2) +#define OPT_o (1 << 3) +#define OPT_z (1 << 4) +#define OPT_STR "ei:n:o:z" + +/* + * Use the Fisher-Yates shuffle algorithm on an array of lines. + */ +static void shuffle_lines(char **lines, unsigned numlines) +{ + unsigned i; + unsigned r; + char *tmp; + + srand(monotonic_us()); + + for (i = numlines-1; i > 0; i--) { + r = rand(); + /* RAND_MAX can be as small as 32767 */ + if (i > RAND_MAX) + r ^= rand() << 15; + r %= i; + tmp = lines[i]; + lines[i] = lines[r]; + lines[r] = tmp; + } +} + +int shuf_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; +int shuf_main(int argc, char **argv) +{ + unsigned opts; + char *opt_i_str, *opt_n_str, *opt_o_str; + unsigned i; + char **lines; + unsigned numlines; + char eol; + + opt_complementary = "e--i:i--e"; /* mutually exclusive */ + opts = getopt32(argv, OPT_STR, &opt_i_str, &opt_n_str, &opt_o_str); + + argc -= optind; + argv += optind; + + /* Prepare lines for shuffling - either: */ + if (opts & OPT_e) { + /* make lines from command-line arguments */ + + numlines = argc; + lines = argv; + } else + if (opts & OPT_i) { + /* create a range of numbers */ + char *dash; + unsigned lo, hi; + + dash = strchr(opt_i_str, '-'); + if (!dash) { + bb_error_msg_and_die("bad range '%s'", opt_i_str); + } + *dash = '\0'; + lo = xatou(opt_i_str); + hi = xatou(dash + 1); + *dash = '-'; + if (hi < lo) { + bb_error_msg_and_die("bad range '%s'", opt_i_str); + } + + numlines = (hi+1) - lo; + lines = xmalloc(numlines * sizeof(lines[0])); + for (i = 0; i < numlines; i++) { + lines[i] = xstrdup(utoa(lo)); + lo++; + } + } else { + /* default - read lines from stdin or the input file */ + FILE *fp; + + if (argc > 1) + bb_show_usage(); + + fp = xfopen_stdin(argv[0] ? argv[0] : "-"); + lines = NULL; + numlines = 0; + for (;;) { + char *line = xmalloc_fgetline(fp); + if (!line) + break; + lines = xrealloc_vector(lines, 6, numlines); + lines[numlines++] = line; + } + fclose_if_not_stdin(fp); + } + + shuffle_lines(lines, numlines); + + if (opts & OPT_o) + xmove_fd(xopen(opt_o_str, O_WRONLY|O_CREAT|O_TRUNC), STDOUT_FILENO); + + if (opts & OPT_n) { + unsigned maxlines; + maxlines = xatou(opt_n_str); + if (numlines > maxlines) + numlines = maxlines; + } + + eol = '\n'; + if (opts & OPT_z) + eol = '\0'; + + for (i = 0; i < numlines; i++) { + printf("%s%c", lines[i], eol); + } + + fflush_stdout_and_exit(EXIT_SUCCESS); +} -- cgit v1.2.3-55-g6feb From 0ed5f7aacd5e412d80524a1fc7f90b55f470827b Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Wed, 5 Mar 2014 18:58:15 +0100 Subject: use [s]rand(), not [s]random() rand() is the most standard C library function, and on uclibc they are the same. I guess they are the same in most todays' libc... Signed-off-by: Denys Vlasenko --- networking/ntpd.c | 10 +++++----- networking/ntpd_simple.c | 10 +++++----- util-linux/mkfs_reiser.c | 4 ++-- 3 files changed, 12 insertions(+), 12 deletions(-) diff --git a/networking/ntpd.c b/networking/ntpd.c index bf8ef0a89..44592ce54 100644 --- a/networking/ntpd.c +++ b/networking/ntpd.c @@ -827,8 +827,8 @@ send_query_to_peer(peer_t *p) * * Save the real transmit timestamp locally. */ - p->p_xmt_msg.m_xmttime.int_partl = random(); - p->p_xmt_msg.m_xmttime.fractionl = random(); + p->p_xmt_msg.m_xmttime.int_partl = rand(); + p->p_xmt_msg.m_xmttime.fractionl = rand(); p->p_xmttime = gettime1900d(); /* Were doing it only if sendto worked, but @@ -1652,7 +1652,7 @@ retry_interval(void) /* Local problem, want to retry soon */ unsigned interval, r; interval = RETRY_INTERVAL; - r = random(); + r = rand(); interval += r % (unsigned)(RETRY_INTERVAL / 4); VERB4 bb_error_msg("chose retry interval:%u", interval); return interval; @@ -1666,7 +1666,7 @@ poll_interval(int exponent) exponent = 0; interval = 1 << exponent; mask = ((interval-1) >> 4) | 1; - r = random(); + r = rand(); interval += r & mask; /* ~ random(0..1) * interval/16 */ VERB4 bb_error_msg("chose poll interval:%u (poll_exp:%d exp:%d)", interval, G.poll_exp, exponent); return interval; @@ -2067,7 +2067,7 @@ static NOINLINE void ntp_init(char **argv) unsigned opts; llist_t *peers; - srandom(getpid()); + srand(getpid()); if (getuid()) bb_error_msg_and_die(bb_msg_you_must_be_root); diff --git a/networking/ntpd_simple.c b/networking/ntpd_simple.c index 22e899cb6..2cfbd55d4 100644 --- a/networking/ntpd_simple.c +++ b/networking/ntpd_simple.c @@ -248,7 +248,7 @@ error_interval(void) { unsigned interval, r; interval = INTERVAL_QUERY_PATHETIC * QSCALE_OFF_MAX / QSCALE_OFF_MIN; - r = (unsigned)random() % (unsigned)(interval / 10); + r = (unsigned)rand() % (unsigned)(interval / 10); return (interval + r); } @@ -326,8 +326,8 @@ send_query_to_peer(peer_t *p) * * Save the real transmit timestamp locally. */ - p->p_xmt_msg.m_xmttime.int_partl = random(); - p->p_xmt_msg.m_xmttime.fractionl = random(); + p->p_xmt_msg.m_xmttime.int_partl = rand(); + p->p_xmt_msg.m_xmttime.fractionl = rand(); p->p_xmttime = gettime1900d(); if (do_sendto(p->p_fd, /*from:*/ NULL, /*to:*/ &p->p_lsa->u.sa, /*addrlen:*/ p->p_lsa->len, @@ -531,7 +531,7 @@ scale_interval(unsigned requested) { unsigned interval, r; interval = requested * G.scale; - r = (unsigned)random() % (unsigned)(MAX(5, interval / 10)); + r = (unsigned)rand() % (unsigned)(MAX(5, interval / 10)); return (interval + r); } static void @@ -825,7 +825,7 @@ static NOINLINE void ntp_init(char **argv) unsigned opts; llist_t *peers; - srandom(getpid()); + srand(getpid()); if (getuid()) bb_error_msg_and_die(bb_msg_you_must_be_root); diff --git a/util-linux/mkfs_reiser.c b/util-linux/mkfs_reiser.c index b4efb9e9f..13abaa889 100644 --- a/util-linux/mkfs_reiser.c +++ b/util-linux/mkfs_reiser.c @@ -224,8 +224,8 @@ int mkfs_reiser_main(int argc UNUSED_PARAM, char **argv) jp = &sb->sb_journal; STORE_LE(jp->jp_journal_1st_block, REISERFS_DISK_OFFSET_IN_BYTES / blocksize + 1/*sb*/ + 1/*bmp#0*/); timestamp = time(NULL); - srandom(timestamp); - STORE_LE(jp->jp_journal_magic, random()); + srand(timestamp); + STORE_LE(jp->jp_journal_magic, rand()); STORE_LE(jp->jp_journal_size, journal_blocks); STORE_LE(jp->jp_journal_trans_max, JOURNAL_TRANS_MAX); STORE_LE(jp->jp_journal_max_batch, JOURNAL_MAX_BATCH); -- cgit v1.2.3-55-g6feb From 58adbb5505d0c643c18d956934aa8afa18e612eb Mon Sep 17 00:00:00 2001 From: Bartosz Golaszewski Date: Fri, 7 Mar 2014 11:46:03 +0100 Subject: shuf: fix a segfault on 'shuf -e' Signed-off-by: Bartosz Golaszewski Signed-off-by: Denys Vlasenko --- coreutils/shuf.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/coreutils/shuf.c b/coreutils/shuf.c index f213d6759..648a4abbb 100644 --- a/coreutils/shuf.c +++ b/coreutils/shuf.c @@ -126,7 +126,8 @@ int shuf_main(int argc, char **argv) fclose_if_not_stdin(fp); } - shuffle_lines(lines, numlines); + if (numlines != 0) + shuffle_lines(lines, numlines); if (opts & OPT_o) xmove_fd(xopen(opt_o_str, O_WRONLY|O_CREAT|O_TRUNC), STDOUT_FILENO); -- cgit v1.2.3-55-g6feb From 190693ced1bb82d96c5dedbe850840aae9246a5c Mon Sep 17 00:00:00 2001 From: Bartosz Golaszewski Date: Fri, 7 Mar 2014 14:07:35 +0100 Subject: shuf: improve help text Signed-off-by: Bartosz Golaszewski Signed-off-by: Denys Vlasenko --- coreutils/shuf.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/coreutils/shuf.c b/coreutils/shuf.c index 648a4abbb..e0c2fbf1f 100644 --- a/coreutils/shuf.c +++ b/coreutils/shuf.c @@ -17,13 +17,13 @@ //applet:IF_SHUF(APPLET_NOEXEC(shuf, shuf, BB_DIR_USR_BIN, BB_SUID_DROP, shuf)) //usage:#define shuf_trivial_usage -//usage: "[-e|-i LO-HI] [-n NUM] [-o FILE] [-z] [FILE|ARG...]" +//usage: "[-e|-i L-H] [-n NUM] [-o FILE] [-z] [FILE|ARG...]" //usage:#define shuf_full_usage "\n\n" //usage: "Write a random permutation of the input lines to standard output\n" //usage: "\n -e Treat each ARG as an input line" -//usage: "\n -i L-H Treat each number L through H as an input line" +//usage: "\n -i L-H Treat numbers L-H as an input line" //usage: "\n -n NUM Output at most NUM lines" -//usage: "\n -o Write result to FILE instead of standard output" +//usage: "\n -o FILE Write to FILE instead of standard output" //usage: "\n -z End lines with zero byte, not newline" #include "libbb.h" -- cgit v1.2.3-55-g6feb From 102f0d0d073c4781b5a58f679bdfd0999eea5e71 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Fri, 7 Mar 2014 14:32:39 +0100 Subject: shuf: do not use strings for -i RANGE case function old new delta shuf_main 482 496 +14 Signed-off-by: Denys Vlasenko --- coreutils/shuf.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/coreutils/shuf.c b/coreutils/shuf.c index e0c2fbf1f..d1cd39db7 100644 --- a/coreutils/shuf.c +++ b/coreutils/shuf.c @@ -79,7 +79,6 @@ int shuf_main(int argc, char **argv) /* Prepare lines for shuffling - either: */ if (opts & OPT_e) { /* make lines from command-line arguments */ - numlines = argc; lines = argv; } else @@ -103,7 +102,7 @@ int shuf_main(int argc, char **argv) numlines = (hi+1) - lo; lines = xmalloc(numlines * sizeof(lines[0])); for (i = 0; i < numlines; i++) { - lines[i] = xstrdup(utoa(lo)); + lines[i] = (char*)(uintptr_t)lo; lo++; } } else { @@ -144,7 +143,10 @@ int shuf_main(int argc, char **argv) eol = '\0'; for (i = 0; i < numlines; i++) { - printf("%s%c", lines[i], eol); + if (opts & OPT_i) + printf("%u%c", (unsigned)(uintptr_t)lines[i], eol); + else + printf("%s%c", lines[i], eol); } fflush_stdout_and_exit(EXIT_SUCCESS); -- cgit v1.2.3-55-g6feb From 69f9567de28976cfbc7b216c46aa391ce82bd3b7 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Fri, 7 Mar 2014 14:41:53 +0100 Subject: shuf: trim help text Signed-off-by: Denys Vlasenko --- coreutils/shuf.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/coreutils/shuf.c b/coreutils/shuf.c index d1cd39db7..6d0a68fc1 100644 --- a/coreutils/shuf.c +++ b/coreutils/shuf.c @@ -19,11 +19,11 @@ //usage:#define shuf_trivial_usage //usage: "[-e|-i L-H] [-n NUM] [-o FILE] [-z] [FILE|ARG...]" //usage:#define shuf_full_usage "\n\n" -//usage: "Write a random permutation of the input lines to standard output\n" -//usage: "\n -e Treat each ARG as an input line" -//usage: "\n -i L-H Treat numbers L-H as an input line" +//usage: "Randomly permute lines\n" +//usage: "\n -e Treat ARGs as lines" +//usage: "\n -i L-H Treat numbers L-H as lines" //usage: "\n -n NUM Output at most NUM lines" -//usage: "\n -o FILE Write to FILE instead of standard output" +//usage: "\n -o FILE Write to FILE, not standard output" //usage: "\n -z End lines with zero byte, not newline" #include "libbb.h" -- cgit v1.2.3-55-g6feb