From 8b141ebd456f6899133c53f0cf833c09a922a6cf Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Sat, 13 Aug 2011 08:56:58 +0200 Subject: Start 1.20.0 development cycle Signed-off-by: Denys Vlasenko --- Makefile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Makefile b/Makefile index 7a1abda1b..35d2e1e00 100644 --- a/Makefile +++ b/Makefile @@ -1,7 +1,7 @@ VERSION = 1 -PATCHLEVEL = 19 +PATCHLEVEL = 20 SUBLEVEL = 0 -EXTRAVERSION = +EXTRAVERSION = .git NAME = Unnamed # *DOCUMENTATION* -- cgit v1.2.3-55-g6feb From c97578de6b283592265fd9132df7d878f6ec6530 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Sat, 13 Aug 2011 09:00:29 +0200 Subject: conspy,nandwrite,nanddump: enable in defconfig Signed-off-by: Denys Vlasenko --- miscutils/conspy.c | 2 +- miscutils/nandwrite.c | 16 ++++++++-------- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/miscutils/conspy.c b/miscutils/conspy.c index 433c3e829..c6ed91832 100644 --- a/miscutils/conspy.c +++ b/miscutils/conspy.c @@ -16,7 +16,7 @@ //config:config CONSPY //config: bool "conspy" -//config: default n +//config: default y //config: select PLATFORM_LINUX //config: help //config: A text-mode VNC like program for Linux virtual terminals. diff --git a/miscutils/nandwrite.c b/miscutils/nandwrite.c index 562a34278..2ba6e3fe5 100644 --- a/miscutils/nandwrite.c +++ b/miscutils/nandwrite.c @@ -8,26 +8,26 @@ * TODO: add support for large (>4GB) MTD devices */ -//applet:IF_NANDWRITE(APPLET(nandwrite, BB_DIR_USR_SBIN, BB_SUID_DROP)) -//applet:IF_NANDWRITE(APPLET_ODDNAME(nanddump, nandwrite, BB_DIR_USR_SBIN, BB_SUID_DROP, nanddump)) - -//kbuild:lib-$(CONFIG_NANDWRITE) += nandwrite.o -//kbuild:lib-$(CONFIG_NANDDUMP) += nandwrite.o - //config:config NANDWRITE //config: bool "nandwrite" -//config: default n +//config: default y //config: select PLATFORM_LINUX //config: help //config: Write to the specified MTD device, with bad blocks awareness //config: //config:config NANDDUMP //config: bool "nanddump" -//config: default n +//config: default y //config: select PLATFORM_LINUX //config: help //config: Dump the content of raw NAND chip +//applet:IF_NANDWRITE(APPLET(nandwrite, BB_DIR_USR_SBIN, BB_SUID_DROP)) +//applet:IF_NANDWRITE(APPLET_ODDNAME(nanddump, nandwrite, BB_DIR_USR_SBIN, BB_SUID_DROP, nanddump)) + +//kbuild:lib-$(CONFIG_NANDWRITE) += nandwrite.o +//kbuild:lib-$(CONFIG_NANDDUMP) += nandwrite.o + //usage:#define nandwrite_trivial_usage //usage: "[-p] [-s ADDR] MTD_DEVICE [FILE]" //usage:#define nandwrite_full_usage "\n\n" -- cgit v1.2.3-55-g6feb From c21c310e4646579d34bb9db25745b1121dc364d5 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Sat, 13 Aug 2011 23:36:36 +0200 Subject: swapoff: dont pass "p" in opt_complementary Signed-off-by: Denys Vlasenko --- util-linux/swaponoff.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/util-linux/swaponoff.c b/util-linux/swaponoff.c index 43ddb4031..e53e24c71 100644 --- a/util-linux/swaponoff.c +++ b/util-linux/swaponoff.c @@ -114,7 +114,8 @@ int swap_on_off_main(int argc UNUSED_PARAM, char **argv) #if !ENABLE_FEATURE_SWAPON_PRI ret = getopt32(argv, "a"); #else - opt_complementary = "p+"; + if (applet_name[5] == 'n') + opt_complementary = "p+"; ret = getopt32(argv, (applet_name[5] == 'n') ? "ap:" : "a", &g_flags); if (ret & 2) { // -p -- cgit v1.2.3-55-g6feb From 4f54168ea21216f1ca322d343a26ee3e568444d9 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Tue, 16 Aug 2011 01:53:12 +0200 Subject: less: fix for screen size detection Signed-off-by: Denys Vlasenko --- miscutils/less.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/miscutils/less.c b/miscutils/less.c index 9543fb9f9..2c6a79326 100644 --- a/miscutils/less.c +++ b/miscutils/less.c @@ -990,7 +990,8 @@ static int64_t less_getch(int pos) */ if (key >= 0 && key < ' ' && key != 0x0d && key != 8) goto again; - return key; + + return key64; } static char* less_gets(int sz) -- cgit v1.2.3-55-g6feb From a7d6bb3b5df1a0a2be2f48583ffc01b1f62d73af Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Tue, 16 Aug 2011 13:29:34 +0200 Subject: sed: fix range handling for sed -i. Closes 4069 function old new delta sed_main 606 618 +12 add_cmd 1099 1101 +2 process_files 2108 2099 -9 ------------------------------------------------------------------------------ (add/remove: 0/0 grow/shrink: 2/1 up/down: 14/-9) Total: 5 bytes Signed-off-by: Denys Vlasenko --- editors/sed.c | 79 ++++++++++++++++++++++++++++++++++------------------- testsuite/sed.tests | 10 +++++-- 2 files changed, 58 insertions(+), 31 deletions(-) diff --git a/editors/sed.c b/editors/sed.c index 5c4e9cc3b..1552cf370 100644 --- a/editors/sed.c +++ b/editors/sed.c @@ -75,6 +75,13 @@ #include "libbb.h" #include "xregex.h" +#if 0 +# define dbg(...) bb_error_msg(__VA_ARGS__) +#else +# define dbg(...) ((void)0) +#endif + + enum { OPT_in_place = 1 << 0, }; @@ -89,6 +96,7 @@ typedef struct sed_cmd_s { regex_t *end_match; /* sed -e '/match/,/end_match/cmd' */ regex_t *sub_match; /* For 's/sub_match/string/' */ int beg_line; /* 'sed 1p' 0 == apply commands to all lines */ + int beg_line_orig; /* copy of the above, needed for -i */ int end_line; /* 'sed 1,3p' 0 == one line only. -1 = last line ($) */ FILE *sw_file; /* File (sw) command writes to, -1 for none. */ @@ -123,7 +131,7 @@ struct globals { regex_t *previous_regex_ptr; /* linked list of sed commands */ - sed_cmd_t sed_cmd_head, *sed_cmd_tail; + sed_cmd_t *sed_cmd_head, **sed_cmd_tail; /* Linked list of append lines */ llist_t *append_head; @@ -148,7 +156,7 @@ struct BUG_G_too_big { #if ENABLE_FEATURE_CLEAN_UP static void sed_free_and_close_stuff(void) { - sed_cmd_t *sed_cmd = G.sed_cmd_head.next; + sed_cmd_t *sed_cmd = G.sed_cmd_head; llist_free(G.append_head, free); @@ -599,6 +607,7 @@ static void add_cmd(const char *cmdstr) /* first part (if present) is an address: either a '$', a number or a /regex/ */ cmdstr += get_address(cmdstr, &sed_cmd->beg_line, &sed_cmd->beg_match); + sed_cmd->beg_line_orig = sed_cmd->beg_line; /* second part (if present) will begin with a comma */ if (*cmdstr == ',') { @@ -630,8 +639,8 @@ static void add_cmd(const char *cmdstr) cmdstr = parse_cmd_args(sed_cmd, cmdstr); /* Add the command to the command array */ - G.sed_cmd_tail->next = sed_cmd; - G.sed_cmd_tail = G.sed_cmd_tail->next; + *G.sed_cmd_tail = sed_cmd; + G.sed_cmd_tail = &sed_cmd->next; } /* If we glued multiple lines together, free the memory. */ @@ -777,7 +786,7 @@ static sed_cmd_t *branch_to(char *label) { sed_cmd_t *sed_cmd; - for (sed_cmd = G.sed_cmd_head.next; sed_cmd; sed_cmd = sed_cmd->next) { + for (sed_cmd = G.sed_cmd_head; sed_cmd; sed_cmd = sed_cmd->next) { if (sed_cmd->cmd == ':' && sed_cmd->string && !strcmp(sed_cmd->string, label)) { return sed_cmd; } @@ -953,24 +962,24 @@ static void process_files(void) /* For every line, go through all the commands */ restart: - for (sed_cmd = G.sed_cmd_head.next; sed_cmd; sed_cmd = sed_cmd->next) { + for (sed_cmd = G.sed_cmd_head; sed_cmd; sed_cmd = sed_cmd->next) { int old_matched, matched; old_matched = sed_cmd->in_match; /* Determine if this command matches this line: */ - //bb_error_msg("match1:%d", sed_cmd->in_match); - //bb_error_msg("match2:%d", (!sed_cmd->beg_line && !sed_cmd->end_line - // && !sed_cmd->beg_match && !sed_cmd->end_match)); - //bb_error_msg("match3:%d", (sed_cmd->beg_line > 0 - // && (sed_cmd->end_line || sed_cmd->end_match - // ? (sed_cmd->beg_line <= linenum) - // : (sed_cmd->beg_line == linenum) - // ) - // ) - //bb_error_msg("match4:%d", (beg_match(sed_cmd, pattern_space))); - //bb_error_msg("match5:%d", (sed_cmd->beg_line == -1 && next_line == NULL)); + dbg("match1:%d", sed_cmd->in_match); + dbg("match2:%d", (!sed_cmd->beg_line && !sed_cmd->end_line + && !sed_cmd->beg_match && !sed_cmd->end_match)); + dbg("match3:%d", (sed_cmd->beg_line > 0 + && (sed_cmd->end_line || sed_cmd->end_match + ? (sed_cmd->beg_line <= linenum) + : (sed_cmd->beg_line == linenum) + ) + )); + dbg("match4:%d", (beg_match(sed_cmd, pattern_space))); + dbg("match5:%d", (sed_cmd->beg_line == -1 && next_line == NULL)); /* Are we continuing a previous multi-line match? */ sed_cmd->in_match = sed_cmd->in_match @@ -981,7 +990,14 @@ static void process_files(void) || (sed_cmd->beg_line > 0 && (sed_cmd->end_line || sed_cmd->end_match /* note: even if end is numeric and is < linenum too, - * GNU sed matches! We match too */ + * GNU sed matches! We match too, therefore we don't + * check here that linenum <= end. + * Example: + * printf '1\n2\n3\n4\n' | sed -n '1{N;N;d};1p;2,3p;3p;4p' + * first three input lines are deleted; + * 4th line is matched and printed + * by "2,3" (!) and by "4" ranges + */ ? (sed_cmd->beg_line <= linenum) /* N,end */ : (sed_cmd->beg_line == linenum) /* N */ ) @@ -994,16 +1010,14 @@ static void process_files(void) /* Snapshot the value */ matched = sed_cmd->in_match; - //bb_error_msg("cmd:'%c' matched:%d beg_line:%d end_line:%d linenum:%d", - //sed_cmd->cmd, matched, sed_cmd->beg_line, sed_cmd->end_line, linenum); + dbg("cmd:'%c' matched:%d beg_line:%d end_line:%d linenum:%d", + sed_cmd->cmd, matched, sed_cmd->beg_line, sed_cmd->end_line, linenum); /* Is this line the end of the current match? */ if (matched) { /* once matched, "n,xxx" range is dead, disabling it */ - if (sed_cmd->beg_line > 0 - && !(option_mask32 & OPT_in_place) /* but not for -i */ - ) { + if (sed_cmd->beg_line > 0) { sed_cmd->beg_line = -2; } sed_cmd->in_match = !( @@ -1017,7 +1031,8 @@ static void process_files(void) /* or does this line matches our last address regex */ || (sed_cmd->end_match && old_matched && (regexec(sed_cmd->end_match, - pattern_space, 0, NULL, 0) == 0)) + pattern_space, 0, NULL, 0) == 0) + ) ); } @@ -1407,11 +1422,12 @@ int sed_main(int argc UNUSED_PARAM, char **argv) add_input_file(stdin); } else { int i; - FILE *file; for (i = 0; argv[i]; i++) { struct stat statbuf; int nonstdoutfd; + FILE *file; + sed_cmd_t *sed_cmd; if (LONE_DASH(argv[i]) && !(opt & OPT_in_place)) { add_input_file(stdin); @@ -1423,11 +1439,13 @@ int sed_main(int argc UNUSED_PARAM, char **argv) status = EXIT_FAILURE; continue; } + add_input_file(file); if (!(opt & OPT_in_place)) { - add_input_file(file); continue; } + /* -i: process each FILE separately: */ + G.outname = xasprintf("%sXXXXXX", argv[i]); nonstdoutfd = xmkstemp(G.outname); G.nonstdout = xfdopen_for_write(nonstdoutfd); @@ -1438,15 +1456,20 @@ int sed_main(int argc UNUSED_PARAM, char **argv) * but GNU sed 4.2.1 does not preserve them either */ fchmod(nonstdoutfd, statbuf.st_mode); fchown(nonstdoutfd, statbuf.st_uid, statbuf.st_gid); - add_input_file(file); + process_files(); fclose(G.nonstdout); - G.nonstdout = stdout; + /* unlink(argv[i]); */ xrename(G.outname, argv[i]); free(G.outname); G.outname = NULL; + + /* Re-enable disabled range matches */ + for (sed_cmd = G.sed_cmd_head; sed_cmd; sed_cmd = sed_cmd->next) { + sed_cmd->beg_line = sed_cmd->beg_line_orig; + } } /* Here, to handle "sed 'cmds' nonexistent_file" case we did: * if (G.current_input_file >= G.input_file_count) diff --git a/testsuite/sed.tests b/testsuite/sed.tests index e9d0ed601..ba163e9e9 100755 --- a/testsuite/sed.tests +++ b/testsuite/sed.tests @@ -6,7 +6,7 @@ . ./testing.sh -# testing "description" "arguments" "result" "infile" "stdin" +# testing "description" "commands" "result" "infile" "stdin" # Corner cases testing "sed no files (stdin)" 'sed ""' "hello\n" "" "hello\n" @@ -225,7 +225,7 @@ testing "sed s/xxx/[/" "sed -e 's/xxx/[/'" "[\n" "" "xxx\n" #testing "sed -g (exhaustive)" "sed -e 's/[[:space:]]*/,/g'" ",1,2,3,4,5," \ # "" "12345" -# testing "description" "arguments" "result" "infile" "stdin" +# testing "description" "commands" "result" "infile" "stdin" testing "sed n command must reset 'substituted' bit" \ "sed 's/1/x/;T;n;: next;s/3/y/;t quit;n;b next;: quit;q'" \ @@ -291,6 +291,10 @@ testing "sed understands \r" \ "sed 's/r/\r/'" \ "\rrr\n" "" "rrr\n" -# testing "description" "arguments" "result" "infile" "stdin" +testing "sed -i finishes ranges correctly" \ + "sed '1,2d' -i input; echo \$?; cat input" \ + "0\n3\n4\n" "1\n2\n3\n4\n" "" + +# testing "description" "commands" "result" "infile" "stdin" exit $FAILCOUNT -- cgit v1.2.3-55-g6feb From 9176f6c52cb60f9de72a1c8e6b4dafc7c29ec1bf Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Tue, 16 Aug 2011 22:57:12 +0200 Subject: patch: add a test we currently fail Signed-off-by: Denys Vlasenko --- testsuite/patch.tests | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/testsuite/patch.tests b/testsuite/patch.tests index c604b9c1d..7cd716ce5 100755 --- a/testsuite/patch.tests +++ b/testsuite/patch.tests @@ -212,6 +212,21 @@ patching file input 666 " \ +# Currently fails +# testing "test name" "command(s)" "expected result" "file input" "stdin" +testing "patch creates new file" \ + 'patch 2>&1; echo $?; cat testfile; rm testfile' \ +"\ +creating testfile +0 +qwerty +" "" "\ +--- /dev/null ++++ testfile +@@ -0,0 +1 @@ ++qwerty +" + rm input.orig 2>/dev/null exit $FAILCOUNT -- cgit v1.2.3-55-g6feb From 816cd16a4ce81ec8d2989a356256f813fc91475d Mon Sep 17 00:00:00 2001 From: Kevin Cernekee Date: Wed, 13 Jul 2011 09:29:55 -0700 Subject: cttyhack: remove the trailing newline when reading console name from sysfs Signed-off-by: Kevin Cernekee Signed-off-by: Denys Vlasenko --- shell/cttyhack.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/shell/cttyhack.c b/shell/cttyhack.c index 4261289b4..37ea13723 100644 --- a/shell/cttyhack.c +++ b/shell/cttyhack.c @@ -122,10 +122,12 @@ int cttyhack_main(int argc UNUSED_PARAM, char **argv) do { #ifdef __linux__ int s = open_read_close("/sys/class/tty/console/active", - console + 5, sizeof(console) - 5 - 1); + console + 5, sizeof(console) - 5); if (s > 0) { - /* found active console via sysfs (Linux 2.6.38+) */ - console[5 + s] = '\0'; + /* found active console via sysfs (Linux 2.6.38+) + * sysfs string looks like "ttyS0\n" so zap the newline: + */ + console[4 + s] = '\0'; break; } -- cgit v1.2.3-55-g6feb From 4619802a5f399119345ca339886b7b060f2c15aa Mon Sep 17 00:00:00 2001 From: Kevin Cernekee Date: Sun, 14 Aug 2011 13:35:25 -0700 Subject: cttyhack: trivial spelling/spacing fixes Signed-off-by: Kevin Cernekee Signed-off-by: Denys Vlasenko --- shell/cttyhack.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/shell/cttyhack.c b/shell/cttyhack.c index 37ea13723..6241c76a9 100644 --- a/shell/cttyhack.c +++ b/shell/cttyhack.c @@ -139,7 +139,7 @@ int cttyhack_main(int argc UNUSED_PARAM, char **argv) #endif #ifdef TIOCGSERIAL if (ioctl(0, TIOCGSERIAL, &u.sr) == 0) { - /* this is a serial console, asuming it is named /dev/ttySn */ + /* this is a serial console; assuming it is named /dev/ttySn */ sprintf(console + 8, "S%d", u.sr.line); break; } -- cgit v1.2.3-55-g6feb From b1611d9a4693f1dc8296ef44f7e0f6044032ce15 Mon Sep 17 00:00:00 2001 From: Pere Orga Date: Thu, 11 Aug 2011 13:42:00 +0200 Subject: hostid: fix behavior on identifiers starting with zeros Signed-off-by: Pere Orga Signed-off-by: Denys Vlasenko --- coreutils/Config.src | 7 ------- coreutils/Kbuild.src | 1 - coreutils/hostid.c | 13 ++++++++++++- include/applets.src.h | 1 - 4 files changed, 12 insertions(+), 10 deletions(-) diff --git a/coreutils/Config.src b/coreutils/Config.src index 65165d79b..a28449b11 100644 --- a/coreutils/Config.src +++ b/coreutils/Config.src @@ -269,13 +269,6 @@ config FEATURE_FANCY_HEAD help This enables the head options (-c, -q, and -v). -config HOSTID - bool "hostid" - default y - help - hostid prints the numeric identifier (in hexadecimal) for - the current host. - config INSTALL bool "install" default y diff --git a/coreutils/Kbuild.src b/coreutils/Kbuild.src index 53d88b391..d6453f014 100644 --- a/coreutils/Kbuild.src +++ b/coreutils/Kbuild.src @@ -36,7 +36,6 @@ lib-$(CONFIG_FALSE) += false.o lib-$(CONFIG_FOLD) += fold.o lib-$(CONFIG_FSYNC) += fsync.o lib-$(CONFIG_HEAD) += head.o -lib-$(CONFIG_HOSTID) += hostid.o lib-$(CONFIG_INSTALL) += install.o #lib-$(CONFIG_LENGTH) += length.o lib-$(CONFIG_LN) += ln.o diff --git a/coreutils/hostid.c b/coreutils/hostid.c index 49409b9de..5c1a4e086 100644 --- a/coreutils/hostid.c +++ b/coreutils/hostid.c @@ -9,6 +9,17 @@ /* BB_AUDIT SUSv3 N/A -- Matches GNU behavior. */ +//config:config HOSTID +//config: bool "hostid" +//config: default y +//config: help +//config: hostid prints the numeric identifier (in hexadecimal) for +//config: the current host. + +//applet:IF_HOSTID(APPLET_NOFORK(hostid, hostid, BB_DIR_USR_BIN, BB_SUID_DROP, hostid)) + +//kbuild:lib-$(CONFIG_HOSTID) += hostid.o + //usage:#define hostid_trivial_usage //usage: "" //usage:#define hostid_full_usage "\n\n" @@ -25,7 +36,7 @@ int hostid_main(int argc UNUSED_PARAM, char **argv UNUSED_PARAM) bb_show_usage(); } - printf("%lx\n", gethostid()); + printf("%08lx\n", gethostid()); return fflush_all(); } diff --git a/include/applets.src.h b/include/applets.src.h index 87d9cbb7b..a5866d83b 100644 --- a/include/applets.src.h +++ b/include/applets.src.h @@ -176,7 +176,6 @@ IF_HD(APPLET_NOEXEC(hd, hexdump, BB_DIR_USR_BIN, BB_SUID_DROP, hd)) IF_HDPARM(APPLET(hdparm, BB_DIR_SBIN, BB_SUID_DROP)) IF_HEAD(APPLET_NOEXEC(head, head, BB_DIR_USR_BIN, BB_SUID_DROP, head)) IF_HEXDUMP(APPLET_NOEXEC(hexdump, hexdump, BB_DIR_USR_BIN, BB_SUID_DROP, hexdump)) -IF_HOSTID(APPLET_NOFORK(hostid, hostid, BB_DIR_USR_BIN, BB_SUID_DROP, hostid)) IF_HOSTNAME(APPLET(hostname, BB_DIR_BIN, BB_SUID_DROP)) IF_HTTPD(APPLET(httpd, BB_DIR_USR_SBIN, BB_SUID_DROP)) IF_HWCLOCK(APPLET(hwclock, BB_DIR_SBIN, BB_SUID_DROP)) -- cgit v1.2.3-55-g6feb From 251fc70e9722f931eec23a34030d05ba5f747b0e Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Thu, 18 Aug 2011 14:29:41 +0200 Subject: uncompress: fix buffer underrun by corrupted input Signed-off-by: Denys Vlasenko --- archival/libarchive/decompress_uncompress.c | 13 ++++++++----- testsuite/uncompress.tests | 20 ++++++++++++++++++++ 2 files changed, 28 insertions(+), 5 deletions(-) create mode 100755 testsuite/uncompress.tests diff --git a/archival/libarchive/decompress_uncompress.c b/archival/libarchive/decompress_uncompress.c index 44d894244..329894be1 100644 --- a/archival/libarchive/decompress_uncompress.c +++ b/archival/libarchive/decompress_uncompress.c @@ -163,7 +163,8 @@ unpack_Z_stream(int fd_in, int fd_out) if (insize < (int) (IBUFSIZ + 64) - IBUFSIZ) { rsize = safe_read(fd_in, inbuf + insize, IBUFSIZ); -//error check?? + if (rsize < 0) + bb_error_msg(bb_msg_read_error); insize += rsize; } @@ -195,6 +196,8 @@ unpack_Z_stream(int fd_in, int fd_out) if (oldcode == -1) { + if (code >= 256) + bb_error_msg_and_die("corrupted data"); /* %ld", code); */ oldcode = code; finchar = (int) oldcode; outbuf[outpos++] = (unsigned char) finchar; @@ -239,6 +242,8 @@ unpack_Z_stream(int fd_in, int fd_out) /* Generate output characters in reverse order */ while ((long) code >= (long) 256) { + if (stackp <= &htabof(0)) + bb_error_msg_and_die("corrupted data"); *--stackp = tab_suffixof(code); code = tab_prefixof(code); } @@ -263,8 +268,7 @@ unpack_Z_stream(int fd_in, int fd_out) } if (outpos >= OBUFSIZ) { - full_write(fd_out, outbuf, outpos); -//error check?? + xwrite(fd_out, outbuf, outpos); IF_DESKTOP(total_written += outpos;) outpos = 0; } @@ -292,8 +296,7 @@ unpack_Z_stream(int fd_in, int fd_out) } while (rsize > 0); if (outpos > 0) { - full_write(fd_out, outbuf, outpos); -//error check?? + xwrite(fd_out, outbuf, outpos); IF_DESKTOP(total_written += outpos;) } diff --git a/testsuite/uncompress.tests b/testsuite/uncompress.tests new file mode 100755 index 000000000..51a233493 --- /dev/null +++ b/testsuite/uncompress.tests @@ -0,0 +1,20 @@ +#!/bin/sh +# Copyright 2011 by Denys Vlasenko +# Licensed under GPLv2, see file LICENSE in this source tree. + +. ./testing.sh + +# testing "test name" "commands" "expected result" "file input" "stdin" + +testing "uncompress < \x1f\x9d\x90 \x01 x N" \ +'uncompress 2>&1 1>/dev/null; echo $?' \ +"\ +uncompress: corrupted data +1 +" \ +"" "\ +\x1f\x9d\x90\ +\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\ +" + +exit $FAILCOUNT -- cgit v1.2.3-55-g6feb From c5f7847659ccddd27c99b300e01f36516326aa3a Mon Sep 17 00:00:00 2001 From: Rob Landley Date: Mon, 22 Aug 2011 04:58:32 +0200 Subject: patch: make it able to create files (again) I broke patch's ability to create files in November, and nobody noticed in the ensuing 11 months. Sigh. Signed-off-by: Rob Landley Signed-off-by: Denys Vlasenko --- editors/patch.c | 8 +++----- testsuite/patch.tests | 1 - 2 files changed, 3 insertions(+), 6 deletions(-) diff --git a/editors/patch.c b/editors/patch.c index ec5b8e7ad..1f2a49b66 100644 --- a/editors/patch.c +++ b/editors/patch.c @@ -70,8 +70,7 @@ struct double_list { // Free all the elements of a linked list // Call freeit() on each element before freeing it. -static -void dlist_free(struct double_list *list, void (*freeit)(void *data)) +static void dlist_free(struct double_list *list, void (*freeit)(void *data)) { while (list) { void *pop = list; @@ -83,8 +82,7 @@ void dlist_free(struct double_list *list, void (*freeit)(void *data)) } // Add an entry before "list" element in (circular) doubly linked list -static -struct double_list *dlist_add(struct double_list **list, char *data) +static struct double_list *dlist_add(struct double_list **list, char *data) { struct double_list *llist; struct double_list *line = xmalloc(sizeof(*line)); @@ -232,7 +230,7 @@ static int apply_one_hunk(void) else matcheof = 0; if (PATCH_DEBUG) fdprintf(2, "HUNK:%s\n", plist->data); } - matcheof = matcheof < TT.context; + matcheof = !matcheof || matcheof < TT.context; if (PATCH_DEBUG) fdprintf(2,"MATCHEOF=%c\n", matcheof ? 'Y' : 'N'); diff --git a/testsuite/patch.tests b/testsuite/patch.tests index 7cd716ce5..8caeed5bd 100755 --- a/testsuite/patch.tests +++ b/testsuite/patch.tests @@ -212,7 +212,6 @@ patching file input 666 " \ -# Currently fails # testing "test name" "command(s)" "expected result" "file input" "stdin" testing "patch creates new file" \ 'patch 2>&1; echo $?; cat testfile; rm testfile' \ -- cgit v1.2.3-55-g6feb From a04e4c2266241b1af8f50b0d78f13be866b405c4 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Mon, 22 Aug 2011 04:59:41 +0200 Subject: uncompress: die on read errors Signed-off-by: Denys Vlasenko --- archival/libarchive/decompress_uncompress.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/archival/libarchive/decompress_uncompress.c b/archival/libarchive/decompress_uncompress.c index 329894be1..d1061a2bb 100644 --- a/archival/libarchive/decompress_uncompress.c +++ b/archival/libarchive/decompress_uncompress.c @@ -164,7 +164,7 @@ unpack_Z_stream(int fd_in, int fd_out) if (insize < (int) (IBUFSIZ + 64) - IBUFSIZ) { rsize = safe_read(fd_in, inbuf + insize, IBUFSIZ); if (rsize < 0) - bb_error_msg(bb_msg_read_error); + bb_error_msg_and_die(bb_msg_read_error); insize += rsize; } -- cgit v1.2.3-55-g6feb From 1285437217a60194186b2c66a0422205b2dedd08 Mon Sep 17 00:00:00 2001 From: Matthias Andree Date: Sun, 28 Aug 2011 05:04:07 +0200 Subject: Fixes for FreeBSD build Signed-off-by: Matthias Andree Signed-off-by: Denys Vlasenko --- include/platform.h | 2 ++ libbb/match_fstype.c | 4 ++++ 2 files changed, 6 insertions(+) diff --git a/include/platform.h b/include/platform.h index e22dbdb4a..826a4c497 100644 --- a/include/platform.h +++ b/include/platform.h @@ -417,6 +417,8 @@ typedef unsigned smalluint; # undef HAVE_STRVERSCMP # undef HAVE_XTABS # undef HAVE_DPRINTF +# undef HAVE_UNLOCKED_STDIO +# undef HAVE_UNLOCKED_LINE_OPS #endif #if defined(__FreeBSD__) diff --git a/libbb/match_fstype.c b/libbb/match_fstype.c index 83d6e6770..c792d13b3 100644 --- a/libbb/match_fstype.c +++ b/libbb/match_fstype.c @@ -10,6 +10,8 @@ * Licensed under GPLv2 or later, see file LICENSE in this source tree. */ +#ifdef HAVE_MNTENT_H + #include "libbb.h" int FAST_FUNC match_fstype(const struct mntent *mt, const char *t_fstype) @@ -40,3 +42,5 @@ int FAST_FUNC match_fstype(const struct mntent *mt, const char *t_fstype) return !match; } + +#endif /* HAVE_MNTENT_H */ -- cgit v1.2.3-55-g6feb From 24915117a284c5536c9c707fc34ec9e7bf331f32 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Sun, 28 Aug 2011 05:31:49 +0200 Subject: Fixes for warnings in FreeBSD build Signed-off-by: Denys Vlasenko --- libbb/getpty.c | 18 ++++++++++-------- libbb/udp_io.c | 2 +- miscutils/less.c | 4 ++-- 3 files changed, 13 insertions(+), 11 deletions(-) diff --git a/libbb/getpty.c b/libbb/getpty.c index 6a15cff2f..435e4d09f 100644 --- a/libbb/getpty.c +++ b/libbb/getpty.c @@ -19,20 +19,22 @@ int FAST_FUNC xgetpty(char *line) if (p > 0) { grantpt(p); /* chmod+chown corresponding slave pty */ unlockpt(p); /* (what does this do?) */ -#ifndef HAVE_PTSNAME_R - const char *name; - name = ptsname(p); /* find out the name of slave pty */ - if (!name) { - bb_perror_msg_and_die("ptsname error (is /dev/pts mounted?)"); +# ifndef HAVE_PTSNAME_R + { + const char *name; + name = ptsname(p); /* find out the name of slave pty */ + if (!name) { + bb_perror_msg_and_die("ptsname error (is /dev/pts mounted?)"); + } + safe_strncpy(line, name, GETPTY_BUFSIZE); } - safe_strncpy(line, name, GETPTY_BUFSIZE); -#else +# else /* find out the name of slave pty */ if (ptsname_r(p, line, GETPTY_BUFSIZE-1) != 0) { bb_perror_msg_and_die("ptsname error (is /dev/pts mounted?)"); } line[GETPTY_BUFSIZE-1] = '\0'; -#endif +# endif return p; } #else diff --git a/libbb/udp_io.c b/libbb/udp_io.c index b8fb6755d..7985a9723 100644 --- a/libbb/udp_io.c +++ b/libbb/udp_io.c @@ -13,7 +13,7 @@ * We don't check for errors here. Not supported == won't be used */ void FAST_FUNC -socket_want_pktinfo(int fd) +socket_want_pktinfo(int fd UNUSED_PARAM) { #ifdef IP_PKTINFO setsockopt(fd, IPPROTO_IP, IP_PKTINFO, &const_int_1, sizeof(int)); diff --git a/miscutils/less.c b/miscutils/less.c index 2c6a79326..045fd2db3 100644 --- a/miscutils/less.c +++ b/miscutils/less.c @@ -721,8 +721,8 @@ static void print_found(const char *line) while (match_status == 0) { char *new = xasprintf("%s%.*s"HIGHLIGHT"%.*s"NORMAL, growline ? growline : "", - match_structs.rm_so, str, - match_structs.rm_eo - match_structs.rm_so, + (int)match_structs.rm_so, str, + (int)(match_structs.rm_eo - match_structs.rm_so), str + match_structs.rm_so); free(growline); growline = new; -- cgit v1.2.3-55-g6feb From abc33ac8b24d2d733aba63ae19e2df6e7da16ec8 Mon Sep 17 00:00:00 2001 From: Ian Wienand Date: Sun, 28 Aug 2011 06:53:20 +0200 Subject: Fix find -follow support Signed-off-by: Ian Wienand Signed-off-by: Denys Vlasenko --- findutils/find.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/findutils/find.c b/findutils/find.c index 05f88d2f0..fc0fc5c9f 100644 --- a/findutils/find.c +++ b/findutils/find.c @@ -932,7 +932,10 @@ static action*** parse_params(char **argv) * expression is reached. */ /* Options */ - if (0) { } + if (parm == OPT_FOLLOW) { + dbg("follow enabled: %d", __LINE__); + G.recurse_flags |= ACTION_FOLLOWLINKS | ACTION_DANGLING_OK; + } #if ENABLE_FEATURE_FIND_XDEV else if (parm == OPT_XDEV) { dbg("%d", __LINE__); -- cgit v1.2.3-55-g6feb From 2390109dcbc7769c8cc373db32805206522ca9a6 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Sun, 28 Aug 2011 11:57:36 +0200 Subject: top: fix CPU% for thread display. Closes 4081 Signed-off-by: Denys Vlasenko --- libbb/procps.c | 34 +++++++++++++++++++--------------- 1 file changed, 19 insertions(+), 15 deletions(-) diff --git a/libbb/procps.c b/libbb/procps.c index 1dea61518..e15ddd1e5 100644 --- a/libbb/procps.c +++ b/libbb/procps.c @@ -284,27 +284,25 @@ int FAST_FUNC procps_read_smaps(pid_t pid, struct smaprec *total, void BUG_comm_size(void); procps_status_t* FAST_FUNC procps_scan(procps_status_t* sp, int flags) { - struct dirent *entry; - char buf[PROCPS_BUFSIZE]; - char filename[sizeof("/proc//cmdline") + sizeof(int)*3]; - char *filename_tail; - long tasknice; - unsigned pid; - int n; - struct stat sb; - if (!sp) sp = alloc_procps_scan(); for (;;) { + struct dirent *entry; + char buf[PROCPS_BUFSIZE]; + long tasknice; + unsigned pid; + int n; + char filename[sizeof("/proc/%u/task/%u/cmdline") + sizeof(int)*3 * 2]; + char *filename_tail; + #if ENABLE_FEATURE_SHOW_THREADS - if ((flags & PSSCAN_TASKS) && sp->task_dir) { + if (sp->task_dir) { entry = readdir(sp->task_dir); if (entry) goto got_entry; closedir(sp->task_dir); sp->task_dir = NULL; - sp->main_thread_pid = 0; } #endif entry = readdir(sp->dir); @@ -321,9 +319,9 @@ procps_status_t* FAST_FUNC procps_scan(procps_status_t* sp, int flags) /* We found another /proc/PID. Do not use it, * there will be /proc/PID/task/PID (same PID!), * so just go ahead and dive into /proc/PID/task. */ - char task_dir[sizeof("/proc/%u/task") + sizeof(int)*3]; - sprintf(task_dir, "/proc/%u/task", pid); - sp->task_dir = xopendir(task_dir); + sprintf(filename, "/proc/%u/task", pid); + /* Note: if opendir fails, we just go to next /proc/XXX */ + sp->task_dir = opendir(filename); sp->main_thread_pid = pid; continue; } @@ -347,9 +345,15 @@ procps_status_t* FAST_FUNC procps_scan(procps_status_t* sp, int flags) } #endif - filename_tail = filename + sprintf(filename, "/proc/%u/", pid); +#if ENABLE_FEATURE_SHOW_THREADS + if (sp->task_dir) + filename_tail = filename + sprintf(filename, "/proc/%u/task/%u/", sp->main_thread_pid, pid); + else +#endif + filename_tail = filename + sprintf(filename, "/proc/%u/", pid); if (flags & PSSCAN_UIDGID) { + struct stat sb; if (stat(filename, &sb)) continue; /* process probably exited */ /* Effective UID/GID, not real */ -- cgit v1.2.3-55-g6feb From 7b46220d922d7c6267a8442ff8c3a6d1ab106727 Mon Sep 17 00:00:00 2001 From: Lauri Kasanen Date: Sun, 28 Aug 2011 12:39:04 +0200 Subject: grep: be GNU compatible with -f EMPTY_FILE Signed-off-by: Lauri Kasanen Signed-off-by: Denys Vlasenko --- findutils/grep.c | 22 +++++++++++++--------- testsuite/grep.tests | 18 +++++++++++++++++- 2 files changed, 30 insertions(+), 10 deletions(-) diff --git a/findutils/grep.c b/findutils/grep.c index 3acfa9197..5f4224203 100644 --- a/findutils/grep.c +++ b/findutils/grep.c @@ -562,20 +562,20 @@ static char *add_grep_list_data(char *pattern) static void load_regexes_from_file(llist_t *fopt) { - char *line; - FILE *f; - while (fopt) { + char *line; + FILE *fp; llist_t *cur = fopt; char *ffile = cur->data; fopt = cur->link; free(cur); - f = xfopen_stdin(ffile); - while ((line = xmalloc_fgetline(f)) != NULL) { + fp = xfopen_stdin(ffile); + while ((line = xmalloc_fgetline(fp)) != NULL) { llist_add_to(&pattern_head, new_grep_list_data(line, ALLOCATED)); } + fclose_if_not_stdin(fp); } } @@ -659,15 +659,19 @@ int grep_main(int argc UNUSED_PARAM, char **argv) #endif invert_search = ((option_mask32 & OPT_v) != 0); /* 0 | 1 */ - if (pattern_head != NULL) { - /* convert char **argv to grep_list_data_t */ + { /* convert char **argv to grep_list_data_t */ llist_t *cur; - for (cur = pattern_head; cur; cur = cur->link) cur->data = new_grep_list_data(cur->data, 0); } - if (option_mask32 & OPT_f) + if (option_mask32 & OPT_f) { load_regexes_from_file(fopt); + if (!pattern_head) { /* -f EMPTY_FILE? */ + /* GNU grep treats it as "nothing matches" */ + llist_add_to(&pattern_head, new_grep_list_data((char*) "", 0)); + invert_search ^= 1; + } + } if (ENABLE_FEATURE_GREP_FGREP_ALIAS && applet_name[0] == 'f') option_mask32 |= OPT_F; diff --git a/testsuite/grep.tests b/testsuite/grep.tests index ffce033e6..006a215e1 100755 --- a/testsuite/grep.tests +++ b/testsuite/grep.tests @@ -7,7 +7,7 @@ . ./testing.sh -# testing "test name" "options" "expected result" "file input" "stdin" +# 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 @@ -103,4 +103,20 @@ testing "grep -o does not loop forever on zero-length match" \ "" \ "" "test\n" +testing "grep -f EMPTY_FILE" \ + "grep -f input" \ + "" \ + "" \ + "test\n" + +testing "grep -v -f EMPTY_FILE" \ + "grep -v -f input" \ + "test\n" \ + "" \ + "test\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 + exit $FAILCOUNT -- cgit v1.2.3-55-g6feb From 4840ae8a06298e987374fa3cc6d7e4969fd19344 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Sun, 4 Sep 2011 15:28:03 +0200 Subject: lineedit: fix atomic replace of history file; hush: fix $HISTFILE handling Signed-off-by: Denys Vlasenko --- libbb/lineedit.c | 4 ++-- shell/ash.c | 2 +- shell/hush.c | 40 +++++++++++++++++++++++----------------- 3 files changed, 26 insertions(+), 20 deletions(-) diff --git a/libbb/lineedit.c b/libbb/lineedit.c index 10265192e..5d139043a 100644 --- a/libbb/lineedit.c +++ b/libbb/lineedit.c @@ -1425,7 +1425,7 @@ static void save_history(char *str) /* write out temp file and replace hist_file atomically */ new_name = xasprintf("%s.%u.new", state->hist_file, (int) getpid()); - fd = open(state->hist_file, O_WRONLY | O_CREAT | O_TRUNC, 0600); + fd = open(new_name, O_WRONLY | O_CREAT | O_TRUNC, 0600); if (fd >= 0) { FILE *fp; int i; @@ -1475,7 +1475,7 @@ static void remember_in_history(char *str) /* i <= state->max_history */ state->cur_history = i; state->cnt_history = i; -# if MAX_HISTORY > 0 && ENABLE_FEATURE_EDITING_SAVEHISTORY +# if ENABLE_FEATURE_EDITING_SAVEHISTORY if ((state->flags & SAVE_HISTORY) && state->hist_file) save_history(str); # endif diff --git a/shell/ash.c b/shell/ash.c index d48cd016f..bf376bd0d 100644 --- a/shell/ash.c +++ b/shell/ash.c @@ -13194,7 +13194,7 @@ int ash_main(int argc UNUSED_PARAM, char **argv) } if (sflag || minusc == NULL) { -#if defined MAX_HISTORY && MAX_HISTORY > 0 && ENABLE_FEATURE_EDITING_SAVEHISTORY +#if MAX_HISTORY > 0 && ENABLE_FEATURE_EDITING_SAVEHISTORY if (iflag) { const char *hp = lookupvar("HISTFILE"); if (hp) diff --git a/shell/hush.c b/shell/hush.c index e4138adf7..42143fd9e 100644 --- a/shell/hush.c +++ b/shell/hush.c @@ -7816,23 +7816,7 @@ int hush_main(int argc, char **argv) */ #if ENABLE_FEATURE_EDITING - G.line_input_state = new_line_input_t(FOR_SHELL); -# if defined MAX_HISTORY && MAX_HISTORY > 0 && ENABLE_HUSH_SAVEHISTORY - { - const char *hp = get_local_var_value("HISTFILE"); - if (!hp) { - hp = get_local_var_value("HOME"); - if (hp) { - G.line_input_state->hist_file = concat_path_file(hp, ".hush_history"); - //set_local_var(xasprintf("HISTFILE=%s", ...)); - } - } -# if ENABLE_FEATURE_SH_HISTFILESIZE - hp = get_local_var_value("HISTFILESIZE"); - G.line_input_state->max_history = size_from_HISTFILESIZE(hp); -# endif - } -# endif + G.line_input_state = new_line_input_t(FOR_SHELL & ~SAVE_HISTORY); #endif /* Initialize some more globals to non-zero values */ @@ -8104,6 +8088,28 @@ int hush_main(int argc, char **argv) /* -1 is special - makes xfuncs longjmp, not exit * (we reset die_sleep = 0 whereever we [v]fork) */ enable_restore_tty_pgrp_on_exit(); /* sets die_sleep = -1 */ + +# if ENABLE_HUSH_SAVEHISTORY && MAX_HISTORY > 0 + { + const char *hp = get_local_var_value("HISTFILE"); + if (!hp) { + hp = get_local_var_value("HOME"); + if (hp) + hp = concat_path_file(hp, ".hush_history"); + } else { + hp = xstrdup(hp); + } + if (hp) { + G.line_input_state->hist_file = hp; + G.line_input_state->flags |= SAVE_HISTORY; + //set_local_var(xasprintf("HISTFILE=%s", ...)); + } +# if ENABLE_FEATURE_SH_HISTFILESIZE + hp = get_local_var_value("HISTFILESIZE"); + G.line_input_state->max_history = size_from_HISTFILESIZE(hp); +# endif + } +# endif } else { install_special_sighandlers(); } -- cgit v1.2.3-55-g6feb From bede215cf105377a1127532d2d710924cb58cc39 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Sun, 4 Sep 2011 16:12:33 +0200 Subject: lineedit: add support for history saving on exit Based on the patch by Dennis Groenen Signed-off-by: Denys Vlasenko --- include/libbb.h | 9 ++++++++ libbb/Config.src | 7 ++++++ libbb/lineedit.c | 68 +++++++++++++++++++++++++++++++++++++++++++++++++++----- shell/ash.c | 4 ++++ shell/hush.c | 4 ++++ 5 files changed, 86 insertions(+), 6 deletions(-) diff --git a/include/libbb.h b/include/libbb.h index 63d041957..91343a95e 100644 --- a/include/libbb.h +++ b/include/libbb.h @@ -1421,6 +1421,12 @@ typedef struct line_input_t { int cur_history; int max_history; /* must never be <= 0 */ # if ENABLE_FEATURE_EDITING_SAVEHISTORY + /* meaning of this field depends on FEATURE_EDITING_SAVE_ON_EXIT: + * if !FEATURE_EDITING_SAVE_ON_EXIT: "how many lines are + * in on-disk history" + * if FEATURE_EDITING_SAVE_ON_EXIT: "how many in-memory lines are + * also in on-disk history (and thus need to be skipped on save)" + */ unsigned cnt_history_in_file; const char *hist_file; # endif @@ -1446,6 +1452,9 @@ line_input_t *new_line_input_t(int flags) FAST_FUNC; * >0 length of input string, including terminating '\n' */ int read_line_input(line_input_t *st, const char *prompt, char *command, int maxsize, int timeout) FAST_FUNC; +# if ENABLE_FEATURE_EDITING_SAVE_ON_EXIT +void save_history(line_input_t *st); +# endif #else #define MAX_HISTORY 0 int read_line_input(const char* prompt, char* command, int maxsize) FAST_FUNC; diff --git a/libbb/Config.src b/libbb/Config.src index aa442365a..f6f88b9ce 100644 --- a/libbb/Config.src +++ b/libbb/Config.src @@ -94,6 +94,13 @@ config FEATURE_EDITING_SAVEHISTORY help Enable history saving in shells. +config FEATURE_EDITING_SAVE_ON_EXIT + bool "Save history on shell exit, not after every command" + default n + depends on FEATURE_EDITING_SAVEHISTORY + help + Save history on shell exit, not after every command. + config FEATURE_REVERSE_SEARCH bool "Reverse history search" default y diff --git a/libbb/lineedit.c b/libbb/lineedit.c index 5d139043a..0786f9ae6 100644 --- a/libbb/lineedit.c +++ b/libbb/lineedit.c @@ -1351,7 +1351,9 @@ static void load_history(line_input_t *st_parm) /* fill temp_h[], retaining only last MAX_HISTORY lines */ memset(temp_h, 0, sizeof(temp_h)); - st_parm->cnt_history_in_file = idx = 0; + idx = 0; + if (!ENABLE_FEATURE_EDITING_SAVE_ON_EXIT) + st_parm->cnt_history_in_file = 0; while ((line = xmalloc_fgetline(fp)) != NULL) { if (line[0] == '\0') { free(line); @@ -1359,7 +1361,8 @@ static void load_history(line_input_t *st_parm) } free(temp_h[idx]); temp_h[idx] = line; - st_parm->cnt_history_in_file++; + if (!ENABLE_FEATURE_EDITING_SAVE_ON_EXIT) + st_parm->cnt_history_in_file++; idx++; if (idx == st_parm->max_history) idx = 0; @@ -1389,15 +1392,66 @@ static void load_history(line_input_t *st_parm) st_parm->history[i++] = line; } st_parm->cnt_history = i; + if (ENABLE_FEATURE_EDITING_SAVE_ON_EXIT) + st_parm->cnt_history_in_file = i; } } -/* state->flags is already checked to be nonzero */ +# if ENABLE_FEATURE_EDITING_SAVE_ON_EXIT +void save_history(line_input_t *st) +{ + FILE *fp; + + if (!(st->flags & SAVE_HISTORY)) + return; + if (!st->hist_file) + return; + if (st->cnt_history <= st->cnt_history_in_file) + return; + + fp = fopen(st->hist_file, "a"); + if (fp) { + int i, fd; + char *new_name; + line_input_t *st_temp; + + for (i = st->cnt_history_in_file; i < st->cnt_history; i++) + fprintf(fp, "%s\n", st->history[i]); + fclose(fp); + + /* we may have concurrently written entries from others. + * load them */ + st_temp = new_line_input_t(st->flags); + st_temp->hist_file = st->hist_file; + st_temp->max_history = st->max_history; + load_history(st_temp); + + /* write out temp file and replace hist_file atomically */ + new_name = xasprintf("%s.%u.new", st->hist_file, (int) getpid()); + fd = open(new_name, O_WRONLY | O_CREAT | O_TRUNC, 0600); + if (fd >= 0) { + fp = xfdopen_for_write(fd); + for (i = 0; i < st_temp->cnt_history; i++) + fprintf(fp, "%s\n", st_temp->history[i]); + fclose(fp); + if (rename(new_name, st->hist_file) == 0) + st->cnt_history_in_file = st_temp->cnt_history; + } + free(new_name); + free_line_input_t(st_temp); + } +} +# else static void save_history(char *str) { int fd; int len, len2; + if (!(state->flags & SAVE_HISTORY)) + return; + if (!state->hist_file) + return; + fd = open(state->hist_file, O_WRONLY | O_CREAT | O_APPEND, 0600); if (fd < 0) return; @@ -1441,6 +1495,7 @@ static void save_history(char *str) free_line_input_t(st_temp); } } +# endif # else # define load_history(a) ((void)0) # define save_history(a) ((void)0) @@ -1469,15 +1524,16 @@ static void remember_in_history(char *str) for (i = 0; i < state->max_history-1; i++) state->history[i] = state->history[i+1]; /* i == state->max_history-1 */ + if (ENABLE_FEATURE_EDITING_SAVE_ON_EXIT && state->cnt_history_in_file) + state->cnt_history_in_file--; } /* i <= state->max_history-1 */ state->history[i++] = xstrdup(str); /* i <= state->max_history */ state->cur_history = i; state->cnt_history = i; -# if ENABLE_FEATURE_EDITING_SAVEHISTORY - if ((state->flags & SAVE_HISTORY) && state->hist_file) - save_history(str); +# if ENABLE_FEATURE_EDITING_SAVEHISTORY && !ENABLE_FEATURE_EDITING_SAVE_ON_EXIT + save_history(str); # endif IF_FEATURE_EDITING_FANCY_PROMPT(num_ok_lines++;) } diff --git a/shell/ash.c b/shell/ash.c index bf376bd0d..14472cb61 100644 --- a/shell/ash.c +++ b/shell/ash.c @@ -12888,6 +12888,10 @@ exitshell(void) char *p; int status; +#if ENABLE_FEATURE_EDITING_SAVE_ON_EXIT + save_history(line_input_state); +#endif + status = exitstatus; TRACE(("pid %d, exitshell(%d)\n", getpid(), status)); if (setjmp(loc.loc)) { diff --git a/shell/hush.c b/shell/hush.c index 42143fd9e..a9e2dd311 100644 --- a/shell/hush.c +++ b/shell/hush.c @@ -1541,6 +1541,10 @@ static sighandler_t pick_sighandler(unsigned sig) static void hush_exit(int exitcode) NORETURN; static void hush_exit(int exitcode) { +#if ENABLE_FEATURE_EDITING_SAVE_ON_EXIT + save_history(G.line_input_state); +#endif + fflush_all(); if (G.exiting <= 0 && G.traps && G.traps[0] && G.traps[0][0]) { char *argv[3]; -- cgit v1.2.3-55-g6feb From e45af7ad17c3f0ecaec1d761aa89cb4fd83afbc2 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Sun, 4 Sep 2011 16:15:24 +0200 Subject: lineedit: remove SAVE_HISTORY bit, ->hist_file can be used as indicator Signed-off-by: Denys Vlasenko --- include/libbb.h | 13 ++++++------- libbb/lineedit.c | 6 +----- shell/hush.c | 3 +-- 3 files changed, 8 insertions(+), 14 deletions(-) diff --git a/include/libbb.h b/include/libbb.h index 91343a95e..1ca448930 100644 --- a/include/libbb.h +++ b/include/libbb.h @@ -1434,13 +1434,12 @@ typedef struct line_input_t { # endif } line_input_t; enum { - DO_HISTORY = 1 * (MAX_HISTORY > 0), - SAVE_HISTORY = 2 * (MAX_HISTORY > 0) * ENABLE_FEATURE_EDITING_SAVEHISTORY, - TAB_COMPLETION = 4 * ENABLE_FEATURE_TAB_COMPLETION, - USERNAME_COMPLETION = 8 * ENABLE_FEATURE_USERNAME_COMPLETION, - VI_MODE = 0x10 * ENABLE_FEATURE_EDITING_VI, - WITH_PATH_LOOKUP = 0x20, - FOR_SHELL = DO_HISTORY | SAVE_HISTORY | TAB_COMPLETION | USERNAME_COMPLETION, + DO_HISTORY = 1 * (MAX_HISTORY > 0), + TAB_COMPLETION = 2 * ENABLE_FEATURE_TAB_COMPLETION, + USERNAME_COMPLETION = 4 * ENABLE_FEATURE_USERNAME_COMPLETION, + VI_MODE = 8 * ENABLE_FEATURE_EDITING_VI, + WITH_PATH_LOOKUP = 0x10, + FOR_SHELL = DO_HISTORY | TAB_COMPLETION | USERNAME_COMPLETION, }; line_input_t *new_line_input_t(int flags) FAST_FUNC; /* So far static: void free_line_input_t(line_input_t *n) FAST_FUNC; */ diff --git a/libbb/lineedit.c b/libbb/lineedit.c index 0786f9ae6..603bbfcae 100644 --- a/libbb/lineedit.c +++ b/libbb/lineedit.c @@ -1402,8 +1402,6 @@ void save_history(line_input_t *st) { FILE *fp; - if (!(st->flags & SAVE_HISTORY)) - return; if (!st->hist_file) return; if (st->cnt_history <= st->cnt_history_in_file) @@ -1447,8 +1445,6 @@ static void save_history(char *str) int fd; int len, len2; - if (!(state->flags & SAVE_HISTORY)) - return; if (!state->hist_file) return; @@ -2188,7 +2184,7 @@ int FAST_FUNC read_line_input(line_input_t *st, const char *prompt, char *comman state = st ? st : (line_input_t*) &const_int_0; #if MAX_HISTORY > 0 # if ENABLE_FEATURE_EDITING_SAVEHISTORY - if ((state->flags & SAVE_HISTORY) && state->hist_file) + if (state->hist_file) if (state->cnt_history == 0) load_history(state); # endif diff --git a/shell/hush.c b/shell/hush.c index a9e2dd311..7a34f59ae 100644 --- a/shell/hush.c +++ b/shell/hush.c @@ -7820,7 +7820,7 @@ int hush_main(int argc, char **argv) */ #if ENABLE_FEATURE_EDITING - G.line_input_state = new_line_input_t(FOR_SHELL & ~SAVE_HISTORY); + G.line_input_state = new_line_input_t(FOR_SHELL); #endif /* Initialize some more globals to non-zero values */ @@ -8105,7 +8105,6 @@ int hush_main(int argc, char **argv) } if (hp) { G.line_input_state->hist_file = hp; - G.line_input_state->flags |= SAVE_HISTORY; //set_local_var(xasprintf("HISTFILE=%s", ...)); } # if ENABLE_FEATURE_SH_HISTFILESIZE -- cgit v1.2.3-55-g6feb From 8c84f7545cf08925edb23d94d9f6519b338267c6 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Wed, 7 Sep 2011 05:56:09 +0200 Subject: crond: fix the case when option -d is disabled Signed-off-by: Denys Vlasenko --- miscutils/crond.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/miscutils/crond.c b/miscutils/crond.c index 014016fb6..a0b73c774 100644 --- a/miscutils/crond.c +++ b/miscutils/crond.c @@ -861,7 +861,8 @@ int crond_main(int argc UNUSED_PARAM, char **argv) /* "-b after -f is ignored", and so on for every pair a-b */ opt_complementary = "f-b:b-f:S-L:L-S" IF_FEATURE_CROND_D(":d-l") - ":l+:d+"; /* -l and -d have numeric param */ + /* -l and -d have numeric param */ + ":l+" IF_FEATURE_CROND_D(":d+"); opts = getopt32(argv, "l:L:fbSc:" IF_FEATURE_CROND_D("d:"), &G.log_level, &G.log_filename, &G.crontab_dir_name IF_FEATURE_CROND_D(,&G.log_level)); -- cgit v1.2.3-55-g6feb From e8f36330d9bb27f9f7e66aa6f01ff92c07d86f62 Mon Sep 17 00:00:00 2001 From: Baruch Siach Date: Wed, 7 Sep 2011 17:52:37 +0200 Subject: networking: consolidate the IP checksum code. -129 bytes. Signed-off-by: Baruch Siach Signed-off-by: Denys Vlasenko --- include/libbb.h | 1 + libbb/Kbuild.src | 6 ++++++ libbb/inet_cksum.c | 32 ++++++++++++++++++++++++++++++++ networking/ping.c | 31 +++---------------------------- networking/traceroute.c | 35 +---------------------------------- networking/udhcp/dhcpc.c | 4 ++-- networking/udhcp/packet.c | 34 +++------------------------------- 7 files changed, 48 insertions(+), 95 deletions(-) create mode 100644 libbb/inet_cksum.c diff --git a/include/libbb.h b/include/libbb.h index 1ca448930..f60f4278b 100644 --- a/include/libbb.h +++ b/include/libbb.h @@ -640,6 +640,7 @@ ssize_t recv_from_to(int fd, void *buf, size_t len, int flags, struct sockaddr *to, socklen_t sa_size) FAST_FUNC; +uint16_t inet_cksum(uint16_t *addr, int len) FAST_FUNC; char *xstrdup(const char *s) FAST_FUNC RETURNS_MALLOC; char *xstrndup(const char *s, int n) FAST_FUNC RETURNS_MALLOC; diff --git a/libbb/Kbuild.src b/libbb/Kbuild.src index 875d02456..335b34128 100644 --- a/libbb/Kbuild.src +++ b/libbb/Kbuild.src @@ -166,6 +166,12 @@ lib-$(CONFIG_IOSTAT) += get_cpu_count.o lib-$(CONFIG_MPSTAT) += get_cpu_count.o lib-$(CONFIG_POWERTOP) += get_cpu_count.o +lib-$(CONFIG_PING) += inet_cksum.o +lib-$(CONFIG_TRACEROUTE) += inet_cksum.o +lib-$(CONFIG_TRACEROUTE6) += inet_cksum.o +lib-$(CONFIG_UDHCPC) += inet_cksum.o +lib-$(CONFIG_UDHCPD) += inet_cksum.o + # We shouldn't build xregcomp.c if we don't need it - this ensures we don't # require regex.h to be in the include dir even if we don't need it thereby # allowing us to build busybox even if uclibc regex support is disabled. diff --git a/libbb/inet_cksum.c b/libbb/inet_cksum.c new file mode 100644 index 000000000..31bf8c4d9 --- /dev/null +++ b/libbb/inet_cksum.c @@ -0,0 +1,32 @@ +/* + * Checksum routine for Internet Protocol family headers (C Version) + * + * Licensed under GPLv2, see file LICENSE in this source tree. + */ + +#include "libbb.h" + +uint16_t FAST_FUNC inet_cksum(uint16_t *addr, int nleft) +{ + /* + * Our algorithm is simple, using a 32 bit accumulator, + * we add sequential 16 bit words to it, and at the end, fold + * back all the carry bits from the top 16 bits into the lower + * 16 bits. + */ + unsigned sum = 0; + while (nleft > 1) { + sum += *addr++; + nleft -= 2; + } + + /* Mop up an odd byte, if necessary */ + if (nleft) + sum += *(uint8_t*)addr; + + /* Add back carry outs from top 16 bits to low 16 bits */ + sum = (sum >> 16) + (sum & 0xffff); /* add hi 16 to low 16 */ + sum += (sum >> 16); /* add carry */ + + return (uint16_t)~sum; +} diff --git a/networking/ping.c b/networking/ping.c index efd4f210b..a1fd9dfb1 100644 --- a/networking/ping.c +++ b/networking/ping.c @@ -149,31 +149,6 @@ enum { PINGINTERVAL = 1, /* 1 second */ }; -/* Common routines */ - -static int in_cksum(unsigned short *buf, int sz) -{ - int nleft = sz; - int sum = 0; - unsigned short *w = buf; - unsigned short ans = 0; - - while (nleft > 1) { - sum += *w++; - nleft -= 2; - } - - if (nleft == 1) { - *(unsigned char *) (&ans) = *(unsigned char *) w; - sum += ans; - } - - sum = (sum >> 16) + (sum & 0xFFFF); - sum += (sum >> 16); - ans = ~sum; - return ans; -} - #if !ENABLE_FEATURE_FANCY_PING /* Simple version */ @@ -201,7 +176,7 @@ static void ping4(len_and_sockaddr *lsa) pkt = (struct icmp *) G.packet; memset(pkt, 0, sizeof(G.packet)); pkt->icmp_type = ICMP_ECHO; - pkt->icmp_cksum = in_cksum((unsigned short *) pkt, sizeof(G.packet)); + pkt->icmp_cksum = inet_cksum((uint16_t *) pkt, sizeof(G.packet)); xsendto(pingsock, G.packet, DEFDATALEN + ICMP_MINLEN, &lsa->u.sa, lsa->len); @@ -493,7 +468,7 @@ static void sendping4(int junk UNUSED_PARAM) /* No hton: we'll read it back on the same machine */ *(uint32_t*)&pkt->icmp_dun = monotonic_us(); - pkt->icmp_cksum = in_cksum((unsigned short *) pkt, datalen + ICMP_MINLEN); + pkt->icmp_cksum = inet_cksum((uint16_t *) pkt, datalen + ICMP_MINLEN); sendping_tail(sendping4, ICMP_MINLEN); } @@ -512,7 +487,7 @@ static void sendping6(int junk UNUSED_PARAM) /*if (datalen >= 4)*/ *(uint32_t*)(&pkt->icmp6_data8[4]) = monotonic_us(); - //TODO? pkt->icmp_cksum = in_cksum(...); + //TODO? pkt->icmp_cksum = inet_cksum(...); sendping_tail(sendping6, sizeof(struct icmp6_hdr)); } diff --git a/networking/traceroute.c b/networking/traceroute.c index c32103519..d197e5410 100644 --- a/networking/traceroute.c +++ b/networking/traceroute.c @@ -418,39 +418,6 @@ wait_for_reply(len_and_sockaddr *from_lsa, struct sockaddr *to, unsigned *timest return read_len; } -/* - * Checksum routine for Internet Protocol family headers (C Version) - */ -static uint16_t -in_cksum(uint16_t *addr, int len) -{ - int nleft = len; - uint16_t *w = addr; - uint16_t answer; - int sum = 0; - - /* - * Our algorithm is simple, using a 32 bit accumulator (sum), - * we add sequential 16 bit words to it, and at the end, fold - * back all the carry bits from the top 16 bits into the lower - * 16 bits. - */ - while (nleft > 1) { - sum += *w++; - nleft -= 2; - } - - /* mop up an odd byte, if necessary */ - if (nleft == 1) - sum += *(unsigned char *)w; - - /* add back carry outs from top 16 bits to low 16 bits */ - sum = (sum >> 16) + (sum & 0xffff); /* add hi 16 to low 16 */ - sum += (sum >> 16); /* add carry */ - answer = ~sum; /* truncate to 16 bits */ - return answer; -} - static void send_probe(int seq, int ttl) { @@ -477,7 +444,7 @@ send_probe(int seq, int ttl) /* Always calculate checksum for icmp packets */ outicmp->icmp_cksum = 0; - outicmp->icmp_cksum = in_cksum((uint16_t *)outicmp, + outicmp->icmp_cksum = inet_cksum((uint16_t *)outicmp, packlen - (sizeof(*outip) + optlen)); if (outicmp->icmp_cksum == 0) outicmp->icmp_cksum = 0xffff; diff --git a/networking/udhcp/dhcpc.c b/networking/udhcp/dhcpc.c index 4d755e6b8..3be09f4d7 100644 --- a/networking/udhcp/dhcpc.c +++ b/networking/udhcp/dhcpc.c @@ -739,7 +739,7 @@ static NOINLINE int udhcp_recv_raw_packet(struct dhcp_packet *dhcp_pkt, int fd) /* verify IP checksum */ check = packet.ip.check; packet.ip.check = 0; - if (check != udhcp_checksum(&packet.ip, sizeof(packet.ip))) { + if (check != inet_cksum((uint16_t *)&packet.ip, sizeof(packet.ip))) { log1("Bad IP header checksum, ignoring"); return -2; } @@ -750,7 +750,7 @@ static NOINLINE int udhcp_recv_raw_packet(struct dhcp_packet *dhcp_pkt, int fd) packet.ip.tot_len = packet.udp.len; /* yes, this is needed */ check = packet.udp.check; packet.udp.check = 0; - if (check && check != udhcp_checksum(&packet, bytes)) { + if (check && check != inet_cksum((uint16_t *)&packet, bytes)) { log1("Packet with bad UDP checksum received, ignoring"); return -2; } diff --git a/networking/udhcp/packet.c b/networking/udhcp/packet.c index 66b42c5e1..4d5ff0676 100644 --- a/networking/udhcp/packet.c +++ b/networking/udhcp/packet.c @@ -129,35 +129,6 @@ int FAST_FUNC udhcp_recv_kernel_packet(struct dhcp_packet *packet, int fd) return bytes; } -uint16_t FAST_FUNC udhcp_checksum(void *addr, int count) -{ - /* Compute Internet Checksum for "count" bytes - * beginning at location "addr". - */ - int32_t sum = 0; - uint16_t *source = (uint16_t *) addr; - - while (count > 1) { - /* This is the inner loop */ - sum += *source++; - count -= 2; - } - - /* Add left-over byte, if any */ - if (count > 0) { - /* Make sure that the left-over byte is added correctly both - * with little and big endian hosts */ - uint16_t tmp = 0; - *(uint8_t*)&tmp = *(uint8_t*)source; - sum += tmp; - } - /* Fold 32-bit sum to 16 bits */ - while (sum >> 16) - sum = (sum & 0xffff) + (sum >> 16); - - return ~sum; -} - /* Construct a ip/udp header for a packet, send packet */ int FAST_FUNC udhcp_send_raw_packet(struct dhcp_packet *dhcp_pkt, uint32_t source_nip, int source_port, @@ -212,13 +183,14 @@ int FAST_FUNC udhcp_send_raw_packet(struct dhcp_packet *dhcp_pkt, packet.udp.len = htons(UDP_DHCP_SIZE - padding); /* for UDP checksumming, ip.len is set to UDP packet len */ packet.ip.tot_len = packet.udp.len; - packet.udp.check = udhcp_checksum(&packet, IP_UDP_DHCP_SIZE - padding); + packet.udp.check = inet_cksum((uint16_t *)&packet, + IP_UDP_DHCP_SIZE - padding); /* but for sending, it is set to IP packet len */ packet.ip.tot_len = htons(IP_UDP_DHCP_SIZE - padding); packet.ip.ihl = sizeof(packet.ip) >> 2; packet.ip.version = IPVERSION; packet.ip.ttl = IPDEFTTL; - packet.ip.check = udhcp_checksum(&packet.ip, sizeof(packet.ip)); + packet.ip.check = inet_cksum((uint16_t *)&packet.ip, sizeof(packet.ip)); udhcp_dump_packet(dhcp_pkt); result = sendto(fd, &packet, IP_UDP_DHCP_SIZE - padding, /*flags:*/ 0, -- cgit v1.2.3-55-g6feb From f65c5f5c547c48b7766db58d10043a504d953aa1 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Wed, 7 Sep 2011 20:01:39 +0200 Subject: awk: next_input_file can return NULL, don't SEGV in this case. Signed-off-by: Denys Vlasenko --- editors/awk.c | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/editors/awk.c b/editors/awk.c index 7685546e5..0918026d7 100644 --- a/editors/awk.c +++ b/editors/awk.c @@ -2627,7 +2627,7 @@ static var *evaluate(node *op, var *res) rsm = iF; } - if (!rsm->F) { + if (!rsm || !rsm->F) { setvar_i(intvar[ERRNO], errno); setvar_i(res, -1); break; @@ -2961,7 +2961,7 @@ static rstream *next_input_file(void) #define rsm (G.next_input_file__rsm) #define files_happen (G.next_input_file__files_happen) - FILE *F = NULL; + FILE *F; const char *fname, *ind; if (rsm.F) @@ -2969,19 +2969,21 @@ static rstream *next_input_file(void) rsm.F = NULL; rsm.pos = rsm.adv = 0; - do { + for (;;) { if (getvar_i(intvar[ARGIND])+1 >= getvar_i(intvar[ARGC])) { if (files_happen) return NULL; fname = "-"; F = stdin; - } else { - ind = getvar_s(incvar(intvar[ARGIND])); - fname = getvar_s(findvar(iamarray(intvar[ARGV]), ind)); - if (fname && *fname && !is_assignment(fname)) - F = xfopen_stdin(fname); + break; } - } while (!F); + ind = getvar_s(incvar(intvar[ARGIND])); + fname = getvar_s(findvar(iamarray(intvar[ARGV]), ind)); + if (fname && *fname && !is_assignment(fname)) { + F = xfopen_stdin(fname); + break; + } + } files_happen = TRUE; setvar_s(intvar[FILENAME], fname); -- cgit v1.2.3-55-g6feb From 9289935cfd44992be6e403efcccf2edf074d8cc9 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Wed, 7 Sep 2011 22:19:46 +0200 Subject: Fix compile breakage Signed-off-by: Denys Vlasenko --- libbb/match_fstype.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libbb/match_fstype.c b/libbb/match_fstype.c index c792d13b3..32c3d7f18 100644 --- a/libbb/match_fstype.c +++ b/libbb/match_fstype.c @@ -10,10 +10,10 @@ * Licensed under GPLv2 or later, see file LICENSE in this source tree. */ -#ifdef HAVE_MNTENT_H - #include "libbb.h" +#ifdef HAVE_MNTENT_H + int FAST_FUNC match_fstype(const struct mntent *mt, const char *t_fstype) { int match = 1; -- cgit v1.2.3-55-g6feb From 0d0260fd1e55c39525660370094d090bc5412fe5 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Thu, 8 Sep 2011 10:59:26 +0200 Subject: inet_cksum: big-endian fix Signed-off-by: Denys Vlasenko --- libbb/inet_cksum.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/libbb/inet_cksum.c b/libbb/inet_cksum.c index 31bf8c4d9..3d5dc3adf 100644 --- a/libbb/inet_cksum.c +++ b/libbb/inet_cksum.c @@ -21,8 +21,12 @@ uint16_t FAST_FUNC inet_cksum(uint16_t *addr, int nleft) } /* Mop up an odd byte, if necessary */ - if (nleft) - sum += *(uint8_t*)addr; + if (nleft == 1) { + if (BB_LITTLE_ENDIAN) + sum += *(uint8_t*)addr; + else + sum += *(uint8_t*)addr << 8; + } /* Add back carry outs from top 16 bits to low 16 bits */ sum = (sum >> 16) + (sum & 0xffff); /* add hi 16 to low 16 */ -- cgit v1.2.3-55-g6feb From 289c47b04921a742e94bf07006eae3f0b97acc1f Mon Sep 17 00:00:00 2001 From: Baruch Siach Date: Fri, 9 Sep 2011 11:03:45 +0200 Subject: udhcp: remove the declaration of non-existent udhcp_checksum Signed-off-by: Baruch Siach Signed-off-by: Denys Vlasenko --- networking/udhcp/common.h | 2 -- 1 file changed, 2 deletions(-) diff --git a/networking/udhcp/common.h b/networking/udhcp/common.h index ad6991c94..80d97e857 100644 --- a/networking/udhcp/common.h +++ b/networking/udhcp/common.h @@ -277,8 +277,6 @@ int FAST_FUNC udhcp_str2nip(const char *str, void *arg); /* 2nd param is "struct option_set**" */ int FAST_FUNC udhcp_str2optset(const char *str, void *arg); -uint16_t udhcp_checksum(void *addr, int count) FAST_FUNC; - void udhcp_init_header(struct dhcp_packet *packet, char type) FAST_FUNC; int udhcp_recv_kernel_packet(struct dhcp_packet *packet, int fd) FAST_FUNC; -- cgit v1.2.3-55-g6feb From 12e154f0cf4dba7bc508356649f8d57ec1dbef37 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Fri, 9 Sep 2011 12:35:49 +0200 Subject: vi: prevent unlimited recursion in do_cmd(). Closes 4153 function old new delta do_cmd 4284 4194 -90 Signed-off-by: Denys Vlasenko --- editors/vi.c | 294 ++++++++++++++++++++++++++++------------------------------- 1 file changed, 139 insertions(+), 155 deletions(-) diff --git a/editors/vi.c b/editors/vi.c index 96a0c8df7..71d600834 100644 --- a/editors/vi.c +++ b/editors/vi.c @@ -3063,7 +3063,6 @@ static void refresh(int full_screen) //----- Execute a Vi Command ----------------------------------- static void do_cmd(int c) { - const char *msg = msg; // for compiler char *p, *q, *save_dot; char buf[12]; int dir; @@ -3072,8 +3071,8 @@ static void do_cmd(int c) // c1 = c; // quiet the compiler // cnt = yf = 0; // quiet the compiler -// msg = p = q = save_dot = buf; // quiet the compiler - memset(buf, '\0', 12); +// p = q = save_dot = buf; // quiet the compiler + memset(buf, '\0', sizeof(buf)); show_status_line(); @@ -3189,19 +3188,18 @@ static void do_cmd(int c) case KEYCODE_LEFT: // cursor key Left case 8: // ctrl-H- move left (This may be ERASE char) case 0x7f: // DEL- move left (This may be ERASE char) - if (--cmdcnt > 0) { - do_cmd(c); - } - dot_left(); + do { + dot_left(); + } while (--cmdcnt > 0); break; case 10: // Newline ^J case 'j': // j- goto next line, same col case KEYCODE_DOWN: // cursor key Down - if (--cmdcnt > 0) { - do_cmd(c); - } - dot_next(); // go to next B-o-l - dot = move_to_col(dot, ccol + offset); // try stay in same col + do { + dot_next(); // go to next B-o-l + // try stay in same col + dot = move_to_col(dot, ccol + offset); + } while (--cmdcnt > 0); break; case 12: // ctrl-L force redraw whole screen case 18: // ctrl-R force redraw @@ -3214,11 +3212,10 @@ static void do_cmd(int c) break; case 13: // Carriage Return ^M case '+': // +- goto next line - if (--cmdcnt > 0) { - do_cmd(c); - } - dot_next(); - dot_skip_over_ws(); + do { + dot_next(); + dot_skip_over_ws(); + } while (--cmdcnt > 0); break; case 21: // ctrl-U scroll up half screen dot_scroll((rows - 2) / 2, -1); @@ -3236,10 +3233,9 @@ static void do_cmd(int c) case ' ': // move right case 'l': // move right case KEYCODE_RIGHT: // Cursor Key Right - if (--cmdcnt > 0) { - do_cmd(c); - } - dot_right(); + do { + dot_right(); + } while (--cmdcnt > 0); break; #if ENABLE_FEATURE_VI_YANKMARK case '"': // "- name a register to use for Delete/Yank @@ -3321,11 +3317,12 @@ static void do_cmd(int c) #endif /* FEATURE_VI_YANKMARK */ case '$': // $- goto end of line case KEYCODE_END: // Cursor Key End - if (--cmdcnt > 0) { + for (;;) { + dot = end_line(dot); + if (--cmdcnt > 0) + break; dot_next(); - do_cmd(c); } - dot = end_line(dot); break; case '%': // %- find matching char of pair () [] {} for (q = dot; q < end && *q != '\n'; q++) { @@ -3350,38 +3347,35 @@ static void do_cmd(int c) // //**** fall through to ... ';' case ';': // ;- look at rest of line for last forward char - if (--cmdcnt > 0) { - do_cmd(';'); - } - if (last_forward_char == 0) - break; - q = dot + 1; - while (q < end - 1 && *q != '\n' && *q != last_forward_char) { - q++; - } - if (*q == last_forward_char) - dot = q; + do { + if (last_forward_char == 0) + break; + q = dot + 1; + while (q < end - 1 && *q != '\n' && *q != last_forward_char) { + q++; + } + if (*q == last_forward_char) + dot = q; + } while (--cmdcnt > 0); break; case ',': // repeat latest 'f' in opposite direction - if (--cmdcnt > 0) { - do_cmd(','); - } if (last_forward_char == 0) break; - q = dot - 1; - while (q >= text && *q != '\n' && *q != last_forward_char) { - q--; - } - if (q >= text && *q == last_forward_char) - dot = q; + do { + q = dot - 1; + while (q >= text && *q != '\n' && *q != last_forward_char) { + q--; + } + if (q >= text && *q == last_forward_char) + dot = q; + } while (--cmdcnt > 0); break; case '-': // -- goto prev line - if (--cmdcnt > 0) { - do_cmd(c); - } - dot_prev(); - dot_skip_over_ws(); + do { + dot_prev(); + dot_skip_over_ws(); + } while (--cmdcnt > 0); break; #if ENABLE_FEATURE_VI_DOT_CMD case '.': // .- repeat the last modifying command @@ -3413,9 +3407,6 @@ static void do_cmd(int c) // user changed mind and erased the "/"- do nothing break; case 'N': // N- backward search for last pattern - if (--cmdcnt > 0) { - do_cmd(c); - } dir = BACK; // assume BACKWARD search p = dot - 1; if (last_search_pattern[0] == '?') { @@ -3427,41 +3418,41 @@ static void do_cmd(int c) case 'n': // n- repeat search for last pattern // search rest of text[] starting at next char // if search fails return orignal "p" not the "p+1" address - if (--cmdcnt > 0) { - do_cmd(c); - } + do { + const char *msg; dc3: - dir = FORWARD; // assume FORWARD search - p = dot + 1; - if (last_search_pattern[0] == '?') { - dir = BACK; - p = dot - 1; - } + dir = FORWARD; // assume FORWARD search + p = dot + 1; + if (last_search_pattern[0] == '?') { + dir = BACK; + p = dot - 1; + } dc4: - q = char_search(p, last_search_pattern + 1, dir, FULL); - if (q != NULL) { - dot = q; // good search, update "dot" - msg = ""; - goto dc2; - } - // no pattern found between "dot" and "end"- continue at top - p = text; - if (dir == BACK) { - p = end - 1; - } - q = char_search(p, last_search_pattern + 1, dir, FULL); - if (q != NULL) { // found something - dot = q; // found new pattern- goto it - msg = "search hit BOTTOM, continuing at TOP"; + q = char_search(p, last_search_pattern + 1, dir, FULL); + if (q != NULL) { + dot = q; // good search, update "dot" + msg = NULL; + goto dc2; + } + // no pattern found between "dot" and "end"- continue at top + p = text; if (dir == BACK) { - msg = "search hit TOP, continuing at BOTTOM"; + p = end - 1; + } + q = char_search(p, last_search_pattern + 1, dir, FULL); + if (q != NULL) { // found something + dot = q; // found new pattern- goto it + msg = "search hit BOTTOM, continuing at TOP"; + if (dir == BACK) { + msg = "search hit TOP, continuing at BOTTOM"; + } + } else { + msg = "Pattern not found"; } - } else { - msg = "Pattern not found"; - } dc2: - if (*msg) - status_line_bold("%s", msg); + if (msg) + status_line_bold("%s", msg); + } while (--cmdcnt > 0); break; case '{': // {- move backward paragraph q = char_search(dot, "\n\n", BACK, FULL); @@ -3580,18 +3571,17 @@ static void do_cmd(int c) case 'B': // B- back a blank-delimited Word case 'E': // E- end of a blank-delimited word case 'W': // W- forward a blank-delimited word - if (--cmdcnt > 0) { - do_cmd(c); - } dir = FORWARD; if (c == 'B') dir = BACK; - if (c == 'W' || isspace(dot[dir])) { - dot = skip_thing(dot, 1, dir, S_TO_WS); - dot = skip_thing(dot, 2, dir, S_OVER_WS); - } - if (c != 'W') - dot = skip_thing(dot, 1, dir, S_BEFORE_WS); + do { + if (c == 'W' || isspace(dot[dir])) { + dot = skip_thing(dot, 1, dir, S_TO_WS); + dot = skip_thing(dot, 2, dir, S_OVER_WS); + } + if (c != 'W') + dot = skip_thing(dot, 1, dir, S_BEFORE_WS); + } while (--cmdcnt > 0); break; case 'C': // C- Change to e-o-l case 'D': // D- delete to e-o-l @@ -3642,20 +3632,19 @@ static void do_cmd(int c) case 'i': // i- insert before current char case KEYCODE_INSERT: // Cursor Key Insert dc_i: - cmd_mode = 1; // start insrting + cmd_mode = 1; // start inserting break; case 'J': // J- join current and next lines together - if (--cmdcnt > 1) { - do_cmd(c); - } - dot_end(); // move to NL - if (dot < end - 1) { // make sure not last char in text[] - *dot++ = ' '; // replace NL with space - file_modified++; - while (isblank(*dot)) { // delete leading WS - dot_delete(); + do { + dot_end(); // move to NL + if (dot < end - 1) { // make sure not last char in text[] + *dot++ = ' '; // replace NL with space + file_modified++; + while (isblank(*dot)) { // delete leading WS + dot_delete(); + } } - } + } while (--cmdcnt > 0); end_cmd_q(); // stop adding to q break; case 'L': // L- goto bottom line on screen @@ -3699,20 +3688,19 @@ static void do_cmd(int c) case 'X': // X- delete char before dot case 'x': // x- delete the current char case 's': // s- substitute the current char - if (--cmdcnt > 0) { - do_cmd(c); - } dir = 0; if (c == 'X') dir = -1; - if (dot[dir] != '\n') { - if (c == 'X') - dot--; // delete prev char - dot = yank_delete(dot, dot, 0, YANKDEL); // delete char - } - if (c == 's') - goto dc_i; // start insrting + do { + if (dot[dir] != '\n') { + if (c == 'X') + dot--; // delete prev char + dot = yank_delete(dot, dot, 0, YANKDEL); // delete char + } + } while (--cmdcnt > 0); end_cmd_q(); // stop adding to q + if (c == 's') + goto dc_i; // start inserting break; case 'Z': // Z- if modified, {write}; exit // ZZ means to save file (if necessary), then exit @@ -3743,23 +3731,22 @@ static void do_cmd(int c) break; case 'b': // b- back a word case 'e': // e- end of word - if (--cmdcnt > 0) { - do_cmd(c); - } dir = FORWARD; if (c == 'b') dir = BACK; - if ((dot + dir) < text || (dot + dir) > end - 1) - break; - dot += dir; - if (isspace(*dot)) { - dot = skip_thing(dot, (c == 'e') ? 2 : 1, dir, S_OVER_WS); - } - if (isalnum(*dot) || *dot == '_') { - dot = skip_thing(dot, 1, dir, S_END_ALNUM); - } else if (ispunct(*dot)) { - dot = skip_thing(dot, 1, dir, S_END_PUNCT); - } + do { + if ((dot + dir) < text || (dot + dir) > end - 1) + break; + dot += dir; + if (isspace(*dot)) { + dot = skip_thing(dot, (c == 'e') ? 2 : 1, dir, S_OVER_WS); + } + if (isalnum(*dot) || *dot == '_') { + dot = skip_thing(dot, 1, dir, S_END_ALNUM); + } else if (ispunct(*dot)) { + dot = skip_thing(dot, 1, dir, S_END_PUNCT); + } + } while (--cmdcnt > 0); break; case 'c': // c- change something case 'd': // d- delete something @@ -3844,11 +3831,10 @@ static void do_cmd(int c) } case 'k': // k- goto prev line, same col case KEYCODE_UP: // cursor key Up - if (--cmdcnt > 0) { - do_cmd(c); - } - dot_prev(); - dot = move_to_col(dot, ccol + offset); // try stay in same col + do { + dot_prev(); + dot = move_to_col(dot, ccol + offset); // try stay in same col + } while (--cmdcnt > 0); break; case 'r': // r- replace the current char with user input c1 = get_one_char(); // get the replacement char @@ -3866,19 +3852,18 @@ static void do_cmd(int c) last_forward_char = 0; break; case 'w': // w- forward a word - if (--cmdcnt > 0) { - do_cmd(c); - } - if (isalnum(*dot) || *dot == '_') { // we are on ALNUM - dot = skip_thing(dot, 1, FORWARD, S_END_ALNUM); - } else if (ispunct(*dot)) { // we are on PUNCT - dot = skip_thing(dot, 1, FORWARD, S_END_PUNCT); - } - if (dot < end - 1) - dot++; // move over word - if (isspace(*dot)) { - dot = skip_thing(dot, 2, FORWARD, S_OVER_WS); - } + do { + if (isalnum(*dot) || *dot == '_') { // we are on ALNUM + dot = skip_thing(dot, 1, FORWARD, S_END_ALNUM); + } else if (ispunct(*dot)) { // we are on PUNCT + dot = skip_thing(dot, 1, FORWARD, S_END_PUNCT); + } + if (dot < end - 1) + dot++; // move over word + if (isspace(*dot)) { + dot = skip_thing(dot, 2, FORWARD, S_OVER_WS); + } + } while (--cmdcnt > 0); break; case 'z': // z- c1 = get_one_char(); // get the replacement char @@ -3894,17 +3879,16 @@ static void do_cmd(int c) dot = move_to_col(dot, cmdcnt - 1); // try to move to column break; case '~': // ~- flip the case of letters a-z -> A-Z - if (--cmdcnt > 0) { - do_cmd(c); - } - if (islower(*dot)) { - *dot = toupper(*dot); - file_modified++; - } else if (isupper(*dot)) { - *dot = tolower(*dot); - file_modified++; - } - dot_right(); + do { + if (islower(*dot)) { + *dot = toupper(*dot); + file_modified++; + } else if (isupper(*dot)) { + *dot = tolower(*dot); + file_modified++; + } + dot_right(); + } while (--cmdcnt > 0); end_cmd_q(); // stop adding to q break; //----- The Cursor and Function Keys ----------------------------- -- cgit v1.2.3-55-g6feb From 831756bac440ce5f582305a81fd2b842eb255fc3 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Fri, 9 Sep 2011 17:30:55 +0200 Subject: unzip: fflush stdout before reading interative y/n answer from stdin Signed-off-by: Denys Vlasenko --- archival/unzip.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/archival/unzip.c b/archival/unzip.c index 4fa729326..4cc98cdb2 100644 --- a/archival/unzip.c +++ b/archival/unzip.c @@ -235,7 +235,7 @@ static void unzip_create_leading_dirs(const char *fn) /* Create all leading directories */ char *name = xstrdup(fn); if (bb_make_directory(dirname(name), 0777, FILEUTILS_RECUR)) { - bb_error_msg_and_die("exiting"); /* bb_make_directory is noisy */ + xfunc_die(); /* bb_make_directory is noisy */ } free(name); } @@ -595,7 +595,7 @@ int unzip_main(int argc, char **argv) } unzip_create_leading_dirs(dst_fn); if (bb_make_directory(dst_fn, dir_mode, 0)) { - bb_error_msg_and_die("exiting"); + xfunc_die(); } } else { if (!S_ISDIR(stat_buf.st_mode)) { @@ -619,6 +619,7 @@ int unzip_main(int argc, char **argv) i = 'y'; } else { printf("replace %s? [y]es, [n]o, [A]ll, [N]one, [r]ename: ", dst_fn); + fflush_all(); if (!fgets(key_buf, sizeof(key_buf), stdin)) { bb_perror_msg_and_die("can't read input"); } -- cgit v1.2.3-55-g6feb From e0894f567ad379f554300886ae3adf087be1efa2 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Fri, 9 Sep 2011 18:00:44 +0200 Subject: Android build fixes and alternate (hopefully simpler) defconfig for it Signed-off-by: Denys Vlasenko --- Makefile.flags | 5 + configs/android2_defconfig | 995 +++++++++++++++++++++++++++++++++++++++++++++ include/platform.h | 2 +- 3 files changed, 1001 insertions(+), 1 deletion(-) create mode 100644 configs/android2_defconfig diff --git a/Makefile.flags b/Makefile.flags index b3e13713d..7e1c6030c 100644 --- a/Makefile.flags +++ b/Makefile.flags @@ -97,7 +97,12 @@ CFLAGS += $(strip $(subst ",,$(CONFIG_EXTRA_CFLAGS))) #")) endif +ifneq ($(CONFIG_CROSS_COMPILER_PREFIX),"arm-linux-androideabi-") LDLIBS += m crypt +else +# Android libc has no crypt. TODO: make a generic CONFIG_LINK_WITH_CRYPT option? +LDLIBS += m +endif ifeq ($(CONFIG_PAM),y) LDLIBS += pam pam_misc diff --git a/configs/android2_defconfig b/configs/android2_defconfig new file mode 100644 index 000000000..05920b11f --- /dev/null +++ b/configs/android2_defconfig @@ -0,0 +1,995 @@ +# Tested with the standalone toolchain from ndk r6: +# android-ndk-r6/build/tools/make-standalone-toolchain.sh --platform=android-8 +# +CONFIG_HAVE_DOT_CONFIG=y + +# +# Busybox Settings +# + +# +# General Configuration +# +# CONFIG_DESKTOP is not set +# CONFIG_EXTRA_COMPAT is not set +# CONFIG_INCLUDE_SUSv2 is not set +# CONFIG_USE_PORTABLE_CODE is not set +CONFIG_PLATFORM_LINUX=y +CONFIG_FEATURE_BUFFERS_USE_MALLOC=y +# CONFIG_FEATURE_BUFFERS_GO_ON_STACK is not set +# CONFIG_FEATURE_BUFFERS_GO_IN_BSS is not set +# CONFIG_SHOW_USAGE is not set +# CONFIG_FEATURE_VERBOSE_USAGE is not set +# CONFIG_FEATURE_COMPRESS_USAGE is not set +# CONFIG_FEATURE_INSTALLER is not set +# CONFIG_INSTALL_NO_USR is not set +# CONFIG_LOCALE_SUPPORT is not set +# CONFIG_UNICODE_SUPPORT is not set +# CONFIG_UNICODE_USING_LOCALE is not set +# CONFIG_FEATURE_CHECK_UNICODE_IN_ENV is not set +CONFIG_SUBST_WCHAR=0 +CONFIG_LAST_SUPPORTED_WCHAR=0 +# CONFIG_UNICODE_COMBINING_WCHARS is not set +# CONFIG_UNICODE_WIDE_WCHARS is not set +# CONFIG_UNICODE_BIDI_SUPPORT is not set +# CONFIG_UNICODE_NEUTRAL_TABLE is not set +# CONFIG_UNICODE_PRESERVE_BROKEN is not set +# CONFIG_LONG_OPTS is not set +# CONFIG_FEATURE_DEVPTS is not set +# CONFIG_FEATURE_CLEAN_UP is not set +# CONFIG_FEATURE_UTMP is not set +# CONFIG_FEATURE_WTMP is not set +# CONFIG_FEATURE_PIDFILE is not set +# CONFIG_FEATURE_SUID is not set +# CONFIG_FEATURE_SUID_CONFIG is not set +# CONFIG_FEATURE_SUID_CONFIG_QUIET is not set +# CONFIG_SELINUX is not set +# CONFIG_FEATURE_PREFER_APPLETS is not set +CONFIG_BUSYBOX_EXEC_PATH="/proc/self/exe" +CONFIG_FEATURE_SYSLOG=y +# CONFIG_FEATURE_HAVE_RPC is not set + +# +# Build Options +# +# CONFIG_STATIC is not set +# CONFIG_PIE is not set +# CONFIG_NOMMU is not set +# CONFIG_BUILD_LIBBUSYBOX is not set +# CONFIG_FEATURE_INDIVIDUAL is not set +# CONFIG_FEATURE_SHARED_BUSYBOX is not set +# CONFIG_LFS is not set +CONFIG_CROSS_COMPILER_PREFIX="arm-linux-androideabi-" +CONFIG_EXTRA_CFLAGS="" + +# +# Debugging Options +# +# CONFIG_DEBUG is not set +# CONFIG_DEBUG_PESSIMIZE is not set +# CONFIG_WERROR is not set +CONFIG_NO_DEBUG_LIB=y +# CONFIG_DMALLOC is not set +# CONFIG_EFENCE is not set + +# +# Installation Options ("make install" behavior) +# +CONFIG_INSTALL_APPLET_SYMLINKS=y +# CONFIG_INSTALL_APPLET_HARDLINKS is not set +# CONFIG_INSTALL_APPLET_SCRIPT_WRAPPERS is not set +# CONFIG_INSTALL_APPLET_DONT is not set +# CONFIG_INSTALL_SH_APPLET_SYMLINK is not set +# CONFIG_INSTALL_SH_APPLET_HARDLINK is not set +# CONFIG_INSTALL_SH_APPLET_SCRIPT_WRAPPER is not set +CONFIG_PREFIX="./_install" + +# +# Busybox Library Tuning +# +# CONFIG_FEATURE_SYSTEMD is not set +# CONFIG_FEATURE_RTMINMAX is not set +CONFIG_PASSWORD_MINLEN=6 +CONFIG_MD5_SIZE_VS_SPEED=2 +# CONFIG_FEATURE_FAST_TOP is not set +# CONFIG_FEATURE_ETC_NETWORKS is not set +CONFIG_FEATURE_USE_TERMIOS=y +# CONFIG_FEATURE_EDITING is not set +CONFIG_FEATURE_EDITING_MAX_LEN=0 +# CONFIG_FEATURE_EDITING_VI is not set +CONFIG_FEATURE_EDITING_HISTORY=0 +# CONFIG_FEATURE_EDITING_SAVEHISTORY is not set +# CONFIG_FEATURE_TAB_COMPLETION is not set +# CONFIG_FEATURE_USERNAME_COMPLETION is not set +# CONFIG_FEATURE_EDITING_FANCY_PROMPT is not set +# CONFIG_FEATURE_EDITING_ASK_TERMINAL is not set +# CONFIG_FEATURE_NON_POSIX_CP is not set +# CONFIG_FEATURE_VERBOSE_CP_MESSAGE is not set +CONFIG_FEATURE_COPYBUF_KB=4 +# CONFIG_FEATURE_SKIP_ROOTFS is not set +# CONFIG_MONOTONIC_SYSCALL is not set +# CONFIG_IOCTL_HEX2STR_ERROR is not set +# CONFIG_FEATURE_HWIB is not set + +# +# Applets +# + +# +# Archival Utilities +# +CONFIG_FEATURE_SEAMLESS_XZ=y +CONFIG_FEATURE_SEAMLESS_LZMA=y +CONFIG_FEATURE_SEAMLESS_BZ2=y +CONFIG_FEATURE_SEAMLESS_GZ=y +CONFIG_FEATURE_SEAMLESS_Z=y +CONFIG_AR=y +CONFIG_FEATURE_AR_LONG_FILENAMES=y +CONFIG_FEATURE_AR_CREATE=y +CONFIG_BUNZIP2=y +CONFIG_BZIP2=y +CONFIG_CPIO=y +CONFIG_FEATURE_CPIO_O=y +CONFIG_FEATURE_CPIO_P=y +CONFIG_DPKG=y +CONFIG_DPKG_DEB=y +# CONFIG_FEATURE_DPKG_DEB_EXTRACT_ONLY is not set +CONFIG_GUNZIP=y +CONFIG_GZIP=y +# CONFIG_FEATURE_GZIP_LONG_OPTIONS is not set +CONFIG_LZOP=y +CONFIG_LZOP_COMPR_HIGH=y +CONFIG_RPM2CPIO=y +CONFIG_RPM=y +CONFIG_TAR=y +CONFIG_FEATURE_TAR_CREATE=y +CONFIG_FEATURE_TAR_AUTODETECT=y +CONFIG_FEATURE_TAR_FROM=y +CONFIG_FEATURE_TAR_OLDGNU_COMPATIBILITY=y +CONFIG_FEATURE_TAR_OLDSUN_COMPATIBILITY=y +CONFIG_FEATURE_TAR_GNU_EXTENSIONS=y +# CONFIG_FEATURE_TAR_LONG_OPTIONS is not set +# CONFIG_FEATURE_TAR_TO_COMMAND is not set +CONFIG_FEATURE_TAR_UNAME_GNAME=y +CONFIG_FEATURE_TAR_NOPRESERVE_TIME=y +# CONFIG_FEATURE_TAR_SELINUX is not set +CONFIG_UNCOMPRESS=y +CONFIG_UNLZMA=y +CONFIG_FEATURE_LZMA_FAST=y +CONFIG_LZMA=y +CONFIG_UNXZ=y +CONFIG_XZ=y +CONFIG_UNZIP=y + +# +# Coreutils +# +CONFIG_BASENAME=y +CONFIG_CAT=y +# CONFIG_DATE is not set +# CONFIG_FEATURE_DATE_ISOFMT is not set +# CONFIG_FEATURE_DATE_NANO is not set +# CONFIG_FEATURE_DATE_COMPAT is not set +# CONFIG_ID is not set +# CONFIG_GROUPS is not set +CONFIG_TEST=y +CONFIG_FEATURE_TEST_64=y +CONFIG_TOUCH=y +CONFIG_TR=y +CONFIG_FEATURE_TR_CLASSES=y +CONFIG_FEATURE_TR_EQUIV=y +CONFIG_BASE64=y +CONFIG_CAL=y +CONFIG_CATV=y +CONFIG_CHGRP=y +CONFIG_CHMOD=y +CONFIG_CHOWN=y +# CONFIG_FEATURE_CHOWN_LONG_OPTIONS is not set +CONFIG_CHROOT=y +CONFIG_CKSUM=y +CONFIG_COMM=y +CONFIG_CP=y +# CONFIG_FEATURE_CP_LONG_OPTIONS is not set +CONFIG_CUT=y +CONFIG_DD=y +CONFIG_FEATURE_DD_SIGNAL_HANDLING=y +CONFIG_FEATURE_DD_THIRD_STATUS_LINE=y +CONFIG_FEATURE_DD_IBS_OBS=y +# CONFIG_DF is not set +# CONFIG_FEATURE_DF_FANCY is not set +CONFIG_DIRNAME=y +CONFIG_DOS2UNIX=y +CONFIG_UNIX2DOS=y +CONFIG_DU=y +CONFIG_FEATURE_DU_DEFAULT_BLOCKSIZE_1K=y +CONFIG_ECHO=y +CONFIG_FEATURE_FANCY_ECHO=y +# CONFIG_ENV is not set +# CONFIG_FEATURE_ENV_LONG_OPTIONS is not set +CONFIG_EXPAND=y +# CONFIG_FEATURE_EXPAND_LONG_OPTIONS is not set +# CONFIG_EXPR is not set +# CONFIG_EXPR_MATH_SUPPORT_64 is not set +CONFIG_FALSE=y +CONFIG_FOLD=y +# CONFIG_FSYNC is not set +CONFIG_HEAD=y +CONFIG_FEATURE_FANCY_HEAD=y +# CONFIG_HOSTID is not set +CONFIG_INSTALL=y +# CONFIG_FEATURE_INSTALL_LONG_OPTIONS is not set +CONFIG_LN=y +# CONFIG_LOGNAME is not set +CONFIG_LS=y +CONFIG_FEATURE_LS_FILETYPES=y +CONFIG_FEATURE_LS_FOLLOWLINKS=y +CONFIG_FEATURE_LS_RECURSIVE=y +CONFIG_FEATURE_LS_SORTFILES=y +CONFIG_FEATURE_LS_TIMESTAMPS=y +CONFIG_FEATURE_LS_USERNAME=y +# CONFIG_FEATURE_LS_COLOR is not set +# CONFIG_FEATURE_LS_COLOR_IS_DEFAULT is not set +CONFIG_MD5SUM=y +CONFIG_MKDIR=y +# CONFIG_FEATURE_MKDIR_LONG_OPTIONS is not set +CONFIG_MKFIFO=y +CONFIG_MKNOD=y +CONFIG_MV=y +# CONFIG_FEATURE_MV_LONG_OPTIONS is not set +CONFIG_NICE=y +CONFIG_NOHUP=y +CONFIG_OD=y +CONFIG_PRINTENV=y +CONFIG_PRINTF=y +CONFIG_PWD=y +CONFIG_READLINK=y +CONFIG_FEATURE_READLINK_FOLLOW=y +CONFIG_REALPATH=y +CONFIG_RM=y +CONFIG_RMDIR=y +# CONFIG_FEATURE_RMDIR_LONG_OPTIONS is not set +CONFIG_SEQ=y +CONFIG_SHA1SUM=y +CONFIG_SHA256SUM=y +CONFIG_SHA512SUM=y +CONFIG_SLEEP=y +CONFIG_FEATURE_FANCY_SLEEP=y +CONFIG_FEATURE_FLOAT_SLEEP=y +CONFIG_SORT=y +CONFIG_FEATURE_SORT_BIG=y +CONFIG_SPLIT=y +CONFIG_FEATURE_SPLIT_FANCY=y +# CONFIG_STAT is not set +# CONFIG_FEATURE_STAT_FORMAT is not set +CONFIG_STTY=y +CONFIG_SUM=y +CONFIG_SYNC=y +CONFIG_TAC=y +CONFIG_TAIL=y +CONFIG_FEATURE_FANCY_TAIL=y +CONFIG_TEE=y +CONFIG_FEATURE_TEE_USE_BLOCK_IO=y +CONFIG_TRUE=y +# CONFIG_TTY is not set +CONFIG_UNAME=y +CONFIG_UNEXPAND=y +# CONFIG_FEATURE_UNEXPAND_LONG_OPTIONS is not set +CONFIG_UNIQ=y +# CONFIG_USLEEP is not set +CONFIG_UUDECODE=y +CONFIG_UUENCODE=y +CONFIG_WC=y +CONFIG_FEATURE_WC_LARGE=y +# CONFIG_WHO is not set +CONFIG_WHOAMI=y +CONFIG_YES=y + +# +# Common options for cp and mv +# +CONFIG_FEATURE_PRESERVE_HARDLINKS=y + +# +# Common options for ls, more and telnet +# +CONFIG_FEATURE_AUTOWIDTH=y + +# +# Common options for df, du, ls +# +CONFIG_FEATURE_HUMAN_READABLE=y + +# +# Common options for md5sum, sha1sum, sha256sum, sha512sum +# +CONFIG_FEATURE_MD5_SHA1_SUM_CHECK=y + +# +# Console Utilities +# +CONFIG_CHVT=y +CONFIG_FGCONSOLE=y +CONFIG_CLEAR=y +CONFIG_DEALLOCVT=y +CONFIG_DUMPKMAP=y +# CONFIG_KBD_MODE is not set +# CONFIG_LOADFONT is not set +CONFIG_LOADKMAP=y +CONFIG_OPENVT=y +CONFIG_RESET=y +CONFIG_RESIZE=y +CONFIG_FEATURE_RESIZE_PRINT=y +CONFIG_SETCONSOLE=y +# CONFIG_FEATURE_SETCONSOLE_LONG_OPTIONS is not set +# CONFIG_SETFONT is not set +# CONFIG_FEATURE_SETFONT_TEXTUAL_MAP is not set +CONFIG_DEFAULT_SETFONT_DIR="" +CONFIG_SETKEYCODES=y +CONFIG_SETLOGCONS=y +CONFIG_SHOWKEY=y +# CONFIG_FEATURE_LOADFONT_PSF2 is not set +# CONFIG_FEATURE_LOADFONT_RAW is not set + +# +# Debian Utilities +# +CONFIG_MKTEMP=y +CONFIG_PIPE_PROGRESS=y +CONFIG_RUN_PARTS=y +# CONFIG_FEATURE_RUN_PARTS_LONG_OPTIONS is not set +CONFIG_FEATURE_RUN_PARTS_FANCY=y +CONFIG_START_STOP_DAEMON=y +CONFIG_FEATURE_START_STOP_DAEMON_FANCY=y +# CONFIG_FEATURE_START_STOP_DAEMON_LONG_OPTIONS is not set +CONFIG_WHICH=y + +# +# Editors +# +CONFIG_PATCH=y +# CONFIG_VI is not set +CONFIG_FEATURE_VI_MAX_LEN=0 +# CONFIG_FEATURE_VI_8BIT is not set +# CONFIG_FEATURE_VI_COLON is not set +# CONFIG_FEATURE_VI_YANKMARK is not set +# CONFIG_FEATURE_VI_SEARCH is not set +# CONFIG_FEATURE_VI_REGEX_SEARCH is not set +# CONFIG_FEATURE_VI_USE_SIGNALS is not set +# CONFIG_FEATURE_VI_DOT_CMD is not set +# CONFIG_FEATURE_VI_READONLY is not set +# CONFIG_FEATURE_VI_SETOPTS is not set +# CONFIG_FEATURE_VI_SET is not set +# CONFIG_FEATURE_VI_WIN_RESIZE is not set +# CONFIG_FEATURE_VI_ASK_TERMINAL is not set +# CONFIG_FEATURE_VI_OPTIMIZE_CURSOR is not set +# CONFIG_AWK is not set +# CONFIG_FEATURE_AWK_LIBM is not set +CONFIG_CMP=y +CONFIG_DIFF=y +# CONFIG_FEATURE_DIFF_LONG_OPTIONS is not set +CONFIG_FEATURE_DIFF_DIR=y +# CONFIG_ED is not set +# CONFIG_SED is not set +# CONFIG_FEATURE_ALLOW_EXEC is not set + +# +# Finding Utilities +# +# CONFIG_FIND is not set +# CONFIG_FEATURE_FIND_PRINT0 is not set +# CONFIG_FEATURE_FIND_MTIME is not set +# CONFIG_FEATURE_FIND_MMIN is not set +# CONFIG_FEATURE_FIND_PERM is not set +# CONFIG_FEATURE_FIND_TYPE is not set +# CONFIG_FEATURE_FIND_XDEV is not set +# CONFIG_FEATURE_FIND_MAXDEPTH is not set +# CONFIG_FEATURE_FIND_NEWER is not set +# CONFIG_FEATURE_FIND_INUM is not set +# CONFIG_FEATURE_FIND_EXEC is not set +# CONFIG_FEATURE_FIND_USER is not set +# CONFIG_FEATURE_FIND_GROUP is not set +# CONFIG_FEATURE_FIND_NOT is not set +# CONFIG_FEATURE_FIND_DEPTH is not set +# CONFIG_FEATURE_FIND_PAREN is not set +# CONFIG_FEATURE_FIND_SIZE is not set +# CONFIG_FEATURE_FIND_PRUNE is not set +# CONFIG_FEATURE_FIND_DELETE is not set +# CONFIG_FEATURE_FIND_PATH is not set +# CONFIG_FEATURE_FIND_REGEX is not set +# CONFIG_FEATURE_FIND_CONTEXT is not set +# CONFIG_FEATURE_FIND_LINKS is not set +# CONFIG_GREP is not set +# CONFIG_FEATURE_GREP_EGREP_ALIAS is not set +# CONFIG_FEATURE_GREP_FGREP_ALIAS is not set +# CONFIG_FEATURE_GREP_CONTEXT is not set +CONFIG_XARGS=y +CONFIG_FEATURE_XARGS_SUPPORT_CONFIRMATION=y +CONFIG_FEATURE_XARGS_SUPPORT_QUOTES=y +CONFIG_FEATURE_XARGS_SUPPORT_TERMOPT=y +CONFIG_FEATURE_XARGS_SUPPORT_ZERO_TERM=y + +# +# Init Utilities +# +# CONFIG_BOOTCHARTD is not set +# CONFIG_FEATURE_BOOTCHARTD_BLOATED_HEADER is not set +# CONFIG_FEATURE_BOOTCHARTD_CONFIG_FILE is not set +CONFIG_HALT=y +# CONFIG_FEATURE_CALL_TELINIT is not set +CONFIG_TELINIT_PATH="" +CONFIG_INIT=y +CONFIG_FEATURE_USE_INITTAB=y +# CONFIG_FEATURE_KILL_REMOVED is not set +CONFIG_FEATURE_KILL_DELAY=0 +CONFIG_FEATURE_INIT_SCTTY=y +CONFIG_FEATURE_INIT_SYSLOG=y +CONFIG_FEATURE_EXTRA_QUIET=y +CONFIG_FEATURE_INIT_COREDUMPS=y +CONFIG_FEATURE_INITRD=y +CONFIG_INIT_TERMINAL_TYPE="linux" +CONFIG_MESG=y +CONFIG_FEATURE_MESG_ENABLE_ONLY_GROUP=y + +# +# Login/Password Management Utilities +# +# CONFIG_ADD_SHELL is not set +# CONFIG_REMOVE_SHELL is not set +# CONFIG_FEATURE_SHADOWPASSWDS is not set +# CONFIG_USE_BB_PWD_GRP is not set +# CONFIG_USE_BB_SHADOW is not set +# CONFIG_USE_BB_CRYPT is not set +# CONFIG_USE_BB_CRYPT_SHA is not set +# CONFIG_ADDUSER is not set +# CONFIG_FEATURE_ADDUSER_LONG_OPTIONS is not set +# CONFIG_FEATURE_CHECK_NAMES is not set +CONFIG_FIRST_SYSTEM_ID=0 +CONFIG_LAST_SYSTEM_ID=0 +# CONFIG_ADDGROUP is not set +# CONFIG_FEATURE_ADDGROUP_LONG_OPTIONS is not set +# CONFIG_FEATURE_ADDUSER_TO_GROUP is not set +# CONFIG_DELUSER is not set +# CONFIG_DELGROUP is not set +# CONFIG_FEATURE_DEL_USER_FROM_GROUP is not set +# CONFIG_GETTY is not set +# CONFIG_LOGIN is not set +# CONFIG_PAM is not set +# CONFIG_LOGIN_SCRIPTS is not set +# CONFIG_FEATURE_NOLOGIN is not set +# CONFIG_FEATURE_SECURETTY is not set +# CONFIG_PASSWD is not set +# CONFIG_FEATURE_PASSWD_WEAK_CHECK is not set +# CONFIG_CRYPTPW is not set +# CONFIG_CHPASSWD is not set +# CONFIG_SU is not set +# CONFIG_FEATURE_SU_SYSLOG is not set +# CONFIG_FEATURE_SU_CHECKS_SHELLS is not set +# CONFIG_SULOGIN is not set +# CONFIG_VLOCK is not set + +# +# Linux Ext2 FS Progs +# +CONFIG_CHATTR=y +# CONFIG_FSCK is not set +CONFIG_LSATTR=y +CONFIG_TUNE2FS=y + +# +# Linux Module Utilities +# +CONFIG_MODINFO=y +CONFIG_MODPROBE_SMALL=y +CONFIG_FEATURE_MODPROBE_SMALL_OPTIONS_ON_CMDLINE=y +CONFIG_FEATURE_MODPROBE_SMALL_CHECK_ALREADY_LOADED=y +# CONFIG_INSMOD is not set +# CONFIG_RMMOD is not set +# CONFIG_LSMOD is not set +# CONFIG_FEATURE_LSMOD_PRETTY_2_6_OUTPUT is not set +# CONFIG_MODPROBE is not set +# CONFIG_FEATURE_MODPROBE_BLACKLIST is not set +# CONFIG_DEPMOD is not set + +# +# Options common to multiple modutils +# +# CONFIG_FEATURE_2_4_MODULES is not set +# CONFIG_FEATURE_INSMOD_TRY_MMAP is not set +# CONFIG_FEATURE_INSMOD_VERSION_CHECKING is not set +# CONFIG_FEATURE_INSMOD_KSYMOOPS_SYMBOLS is not set +# CONFIG_FEATURE_INSMOD_LOADINKMEM is not set +# CONFIG_FEATURE_INSMOD_LOAD_MAP is not set +# CONFIG_FEATURE_INSMOD_LOAD_MAP_FULL is not set +# CONFIG_FEATURE_CHECK_TAINTED_MODULE is not set +# CONFIG_FEATURE_MODUTILS_ALIAS is not set +# CONFIG_FEATURE_MODUTILS_SYMBOLS is not set +CONFIG_DEFAULT_MODULES_DIR="/lib/modules" +CONFIG_DEFAULT_DEPMOD_FILE="modules.dep" + +# +# Linux System Utilities +# +CONFIG_BLOCKDEV=y +CONFIG_REV=y +# CONFIG_ACPID is not set +# CONFIG_FEATURE_ACPID_COMPAT is not set +CONFIG_BLKID=y +# CONFIG_FEATURE_BLKID_TYPE is not set +CONFIG_DMESG=y +CONFIG_FEATURE_DMESG_PRETTY=y +CONFIG_FBSET=y +CONFIG_FEATURE_FBSET_FANCY=y +CONFIG_FEATURE_FBSET_READMODE=y +CONFIG_FDFLUSH=y +CONFIG_FDFORMAT=y +CONFIG_FDISK=y +CONFIG_FDISK_SUPPORT_LARGE_DISKS=y +CONFIG_FEATURE_FDISK_WRITABLE=y +# CONFIG_FEATURE_AIX_LABEL is not set +# CONFIG_FEATURE_SGI_LABEL is not set +# CONFIG_FEATURE_SUN_LABEL is not set +# CONFIG_FEATURE_OSF_LABEL is not set +# CONFIG_FEATURE_GPT_LABEL is not set +CONFIG_FEATURE_FDISK_ADVANCED=y +CONFIG_FINDFS=y +CONFIG_FLOCK=y +CONFIG_FREERAMDISK=y +# CONFIG_FSCK_MINIX is not set +# CONFIG_MKFS_EXT2 is not set +# CONFIG_MKFS_MINIX is not set +# CONFIG_FEATURE_MINIX2 is not set +# CONFIG_MKFS_REISER is not set +# CONFIG_MKFS_VFAT is not set +CONFIG_GETOPT=y +CONFIG_FEATURE_GETOPT_LONG=y +CONFIG_HEXDUMP=y +CONFIG_FEATURE_HEXDUMP_REVERSE=y +CONFIG_HD=y +# CONFIG_HWCLOCK is not set +# CONFIG_FEATURE_HWCLOCK_LONG_OPTIONS is not set +# CONFIG_FEATURE_HWCLOCK_ADJTIME_FHS is not set +# CONFIG_IPCRM is not set +# CONFIG_IPCS is not set +CONFIG_LOSETUP=y +CONFIG_LSPCI=y +CONFIG_LSUSB=y +# CONFIG_MDEV is not set +# CONFIG_FEATURE_MDEV_CONF is not set +# CONFIG_FEATURE_MDEV_RENAME is not set +# CONFIG_FEATURE_MDEV_RENAME_REGEXP is not set +# CONFIG_FEATURE_MDEV_EXEC is not set +# CONFIG_FEATURE_MDEV_LOAD_FIRMWARE is not set +CONFIG_MKSWAP=y +CONFIG_FEATURE_MKSWAP_UUID=y +CONFIG_MORE=y +# CONFIG_MOUNT is not set +# CONFIG_FEATURE_MOUNT_FAKE is not set +# CONFIG_FEATURE_MOUNT_VERBOSE is not set +# CONFIG_FEATURE_MOUNT_HELPERS is not set +# CONFIG_FEATURE_MOUNT_LABEL is not set +# CONFIG_FEATURE_MOUNT_NFS is not set +# CONFIG_FEATURE_MOUNT_CIFS is not set +# CONFIG_FEATURE_MOUNT_FLAGS is not set +# CONFIG_FEATURE_MOUNT_FSTAB is not set +# CONFIG_PIVOT_ROOT is not set +# CONFIG_RDATE is not set +CONFIG_RDEV=y +CONFIG_READPROFILE=y +CONFIG_RTCWAKE=y +CONFIG_SCRIPT=y +CONFIG_SCRIPTREPLAY=y +# CONFIG_SETARCH is not set +# CONFIG_SWAPONOFF is not set +# CONFIG_FEATURE_SWAPON_PRI is not set +# CONFIG_SWITCH_ROOT is not set +# CONFIG_UMOUNT is not set +# CONFIG_FEATURE_UMOUNT_ALL is not set +# CONFIG_FEATURE_MOUNT_LOOP is not set +# CONFIG_FEATURE_MOUNT_LOOP_CREATE is not set +# CONFIG_FEATURE_MTAB_SUPPORT is not set +CONFIG_VOLUMEID=y + +# +# Filesystem/Volume identification +# +CONFIG_FEATURE_VOLUMEID_EXT=y +CONFIG_FEATURE_VOLUMEID_BTRFS=y +CONFIG_FEATURE_VOLUMEID_REISERFS=y +CONFIG_FEATURE_VOLUMEID_FAT=y +CONFIG_FEATURE_VOLUMEID_HFS=y +CONFIG_FEATURE_VOLUMEID_JFS=y +CONFIG_FEATURE_VOLUMEID_XFS=y +CONFIG_FEATURE_VOLUMEID_NTFS=y +CONFIG_FEATURE_VOLUMEID_ISO9660=y +CONFIG_FEATURE_VOLUMEID_UDF=y +CONFIG_FEATURE_VOLUMEID_LUKS=y +CONFIG_FEATURE_VOLUMEID_LINUXSWAP=y +CONFIG_FEATURE_VOLUMEID_CRAMFS=y +CONFIG_FEATURE_VOLUMEID_ROMFS=y +CONFIG_FEATURE_VOLUMEID_SYSV=y +CONFIG_FEATURE_VOLUMEID_OCFS2=y +CONFIG_FEATURE_VOLUMEID_LINUXRAID=y + +# +# Miscellaneous Utilities +# +# CONFIG_CONSPY is not set +# CONFIG_NANDWRITE is not set +CONFIG_NANDDUMP=y +CONFIG_SETSERIAL=y +# CONFIG_UBIATTACH is not set +# CONFIG_UBIDETACH is not set +# CONFIG_UBIMKVOL is not set +# CONFIG_UBIRMVOL is not set +# CONFIG_UBIRSVOL is not set +# CONFIG_UBIUPDATEVOL is not set +# CONFIG_ADJTIMEX is not set +# CONFIG_BBCONFIG is not set +# CONFIG_FEATURE_COMPRESS_BBCONFIG is not set +CONFIG_BEEP=y +CONFIG_FEATURE_BEEP_FREQ=4000 +CONFIG_FEATURE_BEEP_LENGTH_MS=30 +CONFIG_CHAT=y +CONFIG_FEATURE_CHAT_NOFAIL=y +# CONFIG_FEATURE_CHAT_TTY_HIFI is not set +CONFIG_FEATURE_CHAT_IMPLICIT_CR=y +CONFIG_FEATURE_CHAT_SWALLOW_OPTS=y +CONFIG_FEATURE_CHAT_SEND_ESCAPES=y +CONFIG_FEATURE_CHAT_VAR_ABORT_LEN=y +CONFIG_FEATURE_CHAT_CLR_ABORT=y +CONFIG_CHRT=y +# CONFIG_CROND is not set +# CONFIG_FEATURE_CROND_D is not set +# CONFIG_FEATURE_CROND_CALL_SENDMAIL is not set +CONFIG_FEATURE_CROND_DIR="" +# CONFIG_CRONTAB is not set +CONFIG_DC=y +CONFIG_FEATURE_DC_LIBM=y +# CONFIG_DEVFSD is not set +# CONFIG_DEVFSD_MODLOAD is not set +# CONFIG_DEVFSD_FG_NP is not set +# CONFIG_DEVFSD_VERBOSE is not set +# CONFIG_FEATURE_DEVFS is not set +CONFIG_DEVMEM=y +# CONFIG_EJECT is not set +# CONFIG_FEATURE_EJECT_SCSI is not set +CONFIG_FBSPLASH=y +CONFIG_FLASHCP=y +CONFIG_FLASH_LOCK=y +CONFIG_FLASH_UNLOCK=y +# CONFIG_FLASH_ERASEALL is not set +# CONFIG_IONICE is not set +CONFIG_INOTIFYD=y +# CONFIG_LAST is not set +# CONFIG_FEATURE_LAST_SMALL is not set +# CONFIG_FEATURE_LAST_FANCY is not set +# CONFIG_LESS is not set +CONFIG_FEATURE_LESS_MAXLINES=0 +# CONFIG_FEATURE_LESS_BRACKETS is not set +# CONFIG_FEATURE_LESS_FLAGS is not set +# CONFIG_FEATURE_LESS_MARKS is not set +# CONFIG_FEATURE_LESS_REGEXP is not set +# CONFIG_FEATURE_LESS_WINCH is not set +# CONFIG_FEATURE_LESS_DASHCMD is not set +# CONFIG_FEATURE_LESS_LINENUMS is not set +CONFIG_HDPARM=y +CONFIG_FEATURE_HDPARM_GET_IDENTITY=y +CONFIG_FEATURE_HDPARM_HDIO_SCAN_HWIF=y +CONFIG_FEATURE_HDPARM_HDIO_UNREGISTER_HWIF=y +CONFIG_FEATURE_HDPARM_HDIO_DRIVE_RESET=y +CONFIG_FEATURE_HDPARM_HDIO_TRISTATE_HWIF=y +CONFIG_FEATURE_HDPARM_HDIO_GETSET_DMA=y +CONFIG_MAKEDEVS=y +# CONFIG_FEATURE_MAKEDEVS_LEAF is not set +CONFIG_FEATURE_MAKEDEVS_TABLE=y +CONFIG_MAN=y +# CONFIG_MICROCOM is not set +# CONFIG_MOUNTPOINT is not set +# CONFIG_MT is not set +CONFIG_RAIDAUTORUN=y +# CONFIG_READAHEAD is not set +# CONFIG_RFKILL is not set +# CONFIG_RUNLEVEL is not set +CONFIG_RX=y +CONFIG_SETSID=y +CONFIG_STRINGS=y +# CONFIG_TASKSET is not set +# CONFIG_FEATURE_TASKSET_FANCY is not set +CONFIG_TIME=y +CONFIG_TIMEOUT=y +CONFIG_TTYSIZE=y +CONFIG_VOLNAME=y +# CONFIG_WALL is not set +# CONFIG_WATCHDOG is not set + +# +# Networking Utilities +# +# CONFIG_NAMEIF is not set +# CONFIG_FEATURE_NAMEIF_EXTENDED is not set +CONFIG_NBDCLIENT=y +CONFIG_NC=y +CONFIG_NC_SERVER=y +CONFIG_NC_EXTRA=y +# CONFIG_NC_110_COMPAT is not set +# CONFIG_PING is not set +# CONFIG_PING6 is not set +# CONFIG_FEATURE_FANCY_PING is not set +CONFIG_WHOIS=y +# CONFIG_FEATURE_IPV6 is not set +# CONFIG_FEATURE_UNIX_LOCAL is not set +# CONFIG_FEATURE_PREFER_IPV4_ADDRESS is not set +# CONFIG_VERBOSE_RESOLUTION_ERRORS is not set +CONFIG_ARP=y +# CONFIG_ARPING is not set +# CONFIG_BRCTL is not set +# CONFIG_FEATURE_BRCTL_FANCY is not set +# CONFIG_FEATURE_BRCTL_SHOW is not set +CONFIG_DNSD=y +# CONFIG_ETHER_WAKE is not set +CONFIG_FAKEIDENTD=y +CONFIG_FTPD=y +CONFIG_FEATURE_FTP_WRITE=y +CONFIG_FEATURE_FTPD_ACCEPT_BROKEN_LIST=y +CONFIG_FTPGET=y +CONFIG_FTPPUT=y +# CONFIG_FEATURE_FTPGETPUT_LONG_OPTIONS is not set +# CONFIG_HOSTNAME is not set +CONFIG_HTTPD=y +CONFIG_FEATURE_HTTPD_RANGES=y +CONFIG_FEATURE_HTTPD_USE_SENDFILE=y +CONFIG_FEATURE_HTTPD_SETUID=y +CONFIG_FEATURE_HTTPD_BASIC_AUTH=y +# CONFIG_FEATURE_HTTPD_AUTH_MD5 is not set +CONFIG_FEATURE_HTTPD_CGI=y +CONFIG_FEATURE_HTTPD_CONFIG_WITH_SCRIPT_INTERPR=y +CONFIG_FEATURE_HTTPD_SET_REMOTE_PORT_TO_ENV=y +CONFIG_FEATURE_HTTPD_ENCODE_URL_STR=y +CONFIG_FEATURE_HTTPD_ERROR_PAGES=y +CONFIG_FEATURE_HTTPD_PROXY=y +CONFIG_FEATURE_HTTPD_GZIP=y +CONFIG_IFCONFIG=y +CONFIG_FEATURE_IFCONFIG_STATUS=y +# CONFIG_FEATURE_IFCONFIG_SLIP is not set +CONFIG_FEATURE_IFCONFIG_MEMSTART_IOADDR_IRQ=y +CONFIG_FEATURE_IFCONFIG_HW=y +CONFIG_FEATURE_IFCONFIG_BROADCAST_PLUS=y +# CONFIG_IFENSLAVE is not set +# CONFIG_IFPLUGD is not set +CONFIG_IFUPDOWN=y +CONFIG_IFUPDOWN_IFSTATE_PATH="/var/run/ifstate" +CONFIG_FEATURE_IFUPDOWN_IP=y +CONFIG_FEATURE_IFUPDOWN_IP_BUILTIN=y +# CONFIG_FEATURE_IFUPDOWN_IFCONFIG_BUILTIN is not set +CONFIG_FEATURE_IFUPDOWN_IPV4=y +# CONFIG_FEATURE_IFUPDOWN_IPV6 is not set +CONFIG_FEATURE_IFUPDOWN_MAPPING=y +# CONFIG_FEATURE_IFUPDOWN_EXTERNAL_DHCP is not set +# CONFIG_INETD is not set +# CONFIG_FEATURE_INETD_SUPPORT_BUILTIN_ECHO is not set +# CONFIG_FEATURE_INETD_SUPPORT_BUILTIN_DISCARD is not set +# CONFIG_FEATURE_INETD_SUPPORT_BUILTIN_TIME is not set +# CONFIG_FEATURE_INETD_SUPPORT_BUILTIN_DAYTIME is not set +# CONFIG_FEATURE_INETD_SUPPORT_BUILTIN_CHARGEN is not set +# CONFIG_FEATURE_INETD_RPC is not set +CONFIG_IP=y +CONFIG_FEATURE_IP_ADDRESS=y +CONFIG_FEATURE_IP_LINK=y +CONFIG_FEATURE_IP_ROUTE=y +CONFIG_FEATURE_IP_TUNNEL=y +CONFIG_FEATURE_IP_RULE=y +CONFIG_FEATURE_IP_SHORT_FORMS=y +# CONFIG_FEATURE_IP_RARE_PROTOCOLS is not set +CONFIG_IPADDR=y +CONFIG_IPLINK=y +CONFIG_IPROUTE=y +CONFIG_IPTUNNEL=y +CONFIG_IPRULE=y +CONFIG_IPCALC=y +CONFIG_FEATURE_IPCALC_FANCY=y +# CONFIG_FEATURE_IPCALC_LONG_OPTIONS is not set +CONFIG_NETSTAT=y +CONFIG_FEATURE_NETSTAT_WIDE=y +CONFIG_FEATURE_NETSTAT_PRG=y +# CONFIG_NSLOOKUP is not set +# CONFIG_NTPD is not set +# CONFIG_FEATURE_NTPD_SERVER is not set +CONFIG_PSCAN=y +CONFIG_ROUTE=y +# CONFIG_SLATTACH is not set +CONFIG_TCPSVD=y +# CONFIG_TELNET is not set +# CONFIG_FEATURE_TELNET_TTYPE is not set +# CONFIG_FEATURE_TELNET_AUTOLOGIN is not set +# CONFIG_TELNETD is not set +# CONFIG_FEATURE_TELNETD_STANDALONE is not set +# CONFIG_FEATURE_TELNETD_INETD_WAIT is not set +# CONFIG_TFTP is not set +# CONFIG_TFTPD is not set +# CONFIG_FEATURE_TFTP_GET is not set +# CONFIG_FEATURE_TFTP_PUT is not set +# CONFIG_FEATURE_TFTP_BLOCKSIZE is not set +# CONFIG_FEATURE_TFTP_PROGRESS_BAR is not set +# CONFIG_TFTP_DEBUG is not set +# CONFIG_TRACEROUTE is not set +# CONFIG_TRACEROUTE6 is not set +# CONFIG_FEATURE_TRACEROUTE_VERBOSE is not set +# CONFIG_FEATURE_TRACEROUTE_SOURCE_ROUTE is not set +# CONFIG_FEATURE_TRACEROUTE_USE_ICMP is not set +CONFIG_TUNCTL=y +CONFIG_FEATURE_TUNCTL_UG=y +# CONFIG_UDHCPD is not set +# CONFIG_DHCPRELAY is not set +# CONFIG_DUMPLEASES is not set +# CONFIG_FEATURE_UDHCPD_WRITE_LEASES_EARLY is not set +# CONFIG_FEATURE_UDHCPD_BASE_IP_ON_MAC is not set +CONFIG_DHCPD_LEASES_FILE="" +CONFIG_UDHCPC=y +CONFIG_FEATURE_UDHCPC_ARPING=y +# CONFIG_FEATURE_UDHCP_PORT is not set +CONFIG_UDHCP_DEBUG=9 +CONFIG_FEATURE_UDHCP_RFC3397=y +CONFIG_FEATURE_UDHCP_8021Q=y +CONFIG_UDHCPC_DEFAULT_SCRIPT="/usr/share/udhcpc/default.script" +CONFIG_UDHCPC_SLACK_FOR_BUGGY_SERVERS=80 +CONFIG_IFUPDOWN_UDHCPC_CMD_OPTIONS="-R -n" +# CONFIG_UDPSVD is not set +# CONFIG_VCONFIG is not set +CONFIG_WGET=y +CONFIG_FEATURE_WGET_STATUSBAR=y +CONFIG_FEATURE_WGET_AUTHENTICATION=y +# CONFIG_FEATURE_WGET_LONG_OPTIONS is not set +CONFIG_FEATURE_WGET_TIMEOUT=y +# CONFIG_ZCIP is not set + +# +# Print Utilities +# +CONFIG_LPD=y +CONFIG_LPR=y +CONFIG_LPQ=y + +# +# Mail Utilities +# +CONFIG_MAKEMIME=y +CONFIG_FEATURE_MIME_CHARSET="us-ascii" +CONFIG_POPMAILDIR=y +CONFIG_FEATURE_POPMAILDIR_DELIVERY=y +CONFIG_REFORMIME=y +CONFIG_FEATURE_REFORMIME_COMPAT=y +CONFIG_SENDMAIL=y + +# +# Process Utilities +# +CONFIG_IOSTAT=y +CONFIG_MPSTAT=y +CONFIG_NMETER=y +CONFIG_PMAP=y +CONFIG_POWERTOP=y +CONFIG_PSTREE=y +CONFIG_PWDX=y +CONFIG_SMEMCAP=y +# CONFIG_FREE is not set +CONFIG_FUSER=y +# CONFIG_KILL is not set +# CONFIG_KILLALL is not set +# CONFIG_KILLALL5 is not set +# CONFIG_PGREP is not set +CONFIG_PIDOF=y +CONFIG_FEATURE_PIDOF_SINGLE=y +CONFIG_FEATURE_PIDOF_OMIT=y +# CONFIG_PKILL is not set +# CONFIG_PS is not set +# CONFIG_FEATURE_PS_WIDE is not set +# CONFIG_FEATURE_PS_TIME is not set +# CONFIG_FEATURE_PS_ADDITIONAL_COLUMNS is not set +# CONFIG_FEATURE_PS_UNUSUAL_SYSTEMS is not set +CONFIG_RENICE=y +CONFIG_BB_SYSCTL=y +CONFIG_TOP=y +CONFIG_FEATURE_TOP_CPU_USAGE_PERCENTAGE=y +CONFIG_FEATURE_TOP_CPU_GLOBAL_PERCENTS=y +CONFIG_FEATURE_TOP_SMP_CPU=y +CONFIG_FEATURE_TOP_DECIMALS=y +CONFIG_FEATURE_TOP_SMP_PROCESS=y +CONFIG_FEATURE_TOPMEM=y +CONFIG_FEATURE_SHOW_THREADS=y +# CONFIG_UPTIME is not set +CONFIG_WATCH=y + +# +# Runit Utilities +# +CONFIG_RUNSV=y +CONFIG_RUNSVDIR=y +# CONFIG_FEATURE_RUNSVDIR_LOG is not set +CONFIG_SV=y +CONFIG_SV_DEFAULT_SERVICE_DIR="/var/service" +CONFIG_SVLOGD=y +CONFIG_CHPST=y +CONFIG_SETUIDGID=y +CONFIG_ENVUIDGID=y +CONFIG_ENVDIR=y +CONFIG_SOFTLIMIT=y +# CONFIG_CHCON is not set +# CONFIG_FEATURE_CHCON_LONG_OPTIONS is not set +# CONFIG_GETENFORCE is not set +# CONFIG_GETSEBOOL is not set +# CONFIG_LOAD_POLICY is not set +# CONFIG_MATCHPATHCON is not set +# CONFIG_RESTORECON is not set +# CONFIG_RUNCON is not set +# CONFIG_FEATURE_RUNCON_LONG_OPTIONS is not set +# CONFIG_SELINUXENABLED is not set +# CONFIG_SETENFORCE is not set +# CONFIG_SETFILES is not set +# CONFIG_FEATURE_SETFILES_CHECK_OPTION is not set +# CONFIG_SETSEBOOL is not set +# CONFIG_SESTATUS is not set + +# +# Shells +# +# CONFIG_ASH is not set +# CONFIG_ASH_BASH_COMPAT is not set +# CONFIG_ASH_IDLE_TIMEOUT is not set +# CONFIG_ASH_JOB_CONTROL is not set +# CONFIG_ASH_ALIAS is not set +# CONFIG_ASH_GETOPTS is not set +# CONFIG_ASH_BUILTIN_ECHO is not set +# CONFIG_ASH_BUILTIN_PRINTF is not set +# CONFIG_ASH_BUILTIN_TEST is not set +# CONFIG_ASH_CMDCMD is not set +# CONFIG_ASH_MAIL is not set +# CONFIG_ASH_OPTIMIZE_FOR_SIZE is not set +# CONFIG_ASH_RANDOM_SUPPORT is not set +# CONFIG_ASH_EXPAND_PRMT is not set +CONFIG_CTTYHACK=y +# CONFIG_HUSH is not set +# CONFIG_HUSH_BASH_COMPAT is not set +# CONFIG_HUSH_BRACE_EXPANSION is not set +# CONFIG_HUSH_HELP is not set +# CONFIG_HUSH_INTERACTIVE is not set +# CONFIG_HUSH_SAVEHISTORY is not set +# CONFIG_HUSH_JOB is not set +# CONFIG_HUSH_TICK is not set +# CONFIG_HUSH_IF is not set +# CONFIG_HUSH_LOOPS is not set +# CONFIG_HUSH_CASE is not set +# CONFIG_HUSH_FUNCTIONS is not set +# CONFIG_HUSH_LOCAL is not set +# CONFIG_HUSH_RANDOM_SUPPORT is not set +# CONFIG_HUSH_EXPORT_N is not set +# CONFIG_HUSH_MODE_X is not set +# CONFIG_MSH is not set +# CONFIG_FEATURE_SH_IS_ASH is not set +# CONFIG_FEATURE_SH_IS_HUSH is not set +CONFIG_FEATURE_SH_IS_NONE=y +# CONFIG_FEATURE_BASH_IS_ASH is not set +# CONFIG_FEATURE_BASH_IS_HUSH is not set +CONFIG_FEATURE_BASH_IS_NONE=y +# CONFIG_SH_MATH_SUPPORT is not set +# CONFIG_SH_MATH_SUPPORT_64 is not set +# CONFIG_FEATURE_SH_EXTRA_QUIET is not set +# CONFIG_FEATURE_SH_STANDALONE is not set +# CONFIG_FEATURE_SH_NOFORK is not set +# CONFIG_FEATURE_SH_HISTFILESIZE is not set + +# +# System Logging Utilities +# +# CONFIG_SYSLOGD is not set +# CONFIG_FEATURE_ROTATE_LOGFILE is not set +# CONFIG_FEATURE_REMOTE_LOG is not set +# CONFIG_FEATURE_SYSLOGD_DUP is not set +# CONFIG_FEATURE_SYSLOGD_CFG is not set +CONFIG_FEATURE_SYSLOGD_READ_BUFFER_SIZE=0 +# CONFIG_FEATURE_IPC_SYSLOG is not set +CONFIG_FEATURE_IPC_SYSLOG_BUFFER_SIZE=0 +# CONFIG_LOGREAD is not set +# CONFIG_FEATURE_LOGREAD_REDUCED_LOCKING is not set +CONFIG_KLOGD=y +CONFIG_FEATURE_KLOGD_KLOGCTL=y +# CONFIG_LOGGER is not set diff --git a/include/platform.h b/include/platform.h index 826a4c497..aa1bc331b 100644 --- a/include/platform.h +++ b/include/platform.h @@ -433,7 +433,7 @@ typedef unsigned smalluint; # undef HAVE_STPCPY #endif -#if defined(ANDROID) +#if defined(ANDROID) || defined(__ANDROID__) # undef HAVE_DPRINTF # undef HAVE_GETLINE # undef HAVE_STPCPY -- cgit v1.2.3-55-g6feb From f23f7856cbbc578beb8e2c57d8669c7c211ee221 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Fri, 9 Sep 2011 18:07:38 +0200 Subject: tweak comments in android build files Signed-off-by: Denys Vlasenko --- configs/android2_defconfig | 2 ++ examples/android-build | 5 +++-- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/configs/android2_defconfig b/configs/android2_defconfig index 05920b11f..338c7b13d 100644 --- a/configs/android2_defconfig +++ b/configs/android2_defconfig @@ -1,3 +1,5 @@ +# Run "make android2_defconfig", then "make". +# # Tested with the standalone toolchain from ndk r6: # android-ndk-r6/build/tools/make-standalone-toolchain.sh --platform=android-8 # diff --git a/examples/android-build b/examples/android-build index f5fe49bda..89f3b637a 100755 --- a/examples/android-build +++ b/examples/android-build @@ -2,9 +2,10 @@ # Build Busybox against Android's bionic # Originally by Dan Fandrich # -# Configure with android_defconfig +# Configure with "make android_defconfig" +# # This file has been tested on Android Froyo (the lack of ttyname_r in -# the must be patched around) and Gingerbread. +# the android libc must be patched around) and Gingerbread. # Point this to the Android root directory; it's used in the defconfig CFLAGS export A="$HOME/android" -- cgit v1.2.3-55-g6feb From 880eec8f33843d00142d2639dfe7d807dc125cf9 Mon Sep 17 00:00:00 2001 From: Sonic Zhang Date: Fri, 9 Sep 2011 18:58:08 +0200 Subject: depmod.pl: output correct dep format according to kernel version All kernel version except for 2.4 has the same dep output format. (Possibly related to era of kernels 3.0+) Signed-off-by: Sonic Zhang Signed-off-by: Denys Vlasenko --- examples/depmod.pl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/depmod.pl b/examples/depmod.pl index f324b121a..809dc08b3 100755 --- a/examples/depmod.pl +++ b/examples/depmod.pl @@ -199,7 +199,7 @@ if ($stdout == 0) { open(STDOUT, ">$basedir/modules.dep") or die "cannot open $basedir/modules.dep: $!"; } -my $kseries = $basedir =~ m,/2\.6\.[^/]*, ? '2.6' : '2.4'; +my $kseries = $basedir =~ m,/2\.4\.[^/]*, ? '2.4' : 'others'; foreach my $module ( keys %$mod ) { if($kseries eq '2.4') { -- cgit v1.2.3-55-g6feb From c2a06db69de7562024524a89a7b0f0f7e61c5999 Mon Sep 17 00:00:00 2001 From: Ian Wienand Date: Fri, 9 Sep 2011 20:19:35 +0200 Subject: gzip: new GZIP_BIG_MEM option Enabling the config option on my standard linux box and zipping a random 250mb file: small mem: 21.85user 0.44system 0:22.35elapsed big mem: 13.45user 0.46system 0:13.94elapsed Signed-off-by: Ian Wienand Signed-off-by: Denys Vlasenko --- archival/Config.src | 10 ++++++++++ archival/gzip.c | 6 +++++- 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/archival/Config.src b/archival/Config.src index 81788ecd9..9f4908178 100644 --- a/archival/Config.src +++ b/archival/Config.src @@ -187,6 +187,16 @@ config FEATURE_GZIP_LONG_OPTIONS help Enable use of long options, increases size by about 106 Bytes +config GZIP_BIG_MEM + bool "Trade memory for gzip speed" + default n + depends on GZIP + help + Enable big memory options for gzip, including larger I/O + buffers and bigger hash tables. Faster, but uses at least + twice as much memory. Select if speed is more important than + memory use. + config LZOP bool "lzop" default y diff --git a/archival/gzip.c b/archival/gzip.c index 403eb4dcb..0e0b68142 100644 --- a/archival/gzip.c +++ b/archival/gzip.c @@ -81,7 +81,11 @@ aa: 85.1% -- replaced with aa.gz /* =========================================================================== */ -#define SMALL_MEM +#if ENABLE_GZIP_BIG_MEM +# define BIG_MEM +#else +# define SMALL_MEM +#endif #ifndef INBUFSIZ # ifdef SMALL_MEM -- cgit v1.2.3-55-g6feb From 202a1b9284fd763e81340050d228103aef999675 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Sat, 10 Sep 2011 04:51:09 +0200 Subject: awk: fix define name collision with BSD headers Signed-off-by: Denys Vlasenko --- editors/awk.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/editors/awk.c b/editors/awk.c index 0918026d7..8117cab54 100644 --- a/editors/awk.c +++ b/editors/awk.c @@ -238,6 +238,9 @@ typedef struct tsplitter_s { * For builtins it has different meaning: n n s3 s2 s1 v3 v2 v1, * n - min. number of args, vN - resolve Nth arg to var, sN - resolve to string */ +#undef P +#undef PRIMASK +#undef PRIMASK2 #define P(x) (x << 24) #define PRIMASK 0x7F000000 #define PRIMASK2 0x7E000000 -- cgit v1.2.3-55-g6feb From 522041ee7b10ac544b90c6a8d1d4fbf8a5d39c6d Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Sat, 10 Sep 2011 13:25:57 +0200 Subject: regularize options which control size/speed trade Signed-off-by: Denys Vlasenko --- archival/Config.src | 27 +++++++++++++-------------- archival/bzip2.c | 4 ++-- archival/gzip.c | 8 ++++++-- archival/libarchive/bz/blocksort.c | 8 ++++---- archival/libarchive/bz/bzlib_private.h | 2 +- archival/libarchive/bz/compress.c | 8 ++++---- archival/libarchive/bz/huffman.c | 2 +- configs/TEST_nommu_defconfig | 2 +- configs/TEST_noprintf_defconfig | 2 +- configs/TEST_rh9_defconfig | 2 +- configs/android2_defconfig | 2 +- configs/android_defconfig | 2 +- configs/cygwin_defconfig | 2 +- configs/freebsd_defconfig | 2 +- libbb/Config.src | 4 ++-- libbb/hash_md5_sha.c | 32 ++++++++++++++++---------------- libbb/hash_md5prime.c | 26 +++++++++++++------------- 17 files changed, 69 insertions(+), 66 deletions(-) diff --git a/archival/Config.src b/archival/Config.src index 9f4908178..885cb5bcc 100644 --- a/archival/Config.src +++ b/archival/Config.src @@ -187,15 +187,17 @@ config FEATURE_GZIP_LONG_OPTIONS help Enable use of long options, increases size by about 106 Bytes -config GZIP_BIG_MEM - bool "Trade memory for gzip speed" - default n - depends on GZIP - help - Enable big memory options for gzip, including larger I/O - buffers and bigger hash tables. Faster, but uses at least - twice as much memory. Select if speed is more important than - memory use. +config GZIP_FAST + int "Trade memory for gzip speed (0:small,slow - 2:fast,big)" + default 0 + range 0 2 + depends on GZIP + help + Enable big memory options for gzip. + 0: small buffers, small hash-tables + 1: larger buffers, larger hash-tables + 2: larger buffers, largest hash-tables + Larger models may give slightly better compression config LZOP bool "lzop" @@ -340,15 +342,12 @@ config UNLZMA is generally considerably better than that achieved by the bzip2 compressors. - The BusyBox unlzma applet is limited to de-compression only. + The BusyBox unlzma applet is limited to decompression only. On an x86 system, this applet adds about 4K. - Unless you have a specific application which requires unlzma, you - should probably say N here. - config FEATURE_LZMA_FAST bool "Optimize unlzma for speed" - default y + default n depends on UNLZMA help This option reduces decompression time by about 25% at the cost of diff --git a/archival/bzip2.c b/archival/bzip2.c index e39d7f704..3dde970f1 100644 --- a/archival/bzip2.c +++ b/archival/bzip2.c @@ -19,7 +19,7 @@ #include "libbb.h" #include "archive.h" -#define CONFIG_BZIP2_FEATURE_SPEED 1 +#define CONFIG_BZIP2_FAST 1 /* Speed test: * Compiled with gcc 4.2.1, run on Athlon 64 1800 MHz (512K L2 cache). @@ -27,7 +27,7 @@ * (time to compress gcc-4.2.1.tar is 126.4% compared to bbox). * At SPEED 5 difference is 32.7%. * - * Test run of all CONFIG_BZIP2_FEATURE_SPEED values on a 11Mb text file: + * Test run of all CONFIG_BZIP2_FAST values on a 11Mb text file: * Size Time (3 runs) * 0: 10828 4.145 4.146 4.148 * 1: 11097 3.845 3.860 3.861 diff --git a/archival/gzip.c b/archival/gzip.c index 0e0b68142..3af930b7e 100644 --- a/archival/gzip.c +++ b/archival/gzip.c @@ -81,10 +81,14 @@ aa: 85.1% -- replaced with aa.gz /* =========================================================================== */ -#if ENABLE_GZIP_BIG_MEM +#if CONFIG_GZIP_FAST == 0 +# define SMALL_MEM +#elif CONFIG_GZIP_FAST == 1 +# define MEDIUM_MEM +#elif CONFIG_GZIP_FAST == 2 # define BIG_MEM #else -# define SMALL_MEM +# error "Invalid CONFIG_GZIP_FAST value" #endif #ifndef INBUFSIZ diff --git a/archival/libarchive/bz/blocksort.c b/archival/libarchive/bz/blocksort.c index f70c3701d..e600cb7a7 100644 --- a/archival/libarchive/bz/blocksort.c +++ b/archival/libarchive/bz/blocksort.c @@ -385,7 +385,7 @@ int mainGtU( * but speeds up compression 10% overall */ -#if CONFIG_BZIP2_FEATURE_SPEED >= 1 +#if CONFIG_BZIP2_FAST >= 1 #define TIMES_8(code) \ code; code; code; code; \ @@ -496,7 +496,7 @@ void mainSimpleSort(uint32_t* ptr, i++; /* 1.5% overall speedup, +290 bytes */ -#if CONFIG_BZIP2_FEATURE_SPEED >= 3 +#if CONFIG_BZIP2_FAST >= 3 /*-- copy 2 --*/ if (i > hi) break; v = ptr[i]; @@ -750,7 +750,7 @@ void mainSort(EState* state, j = block[0] << 8; i = nblock - 1; /* 3%, +300 bytes */ -#if CONFIG_BZIP2_FEATURE_SPEED >= 2 +#if CONFIG_BZIP2_FAST >= 2 for (; i >= 3; i -= 4) { quadrant[i] = 0; j = (j >> 8) | (((uint16_t)block[i]) << 8); @@ -787,7 +787,7 @@ void mainSort(EState* state, s = block[0] << 8; i = nblock - 1; -#if CONFIG_BZIP2_FEATURE_SPEED >= 2 +#if CONFIG_BZIP2_FAST >= 2 for (; i >= 3; i -= 4) { s = (s >> 8) | (block[i] << 8); j = ftab[s] - 1; diff --git a/archival/libarchive/bz/bzlib_private.h b/archival/libarchive/bz/bzlib_private.h index 6430ce407..43e674bec 100644 --- a/archival/libarchive/bz/bzlib_private.h +++ b/archival/libarchive/bz/bzlib_private.h @@ -183,7 +183,7 @@ typedef struct EState { /* stack-saving measures: these can be local, but they are too big */ int32_t sendMTFValues__code [BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE]; int32_t sendMTFValues__rfreq[BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE]; -#if CONFIG_BZIP2_FEATURE_SPEED >= 5 +#if CONFIG_BZIP2_FAST >= 5 /* second dimension: only 3 needed; 4 makes index calculations faster */ uint32_t sendMTFValues__len_pack[BZ_MAX_ALPHA_SIZE][4]; #endif diff --git a/archival/libarchive/bz/compress.c b/archival/libarchive/bz/compress.c index f93671742..e9f1afdaf 100644 --- a/archival/libarchive/bz/compress.c +++ b/archival/libarchive/bz/compress.c @@ -61,7 +61,7 @@ void bsFinishWrite(EState* s) /*---------------------------------------------------*/ static /* Helps only on level 5, on other levels hurts. ? */ -#if CONFIG_BZIP2_FEATURE_SPEED >= 5 +#if CONFIG_BZIP2_FAST >= 5 ALWAYS_INLINE #endif void bsW(EState* s, int32_t n, uint32_t v) @@ -331,7 +331,7 @@ void sendMTFValues(EState* s) for (v = 0; v < alphaSize; v++) s->rfreq[t][v] = 0; -#if CONFIG_BZIP2_FEATURE_SPEED >= 5 +#if CONFIG_BZIP2_FAST >= 5 /* * Set up an auxiliary length table which is used to fast-track * the common case (nGroups == 6). @@ -361,7 +361,7 @@ void sendMTFValues(EState* s) */ for (t = 0; t < nGroups; t++) cost[t] = 0; -#if CONFIG_BZIP2_FEATURE_SPEED >= 5 +#if CONFIG_BZIP2_FAST >= 5 if (nGroups == 6 && 50 == ge-gs+1) { /*--- fast track the common case ---*/ register uint32_t cost01, cost23, cost45; @@ -420,7 +420,7 @@ void sendMTFValues(EState* s) * Increment the symbol frequencies for the selected table. */ /* 1% faster compress. +800 bytes */ -#if CONFIG_BZIP2_FEATURE_SPEED >= 4 +#if CONFIG_BZIP2_FAST >= 4 if (nGroups == 6 && 50 == ge-gs+1) { /*--- fast track the common case ---*/ #define BZ_ITUR(nn) s->rfreq[bt][mtfv[gs + (nn)]]++ diff --git a/archival/libarchive/bz/huffman.c b/archival/libarchive/bz/huffman.c index 676b1af66..bbec11adb 100644 --- a/archival/libarchive/bz/huffman.c +++ b/archival/libarchive/bz/huffman.c @@ -48,7 +48,7 @@ in the file LICENSE. /* 90 bytes, 0.3% of overall compress speed */ -#if CONFIG_BZIP2_FEATURE_SPEED >= 1 +#if CONFIG_BZIP2_FAST >= 1 /* macro works better than inline (gcc 4.2.1) */ #define DOWNHEAP1(heap, weight, Heap) \ diff --git a/configs/TEST_nommu_defconfig b/configs/TEST_nommu_defconfig index 905f65296..15e12b1d2 100644 --- a/configs/TEST_nommu_defconfig +++ b/configs/TEST_nommu_defconfig @@ -79,7 +79,7 @@ CONFIG_PREFIX="./_install" # Busybox Library Tuning # CONFIG_PASSWORD_MINLEN=6 -CONFIG_MD5_SIZE_VS_SPEED=2 +CONFIG_MD5_SMALL=1 CONFIG_FEATURE_FAST_TOP=y CONFIG_FEATURE_ETC_NETWORKS=y CONFIG_FEATURE_EDITING=y diff --git a/configs/TEST_noprintf_defconfig b/configs/TEST_noprintf_defconfig index b72e12856..f4338df71 100644 --- a/configs/TEST_noprintf_defconfig +++ b/configs/TEST_noprintf_defconfig @@ -89,7 +89,7 @@ CONFIG_PREFIX="./_install" # Busybox Library Tuning # CONFIG_PASSWORD_MINLEN=6 -CONFIG_MD5_SIZE_VS_SPEED=2 +CONFIG_MD5_SMALL=1 CONFIG_FEATURE_FAST_TOP=y # CONFIG_FEATURE_ETC_NETWORKS is not set CONFIG_FEATURE_EDITING=y diff --git a/configs/TEST_rh9_defconfig b/configs/TEST_rh9_defconfig index 23094e391..193d8f615 100644 --- a/configs/TEST_rh9_defconfig +++ b/configs/TEST_rh9_defconfig @@ -88,7 +88,7 @@ CONFIG_PREFIX="./_install" # Busybox Library Tuning # CONFIG_PASSWORD_MINLEN=6 -CONFIG_MD5_SIZE_VS_SPEED=2 +CONFIG_MD5_SMALL=1 CONFIG_FEATURE_FAST_TOP=y # CONFIG_FEATURE_ETC_NETWORKS is not set CONFIG_FEATURE_EDITING=y diff --git a/configs/android2_defconfig b/configs/android2_defconfig index 338c7b13d..b5166e0fc 100644 --- a/configs/android2_defconfig +++ b/configs/android2_defconfig @@ -92,7 +92,7 @@ CONFIG_PREFIX="./_install" # CONFIG_FEATURE_SYSTEMD is not set # CONFIG_FEATURE_RTMINMAX is not set CONFIG_PASSWORD_MINLEN=6 -CONFIG_MD5_SIZE_VS_SPEED=2 +CONFIG_MD5_SMALL=1 # CONFIG_FEATURE_FAST_TOP is not set # CONFIG_FEATURE_ETC_NETWORKS is not set CONFIG_FEATURE_USE_TERMIOS=y diff --git a/configs/android_defconfig b/configs/android_defconfig index 7e5232a84..76068b040 100644 --- a/configs/android_defconfig +++ b/configs/android_defconfig @@ -109,7 +109,7 @@ CONFIG_PREFIX="./_install" # CONFIG_FEATURE_SYSTEMD is not set # CONFIG_FEATURE_RTMINMAX is not set CONFIG_PASSWORD_MINLEN=6 -CONFIG_MD5_SIZE_VS_SPEED=2 +CONFIG_MD5_SMALL=1 # CONFIG_FEATURE_FAST_TOP is not set # CONFIG_FEATURE_ETC_NETWORKS is not set CONFIG_FEATURE_USE_TERMIOS=y diff --git a/configs/cygwin_defconfig b/configs/cygwin_defconfig index cc2d643e1..bdd0d66d0 100644 --- a/configs/cygwin_defconfig +++ b/configs/cygwin_defconfig @@ -92,7 +92,7 @@ CONFIG_PREFIX="./_install" # CONFIG_FEATURE_SYSTEMD is not set CONFIG_FEATURE_RTMINMAX=y CONFIG_PASSWORD_MINLEN=6 -CONFIG_MD5_SIZE_VS_SPEED=2 +CONFIG_MD5_SMALL=1 CONFIG_FEATURE_FAST_TOP=y # CONFIG_FEATURE_ETC_NETWORKS is not set CONFIG_FEATURE_USE_TERMIOS=y diff --git a/configs/freebsd_defconfig b/configs/freebsd_defconfig index 5f2985be1..dcb5d953c 100644 --- a/configs/freebsd_defconfig +++ b/configs/freebsd_defconfig @@ -90,7 +90,7 @@ CONFIG_PREFIX="./_install" # Busybox Library Tuning # CONFIG_PASSWORD_MINLEN=6 -CONFIG_MD5_SIZE_VS_SPEED=2 +CONFIG_MD5_SMALL=1 CONFIG_FEATURE_FAST_TOP=y # CONFIG_FEATURE_ETC_NETWORKS is not set CONFIG_FEATURE_USE_TERMIOS=y diff --git a/libbb/Config.src b/libbb/Config.src index f6f88b9ce..f45e43b04 100644 --- a/libbb/Config.src +++ b/libbb/Config.src @@ -14,9 +14,9 @@ config PASSWORD_MINLEN help Minimum allowable password length. -config MD5_SIZE_VS_SPEED +config MD5_SMALL int "MD5: Trade bytes for speed (0:fast, 3:slow)" - default 2 + default 1 range 0 3 help Trade binary size versus speed for the md5sum algorithm. diff --git a/libbb/hash_md5_sha.c b/libbb/hash_md5_sha.c index b87d1dde8..a313c2a65 100644 --- a/libbb/hash_md5_sha.c +++ b/libbb/hash_md5_sha.c @@ -104,12 +104,12 @@ static void FAST_FUNC common64_end(md5_ctx_t *ctx, int swap_needed) */ /* 0: fastest, 3: smallest */ -#if CONFIG_MD5_SIZE_VS_SPEED < 0 -# define MD5_SIZE_VS_SPEED 0 -#elif CONFIG_MD5_SIZE_VS_SPEED > 3 -# define MD5_SIZE_VS_SPEED 3 +#if CONFIG_MD5_SMALL < 0 +# define MD5_SMALL 0 +#elif CONFIG_MD5_SMALL > 3 +# define MD5_SMALL 3 #else -# define MD5_SIZE_VS_SPEED CONFIG_MD5_SIZE_VS_SPEED +# define MD5_SMALL CONFIG_MD5_SMALL #endif /* These are the four functions used in the four steps of the MD5 algorithm @@ -129,7 +129,7 @@ static void FAST_FUNC common64_end(md5_ctx_t *ctx, int swap_needed) /* Hash a single block, 64 bytes long and 4-byte aligned */ static void FAST_FUNC md5_process_block64(md5_ctx_t *ctx) { -#if MD5_SIZE_VS_SPEED > 0 +#if MD5_SMALL > 0 /* Before we start, one word to the strange constants. They are defined in RFC 1321 as T[i] = (int)(4294967296.0 * fabs(sin(i))), i=1..64 @@ -157,7 +157,7 @@ static void FAST_FUNC md5_process_block64(md5_ctx_t *ctx) 0xf7537e82, 0xbd3af235, 0x2ad7d2bb, 0xeb86d391 }; static const char P_array[] ALIGN1 = { -# if MD5_SIZE_VS_SPEED > 1 +# if MD5_SMALL > 1 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, /* 1 */ # endif 1, 6, 11, 0, 5, 10, 15, 4, 9, 14, 3, 8, 13, 2, 7, 12, /* 2 */ @@ -171,7 +171,7 @@ static void FAST_FUNC md5_process_block64(md5_ctx_t *ctx) uint32_t C = ctx->hash[2]; uint32_t D = ctx->hash[3]; -#if MD5_SIZE_VS_SPEED >= 2 /* 2 or 3 */ +#if MD5_SMALL >= 2 /* 2 or 3 */ static const char S_array[] ALIGN1 = { 7, 12, 17, 22, @@ -190,7 +190,7 @@ static void FAST_FUNC md5_process_block64(md5_ctx_t *ctx) words[i] = SWAP_LE32(words[i]); # endif -# if MD5_SIZE_VS_SPEED == 3 +# if MD5_SMALL == 3 pc = C_array; pp = P_array; ps = S_array - 4; @@ -220,7 +220,7 @@ static void FAST_FUNC md5_process_block64(md5_ctx_t *ctx) C = B; B = temp; } -# else /* MD5_SIZE_VS_SPEED == 2 */ +# else /* MD5_SMALL == 2 */ pc = C_array; pp = P_array; ps = S_array; @@ -271,13 +271,13 @@ static void FAST_FUNC md5_process_block64(md5_ctx_t *ctx) ctx->hash[2] += C; ctx->hash[3] += D; -#else /* MD5_SIZE_VS_SPEED == 0 or 1 */ +#else /* MD5_SMALL == 0 or 1 */ uint32_t A_save = A; uint32_t B_save = B; uint32_t C_save = C; uint32_t D_save = D; -# if MD5_SIZE_VS_SPEED == 1 +# if MD5_SMALL == 1 const uint32_t *pc; const char *pp; int i; @@ -299,7 +299,7 @@ static void FAST_FUNC md5_process_block64(md5_ctx_t *ctx) } while (0) /* Round 1 */ -# if MD5_SIZE_VS_SPEED == 1 +# if MD5_SMALL == 1 pc = C_array; for (i = 0; i < 4; i++) { OP(A, B, C, D, 7, *pc++); @@ -339,7 +339,7 @@ static void FAST_FUNC md5_process_block64(md5_ctx_t *ctx) } while (0) /* Round 2 */ -# if MD5_SIZE_VS_SPEED == 1 +# if MD5_SMALL == 1 pp = P_array; for (i = 0; i < 4; i++) { OP(FG, A, B, C, D, (int) (*pp++), 5, *pc++); @@ -367,7 +367,7 @@ static void FAST_FUNC md5_process_block64(md5_ctx_t *ctx) # endif /* Round 3 */ -# if MD5_SIZE_VS_SPEED == 1 +# if MD5_SMALL == 1 for (i = 0; i < 4; i++) { OP(FH, A, B, C, D, (int) (*pp++), 4, *pc++); OP(FH, D, A, B, C, (int) (*pp++), 11, *pc++); @@ -394,7 +394,7 @@ static void FAST_FUNC md5_process_block64(md5_ctx_t *ctx) # endif /* Round 4 */ -# if MD5_SIZE_VS_SPEED == 1 +# if MD5_SMALL == 1 for (i = 0; i < 4; i++) { OP(FI, A, B, C, D, (int) (*pp++), 6, *pc++); OP(FI, D, A, B, C, (int) (*pp++), 10, *pc++); diff --git a/libbb/hash_md5prime.c b/libbb/hash_md5prime.c index 7986f4d29..e089a15f5 100644 --- a/libbb/hash_md5prime.c +++ b/libbb/hash_md5prime.c @@ -59,7 +59,7 @@ * Completely removed static PADDING array. * * Reintroduced the loop unrolling in md5_transform and added the - * MD5_SIZE_VS_SPEED option for configurability. Define below as: + * MD5_SMALL option for configurability. Define below as: * 0 fully unrolled loops * 1 partially unrolled (4 ops per loop) * 2 no unrolling -- introduces the need to swap 4 variables (slow) @@ -75,12 +75,12 @@ #include "libbb.h" /* 1: fastest, 3: smallest */ -#if CONFIG_MD5_SIZE_VS_SPEED < 1 -# define MD5_SIZE_VS_SPEED 1 -#elif CONFIG_MD5_SIZE_VS_SPEED > 3 -# define MD5_SIZE_VS_SPEED 3 +#if CONFIG_MD5_SMALL < 1 +# define MD5_SMALL 1 +#elif CONFIG_MD5_SMALL > 3 +# define MD5_SMALL 3 #else -# define MD5_SIZE_VS_SPEED CONFIG_MD5_SIZE_VS_SPEED +# define MD5_SMALL CONFIG_MD5_SMALL #endif #if BB_LITTLE_ENDIAN @@ -152,7 +152,7 @@ memcpy32_le2cpu(uint32_t *output, const unsigned char *input, unsigned len) static void md5_transform(uint32_t state[4], const unsigned char block[64]) { uint32_t a, b, c, d, x[16]; -#if MD5_SIZE_VS_SPEED > 1 +#if MD5_SMALL > 1 uint32_t temp; const unsigned char *ps; @@ -162,9 +162,9 @@ static void md5_transform(uint32_t state[4], const unsigned char block[64]) 4, 11, 16, 23, 6, 10, 15, 21 }; -#endif /* MD5_SIZE_VS_SPEED > 1 */ +#endif /* MD5_SMALL > 1 */ -#if MD5_SIZE_VS_SPEED > 0 +#if MD5_SMALL > 0 const uint32_t *pc; const unsigned char *pp; int i; @@ -198,7 +198,7 @@ static void md5_transform(uint32_t state[4], const unsigned char block[64]) 0, 7, 14, 5, 12, 3, 10, 1, 8, 15, 6, 13, 4, 11, 2, 9 /* 4 */ }; -#endif /* MD5_SIZE_VS_SPEED > 0 */ +#endif /* MD5_SMALL > 0 */ memcpy32_le2cpu(x, block, 64); @@ -207,7 +207,7 @@ static void md5_transform(uint32_t state[4], const unsigned char block[64]) c = state[2]; d = state[3]; -#if MD5_SIZE_VS_SPEED > 2 +#if MD5_SMALL > 2 pc = C; pp = P; ps = S - 4; @@ -233,7 +233,7 @@ static void md5_transform(uint32_t state[4], const unsigned char block[64]) temp += b; a = d; d = c; c = b; b = temp; } -#elif MD5_SIZE_VS_SPEED > 1 +#elif MD5_SMALL > 1 pc = C; pp = P; ps = S; @@ -260,7 +260,7 @@ static void md5_transform(uint32_t state[4], const unsigned char block[64]) II(a, b, c, d, x[*pp], ps[i & 0x3], *pc); pp++; pc++; temp = d; d = c; c = b; b = a; a = temp; } -#elif MD5_SIZE_VS_SPEED > 0 +#elif MD5_SMALL > 0 pc = C; pp = P; /* Round 1 */ -- cgit v1.2.3-55-g6feb From d48fdde3704f453014404fca321e08238dc4acc4 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Sat, 10 Sep 2011 13:48:34 +0200 Subject: stop declariong our own dirname prototype Signed-off-by: Denys Vlasenko --- include/libbb.h | 11 +++++------ modutils/modutils-24.c | 1 - 2 files changed, 5 insertions(+), 7 deletions(-) diff --git a/include/libbb.h b/include/libbb.h index f60f4278b..d0c7ace22 100644 --- a/include/libbb.h +++ b/include/libbb.h @@ -32,6 +32,11 @@ #include #include #include +/* There are two incompatible basename's, let not use them! */ +/* See the dirname/basename man page for details */ +#include /* dirname,basename */ +#undef basename +#define basename dont_use_basename #include #include #include @@ -133,12 +138,6 @@ int vdprintf(int d, const char *format, va_list ap); #endif /* klogctl is in libc's klog.h, but we cheat and not #include that */ int klogctl(int type, char *b, int len); -/* This is declared here rather than #including in order to avoid - * confusing the two versions of basename. See the dirname/basename man page - * for details. */ -#if !defined __FreeBSD__ -char *dirname(char *path); -#endif #ifndef PATH_MAX # define PATH_MAX 256 #endif diff --git a/modutils/modutils-24.c b/modutils/modutils-24.c index bbc54e316..12cb75c54 100644 --- a/modutils/modutils-24.c +++ b/modutils/modutils-24.c @@ -60,7 +60,6 @@ #include "libbb.h" #include "modutils.h" -#include #include #if ENABLE_FEATURE_INSMOD_LOADINKMEM -- cgit v1.2.3-55-g6feb From 7b46d11582047d0dd21b547ff4a913defe646d40 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Sun, 11 Sep 2011 00:30:56 +0200 Subject: awk: fix a SEGV Signed-off-by: Denys Vlasenko --- editors/awk.c | 71 ++++++++++++++++++++++++++++++++++++++++++++++------- testsuite/awk.tests | 3 +++ 2 files changed, 65 insertions(+), 9 deletions(-) diff --git a/editors/awk.c b/editors/awk.c index 8117cab54..71abca215 100644 --- a/editors/awk.c +++ b/editors/awk.c @@ -25,6 +25,7 @@ * to perform debug printfs to stderr: */ #define debug_printf_walker(...) do {} while (0) #define debug_printf_eval(...) do {} while (0) +#define debug_printf_parse(...) do {} while (0) #ifndef debug_printf_walker # define debug_printf_walker(...) (fprintf(stderr, __VA_ARGS__)) @@ -32,6 +33,9 @@ #ifndef debug_printf_eval # define debug_printf_eval(...) (fprintf(stderr, __VA_ARGS__)) #endif +#ifndef debug_printf_parse +# define debug_printf_parse(...) (fprintf(stderr, __VA_ARGS__)) +#endif @@ -435,13 +439,13 @@ struct globals { smallint nextrec; smallint nextfile; smallint is_f0_split; + smallint t_rollback; }; struct globals2 { uint32_t t_info; /* often used */ uint32_t t_tclass; char *t_string; int t_lineno; - int t_rollback; var *intvar[NUM_INTERNAL_VARS]; /* often used */ @@ -499,11 +503,11 @@ struct globals2 { #define nextrec (G1.nextrec ) #define nextfile (G1.nextfile ) #define is_f0_split (G1.is_f0_split ) +#define t_rollback (G1.t_rollback ) #define t_info (G.t_info ) #define t_tclass (G.t_tclass ) #define t_string (G.t_string ) #define t_lineno (G.t_lineno ) -#define t_rollback (G.t_rollback ) #define intvar (G.intvar ) #define fsplitter (G.fsplitter ) #define rsplitter (G.rsplitter ) @@ -1011,6 +1015,7 @@ static uint32_t next_token(uint32_t expected) if (*p == '\0') { tc = TC_EOF; + debug_printf_parse("%s: token found: TC_EOF\n", __func__); } else if (*p == '\"') { /* it's a string */ @@ -1026,6 +1031,7 @@ static uint32_t next_token(uint32_t expected) p++; *s = '\0'; tc = TC_STRING; + debug_printf_parse("%s: token found:'%s' TC_STRING\n", __func__, t_string); } else if ((expected & TC_REGEXP) && *p == '/') { /* it's regexp */ @@ -1048,6 +1054,7 @@ static uint32_t next_token(uint32_t expected) p++; *s = '\0'; tc = TC_REGEXP; + debug_printf_parse("%s: token found:'%s' TC_REGEXP\n", __func__, t_string); } else if (*p == '.' || isdigit(*p)) { /* it's a number */ @@ -1057,6 +1064,7 @@ static uint32_t next_token(uint32_t expected) if (*p == '.') syntax_error(EMSG_UNEXP_TOKEN); tc = TC_NUMBER; + debug_printf_parse("%s: token found:%f TC_NUMBER\n", __func__, t_double); } else { /* search for something known */ @@ -1079,6 +1087,7 @@ static uint32_t next_token(uint32_t expected) ) { /* then this is what we are looking for */ t_info = *ti; + debug_printf_parse("%s: token found:'%.*s' t_info:%x\n", __func__, l, p, t_info); p += l; goto token_found; } @@ -1102,14 +1111,17 @@ static uint32_t next_token(uint32_t expected) p = skip_spaces(p); if (*p == '(') { tc = TC_FUNCTION; + debug_printf_parse("%s: token found:'%s' TC_FUNCTION\n", __func__, t_string); } else { if (*p == '[') { p++; tc = TC_ARRAY; - } + debug_printf_parse("%s: token found:'%s' TC_ARRAY\n", __func__, t_string); + } else + debug_printf_parse("%s: token found:'%s' TC_VARIABLE\n", __func__, t_string); } - token_found: ; } + token_found: g_pos = p; /* skipping newlines in some cases */ @@ -1181,6 +1193,8 @@ static node *parse_expr(uint32_t iexp) uint32_t tc, xtc; var *v; + debug_printf_parse("%s(%x)\n", __func__, iexp); + sn.info = PRIMASK; sn.r.n = glptr = NULL; xtc = TC_OPERAND | TC_UOPPRE | TC_REGEXP | iexp; @@ -1189,12 +1203,14 @@ static node *parse_expr(uint32_t iexp) if (glptr && (t_info == (OC_COMPARE | VV | P(39) | 2))) { /* input redirection (<) attached to glptr node */ + debug_printf_parse("%s: input redir\n", __func__); cn = glptr->l.n = new_node(OC_CONCAT | SS | P(37)); cn->a.n = glptr; xtc = TC_OPERAND | TC_UOPPRE; glptr = NULL; } else if (tc & (TC_BINOP | TC_UOPPOST)) { + debug_printf_parse("%s: TC_BINOP | TC_UOPPOST\n", __func__); /* for binary and postfix-unary operators, jump back over * previous operators with higher priority */ vn = cn; @@ -1224,6 +1240,7 @@ static node *parse_expr(uint32_t iexp) vn->a.n = cn; } else { + debug_printf_parse("%s: other\n", __func__); /* for operands and prefix-unary operators, attach them * to last node */ vn = cn; @@ -1231,12 +1248,14 @@ static node *parse_expr(uint32_t iexp) cn->a.n = vn; xtc = TC_OPERAND | TC_UOPPRE | TC_REGEXP; if (tc & (TC_OPERAND | TC_REGEXP)) { + debug_printf_parse("%s: TC_OPERAND | TC_REGEXP\n", __func__); xtc = TC_UOPPRE | TC_UOPPOST | TC_BINOP | TC_OPERAND | iexp; /* one should be very careful with switch on tclass - * only simple tclasses should be used! */ switch (tc) { case TC_VARIABLE: case TC_ARRAY: + debug_printf_parse("%s: TC_VARIABLE | TC_ARRAY\n", __func__); cn->info = OC_VAR; v = hash_search(ahash, t_string); if (v != NULL) { @@ -1253,6 +1272,7 @@ static node *parse_expr(uint32_t iexp) case TC_NUMBER: case TC_STRING: + debug_printf_parse("%s: TC_NUMBER | TC_STRING\n", __func__); cn->info = OC_VAR; v = cn->l.v = xzalloc(sizeof(var)); if (tc & TC_NUMBER) @@ -1262,32 +1282,41 @@ static node *parse_expr(uint32_t iexp) break; case TC_REGEXP: + debug_printf_parse("%s: TC_REGEXP\n", __func__); mk_re_node(t_string, cn, xzalloc(sizeof(regex_t)*2)); break; case TC_FUNCTION: + debug_printf_parse("%s: TC_FUNCTION\n", __func__); cn->info = OC_FUNC; cn->r.f = newfunc(t_string); cn->l.n = condition(); break; case TC_SEQSTART: + debug_printf_parse("%s: TC_SEQSTART\n", __func__); cn = vn->r.n = parse_expr(TC_SEQTERM); + if (!cn) + syntax_error("Empty sequence"); cn->a.n = vn; break; case TC_GETLINE: + debug_printf_parse("%s: TC_GETLINE\n", __func__); glptr = cn; xtc = TC_OPERAND | TC_UOPPRE | TC_BINOP | iexp; break; case TC_BUILTIN: + debug_printf_parse("%s: TC_BUILTIN\n", __func__); cn->l.n = condition(); break; } } } } + + debug_printf_parse("%s() returns %p\n", __func__, sn.r.n); return sn.r.n; } @@ -1356,18 +1385,25 @@ static void chain_group(void) } while (c & TC_NEWLINE); if (c & TC_GRPSTART) { + debug_printf_parse("%s: TC_GRPSTART\n", __func__); while (next_token(TC_GRPSEQ | TC_GRPTERM) != TC_GRPTERM) { + debug_printf_parse("%s: !TC_GRPTERM\n", __func__); if (t_tclass & TC_NEWLINE) continue; rollback_token(); chain_group(); } + debug_printf_parse("%s: TC_GRPTERM\n", __func__); } else if (c & (TC_OPSEQ | TC_OPTERM)) { + debug_printf_parse("%s: TC_OPSEQ | TC_OPTERM\n", __func__); rollback_token(); chain_expr(OC_EXEC | Vx); - } else { /* TC_STATEMNT */ + } else { + /* TC_STATEMNT */ + debug_printf_parse("%s: TC_STATEMNT(?)\n", __func__); switch (t_info & OPCLSMASK) { case ST_IF: + debug_printf_parse("%s: ST_IF\n", __func__); n = chain_node(OC_BR | Vx); n->l.n = condition(); chain_group(); @@ -1382,12 +1418,14 @@ static void chain_group(void) break; case ST_WHILE: + debug_printf_parse("%s: ST_WHILE\n", __func__); n2 = condition(); n = chain_loop(NULL); n->l.n = n2; break; case ST_DO: + debug_printf_parse("%s: ST_DO\n", __func__); n2 = chain_node(OC_EXEC); n = chain_loop(NULL); n2->a.n = n->a.n; @@ -1396,6 +1434,7 @@ static void chain_group(void) break; case ST_FOR: + debug_printf_parse("%s: ST_FOR\n", __func__); next_token(TC_SEQSTART); n2 = parse_expr(TC_SEMICOL | TC_SEQTERM); if (t_tclass & TC_SEQTERM) { /* for-in */ @@ -1421,6 +1460,7 @@ static void chain_group(void) case OC_PRINT: case OC_PRINTF: + debug_printf_parse("%s: OC_PRINT[F]\n", __func__); n = chain_node(t_info); n->l.n = parse_expr(TC_OPTERM | TC_OUTRDR | TC_GRPTERM); if (t_tclass & TC_OUTRDR) { @@ -1432,17 +1472,20 @@ static void chain_group(void) break; case OC_BREAK: + debug_printf_parse("%s: OC_BREAK\n", __func__); n = chain_node(OC_EXEC); n->a.n = break_ptr; break; case OC_CONTINUE: + debug_printf_parse("%s: OC_CONTINUE\n", __func__); n = chain_node(OC_EXEC); n->a.n = continue_ptr; break; /* delete, next, nextfile, return, exit */ default: + debug_printf_parse("%s: default\n", __func__); chain_expr(t_info); } } @@ -1460,19 +1503,24 @@ static void parse_program(char *p) while ((tclass = next_token(TC_EOF | TC_OPSEQ | TC_GRPSTART | TC_OPTERM | TC_BEGIN | TC_END | TC_FUNCDECL)) != TC_EOF) { - if (tclass & TC_OPTERM) + if (tclass & TC_OPTERM) { + debug_printf_parse("%s: TC_OPTERM\n", __func__); continue; + } seq = &mainseq; if (tclass & TC_BEGIN) { + debug_printf_parse("%s: TC_BEGIN\n", __func__); seq = &beginseq; chain_group(); } else if (tclass & TC_END) { + debug_printf_parse("%s: TC_END\n", __func__); seq = &endseq; chain_group(); } else if (tclass & TC_FUNCDECL) { + debug_printf_parse("%s: TC_FUNCDECL\n", __func__); next_token(TC_FUNCTION); g_pos++; f = newfunc(t_string); @@ -1490,22 +1538,27 @@ static void parse_program(char *p) clear_array(ahash); } else if (tclass & TC_OPSEQ) { + debug_printf_parse("%s: TC_OPSEQ\n", __func__); rollback_token(); cn = chain_node(OC_TEST); cn->l.n = parse_expr(TC_OPTERM | TC_EOF | TC_GRPSTART); if (t_tclass & TC_GRPSTART) { + debug_printf_parse("%s: TC_GRPSTART\n", __func__); rollback_token(); chain_group(); } else { + debug_printf_parse("%s: !TC_GRPSTART\n", __func__); chain_node(OC_PRINT); } cn->r.n = mainseq.last; } else /* if (tclass & TC_GRPSTART) */ { + debug_printf_parse("%s: TC_GRPSTART(?)\n", __func__); rollback_token(); chain_group(); } } + debug_printf_parse("%s: TC_EOF\n", __func__); } @@ -3000,7 +3053,7 @@ int awk_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; int awk_main(int argc, char **argv) { unsigned opt; - char *opt_F, *opt_W; + char *opt_F; llist_t *list_v = NULL; llist_t *list_f = NULL; int i, j; @@ -3062,7 +3115,7 @@ int awk_main(int argc, char **argv) } } opt_complementary = "v::f::"; /* -v and -f can occur multiple times */ - opt = getopt32(argv, "F:v:f:W:", &opt_F, &list_v, &list_f, &opt_W); + opt = getopt32(argv, "F:v:f:W:", &opt_F, &list_v, &list_f, NULL); argv += optind; argc -= optind; if (opt & 0x1) @@ -3096,7 +3149,7 @@ int awk_main(int argc, char **argv) parse_program(*argv++); } if (opt & 0x8) // -W - bb_error_msg("warning: unrecognized option '-W %s' ignored", opt_W); + bb_error_msg("warning: option -W is ignored"); /* fill in ARGV array */ setvar_i(intvar[ARGC], argc); diff --git a/testsuite/awk.tests b/testsuite/awk.tests index 0afe9b9e7..5a323047d 100755 --- a/testsuite/awk.tests +++ b/testsuite/awk.tests @@ -202,4 +202,7 @@ end d " \ "" "" +testing "awk handles empty ()" \ + "awk 'BEGIN {print()}' 2>&1" "awk: cmd. line:1: Empty sequence\n" "" "" + exit $FAILCOUNT -- cgit v1.2.3-55-g6feb From d2fe2ba08dd84cd7e94d1ae3e2e9c12ca2b4d561 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Sun, 11 Sep 2011 12:25:59 +0200 Subject: chpasswd: fix possible free() or non-allocated string. +8 bytes Signed-off-by: Denys Vlasenko --- loginutils/chpasswd.c | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/loginutils/chpasswd.c b/loginutils/chpasswd.c index 2262b792a..b7df57e5d 100644 --- a/loginutils/chpasswd.c +++ b/loginutils/chpasswd.c @@ -33,9 +33,8 @@ static const char chpasswd_longopts[] ALIGN1 = int chpasswd_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; int chpasswd_main(int argc UNUSED_PARAM, char **argv) { - char *name, *pass; - char salt[sizeof("$N$XXXXXXXX")]; - int opt, rc; + char *name; + int opt; if (getuid() != 0) bb_error_msg_and_die(bb_msg_perm_denied_are_you_root); @@ -45,6 +44,10 @@ int chpasswd_main(int argc UNUSED_PARAM, char **argv) opt = getopt32(argv, "em"); while ((name = xmalloc_fgetline(stdin)) != NULL) { + char *free_me; + char *pass; + int rc; + pass = strchr(name, ':'); if (!pass) bb_error_msg_and_die("missing new password"); @@ -52,7 +55,10 @@ int chpasswd_main(int argc UNUSED_PARAM, char **argv) xuname2uid(name); /* dies if there is no such user */ + free_me = NULL; if (!(opt & OPT_ENC)) { + char salt[sizeof("$N$XXXXXXXX")]; + crypt_make_salt(salt, 1); if (opt & OPT_MD5) { salt[0] = '$'; @@ -60,7 +66,7 @@ int chpasswd_main(int argc UNUSED_PARAM, char **argv) salt[2] = '$'; crypt_make_salt(salt + 3, 4); } - pass = pw_encrypt(pass, salt, 0); + free_me = pass = pw_encrypt(pass, salt, 0); } /* This is rather complex: if user is not found in /etc/shadow, @@ -81,8 +87,7 @@ int chpasswd_main(int argc UNUSED_PARAM, char **argv) bb_info_msg("Password for '%s' changed", name); logmode = LOGMODE_STDIO; free(name); - if (!(opt & OPT_ENC)) - free(pass); + free(free_me); } return EXIT_SUCCESS; } -- cgit v1.2.3-55-g6feb From 223b9417b3789e60f3a91510661b00a92c0db027 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Sun, 11 Sep 2011 16:48:21 +0200 Subject: inetd: close new udp fd in "udp nowait" case Signed-off-by: Denys Vlasenko --- networking/inetd.c | 66 +++++++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 55 insertions(+), 11 deletions(-) diff --git a/networking/inetd.c b/networking/inetd.c index 873fd9528..fc6847bb5 100644 --- a/networking/inetd.c +++ b/networking/inetd.c @@ -357,10 +357,26 @@ struct BUG_G_too_big { config_filename = "/etc/inetd.conf"; \ } while (0) +#if 1 +# define dbg(...) ((void)0) +#else +# define dbg(...) \ +do { \ + int dbg_fd = open("inetd_debug.log", O_WRONLY | O_CREAT | O_APPEND, 0666); \ + if (dbg_fd >= 0) { \ + fdprintf(dbg_fd, "%d: ", getpid()); \ + fdprintf(dbg_fd, __VA_ARGS__); \ + close(dbg_fd); \ + } \ +} while (0) +#endif + static void maybe_close(int fd) { - if (fd >= 0) + if (fd >= 0) { close(fd); + dbg("closed fd:%d\n", fd); + } } // TODO: move to libbb? @@ -464,7 +480,9 @@ static void remove_fd_from_set(int fd) { if (fd >= 0) { FD_CLR(fd, &allsock); + dbg("stopped listening on fd:%d\n", fd); maxsock = -1; + dbg("maxsock:%d\n", maxsock); } } @@ -472,8 +490,10 @@ static void add_fd_to_set(int fd) { if (fd >= 0) { FD_SET(fd, &allsock); + dbg("started listening on fd:%d\n", fd); if (maxsock >= 0 && fd > maxsock) { prev_maxsock = maxsock = fd; + dbg("maxsock:%d\n", maxsock); if ((rlim_t)fd > rlim_ofile_cur - FD_MARGIN) bump_nofile(); } @@ -492,6 +512,7 @@ static void recalculate_maxsock(void) maxsock = fd; fd++; } + dbg("recalculated maxsock:%d\n", maxsock); prev_maxsock = maxsock; if ((rlim_t)maxsock > rlim_ofile_cur - FD_MARGIN) bump_nofile(); @@ -549,8 +570,13 @@ static void prepare_socket_fd(servtab_t *sep) rearm_alarm(); return; } - if (sep->se_socktype == SOCK_STREAM) + + if (sep->se_socktype == SOCK_STREAM) { listen(fd, global_queuelen); + dbg("new sep->se_fd:%d (stream)\n", fd); + } else { + dbg("new sep->se_fd:%d (!stream)\n", fd); + } add_fd_to_set(fd); sep->se_fd = fd; @@ -1012,7 +1038,7 @@ static void reread_config_file(int sig UNUSED_PARAM) * new config file doesnt have them. */ block_CHLD_HUP_ALRM(&omask); sepp = &serv_list; - while ((sep = *sepp)) { + while ((sep = *sepp) != NULL) { if (sep->se_checked) { sepp = &sep->se_next; continue; @@ -1206,11 +1232,13 @@ int inetd_main(int argc UNUSED_PARAM, char **argv) } continue; } + dbg("ready_fd_cnt:%d\n", ready_fd_cnt); for (sep = serv_list; ready_fd_cnt && sep; sep = sep->se_next) { if (sep->se_fd == -1 || !FD_ISSET(sep->se_fd, &readable)) continue; + dbg("ready fd:%d\n", sep->se_fd); ready_fd_cnt--; ctrl = sep->se_fd; accepted_fd = -1; @@ -1218,6 +1246,7 @@ int inetd_main(int argc UNUSED_PARAM, char **argv) if (!sep->se_wait) { if (sep->se_socktype == SOCK_STREAM) { ctrl = accepted_fd = accept(sep->se_fd, NULL, NULL); + dbg("accepted_fd:%d\n", accepted_fd); if (ctrl < 0) { if (errno != EINTR) bb_perror_msg("accept (for %s)", sep->se_service); @@ -1238,19 +1267,22 @@ int inetd_main(int argc UNUSED_PARAM, char **argv) * (can create many copies of same child, etc). * Parent must create and use new socket instead. */ new_udp_fd = socket(sep->se_family, SOCK_DGRAM, 0); + dbg("new_udp_fd:%d\n", new_udp_fd); if (new_udp_fd < 0) { /* error: eat packet, forget about it */ udp_err: recv(sep->se_fd, line, LINE_SIZE, MSG_DONTWAIT); continue; } setsockopt_reuseaddr(new_udp_fd); - /* TODO: better do bind after vfork in parent, + /* TODO: better do bind after fork in parent, * so that we don't have two wildcard bound sockets * even for a brief moment? */ if (bind(new_udp_fd, &sep->se_lsa->u.sa, sep->se_lsa->len) < 0) { + dbg("bind(new_udp_fd) failed\n"); close(new_udp_fd); goto udp_err; } + dbg("bind(new_udp_fd) succeeded\n"); } } @@ -1278,6 +1310,7 @@ int inetd_main(int argc UNUSED_PARAM, char **argv) sep->se_count = 0; rearm_alarm(); /* will revive it in RETRYTIME sec */ restore_sigmask(&omask); + maybe_close(new_udp_fd); maybe_close(accepted_fd); continue; /* -> check next fd in fd set */ } @@ -1298,17 +1331,18 @@ int inetd_main(int argc UNUSED_PARAM, char **argv) bb_perror_msg("vfork"+1); sleep(1); restore_sigmask(&omask); + maybe_close(new_udp_fd); maybe_close(accepted_fd); continue; /* -> check next fd in fd set */ } if (pid == 0) pid--; /* -1: "we did fork and we are child" */ } - /* if pid == 0 here, we never forked */ + /* if pid == 0 here, we didn't fork */ if (pid > 0) { /* parent */ if (sep->se_wait) { - /* tcp wait: we passed listening socket to child, + /* wait: we passed socket to child, * will wait for child to terminate */ sep->se_wait = pid; remove_fd_from_set(sep->se_fd); @@ -1317,17 +1351,19 @@ int inetd_main(int argc UNUSED_PARAM, char **argv) /* udp nowait: child connected the socket, * we created and will use new, unconnected one */ xmove_fd(new_udp_fd, sep->se_fd); + dbg("moved new_udp_fd:%d to sep->se_fd:%d\n", new_udp_fd, sep->se_fd); } restore_sigmask(&omask); maybe_close(accepted_fd); continue; /* -> check next fd in fd set */ } - /* we are either child or didn't vfork at all */ + /* we are either child or didn't fork at all */ #ifdef INETD_BUILTINS_ENABLED if (sep->se_builtin) { - if (pid) { /* "pid" is -1: we did vfork */ + if (pid) { /* "pid" is -1: we did fork */ close(sep->se_fd); /* listening socket */ + dbg("closed sep->se_fd:%d\n", sep->se_fd); logmode = LOGMODE_NONE; /* make xwrite etc silent */ } restore_sigmask(&omask); @@ -1335,7 +1371,7 @@ int inetd_main(int argc UNUSED_PARAM, char **argv) sep->se_builtin->bi_stream_fn(ctrl, sep); else sep->se_builtin->bi_dgram_fn(ctrl, sep); - if (pid) /* we did vfork */ + if (pid) /* we did fork */ _exit(EXIT_FAILURE); maybe_close(accepted_fd); continue; /* -> check next fd in fd set */ @@ -1345,9 +1381,14 @@ int inetd_main(int argc UNUSED_PARAM, char **argv) setsid(); /* "nowait" udp */ if (new_udp_fd >= 0) { - len_and_sockaddr *lsa = xzalloc_lsa(sep->se_family); + len_and_sockaddr *lsa; + int r; + + close(new_udp_fd); + dbg("closed new_udp_fd:%d\n", new_udp_fd); + lsa = xzalloc_lsa(sep->se_family); /* peek at the packet and remember peer addr */ - int r = recvfrom(ctrl, NULL, 0, MSG_PEEK|MSG_DONTWAIT, + r = recvfrom(ctrl, NULL, 0, MSG_PEEK|MSG_DONTWAIT, &lsa->u.sa, &lsa->len); if (r < 0) goto do_exit1; @@ -1355,6 +1396,7 @@ int inetd_main(int argc UNUSED_PARAM, char **argv) * only packets from this peer will be recv'ed, * and bare write()/send() will work on it */ connect(ctrl, &lsa->u.sa, lsa->len); + dbg("connected ctrl:%d to remote peer\n", ctrl); free(lsa); } /* prepare env and exec program */ @@ -1391,6 +1433,7 @@ int inetd_main(int argc UNUSED_PARAM, char **argv) */ xmove_fd(ctrl, STDIN_FILENO); xdup2(STDIN_FILENO, STDOUT_FILENO); + dbg("moved ctrl:%d to fd 0,1[,2]\n", ctrl); /* manpages of inetd I managed to find either say * that stderr is also redirected to the network, * or do not talk about redirection at all (!) */ @@ -1403,6 +1446,7 @@ int inetd_main(int argc UNUSED_PARAM, char **argv) maybe_close(sep2->se_fd); sigaction_set(SIGPIPE, &saved_pipe_handler); restore_sigmask(&omask); + dbg("execing:'%s'\n", sep->se_program); BB_EXECVP(sep->se_program, sep->se_argv); bb_perror_msg("can't execute '%s'", sep->se_program); do_exit1: -- cgit v1.2.3-55-g6feb From 46aa5e0859646a1e8f96282b0ab2c362c7565a85 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Sun, 11 Sep 2011 20:08:12 +0200 Subject: tune2fs: add support for -C MOUNT_COUNT. +40 bytes. Closes 3901. Signed-off-by: Denys Vlasenko --- e2fsprogs/tune2fs.c | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/e2fsprogs/tune2fs.c b/e2fsprogs/tune2fs.c index 9daec542a..020bdaa33 100644 --- a/e2fsprogs/tune2fs.c +++ b/e2fsprogs/tune2fs.c @@ -28,12 +28,13 @@ do { \ (sizeof(field) == 4 ? SWAP_LE32(field) : BUG_wrong_field_size()) //usage:#define tune2fs_trivial_usage -//usage: "[-c MOUNT_CNT] " +//usage: "[-c MAX_MOUNT_COUNT] " ////usage: "[-e errors-behavior] [-g group] " //usage: "[-i DAYS] " ////usage: "[-j] [-J journal-options] [-l] [-s sparse-flag] " ////usage: "[-m reserved-blocks-percent] [-o [^]mount-options[,...]] " -////usage: "[-r reserved-blocks-count] [-u user] [-C mount-count] " +////usage: "[-r reserved-blocks-count] [-u user] " +//usage: "[-C MOUNT_COUNT] " //usage: "[-L LABEL] " ////usage: "[-M last-mounted-dir] [-O [^]feature[,...]] " ////usage: "[-T last-check-time] [-U UUID] " @@ -46,18 +47,19 @@ enum { OPT_L = 1 << 0, // label OPT_c = 1 << 1, // max mount count OPT_i = 1 << 2, // check interval + OPT_C = 1 << 3, // current mount count }; int tune2fs_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; int tune2fs_main(int argc UNUSED_PARAM, char **argv) { unsigned opts; - const char *label, *str_c, *str_i; + const char *label, *str_c, *str_i, *str_C; struct ext2_super_block *sb; int fd; opt_complementary = "=1"; - opts = getopt32(argv, "L:c:i:", &label, &str_c, &str_i); + opts = getopt32(argv, "L:c:i:C:", &label, &str_c, &str_i, &str_C); if (!opts) bb_show_usage(); argv += optind; // argv[0] -- device @@ -71,6 +73,11 @@ int tune2fs_main(int argc UNUSED_PARAM, char **argv) // mangle superblock //STORE_LE(sb->s_wtime, time(NULL)); - why bother? + if (opts & OPT_C) { + int n = xatoi_range(str_C, 1, 0xfffe); + STORE_LE(sb->s_mnt_count, (unsigned)n); + } + // set the label if (opts & OPT_L) safe_strncpy((char *)sb->s_volume_name, label, sizeof(sb->s_volume_name)); -- cgit v1.2.3-55-g6feb From 5126cf9a15f9e5c3986be0fc2743b63adcc6b1fb Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Sun, 11 Sep 2011 20:27:28 +0200 Subject: ping: display real IPv6 response address. Hopefully closes 3745. Signed-off-by: Denys Vlasenko --- networking/ping.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/networking/ping.c b/networking/ping.c index a1fd9dfb1..b8a438ba8 100644 --- a/networking/ping.c +++ b/networking/ping.c @@ -613,7 +613,7 @@ static void unpack4(char *buf, int sz, struct sockaddr_in *from) } } #if ENABLE_PING6 -static void unpack6(char *packet, int sz, /*struct sockaddr_in6 *from,*/ int hoplimit) +static void unpack6(char *packet, int sz, struct sockaddr_in6 *from, int hoplimit) { struct icmp6_hdr *icmppkt; char buf[INET6_ADDRSTRLEN]; @@ -633,7 +633,7 @@ static void unpack6(char *packet, int sz, /*struct sockaddr_in6 *from,*/ int hop if (sz >= sizeof(struct icmp6_hdr) + sizeof(uint32_t)) tp = (uint32_t *) &icmppkt->icmp6_data8[4]; unpack_tail(sz, tp, - inet_ntop(AF_INET6, &pingaddr.sin6.sin6_addr, + inet_ntop(AF_INET6, &from->sin6_addr, buf, sizeof(buf)), recv_seq, hoplimit); } else if (icmppkt->icmp6_type != ICMP6_ECHO_REQUEST) { @@ -783,7 +783,7 @@ static void ping6(len_and_sockaddr *lsa) move_from_unaligned_int(hoplimit, CMSG_DATA(mp)); } } - unpack6(G.rcv_packet, c, /*&from,*/ hoplimit); + unpack6(G.rcv_packet, c, &from, hoplimit); if (pingcount && nreceived >= pingcount) break; } -- cgit v1.2.3-55-g6feb From dd1061b6a79b0161597799e825bfefc27993ace5 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Sun, 11 Sep 2011 21:04:02 +0200 Subject: wget: URL-decode user:password before base64-encoding it into auth hdr. Closes 3625. function old new delta percent_decode_in_place - 152 +152 parse_url 304 317 +13 handle_incoming_and_exit 2795 2798 +3 httpd_main 763 760 -3 decodeString 152 - -152 ------------------------------------------------------------------------------ (add/remove: 2/1 grow/shrink: 2/1 up/down: 168/-155) Total: 13 bytes Signed-off-by: Denys Vlasenko --- include/libbb.h | 9 ++++++ libbb/percent_decode.c | 69 +++++++++++++++++++++++++++++++++++++++++++++ networking/httpd.c | 76 ++------------------------------------------------ networking/wget.c | 13 ++++----- 4 files changed, 86 insertions(+), 81 deletions(-) create mode 100644 libbb/percent_decode.c diff --git a/include/libbb.h b/include/libbb.h index d0c7ace22..21cbe1cac 100644 --- a/include/libbb.h +++ b/include/libbb.h @@ -1578,6 +1578,15 @@ int starts_with_cpu(const char *str) FAST_FUNC; unsigned get_cpu_count(void) FAST_FUNC; +/* Use strict=1 if you process input from untrusted source: + * it will return NULL on invalid %xx (bad hex chars) + * and str + 1 if decoded char is / or NUL. + * In non-strict mode, it always succeeds (returns str), + * and also it additionally decoded '+' to space. + */ +char *percent_decode_in_place(char *str, int strict) FAST_FUNC; + + extern const char bb_uuenc_tbl_base64[]; extern const char bb_uuenc_tbl_std[]; void bb_uuencode(char *store, const void *s, int length, const char *tbl) FAST_FUNC; diff --git a/libbb/percent_decode.c b/libbb/percent_decode.c new file mode 100644 index 000000000..9a9d80c4a --- /dev/null +++ b/libbb/percent_decode.c @@ -0,0 +1,69 @@ +/* vi: set sw=4 ts=4: */ +/* + * Licensed under GPLv2 or later, see file LICENSE in this source tree. + */ + +//kbuild:lib-y += percent_decode.o + +#include "libbb.h" + +static unsigned hex_to_bin(unsigned char c) +{ + unsigned v; + + v = c - '0'; + if (v <= 9) + return v; + /* c | 0x20: letters to lower case, non-letters + * to (potentially different) non-letters */ + v = (unsigned)(c | 0x20) - 'a'; + if (v <= 5) + return v + 10; + return ~0; +/* For testing: +void t(char c) { printf("'%c'(%u) %u\n", c, c, hex_to_bin(c)); } +int main() { t(0x10); t(0x20); t('0'); t('9'); t('A'); t('F'); t('a'); t('f'); +t('0'-1); t('9'+1); t('A'-1); t('F'+1); t('a'-1); t('f'+1); return 0; } +*/ +} + +char* FAST_FUNC percent_decode_in_place(char *str, int strict) +{ + /* note that decoded string is always shorter than original */ + char *src = str; + char *dst = str; + char c; + + while ((c = *src++) != '\0') { + unsigned v; + + if (!strict && c == '+') { + *dst++ = ' '; + continue; + } + if (c != '%') { + *dst++ = c; + continue; + } + v = hex_to_bin(src[0]); + if (v > 15) { + bad_hex: + if (strict) + return NULL; + *dst++ = '%'; + continue; + } + v = (v * 16) | hex_to_bin(src[1]); + if (v > 255) + goto bad_hex; + if (strict && (v == '/' || v == '\0')) { + /* caller takes it as indication of invalid + * (dangerous wrt exploits) chars */ + return str + 1; + } + *dst++ = v; + src += 2; + } + *dst = '\0'; + return str; +} diff --git a/networking/httpd.c b/networking/httpd.c index ba5eebad5..24482fe52 100644 --- a/networking/httpd.c +++ b/networking/httpd.c @@ -820,78 +820,6 @@ static char *encodeString(const char *string) } #endif -/* - * Given a URL encoded string, convert it to plain ascii. - * Since decoding always makes strings smaller, the decode is done in-place. - * Thus, callers should xstrdup() the argument if they do not want the - * argument modified. The return is the original pointer, allowing this - * function to be easily used as arguments to other functions. - * - * string The first string to decode. - * option_d 1 if called for httpd -d - * - * Returns a pointer to the decoded string (same as input). - */ -static unsigned hex_to_bin(unsigned char c) -{ - unsigned v; - - v = c - '0'; - if (v <= 9) - return v; - /* c | 0x20: letters to lower case, non-letters - * to (potentially different) non-letters */ - v = (unsigned)(c | 0x20) - 'a'; - if (v <= 5) - return v + 10; - return ~0; -/* For testing: -void t(char c) { printf("'%c'(%u) %u\n", c, c, hex_to_bin(c)); } -int main() { t(0x10); t(0x20); t('0'); t('9'); t('A'); t('F'); t('a'); t('f'); -t('0'-1); t('9'+1); t('A'-1); t('F'+1); t('a'-1); t('f'+1); return 0; } -*/ -} -static char *decodeString(char *orig, int option_d) -{ - /* note that decoded string is always shorter than original */ - char *string = orig; - char *ptr = string; - char c; - - while ((c = *ptr++) != '\0') { - unsigned v; - - if (option_d && c == '+') { - *string++ = ' '; - continue; - } - if (c != '%') { - *string++ = c; - continue; - } - v = hex_to_bin(ptr[0]); - if (v > 15) { - bad_hex: - if (!option_d) - return NULL; - *string++ = '%'; - continue; - } - v = (v * 16) | hex_to_bin(ptr[1]); - if (v > 255) - goto bad_hex; - if (!option_d && (v == '/' || v == '\0')) { - /* caller takes it as indication of invalid - * (dangerous wrt exploits) chars */ - return orig + 1; - } - *string++ = v; - ptr += 2; - } - *string = '\0'; - return orig; -} - #if ENABLE_FEATURE_HTTPD_BASIC_AUTH /* * Decode a base64 data stream as per rfc1521. @@ -1949,7 +1877,7 @@ static void handle_incoming_and_exit(const len_and_sockaddr *fromAddr) } /* Decode URL escape sequences */ - tptr = decodeString(urlcopy, 0); + tptr = percent_decode_in_place(urlcopy, /*strict:*/ 1); if (tptr == NULL) send_headers_and_exit(HTTP_BAD_REQUEST); if (tptr == urlcopy + 1) { @@ -2408,7 +2336,7 @@ int httpd_main(int argc UNUSED_PARAM, char **argv) , &verbose ); if (opt & OPT_DECODE_URL) { - fputs(decodeString(url_for_decode, 1), stdout); + fputs(percent_decode_in_place(url_for_decode, /*strict:*/ 0), stdout); return 0; } #if ENABLE_FEATURE_HTTPD_ENCODE_URL_STR diff --git a/networking/wget.c b/networking/wget.c index 6443705fd..94a2f7c3d 100644 --- a/networking/wget.c +++ b/networking/wget.c @@ -298,8 +298,13 @@ static void parse_url(const char *src_url, struct host_info *h) sp = strrchr(h->host, '@'); if (sp != NULL) { - h->user = h->host; + // URL-decode "user:password" string before base64-encoding: + // wget http://test:my%20pass@example.com should send + // Authorization: Basic dGVzdDpteSBwYXNz + // 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); h->host = sp + 1; } @@ -660,12 +665,6 @@ static void download_one_url(const char *url) #if ENABLE_FEATURE_WGET_AUTHENTICATION if (target.user) { -//TODO: URL-decode "user:password" string before base64-encoding: -//wget http://test:my%20pass@example.com should send -// Authorization: Basic dGVzdDpteSBwYXNz -//which decodes to "test:my pass", instead of what we send now: -// Authorization: Basic dGVzdDpteSUyMHBhc3M= -//Can reuse decodeString() from httpd.c fprintf(sfp, "Proxy-Authorization: Basic %s\r\n"+6, base64enc(target.user)); } -- cgit v1.2.3-55-g6feb From 13e709c53f700a18a660feebdf72c613a233bf48 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Mon, 12 Sep 2011 02:13:47 +0200 Subject: losetup: implement -r option. Closes 4033. function old new delta packed_usage 28595 28633 +38 losetup_main 285 290 +5 singlemount 906 908 +2 set_loop 674 672 -2 Signed-off-by: Denys Vlasenko --- include/libbb.h | 2 +- libbb/loop.c | 10 ++++++---- util-linux/losetup.c | 16 +++++++++------- util-linux/mount.c | 2 +- 4 files changed, 17 insertions(+), 13 deletions(-) diff --git a/include/libbb.h b/include/libbb.h index 21cbe1cac..feae85259 100644 --- a/include/libbb.h +++ b/include/libbb.h @@ -1164,7 +1164,7 @@ extern int del_loop(const char *device) FAST_FUNC; /* If *devname is not NULL, use that name, otherwise try to find free one, * malloc and return it in *devname. * return value: 1: read-only loopdev was setup, 0: rw, < 0: error */ -extern int set_loop(char **devname, const char *file, unsigned long long offset) FAST_FUNC; +extern int set_loop(char **devname, const char *file, unsigned long long offset, int ro) FAST_FUNC; /* Like bb_ask below, but asks on stdin with no timeout. */ char *bb_ask_stdin(const char * prompt) FAST_FUNC; diff --git a/libbb/loop.c b/libbb/loop.c index b798932fa..b3a520848 100644 --- a/libbb/loop.c +++ b/libbb/loop.c @@ -84,7 +84,7 @@ int FAST_FUNC del_loop(const char *device) search will re-use an existing loop device already bound to that file/offset if it finds one. */ -int FAST_FUNC set_loop(char **device, const char *file, unsigned long long offset) +int FAST_FUNC set_loop(char **device, const char *file, unsigned long long offset, int ro) { char dev[LOOP_NAMESIZE]; char *try; @@ -93,11 +93,13 @@ int FAST_FUNC set_loop(char **device, const char *file, unsigned long long offse int i, dfd, ffd, mode, rc = -1; /* Open the file. Barf if this doesn't work. */ - mode = O_RDWR; + mode = ro ? O_RDONLY : O_RDWR; ffd = open(file, mode); if (ffd < 0) { - mode = O_RDONLY; - ffd = open(file, mode); + if (mode != O_RDONLY) { + mode = O_RDONLY; + ffd = open(file, mode); + } if (ffd < 0) return -errno; } diff --git a/util-linux/losetup.c b/util-linux/losetup.c index 9b7c49f50..21108d0bf 100644 --- a/util-linux/losetup.c +++ b/util-linux/losetup.c @@ -8,11 +8,12 @@ */ //usage:#define losetup_trivial_usage -//usage: "[-o OFS] LOOPDEV FILE - associate loop devices\n" +//usage: "[-r] [-o OFS] LOOPDEV FILE - associate loop devices\n" //usage: " losetup -d LOOPDEV - disassociate\n" //usage: " losetup [-f] - show" //usage:#define losetup_full_usage "\n\n" //usage: " -o OFS Start OFS bytes into FILE" +//usage: "\n -r Read-only" //usage: "\n -f Show first free loop device" //usage: //usage:#define losetup_notes_usage @@ -37,11 +38,12 @@ int losetup_main(int argc UNUSED_PARAM, char **argv) OPT_d = (1 << 0), OPT_o = (1 << 1), OPT_f = (1 << 2), + OPT_r = (1 << 3), /* must be last */ }; - /* max 2 args, all opts are mutually exclusive */ + /* max 2 args, -d,-o,-f opts are mutually exclusive */ opt_complementary = "?2:d--of:o--df:f--do"; - opt = getopt32(argv, "do:f", &opt_o); + opt = getopt32(argv, "do:fr", &opt_o); argv += optind; if (opt == OPT_o) @@ -63,12 +65,12 @@ int losetup_main(int argc UNUSED_PARAM, char **argv) bb_show_usage(); if (argv[1]) { - /* [-o OFS] BLOCKDEV FILE */ - if (set_loop(&argv[0], argv[1], offset) < 0) + /* [-r] [-o OFS] BLOCKDEV FILE */ + if (set_loop(&argv[0], argv[1], offset, (opt / OPT_r)) < 0) bb_simple_perror_msg_and_die(argv[0]); return EXIT_SUCCESS; } - /* [-o OFS] BLOCKDEV */ + /* [-r] [-o OFS] BLOCKDEV */ s = query_loop(argv[0]); if (!s) bb_simple_perror_msg_and_die(argv[0]); @@ -78,7 +80,7 @@ int losetup_main(int argc UNUSED_PARAM, char **argv) return EXIT_SUCCESS; } - /* [-o OFS|-f] with no params */ + /* [-r] [-o OFS|-f] with no params */ n = 0; while (1) { char *s; diff --git a/util-linux/mount.c b/util-linux/mount.c index 05e532cda..b51ab1782 100644 --- a/util-linux/mount.c +++ b/util-linux/mount.c @@ -1809,7 +1809,7 @@ static int singlemount(struct mntent *mp, int ignore_busy) if (ENABLE_FEATURE_MOUNT_LOOP && S_ISREG(st.st_mode)) { loopFile = bb_simplify_path(mp->mnt_fsname); mp->mnt_fsname = NULL; // will receive malloced loop dev name - if (set_loop(&mp->mnt_fsname, loopFile, 0) < 0) { + if (set_loop(&mp->mnt_fsname, loopFile, 0, /*ro:*/ 0) < 0) { if (errno == EPERM || errno == EACCES) bb_error_msg(bb_msg_perm_denied_are_you_root); else -- cgit v1.2.3-55-g6feb From 74b871febbaf8b363c27879bea398cf11da3f48c Mon Sep 17 00:00:00 2001 From: Bernhard Reutner-Fischer Date: Wed, 15 Jun 2011 21:00:18 +0200 Subject: Config: fix wording in help-text Signed-off-by: Bernhard Reutner-Fischer --- libbb/Config.src | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libbb/Config.src b/libbb/Config.src index f45e43b04..ee1b66a45 100644 --- a/libbb/Config.src +++ b/libbb/Config.src @@ -191,8 +191,8 @@ config FEATURE_SKIP_ROOTFS However, some systems do not mount anything on /. If you need to configure busybox for one of these systems, - you may find useful to turn this option off to make df show - initramfs statistic. + you may find it useful to turn this option off to make df show + initramfs statistics. Otherwise, choose Y. -- cgit v1.2.3-55-g6feb From f9e07e70bb086697190ac1dcfb75d99b59a374be Mon Sep 17 00:00:00 2001 From: Pascal Bellard Date: Tue, 13 Sep 2011 18:39:04 +0200 Subject: conspy: add framebuffer support, -Q option. Signed-off-by: Pascal Bellard Signed-off-by: Denys Vlasenko --- miscutils/conspy.c | 114 +++++++++++++++++++++++++++++++++-------------------- 1 file changed, 71 insertions(+), 43 deletions(-) diff --git a/miscutils/conspy.c b/miscutils/conspy.c index c6ed91832..1a46a4340 100644 --- a/miscutils/conspy.c +++ b/miscutils/conspy.c @@ -25,25 +25,31 @@ //config: or conspy -cs NUM poor man's GNU screen like //usage:#define conspy_trivial_usage -//usage: "[-vcsndf] [-x COL] [-y LINE] [CONSOLE_NO]" +//usage: "[-vcsndfFQ] [-x COL] [-y LINE] [CONSOLE_NO]" //usage:#define conspy_full_usage "\n\n" //usage: "A text-mode VNC like program for Linux virtual consoles." //usage: "\nTo exit, quickly press ESC 3 times." //usage: "\n" //usage: "\n -v Don't send keystrokes to the console" -//usage: "\n -c Create missing devices in /dev" +//usage: "\n -c Create missing /dev/{tty,vcsa}N" //usage: "\n -s Open a SHELL session" //usage: "\n -n Black & white" //usage: "\n -d Dump console to stdout" //usage: "\n -f Follow cursor" +//usage: "\n -F Assume console is on a framebuffer device" +//usage: "\n -Q Disable exit on ESC-ESC-ESC" //usage: "\n -x COL Starting column" //usage: "\n -y LINE Starting line" #include "libbb.h" #include - #define ESC "\033" +#define CURSOR_ON -1 +#define CURSOR_OFF 1 + +#define DEV_TTY "/dev/tty" +#define DEV_VCSA "/dev/vcsa" struct screen_info { unsigned char lines, cols, cursor_x, cursor_y; @@ -72,19 +78,17 @@ struct globals { unsigned col; unsigned line; smallint curoff; // unknown:0 cursor on:-1 cursor off:1 - char attrbuf[sizeof(ESC"[0;1;5;30;40m")]; + char attrbuf[sizeof("0;1;5;30;40m")]; // remote console struct screen_info remote; // saved local tty terminfo struct termios term_orig; - char vcsa_name[sizeof("/dev/vcsaNN")]; + char vcsa_name[sizeof(DEV_VCSA "NN")]; }; #define G (*ptr_to_globals) #define INIT_G() do { \ SET_PTR_TO_GLOBALS(xzalloc(sizeof(G))); \ - G.attrbuf[0] = '\033'; \ - G.attrbuf[1] = '['; \ G.width = G.height = UINT_MAX; \ G.last_attr--; \ } while (0) @@ -92,18 +96,26 @@ struct globals { enum { FLAG_v, // view only FLAG_c, // create device if need + FLAG_Q, // never exit FLAG_s, // session FLAG_n, // no colors FLAG_d, // dump screen FLAG_f, // follow cursor + FLAG_F, // framebuffer }; #define FLAG(x) (1 << FLAG_##x) #define BW (option_mask32 & FLAG(n)) +static void putcsi(const char *s) +{ + fputs(ESC"[", stdout); + fputs(s, stdout); +} + static void clrscr(void) { // Home, clear till end of screen - fputs(ESC"[1;1H" ESC"[J", stdout); + putcsi("1;1H" ESC"[J"); G.col = G.line = 0; } @@ -111,7 +123,7 @@ static void set_cursor(int state) { if (G.curoff != state) { G.curoff = state; - fputs(ESC"[?25", stdout); + putcsi("?25"); bb_putchar("h?l"[1 + state]); } } @@ -125,18 +137,19 @@ static void gotoxy(int col, int line) } } +static void cleanup(int code) NORETURN; static void cleanup(int code) { - set_cursor(-1); // cursor on + set_cursor(CURSOR_ON); tcsetattr(G.kbd_fd, TCSANOW, &G.term_orig); if (ENABLE_FEATURE_CLEAN_UP) { close(G.kbd_fd); } // Reset attributes if (!BW) - fputs(ESC"[0m", stdout); + putcsi("0m"); bb_putchar('\n'); - if (code > 1) + if (code > EXIT_FAILURE) kill_myself_with_sig(code); exit(code); } @@ -157,8 +170,8 @@ static void screen_read_close(void) G.size = i; G.data = xzalloc(2 * i); } - else if (G.size != i) { - cleanup(1); + if (G.size != i) { + cleanup(EXIT_FAILURE); } data = G.data + G.current; xread(vcsa_fd, data, G.size); @@ -168,10 +181,15 @@ static void screen_read_close(void) unsigned x = j - G.x; // if will catch j < G.x too unsigned y = i - G.y; // if will catch i < G.y too - if (CHAR(data) < ' ') - CHAR(data) = ' '; if (y >= G.height || x >= G.width) DATA(data) = 0; + else { + uint8_t ch = CHAR(data); + if (ch < ' ') + CHAR(data) = ch | 0x40; + else if (ch > 0x7e) + CHAR(data) = '?'; + } } } } @@ -179,10 +197,13 @@ static void screen_read_close(void) static void screen_char(char *data) { if (!BW) { + uint8_t attr_diff; uint8_t attr = ATTR(data); - //uint8_t attr = ATTR(data) >> 1; // for framebuffer console - uint8_t attr_diff = G.last_attr ^ attr; + if (option_mask32 & FLAG(F)) { + attr >>= 1; + } + attr_diff = G.last_attr ^ attr; if (attr_diff) { // Attribute layout for VGA compatible text videobuffer: // blinking text @@ -213,7 +234,7 @@ static void screen_char(char *data) const uint8_t bg_mask = 0x70, blink_mask = 0x80; char *ptr; - ptr = G.attrbuf + 2; // skip "ESC [" + ptr = G.attrbuf; // (G.last_attr & ~attr) has 1 only where // G.last_attr has 1 but attr has 0. @@ -244,12 +265,12 @@ static void screen_char(char *data) if (attr_diff & bg_mask) { *ptr++ = '4'; *ptr++ = color[(attr & bg_mask) >> 4]; - *ptr++ = ';'; + ptr++; // last attribute } - if (ptr != G.attrbuf + 2) { + if (ptr != G.attrbuf) { ptr[-1] = 'm'; *ptr = '\0'; - fputs(G.attrbuf, stdout); + putcsi(G.attrbuf); } } } @@ -292,11 +313,11 @@ static void curmove(void) { unsigned cx = G.remote.cursor_x - G.x; unsigned cy = G.remote.cursor_y - G.y; - int cursor = 1; + int cursor = CURSOR_OFF; if (cx < G.width && cy < G.height) { gotoxy(cx, cy); - cursor = -1; + cursor = CURSOR_ON; } set_cursor(cursor); } @@ -341,7 +362,7 @@ static NOINLINE void start_shell_in_child(const char* tty_name) int conspy_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; int conspy_main(int argc UNUSED_PARAM, char **argv) { - char tty_name[sizeof("/dev/ttyNN")]; + char tty_name[sizeof(DEV_TTY "NN")]; #define keybuf bb_common_bufsiz1 struct termios termbuf; unsigned opts; @@ -351,26 +372,28 @@ int conspy_main(int argc UNUSED_PARAM, char **argv) static const char getopt_longopts[] ALIGN1 = "viewonly\0" No_argument "v" "createdevice\0" No_argument "c" + "neverquit\0" No_argument "Q" "session\0" No_argument "s" "nocolors\0" No_argument "n" "dump\0" No_argument "d" "follow\0" No_argument "f" + "framebuffer\0" No_argument "F" ; applet_long_options = getopt_longopts; #endif INIT_G(); - strcpy(G.vcsa_name, "/dev/vcsa"); + strcpy(G.vcsa_name, DEV_VCSA); opt_complementary = "x+:y+"; // numeric params - opts = getopt32(argv, "vcsndfx:y:", &G.x, &G.y); + opts = getopt32(argv, "vcQsndfFx:y:", &G.x, &G.y); argv += optind; ttynum = 0; if (argv[0]) { ttynum = xatou_range(argv[0], 0, 63); - sprintf(G.vcsa_name + sizeof("/dev/vcsa")-1, "%u", ttynum); + sprintf(G.vcsa_name + sizeof(DEV_VCSA)-1, "%u", ttynum); } - sprintf(tty_name, "%s%u", "/dev/tty", ttynum); + sprintf(tty_name, "%s%u", DEV_TTY, ttynum); if (opts & FLAG(c)) { if ((opts & (FLAG(s)|FLAG(v))) != FLAG(v)) create_cdev_if_doesnt_exist(tty_name, makedev(4, ttynum)); @@ -481,7 +504,7 @@ int conspy_main(int argc UNUSED_PARAM, char **argv) char *k; case -1: if (errno != EINTR) - cleanup(1); + goto abort; break; case 0: if (++G.nokeys >= 4) @@ -492,14 +515,16 @@ int conspy_main(int argc UNUSED_PARAM, char **argv) k = keybuf + G.key_count; bytes_read = read(G.kbd_fd, k, sizeof(keybuf) - G.key_count); if (bytes_read < 0) - cleanup(1); + goto abort; // Do exit processing - for (i = 0; i < bytes_read; i++) { - if (k[i] != '\033') - G.escape_count = 0; - else if (++G.escape_count >= 3) - cleanup(0); + if (!(option_mask32 & FLAG(Q))) { + for (i = 0; i < bytes_read; i++) { + if (k[i] != '\033') + G.escape_count = -1; + if (++G.escape_count >= 3) + cleanup(EXIT_SUCCESS); + } } } poll_timeout_ms = 250; @@ -519,6 +544,7 @@ int conspy_main(int argc UNUSED_PARAM, char **argv) if (result >= 0) { char *p = keybuf; + G.ioerror_count = 0; if (kbd_mode != K_XLATE && kbd_mode != K_UNICODE) { G.key_count = 0; // scan code mode } @@ -534,16 +560,18 @@ int conspy_main(int argc UNUSED_PARAM, char **argv) poll_timeout_ms = 20; } } + // We sometimes get spurious IO errors on the TTY + // as programs close and re-open it + else if (errno != EIO || ++G.ioerror_count > 4) { + if (ENABLE_FEATURE_CLEAN_UP) + close(handle); + goto abort; + } // Close & re-open tty in case they have // swapped virtual consoles close(handle); - - // We sometimes get spurious IO errors on the TTY - // as programs close and re-open it - if (result >= 0) - G.ioerror_count = 0; - else if (errno != EIO || ++G.ioerror_count > 4) - cleanup(1); } } /* while (1) */ + abort: + cleanup(EXIT_FAILURE); } -- cgit v1.2.3-55-g6feb From a221bc5f9909a6914ec6f4d14f76bb28c4a4cddf Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Tue, 13 Sep 2011 18:40:22 +0200 Subject: sed: better help text Signed-off-by: Denys Vlasenko --- editors/sed.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/editors/sed.c b/editors/sed.c index 1552cf370..c8bb503ea 100644 --- a/editors/sed.c +++ b/editors/sed.c @@ -26,7 +26,7 @@ * add_input_file() adds a FILE* to the list of input files. We need to * know all input sources ahead of time to find the last line for the $ match. * - * process_files() does actual sedding, reading data lines from each input FILE * + * process_files() does actual sedding, reading data lines from each input FILE* * (which could be stdin) and applying the sed command list (sed_cmd_head) to * each of the resulting lines. * @@ -57,7 +57,8 @@ */ //usage:#define sed_trivial_usage -//usage: "[-efinr] SED_CMD [FILE]..." +//usage: "[-inr] [-f FILE]... [-e CMD]... [FILE]...\n" +//usage: "or: sed [-inr] CMD [FILE]..." //usage:#define sed_full_usage "\n\n" //usage: " -e CMD Add CMD to sed commands to be executed" //usage: "\n -f FILE Add FILE contents to sed commands to be executed" -- cgit v1.2.3-55-g6feb From 378ab6819907fa9e439e93ed081c73c2351b4330 Mon Sep 17 00:00:00 2001 From: Ian Wienand Date: Wed, 14 Sep 2011 08:41:38 +0200 Subject: login: new option LOGIN_SESSION_AS_CHILD Signed-off-by: Ian Wienand Signed-off-by: Denys Vlasenko --- debianutils/run_parts.c | 3 +++ loginutils/Config.src | 11 ++++++++++ loginutils/login.c | 53 +++++++++++++++++++++++++++++++++++++++++++------ 3 files changed, 61 insertions(+), 6 deletions(-) diff --git a/debianutils/run_parts.c b/debianutils/run_parts.c index 65cbfc338..8f08f6dc6 100644 --- a/debianutils/run_parts.c +++ b/debianutils/run_parts.c @@ -66,6 +66,7 @@ struct globals { #define names (G.names) #define cur (G.cur ) #define cmd (G.cmd ) +#define INIT_G() do { } while (0) enum { NUM_CMD = (COMMON_BUFSIZE - sizeof(G)) / sizeof(cmd[0]) - 1 }; @@ -143,6 +144,8 @@ int run_parts_main(int argc UNUSED_PARAM, char **argv) unsigned n; int ret; + INIT_G(); + #if ENABLE_FEATURE_RUN_PARTS_LONG_OPTIONS applet_long_options = runparts_longopts; #endif diff --git a/loginutils/Config.src b/loginutils/Config.src index 0d7f50cf1..14ce53434 100644 --- a/loginutils/Config.src +++ b/loginutils/Config.src @@ -205,6 +205,17 @@ config LOGIN Note that Busybox binary must be setuid root for this applet to work properly. +config LOGIN_SESSION_AS_CHILD + bool "Run logged in session in a child process" + default y if PAM + depends on LOGIN + help + Run the logged in session in a child process. This allows + login to clean up things such as utmp entries or PAM sessions + when the login session is complete. If you use PAM, you + 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 diff --git a/loginutils/login.c b/loginutils/login.c index 2f7b9b212..534343129 100644 --- a/loginutils/login.c +++ b/loginutils/login.c @@ -41,8 +41,6 @@ enum { TTYNAME_SIZE = 32, }; -static char* short_tty; - #if ENABLE_FEATURE_NOLOGIN static void die_if_nologin(void) { @@ -74,7 +72,7 @@ static void die_if_nologin(void) #endif #if ENABLE_FEATURE_SECURETTY && !ENABLE_PAM -static int check_securetty(void) +static int check_securetty(const char *short_tty) { char *buf = (char*)"/etc/securetty"; /* any non-NULL is ok */ parser_t *parser = config_open2("/etc/securetty", fopen_for_read); @@ -89,7 +87,7 @@ static int check_securetty(void) return buf != NULL; } #else -static ALWAYS_INLINE int check_securetty(void) { return 1; } +static ALWAYS_INLINE int check_securetty(const char *short_tty UNUSED_PARAM) { return 1; } #endif #if ENABLE_SELINUX @@ -142,6 +140,29 @@ static void run_login_script(struct passwd *pw, char *full_tty) void run_login_script(struct passwd *pw, char *full_tty); #endif +#if ENABLE_LOGIN_SESSION_AS_CHILD && ENABLE_PAM +static void login_pam_end(pam_handle_t *pamh) +{ + int pamret; + + pamret = pam_setcred(pamh, PAM_DELETE_CRED); + if (pamret != PAM_SUCCESS) { + bb_error_msg("pam_%s failed: %s (%d)", "setcred", + pam_strerror(pamh, pamret), pamret); + } + pamret = pam_close_session(pamh, 0); + if (pamret != PAM_SUCCESS) { + bb_error_msg("pam_%s failed: %s (%d)", "close_session", + pam_strerror(pamh, pamret), pamret); + } + pamret = pam_end(pamh, pamret); + if (pamret != PAM_SUCCESS) { + bb_error_msg("pam_%s failed: %s (%d)", "end", + pam_strerror(pamh, pamret), pamret); + } +} +#endif /* ENABLE_PAM */ + static void get_username_or_die(char *buf, int size_buf) { int c, cntdown; @@ -214,6 +235,7 @@ int login_main(int argc UNUSED_PARAM, char **argv) char *opt_host = NULL; char *opt_user = opt_user; /* for compiler */ char *full_tty; + char *short_tty; IF_SELINUX(security_context_t user_sid = NULL;) #if ENABLE_PAM int pamret; @@ -224,6 +246,9 @@ int login_main(int argc UNUSED_PARAM, char **argv) char pwdbuf[256]; char **pamenv; #endif +#if ENABLE_LOGIN_SESSION_AS_CHILD + pid_t child_pid; +#endif username[0] = '\0'; signal(SIGALRM, alarm_handler); @@ -359,7 +384,7 @@ int login_main(int argc UNUSED_PARAM, char **argv) if (opt & LOGIN_OPT_f) break; /* -f USER: success without asking passwd */ - if (pw->pw_uid == 0 && !check_securetty()) + if (pw->pw_uid == 0 && !check_securetty(short_tty)) goto auth_failed; /* Don't check the password if password entry is empty (!) */ @@ -393,7 +418,23 @@ int login_main(int argc UNUSED_PARAM, char **argv) if (pw->pw_uid != 0) die_if_nologin(); - IF_SELINUX(initselinux(username, full_tty, &user_sid)); + +#if ENABLE_LOGIN_SESSION_AS_CHILD + child_pid = vfork(); + if (child_pid != 0) { + if (child_pid < 0) + bb_perror_msg("vfork"); + else { + if (safe_waitpid(child_pid, NULL, 0) == -1) + bb_perror_msg("waitpid"); + update_utmp(child_pid, DEAD_PROCESS, NULL, NULL, NULL); + } + IF_PAM(login_pam_end(pamh);) + return 0; + } +#endif + + IF_SELINUX(initselinux(username, full_tty, &user_sid);) /* Try these, but don't complain if they fail. * _f_chown is safe wrt race t=ttyname(0);...;chown(t); */ -- cgit v1.2.3-55-g6feb From dd1eb413f28a2a8b5768056e1967e87b2363dc32 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Thu, 15 Sep 2011 10:37:04 +0200 Subject: suppress "warning: implicit declaration of function 'alloca'" Signed-off-by: Denys Vlasenko --- scripts/basic/docproc.c | 1 + scripts/basic/fixdep.c | 1 + 2 files changed, 2 insertions(+) diff --git a/scripts/basic/docproc.c b/scripts/basic/docproc.c index 0984e7d4b..b12569832 100644 --- a/scripts/basic/docproc.c +++ b/scripts/basic/docproc.c @@ -39,6 +39,7 @@ #include #include #include +#include /* exitstatus is used to keep track of any failing calls to kernel-doc, * but execution continues. */ diff --git a/scripts/basic/fixdep.c b/scripts/basic/fixdep.c index f27a17984..165a8c39d 100644 --- a/scripts/basic/fixdep.c +++ b/scripts/basic/fixdep.c @@ -113,6 +113,7 @@ #include #include #include +#include /* bbox: not needed #define INT_CONF ntohl(0x434f4e46) -- cgit v1.2.3-55-g6feb From 585541e8e338a85b9f18cf5f6ed88758b29e61f2 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Thu, 15 Sep 2011 18:27:05 +0200 Subject: start_stop_daemon: set complementary group ids too. Closes 3253 Signed-off-by: Denys Vlasenko --- debianutils/start_stop_daemon.c | 12 ++++++++++-- networking/inetd.c | 2 +- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/debianutils/start_stop_daemon.c b/debianutils/start_stop_daemon.c index bc61959d2..02609c04f 100644 --- a/debianutils/start_stop_daemon.c +++ b/debianutils/start_stop_daemon.c @@ -502,8 +502,16 @@ int start_stop_daemon_main(int argc UNUSED_PARAM, char **argv) if (opt & OPT_c) { struct bb_uidgid_t ugid = { -1, -1 }; parse_chown_usergroup_or_die(&ugid, chuid); - if (ugid.gid != (gid_t) -1) xsetgid(ugid.gid); - if (ugid.uid != (uid_t) -1) xsetuid(ugid.uid); + if (ugid.uid != (uid_t) -1) { + struct passwd *pw = xgetpwuid(ugid.uid); + if (ugid.gid != (gid_t) -1) + pw->pw_gid = ugid.gid; + /* initgroups, setgid, setuid: */ + change_identity(pw); + } else if (ugid.gid != (gid_t) -1) { + xsetgid(ugid.gid); + setgroups(1, &ugid.gid); + } } #if ENABLE_FEATURE_START_STOP_DAEMON_FANCY if (opt & OPT_NICELEVEL) { diff --git a/networking/inetd.c b/networking/inetd.c index fc6847bb5..26b66992d 100644 --- a/networking/inetd.c +++ b/networking/inetd.c @@ -1414,7 +1414,7 @@ int inetd_main(int argc UNUSED_PARAM, char **argv) bb_error_msg("non-root must run services as himself"); goto do_exit1; } - if (pwd->pw_uid) { + if (pwd->pw_uid != 0) { if (sep->se_group) pwd->pw_gid = grp->gr_gid; /* initgroups, setgid, setuid: */ -- cgit v1.2.3-55-g6feb From d18ef6c9f6f5c94f2a65a6ab6ae3776711cb2877 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Fri, 16 Sep 2011 11:52:43 +0200 Subject: chpst: simple code shrink function old new delta chpst_main 733 718 -15 Signed-off-by: Denys Vlasenko --- runit/chpst.c | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/runit/chpst.c b/runit/chpst.c index 185706089..44c21a2a4 100644 --- a/runit/chpst.c +++ b/runit/chpst.c @@ -405,19 +405,18 @@ int chpst_main(int argc UNUSED_PARAM, char **argv) if (opt & OPT_e) edir(env_dir); - // FIXME: chrooted jail must have /etc/passwd if we move this after chroot! - // OTOH chroot fails for non-roots! - // SOLUTION: cache uid/gid before chroot, apply uid/gid after + if (opt & (OPT_u|OPT_U)) { + xget_uidgid(&ugid, set_user); + } + if (opt & OPT_U) { - xget_uidgid(&ugid, env_user); xsetenv("GID", utoa(ugid.gid)); xsetenv("UID", utoa(ugid.uid)); } - if (opt & OPT_u) { - xget_uidgid(&ugid, set_user); - } - + // chrooted jail must have /etc/passwd if we move this after chroot. + // OTOH chroot fails for non-roots. + // Solution: cache uid/gid before chroot, apply uid/gid after. if (opt & OPT_root) { xchdir(root); xchroot("."); -- cgit v1.2.3-55-g6feb From c74a79f28824b634d621c572c079614a8c227479 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Fri, 16 Sep 2011 11:54:13 +0200 Subject: chpst: move misplaced comment Signed-off-by: Denys Vlasenko --- runit/chpst.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/runit/chpst.c b/runit/chpst.c index 44c21a2a4..9b8c99bdd 100644 --- a/runit/chpst.c +++ b/runit/chpst.c @@ -405,18 +405,17 @@ int chpst_main(int argc UNUSED_PARAM, char **argv) if (opt & OPT_e) edir(env_dir); - if (opt & (OPT_u|OPT_U)) { + if (opt & (OPT_u|OPT_U)) xget_uidgid(&ugid, set_user); - } + // chrooted jail must have /etc/passwd if we move this after chroot. + // OTOH chroot fails for non-roots. + // Solution: cache uid/gid before chroot, apply uid/gid after. if (opt & OPT_U) { xsetenv("GID", utoa(ugid.gid)); xsetenv("UID", utoa(ugid.uid)); } - // chrooted jail must have /etc/passwd if we move this after chroot. - // OTOH chroot fails for non-roots. - // Solution: cache uid/gid before chroot, apply uid/gid after. if (opt & OPT_root) { xchdir(root); xchroot("."); -- cgit v1.2.3-55-g6feb From 514cbfc593aaccda22b376e5cc84d3387db2025a Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Fri, 16 Sep 2011 13:28:52 +0200 Subject: syslogd: fix missing newline problen in memory log buffer. Closes 4159 Signed-off-by: Denys Vlasenko --- sysklogd/syslogd.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sysklogd/syslogd.c b/sysklogd/syslogd.c index 2f0ca6ac5..d36d09caf 100644 --- a/sysklogd/syslogd.c +++ b/sysklogd/syslogd.c @@ -278,7 +278,7 @@ static void parse_syslogdcfg(const char *file) parser_t *parser; parser = config_open2(file ? file : "/etc/syslog.conf", - file ? xfopen_for_read : fopen_or_warn_stdin); + file ? xfopen_for_read : fopen_for_read); if (!parser) /* didn't find default /etc/syslog.conf */ /* proceed as if we built busybox without config support */ @@ -678,7 +678,7 @@ static void timestamp_and_log(int pri, char *msg, int len) if (LOG_PRI(pri) < G.logLevel) { #if ENABLE_FEATURE_IPC_SYSLOG if ((option_mask32 & OPT_circularlog) && G.shbuf) { - log_to_shmem(msg); + log_to_shmem(G.printbuf); return; } #endif -- cgit v1.2.3-55-g6feb From 6d2d652cd33679625f5d211d739fcd34826b3a9b Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Fri, 16 Sep 2011 14:28:32 +0200 Subject: applet_tables: fix single applet build failure. Closes 4009 Signed-off-by: Denys Vlasenko --- applets/applet_tables.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/applets/applet_tables.c b/applets/applet_tables.c index 3859d7326..a47574737 100644 --- a/applets/applet_tables.c +++ b/applets/applet_tables.c @@ -80,8 +80,15 @@ int main(int argc, char **argv) printf("#define NUM_APPLETS %u\n", NUM_APPLETS); if (NUM_APPLETS == 1) { + char *dash_to_underscore, *p; printf("#define SINGLE_APPLET_STR \"%s\"\n", applets[0].name); - printf("#define SINGLE_APPLET_MAIN %s_main\n", applets[0].name); + /* Example: "ether-wake" -> "ether_wake" */ + p = dash_to_underscore = strdup(applets[0].name); + p--; + while (*++p) + if (*p == '-') + *p = '_'; + printf("#define SINGLE_APPLET_MAIN %s_main\n", dash_to_underscore); } printf("\n"); -- cgit v1.2.3-55-g6feb From 0851d125c33d65cc8a0655758f2928960077c20c Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Sat, 17 Sep 2011 00:12:24 +0200 Subject: tail: fix -c +N. Closes 4111 Signed-off-by: Denys Vlasenko --- coreutils/tail.c | 6 +++--- testsuite/tail.tests | 8 ++++++++ 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/coreutils/tail.c b/coreutils/tail.c index 454c25936..43cecbd97 100644 --- a/coreutils/tail.c +++ b/coreutils/tail.c @@ -203,7 +203,7 @@ int tail_main(int argc, char **argv) int fd = fds[i]; if (ENABLE_FEATURE_FANCY_TAIL && fd < 0) - continue; /* may happen with -E */ + continue; /* may happen with -F */ if (nfiles > header_threshhold) { tail_xprint_header(fmt, argv[i]); @@ -252,14 +252,14 @@ int tail_main(int argc, char **argv) * Used only by +N code ("start from Nth", 1-based): */ seen = 1; newlines_seen = 0; - while ((nread = tail_read(fd, buf, tailbufsize-taillen)) > 0) { + while ((nread = tail_read(fd, buf, tailbufsize - taillen)) > 0) { if (G.from_top) { int nwrite = nread; if (seen < count) { /* We need to skip a few more bytes/lines */ if (COUNT_BYTES) { nwrite -= (count - seen); - seen = count; + seen += nread; } else { char *s = buf; do { diff --git a/testsuite/tail.tests b/testsuite/tail.tests index 7140da262..305a83b15 100755 --- a/testsuite/tail.tests +++ b/testsuite/tail.tests @@ -14,4 +14,12 @@ testing "tail: +N with N > file length" \ "0\n" \ "" "qw" +testing "tail: -c +N with largish N" \ + " + dd if=/dev/zero bs=16k count=1 2>/dev/null | tail -c +8200 | wc -c; + dd if=/dev/zero bs=16k count=1 2>/dev/null | tail -c +8208 | wc -c; + " \ + "8185\n8177\n" \ + "" "" + exit $FAILCOUNT -- cgit v1.2.3-55-g6feb From 34c469ae0495bb010969eb920c63d31ed4a0e793 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Sun, 18 Sep 2011 03:01:49 +0200 Subject: sendmail: don't talk until 220 code is seen. Closes 3487 function old new delta sendmail_main 934 939 +5 smtp_checkp 167 165 -2 packed_usage 28634 28621 -13 Signed-off-by: Denys Vlasenko --- mailutils/mail.c | 11 ++++--- mailutils/sendmail.c | 90 +++++++++++++++++++++++++++++----------------------- 2 files changed, 58 insertions(+), 43 deletions(-) diff --git a/mailutils/mail.c b/mailutils/mail.c index 66c79471f..f5260d9db 100644 --- a/mailutils/mail.c +++ b/mailutils/mail.c @@ -57,10 +57,13 @@ void FAST_FUNC launch_helper(const char **argv) G.helper_pid = xvfork(); i = (!G.helper_pid) * 2; // for parent:0, for child:2 - close(pipes[i + 1]); // 1 or 3 - closing one write end - close(pipes[2 - i]); // 2 or 0 - closing one read end - xmove_fd(pipes[i], STDIN_FILENO); // 0 or 2 - using other read end - xmove_fd(pipes[3 - i], STDOUT_FILENO); // 3 or 1 - other write end + close(pipes[i + 1]); // 1 or 3 - closing one write end + close(pipes[2 - i]); // 2 or 0 - closing one read end + xmove_fd(pipes[i], STDIN_FILENO); // 0 or 2 - using other read end + xmove_fd(pipes[3 - i], STDOUT_FILENO); // 3 or 1 - using other write end + // End result: + // parent stdout [3] -> child stdin [2] + // child stdout [1] -> parent stdin [0] if (!G.helper_pid) { // child: try to execute connection helper diff --git a/mailutils/sendmail.c b/mailutils/sendmail.c index e0aff20fb..dbd491002 100644 --- a/mailutils/sendmail.c +++ b/mailutils/sendmail.c @@ -26,18 +26,18 @@ //usage: "\n Examples:" //usage: "\n -H 'exec openssl s_client -quiet -tls1 -starttls smtp" //usage: "\n -connect smtp.gmail.com:25' -ap]" +//usage: "\n [4 -ap]" +//usage: "\n [4 Username for AUTH LOGIN" -//usage: "\n -ap Password for AUTH LOGIN" -//usage: "\n -am Authentication method. Ignored. LOGIN is implied" +//usage: "\n -auUSER Username for AUTH LOGIN" +//usage: "\n -apPASS Password for AUTH LOGIN" +////usage: "\n -amMETHOD Authentication method. Ignored. LOGIN is implied" //usage: "\n" //usage: "\nOther options are silently ignored; -oi -t is implied" //usage: IF_MAKEMIME( -//usage: "\nUse makemime applet to create message with attachments" +//usage: "\nUse makemime to create emails with attachments" //usage: ) #include "libbb.h" @@ -66,7 +66,7 @@ static int smtp_checkp(const char *fmt, const char *param, int code) // if not equal -> die saying msg while ((answer = xmalloc_fgetline(stdin)) != NULL) { if (verbose) - bb_error_msg("recv:'%.*s' %d", (int)(strchrnul(answer, '\r') - answer), answer, verbose); + bb_error_msg("recv:'%.*s'", (int)(strchrnul(answer, '\r') - answer), answer); if (strlen(answer) <= 3 || '-' != answer[3]) break; free(answer); @@ -75,10 +75,11 @@ static int smtp_checkp(const char *fmt, const char *param, int code) int n = atoi(answer); if (timeout) alarm(0); - free(msg); free(answer); - if (-1 == code || n == code) + if (-1 == code || n == code) { + free(msg); return n; + } } bb_error_msg_and_die("%s failed", msg); } @@ -176,11 +177,35 @@ int sendmail_main(int argc UNUSED_PARAM, char **argv) const char *args[] = { "sh", "-c", opt_connect, NULL }; // plug it in launch_helper(args); - // vanilla connection + // Now: + // our stdout will go to helper's stdin, + // helper's stdout will be available on our stdin. + + // Wait for initial server message. + // If helper (such as openssl) invokes STARTTLS, the initial 220 + // is swallowed by helper (and not repeated after TLS is initiated). + // We will send NOOP cmd to server and check the response. + // We should get 220+250 on plain connection, 250 on STARTTLSed session. + // + // The problem here is some servers delay initial 220 message, + // and consider client to be a spammer if it starts sending cmds + // before 220 reached it. The code below is unsafe in this regard: + // in non-STARTTLSed case, we potentially send NOOP before 220 + // is sent by server. + // Ideas? (--delay SECS opt? --assume-starttls-helper opt?) + code = smtp_check("NOOP", -1); + if (code == 220) + // we got 220 - this is not STARTTLSed connection, + // eat 250 response to our NOOP + smtp_check(NULL, 250); + else + if (code != 250) + bb_error_msg_and_die("SMTP init failed"); } else { + // vanilla connection int fd; // host[:port] not explicitly specified? -> use $SMTPHOST - // no $SMTPHOST ? -> use localhost + // no $SMTPHOST? -> use localhost if (!(opts & OPT_S)) { opt_connect = getenv("SMTPHOST"); if (!opt_connect) @@ -191,25 +216,14 @@ int sendmail_main(int argc UNUSED_PARAM, char **argv) // and make ourselves a simple IO filter xmove_fd(fd, STDIN_FILENO); xdup2(STDIN_FILENO, STDOUT_FILENO); - } - // N.B. from now we know nothing about network :) - // wait for initial server OK - // N.B. if we used openssl the initial 220 answer is already swallowed during openssl TLS init procedure - // so we need to kick the server to see whether we are ok - code = smtp_check("NOOP", -1); - // 220 on plain connection, 250 on openssl-helped TLS session - if (220 == code) - smtp_check(NULL, 250); // reread the code to stay in sync - else if (250 != code) - bb_error_msg_and_die("INIT failed"); + // Wait for initial server 220 message + smtp_check(NULL, 220); + } // we should start with modern EHLO - if (250 != smtp_checkp("EHLO %s", domain, -1)) { + if (250 != smtp_checkp("EHLO %s", domain, -1)) smtp_checkp("HELO %s", domain, 250); - } - if (ENABLE_FEATURE_CLEAN_UP) - free(domain); // perform authentication if (opts & OPT_a) { @@ -224,7 +238,7 @@ int sendmail_main(int argc UNUSED_PARAM, char **argv) } // set sender - // N.B. we have here a very loosely defined algotythm + // N.B. we have here a very loosely defined algorythm // since sendmail historically offers no means to specify secrets on cmdline. // 1) server can require no authentication -> // we must just provide a (possibly fake) reply address. @@ -241,8 +255,6 @@ int sendmail_main(int argc UNUSED_PARAM, char **argv) // G.user = xuid2uname(getuid()); // opt_from = xasprintf("%s@%s", G.user, domain); //} - //if (ENABLE_FEATURE_CLEAN_UP) - // free(domain); smtp_checkp("MAIL FROM:<%s>", opt_from, 250); // process message @@ -272,26 +284,26 @@ int sendmail_main(int argc UNUSED_PARAM, char **argv) if (0 == strncasecmp("To:", s, 3) || 0 == strncasecmp("Bcc:" + 1, s, 3)) { rcptto(sane_address(s+3)); goto addheader; + } // Bcc: header adds blind copy (hidden) recipient - } else if (0 == strncasecmp("Bcc:", s, 4)) { + if (0 == strncasecmp("Bcc:", s, 4)) { rcptto(sane_address(s+4)); free(s); // N.B. Bcc: vanishes from headers! - - // other headers go verbatim - - // N.B. RFC2822 2.2.3 "Long Header Fields" allows for headers to occupy several lines. - // Continuation is denoted by prefixing additional lines with whitespace(s). - // Thanks (stefan.seyfried at googlemail.com) for pointing this out. - } else if (strchr(s, ':') || (list && skip_whitespace(s) != s)) { + } else + if (strchr(s, ':') || (list && skip_whitespace(s) != s)) { + // other headers go verbatim + // N.B. RFC2822 2.2.3 "Long Header Fields" allows for headers to occupy several lines. + // Continuation is denoted by prefixing additional lines with whitespace(s). + // Thanks (stefan.seyfried at googlemail.com) for pointing this out. addheader: // N.B. we allow MAX_HEADERS generic headers at most to prevent attacks if (MAX_HEADERS && ++nheaders >= MAX_HEADERS) goto bail; llist_add_to_end(&list, s); - // a line without ":" (an empty line too, by definition) doesn't look like a valid header - // so stop "analyze headers" mode } else { + // a line without ":" (an empty line too, by definition) doesn't look like a valid header + // so stop "analyze headers" mode reenter: // put recipients specified on cmdline while (*argv) { -- cgit v1.2.3-55-g6feb From 5c6ba6c56f9653488e1d805e727bb06c39ed23fa Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Mon, 19 Sep 2011 12:18:11 +0200 Subject: mdev: expand --help so that it's actually useful. function old new delta packed_usage 28634 28822 +188 Signed-off-by: Denys Vlasenko --- docs/mdev.txt | 12 +++++-- include/applets.src.h | 1 - util-linux/Config.src | 58 --------------------------------- util-linux/Kbuild.src | 1 - util-linux/mdev.c | 88 ++++++++++++++++++++++++++++++++++++++++++++++----- 5 files changed, 89 insertions(+), 71 deletions(-) diff --git a/docs/mdev.txt b/docs/mdev.txt index 2d03bd8b2..61f93c9df 100644 --- a/docs/mdev.txt +++ b/docs/mdev.txt @@ -51,19 +51,25 @@ device nodes if your system needs something more than the default root/root 660 permissions. The file has the format: - : - or @ : + [-] : +or + @ : +or + $envvar= : For example: - hd[a-z][0-9]* 0:3 660 + hd[a-z][0-9]* 0:3 660 The config file parsing stops at the first matching line. If no line is matched, then the default of 0:0 660 is used. To set your own default, simply create your own total match like so: + .* 1:1 777 You can rename/move device nodes by using the next optional field. + : [=path] + So if you want to place the device node into a subdirectory, make sure the path has a trailing /. If you want to rename the device node, just place the name. hda 0:3 660 =drives/ diff --git a/include/applets.src.h b/include/applets.src.h index a5866d83b..252a060fb 100644 --- a/include/applets.src.h +++ b/include/applets.src.h @@ -239,7 +239,6 @@ IF_MAKEMIME(APPLET(makemime, BB_DIR_BIN, BB_SUID_DROP)) IF_MAN(APPLET(man, BB_DIR_SBIN, BB_SUID_DROP)) IF_MATCHPATHCON(APPLET(matchpathcon, BB_DIR_USR_SBIN, BB_SUID_DROP)) IF_MD5SUM(APPLET_NOEXEC(md5sum, md5_sha1_sum, BB_DIR_USR_BIN, BB_SUID_DROP, md5sum)) -IF_MDEV(APPLET(mdev, BB_DIR_SBIN, BB_SUID_DROP)) IF_MICROCOM(APPLET(microcom, BB_DIR_USR_BIN, BB_SUID_DROP)) IF_MKDIR(APPLET_NOFORK(mkdir, mkdir, BB_DIR_BIN, BB_SUID_DROP, mkdir)) IF_MKFS_VFAT(APPLET_ODDNAME(mkdosfs, mkfs_vfat, BB_DIR_SBIN, BB_SUID_DROP, mkfs_vfat)) diff --git a/util-linux/Config.src b/util-linux/Config.src index bb45705a9..888bc8f3b 100644 --- a/util-linux/Config.src +++ b/util-linux/Config.src @@ -404,64 +404,6 @@ config LSUSB This version uses sysfs (/sys/bus/usb/devices) only. -config MDEV - bool "mdev" - default y - select PLATFORM_LINUX - help - mdev is a mini-udev implementation for dynamically creating device - nodes in the /dev directory. - - For more information, please see docs/mdev.txt - -config FEATURE_MDEV_CONF - bool "Support /etc/mdev.conf" - default y - depends on MDEV - help - Add support for the mdev config file to control ownership and - permissions of the device nodes. - - For more information, please see docs/mdev.txt - -config FEATURE_MDEV_RENAME - bool "Support subdirs/symlinks" - default y - depends on FEATURE_MDEV_CONF - help - Add support for renaming devices and creating symlinks. - - For more information, please see docs/mdev.txt - -config FEATURE_MDEV_RENAME_REGEXP - bool "Support regular expressions substitutions when renaming device" - default y - depends on FEATURE_MDEV_RENAME - help - Add support for regular expressions substitutions when renaming - device. - -config FEATURE_MDEV_EXEC - bool "Support command execution at device addition/removal" - default y - depends on FEATURE_MDEV_CONF - help - This adds support for an optional field to /etc/mdev.conf for - executing commands when devices are created/removed. - - For more information, please see docs/mdev.txt - -config FEATURE_MDEV_LOAD_FIRMWARE - bool "Support loading of firmwares" - default y - depends on MDEV - help - Some devices need to load firmware before they can be usable. - - These devices will request userspace look up the files in - /lib/firmware/ and if it exists, send it to the kernel for - loading into the hardware. - config MKSWAP bool "mkswap" default y diff --git a/util-linux/Kbuild.src b/util-linux/Kbuild.src index c06d911ec..468fc6bc1 100644 --- a/util-linux/Kbuild.src +++ b/util-linux/Kbuild.src @@ -26,7 +26,6 @@ lib-$(CONFIG_IPCS) += ipcs.o lib-$(CONFIG_LOSETUP) += losetup.o lib-$(CONFIG_LSPCI) += lspci.o lib-$(CONFIG_LSUSB) += lsusb.o -lib-$(CONFIG_MDEV) += mdev.o lib-$(CONFIG_MKFS_EXT2) += mkfs_ext2.o lib-$(CONFIG_MKFS_MINIX) += mkfs_minix.o lib-$(CONFIG_MKFS_REISER) += mkfs_reiser.o diff --git a/util-linux/mdev.c b/util-linux/mdev.c index 7cabb1df6..27b35572d 100644 --- a/util-linux/mdev.c +++ b/util-linux/mdev.c @@ -8,19 +8,91 @@ * Licensed under GPLv2, see file LICENSE in this source tree. */ +//config:config MDEV +//config: bool "mdev" +//config: default y +//config: select PLATFORM_LINUX +//config: help +//config: mdev is a mini-udev implementation for dynamically creating device +//config: nodes in the /dev directory. +//config: +//config: For more information, please see docs/mdev.txt +//config: +//config:config FEATURE_MDEV_CONF +//config: bool "Support /etc/mdev.conf" +//config: default y +//config: depends on MDEV +//config: help +//config: Add support for the mdev config file to control ownership and +//config: permissions of the device nodes. +//config: +//config: For more information, please see docs/mdev.txt +//config: +//config:config FEATURE_MDEV_RENAME +//config: bool "Support subdirs/symlinks" +//config: default y +//config: depends on FEATURE_MDEV_CONF +//config: help +//config: Add support for renaming devices and creating symlinks. +//config: +//config: For more information, please see docs/mdev.txt +//config: +//config:config FEATURE_MDEV_RENAME_REGEXP +//config: bool "Support regular expressions substitutions when renaming device" +//config: default y +//config: depends on FEATURE_MDEV_RENAME +//config: help +//config: Add support for regular expressions substitutions when renaming +//config: device. +//config: +//config:config FEATURE_MDEV_EXEC +//config: bool "Support command execution at device addition/removal" +//config: default y +//config: depends on FEATURE_MDEV_CONF +//config: help +//config: This adds support for an optional field to /etc/mdev.conf for +//config: executing commands when devices are created/removed. +//config: +//config: For more information, please see docs/mdev.txt +//config: +//config:config FEATURE_MDEV_LOAD_FIRMWARE +//config: bool "Support loading of firmwares" +//config: default y +//config: depends on MDEV +//config: help +//config: Some devices need to load firmware before they can be usable. +//config: +//config: These devices will request userspace look up the files in +//config: /lib/firmware/ and if it exists, send it to the kernel for +//config: loading into the hardware. + +//applet:IF_MDEV(APPLET(mdev, BB_DIR_SBIN, BB_SUID_DROP)) + +//kbuild:lib-$(CONFIG_MDEV) += mdev.o + //usage:#define mdev_trivial_usage //usage: "[-s]" //usage:#define mdev_full_usage "\n\n" -//usage: " -s Scan /sys and populate /dev during system boot\n" +//usage: "mdev -s is to be run during boot to scan /sys and populate /dev.\n" //usage: "\n" -//usage: "It can be run by kernel as a hotplug helper. To activate it:\n" -//usage: " echo /sbin/mdev > /proc/sys/kernel/hotplug\n" +//usage: "Bare mdev is a kernel hotplug helper. To activate it:\n" +//usage: " echo /sbin/mdev >/proc/sys/kernel/hotplug\n" //usage: IF_FEATURE_MDEV_CONF( +//usage: "\n" //usage: "It uses /etc/mdev.conf with lines\n" -//usage: "[-]DEVNAME UID:GID PERM" -//usage: IF_FEATURE_MDEV_RENAME(" [>|=PATH]") +//usage: " [-]DEVNAME UID:GID PERM" +//usage: IF_FEATURE_MDEV_RENAME(" [>|=PATH]|[!]") //usage: IF_FEATURE_MDEV_EXEC(" [@|$|*PROG]") +//usage: "\n" +//usage: "where DEVNAME is device name regex, @major,minor[-minor2], or\n" +//usage: "environment variable regex. A common use of the latter is\n" +//usage: "to load modules for hotplugged devices:\n" +//usage: " $MODALIAS=.* 0:0 660 @modprobe \"$MODALIAS\"\n" //usage: ) +//usage: "\n" +//usage: "If /dev/mdev.seq file exists, mdev will wait for its value\n" +//usage: "to match $SEQNUM variable. This prevents plug/unplug races.\n" +//usage: "To activate this feature, create empty /dev/mdev.seq at boot." //usage: //usage:#define mdev_notes_usage "" //usage: IF_FEATURE_MDEV_CONFIG( @@ -64,9 +136,9 @@ * If /etc/mdev.conf exists, it may modify /dev/device_name's properties. * /etc/mdev.conf file format: * - * [-][subsystem/]device user:grp mode [>|=path] [@|$|*command args...] - * [-]@maj,min[-min2] user:grp mode [>|=path] [@|$|*command args...] - * [-]$envvar=val user:grp mode [>|=path] [@|$|*command args...] + * [-][subsystem/]device user:grp mode [>|=path]|[!] [@|$|*command args...] + * [-]@maj,min[-min2] user:grp mode [>|=path]|[!] [@|$|*command args...] + * [-]$envvar=val user:grp mode [>|=path]|[!] [@|$|*command args...] * * Leading minus in 1st field means "don't stop on this line", otherwise * search is stopped after the matching line is encountered. -- cgit v1.2.3-55-g6feb From 16714245f9a16ce3725aab079aea7b0d28c6b32f Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Wed, 21 Sep 2011 01:59:15 +0200 Subject: add INIT_G()'s. No code changes. Signed-off-by: Denys Vlasenko --- coreutils/du.c | 3 +++ coreutils/expr.c | 3 +++ coreutils/tail.c | 3 +++ include/libbb.h | 9 ++++++--- miscutils/hdparm.c | 3 +++ networking/zcip.c | 2 ++ procps/top.c | 2 +- runit/runsvdir.c | 3 +-- util-linux/mdev.c | 5 +++++ util-linux/mount.c | 3 +++ util-linux/swaponoff.c | 3 +++ 11 files changed, 33 insertions(+), 6 deletions(-) diff --git a/coreutils/du.c b/coreutils/du.c index b8bbe3d9e..34a549f02 100644 --- a/coreutils/du.c +++ b/coreutils/du.c @@ -88,6 +88,7 @@ struct globals { dev_t dir_dev; } FIX_ALIASING; #define G (*(struct globals*)&bb_common_bufsiz1) +#define INIT_G() do { } while (0) static void print(unsigned long size, const char *filename) @@ -193,6 +194,8 @@ int du_main(int argc UNUSED_PARAM, char **argv) int slink_depth_save; unsigned opt; + INIT_G(); + #if ENABLE_FEATURE_HUMAN_READABLE IF_FEATURE_DU_DEFAULT_BLOCKSIZE_1K(G.disp_hr = 1024;) IF_NOT_FEATURE_DU_DEFAULT_BLOCKSIZE_1K(G.disp_hr = 512;) diff --git a/coreutils/expr.c b/coreutils/expr.c index 24e75b556..c986f9327 100644 --- a/coreutils/expr.c +++ b/coreutils/expr.c @@ -100,6 +100,7 @@ struct globals { char **args; } FIX_ALIASING; #define G (*(struct globals*)&bb_common_bufsiz1) +#define INIT_G() do { } while (0) /* forward declarations */ static VALUE *eval(void); @@ -519,6 +520,8 @@ int expr_main(int argc UNUSED_PARAM, char **argv) { VALUE *v; + INIT_G(); + xfunc_error_retval = 2; /* coreutils compat */ G.args = argv + 1; if (*G.args == NULL) { diff --git a/coreutils/tail.c b/coreutils/tail.c index 43cecbd97..b376ec863 100644 --- a/coreutils/tail.c +++ b/coreutils/tail.c @@ -62,6 +62,7 @@ struct globals { bool exitcode; } FIX_ALIASING; #define G (*(struct globals*)&bb_common_bufsiz1) +#define INIT_G() do { } while (0) static void tail_xprint_header(const char *fmt, const char *filename) { @@ -120,6 +121,8 @@ int tail_main(int argc, char **argv) int *fds; const char *fmt; + INIT_G(); + #if ENABLE_INCLUDE_SUSv2 || ENABLE_FEATURE_FANCY_TAIL /* Allow legacy syntax of an initial numeric option without -n. */ if (argv[1] && (argv[1][0] == '+' || argv[1][0] == '-') diff --git a/include/libbb.h b/include/libbb.h index feae85259..f79b69365 100644 --- a/include/libbb.h +++ b/include/libbb.h @@ -684,10 +684,13 @@ void *malloc_or_warn(size_t size) FAST_FUNC RETURNS_MALLOC; void *xmalloc(size_t size) FAST_FUNC RETURNS_MALLOC; void *xzalloc(size_t size) FAST_FUNC RETURNS_MALLOC; void *xrealloc(void *old, size_t size) FAST_FUNC; -/* After xrealloc_vector(v, 4, idx) it's ok to use +/* After v = xrealloc_vector(v, SHIFT, idx) it's ok to use * at least v[idx] and v[idx+1], for all idx values. - * shift specifies how many new elements are added (1: 2, 2: 4... 8: 256...) - * when all elements are used up. New elements are zeroed out. */ + * SHIFT specifies how many new elements are added (1:2, 2:4, ..., 8:256...) + * when all elements are used up. New elements are zeroed out. + * xrealloc_vector(v, SHIFT, idx) *MUST* be called with consecutive IDXs - + * skipping an index is a bad bug - it may miss a realloc! + */ #define xrealloc_vector(vector, shift, idx) \ xrealloc_vector_helper((vector), (sizeof((vector)[0]) << 8) + (shift), (idx)) void* xrealloc_vector_helper(void *vector, unsigned sizeof_and_shift, int idx) FAST_FUNC; diff --git a/miscutils/hdparm.c b/miscutils/hdparm.c index f30e7dec6..a97f3e7b5 100644 --- a/miscutils/hdparm.c +++ b/miscutils/hdparm.c @@ -433,6 +433,7 @@ struct BUG_G_too_big { #define hwif_data (G.hwif_data ) #define hwif_ctrl (G.hwif_ctrl ) #define hwif_irq (G.hwif_irq ) +#define INIT_G() do { } while (0) /* Busybox messages and functions */ @@ -2059,6 +2060,8 @@ int hdparm_main(int argc, char **argv) int c; int flagcount = 0; + INIT_G(); + while ((c = getopt(argc, argv, hdparm_options)) >= 0) { flagcount++; IF_FEATURE_HDPARM_GET_IDENTITY(get_IDentity |= (c == 'I')); diff --git a/networking/zcip.c b/networking/zcip.c index 8a35eca5d..7314ff8db 100644 --- a/networking/zcip.c +++ b/networking/zcip.c @@ -91,6 +91,7 @@ struct globals { #define G (*(struct globals*)&bb_common_bufsiz1) #define saddr (G.saddr ) #define eth_addr (G.eth_addr) +#define INIT_G() do { } while (0) /** @@ -223,6 +224,7 @@ int zcip_main(int argc UNUSED_PARAM, char **argv) #define verbose (L.verbose ) memset(&L, 0, sizeof(L)); + INIT_G(); #define FOREGROUND (opts & 1) #define QUIT (opts & 2) diff --git a/procps/top.c b/procps/top.c index 011bbf183..15eb624cc 100644 --- a/procps/top.c +++ b/procps/top.c @@ -126,7 +126,6 @@ struct BUG_bad_size { char BUG_G_too_big[sizeof(G) <= COMMON_BUFSIZE ? 1 : -1]; char BUG_line_buf_too_small[LINE_BUF_SIZE > 80 ? 1 : -1]; }; -#define INIT_G() do { } while (0) #define top (G.top ) #define ntop (G.ntop ) #define sort_field (G.sort_field ) @@ -143,6 +142,7 @@ struct BUG_bad_size { #define num_cpus (G.num_cpus ) #define total_pcpu (G.total_pcpu ) #define line_buf (G.line_buf ) +#define INIT_G() do { } while (0) enum { OPT_d = (1 << 0), diff --git a/runit/runsvdir.c b/runit/runsvdir.c index 9495a2a4f..32526cf4c 100644 --- a/runit/runsvdir.c +++ b/runit/runsvdir.c @@ -75,8 +75,7 @@ struct globals { #define logpipe (G.logpipe ) #define pfd (G.pfd ) #define stamplog (G.stamplog ) -#define INIT_G() do { \ -} while (0) +#define INIT_G() do { } while (0) static void fatal2_cannot(const char *m1, const char *m2) { diff --git a/util-linux/mdev.c b/util-linux/mdev.c index 27b35572d..c56741b08 100644 --- a/util-linux/mdev.c +++ b/util-linux/mdev.c @@ -173,6 +173,8 @@ struct globals { char *subsystem; } FIX_ALIASING; #define G (*(struct globals*)&bb_common_bufsiz1) +#define INIT_G() do { } while (0) + /* Prevent infinite loops in /sys symlinks */ #define MAX_SYSFS_DEPTH 3 @@ -180,6 +182,7 @@ struct globals { /* We use additional 64+ bytes in make_device() */ #define SCRATCH_SIZE 80 + /* Builds an alias path. * This function potentionally reallocates the alias parameter. * Only used for ENABLE_FEATURE_MDEV_RENAME @@ -613,6 +616,8 @@ int mdev_main(int argc UNUSED_PARAM, char **argv) { RESERVE_CONFIG_BUFFER(temp, PATH_MAX + SCRATCH_SIZE); + INIT_G(); + /* We can be called as hotplug helper */ /* Kernel cannot provide suitable stdio fds for us, do it ourself */ bb_sanitize_stdio(); diff --git a/util-linux/mount.c b/util-linux/mount.c index b51ab1782..56276ef01 100644 --- a/util-linux/mount.c +++ b/util-linux/mount.c @@ -339,6 +339,7 @@ enum { GETMNTENT_BUFSIZE = COMMON_BUFSIZE - offsetof(struct globals, getmntent_b #endif #define fslist (G.fslist ) #define getmntent_buf (G.getmntent_buf ) +#define INIT_G() do { } while (0) #if ENABLE_FEATURE_MTAB_SUPPORT /* @@ -1944,6 +1945,8 @@ int mount_main(int argc UNUSED_PARAM, char **argv) IF_DESKTOP(int nonroot = ) sanitize_env_if_suid(); + INIT_G(); + // Parse long options, like --bind and --move. Note that -o option // and --option are synonymous. Yes, this means --remount,rw works. for (i = j = 1; argv[i]; i++) { diff --git a/util-linux/swaponoff.c b/util-linux/swaponoff.c index e53e24c71..b3057b309 100644 --- a/util-linux/swaponoff.c +++ b/util-linux/swaponoff.c @@ -48,6 +48,7 @@ struct globals { #else #define g_flags 0 #endif +#define INIT_G() do { } while (0) static int swap_enable_disable(char *device) { @@ -111,6 +112,8 @@ int swap_on_off_main(int argc UNUSED_PARAM, char **argv) { int ret; + INIT_G(); + #if !ENABLE_FEATURE_SWAPON_PRI ret = getopt32(argv, "a"); #else -- cgit v1.2.3-55-g6feb From 3eccd7ecbe6f34e60cbc04ada9abb87313fbfc00 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Thu, 22 Sep 2011 03:46:30 +0200 Subject: mdev: don't reparse rules on -s function old new delta make_device 1648 1843 +195 clean_up_cur_rule - 61 +61 make_default_cur_rule - 41 +41 mdev_main 690 712 +22 ------------------------------------------------------------------------------ (add/remove: 2/0 grow/shrink: 2/0 up/down: 319/0) Total: 319 bytes Signed-off-by: Denys Vlasenko --- util-linux/mdev.c | 558 +++++++++++++++++++++++++++++++++--------------------- 1 file changed, 341 insertions(+), 217 deletions(-) diff --git a/util-linux/mdev.c b/util-linux/mdev.c index c56741b08..0b3e06cf1 100644 --- a/util-linux/mdev.c +++ b/util-linux/mdev.c @@ -168,9 +168,29 @@ * This happens regardless of /sys/class/.../dev existence. */ +struct rule { + bool keep_matching; + bool regex_compiled; + bool regex_has_slash; + mode_t mode; + int maj, min0, min1; + struct bb_uidgid_t ugid; + char *envvar; + char *ren_mov; + IF_FEATURE_MDEV_EXEC(char *r_cmd;) + regex_t match; +}; + struct globals { int root_major, root_minor; char *subsystem; +#if ENABLE_FEATURE_MDEV_CONF + const char *filename; + parser_t *parser; + struct rule **rule_vec; + unsigned rule_idx; +#endif + struct rule cur_rule; } FIX_ALIASING; #define G (*(struct globals*)&bb_common_bufsiz1) #define INIT_G() do { } while (0) @@ -182,6 +202,164 @@ struct globals { /* We use additional 64+ bytes in make_device() */ #define SCRATCH_SIZE 80 +#if 0 +# define dbg(...) bb_error_msg(__VA_ARGS__) +#else +# define dbg(...) ((void)0) +#endif + + +#if ENABLE_FEATURE_MDEV_CONF + +static void make_default_cur_rule(void) +{ + memset(&G.cur_rule, 0, sizeof(G.cur_rule)); + G.cur_rule.maj = -1; /* "not a @major,minor rule" */ + G.cur_rule.mode = 0660; +} + +static void clean_up_cur_rule(void) +{ + free(G.cur_rule.envvar); + if (G.cur_rule.regex_compiled) + regfree(&G.cur_rule.match); + free(G.cur_rule.ren_mov); + IF_FEATURE_MDEV_EXEC(free(G.cur_rule.r_cmd);) + make_default_cur_rule(); +} + +static void parse_next_rule(void) +{ + /* Note: on entry, G.cur_rule is set to default */ + while (1) { + char *tokens[4]; + char *val; + + if (!config_read(G.parser, tokens, 4, 3, "# \t", PARSE_NORMAL)) + break; + + /* Fields: [-]regex uid:gid mode [alias] [cmd] */ + dbg("token1:'%s'", tokens[1]); + + /* 1st field */ + val = tokens[0]; + G.cur_rule.keep_matching = ('-' == val[0]); + val += G.cur_rule.keep_matching; /* swallow leading dash */ + if (val[0] == '@') { + /* @major,minor[-minor2] */ + /* (useful when name is ambiguous: + * "/sys/class/usb/lp0" and + * "/sys/class/printer/lp0") + */ + int sc = sscanf(val, "@%u,%u-%u", &G.cur_rule.maj, &G.cur_rule.min0, &G.cur_rule.min1); + if (sc < 2 || G.cur_rule.maj < 0) { + bb_error_msg("bad @maj,min on line %d", G.parser->lineno); + goto next_rule; + } + if (sc == 2) + G.cur_rule.min1 = G.cur_rule.min0; + } else { + if (val[0] == '$') { + char *eq = strchr(++val, '='); + if (!eq) { + bb_error_msg("bad $envvar=regex on line %d", G.parser->lineno); + goto next_rule; + } + G.cur_rule.envvar = xstrndup(val, eq - val); + val = eq + 1; + } + xregcomp(&G.cur_rule.match, val, REG_EXTENDED); + G.cur_rule.regex_compiled = 1; + G.cur_rule.regex_has_slash = (strchr(val, '/') != NULL); + } + + /* 2nd field: uid:gid - device ownership */ + if (get_uidgid(&G.cur_rule.ugid, tokens[1], /*allow_numeric:*/ 1) == 0) { + bb_error_msg("unknown user/group '%s' on line %d", tokens[1], G.parser->lineno); + goto next_rule; + } + + /* 3rd field: mode - device permissions */ + bb_parse_mode(tokens[2], &G.cur_rule.mode); + + /* 4th field (opt): ">|=alias" or "!" to not create the node */ + val = tokens[3]; + if (ENABLE_FEATURE_MDEV_RENAME && val && strchr(">=!", val[0])) { + char *s = skip_non_whitespace(val); + G.cur_rule.ren_mov = xstrndup(val, s - val); + val = skip_whitespace(s); + } + + if (ENABLE_FEATURE_MDEV_EXEC && val && val[0]) { + const char *s = "$@*"; + const char *s2 = strchr(s, val[0]); + if (!s2) { + bb_error_msg("bad line %u", G.parser->lineno); + goto next_rule; + } + IF_FEATURE_MDEV_EXEC(G.cur_rule.r_cmd = xstrdup(val);) + } + + return; + next_rule: + clean_up_cur_rule(); + } /* while (config_read) */ + + dbg("config_close(G.parser)"); + config_close(G.parser); + G.parser = NULL; + + return; +} + +/* If mdev -s, we remember rules in G.rule_vec[]. + * Otherwise, there is no point in doing it, and we just + * save only one parsed rule in G.cur_rule. + */ +static const struct rule *next_rule(void) +{ + struct rule *rule; + + /* Open conf file if we didn't do it yet */ + if (!G.parser && G.filename) { + dbg("config_open('%s')", G.filename); + G.parser = config_open2(G.filename, fopen_for_read); + G.filename = NULL; + } + + if (G.rule_vec) { + /* mdev -s */ + /* Do we have rule parsed already? */ + if (G.rule_vec[G.rule_idx]) { + dbg("< G.rule_vec[G.rule_idx:%d]=%p", G.rule_idx, G.rule_vec[G.rule_idx]); + return G.rule_vec[G.rule_idx++]; + } + make_default_cur_rule(); + } else { + /* not mdev -s */ + clean_up_cur_rule(); + } + + /* Parse one more rule if file isn't fully read */ + rule = &G.cur_rule; + if (G.parser) { + parse_next_rule(); + if (G.rule_vec) { /* mdev -s */ + rule = memcpy(xmalloc(sizeof(G.cur_rule)), &G.cur_rule, sizeof(G.cur_rule)); + G.rule_vec = xrealloc_vector(G.rule_vec, 4, G.rule_idx); + G.rule_vec[G.rule_idx++] = rule; + dbg("> G.rule_vec[G.rule_idx:%d]=%p", G.rule_idx, G.rule_vec[G.rule_idx]); + } + } + + return rule; +} + +#else + +# define next_rule() (&G.cur_rule) + +#endif /* Builds an alias path. * This function potentionally reallocates the alias parameter. @@ -218,8 +396,8 @@ static void make_device(char *path, int delete) { char *device_name, *subsystem_slash_devname; int major, minor, type, len; - mode_t mode; - parser_t *parser; + + dbg("%s('%s', delete:%d)", __func__, path, delete); /* Try to read major/minor string. Note that the kernel puts \n after * the data, so we don't need to worry about null terminating the string @@ -272,246 +450,184 @@ static void make_device(char *path, int delete) path = subsystem_slash_devname; } - /* If we have config file, look up user settings */ - if (ENABLE_FEATURE_MDEV_CONF) - parser = config_open2("/etc/mdev.conf", fopen_for_read); - - do { - int keep_matching; - struct bb_uidgid_t ugid; - char *tokens[4]; - char *command = NULL; - char *alias = NULL; +#if ENABLE_FEATURE_MDEV_CONF + G.rule_idx = 0; /* restart from the beginning (think mdev -s) */ +#endif + for (;;) { + const char *str_to_match; + regmatch_t off[1 + 9 * ENABLE_FEATURE_MDEV_RENAME_REGEXP]; + char *command; + char *alias; char aliaslink = aliaslink; /* for compiler */ + const char *node_name; + const struct rule *rule; - /* Defaults in case we won't match any line */ - ugid.uid = ugid.gid = 0; - keep_matching = 0; - mode = 0660; - - if (ENABLE_FEATURE_MDEV_CONF - && config_read(parser, tokens, 4, 3, "# \t", PARSE_NORMAL) - ) { - char *val; - char *str_to_match; - regmatch_t off[1 + 9 * ENABLE_FEATURE_MDEV_RENAME_REGEXP]; - - val = tokens[0]; - keep_matching = ('-' == val[0]); - val += keep_matching; /* swallow leading dash */ - - /* Match against either "subsystem/device_name" - * or "device_name" alone */ - str_to_match = strchr(val, '/') ? path : device_name; - - /* Fields: regex uid:gid mode [alias] [cmd] */ - - if (val[0] == '@') { - /* @major,minor[-minor2] */ - /* (useful when name is ambiguous: - * "/sys/class/usb/lp0" and - * "/sys/class/printer/lp0") */ - int cmaj, cmin0, cmin1, sc; - if (major < 0) - continue; /* no dev, no match */ - sc = sscanf(val, "@%u,%u-%u", &cmaj, &cmin0, &cmin1); - if (sc < 1 - || major != cmaj - || (sc == 2 && minor != cmin0) - || (sc == 3 && (minor < cmin0 || minor > cmin1)) - ) { - continue; /* this line doesn't match */ - } - goto line_matches; - } - if (val[0] == '$') { - /* regex to match an environment variable */ - char *eq = strchr(++val, '='); - if (!eq) - continue; - *eq = '\0'; - str_to_match = getenv(val); - if (!str_to_match) - continue; - str_to_match -= strlen(val) + 1; - *eq = '='; + str_to_match = ""; + + rule = next_rule(); + +#if ENABLE_FEATURE_MDEV_CONF + if (rule->maj >= 0) { /* @maj,min rule */ + if (major != rule->maj) + continue; + if (minor < rule->min0 || minor > rule->min1) + continue; + memset(off, 0, sizeof(off)); + goto rule_matches; + } + if (rule->envvar) { /* $envvar=regex rule */ + str_to_match = getenv(rule->envvar); + dbg("getenv('%s'):'%s'", rule->envvar, str_to_match); + if (!str_to_match) + continue; + } else { + /* regex to match [subsystem/]device_name */ + str_to_match = (rule->regex_has_slash ? path : device_name); + } + + if (rule->regex_compiled) { + int regex_match = regexec(&rule->match, str_to_match, ARRAY_SIZE(off), off, 0); + dbg("regex_match for '%s':%d", str_to_match, regex_match); + //bb_error_msg("matches:"); + //for (int i = 0; i < ARRAY_SIZE(off); i++) { + // if (off[i].rm_so < 0) continue; + // bb_error_msg("match %d: '%.*s'\n", i, + // (int)(off[i].rm_eo - off[i].rm_so), + // device_name + off[i].rm_so); + //} + + if (regex_match != 0 + /* regexec returns whole pattern as "range" 0 */ + || off[0].rm_so != 0 + || (int)off[0].rm_eo != (int)strlen(str_to_match) + ) { + continue; /* this rule doesn't match */ } - /* else: regex to match [subsystem/]device_name */ - - { - regex_t match; - int result; - - xregcomp(&match, val, REG_EXTENDED); - result = regexec(&match, str_to_match, ARRAY_SIZE(off), off, 0); - regfree(&match); - //bb_error_msg("matches:"); - //for (int i = 0; i < ARRAY_SIZE(off); i++) { - // if (off[i].rm_so < 0) continue; - // bb_error_msg("match %d: '%.*s'\n", i, - // (int)(off[i].rm_eo - off[i].rm_so), - // device_name + off[i].rm_so); - //} - - /* If no match, skip rest of line */ - /* (regexec returns whole pattern as "range" 0) */ - if (result - || off[0].rm_so - || ((int)off[0].rm_eo != (int)strlen(str_to_match)) - ) { - continue; /* this line doesn't match */ - } + } + /* else: it's final implicit "match-all" rule */ +#endif + + rule_matches: + dbg("rule matched"); + + /* Build alias name */ + alias = NULL; + if (ENABLE_FEATURE_MDEV_RENAME && rule->ren_mov) { + aliaslink = rule->ren_mov[0]; + if (aliaslink == '!') { + /* "!": suppress node creation/deletion */ + major = -2; } - line_matches: - /* This line matches. Stop parsing after parsing - * the rest the line unless keep_matching == 1 */ - - /* 2nd field: uid:gid - device ownership */ - if (get_uidgid(&ugid, tokens[1], /*allow_numeric:*/ 1) == 0) - bb_error_msg("unknown user/group %s on line %d", tokens[1], parser->lineno); - - /* 3rd field: mode - device permissions */ - bb_parse_mode(tokens[2], &mode); - - val = tokens[3]; - /* 4th field (opt): ">|=alias" or "!" to not create the node */ - - if (ENABLE_FEATURE_MDEV_RENAME && val) { - char *a, *s, *st; - - a = val; - s = strchrnul(val, ' '); - st = strchrnul(val, '\t'); - if (st < s) - s = st; - st = (s[0] && s[1]) ? s+1 : NULL; - - aliaslink = a[0]; - if (aliaslink == '!' && s == a+1) { - val = st; - /* "!": suppress node creation/deletion */ - major = -2; - } - else if (aliaslink == '>' || aliaslink == '=') { - val = st; - s[0] = '\0'; - if (ENABLE_FEATURE_MDEV_RENAME_REGEXP) { - char *p; - unsigned i, n; - - /* substitute %1..9 with off[1..9], if any */ - n = 0; - s = a; - while (*s) - if (*s++ == '%') - n++; - - p = alias = xzalloc(strlen(a) + n * strlen(str_to_match)); - s = a + 1; - while (*s) { - *p = *s; - if ('%' == *s) { - i = (s[1] - '0'); - if (i <= 9 && off[i].rm_so >= 0) { - n = off[i].rm_eo - off[i].rm_so; - strncpy(p, str_to_match + off[i].rm_so, n); - p += n - 1; - s++; - } + else if (aliaslink == '>' || aliaslink == '=') { + if (ENABLE_FEATURE_MDEV_RENAME_REGEXP) { + char *s; + char *p; + unsigned n; + + /* substitute %1..9 with off[1..9], if any */ + n = 0; + s = rule->ren_mov; + while (*s) + if (*s++ == '%') + n++; + + p = alias = xzalloc(strlen(rule->ren_mov) + n * strlen(str_to_match)); + s = rule->ren_mov + 1; + while (*s) { + *p = *s; + if ('%' == *s) { + unsigned i = (s[1] - '0'); + if (i <= 9 && off[i].rm_so >= 0) { + n = off[i].rm_eo - off[i].rm_so; + strncpy(p, str_to_match + off[i].rm_so, n); + p += n - 1; + s++; } - p++; - s++; } - } else { - alias = xstrdup(a + 1); + p++; + s++; } + } else { + alias = xstrdup(rule->ren_mov + 1); } } + } + dbg("alias:'%s'", alias); - if (ENABLE_FEATURE_MDEV_EXEC && val) { - const char *s = "$@*"; - const char *s2 = strchr(s, val[0]); - - if (!s2) { - bb_error_msg("bad line %u", parser->lineno); - if (ENABLE_FEATURE_MDEV_RENAME) - free(alias); - continue; - } + command = NULL; + IF_FEATURE_MDEV_EXEC(command = rule->r_cmd;) + if (command) { + const char *s = "$@*"; + const char *s2 = strchr(s, command[0]); - /* Are we running this command now? - * Run $cmd on delete, @cmd on create, *cmd on both + /* Are we running this command now? + * Run $cmd on delete, @cmd on create, *cmd on both + */ + if (s2 - s != delete) { + /* We are here if: '*', + * or: '@' and delete = 0, + * or: '$' and delete = 1 */ - if (s2 - s != delete) { - /* We are here if: '*', - * or: '@' and delete = 0, - * or: '$' and delete = 1 - */ - command = xstrdup(val + 1); - } + command++; + } else { + command = NULL; } } - - /* End of field parsing */ + dbg("command:'%s'", command); /* "Execute" the line we found */ - { - const char *node_name; - - node_name = device_name; - if (ENABLE_FEATURE_MDEV_RENAME && alias) - node_name = alias = build_alias(alias, device_name); - - if (!delete && major >= 0) { - if (mknod(node_name, mode | type, makedev(major, minor)) && errno != EEXIST) - bb_perror_msg("can't create '%s'", node_name); - if (major == G.root_major && minor == G.root_minor) - symlink(node_name, "root"); - if (ENABLE_FEATURE_MDEV_CONF) { - chmod(node_name, mode); - chown(node_name, ugid.uid, ugid.gid); - } - if (ENABLE_FEATURE_MDEV_RENAME && alias) { - if (aliaslink == '>') - symlink(node_name, device_name); - } - } + node_name = device_name; + if (ENABLE_FEATURE_MDEV_RENAME && alias) { + node_name = alias = build_alias(alias, device_name); + dbg("alias2:'%s'", alias); + } - if (ENABLE_FEATURE_MDEV_EXEC && command) { - /* setenv will leak memory, use putenv/unsetenv/free */ - char *s = xasprintf("%s=%s", "MDEV", node_name); - char *s1 = xasprintf("%s=%s", "SUBSYSTEM", G.subsystem); - putenv(s); - putenv(s1); - if (system(command) == -1) - bb_perror_msg("can't run '%s'", command); - bb_unsetenv_and_free(s1); - bb_unsetenv_and_free(s); - free(command); + if (!delete && major >= 0) { + dbg("mknod('%s',%o,(%d,%d))", node_name, rule->mode | type, major, minor); + if (mknod(node_name, rule->mode | type, makedev(major, minor)) && errno != EEXIST) + bb_perror_msg("can't create '%s'", node_name); + if (major == G.root_major && minor == G.root_minor) + symlink(node_name, "root"); + if (ENABLE_FEATURE_MDEV_CONF) { + chmod(node_name, rule->mode); + chown(node_name, rule->ugid.uid, rule->ugid.gid); } - - if (delete && major >= -1) { - if (ENABLE_FEATURE_MDEV_RENAME && alias) { - if (aliaslink == '>') - unlink(device_name); - } - unlink(node_name); + if (ENABLE_FEATURE_MDEV_RENAME && alias) { + if (aliaslink == '>') + symlink(node_name, device_name); } + } - if (ENABLE_FEATURE_MDEV_RENAME) - free(alias); + if (ENABLE_FEATURE_MDEV_EXEC && command) { + /* setenv will leak memory, use putenv/unsetenv/free */ + char *s = xasprintf("%s=%s", "MDEV", node_name); + char *s1 = xasprintf("%s=%s", "SUBSYSTEM", G.subsystem); + putenv(s); + putenv(s1); + if (system(command) == -1) + bb_perror_msg("can't run '%s'", command); + bb_unsetenv_and_free(s1); + bb_unsetenv_and_free(s); } + if (delete && major >= -1) { + if (ENABLE_FEATURE_MDEV_RENAME && alias) { + if (aliaslink == '>') + unlink(device_name); + } + unlink(node_name); + } + + if (ENABLE_FEATURE_MDEV_RENAME) + free(alias); + /* We found matching line. - * Stop unless it was prefixed with '-' */ - if (ENABLE_FEATURE_MDEV_CONF && !keep_matching) + * Stop unless it was prefixed with '-' + */ + if (!ENABLE_FEATURE_MDEV_CONF || !rule->keep_matching) break; + } /* for (;;) */ - /* end of "while line is read from /etc/mdev.conf" */ - } while (ENABLE_FEATURE_MDEV_CONF); - - if (ENABLE_FEATURE_MDEV_CONF) - config_close(parser); free(subsystem_slash_devname); } @@ -618,6 +734,10 @@ int mdev_main(int argc UNUSED_PARAM, char **argv) INIT_G(); +#if ENABLE_FEATURE_MDEV_CONF + G.filename = "/etc/mdev.conf"; +#endif + /* We can be called as hotplug helper */ /* Kernel cannot provide suitable stdio fds for us, do it ourself */ bb_sanitize_stdio(); @@ -633,6 +753,10 @@ int mdev_main(int argc UNUSED_PARAM, char **argv) */ struct stat st; +#if ENABLE_FEATURE_MDEV_CONF + /* Same as xrealloc_vector(NULL, 4, 0): */ + G.rule_vec = xzalloc((1 << 4) * sizeof(*G.rule_vec)); +#endif xstat("/", &st); G.root_major = major(st.st_dev); G.root_minor = minor(st.st_dev); -- cgit v1.2.3-55-g6feb From 45f0a1156d3f3f5be76098f2acb524c19409fa52 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Thu, 22 Sep 2011 04:55:47 +0200 Subject: mdev: trim overlong comments. No code changes Signed-off-by: Denys Vlasenko --- util-linux/mdev.c | 31 +------------------------------ 1 file changed, 1 insertion(+), 30 deletions(-) diff --git a/util-linux/mdev.c b/util-linux/mdev.c index 0b3e06cf1..c6be1b872 100644 --- a/util-linux/mdev.c +++ b/util-linux/mdev.c @@ -93,26 +93,6 @@ //usage: "If /dev/mdev.seq file exists, mdev will wait for its value\n" //usage: "to match $SEQNUM variable. This prevents plug/unplug races.\n" //usage: "To activate this feature, create empty /dev/mdev.seq at boot." -//usage: -//usage:#define mdev_notes_usage "" -//usage: IF_FEATURE_MDEV_CONFIG( -//usage: "The mdev config file contains lines that look like:\n" -//usage: " hd[a-z][0-9]* 0:3 660\n\n" -//usage: "That's device name (with regex match), uid:gid, and permissions.\n\n" -//usage: IF_FEATURE_MDEV_EXEC( -//usage: "Optionally, that can be followed (on the same line) by a special character\n" -//usage: "and a command line to run after creating/before deleting the corresponding\n" -//usage: "device(s). The environment variable $MDEV indicates the active device node\n" -//usage: "(which is useful if it's a regex match). For example:\n\n" -//usage: " hdc root:cdrom 660 *ln -s $MDEV cdrom\n\n" -//usage: "The special characters are @ (run after creating), $ (run before deleting),\n" -//usage: "and * (run both after creating and before deleting). The commands run in\n" -//usage: "the /dev directory, and use system() which calls /bin/sh.\n\n" -//usage: ) -//usage: "Config file parsing stops on the first matching line. If no config\n" -//usage: "entry is matched, devices are created with default 0:0 660. (Make\n" -//usage: "the last line match .* to override this.)\n\n" -//usage: ) #include "libbb.h" #include "xregex.h" @@ -134,20 +114,11 @@ * (todo: explain "delete" and $FIRMWARE) * * If /etc/mdev.conf exists, it may modify /dev/device_name's properties. - * /etc/mdev.conf file format: - * - * [-][subsystem/]device user:grp mode [>|=path]|[!] [@|$|*command args...] - * [-]@maj,min[-min2] user:grp mode [>|=path]|[!] [@|$|*command args...] - * [-]$envvar=val user:grp mode [>|=path]|[!] [@|$|*command args...] * * Leading minus in 1st field means "don't stop on this line", otherwise * search is stopped after the matching line is encountered. * - * The device name or "subsystem/device" combo is matched against 1st field - * (which is a regex), or maj,min is matched against 1st field, - * or specified environment variable (as regex) is matched against 1st field. - * - * $envvar=val format is useful for loading modules for hot-plugged devices + * $envvar=regex format is useful for loading modules for hot-plugged devices * which do not have driver loaded yet. In this case /sys/class/.../dev * does not exist, but $MODALIAS is set to needed module's name * (actually, an alias to it) by kernel. This rule instructs mdev -- cgit v1.2.3-55-g6feb From d184a728cf5c270f1653f60bc0b6b83290127121 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Thu, 22 Sep 2011 12:45:14 +0200 Subject: rename archive.h to bb_archive.h. no code changes Signed-off-by: Denys Vlasenko --- archival/ar.c | 2 +- archival/bbunzip.c | 2 +- archival/bzip2.c | 2 +- archival/cpio.c | 2 +- archival/dpkg.c | 2 +- archival/dpkg_deb.c | 2 +- archival/gzip.c | 2 +- archival/libarchive/data_align.c | 2 +- archival/libarchive/data_extract_all.c | 2 +- archival/libarchive/data_extract_to_command.c | 2 +- archival/libarchive/data_extract_to_stdout.c | 2 +- archival/libarchive/data_skip.c | 2 +- archival/libarchive/decompress_bunzip2.c | 2 +- archival/libarchive/decompress_uncompress.c | 2 +- archival/libarchive/decompress_unlzma.c | 2 +- archival/libarchive/decompress_unxz.c | 2 +- archival/libarchive/decompress_unzip.c | 2 +- archival/libarchive/filter_accept_all.c | 2 +- archival/libarchive/filter_accept_list.c | 2 +- archival/libarchive/filter_accept_list_reassign.c | 2 +- archival/libarchive/filter_accept_reject_list.c | 2 +- archival/libarchive/find_list_entry.c | 2 +- archival/libarchive/get_header_ar.c | 2 +- archival/libarchive/get_header_cpio.c | 2 +- archival/libarchive/get_header_tar.c | 2 +- archival/libarchive/get_header_tar_bz2.c | 2 +- archival/libarchive/get_header_tar_gz.c | 2 +- archival/libarchive/get_header_tar_lzma.c | 2 +- archival/libarchive/header_list.c | 2 +- archival/libarchive/header_skip.c | 2 +- archival/libarchive/header_verbose_list.c | 2 +- archival/libarchive/init_handle.c | 2 +- archival/libarchive/open_transformer.c | 2 +- archival/libarchive/seek_by_jump.c | 2 +- archival/libarchive/seek_by_read.c | 2 +- archival/libarchive/unpack_ar_archive.c | 2 +- archival/lzop.c | 2 +- archival/rpm.c | 2 +- archival/rpm2cpio.c | 2 +- archival/tar.c | 2 +- archival/unzip.c | 2 +- include/archive.h | 241 ---------------------- include/bb_archive.h | 241 ++++++++++++++++++++++ libbb/appletlib.c | 2 +- libbb/read_printf.c | 2 +- miscutils/bbconfig.c | 2 +- procps/smemcap.c | 2 +- 47 files changed, 286 insertions(+), 286 deletions(-) delete mode 100644 include/archive.h create mode 100644 include/bb_archive.h diff --git a/archival/ar.c b/archival/ar.c index acad20ff2..88236e878 100644 --- a/archival/ar.c +++ b/archival/ar.c @@ -28,7 +28,7 @@ //usage: "\n -v Verbose" #include "libbb.h" -#include "archive.h" +#include "bb_archive.h" #include "ar.h" #if ENABLE_FEATURE_AR_CREATE diff --git a/archival/bbunzip.c b/archival/bbunzip.c index bb1ec0e37..9c1a73780 100644 --- a/archival/bbunzip.c +++ b/archival/bbunzip.c @@ -5,7 +5,7 @@ * Licensed under GPLv2 or later, see file LICENSE in this source tree. */ #include "libbb.h" -#include "archive.h" +#include "bb_archive.h" enum { OPT_STDOUT = 1 << 0, diff --git a/archival/bzip2.c b/archival/bzip2.c index 3dde970f1..0716fa89b 100644 --- a/archival/bzip2.c +++ b/archival/bzip2.c @@ -17,7 +17,7 @@ //usage: "\n -f Force" #include "libbb.h" -#include "archive.h" +#include "bb_archive.h" #define CONFIG_BZIP2_FAST 1 diff --git a/archival/cpio.c b/archival/cpio.c index 9674a046b..c2a5b8ab9 100644 --- a/archival/cpio.c +++ b/archival/cpio.c @@ -12,7 +12,7 @@ * */ #include "libbb.h" -#include "archive.h" +#include "bb_archive.h" //usage:#define cpio_trivial_usage //usage: "[-dmvu] [-F FILE]" IF_FEATURE_CPIO_O(" [-H newc]") diff --git a/archival/dpkg.c b/archival/dpkg.c index 2a6a7b3bf..bf9e9992c 100644 --- a/archival/dpkg.c +++ b/archival/dpkg.c @@ -57,7 +57,7 @@ #include "libbb.h" #include -#include "archive.h" +#include "bb_archive.h" /* note: if you vary hash_prime sizes be aware, * 1) tweaking these will have a big effect on how much memory this program uses. diff --git a/archival/dpkg_deb.c b/archival/dpkg_deb.c index 5d814d7ef..a04ec9407 100644 --- a/archival/dpkg_deb.c +++ b/archival/dpkg_deb.c @@ -19,7 +19,7 @@ //usage: "$ dpkg-deb -X ./busybox_0.48-1_i386.deb /tmp\n" #include "libbb.h" -#include "archive.h" +#include "bb_archive.h" #define DPKG_DEB_OPT_CONTENTS 1 #define DPKG_DEB_OPT_CONTROL 2 diff --git a/archival/gzip.c b/archival/gzip.c index 3af930b7e..929107389 100644 --- a/archival/gzip.c +++ b/archival/gzip.c @@ -55,7 +55,7 @@ aa: 85.1% -- replaced with aa.gz //usage: "-rw-rw-r-- 1 andersen andersen 554058 Apr 14 17:49 /tmp/busybox.tar.gz\n" #include "libbb.h" -#include "archive.h" +#include "bb_archive.h" /* =========================================================================== diff --git a/archival/libarchive/data_align.c b/archival/libarchive/data_align.c index 2e56fa8ff..a6b84a440 100644 --- a/archival/libarchive/data_align.c +++ b/archival/libarchive/data_align.c @@ -4,7 +4,7 @@ */ #include "libbb.h" -#include "archive.h" +#include "bb_archive.h" void FAST_FUNC data_align(archive_handle_t *archive_handle, unsigned boundary) { diff --git a/archival/libarchive/data_extract_all.c b/archival/libarchive/data_extract_all.c index 1b25c8bd6..f565e5471 100644 --- a/archival/libarchive/data_extract_all.c +++ b/archival/libarchive/data_extract_all.c @@ -4,7 +4,7 @@ */ #include "libbb.h" -#include "archive.h" +#include "bb_archive.h" void FAST_FUNC data_extract_all(archive_handle_t *archive_handle) { diff --git a/archival/libarchive/data_extract_to_command.c b/archival/libarchive/data_extract_to_command.c index 0e977049d..cc2ff7798 100644 --- a/archival/libarchive/data_extract_to_command.c +++ b/archival/libarchive/data_extract_to_command.c @@ -4,7 +4,7 @@ */ #include "libbb.h" -#include "archive.h" +#include "bb_archive.h" enum { //TAR_FILETYPE, diff --git a/archival/libarchive/data_extract_to_stdout.c b/archival/libarchive/data_extract_to_stdout.c index 91f3f3539..f849f3b42 100644 --- a/archival/libarchive/data_extract_to_stdout.c +++ b/archival/libarchive/data_extract_to_stdout.c @@ -4,7 +4,7 @@ */ #include "libbb.h" -#include "archive.h" +#include "bb_archive.h" void FAST_FUNC data_extract_to_stdout(archive_handle_t *archive_handle) { diff --git a/archival/libarchive/data_skip.c b/archival/libarchive/data_skip.c index a055424e2..588167f01 100644 --- a/archival/libarchive/data_skip.c +++ b/archival/libarchive/data_skip.c @@ -4,7 +4,7 @@ */ #include "libbb.h" -#include "archive.h" +#include "bb_archive.h" void FAST_FUNC data_skip(archive_handle_t *archive_handle) { diff --git a/archival/libarchive/decompress_bunzip2.c b/archival/libarchive/decompress_bunzip2.c index 4e46e6849..cd3144743 100644 --- a/archival/libarchive/decompress_bunzip2.c +++ b/archival/libarchive/decompress_bunzip2.c @@ -40,7 +40,7 @@ */ #include "libbb.h" -#include "archive.h" +#include "bb_archive.h" /* Constants for Huffman coding */ #define MAX_GROUPS 6 diff --git a/archival/libarchive/decompress_uncompress.c b/archival/libarchive/decompress_uncompress.c index d1061a2bb..c6040d04b 100644 --- a/archival/libarchive/decompress_uncompress.c +++ b/archival/libarchive/decompress_uncompress.c @@ -25,7 +25,7 @@ */ #include "libbb.h" -#include "archive.h" +#include "bb_archive.h" /* Default input buffer size */ diff --git a/archival/libarchive/decompress_unlzma.c b/archival/libarchive/decompress_unlzma.c index a04714341..3631b50cc 100644 --- a/archival/libarchive/decompress_unlzma.c +++ b/archival/libarchive/decompress_unlzma.c @@ -9,7 +9,7 @@ * Licensed under GPLv2 or later, see file LICENSE in this source tree. */ #include "libbb.h" -#include "archive.h" +#include "bb_archive.h" #if ENABLE_FEATURE_LZMA_FAST # define speed_inline ALWAYS_INLINE diff --git a/archival/libarchive/decompress_unxz.c b/archival/libarchive/decompress_unxz.c index e90dfb06f..3e5d4edca 100644 --- a/archival/libarchive/decompress_unxz.c +++ b/archival/libarchive/decompress_unxz.c @@ -10,7 +10,7 @@ * Licensed under GPLv2, see file LICENSE in this source tree. */ #include "libbb.h" -#include "archive.h" +#include "bb_archive.h" #define XZ_FUNC FAST_FUNC #define XZ_EXTERN static diff --git a/archival/libarchive/decompress_unzip.c b/archival/libarchive/decompress_unzip.c index a29eef837..aa5d22d0a 100644 --- a/archival/libarchive/decompress_unzip.c +++ b/archival/libarchive/decompress_unzip.c @@ -35,7 +35,7 @@ #include #include "libbb.h" -#include "archive.h" +#include "bb_archive.h" typedef struct huft_t { unsigned char e; /* number of extra bits or operation */ diff --git a/archival/libarchive/filter_accept_all.c b/archival/libarchive/filter_accept_all.c index e69deb679..c33f7d3e3 100644 --- a/archival/libarchive/filter_accept_all.c +++ b/archival/libarchive/filter_accept_all.c @@ -6,7 +6,7 @@ */ #include "libbb.h" -#include "archive.h" +#include "bb_archive.h" /* Accept any non-null name, its not really a filter at all */ char FAST_FUNC filter_accept_all(archive_handle_t *archive_handle) diff --git a/archival/libarchive/filter_accept_list.c b/archival/libarchive/filter_accept_list.c index a7640af79..a2d4b23e9 100644 --- a/archival/libarchive/filter_accept_list.c +++ b/archival/libarchive/filter_accept_list.c @@ -6,7 +6,7 @@ */ #include "libbb.h" -#include "archive.h" +#include "bb_archive.h" /* * Accept names that are in the accept list, ignoring reject list. diff --git a/archival/libarchive/filter_accept_list_reassign.c b/archival/libarchive/filter_accept_list_reassign.c index d80f71668..3d19abe44 100644 --- a/archival/libarchive/filter_accept_list_reassign.c +++ b/archival/libarchive/filter_accept_list_reassign.c @@ -6,7 +6,7 @@ */ #include "libbb.h" -#include "archive.h" +#include "bb_archive.h" /* Built and used only if ENABLE_DPKG || ENABLE_DPKG_DEB */ diff --git a/archival/libarchive/filter_accept_reject_list.c b/archival/libarchive/filter_accept_reject_list.c index 3e86cca65..39c811337 100644 --- a/archival/libarchive/filter_accept_reject_list.c +++ b/archival/libarchive/filter_accept_reject_list.c @@ -6,7 +6,7 @@ */ #include "libbb.h" -#include "archive.h" +#include "bb_archive.h" /* * Accept names that are in the accept list and not in the reject list diff --git a/archival/libarchive/find_list_entry.c b/archival/libarchive/find_list_entry.c index 5efd1af2e..56032c65a 100644 --- a/archival/libarchive/find_list_entry.c +++ b/archival/libarchive/find_list_entry.c @@ -7,7 +7,7 @@ #include #include "libbb.h" -#include "archive.h" +#include "bb_archive.h" /* Find a string in a shell pattern list */ const llist_t* FAST_FUNC find_list_entry(const llist_t *list, const char *filename) diff --git a/archival/libarchive/get_header_ar.c b/archival/libarchive/get_header_ar.c index df603b111..23c412496 100644 --- a/archival/libarchive/get_header_ar.c +++ b/archival/libarchive/get_header_ar.c @@ -5,7 +5,7 @@ */ #include "libbb.h" -#include "archive.h" +#include "bb_archive.h" #include "ar.h" static unsigned read_num(const char *str, int base) diff --git a/archival/libarchive/get_header_cpio.c b/archival/libarchive/get_header_cpio.c index 3d99b492a..1a0058b63 100644 --- a/archival/libarchive/get_header_cpio.c +++ b/archival/libarchive/get_header_cpio.c @@ -5,7 +5,7 @@ */ #include "libbb.h" -#include "archive.h" +#include "bb_archive.h" typedef struct hardlinks_t { struct hardlinks_t *next; diff --git a/archival/libarchive/get_header_tar.c b/archival/libarchive/get_header_tar.c index 79caff55a..41e3efb50 100644 --- a/archival/libarchive/get_header_tar.c +++ b/archival/libarchive/get_header_tar.c @@ -12,7 +12,7 @@ */ #include "libbb.h" -#include "archive.h" +#include "bb_archive.h" typedef uint32_t aliased_uint32_t FIX_ALIASING; typedef off_t aliased_off_t FIX_ALIASING; diff --git a/archival/libarchive/get_header_tar_bz2.c b/archival/libarchive/get_header_tar_bz2.c index 60d32069f..e012dec3b 100644 --- a/archival/libarchive/get_header_tar_bz2.c +++ b/archival/libarchive/get_header_tar_bz2.c @@ -4,7 +4,7 @@ */ #include "libbb.h" -#include "archive.h" +#include "bb_archive.h" char FAST_FUNC get_header_tar_bz2(archive_handle_t *archive_handle) { diff --git a/archival/libarchive/get_header_tar_gz.c b/archival/libarchive/get_header_tar_gz.c index 889fed0d9..b9679b0bd 100644 --- a/archival/libarchive/get_header_tar_gz.c +++ b/archival/libarchive/get_header_tar_gz.c @@ -4,7 +4,7 @@ */ #include "libbb.h" -#include "archive.h" +#include "bb_archive.h" char FAST_FUNC get_header_tar_gz(archive_handle_t *archive_handle) { diff --git a/archival/libarchive/get_header_tar_lzma.c b/archival/libarchive/get_header_tar_lzma.c index da08e0c72..666700729 100644 --- a/archival/libarchive/get_header_tar_lzma.c +++ b/archival/libarchive/get_header_tar_lzma.c @@ -7,7 +7,7 @@ */ #include "libbb.h" -#include "archive.h" +#include "bb_archive.h" char FAST_FUNC get_header_tar_lzma(archive_handle_t *archive_handle) { diff --git a/archival/libarchive/header_list.c b/archival/libarchive/header_list.c index c4fc75f38..0621aa406 100644 --- a/archival/libarchive/header_list.c +++ b/archival/libarchive/header_list.c @@ -3,7 +3,7 @@ * Licensed under GPLv2 or later, see file LICENSE in this source tree. */ #include "libbb.h" -#include "archive.h" +#include "bb_archive.h" void FAST_FUNC header_list(const file_header_t *file_header) { diff --git a/archival/libarchive/header_skip.c b/archival/libarchive/header_skip.c index 2bfc5253c..f5987bfe2 100644 --- a/archival/libarchive/header_skip.c +++ b/archival/libarchive/header_skip.c @@ -3,7 +3,7 @@ * Licensed under GPLv2 or later, see file LICENSE in this source tree. */ #include "libbb.h" -#include "archive.h" +#include "bb_archive.h" void FAST_FUNC header_skip(const file_header_t *file_header UNUSED_PARAM) { diff --git a/archival/libarchive/header_verbose_list.c b/archival/libarchive/header_verbose_list.c index bc4e4154b..87dd82136 100644 --- a/archival/libarchive/header_verbose_list.c +++ b/archival/libarchive/header_verbose_list.c @@ -4,7 +4,7 @@ */ #include "libbb.h" -#include "archive.h" +#include "bb_archive.h" void FAST_FUNC header_verbose_list(const file_header_t *file_header) { diff --git a/archival/libarchive/init_handle.c b/archival/libarchive/init_handle.c index 6644ea13b..cbae06ac3 100644 --- a/archival/libarchive/init_handle.c +++ b/archival/libarchive/init_handle.c @@ -4,7 +4,7 @@ */ #include "libbb.h" -#include "archive.h" +#include "bb_archive.h" archive_handle_t* FAST_FUNC init_handle(void) { diff --git a/archival/libarchive/open_transformer.c b/archival/libarchive/open_transformer.c index 26ae565f5..aa8c1021c 100644 --- a/archival/libarchive/open_transformer.c +++ b/archival/libarchive/open_transformer.c @@ -4,7 +4,7 @@ */ #include "libbb.h" -#include "archive.h" +#include "bb_archive.h" /* transformer(), more than meets the eye */ /* diff --git a/archival/libarchive/seek_by_jump.c b/archival/libarchive/seek_by_jump.c index 7c2c52ae1..4fcd99ac8 100644 --- a/archival/libarchive/seek_by_jump.c +++ b/archival/libarchive/seek_by_jump.c @@ -4,7 +4,7 @@ */ #include "libbb.h" -#include "archive.h" +#include "bb_archive.h" void FAST_FUNC seek_by_jump(int fd, off_t amount) { diff --git a/archival/libarchive/seek_by_read.c b/archival/libarchive/seek_by_read.c index ad931a8de..c0fde9660 100644 --- a/archival/libarchive/seek_by_read.c +++ b/archival/libarchive/seek_by_read.c @@ -4,7 +4,7 @@ */ #include "libbb.h" -#include "archive.h" +#include "bb_archive.h" /* If we are reading through a pipe, or from stdin then we can't lseek, * we must read and discard the data to skip over it. diff --git a/archival/libarchive/unpack_ar_archive.c b/archival/libarchive/unpack_ar_archive.c index 18dbfd54d..214d17e23 100644 --- a/archival/libarchive/unpack_ar_archive.c +++ b/archival/libarchive/unpack_ar_archive.c @@ -4,7 +4,7 @@ */ #include "libbb.h" -#include "archive.h" +#include "bb_archive.h" #include "ar.h" void FAST_FUNC unpack_ar_archive(archive_handle_t *ar_archive) diff --git a/archival/lzop.c b/archival/lzop.c index 1326bd790..7e30091d9 100644 --- a/archival/lzop.c +++ b/archival/lzop.c @@ -51,7 +51,7 @@ //usage: "\n -F Don't store or verify checksum" #include "libbb.h" -#include "archive.h" +#include "bb_archive.h" #include "liblzo_interface.h" /* lzo-2.03/src/lzo_ptr.h */ diff --git a/archival/rpm.c b/archival/rpm.c index 8174f4869..089b68983 100644 --- a/archival/rpm.c +++ b/archival/rpm.c @@ -20,7 +20,7 @@ //usage: "\n -c List config files" #include "libbb.h" -#include "archive.h" +#include "bb_archive.h" #include "rpm.h" #define RPM_CHAR_TYPE 1 diff --git a/archival/rpm2cpio.c b/archival/rpm2cpio.c index ff4a0d1b0..28b43a181 100644 --- a/archival/rpm2cpio.c +++ b/archival/rpm2cpio.c @@ -13,7 +13,7 @@ //usage: "Output a cpio archive of the rpm file" #include "libbb.h" -#include "archive.h" +#include "bb_archive.h" #include "rpm.h" enum { rpm_fd = STDIN_FILENO }; diff --git a/archival/tar.c b/archival/tar.c index 375e838d2..766b79b2b 100644 --- a/archival/tar.c +++ b/archival/tar.c @@ -44,7 +44,7 @@ #include #include "libbb.h" -#include "archive.h" +#include "bb_archive.h" /* FIXME: Stop using this non-standard feature */ #ifndef FNM_LEADING_DIR # define FNM_LEADING_DIR 0 diff --git a/archival/unzip.c b/archival/unzip.c index 4cc98cdb2..3a11f78a5 100644 --- a/archival/unzip.c +++ b/archival/unzip.c @@ -32,7 +32,7 @@ //usage: "\n -d DIR Extract files into DIR" #include "libbb.h" -#include "archive.h" +#include "bb_archive.h" enum { #if BB_BIG_ENDIAN diff --git a/include/archive.h b/include/archive.h deleted file mode 100644 index 9e176d335..000000000 --- a/include/archive.h +++ /dev/null @@ -1,241 +0,0 @@ -/* vi: set sw=4 ts=4: */ -#ifndef UNARCHIVE_H -#define UNARCHIVE_H 1 - -PUSH_AND_SET_FUNCTION_VISIBILITY_TO_HIDDEN - -enum { -#if BB_BIG_ENDIAN - COMPRESS_MAGIC = 0x1f9d, - GZIP_MAGIC = 0x1f8b, - BZIP2_MAGIC = 256 * 'B' + 'Z', - /* .xz signature: 0xfd, '7', 'z', 'X', 'Z', 0x00 */ - /* More info at: http://tukaani.org/xz/xz-file-format.txt */ - XZ_MAGIC1 = 256 * 0xfd + '7', - XZ_MAGIC2 = 256 * (256 * (256 * 'z' + 'X') + 'Z') + 0, - /* Different form: 32 bits, then 16 bits: */ - XZ_MAGIC1a = 256 * (256 * (256 * 0xfd + '7') + 'z') + 'X', - XZ_MAGIC2a = 256 * 'Z' + 0, -#else - COMPRESS_MAGIC = 0x9d1f, - GZIP_MAGIC = 0x8b1f, - BZIP2_MAGIC = 'B' + 'Z' * 256, - XZ_MAGIC1 = 0xfd + '7' * 256, - XZ_MAGIC2 = 'z' + ('X' + ('Z' + 0 * 256) * 256) * 256, - XZ_MAGIC1a = 0xfd + ('7' + ('z' + 'X' * 256) * 256) * 256, - XZ_MAGIC2a = 'Z' + 0 * 256, -#endif -}; - -typedef struct file_header_t { - char *name; - char *link_target; -#if ENABLE_FEATURE_TAR_UNAME_GNAME - char *tar__uname; - char *tar__gname; -#endif - off_t size; - uid_t uid; - gid_t gid; - mode_t mode; - time_t mtime; - dev_t device; -} file_header_t; - -struct hardlinks_t; - -typedef struct archive_handle_t { - /* Flags. 1st since it is most used member */ - unsigned ah_flags; - - /* The raw stream as read from disk or stdin */ - int src_fd; - - /* Define if the header and data component should be processed */ - char FAST_FUNC (*filter)(struct archive_handle_t *); - /* List of files that have been accepted */ - llist_t *accept; - /* List of files that have been rejected */ - llist_t *reject; - /* List of files that have successfully been worked on */ - llist_t *passed; - - /* Currently processed file's header */ - file_header_t *file_header; - - /* Process the header component, e.g. tar -t */ - void FAST_FUNC (*action_header)(const file_header_t *); - - /* Process the data component, e.g. extract to filesystem */ - void FAST_FUNC (*action_data)(struct archive_handle_t *); - - /* Function that skips data */ - void FAST_FUNC (*seek)(int fd, off_t amount); - - /* Count processed bytes */ - off_t offset; - - /* Archiver specific. Can make it a union if it ever gets big */ -#if ENABLE_TAR || ENABLE_DPKG || ENABLE_DPKG_DEB - smallint tar__end; -# if ENABLE_FEATURE_TAR_GNU_EXTENSIONS - char* tar__longname; - char* tar__linkname; -# endif -#if ENABLE_FEATURE_TAR_TO_COMMAND - char* tar__to_command; - const char* tar__to_command_shell; -#endif -# if ENABLE_FEATURE_TAR_SELINUX - char* tar__global_sctx; - char* tar__next_file_sctx; -# endif -#endif -#if ENABLE_CPIO || ENABLE_RPM2CPIO || ENABLE_RPM - uoff_t cpio__blocks; - struct hardlinks_t *cpio__hardlinks_to_create; - struct hardlinks_t *cpio__created_hardlinks; -#endif -#if ENABLE_DPKG || ENABLE_DPKG_DEB - /* Temporary storage */ - char *dpkg__buffer; - /* How to process any sub archive, e.g. get_header_tar_gz */ - char FAST_FUNC (*dpkg__action_data_subarchive)(struct archive_handle_t *); - /* Contains the handle to a sub archive */ - struct archive_handle_t *dpkg__sub_archive; -#endif -#if ENABLE_FEATURE_AR_CREATE - const char *ar__name; - struct archive_handle_t *ar__out; -#endif -} archive_handle_t; -/* bits in ah_flags */ -#define ARCHIVE_RESTORE_DATE (1 << 0) -#define ARCHIVE_CREATE_LEADING_DIRS (1 << 1) -#define ARCHIVE_UNLINK_OLD (1 << 2) -#define ARCHIVE_EXTRACT_QUIET (1 << 3) -#define ARCHIVE_EXTRACT_NEWER (1 << 4) -#define ARCHIVE_DONT_RESTORE_OWNER (1 << 5) -#define ARCHIVE_DONT_RESTORE_PERM (1 << 6) -#define ARCHIVE_NUMERIC_OWNER (1 << 7) -#define ARCHIVE_O_TRUNC (1 << 8) - - -/* POSIX tar Header Block, from POSIX 1003.1-1990 */ -#define TAR_BLOCK_SIZE 512 -#define NAME_SIZE 100 -#define NAME_SIZE_STR "100" -typedef struct tar_header_t { /* byte offset */ - char name[NAME_SIZE]; /* 0-99 */ - char mode[8]; /* 100-107 */ - char uid[8]; /* 108-115 */ - char gid[8]; /* 116-123 */ - char size[12]; /* 124-135 */ - char mtime[12]; /* 136-147 */ - char chksum[8]; /* 148-155 */ - char typeflag; /* 156-156 */ - char linkname[NAME_SIZE]; /* 157-256 */ - /* POSIX: "ustar" NUL "00" */ - /* GNU tar: "ustar " NUL */ - /* Normally it's defined as magic[6] followed by - * version[2], but we put them together to save code. - */ - char magic[8]; /* 257-264 */ - char uname[32]; /* 265-296 */ - char gname[32]; /* 297-328 */ - char devmajor[8]; /* 329-336 */ - char devminor[8]; /* 337-344 */ - char prefix[155]; /* 345-499 */ - char padding[12]; /* 500-512 (pad to exactly TAR_BLOCK_SIZE) */ -} tar_header_t; -struct BUG_tar_header { - char c[sizeof(tar_header_t) == TAR_BLOCK_SIZE ? 1 : -1]; -}; - - - -/* Info struct unpackers can fill out to inform users of thing like - * timestamps of unpacked files */ -typedef struct unpack_info_t { - time_t mtime; -} unpack_info_t; - -archive_handle_t *init_handle(void) FAST_FUNC; - -char filter_accept_all(archive_handle_t *archive_handle) FAST_FUNC; -char filter_accept_list(archive_handle_t *archive_handle) FAST_FUNC; -char filter_accept_list_reassign(archive_handle_t *archive_handle) FAST_FUNC; -char filter_accept_reject_list(archive_handle_t *archive_handle) FAST_FUNC; - -void unpack_ar_archive(archive_handle_t *ar_archive) FAST_FUNC; - -void data_skip(archive_handle_t *archive_handle) FAST_FUNC; -void data_extract_all(archive_handle_t *archive_handle) FAST_FUNC; -void data_extract_to_stdout(archive_handle_t *archive_handle) FAST_FUNC; -void data_extract_to_command(archive_handle_t *archive_handle) FAST_FUNC; - -void header_skip(const file_header_t *file_header) FAST_FUNC; -void header_list(const file_header_t *file_header) FAST_FUNC; -void header_verbose_list(const file_header_t *file_header) FAST_FUNC; - -char get_header_ar(archive_handle_t *archive_handle) FAST_FUNC; -char get_header_cpio(archive_handle_t *archive_handle) FAST_FUNC; -char get_header_tar(archive_handle_t *archive_handle) FAST_FUNC; -char get_header_tar_gz(archive_handle_t *archive_handle) FAST_FUNC; -char get_header_tar_bz2(archive_handle_t *archive_handle) FAST_FUNC; -char get_header_tar_lzma(archive_handle_t *archive_handle) FAST_FUNC; - -void seek_by_jump(int fd, off_t amount) FAST_FUNC; -void seek_by_read(int fd, off_t amount) FAST_FUNC; - -const char *strip_unsafe_prefix(const char *str) FAST_FUNC; - -void data_align(archive_handle_t *archive_handle, unsigned boundary) FAST_FUNC; -const llist_t *find_list_entry(const llist_t *list, const char *filename) FAST_FUNC; -const llist_t *find_list_entry2(const llist_t *list, const char *filename) FAST_FUNC; - -/* A bit of bunzip2 internals are exposed for compressed help support: */ -typedef struct bunzip_data bunzip_data; -int start_bunzip(bunzip_data **bdp, int in_fd, const void *inbuf, int len) FAST_FUNC; -/* NB: read_bunzip returns < 0 on error, or the number of *unfilled* bytes - * in outbuf. IOW: on EOF returns len ("all bytes are not filled"), not 0: */ -int read_bunzip(bunzip_data *bd, char *outbuf, int len) FAST_FUNC; -void dealloc_bunzip(bunzip_data *bd) FAST_FUNC; - -typedef struct inflate_unzip_result { - off_t bytes_out; - uint32_t crc; -} inflate_unzip_result; - -IF_DESKTOP(long long) int inflate_unzip(inflate_unzip_result *res, off_t compr_size, int src_fd, int dst_fd) FAST_FUNC; -/* xz unpacker takes .xz stream from offset 6 */ -IF_DESKTOP(long long) int unpack_xz_stream(int src_fd, int dst_fd) FAST_FUNC; -/* lzma unpacker takes .lzma stream from offset 0 */ -IF_DESKTOP(long long) int unpack_lzma_stream(int src_fd, int dst_fd) FAST_FUNC; -/* the rest wants 2 first bytes already skipped by the caller */ -IF_DESKTOP(long long) int unpack_bz2_stream(int src_fd, int dst_fd) FAST_FUNC; -IF_DESKTOP(long long) int unpack_gz_stream(int src_fd, int dst_fd) FAST_FUNC; -IF_DESKTOP(long long) int unpack_gz_stream_with_info(int src_fd, int dst_fd, unpack_info_t *info) FAST_FUNC; -IF_DESKTOP(long long) int unpack_Z_stream(int src_fd, int dst_fd) FAST_FUNC; -/* wrapper which checks first two bytes to be "BZ" */ -IF_DESKTOP(long long) int unpack_bz2_stream_prime(int src_fd, int dst_fd) FAST_FUNC; - -char* append_ext(char *filename, const char *expected_ext) FAST_FUNC; -int bbunpack(char **argv, - IF_DESKTOP(long long) int FAST_FUNC (*unpacker)(unpack_info_t *info), - char* FAST_FUNC (*make_new_name)(char *filename, const char *expected_ext), - const char *expected_ext -) FAST_FUNC; - -#if BB_MMU -void open_transformer(int fd, - IF_DESKTOP(long long) int FAST_FUNC (*transformer)(int src_fd, int dst_fd)) FAST_FUNC; -#define open_transformer(fd, transformer, transform_prog) open_transformer(fd, transformer) -#else -void open_transformer(int src_fd, const char *transform_prog) FAST_FUNC; -#define open_transformer(fd, transformer, transform_prog) open_transformer(fd, transform_prog) -#endif - -POP_SAVED_FUNCTION_VISIBILITY - -#endif diff --git a/include/bb_archive.h b/include/bb_archive.h new file mode 100644 index 000000000..9e176d335 --- /dev/null +++ b/include/bb_archive.h @@ -0,0 +1,241 @@ +/* vi: set sw=4 ts=4: */ +#ifndef UNARCHIVE_H +#define UNARCHIVE_H 1 + +PUSH_AND_SET_FUNCTION_VISIBILITY_TO_HIDDEN + +enum { +#if BB_BIG_ENDIAN + COMPRESS_MAGIC = 0x1f9d, + GZIP_MAGIC = 0x1f8b, + BZIP2_MAGIC = 256 * 'B' + 'Z', + /* .xz signature: 0xfd, '7', 'z', 'X', 'Z', 0x00 */ + /* More info at: http://tukaani.org/xz/xz-file-format.txt */ + XZ_MAGIC1 = 256 * 0xfd + '7', + XZ_MAGIC2 = 256 * (256 * (256 * 'z' + 'X') + 'Z') + 0, + /* Different form: 32 bits, then 16 bits: */ + XZ_MAGIC1a = 256 * (256 * (256 * 0xfd + '7') + 'z') + 'X', + XZ_MAGIC2a = 256 * 'Z' + 0, +#else + COMPRESS_MAGIC = 0x9d1f, + GZIP_MAGIC = 0x8b1f, + BZIP2_MAGIC = 'B' + 'Z' * 256, + XZ_MAGIC1 = 0xfd + '7' * 256, + XZ_MAGIC2 = 'z' + ('X' + ('Z' + 0 * 256) * 256) * 256, + XZ_MAGIC1a = 0xfd + ('7' + ('z' + 'X' * 256) * 256) * 256, + XZ_MAGIC2a = 'Z' + 0 * 256, +#endif +}; + +typedef struct file_header_t { + char *name; + char *link_target; +#if ENABLE_FEATURE_TAR_UNAME_GNAME + char *tar__uname; + char *tar__gname; +#endif + off_t size; + uid_t uid; + gid_t gid; + mode_t mode; + time_t mtime; + dev_t device; +} file_header_t; + +struct hardlinks_t; + +typedef struct archive_handle_t { + /* Flags. 1st since it is most used member */ + unsigned ah_flags; + + /* The raw stream as read from disk or stdin */ + int src_fd; + + /* Define if the header and data component should be processed */ + char FAST_FUNC (*filter)(struct archive_handle_t *); + /* List of files that have been accepted */ + llist_t *accept; + /* List of files that have been rejected */ + llist_t *reject; + /* List of files that have successfully been worked on */ + llist_t *passed; + + /* Currently processed file's header */ + file_header_t *file_header; + + /* Process the header component, e.g. tar -t */ + void FAST_FUNC (*action_header)(const file_header_t *); + + /* Process the data component, e.g. extract to filesystem */ + void FAST_FUNC (*action_data)(struct archive_handle_t *); + + /* Function that skips data */ + void FAST_FUNC (*seek)(int fd, off_t amount); + + /* Count processed bytes */ + off_t offset; + + /* Archiver specific. Can make it a union if it ever gets big */ +#if ENABLE_TAR || ENABLE_DPKG || ENABLE_DPKG_DEB + smallint tar__end; +# if ENABLE_FEATURE_TAR_GNU_EXTENSIONS + char* tar__longname; + char* tar__linkname; +# endif +#if ENABLE_FEATURE_TAR_TO_COMMAND + char* tar__to_command; + const char* tar__to_command_shell; +#endif +# if ENABLE_FEATURE_TAR_SELINUX + char* tar__global_sctx; + char* tar__next_file_sctx; +# endif +#endif +#if ENABLE_CPIO || ENABLE_RPM2CPIO || ENABLE_RPM + uoff_t cpio__blocks; + struct hardlinks_t *cpio__hardlinks_to_create; + struct hardlinks_t *cpio__created_hardlinks; +#endif +#if ENABLE_DPKG || ENABLE_DPKG_DEB + /* Temporary storage */ + char *dpkg__buffer; + /* How to process any sub archive, e.g. get_header_tar_gz */ + char FAST_FUNC (*dpkg__action_data_subarchive)(struct archive_handle_t *); + /* Contains the handle to a sub archive */ + struct archive_handle_t *dpkg__sub_archive; +#endif +#if ENABLE_FEATURE_AR_CREATE + const char *ar__name; + struct archive_handle_t *ar__out; +#endif +} archive_handle_t; +/* bits in ah_flags */ +#define ARCHIVE_RESTORE_DATE (1 << 0) +#define ARCHIVE_CREATE_LEADING_DIRS (1 << 1) +#define ARCHIVE_UNLINK_OLD (1 << 2) +#define ARCHIVE_EXTRACT_QUIET (1 << 3) +#define ARCHIVE_EXTRACT_NEWER (1 << 4) +#define ARCHIVE_DONT_RESTORE_OWNER (1 << 5) +#define ARCHIVE_DONT_RESTORE_PERM (1 << 6) +#define ARCHIVE_NUMERIC_OWNER (1 << 7) +#define ARCHIVE_O_TRUNC (1 << 8) + + +/* POSIX tar Header Block, from POSIX 1003.1-1990 */ +#define TAR_BLOCK_SIZE 512 +#define NAME_SIZE 100 +#define NAME_SIZE_STR "100" +typedef struct tar_header_t { /* byte offset */ + char name[NAME_SIZE]; /* 0-99 */ + char mode[8]; /* 100-107 */ + char uid[8]; /* 108-115 */ + char gid[8]; /* 116-123 */ + char size[12]; /* 124-135 */ + char mtime[12]; /* 136-147 */ + char chksum[8]; /* 148-155 */ + char typeflag; /* 156-156 */ + char linkname[NAME_SIZE]; /* 157-256 */ + /* POSIX: "ustar" NUL "00" */ + /* GNU tar: "ustar " NUL */ + /* Normally it's defined as magic[6] followed by + * version[2], but we put them together to save code. + */ + char magic[8]; /* 257-264 */ + char uname[32]; /* 265-296 */ + char gname[32]; /* 297-328 */ + char devmajor[8]; /* 329-336 */ + char devminor[8]; /* 337-344 */ + char prefix[155]; /* 345-499 */ + char padding[12]; /* 500-512 (pad to exactly TAR_BLOCK_SIZE) */ +} tar_header_t; +struct BUG_tar_header { + char c[sizeof(tar_header_t) == TAR_BLOCK_SIZE ? 1 : -1]; +}; + + + +/* Info struct unpackers can fill out to inform users of thing like + * timestamps of unpacked files */ +typedef struct unpack_info_t { + time_t mtime; +} unpack_info_t; + +archive_handle_t *init_handle(void) FAST_FUNC; + +char filter_accept_all(archive_handle_t *archive_handle) FAST_FUNC; +char filter_accept_list(archive_handle_t *archive_handle) FAST_FUNC; +char filter_accept_list_reassign(archive_handle_t *archive_handle) FAST_FUNC; +char filter_accept_reject_list(archive_handle_t *archive_handle) FAST_FUNC; + +void unpack_ar_archive(archive_handle_t *ar_archive) FAST_FUNC; + +void data_skip(archive_handle_t *archive_handle) FAST_FUNC; +void data_extract_all(archive_handle_t *archive_handle) FAST_FUNC; +void data_extract_to_stdout(archive_handle_t *archive_handle) FAST_FUNC; +void data_extract_to_command(archive_handle_t *archive_handle) FAST_FUNC; + +void header_skip(const file_header_t *file_header) FAST_FUNC; +void header_list(const file_header_t *file_header) FAST_FUNC; +void header_verbose_list(const file_header_t *file_header) FAST_FUNC; + +char get_header_ar(archive_handle_t *archive_handle) FAST_FUNC; +char get_header_cpio(archive_handle_t *archive_handle) FAST_FUNC; +char get_header_tar(archive_handle_t *archive_handle) FAST_FUNC; +char get_header_tar_gz(archive_handle_t *archive_handle) FAST_FUNC; +char get_header_tar_bz2(archive_handle_t *archive_handle) FAST_FUNC; +char get_header_tar_lzma(archive_handle_t *archive_handle) FAST_FUNC; + +void seek_by_jump(int fd, off_t amount) FAST_FUNC; +void seek_by_read(int fd, off_t amount) FAST_FUNC; + +const char *strip_unsafe_prefix(const char *str) FAST_FUNC; + +void data_align(archive_handle_t *archive_handle, unsigned boundary) FAST_FUNC; +const llist_t *find_list_entry(const llist_t *list, const char *filename) FAST_FUNC; +const llist_t *find_list_entry2(const llist_t *list, const char *filename) FAST_FUNC; + +/* A bit of bunzip2 internals are exposed for compressed help support: */ +typedef struct bunzip_data bunzip_data; +int start_bunzip(bunzip_data **bdp, int in_fd, const void *inbuf, int len) FAST_FUNC; +/* NB: read_bunzip returns < 0 on error, or the number of *unfilled* bytes + * in outbuf. IOW: on EOF returns len ("all bytes are not filled"), not 0: */ +int read_bunzip(bunzip_data *bd, char *outbuf, int len) FAST_FUNC; +void dealloc_bunzip(bunzip_data *bd) FAST_FUNC; + +typedef struct inflate_unzip_result { + off_t bytes_out; + uint32_t crc; +} inflate_unzip_result; + +IF_DESKTOP(long long) int inflate_unzip(inflate_unzip_result *res, off_t compr_size, int src_fd, int dst_fd) FAST_FUNC; +/* xz unpacker takes .xz stream from offset 6 */ +IF_DESKTOP(long long) int unpack_xz_stream(int src_fd, int dst_fd) FAST_FUNC; +/* lzma unpacker takes .lzma stream from offset 0 */ +IF_DESKTOP(long long) int unpack_lzma_stream(int src_fd, int dst_fd) FAST_FUNC; +/* the rest wants 2 first bytes already skipped by the caller */ +IF_DESKTOP(long long) int unpack_bz2_stream(int src_fd, int dst_fd) FAST_FUNC; +IF_DESKTOP(long long) int unpack_gz_stream(int src_fd, int dst_fd) FAST_FUNC; +IF_DESKTOP(long long) int unpack_gz_stream_with_info(int src_fd, int dst_fd, unpack_info_t *info) FAST_FUNC; +IF_DESKTOP(long long) int unpack_Z_stream(int src_fd, int dst_fd) FAST_FUNC; +/* wrapper which checks first two bytes to be "BZ" */ +IF_DESKTOP(long long) int unpack_bz2_stream_prime(int src_fd, int dst_fd) FAST_FUNC; + +char* append_ext(char *filename, const char *expected_ext) FAST_FUNC; +int bbunpack(char **argv, + IF_DESKTOP(long long) int FAST_FUNC (*unpacker)(unpack_info_t *info), + char* FAST_FUNC (*make_new_name)(char *filename, const char *expected_ext), + const char *expected_ext +) FAST_FUNC; + +#if BB_MMU +void open_transformer(int fd, + IF_DESKTOP(long long) int FAST_FUNC (*transformer)(int src_fd, int dst_fd)) FAST_FUNC; +#define open_transformer(fd, transformer, transform_prog) open_transformer(fd, transformer) +#else +void open_transformer(int src_fd, const char *transform_prog) FAST_FUNC; +#define open_transformer(fd, transformer, transform_prog) open_transformer(fd, transform_prog) +#endif + +POP_SAVED_FUNCTION_VISIBILITY + +#endif diff --git a/libbb/appletlib.c b/libbb/appletlib.c index 8157b4f42..efde3b69d 100644 --- a/libbb/appletlib.c +++ b/libbb/appletlib.c @@ -62,7 +62,7 @@ static const char usage_messages[] ALIGN1 = UNPACKED_USAGE; #if ENABLE_FEATURE_COMPRESS_USAGE static const char packed_usage[] ALIGN1 = { PACKED_USAGE }; -# include "archive.h" +# include "bb_archive.h" static const char *unpack_usage_messages(void) { char *outbuf = NULL; diff --git a/libbb/read_printf.c b/libbb/read_printf.c index 192f83d6e..0bbf7802a 100644 --- a/libbb/read_printf.c +++ b/libbb/read_printf.c @@ -15,7 +15,7 @@ ) #if ZIPPED -# include "archive.h" +# include "bb_archive.h" #endif diff --git a/miscutils/bbconfig.c b/miscutils/bbconfig.c index e8be81352..e5f4eb379 100644 --- a/miscutils/bbconfig.c +++ b/miscutils/bbconfig.c @@ -10,7 +10,7 @@ #include "libbb.h" #include "bbconfigopts.h" #if ENABLE_FEATURE_COMPRESS_BBCONFIG -# include "archive.h" +# include "bb_archive.h" # include "bbconfigopts_bz2.h" #endif diff --git a/procps/smemcap.c b/procps/smemcap.c index e108d88ad..9d1126a49 100644 --- a/procps/smemcap.c +++ b/procps/smemcap.c @@ -20,7 +20,7 @@ //config: a memory usage statistic tool. #include "libbb.h" -#include "archive.h" +#include "bb_archive.h" struct fileblock { struct fileblock *next; -- cgit v1.2.3-55-g6feb From 8d9ac30572818bbe78ef08d6580308e013972df3 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Mon, 26 Sep 2011 02:56:08 +0200 Subject: ps: add support for -l for !DESKTOP Signed-off-by: Denys Vlasenko --- procps/Config.src | 10 +++++- procps/ps.c | 103 ++++++++++++++++++++++++++++++++++++++++++++---------- 2 files changed, 94 insertions(+), 19 deletions(-) diff --git a/procps/Config.src b/procps/Config.src index 570b026da..5cd47c84f 100644 --- a/procps/Config.src +++ b/procps/Config.src @@ -90,12 +90,20 @@ config PS config FEATURE_PS_WIDE bool "Enable wide output option (-w)" default y - depends on PS + depends on PS && !DESKTOP help Support argument 'w' for wide output. If given once, 132 chars are printed, and if given more than once, the length is unlimited. +config FEATURE_PS_LONG + bool "Enable long output option (-l)" + default y + depends on PS && !DESKTOP + help + Support argument 'l' for long output. + Adds fields PPID, RSS, START, TIME & TTY + config FEATURE_PS_TIME bool "Enable time and elapsed time output" default y diff --git a/procps/ps.c b/procps/ps.c index dcc0f7bd4..c98384d71 100644 --- a/procps/ps.c +++ b/procps/ps.c @@ -39,6 +39,12 @@ //usage: IF_FEATURE_PS_WIDE( //usage: "\n w Wide output" //usage: ) +//usage: IF_FEATURE_PS_LONG( +//usage: "\n l Long output" +//usage: ) +//usage: IF_FEATURE_SHOW_THREADS( +//usage: "\n T Show threads" +//usage: ) //usage: //usage:#endif /* ENABLE_DESKTOP */ //usage: @@ -56,15 +62,15 @@ //usage: " 2990 andersen andersen R ps\n" #include "libbb.h" +#ifdef __linux__ +# include +#endif /* Absolute maximum on output line length */ enum { MAX_WIDTH = 2*1024 }; #if ENABLE_DESKTOP -#ifdef __linux__ -# include -#endif #include /* for times() */ #ifndef AT_CLKTCK # define AT_CLKTCK 17 @@ -625,15 +631,21 @@ int ps_main(int argc UNUSED_PARAM, char **argv UNUSED_PARAM) enum { OPT_Z = (1 << 0) * ENABLE_SELINUX, OPT_T = (1 << ENABLE_SELINUX) * ENABLE_FEATURE_SHOW_THREADS, + OPT_l = (1 << ENABLE_SELINUX) * (1 << ENABLE_FEATURE_SHOW_THREADS) * ENABLE_FEATURE_PS_LONG, }; +#if ENABLE_FEATURE_PS_LONG + time_t now = now; + struct sysinfo info; +#endif int opts = 0; /* If we support any options, parse argv */ -#if ENABLE_SELINUX || ENABLE_FEATURE_SHOW_THREADS || ENABLE_FEATURE_PS_WIDE +#if ENABLE_SELINUX || ENABLE_FEATURE_SHOW_THREADS || ENABLE_FEATURE_PS_WIDE || ENABLE_FEATURE_PS_LONG # if ENABLE_FEATURE_PS_WIDE /* -w is a bit complicated */ int w_count = 0; opt_complementary = "-:ww"; - opts = getopt32(argv, IF_SELINUX("Z")IF_FEATURE_SHOW_THREADS("T")"w", &w_count); + opts = getopt32(argv, IF_SELINUX("Z")IF_FEATURE_SHOW_THREADS("T")IF_FEATURE_PS_LONG("l") + "w", &w_count); /* if w is given once, GNU ps sets the width to 132, * if w is given more than once, it is "unlimited" */ @@ -648,23 +660,47 @@ int ps_main(int argc UNUSED_PARAM, char **argv UNUSED_PARAM) # else /* -w is not supported, only -Z and/or -T */ opt_complementary = "-"; - opts = getopt32(argv, IF_SELINUX("Z")IF_FEATURE_SHOW_THREADS("T")); + opts = getopt32(argv, IF_SELINUX("Z")IF_FEATURE_SHOW_THREADS("T")IF_FEATURE_PS_LONG("l")); # endif -#endif -#if ENABLE_SELINUX +# if ENABLE_SELINUX if ((opts & OPT_Z) && is_selinux_enabled()) { psscan_flags = PSSCAN_PID | PSSCAN_CONTEXT | PSSCAN_STATE | PSSCAN_COMM; puts(" PID CONTEXT STAT COMMAND"); } else -#endif - { +# endif + if (opts & OPT_l) { + psscan_flags = PSSCAN_STATE | PSSCAN_UIDGID | PSSCAN_PID | PSSCAN_PPID + | PSSCAN_TTY | PSSCAN_STIME | PSSCAN_UTIME | PSSCAN_COMM + | PSSCAN_VSZ | PSSCAN_RSS; +/* http://pubs.opengroup.org/onlinepubs/9699919799/utilities/ps.html + * mandates for -l: + * -F Flags associated with the process (?) + * S The state of the process + * UID,PID,PPID + * -C Processor utilization for scheduling + * -PRI The priority of the process; higher numbers mean lower priority + * -NI Nice value; used in priority computation + * -ADDR The address of the process + * SZ The size in blocks of the core image of the process + * -WCHAN The event for which the process is waiting or sleeping + * TTY + * TIME The cumulative execution time for the process + * CMD + * We don't show fileds marked with '-'. We show VSZ and RSS instead of SZ + */ + puts("S UID PID PPID VSZ RSS TTY TIME CMD"); + now = time(NULL); + sysinfo(&info); + } + else { puts(" PID USER VSZ STAT COMMAND"); } if (opts & OPT_T) { psscan_flags |= PSSCAN_TASKS; } +#endif p = NULL; while ((p = procps_scan(p, psscan_flags)) != NULL) { @@ -678,15 +714,46 @@ int ps_main(int argc UNUSED_PARAM, char **argv UNUSED_PARAM) } else #endif { - const char *user = get_cached_username(p->uid); - //if (p->vsz == 0) - // len = printf("%5u %-8.8s %s ", - // p->pid, user, p->state); - //else + char buf6[6]; + smart_ulltoa5(p->vsz, buf6, " mgtpezy"); + buf6[5] = '\0'; +#if ENABLE_FEATURE_PS_LONG + if (opts & OPT_l) { + char bufr[6], strt[6]; + char tty[2 * sizeof(int)*3 + 2]; + char *endp; + unsigned sut = (p->stime + p->utime) / 100; + unsigned elapsed = info.uptime - (p->start_time / 100); + time_t start = now - elapsed; + struct tm *tm = localtime(&start); + + smart_ulltoa5(p->rss, bufr, " mgtpezy"); + bufr[5] = '\0'; + + if (p->tty_major == 136) + endp = stpcpy(tty, "pts/"); + else + if (p->tty_major == 4) { + endp = stpcpy(tty, "tty"); + if (p->tty_minor >= 64) { + p->tty_minor -= 64; + *endp++ = 'S'; + } + } + else + endp = tty + sprintf(tty, "%d:", p->tty_major); + strcpy(endp, utoa(p->tty_minor)); + + strftime(strt, 6, (elapsed >= (24 * 60 * 60)) ? "%b%d" : "%H:%M", tm); + strt[5] = '\0'; + // S UID PID PPID VSZ RSS TTY TIME CMD + len = printf("%c %5u %5u %5u %5s %5s %-5s %02u:%02u:%02u ", + p->state[0], p->uid, p->pid, p->ppid, buf6, bufr, tty, + sut / 3600, (sut % 3600) / 60, sut % 60); + } else +#endif { - char buf6[6]; - smart_ulltoa5(p->vsz, buf6, " mgtpezy"); - buf6[5] = '\0'; + const char *user = get_cached_username(p->uid); len = printf("%5u %-8.8s %s %s ", p->pid, user, buf6, p->state); } -- cgit v1.2.3-55-g6feb From b64bd16459636c8a7ccf75854e0a2df590d97dec Mon Sep 17 00:00:00 2001 From: Flemming Madsen Date: Tue, 27 Sep 2011 15:31:25 +0200 Subject: ps: with -l, show STIME too Signed-off-by: Flemming Madsen Signed-off-by: Denys Vlasenko --- procps/ps.c | 37 +++++++++++++++++++++---------------- 1 file changed, 21 insertions(+), 16 deletions(-) diff --git a/procps/ps.c b/procps/ps.c index c98384d71..3815c1efa 100644 --- a/procps/ps.c +++ b/procps/ps.c @@ -676,21 +676,23 @@ int ps_main(int argc UNUSED_PARAM, char **argv UNUSED_PARAM) | PSSCAN_VSZ | PSSCAN_RSS; /* http://pubs.opengroup.org/onlinepubs/9699919799/utilities/ps.html * mandates for -l: - * -F Flags associated with the process (?) - * S The state of the process + * -F Flags (?) + * S State * UID,PID,PPID - * -C Processor utilization for scheduling + * -C CPU usage * -PRI The priority of the process; higher numbers mean lower priority - * -NI Nice value; used in priority computation - * -ADDR The address of the process - * SZ The size in blocks of the core image of the process + * -NI Nice value + * -ADDR The address of the process (?) + * SZ The size in blocks of the core image * -WCHAN The event for which the process is waiting or sleeping * TTY - * TIME The cumulative execution time for the process + * TIME The cumulative execution time * CMD - * We don't show fileds marked with '-'. We show VSZ and RSS instead of SZ + * We don't show fields marked with '-'. + * We show VSZ and RSS instead of SZ. + * We also show STIME (standard says that -f shows it, -l doesn't). */ - puts("S UID PID PPID VSZ RSS TTY TIME CMD"); + puts("S UID PID PPID VSZ RSS TTY STIME TIME CMD"); now = time(NULL); sysinfo(&info); } @@ -719,7 +721,7 @@ int ps_main(int argc UNUSED_PARAM, char **argv UNUSED_PARAM) buf6[5] = '\0'; #if ENABLE_FEATURE_PS_LONG if (opts & OPT_l) { - char bufr[6], strt[6]; + char bufr[6], stime_str[6]; char tty[2 * sizeof(int)*3 + 2]; char *endp; unsigned sut = (p->stime + p->utime) / 100; @@ -731,7 +733,10 @@ int ps_main(int argc UNUSED_PARAM, char **argv UNUSED_PARAM) bufr[5] = '\0'; if (p->tty_major == 136) - endp = stpcpy(tty, "pts/"); + /* It should be pts/N, not ptsN, but N > 9 + * will overflow field width... + */ + endp = stpcpy(tty, "pts"); else if (p->tty_major == 4) { endp = stpcpy(tty, "tty"); @@ -744,12 +749,12 @@ int ps_main(int argc UNUSED_PARAM, char **argv UNUSED_PARAM) endp = tty + sprintf(tty, "%d:", p->tty_major); strcpy(endp, utoa(p->tty_minor)); - strftime(strt, 6, (elapsed >= (24 * 60 * 60)) ? "%b%d" : "%H:%M", tm); - strt[5] = '\0'; - // S UID PID PPID VSZ RSS TTY TIME CMD - len = printf("%c %5u %5u %5u %5s %5s %-5s %02u:%02u:%02u ", + strftime(stime_str, 6, (elapsed >= (24 * 60 * 60)) ? "%b%d" : "%H:%M", tm); + stime_str[5] = '\0'; + // S UID PID PPID VSZ RSS TTY STIME TIME CMD + len = printf("%c %5u %5u %5u %5s %5s %-5s %s %02u:%02u:%02u ", p->state[0], p->uid, p->pid, p->ppid, buf6, bufr, tty, - sut / 3600, (sut % 3600) / 60, sut % 60); + stime_str, sut / 3600, (sut % 3600) / 60, sut % 60); } else #endif { -- cgit v1.2.3-55-g6feb From 85b1f292c9c1526448db29b0f2590f8adefa6b04 Mon Sep 17 00:00:00 2001 From: Cristian Ionescu-Idbohrn Date: Thu, 29 Sep 2011 11:02:00 +0200 Subject: ps: fix for !FEATURE_PS_LONG build Signed-off-by: Cristian Ionescu-Idbohrn Signed-off-by: Denys Vlasenko --- procps/ps.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/procps/ps.c b/procps/ps.c index 3815c1efa..4727b218b 100644 --- a/procps/ps.c +++ b/procps/ps.c @@ -693,8 +693,10 @@ int ps_main(int argc UNUSED_PARAM, char **argv UNUSED_PARAM) * We also show STIME (standard says that -f shows it, -l doesn't). */ puts("S UID PID PPID VSZ RSS TTY STIME TIME CMD"); +#if ENABLE_FEATURE_PS_LONG now = time(NULL); sysinfo(&info); +#endif } else { puts(" PID USER VSZ STAT COMMAND"); -- cgit v1.2.3-55-g6feb From faf7c62f1d66c51e8162e30119bfc06d2bc68f1c Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Thu, 6 Oct 2011 17:19:09 +0200 Subject: tftp: mode string is case independent Signed-off-by: Denys Vlasenko --- networking/tftp.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/networking/tftp.c b/networking/tftp.c index 17485a527..043b879af 100644 --- a/networking/tftp.c +++ b/networking/tftp.c @@ -813,7 +813,8 @@ int tftpd_main(int argc UNUSED_PARAM, char **argv) goto err; } mode = local_file + strlen(local_file) + 1; - if (mode >= block_buf + result || strcmp(mode, "octet") != 0) { + /* RFC 1350 says mode string is case independent */ + if (mode >= block_buf + result || strcasecmp(mode, "octet") != 0) { goto err; } # if ENABLE_FEATURE_TFTP_BLOCKSIZE -- cgit v1.2.3-55-g6feb From cc87588a613ce5de8cb47b04f63ba267d1ecfd1e Mon Sep 17 00:00:00 2001 From: Oliver Metz Date: Sun, 9 Oct 2011 02:08:42 +0200 Subject: disable strverscmp usage if we build against uClibc-0.9.31 Signed-off-by: Oliver Metz Signed-off-by: Denys Vlasenko --- include/platform.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/platform.h b/include/platform.h index aa1bc331b..d79cc97e5 100644 --- a/include/platform.h +++ b/include/platform.h @@ -366,7 +366,7 @@ typedef unsigned smalluint; #if defined(__UCLIBC_MAJOR__) # if __UCLIBC_MAJOR__ == 0 \ && ( __UCLIBC_MINOR__ < 9 \ - || (__UCLIBC_MINOR__ == 9 && __UCLIBC_SUBLEVEL__ < 31) \ + || (__UCLIBC_MINOR__ == 9 && __UCLIBC_SUBLEVEL__ < 32) \ ) # undef HAVE_STRVERSCMP # endif -- cgit v1.2.3-55-g6feb From 39ec6a2ad5dae93c125b766eb8e705742216797a Mon Sep 17 00:00:00 2001 From: Rob Landley Date: Mon, 10 Oct 2011 19:59:38 +0200 Subject: patch: make -p count path components, not slashes (think /blah//thing) Signed-off-by: Rob Landley Signed-off-by: Denys Vlasenko --- editors/patch.c | 18 ++++++++++-------- testsuite/patch.tests | 16 ++++++++++++++++ 2 files changed, 26 insertions(+), 8 deletions(-) diff --git a/editors/patch.c b/editors/patch.c index 1f2a49b66..13785ef46 100644 --- a/editors/patch.c +++ b/editors/patch.c @@ -474,19 +474,21 @@ int patch_main(int argc UNUSED_PARAM, char **argv) // We're deleting oldname if new file is /dev/null (before -p) // or if new hunk is empty (zero context) after patching - if (!strcmp(name, "/dev/null") || !(reverse ? oldsum : newsum)) - { + if (!strcmp(name, "/dev/null") || !(reverse ? oldsum : newsum)) { name = reverse ? newname : oldname; empty++; } // handle -p path truncation. - for (i=0, s = name; *s;) { - if ((option_mask32 & FLAG_PATHLEN) && TT.prefix == i) break; - if (*(s++)=='/') { - name = s; - i++; - } + for (i = 0, s = name; *s;) { + if ((option_mask32 & FLAG_PATHLEN) && TT.prefix == i) + break; + if (*s++ != '/') + continue; + while (*s == '/') + s++; + i++; + name = s; } if (empty) { diff --git a/testsuite/patch.tests b/testsuite/patch.tests index 8caeed5bd..2759d2ad4 100755 --- a/testsuite/patch.tests +++ b/testsuite/patch.tests @@ -226,6 +226,22 @@ qwerty +qwerty " +# testing "test name" "command(s)" "expected result" "file input" "stdin" +testing "patch understands ...dir///dir..." \ + 'patch -p1 2>&1; echo $?' \ +"\ +patching file dir2///file +patch: can't open 'dir2///file': No such file or directory +1 +" "" "\ +--- bogus_dir///dir2///file ++++ bogus_dir///dir2///file +@@ -1,2 +1,3 @@ + qwe ++asd + zxc +" + rm input.orig 2>/dev/null exit $FAILCOUNT -- cgit v1.2.3-55-g6feb From ecccbac37b733a57099c73bc806ac5de64643a35 Mon Sep 17 00:00:00 2001 From: Flemming Madsen Date: Mon, 10 Oct 2011 20:24:02 +0200 Subject: inotify: if PROG is -, print events to stdout function old new delta inotifyd_main 516 589 +73 packed_usage 28698 28709 +11 Signed-off-by: Flemming Madsen Signed-off-by: Denys Vlasenko --- miscutils/inotifyd.c | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/miscutils/inotifyd.c b/miscutils/inotifyd.c index b64e0abb9..7a1a6a2e5 100644 --- a/miscutils/inotifyd.c +++ b/miscutils/inotifyd.c @@ -33,6 +33,7 @@ //usage: "Run PROG on filesystem changes." //usage: "\nWhen a filesystem event matching MASK occurs on FILEn," //usage: "\nPROG ACTUAL_EVENTS FILEn [SUBFILE] is run." +//usage: "\nIf PROG is -, events are sent to stdout." //usage: "\nEvents:" //usage: "\n a File is accessed" //usage: "\n c File is modified" @@ -177,12 +178,20 @@ int inotifyd_main(int argc, char **argv) *s++ = mask_names[i]; } *s = '\0'; -// bb_error_msg("exec %s %08X\t%s\t%s\t%s", args[0], -// ie->mask, events, watches[ie->wd], ie->len ? ie->name : ""); - args[1] = events; - args[2] = watches[ie->wd]; - args[3] = ie->len ? ie->name : NULL; - spawn_and_wait((char **)args); + if (LONE_CHAR(args[0], '-')) { + /* "inotifyd - FILE": built-in echo */ + printf(ie->len ? "%s\t%s\t%s\n" : "%s\t%s\n", events, + watches[ie->wd], + ie->name); + fflush(stdout); + } else { +// bb_error_msg("exec %s %08X\t%s\t%s\t%s", args[0], +// ie->mask, events, watches[ie->wd], ie->len ? ie->name : ""); + args[1] = events; + args[2] = watches[ie->wd]; + args[3] = ie->len ? ie->name : NULL; + spawn_and_wait((char **)args); + } // we are done if all files got final x event if (ie->mask & 0x8000) { if (--argc <= 0) -- cgit v1.2.3-55-g6feb From 4c77ad75b11caa824a82eb8a88e91d71c51cdd43 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Sun, 16 Oct 2011 05:16:50 +0200 Subject: pwd: implement -LP if DESKTOP function old new delta pwd_main 41 244 +203 Signed-off-by: Denys Vlasenko --- coreutils/pwd.c | 52 +++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 51 insertions(+), 1 deletion(-) diff --git a/coreutils/pwd.c b/coreutils/pwd.c index 739b835b5..9455975e7 100644 --- a/coreutils/pwd.c +++ b/coreutils/pwd.c @@ -20,13 +20,63 @@ /* This is a NOFORK applet. Be very careful! */ +static int logical_getcwd(void) +{ + struct stat st1; + struct stat st2; + char *wd; + char *p; + + wd = getenv("PWD"); + if (!wd || wd[0] != '/') + return 0; + + p = wd; + while (*p) { + /* doing strstr(p, "/.") by hand is smaller and faster... */ + if (*p++ != '/') + continue; + if (*p != '.') + continue; + /* we found "/.", skip to next char */ + p++; + if (*p == '.') + p++; /* we found "/.." */ + if (*p == '\0' || *p == '/') + return 0; /* "/./" or "/../" component: bad */ + } + + if (stat(wd, &st1) != 0) + return 0; + if (stat(".", &st2) != 0) + return 0; + if (st1.st_ino != st2.st_ino) + return 0; + if (st1.st_dev != st2.st_dev) + return 0; + + puts(wd); + return 1; +} + int pwd_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; int pwd_main(int argc UNUSED_PARAM, char **argv UNUSED_PARAM) { char *buf; + if (ENABLE_DESKTOP) { + /* TODO: assume -L if $POSIXLY_CORRECT? (coreutils does that) + * Rationale: + * POSIX requires a default of -L, but most scripts expect -P + */ + unsigned opt = getopt32(argv, "LP"); + if ((opt & 1) && logical_getcwd()) + return fflush_all(); + } + buf = xrealloc_getcwd_or_warn(NULL); - if (buf != NULL) { + + if (buf) { puts(buf); free(buf); return fflush_all(); -- cgit v1.2.3-55-g6feb From e4fa7b7965fd574cff2a6a9b877522d613804a38 Mon Sep 17 00:00:00 2001 From: Peter Korsgaard Date: Mon, 17 Oct 2011 04:35:23 +0200 Subject: fbsplash: limit progress bar flicker Progress bar updates flicker quite a bit on slow hw / high resolutions as the background is completely cleared before the new progress bar position is drawn on top. Improve it by first drawing the progress bar and then only fill the remaining rows with the background. function old new delta fb_drawprogressbar 444 429 -15 Signed-off-by: Peter Korsgaard Signed-off-by: Denys Vlasenko --- miscutils/fbsplash.c | 30 +++++++++++++++++++----------- 1 file changed, 19 insertions(+), 11 deletions(-) diff --git a/miscutils/fbsplash.c b/miscutils/fbsplash.c index 51ba4729e..bc9ac8fe1 100644 --- a/miscutils/fbsplash.c +++ b/miscutils/fbsplash.c @@ -213,14 +213,15 @@ static void fb_drawfullrectangle(int nx1pos, int ny1pos, int nx2pos, int ny2pos, */ static void fb_drawprogressbar(unsigned percent) { - int i, left_x, top_y, width, height; + int left_x, top_y, pos_x; + unsigned width, height; // outer box left_x = G.nbar_posx; top_y = G.nbar_posy; width = G.nbar_width - 1; height = G.nbar_height - 1; - if ((height | width) < 0) + if ((int)(height | width) < 0) return; // NB: "width" of 1 actually makes rect with width of 2! fb_drawrectangle(); @@ -230,30 +231,37 @@ static void fb_drawprogressbar(unsigned percent) top_y++; width -= 2; height -= 2; - if ((height | width) < 0) + if ((int)(height | width) < 0) return; - fb_drawfullrectangle( - left_x, top_y, - left_x + width, top_y + height, - G.nbar_colr, G.nbar_colg, G.nbar_colb); + pos_x = left_x; if (percent > 0) { + int y; + unsigned i; + // actual progress bar - width = width * percent / 100; + pos_x += (unsigned)(width * percent) / 100; + + y = top_y; i = height; if (height == 0) height++; // divide by 0 is bad while (i >= 0) { // draw one-line thick "rectangle" // top line will have gray lvl 200, bottom one 100 - unsigned gray_level = 100 + i*100/height; + unsigned gray_level = 100 + i*100 / height; fb_drawfullrectangle( - left_x, top_y, left_x + width, top_y, + left_x, y, pos_x, y, gray_level, gray_level, gray_level); - top_y++; + y++; i--; } } + + fb_drawfullrectangle( + pos_x, top_y, + left_x + width, top_y + height, + G.nbar_colr, G.nbar_colg, G.nbar_colb); } -- cgit v1.2.3-55-g6feb From cd06e06eee3ef89e45b60d7122e5518995c7f65e Mon Sep 17 00:00:00 2001 From: Peter Korsgaard Date: Mon, 17 Oct 2011 05:31:52 +0200 Subject: fbsplash: support 8bit mode Fake truecolor support using a RGB:332 palette. function old new delta fb_setpal - 172 +172 fbsplash_main 920 953 +33 fb_pixel_value 50 80 +30 fb_write_pixel 47 51 +4 ------------------------------------------------------------------------------ (add/remove: 1/0 grow/shrink: 3/0 up/down: 239/0) Total: 239 bytes Signed-off-by: Peter Korsgaard Signed-off-by: Denys Vlasenko --- miscutils/fbsplash.c | 69 ++++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 64 insertions(+), 5 deletions(-) diff --git a/miscutils/fbsplash.c b/miscutils/fbsplash.c index bc9ac8fe1..04d583df6 100644 --- a/miscutils/fbsplash.c +++ b/miscutils/fbsplash.c @@ -74,6 +74,43 @@ struct globals { #define DEBUG_MESSAGE(...) ((void)0) #endif +/** + * Configure palette for RGB:332 + */ +static void fb_setpal(int fd) +{ + struct fb_cmap cmap; + /* fb colors are 16 bit */ + unsigned short red[256], green[256], blue[256]; + unsigned i; + + /* RGB:332 */ + for (i = 0; i < 256; i++) { + /* Color is encoded in pixel value as rrrgggbb. + * 3-bit color is mapped to 16-bit one as: + * 000 -> 00000000 00000000 + * 001 -> 00100100 10010010 + * ... + * 011 -> 01101101 10110110 + * 100 -> 10010010 01001001 + * ... + * 111 -> 11111111 11111111 + */ + red[i] = (( i >> 5 ) * 0x9249) >> 2; // rrr * 00 10010010 01001001 >> 2 + green[i] = (((i >> 2) & 0x7) * 0x9249) >> 2; // ggg * 00 10010010 01001001 >> 2 + /* 2-bit color is easier: */ + blue[i] = ( i & 0x3) * 0x5555; // bb * 01010101 01010101 + } + + cmap.start = 0; + cmap.len = 256; + cmap.red = red; + cmap.green = green; + cmap.blue = blue; + cmap.transp = 0; + + xioctl(fd, FBIOPUTCMAP, &cmap); +} /** * Open and initialize the framebuffer device @@ -87,8 +124,21 @@ static void fb_open(const char *strfb_device) xioctl(fbfd, FBIOGET_VSCREENINFO, &G.scr_var); xioctl(fbfd, FBIOGET_FSCREENINFO, &G.scr_fix); - if (G.scr_var.bits_per_pixel < 16 || G.scr_var.bits_per_pixel > 32) + switch (G.scr_var.bits_per_pixel) { + case 8: + fb_setpal(fbfd); + break; + + case 16: + case 24: + case 32: + break; + + default: bb_error_msg_and_die("unsupported %u bpp", (int)G.scr_var.bits_per_pixel); + break; + } + G.bytes_per_pixel = (G.scr_var.bits_per_pixel + 7) >> 3; // map the device in memory @@ -109,11 +159,17 @@ static void fb_open(const char *strfb_device) */ static unsigned fb_pixel_value(unsigned r, unsigned g, unsigned b) { + if (G.bytes_per_pixel == 1) { + r = r & 0xe0; // 3-bit red + g = (g >> 3) & 0x1c; // 3-bit green + b = b >> 6; // 2-bit blue + return r + g + b; + } if (G.bytes_per_pixel == 2) { - r >>= 3; // 5-bit red - g >>= 2; // 6-bit green - b >>= 3; // 5-bit blue - return b + (g << 5) + (r << (5+6)); + r = (r & 0xf8) << 8; // 5-bit red + g = (g & 0xfc) << 3; // 6-bit green + b = b >> 3; // 5-bit blue + return r + g + b; } // RGB 888 return b + (g << 8) + (r << 16); @@ -125,6 +181,9 @@ static unsigned fb_pixel_value(unsigned r, unsigned g, unsigned b) static void fb_write_pixel(unsigned char *addr, unsigned pixel) { switch (G.bytes_per_pixel) { + case 1: + *addr = pixel; + break; case 2: *(uint16_t *)addr = pixel; break; -- cgit v1.2.3-55-g6feb From 6c9c0a1dc9de48b59c103600a1f574a4a234b3d6 Mon Sep 17 00:00:00 2001 From: Leonid Lisovskiy Date: Tue, 18 Oct 2011 00:35:47 +0200 Subject: udhcp: IF_UDHCP_VERBOSE() macro - improve code readability Signed-off-by: Leonid Lisovskiy Signed-off-by: Denys Vlasenko --- networking/udhcp/common.h | 2 ++ networking/udhcp/dhcpc.c | 10 ++-------- networking/udhcp/dhcpd.c | 4 +--- 3 files changed, 5 insertions(+), 11 deletions(-) diff --git a/networking/udhcp/common.h b/networking/udhcp/common.h index 80d97e857..786266810 100644 --- a/networking/udhcp/common.h +++ b/networking/udhcp/common.h @@ -248,6 +248,7 @@ struct option_set *udhcp_find_option(struct option_set *opt_list, uint8_t code) /*** Logging ***/ #if defined CONFIG_UDHCP_DEBUG && CONFIG_UDHCP_DEBUG >= 1 +# define IF_UDHCP_VERBOSE(...) __VA_ARGS__ extern unsigned dhcp_verbose; # define log1(...) do { if (dhcp_verbose >= 1) bb_info_msg(__VA_ARGS__); } while (0) # if CONFIG_UDHCP_DEBUG >= 2 @@ -263,6 +264,7 @@ void udhcp_dump_packet(struct dhcp_packet *packet) FAST_FUNC; # define log3(...) ((void)0) # endif #else +# define IF_UDHCP_VERBOSE(...) # define udhcp_dump_packet(...) ((void)0) # define log1(...) ((void)0) # define log2(...) ((void)0) diff --git a/networking/udhcp/dhcpc.c b/networking/udhcp/dhcpc.c index 3be09f4d7..29a6cd5a1 100644 --- a/networking/udhcp/dhcpc.c +++ b/networking/udhcp/dhcpc.c @@ -1077,11 +1077,7 @@ int udhcpc_main(int argc UNUSED_PARAM, char **argv) /* Parse command line */ /* O,x: list; -T,-t,-A take numeric param */ - opt_complementary = "O::x::T+:t+:A+" -#if defined CONFIG_UDHCP_DEBUG && CONFIG_UDHCP_DEBUG >= 1 - ":vv" -#endif - ; + opt_complementary = "O::x::T+:t+:A+" IF_UDHCP_VERBOSE(":vv") ; IF_LONG_OPTS(applet_long_options = udhcpc_longopts;) opt = getopt32(argv, "CV:H:h:F:i:np:qRr:s:T:t:SA:O:ox:fB" USE_FOR_MMU("b") @@ -1095,9 +1091,7 @@ int udhcpc_main(int argc UNUSED_PARAM, char **argv) , &list_O , &list_x IF_FEATURE_UDHCP_PORT(, &str_P) -#if defined CONFIG_UDHCP_DEBUG && CONFIG_UDHCP_DEBUG >= 1 - , &dhcp_verbose -#endif + IF_UDHCP_VERBOSE(, &dhcp_verbose) ); if (opt & (OPT_h|OPT_H)) client_config.hostname = alloc_dhcp_option(DHCP_HOST_NAME, str_h, 0); diff --git a/networking/udhcp/dhcpd.c b/networking/udhcp/dhcpd.c index 747472d0c..dd55e70f4 100644 --- a/networking/udhcp/dhcpd.c +++ b/networking/udhcp/dhcpd.c @@ -314,9 +314,7 @@ int udhcpd_main(int argc UNUSED_PARAM, char **argv) #endif opt = getopt32(argv, "fSv" IF_FEATURE_UDHCP_PORT("P:", &str_P) -#if defined CONFIG_UDHCP_DEBUG && CONFIG_UDHCP_DEBUG >= 1 - , &dhcp_verbose -#endif + IF_UDHCP_VERBOSE(, &dhcp_verbose) ); if (!(opt & 1)) { /* no -f */ bb_daemonize_or_rexec(0, argv); -- cgit v1.2.3-55-g6feb From 6464f15ddb67f7c3fac9eb99a1336965537c4d67 Mon Sep 17 00:00:00 2001 From: Vladislav Grishenko Date: Tue, 18 Oct 2011 01:37:47 +0200 Subject: udhcpc: on SIGUSR1, limit renew attempts time to 20 seconds; then do total reconfig Scenario: 1. udhcpc gets lease for 86400 secs and sleeps for 43200 before renew attempt 2. PC gets physically disconnected and connected to another network 3. some phy control software sends SIGUSR1 to renew the lease, SIGUSR2 isn't used because newly connected network could be the same as before 4. udhcpc sends unicast renew requests until lease timeout fall to 60 sec. They are ignored by new network dhcp servers 5. udhcpc sends broadcast rebind requests for 60 seconds, which are NAKed or ignored too 6. udhcpc deconfigs and starting from discover state, gets new lease for the new network So, pt.4+5 it could take up to 86400 secs without correct lease, which is too long and not acceptable. Second SIGUSR1 will immediately run into deconfig/discover state, which is not preferable in case of the same subnet replugged. This patch makes sure after SIGUSR1 timeout is no more than -A NUM (usually 20 sec). It means that renew will be requested via broadcast, and if no replies come back, full deconf/reconf cycle will be initiated in 20 seconds. Signed-off-by: Vladislav Grishenko Signed-off-by: Denys Vlasenko --- networking/udhcp/dhcpc.c | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/networking/udhcp/dhcpc.c b/networking/udhcp/dhcpc.c index 29a6cd5a1..ddfe3ccc0 100644 --- a/networking/udhcp/dhcpc.c +++ b/networking/udhcp/dhcpc.c @@ -1355,9 +1355,23 @@ int udhcpc_main(int argc UNUSED_PARAM, char **argv) switch (udhcp_sp_read(&rfds)) { case SIGUSR1: client_config.first_secs = 0; /* make secs field count from 0 */ + already_waited_sec = 0; perform_renew(); - if (state == RENEW_REQUESTED) + if (state == RENEW_REQUESTED) { + /* We might be either on the same network + * (in which case renew might work), + * or we might be on a completely different one + * (in which case renew won't ever succeed). + * For the second case, must make sure timeout + * is not too big, or else we can send + * futile renew requests for hours. + * (Ab)use -A TIMEOUT value (usually 20 sec) + * as a cap on the timeout. + */ + if (timeout > tryagain_timeout) + timeout = tryagain_timeout; goto case_RENEW_REQUESTED; + } /* Start things over */ packet_num = 0; /* Kill any timeouts, user wants this to hurry along */ -- cgit v1.2.3-55-g6feb From 5f92043c3f9026725d518b6c76f7ef64cc8d4059 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Tue, 18 Oct 2011 12:07:05 +0200 Subject: uudecode: fix buggy check for empty filename Signed-off-by: Denys Vlasenko --- coreutils/uudecode.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/coreutils/uudecode.c b/coreutils/uudecode.c index 6ecfe6cef..23ff711fa 100644 --- a/coreutils/uudecode.c +++ b/coreutils/uudecode.c @@ -125,10 +125,11 @@ int uudecode_main(int argc UNUSED_PARAM, char **argv) mode = bb_strtou(line_ptr, NULL, 8); if (outname == NULL) { outname = strchr(line_ptr, ' '); - if ((outname == NULL) || (*outname == '\0')) { + if (!outname) break; - } outname++; + if (!outname[0]) + break; } dst_stream = stdout; if (NOT_LONE_DASH(outname)) { -- cgit v1.2.3-55-g6feb From ce8c4cf37fcb41b5775bbda9d90a1dadd03e4ced Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Wed, 19 Oct 2011 01:55:08 +0200 Subject: TODO: all another location with bbox patches (OpenWRT) Signed-off-by: Denys Vlasenko --- TODO | 2 ++ 1 file changed, 2 insertions(+) diff --git a/TODO b/TODO index 8b9f87f79..44364690f 100644 --- a/TODO +++ b/TODO @@ -2,6 +2,8 @@ Busybox TODO Harvest patches from http://git.openembedded.org/cgit.cgi/openembedded/tree/recipes/busybox/ +https://dev.openwrt.org/browser/trunk/package/busybox/patches/ + Stuff that needs to be done. This is organized by who plans to get around to doing it eventually, but that doesn't mean they "own" the item. If you want to -- cgit v1.2.3-55-g6feb From dd82443b921111d7f5570fddc2eaeb634f1f971d Mon Sep 17 00:00:00 2001 From: Peter Korsgaard Date: Wed, 19 Oct 2011 02:35:54 +0200 Subject: ifupdown: support post-up / pre-down hooks function old new delta set_environ 330 371 +41 ifupdown_main 2156 2194 +38 iface_up 97 113 +16 iface_down 97 113 +16 ------------------------------------------------------------------------------ (add/remove: 0/0 grow/shrink: 4/0 up/down: 111/0) Total: 111 bytes Signed-off-by: Peter Korsgaard Signed-off-by: Denys Vlasenko --- networking/ifupdown.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/networking/ifupdown.c b/networking/ifupdown.c index 382033038..abc6b5813 100644 --- a/networking/ifupdown.c +++ b/networking/ifupdown.c @@ -891,6 +891,8 @@ static struct interfaces_file_t *read_interfaces(const char *filename) if (strcmp(first_word, "up") != 0 && strcmp(first_word, "down") != 0 && strcmp(first_word, "pre-up") != 0 + && strcmp(first_word, "pre-down") != 0 + && strcmp(first_word, "post-up") != 0 && strcmp(first_word, "post-down") != 0 ) { int i; @@ -987,6 +989,8 @@ static void set_environ(struct interface_defn_t *iface, const char *mode) if (strcmp(iface->option[i].name, "up") == 0 || strcmp(iface->option[i].name, "down") == 0 || strcmp(iface->option[i].name, "pre-up") == 0 + || strcmp(iface->option[i].name, "pre-down") == 0 + || strcmp(iface->option[i].name, "post-up") == 0 || strcmp(iface->option[i].name, "post-down") == 0 ) { continue; @@ -1056,6 +1060,7 @@ static int iface_up(struct interface_defn_t *iface) if (!execute_all(iface, "pre-up")) return 0; if (!iface->method->up(iface, doit)) return 0; if (!execute_all(iface, "up")) return 0; + if (!execute_all(iface, "post-up")) return 0; return 1; } @@ -1063,6 +1068,7 @@ static int iface_down(struct interface_defn_t *iface) { if (!iface->method->down(iface,check)) return -1; set_environ(iface, "stop"); + if (!execute_all(iface, "pre-down")) return 0; if (!execute_all(iface, "down")) return 0; if (!iface->method->down(iface, doit)) return 0; if (!execute_all(iface, "post-down")) return 0; -- cgit v1.2.3-55-g6feb From 9c28fb8d288cb9b64d364d278731a20cc56fc29c Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Wed, 19 Oct 2011 02:37:08 +0200 Subject: ifupdown: code shrink function old new delta keywords_up_down - 43 +43 set_environ 371 259 -112 ifupdown_main 2194 2073 -121 ------------------------------------------------------------------------------ (add/remove: 1/0 grow/shrink: 0/2 up/down: 43/-233) Total: -190 bytes Signed-off-by: Denys Vlasenko --- networking/ifupdown.c | 42 +++++++++++++++--------------------------- 1 file changed, 15 insertions(+), 27 deletions(-) diff --git a/networking/ifupdown.c b/networking/ifupdown.c index abc6b5813..5946323d0 100644 --- a/networking/ifupdown.c +++ b/networking/ifupdown.c @@ -87,7 +87,6 @@ struct mapping_defn_t { char *script; - int max_mappings; int n_mappings; char **mapping; }; @@ -102,7 +101,6 @@ struct interface_defn_t { const struct method_t *method; char *iface; - int max_options; int n_options; struct variable_t *option; }; @@ -138,6 +136,16 @@ struct globals { #define INIT_G() do { } while (0) +static const char keywords_up_down[] ALIGN1 = + "up\0" + "down\0" + "pre-up\0" + "pre-down\0" + "post-up\0" + "post-down\0" +; + + #if ENABLE_FEATURE_IFUPDOWN_IPV4 || ENABLE_FEATURE_IFUPDOWN_IPV6 static void addstr(char **bufp, const char *str, size_t str_length) @@ -803,7 +811,6 @@ static struct interfaces_file_t *read_interfaces(const char *filename) currmap->match = xrealloc_vector(currmap->match, 4, currmap->n_matches); currmap->match[currmap->n_matches++] = xstrdup(first_word); } - /*currmap->max_mappings = 0; - done by xzalloc */ /*currmap->n_mappings = 0;*/ /*currmap->mapping = NULL;*/ /*currmap->script = NULL;*/ @@ -888,25 +895,16 @@ static struct interfaces_file_t *read_interfaces(const char *filename) if (rest_of_line[0] == '\0') bb_error_msg_and_die("option with empty value \"%s\"", buf); - if (strcmp(first_word, "up") != 0 - && strcmp(first_word, "down") != 0 - && strcmp(first_word, "pre-up") != 0 - && strcmp(first_word, "pre-down") != 0 - && strcmp(first_word, "post-up") != 0 - && strcmp(first_word, "post-down") != 0 - ) { + /* If not one of "up", "down",... words... */ + if (index_in_strings(keywords_up_down, first_word) < 0) { int i; for (i = 0; i < currif->n_options; i++) { if (strcmp(currif->option[i].name, first_word) == 0) bb_error_msg_and_die("duplicate option \"%s\"", buf); } } - if (currif->n_options >= currif->max_options) { - currif->max_options += 10; - currif->option = xrealloc(currif->option, - sizeof(*currif->option) * currif->max_options); - } debug_noise("\t%s=%s\n", first_word, rest_of_line); + currif->option = xrealloc_vector(currif->option, 4, currif->n_options); currif->option[currif->n_options].name = xstrdup(first_word); currif->option[currif->n_options].value = xstrdup(rest_of_line); currif->n_options++; @@ -918,11 +916,7 @@ static struct interfaces_file_t *read_interfaces(const char *filename) bb_error_msg_and_die("duplicate script in mapping \"%s\"", buf); currmap->script = xstrdup(next_word(&rest_of_line)); } else if (strcmp(first_word, "map") == 0) { - if (currmap->n_mappings >= currmap->max_mappings) { - currmap->max_mappings = currmap->max_mappings * 2 + 1; - currmap->mapping = xrealloc(currmap->mapping, - sizeof(char *) * currmap->max_mappings); - } + currmap->mapping = xrealloc_vector(currmap->mapping, 2, currmap->n_mappings); currmap->mapping[currmap->n_mappings] = xstrdup(next_word(&rest_of_line)); currmap->n_mappings++; } else { @@ -986,13 +980,7 @@ static void set_environ(struct interface_defn_t *iface, const char *mode) pp = G.my_environ; for (i = 0; i < iface->n_options; i++) { - if (strcmp(iface->option[i].name, "up") == 0 - || strcmp(iface->option[i].name, "down") == 0 - || strcmp(iface->option[i].name, "pre-up") == 0 - || strcmp(iface->option[i].name, "pre-down") == 0 - || strcmp(iface->option[i].name, "post-up") == 0 - || strcmp(iface->option[i].name, "post-down") == 0 - ) { + if (index_in_strings(keywords_up_down, iface->option[i].name) >= 0) { continue; } *pp++ = setlocalenv("IF_%s=%s", iface->option[i].name, iface->option[i].value); -- cgit v1.2.3-55-g6feb From f74f280a14f9b79a25e2ba29bab7a3056c94e647 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Wed, 19 Oct 2011 14:51:12 +0200 Subject: get_header_tar: shrink 6->64 sign extension code function old new delta getOctal 125 107 -18 Signed-off-by: Denys Vlasenko --- archival/libarchive/get_header_tar.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/archival/libarchive/get_header_tar.c b/archival/libarchive/get_header_tar.c index 41e3efb50..a63c0fb01 100644 --- a/archival/libarchive/get_header_tar.c +++ b/archival/libarchive/get_header_tar.c @@ -79,10 +79,10 @@ static unsigned long long getOctal(char *str, int len) * * NB: tarballs with NEGATIVE unix times encoded that way were seen! */ - v = first; - /* Sign-extend using 6th bit: */ - v <<= sizeof(unsigned long long)*8 - 7; - v = (long long)v >> (sizeof(unsigned long long)*8 - 7); + /* Sign-extend 7bit 'first' to 64bit 'v' (that is, using 6th bit as sign): */ + first <<= 1; + first >>= 1; /* now 7th bit = 6th bit */ + v = first; /* sign-extend 8 bits to 64 */ while (--len != 0) v = (v << 8) + (unsigned char) *str++; } -- cgit v1.2.3-55-g6feb From efd08bfa0adab3ae299be7abdd45161a15804a3b Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Wed, 19 Oct 2011 17:54:42 +0200 Subject: gen_build_files: don't pass 200k+ strings as params. Closes 4321 Also removes one grep per generated file. Signed-off-by: Denys Vlasenko --- scripts/gen_build_files.sh | 56 +++++++++++++++++++--------------------------- 1 file changed, 23 insertions(+), 33 deletions(-) diff --git a/scripts/gen_build_files.sh b/scripts/gen_build_files.sh index e518a9008..1a3d3e9b8 100755 --- a/scripts/gen_build_files.sh +++ b/scripts/gen_build_files.sh @@ -19,25 +19,20 @@ chk() { status "CHK" "$@"; } generate() { - local src="$1" dst="$2" header="$3" insert="$4" + # NB: data to be inserted at INSERT line is coming on stdin + local src="$1" dst="$2" header="$3" #chk "${dst}" - ( + { # Need to use printf: different shells have inconsistent - # rules re handling of "\n" in echo params, - # and ${insert} definitely contains "\n". - # Therefore, echo "${header}" would not work: + # rules re handling of "\n" in echo params. printf "%s\n" "${header}" - if grep -qs '^INSERT$' "${src}"; then - sed -n '1,/^INSERT$/p' "${src}" - printf "%s\n" "${insert}" - sed -n '/^INSERT$/,$p' "${src}" - else - if [ -n "${insert}" ]; then - printf "%s\n" "ERROR: INSERT line missing in: ${src}" 1>&2 - fi - cat "${src}" - fi - ) | sed '/^INSERT$/d' > "${dst}.tmp" + # print everything up to INSERT line + sed -n '/^INSERT$/q;1,/^INSERT$/p' "${src}" + # copy stdin to stdout + cat + # print everything after INSERT line + sed -n '/^INSERT$/{:l;n;p;bl}' "${src}" + } >"${dst}.tmp" if ! cmp -s "${dst}" "${dst}.tmp"; then gen "${dst}" mv "${dst}.tmp" "${dst}" @@ -47,24 +42,21 @@ generate() } # (Re)generate include/applets.h -s=`sed -n 's@^//applet:@@p' "$srctree"/*/*.c "$srctree"/*/*/*.c` -generate \ +sed -n 's@^//applet:@@p' "$srctree"/*/*.c "$srctree"/*/*/*.c \ +| generate \ "$srctree/include/applets.src.h" \ "include/applets.h" \ - "/* DO NOT EDIT. This file is generated from applets.src.h */" \ - "${s}" + "/* DO NOT EDIT. This file is generated from applets.src.h */" # (Re)generate include/usage.h # We add line continuation backslash after each line, # and insert empty line before each line which doesn't start # with space or tab -# (note: we need to use \\\\ because of ``) -s=`sed -n -e 's@^//usage:\([ \t].*\)$@\1 \\\\@p' -e 's@^//usage:\([^ \t].*\)$@\n\1 \\\\@p' "$srctree"/*/*.c "$srctree"/*/*/*.c` -generate \ +sed -n -e 's@^//usage:\([ \t].*\)$@\1 \\@p' -e 's@^//usage:\([^ \t].*\)$@\n\1 \\@p' "$srctree"/*/*.c "$srctree"/*/*/*.c \ +| generate \ "$srctree/include/usage.src.h" \ "include/usage.h" \ - "/* DO NOT EDIT. This file is generated from usage.src.h */" \ - "${s}" + "/* DO NOT EDIT. This file is generated from usage.src.h */" # (Re)generate */Kbuild and */Config.in { cd -- "$srctree" && find . -type d; } | while read -r d; do @@ -75,11 +67,10 @@ generate \ if test -f "$src"; then mkdir -p -- "$d" 2>/dev/null - s=`sed -n 's@^//kbuild:@@p' "$srctree/$d"/*.c` - generate \ + sed -n 's@^//kbuild:@@p' "$srctree/$d"/*.c \ + | generate \ "${src}" "${dst}" \ - "# DO NOT EDIT. This file is generated from Kbuild.src" \ - "${s}" + "# DO NOT EDIT. This file is generated from Kbuild.src" fi src="$srctree/$d/Config.src" @@ -87,11 +78,10 @@ generate \ if test -f "$src"; then mkdir -p -- "$d" 2>/dev/null - s=`sed -n 's@^//config:@@p' "$srctree/$d"/*.c` - generate \ + sed -n 's@^//config:@@p' "$srctree/$d"/*.c \ + | generate \ "${src}" "${dst}" \ - "# DO NOT EDIT. This file is generated from Config.src" \ - "${s}" + "# DO NOT EDIT. This file is generated from Config.src" fi done -- cgit v1.2.3-55-g6feb From 4ea37d62c2b90e360a97c43ffdb10afabaac46d9 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Wed, 19 Oct 2011 21:17:20 +0200 Subject: gen_build_files.sh: simplify "print everything up to INSERT line" part Signed-off-by: Denys Vlasenko --- scripts/gen_build_files.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/scripts/gen_build_files.sh b/scripts/gen_build_files.sh index 1a3d3e9b8..c42fe9fbb 100755 --- a/scripts/gen_build_files.sh +++ b/scripts/gen_build_files.sh @@ -27,11 +27,11 @@ generate() # rules re handling of "\n" in echo params. printf "%s\n" "${header}" # print everything up to INSERT line - sed -n '/^INSERT$/q;1,/^INSERT$/p' "${src}" + sed -n '/^INSERT$/ q; p' "${src}" # copy stdin to stdout cat # print everything after INSERT line - sed -n '/^INSERT$/{:l;n;p;bl}' "${src}" + sed -n '/^INSERT$/ { :l; n; p; bl }' "${src}" } >"${dst}.tmp" if ! cmp -s "${dst}" "${dst}.tmp"; then gen "${dst}" -- cgit v1.2.3-55-g6feb From 2ea73b513dfa831e75a297dd602576b40d38be3f Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Wed, 19 Oct 2011 22:31:01 +0200 Subject: nc: small code shrink Signed-off-by: Denys Vlasenko --- networking/nc_bloaty.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/networking/nc_bloaty.c b/networking/nc_bloaty.c index 1daad1358..d184f689b 100644 --- a/networking/nc_bloaty.c +++ b/networking/nc_bloaty.c @@ -428,8 +428,7 @@ create new one, and bind() it. TODO */ rr = getsockopt(netfd, IPPROTO_IP, IP_OPTIONS, optbuf, &x); if (rr >= 0 && x) { /* we've got options, lessee em... */ - bin2hex(bigbuf_net, optbuf, x); - bigbuf_net[2*x] = '\0'; + *bin2hex(bigbuf_net, optbuf, x) = '\0'; fprintf(stderr, "IP options: %s\n", bigbuf_net); } #endif -- cgit v1.2.3-55-g6feb From 1f56e51ca1d96b70635eb1b9df1d1ab0edd98a72 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Wed, 19 Oct 2011 22:40:35 +0200 Subject: udhcpc: add support for DHCP option 212 (RFC 5969) The patch is from OpenWRT people. function old new delta xmalloc_optname_optval 637 874 +237 dhcp_option_strings 237 243 +6 dhcp_optflags 68 70 +2 len_of_option_as_string 12 13 +1 dhcp_option_lengths 12 13 +1 ------------------------------------------------------------------------------ (add/remove: 0/0 grow/shrink: 5/0 up/down: 247/0) Total: 247 bytes Signed-off-by: Denys Vlasenko --- include/libbb.h | 4 +-- networking/udhcp/common.c | 3 ++ networking/udhcp/common.h | 1 + networking/udhcp/dhcpc.c | 80 +++++++++++++++++++++++++++++++++++++++++++++-- 4 files changed, 84 insertions(+), 4 deletions(-) diff --git a/include/libbb.h b/include/libbb.h index f79b69365..f0f54ef82 100644 --- a/include/libbb.h +++ b/include/libbb.h @@ -814,9 +814,9 @@ void smart_ulltoa5(unsigned long long ul, char buf[5], const char *scale) FAST_F const char *make_human_readable_str(unsigned long long size, unsigned long block_size, unsigned long display_unit) FAST_FUNC; /* Put a string of hex bytes ("1b2e66fe"...), return advanced pointer */ -char *bin2hex(char *buf, const char *cp, int count) FAST_FUNC; +char *bin2hex(char *dst, const char *src, int count) FAST_FUNC; /* Reverse */ -char* hex2bin(char *dst, const char *str, int count) FAST_FUNC; +char* hex2bin(char *dst, const char *src, int count) FAST_FUNC; /* Generate a UUID */ void generate_uuid(uint8_t *buf) FAST_FUNC; diff --git a/networking/udhcp/common.c b/networking/udhcp/common.c index 70e34614c..ba41905cc 100644 --- a/networking/udhcp/common.c +++ b/networking/udhcp/common.c @@ -59,6 +59,7 @@ const struct dhcp_optflag dhcp_optflags[] = { { OPTION_U16 , 0x84 }, /* DHCP_VLAN_ID */ { OPTION_U8 , 0x85 }, /* DHCP_VLAN_PRIORITY */ #endif + { OPTION_6RD , 0xd4 }, /* DHCP_6RD */ { OPTION_STATIC_ROUTES , 0xf9 }, /* DHCP_MS_STATIC_ROUTES */ { OPTION_STRING , 0xfc }, /* DHCP_WPAD */ @@ -126,6 +127,7 @@ const char dhcp_option_strings[] ALIGN1 = "vlanid" "\0" /* DHCP_VLAN_ID */ "vlanpriority" "\0"/* DHCP_VLAN_PRIORITY */ #endif + "ip6rd" "\0" /* DHCP_6RD */ "msstaticroutes""\0"/* DHCP_MS_STATIC_ROUTES */ "wpad" "\0" /* DHCP_WPAD */ ; @@ -154,6 +156,7 @@ const uint8_t dhcp_option_lengths[] ALIGN1 = { [OPTION_S32] = 4, /* Just like OPTION_STRING, we use minimum length here */ [OPTION_STATIC_ROUTES] = 5, + [OPTION_6RD] = 22, /* ignored by udhcp_str2optset */ }; diff --git a/networking/udhcp/common.h b/networking/udhcp/common.h index 786266810..da0bd38d1 100644 --- a/networking/udhcp/common.h +++ b/networking/udhcp/common.h @@ -88,6 +88,7 @@ enum { OPTION_S32, OPTION_BIN, OPTION_STATIC_ROUTES, + OPTION_6RD, #if ENABLE_FEATURE_UDHCP_RFC3397 OPTION_DNS_STRING, /* RFC1035 compressed domain name list */ OPTION_SIP_SERVERS, diff --git a/networking/udhcp/dhcpc.c b/networking/udhcp/dhcpc.c index ddfe3ccc0..311d4867a 100644 --- a/networking/udhcp/dhcpc.c +++ b/networking/udhcp/dhcpc.c @@ -100,6 +100,7 @@ static const uint8_t len_of_option_as_string[] = { [OPTION_IP ] = sizeof("255.255.255.255 "), [OPTION_IP_PAIR ] = sizeof("255.255.255.255 ") * 2, [OPTION_STATIC_ROUTES ] = sizeof("255.255.255.255/32 255.255.255.255 "), + [OPTION_6RD ] = sizeof("32 128 ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff 255.255.255.255 "), [OPTION_STRING ] = 1, #if ENABLE_FEATURE_UDHCP_RFC3397 [OPTION_DNS_STRING ] = 1, /* unused */ @@ -123,6 +124,24 @@ static int sprint_nip(char *dest, const char *pre, const uint8_t *ip) return sprintf(dest, "%s%u.%u.%u.%u", pre, ip[0], ip[1], ip[2], ip[3]); } +static int sprint_nip6(char *dest, const char *pre, const uint8_t *ip) +{ + char hexstrbuf[16 * 2]; + bin2hex(hexstrbuf, (void*)ip, 16); + return sprintf(dest, "%s" + "%.4s:%.4s:%.4s:%.4s:%.4s:%.4s:%.4s:%.4s", + pre, + hexstrbuf + 0 * 4, + hexstrbuf + 1 * 4, + hexstrbuf + 2 * 4, + hexstrbuf + 3 * 4, + hexstrbuf + 4 * 4, + hexstrbuf + 5 * 4, + hexstrbuf + 6 * 4, + hexstrbuf + 7 * 4 + ); +} + /* really simple implementation, just count the bits */ static int mton(uint32_t mask) { @@ -147,7 +166,8 @@ static NOINLINE char *xmalloc_optname_optval(uint8_t *option, const struct dhcp_ type = optflag->flags & OPTION_TYPE_MASK; optlen = dhcp_option_lengths[type]; - upper_length = len_of_option_as_string[type] * ((unsigned)len / (unsigned)optlen); + upper_length = len_of_option_as_string[type] + * ((unsigned)(len + optlen - 1) / (unsigned)optlen); dest = ret = xmalloc(upper_length + strlen(opt_name) + 2); dest += sprintf(ret, "%s=", opt_name); @@ -230,6 +250,62 @@ static NOINLINE char *xmalloc_optname_optval(uint8_t *option, const struct dhcp_ len -= 4; } + return ret; + } + case OPTION_6RD: { + /* Option binary format (see RFC 5969): + * 0 1 2 3 + * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | OPTION_6RD | option-length | IPv4MaskLen | 6rdPrefixLen | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | | + * | 6rdPrefix | + * | (16 octets) | + * | | + * | | + * | | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | 6rdBRIPv4Address(es) | + * . . + * . . + * . . + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * + * We convert it to a string + * "IPv4MaskLen 6rdPrefixLen 6rdPrefix 6rdBRIPv4Address..." + */ + + /* Sanity check: ensure that our length is at least 22 bytes, that + * IPv4MaskLen <= 32, + * 6rdPrefixLen <= 128, + * 6rdPrefixLen + (32 - IPv4MaskLen) <= 128 + * (2nd condition need no check - it follows from 1st and 3rd). + * If any of these requirements is not fulfilled, return with empty + * value. + */ + if (len >= 22 + && option[0] <= 32 + && (option[1] + 32 - option[0]) <= 128 + ) { + /* IPv4MaskLen */ + dest += sprintf(dest, "%u ", *option++); + /* 6rdPrefixLen */ + dest += sprintf(dest, "%u ", *option++); + /* 6rdPrefix */ + dest += sprint_nip6(dest, "", option); + option += 16; + len -= 1 + 1 + 16; + /* 6rdBRIPv4Address(es) */ + while (1) { + dest += sprint_nip(dest, " ", option); + option += 4; + len -= 4; + if (len < 0) + break; + } + } + return ret; } #if ENABLE_FEATURE_UDHCP_RFC3397 @@ -394,7 +470,7 @@ static char **fill_envp(struct dhcp_packet *packet) len = temp[-OPT_DATA + OPT_LEN]; *curr = xmalloc(sizeof("optNNN=") + 1 + len*2); ofs = sprintf(*curr, "opt%u=", i); - bin2hex(*curr + ofs, (void*) temp, len)[0] = '\0'; + *bin2hex(*curr + ofs, (void*) temp, len) = '\0'; putenv(*curr++); } i++; -- cgit v1.2.3-55-g6feb From f461385521c40a8295e9a36cd2f3f67512984124 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Thu, 20 Oct 2011 08:54:16 +0200 Subject: typo fix in comment Signed-off-by: Denys Vlasenko --- networking/udhcp/common.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/networking/udhcp/common.h b/networking/udhcp/common.h index da0bd38d1..a7f9395b8 100644 --- a/networking/udhcp/common.h +++ b/networking/udhcp/common.h @@ -104,7 +104,7 @@ enum { /* DHCP option codes (partial list). See RFC 2132 and * http://www.iana.org/assignments/bootp-dhcp-parameters/ * Commented out options are handled by common option machinery, - * uncommented ones have spacial cases (grep for them to see). + * uncommented ones have special cases (grep for them to see). */ #define DHCP_PADDING 0x00 #define DHCP_SUBNET 0x01 -- cgit v1.2.3-55-g6feb From 7981d79ef0bea5c8224edd949157be57ffd1173a Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Thu, 20 Oct 2011 10:34:05 +0200 Subject: udhcpc: small code shrink function old new delta udhcp_recv_raw_packet 430 425 -5 Signed-off-by: Denys Vlasenko --- networking/udhcp/dhcpc.c | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/networking/udhcp/dhcpc.c b/networking/udhcp/dhcpc.c index 311d4867a..b84196926 100644 --- a/networking/udhcp/dhcpc.c +++ b/networking/udhcp/dhcpc.c @@ -802,7 +802,8 @@ static NOINLINE int udhcp_recv_raw_packet(struct dhcp_packet *dhcp_pkt, int fd) bytes = ntohs(packet.ip.tot_len); /* make sure its the right packet for us, and that it passes sanity checks */ - if (packet.ip.protocol != IPPROTO_UDP || packet.ip.version != IPVERSION + if (packet.ip.protocol != IPPROTO_UDP + || packet.ip.version != IPVERSION || packet.ip.ihl != (sizeof(packet.ip) >> 2) || packet.udp.dest != htons(CLIENT_PORT) /* || bytes > (int) sizeof(packet) - can't happen */ @@ -831,15 +832,17 @@ static NOINLINE int udhcp_recv_raw_packet(struct dhcp_packet *dhcp_pkt, int fd) return -2; } - memcpy(dhcp_pkt, &packet.data, bytes - (sizeof(packet.ip) + sizeof(packet.udp))); - - if (dhcp_pkt->cookie != htonl(DHCP_MAGIC)) { + if (packet.data.cookie != htonl(DHCP_MAGIC)) { bb_info_msg("Packet with bad magic, ignoring"); return -2; } + log1("Got valid DHCP packet"); - udhcp_dump_packet(dhcp_pkt); - return bytes - (sizeof(packet.ip) + sizeof(packet.udp)); + udhcp_dump_packet(&packet.data); + + bytes -= sizeof(packet.ip) + sizeof(packet.udp); + memcpy(dhcp_pkt, &packet.data, bytes); + return bytes; } -- cgit v1.2.3-55-g6feb From 42816c204d2c592a86498c3d3b215c9b4d80e9e1 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Thu, 20 Oct 2011 10:52:07 +0200 Subject: udhcpc: remove unused argument in sprint_nip6 Signed-off-by: Denys Vlasenko --- networking/udhcp/dhcpc.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/networking/udhcp/dhcpc.c b/networking/udhcp/dhcpc.c index b84196926..d1e40ee65 100644 --- a/networking/udhcp/dhcpc.c +++ b/networking/udhcp/dhcpc.c @@ -124,13 +124,13 @@ static int sprint_nip(char *dest, const char *pre, const uint8_t *ip) return sprintf(dest, "%s%u.%u.%u.%u", pre, ip[0], ip[1], ip[2], ip[3]); } -static int sprint_nip6(char *dest, const char *pre, const uint8_t *ip) +static int sprint_nip6(char *dest, /*const char *pre,*/ const uint8_t *ip) { char hexstrbuf[16 * 2]; bin2hex(hexstrbuf, (void*)ip, 16); - return sprintf(dest, "%s" + return sprintf(dest, /* "%s" */ "%.4s:%.4s:%.4s:%.4s:%.4s:%.4s:%.4s:%.4s", - pre, + /* pre, */ hexstrbuf + 0 * 4, hexstrbuf + 1 * 4, hexstrbuf + 2 * 4, @@ -293,7 +293,7 @@ static NOINLINE char *xmalloc_optname_optval(uint8_t *option, const struct dhcp_ /* 6rdPrefixLen */ dest += sprintf(dest, "%u ", *option++); /* 6rdPrefix */ - dest += sprint_nip6(dest, "", option); + dest += sprint_nip6(dest, /* "", */ option); option += 16; len -= 1 + 1 + 16; /* 6rdBRIPv4Address(es) */ -- cgit v1.2.3-55-g6feb From 1dff672335ce227c0875864e3819c8464f978c08 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Thu, 20 Oct 2011 12:29:18 +0200 Subject: udhcpc: fix 6rd option formatting (was using 4 more bytes than there is) Signed-off-by: Denys Vlasenko --- networking/udhcp/dhcpc.c | 50 ++++++++++++++++++++++-------------------------- 1 file changed, 23 insertions(+), 27 deletions(-) diff --git a/networking/udhcp/dhcpc.c b/networking/udhcp/dhcpc.c index d1e40ee65..d9269f277 100644 --- a/networking/udhcp/dhcpc.c +++ b/networking/udhcp/dhcpc.c @@ -161,8 +161,8 @@ static NOINLINE char *xmalloc_optname_optval(uint8_t *option, const struct dhcp_ int len, type, optlen; char *dest, *ret; - /* option points to OPT_DATA, need to go back and get OPT_LEN */ - len = option[OPT_LEN - OPT_DATA]; + /* option points to OPT_DATA, need to go back to get OPT_LEN */ + len = option[-OPT_DATA + OPT_LEN]; type = optflag->flags & OPTION_TYPE_MASK; optlen = dhcp_option_lengths[type]; @@ -252,39 +252,29 @@ static NOINLINE char *xmalloc_optname_optval(uint8_t *option, const struct dhcp_ return ret; } - case OPTION_6RD: { + case OPTION_6RD: /* Option binary format (see RFC 5969): - * 0 1 2 3 - * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + * 0 1 2 3 + * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * | OPTION_6RD | option-length | IPv4MaskLen | 6rdPrefixLen | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - * | | * | 6rdPrefix | - * | (16 octets) | - * | | - * | | - * | | + * ... (16 octets) ... * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - * | 6rdBRIPv4Address(es) | - * . . - * . . - * . . + * ... 6rdBRIPv4Address(es) ... * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - * * We convert it to a string * "IPv4MaskLen 6rdPrefixLen 6rdPrefix 6rdBRIPv4Address..." - */ - - /* Sanity check: ensure that our length is at least 22 bytes, that + * + * Sanity check: ensure that our length is at least 22 bytes, that * IPv4MaskLen <= 32, * 6rdPrefixLen <= 128, * 6rdPrefixLen + (32 - IPv4MaskLen) <= 128 * (2nd condition need no check - it follows from 1st and 3rd). - * If any of these requirements is not fulfilled, return with empty - * value. + * Else, return envvar with empty value ("optname=") */ - if (len >= 22 + if (len >= (1 + 1 + 16 + 4) && option[0] <= 32 && (option[1] + 32 - option[0]) <= 128 ) { @@ -295,19 +285,20 @@ static NOINLINE char *xmalloc_optname_optval(uint8_t *option, const struct dhcp_ /* 6rdPrefix */ dest += sprint_nip6(dest, /* "", */ option); option += 16; - len -= 1 + 1 + 16; - /* 6rdBRIPv4Address(es) */ + len -= 1 + 1 + 16 + 4; + /* "+ 4" above corresponds to the length of IPv4 addr + * we consume in the loop below */ while (1) { + /* 6rdBRIPv4Address(es) */ dest += sprint_nip(dest, " ", option); option += 4; - len -= 4; + len -= 4; /* do we have yet another 4+ bytes? */ if (len < 0) - break; + break; /* no */ } } return ret; - } #if ENABLE_FEATURE_UDHCP_RFC3397 case OPTION_DNS_STRING: /* unpack option into dest; use ret for prefix (i.e., "optname=") */ @@ -347,6 +338,10 @@ static NOINLINE char *xmalloc_optname_optval(uint8_t *option, const struct dhcp_ return ret; #endif } /* switch */ + + /* If we are here, try to format any remaining data + * in the option as another, similarly-formatted option + */ option += optlen; len -= optlen; // TODO: it can be a list only if (optflag->flags & OPTION_LIST). @@ -356,7 +351,8 @@ static NOINLINE char *xmalloc_optname_optval(uint8_t *option, const struct dhcp_ break; *dest++ = ' '; *dest = '\0'; - } + } /* while */ + return ret; } -- cgit v1.2.3-55-g6feb From cd4d78f525526df0d2b62dce5a0dfc510debd6de Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Thu, 20 Oct 2011 13:21:55 +0200 Subject: dhcpc: fix the case where we might add extra space at the end of envvar. Signed-off-by: Denys Vlasenko --- networking/udhcp/common.c | 3 +++ networking/udhcp/dhcpc.c | 19 ++++++++++--------- 2 files changed, 13 insertions(+), 9 deletions(-) diff --git a/networking/udhcp/common.c b/networking/udhcp/common.c index ba41905cc..2e6113627 100644 --- a/networking/udhcp/common.c +++ b/networking/udhcp/common.c @@ -36,6 +36,9 @@ const struct dhcp_optflag dhcp_optflags[] = { { OPTION_STRING , 0x11 }, /* DHCP_ROOT_PATH */ { OPTION_U8 , 0x17 }, /* DHCP_IP_TTL */ { OPTION_U16 , 0x1a }, /* DHCP_MTU */ +//TODO: why do we request DHCP_BROADCAST? Can't we assume that +//in the unlikely case it is different from typical N.N.255.255, +//server would let us know anyway? { OPTION_IP | OPTION_REQ, 0x1c }, /* DHCP_BROADCAST */ { OPTION_IP_PAIR | OPTION_LIST , 0x21 }, /* DHCP_ROUTES */ { OPTION_STRING , 0x28 }, /* DHCP_NIS_DOMAIN */ diff --git a/networking/udhcp/dhcpc.c b/networking/udhcp/dhcpc.c index d9269f277..d67769e65 100644 --- a/networking/udhcp/dhcpc.c +++ b/networking/udhcp/dhcpc.c @@ -173,16 +173,13 @@ static NOINLINE char *xmalloc_optname_optval(uint8_t *option, const struct dhcp_ dest += sprintf(ret, "%s=", opt_name); while (len >= optlen) { - unsigned ip_ofs = 0; - switch (type) { + case OPTION_IP: case OPTION_IP_PAIR: dest += sprint_nip(dest, "", option); - *dest++ = '/'; - ip_ofs = 4; - /* fall through */ - case OPTION_IP: - dest += sprint_nip(dest, "", option + ip_ofs); + if (type == OPTION_IP) + break; + dest += sprint_nip(dest, "/", option + 4); break; // case OPTION_BOOLEAN: // dest += sprintf(dest, *option ? "yes" : "no"); @@ -204,10 +201,14 @@ static NOINLINE char *xmalloc_optname_optval(uint8_t *option, const struct dhcp_ dest += sprintf(dest, type == OPTION_U32 ? "%lu" : "%ld", (unsigned long) ntohl(val_u32)); break; } + /* Note: options which use 'return' instead of 'break' + * (for example, OPTION_STRING) skip the code which handles + * the case of list of options. + */ case OPTION_STRING: memcpy(dest, option, len); dest[len] = '\0'; - return ret; /* Short circuit this case */ + return ret; case OPTION_STATIC_ROUTES: { /* Option binary format: * mask [one byte, 0..32] @@ -347,7 +348,7 @@ static NOINLINE char *xmalloc_optname_optval(uint8_t *option, const struct dhcp_ // TODO: it can be a list only if (optflag->flags & OPTION_LIST). // Should we bail out/warn if we see multi-ip option which is // not allowed to be such (for example, DHCP_BROADCAST)? - - if (len <= 0 /* || !(optflag->flags & OPTION_LIST) */) + if (len < optlen /* || !(optflag->flags & OPTION_LIST) */) break; *dest++ = ' '; *dest = '\0'; -- cgit v1.2.3-55-g6feb From fbca0c68a75d0f2243bd7995d130e9cb8f6d2e18 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Thu, 20 Oct 2011 14:24:18 +0200 Subject: udhcpc: in fill_envp, export BOOTP fields first Signed-off-by: Denys Vlasenko --- networking/udhcp/dhcpc.c | 54 ++++++++++++++++++++++++++++++++---------------- 1 file changed, 36 insertions(+), 18 deletions(-) diff --git a/networking/udhcp/dhcpc.c b/networking/udhcp/dhcpc.c index d67769e65..36c8a3dd3 100644 --- a/networking/udhcp/dhcpc.c +++ b/networking/udhcp/dhcpc.c @@ -393,7 +393,7 @@ static char **fill_envp(struct dhcp_packet *packet) if (i == DHCP_OPTION_OVERLOAD) overload = *temp; else if (i == DHCP_SUBNET) - envc++; /* for mton */ + envc++; /* for $mask */ envc++; /*if (i != DHCP_MESSAGE_TYPE)*/ FOUND_OPTS(i) |= BMASK(i); @@ -408,10 +408,42 @@ static char **fill_envp(struct dhcp_packet *packet) if (!packet) return envp; + /* Export BOOTP fields. Fields we don't (yet?) export: + * uint8_t op; // always BOOTREPLY + * uint8_t htype; // hardware address type. 1 = 10mb ethernet + * uint8_t hlen; // hardware address length + * uint8_t hops; // used by relay agents only + * uint32_t xid; + * uint16_t secs; // elapsed since client began acquisition/renewal + * uint16_t flags; // only one flag so far: bcast. Never set by server + * uint32_t ciaddr; // client IP (usually == yiaddr. can it be different + * // if during renew server wants to give us differn IP?) + * uint32_t gateway_nip; // relay agent IP address + * uint8_t chaddr[16]; // link-layer client hardware address (MAC) + * TODO: export gateway_nip as $giaddr? + */ + /* Most important one: yiaddr as $ip */ *curr = xmalloc(sizeof("ip=255.255.255.255")); sprint_nip(*curr, "ip=", (uint8_t *) &packet->yiaddr); putenv(*curr++); + if (packet->siaddr_nip) { + /* IP address of next server to use in bootstrap */ + *curr = xmalloc(sizeof("siaddr=255.255.255.255")); + sprint_nip(*curr, "siaddr=", (uint8_t *) &packet->siaddr_nip); + putenv(*curr++); + } + if (!(overload & FILE_FIELD) && packet->file[0]) { + /* watch out for invalid packets */ + *curr = xasprintf("boot_file=%."DHCP_PKT_FILE_LEN_STR"s", packet->file); + putenv(*curr++); + } + if (!(overload & SNAME_FIELD) && packet->sname[0]) { + /* watch out for invalid packets */ + *curr = xasprintf("sname=%."DHCP_PKT_SNAME_LEN_STR"s", packet->sname); + putenv(*curr++); + } + /* Export known DHCP options */ opt_name = dhcp_option_strings; i = 0; while (*opt_name) { @@ -428,29 +460,14 @@ static char **fill_envp(struct dhcp_packet *packet) /* Subnet option: make things like "$ip/$mask" possible */ uint32_t subnet; move_from_unaligned32(subnet, temp); - *curr = xasprintf("mask=%d", mton(subnet)); + *curr = xasprintf("mask=%u", mton(subnet)); putenv(*curr++); } next: opt_name += strlen(opt_name) + 1; i++; } - if (packet->siaddr_nip) { - *curr = xmalloc(sizeof("siaddr=255.255.255.255")); - sprint_nip(*curr, "siaddr=", (uint8_t *) &packet->siaddr_nip); - putenv(*curr++); - } - if (!(overload & FILE_FIELD) && packet->file[0]) { - /* watch out for invalid packets */ - *curr = xasprintf("boot_file=%."DHCP_PKT_FILE_LEN_STR"s", packet->file); - putenv(*curr++); - } - if (!(overload & SNAME_FIELD) && packet->sname[0]) { - /* watch out for invalid packets */ - *curr = xasprintf("sname=%."DHCP_PKT_SNAME_LEN_STR"s", packet->sname); - putenv(*curr++); - } - /* Handle unknown options */ + /* Export unknown options */ for (i = 0; i < 256;) { BITMAP bitmap = FOUND_OPTS(i); if (!bitmap) { @@ -472,6 +489,7 @@ static char **fill_envp(struct dhcp_packet *packet) } i++; } + return envp; } -- cgit v1.2.3-55-g6feb From 2af2acf9b516c378147ea678e4b3bec092e4e44d Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Thu, 20 Oct 2011 14:47:41 +0200 Subject: udhcpc: add comment about server IP Signed-off-by: Denys Vlasenko --- networking/udhcp/dhcpc.c | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/networking/udhcp/dhcpc.c b/networking/udhcp/dhcpc.c index 36c8a3dd3..7cd0b7bcb 100644 --- a/networking/udhcp/dhcpc.c +++ b/networking/udhcp/dhcpc.c @@ -1533,7 +1533,25 @@ int udhcpc_main(int argc UNUSED_PARAM, char **argv) case INIT_SELECTING: /* Must be a DHCPOFFER to one of our xid's */ if (*message == DHCPOFFER) { - /* TODO: why we don't just fetch server's IP from IP header? */ +/* What exactly is server's IP? There are several values. + * Example DHCP offer captured with tchdump: + * + * 10.34.25.254:67 > 10.34.25.202:68 // IP header's src + * BOOTP fields: + * Your-IP 10.34.25.202 + * Server-IP 10.34.32.125 // "next server" IP + * Gateway-IP 10.34.25.254 // relay's address (if DHCP relays are in use) + * DHCP options: + * DHCP-Message Option 53, length 1: Offer + * Server-ID Option 54, length 4: 10.34.255.7 // "server ID" + * Default-Gateway Option 3, length 4: 10.34.25.254 // router + * + * We think that real server IP (one to use in renew/release) + * is one in Server-ID option. But I am not 100% sure. + * IP header's src and Gateway-IP (same in this exaqmple) + * might work too. + * "Next server" and router are definitely wrong ones to use, though... + */ temp = udhcp_get_option(&packet, DHCP_SERVER_ID); if (!temp) { bb_error_msg("no server ID, ignoring packet"); -- cgit v1.2.3-55-g6feb From 17fb598dc2fa094d6bbf56bbc9f6e561f4fb3679 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Fri, 21 Oct 2011 18:44:33 +0200 Subject: docs/ctty.htm: add a useful URL to Signed-off-by: Denys Vlasenko --- docs/ctty.htm | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docs/ctty.htm b/docs/ctty.htm index 8f466cdde..e7d2877f8 100644 --- a/docs/ctty.htm +++ b/docs/ctty.htm @@ -9,6 +9,8 @@

Before looking at the Linux implementation, first a general Unix description of threads, processes, process groups and sessions. +

+(See also General Terminal Interface)

A session contains a number of process groups, and a process group contains a number of processes, and a process contains a number of threads. -- cgit v1.2.3-55-g6feb From 5dd1f472a41f2c3dd3c009d0e623212514205c2c Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Fri, 21 Oct 2011 19:45:13 +0200 Subject: stty: trim too verbose error messages (-40 bytes) Signed-off-by: Denys Vlasenko --- coreutils/stty.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/coreutils/stty.c b/coreutils/stty.c index 7f057ead2..0668cf7be 100644 --- a/coreutils/stty.c +++ b/coreutils/stty.c @@ -1404,13 +1404,15 @@ int stty_main(int argc UNUSED_PARAM, char **argv) /* Specifying both -a and -g is an error */ if ((stty_state & (STTY_verbose_output | STTY_recoverable_output)) == - (STTY_verbose_output | STTY_recoverable_output)) - bb_error_msg_and_die("verbose and stty-readable output styles are mutually exclusive"); + (STTY_verbose_output | STTY_recoverable_output) + ) { + bb_error_msg_and_die("-a and -g are mutually exclusive"); + } /* Specifying -a or -g with non-options is an error */ - if (!(stty_state & STTY_noargs) - && (stty_state & (STTY_verbose_output | STTY_recoverable_output)) + if ((stty_state & (STTY_verbose_output | STTY_recoverable_output)) + && !(stty_state & STTY_noargs) ) { - bb_error_msg_and_die("modes may not be set when specifying an output style"); + bb_error_msg_and_die("modes may not be set when -a or -g is used"); } /* Now it is safe to start doing things */ -- cgit v1.2.3-55-g6feb From ef5a2d757a963fa50807c0abc8cb65be8657c8ee Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Sat, 22 Oct 2011 03:16:23 +0200 Subject: getty: shrink help text Signed-off-by: Denys Vlasenko --- loginutils/getty.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/loginutils/getty.c b/loginutils/getty.c index 62456651b..baad04e9b 100644 --- a/loginutils/getty.c +++ b/loginutils/getty.c @@ -104,7 +104,7 @@ struct globals { //usage:#define getty_trivial_usage //usage: "[OPTIONS] BAUD_RATE[,BAUD_RATE]... TTY [TERMTYPE]" //usage:#define getty_full_usage "\n\n" -//usage: "Open a tty, prompt for a login name, then invoke /bin/login\n" +//usage: "Open TTY, prompt for login name, then invoke /bin/login\n" //usage: "\n -h Enable hardware RTS/CTS flow control" //usage: "\n -L Set CLOCAL (ignore Carrier Detect state)" //usage: "\n -m Get baud rate from modem's CONNECT status message" -- cgit v1.2.3-55-g6feb From 7449e18190b8ed07a7cd1711b40885ae4b97efb4 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Sat, 22 Oct 2011 06:27:41 +0200 Subject: getty,login: tighten up handling of ctty, pgrp, and tty attr restoring on timeout Signed-off-by: Denys Vlasenko --- docs/ctty.htm | 1 + libbb/bb_askpass.c | 22 +++--- loginutils/getty.c | 208 +++++++++++++++++++++++++++++++---------------------- loginutils/login.c | 45 +++++++++--- 4 files changed, 171 insertions(+), 105 deletions(-) diff --git a/docs/ctty.htm b/docs/ctty.htm index e7d2877f8..3cb2dd2bd 100644 --- a/docs/ctty.htm +++ b/docs/ctty.htm @@ -279,6 +279,7 @@ and inspect it by Again, if TOSTOP is set but the background process ignores or blocks the SIGTTOU signal, or if its process group is orphaned (see below), then the write() returns an EIO error, and no signal is sent. +[vda: correction. SUS says that if SIGTTOU is blocked/ignored, write succeeds. ]

Orphaned process groups

diff --git a/libbb/bb_askpass.c b/libbb/bb_askpass.c index 9a4188f52..fe2b50677 100644 --- a/libbb/bb_askpass.c +++ b/libbb/bb_askpass.c @@ -30,14 +30,23 @@ char* FAST_FUNC bb_ask(const int fd, int timeout, const char *prompt) struct sigaction sa, oldsa; struct termios tio, oldtio; - tcgetattr(fd, &oldtio); + fputs(prompt, stdout); + fflush_all(); tcflush(fd, TCIFLUSH); + + tcgetattr(fd, &oldtio); tio = oldtio; -#ifndef IUCLC -# define IUCLC 0 -#endif +#if 0 + /* Switch off UPPERCASE->lowercase conversion (never used since 198x) + * and XON/XOFF (why we want to mess with this??) + */ +# ifndef IUCLC +# define IUCLC 0 +# endif tio.c_iflag &= ~(IUCLC|IXON|IXOFF|IXANY); - tio.c_lflag &= ~(ECHO|ECHOE|ECHOK|ECHONL|TOSTOP); +#endif + /* Switch off echo */ + tio.c_lflag &= ~(ECHO|ECHOE|ECHOK|ECHONL); tcsetattr(fd, TCSANOW, &tio); memset(&sa, 0, sizeof(sa)); @@ -50,9 +59,6 @@ char* FAST_FUNC bb_ask(const int fd, int timeout, const char *prompt) alarm(timeout); } - fputs(prompt, stdout); - fflush_all(); - if (!passwd) passwd = xmalloc(sizeof_passwd); ret = passwd; diff --git a/loginutils/getty.c b/loginutils/getty.c index baad04e9b..168ae4de1 100644 --- a/loginutils/getty.c +++ b/loginutils/getty.c @@ -83,16 +83,16 @@ static FILE *dbf; #define MAX_SPEED 10 /* max. nr. of baud rates */ struct globals { - unsigned timeout; /* time-out period */ + unsigned timeout; const char *login; /* login program */ const char *fakehost; - const char *tty; /* name of tty */ + const char *tty_name; char *initstring; /* modem init string */ const char *issue; /* alternative issue file */ int numspeed; /* number of baud rates to try */ int speeds[MAX_SPEED]; /* baud rates to be tried */ unsigned char eol; /* end-of-line char seen (CR or NL) */ - struct termios termios; /* terminal mode bits */ + struct termios tty_attrs; char line_buf[128]; }; @@ -181,15 +181,14 @@ static void parse_args(char **argv) debug("after getopt\n"); /* We loosen up a bit and accept both "baudrate tty" and "tty baudrate" */ - G.tty = argv[0]; /* tty name */ - ts = argv[1]; /* baud rate(s) */ + G.tty_name = argv[0]; + ts = argv[1]; /* baud rate(s) */ if (isdigit(argv[0][0])) { /* A number first, assume it's a speed (BSD style) */ - G.tty = ts; /* tty name is in argv[1] */ - ts = argv[0]; /* baud rate(s) */ + G.tty_name = ts; /* tty name is in argv[1] */ + ts = argv[0]; /* baud rate(s) */ } parse_speeds(ts); - applet_name = xasprintf("getty: %s", G.tty); if (argv[2]) xsetenv("TERM", argv[2]); @@ -201,42 +200,49 @@ static void parse_args(char **argv) static void open_tty(void) { /* Set up new standard input, unless we are given an already opened port */ - if (NOT_LONE_DASH(G.tty)) { - if (G.tty[0] != '/') - G.tty = xasprintf("/dev/%s", G.tty); /* will leak it */ + if (NOT_LONE_DASH(G.tty_name)) { + if (G.tty_name[0] != '/') + G.tty_name = xasprintf("/dev/%s", G.tty_name); /* will leak it */ /* Open the tty as standard input */ debug("open(2)\n"); close(0); - xopen(G.tty, O_RDWR | O_NONBLOCK); /* uses fd 0 */ + xopen(G.tty_name, O_RDWR | O_NONBLOCK); /* uses fd 0 */ /* Set proper protections and ownership */ fchown(0, 0, 0); /* 0:0 */ fchmod(0, 0620); /* crw--w---- */ } else { + char *n; /* - * Standard input should already be connected to an open port. Make - * sure it is open for read/write. + * Standard input should already be connected to an open port. + * Make sure it is open for read/write. */ if ((fcntl(0, F_GETFL) & (O_RDWR|O_RDONLY|O_WRONLY)) != O_RDWR) bb_error_msg_and_die("stdin is not open for read/write"); + + /* Try to get real tty name instead of "-" */ + n = xmalloc_ttyname(0); + if (n) + G.tty_name = n; } + applet_name = xasprintf("getty: %s", skip_dev_pfx(G.tty_name)); } -static void set_termios(void) +static void set_tty_attrs(void) { - if (tcsetattr_stdin_TCSANOW(&G.termios) < 0) + if (tcsetattr_stdin_TCSANOW(&G.tty_attrs) < 0) bb_perror_msg_and_die("tcsetattr"); } -/* We manipulate termios this way: - * - first, we read existing termios settings - * - termios_init modifies some parts and sets it - * - auto_baud and/or BREAK processing can set different speed and set termios - * - termios_final again modifies some parts and sets termios before +/* We manipulate tty_attrs this way: + * - first, we read existing tty_attrs + * - init_tty_attrs modifies some parts and sets it + * - auto_baud and/or BREAK processing can set different speed and set tty attrs + * - finalize_tty_attrs again modifies some parts and sets tty attrs before * execing login */ -static void termios_init(int speed) +static void init_tty_attrs(int speed) { /* Try to drain output buffer, with 5 sec timeout. * Added on request from users of ~600 baud serial interface @@ -255,14 +261,14 @@ static void termios_init(int speed) /* Set speed if it wasn't specified as "0" on command line */ if (speed != B0) - cfsetspeed(&G.termios, speed); + cfsetspeed(&G.tty_attrs, speed); - /* Initial termios settings: 8-bit characters, raw mode, blocking i/o. + /* Initial settings: 8-bit characters, raw mode, blocking i/o. * Special characters are set after we have read the login name; all * reads will be done in raw mode anyway. */ /* Clear all bits except: */ - G.termios.c_cflag &= (0 + G.tty_attrs.c_cflag &= (0 /* 2 stop bits (1 otherwise) * Enable parity bit (both on input and output) * Odd parity (else even) @@ -280,42 +286,42 @@ static void termios_init(int speed) #endif ); /* Set: 8 bits; hang up (drop DTR) on last close; enable receive */ - G.termios.c_cflag |= CS8 | HUPCL | CREAD; + G.tty_attrs.c_cflag |= CS8 | HUPCL | CREAD; if (option_mask32 & F_LOCAL) { /* ignore Carrier Detect pin: * opens don't block when CD is low, * losing CD doesn't hang up processes whose ctty is this tty */ - G.termios.c_cflag |= CLOCAL; + G.tty_attrs.c_cflag |= CLOCAL; } #ifdef CRTSCTS if (option_mask32 & F_RTSCTS) - G.termios.c_cflag |= CRTSCTS; /* flow control using RTS/CTS pins */ + G.tty_attrs.c_cflag |= CRTSCTS; /* flow control using RTS/CTS pins */ #endif - G.termios.c_iflag = 0; - G.termios.c_lflag = 0; + G.tty_attrs.c_iflag = 0; + G.tty_attrs.c_lflag = 0; /* non-raw output; add CR to each NL */ - G.termios.c_oflag = OPOST | ONLCR; + G.tty_attrs.c_oflag = OPOST | ONLCR; - G.termios.c_cc[VMIN] = 1; /* block reads if < 1 char is available */ - G.termios.c_cc[VTIME] = 0; /* no timeout (reads block forever) */ + G.tty_attrs.c_cc[VMIN] = 1; /* block reads if < 1 char is available */ + G.tty_attrs.c_cc[VTIME] = 0; /* no timeout (reads block forever) */ #ifdef __linux__ - G.termios.c_line = 0; + G.tty_attrs.c_line = 0; #endif - set_termios(); + set_tty_attrs(); debug("term_io 2\n"); } -static void termios_final(void) +static void finalize_tty_attrs(void) { /* software flow control on output (stop sending if XOFF is recvd); * and on input (send XOFF when buffer is full) */ - G.termios.c_iflag |= IXON | IXOFF; + G.tty_attrs.c_iflag |= IXON | IXOFF; if (G.eol == '\r') { - G.termios.c_iflag |= ICRNL; /* map CR on input to NL */ + G.tty_attrs.c_iflag |= ICRNL; /* map CR on input to NL */ } /* Other bits in c_iflag: * IXANY Any recvd char enables output (any char is also a XON) @@ -342,7 +348,7 @@ static void termios_final(void) * echo kill char specially, not as ^c (ECHOKE controls how exactly); * erase all input via BS-SP-BS on kill char (else go to next line) */ - G.termios.c_lflag |= ICANON | ISIG | ECHO | ECHOE | ECHOK | ECHOKE; + G.tty_attrs.c_lflag |= ICANON | ISIG | ECHO | ECHOE | ECHOK | ECHOKE; /* Other bits in c_lflag: * XCASE Map uppercase to \lowercase [tried, doesn't work] * ECHONL Echo NL even if ECHO is not set @@ -360,17 +366,17 @@ static void termios_final(void) * (why "stty sane" unsets this bit?) */ - G.termios.c_cc[VINTR] = DEF_INTR; - G.termios.c_cc[VQUIT] = DEF_QUIT; - G.termios.c_cc[VEOF] = DEF_EOF; - G.termios.c_cc[VEOL] = DEF_EOL; + G.tty_attrs.c_cc[VINTR] = DEF_INTR; + G.tty_attrs.c_cc[VQUIT] = DEF_QUIT; + G.tty_attrs.c_cc[VEOF] = DEF_EOF; + G.tty_attrs.c_cc[VEOL] = DEF_EOL; #ifdef VSWTC - G.termios.c_cc[VSWTC] = DEF_SWITCH; + G.tty_attrs.c_cc[VSWTC] = DEF_SWITCH; #endif #ifdef VSWTCH - G.termios.c_cc[VSWTCH] = DEF_SWITCH; + G.tty_attrs.c_cc[VSWTCH] = DEF_SWITCH; #endif - G.termios.c_cc[VKILL] = DEF_KILL; + G.tty_attrs.c_cc[VKILL] = DEF_KILL; /* Other control chars: * VEOL2 * VERASE, VWERASE - (word) erase. we may set VERASE in get_logname @@ -380,7 +386,7 @@ static void termios_final(void) * VSTART, VSTOP - chars used for IXON/IXOFF */ - set_termios(); + set_tty_attrs(); } /* extract baud rate from modem status message */ @@ -403,8 +409,8 @@ static void auto_baud(void) * modem status messages is enabled. */ - G.termios.c_cc[VMIN] = 0; /* don't block reads (min read is 0 chars) */ - set_termios(); + G.tty_attrs.c_cc[VMIN] = 0; /* don't block reads (min read is 0 chars) */ + set_tty_attrs(); /* * Wait for a while, then read everything the modem has said so far and @@ -420,15 +426,15 @@ static void auto_baud(void) if (isdigit(*bp)) { speed = bcode(bp); if (speed > 0) - cfsetspeed(&G.termios, speed); + cfsetspeed(&G.tty_attrs, speed); break; } } } /* Restore terminal settings */ - G.termios.c_cc[VMIN] = 1; /* restore to value set by termios_init */ - set_termios(); + G.tty_attrs.c_cc[VMIN] = 1; /* restore to value set by init_tty_attrs */ + set_tty_attrs(); } /* get user name, establish parity, speed, erase, kill, eol; @@ -449,7 +455,7 @@ static char *get_logname(void) /* Write issue file and prompt */ #ifdef ISSUE if (!(option_mask32 & F_NOISSUE)) - print_login_issue(G.issue, G.tty); + print_login_issue(G.issue, G.tty_name); #endif print_login_prompt(); @@ -479,7 +485,7 @@ static char *get_logname(void) goto got_logname; case BS: case DEL: - G.termios.c_cc[VERASE] = c; + G.tty_attrs.c_cc[VERASE] = c; if (bp > G.line_buf) { full_write(STDOUT_FILENO, "\010 \010", 3); bp--; @@ -510,11 +516,17 @@ static char *get_logname(void) return G.line_buf; } +static void alarm_handler(int sig UNUSED_PARAM) +{ + finalize_tty_attrs(); + _exit(EXIT_SUCCESS); +} + int getty_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; int getty_main(int argc UNUSED_PARAM, char **argv) { int n; - pid_t pid; + pid_t pid, tsid; char *logname; INIT_G(); @@ -527,14 +539,35 @@ int getty_main(int argc UNUSED_PARAM, char **argv) /* Parse command-line arguments */ parse_args(argv); - logmode = LOGMODE_NONE; + /* Create new session and pgrp, lose controlling tty */ + pid = setsid(); /* this also gives us our pid :) */ + if (pid < 0) { + int fd; + /* :( + * docs/ctty.htm says: + * "This is allowed only when the current process + * is not a process group leader". + * Thus, setsid() will fail if we _already_ are + * a session leader - which is quite possible for getty! + */ + pid = getpid(); + if (getsid(0) != pid) + bb_perror_msg_and_die("setsid"); + /* Looks like we are already a session leader. + * In this case (setsid failed) we may still have ctty, + * and it may be different from tty we need to control! + * If we still have ctty, on Linux ioctl(TIOCSCTTY) + * (which we are going to call a bit later) always fails. + * Try to drop ctty now to prevent that. + */ + fd = open("/dev/tty", O_RDWR); + if (fd >= 0) { + ioctl(fd, TIOCNOTTY); + close(fd); + } + } - /* Create new session, lose controlling tty, if any */ - /* docs/ctty.htm says: - * "This is allowed only when the current process - * is not a process group leader" - is this a problem? */ - setsid(); - /* close stdio, and stray descriptors, just in case */ + /* Close stdio, and stray descriptors, just in case */ n = xopen(bb_dev_null, O_RDWR); /* dup2(n, 0); - no, we need to handle "getty - 9600" too */ xdup2(n, 1); @@ -558,13 +591,25 @@ int getty_main(int argc UNUSED_PARAM, char **argv) #endif /* Open the tty as standard input, if it is not "-" */ - /* If it's not "-" and not taken yet, it will become our ctty */ debug("calling open_tty\n"); open_tty(); - ndelay_off(0); + ndelay_off(STDIN_FILENO); debug("duping\n"); - xdup2(0, 1); - xdup2(0, 2); + xdup2(STDIN_FILENO, 1); + xdup2(STDIN_FILENO, 2); + + /* Steal ctty if we don't have it yet */ + tsid = tcgetsid(STDIN_FILENO); + if (tsid < 0 || pid != tsid) { + if (ioctl(STDIN_FILENO, TIOCSCTTY, /*force:*/ (long)1) < 0) + bb_perror_msg_and_die("TIOCSCTTY"); + } + +#ifdef __linux__ + /* Make ourself a foreground process group within our session */ + if (tcsetpgrp(STDIN_FILENO, pid) < 0) + bb_perror_msg_and_die("tcsetpgrp"); +#endif /* * The following ioctl will fail if stdin is not a tty, but also when @@ -574,25 +619,15 @@ int getty_main(int argc UNUSED_PARAM, char **argv) * by patching the SunOS kernel variable "zsadtrlow" to a larger value; * 5 seconds seems to be a good value. */ - if (tcgetattr(STDIN_FILENO, &G.termios) < 0) + if (tcgetattr(STDIN_FILENO, &G.tty_attrs) < 0) bb_perror_msg_and_die("tcgetattr"); - pid = getpid(); -#ifdef __linux__ -// FIXME: do we need this? Otherwise "-" case seems to be broken... - // /* Forcibly make fd 0 our controlling tty, even if another session - // * has it as a ctty. (Another session loses ctty). */ - // ioctl(STDIN_FILENO, TIOCSCTTY, (void*)1); - /* Make ourself a foreground process group within our session */ - tcsetpgrp(STDIN_FILENO, pid); -#endif - /* Update the utmp file. This tty is ours now! */ - update_utmp(pid, LOGIN_PROCESS, G.tty, "LOGIN", G.fakehost); + update_utmp(pid, LOGIN_PROCESS, G.tty_name, "LOGIN", G.fakehost); - /* Initialize the termios settings (raw mode, eight-bit, blocking i/o) */ - debug("calling termios_init\n"); - termios_init(G.speeds[0]); + /* Initialize tty attrs (raw mode, eight-bit, blocking i/o) */ + debug("calling init_tty_attrs\n"); + init_tty_attrs(G.speeds[0]); /* Write the modem init string and DON'T flush the buffers */ if (option_mask32 & F_INITSTRING) { @@ -606,8 +641,8 @@ int getty_main(int argc UNUSED_PARAM, char **argv) auto_baud(); /* Set the optional timer */ + signal(SIGALRM, alarm_handler); alarm(G.timeout); /* if 0, alarm is not set */ -//BUG: death by signal won't restore termios /* Optionally wait for CR or LF before writing /etc/issue */ if (option_mask32 & F_WAITCRLF) { @@ -622,7 +657,7 @@ int getty_main(int argc UNUSED_PARAM, char **argv) logname = NULL; if (!(option_mask32 & F_NOPROMPT)) { - /* NB: termios_init already set line speed + /* NB: init_tty_attrs already set line speed * to G.speeds[0] */ int baud_index = 0; @@ -634,16 +669,15 @@ int getty_main(int argc UNUSED_PARAM, char **argv) break; /* We are here only if G.numspeed > 1 */ baud_index = (baud_index + 1) % G.numspeed; - cfsetspeed(&G.termios, G.speeds[baud_index]); - set_termios(); + cfsetspeed(&G.tty_attrs, G.speeds[baud_index]); + set_tty_attrs(); } } /* Disable timer */ alarm(0); - /* Finalize the termios settings */ - termios_final(); + finalize_tty_attrs(); /* Now the newline character should be properly written */ full_write(STDOUT_FILENO, "\n", 1); diff --git a/loginutils/login.c b/loginutils/login.c index 534343129..b54beef6e 100644 --- a/loginutils/login.c +++ b/loginutils/login.c @@ -41,6 +41,13 @@ enum { TTYNAME_SIZE = 32, }; +struct globals { + struct termios tty_attrs; +} FIX_ALIASING; +#define G (*(struct globals*)&bb_common_bufsiz1) +#define INIT_G() do { } while (0) + + #if ENABLE_FEATURE_NOLOGIN static void die_if_nologin(void) { @@ -206,15 +213,21 @@ static void motd(void) static void alarm_handler(int sig UNUSED_PARAM) { - /* This is the escape hatch! Poor serial line users and the like + /* This is the escape hatch! Poor serial line users and the like * arrive here when their connection is broken. * We don't want to block here */ - ndelay_on(1); - printf("\r\nLogin timed out after %d seconds\r\n", TIMEOUT); + ndelay_on(STDOUT_FILENO); + /* Test for correct attr restoring: + * run "getty 0 -" from a shell, enter bogus username, stop at + * password prompt, let it time out. Without the tcsetattr below, + * when you are back at shell prompt, echo will be still off. + */ + tcsetattr_stdin_TCSANOW(&G.tty_attrs); + printf("\r\nLogin timed out after %u seconds\r\n", TIMEOUT); fflush_all(); /* unix API is brain damaged regarding O_NONBLOCK, * we should undo it, or else we can affect other processes */ - ndelay_off(1); + ndelay_off(STDOUT_FILENO); _exit(EXIT_SUCCESS); } @@ -250,9 +263,7 @@ int login_main(int argc UNUSED_PARAM, char **argv) pid_t child_pid; #endif - username[0] = '\0'; - signal(SIGALRM, alarm_handler); - alarm(TIMEOUT); + INIT_G(); /* More of suid paranoia if called by non-root: */ /* Clear dangerous stuff, set PATH */ @@ -264,6 +275,7 @@ int login_main(int argc UNUSED_PARAM, char **argv) * (The name of the function is misleading. Not daemonizing here.) */ bb_daemonize_or_rexec(DAEMON_ONLY_SANITIZE | DAEMON_CLOSE_EXTRA_FDS, NULL); + username[0] = '\0'; opt = getopt32(argv, "f:h:p", &opt_user, &opt_host); if (opt & LOGIN_OPT_f) { if (!run_by_root) @@ -274,9 +286,19 @@ int login_main(int argc UNUSED_PARAM, char **argv) if (argv[0]) /* user from command line (getty) */ safe_strncpy(username, argv[0], sizeof(username)); - /* Let's find out and memorize our tty */ - if (!isatty(STDIN_FILENO) || !isatty(STDOUT_FILENO) || !isatty(STDERR_FILENO)) + /* Save tty attributes - and by doing it, check that it's indeed a tty */ + if (tcgetattr(STDIN_FILENO, &G.tty_attrs) < 0 + || !isatty(STDOUT_FILENO) + /*|| !isatty(STDERR_FILENO) - no, guess some people might want to redirect this */ + ) { return EXIT_FAILURE; /* Must be a terminal */ + } + + /* We install timeout handler only _after_ we saved G.tty_attrs */ + signal(SIGALRM, alarm_handler); + alarm(TIMEOUT); + + /* Find out and memorize our tty name */ full_tty = xmalloc_ttyname(STDIN_FILENO); if (!full_tty) full_tty = xstrdup("UNKNOWN"); @@ -391,7 +413,10 @@ int login_main(int argc UNUSED_PARAM, char **argv) if (!pw->pw_passwd[0]) break; fake_it: - /* authorization takes place here */ + /* Password reading and authorization takes place here. + * Note that reads (in no-echo mode) trash tty attributes. + * If we get interrupted by SIGALRM, we need to restore attrs. + */ if (correct_password(pw)) break; #endif /* ENABLE_PAM */ -- cgit v1.2.3-55-g6feb From 94354154c475c92ea6fa0cd0b989bce29d031013 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Sat, 22 Oct 2011 06:30:48 +0200 Subject: getty: remove now not needed resetting of ALRM to to SIG_DFL Signed-off-by: Denys Vlasenko --- loginutils/getty.c | 1 - 1 file changed, 1 deletion(-) diff --git a/loginutils/getty.c b/loginutils/getty.c index 168ae4de1..230846008 100644 --- a/loginutils/getty.c +++ b/loginutils/getty.c @@ -254,7 +254,6 @@ static void init_tty_attrs(int speed) alarm(5); tcdrain(STDIN_FILENO); alarm(0); - signal(SIGALRM, SIG_DFL); /* do not break -t TIMEOUT! */ /* Flush input and output queues, important for modems! */ tcflush(STDIN_FILENO, TCIOFLUSH); -- cgit v1.2.3-55-g6feb From a241069004717c6bef0a4abdf515c0ed1b9304c9 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Sat, 22 Oct 2011 06:39:00 +0200 Subject: remove duplicate include Signed-off-by: Denys Vlasenko --- util-linux/swaponoff.c | 1 - 1 file changed, 1 deletion(-) diff --git a/util-linux/swaponoff.c b/util-linux/swaponoff.c index b3057b309..54867ec36 100644 --- a/util-linux/swaponoff.c +++ b/util-linux/swaponoff.c @@ -24,7 +24,6 @@ #include "libbb.h" #include -#include #ifndef __BIONIC__ # include #endif -- cgit v1.2.3-55-g6feb From e206a4de4c700230f3dc9fdaa101c6f4432e1c27 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Sat, 22 Oct 2011 08:19:42 +0200 Subject: getty: add O_NONBLOCK to open which is used to drop ctty Signed-off-by: Denys Vlasenko --- loginutils/getty.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/loginutils/getty.c b/loginutils/getty.c index 230846008..3496f0284 100644 --- a/loginutils/getty.c +++ b/loginutils/getty.c @@ -556,10 +556,12 @@ int getty_main(int argc UNUSED_PARAM, char **argv) * In this case (setsid failed) we may still have ctty, * and it may be different from tty we need to control! * If we still have ctty, on Linux ioctl(TIOCSCTTY) - * (which we are going to call a bit later) always fails. - * Try to drop ctty now to prevent that. + * (which we are going to use a bit later) always fails - + * even if we try to take ctty which is already ours! + * Try to drop old ctty now to prevent that. + * Use O_NONBLOCK: old ctty may be a serial line. */ - fd = open("/dev/tty", O_RDWR); + fd = open("/dev/tty", O_RDWR | O_NONBLOCK); if (fd >= 0) { ioctl(fd, TIOCNOTTY); close(fd); -- cgit v1.2.3-55-g6feb From ee320c6d9cd0781233ed599d743b4da94b4424a7 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Sun, 23 Oct 2011 18:05:58 +0200 Subject: getty: reset tty attrs on Ctrl-C and Ctrl-D too Signed-off-by: Denys Vlasenko --- loginutils/getty.c | 2 ++ networking/udhcp/dhcpc.c | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/loginutils/getty.c b/loginutils/getty.c index 3496f0284..32735642b 100644 --- a/loginutils/getty.c +++ b/loginutils/getty.c @@ -465,6 +465,7 @@ static char *get_logname(void) /* Do not report trivial EINTR/EIO errors */ errno = EINTR; /* make read of 0 bytes be silent too */ if (read(STDIN_FILENO, &c, 1) < 1) { + finalize_tty_attrs(); if (errno == EINTR || errno == EIO) exit(EXIT_SUCCESS); bb_perror_msg_and_die(bb_msg_read_error); @@ -497,6 +498,7 @@ static char *get_logname(void) } break; case CTL('D'): + finalize_tty_attrs(); exit(EXIT_SUCCESS); default: if ((unsigned char)c < ' ') { diff --git a/networking/udhcp/dhcpc.c b/networking/udhcp/dhcpc.c index 7cd0b7bcb..3d4c397ff 100644 --- a/networking/udhcp/dhcpc.c +++ b/networking/udhcp/dhcpc.c @@ -1548,7 +1548,7 @@ int udhcpc_main(int argc UNUSED_PARAM, char **argv) * * We think that real server IP (one to use in renew/release) * is one in Server-ID option. But I am not 100% sure. - * IP header's src and Gateway-IP (same in this exaqmple) + * IP header's src and Gateway-IP (same in this example) * might work too. * "Next server" and router are definitely wrong ones to use, though... */ -- cgit v1.2.3-55-g6feb From e9dc354df86e9a3026de406520f6cd03a3519495 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Sun, 23 Oct 2011 23:58:59 +0200 Subject: getty: fix a minor problem of Ctrl-D not printing '\n' Also removed defines for control chars which are never changed, and added login/getty README. Signed-off-by: Denys Vlasenko --- loginutils/README | 70 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ loginutils/getty.c | 59 +++++++++++++++++++-------------------------- loginutils/login.c | 1 - 3 files changed, 94 insertions(+), 36 deletions(-) create mode 100644 loginutils/README diff --git a/loginutils/README b/loginutils/README new file mode 100644 index 000000000..ce8851097 --- /dev/null +++ b/loginutils/README @@ -0,0 +1,70 @@ + Getty + +??? Should getty open tty with or without O_NONBLOCK? +For serial lines, it means "should getty wait for Carrier Detect pin?" +I checked other getties: + +- agetty always uses O_NONBLOCK +- mgetty uses O_NONBLOCK unless run with -b, or as "getty" + +??? If we decided to use O_NONBLOCK (perhaps optionally with -b), +when getty should send -I INITSTR data to tty? After open succeeds? +What if we also want to initialize *modem* with some AT commands? + +??? Should we check/create /var/lock/LCK..ttyPFX lockfiles? + +??? mgetty opens tty but does NOT lock it, then waits for input via +select/poll, and when input is available, it checks lock file. +If it exists, mgetty exits (it assumes someone else uses the line). +If no, it creates the file (lock the tty). Sounds like a good algorithm +to use if we are called with -w... + +Getty should establish a new session and process group, and ensure +that tty is a ctty. + +??? Should getty ensure that other processes which might have opened +fds to this tty be dusconnected? agetty has a -R option which makes +agetty call vhangup() after tty is opened. (Then agetty opens it again, +since it probably vhangup'ed its own fd too). + +Getty should leave the tty in approximately the same state as "stty sane" +before it execs login program. Minor things we do conditionally are: + c_iflag |= ICRNL; // if '\r' was used to end username + +??? mgetty uses per-tty file to ignore connects, /etc/nologin.ttyxx - +is it useful? + +It should be possible to run "getty 0 -" from a shell prompt. +[This currently doesn't work from interactive shell since setsid() +fails in process group leader. The workaround is to run it as a child +of something. sh -c 'getty - 0; true' usually works. Should we fix this?] +It should leave tty in a sane state when it exits (Ctrl-D, -t SEC timeout): +echo should be on, speed, control chars properly set, etc. +(However, it can't restore ctty. The symptom is that " 1) - return NULL; - - /* Do erase, kill and end-of-line processing */ switch (c) { case '\r': case '\n': *bp = '\0'; G.eol = c; goto got_logname; - case BS: - case DEL: + case CTL('H'): + case 0x7f: G.tty_attrs.c_cc[VERASE] = c; if (bp > G.line_buf) { full_write(STDOUT_FILENO, "\010 \010", 3); @@ -497,9 +482,16 @@ static char *get_logname(void) bp--; } break; + case CTL('C'): case CTL('D'): finalize_tty_attrs(); exit(EXIT_SUCCESS); + case '\0': + /* BREAK. If we have speeds to try, + * return NULL (will switch speeds and return here) */ + if (G.numspeed > 1) + return NULL; + /* fall through and ignore it */ default: if ((unsigned char)c < ' ') { /* ignore garbage characters */ @@ -512,7 +504,7 @@ static char *get_logname(void) } } /* end of get char loop */ got_logname: ; - } /* while logname is empty */ + } while (G.line_buf[0] == '\0'); /* while logname is empty */ return G.line_buf; } @@ -682,9 +674,6 @@ int getty_main(int argc UNUSED_PARAM, char **argv) finalize_tty_attrs(); - /* Now the newline character should be properly written */ - full_write(STDOUT_FILENO, "\n", 1); - /* Let the login program take care of password validation */ /* We use PATH because we trust that root doesn't set "bad" PATH, * and getty is not suid-root applet */ diff --git a/loginutils/login.c b/loginutils/login.c index b54beef6e..73db8fa63 100644 --- a/loginutils/login.c +++ b/loginutils/login.c @@ -443,7 +443,6 @@ int login_main(int argc UNUSED_PARAM, char **argv) if (pw->pw_uid != 0) die_if_nologin(); - #if ENABLE_LOGIN_SESSION_AS_CHILD child_pid = vfork(); if (child_pid != 0) { -- cgit v1.2.3-55-g6feb From ec447c7f01acb0e3abd9daa52a1b616be3f39484 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Mon, 24 Oct 2011 04:06:18 +0200 Subject: libbb.h: remove unused defines Signed-off-by: Denys Vlasenko --- include/libbb.h | 7 ------- libbb/vdprintf.c | 4 ++-- 2 files changed, 2 insertions(+), 9 deletions(-) diff --git a/include/libbb.h b/include/libbb.h index f0f54ef82..d248781c3 100644 --- a/include/libbb.h +++ b/include/libbb.h @@ -254,13 +254,6 @@ typedef unsigned long uoff_t; #undef SKIP #define SKIP ((int) 2) -/* for mtab.c */ -#define MTAB_GETMOUNTPT '1' -#define MTAB_GETDEVICE '2' - -#define BUF_SIZE 8192 -#define EXPAND_ALLOC 1024 - /* Macros for min/max. */ #ifndef MIN #define MIN(a,b) (((a)<(b))?(a):(b)) diff --git a/libbb/vdprintf.c b/libbb/vdprintf.c index feeb403a0..05426873e 100644 --- a/libbb/vdprintf.c +++ b/libbb/vdprintf.c @@ -12,10 +12,10 @@ #if defined(__GLIBC__) && __GLIBC__ < 2 int FAST_FUNC vdprintf(int d, const char *format, va_list ap) { - char buf[BUF_SIZE]; + char buf[8 * 1024]; int len; - len = vsnprintf(buf, BUF_SIZE, format, ap); + len = vsnprintf(buf, sizeof(buf), format, ap); return write(d, buf, len); } #endif -- cgit v1.2.3-55-g6feb From 328f27fe447761f355104e7f524dc1115f16ca44 Mon Sep 17 00:00:00 2001 From: Leonid Lisovskiy Date: Fri, 28 Oct 2011 13:59:04 +0200 Subject: libbb: split decode_base64 off read_base64 function old new delta decode_base64 - 182 +182 read_base64 378 255 -123 ------------------------------------------------------------------------------ (add/remove: 1/0 grow/shrink: 0/1 up/down: 182/-123) Total: 59 bytes Signed-off-by: Leonid Lisovskiy Signed-off-by: Denys Vlasenko --- include/libbb.h | 3 +- libbb/uuencode.c | 125 +++++++++++++++++++++++++++++++++++++---------- testsuite/uuencode.tests | 101 ++++++++++++++++++++++++++++++++++++-- 3 files changed, 200 insertions(+), 29 deletions(-) diff --git a/include/libbb.h b/include/libbb.h index d248781c3..791cdd94e 100644 --- a/include/libbb.h +++ b/include/libbb.h @@ -1591,7 +1591,8 @@ enum { /* Sign-extends to a value which never matches fgetc result: */ BASE64_FLAG_NO_STOP_CHAR = 0x80, }; -void FAST_FUNC read_base64(FILE *src_stream, FILE *dst_stream, int flags); +const char *decode_base64(char **pp_dst, const char *src) FAST_FUNC; +void read_base64(FILE *src_stream, FILE *dst_stream, int flags) FAST_FUNC; typedef struct md5_ctx_t { uint8_t wbuffer[64]; /* always correctly aligned for uint64_t */ diff --git a/libbb/uuencode.c b/libbb/uuencode.c index 03e708fd5..23e2123bc 100644 --- a/libbb/uuencode.c +++ b/libbb/uuencode.c @@ -73,23 +73,23 @@ void FAST_FUNC bb_uuencode(char *p, const void *src, int length, const char *tbl } /* - * Decode base64 encoded stream. - * Can stop on EOF, specified char, or on uuencode-style "====" line: - * flags argument controls it. + * Decode base64 encoded string. Stops on '\0'. + * + * Returns: pointer to the undecoded part of source. + * If points to '\0', then the source was fully decoded. + * (*dst): advanced past the last written byte. */ -void FAST_FUNC read_base64(FILE *src_stream, FILE *dst_stream, int flags) +const char* FAST_FUNC decode_base64(char **pp_dst, const char *src) { -/* Note that EOF _can_ be passed as exit_char too */ -#define exit_char ((int)(signed char)flags) -#define uu_style_end (flags & BASE64_FLAG_UU_STOP) - - int term_count = 0; + char *dst = *pp_dst; + const char *src_tail; while (1) { unsigned char translated[4]; int count = 0; /* Process one group of 4 chars */ + src_tail = src; while (count < 4) { char *table_ptr; int ch; @@ -101,11 +101,20 @@ void FAST_FUNC read_base64(FILE *src_stream, FILE *dst_stream, int flags) * "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=\n" */ do { - ch = fgetc(src_stream); - if (ch == exit_char && count == 0) - return; - if (ch == EOF) - bb_error_msg_and_die("truncated base64 input"); + ch = *src; + if (ch == '\0') { + if (count == 0) { + /* Example: + * If we decode "QUJD ", we want + * to return ptr to NUL, not to ' ', + * because we did fully decode + * the string (to "ABC"). + */ + src_tail = src; + } + goto ret; + } + src++; table_ptr = strchr(bb_uuenc_tbl_base64, ch); //TODO: add BASE64_FLAG_foo to die on bad char? //Note that then we may need to still allow '\r' (for mail processing) @@ -114,21 +123,15 @@ void FAST_FUNC read_base64(FILE *src_stream, FILE *dst_stream, int flags) /* Convert encoded character to decimal */ ch = table_ptr - bb_uuenc_tbl_base64; - if (ch == 65 /* '\n' */) { - /* Terminating "====" line? */ - if (uu_style_end && term_count == 4) - return; /* yes */ - term_count = 0; + if (ch == 65) { /* '\n' */ continue; } /* ch is 64 if char was '=', otherwise 0..63 */ translated[count] = ch & 63; /* 64 -> 0 */ - if (ch == 64) { - term_count++; + if (ch == 64) { /* '=' */ break; } count++; - term_count = 0; } /* Merge 6 bit chars to 8 bit. @@ -136,10 +139,82 @@ void FAST_FUNC read_base64(FILE *src_stream, FILE *dst_stream, int flags) * "eQ==" -> "y", not "y NUL NUL" */ if (count > 1) - fputc(translated[0] << 2 | translated[1] >> 4, dst_stream); + *dst++ = translated[0] << 2 | translated[1] >> 4; if (count > 2) - fputc(translated[1] << 4 | translated[2] >> 2, dst_stream); + *dst++ = translated[1] << 4 | translated[2] >> 2; if (count > 3) - fputc(translated[2] << 6 | translated[3], dst_stream); + *dst++ = translated[2] << 6 | translated[3]; } /* while (1) */ + ret: + *pp_dst = dst; + return src_tail; +} + +/* + * Decode base64 encoded stream. + * Can stop on EOF, specified char, or on uuencode-style "====" line: + * flags argument controls it. + */ +void FAST_FUNC read_base64(FILE *src_stream, FILE *dst_stream, int flags) +{ +/* Note that EOF _can_ be passed as exit_char too */ +#define exit_char ((int)(signed char)flags) +#define uu_style_end (flags & BASE64_FLAG_UU_STOP) + + /* uuencoded files have 61 byte lines. Use 64 byte buffer + * to process line at a time. + */ + enum { BUFFER_SIZE = 64 }; + + char in_buf[BUFFER_SIZE + 2]; + char out_buf[BUFFER_SIZE / 4 * 3 + 2]; + char *out_tail; + const char *in_tail; + int term_seen = 0; + int in_count = 0; + + while (1) { + while (in_count < BUFFER_SIZE) { + int ch = fgetc(src_stream); + if (ch == exit_char) { + if (in_count == 0) + return; + term_seen = 1; + break; + } + if (ch == EOF) { + term_seen = 1; + break; + } + /* Prevent "====" line to be split: stop if we see '\n'. + * We can also skip other whitespace and skirt the problem + * of files with NULs by stopping on any control char or space: + */ + if (ch <= ' ') + break; + in_buf[in_count++] = ch; + } + in_buf[in_count] = '\0'; + + /* Did we encounter "====" line? */ + if (uu_style_end && strcmp(in_buf, "====") == 0) + return; + + out_tail = out_buf; + in_tail = decode_base64(&out_tail, in_buf); + + fwrite(out_buf, (out_tail - out_buf), 1, dst_stream); + + if (term_seen) { + /* Did we consume ALL characters? */ + if (*in_tail == '\0') + return; + /* No */ + bb_error_msg_and_die("truncated base64 input"); + } + + /* It was partial decode */ + in_count = strlen(in_tail); + memmove(in_buf, in_tail, in_count); + } } diff --git a/testsuite/uuencode.tests b/testsuite/uuencode.tests index cd6191b1b..6ce70f747 100755 --- a/testsuite/uuencode.tests +++ b/testsuite/uuencode.tests @@ -8,9 +8,9 @@ . ./testing.sh -# testing "test name" "options" "expected result" "file input" "stdin" -# file input will be file called "input" -# test can create a file "actual" instead of writing to stdout +# testing "test name" "command(s)" "expected result" "file input" "stdin" +# file input will be file called "input" +# test can create a file "actual" instead of writing to stdout # Test setup of standard input umask 0 @@ -24,4 +24,99 @@ testing "uuencode correct encoding" "uuencode bb_uuenc_test.out" \ testing "uuencode correct base64 encoding" "uuencode -m bb_uuenc_test.out" \ "begin-base64 644 bb_uuenc_test.out\nVGhlIGZhc3QgZ3JleSBmb3gganVtcGVkIG92ZXIgdGhlIGxhenkgYnJvd24g\nZG9nLgo=\n====\n" \ "" "The fast grey fox jumped over the lazy brown dog.\n" + +testing "uuencode empty file" 'r=`uuencode FILE`; echo "$r"; echo "$r" | uudecode -o -;' \ +'begin 644 FILE +` +end +' "" "" +testing "uuencode -m empty file" 'r=`uuencode -m FILE`; echo "$r"; echo "$r" | uudecode -o -;' \ +'begin-base64 644 FILE +==== +' "" "" + +testing "uuencode file 'A'" 'r=`uuencode FILE`; echo "$r"; echo "$r" | uudecode -o -;' \ +'begin 644 FILE +!00`` +` +end +A' "" "A" +testing "uuencode -m file 'A'" 'r=`uuencode -m FILE`; echo "$r"; echo "$r" | uudecode -o -;' \ +'begin-base64 644 FILE +QQ== +==== +A' "" "A" + +testing "uuencode file 'AB'" 'r=`uuencode FILE`; echo "$r"; echo "$r" | uudecode -o -;' \ +'begin 644 FILE +"04(` +` +end +AB' "" "AB" +testing "uuencode -m file 'AB'" 'r=`uuencode -m FILE`; echo "$r"; echo "$r" | uudecode -o -;' \ +'begin-base64 644 FILE +QUI= +==== +AB' "" "AB" + +testing "uuencode file 'ABC'" 'r=`uuencode FILE`; echo "$r"; echo "$r" | uudecode -o -;' \ +'begin 644 FILE +#04)# +` +end +ABC' "" "ABC" +testing "uuencode -m file 'ABC'" 'r=`uuencode -m FILE`; echo "$r"; echo "$r" | uudecode -o -;' \ +'begin-base64 644 FILE +QUJD +==== +ABC' "" "ABC" + +testing "uuencode file 'ABCD'" 'r=`uuencode FILE`; echo "$r"; echo "$r" | uudecode -o -;' \ +'begin 644 FILE +$04)#1``` +` +end +ABCD' "" "ABCD" +testing "uuencode -m file 'ABCD'" 'r=`uuencode -m FILE`; echo "$r"; echo "$r" | uudecode -o -;' \ +'begin-base64 644 FILE +QUJDRA== +==== +ABCD' "" "ABCD" + +testing "uuencode file 'ABCDE'" 'r=`uuencode FILE`; echo "$r"; echo "$r" | uudecode -o -;' \ +'begin 644 FILE +%04)#1$4` +` +end +ABCDE' "" "ABCDE" +testing "uuencode -m file 'ABCDE'" 'r=`uuencode -m FILE`; echo "$r"; echo "$r" | uudecode -o -;' \ +'begin-base64 644 FILE +QUJDREU= +==== +ABCDE' "" "ABCDE" + +testing "uuencode file 'ABCDEF'" 'r=`uuencode FILE`; echo "$r"; echo "$r" | uudecode -o -;' \ +'begin 644 FILE +&04)#1$5& +` +end +ABCDEF' "" "ABCDEF" +testing "uuencode -m file 'ABCDEF'" 'r=`uuencode -m FILE`; echo "$r"; echo "$r" | uudecode -o -;' \ +'begin-base64 644 FILE +QUJDREVG +==== +ABCDEF' "" "ABCDEF" + +testing "uuencode file 'A<0xff>Z'" 'r=`uuencode FILE`; echo "$r"; echo "$r" | uudecode -o -;' \ +'begin 644 FILE +$00#_6@`` +` +end +A\x0\xffZ' "" "A\x0\xffZ" +testing "uuencode -m file 'A<0xff>Z'" 'r=`uuencode -m FILE`; echo "$r"; echo "$r" | uudecode -o -;' \ +'begin-base64 644 FILE +QQD/Wg== +==== +A\x0\xffZ' "" "A\x0\xffZ" + exit $FAILCOUNT -- cgit v1.2.3-55-g6feb From 73d249e704cfdf8632c120599c1ddfeceb81dd32 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Fri, 28 Oct 2011 14:07:44 +0200 Subject: whitespace fixes Signed-off-by: Denys Vlasenko --- coreutils/pwd.c | 2 +- libbb/uuencode.c | 2 +- miscutils/runlevel.c | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/coreutils/pwd.c b/coreutils/pwd.c index 9455975e7..bb3ad04fc 100644 --- a/coreutils/pwd.c +++ b/coreutils/pwd.c @@ -43,7 +43,7 @@ static int logical_getcwd(void) if (*p == '.') p++; /* we found "/.." */ if (*p == '\0' || *p == '/') - return 0; /* "/./" or "/../" component: bad */ + return 0; /* "/./" or "/../" component: bad */ } if (stat(wd, &st1) != 0) diff --git a/libbb/uuencode.c b/libbb/uuencode.c index 23e2123bc..46ca79654 100644 --- a/libbb/uuencode.c +++ b/libbb/uuencode.c @@ -203,7 +203,7 @@ void FAST_FUNC read_base64(FILE *src_stream, FILE *dst_stream, int flags) out_tail = out_buf; in_tail = decode_base64(&out_tail, in_buf); - fwrite(out_buf, (out_tail - out_buf), 1, dst_stream); + fwrite(out_buf, (out_tail - out_buf), 1, dst_stream); if (term_seen) { /* Did we consume ALL characters? */ diff --git a/miscutils/runlevel.c b/miscutils/runlevel.c index 9d38b791f..76231df22 100644 --- a/miscutils/runlevel.c +++ b/miscutils/runlevel.c @@ -11,7 +11,7 @@ * * initially busyboxified by Bernhard Reutner-Fischer */ - + //usage:#define runlevel_trivial_usage //usage: "[FILE]" //usage:#define runlevel_full_usage "\n\n" -- cgit v1.2.3-55-g6feb From e6094d95b5d5a1a4c76aff99d89c8a4f44c5d59a Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Fri, 28 Oct 2011 16:15:00 +0200 Subject: libbb: shrink base64 decoding a bit function old new delta bb_uuenc_tbl_base64 67 66 -1 decode_base64 182 161 -21 Signed-off-by: Denys Vlasenko --- libbb/uuencode.c | 42 +++++++++++++++++++++++------------------- 1 file changed, 23 insertions(+), 19 deletions(-) diff --git a/libbb/uuencode.c b/libbb/uuencode.c index 46ca79654..f7b248492 100644 --- a/libbb/uuencode.c +++ b/libbb/uuencode.c @@ -10,7 +10,7 @@ #include "libbb.h" /* Conversion table. for base 64 */ -const char bb_uuenc_tbl_base64[65 + 2] ALIGN1 = { +const char bb_uuenc_tbl_base64[65 + 1] ALIGN1 = { 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', @@ -20,7 +20,7 @@ const char bb_uuenc_tbl_base64[65 + 2] ALIGN1 = { 'w', 'x', 'y', 'z', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '+', '/', '=' /* termination character */, - '\n', '\0' /* needed for uudecode.c */ + '\0' /* needed for uudecode.c only */ }; const char bb_uuenc_tbl_std[65] ALIGN1 = { @@ -77,7 +77,7 @@ void FAST_FUNC bb_uuencode(char *p, const void *src, int length, const char *tbl * * Returns: pointer to the undecoded part of source. * If points to '\0', then the source was fully decoded. - * (*dst): advanced past the last written byte. + * (*pp_dst): advanced past the last written byte. */ const char* FAST_FUNC decode_base64(char **pp_dst, const char *src) { @@ -85,10 +85,10 @@ const char* FAST_FUNC decode_base64(char **pp_dst, const char *src) const char *src_tail; while (1) { - unsigned char translated[4]; + unsigned char six_bit[4]; int count = 0; - /* Process one group of 4 chars */ + /* Fetch up to four 6-bit values */ src_tail = src; while (count < 4) { char *table_ptr; @@ -97,8 +97,8 @@ const char* FAST_FUNC decode_base64(char **pp_dst, const char *src) /* Get next _valid_ character. * bb_uuenc_tbl_base64[] contains this string: * 0 1 2 3 4 5 6 - * 012345678901234567890123456789012345678901234567890123456789012345 - * "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=\n" + * 01234567890123456789012345678901234567890123456789012345678901234 + * "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=" */ do { ch = *src; @@ -117,33 +117,37 @@ const char* FAST_FUNC decode_base64(char **pp_dst, const char *src) src++; table_ptr = strchr(bb_uuenc_tbl_base64, ch); //TODO: add BASE64_FLAG_foo to die on bad char? -//Note that then we may need to still allow '\r' (for mail processing) } while (!table_ptr); /* Convert encoded character to decimal */ ch = table_ptr - bb_uuenc_tbl_base64; - if (ch == 65) { /* '\n' */ - continue; - } /* ch is 64 if char was '=', otherwise 0..63 */ - translated[count] = ch & 63; /* 64 -> 0 */ - if (ch == 64) { /* '=' */ + if (ch == 64) break; - } + six_bit[count] = ch; count++; } - /* Merge 6 bit chars to 8 bit. + /* Transform 6-bit values to 8-bit ones. * count can be < 4 when we decode the tail: - * "eQ==" -> "y", not "y NUL NUL" + * "eQ==" -> "y", not "y NUL NUL". + * Note that (count > 1) is always true, + * "x===" encoding is not valid: + * even a single zero byte encodes as "AA==". + * However, with current logic we come here with count == 1 + * when we decode "==" tail. */ if (count > 1) - *dst++ = translated[0] << 2 | translated[1] >> 4; + *dst++ = six_bit[0] << 2 | six_bit[1] >> 4; if (count > 2) - *dst++ = translated[1] << 4 | translated[2] >> 2; + *dst++ = six_bit[1] << 4 | six_bit[2] >> 2; if (count > 3) - *dst++ = translated[2] << 6 | translated[3]; + *dst++ = six_bit[2] << 6 | six_bit[3]; + /* Note that if we decode "AA==" and ate first '=', + * we just decoded one char (count == 2) and now we'll + * do the loop once more to decode second '='. + */ } /* while (1) */ ret: *pp_dst = dst; -- cgit v1.2.3-55-g6feb From 8de2e42201bb1b9054861d2f7645885a3b69642a Mon Sep 17 00:00:00 2001 From: Christian Engelmayer Date: Fri, 28 Oct 2011 18:12:42 +0200 Subject: syslogd: work around rename() not renaming hardlinks to themselves Function log_locally() within the syslogd can potentially lock up when restarting the daemon after a power loss in case the unplanned shutdown hit the rename operation during logfile rotation. While POSIX requires the rename operation to be atomic, many file systems such as JFFS2 implement the rename operation in 2 steps by linking the new name followed by unlinking the original name. In case of a power loss during the rename the system can end up with /var/log/messages and /var/log/messages.0 being 2 hard links to the same file. When the syslog daemon restarts in such a situation it will rediscover the need to rotate the log files, however, POSIX also requires that rename does nothing and reports success in case oldpath and newpath are existing hard links to the same file. Looping through reopen: by (O_CREAT | O_APPEND), the daemon eternally reopens the same file without succeeding to rotate. Signed-off-by: Christian Engelmayer Signed-off-by: Denys Vlasenko --- sysklogd/syslogd.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/sysklogd/syslogd.c b/sysklogd/syslogd.c index d36d09caf..fc380d9f9 100644 --- a/sysklogd/syslogd.c +++ b/sysklogd/syslogd.c @@ -594,6 +594,14 @@ static void log_locally(time_t now, char *msg, logFile_t *log_file) } /* newFile == "f.0" now */ rename(log_file->path, newFile); + /* Incredibly, if F and F.0 are hardlinks, POSIX + * _demands_ that rename returns 0 but does not + * remove F!!! + * (hardlinked F/F.0 pair was observed after + * power failure during rename()). + * Ensure old file is gone: + */ + unlink(log_file->path); #ifdef SYSLOGD_WRLOCK fl.l_type = F_UNLCK; fcntl(log_file->fd, F_SETLKW, &fl); -- cgit v1.2.3-55-g6feb From 83e34ac4b574fabd54a2d1a03063b263338ef03d Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Fri, 28 Oct 2011 18:25:38 +0200 Subject: makemime: fix -a option not taking parameter Signed-off-by: Denys Vlasenko --- mailutils/makemime.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mailutils/makemime.c b/mailutils/makemime.c index 4dc53a3b2..a9ff03d03 100644 --- a/mailutils/makemime.c +++ b/mailutils/makemime.c @@ -164,7 +164,7 @@ int makemime_main(int argc UNUSED_PARAM, char **argv) // parse options opt_complementary = "a::"; opts = getopt32(argv, - "c:e:o:C:N:a", //:m:j:", + "c:e:o:C:N:a:", //:m:j:", &G.content_type, NULL, &opt_output, &G.opt_charset, NULL, &opt_headers //, NULL, NULL ); //argc -= optind; -- cgit v1.2.3-55-g6feb From e504c245f7958369d53fd509c444772fb5737c82 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Sun, 30 Oct 2011 21:27:33 +0100 Subject: getty: Hurd has no CBAUD, work around that Signed-off-by: Denys Vlasenko --- loginutils/getty.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/loginutils/getty.c b/loginutils/getty.c index 4d5219725..1f417591b 100644 --- a/loginutils/getty.c +++ b/loginutils/getty.c @@ -266,7 +266,9 @@ static void init_tty_attrs(int speed) #ifdef CMSPAR | CMSPAR /* mark or space parity */ #endif +#ifdef CBAUD | CBAUD /* (output) baud rate */ +#endif #ifdef CBAUDEX | CBAUDEX /* (output) baud rate */ #endif -- cgit v1.2.3-55-g6feb From b076193f741740886a6771cfe7750adb58ce18a0 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Sun, 30 Oct 2011 22:07:36 +0100 Subject: modinfo: make it select PLATFORM_LINUX. Closes 4411 Signed-off-by: Denys Vlasenko --- modutils/modinfo.c | 1 + 1 file changed, 1 insertion(+) diff --git a/modutils/modinfo.c b/modutils/modinfo.c index 410b6fbe4..c0910ffed 100644 --- a/modutils/modinfo.c +++ b/modutils/modinfo.c @@ -13,6 +13,7 @@ //config:config MODINFO //config: bool "modinfo" //config: default y +//config: select PLATFORM_LINUX //config: help //config: Show information about a Linux Kernel module -- cgit v1.2.3-55-g6feb From c531b9a3e4a90fd7c91c78a6991e30bfe0134f34 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Mon, 31 Oct 2011 01:05:16 +0100 Subject: bzcat: fix unpacking of more than one file, and unpacking of zero-size bz2. Closes 4393 Signed-off-by: Denys Vlasenko --- archival/bbunzip.c | 7 ++- archival/libarchive/decompress_bunzip2.c | 9 +++- testsuite/bzcat.tests | 80 +++++++++++--------------------- testsuite/ls.mk_uni_tests | 0 4 files changed, 41 insertions(+), 55 deletions(-) mode change 100644 => 100755 testsuite/ls.mk_uni_tests diff --git a/archival/bbunzip.c b/archival/bbunzip.c index 9c1a73780..853c653c0 100644 --- a/archival/bbunzip.c +++ b/archival/bbunzip.c @@ -103,7 +103,9 @@ int FAST_FUNC bbunpack(char **argv, status = unpacker(&info); if (status < 0) exitcode = 1; - xclose(STDOUT_FILENO); /* with error check! */ + + if (!(option_mask32 & OPT_STDOUT)) + xclose(STDOUT_FILENO); /* with error check! */ if (filename) { char *del = new_name; @@ -143,6 +145,9 @@ int FAST_FUNC bbunpack(char **argv, } } while (*argv && *++argv); + if (option_mask32 & OPT_STDOUT) + xclose(STDOUT_FILENO); /* with error check! */ + return exitcode; } diff --git a/archival/libarchive/decompress_bunzip2.c b/archival/libarchive/decompress_bunzip2.c index cd3144743..c4640d489 100644 --- a/archival/libarchive/decompress_bunzip2.c +++ b/archival/libarchive/decompress_bunzip2.c @@ -752,7 +752,14 @@ unpack_bz2_stream(int src_fd, int dst_fd) } } - if (i != RETVAL_LAST_BLOCK) { + if (i != RETVAL_LAST_BLOCK + /* Observed case when i == RETVAL_OK: + * "bzcat z.bz2", where "z.bz2" is a bzipped zero-length file + * (to be exact, z.bz2 is exactly these 14 bytes: + * 42 5a 68 39 17 72 45 38 50 90 00 00 00 00). + */ + && i != RETVAL_OK + ) { bb_error_msg("bunzip error %d", i); break; } diff --git a/testsuite/bzcat.tests b/testsuite/bzcat.tests index 5b4f3f4b3..c1d384464 100755 --- a/testsuite/bzcat.tests +++ b/testsuite/bzcat.tests @@ -1,54 +1,28 @@ #!/bin/sh - -FAILCOUNT=0 - -ext=bz2 - -bb="busybox " - -unset LC_ALL -unset LC_MESSAGES -unset LANG -unset LANGUAGE - -hello_gz() { - # Gzipped "HELLO\n" - #_________________________ vvv vvv vvv vvv - mtime - $ECHO -ne "\x1f\x8b\x08\x00\x85\x1d\xef\x45\x02\x03\xf3\x70\xf5\xf1\xf1\xe7" - $ECHO -ne "\x02\x00\x6e\xd7\xac\xfd\x06\x00\x00\x00" -} - -hello_bz2() { - # Bzipped "HELLO\n" - $ECHO -ne "\x42\x5a\x68\x39\x31\x41\x59\x26\x53\x59\x5b\xb8\xe8\xa3\x00\x00" - $ECHO -ne "\x01\x44\x00\x00\x10\x02\x44\xa0\x00\x30\xcd\x00\xc3\x46\x29\x97" - $ECHO -ne "\x17\x72\x45\x38\x50\x90\x5b\xb8\xe8\xa3" -} - -prep() { - rm -f t* - hello_$ext >t1.$ext - hello_$ext >t2.$ext -} - -check() { - eval $2 >t_actual 2>&1 - if $ECHO -ne "$expected" | cmp - t_actual; then - echo "PASS: $1" - else - echo "FAIL: $1" - FAILCOUNT=$((FAILCOUNT + 1)) - fi -} - -mkdir testdir 2>/dev/null -( -cd testdir || { echo "cannot cd testdir!"; exit 1; } - -expected="HELLO\nok\n" -prep; check "bzcat: dont delete src" "${bb}bzcat t2.bz2; test -f t2.bz2 && echo ok" - -) -rm -rf testdir - -exit $((FAILCOUNT <= 255 ? FAILCOUNT : 255)) +# Copyright 2011 by Denys Vlasenko +# Licensed under GPLv2, see file LICENSE in this source tree. + +. ./testing.sh + +# testing "test name" "command" "expected result" "file input" "stdin" + +# "input" file is bzipped file with "a\n" data +testing "bzcat can print many files" \ +"$ECHO -ne '$hexdump' | bzcat input input; echo \$?" \ +"\ +a +a +0 +" "\ +\x42\x5a\x68\x39\x31\x41\x59\x26\x53\x59\x63\x3e\xd6\xe2\x00\x00\ +\x00\xc1\x00\x00\x10\x20\x00\x20\x00\x21\x00\x82\xb1\x77\x24\x53\ +\x85\x09\x06\x33\xed\x6e\x20\ +" "" + +# "input" file is bzipped zero byte file +testing "bzcat can handle compressed zero-length bzip2 files" \ +"$ECHO -ne '$hexdump' | bzcat input input; echo \$?" \ +"0\n" \ +"\x42\x5a\x68\x39\x17\x72\x45\x38\x50\x90\x00\x00\x00\x00" "" + +exit $FAILCOUNT diff --git a/testsuite/ls.mk_uni_tests b/testsuite/ls.mk_uni_tests old mode 100644 new mode 100755 -- cgit v1.2.3-55-g6feb From c0e37b4340da35d7d24720c55290a3efd3d78f11 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Mon, 31 Oct 2011 01:08:35 +0100 Subject: testsuite: fix the mishap in the previous commit Signed-off-by: Denys Vlasenko --- testsuite/bzcat.tests | 80 +++++++++++++++++++++++++++++++---------------- testsuite/bzcat2.tests | 28 +++++++++++++++++ testsuite/ls.mk_uni_tests | 0 3 files changed, 81 insertions(+), 27 deletions(-) create mode 100755 testsuite/bzcat2.tests mode change 100755 => 100644 testsuite/ls.mk_uni_tests diff --git a/testsuite/bzcat.tests b/testsuite/bzcat.tests index c1d384464..5b4f3f4b3 100755 --- a/testsuite/bzcat.tests +++ b/testsuite/bzcat.tests @@ -1,28 +1,54 @@ #!/bin/sh -# Copyright 2011 by Denys Vlasenko -# Licensed under GPLv2, see file LICENSE in this source tree. - -. ./testing.sh - -# testing "test name" "command" "expected result" "file input" "stdin" - -# "input" file is bzipped file with "a\n" data -testing "bzcat can print many files" \ -"$ECHO -ne '$hexdump' | bzcat input input; echo \$?" \ -"\ -a -a -0 -" "\ -\x42\x5a\x68\x39\x31\x41\x59\x26\x53\x59\x63\x3e\xd6\xe2\x00\x00\ -\x00\xc1\x00\x00\x10\x20\x00\x20\x00\x21\x00\x82\xb1\x77\x24\x53\ -\x85\x09\x06\x33\xed\x6e\x20\ -" "" - -# "input" file is bzipped zero byte file -testing "bzcat can handle compressed zero-length bzip2 files" \ -"$ECHO -ne '$hexdump' | bzcat input input; echo \$?" \ -"0\n" \ -"\x42\x5a\x68\x39\x17\x72\x45\x38\x50\x90\x00\x00\x00\x00" "" - -exit $FAILCOUNT + +FAILCOUNT=0 + +ext=bz2 + +bb="busybox " + +unset LC_ALL +unset LC_MESSAGES +unset LANG +unset LANGUAGE + +hello_gz() { + # Gzipped "HELLO\n" + #_________________________ vvv vvv vvv vvv - mtime + $ECHO -ne "\x1f\x8b\x08\x00\x85\x1d\xef\x45\x02\x03\xf3\x70\xf5\xf1\xf1\xe7" + $ECHO -ne "\x02\x00\x6e\xd7\xac\xfd\x06\x00\x00\x00" +} + +hello_bz2() { + # Bzipped "HELLO\n" + $ECHO -ne "\x42\x5a\x68\x39\x31\x41\x59\x26\x53\x59\x5b\xb8\xe8\xa3\x00\x00" + $ECHO -ne "\x01\x44\x00\x00\x10\x02\x44\xa0\x00\x30\xcd\x00\xc3\x46\x29\x97" + $ECHO -ne "\x17\x72\x45\x38\x50\x90\x5b\xb8\xe8\xa3" +} + +prep() { + rm -f t* + hello_$ext >t1.$ext + hello_$ext >t2.$ext +} + +check() { + eval $2 >t_actual 2>&1 + if $ECHO -ne "$expected" | cmp - t_actual; then + echo "PASS: $1" + else + echo "FAIL: $1" + FAILCOUNT=$((FAILCOUNT + 1)) + fi +} + +mkdir testdir 2>/dev/null +( +cd testdir || { echo "cannot cd testdir!"; exit 1; } + +expected="HELLO\nok\n" +prep; check "bzcat: dont delete src" "${bb}bzcat t2.bz2; test -f t2.bz2 && echo ok" + +) +rm -rf testdir + +exit $((FAILCOUNT <= 255 ? FAILCOUNT : 255)) diff --git a/testsuite/bzcat2.tests b/testsuite/bzcat2.tests new file mode 100755 index 000000000..c1d384464 --- /dev/null +++ b/testsuite/bzcat2.tests @@ -0,0 +1,28 @@ +#!/bin/sh +# Copyright 2011 by Denys Vlasenko +# Licensed under GPLv2, see file LICENSE in this source tree. + +. ./testing.sh + +# testing "test name" "command" "expected result" "file input" "stdin" + +# "input" file is bzipped file with "a\n" data +testing "bzcat can print many files" \ +"$ECHO -ne '$hexdump' | bzcat input input; echo \$?" \ +"\ +a +a +0 +" "\ +\x42\x5a\x68\x39\x31\x41\x59\x26\x53\x59\x63\x3e\xd6\xe2\x00\x00\ +\x00\xc1\x00\x00\x10\x20\x00\x20\x00\x21\x00\x82\xb1\x77\x24\x53\ +\x85\x09\x06\x33\xed\x6e\x20\ +" "" + +# "input" file is bzipped zero byte file +testing "bzcat can handle compressed zero-length bzip2 files" \ +"$ECHO -ne '$hexdump' | bzcat input input; echo \$?" \ +"0\n" \ +"\x42\x5a\x68\x39\x17\x72\x45\x38\x50\x90\x00\x00\x00\x00" "" + +exit $FAILCOUNT diff --git a/testsuite/ls.mk_uni_tests b/testsuite/ls.mk_uni_tests old mode 100755 new mode 100644 -- cgit v1.2.3-55-g6feb From bcdae638752d5eac9185f69b88f49ed136cf39af Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Mon, 31 Oct 2011 01:10:47 +0100 Subject: testsuite: merge bzcat2.tests into bzcat.tests Signed-off-by: Denys Vlasenko --- testsuite/bzcat.tests | 30 ++++++++++++++++++++++++++++++ testsuite/bzcat2.tests | 28 ---------------------------- 2 files changed, 30 insertions(+), 28 deletions(-) delete mode 100755 testsuite/bzcat2.tests diff --git a/testsuite/bzcat.tests b/testsuite/bzcat.tests index 5b4f3f4b3..1c1fd6563 100755 --- a/testsuite/bzcat.tests +++ b/testsuite/bzcat.tests @@ -51,4 +51,34 @@ prep; check "bzcat: dont delete src" "${bb}bzcat t2.bz2; test -f t2.bz2 && echo ) rm -rf testdir + + +# Copyright 2011 by Denys Vlasenko +# Licensed under GPLv2, see file LICENSE in this source tree. + +. ./testing.sh + +# testing "test name" "command" "expected result" "file input" "stdin" + +# "input" file is bzipped file with "a\n" data +testing "bzcat can print many files" \ +"$ECHO -ne '$hexdump' | bzcat input input; echo \$?" \ +"\ +a +a +0 +" "\ +\x42\x5a\x68\x39\x31\x41\x59\x26\x53\x59\x63\x3e\xd6\xe2\x00\x00\ +\x00\xc1\x00\x00\x10\x20\x00\x20\x00\x21\x00\x82\xb1\x77\x24\x53\ +\x85\x09\x06\x33\xed\x6e\x20\ +" "" + +# "input" file is bzipped zero byte file +testing "bzcat can handle compressed zero-length bzip2 files" \ +"$ECHO -ne '$hexdump' | bzcat input input; echo \$?" \ +"0\n" \ +"\x42\x5a\x68\x39\x17\x72\x45\x38\x50\x90\x00\x00\x00\x00" "" + + + exit $((FAILCOUNT <= 255 ? FAILCOUNT : 255)) diff --git a/testsuite/bzcat2.tests b/testsuite/bzcat2.tests deleted file mode 100755 index c1d384464..000000000 --- a/testsuite/bzcat2.tests +++ /dev/null @@ -1,28 +0,0 @@ -#!/bin/sh -# Copyright 2011 by Denys Vlasenko -# Licensed under GPLv2, see file LICENSE in this source tree. - -. ./testing.sh - -# testing "test name" "command" "expected result" "file input" "stdin" - -# "input" file is bzipped file with "a\n" data -testing "bzcat can print many files" \ -"$ECHO -ne '$hexdump' | bzcat input input; echo \$?" \ -"\ -a -a -0 -" "\ -\x42\x5a\x68\x39\x31\x41\x59\x26\x53\x59\x63\x3e\xd6\xe2\x00\x00\ -\x00\xc1\x00\x00\x10\x20\x00\x20\x00\x21\x00\x82\xb1\x77\x24\x53\ -\x85\x09\x06\x33\xed\x6e\x20\ -" "" - -# "input" file is bzipped zero byte file -testing "bzcat can handle compressed zero-length bzip2 files" \ -"$ECHO -ne '$hexdump' | bzcat input input; echo \$?" \ -"0\n" \ -"\x42\x5a\x68\x39\x17\x72\x45\x38\x50\x90\x00\x00\x00\x00" "" - -exit $FAILCOUNT -- cgit v1.2.3-55-g6feb From 156840c249ddf761d9e60b06ca6d8aaa1bf88402 Mon Sep 17 00:00:00 2001 From: Alexander Shishkin Date: Mon, 31 Oct 2011 13:18:44 +0100 Subject: cttyhack: print detected ctty name when called without parameters Sometimes there's a need to figure out the controlling tty from a shell script, for example, to obtain a line for getty. In this case it's easier to call cttyhack than trying to repeat some of the cttyhack's logic. function old new delta cttyhack_main 283 327 +44 packed_usage 28911 28915 +4 Signed-off-by: Alexander Shishkin Signed-off-by: Denys Vlasenko --- shell/cttyhack.c | 76 +++++++++++++++++++++++++++++++------------------------- 1 file changed, 42 insertions(+), 34 deletions(-) diff --git a/shell/cttyhack.c b/shell/cttyhack.c index 6241c76a9..640f5b1fb 100644 --- a/shell/cttyhack.c +++ b/shell/cttyhack.c @@ -50,9 +50,12 @@ //config: //config: # exec setsid sh -c 'exec sh /dev/tty1 2>&1' //config: +//config: Starting getty on a controlling tty from a shell script: +//config: +//config: # getty 115200 $(cttyhack) //usage:#define cttyhack_trivial_usage -//usage: "PROG ARGS" +//usage: "[PROG ARGS]" //usage:#define cttyhack_full_usage "\n\n" //usage: "Give PROG a controlling tty if possible." //usage: "\nExample for /etc/inittab (for busybox init):" @@ -108,61 +111,66 @@ int cttyhack_main(int argc UNUSED_PARAM, char **argv) char paranoia[sizeof(struct serial_struct) * 3]; } u; - if (!*++argv) { - bb_show_usage(); - } - strcpy(console, "/dev/tty"); fd = open(console, O_RDWR); - if (fd >= 0) { - /* We already have ctty, nothing to do */ - close(fd); - } else { + if (fd < 0) { /* We don't have ctty (or don't have "/dev/tty" node...) */ do { #ifdef __linux__ - int s = open_read_close("/sys/class/tty/console/active", - console + 5, sizeof(console) - 5); - if (s > 0) { - /* found active console via sysfs (Linux 2.6.38+) - * sysfs string looks like "ttyS0\n" so zap the newline: - */ - console[4 + s] = '\0'; - break; - } - + int s; if (ioctl(0, VT_GETSTATE, &u.vt) == 0) { /* this is linux virtual tty */ - sprintf(console + 8, "S%d" + 1, u.vt.v_active); + sprintf(console + 8, "S%u" + 1, (int)u.vt.v_active); break; } #endif #ifdef TIOCGSERIAL if (ioctl(0, TIOCGSERIAL, &u.sr) == 0) { /* this is a serial console; assuming it is named /dev/ttySn */ - sprintf(console + 8, "S%d", u.sr.line); + sprintf(console + 8, "S%u", (int)u.sr.line); + break; + } +#endif +#ifdef __linux__ + /* Note that this method is not related to _stdin_ */ + s = open_read_close("/sys/class/tty/console/active", + console + 5, sizeof(console) - 5); + if (s > 0) { + /* found active console via sysfs (Linux 2.6.38+) + * sysfs string looks like "ttyS0\n" so zap the newline: + */ + console[4 + s] = '\0'; break; } #endif /* nope, could not find it */ - goto ret; + console[0] = '\0'; } while (0); + } + argv++; + if (!argv[0]) { + if (!console[0]) + return EXIT_FAILURE; + puts(console); + return EXIT_SUCCESS; + } + + if (fd < 0) { fd = open_or_warn(console, O_RDWR); if (fd < 0) goto ret; - //bb_error_msg("switching to '%s'", console); - dup2(fd, 0); - dup2(fd, 1); - dup2(fd, 2); - while (fd > 2) - close(fd--); - /* Some other session may have it as ctty, - * steal it from them: - */ - ioctl(0, TIOCSCTTY, 1); } - -ret: + //bb_error_msg("switching to '%s'", console); + dup2(fd, 0); + dup2(fd, 1); + dup2(fd, 2); + while (fd > 2) + close(fd--); + /* Some other session may have it as ctty, + * try to steal it from them: + */ + ioctl(0, TIOCSCTTY, 1); + ret: BB_EXECVP_or_die(argv); } -- cgit v1.2.3-55-g6feb From f8a5b792ba3cb0d11531902a04600fc274dff69e Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Mon, 31 Oct 2011 16:57:04 +0100 Subject: cttyhack: move /sys/class/tty/console/active check to the front Signed-off-by: Denys Vlasenko --- shell/cttyhack.c | 31 ++++++++++++++++++------------- 1 file changed, 18 insertions(+), 13 deletions(-) diff --git a/shell/cttyhack.c b/shell/cttyhack.c index 640f5b1fb..6ff867413 100644 --- a/shell/cttyhack.c +++ b/shell/cttyhack.c @@ -117,7 +117,24 @@ int cttyhack_main(int argc UNUSED_PARAM, char **argv) /* We don't have ctty (or don't have "/dev/tty" node...) */ do { #ifdef __linux__ - int s; + /* Note that this method does not use _stdin_. + * Thus, "cttyhack 0) { + /* found active console via sysfs (Linux 2.6.38+) + * sysfs string looks like "ttyS0\n" so zap the newline: + */ + console[4 + s] = '\0'; + break; + } + if (ioctl(0, VT_GETSTATE, &u.vt) == 0) { /* this is linux virtual tty */ sprintf(console + 8, "S%u" + 1, (int)u.vt.v_active); @@ -130,18 +147,6 @@ int cttyhack_main(int argc UNUSED_PARAM, char **argv) sprintf(console + 8, "S%u", (int)u.sr.line); break; } -#endif -#ifdef __linux__ - /* Note that this method is not related to _stdin_ */ - s = open_read_close("/sys/class/tty/console/active", - console + 5, sizeof(console) - 5); - if (s > 0) { - /* found active console via sysfs (Linux 2.6.38+) - * sysfs string looks like "ttyS0\n" so zap the newline: - */ - console[4 + s] = '\0'; - break; - } #endif /* nope, could not find it */ console[0] = '\0'; -- cgit v1.2.3-55-g6feb From 3b1603410a29046e5dcabe1bdfc2dc109461111d Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Tue, 1 Nov 2011 23:34:46 +0100 Subject: nmeter: fix block i/o count on newer Linux kernels Signed-off-by: Denys Vlasenko --- procps/nmeter.c | 50 ++++++++++++++++++++++++++++++++++++++------------ 1 file changed, 38 insertions(+), 12 deletions(-) diff --git a/procps/nmeter.c b/procps/nmeter.c index 999955982..ed5479024 100644 --- a/procps/nmeter.c +++ b/procps/nmeter.c @@ -274,30 +274,56 @@ static int rdval_loadavg(const char* p, ullong *vec, ...) // 1 2 3 4 5 6(rd) 7 8 9 10(wr) 11 12 13 14 // 3 0 hda 51292 14441 841783 926052 25717 79650 843256 3029804 0 148459 3956933 // 3 1 hda1 0 0 0 0 <- ignore if only 4 fields +// Linux 3.0 (maybe earlier) started printing full stats for hda1 too. +// Had to add code which skips such devices. static int rdval_diskstats(const char* p, ullong *vec) { - ullong rd = rd; // for compiler - int indexline = 0; + char devname[32]; + unsigned devname_len = 0; + int value_idx = 0; + vec[0] = 0; vec[1] = 0; while (1) { - indexline++; - while (*p == ' ' || *p == '\t') p++; - if (*p == '\0') break; + value_idx++; + while (*p == ' ' || *p == '\t') + p++; + if (*p == '\0') + break; if (*p == '\n') { - indexline = 0; + value_idx = 0; p++; continue; } - if (indexline == 6) { - rd = strtoull(p, NULL, 10); - } else if (indexline == 10) { - vec[0] += rd; // TODO: *sectorsize (don't know how to find out sectorsize) + if (value_idx == 3) { + char *end = strchrnul(p, ' '); + /* If this a hda1-like device (same prefix as last one + digit)? */ + if (devname_len && strncmp(devname, p, devname_len) == 0 && isdigit(p[devname_len])) { + p = end; + goto skip_line; /* skip entire line */ + } + /* It is not. Remember the name for future checks */ + devname_len = end - p; + if (devname_len > sizeof(devname)-1) + devname_len = sizeof(devname)-1; + strncpy(devname, p, devname_len); + /* devname[devname_len] = '\0'; - not really needed */ + p = end; + } else + if (value_idx == 6) { + // TODO: *sectorsize (don't know how to find out sectorsize) + vec[0] += strtoull(p, NULL, 10); + } else + if (value_idx == 10) { + // TODO: *sectorsize (don't know how to find out sectorsize) vec[1] += strtoull(p, NULL, 10); - while (*p != '\n' && *p != '\0') p++; + skip_line: + while (*p != '\n' && *p != '\0') + p++; continue; } - while (*p > ' ') p++; // skip over value + while ((unsigned char)(*p) > ' ') // skip over value + p++; } return 0; } -- cgit v1.2.3-55-g6feb From f85554c26525ec2ddc860ccb1aadc05e7a3825f6 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Thu, 3 Nov 2011 09:54:53 +0100 Subject: mount: free commented /etc/filesystems lines when we read it Signed-off-by: Denys Vlasenko --- util-linux/mount.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/util-linux/mount.c b/util-linux/mount.c index 56276ef01..fddd7fba9 100644 --- a/util-linux/mount.c +++ b/util-linux/mount.c @@ -522,12 +522,13 @@ static llist_t *get_block_backed_filesystems(void) while ((buf = xmalloc_fgetline(f)) != NULL) { if (strncmp(buf, "nodev", 5) == 0 && isspace(buf[5])) - continue; + goto next; fs = skip_whitespace(buf); if (*fs == '#' || *fs == '*' || !*fs) - continue; + goto next; llist_add_to_end(&list, xstrdup(fs)); + next: free(buf); } if (ENABLE_FEATURE_CLEAN_UP) fclose(f); -- cgit v1.2.3-55-g6feb From b5ebe5fdb3a520114fc4f956687e2c51f3b81429 Mon Sep 17 00:00:00 2001 From: Karol Lewandowski Date: Thu, 3 Nov 2011 10:02:31 +0100 Subject: mount: handle list of comma-separated fs types in -t option Allows one to specify list of filesystem types to be tried when mounting particular device. E.g. mount -t vfat,ext2 ... Signed-off-by: Karol Lewandowski Signed-off-by: Denys Vlasenko --- util-linux/mount.c | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/util-linux/mount.c b/util-linux/mount.c index fddd7fba9..f94b6e643 100644 --- a/util-linux/mount.c +++ b/util-linux/mount.c @@ -38,7 +38,7 @@ //usage: ) //usage: "\n -r Read-only mount" //usage: "\n -w Read-write mount (default)" -//usage: "\n -t FSTYPE Filesystem type" +//usage: "\n -t FSTYPE[,...] Filesystem type(s)" //usage: "\n -O OPT Mount only filesystems with option OPT (-a only)" //usage: "\n-o OPT:" //usage: IF_FEATURE_MOUNT_LOOP( @@ -1827,7 +1827,16 @@ static int singlemount(struct mntent *mp, int ignore_busy) // If we know the fstype (or don't need to), jump straight // to the actual mount. if (mp->mnt_type || (vfsflags & (MS_REMOUNT | MS_BIND | MS_MOVE))) { - rc = mount_it_now(mp, vfsflags, filteropts); + char *next; + for (;;) { + next = mp->mnt_type ? strchr(mp->mnt_type, ',') : NULL; + if (next) + *next = '\0'; + rc = mount_it_now(mp, vfsflags, filteropts); + if (rc == 0 || !next) + break; + mp->mnt_type = next + 1; + } } else { // Loop through filesystem types until mount succeeds // or we run out @@ -1844,7 +1853,7 @@ static int singlemount(struct mntent *mp, int ignore_busy) for (fl = fslist; fl; fl = fl->link) { mp->mnt_type = fl->data; rc = mount_it_now(mp, vfsflags, filteropts); - if (!rc) + if (rc == 0) break; } } -- cgit v1.2.3-55-g6feb From f808e777db05bed7b3c0a4aa5f12121fb3d0ca5f Mon Sep 17 00:00:00 2001 From: Dan Fandrich Date: Thu, 3 Nov 2011 10:18:33 +0100 Subject: rx: Fix file corruption with duplicate blocks Rather than dropping the dupe, rx was appending it to the file. Signed-off-by: Dan Fandrich Signed-off-by: Denys Vlasenko --- miscutils/rx.c | 1 + 1 file changed, 1 insertion(+) diff --git a/miscutils/rx.c b/miscutils/rx.c index e1225779e..972f7ff37 100644 --- a/miscutils/rx.c +++ b/miscutils/rx.c @@ -172,6 +172,7 @@ static int receive(/*int read_fd, */int file_fd) /* a repeat of the last block is ok, just ignore it. */ /* this also ignores the initial block 0 which is */ /* meta data. */ + blockLength = 0; goto next; } if (blockNo != (wantBlockNo & 0xff)) { -- cgit v1.2.3-55-g6feb From f3efd3c2a08feaf6ed35fcadfa4cf131efe5e070 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Thu, 3 Nov 2011 10:19:53 +0100 Subject: rx: code shrink function old new delta rx_main 961 947 -14 Signed-off-by: Denys Vlasenko --- miscutils/rx.c | 20 +++++++------------- 1 file changed, 7 insertions(+), 13 deletions(-) diff --git a/miscutils/rx.c b/miscutils/rx.c index 972f7ff37..c48a61fd0 100644 --- a/miscutils/rx.c +++ b/miscutils/rx.c @@ -108,12 +108,10 @@ static int receive(/*int read_fd, */int file_fd) } } /* Write previously received block */ - if (blockLength) { - errno = 0; - if (full_write(file_fd, blockBuf, blockLength) != blockLength) { - bb_perror_msg("can't write to file"); - goto fatal; - } + errno = 0; + if (full_write(file_fd, blockBuf, blockLength) != blockLength) { + bb_perror_msg(bb_msg_write_error); + goto fatal; } timeout = TIMEOUT; @@ -155,17 +153,13 @@ static int receive(/*int read_fd, */int file_fd) blockBuf[i] = cc; } + cksum_or_crc = read_byte(TIMEOUT); + if (cksum_or_crc < 0) + goto timeout; if (do_crc) { - cksum_or_crc = read_byte(TIMEOUT); - if (cksum_or_crc < 0) - goto timeout; cksum_or_crc = (cksum_or_crc << 8) | read_byte(TIMEOUT); if (cksum_or_crc < 0) goto timeout; - } else { - cksum_or_crc = read_byte(TIMEOUT); - if (cksum_or_crc < 0) - goto timeout; } if (blockNo == ((wantBlockNo - 1) & 0xff)) { -- cgit v1.2.3-55-g6feb From 45cdf166dccb4981004bae822f52e48df05aab91 Mon Sep 17 00:00:00 2001 From: Daniel Fandrich Date: Thu, 3 Nov 2011 11:20:07 +0100 Subject: android build system updates Signed-off-by: Daniel Fandrich Signed-off-by: Denys Vlasenko --- configs/android_defconfig | 225 ++++++++++++++++++++++++---------------------- 1 file changed, 119 insertions(+), 106 deletions(-) diff --git a/configs/android_defconfig b/configs/android_defconfig index 76068b040..b9df0ea02 100644 --- a/configs/android_defconfig +++ b/configs/android_defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Busybox version: 1.19.0.git -# Wed Jun 29 12:01:57 2011 +# Busybox version: 1.20.0.git +# Wed Nov 2 17:54:00 2011 # CONFIG_HAVE_DOT_CONFIG=y @@ -12,7 +12,7 @@ CONFIG_HAVE_DOT_CONFIG=y # # General Configuration # -# CONFIG_DESKTOP is not set +CONFIG_DESKTOP=y # CONFIG_EXTRA_COMPAT is not set # CONFIG_INCLUDE_SUSv2 is not set # CONFIG_USE_PORTABLE_CODE is not set @@ -60,7 +60,7 @@ CONFIG_FEATURE_SYSLOG=y # CONFIG_BUILD_LIBBUSYBOX is not set # CONFIG_FEATURE_INDIVIDUAL is not set # CONFIG_FEATURE_SHARED_BUSYBOX is not set -# CONFIG_LFS is not set +CONFIG_LFS=y CONFIG_CROSS_COMPILER_PREFIX="arm-eabi-" # # Removed: @@ -70,6 +70,8 @@ CONFIG_CROSS_COMPILER_PREFIX="arm-eabi-" # -Werror=sequence-point -Wstrict-aliasing=2 -Wno-undef -Wno-shadow # bbox already adds these: # -ffunction-sections -fomit-frame-pointer +# enabled implicitly by -Os: +# -frerun-cse-after-loop # should be not needed, or even increases code size: # -finline-functions -fno-inline-functions-called-once -finline-limit=64 # -fstack-protector -fno-strict-aliasing -fno-exceptions -funwind-tables @@ -77,9 +79,8 @@ CONFIG_CROSS_COMPILER_PREFIX="arm-eabi-" # todo: do we need these? - # -fno-short-enums # -fgcse-after-reload -# -frerun-cse-after-loop # -frename-registers -CONFIG_EXTRA_CFLAGS="-I$A/system/core/include -I$A/bionic/libc/arch-arm/include -I$A/bionic/libc/include -I$A/bionic/libc/kernel/common -I$A/bionic/libc/kernel/arch-arm -I$A/bionic/libm/include -I$A/bionic/libm/include/arch/arm -include $A/system/core/include/arch/linux-arm/AndroidConfig.h -I$A/system/core/include/arch/linux-arm/ -DANDROID -DSK_RELEASE -nostdlib -march=armv7-a -msoft-float -mfloat-abi=softfp -mfpu=neon -mthumb -mthumb-interwork -fpic -fno-short-enums -fgcse-after-reload -frerun-cse-after-loop -frename-registers" +CONFIG_EXTRA_CFLAGS="-I$A/system/core/include -I$A/bionic/libc/arch-arm/include -I$A/bionic/libc/include -I$A/bionic/libc/kernel/common -I$A/bionic/libc/kernel/arch-arm -I$A/bionic/libm/include -I$A/bionic/libm/include/arch/arm -include $A/system/core/include/arch/linux-arm/AndroidConfig.h -I$A/system/core/include/arch/linux-arm/ -D__ANDROID__ -DSK_RELEASE -nostdlib -march=armv7-a -msoft-float -mfloat-abi=softfp -mfpu=neon -mthumb -mthumb-interwork -fpic -fno-short-enums -fgcse-after-reload -frename-registers" # # Debugging Options @@ -118,6 +119,8 @@ CONFIG_FEATURE_EDITING_MAX_LEN=0 # CONFIG_FEATURE_EDITING_VI is not set CONFIG_FEATURE_EDITING_HISTORY=0 # CONFIG_FEATURE_EDITING_SAVEHISTORY is not set +# CONFIG_FEATURE_EDITING_SAVE_ON_EXIT is not set +# CONFIG_FEATURE_REVERSE_SEARCH is not set # CONFIG_FEATURE_TAB_COMPLETION is not set # CONFIG_FEATURE_USERNAME_COMPLETION is not set # CONFIG_FEATURE_EDITING_FANCY_PROMPT is not set @@ -156,6 +159,7 @@ CONFIG_DPKG_DEB=y CONFIG_GUNZIP=y CONFIG_GZIP=y # CONFIG_FEATURE_GZIP_LONG_OPTIONS is not set +CONFIG_GZIP_FAST=0 CONFIG_LZOP=y CONFIG_LZOP_COMPR_HIGH=y CONFIG_RPM2CPIO=y @@ -189,6 +193,7 @@ CONFIG_CAT=y # CONFIG_FEATURE_DATE_ISOFMT is not set # CONFIG_FEATURE_DATE_NANO is not set # CONFIG_FEATURE_DATE_COMPAT is not set +# CONFIG_HOSTID is not set # CONFIG_ID is not set # CONFIG_GROUPS is not set CONFIG_TEST=y @@ -198,6 +203,8 @@ CONFIG_TR=y CONFIG_FEATURE_TR_CLASSES=y CONFIG_FEATURE_TR_EQUIV=y CONFIG_BASE64=y +# CONFIG_WHO is not set +# CONFIG_USERS is not set CONFIG_CAL=y CONFIG_CATV=y CONFIG_CHGRP=y @@ -223,18 +230,17 @@ CONFIG_DU=y CONFIG_FEATURE_DU_DEFAULT_BLOCKSIZE_1K=y CONFIG_ECHO=y CONFIG_FEATURE_FANCY_ECHO=y -# CONFIG_ENV is not set +CONFIG_ENV=y # CONFIG_FEATURE_ENV_LONG_OPTIONS is not set CONFIG_EXPAND=y # CONFIG_FEATURE_EXPAND_LONG_OPTIONS is not set -# CONFIG_EXPR is not set -# CONFIG_EXPR_MATH_SUPPORT_64 is not set +CONFIG_EXPR=y +CONFIG_EXPR_MATH_SUPPORT_64=y CONFIG_FALSE=y CONFIG_FOLD=y -# CONFIG_FSYNC is not set +CONFIG_FSYNC=y CONFIG_HEAD=y CONFIG_FEATURE_FANCY_HEAD=y -# CONFIG_HOSTID is not set CONFIG_INSTALL=y # CONFIG_FEATURE_INSTALL_LONG_OPTIONS is not set CONFIG_LN=y @@ -294,12 +300,11 @@ CONFIG_UNAME=y CONFIG_UNEXPAND=y # CONFIG_FEATURE_UNEXPAND_LONG_OPTIONS is not set CONFIG_UNIQ=y -# CONFIG_USLEEP is not set +CONFIG_USLEEP=y CONFIG_UUDECODE=y CONFIG_UUENCODE=y CONFIG_WC=y CONFIG_FEATURE_WC_LARGE=y -# CONFIG_WHO is not set CONFIG_WHOAMI=y CONFIG_YES=y @@ -366,61 +371,61 @@ CONFIG_WHICH=y # Editors # CONFIG_PATCH=y -# CONFIG_VI is not set -CONFIG_FEATURE_VI_MAX_LEN=0 -# CONFIG_FEATURE_VI_8BIT is not set -# CONFIG_FEATURE_VI_COLON is not set -# CONFIG_FEATURE_VI_YANKMARK is not set -# CONFIG_FEATURE_VI_SEARCH is not set +CONFIG_VI=y +CONFIG_FEATURE_VI_MAX_LEN=4096 +CONFIG_FEATURE_VI_8BIT=y +CONFIG_FEATURE_VI_COLON=y +CONFIG_FEATURE_VI_YANKMARK=y +CONFIG_FEATURE_VI_SEARCH=y # CONFIG_FEATURE_VI_REGEX_SEARCH is not set -# CONFIG_FEATURE_VI_USE_SIGNALS is not set -# CONFIG_FEATURE_VI_DOT_CMD is not set -# CONFIG_FEATURE_VI_READONLY is not set -# CONFIG_FEATURE_VI_SETOPTS is not set -# CONFIG_FEATURE_VI_SET is not set -# CONFIG_FEATURE_VI_WIN_RESIZE is not set -# CONFIG_FEATURE_VI_ASK_TERMINAL is not set -# CONFIG_FEATURE_VI_OPTIMIZE_CURSOR is not set -# CONFIG_AWK is not set -# CONFIG_FEATURE_AWK_LIBM is not set +CONFIG_FEATURE_VI_USE_SIGNALS=y +CONFIG_FEATURE_VI_DOT_CMD=y +CONFIG_FEATURE_VI_READONLY=y +CONFIG_FEATURE_VI_SETOPTS=y +CONFIG_FEATURE_VI_SET=y +CONFIG_FEATURE_VI_WIN_RESIZE=y +CONFIG_FEATURE_VI_ASK_TERMINAL=y +CONFIG_FEATURE_VI_OPTIMIZE_CURSOR=y +CONFIG_AWK=y +CONFIG_FEATURE_AWK_LIBM=y CONFIG_CMP=y CONFIG_DIFF=y # CONFIG_FEATURE_DIFF_LONG_OPTIONS is not set CONFIG_FEATURE_DIFF_DIR=y -# CONFIG_ED is not set -# CONFIG_SED is not set -# CONFIG_FEATURE_ALLOW_EXEC is not set +CONFIG_ED=y +CONFIG_SED=y +CONFIG_FEATURE_ALLOW_EXEC=y # # Finding Utilities # -# CONFIG_FIND is not set -# CONFIG_FEATURE_FIND_PRINT0 is not set -# CONFIG_FEATURE_FIND_MTIME is not set -# CONFIG_FEATURE_FIND_MMIN is not set -# CONFIG_FEATURE_FIND_PERM is not set -# CONFIG_FEATURE_FIND_TYPE is not set -# CONFIG_FEATURE_FIND_XDEV is not set -# CONFIG_FEATURE_FIND_MAXDEPTH is not set -# CONFIG_FEATURE_FIND_NEWER is not set -# CONFIG_FEATURE_FIND_INUM is not set -# CONFIG_FEATURE_FIND_EXEC is not set -# CONFIG_FEATURE_FIND_USER is not set -# CONFIG_FEATURE_FIND_GROUP is not set -# CONFIG_FEATURE_FIND_NOT is not set -# CONFIG_FEATURE_FIND_DEPTH is not set -# CONFIG_FEATURE_FIND_PAREN is not set -# CONFIG_FEATURE_FIND_SIZE is not set -# CONFIG_FEATURE_FIND_PRUNE is not set -# CONFIG_FEATURE_FIND_DELETE is not set -# CONFIG_FEATURE_FIND_PATH is not set -# CONFIG_FEATURE_FIND_REGEX is not set +CONFIG_FIND=y +CONFIG_FEATURE_FIND_PRINT0=y +CONFIG_FEATURE_FIND_MTIME=y +CONFIG_FEATURE_FIND_MMIN=y +CONFIG_FEATURE_FIND_PERM=y +CONFIG_FEATURE_FIND_TYPE=y +CONFIG_FEATURE_FIND_XDEV=y +CONFIG_FEATURE_FIND_MAXDEPTH=y +CONFIG_FEATURE_FIND_NEWER=y +CONFIG_FEATURE_FIND_INUM=y +CONFIG_FEATURE_FIND_EXEC=y +CONFIG_FEATURE_FIND_USER=y +CONFIG_FEATURE_FIND_GROUP=y +CONFIG_FEATURE_FIND_NOT=y +CONFIG_FEATURE_FIND_DEPTH=y +CONFIG_FEATURE_FIND_PAREN=y +CONFIG_FEATURE_FIND_SIZE=y +CONFIG_FEATURE_FIND_PRUNE=y +CONFIG_FEATURE_FIND_DELETE=y +CONFIG_FEATURE_FIND_PATH=y +CONFIG_FEATURE_FIND_REGEX=y # CONFIG_FEATURE_FIND_CONTEXT is not set -# CONFIG_FEATURE_FIND_LINKS is not set -# CONFIG_GREP is not set -# CONFIG_FEATURE_GREP_EGREP_ALIAS is not set -# CONFIG_FEATURE_GREP_FGREP_ALIAS is not set -# CONFIG_FEATURE_GREP_CONTEXT is not set +CONFIG_FEATURE_FIND_LINKS=y +CONFIG_GREP=y +CONFIG_FEATURE_GREP_EGREP_ALIAS=y +CONFIG_FEATURE_GREP_FGREP_ALIAS=y +CONFIG_FEATURE_GREP_CONTEXT=y CONFIG_XARGS=y CONFIG_FEATURE_XARGS_SUPPORT_CONFIRMATION=y CONFIG_FEATURE_XARGS_SUPPORT_QUOTES=y @@ -430,9 +435,9 @@ CONFIG_FEATURE_XARGS_SUPPORT_ZERO_TERM=y # # Init Utilities # -# CONFIG_BOOTCHARTD is not set -# CONFIG_FEATURE_BOOTCHARTD_BLOATED_HEADER is not set -# CONFIG_FEATURE_BOOTCHARTD_CONFIG_FILE is not set +CONFIG_BOOTCHARTD=y +CONFIG_FEATURE_BOOTCHARTD_BLOATED_HEADER=y +CONFIG_FEATURE_BOOTCHARTD_CONFIG_FILE=y CONFIG_HALT=y # CONFIG_FEATURE_CALL_TELINIT is not set CONFIG_TELINIT_PATH="" @@ -472,6 +477,7 @@ CONFIG_LAST_SYSTEM_ID=0 # CONFIG_FEATURE_DEL_USER_FROM_GROUP is not set # CONFIG_GETTY is not set # CONFIG_LOGIN is not set +# CONFIG_LOGIN_SESSION_AS_CHILD is not set # CONFIG_PAM is not set # CONFIG_LOGIN_SCRIPTS is not set # CONFIG_FEATURE_NOLOGIN is not set @@ -529,11 +535,17 @@ CONFIG_DEFAULT_DEPMOD_FILE="modules.dep" # Linux System Utilities # CONFIG_BLOCKDEV=y +CONFIG_MDEV=y +CONFIG_FEATURE_MDEV_CONF=y +CONFIG_FEATURE_MDEV_RENAME=y +CONFIG_FEATURE_MDEV_RENAME_REGEXP=y +CONFIG_FEATURE_MDEV_EXEC=y +CONFIG_FEATURE_MDEV_LOAD_FIRMWARE=y CONFIG_REV=y # CONFIG_ACPID is not set # CONFIG_FEATURE_ACPID_COMPAT is not set CONFIG_BLKID=y -# CONFIG_FEATURE_BLKID_TYPE is not set +CONFIG_FEATURE_BLKID_TYPE=y CONFIG_DMESG=y CONFIG_FEATURE_DMESG_PRETTY=y CONFIG_FBSET=y @@ -542,7 +554,7 @@ CONFIG_FEATURE_FBSET_READMODE=y CONFIG_FDFLUSH=y CONFIG_FDFORMAT=y CONFIG_FDISK=y -CONFIG_FDISK_SUPPORT_LARGE_DISKS=y +# CONFIG_FDISK_SUPPORT_LARGE_DISKS is not set CONFIG_FEATURE_FDISK_WRITABLE=y # CONFIG_FEATURE_AIX_LABEL is not set # CONFIG_FEATURE_SGI_LABEL is not set @@ -564,7 +576,7 @@ CONFIG_FEATURE_GETOPT_LONG=y CONFIG_HEXDUMP=y CONFIG_FEATURE_HEXDUMP_REVERSE=y CONFIG_HD=y -# CONFIG_HWCLOCK is not set +CONFIG_HWCLOCK=y # CONFIG_FEATURE_HWCLOCK_LONG_OPTIONS is not set # CONFIG_FEATURE_HWCLOCK_ADJTIME_FHS is not set # CONFIG_IPCRM is not set @@ -572,12 +584,6 @@ CONFIG_HD=y CONFIG_LOSETUP=y CONFIG_LSPCI=y CONFIG_LSUSB=y -# CONFIG_MDEV is not set -# CONFIG_FEATURE_MDEV_CONF is not set -# CONFIG_FEATURE_MDEV_RENAME is not set -# CONFIG_FEATURE_MDEV_RENAME_REGEXP is not set -# CONFIG_FEATURE_MDEV_EXEC is not set -# CONFIG_FEATURE_MDEV_LOAD_FIRMWARE is not set CONFIG_MKSWAP=y CONFIG_FEATURE_MKSWAP_UUID=y CONFIG_MORE=y @@ -600,7 +606,7 @@ CONFIG_SCRIPTREPLAY=y # CONFIG_SETARCH is not set # CONFIG_SWAPONOFF is not set # CONFIG_FEATURE_SWAPON_PRI is not set -# CONFIG_SWITCH_ROOT is not set +CONFIG_SWITCH_ROOT=y # CONFIG_UMOUNT is not set # CONFIG_FEATURE_UMOUNT_ALL is not set # CONFIG_FEATURE_MOUNT_LOOP is not set @@ -633,6 +639,16 @@ CONFIG_FEATURE_VOLUMEID_LINUXRAID=y # Miscellaneous Utilities # # CONFIG_CONSPY is not set +CONFIG_LESS=y +CONFIG_FEATURE_LESS_MAXLINES=9999999 +CONFIG_FEATURE_LESS_BRACKETS=y +CONFIG_FEATURE_LESS_FLAGS=y +CONFIG_FEATURE_LESS_MARKS=y +CONFIG_FEATURE_LESS_REGEXP=y +CONFIG_FEATURE_LESS_WINCH=y +CONFIG_FEATURE_LESS_ASK_TERMINAL=y +CONFIG_FEATURE_LESS_DASHCMD=y +CONFIG_FEATURE_LESS_LINENUMS=y # CONFIG_NANDWRITE is not set CONFIG_NANDDUMP=y CONFIG_SETSERIAL=y @@ -657,11 +673,11 @@ CONFIG_FEATURE_CHAT_SEND_ESCAPES=y CONFIG_FEATURE_CHAT_VAR_ABORT_LEN=y CONFIG_FEATURE_CHAT_CLR_ABORT=y CONFIG_CHRT=y -# CONFIG_CROND is not set -# CONFIG_FEATURE_CROND_D is not set -# CONFIG_FEATURE_CROND_CALL_SENDMAIL is not set -CONFIG_FEATURE_CROND_DIR="" -# CONFIG_CRONTAB is not set +CONFIG_CROND=y +CONFIG_FEATURE_CROND_D=y +CONFIG_FEATURE_CROND_CALL_SENDMAIL=y +CONFIG_FEATURE_CROND_DIR="/var/spool/cron" +CONFIG_CRONTAB=y CONFIG_DC=y CONFIG_FEATURE_DC_LIBM=y # CONFIG_DEVFSD is not set @@ -682,15 +698,6 @@ CONFIG_INOTIFYD=y # CONFIG_LAST is not set # CONFIG_FEATURE_LAST_SMALL is not set # CONFIG_FEATURE_LAST_FANCY is not set -# CONFIG_LESS is not set -CONFIG_FEATURE_LESS_MAXLINES=0 -# CONFIG_FEATURE_LESS_BRACKETS is not set -# CONFIG_FEATURE_LESS_FLAGS is not set -# CONFIG_FEATURE_LESS_MARKS is not set -# CONFIG_FEATURE_LESS_REGEXP is not set -# CONFIG_FEATURE_LESS_WINCH is not set -# CONFIG_FEATURE_LESS_DASHCMD is not set -# CONFIG_FEATURE_LESS_LINENUMS is not set CONFIG_HDPARM=y CONFIG_FEATURE_HDPARM_GET_IDENTITY=y CONFIG_FEATURE_HDPARM_HDIO_SCAN_HWIF=y @@ -731,9 +738,9 @@ CONFIG_NC=y CONFIG_NC_SERVER=y CONFIG_NC_EXTRA=y # CONFIG_NC_110_COMPAT is not set -# CONFIG_PING is not set +CONFIG_PING=y # CONFIG_PING6 is not set -# CONFIG_FEATURE_FANCY_PING is not set +CONFIG_FEATURE_FANCY_PING=y CONFIG_WHOIS=y # CONFIG_FEATURE_IPV6 is not set # CONFIG_FEATURE_UNIX_LOCAL is not set @@ -817,18 +824,22 @@ CONFIG_PSCAN=y CONFIG_ROUTE=y # CONFIG_SLATTACH is not set CONFIG_TCPSVD=y -# CONFIG_TELNET is not set -# CONFIG_FEATURE_TELNET_TTYPE is not set -# CONFIG_FEATURE_TELNET_AUTOLOGIN is not set -# CONFIG_TELNETD is not set -# CONFIG_FEATURE_TELNETD_STANDALONE is not set -# CONFIG_FEATURE_TELNETD_INETD_WAIT is not set -# CONFIG_TFTP is not set -# CONFIG_TFTPD is not set -# CONFIG_FEATURE_TFTP_GET is not set -# CONFIG_FEATURE_TFTP_PUT is not set -# CONFIG_FEATURE_TFTP_BLOCKSIZE is not set -# CONFIG_FEATURE_TFTP_PROGRESS_BAR is not set +CONFIG_TELNET=y +CONFIG_FEATURE_TELNET_TTYPE=y +CONFIG_FEATURE_TELNET_AUTOLOGIN=y +CONFIG_TELNETD=y +CONFIG_FEATURE_TELNETD_STANDALONE=y +CONFIG_FEATURE_TELNETD_INETD_WAIT=y +CONFIG_TFTP=y +CONFIG_TFTPD=y + +# +# Common options for tftp/tftpd +# +CONFIG_FEATURE_TFTP_GET=y +CONFIG_FEATURE_TFTP_PUT=y +CONFIG_FEATURE_TFTP_BLOCKSIZE=y +CONFIG_FEATURE_TFTP_PROGRESS_BAR=y # CONFIG_TFTP_DEBUG is not set # CONFIG_TRACEROUTE is not set # CONFIG_TRACEROUTE6 is not set @@ -852,8 +863,8 @@ CONFIG_FEATURE_UDHCP_8021Q=y CONFIG_UDHCPC_DEFAULT_SCRIPT="/usr/share/udhcpc/default.script" CONFIG_UDHCPC_SLACK_FOR_BUGGY_SERVERS=80 CONFIG_IFUPDOWN_UDHCPC_CMD_OPTIONS="-R -n" -# CONFIG_UDPSVD is not set -# CONFIG_VCONFIG is not set +CONFIG_UDPSVD=y +CONFIG_VCONFIG=y CONFIG_WGET=y CONFIG_FEATURE_WGET_STATUSBAR=y CONFIG_FEATURE_WGET_AUTHENTICATION=y @@ -890,7 +901,9 @@ CONFIG_POWERTOP=y CONFIG_PSTREE=y CONFIG_PWDX=y CONFIG_SMEMCAP=y -# CONFIG_FREE is not set +CONFIG_UPTIME=y +# CONFIG_FEATURE_UPTIME_UTMP_SUPPORT is not set +CONFIG_FREE=y CONFIG_FUSER=y # CONFIG_KILL is not set # CONFIG_KILLALL is not set @@ -900,10 +913,11 @@ CONFIG_PIDOF=y CONFIG_FEATURE_PIDOF_SINGLE=y CONFIG_FEATURE_PIDOF_OMIT=y # CONFIG_PKILL is not set -# CONFIG_PS is not set +CONFIG_PS=y # CONFIG_FEATURE_PS_WIDE is not set -# CONFIG_FEATURE_PS_TIME is not set -# CONFIG_FEATURE_PS_ADDITIONAL_COLUMNS is not set +# CONFIG_FEATURE_PS_LONG is not set +CONFIG_FEATURE_PS_TIME=y +CONFIG_FEATURE_PS_ADDITIONAL_COLUMNS=y # CONFIG_FEATURE_PS_UNUSUAL_SYSTEMS is not set CONFIG_RENICE=y CONFIG_BB_SYSCTL=y @@ -915,7 +929,6 @@ CONFIG_FEATURE_TOP_DECIMALS=y CONFIG_FEATURE_TOP_SMP_PROCESS=y CONFIG_FEATURE_TOPMEM=y CONFIG_FEATURE_SHOW_THREADS=y -# CONFIG_UPTIME is not set CONFIG_WATCH=y # -- cgit v1.2.3-55-g6feb From 9ce09bc9cb7743f87eb3e536c81d8c303e12bc81 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Thu, 3 Nov 2011 13:28:22 +0100 Subject: lineedit: add support for M-b, M-f, M-d, M-Backspace function old new delta ctrl_left - 96 +96 ctrl_right - 76 +76 static.esccmds 81 93 +12 read_line_input 3876 3885 +9 ------------------------------------------------------------------------------ (add/remove: 2/0 grow/shrink: 2/0 up/down: 193/0) Total: 193 bytes Signed-off-by: Denys Vlasenko --- include/libbb.h | 46 +++++++++++++++++++++++++++++----------------- libbb/lineedit.c | 40 ++++++++++++++++++++++++++++++++++++++++ libbb/read_key.c | 11 ++++++++--- 3 files changed, 77 insertions(+), 20 deletions(-) diff --git a/include/libbb.h b/include/libbb.h index 791cdd94e..53224fa35 100644 --- a/include/libbb.h +++ b/include/libbb.h @@ -1358,25 +1358,37 @@ enum { KEYCODE_DELETE = -9, KEYCODE_PAGEUP = -10, KEYCODE_PAGEDOWN = -11, - - KEYCODE_CTRL_UP = KEYCODE_UP & ~0x40, - KEYCODE_CTRL_DOWN = KEYCODE_DOWN & ~0x40, + // -12 is reserved for Alt/Ctrl/Shift-TAB +#if 0 + KEYCODE_FUN1 = -13, + KEYCODE_FUN2 = -14, + KEYCODE_FUN3 = -15, + KEYCODE_FUN4 = -16, + KEYCODE_FUN5 = -17, + KEYCODE_FUN6 = -18, + KEYCODE_FUN7 = -19, + KEYCODE_FUN8 = -20, + KEYCODE_FUN9 = -21, + KEYCODE_FUN10 = -22, + KEYCODE_FUN11 = -23, + KEYCODE_FUN12 = -24, +#endif + /* Be sure that last defined value is small enough + * to not interfere with Alt/Ctrl/Shift bits. + * So far we do not exceed -31 (0xfff..fffe1), + * which gives us three upper bits in LSB to play with. + */ + //KEYCODE_SHIFT_TAB = (-12) & ~0x80, + //KEYCODE_SHIFT_... = KEYCODE_... & ~0x80, + //KEYCODE_CTRL_UP = KEYCODE_UP & ~0x40, + //KEYCODE_CTRL_DOWN = KEYCODE_DOWN & ~0x40, KEYCODE_CTRL_RIGHT = KEYCODE_RIGHT & ~0x40, KEYCODE_CTRL_LEFT = KEYCODE_LEFT & ~0x40, -#if 0 - KEYCODE_FUN1 = -12, - KEYCODE_FUN2 = -13, - KEYCODE_FUN3 = -14, - KEYCODE_FUN4 = -15, - KEYCODE_FUN5 = -16, - KEYCODE_FUN6 = -17, - KEYCODE_FUN7 = -18, - KEYCODE_FUN8 = -19, - KEYCODE_FUN9 = -20, - KEYCODE_FUN10 = -21, - KEYCODE_FUN11 = -22, - KEYCODE_FUN12 = -23, -#endif + //KEYCODE_ALT_UP = KEYCODE_UP & ~0x20, + //KEYCODE_ALT_DOWN = KEYCODE_DOWN & ~0x20, + KEYCODE_ALT_RIGHT = KEYCODE_RIGHT & ~0x20, + KEYCODE_ALT_LEFT = KEYCODE_LEFT & ~0x20, + KEYCODE_CURSOR_POS = -0x100, /* 0xfff..fff00 */ /* How long is the longest ESC sequence we know? * We want it big enough to be able to contain diff --git a/libbb/lineedit.c b/libbb/lineedit.c index 603bbfcae..0d232889b 100644 --- a/libbb/lineedit.c +++ b/libbb/lineedit.c @@ -2504,6 +2504,44 @@ int FAST_FUNC read_line_input(line_input_t *st, const char *prompt, char *comman vi_cmdmode = 1; input_backward(1); } + /* Handle a few ESC- combinations the same way + * standard readline bindings (IOW: bash) do. + * Often, Alt- generates ESC-. + */ + ic = lineedit_read_key(read_key_buffer, timeout); + switch (ic) { + //case KEYCODE_LEFT: - bash doesn't do this + case 'b': + ctrl_left(); + break; + //case KEYCODE_RIGHT: - bash doesn't do this + case 'f': + ctrl_right(); + break; + //case KEYCODE_DELETE: - bash doesn't do this + case 'd': /* Alt-D */ + { + /* Delete word forward */ + int nc, sc = cursor; + ctrl_right(); + nc = cursor; + input_backward(cursor - sc); + while (--nc >= cursor) + input_delete(1); + break; + } + case '\b': /* Alt-Backspace(?) */ + case '\x7f': /* Alt-Backspace(?) */ + //case 'w': - bash doesn't do this + { + /* Delete word backward */ + int sc = cursor; + ctrl_left(); + while (sc-- > cursor) + input_delete(1); + break; + } + } break; #endif /* FEATURE_COMMAND_EDITING_VI */ @@ -2532,9 +2570,11 @@ int FAST_FUNC read_line_input(line_input_t *st, const char *prompt, char *comman input_backward(1); break; case KEYCODE_CTRL_LEFT: + case KEYCODE_ALT_LEFT: /* bash doesn't do it */ ctrl_left(); break; case KEYCODE_CTRL_RIGHT: + case KEYCODE_ALT_RIGHT: /* bash doesn't do it */ ctrl_right(); break; case KEYCODE_HOME: diff --git a/libbb/read_key.c b/libbb/read_key.c index 5dcd19c3f..8d72d2a63 100644 --- a/libbb/read_key.c +++ b/libbb/read_key.c @@ -40,13 +40,14 @@ int64_t FAST_FUNC read_key(int fd, char *buffer, int timeout) '[','C' |0x80,KEYCODE_RIGHT , '[','D' |0x80,KEYCODE_LEFT , /* ESC [ 1 ; 2 x, where x = A/B/C/D: Shift- */ - /* ESC [ 1 ; 3 x, where x = A/B/C/D: Alt- */ + /* ESC [ 1 ; 3 x, where x = A/B/C/D: Alt- - implemented below */ /* ESC [ 1 ; 4 x, where x = A/B/C/D: Alt-Shift- */ /* ESC [ 1 ; 5 x, where x = A/B/C/D: Ctrl- - implemented below */ /* ESC [ 1 ; 6 x, where x = A/B/C/D: Ctrl-Shift- */ '[','H' |0x80,KEYCODE_HOME , /* xterm */ - /* [ESC] ESC [ [2] H - [Alt-][Shift-]Home */ '[','F' |0x80,KEYCODE_END , /* xterm */ + /* [ESC] ESC [ [2] H - [Alt-][Shift-]Home (End similarly?) */ + /* '[','Z' |0x80,KEYCODE_SHIFT_TAB, */ '[','1','~' |0x80,KEYCODE_HOME , /* vt100? linux vt? or what? */ '[','2','~' |0x80,KEYCODE_INSERT , /* ESC [ 2 ; 3 ~ - Alt-Insert */ @@ -86,8 +87,12 @@ int64_t FAST_FUNC read_key(int fd, char *buffer, int timeout) /* '[','1',';','5','B' |0x80,KEYCODE_CTRL_DOWN , - unused */ '[','1',';','5','C' |0x80,KEYCODE_CTRL_RIGHT, '[','1',';','5','D' |0x80,KEYCODE_CTRL_LEFT , + /* '[','1',';','3','A' |0x80,KEYCODE_ALT_UP , - unused */ + /* '[','1',';','3','B' |0x80,KEYCODE_ALT_DOWN , - unused */ + '[','1',';','3','C' |0x80,KEYCODE_ALT_RIGHT, + '[','1',';','3','D' |0x80,KEYCODE_ALT_LEFT , + /* '[','3',';','3','~' |0x80,KEYCODE_ALT_DELETE, - unused */ 0 - /* ESC [ Z - Shift-Tab */ }; pfd.fd = fd; -- cgit v1.2.3-55-g6feb From c0cae52662ccced9df19f19ec94238d1b1e3bd71 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Fri, 4 Nov 2011 01:09:09 +0100 Subject: lineedit: fix build failure Signed-off-by: Denys Vlasenko --- libbb/lineedit.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/libbb/lineedit.c b/libbb/lineedit.c index 0d232889b..1390ed62d 100644 --- a/libbb/lineedit.c +++ b/libbb/lineedit.c @@ -1520,8 +1520,10 @@ static void remember_in_history(char *str) for (i = 0; i < state->max_history-1; i++) state->history[i] = state->history[i+1]; /* i == state->max_history-1 */ - if (ENABLE_FEATURE_EDITING_SAVE_ON_EXIT && state->cnt_history_in_file) +# if ENABLE_FEATURE_EDITING_SAVE_ON_EXIT + if (state->cnt_history_in_file) state->cnt_history_in_file--; +# endif } /* i <= state->max_history-1 */ state->history[i++] = xstrdup(str); -- cgit v1.2.3-55-g6feb