From bugs at busybox.net Tue Apr 1 02:55:24 2008 From: bugs at busybox.net (bugs at busybox.net) Date: Tue, 1 Apr 2008 02:55:24 -0700 Subject: [BusyBox 0000680]: timeout applet (new feature) Message-ID: <33fcd5d79abe2f1b30a2531d0becb055@bugs.busybox.net> A NOTE has been added to this issue. ====================================================================== http://busybox.net/bugs/view.php?id=680 ====================================================================== Reported By: robang74 Assigned To: BusyBox ====================================================================== Project: BusyBox Issue ID: 680 Category: New Features Reproducibility: N/A Severity: feature Priority: normal Status: assigned ====================================================================== Date Submitted: 02-03-2006 02:18 PST Last Modified: 04-01-2008 02:55 PDT ====================================================================== Summary: timeout applet (new feature) Description: Puts in run a command line and if it does not terminate within a specified timeout it signal with a specified signal the commands and all its children. In both case report the exit status of the command and it is able to save it also in a file which could after read by a script or other command. It does NOT need /proc mounted. [roberto at wsraf busybox]$ ./busybox timeout --help BusyBox v1.1.1-pre0 (2006.02.03-09:48+0000) multi-call binary Usage: timeout [-v] [-f exit_status_file] [-s int_signal] "" Runs the "command line" within a timeout window and returns its status. Options: -v Displays verbose resource usage information -f File name in which save the exit status -s Signal to send to the command line and its children after timeout expired ====================================================================== ---------------------------------------------------------------------- robang74 - 07-11-06 01:18 ---------------------------------------------------------------------- Applet version 0.2.7 applies against busybox v1.1.3, changelog: a) http://busybox.net/bugs/view.php?id=471#600bytes less than previous applet version b) 1 bug less than previous applet version c) added regression test in testsuite [roberto at GEDX0327 busybox-1.1.3]$ size libbb/talarm.o text data bss dec hex filename 1176 20 12 1208 4b8 libbb/talarm.o [roberto at GEDX0327 busybox-1.1.3]$ size miscutils/timeout.o text data bss dec hex filename 316 24 0 340 154 miscutils/timeout.o Some options have been removed, now this applet is easier to use: [roberto at GEDX0327 busybox-1.1.3]$ busybox timeout USAGE: timeout [-s int_signal] "" [roberto at GEDX0327 busybox-1.1.3]$ busybox timeout --help BusyBox v1.1.3 (2006.07.11-08:14+0000) multi-call binary Usage: timeout [-s signal] "" Runs the "command line" within a timeout window and returns its status. Options: -s Number of signal to the command and its children when timeout expires ---------------------------------------------------------------------- vda - 04-01-08 02:55 ---------------------------------------------------------------------- Timeout after process ate N seconds of CPU time: softlimit -t N [] Example: softlimit -t 5 ash -c 'while true; do true; done' Issue History Date Modified Username Field Change ====================================================================== 02-03-06 02:18 robang74 New Issue 02-03-06 02:18 robang74 Status new => assigned 02-03-06 02:18 robang74 Assigned To => BusyBox 02-03-06 02:18 robang74 File Added: timeout_applet.tgz 02-03-06 02:18 robang74 Issue Monitored: robang74 07-11-06 01:08 robang74 Note Added: 0001515 07-11-06 01:08 robang74 File Added: timeout_applet-0.2.7.tar.bz2 07-11-06 01:15 robang74 Note Edited: 0001515 07-11-06 01:18 robang74 Note Edited: 0001515 04-01-08 02:55 vda Note Added: 0006264 ====================================================================== From vda at busybox.net Tue Apr 1 07:47:58 2008 From: vda at busybox.net (vda at busybox.net) Date: Tue, 1 Apr 2008 07:47:58 -0700 (PDT) Subject: svn commit: trunk/busybox: applets coreutils include init libbb pro etc... Message-ID: <20080401144758.2AF303C4FF@busybox.net> Author: vda Date: 2008-04-01 07:47:57 -0700 (Tue, 01 Apr 2008) New Revision: 21610 Log: shells: do not frocibly enable test, echo and kill _applets_, just build relevant source and use xxx_main functions. build system: add a special case when we have exactly one applet enabled (makes "true", "false", "basename" REALLY tiny). getopt32: do not use stdio. function old new delta getopt32 1385 1412 +27 make_device 1187 1200 +13 basename_main 120 127 +7 tcpudpsvd_main 1922 1926 +4 testcmd 5 - -5 echocmd 5 - -5 fuser_main 1243 1231 -12 ------------------------------------------------------------------------------ (add/remove: 0/2 grow/shrink: 4/1 up/down: 51/-22) Total: 29 bytes Modified: trunk/busybox/applets/applet_tables.c trunk/busybox/coreutils/Kbuild trunk/busybox/coreutils/basename.c trunk/busybox/coreutils/echo.c trunk/busybox/include/busybox.h trunk/busybox/include/libbb.h trunk/busybox/init/Config.in trunk/busybox/libbb/Kbuild trunk/busybox/libbb/appletlib.c trunk/busybox/libbb/error_msg_and_die.c trunk/busybox/libbb/getopt32.c trunk/busybox/procps/kill.c trunk/busybox/shell/Config.in trunk/busybox/shell/ash.c Changeset: Modified: trunk/busybox/applets/applet_tables.c =================================================================== --- trunk/busybox/applets/applet_tables.c 2008-04-01 12:26:49 UTC (rev 21609) +++ trunk/busybox/applets/applet_tables.c 2008-04-01 14:47:57 UTC (rev 21610) @@ -69,9 +69,14 @@ /* Keep in sync with include/busybox.h! */ - puts("/* This is a generated file, don't edit */"); + puts("/* This is a generated file, don't edit */\n"); - puts("const char applet_names[] ALIGN1 = \"\"\n"); + if (NUM_APPLETS == 1) { + printf("#define SINGLE_APPLET_STR \"%s\"\n", applets[0].name); + printf("#define SINGLE_APPLET_MAIN %s_main\n\n", applets[0].name); + } + + puts("const char applet_names[] ALIGN1 = \"\""); for (i = 0; i < NUM_APPLETS; i++) { printf("\"%s\" \"\\0\"\n", applets[i].name); } Modified: trunk/busybox/coreutils/Kbuild =================================================================== --- trunk/busybox/coreutils/Kbuild 2008-04-01 12:26:49 UTC (rev 21609) +++ trunk/busybox/coreutils/Kbuild 2008-04-01 14:47:57 UTC (rev 21610) @@ -30,6 +30,7 @@ lib-$(CONFIG_DU) += du.o lib-$(CONFIG_ECHO) += echo.o lib-$(CONFIG_ASH) += echo.o # used by ash +lib-$(CONFIG_HUSH) += echo.o # used by hush lib-$(CONFIG_ENV) += env.o lib-$(CONFIG_EXPR) += expr.o lib-$(CONFIG_EXPAND) += expand.o @@ -72,6 +73,8 @@ lib-$(CONFIG_TEE) += tee.o lib-$(CONFIG_TEST) += test.o lib-$(CONFIG_ASH) += test.o # used by ash +lib-$(CONFIG_HUSH) += test.o # used by hush +lib-$(CONFIG_MSH) += test.o # used by msh lib-$(CONFIG_TOUCH) += touch.o lib-$(CONFIG_TR) += tr.o lib-$(CONFIG_TRUE) += true.o Modified: trunk/busybox/coreutils/basename.c =================================================================== --- trunk/busybox/coreutils/basename.c 2008-04-01 12:26:49 UTC (rev 21609) +++ trunk/busybox/coreutils/basename.c 2008-04-01 14:47:57 UTC (rev 21610) @@ -37,15 +37,16 @@ /* It should strip slash: /abc/def/ -> def */ s = bb_get_last_path_component_strip(*++argv); + m = strlen(s); if (*++argv) { n = strlen(*argv); - m = strlen(s); if ((m > n) && ((strcmp)(s+m-n, *argv) == 0)) { - s[m-n] = '\0'; + m -= n; + s[m] = '\0'; } } - puts(s); - - return fflush(stdout); + /* puts(s) will do, but we can do without stdio this way: */ + s[m++] = '\n'; + return full_write(STDOUT_FILENO, s, m) == m; } Modified: trunk/busybox/coreutils/echo.c =================================================================== --- trunk/busybox/coreutils/echo.c 2008-04-01 12:26:49 UTC (rev 21609) +++ trunk/busybox/coreutils/echo.c 2008-04-01 14:47:57 UTC (rev 21610) @@ -27,10 +27,8 @@ /* This is a NOFORK applet. Be very careful! */ -/* argc is unused, but removing it precludes compiler from - * using call -> jump optimization */ +/* NB: can be used by shell even if not enabled as applet */ -int echo_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; int echo_main(int argc ATTRIBUTE_UNUSED, char **argv) { const char *arg; Modified: trunk/busybox/include/busybox.h =================================================================== --- trunk/busybox/include/busybox.h 2008-04-01 12:26:49 UTC (rev 21609) +++ trunk/busybox/include/busybox.h 2008-04-01 14:47:57 UTC (rev 21610) @@ -59,9 +59,6 @@ /* Length of these names has effect on size of libbusybox * and "individual" binaries. Keep them short. */ -void lbb_prepare(const char *applet - USE_FEATURE_INDIVIDUAL(, char **argv) - ) MAIN_EXTERNALLY_VISIBLE; #if ENABLE_BUILD_LIBBUSYBOX #if ENABLE_FEATURE_SHARED_BUSYBOX int lbb_main(char **argv) EXTERNALLY_VISIBLE; Modified: trunk/busybox/include/libbb.h =================================================================== --- trunk/busybox/include/libbb.h 2008-04-01 12:26:49 UTC (rev 21609) +++ trunk/busybox/include/libbb.h 2008-04-01 14:47:57 UTC (rev 21610) @@ -848,23 +848,20 @@ /* applets which are useful from another applets */ int bb_cat(char** argv); -int echo_main(int argc, char** argv) MAIN_EXTERNALLY_VISIBLE; -int test_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; -int kill_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; -#if ENABLE_ROUTE -void bb_displayroutes(int noresolve, int netstatfmt); -#endif +/* If shell needs them, these three "exist" even if not enabled as applets */ +int echo_main(int argc, char** argv) USE_ECHO(MAIN_EXTERNALLY_VISIBLE); +int test_main(int argc, char **argv) USE_TEST(MAIN_EXTERNALLY_VISIBLE); +int kill_main(int argc, char **argv) USE_KILL(MAIN_EXTERNALLY_VISIBLE); int chown_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; -#if ENABLE_GUNZIP int gunzip_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; -#endif -#if ENABLE_BUNZIP2 int bunzip2_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; -#endif int bbunpack(char **argv, char* (*make_new_name)(char *filename), USE_DESKTOP(long long) int (*unpacker)(void) ); +#if ENABLE_ROUTE +void bb_displayroutes(int noresolve, int netstatfmt); +#endif /* Networking */ Modified: trunk/busybox/init/Config.in =================================================================== --- trunk/busybox/init/Config.in 2008-04-01 12:26:49 UTC (rev 21609) +++ trunk/busybox/init/Config.in 2008-04-01 14:47:57 UTC (rev 21610) @@ -98,13 +98,13 @@ config HALT bool "poweroff, halt, and reboot" - default y + default n help Stop all processes and either halt, reboot, or power off the system. config MESG bool "mesg" - default y + default n help Mesg controls access to your terminal by others. It is typically used to allow or disallow other users to write to your terminal Modified: trunk/busybox/libbb/Kbuild =================================================================== --- trunk/busybox/libbb/Kbuild 2008-04-01 12:26:49 UTC (rev 21609) +++ trunk/busybox/libbb/Kbuild 2008-04-01 14:47:57 UTC (rev 21610) @@ -101,6 +101,7 @@ lib-y += xatonum.o lib-y += xconnect.o lib-y += xfuncs.o +lib-y += xfunc_die.o lib-y += xgetcwd.o lib-y += xgethostbyname.o lib-y += xreadlink.o Modified: trunk/busybox/libbb/appletlib.c =================================================================== --- trunk/busybox/libbb/appletlib.c 2008-04-01 12:26:49 UTC (rev 21609) +++ trunk/busybox/libbb/appletlib.c 2008-04-01 14:47:57 UTC (rev 21610) @@ -36,6 +36,13 @@ /* Include generated applet names, pointers to _main, etc */ #include "applet_tables.h" +/* ...and if applet_tables generator says we have only one applet... */ +#ifdef SINGLE_APPLET_MAIN +#undef ENABLE_FEATURE_INDIVIDUAL +#define ENABLE_FEATURE_INDIVIDUAL 1 +#undef USE_FEATURE_INDIVIDUAL +#define USE_FEATURE_INDIVIDUAL(...) __VA_ARGS__ +#endif #if ENABLE_FEATURE_COMPRESS_USAGE @@ -77,6 +84,23 @@ void bb_show_usage(void) { if (ENABLE_SHOW_USAGE) { +#ifdef SINGLE_APPLET_STR + /* Imagine that this applet is "true". Dont suck in printf! */ + const char *p; + const char *usage_string = p = unpack_usage_messages(); + + if (*p == '\b') { + write(2, "\nNo help available.\n\n", + sizeof("\nNo help available.\n\n") - 1); + } else { + write(2, "\nUsage: "SINGLE_APPLET_STR" ", + sizeof("\nUsage: "SINGLE_APPLET_STR" ") - 1); + write(2, p, strlen(p)); + write(2, "\n\n", 2); + } + dealloc_usage_messages((char*)usage_string); +#else +// TODO: in this case, stdio is sucked in by busybox_main() anyway... const char *format_string; const char *p; const char *usage_string = p = unpack_usage_messages(); @@ -84,18 +108,17 @@ if (ap < 0) /* never happens, paranoia */ xfunc_die(); - while (ap) { while (*p++) continue; ap--; } - fprintf(stderr, "%s multi-call binary\n", bb_banner); format_string = "\nUsage: %s %s\n\n"; if (*p == '\b') format_string = "\nNo help available.\n\n"; fprintf(stderr, format_string, applet_name, p); dealloc_usage_messages((char*)usage_string); +#endif } xfunc_die(); } @@ -125,6 +148,9 @@ void lbb_prepare(const char *applet USE_FEATURE_INDIVIDUAL(, char **argv)) + MAIN_EXTERNALLY_VISIBLE; +void lbb_prepare(const char *applet + USE_FEATURE_INDIVIDUAL(, char **argv)) { #ifdef __GLIBC__ (*(int **)&bb_errno) = __errno_location(); @@ -158,6 +184,9 @@ bool re_execed; #endif + +#if !ENABLE_FEATURE_INDIVIDUAL + USE_FEATURE_SUID(static uid_t ruid;) /* real uid */ #if ENABLE_FEATURE_SUID_CONFIG @@ -660,13 +689,21 @@ exit(busybox_main(argv)); } +#endif /* !ENABLE_FEATURE_INDIVIDUAL */ + + #if ENABLE_BUILD_LIBBUSYBOX int lbb_main(char **argv) #else int main(int argc ATTRIBUTE_UNUSED, char **argv) #endif { +#if ENABLE_FEATURE_INDIVIDUAL + /* Only one applet is selected by the user! */ + lbb_prepare(SINGLE_APPLET_STR USE_FEATURE_INDIVIDUAL(, argv)); + return SINGLE_APPLET_MAIN(argc, argv); +#else lbb_prepare("busybox" USE_FEATURE_INDIVIDUAL(, argv)); #if !BB_MMU @@ -685,4 +722,5 @@ run_applet_and_exit(applet_name, argv); bb_error_msg_and_die("applet not found"); +#endif } Modified: trunk/busybox/libbb/error_msg_and_die.c =================================================================== --- trunk/busybox/libbb/error_msg_and_die.c 2008-04-01 12:26:49 UTC (rev 21609) +++ trunk/busybox/libbb/error_msg_and_die.c 2008-04-01 14:47:57 UTC (rev 21610) @@ -9,33 +9,6 @@ #include "libbb.h" -int die_sleep; -#if ENABLE_FEATURE_PREFER_APPLETS || ENABLE_HUSH -jmp_buf die_jmp; -#endif - -void xfunc_die(void) -{ - if (die_sleep) { - if ((ENABLE_FEATURE_PREFER_APPLETS || ENABLE_HUSH) - && die_sleep < 0 - ) { - /* Special case. We arrive here if NOFORK applet - * calls xfunc, which then decides to die. - * We don't die, but jump instead back to caller. - * NOFORK applets still cannot carelessly call xfuncs: - * p = xmalloc(10); - * q = xmalloc(10); // BUG! if this dies, we leak p! - */ - /* -2222 means "zero" (longjmp can't pass 0) - * run_nofork_applet() catches -2222. */ - longjmp(die_jmp, xfunc_error_retval ? xfunc_error_retval : -2222); - } - sleep(die_sleep); - } - exit(xfunc_error_retval); -} - void bb_error_msg_and_die(const char *s, ...) { va_list p; Modified: trunk/busybox/libbb/getopt32.c =================================================================== --- trunk/busybox/libbb/getopt32.c 2008-04-01 12:26:49 UTC (rev 21609) +++ trunk/busybox/libbb/getopt32.c 2008-04-01 14:47:57 UTC (rev 21610) @@ -285,6 +285,10 @@ const char *opt_complementary; +/* Many small applets don't want to suck in stdio.h only because + * they need to parse options by calling us */ +#define DONT_USE_PRINTF 1 + enum { PARAM_STRING, PARAM_LIST, @@ -335,7 +339,8 @@ #define SHOW_USAGE_IF_ERROR 1 #define ALL_ARGV_IS_OPTS 2 #define FIRST_ARGV_IS_OPT 4 -#define FREE_FIRST_ARGV_IS_OPT 8 +#define FREE_FIRST_ARGV_IS_OPT (8 * !DONT_USE_PRINTF) + int spec_flgs = 0; argc = 0; @@ -489,10 +494,16 @@ va_end(p); if (spec_flgs & FIRST_ARGV_IS_OPT) { - if (argv[1] && argv[1][0] != '-' && argv[1][0] != '\0') { + if (argv[1] && argv[1][0] != '-' && argv[1][1] != '\0') { +#if DONT_USE_PRINTF + char *pp = alloca(strlen(argv[1]) + 2); + *pp++ = '-'; + argv[1] = strcpy(pp, argv[1]); +#else argv[1] = xasprintf("-%s", argv[1]); if (ENABLE_FEATURE_CLEAN_UP) spec_flgs |= FREE_FIRST_ARGV_IS_OPT; +#endif } } @@ -573,7 +584,7 @@ } } -#if (ENABLE_AR || ENABLE_TAR) && ENABLE_FEATURE_CLEAN_UP +#if ENABLE_FEATURE_CLEAN_UP if (spec_flgs & FREE_FIRST_ARGV_IS_OPT) free(argv[1]); #endif Modified: trunk/busybox/procps/kill.c =================================================================== --- trunk/busybox/procps/kill.c 2008-04-01 12:26:49 UTC (rev 21609) +++ trunk/busybox/procps/kill.c 2008-04-01 14:47:57 UTC (rev 21610) @@ -24,7 +24,6 @@ * This is needed to avoid collision with kill -9 ... syntax */ -int kill_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; int kill_main(int argc, char **argv) { char *arg; Modified: trunk/busybox/shell/Config.in =================================================================== --- trunk/busybox/shell/Config.in 2008-04-01 12:26:49 UTC (rev 21609) +++ trunk/busybox/shell/Config.in 2008-04-01 14:47:57 UTC (rev 21610) @@ -36,7 +36,6 @@ config ASH bool "ash" default n - select TEST help Tha 'ash' shell adds about 60k in the default configuration and is the most complete and most pedantically correct shell included with @@ -111,7 +110,6 @@ config ASH_BUILTIN_ECHO bool "Builtin version of 'echo'" default y - select ECHO depends on ASH help Enable support for echo, builtin to ash. @@ -119,7 +117,6 @@ config ASH_BUILTIN_TEST bool "Builtin version of 'test'" default y - select TEST depends on ASH help Enable support for test, builtin to ash. @@ -170,10 +167,6 @@ config HUSH bool "hush" default n - select TRUE - select FALSE - select TEST - select ECHO help hush is a very small shell (just 18k) and it has fairly complete Bourne shell grammar. It even handles all the normal flow control @@ -240,13 +233,9 @@ help lash is deprecated and will be removed, please migrate to hush. - config MSH bool "msh" default n - select TRUE - select FALSE - select TEST help The minix shell (adds just 30k) is quite complete and handles things like for/do/done, case/esac and all the things you expect a Bourne Modified: trunk/busybox/shell/ash.c =================================================================== --- trunk/busybox/shell/ash.c 2008-04-01 12:26:49 UTC (rev 21609) +++ trunk/busybox/shell/ash.c 2008-04-01 14:47:57 UTC (rev 21610) @@ -8417,12 +8417,6 @@ static int breakcmd(int, char **); static int dotcmd(int, char **); static int evalcmd(int, char **); -#if ENABLE_ASH_BUILTIN_ECHO -static int echocmd(int, char **); -#endif -#if ENABLE_ASH_BUILTIN_TEST -static int testcmd(int, char **); -#endif static int exitcmd(int, char **); static int exportcmd(int, char **); #if ENABLE_ASH_GETOPTS @@ -8464,6 +8458,9 @@ * Apart from the above, [[ expr ]] should work as [ expr ] */ +#define testcmd test_main +#define echocmd echo_main + /* Keep these in proper order since it is searched via bsearch() */ static const struct builtincmd builtintab[] = { { BUILTIN_SPEC_REG ".", dotcmd }, @@ -11506,22 +11503,6 @@ /* NOTREACHED */ } -#if ENABLE_ASH_BUILTIN_ECHO -static int -echocmd(int argc, char **argv) -{ - return echo_main(argc, argv); -} -#endif - -#if ENABLE_ASH_BUILTIN_TEST -static int -testcmd(int argc, char **argv) -{ - return test_main(argc, argv); -} -#endif - /* * Read a file containing shell functions. */ From vda at busybox.net Tue Apr 1 09:12:18 2008 From: vda at busybox.net (vda at busybox.net) Date: Tue, 1 Apr 2008 09:12:18 -0700 (PDT) Subject: svn commit: trunk/busybox/util-linux Message-ID: <20080401161218.69D943C564@busybox.net> Author: vda Date: 2008-04-01 09:12:17 -0700 (Tue, 01 Apr 2008) New Revision: 21614 Log: script: do not ignore poll() errors. ~+20 bytes. Modified: trunk/busybox/util-linux/script.c Changeset: Modified: trunk/busybox/util-linux/script.c =================================================================== --- trunk/busybox/util-linux/script.c 2008-04-01 16:07:06 UTC (rev 21613) +++ trunk/busybox/util-linux/script.c 2008-04-01 16:12:17 UTC (rev 21614) @@ -115,7 +115,11 @@ /* TODO: don't use full_write's, use proper write buffering */ while (fd_count) { /* not safe_poll! we want SIGCHLD to EINTR poll */ - poll(ppfd, fd_count, -1); + if (poll(ppfd, fd_count, -1) < 0 && errno != EINTR) { + /* If child exits too quickly, we may get EIO: + * for example, try "script -c true" */ + break; + } if (pfd[0].revents) { count = safe_read(0, buf, sizeof(buf)); if (count <= 0) { From vda at busybox.net Tue Apr 1 09:13:15 2008 From: vda at busybox.net (vda at busybox.net) Date: Tue, 1 Apr 2008 09:13:15 -0700 (PDT) Subject: svn commit: trunk/busybox/runit Message-ID: <20080401161315.0F21E3C577@busybox.net> Author: vda Date: 2008-04-01 09:13:14 -0700 (Tue, 01 Apr 2008) New Revision: 21615 Log: chpst: fix "env directory" parsing to not strip everything after 1st whitespace. -6 bytes. Modified: trunk/busybox/runit/chpst.c Changeset: Modified: trunk/busybox/runit/chpst.c =================================================================== --- trunk/busybox/runit/chpst.c 2008-04-01 16:12:17 UTC (rev 21614) +++ trunk/busybox/runit/chpst.c 2008-04-01 16:13:14 UTC (rev 21615) @@ -114,6 +114,10 @@ if (!dir) bb_perror_msg_and_die("opendir %s", directory_name); for (;;) { + char buf[256]; + char *tail; + int size; + errno = 0; d = readdir(dir); if (!d) { @@ -135,31 +139,25 @@ bb_perror_msg_and_die("open %s/%s", directory_name, d->d_name); } - if (fd >= 0) { - char buf[256]; - char *tail; - int size; - - size = safe_read(fd, buf, sizeof(buf)-1); - if (size < 0) - bb_perror_msg_and_die("read %s/%s", - directory_name, d->d_name); - if (size == 0) { - unsetenv(d->d_name); - continue; - } - buf[size] = '\n'; - tail = memchr(buf, '\n', sizeof(buf)); - /* skip trailing whitespace */; - while (1) { - if (tail[0] == ' ') tail[0] = '\0'; - if (tail[0] == '\t') tail[0] = '\0'; - if (tail[0] == '\n') tail[0] = '\0'; - if (tail == buf) break; - tail--; - } - xsetenv(d->d_name, buf); + size = full_read(fd, buf, sizeof(buf)-1); + close(fd); + if (size < 0) + bb_perror_msg_and_die("read %s/%s", + directory_name, d->d_name); + if (size == 0) { + unsetenv(d->d_name); + continue; } + buf[size] = '\n'; + tail = strchr(buf, '\n'); + /* skip trailing whitespace */ + while (1) { + *tail = '\0'; + tail--; + if (tail < buf || !isspace(*tail)) + break; + } + xsetenv(d->d_name, buf); } closedir(dir); if (fchdir(wdir) == -1) From vda at busybox.net Tue Apr 1 09:29:22 2008 From: vda at busybox.net (vda at busybox.net) Date: Tue, 1 Apr 2008 09:29:22 -0700 (PDT) Subject: svn commit: trunk/busybox/coreutils Message-ID: <20080401162922.33A963C547@busybox.net> Author: vda Date: 2008-04-01 09:29:21 -0700 (Tue, 01 Apr 2008) New Revision: 21616 Log: basename: tiny shrink Modified: trunk/busybox/coreutils/basename.c Changeset: Modified: trunk/busybox/coreutils/basename.c =================================================================== --- trunk/busybox/coreutils/basename.c 2008-04-01 16:13:14 UTC (rev 21615) +++ trunk/busybox/coreutils/basename.c 2008-04-01 16:29:21 UTC (rev 21616) @@ -42,7 +42,7 @@ n = strlen(*argv); if ((m > n) && ((strcmp)(s+m-n, *argv) == 0)) { m -= n; - s[m] = '\0'; + /*s[m] = '\0'; - redundant */ } } From vda at busybox.net Tue Apr 1 10:43:04 2008 From: vda at busybox.net (vda at busybox.net) Date: Tue, 1 Apr 2008 10:43:04 -0700 (PDT) Subject: svn commit: trunk/busybox/libbb Message-ID: <20080401174304.C47703C37D@busybox.net> Author: vda Date: 2008-04-01 10:43:03 -0700 (Tue, 01 Apr 2008) New Revision: 21617 Log: xfunc_die: resurrect (actually, it's "svn add" being forgotten again) Added: trunk/busybox/libbb/xfunc_die.c Changeset: Added: trunk/busybox/libbb/xfunc_die.c =================================================================== --- trunk/busybox/libbb/xfunc_die.c (rev 0) +++ trunk/busybox/libbb/xfunc_die.c 2008-04-01 17:43:03 UTC (rev 21617) @@ -0,0 +1,40 @@ +/* vi: set sw=4 ts=4: */ +/* + * Utility routines. + * + * Copyright (C) 2008 by Denys Vlasenko + * + * Licensed under GPLv2, see file LICENSE in this tarball for details. + */ + +/* Keeping it separate allows to NOT suck in stdio for VERY small applets. + * Try building busybox with only "true" enabled... */ + +#include "libbb.h" + +int die_sleep; +#if ENABLE_FEATURE_PREFER_APPLETS || ENABLE_HUSH +jmp_buf die_jmp; +#endif + +void xfunc_die(void) +{ + if (die_sleep) { + if ((ENABLE_FEATURE_PREFER_APPLETS || ENABLE_HUSH) + && die_sleep < 0 + ) { + /* Special case. We arrive here if NOFORK applet + * calls xfunc, which then decides to die. + * We don't die, but jump instead back to caller. + * NOFORK applets still cannot carelessly call xfuncs: + * p = xmalloc(10); + * q = xmalloc(10); // BUG! if this dies, we leak p! + */ + /* -2222 means "zero" (longjmp can't pass 0) + * run_nofork_applet() catches -2222. */ + longjmp(die_jmp, xfunc_error_retval ? xfunc_error_retval : -2222); + } + sleep(die_sleep); + } + exit(xfunc_error_retval); +} From vda at busybox.net Wed Apr 2 06:04:20 2008 From: vda at busybox.net (vda at busybox.net) Date: Wed, 2 Apr 2008 06:04:20 -0700 (PDT) Subject: svn commit: trunk/busybox: include networking networking/udhcp Message-ID: <20080402130420.36B613C3B4@busybox.net> Author: vda Date: 2008-04-02 06:04:19 -0700 (Wed, 02 Apr 2008) New Revision: 21619 Log: udhcpc: add -o "do not request options by default" switch (by L. Gabriel Somlo ) function old new delta udhcpc_main 2513 2554 +41 static.udhcpc_longopts 226 247 +21 add_param_req_option 119 132 +13 packed_usage 23952 23964 +12 ------------------------------------------------------------------------------ (add/remove: 0/0 grow/shrink: 4/0 up/down: 87/0) Total: 87 bytes Modified: trunk/busybox/include/usage.h trunk/busybox/networking/ifupdown.c trunk/busybox/networking/udhcp/clientpacket.c trunk/busybox/networking/udhcp/dhcpc.c trunk/busybox/networking/udhcp/dhcpc.h trunk/busybox/networking/udhcp/files.c Changeset: Modified: trunk/busybox/include/usage.h =================================================================== --- trunk/busybox/include/usage.h 2008-04-02 00:18:57 UTC (rev 21618) +++ trunk/busybox/include/usage.h 2008-04-02 13:04:19 UTC (rev 21619) @@ -4116,7 +4116,7 @@ "Adjust filesystem options on ext[23] filesystems" #define udhcpc_trivial_usage \ - "[-Cfbnqtv] [-c CID] [-V VCLS] [-H HOSTNAME] [-i INTERFACE]\n" \ + "[-Cfbnqtvo] [-c CID] [-V VCLS] [-H HOSTNAME] [-i INTERFACE]\n" \ " [-p pidfile] [-r IP] [-s script] [-O dhcp-option]..." USE_FEATURE_UDHCP_PORT(" [-P N]") #define udhcpc_full_usage \ USE_GETOPT_LONG( \ @@ -4127,17 +4127,18 @@ "\n -C,--clientid-none Suppress default client identifier" \ "\n -p,--pidfile=file Create pidfile" \ "\n -r,--request=IP IP address to request" \ - "\n -s,--script=file Run file at dhcp events (default /usr/share/udhcpc/default.script)" \ + "\n -s,--script=file Run file at DHCP events (default "CONFIG_DHCPC_DEFAULT_SCRIPT")" \ "\n -t,--retries=N Send up to N request packets" \ "\n -T,--timeout=N Try to get a lease for N seconds (default 3)" \ "\n -A,--tryagain=N Wait N seconds (default 20) after failure" \ + "\n -O,--request-option=OPT Request DHCP option OPT (cumulative)" \ + "\n -o,--no-default-options Do not request any options (unless -O is also given)" \ "\n -f,--foreground Run in foreground" \ "\n -b,--background Background if lease is not immediately obtained" \ "\n -S,--syslog Log to syslog too" \ "\n -n,--now Exit with failure if lease is not immediately obtained" \ "\n -q,--quit Quit after obtaining lease" \ "\n -R,--release Release IP on quit" \ - "\n -O,--request-option=OPT Request DHCP option OPT from server" \ USE_FEATURE_UDHCP_PORT( \ "\n -P,--client-port N Use port N instead of default 68" \ ) \ @@ -4153,17 +4154,18 @@ "\n -C Suppress default client identifier" \ "\n -p file Create pidfile" \ "\n -r IP IP address to request" \ - "\n -s file Run file at dhcp events (default /usr/share/udhcpc/default.script)" \ + "\n -s file Run file at DHCP events (default "CONFIG_DHCPC_DEFAULT_SCRIPT")" \ "\n -t N Send up to N request packets" \ "\n -T N Try to get a lease for N seconds (default 3)" \ "\n -A N Wait N seconds (default 20) after failure" \ + "\n -O OPT Request DHCP option OPT (cumulative)" \ + "\n -o Do not request any options (unless -O is also given)" \ "\n -f Run in foreground" \ "\n -b Background if lease is not immediately obtained" \ "\n -S Log to syslog too" \ "\n -n Exit with failure if lease is not immediately obtained" \ "\n -q Quit after obtaining lease" \ "\n -R Release IP on quit" \ - "\n -O OPT Request DHCP option OPT from server" \ USE_FEATURE_UDHCP_PORT( \ "\n -P N Use port N instead of default 68" \ ) \ Modified: trunk/busybox/networking/ifupdown.c =================================================================== --- trunk/busybox/networking/ifupdown.c 2008-04-02 00:18:57 UTC (rev 21618) +++ trunk/busybox/networking/ifupdown.c 2008-04-02 13:04:19 UTC (rev 21619) @@ -476,7 +476,8 @@ "pump -i %iface% -k", }, { "udhcpc", - "udhcpc -R -n -p /var/run/udhcpc.%iface%.pid -i %iface%[[ -H %hostname%]][[ -c %clientid%]][[ -s %script%]][[ -t %retries%]]", + "udhcpc -R -n -p /var/run/udhcpc.%iface%.pid -i %iface%[[ -H %hostname%]][[ -c %clientid%]]" + "[[ -s %script%]][[ %udhcpc_opts%]]", "kill `cat /var/run/udhcpc.%iface%.pid` 2>/dev/null", }, }; @@ -507,7 +508,7 @@ return 0; #endif return execute("udhcpc -R -n -p /var/run/udhcpc.%iface%.pid " - "-i %iface%[[ -H %hostname%]][[ -c %clientid%]][[ -s %script%]][[ -t %retries%]]", + "-i %iface%[[ -H %hostname%]][[ -c %clientid%]][[ -s %script%]][[ %udhcpc_opts%]]", ifd, exec); } #else Modified: trunk/busybox/networking/udhcp/clientpacket.c =================================================================== --- trunk/busybox/networking/udhcp/clientpacket.c 2008-04-02 00:18:57 UTC (rev 21618) +++ trunk/busybox/networking/udhcp/clientpacket.c 2008-04-02 13:04:19 UTC (rev 21619) @@ -62,17 +62,20 @@ int end = end_option(packet->options); int i, len = 0; - packet->options[end + OPT_CODE] = DHCP_PARAM_REQ; for (i = 0; (c = dhcp_options[i].code) != 0; i++) { - if ((dhcp_options[i].flags & OPTION_REQ) + if (((dhcp_options[i].flags & OPTION_REQ) + && !client_config.no_default_options) || (client_config.opt_mask[c >> 3] & (1 << (c & 7))) ) { packet->options[end + OPT_DATA + len] = c; len++; } } - packet->options[end + OPT_LEN] = len; - packet->options[end + OPT_DATA + len] = DHCP_END; + if (len) { + packet->options[end + OPT_CODE] = DHCP_PARAM_REQ; + packet->options[end + OPT_LEN] = len; + packet->options[end + OPT_DATA + len] = DHCP_END; + } } @@ -107,7 +110,9 @@ /* Explicitly saying that we want RFC-compliant packets helps * some buggy DHCP servers to NOT send bigger packets */ add_simple_option(packet.options, DHCP_MAX_SIZE, htons(576)); + add_param_req_option(&packet); + bb_info_msg("Sending discover..."); return udhcp_send_raw_packet(&packet, INADDR_ANY, CLIENT_PORT, INADDR_BROADCAST, SERVER_PORT, MAC_BCAST_ADDR, client_config.ifindex); @@ -125,8 +130,8 @@ add_simple_option(packet.options, DHCP_REQUESTED_IP, requested); add_simple_option(packet.options, DHCP_SERVER_ID, server); + add_param_req_option(&packet); - add_param_req_option(&packet); addr.s_addr = requested; bb_info_msg("Sending select for %s...", inet_ntoa(addr)); return udhcp_send_raw_packet(&packet, INADDR_ANY, CLIENT_PORT, INADDR_BROADCAST, Modified: trunk/busybox/networking/udhcp/dhcpc.c =================================================================== --- trunk/busybox/networking/udhcp/dhcpc.c 2008-04-02 00:18:57 UTC (rev 21618) +++ trunk/busybox/networking/udhcp/dhcpc.c 2008-04-02 13:04:19 UTC (rev 21619) @@ -182,6 +182,7 @@ OPT_W = 1 << 21, #endif OPT_P = 1 << 22, + OPT_o = 1 << 23, }; #if ENABLE_GETOPT_LONG static const char udhcpc_longopts[] ALIGN1 = @@ -211,6 +212,7 @@ #if ENABLE_FEATURE_UDHCP_PORT "client-port\0" Required_argument "P" #endif + "no-default-options\0" No_argument "o" ; #endif /* Default options. */ @@ -230,7 +232,7 @@ opt = getopt32(argv, "c:CV:fbH:h:F:i:np:qRr:s:T:t:vSA:" USE_FEATURE_UDHCPC_ARPING("aW:") USE_FEATURE_UDHCP_PORT("P:") - "O:" + "O:o" , &str_c, &str_V, &str_h, &str_h, &str_F , &client_config.interface, &client_config.pidfile, &str_r , &client_config.script @@ -291,6 +293,8 @@ SERVER_PORT = CLIENT_PORT - 1; } #endif + if (opt & OPT_o) + client_config.no_default_options = 1; while (list_O) { int n = index_in_strings(dhcp_option_strings, list_O->data); if (n < 0) Modified: trunk/busybox/networking/udhcp/dhcpc.h =================================================================== --- trunk/busybox/networking/udhcp/dhcpc.h 2008-04-02 00:18:57 UTC (rev 21618) +++ trunk/busybox/networking/udhcp/dhcpc.h 2008-04-02 13:04:19 UTC (rev 21619) @@ -21,6 +21,7 @@ char release_on_quit; /* Perform release on quit */ char abort_if_no_lease; /* Abort if no lease */ char background_if_no_lease; /* Fork to background if no lease */ + char no_default_options; /* Do not include default optins in request */ const char *interface; /* The name of the interface to use */ char *pidfile; /* Optionally store the process ID */ const char *script; /* User script to run at dhcp events */ Modified: trunk/busybox/networking/udhcp/files.c =================================================================== --- trunk/busybox/networking/udhcp/files.c 2008-04-02 00:18:57 UTC (rev 21618) +++ trunk/busybox/networking/udhcp/files.c 2008-04-02 13:04:19 UTC (rev 21619) @@ -396,6 +396,7 @@ close(fp); if (server_config.notify_file) { +// TODO: vfork-based child creation char *cmd = xasprintf("%s %s", server_config.notify_file, server_config.lease_file); system(cmd); free(cmd); @@ -406,7 +407,7 @@ void read_leases(const char *file) { int fp; - unsigned int i = 0; + unsigned i; struct dhcpOfferedAddr lease; fp = open_or_warn(file, O_RDONLY); @@ -414,6 +415,7 @@ return; } + i = 0; while (i < server_config.max_leases && full_read(fp, &lease, sizeof(lease)) == sizeof(lease) ) { @@ -422,7 +424,7 @@ if (y >= server_config.start_ip && y <= server_config.end_ip) { lease.expires = ntohl(lease.expires); if (!server_config.remaining) - lease.expires -= time(0); + lease.expires -= time(NULL); if (!(add_lease(lease.chaddr, lease.yiaddr, lease.expires))) { bb_error_msg("too many leases while loading %s", file); break; From bugs at busybox.net Wed Apr 2 07:48:53 2008 From: bugs at busybox.net (bugs at busybox.net) Date: Wed, 2 Apr 2008 07:48:53 -0700 Subject: [BusyBox 0002734]: "make menuconfig" unusable with colormake Message-ID: <7a48007c131189321e9c555359450d08@busybox.net> The following issue has been SUBMITTED. ====================================================================== http://busybox.net/bugs/view.php?id=2734 ====================================================================== Reported By: KiBi Assigned To: BusyBox ====================================================================== Project: BusyBox Issue ID: 2734 Category: Other Reproducibility: always Severity: minor Priority: normal Status: assigned ====================================================================== Date Submitted: 04-02-2008 07:48 PDT Last Modified: 04-02-2008 07:48 PDT ====================================================================== Summary: "make menuconfig" unusable with colormake Description: With MAKE=colormake, calling "make menuconfig" (or calling "colormake menuconfig" with MAKE unset) results in the screen being cleared, and then one gets: --8<--8<--8<-- # # using defaults found in .config # interrupted(11) make[1]: *** [menuconfig] Error 1 make: *** [menuconfig] Error 2 -->8-->8-->8-- It might be a problem in colormake as well, but I guess it could be handled at least more gracefully by the busybox build system. Happens with 1.9.2 and 1.10.0 at least (both of which not being available in the "product version" drop-down list anyway). ====================================================================== Issue History Date Modified Username Field Change ====================================================================== 04-02-08 07:48 KiBi New Issue 04-02-08 07:48 KiBi Status new => assigned 04-02-08 07:48 KiBi Assigned To => BusyBox ====================================================================== From bugs at busybox.net Wed Apr 2 11:15:59 2008 From: bugs at busybox.net (bugs at busybox.net) Date: Wed, 2 Apr 2008 11:15:59 -0700 Subject: [BusyBox 0002734]: "make menuconfig" unusable with colormake Message-ID: <83fea5d26dcfad6a894a853c4f2177ea@busybox.net> A NOTE has been added to this issue. ====================================================================== http://busybox.net/bugs/view.php?id=2734 ====================================================================== Reported By: KiBi Assigned To: BusyBox ====================================================================== Project: BusyBox Issue ID: 2734 Category: Other Reproducibility: always Severity: minor Priority: normal Status: assigned ====================================================================== Date Submitted: 04-02-2008 07:48 PDT Last Modified: 04-02-2008 11:15 PDT ====================================================================== Summary: "make menuconfig" unusable with colormake Description: With MAKE=colormake, calling "make menuconfig" (or calling "colormake menuconfig" with MAKE unset) results in the screen being cleared, and then one gets: --8<--8<--8<-- # # using defaults found in .config # interrupted(11) make[1]: *** [menuconfig] Error 1 make: *** [menuconfig] Error 2 -->8-->8-->8-- It might be a problem in colormake as well, but I guess it could be handled at least more gracefully by the busybox build system. Happens with 1.9.2 and 1.10.0 at least (both of which not being available in the "product version" drop-down list anyway). ====================================================================== ---------------------------------------------------------------------- vda - 04-02-08 11:15 ---------------------------------------------------------------------- Hmmm... Colormake --------- This is a simple wrapper for making the output from make easier to read (more colorful), and errors easier to find in messy compilations. It was inspired by Micheal T. Babcock's excellent logcolorize program. It most probalay got utterly confused by "make menuconfig"'s output which contains ESC sequences etc. I am not volunteering to fix it... Issue History Date Modified Username Field Change ====================================================================== 04-02-08 07:48 KiBi New Issue 04-02-08 07:48 KiBi Status new => assigned 04-02-08 07:48 KiBi Assigned To => BusyBox 04-02-08 11:15 vda Note Added: 0006324 ====================================================================== From bugs at busybox.net Wed Apr 2 12:19:21 2008 From: bugs at busybox.net (bugs at busybox.net) Date: Wed, 2 Apr 2008 12:19:21 -0700 Subject: [BusyBox 0002744]: cmp_common should use arith_t Message-ID: The following issue has been SUBMITTED. ====================================================================== http://busybox.net/bugs/view.php?id=2744 ====================================================================== Reported By: ianw Assigned To: BusyBox ====================================================================== Project: BusyBox Issue ID: 2744 Category: Other Reproducibility: always Severity: minor Priority: normal Status: assigned ====================================================================== Date Submitted: 04-02-2008 12:19 PDT Last Modified: 04-02-2008 12:19 PDT ====================================================================== Summary: cmp_common should use arith_t Description: I think cmp_common() should be using an arith_t rather than an int. ====================================================================== Issue History Date Modified Username Field Change ====================================================================== 04-02-08 12:19 ianw New Issue 04-02-08 12:19 ianw Status new => assigned 04-02-08 12:19 ianw Assigned To => BusyBox 04-02-08 12:19 ianw File Added: busybox-expr-arith.diff ====================================================================== From vda at busybox.net Wed Apr 2 13:24:10 2008 From: vda at busybox.net (vda at busybox.net) Date: Wed, 2 Apr 2008 13:24:10 -0700 (PDT) Subject: svn commit: trunk/busybox: coreutils testsuite/expr Message-ID: <20080402202410.8E3A93C56A@busybox.net> Author: vda Date: 2008-04-02 13:24:09 -0700 (Wed, 02 Apr 2008) New Revision: 21620 Log: expr: fix comparisons 'a < b' where we were overflowing a-b (not to mention that we used int, not arith_t). closes bug 2744. Also, shrink a bit and add testsuite entry function old new delta nextarg 75 84 +9 tostring 38 35 -3 toarith 89 86 -3 str_value 35 32 -3 eval6 555 552 -3 int_value 29 23 -6 eval4 128 120 -8 eval3 112 104 -8 eval2 512 417 -95 ------------------------------------------------------------------------------ (add/remove: 0/0 grow/shrink: 1/8 up/down: 9/-129) Total: -120 bytes Added: trunk/busybox/testsuite/expr/expr-big Modified: trunk/busybox/coreutils/expr.c Changeset: Modified: trunk/busybox/coreutils/expr.c =================================================================== --- trunk/busybox/coreutils/expr.c 2008-04-02 13:04:19 UTC (rev 21619) +++ trunk/busybox/coreutils/expr.c 2008-04-02 20:24:09 UTC (rev 21620) @@ -28,13 +28,6 @@ #include "libbb.h" #include "xregex.h" -/* The kinds of value we can have. */ -enum valtype { - integer, - string -}; -typedef enum valtype TYPE; - #if ENABLE_EXPR_MATH_SUPPORT_64 typedef int64_t arith_t; @@ -51,10 +44,16 @@ /* TODO: use bb_strtol[l]? It's easier to check for errors... */ +/* The kinds of value we can have. */ +enum { + INTEGER, + STRING +}; + /* A value is.... */ struct valinfo { - TYPE type; /* Which kind. */ - union { /* The value itself. */ + smallint type; /* Which kind. */ + union { /* The value itself. */ arith_t i; char *s; } u; @@ -77,8 +76,9 @@ { VALUE *v; - v = xmalloc(sizeof(VALUE)); - v->type = integer; + v = xzalloc(sizeof(VALUE)); + if (INTEGER) /* otherwise xzaaloc did it already */ + v->type = INTEGER; v->u.i = i; return v; } @@ -89,46 +89,47 @@ { VALUE *v; - v = xmalloc(sizeof(VALUE)); - v->type = string; + v = xzalloc(sizeof(VALUE)); + if (STRING) /* otherwise xzaaloc did it already */ + v->type = STRING; v->u.s = xstrdup(s); return v; } /* Free VALUE V, including structure components. */ -static void freev(VALUE * v) +static void freev(VALUE *v) { - if (v->type == string) + if (v->type == STRING) free(v->u.s); free(v); } /* Return nonzero if V is a null-string or zero-number. */ -static int null(VALUE * v) +static int null(VALUE *v) { - if (v->type == integer) + if (v->type == INTEGER) return v->u.i == 0; - /* string: */ + /* STRING: */ return v->u.s[0] == '\0' || LONE_CHAR(v->u.s, '0'); } -/* Coerce V to a string value (can't fail). */ +/* Coerce V to a STRING value (can't fail). */ -static void tostring(VALUE * v) +static void tostring(VALUE *v) { - if (v->type == integer) { + if (v->type == INTEGER) { v->u.s = xasprintf("%" PF_REZ "d", PF_REZ_TYPE v->u.i); - v->type = string; + v->type = STRING; } } -/* Coerce V to an integer value. Return 1 on success, 0 on failure. */ +/* Coerce V to an INTEGER value. Return 1 on success, 0 on failure. */ -static bool toarith(VALUE * v) +static bool toarith(VALUE *v) { - if (v->type == string) { + if (v->type == STRING) { arith_t i; char *e; @@ -139,50 +140,54 @@ return 0; free(v->u.s); v->u.i = i; - v->type = integer; + v->type = INTEGER; } return 1; } -/* Return nonzero if the next token matches STR exactly. +/* Return str[0]+str[1] if the next token matches STR exactly. STR must not be NULL. */ -static bool nextarg(const char *str) +static int nextarg(const char *str) { - if (*G.args == NULL) + if (*G.args == NULL || strcmp(*G.args, str) != 0) return 0; - return strcmp(*G.args, str) == 0; + return (unsigned char)str[0] + (unsigned char)str[1]; } /* The comparison operator handling functions. */ -static int cmp_common(VALUE * l, VALUE * r, int op) +static int cmp_common(VALUE *l, VALUE *r, int op) { - int cmpval; + arith_t ll, rr; - if (l->type == string || r->type == string) { + ll = l->u.i; + rr = r->u.i; + if (l->type == STRING || r->type == STRING) { tostring(l); tostring(r); - cmpval = strcmp(l->u.s, r->u.s); - } else - cmpval = l->u.i - r->u.i; + ll = strcmp(l->u.s, r->u.s); + rr = 0; + } + /* calculating ll - rr and checking the result is prone to overflows. + * We'll do it differently: */ if (op == '<') - return cmpval < 0; - if (op == ('L' + 'E')) - return cmpval <= 0; - if (op == '=') - return cmpval == 0; - if (op == '!') - return cmpval != 0; + return ll < rr; + if (op == ('<' + '=')) + return ll <= rr; + if (op == '=' || (op == '=' + '=')) + return ll == rr; + if (op == '!' + '=') + return ll != rr; if (op == '>') - return cmpval > 0; + return ll > rr; /* >= */ - return cmpval >= 0; + return ll >= rr; } /* The arithmetic operator handling functions. */ -static arith_t arithmetic_common(VALUE * l, VALUE * r, int op) +static arith_t arithmetic_common(VALUE *l, VALUE *r, int op) { arith_t li, ri; @@ -190,25 +195,24 @@ bb_error_msg_and_die("non-numeric argument"); li = l->u.i; ri = r->u.i; - if ((op == '/' || op == '%') && ri == 0) - bb_error_msg_and_die("division by zero"); if (op == '+') return li + ri; - else if (op == '-') + if (op == '-') return li - ri; - else if (op == '*') + if (op == '*') return li * ri; - else if (op == '/') + if (ri == 0) + bb_error_msg_and_die("division by zero"); + if (op == '/') return li / ri; - else - return li % ri; + return li % ri; } /* Do the : operator. SV is the VALUE for the lhs (the string), PV is the VALUE for the rhs (the pattern). */ -static VALUE *docolon(VALUE * sv, VALUE * pv) +static VALUE *docolon(VALUE *sv, VALUE *pv) { VALUE *v; regex_t re_buffer; @@ -230,14 +234,16 @@ /* expr uses an anchored pattern match, so check that there was a * match and that the match starts at offset 0. */ - if (regexec(&re_buffer, sv->u.s, NMATCH, re_regs, 0) != REG_NOMATCH && - re_regs[0].rm_so == 0) { + if (regexec(&re_buffer, sv->u.s, NMATCH, re_regs, 0) != REG_NOMATCH + && re_regs[0].rm_so == 0 + ) { /* Were \(...\) used? */ if (re_buffer.re_nsub > 0) { sv->u.s[re_regs[1].rm_eo] = '\0'; v = str_value(sv->u.s + re_regs[1].rm_so); - } else + } else { v = int_value(re_regs[0].rm_eo); + } } else { /* Match failed -- return the right kind of null. */ if (re_buffer.re_nsub > 0) @@ -327,7 +333,7 @@ v = str_value(""); else { v = xmalloc(sizeof(VALUE)); - v->type = string; + v->type = STRING; v->u.s = xstrndup(l->u.s + i1->u.i - 1, i2->u.i); } freev(l); @@ -367,14 +373,11 @@ l = eval5(); while (1) { - if (nextarg("*")) - op = '*'; - else if (nextarg("/")) - op = '/'; - else if (nextarg("%")) - op = '%'; - else - return l; + op = nextarg("*"); + if (!op) { op = nextarg("/"); + if (!op) { op = nextarg("%"); + if (!op) return l; + }} G.args++; r = eval5(); val = arithmetic_common(l, r, op); @@ -394,12 +397,11 @@ l = eval4(); while (1) { - if (nextarg("+")) - op = '+'; - else if (nextarg("-")) - op = '-'; - else - return l; + op = nextarg("+"); + if (!op) { + op = nextarg("-"); + if (!op) return l; + } G.args++; r = eval4(); val = arithmetic_common(l, r, op); @@ -419,20 +421,15 @@ l = eval3(); while (1) { - if (nextarg("<")) - op = '<'; - else if (nextarg("<=")) - op = 'L' + 'E'; - else if (nextarg("=") || nextarg("==")) - op = '='; - else if (nextarg("!=")) - op = '!'; - else if (nextarg(">=")) - op = 'G' + 'E'; - else if (nextarg(">")) - op = '>'; - else - return l; + op = nextarg("<"); + if (!op) { op = nextarg("<="); + if (!op) { op = nextarg("="); + if (!op) { op = nextarg("=="); + if (!op) { op = nextarg("!="); + if (!op) { op = nextarg(">="); + if (!op) { op = nextarg(">"); + if (!op) return l; + }}}}}} G.args++; r = eval3(); toarith(l); @@ -498,7 +495,7 @@ if (*G.args) bb_error_msg_and_die("syntax error"); - if (v->type == integer) + if (v->type == INTEGER) printf("%" PF_REZ "d\n", PF_REZ_TYPE v->u.i); else puts(v->u.s); Added: trunk/busybox/testsuite/expr/expr-big =================================================================== --- trunk/busybox/testsuite/expr/expr-big (rev 0) +++ trunk/busybox/testsuite/expr/expr-big 2008-04-02 20:24:09 UTC (rev 21620) @@ -0,0 +1,16 @@ +# busybox expr + +# 3*1000*1000*1000 overflows 32-bit signed int +res=`busybox expr 0 '<' 3000000000` +[ x"$res" = x1 ] || exit 1 + +# 9223372036854775807 = 2^31-1 +res=`busybox expr 0 '<' 9223372036854775807` +[ x"$res" = x1 ] || exit 1 +# coreutils fails this one! +res=`busybox expr -9223372036854775800 '<' 9223372036854775807` +[ x"$res" = x1 ] || exit 1 + +# This one works only by chance +# res=`busybox expr 0 '<' 9223372036854775808` +# [ x"$res" = x1 ] || exit 1 From bugs at busybox.net Wed Apr 2 13:24:39 2008 From: bugs at busybox.net (bugs at busybox.net) Date: Wed, 2 Apr 2008 13:24:39 -0700 Subject: [BusyBox 0002744]: cmp_common should use arith_t Message-ID: The following issue has been CLOSED ====================================================================== http://busybox.net/bugs/view.php?id=2744 ====================================================================== Reported By: ianw Assigned To: BusyBox ====================================================================== Project: BusyBox Issue ID: 2744 Category: Other Reproducibility: always Severity: minor Priority: normal Status: closed Resolution: open Fixed in Version: ====================================================================== Date Submitted: 04-02-2008 12:19 PDT Last Modified: 04-02-2008 13:24 PDT ====================================================================== Summary: cmp_common should use arith_t Description: I think cmp_common() should be using an arith_t rather than an int. ====================================================================== ---------------------------------------------------------------------- vda - 04-02-08 13:24 ---------------------------------------------------------------------- Fixed in rev 21620. Thanks! Issue History Date Modified Username Field Change ====================================================================== 04-02-08 12:19 ianw New Issue 04-02-08 12:19 ianw Status new => assigned 04-02-08 12:19 ianw Assigned To => BusyBox 04-02-08 12:19 ianw File Added: busybox-expr-arith.diff 04-02-08 13:24 vda Status assigned => closed 04-02-08 13:24 vda Note Added: 0006334 ====================================================================== From vda at busybox.net Wed Apr 2 14:20:37 2008 From: vda at busybox.net (vda at busybox.net) Date: Wed, 2 Apr 2008 14:20:37 -0700 (PDT) Subject: svn commit: trunk/busybox/coreutils Message-ID: <20080402212037.E62B93C40E@busybox.net> Author: vda Date: 2008-04-02 14:20:35 -0700 (Wed, 02 Apr 2008) New Revision: 21621 Log: dd: support conv=fsync dd: support "dd --" if CONFIG_DESKTOP=y function old new delta static.conv_words - 28 +28 dd_main 1369 1373 +4 static.keywords 848 827 -21 ------------------------------------------------------------------------------ (add/remove: 1/0 grow/shrink: 1/1 up/down: 32/-21) Total: 11 bytes Modified: trunk/busybox/coreutils/dd.c Changeset: Modified: trunk/busybox/coreutils/dd.c =================================================================== --- trunk/busybox/coreutils/dd.c 2008-04-02 20:24:09 UTC (rev 21620) +++ trunk/busybox/coreutils/dd.c 2008-04-02 21:20:35 UTC (rev 21621) @@ -79,23 +79,31 @@ #endif int dd_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; -int dd_main(int argc, char **argv) +int dd_main(int argc ATTRIBUTE_UNUSED, char **argv) { enum { - FLAG_SYNC = 1 << 0, - FLAG_NOERROR = 1 << 1, - FLAG_NOTRUNC = 1 << 2, - FLAG_TWOBUFS = 1 << 3, - FLAG_COUNT = 1 << 4, + /* Must be in the same order as OP_conv_XXX! */ + /* (see "flags |= (1 << what)" below) */ + FLAG_NOTRUNC = 1 << 0, + FLAG_SYNC = 1 << 1, + FLAG_NOERROR = 1 << 2, + FLAG_FSYNC = 1 << 3, + /* end of conv flags */ + FLAG_TWOBUFS = 1 << 4, + FLAG_COUNT = 1 << 5, }; static const char keywords[] ALIGN1 = "bs=\0""count=\0""seek=\0""skip=\0""if=\0""of=\0" #if ENABLE_FEATURE_DD_IBS_OBS - "ibs=\0""obs=\0""conv=\0""notrunc\0""sync\0""noerror\0" + "ibs=\0""obs=\0""conv=\0" #endif ; +#if ENABLE_FEATURE_DD_IBS_OBS + static const char conv_words[] ALIGN1 = + "notrunc\0""sync\0""noerror\0""fsync\0"; +#endif enum { - OP_bs = 1, + OP_bs = 0, OP_count, OP_seek, OP_skip, @@ -105,9 +113,23 @@ OP_ibs, OP_obs, OP_conv, - OP_conv_notrunc, + /* Must be in the same order as FLAG_XXX! */ + OP_conv_notrunc = 0, OP_conv_sync, OP_conv_noerror, + OP_conv_fsync, + /* Unimplemented conv=XXX: */ + //nocreat do not create the output file + //excl fail if the output file already exists + //fdatasync physically write output file data before finishing + //swab swap every pair of input bytes + //lcase change upper case to lower case + //ucase change lower case to upper case + //block pad newline-terminated records with spaces to cbs-size + //unblock replace trailing spaces in cbs-size records with newline + //ascii from EBCDIC to ASCII + //ebcdic from ASCII to EBCDIC + //ibm from ASCII to alternate EBCDIC #endif }; int exitcode = EXIT_FAILURE; @@ -138,85 +160,85 @@ signal_SA_RESTART_empty_mask(SIGUSR1, dd_output_status); #endif - for (n = 1; n < argc; n++) { - smalluint key_len; - smalluint what; - char *key; + for (n = 1; argv[n]; n++) { + int what; + char *val; char *arg = argv[n]; -//XXX:FIXME: we reject plain "dd --" This would cost ~20 bytes, so.. -//if (*arg == '-' && *++arg == '-' && !*++arg) continue; - key = strstr(arg, "="); - if (key == NULL) +#if ENABLE_DESKTOP + /* "dd --". NB: coreutils 6.9 will complain if they see + * more than one of them. We wouldn't. */ + if (arg[0] == '-' && arg[1] == '-' && arg[2] == '\0') + continue; +#endif + val = strchr(arg, '='); + if (val == NULL) bb_show_usage(); - key_len = key - arg + 1; - key = xstrndup(arg, key_len); - what = index_in_strings(keywords, key) + 1; - if (ENABLE_FEATURE_CLEAN_UP) - free(key); - if (what == 0) + *val = '\0'; + what = index_in_strings(keywords, arg); + if (what < 0) bb_show_usage(); - arg += key_len; + /* *val = '='; - to preserve ps listing? */ + val++; #if ENABLE_FEATURE_DD_IBS_OBS if (what == OP_ibs) { /* Must fit into positive ssize_t */ - ibs = xatoul_range_sfx(arg, 1, ((size_t)-1L)/2, dd_suffixes); - continue; + ibs = xatoul_range_sfx(val, 1, ((size_t)-1L)/2, dd_suffixes); + /*continue;*/ } if (what == OP_obs) { - obs = xatoul_range_sfx(arg, 1, ((size_t)-1L)/2, dd_suffixes); - continue; + obs = xatoul_range_sfx(val, 1, ((size_t)-1L)/2, dd_suffixes); + /*continue;*/ } if (what == OP_conv) { while (1) { - /* find ',', replace them with NUL so we can use arg for + /* find ',', replace them with NUL so we can use val for * index_in_strings() without copying. - * We rely on arg being non-null, else strchr would fault. + * We rely on val being non-null, else strchr would fault. */ - key = strchr(arg, ','); - if (key) - *key = '\0'; - what = index_in_strings(keywords, arg) + 1; - if (what < OP_conv_notrunc) - bb_error_msg_and_die(bb_msg_invalid_arg, arg, "conv"); - if (what == OP_conv_notrunc) - flags |= FLAG_NOTRUNC; - if (what == OP_conv_sync) - flags |= FLAG_SYNC; - if (what == OP_conv_noerror) - flags |= FLAG_NOERROR; - if (!key) /* no ',' left, so this was the last specifier */ + arg = strchr(val, ','); + if (arg) + *arg = '\0'; + what = index_in_strings(conv_words, val); + if (what < 0) + bb_error_msg_and_die(bb_msg_invalid_arg, val, "conv"); + flags |= (1 << what); + if (!arg) /* no ',' left, so this was the last specifier */ break; - arg = key + 1; /* skip this keyword and ',' */ + /* *arg = ','; - to preserve ps listing? */ + val = arg + 1; /* skip this keyword and ',' */ } - continue; + continue; /* we trashed 'what', can't fall through */ } #endif if (what == OP_bs) { - ibs = obs = xatoul_range_sfx(arg, 1, ((size_t)-1L)/2, dd_suffixes); - continue; + ibs = obs = xatoul_range_sfx(val, 1, ((size_t)-1L)/2, dd_suffixes); + /*continue;*/ } /* These can be large: */ if (what == OP_count) { flags |= FLAG_COUNT; - count = XATOU_SFX(arg, dd_suffixes); - continue; + count = XATOU_SFX(val, dd_suffixes); + /*continue;*/ } if (what == OP_seek) { - seek = XATOU_SFX(arg, dd_suffixes); - continue; + seek = XATOU_SFX(val, dd_suffixes); + /*continue;*/ } if (what == OP_skip) { - skip = XATOU_SFX(arg, dd_suffixes); - continue; + skip = XATOU_SFX(val, dd_suffixes); + /*continue;*/ } if (what == OP_if) { - infile = arg; - continue; + infile = val; + /*continue;*/ } - if (what == OP_of) - outfile = arg; - } + if (what == OP_of) { + outfile = val; + /*continue;*/ + } + } /* end of "for (argv[n])" */ + //XXX:FIXME for huge ibs or obs, malloc'ing them isn't the brightest idea ever ibuf = obuf = xmalloc(ibs); if (ibs != obs) { @@ -304,13 +326,17 @@ } } else if (write_and_stats(ibuf, n, obs, outfile)) goto out_status; + + if (flags & FLAG_FSYNC) { + if (fsync(ofd) < 0) + goto die_outfile; + } } if (ENABLE_FEATURE_DD_IBS_OBS && oc) { w = full_write_or_warn(obuf, oc, outfile); if (w < 0) goto out_status; - if (w > 0) - G.out_part++; + if (w > 0) G.out_part++; } if (close(ifd) < 0) { die_infile: From bugs at busybox.net Thu Apr 3 08:29:14 2008 From: bugs at busybox.net (bugs at busybox.net) Date: Thu, 3 Apr 2008 08:29:14 -0700 Subject: [BusyBox 0002764]: IPv6 support for busybox wget Message-ID: <5a63917cef6490ce9f982ac16dbdd6fd@bugs.busybox.net> The following issue has been SUBMITTED. ====================================================================== http://busybox.net/bugs/view.php?id=2764 ====================================================================== Reported By: Peter Eisentraut Assigned To: BusyBox ====================================================================== Project: BusyBox Issue ID: 2764 Category: Networking Support Reproducibility: have not tried Severity: feature Priority: normal Status: assigned ====================================================================== Date Submitted: 04-03-2008 08:29 PDT Last Modified: 04-03-2008 08:29 PDT ====================================================================== Summary: IPv6 support for busybox wget Description: I'm forwarding you this Debian bug report: . I am not an experienced busybox user, but I found that the patch posted there is not integrated in 1.9.2 yet, so it is probably still relevant. --- The attached patch, written by Jaap Eldering during some Debian BSPs for Etch in Utrecht, adds IPv6 support to busybox wget. This is wanted to support new installations over IPv6 using Debian Installer. Please review the patch and, if it looks OK, forward it upstream. I'm not entirely sure if the patch is completely finished, but it has allowed the author to actually use wget over IPv6. Below are some comments from the author of the patch. During yesterday evening's Bugsquashing "afterparty" I looked again into this IPv6 stuff and made some progress: I got busybox wget to download stuff over IPv{4,6} with http and ftp. Only thing is that it didn't graciously fallback to IPv4 when a host (ftp.surfnet.nl) rejected a connection on IPv6 ftp. I fixed a bug in my code from last time, where the parameter passed to 'connect' indicating the size of the 'sockaddr *' struct was not correct for IPv6 addresses. Furthermore I cloned the two functions 'xconnect' and 'bb_lookup_host' to 'xconnect2' and 'bb_lookup_host2' which take a pointer to a struct of a IPv4 _and_ IPv6 address, to facilitate the possibility of fallback at connect time. The diff to Debian patched busybox-1.1.3-3 sources is again attached. I'll probably try to fix this fallback behaviour in the next week or so, but I'm not sure that I have time. If it is urgent to get this into the etch installer, please let me know. The changes to the functions 'xconnect' and 'bb_lookup_host' might better be dropped to prevent bugs in other applets using those. [...] Another update, I think the last for the moment. I found that ftp over IPv6 didn't work correctly because passive ftp (which busybox wget uses) is implemented slightly different than over IPv4. This patch makes wget handle the port switch correctly for IPv6 too. Furthermore I renamed the combined IPv{4,6} struct to 'sockaddr_in4_in6' to make things more clear. ====================================================================== Issue History Date Modified Username Field Change ====================================================================== 04-03-08 08:29 Peter EisentrautNew Issue 04-03-08 08:29 Peter EisentrautStatus new => assigned 04-03-08 08:29 Peter EisentrautAssigned To => BusyBox 04-03-08 08:29 Peter EisentrautFile Added: busybox_1.1.3-3-ipv6-5.diff ====================================================================== From bugs at busybox.net Thu Apr 3 20:14:59 2008 From: bugs at busybox.net (bugs at busybox.net) Date: Thu, 3 Apr 2008 20:14:59 -0700 Subject: [BusyBox 0002764]: IPv6 support for busybox wget Message-ID: The following issue has been CLOSED ====================================================================== http://busybox.net/bugs/view.php?id=2764 ====================================================================== Reported By: Peter Eisentraut Assigned To: BusyBox ====================================================================== Project: BusyBox Issue ID: 2764 Category: Networking Support Reproducibility: have not tried Severity: feature Priority: normal Status: closed Resolution: open Fixed in Version: ====================================================================== Date Submitted: 04-03-2008 08:29 PDT Last Modified: 04-03-2008 20:14 PDT ====================================================================== Summary: IPv6 support for busybox wget Description: I'm forwarding you this Debian bug report: . I am not an experienced busybox user, but I found that the patch posted there is not integrated in 1.9.2 yet, so it is probably still relevant. --- The attached patch, written by Jaap Eldering during some Debian BSPs for Etch in Utrecht, adds IPv6 support to busybox wget. This is wanted to support new installations over IPv6 using Debian Installer. Please review the patch and, if it looks OK, forward it upstream. I'm not entirely sure if the patch is completely finished, but it has allowed the author to actually use wget over IPv6. Below are some comments from the author of the patch. During yesterday evening's Bugsquashing "afterparty" I looked again into this IPv6 stuff and made some progress: I got busybox wget to download stuff over IPv{4,6} with http and ftp. Only thing is that it didn't graciously fallback to IPv4 when a host (ftp.surfnet.nl) rejected a connection on IPv6 ftp. I fixed a bug in my code from last time, where the parameter passed to 'connect' indicating the size of the 'sockaddr *' struct was not correct for IPv6 addresses. Furthermore I cloned the two functions 'xconnect' and 'bb_lookup_host' to 'xconnect2' and 'bb_lookup_host2' which take a pointer to a struct of a IPv4 _and_ IPv6 address, to facilitate the possibility of fallback at connect time. The diff to Debian patched busybox-1.1.3-3 sources is again attached. I'll probably try to fix this fallback behaviour in the next week or so, but I'm not sure that I have time. If it is urgent to get this into the etch installer, please let me know. The changes to the functions 'xconnect' and 'bb_lookup_host' might better be dropped to prevent bugs in other applets using those. [...] Another update, I think the last for the moment. I found that ftp over IPv6 didn't work correctly because passive ftp (which busybox wget uses) is implemented slightly different than over IPv4. This patch makes wget handle the port switch correctly for IPv6 too. Furthermore I renamed the combined IPv{4,6} struct to 'sockaddr_in4_in6' to make things more clear. ====================================================================== ---------------------------------------------------------------------- vda - 04-03-08 20:14 ---------------------------------------------------------------------- This is fixed many versions ago. Now almost all networking applets work over IPv6. +struct sockaddr_in4_in6 { + int addr4_valid, addr6_valid; + struct in_addr addr4; +#ifdef CONFIG_FEATURE_IPV6 + struct in6_addr addr6; +#endif + in_port_t port; +}; Thank god we have only IPv4 and IPv6. It's horrifying to imagine how big this struct can become if someone will ever decide to support e.g. Unix domain sockets... Seriously, how about designing _generic_ interfaces? Issue History Date Modified Username Field Change ====================================================================== 04-03-08 08:29 Peter EisentrautNew Issue 04-03-08 08:29 Peter EisentrautStatus new => assigned 04-03-08 08:29 Peter EisentrautAssigned To => BusyBox 04-03-08 08:29 Peter EisentrautFile Added: busybox_1.1.3-3-ipv6-5.diff 04-03-08 20:14 vda Status assigned => closed 04-03-08 20:14 vda Note Added: 0006384 ====================================================================== From bugs at busybox.net Fri Apr 4 02:24:38 2008 From: bugs at busybox.net (bugs at busybox.net) Date: Fri, 4 Apr 2008 02:24:38 -0700 Subject: [BusyBox 0002814]: Logging on httpd Message-ID: <86d4a236886ac8979b460631b9fb9d14@busybox.net> The following issue has been SUBMITTED. ====================================================================== http://busybox.net/bugs/view.php?id=2814 ====================================================================== Reported By: opalenzuela Assigned To: BusyBox ====================================================================== Project: BusyBox Issue ID: 2814 Category: New Features Reproducibility: N/A Severity: feature Priority: normal Status: assigned ====================================================================== Date Submitted: 04-04-2008 02:24 PDT Last Modified: 04-04-2008 02:24 PDT ====================================================================== Summary: Logging on httpd Description: It may be interesting to enable logging options for httpd. For instance, an option in the configuration file like: L:/var/log/httpd.log It doesn't look too complicated, and it could be an interesting feature (specially as a debug tool for developers like me). ====================================================================== Issue History Date Modified Username Field Change ====================================================================== 04-04-08 02:24 opalenzuela New Issue 04-04-08 02:24 opalenzuela Status new => assigned 04-04-08 02:24 opalenzuela Assigned To => BusyBox ====================================================================== From bugs at busybox.net Fri Apr 4 09:59:19 2008 From: bugs at busybox.net (bugs at busybox.net) Date: Fri, 4 Apr 2008 09:59:19 -0700 Subject: [BusyBox 0002814]: Logging on httpd Message-ID: <2acda2d8fae0191496e87157630f664d@busybox.net> A NOTE has been added to this issue. ====================================================================== http://busybox.net/bugs/view.php?id=2814 ====================================================================== Reported By: opalenzuela Assigned To: BusyBox ====================================================================== Project: BusyBox Issue ID: 2814 Category: New Features Reproducibility: N/A Severity: feature Priority: normal Status: assigned ====================================================================== Date Submitted: 04-04-2008 02:24 PDT Last Modified: 04-04-2008 09:59 PDT ====================================================================== Summary: Logging on httpd Description: It may be interesting to enable logging options for httpd. For instance, an option in the configuration file like: L:/var/log/httpd.log It doesn't look too complicated, and it could be an interesting feature (specially as a debug tool for developers like me). ====================================================================== ---------------------------------------------------------------------- vda - 04-04-08 09:59 ---------------------------------------------------------------------- Have you tried "httpd -vvv ..." ? Issue History Date Modified Username Field Change ====================================================================== 04-04-08 02:24 opalenzuela New Issue 04-04-08 02:24 opalenzuela Status new => assigned 04-04-08 02:24 opalenzuela Assigned To => BusyBox 04-04-08 05:24 opalenzuela Issue Monitored: opalenzuela 04-04-08 09:59 vda Note Added: 0006404 ====================================================================== From vda at busybox.net Fri Apr 4 13:38:49 2008 From: vda at busybox.net (vda at busybox.net) Date: Fri, 4 Apr 2008 13:38:49 -0700 (PDT) Subject: svn commit: trunk/busybox/miscutils Message-ID: <20080404203850.092A73C327@busybox.net> Author: vda Date: 2008-04-04 13:38:49 -0700 (Fri, 04 Apr 2008) New Revision: 21638 Log: fbsplash: more compact support for named pipes + EOF scenario function old new delta fbsplash_main 1121 1043 -78 Modified: trunk/busybox/miscutils/fbsplash.c Changeset: Modified: trunk/busybox/miscutils/fbsplash.c =================================================================== --- trunk/busybox/miscutils/fbsplash.c 2008-04-04 18:03:12 UTC (rev 21637) +++ trunk/busybox/miscutils/fbsplash.c 2008-04-04 20:38:49 UTC (rev 21638) @@ -360,6 +360,8 @@ { const char *fb_device, *cfg_filename, *fifo_filename; FILE *fp = fp; // for compiler + char *num_buf; + unsigned num; bool bCursorOff; INIT_G(); @@ -392,49 +394,7 @@ return EXIT_SUCCESS; fp = xfopen_stdin(fifo_filename); - - while (1) { - struct stat statbuf; - unsigned num; - char *num_buf; - - fb_drawprogressbar(0); - // Block on read, waiting for some input. - // Use of style I/O allows to correctly - // handle a case when we have many buffered lines - // already in the pipe - while ((num_buf = xmalloc_fgetline(fp)) != NULL) { - if (strncmp(num_buf, "exit", 4) == 0) { - DEBUG_MESSAGE("exit"); - exit_cmd: - if (bCursorOff) { - // restore cursor - full_write(STDOUT_FILENO, "\x1b" "[?25h", 6); - } - return EXIT_SUCCESS; - } - num = atoi(num_buf); - if (isdigit(num_buf[0]) && (num <= 100)) { -#if DEBUG - char strVal[10]; - sprintf(strVal, "%d", num); - DEBUG_MESSAGE(strVal); -#endif - fb_drawprogressbar(num); - } - free(num_buf); - } - // We got EOF/error on fp - if (ferror(fp)) - goto exit_cmd; - fclose(fp); - if (LONE_DASH(fifo_filename) - || stat(fifo_filename, &statbuf) != 0 - || !S_ISFIFO(statbuf.st_mode) - ) { - goto exit_cmd; - } - // It's really a named pipe! + if (fp != stdin) { // For named pipes, we want to support this: // mkfifo cmd_pipe // fbsplash -f cmd_pipe .... & @@ -442,10 +402,37 @@ // echo 33 >cmd_pipe // ... // echo 66 >cmd_pipe - // This means that on EOF, we need to close/open cmd_pipe - // (just reading again works too, but it hogs CPU) - fp = xfopen_stdin(fifo_filename); // blocks on open - } // end of while (1) + // This means that we don't want fbsplash to get EOF + // when last writer closes input end. + // The simplest way is to open fifo for writing too + // and become an additional writer :) + open(fifo_filename, O_WRONLY); // errors are ignored + } + fb_drawprogressbar(0); + // Block on read, waiting for some input. + // Use of style I/O allows to correctly + // handle a case when we have many buffered lines + // already in the pipe + while ((num_buf = xmalloc_fgetline(fp)) != NULL) { + if (strncmp(num_buf, "exit", 4) == 0) { + DEBUG_MESSAGE("exit"); + break; + } + num = atoi(num_buf); + if (isdigit(num_buf[0]) && (num <= 100)) { +#if DEBUG + char strVal[10]; + sprintf(strVal, "%d", num); + DEBUG_MESSAGE(strVal); +#endif + fb_drawprogressbar(num); + } + free(num_buf); + } + + if (bCursorOff) // restore cursor + full_write(STDOUT_FILENO, "\x1b" "[?25h", 6); + return EXIT_SUCCESS; } From vda at busybox.net Fri Apr 4 17:07:47 2008 From: vda at busybox.net (vda at busybox.net) Date: Fri, 4 Apr 2008 17:07:47 -0700 (PDT) Subject: svn commit: trunk/busybox: archival include Message-ID: <20080405000747.A8B0C3C30B@busybox.net> Author: vda Date: 2008-04-04 17:07:46 -0700 (Fri, 04 Apr 2008) New Revision: 21639 Log: cpio: optional support for writing cpio files in newc format. by pascal.bellard AT ads-lu.com. function old new delta cpio_main 247 1122 +875 cpio_pad4 - 58 +58 gnu_dev_major 66 99 +33 gnu_dev_minor 38 57 +19 packed_usage 23964 23978 +14 ------------------------------------------------------------------------------ (add/remove: 1/0 grow/shrink: 4/0 up/down: 999/0) Total: 999 bytes Modified: trunk/busybox/archival/Config.in trunk/busybox/archival/cpio.c trunk/busybox/include/usage.h Changeset: Modified: trunk/busybox/archival/Config.in =================================================================== --- trunk/busybox/archival/Config.in 2008-04-04 20:38:49 UTC (rev 21638) +++ trunk/busybox/archival/Config.in 2008-04-05 00:07:46 UTC (rev 21639) @@ -78,6 +78,14 @@ Unless you have a specific application which requires cpio, you should probably say N here. +config FEATURE_CPIO_O + bool "Support for archive creation" + default n + depends on CPIO + help + This implementation of cpio can create cpio archives in the "newc" + format only. + config DPKG bool "dpkg" default n Modified: trunk/busybox/archival/cpio.c =================================================================== --- trunk/busybox/archival/cpio.c 2008-04-04 20:38:49 UTC (rev 21638) +++ trunk/busybox/archival/cpio.c 2008-04-05 00:07:46 UTC (rev 21639) @@ -7,35 +7,225 @@ * Licensed under GPLv2 or later, see file LICENSE in this tarball for details. * * Limitations: - * Doesn't check CRC's - * Only supports new ASCII and CRC formats + * Doesn't check CRC's + * Only supports new ASCII and CRC formats * */ #include "libbb.h" #include "unarchive.h" -#define CPIO_OPT_EXTRACT 0x01 -#define CPIO_OPT_TEST 0x02 -#define CPIO_OPT_UNCONDITIONAL 0x04 -#define CPIO_OPT_VERBOSE 0x08 -#define CPIO_OPT_FILE 0x10 -#define CPIO_OPT_CREATE_LEADING_DIR 0x20 -#define CPIO_OPT_PRESERVE_MTIME 0x40 +enum { + CPIO_OPT_EXTRACT = (1 << 0), + CPIO_OPT_TEST = (1 << 1), + CPIO_OPT_UNCONDITIONAL = (1 << 2), + CPIO_OPT_VERBOSE = (1 << 3), + CPIO_OPT_FILE = (1 << 4), + CPIO_OPT_CREATE_LEADING_DIR = (1 << 5), + CPIO_OPT_PRESERVE_MTIME = (1 << 6), + CPIO_OPT_CREATE = (1 << 7), + CPIO_OPT_FORMAT = (1 << 8), +}; +#if ENABLE_FEATURE_CPIO_O +static off_t cpio_pad4(off_t size) +{ + int i; + + i = (- size) & 3; + size += i; + while (--i >= 0) + bb_putchar('\0'); + return size; +} + +/* Return value will become exit code. + * It's ok to exit instead of return. */ +static int cpio_o(void) +{ + struct name_s { + struct name_s *next; + char name[1]; + }; + struct inodes_s { + struct inodes_s *next; + struct name_s *names; + struct stat st; + }; + + struct inodes_s *links = NULL; + off_t bytes = 0; /* output bytes count */ + + while (1) { + const char *name; + char *line; + struct stat st; + + line = xmalloc_fgetline(stdin); + + if (line) { + /* Strip leading "./[./]..." from the filename */ + name = line; + while (name[0] == '.' && name[1] == '/') { + while (*++name == '/') + continue; + } + if (!*name) { /* line is empty */ + free(line); + continue; + } + if (lstat(name, &st)) { + abort_cpio_o: + bb_simple_perror_msg_and_die(name); + } + + if (!(S_ISLNK(st.st_mode) || S_ISREG(st.st_mode))) + st.st_size = 0; /* paranoia */ + + /* Store hardlinks for later processing, dont output them */ + if (!S_ISDIR(st.st_mode) && st.st_nlink > 1) { + struct name_s *n; + struct inodes_s *l; + + /* Do we have this hardlink remembered? */ + l = links; + while (1) { + if (l == NULL) { + /* Not found: add new item to "links" list */ + l = xzalloc(sizeof(*l)); + l->st = st; + l->next = links; + links = l; + break; + } + if (l->st.st_ino == st.st_ino) { + /* found */ + break; + } + l = l->next; + } + /* Add new name to "l->names" list */ + n = xmalloc(sizeof(*n) + strlen(name)); + strcpy(n->name, name); + n->next = l->names; + l->names = n; + + free(line); + continue; + } + + } else { /* line == NULL: EOF */ + next_link: + if (links) { + /* Output hardlink's data */ + st = links->st; + name = links->names->name; + links->names = links->names->next; + /* GNU cpio is reported to emit file data + * only for the last instance. Mimic that. */ + if (links->names == NULL) + links = links->next; + else + st.st_size = 0; + /* NB: we leak links->names and/or links, + * this is intended (we exit soon anyway) */ + } else { + /* If no (more) hardlinks to output, + * output "trailer" entry */ + name = "TRAILER!!!"; + /* st.st_size == 0 is a must, but for uniformity + * in the output, we zero out everything */ + memset(&st, 0, sizeof(st)); + /* st.st_nlink = 1; - GNU cpio does this */ + } + } + + bytes += printf("070701" + "%08X%08X%08X%08X%08X%08X%08X" + "%08X%08X%08X%08X" /* GNU cpio uses uppercase hex */ + /* strlen+1: */ "%08X" + /* chksum: */ "00000000" /* (only for "070702" files) */ + /* name,NUL: */ "%s%c", + (unsigned)(uint32_t) st.st_ino, + (unsigned)(uint32_t) st.st_mode, + (unsigned)(uint32_t) st.st_uid, + (unsigned)(uint32_t) st.st_gid, + (unsigned)(uint32_t) st.st_nlink, + (unsigned)(uint32_t) st.st_mtime, + (unsigned)(uint32_t) st.st_size, + (unsigned)(uint32_t) major(st.st_dev), + (unsigned)(uint32_t) minor(st.st_dev), + (unsigned)(uint32_t) major(st.st_rdev), + (unsigned)(uint32_t) minor(st.st_rdev), + (unsigned)(strlen(name) + 1), + name, '\0'); + bytes = cpio_pad4(bytes); + + if (st.st_size) { + if (S_ISLNK(st.st_mode)) { + char *lpath = xmalloc_readlink_or_warn(name); + if (!lpath) + goto abort_cpio_o; + bytes += printf("%s", lpath); + free(lpath); + } else { /* S_ISREG */ + int fd = xopen(name, O_RDONLY); + fflush(stdout); + /* We must abort if file got shorter too! */ + if (bb_copyfd_size(fd, STDOUT_FILENO, st.st_size) != st.st_size) { + bb_error_msg_and_die("I/O error, of file '%s' was truncated", name); + } + bytes += st.st_size; + close(fd); + } + bytes = cpio_pad4(bytes); + } + + if (!line) { + if (links) + goto next_link; + /* TODO: GNU cpio pads trailer to 512 bytes, do we want that? */ + return EXIT_SUCCESS; + } + + free(line); + } /* end of "while (1)" */ +} +#endif + int cpio_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; -int cpio_main(int argc, char **argv) +int cpio_main(int argc ATTRIBUTE_UNUSED, char **argv) { archive_handle_t *archive_handle; - char *cpio_filename = NULL; + char *cpio_filename; +#if ENABLE_FEATURE_CPIO_O + const char *cpio_fmt = ""; +#endif unsigned opt; - /* Initialise */ + /* Initialize */ archive_handle = init_handle(); archive_handle->src_fd = STDIN_FILENO; archive_handle->seek = seek_by_read; archive_handle->flags = ARCHIVE_EXTRACT_NEWER | ARCHIVE_PRESERVE_DATE; +#if ENABLE_FEATURE_CPIO_O + opt = getopt32(argv, "ituvF:dmoH:", &cpio_filename, &cpio_fmt); + + if (opt & CPIO_OPT_CREATE) { + if (*cpio_fmt != 'n') + bb_show_usage(); + if (opt & CPIO_OPT_FILE) { + fclose(stdout); + stdout = fopen(cpio_filename, "w"); + /* Paranoia: I don't trust libc that much */ + xdup2(fileno(stdout), STDOUT_FILENO); + } + return cpio_o(); + } +#else opt = getopt32(argv, "ituvF:dm", &cpio_filename); +#endif + argv += optind; /* One of either extract or test options must be given */ if ((opt & (CPIO_OPT_TEST | CPIO_OPT_EXTRACT)) == 0) { @@ -63,7 +253,7 @@ archive_handle->action_header = header_list; } } - if (cpio_filename) { /* CPIO_OPT_FILE */ + if (opt & CPIO_OPT_FILE) { /* -F */ archive_handle->src_fd = xopen(cpio_filename, O_RDONLY); archive_handle->seek = seek_by_jump; } @@ -71,13 +261,14 @@ archive_handle->flags |= ARCHIVE_CREATE_LEADING_DIRS; } - while (optind < argc) { + while (*argv) { archive_handle->filter = filter_accept_list; - llist_add_to(&(archive_handle->accept), argv[optind]); - optind++; + llist_add_to(&(archive_handle->accept), *argv); + argv++; } - while (get_header_cpio(archive_handle) == EXIT_SUCCESS); + while (get_header_cpio(archive_handle) == EXIT_SUCCESS) + continue; return EXIT_SUCCESS; } Modified: trunk/busybox/include/usage.h =================================================================== --- trunk/busybox/include/usage.h 2008-04-04 20:38:49 UTC (rev 21638) +++ trunk/busybox/include/usage.h 2008-04-05 00:07:46 UTC (rev 21639) @@ -509,13 +509,20 @@ "\n -l,-s Create (sym)links" \ #define cpio_trivial_usage \ - "-[dimtuv][F cpiofile]" + "-[dim" USE_FEATURE_CPIO_O("o") "tuv][F cpiofile]" \ + USE_FEATURE_CPIO_O( "[H newc]" ) #define cpio_full_usage \ - "Extract or list files from a cpio archive\n" \ + "Extract or list files from a cpio archive" \ + USE_FEATURE_CPIO_O( ", or create a cpio archive" ) \ + "\n" \ "Main operation mode:" \ "\n d Make leading directories" \ "\n i Extract" \ "\n m Preserve mtime" \ + USE_FEATURE_CPIO_O( \ + "\n o Create" \ + "\n H newc Define format" \ + ) \ "\n t List" \ "\n v Verbose" \ "\n u Unconditional overwrite" \ From vda at busybox.net Fri Apr 4 17:13:19 2008 From: vda at busybox.net (vda at busybox.net) Date: Fri, 4 Apr 2008 17:13:19 -0700 (PDT) Subject: svn commit: trunk/busybox/archival Message-ID: <20080405001319.8D50F3C320@busybox.net> Author: vda Date: 2008-04-04 17:13:19 -0700 (Fri, 04 Apr 2008) New Revision: 21640 Log: cpio: typo fix in error message Modified: trunk/busybox/archival/cpio.c Changeset: Modified: trunk/busybox/archival/cpio.c =================================================================== --- trunk/busybox/archival/cpio.c 2008-04-05 00:07:46 UTC (rev 21639) +++ trunk/busybox/archival/cpio.c 2008-04-05 00:13:19 UTC (rev 21640) @@ -172,7 +172,7 @@ fflush(stdout); /* We must abort if file got shorter too! */ if (bb_copyfd_size(fd, STDOUT_FILENO, st.st_size) != st.st_size) { - bb_error_msg_and_die("I/O error, of file '%s' was truncated", name); + bb_error_msg_and_die("I/O error or file '%s' was truncated", name); } bytes += st.st_size; close(fd); From vda at busybox.net Fri Apr 4 19:44:31 2008 From: vda at busybox.net (vda at busybox.net) Date: Fri, 4 Apr 2008 19:44:31 -0700 (PDT) Subject: svn commit: trunk/busybox: archival archival/libunarchive scripts Message-ID: <20080405024431.878703C308@busybox.net> Author: vda Date: 2008-04-04 19:44:30 -0700 (Fri, 04 Apr 2008) New Revision: 21641 Log: cpio: fix a bug where we do not extract zero-sized hardlinks (spotted at http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=466771). Add testsuite entry for that, and another one for another bug: we do not list hardlinks in cpio -t (not fixed). function old new delta get_header_cpio 884 909 +25 static.saved_hardlinks_created - 4 +4 static.pending_hardlinks 4 - -4 static.inode 4 - -4 cpio_main 1122 1060 -62 Modified: trunk/busybox/TODO_config_nommu trunk/busybox/archival/Config.in trunk/busybox/archival/cpio.c trunk/busybox/archival/libunarchive/data_extract_all.c trunk/busybox/archival/libunarchive/get_header_cpio.c trunk/busybox/archival/libunarchive/seek_by_jump.c trunk/busybox/scripts/defconfig Changeset: Modified: trunk/busybox/TODO_config_nommu =================================================================== --- trunk/busybox/TODO_config_nommu 2008-04-05 00:13:19 UTC (rev 21640) +++ trunk/busybox/TODO_config_nommu 2008-04-05 02:44:30 UTC (rev 21641) @@ -130,7 +130,6 @@ # # Common options for cpio and tar # -CONFIG_FEATURE_UNARCHIVE_TAPE=y # # Common options for dpkg and dpkg_deb Modified: trunk/busybox/archival/Config.in =================================================================== --- trunk/busybox/archival/Config.in 2008-04-05 00:13:19 UTC (rev 21640) +++ trunk/busybox/archival/Config.in 2008-04-05 02:44:30 UTC (rev 21641) @@ -307,13 +307,6 @@ comment "Common options for cpio and tar" depends on CPIO || TAR -config FEATURE_UNARCHIVE_TAPE - bool "Enable tape drive support" - default n - depends on CPIO || TAR - help - I don't think this is needed anymore. - comment "Common options for dpkg and dpkg_deb" depends on DPKG || DPKG_DEB Modified: trunk/busybox/archival/cpio.c =================================================================== --- trunk/busybox/archival/cpio.c 2008-04-05 00:13:19 UTC (rev 21640) +++ trunk/busybox/archival/cpio.c 2008-04-05 02:44:30 UTC (rev 21641) @@ -171,9 +171,7 @@ int fd = xopen(name, O_RDONLY); fflush(stdout); /* We must abort if file got shorter too! */ - if (bb_copyfd_size(fd, STDOUT_FILENO, st.st_size) != st.st_size) { - bb_error_msg_and_die("I/O error or file '%s' was truncated", name); - } + bb_copyfd_exact_size(fd, STDOUT_FILENO, st.st_size); bytes += st.st_size; close(fd); } Modified: trunk/busybox/archival/libunarchive/data_extract_all.c =================================================================== --- trunk/busybox/archival/libunarchive/data_extract_all.c 2008-04-05 00:13:19 UTC (rev 21640) +++ trunk/busybox/archival/libunarchive/data_extract_all.c 2008-04-05 02:44:30 UTC (rev 21641) @@ -20,7 +20,7 @@ /* Check if the file already exists */ if (archive_handle->flags & ARCHIVE_EXTRACT_UNCONDITIONAL) { - /* Remove the existing entry if it exists */ + /* Remove the entry if it exists */ if (((file_header->mode & S_IFMT) != S_IFDIR) && (unlink(file_header->name) == -1) && (errno != ENOENT) Modified: trunk/busybox/archival/libunarchive/get_header_cpio.c =================================================================== --- trunk/busybox/archival/libunarchive/get_header_cpio.c 2008-04-05 00:13:19 UTC (rev 21640) +++ trunk/busybox/archival/libunarchive/get_header_cpio.c 2008-04-05 02:44:30 UTC (rev 21641) @@ -8,70 +8,32 @@ #include "unarchive.h" typedef struct hardlinks_s { - char *name; - int inode; struct hardlinks_s *next; + int inode; /* TODO: must match maj/min too! */ + int mode ; + int mtime; /* These three are useful only in corner case */ + int uid ; /* of hardlinks with zero size body */ + int gid ; + char name[1]; } hardlinks_t; char get_header_cpio(archive_handle_t *archive_handle) { static hardlinks_t *saved_hardlinks = NULL; - static unsigned pending_hardlinks = 0; - static int inode; + static hardlinks_t *saved_hardlinks_created = NULL; file_header_t *file_header = archive_handle->file_header; char cpio_header[110]; + char dummy[16]; int namesize; - char dummy[16]; - int major, minor, nlink; + int major, minor, nlink, mode, inode; + unsigned size, uid, gid, mtime; - if (pending_hardlinks) { /* Deal with any pending hardlinks */ - hardlinks_t *tmp, *oldtmp; - - tmp = saved_hardlinks; - oldtmp = NULL; - - file_header->link_target = file_header->name; - file_header->size = 0; - - while (tmp) { - if (tmp->inode != inode) { - tmp = tmp->next; - continue; - } - - file_header->name = tmp->name; - - if (archive_handle->filter(archive_handle) == EXIT_SUCCESS) { - archive_handle->action_data(archive_handle); - archive_handle->action_header(archive_handle->file_header); - } - - pending_hardlinks--; - - oldtmp = tmp; - tmp = tmp->next; - free(oldtmp->name); - free(oldtmp); - if (oldtmp == saved_hardlinks) - saved_hardlinks = tmp; - } - - file_header->name = file_header->link_target; - - if (pending_hardlinks > 1) { - bb_error_msg("error resolving hardlink: archive made by GNU cpio 2.0-2.2?"); - } - - /* No more pending hardlinks, read next file entry */ - pending_hardlinks = 0; - } - /* There can be padding before archive header */ data_align(archive_handle, 4); if (archive_xread_all_eof(archive_handle, (unsigned char*)cpio_header, 110) == 0) { - return EXIT_FAILURE; + goto create_hardlinks; } archive_handle->offset += 110; @@ -81,17 +43,19 @@ bb_error_msg_and_die("unsupported cpio format, use newc or crc"); } - { - unsigned long tmpsize; - sscanf(cpio_header, "%6c%8x%8x%8x%8x%8x%8lx%8lx%16c%8x%8x%8x%8c", - dummy, &inode, (unsigned int*)&file_header->mode, - (unsigned int*)&file_header->uid, (unsigned int*)&file_header->gid, - &nlink, &file_header->mtime, &tmpsize, - dummy, &major, &minor, &namesize, dummy); - file_header->size = tmpsize; - } + sscanf(cpio_header + 6, + "%8x" "%8x" "%8x" "%8x" + "%8x" "%8x" "%8x" /*maj,min:*/ "%16c" + /*rmaj,rmin:*/"%8x" "%8x" "%8x" /*chksum:*/ "%8c", + &inode, &mode, &uid, &gid, + &nlink, &mtime, &size, dummy, + &major, &minor, &namesize, dummy); + file_header->mode = mode; + file_header->uid = uid; + file_header->gid = gid; + file_header->mtime = mtime; + file_header->size = size; - free(file_header->name); file_header->name = xzalloc(namesize + 1); /* Read in filename */ xread(archive_handle->src_fd, file_header->name, namesize); @@ -101,25 +65,9 @@ data_align(archive_handle, 4); if (strcmp(file_header->name, "TRAILER!!!") == 0) { - /* Always round up */ - printf("%d blocks\n", (int) (archive_handle->offset % 512 ? - archive_handle->offset / 512 + 1 : - archive_handle->offset / 512 - )); - if (saved_hardlinks) { /* Bummer - we still have unresolved hardlinks */ - hardlinks_t *tmp = saved_hardlinks; - hardlinks_t *oldtmp = NULL; - while (tmp) { - bb_error_msg("%s not created: cannot resolve hardlink", tmp->name); - oldtmp = tmp; - tmp = tmp->next; - free(oldtmp->name); - free(oldtmp); - } - saved_hardlinks = NULL; - pending_hardlinks = 0; - } - return EXIT_FAILURE; + /* Always round up. ">> 9" divides by 512 */ + printf("%"OFF_FMT"u blocks\n", (archive_handle->offset + 511) >> 9); + goto create_hardlinks; } if (S_ISLNK(file_header->mode)) { @@ -130,25 +78,33 @@ } else { file_header->link_target = NULL; } - if (nlink > 1 && !S_ISDIR(file_header->mode)) { - if (file_header->size == 0) { /* Put file on a linked list for later */ - hardlinks_t *new = xmalloc(sizeof(hardlinks_t)); + +// TODO: data_extract_all can't deal with hardlinks to non-files... +// (should be !S_ISDIR instead of S_ISREG here) + + if (nlink > 1 && S_ISREG(file_header->mode)) { + hardlinks_t *new = xmalloc(sizeof(*new) + namesize); + new->inode = inode; + new->mode = mode ; + new->mtime = mtime; + new->uid = uid ; + new->gid = gid ; + strcpy(new->name, file_header->name); + /* Put file on a linked list for later */ + if (size == 0) { new->next = saved_hardlinks; - new->inode = inode; - /* name current allocated, freed later */ - new->name = file_header->name; - file_header->name = NULL; saved_hardlinks = new; return EXIT_SUCCESS; /* Skip this one */ + /* TODO: this breaks cpio -t (it does not show hardlinks) */ } - /* Found the file with data in */ - pending_hardlinks = nlink; + new->next = saved_hardlinks_created; + saved_hardlinks_created = new; } file_header->device = makedev(major, minor); if (archive_handle->filter(archive_handle) == EXIT_SUCCESS) { archive_handle->action_data(archive_handle); - archive_handle->action_header(archive_handle->file_header); + archive_handle->action_header(file_header); } else { data_skip(archive_handle); } @@ -156,6 +112,57 @@ archive_handle->offset += file_header->size; free(file_header->link_target); + free(file_header->name); + file_header->link_target = NULL; + file_header->name = NULL; return EXIT_SUCCESS; + + create_hardlinks: + free(file_header->link_target); + free(file_header->name); + + while (saved_hardlinks) { + hardlinks_t *cur; + hardlinks_t *make_me = saved_hardlinks; + saved_hardlinks = make_me->next; + + memset(file_header, 0, sizeof(*file_header)); + file_header->name = make_me->name; + file_header->mode = make_me->mode; + /*file_header->size = 0;*/ + + /* Try to find a file we are hardlinked to */ + cur = saved_hardlinks_created; + while (cur) { + /* TODO: must match maj/min too! */ + if (cur->inode == make_me->inode) { + file_header->link_target = cur->name; + /* link_target != NULL, size = 0: "I am a hardlink" */ + if (archive_handle->filter(archive_handle) == EXIT_SUCCESS) + archive_handle->action_data(archive_handle); + free(make_me); + goto next_link; + } + } + /* Oops... no file with such inode was created... do it now + * (happens when hardlinked files are empty (zero length)) */ + file_header->mtime = make_me->mtime; + file_header->uid = make_me->uid ; + file_header->gid = make_me->gid ; + if (archive_handle->filter(archive_handle) == EXIT_SUCCESS) + archive_handle->action_data(archive_handle); + /* Move to the list of created hardlinked files */ + make_me->next = saved_hardlinks_created; + saved_hardlinks_created = make_me; + next_link: ; + } + + while (saved_hardlinks_created) { + hardlinks_t *p = saved_hardlinks_created; + saved_hardlinks_created = p->next; + free(p); + } + + return EXIT_FAILURE; /* "No more files to process" */ } Modified: trunk/busybox/archival/libunarchive/seek_by_jump.c =================================================================== --- trunk/busybox/archival/libunarchive/seek_by_jump.c 2008-04-05 00:13:19 UTC (rev 21640) +++ trunk/busybox/archival/libunarchive/seek_by_jump.c 2008-04-05 02:44:30 UTC (rev 21641) @@ -9,11 +9,9 @@ void seek_by_jump(const archive_handle_t *archive_handle, unsigned amount) { if (lseek(archive_handle->src_fd, (off_t) amount, SEEK_CUR) == (off_t) -1) { -#if ENABLE_FEATURE_UNARCHIVE_TAPE - if (errno == ESPIPE) { + if (errno == ESPIPE) seek_by_read(archive_handle, amount); - } else -#endif + else bb_perror_msg_and_die("seek failure"); } } Modified: trunk/busybox/scripts/defconfig =================================================================== --- trunk/busybox/scripts/defconfig 2008-04-05 00:13:19 UTC (rev 21640) +++ trunk/busybox/scripts/defconfig 2008-04-05 02:44:30 UTC (rev 21641) @@ -130,7 +130,6 @@ # # Common options for cpio and tar # -CONFIG_FEATURE_UNARCHIVE_TAPE=y # CONFIG_FEATURE_DEB_TAR_GZ is not set # CONFIG_FEATURE_DEB_TAR_BZ2 is not set # CONFIG_FEATURE_DEB_TAR_LZMA is not set From vda at busybox.net Fri Apr 4 19:46:48 2008 From: vda at busybox.net (vda at busybox.net) Date: Fri, 4 Apr 2008 19:46:48 -0700 (PDT) Subject: svn commit: trunk/busybox/testsuite Message-ID: <20080405024648.4D5583C318@busybox.net> Author: vda Date: 2008-04-04 19:46:47 -0700 (Fri, 04 Apr 2008) New Revision: 21642 Log: cpio: actually add testsuite entry... Added: trunk/busybox/testsuite/cpio.tests Changeset: Added: trunk/busybox/testsuite/cpio.tests =================================================================== --- trunk/busybox/testsuite/cpio.tests (rev 0) +++ trunk/busybox/testsuite/cpio.tests 2008-04-05 02:46:47 UTC (rev 21642) @@ -0,0 +1,58 @@ +#!/bin/sh +# Copyright 2008 by Denys Vlasenko +# Licensed under GPL v2, see file LICENSE for details. + +. testing.sh + +# ls -ln is showing date. Need to remove that, it's variable +# sed: coalesce spaces +# cut: remove date +FILTER_LS="sed 's/ */ /g' | cut -d' ' -f 1-5,9-" + + +# newc cpio archive of directory cpio.testdir with empty x and y hardlinks +hexdump="\ +00000000 42 5a 68 39 31 41 59 26 53 59 64 1e 91 8c 00 00 +00000010 48 7f 80 4c 48 08 00 28 01 ff e0 3f 24 14 00 0e +00000020 20 dc 60 20 00 92 11 ea a0 1a 00 00 00 03 20 8a +00000030 93 d4 9a 68 1a 0d 1e 91 a1 a0 06 98 e3 5c 2f d9 +00000040 26 a1 25 24 20 ed 47 c7 21 40 2b 6e f2 e6 fe 98 +00000050 13 68 a8 bd 82 b2 4f 26 02 24 16 5b 22 16 72 74 +00000060 15 cd c1 a6 9e a6 5e 6c 16 37 35 01 99 c4 81 21 +00000070 29 28 4b 69 51 a9 3c 1a 9b 0a e1 e4 b4 af 85 73 +00000080 ba 23 10 59 e8 b3 e1 a1 63 05 8c 4f c5 dc 91 4e +00000090 14 24 19 07 a4 63 00 +" + +rm -rf cpio.testdir + +# testing "test name" "options" "expected result" "file input" "stdin" + +testing "cpio extracts zero-sized hardlinks" \ + "echo '$hexdump' | hexdump -R | bzcat | cpio -i; echo \$?; + ls -ln cpio.testdir | $FILTER_LS" \ +"\ +1 blocks +0 +-rw-r--r-- 2 0 0 0 x +-rw-r--r-- 2 0 0 0 y +" \ + "" "" + +# Currently fails. Numerous: "1 blocks" versus "1 block", +# "1 block" must go to stderr, does not list cpio.testdir/x and cpio.testdir/y +testing "cpio lists hardlinks" \ + "echo '$hexdump' | hexdump -R | bzcat | cpio -t 2>&1; echo \$?" \ +"\ +1 block +cpio.testdir +cpio.testdir/x +cpio.testdir/y +0 +" \ + "" "" + +# clean up +rm -rf cpio.testdir + +exit $FAILCOUNT Property changes on: trunk/busybox/testsuite/cpio.tests ___________________________________________________________________ Name: svn:executable + * From vda at busybox.net Fri Apr 4 21:24:25 2008 From: vda at busybox.net (vda at busybox.net) Date: Fri, 4 Apr 2008 21:24:25 -0700 (PDT) Subject: svn commit: trunk/busybox/init Message-ID: <20080405042425.1DEA83C342@busybox.net> Author: vda Date: 2008-04-04 21:24:23 -0700 (Fri, 04 Apr 2008) New Revision: 21643 Log: init: fix askfirst not working as intended Modified: trunk/busybox/init/init.c Changeset: Modified: trunk/busybox/init/init.c =================================================================== --- trunk/busybox/init/init.c 2008-04-05 02:46:47 UTC (rev 21642) +++ trunk/busybox/init/init.c 2008-04-05 04:24:23 UTC (rev 21643) @@ -33,14 +33,15 @@ #endif /* Allowed init action types */ -#define SYSINIT 0x001 -#define RESPAWN 0x002 -#define ASKFIRST 0x004 -#define WAIT 0x008 -#define ONCE 0x010 -#define CTRLALTDEL 0x020 -#define SHUTDOWN 0x040 -#define RESTART 0x080 +#define SYSINIT 0x01 +#define RESPAWN 0x02 +/* like respawn, but wait for to be pressed on tty: */ +#define ASKFIRST 0x04 +#define WAIT 0x08 +#define ONCE 0x10 +#define CTRLALTDEL 0x20 +#define SHUTDOWN 0x40 +#define RESTART 0x80 #define STR_SYSINIT "\x01" #define STR_RESPAWN "\x02" @@ -372,7 +373,10 @@ sigemptyset(&nmask); sigaddset(&nmask, SIGCHLD); sigprocmask(SIG_BLOCK, &nmask, &omask); - pid = vfork(); + if (BB_MMU && (a->action_type & ASKFIRST)) + pid = fork(); + else + pid = vfork(); sigprocmask(SIG_SETMASK, &omask, NULL); if (pid < 0) @@ -447,7 +451,8 @@ } #endif - /* NB: on NOMMU we can't wait for input in child */ + /* NB: on NOMMU we can't wait for input in child, so + * "askfirst" will work the same as "respawn". */ if (BB_MMU && (a->action_type & ASKFIRST)) { static const char press_enter[] ALIGN1 = #ifdef CUSTOMIZED_BANNER @@ -499,7 +504,7 @@ for (a = init_action_list; a; a = tmp) { tmp = a->next; - if (a->action_type == action_type) { + if (a->action_type & action_type) { // Pointless: run() will error out if open of device fails. ///* a->terminal of "" means "init's console" */ //if (a->terminal[0] && access(a->terminal, R_OK | W_OK)) { @@ -784,6 +789,7 @@ fclose(file); } +#if ENABLE_FEATURE_USE_INITTAB static void reload_signal(int sig ATTRIBUTE_UNUSED) { struct init_action *a, *tmp; @@ -827,8 +833,9 @@ delete_init_action(a); } } - run_actions(RESPAWN); + run_actions(RESPAWN | ASKFIRST); } +#endif int init_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; int init_main(int argc ATTRIBUTE_UNUSED, char **argv) @@ -952,19 +959,17 @@ run_actions(ONCE); /* Redefine SIGHUP to reread /etc/inittab */ - if (ENABLE_FEATURE_USE_INITTAB) - signal(SIGHUP, reload_signal); - else - signal(SIGHUP, SIG_IGN); +#if ENABLE_FEATURE_USE_INITTAB + signal(SIGHUP, reload_signal); +#else + signal(SIGHUP, SIG_IGN); +#endif /* Now run the looping stuff for the rest of forever */ while (1) { - /* run the respawn stuff */ - run_actions(RESPAWN); + /* run the respawn/askfirst stuff */ + run_actions(RESPAWN | ASKFIRST); - /* run the askfirst stuff */ - run_actions(ASKFIRST); - /* Don't consume all CPU time -- sleep a bit */ sleep(1); From vda at busybox.net Sun Apr 6 00:17:03 2008 From: vda at busybox.net (vda at busybox.net) Date: Sun, 6 Apr 2008 00:17:03 -0700 (PDT) Subject: svn commit: trunk/busybox: include libbb networking Message-ID: <20080406071703.3095D3C376@busybox.net> Author: vda Date: 2008-04-06 00:17:02 -0700 (Sun, 06 Apr 2008) New Revision: 21646 Log: brctl: optional support for "show" cmd (by L. Gabriel Somlo ) function old new delta brctl_main 739 1186 +447 if_indextoname - 104 +104 static.keywords 827 841 +14 static.ops - 7 +7 packed_usage 23978 23976 -2 Modified: trunk/busybox/include/libbb.h trunk/busybox/include/usage.h trunk/busybox/libbb/xfuncs.c trunk/busybox/networking/Config.in trunk/busybox/networking/brctl.c Changeset: Modified: trunk/busybox/include/libbb.h =================================================================== --- trunk/busybox/include/libbb.h 2008-04-05 16:59:44 UTC (rev 21645) +++ trunk/busybox/include/libbb.h 2008-04-06 07:17:02 UTC (rev 21646) @@ -1017,15 +1017,15 @@ int get_terminal_width_height(int fd, int *width, int *height); int ioctl_or_perror(int fd, int request, void *argp, const char *fmt,...) __attribute__ ((format (printf, 4, 5))); -void ioctl_or_perror_and_die(int fd, int request, void *argp, const char *fmt,...) __attribute__ ((format (printf, 4, 5))); +int ioctl_or_perror_and_die(int fd, int request, void *argp, const char *fmt,...) __attribute__ ((format (printf, 4, 5))); #if ENABLE_IOCTL_HEX2STR_ERROR int bb_ioctl_or_warn(int fd, int request, void *argp, const char *ioctl_name); -void bb_xioctl(int fd, int request, void *argp, const char *ioctl_name); +int bb_xioctl(int fd, int request, void *argp, const char *ioctl_name); #define ioctl_or_warn(fd,request,argp) bb_ioctl_or_warn(fd,request,argp,#request) #define xioctl(fd,request,argp) bb_xioctl(fd,request,argp,#request) #else int bb_ioctl_or_warn(int fd, int request, void *argp); -void bb_xioctl(int fd, int request, void *argp); +int bb_xioctl(int fd, int request, void *argp); #define ioctl_or_warn(fd,request,argp) bb_ioctl_or_warn(fd,request,argp) #define xioctl(fd,request,argp) bb_xioctl(fd,request,argp) #endif Modified: trunk/busybox/include/usage.h =================================================================== --- trunk/busybox/include/usage.h 2008-04-05 16:59:44 UTC (rev 21645) +++ trunk/busybox/include/usage.h 2008-04-06 07:17:02 UTC (rev 21646) @@ -138,6 +138,9 @@ #define brctl_full_usage \ "Manage ethernet bridges.\n" \ "\nCommands:" \ + USE_FEATURE_BRCTL_SHOW( \ + "\n show Show a list of bridges" \ + ) \ "\n addbr BRIDGE Create BRIDGE" \ "\n delbr BRIDGE Delete BRIDGE" \ "\n addif BRIDGE IFACE Add IFACE to BRIDGE" \ @@ -151,7 +154,8 @@ "\n setportprio BRIDGE PRIO Set port priority" \ "\n setbridgeprio BRIDGE PRIO Set bridge priority" \ "\n stp BRIDGE [1|0] STP on/off" \ - ) + ) \ + #define bunzip2_trivial_usage \ "[OPTION]... [FILE]" #define bunzip2_full_usage \ Modified: trunk/busybox/libbb/xfuncs.c =================================================================== --- trunk/busybox/libbb/xfuncs.c 2008-04-05 16:59:44 UTC (rev 21645) +++ trunk/busybox/libbb/xfuncs.c 2008-04-06 07:17:02 UTC (rev 21646) @@ -704,17 +704,20 @@ return ret; } -void ioctl_or_perror_and_die(int fd, int request, void *argp, const char *fmt,...) +int ioctl_or_perror_and_die(int fd, int request, void *argp, const char *fmt,...) { + int ret; va_list p; - if (ioctl(fd, request, argp) < 0) { + ret = ioctl(fd, request, argp); + if (ret < 0) { va_start(p, fmt); bb_verror_msg(fmt, p, strerror(errno)); /* xfunc_die can actually longjmp, so be nice */ va_end(p); xfunc_die(); } + return ret; } int ioctl_or_perror(int fd, int request, void *argp, const char *fmt,...) @@ -740,10 +743,14 @@ bb_simple_perror_msg(ioctl_name); return ret; } -void bb_xioctl(int fd, int request, void *argp, const char *ioctl_name) +int bb_xioctl(int fd, int request, void *argp, const char *ioctl_name) { - if (ioctl(fd, request, argp) < 0) + int ret; + + ret = ioctl(fd, request, argp); + if (ret < 0) bb_simple_perror_msg_and_die(ioctl_name); + return ret; } #else int bb_ioctl_or_warn(int fd, int request, void *argp) @@ -755,9 +762,13 @@ bb_perror_msg("ioctl %#x failed", request); return ret; } -void bb_xioctl(int fd, int request, void *argp) +int bb_xioctl(int fd, int request, void *argp) { - if (ioctl(fd, request, argp) < 0) + int ret; + + ret = ioctl(fd, request, argp); + if (ret < 0) bb_perror_msg_and_die("ioctl %#x failed", request); + return ret; } #endif Modified: trunk/busybox/networking/Config.in =================================================================== --- trunk/busybox/networking/Config.in 2008-04-05 16:59:44 UTC (rev 21645) +++ trunk/busybox/networking/Config.in 2008-04-06 07:17:02 UTC (rev 21646) @@ -54,14 +54,6 @@ Manage ethernet bridges. Supports addbr/delbr and addif/delif. -#config FEATURE_BRCTL_SHOW -# bool "Support show, showmac and showstp" -# default n -# depends on BRCTL -# help -# Add support for option which print the current config: -# showmacs, showstp, show - config FEATURE_BRCTL_FANCY bool "Fancy options" default n @@ -73,6 +65,14 @@ stp This adds about 600 bytes. +config FEATURE_BRCTL_SHOW + bool "Support show, showmac and showstp" + default n + depends on BRCTL && FEATURE_BRCTL_FANCY + help + Add support for option which prints the current config: + showmacs, showstp, show + config DNSD bool "dnsd" default n Modified: trunk/busybox/networking/brctl.c =================================================================== --- trunk/busybox/networking/brctl.c 2008-04-05 16:59:44 UTC (rev 21645) +++ trunk/busybox/networking/brctl.c 2008-04-06 07:17:02 UTC (rev 21646) @@ -25,12 +25,6 @@ /* #define BRCTL_USE_INTERNAL 0 */ /* use exact conversion */ #define BRCTL_USE_INTERNAL 1 -#ifdef ENABLE_FEATURE_BRCTL_SHOW -#error Remove these -#endif -#define ENABLE_FEATURE_BRCTL_SHOW 0 -#define USE_FEATURE_BRCTL_SHOW(...) - #if ENABLE_FEATURE_BRCTL_FANCY #include @@ -96,7 +90,7 @@ "setageing\0" "setfd\0" "sethello\0" "setmaxage\0" "setpathcost\0" "setportprio\0" "setbridgeprio\0" ) - USE_FEATURE_BRCTL_SHOW("showmacs\0" "show\0"); + USE_FEATURE_BRCTL_SHOW("showmacs\0" "show\0"); enum { ARG_addbr = 0, ARG_delbr, ARG_addif, ARG_delif USE_FEATURE_BRCTL_FANCY(, @@ -104,31 +98,87 @@ ARG_setageing, ARG_setfd, ARG_sethello, ARG_setmaxage, ARG_setpathcost, ARG_setportprio, ARG_setbridgeprio ) - USE_FEATURE_BRCTL_SHOW(, ARG_showmacs, ARG_show) + USE_FEATURE_BRCTL_SHOW(, ARG_showmacs, ARG_show) }; int fd; smallint key; struct ifreq ifr; char *br, *brif; + + argv++; + while (*argv) { #if ENABLE_FEATURE_BRCTL_FANCY - unsigned long args[4] = {0, 0, 0, 0}; - int port; - int tmp; + int ifidx[MAX_PORTS]; + unsigned long args[4]; + ifr.ifr_data = (char *) &args; #endif - argv++; - while (*argv) { key = index_in_strings(keywords, *argv); if (key == -1) /* no match found in keywords array, bail out. */ bb_error_msg_and_die(bb_msg_invalid_arg, *argv, applet_name); argv++; + fd = xsocket(AF_INET, SOCK_STREAM, 0); + #if ENABLE_FEATURE_BRCTL_SHOW if (key == ARG_show) { /* show */ - goto out; /* FIXME: implement me! :) */ + char brname[IFNAMSIZ]; + int bridx[MAX_PORTS]; + int i, num; + arm_ioctl(args, BRCTL_GET_BRIDGES, + (unsigned long) bridx, MAX_PORTS); + num = xioctl(fd, SIOCGIFBR, args); + printf("bridge name\tbridge id\t\tSTP enabled\tinterfaces\n"); + for (i = 0; i < num; i++) { + char ifname[IFNAMSIZ]; + int j, tabs; + struct __bridge_info bi; + unsigned char *x; + + if (!if_indextoname(bridx[i], brname)) + bb_perror_msg_and_die("can't get bridge name for index %d", i); + safe_strncpy(ifr.ifr_name, brname, IFNAMSIZ); + + arm_ioctl(args, BRCTL_GET_BRIDGE_INFO, + (unsigned long) &bi, 0); + xioctl(fd, SIOCDEVPRIVATE, &ifr); + printf("%s\t\t", brname); + + /* print bridge id */ + x = (unsigned char *) &bi.bridge_id; + for (j = 0; j < 8; j++) { + printf("%.2x", x[j]); + if (j == 1) + bb_putchar('.'); + } + printf(bi.stp_enabled ? "\tyes" : "\tno"); + + /* print interface list */ + arm_ioctl(args, BRCTL_GET_PORT_LIST, + (unsigned long) ifidx, MAX_PORTS); + xioctl(fd, SIOCDEVPRIVATE, &ifr); + tabs = 0; + for (j = 0; j < MAX_PORTS; j++) { + if (!ifidx[j]) + continue; + if (!if_indextoname(ifidx[j], ifname)) + bb_perror_msg_and_die("can't get interface name for index %d", j); + if (tabs) + printf("\t\t\t\t\t"); + else + tabs = 1; + printf("\t\t%s\n", ifname); + } + if (!tabs) /* bridge has no interfaces */ + bb_putchar('\n'); + } + goto done; } #endif - fd = xsocket(AF_INET, SOCK_STREAM, 0); + + if (!*argv) /* all but 'show' need at least one argument */ + bb_show_usage(); + br = *argv++; if (key == ARG_addbr || key == ARG_delbr) { /* addbr or delbr */ @@ -137,11 +187,13 @@ br, "bridge %s", br); goto done; } - if (!*argv) /* all but 'show' need at least one argument */ + + if (!*argv) /* all but 'addif/delif' need at least two arguments */ bb_show_usage(); + safe_strncpy(ifr.ifr_name, br, IFNAMSIZ); if (key == ARG_addif || key == ARG_delif) { /* addif or delif */ - brif = *argv++; + brif = *argv; ifr.ifr_ifindex = if_nametoindex(brif); if (!ifr.ifr_ifindex) { bb_perror_msg_and_die("iface %s", brif); @@ -149,76 +201,72 @@ ioctl_or_perror_and_die(fd, key == ARG_addif ? SIOCBRADDIF : SIOCBRDELIF, &ifr, "bridge %s", br); - goto done; + goto done_next_argv; } #if ENABLE_FEATURE_BRCTL_FANCY - ifr.ifr_data = (char *) &args; if (key == ARG_stp) { /* stp */ /* FIXME: parsing yes/y/on/1 versus no/n/off/0 is too involved */ arm_ioctl(args, BRCTL_SET_BRIDGE_STP_STATE, (unsigned)(**argv - '0'), 0); goto fire; } - if ((unsigned)(key - ARG_stp) < 5) { /* time related ops */ - unsigned long op = (key == ARG_setageing) ? BRCTL_SET_AGEING_TIME : - (key == ARG_setfd) ? BRCTL_SET_BRIDGE_FORWARD_DELAY : - (key == ARG_sethello) ? BRCTL_SET_BRIDGE_HELLO_TIME : - /*key == ARG_setmaxage*/ BRCTL_SET_BRIDGE_MAX_AGE; - arm_ioctl(args, op, str_to_jiffies(*argv), 0); + if ((unsigned)(key - ARG_setageing) < 4) { /* time related ops */ + static const uint8_t ops[] ALIGN1 = { + BRCTL_SET_AGEING_TIME, /* ARG_setageing */ + BRCTL_SET_BRIDGE_FORWARD_DELAY, /* ARG_setfd */ + BRCTL_SET_BRIDGE_HELLO_TIME, /* ARG_sethello */ + BRCTL_SET_BRIDGE_MAX_AGE /* ARG_setmaxage */ + }; + arm_ioctl(args, ops[key - ARG_setageing], str_to_jiffies(*argv), 0); goto fire; } - port = -1; - if (key == ARG_setpathcost || key == ARG_setportprio) {/* get portnum */ - int ifidx[MAX_PORTS]; - unsigned i; - - port = if_nametoindex(*argv); - if (!port) - bb_error_msg_and_die(bb_msg_invalid_arg, *argv, "port"); - argv++; - memset(ifidx, 0, sizeof ifidx); - arm_ioctl(args, BRCTL_GET_PORT_LIST, (unsigned long)ifidx, - MAX_PORTS); - xioctl(fd, SIOCDEVPRIVATE, &ifr); - for (i = 0; i < MAX_PORTS; i++) { - if (ifidx[i] == port) { - port = i; - break; - } - } - } if (key == ARG_setpathcost || key == ARG_setportprio || key == ARG_setbridgeprio ) { - unsigned long op = (key == ARG_setpathcost) ? BRCTL_SET_PATH_COST : - (key == ARG_setportprio) ? BRCTL_SET_PORT_PRIORITY : - /*key == ARG_setbridgeprio*/ BRCTL_SET_BRIDGE_PRIORITY; - unsigned long arg1 = port; - unsigned long arg2; -# if BRCTL_USE_INTERNAL - tmp = xatoi(*argv); -# else - if (sscanf(*argv, "%i", &tmp) != 1) - bb_error_msg_and_die(bb_msg_invalid_arg, *argv, - key == ARG_setpathcost ? "cost" : "prio"); -# endif + static const uint8_t ops[] ALIGN1 = { + BRCTL_SET_PATH_COST, /* ARG_setpathcost */ + BRCTL_SET_PORT_PRIORITY, /* ARG_setportprio */ + BRCTL_SET_BRIDGE_PRIORITY /* ARG_setbridgeprio */ + }; + int port = -1; + unsigned arg1, arg2; + + if (key != ARG_setbridgeprio) { + /* get portnum */ + unsigned i; + + port = if_nametoindex(*argv++); + if (!port) + bb_error_msg_and_die(bb_msg_invalid_arg, *argv, "port"); + memset(ifidx, 0, sizeof ifidx); + arm_ioctl(args, BRCTL_GET_PORT_LIST, (unsigned long)ifidx, + MAX_PORTS); + xioctl(fd, SIOCDEVPRIVATE, &ifr); + for (i = 0; i < MAX_PORTS; i++) { + if (ifidx[i] == port) { + port = i; + break; + } + } + } + arg1 = port; + arg2 = xatoi_u(*argv); if (key == ARG_setbridgeprio) { - arg1 = tmp; + arg1 = arg2; arg2 = 0; - } else - arg2 = tmp; - arm_ioctl(args, op, arg1, arg2); + } + arm_ioctl(args, ops[key - ARG_setpathcost], arg1, arg2); } fire: - /* Execute the previously set command. */ + /* Execute the previously set command */ xioctl(fd, SIOCDEVPRIVATE, &ifr); +#endif + done_next_argv: argv++; -#endif done: - if (ENABLE_FEATURE_CLEAN_UP) - close(fd); + close(fd); } - USE_FEATURE_BRCTL_SHOW(out:) + return EXIT_SUCCESS; } From vda at busybox.net Sun Apr 6 17:46:29 2008 From: vda at busybox.net (vda at busybox.net) Date: Sun, 6 Apr 2008 17:46:29 -0700 (PDT) Subject: svn commit: trunk/busybox: include networking Message-ID: <20080407004629.E30623C40B@busybox.net> Author: vda Date: 2008-04-06 17:46:29 -0700 (Sun, 06 Apr 2008) New Revision: 21658 Log: ping: add -w, -W support (James Simmons ) function old new delta print_stats_and_exit - 282 +282 sendping_tail 151 231 +80 packed_usage 23976 24054 +78 ping_main 401 412 +11 arm_ioctl 13 20 +7 pingstats 259 - -259 ------------------------------------------------------------------------------ (add/remove: 1/1 grow/shrink: 4/0 up/down: 458/-259) Total: 199 bytes Modified: trunk/busybox/include/usage.h trunk/busybox/networking/ping.c Changeset: Modified: trunk/busybox/include/usage.h =================================================================== --- trunk/busybox/include/usage.h 2008-04-06 19:59:21 UTC (rev 21657) +++ trunk/busybox/include/usage.h 2008-04-07 00:46:29 UTC (rev 21658) @@ -2935,6 +2935,10 @@ "\n -c CNT Send only CNT pings" \ "\n -s SIZE Send SIZE data bytes in packets (default=56)" \ "\n -I iface/IP Use interface or IP address as source" \ + "\n -W timeout Seconds to wait for the first response (default:10)" \ + "\n (after all -c CNT packets are sent)" \ + "\n -w deadline Seconds until ping exits (default:infinite)" \ + "\n (can exit earlier with -c CNT)" \ "\n -q Quiet, only displays output at start" \ "\n and when finished" \ Modified: trunk/busybox/networking/ping.c =================================================================== --- trunk/busybox/networking/ping.c 2008-04-06 19:59:21 UTC (rev 21657) +++ trunk/busybox/networking/ping.c 2008-04-07 00:46:29 UTC (rev 21658) @@ -224,15 +224,17 @@ /* full(er) version */ -#define OPT_STRING ("qvc:s:I:4" USE_PING6("6")) +#define OPT_STRING ("qvc:s:w:W:I:4" USE_PING6("6")) enum { OPT_QUIET = 1 << 0, OPT_VERBOSE = 1 << 1, OPT_c = 1 << 2, OPT_s = 1 << 3, - OPT_I = 1 << 4, - OPT_IPV4 = 1 << 5, - OPT_IPV6 = (1 << 6) * ENABLE_PING6, + OPT_w = 1 << 4, + OPT_W = 1 << 5, + OPT_I = 1 << 6, + OPT_IPV4 = 1 << 7, + OPT_IPV6 = (1 << 8) * ENABLE_PING6, }; @@ -246,6 +248,9 @@ uint16_t myid; unsigned tmin, tmax; /* in us */ unsigned long long tsum; /* in us, sum of all times */ + unsigned deadline; + unsigned timeout; + unsigned total_secs; const char *hostname; const char *dotted; union { @@ -271,6 +276,9 @@ #define tmin (G.tmin ) #define tmax (G.tmax ) #define tsum (G.tsum ) +#define deadline (G.deadline ) +#define timeout (G.timeout ) +#define total_secs (G.total_secs ) #define hostname (G.hostname ) #define dotted (G.dotted ) #define pingaddr (G.pingaddr ) @@ -280,6 +288,8 @@ if (sizeof(G) > COMMON_BUFSIZE) \ BUG_ping_globals_too_big(); \ pingsock = -1; \ + datalen = DEFDATALEN; \ + timeout = MAXWAIT; \ tmin = UINT_MAX; \ } while (0) @@ -292,7 +302,8 @@ /**************************************************************************/ -static void pingstats(int junk ATTRIBUTE_UNUSED) +static void print_stats_and_exit(int junk) ATTRIBUTE_NORETURN; +static void print_stats_and_exit(int junk ATTRIBUTE_UNUSED) { signal(SIGINT, SIG_IGN); @@ -311,7 +322,8 @@ tavg / 1000, tavg % 1000, tmax / 1000, tmax % 1000); } - exit(nreceived == 0); /* (nreceived == 0) is true (1) -- 'failure' */ + /* if condition is true, exit with 1 -- 'failure' */ + exit(nreceived == 0 || (deadline && nreceived < pingcount)); } static void sendping_tail(void (*sp)(int), const void *pkt, int size_pkt) @@ -327,13 +339,30 @@ if (sz != size_pkt) bb_error_msg_and_die(bb_msg_write_error); - signal(SIGALRM, sp); - if (pingcount == 0 || ntransmitted < pingcount) { /* schedule next in 1s */ + if (pingcount == 0 || deadline || ntransmitted < pingcount) { + /* Didn't send all pings yet - schedule next in 1s */ + signal(SIGALRM, sp); + if (deadline) { + total_secs += PINGINTERVAL; + if (total_secs >= deadline) + signal(SIGALRM, print_stats_and_exit); + } alarm(PINGINTERVAL); - } else { /* done, wait for the last ping to come back */ - /* todo, don't necessarily need to wait so long... */ - signal(SIGALRM, pingstats); - alarm(MAXWAIT); + } else { /* -c NN, and all NN are sent (and no deadline) */ + /* Wait for the last ping to come back. + * -W timeout: wait for a response in seconds. + * Affects only timeout in absense of any responses, + * otherwise ping waits for two RTTs. */ + unsigned expire = timeout; + + if (nreceived) { + /* approx. 2*tmax, in seconds (2 RTT) */ + expire = tmax / (512*1024); + if (expire == 0) + expire = 1; + } + signal(SIGALRM, print_stats_and_exit); + alarm(expire); } } @@ -549,7 +578,7 @@ sockopt = 48 * 1024; /* explain why 48k? */ setsockopt(pingsock, SOL_SOCKET, SO_RCVBUF, &sockopt, sizeof(sockopt)); - signal(SIGINT, pingstats); + signal(SIGINT, print_stats_and_exit); /* start the ping's going ... */ sendping4(0); @@ -568,7 +597,7 @@ continue; } unpack4(packet, c, &from); - if (pingcount > 0 && nreceived >= pingcount) + if (pingcount && nreceived >= pingcount) break; } } @@ -624,7 +653,7 @@ if (if_index) pingaddr.sin6.sin6_scope_id = if_index; - signal(SIGINT, pingstats); + signal(SIGINT, print_stats_and_exit); /* start the ping's going ... */ sendping6(0); @@ -659,7 +688,7 @@ } } unpack6(packet, c, /*&from,*/ hoplimit); - if (pingcount > 0 && nreceived >= pingcount) + if (pingcount && nreceived >= pingcount) break; } } @@ -691,11 +720,9 @@ INIT_G(); - datalen = DEFDATALEN; - - /* exactly one argument needed, -v and -q don't mix */ - opt_complementary = "=1:q--v:v--q"; - getopt32(argv, OPT_STRING, &opt_c, &opt_s, &opt_I); + /* exactly one argument needed; -v and -q don't mix; -w NUM, -W NUM */ + opt_complementary = "=1:q--v:v--q:w+:W+"; + getopt32(argv, OPT_STRING, &opt_c, &opt_s, &deadline, &timeout, &opt_I); if (option_mask32 & OPT_c) pingcount = xatoul(opt_c); // -c if (option_mask32 & OPT_s) @@ -726,8 +753,8 @@ dotted = xmalloc_sockaddr2dotted_noport(&lsa->u.sa); ping(lsa); - pingstats(0); - return EXIT_SUCCESS; + print_stats_and_exit(0); + /*return EXIT_SUCCESS;*/ } #endif /* FEATURE_FANCY_PING */ From vda at busy