From 966423d4034067f52b419570a1016d1dfc4aeacd Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Mon, 12 Oct 2015 14:33:46 +0200 Subject: [PATCH 001/260] Start 1.25.0 development cycle Signed-off-by: Denys Vlasenko --- Makefile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Makefile b/Makefile index efb6d46b3..dab807805 100644 --- a/Makefile +++ b/Makefile @@ -1,7 +1,7 @@ VERSION = 1 -PATCHLEVEL = 24 +PATCHLEVEL = 25 SUBLEVEL = 0 -EXTRAVERSION = +EXTRAVERSION = .git NAME = Unnamed # *DOCUMENTATION* From b5dabd9078492c6b3366bab57a51e070b83f9b45 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Tue, 13 Oct 2015 00:31:02 +0200 Subject: [PATCH 002/260] libpwdgrp: fix comment discrepancies Signed-off-by: Denys Vlasenko --- libpwdgrp/pwd_grp.c | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/libpwdgrp/pwd_grp.c b/libpwdgrp/pwd_grp.c index 139b93007..1b13325cf 100644 --- a/libpwdgrp/pwd_grp.c +++ b/libpwdgrp/pwd_grp.c @@ -16,11 +16,10 @@ * a) must contain the expected number of fields (as per count of field * delimeters ":") or we will complain with a error message. * b) leading and trailing whitespace in fields is stripped. - * c) some fields are not allowed to be empty (e.g. username, uid/gid, - * homedir, shell) and in this case NULL is returned and errno is - * set to EINVAL. This behaviour could be easily changed by - * modifying PW_DEF, GR_DEF, SP_DEF strings (uppercase - * makes a field mandatory). + * c) some fields are not allowed to be empty (e.g. username, uid/gid), + * and in this case NULL is returned and errno is set to EINVAL. + * This behaviour could be easily changed by modifying PW_DEF, GR_DEF, + * SP_DEF strings (uppercase makes a field mandatory). * d) the string representing uid/gid must be convertible by strtoXX * functions, or errno is set to EINVAL. * e) leading and trailing whitespace in group member names is stripped. @@ -70,8 +69,8 @@ static const struct const_passdb const_pw_db = { offsetof(struct passwd, pw_uid), /* 2 I */ offsetof(struct passwd, pw_gid), /* 3 I */ offsetof(struct passwd, pw_gecos), /* 4 s */ - offsetof(struct passwd, pw_dir), /* 5 S */ - offsetof(struct passwd, pw_shell) /* 6 S */ + offsetof(struct passwd, pw_dir), /* 5 s */ + offsetof(struct passwd, pw_shell) /* 6 s */ }, sizeof(PW_DEF)-1, sizeof(struct passwd) }; From 450a367a11283d44811b8eec33afe5fa00a95f5f Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Tue, 13 Oct 2015 01:49:06 +0200 Subject: [PATCH 003/260] typo fix Signed-off-by: Denys Vlasenko --- shell/hush_test/hush-misc/nommu3.tests | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/shell/hush_test/hush-misc/nommu3.tests b/shell/hush_test/hush-misc/nommu3.tests index 0aca67a67..ac82a6a11 100755 --- a/shell/hush_test/hush-misc/nommu3.tests +++ b/shell/hush_test/hush-misc/nommu3.tests @@ -7,7 +7,7 @@ func() pipe_to_func() { - # We had a NOMMU bug which caused "echo Ok |" part ot be lost + # We had a NOMMU bug which caused "echo Ok |" part to be lost echo Ok | func } From 6390a3a4e5e44894a94b31b57a9b2a07a215f171 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Tue, 13 Oct 2015 01:51:37 +0200 Subject: [PATCH 004/260] whitespace fixes Signed-off-by: Denys Vlasenko --- libpwdgrp/pwd_grp.c | 2 +- networking/zcip.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/libpwdgrp/pwd_grp.c b/libpwdgrp/pwd_grp.c index 1b13325cf..cefbc8a7e 100644 --- a/libpwdgrp/pwd_grp.c +++ b/libpwdgrp/pwd_grp.c @@ -121,7 +121,7 @@ static struct statics *ptr_to_statics; #if ENABLE_FEATURE_CLEAN_UP static void free_static(void) { - free(S.db[0].malloced); + free(S.db[0].malloced); free(S.db[1].malloced); # if ENABLE_USE_BB_SHADOW free(S.db[2].malloced); diff --git a/networking/zcip.c b/networking/zcip.c index dba269bd8..d15c67d55 100644 --- a/networking/zcip.c +++ b/networking/zcip.c @@ -387,7 +387,7 @@ int zcip_main(int argc UNUSED_PARAM, char **argv) send_arp_request(0, &null_ethaddr, chosen_nip); continue; } - // Switch to announce state + // Switch to announce state nsent = 0; state = ANNOUNCE; goto send_announce; From bf74fb44977d9b90c51dba19c1fd7f071147d955 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Tue, 13 Oct 2015 12:34:35 +0200 Subject: [PATCH 005/260] typo fix in comment Signed-off-by: Denys Vlasenko --- util-linux/switch_root.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/util-linux/switch_root.c b/util-linux/switch_root.c index a301b365b..7960b672c 100644 --- a/util-linux/switch_root.c +++ b/util-linux/switch_root.c @@ -206,7 +206,7 @@ because they're what all paths your process uses would be relative to. That's why the careful sequencing above: we cd into the new mount point before we do the mount --move. Moving the mount point would otherwise make it -totally inaccessible to is because cd-ing to the old path wouldn't give it to +totally inaccessible to us because cd-ing to the old path wouldn't give it to us anymore, and cd "/" just gives us the cached dentry from when the process was created (in this case the old initramfs one). But the "." symlink gives us the dentry of the filesystem we just moved, so we can then "chroot ." to From f7ad927c2059ef9cd1cd6befeb43f26b92f6369f Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Tue, 13 Oct 2015 13:49:53 +0200 Subject: [PATCH 006/260] ftpd: make DIR parameter work for non-root too: chdir to it instead of chroot Unfortunately, chroot() works only for root user, because of attacks on setuid binaries (make DIR/lib/ld-linux.so a shell, hardlink to a setuid binary, chroot to DIR, execute it and get root shell). function old new delta ftpd_main 2160 2180 +20 Signed-off-by: Denys Vlasenko --- networking/ftpd.c | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/networking/ftpd.c b/networking/ftpd.c index 7735b7233..8345ae67c 100644 --- a/networking/ftpd.c +++ b/networking/ftpd.c @@ -1223,11 +1223,26 @@ int ftpd_main(int argc UNUSED_PARAM, char **argv) #endif argv += optind; if (argv[0]) { + const char *basedir = argv[0]; #if !BB_MMU G.root_fd = xopen("/", O_RDONLY | O_DIRECTORY); close_on_exec_on(G.root_fd); #endif - xchroot(argv[0]); + if (chroot(basedir) == 0) + basedir = "/"; +#if !BB_MMU + else { + close(G.root_fd); + G.root_fd = -1; + } +#endif + /* + * If chroot failed, assume that we aren't root, + * and at least chdir to the specified DIR + * (older versions were dying with error message). + * If chroot worked, move current dir to new "/": + */ + xchdir(basedir); } #if ENABLE_FEATURE_FTP_AUTHENTICATION From ab3964db4e75e34f6f9347406c5fd2bced04f2dd Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Tue, 13 Oct 2015 14:50:20 +0200 Subject: [PATCH 007/260] libbb: introduce kernel-style BUILD_BUG_ON() Signed-off-by: Denys Vlasenko --- include/libbb.h | 1 + libbb/procps.c | 4 +--- networking/ftpgetput.c | 7 +++---- networking/isrv.c | 4 +--- networking/ping.c | 8 ++------ networking/tc.c | 7 +++---- networking/tftp.c | 7 +++---- runit/runsv.c | 15 +++++---------- util-linux/umount.c | 6 +----- 9 files changed, 20 insertions(+), 39 deletions(-) diff --git a/include/libbb.h b/include/libbb.h index a8ceb449c..5a270cdca 100644 --- a/include/libbb.h +++ b/include/libbb.h @@ -1901,6 +1901,7 @@ extern const char bb_default_login_shell[] ALIGN1; #define ARRAY_SIZE(x) ((unsigned)(sizeof(x) / sizeof((x)[0]))) +#define BUILD_BUG_ON(condition) ((void)sizeof(char[1 - 2*!!(condition)])) /* We redefine ctype macros. Unicode-correct handling of char types diff --git a/libbb/procps.c b/libbb/procps.c index 71ad071e6..05eefe0da 100644 --- a/libbb/procps.c +++ b/libbb/procps.c @@ -283,7 +283,6 @@ int FAST_FUNC procps_read_smaps(pid_t pid, struct smaprec *total, } #endif -void BUG_comm_size(void); procps_status_t* FAST_FUNC procps_scan(procps_status_t* sp, int flags) { if (!sp) @@ -385,8 +384,7 @@ procps_status_t* FAST_FUNC procps_scan(procps_status_t* sp, int flags) /*if (!cp || cp[1] != ' ') continue;*/ cp[0] = '\0'; - if (sizeof(sp->comm) < 16) - BUG_comm_size(); + BUILD_BUG_ON(sizeof(sp->comm) < 16); comm1 = strchr(buf, '('); /*if (comm1)*/ safe_strncpy(sp->comm, comm1 + 1, sizeof(sp->comm)); diff --git a/networking/ftpgetput.c b/networking/ftpgetput.c index 8283366cc..b398bc874 100644 --- a/networking/ftpgetput.c +++ b/networking/ftpgetput.c @@ -62,9 +62,6 @@ struct globals { } FIX_ALIASING; #define G (*(struct globals*)&bb_common_bufsiz1) enum { BUFSZ = COMMON_BUFSIZE - offsetof(struct globals, buf) }; -struct BUG_G_too_big { - char BUG_G_too_big[sizeof(G) <= COMMON_BUFSIZE ? 1 : -1]; -}; #define user (G.user ) #define password (G.password ) #define lsa (G.lsa ) @@ -72,7 +69,9 @@ struct BUG_G_too_big { #define verbose_flag (G.verbose_flag ) #define do_continue (G.do_continue ) #define buf (G.buf ) -#define INIT_G() do { } while (0) +#define INIT_G() do { \ + BUILD_BUG_ON(sizeof(G) > COMMON_BUFSIZE); \ +} while (0) static void ftp_die(const char *msg) NORETURN; diff --git a/networking/isrv.c b/networking/isrv.c index 1c6491edd..3673db715 100644 --- a/networking/isrv.c +++ b/networking/isrv.c @@ -194,7 +194,6 @@ static void handle_accept(isrv_state_t *state, int fd) remove_peer(state, n); /* unsuccesful peer start */ } -void BUG_sizeof_fd_set_is_strange(void); static void handle_fd_set(isrv_state_t *state, fd_set *fds, int (*h)(int, void **)) { enum { LONG_CNT = sizeof(fd_set) / sizeof(long) }; @@ -203,8 +202,7 @@ static void handle_fd_set(isrv_state_t *state, fd_set *fds, int (*h)(int, void * /* need to know value at _the beginning_ of this routine */ int fd_cnt = FD_COUNT; - if (LONG_CNT * sizeof(long) != sizeof(fd_set)) - BUG_sizeof_fd_set_is_strange(); + BUILD_BUG_ON(LONG_CNT * sizeof(long) != sizeof(fd_set)); fds_pos = 0; while (1) { diff --git a/networking/ping.c b/networking/ping.c index dcbf19682..0eb1ae799 100644 --- a/networking/ping.c +++ b/networking/ping.c @@ -396,10 +396,8 @@ struct globals { #define dotted (G.dotted ) #define pingaddr (G.pingaddr ) #define rcvd_tbl (G.rcvd_tbl ) -void BUG_ping_globals_too_big(void); #define INIT_G() do { \ - if (sizeof(G) > COMMON_BUFSIZE) \ - BUG_ping_globals_too_big(); \ + BUILD_BUG_ON(sizeof(G) > COMMON_BUFSIZE); \ datalen = DEFDATALEN; \ timeout = MAXWAIT; \ tmin = UINT_MAX; \ @@ -732,7 +730,6 @@ static void ping4(len_and_sockaddr *lsa) } } #if ENABLE_PING6 -extern int BUG_bad_offsetof_icmp6_cksum(void); static void ping6(len_and_sockaddr *lsa) { int sockopt; @@ -769,8 +766,7 @@ static void ping6(len_and_sockaddr *lsa) setsockopt_SOL_SOCKET_int(pingsock, SO_RCVBUF, sockopt); sockopt = offsetof(struct icmp6_hdr, icmp6_cksum); - if (offsetof(struct icmp6_hdr, icmp6_cksum) != 2) - BUG_bad_offsetof_icmp6_cksum(); + BUILD_BUG_ON(offsetof(struct icmp6_hdr, icmp6_cksum) != 2); setsockopt_int(pingsock, SOL_RAW, IPV6_CHECKSUM, sockopt); /* request ttl info to be returned in ancillary data */ diff --git a/networking/tc.c b/networking/tc.c index 76e2e8359..6d1fef993 100644 --- a/networking/tc.c +++ b/networking/tc.c @@ -64,15 +64,14 @@ struct globals { uint32_t filter_proto; } FIX_ALIASING; #define G (*(struct globals*)&bb_common_bufsiz1) -struct BUG_G_too_big { - char BUG_G_too_big[sizeof(G) <= COMMON_BUFSIZE ? 1 : -1]; -}; #define filter_ifindex (G.filter_ifindex) #define filter_qdisc (G.filter_qdisc) #define filter_parent (G.filter_parent) #define filter_prio (G.filter_prio) #define filter_proto (G.filter_proto) -#define INIT_G() do { } while (0) +#define INIT_G() do { \ + BUILD_BUG_ON(sizeof(G) > COMMON_BUFSIZE); \ +} while (0) /* Allocates a buffer containing the name of a class id. * The caller must free the returned memory. */ diff --git a/networking/tftp.c b/networking/tftp.c index 8ecd7bb6f..ad9308e52 100644 --- a/networking/tftp.c +++ b/networking/tftp.c @@ -129,10 +129,9 @@ struct globals { #endif } FIX_ALIASING; #define G (*(struct globals*)&bb_common_bufsiz1) -struct BUG_G_too_big { - char BUG_G_too_big[sizeof(G) <= COMMON_BUFSIZE ? 1 : -1]; -}; -#define INIT_G() do { } while (0) +#define INIT_G() do { \ + BUILD_BUG_ON(sizeof(G) > COMMON_BUFSIZE); \ +} while (0) #define G_error_pkt_reason (G.error_pkt[3]) #define G_error_pkt_str ((char*)(G.error_pkt + 4)) diff --git a/runit/runsv.c b/runit/runsv.c index 94d286059..6cf5bcc29 100644 --- a/runit/runsv.c +++ b/runit/runsv.c @@ -49,16 +49,11 @@ static void gettimeofday_ns(struct timespec *ts) #else static void gettimeofday_ns(struct timespec *ts) { - if (sizeof(struct timeval) == sizeof(struct timespec) - && sizeof(((struct timeval*)ts)->tv_usec) == sizeof(ts->tv_nsec) - ) { - /* Cheat */ - gettimeofday((void*)ts, NULL); - ts->tv_nsec *= 1000; - } else { - extern void BUG_need_to_implement_gettimeofday_ns(void); - BUG_need_to_implement_gettimeofday_ns(); - } + BUILD_BUG_ON(sizeof(struct timeval) != sizeof(struct timespec)); + BUILD_BUG_ON(sizeof(((struct timeval*)ts)->tv_usec) != sizeof(ts->tv_nsec)); + /* Cheat */ + gettimeofday((void*)ts, NULL); + ts->tv_nsec *= 1000; } #endif diff --git a/util-linux/umount.c b/util-linux/umount.c index c6c7441b8..00910977d 100644 --- a/util-linux/umount.c +++ b/util-linux/umount.c @@ -82,11 +82,7 @@ int umount_main(int argc UNUSED_PARAM, char **argv) // MNT_FORCE and MNT_DETACH (from linux/fs.h) must match // OPT_FORCE and OPT_LAZY. - { - typedef char bug[ - (OPT_FORCE != MNT_FORCE || OPT_LAZY != MNT_DETACH) ? -1 : 1 - ]; - } + BUILD_BUG_ON(OPT_FORCE != MNT_FORCE || OPT_LAZY != MNT_DETACH); doForce = opt & (OPT_FORCE|OPT_LAZY); /* Get a list of mount points from mtab. We read them all in now mostly From 4d0c1ea4784c9844f8468d97ca5c26d3c70f9921 Mon Sep 17 00:00:00 2001 From: Ron Yorston Date: Mon, 12 Oct 2015 10:51:25 +0100 Subject: [PATCH 008/260] wget: shrink code if https isn't supported If FEATURE_WGET_OPENSSL and FEATURE_WGET_SSL_HELPER are both disabled there's no point in checking for https URLs. function old new delta P_HTTPS 6 - -6 .rodata 155501 155469 -32 parse_url 476 423 -53 ------------------------------------------------------------------------------ (add/remove: 0/1 grow/shrink: 0/2 up/down: 0/-91) Total: -91 bytes Signed-off-by: Ron Yorston Signed-off-by: Denys Vlasenko --- networking/wget.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/networking/wget.c b/networking/wget.c index d4a9c0cb1..af9c53c22 100644 --- a/networking/wget.c +++ b/networking/wget.c @@ -147,7 +147,9 @@ struct host_info { }; static const char P_FTP[] = "ftp"; static const char P_HTTP[] = "http"; +#if ENABLE_FEATURE_WGET_OPENSSL || ENABLE_FEATURE_WGET_SSL_HELPER static const char P_HTTPS[] = "https"; +#endif #if ENABLE_FEATURE_WGET_LONG_OPTIONS /* User-specified headers prevent using our corresponding built-in headers. */ @@ -410,10 +412,12 @@ static void parse_url(const char *src_url, struct host_info *h) if (strcmp(url, P_FTP) == 0) { h->port = bb_lookup_port(P_FTP, "tcp", 21); } else +#if ENABLE_FEATURE_WGET_OPENSSL || ENABLE_FEATURE_WGET_SSL_HELPER if (strcmp(url, P_HTTPS) == 0) { h->port = bb_lookup_port(P_HTTPS, "tcp", 443); h->protocol = P_HTTPS; } else +#endif if (strcmp(url, P_HTTP) == 0) { http: h->port = bb_lookup_port(P_HTTP, "tcp", 80); From 7b85ec30b5941f0b90c48a990f2f6840aca87bce Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Tue, 13 Oct 2015 17:17:34 +0200 Subject: [PATCH 009/260] *: more BUILD_BUG_ON conversions Signed-off-by: Denys Vlasenko --- archival/libarchive/decompress_gunzip.c | 5 ++--- editors/sed.c | 10 +++++----- findutils/find.c | 4 +--- findutils/grep.c | 4 +--- miscutils/hdparm.c | 7 +++---- miscutils/taskset.c | 6 ++---- networking/inetd.c | 4 +--- networking/nbd-client.c | 5 ++--- networking/telnet.c | 4 +--- procps/top.c | 9 ++++----- 10 files changed, 22 insertions(+), 36 deletions(-) diff --git a/archival/libarchive/decompress_gunzip.c b/archival/libarchive/decompress_gunzip.c index 1360abef7..7b6f45934 100644 --- a/archival/libarchive/decompress_gunzip.c +++ b/archival/libarchive/decompress_gunzip.c @@ -1118,9 +1118,8 @@ static int check_header_gzip(STATE_PARAM transformer_state_t *xstate) uint8_t os_flags_UNUSED; } PACKED formatted; } header; - struct BUG_header { - char BUG_header[sizeof(header) == 8 ? 1 : -1]; - }; + + BUILD_BUG_ON(sizeof(header) != 8); /* * Rewind bytebuffer. We use the beginning because the header has 8 diff --git a/editors/sed.c b/editors/sed.c index 7bbf820d8..a8c35388b 100644 --- a/editors/sed.c +++ b/editors/sed.c @@ -162,10 +162,8 @@ struct globals { } pipeline; } FIX_ALIASING; #define G (*(struct globals*)&bb_common_bufsiz1) -struct BUG_G_too_big { - char BUG_G_too_big[sizeof(G) <= COMMON_BUFSIZE ? 1 : -1]; -}; #define INIT_G() do { \ + BUILD_BUG_ON(sizeof(G) > COMMON_BUFSIZE); \ G.sed_cmd_tail = &G.sed_cmd_head; \ } while (0) @@ -501,9 +499,11 @@ static const char *parse_cmd_args(sed_cmd_t *sed_cmd, const char *cmdstr) IDX_rbrace, IDX_nul }; - struct chk { char chk[sizeof(cmd_letters)-1 == IDX_nul ? 1 : -1]; }; + unsigned idx; - unsigned idx = strchrnul(cmd_letters, sed_cmd->cmd) - cmd_letters; + BUILD_BUG_ON(sizeof(cmd_letters)-1 != IDX_nul); + + idx = strchrnul(cmd_letters, sed_cmd->cmd) - cmd_letters; /* handle (s)ubstitution command */ if (idx == IDX_s) { diff --git a/findutils/find.c b/findutils/find.c index bd7ccc323..5bd753536 100644 --- a/findutils/find.c +++ b/findutils/find.c @@ -423,9 +423,7 @@ struct globals { } FIX_ALIASING; #define G (*(struct globals*)&bb_common_bufsiz1) #define INIT_G() do { \ - struct G_sizecheck { \ - char G_sizecheck[sizeof(G) > COMMON_BUFSIZE ? -1 : 1]; \ - }; \ + BUILD_BUG_ON(sizeof(G) > COMMON_BUFSIZE); \ /* we have to zero it out because of NOEXEC */ \ memset(&G, 0, sizeof(G)); \ IF_FEATURE_FIND_MAXDEPTH(G.minmaxdepth[1] = INT_MAX;) \ diff --git a/findutils/grep.c b/findutils/grep.c index b9621384e..10b69275a 100644 --- a/findutils/grep.c +++ b/findutils/grep.c @@ -203,9 +203,7 @@ struct globals { } FIX_ALIASING; #define G (*(struct globals*)&bb_common_bufsiz1) #define INIT_G() do { \ - struct G_sizecheck { \ - char G_sizecheck[sizeof(G) > COMMON_BUFSIZE ? -1 : 1]; \ - }; \ + BUILD_BUG_ON(sizeof(G) > COMMON_BUFSIZE); \ } while (0) #define max_matches (G.max_matches ) #if !ENABLE_EXTRA_COMPAT diff --git a/miscutils/hdparm.c b/miscutils/hdparm.c index 9c486e7aa..8e201ac35 100644 --- a/miscutils/hdparm.c +++ b/miscutils/hdparm.c @@ -368,9 +368,6 @@ struct globals { #endif } FIX_ALIASING; #define G (*(struct globals*)&bb_common_bufsiz1) -struct BUG_G_too_big { - char BUG_G_too_big[sizeof(G) <= COMMON_BUFSIZE ? 1 : -1]; -}; #define get_identity (G.get_identity ) #define get_geom (G.get_geom ) #define do_flush (G.do_flush ) @@ -433,7 +430,9 @@ struct BUG_G_too_big { #define hwif_data (G.hwif_data ) #define hwif_ctrl (G.hwif_ctrl ) #define hwif_irq (G.hwif_irq ) -#define INIT_G() do { } while (0) +#define INIT_G() do { \ + BUILD_BUG_ON(sizeof(G) > COMMON_BUFSIZE); \ +} while (0) /* Busybox messages and functions */ diff --git a/miscutils/taskset.c b/miscutils/taskset.c index 2646e1dab..100b1d926 100644 --- a/miscutils/taskset.c +++ b/miscutils/taskset.c @@ -75,12 +75,10 @@ static char *from_cpuset(cpu_set_t *mask) #define TASKSET_PRINTF_MASK "%llx" static unsigned long long from_cpuset(cpu_set_t *mask) { - struct BUG_CPU_SETSIZE_is_too_small { - char BUG_CPU_SETSIZE_is_too_small[ - CPU_SETSIZE < sizeof(int) ? -1 : 1]; - }; char *p = (void*)mask; + BUILD_BUG_ON(CPU_SETSIZE < sizeof(int)); + /* Take the least significant bits. Careful! * Consider both CPU_SETSIZE=4 and CPU_SETSIZE=1024 cases */ diff --git a/networking/inetd.c b/networking/inetd.c index dce5a0885..243165a07 100644 --- a/networking/inetd.c +++ b/networking/inetd.c @@ -329,9 +329,6 @@ struct globals { } FIX_ALIASING; #define G (*(struct globals*)&bb_common_bufsiz1) enum { LINE_SIZE = COMMON_BUFSIZE - offsetof(struct globals, line) }; -struct BUG_G_too_big { - char BUG_G_too_big[sizeof(G) <= COMMON_BUFSIZE ? 1 : -1]; -}; #define rlim_ofile_cur (G.rlim_ofile_cur ) #define rlim_ofile (G.rlim_ofile ) #define serv_list (G.serv_list ) @@ -352,6 +349,7 @@ struct BUG_G_too_big { #define allsock (G.allsock ) #define line (G.line ) #define INIT_G() do { \ + BUILD_BUG_ON(sizeof(G) > COMMON_BUFSIZE); \ rlim_ofile_cur = OPEN_MAX; \ global_queuelen = 128; \ config_filename = "/etc/inetd.conf"; \ diff --git a/networking/nbd-client.c b/networking/nbd-client.c index a601430b6..70869d651 100644 --- a/networking/nbd-client.c +++ b/networking/nbd-client.c @@ -57,9 +57,8 @@ int nbdclient_main(int argc, char **argv) uint32_t flags; char data[124]; } nbd_header; - struct bug_check { - char c[offsetof(struct nbd_header_t, data) == 8+8+8+4 ? 1 : -1]; - }; + + BUILD_BUG_ON(offsetof(struct nbd_header_t, data) != 8+8+8+4); // Parse command line stuff (just a stub now) if (argc != 4) diff --git a/networking/telnet.c b/networking/telnet.c index 3bb6fb1ba..944cf1bd6 100644 --- a/networking/telnet.c +++ b/networking/telnet.c @@ -110,9 +110,7 @@ struct globals { } FIX_ALIASING; #define G (*(struct globals*)&bb_common_bufsiz1) #define INIT_G() do { \ - struct G_sizecheck { \ - char G_sizecheck[sizeof(G) > COMMON_BUFSIZE ? -1 : 1]; \ - }; \ + BUILD_BUG_ON(sizeof(G) > COMMON_BUFSIZE); \ } while (0) diff --git a/procps/top.c b/procps/top.c index 3d67c3cfd..9a3f171ac 100644 --- a/procps/top.c +++ b/procps/top.c @@ -184,10 +184,6 @@ struct globals { }; //FIX_ALIASING; - large code growth enum { LINE_BUF_SIZE = COMMON_BUFSIZE - offsetof(struct globals, line_buf) }; #define G (*(struct globals*)&bb_common_bufsiz1) -struct BUG_bad_size { - char BUG_G_too_big[sizeof(G) <= COMMON_BUFSIZE ? 1 : -1]; - char BUG_line_buf_too_small[LINE_BUF_SIZE > 80 ? 1 : -1]; -}; #define top (G.top ) #define ntop (G.ntop ) #define sort_field (G.sort_field ) @@ -204,7 +200,10 @@ struct BUG_bad_size { #define num_cpus (G.num_cpus ) #define total_pcpu (G.total_pcpu ) #define line_buf (G.line_buf ) -#define INIT_G() do { } while (0) +#define INIT_G() do { \ + BUILD_BUG_ON(sizeof(G) > COMMON_BUFSIZE); \ + BUILD_BUG_ON(LINE_BUF_SIZE <= 80); \ +} while (0) enum { OPT_d = (1 << 0), From 69934701fd1b18327b3a779cb292a728834b2d0d Mon Sep 17 00:00:00 2001 From: Curt Brune Date: Wed, 14 Oct 2015 12:53:47 +0200 Subject: [PATCH 010/260] networking: add 'ip neigh' command This patch ports the 'ip neigh' command, originally written by Alexey Kuznetsov, , to busybox. The base of the port is the version of iproute that shipped with Debian Squeeze, taken from: http://http.debian.net/debian/pool/main/i/iproute/iproute_20100519.orig.tar.gz This patch has actively been used by the Open Network Install Environment (ONIE) project for over 3 years without incident. function old new delta print_neigh - 933 +933 ipneigh_list_or_flush - 742 +742 get_hz - 109 +109 do_ipneigh - 62 +62 do_iproute 2112 2153 +41 packed_usage 30647 30667 +20 ipneigh_main - 14 +14 static.ip_neigh_commands - 12 +12 static.nuds - 9 +9 static.ip_func_ptrs 32 36 +4 print_route 1858 1727 -131 ------------------------------------------------------------------------------ (add/remove: 8/0 grow/shrink: 3/1 up/down: 1946/-131) Total: 1815 bytes Signed-off-by: Curt Brune Signed-off-by: Denys Vlasenko --- networking/Config.src | 13 ++ networking/ip.c | 19 +- networking/libiproute/Kbuild.src | 8 + networking/libiproute/ip_common.h | 2 +- networking/libiproute/ipneigh.c | 354 ++++++++++++++++++++++++++++++ networking/libiproute/iproute.c | 26 +-- networking/libiproute/utils.c | 22 ++ networking/libiproute/utils.h | 2 + 8 files changed, 420 insertions(+), 26 deletions(-) create mode 100644 networking/libiproute/ipneigh.c diff --git a/networking/Config.src b/networking/Config.src index 43ccbf385..8c7417f86 100644 --- a/networking/Config.src +++ b/networking/Config.src @@ -554,6 +554,13 @@ config FEATURE_IP_RULE help Add support for rule commands to "ip". +config FEATURE_IP_NEIGH + bool "ip neighbor" + default y + depends on IP + help + Add support for neighbor commands to "ip". + config FEATURE_IP_SHORT_FORMS bool "Support short forms of ip commands" default y @@ -565,6 +572,7 @@ config FEATURE_IP_SHORT_FORMS ip route -> iproute ip tunnel -> iptunnel ip rule -> iprule + ip neigh -> ipneigh Say N unless you desparately need the short form of the ip object commands. @@ -604,6 +612,11 @@ config IPRULE default y depends on FEATURE_IP_SHORT_FORMS && FEATURE_IP_RULE +config IPNEIGH + bool + default y + depends on FEATURE_IP_SHORT_FORMS && FEATURE_IP_NEIGH + config IPCALC bool "ipcalc" default y diff --git a/networking/ip.c b/networking/ip.c index d35345c36..ddfe74e9c 100644 --- a/networking/ip.c +++ b/networking/ip.c @@ -16,6 +16,7 @@ //usage: IF_FEATURE_IP_ROUTE("route | ") //usage: IF_FEATURE_IP_LINK("link | ") //usage: IF_FEATURE_IP_TUNNEL("tunnel | ") +//usage: IF_FEATURE_IP_NEIGH("neigh | ") //usage: IF_FEATURE_IP_RULE("rule") //usage: "} {COMMAND}" //usage:#define ip_full_usage "\n\n" @@ -25,6 +26,7 @@ //usage: IF_FEATURE_IP_ROUTE("route | ") //usage: IF_FEATURE_IP_LINK("link | ") //usage: IF_FEATURE_IP_TUNNEL("tunnel | ") +//usage: IF_FEATURE_IP_NEIGH("neigh | ") //usage: IF_FEATURE_IP_RULE("rule") //usage: "}\n" //usage: "OPTIONS := { -f[amily] { inet | inet6 | link } | -o[neline] }" @@ -80,6 +82,11 @@ //usage: " [mode { ipip | gre | sit }] [remote ADDR] [local ADDR]\n" //usage: " [[i|o]seq] [[i|o]key KEY] [[i|o]csum]\n" //usage: " [ttl TTL] [tos TOS] [[no]pmtudisc] [dev PHYS_DEV]" +//usage: +//usage:#define ipneigh_trivial_usage +//usage: "{ show | flush} [ to PREFIX ] [ dev DEV ] [ nud STATE ]" +//usage:#define ipneigh_full_usage "\n\n" +//usage: "ipneigh { show | flush} [ to PREFIX ] [ dev DEV ] [ nud STATE ]" #include "libbb.h" @@ -90,7 +97,8 @@ || ENABLE_FEATURE_IP_ROUTE \ || ENABLE_FEATURE_IP_LINK \ || ENABLE_FEATURE_IP_TUNNEL \ - || ENABLE_FEATURE_IP_RULE + || ENABLE_FEATURE_IP_RULE \ + || ENABLE_FEATURE_IP_NEIGH static int FAST_FUNC ip_print_help(char **argv UNUSED_PARAM) { @@ -140,6 +148,13 @@ int iptunnel_main(int argc UNUSED_PARAM, char **argv) return ip_do(do_iptunnel, argv); } #endif +#if ENABLE_FEATURE_IP_NEIGH +int ipneigh_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; +int ipneigh_main(int argc UNUSED_PARAM, char **argv) +{ + return ip_do(do_ipneigh, argv); +} +#endif int ip_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; @@ -153,6 +168,7 @@ int ip_main(int argc UNUSED_PARAM, char **argv) IF_FEATURE_IP_TUNNEL("tunnel\0") IF_FEATURE_IP_TUNNEL("tunl\0") IF_FEATURE_IP_RULE("rule\0") + IF_FEATURE_IP_NEIGH("neigh\0") ; static const ip_func_ptr_t ip_func_ptrs[] = { ip_print_help, @@ -163,6 +179,7 @@ int ip_main(int argc UNUSED_PARAM, char **argv) IF_FEATURE_IP_TUNNEL(do_iptunnel,) IF_FEATURE_IP_TUNNEL(do_iptunnel,) IF_FEATURE_IP_RULE(do_iprule,) + IF_FEATURE_IP_NEIGH(do_ipneigh,) }; ip_func_ptr_t ip_func; int key; diff --git a/networking/libiproute/Kbuild.src b/networking/libiproute/Kbuild.src index 7c78f3c6a..c20e2fee8 100644 --- a/networking/libiproute/Kbuild.src +++ b/networking/libiproute/Kbuild.src @@ -64,3 +64,11 @@ lib-$(CONFIG_FEATURE_IP_RULE) += \ iprule.o \ rt_names.o \ utils.o + +lib-$(CONFIG_FEATURE_IP_NEIGH) += \ + ip_parse_common_args.o \ + ipneigh.o \ + libnetlink.o \ + ll_map.o \ + rt_names.o \ + utils.o diff --git a/networking/libiproute/ip_common.h b/networking/libiproute/ip_common.h index 30c7e595b..40171bed9 100644 --- a/networking/libiproute/ip_common.h +++ b/networking/libiproute/ip_common.h @@ -24,7 +24,7 @@ int FAST_FUNC ipaddr_list_or_flush(char **argv, int flush); int FAST_FUNC do_ipaddr(char **argv); int FAST_FUNC do_iproute(char **argv); int FAST_FUNC do_iprule(char **argv); -//int FAST_FUNC do_ipneigh(char **argv); +int FAST_FUNC do_ipneigh(char **argv); int FAST_FUNC do_iptunnel(char **argv); int FAST_FUNC do_iplink(char **argv); //int FAST_FUNC do_ipmonitor(char **argv); diff --git a/networking/libiproute/ipneigh.c b/networking/libiproute/ipneigh.c new file mode 100644 index 000000000..03a15d845 --- /dev/null +++ b/networking/libiproute/ipneigh.c @@ -0,0 +1,354 @@ +/* vi: set sw=4 ts=4: */ +/* + * Licensed under GPLv2 or later, see file LICENSE in this source tree. + * + * Authors: Alexey Kuznetsov, + * + * Ported to Busybox by: Curt Brune + */ + +#include "ip_common.h" /* #include "libbb.h" is inside */ +#include "rt_names.h" +#include "utils.h" +#include +#include + +//static int xshow_stats = 3; +enum { xshow_stats = 3 }; + +static inline uint32_t rta_getattr_u32(const struct rtattr *rta) +{ + return *(uint32_t *)RTA_DATA(rta); +} + +#ifndef RTAX_RTTVAR +#define RTAX_RTTVAR RTAX_HOPS +#endif + + +struct filter_t { + int family; + int index; + int state; + int unused_only; + inet_prefix pfx; + int flushed; + char *flushb; + int flushp; + int flushe; + struct rtnl_handle *rth; +} FIX_ALIASING; +typedef struct filter_t filter_t; + +#define G_filter (*(filter_t*)&bb_common_bufsiz1) + +static int flush_update(void) +{ + if (rtnl_send(G_filter.rth, G_filter.flushb, G_filter.flushp) < 0) { + bb_perror_msg("can't send flush request"); + return -1; + } + G_filter.flushp = 0; + return 0; +} + +static unsigned nud_state_a2n(char *arg) +{ + static const char keywords[] ALIGN1 = + /* "ip neigh show/flush" parameters: */ + "permanent\0" "reachable\0" "noarp\0" "none\0" + "stale\0" "incomplete\0" "delay\0" "probe\0" + "failed\0" + ; + static uint8_t nuds[] = { + NUD_PERMANENT,NUD_REACHABLE, NUD_NOARP,NUD_NONE, + NUD_STALE, NUD_INCOMPLETE,NUD_DELAY,NUD_PROBE, + NUD_FAILED + }; + int id; + + BUILD_BUG_ON( + (NUD_PERMANENT|NUD_REACHABLE| NUD_NOARP|NUD_NONE| + NUD_STALE| NUD_INCOMPLETE|NUD_DELAY|NUD_PROBE| + NUD_FAILED) > 0xff + ); + + id = index_in_substrings(keywords, arg); + if (id < 0) + bb_error_msg_and_die(bb_msg_invalid_arg, arg, "nud state"); + return nuds[id]; +} + +#ifndef NDA_RTA +#define NDA_RTA(r) \ + ((struct rtattr*)(((char*)(r)) + NLMSG_ALIGN(sizeof(struct ndmsg)))) +#endif + + +static int FAST_FUNC print_neigh(const struct sockaddr_nl *who UNUSED_PARAM, + struct nlmsghdr *n, void *arg UNUSED_PARAM) +{ + struct ndmsg *r = NLMSG_DATA(n); + int len = n->nlmsg_len; + struct rtattr *tb[NDA_MAX+1]; + char abuf[256]; + + if (n->nlmsg_type != RTM_NEWNEIGH && n->nlmsg_type != RTM_DELNEIGH) { + bb_error_msg_and_die("not RTM_NEWNEIGH: %08x %08x %08x", + n->nlmsg_len, n->nlmsg_type, + n->nlmsg_flags); + } + len -= NLMSG_LENGTH(sizeof(*r)); + if (len < 0) { + bb_error_msg_and_die("BUG: wrong nlmsg len %d", len); + } + + if (G_filter.flushb && n->nlmsg_type != RTM_NEWNEIGH) + return 0; + + if (G_filter.family && G_filter.family != r->ndm_family) + return 0; + if (G_filter.index && G_filter.index != r->ndm_ifindex) + return 0; + if (!(G_filter.state&r->ndm_state) && + !(r->ndm_flags & NTF_PROXY) && + (r->ndm_state || !(G_filter.state & 0x100)) && + (r->ndm_family != AF_DECnet)) + return 0; + + parse_rtattr(tb, NDA_MAX, NDA_RTA(r), n->nlmsg_len - NLMSG_LENGTH(sizeof(*r))); + + if (tb[NDA_DST]) { + if (G_filter.pfx.family) { + inet_prefix dst; + memset(&dst, 0, sizeof(dst)); + dst.family = r->ndm_family; + memcpy(&dst.data, RTA_DATA(tb[NDA_DST]), RTA_PAYLOAD(tb[NDA_DST])); + if (inet_addr_match(&dst, &G_filter.pfx, G_filter.pfx.bitlen)) + return 0; + } + } + if (G_filter.unused_only && tb[NDA_CACHEINFO]) { + struct nda_cacheinfo *ci = RTA_DATA(tb[NDA_CACHEINFO]); + if (ci->ndm_refcnt) + return 0; + } + + if (G_filter.flushb) { + struct nlmsghdr *fn; + if (NLMSG_ALIGN(G_filter.flushp) + n->nlmsg_len > G_filter.flushe) { + if (flush_update()) + return -1; + } + fn = (struct nlmsghdr*)(G_filter.flushb + NLMSG_ALIGN(G_filter.flushp)); + memcpy(fn, n, n->nlmsg_len); + fn->nlmsg_type = RTM_DELNEIGH; + fn->nlmsg_flags = NLM_F_REQUEST; + fn->nlmsg_seq = ++(G_filter.rth->seq); + G_filter.flushp = (((char*)fn) + n->nlmsg_len) - G_filter.flushb; + G_filter.flushed++; + if (xshow_stats < 2) + return 0; + } + + if (tb[NDA_DST]) { + printf("%s ", + format_host(r->ndm_family, + RTA_PAYLOAD(tb[NDA_DST]), + RTA_DATA(tb[NDA_DST]), + abuf, sizeof(abuf))); + } + if (!G_filter.index && r->ndm_ifindex) + printf("dev %s ", ll_index_to_name(r->ndm_ifindex)); + if (tb[NDA_LLADDR]) { + SPRINT_BUF(b1); + printf("lladdr %s", ll_addr_n2a(RTA_DATA(tb[NDA_LLADDR]), + RTA_PAYLOAD(tb[NDA_LLADDR]), + ARPHRD_ETHER, + b1, sizeof(b1))); + } + if (r->ndm_flags & NTF_ROUTER) { + printf(" router"); + } + if (r->ndm_flags & NTF_PROXY) { + printf(" proxy"); + } + if (tb[NDA_CACHEINFO] && xshow_stats) { + struct nda_cacheinfo *ci = RTA_DATA(tb[NDA_CACHEINFO]); + int hz = get_hz(); + + if (ci->ndm_refcnt) + printf(" ref %d", ci->ndm_refcnt); + printf(" used %d/%d/%d", ci->ndm_used/hz, + ci->ndm_confirmed/hz, ci->ndm_updated/hz); + } + + if (tb[NDA_PROBES] && xshow_stats) { + uint32_t p = rta_getattr_u32(tb[NDA_PROBES]); + printf(" probes %u", p); + } + + /*if (r->ndm_state)*/ { + int nud = r->ndm_state; + char c = ' '; +#define PRINT_FLAG(f) \ + if (nud & NUD_##f) { \ + printf("%c"#f, c); \ + c = ','; \ + } + PRINT_FLAG(INCOMPLETE); + PRINT_FLAG(REACHABLE); + PRINT_FLAG(STALE); + PRINT_FLAG(DELAY); + PRINT_FLAG(PROBE); + PRINT_FLAG(FAILED); + PRINT_FLAG(NOARP); + PRINT_FLAG(PERMANENT); +#undef PRINT_FLAG + } + bb_putchar('\n'); + + return 0; +} + +static void ipneigh_reset_filter(void) +{ + memset(&G_filter, 0, sizeof(G_filter)); + G_filter.state = ~0; +} + +#define MAX_ROUNDS 10 +/* Return value becomes exitcode. It's okay to not return at all */ +static int FAST_FUNC ipneigh_list_or_flush(char **argv, int flush) +{ + static const char keywords[] ALIGN1 = + /* "ip neigh show/flush" parameters: */ + "to\0" "dev\0" "nud\0"; + enum { + KW_to, KW_dev, KW_nud, + }; + struct rtnl_handle rth; + struct ndmsg ndm = { 0 }; + char *filter_dev = NULL; + int state_given = 0; + int arg; + + ipneigh_reset_filter(); + + if (flush && !*argv) + bb_error_msg_and_die(bb_msg_requires_arg, "\"ip neigh flush\""); + + if (!G_filter.family) + G_filter.family = preferred_family; + + G_filter.state = (flush) ? + ~(NUD_PERMANENT|NUD_NOARP) : 0xFF & ~NUD_NOARP; + + while (*argv) { + arg = index_in_substrings(keywords, *argv); + if (arg == KW_dev) { + NEXT_ARG(); + filter_dev = *argv; + } else if (arg == KW_nud) { + unsigned state; + NEXT_ARG(); + if (!state_given) { + state_given = 1; + G_filter.state = 0; + } + if (strcmp(*argv, "all") == 0) { + state = ~0; + if (flush) + state &= ~NUD_NOARP; + } else { + state = nud_state_a2n(*argv); + } + if (state == 0) + state = 0x100; + G_filter.state |= state; + } else { + if (arg == KW_to) { + NEXT_ARG(); + } + get_prefix(&G_filter.pfx, *argv, G_filter.family); + if (G_filter.family == AF_UNSPEC) + G_filter.family = G_filter.pfx.family; + } + argv++; + } + + xrtnl_open(&rth); + ll_init_map(&rth); + + if (filter_dev) { + if ((G_filter.index = xll_name_to_index(filter_dev)) == 0) { + bb_error_msg_and_die(bb_msg_invalid_arg, + filter_dev, "Cannot find device"); + } + } + + if (flush) { + int round = 0; + char flushb[4096-512]; + G_filter.flushb = flushb; + G_filter.flushp = 0; + G_filter.flushe = sizeof(flushb); + G_filter.state &= ~NUD_FAILED; + G_filter.rth = &rth; + + while (round < MAX_ROUNDS) { + if (xrtnl_wilddump_request(&rth, G_filter.family, RTM_GETNEIGH) < 0) { + bb_perror_msg_and_die("can't send dump request"); + } + G_filter.flushed = 0; + if (xrtnl_dump_filter(&rth, print_neigh, NULL) < 0) { + bb_perror_msg_and_die("flush terminated"); + } + if (G_filter.flushed == 0) { + if (round == 0) + puts("Nothing to flush"); + else + printf("*** Flush is complete after %d round(s) ***\n", round); + return 0; + } + round++; + if (flush_update() < 0) + xfunc_die(); + printf("\n*** Round %d, deleting %d entries ***\n", round, G_filter.flushed); + } + bb_error_msg_and_die("*** Flush not complete bailing out after %d rounds", MAX_ROUNDS); + } + + ndm.ndm_family = G_filter.family; + + if (rtnl_dump_request(&rth, RTM_GETNEIGH, &ndm, sizeof(struct ndmsg)) < 0) { + bb_perror_msg_and_die("can't send dump request"); + } + + if (xrtnl_dump_filter(&rth, print_neigh, NULL) < 0) { + bb_error_msg_and_die("dump terminated"); + } + + return 0; +} + +/* Return value becomes exitcode. It's okay to not return at all */ +int FAST_FUNC do_ipneigh(char **argv) +{ + static const char ip_neigh_commands[] ALIGN1 = + /*0-1*/ "show\0" "flush\0"; + int command_num; + + if (!*argv) + return ipneigh_list_or_flush(argv, 0); + + command_num = index_in_substrings(ip_neigh_commands, *argv); + switch (command_num) { + case 0: /* show */ + return ipneigh_list_or_flush(argv + 1, 0); + case 1: /* flush */ + return ipneigh_list_or_flush(argv + 1, 1); + } + invarg(*argv, applet_name); + return 1; +} diff --git a/networking/libiproute/iproute.c b/networking/libiproute/iproute.c index 6ecd5f719..f7209b126 100644 --- a/networking/libiproute/iproute.c +++ b/networking/libiproute/iproute.c @@ -55,28 +55,6 @@ static int flush_update(void) return 0; } -static unsigned get_hz(void) -{ - static unsigned hz_internal; - FILE *fp; - - if (hz_internal) - return hz_internal; - - fp = fopen_for_read("/proc/net/psched"); - if (fp) { - unsigned nom, denom; - - if (fscanf(fp, "%*08x%*08x%08x%08x", &nom, &denom) == 2) - if (nom == 1000000) - hz_internal = denom; - fclose(fp); - } - if (!hz_internal) - hz_internal = bb_clk_tck(); - return hz_internal; -} - static int FAST_FUNC print_route(const struct sockaddr_nl *who UNUSED_PARAM, struct nlmsghdr *n, void *arg UNUSED_PARAM) { @@ -217,7 +195,7 @@ static int FAST_FUNC print_route(const struct sockaddr_nl *who UNUSED_PARAM, if (NLMSG_ALIGN(G_filter.flushp) + n->nlmsg_len > G_filter.flushe) { if (flush_update()) - bb_error_msg_and_die("flush"); + xfunc_die(); } fn = (void*)(G_filter.flushb + NLMSG_ALIGN(G_filter.flushp)); memcpy(fn, n, n->nlmsg_len); @@ -954,7 +932,7 @@ int FAST_FUNC do_iproute(char **argv) case 11: /* flush */ return iproute_list_or_flush(argv+1, 1); default: - bb_error_msg_and_die("unknown command %s", *argv); + invarg(*argv, applet_name); } return iproute_modify(cmd, flags, argv+1); diff --git a/networking/libiproute/utils.c b/networking/libiproute/utils.c index d0fe30605..37b5311f0 100644 --- a/networking/libiproute/utils.c +++ b/networking/libiproute/utils.c @@ -13,6 +13,28 @@ #include "utils.h" #include "inet_common.h" +unsigned get_hz(void) +{ + static unsigned hz_internal; + FILE *fp; + + if (hz_internal) + return hz_internal; + + fp = fopen_for_read("/proc/net/psched"); + if (fp) { + unsigned nom, denom; + + if (fscanf(fp, "%*08x%*08x%08x%08x", &nom, &denom) == 2) + if (nom == 1000000) + hz_internal = denom; + fclose(fp); + } + if (!hz_internal) + hz_internal = bb_clk_tck(); + return hz_internal; +} + unsigned get_unsigned(char *arg, const char *errmsg) { unsigned long res; diff --git a/networking/libiproute/utils.h b/networking/libiproute/utils.h index 5fb4a862c..cd15b706b 100644 --- a/networking/libiproute/utils.h +++ b/networking/libiproute/utils.h @@ -85,6 +85,8 @@ int dnet_pton(int af, const char *src, void *addr); const char *ipx_ntop(int af, const void *addr, char *str, size_t len); int ipx_pton(int af, const char *src, void *addr); +unsigned get_hz(void); + POP_SAVED_FUNCTION_VISIBILITY #endif From 0f296a3a56b52842057e5a2bc653621a3a6c7bec Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Wed, 14 Oct 2015 13:21:01 +0200 Subject: [PATCH 011/260] libiproute: rename invarg(a,b) to invarg_1_to_2(a,b) invarg(a,b) - "invalid argument", but how a and b enter the message? invarg_1_to_2(a,b) is somewhat easier to read: "invalid argument 'a' to 'b'" Audit of usage revealed a number of bad uses, with too long messages. text data bss dec hex filename 938848 932 17448 957228 e9b2c busybox_old 938788 932 17448 957168 e9af0 busybox_unstripped Signed-off-by: Denys Vlasenko --- coreutils/dd.c | 4 +-- findutils/find.c | 2 +- include/libbb.h | 2 +- libbb/messages.c | 2 +- networking/brctl.c | 8 +++--- networking/libiproute/ip_parse_common_args.c | 2 +- networking/libiproute/ipaddress.c | 6 ++--- networking/libiproute/iplink.c | 27 ++++++++++---------- networking/libiproute/ipneigh.c | 10 ++++---- networking/libiproute/iproute.c | 12 ++++----- networking/libiproute/iprule.c | 12 ++++----- networking/libiproute/iptunnel.c | 6 ++--- networking/libiproute/utils.c | 12 ++++----- networking/libiproute/utils.h | 2 +- networking/slattach.c | 6 ++--- networking/tc.c | 12 ++++----- 16 files changed, 62 insertions(+), 63 deletions(-) diff --git a/coreutils/dd.c b/coreutils/dd.c index 53a843ca0..6a5288da1 100644 --- a/coreutils/dd.c +++ b/coreutils/dd.c @@ -326,7 +326,7 @@ int dd_main(int argc UNUSED_PARAM, char **argv) *arg = '\0'; n = index_in_strings(conv_words, val); if (n < 0) - bb_error_msg_and_die(bb_msg_invalid_arg, val, "conv"); + bb_error_msg_and_die(bb_msg_invalid_arg_to, val, "conv"); G.flags |= (1 << n); if (!arg) /* no ',' left, so this was the last specifier */ break; @@ -368,7 +368,7 @@ int dd_main(int argc UNUSED_PARAM, char **argv) int n; n = index_in_strings(status_words, val); if (n < 0) - bb_error_msg_and_die(bb_msg_invalid_arg, val, "status"); + bb_error_msg_and_die(bb_msg_invalid_arg_to, val, "status"); G.flags |= FLAG_STATUS << n; /*continue;*/ } diff --git a/findutils/find.c b/findutils/find.c index 5bd753536..a0d4853de 100644 --- a/findutils/find.c +++ b/findutils/find.c @@ -882,7 +882,7 @@ static int find_type(const char *type) mask = S_IFSOCK; if (mask == 0 || type[1] != '\0') - bb_error_msg_and_die(bb_msg_invalid_arg, type, "-type"); + bb_error_msg_and_die(bb_msg_invalid_arg_to, type, "-type"); return mask; } diff --git a/include/libbb.h b/include/libbb.h index 5a270cdca..f04f555c0 100644 --- a/include/libbb.h +++ b/include/libbb.h @@ -1786,7 +1786,7 @@ extern const char bb_msg_can_not_create_raw_socket[] ALIGN1; extern const char bb_msg_perm_denied_are_you_root[] ALIGN1; extern const char bb_msg_you_must_be_root[] ALIGN1; extern const char bb_msg_requires_arg[] ALIGN1; -extern const char bb_msg_invalid_arg[] ALIGN1; +extern const char bb_msg_invalid_arg_to[] ALIGN1; extern const char bb_msg_standard_input[] ALIGN1; extern const char bb_msg_standard_output[] ALIGN1; diff --git a/libbb/messages.c b/libbb/messages.c index c1b7ba252..23e440bcd 100644 --- a/libbb/messages.c +++ b/libbb/messages.c @@ -29,7 +29,7 @@ const char bb_msg_can_not_create_raw_socket[] ALIGN1 = "can't create raw socket" const char bb_msg_perm_denied_are_you_root[] ALIGN1 = "permission denied (are you root?)"; const char bb_msg_you_must_be_root[] ALIGN1 = "you must be root"; const char bb_msg_requires_arg[] ALIGN1 = "%s requires an argument"; -const char bb_msg_invalid_arg[] ALIGN1 = "invalid argument '%s' to '%s'"; +const char bb_msg_invalid_arg_to[] ALIGN1 = "invalid argument '%s' to '%s'"; const char bb_msg_standard_input[] ALIGN1 = "standard input"; const char bb_msg_standard_output[] ALIGN1 = "standard output"; diff --git a/networking/brctl.c b/networking/brctl.c index c01a86998..b7320966a 100644 --- a/networking/brctl.c +++ b/networking/brctl.c @@ -128,7 +128,7 @@ static ALWAYS_INLINE void bb_strtotimeval(struct timeval *tv, # else if (sscanf(time_str, "%lf", &secs) != 1) # endif - bb_error_msg_and_die(bb_msg_invalid_arg, time_str, "timespec"); + bb_error_msg_and_die(bb_msg_invalid_arg_to, time_str, "timespec"); tv->tv_sec = secs; tv->tv_usec = 1000000 * (secs - tv->tv_sec); } @@ -205,7 +205,7 @@ int brctl_main(int argc UNUSED_PARAM, char **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); + bb_error_msg_and_die(bb_msg_invalid_arg_to, *argv, applet_name); argv++; fd = xsocket(AF_INET, SOCK_STREAM, 0); @@ -299,7 +299,7 @@ int brctl_main(int argc UNUSED_PARAM, char **argv) "1\0" "on\0" "y\0" "yes\0"; /* 4 .. 7 */ int onoff = index_in_strings(no_yes, *argv); if (onoff < 0) - bb_error_msg_and_die(bb_msg_invalid_arg, *argv, applet_name); + bb_error_msg_and_die(bb_msg_invalid_arg_to, *argv, applet_name); onoff = (unsigned)onoff / 4; arm_ioctl(args, BRCTL_SET_BRIDGE_STP_STATE, onoff, 0); goto fire; @@ -332,7 +332,7 @@ int brctl_main(int argc UNUSED_PARAM, char **argv) port = if_nametoindex(*argv++); if (!port) - bb_error_msg_and_die(bb_msg_invalid_arg, *argv, "port"); + bb_error_msg_and_die(bb_msg_invalid_arg_to, *argv, "port"); memset(ifidx, 0, sizeof ifidx); arm_ioctl(args, BRCTL_GET_PORT_LIST, (unsigned long)ifidx, MAX_PORTS); diff --git a/networking/libiproute/ip_parse_common_args.c b/networking/libiproute/ip_parse_common_args.c index 59c759b23..1a298f738 100644 --- a/networking/libiproute/ip_parse_common_args.c +++ b/networking/libiproute/ip_parse_common_args.c @@ -67,7 +67,7 @@ char** FAST_FUNC ip_parse_common_args(char **argv) bb_show_usage(); arg = index_in_strings(families, *argv); if (arg < 0) - invarg(*argv, "protocol family"); + invarg_1_to_2(*argv, "family"); /* now arg == 0, 1 or 2 */ } else { arg -= ARG_IPv4; diff --git a/networking/libiproute/ipaddress.c b/networking/libiproute/ipaddress.c index 8845cab91..c0f27c70d 100644 --- a/networking/libiproute/ipaddress.c +++ b/networking/libiproute/ipaddress.c @@ -455,7 +455,7 @@ int FAST_FUNC ipaddr_list_or_flush(char **argv, int flush) G_filter.scopemask = -1; if (rtnl_rtscope_a2n(&scope, *argv)) { if (strcmp(*argv, "all") != 0) { - invarg(*argv, "scope"); + invarg_1_to_2(*argv, "scope"); } scope = RT_SCOPE_NOWHERE; G_filter.scopemask = 0; @@ -669,7 +669,7 @@ static int ipaddr_modify(int cmd, int flags, char **argv) } else if (arg == 5) { /* scope */ uint32_t scope = 0; if (rtnl_rtscope_a2n(&scope, *argv)) { - invarg(*argv, "scope"); + invarg_1_to_2(*argv, "scope"); } req.ifa.ifa_scope = scope; scoped = 1; @@ -751,7 +751,7 @@ int FAST_FUNC do_ipaddr(char **argv) if (*argv) { cmd = index_in_substrings(commands, *argv); if (cmd < 0) - invarg(*argv, applet_name); + invarg_1_to_2(*argv, applet_name); argv++; if (cmd <= 4) { return ipaddr_modify( diff --git a/networking/libiproute/iplink.c b/networking/libiproute/iplink.c index 5c27c2de3..ae3ef0ceb 100644 --- a/networking/libiproute/iplink.c +++ b/networking/libiproute/iplink.c @@ -349,7 +349,7 @@ static void vlan_parse_opt(char **argv, struct nlmsghdr *n, unsigned int size) while (*argv) { arg = index_in_substrings(keywords, *argv); if (arg < 0) - invarg(*argv, "type vlan"); + invarg_1_to_2(*argv, "type vlan"); NEXT_ARG(); if (arg == ARG_id) { @@ -512,7 +512,7 @@ static int do_add_or_delete(char **argv, const unsigned rtm) if (name_str) { const size_t name_len = strlen(name_str) + 1; if (name_len < 2 || name_len > IFNAMSIZ) - invarg(name_str, "name"); + invarg_1_to_2(name_str, "name"); addattr_l(&req.n, sizeof(req), IFLA_IFNAME, name_str, name_len); } if (rtnl_talk(&rth, &req.n, 0, 0, NULL, NULL, NULL) < 0) @@ -536,14 +536,14 @@ static int do_add_or_delete(char **argv, const unsigned rtm) if (qlen != -1) duparg("txqueuelen", *argv); if (get_integer(&qlen, *argv, 0)) - invarg("Invalid \"txqueuelen\" value\n", *argv); + invarg_1_to_2(*argv, "txqueuelen"); addattr_l(&req->n, sizeof(*req), IFLA_TXQLEN, &qlen, 4); } else if (strcmp(*argv, "mtu") == 0) { NEXT_ARG(); if (mtu != -1) duparg("mtu", *argv); if (get_integer(&mtu, *argv, 0)) - invarg("Invalid \"mtu\" value\n", *argv); + invarg_1_to_2(*argv, "mtu"); addattr_l(&req->n, sizeof(*req), IFLA_MTU, &mtu, 4); } else if (strcmp(*argv, "netns") == 0) { NEXT_ARG(); @@ -554,7 +554,7 @@ static int do_add_or_delete(char **argv, const unsigned rtm) else if (get_integer(&netns, *argv, 0) == 0) addattr_l(&req->n, sizeof(*req), IFLA_NET_NS_PID, &netns, 4); else - invarg("Invalid \"netns\" value\n", *argv); + invarg_1_to_2(*argv, "netns"); } else if (strcmp(*argv, "multicast") == 0) { NEXT_ARG(); req->i.ifi_change |= IFF_MULTICAST; @@ -604,7 +604,7 @@ static int do_add_or_delete(char **argv, const unsigned rtm) struct rtattr *vflist; NEXT_ARG(); if (get_integer(&vf, *argv, 0)) { - invarg("Invalid \"vf\" value\n", *argv); + invarg_1_to_2(*argv, "vf"); } vflist = addattr_nest(&req->n, sizeof(*req), IFLA_VFINFO_LIST); @@ -617,7 +617,7 @@ static int do_add_or_delete(char **argv, const unsigned rtm) NEXT_ARG(); ifindex = ll_name_to_index(*argv); if (!ifindex) - invarg("Device does not exist\n", *argv); + invarg_1_to_2(*argv, "master"); addattr_l(&req->n, sizeof(*req), IFLA_MASTER, &ifindex, 4); } else if (matches(*argv, "nomaster") == 0) { @@ -644,28 +644,27 @@ static int do_add_or_delete(char **argv, const unsigned rtm) if (*group != -1) duparg("group", *argv); if (rtnl_group_a2n(group, *argv)) - invarg("Invalid \"group\" value\n", *argv); + invarg_1_to_2(*argv, "group"); } else if (strcmp(*argv, "mode") == 0) { int mode; NEXT_ARG(); mode = get_link_mode(*argv); if (mode < 0) - invarg("Invalid link mode\n", *argv); + invarg_1_to_2(*argv, "mode"); addattr8(&req->n, sizeof(*req), IFLA_LINKMODE, mode); } else if (strcmp(*argv, "state") == 0) { int state; NEXT_ARG(); state = get_operstate(*argv); if (state < 0) - invarg("Invalid operstate\n", *argv); - + invarg_1_to_2(*argv, "state"); addattr8(&req->n, sizeof(*req), IFLA_OPERSTATE, state); } else if (matches(*argv, "numtxqueues") == 0) { NEXT_ARG(); if (numtxqueues != -1) duparg("numtxqueues", *argv); if (get_integer(&numtxqueues, *argv, 0)) - invarg("Invalid \"numtxqueues\" value\n", *argv); + invarg_1_to_2(*argv, "numtxqueues"); addattr_l(&req->n, sizeof(*req), IFLA_NUM_TX_QUEUES, &numtxqueues, 4); } else if (matches(*argv, "numrxqueues") == 0) { @@ -673,7 +672,7 @@ static int do_add_or_delete(char **argv, const unsigned rtm) if (numrxqueues != -1) duparg("numrxqueues", *argv); if (get_integer(&numrxqueues, *argv, 0)) - invarg("Invalid \"numrxqueues\" value\n", *argv); + invarg_1_to_2(*argv, "numrxqueues"); addattr_l(&req->n, sizeof(*req), IFLA_NUM_RX_QUEUES, &numrxqueues, 4); } @@ -687,7 +686,7 @@ int FAST_FUNC do_iplink(char **argv) if (*argv) { int key = index_in_substrings(keywords, *argv); if (key < 0) /* invalid argument */ - invarg(*argv, applet_name); + invarg_1_to_2(*argv, applet_name); argv++; if (key <= 1) /* add/delete */ return do_add_or_delete(argv, key ? RTM_DELLINK : RTM_NEWLINK); diff --git a/networking/libiproute/ipneigh.c b/networking/libiproute/ipneigh.c index 03a15d845..6588c12f1 100644 --- a/networking/libiproute/ipneigh.c +++ b/networking/libiproute/ipneigh.c @@ -75,7 +75,7 @@ static unsigned nud_state_a2n(char *arg) id = index_in_substrings(keywords, arg); if (id < 0) - bb_error_msg_and_die(bb_msg_invalid_arg, arg, "nud state"); + bb_error_msg_and_die(bb_msg_invalid_arg_to, arg, "nud state"); return nuds[id]; } @@ -281,9 +281,9 @@ static int FAST_FUNC ipneigh_list_or_flush(char **argv, int flush) ll_init_map(&rth); if (filter_dev) { - if ((G_filter.index = xll_name_to_index(filter_dev)) == 0) { - bb_error_msg_and_die(bb_msg_invalid_arg, - filter_dev, "Cannot find device"); + G_filter.index = xll_name_to_index(filter_dev); + if (G_filter.index == 0) { + bb_error_msg_and_die("can't find device '%s'", filter_dev); } } @@ -349,6 +349,6 @@ int FAST_FUNC do_ipneigh(char **argv) case 1: /* flush */ return ipneigh_list_or_flush(argv + 1, 1); } - invarg(*argv, applet_name); + invarg_1_to_2(*argv, applet_name); return 1; } diff --git a/networking/libiproute/iproute.c b/networking/libiproute/iproute.c index f7209b126..0d2914405 100644 --- a/networking/libiproute/iproute.c +++ b/networking/libiproute/iproute.c @@ -403,7 +403,7 @@ IF_FEATURE_IP_RULE(ARG_table,) uint32_t prot; NEXT_ARG(); if (rtnl_rtprot_a2n(&prot, *argv)) - invarg(*argv, "protocol"); + invarg_1_to_2(*argv, "protocol"); req.r.rtm_protocol = prot; ok |= proto_ok; #if ENABLE_FEATURE_IP_RULE @@ -411,7 +411,7 @@ IF_FEATURE_IP_RULE(ARG_table,) uint32_t tid; NEXT_ARG(); if (rtnl_rttable_a2n(&tid, *argv)) - invarg(*argv, "table"); + invarg_1_to_2(*argv, "table"); req.r.rtm_table = tid; #endif } else if (arg == ARG_dev || arg == ARG_oif) { @@ -597,7 +597,7 @@ static int iproute_list_or_flush(char **argv, int flush) //G_filter.protocolmask = -1; if (rtnl_rtprot_a2n(&prot, *argv)) { if (index_in_strings(keywords, *argv) != KW_all) - invarg(*argv, "protocol"); + invarg_1_to_2(*argv, "protocol"); prot = 0; //G_filter.protocolmask = 0; } @@ -622,10 +622,10 @@ static int iproute_list_or_flush(char **argv, int flush) #if ENABLE_FEATURE_IP_RULE uint32_t tid; if (rtnl_rttable_a2n(&tid, *argv)) - invarg(*argv, "table"); + invarg_1_to_2(*argv, "table"); G_filter.tb = tid; #else - invarg(*argv, "table"); + invarg_1_to_2(*argv, "table"); #endif } } else if (arg == KW_cache) { @@ -932,7 +932,7 @@ int FAST_FUNC do_iproute(char **argv) case 11: /* flush */ return iproute_list_or_flush(argv+1, 1); default: - invarg(*argv, applet_name); + invarg_1_to_2(*argv, applet_name); } return iproute_modify(cmd, flags, argv+1); diff --git a/networking/libiproute/iprule.c b/networking/libiproute/iprule.c index 774a3e220..c3b210982 100644 --- a/networking/libiproute/iprule.c +++ b/networking/libiproute/iprule.c @@ -214,7 +214,7 @@ static int iprule_modify(int cmd, char **argv) while (*argv) { key = index_in_substrings(keywords, *argv) + 1; if (key == 0) /* no match found in keywords array, bail out. */ - invarg(*argv, applet_name); + invarg_1_to_2(*argv, applet_name); if (key == ARG_from) { inet_prefix dst; NEXT_ARG(); @@ -239,7 +239,7 @@ static int iprule_modify(int cmd, char **argv) uint32_t tos; NEXT_ARG(); if (rtnl_dsfield_a2n(&tos, *argv)) - invarg(*argv, "TOS"); + invarg_1_to_2(*argv, "TOS"); req.r.rtm_tos = tos; } else if (key == ARG_fwmark) { uint32_t fwmark; @@ -250,7 +250,7 @@ static int iprule_modify(int cmd, char **argv) uint32_t realm; NEXT_ARG(); if (get_rt_realms(&realm, *argv)) - invarg(*argv, "realms"); + invarg_1_to_2(*argv, "realms"); addattr32(&req.n, sizeof(req), RTA_FLOW, realm); } else if (key == ARG_table || key == ARG_lookup @@ -258,7 +258,7 @@ static int iprule_modify(int cmd, char **argv) uint32_t tid; NEXT_ARG(); if (rtnl_rttable_a2n(&tid, *argv)) - invarg(*argv, "table ID"); + invarg_1_to_2(*argv, "table ID"); req.r.rtm_table = tid; table_ok = 1; } else if (key == ARG_dev || @@ -281,7 +281,7 @@ static int iprule_modify(int cmd, char **argv) if (key == ARG_help) bb_show_usage(); if (rtnl_rtntype_a2n(&type, *argv)) - invarg(*argv, "type"); + invarg_1_to_2(*argv, "type"); req.r.rtm_type = type; } argv++; @@ -309,7 +309,7 @@ int FAST_FUNC do_iprule(char **argv) if (*argv) { int cmd = index_in_substrings(ip_rule_commands, *argv); if (cmd < 0) - invarg(*argv, applet_name); + invarg_1_to_2(*argv, applet_name); argv++; if (cmd < 2) return iprule_modify((cmd == 0) ? RTM_NEWRULE : RTM_DELRULE, argv); diff --git a/networking/libiproute/iptunnel.c b/networking/libiproute/iptunnel.c index a65d5e579..b88c3a401 100644 --- a/networking/libiproute/iptunnel.c +++ b/networking/libiproute/iptunnel.c @@ -294,7 +294,7 @@ static void parse_args(char **argv, int cmd, struct ip_tunnel_parm *p) if (key != ARG_inherit) { uval = get_unsigned(*argv, "TTL"); if (uval > 255) - invarg(*argv, "TTL must be <=255"); + invarg_1_to_2(*argv, "TTL"); p->iph.ttl = uval; } } else if (key == ARG_tos || @@ -305,7 +305,7 @@ static void parse_args(char **argv, int cmd, struct ip_tunnel_parm *p) key = index_in_strings(keywords, *argv); if (key != ARG_inherit) { if (rtnl_dsfield_a2n(&uval, *argv)) - invarg(*argv, "TOS"); + invarg_1_to_2(*argv, "TOS"); p->iph.tos = uval; } else p->iph.tos = 1; @@ -562,7 +562,7 @@ int FAST_FUNC do_iptunnel(char **argv) if (*argv) { int key = index_in_substrings(keywords, *argv); if (key < 0) - invarg(*argv, applet_name); + invarg_1_to_2(*argv, applet_name); argv++; if (key == ARG_add) return do_add(SIOCADDTUNNEL, argv); diff --git a/networking/libiproute/utils.c b/networking/libiproute/utils.c index 37b5311f0..7f7cb4203 100644 --- a/networking/libiproute/utils.c +++ b/networking/libiproute/utils.c @@ -47,7 +47,7 @@ unsigned get_unsigned(char *arg, const char *errmsg) return res; } } - invarg(arg, errmsg); /* does not return */ + invarg_1_to_2(arg, errmsg); /* does not return */ } uint32_t get_u32(char *arg, const char *errmsg) @@ -62,7 +62,7 @@ uint32_t get_u32(char *arg, const char *errmsg) return res; } } - invarg(arg, errmsg); /* does not return */ + invarg_1_to_2(arg, errmsg); /* does not return */ } uint16_t get_u16(char *arg, const char *errmsg) @@ -77,7 +77,7 @@ uint16_t get_u16(char *arg, const char *errmsg) return res; } } - invarg(arg, errmsg); /* does not return */ + invarg_1_to_2(arg, errmsg); /* does not return */ } int get_addr_1(inet_prefix *addr, char *name, int family) @@ -230,12 +230,12 @@ uint32_t get_addr32(char *name) void incomplete_command(void) { - bb_error_msg_and_die("command line is not complete, try option \"help\""); + bb_error_msg_and_die("command line is not complete, try \"help\""); } -void invarg(const char *arg, const char *opt) +void invarg_1_to_2(const char *arg, const char *opt) { - bb_error_msg_and_die(bb_msg_invalid_arg, arg, opt); + bb_error_msg_and_die(bb_msg_invalid_arg_to, arg, opt); } void duparg(const char *key, const char *arg) diff --git a/networking/libiproute/utils.h b/networking/libiproute/utils.h index cd15b706b..9bbed6481 100644 --- a/networking/libiproute/utils.h +++ b/networking/libiproute/utils.h @@ -74,7 +74,7 @@ extern const char *format_host(int af, int len, void *addr, char *buf, int bufle rt_addr_n2a(af, addr, buf, buflen) #endif -void invarg(const char *, const char *) NORETURN; +void invarg_1_to_2(const char *, const char *) NORETURN; void duparg(const char *, const char *) NORETURN; void duparg2(const char *, const char *) NORETURN; int inet_addr_match(const inet_prefix *a, const inet_prefix *b, int bits); diff --git a/networking/slattach.c b/networking/slattach.c index a500da6d0..14e0c1941 100644 --- a/networking/slattach.c +++ b/networking/slattach.c @@ -27,7 +27,7 @@ //usage: "\n -F Disable RTS/CTS flow control" #include "libbb.h" -#include "libiproute/utils.h" /* invarg() */ +#include "libiproute/utils.h" /* invarg_1_to_2() */ struct globals { int handle; @@ -175,7 +175,7 @@ int slattach_main(int argc UNUSED_PARAM, char **argv) encap = index_in_strings(proto_names, proto); if (encap < 0) - invarg(proto, "protocol"); + invarg_1_to_2(proto, "protocol"); if (encap > 3) encap = 8; @@ -183,7 +183,7 @@ int slattach_main(int argc UNUSED_PARAM, char **argv) if (opt & OPT_s_baud) { baud_code = tty_value_to_baud(xatoi(baud_str)); if (baud_code < 0) - invarg(baud_str, "baud rate"); + invarg_1_to_2(baud_str, "baud rate"); } /* Trap signals in order to restore tty states upon exit */ diff --git a/networking/tc.c b/networking/tc.c index 6d1fef993..c84c18a67 100644 --- a/networking/tc.c +++ b/networking/tc.c @@ -459,14 +459,14 @@ int tc_main(int argc UNUSED_PARAM, char **argv) obj = index_in_substrings(objects, *argv++); - if (obj < OBJ_qdisc) + if (obj < 0) bb_show_usage(); if (!*argv) cmd = CMD_show; /* list is the default */ else { cmd = index_in_substrings(commands, *argv); if (cmd < 0) - bb_error_msg_and_die(bb_msg_invalid_arg, *argv, applet_name); + invarg_1_to_2(*argv, argv[-1]); argv++; } memset(&msg, 0, sizeof(msg)); @@ -489,7 +489,7 @@ int tc_main(int argc UNUSED_PARAM, char **argv) NEXT_ARG(); /* We don't care about duparg2("qdisc handle",*argv) for now */ if (get_qdisc_handle(&filter_qdisc, *argv)) - invarg(*argv, "qdisc"); + invarg_1_to_2(*argv, "qdisc"); } else if (obj != OBJ_qdisc && (arg == ARG_root @@ -499,7 +499,7 @@ int tc_main(int argc UNUSED_PARAM, char **argv) ) { /* nothing */ } else { - invarg(*argv, "command"); + invarg_1_to_2(*argv, "command"); } NEXT_ARG(); if (arg == ARG_root) { @@ -513,7 +513,7 @@ int tc_main(int argc UNUSED_PARAM, char **argv) if (msg.tcm_parent) duparg(*argv, "parent"); if (get_tc_classid(&handle, *argv)) - invarg(*argv, "parent"); + invarg_1_to_2(*argv, "parent"); msg.tcm_parent = handle; if (obj == OBJ_filter) filter_parent = handle; @@ -538,7 +538,7 @@ int tc_main(int argc UNUSED_PARAM, char **argv) if (filter_proto) duparg(*argv, "protocol"); if (ll_proto_a2n(&tmp, *argv)) - invarg(*argv, "protocol"); + invarg_1_to_2(*argv, "protocol"); filter_proto = tmp; } } From 926d801fa51717b3af3faf33f9d686e92a20ecfd Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Wed, 14 Oct 2015 13:56:42 +0200 Subject: [PATCH 012/260] libiproute: make rt_addr_n2a() and format_host() return auto strings function old new delta rt_addr_n2a 56 53 -3 print_addrinfo 1227 1178 -49 print_neigh 933 881 -52 print_rule 689 617 -72 print_tunnel 640 560 -80 print_route 1727 1588 -139 ------------------------------------------------------------------------------ (add/remove: 0/0 grow/shrink: 0/6 up/down: 0/-395) Total: -395 bytes Signed-off-by: Denys Vlasenko --- networking/libiproute/ipaddress.c | 22 ++++++++----------- networking/libiproute/ipneigh.c | 5 ++--- networking/libiproute/iproute.c | 36 +++++++++++++------------------ networking/libiproute/iprule.c | 19 ++++++---------- networking/libiproute/iptunnel.c | 28 +++++++++++------------- networking/libiproute/utils.c | 14 ++++++------ networking/libiproute/utils.h | 8 +++---- 7 files changed, 57 insertions(+), 75 deletions(-) diff --git a/networking/libiproute/ipaddress.c b/networking/libiproute/ipaddress.c index c0f27c70d..5c975d8c5 100644 --- a/networking/libiproute/ipaddress.c +++ b/networking/libiproute/ipaddress.c @@ -214,8 +214,7 @@ static int FAST_FUNC print_addrinfo(const struct sockaddr_nl *who UNUSED_PARAM, { struct ifaddrmsg *ifa = NLMSG_DATA(n); int len = n->nlmsg_len; - struct rtattr * rta_tb[IFA_MAX+1]; - char abuf[256]; + struct rtattr *rta_tb[IFA_MAX+1]; if (n->nlmsg_type != RTM_NEWADDR && n->nlmsg_type != RTM_DELADDR) return 0; @@ -291,9 +290,9 @@ static int FAST_FUNC print_addrinfo(const struct sockaddr_nl *who UNUSED_PARAM, printf(" family %d ", ifa->ifa_family); if (rta_tb[IFA_LOCAL]) { - fputs(rt_addr_n2a(ifa->ifa_family, - RTA_DATA(rta_tb[IFA_LOCAL]), - abuf, sizeof(abuf)), stdout); + fputs(rt_addr_n2a(ifa->ifa_family, RTA_DATA(rta_tb[IFA_LOCAL])), + stdout + ); if (rta_tb[IFA_ADDRESS] == NULL || memcmp(RTA_DATA(rta_tb[IFA_ADDRESS]), RTA_DATA(rta_tb[IFA_LOCAL]), 4) == 0 @@ -301,25 +300,22 @@ static int FAST_FUNC print_addrinfo(const struct sockaddr_nl *who UNUSED_PARAM, printf("/%d ", ifa->ifa_prefixlen); } else { printf(" peer %s/%d ", - rt_addr_n2a(ifa->ifa_family, - RTA_DATA(rta_tb[IFA_ADDRESS]), - abuf, sizeof(abuf)), - ifa->ifa_prefixlen); + rt_addr_n2a(ifa->ifa_family, RTA_DATA(rta_tb[IFA_ADDRESS])), + ifa->ifa_prefixlen + ); } } if (rta_tb[IFA_BROADCAST]) { printf("brd %s ", rt_addr_n2a(ifa->ifa_family, - RTA_DATA(rta_tb[IFA_BROADCAST]), - abuf, sizeof(abuf)) + RTA_DATA(rta_tb[IFA_BROADCAST])) ); } if (rta_tb[IFA_ANYCAST]) { printf("any %s ", rt_addr_n2a(ifa->ifa_family, - RTA_DATA(rta_tb[IFA_ANYCAST]), - abuf, sizeof(abuf)) + RTA_DATA(rta_tb[IFA_ANYCAST])) ); } printf("scope %s ", rtnl_rtscope_n2a(ifa->ifa_scope)); diff --git a/networking/libiproute/ipneigh.c b/networking/libiproute/ipneigh.c index 6588c12f1..179505c2d 100644 --- a/networking/libiproute/ipneigh.c +++ b/networking/libiproute/ipneigh.c @@ -91,7 +91,6 @@ static int FAST_FUNC print_neigh(const struct sockaddr_nl *who UNUSED_PARAM, struct ndmsg *r = NLMSG_DATA(n); int len = n->nlmsg_len; struct rtattr *tb[NDA_MAX+1]; - char abuf[256]; if (n->nlmsg_type != RTM_NEWNEIGH && n->nlmsg_type != RTM_DELNEIGH) { bb_error_msg_and_die("not RTM_NEWNEIGH: %08x %08x %08x", @@ -155,8 +154,8 @@ static int FAST_FUNC print_neigh(const struct sockaddr_nl *who UNUSED_PARAM, printf("%s ", format_host(r->ndm_family, RTA_PAYLOAD(tb[NDA_DST]), - RTA_DATA(tb[NDA_DST]), - abuf, sizeof(abuf))); + RTA_DATA(tb[NDA_DST])) + ); } if (!G_filter.index && r->ndm_ifindex) printf("dev %s ", ll_index_to_name(r->ndm_ifindex)); diff --git a/networking/libiproute/iproute.c b/networking/libiproute/iproute.c index 0d2914405..d232ee6fd 100644 --- a/networking/libiproute/iproute.c +++ b/networking/libiproute/iproute.c @@ -61,7 +61,6 @@ static int FAST_FUNC print_route(const struct sockaddr_nl *who UNUSED_PARAM, struct rtmsg *r = NLMSG_DATA(n); int len = n->nlmsg_len; struct rtattr *tb[RTA_MAX+1]; - char abuf[256]; inet_prefix dst; inet_prefix src; int host_len = -1; @@ -218,17 +217,15 @@ static int FAST_FUNC print_route(const struct sockaddr_nl *who UNUSED_PARAM, if (tb[RTA_DST]) { if (r->rtm_dst_len != host_len) { - printf("%s/%u ", rt_addr_n2a(r->rtm_family, - RTA_DATA(tb[RTA_DST]), - abuf, sizeof(abuf)), - r->rtm_dst_len - ); + printf("%s/%u ", + rt_addr_n2a(r->rtm_family, RTA_DATA(tb[RTA_DST])), + r->rtm_dst_len + ); } else { printf("%s ", format_host(r->rtm_family, RTA_PAYLOAD(tb[RTA_DST]), - RTA_DATA(tb[RTA_DST]), - abuf, sizeof(abuf)) - ); + RTA_DATA(tb[RTA_DST])) + ); } } else if (r->rtm_dst_len) { printf("0/%d ", r->rtm_dst_len); @@ -237,17 +234,15 @@ static int FAST_FUNC print_route(const struct sockaddr_nl *who UNUSED_PARAM, } if (tb[RTA_SRC]) { if (r->rtm_src_len != host_len) { - printf("from %s/%u ", rt_addr_n2a(r->rtm_family, - RTA_DATA(tb[RTA_SRC]), - abuf, sizeof(abuf)), - r->rtm_src_len - ); + printf("from %s/%u ", + rt_addr_n2a(r->rtm_family, RTA_DATA(tb[RTA_SRC])), + r->rtm_src_len + ); } else { printf("from %s ", format_host(r->rtm_family, RTA_PAYLOAD(tb[RTA_SRC]), - RTA_DATA(tb[RTA_SRC]), - abuf, sizeof(abuf)) - ); + RTA_DATA(tb[RTA_SRC])) + ); } } else if (r->rtm_src_len) { printf("from 0/%u ", r->rtm_src_len); @@ -255,8 +250,8 @@ static int FAST_FUNC print_route(const struct sockaddr_nl *who UNUSED_PARAM, if (tb[RTA_GATEWAY] && G_filter.rvia.bitlen != host_len) { printf("via %s ", format_host(r->rtm_family, RTA_PAYLOAD(tb[RTA_GATEWAY]), - RTA_DATA(tb[RTA_GATEWAY]), - abuf, sizeof(abuf))); + RTA_DATA(tb[RTA_GATEWAY])) + ); } if (tb[RTA_OIF]) { printf("dev %s ", ll_index_to_name(*(int*)RTA_DATA(tb[RTA_OIF]))); @@ -269,8 +264,7 @@ static int FAST_FUNC print_route(const struct sockaddr_nl *who UNUSED_PARAM, and symbolic name will not be useful. */ printf(" src %s ", rt_addr_n2a(r->rtm_family, - RTA_DATA(tb[RTA_PREFSRC]), - abuf, sizeof(abuf))); + RTA_DATA(tb[RTA_PREFSRC]))); } if (tb[RTA_PRIORITY]) { printf(" metric %d ", *(uint32_t*)RTA_DATA(tb[RTA_PRIORITY])); diff --git a/networking/libiproute/iprule.c b/networking/libiproute/iprule.c index c3b210982..dba64346f 100644 --- a/networking/libiproute/iprule.c +++ b/networking/libiproute/iprule.c @@ -44,7 +44,6 @@ static int FAST_FUNC print_rule(const struct sockaddr_nl *who UNUSED_PARAM, int len = n->nlmsg_len; int host_len = -1; struct rtattr * tb[RTA_MAX+1]; - char abuf[256]; if (n->nlmsg_type != RTM_NEWRULE) return 0; @@ -71,16 +70,14 @@ static int FAST_FUNC print_rule(const struct sockaddr_nl *who UNUSED_PARAM, printf("from "); if (tb[RTA_SRC]) { if (r->rtm_src_len != host_len) { - printf("%s/%u", rt_addr_n2a(r->rtm_family, - RTA_DATA(tb[RTA_SRC]), - abuf, sizeof(abuf)), + printf("%s/%u", + rt_addr_n2a(r->rtm_family, RTA_DATA(tb[RTA_SRC])), r->rtm_src_len ); } else { fputs(format_host(r->rtm_family, RTA_PAYLOAD(tb[RTA_SRC]), - RTA_DATA(tb[RTA_SRC]), - abuf, sizeof(abuf)), + RTA_DATA(tb[RTA_SRC])), stdout ); } @@ -94,15 +91,13 @@ static int FAST_FUNC print_rule(const struct sockaddr_nl *who UNUSED_PARAM, if (tb[RTA_DST]) { if (r->rtm_dst_len != host_len) { printf("to %s/%u ", rt_addr_n2a(r->rtm_family, - RTA_DATA(tb[RTA_DST]), - abuf, sizeof(abuf)), + RTA_DATA(tb[RTA_DST])), r->rtm_dst_len ); } else { printf("to %s ", format_host(r->rtm_family, RTA_PAYLOAD(tb[RTA_DST]), - RTA_DATA(tb[RTA_DST]), - abuf, sizeof(abuf))); + RTA_DATA(tb[RTA_DST]))); } } else if (r->rtm_dst_len) { printf("to 0/%d ", r->rtm_dst_len); @@ -139,8 +134,8 @@ static int FAST_FUNC print_rule(const struct sockaddr_nl *who UNUSED_PARAM, printf("map-to %s ", format_host(r->rtm_family, RTA_PAYLOAD(tb[RTA_GATEWAY]), - RTA_DATA(tb[RTA_GATEWAY]), - abuf, sizeof(abuf))); + RTA_DATA(tb[RTA_GATEWAY])) + ); } else printf("masquerade"); } else if (r->rtm_type != RTN_UNICAST) diff --git a/networking/libiproute/iptunnel.c b/networking/libiproute/iptunnel.c index b88c3a401..eb136e435 100644 --- a/networking/libiproute/iptunnel.c +++ b/networking/libiproute/iptunnel.c @@ -404,22 +404,18 @@ static int do_del(char **argv) static void print_tunnel(struct ip_tunnel_parm *p) { - char s1[256]; - char s2[256]; - char s3[64]; - char s4[64]; - - format_host(AF_INET, 4, &p->iph.daddr, s1, sizeof(s1)); - format_host(AF_INET, 4, &p->iph.saddr, s2, sizeof(s2)); - inet_ntop(AF_INET, &p->i_key, s3, sizeof(s3)); - inet_ntop(AF_INET, &p->o_key, s4, sizeof(s4)); + char s3[INET_ADDRSTRLEN]; + char s4[INET_ADDRSTRLEN]; printf("%s: %s/ip remote %s local %s ", - p->name, - p->iph.protocol == IPPROTO_IPIP ? "ip" : - (p->iph.protocol == IPPROTO_GRE ? "gre" : - (p->iph.protocol == IPPROTO_IPV6 ? "ipv6" : "unknown")), - p->iph.daddr ? s1 : "any", p->iph.saddr ? s2 : "any"); + p->name, + p->iph.protocol == IPPROTO_IPIP ? "ip" : + p->iph.protocol == IPPROTO_GRE ? "gre" : + p->iph.protocol == IPPROTO_IPV6 ? "ipv6" : + "unknown", + p->iph.daddr ? format_host(AF_INET, 4, &p->iph.daddr) : "any", + p->iph.saddr ? format_host(AF_INET, 4, &p->iph.saddr) : "any" + ); if (p->link) { char *n = do_ioctl_get_ifname(p->link); if (n) { @@ -442,9 +438,11 @@ static void print_tunnel(struct ip_tunnel_parm *p) if (!(p->iph.frag_off & htons(IP_DF))) printf(" nopmtudisc"); + inet_ntop(AF_INET, &p->i_key, s3, sizeof(s3)); + inet_ntop(AF_INET, &p->o_key, s4, sizeof(s4)); if ((p->i_flags & GRE_KEY) && (p->o_flags & GRE_KEY) && p->o_key == p->i_key) printf(" key %s", s3); - else if ((p->i_flags | p->o_flags) & GRE_KEY) { + else { if (p->i_flags & GRE_KEY) printf(" ikey %s ", s3); if (p->o_flags & GRE_KEY) diff --git a/networking/libiproute/utils.c b/networking/libiproute/utils.c index 7f7cb4203..42025bc66 100644 --- a/networking/libiproute/utils.c +++ b/networking/libiproute/utils.c @@ -276,20 +276,21 @@ int inet_addr_match(const inet_prefix *a, const inet_prefix *b, int bits) return 0; } -const char *rt_addr_n2a(int af, - void *addr, char *buf, int buflen) +const char *rt_addr_n2a(int af, void *addr) { switch (af) { case AF_INET: case AF_INET6: - return inet_ntop(af, addr, buf, buflen); + return inet_ntop(af, addr, + auto_string(xzalloc(INET6_ADDRSTRLEN)), INET6_ADDRSTRLEN + ); default: return "???"; } } #ifdef RESOLVE_HOSTNAMES -const char *format_host(int af, int len, void *addr, char *buf, int buflen) +const char *format_host(int af, int len, void *addr) { if (resolve_hosts) { struct hostent *h_ent; @@ -308,11 +309,10 @@ const char *format_host(int af, int len, void *addr, char *buf, int buflen) if (len > 0) { h_ent = gethostbyaddr(addr, len, af); if (h_ent != NULL) { - safe_strncpy(buf, h_ent->h_name, buflen); - return buf; + return auto_string(xstrdup(h_ent->h_name)); } } } - return rt_addr_n2a(af, addr, buf, buflen); + return rt_addr_n2a(af, addr); } #endif diff --git a/networking/libiproute/utils.h b/networking/libiproute/utils.h index 9bbed6481..408d5f65f 100644 --- a/networking/libiproute/utils.h +++ b/networking/libiproute/utils.h @@ -66,12 +66,12 @@ extern unsigned get_unsigned(char *arg, const char *errmsg); extern uint32_t get_u32(char *arg, const char *errmsg); extern uint16_t get_u16(char *arg, const char *errmsg); -extern const char *rt_addr_n2a(int af, void *addr, char *buf, int buflen); +extern const char *rt_addr_n2a(int af, void *addr); #ifdef RESOLVE_HOSTNAMES -extern const char *format_host(int af, int len, void *addr, char *buf, int buflen); +extern const char *format_host(int af, int len, void *addr); #else -#define format_host(af, len, addr, buf, buflen) \ - rt_addr_n2a(af, addr, buf, buflen) +#define format_host(af, len, addr) \ + rt_addr_n2a(af, addr) #endif void invarg_1_to_2(const char *, const char *) NORETURN; From 4ad702c0a70628ce7574609087e50b0ce40455d6 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Wed, 14 Oct 2015 22:29:52 +0200 Subject: [PATCH 013/260] top: make sort field for 's' mode less confusing function old new delta display_topmem_process_list 542 565 +23 Signed-off-by: Denys Vlasenko --- procps/top.c | 27 ++++++++++++++------------- 1 file changed, 14 insertions(+), 13 deletions(-) diff --git a/procps/top.c b/procps/top.c index 9a3f171ac..ddf794d7d 100644 --- a/procps/top.c +++ b/procps/top.c @@ -829,10 +829,17 @@ static NOINLINE void display_topmem_process_list(int lines_rem, int scr_width) #define HDR_STR " PID VSZ VSZRW RSS (SHR) DIRTY (SHR) STACK" #define MIN_WIDTH sizeof(HDR_STR) const topmem_status_t *s = topmem + G_scroll_ofs; + char *cp, ch; display_topmem_header(scr_width, &lines_rem); + strcpy(line_buf, HDR_STR " COMMAND"); - line_buf[11 + sort_field * 6] = "^_"[inverted]; + /* Mark the ^FIELD^ we sort by */ + cp = &line_buf[5 + sort_field * 6]; + ch = "^_"[inverted]; + cp[6] = ch; + do *cp++ = ch; while (*cp == ' '); + printf(OPT_BATCH_MODE ? "%.*s" : "\e[7m%.*s\e[0m", scr_width, line_buf); lines_rem--; @@ -1172,10 +1179,8 @@ int top_main(int argc UNUSED_PARAM, char **argv) ntop = 0; while ((p = procps_scan(p, scan_mask)) != NULL) { int n; -#if ENABLE_FEATURE_TOPMEM - if (scan_mask != TOPMEM_MASK) -#endif - { + + IF_FEATURE_TOPMEM(if (scan_mask != TOPMEM_MASK)) { n = ntop; top = xrealloc_vector(top, 6, ntop++); top[n].pid = p->pid; @@ -1215,7 +1220,7 @@ int top_main(int argc UNUSED_PARAM, char **argv) break; } - if (scan_mask != TOPMEM_MASK) { + IF_FEATURE_TOPMEM(if (scan_mask != TOPMEM_MASK)) { #if ENABLE_FEATURE_TOP_CPU_USAGE_PERCENTAGE if (!prev_hist_count) { do_stats(); @@ -1229,17 +1234,13 @@ int top_main(int argc UNUSED_PARAM, char **argv) #else qsort(top, ntop, sizeof(top_status_t), (void*)(sort_function[0])); #endif + display_process_list(G.lines, col); } #if ENABLE_FEATURE_TOPMEM else { /* TOPMEM */ qsort(topmem, ntop, sizeof(topmem_status_t), (void*)topmem_sort); - } -#endif - if (scan_mask != TOPMEM_MASK) - display_process_list(G.lines, col); -#if ENABLE_FEATURE_TOPMEM - else display_topmem_process_list(G.lines, col); + } #endif clearmems(); if (iterations >= 0 && !--iterations) @@ -1248,7 +1249,7 @@ int top_main(int argc UNUSED_PARAM, char **argv) sleep(interval); #else scan_mask = handle_input(scan_mask, interval); -#endif /* FEATURE_USE_TERMIOS */ +#endif } /* end of "while (not Q)" */ bb_putchar('\n'); From 5251135bc184bdcb8cbcb964e8c44c6c301bffdc Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Thu, 15 Oct 2015 02:10:11 +0200 Subject: [PATCH 014/260] better pinger service example Signed-off-by: Denys Vlasenko --- examples/var_service/dhcp_if_pinger/run | 44 +++++++++++++++++++------ 1 file changed, 34 insertions(+), 10 deletions(-) diff --git a/examples/var_service/dhcp_if_pinger/run b/examples/var_service/dhcp_if_pinger/run index 20b2fc516..1868510d1 100755 --- a/examples/var_service/dhcp_if_pinger/run +++ b/examples/var_service/dhcp_if_pinger/run @@ -1,23 +1,47 @@ #!/bin/sh -delay=67 - +# How often to test, seconds +ping_time=67 +# "One ping, must have reply in 1 sec" +ping_opts="-c1 -W1 -w1" +# If ping failed, how soon to retry +retry_time=5 +# Reinit after this many consecutive ping error +max_fail=5 +# Interface whose DHCP data to use if=${PWD##*/dhcp_} if=${if%%_pinger} +msg() { + echo "`date '+%Y-%m-%d %H:%M:%S'` $*" >>"$0.log" +} + if test -f "$0.log"; then tail -999 "$0.log" >"$0.log.new" mv "$0.log.new" "$0.log" fi -test -f "/var/service/dhcp_$if/dhcp_$if.out" || exec env - sleep "$delay" +test -f "/var/service/dhcp_$if/dhcp_$if.out" || exec env - sleep "$ping_time" + . "/var/service/dhcp_$if/dhcp_$if.out" -test x"$router" != x"" || exec env - sleep "$delay" +test x"$router" != x"" || exec env - sleep "$ping_time" -#echo "`date '+%Y-%m-%d %H:%M:%S'` Testing ping -c3 $router" >>"$0.log" -ping -c3 "$router" && exec env - sleep "$delay" +#msg "Pinging $router" +failcnt=0 +while true; do + ping $ping_opts "$router" && exec env - sleep "$ping_time" + : $((failcnt++)) + msg "Failed to ping $router, fail count:$failcnt" + test $failcnt -ge $max_fail && break + env - sleep "$retry_time" +done -echo "`date '+%Y-%m-%d %H:%M:%S'` Restarting /var/service/dhcp_$if" >>"$0.log" -sv t "/var/service/dhcp_$if" - -exec env - sleep "$delay" +test -d "/var/service/dhcp_$if" && { + msg "Restarting /var/service/dhcp_$if" + sv t "/var/service/dhcp_$if" +} +test -d "/var/service/supplicant_$if" && { + msg "Restarting /var/service/supplicant_$if" + sv t "/var/service/supplicant_$if" +} +exec env - sleep "$ping_time" From 93dd9fd90ae284e7878767fe14bcb17e3edd9cf8 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Thu, 15 Oct 2015 21:33:34 +0200 Subject: [PATCH 015/260] du: extra compat: with -k and -m, round sizes up function old new delta print 36 65 +29 Signed-off-by: Denys Vlasenko --- coreutils/du.c | 37 +++++++++++++++++++++++-------------- libbb/human_readable.c | 11 +++-------- 2 files changed, 26 insertions(+), 22 deletions(-) diff --git a/coreutils/du.c b/coreutils/du.c index 9c6ff8800..1889c16bb 100644 --- a/coreutils/du.c +++ b/coreutils/du.c @@ -75,7 +75,7 @@ enum { struct globals { #if ENABLE_FEATURE_HUMAN_READABLE - unsigned long disp_hr; + unsigned long disp_unit; #else unsigned disp_k; #endif @@ -89,18 +89,27 @@ struct globals { #define INIT_G() do { } while (0) -/* FIXME? coreutils' du rounds sizes up: - * for example, 1025k file is shown as "2" by du -m. - * We round to nearest. - */ static void print(unsigned long long size, const char *filename) { /* TODO - May not want to defer error checking here. */ #if ENABLE_FEATURE_HUMAN_READABLE +# if ENABLE_DESKTOP + /* ~30 bytes of code for extra comtat: + * coreutils' du rounds sizes up: + * for example, 1025k file is shown as "2" by du -m. + * We round to nearest if human-readable [too hard to fix], + * else (fixed scale such as -m), we round up. To that end, + * add yet another half of the unit before displaying: + */ + if (G.disp_unit) + size += (G.disp_unit-1) / (unsigned)(512 * 2); +# endif printf("%s\t%s\n", - /* size x 512 / G.disp_hr, show one fractional, - * use suffixes if G.disp_hr == 0 */ - make_human_readable_str(size, 512, G.disp_hr), + /* size x 512 / G.disp_unit. + * If G.disp_unit == 0, show one fractional + * and use suffixes + */ + make_human_readable_str(size, 512, G.disp_unit), filename); #else if (G.disp_k) { @@ -199,10 +208,10 @@ int du_main(int argc UNUSED_PARAM, char **argv) INIT_G(); #if ENABLE_FEATURE_HUMAN_READABLE - IF_FEATURE_DU_DEFAULT_BLOCKSIZE_1K(G.disp_hr = 1024;) - IF_NOT_FEATURE_DU_DEFAULT_BLOCKSIZE_1K(G.disp_hr = 512;) + IF_FEATURE_DU_DEFAULT_BLOCKSIZE_1K(G.disp_unit = 1024;) + IF_NOT_FEATURE_DU_DEFAULT_BLOCKSIZE_1K(G.disp_unit = 512;) if (getenv("POSIXLY_CORRECT")) /* TODO - a new libbb function? */ - G.disp_hr = 512; + G.disp_unit = 512; #else IF_FEATURE_DU_DEFAULT_BLOCKSIZE_1K(G.disp_k = 1;) /* IF_NOT_FEATURE_DU_DEFAULT_BLOCKSIZE_1K(G.disp_k = 0;) - G is pre-zeroed */ @@ -220,13 +229,13 @@ int du_main(int argc UNUSED_PARAM, char **argv) opt = getopt32(argv, "aHkLsx" "d:" "lc" "hm", &G.max_print_depth); argv += optind; if (opt & OPT_h_for_humans) { - G.disp_hr = 0; + G.disp_unit = 0; } if (opt & OPT_m_mbytes) { - G.disp_hr = 1024*1024; + G.disp_unit = 1024*1024; } if (opt & OPT_k_kbytes) { - G.disp_hr = 1024; + G.disp_unit = 1024; } #else opt_complementary = "H-L:L-H:s-d:d-s:d+"; diff --git a/libbb/human_readable.c b/libbb/human_readable.c index 5c7fc076f..b4e0ef181 100644 --- a/libbb/human_readable.c +++ b/libbb/human_readable.c @@ -14,16 +14,11 @@ * representations (say, powers of 1024) and manipulating coefficients. * The base ten "bytes" output could be handled similarly. * - * 2) This routine always outputs a decimal point and a tenths digit when - * display_unit != 0. Hence, it isn't uncommon for the returned string + * 2) This routine outputs a decimal point and a tenths digit when + * display_unit == 0. Hence, it isn't uncommon for the returned string * to have a length of 5 or 6. * - * It might be nice to add a flag to indicate no decimal digits in - * that case. This could be either an additional parameter, or a - * special value of display_unit. Such a flag would also be nice for du. - * - * Some code to omit the decimal point and tenths digit is sketched out - * and "#if 0"'d below. + * If block_size is also 0, no decimal digits are printed. * * Licensed under GPLv2, see file LICENSE in this source tree. */ From 2735bc00e35c5fd8eec6d656f4d8a17ee2630c2a Mon Sep 17 00:00:00 2001 From: Aaro Koskinen Date: Fri, 16 Oct 2015 17:24:46 +0200 Subject: [PATCH 016/260] cpio: implement -R/--owner Implement -R/--owner to force ownership of files. function old new delta cpio_main 532 586 +54 get_header_cpio 909 939 +30 print 36 65 +29 cpio_o 804 832 +28 cpio_TRAILER - 11 +11 packed_usage 30667 30662 -5 static.trailer 11 - -11 ------------------------------------------------------------------------------ (add/remove: 1/1 grow/shrink: 4/1 up/down: 152/-16) Total: 136 bytes Signed-off-by: Aaro Koskinen Signed-off-by: Denys Vlasenko --- archival/Kbuild.src | 2 +- archival/cpio.c | 46 +++++++++++++++++++++------ archival/libarchive/Kbuild.src | 2 +- archival/libarchive/common.c | 9 ++++++ archival/libarchive/get_header_cpio.c | 7 +++- coreutils/chown.c | 4 +-- include/bb_archive.h | 3 ++ 7 files changed, 58 insertions(+), 15 deletions(-) create mode 100644 archival/libarchive/common.c diff --git a/archival/Kbuild.src b/archival/Kbuild.src index a6fd2eac0..b3a7d538f 100644 --- a/archival/Kbuild.src +++ b/archival/Kbuild.src @@ -4,7 +4,7 @@ # # Licensed under GPLv2, see file LICENSE in this source tree. -libs-y += libarchive/ +libs-y += libarchive/ lib-y:= diff --git a/archival/cpio.c b/archival/cpio.c index cdc16c14e..82b3fe5ed 100644 --- a/archival/cpio.c +++ b/archival/cpio.c @@ -46,7 +46,7 @@ //kbuild:lib-$(CONFIG_CPIO) += cpio.o //usage:#define cpio_trivial_usage -//usage: "[-dmvu] [-F FILE]" IF_FEATURE_CPIO_O(" [-H newc]") +//usage: "[-dmvu] [-F FILE] [-R USER[:GRP]]" IF_FEATURE_CPIO_O(" [-H newc]") //usage: " [-ti"IF_FEATURE_CPIO_O("o")"]" IF_FEATURE_CPIO_P(" [-p DIR]") //usage: " [EXTR_FILE]..." //usage:#define cpio_full_usage "\n\n" @@ -71,6 +71,7 @@ //usage: "\n -v Verbose" //usage: "\n -u Overwrite" //usage: "\n -F FILE Input (-t,-i,-p) or output (-o) file" +//usage: "\n -R USER[:GRP] Set owner of created files" //usage: IF_FEATURE_CPIO_O( //usage: "\n -H newc Archive format" //usage: ) @@ -130,7 +131,7 @@ -I FILE File to use instead of standard input -L, --dereference Dereference symbolic links (copy the files that they point to instead of copying the links) - -R, --owner=[USER][:.][GROUP] Set owner of created files + -R, --owner=[USER][:.][GRP] Set owner of created files Options valid in --extract and --pass-through modes: -d, --make-directories Create leading directories where needed @@ -150,7 +151,8 @@ enum { OPT_PRESERVE_MTIME = (1 << 6), OPT_DEREF = (1 << 7), OPT_FILE = (1 << 8), - OPTBIT_FILE = 8, + OPT_OWNER = (1 << 9), + OPTBIT_OWNER = 9, IF_FEATURE_CPIO_O(OPTBIT_CREATE ,) IF_FEATURE_CPIO_O(OPTBIT_FORMAT ,) IF_FEATURE_CPIO_P(OPTBIT_PASSTHROUGH,) @@ -163,7 +165,17 @@ enum { OPT_2STDOUT = IF_LONG_OPTS( (1 << OPTBIT_2STDOUT )) + 0, }; -#define OPTION_STR "it0uvdmLF:" +#define OPTION_STR "it0uvdmLF:R:" + +struct globals { + struct bb_uidgid_t owner_ugid; +} FIX_ALIASING; +#define G (*(struct globals*)&bb_common_bufsiz1) +void BUG_cpio_globals_too_big(void); +#define INIT_G() do { \ + G.owner_ugid.uid = -1L; \ + G.owner_ugid.gid = -1L; \ +} while (0) #if ENABLE_FEATURE_CPIO_O static off_t cpio_pad4(off_t size) @@ -181,7 +193,6 @@ static off_t cpio_pad4(off_t size) * It's ok to exit instead of return. */ static NOINLINE int cpio_o(void) { - static const char trailer[] ALIGN1 = "TRAILER!!!"; struct name_s { struct name_s *next; char name[1]; @@ -223,6 +234,11 @@ static NOINLINE int cpio_o(void) bb_simple_perror_msg_and_die(name); } + if (G.owner_ugid.uid != (uid_t)-1L) + st.st_uid = G.owner_ugid.uid; + if (G.owner_ugid.gid != (gid_t)-1L) + st.st_gid = G.owner_ugid.gid; + if (!(S_ISLNK(st.st_mode) || S_ISREG(st.st_mode))) st.st_size = 0; /* paranoia */ @@ -275,7 +291,7 @@ static NOINLINE int cpio_o(void) } else { /* If no (more) hardlinks to output, * output "trailer" entry */ - name = trailer; + name = cpio_TRAILER; /* st.st_size == 0 is a must, but for uniformity * in the output, we zero out everything */ memset(&st, 0, sizeof(st)); @@ -323,7 +339,7 @@ static NOINLINE int cpio_o(void) } if (!line) { - if (name != trailer) + if (name != cpio_TRAILER) goto next_link; /* TODO: GNU cpio pads trailer to 512 bytes, do we want that? */ return EXIT_SUCCESS; @@ -339,6 +355,7 @@ int cpio_main(int argc UNUSED_PARAM, char **argv) { archive_handle_t *archive_handle; char *cpio_filename; + char *cpio_owner; IF_FEATURE_CPIO_O(const char *cpio_fmt = "";) unsigned opt; @@ -353,12 +370,14 @@ int cpio_main(int argc UNUSED_PARAM, char **argv) "pass-through\0" No_argument "p" #endif #endif + "owner\0" Required_argument "R" "verbose\0" No_argument "v" "quiet\0" No_argument "\xff" "to-stdout\0" No_argument "\xfe" ; #endif + INIT_G(); archive_handle = init_handle(); /* archive_handle->src_fd = STDIN_FILENO; - done by init_handle */ archive_handle->ah_flags = ARCHIVE_EXTRACT_NEWER; @@ -369,14 +388,21 @@ int cpio_main(int argc UNUSED_PARAM, char **argv) /* -L makes sense only with -o or -p */ #if !ENABLE_FEATURE_CPIO_O - opt = getopt32(argv, OPTION_STR, &cpio_filename); + opt = getopt32(argv, OPTION_STR, &cpio_filename, &cpio_owner); +#else + opt = getopt32(argv, OPTION_STR "oH:" IF_FEATURE_CPIO_P("p"), + &cpio_filename, &cpio_owner, &cpio_fmt); +#endif argv += optind; + if (opt & OPT_OWNER) { /* -R */ + parse_chown_usergroup_or_die(&G.owner_ugid, cpio_owner); + archive_handle->cpio__owner = G.owner_ugid; + } +#if !ENABLE_FEATURE_CPIO_O if (opt & OPT_FILE) { /* -F */ xmove_fd(xopen(cpio_filename, O_RDONLY), STDIN_FILENO); } #else - opt = getopt32(argv, OPTION_STR "oH:" IF_FEATURE_CPIO_P("p"), &cpio_filename, &cpio_fmt); - argv += optind; if ((opt & (OPT_FILE|OPT_CREATE)) == OPT_FILE) { /* -F without -o */ xmove_fd(xopen(cpio_filename, O_RDONLY), STDIN_FILENO); } diff --git a/archival/libarchive/Kbuild.src b/archival/libarchive/Kbuild.src index b7faaf77f..b159a786a 100644 --- a/archival/libarchive/Kbuild.src +++ b/archival/libarchive/Kbuild.src @@ -4,7 +4,7 @@ # # Licensed under GPLv2 or later, see file LICENSE in this source tree. -lib-y:= +lib-y:= common.o COMMON_FILES:= \ \ diff --git a/archival/libarchive/common.c b/archival/libarchive/common.c new file mode 100644 index 000000000..dd69d2222 --- /dev/null +++ b/archival/libarchive/common.c @@ -0,0 +1,9 @@ +/* vi: set sw=4 ts=4: */ +/* + * Licensed under GPLv2 or later, see file LICENSE in this source tree. + */ + +#include "libbb.h" +#include "bb_archive.h" + +const char cpio_TRAILER[] = "TRAILER!!!"; diff --git a/archival/libarchive/get_header_cpio.c b/archival/libarchive/get_header_cpio.c index 7861d1f6f..badd4a841 100644 --- a/archival/libarchive/get_header_cpio.c +++ b/archival/libarchive/get_header_cpio.c @@ -52,6 +52,11 @@ char FAST_FUNC get_header_cpio(archive_handle_t *archive_handle) &major, &minor, &namesize) != 10) bb_error_msg_and_die("damaged cpio file"); file_header->mode = mode; + /* "cpio -R USER:GRP" support: */ + if (archive_handle->cpio__owner.uid != (uid_t)-1L) + uid = archive_handle->cpio__owner.uid; + if (archive_handle->cpio__owner.gid != (gid_t)-1L) + gid = archive_handle->cpio__owner.gid; file_header->uid = uid; file_header->gid = gid; file_header->mtime = mtime; @@ -75,7 +80,7 @@ char FAST_FUNC get_header_cpio(archive_handle_t *archive_handle) /* Update offset amount and skip padding before file contents */ data_align(archive_handle, 4); - if (strcmp(file_header->name, "TRAILER!!!") == 0) { + if (strcmp(file_header->name, cpio_TRAILER) == 0) { /* Always round up. ">> 9" divides by 512 */ archive_handle->cpio__blocks = (uoff_t)(archive_handle->offset + 511) >> 9; goto create_hardlinks; diff --git a/coreutils/chown.c b/coreutils/chown.c index 679c0d832..eaa1ee2a3 100644 --- a/coreutils/chown.c +++ b/coreutils/chown.c @@ -11,9 +11,9 @@ /* http://www.opengroup.org/onlinepubs/007904975/utilities/chown.html */ //usage:#define chown_trivial_usage -//usage: "[-Rh"IF_DESKTOP("LHPcvf")"]... OWNER[<.|:>[GROUP]] FILE..." +//usage: "[-Rh"IF_DESKTOP("LHPcvf")"]... USER[:[GRP]] FILE..." //usage:#define chown_full_usage "\n\n" -//usage: "Change the owner and/or group of each FILE to OWNER and/or GROUP\n" +//usage: "Change the owner and/or group of each FILE to USER and/or GRP\n" //usage: "\n -R Recurse" //usage: "\n -h Affect symlinks instead of symlink targets" //usage: IF_DESKTOP( diff --git a/include/bb_archive.h b/include/bb_archive.h index 5d9e24c17..2329d025d 100644 --- a/include/bb_archive.h +++ b/include/bb_archive.h @@ -95,6 +95,7 @@ typedef struct archive_handle_t { #endif #if ENABLE_CPIO || ENABLE_RPM2CPIO || ENABLE_RPM uoff_t cpio__blocks; + struct bb_uidgid_t cpio__owner; struct hardlinks_t *cpio__hardlinks_to_create; struct hardlinks_t *cpio__created_hardlinks; #endif @@ -159,6 +160,8 @@ struct BUG_tar_header { }; +extern const char cpio_TRAILER[]; + archive_handle_t *init_handle(void) FAST_FUNC; From d34f300db6d7a726759f4d820a61f19eacf11288 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Sun, 18 Oct 2015 18:42:03 +0200 Subject: [PATCH 017/260] sysklogd/*: convert to new-style "one file" applets Signed-off-by: Denys Vlasenko --- include/applets.src.h | 4 -- sysklogd/Config.src | 159 ------------------------------------------ sysklogd/Kbuild.src | 4 -- sysklogd/klogd.c | 33 +++++++++ sysklogd/logger.c | 13 ++++ sysklogd/logread.c | 25 +++++++ sysklogd/syslogd.c | 101 +++++++++++++++++++++++++++ 7 files changed, 172 insertions(+), 167 deletions(-) diff --git a/include/applets.src.h b/include/applets.src.h index dac83e7fb..c1b8017d4 100644 --- a/include/applets.src.h +++ b/include/applets.src.h @@ -201,7 +201,6 @@ IF_KBD_MODE(APPLET(kbd_mode, BB_DIR_BIN, BB_SUID_DROP)) IF_KILL(APPLET(kill, BB_DIR_BIN, BB_SUID_DROP)) IF_KILLALL(APPLET_ODDNAME(killall, kill, BB_DIR_USR_BIN, BB_SUID_DROP, killall)) IF_KILLALL5(APPLET_ODDNAME(killall5, kill, BB_DIR_USR_SBIN, BB_SUID_DROP, killall5)) -IF_KLOGD(APPLET(klogd, BB_DIR_SBIN, BB_SUID_DROP)) IF_LAST(APPLET(last, BB_DIR_USR_BIN, BB_SUID_DROP)) //IF_LENGTH(APPLET_NOFORK(length, length, BB_DIR_USR_BIN, BB_SUID_DROP, length)) IF_LESS(APPLET(less, BB_DIR_USR_BIN, BB_SUID_DROP)) @@ -211,11 +210,9 @@ IF_LN(APPLET_NOEXEC(ln, ln, BB_DIR_BIN, BB_SUID_DROP, ln)) IF_LOAD_POLICY(APPLET(load_policy, BB_DIR_USR_SBIN, BB_SUID_DROP)) IF_LOADFONT(APPLET(loadfont, BB_DIR_USR_SBIN, BB_SUID_DROP)) IF_LOADKMAP(APPLET(loadkmap, BB_DIR_SBIN, BB_SUID_DROP)) -IF_LOGGER(APPLET(logger, BB_DIR_USR_BIN, BB_SUID_DROP)) /* Needs to be run by root or be suid root - needs to change uid and gid: */ IF_LOGIN(APPLET(login, BB_DIR_BIN, BB_SUID_REQUIRE)) IF_LOGNAME(APPLET_NOFORK(logname, logname, BB_DIR_USR_BIN, BB_SUID_DROP, logname)) -IF_LOGREAD(APPLET(logread, BB_DIR_SBIN, BB_SUID_DROP)) IF_LOSETUP(APPLET(losetup, BB_DIR_SBIN, BB_SUID_DROP)) IF_LPD(APPLET(lpd, BB_DIR_USR_SBIN, BB_SUID_DROP)) IF_LPQ(APPLET_ODDNAME(lpq, lpqr, BB_DIR_USR_BIN, BB_SUID_DROP, lpq)) @@ -338,7 +335,6 @@ IF_SWAPONOFF(APPLET_ODDNAME(swapoff, swap_on_off, BB_DIR_SBIN, BB_SUID_DROP, swa IF_SWAPONOFF(APPLET_ODDNAME(swapon, swap_on_off, BB_DIR_SBIN, BB_SUID_DROP, swapon)) IF_SWITCH_ROOT(APPLET(switch_root, BB_DIR_SBIN, BB_SUID_DROP)) IF_BB_SYSCTL(APPLET(sysctl, BB_DIR_SBIN, BB_SUID_DROP)) -IF_SYSLOGD(APPLET(syslogd, BB_DIR_SBIN, BB_SUID_DROP)) IF_TAC(APPLET_NOEXEC(tac, tac, BB_DIR_USR_BIN, BB_SUID_DROP, tac)) IF_TAIL(APPLET(tail, BB_DIR_USR_BIN, BB_SUID_DROP)) /* IF_TC(APPLET(tc, BB_DIR_SBIN, BB_SUID_DROP)) */ diff --git a/sysklogd/Config.src b/sysklogd/Config.src index fcf993054..684e7d414 100644 --- a/sysklogd/Config.src +++ b/sysklogd/Config.src @@ -7,163 +7,4 @@ menu "System Logging Utilities" INSERT -config SYSLOGD - bool "syslogd" - default y - help - The syslogd utility is used to record logs of all the - significant events that occur on a system. Every - message that is logged records the date and time of the - event, and will generally also record the name of the - application that generated the message. When used in - conjunction with klogd, messages from the Linux kernel - can also be recorded. This is terribly useful, - especially for finding what happened when something goes - wrong. And something almost always will go wrong if - you wait long enough.... - -config FEATURE_ROTATE_LOGFILE - bool "Rotate message files" - default y - depends on SYSLOGD - help - This enables syslogd to rotate the message files - on his own. No need to use an external rotatescript. - -config FEATURE_REMOTE_LOG - bool "Remote Log support" - default y - depends on SYSLOGD - help - When you enable this feature, the syslogd utility can - be used to send system log messages to another system - connected via a network. This allows the remote - machine to log all the system messages, which can be - terribly useful for reducing the number of serial - cables you use. It can also be a very good security - measure to prevent system logs from being tampered with - by an intruder. - -config FEATURE_SYSLOGD_DUP - bool "Support -D (drop dups) option" - default y - depends on SYSLOGD - help - Option -D instructs syslogd to drop consecutive messages - which are totally the same. - -config FEATURE_SYSLOGD_CFG - bool "Support syslog.conf" - default y - depends on SYSLOGD - help - Supports restricted syslogd config. See docs/syslog.conf.txt - -config FEATURE_SYSLOGD_READ_BUFFER_SIZE - int "Read buffer size in bytes" - default 256 - range 256 20000 - depends on SYSLOGD - help - This option sets the size of the syslog read buffer. - Actual memory usage increases around five times the - change done here. - -config FEATURE_IPC_SYSLOG - bool "Circular Buffer support" - default y - depends on SYSLOGD - help - When you enable this feature, the syslogd utility will - use a circular buffer to record system log messages. - When the buffer is filled it will continue to overwrite - the oldest messages. This can be very useful for - systems with little or no permanent storage, since - otherwise system logs can eventually fill up your - entire filesystem, which may cause your system to - break badly. - -config FEATURE_IPC_SYSLOG_BUFFER_SIZE - int "Circular buffer size in Kbytes (minimum 4KB)" - default 16 - range 4 2147483647 - depends on FEATURE_IPC_SYSLOG - help - This option sets the size of the circular buffer - used to record system log messages. - -config LOGREAD - bool "logread" - default y - depends on FEATURE_IPC_SYSLOG - help - If you enabled Circular Buffer support, you almost - certainly want to enable this feature as well. This - utility will allow you to read the messages that are - stored in the syslogd circular buffer. - -config FEATURE_LOGREAD_REDUCED_LOCKING - bool "Double buffering" - default y - depends on LOGREAD - help - 'logread' ouput to slow serial terminals can have - side effects on syslog because of the semaphore. - This option make logread to double buffer copy - from circular buffer, minimizing semaphore - contention at some minor memory expense. - -config FEATURE_KMSG_SYSLOG - bool "Linux kernel printk buffer support" - default y - depends on SYSLOGD - select PLATFORM_LINUX - help - When you enable this feature, the syslogd utility will - write system log message to the Linux kernel's printk buffer. - This can be used as a smaller alternative to the syslogd IPC - support, as klogd and logread aren't needed. - - NOTICE: Syslog facilities in log entries needs kernel 3.5+. - -config KLOGD - bool "klogd" - default y - help - klogd is a utility which intercepts and logs all - messages from the Linux kernel and sends the messages - out to the 'syslogd' utility so they can be logged. If - you wish to record the messages produced by the kernel, - you should enable this option. - -comment "klogd should not be used together with syslog to kernel printk buffer" - depends on KLOGD && FEATURE_KMSG_SYSLOG - -config FEATURE_KLOGD_KLOGCTL - bool "Use the klogctl() interface" - default y - depends on KLOGD - select PLATFORM_LINUX - help - The klogd applet supports two interfaces for reading - kernel messages. Linux provides the klogctl() interface - which allows reading messages from the kernel ring buffer - independently from the file system. - - If you answer 'N' here, klogd will use the more portable - approach of reading them from /proc or a device node. - However, this method requires the file to be available. - - If in doubt, say 'Y'. - -config LOGGER - bool "logger" - default y - select FEATURE_SYSLOG - help - The logger utility allows you to send arbitrary text - messages to the system log (i.e. the 'syslogd' utility) so - they can be logged. This is generally used to help locate - problems that occur within programs and scripts. - endmenu diff --git a/sysklogd/Kbuild.src b/sysklogd/Kbuild.src index d386cc291..6b4fb7470 100644 --- a/sysklogd/Kbuild.src +++ b/sysklogd/Kbuild.src @@ -7,7 +7,3 @@ lib-y:= INSERT -lib-$(CONFIG_KLOGD) += klogd.o -lib-$(CONFIG_LOGGER) += syslogd_and_logger.o -lib-$(CONFIG_LOGREAD) += logread.o -lib-$(CONFIG_SYSLOGD) += syslogd_and_logger.o diff --git a/sysklogd/klogd.c b/sysklogd/klogd.c index 432ded153..ca8b848bd 100644 --- a/sysklogd/klogd.c +++ b/sysklogd/klogd.c @@ -16,6 +16,39 @@ * * Licensed under GPLv2 or later, see file LICENSE in this source tree. */ +//config:config KLOGD +//config: bool "klogd" +//config: default y +//config: help +//config: klogd is a utility which intercepts and logs all +//config: messages from the Linux kernel and sends the messages +//config: out to the 'syslogd' utility so they can be logged. If +//config: you wish to record the messages produced by the kernel, +//config: you should enable this option. +//config: +//config:comment "klogd should not be used together with syslog to kernel printk buffer" +//config: depends on KLOGD && FEATURE_KMSG_SYSLOG +//config: +//config:config FEATURE_KLOGD_KLOGCTL +//config: bool "Use the klogctl() interface" +//config: default y +//config: depends on KLOGD +//config: select PLATFORM_LINUX +//config: help +//config: The klogd applet supports two interfaces for reading +//config: kernel messages. Linux provides the klogctl() interface +//config: which allows reading messages from the kernel ring buffer +//config: independently from the file system. +//config: +//config: If you answer 'N' here, klogd will use the more portable +//config: approach of reading them from /proc or a device node. +//config: However, this method requires the file to be available. +//config: +//config: If in doubt, say 'Y'. + +//applet:IF_KLOGD(APPLET(klogd, BB_DIR_SBIN, BB_SUID_DROP)) + +//kbuild:lib-$(CONFIG_KLOGD) += klogd.o //usage:#define klogd_trivial_usage //usage: "[-c N] [-n]" diff --git a/sysklogd/logger.c b/sysklogd/logger.c index 5a7027731..b3ca85703 100644 --- a/sysklogd/logger.c +++ b/sysklogd/logger.c @@ -6,6 +6,19 @@ * * Licensed under GPLv2 or later, see file LICENSE in this source tree. */ +//config:config LOGGER +//config: bool "logger" +//config: default y +//config: select FEATURE_SYSLOG +//config: help +//config: The logger utility allows you to send arbitrary text +//config: messages to the system log (i.e. the 'syslogd' utility) so +//config: they can be logged. This is generally used to help locate +//config: problems that occur within programs and scripts. + +//applet:IF_LOGGER(APPLET(logger, BB_DIR_USR_BIN, BB_SUID_DROP)) + +//kbuild:lib-$(CONFIG_LOGGER) += syslogd_and_logger.o //usage:#define logger_trivial_usage //usage: "[OPTIONS] [MESSAGE]" diff --git a/sysklogd/logread.c b/sysklogd/logread.c index da4a4d4df..781a603b2 100644 --- a/sysklogd/logread.c +++ b/sysklogd/logread.c @@ -8,6 +8,31 @@ * * Licensed under GPLv2 or later, see file LICENSE in this source tree. */ +//config:config LOGREAD +//config: bool "logread" +//config: default y +//config: depends on FEATURE_IPC_SYSLOG +//config: help +//config: If you enabled Circular Buffer support, you almost +//config: certainly want to enable this feature as well. This +//config: utility will allow you to read the messages that are +//config: stored in the syslogd circular buffer. +//config: +//config:config FEATURE_LOGREAD_REDUCED_LOCKING +//config: bool "Double buffering" +//config: default y +//config: depends on LOGREAD +//config: help +//config: 'logread' ouput to slow serial terminals can have +//config: side effects on syslog because of the semaphore. +//config: This option make logread to double buffer copy +//config: from circular buffer, minimizing semaphore +//config: contention at some minor memory expense. +//config: + +//applet:IF_LOGREAD(APPLET(logread, BB_DIR_SBIN, BB_SUID_DROP)) + +//kbuild:lib-$(CONFIG_LOGREAD) += logread.o //usage:#define logread_trivial_usage //usage: "[-fF]" diff --git a/sysklogd/syslogd.c b/sysklogd/syslogd.c index 156f487e5..288b29cf7 100644 --- a/sysklogd/syslogd.c +++ b/sysklogd/syslogd.c @@ -12,6 +12,107 @@ * * Licensed under GPLv2 or later, see file LICENSE in this source tree. */ +//config:config SYSLOGD +//config: bool "syslogd" +//config: default y +//config: help +//config: The syslogd utility is used to record logs of all the +//config: significant events that occur on a system. Every +//config: message that is logged records the date and time of the +//config: event, and will generally also record the name of the +//config: application that generated the message. When used in +//config: conjunction with klogd, messages from the Linux kernel +//config: can also be recorded. This is terribly useful, +//config: especially for finding what happened when something goes +//config: wrong. And something almost always will go wrong if +//config: you wait long enough.... +//config: +//config:config FEATURE_ROTATE_LOGFILE +//config: bool "Rotate message files" +//config: default y +//config: depends on SYSLOGD +//config: help +//config: This enables syslogd to rotate the message files +//config: on his own. No need to use an external rotatescript. +//config: +//config:config FEATURE_REMOTE_LOG +//config: bool "Remote Log support" +//config: default y +//config: depends on SYSLOGD +//config: help +//config: When you enable this feature, the syslogd utility can +//config: be used to send system log messages to another system +//config: connected via a network. This allows the remote +//config: machine to log all the system messages, which can be +//config: terribly useful for reducing the number of serial +//config: cables you use. It can also be a very good security +//config: measure to prevent system logs from being tampered with +//config: by an intruder. +//config: +//config:config FEATURE_SYSLOGD_DUP +//config: bool "Support -D (drop dups) option" +//config: default y +//config: depends on SYSLOGD +//config: help +//config: Option -D instructs syslogd to drop consecutive messages +//config: which are totally the same. +//config: +//config:config FEATURE_SYSLOGD_CFG +//config: bool "Support syslog.conf" +//config: default y +//config: depends on SYSLOGD +//config: help +//config: Supports restricted syslogd config. See docs/syslog.conf.txt +//config: +//config:config FEATURE_SYSLOGD_READ_BUFFER_SIZE +//config: int "Read buffer size in bytes" +//config: default 256 +//config: range 256 20000 +//config: depends on SYSLOGD +//config: help +//config: This option sets the size of the syslog read buffer. +//config: Actual memory usage increases around five times the +//config: change done here. +//config: +//config:config FEATURE_IPC_SYSLOG +//config: bool "Circular Buffer support" +//config: default y +//config: depends on SYSLOGD +//config: help +//config: When you enable this feature, the syslogd utility will +//config: use a circular buffer to record system log messages. +//config: When the buffer is filled it will continue to overwrite +//config: the oldest messages. This can be very useful for +//config: systems with little or no permanent storage, since +//config: otherwise system logs can eventually fill up your +//config: entire filesystem, which may cause your system to +//config: break badly. +//config: +//config:config FEATURE_IPC_SYSLOG_BUFFER_SIZE +//config: int "Circular buffer size in Kbytes (minimum 4KB)" +//config: default 16 +//config: range 4 2147483647 +//config: depends on FEATURE_IPC_SYSLOG +//config: help +//config: This option sets the size of the circular buffer +//config: used to record system log messages. +//config: +//config:config FEATURE_KMSG_SYSLOG +//config: bool "Linux kernel printk buffer support" +//config: default y +//config: depends on SYSLOGD +//config: select PLATFORM_LINUX +//config: help +//config: When you enable this feature, the syslogd utility will +//config: write system log message to the Linux kernel's printk buffer. +//config: This can be used as a smaller alternative to the syslogd IPC +//config: support, as klogd and logread aren't needed. +//config: +//config: NOTICE: Syslog facilities in log entries needs kernel 3.5+. + +//applet:IF_SYSLOGD(APPLET(syslogd, BB_DIR_SBIN, BB_SUID_DROP)) + +//kbuild:lib-$(CONFIG_SYSLOGD) += syslogd_and_logger.o //usage:#define syslogd_trivial_usage //usage: "[OPTIONS]" From 000eda41c084bae95d9e40a570cbdaa5ffd3d22e Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Sun, 18 Oct 2015 22:40:23 +0200 Subject: [PATCH 018/260] e2fsprogs/*: convert to new-style "one file" applets Signed-off-by: Denys Vlasenko --- e2fsprogs/Config.src | 28 ---------------------------- e2fsprogs/Kbuild.src | 6 ------ e2fsprogs/chattr.c | 16 ++++++++-------- e2fsprogs/fsck.c | 11 +++++++++++ e2fsprogs/lsattr.c | 16 +++++++++------- e2fsprogs/tune2fs.c | 43 +++++++++++++++++++++++++++---------------- include/applets.src.h | 4 ---- 7 files changed, 55 insertions(+), 69 deletions(-) diff --git a/e2fsprogs/Config.src b/e2fsprogs/Config.src index 743e1e11f..a20d849e6 100644 --- a/e2fsprogs/Config.src +++ b/e2fsprogs/Config.src @@ -7,12 +7,6 @@ menu "Linux Ext2 FS Progs" INSERT -config CHATTR - bool "chattr" - default y - help - chattr changes the file attributes on a second extended file system. - ### config E2FSCK ### bool "e2fsck" ### default y @@ -22,21 +16,6 @@ config CHATTR ### The normal compat symlinks 'fsck.ext2' and 'fsck.ext3' are also ### provided. -config FSCK - bool "fsck" - default y - help - fsck is used to check and optionally repair one or more filesystems. - In actuality, fsck is simply a front-end for the various file system - checkers (fsck.fstype) available under Linux. - -config LSATTR - bool "lsattr" - default y - select PLATFORM_LINUX - help - lsattr lists the file attributes on a second extended file system. - ### config MKE2FS ### bool "mke2fs" ### default y @@ -44,13 +23,6 @@ config LSATTR ### mke2fs is used to create an ext2/ext3 filesystem. The normal compat ### symlinks 'mkfs.ext2' and 'mkfs.ext3' are also provided. -config TUNE2FS - bool "tune2fs" - default n # off: it is too limited compared to upstream version - help - tune2fs allows the system administrator to adjust various tunable - filesystem parameters on Linux ext2/ext3 filesystems. - ### config E2LABEL ### bool "e2label" ### default y diff --git a/e2fsprogs/Kbuild.src b/e2fsprogs/Kbuild.src index b7a14c381..6b4fb7470 100644 --- a/e2fsprogs/Kbuild.src +++ b/e2fsprogs/Kbuild.src @@ -7,9 +7,3 @@ lib-y:= INSERT - -lib-$(CONFIG_CHATTR) += chattr.o e2fs_lib.o -lib-$(CONFIG_LSATTR) += lsattr.o e2fs_lib.o - -lib-$(CONFIG_FSCK) += fsck.o -lib-$(CONFIG_TUNE2FS) += tune2fs.o diff --git a/e2fsprogs/chattr.c b/e2fsprogs/chattr.c index f1cc8389f..c4e2415f8 100644 --- a/e2fsprogs/chattr.c +++ b/e2fsprogs/chattr.c @@ -9,15 +9,15 @@ * This file can be redistributed under the terms of the GNU General * Public License */ +//config:config CHATTR +//config: bool "chattr" +//config: default y +//config: help +//config: chattr changes the file attributes on a second extended file system. -/* - * History: - * 93/10/30 - Creation - * 93/11/13 - Replace stat() calls by lstat() to avoid loops - * 94/02/27 - Integrated in Ted's distribution - * 98/12/29 - Ignore symlinks when working recursively (G M Sipe) - * 98/12/29 - Display version info only when -V specified (G M Sipe) - */ +//applet:IF_CHATTR(APPLET(chattr, BB_DIR_BIN, BB_SUID_DROP)) + +//kbuild:lib-$(CONFIG_CHATTR) += chattr.o e2fs_lib.o //usage:#define chattr_trivial_usage //usage: "[-R] [-+=AacDdijsStTu] [-v VERSION] [FILE]..." diff --git a/e2fsprogs/fsck.c b/e2fsprogs/fsck.c index d2d312e5c..adaf0c538 100644 --- a/e2fsprogs/fsck.c +++ b/e2fsprogs/fsck.c @@ -33,6 +33,17 @@ * spawns actual fsck.something for each filesystem to check. * It doesn't guess filesystem types from on-disk format. */ +//config:config FSCK +//config: bool "fsck" +//config: default y +//config: help +//config: fsck is used to check and optionally repair one or more filesystems. +//config: In actuality, fsck is simply a front-end for the various file system +//config: checkers (fsck.fstype) available under Linux. + +//applet:IF_FSCK(APPLET(fsck, BB_DIR_SBIN, BB_SUID_DROP)) + +//kbuild:lib-$(CONFIG_FSCK) += fsck.o //usage:#define fsck_trivial_usage //usage: "[-ANPRTV] [-C FD] [-t FSTYPE] [FS_OPTS] [BLOCKDEV]..." diff --git a/e2fsprogs/lsattr.c b/e2fsprogs/lsattr.c index 1312fe754..3a7dd6b56 100644 --- a/e2fsprogs/lsattr.c +++ b/e2fsprogs/lsattr.c @@ -9,14 +9,16 @@ * This file can be redistributed under the terms of the GNU General * Public License */ +//config:config LSATTR +//config: bool "lsattr" +//config: default y +//config: select PLATFORM_LINUX +//config: help +//config: lsattr lists the file attributes on a second extended file system. -/* - * History: - * 93/10/30 - Creation - * 93/11/13 - Replace stat() calls by lstat() to avoid loops - * 94/02/27 - Integrated in Ted's distribution - * 98/12/29 - Display version info only when -V specified (G M Sipe) - */ +//applet:IF_LSATTR(APPLET(lsattr, BB_DIR_BIN, BB_SUID_DROP)) + +//kbuild:lib-$(CONFIG_LSATTR) += lsattr.o e2fs_lib.o //usage:#define lsattr_trivial_usage //usage: "[-Radlv] [FILE]..." diff --git a/e2fsprogs/tune2fs.c b/e2fsprogs/tune2fs.c index 46a745ee4..c9f88b39d 100644 --- a/e2fsprogs/tune2fs.c +++ b/e2fsprogs/tune2fs.c @@ -6,6 +6,33 @@ * * Licensed under GPLv2, see file LICENSE in this source tree. */ +//config:config TUNE2FS +//config: bool "tune2fs" +//config: default n # off: it is too limited compared to upstream version +//config: help +//config: tune2fs allows the system administrator to adjust various tunable +//config: filesystem parameters on Linux ext2/ext3 filesystems. + +//applet:IF_TUNE2FS(APPLET(tune2fs, BB_DIR_SBIN, BB_SUID_DROP)) + +//kbuild:lib-$(CONFIG_TUNE2FS) += tune2fs.o + +//usage:#define tune2fs_trivial_usage +//usage: "[-c MAX_MOUNT_COUNT] " +////usage: "[-e errors-behavior] [-g group] " +//usage: "[-i DAYS] " +////usage: "[-j] [-J journal-options] [-l] [-s sparse-flag] " +////usage: "[-m reserved-blocks-percent] [-o [^]mount-options[,...]] " +////usage: "[-r reserved-blocks-count] [-u user] " +//usage: "[-C MOUNT_COUNT] " +//usage: "[-L LABEL] " +////usage: "[-M last-mounted-dir] [-O [^]feature[,...]] " +////usage: "[-T last-check-time] [-U UUID] " +//usage: "BLOCKDEV" +//usage: +//usage:#define tune2fs_full_usage "\n\n" +//usage: "Adjust filesystem options on ext[23] filesystems" + #include "libbb.h" #include #include "bb_e2fs_defs.h" @@ -27,22 +54,6 @@ do { \ #define FETCH_LE32(field) \ (sizeof(field) == 4 ? SWAP_LE32(field) : BUG_wrong_field_size()) -//usage:#define tune2fs_trivial_usage -//usage: "[-c MAX_MOUNT_COUNT] " -////usage: "[-e errors-behavior] [-g group] " -//usage: "[-i DAYS] " -////usage: "[-j] [-J journal-options] [-l] [-s sparse-flag] " -////usage: "[-m reserved-blocks-percent] [-o [^]mount-options[,...]] " -////usage: "[-r reserved-blocks-count] [-u user] " -//usage: "[-C MOUNT_COUNT] " -//usage: "[-L LABEL] " -////usage: "[-M last-mounted-dir] [-O [^]feature[,...]] " -////usage: "[-T last-check-time] [-U UUID] " -//usage: "BLOCKDEV" -//usage: -//usage:#define tune2fs_full_usage "\n\n" -//usage: "Adjust filesystem options on ext[23] filesystems" - enum { OPT_L = 1 << 0, // label OPT_c = 1 << 1, // max mount count diff --git a/include/applets.src.h b/include/applets.src.h index c1b8017d4..c1ed0e82f 100644 --- a/include/applets.src.h +++ b/include/applets.src.h @@ -90,7 +90,6 @@ IF_CAL(APPLET(cal, BB_DIR_USR_BIN, BB_SUID_DROP)) IF_CAT(APPLET_NOFORK(cat, cat, BB_DIR_BIN, BB_SUID_DROP, cat)) IF_CATV(APPLET(catv, BB_DIR_BIN, BB_SUID_DROP)) IF_CHAT(APPLET(chat, BB_DIR_USR_SBIN, BB_SUID_DROP)) -IF_CHATTR(APPLET(chattr, BB_DIR_BIN, BB_SUID_DROP)) IF_CHCON(APPLET(chcon, BB_DIR_USR_BIN, BB_SUID_DROP)) IF_CHGRP(APPLET_NOEXEC(chgrp, chgrp, BB_DIR_BIN, BB_SUID_DROP, chgrp)) IF_CHMOD(APPLET_NOEXEC(chmod, chmod, BB_DIR_BIN, BB_SUID_DROP, chmod)) @@ -153,7 +152,6 @@ IF_FLOCK(APPLET(flock, BB_DIR_USR_BIN, BB_SUID_DROP)) IF_FOLD(APPLET_NOEXEC(fold, fold, BB_DIR_USR_BIN, BB_SUID_DROP, fold)) IF_FREE(APPLET(free, BB_DIR_USR_BIN, BB_SUID_DROP)) IF_FREERAMDISK(APPLET(freeramdisk, BB_DIR_SBIN, BB_SUID_DROP)) -IF_FSCK(APPLET(fsck, BB_DIR_SBIN, BB_SUID_DROP)) //IF_E2FSCK(APPLET_ODDNAME(fsck.ext2, e2fsck, BB_DIR_SBIN, BB_SUID_DROP, fsck_ext2)) //IF_E2FSCK(APPLET_ODDNAME(fsck.ext3, e2fsck, BB_DIR_SBIN, BB_SUID_DROP, fsck_ext3)) IF_FSCK_MINIX(APPLET_ODDNAME(fsck.minix, fsck_minix, BB_DIR_SBIN, BB_SUID_DROP, fsck_minix)) @@ -218,7 +216,6 @@ IF_LPD(APPLET(lpd, BB_DIR_USR_SBIN, BB_SUID_DROP)) IF_LPQ(APPLET_ODDNAME(lpq, lpqr, BB_DIR_USR_BIN, BB_SUID_DROP, lpq)) IF_LPR(APPLET_ODDNAME(lpr, lpqr, BB_DIR_USR_BIN, BB_SUID_DROP, lpr)) IF_LS(APPLET_NOEXEC(ls, ls, BB_DIR_BIN, BB_SUID_DROP, ls)) -IF_LSATTR(APPLET(lsattr, BB_DIR_BIN, BB_SUID_DROP)) IF_LSPCI(APPLET(lspci, BB_DIR_USR_BIN, BB_SUID_DROP)) IF_LSUSB(APPLET(lsusb, BB_DIR_USR_BIN, BB_SUID_DROP)) IF_MAKEDEVS(APPLET(makedevs, BB_DIR_SBIN, BB_SUID_DROP)) @@ -358,7 +355,6 @@ IF_TRUE(APPLET_NOFORK(true, true, BB_DIR_BIN, BB_SUID_DROP, true)) IF_TTY(APPLET(tty, BB_DIR_USR_BIN, BB_SUID_DROP)) IF_TTYSIZE(APPLET(ttysize, BB_DIR_USR_BIN, BB_SUID_DROP)) IF_TUNCTL(APPLET(tunctl, BB_DIR_SBIN, BB_SUID_DROP)) -IF_TUNE2FS(APPLET(tune2fs, BB_DIR_SBIN, BB_SUID_DROP)) IF_UDHCPC(APPLET(udhcpc, BB_DIR_SBIN, BB_SUID_DROP)) IF_UDHCPD(APPLET(udhcpd, BB_DIR_USR_SBIN, BB_SUID_DROP)) IF_UDPSVD(APPLET_ODDNAME(udpsvd, tcpudpsvd, BB_DIR_USR_BIN, BB_SUID_DROP, udpsvd)) From 0863e1a576c4b26bb87564b3a403f1094814f1aa Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Mon, 19 Oct 2015 00:41:28 +0200 Subject: [PATCH 019/260] runit/*: convert to new-style "one file" applets Signed-off-by: Denys Vlasenko --- include/applets.src.h | 9 ----- runit/Config.src | 79 ------------------------------------------- runit/Kbuild.src | 11 ------ runit/chpst.c | 45 +++++++++++++++++++++++- runit/runsv.c | 12 ++++++- runit/runsvdir.c | 22 +++++++++++- runit/sv.c | 20 ++++++++++- runit/svlogd.c | 13 ++++++- 8 files changed, 107 insertions(+), 104 deletions(-) diff --git a/include/applets.src.h b/include/applets.src.h index c1ed0e82f..d243d89e1 100644 --- a/include/applets.src.h +++ b/include/applets.src.h @@ -95,7 +95,6 @@ IF_CHGRP(APPLET_NOEXEC(chgrp, chgrp, BB_DIR_BIN, BB_SUID_DROP, chgrp)) IF_CHMOD(APPLET_NOEXEC(chmod, chmod, BB_DIR_BIN, BB_SUID_DROP, chmod)) IF_CHOWN(APPLET_NOEXEC(chown, chown, BB_DIR_BIN, BB_SUID_DROP, chown)) IF_CHPASSWD(APPLET(chpasswd, BB_DIR_USR_SBIN, BB_SUID_DROP)) -IF_CHPST(APPLET(chpst, BB_DIR_USR_BIN, BB_SUID_DROP)) IF_CHROOT(APPLET(chroot, BB_DIR_USR_SBIN, BB_SUID_DROP)) IF_CHRT(APPLET(chrt, BB_DIR_USR_BIN, BB_SUID_DROP)) IF_CHVT(APPLET(chvt, BB_DIR_USR_BIN, BB_SUID_DROP)) @@ -129,8 +128,6 @@ IF_DUMPLEASES(APPLET(dumpleases, BB_DIR_USR_BIN, BB_SUID_DROP)) IF_ECHO(APPLET_NOFORK(echo, echo, BB_DIR_BIN, BB_SUID_DROP, echo)) IF_EJECT(APPLET(eject, BB_DIR_USR_BIN, BB_SUID_DROP)) IF_ENV(APPLET_NOEXEC(env, env, BB_DIR_USR_BIN, BB_SUID_DROP, env)) -IF_ENVDIR(APPLET_ODDNAME(envdir, chpst, BB_DIR_USR_BIN, BB_SUID_DROP, envdir)) -IF_ENVUIDGID(APPLET_ODDNAME(envuidgid, chpst, BB_DIR_USR_BIN, BB_SUID_DROP, envuidgid)) IF_ETHER_WAKE(APPLET_ODDNAME(ether-wake, ether_wake, BB_DIR_USR_SBIN, BB_SUID_DROP, ether_wake)) IF_EXPAND(APPLET(expand, BB_DIR_USR_BIN, BB_SUID_DROP)) IF_EXPR(APPLET(expr, BB_DIR_USR_BIN, BB_SUID_DROP)) @@ -288,8 +285,6 @@ IF_RTCWAKE(APPLET(rtcwake, BB_DIR_USR_SBIN, BB_SUID_DROP)) IF_RUN_PARTS(APPLET_ODDNAME(run-parts, run_parts, BB_DIR_BIN, BB_SUID_DROP, run_parts)) IF_RUNCON(APPLET(runcon, BB_DIR_USR_BIN, BB_SUID_DROP)) IF_RUNLEVEL(APPLET(runlevel, BB_DIR_SBIN, BB_SUID_DROP)) -IF_RUNSV(APPLET(runsv, BB_DIR_USR_BIN, BB_SUID_DROP)) -IF_RUNSVDIR(APPLET(runsvdir, BB_DIR_USR_BIN, BB_SUID_DROP)) IF_RX(APPLET(rx, BB_DIR_USR_BIN, BB_SUID_DROP)) IF_SCRIPT(APPLET(script, BB_DIR_USR_BIN, BB_SUID_DROP)) IF_SCRIPTREPLAY(APPLET(scriptreplay, BB_DIR_BIN, BB_SUID_DROP)) @@ -306,7 +301,6 @@ IF_SETKEYCODES(APPLET(setkeycodes, BB_DIR_USR_BIN, BB_SUID_DROP)) IF_SETLOGCONS(APPLET(setlogcons, BB_DIR_USR_SBIN, BB_SUID_DROP)) IF_SETSEBOOL(APPLET(setsebool, BB_DIR_USR_SBIN, BB_SUID_DROP)) IF_SETSID(APPLET(setsid, BB_DIR_USR_BIN, BB_SUID_DROP)) -IF_SETUIDGID(APPLET_ODDNAME(setuidgid, chpst, BB_DIR_USR_BIN, BB_SUID_DROP, setuidgid)) IF_SHA1SUM(APPLET_NOEXEC(sha1sum, md5_sha1_sum, BB_DIR_USR_BIN, BB_SUID_DROP, sha1sum)) IF_SHA3SUM(APPLET_NOEXEC(sha3sum, md5_sha1_sum, BB_DIR_USR_BIN, BB_SUID_DROP, sha3sum)) IF_SHA256SUM(APPLET_NOEXEC(sha256sum, md5_sha1_sum, BB_DIR_USR_BIN, BB_SUID_DROP, sha256sum)) @@ -315,7 +309,6 @@ IF_SHOWKEY(APPLET(showkey, BB_DIR_USR_BIN, BB_SUID_DROP)) IF_SLATTACH(APPLET(slattach, BB_DIR_SBIN, BB_SUID_DROP)) /* Do not make this applet NOFORK. It breaks ^C-ing of pauses in shells: */ IF_SLEEP(APPLET(sleep, BB_DIR_BIN, BB_SUID_DROP)) -IF_SOFTLIMIT(APPLET_ODDNAME(softlimit, chpst, BB_DIR_USR_BIN, BB_SUID_DROP, softlimit)) IF_SORT(APPLET_NOEXEC(sort, sort, BB_DIR_USR_BIN, BB_SUID_DROP, sort)) IF_SPLIT(APPLET(split, BB_DIR_USR_BIN, BB_SUID_DROP)) IF_START_STOP_DAEMON(APPLET_ODDNAME(start-stop-daemon, start_stop_daemon, BB_DIR_SBIN, BB_SUID_DROP, start_stop_daemon)) @@ -326,8 +319,6 @@ IF_STTY(APPLET(stty, BB_DIR_BIN, BB_SUID_DROP)) IF_SU(APPLET(su, BB_DIR_BIN, BB_SUID_REQUIRE)) IF_SULOGIN(APPLET(sulogin, BB_DIR_SBIN, BB_SUID_DROP)) IF_SUM(APPLET(sum, BB_DIR_USR_BIN, BB_SUID_DROP)) -IF_SV(APPLET(sv, BB_DIR_USR_BIN, BB_SUID_DROP)) -IF_SVLOGD(APPLET(svlogd, BB_DIR_USR_SBIN, BB_SUID_DROP)) IF_SWAPONOFF(APPLET_ODDNAME(swapoff, swap_on_off, BB_DIR_SBIN, BB_SUID_DROP, swapoff)) IF_SWAPONOFF(APPLET_ODDNAME(swapon, swap_on_off, BB_DIR_SBIN, BB_SUID_DROP, swapon)) IF_SWITCH_ROOT(APPLET(switch_root, BB_DIR_SBIN, BB_SUID_DROP)) diff --git a/runit/Config.src b/runit/Config.src index 9db974002..8cde89680 100644 --- a/runit/Config.src +++ b/runit/Config.src @@ -7,83 +7,4 @@ menu "Runit Utilities" INSERT -config RUNSV - bool "runsv" - default y - help - runsv starts and monitors a service and optionally an appendant log - service. - -config RUNSVDIR - bool "runsvdir" - default y - help - runsvdir starts a runsv process for each subdirectory, or symlink to - a directory, in the services directory dir, up to a limit of 1000 - subdirectories, and restarts a runsv process if it terminates. - -config FEATURE_RUNSVDIR_LOG - bool "Enable scrolling argument log" - depends on RUNSVDIR - default n - help - Enable feature where second parameter of runsvdir holds last error - message (viewable via top/ps). Otherwise (feature is off - or no parameter), error messages go to stderr only. - -config SV - bool "sv" - default y - help - sv reports the current status and controls the state of services - monitored by the runsv supervisor. - -config SV_DEFAULT_SERVICE_DIR - string "Default directory for services" - default "/var/service" - depends on SV - help - Default directory for services. - Defaults to "/var/service" - -config SVLOGD - bool "svlogd" - default y - help - svlogd continuously reads log data from its standard input, optionally - filters log messages, and writes the data to one or more automatically - rotated logs. - -config CHPST - bool "chpst" - default y - help - chpst changes the process state according to the given options, and - execs specified program. - -config SETUIDGID - bool "setuidgid" - default y - help - Sets soft resource limits as specified by options - -config ENVUIDGID - bool "envuidgid" - default y - help - Sets $UID to account's uid and $GID to account's gid - -config ENVDIR - bool "envdir" - default y - help - Sets various environment variables as specified by files - in the given directory - -config SOFTLIMIT - bool "softlimit" - default y - help - Sets soft resource limits as specified by options - endmenu diff --git a/runit/Kbuild.src b/runit/Kbuild.src index 0fce95507..6b4fb7470 100644 --- a/runit/Kbuild.src +++ b/runit/Kbuild.src @@ -7,14 +7,3 @@ lib-y:= INSERT - -lib-$(CONFIG_RUNSV) += runsv.o -lib-$(CONFIG_RUNSVDIR) += runsvdir.o -lib-$(CONFIG_SV) += sv.o -lib-$(CONFIG_SVLOGD) += svlogd.o -lib-$(CONFIG_CHPST) += chpst.o - -lib-$(CONFIG_ENVDIR) += chpst.o -lib-$(CONFIG_ENVUIDGID) += chpst.o -lib-$(CONFIG_SETUIDGID) += chpst.o -lib-$(CONFIG_SOFTLIMIT) += chpst.o diff --git a/runit/chpst.c b/runit/chpst.c index 71af29f66..301cdd08a 100644 --- a/runit/chpst.c +++ b/runit/chpst.c @@ -26,7 +26,50 @@ ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /* Busyboxed by Denys Vlasenko */ -/* Dependencies on runit_lib.c removed */ + +//config:config CHPST +//config: bool "chpst" +//config: default y +//config: help +//config: chpst changes the process state according to the given options, and +//config: execs specified program. +//config: +//config:config SETUIDGID +//config: bool "setuidgid" +//config: default y +//config: help +//config: Sets soft resource limits as specified by options +//config: +//config:config ENVUIDGID +//config: bool "envuidgid" +//config: default y +//config: help +//config: Sets $UID to account's uid and $GID to account's gid +//config: +//config:config ENVDIR +//config: bool "envdir" +//config: default y +//config: help +//config: Sets various environment variables as specified by files +//config: in the given directory +//config: +//config:config SOFTLIMIT +//config: bool "softlimit" +//config: default y +//config: help +//config: Sets soft resource limits as specified by options + +//applet:IF_CHPST(APPLET(chpst, BB_DIR_USR_BIN, BB_SUID_DROP)) +//applet:IF_ENVDIR(APPLET_ODDNAME(envdir, chpst, BB_DIR_USR_BIN, BB_SUID_DROP, envdir)) +//applet:IF_ENVUIDGID(APPLET_ODDNAME(envuidgid, chpst, BB_DIR_USR_BIN, BB_SUID_DROP, envuidgid)) +//applet:IF_SETUIDGID(APPLET_ODDNAME(setuidgid, chpst, BB_DIR_USR_BIN, BB_SUID_DROP, setuidgid)) +//applet:IF_SOFTLIMIT(APPLET_ODDNAME(softlimit, chpst, BB_DIR_USR_BIN, BB_SUID_DROP, softlimit)) + +//kbuild:lib-$(CONFIG_CHPST) += chpst.o +//kbuild:lib-$(CONFIG_ENVDIR) += chpst.o +//kbuild:lib-$(CONFIG_ENVUIDGID) += chpst.o +//kbuild:lib-$(CONFIG_SETUIDGID) += chpst.o +//kbuild:lib-$(CONFIG_SOFTLIMIT) += chpst.o //usage:#define chpst_trivial_usage //usage: "[-vP012] [-u USER[:GRP]] [-U USER[:GRP]] [-e DIR]\n" diff --git a/runit/runsv.c b/runit/runsv.c index 6cf5bcc29..4b18d12d5 100644 --- a/runit/runsv.c +++ b/runit/runsv.c @@ -26,7 +26,17 @@ ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /* Busyboxed by Denys Vlasenko */ -/* TODO: depends on runit_lib.c - review and reduce/eliminate */ + +//config:config RUNSV +//config: bool "runsv" +//config: default y +//config: help +//config: runsv starts and monitors a service and optionally an appendant log +//config: service. + +//applet:IF_RUNSV(APPLET(runsv, BB_DIR_USR_BIN, BB_SUID_DROP)) + +//kbuild:lib-$(CONFIG_RUNSV) += runsv.o //usage:#define runsv_trivial_usage //usage: "DIR" diff --git a/runit/runsvdir.c b/runit/runsvdir.c index b4c0b2ef0..b3d9e7390 100644 --- a/runit/runsvdir.c +++ b/runit/runsvdir.c @@ -26,7 +26,27 @@ ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /* Busyboxed by Denys Vlasenko */ -/* TODO: depends on runit_lib.c - review and reduce/eliminate */ + +//config:config RUNSVDIR +//config: bool "runsvdir" +//config: default y +//config: help +//config: runsvdir starts a runsv process for each subdirectory, or symlink to +//config: a directory, in the services directory dir, up to a limit of 1000 +//config: subdirectories, and restarts a runsv process if it terminates. +//config: +//config:config FEATURE_RUNSVDIR_LOG +//config: bool "Enable scrolling argument log" +//config: depends on RUNSVDIR +//config: default n +//config: help +//config: Enable feature where second parameter of runsvdir holds last error +//config: message (viewable via top/ps). Otherwise (feature is off +//config: or no parameter), error messages go to stderr only. + +//applet:IF_RUNSVDIR(APPLET(runsvdir, BB_DIR_USR_BIN, BB_SUID_DROP)) + +//kbuild:lib-$(CONFIG_RUNSVDIR) += runsvdir.o //usage:#define runsvdir_trivial_usage //usage: "[-P] [-s SCRIPT] DIR" diff --git a/runit/sv.c b/runit/sv.c index 825e9d45b..de8a0d8a4 100644 --- a/runit/sv.c +++ b/runit/sv.c @@ -151,7 +151,25 @@ Exit Codes */ /* Busyboxed by Denys Vlasenko */ -/* TODO: depends on runit_lib.c - review and reduce/eliminate */ + +//config:config SV +//config: bool "sv" +//config: default y +//config: help +//config: sv reports the current status and controls the state of services +//config: monitored by the runsv supervisor. +//config: +//config:config SV_DEFAULT_SERVICE_DIR +//config: string "Default directory for services" +//config: default "/var/service" +//config: depends on SV +//config: help +//config: Default directory for services. +//config: Defaults to "/var/service" + +//applet:IF_SV(APPLET(sv, BB_DIR_USR_BIN, BB_SUID_DROP)) + +//kbuild:lib-$(CONFIG_SV) += sv.o //usage:#define sv_trivial_usage //usage: "[-v] [-w SEC] CMD SERVICE_DIR..." diff --git a/runit/svlogd.c b/runit/svlogd.c index c080b9acc..dbe8df65c 100644 --- a/runit/svlogd.c +++ b/runit/svlogd.c @@ -26,7 +26,6 @@ ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /* Busyboxed by Denys Vlasenko */ -/* TODO: depends on runit_lib.c - review and reduce/eliminate */ /* Config files @@ -125,6 +124,18 @@ log message, you can use a pattern like this instead -*: *: pid * */ +//config:config SVLOGD +//config: bool "svlogd" +//config: default y +//config: help +//config: svlogd continuously reads log data from its standard input, optionally +//config: filters log messages, and writes the data to one or more automatically +//config: rotated logs. + +//applet:IF_SVLOGD(APPLET(svlogd, BB_DIR_USR_SBIN, BB_SUID_DROP)) + +//kbuild:lib-$(CONFIG_SVLOGD) += svlogd.o + //usage:#define svlogd_trivial_usage //usage: "[-ttv] [-r C] [-R CHARS] [-l MATCHLEN] [-b BUFLEN] DIR..." //usage:#define svlogd_full_usage "\n\n" From 854bb6879da7277446c7a943387e2880017804e0 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Mon, 19 Oct 2015 00:45:46 +0200 Subject: [PATCH 020/260] printutils/*: convert to new-style "one file" applets Signed-off-by: Denys Vlasenko --- include/applets.src.h | 3 --- printutils/Config.src | 18 ------------------ printutils/Kbuild.src | 4 +--- printutils/lpd.c | 9 +++++++++ printutils/lpr.c | 17 +++++++++++++++++ 5 files changed, 27 insertions(+), 24 deletions(-) diff --git a/include/applets.src.h b/include/applets.src.h index d243d89e1..9c4f9daa0 100644 --- a/include/applets.src.h +++ b/include/applets.src.h @@ -209,9 +209,6 @@ IF_LOADKMAP(APPLET(loadkmap, BB_DIR_SBIN, BB_SUID_DROP)) IF_LOGIN(APPLET(login, BB_DIR_BIN, BB_SUID_REQUIRE)) IF_LOGNAME(APPLET_NOFORK(logname, logname, BB_DIR_USR_BIN, BB_SUID_DROP, logname)) IF_LOSETUP(APPLET(losetup, BB_DIR_SBIN, BB_SUID_DROP)) -IF_LPD(APPLET(lpd, BB_DIR_USR_SBIN, BB_SUID_DROP)) -IF_LPQ(APPLET_ODDNAME(lpq, lpqr, BB_DIR_USR_BIN, BB_SUID_DROP, lpq)) -IF_LPR(APPLET_ODDNAME(lpr, lpqr, BB_DIR_USR_BIN, BB_SUID_DROP, lpr)) IF_LS(APPLET_NOEXEC(ls, ls, BB_DIR_BIN, BB_SUID_DROP, ls)) IF_LSPCI(APPLET(lspci, BB_DIR_USR_BIN, BB_SUID_DROP)) IF_LSUSB(APPLET(lsusb, BB_DIR_USR_BIN, BB_SUID_DROP)) diff --git a/printutils/Config.src b/printutils/Config.src index cc4ab8d28..e53b9d093 100644 --- a/printutils/Config.src +++ b/printutils/Config.src @@ -7,22 +7,4 @@ menu "Print Utilities" INSERT -config LPD - bool "lpd" - default y - help - lpd is a print spooling daemon. - -config LPR - bool "lpr" - default y - help - lpr sends files (or standard input) to a print spooling daemon. - -config LPQ - bool "lpq" - default y - help - lpq is a print spool queue examination and manipulation program. - endmenu diff --git a/printutils/Kbuild.src b/printutils/Kbuild.src index 194fe01d6..10c823063 100644 --- a/printutils/Kbuild.src +++ b/printutils/Kbuild.src @@ -4,6 +4,4 @@ lib-y := -lib-$(CONFIG_LPD) += lpd.o -lib-$(CONFIG_LPR) += lpr.o -lib-$(CONFIG_LPQ) += lpr.o +INSERT diff --git a/printutils/lpd.c b/printutils/lpd.c index c98bbb347..882393436 100644 --- a/printutils/lpd.c +++ b/printutils/lpd.c @@ -69,6 +69,15 @@ * cat ./"$DATAFILE" >/dev/lp0 * mv -f ./"$DATAFILE" save/ */ +//config:config LPD +//config: bool "lpd" +//config: default y +//config: help +//config: lpd is a print spooling daemon. + +//applet:IF_LPD(APPLET(lpd, BB_DIR_USR_SBIN, BB_SUID_DROP)) + +//kbuild:lib-$(CONFIG_LPD) += lpd.o //usage:#define lpd_trivial_usage //usage: "SPOOLDIR [HELPER [ARGS]]" diff --git a/printutils/lpr.c b/printutils/lpr.c index 70cda7717..ed6a84a93 100644 --- a/printutils/lpr.c +++ b/printutils/lpr.c @@ -11,6 +11,23 @@ * * See RFC 1179 for protocol description. */ +//config:config LPR +//config: bool "lpr" +//config: default y +//config: help +//config: lpr sends files (or standard input) to a print spooling daemon. +//config: +//config:config LPQ +//config: bool "lpq" +//config: default y +//config: help +//config: lpq is a print spool queue examination and manipulation program. + +//applet:IF_LPQ(APPLET_ODDNAME(lpq, lpqr, BB_DIR_USR_BIN, BB_SUID_DROP, lpq)) +//applet:IF_LPR(APPLET_ODDNAME(lpr, lpqr, BB_DIR_USR_BIN, BB_SUID_DROP, lpr)) + +//kbuild:lib-$(CONFIG_LPR) += lpr.o +//kbuild:lib-$(CONFIG_LPQ) += lpr.o //usage:#define lpr_trivial_usage //usage: "-P queue[@host[:port]] -U USERNAME -J TITLE -Vmh [FILE]..." From 28826ac8c02793431203edb4adb961d5521d643d Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Mon, 19 Oct 2015 00:52:26 +0200 Subject: [PATCH 021/260] debianutils/*: convert to new-style "one file" applets Signed-off-by: Denys Vlasenko --- debianutils/Config.src | 75 --------------------------------- debianutils/Kbuild.src | 5 --- debianutils/mktemp.c | 9 ++++ debianutils/pipe_progress.c | 9 ++++ debianutils/run_parts.c | 34 +++++++++++++++ debianutils/start_stop_daemon.c | 28 ++++++++++++ debianutils/which.c | 10 +++++ include/applets.src.h | 5 --- 8 files changed, 90 insertions(+), 85 deletions(-) diff --git a/debianutils/Config.src b/debianutils/Config.src index cbc09b5ce..61daeb047 100644 --- a/debianutils/Config.src +++ b/debianutils/Config.src @@ -7,79 +7,4 @@ menu "Debian Utilities" INSERT -config MKTEMP - bool "mktemp" - default y - help - mktemp is used to create unique temporary files - -config PIPE_PROGRESS - bool "pipe_progress" - default y - help - Display a dot to indicate pipe activity. - -config RUN_PARTS - bool "run-parts" - default y - help - run-parts is a utility designed to run all the scripts in a directory. - - It is useful to set up a directory like cron.daily, where you need to - execute all the scripts in that directory. - - In this implementation of run-parts some features (such as report - mode) are not implemented. - - Unless you know that run-parts is used in some of your scripts - you can safely say N here. - -config FEATURE_RUN_PARTS_LONG_OPTIONS - bool "Enable long options" - default y - depends on RUN_PARTS && LONG_OPTS - help - Support long options for the run-parts applet. - -config FEATURE_RUN_PARTS_FANCY - bool "Support additional arguments" - default y - depends on RUN_PARTS - help - Support additional options: - -l --list print the names of the all matching files (not - limited to executables), but don't actually run them. - -config START_STOP_DAEMON - bool "start-stop-daemon" - default y - help - start-stop-daemon is used to control the creation and - termination of system-level processes, usually the ones - started during the startup of the system. - -config FEATURE_START_STOP_DAEMON_FANCY - bool "Support additional arguments" - default y - depends on START_STOP_DAEMON - help - Support additional arguments. - -o|--oknodo ignored since we exit with 0 anyway - -v|--verbose - -N|--nicelevel N - -config FEATURE_START_STOP_DAEMON_LONG_OPTIONS - bool "Enable long options" - default y - depends on START_STOP_DAEMON && LONG_OPTS - help - Support long options for the start-stop-daemon applet. - -config WHICH - bool "which" - default y - help - which is used to find programs in your PATH and - print out their pathnames. - endmenu diff --git a/debianutils/Kbuild.src b/debianutils/Kbuild.src index d41b5c8e4..6b4fb7470 100644 --- a/debianutils/Kbuild.src +++ b/debianutils/Kbuild.src @@ -7,8 +7,3 @@ lib-y:= INSERT -lib-$(CONFIG_MKTEMP) += mktemp.o -lib-$(CONFIG_PIPE_PROGRESS) += pipe_progress.o -lib-$(CONFIG_RUN_PARTS) += run_parts.o -lib-$(CONFIG_START_STOP_DAEMON) += start_stop_daemon.o -lib-$(CONFIG_WHICH) += which.o diff --git a/debianutils/mktemp.c b/debianutils/mktemp.c index 983d7a246..65353697a 100644 --- a/debianutils/mktemp.c +++ b/debianutils/mktemp.c @@ -30,6 +30,15 @@ * a directory: $TMPDIR, if set; else the directory specified via * -p; else /tmp [deprecated] */ +//config:config MKTEMP +//config: bool "mktemp" +//config: default y +//config: help +//config: mktemp is used to create unique temporary files + +//applet:IF_MKTEMP(APPLET(mktemp, BB_DIR_BIN, BB_SUID_DROP)) + +//kbuild:lib-$(CONFIG_MKTEMP) += mktemp.o //usage:#define mktemp_trivial_usage //usage: "[-dt] [-p DIR] [TEMPLATE]" diff --git a/debianutils/pipe_progress.c b/debianutils/pipe_progress.c index 2c7444f31..21d330b59 100644 --- a/debianutils/pipe_progress.c +++ b/debianutils/pipe_progress.c @@ -6,6 +6,15 @@ * * Licensed under GPLv2 or later, see file LICENSE in this source tree. */ +//config:config PIPE_PROGRESS +//config: bool "pipe_progress" +//config: default y +//config: help +//config: Display a dot to indicate pipe activity. + +//applet:IF_PIPE_PROGRESS(APPLET(pipe_progress, BB_DIR_BIN, BB_SUID_DROP)) + +//kbuild:lib-$(CONFIG_PIPE_PROGRESS) += pipe_progress.o //usage:#define pipe_progress_trivial_usage NOUSAGE_STR //usage:#define pipe_progress_full_usage "" diff --git a/debianutils/run_parts.c b/debianutils/run_parts.c index dd6fe7d49..13617c6e1 100644 --- a/debianutils/run_parts.c +++ b/debianutils/run_parts.c @@ -22,6 +22,40 @@ * report mode. As the original run-parts support only long options, I've * broken compatibility because the BusyBox policy doesn't allow them. */ +//config:config RUN_PARTS +//config: bool "run-parts" +//config: default y +//config: help +//config: run-parts is a utility designed to run all the scripts in a directory. +//config: +//config: It is useful to set up a directory like cron.daily, where you need to +//config: execute all the scripts in that directory. +//config: +//config: In this implementation of run-parts some features (such as report +//config: mode) are not implemented. +//config: +//config: Unless you know that run-parts is used in some of your scripts +//config: you can safely say N here. +//config: +//config:config FEATURE_RUN_PARTS_LONG_OPTIONS +//config: bool "Enable long options" +//config: default y +//config: depends on RUN_PARTS && LONG_OPTS +//config: help +//config: Support long options for the run-parts applet. +//config: +//config:config FEATURE_RUN_PARTS_FANCY +//config: bool "Support additional arguments" +//config: default y +//config: depends on RUN_PARTS +//config: help +//config: Support additional options: +//config: -l --list print the names of the all matching files (not +//config: limited to executables), but don't actually run them. + +//applet:IF_RUN_PARTS(APPLET_ODDNAME(run-parts, run_parts, BB_DIR_BIN, BB_SUID_DROP, run_parts)) + +//kbuild:lib-$(CONFIG_RUN_PARTS) += run_parts.o //usage:#define run_parts_trivial_usage //usage: "[-a ARG]... [-u UMASK] " diff --git a/debianutils/start_stop_daemon.c b/debianutils/start_stop_daemon.c index 7dadc3c9e..42f1943dd 100644 --- a/debianutils/start_stop_daemon.c +++ b/debianutils/start_stop_daemon.c @@ -56,6 +56,34 @@ Misc options: -q,--quiet Quiet -v,--verbose Verbose */ +//config:config START_STOP_DAEMON +//config: bool "start-stop-daemon" +//config: default y +//config: help +//config: start-stop-daemon is used to control the creation and +//config: termination of system-level processes, usually the ones +//config: started during the startup of the system. +//config: +//config:config FEATURE_START_STOP_DAEMON_FANCY +//config: bool "Support additional arguments" +//config: default y +//config: depends on START_STOP_DAEMON +//config: help +//config: Support additional arguments. +//config: -o|--oknodo ignored since we exit with 0 anyway +//config: -v|--verbose +//config: -N|--nicelevel N +//config: +//config:config FEATURE_START_STOP_DAEMON_LONG_OPTIONS +//config: bool "Enable long options" +//config: default y +//config: depends on START_STOP_DAEMON && LONG_OPTS +//config: help +//config: Support long options for the start-stop-daemon applet. + +//applet:IF_START_STOP_DAEMON(APPLET_ODDNAME(start-stop-daemon, start_stop_daemon, BB_DIR_SBIN, BB_SUID_DROP, start_stop_daemon)) + +//kbuild:lib-$(CONFIG_START_STOP_DAEMON) += start_stop_daemon.o //usage:#define start_stop_daemon_trivial_usage //usage: "[OPTIONS] [-S|-K] ... [-- ARGS...]" diff --git a/debianutils/which.c b/debianutils/which.c index d50e7a0d3..c0f897809 100644 --- a/debianutils/which.c +++ b/debianutils/which.c @@ -5,6 +5,16 @@ * * Licensed under GPLv2 or later, see file LICENSE in this source tree. */ +//config:config WHICH +//config: bool "which" +//config: default y +//config: help +//config: which is used to find programs in your PATH and +//config: print out their pathnames. + +//applet:IF_WHICH(APPLET(which, BB_DIR_USR_BIN, BB_SUID_DROP)) + +//kbuild:lib-$(CONFIG_WHICH) += which.o //usage:#define which_trivial_usage //usage: "[COMMAND]..." diff --git a/include/applets.src.h b/include/applets.src.h index 9c4f9daa0..f49179996 100644 --- a/include/applets.src.h +++ b/include/applets.src.h @@ -230,7 +230,6 @@ IF_MKFS_VFAT(APPLET_ODDNAME(mkfs.vfat, mkfs_vfat, BB_DIR_SBIN, BB_SUID_DROP, mkf IF_MKNOD(APPLET_NOEXEC(mknod, mknod, BB_DIR_BIN, BB_SUID_DROP, mknod)) IF_CRYPTPW(APPLET_ODDNAME(mkpasswd, cryptpw, BB_DIR_USR_BIN, BB_SUID_DROP, mkpasswd)) IF_MKSWAP(APPLET(mkswap, BB_DIR_SBIN, BB_SUID_DROP)) -IF_MKTEMP(APPLET(mktemp, BB_DIR_BIN, BB_SUID_DROP)) IF_MORE(APPLET(more, BB_DIR_BIN, BB_SUID_DROP)) /* On full-blown systems, requires suid for user mounts. * But it's not unthinkable to have it available in non-suid flavor on some systems, @@ -254,7 +253,6 @@ IF_OPENVT(APPLET(openvt, BB_DIR_USR_BIN, BB_SUID_DROP)) IF_PASSWD(APPLET(passwd, BB_DIR_USR_BIN, BB_SUID_REQUIRE)) IF_PGREP(APPLET(pgrep, BB_DIR_USR_BIN, BB_SUID_DROP)) IF_PIDOF(APPLET(pidof, BB_DIR_BIN, BB_SUID_DROP)) -IF_PIPE_PROGRESS(APPLET(pipe_progress, BB_DIR_BIN, BB_SUID_DROP)) IF_PIVOT_ROOT(APPLET(pivot_root, BB_DIR_SBIN, BB_SUID_DROP)) IF_PKILL(APPLET_ODDNAME(pkill, pgrep, BB_DIR_USR_BIN, BB_SUID_DROP, pkill)) IF_POPMAILDIR(APPLET(popmaildir, BB_DIR_USR_SBIN, BB_SUID_DROP)) @@ -279,7 +277,6 @@ IF_RM(APPLET_NOFORK(rm, rm, BB_DIR_BIN, BB_SUID_DROP, rm)) IF_RMDIR(APPLET_NOFORK(rmdir, rmdir, BB_DIR_BIN, BB_SUID_DROP, rmdir)) IF_ROUTE(APPLET(route, BB_DIR_SBIN, BB_SUID_DROP)) IF_RTCWAKE(APPLET(rtcwake, BB_DIR_USR_SBIN, BB_SUID_DROP)) -IF_RUN_PARTS(APPLET_ODDNAME(run-parts, run_parts, BB_DIR_BIN, BB_SUID_DROP, run_parts)) IF_RUNCON(APPLET(runcon, BB_DIR_USR_BIN, BB_SUID_DROP)) IF_RUNLEVEL(APPLET(runlevel, BB_DIR_SBIN, BB_SUID_DROP)) IF_RX(APPLET(rx, BB_DIR_USR_BIN, BB_SUID_DROP)) @@ -308,7 +305,6 @@ IF_SLATTACH(APPLET(slattach, BB_DIR_SBIN, BB_SUID_DROP)) IF_SLEEP(APPLET(sleep, BB_DIR_BIN, BB_SUID_DROP)) IF_SORT(APPLET_NOEXEC(sort, sort, BB_DIR_USR_BIN, BB_SUID_DROP, sort)) IF_SPLIT(APPLET(split, BB_DIR_USR_BIN, BB_SUID_DROP)) -IF_START_STOP_DAEMON(APPLET_ODDNAME(start-stop-daemon, start_stop_daemon, BB_DIR_SBIN, BB_SUID_DROP, start_stop_daemon)) IF_STAT(APPLET(stat, BB_DIR_BIN, BB_SUID_DROP)) IF_STRINGS(APPLET(strings, BB_DIR_USR_BIN, BB_SUID_DROP)) IF_STTY(APPLET(stty, BB_DIR_BIN, BB_SUID_DROP)) @@ -362,7 +358,6 @@ IF_VOLNAME(APPLET(volname, BB_DIR_USR_BIN, BB_SUID_DROP)) IF_WATCH(APPLET(watch, BB_DIR_BIN, BB_SUID_DROP)) IF_WATCHDOG(APPLET(watchdog, BB_DIR_SBIN, BB_SUID_DROP)) IF_WC(APPLET(wc, BB_DIR_USR_BIN, BB_SUID_DROP)) -IF_WHICH(APPLET(which, BB_DIR_USR_BIN, BB_SUID_DROP)) IF_WHOAMI(APPLET_NOFORK(whoami, whoami, BB_DIR_USR_BIN, BB_SUID_DROP, whoami)) IF_YES(APPLET_NOFORK(yes, yes, BB_DIR_USR_BIN, BB_SUID_DROP, yes)) IF_ZCIP(APPLET(zcip, BB_DIR_SBIN, BB_SUID_DROP)) From 95dee81a465668151cff3ffd757456a9a10c1f1f Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Mon, 19 Oct 2015 01:20:36 +0200 Subject: [PATCH 022/260] loginutils/*: convert to new-style "one file" applets Signed-off-by: Denys Vlasenko --- include/applets.src.h | 17 --- loginutils/Config.src | 237 +--------------------------------- loginutils/Kbuild.src | 12 -- loginutils/add-remove-shell.c | 13 +- loginutils/addgroup.c | 25 ++++ loginutils/adduser.c | 51 ++++++++ loginutils/chpasswd.c | 20 ++- loginutils/cryptpw.c | 12 ++ loginutils/deluser.c | 26 +++- loginutils/getty.c | 22 ++++ loginutils/login.c | 50 +++++++ loginutils/passwd.c | 24 ++++ loginutils/su.c | 29 ++++- loginutils/sulogin.c | 12 ++ loginutils/vlock.c | 16 ++- 15 files changed, 289 insertions(+), 277 deletions(-) diff --git a/include/applets.src.h b/include/applets.src.h index f49179996..5b597202e 100644 --- a/include/applets.src.h +++ b/include/applets.src.h @@ -76,8 +76,6 @@ INSERT IF_TEST(APPLET_NOFORK([, test, BB_DIR_USR_BIN, BB_SUID_DROP, test)) IF_TEST(APPLET_NOFORK([[, test, BB_DIR_USR_BIN, BB_SUID_DROP, test)) IF_ACPID(APPLET(acpid, BB_DIR_SBIN, BB_SUID_DROP)) -IF_ADDGROUP(APPLET(addgroup, BB_DIR_USR_SBIN, BB_SUID_DROP)) -IF_ADDUSER(APPLET(adduser, BB_DIR_USR_SBIN, BB_SUID_DROP)) IF_ADJTIMEX(APPLET(adjtimex, BB_DIR_SBIN, BB_SUID_DROP)) IF_ARP(APPLET(arp, BB_DIR_SBIN, BB_SUID_DROP)) IF_ARPING(APPLET(arping, BB_DIR_USR_SBIN, BB_SUID_DROP)) @@ -94,7 +92,6 @@ IF_CHCON(APPLET(chcon, BB_DIR_USR_BIN, BB_SUID_DROP)) IF_CHGRP(APPLET_NOEXEC(chgrp, chgrp, BB_DIR_BIN, BB_SUID_DROP, chgrp)) IF_CHMOD(APPLET_NOEXEC(chmod, chmod, BB_DIR_BIN, BB_SUID_DROP, chmod)) IF_CHOWN(APPLET_NOEXEC(chown, chown, BB_DIR_BIN, BB_SUID_DROP, chown)) -IF_CHPASSWD(APPLET(chpasswd, BB_DIR_USR_SBIN, BB_SUID_DROP)) IF_CHROOT(APPLET(chroot, BB_DIR_USR_SBIN, BB_SUID_DROP)) IF_CHRT(APPLET(chrt, BB_DIR_USR_BIN, BB_SUID_DROP)) IF_CHVT(APPLET(chvt, BB_DIR_USR_BIN, BB_SUID_DROP)) @@ -104,13 +101,10 @@ IF_COMM(APPLET(comm, BB_DIR_USR_BIN, BB_SUID_DROP)) IF_CP(APPLET_NOEXEC(cp, cp, BB_DIR_BIN, BB_SUID_DROP, cp)) /* Needs to be run by root or be suid root - needs to change /var/spool/cron* files: */ IF_CRONTAB(APPLET(crontab, BB_DIR_USR_BIN, BB_SUID_REQUIRE)) -IF_CRYPTPW(APPLET(cryptpw, BB_DIR_USR_BIN, BB_SUID_DROP)) IF_CUT(APPLET_NOEXEC(cut, cut, BB_DIR_USR_BIN, BB_SUID_DROP, cut)) IF_DC(APPLET(dc, BB_DIR_USR_BIN, BB_SUID_DROP)) IF_DD(APPLET_NOEXEC(dd, dd, BB_DIR_BIN, BB_SUID_DROP, dd)) IF_DEALLOCVT(APPLET(deallocvt, BB_DIR_USR_BIN, BB_SUID_DROP)) -IF_DELGROUP(APPLET_ODDNAME(delgroup, deluser, BB_DIR_USR_SBIN, BB_SUID_DROP, delgroup)) -IF_DELUSER(APPLET(deluser, BB_DIR_USR_SBIN, BB_SUID_DROP)) IF_DEVFSD(APPLET(devfsd, BB_DIR_SBIN, BB_SUID_DROP)) IF_DEVMEM(APPLET(devmem, BB_DIR_SBIN, BB_SUID_DROP)) IF_DF(APPLET(df, BB_DIR_BIN, BB_SUID_DROP)) @@ -160,7 +154,6 @@ IF_FUSER(APPLET(fuser, BB_DIR_USR_BIN, BB_SUID_DROP)) IF_GETENFORCE(APPLET(getenforce, BB_DIR_USR_SBIN, BB_SUID_DROP)) IF_GETOPT(APPLET(getopt, BB_DIR_BIN, BB_SUID_DROP)) IF_GETSEBOOL(APPLET(getsebool, BB_DIR_USR_SBIN, BB_SUID_DROP)) -IF_GETTY(APPLET(getty, BB_DIR_SBIN, BB_SUID_DROP)) IF_HD(APPLET_NOEXEC(hd, hexdump, BB_DIR_USR_BIN, BB_SUID_DROP, hd)) IF_HDPARM(APPLET(hdparm, BB_DIR_SBIN, BB_SUID_DROP)) IF_HEAD(APPLET_NOEXEC(head, head, BB_DIR_USR_BIN, BB_SUID_DROP, head)) @@ -205,8 +198,6 @@ IF_LN(APPLET_NOEXEC(ln, ln, BB_DIR_BIN, BB_SUID_DROP, ln)) IF_LOAD_POLICY(APPLET(load_policy, BB_DIR_USR_SBIN, BB_SUID_DROP)) IF_LOADFONT(APPLET(loadfont, BB_DIR_USR_SBIN, BB_SUID_DROP)) IF_LOADKMAP(APPLET(loadkmap, BB_DIR_SBIN, BB_SUID_DROP)) -/* Needs to be run by root or be suid root - needs to change uid and gid: */ -IF_LOGIN(APPLET(login, BB_DIR_BIN, BB_SUID_REQUIRE)) IF_LOGNAME(APPLET_NOFORK(logname, logname, BB_DIR_USR_BIN, BB_SUID_DROP, logname)) IF_LOSETUP(APPLET(losetup, BB_DIR_SBIN, BB_SUID_DROP)) IF_LS(APPLET_NOEXEC(ls, ls, BB_DIR_BIN, BB_SUID_DROP, ls)) @@ -228,7 +219,6 @@ IF_MKFS_MINIX(APPLET_ODDNAME(mkfs.minix, mkfs_minix, BB_DIR_SBIN, BB_SUID_DROP, IF_MKFS_REISER(APPLET_ODDNAME(mkfs.reiser, mkfs_reiser, BB_DIR_SBIN, BB_SUID_DROP, mkfs_reiser)) IF_MKFS_VFAT(APPLET_ODDNAME(mkfs.vfat, mkfs_vfat, BB_DIR_SBIN, BB_SUID_DROP, mkfs_vfat)) IF_MKNOD(APPLET_NOEXEC(mknod, mknod, BB_DIR_BIN, BB_SUID_DROP, mknod)) -IF_CRYPTPW(APPLET_ODDNAME(mkpasswd, cryptpw, BB_DIR_USR_BIN, BB_SUID_DROP, mkpasswd)) IF_MKSWAP(APPLET(mkswap, BB_DIR_SBIN, BB_SUID_DROP)) IF_MORE(APPLET(more, BB_DIR_BIN, BB_SUID_DROP)) /* On full-blown systems, requires suid for user mounts. @@ -249,8 +239,6 @@ IF_NTPD(APPLET(ntpd, BB_DIR_USR_SBIN, BB_SUID_DROP)) IF_OD(APPLET(od, BB_DIR_USR_BIN, BB_SUID_DROP)) IF_OPENVT(APPLET(openvt, BB_DIR_USR_BIN, BB_SUID_DROP)) //IF_PARSE(APPLET(parse, BB_DIR_USR_BIN, BB_SUID_DROP)) -/* Needs to be run by root or be suid root - needs to change /etc/{passwd,shadow}: */ -IF_PASSWD(APPLET(passwd, BB_DIR_USR_BIN, BB_SUID_REQUIRE)) IF_PGREP(APPLET(pgrep, BB_DIR_USR_BIN, BB_SUID_DROP)) IF_PIDOF(APPLET(pidof, BB_DIR_BIN, BB_SUID_DROP)) IF_PIVOT_ROOT(APPLET(pivot_root, BB_DIR_SBIN, BB_SUID_DROP)) @@ -308,9 +296,6 @@ IF_SPLIT(APPLET(split, BB_DIR_USR_BIN, BB_SUID_DROP)) IF_STAT(APPLET(stat, BB_DIR_BIN, BB_SUID_DROP)) IF_STRINGS(APPLET(strings, BB_DIR_USR_BIN, BB_SUID_DROP)) IF_STTY(APPLET(stty, BB_DIR_BIN, BB_SUID_DROP)) -/* Needs to be run by root or be suid root - needs to change uid and gid: */ -IF_SU(APPLET(su, BB_DIR_BIN, BB_SUID_REQUIRE)) -IF_SULOGIN(APPLET(sulogin, BB_DIR_SBIN, BB_SUID_DROP)) IF_SUM(APPLET(sum, BB_DIR_USR_BIN, BB_SUID_DROP)) IF_SWAPONOFF(APPLET_ODDNAME(swapoff, swap_on_off, BB_DIR_SBIN, BB_SUID_DROP, swapoff)) IF_SWAPONOFF(APPLET_ODDNAME(swapon, swap_on_off, BB_DIR_SBIN, BB_SUID_DROP, swapon)) @@ -352,8 +337,6 @@ IF_USLEEP(APPLET_NOFORK(usleep, usleep, BB_DIR_BIN, BB_SUID_DROP, usleep)) IF_UUDECODE(APPLET(uudecode, BB_DIR_USR_BIN, BB_SUID_DROP)) IF_UUENCODE(APPLET(uuencode, BB_DIR_USR_BIN, BB_SUID_DROP)) IF_VCONFIG(APPLET(vconfig, BB_DIR_SBIN, BB_SUID_DROP)) -/* Needs to be run by root or be suid root - needs to change uid and gid: */ -IF_VLOCK(APPLET(vlock, BB_DIR_USR_BIN, BB_SUID_REQUIRE)) IF_VOLNAME(APPLET(volname, BB_DIR_USR_BIN, BB_SUID_DROP)) IF_WATCH(APPLET(watch, BB_DIR_BIN, BB_SUID_DROP)) IF_WATCHDOG(APPLET(watchdog, BB_DIR_SBIN, BB_SUID_DROP)) diff --git a/loginutils/Config.src b/loginutils/Config.src index fa2b4f8c0..efb954b6c 100644 --- a/loginutils/Config.src +++ b/loginutils/Config.src @@ -5,8 +5,6 @@ menu "Login/Password Management Utilities" -INSERT - config FEATURE_SHADOWPASSWDS bool "Support for shadow passwords" default y @@ -93,239 +91,6 @@ config USE_BB_CRYPT_SHA With this option off, login will fail password check for any user which has password encrypted with these algorithms. -config ADDUSER - bool "adduser" - default y - help - Utility for creating a new user account. - -config FEATURE_ADDUSER_LONG_OPTIONS - bool "Enable long options" - default y - depends on ADDUSER && LONG_OPTS - help - Support long options for the adduser applet. - -config FEATURE_CHECK_NAMES - bool "Enable sanity check on user/group names in adduser and addgroup" - default n - depends on ADDUSER || ADDGROUP - help - Enable sanity check on user and group names in adduser and addgroup. - To avoid problems, the user or group name should consist only of - letters, digits, underscores, periods, at signs and dashes, - and not start with a dash (as defined by IEEE Std 1003.1-2001). - For compatibility with Samba machine accounts "$" is also supported - at the end of the user or group name. - -config LAST_ID - int "Last valid uid or gid for adduser and addgroup" - depends on ADDUSER || ADDGROUP - default 60000 - help - Last valid uid or gid for adduser and addgroup - -config FIRST_SYSTEM_ID - int "First valid system uid or gid for adduser and addgroup" - depends on ADDUSER || ADDGROUP - range 0 LAST_ID - default 100 - help - First valid system uid or gid for adduser and addgroup - -config LAST_SYSTEM_ID - int "Last valid system uid or gid for adduser and addgroup" - depends on ADDUSER || ADDGROUP - range FIRST_SYSTEM_ID LAST_ID - default 999 - help - Last valid system uid or gid for adduser and addgroup - -config ADDGROUP - bool "addgroup" - default y - help - Utility for creating a new group account. - -config FEATURE_ADDGROUP_LONG_OPTIONS - bool "Enable long options" - default y - depends on ADDGROUP && LONG_OPTS - help - Support long options for the addgroup applet. - -config FEATURE_ADDUSER_TO_GROUP - bool "Support for adding users to groups" - default y - depends on ADDGROUP - help - If called with two non-option arguments, - addgroup will add an existing user to an - existing group. - -config DELUSER - bool "deluser" - default y - help - Utility for deleting a user account. - -config DELGROUP - bool "delgroup" - default y - help - Utility for deleting a group account. - -config FEATURE_DEL_USER_FROM_GROUP - bool "Support for removing users from groups" - default y - depends on DELGROUP - help - If called with two non-option arguments, deluser - or delgroup will remove an user from a specified group. - -config GETTY - bool "getty" - default y - select FEATURE_SYSLOG - help - getty lets you log in on a tty. It is normally invoked by init. - - Note that you can save a few bytes by disabling it and - using login applet directly. - If you need to reset tty attributes before calling login, - this script approximates getty: - - exec /dev/$1 2>&1 || exit 1 - reset - stty sane; stty ispeed 38400; stty ospeed 38400 - printf "%s login: " "`hostname`" - read -r login - exec /bin/login "$login" - -config LOGIN - bool "login" - default y - select FEATURE_SYSLOG - help - login is used when signing onto a system. - - Note that Busybox binary must be setuid root for this applet to - work properly. - -config LOGIN_SESSION_AS_CHILD - bool "Run logged in session in a child process" - default y if PAM - depends on LOGIN - help - Run the logged in session in a child process. This allows - login to clean up things such as utmp entries or PAM sessions - when the login session is complete. If you use PAM, you - almost always would want this to be set to Y, else PAM session - will not be cleaned up. - -config LOGIN_SCRIPTS - bool "Support for login scripts" - depends on LOGIN - default y - help - Enable this if you want login to execute $LOGIN_PRE_SUID_SCRIPT - just prior to switching from root to logged-in user. - -config FEATURE_NOLOGIN - bool "Support for /etc/nologin" - default y - depends on LOGIN - help - The file /etc/nologin is used by (some versions of) login(1). - If it exists, non-root logins are prohibited. - -config FEATURE_SECURETTY - bool "Support for /etc/securetty" - default y - depends on LOGIN - help - The file /etc/securetty is used by (some versions of) login(1). - The file contains the device names of tty lines (one per line, - without leading /dev/) on which root is allowed to login. - -config PASSWD - bool "passwd" - default y - select FEATURE_SYSLOG - help - passwd changes passwords for user and group accounts. A normal user - may only change the password for his/her own account, the super user - may change the password for any account. The administrator of a group - may change the password for the group. - - Note that Busybox binary must be setuid root for this applet to - work properly. - -config FEATURE_PASSWD_WEAK_CHECK - bool "Check new passwords for weakness" - default y - depends on PASSWD - help - With this option passwd will refuse new passwords which are "weak". - -config CRYPTPW - bool "cryptpw" - default y - help - Encrypts the given password with the crypt(3) libc function - using the given salt. Debian has this utility under mkpasswd - name. Busybox provides mkpasswd as an alias for cryptpw. - -config CHPASSWD - bool "chpasswd" - default y - help - Reads a file of user name and password pairs from standard input - and uses this information to update a group of existing users. - -config FEATURE_DEFAULT_PASSWD_ALGO - string "Default password encryption method (passwd -a, cryptpw -m parameter)" - default "des" - depends on PASSWD || CRYPTPW - help - Possible choices are "d[es]", "m[d5]", "s[ha256]" or "sha512". - -config SU - bool "su" - default y - select FEATURE_SYSLOG - help - su is used to become another user during a login session. - Invoked without a username, su defaults to becoming the super user. - - Note that Busybox binary must be setuid root for this applet to - work properly. - -config FEATURE_SU_SYSLOG - bool "Enable su to write to syslog" - default y - depends on SU - -config FEATURE_SU_CHECKS_SHELLS - bool "Enable su to check user's shell to be listed in /etc/shells" - depends on SU - default y - -config SULOGIN - bool "sulogin" - default y - select FEATURE_SYSLOG - help - sulogin is invoked when the system goes into single user - mode (this is done through an entry in inittab). - -config VLOCK - bool "vlock" - default y - help - Build the "vlock" applet which allows you to lock (virtual) terminals. - - Note that Busybox binary must be setuid root for this applet to - work properly. +INSERT endmenu diff --git a/loginutils/Kbuild.src b/loginutils/Kbuild.src index ef416a76f..6b4fb7470 100644 --- a/loginutils/Kbuild.src +++ b/loginutils/Kbuild.src @@ -7,15 +7,3 @@ lib-y:= INSERT -lib-$(CONFIG_ADDGROUP) += addgroup.o -lib-$(CONFIG_ADDUSER) += adduser.o -lib-$(CONFIG_CRYPTPW) += cryptpw.o -lib-$(CONFIG_CHPASSWD) += chpasswd.o -lib-$(CONFIG_GETTY) += getty.o -lib-$(CONFIG_LOGIN) += login.o -lib-$(CONFIG_PASSWD) += passwd.o -lib-$(CONFIG_SU) += su.o -lib-$(CONFIG_SULOGIN) += sulogin.o -lib-$(CONFIG_VLOCK) += vlock.o -lib-$(CONFIG_DELUSER) += deluser.o -lib-$(CONFIG_DELGROUP) += deluser.o diff --git a/loginutils/add-remove-shell.c b/loginutils/add-remove-shell.c index 9419ff5e7..ce4a7bbd2 100644 --- a/loginutils/add-remove-shell.c +++ b/loginutils/add-remove-shell.c @@ -7,13 +7,6 @@ * Licensed under GPLv2 or later, see the LICENSE file in this source tree * for details. */ - -//applet:IF_ADD_SHELL( APPLET_ODDNAME(add-shell , add_remove_shell, BB_DIR_USR_SBIN, BB_SUID_DROP, add_shell )) -//applet:IF_REMOVE_SHELL(APPLET_ODDNAME(remove-shell, add_remove_shell, BB_DIR_USR_SBIN, BB_SUID_DROP, remove_shell)) - -//kbuild:lib-$(CONFIG_ADD_SHELL) += add-remove-shell.o -//kbuild:lib-$(CONFIG_REMOVE_SHELL) += add-remove-shell.o - //config:config ADD_SHELL //config: bool "add-shell" //config: default y if DESKTOP @@ -26,6 +19,12 @@ //config: help //config: Remove shells from /etc/shells. +//applet:IF_ADD_SHELL( APPLET_ODDNAME(add-shell , add_remove_shell, BB_DIR_USR_SBIN, BB_SUID_DROP, add_shell )) +//applet:IF_REMOVE_SHELL(APPLET_ODDNAME(remove-shell, add_remove_shell, BB_DIR_USR_SBIN, BB_SUID_DROP, remove_shell)) + +//kbuild:lib-$(CONFIG_ADD_SHELL) += add-remove-shell.o +//kbuild:lib-$(CONFIG_REMOVE_SHELL) += add-remove-shell.o + //usage:#define add_shell_trivial_usage //usage: "SHELL..." //usage:#define add_shell_full_usage "\n\n" diff --git a/loginutils/addgroup.c b/loginutils/addgroup.c index 260e337f3..4d4fc3f28 100644 --- a/loginutils/addgroup.c +++ b/loginutils/addgroup.c @@ -9,6 +9,31 @@ * Licensed under GPLv2 or later, see file LICENSE in this source tree. * */ +//config:config ADDGROUP +//config: bool "addgroup" +//config: default y +//config: help +//config: Utility for creating a new group account. +//config: +//config:config FEATURE_ADDGROUP_LONG_OPTIONS +//config: bool "Enable long options" +//config: default y +//config: depends on ADDGROUP && LONG_OPTS +//config: help +//config: Support long options for the addgroup applet. +//config: +//config:config FEATURE_ADDUSER_TO_GROUP +//config: bool "Support for adding users to groups" +//config: default y +//config: depends on ADDGROUP +//config: help +//config: If called with two non-option arguments, +//config: addgroup will add an existing user to an +//config: existing group. + +//applet:IF_ADDGROUP(APPLET(addgroup, BB_DIR_USR_SBIN, BB_SUID_DROP)) + +//kbuild:lib-$(CONFIG_ADDGROUP) += addgroup.o //usage:#define addgroup_trivial_usage //usage: "[-g GID] [-S] " IF_FEATURE_ADDUSER_TO_GROUP("[USER] ") "GROUP" diff --git a/loginutils/adduser.c b/loginutils/adduser.c index 605e3363f..608fb8437 100644 --- a/loginutils/adduser.c +++ b/loginutils/adduser.c @@ -7,6 +7,57 @@ * * Licensed under GPLv2 or later, see file LICENSE in this source tree. */ +//config:config ADDUSER +//config: bool "adduser" +//config: default y +//config: help +//config: Utility for creating a new user account. +//config: +//config:config FEATURE_ADDUSER_LONG_OPTIONS +//config: bool "Enable long options" +//config: default y +//config: depends on ADDUSER && LONG_OPTS +//config: help +//config: Support long options for the adduser applet. +//config: +//config:config FEATURE_CHECK_NAMES +//config: bool "Enable sanity check on user/group names in adduser and addgroup" +//config: default n +//config: depends on ADDUSER || ADDGROUP +//config: help +//config: Enable sanity check on user and group names in adduser and addgroup. +//config: To avoid problems, the user or group name should consist only of +//config: letters, digits, underscores, periods, at signs and dashes, +//config: and not start with a dash (as defined by IEEE Std 1003.1-2001). +//config: For compatibility with Samba machine accounts "$" is also supported +//config: at the end of the user or group name. +//config: +//config:config LAST_ID +//config: int "Last valid uid or gid for adduser and addgroup" +//config: depends on ADDUSER || ADDGROUP +//config: default 60000 +//config: help +//config: Last valid uid or gid for adduser and addgroup +//config: +//config:config FIRST_SYSTEM_ID +//config: int "First valid system uid or gid for adduser and addgroup" +//config: depends on ADDUSER || ADDGROUP +//config: range 0 LAST_ID +//config: default 100 +//config: help +//config: First valid system uid or gid for adduser and addgroup +//config: +//config:config LAST_SYSTEM_ID +//config: int "Last valid system uid or gid for adduser and addgroup" +//config: depends on ADDUSER || ADDGROUP +//config: range FIRST_SYSTEM_ID LAST_ID +//config: default 999 +//config: help +//config: Last valid system uid or gid for adduser and addgroup + +//applet:IF_ADDUSER(APPLET(adduser, BB_DIR_USR_SBIN, BB_SUID_DROP)) + +//kbuild:lib-$(CONFIG_ADDUSER) += adduser.o //usage:#define adduser_trivial_usage //usage: "[OPTIONS] USER [GROUP]" diff --git a/loginutils/chpasswd.c b/loginutils/chpasswd.c index 54ed73795..6c41d17be 100644 --- a/loginutils/chpasswd.c +++ b/loginutils/chpasswd.c @@ -5,7 +5,23 @@ * Written for SLIND (from passwd.c) by Alexander Shishkin * Licensed under GPLv2 or later, see file LICENSE in this source tree. */ -#include "libbb.h" +//config:config CHPASSWD +//config: bool "chpasswd" +//config: default y +//config: help +//config: Reads a file of user name and password pairs from standard input +//config: and uses this information to update a group of existing users. +//config: +//config:config FEATURE_DEFAULT_PASSWD_ALGO +//config: string "Default password encryption method (passwd -a, cryptpw -m parameter)" +//config: default "des" +//config: depends on PASSWD || CRYPTPW +//config: help +//config: Possible choices are "d[es]", "m[d5]", "s[ha256]" or "sha512". + +//applet:IF_CHPASSWD(APPLET(chpasswd, BB_DIR_USR_SBIN, BB_SUID_DROP)) + +//kbuild:lib-$(CONFIG_CHPASSWD) += chpasswd.o //usage:#define chpasswd_trivial_usage //usage: IF_LONG_OPTS("[--md5|--encrypted]") IF_NOT_LONG_OPTS("[-m|-e]") @@ -22,6 +38,8 @@ //TODO: implement -c ALGO +#include "libbb.h" + #if ENABLE_LONG_OPTS static const char chpasswd_longopts[] ALIGN1 = "encrypted\0" No_argument "e" diff --git a/loginutils/cryptpw.c b/loginutils/cryptpw.c index 29f0fbe91..55dcc2914 100644 --- a/loginutils/cryptpw.c +++ b/loginutils/cryptpw.c @@ -9,6 +9,18 @@ * * Licensed under GPLv2, see file LICENSE in this source tree. */ +//config:config CRYPTPW +//config: bool "cryptpw" +//config: default y +//config: help +//config: Encrypts the given password with the crypt(3) libc function +//config: using the given salt. Debian has this utility under mkpasswd +//config: name. Busybox provides mkpasswd as an alias for cryptpw. + +//applet:IF_CRYPTPW(APPLET(cryptpw, BB_DIR_USR_BIN, BB_SUID_DROP)) +//applet:IF_CRYPTPW(APPLET_ODDNAME(mkpasswd, cryptpw, BB_DIR_USR_BIN, BB_SUID_DROP, mkpasswd)) + +//kbuild:lib-$(CONFIG_CRYPTPW) += cryptpw.o //usage:#define cryptpw_trivial_usage //usage: "[OPTIONS] [PASSWORD] [SALT]" diff --git a/loginutils/deluser.c b/loginutils/deluser.c index 110cd6310..7c3caf9e3 100644 --- a/loginutils/deluser.c +++ b/loginutils/deluser.c @@ -7,8 +7,32 @@ * Copyright (C) 2007 by Tito Ragusa * * Licensed under GPLv2, see file LICENSE in this source tree. - * */ +//config:config DELUSER +//config: bool "deluser" +//config: default y +//config: help +//config: Utility for deleting a user account. +//config: +//config:config DELGROUP +//config: bool "delgroup" +//config: default y +//config: help +//config: Utility for deleting a group account. +//config: +//config:config FEATURE_DEL_USER_FROM_GROUP +//config: bool "Support for removing users from groups" +//config: default y +//config: depends on DELGROUP +//config: help +//config: If called with two non-option arguments, deluser +//config: or delgroup will remove an user from a specified group. + +//applet:IF_DELUSER(APPLET(deluser, BB_DIR_USR_SBIN, BB_SUID_DROP)) +//applet:IF_DELGROUP(APPLET_ODDNAME(delgroup, deluser, BB_DIR_USR_SBIN, BB_SUID_DROP, delgroup)) + +//kbuild:lib-$(CONFIG_DELUSER) += deluser.o +//kbuild:lib-$(CONFIG_DELGROUP) += deluser.o //usage:#define deluser_trivial_usage //usage: IF_LONG_OPTS("[--remove-home] ") "USER" diff --git a/loginutils/getty.c b/loginutils/getty.c index 762d5c773..b10bdbdbf 100644 --- a/loginutils/getty.c +++ b/loginutils/getty.c @@ -21,6 +21,28 @@ * * Licensed under GPLv2 or later, see file LICENSE in this source tree. */ +//config:config GETTY +//config: bool "getty" +//config: default y +//config: select FEATURE_SYSLOG +//config: help +//config: getty lets you log in on a tty. It is normally invoked by init. +//config: +//config: Note that you can save a few bytes by disabling it and +//config: using login applet directly. +//config: If you need to reset tty attributes before calling login, +//config: this script approximates getty: +//config: +//config: exec /dev/$1 2>&1 || exit 1 +//config: reset +//config: stty sane; stty ispeed 38400; stty ospeed 38400 +//config: printf "%s login: " "`hostname`" +//config: read -r login +//config: exec /bin/login "$login" + +//applet:IF_GETTY(APPLET(getty, BB_DIR_SBIN, BB_SUID_DROP)) + +//kbuild:lib-$(CONFIG_GETTY) += getty.o #include "libbb.h" #include diff --git a/loginutils/login.c b/loginutils/login.c index 1700cfcb5..f1f04da19 100644 --- a/loginutils/login.c +++ b/loginutils/login.c @@ -2,6 +2,56 @@ /* * Licensed under GPLv2 or later, see file LICENSE in this source tree. */ +//config:config LOGIN +//config: bool "login" +//config: default y +//config: select FEATURE_SYSLOG +//config: help +//config: login is used when signing onto a system. +//config: +//config: Note that Busybox binary must be setuid root for this applet to +//config: work properly. +//config: +//config:config LOGIN_SESSION_AS_CHILD +//config: bool "Run logged in session in a child process" +//config: default y if PAM +//config: depends on LOGIN +//config: help +//config: Run the logged in session in a child process. This allows +//config: login to clean up things such as utmp entries or PAM sessions +//config: when the login session is complete. If you use PAM, you +//config: almost always would want this to be set to Y, else PAM session +//config: will not be cleaned up. +//config: +//config:config LOGIN_SCRIPTS +//config: bool "Support for login scripts" +//config: depends on LOGIN +//config: default y +//config: help +//config: Enable this if you want login to execute $LOGIN_PRE_SUID_SCRIPT +//config: just prior to switching from root to logged-in user. +//config: +//config:config FEATURE_NOLOGIN +//config: bool "Support for /etc/nologin" +//config: default y +//config: depends on LOGIN +//config: help +//config: The file /etc/nologin is used by (some versions of) login(1). +//config: If it exists, non-root logins are prohibited. +//config: +//config:config FEATURE_SECURETTY +//config: bool "Support for /etc/securetty" +//config: default y +//config: depends on LOGIN +//config: help +//config: The file /etc/securetty is used by (some versions of) login(1). +//config: The file contains the device names of tty lines (one per line, +//config: without leading /dev/) on which root is allowed to login. + +//applet:/* Needs to be run by root or be suid root - needs to change uid and gid: */ +//applet:IF_LOGIN(APPLET(login, BB_DIR_BIN, BB_SUID_REQUIRE)) + +//kbuild:lib-$(CONFIG_LOGIN) += login.o //usage:#define login_trivial_usage //usage: "[-p] [-h HOST] [[-f] USER]" diff --git a/loginutils/passwd.c b/loginutils/passwd.c index 150908932..73726d3e0 100644 --- a/loginutils/passwd.c +++ b/loginutils/passwd.c @@ -2,6 +2,30 @@ /* * Licensed under GPLv2 or later, see file LICENSE in this source tree. */ +//config:config PASSWD +//config: bool "passwd" +//config: default y +//config: select FEATURE_SYSLOG +//config: help +//config: passwd changes passwords for user and group accounts. A normal user +//config: may only change the password for his/her own account, the super user +//config: may change the password for any account. The administrator of a group +//config: may change the password for the group. +//config: +//config: Note that Busybox binary must be setuid root for this applet to +//config: work properly. +//config: +//config:config FEATURE_PASSWD_WEAK_CHECK +//config: bool "Check new passwords for weakness" +//config: default y +//config: depends on PASSWD +//config: help +//config: With this option passwd will refuse new passwords which are "weak". + +//applet:/* Needs to be run by root or be suid root - needs to change /etc/{passwd,shadow}: */ +//applet:IF_PASSWD(APPLET(passwd, BB_DIR_USR_BIN, BB_SUID_REQUIRE)) + +//kbuild:lib-$(CONFIG_PASSWD) += passwd.o //usage:#define passwd_trivial_usage //usage: "[OPTIONS] [USER]" diff --git a/loginutils/su.c b/loginutils/su.c index f8125054a..3c0e8c100 100644 --- a/loginutils/su.c +++ b/loginutils/su.c @@ -4,9 +4,31 @@ * * Licensed under GPLv2 or later, see file LICENSE in this source tree. */ +//config:config SU +//config: bool "su" +//config: default y +//config: select FEATURE_SYSLOG +//config: help +//config: su is used to become another user during a login session. +//config: Invoked without a username, su defaults to becoming the super user. +//config: +//config: Note that Busybox binary must be setuid root for this applet to +//config: work properly. +//config: +//config:config FEATURE_SU_SYSLOG +//config: bool "Enable su to write to syslog" +//config: default y +//config: depends on SU +//config: +//config:config FEATURE_SU_CHECKS_SHELLS +//config: bool "Enable su to check user's shell to be listed in /etc/shells" +//config: depends on SU +//config: default y -#include "libbb.h" -#include +//applet:/* Needs to be run by root or be suid root - needs to change uid and gid: */ +//applet:IF_SU(APPLET(su, BB_DIR_BIN, BB_SUID_REQUIRE)) + +//kbuild:lib-$(CONFIG_SU) += su.o //usage:#define su_trivial_usage //usage: "[OPTIONS] [-] [USER]" @@ -17,6 +39,9 @@ //usage: "\n -c CMD Command to pass to 'sh -c'" //usage: "\n -s SH Shell to use instead of user's default" +#include "libbb.h" +#include + #if ENABLE_FEATURE_SU_CHECKS_SHELLS /* Return 1 if SHELL is a restricted shell (one not returned by * getusershell), else 0, meaning it is a standard shell. */ diff --git a/loginutils/sulogin.c b/loginutils/sulogin.c index 2a2909937..19b1e304c 100644 --- a/loginutils/sulogin.c +++ b/loginutils/sulogin.c @@ -4,6 +4,18 @@ * * Licensed under GPLv2 or later, see file LICENSE in this source tree. */ +//config:config SULOGIN +//config: bool "sulogin" +//config: default y +//config: select FEATURE_SYSLOG +//config: help +//config: sulogin is invoked when the system goes into single user +//config: mode (this is done through an entry in inittab). + +//applet:/* Needs to be run by root or be suid root - needs to change uid and gid: */ +//applet:IF_SULOGIN(APPLET(sulogin, BB_DIR_SBIN, BB_SUID_DROP)) + +//kbuild:lib-$(CONFIG_SULOGIN) += sulogin.o //usage:#define sulogin_trivial_usage //usage: "[-t N] [TTY]" diff --git a/loginutils/vlock.c b/loginutils/vlock.c index 44b14e6bc..52ae607c9 100644 --- a/loginutils/vlock.c +++ b/loginutils/vlock.c @@ -13,7 +13,21 @@ * minimalistic vlock. */ /* Fixed by Erik Andersen to do passwords the tinylogin way... - * It now works with md5, sha1, etc passwords. */ + * It now works with md5, sha1, etc passwords. + */ +//config:config VLOCK +//config: bool "vlock" +//config: default y +//config: help +//config: Build the "vlock" applet which allows you to lock (virtual) terminals. +//config: +//config: Note that Busybox binary must be setuid root for this applet to +//config: work properly. + +//applet:/* Needs to be run by root or be suid root - needs to change uid and gid: */ +//applet:IF_VLOCK(APPLET(vlock, BB_DIR_USR_BIN, BB_SUID_REQUIRE)) + +//kbuild:lib-$(CONFIG_VLOCK) += vlock.o //usage:#define vlock_trivial_usage //usage: "[-a]" From 36647abcc393daf2ddd7876e6f24d9497c2a84a1 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Mon, 19 Oct 2015 01:29:20 +0200 Subject: [PATCH 023/260] chattr,lsattr: shorten help message function old new delta packed_usage 30662 30645 -17 Signed-off-by: Denys Vlasenko --- e2fsprogs/chattr.c | 10 ++++------ e2fsprogs/lsattr.c | 4 ++-- 2 files changed, 6 insertions(+), 8 deletions(-) diff --git a/e2fsprogs/chattr.c b/e2fsprogs/chattr.c index c4e2415f8..043f39591 100644 --- a/e2fsprogs/chattr.c +++ b/e2fsprogs/chattr.c @@ -22,11 +22,9 @@ //usage:#define chattr_trivial_usage //usage: "[-R] [-+=AacDdijsStTu] [-v VERSION] [FILE]..." //usage:#define chattr_full_usage "\n\n" -//usage: "Change file attributes on an ext2 fs\n" +//usage: "Change ext2 file attributes\n" //usage: "\nModifiers:" -//usage: "\n - Remove attributes" -//usage: "\n + Add attributes" -//usage: "\n = Set attributes" +//usage: "\n -,+,= Remove/add/set attributes" //usage: "\nAttributes:" //usage: "\n A Don't track atime" //usage: "\n a Append mode only" @@ -36,11 +34,11 @@ //usage: "\n i Cannot be modified (immutable)" //usage: "\n j Write all data to journal first" //usage: "\n s Zero disk storage when deleted" -//usage: "\n S Write file contents synchronously" +//usage: "\n S Write synchronously" //usage: "\n t Disable tail-merging of partial blocks with other files" //usage: "\n u Allow file to be undeleted" //usage: "\n -R Recurse" -//usage: "\n -v Set the file's version/generation number" +//usage: "\n -v VER Set version/generation number" #include "libbb.h" #include "e2fs_lib.h" diff --git a/e2fsprogs/lsattr.c b/e2fsprogs/lsattr.c index 3a7dd6b56..d2348b5f7 100644 --- a/e2fsprogs/lsattr.c +++ b/e2fsprogs/lsattr.c @@ -23,12 +23,12 @@ //usage:#define lsattr_trivial_usage //usage: "[-Radlv] [FILE]..." //usage:#define lsattr_full_usage "\n\n" -//usage: "List file attributes on an ext2 fs\n" +//usage: "List ext2 file attributes\n" //usage: "\n -R Recurse" //usage: "\n -a Don't hide entries starting with ." //usage: "\n -d List directory entries instead of contents" //usage: "\n -l List long flag names" -//usage: "\n -v List the file's version/generation number" +//usage: "\n -v List version/generation number" #include "libbb.h" #include "e2fs_lib.h" From c4fb8c6ad52e8007c6fa07e40f043bb2e0c043d1 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Mon, 19 Oct 2015 02:24:14 +0200 Subject: [PATCH 024/260] fsck: do not use statics function old new delta fsck_main 1794 1812 +18 packed_usage 30662 30664 +2 kill_all_if_got_signal 60 62 +2 create_fs_device 158 160 +2 static.kill_sent 1 - -1 skip_root 1 - -1 serialize 1 - -1 parallel_root 1 - -1 noexecute 1 - -1 fs_type_negated 1 - -1 force_all_parallel 1 - -1 verbose 4 - -4 num_running 4 - -4 num_args 4 - -4 max_running 4 - -4 instance_list 4 - -4 fstype 4 - -4 fs_type_list 4 - -4 fs_type_flag 4 - -4 filesys_last 4 - -4 filesys_info 4 - -4 args 4 - -4 wait_one 309 300 -9 ignore 196 174 -22 ------------------------------------------------------------------------------ (add/remove: 0/18 grow/shrink: 4/2 up/down: 24/-82) Total: -58 bytes text data bss dec hex filename 938527 932 17448 956907 e99eb busybox_old 938487 932 17392 956811 e998b busybox_unstripped Signed-off-by: Denys Vlasenko --- e2fsprogs/fsck.c | 259 ++++++++++++++++++++++++----------------------- 1 file changed, 132 insertions(+), 127 deletions(-) diff --git a/e2fsprogs/fsck.c b/e2fsprogs/fsck.c index adaf0c538..627d2be31 100644 --- a/e2fsprogs/fsck.c +++ b/e2fsprogs/fsck.c @@ -46,7 +46,7 @@ //kbuild:lib-$(CONFIG_FSCK) += fsck.o //usage:#define fsck_trivial_usage -//usage: "[-ANPRTV] [-C FD] [-t FSTYPE] [FS_OPTS] [BLOCKDEV]..." +//usage: "[-ANPRTV] [-t FSTYPE] [FS_OPTS] [BLOCKDEV]..." //usage:#define fsck_full_usage "\n\n" //usage: "Check and repair filesystems\n" //usage: "\n -A Walk /etc/fstab and check all filesystems" @@ -55,7 +55,8 @@ //usage: "\n -R With -A, skip the root filesystem" //usage: "\n -T Don't show title on startup" //usage: "\n -V Verbose" -//usage: "\n -C n Write status information to specified filedescriptor" +//DO_PROGRESS_INDICATOR is off: +////usage: "\n -C FD Write status information to specified file descriptor" //usage: "\n -t TYPE List of filesystem types to check" #include "libbb.h" @@ -136,35 +137,42 @@ static const char really_wanted[] ALIGN1 = #define BASE_MD "/dev/md" -static char **args; -static int num_args; -static int verbose; +struct globals { + char **args; + int num_args; + int verbose; #define FS_TYPE_FLAG_NORMAL 0 #define FS_TYPE_FLAG_OPT 1 #define FS_TYPE_FLAG_NEGOPT 2 -static char **fs_type_list; -static uint8_t *fs_type_flag; -static smallint fs_type_negated; + char **fs_type_list; + uint8_t *fs_type_flag; + smallint fs_type_negated; -static smallint noexecute; -static smallint serialize; -static smallint skip_root; -/* static smallint like_mount; */ -static smallint parallel_root; -static smallint force_all_parallel; + smallint noexecute; + smallint serialize; + smallint skip_root; + /* smallint like_mount; */ + smallint parallel_root; + smallint force_all_parallel; + smallint kill_sent; #if DO_PROGRESS_INDICATOR -static smallint progress; -static int progress_fd; + smallint progress; + int progress_fd; #endif -static int num_running; -static int max_running; -static char *fstype; -static struct fs_info *filesys_info; -static struct fs_info *filesys_last; -static struct fsck_instance *instance_list; + int num_running; + int max_running; + char *fstype; + struct fs_info *filesys_info; + struct fs_info *filesys_last; + struct fsck_instance *instance_list; +} FIX_ALIASING; +#define G (*(struct globals*)&bb_common_bufsiz1) +#define INIT_G() do { \ + BUILD_BUG_ON(sizeof(G) > COMMON_BUFSIZE); \ +} while (0) /* * Return the "base device" given a particular device; this is used to @@ -313,11 +321,11 @@ static struct fs_info *create_fs_device(const char *device, const char *mntpnt, /*fs->flags = 0; */ /*fs->next = NULL; */ - if (!filesys_info) - filesys_info = fs; + if (!G.filesys_info) + G.filesys_info = fs; else - filesys_last->next = fs; - filesys_last = fs; + G.filesys_last->next = fs; + G.filesys_last = fs; return fs; } @@ -327,6 +335,7 @@ static void load_fs_info(const char *filename) { FILE *fstab; struct mntent mte; + char buf[1024]; fstab = setmntent(filename, "r"); if (!fstab) { @@ -335,7 +344,7 @@ static void load_fs_info(const char *filename) } // Loop through entries - while (getmntent_r(fstab, &mte, bb_common_bufsiz1, COMMON_BUFSIZE)) { + while (getmntent_r(fstab, &mte, buf, sizeof(buf))) { //bb_info_msg("CREATE[%s][%s][%s][%s][%d]", mte.mnt_fsname, mte.mnt_dir, // mte.mnt_type, mte.mnt_opts, // mte.mnt_passno); @@ -351,7 +360,7 @@ static struct fs_info *lookup(char *filesys) { struct fs_info *fs; - for (fs = filesys_info; fs; fs = fs->next) { + for (fs = G.filesys_info; fs; fs = fs->next) { if (strcmp(filesys, fs->device) == 0 || (fs->mountpt && strcmp(filesys, fs->mountpt) == 0) ) @@ -366,7 +375,7 @@ static int progress_active(void) { struct fsck_instance *inst; - for (inst = instance_list; inst; inst = inst->next) { + for (inst = G.instance_list; inst; inst = inst->next) { if (inst->flags & FLAG_DONE) continue; if (inst->flags & FLAG_PROGRESS) @@ -382,19 +391,17 @@ static int progress_active(void) */ static void kill_all_if_got_signal(void) { - static smallint kill_sent; - struct fsck_instance *inst; - if (!bb_got_signal || kill_sent) + if (!bb_got_signal || G.kill_sent) return; - for (inst = instance_list; inst; inst = inst->next) { + for (inst = G.instance_list; inst; inst = inst->next) { if (inst->flags & FLAG_DONE) continue; kill(inst->pid, SIGTERM); } - kill_sent = 1; + G.kill_sent = 1; } /* @@ -409,9 +416,9 @@ static int wait_one(int flags) struct fsck_instance *inst, *prev; pid_t pid; - if (!instance_list) + if (!G.instance_list) return -1; - /* if (noexecute) { already returned -1; } */ + /* if (G.noexecute) { already returned -1; } */ while (1) { pid = waitpid(-1, &status, flags); @@ -429,7 +436,7 @@ static int wait_one(int flags) continue; } prev = NULL; - inst = instance_list; + inst = G.instance_list; do { if (inst->pid == pid) goto child_died; @@ -439,9 +446,8 @@ static int wait_one(int flags) } child_died: - if (WIFEXITED(status)) - status = WEXITSTATUS(status); - else if (WIFSIGNALED(status)) { + status = WEXITSTATUS(status); + if (WIFSIGNALED(status)) { sig = WTERMSIG(status); status = EXIT_UNCORRECTED; if (sig != SIGINT) { @@ -450,16 +456,12 @@ static int wait_one(int flags) inst->prog, inst->device, sig); status = EXIT_ERROR; } - } else { - printf("%s %s: status is %x, should never happen\n", - inst->prog, inst->device, status); - status = EXIT_ERROR; } #if DO_PROGRESS_INDICATOR if (progress && (inst->flags & FLAG_PROGRESS) && !progress_active()) { struct fsck_instance *inst2; - for (inst2 = instance_list; inst2; inst2 = inst2->next) { + for (inst2 = G.instance_list; inst2; inst2 = inst2->next) { if (inst2->flags & FLAG_DONE) continue; if (strcmp(inst2->type, "ext2") != 0 @@ -486,11 +488,11 @@ static int wait_one(int flags) if (prev) prev->next = inst->next; else - instance_list = inst->next; - if (verbose > 1) + G.instance_list = inst->next; + if (G.verbose > 1) printf("Finished with %s (exit status %d)\n", inst->device, status); - num_running--; + G.num_running--; free_instance(inst); return status; @@ -526,51 +528,51 @@ static void execute(const char *type, const char *device, struct fsck_instance *inst; pid_t pid; - args[0] = xasprintf("fsck.%s", type); + G.args[0] = xasprintf("fsck.%s", type); #if DO_PROGRESS_INDICATOR if (progress && !progress_active()) { if (strcmp(type, "ext2") == 0 || strcmp(type, "ext3") == 0 ) { - args[XXX] = xasprintf("-C%d", progress_fd); /* 1 */ + G.args[XXX] = xasprintf("-C%d", progress_fd); /* 1 */ inst->flags |= FLAG_PROGRESS; } } #endif - args[num_args - 2] = (char*)device; - /* args[num_args - 1] = NULL; - already is */ + G.args[G.num_args - 2] = (char*)device; + /* G.args[G.num_args - 1] = NULL; - already is */ - if (verbose || noexecute) { - printf("[%s (%d) -- %s]", args[0], num_running, + if (G.verbose || G.noexecute) { + printf("[%s (%d) -- %s]", G.args[0], G.num_running, mntpt ? mntpt : device); - for (i = 0; args[i]; i++) - printf(" %s", args[i]); + for (i = 0; G.args[i]; i++) + printf(" %s", G.args[i]); bb_putchar('\n'); } /* Fork and execute the correct program. */ pid = -1; - if (!noexecute) { - pid = spawn(args); + if (!G.noexecute) { + pid = spawn(G.args); if (pid < 0) - bb_simple_perror_msg(args[0]); + bb_simple_perror_msg(G.args[0]); } #if DO_PROGRESS_INDICATOR - free(args[XXX]); + free(G.args[XXX]); #endif /* No child, so don't record an instance */ if (pid <= 0) { - free(args[0]); + free(G.args[0]); return; } inst = xzalloc(sizeof(*inst)); inst->pid = pid; - inst->prog = args[0]; + inst->prog = G.args[0]; inst->device = xstrdup(device); inst->base_device = base_device(device); #if DO_PROGRESS_INDICATOR @@ -579,8 +581,8 @@ static void execute(const char *type, const char *device, /* Add to the list of running fsck's. * (was adding to the end, but adding to the front is simpler...) */ - inst->next = instance_list; - instance_list = inst; + inst->next = G.instance_list; + G.instance_list = inst; } /* @@ -599,27 +601,27 @@ static void fsck_device(struct fs_info *fs /*, int interactive */) if (strcmp(fs->type, "auto") != 0) { type = fs->type; - if (verbose > 2) + if (G.verbose > 2) bb_info_msg("using filesystem type '%s' %s", type, "from fstab"); - } else if (fstype - && (fstype[0] != 'n' || fstype[1] != 'o') /* != "no" */ - && !is_prefixed_with(fstype, "opts=") - && !is_prefixed_with(fstype, "loop") - && !strchr(fstype, ',') + } else if (G.fstype + && (G.fstype[0] != 'n' || G.fstype[1] != 'o') /* != "no" */ + && !is_prefixed_with(G.fstype, "opts=") + && !is_prefixed_with(G.fstype, "loop") + && !strchr(G.fstype, ',') ) { - type = fstype; - if (verbose > 2) + type = G.fstype; + if (G.verbose > 2) bb_info_msg("using filesystem type '%s' %s", type, "from -t"); } else { type = "auto"; - if (verbose > 2) + if (G.verbose > 2) bb_info_msg("using filesystem type '%s' %s", type, "(default)"); } - num_running++; + G.num_running++; execute(type, fs->device, fs->mountpt /*, interactive */); } @@ -632,13 +634,13 @@ static int device_already_active(char *device) struct fsck_instance *inst; char *base; - if (force_all_parallel) + if (G.force_all_parallel) return 0; #ifdef BASE_MD /* Don't check a soft raid disk with any other disk */ - if (instance_list - && (is_prefixed_with(instance_list->device, BASE_MD) + if (G.instance_list + && (is_prefixed_with(G.instance_list->device, BASE_MD) || is_prefixed_with(device, BASE_MD)) ) { return 1; @@ -651,9 +653,9 @@ static int device_already_active(char *device) * already active if there are any fsck instances running. */ if (!base) - return (instance_list != NULL); + return (G.instance_list != NULL); - for (inst = instance_list; inst; inst = inst->next) { + for (inst = G.instance_list; inst; inst = inst->next) { if (!inst->base_device || !strcmp(base, inst->base_device)) { free(base); return 1; @@ -698,17 +700,17 @@ static int fs_match(struct fs_info *fs) int n, ret, checked_type; char *cp; - if (!fs_type_list) + if (!G.fs_type_list) return 1; ret = 0; checked_type = 0; n = 0; while (1) { - cp = fs_type_list[n]; + cp = G.fs_type_list[n]; if (!cp) break; - switch (fs_type_flag[n]) { + switch (G.fs_type_flag[n]) { case FS_TYPE_FLAG_NORMAL: checked_type++; if (strcmp(cp, fs->type) == 0) @@ -728,7 +730,7 @@ static int fs_match(struct fs_info *fs) if (checked_type == 0) return 1; - return (fs_type_negated ? !ret : ret); + return (G.fs_type_negated ? !ret : ret); } /* Check if we should ignore this filesystem. */ @@ -764,7 +766,7 @@ static int check_all(void) smallint pass_done; int passno; - if (verbose) + if (G.verbose) puts("Checking all filesystems"); /* @@ -772,17 +774,17 @@ static int check_all(void) * which should be ignored as done, and resolve any "auto" * filesystem types (done as a side-effect of calling ignore()). */ - for (fs = filesys_info; fs; fs = fs->next) + for (fs = G.filesys_info; fs; fs = fs->next) if (ignore(fs)) fs->flags |= FLAG_DONE; /* * Find and check the root filesystem. */ - if (!parallel_root) { - for (fs = filesys_info; fs; fs = fs->next) { + if (!G.parallel_root) { + for (fs = G.filesys_info; fs; fs = fs->next) { if (LONE_CHAR(fs->mountpt, '/')) { - if (!skip_root && !ignore(fs)) { + if (!G.skip_root && !ignore(fs)) { fsck_device(fs /*, 1*/); status |= wait_many(FLAG_WAIT_ALL); if (status > EXIT_NONDESTRUCT) @@ -798,8 +800,8 @@ static int check_all(void) * filesystem listed twice. * "Skip root" will skip _all_ root entries. */ - if (skip_root) - for (fs = filesys_info; fs; fs = fs->next) + if (G.skip_root) + for (fs = G.filesys_info; fs; fs = fs->next) if (LONE_CHAR(fs->mountpt, '/')) fs->flags |= FLAG_DONE; @@ -809,7 +811,7 @@ static int check_all(void) not_done_yet = 0; pass_done = 1; - for (fs = filesys_info; fs; fs = fs->next) { + for (fs = G.filesys_info; fs; fs = fs->next) { if (bb_got_signal) break; if (fs->flags & FLAG_DONE) @@ -835,7 +837,7 @@ static int check_all(void) /* * Spawn off the fsck process */ - fsck_device(fs /*, serialize*/); + fsck_device(fs /*, G.serialize*/); fs->flags |= FLAG_DONE; /* @@ -843,8 +845,8 @@ static int check_all(void) * have a limit on the number of fsck's extant * at one time, apply that limit. */ - if (serialize - || (max_running && (num_running >= max_running)) + if (G.serialize + || (G.num_running >= G.max_running) ) { pass_done = 0; break; @@ -852,12 +854,12 @@ static int check_all(void) } if (bb_got_signal) break; - if (verbose > 1) + if (G.verbose > 1) printf("--waiting-- (pass %d)\n", passno); status |= wait_many(pass_done ? FLAG_WAIT_ALL : FLAG_WAIT_ATLEAST_ONE); if (pass_done) { - if (verbose > 1) + if (G.verbose > 1) puts("----------------------------------"); passno++; } else @@ -885,9 +887,9 @@ static void compile_fs_type(char *fs_type) s++; } - fs_type_list = xzalloc(num * sizeof(fs_type_list[0])); - fs_type_flag = xzalloc(num * sizeof(fs_type_flag[0])); - fs_type_negated = -1; /* not yet known is it negated or not */ + G.fs_type_list = xzalloc(num * sizeof(G.fs_type_list[0])); + G.fs_type_flag = xzalloc(num * sizeof(G.fs_type_flag[0])); + G.fs_type_negated = -1; /* not yet known is it negated or not */ num = 0; s = fs_type; @@ -909,18 +911,18 @@ static void compile_fs_type(char *fs_type) if (is_prefixed_with(s, "opts=")) { s += 5; loop_special_case: - fs_type_flag[num] = negate ? FS_TYPE_FLAG_NEGOPT : FS_TYPE_FLAG_OPT; + G.fs_type_flag[num] = negate ? FS_TYPE_FLAG_NEGOPT : FS_TYPE_FLAG_OPT; } else { - if (fs_type_negated == -1) - fs_type_negated = negate; - if (fs_type_negated != negate) + if (G.fs_type_negated == -1) + G.fs_type_negated = negate; + if (G.fs_type_negated != negate) bb_error_msg_and_die( "either all or none of the filesystem types passed to -t must be prefixed " "with 'no' or '!'"); } - comma = strchr(s, ','); - fs_type_list[num++] = comma ? xstrndup(s, comma-s) : xstrdup(s); - if (!comma) + comma = strchrnul(s, ','); + G.fs_type_list[num++] = xstrndup(s, comma-s); + if (*comma == '\0') break; s = comma + 1; } @@ -928,8 +930,8 @@ static void compile_fs_type(char *fs_type) static char **new_args(void) { - args = xrealloc_vector(args, 2, num_args); - return &args[num_args++]; + G.args = xrealloc_vector(G.args, 2, G.num_args); + return &G.args[G.num_args++]; } int fsck_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; @@ -946,6 +948,8 @@ int fsck_main(int argc UNUSED_PARAM, char **argv) smallint doall; smallint notitle; + INIT_G(); + /* we want wait() to be interruptible */ signal_no_SA_RESTART_empty_mask(SIGINT, record_signo); signal_no_SA_RESTART_empty_mask(SIGTERM, record_signo); @@ -955,8 +959,8 @@ int fsck_main(int argc UNUSED_PARAM, char **argv) opts_for_fsck = doall = notitle = 0; devices = NULL; num_devices = 0; - new_args(); /* args[0] = NULL, will be replaced by fsck. */ - /* instance_list = NULL; - in bss, so already zeroed */ + new_args(); /* G.args[0] = NULL, will be replaced by fsck. */ + /* G.instance_list = NULL; - in bss, so already zeroed */ while (*++argv) { int j; @@ -1005,13 +1009,13 @@ int fsck_main(int argc UNUSED_PARAM, char **argv) goto next_arg; #endif case 'V': - verbose++; + G.verbose++; break; case 'N': - noexecute = 1; + G.noexecute = 1; break; case 'R': - skip_root = 1; + G.skip_root = 1; break; case 'T': notitle = 1; @@ -1020,13 +1024,13 @@ int fsck_main(int argc UNUSED_PARAM, char **argv) like_mount = 1; break; */ case 'P': - parallel_root = 1; + G.parallel_root = 1; break; case 's': - serialize = 1; + G.serialize = 1; break; case 't': - if (fstype) + if (G.fstype) bb_show_usage(); if (arg[++j]) tmp = &arg[j]; @@ -1034,8 +1038,8 @@ int fsck_main(int argc UNUSED_PARAM, char **argv) tmp = *argv; else bb_show_usage(); - fstype = xstrdup(tmp); - compile_fs_type(fstype); + G.fstype = xstrdup(tmp); + compile_fs_type(G.fstype); goto next_arg; case '?': bb_show_usage(); @@ -1056,12 +1060,13 @@ int fsck_main(int argc UNUSED_PARAM, char **argv) } } if (getenv("FSCK_FORCE_ALL_PARALLEL")) - force_all_parallel = 1; + G.force_all_parallel = 1; tmp = getenv("FSCK_MAX_INST"); + G.max_running = INT_MAX; if (tmp) - max_running = xatoi(tmp); - new_args(); /* args[num_args - 2] will be replaced by */ - new_args(); /* args[num_args - 1] is the last, NULL element */ + G.max_running = xatoi(tmp); + new_args(); /* G.args[G.num_args - 2] will be replaced by */ + new_args(); /* G.args[G.num_args - 1] is the last, NULL element */ if (!notitle) puts("fsck (busybox "BB_VER", "BB_BT")"); @@ -1073,10 +1078,10 @@ int fsck_main(int argc UNUSED_PARAM, char **argv) fstab = "/etc/fstab"; load_fs_info(fstab); - /*interactive = (num_devices == 1) | serialize;*/ + /*interactive = (num_devices == 1) | G.serialize;*/ if (num_devices == 0) - /*interactive =*/ serialize = doall = 1; + /*interactive =*/ G.serialize = doall = 1; if (doall) return check_all(); @@ -1092,13 +1097,13 @@ int fsck_main(int argc UNUSED_PARAM, char **argv) fs = create_fs_device(devices[i], "", "auto", NULL, -1); fsck_device(fs /*, interactive */); - if (serialize - || (max_running && (num_running >= max_running)) + if (G.serialize + || (G.num_running >= G.max_running) ) { int exit_status = wait_one(0); if (exit_status >= 0) status |= exit_status; - if (verbose > 1) + if (G.verbose > 1) puts("----------------------------------"); } } From f3d58a29be7cbf5c0bf94f1a12ac747f706b3d99 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Mon, 19 Oct 2015 02:51:56 +0200 Subject: [PATCH 025/260] od: get rid of (almost all) statics function old new delta od_main 2565 2600 +35 check_and_close 113 115 +2 static.prev_pair_equal 1 - -1 static.first 1 - -1 exit_code 1 - -1 string_min 4 - -4 n_specs 4 - -4 in_stream 4 - -4 format_address 4 - -4 file_list 4 - -4 bytes_per_block 4 - -4 get_lcm 120 115 -5 pseudo_offset 8 - -8 ------------------------------------------------------------------------------ (add/remove: 0/10 grow/shrink: 2/1 up/down: 37/-40) Total: -3 bytes text data bss dec hex filename 938487 932 17392 956811 e998b busybox_old 938519 924 17360 956803 e9983 busybox_unstripped Signed-off-by: Denys Vlasenko --- coreutils/od_bloaty.c | 226 ++++++++++++++++++++++-------------------- 1 file changed, 120 insertions(+), 106 deletions(-) diff --git a/coreutils/od_bloaty.c b/coreutils/od_bloaty.c index ab7ea997d..f47f84b54 100644 --- a/coreutils/od_bloaty.c +++ b/coreutils/od_bloaty.c @@ -66,7 +66,7 @@ enum { /* -S was -s and also had optional parameter */ \ /* but in coreutils 6.3 it was renamed and now has */ \ /* _mandatory_ parameter */ \ - &str_A, &str_N, &str_j, &lst_t, &str_S, &bytes_per_block) + &str_A, &str_N, &str_j, &lst_t, &str_S, &G.bytes_per_block) /* Check for 0x7f is a coreutils 6.3 addition */ @@ -174,38 +174,52 @@ struct ERR_width_bytes_has_bad_size { char ERR_width_bytes_has_bad_size[ARRAY_SIZE(width_bytes) == N_SIZE_SPECS ? 1 : -1]; }; -static smallint exit_code; +struct globals { + smallint exit_code; -static unsigned string_min; + unsigned string_min; -/* An array of specs describing how to format each input block. */ -static size_t n_specs; -static struct tspec *spec; + /* An array of specs describing how to format each input block. */ + unsigned n_specs; + struct tspec *spec; -/* Function that accepts an address and an optional following char, - and prints the address and char to stdout. */ -static void (*format_address)(off_t, char); -/* The difference between the old-style pseudo starting address and - the number of bytes to skip. */ + /* Function that accepts an address and an optional following char, + and prints the address and char to stdout. */ + void (*format_address)(off_t, char); + + /* The difference between the old-style pseudo starting address and + the number of bytes to skip. */ #if ENABLE_LONG_OPTS -static off_t pseudo_offset; -#else -enum { pseudo_offset = 0 }; + off_t pseudo_offset; +# define G_pseudo_offset G.pseudo_offset #endif -/* When zero, MAX_BYTES_TO_FORMAT and END_OFFSET are ignored, and all - input is formatted. */ + /* When zero, MAX_BYTES_TO_FORMAT and END_OFFSET are ignored, and all + input is formatted. */ -/* The number of input bytes formatted per output line. It must be - a multiple of the least common multiple of the sizes associated with - the specified output types. It should be as large as possible, but - no larger than 16 -- unless specified with the -w option. */ -static unsigned bytes_per_block = 32; /* have to use unsigned, not size_t */ + /* The number of input bytes formatted per output line. It must be + a multiple of the least common multiple of the sizes associated with + the specified output types. It should be as large as possible, but + no larger than 16 -- unless specified with the -w option. */ + unsigned bytes_per_block; /* have to use unsigned, not size_t */ -/* A NULL-terminated list of the file-arguments from the command line. */ -static const char *const *file_list; + /* A NULL-terminated list of the file-arguments from the command line. */ + const char *const *file_list; + + /* The input stream associated with the current file. */ + FILE *in_stream; + + bool not_first; + bool prev_pair_equal; +} FIX_ALIASING; +#if !ENABLE_LONG_OPTS +enum { G_pseudo_offset = 0 }; +#endif +#define G (*(struct globals*)&bb_common_bufsiz1) +#define INIT_G() do { \ + BUILD_BUG_ON(sizeof(G) > COMMON_BUFSIZE); \ + G.bytes_per_block = 32; \ +} while (0) -/* The input stream associated with the current file. */ -static FILE *in_stream; #define MAX_INTEGRAL_TYPE_SIZE sizeof(ulonglong_t) static const unsigned char integral_type_size[MAX_INTEGRAL_TYPE_SIZE + 1] ALIGN1 = { @@ -476,17 +490,17 @@ static void open_next_file(void) { while (1) { - if (!*file_list) + if (!*G.file_list) return; - in_stream = fopen_or_warn_stdin(*file_list++); - if (in_stream) { + G.in_stream = fopen_or_warn_stdin(*G.file_list++); + if (G.in_stream) { break; } - exit_code = 1; + G.exit_code = 1; } if ((option_mask32 & (OPT_N|OPT_S)) == OPT_N) - setbuf(in_stream, NULL); + setbuf(G.in_stream, NULL); } /* Test whether there have been errors on in_stream, and close it if @@ -499,16 +513,16 @@ open_next_file(void) static void check_and_close(void) { - if (in_stream) { - if (ferror(in_stream)) { - bb_error_msg("%s: read error", (in_stream == stdin) + if (G.in_stream) { + if (ferror(G.in_stream)) { + bb_error_msg("%s: read error", (G.in_stream == stdin) ? bb_msg_standard_input - : file_list[-1] + : G.file_list[-1] ); - exit_code = 1; + G.exit_code = 1; } - fclose_if_not_stdin(in_stream); - in_stream = NULL; + fclose_if_not_stdin(G.in_stream); + G.in_stream = NULL; } if (ferror(stdout)) { @@ -744,9 +758,9 @@ decode_format_string(const char *s) assert(s != next); s = next; - spec = xrealloc_vector(spec, 4, n_specs); - memcpy(&spec[n_specs], &tspec, sizeof(spec[0])); - n_specs++; + G.spec = xrealloc_vector(G.spec, 4, G.n_specs); + memcpy(&G.spec[G.n_specs], &tspec, sizeof(G.spec[0])); + G.n_specs++; } } @@ -763,7 +777,7 @@ skip(off_t n_skip) if (n_skip == 0) return; - while (in_stream) { /* !EOF */ + while (G.in_stream) { /* !EOF */ struct stat file_stats; /* First try seeking. For large offsets, this extra work is @@ -781,15 +795,15 @@ skip(off_t n_skip) If the number of bytes left to skip is at least as large as the size of the current file, we can decrement n_skip and go on to the next file. */ - if (fstat(fileno(in_stream), &file_stats) == 0 + if (fstat(fileno(G.in_stream), &file_stats) == 0 && S_ISREG(file_stats.st_mode) && file_stats.st_size > 0 ) { if (file_stats.st_size < n_skip) { n_skip -= file_stats.st_size; /* take "check & close / open_next" route */ } else { - if (fseeko(in_stream, n_skip, SEEK_CUR) != 0) - exit_code = 1; + if (fseeko(G.in_stream, n_skip, SEEK_CUR) != 0) + G.exit_code = 1; return; } } else { @@ -802,7 +816,7 @@ skip(off_t n_skip) while (n_skip > 0) { if (n_skip < n_bytes_to_read) n_bytes_to_read = n_skip; - n_bytes_read = fread(buf, 1, n_bytes_to_read, in_stream); + n_bytes_read = fread(buf, 1, n_bytes_to_read, G.in_stream); n_skip -= n_bytes_read; if (n_bytes_read != n_bytes_to_read) break; /* EOF on this file or error */ @@ -855,7 +869,7 @@ static void format_address_label(off_t address, char c) { format_address_std(address, ' '); - format_address_paren(address + pseudo_offset, c); + format_address_paren(address + G_pseudo_offset, c); } #endif @@ -886,36 +900,34 @@ static void write_block(off_t current_offset, size_t n_bytes, const char *prev_block, const char *curr_block) { - static char first = 1; - static char prev_pair_equal = 0; - size_t i; + unsigned i; if (!(option_mask32 & OPT_v) - && !first - && n_bytes == bytes_per_block - && memcmp(prev_block, curr_block, bytes_per_block) == 0 + && G.not_first + && n_bytes == G.bytes_per_block + && memcmp(prev_block, curr_block, G.bytes_per_block) == 0 ) { - if (prev_pair_equal) { + if (G.prev_pair_equal) { /* The two preceding blocks were equal, and the current block is the same as the last one, so print nothing. */ } else { puts("*"); - prev_pair_equal = 1; + G.prev_pair_equal = 1; } } else { - first = 0; - prev_pair_equal = 0; - for (i = 0; i < n_specs; i++) { + G.not_first = 1; + G.prev_pair_equal = 0; + for (i = 0; i < G.n_specs; i++) { if (i == 0) - format_address(current_offset, '\0'); + G.format_address(current_offset, '\0'); else printf("%*s", address_pad_len_char - '0', ""); - (*spec[i].print_function) (n_bytes, curr_block, spec[i].fmt_string); - if (spec[i].hexl_mode_trailer) { + (*G.spec[i].print_function) (n_bytes, curr_block, G.spec[i].fmt_string); + if (G.spec[i].hexl_mode_trailer) { /* space-pad out to full line width, then dump the trailer */ - unsigned datum_width = width_bytes[spec[i].size]; - unsigned blank_fields = (bytes_per_block - n_bytes) / datum_width; - unsigned field_width = spec[i].field_width + 1; + unsigned datum_width = width_bytes[G.spec[i].size]; + unsigned blank_fields = (G.bytes_per_block - n_bytes) / datum_width; + unsigned field_width = G.spec[i].field_width + 1; printf("%*s", blank_fields * field_width, ""); dump_hexl_mode_trailer(n_bytes, curr_block); } @@ -927,19 +939,19 @@ write_block(off_t current_offset, size_t n_bytes, static void read_block(size_t n, char *block, size_t *n_bytes_in_buffer) { - assert(0 < n && n <= bytes_per_block); + assert(0 < n && n <= G.bytes_per_block); *n_bytes_in_buffer = 0; if (n == 0) return; - while (in_stream != NULL) { /* EOF. */ + while (G.in_stream != NULL) { /* EOF. */ size_t n_needed; size_t n_read; n_needed = n - *n_bytes_in_buffer; - n_read = fread(block + *n_bytes_in_buffer, 1, n_needed, in_stream); + n_read = fread(block + *n_bytes_in_buffer, 1, n_needed, G.in_stream); *n_bytes_in_buffer += n_read; if (n_read == n_needed) break; @@ -958,8 +970,8 @@ get_lcm(void) size_t i; int l_c_m = 1; - for (i = 0; i < n_specs; i++) - l_c_m = lcm(l_c_m, width_bytes[(int) spec[i].size]); + for (i = 0; i < G.n_specs; i++) + l_c_m = lcm(l_c_m, width_bytes[(int) G.spec[i].size]); return l_c_m; } @@ -980,8 +992,8 @@ dump(off_t current_offset, off_t end_offset) int idx; size_t n_bytes_read; - block[0] = xmalloc(2 * bytes_per_block); - block[1] = block[0] + bytes_per_block; + block[0] = xmalloc(2 * G.bytes_per_block); + block[1] = block[0] + G.bytes_per_block; idx = 0; if (option_mask32 & OPT_N) { @@ -991,21 +1003,21 @@ dump(off_t current_offset, off_t end_offset) n_bytes_read = 0; break; } - n_needed = MIN(end_offset - current_offset, (off_t) bytes_per_block); + n_needed = MIN(end_offset - current_offset, (off_t) G.bytes_per_block); read_block(n_needed, block[idx], &n_bytes_read); - if (n_bytes_read < bytes_per_block) + if (n_bytes_read < G.bytes_per_block) break; - assert(n_bytes_read == bytes_per_block); + assert(n_bytes_read == G.bytes_per_block); write_block(current_offset, n_bytes_read, block[idx ^ 1], block[idx]); current_offset += n_bytes_read; idx ^= 1; } } else { while (1) { - read_block(bytes_per_block, block[idx], &n_bytes_read); - if (n_bytes_read < bytes_per_block) + read_block(G.bytes_per_block, block[idx], &n_bytes_read); + if (n_bytes_read < G.bytes_per_block) break; - assert(n_bytes_read == bytes_per_block); + assert(n_bytes_read == G.bytes_per_block); write_block(current_offset, n_bytes_read, block[idx ^ 1], block[idx]); current_offset += n_bytes_read; idx ^= 1; @@ -1028,7 +1040,7 @@ dump(off_t current_offset, off_t end_offset) current_offset += n_bytes_read; } - format_address(current_offset, '\n'); + G.format_address(current_offset, '\n'); if ((option_mask32 & OPT_N) && current_offset >= end_offset) check_and_close(); @@ -1059,16 +1071,16 @@ dump(off_t current_offset, off_t end_offset) static void dump_strings(off_t address, off_t end_offset) { - unsigned bufsize = MAX(100, string_min); + unsigned bufsize = MAX(100, G.string_min); unsigned char *buf = xmalloc(bufsize); while (1) { size_t i; int c; - /* See if the next 'string_min' chars are all printing chars. */ + /* See if the next 'G.string_min' chars are all printing chars. */ tryline: - if ((option_mask32 & OPT_N) && (end_offset - string_min <= address)) + if ((option_mask32 & OPT_N) && (end_offset - G.string_min <= address)) break; i = 0; while (!(option_mask32 & OPT_N) || address < end_offset) { @@ -1077,8 +1089,8 @@ dump_strings(off_t address, off_t end_offset) buf = xrealloc(buf, bufsize); } - while (in_stream) { /* !EOF */ - c = fgetc(in_stream); + while (G.in_stream) { /* !EOF */ + c = fgetc(G.in_stream); if (c != EOF) goto got_char; check_and_close(); @@ -1095,12 +1107,12 @@ dump_strings(off_t address, off_t end_offset) buf[i++] = c; /* String continues; store it all. */ } - if (i < string_min) /* Too short! */ + if (i < G.string_min) /* Too short! */ goto tryline; /* If we get here, the string is all printable and NUL-terminated */ buf[i] = 0; - format_address(address - i - 1, ' '); + G.format_address(address - i - 1, ' '); for (i = 0; (c = buf[i]); i++) { switch (c) { @@ -1118,7 +1130,7 @@ dump_strings(off_t address, off_t end_offset) } /* We reach this point only if we search through - (max_bytes_to_format - string_min) bytes before reaching EOF. */ + (max_bytes_to_format - G.string_min) bytes before reaching EOF. */ check_and_close(); ret: free(buf); @@ -1190,8 +1202,10 @@ int od_main(int argc UNUSED_PARAM, char **argv) /* The maximum number of bytes that will be formatted. */ off_t max_bytes_to_format = 0; - spec = NULL; - format_address = format_address_std; + INIT_G(); + + /*G.spec = NULL; - already is */ + G.format_address = format_address_std; address_base_char = 'o'; address_pad_len_char = '7'; @@ -1217,7 +1231,7 @@ int od_main(int argc UNUSED_PARAM, char **argv) bb_error_msg_and_die("bad output address radix " "'%c' (must be [doxn])", str_A[0]); pos = p - doxn; - if (pos == 3) format_address = format_address_none; + if (pos == 3) G.format_address = format_address_none; address_base_char = doxn_address_base_char[pos]; address_pad_len_char = doxn_address_pad_len_char[pos]; } @@ -1240,11 +1254,11 @@ int od_main(int argc UNUSED_PARAM, char **argv) if (opt & OPT_x) decode_format_string("x2"); if (opt & OPT_s) decode_format_string("d2"); if (opt & OPT_S) { - string_min = xstrtou_sfx(str_S, 0, bkm_suffixes); + G.string_min = xstrtou_sfx(str_S, 0, bkm_suffixes); } // Bloat: - //if ((option_mask32 & OPT_S) && n_specs > 0) + //if ((option_mask32 & OPT_S) && G.n_specs > 0) // bb_error_msg_and_die("no type may be specified when dumping strings"); /* If the --traditional option is used, there may be from @@ -1300,14 +1314,14 @@ int od_main(int argc UNUSED_PARAM, char **argv) } if (pseudo_start >= 0) { - if (format_address == format_address_none) { + if (G.format_address == format_address_none) { address_base_char = 'o'; address_pad_len_char = '7'; - format_address = format_address_paren; + G.format_address = format_address_paren; } else { - format_address = format_address_label; + G.format_address = format_address_label; } - pseudo_offset = pseudo_start - n_bytes_to_skip; + G_pseudo_offset = pseudo_start - n_bytes_to_skip; } } /* else: od --traditional (without args) */ @@ -1320,45 +1334,45 @@ int od_main(int argc UNUSED_PARAM, char **argv) bb_error_msg_and_die("SKIP + SIZE is too large"); } - if (n_specs == 0) { + if (G.n_specs == 0) { decode_format_string("o2"); - /*n_specs = 1; - done by decode_format_string */ + /*G.n_specs = 1; - done by decode_format_string */ } /* If no files were listed on the command line, set the global pointer FILE_LIST so that it references the null-terminated list of one name: "-". */ - file_list = bb_argv_dash; + G.file_list = bb_argv_dash; if (argv[0]) { /* Set the global pointer FILE_LIST so that it references the first file-argument on the command-line. */ - file_list = (char const *const *) argv; + G.file_list = (char const *const *) argv; } /* Open the first input file */ open_next_file(); /* Skip over any unwanted header bytes */ skip(n_bytes_to_skip); - if (!in_stream) + if (!G.in_stream) return EXIT_FAILURE; /* Compute output block length */ l_c_m = get_lcm(); if (opt & OPT_w) { /* -w: width */ - if (!bytes_per_block || bytes_per_block % l_c_m != 0) { + if (!G.bytes_per_block || G.bytes_per_block % l_c_m != 0) { bb_error_msg("warning: invalid width %u; using %d instead", - (unsigned)bytes_per_block, l_c_m); - bytes_per_block = l_c_m; + (unsigned)G.bytes_per_block, l_c_m); + G.bytes_per_block = l_c_m; } } else { - bytes_per_block = l_c_m; + G.bytes_per_block = l_c_m; if (l_c_m < DEFAULT_BYTES_PER_BLOCK) - bytes_per_block *= DEFAULT_BYTES_PER_BLOCK / l_c_m; + G.bytes_per_block *= DEFAULT_BYTES_PER_BLOCK / l_c_m; } #ifdef DEBUG - for (i = 0; i < n_specs; i++) { + for (i = 0; i < G.n_specs; i++) { printf("%d: fmt=\"%s\" width=%d\n", i, spec[i].fmt_string, width_bytes[spec[i].size]); } @@ -1372,5 +1386,5 @@ int od_main(int argc UNUSED_PARAM, char **argv) if (fclose(stdin)) bb_perror_msg_and_die(bb_msg_standard_input); - return exit_code; + return G.exit_code; } From 526d85831e7480b9c7a3673d8dd356a438e6dd74 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Mon, 19 Oct 2015 04:27:17 +0200 Subject: [PATCH 026/260] libbb: get_uidgid() always called with allow_numeric=1 function old new delta xget_uidgid 30 25 -5 make_device 2188 2183 -5 main 797 792 -5 get_uidgid 240 225 -15 Signed-off-by: Denys Vlasenko --- include/libbb.h | 7 +++---- libbb/appletlib.c | 2 +- libpwdgrp/uidgid_get.c | 42 +++++++++++++++++++----------------------- util-linux/mdev.c | 2 +- 4 files changed, 24 insertions(+), 29 deletions(-) diff --git a/include/libbb.h b/include/libbb.h index f04f555c0..1a3f6d8ce 100644 --- a/include/libbb.h +++ b/include/libbb.h @@ -920,14 +920,13 @@ long xuname2uid(const char *name) FAST_FUNC; long xgroup2gid(const char *name) FAST_FUNC; /* wrapper: allows string to contain numeric uid or gid */ unsigned long get_ug_id(const char *s, long FAST_FUNC (*xname2id)(const char *)) FAST_FUNC; -/* from chpst. Does not die, returns 0 on failure */ struct bb_uidgid_t { uid_t uid; gid_t gid; }; -/* always sets uid and gid */ -int get_uidgid(struct bb_uidgid_t*, const char*, int numeric_ok) FAST_FUNC; -/* always sets uid and gid, allows numeric; exits on failure */ +/* always sets uid and gid; returns 0 on failure */ +int get_uidgid(struct bb_uidgid_t*, const char*) FAST_FUNC; +/* always sets uid and gid; exits on failure */ void xget_uidgid(struct bb_uidgid_t*, const char*) FAST_FUNC; /* chown-like handling of "user[:[group]" */ void parse_chown_usergroup_or_die(struct bb_uidgid_t *u, char *user_group) FAST_FUNC; diff --git a/libbb/appletlib.c b/libbb/appletlib.c index 24253cf27..0f83eda4b 100644 --- a/libbb/appletlib.c +++ b/libbb/appletlib.c @@ -437,7 +437,7 @@ static void parse_config_file(void) goto pe_label; } *e = ':'; /* get_uidgid needs USER:GROUP syntax */ - if (get_uidgid(&sct->m_ugid, s, /*allow_numeric:*/ 1) == 0) { + if (get_uidgid(&sct->m_ugid, s) == 0) { errmsg = "unknown user/group"; goto pe_label; } diff --git a/libpwdgrp/uidgid_get.c b/libpwdgrp/uidgid_get.c index 8388be0da..eeb65191f 100644 --- a/libpwdgrp/uidgid_get.c +++ b/libpwdgrp/uidgid_get.c @@ -28,7 +28,7 @@ ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include "libbb.h" /* Always sets uid and gid */ -int FAST_FUNC get_uidgid(struct bb_uidgid_t *u, const char *ug, int numeric_ok) +int FAST_FUNC get_uidgid(struct bb_uidgid_t *u, const char *ug) { struct passwd *pwd; struct group *gr; @@ -43,18 +43,16 @@ int FAST_FUNC get_uidgid(struct bb_uidgid_t *u, const char *ug, int numeric_ok) /* copies sz-1 bytes, stores terminating '\0' */ safe_strncpy(user, ug, sz); } - if (numeric_ok) { - n = bb_strtou(user, NULL, 10); - if (!errno) { - u->uid = n; - pwd = getpwuid(n); - /* If we have e.g. "500" string without user */ - /* with uid 500 in /etc/passwd, we set gid == uid */ - u->gid = pwd ? pwd->pw_gid : n; - goto skip; - } + n = bb_strtou(user, NULL, 10); + if (!errno) { + u->uid = n; + pwd = getpwuid(n); + /* If we have e.g. "500" string without user */ + /* with uid 500 in /etc/passwd, we set gid == uid */ + u->gid = pwd ? pwd->pw_gid : n; + goto skip; } - /* Either it is not numeric, or caller disallows numeric username */ + /* it is not numeric */ pwd = getpwnam(user); if (!pwd) return 0; @@ -63,12 +61,10 @@ int FAST_FUNC get_uidgid(struct bb_uidgid_t *u, const char *ug, int numeric_ok) skip: if (group) { - if (numeric_ok) { - n = bb_strtou(group, NULL, 10); - if (!errno) { - u->gid = n; - return 1; - } + n = bb_strtou(group, NULL, 10); + if (!errno) { + u->gid = n; + return 1; } gr = getgrnam(group); if (!gr) @@ -79,7 +75,7 @@ int FAST_FUNC get_uidgid(struct bb_uidgid_t *u, const char *ug, int numeric_ok) } void FAST_FUNC xget_uidgid(struct bb_uidgid_t *u, const char *ug) { - if (!get_uidgid(u, ug, 1)) + if (!get_uidgid(u, ug)) bb_error_msg_and_die("unknown user/group %s", ug); } @@ -119,16 +115,16 @@ int main() { unsigned u; struct bb_uidgid_t ug; - u = get_uidgid(&ug, "apache", 0); + u = get_uidgid(&ug, "apache"); printf("%u = %u:%u\n", u, ug.uid, ug.gid); ug.uid = ug.gid = 1111; - u = get_uidgid(&ug, "apache", 0); + u = get_uidgid(&ug, "apache"); printf("%u = %u:%u\n", u, ug.uid, ug.gid); ug.uid = ug.gid = 1111; - u = get_uidgid(&ug, "apache:users", 0); + u = get_uidgid(&ug, "apache:users"); printf("%u = %u:%u\n", u, ug.uid, ug.gid); ug.uid = ug.gid = 1111; - u = get_uidgid(&ug, "apache:users", 0); + u = get_uidgid(&ug, "apache:users"); printf("%u = %u:%u\n", u, ug.uid, ug.gid); return 0; } diff --git a/util-linux/mdev.c b/util-linux/mdev.c index 51781d597..37fa56827 100644 --- a/util-linux/mdev.c +++ b/util-linux/mdev.c @@ -400,7 +400,7 @@ static void parse_next_rule(void) } /* 2nd field: uid:gid - device ownership */ - if (get_uidgid(&G.cur_rule.ugid, tokens[1], /*allow_numeric:*/ 1) == 0) { + if (get_uidgid(&G.cur_rule.ugid, tokens[1]) == 0) { bb_error_msg("unknown user/group '%s' on line %d", tokens[1], G.parser->lineno); goto next_rule; } From 3d0805e9e7c45e6c0f9fb5e587d8b4a5a5f3c74c Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Mon, 19 Oct 2015 04:37:19 +0200 Subject: [PATCH 027/260] libbb: make parse_chown_usergroup_or_die() set unspecified uid/gid to -1 function old new delta parse_chown_usergroup_or_die 102 115 +13 chown_main 190 175 -15 start_stop_daemon_main 1043 1027 -16 ------------------------------------------------------------------------------ (add/remove: 0/0 grow/shrink: 1/2 up/down: 13/-31) Total: -18 bytes Signed-off-by: Denys Vlasenko --- coreutils/chown.c | 4 ---- debianutils/start_stop_daemon.c | 8 ++++---- libpwdgrp/uidgid_get.c | 2 ++ 3 files changed, 6 insertions(+), 8 deletions(-) diff --git a/coreutils/chown.c b/coreutils/chown.c index eaa1ee2a3..247aa3bf1 100644 --- a/coreutils/chown.c +++ b/coreutils/chown.c @@ -112,10 +112,6 @@ int chown_main(int argc UNUSED_PARAM, char **argv) int opt, flags; struct param_t param; - /* Just -1 might not work: uid_t may be unsigned long */ - param.ugid.uid = -1L; - param.ugid.gid = -1L; - #if ENABLE_FEATURE_CHOWN_LONG_OPTIONS applet_long_options = chown_longopts; #endif diff --git a/debianutils/start_stop_daemon.c b/debianutils/start_stop_daemon.c index 42f1943dd..d7c730f45 100644 --- a/debianutils/start_stop_daemon.c +++ b/debianutils/start_stop_daemon.c @@ -539,15 +539,15 @@ int start_stop_daemon_main(int argc UNUSED_PARAM, char **argv) write_pidfile(pidfile); } if (opt & OPT_c) { - struct bb_uidgid_t ugid = { -1, -1 }; + struct bb_uidgid_t ugid; parse_chown_usergroup_or_die(&ugid, chuid); - if (ugid.uid != (uid_t) -1) { + if (ugid.uid != (uid_t) -1L) { struct passwd *pw = xgetpwuid(ugid.uid); - if (ugid.gid != (gid_t) -1) + if (ugid.gid != (gid_t) -1L) pw->pw_gid = ugid.gid; /* initgroups, setgid, setuid: */ change_identity(pw); - } else if (ugid.gid != (gid_t) -1) { + } else if (ugid.gid != (gid_t) -1L) { xsetgid(ugid.gid); setgroups(1, &ugid.gid); } diff --git a/libpwdgrp/uidgid_get.c b/libpwdgrp/uidgid_get.c index eeb65191f..1199f23f9 100644 --- a/libpwdgrp/uidgid_get.c +++ b/libpwdgrp/uidgid_get.c @@ -90,6 +90,8 @@ void FAST_FUNC parse_chown_usergroup_or_die(struct bb_uidgid_t *u, char *user_gr { char *group; + u->uid = u->gid = (gid_t)-1L; + /* Check if there is a group name */ group = strchr(user_group, '.'); /* deprecated? */ if (!group) From 2e86a5c98d8cc716844eb0084adc5849a12cf0c7 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Mon, 19 Oct 2015 14:44:51 +0200 Subject: [PATCH 028/260] sort: fix key with delimiters breakage function old new delta get_key 509 505 -4 Signed-off-by: Denys Vlasenko --- coreutils/sort.c | 21 ++++++++++++++++----- testsuite/sort.tests | 36 ++++++++++++++++++++++++++++++++++++ 2 files changed, 52 insertions(+), 5 deletions(-) diff --git a/coreutils/sort.c b/coreutils/sort.c index 36f02543b..7fb4df5bd 100644 --- a/coreutils/sort.c +++ b/coreutils/sort.c @@ -106,7 +106,9 @@ static struct sort_key { static char *get_key(char *str, struct sort_key *key, int flags) { - int start = 0, end = 0, len, j; + int start = start; /* for compiler */ + int end; + int len, j; unsigned i; /* Special case whole string, so we don't have to make a copy */ @@ -123,12 +125,15 @@ static char *get_key(char *str, struct sort_key *key, int flags) end = len; /* Loop through fields */ else { + unsigned char ch = 0; + end = 0; for (i = 1; i < key->range[2*j] + j; i++) { if (key_separator) { /* Skip body of key and separator */ - while (str[end]) { - if (str[end++] == key_separator) + while ((ch = str[end]) != '\0') { + end++; + if (ch == key_separator) break; } } else { @@ -136,7 +141,7 @@ static char *get_key(char *str, struct sort_key *key, int flags) while (isspace(str[end])) end++; /* Skip body of key */ - while (str[end]) { + while (str[end] != '\0') { if (isspace(str[end])) break; end++; @@ -144,11 +149,17 @@ static char *get_key(char *str, struct sort_key *key, int flags) } } /* Remove last delim: "abc:def:" => "abc:def" */ - if (key_separator && j && end != 0) + if (j && ch) { + //if (str[end-1] != key_separator) + // bb_error_msg(_and_die("BUG! " + // "str[start:%d,end:%d]:'%.*s'", + // start, end, (int)(end-start), &str[start]); end--; + } } if (!j) start = end; } +//bb_error_msg("start:%d,end:%d", start, end); /* Strip leading whitespace if necessary */ //XXX: skip_whitespace() if (flags & FLAG_b) diff --git a/testsuite/sort.tests b/testsuite/sort.tests index c4b223464..39c7af738 100755 --- a/testsuite/sort.tests +++ b/testsuite/sort.tests @@ -106,6 +106,42 @@ a/a:a a:b " "" +testing "glibc build sort" "sort -t. -k 1,1 -k 2n,2n -k 3 input" "\ +GLIBC_2.1 +GLIBC_2.1.1 +GLIBC_2.2 +GLIBC_2.2.1 +GLIBC_2.10 +GLIBC_2.20 +GLIBC_2.21 +" "\ +GLIBC_2.21 +GLIBC_2.1.1 +GLIBC_2.2.1 +GLIBC_2.2 +GLIBC_2.20 +GLIBC_2.10 +GLIBC_2.1 +" "" + +testing "glibc build sort unique" "sort -u -t. -k 1,1 -k 2n,2n -k 3 input" "\ +GLIBC_2.1 +GLIBC_2.1.1 +GLIBC_2.2 +GLIBC_2.2.1 +GLIBC_2.10 +GLIBC_2.20 +GLIBC_2.21 +" "\ +GLIBC_2.10 +GLIBC_2.2.1 +GLIBC_2.1.1 +GLIBC_2.20 +GLIBC_2.2 +GLIBC_2.1 +GLIBC_2.21 +" "" + testing "sort -u should consider field only when discarding" "sort -u -k2 input" "\ a c " "\ From fd19faf70569ca3173a94cf19ecc9b60efe3f480 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Mon, 19 Oct 2015 14:48:24 +0200 Subject: [PATCH 029/260] remove extra debug printout Signed-off-by: Denys Vlasenko --- coreutils/sort.c | 1 - 1 file changed, 1 deletion(-) diff --git a/coreutils/sort.c b/coreutils/sort.c index 7fb4df5bd..c2e8bb8de 100644 --- a/coreutils/sort.c +++ b/coreutils/sort.c @@ -159,7 +159,6 @@ static char *get_key(char *str, struct sort_key *key, int flags) } if (!j) start = end; } -//bb_error_msg("start:%d,end:%d", start, end); /* Strip leading whitespace if necessary */ //XXX: skip_whitespace() if (flags & FLAG_b) From d1ed3e68b8080161642cc106099c0a17ac7892e6 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Mon, 19 Oct 2015 19:13:06 +0200 Subject: [PATCH 030/260] sort: code shrink function old new delta compare_keys 738 695 -43 Signed-off-by: Denys Vlasenko --- coreutils/sort.c | 40 ++++++++++++++++++++++------------------ 1 file changed, 22 insertions(+), 18 deletions(-) diff --git a/coreutils/sort.c b/coreutils/sort.c index c2e8bb8de..f2bc5335f 100644 --- a/coreutils/sort.c +++ b/coreutils/sort.c @@ -291,7 +291,7 @@ static int compare_keys(const void *xarg, const void *yarg) else if (!yy) retval = 1; else - retval = (dx == thyme.tm_mon) ? 0 : dx - thyme.tm_mon; + retval = dx - thyme.tm_mon; break; } /* Full floating point version of -n */ @@ -317,8 +317,8 @@ static int compare_keys(const void *xarg, const void *yarg) /* Perform fallback sort if necessary */ if (!retval && !(option_mask32 & FLAG_s)) { - retval = strcmp(*(char **)xarg, *(char **)yarg); flags = option_mask32; + retval = strcmp(*(char **)xarg, *(char **)yarg); } if (flags & FLAG_r) @@ -346,7 +346,7 @@ int sort_main(int argc UNUSED_PARAM, char **argv) char *line, **lines; char *str_ignored, *str_o, *str_t; llist_t *lst_k = NULL; - int i, flag; + int i; int linecount; unsigned opts; @@ -369,7 +369,7 @@ int sort_main(int argc UNUSED_PARAM, char **argv) /* note: below this point we use option_mask32, not opts, * since that reduces register pressure and makes code smaller */ - /* parse sort key */ + /* Parse sort key */ while (lst_k) { enum { FLAG_allowed_for_k = @@ -396,17 +396,18 @@ int sort_main(int argc UNUSED_PARAM, char **argv) key->range[2*i+1] = str2u(&str_k); } while (*str_k) { - const char *temp2; + int flag; + const char *idx; if (*str_k == ',' && !i++) { str_k++; break; } /* no else needed: fall through to syntax error because comma isn't in OPT_STR */ - temp2 = strchr(OPT_STR, *str_k); - if (!temp2) + idx = strchr(OPT_STR, *str_k); + if (!idx) bb_error_msg_and_die("unknown key option"); - flag = 1 << (temp2 - OPT_STR); + flag = 1 << (idx - OPT_STR); if (flag & ~FLAG_allowed_for_k) bb_error_msg_and_die("unknown sort type"); /* b after ',' means strip _trailing_ space */ @@ -440,10 +441,10 @@ int sort_main(int argc UNUSED_PARAM, char **argv) } while (*++argv); #if ENABLE_FEATURE_SORT_BIG - /* if no key, perform alphabetic sort */ + /* If no key, perform alphabetic sort */ if (!key_list) add_key()->range[0] = 1; - /* handle -c */ + /* Handle -c */ if (option_mask32 & FLAG_c) { int j = (option_mask32 & FLAG_u) ? -1 : 0; for (i = 1; i < linecount; i++) { @@ -457,20 +458,21 @@ int sort_main(int argc UNUSED_PARAM, char **argv) #endif /* Perform the actual sort */ qsort(lines, linecount, sizeof(lines[0]), compare_keys); - /* handle -u */ + + /* Handle -u */ if (option_mask32 & FLAG_u) { - flag = 0; + int j = 0; /* coreutils 6.3 drop lines for which only key is the same */ /* -- disabling last-resort compare... */ option_mask32 |= FLAG_s; for (i = 1; i < linecount; i++) { - if (compare_keys(&lines[flag], &lines[i]) == 0) + if (compare_keys(&lines[j], &lines[i]) == 0) free(lines[i]); else - lines[++flag] = lines[i]; + lines[++j] = lines[i]; } if (linecount) - linecount = flag+1; + linecount = j+1; } /* Print it */ @@ -479,9 +481,11 @@ int sort_main(int argc UNUSED_PARAM, char **argv) if (option_mask32 & FLAG_o) xmove_fd(xopen(str_o, O_WRONLY|O_CREAT|O_TRUNC), STDOUT_FILENO); #endif - flag = (option_mask32 & FLAG_z) ? '\0' : '\n'; - for (i = 0; i < linecount; i++) - printf("%s%c", lines[i], flag); + { + int ch = (option_mask32 & FLAG_z) ? '\0' : '\n'; + for (i = 0; i < linecount; i++) + printf("%s%c", lines[i], ch); + } fflush_stdout_and_exit(EXIT_SUCCESS); } From 0506e292b518a04846ae1f611ecc0633969a2801 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Mon, 19 Oct 2015 19:27:26 +0200 Subject: [PATCH 031/260] sort: fix ENDCHAR handling in "-kSTART,N.ENDCHAR" function old new delta get_key 505 503 -2 Signed-off-by: Denys Vlasenko --- coreutils/sort.c | 7 ++++--- testsuite/sort.tests | 8 ++++++++ 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/coreutils/sort.c b/coreutils/sort.c index f2bc5335f..07d903388 100644 --- a/coreutils/sort.c +++ b/coreutils/sort.c @@ -160,17 +160,18 @@ static char *get_key(char *str, struct sort_key *key, int flags) if (!j) start = end; } /* Strip leading whitespace if necessary */ -//XXX: skip_whitespace() if (flags & FLAG_b) + /* not using skip_whitespace() for speed */ while (isspace(str[start])) start++; /* Strip trailing whitespace if necessary */ if (flags & FLAG_bb) while (end > start && isspace(str[end-1])) end--; - /* Handle offsets on start and end */ + /* -kSTART,N.ENDCHAR: honor ENDCHAR (1-based) */ if (key->range[3]) { - end += key->range[3] - 1; + end = key->range[3]; if (end > len) end = len; } + /* -kN.STARTCHAR[,...]: honor STARTCHAR (1-based) */ if (key->range[1]) { start += key->range[1] - 1; if (start > len) start = len; diff --git a/testsuite/sort.tests b/testsuite/sort.tests index 39c7af738..c51a8e475 100755 --- a/testsuite/sort.tests +++ b/testsuite/sort.tests @@ -106,6 +106,14 @@ a/a:a a:b " "" +testing "sort with ENDCHAR" "sort -t. -k1,1.1 -k2 input" "\ +ab.1 +aa.2 +" "\ +aa.2 +ab.1 +" "" + testing "glibc build sort" "sort -t. -k 1,1 -k 2n,2n -k 3 input" "\ GLIBC_2.1 GLIBC_2.1.1 From f2ccefb946c5de69ce6a51c9a8e95024d44c273b Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Mon, 19 Oct 2015 23:26:50 +0200 Subject: [PATCH 032/260] setarch: add support for '-R' (disable randomization) This commit adds support for the -R flag of setarch, which disables randomization of the virtual address space. function old new delta setarch_main 115 150 +35 packed_usage 30664 30651 -13 Signed-off-by: Jan Heylen Signed-off-by: Thomas De Schampheleire Signed-off-by: Denys Vlasenko --- include/applets.src.h | 3 --- util-linux/Config.src | 10 -------- util-linux/Kbuild.src | 1 - util-linux/setarch.c | 54 +++++++++++++++++++++++++++++++------------ 4 files changed, 39 insertions(+), 29 deletions(-) diff --git a/include/applets.src.h b/include/applets.src.h index 5b597202e..6e1b02fc3 100644 --- a/include/applets.src.h +++ b/include/applets.src.h @@ -192,8 +192,6 @@ IF_KILLALL5(APPLET_ODDNAME(killall5, kill, BB_DIR_USR_SBIN, BB_SUID_DROP, killal IF_LAST(APPLET(last, BB_DIR_USR_BIN, BB_SUID_DROP)) //IF_LENGTH(APPLET_NOFORK(length, length, BB_DIR_USR_BIN, BB_SUID_DROP, length)) IF_LESS(APPLET(less, BB_DIR_USR_BIN, BB_SUID_DROP)) -IF_SETARCH(APPLET_ODDNAME(linux32, setarch, BB_DIR_BIN, BB_SUID_DROP, linux32)) -IF_SETARCH(APPLET_ODDNAME(linux64, setarch, BB_DIR_BIN, BB_SUID_DROP, linux64)) IF_LN(APPLET_NOEXEC(ln, ln, BB_DIR_BIN, BB_SUID_DROP, ln)) IF_LOAD_POLICY(APPLET(load_policy, BB_DIR_USR_SBIN, BB_SUID_DROP)) IF_LOADFONT(APPLET(loadfont, BB_DIR_USR_SBIN, BB_SUID_DROP)) @@ -274,7 +272,6 @@ IF_SELINUXENABLED(APPLET(selinuxenabled, BB_DIR_USR_SBIN, BB_SUID_DROP)) IF_SENDMAIL(APPLET(sendmail, BB_DIR_USR_SBIN, BB_SUID_DROP)) IF_SEQ(APPLET_NOFORK(seq, seq, BB_DIR_USR_BIN, BB_SUID_DROP, seq)) IF_SESTATUS(APPLET(sestatus, BB_DIR_USR_SBIN, BB_SUID_DROP)) -IF_SETARCH(APPLET(setarch, BB_DIR_BIN, BB_SUID_DROP)) IF_SETCONSOLE(APPLET(setconsole, BB_DIR_SBIN, BB_SUID_DROP)) IF_SETENFORCE(APPLET(setenforce, BB_DIR_USR_SBIN, BB_SUID_DROP)) IF_SETFILES(APPLET(setfiles, BB_DIR_SBIN, BB_SUID_DROP)) diff --git a/util-linux/Config.src b/util-linux/Config.src index 854b3682e..922cabdb8 100644 --- a/util-linux/Config.src +++ b/util-linux/Config.src @@ -489,16 +489,6 @@ config SCRIPTREPLAY This program replays a typescript, using timing information given by script -t. -config SETARCH - bool "setarch" - default y - select PLATFORM_LINUX - help - The linux32 utility is used to create a 32bit environment for the - specified program (usually a shell). It only makes sense to have - this util on a system that supports both 64bit and 32bit userland - (like amd64/x86, ppc64/ppc, sparc64/sparc, etc...). - config SWAPONOFF bool "swaponoff" default y diff --git a/util-linux/Kbuild.src b/util-linux/Kbuild.src index 468fc6bc1..0b87c52ac 100644 --- a/util-linux/Kbuild.src +++ b/util-linux/Kbuild.src @@ -40,7 +40,6 @@ lib-$(CONFIG_READPROFILE) += readprofile.o lib-$(CONFIG_RTCWAKE) += rtcwake.o lib-$(CONFIG_SCRIPT) += script.o lib-$(CONFIG_SCRIPTREPLAY) += scriptreplay.o -lib-$(CONFIG_SETARCH) += setarch.o lib-$(CONFIG_SWAPONOFF) += swaponoff.o lib-$(CONFIG_SWITCH_ROOT) += switch_root.o lib-$(CONFIG_UMOUNT) += umount.o diff --git a/util-linux/setarch.c b/util-linux/setarch.c index 7b9421af1..2e989ec2a 100644 --- a/util-linux/setarch.c +++ b/util-linux/setarch.c @@ -6,13 +6,30 @@ * * Licensed under GPLv2 or later, see file LICENSE in this source tree. */ +//config:config SETARCH +//config: bool "setarch" +//config: default y +//config: select PLATFORM_LINUX +//config: help +//config: The linux32 utility is used to create a 32bit environment for the +//config: specified program (usually a shell). It only makes sense to have +//config: this util on a system that supports both 64bit and 32bit userland +//config: (like amd64/x86, ppc64/ppc, sparc64/sparc, etc...). + +//applet:IF_SETARCH(APPLET(setarch, BB_DIR_BIN, BB_SUID_DROP)) +//applet:IF_SETARCH(APPLET_ODDNAME(linux32, setarch, BB_DIR_BIN, BB_SUID_DROP, linux32)) +//applet:IF_SETARCH(APPLET_ODDNAME(linux64, setarch, BB_DIR_BIN, BB_SUID_DROP, linux64)) + +//kbuild:lib-$(CONFIG_SETARCH) += setarch.o //usage:#define setarch_trivial_usage -//usage: "personality PROG ARGS" +//usage: "PERSONALITY [-R] PROG ARGS" //usage:#define setarch_full_usage "\n\n" -//usage: "Personality may be:\n" -//usage: " linux32 Set 32bit uname emulation\n" -//usage: " linux64 Set 64bit uname emulation" +//usage: "PERSONALITY may be:" +//usage: "\n"" linux32 Set 32bit uname emulation" +//usage: "\n"" linux64 Set 64bit uname emulation" +//usage: "\n" +//usage: "\n"" -R Disable address space randomization" //usage: //usage:#define linux32_trivial_usage NOUSAGE_STR //usage:#define linux32_full_usage "" @@ -20,14 +37,18 @@ //usage:#define linux64_trivial_usage NOUSAGE_STR //usage:#define linux64_full_usage "" +#include "libbb.h" #include -#include "libbb.h" +#ifndef ADDR_NO_RANDOMIZE +# define ADDR_NO_RANDOMIZE 0x0040000 +#endif int setarch_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; int setarch_main(int argc UNUSED_PARAM, char **argv) { - int pers; + unsigned opts; + unsigned long pers; /* Figure out what personality we are supposed to switch to ... * we can be invoked as either: @@ -35,7 +56,7 @@ int setarch_main(int argc UNUSED_PARAM, char **argv) * argv[0] == "personality" */ if (ENABLE_SETARCH && applet_name[0] == 's' - && argv[1] && strncpy(argv[1], "linux", 5) + && argv[1] && is_prefixed_with(argv[1], "linux") ) { applet_name = argv[1]; argv++; @@ -47,15 +68,18 @@ int setarch_main(int argc UNUSED_PARAM, char **argv) else bb_show_usage(); - argv++; - if (argv[0] == NULL) - bb_show_usage(); + opts = getopt32(argv, "+R"); /* '+': stop at first non-option */ + if (opts) + pers |= ADDR_NO_RANDOMIZE; /* Try to set personality */ - if (personality(pers) >= 0) { - /* Try to execute the program */ - BB_EXECVP(argv[0], argv); - } + if (personality(pers) < 0) + bb_perror_msg_and_die("personality(0x%lx)", pers); - bb_simple_perror_msg_and_die(argv[0]); + argv += optind; + if (!argv[0]) + (--argv)[0] = (char*)"/bin/sh"; + + /* Try to execute the program */ + BB_EXECVP_or_die(argv); } From 76efb3ed339c9003449980d3ea4d75ce19a7c3c5 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Tue, 20 Oct 2015 12:58:37 +0200 Subject: [PATCH 033/260] qemu_multiarch_testing/README: add a list of qemu's needed Signed-off-by: Denys Vlasenko --- qemu_multiarch_testing/README | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/qemu_multiarch_testing/README b/qemu_multiarch_testing/README index 9757ff0e4..ecb63f9ef 100644 --- a/qemu_multiarch_testing/README +++ b/qemu_multiarch_testing/README @@ -11,6 +11,11 @@ hdc.img, from hdc.dir/* data. This requires root for loop mount. one or more system-image-ARCH directories into this directory (the one which contains this README). +* Install qemu-system-ARCH. The arch names may differ from +system-image-ARCH: for example, all ARM flavors (armv4l...armv6l) +are served by the same qemu - qemu-system-arm. On my machine, +I needed to install qemu-system-{arm,mips,x86,ppc,sparc,m68k,sh4}. + * Run: ./parallel-build-hdc-img.sh system-image-DIR1 system-image-DIR2... (background it if you don't want to see "Waiting to finish" thing). This runs build in several qemu virtual machines in parallel. From 5134010d88b4aab286b4480822a8d8db8c32d903 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Tue, 20 Oct 2015 16:16:16 +0200 Subject: [PATCH 034/260] scripts/trylink: fix bit-rotted linker option verification To that end, *make it complain* when check_cc fails on options we usually want to succeed. text data bss dec hex filename 929697 932 17692 948321 e7861 busybox-1.23.2/busybox 915361 911 17484 933756 e3f7c busybox-1.23.2.fixed/busybox 927725 932 17448 946105 e6fb9 busybox-1.24.0/busybox 913630 911 17240 931781 e37c5 busybox-1.24.0.fixed/busybox Signed-off-by: Denys Vlasenko --- scripts/trylink | 59 +++++++++++++++++++++++++++++-------------------- 1 file changed, 35 insertions(+), 24 deletions(-) diff --git a/scripts/trylink b/scripts/trylink index 48c487bcd..26099976a 100755 --- a/scripts/trylink +++ b/scripts/trylink @@ -47,18 +47,22 @@ try() { check_cc() { local tempname="$(mktemp)" + local r + echo "int main(int argc,char**argv){return argv?argc:0;}" >"$tempname".c # Can use "-o /dev/null", but older gcc tend to *unlink it* on failure! :( - # "-xc": C language. "/dev/null" is an empty source file. - if $CC $CPPFLAGS $CFLAGS $1 -shared -xc /dev/null -o "$tempname".o >/dev/null 2>&1; then - echo "$1"; - else - echo "$2"; - fi - rm -f "$tempname" "$tempname".o + # Was using "-xc /dev/null", but we need a valid C program. + # "eval" is needed because CFLAGS can contain + # '... -D"BB_VER=KBUILD_STR(1.N.M)" ...' + # and we need shell to process quotes! + eval $CC $CPPFLAGS $CFLAGS $1 "$tempname".c -o "$tempname" >/dev/null 2>&1 + r=$? + rm -f "$tempname" "$tempname".c "$tempname".o + return $r } check_libc_is_glibc() { local tempname="$(mktemp)" + local r echo "\ #include /* Apparently uclibc defines __GLIBC__ (compat trick?). Oh well. */ @@ -66,12 +70,10 @@ check_libc_is_glibc() { syntax error here #endif " >"$tempname".c - if $CC $CPPFLAGS $CFLAGS "$tempname".c -c -o "$tempname".o >/dev/null 2>&1; then - echo "$2"; - else - echo "$1"; - fi - rm -f "$tempname" "$tempname".[co] + $CC $CPPFLAGS $CFLAGS "$tempname".c -c -o "$tempname".o >/dev/null 2>&1 + r=$? + rm -f "$tempname" "$tempname".c "$tempname".o + return $r } EXE="$1" @@ -83,32 +85,41 @@ A_FILES="$6" LDLIBS="$7" # The --sort-section option is not supported by older versions of ld -SORT_SECTION=`check_cc "-Wl,--sort-section,alignment" ""` +SORT_SECTION="-Wl,--sort-section,alignment" +if ! check_cc "-Wl,--sort-section,alignment"; then + echo "Your linker does not support --sort-section,alignment" + SORT_SECTION="" +fi START_GROUP="-Wl,--start-group" END_GROUP="-Wl,--end-group" INFO_OPTS="-Wl,--warn-common -Wl,-Map,$EXE.map -Wl,--verbose" # gold may not support --sort-common (yet) -SORT_COMMON=`check_cc "-Wl,--sort-common" ""` +SORT_COMMON="-Wl,--sort-common" +if ! check_cc "-Wl,--sort-common"; then + echo "Your linker does not support --sort-common" + SORT_COMMON="" +fi # Static linking against glibc produces buggy executables # (glibc does not cope well with ld --gc-sections). # See sources.redhat.com/bugzilla/show_bug.cgi?id=3400 # Note that glibc is unsuitable for static linking anyway. # We are removing -Wl,--gc-sections from link command line. -GC_SECTIONS=`( -. ./.config -if test x"$CONFIG_STATIC" = x"y"; then - check_libc_is_glibc "" "-Wl,--gc-sections" -else - echo "-Wl,--gc-sections" +GC_SECTIONS="-Wl,--gc-sections" +if (. ./.config && test x"$CONFIG_STATIC" = x"y") then + if check_libc_is_glibc; then + echo "Static linking against glibc, can't use --gc-sections" + GC_SECTIONS="" + fi fi -)` - # The --gc-sections option is not supported by older versions of ld if test -n "$GC_SECTIONS"; then - GC_SECTIONS=`check_cc "$GC_SECTIONS" ""` + if ! check_cc "$GC_SECTIONS"; then + echo "Your linker does not support $GC_SECTIONS" + GC_SECTIONS="" + fi fi # Sanitize lib list (dups, extra spaces etc) From 58d0e20ad00cc8a24f3485a363a5a51ab2387bdc Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Tue, 20 Oct 2015 16:40:43 +0200 Subject: [PATCH 035/260] scripts/trylink: remove $CPPFLAGS We don't use it in final link, should not use it in check_FOO then. This uncovered a logic bug in glibc check... Signed-off-by: Denys Vlasenko --- scripts/trylink | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/scripts/trylink b/scripts/trylink index 26099976a..9132b3f76 100755 --- a/scripts/trylink +++ b/scripts/trylink @@ -51,10 +51,10 @@ check_cc() { echo "int main(int argc,char**argv){return argv?argc:0;}" >"$tempname".c # Can use "-o /dev/null", but older gcc tend to *unlink it* on failure! :( # Was using "-xc /dev/null", but we need a valid C program. - # "eval" is needed because CFLAGS can contain + # "eval" may be needed is CFLAGS can contain # '... -D"BB_VER=KBUILD_STR(1.N.M)" ...' # and we need shell to process quotes! - eval $CC $CPPFLAGS $CFLAGS $1 "$tempname".c -o "$tempname" >/dev/null 2>&1 + $CC $CFLAGS $1 "$tempname".c -o "$tempname" >/dev/null 2>&1 r=$? rm -f "$tempname" "$tempname".c "$tempname".o return $r @@ -70,7 +70,7 @@ check_libc_is_glibc() { syntax error here #endif " >"$tempname".c - $CC $CPPFLAGS $CFLAGS "$tempname".c -c -o "$tempname".o >/dev/null 2>&1 + ! $CC $CFLAGS "$tempname".c -c -o "$tempname".o >/dev/null 2>&1 r=$? rm -f "$tempname" "$tempname".c "$tempname".o return $r From edcd5dcc9b075af9965c66b54e14f1cb87940c9b Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Tue, 20 Oct 2015 18:15:01 +0200 Subject: [PATCH 036/260] typo fix Signed-off-by: Denys Vlasenko --- scripts/trylink | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/trylink b/scripts/trylink index 9132b3f76..6e1187ed0 100755 --- a/scripts/trylink +++ b/scripts/trylink @@ -51,7 +51,7 @@ check_cc() { echo "int main(int argc,char**argv){return argv?argc:0;}" >"$tempname".c # Can use "-o /dev/null", but older gcc tend to *unlink it* on failure! :( # Was using "-xc /dev/null", but we need a valid C program. - # "eval" may be needed is CFLAGS can contain + # "eval" may be needed if CFLAGS can contain # '... -D"BB_VER=KBUILD_STR(1.N.M)" ...' # and we need shell to process quotes! $CC $CFLAGS $1 "$tempname".c -o "$tempname" >/dev/null 2>&1 From 92e1b0826d8490c31d48048ef4c517ec2943d706 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Tue, 20 Oct 2015 21:51:52 +0200 Subject: [PATCH 037/260] wget: make Bartosz's "wget --passive-ftp -nd -t 3" work function old new delta static.wget_longopts 166 234 +68 wget_main 2608 2610 +2 Signed-off-by: Denys Vlasenko --- networking/wget.c | 47 +++++++++++++++++++++++++++++++---------------- 1 file changed, 31 insertions(+), 16 deletions(-) diff --git a/networking/wget.c b/networking/wget.c index af9c53c22..7f27e4e7b 100644 --- a/networking/wget.c +++ b/networking/wget.c @@ -102,7 +102,8 @@ //usage: "[-c|--continue] [-s|--spider] [-q|--quiet] [-O|--output-document FILE]\n" //usage: " [--header 'header: value'] [-Y|--proxy on/off] [-P DIR]\n" /* Since we ignore these opts, we don't show them in --help */ -/* //usage: " [--no-check-certificate] [--no-cache]" */ +/* //usage: " [--no-check-certificate] [--no-cache] [--passive-ftp] [-t TRIES]" */ +/* //usage: " [-nv] [-nc] [-nH] [-np]" */ //usage: " [-U|--user-agent AGENT]" IF_FEATURE_WGET_TIMEOUT(" [-T SEC]") " URL..." //usage: ) //usage: IF_NOT_FEATURE_WGET_LONG_OPTIONS( @@ -1219,19 +1220,22 @@ int wget_main(int argc UNUSED_PARAM, char **argv) "directory-prefix\0" Required_argument "P" "proxy\0" Required_argument "Y" "user-agent\0" Required_argument "U" -#if ENABLE_FEATURE_WGET_TIMEOUT - "timeout\0" Required_argument "T" -#endif +IF_FEATURE_WGET_TIMEOUT( + "timeout\0" Required_argument "T") /* Ignored: */ - // "tries\0" Required_argument "t" +IF_DESKTOP( "tries\0" Required_argument "t") + "header\0" Required_argument "\xff" + "post-data\0" Required_argument "\xfe" /* Ignored (we always use PASV): */ - "passive-ftp\0" No_argument "\xff" - "header\0" Required_argument "\xfe" - "post-data\0" Required_argument "\xfd" +IF_DESKTOP( "passive-ftp\0" No_argument "\xf0") /* Ignored (we don't do ssl) */ - "no-check-certificate\0" No_argument "\xfc" +IF_DESKTOP( "no-check-certificate\0" No_argument "\xf0") /* Ignored (we don't support caching) */ - "no-cache\0" No_argument "\xfb" +IF_DESKTOP( "no-cache\0" No_argument "\xf0") +IF_DESKTOP( "no-verbose\0" No_argument "\xf0") +IF_DESKTOP( "no-clobber\0" No_argument "\xf0") +IF_DESKTOP( "no-host-directories\0" No_argument "\xf0") +IF_DESKTOP( "no-parent\0" No_argument "\xf0") ; #endif @@ -1251,14 +1255,25 @@ int wget_main(int argc UNUSED_PARAM, char **argv) #if ENABLE_FEATURE_WGET_LONG_OPTIONS applet_long_options = wget_longopts; #endif - opt_complementary = "-1" - IF_FEATURE_WGET_TIMEOUT(":T+") - IF_FEATURE_WGET_LONG_OPTIONS(":\xfe::"); - getopt32(argv, "csqO:P:Y:U:T:" /*ignored:*/ "t:", - &G.fname_out, &G.dir_prefix, + opt_complementary = "-1" /* at least one URL */ + IF_FEATURE_WGET_TIMEOUT(":T+") /* -T NUM */ + IF_FEATURE_WGET_LONG_OPTIONS(":\xff::"); /* --header is a list */ + getopt32(argv, "csqO:P:Y:U:T:" + /*ignored:*/ "t:" + /*ignored:*/ "n::" + /* wget has exactly four -n opts, all of which we can ignore: + * -nv --no-verbose: be moderately quiet (-q is full quiet) + * -nc --no-clobber: abort if exists, neither download to FILE.n nor overwrite FILE + * -nH --no-host-directories: wget -r http://host/ won't create host/ + * -np --no-parent + * "n::" above says that we accept -n[ARG]. + * Specifying "n:" would be a bug: "-n ARG" would eat ARG! + */ + , &G.fname_out, &G.dir_prefix, &G.proxy_flag, &G.user_agent, IF_FEATURE_WGET_TIMEOUT(&G.timeout_seconds) IF_NOT_FEATURE_WGET_TIMEOUT(NULL), - NULL /* -t RETRIES */ + NULL, /* -t RETRIES */ + NULL /* -n[ARG] */ IF_FEATURE_WGET_LONG_OPTIONS(, &headers_llist) IF_FEATURE_WGET_LONG_OPTIONS(, &G.post_data) ); From c47917865d5f40f9044dd8845814c591d801318d Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Wed, 21 Oct 2015 16:06:40 +0200 Subject: [PATCH 038/260] login: explain -h HOST option better Signed-off-by: Denys Vlasenko --- loginutils/login.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/loginutils/login.c b/loginutils/login.c index f1f04da19..67fe82e86 100644 --- a/loginutils/login.c +++ b/loginutils/login.c @@ -58,7 +58,7 @@ //usage:#define login_full_usage "\n\n" //usage: "Begin a new session on the system\n" //usage: "\n -f Don't authenticate (user already authenticated)" -//usage: "\n -h Name of the remote host" +//usage: "\n -h HOST Host user came from (for network logins)" //usage: "\n -p Preserve environment" #include "libbb.h" From 6c563e370d0f2f3cf36f3b274e8fe1392ca7125f Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Thu, 22 Oct 2015 01:07:13 +0200 Subject: [PATCH 039/260] tar: add support for --strip-components=N function old new delta data_extract_all 882 995 +113 tar_longopts 290 309 +19 tar_main 938 942 +4 ------------------------------------------------------------------------------ (add/remove: 0/0 grow/shrink: 3/0 up/down: 136/0) Total: 136 bytes Signed-off-by: Denys Vlasenko --- archival/libarchive/data_extract_all.c | 108 +++++++++++++++++-------- archival/libarchive/get_header_tar.c | 1 + archival/tar.c | 80 ++++++++++++++---- include/bb_archive.h | 3 + testsuite/tar.tests | 10 +++ 5 files changed, 156 insertions(+), 46 deletions(-) diff --git a/archival/libarchive/data_extract_all.c b/archival/libarchive/data_extract_all.c index 45776dcbe..bd51d2ad3 100644 --- a/archival/libarchive/data_extract_all.c +++ b/archival/libarchive/data_extract_all.c @@ -8,9 +8,17 @@ void FAST_FUNC data_extract_all(archive_handle_t *archive_handle) { + file_header_t *file_header = archive_handle->file_header; int dst_fd; int res; +#if ENABLE_FEATURE_TAR_LONG_OPTIONS + char *dst_name; + char *dst_link; +#else +# define dst_name (file_header->name) +# define dst_link (file_header->link_target) +#endif #if ENABLE_FEATURE_TAR_SELINUX char *sctx = archive_handle->tar__sctx[PAX_NEXT_FILE]; @@ -23,11 +31,47 @@ void FAST_FUNC data_extract_all(archive_handle_t *archive_handle) } #endif +#if ENABLE_FEATURE_TAR_LONG_OPTIONS + dst_name = file_header->name; + dst_link = file_header->link_target; + if (archive_handle->tar__strip_components) { + unsigned n = archive_handle->tar__strip_components; + do { + dst_name = strchr(dst_name, '/'); + if (!dst_name || dst_name[1] == '\0') { + data_skip(archive_handle); + return; + } + dst_name++; + /* + * Link target is shortened only for hardlinks: + * softlinks restored unchanged. + */ + if (S_ISREG(file_header->mode) + && file_header->size == 0 + && dst_link + ) { +// GNU tar 1.26 does not check that we reached end of link name: +// if "dir/hardlink" is hardlinked to "file", +// tar xvf a.tar --strip-components=1 says: +// tar: hardlink: Cannot hard link to '': No such file or directory +// and continues processing. We silently skip such entries. + dst_link = strchr(dst_link, '/'); + if (!dst_link || dst_link[1] == '\0') { + data_skip(archive_handle); + return; + } + dst_link++; + } + } while (--n != 0); + } +#endif + if (archive_handle->ah_flags & ARCHIVE_CREATE_LEADING_DIRS) { - char *slash = strrchr(file_header->name, '/'); + char *slash = strrchr(dst_name, '/'); if (slash) { *slash = '\0'; - bb_make_directory(file_header->name, -1, FILEUTILS_RECUR); + bb_make_directory(dst_name, -1, FILEUTILS_RECUR); *slash = '/'; } } @@ -38,8 +82,8 @@ void FAST_FUNC data_extract_all(archive_handle_t *archive_handle) /* Is it hardlink? * We encode hard links as regular files of size 0 with a symlink */ if (S_ISREG(file_header->mode) - && file_header->link_target && file_header->size == 0 + && dst_link ) { /* Ugly special case: * tar cf t.tar hardlink1 hardlink2 hardlink1 @@ -48,22 +92,22 @@ void FAST_FUNC data_extract_all(archive_handle_t *archive_handle) * hardlink2 -> hardlink1 * hardlink1 -> hardlink1 <== !!! */ - if (strcmp(file_header->link_target, file_header->name) == 0) + if (strcmp(dst_link, dst_name) == 0) goto ret; } /* Proceed with deleting */ - if (unlink(file_header->name) == -1 + if (unlink(dst_name) == -1 && errno != ENOENT ) { bb_perror_msg_and_die("can't remove old file %s", - file_header->name); + dst_name); } } } else if (archive_handle->ah_flags & ARCHIVE_EXTRACT_NEWER) { /* Remove the existing entry if its older than the extracted entry */ struct stat existing_sb; - if (lstat(file_header->name, &existing_sb) == -1) { + if (lstat(dst_name, &existing_sb) == -1) { if (errno != ENOENT) { bb_perror_msg_and_die("can't stat old file"); } @@ -73,30 +117,30 @@ void FAST_FUNC data_extract_all(archive_handle_t *archive_handle) && !S_ISDIR(file_header->mode) ) { bb_error_msg("%s not created: newer or " - "same age file exists", file_header->name); + "same age file exists", dst_name); } data_skip(archive_handle); goto ret; } - else if ((unlink(file_header->name) == -1) && (errno != EISDIR)) { + else if ((unlink(dst_name) == -1) && (errno != EISDIR)) { bb_perror_msg_and_die("can't remove old file %s", - file_header->name); + dst_name); } } /* Handle hard links separately * We encode hard links as regular files of size 0 with a symlink */ if (S_ISREG(file_header->mode) - && file_header->link_target && file_header->size == 0 + && dst_link ) { - /* hard link */ - res = link(file_header->link_target, file_header->name); - if ((res == -1) && !(archive_handle->ah_flags & ARCHIVE_EXTRACT_QUIET)) { + /* Hard link */ + res = link(dst_link, dst_name); + if (res != 0 && !(archive_handle->ah_flags & ARCHIVE_EXTRACT_QUIET)) { bb_perror_msg("can't create %slink " "from %s to %s", "hard", - file_header->name, - file_header->link_target); + dst_name, + dst_link); } /* Hardlinks have no separate mode/ownership, skip chown/chmod */ goto ret; @@ -106,17 +150,17 @@ void FAST_FUNC data_extract_all(archive_handle_t *archive_handle) switch (file_header->mode & S_IFMT) { case S_IFREG: { /* Regular file */ - char *dst_name; + char *dst_nameN; int flags = O_WRONLY | O_CREAT | O_EXCL; if (archive_handle->ah_flags & ARCHIVE_O_TRUNC) flags = O_WRONLY | O_CREAT | O_TRUNC; - dst_name = file_header->name; + dst_nameN = dst_name; #ifdef ARCHIVE_REPLACE_VIA_RENAME if (archive_handle->ah_flags & ARCHIVE_REPLACE_VIA_RENAME) /* rpm-style temp file name */ - dst_name = xasprintf("%s;%x", dst_name, (int)getpid()); + dst_nameN = xasprintf("%s;%x", dst_name, (int)getpid()); #endif - dst_fd = xopen3(dst_name, + dst_fd = xopen3(dst_nameN, flags, file_header->mode ); @@ -124,32 +168,32 @@ void FAST_FUNC data_extract_all(archive_handle_t *archive_handle) close(dst_fd); #ifdef ARCHIVE_REPLACE_VIA_RENAME if (archive_handle->ah_flags & ARCHIVE_REPLACE_VIA_RENAME) { - xrename(dst_name, file_header->name); - free(dst_name); + xrename(dst_nameN, dst_name); + free(dst_nameN); } #endif break; } case S_IFDIR: - res = mkdir(file_header->name, file_header->mode); + res = mkdir(dst_name, file_header->mode); if ((res == -1) && (errno != EISDIR) /* btw, Linux doesn't return this */ && (errno != EEXIST) && !(archive_handle->ah_flags & ARCHIVE_EXTRACT_QUIET) ) { - bb_perror_msg("can't make dir %s", file_header->name); + bb_perror_msg("can't make dir %s", dst_name); } break; case S_IFLNK: /* Symlink */ //TODO: what if file_header->link_target == NULL (say, corrupted tarball?) - res = symlink(file_header->link_target, file_header->name); - if ((res == -1) + res = symlink(file_header->link_target, dst_name); + if (res != 0 && !(archive_handle->ah_flags & ARCHIVE_EXTRACT_QUIET) ) { bb_perror_msg("can't create %slink " "from %s to %s", "sym", - file_header->name, + dst_name, file_header->link_target); } break; @@ -157,11 +201,11 @@ void FAST_FUNC data_extract_all(archive_handle_t *archive_handle) case S_IFBLK: case S_IFCHR: case S_IFIFO: - res = mknod(file_header->name, file_header->mode, file_header->device); + res = mknod(dst_name, file_header->mode, file_header->device); if ((res == -1) && !(archive_handle->ah_flags & ARCHIVE_EXTRACT_QUIET) ) { - bb_perror_msg("can't create node %s", file_header->name); + bb_perror_msg("can't create node %s", dst_name); } break; default: @@ -186,20 +230,20 @@ void FAST_FUNC data_extract_all(archive_handle_t *archive_handle) } #endif /* GNU tar 1.15.1 uses chown, not lchown */ - chown(file_header->name, uid, gid); + chown(dst_name, uid, gid); } /* uclibc has no lchmod, glibc is even stranger - * it has lchmod which seems to do nothing! * so we use chmod... */ if (!(archive_handle->ah_flags & ARCHIVE_DONT_RESTORE_PERM)) { - chmod(file_header->name, file_header->mode); + chmod(dst_name, file_header->mode); } if (archive_handle->ah_flags & ARCHIVE_RESTORE_DATE) { struct timeval t[2]; t[1].tv_sec = t[0].tv_sec = file_header->mtime; t[1].tv_usec = t[0].tv_usec = 0; - utimes(file_header->name, t); + utimes(dst_name, t); } } diff --git a/archival/libarchive/get_header_tar.c b/archival/libarchive/get_header_tar.c index fb68673b9..ac2be726f 100644 --- a/archival/libarchive/get_header_tar.c +++ b/archival/libarchive/get_header_tar.c @@ -418,6 +418,7 @@ char FAST_FUNC get_header_tar(archive_handle_t *archive_handle) /* Everything up to and including last ".." component is stripped */ overlapping_strcpy(file_header->name, strip_unsafe_prefix(file_header->name)); +//TODO: do the same for file_header->link_target? /* Strip trailing '/' in directories */ /* Must be done after mode is set as '/' is used to check if it's a directory */ diff --git a/archival/tar.c b/archival/tar.c index aa03ba990..566ba34f6 100644 --- a/archival/tar.c +++ b/archival/tar.c @@ -152,9 +152,12 @@ # define FNM_LEADING_DIR 0 #endif - -//#define DBG(fmt, ...) bb_error_msg("%s: " fmt, __func__, ## __VA_ARGS__) -#define DBG(...) ((void)0) +#if 0 +# define DBG(fmt, ...) bb_error_msg("%s: " fmt, __func__, ## __VA_ARGS__) +#else +# define DBG(...) ((void)0) +#endif +#define DBG_OPTION_PARSING 0 #define block_buf bb_common_bufsiz1 @@ -855,6 +858,7 @@ enum { IF_FEATURE_SEAMLESS_Z( OPTBIT_COMPRESS ,) IF_FEATURE_TAR_NOPRESERVE_TIME(OPTBIT_NOPRESERVE_TIME,) #if ENABLE_FEATURE_TAR_LONG_OPTIONS + OPTBIT_STRIP_COMPONENTS, OPTBIT_NORECURSION, IF_FEATURE_TAR_TO_COMMAND(OPTBIT_2COMMAND ,) OPTBIT_NUMERIC_OWNER, @@ -879,12 +883,13 @@ enum { OPT_GZIP = IF_FEATURE_SEAMLESS_GZ( (1 << OPTBIT_GZIP )) + 0, // z OPT_XZ = IF_FEATURE_SEAMLESS_XZ( (1 << OPTBIT_XZ )) + 0, // J OPT_COMPRESS = IF_FEATURE_SEAMLESS_Z( (1 << OPTBIT_COMPRESS )) + 0, // Z - OPT_NOPRESERVE_TIME = IF_FEATURE_TAR_NOPRESERVE_TIME((1 << OPTBIT_NOPRESERVE_TIME)) + 0, // m - OPT_NORECURSION = IF_FEATURE_TAR_LONG_OPTIONS((1 << OPTBIT_NORECURSION )) + 0, // no-recursion - OPT_2COMMAND = IF_FEATURE_TAR_TO_COMMAND( (1 << OPTBIT_2COMMAND )) + 0, // to-command - OPT_NUMERIC_OWNER = IF_FEATURE_TAR_LONG_OPTIONS((1 << OPTBIT_NUMERIC_OWNER )) + 0, // numeric-owner - OPT_NOPRESERVE_PERM = IF_FEATURE_TAR_LONG_OPTIONS((1 << OPTBIT_NOPRESERVE_PERM)) + 0, // no-same-permissions - OPT_OVERWRITE = IF_FEATURE_TAR_LONG_OPTIONS((1 << OPTBIT_OVERWRITE )) + 0, // overwrite + OPT_NOPRESERVE_TIME = IF_FEATURE_TAR_NOPRESERVE_TIME((1 << OPTBIT_NOPRESERVE_TIME)) + 0, // m + OPT_STRIP_COMPONENTS = IF_FEATURE_TAR_LONG_OPTIONS((1 << OPTBIT_STRIP_COMPONENTS)) + 0, // strip-components + OPT_NORECURSION = IF_FEATURE_TAR_LONG_OPTIONS((1 << OPTBIT_NORECURSION )) + 0, // no-recursion + OPT_2COMMAND = IF_FEATURE_TAR_TO_COMMAND( (1 << OPTBIT_2COMMAND )) + 0, // to-command + OPT_NUMERIC_OWNER = IF_FEATURE_TAR_LONG_OPTIONS((1 << OPTBIT_NUMERIC_OWNER )) + 0, // numeric-owner + OPT_NOPRESERVE_PERM = IF_FEATURE_TAR_LONG_OPTIONS((1 << OPTBIT_NOPRESERVE_PERM)) + 0, // no-same-permissions + OPT_OVERWRITE = IF_FEATURE_TAR_LONG_OPTIONS((1 << OPTBIT_OVERWRITE )) + 0, // overwrite OPT_ANY_COMPRESS = (OPT_BZIP2 | OPT_LZMA | OPT_GZIP | OPT_XZ | OPT_COMPRESS), }; @@ -928,6 +933,7 @@ static const char tar_longopts[] ALIGN1 = # if ENABLE_FEATURE_TAR_NOPRESERVE_TIME "touch\0" No_argument "m" # endif + "strip-components\0" Required_argument "\xf9" "no-recursion\0" No_argument "\xfa" # if ENABLE_FEATURE_TAR_TO_COMMAND "to-command\0" Required_argument "\xfb" @@ -973,11 +979,15 @@ int tar_main(int argc UNUSED_PARAM, char **argv) "tt:vv:" // count -t,-v IF_FEATURE_TAR_FROM("X::T::") // cumulative lists #if ENABLE_FEATURE_TAR_LONG_OPTIONS && ENABLE_FEATURE_TAR_FROM - "\xff::" // cumulative lists for --exclude + "\xff::" // --exclude=PATTERN is a list #endif IF_FEATURE_TAR_CREATE("c:") "t:x:" // at least one of these is reqd IF_FEATURE_TAR_CREATE("c--tx:t--cx:x--ct") // mutually exclusive - IF_NOT_FEATURE_TAR_CREATE("t--x:x--t"); // mutually exclusive + IF_NOT_FEATURE_TAR_CREATE("t--x:x--t") // mutually exclusive +#if ENABLE_FEATURE_TAR_LONG_OPTIONS + ":\xf9+" // --strip-components=NUM +#endif + ; #if ENABLE_FEATURE_TAR_LONG_OPTIONS applet_long_options = tar_longopts; #endif @@ -1018,10 +1028,14 @@ int tar_main(int argc UNUSED_PARAM, char **argv) IF_FEATURE_SEAMLESS_XZ( "J" ) IF_FEATURE_SEAMLESS_Z( "Z" ) IF_FEATURE_TAR_NOPRESERVE_TIME("m") + IF_FEATURE_TAR_LONG_OPTIONS("\xf9:") // --strip-components , &base_dir // -C dir , &tar_filename // -f filename IF_FEATURE_TAR_FROM(, &(tar_handle->accept)) // T IF_FEATURE_TAR_FROM(, &(tar_handle->reject)) // X +#if ENABLE_FEATURE_TAR_LONG_OPTIONS + , &tar_handle->tar__strip_components // --strip-components +#endif IF_FEATURE_TAR_TO_COMMAND(, &(tar_handle->tar__to_command)) // --to-command #if ENABLE_FEATURE_TAR_LONG_OPTIONS && ENABLE_FEATURE_TAR_FROM , &excludes // --exclude @@ -1029,11 +1043,49 @@ int tar_main(int argc UNUSED_PARAM, char **argv) , &verboseFlag // combined count for -t and -v , &verboseFlag // combined count for -t and -v ); - //bb_error_msg("opt:%08x", opt); +#if DBG_OPTION_PARSING + bb_error_msg("opt: 0x%08x", opt); +# define showopt(o) bb_error_msg("opt & %s(%x): %x", #o, o, opt & o); + showopt(OPT_TEST ); + showopt(OPT_EXTRACT ); + showopt(OPT_BASEDIR ); + showopt(OPT_TARNAME ); + showopt(OPT_2STDOUT ); + showopt(OPT_NOPRESERVE_OWNER); + showopt(OPT_P ); + showopt(OPT_VERBOSE ); + showopt(OPT_KEEP_OLD ); + showopt(OPT_CREATE ); + showopt(OPT_DEREFERENCE ); + showopt(OPT_BZIP2 ); + showopt(OPT_LZMA ); + showopt(OPT_INCLUDE_FROM ); + showopt(OPT_EXCLUDE_FROM ); + showopt(OPT_GZIP ); + showopt(OPT_XZ ); + showopt(OPT_COMPRESS ); + showopt(OPT_NOPRESERVE_TIME ); + showopt(OPT_STRIP_COMPONENTS); + showopt(OPT_NORECURSION ); + showopt(OPT_2COMMAND ); + showopt(OPT_NUMERIC_OWNER ); + showopt(OPT_NOPRESERVE_PERM ); + showopt(OPT_OVERWRITE ); + showopt(OPT_ANY_COMPRESS ); + bb_error_msg("base_dir:'%s'", base_dir); + bb_error_msg("tar_filename:'%s'", tar_filename); + bb_error_msg("verboseFlag:%d", verboseFlag); + bb_error_msg("tar_handle->tar__to_command:'%s'", tar_handle->tar__to_command); + bb_error_msg("tar_handle->tar__strip_components:%u", tar_handle->tar__strip_components); + return 0; +# undef showopt +#endif argv += optind; - if (verboseFlag) tar_handle->action_header = header_verbose_list; - if (verboseFlag == 1) tar_handle->action_header = header_list; + if (verboseFlag) + tar_handle->action_header = header_verbose_list; + if (verboseFlag == 1) + tar_handle->action_header = header_list; if (opt & OPT_EXTRACT) tar_handle->action_data = data_extract_all; diff --git a/include/bb_archive.h b/include/bb_archive.h index 2329d025d..10969b567 100644 --- a/include/bb_archive.h +++ b/include/bb_archive.h @@ -77,6 +77,9 @@ typedef struct archive_handle_t { off_t offset; /* Archiver specific. Can make it a union if it ever gets big */ +#if ENABLE_FEATURE_TAR_LONG_OPTIONS + unsigned tar__strip_components; +#endif #define PAX_NEXT_FILE 0 #define PAX_GLOBAL 1 #if ENABLE_TAR || ENABLE_DPKG || ENABLE_DPKG_DEB diff --git a/testsuite/tar.tests b/testsuite/tar.tests index 4929f4e49..383a4646c 100755 --- a/testsuite/tar.tests +++ b/testsuite/tar.tests @@ -53,6 +53,15 @@ dd if=/dev/zero bs=512 count=20 2>/dev/null | tar xvf - 2>&1; echo $? "" "" SKIP= +# "tar cf test.tar input input_dir/ input_hard1 input_hard2 input_hard1 input_dir/ input": +# GNU tar 1.26 records as hardlinks: +# input_hard2 -> input_hard1 +# input_hard1 -> input_hard1 (!!!) +# input_dir/file -> input_dir/file +# input -> input +# As of 1.24.0, we don't record last two: for them, nlink==1 +# and we check for "hardlink"ness only files with nlink!=1 +# We also don't use "hrw-r--r--" notation for hardlinks in "tar tv" listing. optional FEATURE_TAR_CREATE FEATURE_LS_SORTFILES testing "tar hardlinks and repeated files" '\ rm -rf input_* test.tar 2>/dev/null @@ -64,6 +73,7 @@ chmod -R 644 * chmod 755 input_dir tar cf test.tar input input_dir/ input_hard1 input_hard2 input_hard1 input_dir/ input tar tvf test.tar | sed "s/.*[0-9] input/input/" +rm -rf input_dir tar xf test.tar 2>&1 echo Ok: $? ls -l . input_dir/* | grep input_ | sed "s/\\(^[^ ]*\\) .* input/\\1 input/" From 62ae323df0856546754ecfe226fc9bf0dc16bcb8 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Thu, 22 Oct 2015 13:22:26 +0200 Subject: [PATCH 040/260] tar: implement --version for buildroot Signed-off-by: Denys Vlasenko --- archival/tar.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/archival/tar.c b/archival/tar.c index 566ba34f6..23ac00e86 100644 --- a/archival/tar.c +++ b/archival/tar.c @@ -992,6 +992,15 @@ int tar_main(int argc UNUSED_PARAM, char **argv) applet_long_options = tar_longopts; #endif #if ENABLE_DESKTOP + /* Lie to buildroot when it starts asking stupid questions. */ + if (argv[1] && strcmp(argv[1], "--version") == 0) { + // Output of 'tar --version' examples: + // tar (GNU tar) 1.15.1 + // tar (GNU tar) 1.25 + // bsdtar 2.8.3 - libarchive 2.8.3 + puts("tar (busybox) " BB_VER); + return 0; + } if (argv[1] && argv[1][0] != '-') { /* Compat: * 1st argument without dash handles options with parameters From f167e4503d08561054e75deb2ff123be2b30afa5 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Thu, 22 Oct 2015 13:30:34 +0200 Subject: [PATCH 041/260] tar: shrink hardlink name handling code function old new delta data_extract_all 1069 1040 -29 Signed-off-by: Denys Vlasenko --- archival/libarchive/data_extract_all.c | 43 ++++++++++---------------- 1 file changed, 17 insertions(+), 26 deletions(-) diff --git a/archival/libarchive/data_extract_all.c b/archival/libarchive/data_extract_all.c index bd51d2ad3..cf821c9de 100644 --- a/archival/libarchive/data_extract_all.c +++ b/archival/libarchive/data_extract_all.c @@ -12,12 +12,11 @@ void FAST_FUNC data_extract_all(archive_handle_t *archive_handle) file_header_t *file_header = archive_handle->file_header; int dst_fd; int res; + char *hard_link; #if ENABLE_FEATURE_TAR_LONG_OPTIONS char *dst_name; - char *dst_link; #else # define dst_name (file_header->name) -# define dst_link (file_header->link_target) #endif #if ENABLE_FEATURE_TAR_SELINUX @@ -31,9 +30,14 @@ void FAST_FUNC data_extract_all(archive_handle_t *archive_handle) } #endif + /* Hard links are encoded as regular files of size 0 + * with a nonempty link field */ + hard_link = NULL; + if (S_ISREG(file_header->mode) && file_header->size == 0) + hard_link = file_header->link_target; + #if ENABLE_FEATURE_TAR_LONG_OPTIONS dst_name = file_header->name; - dst_link = file_header->link_target; if (archive_handle->tar__strip_components) { unsigned n = archive_handle->tar__strip_components; do { @@ -47,21 +51,18 @@ void FAST_FUNC data_extract_all(archive_handle_t *archive_handle) * Link target is shortened only for hardlinks: * softlinks restored unchanged. */ - if (S_ISREG(file_header->mode) - && file_header->size == 0 - && dst_link - ) { + if (hard_link) { // GNU tar 1.26 does not check that we reached end of link name: // if "dir/hardlink" is hardlinked to "file", // tar xvf a.tar --strip-components=1 says: // tar: hardlink: Cannot hard link to '': No such file or directory // and continues processing. We silently skip such entries. - dst_link = strchr(dst_link, '/'); - if (!dst_link || dst_link[1] == '\0') { + hard_link = strchr(hard_link, '/'); + if (!hard_link || hard_link[1] == '\0') { data_skip(archive_handle); return; } - dst_link++; + hard_link++; } } while (--n != 0); } @@ -79,12 +80,7 @@ void FAST_FUNC data_extract_all(archive_handle_t *archive_handle) if (archive_handle->ah_flags & ARCHIVE_UNLINK_OLD) { /* Remove the entry if it exists */ if (!S_ISDIR(file_header->mode)) { - /* Is it hardlink? - * We encode hard links as regular files of size 0 with a symlink */ - if (S_ISREG(file_header->mode) - && file_header->size == 0 - && dst_link - ) { + if (hard_link) { /* Ugly special case: * tar cf t.tar hardlink1 hardlink2 hardlink1 * results in this tarball structure: @@ -92,7 +88,7 @@ void FAST_FUNC data_extract_all(archive_handle_t *archive_handle) * hardlink2 -> hardlink1 * hardlink1 -> hardlink1 <== !!! */ - if (strcmp(dst_link, dst_name) == 0) + if (strcmp(hard_link, dst_name) == 0) goto ret; } /* Proceed with deleting */ @@ -128,19 +124,14 @@ void FAST_FUNC data_extract_all(archive_handle_t *archive_handle) } } - /* Handle hard links separately - * We encode hard links as regular files of size 0 with a symlink */ - if (S_ISREG(file_header->mode) - && file_header->size == 0 - && dst_link - ) { - /* Hard link */ - res = link(dst_link, dst_name); + /* Handle hard links separately */ + if (hard_link) { + res = link(hard_link, dst_name); if (res != 0 && !(archive_handle->ah_flags & ARCHIVE_EXTRACT_QUIET)) { bb_perror_msg("can't create %slink " "from %s to %s", "hard", dst_name, - dst_link); + hard_link); } /* Hardlinks have no separate mode/ownership, skip chown/chmod */ goto ret; From 537389cedd3acaf658c73ec4e36a40db00a5a92f Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Thu, 22 Oct 2015 13:38:09 +0200 Subject: [PATCH 042/260] tar: fix files skipped with --strip_components not resetting selinux context Signed-off-by: Denys Vlasenko --- archival/libarchive/data_extract_all.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/archival/libarchive/data_extract_all.c b/archival/libarchive/data_extract_all.c index cf821c9de..bd034afdc 100644 --- a/archival/libarchive/data_extract_all.c +++ b/archival/libarchive/data_extract_all.c @@ -8,7 +8,6 @@ void FAST_FUNC data_extract_all(archive_handle_t *archive_handle) { - file_header_t *file_header = archive_handle->file_header; int dst_fd; int res; @@ -44,7 +43,7 @@ void FAST_FUNC data_extract_all(archive_handle_t *archive_handle) dst_name = strchr(dst_name, '/'); if (!dst_name || dst_name[1] == '\0') { data_skip(archive_handle); - return; + goto ret; } dst_name++; /* @@ -60,7 +59,7 @@ void FAST_FUNC data_extract_all(archive_handle_t *archive_handle) hard_link = strchr(hard_link, '/'); if (!hard_link || hard_link[1] == '\0') { data_skip(archive_handle); - return; + goto ret; } hard_link++; } From accd9eeb719916da974584b33b1aeced5f3bb346 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Thu, 22 Oct 2015 16:01:57 +0200 Subject: [PATCH 043/260] remove systemd support systemd people are not willing to play nice with the rest of the world. Therefore there is no reason for the rest of the world to cooperate with them. Signed-off-by: Denys Vlasenko --- configs/android2_defconfig | 1 - configs/android_defconfig | 1 - configs/android_ndk_defconfig | 1 - configs/cygwin_defconfig | 1 - include/libbb.h | 5 --- libbb/systemd_support.c | 62 ----------------------------------- sysklogd/syslogd.c | 5 --- 7 files changed, 76 deletions(-) delete mode 100644 libbb/systemd_support.c diff --git a/configs/android2_defconfig b/configs/android2_defconfig index 4dfbdb526..1095094fe 100644 --- a/configs/android2_defconfig +++ b/configs/android2_defconfig @@ -89,7 +89,6 @@ CONFIG_PREFIX="./_install" # # Busybox Library Tuning # -# CONFIG_FEATURE_SYSTEMD is not set # CONFIG_FEATURE_RTMINMAX is not set CONFIG_PASSWORD_MINLEN=6 CONFIG_MD5_SMALL=1 diff --git a/configs/android_defconfig b/configs/android_defconfig index e35830e7f..082994b6c 100644 --- a/configs/android_defconfig +++ b/configs/android_defconfig @@ -107,7 +107,6 @@ CONFIG_PREFIX="./_install" # # Busybox Library Tuning # -# CONFIG_FEATURE_SYSTEMD is not set # CONFIG_FEATURE_RTMINMAX is not set CONFIG_PASSWORD_MINLEN=6 CONFIG_MD5_SMALL=1 diff --git a/configs/android_ndk_defconfig b/configs/android_ndk_defconfig index 66c85268f..63fafb468 100644 --- a/configs/android_ndk_defconfig +++ b/configs/android_ndk_defconfig @@ -96,7 +96,6 @@ CONFIG_PREFIX="./_install" # # Busybox Library Tuning # -# CONFIG_FEATURE_SYSTEMD is not set # CONFIG_FEATURE_RTMINMAX is not set CONFIG_PASSWORD_MINLEN=6 CONFIG_MD5_SMALL=1 diff --git a/configs/cygwin_defconfig b/configs/cygwin_defconfig index aa346e34c..2c02be743 100644 --- a/configs/cygwin_defconfig +++ b/configs/cygwin_defconfig @@ -89,7 +89,6 @@ CONFIG_PREFIX="./_install" # # Busybox Library Tuning # -# CONFIG_FEATURE_SYSTEMD is not set CONFIG_FEATURE_RTMINMAX=y CONFIG_PASSWORD_MINLEN=6 CONFIG_MD5_SMALL=1 diff --git a/include/libbb.h b/include/libbb.h index 1a3f6d8ce..28f57223d 100644 --- a/include/libbb.h +++ b/include/libbb.h @@ -1333,11 +1333,6 @@ extern void selinux_preserve_fcontext(int fdesc) FAST_FUNC; extern void selinux_or_die(void) FAST_FUNC; -/* systemd support */ -#define SD_LISTEN_FDS_START 3 -int sd_listen_fds(void); - - /* setup_environment: * if chdir pw->pw_dir: ok: else if to_tmp == 1: goto /tmp else: goto / or die * if clear_env = 1: cd(pw->pw_dir), clear environment, then set diff --git a/libbb/systemd_support.c b/libbb/systemd_support.c deleted file mode 100644 index 542a3efff..000000000 --- a/libbb/systemd_support.c +++ /dev/null @@ -1,62 +0,0 @@ -/* - * Copyright (C) 2011 Davide Cavalca - * - * Based on http://cgit.freedesktop.org/systemd/tree/src/sd-daemon.c - * Copyright 2010 Lennart Poettering - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation files - * (the "Software"), to deal in the Software without restriction, - * including without limitation the rights to use, copy, modify, merge, - * publish, distribute, sublicense, and/or sell copies of the Software, - * and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ -#include "libbb.h" - -//config:config FEATURE_SYSTEMD -//config: bool "Enable systemd support" -//config: default y -//config: help -//config: If you plan to use busybox daemons on a system where daemons -//config: are controlled by systemd, enable this option. -//config: If you don't use systemd, it is still safe to enable it, -//config: but the downside is increased code size. - -//kbuild:lib-$(CONFIG_FEATURE_SYSTEMD) += systemd_support.o - -int sd_listen_fds(void) -{ - const char *e; - int n; - int fd; - - e = getenv("LISTEN_PID"); - if (!e) - return 0; - n = xatoi_positive(e); - /* Is this for us? */ - if (getpid() != (pid_t) n) - return 0; - - e = getenv("LISTEN_FDS"); - if (!e) - return 0; - n = xatoi_positive(e); - for (fd = SD_LISTEN_FDS_START; fd < SD_LISTEN_FDS_START + n; fd++) - close_on_exec_on(fd); - - return n; -} diff --git a/sysklogd/syslogd.c b/sysklogd/syslogd.c index 288b29cf7..0ea557a6c 100644 --- a/sysklogd/syslogd.c +++ b/sysklogd/syslogd.c @@ -936,11 +936,6 @@ static NOINLINE int create_socket(void) int sock_fd; char *dev_log_name; -#if ENABLE_FEATURE_SYSTEMD - if (sd_listen_fds() == 1) - return SD_LISTEN_FDS_START; -#endif - memset(&sunx, 0, sizeof(sunx)); sunx.sun_family = AF_UNIX; From a96074874857b31361d02ead97a1152164568918 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Thu, 22 Oct 2015 16:37:01 +0200 Subject: [PATCH 044/260] tar: add a test that we don't write into symlinks Signed-off-by: Denys Vlasenko --- testsuite/tar.tests | 43 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) diff --git a/testsuite/tar.tests b/testsuite/tar.tests index 383a4646c..890a73dd5 100755 --- a/testsuite/tar.tests +++ b/testsuite/tar.tests @@ -256,6 +256,49 @@ Ok "" "" SKIP= +# attack.tar.bz2 has symlink pointing to a system file +# followed by a regular file with the same name +# containing "root::0:0::/root:/bin/sh": +# lrwxrwxrwx root/root passwd -> /tmp/passwd +# -rw-r--r-- root/root passwd +# naive tar implementation may end up creating the symlink +# and then writing into it. +# The correct implementation unlinks target before +# creating the second file. +# We test that /tmp/passwd remains empty: +optional UUDECODE FEATURE_SEAMLESS_BZ2 +testing "tar does not extract into symlinks" "\ +>>/tmp/passwd && uudecode -o input && tar xf input 2>&1 && rm passwd; cat /tmp/passwd; echo \$? +" "\ +0 +" \ +"" "\ +begin-base64 644 attack.tar.bz2 +QlpoOTFBWSZTWRVn/bIAAKt7hMqwAEBAAP2QAhB0Y96AAACACCAAlISgpqe0 +po0DIaDynqAkpDRP1ANAhiYNSPR8VchKhAz0AK59+DA6FcMKBggOARIJdVHL +DGllrjs20ATUgR1HmccBX3EhoMnpMJaNyggmxgLDMz54lBnBTJO/1L1lbMS4 +l4/V8LDoe90yiWJhOJvIypgEfxdyRThQkBVn/bI= +==== +" +SKIP= +# And same with -k +optional UUDECODE FEATURE_SEAMLESS_BZ2 +testing "tar -k does not extract into symlinks" "\ +>>/tmp/passwd && uudecode -o input && tar xf input -k 2>&1 && rm passwd; cat /tmp/passwd; echo \$? +" "\ +tar: can't open 'passwd': File exists +0 +" \ +"" "\ +begin-base64 644 attack.tar.bz2 +QlpoOTFBWSZTWRVn/bIAAKt7hMqwAEBAAP2QAhB0Y96AAACACCAAlISgpqe0 +po0DIaDynqAkpDRP1ANAhiYNSPR8VchKhAz0AK59+DA6FcMKBggOARIJdVHL +DGllrjs20ATUgR1HmccBX3EhoMnpMJaNyggmxgLDMz54lBnBTJO/1L1lbMS4 +l4/V8LDoe90yiWJhOJvIypgEfxdyRThQkBVn/bI= +==== +" +SKIP= + cd .. && rm -rf tar.tempdir || exit 1 From 641caaec3d495f3a92f652f12ab70b02ba9312ac Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Fri, 23 Oct 2015 01:44:22 +0200 Subject: [PATCH 045/260] libbb: factor out code which queries screen width function old new delta get_terminal_width - 17 +17 stty_main 1196 1197 +1 pstree_main 321 319 -2 ls_main 735 731 -4 watch_main 232 225 -7 bb_progress_update 714 706 -8 ps_main 555 543 -12 run_applet_and_exit 708 695 -13 ------------------------------------------------------------------------------ (add/remove: 1/0 grow/shrink: 1/6 up/down: 18/-46) Total: -28 byte Signed-off-by: Denys Vlasenko --- coreutils/ls.c | 2 +- coreutils/stty.c | 2 +- include/libbb.h | 1 + libbb/appletlib.c | 2 +- libbb/progress.c | 9 +-------- libbb/xfuncs.c | 6 ++++++ procps/ps.c | 4 ++-- procps/pstree.c | 2 +- procps/watch.c | 2 +- 9 files changed, 15 insertions(+), 15 deletions(-) diff --git a/coreutils/ls.c b/coreutils/ls.c index 14c8beaff..c48498858 100644 --- a/coreutils/ls.c +++ b/coreutils/ls.c @@ -1105,7 +1105,7 @@ int ls_main(int argc UNUSED_PARAM, char **argv) #if ENABLE_FEATURE_AUTOWIDTH /* obtain the terminal width */ - get_terminal_width_height(STDIN_FILENO, &G_terminal_width, NULL); + G_terminal_width = get_terminal_width(STDIN_FILENO); /* go one less... */ G_terminal_width--; #endif diff --git a/coreutils/stty.c b/coreutils/stty.c index 378a848e7..b63b0b91a 100644 --- a/coreutils/stty.c +++ b/coreutils/stty.c @@ -1403,7 +1403,7 @@ int stty_main(int argc UNUSED_PARAM, char **argv) perror_on_device_and_die("%s"); if (stty_state & (STTY_verbose_output | STTY_recoverable_output | STTY_noargs)) { - get_terminal_width_height(STDOUT_FILENO, &G.max_col, NULL); + G.max_col = get_terminal_width(STDOUT_FILENO); output_func(&mode, display_all); return EXIT_SUCCESS; } diff --git a/include/libbb.h b/include/libbb.h index 28f57223d..82484f911 100644 --- a/include/libbb.h +++ b/include/libbb.h @@ -1399,6 +1399,7 @@ extern void print_login_prompt(void) FAST_FUNC; char *xmalloc_ttyname(int fd) FAST_FUNC RETURNS_MALLOC; /* NB: typically you want to pass fd 0, not 1. Think 'applet | grep something' */ int get_terminal_width_height(int fd, unsigned *width, unsigned *height) FAST_FUNC; +int get_terminal_width(int fd) FAST_FUNC; int tcsetattr_stdin_TCSANOW(const struct termios *tp) FAST_FUNC; diff --git a/libbb/appletlib.c b/libbb/appletlib.c index 0f83eda4b..58bb2f1a0 100644 --- a/libbb/appletlib.c +++ b/libbb/appletlib.c @@ -623,7 +623,7 @@ static int busybox_main(char **argv) output_width = 80; if (ENABLE_FEATURE_AUTOWIDTH) { /* Obtain the terminal width */ - get_terminal_width_height(0, &output_width, NULL); + output_width = get_terminal_width(2); } dup2(1, 2); diff --git a/libbb/progress.c b/libbb/progress.c index 372feb0c2..6154dca17 100644 --- a/libbb/progress.c +++ b/libbb/progress.c @@ -45,13 +45,6 @@ enum { STALLTIME = 5 }; -static unsigned int get_tty2_width(void) -{ - unsigned width; - get_terminal_width_height(2, &width, NULL); - return width; -} - void FAST_FUNC bb_progress_init(bb_progress_t *p, const char *curfile) { #if ENABLE_UNICODE_SUPPORT @@ -148,7 +141,7 @@ void FAST_FUNC bb_progress_update(bb_progress_t *p, unsigned ratio = 100 * beg_and_transferred / totalsize; fprintf(stderr, "%4u%%", ratio); - barlength = get_tty2_width() - 49; + barlength = get_terminal_width(2) - 49; if (barlength > 0) { /* god bless gcc for variable arrays :) */ char buf[barlength + 1]; diff --git a/libbb/xfuncs.c b/libbb/xfuncs.c index 0c9969640..206edb4a0 100644 --- a/libbb/xfuncs.c +++ b/libbb/xfuncs.c @@ -270,6 +270,12 @@ int FAST_FUNC get_terminal_width_height(int fd, unsigned *width, unsigned *heigh *width = wh_helper(win.ws_col, 80, "COLUMNS", &err); return err; } +int FAST_FUNC get_terminal_width(int fd) +{ + unsigned width; + get_terminal_width_height(fd, &width, NULL); + return width; +} int FAST_FUNC tcsetattr_stdin_TCSANOW(const struct termios *tp) { diff --git a/procps/ps.c b/procps/ps.c index bde5f9485..fbafa68a9 100644 --- a/procps/ps.c +++ b/procps/ps.c @@ -622,7 +622,7 @@ int ps_main(int argc UNUSED_PARAM, char **argv) * and such large widths */ terminal_width = MAX_WIDTH; if (isatty(1)) { - get_terminal_width_height(0, &terminal_width, NULL); + terminal_width = get_terminal_width(0); if (--terminal_width > MAX_WIDTH) terminal_width = MAX_WIDTH; } @@ -672,7 +672,7 @@ int ps_main(int argc UNUSED_PARAM, char **argv UNUSED_PARAM) if (w_count) { terminal_width = (w_count == 1) ? 132 : MAX_WIDTH; } else { - get_terminal_width_height(0, &terminal_width, NULL); + terminal_width = get_terminal_width(0); /* Go one less... */ if (--terminal_width > MAX_WIDTH) terminal_width = MAX_WIDTH; diff --git a/procps/pstree.c b/procps/pstree.c index ed1a41289..c5fb83688 100644 --- a/procps/pstree.c +++ b/procps/pstree.c @@ -381,7 +381,7 @@ int pstree_main(int argc UNUSED_PARAM, char **argv) INIT_G(); - get_terminal_width_height(0, &G.output_width, NULL); + G.output_width = get_terminal_width(0); opt_complementary = "?1"; getopt32(argv, "p"); diff --git a/procps/watch.c b/procps/watch.c index 0397f21bf..97aa04767 100644 --- a/procps/watch.c +++ b/procps/watch.c @@ -72,7 +72,7 @@ int watch_main(int argc UNUSED_PARAM, char **argv) // STDERR_FILENO is procps3 compat: // "watch ls 2>/dev/null" does not detect tty size - get_terminal_width_height(STDERR_FILENO, &new_width, NULL); + new_width = get_terminal_width(STDERR_FILENO); if (new_width != width) { width = new_width; free(header); From d3d6534b2a86bdd651aa39dfabe620fe2208459f Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Fri, 23 Oct 2015 02:01:38 +0200 Subject: [PATCH 046/260] wget: if stderr is not a tty, progress bar shouldn't use tty-tricks function old new delta bb_progress_update 706 768 +62 Signed-off-by: Denys Vlasenko --- libbb/progress.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/libbb/progress.c b/libbb/progress.c index 6154dca17..3c2f01667 100644 --- a/libbb/progress.c +++ b/libbb/progress.c @@ -73,7 +73,7 @@ void FAST_FUNC bb_progress_update(bb_progress_t *p, { uoff_t beg_and_transferred; unsigned since_last_update, elapsed; - int barlength; + int notty; int kiloscale; //transferred = 1234; /* use for stall detection testing */ @@ -130,14 +130,17 @@ void FAST_FUNC bb_progress_update(bb_progress_t *p, } } + notty = !isatty(STDERR_FILENO); + if (ENABLE_UNICODE_SUPPORT) - fprintf(stderr, "\r%s", p->curfile); + fprintf(stderr, "\r%s" + notty, p->curfile); else - fprintf(stderr, "\r%-20.20s", p->curfile); + fprintf(stderr, "\r%-20.20s" + notty, p->curfile); beg_and_transferred = beg_size + transferred; if (totalsize != 0) { + int barlength; unsigned ratio = 100 * beg_and_transferred / totalsize; fprintf(stderr, "%4u%%", ratio); @@ -197,4 +200,6 @@ void FAST_FUNC bb_progress_update(bb_progress_t *p, hours = eta / 3600; fprintf(stderr, "%3u:%02u:%02u ETA", hours, secs / 60, secs % 60); } + if (notty) + fputc('\n', stderr); } From 59f8475924760a5d74e18a88f325493e7c38c537 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Fri, 23 Oct 2015 11:49:04 +0200 Subject: [PATCH 047/260] httpd: fix heap buffer overflow. Closes 8426 function old new delta send_headers 654 677 +23 Signed-off-by: Denys Vlasenko --- networking/httpd.c | 25 +++++++++++++++++++------ 1 file changed, 19 insertions(+), 6 deletions(-) diff --git a/networking/httpd.c b/networking/httpd.c index 00169c36d..ed15fd883 100644 --- a/networking/httpd.c +++ b/networking/httpd.c @@ -967,19 +967,30 @@ static void send_headers(int responseNum) } #endif if (responseNum == HTTP_MOVED_TEMPORARILY) { - len += sprintf(iobuf + len, "Location: %s/%s%s\r\n", + /* Responding to "GET /dir" with + * "HTTP/1.0 302 Found" "Location: /dir/" + * - IOW, asking them to repeat with a slash. + * Here, overflow IS possible, can't use sprintf: + * mkdir test + * python -c 'print("get /test?" + ("x" * 8192))' | busybox httpd -i -h . + */ + len += snprintf(iobuf + len, IOBUF_SIZE-3 - len, + "Location: %s/%s%s\r\n", found_moved_temporarily, (g_query ? "?" : ""), (g_query ? g_query : "")); + if (len > IOBUF_SIZE-3) + len = IOBUF_SIZE-3; } #if ENABLE_FEATURE_HTTPD_ERROR_PAGES if (error_page && access(error_page, R_OK) == 0) { - strcat(iobuf, "\r\n"); - len += 2; - - if (DEBUG) + iobuf[len++] = '\r'; + iobuf[len++] = '\n'; + if (DEBUG) { + iobuf[len] = '\0'; fprintf(stderr, "headers: '%s'\n", iobuf); + } full_write(STDOUT_FILENO, iobuf, len); if (DEBUG) fprintf(stderr, "writing error page: '%s'\n", error_page); @@ -1021,8 +1032,10 @@ static void send_headers(int responseNum) responseNum, responseString, responseNum, responseString, infoString); } - if (DEBUG) + if (DEBUG) { + iobuf[len] = '\0'; fprintf(stderr, "headers: '%s'\n", iobuf); + } if (full_write(STDOUT_FILENO, iobuf, len) != len) { if (verbose > 1) bb_perror_msg("error"); From 00da72bee09cfe4a757cbba4465a76269dae9f43 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Fri, 23 Oct 2015 18:43:16 +0200 Subject: [PATCH 048/260] tidy up strtok use Signed-off-by: Denys Vlasenko --- libbb/kernel_version.c | 8 ++++---- shell/ash.c | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/libbb/kernel_version.c b/libbb/kernel_version.c index 738ed022b..9b6c62299 100644 --- a/libbb/kernel_version.c +++ b/libbb/kernel_version.c @@ -20,16 +20,16 @@ int FAST_FUNC get_linux_version_code(void) { struct utsname name; - char *s, *t; + char *t; int i, r; uname(&name); /* never fails */ - s = name.release; + t = name.release; r = 0; for (i = 0; i < 3; i++) { - t = strtok(s, "."); + t = strtok(t, "."); r = r * 256 + (t ? atoi(t) : 0); - s = NULL; + t = NULL; } return r; } diff --git a/shell/ash.c b/shell/ash.c index 8a1628e81..17121aa9b 100644 --- a/shell/ash.c +++ b/shell/ash.c @@ -2556,7 +2556,7 @@ updatepwd(const char *dir) new = stack_putstr(p, new); USTPUTC('/', new); } - p = strtok(0, "/"); + p = strtok(NULL, "/"); } if (new > lim) STUNPUTC(new); From 049b007865e2dfcfd2093db732b3bfbcb75b5c77 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Sat, 24 Oct 2015 03:45:57 +0200 Subject: [PATCH 049/260] pmap: fix bogus {no such process} comm field text function old new delta read_cmdline 246 266 +20 procps_get_maps 196 193 -3 packed_usage 30413 30404 -9 ------------------------------------------------------------------------------ (add/remove: 0/0 grow/shrink: 1/2 up/down: 20/-12) Total: 8 bytes Signed-off-by: Denys Vlasenko --- libbb/procps.c | 8 +++++--- procps/pmap.c | 4 ++-- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/libbb/procps.c b/libbb/procps.c index 05eefe0da..4edc54d48 100644 --- a/libbb/procps.c +++ b/libbb/procps.c @@ -588,12 +588,14 @@ void FAST_FUNC read_cmdline(char *buf, int col, unsigned pid, const char *comm) buf[sz] = ' '; sz--; } + if (base[0] == '-') /* "-sh" (login shell)? */ + base++; /* If comm differs from argv0, prepend "{comm} ". * It allows to see thread names set by prctl(PR_SET_NAME). */ - if (base[0] == '-') /* "-sh" (login shell)? */ - base++; + if (!comm) + return; comm_len = strlen(comm); /* Why compare up to comm_len, not COMM_LEN-1? * Well, some processes rewrite argv, and use _spaces_ there @@ -612,7 +614,7 @@ void FAST_FUNC read_cmdline(char *buf, int col, unsigned pid, const char *comm) buf[col - 1] = '\0'; } } else { - snprintf(buf, col, "[%s]", comm); + snprintf(buf, col, "[%s]", comm ? comm : "?"); } } diff --git a/procps/pmap.c b/procps/pmap.c index fd995a54d..aa221cfb8 100644 --- a/procps/pmap.c +++ b/procps/pmap.c @@ -20,7 +20,7 @@ //usage:#define pmap_trivial_usage //usage: "[-xq] PID" //usage:#define pmap_full_usage "\n\n" -//usage: "Display detailed process memory usage" +//usage: "Display process memory usage" //usage: "\n" //usage: "\n -x Show details" //usage: "\n -q Quiet" @@ -66,7 +66,7 @@ static int procps_get_maps(pid_t pid, unsigned opt) int ret; char buf[256]; - read_cmdline(buf, sizeof(buf), pid, "no such process"); + read_cmdline(buf, sizeof(buf), pid, NULL); printf("%u: %s\n", (int)pid, buf); if (!(opt & OPT_q) && (opt & OPT_x)) From 2e9a0662bce58b0fe838f7e1e03c35c4765ff3bc Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Sat, 24 Oct 2015 04:13:16 +0200 Subject: [PATCH 050/260] MODPROBE_SMALL is not experimental anymore Signed-off-by: Denys Vlasenko --- modutils/Config.src | 3 --- 1 file changed, 3 deletions(-) diff --git a/modutils/Config.src b/modutils/Config.src index 449ac65af..0b11832bc 100644 --- a/modutils/Config.src +++ b/modutils/Config.src @@ -38,9 +38,6 @@ config MODPROBE_SMALL - rmmod is an alias to modprobe -r - depmod generates modules.dep.bb - As of 2008-07, this code is experimental. It is 14kb smaller - than "non-small" modutils. - config FEATURE_MODPROBE_SMALL_OPTIONS_ON_CMDLINE bool "Accept module options on modprobe command line" default y From cd13974b201972ffb605e243f63f674e95b99e5c Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Sat, 24 Oct 2015 04:17:04 +0200 Subject: [PATCH 051/260] rmmod: fix bad error message Before: ># busybox_old rmmod gtrhfhdfghdf rmmod: can't unload 'gtrhfhdfghdf': unknown symbol in module, or unknown parameter After: ># busybox rmmod gtrhfhdfghdf rmmod: can't unload module 'gtrhfhdfghdf': No such file or directory function old new delta modprobe_main 726 721 -5 do_modprobe 599 590 -9 rmmod_main 187 169 -18 ------------------------------------------------------------------------------ (add/remove: 0/0 grow/shrink: 0/3 up/down: 0/-32) Total: -32 bytes Signed-off-by: Denys Vlasenko --- modutils/modprobe.c | 7 +++---- modutils/modutils.c | 5 +++++ modutils/rmmod.c | 12 +++++++----- 3 files changed, 15 insertions(+), 9 deletions(-) diff --git a/modutils/modprobe.c b/modutils/modprobe.c index 314a7a1cb..952ba0377 100644 --- a/modutils/modprobe.c +++ b/modutils/modprobe.c @@ -461,9 +461,8 @@ static int do_modprobe(struct module_entry *m) rc = bb_delete_module(m2->modname, O_EXCL); if (rc) { if (first) { - bb_error_msg("can't unload module %s: %s", - humanly_readable_name(m2), - moderror(rc)); + bb_perror_msg("can't unload module %s", + humanly_readable_name(m2)); break; } } else { @@ -622,7 +621,7 @@ int modprobe_main(int argc UNUSED_PARAM, char **argv) * autoclean will be removed". */ if (bb_delete_module(NULL, O_NONBLOCK | O_EXCL) != 0) - bb_perror_msg_and_die("rmmod"); + bb_perror_nomsg_and_die(); } return EXIT_SUCCESS; } diff --git a/modutils/modutils.c b/modutils/modutils.c index 84300d931..ef4134af5 100644 --- a/modutils/modutils.c +++ b/modutils/modutils.c @@ -190,6 +190,11 @@ int FAST_FUNC bb_delete_module(const char *module, unsigned int flags) return errno; } +/* Note: not suitable for delete_module() errnos. + * For them, probably only EWOULDBLOCK needs explaining: + * "Other modules depend on us". So far we don't do such + * translation and don't use moderror() for removal errors. + */ const char* FAST_FUNC moderror(int err) { switch (err) { diff --git a/modutils/rmmod.c b/modutils/rmmod.c index f13ff9eb6..5c353ef95 100644 --- a/modutils/rmmod.c +++ b/modutils/rmmod.c @@ -28,7 +28,7 @@ int rmmod_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; int rmmod_main(int argc UNUSED_PARAM, char **argv) { - int n; + int n, err; unsigned flags = O_NONBLOCK | O_EXCL; /* Parse command line. */ @@ -40,7 +40,8 @@ int rmmod_main(int argc UNUSED_PARAM, char **argv) flags |= O_TRUNC; if (n & 4) { /* Unload _all_ unused modules via NULL delete_module() call */ - if (bb_delete_module(NULL, flags) != 0 && errno != EFAULT) + err = bb_delete_module(NULL, flags); + if (err && err != EFAULT) bb_perror_msg_and_die("rmmod"); return EXIT_SUCCESS; } @@ -58,9 +59,10 @@ int rmmod_main(int argc UNUSED_PARAM, char **argv) safe_strncpy(modname, bname, MODULE_NAME_LEN); else filename2modname(bname, modname); - if (bb_delete_module(modname, flags)) - bb_error_msg_and_die("can't unload '%s': %s", - modname, moderror(errno)); + err = bb_delete_module(modname, flags); + if (err) + bb_perror_msg_and_die("can't unload module '%s'", + modname); } return EXIT_SUCCESS; From 941e7a491971574e5d06227f8dc63806335b8745 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Sat, 24 Oct 2015 04:19:56 +0200 Subject: [PATCH 052/260] reuse a string Signed-off-by: Denys Vlasenko --- modutils/modprobe.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modutils/modprobe.c b/modutils/modprobe.c index 952ba0377..05bf02cf8 100644 --- a/modutils/modprobe.c +++ b/modutils/modprobe.c @@ -461,7 +461,7 @@ static int do_modprobe(struct module_entry *m) rc = bb_delete_module(m2->modname, O_EXCL); if (rc) { if (first) { - bb_perror_msg("can't unload module %s", + bb_perror_msg("can't unload module '%s'", humanly_readable_name(m2)); break; } From 9a512176686d5f1548dc1e1c610af440a3ee0d73 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Sat, 24 Oct 2015 04:45:22 +0200 Subject: [PATCH 053/260] dumpleases: make host names sanitized to shell-friendly condition function old new delta add_lease 271 298 +27 Signed-off-by: Denys Vlasenko --- networking/udhcp/leases.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/networking/udhcp/leases.c b/networking/udhcp/leases.c index 745340ad3..844bb60b1 100644 --- a/networking/udhcp/leases.c +++ b/networking/udhcp/leases.c @@ -65,10 +65,15 @@ struct dyn_lease* FAST_FUNC add_lease( if (hostname_len > sizeof(oldest->hostname)) hostname_len = sizeof(oldest->hostname); p = safe_strncpy(oldest->hostname, hostname, hostname_len); - /* sanitization (s/non-ASCII/^/g) */ + /* + * Sanitization (s/bad_char/./g). + * The intent is not to allow only "DNS-valid" hostnames, + * but merely make dumpleases output safe for shells to use. + * We accept "0-9A-Za-z._-", all other chars turn to dots. + */ while (*p) { - if (*p < ' ' || *p > 126) - *p = '^'; + if (!isalnum(*p) && *p != '-' && *p != '_') + *p = '.'; p++; } } From d32a1a4054444d8193736ee4c5f515fa90dbb24f Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Sat, 24 Oct 2015 05:30:58 +0200 Subject: [PATCH 054/260] New example of a service: examples/var_service/zcip_if Zeroconf for IPv4 Signed-off-by: Denys Vlasenko --- examples/var_service/zcip_if/README | 5 +++ examples/var_service/zcip_if/convert2ipconf | 22 ++++++++++ examples/var_service/zcip_if/log/run | 21 ++++++++++ examples/var_service/zcip_if/p_log | 4 ++ examples/var_service/zcip_if/run | 20 +++++++++ examples/var_service/zcip_if/w_log | 4 ++ examples/var_service/zcip_if/zcip_handler | 46 +++++++++++++++++++++ 7 files changed, 122 insertions(+) create mode 100644 examples/var_service/zcip_if/README create mode 100755 examples/var_service/zcip_if/convert2ipconf create mode 100755 examples/var_service/zcip_if/log/run create mode 100755 examples/var_service/zcip_if/p_log create mode 100755 examples/var_service/zcip_if/run create mode 100755 examples/var_service/zcip_if/w_log create mode 100755 examples/var_service/zcip_if/zcip_handler diff --git a/examples/var_service/zcip_if/README b/examples/var_service/zcip_if/README new file mode 100644 index 000000000..4ddccb22d --- /dev/null +++ b/examples/var_service/zcip_if/README @@ -0,0 +1,5 @@ +The real README file is one directory up. + +This directory's run script can have useful comments. +If it doesn't but you feel it should, please send a patch +to busybox's mailing list. diff --git a/examples/var_service/zcip_if/convert2ipconf b/examples/var_service/zcip_if/convert2ipconf new file mode 100755 index 000000000..aa133d815 --- /dev/null +++ b/examples/var_service/zcip_if/convert2ipconf @@ -0,0 +1,22 @@ +#!/bin/sh +# convert: + +#interface=eth1 +#ip=169.254.x.y + +#let cfg=cfg+1 +#if[$cfg]=...; ip[$cfg]=...; ipmask[$cfg]=.../...; gw[$cfg]=...; net[$cfg]=... dns[$cfg]=... + +exec >/dev/null +#exec >"$0.out" # debug +exec 2>&1 + +test "$interface" || exit 1 +test "$ip" || exit 1 + +{ +echo "let cfg=cfg+1" +test "$interface" && echo "if[\$cfg]='$interface'" +test "$ip" && echo "ip[\$cfg]='$ip'" +test "$ip" && echo "ipmask[\$cfg]='$ip/16'" +} >"$1" diff --git a/examples/var_service/zcip_if/log/run b/examples/var_service/zcip_if/log/run new file mode 100755 index 000000000..560d1b19f --- /dev/null +++ b/examples/var_service/zcip_if/log/run @@ -0,0 +1,21 @@ +#!/bin/sh + +user=logger + +logdir="/var/log/service/`(cd ..;basename $PWD)`" +mkdir -p "$logdir" 2>/dev/null +chown -R "$user": "$logdir" +chmod -R go-rwxst,u+rwX "$logdir" +rm logdir +ln -s "$logdir" logdir + +# make this dir accessible to logger +chmod a+rX . + +exec >/dev/null +exec 2>&1 +exec \ +env - PATH="$PATH" \ +softlimit \ +setuidgid "$user" \ +svlogd -tt "$logdir" diff --git a/examples/var_service/zcip_if/p_log b/examples/var_service/zcip_if/p_log new file mode 100755 index 000000000..a2521be05 --- /dev/null +++ b/examples/var_service/zcip_if/p_log @@ -0,0 +1,4 @@ +#!/bin/sh + +cd log/logdir || exit 1 +cat @* current | $PAGER diff --git a/examples/var_service/zcip_if/run b/examples/var_service/zcip_if/run new file mode 100755 index 000000000..94a875465 --- /dev/null +++ b/examples/var_service/zcip_if/run @@ -0,0 +1,20 @@ +#!/bin/sh + +exec 2>&1 +exec &1 | cut -b1-$((w-2))' diff --git a/examples/var_service/zcip_if/zcip_handler b/examples/var_service/zcip_if/zcip_handler new file mode 100755 index 000000000..13010db27 --- /dev/null +++ b/examples/var_service/zcip_if/zcip_handler @@ -0,0 +1,46 @@ +#!/bin/sh +# executed by zcip +# parameters: $1 and environment +# $1 is: +# +# init: zcip starts. Environment: +# interface=eth0 +# +# config: Address is obtained. +# interface=eth0 +# ip=169.254.a.b +# +# deconfig: Conflict or link went down. +# interface=eth0 + +service=${PWD##*/} +file_ipconf="$service.ipconf" +dir_ipconf="/var/run/service/fw" + +exec >/dev/null +#exec >>"$0.out" #debug +exec 2>&1 + +echo "`date`: Params: $*" + +if test x"$1" != x"config"; then + # Reconfigure network with this interface disabled + echo "Deconfiguring" + rm "$file_ipconf" + rm "$dir_ipconf/$file_ipconf" + sv u /var/service/fw + exit +fi + +# "config": we've got the address +#env # debug + +./convert2ipconf "$file_ipconf" +# Reconfigure routing and firewall if needed +diff --brief "$file_ipconf" "$dir_ipconf/$file_ipconf" >/dev/null 2>&1 +if test $? != 0; then + echo "Reconfiguring fw" + mkdir -p "$dir_ipconf" 2>/dev/null + cp "$file_ipconf" "$dir_ipconf/$file_ipconf" + sv u /var/service/fw +fi From 4f8ecf273c4a239d007125f3b96a55100b661c04 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Sat, 24 Oct 2015 14:55:33 +0200 Subject: [PATCH 055/260] update network service examples Signed-off-by: Denys Vlasenko --- examples/var_service/dhcp_if/convert2ntpconf | 2 +- examples/var_service/dhcp_if/dhcp_handler | 13 +++++++------ examples/var_service/dhcp_if/finish | 17 +++++++++++++++++ examples/var_service/dhcp_if/log/run | 2 +- examples/var_service/dhcp_if_pinger/run | 4 ++-- examples/var_service/ftpd/log/run | 2 +- examples/var_service/fw/run | 2 +- examples/var_service/httpd/log/run | 2 +- examples/var_service/ifplugd_if/log/run | 2 +- examples/var_service/ifplugd_if/run | 3 +++ examples/var_service/inetd/log/run | 2 +- examples/var_service/ntpd/log/run | 2 +- examples/var_service/ntpd/run | 2 +- examples/var_service/tftpd/log/run | 2 +- examples/var_service/zcip_if/finish | 13 +++++++++++++ examples/var_service/zcip_if/log/run | 2 +- examples/var_service/zcip_if/zcip_handler | 3 ++- 17 files changed, 55 insertions(+), 20 deletions(-) create mode 100755 examples/var_service/dhcp_if/finish create mode 100755 examples/var_service/zcip_if/finish diff --git a/examples/var_service/dhcp_if/convert2ntpconf b/examples/var_service/dhcp_if/convert2ntpconf index debf1ebfe..e9d829308 100755 --- a/examples/var_service/dhcp_if/convert2ntpconf +++ b/examples/var_service/dhcp_if/convert2ntpconf @@ -29,6 +29,6 @@ test "$ip" || exit 1 { for n in $ntpsrv; do echo "let cfg=cfg+1" - echo "ntpip[\$cfg]='$n'"; + echo "ntpip[\$cfg]='$n'" done } >"$1" diff --git a/examples/var_service/dhcp_if/dhcp_handler b/examples/var_service/dhcp_if/dhcp_handler index 927e02a17..3d2a5cb79 100755 --- a/examples/var_service/dhcp_if/dhcp_handler +++ b/examples/var_service/dhcp_if/dhcp_handler @@ -36,7 +36,7 @@ service=${PWD##*/} file_ipconf="$service.ipconf" file_ntpconf="$service.ntpconf" dir_ipconf="/var/run/service/fw" -dir_ntpconf="/var/run/service/ntp" +dir_ntpconf="/var/run/service/ntpd" exec >/dev/null #exec >>"$0.out" #debug @@ -47,7 +47,7 @@ echo "`date`: Params: $*" if test x"$1" != x"bound" && test x"$1" != x"renew" ; then # Reconfigure network with this interface disabled echo "Deconfiguring" - rm "$service.out" + rm "env.out" rm "$file_ipconf" rm "$file_ntpconf" rm "$dir_ipconf/$file_ipconf" @@ -57,7 +57,8 @@ if test x"$1" != x"bound" && test x"$1" != x"renew" ; then fi # Bound: we've got the lease -#env >"$service.out" # debug +# Record information for e.g. dhcp_$IF_pinger service +env >"env.out" ./convert2ipconf "$file_ipconf" # Reconfigure routing and firewall if needed @@ -69,7 +70,7 @@ if test $? != 0; then sv u /var/service/fw fi -if test -d /var/service/ntp; then +if test -d /var/service/ntpd; then ./convert2ntpconf "$file_ntpconf" # Reconfigure ntp server addresses if needed diff --brief "$file_ntpconf" "$dir_ntpconf/$file_ntpconf" >/dev/null 2>&1 @@ -77,7 +78,7 @@ if test -d /var/service/ntp; then echo "Reconfiguring ntp" mkdir -p "$dir_ntpconf" 2>/dev/null cp "$file_ntpconf" "$dir_ntpconf/$file_ntpconf" - sv t /var/service/ntp - sv u /var/service/ntp + sv t /var/service/ntpd + sv u /var/service/ntpd fi fi diff --git a/examples/var_service/dhcp_if/finish b/examples/var_service/dhcp_if/finish new file mode 100755 index 000000000..5e7667a2d --- /dev/null +++ b/examples/var_service/dhcp_if/finish @@ -0,0 +1,17 @@ +#!/bin/sh +# executed when service is taken down ("sv d .") + +service=${PWD##*/} +file_ipconf="$service.ipconf" +file_ntpconf="$service.ntpconf" +dir_ipconf="/var/run/service/fw" +dir_ntpconf="/var/run/service/ntpd" + +# Reconfigure network with this interface disabled +echo "Finish: deconfiguring" +rm "env.out" +rm "$file_ipconf" +rm "$file_ntpconf" +rm "$dir_ipconf/$file_ipconf" +rm "$dir_ntpconf/$file_ntpconf" +sv u /var/service/fw diff --git a/examples/var_service/dhcp_if/log/run b/examples/var_service/dhcp_if/log/run index 560d1b19f..69d74b73f 100755 --- a/examples/var_service/dhcp_if/log/run +++ b/examples/var_service/dhcp_if/log/run @@ -6,7 +6,7 @@ logdir="/var/log/service/`(cd ..;basename $PWD)`" mkdir -p "$logdir" 2>/dev/null chown -R "$user": "$logdir" chmod -R go-rwxst,u+rwX "$logdir" -rm logdir +rm -rf logdir ln -s "$logdir" logdir # make this dir accessible to logger diff --git a/examples/var_service/dhcp_if_pinger/run b/examples/var_service/dhcp_if_pinger/run index 1868510d1..e0e87a16a 100755 --- a/examples/var_service/dhcp_if_pinger/run +++ b/examples/var_service/dhcp_if_pinger/run @@ -21,9 +21,9 @@ if test -f "$0.log"; then mv "$0.log.new" "$0.log" fi -test -f "/var/service/dhcp_$if/dhcp_$if.out" || exec env - sleep "$ping_time" +test -f "/var/service/dhcp_$if/env.out" || exec env - sleep "$ping_time" -. "/var/service/dhcp_$if/dhcp_$if.out" +. "/var/service/dhcp_$if/env.out" test x"$router" != x"" || exec env - sleep "$ping_time" #msg "Pinging $router" diff --git a/examples/var_service/ftpd/log/run b/examples/var_service/ftpd/log/run index 560d1b19f..69d74b73f 100755 --- a/examples/var_service/ftpd/log/run +++ b/examples/var_service/ftpd/log/run @@ -6,7 +6,7 @@ logdir="/var/log/service/`(cd ..;basename $PWD)`" mkdir -p "$logdir" 2>/dev/null chown -R "$user": "$logdir" chmod -R go-rwxst,u+rwX "$logdir" -rm logdir +rm -rf logdir ln -s "$logdir" logdir # make this dir accessible to logger diff --git a/examples/var_service/fw/run b/examples/var_service/fw/run index 396b678ab..81c7f2e7c 100755 --- a/examples/var_service/fw/run +++ b/examples/var_service/fw/run @@ -62,7 +62,7 @@ umask 077 # Make sure rundir/ exists mkdir -p "$rundir" 2>/dev/null -chown -R "$user:" "$rundir" +chown -R "$user": "$rundir" chmod -R a=rX "$rundir" rm -rf rundir 2>/dev/null ln -s "$rundir" rundir diff --git a/examples/var_service/httpd/log/run b/examples/var_service/httpd/log/run index 560d1b19f..69d74b73f 100755 --- a/examples/var_service/httpd/log/run +++ b/examples/var_service/httpd/log/run @@ -6,7 +6,7 @@ logdir="/var/log/service/`(cd ..;basename $PWD)`" mkdir -p "$logdir" 2>/dev/null chown -R "$user": "$logdir" chmod -R go-rwxst,u+rwX "$logdir" -rm logdir +rm -rf logdir ln -s "$logdir" logdir # make this dir accessible to logger diff --git a/examples/var_service/ifplugd_if/log/run b/examples/var_service/ifplugd_if/log/run index 560d1b19f..69d74b73f 100755 --- a/examples/var_service/ifplugd_if/log/run +++ b/examples/var_service/ifplugd_if/log/run @@ -6,7 +6,7 @@ logdir="/var/log/service/`(cd ..;basename $PWD)`" mkdir -p "$logdir" 2>/dev/null chown -R "$user": "$logdir" chmod -R go-rwxst,u+rwX "$logdir" -rm logdir +rm -rf logdir ln -s "$logdir" logdir # make this dir accessible to logger diff --git a/examples/var_service/ifplugd_if/run b/examples/var_service/ifplugd_if/run index 2781cf9f9..c4f766e88 100755 --- a/examples/var_service/ifplugd_if/run +++ b/examples/var_service/ifplugd_if/run @@ -8,6 +8,9 @@ pwd="$PWD" if="${PWD##*/ifplugd_}" +echo "* Upping iface $if" +ip link set dev "$if" up + echo "* Starting ifplugd on $if [$$]" exec \ env - PATH="$PATH" \ diff --git a/examples/var_service/inetd/log/run b/examples/var_service/inetd/log/run index 560d1b19f..69d74b73f 100755 --- a/examples/var_service/inetd/log/run +++ b/examples/var_service/inetd/log/run @@ -6,7 +6,7 @@ logdir="/var/log/service/`(cd ..;basename $PWD)`" mkdir -p "$logdir" 2>/dev/null chown -R "$user": "$logdir" chmod -R go-rwxst,u+rwX "$logdir" -rm logdir +rm -rf logdir ln -s "$logdir" logdir # make this dir accessible to logger diff --git a/examples/var_service/ntpd/log/run b/examples/var_service/ntpd/log/run index 560d1b19f..69d74b73f 100755 --- a/examples/var_service/ntpd/log/run +++ b/examples/var_service/ntpd/log/run @@ -6,7 +6,7 @@ logdir="/var/log/service/`(cd ..;basename $PWD)`" mkdir -p "$logdir" 2>/dev/null chown -R "$user": "$logdir" chmod -R go-rwxst,u+rwX "$logdir" -rm logdir +rm -rf logdir ln -s "$logdir" logdir # make this dir accessible to logger diff --git a/examples/var_service/ntpd/run b/examples/var_service/ntpd/run index 581d231a3..6f2a68188 100755 --- a/examples/var_service/ntpd/run +++ b/examples/var_service/ntpd/run @@ -15,7 +15,7 @@ default_p_opt="-p 0.$pool -p 1.$pool -p 2.$pool -p 3.$pool" # Make sure rundir/ exists mkdir -p "$rundir" 2>/dev/null -chown -R "$user:" "$rundir" +chown -R "$user": "$rundir" chmod -R a=rX "$rundir" rm -rf rundir 2>/dev/null ln -s "$rundir" rundir diff --git a/examples/var_service/tftpd/log/run b/examples/var_service/tftpd/log/run index 560d1b19f..69d74b73f 100755 --- a/examples/var_service/tftpd/log/run +++ b/examples/var_service/tftpd/log/run @@ -6,7 +6,7 @@ logdir="/var/log/service/`(cd ..;basename $PWD)`" mkdir -p "$logdir" 2>/dev/null chown -R "$user": "$logdir" chmod -R go-rwxst,u+rwX "$logdir" -rm logdir +rm -rf logdir ln -s "$logdir" logdir # make this dir accessible to logger diff --git a/examples/var_service/zcip_if/finish b/examples/var_service/zcip_if/finish new file mode 100755 index 000000000..95995cf5f --- /dev/null +++ b/examples/var_service/zcip_if/finish @@ -0,0 +1,13 @@ +#!/bin/sh +# executed when service is taken down ("sv d .") + +service=${PWD##*/} +file_ipconf="$service.ipconf" +dir_ipconf="/var/run/service/fw" + +# Reconfigure network with this interface disabled +echo "Finish: deconfiguring" +rm "env.out" +rm "$file_ipconf" +rm "$dir_ipconf/$file_ipconf" +sv u /var/service/fw diff --git a/examples/var_service/zcip_if/log/run b/examples/var_service/zcip_if/log/run index 560d1b19f..69d74b73f 100755 --- a/examples/var_service/zcip_if/log/run +++ b/examples/var_service/zcip_if/log/run @@ -6,7 +6,7 @@ logdir="/var/log/service/`(cd ..;basename $PWD)`" mkdir -p "$logdir" 2>/dev/null chown -R "$user": "$logdir" chmod -R go-rwxst,u+rwX "$logdir" -rm logdir +rm -rf logdir ln -s "$logdir" logdir # make this dir accessible to logger diff --git a/examples/var_service/zcip_if/zcip_handler b/examples/var_service/zcip_if/zcip_handler index 13010db27..3c6ca788b 100755 --- a/examples/var_service/zcip_if/zcip_handler +++ b/examples/var_service/zcip_if/zcip_handler @@ -33,7 +33,8 @@ if test x"$1" != x"config"; then fi # "config": we've got the address -#env # debug +# Record information for e.g. dhcp_$IF_pinger service +env >"env.out" ./convert2ipconf "$file_ipconf" # Reconfigure routing and firewall if needed From 1a1cfedbef2ee45467b5ed829416090cf8b149ca Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Sat, 24 Oct 2015 14:58:58 +0200 Subject: [PATCH 056/260] Tweak README Signed-off-by: Denys Vlasenko --- examples/var_service/README | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/examples/var_service/README b/examples/var_service/README index 9ad1b2581..d096ad0b9 100644 --- a/examples/var_service/README +++ b/examples/var_service/README @@ -36,10 +36,10 @@ service accordingly. In effect, it allows you to unplug/plug-to-different-networ and have your IP properly re-negotiated at once. var_service/dhcp_if_pinger - -Uses var_service/dhcp_if's data (/var/service/dhcp_if/dhcp_if.out file) -to determine router IP. Pings it. If ping fails, restarts /var/service/dhcp_if -service. Basically, an example of watchdog service for networks -which are not reliable and need babysitting. +Uses var_service/dhcp_if's data to determine router IP. Pings it. +If ping fails, restarts /var/service/dhcp_if service. +Basically, an example of watchdog service for networks which are not reliable +and need babysitting. var_service/fw - A *one-shot* service which reconfigures network based on current known state From bf1866c1832ddc5ac429b9af6bb1bc577c7796f8 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Sat, 24 Oct 2015 18:57:32 +0200 Subject: [PATCH 057/260] tweak zcip service example Signed-off-by: Denys Vlasenko --- examples/var_service/zcip_if/convert2ipconf | 2 ++ 1 file changed, 2 insertions(+) diff --git a/examples/var_service/zcip_if/convert2ipconf b/examples/var_service/zcip_if/convert2ipconf index aa133d815..c858723fb 100755 --- a/examples/var_service/zcip_if/convert2ipconf +++ b/examples/var_service/zcip_if/convert2ipconf @@ -4,6 +4,8 @@ #interface=eth1 #ip=169.254.x.y +# into: + #let cfg=cfg+1 #if[$cfg]=...; ip[$cfg]=...; ipmask[$cfg]=.../...; gw[$cfg]=...; net[$cfg]=... dns[$cfg]=... From 49d51598ac1db5e07a496a3014545f5daab8c501 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Sat, 24 Oct 2015 19:14:04 +0200 Subject: [PATCH 058/260] zcip: do not query current time if we won't use the result Signed-off-by: Denys Vlasenko --- networking/zcip.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/networking/zcip.c b/networking/zcip.c index d15c67d55..f0e734283 100644 --- a/networking/zcip.c +++ b/networking/zcip.c @@ -361,8 +361,10 @@ int zcip_main(int argc UNUSED_PARAM, char **argv) // make the kernel filter out all packets except // ones we'd care about. } - // Set deadline_us to the point in time when we timeout - deadline_us = MONOTONIC_US() + timeout_ms * 1000; + if (timeout_ms >= 0) { + // Set deadline_us to the point in time when we timeout + deadline_us = MONOTONIC_US() + timeout_ms * 1000; + } VDBG("...wait %d %s nsent=%u\n", timeout_ms, argv_intf, nsent); From 334e12ac6a5c26a83e45e32436449730877de49a Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Sat, 24 Oct 2015 19:15:44 +0200 Subject: [PATCH 059/260] zcip: ...ad suppress the warning Signed-off-by: Denys Vlasenko --- networking/zcip.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/networking/zcip.c b/networking/zcip.c index f0e734283..1d6910555 100644 --- a/networking/zcip.c +++ b/networking/zcip.c @@ -345,7 +345,7 @@ int zcip_main(int argc UNUSED_PARAM, char **argv) state = PROBE; while (1) { struct pollfd fds[1]; - unsigned deadline_us; + unsigned deadline_us = deadline_us; struct arp_packet p; int ip_conflict; int n; From d320a1e7a57512e351aa119beb2c18115f9c80ae Mon Sep 17 00:00:00 2001 From: Isaac Dunham Date: Sat, 24 Oct 2015 20:28:04 +0200 Subject: [PATCH 060/260] dumpleases: new option -d to show time in seconds function old new delta dumpleases_main 493 534 +41 static.dumpleases_longopts 31 41 +10 packed_usage 30777 30752 -25 ------------------------------------------------------------------------------ (add/remove: 0/0 grow/shrink: 2/1 up/down: 51/-25) Total: 26 bytes Signed-off-by: Isaac Dunham Signed-off-by: Denys Vlasenko --- networking/udhcp/dumpleases.c | 24 +++++++++++++++++++----- 1 file changed, 19 insertions(+), 5 deletions(-) diff --git a/networking/udhcp/dumpleases.c b/networking/udhcp/dumpleases.c index 64cd73ec7..f68e499e7 100644 --- a/networking/udhcp/dumpleases.c +++ b/networking/udhcp/dumpleases.c @@ -4,18 +4,20 @@ */ //usage:#define dumpleases_trivial_usage -//usage: "[-r|-a] [-f LEASEFILE]" +//usage: "[-r|-a] [-d] [-f LEASEFILE]" //usage:#define dumpleases_full_usage "\n\n" //usage: "Display DHCP leases granted by udhcpd\n" //usage: IF_LONG_OPTS( //usage: "\n -f,--file=FILE Lease file" //usage: "\n -r,--remaining Show remaining time" //usage: "\n -a,--absolute Show expiration time" +//usage: "\n -d,--decimal Show time in seconds" //usage: ) //usage: IF_NOT_LONG_OPTS( //usage: "\n -f FILE Lease file" //usage: "\n -r Show remaining time" //usage: "\n -a Show expiration time" +//usage: "\n -d Show time in seconds" //usage: ) #include "common.h" @@ -28,21 +30,22 @@ int dumpleases_main(int argc UNUSED_PARAM, char **argv) int fd; int i; unsigned opt; - int64_t written_at, curr, expires_abs; + int64_t written_at, curr; const char *file = LEASES_FILE; struct dyn_lease lease; - struct in_addr addr; enum { OPT_a = 0x1, // -a OPT_r = 0x2, // -r OPT_f = 0x4, // -f + OPT_d = 0x8, // -d }; #if ENABLE_LONG_OPTS static const char dumpleases_longopts[] ALIGN1 = "absolute\0" No_argument "a" "remaining\0" No_argument "r" "file\0" Required_argument "f" + "decimal\0" No_argument "d" ; applet_long_options = dumpleases_longopts; @@ -50,11 +53,12 @@ int dumpleases_main(int argc UNUSED_PARAM, char **argv) init_unicode(); opt_complementary = "=0:a--r:r--a"; - opt = getopt32(argv, "arf:", &file); + opt = getopt32(argv, "arf:d", &file); fd = xopen(file, O_RDONLY); - printf("Mac Address IP Address Host Name Expires %s\n", (opt & OPT_a) ? "at" : "in"); + printf("Mac Address IP Address Host Name Expires %s\n", + (opt & OPT_a) ? "at" : "in"); /* "00:00:00:00:00:00 255.255.255.255 ABCDEFGHIJKLMNOPQRS Wed Jun 30 21:49:08 1993" */ /* "123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 */ @@ -65,6 +69,9 @@ int dumpleases_main(int argc UNUSED_PARAM, char **argv) written_at = curr; /* lease file from future! :) */ while (full_read(fd, &lease, sizeof(lease)) == sizeof(lease)) { + struct in_addr addr; + int64_t expires_abs; + const char *fmt = ":%02x" + 1; for (i = 0; i < 6; i++) { printf(fmt, lease.lease_mac[i]); @@ -87,6 +94,13 @@ int dumpleases_main(int argc UNUSED_PARAM, char **argv) puts("expired"); continue; } + if (opt & OPT_d) { + /* -d: decimal time */ + if (!(opt & OPT_a)) + expires_abs -= curr; + printf("%llu\n", (unsigned long long) expires_abs); + continue; + } if (!(opt & OPT_a)) { /* no -a */ unsigned d, h, m; unsigned expires = expires_abs - curr; From f98705a00c15fc029116e00507abcfb745b86bfa Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Sat, 24 Oct 2015 20:45:10 +0200 Subject: [PATCH 061/260] dumpleases: string reuse text data bss dec hex filename 926254 906 17160 944320 e68c0 busybox_old 926242 906 17160 944308 e68b4 busybox_unstripped Signed-off-by: Denys Vlasenko --- networking/udhcp/dumpleases.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/networking/udhcp/dumpleases.c b/networking/udhcp/dumpleases.c index f68e499e7..987cc9aff 100644 --- a/networking/udhcp/dumpleases.c +++ b/networking/udhcp/dumpleases.c @@ -57,10 +57,12 @@ int dumpleases_main(int argc UNUSED_PARAM, char **argv) fd = xopen(file, O_RDONLY); - printf("Mac Address IP Address Host Name Expires %s\n", - (opt & OPT_a) ? "at" : "in"); - /* "00:00:00:00:00:00 255.255.255.255 ABCDEFGHIJKLMNOPQRS Wed Jun 30 21:49:08 1993" */ /* "123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 */ + /* "00:00:00:00:00:00 255.255.255.255 ABCDEFGHIJKLMNOPQRS Wed Jun 30 21:49:08 1993" */ + printf("Mac %-14s" "IP %-13s" "Host %-15s" "Expires %s\n", + "Address", "Address", "Name", + (opt & OPT_a) ? "at" : "in" + ); xread(fd, &written_at, sizeof(written_at)); written_at = SWAP_BE64(written_at); From 6d777b75ed322ea5ef0d1674ddfee1b5713cb04f Mon Sep 17 00:00:00 2001 From: Aaro Koskinen Date: Sat, 24 Oct 2015 22:01:29 +0200 Subject: [PATCH 062/260] xargs: make -I imply -r Make -I imply -r (GNU findutils seems to do the same). Fixes the following bug: $ echo -n | xargs -I% echo % Segmentation fault Signed-off-by: Aaro Koskinen Signed-off-by: Denys Vlasenko --- findutils/xargs.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/findutils/xargs.c b/findutils/xargs.c index 5870b8a16..69f83b128 100644 --- a/findutils/xargs.c +++ b/findutils/xargs.c @@ -577,6 +577,9 @@ int xargs_main(int argc, char **argv) G.argv = argv; argc = 0; read_args = process_stdin_with_replace; + /* Make -I imply -r. GNU findutils seems to do the same: */ + /* (otherwise "echo -n | xargs -I% echo %" would SEGV) */ + opt |= OPT_NO_EMPTY; } else #endif { From 8814431aca695a43b2e164a6620ea0a3274ce678 Mon Sep 17 00:00:00 2001 From: Ron Yorston Date: Wed, 21 Oct 2015 16:57:25 +0100 Subject: [PATCH 063/260] libiproute: use if_nametoindex Saves 87 bytes. Assuming, of course, all platforms have it. Signed-off-by: Ron Yorston Signed-off-by: Denys Vlasenko --- networking/libiproute/ll_map.c | 25 +------------------------ 1 file changed, 1 insertion(+), 24 deletions(-) diff --git a/networking/libiproute/ll_map.c b/networking/libiproute/ll_map.c index e2b85fc7b..af9eb46f7 100644 --- a/networking/libiproute/ll_map.c +++ b/networking/libiproute/ll_map.c @@ -136,7 +136,6 @@ unsigned FAST_FUNC ll_index_to_flags(int idx) int FAST_FUNC xll_name_to_index(const char *name) { int ret = 0; - int sock_fd; /* caching is not warranted - no users which repeatedly call it */ #ifdef UNUSED @@ -164,30 +163,8 @@ int FAST_FUNC xll_name_to_index(const char *name) } } } - /* We have not found the interface in our cache, but the kernel - * may still know about it. One reason is that we may be using - * module on-demand loading, which means that the kernel will - * load the module and make the interface exist only when - * we explicitely request it (check for dev_load() in net/core/dev.c). - * I can think of other similar scenario, but they are less common... - * Jean II */ #endif - - sock_fd = socket(AF_INET, SOCK_DGRAM, 0); - if (sock_fd >= 0) { - struct ifreq ifr; - int tmp; - - strncpy_IFNAMSIZ(ifr.ifr_name, name); - ifr.ifr_ifindex = -1; - tmp = ioctl(sock_fd, SIOCGIFINDEX, &ifr); - close(sock_fd); - if (tmp >= 0) - /* In theory, we should redump the interface list - * to update our cache, this is left as an exercise - * to the reader... Jean II */ - ret = ifr.ifr_ifindex; - } + ret = if_nametoindex(name); /* out:*/ if (ret <= 0) bb_error_msg_and_die("can't find device '%s'", name); From 0269789537c0c16de948e100ea331fdba54008e4 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Sun, 25 Oct 2015 20:10:46 +0100 Subject: [PATCH 064/260] inetd: make FEATURE_INETD_RPC off by default Signed-off-by: Denys Vlasenko --- archival/Config.src | 2 +- networking/Config.src | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/archival/Config.src b/archival/Config.src index 76635ba78..a9afaea5b 100644 --- a/archival/Config.src +++ b/archival/Config.src @@ -31,7 +31,7 @@ config FEATURE_SEAMLESS_GZ config FEATURE_SEAMLESS_Z bool "tar, rpm, modprobe etc understand .Z data" - default n + default n # it is ancient help Make tar, rpm, modprobe etc understand .Z data. diff --git a/networking/Config.src b/networking/Config.src index 8c7417f86..27c604a31 100644 --- a/networking/Config.src +++ b/networking/Config.src @@ -497,7 +497,7 @@ config FEATURE_INETD_SUPPORT_BUILTIN_CHARGEN config FEATURE_INETD_RPC bool "Support RPC services" - default y + default n # very rarely used, and needs Sun RPC support in libc depends on INETD select FEATURE_HAVE_RPC help From db700330d8951d96ea70102797041730c925eeeb Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Sun, 25 Oct 2015 20:36:03 +0100 Subject: [PATCH 065/260] tweak defconfig MONOTONIC_SYSCALL=y by default FEATURE_LAST_SMALL is gone: now FEATURE_LAST_FANCY is a "bool", not a "choice". Signed-off-by: Denys Vlasenko --- archival/ar.c | 16 +++------------- archival/bbunzip.c | 2 +- libbb/Config.src | 8 ++++---- miscutils/Config.src | 16 +++------------- 4 files changed, 11 insertions(+), 31 deletions(-) diff --git a/archival/ar.c b/archival/ar.c index f86c52d9b..e49d5cb2b 100644 --- a/archival/ar.c +++ b/archival/ar.c @@ -22,23 +22,13 @@ //config: default n # needs to be improved to be able to replace binutils ar //config: help //config: ar is an archival utility program used to create, modify, and -//config: extract contents from archives. An archive is a single file holding -//config: a collection of other files in a structure that makes it possible to -//config: retrieve the original individual files (called archive members). -//config: The original files' contents, mode (permissions), timestamp, owner, -//config: and group are preserved in the archive, and can be restored on -//config: extraction. +//config: extract contents from archives. In practice, it is used exclusively +//config: for object module archives used by compilers. //config: -//config: The stored filename is limited to 15 characters. (for more information -//config: see long filename support). -//config: ar has 60 bytes of overheads for every stored file. -//config: -//config: This implementation of ar can extract archives, it cannot create or -//config: modify them. //config: On an x86 system, the ar applet adds about 1K. //config: //config: Unless you have a specific application which requires ar, you should -//config: probably say N here. +//config: probably say N here: most compilers come with their own ar utility. //config: //config:config FEATURE_AR_LONG_FILENAMES //config: bool "Support for long filenames (not needed for debs)" diff --git a/archival/bbunzip.c b/archival/bbunzip.c index 90aac1427..548882f53 100644 --- a/archival/bbunzip.c +++ b/archival/bbunzip.c @@ -220,7 +220,7 @@ char* FAST_FUNC make_new_name_generic(char *filename, const char *expected_ext) //config:config UNCOMPRESS //config: bool "uncompress" -//config: default n +//config: default n # ancient //config: help //config: uncompress is used to decompress archives created by compress. //config: Not much used anymore, replaced by gzip/gunzip. diff --git a/libbb/Config.src b/libbb/Config.src index 19021fed1..b02ea14b0 100644 --- a/libbb/Config.src +++ b/libbb/Config.src @@ -16,7 +16,7 @@ config PASSWORD_MINLEN config MD5_SMALL int "MD5: Trade bytes for speed (0:fast, 3:slow)" - default 1 + default 1 # all "fast or small" options default to small range 0 3 help Trade binary size versus speed for the md5sum algorithm. @@ -30,7 +30,7 @@ config MD5_SMALL config SHA3_SMALL int "SHA3: Trade bytes for speed (0:fast, 1:slow)" - default 1 + default 1 # all "fast or small" options default to small range 0 1 help Trade binary size versus speed for the sha3sum algorithm. @@ -40,7 +40,7 @@ config SHA3_SMALL config FEATURE_FAST_TOP bool "Faster /proc scanning code (+100 bytes)" - default y + default n # all "fast or small" options default to small help This option makes top (and ps) ~20% faster (or 20% less CPU hungry), but code size is slightly bigger. @@ -208,7 +208,7 @@ config FEATURE_SKIP_ROOTFS config MONOTONIC_SYSCALL bool "Use clock_gettime(CLOCK_MONOTONIC) syscall" - default n + default y select PLATFORM_LINUX help Use clock_gettime(CLOCK_MONOTONIC) syscall for measuring diff --git a/miscutils/Config.src b/miscutils/Config.src index d69abf1a2..06f1c52ba 100644 --- a/miscutils/Config.src +++ b/miscutils/Config.src @@ -308,23 +308,13 @@ config LAST help 'last' displays a list of the last users that logged into the system. -choice - prompt "Choose last implementation" - depends on LAST - default FEATURE_LAST_FANCY - -config FEATURE_LAST_SMALL - bool "small" - help - This is a small version of last with just the basic set of - features. - config FEATURE_LAST_FANCY - bool "huge" + bool "Turn on output of extra information" + default y + depends on LAST help 'last' displays detailed information about the last users that logged into the system (mimics sysvinit last). +900 bytes. -endchoice config HDPARM bool "hdparm" From 028524317d8d0011ed38e86e507a06738a5b5a97 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timo=20Ter=C3=A4s?= Date: Mon, 26 Oct 2015 17:06:12 +0100 Subject: [PATCH 066/260] ifupdown: pass interface device name for ipv6 route commands MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit IPv6 routes need the device argument for link-local routes, or they cannot be used at all. E.g. "gateway fe80::def" seems to be used in some places, but kernel refuses to insert the route unless device name is explicitly specified in the route addition. Signed-off-by: Timo Teräs Signed-off-by: Denys Vlasenko --- networking/ifupdown.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/networking/ifupdown.c b/networking/ifupdown.c index 7c45e8927..d477ff6d1 100644 --- a/networking/ifupdown.c +++ b/networking/ifupdown.c @@ -394,8 +394,8 @@ static int FAST_FUNC static_up6(struct interface_defn_t *ifd, execfn *exec) # if ENABLE_FEATURE_IFUPDOWN_IP result = execute("ip addr add %address%/%netmask% dev %iface%[[ label %label%]]", ifd, exec); result += execute("ip link set[[ mtu %mtu%]][[ addr %hwaddress%]] %iface% up", ifd, exec); - /* Was: "[[ ip ....%gateway% ]]". Removed extra spaces w/o checking */ - result += execute("[[ip route add ::/0 via %gateway%]][[ metric %metric%]]", ifd, exec); + /* Reportedly, IPv6 needs "dev %iface%", but IPv4 does not: */ + result += execute("[[ip route add ::/0 via %gateway% dev %iface%]][[ metric %metric%]]", ifd, exec); # else result = execute("ifconfig %iface%[[ media %media%]][[ hw %hwaddress%]][[ mtu %mtu%]] up", ifd, exec); result += execute("ifconfig %iface% add %address%/%netmask%", ifd, exec); @@ -421,7 +421,8 @@ static int FAST_FUNC v4tunnel_up(struct interface_defn_t *ifd, execfn *exec) "%endpoint%[[ local %local%]][[ ttl %ttl%]]", ifd, exec); result += execute("ip link set %iface% up", ifd, exec); result += execute("ip addr add %address%/%netmask% dev %iface%", ifd, exec); - result += execute("[[ip route add ::/0 via %gateway%]]", ifd, exec); + /* Reportedly, IPv6 needs "dev %iface%", but IPv4 does not: */ + result += execute("[[ip route add ::/0 via %gateway% dev %iface%]]", ifd, exec); return ((result == 4) ? 4 : 0); } From d683c5c2f1493c2b0856a5f8751508836b0988d5 Mon Sep 17 00:00:00 2001 From: Richard Genoud Date: Mon, 26 Oct 2015 10:10:28 +0100 Subject: [PATCH 067/260] tr: support octal ranges now, we can do printf "a\tb\tcdef\n" | ./busybox tr -d "\1-\14b-e" af and bonus, we save some bytes. function old new delta expand 718 699 -19 ------------------------------------------------------------------------------ (add/remove: 0/0 grow/shrink: 0/1 up/down: 0/-19) Total: -19 bytes Signed-off-by: Richard Genoud Signed-off-by: Denys Vlasenko --- coreutils/tr.c | 23 ++++++++++++++++++----- 1 file changed, 18 insertions(+), 5 deletions(-) diff --git a/coreutils/tr.c b/coreutils/tr.c index e67948a36..2f49d5a86 100644 --- a/coreutils/tr.c +++ b/coreutils/tr.c @@ -91,7 +91,6 @@ static void map(char *pvector, * Character classes, e.g. [:upper:] ==> A...Z * Equiv classess, e.g. [=A=] ==> A (hmmmmmmm?) * not supported: - * \ooo-\ooo - octal ranges * [x*N] - repeat char x N times * [x*] - repeat char x until it fills STRING2: * # echo qwe123 | /usr/bin/tr 123456789 '[d]' @@ -99,7 +98,7 @@ static void map(char *pvector, * # echo qwe123 | /usr/bin/tr 123456789 '[d*]' * qweddd */ -static unsigned expand(const char *arg, char **buffer_p) +static unsigned expand(char *arg, char **buffer_p) { char *buffer = *buffer_p; unsigned pos = 0; @@ -113,9 +112,17 @@ static unsigned expand(const char *arg, char **buffer_p) *buffer_p = buffer = xrealloc(buffer, size); } if (*arg == '\\') { + const char *z; arg++; - buffer[pos++] = bb_process_escape_sequence(&arg); - continue; + z = arg; + ac = bb_process_escape_sequence(&z); + arg = (char *)z; + arg--; + *arg = ac; + /* + * fall through, there may be a range. + * If not, current char will be treated anyway. + */ } if (arg[1] == '-') { /* "0-9..." */ ac = arg[2]; @@ -124,9 +131,15 @@ static unsigned expand(const char *arg, char **buffer_p) continue; /* next iter will copy '-' and stop */ } i = (unsigned char) *arg; + arg += 3; /* skip 0-9 or 0-\ */ + if (ac == '\\') { + const char *z; + z = arg; + ac = bb_process_escape_sequence(&z); + arg = (char *)z; + } while (i <= ac) /* ok: i is unsigned _int_ */ buffer[pos++] = i++; - arg += 3; /* skip 0-9 */ continue; } if ((ENABLE_FEATURE_TR_CLASSES || ENABLE_FEATURE_TR_EQUIV) From 1de25a6e87e0e627aa34298105a3d17c60a1f44e Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Mon, 26 Oct 2015 19:33:05 +0100 Subject: [PATCH 068/260] unzip: test for bad archive SEGVing function old new delta huft_build 1296 1300 +4 Signed-off-by: Denys Vlasenko --- archival/libarchive/decompress_gunzip.c | 11 +++++++---- testsuite/unzip.tests | 23 ++++++++++++++++++++++- 2 files changed, 29 insertions(+), 5 deletions(-) diff --git a/archival/libarchive/decompress_gunzip.c b/archival/libarchive/decompress_gunzip.c index 7b6f45934..30bf45154 100644 --- a/archival/libarchive/decompress_gunzip.c +++ b/archival/libarchive/decompress_gunzip.c @@ -305,11 +305,12 @@ static int huft_build(const unsigned *b, const unsigned n, unsigned i; /* counter, current code */ unsigned j; /* counter */ int k; /* number of bits in current code */ - unsigned *p; /* pointer into c[], b[], or v[] */ + const unsigned *p; /* pointer into c[], b[], or v[] */ huft_t *q; /* points to current table */ huft_t r; /* table entry for structure assignment */ huft_t *u[BMAX]; /* table stack */ unsigned v[N_MAX]; /* values in order of bit length */ + unsigned v_end; int ws[BMAX + 1]; /* bits decoded stack */ int w; /* bits decoded */ unsigned x[BMAX + 1]; /* bit offsets, then code stack */ @@ -324,7 +325,7 @@ static int huft_build(const unsigned *b, const unsigned n, /* Generate counts for each bit length */ memset(c, 0, sizeof(c)); - p = (unsigned *) b; /* cast allows us to reuse p for pointing to b */ + p = b; i = n; do { c[*p]++; /* assume all entries <= BMAX */ @@ -365,12 +366,14 @@ static int huft_build(const unsigned *b, const unsigned n, } /* Make a table of values in order of bit lengths */ - p = (unsigned *) b; + p = b; i = 0; + v_end = 0; do { j = *p++; if (j != 0) { v[x[j]++] = i; + v_end = x[j]; } } while (++i < n); @@ -432,7 +435,7 @@ static int huft_build(const unsigned *b, const unsigned n, /* set up table entry in r */ r.b = (unsigned char) (k - w); - if (p >= v + n) { + if (p >= v + v_end) { // Was "if (p >= v + n)" but v[] can be shorter! r.e = 99; /* out of values--invalid code */ } else if (*p < s) { r.e = (unsigned char) (*p < 256 ? 16 : 15); /* 256 is EOB code */ diff --git a/testsuite/unzip.tests b/testsuite/unzip.tests index 8677a0306..ca0a45800 100755 --- a/testsuite/unzip.tests +++ b/testsuite/unzip.tests @@ -7,7 +7,7 @@ . ./testing.sh -# testing "test name" "options" "expected result" "file input" "stdin" +# testing "test name" "commands" "expected result" "file input" "stdin" # file input will be file called "input" # test can create a file "actual" instead of writing to stdout @@ -30,6 +30,27 @@ testing "unzip (subdir only)" "unzip -q foo.zip foo/ && test -d foo && test ! -f rmdir foo rm foo.zip +# File containing some damaged encrypted stream +testing "unzip (bad archive)" "uudecode; unzip bad.zip 2>&1; echo \$?" \ +"Archive: bad.zip + inflating: ]3j½r«IK-%Ix +unzip: inflate error +1 +" \ +"" "\ +begin-base64 644 bad.zip +UEsDBBQAAgkIAAAAIQA5AAAANwAAADwAAAAQAAcAXTNqwr1ywqtJGxJLLSVJ +eCkBD0AdKBk8JzQsIj01JC0/ORJQSwMEFAECCAAAAAAhADoAAAAPAAAANgAA +AAwAAQASw73Ct1DCokohPXQiNjoUNTUiHRwgLT4WHlBLAQIQABQAAggIAAAA +oQA5AAAANwAAADwAAAAQQAcADAAAACwAMgCAAAAAAABdM2rCvXLCq0kbEkst +JUl4KQEPQB0oGSY4Cz4QNgEnJSYIPVBLAQIAABQAAggAAAAAIQAqAAAADwAA +BDYAAAAMAAEADQAAADIADQAAAEEAAAASw73Ct1DKokohPXQiNzA+FAI1HCcW +NzITNFBLBQUKAC4JAA04Cw0EOhZQSwUGAQAABAIAAgCZAAAAeQAAAAIALhM= +==== +" + +rm * + # Clean up scratch directory. cd .. From fbe50cf6bc685f7cf4fbcb9c0c425fc93575a085 Mon Sep 17 00:00:00 2001 From: Aaro Koskinen Date: Mon, 26 Oct 2015 23:42:32 +0200 Subject: [PATCH 069/260] gunzip: add support for long options Add support for long options. Signed-off-by: Aaro Koskinen Signed-off-by: Denys Vlasenko --- archival/bbunzip.c | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/archival/bbunzip.c b/archival/bbunzip.c index 548882f53..e10372e14 100644 --- a/archival/bbunzip.c +++ b/archival/bbunzip.c @@ -290,6 +290,13 @@ int uncompress_main(int argc UNUSED_PARAM, char **argv) //config: gunzip is used to decompress archives created by gzip. //config: You can use the `-t' option to test the integrity of //config: an archive, without decompressing it. +//config: +//config:config FEATURE_GUNZIP_LONG_OPTIONS +//config: bool "Enable long options" +//config: default y +//config: depends on GUNZIP && LONG_OPTS +//config: help +//config: Enable use of long options. //applet:IF_GUNZIP(APPLET(gunzip, BB_DIR_BIN, BB_SUID_DROP)) //applet:IF_GUNZIP(APPLET_ODDNAME(zcat, gunzip, BB_DIR_BIN, BB_SUID_DROP, zcat)) @@ -321,6 +328,16 @@ char* FAST_FUNC make_new_name_gunzip(char *filename, const char *expected_ext UN } return filename; } + +#if ENABLE_FEATURE_GUNZIP_LONG_OPTIONS +static const char gunzip_longopts[] ALIGN1 = + "stdout\0" No_argument "c" + "to-stdout\0" No_argument "c" + "force\0" No_argument "f" + "test\0" No_argument "t" + ; +#endif + /* * Linux kernel build uses gzip -d -n. We accept and ignore it. * Man page says: @@ -337,6 +354,9 @@ char* FAST_FUNC make_new_name_gunzip(char *filename, const char *expected_ext UN int gunzip_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; int gunzip_main(int argc UNUSED_PARAM, char **argv) { +#if ENABLE_FEATURE_GUNZIP_LONG_OPTIONS + applet_long_options = gunzip_longopts; +#endif getopt32(argv, "cfvqdtn"); argv += optind; From cddc98eab7d770427941db4abae2da4ae68f1e68 Mon Sep 17 00:00:00 2001 From: Aaro Koskinen Date: Mon, 26 Oct 2015 23:42:33 +0200 Subject: [PATCH 070/260] gzip: add support for --no-name long option Add support for --no-name long option. Just silently ignore it like the short -n option. This allows to use busybox gzip with Lynx browser. Signed-off-by: Aaro Koskinen Signed-off-by: Denys Vlasenko --- archival/bbunzip.c | 1 + archival/gzip.c | 1 + 2 files changed, 2 insertions(+) diff --git a/archival/bbunzip.c b/archival/bbunzip.c index e10372e14..b4f754e0b 100644 --- a/archival/bbunzip.c +++ b/archival/bbunzip.c @@ -335,6 +335,7 @@ static const char gunzip_longopts[] ALIGN1 = "to-stdout\0" No_argument "c" "force\0" No_argument "f" "test\0" No_argument "t" + "no-name\0" No_argument "n" ; #endif diff --git a/archival/gzip.c b/archival/gzip.c index c9171304a..f9bb3c742 100644 --- a/archival/gzip.c +++ b/archival/gzip.c @@ -2160,6 +2160,7 @@ static const char gzip_longopts[] ALIGN1 = "quiet\0" No_argument "q" "fast\0" No_argument "1" "best\0" No_argument "9" + "no-name\0" No_argument "n" ; #endif From 82c2fad26c4134cc60eed9a3f05a9bbec70ab65b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timo=20Ter=C3=A4s?= Date: Mon, 26 Oct 2015 09:40:31 +0200 Subject: [PATCH 071/260] fbsplash: use virtual y size in mmap size calculations MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The virtual y can be larger - and we can be even writing there since we are taking into account the y offset. Avoids possible crash. But use it only if set, seems it is not set if virtual area is not allocated (though, often fbcon allocates some scrollback area). Signed-off-by: Timo Teräs Signed-off-by: Denys Vlasenko --- miscutils/fbsplash.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/miscutils/fbsplash.c b/miscutils/fbsplash.c index 77033c258..9557c41db 100644 --- a/miscutils/fbsplash.c +++ b/miscutils/fbsplash.c @@ -150,7 +150,7 @@ static void fb_open(const char *strfb_device) // map the device in memory G.addr = mmap(NULL, - G.scr_var.yres * G.scr_fix.line_length, + (G.scr_var.yres_virtual ?: G.scr_var.yres) * G.scr_fix.line_length, PROT_WRITE, MAP_SHARED, fbfd, 0); if (G.addr == MAP_FAILED) bb_perror_msg_and_die("mmap"); From 4840325351911780a02f953f17b2eee919a36340 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Wed, 28 Oct 2015 15:33:19 +0100 Subject: [PATCH 072/260] lzop: eliminate variable, use "int" as return type Based on patch by Maxin B. John function old new delta pack_lzop 870 859 -11 Signed-off-by: Denys Vlasenko --- archival/lzop.c | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/archival/lzop.c b/archival/lzop.c index 73d11a705..a5fc01941 100644 --- a/archival/lzop.c +++ b/archival/lzop.c @@ -640,7 +640,7 @@ static int lzo_get_method(header_t *h) /**********************************************************************/ // compress a file /**********************************************************************/ -static NOINLINE smallint lzo_compress(const header_t *h) +static NOINLINE int lzo_compress(const header_t *h) { unsigned block_size = LZO_BLOCK_SIZE; int r = 0; /* LZO_E_OK */ @@ -650,7 +650,6 @@ static NOINLINE smallint lzo_compress(const header_t *h) uint32_t d_adler32 = ADLER32_INIT_VALUE; uint32_t d_crc32 = CRC32_INIT_VALUE; int l; - smallint ok = 1; uint8_t *wrk_mem = NULL; if (h->method == M_LZO1X_1) @@ -732,7 +731,7 @@ static NOINLINE smallint lzo_compress(const header_t *h) free(wrk_mem); free(b1); free(b2); - return ok; + return 1; } static FAST_FUNC void lzo_check( @@ -753,7 +752,7 @@ static FAST_FUNC void lzo_check( /**********************************************************************/ // decompress a file /**********************************************************************/ -static NOINLINE smallint lzo_decompress(const header_t *h) +static NOINLINE int lzo_decompress(const header_t *h) { unsigned block_size = LZO_BLOCK_SIZE; int r; @@ -761,7 +760,6 @@ static NOINLINE smallint lzo_decompress(const header_t *h) uint32_t c_adler32 = ADLER32_INIT_VALUE; uint32_t d_adler32 = ADLER32_INIT_VALUE; uint32_t c_crc32 = CRC32_INIT_VALUE, d_crc32 = CRC32_INIT_VALUE; - smallint ok = 1; uint8_t *b1; uint32_t mcs_block_size = MAX_COMPRESSED_SIZE(block_size); uint8_t *b2 = NULL; @@ -865,7 +863,7 @@ static NOINLINE smallint lzo_decompress(const header_t *h) } free(b2); - return ok; + return 1; } /**********************************************************************/ @@ -1050,7 +1048,7 @@ static void lzo_set_method(header_t *h) h->level = level; } -static smallint do_lzo_compress(void) +static int do_lzo_compress(void) { header_t header; @@ -1078,7 +1076,7 @@ static smallint do_lzo_compress(void) /**********************************************************************/ // decompress /**********************************************************************/ -static smallint do_lzo_decompress(void) +static int do_lzo_decompress(void) { header_t header; From 4c8576fea18552d93d43c367638bacc54c26f2b7 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Wed, 28 Oct 2015 18:07:46 +0100 Subject: [PATCH 073/260] modinfo: fix "-F firmware", add "intree" field display function old new delta shortcuts - 52 +52 modinfo 317 330 +13 display 77 87 +10 packed_usage 30752 30761 +9 modinfo_main 351 345 -6 static.shortcuts 48 - -48 ------------------------------------------------------------------------------ (add/remove: 1/1 grow/shrink: 3/1 up/down: 84/-54) Total: 30 bytes Signed-off-by: Denys Vlasenko --- modutils/modinfo.c | 114 ++++++++++++++++++++++++--------------------- 1 file changed, 62 insertions(+), 52 deletions(-) diff --git a/modutils/modinfo.c b/modutils/modinfo.c index 8e74b6438..aa641ad54 100644 --- a/modutils/modinfo.c +++ b/modutils/modinfo.c @@ -5,11 +5,6 @@ * * Licensed under GPLv2 or later, see file LICENSE in this source tree. */ - -//applet:IF_MODINFO(APPLET(modinfo, BB_DIR_SBIN, BB_SUID_DROP)) - -//kbuild:lib-$(CONFIG_MODINFO) += modinfo.o modutils.o - //config:config MODINFO //config: bool "modinfo" //config: default y @@ -17,26 +12,46 @@ //config: help //config: Show information about a Linux Kernel module +//applet:IF_MODINFO(APPLET(modinfo, BB_DIR_SBIN, BB_SUID_DROP)) + +//kbuild:lib-$(CONFIG_MODINFO) += modinfo.o modutils.o + #include #include /* uname() */ #include "libbb.h" #include "modutils.h" +static const char *const shortcuts[] = { + "filename", // -n + "author", // -a + "description", // -d + "license", // -l + "parm", // -p + "version", // the rest has no shortcut options + "alias", + "srcversion", + "depends", + "uts_release", + "intree", + "vermagic", + "firmware", +}; enum { - OPT_TAGS = (1 << 12) - 1, /* shortcut count */ - OPT_F = (1 << 12), /* field name */ - OPT_0 = (1 << 13), /* \0 as separator */ + OPT_0 = (1 << 0), /* \0 as separator */ + OPT_F = (1 << 1), /* field name */ + /* first bits are for -nadlp options, the rest are for + * fields not selectable with "shortcut" options + */ + OPT_n = (1 << 2), + OPT_TAGS = ((1 << ARRAY_SIZE(shortcuts)) - 1) << 2, }; -struct modinfo_env { - char *field; - int tags; -}; - -static void display(const char *data, const char *pattern, int flag) +static void display(const char *data, const char *pattern) { - if (flag) { + int flag = option_mask32 >> 1; /* shift out -0 bit */ + if (flag & (flag-1)) { + /* more than one field to show: print "FIELD:" pfx */ int n = printf("%s:", pattern); while (n++ < 16) bb_putchar(' '); @@ -45,55 +60,45 @@ static void display(const char *data, const char *pattern, int flag) } static void modinfo(const char *path, const char *version, - const struct modinfo_env *env) + const char *field) { - static const char *const shortcuts[] = { - "filename", - "license", - "author", - "description", - "version", - "alias", - "srcversion", - "depends", - "uts_release", - "vermagic", - "parm", - "firmware", - }; size_t len; int j; char *ptr, *the_module; - const char *field = env->field; - int tags = env->tags; - - if (tags & 1) { /* filename */ - display(path, shortcuts[0], 1 != tags); - } + char *allocated; + int tags = option_mask32; + allocated = NULL; len = MAXINT(ssize_t); the_module = xmalloc_open_zipped_read_close(path, &len); if (!the_module) { if (path[0] == '/') return; /* Newer depmod puts relative paths in modules.dep */ - path = xasprintf("%s/%s/%s", CONFIG_DEFAULT_MODULES_DIR, version, path); + path = allocated = xasprintf("%s/%s/%s", CONFIG_DEFAULT_MODULES_DIR, version, path); the_module = xmalloc_open_zipped_read_close(path, &len); - free((char*)path); - if (!the_module) - return; + if (!the_module) { + bb_error_msg("module '%s' not found", path); + goto ret; + } } - if (field) - tags |= OPT_F; - for (j = 1; (1< Date: Thu, 29 Oct 2015 11:29:59 +0000 Subject: [PATCH 074/260] ash: add test for issue with here document This used to work but doesn't now: foo () { cat < Signed-off-by: Ron Yorston Signed-off-by: Denys Vlasenko --- shell/ash_test/ash-heredoc/heredoc2.right | 2 ++ shell/ash_test/ash-heredoc/heredoc2.tests | 7 +++++++ 2 files changed, 9 insertions(+) create mode 100644 shell/ash_test/ash-heredoc/heredoc2.right create mode 100755 shell/ash_test/ash-heredoc/heredoc2.tests diff --git a/shell/ash_test/ash-heredoc/heredoc2.right b/shell/ash_test/ash-heredoc/heredoc2.right new file mode 100644 index 000000000..a486f1ac4 --- /dev/null +++ b/shell/ash_test/ash-heredoc/heredoc2.right @@ -0,0 +1,2 @@ +bar +bar diff --git a/shell/ash_test/ash-heredoc/heredoc2.tests b/shell/ash_test/ash-heredoc/heredoc2.tests new file mode 100755 index 000000000..6d9ccb6cc --- /dev/null +++ b/shell/ash_test/ash-heredoc/heredoc2.tests @@ -0,0 +1,7 @@ +foo () { +cat < Date: Mon, 3 Aug 2015 13:46:00 +0100 Subject: [PATCH 075/260] ash: allow newline after variable name in for loop Newline is a valid delimiter between the variable name and `in` keyword in for loops. Based on commit 22e8fb4 from git://git.kernel.org/pub/scm/utils/dash/dash.git by Herbert Xu. function old new delta parse_command 1568 1563 -5 ------------------------------------------------------------------------------ (add/remove: 0/0 grow/shrink: 0/1 up/down: 0/-5) Total: -5 bytes Signed-off-by: Ron Yorston Signed-off-by: Denys Vlasenko --- shell/ash.c | 4 ++-- shell/ash_test/ash-misc/for.right | 1 + shell/ash_test/ash-misc/for.tests | 5 +++++ 3 files changed, 8 insertions(+), 2 deletions(-) create mode 100644 shell/ash_test/ash-misc/for.right create mode 100755 shell/ash_test/ash-misc/for.tests diff --git a/shell/ash.c b/shell/ash.c index 17121aa9b..3339666b9 100644 --- a/shell/ash.c +++ b/shell/ash.c @@ -10913,7 +10913,7 @@ parse_command(void) n1 = stzalloc(sizeof(struct nfor)); n1->type = NFOR; n1->nfor.var = wordtext; - checkkwd = CHKKWD | CHKALIAS; + checkkwd = CHKNL | CHKKWD | CHKALIAS; if (readtoken() == TIN) { app = ≈ while (readtoken() == TWORD) { @@ -10940,7 +10940,7 @@ parse_command(void) * Newline or semicolon here is optional (but note * that the original Bourne shell only allowed NL). */ - if (lasttoken != TNL && lasttoken != TSEMI) + if (lasttoken != TSEMI) tokpushback = 1; } checkkwd = CHKNL | CHKKWD | CHKALIAS; diff --git a/shell/ash_test/ash-misc/for.right b/shell/ash_test/ash-misc/for.right new file mode 100644 index 000000000..d86bac9de --- /dev/null +++ b/shell/ash_test/ash-misc/for.right @@ -0,0 +1 @@ +OK diff --git a/shell/ash_test/ash-misc/for.tests b/shell/ash_test/ash-misc/for.tests new file mode 100755 index 000000000..4889a9f2d --- /dev/null +++ b/shell/ash_test/ash-misc/for.tests @@ -0,0 +1,5 @@ +for i +in OK +do + echo $i +done From 383b885ff7654dc0171b5c1eaa449bb1e1cfe8f0 Mon Sep 17 00:00:00 2001 From: Ron Yorston Date: Mon, 3 Aug 2015 13:46:25 +0100 Subject: [PATCH 076/260] ash: save a few bytes in code to parse case statements Based on commit 49b82fc from git://git.kernel.org/pub/scm/utils/dash/dash.git by Herbert Xu. function old new delta parse_command 1563 1555 -8 ------------------------------------------------------------------------------ (add/remove: 0/0 grow/shrink: 0/1 up/down: 0/-8) Total: -8 bytes Signed-off-by: Ron Yorston Signed-off-by: Denys Vlasenko --- shell/ash.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/shell/ash.c b/shell/ash.c index 3339666b9..18c7ff523 100644 --- a/shell/ash.c +++ b/shell/ash.c @@ -10959,10 +10959,8 @@ parse_command(void) /*n2->narg.next = NULL; - stzalloc did it */ n2->narg.text = wordtext; n2->narg.backquote = backquotelist; - do { - checkkwd = CHKKWD | CHKALIAS; - } while (readtoken() == TNL); - if (lasttoken != TIN) + checkkwd = CHKNL | CHKKWD | CHKALIAS; + if (readtoken() != TIN) raise_error_unexpected_syntax(TIN); cpp = &n1->ncase.cases; next_case: From e2f32c02b149f5a128c634231a0ef12d03843967 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Thu, 29 Oct 2015 19:46:40 +0100 Subject: [PATCH 077/260] ash: fix command -- crash busybox sh -c 'command --' segfaults because parse_command_args returns a pointer to a null pointer. Based on commit 18071c7 from git://git.kernel.org/pub/scm/utils/dash/dash.git by Gerrit Pape. Signed-off-by: Denys Vlasenko --- shell/ash.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/shell/ash.c b/shell/ash.c index 18c7ff523..8f0a5e0be 100644 --- a/shell/ash.c +++ b/shell/ash.c @@ -8878,14 +8878,15 @@ parse_command_args(char **argv, const char **path) for (;;) { cp = *++argv; if (!cp) - return 0; + return NULL; if (*cp++ != '-') break; c = *cp++; if (!c) break; if (c == '-' && !*cp) { - argv++; + if (!*++argv) + return NULL; break; } do { @@ -8895,7 +8896,7 @@ parse_command_args(char **argv, const char **path) break; default: /* run 'typecmd' for other options */ - return 0; + return NULL; } c = *cp++; } while (c); From 3f221113a50196e536bfb059712915bd8bde10d1 Mon Sep 17 00:00:00 2001 From: Ron Yorston Date: Mon, 3 Aug 2015 13:47:33 +0100 Subject: [PATCH 078/260] ash: respect -p flag when command builtin is run with -v/-V The command builtin should only check the default path, not $PATH, when the -p flag is used along with -v/-V. Based on commits 65ae84b (by Harald van Dijk) and 29ee27d (by Herbert Xu) from git://git.kernel.org/pub/scm/utils/dash/dash.git). function old new delta commandcmd 72 87 +15 describe_command 437 450 +13 typecmd 84 86 +2 ------------------------------------------------------------------------------ (add/remove: 0/0 grow/shrink: 3/0 up/down: 30/0) Total: 30 bytes Signed-off-by: Ron Yorston Signed-off-by: Denys Vlasenko --- shell/ash.c | 12 ++++++++---- shell/ash_test/ash-misc/command.right | 1 + shell/ash_test/ash-misc/command.tests | 1 + 3 files changed, 10 insertions(+), 4 deletions(-) create mode 100644 shell/ash_test/ash-misc/command.right create mode 100755 shell/ash_test/ash-misc/command.tests diff --git a/shell/ash.c b/shell/ash.c index 8f0a5e0be..a2e06184b 100644 --- a/shell/ash.c +++ b/shell/ash.c @@ -7812,14 +7812,15 @@ findkwd(const char *s) * Locate and print what a word is... */ static int -describe_command(char *command, int describe_command_verbose) +describe_command(char *command, const char *path, int describe_command_verbose) { struct cmdentry entry; struct tblentry *cmdp; #if ENABLE_ASH_ALIAS const struct alias *ap; #endif - const char *path = pathval(); + + path = path ? path : pathval(); if (describe_command_verbose) { out1str(command); @@ -7919,7 +7920,7 @@ typecmd(int argc UNUSED_PARAM, char **argv) verbose = 0; } while (argv[i]) { - err |= describe_command(argv[i++], verbose); + err |= describe_command(argv[i++], NULL, verbose); } return err; } @@ -7933,6 +7934,7 @@ commandcmd(int argc UNUSED_PARAM, char **argv UNUSED_PARAM) VERIFY_BRIEF = 1, VERIFY_VERBOSE = 2, } verify = 0; + const char *path = NULL; while ((c = nextopt("pvV")) != '\0') if (c == 'V') @@ -7943,9 +7945,11 @@ commandcmd(int argc UNUSED_PARAM, char **argv UNUSED_PARAM) else if (c != 'p') abort(); #endif + else + path = bb_default_path; /* Mimic bash: just "command -v" doesn't complain, it's a nop */ if (verify && (*argptr != NULL)) { - return describe_command(*argptr, verify - VERIFY_BRIEF); + return describe_command(*argptr, path, verify - VERIFY_BRIEF); } return 0; diff --git a/shell/ash_test/ash-misc/command.right b/shell/ash_test/ash-misc/command.right new file mode 100644 index 000000000..7f746d9c4 --- /dev/null +++ b/shell/ash_test/ash-misc/command.right @@ -0,0 +1 @@ +recho: not found diff --git a/shell/ash_test/ash-misc/command.tests b/shell/ash_test/ash-misc/command.tests new file mode 100755 index 000000000..5d445af51 --- /dev/null +++ b/shell/ash_test/ash-misc/command.tests @@ -0,0 +1 @@ +command -p -V recho From ef2386b80abfb22ccb697ddbdd4047aacc395c50 Mon Sep 17 00:00:00 2001 From: Ron Yorston Date: Thu, 29 Oct 2015 16:19:14 +0000 Subject: [PATCH 079/260] ash: only allow local variables in functions Signed-off-by: Ron Yorston Signed-off-by: Denys Vlasenko --- shell/ash.c | 3 +++ shell/ash_test/ash-misc/local2.right | 1 + shell/ash_test/ash-misc/local2.tests | 1 + 3 files changed, 5 insertions(+) create mode 100644 shell/ash_test/ash-misc/local2.right create mode 100755 shell/ash_test/ash-misc/local2.tests diff --git a/shell/ash.c b/shell/ash.c index a2e06184b..0d7cac0b5 100644 --- a/shell/ash.c +++ b/shell/ash.c @@ -8987,6 +8987,9 @@ localcmd(int argc UNUSED_PARAM, char **argv) { char *name; + if (!funcnest) + ash_msg_and_raise_error("not in a function"); + argv = argptr; while ((name = *argv++) != NULL) { mklocal(name); diff --git a/shell/ash_test/ash-misc/local2.right b/shell/ash_test/ash-misc/local2.right new file mode 100644 index 000000000..630ef7979 --- /dev/null +++ b/shell/ash_test/ash-misc/local2.right @@ -0,0 +1 @@ +./local2.tests: local: line 1: not in a function diff --git a/shell/ash_test/ash-misc/local2.tests b/shell/ash_test/ash-misc/local2.tests new file mode 100755 index 000000000..8e14037c5 --- /dev/null +++ b/shell/ash_test/ash-misc/local2.tests @@ -0,0 +1 @@ +local x=1 From 7b14ede049d467e1a6da46ef69b917645e94a6b9 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Thu, 29 Oct 2015 20:29:05 +0100 Subject: [PATCH 080/260] ash tests: make test print test name before it is run Signed-off-by: Denys Vlasenko --- shell/ash_test/run-all | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/shell/ash_test/run-all b/shell/ash_test/run-all index ad93e251d..354cc1fcf 100755 --- a/shell/ash_test/run-all +++ b/shell/ash_test/run-all @@ -31,8 +31,9 @@ do_test() *.orig|*~) ;; #*) echo $x ; sh $x ;; *) + echo -n "$1/$x: " sh "$x" >"$TOPDIR/$noslash-$x.fail" 2>&1 && \ - { echo "$1/$x: ok"; rm "$TOPDIR/$noslash-$x.fail"; } || echo "$1/$x: fail"; + { echo "ok"; rm "$TOPDIR/$noslash-$x.fail"; } || echo "fail"; ;; esac done @@ -42,11 +43,12 @@ do_test() test -x "$x" || continue name="${x%%.tests}" test -f "$name.right" || continue + echo -n "$1/$x: " { "$THIS_SH" "./$x" >"$name.xx" 2>&1 diff -u "$name.xx" "$name.right" >"$TOPDIR/$noslash-$x.fail" \ && rm -f "$name.xx" "$TOPDIR/$noslash-$x.fail" - } && echo "$1/$x: ok" || echo "$1/$x: fail" + } && echo "ok" || echo "fail" done ) } From 713f07d906d9171953be0c12e2369869855b6ca6 Mon Sep 17 00:00:00 2001 From: Ron Yorston Date: Thu, 29 Oct 2015 16:44:56 +0000 Subject: [PATCH 081/260] ash: fix error during recursive processing of here document Save the value of the checkkwd flag to prevent it being clobbered during recursion. Based on commit ec2c84d from git://git.kernel.org/pub/scm/utils/dash/dash.git by Herbert Xu. function old new delta readtoken 190 203 +13 ------------------------------------------------------------------------------ (add/remove: 0/0 grow/shrink: 1/0 up/down: 13/0) Total: 13 bytes Signed-off-by: Ron Yorston Signed-off-by: Denys Vlasenko --- shell/ash.c | 5 +++-- shell/ash_test/ash-heredoc/heredoc3.right | 1 + shell/ash_test/ash-heredoc/heredoc3.tests | 9 +++++++++ 3 files changed, 13 insertions(+), 2 deletions(-) create mode 100644 shell/ash_test/ash-heredoc/heredoc3.right create mode 100755 shell/ash_test/ash-heredoc/heredoc3.tests diff --git a/shell/ash.c b/shell/ash.c index 0d7cac0b5..384c7b9e4 100644 --- a/shell/ash.c +++ b/shell/ash.c @@ -11899,6 +11899,7 @@ static int readtoken(void) { int t; + int kwd = checkkwd; #if DEBUG smallint alreadyseen = tokpushback; #endif @@ -11912,7 +11913,7 @@ readtoken(void) /* * eat newlines */ - if (checkkwd & CHKNL) { + if (kwd & CHKNL) { while (t == TNL) { parseheredoc(); t = xxreadtoken(); @@ -11926,7 +11927,7 @@ readtoken(void) /* * check for keywords */ - if (checkkwd & CHKKWD) { + if (kwd & CHKKWD) { const char *const *pp; pp = findkwd(wordtext); diff --git a/shell/ash_test/ash-heredoc/heredoc3.right b/shell/ash_test/ash-heredoc/heredoc3.right new file mode 100644 index 000000000..ce0136250 --- /dev/null +++ b/shell/ash_test/ash-heredoc/heredoc3.right @@ -0,0 +1 @@ +hello diff --git a/shell/ash_test/ash-heredoc/heredoc3.tests b/shell/ash_test/ash-heredoc/heredoc3.tests new file mode 100755 index 000000000..96c227cc1 --- /dev/null +++ b/shell/ash_test/ash-heredoc/heredoc3.tests @@ -0,0 +1,9 @@ +echo hello >greeting +cat </dev/null +rm greeting From 6bd2fabc52fa76b69a65772878e2e745c0fff3ff Mon Sep 17 00:00:00 2001 From: Ron Yorston Date: Thu, 29 Oct 2015 11:30:22 +0000 Subject: [PATCH 082/260] Revert "ash: fix a SEGV case in an invalid heredoc" xxx This reverts commit 7e66102f762a7d80715f0c7e5925433256b78cee but leaves the test in place as it's still valid. Reported-by: Natanael Copa Signed-off-by: Ron Yorston Signed-off-by: Denys Vlasenko --- shell/ash.c | 15 ++++----------- 1 file changed, 4 insertions(+), 11 deletions(-) diff --git a/shell/ash.c b/shell/ash.c index 384c7b9e4..72fc7d524 100644 --- a/shell/ash.c +++ b/shell/ash.c @@ -10524,7 +10524,7 @@ static union node *andor(void); static union node *pipeline(void); static union node *parse_command(void); static void parseheredoc(void); -static char nexttoken_ends_list(void); +static char peektoken(void); static int readtoken(void); static union node * @@ -10534,7 +10534,7 @@ list(int nlflag) int tok; checkkwd = CHKNL | CHKKWD | CHKALIAS; - if (nlflag == 2 && nexttoken_ends_list()) + if (nlflag == 2 && peektoken()) return NULL; n1 = NULL; for (;;) { @@ -10576,15 +10576,8 @@ list(int nlflag) tokpushback = 1; } checkkwd = CHKNL | CHKKWD | CHKALIAS; - if (nexttoken_ends_list()) { - /* Testcase: "< Date: Thu, 29 Oct 2015 11:30:55 +0000 Subject: [PATCH 083/260] ash: simplify EOF/newline handling in list parser Processing of here documents in ash has had a couple of breakages which are now the subject of tests. This commit should fix both. It is based on the following commit in dash git by Herbert Xu: <7c245aa> [PARSER] Simplify EOF/newline handling in list parser (See git://git.kernel.org/pub/scm/utils/dash/dash.git) Reported-by: Natanael Copa Signed-off-by: Ron Yorston Signed-off-by: Denys Vlasenko --- shell/ash.c | 63 ++++++++++++++++++++++++----------------------------- 1 file changed, 29 insertions(+), 34 deletions(-) diff --git a/shell/ash.c b/shell/ash.c index 72fc7d524..9a8bab5ab 100644 --- a/shell/ash.c +++ b/shell/ash.c @@ -10524,7 +10524,7 @@ static union node *andor(void); static union node *pipeline(void); static union node *parse_command(void); static void parseheredoc(void); -static char peektoken(void); +static int peektoken(void); static int readtoken(void); static union node * @@ -10533,11 +10533,27 @@ list(int nlflag) union node *n1, *n2, *n3; int tok; - checkkwd = CHKNL | CHKKWD | CHKALIAS; - if (nlflag == 2 && peektoken()) - return NULL; n1 = NULL; for (;;) { + switch (peektoken()) { + case TNL: + if (!(nlflag & 1)) + break; + parseheredoc(); + return n1; + + case TEOF: + if (!n1 && (nlflag & 1)) + n1 = NODE_EOF; + parseheredoc(); + return n1; + } + + checkkwd = CHKNL | CHKKWD | CHKALIAS; + if (nlflag == 2 && tokname_array[peektoken()][0]) + return n1; + nlflag |= 2; + n2 = andor(); tok = readtoken(); if (tok == TBACKGND) { @@ -10563,30 +10579,15 @@ list(int nlflag) n1 = n3; } switch (tok) { + case TNL: + case TEOF: + tokpushback = 1; + /* fall through */ case TBACKGND: case TSEMI: - tok = readtoken(); - /* fall through */ - case TNL: - if (tok == TNL) { - parseheredoc(); - if (nlflag == 1) - return n1; - } else { - tokpushback = 1; - } - checkkwd = CHKNL | CHKKWD | CHKALIAS; - if (peektoken()) - return n1; break; - case TEOF: - if (heredoclist) - parseheredoc(); - else - pungetc(); /* push back EOF on input */ - return n1; default: - if (nlflag == 1) + if ((nlflag & 1)) raise_error_unexpected_syntax(-1); tokpushback = 1; return n1; @@ -11954,14 +11955,14 @@ readtoken(void) return t; } -static char +static int peektoken(void) { int t; t = readtoken(); tokpushback = 1; - return tokname_array[t][0]; + return t; } /* @@ -11971,18 +11972,12 @@ peektoken(void) static union node * parsecmd(int interact) { - int t; - tokpushback = 0; + checkkwd = 0; + heredoclist = 0; doprompt = interact; setprompt_if(doprompt, doprompt); needprompt = 0; - t = readtoken(); - if (t == TEOF) - return NODE_EOF; - if (t == TNL) - return NULL; - tokpushback = 1; return list(1); } From 112889d70670a23ecf8d493eab7e632b47435bb9 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Thu, 29 Oct 2015 22:37:25 +0100 Subject: [PATCH 084/260] hush: copy for.tests from ash testsuite This test passes for hush Signed-off-by: Denys Vlasenko --- shell/hush_test/hush-misc/for.right | 1 + shell/hush_test/hush-misc/for.tests | 5 +++++ 2 files changed, 6 insertions(+) create mode 100644 shell/hush_test/hush-misc/for.right create mode 100755 shell/hush_test/hush-misc/for.tests diff --git a/shell/hush_test/hush-misc/for.right b/shell/hush_test/hush-misc/for.right new file mode 100644 index 000000000..d86bac9de --- /dev/null +++ b/shell/hush_test/hush-misc/for.right @@ -0,0 +1 @@ +OK diff --git a/shell/hush_test/hush-misc/for.tests b/shell/hush_test/hush-misc/for.tests new file mode 100755 index 000000000..4889a9f2d --- /dev/null +++ b/shell/hush_test/hush-misc/for.tests @@ -0,0 +1,5 @@ +for i +in OK +do + echo $i +done From ae57af6e78ed7179b2b12675ad86adc4e8d5bebd Mon Sep 17 00:00:00 2001 From: Ron Yorston Date: Sat, 30 May 2015 17:13:52 +0100 Subject: [PATCH 085/260] busybox: alter help message in standalone shell mode Signed-off-by: Ron Yorston Signed-off-by: Denys Vlasenko --- libbb/appletlib.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/libbb/appletlib.c b/libbb/appletlib.c index 58bb2f1a0..95e589e74 100644 --- a/libbb/appletlib.c +++ b/libbb/appletlib.c @@ -641,10 +641,19 @@ static int busybox_main(char **argv) ) " or: function [arguments]...\n" "\n" + IF_NOT_FEATURE_SH_STANDALONE( "\tBusyBox is a multi-call binary that combines many common Unix\n" "\tutilities into a single executable. Most people will create a\n" "\tlink to busybox for each function they wish to use and BusyBox\n" "\twill act like whatever it was invoked as.\n" + ) + IF_FEATURE_SH_STANDALONE( + "\tBusyBox is a multi-call binary that combines many common Unix\n" + "\tutilities into a single executable. The shell in this build\n" + "\tis configured to run built-in utilities without $PATH search.\n" + "\tYou don't need to install a link to busybox for each utility.\n" + "\tTo run external program, use full path (/sbin/ip instead of ip).\n" + ) "\n" "Currently defined functions:\n" ); From f23264b35f5bb138c6c3676079251e71bee42c8a Mon Sep 17 00:00:00 2001 From: Ron Yorston Date: Fri, 29 May 2015 11:31:40 +0100 Subject: [PATCH 086/260] lineedit: search applets as well as PATH for tab completion In standalone shell mode search the applet table as well as PATH when tab completing a command. Use a stupid linear search: we're also about to read all the directories on PATH so efficiency isn't a big concern. function old new delta add_match - 53 +53 complete_cmd_dir_file 687 724 +37 ------------------------------------------------------------------------------ (add/remove: 1/0 grow/shrink: 1/0 up/down: 90/0) Total: 90 bytes Signed-off-by: Ron Yorston Signed-off-by: Denys Vlasenko --- libbb/lineedit.c | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/libbb/lineedit.c b/libbb/lineedit.c index a83e07c0c..2ddb2b6e9 100644 --- a/libbb/lineedit.c +++ b/libbb/lineedit.c @@ -47,7 +47,8 @@ * It stems from simplistic "cmdedit_y = cmdedit_prmt_len / cmdedit_termw" * calculation of how many lines the prompt takes. */ -#include "libbb.h" +#include "busybox.h" +#include "NUM_APPLETS.h" #include "unicode.h" #ifndef _POSIX_VDISABLE # define _POSIX_VDISABLE '\0' @@ -774,6 +775,20 @@ static NOINLINE unsigned complete_cmd_dir_file(const char *command, int type) } pf_len = strlen(pfind); +#if ENABLE_FEATURE_SH_STANDALONE && NUM_APPLETS != 1 + if (type == FIND_EXE_ONLY) { + const char *p = applet_names; + + i = 0; + while (i < NUM_APPLETS) { + if (strncmp(pfind, p, pf_len) == 0) + add_match(xstrdup(p)); + p += strlen(p) + 1; + i++; + } + } +#endif + for (i = 0; i < npaths; i++) { DIR *dir; struct dirent *next; From fe0dc34746b141f158908e311b405dd332c3dcb1 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Fri, 30 Oct 2015 21:39:19 +0100 Subject: [PATCH 087/260] lineedit: FEATURE_REVERSE_SEARCH should not depend on SAVEHISTORY Signed-off-by: Denys Vlasenko --- libbb/Config.src | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libbb/Config.src b/libbb/Config.src index b02ea14b0..6ba256290 100644 --- a/libbb/Config.src +++ b/libbb/Config.src @@ -114,7 +114,7 @@ config FEATURE_EDITING_SAVE_ON_EXIT config FEATURE_REVERSE_SEARCH bool "Reverse history search" default y - depends on FEATURE_EDITING_SAVEHISTORY + depends on FEATURE_EDITING help Enable readline-like Ctrl-R combination for reverse history search. Increases code by about 0.5k. From ace833028f12c236ac6d148158d10129e542b985 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Fri, 30 Oct 2015 22:10:44 +0100 Subject: [PATCH 088/260] stat: make -f optional. This allows to build stat for non-linux systems function old new delta packed_usage 30761 30706 -55 Based on the patch by Ron Yorston. Signed-off-by: Denys Vlasenko --- coreutils/Config.src | 16 --------- coreutils/stat.c | 81 +++++++++++++++++++++++++++++++++----------- 2 files changed, 61 insertions(+), 36 deletions(-) diff --git a/coreutils/Config.src b/coreutils/Config.src index ffbef1a31..619c2efe8 100644 --- a/coreutils/Config.src +++ b/coreutils/Config.src @@ -543,22 +543,6 @@ config FEATURE_SPLIT_FANCY Supports additional suffixes 'b' for 512 bytes, 'g' for 1GiB for the -b option. -config STAT - bool "stat" - default y - select PLATFORM_LINUX # statfs() - help - display file or filesystem status. - -config FEATURE_STAT_FORMAT - bool "Enable custom formats (-c)" - default y - depends on STAT - help - Without this, stat will not support the '-c format' option where - users can pass a custom format string for output. This adds about - 7k to a nonstatic build on amd64. - config STTY bool "stty" default y diff --git a/coreutils/stat.c b/coreutils/stat.c index f7fd227bb..1a490fef7 100644 --- a/coreutils/stat.c +++ b/coreutils/stat.c @@ -12,54 +12,83 @@ * * Licensed under GPLv2 or later, see file LICENSE in this source tree. */ +//config:config STAT +//config: bool "stat" +//config: default y +//config: help +//config: display file or filesystem status. +//config: +//config:config FEATURE_STAT_FORMAT +//config: bool "Enable custom formats (-c)" +//config: default y +//config: depends on STAT +//config: help +//config: Without this, stat will not support the '-c format' option where +//config: users can pass a custom format string for output. This adds about +//config: 7k to a nonstatic build on amd64. +//config: +//config:config FEATURE_STAT_FILESYSTEM +//config: bool "Enable display of filesystem status (-f)" +//config: default y +//config: depends on STAT +//config: select PLATFORM_LINUX # statfs() +//config: help +//config: Without this, stat will not support the '-f' option to display +//config: information about filesystem status. + //usage:#define stat_trivial_usage //usage: "[OPTIONS] FILE..." //usage:#define stat_full_usage "\n\n" -//usage: "Display file (default) or filesystem status\n" +//usage: "Display file" +//usage: IF_FEATURE_STAT_FILESYSTEM(" (default) or filesystem") +//usage: " status\n" //usage: IF_FEATURE_STAT_FORMAT( -//usage: "\n -c fmt Use the specified format" +//usage: "\n -c FMT Use the specified format" //usage: ) +//usage: IF_FEATURE_STAT_FILESYSTEM( //usage: "\n -f Display filesystem status" +//usage: ) //usage: "\n -L Follow links" -//usage: "\n -t Display info in terse form" +//usage: "\n -t Terse display" //usage: IF_SELINUX( //usage: "\n -Z Print security context" //usage: ) //usage: IF_FEATURE_STAT_FORMAT( -//usage: "\n\nValid format sequences for files:\n" +//usage: "\n\nFMT sequences"IF_FEATURE_STAT_FILESYSTEM(" for files")":\n" //usage: " %a Access rights in octal\n" //usage: " %A Access rights in human readable form\n" //usage: " %b Number of blocks allocated (see %B)\n" -//usage: " %B The size in bytes of each block reported by %b\n" +//usage: " %B Size in bytes of each block reported by %b\n" //usage: " %d Device number in decimal\n" //usage: " %D Device number in hex\n" //usage: " %f Raw mode in hex\n" //usage: " %F File type\n" -//usage: " %g Group ID of owner\n" -//usage: " %G Group name of owner\n" +//usage: " %g Group ID\n" +//usage: " %G Group name\n" //usage: " %h Number of hard links\n" //usage: " %i Inode number\n" //usage: " %n File name\n" //usage: " %N File name, with -> TARGET if symlink\n" //usage: " %o I/O block size\n" -//usage: " %s Total size, in bytes\n" +//usage: " %s Total size in bytes\n" //usage: " %t Major device type in hex\n" //usage: " %T Minor device type in hex\n" -//usage: " %u User ID of owner\n" -//usage: " %U User name of owner\n" +//usage: " %u User ID\n" +//usage: " %U User name\n" //usage: " %x Time of last access\n" //usage: " %X Time of last access as seconds since Epoch\n" //usage: " %y Time of last modification\n" //usage: " %Y Time of last modification as seconds since Epoch\n" //usage: " %z Time of last change\n" //usage: " %Z Time of last change as seconds since Epoch\n" -//usage: "\nValid format sequences for file systems:\n" +//usage: IF_FEATURE_STAT_FILESYSTEM( +//usage: "\nFMT sequences for file systems:\n" //usage: " %a Free blocks available to non-superuser\n" -//usage: " %b Total data blocks in file system\n" -//usage: " %c Total file nodes in file system\n" -//usage: " %d Free file nodes in file system\n" -//usage: " %f Free blocks in file system\n" +//usage: " %b Total data blocks\n" +//usage: " %c Total file nodes\n" +//usage: " %d Free file nodes\n" +//usage: " %f Free blocks\n" //usage: IF_SELINUX( //usage: " %C Security context in selinux\n" //usage: ) @@ -71,13 +100,16 @@ //usage: " %t Type in hex\n" //usage: " %T Type in human readable form" //usage: ) +//usage: ) #include "libbb.h" -#define OPT_FILESYS (1 << 0) -#define OPT_TERSE (1 << 1) -#define OPT_DEREFERENCE (1 << 2) -#define OPT_SELINUX (1 << 3) +enum { + OPT_TERSE = (1 << 0), + OPT_DEREFERENCE = (1 << 1), + OPT_FILESYS = (1 << 2) * ENABLE_FEATURE_STAT_FILESYSTEM, + OPT_SELINUX = (1 << (2+ENABLE_FEATURE_STAT_FILESYSTEM)) * ENABLE_SELINUX, +}; #if ENABLE_FEATURE_STAT_FORMAT typedef bool (*statfunc_ptr)(const char *, const char *); @@ -132,6 +164,7 @@ static const char *human_time(time_t t) #undef buf } +#if ENABLE_FEATURE_STAT_FILESYSTEM /* Return the type of the specified file system. * Some systems have statfvs.f_basetype[FSTYPSZ]. (AIX, HP-UX, and Solaris) * Others have statfs.f_fstypename[MFSNAMELEN]. (NetBSD 1.5.2) @@ -202,6 +235,7 @@ static unsigned long long get_f_fsid(const struct statfs *statfsbuf) while (--sz > 0); return r; } +#endif /* FEATURE_STAT_FILESYSTEM */ #if ENABLE_FEATURE_STAT_FORMAT static void strcatc(char *str, char c) @@ -217,6 +251,7 @@ static void printfs(char *pformat, const char *msg) printf(pformat, msg); } +#if ENABLE_FEATURE_STAT_FILESYSTEM /* print statfs info */ static void FAST_FUNC print_statfs(char *pformat, const char m, const char *const filename, const void *data @@ -263,6 +298,7 @@ static void FAST_FUNC print_statfs(char *pformat, const char m, printf(pformat, m); } } +#endif /* print stat info */ static void FAST_FUNC print_stat(char *pformat, const char m, @@ -423,6 +459,7 @@ static void print_it(const char *masterformat, } #endif /* FEATURE_STAT_FORMAT */ +#if ENABLE_FEATURE_STAT_FILESYSTEM /* Stat the file system and print what we find. */ #if !ENABLE_FEATURE_STAT_FORMAT #define do_statfs(filename, format) do_statfs(filename) @@ -538,6 +575,7 @@ static bool do_statfs(const char *filename, const char *format) #endif /* FEATURE_STAT_FORMAT */ return 1; } +#endif /* FEATURE_STAT_FILESYSTEM */ /* stat the file and print what we find */ #if !ENABLE_FEATURE_STAT_FORMAT @@ -721,12 +759,15 @@ int stat_main(int argc UNUSED_PARAM, char **argv) statfunc_ptr statfunc = do_stat; opt_complementary = "-1"; /* min one arg */ - opts = getopt32(argv, "ftL" + opts = getopt32(argv, "tL" + IF_FEATURE_STAT_FILESYSTEM("f") IF_SELINUX("Z") IF_FEATURE_STAT_FORMAT("c:", &format) ); +#if ENABLE_FEATURE_STAT_FILESYSTEM if (opts & OPT_FILESYS) /* -f */ statfunc = do_statfs; +#endif #if ENABLE_SELINUX if (opts & OPT_SELINUX) { selinux_or_die(); From e939856c8724e357b3a7ba878563bfc957605504 Mon Sep 17 00:00:00 2001 From: Ron Yorston Date: Fri, 30 Oct 2015 19:05:55 +0000 Subject: [PATCH 089/260] ash: add tests for failures of the exec and command builtins The exec builtin should return an exit status of 127 if the command can't be found. It doesn't: it returns 2. If the command builtin is used to source a script that runs a second script that doesn't exist ash should issue an error. Instead it seg faults. Signed-off-by: Ron Yorston Signed-off-by: Denys Vlasenko --- shell/ash_test/ash-misc/command2.right | 2 ++ shell/ash_test/ash-misc/command2.tests | 6 ++++++ shell/ash_test/ash-misc/exec.right | 2 ++ shell/ash_test/ash-misc/exec.tests | 3 +++ 4 files changed, 13 insertions(+) create mode 100644 shell/ash_test/ash-misc/command2.right create mode 100755 shell/ash_test/ash-misc/command2.tests create mode 100644 shell/ash_test/ash-misc/exec.right create mode 100755 shell/ash_test/ash-misc/exec.tests diff --git a/shell/ash_test/ash-misc/command2.right b/shell/ash_test/ash-misc/command2.right new file mode 100644 index 000000000..8d2165f69 --- /dev/null +++ b/shell/ash_test/ash-misc/command2.right @@ -0,0 +1,2 @@ +test1 +./command2.tests: ./test1.sh: line 1: ./test2.sh: Permission denied diff --git a/shell/ash_test/ash-misc/command2.tests b/shell/ash_test/ash-misc/command2.tests new file mode 100755 index 000000000..9d9de9a89 --- /dev/null +++ b/shell/ash_test/ash-misc/command2.tests @@ -0,0 +1,6 @@ +echo "echo test1; ./test2.sh" >test1.sh +echo "echo test2" >test2.sh + +command . ./test1.sh + +rm -f test1.sh test2.sh diff --git a/shell/ash_test/ash-misc/exec.right b/shell/ash_test/ash-misc/exec.right new file mode 100644 index 000000000..1741a38dd --- /dev/null +++ b/shell/ash_test/ash-misc/exec.right @@ -0,0 +1,2 @@ +./exec.tests: exec: line 2: ./test1.sh: not found +127 diff --git a/shell/ash_test/ash-misc/exec.tests b/shell/ash_test/ash-misc/exec.tests new file mode 100755 index 000000000..624915de1 --- /dev/null +++ b/shell/ash_test/ash-misc/exec.tests @@ -0,0 +1,3 @@ +rm -f test1.sh +(exec ./test1.sh) +echo $? From 8c55dc79a79d6a16c364e6b1f849bf426f21fcbb Mon Sep 17 00:00:00 2001 From: Ron Yorston Date: Fri, 30 Oct 2015 19:06:47 +0000 Subject: [PATCH 090/260] ash: fix EXEXEC status clobbering evalcommand always clobbers the exit status in case of an EXEXEC which means that exec always fails with exit status 2 regardless of what it actually returns. This patch adds the missing check for EXEXEC so that the correct exit status is preserved. It causes the test ash-misc/exec.tests to succeed. Based on commit 7f68426 in dash git, by Herbert Xu. Signed-off-by: Ron Yorston Signed-off-by: Denys Vlasenko --- shell/ash.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/shell/ash.c b/shell/ash.c index 9a8bab5ab..c333b235b 100644 --- a/shell/ash.c +++ b/shell/ash.c @@ -9432,7 +9432,7 @@ evalcommand(union node *cmd, int flags) if (evalbltin(cmdentry.u.cmd, argc, argv)) { int exit_status; int i = exception_type; - if (i == EXEXIT) + if (i == EXEXIT || i == EXEXEC) goto raise; exit_status = 2; if (i == EXINT) From 95650a86d176ee83a264fd9e7047c414b71ee7cb Mon Sep 17 00:00:00 2001 From: Ron Yorston Date: Fri, 30 Oct 2015 19:07:37 +0000 Subject: [PATCH 091/260] ash: allow popredir to be called if the stack is empty If /tmp/test.sh is a script that tries to run a second script which happens to be non-executable this: command . /tmp/test.sh causes a seg fault. This is because clearredir is called in the error path to clear the stack of redirections. The normal path then calls popredir, but popredir fails when the stack is empty. Reported-by: Bastian Bittorf Signed-off-by: Ron Yorston Signed-off-by: Denys Vlasenko --- shell/ash.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/shell/ash.c b/shell/ash.c index c333b235b..84502636a 100644 --- a/shell/ash.c +++ b/shell/ash.c @@ -5409,7 +5409,7 @@ popredir(int drop, int restore) struct redirtab *rp; int i; - if (--g_nullredirs >= 0) + if (--g_nullredirs >= 0 || redirlist == NULL) return; INT_OFF; rp = redirlist; From 6bd3fff51aa74e2ee2d87887b12182a3b09792ef Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Fri, 30 Oct 2015 23:41:53 +0100 Subject: [PATCH 092/260] [g]unzip: fix recent breakage. Also, do emit error message we so painstakingly pass from gzip internals Signed-off-by: Denys Vlasenko --- archival/libarchive/decompress_gunzip.c | 33 ++++++++++++++++--------- testsuite/unzip.tests | 1 + 2 files changed, 22 insertions(+), 12 deletions(-) diff --git a/archival/libarchive/decompress_gunzip.c b/archival/libarchive/decompress_gunzip.c index 30bf45154..20e4d9ac5 100644 --- a/archival/libarchive/decompress_gunzip.c +++ b/archival/libarchive/decompress_gunzip.c @@ -309,8 +309,7 @@ static int huft_build(const unsigned *b, const unsigned n, huft_t *q; /* points to current table */ huft_t r; /* table entry for structure assignment */ huft_t *u[BMAX]; /* table stack */ - unsigned v[N_MAX]; /* values in order of bit length */ - unsigned v_end; + unsigned v[N_MAX + 1]; /* values in order of bit length. last v[] is never used */ int ws[BMAX + 1]; /* bits decoded stack */ int w; /* bits decoded */ unsigned x[BMAX + 1]; /* bit offsets, then code stack */ @@ -365,15 +364,17 @@ static int huft_build(const unsigned *b, const unsigned n, *xp++ = j; } - /* Make a table of values in order of bit lengths */ + /* Make a table of values in order of bit lengths. + * To detect bad input, unused v[i]'s are set to invalid value UINT_MAX. + * In particular, last v[i] is never filled and must not be accessed. + */ + memset(v, 0xff, sizeof(v)); p = b; i = 0; - v_end = 0; do { j = *p++; if (j != 0) { v[x[j]++] = i; - v_end = x[j]; } } while (++i < n); @@ -435,7 +436,9 @@ static int huft_build(const unsigned *b, const unsigned n, /* set up table entry in r */ r.b = (unsigned char) (k - w); - if (p >= v + v_end) { // Was "if (p >= v + n)" but v[] can be shorter! + if (/*p >= v + n || -- redundant, caught by the second check: */ + *p == UINT_MAX /* do we access uninited v[i]? (see memset(v))*/ + ) { r.e = 99; /* out of values--invalid code */ } else if (*p < s) { r.e = (unsigned char) (*p < 256 ? 16 : 15); /* 256 is EOB code */ @@ -520,8 +523,9 @@ static NOINLINE int inflate_codes(STATE_PARAM_ONLY) e = t->e; if (e > 16) do { - if (e == 99) - abort_unzip(PASS_STATE_ONLY);; + if (e == 99) { + abort_unzip(PASS_STATE_ONLY); + } bb >>= t->b; k -= t->b; e -= 16; @@ -557,8 +561,9 @@ static NOINLINE int inflate_codes(STATE_PARAM_ONLY) e = t->e; if (e > 16) do { - if (e == 99) + if (e == 99) { abort_unzip(PASS_STATE_ONLY); + } bb >>= t->b; k -= t->b; e -= 16; @@ -824,8 +829,9 @@ static int inflate_block(STATE_PARAM smallint *e) b_dynamic >>= 4; k_dynamic -= 4; - if (nl > 286 || nd > 30) + if (nl > 286 || nd > 30) { abort_unzip(PASS_STATE_ONLY); /* bad lengths */ + } /* read in bit-length-code lengths */ for (j = 0; j < nb; j++) { @@ -906,12 +912,14 @@ static int inflate_block(STATE_PARAM smallint *e) bl = lbits; i = huft_build(ll, nl, 257, cplens, cplext, &inflate_codes_tl, &bl); - if (i != 0) + if (i != 0) { abort_unzip(PASS_STATE_ONLY); + } bd = dbits; i = huft_build(ll + nl, nd, 0, cpdist, cpdext, &inflate_codes_td, &bd); - if (i != 0) + if (i != 0) { abort_unzip(PASS_STATE_ONLY); + } /* set up data for inflate_codes() */ inflate_codes_setup(PASS_STATE bl, bd); @@ -999,6 +1007,7 @@ inflate_unzip_internal(STATE_PARAM transformer_state_t *xstate) error_msg = "corrupted data"; if (setjmp(error_jmp)) { /* Error from deep inside zip machinery */ + bb_error_msg(error_msg); n = -1; goto ret; } diff --git a/testsuite/unzip.tests b/testsuite/unzip.tests index ca0a45800..d8738a3bd 100755 --- a/testsuite/unzip.tests +++ b/testsuite/unzip.tests @@ -34,6 +34,7 @@ rm foo.zip testing "unzip (bad archive)" "uudecode; unzip bad.zip 2>&1; echo \$?" \ "Archive: bad.zip inflating: ]3j½r«IK-%Ix +unzip: corrupted data unzip: inflate error 1 " \ From 1062391365981a09069f96509937b7f1181b7484 Mon Sep 17 00:00:00 2001 From: Natanael Copa Date: Wed, 19 Sep 2012 16:55:08 +0200 Subject: [PATCH 093/260] ifupdown: use -x hostname:NAME with udhcpc The -H NAME is deprecated in udhcpc. See commit 2017d48c0d70bef8768efb42909e605ea8eb5a21 Signed-off-by: Natanael Copa Signed-off-by: Denys Vlasenko --- networking/ifupdown.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/networking/ifupdown.c b/networking/ifupdown.c index d477ff6d1..766dfabbd 100644 --- a/networking/ifupdown.c +++ b/networking/ifupdown.c @@ -535,7 +535,7 @@ static const struct dhcp_client_t ext_dhcp_clients[] = { "pump -i %iface% -k", }, { "udhcpc", - "udhcpc " UDHCPC_CMD_OPTIONS " -p /var/run/udhcpc.%iface%.pid -i %iface%[[ -H %hostname%]][[ -c %client%]]" + "udhcpc " UDHCPC_CMD_OPTIONS " -p /var/run/udhcpc.%iface%.pid -i %iface%[[ -x hostname:%hostname%]][[ -c %client%]]" "[[ -s %script%]][[ %udhcpc_opts%]]", "kill `cat /var/run/udhcpc.%iface%.pid` 2>/dev/null", }, @@ -575,7 +575,7 @@ static int FAST_FUNC dhcp_up(struct interface_defn_t *ifd, execfn *exec) return 0; # endif return execute("udhcpc " UDHCPC_CMD_OPTIONS " -p /var/run/udhcpc.%iface%.pid " - "-i %iface%[[ -H %hostname%]][[ -c %client%]][[ -s %script%]][[ %udhcpc_opts%]]", + "-i %iface%[[ -x hostname:%hostname%]][[ -c %client%]][[ -s %script%]][[ %udhcpc_opts%]]", ifd, exec); } # else From 99f025a4999ee9d44db17d8abfbde7813bf99de1 Mon Sep 17 00:00:00 2001 From: Bartosz Golaszewski Date: Tue, 27 Oct 2015 17:15:00 +0100 Subject: [PATCH 094/260] i2cdetect: fix address skipping in auto mode If the bus doesn't support SMBus Quick Write or Receive Byte commands and we're running in auto mode all addresses will be skipped resulting in an empty table being printed. This is caused by not restoring the auto mode after it's been changed for certain address ranges - we need an additional variable to hold the temporary state. Signed-off-by: Bartosz Golaszewski Signed-off-by: Denys Vlasenko --- miscutils/i2c_tools.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/miscutils/i2c_tools.c b/miscutils/i2c_tools.c index d77e6bacf..c5baaa78e 100644 --- a/miscutils/i2c_tools.c +++ b/miscutils/i2c_tools.c @@ -1200,7 +1200,7 @@ int i2cdetect_main(int argc UNUSED_PARAM, char **argv) opt_F = (1 << 4), opt_l = (1 << 5); const char *const optstr = "yaqrFl"; - int fd, bus_num, i, j, mode = I2CDETECT_MODE_AUTO, status; + int fd, bus_num, i, j, mode = I2CDETECT_MODE_AUTO, status, cmd; unsigned first = 0x03, last = 0x77, opts; unsigned long funcs; @@ -1273,19 +1273,20 @@ int i2cdetect_main(int argc UNUSED_PARAM, char **argv) for(j = 0; j < 16; j++) { fflush_all(); + cmd = mode; if (mode == I2CDETECT_MODE_AUTO) { if ((i+j >= 0x30 && i+j <= 0x37) || (i+j >= 0x50 && i+j <= 0x5F)) - mode = I2CDETECT_MODE_READ; + cmd = I2CDETECT_MODE_READ; else - mode = I2CDETECT_MODE_QUICK; + cmd = I2CDETECT_MODE_QUICK; } /* Skip unwanted addresses. */ if (i+j < first || i+j > last - || (mode == I2CDETECT_MODE_READ && !(funcs & I2C_FUNC_SMBUS_READ_BYTE)) - || (mode == I2CDETECT_MODE_QUICK && !(funcs & I2C_FUNC_SMBUS_QUICK))) + || (cmd == I2CDETECT_MODE_READ && !(funcs & I2C_FUNC_SMBUS_READ_BYTE)) + || (cmd == I2CDETECT_MODE_QUICK && !(funcs & I2C_FUNC_SMBUS_QUICK))) { printf(" "); continue; @@ -1302,7 +1303,7 @@ int i2cdetect_main(int argc UNUSED_PARAM, char **argv) "can't set address to 0x%02x", i + j); } - switch (mode) { + switch (cmd) { case I2CDETECT_MODE_READ: /* * This is known to lock SMBus on various From fc8eb056ea8b81798467f8306629a7ea1feffe50 Mon Sep 17 00:00:00 2001 From: Bartosz Golaszewski Date: Tue, 27 Oct 2015 17:15:01 +0100 Subject: [PATCH 095/260] i2cdetect: coding style: add a space after 'for' Signed-off-by: Bartosz Golaszewski Signed-off-by: Denys Vlasenko --- miscutils/i2c_tools.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/miscutils/i2c_tools.c b/miscutils/i2c_tools.c index c5baaa78e..907d738fd 100644 --- a/miscutils/i2c_tools.c +++ b/miscutils/i2c_tools.c @@ -1270,7 +1270,7 @@ int i2cdetect_main(int argc UNUSED_PARAM, char **argv) puts(" 0 1 2 3 4 5 6 7 8 9 a b c d e f"); for (i = 0; i < 128; i += 16) { printf("%02x: ", i); - for(j = 0; j < 16; j++) { + for (j = 0; j < 16; j++) { fflush_all(); cmd = mode; From 1cde5f79d4c077cd6a2a8998a9180dfcc2800852 Mon Sep 17 00:00:00 2001 From: Bartosz Golaszewski Date: Tue, 27 Oct 2015 17:15:02 +0100 Subject: [PATCH 096/260] i2cdump: don't read block data in non-block modes We currently read data twice in byte mode. Add a check to avoid calling i2c_smbus_read_i2c_block_data() if we're not in I2C or SMBus block mode. Signed-off-by: Bartosz Golaszewski Signed-off-by: Denys Vlasenko --- miscutils/i2c_tools.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/miscutils/i2c_tools.c b/miscutils/i2c_tools.c index 907d738fd..094bf9e38 100644 --- a/miscutils/i2c_tools.c +++ b/miscutils/i2c_tools.c @@ -971,7 +971,8 @@ int i2cdump_main(int argc UNUSED_PARAM, char **argv) /* All but word data. */ if (mode != I2C_SMBUS_WORD_DATA || even) { - blen = read_block_data(fd, mode, block); + if (mode == I2C_SMBUS_BLOCK_DATA || mode == I2C_SMBUS_I2C_BLOCK_DATA) + blen = read_block_data(fd, mode, block); if (mode == I2C_SMBUS_BYTE) { res = i2c_smbus_write_byte(fd, first); From 1fe75b8ef10933d047f7ab6060d4710a39611e92 Mon Sep 17 00:00:00 2001 From: Bartosz Golaszewski Date: Tue, 27 Oct 2015 17:15:03 +0100 Subject: [PATCH 097/260] i2cdump: use I2C block mode for the 'i' mode parameter Currently we're calling i2c_smbus_read_block_data() for both 'i' and 's' mode parameters. If the bus doesn't support SMBus block mode, then the i2c access ioctl() fails. Make i2cdump behave compatibly with upstream version by calling i2c_smbus_read_i2c_block_data() for I2C block. Signed-off-by: Bartosz Golaszewski Signed-off-by: Denys Vlasenko --- miscutils/i2c_tools.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/miscutils/i2c_tools.c b/miscutils/i2c_tools.c index 094bf9e38..6d221e9fc 100644 --- a/miscutils/i2c_tools.c +++ b/miscutils/i2c_tools.c @@ -723,7 +723,7 @@ static int read_block_data(int buf_fd, int mode, int *block) uint8_t cblock[I2C_SMBUS_BLOCK_MAX + I2CDUMP_NUM_REGS]; int res, blen = 0, tmp, i; - if (mode == I2C_SMBUS_BLOCK_DATA || mode == I2C_SMBUS_I2C_BLOCK_DATA) { + if (mode == I2C_SMBUS_BLOCK_DATA) { res = i2c_smbus_read_block_data(buf_fd, 0, cblock); blen = res; } else { From 74bb9d5e63b0928ceac57fedd4a2d383129ade7d Mon Sep 17 00:00:00 2001 From: Bartosz Golaszewski Date: Tue, 27 Oct 2015 17:15:04 +0100 Subject: [PATCH 098/260] i2cdump: bail-out if block read fails We should bail-out if i2c_smbus_read_block_data() or i2c_smbus_read_i2c_block_data() return 0 or less. Add the missing check for the former and fix the existing for the latter. Signed-off-by: Bartosz Golaszewski Signed-off-by: Denys Vlasenko --- miscutils/i2c_tools.c | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/miscutils/i2c_tools.c b/miscutils/i2c_tools.c index 6d221e9fc..7be489036 100644 --- a/miscutils/i2c_tools.c +++ b/miscutils/i2c_tools.c @@ -724,16 +724,16 @@ static int read_block_data(int buf_fd, int mode, int *block) int res, blen = 0, tmp, i; if (mode == I2C_SMBUS_BLOCK_DATA) { - res = i2c_smbus_read_block_data(buf_fd, 0, cblock); - blen = res; + blen = i2c_smbus_read_block_data(buf_fd, 0, cblock); + if (blen <= 0) + goto fail; } else { for (res = 0; res < I2CDUMP_NUM_REGS; res += tmp) { tmp = i2c_smbus_read_i2c_block_data( buf_fd, res, I2C_SMBUS_BLOCK_MAX, cblock + res); - if (tmp < 0) { - bb_error_msg_and_die("block read failed"); - } + if (tmp <= 0) + goto fail; } if (res >= I2CDUMP_NUM_REGS) @@ -748,6 +748,9 @@ static int read_block_data(int buf_fd, int mode, int *block) } return blen; + + fail: + bb_error_msg_and_die("block read failed"); } /* Dump all but word data. */ From 5ed6989d805535804fcd05ddc777fbae48d21f3a Mon Sep 17 00:00:00 2001 From: Bartosz Golaszewski Date: Tue, 27 Oct 2015 17:15:05 +0100 Subject: [PATCH 099/260] i2cdump: display the numeric value for block read ioctl() errors This makes busybox i2cdump compatible with the upstream version, which also displays the numeric error value in case of a block read failure. Signed-off-by: Bartosz Golaszewski Signed-off-by: Denys Vlasenko --- miscutils/i2c_tools.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/miscutils/i2c_tools.c b/miscutils/i2c_tools.c index 7be489036..e19d851fe 100644 --- a/miscutils/i2c_tools.c +++ b/miscutils/i2c_tools.c @@ -732,8 +732,10 @@ static int read_block_data(int buf_fd, int mode, int *block) tmp = i2c_smbus_read_i2c_block_data( buf_fd, res, I2C_SMBUS_BLOCK_MAX, cblock + res); - if (tmp <= 0) + if (tmp <= 0) { + blen = tmp; goto fail; + } } if (res >= I2CDUMP_NUM_REGS) @@ -750,7 +752,7 @@ static int read_block_data(int buf_fd, int mode, int *block) return blen; fail: - bb_error_msg_and_die("block read failed"); + bb_error_msg_and_die("block read failed: %d", blen); } /* Dump all but word data. */ From 2cf459141373d7ade0ba8cf5de83d4ef12b7dc97 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Sun, 1 Nov 2015 20:57:34 +0100 Subject: [PATCH 100/260] i2c_tools: suppress "'blen' may be used uninitialized in this function" Signed-off-by: Denys Vlasenko --- miscutils/i2c_tools.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/miscutils/i2c_tools.c b/miscutils/i2c_tools.c index e19d851fe..aa1c7c5cc 100644 --- a/miscutils/i2c_tools.c +++ b/miscutils/i2c_tools.c @@ -909,7 +909,7 @@ int i2cdump_main(int argc UNUSED_PARAM, char **argv) unsigned first = 0x00, last = 0xff, opts; int *block = (int *)bb_common_bufsiz1; char *opt_r_str, *dash; - int fd, res, blen; + int fd, res; opt_complementary = "-2:?3"; /* from 2 to 3 args */ opts = getopt32(argv, optstr, &opt_r_str); @@ -976,6 +976,8 @@ int i2cdump_main(int argc UNUSED_PARAM, char **argv) /* All but word data. */ if (mode != I2C_SMBUS_WORD_DATA || even) { + int blen = 0; + if (mode == I2C_SMBUS_BLOCK_DATA || mode == I2C_SMBUS_I2C_BLOCK_DATA) blen = read_block_data(fd, mode, block); From 85405c80a28509f2f36c0d4fda8693aac7652d9b Mon Sep 17 00:00:00 2001 From: Ron Yorston Date: Tue, 3 Nov 2015 09:37:40 +0000 Subject: [PATCH 101/260] ash: copy function tests from hush testsuite Signed-off-by: Ron Yorston Signed-off-by: Denys Vlasenko --- shell/ash_test/ash-misc/func1.right | 6 ++++++ shell/ash_test/ash-misc/func1.tests | 16 ++++++++++++++++ shell/ash_test/ash-misc/func2.right | 5 +++++ shell/ash_test/ash-misc/func2.tests | 9 +++++++++ shell/ash_test/ash-misc/func3.right | 4 ++++ shell/ash_test/ash-misc/func3.tests | 8 ++++++++ shell/ash_test/ash-misc/func4.right | 2 ++ shell/ash_test/ash-misc/func4.tests | 7 +++++++ shell/ash_test/ash-misc/func5.right | 6 ++++++ shell/ash_test/ash-misc/func5.tests | 13 +++++++++++++ shell/ash_test/ash-misc/func_args1.right | 5 +++++ shell/ash_test/ash-misc/func_args1.tests | 9 +++++++++ shell/ash_test/ash-misc/func_local1.right | 3 +++ shell/ash_test/ash-misc/func_local1.tests | 5 +++++ shell/ash_test/ash-misc/func_local2.right | 14 ++++++++++++++ shell/ash_test/ash-misc/func_local2.tests | 7 +++++++ 16 files changed, 119 insertions(+) create mode 100644 shell/ash_test/ash-misc/func1.right create mode 100755 shell/ash_test/ash-misc/func1.tests create mode 100644 shell/ash_test/ash-misc/func2.right create mode 100755 shell/ash_test/ash-misc/func2.tests create mode 100644 shell/ash_test/ash-misc/func3.right create mode 100755 shell/ash_test/ash-misc/func3.tests create mode 100644 shell/ash_test/ash-misc/func4.right create mode 100755 shell/ash_test/ash-misc/func4.tests create mode 100644 shell/ash_test/ash-misc/func5.right create mode 100755 shell/ash_test/ash-misc/func5.tests create mode 100644 shell/ash_test/ash-misc/func_args1.right create mode 100755 shell/ash_test/ash-misc/func_args1.tests create mode 100644 shell/ash_test/ash-misc/func_local1.right create mode 100755 shell/ash_test/ash-misc/func_local1.tests create mode 100644 shell/ash_test/ash-misc/func_local2.right create mode 100755 shell/ash_test/ash-misc/func_local2.tests diff --git a/shell/ash_test/ash-misc/func1.right b/shell/ash_test/ash-misc/func1.right new file mode 100644 index 000000000..e21665aaf --- /dev/null +++ b/shell/ash_test/ash-misc/func1.right @@ -0,0 +1,6 @@ +Hello +Zero: 0 +One: 1 Param1: World +Zero: 0 Param1: Restored +Multi line function +One: 1 diff --git a/shell/ash_test/ash-misc/func1.tests b/shell/ash_test/ash-misc/func1.tests new file mode 100755 index 000000000..ffb269fad --- /dev/null +++ b/shell/ash_test/ash-misc/func1.tests @@ -0,0 +1,16 @@ +f() { echo Hello; } +g () { echo One: $# Param1: $1; } +h ( ) +{ + echo -n 'Multi ' && echo -n 'line ' + echo function + false +} + +f +echo Zero: $? +set -- Restored +{ g World; } +echo Zero: $? Param1: $1 +( h ) +echo One: $? diff --git a/shell/ash_test/ash-misc/func2.right b/shell/ash_test/ash-misc/func2.right new file mode 100644 index 000000000..f2a041da7 --- /dev/null +++ b/shell/ash_test/ash-misc/func2.right @@ -0,0 +1,5 @@ +First 0 +Second 0 +First 1 +Second 1 +Done diff --git a/shell/ash_test/ash-misc/func2.tests b/shell/ash_test/ash-misc/func2.tests new file mode 100755 index 000000000..763203f15 --- /dev/null +++ b/shell/ash_test/ash-misc/func2.tests @@ -0,0 +1,9 @@ +i=0 +while test $i != 2; do + f() { echo First $i; } + f + f() { echo Second $i; } + f + : $((i++)) +done +echo Done diff --git a/shell/ash_test/ash-misc/func3.right b/shell/ash_test/ash-misc/func3.right new file mode 100644 index 000000000..b6d73459a --- /dev/null +++ b/shell/ash_test/ash-misc/func3.right @@ -0,0 +1,4 @@ +One:1 +Zero:0 +One:1 +Five:5 diff --git a/shell/ash_test/ash-misc/func3.tests b/shell/ash_test/ash-misc/func3.tests new file mode 100755 index 000000000..fa6f26a23 --- /dev/null +++ b/shell/ash_test/ash-misc/func3.tests @@ -0,0 +1,8 @@ +f() { false; return; echo BAD; }; +{ f; echo One:$?; }; echo Zero:$? + +f() { false; return; }; +f; echo One:$? + +f() { return 5; }; +f; echo Five:$? diff --git a/shell/ash_test/ash-misc/func4.right b/shell/ash_test/ash-misc/func4.right new file mode 100644 index 000000000..0c87e316a --- /dev/null +++ b/shell/ash_test/ash-misc/func4.right @@ -0,0 +1,2 @@ +24 +Done diff --git a/shell/ash_test/ash-misc/func4.tests b/shell/ash_test/ash-misc/func4.tests new file mode 100755 index 000000000..74c1b9a46 --- /dev/null +++ b/shell/ash_test/ash-misc/func4.tests @@ -0,0 +1,7 @@ +func() { + eval "echo \"\${val_${1}}\"" +} + +val_x=24 +(func x) +echo Done diff --git a/shell/ash_test/ash-misc/func5.right b/shell/ash_test/ash-misc/func5.right new file mode 100644 index 000000000..2c9d316b3 --- /dev/null +++ b/shell/ash_test/ash-misc/func5.right @@ -0,0 +1,6 @@ +1 +2 +3 +1 +2 +3 diff --git a/shell/ash_test/ash-misc/func5.tests b/shell/ash_test/ash-misc/func5.tests new file mode 100755 index 000000000..e967208cc --- /dev/null +++ b/shell/ash_test/ash-misc/func5.tests @@ -0,0 +1,13 @@ +f() { echo $1; } +f 1 + +f() ( echo $1; ) +f 2 + +f() ( echo $1 ) +f 3 + +f() for i in 1 2 3; do + echo $i +done +f diff --git a/shell/ash_test/ash-misc/func_args1.right b/shell/ash_test/ash-misc/func_args1.right new file mode 100644 index 000000000..2dfb9629b --- /dev/null +++ b/shell/ash_test/ash-misc/func_args1.right @@ -0,0 +1,5 @@ +params: a b c +'f 1 2 3' called +params: a b c +'f 1 2 3' called +params: a b c diff --git a/shell/ash_test/ash-misc/func_args1.tests b/shell/ash_test/ash-misc/func_args1.tests new file mode 100755 index 000000000..7970795a9 --- /dev/null +++ b/shell/ash_test/ash-misc/func_args1.tests @@ -0,0 +1,9 @@ + +f() { echo "'f $1 $2 $3' called"; } + +set -- a b c +echo "params: $1 $2 $3" +f 1 2 3 +echo "params: $1 $2 $3" +true | f 1 2 3 +echo "params: $1 $2 $3" diff --git a/shell/ash_test/ash-misc/func_local1.right b/shell/ash_test/ash-misc/func_local1.right new file mode 100644 index 000000000..312178366 --- /dev/null +++ b/shell/ash_test/ash-misc/func_local1.right @@ -0,0 +1,3 @@ +z=a +z=z +Done diff --git a/shell/ash_test/ash-misc/func_local1.tests b/shell/ash_test/ash-misc/func_local1.tests new file mode 100755 index 000000000..1d594e20c --- /dev/null +++ b/shell/ash_test/ash-misc/func_local1.tests @@ -0,0 +1,5 @@ +export z=z +f() { local z=a; env | grep ^z; } +f +env | grep ^z +echo Done diff --git a/shell/ash_test/ash-misc/func_local2.right b/shell/ash_test/ash-misc/func_local2.right new file mode 100644 index 000000000..fe9343ac8 --- /dev/null +++ b/shell/ash_test/ash-misc/func_local2.right @@ -0,0 +1,14 @@ +1 +2 +1 +2 +1 +1 +2 +2 +3 +2 +2 +3 +1 +Done diff --git a/shell/ash_test/ash-misc/func_local2.tests b/shell/ash_test/ash-misc/func_local2.tests new file mode 100755 index 000000000..1a9ae559d --- /dev/null +++ b/shell/ash_test/ash-misc/func_local2.tests @@ -0,0 +1,7 @@ +x=1 +f() { echo $x; local x=$((x+1)); echo $x; } +g() { f; echo $x; f; local x=$((x+1)); f; echo $x; f; } +f +g +echo $x +echo Done From bc9bee01f35d6c716c087e82dae5f439de90914b Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Wed, 4 Nov 2015 14:50:19 +0100 Subject: [PATCH 102/260] hush-misc/func_args1.tests: remove "UNFIXED BUG", it does not fail Signed-off-by: Denys Vlasenko --- shell/ash_test/ash-misc/func_args1.tests | 1 - shell/hush_test/hush-misc/func_args1.tests | 2 -- 2 files changed, 3 deletions(-) diff --git a/shell/ash_test/ash-misc/func_args1.tests b/shell/ash_test/ash-misc/func_args1.tests index 7970795a9..d394c637f 100755 --- a/shell/ash_test/ash-misc/func_args1.tests +++ b/shell/ash_test/ash-misc/func_args1.tests @@ -1,4 +1,3 @@ - f() { echo "'f $1 $2 $3' called"; } set -- a b c diff --git a/shell/hush_test/hush-misc/func_args1.tests b/shell/hush_test/hush-misc/func_args1.tests index 157921fb1..d394c637f 100755 --- a/shell/hush_test/hush-misc/func_args1.tests +++ b/shell/hush_test/hush-misc/func_args1.tests @@ -1,5 +1,3 @@ -# UNFIXED BUG - f() { echo "'f $1 $2 $3' called"; } set -- a b c From 95ebcf79ff6f8ad21ceacb7bac665fb86c078d84 Mon Sep 17 00:00:00 2001 From: Ron Yorston Date: Tue, 3 Nov 2015 09:42:23 +0000 Subject: [PATCH 103/260] ash: add support for bash 'function' keyword Where the POSIX shell allows functions to be defined as: name () compound-command [ redirections ] bash adds the alternative syntax: function name [()] compound-command [ redirections ] Implement this in ash's bash compatibility mode. Most compound commands work (for/while/until/if/case/[[]]/{}); one exception is: function f (echo "no way!") The other two variants work: f() (echo "ok") function f() (echo "also ok") function old new delta parse_command 1555 1744 +189 tokname_array 232 240 +8 .rodata 155612 155566 -46 ------------------------------------------------------------------------------ (add/remove: 0/0 grow/shrink: 2/1 up/down: 197/-46) Total: 151 bytes Signed-off-by: Ron Yorston Signed-off-by: Denys Vlasenko --- shell/ash.c | 101 ++++++++++++++++------- shell/ash_test/ash-misc/func_bash1.right | 12 +++ shell/ash_test/ash-misc/func_bash1.tests | 28 +++++++ 3 files changed, 110 insertions(+), 31 deletions(-) create mode 100644 shell/ash_test/ash-misc/func_bash1.right create mode 100755 shell/ash_test/ash-misc/func_bash1.tests diff --git a/shell/ash.c b/shell/ash.c index 84502636a..e7a867f52 100644 --- a/shell/ash.c +++ b/shell/ash.c @@ -7726,36 +7726,40 @@ changepath(const char *new) clearcmdentry(firstchange); builtinloc = idx_bltin; } - -#define TEOF 0 -#define TNL 1 -#define TREDIR 2 -#define TWORD 3 -#define TSEMI 4 -#define TBACKGND 5 -#define TAND 6 -#define TOR 7 -#define TPIPE 8 -#define TLP 9 -#define TRP 10 -#define TENDCASE 11 -#define TENDBQUOTE 12 -#define TNOT 13 -#define TCASE 14 -#define TDO 15 -#define TDONE 16 -#define TELIF 17 -#define TELSE 18 -#define TESAC 19 -#define TFI 20 -#define TFOR 21 -#define TIF 22 -#define TIN 23 -#define TTHEN 24 -#define TUNTIL 25 -#define TWHILE 26 -#define TBEGIN 27 -#define TEND 28 +enum { + TEOF, + TNL, + TREDIR, + TWORD, + TSEMI, + TBACKGND, + TAND, + TOR, + TPIPE, + TLP, + TRP, + TENDCASE, + TENDBQUOTE, + TNOT, + TCASE, + TDO, + TDONE, + TELIF, + TELSE, + TESAC, + TFI, + TFOR, +#if ENABLE_ASH_BASH_COMPAT + TFUNCTION, +#endif + TIF, + TIN, + TTHEN, + TUNTIL, + TWHILE, + TBEGIN, + TEND +}; typedef smallint token_id_t; /* first char is indicating which tokens mark the end of a list */ @@ -7784,6 +7788,9 @@ static const char *const tokname_array[] = { "\1esac", "\1fi", "\0for", +#if ENABLE_ASH_BASH_COMPAT + "\0function", +#endif "\0if", "\0in", "\1then", @@ -10762,6 +10769,7 @@ simplecmd(void) int savecheckkwd; #if ENABLE_ASH_BASH_COMPAT smallint double_brackets_flag = 0; + smallint function_flag = 0; #endif args = NULL; @@ -10778,6 +10786,11 @@ simplecmd(void) t = readtoken(); switch (t) { #if ENABLE_ASH_BASH_COMPAT + case TFUNCTION: + if (peektoken() != TWORD) + raise_error_unexpected_syntax(TWORD); + function_flag = 1; + break; case TAND: /* "&&" */ case TOR: /* "||" */ if (!double_brackets_flag) { @@ -10806,6 +10819,29 @@ simplecmd(void) app = &n->narg.next; savecheckkwd = 0; } +#if ENABLE_ASH_BASH_COMPAT + if (function_flag) { + checkkwd = CHKNL | CHKKWD; + switch (peektoken()) { + case TBEGIN: + case TIF: + case TCASE: + case TUNTIL: + case TWHILE: + case TFOR: + goto do_func; + case TLP: + function_flag = 0; + break; + case TWORD: + if (strcmp("[[", wordtext) == 0) + goto do_func; + /* fall through */ + default: + raise_error_unexpected_syntax(-1); + } + } +#endif break; case TREDIR: *rpp = n = redirnode; @@ -10813,6 +10849,7 @@ simplecmd(void) parsefname(); /* read name of redirection file */ break; case TLP: + IF_ASH_BASH_COMPAT(do_func:) if (args && app == &args->narg.next && !vars && !redir ) { @@ -10820,7 +10857,7 @@ simplecmd(void) const char *name; /* We have a function */ - if (readtoken() != TRP) + if (IF_ASH_BASH_COMPAT(!function_flag &&) readtoken() != TRP) raise_error_unexpected_syntax(TRP); name = n->narg.text; if (!goodname(name) @@ -10833,6 +10870,7 @@ simplecmd(void) n->narg.next = parse_command(); return n; } + IF_ASH_BASH_COMPAT(function_flag = 0;) /* fall through */ default: tokpushback = 1; @@ -11013,6 +11051,7 @@ parse_command(void) n1 = list(0); t = TEND; break; + IF_ASH_BASH_COMPAT(case TFUNCTION:) case TWORD: case TREDIR: tokpushback = 1; diff --git a/shell/ash_test/ash-misc/func_bash1.right b/shell/ash_test/ash-misc/func_bash1.right new file mode 100644 index 000000000..41bf8828c --- /dev/null +++ b/shell/ash_test/ash-misc/func_bash1.right @@ -0,0 +1,12 @@ +1 +2 +3 +1 +2 +3 +1 +2 +3 +1 +2 +3 diff --git a/shell/ash_test/ash-misc/func_bash1.tests b/shell/ash_test/ash-misc/func_bash1.tests new file mode 100755 index 000000000..2cc0970e8 --- /dev/null +++ b/shell/ash_test/ash-misc/func_bash1.tests @@ -0,0 +1,28 @@ +function f() { echo $1; } +f 1 + +function f() ( echo $1; ) +f 2 + +function f() ( echo $1 ) +f 3 + +function f() for i in 1 2 3; do + echo $i +done +f + +function f { echo $1; } +f 1 + +# the next two don't work +#function f ( echo $1; ) +f 2 + +#function f ( echo $1 ) +f 3 + +function f for i in 1 2 3; do + echo $i +done +f From 34adecc2b049f6941c5e075ffb58fe2183823da3 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Wed, 4 Nov 2015 19:39:54 +0100 Subject: [PATCH 104/260] TODO file: remove mpstat, iostat, powertop - we have them now Signed-off-by: Denys Vlasenko --- TODO | 2 -- 1 file changed, 2 deletions(-) diff --git a/TODO b/TODO index dcf48c2c2..8904b2135 100644 --- a/TODO +++ b/TODO @@ -258,5 +258,3 @@ vdprintf() -> similar sized functionality * more support for advanced linux 2.6.x features, see: iotop most likely there is more - -* even more support for statistics: mpstat, iostat, powertop.... From 48dc80bbba994eee24ed94ae4532a1cce76d7cb7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timo=20Ter=C3=A4s?= Date: Thu, 5 Nov 2015 18:54:55 +0100 Subject: [PATCH 105/260] modutils: merge module_entry and module_info to common MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This merges the in-memory module info structures of modprobe and depmod. This allows sharing hashing by modulename code improving depmod runtime with almost factor of 2x. function old new delta get_or_add_modentry - 17 +17 do_modprobe 590 601 +11 moddb_get_or_create - 10 +10 load_modules_dep 195 205 +10 moddb_get - 7 +7 add_probe 81 78 -3 modprobe_main 721 714 -7 depmod_main 553 543 -10 config_file_action 434 421 -13 helper_get_module 160 144 -16 parse_module 343 320 -23 order_dep_list 105 82 -23 ------------------------------------------------------------------------------ (add/remove: 3/0 grow/shrink: 2/7 up/down: 55/-95) Total: -40 bytes Signed-off-by: Timo Teräs Signed-off-by: Denys Vlasenko --- modutils/depmod.c | 86 +++++++++++++-------------------------------- modutils/modprobe.c | 66 ++++------------------------------ modutils/modutils.c | 51 +++++++++++++++++++++++++++ modutils/modutils.h | 30 ++++++++++++++++ 4 files changed, 113 insertions(+), 120 deletions(-) diff --git a/modutils/depmod.c b/modutils/depmod.c index 9713aef92..e5f0e3d2b 100644 --- a/modutils/depmod.c +++ b/modutils/depmod.c @@ -21,21 +21,13 @@ * for each depends, look through our list of full paths and emit if found */ -typedef struct module_info { - struct module_info *next; - char *name, *modname; - llist_t *dependencies; - llist_t *aliases; - llist_t *symbols; - struct module_info *dnext, *dprev; -} module_info; - static int FAST_FUNC parse_module(const char *fname, struct stat *sb UNUSED_PARAM, void *data, int depth UNUSED_PARAM) { - module_info **first = (module_info **) data; + module_db *modules = data; char *image, *ptr; - module_info *info; + module_entry *e; + /* Arbitrary. Was sb->st_size, but that breaks .gz etc */ size_t len = (64*1024*1024 - 4096); @@ -43,17 +35,10 @@ static int FAST_FUNC parse_module(const char *fname, struct stat *sb UNUSED_PARA return TRUE; image = xmalloc_open_zipped_read_close(fname, &len); - info = xzalloc(sizeof(*info)); - info->next = *first; - *first = info; + e = moddb_get_or_create(modules, bb_get_last_path_component_nostrip(fname)); + e->name = xstrdup(fname + 2); /* skip "./" */ - info->dnext = info->dprev = info; - info->name = xstrdup(fname + 2); /* skip "./" */ - info->modname = filename2modname( - bb_get_last_path_component_nostrip(fname), - NULL - ); for (ptr = image; ptr < image + len - 10; ptr++) { if (is_prefixed_with(ptr, "depends=")) { char *u; @@ -62,11 +47,11 @@ static int FAST_FUNC parse_module(const char *fname, struct stat *sb UNUSED_PARA for (u = ptr; *u; u++) if (*u == '-') *u = '_'; - ptr += string_to_llist(ptr, &info->dependencies, ","); + ptr += string_to_llist(ptr, &e->deps, ","); } else if (ENABLE_FEATURE_MODUTILS_ALIAS && is_prefixed_with(ptr, "alias=") ) { - llist_add_to(&info->aliases, xstrdup(ptr + 6)); + llist_add_to(&e->aliases, xstrdup(ptr + 6)); ptr += strlen(ptr); } else if (ENABLE_FEATURE_MODUTILS_SYMBOLS && is_prefixed_with(ptr, "__ksymtab_") @@ -77,7 +62,7 @@ static int FAST_FUNC parse_module(const char *fname, struct stat *sb UNUSED_PARA ) { continue; } - llist_add_to(&info->symbols, xstrdup(ptr)); + llist_add_to(&e->symbols, xstrdup(ptr)); ptr += strlen(ptr); } } @@ -86,24 +71,13 @@ static int FAST_FUNC parse_module(const char *fname, struct stat *sb UNUSED_PARA return TRUE; } -static module_info *find_module(module_info *modules, const char *modname) +static void order_dep_list(module_db *modules, module_entry *start, llist_t *add) { - module_info *m; - - for (m = modules; m != NULL; m = m->next) - if (strcmp(m->modname, modname) == 0) - return m; - return NULL; -} - -static void order_dep_list(module_info *modules, module_info *start, - llist_t *add) -{ - module_info *m; + module_entry *m; llist_t *n; for (n = add; n != NULL; n = n->link) { - m = find_module(modules, n->data); + m = moddb_get(modules, n->data); if (m == NULL) continue; @@ -118,7 +92,7 @@ static void order_dep_list(module_info *modules, module_info *start, start->dprev = m; /* recurse */ - order_dep_list(modules, start, m->dependencies); + order_dep_list(modules, start, m->deps); } } @@ -184,10 +158,12 @@ enum { int depmod_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; int depmod_main(int argc UNUSED_PARAM, char **argv) { - module_info *modules, *m, *dep; + module_db modules; + module_entry *m, *dep; const char *moddir_base = "/"; char *moddir, *version; struct utsname uts; + unsigned i; int tmp; getopt32(argv, "aAb:eF:nruqC:", &moddir_base, NULL, NULL); @@ -211,7 +187,7 @@ int depmod_main(int argc UNUSED_PARAM, char **argv) free(moddir); /* Scan modules */ - modules = NULL; + memset(&modules, 0, sizeof(modules)); if (*argv) { do { parse_module(*argv, /*sb (unused):*/ NULL, &modules, 0); @@ -224,10 +200,11 @@ int depmod_main(int argc UNUSED_PARAM, char **argv) /* Generate dependency and alias files */ if (!(option_mask32 & OPT_n)) xfreopen_write(CONFIG_DEFAULT_DEPMOD_FILE, stdout); - for (m = modules; m != NULL; m = m->next) { + + moddb_foreach_module(&modules, m, i) { printf("%s:", m->name); - order_dep_list(modules, m, m->dependencies); + order_dep_list(&modules, m, m->deps); while (m->dnext != m) { dep = m->dnext; printf(" %s", dep->name); @@ -243,10 +220,7 @@ int depmod_main(int argc UNUSED_PARAM, char **argv) #if ENABLE_FEATURE_MODUTILS_ALIAS if (!(option_mask32 & OPT_n)) xfreopen_write("modules.alias", stdout); - for (m = modules; m != NULL; m = m->next) { - char modname[MODULE_NAME_LEN]; - const char *fname = bb_basename(m->name); - filename2modname(fname, modname); + moddb_foreach_module(&modules, m, i) { while (m->aliases) { /* * Last word used to be a basename @@ -256,34 +230,24 @@ int depmod_main(int argc UNUSED_PARAM, char **argv) */ printf("alias %s %s\n", (char*)llist_pop(&m->aliases), - modname); + m->modname); } } #endif #if ENABLE_FEATURE_MODUTILS_SYMBOLS if (!(option_mask32 & OPT_n)) xfreopen_write("modules.symbols", stdout); - for (m = modules; m != NULL; m = m->next) { - char modname[MODULE_NAME_LEN]; - const char *fname = bb_basename(m->name); - filename2modname(fname, modname); + moddb_foreach_module(&modules, m, i) { while (m->symbols) { printf("alias symbol:%s %s\n", (char*)llist_pop(&m->symbols), - modname); + m->modname); } } #endif - if (ENABLE_FEATURE_CLEAN_UP) { - while (modules) { - module_info *old = modules; - modules = modules->next; - free(old->name); - free(old->modname); - free(old); - } - } + if (ENABLE_FEATURE_CLEAN_UP) + moddb_free(&modules); return EXIT_SUCCESS; } diff --git a/modutils/modprobe.c b/modutils/modprobe.c index 05bf02cf8..ec490b74d 100644 --- a/modutils/modprobe.c +++ b/modutils/modprobe.c @@ -150,19 +150,6 @@ static const char modprobe_longopts[] ALIGN1 = #define MODULE_FLAG_FOUND_IN_MODDEP 0x0004 #define MODULE_FLAG_BLACKLISTED 0x0008 -struct module_entry { /* I'll call it ME. */ - unsigned flags; - char *modname; /* stripped of /path/, .ext and s/-/_/g */ - const char *probed_name; /* verbatim as seen on cmdline */ - char *options; /* options from config files */ - llist_t *realnames; /* strings. if this module is an alias, */ - /* real module name is one of these. */ -//Can there really be more than one? Example from real kernel? - llist_t *deps; /* strings. modules we depend on */ -}; - -#define DB_HASH_SIZE 256 - struct globals { llist_t *probes; /* MEs of module(s) requested on cmdline */ char *cmdline_mopts; /* module options from cmdline */ @@ -170,7 +157,7 @@ struct globals { /* bool. "Did we have 'symbol:FOO' requested on cmdline?" */ smallint need_symbols; struct utsname uts; - llist_t *db[DB_HASH_SIZE]; /* MEs of all modules ever seen (caching for speed) */ + module_db db; } FIX_ALIASING; #define G (*ptr_to_globals) #define INIT_G() do { \ @@ -195,51 +182,9 @@ static char *gather_options_str(char *opts, const char *append) return opts; } -/* These three functions called many times, optimizing for speed. - * Users reported minute-long delays when they runn iptables repeatedly - * (iptables use modprobe to install needed kernel modules). - */ -static struct module_entry *helper_get_module(const char *module, int create) +static struct module_entry *get_or_add_modentry(const char *module) { - char modname[MODULE_NAME_LEN]; - struct module_entry *e; - llist_t *l; - unsigned i; - unsigned hash; - - filename2modname(module, modname); - - hash = 0; - for (i = 0; modname[i]; i++) - hash = ((hash << 5) + hash) + modname[i]; - hash %= DB_HASH_SIZE; - - for (l = G.db[hash]; l; l = l->link) { - e = (struct module_entry *) l->data; - if (strcmp(e->modname, modname) == 0) - return e; - } - if (!create) - return NULL; - - e = xzalloc(sizeof(*e)); - e->modname = xstrdup(modname); - llist_add_to(&G.db[hash], e); - - return e; -} -static ALWAYS_INLINE struct module_entry *get_or_add_modentry(const char *module) -{ - return helper_get_module(module, 1); -} -/* So far this function always gets a module pathname, never an alias name. - * The crucial difference is that pathname needs dirname stripping, - * while alias name must NOT do it! - * Testcase where dirname stripping is likely to go wrong: "modprobe devname:snd/timer" - */ -static ALWAYS_INLINE struct module_entry *get_modentry(const char *pathname) -{ - return helper_get_module(bb_get_last_path_component_nostrip(pathname), 0); + return moddb_get_or_create(&G.db, module); } static void add_probe(const char *name) @@ -536,7 +481,7 @@ static void load_modules_dep(void) continue; *colon = '\0'; - m = get_modentry(tokens[0]); + m = moddb_get(&G.db, bb_get_last_path_component_nostrip(tokens[0])); if (m == NULL) continue; @@ -697,5 +642,8 @@ int modprobe_main(int argc UNUSED_PARAM, char **argv) } while (me->realnames != NULL); } + if (ENABLE_FEATURE_CLEAN_UP) + moddb_free(&G.db); + return (rc != 0); } diff --git a/modutils/modutils.c b/modutils/modutils.c index ef4134af5..8e9eef72d 100644 --- a/modutils/modutils.c +++ b/modutils/modutils.c @@ -16,6 +16,57 @@ extern int delete_module(const char *module, unsigned int flags); # define delete_module(mod, flags) syscall(__NR_delete_module, mod, flags) #endif +static module_entry *helper_get_module(module_db *db, const char *module, int create) +{ + char modname[MODULE_NAME_LEN]; + struct module_entry *e; + unsigned i, hash; + + filename2modname(module, modname); + + hash = 0; + for (i = 0; modname[i]; i++) + hash = ((hash << 5) + hash) + modname[i]; + hash %= MODULE_HASH_SIZE; + + for (e = db->buckets[hash]; e; e = e->next) + if (strcmp(e->modname, modname) == 0) + return e; + if (!create) + return NULL; + + e = xzalloc(sizeof(*e)); + e->modname = xstrdup(modname); + e->next = db->buckets[hash]; + db->buckets[hash] = e; + e->dnext = e->dprev = e; + + return e; +} +module_entry* FAST_FUNC moddb_get(module_db *db, const char *module) +{ + return helper_get_module(db, module, 0); +} +module_entry* FAST_FUNC moddb_get_or_create(module_db *db, const char *module) +{ + return helper_get_module(db, module, 1); +} + +void FAST_FUNC moddb_free(module_db *db) +{ + module_entry *e, *n; + unsigned i; + + for (i = 0; i < MODULE_HASH_SIZE; i++) { + for (e = db->buckets[i]; e; e = n) { + n = e->next; + free(e->name); + free(e->modname); + free(e); + } + } +} + void FAST_FUNC replace(char *s, char what, char with) { while (*s) { diff --git a/modutils/modutils.h b/modutils/modutils.h index 5f059c716..2cbd1448a 100644 --- a/modutils/modutils.h +++ b/modutils/modutils.h @@ -16,6 +16,36 @@ PUSH_AND_SET_FUNCTION_VISIBILITY_TO_HIDDEN /* linux/include/linux/module.h has 64, but this is also used * internally for the maximum alias name length, which can be quite long */ #define MODULE_NAME_LEN 256 +#define MODULE_HASH_SIZE 256 + +typedef struct module_entry { + struct module_entry *next; + char *name, *modname; + llist_t *deps; + IF_MODPROBE( + llist_t *realnames; + unsigned flags; + const char *probed_name; /* verbatim as seen on cmdline */ + char *options; /* options from config files */ + ) + IF_DEPMOD( + llist_t *aliases; + llist_t *symbols; + struct module_entry *dnext, *dprev; + ) +} module_entry; + +typedef struct module_db { + module_entry *buckets[MODULE_HASH_SIZE]; +} module_db; + +#define moddb_foreach_module(db, module, index) \ + for ((index) = 0; (index) < MODULE_HASH_SIZE; (index)++) \ + for (module = (db)->buckets[index]; module; module = module->next) + +module_entry *moddb_get(module_db *db, const char *s) FAST_FUNC; +module_entry *moddb_get_or_create(module_db *db, const char *s) FAST_FUNC; +void moddb_free(module_db *db) FAST_FUNC; void replace(char *s, char what, char with) FAST_FUNC; char *replace_underscores(char *s) FAST_FUNC; From 196e400441652946b9c7ad7bc2d78c73885f2359 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Fri, 6 Nov 2015 15:50:28 +0100 Subject: [PATCH 106/260] modutils: fix build error with !DEPMOD Signed-off-by: Denys Vlasenko --- modutils/modutils.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modutils/modutils.c b/modutils/modutils.c index 8e9eef72d..0a056731d 100644 --- a/modutils/modutils.c +++ b/modutils/modutils.c @@ -39,7 +39,7 @@ static module_entry *helper_get_module(module_db *db, const char *module, int cr e->modname = xstrdup(modname); e->next = db->buckets[hash]; db->buckets[hash] = e; - e->dnext = e->dprev = e; + IF_DEPMOD(e->dnext = e->dprev = e;) return e; } From 77e2bde6a50f0f6b9b3c9983c86e661a9872b5f6 Mon Sep 17 00:00:00 2001 From: Mike Frysinger Date: Tue, 1 Dec 2015 11:25:10 -0500 Subject: [PATCH 107/260] trylink: include LDFLAGS when checking linkage The user might be including options in their LDFLAGS (like -fuse-ld=gold) that change the behavior of the linker and thus change the results of the flag tests. Make sure we include the user's LDFLAGS when running these tests so we filter out flags that will fail when used later on. URL: https://bugs.gentoo.org/499712 Signed-off-by: Mike Frysinger --- scripts/trylink | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/trylink b/scripts/trylink index 6e1187ed0..3c431edc3 100755 --- a/scripts/trylink +++ b/scripts/trylink @@ -54,7 +54,7 @@ check_cc() { # "eval" may be needed if CFLAGS can contain # '... -D"BB_VER=KBUILD_STR(1.N.M)" ...' # and we need shell to process quotes! - $CC $CFLAGS $1 "$tempname".c -o "$tempname" >/dev/null 2>&1 + $CC $CFLAGS $LDFLAGS $1 "$tempname".c -o "$tempname" >/dev/null 2>&1 r=$? rm -f "$tempname" "$tempname".c "$tempname".o return $r From 5f11ec3f6a7e4fe6cc2626ccb7cda4ecb5c3938a Mon Sep 17 00:00:00 2001 From: Mike Frysinger Date: Wed, 16 Dec 2015 12:59:08 -0500 Subject: [PATCH 108/260] swapon/swapoff: refine the -e (ifexists) option The -e option should only apply to swapon, and it should swallow all errors/warnings when the device does not exist. So delete the flag from the swapoff patch and unify the check in the swapoff path. Signed-off-by: Mike Frysinger --- util-linux/swaponoff.c | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/util-linux/swaponoff.c b/util-linux/swaponoff.c index 5cd1fbe70..7e548a464 100644 --- a/util-linux/swaponoff.c +++ b/util-linux/swaponoff.c @@ -22,11 +22,10 @@ //usage: ) //usage: //usage:#define swapoff_trivial_usage -//usage: "[-a] [-e] [DEVICE]" +//usage: "[-a] [DEVICE]" //usage:#define swapoff_full_usage "\n\n" //usage: "Stop swapping on DEVICE\n" //usage: "\n -a Stop swapping on all swap devices" -//usage: "\n -e Silently skip devices that do not exist" #include "libbb.h" #include @@ -93,15 +92,12 @@ enum { #define OPT_IFEXISTS (option_mask32 & OPT_e) #define OPT_PRIO (option_mask32 & OPT_p) -static int swap_enable_disable(char *device) +static int swap_enable_disable(const char *device) { int err = 0; int quiet = 0; - struct stat st; resolve_mount_spec(&device); - if (!OPT_IFEXISTS) - xstat(device, &st); if (do_swapoff) { err = swapoff(device); @@ -109,6 +105,7 @@ static int swap_enable_disable(char *device) quiet = (OPT_ALL && (errno == EINVAL || errno == ENOENT)); } else { /* swapon */ + struct stat st; err = stat(device, &st); if (!err) { if (ENABLE_DESKTOP && S_ISREG(st.st_mode)) { @@ -119,9 +116,11 @@ static int swap_enable_disable(char *device) } err = swapon(device, g_flags); /* Don't complain on swapon -a if device is already in use */ - /* Don't complain if file does not exist with -e option */ - quiet = (OPT_ALL && errno == EBUSY) || (OPT_IFEXISTS && errno == ENOENT); + quiet = (OPT_ALL && errno == EBUSY); } + /* Don't complain if file does not exist with -e option */ + if (err && OPT_IFEXISTS && errno == ENOENT) + err = 0; } if (err && !quiet) { From e0942acb9e186cbfc16afe704e10a8af9cd1cc58 Mon Sep 17 00:00:00 2001 From: Mike Frysinger Date: Wed, 16 Dec 2015 14:42:25 -0500 Subject: [PATCH 109/260] blkid: add bcache support URL: https://bugs.gentoo.org/508596 Signed-off-by: Mike Frysinger --- util-linux/volume_id/bcache.c | 110 ++++++++++++++++++++++ util-linux/volume_id/volume_id.c | 3 + util-linux/volume_id/volume_id_internal.h | 2 + 3 files changed, 115 insertions(+) create mode 100644 util-linux/volume_id/bcache.c diff --git a/util-linux/volume_id/bcache.c b/util-linux/volume_id/bcache.c new file mode 100644 index 000000000..648e44de5 --- /dev/null +++ b/util-linux/volume_id/bcache.c @@ -0,0 +1,110 @@ +/* + * Copyright (C) 2013 Rolf Fokkens + * + * This file may be redistributed under the terms of the + * GNU Lesser General Public License. + * + * Based on code fragments from bcache-tools by Kent Overstreet: + * http://evilpiepirate.org/git/bcache-tools.git + */ + +//kbuild:lib-$(CONFIG_FEATURE_VOLUMEID_BCACHE) += bcache.o + +//config: +//config:config FEATURE_VOLUMEID_BCACHE +//config: bool "bcache filesystem" +//config: default y +//config: depends on VOLUMEID +//config: help +//config: TODO +//config: + +#include "volume_id_internal.h" + +#define SB_LABEL_SIZE 32 +#define SB_JOURNAL_BUCKETS 256U + +static const char bcache_magic[] = { + 0xc6, 0x85, 0x73, 0xf6, 0x4e, 0x1a, 0x45, 0xca, + 0x82, 0x65, 0xf5, 0x7f, 0x48, 0xba, 0x6d, 0x81 +}; + +struct bcache_super_block { + uint64_t csum; + uint64_t offset; /* sector where this sb was written */ + uint64_t version; + + uint8_t magic[16]; + + uint8_t uuid[16]; + union { + uint8_t set_uuid[16]; + uint64_t set_magic; + }; + uint8_t label[SB_LABEL_SIZE]; + + uint64_t flags; + uint64_t seq; + uint64_t pad[8]; + + union { + struct { + /* Cache devices */ + uint64_t nbuckets; /* device size */ + + uint16_t block_size; /* sectors */ + uint16_t bucket_size; /* sectors */ + + uint16_t nr_in_set; + uint16_t nr_this_dev; + }; + struct { + /* Backing devices */ + uint64_t data_offset; + + /* + * block_size from the cache device section is still used by + * backing devices, so don't add anything here until we fix + * things to not need it for backing devices anymore + */ + }; + }; + + uint32_t last_mount; /* time_t */ + + uint16_t first_bucket; + union { + uint16_t njournal_buckets; + uint16_t keys; + }; + uint64_t d[SB_JOURNAL_BUCKETS]; /* journal buckets */ +}; + +/* magic string */ +#define BCACHE_SB_MAGIC bcache_magic +/* magic string len */ +#define BCACHE_SB_MAGIC_LEN sizeof (bcache_magic) +/* super block offset */ +#define BCACHE_SB_OFF 0x1000 +/* supper block offset in kB */ +#define BCACHE_SB_KBOFF (BCACHE_SB_OFF >> 10) +/* magic string offset within super block */ +#define BCACHE_SB_MAGIC_OFF offsetof (struct bcache_super_block, magic) + +int FAST_FUNC volume_id_probe_bcache(struct volume_id *id /*,uint64_t off*/) +{ + struct bcache_super_block *sb; + + sb = volume_id_get_buffer(id, BCACHE_SB_OFF, sizeof(*sb)); + if (sb == NULL) + return -1; + + if (memcmp(sb->magic, BCACHE_SB_MAGIC, BCACHE_SB_MAGIC_LEN) != 0) + return -1; + + volume_id_set_label_string(id, sb->label, SB_LABEL_SIZE); + volume_id_set_uuid(id, sb->uuid, UUID_DCE); + IF_FEATURE_BLKID_TYPE(id->type = "bcache";) + + return 0; +} diff --git a/util-linux/volume_id/volume_id.c b/util-linux/volume_id/volume_id.c index 5c459a0e2..3f71e0084 100644 --- a/util-linux/volume_id/volume_id.c +++ b/util-linux/volume_id/volume_id.c @@ -107,6 +107,9 @@ static const probe_fptr fs1[] = { #if ENABLE_FEATURE_VOLUMEID_XFS volume_id_probe_xfs, #endif +#if ENABLE_FEATURE_VOLUMEID_BCACHE + volume_id_probe_bcache, +#endif }; /* fill buffer with maximum */ diff --git a/util-linux/volume_id/volume_id_internal.h b/util-linux/volume_id/volume_id_internal.h index 6e2dbd7bb..3061ac4d5 100644 --- a/util-linux/volume_id/volume_id_internal.h +++ b/util-linux/volume_id/volume_id_internal.h @@ -169,6 +169,8 @@ int FAST_FUNC volume_id_probe_linux_raid(struct volume_id *id /*,uint64_t off*/, /* FS */ +int FAST_FUNC volume_id_probe_bcache(struct volume_id *id /*,uint64_t off*/); + int FAST_FUNC volume_id_probe_btrfs(struct volume_id *id /*,uint64_t off*/); int FAST_FUNC volume_id_probe_cramfs(struct volume_id *id /*,uint64_t off*/); From 6df961257d584714c5690b1f4197c677e4f832ec Mon Sep 17 00:00:00 2001 From: Chris Renshaw Date: Thu, 17 Dec 2015 16:42:01 +0100 Subject: [PATCH 110/260] Resolve linker issues with Android API 21 (dprintf, tcdrain) Signed-off-by: Chris Renshaw Signed-off-by: Denys Vlasenko --- include/platform.h | 7 ++++++- libbb/missing_syscalls.c | 2 ++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/include/platform.h b/include/platform.h index 1706b1847..026ebbe17 100644 --- a/include/platform.h +++ b/include/platform.h @@ -481,9 +481,14 @@ typedef unsigned smalluint; #if defined(ANDROID) || defined(__ANDROID__) # if __ANDROID_API__ < 8 + /* ANDROID < 8 has no [f]dprintf at all */ # undef HAVE_DPRINTF -# else +# elif __ANDROID_API__ < 21 + /* ANDROID < 21 has fdprintf */ # define dprintf fdprintf +# else + /* ANDROID >= 21 has standard dprintf */ +# endif # endif # if __ANDROID_API__ < 21 # undef HAVE_TTYNAME_R diff --git a/libbb/missing_syscalls.c b/libbb/missing_syscalls.c index e3c1e924b..093412811 100644 --- a/libbb/missing_syscalls.c +++ b/libbb/missing_syscalls.c @@ -40,8 +40,10 @@ int pivot_root(const char *new_root, const char *put_old) return syscall(__NR_pivot_root, new_root, put_old); } +# if __ANDROID_API__ < 21 int tcdrain(int fd) { return ioctl(fd, TCSBRK, 1); } +# endif #endif From b50525124228b566ccfd5c6df0647988bb2d2d3a Mon Sep 17 00:00:00 2001 From: Ari Sundholm Date: Thu, 17 Dec 2015 20:43:12 +0200 Subject: [PATCH 111/260] include/platform.h: Remove extra #endif introduced in 6df9612. It causes the compilation to fail. Signed-off-by: Ari Sundholm Signed-off-by: Mike Frysinger --- include/platform.h | 1 - 1 file changed, 1 deletion(-) diff --git a/include/platform.h b/include/platform.h index 026ebbe17..c987d418c 100644 --- a/include/platform.h +++ b/include/platform.h @@ -489,7 +489,6 @@ typedef unsigned smalluint; # else /* ANDROID >= 21 has standard dprintf */ # endif -# endif # if __ANDROID_API__ < 21 # undef HAVE_TTYNAME_R # undef HAVE_GETLINE From 2c0d3f5fd08ccc6963c402030efcbe8a2c028f2d Mon Sep 17 00:00:00 2001 From: Pascal Bach Date: Fri, 18 Dec 2015 19:01:14 +0100 Subject: [PATCH 112/260] chpasswd: support -c argument and respect DEFAULT_PASSWD_ALGO Signed-off-by: Pascal Bach Signed-off-by: Denys Vlasenko --- libbb/pw_encrypt.c | 10 +++++++--- loginutils/chpasswd.c | 31 ++++++++++++++++--------------- 2 files changed, 23 insertions(+), 18 deletions(-) diff --git a/libbb/pw_encrypt.c b/libbb/pw_encrypt.c index bfc7030a8..dbc15e5fc 100644 --- a/libbb/pw_encrypt.c +++ b/libbb/pw_encrypt.c @@ -52,14 +52,18 @@ char* FAST_FUNC crypt_make_pw_salt(char salt[MAX_PW_SALT_LEN], const char *algo) { int len = 2/2; char *salt_ptr = salt; - if (algo[0] != 'd') { /* not des */ + + /* Standard chpasswd uses uppercase algos ("MD5", not "md5"). + * Need to be case-insensitive in the code below. + */ + if ((algo[0]|0x20) != 'd') { /* not des */ len = 8/2; /* so far assuming md5 */ *salt_ptr++ = '$'; *salt_ptr++ = '1'; *salt_ptr++ = '$'; #if !ENABLE_USE_BB_CRYPT || ENABLE_USE_BB_CRYPT_SHA - if (algo[0] == 's') { /* sha */ - salt[1] = '5' + (strcmp(algo, "sha512") == 0); + if ((algo[0]|0x20) == 's') { /* sha */ + salt[1] = '5' + (strcasecmp(algo, "sha512") == 0); len = 16/2; } #endif diff --git a/loginutils/chpasswd.c b/loginutils/chpasswd.c index 6c41d17be..a022a42d6 100644 --- a/loginutils/chpasswd.c +++ b/loginutils/chpasswd.c @@ -24,26 +24,27 @@ //kbuild:lib-$(CONFIG_CHPASSWD) += chpasswd.o //usage:#define chpasswd_trivial_usage -//usage: IF_LONG_OPTS("[--md5|--encrypted]") IF_NOT_LONG_OPTS("[-m|-e]") +//usage: IF_LONG_OPTS("[--md5|--encrypted|--crypt-method]") IF_NOT_LONG_OPTS("[-m|-e|-c]") //usage:#define chpasswd_full_usage "\n\n" //usage: "Read user:password from stdin and update /etc/passwd\n" //usage: IF_LONG_OPTS( -//usage: "\n -e,--encrypted Supplied passwords are in encrypted form" -//usage: "\n -m,--md5 Use MD5 encryption instead of DES" +//usage: "\n -e,--encrypted Supplied passwords are in encrypted form" +//usage: "\n -m,--md5 Use MD5 encryption instead of DES" +//usage: "\n -c,--crypt-method Use the specified method to encrypt the passwords" //usage: ) //usage: IF_NOT_LONG_OPTS( //usage: "\n -e Supplied passwords are in encrypted form" //usage: "\n -m Use MD5 encryption instead of DES" +//usage: "\n -c Use the specified method to encrypt the passwords" //usage: ) -//TODO: implement -c ALGO - #include "libbb.h" #if ENABLE_LONG_OPTS static const char chpasswd_longopts[] ALIGN1 = - "encrypted\0" No_argument "e" - "md5\0" No_argument "m" + "encrypted\0" No_argument "e" + "md5\0" No_argument "m" + "crypt-method\0" Required_argument "c" ; #endif @@ -54,14 +55,15 @@ int chpasswd_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; int chpasswd_main(int argc UNUSED_PARAM, char **argv) { char *name; + const char *algo = CONFIG_FEATURE_DEFAULT_PASSWD_ALGO; int opt; if (getuid() != 0) bb_error_msg_and_die(bb_msg_perm_denied_are_you_root); - opt_complementary = "m--e:e--m"; + opt_complementary = "m--ec:e--mc:c--em"; IF_LONG_OPTS(applet_long_options = chpasswd_longopts;) - opt = getopt32(argv, "em"); + opt = getopt32(argv, "emc:", &algo); while ((name = xmalloc_fgetline(stdin)) != NULL) { char *free_me; @@ -77,15 +79,14 @@ int chpasswd_main(int argc UNUSED_PARAM, char **argv) free_me = NULL; if (!(opt & OPT_ENC)) { - char salt[sizeof("$N$XXXXXXXX")]; + char salt[MAX_PW_SALT_LEN]; - crypt_make_salt(salt, 1); if (opt & OPT_MD5) { - salt[0] = '$'; - salt[1] = '1'; - salt[2] = '$'; - crypt_make_salt(salt + 3, 4); + /* Force MD5 if the -m flag is set */ + algo = "md5"; } + + crypt_make_pw_salt(salt, algo); free_me = pass = pw_encrypt(pass, salt, 0); } From 6c634f7968032ab2b8b7daf528990ac15809f7eb Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Fri, 18 Dec 2015 19:02:31 +0100 Subject: [PATCH 113/260] swaponoff: fix compile-time warning CC util-linux/swaponoff.o cc1: warnings being treated as errors util-linux/swaponoff.c: In function 'swap_enable_disable': util-linux/swaponoff.c:100: warning: passing argument 1 of 'resolve_mount_spec' from incompatible pointer type make[1]: *** [util-linux/swaponoff.o] Error 1 Signed-off-by: Denys Vlasenko --- util-linux/swaponoff.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/util-linux/swaponoff.c b/util-linux/swaponoff.c index 7e548a464..c29dd3071 100644 --- a/util-linux/swaponoff.c +++ b/util-linux/swaponoff.c @@ -92,7 +92,7 @@ enum { #define OPT_IFEXISTS (option_mask32 & OPT_e) #define OPT_PRIO (option_mask32 & OPT_p) -static int swap_enable_disable(const char *device) +static int swap_enable_disable(char *device) { int err = 0; int quiet = 0; From ce4bc1ed048233e89ee4cb95830bf6f01d523d1e Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Wed, 30 Dec 2015 17:32:51 +0100 Subject: [PATCH 114/260] iproute: support "scope". Closes 8561 function old new delta iproute_modify 1051 1120 +69 Signed-off-by: Denys Vlasenko --- networking/libiproute/iproute.c | 52 +++++++++++++++++++++------------ 1 file changed, 33 insertions(+), 19 deletions(-) diff --git a/networking/libiproute/iproute.c b/networking/libiproute/iproute.c index d232ee6fd..82827488f 100644 --- a/networking/libiproute/iproute.c +++ b/networking/libiproute/iproute.c @@ -313,12 +313,13 @@ static int FAST_FUNC print_route(const struct sockaddr_nl *who UNUSED_PARAM, static int iproute_modify(int cmd, unsigned flags, char **argv) { static const char keywords[] ALIGN1 = - "src\0""via\0""mtu\0""lock\0""protocol\0"IF_FEATURE_IP_RULE("table\0") + "src\0""via\0""mtu\0""lock\0""scope\0""protocol\0"IF_FEATURE_IP_RULE("table\0") "dev\0""oif\0""to\0""metric\0""onlink\0"; enum { ARG_src, ARG_via, ARG_mtu, PARM_lock, + ARG_scope, ARG_protocol, IF_FEATURE_IP_RULE(ARG_table,) ARG_dev, @@ -344,6 +345,7 @@ IF_FEATURE_IP_RULE(ARG_table,) unsigned mxlock = 0; char *d = NULL; smalluint ok = 0; + smalluint scope_ok = 0; int arg; memset(&req, 0, sizeof(req)); @@ -352,15 +354,18 @@ IF_FEATURE_IP_RULE(ARG_table,) req.n.nlmsg_flags = NLM_F_REQUEST | flags; req.n.nlmsg_type = cmd; req.r.rtm_family = preferred_family; - if (RT_TABLE_MAIN) /* if it is zero, memset already did it */ + if (RT_TABLE_MAIN != 0) /* if it is zero, memset already did it */ req.r.rtm_table = RT_TABLE_MAIN; - if (RT_SCOPE_NOWHERE) + if (RT_SCOPE_NOWHERE != 0) req.r.rtm_scope = RT_SCOPE_NOWHERE; if (cmd != RTM_DELROUTE) { - req.r.rtm_protocol = RTPROT_BOOT; - req.r.rtm_scope = RT_SCOPE_UNIVERSE; - req.r.rtm_type = RTN_UNICAST; + if (RTPROT_BOOT != 0) + req.r.rtm_protocol = RTPROT_BOOT; + if (RT_SCOPE_UNIVERSE != 0) + req.r.rtm_scope = RT_SCOPE_UNIVERSE; + if (RTN_UNICAST != 0) + req.r.rtm_type = RTN_UNICAST; } mxrta->rta_type = RTA_METRICS; @@ -393,6 +398,13 @@ IF_FEATURE_IP_RULE(ARG_table,) } mtu = get_unsigned(*argv, "mtu"); rta_addattr32(mxrta, sizeof(mxbuf), RTAX_MTU, mtu); + } else if (arg == ARG_scope) { + uint32_t scope; + NEXT_ARG(); + if (rtnl_rtscope_a2n(&scope, *argv)) + invarg_1_to_2(*argv, "scope"); + req.r.rtm_scope = scope; + scope_ok = 1; } else if (arg == ARG_protocol) { uint32_t prot; NEXT_ARG(); @@ -469,20 +481,22 @@ IF_FEATURE_IP_RULE(ARG_table,) addattr_l(&req.n, sizeof(req), RTA_METRICS, RTA_DATA(mxrta), RTA_PAYLOAD(mxrta)); } - if (req.r.rtm_type == RTN_LOCAL || req.r.rtm_type == RTN_NAT) - req.r.rtm_scope = RT_SCOPE_HOST; - else - if (req.r.rtm_type == RTN_BROADCAST - || req.r.rtm_type == RTN_MULTICAST - || req.r.rtm_type == RTN_ANYCAST - ) { - req.r.rtm_scope = RT_SCOPE_LINK; - } - else if (req.r.rtm_type == RTN_UNICAST || req.r.rtm_type == RTN_UNSPEC) { - if (cmd == RTM_DELROUTE) - req.r.rtm_scope = RT_SCOPE_NOWHERE; - else if (!(ok & gw_ok)) + if (!scope_ok) { + if (req.r.rtm_type == RTN_LOCAL || req.r.rtm_type == RTN_NAT) + req.r.rtm_scope = RT_SCOPE_HOST; + else + if (req.r.rtm_type == RTN_BROADCAST + || req.r.rtm_type == RTN_MULTICAST + || req.r.rtm_type == RTN_ANYCAST + ) { req.r.rtm_scope = RT_SCOPE_LINK; + } + else if (req.r.rtm_type == RTN_UNICAST || req.r.rtm_type == RTN_UNSPEC) { + if (cmd == RTM_DELROUTE) + req.r.rtm_scope = RT_SCOPE_NOWHERE; + else if (!(ok & gw_ok)) + req.r.rtm_scope = RT_SCOPE_LINK; + } } if (req.r.rtm_family == AF_UNSPEC) { From 911d265faf34c90158f5ba0ef81d1d558ec595e6 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Wed, 30 Dec 2015 20:11:34 +0100 Subject: [PATCH 115/260] mount: support "nofail" option. Closes 8551 function old new delta singlemount 1045 1060 +15 mount_option_str 338 345 +7 mount_it_now 355 361 +6 mount_options 172 176 +4 ------------------------------------------------------------------------------ (add/remove: 0/0 grow/shrink: 4/0 up/down: 32/0) Total: 32 bytes Signed-off-by: Denys Vlasenko --- util-linux/mount.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/util-linux/mount.c b/util-linux/mount.c index cb40c802d..c428f5827 100644 --- a/util-linux/mount.c +++ b/util-linux/mount.c @@ -259,9 +259,11 @@ static struct mntent *getmntent_r(FILE* stream, struct mntent* result, // Not real flags, but we want to be able to check for this. enum { - MOUNT_USERS = (1 << 28) * ENABLE_DESKTOP, + MOUNT_USERS = (1 << 27) * ENABLE_DESKTOP, + MOUNT_NOFAIL = (1 << 28) * ENABLE_DESKTOP, MOUNT_NOAUTO = (1 << 29), MOUNT_SWAP = (1 << 30), + MOUNT_FAKEFLAGS = MOUNT_USERS | MOUNT_NOFAIL | MOUNT_NOAUTO | MOUNT_SWAP }; @@ -326,6 +328,7 @@ static const int32_t mount_options[] = { /* "swap" */ MOUNT_SWAP, IF_DESKTOP(/* "user" */ MOUNT_USERS,) IF_DESKTOP(/* "users" */ MOUNT_USERS,) + IF_DESKTOP(/* "nofail" */ MOUNT_NOFAIL,) /* "_netdev" */ 0, IF_DESKTOP(/* "comment=" */ 0,) /* systemd uses this in fstab */ ) @@ -385,6 +388,7 @@ static const char mount_option_str[] = "swap\0" IF_DESKTOP("user\0") IF_DESKTOP("users\0") + IF_DESKTOP("nofail\0") "_netdev\0" IF_DESKTOP("comment=\0") /* systemd uses this in fstab */ ) @@ -672,6 +676,8 @@ static int mount_it_now(struct mntent *mp, unsigned long vfsflags, char *filtero { int rc = 0; + vfsflags &= ~(unsigned long)MOUNT_FAKEFLAGS; + if (FAKE_IT) { if (verbose >= 2) bb_error_msg("would do mount('%s','%s','%s',0x%08lx,'%s')", @@ -2061,6 +2067,8 @@ static int singlemount(struct mntent *mp, int ignore_busy) if (errno == EBUSY && ignore_busy) return 0; + if (errno == ENOENT && (vfsflags & MOUNT_NOFAIL)) + return 0; if (rc != 0) bb_perror_msg("mounting %s on %s failed", mp->mnt_fsname, mp->mnt_dir); return rc; From c2a2625bcbd0d883ca74afb5275e6fd9806936d2 Mon Sep 17 00:00:00 2001 From: Cristian Ionescu-Idbohrn Date: Sat, 2 Jan 2016 00:52:29 +0100 Subject: [PATCH 116/260] ash: suppress a compilation warning Reported by gcc (Debian 5.3.1-4) 5.3.1 20151219 shell/ash.c: In function 'evaltree': shell/ash.c:8432:19: warning: logical not is only applied to the left hand side of comparison Signed-off-by: Cristian Ionescu-Idbohrn Signed-off-by: Denys Vlasenko --- shell/ash.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/shell/ash.c b/shell/ash.c index e7a867f52..daec975c5 100644 --- a/shell/ash.c +++ b/shell/ash.c @@ -8429,7 +8429,7 @@ evaltree(union node *n, int flags) n->nbinary.ch1, (flags | ((is_or >> 1) - 1)) & EV_TESTED ); - if (!exitstatus == is_or) + if ((!exitstatus) == is_or) break; if (!evalskip) { n = n->nbinary.ch2; From dbf5a6da6a4295ce26edd1ce34fde567d19afa02 Mon Sep 17 00:00:00 2001 From: Ari Sundholm Date: Sat, 2 Jan 2016 01:18:32 +0100 Subject: [PATCH 117/260] blkdiscard: new applet function old new delta blkdiscard_main - 264 +264 Signed-off-by: Ari Sundholm Signed-off-by: Denys Vlasenko --- util-linux/blkdiscard.c | 83 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 83 insertions(+) create mode 100644 util-linux/blkdiscard.c diff --git a/util-linux/blkdiscard.c b/util-linux/blkdiscard.c new file mode 100644 index 000000000..ace88a1f0 --- /dev/null +++ b/util-linux/blkdiscard.c @@ -0,0 +1,83 @@ +/* + * Mini blkdiscard implementation for busybox + * + * Copyright (C) 2015 by Ari Sundholm and Tuxera Inc. + * + * Licensed under GPLv2 or later, see file LICENSE in this source tree. + */ + +//config:config BLKDISCARD +//config: bool "blkdiscard" +//config: default y +//config: help +//config: blkdiscard discards sectors on a given device. + +//kbuild:lib-$(CONFIG_BLKDISCARD) += blkdiscard.o +//applet:IF_BLKDISCARD(APPLET(blkdiscard, BB_DIR_USR_BIN, BB_SUID_DROP)) + +//usage:#define blkdiscard_trivial_usage +//usage: "[-o OFS] [-l LEN] [-s] DEVICE" +//usage:#define blkdiscard_full_usage "\n\n" +//usage: "Discard sectors on DEVICE\n" +//usage: "\n -o OFS Byte offset into device" +//usage: "\n -l LEN Number of bytes to discard" +//usage: "\n -s Perform a secure discard" +//usage: +//usage:#define blkdiscard_example_usage +//usage: "$ blkdiscard -o 0 -l 1G /dev/sdb" + +#include "libbb.h" +#include + +int blkdiscard_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; +int blkdiscard_main(int argc UNUSED_PARAM, char **argv) +{ + unsigned opts; + const char *offset_str = "0"; + const char *length_str; + uint64_t offset; /* Leaving these two variables out does not */ + uint64_t length; /* shrink code size and hampers readability. */ + uint64_t range[2]; +// struct stat st; + int fd; + + enum { + OPT_OFFSET = (1 << 0), + OPT_LENGTH = (1 << 1), + OPT_SECURE = (1 << 2), + }; + + opt_complementary = "=1"; + opts = getopt32(argv, "o:l:s", &offset_str, &length_str); + argv += optind; + + fd = xopen(argv[0], O_RDWR|O_EXCL); +//Why bother, BLK[SEC]DISCARD will fail on non-blockdevs anyway? +// xfstat(fd, &st); +// if (!S_ISBLK(st.st_mode)) +// bb_error_msg_and_die("%s: not a block device", argv[0]); + + offset = xatoull_sfx(offset_str, kMG_suffixes); + + if (opts & OPT_LENGTH) + length = xatoull_sfx(length_str, kMG_suffixes); + else { + xioctl(fd, BLKGETSIZE64, &length); + length -= offset; + } + + range[0] = offset; + range[1] = length; + ioctl_or_perror_and_die(fd, + (opts & OPT_SECURE) ? BLKSECDISCARD : BLKDISCARD, + &range, + "%s: %s failed", + argv[0], + (opts & OPT_SECURE) ? "BLKSECDISCARD" : "BLKDISCARD" + ); + + if (ENABLE_FEATURE_CLEAN_UP) + close(fd); + + return EXIT_SUCCESS; +} From 76915bf738c4532c7ca57fc673b5a0ebd4b91af8 Mon Sep 17 00:00:00 2001 From: Aaro Koskinen Date: Sat, 19 Dec 2015 22:34:44 +0200 Subject: [PATCH 118/260] nandwrite: implement -n (read/write without ecc) Implement -n (read/write without ecc). Signed-off-by: Aaro Koskinen Signed-off-by: Denys Vlasenko --- miscutils/nandwrite.c | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/miscutils/nandwrite.c b/miscutils/nandwrite.c index 247fc72f4..c95cbb21e 100644 --- a/miscutils/nandwrite.c +++ b/miscutils/nandwrite.c @@ -29,16 +29,18 @@ //kbuild:lib-$(CONFIG_NANDDUMP) += nandwrite.o //usage:#define nandwrite_trivial_usage -//usage: "[-p] [-s ADDR] MTD_DEVICE [FILE]" +//usage: "[-np] [-s ADDR] MTD_DEVICE [FILE]" //usage:#define nandwrite_full_usage "\n\n" //usage: "Write to MTD_DEVICE\n" +//usage: "\n -n Write without ecc" //usage: "\n -p Pad to page size" //usage: "\n -s ADDR Start address" //usage:#define nanddump_trivial_usage -//usage: "[-o]" IF_LONG_OPTS(" [--bb=padbad|skipbad]") " [-s ADDR] [-l LEN] [-f FILE] MTD_DEVICE" +//usage: "[-no]" IF_LONG_OPTS(" [--bb=padbad|skipbad]") " [-s ADDR] [-l LEN] [-f FILE] MTD_DEVICE" //usage:#define nanddump_full_usage "\n\n" //usage: "Dump MTD_DEVICE\n" +//usage: "\n -n Read without ecc" //usage: "\n -o Dump oob data" //usage: "\n -s ADDR Start address" //usage: "\n -l LEN Length" @@ -57,10 +59,11 @@ #define OPT_p (1 << 0) /* nandwrite only */ #define OPT_o (1 << 0) /* nanddump only */ -#define OPT_s (1 << 1) -#define OPT_f (1 << 2) -#define OPT_l (1 << 3) -#define OPT_bb (1 << 4) /* must be the last one in the list */ +#define OPT_n (1 << 1) +#define OPT_s (1 << 2) +#define OPT_f (1 << 3) +#define OPT_l (1 << 4) +#define OPT_bb (1 << 5) /* must be the last one in the list */ #define BB_PADBAD (1 << 0) #define BB_SKIPBAD (1 << 1) @@ -125,10 +128,10 @@ int nandwrite_main(int argc UNUSED_PARAM, char **argv) applet_long_options = "bb\0" Required_argument "\xff"; /* no short equivalent */ #endif - opts = getopt32(argv, "os:f:l:", &opt_s, &opt_f, &opt_l, &opt_bb); + opts = getopt32(argv, "ons:f:l:", &opt_s, &opt_f, &opt_l, &opt_bb); } else { /* nandwrite */ opt_complementary = "-1:?2"; - opts = getopt32(argv, "ps:", &opt_s); + opts = getopt32(argv, "pns:", &opt_s); } argv += optind; @@ -144,6 +147,9 @@ int nandwrite_main(int argc UNUSED_PARAM, char **argv) fd = xopen(argv[0], IS_NANDWRITE ? O_RDWR : O_RDONLY); xioctl(fd, MEMGETINFO, &meminfo); + if (opts & OPT_n) + xioctl(fd, MTDFILEMODE, (void *)MTD_FILE_MODE_RAW); + mtdoffset = xstrtou(opt_s, 0); if (IS_NANDDUMP && (opts & OPT_l)) { unsigned length = xstrtou(opt_l, 0); From bae8f986336383f688f0cf913e6315d430217095 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Sun, 3 Jan 2016 22:43:40 +0100 Subject: [PATCH 119/260] login: add commented-out PAM double password avoidance from BZ 4003 Signed-off-by: Denys Vlasenko --- loginutils/login.c | 43 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) diff --git a/loginutils/login.c b/loginutils/login.c index 67fe82e86..4ebc18502 100644 --- a/loginutils/login.c +++ b/loginutils/login.c @@ -78,6 +78,49 @@ * Apparently they like to confuse people. */ # include # include + +# if 0 +/* This supposedly can be used to avoid double password prompt, + * if used instead of standard misc_conv(): + * + * "When we want to authenticate first with local method and then with tacacs for example, + * the password is asked for local method and if not good is asked a second time for tacacs. + * So if we want to authenticate a user with tacacs, and the user exists localy, the password is + * asked two times before authentication is accepted." + * + * However, code looks shaky. For example, why misc_conv() return value is ignored? + * Are msg[i] and resp[i] indexes handled correctly? + */ +static char *passwd = NULL; +static int my_conv(int num_msg, const struct pam_message **msg, + struct pam_response **resp, void *data) +{ + int i; + for (i = 0; i < num_msg; i++) { + switch (msg[i]->msg_style) { + case PAM_PROMPT_ECHO_OFF: + if (passwd == NULL) { + misc_conv(num_msg, msg, resp, data); + passwd = xstrdup(resp[i]->resp); + return PAM_SUCCESS; + } + + resp[0] = xzalloc(sizeof(struct pam_response)); + resp[0]->resp = passwd; + passwd = NULL; + resp[0]->resp_retcode = PAM_SUCCESS; + resp[1] = NULL; + return PAM_SUCCESS; + + default: + break; + } + } + + return PAM_SUCCESS; +} +# endif + static const struct pam_conv conv = { misc_conv, NULL From e111a1640494fe87fc913f94fae3bb805de0fc99 Mon Sep 17 00:00:00 2001 From: Ari Sundholm Date: Mon, 4 Jan 2016 15:40:37 +0200 Subject: [PATCH 120/260] truncate: always set mode when opening file to avoid fortify errors Busybox crashes due to no mode being given when opening: $ ./busybox truncate -s 1M foo *** invalid open64 call: O_CREAT without mode ***: ./busybox terminated ======= Backtrace: ========= /lib/x86_64-linux-gnu/libc.so.6(+0x7338f)[0x7f66d921338f] /lib/x86_64-linux-gnu/libc.so.6(__fortify_fail+0x5c)[0x7f66d92aac9c] /lib/x86_64-linux-gnu/libc.so.6(+0xeb6aa)[0x7f66d928b6aa] ./busybox[0x4899f9] ======= Memory map: ======== 00400000-004d0000 r-xp 00000000 00:1a 137559 /home/ari/busybox/busybox 006cf000-006d0000 r--p 000cf000 00:1a 137559 /home/ari/busybox/busybox 006d0000-006d1000 rw-p 000d0000 00:1a 137559 /home/ari/busybox/busybox 006d1000-006d4000 rw-p 00000000 00:00 0 014e7000-01508000 rw-p 00000000 00:00 0 [heap] 7f66d8f8a000-7f66d8fa0000 r-xp 00000000 08:07 1579008 /lib/x86_64-linux-gnu/libgcc_s.so.1 7f66d8fa0000-7f66d919f000 ---p 00016000 08:07 1579008 /lib/x86_64-linux-gnu/libgcc_s.so.1 7f66d919f000-7f66d91a0000 rw-p 00015000 08:07 1579008 /lib/x86_64-linux-gnu/libgcc_s.so.1 7f66d91a0000-7f66d935b000 r-xp 00000000 08:07 1578994 /lib/x86_64-linux-gnu/libc-2.19.so 7f66d935b000-7f66d955a000 ---p 001bb000 08:07 1578994 /lib/x86_64-linux-gnu/libc-2.19.so 7f66d955a000-7f66d955e000 r--p 001ba000 08:07 1578994 /lib/x86_64-linux-gnu/libc-2.19.so 7f66d955e000-7f66d9560000 rw-p 001be000 08:07 1578994 /lib/x86_64-linux-gnu/libc-2.19.so 7f66d9560000-7f66d9565000 rw-p 00000000 00:00 0 7f66d9565000-7f66d966a000 r-xp 00000000 08:07 1579020 /lib/x86_64-linux-gnu/libm-2.19.so 7f66d966a000-7f66d9869000 ---p 00105000 08:07 1579020 /lib/x86_64-linux-gnu/libm-2.19.so 7f66d9869000-7f66d986a000 r--p 00104000 08:07 1579020 /lib/x86_64-linux-gnu/libm-2.19.so 7f66d986a000-7f66d986b000 rw-p 00105000 08:07 1579020 /lib/x86_64-linux-gnu/libm-2.19.so 7f66d986b000-7f66d988e000 r-xp 00000000 08:07 1578981 /lib/x86_64-linux-gnu/ld-2.19.so 7f66d9a64000-7f66d9a67000 rw-p 00000000 00:00 0 7f66d9a8a000-7f66d9a8d000 rw-p 00000000 00:00 0 7f66d9a8d000-7f66d9a8e000 r--p 00022000 08:07 1578981 /lib/x86_64-linux-gnu/ld-2.19.so 7f66d9a8e000-7f66d9a8f000 rw-p 00023000 08:07 1578981 /lib/x86_64-linux-gnu/ld-2.19.so 7f66d9a8f000-7f66d9a90000 rw-p 00000000 00:00 0 7ffc47761000-7ffc47782000 rw-p 00000000 00:00 0 [stack] 7ffc477ab000-7ffc477ad000 r-xp 00000000 00:00 0 [vdso] ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0 [vsyscall] Aborted (core dumped) $ Fix this by simply always setting the mode, as it doesn't hurt even when O_CREAT is not specified. This bug is a regression introduced in fc3e40e, as xopen(), which was originally used, would automatically set the mode. Signed-off-by: Ari Sundholm Signed-off-by: Mike Frysinger --- coreutils/truncate.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/coreutils/truncate.c b/coreutils/truncate.c index e5fa656c8..4c997bf7a 100644 --- a/coreutils/truncate.c +++ b/coreutils/truncate.c @@ -64,7 +64,7 @@ int truncate_main(int argc UNUSED_PARAM, char **argv) argv += optind; while (*argv) { - int fd = open(*argv, flags); + int fd = open(*argv, flags, 0666); if (fd < 0) { if (errno != ENOENT || !(opts & OPT_NOCREATE)) { bb_perror_msg("%s: open", *argv); From 6a70db85cfc2aba89fc23edf426a47630f497eb8 Mon Sep 17 00:00:00 2001 From: Mike Frysinger Date: Wed, 13 Jan 2016 13:30:20 -0500 Subject: [PATCH 121/260] truncate: use O_WRONLY|O_NONBLOCK This matches coreutils behavior. We don't read the fd, and truncation does not need blocking. Signed-off-by: Mike Frysinger --- coreutils/truncate.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/coreutils/truncate.c b/coreutils/truncate.c index 4c997bf7a..8d845f218 100644 --- a/coreutils/truncate.c +++ b/coreutils/truncate.c @@ -40,7 +40,7 @@ int truncate_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; int truncate_main(int argc UNUSED_PARAM, char **argv) { unsigned opts; - int flags = O_RDWR; + int flags = O_WRONLY | O_NONBLOCK; int ret = EXIT_SUCCESS; char *size_str; off_t size; From ccf7f0e4d3aed3bd9f46a239d9033cd773e67ab8 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Sun, 17 Jan 2016 01:09:36 +0100 Subject: [PATCH 122/260] setsid: implement -c function old new delta setsid_main 53 96 +43 packed_usage 30846 30833 -13 Signed-off-by: Denys Vlasenko --- miscutils/setsid.c | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/miscutils/setsid.c b/miscutils/setsid.c index 637081b6c..1b27377b2 100644 --- a/miscutils/setsid.c +++ b/miscutils/setsid.c @@ -15,19 +15,22 @@ */ //usage:#define setsid_trivial_usage -//usage: "PROG ARGS" +//usage: "[-c] PROG ARGS" //usage:#define setsid_full_usage "\n\n" //usage: "Run PROG in a new session. PROG will have no controlling terminal\n" -//usage: "and will not be affected by keyboard signals (Ctrl-C etc).\n" -//usage: "See setsid(2) for details." +//usage: "and will not be affected by keyboard signals (^C etc).\n" +//usage: "\n -c Set controlling terminal to stdin" #include "libbb.h" int setsid_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; int setsid_main(int argc UNUSED_PARAM, char **argv) { - if (!argv[1]) - bb_show_usage(); + unsigned opt; + + opt_complementary = "-1"; /* at least one arg */ + opt = getopt32(argv, "c"); + argv += optind; /* setsid() is allowed only when we are not a process group leader. * Otherwise our PID serves as PGID of some existing process group @@ -61,6 +64,10 @@ int setsid_main(int argc UNUSED_PARAM, char **argv) setsid(); } - argv++; + if (opt) { + /* -c: set (with stealing) controlling tty */ + ioctl(0, TIOCSCTTY, 1); + } + BB_EXECVP_or_die(argv); } From c7e47cf6273830a59f5d3f822e4a6855a80312c6 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Sun, 17 Jan 2016 03:50:36 +0100 Subject: [PATCH 123/260] dos2unix: try to preserve ownership. closes 8311 function old new delta dos2unix_main 426 441 +15 Signed-off-by: Denys Vlasenko --- coreutils/dos2unix.c | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/coreutils/dos2unix.c b/coreutils/dos2unix.c index 07398bdfa..ccb74a113 100644 --- a/coreutils/dos2unix.c +++ b/coreutils/dos2unix.c @@ -41,7 +41,7 @@ enum { static void convert(char *fn, int conv_type) { FILE *in, *out; - int i; + int ch; char *temp_fn = temp_fn; /* for compiler */ char *resolved_fn = resolved_fn; @@ -49,28 +49,30 @@ static void convert(char *fn, int conv_type) out = stdout; if (fn != NULL) { struct stat st; + int fd; resolved_fn = xmalloc_follow_symlinks(fn); if (resolved_fn == NULL) bb_simple_perror_msg_and_die(fn); in = xfopen_for_read(resolved_fn); - fstat(fileno(in), &st); + xfstat(fileno(in), &st, resolved_fn); temp_fn = xasprintf("%sXXXXXX", resolved_fn); - i = xmkstemp(temp_fn); - if (fchmod(i, st.st_mode) == -1) + fd = xmkstemp(temp_fn); + if (fchmod(fd, st.st_mode) == -1) bb_simple_perror_msg_and_die(temp_fn); + fchown(fd, st.st_uid, st.st_gid); - out = xfdopen_for_write(i); + out = xfdopen_for_write(fd); } - while ((i = fgetc(in)) != EOF) { - if (i == '\r') + while ((ch = fgetc(in)) != EOF) { + if (ch == '\r') continue; - if (i == '\n') + if (ch == '\n') if (conv_type == CT_UNIX2DOS) fputc('\r', out); - fputc(i, out); + fputc(ch, out); } if (fn != NULL) { From eb5091070f6876993d868d2b2bb49b4b4d3ed002 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Sat, 23 Jan 2016 05:13:15 +0100 Subject: [PATCH 124/260] patch: correctly handle "patch FILE_TO_PATCH" form. Closes 7736 Signed-off-by: Denys Vlasenko --- editors/patch.c | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/editors/patch.c b/editors/patch.c index cb25e4140..988021d77 100644 --- a/editors/patch.c +++ b/editors/patch.c @@ -372,10 +372,6 @@ int patch_main(int argc UNUSED_PARAM, char **argv) xmove_fd(xopen_stdin(argv[1]), STDIN_FILENO); } } - if (argv[0]) { - oldname = xstrdup(argv[0]); - newname = xstrdup(argv[0]); - } // Loop through the lines in the patch for(;;) { @@ -486,10 +482,10 @@ int patch_main(int argc UNUSED_PARAM, char **argv) // or if new hunk is empty (zero context) after patching if (!strcmp(name, "/dev/null") || !(reverse ? oldsum : newsum)) { name = reverse ? newname : oldname; - empty++; + empty = 1; } - // handle -p path truncation. + // Handle -p path truncation. for (i = 0, s = name; *s;) { if ((option_mask32 & FLAG_PATHLEN) && TT.prefix == i) break; @@ -500,6 +496,9 @@ int patch_main(int argc UNUSED_PARAM, char **argv) i++; name = s; } + // If "patch FILE_TO_PATCH", completely ignore name from patch + if (argv[0]) + name = argv[0]; if (empty) { // File is empty after the patches have been applied From 2a4bba3ce2e00e55e6690fa8ba2607679277eed4 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Sun, 24 Jan 2016 15:52:16 +0100 Subject: [PATCH 125/260] sed: make 's///w FILE' actually write to FILE. Closes 8251 function old new delta add_cmd 1167 1210 +43 Signed-off-by: Denys Vlasenko --- editors/sed.c | 11 +++++++---- testsuite/sed.tests | 6 ++++++ 2 files changed, 13 insertions(+), 4 deletions(-) diff --git a/editors/sed.c b/editors/sed.c index a8c35388b..4c7f75521 100644 --- a/editors/sed.c +++ b/editors/sed.c @@ -113,7 +113,7 @@ typedef struct sed_cmd_s { int end_line; /* 'sed 1,3p' 0 == one line only. -1 = last line ($). -2-N = +N */ int end_line_orig; - FILE *sw_file; /* File (sw) command writes to, -1 for none. */ + FILE *sw_file; /* File (sw) command writes to, NULL for none. */ char *string; /* Data string for (saicytb) commands. */ unsigned which_match; /* (s) Which match to replace (0 for all) */ @@ -179,7 +179,7 @@ static void sed_free_and_close_stuff(void) sed_cmd_t *sed_cmd_next = sed_cmd->next; if (sed_cmd->sw_file) - xprint_and_close_file(sed_cmd->sw_file); + fclose(sed_cmd->sw_file); if (sed_cmd->beg_match) { regfree(sed_cmd->beg_match); @@ -426,8 +426,11 @@ static int parse_subst_cmd(sed_cmd_t *sed_cmd, const char *substr) /* Write to file */ case 'w': { - char *temp; - idx += parse_file_cmd(/*sed_cmd,*/ substr+idx, &temp); + char *fname; + idx += parse_file_cmd(/*sed_cmd,*/ substr+idx+1, &fname); + sed_cmd->sw_file = xfopen_for_write(fname); + sed_cmd->sw_last_char = '\n'; + free(fname); break; } /* Ignore case (gnu exension) */ diff --git a/testsuite/sed.tests b/testsuite/sed.tests index 34479e55f..5d2356b64 100755 --- a/testsuite/sed.tests +++ b/testsuite/sed.tests @@ -365,6 +365,12 @@ testing "sed /regex/,+0 -i works" \ "1\n2\n3\n4\n5\n6\n7\n8\n" \ "1\n2\n4\n5\n6\n7\n8\n" \ +testing "sed 's///w FILE'" \ + "sed 's/qwe/ZZZ/wz'; cat z; rm z" \ + "123\nZZZ\nasd\n""ZZZ\n" \ + "" \ + "123\nqwe\nasd\n" + # testing "description" "commands" "result" "infile" "stdin" exit $FAILCOUNT From 4a79224cfcde1c941f581d0c61edaf293e743af5 Mon Sep 17 00:00:00 2001 From: Ron Yorston Date: Sun, 31 Jan 2016 22:22:25 +0100 Subject: [PATCH 126/260] printf: short-circuit output when argument to %b includes \c printf wasn't correctly handling \c in an argument to the %b format specifier. printf %bXX OK\\c returned 'OK\cXX' rather than the expected 'OK'. function old new delta printf_main 886 899 +13 Signed-off-by: Ron Yorston Signed-off-by: Denys Vlasenko --- coreutils/printf.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/coreutils/printf.c b/coreutils/printf.c index 3dd43a978..9ee7350d0 100644 --- a/coreutils/printf.c +++ b/coreutils/printf.c @@ -131,8 +131,8 @@ static double my_xstrtod(const char *arg) return result; } -/* Handles %b */ -static void print_esc_string(const char *str) +/* Handles %b; return 1 if output is to be short-circuited by \c */ +static int print_esc_string(const char *str) { char c; while ((c = *str) != '\0') { @@ -145,6 +145,9 @@ static void print_esc_string(const char *str) str++; } } + else if (*str == 'c') { + return 1; + } { /* optimization: don't force arg to be on-stack, * use another variable for that. */ @@ -155,6 +158,8 @@ static void print_esc_string(const char *str) } putchar(c); } + + return 0; } static void print_direc(char *format, unsigned fmt_length, @@ -280,7 +285,8 @@ static char **print_formatted(char *f, char **argv, int *conv_err) } if (*f == 'b') { if (*argv) { - print_esc_string(*argv); + if (print_esc_string(*argv)) + return saved_argv; /* causes main() to exit */ ++argv; } break; From 40eea690c7eabbf4d12e1e0c30c31f40125ca996 Mon Sep 17 00:00:00 2001 From: Kylie McClain Date: Mon, 1 Feb 2016 01:36:05 +0100 Subject: [PATCH 127/260] Fix compiling with musl's utmp stubs This patch fixes compiling busybox with FEATURE_UTMP and _WTMP enabled. musl, while not really support utmp/wtmp, provides stub functions, as well as variables such as _PATH_UTMP, so that programs using utmp or wtmp can still compile fine. My reasoning for this patch is that on Exherbo, I'm currently trying to get us to be able to use the same busybox config file for both glibc and musl systems, using utmp/wtmp on systems that support it, and using the stubs on musl without needing two different configs. As of latest musl git, it provides all utmp functions needed; 1.1.12 doesn't, but I sent a patch to Rich to add the utmp{,x}name functions expected to exist, which was merged into musl upstream. Signed-off-by: Kylie McClain Signed-off-by: Denys Vlasenko --- include/libbb.h | 5 +++++ init/init.c | 1 - shell/ash.c | 1 - sysklogd/klogd.c | 1 - 4 files changed, 5 insertions(+), 3 deletions(-) diff --git a/include/libbb.h b/include/libbb.h index 82484f911..d05ac2976 100644 --- a/include/libbb.h +++ b/include/libbb.h @@ -20,6 +20,7 @@ #include #include #include +#include #if defined __UCLIBC__ /* TODO: and glibc? */ /* use inlined versions of these: */ # define sigfillset(s) __sigfillset(s) @@ -106,7 +107,11 @@ # define updwtmpx updwtmp # define _PATH_UTMPX _PATH_UTMP # else +# include # include +# if defined _PATH_UTMP && !defined _PATH_UTMPX +# define _PATH_UTMPX _PATH_UTMP +# endif # endif #endif #if ENABLE_LOCALE_SUPPORT diff --git a/init/init.c b/init/init.c index 80c5d0f74..2040a59e8 100644 --- a/init/init.c +++ b/init/init.c @@ -112,7 +112,6 @@ #include "libbb.h" #include -#include #include #ifdef __linux__ # include diff --git a/shell/ash.c b/shell/ash.c index daec975c5..b5a2d961d 100644 --- a/shell/ash.c +++ b/shell/ash.c @@ -37,7 +37,6 @@ #define JOBS ENABLE_ASH_JOB_CONTROL -#include #include #include #include diff --git a/sysklogd/klogd.c b/sysklogd/klogd.c index ca8b848bd..03d65b37f 100644 --- a/sysklogd/klogd.c +++ b/sysklogd/klogd.c @@ -98,7 +98,6 @@ static void klogd_close(void) #else -# include # ifndef _PATH_KLOG # ifdef __GNU__ # define _PATH_KLOG "/dev/klog" From c30a5b13731919367ec2d781a107706fd00f21bc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= Date: Mon, 1 Feb 2016 02:17:28 +0100 Subject: [PATCH 128/260] dd: support iflag=skip_bytes MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit It allows specifying amount of bytes directly (not only amount of blocks) is also supported by GNU's Coreutils. function old new delta parse_comma_flags - 93 +93 static.iflag_words - 12 +12 dd_main 1569 1580 +11 packed_usage 30591 30600 +9 ------------------------------------------------------------------------------ (add/remove: 2/0 grow/shrink: 2/0 up/down: 125/0) Total: 125 bytes Signed-off-by: Rafał Miłecki Signed-off-by: Denys Vlasenko --- coreutils/dd.c | 78 +++++++++++++++++++++++++------------- docs/posix_conformance.txt | 1 + 2 files changed, 52 insertions(+), 27 deletions(-) diff --git a/coreutils/dd.c b/coreutils/dd.c index 6a5288da1..0c0ea07b9 100644 --- a/coreutils/dd.c +++ b/coreutils/dd.c @@ -55,7 +55,7 @@ //usage:#define dd_trivial_usage //usage: "[if=FILE] [of=FILE] " IF_FEATURE_DD_IBS_OBS("[ibs=N] [obs=N] ") "[bs=N] [count=N] [skip=N]\n" -//usage: " [seek=N]" IF_FEATURE_DD_IBS_OBS(" [conv=notrunc|noerror|sync|fsync]") +//usage: " [seek=N]" IF_FEATURE_DD_IBS_OBS(" [conv=notrunc|noerror|sync|fsync] [iflag=skip_bytes]") //usage:#define dd_full_usage "\n\n" //usage: "Copy a file with converting and formatting\n" //usage: "\n if=FILE Read from FILE instead of stdin" @@ -76,6 +76,7 @@ //usage: "\n conv=sync Pad blocks with zeros" //usage: "\n conv=fsync Physically write data out before finishing" //usage: "\n conv=swab Swap every pair of bytes" +//usage: "\n iflag=skip_bytes skip=N is in bytes" //usage: ) //usage: IF_FEATURE_DD_STATUS( //usage: "\n status=noxfer Suppress rate output" @@ -122,11 +123,15 @@ enum { FLAG_FSYNC = (1 << 3) * ENABLE_FEATURE_DD_IBS_OBS, FLAG_SWAB = (1 << 4) * ENABLE_FEATURE_DD_IBS_OBS, /* end of conv flags */ - FLAG_TWOBUFS = (1 << 5) * ENABLE_FEATURE_DD_IBS_OBS, - FLAG_COUNT = 1 << 6, - FLAG_STATUS = 1 << 7, - FLAG_STATUS_NONE = 1 << 7, - FLAG_STATUS_NOXFER = 1 << 8, + /* start of input flags */ + FLAG_IFLAG_SHIFT = 5, + FLAG_SKIP_BYTES = (1 << 5) * ENABLE_FEATURE_DD_IBS_OBS, + /* end of input flags */ + FLAG_TWOBUFS = (1 << 6) * ENABLE_FEATURE_DD_IBS_OBS, + FLAG_COUNT = 1 << 7, + FLAG_STATUS = 1 << 8, + FLAG_STATUS_NONE = 1 << 9, + FLAG_STATUS_NOXFER = 1 << 10, }; static void dd_output_status(int UNUSED_PARAM cur_signal) @@ -203,18 +208,47 @@ static bool write_and_stats(const void *buf, size_t len, size_t obs, # define XATOU_SFX xatoul_sfx #endif +#if ENABLE_FEATURE_DD_IBS_OBS +static int parse_comma_flags(char *val, const char *words, const char *error_in) +{ + int flags = 0; + while (1) { + int n; + char *arg; + /* find ',', replace them with NUL so we can use val for + * index_in_strings() without copying. + * We rely on val being non-null, else strchr would fault. + */ + arg = strchr(val, ','); + if (arg) + *arg = '\0'; + n = index_in_strings(words, val); + if (n < 0) + bb_error_msg_and_die(bb_msg_invalid_arg_to, val, error_in); + flags |= (1 << n); + if (!arg) /* no ',' left, so this was the last specifier */ + break; + *arg = ','; /* to preserve ps listing */ + val = arg + 1; /* skip this keyword and ',' */ + } + return flags; +} +#endif + int dd_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; int dd_main(int argc UNUSED_PARAM, char **argv) { static const char keywords[] ALIGN1 = "bs\0""count\0""seek\0""skip\0""if\0""of\0"IF_FEATURE_DD_STATUS("status\0") #if ENABLE_FEATURE_DD_IBS_OBS - "ibs\0""obs\0""conv\0" + "ibs\0""obs\0""conv\0""iflag\0" #endif ; #if ENABLE_FEATURE_DD_IBS_OBS static const char conv_words[] ALIGN1 = "notrunc\0""sync\0""noerror\0""fsync\0""swab\0"; + static const char iflag_words[] ALIGN1 = + "skip_bytes\0"; #endif #if ENABLE_FEATURE_DD_STATUS static const char status_words[] ALIGN1 = @@ -232,6 +266,7 @@ int dd_main(int argc UNUSED_PARAM, char **argv) OP_ibs, OP_obs, OP_conv, + OP_iflag, /* Must be in the same order as FLAG_XXX! */ OP_conv_notrunc = 0, OP_conv_sync, @@ -251,6 +286,7 @@ int dd_main(int argc UNUSED_PARAM, char **argv) //ibm from ASCII to alternate EBCDIC /* Partially implemented: */ //swab swap every pair of input bytes: will abort on non-even reads + OP_iflag_skip_bytes, #endif }; smallint exitcode = EXIT_FAILURE; @@ -315,24 +351,11 @@ int dd_main(int argc UNUSED_PARAM, char **argv) /*continue;*/ } if (what == OP_conv) { - while (1) { - int n; - /* find ',', replace them with NUL so we can use val for - * index_in_strings() without copying. - * We rely on val being non-null, else strchr would fault. - */ - arg = strchr(val, ','); - if (arg) - *arg = '\0'; - n = index_in_strings(conv_words, val); - if (n < 0) - bb_error_msg_and_die(bb_msg_invalid_arg_to, val, "conv"); - G.flags |= (1 << n); - if (!arg) /* no ',' left, so this was the last specifier */ - break; - /* *arg = ','; - to preserve ps listing? */ - val = arg + 1; /* skip this keyword and ',' */ - } + G.flags |= parse_comma_flags(val, conv_words, "conv"); + /*continue;*/ + } + if (what == OP_iflag) { + G.flags |= parse_comma_flags(val, iflag_words, "iflag") << FLAG_IFLAG_SHIFT; /*continue;*/ } #endif @@ -421,9 +444,10 @@ int dd_main(int argc UNUSED_PARAM, char **argv) outfile = bb_msg_standard_output; } if (skip) { - if (lseek(ifd, skip * ibs, SEEK_CUR) < 0) { + size_t blocksz = (G.flags & FLAG_SKIP_BYTES) ? 1 : ibs; + if (lseek(ifd, skip * blocksz, SEEK_CUR) < 0) { do { - ssize_t n = safe_read(ifd, ibuf, ibs); + ssize_t n = safe_read(ifd, ibuf, blocksz); if (n < 0) goto die_infile; if (n == 0) diff --git a/docs/posix_conformance.txt b/docs/posix_conformance.txt index 5b616d701..c0582dc23 100644 --- a/docs/posix_conformance.txt +++ b/docs/posix_conformance.txt @@ -178,6 +178,7 @@ dd POSIX options: conv=noerror | yes | | conv=notrunc | yes | | conv=sync | yes | | + iflag=skip_bytes| yes | | dd Busybox specific options: conv=fsync From f2c043acfcf9dad9fd3d65821b81f89986bbe54e Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Mon, 18 Jan 2016 12:07:35 +0100 Subject: [PATCH 129/260] busybox: fix uninitialized memory when displaying IPv6 addresses After commit 8e74adab0107658e3dc04ed342206272a284f43e ("libbb: make INET[6]_rresolve use sockaddr2{host,dotted}_noport") INET_sprint6 uses more than just sin6_addr, it also tries to display the scope id, which is uninitialized when called from ife_print6. Signed-off-by: Felix Fietkau Signed-off-by: Denys Vlasenko --- networking/interface.c | 1 + 1 file changed, 1 insertion(+) diff --git a/networking/interface.c b/networking/interface.c index 24bd13c57..e5723b428 100644 --- a/networking/interface.c +++ b/networking/interface.c @@ -881,6 +881,7 @@ static void ife_print6(struct interface *ptr) sprintf(addr6, "%s:%s:%s:%s:%s:%s:%s:%s", addr6p[0], addr6p[1], addr6p[2], addr6p[3], addr6p[4], addr6p[5], addr6p[6], addr6p[7]); + memset(&sap, 0, sizeof(sap)); inet_pton(AF_INET6, addr6, (struct sockaddr *) &sap.sin6_addr); sap.sin6_family = AF_INET6; From fc47fcefb6401605b142c30025c597dc4d110087 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Wed, 10 Feb 2016 06:55:07 +0100 Subject: [PATCH 130/260] ntpd: step when |offset| > 1 sec, not 0.125 sec update_local_clock 769 820 +51 recv_and_process_peer_pkt 838 862 +24 reset_peer_stats 137 133 -4 ------------------------------------------------------------------------------ (add/remove: 0/0 grow/shrink: 2/1 up/down: 75/-4) Total: 71 bytes Signed-off-by: Denys Vlasenko --- networking/ntpd.c | 54 +++++++++++++++++++++++++++++++---------------- 1 file changed, 36 insertions(+), 18 deletions(-) diff --git a/networking/ntpd.c b/networking/ntpd.c index 9732c9b1a..32590a185 100644 --- a/networking/ntpd.c +++ b/networking/ntpd.c @@ -112,7 +112,7 @@ * * Made some changes to speed up re-syncing after our clock goes bad * (tested with suspending my laptop): - * - if largish offset (>= STEP_THRESHOLD * 8 == 1 sec) is seen + * - if largish offset (>= STEP_THRESHOLD == 1 sec) is seen * from a peer, schedule next query for this peer soon * without drastically lowering poll interval for everybody. * This makes us collect enough data for step much faster: @@ -131,11 +131,14 @@ #define RESPONSE_INTERVAL 16 /* wait for reply up to N secs */ /* Step threshold (sec). std ntpd uses 0.128. + */ +#define STEP_THRESHOLD 1 +/* Slew threshold (sec): adjtimex() won't accept offsets larger than this. * Using exact power of 2 (1/8) results in smaller code */ -#define STEP_THRESHOLD 0.125 +#define SLEW_THRESHOLD 0.125 /* Stepout threshold (sec). std ntpd uses 900 (11 mins (!)) */ -#define WATCH_THRESHOLD 128 +#define WATCH_THRESHOLD 128 /* NB: set WATCH_THRESHOLD to ~60 when debugging to save time) */ //UNUSED: #define PANIC_THRESHOLD 1000 /* panic threshold (sec) */ @@ -143,7 +146,7 @@ * If we got |offset| > BIGOFF from a peer, cap next query interval * for this peer by this many seconds: */ -#define BIGOFF (STEP_THRESHOLD * 8) +#define BIGOFF STEP_THRESHOLD #define BIGOFF_INTERVAL (1 << 7) /* 128 s */ #define FREQ_TOLERANCE 0.000015 /* frequency tolerance (15 PPM) */ @@ -157,10 +160,10 @@ #define MAXPOLL 12 /* maximum poll interval (12: 1.1h, 17: 36.4h). std ntpd uses 17 */ /* * Actively lower poll when we see such big offsets. - * With STEP_THRESHOLD = 0.125, it means we try to sync more aggressively + * With SLEW_THRESHOLD = 0.125, it means we try to sync more aggressively * if offset increases over ~0.04 sec */ -//#define POLLDOWN_OFFSET (STEP_THRESHOLD / 3) +//#define POLLDOWN_OFFSET (SLEW_THRESHOLD / 3) #define MINDISP 0.01 /* minimum dispersion (sec) */ #define MAXDISP 16 /* maximum dispersion (sec) */ #define MAXSTRAT 16 /* maximum stratum (infinity metric) */ @@ -720,7 +723,7 @@ static void reset_peer_stats(peer_t *p, double offset) { int i; - bool small_ofs = fabs(offset) < 16 * STEP_THRESHOLD; + bool small_ofs = fabs(offset) < STEP_THRESHOLD; /* Used to set p->filter_datapoint[i].d_dispersion = MAXDISP * and clear reachable bits, but this proved to be too agressive: @@ -771,7 +774,7 @@ add_peers(const char *s) p->p_fd = -1; p->p_xmt_msg.m_status = MODE_CLIENT | (NTP_VERSION << 3); p->next_action_time = G.cur_time; /* = set_next(p, 0); */ - reset_peer_stats(p, 16 * STEP_THRESHOLD); + reset_peer_stats(p, STEP_THRESHOLD); llist_add_to(&G.ntp_peers, p); G.peer_cnt++; @@ -1638,14 +1641,7 @@ update_local_clock(peer_t *p) tmx.freq = G.discipline_freq_drift * 65536e6; #endif tmx.modes = ADJ_OFFSET | ADJ_STATUS | ADJ_TIMECONST;// | ADJ_MAXERROR | ADJ_ESTERROR; - tmx.offset = (offset * 1000000); /* usec */ - tmx.status = STA_PLL; - if (G.ntp_status & LI_PLUSSEC) - tmx.status |= STA_INS; - if (G.ntp_status & LI_MINUSSEC) - tmx.status |= STA_DEL; - - tmx.constant = (int)G.poll_exp - 4 > 0 ? (int)G.poll_exp - 4 : 0; + tmx.constant = (int)G.poll_exp - 4; /* EXPERIMENTAL. * The below if statement should be unnecessary, but... * It looks like Linux kernel's PLL is far too gentle in changing @@ -1656,8 +1652,27 @@ update_local_clock(peer_t *p) * To be on a safe side, let's do it only if offset is significantly * larger than jitter. */ - if (tmx.constant > 0 && G.offset_to_jitter_ratio >= TIMECONST_HACK_GATE) + if (G.offset_to_jitter_ratio >= TIMECONST_HACK_GATE) tmx.constant--; + tmx.offset = (long)(offset * 1000000); /* usec */ + if (SLEW_THRESHOLD < STEP_THRESHOLD) { + if (tmx.offset > (long)(SLEW_THRESHOLD * 1000000)) { + tmx.offset = (long)(SLEW_THRESHOLD * 1000000); + tmx.constant--; + } + if (tmx.offset < -(long)(SLEW_THRESHOLD * 1000000)) { + tmx.offset = -(long)(SLEW_THRESHOLD * 1000000); + tmx.constant--; + } + } + if (tmx.constant < 0) + tmx.constant = 0; + + tmx.status = STA_PLL; + if (G.ntp_status & LI_PLUSSEC) + tmx.status |= STA_INS; + if (G.ntp_status & LI_MINUSSEC) + tmx.status |= STA_DEL; //tmx.esterror = (uint32_t)(clock_jitter * 1e6); //tmx.maxerror = (uint32_t)((sys_rootdelay / 2 + sys_rootdisp) * 1e6); @@ -1931,6 +1946,9 @@ recv_and_process_peer_pkt(peer_t *p) increase_interval: adjust_poll(MINPOLL); } else { + VERB3 if (rc > 0) + bb_error_msg("want smaller poll interval: offset/jitter ratio > %u", + POLLADJ_GATE); adjust_poll(-G.poll_exp * 2); } } @@ -1939,7 +1957,7 @@ recv_and_process_peer_pkt(peer_t *p) pick_normal_interval: interval = poll_interval(INT_MAX); if (fabs(offset) >= BIGOFF && interval > BIGOFF_INTERVAL) { - /* If we are synced, offsets are less than STEP_THRESHOLD, + /* If we are synced, offsets are less than SLEW_THRESHOLD, * or at the very least not much larger than it. * Now we see a largish one. * Either this peer is feeling bad, or packet got corrupted, From 383201e7258c3c1646f6d5cab4e813b5c3b3ecd0 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Wed, 10 Feb 2016 07:06:31 +0100 Subject: [PATCH 131/260] ntpd: shorter message Signed-off-by: Denys Vlasenko --- networking/ntpd.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/networking/ntpd.c b/networking/ntpd.c index 32590a185..1651670d9 100644 --- a/networking/ntpd.c +++ b/networking/ntpd.c @@ -1947,7 +1947,7 @@ recv_and_process_peer_pkt(peer_t *p) adjust_poll(MINPOLL); } else { VERB3 if (rc > 0) - bb_error_msg("want smaller poll interval: offset/jitter ratio > %u", + bb_error_msg("want smaller poll interval: offset/jitter > %u", POLLADJ_GATE); adjust_poll(-G.poll_exp * 2); } From 29eae728e959a382841bd0a32cc1a8d1bcdc9150 Mon Sep 17 00:00:00 2001 From: Nicolas Carrier Date: Thu, 4 Feb 2016 12:18:01 +0100 Subject: [PATCH 132/260] init: make the command-line rewrite optional When launched as PID 1 and after parsing its arguments, init wipes all all of them except argv[0] and rewrites argv[0] to contain only "init", so that its command-line appears solely as "init" in tools such as ps. This patch adds the FEATURE_INIT_MODIFY_CMDLINE which, if set to n, will make init preserve all its arguments including argv[0], be they parsed or ignored. The original command-line used to launch init can then be retrieved in /proc/1/cmdline on Linux, for example. Signed-off-by: Nicolas Carrier Signed-off-by: Denys Vlasenko --- init/init.c | 27 ++++++++++++++++++++++----- 1 file changed, 22 insertions(+), 5 deletions(-) diff --git a/init/init.c b/init/init.c index 2040a59e8..25bfaec8c 100644 --- a/init/init.c +++ b/init/init.c @@ -102,6 +102,21 @@ //config: //config: Note that on Linux, init attempts to detect serial terminal and //config: sets TERM to "vt102" if one is found. +//config: +//config:config FEATURE_INIT_MODIFY_CMDLINE +//config: bool "Modify the command-line to \"init\"" +//config: default y +//config: depends on INIT +//config: help +//config: When launched as PID 1 and after parsing its arguments, init +//config: wipes all the arguments but argv[0] and rewrites argv[0] to +//config: contain only "init", so that its command-line appears solely as +//config: "init" in tools such as ps. +//config: If this option is set to Y, init will keep its original behavior, +//config: otherwise, all the arguments including argv[0] will be preserved, +//config: be they parsed or ignored by init. +//config: The original command-line used to launch init can then be +//config: retrieved in /proc/1/cmdline on Linux, for example. //applet:IF_INIT(APPLET(init, BB_DIR_SBIN, BB_SUID_DROP)) //applet:IF_FEATURE_INITRD(APPLET_ODDNAME(linuxrc, init, BB_DIR_ROOT, BB_SUID_DROP, linuxrc)) @@ -1138,11 +1153,13 @@ int init_main(int argc UNUSED_PARAM, char **argv) } #endif - /* Make the command line just say "init" - thats all, nothing else */ - strncpy(argv[0], "init", strlen(argv[0])); - /* Wipe argv[1]-argv[N] so they don't clutter the ps listing */ - while (*++argv) - nuke_str(*argv); + if (ENABLE_FEATURE_INIT_MODIFY_CMDLINE) { + /* Make the command line just say "init" - that's all, nothing else */ + strncpy(argv[0], "init", strlen(argv[0])); + /* Wipe argv[1]-argv[N] so they don't clutter the ps listing */ + while (*++argv) + nuke_str(*argv); + } /* Set up signal handlers */ if (!DEBUG_INIT) { From 8efcc9589bd61171ec1fe4f71c33e9df62b6005b Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Thu, 11 Feb 2016 17:44:44 +0100 Subject: [PATCH 133/260] networking: allow dot at the end of the domain name in dhcp response Patch based on Balaji Punnuru work. Signed-off-by: Denys Vlasenko --- networking/udhcp/dhcpc.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/networking/udhcp/dhcpc.c b/networking/udhcp/dhcpc.c index 915f65935..48097bc24 100644 --- a/networking/udhcp/dhcpc.c +++ b/networking/udhcp/dhcpc.c @@ -201,6 +201,8 @@ static int good_hostname(const char *name) //Do we want this? //return ((name - start) < 1025); /* NS_MAXDNAME */ name++; + if (*name == '\0') + return 1; // We allow trailing dot too } } #else From 43e56639c6739953d5a6686823bcd0d256512ea5 Mon Sep 17 00:00:00 2001 From: Mike Frysinger Date: Fri, 12 Feb 2016 22:12:47 -0500 Subject: [PATCH 134/260] build: add a sanitizer debug option Building & running with ASAN is super helpful, so add a dedicated config knob for it. This way people don't have to guess at the right compiler settings in order to get a good build. We can just tell people to enable this one option. Signed-off-by: Mike Frysinger --- Config.in | 10 ++++++++++ Makefile.flags | 5 +++++ 2 files changed, 15 insertions(+) diff --git a/Config.in b/Config.in index 07b4bf36b..0a0b5d7cb 100644 --- a/Config.in +++ b/Config.in @@ -688,6 +688,16 @@ config DEBUG_PESSIMIZE in a much bigger executable that more closely matches the source code. +config DEBUG_SANITIZE + bool "Enable runtime sanitizers (ASAN/LSAN/USAN/etc...)" + default n + help + Say Y here if you want to enable runtime sanitizers. These help + catch bad memory accesses (e.g. buffer overflows), but will make + the executable larger and slow down runtime a bit. + + If you aren't developing/testing busybox, say N here. + config UNIT_TEST bool "Build unit tests" default n diff --git a/Makefile.flags b/Makefile.flags index 9f77674ba..65021de25 100644 --- a/Makefile.flags +++ b/Makefile.flags @@ -75,6 +75,11 @@ else CFLAGS += $(call cc-option,-Os,$(call cc-option,-O2,)) endif endif +ifeq ($(CONFIG_DEBUG_SANITIZE),y) +CFLAGS += $(call cc-option,-fsanitize=address,) +CFLAGS += $(call cc-option,-fsanitize=leak,) +CFLAGS += $(call cc-option,-fsanitize=undefined,) +endif # If arch/$(ARCH)/Makefile did not override it (with, say, -fPIC)... ARCH_FPIC ?= -fpic From 3a5cc989025eefe03fda0552b253a4a8f015a761 Mon Sep 17 00:00:00 2001 From: Mike Frysinger Date: Fri, 12 Feb 2016 23:26:51 -0500 Subject: [PATCH 135/260] modprobe: only parse files that end in .conf MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This matches behavior with kmod which has been the standard for a long time at this point. URL: https://bugs.busybox.net/8021 Reported-by: Jö Signed-off-by: Mike Frysinger --- modutils/modprobe.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/modutils/modprobe.c b/modutils/modprobe.c index ec490b74d..997ee3c67 100644 --- a/modutils/modprobe.c +++ b/modutils/modprobe.c @@ -220,8 +220,16 @@ static int FAST_FUNC config_file_action(const char *filename, parser_t *p; struct module_entry *m; int rc = TRUE; + const char *base, *ext; - if (bb_basename(filename)[0] == '.') + /* Skip files that begin with a ".". */ + base = bb_basename(filename); + if (base[0] == '.') + goto error; + + /* Skip files that do not end with a ".conf". */ + ext = strrchr(base, '.'); + if (ext == NULL || strcmp(ext + 1, "conf")) goto error; p = config_open2(filename, fopen_for_read); From 03718bb2743fbd772732a2c57c76c1c56fa9cd37 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Wed, 24 Feb 2016 01:22:45 +0100 Subject: [PATCH 136/260] ntpd: print packet delay in clock update message function old new delta update_local_clock 820 826 +6 Signed-off-by: Denys Vlasenko --- networking/ntpd.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/networking/ntpd.c b/networking/ntpd.c index 1651670d9..2a96ddbd0 100644 --- a/networking/ntpd.c +++ b/networking/ntpd.c @@ -1685,8 +1685,14 @@ update_local_clock(peer_t *p) VERB4 bb_error_msg("adjtimex:%d freq:%ld offset:%+ld status:0x%x", rc, tmx.freq, tmx.offset, tmx.status); G.kernel_freq_drift = tmx.freq / 65536; - VERB2 bb_error_msg("update from:%s offset:%+f jitter:%f clock drift:%+.3fppm tc:%d", - p->p_dotted, offset, G.discipline_jitter, (double)tmx.freq / 65536, (int)tmx.constant); + VERB2 bb_error_msg("update from:%s offset:%+f delay:%f jitter:%f clock drift:%+.3fppm tc:%d", + p->p_dotted, + offset, + p->lastpkt_delay, + G.discipline_jitter, + (double)tmx.freq / 65536, + (int)tmx.constant + ); return 1; /* "ok to increase poll interval" */ } From 5fa9fefddce56fab75b2e6c88c4516e2b21d2f5a Mon Sep 17 00:00:00 2001 From: "Arnout Vandecappelle (Essensium/Mind)" Date: Sun, 14 Feb 2016 19:04:09 +0100 Subject: [PATCH 137/260] taskset: fix non-fancy cpuset printing on big-endian The non-fancy version of the from_cpuset uses CPU_SETSIZE as if it represents the number of bytes in the cpuset, while it is actually the number of bits. This leads to out-of-bounds accesses on the cpu_set_t in the big-endian case. Basically all uses of CPU_SETSIZE have to be divided by 8. This is done correctly in the fancy version of from_cpuset. In addition, the big-endian case is completely wrong to begin with. All standard C libraries that I know of implement cpu_set_t as an unsigned long array, so both for big and little endian, the least significant bits are in the beginning of the array. Therefore, the approach taken for the little endian case is equally valid. We only need special handling for big endian when CPU_SETSIZE is large and we use an unsigned long long to get more bits out. Signed-off-by: Arnout Vandecappelle (Essensium/Mind) Signed-off-by: Denys Vlasenko --- miscutils/taskset.c | 37 ++++++++++++++++++------------------- 1 file changed, 18 insertions(+), 19 deletions(-) diff --git a/miscutils/taskset.c b/miscutils/taskset.c index 100b1d926..fb352ab8d 100644 --- a/miscutils/taskset.c +++ b/miscutils/taskset.c @@ -75,27 +75,26 @@ static char *from_cpuset(cpu_set_t *mask) #define TASKSET_PRINTF_MASK "%llx" static unsigned long long from_cpuset(cpu_set_t *mask) { - char *p = (void*)mask; + BUILD_BUG_ON(CPU_SETSIZE < 8*sizeof(int)); - BUILD_BUG_ON(CPU_SETSIZE < sizeof(int)); - - /* Take the least significant bits. Careful! - * Consider both CPU_SETSIZE=4 and CPU_SETSIZE=1024 cases + /* Take the least significant bits. Assume cpu_set_t is + * implemented as an array of unsigned long or unsigned + * int. */ -#if BB_BIG_ENDIAN - /* For big endian, it means LAST bits */ - if (CPU_SETSIZE < sizeof(long)) - p += CPU_SETSIZE - sizeof(int); - else if (CPU_SETSIZE < sizeof(long long)) - p += CPU_SETSIZE - sizeof(long); - else - p += CPU_SETSIZE - sizeof(long long); -#endif - if (CPU_SETSIZE < sizeof(long)) - return *(unsigned*)p; - if (CPU_SETSIZE < sizeof(long long)) - return *(unsigned long*)p; - return *(unsigned long long*)p; + if (CPU_SETSIZE < 8*sizeof(long)) + return *(unsigned*)mask; + if (CPU_SETSIZE < 8*sizeof(long long)) + return *(unsigned long*)mask; +# if BB_BIG_ENDIAN + if (sizeof(long long) > sizeof(long)) { + /* We can put two long in the long long, but they have to + * be swapped: the least significant word comes first in the + * array */ + unsigned long *p = (void*)mask; + return p[0] + ((unsigned long long)p[1] << (8*sizeof(long))); + } +# endif + return *(unsigned long long*)mask; } #endif From 5bec08cebd559c906eb94b8b957afb9f0b8db338 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Fri, 26 Feb 2016 14:56:18 +0100 Subject: [PATCH 138/260] udhcp: trivial shrink function old new delta dname_dec 337 332 -5 Signed-off-by: Denys Vlasenko --- networking/udhcp/domain_codec.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/networking/udhcp/domain_codec.c b/networking/udhcp/domain_codec.c index c1325d8be..05cdf51e9 100644 --- a/networking/udhcp/domain_codec.c +++ b/networking/udhcp/domain_codec.c @@ -42,7 +42,7 @@ char* FAST_FUNC dname_dec(const uint8_t *cstr, int clen, const char *pre) */ while (1) { /* note: "return NULL" below are leak-safe since - * dst isn't yet allocated */ + * dst isn't allocated yet */ const uint8_t *c; unsigned crtpos, retpos, depth, len; @@ -95,9 +95,8 @@ char* FAST_FUNC dname_dec(const uint8_t *cstr, int clen, const char *pre) if (!dst) { /* first pass? */ /* allocate dst buffer and copy pre */ unsigned plen = strlen(pre); - ret = dst = xmalloc(plen + len); - memcpy(dst, pre, plen); - dst += plen; + ret = xmalloc(plen + len); + dst = stpcpy(ret, pre); } else { dst[len - 1] = '\0'; break; From 352f79acbd759c14399e39baef21fc4ffe180ac2 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Fri, 26 Feb 2016 15:54:56 +0100 Subject: [PATCH 139/260] udhcpc: fix OPTION_6RD parsing (could overflow its malloced buffer) Signed-off-by: Denys Vlasenko --- networking/udhcp/common.c | 15 +++++++++++++-- networking/udhcp/dhcpc.c | 4 ++-- 2 files changed, 15 insertions(+), 4 deletions(-) diff --git a/networking/udhcp/common.c b/networking/udhcp/common.c index bc41c8d4d..680852ce4 100644 --- a/networking/udhcp/common.c +++ b/networking/udhcp/common.c @@ -142,7 +142,7 @@ const char dhcp_option_strings[] ALIGN1 = * udhcp_str2optset: to determine how many bytes to allocate. * xmalloc_optname_optval: to estimate string length * from binary option length: (option[LEN] / dhcp_option_lengths[opt_type]) - * is the number of elements, multiply in by one element's string width + * is the number of elements, multiply it by one element's string width * (len_of_option_as_string[opt_type]) and you know how wide string you need. */ const uint8_t dhcp_option_lengths[] ALIGN1 = { @@ -162,7 +162,18 @@ const uint8_t dhcp_option_lengths[] ALIGN1 = { [OPTION_S32] = 4, /* Just like OPTION_STRING, we use minimum length here */ [OPTION_STATIC_ROUTES] = 5, - [OPTION_6RD] = 22, /* ignored by udhcp_str2optset */ + [OPTION_6RD] = 12, /* ignored by udhcp_str2optset */ + /* The above value was chosen as follows: + * len_of_option_as_string[] for this option is >60: it's a string of the form + * "32 128 ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff 255.255.255.255 ". + * Each additional ipv4 address takes 4 bytes in binary option and appends + * another "255.255.255.255 " 16-byte string. We can set [OPTION_6RD] = 4 + * but this severely overestimates string length: instead of 16 bytes, + * it adds >60 for every 4 bytes in binary option. + * We cheat and declare here that option is in units of 12 bytes. + * This adds more than 60 bytes for every three ipv4 addresses - more than enough. + * (Even 16 instead of 12 should work, but let's be paranoid). + */ }; diff --git a/networking/udhcp/dhcpc.c b/networking/udhcp/dhcpc.c index 48097bc24..2fe84e1ca 100644 --- a/networking/udhcp/dhcpc.c +++ b/networking/udhcp/dhcpc.c @@ -113,7 +113,7 @@ static const uint8_t len_of_option_as_string[] = { [OPTION_IP ] = sizeof("255.255.255.255 "), [OPTION_IP_PAIR ] = sizeof("255.255.255.255 ") * 2, [OPTION_STATIC_ROUTES ] = sizeof("255.255.255.255/32 255.255.255.255 "), - [OPTION_6RD ] = sizeof("32 128 ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff 255.255.255.255 "), + [OPTION_6RD ] = sizeof("132 128 ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff 255.255.255.255 "), [OPTION_STRING ] = 1, [OPTION_STRING_HOST ] = 1, #if ENABLE_FEATURE_UDHCP_RFC3397 @@ -222,7 +222,7 @@ static NOINLINE char *xmalloc_optname_optval(uint8_t *option, const struct dhcp_ type = optflag->flags & OPTION_TYPE_MASK; optlen = dhcp_option_lengths[type]; upper_length = len_of_option_as_string[type] - * ((unsigned)(len + optlen - 1) / (unsigned)optlen); + * ((unsigned)(len + optlen) / (unsigned)optlen); dest = ret = xmalloc(upper_length + strlen(opt_name) + 2); dest += sprintf(ret, "%s=", opt_name); From e5aba8871254d411766b9d04d89dcff4ded21e76 Mon Sep 17 00:00:00 2001 From: Nicolas Cavallari Date: Tue, 1 Mar 2016 18:59:08 +0100 Subject: [PATCH 140/260] ifupdown: allow duplicate interface definitions This patch allow to have multiple interface definitions, much like Debian's ifupdown. More specifically, it removes the check for a duplicate definition, so the impact on binary size should be fairly minimal. This configuration: iface eth0 inet static address 192.168.0.15 netmask 255.255.0.0 gateway 192.168.0.1 iface eth0 inet static address 10.0.0.1 netmask 255.255.255.0 Will add two addresses to eth0 if ip is used. If ifconfig is used, the standards methods will likely not stack, but the administrator may still use the manual method. The DHCP method may work depending on the DHCP client in use. This is a fairly advanced feature for power users who knows what they are doing. There are not many other network configuration systems that allows multiple addresses on an interface. Signed-off-by: Nicolas Cavallari Signed-off-by: Denys Vlasenko --- networking/ifupdown.c | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/networking/ifupdown.c b/networking/ifupdown.c index 766dfabbd..179186199 100644 --- a/networking/ifupdown.c +++ b/networking/ifupdown.c @@ -875,7 +875,19 @@ static struct interfaces_file_t *read_interfaces(const char *filename, struct in currif->method = get_method(currif->address_family, method_name); if (!currif->method) bb_error_msg_and_die("unknown method \"%s\"", method_name); - +#if 0 +// Allegedly, Debian allows a duplicate definition: +// iface eth0 inet static +// address 192.168.0.15 +// netmask 255.255.0.0 +// gateway 192.168.0.1 +// +// iface eth0 inet static +// address 10.0.0.1 +// netmask 255.255.255.0 +// +// This adds *two* addresses to eth0 (probably requires use of "ip", not "ifconfig" +// for (iface_list = defn->ifaces; iface_list; iface_list = iface_list->link) { struct interface_defn_t *tmp = (struct interface_defn_t *) iface_list->data; if ((strcmp(tmp->iface, currif->iface) == 0) @@ -884,6 +896,7 @@ static struct interfaces_file_t *read_interfaces(const char *filename, struct in bb_error_msg_and_die("duplicate interface \"%s\"", tmp->iface); } } +#endif llist_add_to_end(&(defn->ifaces), (char*)currif); debug_noise("iface %s %s %s\n", currif->iface, address_family_name, method_name); From ea2b71be66b7500cc3ddaa0f617491610ff07dc4 Mon Sep 17 00:00:00 2001 From: Christian Lindeberg Date: Tue, 1 Mar 2016 19:23:22 +0100 Subject: [PATCH 141/260] udhcpd: keep expired leases at startup Let udhcpd retain the information about expired leases when restarting so that the leases are reserved until they possibly become the oldest expired lease. This reduces the frequency of IP address changes for example when the DHCP server and a group of clients, who do not store and request their previously offered IP address across restarts, are collectively restarted and the startup order of the clients are not guaranteed. Signed-off-by: Christian Lindeberg Signed-off-by: Denys Vlasenko --- networking/udhcp/files.c | 6 +++++- networking/udhcp/leases.c | 4 +++- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/networking/udhcp/files.c b/networking/udhcp/files.c index 1c8808c0f..5b90e26d2 100644 --- a/networking/udhcp/files.c +++ b/networking/udhcp/files.c @@ -195,7 +195,11 @@ void FAST_FUNC read_leases(const char *file) uint32_t static_nip; if (expires <= 0) - continue; + /* We keep expired leases: add_lease() will add + * a lease with 0 seconds remaining. + * Fewer IP address changes this way for mass reboot scenario. + */ + expires = 0; /* Check if there is a different static lease for this IP or MAC */ static_nip = get_static_nip_by_mac(server_config.static_leases, lease.lease_mac); diff --git a/networking/udhcp/leases.c b/networking/udhcp/leases.c index 844bb60b1..411b74962 100644 --- a/networking/udhcp/leases.c +++ b/networking/udhcp/leases.c @@ -17,7 +17,9 @@ static struct dyn_lease *oldest_expired_lease(void) /* Unexpired leases have g_leases[i].expires >= current time * and therefore can't ever match */ for (i = 0; i < server_config.max_leases; i++) { - if (g_leases[i].expires < oldest_time) { + if (g_leases[i].expires == 0 /* empty entry */ + || g_leases[i].expires < oldest_time + ) { oldest_time = g_leases[i].expires; oldest_lease = &g_leases[i]; } From abe8f7515aded80889d78c2c1c8947997918cf90 Mon Sep 17 00:00:00 2001 From: Hans Dedecker Date: Thu, 18 Feb 2016 12:27:07 +0100 Subject: [PATCH 142/260] dhcpc: Use client IP address as source address for DHCP renew/rebind messages RFC2131 paragraph 4.1 states DHCP messages broadcast by a client prior to that client obtaining its IP address must have the source IP address field in the header set to 0. Request messages transmitted in renewing and rebinding state need to use the obtained IP address as source IP address in the header; this behavior lines up with other implementations like ISC dhcp client. Signed-off-by: Hans Dedecker Signed-off-by: Denys Vlasenko --- networking/udhcp/dhcpc.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/networking/udhcp/dhcpc.c b/networking/udhcp/dhcpc.c index 2fe84e1ca..6c2b112f0 100644 --- a/networking/udhcp/dhcpc.c +++ b/networking/udhcp/dhcpc.c @@ -675,10 +675,10 @@ static void add_client_options(struct dhcp_packet *packet) * client reverts to using the IP broadcast address. */ -static int raw_bcast_from_client_config_ifindex(struct dhcp_packet *packet) +static int raw_bcast_from_client_config_ifindex(struct dhcp_packet *packet, uint32_t src_nip) { return udhcp_send_raw_packet(packet, - /*src*/ INADDR_ANY, CLIENT_PORT, + /*src*/ src_nip, CLIENT_PORT, /*dst*/ INADDR_BROADCAST, SERVER_PORT, MAC_BCAST_ADDR, client_config.ifindex); } @@ -689,7 +689,7 @@ static int bcast_or_ucast(struct dhcp_packet *packet, uint32_t ciaddr, uint32_t return udhcp_send_kernel_packet(packet, ciaddr, CLIENT_PORT, server, SERVER_PORT); - return raw_bcast_from_client_config_ifindex(packet); + return raw_bcast_from_client_config_ifindex(packet, ciaddr); } /* Broadcast a DHCP discover packet to the network, with an optionally requested IP */ @@ -715,7 +715,7 @@ static NOINLINE int send_discover(uint32_t xid, uint32_t requested) add_client_options(&packet); bb_info_msg("Sending discover..."); - return raw_bcast_from_client_config_ifindex(&packet); + return raw_bcast_from_client_config_ifindex(&packet, INADDR_ANY); } /* Broadcast a DHCP request message */ @@ -759,7 +759,7 @@ static NOINLINE int send_select(uint32_t xid, uint32_t server, uint32_t requeste addr.s_addr = requested; bb_info_msg("Sending select for %s...", inet_ntoa(addr)); - return raw_bcast_from_client_config_ifindex(&packet); + return raw_bcast_from_client_config_ifindex(&packet, INADDR_ANY); } /* Unicast or broadcast a DHCP renew message */ @@ -827,7 +827,7 @@ static NOINLINE int send_decline(/*uint32_t xid,*/ uint32_t server, uint32_t req udhcp_add_simple_option(&packet, DHCP_SERVER_ID, server); bb_info_msg("Sending decline..."); - return raw_bcast_from_client_config_ifindex(&packet); + return raw_bcast_from_client_config_ifindex(&packet, INADDR_ANY); } #endif From 35e063e1b9a1d35d311859fe61a934304952d5b5 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Thu, 3 Mar 2016 02:19:16 +0100 Subject: [PATCH 143/260] ifupdowm: fix "warning: unused variable 'iface_list'" Signed-off-by: Denys Vlasenko --- networking/ifupdown.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/networking/ifupdown.c b/networking/ifupdown.c index 179186199..2c6db926f 100644 --- a/networking/ifupdown.c +++ b/networking/ifupdown.c @@ -850,7 +850,6 @@ static struct interfaces_file_t *read_interfaces(const char *filename, struct in char *iface_name; char *address_family_name; char *method_name; - llist_t *iface_list; currif = xzalloc(sizeof(*currif)); iface_name = next_word(&rest_of_line); @@ -888,6 +887,7 @@ static struct interfaces_file_t *read_interfaces(const char *filename, struct in // // This adds *two* addresses to eth0 (probably requires use of "ip", not "ifconfig" // + llist_t *iface_list; for (iface_list = defn->ifaces; iface_list; iface_list = iface_list->link) { struct interface_defn_t *tmp = (struct interface_defn_t *) iface_list->data; if ((strcmp(tmp->iface, currif->iface) == 0) From 4c48a6474701d8b396a14213ebcc979a49187faf Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Thu, 3 Mar 2016 22:01:23 +0100 Subject: [PATCH 144/260] ntpd: more informative poll lowering message Signed-off-by: Denys Vlasenko --- networking/ntpd.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/networking/ntpd.c b/networking/ntpd.c index 2a96ddbd0..4695c3366 100644 --- a/networking/ntpd.c +++ b/networking/ntpd.c @@ -1953,8 +1953,8 @@ recv_and_process_peer_pkt(peer_t *p) adjust_poll(MINPOLL); } else { VERB3 if (rc > 0) - bb_error_msg("want smaller poll interval: offset/jitter > %u", - POLLADJ_GATE); + bb_error_msg("want smaller interval: offset/jitter = %u", + G.offset_to_jitter_ratio); adjust_poll(-G.poll_exp * 2); } } From f37f28199f508f5fee44753d320f044a91e76e39 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Fri, 4 Mar 2016 07:06:53 +0100 Subject: [PATCH 145/260] ntpd: do not use a peer more than once (say, if two peers resolve to the same IP) function old new delta add_peers 98 166 +68 Signed-off-by: Denys Vlasenko --- networking/ntpd.c | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/networking/ntpd.c b/networking/ntpd.c index 4695c3366..517806e75 100644 --- a/networking/ntpd.c +++ b/networking/ntpd.c @@ -727,7 +727,7 @@ reset_peer_stats(peer_t *p, double offset) /* Used to set p->filter_datapoint[i].d_dispersion = MAXDISP * and clear reachable bits, but this proved to be too agressive: - * after step (tested with suspinding laptop for ~30 secs), + * after step (tested with suspending laptop for ~30 secs), * this caused all previous data to be considered invalid, * making us needing to collect full ~8 datapoins per peer * after step in order to start trusting them. @@ -766,11 +766,26 @@ reset_peer_stats(peer_t *p, double offset) static void add_peers(const char *s) { + llist_t *item; peer_t *p; p = xzalloc(sizeof(*p)); p->p_lsa = xhost2sockaddr(s, 123); p->p_dotted = xmalloc_sockaddr2dotted_noport(&p->p_lsa->u.sa); + + /* Names like N..pool.ntp.org are randomly resolved + * to a pool of machines. Sometimes different N's resolve to the same IP. + * It is not useful to have two peers with same IP. We skip duplicates. + */ + for (item = G.ntp_peers; item != NULL; item = item->link) { + peer_t *pp = (peer_t *) item->data; + if (strcmp(p->p_dotted, pp->p_dotted) == 0) { + bb_error_msg("duplicate peer %s (%s)", s, p->p_dotted); + free(p); + return; + } + } + p->p_fd = -1; p->p_xmt_msg.m_status = MODE_CLIENT | (NTP_VERSION << 3); p->next_action_time = G.cur_time; /* = set_next(p, 0); */ From c8641962e4cbde48108ddfc1c105e3320778190d Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Fri, 4 Mar 2016 07:26:08 +0100 Subject: [PATCH 146/260] ntpd: if peer does not reply anymore, try re-resolving its hostname function old new delta ntpd_main 1053 1130 +77 add_peers 166 195 +29 Signed-off-by: Denys Vlasenko --- networking/ntpd.c | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/networking/ntpd.c b/networking/ntpd.c index 517806e75..410318979 100644 --- a/networking/ntpd.c +++ b/networking/ntpd.c @@ -267,6 +267,7 @@ typedef struct { typedef struct { len_and_sockaddr *p_lsa; + char *p_hostname; char *p_dotted; int p_fd; int datapoint_idx; @@ -781,11 +782,14 @@ add_peers(const char *s) peer_t *pp = (peer_t *) item->data; if (strcmp(p->p_dotted, pp->p_dotted) == 0) { bb_error_msg("duplicate peer %s (%s)", s, p->p_dotted); + free(p->p_lsa); + free(p->p_dotted); free(p); return; } } + p->p_hostname = xstrdup(s); p->p_fd = -1; p->p_xmt_msg.m_status = MODE_CLIENT | (NTP_VERSION << 3); p->next_action_time = G.cur_time; /* = set_next(p, 0); */ @@ -2332,6 +2336,21 @@ int ntpd_main(int argc UNUSED_PARAM, char **argv) timeout = poll_interval(NOREPLY_INTERVAL); bb_error_msg("timed out waiting for %s, reach 0x%02x, next query in %us", p->p_dotted, p->reachable_bits, timeout); + + /* What if don't see it because it changed its IP? */ + if (p->reachable_bits == 0) { + len_and_sockaddr *lsa = host2sockaddr(p->p_hostname, 123); + if (lsa) { + char *dotted = xmalloc_sockaddr2dotted_noport(&lsa->u.sa); + //if (strcmp(dotted, p->p_dotted) != 0) + // bb_error_msg("peer IP changed"); + free(p->p_lsa); + free(p->p_dotted); + p->p_lsa = lsa; + p->p_dotted = dotted; + } + } + set_next(p, timeout); } } From aee7cd82be31577c2e5c144d083af206bedbb96a Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Fri, 4 Mar 2016 07:36:04 +0100 Subject: [PATCH 147/260] ntpd: add experimental patch Signed-off-by: Denys Vlasenko --- networking/ntpd.diff | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) create mode 100644 networking/ntpd.diff diff --git a/networking/ntpd.diff b/networking/ntpd.diff new file mode 100644 index 000000000..4afd7e134 --- /dev/null +++ b/networking/ntpd.diff @@ -0,0 +1,24 @@ +This patch scales down small offsets quadratically. Reduces sensitivity to jitter + +diff --git a/networking/ntpd.c b/networking/ntpd.c +index 4695c33..ac05815 100644 +--- a/networking/ntpd.c ++++ b/networking/ntpd.c +@@ -1654,6 +1654,17 @@ update_local_clock(peer_t *p) + */ + if (G.offset_to_jitter_ratio >= TIMECONST_HACK_GATE) + tmx.constant--; ++ ++{ ++ double d = p->lastpkt_delay; ++ if (d > SLEW_THRESHOLD) ++ d = SLEW_THRESHOLD; ++ d /= 2; ++ if ((abs_offset / d) < 1) { ++ offset *= (abs_offset / d); ++ } ++} ++ + tmx.offset = (long)(offset * 1000000); /* usec */ + if (SLEW_THRESHOLD < STEP_THRESHOLD) { + if (tmx.offset > (long)(SLEW_THRESHOLD * 1000000)) { From 86d9f60f3acc4a5d755912003278267f8e6f3e89 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Fri, 4 Mar 2016 17:00:56 +0100 Subject: [PATCH 148/260] udhcpc: do not use -t NUM for counting "select" packets, use 3 Otherwise, "-t 0" usage may end up sending them forever if server does not respond. function old new delta udhcpc_main 2846 2836 -10 Signed-off-by: Denys Vlasenko --- networking/udhcp/dhcpc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/networking/udhcp/dhcpc.c b/networking/udhcp/dhcpc.c index 6c2b112f0..dfd5ca606 100644 --- a/networking/udhcp/dhcpc.c +++ b/networking/udhcp/dhcpc.c @@ -1501,7 +1501,7 @@ int udhcpc_main(int argc UNUSED_PARAM, char **argv) packet_num = 0; continue; case REQUESTING: - if (!discover_retries || packet_num < discover_retries) { + if (packet_num < 3) { /* send broadcast select packet */ send_select(xid, server_addr, requested_ip); timeout = discover_timeout; From 7849ccb61c376e4704ce1c3e5a0d12fd7d743200 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Sun, 6 Mar 2016 17:35:16 +0100 Subject: [PATCH 149/260] inotifyd: swap meaning of 'y' and 'm' events in help text. Closes 8726 Signed-off-by: Denys Vlasenko --- miscutils/inotifyd.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/miscutils/inotifyd.c b/miscutils/inotifyd.c index 7a1a6a2e5..908d657fd 100644 --- a/miscutils/inotifyd.c +++ b/miscutils/inotifyd.c @@ -47,8 +47,8 @@ //usage: "\n o Event queue overflowed" //usage: "\n x File can't be watched anymore" //usage: "\nIf watching a directory:" -//usage: "\n m Subfile is moved into dir" -//usage: "\n y Subfile is moved out of dir" +//usage: "\n y Subfile is moved into dir" +//usage: "\n m Subfile is moved out of dir" //usage: "\n n Subfile is created" //usage: "\n d Subfile is deleted" //usage: "\n" From ea351b97428f7dc921d5431ccac366201754fcef Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Sun, 6 Mar 2016 17:53:11 +0100 Subject: [PATCH 150/260] ls: fix columnar output. Closes 8731 In coreutils/ls.c, 1.19 introduced commit 2f7d9e8903029b1b5e51a15f9cb0dcb6ca17c3ac, removing the variable tabstops and hard coding the column separation to 2 characters, but was not done correctly. The column_width assumes a gap of 1 character, so the computed number of columns exceeds the terminal width when many small files are encountered. A minor problem but surprisingly annoying. Signed-off-by: Denys Vlasenko --- coreutils/ls.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/coreutils/ls.c b/coreutils/ls.c index c48498858..20bd61860 100644 --- a/coreutils/ls.c +++ b/coreutils/ls.c @@ -668,7 +668,7 @@ static void display_files(struct dnode **dn, unsigned nfiles) if (column_width < len) column_width = len; } - column_width += 1 + + column_width += 2 + IF_SELINUX( ((G.all_fmt & LIST_CONTEXT) ? 33 : 0) + ) ((G.all_fmt & LIST_INO) ? 8 : 0) + ((G.all_fmt & LIST_BLOCKS) ? 5 : 0); @@ -696,8 +696,8 @@ static void display_files(struct dnode **dn, unsigned nfiles) if (i < nfiles) { if (column > 0) { nexttab -= column; - printf("%*s ", nexttab, ""); - column += nexttab + 1; + printf("%*s", nexttab, ""); + column += nexttab; } nexttab = column + column_width; column += display_single(dn[i]); From d2b820b540ada43dfef8751328c158e342387304 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Mon, 7 Mar 2016 15:21:54 +0100 Subject: [PATCH 151/260] renice: tweak help text Signed-off-by: Denys Vlasenko --- procps/renice.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/procps/renice.c b/procps/renice.c index 77f400a1d..2b690e0ed 100644 --- a/procps/renice.c +++ b/procps/renice.c @@ -20,13 +20,14 @@ */ //usage:#define renice_trivial_usage -//usage: "{{-n INCREMENT} | PRIORITY} [[-p | -g | -u] ID...]" +//usage: "[-n] PRIORITY [[-p | -g | -u] ID...]..." //usage:#define renice_full_usage "\n\n" -//usage: "Change scheduling priority for a running process\n" -//usage: "\n -n Adjust current nice value (smaller is faster)" -//usage: "\n -p Process id(s) (default)" -//usage: "\n -g Process group id(s)" -//usage: "\n -u Process user name(s) and/or id(s)" +//usage: "Change scheduling priority of a running process\n" +//usage: "\n -n Add PRIORITY to current nice value" +//usage: "\n Without -n, nice value is set to PRIORITY" +//usage: "\n -p Process ids (default)" +//usage: "\n -g Process group ids" +//usage: "\n -u Process user names" #include "libbb.h" #include From d474ffc68290e0a83651c4432eeabfa62cd51e87 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Thu, 10 Mar 2016 11:47:58 +0100 Subject: [PATCH 152/260] udhcp: fix a SEGV on malformed RFC1035-encoded domain name Signed-off-by: Denys Vlasenko --- networking/udhcp/domain_codec.c | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/networking/udhcp/domain_codec.c b/networking/udhcp/domain_codec.c index 05cdf51e9..cee31f14d 100644 --- a/networking/udhcp/domain_codec.c +++ b/networking/udhcp/domain_codec.c @@ -63,11 +63,10 @@ char* FAST_FUNC dname_dec(const uint8_t *cstr, int clen, const char *pre) if (crtpos + *c + 1 > clen) /* label too long? abort */ return NULL; if (dst) - memcpy(dst + len, c + 1, *c); + /* \3com ---> "com." */ + ((char*)mempcpy(dst + len, c + 1, *c))[0] = '.'; len += *c + 1; crtpos += *c + 1; - if (dst) - dst[len - 1] = '.'; } else { /* NUL: end of current domain name */ if (retpos == 0) { @@ -78,7 +77,10 @@ char* FAST_FUNC dname_dec(const uint8_t *cstr, int clen, const char *pre) crtpos = retpos; retpos = depth = 0; } - if (dst) + if (dst && len != 0) + /* \4host\3com\0\4host and we are at \0: + * \3com was converted to "com.", change dot to space. + */ dst[len - 1] = ' '; } @@ -227,6 +229,9 @@ int main(int argc, char **argv) int len; uint8_t *encoded; + uint8_t str[6] = { 0x00, 0x00, 0x02, 0x65, 0x65, 0x00 }; + printf("NUL:'%s'\n", dname_dec(str, 6, "")); + #define DNAME_DEC(encoded,pre) dname_dec((uint8_t*)(encoded), sizeof(encoded), (pre)) printf("'%s'\n", DNAME_DEC("\4host\3com\0", "test1:")); printf("test2:'%s'\n", DNAME_DEC("\4host\3com\0\4host\3com\0", "")); From 1b7c17391de66502dd7a97c866e0a33681edbb1f Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Fri, 11 Mar 2016 00:26:58 +0100 Subject: [PATCH 153/260] udhcpc: fix a warning in debug code Signed-off-by: Denys Vlasenko --- networking/udhcp/domain_codec.c | 1 + 1 file changed, 1 insertion(+) diff --git a/networking/udhcp/domain_codec.c b/networking/udhcp/domain_codec.c index cee31f14d..5a923cc2c 100644 --- a/networking/udhcp/domain_codec.c +++ b/networking/udhcp/domain_codec.c @@ -7,6 +7,7 @@ * Licensed under GPLv2 or later, see file LICENSE in this source tree. */ #ifdef DNS_COMPR_TESTING +# define _GNU_SOURCE # define FAST_FUNC /* nothing */ # define xmalloc malloc # include From dbb58a3879c2daa3e286a8cd9da7935e264f3072 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Mon, 14 Mar 2016 18:23:33 +0100 Subject: [PATCH 154/260] fixes for problems found by bionic build Signed-off-by: Denys Vlasenko --- include/libbb.h | 20 ++++++++++++-------- miscutils/eject.c | 26 ++++++++++++++++---------- 2 files changed, 28 insertions(+), 18 deletions(-) diff --git a/include/libbb.h b/include/libbb.h index d05ac2976..8b226c00c 100644 --- a/include/libbb.h +++ b/include/libbb.h @@ -142,14 +142,18 @@ # include #else # include -# if !defined(__socklen_t_defined) && !defined(_SOCKLEN_T_DECLARED) -/* We #define socklen_t *after* includes, otherwise we get - * typedef redefinition errors from system headers - * (in case "is it defined already" detection above failed) - */ -# define socklen_t bb_socklen_t - typedef unsigned socklen_t; -# endif +//This breaks on bionic: +//# if !defined(__socklen_t_defined) && !defined(_SOCKLEN_T_DECLARED) +///* We #define socklen_t *after* includes, otherwise we get +// * typedef redefinition errors from system headers +// * (in case "is it defined already" detection above failed) +// */ +//# define socklen_t bb_socklen_t +// typedef unsigned socklen_t; +//# endif +//if this is still needed, add a fix along the lines of +// ifdef SPECIFIC_BROKEN_LIBC_CHECK / typedef socklen_t / endif +//in platform.h instead! #endif #ifndef HAVE_CLEARENV # define clearenv() do { if (environ) environ[0] = NULL; } while (0) diff --git a/miscutils/eject.c b/miscutils/eject.c index a20e04b7f..15eaf556d 100644 --- a/miscutils/eject.c +++ b/miscutils/eject.c @@ -25,23 +25,19 @@ #include #include "libbb.h" +#if ENABLE_FEATURE_EJECT_SCSI /* Must be after libbb.h: they need size_t */ -#include "fix_u32.h" -#include -#include - -/* various defines swiped from linux/cdrom.h */ -#define CDROMCLOSETRAY 0x5319 /* pendant of CDROMEJECT */ -#define CDROMEJECT 0x5309 /* Ejects the cdrom media */ -#define CDROM_DRIVE_STATUS 0x5326 /* Get tray position, etc. */ -/* drive status possibilities returned by CDROM_DRIVE_STATUS ioctl */ -#define CDS_TRAY_OPEN 2 +# include "fix_u32.h" +# include +# include +#endif #define dev_fd 3 /* Code taken from the original eject (http://eject.sourceforge.net/), * refactored it a bit for busybox (ne-bb@nicoerfurth.de) */ +#if ENABLE_FEATURE_EJECT_SCSI static void eject_scsi(const char *dev) { static const char sg_commands[3][6] = { @@ -76,6 +72,16 @@ static void eject_scsi(const char *dev) /* force kernel to reread partition table when new disc is inserted */ ioctl(dev_fd, BLKRRPART); } +#else +# define eject_scsi() ((void)0) +#endif + +/* various defines swiped from linux/cdrom.h */ +#define CDROMCLOSETRAY 0x5319 /* pendant of CDROMEJECT */ +#define CDROMEJECT 0x5309 /* Ejects the cdrom media */ +#define CDROM_DRIVE_STATUS 0x5326 /* Get tray position, etc. */ +/* drive status possibilities returned by CDROM_DRIVE_STATUS ioctl */ +#define CDS_TRAY_OPEN 2 #define FLAG_CLOSE 1 #define FLAG_SMART 2 From 23961b2fd39d1c8e8d623c15fc12dc7b1b91a1be Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Mon, 14 Mar 2016 19:34:15 +0100 Subject: [PATCH 155/260] more bionic fixes Signed-off-by: Denys Vlasenko --- miscutils/eject.c | 2 +- util-linux/minix.h | 5 +++++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/miscutils/eject.c b/miscutils/eject.c index 15eaf556d..e33d79127 100644 --- a/miscutils/eject.c +++ b/miscutils/eject.c @@ -73,7 +73,7 @@ static void eject_scsi(const char *dev) ioctl(dev_fd, BLKRRPART); } #else -# define eject_scsi() ((void)0) +# define eject_scsi(dev) ((void)0) #endif /* various defines swiped from linux/cdrom.h */ diff --git a/util-linux/minix.h b/util-linux/minix.h index e0fbcf761..83ffe6da5 100644 --- a/util-linux/minix.h +++ b/util-linux/minix.h @@ -61,9 +61,14 @@ enum { MINIX_ROOT_INO = 1, MINIX_BAD_INO = 2, +#undef MINIX1_SUPER_MAGIC MINIX1_SUPER_MAGIC = 0x137F, /* original minix fs */ +#undef MINIX1_SUPER_MAGIC2 MINIX1_SUPER_MAGIC2 = 0x138F, /* minix fs, 30 char names */ +/* bionic has this define */ +#undef MINIX2_SUPER_MAGIC MINIX2_SUPER_MAGIC = 0x2468, /* minix V2 fs */ +#undef MINIX2_SUPER_MAGIC2 MINIX2_SUPER_MAGIC2 = 0x2478, /* minix V2 fs, 30 char names */ MINIX_VALID_FS = 0x0001, /* clean fs */ MINIX_ERROR_FS = 0x0002, /* fs has errors */ From fd5a2b7b0441495fa520cfc938818cd1555a8129 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Mon, 14 Mar 2016 22:28:53 +0100 Subject: [PATCH 156/260] New example config: android_502_defconfig Signed-off-by: Denys Vlasenko --- configs/android_502_defconfig | 1142 +++++++++++++++++++++++++++++++++ 1 file changed, 1142 insertions(+) create mode 100644 configs/android_502_defconfig diff --git a/configs/android_502_defconfig b/configs/android_502_defconfig new file mode 100644 index 000000000..c5146c719 --- /dev/null +++ b/configs/android_502_defconfig @@ -0,0 +1,1142 @@ +## This config was successfully used to build busybox on +## Samsung SM-T700 tablet +## Android 5.0.2 +## gcc/toolchain from https://termux.com/ +## binutils 2.26.20160125 +## gcc 4.9.3 +## bionic ANDROID_API 21 +## +## Static build did not work (static libraries not installed?): +## # CONFIG_STATIC is not set +## syslog() requires an additional library: +## CONFIG_EXTRA_LDLIBS="log" +## Bionic's botched off_t: +## # CONFIG_LFS is not set +## +## Incompatible password database API: +## # CONFIG_FEATURE_SHADOWPASSWDS is not set +## # CONFIG_USE_BB_PWD_GRP is not set +## # CONFIG_USE_BB_SHADOW is not set +## # CONFIG_ADDUSER is not set +## # CONFIG_ADDGROUP is not set +## # CONFIG_DELUSER is not set +## # CONFIG_DELGROUP is not set +## +## No utmp/wtmp: +## # CONFIG_FEATURE_UTMP is not set +## # CONFIG_FEATURE_WTMP is not set +## # CONFIG_WHO is not set +## # CONFIG_LAST is not set +## # CONFIG_USERS is not set +## # CONFIG_WALL is not set +## +## Assorted header problems: +## # CONFIG_HOSTID is not set +## # CONFIG_FEATURE_SYNC_FANCY is not set - syncfs() +## # CONFIG_FEATURE_TOUCH_NODEREF is not set - lutimes() +## # CONFIG_LOGNAME is not set - getlogin_r() +## # CONFIG_LOADFONT is not set +## # CONFIG_SETFONT is not set +## # CONFIG_MDEV is not set +## # CONFIG_FSCK_MINIX is not set +## # CONFIG_MKFS_MINIX is not set +## # CONFIG_IPCRM is not set +## # CONFIG_IPCS is not set +## # CONFIG_SWAPONOFF is not set +## # CONFIG_CONSPY is not set +## # CONFIG_NANDWRITE is not set +## # CONFIG_NANDDUMP is not set +## # CONFIG_RFKILL is not set +## # CONFIG_UBIATTACH is not set +## # CONFIG_UBIDETACH is not set +## # CONFIG_UBIMKVOL is not set +## # CONFIG_UBIRMVOL is not set +## # CONFIG_UBIRSVOL is not set +## # CONFIG_UBIUPDATEVOL is not set +## # CONFIG_FEATURE_EJECT_SCSI is not set - scsi headers +## # CONFIG_ARP is not set +## # CONFIG_ARPING is not set +## # CONFIG_ETHER_WAKE is not set +## # CONFIG_IFCONFIG is not set +## # CONFIG_IFENSLAVE is not set +## # CONFIG_NSLOOKUP is not set +## # CONFIG_ROUTE is not set +## # CONFIG_ZCIP is not set +## # CONFIG_HUSH is not set - glob.h +## # CONFIG_KLOGD is not set +## # CONFIG_LOGGER is not set +## # CONFIG_LOGREAD is not set +## # CONFIG_SYSLOGD is not set +##----------------------------------------------- + +# +# Automatically generated make config: don't edit +# Busybox version: 1.25.0.git +# Mon Mar 14 20:43:42 2016 +# +CONFIG_HAVE_DOT_CONFIG=y + +# +# Busybox Settings +# + +# +# General Configuration +# +CONFIG_DESKTOP=y +# CONFIG_EXTRA_COMPAT is not set +CONFIG_INCLUDE_SUSv2=y +# CONFIG_USE_PORTABLE_CODE is not set +CONFIG_PLATFORM_LINUX=y +CONFIG_FEATURE_BUFFERS_USE_MALLOC=y +# CONFIG_FEATURE_BUFFERS_GO_ON_STACK is not set +# CONFIG_FEATURE_BUFFERS_GO_IN_BSS is not set +CONFIG_SHOW_USAGE=y +CONFIG_FEATURE_VERBOSE_USAGE=y +CONFIG_FEATURE_COMPRESS_USAGE=y +CONFIG_FEATURE_INSTALLER=y +# CONFIG_INSTALL_NO_USR is not set +# CONFIG_LOCALE_SUPPORT is not set +CONFIG_UNICODE_SUPPORT=y +# CONFIG_UNICODE_USING_LOCALE is not set +# CONFIG_FEATURE_CHECK_UNICODE_IN_ENV is not set +CONFIG_SUBST_WCHAR=63 +CONFIG_LAST_SUPPORTED_WCHAR=767 +# CONFIG_UNICODE_COMBINING_WCHARS is not set +# CONFIG_UNICODE_WIDE_WCHARS is not set +# CONFIG_UNICODE_BIDI_SUPPORT is not set +# CONFIG_UNICODE_NEUTRAL_TABLE is not set +# CONFIG_UNICODE_PRESERVE_BROKEN is not set +# CONFIG_PAM is not set +CONFIG_FEATURE_USE_SENDFILE=y +CONFIG_LONG_OPTS=y +CONFIG_FEATURE_DEVPTS=y +# CONFIG_FEATURE_CLEAN_UP is not set +# CONFIG_FEATURE_UTMP is not set +# CONFIG_FEATURE_WTMP is not set +CONFIG_FEATURE_PIDFILE=y +CONFIG_PID_FILE_PATH="/var/run" +CONFIG_FEATURE_SUID=y +CONFIG_FEATURE_SUID_CONFIG=y +CONFIG_FEATURE_SUID_CONFIG_QUIET=y +# CONFIG_SELINUX is not set +# CONFIG_FEATURE_PREFER_APPLETS is not set +CONFIG_BUSYBOX_EXEC_PATH="/proc/self/exe" +CONFIG_FEATURE_SYSLOG=y +# CONFIG_FEATURE_HAVE_RPC is not set + +# +# Build Options +# +# CONFIG_STATIC is not set +# CONFIG_PIE is not set +# CONFIG_NOMMU is not set +# CONFIG_BUILD_LIBBUSYBOX is not set +# CONFIG_FEATURE_INDIVIDUAL is not set +# CONFIG_FEATURE_SHARED_BUSYBOX is not set +# CONFIG_LFS is not set +CONFIG_CROSS_COMPILER_PREFIX="" +CONFIG_SYSROOT="" +CONFIG_EXTRA_CFLAGS="" +CONFIG_EXTRA_LDFLAGS="" +CONFIG_EXTRA_LDLIBS="log" + +# +# Debugging Options +# +# CONFIG_DEBUG is not set +# CONFIG_DEBUG_PESSIMIZE is not set +# CONFIG_DEBUG_SANITIZE is not set +# CONFIG_UNIT_TEST is not set +# CONFIG_WERROR is not set +CONFIG_NO_DEBUG_LIB=y +# CONFIG_DMALLOC is not set +# CONFIG_EFENCE is not set + +# +# Installation Options ("make install" behavior) +# +CONFIG_INSTALL_APPLET_SYMLINKS=y +# CONFIG_INSTALL_APPLET_HARDLINKS is not set +# CONFIG_INSTALL_APPLET_SCRIPT_WRAPPERS is not set +# CONFIG_INSTALL_APPLET_DONT is not set +# CONFIG_INSTALL_SH_APPLET_SYMLINK is not set +# CONFIG_INSTALL_SH_APPLET_HARDLINK is not set +# CONFIG_INSTALL_SH_APPLET_SCRIPT_WRAPPER is not set +CONFIG_PREFIX="./_install" + +# +# Busybox Library Tuning +# +CONFIG_FEATURE_RTMINMAX=y +CONFIG_PASSWORD_MINLEN=6 +CONFIG_MD5_SMALL=1 +CONFIG_SHA3_SMALL=1 +# CONFIG_FEATURE_FAST_TOP is not set +# CONFIG_FEATURE_ETC_NETWORKS is not set +CONFIG_FEATURE_USE_TERMIOS=y +CONFIG_FEATURE_EDITING=y +CONFIG_FEATURE_EDITING_MAX_LEN=1024 +# CONFIG_FEATURE_EDITING_VI is not set +CONFIG_FEATURE_EDITING_HISTORY=255 +CONFIG_FEATURE_EDITING_SAVEHISTORY=y +# CONFIG_FEATURE_EDITING_SAVE_ON_EXIT is not set +CONFIG_FEATURE_REVERSE_SEARCH=y +CONFIG_FEATURE_TAB_COMPLETION=y +# CONFIG_FEATURE_USERNAME_COMPLETION is not set +CONFIG_FEATURE_EDITING_FANCY_PROMPT=y +# CONFIG_FEATURE_EDITING_ASK_TERMINAL is not set +CONFIG_FEATURE_NON_POSIX_CP=y +# CONFIG_FEATURE_VERBOSE_CP_MESSAGE is not set +CONFIG_FEATURE_COPYBUF_KB=4 +CONFIG_FEATURE_SKIP_ROOTFS=y +CONFIG_MONOTONIC_SYSCALL=y +CONFIG_IOCTL_HEX2STR_ERROR=y +CONFIG_FEATURE_HWIB=y + +# +# Applets +# + +# +# Archival Utilities +# +CONFIG_FEATURE_SEAMLESS_XZ=y +CONFIG_FEATURE_SEAMLESS_LZMA=y +CONFIG_FEATURE_SEAMLESS_BZ2=y +CONFIG_FEATURE_SEAMLESS_GZ=y +# CONFIG_FEATURE_SEAMLESS_Z is not set +# CONFIG_AR is not set +# CONFIG_FEATURE_AR_LONG_FILENAMES is not set +# CONFIG_FEATURE_AR_CREATE is not set +# CONFIG_UNCOMPRESS is not set +CONFIG_GUNZIP=y +CONFIG_FEATURE_GUNZIP_LONG_OPTIONS=y +CONFIG_BUNZIP2=y +CONFIG_UNLZMA=y +# CONFIG_FEATURE_LZMA_FAST is not set +CONFIG_LZMA=y +CONFIG_UNXZ=y +CONFIG_XZ=y +CONFIG_BZIP2=y +CONFIG_CPIO=y +CONFIG_FEATURE_CPIO_O=y +CONFIG_FEATURE_CPIO_P=y +# CONFIG_DPKG is not set +# CONFIG_DPKG_DEB is not set +# CONFIG_FEATURE_DPKG_DEB_EXTRACT_ONLY is not set +CONFIG_GZIP=y +CONFIG_FEATURE_GZIP_LONG_OPTIONS=y +CONFIG_GZIP_FAST=0 +# CONFIG_FEATURE_GZIP_LEVELS is not set +CONFIG_LZOP=y +# CONFIG_LZOP_COMPR_HIGH is not set +CONFIG_RPM=y +CONFIG_RPM2CPIO=y +CONFIG_TAR=y +CONFIG_FEATURE_TAR_CREATE=y +CONFIG_FEATURE_TAR_AUTODETECT=y +CONFIG_FEATURE_TAR_FROM=y +CONFIG_FEATURE_TAR_OLDGNU_COMPATIBILITY=y +CONFIG_FEATURE_TAR_OLDSUN_COMPATIBILITY=y +CONFIG_FEATURE_TAR_GNU_EXTENSIONS=y +CONFIG_FEATURE_TAR_LONG_OPTIONS=y +CONFIG_FEATURE_TAR_TO_COMMAND=y +CONFIG_FEATURE_TAR_UNAME_GNAME=y +CONFIG_FEATURE_TAR_NOPRESERVE_TIME=y +# CONFIG_FEATURE_TAR_SELINUX is not set +CONFIG_UNZIP=y + +# +# Coreutils +# +CONFIG_BASENAME=y +CONFIG_CAT=y +CONFIG_DATE=y +CONFIG_FEATURE_DATE_ISOFMT=y +# CONFIG_FEATURE_DATE_NANO is not set +CONFIG_FEATURE_DATE_COMPAT=y +CONFIG_DD=y +CONFIG_FEATURE_DD_SIGNAL_HANDLING=y +CONFIG_FEATURE_DD_THIRD_STATUS_LINE=y +CONFIG_FEATURE_DD_IBS_OBS=y +CONFIG_FEATURE_DD_STATUS=y +# CONFIG_HOSTID is not set +CONFIG_ID=y +CONFIG_GROUPS=y +CONFIG_SHUF=y +CONFIG_STAT=y +CONFIG_FEATURE_STAT_FORMAT=y +CONFIG_FEATURE_STAT_FILESYSTEM=y +CONFIG_SYNC=y +# CONFIG_FEATURE_SYNC_FANCY is not set +CONFIG_TEST=y +CONFIG_FEATURE_TEST_64=y +CONFIG_TOUCH=y +# CONFIG_FEATURE_TOUCH_NODEREF is not set +CONFIG_FEATURE_TOUCH_SUSV3=y +CONFIG_TR=y +CONFIG_FEATURE_TR_CLASSES=y +CONFIG_FEATURE_TR_EQUIV=y +CONFIG_TRUNCATE=y +CONFIG_UNLINK=y +CONFIG_BASE64=y +# CONFIG_WHO is not set +# CONFIG_USERS is not set +CONFIG_CAL=y +CONFIG_CATV=y +CONFIG_CHGRP=y +CONFIG_CHMOD=y +CONFIG_CHOWN=y +CONFIG_FEATURE_CHOWN_LONG_OPTIONS=y +CONFIG_CHROOT=y +CONFIG_CKSUM=y +CONFIG_COMM=y +CONFIG_CP=y +CONFIG_FEATURE_CP_LONG_OPTIONS=y +CONFIG_CUT=y +CONFIG_DF=y +CONFIG_FEATURE_DF_FANCY=y +CONFIG_DIRNAME=y +CONFIG_DOS2UNIX=y +CONFIG_UNIX2DOS=y +CONFIG_DU=y +CONFIG_FEATURE_DU_DEFAULT_BLOCKSIZE_1K=y +CONFIG_ECHO=y +CONFIG_FEATURE_FANCY_ECHO=y +CONFIG_ENV=y +CONFIG_FEATURE_ENV_LONG_OPTIONS=y +CONFIG_EXPAND=y +CONFIG_FEATURE_EXPAND_LONG_OPTIONS=y +CONFIG_EXPR=y +CONFIG_EXPR_MATH_SUPPORT_64=y +CONFIG_FALSE=y +CONFIG_FOLD=y +CONFIG_FSYNC=y +CONFIG_HEAD=y +CONFIG_FEATURE_FANCY_HEAD=y +CONFIG_INSTALL=y +CONFIG_FEATURE_INSTALL_LONG_OPTIONS=y +CONFIG_LN=y +# CONFIG_LOGNAME is not set +CONFIG_LS=y +CONFIG_FEATURE_LS_FILETYPES=y +CONFIG_FEATURE_LS_FOLLOWLINKS=y +CONFIG_FEATURE_LS_RECURSIVE=y +CONFIG_FEATURE_LS_SORTFILES=y +CONFIG_FEATURE_LS_TIMESTAMPS=y +CONFIG_FEATURE_LS_USERNAME=y +CONFIG_FEATURE_LS_COLOR=y +CONFIG_FEATURE_LS_COLOR_IS_DEFAULT=y +CONFIG_MD5SUM=y +CONFIG_MKDIR=y +CONFIG_FEATURE_MKDIR_LONG_OPTIONS=y +CONFIG_MKFIFO=y +CONFIG_MKNOD=y +CONFIG_MV=y +CONFIG_FEATURE_MV_LONG_OPTIONS=y +CONFIG_NICE=y +CONFIG_NOHUP=y +CONFIG_OD=y +CONFIG_PRINTENV=y +CONFIG_PRINTF=y +CONFIG_PWD=y +CONFIG_READLINK=y +CONFIG_FEATURE_READLINK_FOLLOW=y +CONFIG_REALPATH=y +CONFIG_RM=y +CONFIG_RMDIR=y +CONFIG_FEATURE_RMDIR_LONG_OPTIONS=y +CONFIG_SEQ=y +CONFIG_SHA1SUM=y +CONFIG_SHA256SUM=y +CONFIG_SHA512SUM=y +CONFIG_SHA3SUM=y +CONFIG_SLEEP=y +CONFIG_FEATURE_FANCY_SLEEP=y +CONFIG_FEATURE_FLOAT_SLEEP=y +CONFIG_SORT=y +CONFIG_FEATURE_SORT_BIG=y +CONFIG_SPLIT=y +CONFIG_FEATURE_SPLIT_FANCY=y +CONFIG_STTY=y +CONFIG_SUM=y +CONFIG_TAC=y +CONFIG_TAIL=y +CONFIG_FEATURE_FANCY_TAIL=y +CONFIG_TEE=y +CONFIG_FEATURE_TEE_USE_BLOCK_IO=y +CONFIG_TRUE=y +CONFIG_TTY=y +CONFIG_UNAME=y +CONFIG_UNAME_OSNAME="GNU/Linux" +CONFIG_UNEXPAND=y +CONFIG_FEATURE_UNEXPAND_LONG_OPTIONS=y +CONFIG_UNIQ=y +CONFIG_USLEEP=y +CONFIG_UUDECODE=y +CONFIG_UUENCODE=y +CONFIG_WC=y +CONFIG_FEATURE_WC_LARGE=y +CONFIG_WHOAMI=y +CONFIG_YES=y + +# +# Common options +# +CONFIG_FEATURE_VERBOSE=y + +# +# Common options for cp and mv +# +CONFIG_FEATURE_PRESERVE_HARDLINKS=y + +# +# Common options for ls, more and telnet +# +CONFIG_FEATURE_AUTOWIDTH=y + +# +# Common options for df, du, ls +# +CONFIG_FEATURE_HUMAN_READABLE=y + +# +# Common options for md5sum, sha1sum, sha256sum, sha512sum, sha3sum +# +CONFIG_FEATURE_MD5_SHA1_SUM_CHECK=y + +# +# Console Utilities +# +CONFIG_CHVT=y +CONFIG_FGCONSOLE=y +CONFIG_CLEAR=y +CONFIG_DEALLOCVT=y +CONFIG_DUMPKMAP=y +CONFIG_KBD_MODE=y +# CONFIG_LOADFONT is not set +CONFIG_LOADKMAP=y +CONFIG_OPENVT=y +CONFIG_RESET=y +CONFIG_RESIZE=y +CONFIG_FEATURE_RESIZE_PRINT=y +CONFIG_SETCONSOLE=y +CONFIG_FEATURE_SETCONSOLE_LONG_OPTIONS=y +# CONFIG_SETFONT is not set +# CONFIG_FEATURE_SETFONT_TEXTUAL_MAP is not set +CONFIG_DEFAULT_SETFONT_DIR="" +CONFIG_SETKEYCODES=y +CONFIG_SETLOGCONS=y +CONFIG_SHOWKEY=y +# CONFIG_FEATURE_LOADFONT_PSF2 is not set +# CONFIG_FEATURE_LOADFONT_RAW is not set + +# +# Debian Utilities +# +CONFIG_MKTEMP=y +CONFIG_PIPE_PROGRESS=y +CONFIG_RUN_PARTS=y +CONFIG_FEATURE_RUN_PARTS_LONG_OPTIONS=y +CONFIG_FEATURE_RUN_PARTS_FANCY=y +CONFIG_START_STOP_DAEMON=y +CONFIG_FEATURE_START_STOP_DAEMON_FANCY=y +CONFIG_FEATURE_START_STOP_DAEMON_LONG_OPTIONS=y +CONFIG_WHICH=y + +# +# Editors +# +CONFIG_AWK=y +CONFIG_FEATURE_AWK_LIBM=y +CONFIG_FEATURE_AWK_GNU_EXTENSIONS=y +CONFIG_CMP=y +CONFIG_DIFF=y +CONFIG_FEATURE_DIFF_LONG_OPTIONS=y +CONFIG_FEATURE_DIFF_DIR=y +CONFIG_ED=y +CONFIG_PATCH=y +CONFIG_SED=y +CONFIG_VI=y +CONFIG_FEATURE_VI_MAX_LEN=4096 +# CONFIG_FEATURE_VI_8BIT is not set +CONFIG_FEATURE_VI_COLON=y +CONFIG_FEATURE_VI_YANKMARK=y +CONFIG_FEATURE_VI_SEARCH=y +# CONFIG_FEATURE_VI_REGEX_SEARCH is not set +CONFIG_FEATURE_VI_USE_SIGNALS=y +CONFIG_FEATURE_VI_DOT_CMD=y +CONFIG_FEATURE_VI_READONLY=y +CONFIG_FEATURE_VI_SETOPTS=y +CONFIG_FEATURE_VI_SET=y +CONFIG_FEATURE_VI_WIN_RESIZE=y +CONFIG_FEATURE_VI_ASK_TERMINAL=y +CONFIG_FEATURE_VI_UNDO=y +CONFIG_FEATURE_VI_UNDO_QUEUE=y +CONFIG_FEATURE_VI_UNDO_QUEUE_MAX=256 +CONFIG_FEATURE_ALLOW_EXEC=y + +# +# Finding Utilities +# +CONFIG_FIND=y +CONFIG_FEATURE_FIND_PRINT0=y +CONFIG_FEATURE_FIND_MTIME=y +CONFIG_FEATURE_FIND_MMIN=y +CONFIG_FEATURE_FIND_PERM=y +CONFIG_FEATURE_FIND_TYPE=y +CONFIG_FEATURE_FIND_XDEV=y +CONFIG_FEATURE_FIND_MAXDEPTH=y +CONFIG_FEATURE_FIND_NEWER=y +CONFIG_FEATURE_FIND_INUM=y +CONFIG_FEATURE_FIND_EXEC=y +CONFIG_FEATURE_FIND_EXEC_PLUS=y +CONFIG_FEATURE_FIND_USER=y +CONFIG_FEATURE_FIND_GROUP=y +CONFIG_FEATURE_FIND_NOT=y +CONFIG_FEATURE_FIND_DEPTH=y +CONFIG_FEATURE_FIND_PAREN=y +CONFIG_FEATURE_FIND_SIZE=y +CONFIG_FEATURE_FIND_PRUNE=y +CONFIG_FEATURE_FIND_DELETE=y +CONFIG_FEATURE_FIND_PATH=y +CONFIG_FEATURE_FIND_REGEX=y +# CONFIG_FEATURE_FIND_CONTEXT is not set +CONFIG_FEATURE_FIND_LINKS=y +CONFIG_GREP=y +CONFIG_FEATURE_GREP_EGREP_ALIAS=y +CONFIG_FEATURE_GREP_FGREP_ALIAS=y +CONFIG_FEATURE_GREP_CONTEXT=y +CONFIG_XARGS=y +CONFIG_FEATURE_XARGS_SUPPORT_CONFIRMATION=y +CONFIG_FEATURE_XARGS_SUPPORT_QUOTES=y +CONFIG_FEATURE_XARGS_SUPPORT_TERMOPT=y +CONFIG_FEATURE_XARGS_SUPPORT_ZERO_TERM=y +CONFIG_FEATURE_XARGS_SUPPORT_REPL_STR=y + +# +# Init Utilities +# +CONFIG_BOOTCHARTD=y +CONFIG_FEATURE_BOOTCHARTD_BLOATED_HEADER=y +CONFIG_FEATURE_BOOTCHARTD_CONFIG_FILE=y +CONFIG_HALT=y +# CONFIG_FEATURE_CALL_TELINIT is not set +CONFIG_TELINIT_PATH="" +CONFIG_INIT=y +CONFIG_FEATURE_USE_INITTAB=y +# CONFIG_FEATURE_KILL_REMOVED is not set +CONFIG_FEATURE_KILL_DELAY=0 +CONFIG_FEATURE_INIT_SCTTY=y +CONFIG_FEATURE_INIT_SYSLOG=y +CONFIG_FEATURE_EXTRA_QUIET=y +CONFIG_FEATURE_INIT_COREDUMPS=y +CONFIG_FEATURE_INITRD=y +CONFIG_INIT_TERMINAL_TYPE="linux" +CONFIG_FEATURE_INIT_MODIFY_CMDLINE=y +CONFIG_MESG=y +CONFIG_FEATURE_MESG_ENABLE_ONLY_GROUP=y + +# +# Login/Password Management Utilities +# +# CONFIG_FEATURE_SHADOWPASSWDS is not set +# CONFIG_USE_BB_PWD_GRP is not set +# CONFIG_USE_BB_SHADOW is not set +CONFIG_USE_BB_CRYPT=y +CONFIG_USE_BB_CRYPT_SHA=y +CONFIG_ADD_SHELL=y +CONFIG_REMOVE_SHELL=y +# CONFIG_ADDGROUP is not set +# CONFIG_FEATURE_ADDGROUP_LONG_OPTIONS is not set +# CONFIG_FEATURE_ADDUSER_TO_GROUP is not set +# CONFIG_ADDUSER is not set +# CONFIG_FEATURE_ADDUSER_LONG_OPTIONS is not set +# CONFIG_FEATURE_CHECK_NAMES is not set +CONFIG_LAST_ID=0 +CONFIG_FIRST_SYSTEM_ID=0 +CONFIG_LAST_SYSTEM_ID=0 +CONFIG_CHPASSWD=y +CONFIG_FEATURE_DEFAULT_PASSWD_ALGO="des" +CONFIG_CRYPTPW=y +# CONFIG_DELUSER is not set +# CONFIG_DELGROUP is not set +# CONFIG_FEATURE_DEL_USER_FROM_GROUP is not set +CONFIG_GETTY=y +CONFIG_LOGIN=y +# CONFIG_LOGIN_SESSION_AS_CHILD is not set +CONFIG_LOGIN_SCRIPTS=y +CONFIG_FEATURE_NOLOGIN=y +CONFIG_FEATURE_SECURETTY=y +CONFIG_PASSWD=y +CONFIG_FEATURE_PASSWD_WEAK_CHECK=y +CONFIG_SU=y +CONFIG_FEATURE_SU_SYSLOG=y +CONFIG_FEATURE_SU_CHECKS_SHELLS=y +CONFIG_SULOGIN=y +CONFIG_VLOCK=y + +# +# Linux Ext2 FS Progs +# +CONFIG_CHATTR=y +CONFIG_FSCK=y +CONFIG_LSATTR=y +# CONFIG_TUNE2FS is not set + +# +# Linux Module Utilities +# +CONFIG_MODINFO=y +CONFIG_MODPROBE_SMALL=y +CONFIG_FEATURE_MODPROBE_SMALL_OPTIONS_ON_CMDLINE=y +CONFIG_FEATURE_MODPROBE_SMALL_CHECK_ALREADY_LOADED=y +# CONFIG_INSMOD is not set +# CONFIG_RMMOD is not set +# CONFIG_LSMOD is not set +# CONFIG_FEATURE_LSMOD_PRETTY_2_6_OUTPUT is not set +# CONFIG_MODPROBE is not set +# CONFIG_FEATURE_MODPROBE_BLACKLIST is not set +# CONFIG_DEPMOD is not set + +# +# Options common to multiple modutils +# +# CONFIG_FEATURE_2_4_MODULES is not set +# CONFIG_FEATURE_INSMOD_TRY_MMAP is not set +# CONFIG_FEATURE_INSMOD_VERSION_CHECKING is not set +# CONFIG_FEATURE_INSMOD_KSYMOOPS_SYMBOLS is not set +# CONFIG_FEATURE_INSMOD_LOADINKMEM is not set +# CONFIG_FEATURE_INSMOD_LOAD_MAP is not set +# CONFIG_FEATURE_INSMOD_LOAD_MAP_FULL is not set +# CONFIG_FEATURE_CHECK_TAINTED_MODULE is not set +# CONFIG_FEATURE_MODUTILS_ALIAS is not set +# CONFIG_FEATURE_MODUTILS_SYMBOLS is not set +CONFIG_DEFAULT_MODULES_DIR="/lib/modules" +CONFIG_DEFAULT_DEPMOD_FILE="modules.dep" + +# +# Linux System Utilities +# +CONFIG_BLKDISCARD=y +CONFIG_BLOCKDEV=y +CONFIG_FATATTR=y +CONFIG_FSTRIM=y +# CONFIG_MDEV is not set +# CONFIG_FEATURE_MDEV_CONF is not set +# CONFIG_FEATURE_MDEV_RENAME is not set +# CONFIG_FEATURE_MDEV_RENAME_REGEXP is not set +# CONFIG_FEATURE_MDEV_EXEC is not set +# CONFIG_FEATURE_MDEV_LOAD_FIRMWARE is not set +CONFIG_MOUNT=y +CONFIG_FEATURE_MOUNT_FAKE=y +CONFIG_FEATURE_MOUNT_VERBOSE=y +# CONFIG_FEATURE_MOUNT_HELPERS is not set +CONFIG_FEATURE_MOUNT_LABEL=y +# CONFIG_FEATURE_MOUNT_NFS is not set +CONFIG_FEATURE_MOUNT_CIFS=y +CONFIG_FEATURE_MOUNT_FLAGS=y +CONFIG_FEATURE_MOUNT_FSTAB=y +CONFIG_FEATURE_MOUNT_OTHERTAB=y +CONFIG_REV=y +CONFIG_SETARCH=y +CONFIG_UEVENT=y +CONFIG_ACPID=y +CONFIG_FEATURE_ACPID_COMPAT=y +CONFIG_BLKID=y +# CONFIG_FEATURE_BLKID_TYPE is not set +CONFIG_DMESG=y +CONFIG_FEATURE_DMESG_PRETTY=y +CONFIG_FBSET=y +CONFIG_FEATURE_FBSET_FANCY=y +CONFIG_FEATURE_FBSET_READMODE=y +CONFIG_FDFLUSH=y +CONFIG_FDFORMAT=y +CONFIG_FDISK=y +CONFIG_FDISK_SUPPORT_LARGE_DISKS=y +CONFIG_FEATURE_FDISK_WRITABLE=y +# CONFIG_FEATURE_AIX_LABEL is not set +# CONFIG_FEATURE_SGI_LABEL is not set +# CONFIG_FEATURE_SUN_LABEL is not set +# CONFIG_FEATURE_OSF_LABEL is not set +# CONFIG_FEATURE_GPT_LABEL is not set +CONFIG_FEATURE_FDISK_ADVANCED=y +CONFIG_FINDFS=y +CONFIG_FLOCK=y +CONFIG_FREERAMDISK=y +# CONFIG_FSCK_MINIX is not set +CONFIG_MKFS_EXT2=y +# CONFIG_MKFS_MINIX is not set +# CONFIG_FEATURE_MINIX2 is not set +# CONFIG_MKFS_REISER is not set +CONFIG_MKFS_VFAT=y +CONFIG_GETOPT=y +CONFIG_FEATURE_GETOPT_LONG=y +CONFIG_HEXDUMP=y +CONFIG_FEATURE_HEXDUMP_REVERSE=y +CONFIG_HD=y +CONFIG_HWCLOCK=y +CONFIG_FEATURE_HWCLOCK_LONG_OPTIONS=y +# CONFIG_FEATURE_HWCLOCK_ADJTIME_FHS is not set +# CONFIG_IPCRM is not set +# CONFIG_IPCS is not set +CONFIG_LOSETUP=y +CONFIG_LSPCI=y +CONFIG_LSUSB=y +CONFIG_MKSWAP=y +CONFIG_FEATURE_MKSWAP_UUID=y +CONFIG_MORE=y +CONFIG_PIVOT_ROOT=y +CONFIG_RDATE=y +CONFIG_RDEV=y +CONFIG_READPROFILE=y +CONFIG_RTCWAKE=y +CONFIG_SCRIPT=y +CONFIG_SCRIPTREPLAY=y +# CONFIG_SWAPONOFF is not set +# CONFIG_FEATURE_SWAPON_DISCARD is not set +# CONFIG_FEATURE_SWAPON_PRI is not set +CONFIG_SWITCH_ROOT=y +CONFIG_UMOUNT=y +CONFIG_FEATURE_UMOUNT_ALL=y + +# +# Common options for mount/umount +# +CONFIG_FEATURE_MOUNT_LOOP=y +CONFIG_FEATURE_MOUNT_LOOP_CREATE=y +# CONFIG_FEATURE_MTAB_SUPPORT is not set +CONFIG_VOLUMEID=y + +# +# Filesystem/Volume identification +# +CONFIG_FEATURE_VOLUMEID_BCACHE=y +CONFIG_FEATURE_VOLUMEID_BTRFS=y +CONFIG_FEATURE_VOLUMEID_CRAMFS=y +CONFIG_FEATURE_VOLUMEID_EXFAT=y +CONFIG_FEATURE_VOLUMEID_EXT=y +CONFIG_FEATURE_VOLUMEID_F2FS=y +CONFIG_FEATURE_VOLUMEID_FAT=y +CONFIG_FEATURE_VOLUMEID_HFS=y +CONFIG_FEATURE_VOLUMEID_ISO9660=y +CONFIG_FEATURE_VOLUMEID_JFS=y +CONFIG_FEATURE_VOLUMEID_LINUXRAID=y +CONFIG_FEATURE_VOLUMEID_LINUXSWAP=y +CONFIG_FEATURE_VOLUMEID_LUKS=y +CONFIG_FEATURE_VOLUMEID_NILFS=y +CONFIG_FEATURE_VOLUMEID_NTFS=y +CONFIG_FEATURE_VOLUMEID_OCFS2=y +CONFIG_FEATURE_VOLUMEID_REISERFS=y +CONFIG_FEATURE_VOLUMEID_ROMFS=y +# CONFIG_FEATURE_VOLUMEID_SQUASHFS is not set +CONFIG_FEATURE_VOLUMEID_SYSV=y +CONFIG_FEATURE_VOLUMEID_UDF=y +CONFIG_FEATURE_VOLUMEID_XFS=y + +# +# Miscellaneous Utilities +# +# CONFIG_CONSPY is not set +CONFIG_CROND=y +CONFIG_FEATURE_CROND_D=y +CONFIG_FEATURE_CROND_CALL_SENDMAIL=y +CONFIG_FEATURE_CROND_DIR="/var/spool/cron" +CONFIG_I2CGET=y +CONFIG_I2CSET=y +CONFIG_I2CDUMP=y +CONFIG_I2CDETECT=y +CONFIG_LESS=y +CONFIG_FEATURE_LESS_MAXLINES=9999999 +CONFIG_FEATURE_LESS_BRACKETS=y +CONFIG_FEATURE_LESS_FLAGS=y +CONFIG_FEATURE_LESS_TRUNCATE=y +CONFIG_FEATURE_LESS_MARKS=y +CONFIG_FEATURE_LESS_REGEXP=y +CONFIG_FEATURE_LESS_WINCH=y +CONFIG_FEATURE_LESS_ASK_TERMINAL=y +CONFIG_FEATURE_LESS_DASHCMD=y +CONFIG_FEATURE_LESS_LINENUMS=y +# CONFIG_NANDWRITE is not set +# CONFIG_NANDDUMP is not set +# CONFIG_RFKILL is not set +CONFIG_SETSERIAL=y +CONFIG_TASKSET=y +CONFIG_FEATURE_TASKSET_FANCY=y +# CONFIG_UBIATTACH is not set +# CONFIG_UBIDETACH is not set +# CONFIG_UBIMKVOL is not set +# CONFIG_UBIRMVOL is not set +# CONFIG_UBIRSVOL is not set +# CONFIG_UBIUPDATEVOL is not set +# CONFIG_WALL is not set +CONFIG_ADJTIMEX=y +# CONFIG_BBCONFIG is not set +# CONFIG_FEATURE_COMPRESS_BBCONFIG is not set +CONFIG_BEEP=y +CONFIG_FEATURE_BEEP_FREQ=4000 +CONFIG_FEATURE_BEEP_LENGTH_MS=30 +CONFIG_CHAT=y +CONFIG_FEATURE_CHAT_NOFAIL=y +# CONFIG_FEATURE_CHAT_TTY_HIFI is not set +CONFIG_FEATURE_CHAT_IMPLICIT_CR=y +CONFIG_FEATURE_CHAT_SWALLOW_OPTS=y +CONFIG_FEATURE_CHAT_SEND_ESCAPES=y +CONFIG_FEATURE_CHAT_VAR_ABORT_LEN=y +CONFIG_FEATURE_CHAT_CLR_ABORT=y +CONFIG_CHRT=y +CONFIG_CRONTAB=y +CONFIG_DC=y +CONFIG_FEATURE_DC_LIBM=y +# CONFIG_DEVFSD is not set +# CONFIG_DEVFSD_MODLOAD is not set +# CONFIG_DEVFSD_FG_NP is not set +# CONFIG_DEVFSD_VERBOSE is not set +# CONFIG_FEATURE_DEVFS is not set +CONFIG_DEVMEM=y +CONFIG_EJECT=y +# CONFIG_FEATURE_EJECT_SCSI is not set +CONFIG_FBSPLASH=y +# CONFIG_FLASHCP is not set +# CONFIG_FLASH_LOCK is not set +# CONFIG_FLASH_UNLOCK is not set +# CONFIG_FLASH_ERASEALL is not set +CONFIG_IONICE=y +# CONFIG_INOTIFYD is not set +# CONFIG_LAST is not set +# CONFIG_FEATURE_LAST_FANCY is not set +CONFIG_HDPARM=y +CONFIG_FEATURE_HDPARM_GET_IDENTITY=y +CONFIG_FEATURE_HDPARM_HDIO_SCAN_HWIF=y +CONFIG_FEATURE_HDPARM_HDIO_UNREGISTER_HWIF=y +CONFIG_FEATURE_HDPARM_HDIO_DRIVE_RESET=y +CONFIG_FEATURE_HDPARM_HDIO_TRISTATE_HWIF=y +CONFIG_FEATURE_HDPARM_HDIO_GETSET_DMA=y +CONFIG_MAKEDEVS=y +# CONFIG_FEATURE_MAKEDEVS_LEAF is not set +CONFIG_FEATURE_MAKEDEVS_TABLE=y +CONFIG_MAN=y +CONFIG_MICROCOM=y +CONFIG_MOUNTPOINT=y +# CONFIG_MT is not set +CONFIG_RAIDAUTORUN=y +# CONFIG_READAHEAD is not set +# CONFIG_RUNLEVEL is not set +CONFIG_RX=y +CONFIG_SETSID=y +CONFIG_STRINGS=y +CONFIG_TIME=y +CONFIG_TIMEOUT=y +CONFIG_TTYSIZE=y +CONFIG_VOLNAME=y +CONFIG_WATCHDOG=y + +# +# Networking Utilities +# +CONFIG_NAMEIF=y +CONFIG_FEATURE_NAMEIF_EXTENDED=y +CONFIG_NBDCLIENT=y +CONFIG_NC=y +CONFIG_NC_SERVER=y +CONFIG_NC_EXTRA=y +# CONFIG_NC_110_COMPAT is not set +CONFIG_PING=y +CONFIG_PING6=y +CONFIG_FEATURE_FANCY_PING=y +CONFIG_WGET=y +CONFIG_FEATURE_WGET_STATUSBAR=y +CONFIG_FEATURE_WGET_AUTHENTICATION=y +CONFIG_FEATURE_WGET_LONG_OPTIONS=y +CONFIG_FEATURE_WGET_TIMEOUT=y +CONFIG_FEATURE_WGET_OPENSSL=y +CONFIG_FEATURE_WGET_SSL_HELPER=y +CONFIG_WHOIS=y +CONFIG_FEATURE_IPV6=y +# CONFIG_FEATURE_UNIX_LOCAL is not set +CONFIG_FEATURE_PREFER_IPV4_ADDRESS=y +# CONFIG_VERBOSE_RESOLUTION_ERRORS is not set +# CONFIG_ARP is not set +# CONFIG_ARPING is not set +CONFIG_BRCTL=y +CONFIG_FEATURE_BRCTL_FANCY=y +CONFIG_FEATURE_BRCTL_SHOW=y +CONFIG_DNSD=y +# CONFIG_ETHER_WAKE is not set +CONFIG_FAKEIDENTD=y +CONFIG_FTPD=y +CONFIG_FEATURE_FTP_WRITE=y +CONFIG_FEATURE_FTPD_ACCEPT_BROKEN_LIST=y +CONFIG_FEATURE_FTP_AUTHENTICATION=y +CONFIG_FTPGET=y +CONFIG_FTPPUT=y +CONFIG_FEATURE_FTPGETPUT_LONG_OPTIONS=y +CONFIG_HOSTNAME=y +CONFIG_HTTPD=y +CONFIG_FEATURE_HTTPD_RANGES=y +CONFIG_FEATURE_HTTPD_SETUID=y +CONFIG_FEATURE_HTTPD_BASIC_AUTH=y +CONFIG_FEATURE_HTTPD_AUTH_MD5=y +CONFIG_FEATURE_HTTPD_CGI=y +CONFIG_FEATURE_HTTPD_CONFIG_WITH_SCRIPT_INTERPR=y +CONFIG_FEATURE_HTTPD_SET_REMOTE_PORT_TO_ENV=y +CONFIG_FEATURE_HTTPD_ENCODE_URL_STR=y +CONFIG_FEATURE_HTTPD_ERROR_PAGES=y +CONFIG_FEATURE_HTTPD_PROXY=y +CONFIG_FEATURE_HTTPD_GZIP=y +# CONFIG_IFCONFIG is not set +# CONFIG_FEATURE_IFCONFIG_STATUS is not set +# CONFIG_FEATURE_IFCONFIG_SLIP is not set +# CONFIG_FEATURE_IFCONFIG_MEMSTART_IOADDR_IRQ is not set +# CONFIG_FEATURE_IFCONFIG_HW is not set +# CONFIG_FEATURE_IFCONFIG_BROADCAST_PLUS is not set +# CONFIG_IFENSLAVE is not set +CONFIG_IFPLUGD=y +CONFIG_IFUPDOWN=y +CONFIG_IFUPDOWN_IFSTATE_PATH="/var/run/ifstate" +CONFIG_FEATURE_IFUPDOWN_IP=y +CONFIG_FEATURE_IFUPDOWN_IP_BUILTIN=y +# CONFIG_FEATURE_IFUPDOWN_IFCONFIG_BUILTIN is not set +CONFIG_FEATURE_IFUPDOWN_IPV4=y +CONFIG_FEATURE_IFUPDOWN_IPV6=y +CONFIG_FEATURE_IFUPDOWN_MAPPING=y +# CONFIG_FEATURE_IFUPDOWN_EXTERNAL_DHCP is not set +CONFIG_INETD=y +CONFIG_FEATURE_INETD_SUPPORT_BUILTIN_ECHO=y +CONFIG_FEATURE_INETD_SUPPORT_BUILTIN_DISCARD=y +CONFIG_FEATURE_INETD_SUPPORT_BUILTIN_TIME=y +CONFIG_FEATURE_INETD_SUPPORT_BUILTIN_DAYTIME=y +CONFIG_FEATURE_INETD_SUPPORT_BUILTIN_CHARGEN=y +# CONFIG_FEATURE_INETD_RPC is not set +CONFIG_IP=y +CONFIG_FEATURE_IP_ADDRESS=y +CONFIG_FEATURE_IP_LINK=y +CONFIG_FEATURE_IP_ROUTE=y +CONFIG_FEATURE_IP_ROUTE_DIR="/etc/iproute2" +CONFIG_FEATURE_IP_TUNNEL=y +CONFIG_FEATURE_IP_RULE=y +CONFIG_FEATURE_IP_NEIGH=y +CONFIG_FEATURE_IP_SHORT_FORMS=y +# CONFIG_FEATURE_IP_RARE_PROTOCOLS is not set +CONFIG_IPADDR=y +CONFIG_IPLINK=y +CONFIG_IPROUTE=y +CONFIG_IPTUNNEL=y +CONFIG_IPRULE=y +CONFIG_IPNEIGH=y +CONFIG_IPCALC=y +CONFIG_FEATURE_IPCALC_FANCY=y +CONFIG_FEATURE_IPCALC_LONG_OPTIONS=y +CONFIG_NETSTAT=y +CONFIG_FEATURE_NETSTAT_WIDE=y +CONFIG_FEATURE_NETSTAT_PRG=y +# CONFIG_NSLOOKUP is not set +CONFIG_NTPD=y +CONFIG_FEATURE_NTPD_SERVER=y +CONFIG_FEATURE_NTPD_CONF=y +CONFIG_PSCAN=y +# CONFIG_ROUTE is not set +CONFIG_SLATTACH=y +CONFIG_TCPSVD=y +CONFIG_TELNET=y +CONFIG_FEATURE_TELNET_TTYPE=y +CONFIG_FEATURE_TELNET_AUTOLOGIN=y +CONFIG_TELNETD=y +CONFIG_FEATURE_TELNETD_STANDALONE=y +CONFIG_FEATURE_TELNETD_INETD_WAIT=y +CONFIG_TFTP=y +CONFIG_TFTPD=y + +# +# Common options for tftp/tftpd +# +CONFIG_FEATURE_TFTP_GET=y +CONFIG_FEATURE_TFTP_PUT=y +CONFIG_FEATURE_TFTP_BLOCKSIZE=y +CONFIG_FEATURE_TFTP_PROGRESS_BAR=y +# CONFIG_TFTP_DEBUG is not set +CONFIG_TRACEROUTE=y +CONFIG_TRACEROUTE6=y +CONFIG_FEATURE_TRACEROUTE_VERBOSE=y +# CONFIG_FEATURE_TRACEROUTE_SOURCE_ROUTE is not set +# CONFIG_FEATURE_TRACEROUTE_USE_ICMP is not set +CONFIG_TUNCTL=y +CONFIG_FEATURE_TUNCTL_UG=y +# CONFIG_UDHCPC6 is not set +CONFIG_UDHCPD=y +CONFIG_DHCPRELAY=y +CONFIG_DUMPLEASES=y +CONFIG_FEATURE_UDHCPD_WRITE_LEASES_EARLY=y +# CONFIG_FEATURE_UDHCPD_BASE_IP_ON_MAC is not set +CONFIG_DHCPD_LEASES_FILE="/var/lib/misc/udhcpd.leases" +CONFIG_UDHCPC=y +CONFIG_FEATURE_UDHCPC_ARPING=y +CONFIG_FEATURE_UDHCPC_SANITIZEOPT=y +# CONFIG_FEATURE_UDHCP_PORT is not set +CONFIG_UDHCP_DEBUG=9 +CONFIG_FEATURE_UDHCP_RFC3397=y +CONFIG_FEATURE_UDHCP_8021Q=y +CONFIG_UDHCPC_DEFAULT_SCRIPT="/usr/share/udhcpc/default.script" +CONFIG_UDHCPC_SLACK_FOR_BUGGY_SERVERS=80 +CONFIG_IFUPDOWN_UDHCPC_CMD_OPTIONS="-R -n" +CONFIG_UDPSVD=y +CONFIG_VCONFIG=y +# CONFIG_ZCIP is not set + +# +# Print Utilities +# +CONFIG_LPD=y +CONFIG_LPR=y +CONFIG_LPQ=y + +# +# Mail Utilities +# +CONFIG_MAKEMIME=y +CONFIG_FEATURE_MIME_CHARSET="us-ascii" +CONFIG_POPMAILDIR=y +CONFIG_FEATURE_POPMAILDIR_DELIVERY=y +CONFIG_REFORMIME=y +CONFIG_FEATURE_REFORMIME_COMPAT=y +CONFIG_SENDMAIL=y + +# +# Process Utilities +# +CONFIG_IOSTAT=y +CONFIG_LSOF=y +CONFIG_MPSTAT=y +CONFIG_NMETER=y +CONFIG_PMAP=y +CONFIG_POWERTOP=y +CONFIG_PSTREE=y +CONFIG_PWDX=y +CONFIG_SMEMCAP=y +CONFIG_TOP=y +CONFIG_FEATURE_TOP_CPU_USAGE_PERCENTAGE=y +CONFIG_FEATURE_TOP_CPU_GLOBAL_PERCENTS=y +CONFIG_FEATURE_TOP_SMP_CPU=y +CONFIG_FEATURE_TOP_DECIMALS=y +CONFIG_FEATURE_TOP_SMP_PROCESS=y +CONFIG_FEATURE_TOPMEM=y +CONFIG_UPTIME=y +# CONFIG_FEATURE_UPTIME_UTMP_SUPPORT is not set +CONFIG_FREE=y +CONFIG_FUSER=y +CONFIG_KILL=y +CONFIG_KILLALL=y +CONFIG_KILLALL5=y +CONFIG_PGREP=y +CONFIG_PIDOF=y +CONFIG_FEATURE_PIDOF_SINGLE=y +CONFIG_FEATURE_PIDOF_OMIT=y +CONFIG_PKILL=y +CONFIG_PS=y +# CONFIG_FEATURE_PS_WIDE is not set +# CONFIG_FEATURE_PS_LONG is not set +CONFIG_FEATURE_PS_TIME=y +CONFIG_FEATURE_PS_ADDITIONAL_COLUMNS=y +# CONFIG_FEATURE_PS_UNUSUAL_SYSTEMS is not set +CONFIG_RENICE=y +CONFIG_BB_SYSCTL=y +CONFIG_FEATURE_SHOW_THREADS=y +CONFIG_WATCH=y + +# +# Runit Utilities +# +CONFIG_CHPST=y +CONFIG_SETUIDGID=y +CONFIG_ENVUIDGID=y +CONFIG_ENVDIR=y +CONFIG_SOFTLIMIT=y +CONFIG_RUNSV=y +CONFIG_RUNSVDIR=y +# CONFIG_FEATURE_RUNSVDIR_LOG is not set +CONFIG_SV=y +CONFIG_SV_DEFAULT_SERVICE_DIR="/var/service" +CONFIG_SVLOGD=y +# CONFIG_CHCON is not set +# CONFIG_FEATURE_CHCON_LONG_OPTIONS is not set +# CONFIG_GETENFORCE is not set +# CONFIG_GETSEBOOL is not set +# CONFIG_LOAD_POLICY is not set +# CONFIG_MATCHPATHCON is not set +# CONFIG_RESTORECON is not set +# CONFIG_RUNCON is not set +# CONFIG_FEATURE_RUNCON_LONG_OPTIONS is not set +# CONFIG_SELINUXENABLED is not set +# CONFIG_SETENFORCE is not set +# CONFIG_SETFILES is not set +# CONFIG_FEATURE_SETFILES_CHECK_OPTION is not set +# CONFIG_SETSEBOOL is not set +# CONFIG_SESTATUS is not set + +# +# Shells +# +CONFIG_ASH=y +CONFIG_ASH_BASH_COMPAT=y +# CONFIG_ASH_IDLE_TIMEOUT is not set +CONFIG_ASH_JOB_CONTROL=y +CONFIG_ASH_ALIAS=y +CONFIG_ASH_GETOPTS=y +CONFIG_ASH_BUILTIN_ECHO=y +CONFIG_ASH_BUILTIN_PRINTF=y +CONFIG_ASH_BUILTIN_TEST=y +CONFIG_ASH_HELP=y +CONFIG_ASH_CMDCMD=y +# CONFIG_ASH_MAIL is not set +CONFIG_ASH_OPTIMIZE_FOR_SIZE=y +CONFIG_ASH_RANDOM_SUPPORT=y +CONFIG_ASH_EXPAND_PRMT=y +CONFIG_CTTYHACK=y +# CONFIG_HUSH is not set +# CONFIG_HUSH_BASH_COMPAT is not set +# CONFIG_HUSH_BRACE_EXPANSION is not set +# CONFIG_HUSH_HELP is not set +# CONFIG_HUSH_INTERACTIVE is not set +# CONFIG_HUSH_SAVEHISTORY is not set +# CONFIG_HUSH_JOB is not set +# CONFIG_HUSH_TICK is not set +# CONFIG_HUSH_IF is not set +# CONFIG_HUSH_LOOPS is not set +# CONFIG_HUSH_CASE is not set +# CONFIG_HUSH_FUNCTIONS is not set +# CONFIG_HUSH_LOCAL is not set +# CONFIG_HUSH_RANDOM_SUPPORT is not set +# CONFIG_HUSH_EXPORT_N is not set +# CONFIG_HUSH_MODE_X is not set +# CONFIG_MSH is not set +CONFIG_FEATURE_SH_IS_ASH=y +# CONFIG_FEATURE_SH_IS_HUSH is not set +# CONFIG_FEATURE_SH_IS_NONE is not set +# CONFIG_FEATURE_BASH_IS_ASH is not set +# CONFIG_FEATURE_BASH_IS_HUSH is not set +CONFIG_FEATURE_BASH_IS_NONE=y +CONFIG_SH_MATH_SUPPORT=y +CONFIG_SH_MATH_SUPPORT_64=y +CONFIG_FEATURE_SH_EXTRA_QUIET=y +# CONFIG_FEATURE_SH_STANDALONE is not set +# CONFIG_FEATURE_SH_NOFORK is not set +CONFIG_FEATURE_SH_HISTFILESIZE=y + +# +# System Logging Utilities +# +# CONFIG_KLOGD is not set +# CONFIG_FEATURE_KLOGD_KLOGCTL is not set +# CONFIG_LOGGER is not set +# CONFIG_LOGREAD is not set +# CONFIG_FEATURE_LOGREAD_REDUCED_LOCKING is not set +# CONFIG_SYSLOGD is not set +# CONFIG_FEATURE_ROTATE_LOGFILE is not set +# CONFIG_FEATURE_REMOTE_LOG is not set +# CONFIG_FEATURE_SYSLOGD_DUP is not set +# CONFIG_FEATURE_SYSLOGD_CFG is not set +CONFIG_FEATURE_SYSLOGD_READ_BUFFER_SIZE=0 +# CONFIG_FEATURE_IPC_SYSLOG is not set +CONFIG_FEATURE_IPC_SYSLOG_BUFFER_SIZE=0 +# CONFIG_FEATURE_KMSG_SYSLOG is not set From e4de8c631644be5e96711462763bf16491dda54f Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Tue, 15 Mar 2016 15:22:42 +0100 Subject: [PATCH 157/260] nmeter: fix a bug with unterminated varargs function old new delta collect_mem 361 371 +10 collect_swp 116 120 +4 vrdval 168 170 +2 collect_thread_nr 63 65 +2 collect_int 121 123 +2 collect_if 205 207 +2 collect_fork 117 119 +2 collect_fd 79 81 +2 collect_ctx 117 119 +2 collect_cpu 621 623 +2 collect_blk 557 559 +2 ------------------------------------------------------------------------------ (add/remove: 0/0 grow/shrink: 11/0 up/down: 32/0) Total: 32 bytes Signed-off-by: Denys Vlasenko --- procps/nmeter.c | 32 +++++++++++++++++--------------- 1 file changed, 17 insertions(+), 15 deletions(-) diff --git a/procps/nmeter.c b/procps/nmeter.c index 5d5b83b8d..0ce6842e7 100644 --- a/procps/nmeter.c +++ b/procps/nmeter.c @@ -235,6 +235,8 @@ static int vrdval(const char* p, const char* key, strtoull(p, NULL, 10) : read_after_slash(p); indexnext = va_arg(arg_ptr, int); + if (!indexnext) + return 0; } while (*p > ' ') p++; // skip over value indexline++; @@ -395,7 +397,7 @@ static void FAST_FUNC collect_cpu(cpu_stat *s) char *bar = s->bar; int i; - if (rdval(get_file(&proc_stat), "cpu ", data, 1, 2, 3, 4, 5, 6, 7)) { + if (rdval(get_file(&proc_stat), "cpu ", data, 1, 2, 3, 4, 5, 6, 7, 0)) { put_question_marks(bar_sz); return; } @@ -464,7 +466,7 @@ static void FAST_FUNC collect_int(int_stat *s) ullong data[1]; ullong old; - if (rdval(get_file(&proc_stat), "intr", data, s->no)) { + if (rdval(get_file(&proc_stat), "intr", data, s->no, 0)) { put_question_marks(4); return; } @@ -498,7 +500,7 @@ static void FAST_FUNC collect_ctx(ctx_stat *s) ullong data[1]; ullong old; - if (rdval(get_file(&proc_stat), "ctxt", data, 1)) { + if (rdval(get_file(&proc_stat), "ctxt", data, 1, 0)) { put_question_marks(4); return; } @@ -530,7 +532,7 @@ static void FAST_FUNC collect_blk(blk_stat *s) if (is26) { i = rdval_diskstats(get_file(&proc_diskstats), data); } else { - i = rdval(get_file(&proc_stat), s->lookfor, data, 1, 2); + i = rdval(get_file(&proc_stat), s->lookfor, data, 1, 2, 0); // Linux 2.4 reports bio in Kbytes, convert to sectors: data[0] *= 2; data[1] *= 2; @@ -568,7 +570,7 @@ static void FAST_FUNC collect_thread_nr(fork_stat *s UNUSED_PARAM) { ullong data[1]; - if (rdval_loadavg(get_file(&proc_loadavg), data, 4)) { + if (rdval_loadavg(get_file(&proc_loadavg), data, 4, 0)) { put_question_marks(4); return; } @@ -580,7 +582,7 @@ static void FAST_FUNC collect_fork(fork_stat *s) ullong data[1]; ullong old; - if (rdval(get_file(&proc_stat), "processes", data, 1)) { + if (rdval(get_file(&proc_stat), "processes", data, 1, 0)) { put_question_marks(4); return; } @@ -614,7 +616,7 @@ static void FAST_FUNC collect_if(if_stat *s) ullong data[4]; int i; - if (rdval(get_file(&proc_net_dev), s->device_colon, data, 1, 3, 9, 11)) { + if (rdval(get_file(&proc_net_dev), s->device_colon, data, 1, 3, 9, 11, 0)) { put_question_marks(10); return; } @@ -692,7 +694,7 @@ static void FAST_FUNC collect_mem(mem_stat *s) ullong m_cached = 0; ullong m_slab = 0; - if (rdval(get_file(&proc_meminfo), "MemTotal:", &m_total, 1)) { + if (rdval(get_file(&proc_meminfo), "MemTotal:", &m_total, 1, 0)) { put_question_marks(4); return; } @@ -701,10 +703,10 @@ static void FAST_FUNC collect_mem(mem_stat *s) return; } - if (rdval(proc_meminfo.file, "MemFree:", &m_free , 1) - || rdval(proc_meminfo.file, "Buffers:", &m_bufs , 1) - || rdval(proc_meminfo.file, "Cached:", &m_cached, 1) - || rdval(proc_meminfo.file, "Slab:", &m_slab , 1) + if (rdval(proc_meminfo.file, "MemFree:", &m_free , 1, 0) + || rdval(proc_meminfo.file, "Buffers:", &m_bufs , 1, 0) + || rdval(proc_meminfo.file, "Cached:", &m_cached, 1, 0) + || rdval(proc_meminfo.file, "Slab:", &m_slab , 1, 0) ) { put_question_marks(4); return; @@ -735,8 +737,8 @@ static void FAST_FUNC collect_swp(swp_stat *s UNUSED_PARAM) { ullong s_total[1]; ullong s_free[1]; - if (rdval(get_file(&proc_meminfo), "SwapTotal:", s_total, 1) - || rdval(proc_meminfo.file, "SwapFree:" , s_free, 1) + if (rdval(get_file(&proc_meminfo), "SwapTotal:", s_total, 1, 0) + || rdval(proc_meminfo.file, "SwapFree:" , s_free, 1, 0) ) { put_question_marks(4); return; @@ -759,7 +761,7 @@ static void FAST_FUNC collect_fd(fd_stat *s UNUSED_PARAM) { ullong data[2]; - if (rdval(get_file(&proc_sys_fs_filenr), "", data, 1, 2)) { + if (rdval(get_file(&proc_sys_fs_filenr), "", data, 1, 2, 0)) { put_question_marks(4); return; } From 99c71c9e800d51aa52d7bd592e8071341013a628 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Tue, 15 Mar 2016 15:28:49 +0100 Subject: [PATCH 158/260] nmeter: code shrink function old new delta put 52 43 -9 Signed-off-by: Denys Vlasenko --- procps/nmeter.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/procps/nmeter.c b/procps/nmeter.c index 0ce6842e7..8fe39c43b 100644 --- a/procps/nmeter.c +++ b/procps/nmeter.c @@ -142,11 +142,11 @@ static void print_outbuf(void) static void put(const char *s) { - int sz = strlen(s); - if (sz > outbuf + sizeof(outbuf) - cur_outbuf) - sz = outbuf + sizeof(outbuf) - cur_outbuf; - memcpy(cur_outbuf, s, sz); - cur_outbuf += sz; + char *p = cur_outbuf; + int sz = outbuf + sizeof(outbuf) - p; + while (*s && --sz >= 0) + *p++ = *s++; + cur_outbuf = p; } static void put_c(char c) From 8a26fda98c46b1ffd98a1a9874a0899b061226d8 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Tue, 15 Mar 2016 15:52:40 +0100 Subject: [PATCH 159/260] nmeter: convert field list to bit list function old new delta rdval 34 157 +123 collect_int 123 122 -1 collect_thread_nr 65 62 -3 collect_blk 559 552 -7 collect_if 207 199 -8 collect_fork 119 111 -8 collect_ctx 119 111 -8 collect_fd 81 71 -10 collect_swp 120 107 -13 collect_cpu 623 610 -13 collect_mem 371 339 -32 rdval_loadavg 38 - -38 vrdval 170 - -170 ------------------------------------------------------------------------------ (add/remove: 0/2 grow/shrink: 1/10 up/down: 123/-311) Total: -188 bytes Signed-off-by: Denys Vlasenko --- procps/nmeter.c | 106 ++++++++++++++++++++++++------------------------ 1 file changed, 54 insertions(+), 52 deletions(-) diff --git a/procps/nmeter.c b/procps/nmeter.c index 8fe39c43b..d6222af6b 100644 --- a/procps/nmeter.c +++ b/procps/nmeter.c @@ -208,67 +208,50 @@ static ullong read_after_slash(const char *p) return strtoull(p+1, NULL, 10); } -enum conv_type { conv_decimal, conv_slash }; +enum conv_type { + conv_decimal = 0, + conv_slash = 1 +}; // Reads decimal values from line. Values start after key, for example: // "cpu 649369 0 341297 4336769..." - key is "cpu" here. -// Values are stored in vec[]. arg_ptr has list of positions -// we are interested in: for example: 1,2,5 - we want 1st, 2nd and 5th value. -static int vrdval(const char* p, const char* key, - enum conv_type conv, ullong *vec, va_list arg_ptr) +// Values are stored in vec[]. +// posbits is a bit lit of positions we are interested in. +// for example: 00100110 - we want 1st, 2nd and 5th value. +// posbits.bit0 encodes conversion type. +static int rdval(const char* p, const char* key, ullong *vec, long posbits) { - int indexline; - int indexnext; + unsigned curpos; p = strstr(p, key); if (!p) return 1; p += strlen(key); - indexline = 1; - indexnext = va_arg(arg_ptr, int); + curpos = 1 << 1; while (1) { while (*p == ' ' || *p == '\t') p++; if (*p == '\n' || *p == '\0') break; - if (indexline == indexnext) { // read this value - *vec++ = conv==conv_decimal ? + if (curpos & posbits) { // read this value + *vec++ = (posbits & 1) == conv_decimal ? strtoull(p, NULL, 10) : read_after_slash(p); - indexnext = va_arg(arg_ptr, int); - if (!indexnext) + posbits -= curpos; + if (posbits <= 1) return 0; } - while (*p > ' ') p++; // skip over value - indexline++; + while (*p > ' ') // skip over the value + p++; + curpos <<= 1; } return 0; } -// Parses files with lines like "cpu0 21727 0 15718 1813856 9461 10485 0 0": -// rdval(file_contents, "string_to_find", result_vector, value#, value#...) -// value# start with 1 -static int rdval(const char* p, const char* key, ullong *vec, ...) -{ - va_list arg_ptr; - int result; - - va_start(arg_ptr, vec); - result = vrdval(p, key, conv_decimal, vec, arg_ptr); - va_end(arg_ptr); - - return result; -} - // Parses files with lines like "... ... ... 3/148 ...." -static int rdval_loadavg(const char* p, ullong *vec, ...) +static int rdval_loadavg(const char* p, ullong *vec, long posbits) { - va_list arg_ptr; int result; - - va_start(arg_ptr, vec); - result = vrdval(p, "", conv_slash, vec, arg_ptr); - va_end(arg_ptr); - + result = rdval(p, "", vec, posbits | conv_slash); return result; } @@ -397,7 +380,15 @@ static void FAST_FUNC collect_cpu(cpu_stat *s) char *bar = s->bar; int i; - if (rdval(get_file(&proc_stat), "cpu ", data, 1, 2, 3, 4, 5, 6, 7, 0)) { + if (rdval(get_file(&proc_stat), "cpu ", data, 0 + | (1 << 1) + | (1 << 2) + | (1 << 3) + | (1 << 4) + | (1 << 5) + | (1 << 6) + | (1 << 7)) + ) { put_question_marks(bar_sz); return; } @@ -466,7 +457,7 @@ static void FAST_FUNC collect_int(int_stat *s) ullong data[1]; ullong old; - if (rdval(get_file(&proc_stat), "intr", data, s->no, 0)) { + if (rdval(get_file(&proc_stat), "intr", data, 1 << s->no)) { put_question_marks(4); return; } @@ -500,7 +491,7 @@ static void FAST_FUNC collect_ctx(ctx_stat *s) ullong data[1]; ullong old; - if (rdval(get_file(&proc_stat), "ctxt", data, 1, 0)) { + if (rdval(get_file(&proc_stat), "ctxt", data, 1 << 1)) { put_question_marks(4); return; } @@ -532,7 +523,10 @@ static void FAST_FUNC collect_blk(blk_stat *s) if (is26) { i = rdval_diskstats(get_file(&proc_diskstats), data); } else { - i = rdval(get_file(&proc_stat), s->lookfor, data, 1, 2, 0); + i = rdval(get_file(&proc_stat), s->lookfor, data, 0 + | (1 << 1) + | (1 << 2) + ); // Linux 2.4 reports bio in Kbytes, convert to sectors: data[0] *= 2; data[1] *= 2; @@ -570,7 +564,7 @@ static void FAST_FUNC collect_thread_nr(fork_stat *s UNUSED_PARAM) { ullong data[1]; - if (rdval_loadavg(get_file(&proc_loadavg), data, 4, 0)) { + if (rdval_loadavg(get_file(&proc_loadavg), data, 1 << 4)) { put_question_marks(4); return; } @@ -582,7 +576,7 @@ static void FAST_FUNC collect_fork(fork_stat *s) ullong data[1]; ullong old; - if (rdval(get_file(&proc_stat), "processes", data, 1, 0)) { + if (rdval(get_file(&proc_stat), "processes", data, 1 << 1)) { put_question_marks(4); return; } @@ -616,7 +610,12 @@ static void FAST_FUNC collect_if(if_stat *s) ullong data[4]; int i; - if (rdval(get_file(&proc_net_dev), s->device_colon, data, 1, 3, 9, 11, 0)) { + if (rdval(get_file(&proc_net_dev), s->device_colon, data, 0 + | (1 << 1) + | (1 << 3) + | (1 << 9) + | (1 << 11)) + ) { put_question_marks(10); return; } @@ -694,7 +693,7 @@ static void FAST_FUNC collect_mem(mem_stat *s) ullong m_cached = 0; ullong m_slab = 0; - if (rdval(get_file(&proc_meminfo), "MemTotal:", &m_total, 1, 0)) { + if (rdval(get_file(&proc_meminfo), "MemTotal:", &m_total, 1 << 1)) { put_question_marks(4); return; } @@ -703,10 +702,10 @@ static void FAST_FUNC collect_mem(mem_stat *s) return; } - if (rdval(proc_meminfo.file, "MemFree:", &m_free , 1, 0) - || rdval(proc_meminfo.file, "Buffers:", &m_bufs , 1, 0) - || rdval(proc_meminfo.file, "Cached:", &m_cached, 1, 0) - || rdval(proc_meminfo.file, "Slab:", &m_slab , 1, 0) + if (rdval(proc_meminfo.file, "MemFree:", &m_free , 1 << 1) + || rdval(proc_meminfo.file, "Buffers:", &m_bufs , 1 << 1) + || rdval(proc_meminfo.file, "Cached:", &m_cached, 1 << 1) + || rdval(proc_meminfo.file, "Slab:", &m_slab , 1 << 1) ) { put_question_marks(4); return; @@ -737,8 +736,8 @@ static void FAST_FUNC collect_swp(swp_stat *s UNUSED_PARAM) { ullong s_total[1]; ullong s_free[1]; - if (rdval(get_file(&proc_meminfo), "SwapTotal:", s_total, 1, 0) - || rdval(proc_meminfo.file, "SwapFree:" , s_free, 1, 0) + if (rdval(get_file(&proc_meminfo), "SwapTotal:", s_total, 1 << 1) + || rdval(proc_meminfo.file, "SwapFree:" , s_free, 1 << 1) ) { put_question_marks(4); return; @@ -761,7 +760,10 @@ static void FAST_FUNC collect_fd(fd_stat *s UNUSED_PARAM) { ullong data[2]; - if (rdval(get_file(&proc_sys_fs_filenr), "", data, 1, 2, 0)) { + if (rdval(get_file(&proc_sys_fs_filenr), "", data, 0 + | (1 << 1) + | (1 << 2)) + ) { put_question_marks(4); return; } From a63e2a8cb2dd0d6819c1844c52344c3bd6f73659 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Tue, 15 Mar 2016 16:06:29 +0100 Subject: [PATCH 160/260] nmeter: simple code shrink here and there function old new delta nmeter_main 709 707 -2 init_cr 15 12 -3 collect_time 141 131 -10 collect_cpu 610 593 -17 init_cpu 82 63 -19 ------------------------------------------------------------------------------ (add/remove: 0/0 grow/shrink: 0/5 up/down: 0/-51) Total: -51 bytes Signed-off-by: Denys Vlasenko --- procps/nmeter.c | 39 ++++++++++++--------------------------- 1 file changed, 12 insertions(+), 27 deletions(-) diff --git a/procps/nmeter.c b/procps/nmeter.c index d6222af6b..1cc908504 100644 --- a/procps/nmeter.c +++ b/procps/nmeter.c @@ -83,8 +83,8 @@ struct globals { smallint is26; // 1 if sample delay is not an integer fraction of a second smallint need_seconds; + char final_char; char *cur_outbuf; - const char *final_str; int delta; int deltanz; struct timeval tv; @@ -101,7 +101,6 @@ struct globals { #define is26 (G.is26 ) #define need_seconds (G.need_seconds ) #define cur_outbuf (G.cur_outbuf ) -#define final_str (G.final_str ) #define delta (G.delta ) #define deltanz (G.deltanz ) #define tv (G.tv ) @@ -114,7 +113,7 @@ struct globals { #define INIT_G() do { \ SET_PTR_TO_GLOBALS(xzalloc(sizeof(G))); \ cur_outbuf = outbuf; \ - final_str = "\n"; \ + G.final_char = '\n'; \ deltanz = delta = 1000000; \ } while (0) @@ -322,7 +321,6 @@ static void scale(ullong ul) put(buf); } - #define S_STAT(a) \ typedef struct a { \ struct s_stat *next; \ @@ -354,11 +352,10 @@ static s_stat* init_delay(const char *param) static s_stat* init_cr(const char *param UNUSED_PARAM) { - final_str = "\r"; - return (s_stat*)0; + G.final_char = '\r'; + return NULL; } - // user nice system idle iowait irq softirq (last 3 only in 2.6) //cpu 649369 0 341297 4336769 11640 7122 1183 //cpuN 649369 0 341297 4336769 11640 7122 1183 @@ -366,10 +363,9 @@ enum { CPU_FIELDCNT = 7 }; S_STAT(cpu_stat) ullong old[CPU_FIELDCNT]; int bar_sz; - char *bar; + char bar[1]; S_STAT_END(cpu_stat) - static void FAST_FUNC collect_cpu(cpu_stat *s) { ullong data[CPU_FIELDCNT] = { 0, 0, 0, 0, 0, 0, 0 }; @@ -431,22 +427,20 @@ static void FAST_FUNC collect_cpu(cpu_stat *s) put(s->bar); } - static s_stat* init_cpu(const char *param) { int sz; - cpu_stat *s = xzalloc(sizeof(*s)); - s->collect = collect_cpu; + cpu_stat *s; sz = strtoul(param, NULL, 0); /* param can be "" */ if (sz < 10) sz = 10; if (sz > 1000) sz = 1000; - s->bar = xzalloc(sz+1); + s = xzalloc(sizeof(*s) + sz); /*s->bar[sz] = '\0'; - xzalloc did it */ s->bar_sz = sz; + s->collect = collect_cpu; return (s_stat*)s; } - S_STAT(int_stat) ullong old; int no; @@ -481,7 +475,6 @@ static s_stat* init_int(const char *param) return (s_stat*)s; } - S_STAT(ctx_stat) ullong old; S_STAT_END(ctx_stat) @@ -509,7 +502,6 @@ static s_stat* init_ctx(const char *param UNUSED_PARAM) return (s_stat*)s; } - S_STAT(blk_stat) const char* lookfor; ullong old[2]; @@ -555,7 +547,6 @@ static s_stat* init_blk(const char *param UNUSED_PARAM) return (s_stat*)s; } - S_STAT(fork_stat) ullong old; S_STAT_END(fork_stat) @@ -598,7 +589,6 @@ static s_stat* init_fork(const char *param) return (s_stat*)s; } - S_STAT(if_stat) ullong old[4]; const char *device; @@ -645,7 +635,6 @@ static s_stat* init_if(const char *device) return (s_stat*)s; } - S_STAT(mem_stat) char opt; S_STAT_END(mem_stat) @@ -728,7 +717,6 @@ static s_stat* init_mem(const char *param) return (s_stat*)s; } - S_STAT(swp_stat) S_STAT_END(swp_stat) @@ -752,7 +740,6 @@ static s_stat* init_swp(const char *param UNUSED_PARAM) return (s_stat*)s; } - S_STAT(fd_stat) S_STAT_END(fd_stat) @@ -778,17 +765,16 @@ static s_stat* init_fd(const char *param UNUSED_PARAM) return (s_stat*)s; } - S_STAT(time_stat) - int prec; - int scale; + unsigned prec; + unsigned scale; S_STAT_END(time_stat) static void FAST_FUNC collect_time(time_stat *s) { char buf[sizeof("12:34:56.123456")]; struct tm* tm; - int us = tv.tv_usec + s->scale/2; + unsigned us = tv.tv_usec + s->scale/2; time_t t = tv.tv_sec; if (us >= 1000000) { @@ -829,7 +815,6 @@ static void FAST_FUNC collect_info(s_stat *s) } } - typedef s_stat* init_func(const char *param); // Deprecated %NNNd is to be removed, -d MSEC supersedes it @@ -951,7 +936,7 @@ int nmeter_main(int argc UNUSED_PARAM, char **argv) while (1) { gettimeofday(&tv, NULL); collect_info(first); - put(final_str); + put_c(G.final_char); print_outbuf(); // Negative delta -> no usleep at all From 41b1e2c39238ef1f333588b9a857e5af806bd157 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Tue, 15 Mar 2016 16:13:23 +0100 Subject: [PATCH 161/260] nmeter: remove undocumented %NNNd specifier function old new delta nmeter_main 707 745 +38 init_functions 48 44 -4 init_delay 63 - -63 ------------------------------------------------------------------------------ (add/remove: 0/1 grow/shrink: 1/1 up/down: 38/-67) Total: -29 bytes Signed-off-by: Denys Vlasenko --- procps/nmeter.c | 19 ++++++------------- 1 file changed, 6 insertions(+), 13 deletions(-) diff --git a/procps/nmeter.c b/procps/nmeter.c index 1cc908504..d6c46c657 100644 --- a/procps/nmeter.c +++ b/procps/nmeter.c @@ -342,14 +342,6 @@ static s_stat* init_literal(void) return (s_stat*)s; } -static s_stat* init_delay(const char *param) -{ - delta = strtoul(param, NULL, 0) * 1000; /* param can be "" */ - deltanz = delta > 0 ? delta : 1; - need_seconds = (1000000%deltanz) != 0; - return NULL; -} - static s_stat* init_cr(const char *param UNUSED_PARAM) { G.final_char = '\r'; @@ -817,8 +809,7 @@ static void FAST_FUNC collect_info(s_stat *s) typedef s_stat* init_func(const char *param); -// Deprecated %NNNd is to be removed, -d MSEC supersedes it -static const char options[] ALIGN1 = "ncmsfixptbdr"; +static const char options[] ALIGN1 = "ncmsfixptbr"; static init_func *const init_functions[] = { init_if, init_cpu, @@ -830,7 +821,6 @@ static init_func *const init_functions[] = { init_fork, init_time, init_blk, - init_delay, init_cr }; @@ -853,8 +843,11 @@ int nmeter_main(int argc UNUSED_PARAM, char **argv) is26 = (strstr(buf, " 2.4.") == NULL); } - if (getopt32(argv, "d:", &opt_d)) - init_delay(opt_d); + if (getopt32(argv, "d:", &opt_d)) { + delta = xatou(opt_d) * 1000; + deltanz = delta > 0 ? delta : 1; + need_seconds = (1000000 % deltanz) != 0; + } argv += optind; if (!argv[0]) From 0d1b71e8e61491cf50fc3a21ec0a412f6dca4d56 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Tue, 15 Mar 2016 17:54:17 +0100 Subject: [PATCH 162/260] nmeter: reinstate and document -d-1 Signed-off-by: Denys Vlasenko --- procps/nmeter.c | 32 +++++++++++++++----------------- 1 file changed, 15 insertions(+), 17 deletions(-) diff --git a/procps/nmeter.c b/procps/nmeter.c index d6c46c657..33de3790f 100644 --- a/procps/nmeter.c +++ b/procps/nmeter.c @@ -21,7 +21,7 @@ //usage:#define nmeter_full_usage "\n\n" //usage: "Monitor system in real time" //usage: "\n" -//usage: "\n -d MSEC Milliseconds between updates (default:1000)" +//usage: "\n -d MSEC Milliseconds between updates, default:1000, none:-1" //usage: "\n" //usage: "\nFormat specifiers:" //usage: "\n %Nc or %[cN] CPU. N - bar size (default:10)" @@ -86,7 +86,7 @@ struct globals { char final_char; char *cur_outbuf; int delta; - int deltanz; + unsigned deltanz; struct timeval tv; #define first_proc_file proc_stat proc_file proc_stat; // Must match the order of proc_name's! @@ -101,8 +101,6 @@ struct globals { #define is26 (G.is26 ) #define need_seconds (G.need_seconds ) #define cur_outbuf (G.cur_outbuf ) -#define delta (G.delta ) -#define deltanz (G.deltanz ) #define tv (G.tv ) #define proc_stat (G.proc_stat ) #define proc_loadavg (G.proc_loadavg ) @@ -114,7 +112,7 @@ struct globals { SET_PTR_TO_GLOBALS(xzalloc(sizeof(G))); \ cur_outbuf = outbuf; \ G.final_char = '\n'; \ - deltanz = delta = 1000000; \ + G.deltanz = G.delta = 1000000; \ } while (0) // We depend on this being a char[], not char* - we take sizeof() of it @@ -844,9 +842,9 @@ int nmeter_main(int argc UNUSED_PARAM, char **argv) } if (getopt32(argv, "d:", &opt_d)) { - delta = xatou(opt_d) * 1000; - deltanz = delta > 0 ? delta : 1; - need_seconds = (1000000 % deltanz) != 0; + G.delta = xatoi(opt_d) * 1000; + G.deltanz = G.delta > 0 ? G.delta : 1; + need_seconds = (1000000 % G.deltanz) != 0; } argv += optind; @@ -902,8 +900,8 @@ int nmeter_main(int argc UNUSED_PARAM, char **argv) last->next = s; last = s; } else { - // %NNNNd or %r option. remove it from string - strcpy(prev + strlen(prev), cur); + // %r option. remove it from string + overlapping_strcpy(prev + strlen(prev), cur); cur = prev; } } @@ -921,9 +919,9 @@ int nmeter_main(int argc UNUSED_PARAM, char **argv) // Generate first samples but do not print them, they're bogus collect_info(first); reset_outbuf(); - if (delta >= 0) { + if (G.delta >= 0) { gettimeofday(&tv, NULL); - usleep(delta > 1000000 ? 1000000 : delta - tv.tv_usec%deltanz); + usleep(G.delta > 1000000 ? 1000000 : G.delta - tv.tv_usec % G.deltanz); } while (1) { @@ -937,18 +935,18 @@ int nmeter_main(int argc UNUSED_PARAM, char **argv) // time resolution ;) // TODO: detect and avoid useless updates // (like: nothing happens except time) - if (delta >= 0) { + if (G.delta >= 0) { int rem; // can be commented out, will sacrifice sleep time precision a bit gettimeofday(&tv, NULL); if (need_seconds) - rem = delta - ((ullong)tv.tv_sec*1000000 + tv.tv_usec) % deltanz; + rem = G.delta - ((ullong)tv.tv_sec*1000000 + tv.tv_usec) % G.deltanz; else - rem = delta - tv.tv_usec%deltanz; + rem = G.delta - (unsigned)tv.tv_usec % G.deltanz; // Sometimes kernel wakes us up just a tiny bit earlier than asked // Do not go to very short sleep in this case - if (rem < delta/128) { - rem += delta; + if (rem < (unsigned)G.delta / 128) { + rem += G.delta; } usleep(rem); } From 6701e91d84fe499b5d87dc21790cd9d7bcb13220 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Thu, 17 Mar 2016 15:58:16 +0100 Subject: [PATCH 163/260] wget: make -T timeout work on header reads too. Closes 8636 function old new delta set_alarm - 27 +27 fgets_and_trim 76 92 +16 wget_main 2610 2616 +6 open_socket 64 54 -10 Signed-off-by: Denys Vlasenko --- networking/wget.c | 22 +++++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-) diff --git a/networking/wget.c b/networking/wget.c index 7f27e4e7b..5c12423c7 100644 --- a/networking/wget.c +++ b/networking/wget.c @@ -203,7 +203,7 @@ struct globals { const char *user_agent; /* "User-Agent" header field */ #if ENABLE_FEATURE_WGET_TIMEOUT unsigned timeout_seconds; - bool connecting; + bool die_if_timed_out; #endif int output_fd; int o_flags; @@ -333,9 +333,20 @@ static char* sanitize_string(char *s) static void alarm_handler(int sig UNUSED_PARAM) { /* This is theoretically unsafe (uses stdio and malloc in signal handler) */ - if (G.connecting) + if (G.die_if_timed_out) bb_error_msg_and_die("download timed out"); } +static void set_alarm(void) +{ + if (G.timeout_seconds) { + alarm(G.timeout_seconds); + G.die_if_timed_out = 1; + } +} +# define clear_alarm() ((void)(G.die_if_timed_out = 0)) +#else +# define set_alarm() ((void)0) +# define clear_alarm() ((void)0) #endif static FILE *open_socket(len_and_sockaddr *lsa) @@ -343,9 +354,9 @@ static FILE *open_socket(len_and_sockaddr *lsa) int fd; FILE *fp; - IF_FEATURE_WGET_TIMEOUT(alarm(G.timeout_seconds); G.connecting = 1;) + set_alarm(); fd = xconnect_stream(lsa); - IF_FEATURE_WGET_TIMEOUT(G.connecting = 0;) + clear_alarm(); /* glibc 2.4 seems to try seeking on it - ??! */ /* hopefully it understands what ESPIPE means... */ @@ -357,14 +368,15 @@ static FILE *open_socket(len_and_sockaddr *lsa) } /* Returns '\n' if it was seen, else '\0'. Trims at first '\r' or '\n' */ -/* FIXME: does not respect FEATURE_WGET_TIMEOUT and -T N: */ static char fgets_and_trim(FILE *fp) { char c; char *buf_ptr; + set_alarm(); if (fgets(G.wget_buf, sizeof(G.wget_buf) - 1, fp) == NULL) bb_perror_msg_and_die("error getting response"); + clear_alarm(); buf_ptr = strchrnul(G.wget_buf, '\n'); c = *buf_ptr; From 3e3bfb896e0dd8a54caad9c6264e2452566b4012 Mon Sep 17 00:00:00 2001 From: Ron Yorston Date: Fri, 18 Mar 2016 11:29:19 +0000 Subject: [PATCH 164/260] ash: fix corruption of ${#var} if $var contains UTF-8 characters MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit As reported in bug 8506: $ X=abcdÉfghÍjklmnÓpqrstÚvwcyz $ echo ${#X} abcd26 The result should be 26. This regression was introduced by: 2015-05-18 [Ron Yorston] ash: code shrink around varvalue The length in characters was being used to discard the contents of the variable instead of the length in bytes. URL: https://bugs.busybox.net/8506 Reported-by: Martijn Dekker Signed-off-by: Ron Yorston Signed-off-by: Mike Frysinger --- shell/ash.c | 2 ++ shell/ash_test/ash-vars/var-utf8-length.right | 1 + shell/ash_test/ash-vars/var-utf8-length.tests | 2 ++ 3 files changed, 5 insertions(+) create mode 100644 shell/ash_test/ash-vars/var-utf8-length.right create mode 100755 shell/ash_test/ash-vars/var-utf8-length.tests diff --git a/shell/ash.c b/shell/ash.c index b5a2d961d..5613e1f33 100644 --- a/shell/ash.c +++ b/shell/ash.c @@ -6692,6 +6692,8 @@ varvalue(char *name, int varflags, int flags, struct strlist *var_str_list) if (subtype == VSLENGTH && len > 0) { reinit_unicode_for_ash(); if (unicode_status == UNICODE_ON) { + STADJUST(-len, expdest); + discard = 0; len = unicode_strlen(p); } } diff --git a/shell/ash_test/ash-vars/var-utf8-length.right b/shell/ash_test/ash-vars/var-utf8-length.right new file mode 100644 index 000000000..6f4247a62 --- /dev/null +++ b/shell/ash_test/ash-vars/var-utf8-length.right @@ -0,0 +1 @@ +26 diff --git a/shell/ash_test/ash-vars/var-utf8-length.tests b/shell/ash_test/ash-vars/var-utf8-length.tests new file mode 100755 index 000000000..d04b2cbb6 --- /dev/null +++ b/shell/ash_test/ash-vars/var-utf8-length.tests @@ -0,0 +1,2 @@ +X=abcdÉfghÍjklmnÓpqrstÚvwcyz +echo ${#X} From 787972f60b08c34059de65f9ee24febaa50667a2 Mon Sep 17 00:00:00 2001 From: Mike Frysinger Date: Tue, 22 Mar 2016 18:15:14 -0400 Subject: [PATCH 165/260] ash_test: printenv: fix missing includes Signed-off-by: Mike Frysinger --- shell/ash_test/printenv.c | 1 + 1 file changed, 1 insertion(+) diff --git a/shell/ash_test/printenv.c b/shell/ash_test/printenv.c index c4ccda8a6..c0c5e197c 100644 --- a/shell/ash_test/printenv.c +++ b/shell/ash_test/printenv.c @@ -24,6 +24,7 @@ with Bash; see the file COPYING. If not, write to the Free Software Foundation, 59 Temple Place, Suite 330, Boston, MA 02111 USA. */ +#include #include #include From b9b7aa1910907f59f1130667fbe7b870087e97f8 Mon Sep 17 00:00:00 2001 From: Mike Frysinger Date: Tue, 22 Mar 2016 18:15:24 -0400 Subject: [PATCH 166/260] ash_test: ignore generated files Signed-off-by: Mike Frysinger --- shell/ash_test/.gitignore | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 shell/ash_test/.gitignore diff --git a/shell/ash_test/.gitignore b/shell/ash_test/.gitignore new file mode 100644 index 000000000..a1f937cdd --- /dev/null +++ b/shell/ash_test/.gitignore @@ -0,0 +1,7 @@ +/ash +/printenv +/recho +/zecho + +/*.fail +*.xx From 73dfdda92e20da718a9cb398ed762cc09c82e3a7 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Mon, 28 Mar 2016 22:12:09 +0200 Subject: [PATCH 167/260] grep: make errors other than "not found" result in exit code 2. Closes 8796 Signed-off-by: Denys Vlasenko --- findutils/grep.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/findutils/grep.c b/findutils/grep.c index 10b69275a..dece90c58 100644 --- a/findutils/grep.c +++ b/findutils/grep.c @@ -681,11 +681,15 @@ int grep_main(int argc UNUSED_PARAM, char **argv) FILE *file; int matched; llist_t *fopt = NULL; +#if ENABLE_FEATURE_GREP_CONTEXT + int Copt, opts; +#endif + + /* For grep, exitcode of 1 is "not found". Other errors are 2: */ + xfunc_error_retval = 2; /* do normal option parsing */ #if ENABLE_FEATURE_GREP_CONTEXT - int Copt, opts; - /* -H unsets -h; -C unsets -A,-B; -e,-f are lists; * -m,-A,-B,-C have numeric param */ opt_complementary = "H-h:C-AB:e::f::m+:A+:B+:C+"; From 2fb63292f7083fb259a3f8d8ee70ef8acdaed626 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timo=20Ter=C3=A4s?= Date: Mon, 28 Mar 2016 22:16:48 +0200 Subject: [PATCH 168/260] networking: properly initialize ipv6 scope id for printing it MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Timo Teräs Signed-off-by: Denys Vlasenko --- networking/interface.c | 1 + 1 file changed, 1 insertion(+) diff --git a/networking/interface.c b/networking/interface.c index e5723b428..90c1449b3 100644 --- a/networking/interface.c +++ b/networking/interface.c @@ -885,6 +885,7 @@ static void ife_print6(struct interface *ptr) inet_pton(AF_INET6, addr6, (struct sockaddr *) &sap.sin6_addr); sap.sin6_family = AF_INET6; + sap.sin6_scope_id = scope; printf(" inet6 addr: %s/%d", INET6_sprint((struct sockaddr *) &sap, 1), plen); From 31c984dd6904a11b655879b3ad927bd9bf639192 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Mon, 28 Mar 2016 22:23:33 +0200 Subject: [PATCH 169/260] umount: build fix for older glibc Based on a patch by Veli-Pekka Peltola Signed-off-by: Denys Vlasenko --- util-linux/umount.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/util-linux/umount.c b/util-linux/umount.c index 00910977d..30bef1686 100644 --- a/util-linux/umount.c +++ b/util-linux/umount.c @@ -30,6 +30,9 @@ #include #include +#ifndef MNT_DETACH +# define MNT_DETACH 0x00000002 +#endif #include "libbb.h" #if defined(__dietlibc__) From 20dd49934146bdcfdfc58ee4f8f566ecda1dda77 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Tue, 29 Mar 2016 19:23:55 +0200 Subject: [PATCH 170/260] modprobe: skip non-.conf files only in subdirectories Signed-off-by: Denys Vlasenko --- modutils/modprobe.c | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/modutils/modprobe.c b/modutils/modprobe.c index 997ee3c67..8130c40b7 100644 --- a/modutils/modprobe.c +++ b/modutils/modprobe.c @@ -214,7 +214,7 @@ static void add_probe(const char *name) static int FAST_FUNC config_file_action(const char *filename, struct stat *statbuf UNUSED_PARAM, void *userdata UNUSED_PARAM, - int depth UNUSED_PARAM) + int depth) { char *tokens[3]; parser_t *p; @@ -222,15 +222,20 @@ static int FAST_FUNC config_file_action(const char *filename, int rc = TRUE; const char *base, *ext; - /* Skip files that begin with a ".". */ + /* Skip files that begin with a "." */ base = bb_basename(filename); if (base[0] == '.') goto error; - /* Skip files that do not end with a ".conf". */ - ext = strrchr(base, '.'); - if (ext == NULL || strcmp(ext + 1, "conf")) - goto error; + /* In dir recursion, skip files that do not end with a ".conf" + * depth==0: read_config("modules.{symbols,alias}") must work, + * "include FILE_NOT_ENDING_IN_CONF" must work too. + */ + if (depth != 0) { + ext = strrchr(base, '.'); + if (ext == NULL || strcmp(ext + 1, "conf")) + goto error; + } p = config_open2(filename, fopen_for_read); if (p == NULL) { @@ -275,7 +280,7 @@ static int FAST_FUNC config_file_action(const char *filename, m = get_or_add_modentry(tokens[1]); m->options = gather_options_str(m->options, tokens[2]); } else if (strcmp(tokens[0], "include") == 0) { - /* include */ + /* include / (yes, directories also must work) */ read_config(tokens[1]); } else if (ENABLE_FEATURE_MODPROBE_BLACKLIST && strcmp(tokens[0], "blacklist") == 0 @@ -292,7 +297,8 @@ static int FAST_FUNC config_file_action(const char *filename, static int read_config(const char *path) { return recursive_action(path, ACTION_RECURSE | ACTION_QUIET, - config_file_action, NULL, NULL, 1); + config_file_action, NULL, NULL, + /*depth:*/ 0); } static const char *humanly_readable_name(struct module_entry *m) From 9844d7e830a2c55421e27e8828d2067c50f57c23 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Tue, 29 Mar 2016 19:27:00 +0200 Subject: [PATCH 171/260] Revert "networking: properly initialize ipv6 scope id for printing it" This reverts commit 2fb63292f7083fb259a3f8d8ee70ef8acdaed626. Signed-off-by: Denys Vlasenko --- networking/interface.c | 1 - 1 file changed, 1 deletion(-) diff --git a/networking/interface.c b/networking/interface.c index 90c1449b3..e5723b428 100644 --- a/networking/interface.c +++ b/networking/interface.c @@ -885,7 +885,6 @@ static void ife_print6(struct interface *ptr) inet_pton(AF_INET6, addr6, (struct sockaddr *) &sap.sin6_addr); sap.sin6_family = AF_INET6; - sap.sin6_scope_id = scope; printf(" inet6 addr: %s/%d", INET6_sprint((struct sockaddr *) &sap, 1), plen); From 610c4c385b38280c7bde7a48d95ec019cbfe1ab4 Mon Sep 17 00:00:00 2001 From: Ron Yorston Date: Wed, 30 Mar 2016 00:42:05 +0200 Subject: [PATCH 172/260] applet_tables: save space by removing applet name offsets The array applet_nameofs consumes two bytes per applet. It encodes nofork/noexec flags suid flags the offset of the applet name in the applet_name string Change the applet_table build tool to store the flags in two separate arrays (applet_flags and applet_suid). Replace applet_nameofs[] with a smaller version that only stores a limited number of offsets. This requires changes to the macros APPLET_IS_NOFORK, APPLET_IS_NOEXEC and APPLET_SUID. According to Valgrind the original find_applet_by_name required 353 cycles per call, averaged over all names. Adjusting the number of known offsets allows space to be traded off against execution time: KNOWN_OFFSETS cycles bytes (wrt KNOWN_OFFSETS = 0) 0 9057 - 2 4604 32 4 2407 75 8 1342 98 16 908 130 32 884 194 This patch uses KNOWN_OFFSETS = 8. v2: Remove some dead code from the applet_table tool; Treat the applet in the middle of the table as a special case. v3: Use the middle applet to adjust the start of the linear search as well as the last applet found. v4: Use an augmented linear search in find_applet_by_name. Drop the special treatment of the middle name from get_applet_name: most of the advantage now derives from the last stored value. v5: Don't store index in applet_nameofs, it can be calculated. v6: Tweaks by Denys function old new delta find_applet_by_name 25 125 +100 applet_suid - 92 +92 run_applet_no_and_exit 452 460 +8 run_applet_and_exit 695 697 +2 applet_name_compare 31 - -31 applet_nameofs 734 14 -720 ------------------------------------------------------------------------------ (add/remove: 1/1 grow/shrink: 3/1 up/down: 202/-751) Total: -549 bytes text data bss dec hex filename 925464 906 17160 943530 e65aa busybox_old 924915 906 17160 942981 e6385 busybox_unstripped Signed-off-by: Ron Yorston Signed-off-by: Denys Vlasenko --- applets/applet_tables.c | 82 ++++++++++++++++++++++++++++---------- include/busybox.h | 15 +++---- libbb/appletlib.c | 82 +++++++++++++++++++++++++------------- libbb/vfork_daemon_rexec.c | 3 +- 4 files changed, 122 insertions(+), 60 deletions(-) diff --git a/applets/applet_tables.c b/applets/applet_tables.c index 92bf1e447..48544f08d 100644 --- a/applets/applet_tables.c +++ b/applets/applet_tables.c @@ -41,8 +41,6 @@ struct bb_applet { enum { NUM_APPLETS = ARRAY_SIZE(applets) }; -static int offset[NUM_APPLETS]; - static int cmp_name(const void *a, const void *b) { const struct bb_applet *aa = a; @@ -60,22 +58,37 @@ static int str_isalnum_(const char *s) return 1; } +// Before linear search, narrow it down by looking at N "equidistant" names: +// KNOWN_APPNAME_OFFSETS cycles code_size +// 0 9057 +// 2 4604 +32 +// 4 2407 +75 +// 8 1342 +98 +// 16 908 +130 +// 32 884 +194 +// With 8, applet_nameofs[] table has 7 elements. +#define KNOWN_APPNAME_OFFSETS 8 + int main(int argc, char **argv) { - int i; - int ofs; + int i, j; + int ofs, offset[KNOWN_APPNAME_OFFSETS], index[KNOWN_APPNAME_OFFSETS]; // unsigned MAX_APPLET_NAME_LEN = 1; qsort(applets, NUM_APPLETS, sizeof(applets[0]), cmp_name); + for (i = 0; i < KNOWN_APPNAME_OFFSETS; i++) + index[i] = i * NUM_APPLETS / KNOWN_APPNAME_OFFSETS; + ofs = 0; for (i = 0; i < NUM_APPLETS; i++) { - offset[i] = ofs; + for (j = 0; j < KNOWN_APPNAME_OFFSETS; j++) + if (i == index[j]) + offset[j] = ofs; ofs += strlen(applets[i].name) + 1; } - /* We reuse 4 high-order bits of offset array for other purposes, - * so if they are indeed needed, refuse to proceed */ - if (ofs > 0xfff) + /* If the list of names is too long refuse to proceed */ + if (ofs > 0xffff) return 1; if (!argv[1]) return 1; @@ -94,7 +107,17 @@ int main(int argc, char **argv) printf("#define SINGLE_APPLET_STR \"%s\"\n", applets[0].name); printf("#define SINGLE_APPLET_MAIN %s_main\n", applets[0].main); } - printf("\n"); + + if (KNOWN_APPNAME_OFFSETS > 0 && NUM_APPLETS > 2*KNOWN_APPNAME_OFFSETS) { + printf("#define KNOWN_APPNAME_OFFSETS %u\n\n", KNOWN_APPNAME_OFFSETS); + printf("const uint16_t applet_nameofs[] ALIGN2 = {\n"); + for (i = 1; i < KNOWN_APPNAME_OFFSETS; i++) + printf("%d,\n", offset[i]); + printf("};\n\n"); + } + else { + printf("#define KNOWN_APPNAME_OFFSETS 0\n\n"); + } //printf("#ifndef SKIP_definitions\n"); printf("const char applet_names[] ALIGN1 = \"\"\n"); @@ -119,20 +142,39 @@ int main(int argc, char **argv) printf("};\n"); printf("#endif\n\n"); - printf("const uint16_t applet_nameofs[] ALIGN2 = {\n"); - for (i = 0; i < NUM_APPLETS; i++) { - printf("0x%04x,\n", - offset[i] #if ENABLE_FEATURE_PREFER_APPLETS - + (applets[i].nofork << 12) - + (applets[i].noexec << 13) -#endif -#if ENABLE_FEATURE_SUID - + (applets[i].need_suid << 14) /* 2 bits */ -#endif - ); + printf("const uint8_t applet_flags[] ALIGN1 = {\n"); + i = 0; + while (i < NUM_APPLETS) { + int v = applets[i].nofork + (applets[i].noexec << 1); + if (++i < NUM_APPLETS) + v |= (applets[i].nofork + (applets[i].noexec << 1)) << 2; + if (++i < NUM_APPLETS) + v |= (applets[i].nofork + (applets[i].noexec << 1)) << 4; + if (++i < NUM_APPLETS) + v |= (applets[i].nofork + (applets[i].noexec << 1)) << 6; + printf("0x%02x,\n", v); + i++; } printf("};\n\n"); +#endif + +#if ENABLE_FEATURE_SUID + printf("const uint8_t applet_suid[] ALIGN1 = {\n"); + i = 0; + while (i < NUM_APPLETS) { + int v = applets[i].need_suid; /* 2 bits */ + if (++i < NUM_APPLETS) + v |= applets[i].need_suid << 2; + if (++i < NUM_APPLETS) + v |= applets[i].need_suid << 4; + if (++i < NUM_APPLETS) + v |= applets[i].need_suid << 6; + printf("0x%02x,\n", v); + i++; + } + printf("};\n\n"); +#endif #if ENABLE_FEATURE_INSTALLER printf("const uint8_t applet_install_loc[] ALIGN1 = {\n"); diff --git a/include/busybox.h b/include/busybox.h index b1e31e5ee..737627bd0 100644 --- a/include/busybox.h +++ b/include/busybox.h @@ -15,25 +15,20 @@ PUSH_AND_SET_FUNCTION_VISIBILITY_TO_HIDDEN /* Keep in sync with applets/applet_tables.c! */ extern const char applet_names[] ALIGN1; extern int (*const applet_main[])(int argc, char **argv); -extern const uint16_t applet_nameofs[]; +extern const uint8_t applet_flags[] ALIGN1; +extern const uint8_t applet_suid[] ALIGN1; extern const uint8_t applet_install_loc[] ALIGN1; -#if ENABLE_FEATURE_SUID || ENABLE_FEATURE_PREFER_APPLETS -# define APPLET_NAME(i) (applet_names + (applet_nameofs[i] & 0x0fff)) -#else -# define APPLET_NAME(i) (applet_names + applet_nameofs[i]) -#endif - #if ENABLE_FEATURE_PREFER_APPLETS -# define APPLET_IS_NOFORK(i) (applet_nameofs[i] & (1 << 12)) -# define APPLET_IS_NOEXEC(i) (applet_nameofs[i] & (1 << 13)) +# define APPLET_IS_NOFORK(i) (applet_flags[(i)/4] & (1 << (2 * ((i)%4)))) +# define APPLET_IS_NOEXEC(i) (applet_flags[(i)/4] & (1 << ((2 * ((i)%4))+1))) #else # define APPLET_IS_NOFORK(i) 0 # define APPLET_IS_NOEXEC(i) 0 #endif #if ENABLE_FEATURE_SUID -# define APPLET_SUID(i) ((applet_nameofs[i] >> 14) & 0x3) +# define APPLET_SUID(i) ((applet_suid[(i)/4] >> (2 * ((i)%4)) & 3)) #endif #if ENABLE_FEATURE_INSTALLER diff --git a/libbb/appletlib.c b/libbb/appletlib.c index 95e589e74..aeaf238f1 100644 --- a/libbb/appletlib.c +++ b/libbb/appletlib.c @@ -139,36 +139,56 @@ void FAST_FUNC bb_show_usage(void) xfunc_die(); } -#if NUM_APPLETS > 8 -static int applet_name_compare(const void *name, const void *idx) -{ - int i = (int)(ptrdiff_t)idx - 1; - return strcmp(name, APPLET_NAME(i)); -} -#endif int FAST_FUNC find_applet_by_name(const char *name) { -#if NUM_APPLETS > 8 - /* Do a binary search to find the applet entry given the name. */ + unsigned i, max; + int j; const char *p; - p = bsearch(name, (void*)(ptrdiff_t)1, ARRAY_SIZE(applet_main), 1, applet_name_compare); - /* - * if (!p) return -1; - * ^^^^^^^^^^^^^^^^^^ the code below will do this if p == NULL :) - */ - return (int)(ptrdiff_t)p - 1; + + p = applet_names; + i = 0; +#if KNOWN_APPNAME_OFFSETS <= 0 + max = NUM_APPLETS; #else - /* A version which does not pull in bsearch */ - int i = 0; - const char *p = applet_names; - while (i < NUM_APPLETS) { - if (strcmp(name, p) == 0) - return i; - p += strlen(p) + 1; + max = NUM_APPLETS * KNOWN_APPNAME_OFFSETS; + for (j = ARRAY_SIZE(applet_nameofs)-1; j >= 0; j--) { + const char *pp = applet_names + applet_nameofs[j]; + if (strcmp(name, pp) >= 0) { + //bb_error_msg("name:'%s' >= pp:'%s'", name, pp); + p = pp; + i = max - NUM_APPLETS; + break; + } + max -= NUM_APPLETS; + } + max /= (unsigned)KNOWN_APPNAME_OFFSETS; + i /= (unsigned)KNOWN_APPNAME_OFFSETS; + //bb_error_msg("name:'%s' starting from:'%s' i:%u max:%u", name, p, i, max); +#endif + + /* Open-coding without strcmp/strlen calls for speed */ + while (i < max) { + char ch; + j = 0; + /* Do we see "name\0" in applet_names[p] position? */ + while ((ch = *p) == name[j]) { + if (ch == '\0') { + //bb_error_msg("found:'%s' i:%u", name, i); + return i; /* yes */ + } + p++; + j++; + } + /* No. + * p => 1st non-matching char in applet_names[], + * skip to and including NUL. + */ + while (ch != '\0') + ch = *++p; + p++; i++; } return -1; -#endif } @@ -583,6 +603,7 @@ static void install_links(const char *busybox, int use_symbolic_links, * busybox.h::bb_install_loc_t, or else... */ int (*lf)(const char *, const char *); char *fpc; + const char *appname = applet_names; unsigned i; int rc; @@ -593,7 +614,7 @@ static void install_links(const char *busybox, int use_symbolic_links, for (i = 0; i < ARRAY_SIZE(applet_main); i++) { fpc = concat_path_file( custom_install_dir ? custom_install_dir : install_dir[APPLET_INSTALL_LOC(i)], - APPLET_NAME(i)); + appname); // debug: bb_error_msg("%slinking %s to busybox", // use_symbolic_links ? "sym" : "", fpc); rc = lf(busybox, fpc); @@ -601,6 +622,8 @@ static void install_links(const char *busybox, int use_symbolic_links, bb_simple_perror_msg(fpc); } free(fpc); + while (*appname++ != '\0') + continue; } } # else @@ -754,7 +777,7 @@ void FAST_FUNC run_applet_no_and_exit(int applet_no, char **argv) /* Reinit some shared global data */ xfunc_error_retval = EXIT_FAILURE; - applet_name = APPLET_NAME(applet_no); + applet_name = bb_get_last_path_component_nostrip(argv[0]); /* Special case. POSIX says "test --help" * should be no different from e.g. "test --foo". @@ -785,11 +808,14 @@ void FAST_FUNC run_applet_no_and_exit(int applet_no, char **argv) void FAST_FUNC run_applet_and_exit(const char *name, char **argv) { - int applet = find_applet_by_name(name); - if (applet >= 0) - run_applet_no_and_exit(applet, argv); + int applet; + if (is_prefixed_with(name, "busybox")) exit(busybox_main(argv)); + /* find_applet_by_name() search is more expensive, so goes second */ + applet = find_applet_by_name(name); + if (applet >= 0) + run_applet_no_and_exit(applet, argv); } #endif /* !defined(SINGLE_APPLET_MAIN) */ diff --git a/libbb/vfork_daemon_rexec.c b/libbb/vfork_daemon_rexec.c index d6ca7b263..1adb5b3c4 100644 --- a/libbb/vfork_daemon_rexec.c +++ b/libbb/vfork_daemon_rexec.c @@ -116,8 +116,6 @@ int FAST_FUNC run_nofork_applet(int applet_no, char **argv) save_nofork_data(&old); - applet_name = APPLET_NAME(applet_no); - xfunc_error_retval = EXIT_FAILURE; /* In case getopt() or getopt32() was already called: @@ -157,6 +155,7 @@ int FAST_FUNC run_nofork_applet(int applet_no, char **argv) * need argv untouched because they free argv[i]! */ char *tmp_argv[argc+1]; memcpy(tmp_argv, argv, (argc+1) * sizeof(tmp_argv[0])); + applet_name = tmp_argv[0]; /* Finally we can call NOFORK applet's main() */ rc = applet_main[applet_no](argc, tmp_argv); } else { From 76b680c7a8d5a99e46ab8d9cad49aed0cfc440a7 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Wed, 30 Mar 2016 16:04:37 +0200 Subject: [PATCH 173/260] Use bb_error_msg instead of bb_info_msg in all commented-out debug printouts Signed-off-by: Denys Vlasenko --- e2fsprogs/fsck.c | 2 +- mailutils/sendmail.c | 2 +- miscutils/beep.c | 2 +- networking/udhcp/d6_packet.c | 2 +- util-linux/fbset.c | 18 +++++++++--------- util-linux/mkfs_ext2.c | 8 ++++---- 6 files changed, 17 insertions(+), 17 deletions(-) diff --git a/e2fsprogs/fsck.c b/e2fsprogs/fsck.c index 627d2be31..8d89179e3 100644 --- a/e2fsprogs/fsck.c +++ b/e2fsprogs/fsck.c @@ -345,7 +345,7 @@ static void load_fs_info(const char *filename) // Loop through entries while (getmntent_r(fstab, &mte, buf, sizeof(buf))) { - //bb_info_msg("CREATE[%s][%s][%s][%s][%d]", mte.mnt_fsname, mte.mnt_dir, + //bb_error_msg("CREATE[%s][%s][%s][%s][%d]", mte.mnt_fsname, mte.mnt_dir, // mte.mnt_type, mte.mnt_opts, // mte.mnt_passno); create_fs_device(mte.mnt_fsname, mte.mnt_dir, diff --git a/mailutils/sendmail.c b/mailutils/sendmail.c index 4355e4dc5..5143fac8f 100644 --- a/mailutils/sendmail.c +++ b/mailutils/sendmail.c @@ -270,7 +270,7 @@ int sendmail_main(int argc UNUSED_PARAM, char **argv) // G.method = xstrdup(a+1); } // N.B. list == NULL here - //bb_info_msg("OPT[%x] AU[%s], AP[%s], AM[%s], ARGV[%s]", opts, au, ap, am, *argv); + //bb_error_msg("OPT[%x] AU[%s], AP[%s], AM[%s], ARGV[%s]", opts, au, ap, am, *argv); // connect to server diff --git a/miscutils/beep.c b/miscutils/beep.c index 910e03e1b..18b160cc4 100644 --- a/miscutils/beep.c +++ b/miscutils/beep.c @@ -88,7 +88,7 @@ int beep_main(int argc, char **argv) bb_show_usage(); } while (rep) { -//bb_info_msg("rep[%d] freq=%d, length=%d, delay=%d", rep, freq, length, delay); +//bb_error_msg("rep[%d] freq=%d, length=%d, delay=%d", rep, freq, length, delay); xioctl(speaker, KIOCSOUND, (void*)(uintptr_t)tickrate_div_freq); usleep(1000 * length); ioctl(speaker, KIOCSOUND, (void*)0); diff --git a/networking/udhcp/d6_packet.c b/networking/udhcp/d6_packet.c index 79b2946ef..b340b5db6 100644 --- a/networking/udhcp/d6_packet.c +++ b/networking/udhcp/d6_packet.c @@ -22,7 +22,7 @@ void FAST_FUNC d6_dump_packet(struct d6_packet *packet) , packet->d6_xid32 ); //*bin2hex(buf, (void *) packet->chaddr, sizeof(packet->chaddr)) = '\0'; - //bb_info_msg(" chaddr %s", buf); + //bb_error_msg(" chaddr %s", buf); } #endif diff --git a/util-linux/fbset.c b/util-linux/fbset.c index ac0082f70..09e96b763 100644 --- a/util-linux/fbset.c +++ b/util-linux/fbset.c @@ -248,12 +248,12 @@ static int read_mode_db(struct fb_var_screeninfo *base, const char *fn, if (!p) continue; s = p + strlen(mode); - //bb_info_msg("CHECK[%s][%s][%d]", mode, p-1, *s); + //bb_error_msg("CHECK[%s][%s][%d]", mode, p-1, *s); /* exact match? */ if (((!*s || isspace(*s)) && '"' != s[-1]) /* end-of-token */ || ('"' == *s && '"' == p[-1]) /* ends with " but starts with " too! */ ) { - //bb_info_msg("FOUND[%s][%s][%s][%d]", token[1], p, mode, isspace(*s)); + //bb_error_msg("FOUND[%s][%s][%s][%d]", token[1], p, mode, isspace(*s)); break; } } @@ -264,9 +264,9 @@ static int read_mode_db(struct fb_var_screeninfo *base, const char *fn, while (config_read(parser, token, 2, 1, "# \t", PARSE_NORMAL)) { int i; -//bb_info_msg("???[%s][%s]", token[0], token[1]); +//bb_error_msg("???[%s][%s]", token[0], token[1]); if (strcmp(token[0], "endmode") == 0) { -//bb_info_msg("OK[%s]", mode); +//bb_error_msg("OK[%s]", mode); return 1; } p = token[1]; @@ -294,7 +294,7 @@ static int read_mode_db(struct fb_var_screeninfo *base, const char *fn, base->yres_virtual = base_yres_virtual; base->bits_per_pixel = base_bits_per_pixel; } -//bb_info_msg("GEO[%s]", p); +//bb_error_msg("GEO[%s]", p); break; case 1: if (sizeof(int) == sizeof(base->xres)) { @@ -321,13 +321,13 @@ static int read_mode_db(struct fb_var_screeninfo *base, const char *fn, base->hsync_len = base_hsync_len; base->vsync_len = base_vsync_len; } -//bb_info_msg("TIM[%s]", p); +//bb_error_msg("TIM[%s]", p); break; case 2: case 3: { static const uint32_t syncs[] = {FB_VMODE_INTERLACED, FB_VMODE_DOUBLE}; ss(&base->vmode, syncs[i-2], p, "false"); -//bb_info_msg("VMODE[%s]", p); +//bb_error_msg("VMODE[%s]", p); break; } case 4: @@ -335,12 +335,12 @@ static int read_mode_db(struct fb_var_screeninfo *base, const char *fn, case 6: { static const uint32_t syncs[] = {FB_SYNC_VERT_HIGH_ACT, FB_SYNC_HOR_HIGH_ACT, FB_SYNC_COMP_HIGH_ACT}; ss(&base->sync, syncs[i-4], p, "low"); -//bb_info_msg("SYNC[%s]", p); +//bb_error_msg("SYNC[%s]", p); break; } case 7: ss(&base->sync, FB_SYNC_EXT, p, "false"); -//bb_info_msg("EXTSYNC[%s]", p); +//bb_error_msg("EXTSYNC[%s]", p); break; case 8: { int red_offset, red_length; diff --git a/util-linux/mkfs_ext2.c b/util-linux/mkfs_ext2.c index 3258d7eee..749f42068 100644 --- a/util-linux/mkfs_ext2.c +++ b/util-linux/mkfs_ext2.c @@ -116,7 +116,7 @@ static void allocate(uint8_t *bitmap, uint32_t blocksize, uint32_t start, uint32 { uint32_t i; -//bb_info_msg("ALLOC: [%u][%u][%u]: [%u-%u]:=[%x],[%x]", blocksize, start, end, start/8, blocksize - end/8 - 1, (1 << (start & 7)) - 1, (uint8_t)(0xFF00 >> (end & 7))); +//bb_error_msg("ALLOC: [%u][%u][%u]: [%u-%u]:=[%x],[%x]", blocksize, start, end, start/8, blocksize - end/8 - 1, (1 << (start & 7)) - 1, (uint8_t)(0xFF00 >> (end & 7))); memset(bitmap, 0, blocksize); i = start / 8; memset(bitmap, 0xFF, i); @@ -412,7 +412,7 @@ int mkfs_ext2_main(int argc UNUSED_PARAM, char **argv) // (a bit after 8M image size), but it works for two->three groups // transition (at 16M). if (remainder && (remainder < overhead + 50)) { -//bb_info_msg("CHOP[%u]", remainder); +//bb_error_msg("CHOP[%u]", remainder); nblocks -= remainder; goto retry; } @@ -568,7 +568,7 @@ int mkfs_ext2_main(int argc UNUSED_PARAM, char **argv) free_blocks = (n < blocks_per_group ? n : blocks_per_group) - overhead; // mark preallocated blocks as allocated -//bb_info_msg("ALLOC: [%u][%u][%u]", blocksize, overhead, blocks_per_group - (free_blocks + overhead)); +//bb_error_msg("ALLOC: [%u][%u][%u]", blocksize, overhead, blocks_per_group - (free_blocks + overhead)); allocate(buf, blocksize, // reserve "overhead" blocks overhead, @@ -647,7 +647,7 @@ int mkfs_ext2_main(int argc UNUSED_PARAM, char **argv) n = FETCH_LE32(inode->i_block[0]) + 1; for (i = 0; i < lost_and_found_blocks; ++i) STORE_LE(inode->i_block[i], i + n); // use next block -//bb_info_msg("LAST BLOCK USED[%u]", i + n); +//bb_error_msg("LAST BLOCK USED[%u]", i + n); PUT(((uint64_t)FETCH_LE32(gd[0].bg_inode_table) * blocksize) + (EXT2_GOOD_OLD_FIRST_INO-1) * inodesize, buf, inodesize); From 066e76befe5d39fc3451846af94cbba96747186c Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Wed, 30 Mar 2016 16:20:28 +0200 Subject: [PATCH 174/260] Replace a few more bb_info_msg's by bb_error_msg or printf Signed-off-by: Denys Vlasenko --- loginutils/chpasswd.c | 2 +- loginutils/passwd.c | 2 +- miscutils/devfsd.c | 2 +- miscutils/flash_eraseall.c | 2 +- networking/inetd.c | 8 ++++---- networking/traceroute.c | 2 +- networking/tunctl.c | 2 +- util-linux/mkfs_ext2.c | 2 +- 8 files changed, 11 insertions(+), 11 deletions(-) diff --git a/loginutils/chpasswd.c b/loginutils/chpasswd.c index a022a42d6..2d268be67 100644 --- a/loginutils/chpasswd.c +++ b/loginutils/chpasswd.c @@ -105,7 +105,7 @@ int chpasswd_main(int argc UNUSED_PARAM, char **argv) if (rc < 0) bb_error_msg_and_die("an error occurred updating password for %s", name); if (rc) - bb_info_msg("Password for '%s' changed", name); + bb_error_msg("password for '%s' changed", name); logmode = LOGMODE_STDIO; free(name); free(free_me); diff --git a/loginutils/passwd.c b/loginutils/passwd.c index 73726d3e0..52b66ca50 100644 --- a/loginutils/passwd.c +++ b/loginutils/passwd.c @@ -230,7 +230,7 @@ int passwd_main(int argc UNUSED_PARAM, char **argv) /* LOGMODE_BOTH */ if (rc < 0) bb_error_msg_and_die("can't update password file %s", filename); - bb_info_msg("Password for %s changed by %s", name, myname); + bb_error_msg("password for %s changed by %s", name, myname); /*if (ENABLE_FEATURE_CLEAN_UP) free(newp); - can't, it may be non-malloced */ skip: diff --git a/miscutils/devfsd.c b/miscutils/devfsd.c index 9256567cc..6217918da 100644 --- a/miscutils/devfsd.c +++ b/miscutils/devfsd.c @@ -284,7 +284,7 @@ static const char bb_msg_variable_not_found[] ALIGN1 = "variable: %s not found"; /* Busybox stuff */ #if ENABLE_DEVFSD_VERBOSE || ENABLE_DEBUG -#define info_logger(p, fmt, args...) bb_info_msg(fmt, ## args) +#define info_logger(p, fmt, args...) bb_error_msg(fmt, ## args) #define msg_logger(p, fmt, args...) bb_error_msg(fmt, ## args) #define msg_logger_and_die(p, fmt, args...) bb_error_msg_and_die(fmt, ## args) #define error_logger(p, fmt, args...) bb_perror_msg(fmt, ## args) diff --git a/miscutils/flash_eraseall.c b/miscutils/flash_eraseall.c index bf9b739a1..d95d214d9 100644 --- a/miscutils/flash_eraseall.c +++ b/miscutils/flash_eraseall.c @@ -147,7 +147,7 @@ int flash_eraseall_main(int argc UNUSED_PARAM, char **argv) ret = ioctl(fd, MEMGETBADBLOCK, &offset); if (ret > 0) { if (!(flags & OPTION_Q)) - bb_info_msg("\nSkipping bad block at 0x%08x", erase.start); + printf("\nSkipping bad block at 0x%08x\n", erase.start); continue; } if (ret < 0) { diff --git a/networking/inetd.c b/networking/inetd.c index 243165a07..4f6673b12 100644 --- a/networking/inetd.c +++ b/networking/inetd.c @@ -834,10 +834,10 @@ static NOINLINE servtab_t *parse_one_line(void) goto parse_err; } -// bb_info_msg( -// "ENTRY[%s][%s][%s][%d][%d][%d][%d][%d][%s][%s][%s]", -// sep->se_local_hostname, sep->se_service, sep->se_proto, sep->se_wait, sep->se_proto_no, -// sep->se_max, sep->se_count, sep->se_time, sep->se_user, sep->se_group, sep->se_program); + //bb_error_msg( + // "ENTRY[%s][%s][%s][%d][%d][%d][%d][%d][%s][%s][%s]", + // sep->se_local_hostname, sep->se_service, sep->se_proto, sep->se_wait, sep->se_proto_no, + // sep->se_max, sep->se_count, sep->se_time, sep->se_user, sep->se_group, sep->se_program); /* check if the hostname specifier is a comma separated list * of hostnames. we'll make new entries for each address. */ diff --git a/networking/traceroute.c b/networking/traceroute.c index 642110c54..eee4f8873 100644 --- a/networking/traceroute.c +++ b/networking/traceroute.c @@ -497,7 +497,7 @@ send_probe(int seq, int ttl) res = xsendto(sndsock, out, len, &dest_lsa->u.sa, dest_lsa->len); if (res != len) - bb_info_msg("sent %d octets, ret=%d", len, res); + bb_error_msg("sent %d octets, ret=%d", len, res); } #if ENABLE_FEATURE_TRACEROUTE_VERBOSE diff --git a/networking/tunctl.c b/networking/tunctl.c index 3a0870eb5..941e8bbd3 100644 --- a/networking/tunctl.c +++ b/networking/tunctl.c @@ -82,7 +82,7 @@ int tunctl_main(int argc UNUSED_PARAM, char **argv) // delete? if (opts & OPT_d) { IOCTL(fd, TUNSETPERSIST, (void *)(uintptr_t)0); - bb_info_msg("Set '%s' %spersistent", ifr.ifr_name, "non"); + printf("Set '%s' nonpersistent\n", ifr.ifr_name); return EXIT_SUCCESS; } diff --git a/util-linux/mkfs_ext2.c b/util-linux/mkfs_ext2.c index 749f42068..f91a0b4bf 100644 --- a/util-linux/mkfs_ext2.c +++ b/util-linux/mkfs_ext2.c @@ -151,7 +151,7 @@ static uint32_t has_super(uint32_t x) static void PUT(uint64_t off, void *buf, uint32_t size) { -// bb_info_msg("PUT[%llu]:[%u]", off, size); + //bb_error_msg("PUT[%llu]:[%u]", off, size); xlseek(fd, off, SEEK_SET); xwrite(fd, buf, size); } From cde1199e01aa14f1777f97cdcb7d0de2d00add80 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Wed, 30 Mar 2016 16:22:13 +0200 Subject: [PATCH 175/260] zcip: use bb_error_msg for logging, not bb_info_msg Signed-off-by: Denys Vlasenko --- networking/zcip.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/networking/zcip.c b/networking/zcip.c index 1d6910555..c93082619 100644 --- a/networking/zcip.c +++ b/networking/zcip.c @@ -176,7 +176,7 @@ static int run(char *argv[3], const char *param, uint32_t nip) xsetenv("ip", addr); fmt -= 3; } - bb_info_msg(fmt, argv[2], argv[0], addr); + bb_error_msg(fmt, argv[2], argv[0], addr); status = spawn_and_wait(argv + 1); if (status < 0) { @@ -317,7 +317,7 @@ int zcip_main(int argc UNUSED_PARAM, char **argv) #if BB_MMU bb_daemonize(0 /*was: DAEMON_CHDIR_ROOT*/); #endif - bb_info_msg("start, interface %s", argv_intf); + bb_error_msg("start, interface %s", argv_intf); } // Run the dynamic address negotiation protocol, From 3b757f07982b38b7a550c10ca37c9d173d450cac Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Wed, 30 Mar 2016 16:23:10 +0200 Subject: [PATCH 176/260] mkfs_vfat: use bb_error_msg for logging, not bb_info_msg This affects only a commented-out code section which searches for bad blocks Signed-off-by: Denys Vlasenko --- util-linux/mkfs_vfat.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/util-linux/mkfs_vfat.c b/util-linux/mkfs_vfat.c index 7d81ed06d..d53c751eb 100644 --- a/util-linux/mkfs_vfat.c +++ b/util-linux/mkfs_vfat.c @@ -578,7 +578,7 @@ int mkfs_vfat_main(int argc UNUSED_PARAM, char **argv) start_data_sector = (reserved_sect + NUM_FATS * sect_per_fat) * (bytes_per_sect / SECTOR_SIZE); start_data_block = (start_data_sector + SECTORS_PER_BLOCK - 1) / SECTORS_PER_BLOCK; - bb_info_msg("searching for bad blocks "); + bb_error_msg("searching for bad blocks"); currently_testing = 0; try = TEST_BUFFER_BLOCKS; while (currently_testing < volume_size_blocks) { @@ -616,7 +616,7 @@ int mkfs_vfat_main(int argc UNUSED_PARAM, char **argv) } free(blkbuf); if (badblocks) - bb_info_msg("%d bad block(s)", badblocks); + bb_error_msg("%d bad block(s)", badblocks); } #endif From c418f48d8dd311f2c093f8f5727b93e40a512330 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Wed, 30 Mar 2016 16:30:24 +0200 Subject: [PATCH 177/260] fsck: use printf for message, not bb_info_msg Signed-off-by: Denys Vlasenko --- e2fsprogs/fsck.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/e2fsprogs/fsck.c b/e2fsprogs/fsck.c index 8d89179e3..987d97528 100644 --- a/e2fsprogs/fsck.c +++ b/e2fsprogs/fsck.c @@ -602,7 +602,7 @@ static void fsck_device(struct fs_info *fs /*, int interactive */) if (strcmp(fs->type, "auto") != 0) { type = fs->type; if (G.verbose > 2) - bb_info_msg("using filesystem type '%s' %s", + printf("using filesystem type '%s' %s\n", type, "from fstab"); } else if (G.fstype && (G.fstype[0] != 'n' || G.fstype[1] != 'o') /* != "no" */ @@ -612,12 +612,12 @@ static void fsck_device(struct fs_info *fs /*, int interactive */) ) { type = G.fstype; if (G.verbose > 2) - bb_info_msg("using filesystem type '%s' %s", + printf("using filesystem type '%s' %s\n", type, "from -t"); } else { type = "auto"; if (G.verbose > 2) - bb_info_msg("using filesystem type '%s' %s", + printf("using filesystem type '%s' %s\n", type, "(default)"); } From 8ac6effb029f1fe4f620e061c1b62c4721f41491 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Wed, 30 Mar 2016 16:49:13 +0200 Subject: [PATCH 178/260] sulogin: Dorp incorrect comment about suid-ness Sulogin is not a suid app, should fail if run by non-root. Signed-off-by: Denys Vlasenko --- loginutils/sulogin.c | 1 - 1 file changed, 1 deletion(-) diff --git a/loginutils/sulogin.c b/loginutils/sulogin.c index 19b1e304c..d2ac1f65d 100644 --- a/loginutils/sulogin.c +++ b/loginutils/sulogin.c @@ -12,7 +12,6 @@ //config: sulogin is invoked when the system goes into single user //config: mode (this is done through an entry in inittab). -//applet:/* Needs to be run by root or be suid root - needs to change uid and gid: */ //applet:IF_SULOGIN(APPLET(sulogin, BB_DIR_SBIN, BB_SUID_DROP)) //kbuild:lib-$(CONFIG_SULOGIN) += sulogin.o From 32c08acba3d938ec2fa4f9d2ff8160bbe05a20cb Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Wed, 30 Mar 2016 17:27:32 +0200 Subject: [PATCH 179/260] sulogin: remove suid paranoia code, explain why it's not necessary function old new delta sulogin_main 325 270 -55 Signed-off-by: Denys Vlasenko --- loginutils/sulogin.c | 22 +++++++++------------- 1 file changed, 9 insertions(+), 13 deletions(-) diff --git a/loginutils/sulogin.c b/loginutils/sulogin.c index d2ac1f65d..33f078ae7 100644 --- a/loginutils/sulogin.c +++ b/loginutils/sulogin.c @@ -32,6 +32,14 @@ int sulogin_main(int argc UNUSED_PARAM, char **argv) struct passwd *pwd; const char *shell; + /* Note: sulogin is not a suid app. It is meant to be run by init + * for single user / emergency mode. init starts it as root. + * Normal users (potentially malisious ones) can only run it under + * their UID, therefore no paranoia here is warranted: + * $LD_LIBRARY_PATH in env, TTY = /dev/sda + * are no more dangerous here than in e.g. cp applet. + */ + logmode = LOGMODE_BOTH; openlog(applet_name, 0, LOG_AUTH); @@ -47,18 +55,9 @@ int sulogin_main(int argc UNUSED_PARAM, char **argv) dup(0); } - /* Malicious use like "sulogin /dev/sda"? */ - if (!isatty(0) || !isatty(1) || !isatty(2)) { - logmode = LOGMODE_SYSLOG; - bb_error_msg_and_die("not a tty"); - } - - /* Clear dangerous stuff, set PATH */ - sanitize_env_if_suid(); - pwd = getpwuid(0); if (!pwd) { - goto auth_error; + bb_error_msg_and_die("no password entry for root"); } while (1) { @@ -92,7 +91,4 @@ int sulogin_main(int argc UNUSED_PARAM, char **argv) /* Exec login shell with no additional parameters. Never returns. */ run_shell(shell, 1, NULL, NULL); - - auth_error: - bb_error_msg_and_die("no password entry for root"); } From 2a17fbe88a0cc064248db4ce8939f0fbc357922d Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Wed, 30 Mar 2016 17:36:20 +0200 Subject: [PATCH 180/260] sulogin: use bb_error_msg instead of bb_info_msg; better message Historic "System Maintenance Mode" message is a tiny bit cryptic. Let's say explicitly what we are doing: we are giving user a shell (presumably to do some maintenance in single-user mode). Signed-off-by: Denys Vlasenko --- loginutils/sulogin.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/loginutils/sulogin.c b/loginutils/sulogin.c index 33f078ae7..f32469551 100644 --- a/loginutils/sulogin.c +++ b/loginutils/sulogin.c @@ -69,17 +69,17 @@ int sulogin_main(int argc UNUSED_PARAM, char **argv) ); if (r < 0) { /* ^D, ^C, timeout, or read error */ - bb_info_msg("Normal startup"); + bb_error_msg("normal startup"); return 0; } if (r > 0) { break; } bb_do_delay(LOGIN_FAIL_DELAY); - bb_info_msg("Login incorrect"); + bb_error_msg("Login incorrect"); } - bb_info_msg("System Maintenance Mode"); + bb_error_msg("starting shell for system maintenance"); IF_SELINUX(renew_current_security_context()); From 80f0f1d712fb3ab236e1fc8b37dfa7a9224d7849 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Wed, 30 Mar 2016 18:17:35 +0200 Subject: [PATCH 181/260] setfiles: switch bb_info_msg to printf Presumably, bb_info_msg was used here for syslog logging (-l), but there is no actual code to activate syslog logging. Added a TODO note on that, so that selinux users would notice and fix if needed. Signed-off-by: Denys Vlasenko --- selinux/setfiles.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/selinux/setfiles.c b/selinux/setfiles.c index c974c4a9d..de99dfe44 100644 --- a/selinux/setfiles.c +++ b/selinux/setfiles.c @@ -17,6 +17,7 @@ //usage: ) //usage: "\n -d Show which specification matched each file" //usage: "\n -l Log changes in file labels to syslog" +//TODO: log to syslog is not yet implemented, it goes to stdout only now //usage: "\n -n Don't change any file labels" //usage: "\n -q Suppress warnings" //usage: "\n -r DIR Use an alternate root path" @@ -383,16 +384,16 @@ static int restore(const char *file) * the user has changed but the role and type are the * same. For "-vv", emit everything. */ if (verbose > 1 || !user_only_changed) { - bb_info_msg("%s: reset %s context %s->%s", + printf("%s: reset %s context %s->%s\n", applet_name, my_file, context ? context : "", newcon); } } if (FLAG_l_take_log && !user_only_changed) { if (context) - bb_info_msg("relabeling %s from %s to %s", my_file, context, newcon); + printf("relabeling %s from %s to %s\n", my_file, context, newcon); else - bb_info_msg("labeling %s to %s", my_file, newcon); + printf("labeling %s to %s\n", my_file, newcon); } if (outfile && !user_only_changed) From 8f2e99c813dcac25faf58162ed18848a02888ff6 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Wed, 30 Mar 2016 18:41:23 +0200 Subject: [PATCH 182/260] udhcp: get rid of bb_info_msg() function old new delta udhcpd_main 1501 1531 +30 d6_recv_raw_packet 251 264 +13 perform_d6_release 188 198 +10 udhcpc6_main 2443 2449 +6 udhcp_recv_raw_packet 582 588 +6 udhcp_recv_kernel_packet 132 138 +6 send_d6_renew 140 146 +6 d6_recv_kernel_packet 118 124 +6 send_renew 77 82 +5 send_discover 85 90 +5 send_decline 84 89 +5 send_d6_select 97 102 +5 send_d6_discover 174 179 +5 perform_release 167 172 +5 count_lines 72 74 +2 udhcpc_main 2836 2837 +1 bb_info_msg 125 - -125 ------------------------------------------------------------------------------ (add/remove: 0/2 grow/shrink: 17/4 up/down: 117/-180) Total: -63 bytes text data bss dec hex filename 924935 906 17160 943001 e6399 busybox_old 924736 906 17160 942802 e62d2 busybox_unstripped Signed-off-by: Denys Vlasenko --- include/libbb.h | 1 - libbb/Kbuild.src | 1 - libbb/info_msg.c | 62 ---------------------------- networking/udhcp/arpping.c | 2 +- networking/udhcp/common.c | 8 ++-- networking/udhcp/common.h | 6 +-- networking/udhcp/d6_dhcpc.c | 60 +++++++++++++-------------- networking/udhcp/d6_packet.c | 10 ++--- networking/udhcp/d6_socket.c | 2 +- networking/udhcp/dhcpc.c | 70 ++++++++++++++++---------------- networking/udhcp/dhcpd.c | 34 ++++++++-------- networking/udhcp/files.c | 2 +- networking/udhcp/leases.c | 2 +- networking/udhcp/packet.c | 12 +++--- networking/udhcp/socket.c | 4 +- networking/udhcp/static_leases.c | 2 +- 16 files changed, 107 insertions(+), 171 deletions(-) delete mode 100644 libbb/info_msg.c diff --git a/include/libbb.h b/include/libbb.h index 8b226c00c..98d788402 100644 --- a/include/libbb.h +++ b/include/libbb.h @@ -1150,7 +1150,6 @@ extern void bb_herror_msg(const char *s, ...) __attribute__ ((format (printf, 1, extern void bb_herror_msg_and_die(const char *s, ...) __attribute__ ((noreturn, format (printf, 1, 2))) FAST_FUNC; extern void bb_perror_nomsg_and_die(void) NORETURN FAST_FUNC; extern void bb_perror_nomsg(void) FAST_FUNC; -extern void bb_info_msg(const char *s, ...) __attribute__ ((format (printf, 1, 2))) FAST_FUNC; extern void bb_verror_msg(const char *s, va_list p, const char *strerr) FAST_FUNC; extern void bb_logenv_override(void) FAST_FUNC; diff --git a/libbb/Kbuild.src b/libbb/Kbuild.src index 7fb687227..b08ce1158 100644 --- a/libbb/Kbuild.src +++ b/libbb/Kbuild.src @@ -46,7 +46,6 @@ lib-y += get_volsize.o lib-y += herror_msg.o lib-y += human_readable.o lib-y += inet_common.o -lib-y += info_msg.o lib-y += inode_hash.o lib-y += isdirectory.o lib-y += kernel_version.o diff --git a/libbb/info_msg.c b/libbb/info_msg.c deleted file mode 100644 index 56ca2efd4..000000000 --- a/libbb/info_msg.c +++ /dev/null @@ -1,62 +0,0 @@ -/* vi: set sw=4 ts=4: */ -/* - * Utility routines. - * - * Copyright (C) 1999-2004 by Erik Andersen - * - * Licensed under GPLv2 or later, see file LICENSE in this source tree. - */ - -#include "libbb.h" -#if ENABLE_FEATURE_SYSLOG -# include -#endif - -void FAST_FUNC bb_info_msg(const char *s, ...) -{ -#ifdef THIS_ONE_DOESNT_DO_SINGLE_WRITE - va_list p; - /* va_copy is used because it is not portable - * to use va_list p twice */ - va_list p2; - - va_start(p, s); - va_copy(p2, p); - if (logmode & LOGMODE_STDIO) { - vprintf(s, p); - fputs(msg_eol, stdout); - } -# if ENABLE_FEATURE_SYSLOG - if (logmode & LOGMODE_SYSLOG) - vsyslog(LOG_INFO, s, p2); -# endif - va_end(p2); - va_end(p); -#else - int used; - char *msg; - va_list p; - - if (logmode == 0) - return; - - va_start(p, s); - used = vasprintf(&msg, s, p); - va_end(p); - if (used < 0) - return; - -# if ENABLE_FEATURE_SYSLOG - if (logmode & LOGMODE_SYSLOG) - syslog(LOG_INFO, "%s", msg); -# endif - if (logmode & LOGMODE_STDIO) { - fflush_all(); - /* used = strlen(msg); - must be true already */ - msg[used++] = '\n'; - full_write(STDOUT_FILENO, msg, used); - } - - free(msg); -#endif -} diff --git a/networking/udhcp/arpping.c b/networking/udhcp/arpping.c index fad2283c3..c98027316 100644 --- a/networking/udhcp/arpping.c +++ b/networking/udhcp/arpping.c @@ -132,6 +132,6 @@ int FAST_FUNC arpping(uint32_t test_nip, ret: close(s); - log1("%srp reply received for this address", rv ? "No a" : "A"); + log1("%srp reply received for this address", rv ? "no a" : "A"); return rv; } diff --git a/networking/udhcp/common.c b/networking/udhcp/common.c index 680852ce4..1c1863451 100644 --- a/networking/udhcp/common.c +++ b/networking/udhcp/common.c @@ -183,7 +183,7 @@ static void log_option(const char *pfx, const uint8_t *opt) if (dhcp_verbose >= 2) { char buf[256 * 2 + 2]; *bin2hex(buf, (void*) (opt + OPT_DATA), opt[OPT_LEN]) = '\0'; - bb_info_msg("%s: 0x%02x %s", pfx, opt[OPT_CODE], buf); + bb_error_msg("%s: 0x%02x %s", pfx, opt[OPT_CODE], buf); } } #else @@ -269,7 +269,7 @@ uint8_t* FAST_FUNC udhcp_get_option(struct dhcp_packet *packet, int code) } /* log3 because udhcpc uses it a lot - very noisy */ - log3("Option 0x%02x not found", code); + log3("option 0x%02x not found", code); return NULL; } @@ -402,7 +402,7 @@ static NOINLINE void attach_option( struct option_set *new, **curr; /* make a new option */ - log2("Attaching option %02x to list", optflag->code); + log2("attaching option %02x to list", optflag->code); new = xmalloc(sizeof(*new)); new->data = xmalloc(length + OPT_DATA); new->data[OPT_CODE] = optflag->code; @@ -422,7 +422,7 @@ static NOINLINE void attach_option( unsigned old_len; /* add it to an existing option */ - log2("Attaching option %02x to existing member of list", optflag->code); + log2("attaching option %02x to existing member of list", optflag->code); old_len = existing->data[OPT_LEN]; if (old_len + length < 255) { /* actually 255 is ok too, but adding a space can overlow it */ diff --git a/networking/udhcp/common.h b/networking/udhcp/common.h index d20659e2f..496ab11a1 100644 --- a/networking/udhcp/common.h +++ b/networking/udhcp/common.h @@ -256,16 +256,16 @@ struct option_set *udhcp_find_option(struct option_set *opt_list, uint8_t code) #if defined CONFIG_UDHCP_DEBUG && CONFIG_UDHCP_DEBUG >= 1 # define IF_UDHCP_VERBOSE(...) __VA_ARGS__ extern unsigned dhcp_verbose; -# define log1(...) do { if (dhcp_verbose >= 1) bb_info_msg(__VA_ARGS__); } while (0) +# define log1(...) do { if (dhcp_verbose >= 1) bb_error_msg(__VA_ARGS__); } while (0) # if CONFIG_UDHCP_DEBUG >= 2 void udhcp_dump_packet(struct dhcp_packet *packet) FAST_FUNC; -# define log2(...) do { if (dhcp_verbose >= 2) bb_info_msg(__VA_ARGS__); } while (0) +# define log2(...) do { if (dhcp_verbose >= 2) bb_error_msg(__VA_ARGS__); } while (0) # else # define udhcp_dump_packet(...) ((void)0) # define log2(...) ((void)0) # endif # if CONFIG_UDHCP_DEBUG >= 3 -# define log3(...) do { if (dhcp_verbose >= 3) bb_info_msg(__VA_ARGS__); } while (0) +# define log3(...) do { if (dhcp_verbose >= 3) bb_error_msg(__VA_ARGS__); } while (0) # else # define log3(...) ((void)0) # endif diff --git a/networking/udhcp/d6_dhcpc.c b/networking/udhcp/d6_dhcpc.c index 4e9b705b9..422254d62 100644 --- a/networking/udhcp/d6_dhcpc.c +++ b/networking/udhcp/d6_dhcpc.c @@ -251,7 +251,7 @@ static void d6_run_script(struct d6_packet *packet, const char *name) envp = fill_envp(packet); /* call script */ - log1("Executing %s %s", client_config.script, name); + log1("executing %s %s", client_config.script, name); argv[0] = (char*) client_config.script; argv[1] = (char*) name; argv[2] = NULL; @@ -428,7 +428,7 @@ static NOINLINE int send_d6_discover(uint32_t xid, struct in6_addr *requested_ip */ opt_ptr = add_d6_client_options(opt_ptr); - bb_info_msg("Sending discover..."); + bb_error_msg("sending %s", "discover"); return d6_mcast_from_client_config_ifindex(&packet, opt_ptr); } @@ -481,7 +481,7 @@ static NOINLINE int send_d6_select(uint32_t xid) */ opt_ptr = add_d6_client_options(opt_ptr); - bb_info_msg("Sending select..."); + bb_error_msg("sending %s", "select"); return d6_mcast_from_client_config_ifindex(&packet, opt_ptr); } @@ -550,7 +550,7 @@ static NOINLINE int send_d6_renew(uint32_t xid, struct in6_addr *server_ipv6, st */ opt_ptr = add_d6_client_options(opt_ptr); - bb_info_msg("Sending renew..."); + bb_error_msg("sending %s", "renew"); if (server_ipv6) return d6_send_kernel_packet( &packet, (opt_ptr - (uint8_t*) &packet), @@ -573,7 +573,7 @@ static int send_d6_release(struct in6_addr *server_ipv6, struct in6_addr *our_cu /* IA NA (contains our current IP) */ opt_ptr = d6_store_blob(opt_ptr, client6_data.ia_na, client6_data.ia_na->len + 2+2); - bb_info_msg("Sending release..."); + bb_error_msg("sending %s", "release"); return d6_send_kernel_packet( &packet, (opt_ptr - (uint8_t*) &packet), our_cur_ipv6, CLIENT_PORT6, @@ -592,19 +592,19 @@ static NOINLINE int d6_recv_raw_packet(struct in6_addr *peer_ipv6 bytes = safe_read(fd, &packet, sizeof(packet)); if (bytes < 0) { - log1("Packet read error, ignoring"); + log1("packet read error, ignoring"); /* NB: possible down interface, etc. Caller should pause. */ return bytes; /* returns -1 */ } if (bytes < (int) (sizeof(packet.ip6) + sizeof(packet.udp))) { - log1("Packet is too short, ignoring"); + log1("packet is too short, ignoring"); return -2; } if (bytes < sizeof(packet.ip6) + ntohs(packet.ip6.ip6_plen)) { /* packet is bigger than sizeof(packet), we did partial read */ - log1("Oversized packet, ignoring"); + log1("oversized packet, ignoring"); return -2; } @@ -618,7 +618,7 @@ static NOINLINE int d6_recv_raw_packet(struct in6_addr *peer_ipv6 /* || bytes > (int) sizeof(packet) - can't happen */ || packet.udp.len != packet.ip6.ip6_plen ) { - log1("Unrelated/bogus packet, ignoring"); + log1("unrelated/bogus packet, ignoring"); return -2; } @@ -630,11 +630,11 @@ static NOINLINE int d6_recv_raw_packet(struct in6_addr *peer_ipv6 // check = packet.udp.check; // packet.udp.check = 0; // if (check && check != inet_cksum((uint16_t *)&packet, bytes)) { -// log1("Packet with bad UDP checksum received, ignoring"); +// log1("packet with bad UDP checksum received, ignoring"); // return -2; // } - log1("Received a packet"); + log1("received %s", "a packet"); d6_dump_packet(&packet.data); bytes -= sizeof(packet.ip6) + sizeof(packet.udp); @@ -722,10 +722,10 @@ static int d6_raw_socket(int ifindex) }; #endif - log1("Opening raw socket on ifindex %d", ifindex); //log2? + log1("opening raw socket on ifindex %d", ifindex); //log2? fd = xsocket(PF_PACKET, SOCK_DGRAM, htons(ETH_P_IPV6)); - log1("Got raw socket fd %d", fd); //log2? + log1("got raw socket fd %d", fd); //log2? sock.sll_family = AF_PACKET; sock.sll_protocol = htons(ETH_P_IPV6); @@ -738,18 +738,18 @@ static int d6_raw_socket(int ifindex) /* Ignoring error (kernel may lack support for this) */ if (setsockopt(fd, SOL_SOCKET, SO_ATTACH_FILTER, &filter_prog, sizeof(filter_prog)) >= 0) - log1("Attached filter to raw socket fd %d", fd); // log? + log1("attached filter to raw socket fd %d", fd); // log? } #endif - log1("Created raw socket"); + log1("created raw socket"); return fd; } static void change_listen_mode(int new_mode) { - log1("Entering listen mode: %s", + log1("entering listen mode: %s", new_mode != LISTEN_NONE ? (new_mode == LISTEN_KERNEL ? "kernel" : "raw") : "none" @@ -770,7 +770,7 @@ static void change_listen_mode(int new_mode) /* Called only on SIGUSR1 */ static void perform_renew(void) { - bb_info_msg("Performing a DHCP renew"); + bb_error_msg("performing DHCP renew"); switch (state) { case BOUND: change_listen_mode(LISTEN_KERNEL); @@ -794,11 +794,11 @@ static void perform_d6_release(struct in6_addr *server_ipv6, struct in6_addr *ou { /* send release packet */ if (state == BOUND || state == RENEWING || state == REBINDING) { - bb_info_msg("Unicasting a release"); + bb_error_msg("unicasting a release"); send_d6_release(server_ipv6, our_cur_ipv6); /* unicast */ d6_run_script(NULL, "deconfig"); } - bb_info_msg("Entering released state"); + bb_error_msg("entering released state"); change_listen_mode(LISTEN_NONE); state = RELEASED; @@ -1034,7 +1034,7 @@ int udhcpc6_main(int argc UNUSED_PARAM, char **argv) /* Create pidfile */ write_pidfile(client_config.pidfile); /* Goes to stdout (unless NOMMU) and possibly syslog */ - bb_info_msg("%s (v"BB_VER") started", applet_name); + bb_error_msg("started, v"BB_VER); /* Set up the signal pipe */ udhcp_sp_setup(); /* We want random_xid to be random... */ @@ -1074,7 +1074,7 @@ int udhcpc6_main(int argc UNUSED_PARAM, char **argv) retval = 0; /* If we already timed out, fall through with retval = 0, else... */ if ((int)tv.tv_sec > 0) { - log1("Waiting on select %u seconds", (int)tv.tv_sec); + log1("waiting on select %u seconds", (int)tv.tv_sec); timestamp_before_wait = (unsigned)monotonic_sec(); retval = select(max_fd + 1, &rfds, NULL, NULL, &tv); if (retval < 0) { @@ -1124,14 +1124,14 @@ int udhcpc6_main(int argc UNUSED_PARAM, char **argv) d6_run_script(NULL, "leasefail"); #if BB_MMU /* -b is not supported on NOMMU */ if (opt & OPT_b) { /* background if no lease */ - bb_info_msg("No lease, forking to background"); + bb_error_msg("no lease, forking to background"); client_background(); /* do not background again! */ opt = ((opt & ~OPT_b) | OPT_f); } else #endif if (opt & OPT_n) { /* abort if no lease */ - bb_info_msg("No lease, failing"); + bb_error_msg("no lease, failing"); retval = 1; goto ret; } @@ -1159,7 +1159,7 @@ int udhcpc6_main(int argc UNUSED_PARAM, char **argv) state = RENEWING; client_config.first_secs = 0; /* make secs field count from 0 */ change_listen_mode(LISTEN_KERNEL); - log1("Entering renew state"); + log1("entering renew state"); /* fall right through */ case RENEW_REQUESTED: /* manual (SIGUSR1) renew */ case_RENEW_REQUESTED: @@ -1179,7 +1179,7 @@ int udhcpc6_main(int argc UNUSED_PARAM, char **argv) continue; } /* Timed out, enter rebinding state */ - log1("Entering rebinding state"); + log1("entering rebinding state"); state = REBINDING; /* fall right through */ case REBINDING: @@ -1194,7 +1194,7 @@ int udhcpc6_main(int argc UNUSED_PARAM, char **argv) continue; } /* Timed out, enter init state */ - bb_info_msg("Lease lost, entering init state"); + bb_error_msg("lease lost, entering init state"); d6_run_script(NULL, "deconfig"); state = INIT_SELECTING; client_config.first_secs = 0; /* make secs field count from 0 */ @@ -1242,7 +1242,7 @@ int udhcpc6_main(int argc UNUSED_PARAM, char **argv) timeout = INT_MAX; continue; case SIGTERM: - bb_info_msg("Received SIGTERM"); + bb_error_msg("received %s", "SIGTERM"); goto ret0; } @@ -1260,7 +1260,7 @@ int udhcpc6_main(int argc UNUSED_PARAM, char **argv) len = d6_recv_raw_packet(&srv6_buf, &packet, sockfd); if (len == -1) { /* Error is severe, reopen socket */ - bb_info_msg("Read error: %s, reopening socket", strerror(errno)); + bb_error_msg("read error: %s, reopening socket", strerror(errno)); sleep(discover_timeout); /* 3 seconds by default */ change_listen_mode(listen_mode); /* just close and reopen */ } @@ -1298,7 +1298,7 @@ int udhcpc6_main(int argc UNUSED_PARAM, char **argv) option = d6_find_option(packet.d6_options, packet_end, D6_OPT_STATUS_CODE); if (option && option->data[4] != 0) { /* return to init state */ - bb_info_msg("Received DHCP NAK (%u)", option->data[4]); + bb_error_msg("received DHCP NAK (%u)", option->data[4]); d6_run_script(&packet, "nak"); if (state != REQUESTING) d6_run_script(NULL, "deconfig"); @@ -1453,7 +1453,7 @@ int udhcpc6_main(int argc UNUSED_PARAM, char **argv) lease_seconds = 0x0fffffff; /* enter bound state */ timeout = lease_seconds / 2; - bb_info_msg("Lease obtained, lease time %u", + bb_error_msg("lease obtained, lease time %u", /*inet_ntoa(temp_addr),*/ (unsigned)lease_seconds); d6_run_script(&packet, state == REQUESTING ? "bound" : "renew"); diff --git a/networking/udhcp/d6_packet.c b/networking/udhcp/d6_packet.c index b340b5db6..e166f520d 100644 --- a/networking/udhcp/d6_packet.c +++ b/networking/udhcp/d6_packet.c @@ -17,8 +17,8 @@ void FAST_FUNC d6_dump_packet(struct d6_packet *packet) if (dhcp_verbose < 2) return; - bb_info_msg( - " xid %x" + bb_error_msg( + "xid %x" , packet->d6_xid32 ); //*bin2hex(buf, (void *) packet->chaddr, sizeof(packet->chaddr)) = '\0'; @@ -35,15 +35,15 @@ int FAST_FUNC d6_recv_kernel_packet(struct in6_addr *peer_ipv6 memset(packet, 0, sizeof(*packet)); bytes = safe_read(fd, packet, sizeof(*packet)); if (bytes < 0) { - log1("Packet read error, ignoring"); + log1("packet read error, ignoring"); return bytes; /* returns -1 */ } if (bytes < offsetof(struct d6_packet, d6_options)) { - bb_info_msg("Packet with bad magic, ignoring"); + bb_error_msg("packet with bad magic, ignoring"); return -2; } - log1("Received a packet"); + log1("received %s", "a packet"); d6_dump_packet(packet); return bytes; diff --git a/networking/udhcp/d6_socket.c b/networking/udhcp/d6_socket.c index 56f69f6a1..910f296a3 100644 --- a/networking/udhcp/d6_socket.c +++ b/networking/udhcp/d6_socket.c @@ -13,7 +13,7 @@ int FAST_FUNC d6_listen_socket(int port, const char *inf) int fd; struct sockaddr_in6 addr; - log1("Opening listen socket on *:%d %s", port, inf); + log1("opening listen socket on *:%d %s", port, inf); fd = xsocket(PF_INET6, SOCK_DGRAM, IPPROTO_UDP); setsockopt_reuseaddr(fd); diff --git a/networking/udhcp/dhcpc.c b/networking/udhcp/dhcpc.c index dfd5ca606..660b943ce 100644 --- a/networking/udhcp/dhcpc.c +++ b/networking/udhcp/dhcpc.c @@ -561,7 +561,7 @@ static void udhcp_run_script(struct dhcp_packet *packet, const char *name) envp = fill_envp(packet); /* call script */ - log1("Executing %s %s", client_config.script, name); + log1("executing %s %s", client_config.script, name); argv[0] = (char*) client_config.script; argv[1] = (char*) name; argv[2] = NULL; @@ -714,7 +714,7 @@ static NOINLINE int send_discover(uint32_t xid, uint32_t requested) */ add_client_options(&packet); - bb_info_msg("Sending discover..."); + bb_error_msg("sending %s", "discover"); return raw_bcast_from_client_config_ifindex(&packet, INADDR_ANY); } @@ -758,7 +758,7 @@ static NOINLINE int send_select(uint32_t xid, uint32_t server, uint32_t requeste add_client_options(&packet); addr.s_addr = requested; - bb_info_msg("Sending select for %s...", inet_ntoa(addr)); + bb_error_msg("sending select for %s", inet_ntoa(addr)); return raw_bcast_from_client_config_ifindex(&packet, INADDR_ANY); } @@ -797,7 +797,7 @@ static NOINLINE int send_renew(uint32_t xid, uint32_t server, uint32_t ciaddr) */ add_client_options(&packet); - bb_info_msg("Sending renew..."); + bb_error_msg("sending %s", "renew"); return bcast_or_ucast(&packet, ciaddr, server); } @@ -826,7 +826,7 @@ static NOINLINE int send_decline(/*uint32_t xid,*/ uint32_t server, uint32_t req udhcp_add_simple_option(&packet, DHCP_SERVER_ID, server); - bb_info_msg("Sending decline..."); + bb_error_msg("sending %s", "decline"); return raw_bcast_from_client_config_ifindex(&packet, INADDR_ANY); } #endif @@ -846,7 +846,7 @@ static int send_release(uint32_t server, uint32_t ciaddr) udhcp_add_simple_option(&packet, DHCP_SERVER_ID, server); - bb_info_msg("Sending release..."); + bb_error_msg("sending %s", "release"); /* Note: normally we unicast here since "server" is not zero. * However, there _are_ people who run "address-less" DHCP servers, * and reportedly ISC dhcp client and Windows allow that. @@ -881,7 +881,7 @@ static NOINLINE int udhcp_recv_raw_packet(struct dhcp_packet *dhcp_pkt, int fd) if (bytes < 0) { if (errno == EINTR) continue; - log1("Packet read error, ignoring"); + log1("packet read error, ignoring"); /* NB: possible down interface, etc. Caller should pause. */ return bytes; /* returns -1 */ } @@ -889,13 +889,13 @@ static NOINLINE int udhcp_recv_raw_packet(struct dhcp_packet *dhcp_pkt, int fd) } if (bytes < (int) (sizeof(packet.ip) + sizeof(packet.udp))) { - log1("Packet is too short, ignoring"); + log1("packet is too short, ignoring"); return -2; } if (bytes < ntohs(packet.ip.tot_len)) { /* packet is bigger than sizeof(packet), we did partial read */ - log1("Oversized packet, ignoring"); + log1("oversized packet, ignoring"); return -2; } @@ -910,7 +910,7 @@ static NOINLINE int udhcp_recv_raw_packet(struct dhcp_packet *dhcp_pkt, int fd) /* || bytes > (int) sizeof(packet) - can't happen */ || ntohs(packet.udp.len) != (uint16_t)(bytes - sizeof(packet.ip)) ) { - log1("Unrelated/bogus packet, ignoring"); + log1("unrelated/bogus packet, ignoring"); return -2; } @@ -918,7 +918,7 @@ static NOINLINE int udhcp_recv_raw_packet(struct dhcp_packet *dhcp_pkt, int fd) check = packet.ip.check; packet.ip.check = 0; if (check != inet_cksum((uint16_t *)&packet.ip, sizeof(packet.ip))) { - log1("Bad IP header checksum, ignoring"); + log1("bad IP header checksum, ignoring"); return -2; } @@ -943,17 +943,17 @@ static NOINLINE int udhcp_recv_raw_packet(struct dhcp_packet *dhcp_pkt, int fd) check = packet.udp.check; packet.udp.check = 0; if (check && check != inet_cksum((uint16_t *)&packet, bytes)) { - log1("Packet with bad UDP checksum received, ignoring"); + log1("packet with bad UDP checksum received, ignoring"); return -2; } skip_udp_sum_check: if (packet.data.cookie != htonl(DHCP_MAGIC)) { - bb_info_msg("Packet with bad magic, ignoring"); + bb_error_msg("packet with bad magic, ignoring"); return -2; } - log1("Received a packet"); + log1("received %s", "a packet"); udhcp_dump_packet(&packet.data); bytes -= sizeof(packet.ip) + sizeof(packet.udp); @@ -992,14 +992,14 @@ static int udhcp_raw_socket(int ifindex) int fd; struct sockaddr_ll sock; - log1("Opening raw socket on ifindex %d", ifindex); //log2? + log1("opening raw socket on ifindex %d", ifindex); //log2? fd = xsocket(PF_PACKET, SOCK_DGRAM, htons(ETH_P_IP)); /* ^^^^^ * SOCK_DGRAM: remove link-layer headers on input (SOCK_RAW keeps them) * ETH_P_IP: want to receive only packets with IPv4 eth type */ - log1("Got raw socket fd"); //log2? + log1("got raw socket fd"); //log2? sock.sll_family = AF_PACKET; sock.sll_protocol = htons(ETH_P_IP); @@ -1055,23 +1055,23 @@ static int udhcp_raw_socket(int ifindex) /* Ignoring error (kernel may lack support for this) */ if (setsockopt(fd, SOL_SOCKET, SO_ATTACH_FILTER, &filter_prog, sizeof(filter_prog)) >= 0) - log1("Attached filter to raw socket fd"); // log? + log1("attached filter to raw socket fd"); // log? } #endif if (setsockopt_1(fd, SOL_PACKET, PACKET_AUXDATA) != 0) { if (errno != ENOPROTOOPT) - log1("Can't set PACKET_AUXDATA on raw socket"); + log1("can't set PACKET_AUXDATA on raw socket"); } - log1("Created raw socket"); + log1("created raw socket"); return fd; } static void change_listen_mode(int new_mode) { - log1("Entering listen mode: %s", + log1("entering listen mode: %s", new_mode != LISTEN_NONE ? (new_mode == LISTEN_KERNEL ? "kernel" : "raw") : "none" @@ -1092,7 +1092,7 @@ static void change_listen_mode(int new_mode) /* Called only on SIGUSR1 */ static void perform_renew(void) { - bb_info_msg("Performing a DHCP renew"); + bb_error_msg("performing DHCP renew"); switch (state) { case BOUND: change_listen_mode(LISTEN_KERNEL); @@ -1122,12 +1122,12 @@ static void perform_release(uint32_t server_addr, uint32_t requested_ip) temp_addr.s_addr = server_addr; strcpy(buffer, inet_ntoa(temp_addr)); temp_addr.s_addr = requested_ip; - bb_info_msg("Unicasting a release of %s to %s", + bb_error_msg("unicasting a release of %s to %s", inet_ntoa(temp_addr), buffer); send_release(server_addr, requested_ip); /* unicast */ udhcp_run_script(NULL, "deconfig"); } - bb_info_msg("Entering released state"); + bb_error_msg("entering released state"); change_listen_mode(LISTEN_NONE); state = RELEASED; @@ -1395,7 +1395,7 @@ int udhcpc_main(int argc UNUSED_PARAM, char **argv) /* Create pidfile */ write_pidfile(client_config.pidfile); /* Goes to stdout (unless NOMMU) and possibly syslog */ - bb_info_msg("%s (v"BB_VER") started", applet_name); + bb_error_msg("started, v"BB_VER); /* Set up the signal pipe */ udhcp_sp_setup(); /* We want random_xid to be random... */ @@ -1434,7 +1434,7 @@ int udhcpc_main(int argc UNUSED_PARAM, char **argv) retval = 0; /* If we already timed out, fall through with retval = 0, else... */ if ((int)tv.tv_sec > 0) { - log1("Waiting on select %u seconds", (int)tv.tv_sec); + log1("waiting on select %u seconds", (int)tv.tv_sec); timestamp_before_wait = (unsigned)monotonic_sec(); retval = select(max_fd + 1, &rfds, NULL, NULL, &tv); if (retval < 0) { @@ -1485,14 +1485,14 @@ int udhcpc_main(int argc UNUSED_PARAM, char **argv) udhcp_run_script(NULL, "leasefail"); #if BB_MMU /* -b is not supported on NOMMU */ if (opt & OPT_b) { /* background if no lease */ - bb_info_msg("No lease, forking to background"); + bb_error_msg("no lease, forking to background"); client_background(); /* do not background again! */ opt = ((opt & ~OPT_b) | OPT_f); } else #endif if (opt & OPT_n) { /* abort if no lease */ - bb_info_msg("No lease, failing"); + bb_error_msg("no lease, failing"); retval = 1; goto ret; } @@ -1520,7 +1520,7 @@ int udhcpc_main(int argc UNUSED_PARAM, char **argv) state = RENEWING; client_config.first_secs = 0; /* make secs field count from 0 */ change_listen_mode(LISTEN_KERNEL); - log1("Entering renew state"); + log1("entering renew state"); /* fall right through */ case RENEW_REQUESTED: /* manual (SIGUSR1) renew */ case_RENEW_REQUESTED: @@ -1540,7 +1540,7 @@ int udhcpc_main(int argc UNUSED_PARAM, char **argv) continue; } /* Timed out, enter rebinding state */ - log1("Entering rebinding state"); + log1("entering rebinding state"); state = REBINDING; /* fall right through */ case REBINDING: @@ -1555,7 +1555,7 @@ int udhcpc_main(int argc UNUSED_PARAM, char **argv) continue; } /* Timed out, enter init state */ - bb_info_msg("Lease lost, entering init state"); + bb_error_msg("lease lost, entering init state"); udhcp_run_script(NULL, "deconfig"); state = INIT_SELECTING; client_config.first_secs = 0; /* make secs field count from 0 */ @@ -1603,7 +1603,7 @@ int udhcpc_main(int argc UNUSED_PARAM, char **argv) timeout = INT_MAX; continue; case SIGTERM: - bb_info_msg("Received SIGTERM"); + bb_error_msg("received %s", "SIGTERM"); goto ret0; } @@ -1621,7 +1621,7 @@ int udhcpc_main(int argc UNUSED_PARAM, char **argv) len = udhcp_recv_raw_packet(&packet, sockfd); if (len == -1) { /* Error is severe, reopen socket */ - bb_info_msg("Read error: %s, reopening socket", strerror(errno)); + bb_error_msg("read error: %s, reopening socket", strerror(errno)); sleep(discover_timeout); /* 3 seconds by default */ change_listen_mode(listen_mode); /* just close and reopen */ } @@ -1744,7 +1744,7 @@ int udhcpc_main(int argc UNUSED_PARAM, char **argv) client_config.interface, arpping_ms) ) { - bb_info_msg("Offered address is in use " + bb_error_msg("offered address is in use " "(got ARP reply), declining"); send_decline(/*xid,*/ server_addr, packet.yiaddr); @@ -1763,7 +1763,7 @@ int udhcpc_main(int argc UNUSED_PARAM, char **argv) #endif /* enter bound state */ temp_addr.s_addr = packet.yiaddr; - bb_info_msg("Lease of %s obtained, lease time %u", + bb_error_msg("lease of %s obtained, lease time %u", inet_ntoa(temp_addr), (unsigned)lease_seconds); requested_ip = packet.yiaddr; @@ -1817,7 +1817,7 @@ int udhcpc_main(int argc UNUSED_PARAM, char **argv) goto non_matching_svid; } /* return to init state */ - bb_info_msg("Received DHCP NAK"); + bb_error_msg("received %s", "DHCP NAK"); udhcp_run_script(&packet, "nak"); if (state != REQUESTING) udhcp_run_script(NULL, "deconfig"); diff --git a/networking/udhcp/dhcpd.c b/networking/udhcp/dhcpd.c index 2de074f9b..79677ee93 100644 --- a/networking/udhcp/dhcpd.c +++ b/networking/udhcp/dhcpd.c @@ -61,11 +61,11 @@ static void send_packet_to_client(struct dhcp_packet *dhcp_pkt, int force_broadc || (dhcp_pkt->flags & htons(BROADCAST_FLAG)) || dhcp_pkt->ciaddr == 0 ) { - log1("Broadcasting packet to client"); + log1("broadcasting packet to client"); ciaddr = INADDR_BROADCAST; chaddr = MAC_BCAST_ADDR; } else { - log1("Unicasting packet to client ciaddr"); + log1("unicasting packet to client ciaddr"); ciaddr = dhcp_pkt->ciaddr; chaddr = dhcp_pkt->chaddr; } @@ -79,7 +79,7 @@ static void send_packet_to_client(struct dhcp_packet *dhcp_pkt, int force_broadc /* Send a packet to gateway_nip using the kernel ip stack */ static void send_packet_to_relay(struct dhcp_packet *dhcp_pkt) { - log1("Forwarding packet to relay"); + log1("forwarding packet to relay"); udhcp_send_kernel_packet(dhcp_pkt, server_config.server_nip, SERVER_PORT, @@ -214,7 +214,7 @@ static NOINLINE void send_offer(struct dhcp_packet *oldpacket, add_server_options(&packet); addr.s_addr = packet.yiaddr; - bb_info_msg("Sending OFFER of %s", inet_ntoa(addr)); + bb_error_msg("sending OFFER of %s", inet_ntoa(addr)); /* send_packet emits error message itself if it detects failure */ send_packet(&packet, /*force_bcast:*/ 0); } @@ -226,7 +226,7 @@ static NOINLINE void send_NAK(struct dhcp_packet *oldpacket) init_packet(&packet, oldpacket, DHCPNAK); - log1("Sending NAK"); + log1("sending NAK"); send_packet(&packet, /*force_bcast:*/ 1); } @@ -247,7 +247,7 @@ static NOINLINE void send_ACK(struct dhcp_packet *oldpacket, uint32_t yiaddr) add_server_options(&packet); addr.s_addr = yiaddr; - bb_info_msg("Sending ACK to %s", inet_ntoa(addr)); + bb_error_msg("sending ACK to %s", inet_ntoa(addr)); send_packet(&packet, /*force_bcast:*/ 0); p_host_name = (const char*) udhcp_get_option(oldpacket, DHCP_HOST_NAME); @@ -361,7 +361,7 @@ int udhcpd_main(int argc UNUSED_PARAM, char **argv) write_pidfile(server_config.pidfile); /* if (!..) bb_perror_msg("can't create pidfile %s", pidfile); */ - bb_info_msg("%s (v"BB_VER") started", applet_name); + bb_error_msg("started, v"BB_VER); option = udhcp_find_option(server_config.options, DHCP_LEASE_TIME); server_config.max_lease_sec = DEFAULT_LEASE_TIME; @@ -427,18 +427,18 @@ int udhcpd_main(int argc UNUSED_PARAM, char **argv) goto continue_with_autotime; } if (retval < 0 && errno != EINTR) { - log1("Error on select"); + log1("error on select"); continue; } switch (udhcp_sp_read(&rfds)) { case SIGUSR1: - bb_info_msg("Received SIGUSR1"); + bb_error_msg("received %s", "SIGUSR1"); write_leases(); /* why not just reset the timeout, eh */ goto continue_with_autotime; case SIGTERM: - bb_info_msg("Received SIGTERM"); + bb_error_msg("received %s", "SIGTERM"); write_leases(); goto ret0; case 0: /* no signal: read a packet */ @@ -451,7 +451,7 @@ int udhcpd_main(int argc UNUSED_PARAM, char **argv) if (bytes < 0) { /* bytes can also be -2 ("bad packet data") */ if (bytes == -1 && errno != EINTR) { - log1("Read error: %s, reopening socket", strerror(errno)); + log1("read error: %s, reopening socket", strerror(errno)); close(server_socket); server_socket = -1; } @@ -486,7 +486,7 @@ int udhcpd_main(int argc UNUSED_PARAM, char **argv) /* Look for a static/dynamic lease */ static_lease_nip = get_static_nip_by_mac(server_config.static_leases, &packet.chaddr); if (static_lease_nip) { - bb_info_msg("Found static lease: %x", static_lease_nip); + bb_error_msg("found static lease: %x", static_lease_nip); memcpy(&fake_lease.lease_mac, &packet.chaddr, 6); fake_lease.lease_nip = static_lease_nip; fake_lease.expires = 0; @@ -504,13 +504,13 @@ int udhcpd_main(int argc UNUSED_PARAM, char **argv) switch (state[0]) { case DHCPDISCOVER: - log1("Received DISCOVER"); + log1("received %s", "DISCOVER"); send_offer(&packet, static_lease_nip, lease, requested_ip_opt, arpping_ms); break; case DHCPREQUEST: - log1("Received REQUEST"); + log1("received %s", "REQUEST"); /* RFC 2131: o DHCPREQUEST generated during SELECTING state: @@ -635,7 +635,7 @@ o DHCPREQUEST generated during REBINDING state: * chaddr must be filled in, * ciaddr must be 0 (we do not check this) */ - log1("Received DECLINE"); + log1("received %s", "DECLINE"); if (server_id_opt && requested_ip_opt && lease /* chaddr matches this lease */ @@ -655,7 +655,7 @@ o DHCPREQUEST generated during REBINDING state: * chaddr must be filled in, * ciaddr must be filled in */ - log1("Received RELEASE"); + log1("received %s", "RELEASE"); if (server_id_opt && lease /* chaddr matches this lease */ && packet.ciaddr == lease->lease_nip @@ -665,7 +665,7 @@ o DHCPREQUEST generated during REBINDING state: break; case DHCPINFORM: - log1("Received INFORM"); + log1("received %s", "INFORM"); send_inform(&packet); break; } diff --git a/networking/udhcp/files.c b/networking/udhcp/files.c index 5b90e26d2..7b57c6258 100644 --- a/networking/udhcp/files.c +++ b/networking/udhcp/files.c @@ -226,7 +226,7 @@ void FAST_FUNC read_leases(const char *file) #endif } } - log1("Read %d leases", i); + log1("read %d leases", i); ret: close(fd); } diff --git a/networking/udhcp/leases.c b/networking/udhcp/leases.c index 411b74962..6642e396d 100644 --- a/networking/udhcp/leases.c +++ b/networking/udhcp/leases.c @@ -133,7 +133,7 @@ static int nobody_responds_to_arp(uint32_t nip, const uint8_t *safe_mac, unsigne return r; temp.s_addr = nip; - bb_info_msg("%s belongs to someone, reserving it for %u seconds", + bb_error_msg("%s belongs to someone, reserving it for %u seconds", inet_ntoa(temp), (unsigned)server_config.conflict_time); add_lease(NULL, nip, server_config.conflict_time, NULL, 0); return 0; diff --git a/networking/udhcp/packet.c b/networking/udhcp/packet.c index 148f52551..0a31f2643 100644 --- a/networking/udhcp/packet.c +++ b/networking/udhcp/packet.c @@ -38,8 +38,8 @@ void FAST_FUNC udhcp_dump_packet(struct dhcp_packet *packet) if (dhcp_verbose < 2) return; - bb_info_msg( - //" op %x" + bb_error_msg( + //"op %x" //" htype %x" " hlen %x" //" hops %x" @@ -73,7 +73,7 @@ void FAST_FUNC udhcp_dump_packet(struct dhcp_packet *packet) //, packet->options[] ); *bin2hex(buf, (void *) packet->chaddr, sizeof(packet->chaddr)) = '\0'; - bb_info_msg(" chaddr %s", buf); + bb_error_msg("chaddr %s", buf); } #endif @@ -85,17 +85,17 @@ int FAST_FUNC udhcp_recv_kernel_packet(struct dhcp_packet *packet, int fd) memset(packet, 0, sizeof(*packet)); bytes = safe_read(fd, packet, sizeof(*packet)); if (bytes < 0) { - log1("Packet read error, ignoring"); + log1("packet read error, ignoring"); return bytes; /* returns -1 */ } if (bytes < offsetof(struct dhcp_packet, options) || packet->cookie != htonl(DHCP_MAGIC) ) { - bb_info_msg("Packet with bad magic, ignoring"); + bb_error_msg("packet with bad magic, ignoring"); return -2; } - log1("Received a packet"); + log1("received %s", "a packet"); udhcp_dump_packet(packet); return bytes; diff --git a/networking/udhcp/socket.c b/networking/udhcp/socket.c index a42106960..4fd79f423 100644 --- a/networking/udhcp/socket.c +++ b/networking/udhcp/socket.c @@ -56,7 +56,7 @@ int FAST_FUNC udhcp_read_interface(const char *interface, int *ifindex, uint32_t close(fd); return -1; } - log1("Adapter index %d", ifr->ifr_ifindex); + log1("adapter index %d", ifr->ifr_ifindex); *ifindex = ifr->ifr_ifindex; } @@ -82,7 +82,7 @@ int FAST_FUNC udhcp_listen_socket(/*uint32_t ip,*/ int port, const char *inf) struct sockaddr_in addr; char *colon; - log1("Opening listen socket on *:%d %s", port, inf); + log1("opening listen socket on *:%d %s", port, inf); fd = xsocket(PF_INET, SOCK_DGRAM, IPPROTO_UDP); setsockopt_reuseaddr(fd); diff --git a/networking/udhcp/static_leases.c b/networking/udhcp/static_leases.c index f4a24ab62..b7f9e5c59 100644 --- a/networking/udhcp/static_leases.c +++ b/networking/udhcp/static_leases.c @@ -66,7 +66,7 @@ void FAST_FUNC log_static_leases(struct static_lease **st_lease_pp) cur = *st_lease_pp; while (cur) { - bb_info_msg("static lease: mac:%02x:%02x:%02x:%02x:%02x:%02x nip:%x", + bb_error_msg("static lease: mac:%02x:%02x:%02x:%02x:%02x:%02x nip:%x", cur->mac[0], cur->mac[1], cur->mac[2], cur->mac[3], cur->mac[4], cur->mac[5], cur->nip From 16efe191289ea7507410c343342486b6ea918024 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Wed, 30 Mar 2016 18:44:52 +0200 Subject: [PATCH 183/260] dhcpd: string reuse Signed-off-by: Denys Vlasenko --- networking/udhcp/dhcpd.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/networking/udhcp/dhcpd.c b/networking/udhcp/dhcpd.c index 79677ee93..2671ea3e2 100644 --- a/networking/udhcp/dhcpd.c +++ b/networking/udhcp/dhcpd.c @@ -226,7 +226,7 @@ static NOINLINE void send_NAK(struct dhcp_packet *oldpacket) init_packet(&packet, oldpacket, DHCPNAK); - log1("sending NAK"); + log1("sending %s", "NAK"); send_packet(&packet, /*force_bcast:*/ 1); } From f75a96d74c2e87d0f11995466683b0bf316b9973 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Wed, 30 Mar 2016 18:49:45 +0200 Subject: [PATCH 184/260] udhcp: fix capitalization of two messages Signed-off-by: Denys Vlasenko --- networking/udhcp/common.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/networking/udhcp/common.c b/networking/udhcp/common.c index 1c1863451..0cf4dab63 100644 --- a/networking/udhcp/common.c +++ b/networking/udhcp/common.c @@ -257,7 +257,7 @@ uint8_t* FAST_FUNC udhcp_get_option(struct dhcp_packet *packet, int code) continue; /* complain and return NULL */ if (optionptr[OPT_CODE] == code) { - log_option("Option found", optionptr); + log_option("option found", optionptr); return optionptr + OPT_DATA; } @@ -303,7 +303,7 @@ void FAST_FUNC udhcp_add_binary_option(struct dhcp_packet *packet, uint8_t *addo addopt[OPT_CODE]); return; } - log_option("Adding option", addopt); + log_option("adding option", addopt); memcpy(optionptr + end, addopt, len); optionptr[end + len] = DHCP_END; } From a27dc33f976b15ccfe9180d652ed16579638c48c Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Thu, 31 Mar 2016 00:32:39 +0200 Subject: [PATCH 185/260] make MKPASSWD a separate config option, not an automatic alias to cryptpw Signed-off-by: Denys Vlasenko --- loginutils/cryptpw.c | 32 +++++++++++--------------------- 1 file changed, 11 insertions(+), 21 deletions(-) diff --git a/loginutils/cryptpw.c b/loginutils/cryptpw.c index 55dcc2914..23a1884f4 100644 --- a/loginutils/cryptpw.c +++ b/loginutils/cryptpw.c @@ -14,13 +14,22 @@ //config: default y //config: help //config: Encrypts the given password with the crypt(3) libc function +//config: using the given salt. +//config: +//config:config MKPASSWD +//config: bool "mkpasswd" +//config: default y +//config: help +//config: Encrypts the given password with the crypt(3) libc function //config: using the given salt. Debian has this utility under mkpasswd //config: name. Busybox provides mkpasswd as an alias for cryptpw. //applet:IF_CRYPTPW(APPLET(cryptpw, BB_DIR_USR_BIN, BB_SUID_DROP)) -//applet:IF_CRYPTPW(APPLET_ODDNAME(mkpasswd, cryptpw, BB_DIR_USR_BIN, BB_SUID_DROP, mkpasswd)) +// APPLET_ODDNAME:name main location suid_type help +//applet:IF_MKPASSWD(APPLET_ODDNAME(mkpasswd, cryptpw, BB_DIR_USR_BIN, BB_SUID_DROP, cryptpw)) //kbuild:lib-$(CONFIG_CRYPTPW) += cryptpw.o +//kbuild:lib-$(CONFIG_MKPASSWD) += cryptpw.o //usage:#define cryptpw_trivial_usage //usage: "[OPTIONS] [PASSWORD] [SALT]" @@ -40,25 +49,6 @@ //usage: "\n -S SALT" //usage: ) -/* mkpasswd is an alias to cryptpw */ -//usage:#define mkpasswd_trivial_usage -//usage: "[OPTIONS] [PASSWORD] [SALT]" -/* We do support -s, we just don't mention it */ -//usage:#define mkpasswd_full_usage "\n\n" -//usage: "Crypt PASSWORD using crypt(3)\n" -//usage: IF_LONG_OPTS( -//usage: "\n -P,--password-fd=N Read password from fd N" -/* //usage: "\n -s,--stdin Use stdin; like -P0" */ -//usage: "\n -m,--method=TYPE Encryption method" -//usage: "\n -S,--salt=SALT" -//usage: ) -//usage: IF_NOT_LONG_OPTS( -//usage: "\n -P N Read password from fd N" -/* //usage: "\n -s Use stdin; like -P0" */ -//usage: "\n -m TYPE Encryption method TYPE" -//usage: "\n -S SALT" -//usage: ) - #include "libbb.h" /* Debian has 'mkpasswd' utility, manpage says: @@ -140,7 +130,7 @@ int cryptpw_main(int argc UNUSED_PARAM, char **argv) if (!password) { /* Only mkpasswd, and only from tty, prompts. * Otherwise it is a plain read. */ - password = (isatty(STDIN_FILENO) && applet_name[0] == 'm') + password = (ENABLE_MKPASSWD && isatty(STDIN_FILENO) && applet_name[0] == 'm') ? bb_ask_stdin("Password: ") : xmalloc_fgetline(stdin) ; From 52977a7d600c7db0f7c4935fd501427fd6b580d0 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Thu, 31 Mar 2016 00:42:57 +0200 Subject: [PATCH 186/260] Rename FEATURE_INITRD to LINUXRC and make it separate, not an alias to init Signed-off-by: Denys Vlasenko --- configs/TEST_nommu_defconfig | 2 +- configs/TEST_noprintf_defconfig | 2 +- configs/TEST_rh9_defconfig | 2 +- configs/android2_defconfig | 2 +- configs/android_502_defconfig | 2 +- configs/android_defconfig | 2 +- configs/android_ndk_defconfig | 2 +- configs/cygwin_defconfig | 2 +- configs/freebsd_defconfig | 2 +- init/halt.c | 2 +- init/init.c | 41 +++++++++++++++++---------------- 11 files changed, 31 insertions(+), 30 deletions(-) diff --git a/configs/TEST_nommu_defconfig b/configs/TEST_nommu_defconfig index b45afd956..5f822e598 100644 --- a/configs/TEST_nommu_defconfig +++ b/configs/TEST_nommu_defconfig @@ -390,7 +390,7 @@ CONFIG_FEATURE_INIT_SCTTY=y CONFIG_FEATURE_INIT_SYSLOG=y CONFIG_FEATURE_EXTRA_QUIET=y CONFIG_FEATURE_INIT_COREDUMPS=y -CONFIG_FEATURE_INITRD=y +CONFIG_LINUXRC=y CONFIG_HALT=y # CONFIG_FEATURE_CALL_TELINIT is not set CONFIG_TELINIT_PATH="" diff --git a/configs/TEST_noprintf_defconfig b/configs/TEST_noprintf_defconfig index 809b60cd8..c56781e32 100644 --- a/configs/TEST_noprintf_defconfig +++ b/configs/TEST_noprintf_defconfig @@ -395,7 +395,7 @@ CONFIG_FEATURE_KILL_DELAY=0 # CONFIG_FEATURE_INIT_SYSLOG is not set # CONFIG_FEATURE_EXTRA_QUIET is not set # CONFIG_FEATURE_INIT_COREDUMPS is not set -# CONFIG_FEATURE_INITRD is not set +# CONFIG_LINUXRC is not set # CONFIG_HALT is not set # CONFIG_FEATURE_CALL_TELINIT is not set CONFIG_TELINIT_PATH="" diff --git a/configs/TEST_rh9_defconfig b/configs/TEST_rh9_defconfig index 565b826d0..28daa6273 100644 --- a/configs/TEST_rh9_defconfig +++ b/configs/TEST_rh9_defconfig @@ -407,7 +407,7 @@ CONFIG_FEATURE_INIT_SCTTY=y CONFIG_FEATURE_INIT_SYSLOG=y CONFIG_FEATURE_EXTRA_QUIET=y CONFIG_FEATURE_INIT_COREDUMPS=y -CONFIG_FEATURE_INITRD=y +CONFIG_LINUXRC=y CONFIG_HALT=y # CONFIG_FEATURE_CALL_TELINIT is not set CONFIG_TELINIT_PATH="" diff --git a/configs/android2_defconfig b/configs/android2_defconfig index 1095094fe..fbc0da091 100644 --- a/configs/android2_defconfig +++ b/configs/android2_defconfig @@ -425,7 +425,7 @@ CONFIG_FEATURE_INIT_SCTTY=y CONFIG_FEATURE_INIT_SYSLOG=y CONFIG_FEATURE_EXTRA_QUIET=y CONFIG_FEATURE_INIT_COREDUMPS=y -CONFIG_FEATURE_INITRD=y +CONFIG_LINUXRC=y CONFIG_INIT_TERMINAL_TYPE="linux" CONFIG_MESG=y CONFIG_FEATURE_MESG_ENABLE_ONLY_GROUP=y diff --git a/configs/android_502_defconfig b/configs/android_502_defconfig index c5146c719..7ef1585fb 100644 --- a/configs/android_502_defconfig +++ b/configs/android_502_defconfig @@ -532,7 +532,7 @@ CONFIG_FEATURE_INIT_SCTTY=y CONFIG_FEATURE_INIT_SYSLOG=y CONFIG_FEATURE_EXTRA_QUIET=y CONFIG_FEATURE_INIT_COREDUMPS=y -CONFIG_FEATURE_INITRD=y +CONFIG_LINUXRC=y CONFIG_INIT_TERMINAL_TYPE="linux" CONFIG_FEATURE_INIT_MODIFY_CMDLINE=y CONFIG_MESG=y diff --git a/configs/android_defconfig b/configs/android_defconfig index 082994b6c..4e0224207 100644 --- a/configs/android_defconfig +++ b/configs/android_defconfig @@ -448,7 +448,7 @@ CONFIG_FEATURE_INIT_SCTTY=y CONFIG_FEATURE_INIT_SYSLOG=y CONFIG_FEATURE_EXTRA_QUIET=y CONFIG_FEATURE_INIT_COREDUMPS=y -CONFIG_FEATURE_INITRD=y +CONFIG_LINUXRC=y CONFIG_INIT_TERMINAL_TYPE="linux" CONFIG_MESG=y CONFIG_FEATURE_MESG_ENABLE_ONLY_GROUP=y diff --git a/configs/android_ndk_defconfig b/configs/android_ndk_defconfig index 63fafb468..d657d33e9 100644 --- a/configs/android_ndk_defconfig +++ b/configs/android_ndk_defconfig @@ -458,7 +458,7 @@ CONFIG_FEATURE_INIT_SCTTY=y CONFIG_FEATURE_INIT_SYSLOG=y CONFIG_FEATURE_EXTRA_QUIET=y CONFIG_FEATURE_INIT_COREDUMPS=y -CONFIG_FEATURE_INITRD=y +CONFIG_LINUXRC=y CONFIG_INIT_TERMINAL_TYPE="linux" CONFIG_MESG=y CONFIG_FEATURE_MESG_ENABLE_ONLY_GROUP=y diff --git a/configs/cygwin_defconfig b/configs/cygwin_defconfig index 2c02be743..38d580ad1 100644 --- a/configs/cygwin_defconfig +++ b/configs/cygwin_defconfig @@ -425,7 +425,7 @@ CONFIG_FEATURE_KILL_DELAY=0 # CONFIG_FEATURE_INIT_SYSLOG is not set # CONFIG_FEATURE_EXTRA_QUIET is not set # CONFIG_FEATURE_INIT_COREDUMPS is not set -# CONFIG_FEATURE_INITRD is not set +# CONFIG_LINUXRC is not set CONFIG_INIT_TERMINAL_TYPE="" CONFIG_MESG=y CONFIG_FEATURE_MESG_ENABLE_ONLY_GROUP=y diff --git a/configs/freebsd_defconfig b/configs/freebsd_defconfig index ec3ed03c4..ae62f1389 100644 --- a/configs/freebsd_defconfig +++ b/configs/freebsd_defconfig @@ -422,7 +422,7 @@ CONFIG_FEATURE_KILL_DELAY=0 # CONFIG_FEATURE_INIT_SYSLOG is not set # CONFIG_FEATURE_EXTRA_QUIET is not set # CONFIG_FEATURE_INIT_COREDUMPS is not set -# CONFIG_FEATURE_INITRD is not set +# CONFIG_LINUXRC is not set CONFIG_INIT_TERMINAL_TYPE="" # CONFIG_MESG is not set diff --git a/init/halt.c b/init/halt.c index ad12d9148..572d751b0 100644 --- a/init/halt.c +++ b/init/halt.c @@ -135,7 +135,7 @@ int halt_main(int argc UNUSED_PARAM, char **argv) if (!(flags & 4)) { /* no -f */ //TODO: I tend to think that signalling linuxrc is wrong // pity original author didn't comment on it... - if (ENABLE_FEATURE_INITRD) { + if (ENABLE_LINUXRC) { /* talk to linuxrc */ /* bbox init/linuxrc assumed */ pid_t *pidlist = find_pid_by_name("linuxrc"); diff --git a/init/init.c b/init/init.c index 25bfaec8c..6eb76b80e 100644 --- a/init/init.c +++ b/init/init.c @@ -16,10 +16,21 @@ //config: help //config: init is the first program run when the system boots. //config: +//config:config LINUXRC +//config: bool "Support running init from within an initrd (not initramfs)" +//config: default y +//config: select FEATURE_SYSLOG +//config: help +//config: Legacy support for running init under the old-style initrd. Allows +//config: the name linuxrc to act as init, and it doesn't assume init is PID 1. +//config: +//config: This does not apply to initramfs, which runs /init as PID 1 and +//config: requires no special support. +//config: //config:config FEATURE_USE_INITTAB //config: bool "Support reading an inittab file" //config: default y -//config: depends on INIT +//config: depends on INIT || LINUXRC //config: help //config: Allow init to read an inittab file when the system boot. //config: @@ -46,7 +57,7 @@ //config:config FEATURE_INIT_SCTTY //config: bool "Run commands with leading dash with controlling tty" //config: default y -//config: depends on INIT +//config: depends on INIT || LINUXRC //config: help //config: If this option is enabled, init will try to give a controlling //config: tty to any command which has leading hyphen (often it's "-/bin/sh"). @@ -61,40 +72,29 @@ //config:config FEATURE_INIT_SYSLOG //config: bool "Enable init to write to syslog" //config: default y -//config: depends on INIT +//config: depends on INIT || LINUXRC //config: //config:config FEATURE_EXTRA_QUIET //config: bool "Be _extra_ quiet on boot" //config: default y -//config: depends on INIT +//config: depends on INIT || LINUXRC //config: help //config: Prevent init from logging some messages to the console during boot. //config: //config:config FEATURE_INIT_COREDUMPS //config: bool "Support dumping core for child processes (debugging only)" //config: default y -//config: depends on INIT +//config: depends on INIT || LINUXRC //config: help //config: If this option is enabled and the file /.init_enable_core //config: exists, then init will call setrlimit() to allow unlimited //config: core file sizes. If this option is disabled, processes //config: will not generate any core files. //config: -//config:config FEATURE_INITRD -//config: bool "Support running init from within an initrd (not initramfs)" -//config: default y -//config: depends on INIT -//config: help -//config: Legacy support for running init under the old-style initrd. Allows -//config: the name linuxrc to act as init, and it doesn't assume init is PID 1. -//config: -//config: This does not apply to initramfs, which runs /init as PID 1 and -//config: requires no special support. -//config: //config:config INIT_TERMINAL_TYPE //config: string "Initial terminal type" //config: default "linux" -//config: depends on INIT +//config: depends on INIT || LINUXRC //config: help //config: This is the initial value set by init for the TERM environment //config: variable. This variable is used by programs which make use of @@ -106,7 +106,7 @@ //config:config FEATURE_INIT_MODIFY_CMDLINE //config: bool "Modify the command-line to \"init\"" //config: default y -//config: depends on INIT +//config: depends on INIT || LINUXRC //config: help //config: When launched as PID 1 and after parsing its arguments, init //config: wipes all the arguments but argv[0] and rewrites argv[0] to @@ -119,9 +119,10 @@ //config: retrieved in /proc/1/cmdline on Linux, for example. //applet:IF_INIT(APPLET(init, BB_DIR_SBIN, BB_SUID_DROP)) -//applet:IF_FEATURE_INITRD(APPLET_ODDNAME(linuxrc, init, BB_DIR_ROOT, BB_SUID_DROP, linuxrc)) +//applet:IF_LINUXRC(APPLET_ODDNAME(linuxrc, init, BB_DIR_ROOT, BB_SUID_DROP, linuxrc)) //kbuild:lib-$(CONFIG_INIT) += init.o +//kbuild:lib-$(CONFIG_LINUXRC) += init.o #define DEBUG_SEGV_HANDLER 0 @@ -1057,7 +1058,7 @@ int init_main(int argc UNUSED_PARAM, char **argv) if (!DEBUG_INIT) { /* Expect to be invoked as init with PID=1 or be invoked as linuxrc */ if (getpid() != 1 - && (!ENABLE_FEATURE_INITRD || applet_name[0] != 'l') /* not linuxrc? */ + && (!ENABLE_LINUXRC || applet_name[0] != 'l') /* not linuxrc? */ ) { bb_error_msg_and_die("must be run as PID 1"); } From 29b33b63d49be88200f794d832450a4c71e85a5e Mon Sep 17 00:00:00 2001 From: Bartosz Golaszewski Date: Fri, 1 Apr 2016 19:41:13 +0200 Subject: [PATCH 187/260] unshare: new applet function old new delta unshare_main - 873 +873 .rodata 154444 155131 +687 packed_usage 30329 30520 +191 unshare_longopts - 106 +106 mount_namespaces - 99 +99 mount_or_die - 51 +51 ns_list - 48 +48 wait_for_exitstatus - 41 +41 opt_str - 17 +17 applet_names 2510 2518 +8 applet_main 2912 2920 +8 applet_suid 91 92 +1 applet_install_loc 182 183 +1 ------------------------------------------------------------------------------ (add/remove: 8/0 grow/shrink: 6/0 up/down: 2131/0) Total: 2131 bytes text data bss dec hex filename 826110 4070 9080 839260 cce5c busybox_old 827961 4078 9080 841119 cd59f busybox_unstripped Signed-off-by: Bartosz Golaszewski Signed-off-by: Denys Vlasenko --- util-linux/unshare.c | 380 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 380 insertions(+) create mode 100644 util-linux/unshare.c diff --git a/util-linux/unshare.c b/util-linux/unshare.c new file mode 100644 index 000000000..f1a9cdf19 --- /dev/null +++ b/util-linux/unshare.c @@ -0,0 +1,380 @@ +/* vi: set sw=4 ts=4: */ +/* + * Mini unshare implementation for busybox. + * + * Copyright (C) 2016 by Bartosz Golaszewski + * + * Licensed under GPLv2 or later, see file LICENSE in this source tree. + */ + +//config:config UNSHARE +//config: bool "unshare" +//config: default y +//config: depends on LONG_OPTS && !NOMMU +//config: select PLATFORM_LINUX +//config: help +//config: Run program with some namespaces unshared from parent. + +// depends on LONG_OPTS: it is awkward to exclude code which handles --propagation +// and --setgroups based on LONG_OPTS, so instead applet requires LONG_OPTS. +// depends on !NOMMU: we need fork() + +//applet:IF_UNSHARE(APPLET(unshare, BB_DIR_USR_BIN, BB_SUID_DROP)) + +//kbuild:lib-$(CONFIG_UNSHARE) += unshare.o + +//usage:#define unshare_trivial_usage +//usage: "[OPTIONS] [PROG [ARGS]]" +//usage:#define unshare_full_usage "\n" +//usage: "\n -m, --mount[=FILE] Unshare mount namespace" +//usage: "\n -u, --uts[=FILE] Unshare UTS namespace (hostname etc.)" +//usage: "\n -i, --ipc[=FILE] Unshare System V IPC namespace" +//usage: "\n -n, --net[=FILE] Unshare network namespace" +//usage: "\n -p, --pid[=FILE] Unshare PID namespace" +//usage: "\n -U, --user[=FILE} Unshare user namespace" +//usage: "\n -f, --fork Fork before execing PROG" +//usage: "\n -r, --map-root-user Map current user to root (implies -u)" +//usage: "\n --mount-proc[=DIR] Mount /proc filesystem first (implies -m)" +//usage: "\n --propagation slave|shared|private|unchanged" +//usage: "\n Modify mount propagation in mount namespace" +//usage: "\n --setgroups allow|deny Control the setgroups syscall in user namespaces" + +#include +#include +#include "libbb.h" + +static void mount_or_die(const char *source, const char *target, + const char *fstype, unsigned long mountflags) +{ + if (mount(source, target, fstype, mountflags, NULL)) { + bb_perror_msg_and_die("can't mount %s on %s (flags:0x%lx)", + source, target, mountflags); + /* fstype is always either NULL or "proc". + * "proc" is only used to mount /proc. + * No need to clutter up error message with fstype, + * it is easily deductible. + */ + } +} + +// TODO: move to libbb +static int wait_for_exitstatus(pid_t pid) +{ + int exit_status, n; + + n = safe_waitpid(pid, &exit_status, 0); + if (n < 0) + bb_perror_msg_and_die("waitpid"); + return exit_status; +} + +/* + * Longest possible path to a procfs file used in unshare. Must be able to + * contain the '/proc/' string, the '/ns/user' string which is the longest + * namespace name and a 32-bit integer representing the process ID. + */ +#define PATH_PROC_SETGROUPS "/proc/self/setgroups" +#define PATH_PROC_UIDMAP "/proc/self/uid_map" +#define PATH_PROC_GIDMAP "/proc/self/gid_map" + +struct namespace_descr { + int flag; + const char nsfile4[4]; +}; + +struct namespace_ctx { + char *path; +}; + +enum { + OPT_mount = 1 << 0, + OPT_uts = 1 << 1, + OPT_ipc = 1 << 2, + OPT_network = 1 << 3, + OPT_pid = 1 << 4, + OPT_user = 1 << 5, /* OPT_user, NS_USR_POS, and ns_list[] index must match! */ + OPT_fork = 1 << 6, + OPT_map_root = 1 << 7, + OPT_mount_proc = 1 << 8, + OPT_propagation = 1 << 9, + OPT_setgroups = 1 << 10, +}; +enum { + NS_MNT_POS = 0, + NS_UTS_POS, + NS_IPC_POS, + NS_NET_POS, + NS_PID_POS, + NS_USR_POS, /* OPT_user, NS_USR_POS, and ns_list[] index must match! */ + NS_COUNT, +}; +static const struct namespace_descr ns_list[] = { + { CLONE_NEWNS, "mnt" }, + { CLONE_NEWUTS, "uts" }, + { CLONE_NEWIPC, "ipc" }, + { CLONE_NEWNET, "net" }, + { CLONE_NEWPID, "pid" }, + { CLONE_NEWUSER, "user" }, /* OPT_user, NS_USR_POS, and ns_list[] index must match! */ +}; + +/* + * Upstream unshare doesn't support short options for --mount-proc, + * --propagation, --setgroups. + * Optional arguments (namespace mountpoints) exist only for long opts, + * we are forced to use "fake" letters for them. + * '+': stop at first non-option. + */ +static const char opt_str[] = "+muinpU""fr""\xfd::""\xfe:""\xff:"; +static const char unshare_longopts[] ALIGN1 = + "mount\0" Optional_argument "\xf0" + "uts\0" Optional_argument "\xf1" + "ipc\0" Optional_argument "\xf2" + "network\0" Optional_argument "\xf3" + "pid\0" Optional_argument "\xf4" + "user\0" Optional_argument "\xf5" + "fork\0" No_argument "f" + "map-root-user\0" No_argument "r" + "mount-proc\0" Optional_argument "\xfd" + "propagation\0" Required_argument "\xfe" + "setgroups\0" Required_argument "\xff" +; + +/* Ugly-looking string reuse trick */ +#define PRIVATE_STR "private\0""unchanged\0""shared\0""slave\0" +#define PRIVATE_UNCHANGED_SHARED_SLAVE PRIVATE_STR + +static unsigned long parse_propagation(const char *prop_str) +{ + int i = index_in_strings(PRIVATE_UNCHANGED_SHARED_SLAVE, prop_str); + if (i < 0) + bb_error_msg_and_die("unrecognized: --%s=%s", "propagation", prop_str); + if (i == 0) + return MS_REC | MS_PRIVATE; + if (i == 1) + return 0; + if (i == 2) + return MS_REC | MS_SHARED; + return MS_REC | MS_SLAVE; +} + +static void mount_namespaces(pid_t pid, struct namespace_ctx *ns_ctx_list) +{ + const struct namespace_descr *ns; + struct namespace_ctx *ns_ctx; + int i; + + for (i = 0; i < NS_COUNT; i++) { + char nsf[sizeof("/proc/%u/ns/AAAA") + sizeof(int)*3]; + + ns = &ns_list[i]; + ns_ctx = &ns_ctx_list[i]; + if (!ns_ctx->path) + continue; + sprintf(nsf, "/proc/%u/ns/%.4s", (unsigned)pid, ns->nsfile4); + mount_or_die(nsf, ns_ctx->path, NULL, MS_BIND); + } +} + +int unshare_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; +int unshare_main(int argc UNUSED_PARAM, char **argv) +{ + int i; + unsigned int opts; + int unsflags; + uintptr_t need_mount; + const char *proc_mnt_target; + const char *prop_str; + const char *setgrp_str; + unsigned long prop_flags; + uid_t reuid = geteuid(); + gid_t regid = getegid(); + struct fd_pair fdp; + pid_t child = child; /* for compiler */ + struct namespace_ctx ns_ctx_list[NS_COUNT]; + + memset(ns_ctx_list, 0, sizeof(ns_ctx_list)); + proc_mnt_target = "/proc"; + prop_str = PRIVATE_STR; + setgrp_str = NULL; + + opt_complementary = + "\xf0""m" /* long opts (via their "fake chars") imply short opts */ + ":\xf1""u" + ":\xf2""i" + ":\xf3""n" + ":\xf4""p" + ":\xf5""U" + ":ru" /* --map-root-user or -r implies -u */ + ":\xfd""m" /* --mount-proc implies -m */ + ; + applet_long_options = unshare_longopts; + opts = getopt32(argv, opt_str, + &proc_mnt_target, &prop_str, &setgrp_str, + &ns_ctx_list[NS_MNT_POS].path, + &ns_ctx_list[NS_UTS_POS].path, + &ns_ctx_list[NS_IPC_POS].path, + &ns_ctx_list[NS_NET_POS].path, + &ns_ctx_list[NS_PID_POS].path, + &ns_ctx_list[NS_USR_POS].path + ); + argv += optind; + //bb_error_msg("opts:0x%x", opts); + //bb_error_msg("mount:%s", ns_ctx_list[NS_MNT_POS].path); + //bb_error_msg("proc_mnt_target:%s", proc_mnt_target); + //bb_error_msg("prop_str:%s", prop_str); + //bb_error_msg("setgrp_str:%s", setgrp_str); + //exit(1); + + if (setgrp_str) { + if (strcmp(setgrp_str, "allow") == 0) { + if (opts & OPT_map_root) { + bb_error_msg_and_die( + "--setgroups=allow and --map-root-user " + "are mutually exclusive" + ); + } + } else { + /* It's not "allow", must be "deny" */ + if (strcmp(setgrp_str, "deny") != 0) + bb_error_msg_and_die("unrecognized: --%s=%s", + "setgroups", setgrp_str); + } + } + + unsflags = 0; + need_mount = 0; + for (i = 0; i < NS_COUNT; i++) { + const struct namespace_descr *ns = &ns_list[i]; + struct namespace_ctx *ns_ctx = &ns_ctx_list[i]; + + if (opts & (1 << i)) + unsflags |= ns->flag; + + need_mount |= (uintptr_t)(ns_ctx->path); + } + /* need_mount != 0 if at least one FILE was given */ + + prop_flags = MS_REC | MS_PRIVATE; + /* Silently ignore --propagation if --mount is not requested. */ + if (opts & OPT_mount) + prop_flags = parse_propagation(prop_str); + + /* + * Special case: if we were requested to unshare the mount namespace + * AND to make any namespace persistent (by bind mounting it) we need + * to spawn a child process which will wait for the parent to call + * unshare(), then mount parent's namespaces while still in the + * previous namespace. + */ + fdp.wr = -1; + if (need_mount && (opts & OPT_mount)) { + /* + * Can't use getppid() in child, as we can be unsharing the + * pid namespace. + */ + pid_t ppid = getpid(); + + xpiped_pair(fdp); + + child = xfork(); + if (child == 0) { + /* Child */ + close(fdp.wr); + + /* Wait until parent calls unshare() */ + read(fdp.rd, ns_ctx_list, 1); /* ...using bogus buffer */ + /*close(fdp.rd);*/ + + /* Mount parent's unshared namespaces. */ + mount_namespaces(ppid, ns_ctx_list); + return EXIT_SUCCESS; + } + /* Parent continues */ + } + + if (unshare(unsflags) != 0) + bb_perror_msg_and_die("unshare(0x%x)", unsflags); + + if (fdp.wr >= 0) { + close(fdp.wr); /* Release child */ + /*close(fdp.rd);*/ + } + + if (need_mount) { + /* Wait for the child to finish mounting the namespaces. */ + if (opts & OPT_mount) { + int exit_status = wait_for_exitstatus(child); + if (WIFEXITED(exit_status) && + WEXITSTATUS(exit_status) != EXIT_SUCCESS) + return WEXITSTATUS(exit_status); + } else { + /* + * Regular way - we were requested to mount some other + * namespaces: mount them after the call to unshare(). + */ + mount_namespaces(getpid(), ns_ctx_list); + } + } + + /* + * When we're unsharing the pid namespace, it's not the process that + * calls unshare() that is put into the new namespace, but its first + * child. The user may want to use this option to spawn a new process + * that'll become PID 1 in this new namespace. + */ + if (opts & OPT_fork) { + pid_t pid = xfork(); + if (pid > 0) { + /* Parent */ + int exit_status = wait_for_exitstatus(pid); + if (WIFSIGNALED(exit_status)) + kill_myself_with_sig(WTERMSIG(exit_status)); + return WEXITSTATUS(exit_status); + } + /* Child continues */ + } + + if (opts & OPT_map_root) { + char uidmap_buf[sizeof("%u 0 1") + sizeof(int)*3]; + + /* + * Since Linux 3.19 unprivileged writing of /proc/self/gid_map + * has been disabled unless /proc/self/setgroups is written + * first to permanently disable the ability to call setgroups + * in that user namespace. + */ + xopen_xwrite_close(PATH_PROC_SETGROUPS, "deny"); + sprintf(uidmap_buf, "%u 0 1", (unsigned)reuid); + xopen_xwrite_close(PATH_PROC_UIDMAP, uidmap_buf); + sprintf(uidmap_buf, "%u 0 1", (unsigned)regid); + xopen_xwrite_close(PATH_PROC_GIDMAP, uidmap_buf); + } else + if (setgrp_str) { + /* Write "allow" or "deny" */ + xopen_xwrite_close(PATH_PROC_SETGROUPS, setgrp_str); + } + + if (opts & OPT_mount) { + mount_or_die("none", "/", NULL, prop_flags); + } + + if (opts & OPT_mount_proc) { + /* + * When creating a new pid namespace, we might want the pid + * subdirectories in /proc to remain consistent with the new + * process IDs. Without --mount-proc the pids in /proc would + * still reflect the old pid namespace. This is why we make + * /proc private here and then do a fresh mount. + */ + mount_or_die("none", proc_mnt_target, NULL, MS_PRIVATE | MS_REC); + mount_or_die("proc", proc_mnt_target, "proc", MS_NOSUID | MS_NOEXEC | MS_NODEV); + } + + if (argv[0]) { + BB_EXECVP_or_die(argv); + } + /* unshare from util-linux 2.27.1, despite not documenting it, + * runs a login shell (argv0="-sh") if no PROG is given + */ + run_shell(getenv("SHELL"), /*login:*/ 1, NULL, NULL); +} From c4199f22d0f7793b70db51c01783f0d45afce3d4 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Fri, 1 Apr 2016 22:12:44 +0200 Subject: [PATCH 188/260] libbb: two new functions: wait_for_exitstatus(pid), xfchdir(fd) Bartosz Golaszewski proposed xfchdir() Signed-off-by: Denys Vlasenko --- archival/libarchive/data_extract_to_command.c | 3 +-- include/libbb.h | 2 ++ libbb/xfuncs.c | 12 ++++++++++++ libbb/xfuncs_printf.c | 6 ++++++ runit/chpst.c | 3 +-- util-linux/unshare.c | 11 ----------- 6 files changed, 22 insertions(+), 15 deletions(-) diff --git a/archival/libarchive/data_extract_to_command.c b/archival/libarchive/data_extract_to_command.c index 6f5317a0e..5d8769382 100644 --- a/archival/libarchive/data_extract_to_command.c +++ b/archival/libarchive/data_extract_to_command.c @@ -112,8 +112,7 @@ void FAST_FUNC data_extract_to_command(archive_handle_t *archive_handle) bb_copyfd_exact_size(archive_handle->src_fd, p[1], -file_header->size); close(p[1]); - if (safe_waitpid(pid, &status, 0) == -1) - bb_perror_msg_and_die("waitpid"); + status = wait_for_exitstatus(pid); if (WIFEXITED(status) && WEXITSTATUS(status)) bb_error_msg_and_die("'%s' returned status %d", archive_handle->tar__to_command, WEXITSTATUS(status)); diff --git a/include/libbb.h b/include/libbb.h index 98d788402..5b4280e34 100644 --- a/include/libbb.h +++ b/include/libbb.h @@ -500,6 +500,7 @@ void xsetuid(uid_t uid) FAST_FUNC; void xsetegid(gid_t egid) FAST_FUNC; void xseteuid(uid_t euid) FAST_FUNC; void xchdir(const char *path) FAST_FUNC; +void xfchdir(int fd) FAST_FUNC; void xchroot(const char *path) FAST_FUNC; void xsetenv(const char *key, const char *value) FAST_FUNC; void bb_unsetenv(const char *key) FAST_FUNC; @@ -1021,6 +1022,7 @@ pid_t wait_any_nohang(int *wstat) FAST_FUNC; * if (rc > 0) bb_error_msg("exit code: %d", rc & 0xff); */ int wait4pid(pid_t pid) FAST_FUNC; +int wait_for_exitstatus(pid_t pid) FAST_FUNC; /* Same as wait4pid(spawn(argv)), but with NOFORK/NOEXEC if configured: */ int spawn_and_wait(char **argv) FAST_FUNC; /* Does NOT check that applet is NOFORK, just blindly runs it */ diff --git a/libbb/xfuncs.c b/libbb/xfuncs.c index 206edb4a0..3f9a84ad4 100644 --- a/libbb/xfuncs.c +++ b/libbb/xfuncs.c @@ -315,3 +315,15 @@ int FAST_FUNC wait4pid(pid_t pid) return WTERMSIG(status) + 0x180; return 0; } + +// Useful when we do know that pid is valid, and we just want to wait +// for it to exit. Not existing pid is fatal. waitpid() status is not returned. +int FAST_FUNC wait_for_exitstatus(pid_t pid) +{ + int exit_status, n; + + n = safe_waitpid(pid, &exit_status, 0); + if (n < 0) + bb_perror_msg_and_die("waitpid"); + return exit_status; +} diff --git a/libbb/xfuncs_printf.c b/libbb/xfuncs_printf.c index 73488908d..4aa1b5ce2 100644 --- a/libbb/xfuncs_printf.c +++ b/libbb/xfuncs_printf.c @@ -390,6 +390,12 @@ void FAST_FUNC xchdir(const char *path) bb_perror_msg_and_die("can't change directory to '%s'", path); } +void FAST_FUNC xfchdir(int fd) +{ + if (fchdir(fd)) + bb_perror_msg_and_die("fchdir"); +} + void FAST_FUNC xchroot(const char *path) { if (chroot(path)) diff --git a/runit/chpst.c b/runit/chpst.c index 301cdd08a..7fe5151db 100644 --- a/runit/chpst.c +++ b/runit/chpst.c @@ -255,8 +255,7 @@ static NOINLINE void edir(const char *directory_name) xsetenv(d->d_name, buf); } closedir(dir); - if (fchdir(wdir) == -1) - bb_perror_msg_and_die("fchdir"); + xfchdir(wdir); close(wdir); } diff --git a/util-linux/unshare.c b/util-linux/unshare.c index f1a9cdf19..b8cd4676a 100644 --- a/util-linux/unshare.c +++ b/util-linux/unshare.c @@ -57,17 +57,6 @@ static void mount_or_die(const char *source, const char *target, } } -// TODO: move to libbb -static int wait_for_exitstatus(pid_t pid) -{ - int exit_status, n; - - n = safe_waitpid(pid, &exit_status, 0); - if (n < 0) - bb_perror_msg_and_die("waitpid"); - return exit_status; -} - /* * Longest possible path to a procfs file used in unshare. Must be able to * contain the '/proc/' string, the '/ns/user' string which is the longest From 80c934a2517f7bfc7642da6555d7ca01bc6f2edd Mon Sep 17 00:00:00 2001 From: Bartosz Golaszewski Date: Fri, 1 Apr 2016 22:17:25 +0200 Subject: [PATCH 189/260] nsenter: new applet function old new delta nsenter_main - 663 +663 .rodata 155147 155612 +465 packed_usage 30536 30708 +172 nsenter_longopts - 116 +116 open_by_path_or_target - 58 +58 applet_names 2518 2526 +8 applet_main 2920 2928 +8 ------------------------------------------------------------------------------ (add/remove: 4/0 grow/shrink: 4/0 up/down: 1490/0) Total: 1490 bytes text data bss dec hex filename 827956 4078 9080 841114 cd59a busybox_old 829214 4086 9080 842380 cda8c busybox_unstripped Signed-off-by: Bartosz Golaszewski Signed-off-by: Denys Vlasenko --- util-linux/nsenter.c | 286 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 286 insertions(+) create mode 100644 util-linux/nsenter.c diff --git a/util-linux/nsenter.c b/util-linux/nsenter.c new file mode 100644 index 000000000..9c1dabaa8 --- /dev/null +++ b/util-linux/nsenter.c @@ -0,0 +1,286 @@ +/* vi: set sw=4 ts=4: */ +/* + * Mini nsenter implementation for busybox. + * + * Copyright (C) 2016 by Bartosz Golaszewski + * + * Licensed under GPLv2 or later, see file LICENSE in this source tree. + */ + +//config:config NSENTER +//config: bool "nsenter" +//config: default y +//config: select PLATFORM_LINUX +//config: help +//config: Run program with namespaces of other processes. +//config: +//config:config FEATURE_NSENTER_LONG_OPTS +//config: bool "Enable long options" +//config: default y +//config: depends on NSENTER && LONG_OPTS +//config: help +//config: Support long options for the nsenter applet. This makes +//config: the busybox implementation more compatible with upstream. + +//applet:IF_NSENTER(APPLET(nsenter, BB_DIR_USR_BIN, BB_SUID_DROP)) + +//kbuild:lib-$(CONFIG_NSENTER) += nsenter.o + +//usage:#define nsenter_trivial_usage +//usage: "[OPTIONS] [PROG [ARGS]]" +//usage:#if ENABLE_FEATURE_NSENTER_LONG_OPTS +//usage:#define nsenter_full_usage "\n" +//usage: "\n -t, --target=PID Target process to get namespaces from" +//usage: "\n -m, --mount[=FILE] Enter mount namespace" +//usage: "\n -u, --uts[=FILE] Enter UTS namespace (hostname etc)" +//usage: "\n -i, --ipc[=FILE] Enter System V IPC namespace" +//usage: "\n -n, --net[=FILE] Enter network namespace" +//usage: "\n -p, --pid[=FILE] Enter pid namespace" +//usage: "\n -U, --user[=FILE] Enter user namespace" +//usage: "\n -S, --setuid=UID Set uid in entered namespace" +//usage: "\n -G, --setgid=GID Set gid in entered namespace" +//usage: "\n --preserve-credentials Don't touch uids or gids" +//usage: "\n -r, --root[=DIR] Set root directory" +//usage: "\n -w, --wd[=DIR] Set working directory" +//usage: "\n -F, --no-fork Don't fork before exec'ing PROG" +//usage:#else +//usage:#define nsenter_full_usage "\n" +//usage: "\n -t PID Target process to get namespaces from" +//usage: "\n -m[FILE] Enter mount namespace" +//usage: "\n -u[FILE] Enter UTS namespace (hostname etc)" +//usage: "\n -i[FILE] Enter System V IPC namespace" +//usage: "\n -n[FILE] Enter network namespace" +//usage: "\n -p[FILE] Enter pid namespace" +//usage: "\n -U[FILE] Enter user namespace" +//usage: "\n -S UID Set uid in entered namespace" +//usage: "\n -G GID Set gid in entered namespace" +//usage: "\n -r[DIR] Set root directory" +//usage: "\n -w[DIR] Set working directory" +//usage: "\n -F Don't fork before exec'ing PROG" +//usage:#endif + +#include +#include "libbb.h" + +struct namespace_descr { + int flag; /* value passed to setns() */ + char ns_nsfile8[8]; /* "ns/" + namespace file in process' procfs entry */ +}; + +struct namespace_ctx { + char *path; /* optional path to a custom ns file */ + int fd; /* opened namespace file descriptor */ +}; + +enum { + OPT_user = 1 << 0, + OPT_ipc = 1 << 1, + OPT_uts = 1 << 2, + OPT_network = 1 << 3, + OPT_pid = 1 << 4, + OPT_mount = 1 << 5, + OPT_target = 1 << 6, + OPT_setuid = 1 << 7, + OPT_setgid = 1 << 8, + OPT_root = 1 << 9, + OPT_wd = 1 << 10, + OPT_nofork = 1 << 11, + OPT_prescred = (1 << 12) * ENABLE_FEATURE_NSENTER_LONG_OPTS, +}; +enum { + NS_USR_POS = 0, + NS_IPC_POS, + NS_UTS_POS, + NS_NET_POS, + NS_PID_POS, + NS_MNT_POS, + NS_COUNT, +}; +/* + * The order is significant in nsenter. + * The user namespace comes first, so that it is entered first. + * This gives an unprivileged user the potential to enter other namespaces. + */ +static const struct namespace_descr ns_list[] = { + { CLONE_NEWUSER, "ns/user", }, + { CLONE_NEWIPC, "ns/ipc", }, + { CLONE_NEWUTS, "ns/uts", }, + { CLONE_NEWNET, "ns/net", }, + { CLONE_NEWPID, "ns/pid", }, + { CLONE_NEWNS, "ns/mnt", }, +}; +/* + * Upstream nsenter doesn't support the short option for --preserve-credentials + */ +static const char opt_str[] = "U::i::u::n::p::m::""t+S+G+r::w::F"; + +#if ENABLE_FEATURE_NSENTER_LONG_OPTS +static const char nsenter_longopts[] ALIGN1 = + "user\0" Optional_argument "U" + "ipc\0" Optional_argument "i" + "uts\0" Optional_argument "u" + "network\0" Optional_argument "n" + "pid\0" Optional_argument "p" + "mount\0" Optional_argument "m" + "target\0" Required_argument "t" + "setuid\0" Required_argument "S" + "setgid\0" Required_argument "G" + "root\0" Optional_argument "r" + "wd\0" Optional_argument "w" + "no-fork\0" No_argument "F" + "preserve-credentials\0" No_argument "\xff" + ; +#endif + +/* + * Open a file and return the new descriptor. If a full path is provided in + * fs_path, then the file to which it points is opened. Otherwise (fd_path is + * NULL) the routine builds a path to a procfs file using the following + * template: '/proc//'. + */ +static int open_by_path_or_target(const char *path, + pid_t target_pid, const char *target_file) +{ + char proc_path_buf[sizeof("/proc/%u/1234567890") + sizeof(int)*3]; + + if (!path) { + if (target_pid == 0) { + /* Example: + * "nsenter -p PROG" - neither -pFILE nor -tPID given. + */ + bb_show_usage(); + } + snprintf(proc_path_buf, sizeof(proc_path_buf), + "/proc/%u/%s", (unsigned)target_pid, target_file); + path = proc_path_buf; + } + + return xopen(path, O_RDONLY); +} + +int nsenter_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; +int nsenter_main(int argc UNUSED_PARAM, char **argv) +{ + int i; + unsigned int opts; + const char *root_dir_str = NULL; + const char *wd_str = NULL; + struct namespace_ctx ns_ctx_list[NS_COUNT]; + int setgroups_failed; + int root_fd, wd_fd; + int target_pid = 0; + int uid = 0; + int gid = 0; + + memset(ns_ctx_list, 0, sizeof(ns_ctx_list)); + + IF_FEATURE_NSENTER_LONG_OPTS(applet_long_options = nsenter_longopts); + opts = getopt32(argv, opt_str, + &ns_ctx_list[NS_USR_POS].path, + &ns_ctx_list[NS_IPC_POS].path, + &ns_ctx_list[NS_UTS_POS].path, + &ns_ctx_list[NS_NET_POS].path, + &ns_ctx_list[NS_PID_POS].path, + &ns_ctx_list[NS_MNT_POS].path, + &target_pid, &uid, &gid, + &root_dir_str, &wd_str + ); + argv += optind; + + root_fd = wd_fd = -1; + if (opts & OPT_root) + root_fd = open_by_path_or_target(root_dir_str, + target_pid, "root"); + if (opts & OPT_wd) + wd_fd = open_by_path_or_target(wd_str, target_pid, "cwd"); + + for (i = 0; i < NS_COUNT; i++) { + const struct namespace_descr *ns = &ns_list[i]; + struct namespace_ctx *ns_ctx = &ns_ctx_list[i]; + + ns_ctx->fd = -1; + if (opts & (1 << i)) + ns_ctx->fd = open_by_path_or_target(ns_ctx->path, + target_pid, ns->ns_nsfile8); + } + + /* + * Entering the user namespace without --preserve-credentials implies + * --setuid & --setgid and clearing root's groups. + */ + setgroups_failed = 0; + if ((opts & OPT_user) && !(opts & OPT_prescred)) { + opts |= (OPT_setuid | OPT_setgid); + /* + * We call setgroups() before and after setns() and only + * bail-out if it fails twice. + */ + setgroups_failed = (setgroups(0, NULL) < 0); + } + + for (i = 0; i < NS_COUNT; i++) { + const struct namespace_descr *ns = &ns_list[i]; + struct namespace_ctx *ns_ctx = &ns_ctx_list[i]; + + if (ns_ctx->fd < 0) + continue; + if (setns(ns_ctx->fd, ns->flag)) { + bb_perror_msg_and_die( + "setns(): can't reassociate to namespace '%s'", + ns->ns_nsfile8 + 3 /* skip over "ns/" */ + ); + } + /*close(ns_ctx->fd);*/ + /*ns_ctx->fd = -1;*/ + } + + if (root_fd >= 0) { + if (wd_fd < 0) { + /* + * Save the current working directory if we're not + * changing it. + */ + wd_fd = xopen(".", O_RDONLY); + } + xfchdir(root_fd); + xchroot("."); + /*close(root_fd);*/ + /*root_fd = -1;*/ + } + + if (wd_fd >= 0) { + xfchdir(wd_fd); + /*close(wd_fd);*/ + /*wd_fd = -1;*/ + } + + /* + * Entering the pid namespace implies forking unless it's been + * explicitly requested by the user not to. + */ + if (!(opts & OPT_nofork) && (opts & OPT_pid)) { + pid_t pid = xvfork(); + if (pid > 0) { + /* Parent */ + int exit_status = wait_for_exitstatus(pid); + if (WIFSIGNALED(exit_status)) + kill_myself_with_sig(WTERMSIG(exit_status)); + return WEXITSTATUS(exit_status); + } + /* Child continues */ + } + + if (opts & OPT_setgid) { + if (setgroups(0, NULL) < 0 && setgroups_failed) + bb_perror_msg_and_die("setgroups"); + xsetgid(gid); + } + if (opts & OPT_setuid) + xsetuid(uid); + + if (*argv) { + BB_EXECVP_or_die(argv); + } + + run_shell(getenv("SHELL"), /*login:*/ 1, NULL, NULL); +} From 9f2f96edfa7eddd8a77b76ccae7c2ed88348182e Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Sat, 2 Apr 2016 04:44:39 +0200 Subject: [PATCH 190/260] unshare: remove stale comment Signed-off-by: Denys Vlasenko --- util-linux/unshare.c | 5 ----- 1 file changed, 5 deletions(-) diff --git a/util-linux/unshare.c b/util-linux/unshare.c index b8cd4676a..2a5bea5a6 100644 --- a/util-linux/unshare.c +++ b/util-linux/unshare.c @@ -57,11 +57,6 @@ static void mount_or_die(const char *source, const char *target, } } -/* - * Longest possible path to a procfs file used in unshare. Must be able to - * contain the '/proc/' string, the '/ns/user' string which is the longest - * namespace name and a 32-bit integer representing the process ID. - */ #define PATH_PROC_SETGROUPS "/proc/self/setgroups" #define PATH_PROC_UIDMAP "/proc/self/uid_map" #define PATH_PROC_GIDMAP "/proc/self/gid_map" From dd02a05e082b96d76707964179921107cd43cdd8 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Sat, 2 Apr 2016 15:18:26 +0200 Subject: [PATCH 191/260] build system: finer-grained selection of search speedup table. KNOWN_APPNAME_OFFSETS=8 versus KNOWN_APPNAME_OFFSETS=0: function old new delta find_applet_by_name 55 136 +81 applet_nameofs - 14 +14 run_applet_and_exit 757 758 +1 Signed-off-by: Denys Vlasenko --- applets/applet_tables.c | 65 +++++++++++++++++++++-------------------- 1 file changed, 33 insertions(+), 32 deletions(-) diff --git a/applets/applet_tables.c b/applets/applet_tables.c index 48544f08d..843f2ec08 100644 --- a/applets/applet_tables.c +++ b/applets/applet_tables.c @@ -58,41 +58,32 @@ static int str_isalnum_(const char *s) return 1; } -// Before linear search, narrow it down by looking at N "equidistant" names: -// KNOWN_APPNAME_OFFSETS cycles code_size -// 0 9057 -// 2 4604 +32 -// 4 2407 +75 -// 8 1342 +98 -// 16 908 +130 -// 32 884 +194 -// With 8, applet_nameofs[] table has 7 elements. -#define KNOWN_APPNAME_OFFSETS 8 - int main(int argc, char **argv) { int i, j; - int ofs, offset[KNOWN_APPNAME_OFFSETS], index[KNOWN_APPNAME_OFFSETS]; -// unsigned MAX_APPLET_NAME_LEN = 1; + + // In find_applet_by_name(), before linear search, narrow it down + // by looking at N "equidistant" names. With ~350 applets: + // KNOWN_APPNAME_OFFSETS cycles + // 0 9057 + // 2 4604 + ~100 bytes of code + // 4 2407 + 4 bytes + // 8 1342 + 8 bytes + // 16 908 + 16 bytes + // 32 884 + 32 bytes + // With 8, int16_t applet_nameofs[] table has 7 elements. + int KNOWN_APPNAME_OFFSETS = 8; + // With 128 applets we do two linear searches, with 1..7 strcmp's in the first one + // and 1..16 strcmp's in the second. With 256 apps, second search does 1..32 strcmp's. + if (NUM_APPLETS < 128) + KNOWN_APPNAME_OFFSETS = 4; + if (NUM_APPLETS < 32) + KNOWN_APPNAME_OFFSETS = 0; qsort(applets, NUM_APPLETS, sizeof(applets[0]), cmp_name); - for (i = 0; i < KNOWN_APPNAME_OFFSETS; i++) - index[i] = i * NUM_APPLETS / KNOWN_APPNAME_OFFSETS; - - ofs = 0; - for (i = 0; i < NUM_APPLETS; i++) { - for (j = 0; j < KNOWN_APPNAME_OFFSETS; j++) - if (i == index[j]) - offset[j] = ofs; - ofs += strlen(applets[i].name) + 1; - } - /* If the list of names is too long refuse to proceed */ - if (ofs > 0xffff) - return 1; if (!argv[1]) return 1; - i = open(argv[1], O_WRONLY | O_TRUNC | O_CREAT, 0666); if (i < 0) return 1; @@ -108,16 +99,26 @@ int main(int argc, char **argv) printf("#define SINGLE_APPLET_MAIN %s_main\n", applets[0].main); } - if (KNOWN_APPNAME_OFFSETS > 0 && NUM_APPLETS > 2*KNOWN_APPNAME_OFFSETS) { - printf("#define KNOWN_APPNAME_OFFSETS %u\n\n", KNOWN_APPNAME_OFFSETS); + printf("#define KNOWN_APPNAME_OFFSETS %u\n\n", KNOWN_APPNAME_OFFSETS); + if (KNOWN_APPNAME_OFFSETS > 0) { + int ofs, offset[KNOWN_APPNAME_OFFSETS], index[KNOWN_APPNAME_OFFSETS]; + for (i = 0; i < KNOWN_APPNAME_OFFSETS; i++) + index[i] = i * NUM_APPLETS / KNOWN_APPNAME_OFFSETS; + ofs = 0; + for (i = 0; i < NUM_APPLETS; i++) { + for (j = 0; j < KNOWN_APPNAME_OFFSETS; j++) + if (i == index[j]) + offset[j] = ofs; + ofs += strlen(applets[i].name) + 1; + } + /* If the list of names is too long refuse to proceed */ + if (ofs > 0xffff) + return 1; printf("const uint16_t applet_nameofs[] ALIGN2 = {\n"); for (i = 1; i < KNOWN_APPNAME_OFFSETS; i++) printf("%d,\n", offset[i]); printf("};\n\n"); } - else { - printf("#define KNOWN_APPNAME_OFFSETS 0\n\n"); - } //printf("#ifndef SKIP_definitions\n"); printf("const char applet_names[] ALIGN1 = \"\"\n"); From c87e81f9440278dd46a3eddd1e0f4773afd46a95 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Sat, 2 Apr 2016 17:39:50 +0200 Subject: [PATCH 192/260] sort: help text does not need to say that -mST are supported but ignored Such information is useless for users of "sort --help" Signed-off-by: Denys Vlasenko --- coreutils/sort.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/coreutils/sort.c b/coreutils/sort.c index 07d903388..c8b42c719 100644 --- a/coreutils/sort.c +++ b/coreutils/sort.c @@ -14,7 +14,7 @@ //usage:#define sort_trivial_usage //usage: "[-nru" -//usage: IF_FEATURE_SORT_BIG("gMcszbdfimSTokt] [-o FILE] [-k start[.offset][opts][,end[.offset][opts]] [-t CHAR") +//usage: IF_FEATURE_SORT_BIG("gMcszbdfiokt] [-o FILE] [-k start[.offset][opts][,end[.offset][opts]] [-t CHAR") //usage: "] [FILE]..." //usage:#define sort_full_usage "\n\n" //usage: "Sort lines of text\n" @@ -41,7 +41,10 @@ //usage: "\n -u Suppress duplicate lines" //usage: IF_FEATURE_SORT_BIG( //usage: "\n -z Lines are terminated by NUL, not newline" -//usage: "\n -mST Ignored for GNU compatibility") +////usage: "\n -m Ignored for GNU compatibility" +////usage: "\n -S BUFSZ Ignored for GNU compatibility" +////usage: "\n -T TMPDIR Ignored for GNU compatibility" +//usage: ) //usage: //usage:#define sort_example_usage //usage: "$ echo -e \"e\\nf\\nb\\nd\\nc\\na\" | sort\n" From 8220399173cf8d25e37059cadac96ac30f94e82a Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Sat, 2 Apr 2016 18:06:24 +0200 Subject: [PATCH 193/260] nsenter,unshare: share common code; fix a bug of not closing all fds function old new delta xvfork_parent_waits_and_exits - 64 +64 exec_prog_or_SHELL - 39 +39 unshare_main 873 810 -63 nsenter_main 663 596 -67 ------------------------------------------------------------------------------ (add/remove: 2/0 grow/shrink: 0/2 up/down: 106/-130) Total: -27 bytes Signed-off-by: Denys Vlasenko --- include/libbb.h | 6 ++++-- libbb/executable.c | 11 ++++++++++- libbb/xfuncs_printf.c | 16 ++++++++++++++++ util-linux/nsenter.c | 21 +++++---------------- util-linux/unshare.c | 19 +++---------------- 5 files changed, 38 insertions(+), 35 deletions(-) diff --git a/include/libbb.h b/include/libbb.h index 5b4280e34..64e61cd26 100644 --- a/include/libbb.h +++ b/include/libbb.h @@ -992,9 +992,10 @@ int BB_EXECVP(const char *file, char *const argv[]) FAST_FUNC; #define BB_EXECVP(prog,cmd) execvp(prog,cmd) #define BB_EXECLP(prog,cmd,...) execlp(prog,cmd,__VA_ARGS__) #endif -int BB_EXECVP_or_die(char **argv) NORETURN FAST_FUNC; +void BB_EXECVP_or_die(char **argv) NORETURN FAST_FUNC; +void exec_prog_or_SHELL(char **argv) NORETURN FAST_FUNC; -/* xvfork() can't be a _function_, return after vfork mangles stack +/* xvfork() can't be a _function_, return after vfork in child mangles stack * in the parent. It must be a macro. */ #define xvfork() \ ({ \ @@ -1006,6 +1007,7 @@ int BB_EXECVP_or_die(char **argv) NORETURN FAST_FUNC; #if BB_MMU pid_t xfork(void) FAST_FUNC; #endif +void xvfork_parent_waits_and_exits(void) FAST_FUNC; /* NOMMU friendy fork+exec: */ pid_t spawn(char **argv) FAST_FUNC; diff --git a/libbb/executable.c b/libbb/executable.c index 85ecc3e6c..05e70312f 100644 --- a/libbb/executable.c +++ b/libbb/executable.c @@ -83,10 +83,19 @@ int FAST_FUNC BB_EXECVP(const char *file, char *const argv[]) } #endif -int FAST_FUNC BB_EXECVP_or_die(char **argv) +void FAST_FUNC BB_EXECVP_or_die(char **argv) { BB_EXECVP(argv[0], argv); /* SUSv3-mandated exit codes */ xfunc_error_retval = (errno == ENOENT) ? 127 : 126; bb_perror_msg_and_die("can't execute '%s'", argv[0]); } + +/* Typical idiom for applets which exec *optional* PROG [ARGS] */ +void FAST_FUNC exec_prog_or_SHELL(char **argv) +{ + if (argv[0]) { + BB_EXECVP_or_die(argv); + } + run_shell(getenv("SHELL"), /*login:*/ 1, NULL, NULL); +} diff --git a/libbb/xfuncs_printf.c b/libbb/xfuncs_printf.c index 4aa1b5ce2..e9222f690 100644 --- a/libbb/xfuncs_printf.c +++ b/libbb/xfuncs_printf.c @@ -659,3 +659,19 @@ pid_t FAST_FUNC xfork(void) return pid; } #endif + +void FAST_FUNC xvfork_parent_waits_and_exits(void) +{ + pid_t pid; + + fflush_all(); + pid = xvfork(); + if (pid > 0) { + /* Parent */ + int exit_status = wait_for_exitstatus(pid); + if (WIFSIGNALED(exit_status)) + kill_myself_with_sig(WTERMSIG(exit_status)); + _exit(WEXITSTATUS(exit_status)); + } + /* Child continues */ +} diff --git a/util-linux/nsenter.c b/util-linux/nsenter.c index 9c1dabaa8..0dad595cd 100644 --- a/util-linux/nsenter.c +++ b/util-linux/nsenter.c @@ -230,7 +230,7 @@ int nsenter_main(int argc UNUSED_PARAM, char **argv) ns->ns_nsfile8 + 3 /* skip over "ns/" */ ); } - /*close(ns_ctx->fd);*/ + close(ns_ctx->fd); /* should close fds, to not confuse exec'ed PROG */ /*ns_ctx->fd = -1;*/ } @@ -244,13 +244,13 @@ int nsenter_main(int argc UNUSED_PARAM, char **argv) } xfchdir(root_fd); xchroot("."); - /*close(root_fd);*/ + close(root_fd); /*root_fd = -1;*/ } if (wd_fd >= 0) { xfchdir(wd_fd); - /*close(wd_fd);*/ + close(wd_fd); /*wd_fd = -1;*/ } @@ -259,14 +259,7 @@ int nsenter_main(int argc UNUSED_PARAM, char **argv) * explicitly requested by the user not to. */ if (!(opts & OPT_nofork) && (opts & OPT_pid)) { - pid_t pid = xvfork(); - if (pid > 0) { - /* Parent */ - int exit_status = wait_for_exitstatus(pid); - if (WIFSIGNALED(exit_status)) - kill_myself_with_sig(WTERMSIG(exit_status)); - return WEXITSTATUS(exit_status); - } + xvfork_parent_waits_and_exits(); /* Child continues */ } @@ -278,9 +271,5 @@ int nsenter_main(int argc UNUSED_PARAM, char **argv) if (opts & OPT_setuid) xsetuid(uid); - if (*argv) { - BB_EXECVP_or_die(argv); - } - - run_shell(getenv("SHELL"), /*login:*/ 1, NULL, NULL); + exec_prog_or_SHELL(argv); } diff --git a/util-linux/unshare.c b/util-linux/unshare.c index 2a5bea5a6..95a7cb647 100644 --- a/util-linux/unshare.c +++ b/util-linux/unshare.c @@ -281,7 +281,7 @@ int unshare_main(int argc UNUSED_PARAM, char **argv) if (fdp.wr >= 0) { close(fdp.wr); /* Release child */ - /*close(fdp.rd);*/ + close(fdp.rd); /* should close fd, to not confuse exec'ed PROG */ } if (need_mount) { @@ -307,14 +307,7 @@ int unshare_main(int argc UNUSED_PARAM, char **argv) * that'll become PID 1 in this new namespace. */ if (opts & OPT_fork) { - pid_t pid = xfork(); - if (pid > 0) { - /* Parent */ - int exit_status = wait_for_exitstatus(pid); - if (WIFSIGNALED(exit_status)) - kill_myself_with_sig(WTERMSIG(exit_status)); - return WEXITSTATUS(exit_status); - } + xvfork_parent_waits_and_exits(); /* Child continues */ } @@ -354,11 +347,5 @@ int unshare_main(int argc UNUSED_PARAM, char **argv) mount_or_die("proc", proc_mnt_target, "proc", MS_NOSUID | MS_NOEXEC | MS_NODEV); } - if (argv[0]) { - BB_EXECVP_or_die(argv); - } - /* unshare from util-linux 2.27.1, despite not documenting it, - * runs a login shell (argv0="-sh") if no PROG is given - */ - run_shell(getenv("SHELL"), /*login:*/ 1, NULL, NULL); + exec_prog_or_SHELL(argv); } From b14374a5ba7060d03c9859a5f61afdcdacc3dae6 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Sat, 2 Apr 2016 18:20:26 +0200 Subject: [PATCH 194/260] sort: "-o FILE", not "-o", is the syntax Signed-off-by: Denys Vlasenko --- coreutils/sort.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/coreutils/sort.c b/coreutils/sort.c index c8b42c719..9139d9f47 100644 --- a/coreutils/sort.c +++ b/coreutils/sort.c @@ -19,18 +19,18 @@ //usage:#define sort_full_usage "\n\n" //usage: "Sort lines of text\n" //usage: IF_FEATURE_SORT_BIG( -//usage: "\n -b Ignore leading blanks" +//usage: "\n -o FILE Output to FILE" //usage: "\n -c Check whether input is sorted" -//usage: "\n -d Dictionary order (blank or alphanumeric only)" +//usage: "\n -b Ignore leading blanks" //usage: "\n -f Ignore case" -//usage: "\n -g General numerical sort" //usage: "\n -i Ignore unprintable characters" +//usage: "\n -d Dictionary order (blank or alphanumeric only)" +//usage: "\n -g General numerical sort" //usage: "\n -M Sort month" //usage: ) //-h, --human-numeric-sort: compare human readable numbers (e.g., 2K 1G) //usage: "\n -n Sort numbers" //usage: IF_FEATURE_SORT_BIG( -//usage: "\n -o Output to file" //usage: "\n -t CHAR Field separator" //usage: "\n -k N[,M] Sort by Nth field" //usage: ) From 8b0f459af7aa108089d0f87b0be81ccadb8638cb Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Sat, 2 Apr 2016 19:00:44 +0200 Subject: [PATCH 195/260] nsenter,unshare: work around older header Signed-off-by: Denys Vlasenko --- util-linux/nsenter.c | 16 ++++++++++++++++ util-linux/unshare.c | 29 +++++++++++++++++++++++++++++ 2 files changed, 45 insertions(+) diff --git a/util-linux/nsenter.c b/util-linux/nsenter.c index 0dad595cd..b08b3dae7 100644 --- a/util-linux/nsenter.c +++ b/util-linux/nsenter.c @@ -60,6 +60,22 @@ //usage:#endif #include +#ifndef CLONE_NEWUTS +# define CLONE_NEWUTS 0x04000000 +#endif +#ifndef CLONE_NEWIPC +# define CLONE_NEWIPC 0x08000000 +#endif +#ifndef CLONE_NEWUSER +# define CLONE_NEWUSER 0x10000000 +#endif +#ifndef CLONE_NEWPID +# define CLONE_NEWPID 0x20000000 +#endif +#ifndef CLONE_NEWNET +# define CLONE_NEWNET 0x40000000 +#endif + #include "libbb.h" struct namespace_descr { diff --git a/util-linux/unshare.c b/util-linux/unshare.c index 95a7cb647..d05cfdb6c 100644 --- a/util-linux/unshare.c +++ b/util-linux/unshare.c @@ -40,7 +40,36 @@ //usage: "\n --setgroups allow|deny Control the setgroups syscall in user namespaces" #include +#ifndef CLONE_NEWUTS +# define CLONE_NEWUTS 0x04000000 +#endif +#ifndef CLONE_NEWIPC +# define CLONE_NEWIPC 0x08000000 +#endif +#ifndef CLONE_NEWUSER +# define CLONE_NEWUSER 0x10000000 +#endif +#ifndef CLONE_NEWPID +# define CLONE_NEWPID 0x20000000 +#endif +#ifndef CLONE_NEWNET +# define CLONE_NEWNET 0x40000000 +#endif + #include +#ifndef MS_REC +# define MS_REC (1 << 14) +#endif +#ifndef MS_PRIVATE +# define MS_PRIVATE (1 << 18) +#endif +#ifndef MS_SLAVE +# define MS_SLAVE (1 << 19) +#endif +#ifndef MS_SHARED +# define MS_SHARED (1 << 20) +#endif + #include "libbb.h" static void mount_or_die(const char *source, const char *target, From a93e4fd376d990ead254657228e75715b74ca0ac Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Sat, 2 Apr 2016 22:54:23 +0200 Subject: [PATCH 196/260] find_applet_by_name: add an example of faster linear search code Signed-off-by: Denys Vlasenko --- libbb/appletlib.c | 80 +++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 77 insertions(+), 3 deletions(-) diff --git a/libbb/appletlib.c b/libbb/appletlib.c index aeaf238f1..18583f91a 100644 --- a/libbb/appletlib.c +++ b/libbb/appletlib.c @@ -141,10 +141,28 @@ void FAST_FUNC bb_show_usage(void) int FAST_FUNC find_applet_by_name(const char *name) { - unsigned i, max; - int j; + unsigned i, j, max; const char *p; +/* The commented-out word-at-a-time code is ~40% faster, but +160 bytes. + * "Faster" here saves ~0.5 microsecond of real time - not worth it. + */ +#if 0 /*BB_UNALIGNED_MEMACCESS_OK && BB_LITTLE_ENDIAN*/ + uint32_t n32; + + /* Handle all names < 2 chars long early */ + if (name[0] == '\0') + return -1; /* "" is not a valid applet name */ + if (name[1] == '\0') { + if (!ENABLE_TEST) + return -1; /* 1-char name is not valid */ + if (name[0] != ']') + return -1; /* 1-char name which isn't "[" is not valid */ + /* applet "[" is always applet #0: */ + return 0; + } +#endif + p = applet_names; i = 0; #if KNOWN_APPNAME_OFFSETS <= 0 @@ -166,7 +184,62 @@ int FAST_FUNC find_applet_by_name(const char *name) //bb_error_msg("name:'%s' starting from:'%s' i:%u max:%u", name, p, i, max); #endif - /* Open-coding without strcmp/strlen calls for speed */ + /* Open-coded linear seatch without strcmp/strlen calls for speed */ + +#if 0 /*BB_UNALIGNED_MEMACCESS_OK && BB_LITTLE_ENDIAN*/ + /* skip "[\0" name, it's surely not it */ + if (ENABLE_TEST && LONE_CHAR(p, '[')) + i++, p += 2; + /* All remaining applet names in p[] are at least 2 chars long */ + /* name[] is also at least 2 chars long */ + + n32 = (name[0] << 0) | (name[1] << 8) | (name[2] << 16); + while (i < max) { + uint32_t p32; + char ch; + + /* Quickly check match of the first 3 bytes */ + move_from_unaligned32(p32, p); + p += 3; + if ((p32 & 0x00ffffff) != n32) { + /* Most likely case: 3 first bytes do not match */ + i++; + if ((p32 & 0x00ff0000) == '\0') + continue; // p[2] was NUL + p++; + if ((p32 & 0xff000000) == '\0') + continue; // p[3] was NUL + /* p[0..3] aren't matching and none is NUL, check the rest */ + while (*p++ != '\0') + continue; + continue; + } + + /* Unlikely branch: first 3 bytes ([0..2]) match */ + if ((p32 & 0x00ff0000) == '\0') { + /* name is 2-byte long, it is full match */ + //bb_error_msg("found:'%s' i:%u", name, i); + return i; + } + /* Check remaining bytes [3..NUL] */ + ch = (p32 >> 24); + j = 3; + while (ch == name[j]) { + if (ch == '\0') { + //bb_error_msg("found:'%s' i:%u", name, i); + return i; + } + ch = *++p; + j++; + } + /* Not a match. Skip it, including NUL */ + while (ch != '\0') + ch = *++p; + p++; + i++; + } + return -1; +#else while (i < max) { char ch; j = 0; @@ -189,6 +262,7 @@ int FAST_FUNC find_applet_by_name(const char *name) i++; } return -1; +#endif } From 1cf68e303328671f74dfd9f7d24e6c9f91d18969 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Sat, 2 Apr 2016 22:57:17 +0200 Subject: [PATCH 197/260] typo fix Signed-off-by: Denys Vlasenko --- libbb/appletlib.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libbb/appletlib.c b/libbb/appletlib.c index 18583f91a..4b5b09f45 100644 --- a/libbb/appletlib.c +++ b/libbb/appletlib.c @@ -184,7 +184,7 @@ int FAST_FUNC find_applet_by_name(const char *name) //bb_error_msg("name:'%s' starting from:'%s' i:%u max:%u", name, p, i, max); #endif - /* Open-coded linear seatch without strcmp/strlen calls for speed */ + /* Open-coded linear search without strcmp/strlen calls for speed */ #if 0 /*BB_UNALIGNED_MEMACCESS_OK && BB_LITTLE_ENDIAN*/ /* skip "[\0" name, it's surely not it */ From 056e1f558cc8bc22f221b49bf4571aed59cdae09 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Sun, 3 Apr 2016 15:38:53 +0200 Subject: [PATCH 198/260] trylink: on failure, print a hint about CONFIG_EXTRA_LDLIBS Signed-off-by: Denys Vlasenko --- scripts/trylink | 2 ++ 1 file changed, 2 insertions(+) diff --git a/scripts/trylink b/scripts/trylink index 3c431edc3..15435f009 100755 --- a/scripts/trylink +++ b/scripts/trylink @@ -140,6 +140,8 @@ try $CC $CFLAGS $LDFLAGS \ || { echo "Failed: $l_list" cat $EXE.out + echo 'Note: if build needs additional libraries, put them in CONFIG_EXTRA_LDLIBS.' + echo 'Example: CONFIG_EXTRA_LDLIBS="pthread dl tirpc audit pam"' exit 1 } From bc14f4d13d3cf1d43ae809d641e29174662cd1e4 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Sun, 3 Apr 2016 16:06:42 +0200 Subject: [PATCH 199/260] main(): add a TODO about finding a use for _end[] area Signed-off-by: Denys Vlasenko --- libbb/appletlib.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/libbb/appletlib.c b/libbb/appletlib.c index 4b5b09f45..d798a2eac 100644 --- a/libbb/appletlib.c +++ b/libbb/appletlib.c @@ -902,6 +902,19 @@ int lbb_main(char **argv) int main(int argc UNUSED_PARAM, char **argv) #endif { +#if 0 + /* TODO: find a use for a block of memory between end of .bss + * and end of page. For example, I'm getting "_end:0x812e698 2408 bytes" + * - more than 2k of wasted memory (in this particular build) + * *per each running process*! + * (If your linker does not generate "_end" name, weak attribute + * makes &_end == NULL, end_len == 0 here.) + */ + extern char _end[] __attribute__((weak)); + unsigned end_len = (-(int)_end) & 0xfff; + printf("_end:%p %u bytes\n", &_end, end_len); +#endif + /* Tweak malloc for reduced memory consumption */ #ifdef M_TRIM_THRESHOLD /* M_TRIM_THRESHOLD is the maximum amount of freed top-most memory From 46b494635e6ef54e282749d2c65dd1922b167931 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Sun, 3 Apr 2016 16:55:03 +0200 Subject: [PATCH 200/260] libbb: speed up error_msg functions function old new delta bb_verror_msg 386 466 +80 Signed-off-by: Denys Vlasenko --- libbb/verror_msg.c | 29 +++++++++++++++++++++++++---- 1 file changed, 25 insertions(+), 4 deletions(-) diff --git a/libbb/verror_msg.c b/libbb/verror_msg.c index 0ef2a311f..22c30357b 100644 --- a/libbb/verror_msg.c +++ b/libbb/verror_msg.c @@ -20,6 +20,7 @@ const char *msg_eol = "\n"; void FAST_FUNC bb_verror_msg(const char *s, va_list p, const char* strerr) { char *msg, *msg1; + char stack_msg[80]; int applet_len, strerr_len, msgeol_len, used; if (!logmode) @@ -28,6 +29,27 @@ void FAST_FUNC bb_verror_msg(const char *s, va_list p, const char* strerr) if (!s) /* nomsg[_and_die] uses NULL fmt */ s = ""; /* some libc don't like printf(NULL) */ + applet_len = strlen(applet_name) + 2; /* "applet: " */ + strerr_len = strerr ? strlen(strerr) : 0; + msgeol_len = strlen(msg_eol); + + /* This costs ~90 bytes of code, but avoids costly + * malloc()[in vasprintf]+realloc()+memmove()+free() in 99% of cases. + * ~40% speedup. + */ + if ((int)sizeof(stack_msg) - applet_len > 0) { + va_list p2; + + /* It is not portable to use va_list twice, need to va_copy it */ + va_copy(p2, p); + used = vsnprintf(stack_msg + applet_len, (int)sizeof(stack_msg) - applet_len, s, p2); + va_end(p2); + msg = stack_msg; + used += applet_len; + if (used < (int)sizeof(stack_msg) - 3 - msgeol_len - strerr_len) + goto add_pfx_and_sfx; + } + used = vasprintf(&msg, s, p); if (used < 0) return; @@ -37,9 +59,6 @@ void FAST_FUNC bb_verror_msg(const char *s, va_list p, const char* strerr) * This is needed for e.g. httpd logging, when multiple * children can produce log messages simultaneously. */ - applet_len = strlen(applet_name) + 2; /* "applet: " */ - strerr_len = strerr ? strlen(strerr) : 0; - msgeol_len = strlen(msg_eol); /* can't use xrealloc: it calls error_msg on failure, * that may result in a recursion */ /* +3 is for ": " before strerr and for terminating NUL */ @@ -52,6 +71,7 @@ void FAST_FUNC bb_verror_msg(const char *s, va_list p, const char* strerr) /* TODO: maybe use writev instead of memmoving? Need full_writev? */ memmove(msg + applet_len, msg, used); used += applet_len; + add_pfx_and_sfx: strcpy(msg, applet_name); msg[applet_len - 2] = ':'; msg[applet_len - 1] = ' '; @@ -76,7 +96,8 @@ void FAST_FUNC bb_verror_msg(const char *s, va_list p, const char* strerr) syslog(syslog_level, "%s", msg + applet_len); } #endif - free(msg); + if (msg != stack_msg) + free(msg); } #ifdef VERSION_WITH_WRITEV From cb9264099822505dc2930cfea0b1f9027a02dc06 Mon Sep 17 00:00:00 2001 From: Sven Eisenberg Date: Sun, 3 Apr 2016 20:12:03 +0200 Subject: [PATCH 201/260] ubirename: new applet function old new delta ubirename_main - 394 +394 packed_usage 30611 30674 +63 applet_names 2530 2540 +10 Signed-off-by: Sven Eisenberg Signed-off-by: Denys Vlasenko --- miscutils/ubirename.c | 111 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 111 insertions(+) create mode 100644 miscutils/ubirename.c diff --git a/miscutils/ubirename.c b/miscutils/ubirename.c new file mode 100644 index 000000000..455a49485 --- /dev/null +++ b/miscutils/ubirename.c @@ -0,0 +1,111 @@ +/* ubirename - port of the ubirename from the mtd-utils package + * + * A utility to rename one UBI volume. + * + * 2016-03-01 Sven Eisenberg + * + * Licensed under GPLv2, see file LICENSE in this source tree. + */ +//config:config UBIRENAME +//config: bool "ubirename" +//config: default y +//config: select PLATFORM_LINUX +//config: help +//config: Utility to rename UBI volumes + +//applet:IF_UBIRENAME(APPLET(ubirename, BB_DIR_USR_SBIN, BB_SUID_DROP)) + +//kbuild:lib-$(CONFIG_UBIRENAME) += ubirename.o + +//usage:#define ubirename_trivial_usage +//usage: "UBI_DEVICE OLD_VOLNAME NEW_VOLNAME [OLD2 NEW2]..." +//usage:#define ubirename_full_usage "\n\n" +//usage: "Rename UBI volumes on UBI_DEVICE" + +#include "libbb.h" +#include + +#ifndef __packed +# define __packed __attribute__((packed)) +#endif + +// from ubi-media.h +#define UBI_VOL_NAME_MAX 127 +#define UBI_MAX_VOLUMES 128 +// end ubi-media.h + +#define UBI_MAX_VOLUME_NAME UBI_VOL_NAME_MAX + +// from ubi-user.h +/* ioctl commands of UBI character devices */ +#define UBI_IOC_MAGIC 'o' + +/* Re-name volumes */ +#define UBI_IOCRNVOL _IOW(UBI_IOC_MAGIC, 3, struct ubi_rnvol_req) + +/* Maximum amount of UBI volumes that can be re-named at one go */ +#define UBI_MAX_RNVOL 32 + +struct ubi_rnvol_req { + int32_t count; + int8_t padding1[12]; + struct { + int32_t vol_id; + int16_t name_len; + int8_t padding2[2]; + char name[UBI_MAX_VOLUME_NAME + 1]; + } ents[UBI_MAX_RNVOL]; +} __packed; +// end ubi-user.h + +int ubirename_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; +int ubirename_main(int argc, char **argv) +{ + struct ubi_rnvol_req *rnvol; + const char *ubi_devname; + unsigned ubi_devnum; + unsigned i, n; + + /* argc can be 4, 6, 8, ... */ + if ((argc & 1) || (argc >>= 1) < 2) + bb_show_usage(); + + rnvol = xzalloc(sizeof(*rnvol)); + rnvol->count = --argc; + if (argc > ARRAY_SIZE(rnvol->ents)) + bb_error_msg_and_die("too many renames requested"); + + ubi_devname = argv[1]; + if (sscanf(ubi_devname, "/dev/ubi%u", &ubi_devnum) != 1) + bb_error_msg_and_die("not a ubi device: '%s'", ubi_devname); + + n = 0; + argv += 2; + while (argv[0]) { + for (i = 0; i < UBI_MAX_VOLUMES; i++) { + char buf[UBI_VOL_NAME_MAX + 1]; + char fname[sizeof("/sys/class/ubi/ubi%u_%u/name") + 2 * sizeof(int)*3]; + + sprintf(fname, "/sys/class/ubi/ubi%u_%u/name", ubi_devnum, i); + if (open_read_close(fname, buf, sizeof(buf)) <= 0) + continue; + + strchrnul(buf, '\n')[0] = '\0'; + if (strcmp(buf, argv[0]) == 0) + goto found; + } + bb_error_msg_and_die("no volume '%s' found", argv[0]); + found: + rnvol->ents[n].vol_id = i; + rnvol->ents[n].name_len = strlen(argv[1]); + if (rnvol->ents[n].name_len >= sizeof(rnvol->ents[n].name)) + bb_error_msg_and_die("new name '%s' is too long", argv[1]); + strcpy(rnvol->ents[n].name, argv[1]); + n++; + argv += 2; + } + + xioctl(xopen(ubi_devname, O_RDONLY), UBI_IOCRNVOL, rnvol); + + return 0; +} From b068cf2a7e036da8d0b3533b41886c5605c8139d Mon Sep 17 00:00:00 2001 From: Sven Eisenberg Date: Sun, 3 Apr 2016 21:53:12 +0200 Subject: [PATCH 202/260] ubirmvol: Implement -N switch for ubirmvol function old new delta get_volid_by_name - 125 +125 ubi_devnum_from_devname - 43 +43 ubi_tools_main 1215 1220 +5 packed_usage 30674 30655 -19 ubirename_main 394 221 -173 ------------------------------------------------------------------------------ (add/remove: 3/0 grow/shrink: 1/2 up/down: 173/-192) Total: -19 bytes Signed-off-by: Denys Vlasenko --- include/libbb.h | 3 +++ libbb/ubi.c | 43 +++++++++++++++++++++++++++++++++++++++++++ miscutils/ubi_tools.c | 29 +++++++++++++++++++---------- miscutils/ubirename.c | 25 ++++--------------------- 4 files changed, 69 insertions(+), 31 deletions(-) create mode 100644 libbb/ubi.c diff --git a/include/libbb.h b/include/libbb.h index 64e61cd26..35c28df51 100644 --- a/include/libbb.h +++ b/include/libbb.h @@ -1770,6 +1770,9 @@ void bb_progress_update(bb_progress_t *p, uoff_t transferred, uoff_t totalsize) FAST_FUNC; +unsigned ubi_devnum_from_devname(const char *str) FAST_FUNC; +int get_volid_by_name(unsigned ubi_devnum, const char *vol_name) FAST_FUNC; + extern const char *applet_name; diff --git a/libbb/ubi.c b/libbb/ubi.c new file mode 100644 index 000000000..7d3b2952d --- /dev/null +++ b/libbb/ubi.c @@ -0,0 +1,43 @@ +/* vi: set sw=4 ts=4: */ +/* + * Utility routines. + * + * Copyright (C) 2016 Denys Vlasenko + * + * Licensed under GPLv2, see file LICENSE in this source tree. + */ +//kbuild:lib-y += ubi.o + +#include "libbb.h" + +// from ubi-media.h +#define UBI_MAX_VOLUME_NAME 127 +#define UBI_MAX_VOLUMES 128 + +unsigned FAST_FUNC ubi_devnum_from_devname(const char *str) +{ + unsigned ubi_devnum; + + if (sscanf(str, "/dev/ubi%u", &ubi_devnum) != 1) + bb_error_msg_and_die("not an UBI device: '%s'", str); + return ubi_devnum; +} + +int FAST_FUNC get_volid_by_name(unsigned ubi_devnum, const char *vol_name) +{ + unsigned i; + + for (i = 0; i < UBI_MAX_VOLUMES; i++) { + char buf[UBI_MAX_VOLUME_NAME + 1]; + char fname[sizeof("/sys/class/ubi/ubi%u_%u/name") + 2 * sizeof(int)*3]; + + sprintf(fname, "/sys/class/ubi/ubi%u_%u/name", ubi_devnum, i); + if (open_read_close(fname, buf, sizeof(buf)) <= 0) + continue; + + strchrnul(buf, '\n')[0] = '\0'; + if (strcmp(vol_name, buf) == 0) + return i; + } + bb_error_msg_and_die("volume '%s' not found", vol_name); +} diff --git a/miscutils/ubi_tools.c b/miscutils/ubi_tools.c index dd1bda300..ac0c56d6b 100644 --- a/miscutils/ubi_tools.c +++ b/miscutils/ubi_tools.c @@ -195,7 +195,7 @@ int ubi_tools_main(int argc UNUSED_PARAM, char **argv) } else //usage:#define ubimkvol_trivial_usage -//usage: "UBI_DEVICE -N NAME [-s SIZE | -m]" +//usage: "-N NAME [-s SIZE | -m] UBI_DEVICE" //usage:#define ubimkvol_full_usage "\n\n" //usage: "Create UBI volume\n" //usage: "\n -a ALIGNMENT Volume alignment (default 1)" @@ -212,9 +212,7 @@ int ubi_tools_main(int argc UNUSED_PARAM, char **argv) unsigned num; char *p; - if (sscanf(ubi_ctrl, "/dev/ubi%u", &num) != 1) - bb_error_msg_and_die("wrong format of UBI device name"); - + num = ubi_devnum_from_devname(ubi_ctrl); p = path_sys_class_ubi_ubi + sprintf(path_sys_class_ubi_ubi, "%u/", num); strcpy(p, "avail_eraseblocks"); @@ -248,20 +246,31 @@ int ubi_tools_main(int argc UNUSED_PARAM, char **argv) } else //usage:#define ubirmvol_trivial_usage -//usage: "UBI_DEVICE -n VOLID" +//usage: "-n VOLID / -N VOLNAME UBI_DEVICE" //usage:#define ubirmvol_full_usage "\n\n" //usage: "Remove UBI volume\n" //usage: "\n -n VOLID Volume ID" +//usage: "\n -N VOLNAME Volume name" if (do_rmvol) { - if (!(opts & OPTION_n)) + if (!(opts & (OPTION_n|OPTION_N))) bb_error_msg_and_die("volume id not specified"); - /* FIXME? kernel expects int32_t* here: */ - xioctl(fd, UBI_IOCRMVOL, &vol_id); + if (opts & OPTION_N) { + unsigned num = ubi_devnum_from_devname(ubi_ctrl); + vol_id = get_volid_by_name(num, vol_name); + } + + if (sizeof(vol_id) != 4) { + /* kernel expects int32_t* in this ioctl */ + int32_t t = vol_id; + xioctl(fd, UBI_IOCRMVOL, &t); + } else { + xioctl(fd, UBI_IOCRMVOL, &vol_id); + } } else //usage:#define ubirsvol_trivial_usage -//usage: "UBI_DEVICE -n VOLID -s SIZE" +//usage: "-n VOLID -s SIZE UBI_DEVICE" //usage:#define ubirsvol_full_usage "\n\n" //usage: "Resize UBI volume\n" //usage: "\n -n VOLID Volume ID" @@ -279,7 +288,7 @@ int ubi_tools_main(int argc UNUSED_PARAM, char **argv) } else //usage:#define ubiupdatevol_trivial_usage -//usage: "UBI_DEVICE [-t | [-s SIZE] IMG_FILE]" +//usage: "[-t | [-s SIZE] IMG_FILE] UBI_DEVICE" //usage:#define ubiupdatevol_full_usage "\n\n" //usage: "Update UBI volume\n" //usage: "\n -t Truncate to zero size" diff --git a/miscutils/ubirename.c b/miscutils/ubirename.c index 455a49485..d6ccfcb10 100644 --- a/miscutils/ubirename.c +++ b/miscutils/ubirename.c @@ -30,12 +30,10 @@ #endif // from ubi-media.h -#define UBI_VOL_NAME_MAX 127 +#define UBI_MAX_VOLUME_NAME 127 #define UBI_MAX_VOLUMES 128 // end ubi-media.h -#define UBI_MAX_VOLUME_NAME UBI_VOL_NAME_MAX - // from ubi-user.h /* ioctl commands of UBI character devices */ #define UBI_IOC_MAGIC 'o' @@ -64,7 +62,7 @@ int ubirename_main(int argc, char **argv) struct ubi_rnvol_req *rnvol; const char *ubi_devname; unsigned ubi_devnum; - unsigned i, n; + unsigned n; /* argc can be 4, 6, 8, ... */ if ((argc & 1) || (argc >>= 1) < 2) @@ -76,27 +74,12 @@ int ubirename_main(int argc, char **argv) bb_error_msg_and_die("too many renames requested"); ubi_devname = argv[1]; - if (sscanf(ubi_devname, "/dev/ubi%u", &ubi_devnum) != 1) - bb_error_msg_and_die("not a ubi device: '%s'", ubi_devname); + ubi_devnum = ubi_devnum_from_devname(ubi_devname); n = 0; argv += 2; while (argv[0]) { - for (i = 0; i < UBI_MAX_VOLUMES; i++) { - char buf[UBI_VOL_NAME_MAX + 1]; - char fname[sizeof("/sys/class/ubi/ubi%u_%u/name") + 2 * sizeof(int)*3]; - - sprintf(fname, "/sys/class/ubi/ubi%u_%u/name", ubi_devnum, i); - if (open_read_close(fname, buf, sizeof(buf)) <= 0) - continue; - - strchrnul(buf, '\n')[0] = '\0'; - if (strcmp(buf, argv[0]) == 0) - goto found; - } - bb_error_msg_and_die("no volume '%s' found", argv[0]); - found: - rnvol->ents[n].vol_id = i; + rnvol->ents[n].vol_id = get_volid_by_name(ubi_devnum, argv[0]); rnvol->ents[n].name_len = strlen(argv[1]); if (rnvol->ents[n].name_len >= sizeof(rnvol->ents[n].name)) bb_error_msg_and_die("new name '%s' is too long", argv[1]); From 6aab9928dec29855bcee21bce163e5fdf7144350 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Sun, 3 Apr 2016 22:24:51 +0200 Subject: [PATCH 203/260] whitespace and namespace cleanups Signed-off-by: Denys Vlasenko --- include/libbb.h | 2 +- libbb/ubi.c | 8 ++++---- miscutils/ubi_tools.c | 2 +- miscutils/ubirename.c | 4 ++-- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/include/libbb.h b/include/libbb.h index 35c28df51..111dd66e0 100644 --- a/include/libbb.h +++ b/include/libbb.h @@ -1771,7 +1771,7 @@ void bb_progress_update(bb_progress_t *p, uoff_t totalsize) FAST_FUNC; unsigned ubi_devnum_from_devname(const char *str) FAST_FUNC; -int get_volid_by_name(unsigned ubi_devnum, const char *vol_name) FAST_FUNC; +int ubi_get_volid_by_name(unsigned ubi_devnum, const char *vol_name) FAST_FUNC; extern const char *applet_name; diff --git a/libbb/ubi.c b/libbb/ubi.c index 7d3b2952d..34595d797 100644 --- a/libbb/ubi.c +++ b/libbb/ubi.c @@ -16,14 +16,14 @@ unsigned FAST_FUNC ubi_devnum_from_devname(const char *str) { - unsigned ubi_devnum; + unsigned ubi_devnum; - if (sscanf(str, "/dev/ubi%u", &ubi_devnum) != 1) - bb_error_msg_and_die("not an UBI device: '%s'", str); + if (sscanf(str, "/dev/ubi%u", &ubi_devnum) != 1) + bb_error_msg_and_die("not an UBI device: '%s'", str); return ubi_devnum; } -int FAST_FUNC get_volid_by_name(unsigned ubi_devnum, const char *vol_name) +int FAST_FUNC ubi_get_volid_by_name(unsigned ubi_devnum, const char *vol_name) { unsigned i; diff --git a/miscutils/ubi_tools.c b/miscutils/ubi_tools.c index ac0c56d6b..4364bc807 100644 --- a/miscutils/ubi_tools.c +++ b/miscutils/ubi_tools.c @@ -257,7 +257,7 @@ int ubi_tools_main(int argc UNUSED_PARAM, char **argv) if (opts & OPTION_N) { unsigned num = ubi_devnum_from_devname(ubi_ctrl); - vol_id = get_volid_by_name(num, vol_name); + vol_id = ubi_get_volid_by_name(num, vol_name); } if (sizeof(vol_id) != 4) { diff --git a/miscutils/ubirename.c b/miscutils/ubirename.c index d6ccfcb10..8b1c3785a 100644 --- a/miscutils/ubirename.c +++ b/miscutils/ubirename.c @@ -31,7 +31,7 @@ // from ubi-media.h #define UBI_MAX_VOLUME_NAME 127 -#define UBI_MAX_VOLUMES 128 +#define UBI_MAX_VOLUMES 128 // end ubi-media.h // from ubi-user.h @@ -79,7 +79,7 @@ int ubirename_main(int argc, char **argv) n = 0; argv += 2; while (argv[0]) { - rnvol->ents[n].vol_id = get_volid_by_name(ubi_devnum, argv[0]); + rnvol->ents[n].vol_id = ubi_get_volid_by_name(ubi_devnum, argv[0]); rnvol->ents[n].name_len = strlen(argv[1]); if (rnvol->ents[n].name_len >= sizeof(rnvol->ents[n].name)) bb_error_msg_and_die("new name '%s' is too long", argv[1]); From b22061718db0111f9e7474f9b60aef02456ac070 Mon Sep 17 00:00:00 2001 From: Ron Yorston Date: Sun, 3 Apr 2016 22:29:35 +0200 Subject: [PATCH 204/260] find_applet_by_name: loop index should be signed The loop for (j = ARRAY_SIZE(applet_nameofs)-1; j >= 0; j--) { was intended to terminate when j goes negative, so j needs to be signed. Signed-off-by: Ron Yorston Signed-off-by: Denys Vlasenko --- libbb/appletlib.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/libbb/appletlib.c b/libbb/appletlib.c index d798a2eac..de654f64c 100644 --- a/libbb/appletlib.c +++ b/libbb/appletlib.c @@ -141,7 +141,8 @@ void FAST_FUNC bb_show_usage(void) int FAST_FUNC find_applet_by_name(const char *name) { - unsigned i, j, max; + unsigned i, max; + int j; const char *p; /* The commented-out word-at-a-time code is ~40% faster, but +160 bytes. From 993dab78220d9dce42c45c8cecba23706735c860 Mon Sep 17 00:00:00 2001 From: Mike Frysinger Date: Sun, 3 Apr 2016 23:58:50 -0400 Subject: [PATCH 205/260] Revert "lxdialog: fix ncursesw include detection" This reverts commit e91bc53d0c2e8de7dc4fbdb888ab0a4923c2b475. Let's get back to a state that matches upstream so we can pull in all of their fixes from the last few years. Signed-off-by: Mike Frysinger --- scripts/kconfig/lxdialog/check-lxdialog.sh | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/scripts/kconfig/lxdialog/check-lxdialog.sh b/scripts/kconfig/lxdialog/check-lxdialog.sh index d34dfd46d..fcef0f59d 100644 --- a/scripts/kconfig/lxdialog/check-lxdialog.sh +++ b/scripts/kconfig/lxdialog/check-lxdialog.sh @@ -19,11 +19,7 @@ ldflags() # Where is ncurses.h? ccflags() { - if [ -f /usr/include/ncursesw/ncurses.h ]; then - echo '-I/usr/include/ncursesw -DCURSES_LOC=""' - elif [ -f /usr/include/ncursesw/curses.h ]; then - echo '-I/usr/include/ncursesw -DCURSES_LOC=""' - elif [ -f /usr/include/ncurses/ncurses.h ]; then + if [ -f /usr/include/ncurses/ncurses.h ]; then echo '-I/usr/include/ncurses -DCURSES_LOC=""' elif [ -f /usr/include/ncurses/curses.h ]; then echo '-I/usr/include/ncurses -DCURSES_LOC=""' From f48bd92285e20f1f9955bd3b07599beb80ef9ea5 Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Sat, 18 Sep 2010 19:25:32 -0700 Subject: [PATCH 206/260] kconfig: fix menuconfig on debian lenny In 60f33b8 (kconfig: get rid of stray a.o, support ncursesw, 2006-01-15), support to link menuconfig with ncursesw library was added. To compute the linker command option -l, we check "libncursesw.{so,a,dylib}" to allow ncursesw to be used as a replacement ncurses. However, when checking what header file to include, we do not check /usr/include/ncursesw directory. Add /usr/include/ncursesw to the list of directories that are checked. With this patch, on my Debian Lenny box with libncursesw5-dev package but not libncurses5-dev package, I can say "make menuconfig". Signed-off-by: Junio C Hamano Acked-by: Sam Ravnborg Signed-off-by: Michal Marek Signed-off-by: Mike Frysinger --- scripts/kconfig/lxdialog/check-lxdialog.sh | 2 ++ 1 file changed, 2 insertions(+) diff --git a/scripts/kconfig/lxdialog/check-lxdialog.sh b/scripts/kconfig/lxdialog/check-lxdialog.sh index fcef0f59d..82cc3a85e 100644 --- a/scripts/kconfig/lxdialog/check-lxdialog.sh +++ b/scripts/kconfig/lxdialog/check-lxdialog.sh @@ -23,6 +23,8 @@ ccflags() echo '-I/usr/include/ncurses -DCURSES_LOC=""' elif [ -f /usr/include/ncurses/curses.h ]; then echo '-I/usr/include/ncurses -DCURSES_LOC=""' + elif [ -f /usr/include/ncursesw/curses.h ]; then + echo '-I/usr/include/ncursesw -DCURSES_LOC=""' elif [ -f /usr/include/ncurses.h ]; then echo '-DCURSES_LOC=""' else From a0f24a06df79e70661d43fb543272e2fc1074291 Mon Sep 17 00:00:00 2001 From: Yaakov Selkowitz Date: Tue, 12 Jun 2012 19:05:02 -0500 Subject: [PATCH 207/260] kconfig: check ncursesw headers first in check-lxdialog Commit 8c41e5e363db55d91aa3b1cdce4ab02ad9821de7 added a check for ncursesw/curses.h for the case where ncurses and ncursesw are build separately but only one is installed. But if both are installed, the headers ncurses/curses.h and ncursesw/curses.h differ, and since libncursesw will be found first, so should ncursesw/curses.h. Signed-off-by: Yaakov Selkowitz Signed-off-by: Michal Marek Signed-off-by: Mike Frysinger --- scripts/kconfig/lxdialog/check-lxdialog.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/scripts/kconfig/lxdialog/check-lxdialog.sh b/scripts/kconfig/lxdialog/check-lxdialog.sh index 82cc3a85e..b75820bbd 100644 --- a/scripts/kconfig/lxdialog/check-lxdialog.sh +++ b/scripts/kconfig/lxdialog/check-lxdialog.sh @@ -19,12 +19,12 @@ ldflags() # Where is ncurses.h? ccflags() { - if [ -f /usr/include/ncurses/ncurses.h ]; then + if [ -f /usr/include/ncursesw/curses.h ]; then + echo '-I/usr/include/ncursesw -DCURSES_LOC=""' + elif [ -f /usr/include/ncurses/ncurses.h ]; then echo '-I/usr/include/ncurses -DCURSES_LOC=""' elif [ -f /usr/include/ncurses/curses.h ]; then echo '-I/usr/include/ncurses -DCURSES_LOC=""' - elif [ -f /usr/include/ncursesw/curses.h ]; then - echo '-I/usr/include/ncursesw -DCURSES_LOC=""' elif [ -f /usr/include/ncurses.h ]; then echo '-DCURSES_LOC=""' else From 74f58ed48cd6b8bdb3fb265b649db7dea4574341 Mon Sep 17 00:00:00 2001 From: Yaakov Selkowitz Date: Tue, 12 Jun 2012 19:05:15 -0500 Subject: [PATCH 208/260] kconfig: fix check-lxdialog for DLL platforms Import libraries on Cygwin and MinGW/MSYS use the .dll.a suffix, so checking this suffix is necessary to make sure ncurses will still be found when built without static libraries. Signed-off-by: Yaakov Selkowitz Signed-off-by: Michal Marek Signed-off-by: Mike Frysinger --- scripts/kconfig/lxdialog/check-lxdialog.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/kconfig/lxdialog/check-lxdialog.sh b/scripts/kconfig/lxdialog/check-lxdialog.sh index b75820bbd..e3b12c010 100644 --- a/scripts/kconfig/lxdialog/check-lxdialog.sh +++ b/scripts/kconfig/lxdialog/check-lxdialog.sh @@ -4,7 +4,7 @@ # What library to link ldflags() { - for ext in so a dylib ; do + for ext in so a dll.a dylib ; do for lib in ncursesw ncurses curses ; do $cc -print-file-name=lib${lib}.${ext} | grep -q / if [ $? -eq 0 ]; then From 8c3f943410ccfd79bb24eaa816dc8d57200d7a4c Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Tue, 2 Oct 2012 16:42:36 +0200 Subject: [PATCH 209/260] kbuild: Fix gcc -x syntax The correct syntax for gcc -x is "gcc -x assembler", not "gcc -xassembler". Even though the latter happens to work, the former is what is documented in the manual page and thus what gcc wrappers such as icecream do expect. This isn't a cosmetic change. The missing space prevents icecream from recognizing compilation tasks it can't handle, leading to silent kernel miscompilations. Besides me, credits go to Michael Matz and Dirk Mueller for investigating the miscompilation issue and tracking it down to this incorrect -x parameter syntax. Signed-off-by: Jean Delvare Acked-by: Ingo Molnar Cc: stable@vger.kernel.org Cc: Bernhard Walle Cc: Michal Marek Cc: Ralf Baechle Signed-off-by: Michal Marek Signed-off-by: Mike Frysinger --- scripts/kconfig/lxdialog/check-lxdialog.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/kconfig/lxdialog/check-lxdialog.sh b/scripts/kconfig/lxdialog/check-lxdialog.sh index e3b12c010..c8e8a7154 100644 --- a/scripts/kconfig/lxdialog/check-lxdialog.sh +++ b/scripts/kconfig/lxdialog/check-lxdialog.sh @@ -38,7 +38,7 @@ trap "rm -f $tmp" 0 1 2 3 15 # Check if we can link to ncurses check() { - $cc -xc - -o $tmp 2>/dev/null <<'EOF' + $cc -x c - -o $tmp 2>/dev/null <<'EOF' #include CURSES_LOC main() {} EOF From f755430d79171b2391ad9bf18da036720ab83b70 Mon Sep 17 00:00:00 2001 From: Krzysztof Mazur Date: Mon, 8 Oct 2012 18:18:22 +0200 Subject: [PATCH 210/260] menuconfig: fix extended colors ncurses support The ncurses library allows for extended colors. The support for extended colors support depends on wide-character support. ncurses headers enable extended colors (NCURSES_EXT_COLORS) only when wide-character support is enabled (NCURSES_WIDECHAR). The "make menuconfig" uses wide-character ncursesw library, which can be compiled with wide-character support, but does not define NCURSES_WIDECHAR and it's using headers without wide-character (and extended colors) support. This fixes problems with colors on systems with enabled extended colors (like PLD Linux). Without this patch "make menuconfig" is hard to use. Signed-off-by: Krzysztof Mazur Signed-off-by: Michal Marek Signed-off-by: Mike Frysinger --- scripts/kconfig/lxdialog/check-lxdialog.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/scripts/kconfig/lxdialog/check-lxdialog.sh b/scripts/kconfig/lxdialog/check-lxdialog.sh index c8e8a7154..80788137c 100644 --- a/scripts/kconfig/lxdialog/check-lxdialog.sh +++ b/scripts/kconfig/lxdialog/check-lxdialog.sh @@ -21,6 +21,7 @@ ccflags() { if [ -f /usr/include/ncursesw/curses.h ]; then echo '-I/usr/include/ncursesw -DCURSES_LOC=""' + echo ' -DNCURSES_WIDECHAR=1' elif [ -f /usr/include/ncurses/ncurses.h ]; then echo '-I/usr/include/ncurses -DCURSES_LOC=""' elif [ -f /usr/include/ncurses/curses.h ]; then From e62c715b3ebd6fc1d832229ded946d053bd45b94 Mon Sep 17 00:00:00 2001 From: Justin Lecher Date: Wed, 6 Mar 2013 14:02:01 +0100 Subject: [PATCH 211/260] menuconfig: optionally use pkg-config to detect ncurses libs When building ncurses with --with-termlib several symbols get moved from libncurses.so to libtinfo.so. Thus when linking with libncurses.so, one additionally needs to link with libtinfo.so. The ncurses pkg-config module will be used to detect the necessary libs for linking. If not available the old heuristic for detection of the ncurses libs will be used. Signed-off-by: Justin Lecher Tested-by: "Yann E. MORIN" Signed-off-by: "Yann E. MORIN" Signed-off-by: Mike Frysinger --- scripts/kconfig/lxdialog/check-lxdialog.sh | 2 ++ 1 file changed, 2 insertions(+) diff --git a/scripts/kconfig/lxdialog/check-lxdialog.sh b/scripts/kconfig/lxdialog/check-lxdialog.sh index 80788137c..782d20085 100644 --- a/scripts/kconfig/lxdialog/check-lxdialog.sh +++ b/scripts/kconfig/lxdialog/check-lxdialog.sh @@ -4,6 +4,8 @@ # What library to link ldflags() { + pkg-config --libs ncursesw 2>/dev/null && exit + pkg-config --libs ncurses 2>/dev/null && exit for ext in so a dll.a dylib ; do for lib in ncursesw ncurses curses ; do $cc -print-file-name=lib${lib}.${ext} | grep -q / From d35ba8b5eddedd50349adf9358574cdbbc3c47ef Mon Sep 17 00:00:00 2001 From: "Yann E. MORIN" Date: Fri, 22 Mar 2013 23:12:16 +0100 Subject: [PATCH 212/260] kconfig/lxdialog: rationalise the include paths where to find {.n}curses{,w}.h The current code does this: if [ -f /usr/include/ncursesw/curses.h ]; then echo '-I/usr/include/ncursesw -DCURSES_LOC=""' elif [ -f /usr/include/ncurses/ncurses.h ]; then echo '-I/usr/include/ncurses -DCURSES_LOC=""' elif [ -f /usr/include/ncurses/curses.h ]; then echo '-I/usr/include/ncurses -DCURSES_LOC=""' [...] This is merely inconsistent: - adding the full path to the directory in the -I directive, - especially since that path is already a sub-path of the system include path, - and then repeating the sub-path in the #include directive. Rationalise each include directive: - only use the filename in the #include directive, - keep the -I directives: they are always searched for before the system include path; this ensures the correct header is used. Using the -I directives and the filename-only in #include is more in line with how pkg-config behaves, eg.: $ pkg-config --cflags ncursesw -I/usr/include/ncursesw This paves the way for using pkg-config for CFLAGS, too, now we use it to find the libraries. Signed-off-by: "Yann E. MORIN" Signed-off-by: Mike Frysinger --- scripts/kconfig/lxdialog/check-lxdialog.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/scripts/kconfig/lxdialog/check-lxdialog.sh b/scripts/kconfig/lxdialog/check-lxdialog.sh index 782d20085..9d2a4c585 100644 --- a/scripts/kconfig/lxdialog/check-lxdialog.sh +++ b/scripts/kconfig/lxdialog/check-lxdialog.sh @@ -22,12 +22,12 @@ ldflags() ccflags() { if [ -f /usr/include/ncursesw/curses.h ]; then - echo '-I/usr/include/ncursesw -DCURSES_LOC=""' + echo '-I/usr/include/ncursesw -DCURSES_LOC=""' echo ' -DNCURSES_WIDECHAR=1' elif [ -f /usr/include/ncurses/ncurses.h ]; then echo '-I/usr/include/ncurses -DCURSES_LOC=""' elif [ -f /usr/include/ncurses/curses.h ]; then - echo '-I/usr/include/ncurses -DCURSES_LOC=""' + echo '-I/usr/include/ncurses -DCURSES_LOC=""' elif [ -f /usr/include/ncurses.h ]; then echo '-DCURSES_LOC=""' else From 935fe68236f21bf641b316fea1867754e754911b Mon Sep 17 00:00:00 2001 From: Michal Marek Date: Wed, 20 Aug 2014 16:02:59 +0200 Subject: [PATCH 213/260] kbuild: Make scripts executable The Makefiles call the respective interpreter explicitly, but this makes it easier to use the scripts manually. Signed-off-by: Michal Marek Signed-off-by: Mike Frysinger --- scripts/kconfig/lxdialog/check-lxdialog.sh | 0 1 file changed, 0 insertions(+), 0 deletions(-) mode change 100644 => 100755 scripts/kconfig/lxdialog/check-lxdialog.sh diff --git a/scripts/kconfig/lxdialog/check-lxdialog.sh b/scripts/kconfig/lxdialog/check-lxdialog.sh old mode 100644 new mode 100755 From d63d77a7f03eaa49729619a14aa9a12a0e9f95ad Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B8rn=20Forsman?= Date: Sun, 14 Sep 2014 12:57:50 +0200 Subject: [PATCH 214/260] kconfig/lxdialog: get ncurses CFLAGS with pkg-config MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This makes "make menuconfig" also work on systems where ncurses is not installed in a standard location (such as on NixOS). This patch changes ccflags() so that it tries pkg-config first, and only if pkg-config fails does it go back to the fallback/manual checks. This is the same algorithm that ldflags() already uses. Signed-off-by: Bjørn Forsman Signed-off-by: Michal Marek Signed-off-by: Mike Frysinger --- scripts/kconfig/lxdialog/check-lxdialog.sh | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/scripts/kconfig/lxdialog/check-lxdialog.sh b/scripts/kconfig/lxdialog/check-lxdialog.sh index 9d2a4c585..5075ebf2d 100755 --- a/scripts/kconfig/lxdialog/check-lxdialog.sh +++ b/scripts/kconfig/lxdialog/check-lxdialog.sh @@ -21,7 +21,11 @@ ldflags() # Where is ncurses.h? ccflags() { - if [ -f /usr/include/ncursesw/curses.h ]; then + if pkg-config --cflags ncursesw 2>/dev/null; then + echo '-DCURSES_LOC="" -DNCURSES_WIDECHAR=1' + elif pkg-config --cflags ncurses 2>/dev/null; then + echo '-DCURSES_LOC=""' + elif [ -f /usr/include/ncursesw/curses.h ]; then echo '-I/usr/include/ncursesw -DCURSES_LOC=""' echo ' -DNCURSES_WIDECHAR=1' elif [ -f /usr/include/ncurses/ncurses.h ]; then From ea1b44412a5802f507880ae8b705d58360e387c0 Mon Sep 17 00:00:00 2001 From: Mike Frysinger Date: Mon, 4 Apr 2016 01:28:32 -0400 Subject: [PATCH 215/260] syslogd: minor tweaks to text Signed-off-by: Mike Frysinger --- sysklogd/syslogd.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sysklogd/syslogd.c b/sysklogd/syslogd.c index 0ea557a6c..a119bdeae 100644 --- a/sysklogd/syslogd.c +++ b/sysklogd/syslogd.c @@ -33,7 +33,7 @@ //config: depends on SYSLOGD //config: help //config: This enables syslogd to rotate the message files -//config: on his own. No need to use an external rotatescript. +//config: on his own. No need to use an external rotate script. //config: //config:config FEATURE_REMOTE_LOG //config: bool "Remote Log support" @@ -133,7 +133,7 @@ //usage: IF_FEATURE_KMSG_SYSLOG( //usage: "\n -K Log to kernel printk buffer (use dmesg to read it)" //usage: ) -//usage: "\n -O FILE Log to FILE (default:/var/log/messages, stdout if -)" +//usage: "\n -O FILE Log to FILE (default: /var/log/messages, stdout if -)" //usage: IF_FEATURE_ROTATE_LOGFILE( //usage: "\n -s SIZE Max size (KB) before rotation (default:200KB, 0=off)" //usage: "\n -b N N rotated logs to keep (default:1, max=99, 0=purge)" From ee22fe8793679e0f366a5501e3c7b576a9eb46c9 Mon Sep 17 00:00:00 2001 From: Mike Frysinger Date: Mon, 4 Apr 2016 01:35:34 -0400 Subject: [PATCH 216/260] undeb: clean up Signed-off-by: Mike Frysinger --- examples/undeb | 74 +++++++++++++++++++++++++++----------------------- 1 file changed, 40 insertions(+), 34 deletions(-) diff --git a/examples/undeb b/examples/undeb index 37104e9d8..c30baf31b 100755 --- a/examples/undeb +++ b/examples/undeb @@ -5,49 +5,55 @@ # Requires the programs (ar, tar, gzip, and the pager more or less). # usage() { -echo "Usage: undeb -c package.deb " -echo " undeb -l package.deb " -echo " undeb -x package.deb /foo/boo " -exit + cat < + undeb -l package.deb + undeb -x package.deb /foo/boo +EOF + exit } deb=$2 exist() { -if [ "$deb" = "" ]; then -usage -elif [ ! -s "$deb" ]; then -echo "Can't find $deb!" -exit -fi + if [ -z "${deb}" ]; then + usage + elif [ ! -s "${deb}" ]; then + echo "Can't find ${deb}!" + exit 1 + fi } -if [ "$1" = "" ]; then -usage +if [ -z "$1" ]; then + usage elif [ "$1" = "-l" ]; then -exist -type more >/dev/null 2>&1 && pager=more -type less >/dev/null 2>&1 && pager=less -[ "$pager" = "" ] && echo "No pager found!" && exit -(ar -p $deb control.tar.gz | tar -xzO *control ; echo -e "\nPress enter to scroll, q to Quit!\n" ; ar -p $deb data.tar.gz | tar -tzv) | $pager -exit + exist + type more >/dev/null 2>&1 && pager=more + type less >/dev/null 2>&1 && pager=less + [ -z "${pager}" ] && echo "No pager found!" && exit 1 + ( + ar -p "${deb}" control.tar.gz | tar -xzO *control + printf "\nPress enter to scroll, q to Quit!\n\n" + ar -p "${deb}" data.tar.gz | tar -tzv + ) | ${pager} + exit elif [ "$1" = "-c" ]; then -exist -ar -p $deb control.tar.gz | tar -xzO *control -exit + exist + ar -p "${deb}" control.tar.gz | tar -xzO *control + exit elif [ "$1" = "-x" ]; then -exist -if [ "$3" = "" ]; then -usage -elif [ ! -d "$3" ]; then -echo "No such directory $3!" -exit -fi -ar -p $deb data.tar.gz | tar -xzvpf - -C $3 || exit -echo -echo "Extracted $deb to $3!" -exit + exist + if [ -z "$3" ]; then + usage + elif [ ! -d "$3" ]; then + echo "No such directory $3!" + exit 1 + fi + ar -p "${deb}" data.tar.gz | tar -xzvpf - -C "$3" || exit + echo + echo "Extracted ${deb} to $3!" + exit else -usage + usage fi From d7d4750e1e213e7448147186dddfe3bfbb47eea0 Mon Sep 17 00:00:00 2001 From: Mike Frysinger Date: Mon, 4 Apr 2016 01:39:17 -0400 Subject: [PATCH 217/260] unrpm: clean up Signed-off-by: Mike Frysinger --- examples/unrpm | 65 +++++++++++++++++++++++++++----------------------- 1 file changed, 35 insertions(+), 30 deletions(-) diff --git a/examples/unrpm b/examples/unrpm index 7fd3676f6..f48550b0a 100755 --- a/examples/unrpm +++ b/examples/unrpm @@ -5,44 +5,49 @@ # Requires the programs (cpio, gzip, and the pager more or less). # usage() { -echo "Usage: unrpm -l package.rpm " -echo " unrpm -x package.rpm /foo/boo " -exit + cat < + unrpm -x package.rpm /foo/boo +EOF + exit } rpm=$2 exist() { -if [ "$rpm" = "" ]; then -usage -elif [ ! -s "$rpm" ]; then -echo "Can't find $rpm!" -exit -fi + if [ -z "${rpm}" ]; then + usage + elif [ ! -s "${rpm}" ]; then + echo "Can't find ${rpm}!" + exit 1 + fi } -if [ "$1" = "" ]; then -usage +if [ -z "$1" ]; then + usage elif [ "$1" = "-l" ]; then -exist -type more >/dev/null 2>&1 && pager=more -type less >/dev/null 2>&1 && pager=less -[ "$pager" = "" ] && echo "No pager found!" && exit -(echo -e "\nPress enter to scroll, q to Quit!\n" ; rpm2cpio $rpm | cpio -tv --quiet) | $pager -exit + exist + type more >/dev/null 2>&1 && pager=more + type less >/dev/null 2>&1 && pager=less + [ "$pager" = "" ] && echo "No pager found!" && exit + ( + printf "\nPress enter to scroll, q to Quit!\n\n" + rpm2cpio "${rpm}" | cpio -tv --quiet + ) | ${pager} + exit elif [ "$1" = "-x" ]; then -exist -if [ "$3" = "" ]; then -usage -elif [ ! -d "$3" ]; then -echo "No such directory $3!" -exit -fi -rpm2cpio $rpm | (umask 0 ; cd $3 ; cpio -idmuv) || exit -echo -echo "Extracted $rpm to $3!" -exit + exist + if [ -z "$3" ]; then + usage + elif [ ! -d "$3" ]; then + echo "No such directory $3!" + exit 1 + fi + rpm2cpio "${rpm}" | (umask 0 ; cd "$3" ; cpio -idmuv) || exit + echo + echo "Extracted ${rpm} to $3!" + exit else -usage + usage fi From e4d925b8899e38437311d2c63d0d0d200e04b5a1 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Fri, 8 Apr 2016 00:20:36 +0200 Subject: [PATCH 218/260] sed: support "-f -" idiom Signed-off-by: Denys Vlasenko --- editors/sed.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/editors/sed.c b/editors/sed.c index 4c7f75521..9c4c8e148 100644 --- a/editors/sed.c +++ b/editors/sed.c @@ -1507,12 +1507,12 @@ int sed_main(int argc UNUSED_PARAM, char **argv) while (opt_f) { // -f char *line; FILE *cmdfile; - cmdfile = xfopen_for_read(llist_pop(&opt_f)); + cmdfile = xfopen_stdin(llist_pop(&opt_f)); while ((line = xmalloc_fgetline(cmdfile)) != NULL) { add_cmd(line); free(line); } - fclose(cmdfile); + fclose_if_not_stdin(cmdfile); } /* if we didn't get a pattern from -e or -f, use argv[0] */ if (!(opt & 0x30)) { From 2b91958dff0b7bae83cf2c3f2db55bd248fe0956 Mon Sep 17 00:00:00 2001 From: Ron Yorston Date: Fri, 8 Apr 2016 11:57:20 +0100 Subject: [PATCH 219/260] Rewrite iteration through applet names to save a few bytes function old new delta run_applet_and_exit 758 755 -3 ------------------------------------------------------------------------------ (add/remove: 0/0 grow/shrink: 0/1 up/down: 0/-3) Total: -3 bytes In standalone shell mode the saving increases to 17 bytes. Signed-off-by: Ron Yorston Signed-off-by: Denys Vlasenko --- libbb/appletlib.c | 3 ++- libbb/lineedit.c | 7 +++---- shell/ash.c | 3 ++- 3 files changed, 7 insertions(+), 6 deletions(-) diff --git a/libbb/appletlib.c b/libbb/appletlib.c index de654f64c..b682e6b85 100644 --- a/libbb/appletlib.c +++ b/libbb/appletlib.c @@ -791,7 +791,8 @@ static int busybox_main(char **argv) full_write2_str(a); full_write2_str("\n"); i++; - a += strlen(a) + 1; + while (*a++ != '\0') + continue; } return 0; } diff --git a/libbb/lineedit.c b/libbb/lineedit.c index 2ddb2b6e9..3e62f46b4 100644 --- a/libbb/lineedit.c +++ b/libbb/lineedit.c @@ -779,12 +779,11 @@ static NOINLINE unsigned complete_cmd_dir_file(const char *command, int type) if (type == FIND_EXE_ONLY) { const char *p = applet_names; - i = 0; - while (i < NUM_APPLETS) { + while (*p) { if (strncmp(pfind, p, pf_len) == 0) add_match(xstrdup(p)); - p += strlen(p) + 1; - i++; + while (*p++ != '\0') + continue; } } #endif diff --git a/shell/ash.c b/shell/ash.c index 5613e1f33..13eeab34b 100644 --- a/shell/ash.c +++ b/shell/ash.c @@ -12597,7 +12597,8 @@ helpcmd(int argc UNUSED_PARAM, char **argv UNUSED_PARAM) out1fmt("\n"); col = 0; } - a += strlen(a) + 1; + while (*a++ != '\0') + continue; } } # endif From 84ba50c32f7dbfccddd5c5ca34d48d97c3f72193 Mon Sep 17 00:00:00 2001 From: Ron Yorston Date: Sun, 3 Apr 2016 22:43:14 +0100 Subject: [PATCH 220/260] ash: bash-compatible $'...' shouldn't expand in double quotes Bash doesn't expand its $'...' construct in double quotes: $ echo "$'a\tb'" $'a\tb' Change BusyBox ash to do the same. This also fixes a problem with here documents where BusyBox ash gave an incorrect result for: $ cat < '$' > EOF '$' Reported-by: Timo Teras Signed-off-by: Ron Yorston Signed-off-by: Denys Vlasenko --- shell/ash.c | 2 +- shell/ash_test/ash-heredoc/heredoc4.right | 1 + shell/ash_test/ash-heredoc/heredoc4.tests | 3 +++ shell/ash_test/ash-quoting/dollar_squote_bash1.right | 1 + shell/ash_test/ash-quoting/dollar_squote_bash1.tests | 1 + 5 files changed, 7 insertions(+), 1 deletion(-) create mode 100644 shell/ash_test/ash-heredoc/heredoc4.right create mode 100755 shell/ash_test/ash-heredoc/heredoc4.tests diff --git a/shell/ash.c b/shell/ash.c index 13eeab34b..da9c95045 100644 --- a/shell/ash.c +++ b/shell/ash.c @@ -11500,7 +11500,7 @@ parsesub: { || (c != '(' && c != '{' && !is_name(c) && !is_special(c)) ) { #if ENABLE_ASH_BASH_COMPAT - if (c == '\'') + if (syntax != DQSYNTAX && c == '\'') bash_dollar_squote = 1; else #endif diff --git a/shell/ash_test/ash-heredoc/heredoc4.right b/shell/ash_test/ash-heredoc/heredoc4.right new file mode 100644 index 000000000..371b092e2 --- /dev/null +++ b/shell/ash_test/ash-heredoc/heredoc4.right @@ -0,0 +1 @@ +'$' diff --git a/shell/ash_test/ash-heredoc/heredoc4.tests b/shell/ash_test/ash-heredoc/heredoc4.tests new file mode 100755 index 000000000..642ddb324 --- /dev/null +++ b/shell/ash_test/ash-heredoc/heredoc4.tests @@ -0,0 +1,3 @@ +cat < Date: Sun, 17 Apr 2016 21:05:34 +0200 Subject: [PATCH 221/260] unzip: fix a case where we find wrong CDE. Closes 8821 function old new delta unzip_main 2472 2490 +18 Signed-off-by: Denys Vlasenko --- archival/unzip.c | 43 +++++++++++++++++++++++++++++++++++-------- 1 file changed, 35 insertions(+), 8 deletions(-) diff --git a/archival/unzip.c b/archival/unzip.c index f41ab6f44..b0a6ca836 100644 --- a/archival/unzip.c +++ b/archival/unzip.c @@ -45,6 +45,12 @@ #include "libbb.h" #include "bb_archive.h" +#if 0 +# define dbg(...) bb_error_msg(__VA_ARGS__) +#else +# define dbg(...) ((void)0) +#endif + enum { #if BB_BIG_ENDIAN ZIP_FILEHEADER_MAGIC = 0x504b0304, @@ -193,15 +199,17 @@ static uint32_t find_cdf_offset(void) unsigned char *p; off_t end; unsigned char *buf = xzalloc(PEEK_FROM_END); + uint32_t found; end = xlseek(zip_fd, 0, SEEK_END); end -= PEEK_FROM_END; if (end < 0) end = 0; - xlseek(zip_fd, end, SEEK_SET); + dbg("Looking for cdf_offset starting from 0x%"OFF_FMT"x", end); + xlseek(zip_fd, end, SEEK_SET); full_read(zip_fd, buf, PEEK_FROM_END); - cde_header.formatted.cdf_offset = BAD_CDF_OFFSET; + found = BAD_CDF_OFFSET; p = buf; while (p <= buf + PEEK_FROM_END - CDE_HEADER_LEN - 4) { if (*p != 'P') { @@ -220,14 +228,25 @@ static uint32_t find_cdf_offset(void) /* * I've seen .ZIP files with seemingly valid CDEs * where cdf_offset points past EOF - ?? - * Ignore such CDEs: + * This check ignores such CDEs: */ - if (cde_header.formatted.cdf_offset < end + (p - buf)) - break; - cde_header.formatted.cdf_offset = BAD_CDF_OFFSET; + if (cde_header.formatted.cdf_offset < end + (p - buf)) { + found = cde_header.formatted.cdf_offset; + dbg("Possible cdf_offset:0x%x at 0x%"OFF_FMT"x", + (unsigned)found, end + (p-3 - buf)); + dbg(" cdf_offset+cdf_size:0x%x", + (unsigned)(found + SWAP_LE32(cde_header.formatted.cdf_size))); + /* + * We do not "break" here because only the last CDE is valid. + * I've seen a .zip archive which contained a .zip file, + * uncompressed, and taking the first CDE was using + * the CDE inside that file! + */ + } } free(buf); - return cde_header.formatted.cdf_offset; + dbg("Found cdf_offset:0x%x", (unsigned)found); + return found; }; static uint32_t read_next_cdf(uint32_t cdf_offset, cdf_header_t *cdf_ptr) @@ -240,9 +259,13 @@ static uint32_t read_next_cdf(uint32_t cdf_offset, cdf_header_t *cdf_ptr) cdf_offset = find_cdf_offset(); if (cdf_offset != BAD_CDF_OFFSET) { + dbg("Reading CDF at 0x%x", (unsigned)cdf_offset); xlseek(zip_fd, cdf_offset + 4, SEEK_SET); xread(zip_fd, cdf_ptr->raw, CDF_HEADER_LEN); FIX_ENDIANNESS_CDF(*cdf_ptr); + dbg("file_name_length:%u", (unsigned)cdf_ptr->formatted.file_name_length); + dbg("extra_field_length:%u", (unsigned)cdf_ptr->formatted.extra_field_length); + dbg("file_comment_length:%u", (unsigned)cdf_ptr->formatted.file_comment_length); cdf_offset += 4 + CDF_HEADER_LEN + cdf_ptr->formatted.file_name_length + cdf_ptr->formatted.extra_field_length @@ -532,11 +555,14 @@ int unzip_main(int argc, char **argv) /* Check magic number */ xread(zip_fd, &magic, 4); /* Central directory? It's at the end, so exit */ - if (magic == ZIP_CDF_MAGIC) + if (magic == ZIP_CDF_MAGIC) { + dbg("got ZIP_CDF_MAGIC"); break; + } #if ENABLE_DESKTOP /* Data descriptor? It was a streaming file, go on */ if (magic == ZIP_DD_MAGIC) { + dbg("got ZIP_DD_MAGIC"); /* skip over duplicate crc32, cmpsize and ucmpsize */ unzip_skip(3 * 4); continue; @@ -544,6 +570,7 @@ int unzip_main(int argc, char **argv) #endif if (magic != ZIP_FILEHEADER_MAGIC) bb_error_msg_and_die("invalid zip magic %08X", (int)magic); + dbg("got ZIP_FILEHEADER_MAGIC"); /* Read the file header */ xread(zip_fd, zip_header.raw, ZIP_HEADER_LEN); From bca4deee8393395f77630ad320c306d06ea186ed Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Mon, 18 Apr 2016 01:14:05 +0200 Subject: [PATCH 222/260] unzip: fix percent overflow; show "stored" files properly Signed-off-by: Denys Vlasenko --- archival/unzip.c | 35 +++++++++++++++++++++++++++++------ 1 file changed, 29 insertions(+), 6 deletions(-) diff --git a/archival/unzip.c b/archival/unzip.c index b0a6ca836..7bf51f466 100644 --- a/archival/unzip.c +++ b/archival/unzip.c @@ -263,15 +263,18 @@ static uint32_t read_next_cdf(uint32_t cdf_offset, cdf_header_t *cdf_ptr) xlseek(zip_fd, cdf_offset + 4, SEEK_SET); xread(zip_fd, cdf_ptr->raw, CDF_HEADER_LEN); FIX_ENDIANNESS_CDF(*cdf_ptr); - dbg("file_name_length:%u", (unsigned)cdf_ptr->formatted.file_name_length); - dbg("extra_field_length:%u", (unsigned)cdf_ptr->formatted.extra_field_length); - dbg("file_comment_length:%u", (unsigned)cdf_ptr->formatted.file_comment_length); + dbg(" file_name_length:%u extra_field_length:%u file_comment_length:%u", + (unsigned)cdf_ptr->formatted.file_name_length, + (unsigned)cdf_ptr->formatted.extra_field_length, + (unsigned)cdf_ptr->formatted.file_comment_length + ); cdf_offset += 4 + CDF_HEADER_LEN + cdf_ptr->formatted.file_name_length + cdf_ptr->formatted.extra_field_length + cdf_ptr->formatted.file_comment_length; } + dbg("Returning file position to 0x%"OFF_FMT"x", org); xlseek(zip_fd, org, SEEK_SET); return cdf_offset; }; @@ -614,6 +617,11 @@ int unzip_main(int argc, char **argv) bb_error_msg_and_die("can't find file table"); } #endif + dbg("File cmpsize:0x%x extra_len:0x%x ucmpsize:0x%x", + (unsigned)zip_header.formatted.cmpsize, + (unsigned)zip_header.formatted.extra_len, + (unsigned)zip_header.formatted.ucmpsize + ); /* Read filename */ free(dst_fn); @@ -646,16 +654,31 @@ int unzip_main(int argc, char **argv) (dostime & 0x0000f800) >> 11, (dostime & 0x000007e0) >> 5, dst_fn); - total_usize += zip_header.formatted.ucmpsize; } else { unsigned long percents = zip_header.formatted.ucmpsize - zip_header.formatted.cmpsize; + if ((int32_t)percents < 0) + percents = 0; /* happens if ucmpsize < cmpsize */ percents = percents * 100; if (zip_header.formatted.ucmpsize) percents /= zip_header.formatted.ucmpsize; // " Length Method Size Ratio Date Time CRC-32 Name\n" // "-------- ------ ------- ----- ---- ---- ------ ----" - printf( "%8u Defl:N" "%9u%4u%% %02u-%02u-%02u %02u:%02u %08x %s\n", + printf( "%8u %s" "%9u%4u%% %02u-%02u-%02u %02u:%02u %08x %s\n", (unsigned)zip_header.formatted.ucmpsize, + zip_header.formatted.method == 0 ? "Stored" : "Defl:N", /* Defl is method 8 */ +/* TODO: show other methods? + * 1 - Shrunk + * 2 - Reduced with compression factor 1 + * 3 - Reduced with compression factor 2 + * 4 - Reduced with compression factor 3 + * 5 - Reduced with compression factor 4 + * 6 - Imploded + * 7 - Reserved for Tokenizing compression algorithm + * 9 - Deflate64 + * 10 - PKWARE Data Compression Library Imploding + * 11 - Reserved by PKWARE + * 12 - BZIP2 + */ (unsigned)zip_header.formatted.cmpsize, (unsigned)percents, (dostime & 0x01e00000) >> 21, @@ -665,9 +688,9 @@ int unzip_main(int argc, char **argv) (dostime & 0x000007e0) >> 5, zip_header.formatted.crc32, dst_fn); - total_usize += zip_header.formatted.ucmpsize; total_size += zip_header.formatted.cmpsize; } + total_usize += zip_header.formatted.ucmpsize; i = 'n'; } else if (dst_fd == STDOUT_FILENO) { /* Extracting to STDOUT */ From 07bd9799217038391c8d299e6a2e031fef23c20b Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Mon, 18 Apr 2016 01:43:24 +0200 Subject: [PATCH 223/260] unzip: better match for "standard" unzip's output; string shrinkage function old new delta unzip_main 2490 2426 -64 ------------------------------------------------------------------------------ (add/remove: 0/0 grow/shrink: 0/1 up/down: 0/-64) Total: -64 bytes text data bss dec hex filename 924008 906 17160 942074 e5ffa busybox_old 923846 906 17160 941912 e5f58 busybox_unstripped Signed-off-by: Denys Vlasenko --- archival/unzip.c | 62 ++++++++++++++++++++++++++---------------------- 1 file changed, 33 insertions(+), 29 deletions(-) diff --git a/archival/unzip.c b/archival/unzip.c index 7bf51f466..a7532e0ff 100644 --- a/archival/unzip.c +++ b/archival/unzip.c @@ -514,11 +514,11 @@ int unzip_main(int argc, char **argv) printf("Archive: %s\n", src_fn); if (listing) { puts(verbose ? - " Length Method Size Ratio Date Time CRC-32 Name\n" - "-------- ------ ------- ----- ---- ---- ------ ----" + " Length Method Size Cmpr Date Time CRC-32 Name\n" + "-------- ------ ------- ---- ---------- ----- -------- ----" : - " Length Date Time Name\n" - " -------- ---- ---- ----" + " Length Date Time Name\n" + "--------- ---------- ----- ----" ); } } @@ -643,16 +643,20 @@ int unzip_main(int argc, char **argv) if (listing) { /* List entry */ unsigned dostime = zip_header.formatted.modtime | (zip_header.formatted.moddate << 16); - if (!verbose) { - // " Length Date Time Name\n" - // " -------- ---- ---- ----" - printf( "%9u %02u-%02u-%02u %02u:%02u %s\n", - (unsigned)zip_header.formatted.ucmpsize, + char dtbuf[sizeof("mm-dd-yyyy hh:mm")]; + sprintf(dtbuf, "%02u-%02u-%04u %02u:%02u", (dostime & 0x01e00000) >> 21, (dostime & 0x001f0000) >> 16, - (((dostime & 0xfe000000) >> 25) + 1980) % 100, + ((dostime & 0xfe000000) >> 25) + 1980, (dostime & 0x0000f800) >> 11, - (dostime & 0x000007e0) >> 5, + (dostime & 0x000007e0) >> 5 + ); + if (!verbose) { + // " Length Date Time Name\n" + // "--------- ---------- ----- ----" + printf( "%9u " "%s " "%s\n", + (unsigned)zip_header.formatted.ucmpsize, + dtbuf, dst_fn); } else { unsigned long percents = zip_header.formatted.ucmpsize - zip_header.formatted.cmpsize; @@ -661,9 +665,9 @@ int unzip_main(int argc, char **argv) percents = percents * 100; if (zip_header.formatted.ucmpsize) percents /= zip_header.formatted.ucmpsize; - // " Length Method Size Ratio Date Time CRC-32 Name\n" - // "-------- ------ ------- ----- ---- ---- ------ ----" - printf( "%8u %s" "%9u%4u%% %02u-%02u-%02u %02u:%02u %08x %s\n", + // " Length Method Size Cmpr Date Time CRC-32 Name\n" + // "-------- ------ ------- ---- ---------- ----- -------- ----" + printf( "%8u %s" "%9u%4u%% " "%s " "%08x " "%s\n", (unsigned)zip_header.formatted.ucmpsize, zip_header.formatted.method == 0 ? "Stored" : "Defl:N", /* Defl is method 8 */ /* TODO: show other methods? @@ -681,11 +685,7 @@ int unzip_main(int argc, char **argv) */ (unsigned)zip_header.formatted.cmpsize, (unsigned)percents, - (dostime & 0x01e00000) >> 21, - (dostime & 0x001f0000) >> 16, - (((dostime & 0xfe000000) >> 25) + 1980) % 100, - (dostime & 0x0000f800) >> 11, - (dostime & 0x000007e0) >> 5, + dtbuf, zip_header.formatted.crc32, dst_fn); total_size += zip_header.formatted.cmpsize; @@ -793,21 +793,25 @@ int unzip_main(int argc, char **argv) if (listing && quiet <= 1) { if (!verbose) { - // " Length Date Time Name\n" - // " -------- ---- ---- ----" - printf( " -------- -------\n" - "%9lu" " %u files\n", - total_usize, total_entries); + // " Length Date Time Name\n" + // "--------- ---------- ----- ----" + printf( " --------%21s" "-------\n" + "%9lu%21s" "%u files\n", + "", + total_usize, "", total_entries); } else { unsigned long percents = total_usize - total_size; + if ((long)percents < 0) + percents = 0; /* happens if usize < size */ percents = percents * 100; if (total_usize) percents /= total_usize; - // " Length Method Size Ratio Date Time CRC-32 Name\n" - // "-------- ------ ------- ----- ---- ---- ------ ----" - printf( "-------- ------- --- -------\n" - "%8lu" "%17lu%4u%% %u files\n", - total_usize, total_size, (unsigned)percents, + // " Length Method Size Cmpr Date Time CRC-32 Name\n" + // "-------- ------ ------- ---- ---------- ----- -------- ----" + printf( "-------- ------- ----%28s" "----\n" + "%8lu" "%17lu%4u%%%28s" "%u files\n", + "", + total_usize, total_size, (unsigned)percents, "", total_entries); } } From 5598bdf0d3d46a865a4d23785e2d09e6db9be420 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Mon, 18 Apr 2016 02:34:29 +0200 Subject: [PATCH 224/260] unzip: shorter code for date/time generation function old new delta unzip_main 2426 2414 -12 Signed-off-by: Denys Vlasenko --- archival/unzip.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/archival/unzip.c b/archival/unzip.c index a7532e0ff..be32e60e2 100644 --- a/archival/unzip.c +++ b/archival/unzip.c @@ -642,14 +642,14 @@ int unzip_main(int argc, char **argv) } else { if (listing) { /* List entry */ - unsigned dostime = zip_header.formatted.modtime | (zip_header.formatted.moddate << 16); char dtbuf[sizeof("mm-dd-yyyy hh:mm")]; sprintf(dtbuf, "%02u-%02u-%04u %02u:%02u", - (dostime & 0x01e00000) >> 21, - (dostime & 0x001f0000) >> 16, - ((dostime & 0xfe000000) >> 25) + 1980, - (dostime & 0x0000f800) >> 11, - (dostime & 0x000007e0) >> 5 + (zip_header.formatted.moddate >> 5) & 0xf, // mm: 0x01e0 + (zip_header.formatted.moddate) & 0x1f, // dd: 0x001f + (zip_header.formatted.moddate >> 9) + 1980, // yy: 0xfe00 + (zip_header.formatted.modtime >> 11), // hh: 0xf800 + (zip_header.formatted.modtime >> 5) & 0x3f // mm: 0x07e0 + // seconds/2 are not shown, encoded in ----------- 0x001f ); if (!verbose) { // " Length Date Time Name\n" From e6a2f4cc5a47d3022bdf5ca2cacbaa5a8c5baf7a Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Thu, 21 Apr 2016 16:26:30 +0200 Subject: [PATCH 225/260] libbb: make bb_common_bufsiz1 1 kbyte, add capability to use bss tail for it The config item is FEATURE_USE_BSS_TAIL. When it is off (default): function old new delta read_config 210 228 +18 doCommands 2279 2294 +15 ipneigh_list_or_flush 763 772 +9 ipaddr_list_or_flush 1256 1261 +5 display_process_list 1301 1306 +5 conspy_main 1378 1383 +5 do_lzo_compress 352 355 +3 do_lzo_decompress 565 567 +2 push 46 44 -2 inetd_main 2136 2134 -2 uevent_main 421 418 -3 addLines 97 92 -5 bb_common_bufsiz1 8193 1024 -7169 ------------------------------------------------------------------------------ (add/remove: 0/0 grow/shrink: 8/5 up/down: 62/-7181) Total: -7119 bytes text data bss dec hex filename 829850 4086 9080 843016 cdd08 busybox_old 829901 4086 1904 835891 cc133 busybox_unstripped FEATURE_USE_BSS_TAIL=y: read_config 210 228 +18 doCommands 2279 2294 +15 ipneigh_list_or_flush 763 772 +9 ipaddr_list_or_flush 1256 1261 +5 display_process_list 1301 1306 +5 conspy_main 1378 1383 +5 do_lzo_compress 352 355 +3 do_lzo_decompress 565 567 +2 inetd_main 2136 2134 -2 bb_common_bufsiz1 8193 - -8193 ------------------------------------------------------------------------------ (add/remove: 0/1 grow/shrink: 8/1 up/down: 62/-8195) Total: -8133 bytes text data bss dec hex filename 829850 4086 9080 843016 cdd08 busybox_old 829911 4086 880 834877 cbd3d busybox_unstripped FIXME: setup_common_bufsiz() calls are missing. Signed-off-by: Denys Vlasenko --- Makefile | 7 +- archival/cpio.c | 3 +- archival/lzop.c | 3 +- archival/rpm.c | 3 +- archival/tar.c | 1 + console-tools/dumpkmap.c | 1 + console-tools/resize.c | 3 +- coreutils/catv.c | 1 + coreutils/cksum.c | 6 +- coreutils/date.c | 6 +- coreutils/dd.c | 3 +- coreutils/du.c | 3 +- coreutils/expr.c | 3 +- coreutils/ls.c | 3 +- coreutils/od_bloaty.c | 3 +- coreutils/split.c | 1 + coreutils/stat.c | 6 +- coreutils/stty.c | 3 +- coreutils/sum.c | 3 +- coreutils/tail.c | 3 +- coreutils/tee.c | 6 +- debianutils/run_parts.c | 3 +- debianutils/start_stop_daemon.c | 3 +- e2fsprogs/fsck.c | 3 +- editors/diff.c | 1 + editors/ed.c | 8 ++- editors/sed.c | 3 +- findutils/find.c | 3 +- findutils/grep.c | 3 +- findutils/xargs.c | 3 +- include/libbb.h | 4 -- init/bootchartd.c | 3 +- libbb/common_bufsiz.c | 74 +++++++++++++++++++ libbb/messages.c | 5 -- loginutils/login.c | 3 +- miscutils/chat.c | 1 + miscutils/conspy.c | 6 +- miscutils/crond.c | 3 +- miscutils/dc.c | 3 +- miscutils/fbsplash.c | 6 +- miscutils/hdparm.c | 3 +- miscutils/i2c_tools.c | 1 + miscutils/inotifyd.c | 6 +- miscutils/less.c | 6 +- miscutils/microcom.c | 6 +- networking/arp.c | 3 +- networking/arping.c | 3 +- networking/ftpd.c | 3 +- networking/ftpgetput.c | 3 +- networking/httpd.c | 10 +-- networking/ifupdown.c | 3 +- networking/inetd.c | 3 +- networking/isrv_identd.c | 6 +- networking/libiproute/ipaddress.c | 3 +- networking/libiproute/ipneigh.c | 3 +- networking/libiproute/iproute.c | 3 +- networking/nc.c | 3 +- networking/ping.c | 5 +- networking/slattach.c | 3 +- networking/tc.c | 3 +- networking/tcpudp.c | 3 +- networking/telnet.c | 3 +- networking/telnetd.c | 3 +- networking/tftp.c | 6 +- networking/udhcp/common.h | 1 + networking/udhcp/dhcpd.h | 2 +- networking/udhcp/dhcprelay.c | 2 +- networking/udhcp/files.c | 46 ++++++------ networking/zcip.c | 3 +- procps/free.c | 3 +- procps/fuser.c | 3 +- procps/nmeter.c | 9 +-- procps/ps.c | 3 +- procps/top.c | 3 +- runit/runsv.c | 3 +- runit/runsvdir.c | 3 +- runit/sv.c | 3 +- runit/svlogd.c | 5 +- scripts/generate_BUFSIZ.sh | 114 ++++++++++++++++++++++++++++++ selinux/setfiles.c | 2 +- sysklogd/klogd.c | 6 +- sysklogd/logread.c | 3 +- sysklogd/syslogd_and_logger.c | 1 + util-linux/mdev.c | 3 +- util-linux/mkswap.c | 1 + util-linux/more.c | 1 + util-linux/mount.c | 3 +- util-linux/script.c | 10 +-- util-linux/swaponoff.c | 3 +- util-linux/uevent.c | 3 +- util-linux/umount.c | 3 +- 91 files changed, 414 insertions(+), 131 deletions(-) create mode 100644 libbb/common_bufsiz.c create mode 100755 scripts/generate_BUFSIZ.sh diff --git a/Makefile b/Makefile index dab807805..75a33c1fb 100644 --- a/Makefile +++ b/Makefile @@ -610,7 +610,8 @@ quiet_cmd_busybox__ ?= LINK $@ "$(LDFLAGS) $(EXTRA_LDFLAGS)" \ "$(core-y)" \ "$(libs-y)" \ - "$(LDLIBS)" + "$(LDLIBS)" \ + && $(srctree)/scripts/generate_BUFSIZ.sh include/common_bufsiz.h # Generate System.map quiet_cmd_sysmap = SYSMAP @@ -844,12 +845,15 @@ export CPPFLAGS_busybox.lds += -P -C -U$(ARCH) # Split autoconf.h into include/linux/config/* quiet_cmd_gen_bbconfigopts = GEN include/bbconfigopts.h cmd_gen_bbconfigopts = $(srctree)/scripts/mkconfigs include/bbconfigopts.h include/bbconfigopts_bz2.h +quiet_cmd_gen_common_bufsiz = GEN include/common_bufsiz.h + cmd_gen_common_bufsiz = $(srctree)/scripts/generate_BUFSIZ.sh include/common_bufsiz.h quiet_cmd_split_autoconf = SPLIT include/autoconf.h -> include/config/* cmd_split_autoconf = scripts/basic/split-include include/autoconf.h include/config #bbox# piggybacked generation of few .h files include/config/MARKER: scripts/basic/split-include include/autoconf.h $(call cmd,split_autoconf) $(call cmd,gen_bbconfigopts) + $(call cmd,gen_common_bufsiz) @touch $@ # Generate some files @@ -965,6 +969,7 @@ CLEAN_FILES += busybox busybox_unstripped* busybox.links \ MRPROPER_DIRS += include/config include2 MRPROPER_FILES += .config .config.old include/asm .version .old_version \ include/NUM_APPLETS.h \ + include/common_bufsiz.h \ include/autoconf.h \ include/bbconfigopts.h \ include/bbconfigopts_bz2.h \ diff --git a/archival/cpio.c b/archival/cpio.c index 82b3fe5ed..a3036e1ab 100644 --- a/archival/cpio.c +++ b/archival/cpio.c @@ -11,6 +11,7 @@ * Only supports new ASCII and CRC formats */ #include "libbb.h" +#include "common_bufsiz.h" #include "bb_archive.h" //config:config CPIO @@ -170,7 +171,7 @@ enum { struct globals { struct bb_uidgid_t owner_ugid; } FIX_ALIASING; -#define G (*(struct globals*)&bb_common_bufsiz1) +#define G (*(struct globals*)bb_common_bufsiz1) void BUG_cpio_globals_too_big(void); #define INIT_G() do { \ G.owner_ugid.uid = -1L; \ diff --git a/archival/lzop.c b/archival/lzop.c index a5fc01941..1371c9751 100644 --- a/archival/lzop.c +++ b/archival/lzop.c @@ -71,6 +71,7 @@ //usage: "\n -F Don't store or verify checksum" #include "libbb.h" +#include "common_bufsiz.h" #include "bb_archive.h" #include "liblzo_interface.h" @@ -443,7 +444,7 @@ struct globals { chksum_t chksum_in; chksum_t chksum_out; } FIX_ALIASING; -#define G (*(struct globals*)&bb_common_bufsiz1) +#define G (*(struct globals*)bb_common_bufsiz1) #define INIT_G() do { } while (0) //#define G (*ptr_to_globals) //#define INIT_G() do { diff --git a/archival/rpm.c b/archival/rpm.c index 105394481..079b7a95b 100644 --- a/archival/rpm.c +++ b/archival/rpm.c @@ -29,6 +29,7 @@ //usage: "\n -qpc List config files" #include "libbb.h" +#include "common_bufsiz.h" #include "bb_archive.h" #include "rpm.h" @@ -93,7 +94,7 @@ struct globals { rpm_index **mytags; int tagcount; } FIX_ALIASING; -#define G (*(struct globals*)&bb_common_bufsiz1) +#define G (*(struct globals*)bb_common_bufsiz1) #define INIT_G() do { } while (0) static void extract_cpio(int fd, const char *source_rpm) diff --git a/archival/tar.c b/archival/tar.c index 23ac00e86..caf4363de 100644 --- a/archival/tar.c +++ b/archival/tar.c @@ -146,6 +146,7 @@ #include #include "libbb.h" +#include "common_bufsiz.h" #include "bb_archive.h" /* FIXME: Stop using this non-standard feature */ #ifndef FNM_LEADING_DIR diff --git a/console-tools/dumpkmap.c b/console-tools/dumpkmap.c index bf8d690da..6412dffc8 100644 --- a/console-tools/dumpkmap.c +++ b/console-tools/dumpkmap.c @@ -18,6 +18,7 @@ //usage: "$ dumpkmap > keymap\n" #include "libbb.h" +#include "common_bufsiz.h" /* From */ struct kbentry { diff --git a/console-tools/resize.c b/console-tools/resize.c index 4b0d63a03..ed80aa082 100644 --- a/console-tools/resize.c +++ b/console-tools/resize.c @@ -14,10 +14,11 @@ //usage: "Resize the screen" #include "libbb.h" +#include "common_bufsiz.h" #define ESC "\033" -#define old_termios_p ((struct termios*)&bb_common_bufsiz1) +#define old_termios_p ((struct termios*)bb_common_bufsiz1) static void onintr(int sig UNUSED_PARAM) diff --git a/coreutils/catv.c b/coreutils/catv.c index 6bb73ba63..801d2451d 100644 --- a/coreutils/catv.c +++ b/coreutils/catv.c @@ -19,6 +19,7 @@ //usage: "\n -v Don't use ^x or M-x escapes" #include "libbb.h" +#include "common_bufsiz.h" #define CATV_OPT_e (1<<0) #define CATV_OPT_t (1<<1) diff --git a/coreutils/cksum.c b/coreutils/cksum.c index ac0b0c319..d8351e7c6 100644 --- a/coreutils/cksum.c +++ b/coreutils/cksum.c @@ -13,6 +13,7 @@ //usage: "Calculate the CRC32 checksums of FILES" #include "libbb.h" +#include "common_bufsiz.h" /* This is a NOEXEC applet. Be very careful! */ @@ -42,8 +43,9 @@ int cksum_main(int argc UNUSED_PARAM, char **argv) crc = 0; length = 0; -#define read_buf bb_common_bufsiz1 - while ((bytes_read = safe_read(fd, read_buf, sizeof(read_buf))) > 0) { +#define read_buf bb_common_bufsiz1 +#define sizeof_read_buf COMMON_BUFSIZE + while ((bytes_read = safe_read(fd, read_buf, sizeof_read_buf)) > 0) { length += bytes_read; crc = crc32_block_endian1(crc, read_buf, bytes_read, crc32_table); } diff --git a/coreutils/date.c b/coreutils/date.c index 7965775fe..59b4b8f2a 100644 --- a/coreutils/date.c +++ b/coreutils/date.c @@ -138,6 +138,7 @@ //usage: "Wed Apr 12 18:52:41 MDT 2000\n" #include "libbb.h" +#include "common_bufsiz.h" #if ENABLE_FEATURE_DATE_NANO # include #endif @@ -367,7 +368,8 @@ int date_main(int argc UNUSED_PARAM, char **argv) } #endif -#define date_buf bb_common_bufsiz1 +#define date_buf bb_common_bufsiz1 +#define sizeof_date_buf COMMON_BUFSIZE if (*fmt_dt2str == '\0') { /* With no format string, just print a blank line */ date_buf[0] = '\0'; @@ -377,7 +379,7 @@ int date_main(int argc UNUSED_PARAM, char **argv) fmt_dt2str = (char*)"%Y.%m.%d-%H:%M:%S"; } /* Generate output string */ - strftime(date_buf, sizeof(date_buf), fmt_dt2str, &tm_time); + strftime(date_buf, sizeof_date_buf, fmt_dt2str, &tm_time); } puts(date_buf); diff --git a/coreutils/dd.c b/coreutils/dd.c index 0c0ea07b9..a5b8882a0 100644 --- a/coreutils/dd.c +++ b/coreutils/dd.c @@ -91,6 +91,7 @@ //usage: "4+0 records out\n" #include "libbb.h" +#include "common_bufsiz.h" /* This is a NOEXEC applet. Be very careful! */ @@ -108,7 +109,7 @@ struct globals { #endif int flags; } FIX_ALIASING; -#define G (*(struct globals*)&bb_common_bufsiz1) +#define G (*(struct globals*)bb_common_bufsiz1) #define INIT_G() do { \ /* we have to zero it out because of NOEXEC */ \ memset(&G, 0, sizeof(G)); \ diff --git a/coreutils/du.c b/coreutils/du.c index 1889c16bb..3d6777670 100644 --- a/coreutils/du.c +++ b/coreutils/du.c @@ -58,6 +58,7 @@ //usage: "2417 .\n" #include "libbb.h" +#include "common_bufsiz.h" enum { OPT_a_files_too = (1 << 0), @@ -85,7 +86,7 @@ struct globals { int du_depth; dev_t dir_dev; } FIX_ALIASING; -#define G (*(struct globals*)&bb_common_bufsiz1) +#define G (*(struct globals*)bb_common_bufsiz1) #define INIT_G() do { } while (0) diff --git a/coreutils/expr.c b/coreutils/expr.c index c986f9327..59a66d9c5 100644 --- a/coreutils/expr.c +++ b/coreutils/expr.c @@ -61,6 +61,7 @@ //usage: "of characters matched or 0." #include "libbb.h" +#include "common_bufsiz.h" #include "xregex.h" #if ENABLE_EXPR_MATH_SUPPORT_64 @@ -99,7 +100,7 @@ typedef struct valinfo VALUE; struct globals { char **args; } FIX_ALIASING; -#define G (*(struct globals*)&bb_common_bufsiz1) +#define G (*(struct globals*)bb_common_bufsiz1) #define INIT_G() do { } while (0) /* forward declarations */ diff --git a/coreutils/ls.c b/coreutils/ls.c index 20bd61860..e8c3e0490 100644 --- a/coreutils/ls.c +++ b/coreutils/ls.c @@ -93,6 +93,7 @@ //usage: ) #include "libbb.h" +#include "common_bufsiz.h" #include "unicode.h" @@ -365,7 +366,7 @@ struct globals { time_t current_time_t; #endif } FIX_ALIASING; -#define G (*(struct globals*)&bb_common_bufsiz1) +#define G (*(struct globals*)bb_common_bufsiz1) #define INIT_G() do { \ /* we have to zero it out because of NOEXEC */ \ memset(&G, 0, sizeof(G)); \ diff --git a/coreutils/od_bloaty.c b/coreutils/od_bloaty.c index f47f84b54..1e252caf0 100644 --- a/coreutils/od_bloaty.c +++ b/coreutils/od_bloaty.c @@ -20,6 +20,7 @@ /* #include "libbb.h" - done in od.c */ +#include "common_bufsiz.h" #define assert(a) ((void)0) @@ -214,7 +215,7 @@ struct globals { #if !ENABLE_LONG_OPTS enum { G_pseudo_offset = 0 }; #endif -#define G (*(struct globals*)&bb_common_bufsiz1) +#define G (*(struct globals*)bb_common_bufsiz1) #define INIT_G() do { \ BUILD_BUG_ON(sizeof(G) > COMMON_BUFSIZE); \ G.bytes_per_block = 32; \ diff --git a/coreutils/split.c b/coreutils/split.c index 1e1673efb..b2da74e27 100644 --- a/coreutils/split.c +++ b/coreutils/split.c @@ -22,6 +22,7 @@ //usage: "$ cat TODO | split -a 2 -l 2 TODO_\n" #include "libbb.h" +#include "common_bufsiz.h" #if ENABLE_FEATURE_SPLIT_FANCY static const struct suffix_mult split_suffixes[] = { diff --git a/coreutils/stat.c b/coreutils/stat.c index 1a490fef7..78df9c948 100644 --- a/coreutils/stat.c +++ b/coreutils/stat.c @@ -103,6 +103,7 @@ //usage: ) #include "libbb.h" +#include "common_bufsiz.h" enum { OPT_TERSE = (1 << 0), @@ -157,9 +158,10 @@ static const char *human_time(time_t t) /* coreutils 6.3 compat: */ /*static char buf[sizeof("YYYY-MM-DD HH:MM:SS.000000000")] ALIGN1;*/ -#define buf bb_common_bufsiz1 +#define buf bb_common_bufsiz1 +#define sizeof_buf COMMON_BUFSIZE - strcpy(strftime_YYYYMMDDHHMMSS(buf, sizeof(buf), &t), ".000000000"); + strcpy(strftime_YYYYMMDDHHMMSS(buf, sizeof_buf, &t), ".000000000"); return buf; #undef buf } diff --git a/coreutils/stty.c b/coreutils/stty.c index b63b0b91a..0e32fc898 100644 --- a/coreutils/stty.c +++ b/coreutils/stty.c @@ -32,6 +32,7 @@ //usage: "\n [SETTING] See manpage" #include "libbb.h" +#include "common_bufsiz.h" #ifndef _POSIX_VDISABLE # define _POSIX_VDISABLE ((unsigned char) 0) @@ -775,7 +776,7 @@ struct globals { unsigned current_col; char buf[10]; } FIX_ALIASING; -#define G (*(struct globals*)&bb_common_bufsiz1) +#define G (*(struct globals*)bb_common_bufsiz1) #define INIT_G() do { \ G.device_name = bb_msg_standard_input; \ G.max_col = 80; \ diff --git a/coreutils/sum.c b/coreutils/sum.c index deb068e10..cc6677221 100644 --- a/coreutils/sum.c +++ b/coreutils/sum.c @@ -21,6 +21,7 @@ //usage: "\n -s Use System V sum algorithm (512byte blocks)" #include "libbb.h" +#include "common_bufsiz.h" enum { SUM_BSD, PRINT_NAME, SUM_SYSV }; @@ -41,7 +42,7 @@ static unsigned sum_file(const char *file, unsigned type) return 0; while (1) { - size_t bytes_read = safe_read(fd, buf, BUFSIZ); + size_t bytes_read = safe_read(fd, buf, COMMON_BUFSIZE); if ((ssize_t)bytes_read <= 0) { r = (fd && close(fd) != 0); diff --git a/coreutils/tail.c b/coreutils/tail.c index e352ab627..cdc9fb66a 100644 --- a/coreutils/tail.c +++ b/coreutils/tail.c @@ -49,12 +49,13 @@ //usage: "nameserver 10.0.0.1\n" #include "libbb.h" +#include "common_bufsiz.h" struct globals { bool from_top; bool exitcode; } FIX_ALIASING; -#define G (*(struct globals*)&bb_common_bufsiz1) +#define G (*(struct globals*)bb_common_bufsiz1) #define INIT_G() do { } while (0) static void tail_xprint_header(const char *fmt, const char *filename) diff --git a/coreutils/tee.c b/coreutils/tee.c index 48cc0508f..a0e177cbc 100644 --- a/coreutils/tee.c +++ b/coreutils/tee.c @@ -23,6 +23,7 @@ //usage: "Hello\n" #include "libbb.h" +#include "common_bufsiz.h" int tee_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; int tee_main(int argc, char **argv) @@ -36,7 +37,8 @@ int tee_main(int argc, char **argv) //TODO: make unconditional #if ENABLE_FEATURE_TEE_USE_BLOCK_IO ssize_t c; -# define buf bb_common_bufsiz1 +# define buf bb_common_bufsiz1 +# define sizeof_buf COMMON_BUFSIZE #else int c; #endif @@ -79,7 +81,7 @@ int tee_main(int argc, char **argv) /* names[0] will be filled later */ #if ENABLE_FEATURE_TEE_USE_BLOCK_IO - while ((c = safe_read(STDIN_FILENO, buf, sizeof(buf))) > 0) { + while ((c = safe_read(STDIN_FILENO, buf, sizeof_buf)) > 0) { fp = files; do fwrite(buf, 1, c, *fp); diff --git a/debianutils/run_parts.c b/debianutils/run_parts.c index 13617c6e1..a5e53576c 100644 --- a/debianutils/run_parts.c +++ b/debianutils/run_parts.c @@ -89,13 +89,14 @@ //usage: "+ shutdown -h +4m" #include "libbb.h" +#include "common_bufsiz.h" struct globals { char **names; int cur; char *cmd[2 /* using 1 provokes compiler warning */]; } FIX_ALIASING; -#define G (*(struct globals*)&bb_common_bufsiz1) +#define G (*(struct globals*)bb_common_bufsiz1) #define names (G.names) #define cur (G.cur ) #define cmd (G.cmd ) diff --git a/debianutils/start_stop_daemon.c b/debianutils/start_stop_daemon.c index d7c730f45..6b8d53b13 100644 --- a/debianutils/start_stop_daemon.c +++ b/debianutils/start_stop_daemon.c @@ -153,6 +153,7 @@ Misc options: /* Override ENABLE_FEATURE_PIDFILE */ #define WANT_PIDFILE 1 #include "libbb.h" +#include "common_bufsiz.h" struct pid_list { struct pid_list *next; @@ -191,7 +192,7 @@ struct globals { int user_id; smallint signal_nr; } FIX_ALIASING; -#define G (*(struct globals*)&bb_common_bufsiz1) +#define G (*(struct globals*)bb_common_bufsiz1) #define userspec (G.userspec ) #define cmdname (G.cmdname ) #define execname (G.execname ) diff --git a/e2fsprogs/fsck.c b/e2fsprogs/fsck.c index 987d97528..b534568c2 100644 --- a/e2fsprogs/fsck.c +++ b/e2fsprogs/fsck.c @@ -60,6 +60,7 @@ //usage: "\n -t TYPE List of filesystem types to check" #include "libbb.h" +#include "common_bufsiz.h" /* "progress indicator" code is somewhat buggy and ext[23] specific. * We should be filesystem agnostic. IOW: there should be a well-defined @@ -169,7 +170,7 @@ struct globals { struct fs_info *filesys_last; struct fsck_instance *instance_list; } FIX_ALIASING; -#define G (*(struct globals*)&bb_common_bufsiz1) +#define G (*(struct globals*)bb_common_bufsiz1) #define INIT_G() do { \ BUILD_BUG_ON(sizeof(G) > COMMON_BUFSIZE); \ } while (0) diff --git a/editors/diff.c b/editors/diff.c index a892cfdf2..3c8e9074a 100644 --- a/editors/diff.c +++ b/editors/diff.c @@ -125,6 +125,7 @@ //usage: "\n -w Ignore all whitespace" #include "libbb.h" +#include "common_bufsiz.h" #if 0 # define dbg_error_msg(...) bb_error_msg(__VA_ARGS__) diff --git a/editors/ed.c b/editors/ed.c index a4c419099..8da7b1dd5 100644 --- a/editors/ed.c +++ b/editors/ed.c @@ -23,6 +23,7 @@ //usage:#define ed_full_usage "" #include "libbb.h" +#include "common_bufsiz.h" typedef struct LINE { struct LINE *next; @@ -32,11 +33,12 @@ typedef struct LINE { } LINE; -#define searchString bb_common_bufsiz1 +#define searchString bb_common_bufsiz1 +#define sizeof_searchString COMMON_BUFSIZE enum { - USERSIZE = sizeof(searchString) > 1024 ? 1024 - : sizeof(searchString) - 1, /* max line length typed in by user */ + USERSIZE = sizeof_searchString > 1024 ? 1024 + : sizeof_searchString - 1, /* max line length typed in by user */ INITBUF_SIZE = 1024, /* initial buffer size */ }; diff --git a/editors/sed.c b/editors/sed.c index 9c4c8e148..330190e78 100644 --- a/editors/sed.c +++ b/editors/sed.c @@ -86,6 +86,7 @@ //usage: "bar\n" #include "libbb.h" +#include "common_bufsiz.h" #include "xregex.h" #if 0 @@ -161,7 +162,7 @@ struct globals { int len; /* Space allocated */ } pipeline; } FIX_ALIASING; -#define G (*(struct globals*)&bb_common_bufsiz1) +#define G (*(struct globals*)bb_common_bufsiz1) #define INIT_G() do { \ BUILD_BUG_ON(sizeof(G) > COMMON_BUFSIZE); \ G.sed_cmd_tail = &G.sed_cmd_head; \ diff --git a/findutils/find.c b/findutils/find.c index a0d4853de..32d830337 100644 --- a/findutils/find.c +++ b/findutils/find.c @@ -342,6 +342,7 @@ #include #include "libbb.h" +#include "common_bufsiz.h" #if ENABLE_FEATURE_FIND_REGEX # include "xregex.h" #endif @@ -421,7 +422,7 @@ struct globals { recurse_flags_t recurse_flags; IF_FEATURE_FIND_EXEC_PLUS(unsigned max_argv_len;) } FIX_ALIASING; -#define G (*(struct globals*)&bb_common_bufsiz1) +#define G (*(struct globals*)bb_common_bufsiz1) #define INIT_G() do { \ BUILD_BUG_ON(sizeof(G) > COMMON_BUFSIZE); \ /* we have to zero it out because of NOEXEC */ \ diff --git a/findutils/grep.c b/findutils/grep.c index dece90c58..a669ac80b 100644 --- a/findutils/grep.c +++ b/findutils/grep.c @@ -58,6 +58,7 @@ //config: Print the specified number of context lines (-C). #include "libbb.h" +#include "common_bufsiz.h" #include "xregex.h" @@ -201,7 +202,7 @@ struct globals { llist_t *pattern_head; /* growable list of patterns to match */ const char *cur_file; /* the current file we are reading */ } FIX_ALIASING; -#define G (*(struct globals*)&bb_common_bufsiz1) +#define G (*(struct globals*)bb_common_bufsiz1) #define INIT_G() do { \ BUILD_BUG_ON(sizeof(G) > COMMON_BUFSIZE); \ } while (0) diff --git a/findutils/xargs.c b/findutils/xargs.c index 69f83b128..bfbd94960 100644 --- a/findutils/xargs.c +++ b/findutils/xargs.c @@ -66,6 +66,7 @@ //kbuild:lib-$(CONFIG_XARGS) += xargs.o #include "libbb.h" +#include "common_bufsiz.h" /* This is a NOEXEC applet. Be very careful! */ @@ -100,7 +101,7 @@ struct globals { const char *eof_str; int idx; } FIX_ALIASING; -#define G (*(struct globals*)&bb_common_bufsiz1) +#define G (*(struct globals*)bb_common_bufsiz1) #define INIT_G() do { \ G.eof_str = NULL; /* need to clear by hand because we are NOEXEC applet */ \ IF_FEATURE_XARGS_SUPPORT_REPL_STR(G.repl_str = "{}";) \ diff --git a/include/libbb.h b/include/libbb.h index 111dd66e0..fd40ef74c 100644 --- a/include/libbb.h +++ b/include/libbb.h @@ -1827,10 +1827,6 @@ extern const char bb_PATH_root_path[] ALIGN1; /* "PATH=/sbin:/usr/sbin:/bin:/usr extern const int const_int_0; //extern const int const_int_1; - -/* Providing hard guarantee on minimum size (think of BUFSIZ == 128) */ -enum { COMMON_BUFSIZE = (BUFSIZ >= 256*sizeof(void*) ? BUFSIZ+1 : 256*sizeof(void*)) }; -extern char bb_common_bufsiz1[COMMON_BUFSIZE]; /* This struct is deliberately not defined. */ /* See docs/keep_data_small.txt */ struct globals; diff --git a/init/bootchartd.c b/init/bootchartd.c index c7388c99e..5101b28ae 100644 --- a/init/bootchartd.c +++ b/init/bootchartd.c @@ -47,6 +47,7 @@ //config: and /etc/bootchartd.conf files. #include "libbb.h" +#include "common_bufsiz.h" /* After libbb.h, since it needs sys/types.h on some systems */ #include @@ -115,7 +116,7 @@ struct globals { char jiffy_line[COMMON_BUFSIZE]; } FIX_ALIASING; -#define G (*(struct globals*)&bb_common_bufsiz1) +#define G (*(struct globals*)bb_common_bufsiz1) #define INIT_G() do { } while (0) static void dump_file(FILE *fp, const char *filename) diff --git a/libbb/common_bufsiz.c b/libbb/common_bufsiz.c new file mode 100644 index 000000000..c16c361c9 --- /dev/null +++ b/libbb/common_bufsiz.c @@ -0,0 +1,74 @@ +/* vi: set sw=4 ts=4: */ +/* + * Utility routines. + * + * Copyright (C) 2016 Denys Vlasenko + * + * Licensed under GPLv2, see file LICENSE in this source tree. + */ +//config:config FEATURE_USE_BSS_TAIL +//config: bool "Use the end of BSS page" +//config: default n +//config: help +//config: Attempt to reclaim a small unused part of BSS. +//config: +//config: Executables have the following parts: +//config: = read-only executable code and constants, also known as "text" +//config: = read-write data +//config: = non-initialized (zeroed on demand) data, also known as "bss" +//config: +//config: At link time, "text" is padded to a full page. At runtime, all "text" +//config: pages are mapped RO and executable. +//config: "Data" starts on the next page boundary, but is not padded +//config: to a full page at the end. "Bss" starts wherever "data" ends. +//config: At runtime, "data" pages are mapped RW and they are file-backed +//config: (this includes a small portion of "bss" which may live in the last +//config: partial page of "data"). +//config: Pages which are fully in "bss" are mapped to anonymous memory. +//config: +//config: "Bss" end is usually not page-aligned. There is an unused space +//config: in the last page. Linker marks its start with the "_end" symbol. +//config: +//config: This option will attempt to use that space for bb_common_bufsiz1[] +//config: array. If it fits after _end, it will be used, and COMMON_BUFSIZE +//config: will be enlarged from its guaranteed minimum size of 1 kbyte. +//config: This may require recompilation a second time, since value of _end +//config: is known only after final link. +//config: +//config: If you are getting a build error like this: +//config: appletlib.c:(.text.main+0xd): undefined reference to '_end' +//config: disable this option. + +//kbuild:lib-y += common_bufsiz.o + +#include "libbb.h" +#include "common_bufsiz.h" + +#if !ENABLE_FEATURE_USE_BSS_TAIL + +/* We use it for "global" data via *(struct global*)bb_common_bufsiz1. + * Since gcc insists on aligning struct global's members, it would be a pity + * (and an alignment fault on some CPUs) to mess it up. */ +char bb_common_bufsiz1[COMMON_BUFSIZE] ALIGNED(sizeof(long long)); + +#else + +# ifndef setup_common_bufsiz +/* + * It is not a "((void)0)" macro. It means we have to provide this function. + */ +char* bb_common_bufsiz1; +char* setup_common_bufsiz(void) +{ + if (!bb_common_bufsiz1) + bb_common_bufsiz1 = xzalloc(COMMON_BUFSIZE); + return bb_common_bufsiz1; +} +# else +# ifndef bb_common_bufsiz1 + /* bb_common_bufsiz1[] is not aliased to _end[] */ +char bb_common_bufsiz1[COMMON_BUFSIZE] ALIGNED(sizeof(long long)); +# endif +# endif + +#endif diff --git a/libbb/messages.c b/libbb/messages.c index 23e440bcd..cb0836de8 100644 --- a/libbb/messages.c +++ b/libbb/messages.c @@ -59,8 +59,3 @@ const char bb_path_wtmp_file[] ALIGN1 = # error unknown path to wtmp file # endif #endif - -/* We use it for "global" data via *(struct global*)&bb_common_bufsiz1. - * Since gcc insists on aligning struct global's members, it would be a pity - * (and an alignment fault on some CPUs) to mess it up. */ -char bb_common_bufsiz1[COMMON_BUFSIZE] ALIGNED(sizeof(long long)); diff --git a/loginutils/login.c b/loginutils/login.c index 4ebc18502..ea7c5a23d 100644 --- a/loginutils/login.c +++ b/loginutils/login.c @@ -62,6 +62,7 @@ //usage: "\n -p Preserve environment" #include "libbb.h" +#include "common_bufsiz.h" #include #include @@ -138,7 +139,7 @@ enum { struct globals { struct termios tty_attrs; } FIX_ALIASING; -#define G (*(struct globals*)&bb_common_bufsiz1) +#define G (*(struct globals*)bb_common_bufsiz1) #define INIT_G() do { } while (0) diff --git a/miscutils/chat.c b/miscutils/chat.c index bd2abc24a..25850dd20 100644 --- a/miscutils/chat.c +++ b/miscutils/chat.c @@ -17,6 +17,7 @@ //usage: "chat '' ATZ OK ATD123456 CONNECT '' ogin: pppuser word: ppppass '~'" #include "libbb.h" +#include "common_bufsiz.h" // default timeout: 45 sec #define DEFAULT_CHAT_TIMEOUT 45*1000 diff --git a/miscutils/conspy.c b/miscutils/conspy.c index 1a46a4340..0d96a5f9a 100644 --- a/miscutils/conspy.c +++ b/miscutils/conspy.c @@ -42,6 +42,7 @@ //usage: "\n -y LINE Starting line" #include "libbb.h" +#include "common_bufsiz.h" #include #define ESC "\033" @@ -363,7 +364,8 @@ int conspy_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; int conspy_main(int argc UNUSED_PARAM, char **argv) { char tty_name[sizeof(DEV_TTY "NN")]; -#define keybuf bb_common_bufsiz1 +#define keybuf bb_common_bufsiz1 +#define sizeof_keybuf COMMON_BUFSIZE struct termios termbuf; unsigned opts; unsigned ttynum; @@ -513,7 +515,7 @@ int conspy_main(int argc UNUSED_PARAM, char **argv) default: // Read the keys pressed k = keybuf + G.key_count; - bytes_read = read(G.kbd_fd, k, sizeof(keybuf) - G.key_count); + bytes_read = read(G.kbd_fd, k, sizeof_keybuf - G.key_count); if (bytes_read < 0) goto abort; diff --git a/miscutils/crond.c b/miscutils/crond.c index eb327f855..8536d43c5 100644 --- a/miscutils/crond.c +++ b/miscutils/crond.c @@ -60,6 +60,7 @@ //usage: "\n -c DIR Cron dir. Default:"CONFIG_FEATURE_CROND_DIR"/crontabs" #include "libbb.h" +#include "common_bufsiz.h" #include /* glibc frees previous setenv'ed value when we do next setenv() @@ -140,7 +141,7 @@ struct globals { char *env_var_logname; #endif } FIX_ALIASING; -#define G (*(struct globals*)&bb_common_bufsiz1) +#define G (*(struct globals*)bb_common_bufsiz1) #define INIT_G() do { \ G.log_level = 8; \ G.crontab_dir_name = CRONTABS; \ diff --git a/miscutils/dc.c b/miscutils/dc.c index 9c74172ba..3fbb89f5b 100644 --- a/miscutils/dc.c +++ b/miscutils/dc.c @@ -4,6 +4,7 @@ */ #include "libbb.h" +#include "common_bufsiz.h" #include //usage:#define dc_trivial_usage @@ -47,7 +48,7 @@ struct globals { double stack[1]; } FIX_ALIASING; enum { STACK_SIZE = (COMMON_BUFSIZE - offsetof(struct globals, stack)) / sizeof(double) }; -#define G (*(struct globals*)&bb_common_bufsiz1) +#define G (*(struct globals*)bb_common_bufsiz1) #define pointer (G.pointer ) #define base (G.base ) #define stack (G.stack ) diff --git a/miscutils/fbsplash.c b/miscutils/fbsplash.c index 9557c41db..b26ad2c15 100644 --- a/miscutils/fbsplash.c +++ b/miscutils/fbsplash.c @@ -34,6 +34,7 @@ //usage: "\n commands: 'NN' (% for progress bar) or 'exit'" #include "libbb.h" +#include "common_bufsiz.h" #include /* If you want logging messages on /tmp/fbsplash.log... */ @@ -372,11 +373,12 @@ static void fb_drawimage(void) * - A raster of Width * Height pixels in triplets of rgb * in pure binary by 1 or 2 bytes. (we support only 1 byte) */ -#define concat_buf bb_common_bufsiz1 +#define concat_buf bb_common_bufsiz1 +#define sizeof_concat_buf COMMON_BUFSIZE read_ptr = concat_buf; while (1) { int w, h, max_color_val; - int rem = concat_buf + sizeof(concat_buf) - read_ptr; + int rem = concat_buf + sizeof_concat_buf - read_ptr; if (rem < 2 || fgets(read_ptr, rem, theme_file) == NULL ) { diff --git a/miscutils/hdparm.c b/miscutils/hdparm.c index 8e201ac35..9e141de2f 100644 --- a/miscutils/hdparm.c +++ b/miscutils/hdparm.c @@ -63,6 +63,7 @@ //usage: "\n -z Reread partition table" #include "libbb.h" +#include "common_bufsiz.h" /* must be _after_ libbb.h: */ #include #include @@ -367,7 +368,7 @@ struct globals { unsigned char flushcache[4] = { WIN_FLUSHCACHE, 0, 0, 0 }; #endif } FIX_ALIASING; -#define G (*(struct globals*)&bb_common_bufsiz1) +#define G (*(struct globals*)bb_common_bufsiz1) #define get_identity (G.get_identity ) #define get_geom (G.get_geom ) #define do_flush (G.do_flush ) diff --git a/miscutils/i2c_tools.c b/miscutils/i2c_tools.c index aa1c7c5cc..57bb72ae7 100644 --- a/miscutils/i2c_tools.c +++ b/miscutils/i2c_tools.c @@ -60,6 +60,7 @@ */ #include "libbb.h" +#include "common_bufsiz.h" #include #include diff --git a/miscutils/inotifyd.c b/miscutils/inotifyd.c index 908d657fd..1d28e8f99 100644 --- a/miscutils/inotifyd.c +++ b/miscutils/inotifyd.c @@ -56,6 +56,7 @@ //usage: "\nWhen x event happens for all FILEs, inotifyd exits." #include "libbb.h" +#include "common_bufsiz.h" #include static const char mask_names[] ALIGN1 = @@ -162,8 +163,9 @@ int inotifyd_main(int argc, char **argv) // read out all pending events // (NB: len must be int, not ssize_t or long!) xioctl(pfd.fd, FIONREAD, &len); -#define eventbuf bb_common_bufsiz1 - ie = buf = (len <= sizeof(eventbuf)) ? eventbuf : xmalloc(len); +#define eventbuf bb_common_bufsiz1 +#define sizeof_eventbuf COMMON_BUFSIZE + ie = buf = (len <= sizeof_eventbuf) ? eventbuf : xmalloc(len); len = full_read(pfd.fd, buf, len); // process events. N.B. events may vary in length while (len > 0) { diff --git a/miscutils/less.c b/miscutils/less.c index ccdb15fdc..94ecf1686 100644 --- a/miscutils/less.c +++ b/miscutils/less.c @@ -127,6 +127,7 @@ #include /* sched_yield() */ #include "libbb.h" +#include "common_bufsiz.h" #if ENABLE_FEATURE_LESS_REGEXP #include "xregex.h" #endif @@ -439,7 +440,8 @@ static int at_end(void) */ static void read_lines(void) { -#define readbuf bb_common_bufsiz1 +#define readbuf bb_common_bufsiz1 +#define sizeof_readbuf COMMON_BUFSIZE char *current_line, *p; int w = width; char last_terminated = terminated; @@ -480,7 +482,7 @@ static void read_lines(void) time_t t; errno = 0; - eof_error = safe_read(STDIN_FILENO, readbuf, sizeof(readbuf)); + eof_error = safe_read(STDIN_FILENO, readbuf, sizeof_readbuf); if (errno != EAGAIN) break; t = time(NULL); diff --git a/miscutils/microcom.c b/miscutils/microcom.c index 5e29a1acd..5eb2e6743 100644 --- a/miscutils/microcom.c +++ b/miscutils/microcom.c @@ -19,6 +19,7 @@ //usage: "\n -X Disable special meaning of NUL and Ctrl-X from stdin" #include "libbb.h" +#include "common_bufsiz.h" // set raw tty mode static void xget1(int fd, struct termios *t, struct termios *oldt) @@ -155,10 +156,11 @@ int microcom_main(int argc UNUSED_PARAM, char **argv) skip_write: ; } if (pfd[0].revents) { -#define iobuf bb_common_bufsiz1 +#define iobuf bb_common_bufsiz1 +#define sizeof_iobuf COMMON_BUFSIZE ssize_t len; // read from device -> write to stdout - len = safe_read(sfd, iobuf, sizeof(iobuf)); + len = safe_read(sfd, iobuf, sizeof_iobuf); if (len > 0) full_write(STDOUT_FILENO, iobuf, len); else { diff --git a/networking/arp.c b/networking/arp.c index 0099aa534..5f7818663 100644 --- a/networking/arp.c +++ b/networking/arp.c @@ -32,6 +32,7 @@ //usage: "\n -H HWTYPE Hardware address type" #include "libbb.h" +#include "common_bufsiz.h" #include "inet_common.h" #include @@ -69,7 +70,7 @@ struct globals { const char *device; /* current device */ smallint hw_set; /* flag if hw-type was set (-H) */ } FIX_ALIASING; -#define G (*(struct globals*)&bb_common_bufsiz1) +#define G (*(struct globals*)bb_common_bufsiz1) #define ap (G.ap ) #define hw (G.hw ) #define device (G.device ) diff --git a/networking/arping.c b/networking/arping.c index ef205e5e6..52f5ba51f 100644 --- a/networking/arping.c +++ b/networking/arping.c @@ -28,6 +28,7 @@ #include #include "libbb.h" +#include "common_bufsiz.h" /* We don't expect to see 1000+ seconds delay, unsigned is enough */ #define MONOTONIC_US() ((unsigned)monotonic_us()) @@ -60,7 +61,7 @@ struct globals { unsigned brd_recv; unsigned req_recv; } FIX_ALIASING; -#define G (*(struct globals*)&bb_common_bufsiz1) +#define G (*(struct globals*)bb_common_bufsiz1) #define src (G.src ) #define dst (G.dst ) #define me (G.me ) diff --git a/networking/ftpd.c b/networking/ftpd.c index 8345ae67c..8553a28f5 100644 --- a/networking/ftpd.c +++ b/networking/ftpd.c @@ -29,6 +29,7 @@ //usage: "\n DIR Change root to this directory" #include "libbb.h" +#include "common_bufsiz.h" #include #include @@ -123,7 +124,7 @@ struct globals { char msg_ok [(sizeof("NNN " MSG_OK ) + 3) & 0xfffc]; char msg_err[(sizeof("NNN " MSG_ERR) + 3) & 0xfffc]; } FIX_ALIASING; -#define G (*(struct globals*)&bb_common_bufsiz1) +#define G (*(struct globals*)bb_common_bufsiz1) #define INIT_G() do { \ /* Moved to main */ \ /*strcpy(G.msg_ok + 4, MSG_OK );*/ \ diff --git a/networking/ftpgetput.c b/networking/ftpgetput.c index b398bc874..61bc45c4e 100644 --- a/networking/ftpgetput.c +++ b/networking/ftpgetput.c @@ -50,6 +50,7 @@ //usage: ) #include "libbb.h" +#include "common_bufsiz.h" struct globals { const char *user; @@ -60,7 +61,7 @@ struct globals { int do_continue; char buf[4]; /* actually [BUFSZ] */ } FIX_ALIASING; -#define G (*(struct globals*)&bb_common_bufsiz1) +#define G (*(struct globals*)bb_common_bufsiz1) enum { BUFSZ = COMMON_BUFSIZE - offsetof(struct globals, buf) }; #define user (G.user ) #define password (G.password ) diff --git a/networking/httpd.c b/networking/httpd.c index ed15fd883..ef90770ac 100644 --- a/networking/httpd.c +++ b/networking/httpd.c @@ -125,6 +125,7 @@ //usage: "\n -d STRING URL decode STRING" #include "libbb.h" +#include "common_bufsiz.h" #if ENABLE_PAM /* PAM may include . We may need to undefine bbox's stub define: */ # undef setlocale @@ -307,7 +308,8 @@ struct globals { Htaccess *script_i; /* config script interpreters */ #endif char *iobuf; /* [IOBUF_SIZE] */ -#define hdr_buf bb_common_bufsiz1 +#define hdr_buf bb_common_bufsiz1 +#define sizeof_hdr_buf COMMON_BUFSIZE char *hdr_ptr; int hdr_cnt; #if ENABLE_FEATURE_HTTPD_ERROR_PAGES @@ -1066,7 +1068,7 @@ static int get_line(void) alarm(HEADER_READ_TIMEOUT); while (1) { if (hdr_cnt <= 0) { - hdr_cnt = safe_read(STDIN_FILENO, hdr_buf, sizeof(hdr_buf)); + hdr_cnt = safe_read(STDIN_FILENO, hdr_buf, sizeof_hdr_buf); if (hdr_cnt <= 0) break; hdr_ptr = hdr_buf; @@ -1191,9 +1193,9 @@ static NOINLINE void cgi_io_loop_and_exit(int fromCgi_rd, int toCgi_wr, int post /* We expect data, prev data portion is eaten by CGI * and there *is* data to read from the peer * (POSTDATA) */ - //count = post_len > (int)sizeof(hdr_buf) ? (int)sizeof(hdr_buf) : post_len; + //count = post_len > (int)sizeof_hdr_buf ? (int)sizeof_hdr_buf : post_len; //count = safe_read(STDIN_FILENO, hdr_buf, count); - count = safe_read(STDIN_FILENO, hdr_buf, sizeof(hdr_buf)); + count = safe_read(STDIN_FILENO, hdr_buf, sizeof_hdr_buf); if (count > 0) { hdr_cnt = count; hdr_ptr = hdr_buf; diff --git a/networking/ifupdown.c b/networking/ifupdown.c index 2c6db926f..399ff6b5d 100644 --- a/networking/ifupdown.c +++ b/networking/ifupdown.c @@ -44,6 +44,7 @@ //usage: "\n -f Force de/configuration" #include "libbb.h" +#include "common_bufsiz.h" /* After libbb.h, since it needs sys/types.h on some systems */ #include #include @@ -129,7 +130,7 @@ struct globals { const char *startup_PATH; char *shell; } FIX_ALIASING; -#define G (*(struct globals*)&bb_common_bufsiz1) +#define G (*(struct globals*)bb_common_bufsiz1) #define INIT_G() do { } while (0) diff --git a/networking/inetd.c b/networking/inetd.c index 4f6673b12..aa35ffa2b 100644 --- a/networking/inetd.c +++ b/networking/inetd.c @@ -170,6 +170,7 @@ #include #include "libbb.h" +#include "common_bufsiz.h" #if ENABLE_FEATURE_INETD_RPC # if defined(__UCLIBC__) && ! defined(__UCLIBC_HAS_RPC__) @@ -327,7 +328,7 @@ struct globals { /* Used in next_line(), and as scratch read buffer */ char line[256]; /* _at least_ 256, see LINE_SIZE */ } FIX_ALIASING; -#define G (*(struct globals*)&bb_common_bufsiz1) +#define G (*(struct globals*)bb_common_bufsiz1) enum { LINE_SIZE = COMMON_BUFSIZE - offsetof(struct globals, line) }; #define rlim_ofile_cur (G.rlim_ofile_cur ) #define rlim_ofile (G.rlim_ofile ) diff --git a/networking/isrv_identd.c b/networking/isrv_identd.c index 252c8aba9..f63ed8ee4 100644 --- a/networking/isrv_identd.c +++ b/networking/isrv_identd.c @@ -18,6 +18,7 @@ //usage: "\n STRING Ident answer string (default: nobody)" #include "libbb.h" +#include "common_bufsiz.h" #include #include "isrv.h" @@ -28,7 +29,8 @@ typedef struct identd_buf_t { char buf[64 - sizeof(int)]; } identd_buf_t; -#define bogouser bb_common_bufsiz1 +#define bogouser bb_common_bufsiz1 +#define sizeof_bogouser COMMON_BUFSIZE static int new_peer(isrv_state_t *state, int fd) { @@ -118,7 +120,7 @@ int fakeidentd_main(int argc UNUSED_PARAM, char **argv) opt = getopt32(argv, "fiwb:", &bind_address); strcpy(bogouser, "nobody"); if (argv[optind]) - strncpy(bogouser, argv[optind], sizeof(bogouser) - 1); + strncpy(bogouser, argv[optind], sizeof_bogouser - 1); /* Daemonize if no -f and no -i and no -w */ if (!(opt & OPT_fiw)) diff --git a/networking/libiproute/ipaddress.c b/networking/libiproute/ipaddress.c index 5c975d8c5..2c0f514c7 100644 --- a/networking/libiproute/ipaddress.c +++ b/networking/libiproute/ipaddress.c @@ -13,6 +13,7 @@ #include #include "ip_common.h" /* #include "libbb.h" is inside */ +#include "common_bufsiz.h" #include "rt_names.h" #include "utils.h" @@ -39,7 +40,7 @@ struct filter_t { } FIX_ALIASING; typedef struct filter_t filter_t; -#define G_filter (*(filter_t*)&bb_common_bufsiz1) +#define G_filter (*(filter_t*)bb_common_bufsiz1) static void print_link_flags(unsigned flags, unsigned mdown) diff --git a/networking/libiproute/ipneigh.c b/networking/libiproute/ipneigh.c index 179505c2d..151d3d109 100644 --- a/networking/libiproute/ipneigh.c +++ b/networking/libiproute/ipneigh.c @@ -8,6 +8,7 @@ */ #include "ip_common.h" /* #include "libbb.h" is inside */ +#include "common_bufsiz.h" #include "rt_names.h" #include "utils.h" #include @@ -40,7 +41,7 @@ struct filter_t { } FIX_ALIASING; typedef struct filter_t filter_t; -#define G_filter (*(filter_t*)&bb_common_bufsiz1) +#define G_filter (*(filter_t*)bb_common_bufsiz1) static int flush_update(void) { diff --git a/networking/libiproute/iproute.c b/networking/libiproute/iproute.c index 82827488f..34d4f4758 100644 --- a/networking/libiproute/iproute.c +++ b/networking/libiproute/iproute.c @@ -11,6 +11,7 @@ */ #include "ip_common.h" /* #include "libbb.h" is inside */ +#include "common_bufsiz.h" #include "rt_names.h" #include "utils.h" @@ -43,7 +44,7 @@ struct filter_t { } FIX_ALIASING; typedef struct filter_t filter_t; -#define G_filter (*(filter_t*)&bb_common_bufsiz1) +#define G_filter (*(filter_t*)bb_common_bufsiz1) static int flush_update(void) { diff --git a/networking/nc.c b/networking/nc.c index 2f9e17466..50edee450 100644 --- a/networking/nc.c +++ b/networking/nc.c @@ -8,6 +8,7 @@ */ #include "libbb.h" +#include "common_bufsiz.h" //config:config NC //config: bool "nc" @@ -252,7 +253,7 @@ int nc_main(int argc, char **argv) fd = STDIN_FILENO; while (1) { if (FD_ISSET(fd, &testfds)) { - nread = safe_read(fd, iobuf, sizeof(iobuf)); + nread = safe_read(fd, iobuf, COMMON_BUFSIZE); if (fd == cfd) { if (nread < 1) exit(EXIT_SUCCESS); diff --git a/networking/ping.c b/networking/ping.c index 0eb1ae799..761660979 100644 --- a/networking/ping.c +++ b/networking/ping.c @@ -28,6 +28,7 @@ #include #include #include "libbb.h" +#include "common_bufsiz.h" #ifdef __BIONIC__ /* should be in netinet/ip_icmp.h */ @@ -186,7 +187,7 @@ struct globals { char *hostname; char packet[DEFDATALEN + MAXIPLEN + MAXICMPLEN]; } FIX_ALIASING; -#define G (*(struct globals*)&bb_common_bufsiz1) +#define G (*(struct globals*)bb_common_bufsiz1) #define INIT_G() do { } while (0) static void noresp(int ign UNUSED_PARAM) @@ -378,7 +379,7 @@ struct globals { } pingaddr; unsigned char rcvd_tbl[MAX_DUP_CHK / 8]; } FIX_ALIASING; -#define G (*(struct globals*)&bb_common_bufsiz1) +#define G (*(struct globals*)bb_common_bufsiz1) #define if_index (G.if_index ) #define source_lsa (G.source_lsa ) #define str_I (G.str_I ) diff --git a/networking/slattach.c b/networking/slattach.c index 14e0c1941..d9d8fe7b8 100644 --- a/networking/slattach.c +++ b/networking/slattach.c @@ -27,6 +27,7 @@ //usage: "\n -F Disable RTS/CTS flow control" #include "libbb.h" +#include "common_bufsiz.h" #include "libiproute/utils.h" /* invarg_1_to_2() */ struct globals { @@ -34,7 +35,7 @@ struct globals { int saved_disc; struct termios saved_state; } FIX_ALIASING; -#define G (*(struct globals*)&bb_common_bufsiz1) +#define G (*(struct globals*)bb_common_bufsiz1) #define handle (G.handle ) #define saved_disc (G.saved_disc ) #define saved_state (G.saved_state ) diff --git a/networking/tc.c b/networking/tc.c index c84c18a67..1372ca081 100644 --- a/networking/tc.c +++ b/networking/tc.c @@ -29,6 +29,7 @@ //usage: "filter show [ dev STRING ] [ root | parent CLASSID ]" #include "libbb.h" +#include "common_bufsiz.h" #include "libiproute/utils.h" #include "libiproute/ip_common.h" @@ -63,7 +64,7 @@ struct globals { uint32_t filter_prio; uint32_t filter_proto; } FIX_ALIASING; -#define G (*(struct globals*)&bb_common_bufsiz1) +#define G (*(struct globals*)bb_common_bufsiz1) #define filter_ifindex (G.filter_ifindex) #define filter_qdisc (G.filter_qdisc) #define filter_parent (G.filter_parent) diff --git a/networking/tcpudp.c b/networking/tcpudp.c index 3df6a98d8..624973042 100644 --- a/networking/tcpudp.c +++ b/networking/tcpudp.c @@ -67,6 +67,7 @@ //usage: "\n -v Verbose" #include "libbb.h" +#include "common_bufsiz.h" /* Wants etc, thus included after libbb.h: */ #ifdef __linux__ @@ -91,7 +92,7 @@ struct globals { char **env_cur; char *env_var[1]; /* actually bigger */ } FIX_ALIASING; -#define G (*(struct globals*)&bb_common_bufsiz1) +#define G (*(struct globals*)bb_common_bufsiz1) #define verbose (G.verbose ) #define max_per_host (G.max_per_host) #define cur_per_host (G.cur_per_host) diff --git a/networking/telnet.c b/networking/telnet.c index 944cf1bd6..2946bc831 100644 --- a/networking/telnet.c +++ b/networking/telnet.c @@ -39,6 +39,7 @@ #include #include #include "libbb.h" +#include "common_bufsiz.h" #ifdef __BIONIC__ /* should be in arpa/telnet.h */ @@ -108,7 +109,7 @@ struct globals { struct termios termios_def; struct termios termios_raw; } FIX_ALIASING; -#define G (*(struct globals*)&bb_common_bufsiz1) +#define G (*(struct globals*)bb_common_bufsiz1) #define INIT_G() do { \ BUILD_BUG_ON(sizeof(G) > COMMON_BUFSIZE); \ } while (0) diff --git a/networking/telnetd.c b/networking/telnetd.c index 25d05fe7a..13d5a8f64 100644 --- a/networking/telnetd.c +++ b/networking/telnetd.c @@ -44,6 +44,7 @@ #define DEBUG 0 #include "libbb.h" +#include "common_bufsiz.h" #include #if DEBUG @@ -82,7 +83,7 @@ struct globals { const char *issuefile; int maxfd; } FIX_ALIASING; -#define G (*(struct globals*)&bb_common_bufsiz1) +#define G (*(struct globals*)bb_common_bufsiz1) #define INIT_G() do { \ G.loginpath = "/bin/login"; \ G.issuefile = "/etc/issue.net"; \ diff --git a/networking/tftp.c b/networking/tftp.c index ad9308e52..8aeb79aca 100644 --- a/networking/tftp.c +++ b/networking/tftp.c @@ -51,6 +51,7 @@ //usage: "\n -l Log to syslog (inetd mode requires this)" #include "libbb.h" +#include "common_bufsiz.h" #include #if ENABLE_FEATURE_TFTP_GET || ENABLE_FEATURE_TFTP_PUT @@ -128,7 +129,7 @@ struct globals { bb_progress_t pmt; #endif } FIX_ALIASING; -#define G (*(struct globals*)&bb_common_bufsiz1) +#define G (*(struct globals*)bb_common_bufsiz1) #define INIT_G() do { \ BUILD_BUG_ON(sizeof(G) > COMMON_BUFSIZE); \ } while (0) @@ -757,7 +758,8 @@ int tftpd_main(int argc UNUSED_PARAM, char **argv) { len_and_sockaddr *our_lsa; len_and_sockaddr *peer_lsa; - char *local_file, *mode, *user_opt; + char *mode, *user_opt; + char *local_file = local_file; const char *error_msg; int opt, result, opcode; IF_FEATURE_TFTP_BLOCKSIZE(int blksize = TFTP_BLKSIZE_DEFAULT;) diff --git a/networking/udhcp/common.h b/networking/udhcp/common.h index 496ab11a1..a526494d7 100644 --- a/networking/udhcp/common.h +++ b/networking/udhcp/common.h @@ -9,6 +9,7 @@ #define UDHCP_COMMON_H 1 #include "libbb.h" +#include "common_bufsiz.h" #include #include diff --git a/networking/udhcp/dhcpd.h b/networking/udhcp/dhcpd.h index 183e7e24c..9dd5bef9e 100644 --- a/networking/udhcp/dhcpd.h +++ b/networking/udhcp/dhcpd.h @@ -57,7 +57,7 @@ struct server_config_t { struct static_lease *static_leases; /* List of ip/mac pairs to assign static leases */ } FIX_ALIASING; -#define server_config (*(struct server_config_t*)&bb_common_bufsiz1) +#define server_config (*(struct server_config_t*)bb_common_bufsiz1) /* client_config sits in 2nd half of bb_common_bufsiz1 */ #if ENABLE_FEATURE_UDHCP_PORT diff --git a/networking/udhcp/dhcprelay.c b/networking/udhcp/dhcprelay.c index f82ac05b4..1722a85de 100644 --- a/networking/udhcp/dhcprelay.c +++ b/networking/udhcp/dhcprelay.c @@ -33,7 +33,7 @@ struct xid_item { struct xid_item *next; } FIX_ALIASING; -#define dhcprelay_xid_list (*(struct xid_item*)&bb_common_bufsiz1) +#define dhcprelay_xid_list (*(struct xid_item*)bb_common_bufsiz1) static struct xid_item *xid_add(uint32_t xid, struct sockaddr_in *ip, int client) { diff --git a/networking/udhcp/files.c b/networking/udhcp/files.c index 7b57c6258..b22425352 100644 --- a/networking/udhcp/files.c +++ b/networking/udhcp/files.c @@ -57,33 +57,35 @@ static int FAST_FUNC read_staticlease(const char *const_line, void *arg) struct config_keyword { const char *keyword; int (*handler)(const char *line, void *var) FAST_FUNC; - void *var; + unsigned ofs; const char *def; }; +#define OFS(field) offsetof(struct server_config_t, field) + static const struct config_keyword keywords[] = { /* keyword handler variable address default */ - {"start" , udhcp_str2nip , &server_config.start_ip , "192.168.0.20"}, - {"end" , udhcp_str2nip , &server_config.end_ip , "192.168.0.254"}, - {"interface" , read_str , &server_config.interface , "eth0"}, + {"start" , udhcp_str2nip , OFS(start_ip ), "192.168.0.20"}, + {"end" , udhcp_str2nip , OFS(end_ip ), "192.168.0.254"}, + {"interface" , read_str , OFS(interface ), "eth0"}, /* Avoid "max_leases value not sane" warning by setting default * to default_end_ip - default_start_ip + 1: */ - {"max_leases" , read_u32 , &server_config.max_leases , "235"}, - {"auto_time" , read_u32 , &server_config.auto_time , "7200"}, - {"decline_time" , read_u32 , &server_config.decline_time , "3600"}, - {"conflict_time", read_u32 , &server_config.conflict_time, "3600"}, - {"offer_time" , read_u32 , &server_config.offer_time , "60"}, - {"min_lease" , read_u32 , &server_config.min_lease_sec, "60"}, - {"lease_file" , read_str , &server_config.lease_file , LEASES_FILE}, - {"pidfile" , read_str , &server_config.pidfile , "/var/run/udhcpd.pid"}, - {"siaddr" , udhcp_str2nip , &server_config.siaddr_nip , "0.0.0.0"}, + {"max_leases" , read_u32 , OFS(max_leases ), "235"}, + {"auto_time" , read_u32 , OFS(auto_time ), "7200"}, + {"decline_time" , read_u32 , OFS(decline_time ), "3600"}, + {"conflict_time", read_u32 , OFS(conflict_time), "3600"}, + {"offer_time" , read_u32 , OFS(offer_time ), "60"}, + {"min_lease" , read_u32 , OFS(min_lease_sec), "60"}, + {"lease_file" , read_str , OFS(lease_file ), LEASES_FILE}, + {"pidfile" , read_str , OFS(pidfile ), "/var/run/udhcpd.pid"}, + {"siaddr" , udhcp_str2nip , OFS(siaddr_nip ), "0.0.0.0"}, /* keywords with no defaults must be last! */ - {"option" , udhcp_str2optset, &server_config.options , ""}, - {"opt" , udhcp_str2optset, &server_config.options , ""}, - {"notify_file" , read_str , &server_config.notify_file , NULL}, - {"sname" , read_str , &server_config.sname , NULL}, - {"boot_file" , read_str , &server_config.boot_file , NULL}, - {"static_lease" , read_staticlease, &server_config.static_leases, ""}, + {"option" , udhcp_str2optset, OFS(options ), ""}, + {"opt" , udhcp_str2optset, OFS(options ), ""}, + {"notify_file" , read_str , OFS(notify_file ), NULL}, + {"sname" , read_str , OFS(sname ), NULL}, + {"boot_file" , read_str , OFS(boot_file ), NULL}, + {"static_lease" , read_staticlease, OFS(static_leases), ""}, }; enum { KWS_WITH_DEFAULTS = ARRAY_SIZE(keywords) - 6 }; @@ -95,17 +97,17 @@ void FAST_FUNC read_config(const char *file) char *token[2]; for (i = 0; i < KWS_WITH_DEFAULTS; i++) - keywords[i].handler(keywords[i].def, keywords[i].var); + keywords[i].handler(keywords[i].def, (char*)&server_config + keywords[i].ofs); parser = config_open(file); while (config_read(parser, token, 2, 2, "# \t", PARSE_NORMAL)) { for (k = keywords, i = 0; i < ARRAY_SIZE(keywords); k++, i++) { if (strcasecmp(token[0], k->keyword) == 0) { - if (!k->handler(token[1], k->var)) { + if (!k->handler(token[1], (char*)&server_config + k->ofs)) { bb_error_msg("can't parse line %u in %s", parser->lineno, file); /* reset back to the default value */ - k->handler(k->def, k->var); + k->handler(k->def, (char*)&server_config + k->ofs); } break; } diff --git a/networking/zcip.c b/networking/zcip.c index c93082619..79643458c 100644 --- a/networking/zcip.c +++ b/networking/zcip.c @@ -40,6 +40,7 @@ //usage: "\nexits only on I/O errors (link down etc)" #include "libbb.h" +#include "common_bufsiz.h" #include #include #include @@ -90,7 +91,7 @@ struct globals { struct ether_addr our_ethaddr; uint32_t localnet_ip; } FIX_ALIASING; -#define G (*(struct globals*)&bb_common_bufsiz1) +#define G (*(struct globals*)bb_common_bufsiz1) #define INIT_G() do { } while (0) diff --git a/procps/free.c b/procps/free.c index 0d023f740..9fde64b64 100644 --- a/procps/free.c +++ b/procps/free.c @@ -22,6 +22,7 @@ //usage: "Total: 386144 257128 129016\n" #include "libbb.h" +#include "common_bufsiz.h" #ifdef __linux__ # include #endif @@ -35,7 +36,7 @@ struct globals { # define G_unit_steps 10 #endif } FIX_ALIASING; -#define G (*(struct globals*)&bb_common_bufsiz1) +#define G (*(struct globals*)bb_common_bufsiz1) #define INIT_G() do { } while (0) diff --git a/procps/fuser.c b/procps/fuser.c index 05b52abb1..2cda0f9d7 100644 --- a/procps/fuser.c +++ b/procps/fuser.c @@ -18,6 +18,7 @@ //usage: "\n -SIGNAL Signal to send (default: KILL)" #include "libbb.h" +#include "common_bufsiz.h" #define MAX_LINE 255 @@ -43,7 +44,7 @@ struct globals { smallint kill_failed; int killsig; } FIX_ALIASING; -#define G (*(struct globals*)&bb_common_bufsiz1) +#define G (*(struct globals*)bb_common_bufsiz1) #define INIT_G() do { \ G.mypid = getpid(); \ G.killsig = SIGKILL; \ diff --git a/procps/nmeter.c b/procps/nmeter.c index 33de3790f..efa3d553d 100644 --- a/procps/nmeter.c +++ b/procps/nmeter.c @@ -53,6 +53,7 @@ // totalswap=134209536, freeswap=134209536, procs=157}) #include "libbb.h" +#include "common_bufsiz.h" typedef unsigned long long ullong; @@ -115,8 +116,8 @@ struct globals { G.deltanz = G.delta = 1000000; \ } while (0) -// We depend on this being a char[], not char* - we take sizeof() of it -#define outbuf bb_common_bufsiz1 +#define outbuf bb_common_bufsiz1 +#define sizeof_outbuf COMMON_BUFSIZE static inline void reset_outbuf(void) { @@ -140,7 +141,7 @@ static void print_outbuf(void) static void put(const char *s) { char *p = cur_outbuf; - int sz = outbuf + sizeof(outbuf) - p; + int sz = outbuf + sizeof_outbuf - p; while (*s && --sz >= 0) *p++ = *s++; cur_outbuf = p; @@ -148,7 +149,7 @@ static void put(const char *s) static void put_c(char c) { - if (cur_outbuf < outbuf + sizeof(outbuf)) + if (cur_outbuf < outbuf + sizeof_outbuf) *cur_outbuf++ = c; } diff --git a/procps/ps.c b/procps/ps.c index fbafa68a9..65d62e256 100644 --- a/procps/ps.c +++ b/procps/ps.c @@ -62,6 +62,7 @@ //usage: " 2990 andersen andersen R ps\n" #include "libbb.h" +#include "common_bufsiz.h" #ifdef __linux__ # include #endif @@ -144,7 +145,7 @@ struct globals { unsigned long seconds_since_boot; #endif } FIX_ALIASING; -#define G (*(struct globals*)&bb_common_bufsiz1) +#define G (*(struct globals*)bb_common_bufsiz1) #define out (G.out ) #define out_cnt (G.out_cnt ) #define print_header (G.print_header ) diff --git a/procps/top.c b/procps/top.c index ddf794d7d..1c42b249c 100644 --- a/procps/top.c +++ b/procps/top.c @@ -105,6 +105,7 @@ //config: Enable 's' in top (gives lots of memory info). #include "libbb.h" +#include "common_bufsiz.h" typedef struct top_status_t { @@ -183,7 +184,7 @@ struct globals { char line_buf[80]; }; //FIX_ALIASING; - large code growth enum { LINE_BUF_SIZE = COMMON_BUFSIZE - offsetof(struct globals, line_buf) }; -#define G (*(struct globals*)&bb_common_bufsiz1) +#define G (*(struct globals*)bb_common_bufsiz1) #define top (G.top ) #define ntop (G.ntop ) #define sort_field (G.sort_field ) diff --git a/runit/runsv.c b/runit/runsv.c index 4b18d12d5..8833f4c96 100644 --- a/runit/runsv.c +++ b/runit/runsv.c @@ -45,6 +45,7 @@ ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include #include "libbb.h" +#include "common_bufsiz.h" #include "runit_lib.h" #if ENABLE_MONOTONIC_SYSCALL @@ -105,7 +106,7 @@ struct globals { char *dir; struct svdir svd[2]; } FIX_ALIASING; -#define G (*(struct globals*)&bb_common_bufsiz1) +#define G (*(struct globals*)bb_common_bufsiz1) #define haslog (G.haslog ) #define sigterm (G.sigterm ) #define pidchanged (G.pidchanged ) diff --git a/runit/runsvdir.c b/runit/runsvdir.c index b3d9e7390..49c8f5b48 100644 --- a/runit/runsvdir.c +++ b/runit/runsvdir.c @@ -57,6 +57,7 @@ ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include #include "libbb.h" +#include "common_bufsiz.h" #include "runit_lib.h" #define MAXSERVICES 1000 @@ -84,7 +85,7 @@ struct globals { unsigned stamplog; #endif } FIX_ALIASING; -#define G (*(struct globals*)&bb_common_bufsiz1) +#define G (*(struct globals*)bb_common_bufsiz1) #define sv (G.sv ) #define svdir (G.svdir ) #define svnum (G.svnum ) diff --git a/runit/sv.c b/runit/sv.c index de8a0d8a4..e83a29781 100644 --- a/runit/sv.c +++ b/runit/sv.c @@ -189,6 +189,7 @@ Exit Codes #include #include "libbb.h" +#include "common_bufsiz.h" #include "runit_lib.h" struct globals { @@ -199,7 +200,7 @@ struct globals { uint64_t tstart, tnow; svstatus_t svstatus; } FIX_ALIASING; -#define G (*(struct globals*)&bb_common_bufsiz1) +#define G (*(struct globals*)bb_common_bufsiz1) #define acts (G.acts ) #define service (G.service ) #define rc (G.rc ) diff --git a/runit/svlogd.c b/runit/svlogd.c index dbe8df65c..09efdb695 100644 --- a/runit/svlogd.c +++ b/runit/svlogd.c @@ -155,6 +155,7 @@ log message, you can use a pattern like this instead #include #include "libbb.h" +#include "common_bufsiz.h" #include "runit_lib.h" #define LESS(a,b) ((int)((unsigned)(b) - (unsigned)(a)) > 0) @@ -1045,9 +1046,9 @@ int svlogd_main(int argc, char **argv) } if (opt & 2) if (!repl) repl = '_'; // -R if (opt & 4) { // -l - linemax = xatou_range(l, 0, BUFSIZ-26); + linemax = xatou_range(l, 0, COMMON_BUFSIZE-26); if (linemax == 0) - linemax = BUFSIZ-26; + linemax = COMMON_BUFSIZE-26; if (linemax < 256) linemax = 256; } diff --git a/scripts/generate_BUFSIZ.sh b/scripts/generate_BUFSIZ.sh new file mode 100755 index 000000000..afe9eee1e --- /dev/null +++ b/scripts/generate_BUFSIZ.sh @@ -0,0 +1,114 @@ +#!/bin/sh +# Called from top-level directory a-la +# +# scripts/generate_BUFSIZ.sh include/common_bufsiz.h + +. ./.config || exit 1 + +debug=false + +common_bufsiz_h=$1 + +test x"$NM" = x"" && NM="${CONFIG_CROSS_COMPILER_PREFIX}nm" +test x"$CC" = x"" && CC="${CONFIG_CROSS_COMPILER_PREFIX}gcc" + +regenerate() { + cat >"$1.$$" + test -f "$1" && diff "$1.$$" "$1" >/dev/null && rm "$1.$$" && return + mv "$1.$$" "$1" +} + +generate_std_and_exit() { + $debug && echo "Default: bb_common_bufsiz1[] in bss" + { + echo "enum { COMMON_BUFSIZE = 1024 };" + echo "extern char bb_common_bufsiz1[];" + echo "#define setup_common_bufsiz() ((void)0)" + } | regenerate "$common_bufsiz_h" + exit 0 +} + +# User does not want any funky stuff? +test x"$CONFIG_FEATURE_USE_BSS_TAIL" = x"y" || generate_std_and_exit + +test -f busybox_unstripped || { + # We did not try anything yet + $debug && echo "Will try to fit bb_common_bufsiz1[] into _end[]" + { + echo "enum { COMMON_BUFSIZE = 1024 };" + echo "extern char _end[]; /* linker-provided label */" + echo "#define bb_common_bufsiz1 _end" + echo "#define setup_common_bufsiz() ((void)0)" + } | regenerate "$common_bufsiz_h" + echo 1024 >"$common_bufsiz_h.BUFSIZE" + exit 0 +} + +# Get _end address +END=`$NM busybox_unstripped | grep ' . _end$'| cut -d' ' -f1` +test x"$END" = x"" && generate_std_and_exit +$debug && echo "END:0x$END $((0x$END))" +END=$((0x$END)) + +# Get PAGE_SIZE +echo "\ +#include +#if defined(PAGE_SIZE) && PAGE_SIZE > 0 +char page_size[PAGE_SIZE]; +#else +char page_size[1]; +#endif +" >page_size_$$.c +$CC -c "page_size_$$.c" || generate_std_and_exit +PAGE_SIZE=`$NM --size-sort "page_size_$$.o" | cut -d' ' -f1` +rm "page_size_$$.c" "page_size_$$.o" +test x"$PAGE_SIZE" = x"" && generate_std_and_exit +$debug && echo "PAGE_SIZE:0x$PAGE_SIZE $((0x$PAGE_SIZE))" +PAGE_SIZE=$((0x$PAGE_SIZE)) +test $PAGE_SIZE -lt 1024 && generate_std_and_exit + +# How much space between _end[] and next page? +PAGE_MASK=$((PAGE_SIZE-1)) +REM=$(( (-END) & PAGE_MASK )) +$debug && echo "REM:$REM" + +if test $REM -lt 1024; then + # _end[] has no enough space for bb_common_bufsiz1[], + # users will need to malloc it. + { + echo "enum { COMMON_BUFSIZE = 1024 };" + echo "extern char *bb_common_bufsiz1;" + echo "void setup_common_bufsiz(void);" + } | regenerate "$common_bufsiz_h" + # Check that we aren't left with a buggy binary: + if test -f "$common_bufsiz_h.BUFSIZE"; then + rm "$common_bufsiz_h.BUFSIZE" + echo "Warning! Space in _end[] is too small ($REM bytes)!" + echo "Rerun make to build a binary which doesn't use it!" + exit 1 + fi + exit 0 +fi + +# _end[] has REM bytes for bb_common_bufsiz1[] +OLD=1024 +test -f "$common_bufsiz_h.BUFSIZE" && OLD=`cat "$common_bufsiz_h.BUFSIZE"` +$debug && echo "OLD:$OLD" +{ +echo "enum { COMMON_BUFSIZE = $REM };" +echo "extern char _end[]; /* linker-provided label */" +echo "#define bb_common_bufsiz1 _end" +echo "#define setup_common_bufsiz() ((void)0)" +} | regenerate "$common_bufsiz_h" +echo $REM >"$common_bufsiz_h.BUFSIZE" + +# Check that code did not grow too much and thus _end[] did not shink: +if test $OLD -gt $REM; then + echo "Warning! Space in _end[] has decreased from $OLD to $REM bytes!" + echo "Rerun make!" + exit 1 +fi + +if test $OLD != $REM; then + echo "Space in _end[] is $REM bytes. Rerun make to use larger COMMON_BUFSIZE." +fi diff --git a/selinux/setfiles.c b/selinux/setfiles.c index de99dfe44..441345ae9 100644 --- a/selinux/setfiles.c +++ b/selinux/setfiles.c @@ -77,7 +77,7 @@ struct globals { int nerr; struct edir excludeArray[MAX_EXCLUDES]; } FIX_ALIASING; -#define G (*(struct globals*)&bb_common_bufsiz1) +#define G (*(struct globals*)bb_common_bufsiz1) void BUG_setfiles_globals_too_big(void); #define INIT_G() do { \ if (sizeof(G) > COMMON_BUFSIZE) \ diff --git a/sysklogd/klogd.c b/sysklogd/klogd.c index 03d65b37f..845c49a5e 100644 --- a/sysklogd/klogd.c +++ b/sysklogd/klogd.c @@ -58,6 +58,7 @@ //usage: "\n -n Run in foreground" #include "libbb.h" +#include "common_bufsiz.h" #include @@ -145,9 +146,10 @@ static void klogd_close(void) #endif -#define log_buffer bb_common_bufsiz1 +#define log_buffer bb_common_bufsiz1 +#define sizeof_log_buffer COMMON_BUFSIZE enum { - KLOGD_LOGBUF_SIZE = sizeof(log_buffer), + KLOGD_LOGBUF_SIZE = sizeof_log_buffer, OPT_LEVEL = (1 << 0), OPT_FOREGROUND = (1 << 1), }; diff --git a/sysklogd/logread.c b/sysklogd/logread.c index 781a603b2..ebd7f8b2c 100644 --- a/sysklogd/logread.c +++ b/sysklogd/logread.c @@ -42,6 +42,7 @@ //usage: "\n -F Same as -f, but dump buffer first" #include "libbb.h" +#include "common_bufsiz.h" #include #include #include @@ -67,7 +68,7 @@ struct globals { struct sembuf SMrdn[2]; // {1, 0}, {0, +1, SEM_UNDO} struct shbuf_ds *shbuf; } FIX_ALIASING; -#define G (*(struct globals*)&bb_common_bufsiz1) +#define G (*(struct globals*)bb_common_bufsiz1) #define SMrup (G.SMrup) #define SMrdn (G.SMrdn) #define shbuf (G.shbuf) diff --git a/sysklogd/syslogd_and_logger.c b/sysklogd/syslogd_and_logger.c index 0964f239c..6458a9332 100644 --- a/sysklogd/syslogd_and_logger.c +++ b/sysklogd/syslogd_and_logger.c @@ -8,6 +8,7 @@ */ #include "libbb.h" +#include "common_bufsiz.h" #define SYSLOG_NAMES #define SYSLOG_NAMES_CONST #include diff --git a/util-linux/mdev.c b/util-linux/mdev.c index 37fa56827..7473b1855 100644 --- a/util-linux/mdev.c +++ b/util-linux/mdev.c @@ -97,6 +97,7 @@ //usage: "If /dev/mdev.log file exists, debug log will be appended to it." #include "libbb.h" +#include "common_bufsiz.h" #include "xregex.h" /* "mdev -s" scans /sys/class/xxx, looking for directories which have dev @@ -285,7 +286,7 @@ struct globals { struct rule cur_rule; char timestr[sizeof("HH:MM:SS.123456")]; } FIX_ALIASING; -#define G (*(struct globals*)&bb_common_bufsiz1) +#define G (*(struct globals*)bb_common_bufsiz1) #define INIT_G() do { \ IF_NOT_FEATURE_MDEV_CONF(G.cur_rule.maj = -1;) \ IF_NOT_FEATURE_MDEV_CONF(G.cur_rule.mode = 0660;) \ diff --git a/util-linux/mkswap.c b/util-linux/mkswap.c index b5d2c49b6..f9451792b 100644 --- a/util-linux/mkswap.c +++ b/util-linux/mkswap.c @@ -13,6 +13,7 @@ //usage: "\n -L LBL Label" #include "libbb.h" +#include "common_bufsiz.h" #if ENABLE_SELINUX static void mkswap_selinux_setcontext(int fd, const char *path) diff --git a/util-linux/more.c b/util-linux/more.c index 359571397..58be3ac3b 100644 --- a/util-linux/more.c +++ b/util-linux/more.c @@ -23,6 +23,7 @@ //usage: "$ dmesg | more\n" #include "libbb.h" +#include "common_bufsiz.h" /* Support for FEATURE_USE_TERMIOS */ diff --git a/util-linux/mount.c b/util-linux/mount.c index c428f5827..e5c85feff 100644 --- a/util-linux/mount.c +++ b/util-linux/mount.c @@ -223,6 +223,7 @@ #define BB_MS_INVERTED_VALUE (1u << 31) #include "libbb.h" +#include "common_bufsiz.h" #if ENABLE_FEATURE_MOUNT_LABEL # include "volume_id.h" #else @@ -447,7 +448,7 @@ struct globals { char getmntent_buf[1]; } FIX_ALIASING; enum { GETMNTENT_BUFSIZE = COMMON_BUFSIZE - offsetof(struct globals, getmntent_buf) }; -#define G (*(struct globals*)&bb_common_bufsiz1) +#define G (*(struct globals*)bb_common_bufsiz1) #define nfs_mount_version (G.nfs_mount_version) #if ENABLE_FEATURE_MOUNT_VERBOSE #define verbose (G.verbose ) diff --git a/util-linux/script.c b/util-linux/script.c index abcd73bff..6195161bc 100644 --- a/util-linux/script.c +++ b/util-linux/script.c @@ -23,6 +23,7 @@ //usage: ) #include "libbb.h" +#include "common_bufsiz.h" int script_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; int script_main(int argc UNUSED_PARAM, char **argv) @@ -108,7 +109,8 @@ int script_main(int argc UNUSED_PARAM, char **argv) if (child_pid) { /* parent */ -#define buf bb_common_bufsiz1 +#define buf bb_common_bufsiz1 +#define sizeof_buf COMMON_BUFSIZE struct pollfd pfd[2]; int outfd, count, loop; double oldtime = ENABLE_SCRIPTREPLAY ? time(NULL) : 0; @@ -134,7 +136,7 @@ int script_main(int argc UNUSED_PARAM, char **argv) } if (pfd[0].revents) { errno = 0; - count = safe_read(pty, buf, sizeof(buf)); + count = safe_read(pty, buf, sizeof_buf); if (count <= 0 && errno != EAGAIN) { /* err/eof from pty: exit */ goto restore; @@ -157,7 +159,7 @@ int script_main(int argc UNUSED_PARAM, char **argv) } } if (pfd[1].revents) { - count = safe_read(STDIN_FILENO, buf, sizeof(buf)); + count = safe_read(STDIN_FILENO, buf, sizeof_buf); if (count <= 0) { /* err/eof from stdin: don't read stdin anymore */ pfd[1].revents = 0; @@ -176,7 +178,7 @@ int script_main(int argc UNUSED_PARAM, char **argv) * (util-linux's script doesn't do this. buggy :) */ loop = 999; /* pty is in O_NONBLOCK mode, we exit as soon as buffer is empty */ - while (--loop && (count = safe_read(pty, buf, sizeof(buf))) > 0) { + while (--loop && (count = safe_read(pty, buf, sizeof_buf)) > 0) { full_write(STDOUT_FILENO, buf, count); full_write(outfd, buf, count); } diff --git a/util-linux/swaponoff.c b/util-linux/swaponoff.c index c29dd3071..43228a6ba 100644 --- a/util-linux/swaponoff.c +++ b/util-linux/swaponoff.c @@ -28,6 +28,7 @@ //usage: "\n -a Stop swapping on all swap devices" #include "libbb.h" +#include "common_bufsiz.h" #include #ifndef __BIONIC__ # include @@ -62,7 +63,7 @@ struct globals { int flags; } FIX_ALIASING; -#define G (*(struct globals*)&bb_common_bufsiz1) +#define G (*(struct globals*)bb_common_bufsiz1) #define g_flags (G.flags) #define save_g_flags() int save_g_flags = g_flags #define restore_g_flags() g_flags = save_g_flags diff --git a/util-linux/uevent.c b/util-linux/uevent.c index 514a9e934..58668fa5d 100644 --- a/util-linux/uevent.c +++ b/util-linux/uevent.c @@ -25,11 +25,12 @@ //usage: "\n"" # uevent mdev & mdev -s" #include "libbb.h" +#include "common_bufsiz.h" #include #define BUFFER_SIZE 16*1024 -#define env ((char **)&bb_common_bufsiz1) +#define env ((char **)bb_common_bufsiz1) enum { MAX_ENV = COMMON_BUFSIZE / sizeof(env[0]) - 1, }; diff --git a/util-linux/umount.c b/util-linux/umount.c index 30bef1686..be0300394 100644 --- a/util-linux/umount.c +++ b/util-linux/umount.c @@ -34,6 +34,7 @@ # define MNT_DETACH 0x00000002 #endif #include "libbb.h" +#include "common_bufsiz.h" #if defined(__dietlibc__) // TODO: This does not belong here. @@ -102,7 +103,7 @@ int umount_main(int argc UNUSED_PARAM, char **argv) if (opt & OPT_ALL) bb_error_msg_and_die("can't open '%s'", bb_path_mtab_file); } else { - while (getmntent_r(fp, &me, bb_common_bufsiz1, sizeof(bb_common_bufsiz1))) { + while (getmntent_r(fp, &me, bb_common_bufsiz1, COMMON_BUFSIZE)) { /* Match fstype if passed */ if (!match_fstype(&me, fstype)) continue; From 47cfbf32fd66563f8c4e09ad6cced6abfbe2fad5 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Thu, 21 Apr 2016 18:18:48 +0200 Subject: [PATCH 226/260] *: add most of the required setup_common_bufsiz() calls Signed-off-by: Denys Vlasenko --- archival/cpio.c | 1 + archival/lzop.c | 2 +- archival/rpm.c | 2 +- console-tools/resize.c | 3 +++ coreutils/dd.c | 1 + coreutils/du.c | 2 +- coreutils/expr.c | 2 +- coreutils/ls.c | 1 + coreutils/od_bloaty.c | 1 + coreutils/tail.c | 2 +- debianutils/run_parts.c | 2 +- debianutils/start_stop_daemon.c | 1 + e2fsprogs/fsck.c | 1 + editors/sed.c | 1 + findutils/find.c | 1 + findutils/grep.c | 1 + findutils/xargs.c | 1 + init/bootchartd.c | 2 +- loginutils/login.c | 2 +- miscutils/crond.c | 1 + miscutils/dc.c | 1 + miscutils/hdparm.c | 1 + networking/arp.c | 1 + networking/arping.c | 1 + networking/ftpd.c | 1 + networking/ftpgetput.c | 1 + networking/ifupdown.c | 2 +- networking/inetd.c | 1 + networking/ping.c | 3 ++- networking/slattach.c | 2 +- networking/tc.c | 1 + networking/tcpudp.c | 1 + networking/telnet.c | 1 + networking/telnetd.c | 1 + networking/tftp.c | 1 + networking/udhcp/dhcprelay.c | 3 +++ networking/zcip.c | 2 +- procps/free.c | 2 +- procps/fuser.c | 1 + procps/ps.c | 2 +- procps/top.c | 1 + runit/runsv.c | 1 + runit/runsvdir.c | 2 +- runit/sv.c | 2 +- scripts/generate_BUFSIZ.sh | 2 ++ selinux/setfiles.c | 1 + sysklogd/logread.c | 1 + util-linux/mdev.c | 1 + util-linux/mkswap.c | 3 +++ util-linux/more.c | 2 +- util-linux/mount.c | 2 +- util-linux/swaponoff.c | 2 +- util-linux/uevent.c | 3 +++ 53 files changed, 63 insertions(+), 19 deletions(-) diff --git a/archival/cpio.c b/archival/cpio.c index a3036e1ab..3b1550720 100644 --- a/archival/cpio.c +++ b/archival/cpio.c @@ -174,6 +174,7 @@ struct globals { #define G (*(struct globals*)bb_common_bufsiz1) void BUG_cpio_globals_too_big(void); #define INIT_G() do { \ + setup_common_bufsiz(); \ G.owner_ugid.uid = -1L; \ G.owner_ugid.gid = -1L; \ } while (0) diff --git a/archival/lzop.c b/archival/lzop.c index 1371c9751..4afa21889 100644 --- a/archival/lzop.c +++ b/archival/lzop.c @@ -445,7 +445,7 @@ struct globals { chksum_t chksum_out; } FIX_ALIASING; #define G (*(struct globals*)bb_common_bufsiz1) -#define INIT_G() do { } while (0) +#define INIT_G() do { setup_common_bufsiz(); } while (0) //#define G (*ptr_to_globals) //#define INIT_G() do { // SET_PTR_TO_GLOBALS(xzalloc(sizeof(G))); diff --git a/archival/rpm.c b/archival/rpm.c index 079b7a95b..83160f975 100644 --- a/archival/rpm.c +++ b/archival/rpm.c @@ -95,7 +95,7 @@ struct globals { int tagcount; } FIX_ALIASING; #define G (*(struct globals*)bb_common_bufsiz1) -#define INIT_G() do { } while (0) +#define INIT_G() do { setup_common_bufsiz(); } while (0) static void extract_cpio(int fd, const char *source_rpm) { diff --git a/console-tools/resize.c b/console-tools/resize.c index ed80aa082..a3342a195 100644 --- a/console-tools/resize.c +++ b/console-tools/resize.c @@ -19,6 +19,7 @@ #define ESC "\033" #define old_termios_p ((struct termios*)bb_common_bufsiz1) +#define INIT_G() do { setup_common_bufsiz(); } while (0) static void onintr(int sig UNUSED_PARAM) @@ -34,6 +35,8 @@ int resize_main(int argc UNUSED_PARAM, char **argv UNUSED_PARAM) struct winsize w = { 0, 0, 0, 0 }; int ret; + INIT_G(); + /* We use _stderr_ in order to make resize usable * in shell backticks (those redirect stdout away from tty). * NB: other versions of resize open "/dev/tty" diff --git a/coreutils/dd.c b/coreutils/dd.c index a5b8882a0..4dc302926 100644 --- a/coreutils/dd.c +++ b/coreutils/dd.c @@ -111,6 +111,7 @@ struct globals { } FIX_ALIASING; #define G (*(struct globals*)bb_common_bufsiz1) #define INIT_G() do { \ + setup_common_bufsiz(); \ /* we have to zero it out because of NOEXEC */ \ memset(&G, 0, sizeof(G)); \ } while (0) diff --git a/coreutils/du.c b/coreutils/du.c index 3d6777670..1240bcbbc 100644 --- a/coreutils/du.c +++ b/coreutils/du.c @@ -87,7 +87,7 @@ struct globals { dev_t dir_dev; } FIX_ALIASING; #define G (*(struct globals*)bb_common_bufsiz1) -#define INIT_G() do { } while (0) +#define INIT_G() do { setup_common_bufsiz(); } while (0) static void print(unsigned long long size, const char *filename) diff --git a/coreutils/expr.c b/coreutils/expr.c index 59a66d9c5..ce6b2d189 100644 --- a/coreutils/expr.c +++ b/coreutils/expr.c @@ -101,7 +101,7 @@ struct globals { char **args; } FIX_ALIASING; #define G (*(struct globals*)bb_common_bufsiz1) -#define INIT_G() do { } while (0) +#define INIT_G() do { setup_common_bufsiz(); } while (0) /* forward declarations */ static VALUE *eval(void); diff --git a/coreutils/ls.c b/coreutils/ls.c index e8c3e0490..344b4e61e 100644 --- a/coreutils/ls.c +++ b/coreutils/ls.c @@ -368,6 +368,7 @@ struct globals { } FIX_ALIASING; #define G (*(struct globals*)bb_common_bufsiz1) #define INIT_G() do { \ + setup_common_bufsiz(); \ /* we have to zero it out because of NOEXEC */ \ memset(&G, 0, sizeof(G)); \ IF_FEATURE_AUTOWIDTH(G_terminal_width = TERMINAL_WIDTH;) \ diff --git a/coreutils/od_bloaty.c b/coreutils/od_bloaty.c index 1e252caf0..c8a654165 100644 --- a/coreutils/od_bloaty.c +++ b/coreutils/od_bloaty.c @@ -217,6 +217,7 @@ enum { G_pseudo_offset = 0 }; #endif #define G (*(struct globals*)bb_common_bufsiz1) #define INIT_G() do { \ + setup_common_bufsiz(); \ BUILD_BUG_ON(sizeof(G) > COMMON_BUFSIZE); \ G.bytes_per_block = 32; \ } while (0) diff --git a/coreutils/tail.c b/coreutils/tail.c index cdc9fb66a..39f87679e 100644 --- a/coreutils/tail.c +++ b/coreutils/tail.c @@ -56,7 +56,7 @@ struct globals { bool exitcode; } FIX_ALIASING; #define G (*(struct globals*)bb_common_bufsiz1) -#define INIT_G() do { } while (0) +#define INIT_G() do { setup_common_bufsiz(); } while (0) static void tail_xprint_header(const char *fmt, const char *filename) { diff --git a/debianutils/run_parts.c b/debianutils/run_parts.c index a5e53576c..c671b9252 100644 --- a/debianutils/run_parts.c +++ b/debianutils/run_parts.c @@ -100,7 +100,7 @@ struct globals { #define names (G.names) #define cur (G.cur ) #define cmd (G.cmd ) -#define INIT_G() do { } while (0) +#define INIT_G() do { setup_common_bufsiz(); } while (0) enum { NUM_CMD = (COMMON_BUFSIZE - sizeof(G)) / sizeof(cmd[0]) - 1 }; diff --git a/debianutils/start_stop_daemon.c b/debianutils/start_stop_daemon.c index 6b8d53b13..3625ffee8 100644 --- a/debianutils/start_stop_daemon.c +++ b/debianutils/start_stop_daemon.c @@ -200,6 +200,7 @@ struct globals { #define user_id (G.user_id ) #define signal_nr (G.signal_nr ) #define INIT_G() do { \ + setup_common_bufsiz(); \ user_id = -1; \ signal_nr = 15; \ } while (0) diff --git a/e2fsprogs/fsck.c b/e2fsprogs/fsck.c index b534568c2..59514a1a6 100644 --- a/e2fsprogs/fsck.c +++ b/e2fsprogs/fsck.c @@ -172,6 +172,7 @@ struct globals { } FIX_ALIASING; #define G (*(struct globals*)bb_common_bufsiz1) #define INIT_G() do { \ + setup_common_bufsiz(); \ BUILD_BUG_ON(sizeof(G) > COMMON_BUFSIZE); \ } while (0) diff --git a/editors/sed.c b/editors/sed.c index 330190e78..ed48de17f 100644 --- a/editors/sed.c +++ b/editors/sed.c @@ -164,6 +164,7 @@ struct globals { } FIX_ALIASING; #define G (*(struct globals*)bb_common_bufsiz1) #define INIT_G() do { \ + setup_common_bufsiz(); \ BUILD_BUG_ON(sizeof(G) > COMMON_BUFSIZE); \ G.sed_cmd_tail = &G.sed_cmd_head; \ } while (0) diff --git a/findutils/find.c b/findutils/find.c index 32d830337..d71c69782 100644 --- a/findutils/find.c +++ b/findutils/find.c @@ -424,6 +424,7 @@ struct globals { } FIX_ALIASING; #define G (*(struct globals*)bb_common_bufsiz1) #define INIT_G() do { \ + setup_common_bufsiz(); \ BUILD_BUG_ON(sizeof(G) > COMMON_BUFSIZE); \ /* we have to zero it out because of NOEXEC */ \ memset(&G, 0, sizeof(G)); \ diff --git a/findutils/grep.c b/findutils/grep.c index a669ac80b..b072cd441 100644 --- a/findutils/grep.c +++ b/findutils/grep.c @@ -204,6 +204,7 @@ struct globals { } FIX_ALIASING; #define G (*(struct globals*)bb_common_bufsiz1) #define INIT_G() do { \ + setup_common_bufsiz(); \ BUILD_BUG_ON(sizeof(G) > COMMON_BUFSIZE); \ } while (0) #define max_matches (G.max_matches ) diff --git a/findutils/xargs.c b/findutils/xargs.c index bfbd94960..ae01a49be 100644 --- a/findutils/xargs.c +++ b/findutils/xargs.c @@ -103,6 +103,7 @@ struct globals { } FIX_ALIASING; #define G (*(struct globals*)bb_common_bufsiz1) #define INIT_G() do { \ + setup_common_bufsiz(); \ G.eof_str = NULL; /* need to clear by hand because we are NOEXEC applet */ \ IF_FEATURE_XARGS_SUPPORT_REPL_STR(G.repl_str = "{}";) \ IF_FEATURE_XARGS_SUPPORT_REPL_STR(G.eol_ch = '\n';) \ diff --git a/init/bootchartd.c b/init/bootchartd.c index 5101b28ae..7f511e650 100644 --- a/init/bootchartd.c +++ b/init/bootchartd.c @@ -117,7 +117,7 @@ struct globals { char jiffy_line[COMMON_BUFSIZE]; } FIX_ALIASING; #define G (*(struct globals*)bb_common_bufsiz1) -#define INIT_G() do { } while (0) +#define INIT_G() do { setup_common_bufsiz(); } while (0) static void dump_file(FILE *fp, const char *filename) { diff --git a/loginutils/login.c b/loginutils/login.c index ea7c5a23d..94b6c45db 100644 --- a/loginutils/login.c +++ b/loginutils/login.c @@ -140,7 +140,7 @@ struct globals { struct termios tty_attrs; } FIX_ALIASING; #define G (*(struct globals*)bb_common_bufsiz1) -#define INIT_G() do { } while (0) +#define INIT_G() do { setup_common_bufsiz(); } while (0) #if ENABLE_FEATURE_NOLOGIN diff --git a/miscutils/crond.c b/miscutils/crond.c index 8536d43c5..f96c96ee7 100644 --- a/miscutils/crond.c +++ b/miscutils/crond.c @@ -143,6 +143,7 @@ struct globals { } FIX_ALIASING; #define G (*(struct globals*)bb_common_bufsiz1) #define INIT_G() do { \ + setup_common_bufsiz(); \ G.log_level = 8; \ G.crontab_dir_name = CRONTABS; \ } while (0) diff --git a/miscutils/dc.c b/miscutils/dc.c index 3fbb89f5b..4d92bc3d0 100644 --- a/miscutils/dc.c +++ b/miscutils/dc.c @@ -53,6 +53,7 @@ enum { STACK_SIZE = (COMMON_BUFSIZE - offsetof(struct globals, stack)) / sizeof( #define base (G.base ) #define stack (G.stack ) #define INIT_G() do { \ + setup_common_bufsiz(); \ base = 10; \ } while (0) diff --git a/miscutils/hdparm.c b/miscutils/hdparm.c index 9e141de2f..b4c5876d4 100644 --- a/miscutils/hdparm.c +++ b/miscutils/hdparm.c @@ -432,6 +432,7 @@ struct globals { #define hwif_ctrl (G.hwif_ctrl ) #define hwif_irq (G.hwif_irq ) #define INIT_G() do { \ + setup_common_bufsiz(); \ BUILD_BUG_ON(sizeof(G) > COMMON_BUFSIZE); \ } while (0) diff --git a/networking/arp.c b/networking/arp.c index 5f7818663..9381eb53a 100644 --- a/networking/arp.c +++ b/networking/arp.c @@ -76,6 +76,7 @@ struct globals { #define device (G.device ) #define hw_set (G.hw_set ) #define INIT_G() do { \ + setup_common_bufsiz(); \ device = ""; \ } while (0) diff --git a/networking/arping.c b/networking/arping.c index 52f5ba51f..6b0de4de2 100644 --- a/networking/arping.c +++ b/networking/arping.c @@ -77,6 +77,7 @@ struct globals { #define brd_recv (G.brd_recv ) #define req_recv (G.req_recv ) #define INIT_G() do { \ + setup_common_bufsiz(); \ count = -1; \ } while (0) diff --git a/networking/ftpd.c b/networking/ftpd.c index 8553a28f5..360d1e6be 100644 --- a/networking/ftpd.c +++ b/networking/ftpd.c @@ -126,6 +126,7 @@ struct globals { } FIX_ALIASING; #define G (*(struct globals*)bb_common_bufsiz1) #define INIT_G() do { \ + setup_common_bufsiz(); \ /* Moved to main */ \ /*strcpy(G.msg_ok + 4, MSG_OK );*/ \ /*strcpy(G.msg_err + 4, MSG_ERR);*/ \ diff --git a/networking/ftpgetput.c b/networking/ftpgetput.c index 61bc45c4e..91fb4569a 100644 --- a/networking/ftpgetput.c +++ b/networking/ftpgetput.c @@ -71,6 +71,7 @@ enum { BUFSZ = COMMON_BUFSIZE - offsetof(struct globals, buf) }; #define do_continue (G.do_continue ) #define buf (G.buf ) #define INIT_G() do { \ + setup_common_bufsiz(); \ BUILD_BUG_ON(sizeof(G) > COMMON_BUFSIZE); \ } while (0) diff --git a/networking/ifupdown.c b/networking/ifupdown.c index 399ff6b5d..25b04c9d7 100644 --- a/networking/ifupdown.c +++ b/networking/ifupdown.c @@ -131,7 +131,7 @@ struct globals { char *shell; } FIX_ALIASING; #define G (*(struct globals*)bb_common_bufsiz1) -#define INIT_G() do { } while (0) +#define INIT_G() do { setup_common_bufsiz(); } while (0) static const char keywords_up_down[] ALIGN1 = diff --git a/networking/inetd.c b/networking/inetd.c index aa35ffa2b..8d44b5198 100644 --- a/networking/inetd.c +++ b/networking/inetd.c @@ -350,6 +350,7 @@ enum { LINE_SIZE = COMMON_BUFSIZE - offsetof(struct globals, line) }; #define allsock (G.allsock ) #define line (G.line ) #define INIT_G() do { \ + setup_common_bufsiz(); \ BUILD_BUG_ON(sizeof(G) > COMMON_BUFSIZE); \ rlim_ofile_cur = OPEN_MAX; \ global_queuelen = 128; \ diff --git a/networking/ping.c b/networking/ping.c index 761660979..cfe682646 100644 --- a/networking/ping.c +++ b/networking/ping.c @@ -188,7 +188,7 @@ struct globals { char packet[DEFDATALEN + MAXIPLEN + MAXICMPLEN]; } FIX_ALIASING; #define G (*(struct globals*)bb_common_bufsiz1) -#define INIT_G() do { } while (0) +#define INIT_G() do { setup_common_bufsiz(); } while (0) static void noresp(int ign UNUSED_PARAM) { @@ -398,6 +398,7 @@ struct globals { #define pingaddr (G.pingaddr ) #define rcvd_tbl (G.rcvd_tbl ) #define INIT_G() do { \ + setup_common_bufsiz(); \ BUILD_BUG_ON(sizeof(G) > COMMON_BUFSIZE); \ datalen = DEFDATALEN; \ timeout = MAXWAIT; \ diff --git a/networking/slattach.c b/networking/slattach.c index d9d8fe7b8..2d1305e32 100644 --- a/networking/slattach.c +++ b/networking/slattach.c @@ -39,7 +39,7 @@ struct globals { #define handle (G.handle ) #define saved_disc (G.saved_disc ) #define saved_state (G.saved_state ) -#define INIT_G() do { } while (0) +#define INIT_G() do { setup_common_bufsiz(); } while (0) /* diff --git a/networking/tc.c b/networking/tc.c index 1372ca081..d0bcbdeaa 100644 --- a/networking/tc.c +++ b/networking/tc.c @@ -71,6 +71,7 @@ struct globals { #define filter_prio (G.filter_prio) #define filter_proto (G.filter_proto) #define INIT_G() do { \ + setup_common_bufsiz(); \ BUILD_BUG_ON(sizeof(G) > COMMON_BUFSIZE); \ } while (0) diff --git a/networking/tcpudp.c b/networking/tcpudp.c index 624973042..31bc70459 100644 --- a/networking/tcpudp.c +++ b/networking/tcpudp.c @@ -101,6 +101,7 @@ struct globals { #define env_cur (G.env_cur ) #define env_var (G.env_var ) #define INIT_G() do { \ + setup_common_bufsiz(); \ cmax = 30; \ env_cur = &env_var[0]; \ } while (0) diff --git a/networking/telnet.c b/networking/telnet.c index 2946bc831..d2daf5c8c 100644 --- a/networking/telnet.c +++ b/networking/telnet.c @@ -111,6 +111,7 @@ struct globals { } FIX_ALIASING; #define G (*(struct globals*)bb_common_bufsiz1) #define INIT_G() do { \ + setup_common_bufsiz(); \ BUILD_BUG_ON(sizeof(G) > COMMON_BUFSIZE); \ } while (0) diff --git a/networking/telnetd.c b/networking/telnetd.c index 13d5a8f64..13c36aa46 100644 --- a/networking/telnetd.c +++ b/networking/telnetd.c @@ -85,6 +85,7 @@ struct globals { } FIX_ALIASING; #define G (*(struct globals*)bb_common_bufsiz1) #define INIT_G() do { \ + setup_common_bufsiz(); \ G.loginpath = "/bin/login"; \ G.issuefile = "/etc/issue.net"; \ } while (0) diff --git a/networking/tftp.c b/networking/tftp.c index 8aeb79aca..e879c4674 100644 --- a/networking/tftp.c +++ b/networking/tftp.c @@ -131,6 +131,7 @@ struct globals { } FIX_ALIASING; #define G (*(struct globals*)bb_common_bufsiz1) #define INIT_G() do { \ + setup_common_bufsiz(); \ BUILD_BUG_ON(sizeof(G) > COMMON_BUFSIZE); \ } while (0) diff --git a/networking/udhcp/dhcprelay.c b/networking/udhcp/dhcprelay.c index 1722a85de..f52a0cf88 100644 --- a/networking/udhcp/dhcprelay.c +++ b/networking/udhcp/dhcprelay.c @@ -34,6 +34,7 @@ struct xid_item { } FIX_ALIASING; #define dhcprelay_xid_list (*(struct xid_item*)bb_common_bufsiz1) +#define INIT_G() do { setup_common_bufsiz(); } while (0) static struct xid_item *xid_add(uint32_t xid, struct sockaddr_in *ip, int client) { @@ -257,6 +258,8 @@ int dhcprelay_main(int argc, char **argv) int num_sockets, max_socket; uint32_t our_nip; + INIT_G(); + server_addr.sin_family = AF_INET; server_addr.sin_addr.s_addr = htonl(INADDR_BROADCAST); server_addr.sin_port = htons(SERVER_PORT); diff --git a/networking/zcip.c b/networking/zcip.c index 79643458c..47f3216a0 100644 --- a/networking/zcip.c +++ b/networking/zcip.c @@ -92,7 +92,7 @@ struct globals { uint32_t localnet_ip; } FIX_ALIASING; #define G (*(struct globals*)bb_common_bufsiz1) -#define INIT_G() do { } while (0) +#define INIT_G() do { setup_common_bufsiz(); } while (0) /** diff --git a/procps/free.c b/procps/free.c index 9fde64b64..fca9a2242 100644 --- a/procps/free.c +++ b/procps/free.c @@ -37,7 +37,7 @@ struct globals { #endif } FIX_ALIASING; #define G (*(struct globals*)bb_common_bufsiz1) -#define INIT_G() do { } while (0) +#define INIT_G() do { setup_common_bufsiz(); } while (0) static unsigned long long scale(unsigned long d) diff --git a/procps/fuser.c b/procps/fuser.c index 2cda0f9d7..6dac852ed 100644 --- a/procps/fuser.c +++ b/procps/fuser.c @@ -46,6 +46,7 @@ struct globals { } FIX_ALIASING; #define G (*(struct globals*)bb_common_bufsiz1) #define INIT_G() do { \ + setup_common_bufsiz(); \ G.mypid = getpid(); \ G.killsig = SIGKILL; \ } while (0) diff --git a/procps/ps.c b/procps/ps.c index 65d62e256..08dfce12e 100644 --- a/procps/ps.c +++ b/procps/ps.c @@ -153,7 +153,7 @@ struct globals { #define buffer (G.buffer ) #define terminal_width (G.terminal_width ) #define kernel_HZ (G.kernel_HZ ) -#define INIT_G() do { } while (0) +#define INIT_G() do { setup_common_bufsiz(); } while (0) #if ENABLE_FEATURE_PS_TIME /* for ELF executables, notes are pushed before environment and args */ diff --git a/procps/top.c b/procps/top.c index 1c42b249c..640bcdc6d 100644 --- a/procps/top.c +++ b/procps/top.c @@ -202,6 +202,7 @@ enum { LINE_BUF_SIZE = COMMON_BUFSIZE - offsetof(struct globals, line_buf) }; #define total_pcpu (G.total_pcpu ) #define line_buf (G.line_buf ) #define INIT_G() do { \ + setup_common_bufsiz(); \ BUILD_BUG_ON(sizeof(G) > COMMON_BUFSIZE); \ BUILD_BUG_ON(LINE_BUF_SIZE <= 80); \ } while (0) diff --git a/runit/runsv.c b/runit/runsv.c index 8833f4c96..e0e31508a 100644 --- a/runit/runsv.c +++ b/runit/runsv.c @@ -115,6 +115,7 @@ struct globals { #define dir (G.dir ) #define svd (G.svd ) #define INIT_G() do { \ + setup_common_bufsiz(); \ pidchanged = 1; \ } while (0) diff --git a/runit/runsvdir.c b/runit/runsvdir.c index 49c8f5b48..2b7927542 100644 --- a/runit/runsvdir.c +++ b/runit/runsvdir.c @@ -93,7 +93,7 @@ struct globals { #define logpipe (G.logpipe ) #define pfd (G.pfd ) #define stamplog (G.stamplog ) -#define INIT_G() do { } while (0) +#define INIT_G() do { setup_common_bufsiz(); } while (0) static void fatal2_cannot(const char *m1, const char *m2) { diff --git a/runit/sv.c b/runit/sv.c index e83a29781..2a256a6b4 100644 --- a/runit/sv.c +++ b/runit/sv.c @@ -207,7 +207,7 @@ struct globals { #define tstart (G.tstart ) #define tnow (G.tnow ) #define svstatus (G.svstatus ) -#define INIT_G() do { } while (0) +#define INIT_G() do { setup_common_bufsiz(); } while (0) #define str_equal(s,t) (!strcmp((s), (t))) diff --git a/scripts/generate_BUFSIZ.sh b/scripts/generate_BUFSIZ.sh index afe9eee1e..bb0738641 100755 --- a/scripts/generate_BUFSIZ.sh +++ b/scripts/generate_BUFSIZ.sh @@ -111,4 +111,6 @@ fi if test $OLD != $REM; then echo "Space in _end[] is $REM bytes. Rerun make to use larger COMMON_BUFSIZE." +else + echo "COMMON_BUFSIZE = $REM bytes" fi diff --git a/selinux/setfiles.c b/selinux/setfiles.c index 441345ae9..51a7e63bd 100644 --- a/selinux/setfiles.c +++ b/selinux/setfiles.c @@ -80,6 +80,7 @@ struct globals { #define G (*(struct globals*)bb_common_bufsiz1) void BUG_setfiles_globals_too_big(void); #define INIT_G() do { \ + setup_common_bufsiz(); \ if (sizeof(G) > COMMON_BUFSIZE) \ BUG_setfiles_globals_too_big(); \ /* memset(&G, 0, sizeof(G)); - already is */ \ diff --git a/sysklogd/logread.c b/sysklogd/logread.c index ebd7f8b2c..5b999730a 100644 --- a/sysklogd/logread.c +++ b/sysklogd/logread.c @@ -73,6 +73,7 @@ struct globals { #define SMrdn (G.SMrdn) #define shbuf (G.shbuf) #define INIT_G() do { \ + setup_common_bufsiz(); \ memcpy(SMrup, init_sem, sizeof(init_sem)); \ } while (0) diff --git a/util-linux/mdev.c b/util-linux/mdev.c index 7473b1855..37514eb54 100644 --- a/util-linux/mdev.c +++ b/util-linux/mdev.c @@ -288,6 +288,7 @@ struct globals { } FIX_ALIASING; #define G (*(struct globals*)bb_common_bufsiz1) #define INIT_G() do { \ + setup_common_bufsiz(); \ IF_NOT_FEATURE_MDEV_CONF(G.cur_rule.maj = -1;) \ IF_NOT_FEATURE_MDEV_CONF(G.cur_rule.mode = 0660;) \ } while (0) diff --git a/util-linux/mkswap.c b/util-linux/mkswap.c index f9451792b..dcb53f008 100644 --- a/util-linux/mkswap.c +++ b/util-linux/mkswap.c @@ -76,6 +76,7 @@ struct swap_header_v1 { #define NWORDS 129 #define hdr ((struct swap_header_v1*)bb_common_bufsiz1) +#define INIT_G() do { setup_common_bufsiz(); } while (0) struct BUG_sizes { char swap_header_v1_wrong[sizeof(*hdr) != (NWORDS * 4) ? -1 : 1]; @@ -93,6 +94,8 @@ int mkswap_main(int argc UNUSED_PARAM, char **argv) off_t len; const char *label = ""; + INIT_G(); + opt_complementary = "-1"; /* at least one param */ /* TODO: -p PAGESZ, -U UUID */ getopt32(argv, "L:", &label); diff --git a/util-linux/more.c b/util-linux/more.c index 58be3ac3b..95cbdd994 100644 --- a/util-linux/more.c +++ b/util-linux/more.c @@ -33,10 +33,10 @@ struct globals { struct termios new_settings; } FIX_ALIASING; #define G (*(struct globals*)bb_common_bufsiz1) -#define INIT_G() ((void)0) #define initial_settings (G.initial_settings) #define new_settings (G.new_settings ) #define cin_fileno (G.cin_fileno ) +#define INIT_G() do { setup_common_bufsiz(); } while (0) #define setTermSettings(fd, argp) \ do { \ diff --git a/util-linux/mount.c b/util-linux/mount.c index e5c85feff..244f4fa27 100644 --- a/util-linux/mount.c +++ b/util-linux/mount.c @@ -457,7 +457,7 @@ enum { GETMNTENT_BUFSIZE = COMMON_BUFSIZE - offsetof(struct globals, getmntent_b #endif #define fslist (G.fslist ) #define getmntent_buf (G.getmntent_buf ) -#define INIT_G() do { } while (0) +#define INIT_G() do { setup_common_bufsiz(); } while (0) #if ENABLE_FEATURE_MTAB_SUPPORT /* diff --git a/util-linux/swaponoff.c b/util-linux/swaponoff.c index 43228a6ba..6713852e5 100644 --- a/util-linux/swaponoff.c +++ b/util-linux/swaponoff.c @@ -72,7 +72,7 @@ struct globals { #define save_g_flags() ((void)0) #define restore_g_flags() ((void)0) #endif -#define INIT_G() do { } while (0) +#define INIT_G() do { setup_common_bufsiz(); } while (0) #define do_swapoff (applet_name[5] == 'f') diff --git a/util-linux/uevent.c b/util-linux/uevent.c index 58668fa5d..b98fe6160 100644 --- a/util-linux/uevent.c +++ b/util-linux/uevent.c @@ -31,6 +31,7 @@ #define BUFFER_SIZE 16*1024 #define env ((char **)bb_common_bufsiz1) +#define INIT_G() do { setup_common_bufsiz(); } while (0) enum { MAX_ENV = COMMON_BUFSIZE / sizeof(env[0]) - 1, }; @@ -46,6 +47,8 @@ int uevent_main(int argc UNUSED_PARAM, char **argv) struct sockaddr_nl sa; int fd; + INIT_G(); + argv++; // Subscribe for UEVENT kernel messages From 9de2e5a22213842da5b116723392de88de9ed419 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Thu, 21 Apr 2016 18:38:51 +0200 Subject: [PATCH 227/260] *: hopefully all setup_common_bufsiz() are in place Signed-off-by: Denys Vlasenko --- archival/tar.c | 2 ++ console-tools/dumpkmap.c | 1 + coreutils/catv.c | 4 +++- coreutils/cksum.c | 6 +++--- coreutils/date.c | 6 +++--- coreutils/split.c | 2 ++ coreutils/stat.c | 7 +++---- coreutils/sum.c | 4 +++- coreutils/tee.c | 6 +++--- editors/diff.c | 1 + editors/ed.c | 8 ++++---- miscutils/chat.c | 3 ++- miscutils/conspy.c | 7 ++++--- miscutils/fbsplash.c | 7 ++++--- miscutils/inotifyd.c | 6 +++--- miscutils/less.c | 7 ++++--- miscutils/microcom.c | 6 +++--- networking/httpd.c | 1 + networking/isrv_identd.c | 7 ++++--- networking/libiproute/ipaddress.c | 5 ++++- networking/libiproute/ipneigh.c | 3 +++ networking/libiproute/iproute.c | 3 +++ networking/nc.c | 3 ++- procps/nmeter.c | 9 ++++----- runit/svlogd.c | 4 ++-- sysklogd/klogd.c | 7 ++++--- sysklogd/logger.c | 2 ++ util-linux/script.c | 10 +++++----- util-linux/umount.c | 1 + 29 files changed, 83 insertions(+), 55 deletions(-) diff --git a/archival/tar.c b/archival/tar.c index caf4363de..346a9404e 100644 --- a/archival/tar.c +++ b/archival/tar.c @@ -162,6 +162,7 @@ #define block_buf bb_common_bufsiz1 +#define INIT_G() do { setup_common_bufsiz(); } while (0) #if ENABLE_FEATURE_TAR_CREATE @@ -964,6 +965,7 @@ int tar_main(int argc UNUSED_PARAM, char **argv) #if ENABLE_FEATURE_TAR_LONG_OPTIONS && ENABLE_FEATURE_TAR_FROM llist_t *excludes = NULL; #endif + INIT_G(); /* Initialise default values */ tar_handle = init_handle(); diff --git a/console-tools/dumpkmap.c b/console-tools/dumpkmap.c index 6412dffc8..b6fd466dc 100644 --- a/console-tools/dumpkmap.c +++ b/console-tools/dumpkmap.c @@ -38,6 +38,7 @@ int dumpkmap_main(int argc UNUSED_PARAM, char **argv) struct kbentry ke; int i, j, fd; #define flags bb_common_bufsiz1 + setup_common_bufsiz(); /* When user accidentally runs "dumpkmap FILE" * instead of "dumpkmap >FILE", we'd dump binary stuff to tty. diff --git a/coreutils/catv.c b/coreutils/catv.c index 801d2451d..0e71368a5 100644 --- a/coreutils/catv.c +++ b/coreutils/catv.c @@ -49,6 +49,9 @@ int catv_main(int argc UNUSED_PARAM, char **argv) /* Read from stdin if there's nothing else to do. */ if (!argv[0]) *--argv = (char*)"-"; + +#define read_buf bb_common_bufsiz1 + setup_common_bufsiz(); do { fd = open_or_warn_stdin(*argv); if (fd < 0) { @@ -58,7 +61,6 @@ int catv_main(int argc UNUSED_PARAM, char **argv) for (;;) { int i, res; -#define read_buf bb_common_bufsiz1 res = read(fd, read_buf, COMMON_BUFSIZE); if (res < 0) retval = EXIT_FAILURE; diff --git a/coreutils/cksum.c b/coreutils/cksum.c index d8351e7c6..8a8a39f68 100644 --- a/coreutils/cksum.c +++ b/coreutils/cksum.c @@ -33,6 +33,7 @@ int cksum_main(int argc UNUSED_PARAM, char **argv) argv++; #endif + setup_common_bufsiz(); do { int fd = open_or_warn_stdin(*argv ? *argv : bb_msg_standard_input); @@ -43,9 +44,8 @@ int cksum_main(int argc UNUSED_PARAM, char **argv) crc = 0; length = 0; -#define read_buf bb_common_bufsiz1 -#define sizeof_read_buf COMMON_BUFSIZE - while ((bytes_read = safe_read(fd, read_buf, sizeof_read_buf)) > 0) { +#define read_buf bb_common_bufsiz1 + while ((bytes_read = safe_read(fd, read_buf, COMMON_BUFSIZE)) > 0) { length += bytes_read; crc = crc32_block_endian1(crc, read_buf, bytes_read, crc32_table); } diff --git a/coreutils/date.c b/coreutils/date.c index 59b4b8f2a..ff3214d85 100644 --- a/coreutils/date.c +++ b/coreutils/date.c @@ -368,8 +368,8 @@ int date_main(int argc UNUSED_PARAM, char **argv) } #endif -#define date_buf bb_common_bufsiz1 -#define sizeof_date_buf COMMON_BUFSIZE +#define date_buf bb_common_bufsiz1 + setup_common_bufsiz(); if (*fmt_dt2str == '\0') { /* With no format string, just print a blank line */ date_buf[0] = '\0'; @@ -379,7 +379,7 @@ int date_main(int argc UNUSED_PARAM, char **argv) fmt_dt2str = (char*)"%Y.%m.%d-%H:%M:%S"; } /* Generate output string */ - strftime(date_buf, sizeof_date_buf, fmt_dt2str, &tm_time); + strftime(date_buf, COMMON_BUFSIZE, fmt_dt2str, &tm_time); } puts(date_buf); diff --git a/coreutils/split.c b/coreutils/split.c index b2da74e27..e67c3de66 100644 --- a/coreutils/split.c +++ b/coreutils/split.c @@ -79,6 +79,8 @@ int split_main(int argc UNUSED_PARAM, char **argv) ssize_t bytes_read, to_write; char *src; + setup_common_bufsiz(); + opt_complementary = "?2:a+"; /* max 2 args; -a N */ opt = getopt32(argv, "l:b:a:", &count_p, &count_p, &suffix_len); diff --git a/coreutils/stat.c b/coreutils/stat.c index 78df9c948..ddcfcf2d7 100644 --- a/coreutils/stat.c +++ b/coreutils/stat.c @@ -158,10 +158,9 @@ static const char *human_time(time_t t) /* coreutils 6.3 compat: */ /*static char buf[sizeof("YYYY-MM-DD HH:MM:SS.000000000")] ALIGN1;*/ -#define buf bb_common_bufsiz1 -#define sizeof_buf COMMON_BUFSIZE - - strcpy(strftime_YYYYMMDDHHMMSS(buf, sizeof_buf, &t), ".000000000"); +#define buf bb_common_bufsiz1 + setup_common_bufsiz(); + strcpy(strftime_YYYYMMDDHHMMSS(buf, COMMON_BUFSIZE, &t), ".000000000"); return buf; #undef buf } diff --git a/coreutils/sum.c b/coreutils/sum.c index cc6677221..ec9ed2a11 100644 --- a/coreutils/sum.c +++ b/coreutils/sum.c @@ -31,12 +31,14 @@ enum { SUM_BSD, PRINT_NAME, SUM_SYSV }; /* Return 1 if successful. */ static unsigned sum_file(const char *file, unsigned type) { -#define buf bb_common_bufsiz1 unsigned long long total_bytes = 0; int fd, r; /* The sum of all the input bytes, modulo (UINT_MAX + 1). */ unsigned s = 0; +#define buf bb_common_bufsiz1 + setup_common_bufsiz(); + fd = open_or_warn_stdin(file); if (fd == -1) return 0; diff --git a/coreutils/tee.c b/coreutils/tee.c index a0e177cbc..a68e9446f 100644 --- a/coreutils/tee.c +++ b/coreutils/tee.c @@ -37,8 +37,8 @@ int tee_main(int argc, char **argv) //TODO: make unconditional #if ENABLE_FEATURE_TEE_USE_BLOCK_IO ssize_t c; -# define buf bb_common_bufsiz1 -# define sizeof_buf COMMON_BUFSIZE +# define buf bb_common_bufsiz1 + setup_common_bufsiz(); #else int c; #endif @@ -81,7 +81,7 @@ int tee_main(int argc, char **argv) /* names[0] will be filled later */ #if ENABLE_FEATURE_TEE_USE_BLOCK_IO - while ((c = safe_read(STDIN_FILENO, buf, sizeof_buf)) > 0) { + while ((c = safe_read(STDIN_FILENO, buf, COMMON_BUFSIZE)) > 0) { fp = files; do fwrite(buf, 1, c, *fp); diff --git a/editors/diff.c b/editors/diff.c index 3c8e9074a..ff269360f 100644 --- a/editors/diff.c +++ b/editors/diff.c @@ -749,6 +749,7 @@ static int diffreg(char *file[2]) fp[i] = fdopen(fd, "r"); } + setup_common_bufsiz(); while (1) { const size_t sz = COMMON_BUFSIZE / 2; char *const buf0 = bb_common_bufsiz1; diff --git a/editors/ed.c b/editors/ed.c index 8da7b1dd5..c028b78cb 100644 --- a/editors/ed.c +++ b/editors/ed.c @@ -33,12 +33,11 @@ typedef struct LINE { } LINE; -#define searchString bb_common_bufsiz1 -#define sizeof_searchString COMMON_BUFSIZE +#define searchString bb_common_bufsiz1 enum { - USERSIZE = sizeof_searchString > 1024 ? 1024 - : sizeof_searchString - 1, /* max line length typed in by user */ + USERSIZE = COMMON_BUFSIZE > 1024 ? 1024 + : COMMON_BUFSIZE - 1, /* max line length typed in by user */ INITBUF_SIZE = 1024, /* initial buffer size */ }; @@ -68,6 +67,7 @@ struct globals { #define lines (G.lines ) #define marks (G.marks ) #define INIT_G() do { \ + setup_common_bufsiz(); \ SET_PTR_TO_GLOBALS(xzalloc(sizeof(G))); \ } while (0) diff --git a/miscutils/chat.c b/miscutils/chat.c index 25850dd20..6b429f2a6 100644 --- a/miscutils/chat.c +++ b/miscutils/chat.c @@ -286,9 +286,10 @@ int chat_main(int argc UNUSED_PARAM, char **argv) && poll(&pfd, 1, timeout) > 0 && (pfd.revents & POLLIN) ) { -#define buf bb_common_bufsiz1 llist_t *l; ssize_t delta; +#define buf bb_common_bufsiz1 + setup_common_bufsiz(); // read next char from device if (safe_read(STDIN_FILENO, buf+buf_len, 1) > 0) { diff --git a/miscutils/conspy.c b/miscutils/conspy.c index 0d96a5f9a..f6468c116 100644 --- a/miscutils/conspy.c +++ b/miscutils/conspy.c @@ -364,8 +364,6 @@ int conspy_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; int conspy_main(int argc UNUSED_PARAM, char **argv) { char tty_name[sizeof(DEV_TTY "NN")]; -#define keybuf bb_common_bufsiz1 -#define sizeof_keybuf COMMON_BUFSIZE struct termios termbuf; unsigned opts; unsigned ttynum; @@ -384,6 +382,9 @@ int conspy_main(int argc UNUSED_PARAM, char **argv) applet_long_options = getopt_longopts; #endif +#define keybuf bb_common_bufsiz1 + setup_common_bufsiz(); + INIT_G(); strcpy(G.vcsa_name, DEV_VCSA); @@ -515,7 +516,7 @@ int conspy_main(int argc UNUSED_PARAM, char **argv) default: // Read the keys pressed k = keybuf + G.key_count; - bytes_read = read(G.kbd_fd, k, sizeof_keybuf - G.key_count); + bytes_read = read(G.kbd_fd, k, COMMON_BUFSIZE - G.key_count); if (bytes_read < 0) goto abort; diff --git a/miscutils/fbsplash.c b/miscutils/fbsplash.c index b26ad2c15..3ddf8a242 100644 --- a/miscutils/fbsplash.c +++ b/miscutils/fbsplash.c @@ -373,12 +373,13 @@ static void fb_drawimage(void) * - A raster of Width * Height pixels in triplets of rgb * in pure binary by 1 or 2 bytes. (we support only 1 byte) */ -#define concat_buf bb_common_bufsiz1 -#define sizeof_concat_buf COMMON_BUFSIZE +#define concat_buf bb_common_bufsiz1 + setup_common_bufsiz(); + read_ptr = concat_buf; while (1) { int w, h, max_color_val; - int rem = concat_buf + sizeof_concat_buf - read_ptr; + int rem = concat_buf + COMMON_BUFSIZE - read_ptr; if (rem < 2 || fgets(read_ptr, rem, theme_file) == NULL ) { diff --git a/miscutils/inotifyd.c b/miscutils/inotifyd.c index 1d28e8f99..52db08ada 100644 --- a/miscutils/inotifyd.c +++ b/miscutils/inotifyd.c @@ -162,10 +162,10 @@ int inotifyd_main(int argc, char **argv) // read out all pending events // (NB: len must be int, not ssize_t or long!) +#define eventbuf bb_common_bufsiz1 + setup_common_bufsiz(); xioctl(pfd.fd, FIONREAD, &len); -#define eventbuf bb_common_bufsiz1 -#define sizeof_eventbuf COMMON_BUFSIZE - ie = buf = (len <= sizeof_eventbuf) ? eventbuf : xmalloc(len); + ie = buf = (len <= COMMON_BUFSIZE) ? eventbuf : xmalloc(len); len = full_read(pfd.fd, buf, len); // process events. N.B. events may vary in length while (len > 0) { diff --git a/miscutils/less.c b/miscutils/less.c index 94ecf1686..d7076dbbc 100644 --- a/miscutils/less.c +++ b/miscutils/less.c @@ -440,8 +440,6 @@ static int at_end(void) */ static void read_lines(void) { -#define readbuf bb_common_bufsiz1 -#define sizeof_readbuf COMMON_BUFSIZE char *current_line, *p; int w = width; char last_terminated = terminated; @@ -451,6 +449,9 @@ static void read_lines(void) unsigned old_max_fline = max_fline; #endif +#define readbuf bb_common_bufsiz1 + setup_common_bufsiz(); + /* (careful: max_fline can be -1) */ if (max_fline + 1 > MAXLINES) return; @@ -482,7 +483,7 @@ static void read_lines(void) time_t t; errno = 0; - eof_error = safe_read(STDIN_FILENO, readbuf, sizeof_readbuf); + eof_error = safe_read(STDIN_FILENO, readbuf, COMMON_BUFSIZE); if (errno != EAGAIN) break; t = time(NULL); diff --git a/miscutils/microcom.c b/miscutils/microcom.c index 5eb2e6743..d9e8f9187 100644 --- a/miscutils/microcom.c +++ b/miscutils/microcom.c @@ -156,11 +156,11 @@ int microcom_main(int argc UNUSED_PARAM, char **argv) skip_write: ; } if (pfd[0].revents) { -#define iobuf bb_common_bufsiz1 -#define sizeof_iobuf COMMON_BUFSIZE ssize_t len; +#define iobuf bb_common_bufsiz1 + setup_common_bufsiz(); // read from device -> write to stdout - len = safe_read(sfd, iobuf, sizeof_iobuf); + len = safe_read(sfd, iobuf, COMMON_BUFSIZE); if (len > 0) full_write(STDOUT_FILENO, iobuf, len); else { diff --git a/networking/httpd.c b/networking/httpd.c index ef90770ac..abe83a458 100644 --- a/networking/httpd.c +++ b/networking/httpd.c @@ -370,6 +370,7 @@ enum { # define content_gzip 0 #endif #define INIT_G() do { \ + setup_common_bufsiz(); \ SET_PTR_TO_GLOBALS(xzalloc(sizeof(G))); \ IF_FEATURE_HTTPD_BASIC_AUTH(g_realm = "Web Server Authentication";) \ IF_FEATURE_HTTPD_RANGES(range_start = -1;) \ diff --git a/networking/isrv_identd.c b/networking/isrv_identd.c index f63ed8ee4..8a15926e5 100644 --- a/networking/isrv_identd.c +++ b/networking/isrv_identd.c @@ -29,8 +29,7 @@ typedef struct identd_buf_t { char buf[64 - sizeof(int)]; } identd_buf_t; -#define bogouser bb_common_bufsiz1 -#define sizeof_bogouser COMMON_BUFSIZE +#define bogouser bb_common_bufsiz1 static int new_peer(isrv_state_t *state, int fd) { @@ -117,10 +116,12 @@ int fakeidentd_main(int argc UNUSED_PARAM, char **argv) unsigned opt; int fd; + setup_common_bufsiz(); + opt = getopt32(argv, "fiwb:", &bind_address); strcpy(bogouser, "nobody"); if (argv[optind]) - strncpy(bogouser, argv[optind], sizeof_bogouser - 1); + strncpy(bogouser, argv[optind], COMMON_BUFSIZE - 1); /* Daemonize if no -f and no -i and no -w */ if (!(opt & OPT_fiw)) diff --git a/networking/libiproute/ipaddress.c b/networking/libiproute/ipaddress.c index 2c0f514c7..d9e099607 100644 --- a/networking/libiproute/ipaddress.c +++ b/networking/libiproute/ipaddress.c @@ -41,7 +41,7 @@ struct filter_t { typedef struct filter_t filter_t; #define G_filter (*(filter_t*)bb_common_bufsiz1) - +#define INIT_G() do { setup_common_bufsiz(); } while (0) static void print_link_flags(unsigned flags, unsigned mdown) { @@ -745,6 +745,9 @@ int FAST_FUNC do_ipaddr(char **argv) /* 0 1 2 3 4 5 6 7 8 */ "add\0""change\0""chg\0""replace\0""delete\0""list\0""show\0""lst\0""flush\0"; int cmd = 2; + + INIT_G(); + if (*argv) { cmd = index_in_substrings(commands, *argv); if (cmd < 0) diff --git a/networking/libiproute/ipneigh.c b/networking/libiproute/ipneigh.c index 151d3d109..d2028b7b6 100644 --- a/networking/libiproute/ipneigh.c +++ b/networking/libiproute/ipneigh.c @@ -42,6 +42,7 @@ struct filter_t { typedef struct filter_t filter_t; #define G_filter (*(filter_t*)bb_common_bufsiz1) +#define INIT_G() do { setup_common_bufsiz(); } while (0) static int flush_update(void) { @@ -339,6 +340,8 @@ int FAST_FUNC do_ipneigh(char **argv) /*0-1*/ "show\0" "flush\0"; int command_num; + INIT_G(); + if (!*argv) return ipneigh_list_or_flush(argv, 0); diff --git a/networking/libiproute/iproute.c b/networking/libiproute/iproute.c index 34d4f4758..e674e9a0d 100644 --- a/networking/libiproute/iproute.c +++ b/networking/libiproute/iproute.c @@ -45,6 +45,7 @@ struct filter_t { typedef struct filter_t filter_t; #define G_filter (*(filter_t*)bb_common_bufsiz1) +#define INIT_G() do { setup_common_bufsiz(); } while (0) static int flush_update(void) { @@ -903,6 +904,8 @@ int FAST_FUNC do_iproute(char **argv) unsigned flags = 0; int cmd = RTM_NEWROUTE; + INIT_G(); + if (!*argv) return iproute_list_or_flush(argv, 0); diff --git a/networking/nc.c b/networking/nc.c index 50edee450..13a9b48a8 100644 --- a/networking/nc.c +++ b/networking/nc.c @@ -239,6 +239,8 @@ int nc_main(int argc, char **argv) FD_SET(cfd, &readfds); FD_SET(STDIN_FILENO, &readfds); +#define iobuf bb_common_bufsiz1 + setup_common_bufsiz(); for (;;) { int fd; int ofd; @@ -249,7 +251,6 @@ int nc_main(int argc, char **argv) if (select(cfd + 1, &testfds, NULL, NULL, NULL) < 0) bb_perror_msg_and_die("select"); -#define iobuf bb_common_bufsiz1 fd = STDIN_FILENO; while (1) { if (FD_ISSET(fd, &testfds)) { diff --git a/procps/nmeter.c b/procps/nmeter.c index efa3d553d..3eac2d3b2 100644 --- a/procps/nmeter.c +++ b/procps/nmeter.c @@ -109,16 +109,15 @@ struct globals { #define proc_meminfo (G.proc_meminfo ) #define proc_diskstats (G.proc_diskstats ) #define proc_sys_fs_filenr (G.proc_sys_fs_filenr) +#define outbuf bb_common_bufsiz1 #define INIT_G() do { \ + setup_common_bufsiz(); \ SET_PTR_TO_GLOBALS(xzalloc(sizeof(G))); \ cur_outbuf = outbuf; \ G.final_char = '\n'; \ G.deltanz = G.delta = 1000000; \ } while (0) -#define outbuf bb_common_bufsiz1 -#define sizeof_outbuf COMMON_BUFSIZE - static inline void reset_outbuf(void) { cur_outbuf = outbuf; @@ -141,7 +140,7 @@ static void print_outbuf(void) static void put(const char *s) { char *p = cur_outbuf; - int sz = outbuf + sizeof_outbuf - p; + int sz = outbuf + COMMON_BUFSIZE - p; while (*s && --sz >= 0) *p++ = *s++; cur_outbuf = p; @@ -149,7 +148,7 @@ static void put(const char *s) static void put_c(char c) { - if (cur_outbuf < outbuf + sizeof_outbuf) + if (cur_outbuf < outbuf + COMMON_BUFSIZE) *cur_outbuf++ = c; } diff --git a/runit/svlogd.c b/runit/svlogd.c index 09efdb695..7cae81cb2 100644 --- a/runit/svlogd.c +++ b/runit/svlogd.c @@ -234,7 +234,9 @@ struct globals { #define blocked_sigset (G.blocked_sigset) #define fl_flag_0 (G.fl_flag_0 ) #define dirn (G.dirn ) +#define line bb_common_bufsiz1 #define INIT_G() do { \ + setup_common_bufsiz(); \ SET_PTR_TO_GLOBALS(xzalloc(sizeof(G))); \ linemax = 1000; \ /*buflen = 1024;*/ \ @@ -242,8 +244,6 @@ struct globals { replace = ""; \ } while (0) -#define line bb_common_bufsiz1 - #define FATAL "fatal: " #define WARNING "warning: " diff --git a/sysklogd/klogd.c b/sysklogd/klogd.c index 845c49a5e..4db72110d 100644 --- a/sysklogd/klogd.c +++ b/sysklogd/klogd.c @@ -146,10 +146,9 @@ static void klogd_close(void) #endif -#define log_buffer bb_common_bufsiz1 -#define sizeof_log_buffer COMMON_BUFSIZE +#define log_buffer bb_common_bufsiz1 enum { - KLOGD_LOGBUF_SIZE = sizeof_log_buffer, + KLOGD_LOGBUF_SIZE = COMMON_BUFSIZE, OPT_LEVEL = (1 << 0), OPT_FOREGROUND = (1 << 1), }; @@ -175,6 +174,8 @@ int klogd_main(int argc UNUSED_PARAM, char **argv) int opt; int used; + setup_common_bufsiz(); + opt = getopt32(argv, "c:n", &opt_c); if (opt & OPT_LEVEL) { /* Valid levels are between 1 and 8 */ diff --git a/sysklogd/logger.c b/sysklogd/logger.c index b3ca85703..f9eafeb25 100644 --- a/sysklogd/logger.c +++ b/sysklogd/logger.c @@ -99,6 +99,8 @@ int logger_main(int argc UNUSED_PARAM, char **argv) int opt; int i = 0; + setup_common_bufsiz(); + /* Fill out the name string early (may be overwritten later) */ str_t = uid2uname_utoa(geteuid()); diff --git a/util-linux/script.c b/util-linux/script.c index 6195161bc..86475c1f1 100644 --- a/util-linux/script.c +++ b/util-linux/script.c @@ -109,12 +109,12 @@ int script_main(int argc UNUSED_PARAM, char **argv) if (child_pid) { /* parent */ -#define buf bb_common_bufsiz1 -#define sizeof_buf COMMON_BUFSIZE struct pollfd pfd[2]; int outfd, count, loop; double oldtime = ENABLE_SCRIPTREPLAY ? time(NULL) : 0; smallint fd_count = 2; +#define buf bb_common_bufsiz1 + setup_common_bufsiz(); outfd = xopen(fname, mode); pfd[0].fd = pty; @@ -136,7 +136,7 @@ int script_main(int argc UNUSED_PARAM, char **argv) } if (pfd[0].revents) { errno = 0; - count = safe_read(pty, buf, sizeof_buf); + count = safe_read(pty, buf, COMMON_BUFSIZE); if (count <= 0 && errno != EAGAIN) { /* err/eof from pty: exit */ goto restore; @@ -159,7 +159,7 @@ int script_main(int argc UNUSED_PARAM, char **argv) } } if (pfd[1].revents) { - count = safe_read(STDIN_FILENO, buf, sizeof_buf); + count = safe_read(STDIN_FILENO, buf, COMMON_BUFSIZE); if (count <= 0) { /* err/eof from stdin: don't read stdin anymore */ pfd[1].revents = 0; @@ -178,7 +178,7 @@ int script_main(int argc UNUSED_PARAM, char **argv) * (util-linux's script doesn't do this. buggy :) */ loop = 999; /* pty is in O_NONBLOCK mode, we exit as soon as buffer is empty */ - while (--loop && (count = safe_read(pty, buf, sizeof_buf)) > 0) { + while (--loop && (count = safe_read(pty, buf, COMMON_BUFSIZE)) > 0) { full_write(STDOUT_FILENO, buf, count); full_write(outfd, buf, count); } diff --git a/util-linux/umount.c b/util-linux/umount.c index be0300394..91da69674 100644 --- a/util-linux/umount.c +++ b/util-linux/umount.c @@ -103,6 +103,7 @@ int umount_main(int argc UNUSED_PARAM, char **argv) if (opt & OPT_ALL) bb_error_msg_and_die("can't open '%s'", bb_path_mtab_file); } else { + setup_common_bufsiz(); while (getmntent_r(fp, &me, bb_common_bufsiz1, COMMON_BUFSIZE)) { /* Match fstype if passed */ if (!match_fstype(&me, fstype)) From df70a43af281f7e653b1c95ff17201669fdcfca3 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Thu, 21 Apr 2016 18:54:36 +0200 Subject: [PATCH 228/260] udhcp: add setup_common_bufsiz() as needed Signed-off-by: Denys Vlasenko --- networking/udhcp/d6_dhcpc.c | 2 ++ networking/udhcp/dhcpc.c | 2 ++ networking/udhcp/dhcpd.c | 8 ++++---- 3 files changed, 8 insertions(+), 4 deletions(-) diff --git a/networking/udhcp/d6_dhcpc.c b/networking/udhcp/d6_dhcpc.c index 422254d62..c77669a31 100644 --- a/networking/udhcp/d6_dhcpc.c +++ b/networking/udhcp/d6_dhcpc.c @@ -930,6 +930,8 @@ int udhcpc6_main(int argc UNUSED_PARAM, char **argv) int retval; fd_set rfds; + setup_common_bufsiz(); + /* Default options */ IF_FEATURE_UDHCP_PORT(SERVER_PORT6 = 547;) IF_FEATURE_UDHCP_PORT(CLIENT_PORT6 = 546;) diff --git a/networking/udhcp/dhcpc.c b/networking/udhcp/dhcpc.c index 660b943ce..8f5a03f2e 100644 --- a/networking/udhcp/dhcpc.c +++ b/networking/udhcp/dhcpc.c @@ -1268,6 +1268,8 @@ int udhcpc_main(int argc UNUSED_PARAM, char **argv) int retval; fd_set rfds; + setup_common_bufsiz(); + /* Default options */ IF_FEATURE_UDHCP_PORT(SERVER_PORT = 67;) IF_FEATURE_UDHCP_PORT(CLIENT_PORT = 68;) diff --git a/networking/udhcp/dhcpd.c b/networking/udhcp/dhcpd.c index 2671ea3e2..e93a9f1da 100644 --- a/networking/udhcp/dhcpd.c +++ b/networking/udhcp/dhcpd.c @@ -310,10 +310,10 @@ int udhcpd_main(int argc UNUSED_PARAM, char **argv) unsigned arpping_ms; IF_FEATURE_UDHCP_PORT(char *str_P;) -#if ENABLE_FEATURE_UDHCP_PORT - SERVER_PORT = 67; - CLIENT_PORT = 68; -#endif + setup_common_bufsiz(); + + IF_FEATURE_UDHCP_PORT(SERVER_PORT = 67;) + IF_FEATURE_UDHCP_PORT(CLIENT_PORT = 68;) #if defined CONFIG_UDHCP_DEBUG && CONFIG_UDHCP_DEBUG >= 1 opt_complementary = "vv"; From f56fb5eb1120a92bdfb6d0ce64b3430b42a2efa0 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Thu, 21 Apr 2016 21:03:51 +0200 Subject: [PATCH 229/260] libbb: make "COMMON_BUFSIZE = 1024 bytes, the buffer will be malloced" work Signed-off-by: Denys Vlasenko --- libbb/common_bufsiz.c | 6 +++--- scripts/generate_BUFSIZ.sh | 5 +++-- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/libbb/common_bufsiz.c b/libbb/common_bufsiz.c index c16c361c9..26faafcbb 100644 --- a/libbb/common_bufsiz.c +++ b/libbb/common_bufsiz.c @@ -55,14 +55,14 @@ char bb_common_bufsiz1[COMMON_BUFSIZE] ALIGNED(sizeof(long long)); # ifndef setup_common_bufsiz /* - * It is not a "((void)0)" macro. It means we have to provide this function. + * It is not defined as a dummy macro. + * It means we have to provide this function. */ char* bb_common_bufsiz1; -char* setup_common_bufsiz(void) +void setup_common_bufsiz(void) { if (!bb_common_bufsiz1) bb_common_bufsiz1 = xzalloc(COMMON_BUFSIZE); - return bb_common_bufsiz1; } # else # ifndef bb_common_bufsiz1 diff --git a/scripts/generate_BUFSIZ.sh b/scripts/generate_BUFSIZ.sh index bb0738641..d54142597 100755 --- a/scripts/generate_BUFSIZ.sh +++ b/scripts/generate_BUFSIZ.sh @@ -87,7 +87,8 @@ if test $REM -lt 1024; then echo "Rerun make to build a binary which doesn't use it!" exit 1 fi - exit 0 + echo "COMMON_BUFSIZE = 1024 bytes, the buffer will be malloced" + exit 0 fi # _end[] has REM bytes for bb_common_bufsiz1[] @@ -102,7 +103,7 @@ echo "#define setup_common_bufsiz() ((void)0)" } | regenerate "$common_bufsiz_h" echo $REM >"$common_bufsiz_h.BUFSIZE" -# Check that code did not grow too much and thus _end[] did not shink: +# Check that code did not grow too much and thus _end[] did not shrink: if test $OLD -gt $REM; then echo "Warning! Space in _end[] has decreased from $OLD to $REM bytes!" echo "Rerun make!" From 93e1aaa1c7e5ed6d2704262700ec28837bdfc9b7 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Thu, 21 Apr 2016 21:47:45 +0200 Subject: [PATCH 230/260] libbb: constify *bb_common_bufsiz1 (if it is compiled to be a pointer) This lets gcc optimize much better: text data bss dec hex filename 922846 910 13056 936812 e4b6c busybox_unstripped.nonconst 920255 910 13056 934221 e414d busybox_unstripped Signed-off-by: Denys Vlasenko --- libbb/common_bufsiz.c | 4 ++-- scripts/generate_BUFSIZ.sh | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/libbb/common_bufsiz.c b/libbb/common_bufsiz.c index 26faafcbb..1a3585169 100644 --- a/libbb/common_bufsiz.c +++ b/libbb/common_bufsiz.c @@ -58,11 +58,11 @@ char bb_common_bufsiz1[COMMON_BUFSIZE] ALIGNED(sizeof(long long)); * It is not defined as a dummy macro. * It means we have to provide this function. */ -char* bb_common_bufsiz1; +char *const bb_common_bufsiz1 __attribute__ ((section (".data"))); void setup_common_bufsiz(void) { if (!bb_common_bufsiz1) - bb_common_bufsiz1 = xzalloc(COMMON_BUFSIZE); + *(char**)&bb_common_bufsiz1 = xzalloc(COMMON_BUFSIZE); } # else # ifndef bb_common_bufsiz1 diff --git a/scripts/generate_BUFSIZ.sh b/scripts/generate_BUFSIZ.sh index d54142597..1914fa0f5 100755 --- a/scripts/generate_BUFSIZ.sh +++ b/scripts/generate_BUFSIZ.sh @@ -77,7 +77,7 @@ if test $REM -lt 1024; then # users will need to malloc it. { echo "enum { COMMON_BUFSIZE = 1024 };" - echo "extern char *bb_common_bufsiz1;" + echo "extern char *const bb_common_bufsiz1;" echo "void setup_common_bufsiz(void);" } | regenerate "$common_bufsiz_h" # Check that we aren't left with a buggy binary: From d7b502c05911e1cf1d4fc31be71f3abccd0927a5 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Thu, 21 Apr 2016 23:52:35 +0200 Subject: [PATCH 231/260] build system: fix generate_BUFSIZ.sh to not alternate 1k and malloc builds Signed-off-by: Denys Vlasenko --- Makefile | 2 +- scripts/generate_BUFSIZ.sh | 174 ++++++++++++++++++++++--------------- 2 files changed, 106 insertions(+), 70 deletions(-) diff --git a/Makefile b/Makefile index 75a33c1fb..d5950230d 100644 --- a/Makefile +++ b/Makefile @@ -611,7 +611,7 @@ quiet_cmd_busybox__ ?= LINK $@ "$(core-y)" \ "$(libs-y)" \ "$(LDLIBS)" \ - && $(srctree)/scripts/generate_BUFSIZ.sh include/common_bufsiz.h + && $(srctree)/scripts/generate_BUFSIZ.sh --post include/common_bufsiz.h # Generate System.map quiet_cmd_sysmap = SYSMAP diff --git a/scripts/generate_BUFSIZ.sh b/scripts/generate_BUFSIZ.sh index 1914fa0f5..8aa0174a6 100755 --- a/scripts/generate_BUFSIZ.sh +++ b/scripts/generate_BUFSIZ.sh @@ -7,11 +7,16 @@ debug=false +postcompile=false +test x"$1" = x"--post" && { postcompile=true; shift; } + common_bufsiz_h=$1 test x"$NM" = x"" && NM="${CONFIG_CROSS_COMPILER_PREFIX}nm" test x"$CC" = x"" && CC="${CONFIG_CROSS_COMPILER_PREFIX}gcc" +exitcmd="exit 0" + regenerate() { cat >"$1.$$" test -f "$1" && diff "$1.$$" "$1" >/dev/null && rm "$1.$$" && return @@ -19,99 +24,130 @@ regenerate() { } generate_std_and_exit() { - $debug && echo "Default: bb_common_bufsiz1[] in bss" + $debug && echo "Configuring: bb_common_bufsiz1[] in bss" { echo "enum { COMMON_BUFSIZE = 1024 };" echo "extern char bb_common_bufsiz1[];" echo "#define setup_common_bufsiz() ((void)0)" } | regenerate "$common_bufsiz_h" - exit 0 + echo "std" >"$common_bufsiz_h.method" + $exitcmd } -# User does not want any funky stuff? -test x"$CONFIG_FEATURE_USE_BSS_TAIL" = x"y" || generate_std_and_exit - -test -f busybox_unstripped || { - # We did not try anything yet - $debug && echo "Will try to fit bb_common_bufsiz1[] into _end[]" +generate_big_and_exit() { + $debug && echo "Configuring: bb_common_bufsiz1[] in _end[], COMMON_BUFSIZE = $1" { - echo "enum { COMMON_BUFSIZE = 1024 };" + echo "enum { COMMON_BUFSIZE = $1 };" echo "extern char _end[]; /* linker-provided label */" echo "#define bb_common_bufsiz1 _end" echo "#define setup_common_bufsiz() ((void)0)" } | regenerate "$common_bufsiz_h" - echo 1024 >"$common_bufsiz_h.BUFSIZE" - exit 0 + echo "$2" >"$common_bufsiz_h.method" + $exitcmd } -# Get _end address -END=`$NM busybox_unstripped | grep ' . _end$'| cut -d' ' -f1` -test x"$END" = x"" && generate_std_and_exit -$debug && echo "END:0x$END $((0x$END))" -END=$((0x$END)) +generate_1k_and_exit() { + generate_big_and_exit 1024 "1k" +} -# Get PAGE_SIZE -echo "\ -#include -#if defined(PAGE_SIZE) && PAGE_SIZE > 0 -char page_size[PAGE_SIZE]; -#else -char page_size[1]; -#endif -" >page_size_$$.c -$CC -c "page_size_$$.c" || generate_std_and_exit -PAGE_SIZE=`$NM --size-sort "page_size_$$.o" | cut -d' ' -f1` -rm "page_size_$$.c" "page_size_$$.o" -test x"$PAGE_SIZE" = x"" && generate_std_and_exit -$debug && echo "PAGE_SIZE:0x$PAGE_SIZE $((0x$PAGE_SIZE))" -PAGE_SIZE=$((0x$PAGE_SIZE)) -test $PAGE_SIZE -lt 1024 && generate_std_and_exit -# How much space between _end[] and next page? -PAGE_MASK=$((PAGE_SIZE-1)) -REM=$(( (-END) & PAGE_MASK )) -$debug && echo "REM:$REM" - -if test $REM -lt 1024; then - # _end[] has no enough space for bb_common_bufsiz1[], - # users will need to malloc it. +generate_malloc_and_exit() { + $debug && echo "Configuring: bb_common_bufsiz1[] is malloced" { echo "enum { COMMON_BUFSIZE = 1024 };" echo "extern char *const bb_common_bufsiz1;" echo "void setup_common_bufsiz(void);" } | regenerate "$common_bufsiz_h" - # Check that we aren't left with a buggy binary: - if test -f "$common_bufsiz_h.BUFSIZE"; then - rm "$common_bufsiz_h.BUFSIZE" - echo "Warning! Space in _end[] is too small ($REM bytes)!" - echo "Rerun make to build a binary which doesn't use it!" - exit 1 + echo "malloc" >"$common_bufsiz_h.method" + $exitcmd +} + +# User does not want any funky stuff? +test x"$CONFIG_FEATURE_USE_BSS_TAIL" = x"y" || generate_std_and_exit + +# The script is run two times: before compilation, when it needs to +# (re)generate $common_bufsiz_h, and directly after successful build, +# when it needs to assess whether the build is ok to use at all (not buggy), +# and (re)generate $common_bufsiz_h for a future build. + +if $postcompile; then + # Postcompile needs to create/delete OK/FAIL files + + test -f busybox_unstripped || exit 1 + test -f "$common_bufsiz_h.method" || exit 1 + + # How the build was done? + method=`cat -- "$common_bufsiz_h.method"` + + # Get _end address + END=`$NM busybox_unstripped | grep ' . _end$'| cut -d' ' -f1` + test x"$END" = x"" && generate_std_and_exit + $debug && echo "END:0x$END $((0x$END))" + END=$((0x$END)) + + # Get PAGE_SIZE + { + echo "#include " + echo "#if defined(PAGE_SIZE) && PAGE_SIZE > 0" + echo "char page_size[PAGE_SIZE];" + echo "#endif" + } >page_size_$$.c + $CC -c "page_size_$$.c" || exit 1 + PAGE_SIZE=`$NM --size-sort "page_size_$$.o" | cut -d' ' -f1` + rm "page_size_$$.c" "page_size_$$.o" + test x"$PAGE_SIZE" = x"" && exit 1 + $debug && echo "PAGE_SIZE:0x$PAGE_SIZE $((0x$PAGE_SIZE))" + PAGE_SIZE=$((0x$PAGE_SIZE)) + test $PAGE_SIZE -lt 512 && exit 1 + + # How much space between _end[] and next page? + PAGE_MASK=$((PAGE_SIZE-1)) + COMMON_BUFSIZE=$(( (-END) & PAGE_MASK )) + echo "COMMON_BUFSIZE = $COMMON_BUFSIZE bytes" + + if test x"$method" = x"1k"; then + if test $COMMON_BUFSIZE -lt 1024; then + # _end[] has no enough space for bb_common_bufsiz1[] + rm -- "$common_bufsiz_h.1k.OK" 2>/dev/null + { md5sum <.config | cut -d' ' -f1; stat -c "%Y" .config; } >"$common_bufsiz_h.1k.FAIL" + echo "Warning! Space in _end[] is too small ($COMMON_BUFSIZE bytes)!" + echo "Rerun make to build a binary which doesn't use it!" + rm busybox_unstripped + exitcmd="exit 1" + else + rm -- "$common_bufsiz_h.1k.FAIL" 2>/dev/null + echo $COMMON_BUFSIZE >"$common_bufsiz_h.1k.OK" + test $COMMON_BUFSIZE -gt $((1024+32)) && echo "Rerun make to use larger COMMON_BUFSIZE" + fi fi - echo "COMMON_BUFSIZE = 1024 bytes, the buffer will be malloced" - exit 0 fi -# _end[] has REM bytes for bb_common_bufsiz1[] -OLD=1024 -test -f "$common_bufsiz_h.BUFSIZE" && OLD=`cat "$common_bufsiz_h.BUFSIZE"` -$debug && echo "OLD:$OLD" -{ -echo "enum { COMMON_BUFSIZE = $REM };" -echo "extern char _end[]; /* linker-provided label */" -echo "#define bb_common_bufsiz1 _end" -echo "#define setup_common_bufsiz() ((void)0)" -} | regenerate "$common_bufsiz_h" -echo $REM >"$common_bufsiz_h.BUFSIZE" +# Based on past success/fail of 1k build, decide next build type -# Check that code did not grow too much and thus _end[] did not shrink: -if test $OLD -gt $REM; then - echo "Warning! Space in _end[] has decreased from $OLD to $REM bytes!" - echo "Rerun make!" - exit 1 +if test -f "$common_bufsiz_h.1k.OK"; then + # Previous build succeeded fitting 1k into _end[]. + # Try bigger COMMON_BUFSIZE if possible. + COMMON_BUFSIZE=`cat -- "$common_bufsiz_h.1k.OK"` + # Round down a bit + COMMON_BUFSIZE=$(( (COMMON_BUFSIZE-32) & 0xfffffe0 )) + COMMON_BUFSIZE=$(( COMMON_BUFSIZE < 1024 ? 1024 : COMMON_BUFSIZE )) + test $COMMON_BUFSIZE = 1024 && generate_1k_and_exit + generate_big_and_exit $COMMON_BUFSIZE "big" fi - -if test $OLD != $REM; then - echo "Space in _end[] is $REM bytes. Rerun make to use larger COMMON_BUFSIZE." -else - echo "COMMON_BUFSIZE = $REM bytes" +if test -f "$common_bufsiz_h.1k.FAIL"; then + # Previous build FAILED to fit 1k into _end[]. + # Was it with same .config? + oldcfg=`cat -- "$common_bufsiz_h.1k.FAIL"` + curcfg=`md5sum <.config | cut -d' ' -f1; stat -c "%Y" .config` + # If yes, then build a "malloced" version + if test x"$oldcfg" = x"$curcfg"; then + echo "Will not try 1k build, it failed before. Touch .config to override" + generate_malloc_and_exit + fi + # else: try 1k version + echo "New .config, will try 1k build" + rm -- "$common_bufsiz_h.1k.FAIL" + generate_1k_and_exit fi +# There was no 1k build yet. Try it. +generate_1k_and_exit From 7ff24bd5fb37c58d9e41743a910df147357dda61 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Fri, 22 Apr 2016 00:24:53 +0200 Subject: [PATCH 232/260] generate_BUFSIZ.sh: catch BUFSIZE < 1024 also on "big" builds Signed-off-by: Denys Vlasenko --- scripts/generate_BUFSIZ.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/scripts/generate_BUFSIZ.sh b/scripts/generate_BUFSIZ.sh index 8aa0174a6..750fedbef 100755 --- a/scripts/generate_BUFSIZ.sh +++ b/scripts/generate_BUFSIZ.sh @@ -105,14 +105,14 @@ if $postcompile; then COMMON_BUFSIZE=$(( (-END) & PAGE_MASK )) echo "COMMON_BUFSIZE = $COMMON_BUFSIZE bytes" - if test x"$method" = x"1k"; then + if test x"$method" != x"malloc"; then if test $COMMON_BUFSIZE -lt 1024; then # _end[] has no enough space for bb_common_bufsiz1[] rm -- "$common_bufsiz_h.1k.OK" 2>/dev/null { md5sum <.config | cut -d' ' -f1; stat -c "%Y" .config; } >"$common_bufsiz_h.1k.FAIL" echo "Warning! Space in _end[] is too small ($COMMON_BUFSIZE bytes)!" echo "Rerun make to build a binary which doesn't use it!" - rm busybox_unstripped + rm busybox_unstripped busybox exitcmd="exit 1" else rm -- "$common_bufsiz_h.1k.FAIL" 2>/dev/null From 663d1da1e68b15397c00d6a094f78c2cf08358ea Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Fri, 22 Apr 2016 02:00:04 +0200 Subject: [PATCH 233/260] scripts/trylink: document DATA_SEGMENT_ALIGN() hack Signed-off-by: Denys Vlasenko --- scripts/trylink | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/scripts/trylink b/scripts/trylink index 15435f009..129570a60 100755 --- a/scripts/trylink +++ b/scripts/trylink @@ -209,6 +209,16 @@ else # *(.bss SORT_BY_ALIGNMENT(.bss.*) .gnu.linkonce.b.*) # This will eliminate most of the padding (~3kb). # Hmm, "ld --sort-section alignment" should do it too. + # + # There is a ld hack which is meant to decrease disk usage + # at the cost of more RAM usage (??!!) in standard ld script: + # /* Adjust the address for the data segment. We want to adjust up to + # the same address within the page on the next page up. */ + # . = ALIGN (0x1000) - ((0x1000 - .) & (0x1000 - 1)); . = DATA_SEGMENT_ALIGN (0x1000, 0x1000); + # Replace it with: + # . = ALIGN (0x1000); . = DATA_SEGMENT_ALIGN (0x1000, 0x1000); + # to unconditionally align .data to the next page boundary, + # instead of "next page, plus current offset in this page" try $CC $CFLAGS $LDFLAGS \ -o $EXE \ $SORT_COMMON \ From 3e134ebf6afb5552b3619f98f6a2ffa01a07eebb Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Fri, 22 Apr 2016 18:09:21 +0200 Subject: [PATCH 234/260] *: slap on a few ALIGN1/2s where appropriate The result of looking at "grep -F -B2 '*fill*' busybox_unstripped.map" text data bss dec hex filename 829901 4086 1904 835891 cc133 busybox_before 829665 4086 1904 835655 cc047 busybox Signed-off-by: Denys Vlasenko --- archival/libarchive/common.c | 2 +- archival/lzop.c | 2 +- archival/unzip.c | 2 +- coreutils/stty.c | 6 +++--- e2fsprogs/e2fs_lib.c | 4 ++-- editors/sed.c | 2 +- editors/vi.c | 2 +- init/bootchartd.c | 2 +- libbb/mode_string.c | 4 ++-- libbb/pw_encrypt.c | 2 +- libbb/u_signal_names.c | 2 +- miscutils/adjtimex.c | 6 +++--- miscutils/eject.c | 2 +- miscutils/ionice.c | 2 +- miscutils/setserial.c | 8 ++++---- networking/libiproute/ipneigh.c | 2 +- networking/libiproute/ll_proto.c | 2 +- networking/libiproute/ll_types.c | 4 ++-- networking/telnetd.ctrlSQ.patch | 4 ++-- networking/udhcp/dhcpc.c | 2 +- networking/wget.c | 6 +++--- procps/top.c | 6 +++--- shell/ash.c | 6 +++--- shell/shell_common.c | 2 +- util-linux/fatattr.c | 2 +- util-linux/mount.c | 6 +++--- util-linux/nsenter.c | 2 +- util-linux/unshare.c | 2 +- util-linux/volume_id/bcache.c | 2 +- util-linux/volume_id/luks.c | 2 +- 30 files changed, 49 insertions(+), 49 deletions(-) diff --git a/archival/libarchive/common.c b/archival/libarchive/common.c index dd69d2222..389cb7856 100644 --- a/archival/libarchive/common.c +++ b/archival/libarchive/common.c @@ -6,4 +6,4 @@ #include "libbb.h" #include "bb_archive.h" -const char cpio_TRAILER[] = "TRAILER!!!"; +const char cpio_TRAILER[] ALIGN1 = "TRAILER!!!"; diff --git a/archival/lzop.c b/archival/lzop.c index 4afa21889..202de4d03 100644 --- a/archival/lzop.c +++ b/archival/lzop.c @@ -896,7 +896,7 @@ static NOINLINE int lzo_decompress(const header_t *h) * chksum_out * The rest is identical. */ -static const unsigned char lzop_magic[9] = { +static const unsigned char lzop_magic[9] ALIGN1 = { 0x89, 0x4c, 0x5a, 0x4f, 0x00, 0x0d, 0x0a, 0x1a, 0x0a }; diff --git a/archival/unzip.c b/archival/unzip.c index be32e60e2..c540485ac 100644 --- a/archival/unzip.c +++ b/archival/unzip.c @@ -487,7 +487,7 @@ int unzip_main(int argc, char **argv) if (overwrite == O_PROMPT) overwrite = O_NEVER; } else { - static const char extn[][5] = { ".zip", ".ZIP" }; + static const char extn[][5] ALIGN1 = { ".zip", ".ZIP" }; char *ext = src_fn + strlen(src_fn); int src_fd; diff --git a/coreutils/stty.c b/coreutils/stty.c index 0e32fc898..52967ea8f 100644 --- a/coreutils/stty.c +++ b/coreutils/stty.c @@ -318,7 +318,7 @@ enum { #define MI_ENTRY(N,T,F,B,M) N "\0" /* Mode names given on command line */ -static const char mode_name[] = +static const char mode_name[] ALIGN1 = MI_ENTRY("evenp", combination, REV | OMIT, 0, 0 ) MI_ENTRY("parity", combination, REV | OMIT, 0, 0 ) MI_ENTRY("oddp", combination, REV | OMIT, 0, 0 ) @@ -681,7 +681,7 @@ enum { #define CI_ENTRY(n,s,o) n "\0" /* Name given on command line */ -static const char control_name[] = +static const char control_name[] ALIGN1 = CI_ENTRY("intr", CINTR, VINTR ) CI_ENTRY("quit", CQUIT, VQUIT ) CI_ENTRY("erase", CERASE, VERASE ) @@ -723,7 +723,7 @@ static const char control_name[] = #undef CI_ENTRY #define CI_ENTRY(n,s,o) { s, o }, -static const struct control_info control_info[] = { +static const struct control_info control_info[] ALIGN2 = { /* This should be verbatim cut-n-paste copy of the above CI_ENTRYs */ CI_ENTRY("intr", CINTR, VINTR ) CI_ENTRY("quit", CQUIT, VQUIT ) diff --git a/e2fsprogs/e2fs_lib.c b/e2fsprogs/e2fs_lib.c index a6aec9484..6ce655be3 100644 --- a/e2fsprogs/e2fs_lib.c +++ b/e2fsprogs/e2fs_lib.c @@ -149,14 +149,14 @@ const uint32_t e2attr_flags_value[] = { EXT2_TOPDIR_FL }; -const char e2attr_flags_sname[] = +const char e2attr_flags_sname[] ALIGN1 = #ifdef ENABLE_COMPRESSION "BZXE" #endif "I" "suSDiadAcjtT"; -static const char e2attr_flags_lname[] = +static const char e2attr_flags_lname[] ALIGN1 = #ifdef ENABLE_COMPRESSION "Compressed_File" "\0" "Compressed_Dirty_File" "\0" diff --git a/editors/sed.c b/editors/sed.c index ed48de17f..6bce25b2c 100644 --- a/editors/sed.c +++ b/editors/sed.c @@ -473,7 +473,7 @@ static int parse_subst_cmd(sed_cmd_t *sed_cmd, const char *substr) */ static const char *parse_cmd_args(sed_cmd_t *sed_cmd, const char *cmdstr) { - static const char cmd_letters[] = "saicrw:btTydDgGhHlnNpPqx={}"; + static const char cmd_letters[] ALIGN1 = "saicrw:btTydDgGhHlnNpPqx={}"; enum { IDX_s = 0, IDX_a, diff --git a/editors/vi.c b/editors/vi.c index f355712ab..974f9978b 100644 --- a/editors/vi.c +++ b/editors/vi.c @@ -251,7 +251,7 @@ enum { // cmds modifying text[] // vda: removed "aAiIs" as they switch us into insert mode // and remembering input for replay after them makes no sense -static const char modifying_cmds[] = "cCdDJoOpPrRxX<>~"; +static const char modifying_cmds[] ALIGN1 = "cCdDJoOpPrRxX<>~"; #endif enum { diff --git a/init/bootchartd.c b/init/bootchartd.c index 7f511e650..92aaade0f 100644 --- a/init/bootchartd.c +++ b/init/bootchartd.c @@ -194,7 +194,7 @@ static char *make_tempdir(void) * Since we unmount it at once, we can mount it anywhere. * Try a few locations which are likely ti exist. */ - static const char dirs[] = "/mnt\0""/tmp\0""/boot\0""/proc\0"; + static const char dirs[] ALIGN1 = "/mnt\0""/tmp\0""/boot\0""/proc\0"; const char *try_dir = dirs; while (mount("none", try_dir, "tmpfs", MS_SILENT, "size=16m") != 0) { try_dir += strlen(try_dir) + 1; diff --git a/libbb/mode_string.c b/libbb/mode_string.c index f1afe7d61..934eb6dc7 100644 --- a/libbb/mode_string.c +++ b/libbb/mode_string.c @@ -87,9 +87,9 @@ const char* FAST_FUNC bb_mode_string(mode_t mode) /* The previous version used "0pcCd?bB-?l?s???". However, the '0', 'C', * and 'B' types don't appear to be available on linux. So I removed them. */ -static const char type_chars[16] = "?pc?d?b?-?l?s???"; +static const char type_chars[16] ALIGN1 = "?pc?d?b?-?l?s???"; /********************************** 0123456789abcdef */ -static const char mode_chars[7] = "rwxSTst"; +static const char mode_chars[7] ALIGN1 = "rwxSTst"; const char* FAST_FUNC bb_mode_string(mode_t mode) { diff --git a/libbb/pw_encrypt.c b/libbb/pw_encrypt.c index dbc15e5fc..4cdc2de76 100644 --- a/libbb/pw_encrypt.c +++ b/libbb/pw_encrypt.c @@ -9,7 +9,7 @@ #include "libbb.h" -/* static const uint8_t ascii64[] = +/* static const uint8_t ascii64[] ALIGN1 = * "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; */ diff --git a/libbb/u_signal_names.c b/libbb/u_signal_names.c index 8c78f5e20..b49714f2a 100644 --- a/libbb/u_signal_names.c +++ b/libbb/u_signal_names.c @@ -19,7 +19,7 @@ /* Believe it or not, but some arches have more than 32 SIGs! * HPPA: SIGSTKFLT == 36. */ -static const char signals[][7] = { +static const char signals[][7] ALIGN1 = { // SUSv3 says kill must support these, and specifies the numerical values, // http://www.opengroup.org/onlinepubs/009695399/utilities/kill.html // {0, "EXIT"}, {1, "HUP"}, {2, "INT"}, {3, "QUIT"}, diff --git a/miscutils/adjtimex.c b/miscutils/adjtimex.c index 534364a69..058aa9a5c 100644 --- a/miscutils/adjtimex.c +++ b/miscutils/adjtimex.c @@ -29,7 +29,7 @@ # include #endif -static const uint16_t statlist_bit[] = { +static const uint16_t statlist_bit[] ALIGN2 = { STA_PLL, STA_PPSFREQ, STA_PPSTIME, @@ -45,7 +45,7 @@ static const uint16_t statlist_bit[] = { STA_CLOCKERR, 0 }; -static const char statlist_name[] = +static const char statlist_name[] ALIGN1 = "PLL" "\0" "PPSFREQ" "\0" "PPSTIME" "\0" @@ -61,7 +61,7 @@ static const char statlist_name[] = "CLOCKERR" ; -static const char ret_code_descript[] = +static const char ret_code_descript[] ALIGN1 = "clock synchronized" "\0" "insert leap second" "\0" "delete leap second" "\0" diff --git a/miscutils/eject.c b/miscutils/eject.c index e33d79127..16ae250ff 100644 --- a/miscutils/eject.c +++ b/miscutils/eject.c @@ -40,7 +40,7 @@ #if ENABLE_FEATURE_EJECT_SCSI static void eject_scsi(const char *dev) { - static const char sg_commands[3][6] = { + static const char sg_commands[3][6] ALIGN1 = { { ALLOW_MEDIUM_REMOVAL, 0, 0, 0, 0, 0 }, { START_STOP, 0, 0, 0, 1, 0 }, { START_STOP, 0, 0, 0, 2, 0 } diff --git a/miscutils/ionice.c b/miscutils/ionice.c index bd300605f..0c14256ab 100644 --- a/miscutils/ionice.c +++ b/miscutils/ionice.c @@ -41,7 +41,7 @@ enum { IOPRIO_CLASS_IDLE }; -static const char to_prio[] = "none\0realtime\0best-effort\0idle"; +static const char to_prio[] ALIGN1 = "none\0realtime\0best-effort\0idle"; #define IOPRIO_CLASS_SHIFT 13 diff --git a/miscutils/setserial.c b/miscutils/setserial.c index dfed3306e..8b5c4a9c7 100644 --- a/miscutils/setserial.c +++ b/miscutils/setserial.c @@ -257,7 +257,7 @@ enum print_mode #define CTL_CLOSE (1 << 3) #define CTL_NODIE (1 << 4) -static const char serial_types[] = +static const char serial_types[] ALIGN1 = "unknown\0" /* 0 */ "8250\0" /* 1 */ "16450\0" /* 2 */ @@ -288,7 +288,7 @@ static const char serial_types[] = # define MAX_SERIAL_TYPE 13 #endif -static const char commands[] = +static const char commands[] ALIGN1 = "spd_normal\0" "spd_hi\0" "spd_vhi\0" @@ -404,8 +404,8 @@ static const uint16_t setbits[CMD_FLAG_LAST + 1] = ASYNC_LOW_LATENCY }; -static const char STR_INFINITE[] = "infinite"; -static const char STR_NONE[] = "none"; +#define STR_INFINITE "infinite" +#define STR_NONE "none" static const char *uart_type(int type) { diff --git a/networking/libiproute/ipneigh.c b/networking/libiproute/ipneigh.c index d2028b7b6..2a1c20e20 100644 --- a/networking/libiproute/ipneigh.c +++ b/networking/libiproute/ipneigh.c @@ -62,7 +62,7 @@ static unsigned nud_state_a2n(char *arg) "stale\0" "incomplete\0" "delay\0" "probe\0" "failed\0" ; - static uint8_t nuds[] = { + static uint8_t nuds[] ALIGN1 = { NUD_PERMANENT,NUD_REACHABLE, NUD_NOARP,NUD_NONE, NUD_STALE, NUD_INCOMPLETE,NUD_DELAY,NUD_PROBE, NUD_FAILED diff --git a/networking/libiproute/ll_proto.c b/networking/libiproute/ll_proto.c index da2b53cbf..4c32ae574 100644 --- a/networking/libiproute/ll_proto.c +++ b/networking/libiproute/ll_proto.c @@ -84,7 +84,7 @@ ETH_P_IP /* Keep declarations above and below in sync! */ -static const char llproto_names[] = +static const char llproto_names[] ALIGN1 = #define __PF(f,n) #n "\0" __PF(LOOP,loop) __PF(PUP,pup) diff --git a/networking/libiproute/ll_types.c b/networking/libiproute/ll_types.c index bb42e269e..62ee0cc54 100644 --- a/networking/libiproute/ll_types.c +++ b/networking/libiproute/ll_types.c @@ -16,7 +16,7 @@ const char* FAST_FUNC ll_type_n2a(int type, char *buf) { - static const char arphrd_name[] = + static const char arphrd_name[] ALIGN1 = /* 0, */ "generic" "\0" /* ARPHRD_LOOPBACK, */ "loopback" "\0" /* ARPHRD_ETHER, */ "ether" "\0" @@ -105,7 +105,7 @@ const char* FAST_FUNC ll_type_n2a(int type, char *buf) /* Keep these arrays in sync! */ - static const uint16_t arphrd_type[] = { + static const uint16_t arphrd_type[] ALIGN2 = { 0, /* "generic" "\0" */ ARPHRD_LOOPBACK, /* "loopback" "\0" */ ARPHRD_ETHER, /* "ether" "\0" */ diff --git a/networking/telnetd.ctrlSQ.patch b/networking/telnetd.ctrlSQ.patch index 7060e1c6e..bc26d2279 100644 --- a/networking/telnetd.ctrlSQ.patch +++ b/networking/telnetd.ctrlSQ.patch @@ -94,9 +94,9 @@ exceptional conditions. #endif +#ifdef TIOCPKT + int control; -+ static const char lflow_on[] = ++ static const char lflow_on[] ALIGN1 = + {IAC, SB, TELOPT_LFLOW, LFLOW_ON, IAC, SE}; -+ static const char lflow_off[] = ++ static const char lflow_off[] ALIGN1 = + {IAC, SB, TELOPT_LFLOW, LFLOW_OFF, IAC, SE}; +# define RESERVED sizeof(lflow_on) +#else diff --git a/networking/udhcp/dhcpc.c b/networking/udhcp/dhcpc.c index 8f5a03f2e..fc7b6216d 100644 --- a/networking/udhcp/dhcpc.c +++ b/networking/udhcp/dhcpc.c @@ -109,7 +109,7 @@ enum { /*** Script execution code ***/ /* get a rough idea of how long an option will be (rounding up...) */ -static const uint8_t len_of_option_as_string[] = { +static const uint8_t len_of_option_as_string[] ALIGN1 = { [OPTION_IP ] = sizeof("255.255.255.255 "), [OPTION_IP_PAIR ] = sizeof("255.255.255.255 ") * 2, [OPTION_STATIC_ROUTES ] = sizeof("255.255.255.255/32 255.255.255.255 "), diff --git a/networking/wget.c b/networking/wget.c index 5c12423c7..28c12540b 100644 --- a/networking/wget.c +++ b/networking/wget.c @@ -146,10 +146,10 @@ struct host_info { char *host; int port; }; -static const char P_FTP[] = "ftp"; -static const char P_HTTP[] = "http"; +static const char P_FTP[] ALIGN1 = "ftp"; +static const char P_HTTP[] ALIGN1 = "http"; #if ENABLE_FEATURE_WGET_OPENSSL || ENABLE_FEATURE_WGET_SSL_HELPER -static const char P_HTTPS[] = "https"; +static const char P_HTTPS[] ALIGN1 = "https"; #endif #if ENABLE_FEATURE_WGET_LONG_OPTIONS diff --git a/procps/top.c b/procps/top.c index 640bcdc6d..73cd285f0 100644 --- a/procps/top.c +++ b/procps/top.c @@ -265,9 +265,9 @@ static int mult_lvl_cmp(void* a, void* b) static NOINLINE int read_cpu_jiffy(FILE *fp, jiffy_counts_t *p_jif) { #if !ENABLE_FEATURE_TOP_SMP_CPU - static const char fmt[] = "cpu %llu %llu %llu %llu %llu %llu %llu %llu"; + static const char fmt[] ALIGN1 = "cpu %llu %llu %llu %llu %llu %llu %llu %llu"; #else - static const char fmt[] = "cp%*s %llu %llu %llu %llu %llu %llu %llu %llu"; + static const char fmt[] ALIGN1 = "cp%*s %llu %llu %llu %llu %llu %llu %llu %llu"; #endif int ret; @@ -519,7 +519,7 @@ enum { static void parse_meminfo(unsigned long meminfo[MI_MAX]) { - static const char fields[] = + static const char fields[] ALIGN1 = "MemTotal\0" "MemFree\0" "MemShared\0" diff --git a/shell/ash.c b/shell/ash.c index da9c95045..faa45a8dc 100644 --- a/shell/ash.c +++ b/shell/ash.c @@ -2750,7 +2750,7 @@ pwdcmd(int argc UNUSED_PARAM, char **argv UNUSED_PARAM) #else # define SIT_ITEM(a,b,c,d) (a | (b << 4) | (c << 8)) #endif -static const uint16_t S_I_T[] = { +static const uint16_t S_I_T[] ALIGN2 = { #if ENABLE_ASH_ALIAS SIT_ITEM(CSPCL , CIGN , CIGN , CIGN ), /* 0, PEOA */ #endif @@ -2852,7 +2852,7 @@ SIT(int c, int syntax) #else /* !USE_SIT_FUNCTION */ -static const uint8_t syntax_index_table[] = { +static const uint8_t syntax_index_table[] ALIGN1 = { /* BASESYNTAX_DQSYNTAX_SQSYNTAX_ARISYNTAX */ /* 0 */ CWORD_CWORD_CWORD_CWORD, /* 1 */ CWORD_CWORD_CWORD_CWORD, @@ -7977,7 +7977,7 @@ static char *funcstring; /* block to allocate strings from */ #define EV_TESTED 02 /* exit status is checked; ignore -e flag */ #define EV_BACKCMD 04 /* command executing within back quotes */ -static const uint8_t nodesize[N_NUMBER] = { +static const uint8_t nodesize[N_NUMBER] ALIGN1 = { [NCMD ] = SHELL_ALIGN(sizeof(struct ncmd)), [NPIPE ] = SHELL_ALIGN(sizeof(struct npipe)), [NREDIR ] = SHELL_ALIGN(sizeof(struct nredir)), diff --git a/shell/shell_common.c b/shell/shell_common.c index 8c9607c8c..14eeaafcc 100644 --- a/shell/shell_common.c +++ b/shell/shell_common.c @@ -328,7 +328,7 @@ enum { }; /* "-": treat args as parameters of option with ASCII code 1 */ -static const char ulimit_opt_string[] = "-HSa" +static const char ulimit_opt_string[] ALIGN1 = "-HSa" #ifdef RLIMIT_FSIZE "f::" #endif diff --git a/util-linux/fatattr.c b/util-linux/fatattr.c index 5d933874a..6dca24a73 100644 --- a/util-linux/fatattr.c +++ b/util-linux/fatattr.c @@ -42,7 +42,7 @@ * Extra space at the end is a hack to print space separator in file listing. * Let's hope no one ever passes space as an option char :) */ -static const char bit_to_char[] = "rhsvda67 "; +static const char bit_to_char[] ALIGN1 = "rhsvda67 "; static inline unsigned long get_flag(char c) { diff --git a/util-linux/mount.c b/util-linux/mount.c index 244f4fa27..c76f6ef61 100644 --- a/util-linux/mount.c +++ b/util-linux/mount.c @@ -377,7 +377,7 @@ static const int32_t mount_options[] = { /* "remount" */ MS_REMOUNT // action flag }; -static const char mount_option_str[] = +static const char mount_option_str[] ALIGN1 = IF_FEATURE_MOUNT_LOOP( "loop\0" ) @@ -1003,7 +1003,7 @@ enum { # define EDQUOT ENOSPC #endif /* Convert each NFSERR_BLAH into EBLAH */ -static const uint8_t nfs_err_stat[] = { +static const uint8_t nfs_err_stat[] ALIGN1 = { 1, 2, 5, 6, 13, 17, 19, 20, 21, 22, 27, 28, 30, 63, 66, 69, 70, 71 @@ -1016,7 +1016,7 @@ typedef uint8_t nfs_err_type; #else typedef uint16_t nfs_err_type; #endif -static const nfs_err_type nfs_err_errnum[] = { +static const nfs_err_type nfs_err_errnum[] ALIGN2 = { EPERM , ENOENT , EIO , ENXIO , EACCES, EEXIST, ENODEV, ENOTDIR , EISDIR , EINVAL, EFBIG , ENOSPC, EROFS , ENAMETOOLONG, ENOTEMPTY, EDQUOT, ESTALE, EREMOTE diff --git a/util-linux/nsenter.c b/util-linux/nsenter.c index b08b3dae7..6834292da 100644 --- a/util-linux/nsenter.c +++ b/util-linux/nsenter.c @@ -128,7 +128,7 @@ static const struct namespace_descr ns_list[] = { /* * Upstream nsenter doesn't support the short option for --preserve-credentials */ -static const char opt_str[] = "U::i::u::n::p::m::""t+S+G+r::w::F"; +static const char opt_str[] ALIGN1 = "U::i::u::n::p::m::""t+S+G+r::w::F"; #if ENABLE_FEATURE_NSENTER_LONG_OPTS static const char nsenter_longopts[] ALIGN1 = diff --git a/util-linux/unshare.c b/util-linux/unshare.c index d05cfdb6c..fa7086add 100644 --- a/util-linux/unshare.c +++ b/util-linux/unshare.c @@ -137,7 +137,7 @@ static const struct namespace_descr ns_list[] = { * we are forced to use "fake" letters for them. * '+': stop at first non-option. */ -static const char opt_str[] = "+muinpU""fr""\xfd::""\xfe:""\xff:"; +static const char opt_str[] ALIGN1 = "+muinpU""fr""\xfd::""\xfe:""\xff:"; static const char unshare_longopts[] ALIGN1 = "mount\0" Optional_argument "\xf0" "uts\0" Optional_argument "\xf1" diff --git a/util-linux/volume_id/bcache.c b/util-linux/volume_id/bcache.c index 648e44de5..fd40eb081 100644 --- a/util-linux/volume_id/bcache.c +++ b/util-linux/volume_id/bcache.c @@ -24,7 +24,7 @@ #define SB_LABEL_SIZE 32 #define SB_JOURNAL_BUCKETS 256U -static const char bcache_magic[] = { +static const char bcache_magic[] ALIGN1 = { 0xc6, 0x85, 0x73, 0xf6, 0x4e, 0x1a, 0x45, 0xca, 0x82, 0x65, 0xf5, 0x7f, 0x48, 0xba, 0x6d, 0x81 }; diff --git a/util-linux/volume_id/luks.c b/util-linux/volume_id/luks.c index 42bf87659..21cb26f51 100644 --- a/util-linux/volume_id/luks.c +++ b/util-linux/volume_id/luks.c @@ -40,7 +40,7 @@ #define LUKS_SALTSIZE 32 #define LUKS_NUMKEYS 8 -static const uint8_t LUKS_MAGIC[] = { 'L','U','K','S', 0xba, 0xbe }; +static const uint8_t LUKS_MAGIC[] ALIGN1 = { 'L','U','K','S', 0xba, 0xbe }; struct luks_phdr { uint8_t magic[LUKS_MAGIC_L]; From 4c8fa34417fd2ccdda6a8ea508a3f1e7fb1d4ceb Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Sun, 24 Apr 2016 14:13:35 +0200 Subject: [PATCH 235/260] generate_BUFSIZ.sh: yet another tweak Signed-off-by: Denys Vlasenko --- include/.gitignore | 1 + scripts/generate_BUFSIZ.sh | 54 +++++++++++++++++++++++++++++--------- 2 files changed, 42 insertions(+), 13 deletions(-) diff --git a/include/.gitignore b/include/.gitignore index 9d9b6c499..75afff9ca 100644 --- a/include/.gitignore +++ b/include/.gitignore @@ -8,3 +8,4 @@ /NUM_APPLETS.h /usage_compressed.h /usage.h +/common_bufsiz.h* diff --git a/scripts/generate_BUFSIZ.sh b/scripts/generate_BUFSIZ.sh index 750fedbef..844261906 100755 --- a/scripts/generate_BUFSIZ.sh +++ b/scripts/generate_BUFSIZ.sh @@ -6,6 +6,7 @@ . ./.config || exit 1 debug=false +#debug=true postcompile=false test x"$1" = x"--post" && { postcompile=true; shift; } @@ -62,6 +63,11 @@ generate_malloc_and_exit() { $exitcmd } +round_down_COMMON_BUFSIZE() { + COMMON_BUFSIZE=$(( ($1-32) & 0xfffffe0 )) + COMMON_BUFSIZE=$(( COMMON_BUFSIZE < 1024 ? 1024 : COMMON_BUFSIZE )) +} + # User does not want any funky stuff? test x"$CONFIG_FEATURE_USE_BSS_TAIL" = x"y" || generate_std_and_exit @@ -102,22 +108,43 @@ if $postcompile; then # How much space between _end[] and next page? PAGE_MASK=$((PAGE_SIZE-1)) - COMMON_BUFSIZE=$(( (-END) & PAGE_MASK )) - echo "COMMON_BUFSIZE = $COMMON_BUFSIZE bytes" + TAIL_SIZE=$(( (-END) & PAGE_MASK )) + $debug && echo "TAIL_SIZE:$TAIL_SIZE bytes" - if test x"$method" != x"malloc"; then - if test $COMMON_BUFSIZE -lt 1024; then + if test x"$method" = x"1k" || test x"$method" = x"big"; then + if test $TAIL_SIZE -lt 1024; then # _end[] has no enough space for bb_common_bufsiz1[] + echo "Warning! Space in _end[] is too small ($TAIL_SIZE bytes)!" + echo "Rerun make to build a binary which doesn't use it!" rm -- "$common_bufsiz_h.1k.OK" 2>/dev/null { md5sum <.config | cut -d' ' -f1; stat -c "%Y" .config; } >"$common_bufsiz_h.1k.FAIL" - echo "Warning! Space in _end[] is too small ($COMMON_BUFSIZE bytes)!" - echo "Rerun make to build a binary which doesn't use it!" - rm busybox_unstripped busybox + rm busybox_unstripped busybox 2>/dev/null +# Note: here we can do either a "malloc" or "std" build. +# "malloc" gives a bit bigger code: +# text bss filename +# 804355 5385 busybox.std +# 804618 4361 busybox.malloc +# but may have a smaller .bss (not guaranteed!). Use "pmap -x" to verify. exitcmd="exit 1" + generate_malloc_and_exit else + PREV_SIZE=1024 + test x"$method" = x"big" && PREV_SIZE=`cat -- "$common_bufsiz_h.1k.OK"` + round_down_COMMON_BUFSIZE $PREV_SIZE + PREV_BUFSIZE=$COMMON_BUFSIZE + rm -- "$common_bufsiz_h.1k.FAIL" 2>/dev/null - echo $COMMON_BUFSIZE >"$common_bufsiz_h.1k.OK" - test $COMMON_BUFSIZE -gt $((1024+32)) && echo "Rerun make to use larger COMMON_BUFSIZE" + echo $TAIL_SIZE >"$common_bufsiz_h.1k.OK" + round_down_COMMON_BUFSIZE $TAIL_SIZE + # emit message only if COMMON_BUFSIZE is indeed larger + test $COMMON_BUFSIZE -gt $PREV_BUFSIZE \ + && echo "Rerun make to use larger COMMON_BUFSIZE ($COMMON_BUFSIZE)" +#TODO: test $PREV_BUFSIZE -lt $TAIL_SIZE && PANIC!!! +#Code size with COMMON_BUFSIZE > 1024 may be bigger than code with COMMON_BUFSIZE = 1024! +#(currently we just hope "-32 and round down to 32" saves us) + + test $COMMON_BUFSIZE = 1024 && generate_1k_and_exit + generate_big_and_exit $COMMON_BUFSIZE "big" fi fi fi @@ -127,13 +154,12 @@ fi if test -f "$common_bufsiz_h.1k.OK"; then # Previous build succeeded fitting 1k into _end[]. # Try bigger COMMON_BUFSIZE if possible. - COMMON_BUFSIZE=`cat -- "$common_bufsiz_h.1k.OK"` - # Round down a bit - COMMON_BUFSIZE=$(( (COMMON_BUFSIZE-32) & 0xfffffe0 )) - COMMON_BUFSIZE=$(( COMMON_BUFSIZE < 1024 ? 1024 : COMMON_BUFSIZE )) + TAIL_SIZE=`cat -- "$common_bufsiz_h.1k.OK"` + round_down_COMMON_BUFSIZE $TAIL_SIZE test $COMMON_BUFSIZE = 1024 && generate_1k_and_exit generate_big_and_exit $COMMON_BUFSIZE "big" fi + if test -f "$common_bufsiz_h.1k.FAIL"; then # Previous build FAILED to fit 1k into _end[]. # Was it with same .config? @@ -142,6 +168,7 @@ if test -f "$common_bufsiz_h.1k.FAIL"; then # If yes, then build a "malloced" version if test x"$oldcfg" = x"$curcfg"; then echo "Will not try 1k build, it failed before. Touch .config to override" +# Note: here we can do either a "malloc" or "std" build. generate_malloc_and_exit fi # else: try 1k version @@ -149,5 +176,6 @@ if test -f "$common_bufsiz_h.1k.FAIL"; then rm -- "$common_bufsiz_h.1k.FAIL" generate_1k_and_exit fi + # There was no 1k build yet. Try it. generate_1k_and_exit From cbdff15bb78ba9d83be7f6b5087ee665715999b0 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Sun, 24 Apr 2016 16:18:03 +0200 Subject: [PATCH 236/260] sed: understand \n,\r and \t in i and a commands. Closes 8871 Signed-off-by: Denys Vlasenko --- editors/sed.c | 38 +++++++++++++++++++++++++------------- testsuite/sed.tests | 18 ++++++++++++++++++ 2 files changed, 43 insertions(+), 13 deletions(-) diff --git a/editors/sed.c b/editors/sed.c index 6bce25b2c..7f18fd0c4 100644 --- a/editors/sed.c +++ b/editors/sed.c @@ -218,23 +218,33 @@ static void cleanup_outname(void) /* strcpy, replacing "\from" with 'to'. If to is NUL, replacing "\any" with 'any' */ -static void parse_escapes(char *dest, const char *string, int len, char from, char to) +static unsigned parse_escapes(char *dest, const char *string, int len, char from, char to) { + char *d = dest; int i = 0; + if (len == -1) + len = strlen(string); + while (i < len) { if (string[i] == '\\') { if (!to || string[i+1] == from) { - *dest++ = to ? to : string[i+1]; + if ((*d = to ? to : string[i+1]) == '\0') + return d - dest; i += 2; + d++; continue; } - *dest++ = string[i++]; + i++; /* skip backslash in string[] */ + *d++ = '\\'; + /* fall through: copy next char verbatim */ } - /* TODO: is it safe wrt a string with trailing '\\' ? */ - *dest++ = string[i++]; + if ((*d = string[i++]) == '\0') + return d - dest; + d++; } - *dest = '\0'; + *d = '\0'; + return d - dest; } static char *copy_parsing_escapes(const char *string, int len) @@ -245,9 +255,8 @@ static char *copy_parsing_escapes(const char *string, int len) /* sed recognizes \n */ /* GNU sed also recognizes \t and \r */ for (s = "\nn\tt\rr"; *s; s += 2) { - parse_escapes(dest, string, len, s[1], s[0]); + len = parse_escapes(dest, string, len, s[1], s[0]); string = dest; - len = strlen(dest); } return dest; } @@ -516,6 +525,8 @@ static const char *parse_cmd_args(sed_cmd_t *sed_cmd, const char *cmdstr) } /* handle edit cmds: (a)ppend, (i)nsert, and (c)hange */ else if (idx <= IDX_c) { /* a,i,c */ + unsigned len; + if (idx < IDX_c) { /* a,i */ if (sed_cmd->end_line || sed_cmd->end_match) bb_error_msg_and_die("command '%c' uses only one address", sed_cmd->cmd); @@ -529,10 +540,11 @@ static const char *parse_cmd_args(sed_cmd_t *sed_cmd, const char *cmdstr) break; cmdstr++; } - sed_cmd->string = xstrdup(cmdstr); + len = strlen(cmdstr); + sed_cmd->string = copy_parsing_escapes(cmdstr, len); + cmdstr += len; /* "\anychar" -> "anychar" */ - parse_escapes(sed_cmd->string, sed_cmd->string, strlen(cmdstr), '\0', '\0'); - cmdstr += strlen(cmdstr); + parse_escapes(sed_cmd->string, sed_cmd->string, -1, '\0', '\0'); } /* handle file cmds: (r)ead */ else if (idx <= IDX_w) { /* r,w */ @@ -564,8 +576,8 @@ static const char *parse_cmd_args(sed_cmd_t *sed_cmd, const char *cmdstr) cmdstr += parse_regex_delim(cmdstr, &match, &replace)+1; /* \n already parsed, but \delimiter needs unescaping. */ - parse_escapes(match, match, strlen(match), i, i); - parse_escapes(replace, replace, strlen(replace), i, i); + parse_escapes(match, match, -1, i, i); + parse_escapes(replace, replace, -1, i, i); sed_cmd->string = xzalloc((strlen(match) + 1) * 2); for (i = 0; match[i] && replace[i]; i++) { diff --git a/testsuite/sed.tests b/testsuite/sed.tests index 5d2356b64..c4b6fa278 100755 --- a/testsuite/sed.tests +++ b/testsuite/sed.tests @@ -275,6 +275,24 @@ testing "sed a cmd ended by double backslash" \ | two \\ ' +testing "sed a cmd understands \\n,\\t,\\r" \ + "sed '/1/a\\\\t\\rzero\\none\\\\ntwo\\\\\\nthree'" \ +"\ +line1 +\t\rzero +one\\\\ntwo\\ +three +" "" "line1\n" + +testing "sed i cmd understands \\n,\\t,\\r" \ + "sed '/1/i\\\\t\\rzero\\none\\\\ntwo\\\\\\nthree'" \ +"\ +\t\rzero +one\\\\ntwo\\ +three +line1 +" "" "line1\n" + # first three lines are deleted; 4th line is matched and printed by "2,3" and by "4" ranges testing "sed with N skipping lines past ranges on next cmds" \ "sed -n '1{N;N;d};1p;2,3p;3p;4p'" \ From 4ab372d49a6e82b0bf097dedb96d26330c5f2d5f Mon Sep 17 00:00:00 2001 From: Szabolcs Nagy Date: Sun, 24 Apr 2016 17:39:02 +0200 Subject: [PATCH 237/260] ip: fix problem on mips64 n64 big endian musl systems Use designated initializers for struct msghdr. The struct layout is non-portable and musl libc does not match what busybox expects. Signed-off-by: Szabolcs Nagy Tested-by: Waldemar Brodkorb Signed-off-by: Denys Vlasenko --- networking/libiproute/libnetlink.c | 37 +++++++++++++++++++----------- 1 file changed, 24 insertions(+), 13 deletions(-) diff --git a/networking/libiproute/libnetlink.c b/networking/libiproute/libnetlink.c index c7533a4a7..cbb5daf95 100644 --- a/networking/libiproute/libnetlink.c +++ b/networking/libiproute/libnetlink.c @@ -71,11 +71,15 @@ int FAST_FUNC rtnl_dump_request(struct rtnl_handle *rth, int type, void *req, in struct nlmsghdr nlh; struct sockaddr_nl nladdr; struct iovec iov[2] = { { &nlh, sizeof(nlh) }, { req, len } }; + /* Use designated initializers, struct layout is non-portable */ struct msghdr msg = { - (void*)&nladdr, sizeof(nladdr), - iov, 2, - NULL, 0, - 0 + .msg_name = (void*)&nladdr, + .msg_namelen = sizeof(nladdr), + .msg_iov = iov, + .msg_iovlen = 2, + .msg_control = NULL, + .msg_controllen = 0, + .msg_flags = 0 }; memset(&nladdr, 0, sizeof(nladdr)); @@ -104,12 +108,15 @@ static int rtnl_dump_filter(struct rtnl_handle *rth, while (1) { int status; struct nlmsghdr *h; - + /* Use designated initializers, struct layout is non-portable */ struct msghdr msg = { - (void*)&nladdr, sizeof(nladdr), - &iov, 1, - NULL, 0, - 0 + .msg_name = (void*)&nladdr, + .msg_namelen = sizeof(nladdr), + .msg_iov = &iov, + .msg_iovlen = 1, + .msg_control = NULL, + .msg_controllen = 0, + .msg_flags = 0 }; status = recvmsg(rth->fd, &msg, 0); @@ -211,11 +218,15 @@ int FAST_FUNC rtnl_talk(struct rtnl_handle *rtnl, struct nlmsghdr *n, struct sockaddr_nl nladdr; struct iovec iov = { (void*)n, n->nlmsg_len }; char *buf = xmalloc(8*1024); /* avoid big stack buffer */ + /* Use designated initializers, struct layout is non-portable */ struct msghdr msg = { - (void*)&nladdr, sizeof(nladdr), - &iov, 1, - NULL, 0, - 0 + .msg_name = (void*)&nladdr, + .msg_namelen = sizeof(nladdr), + .msg_iov = &iov, + .msg_iovlen = 1, + .msg_control = NULL, + .msg_controllen = 0, + .msg_flags = 0 }; memset(&nladdr, 0, sizeof(nladdr)); From e1d426fd65c00a6d01a10d85edf8a294ae8a2d2b Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Sun, 24 Apr 2016 18:19:49 +0200 Subject: [PATCH 238/260] flock: fix -c; improve error handling of fork+exec function old new delta flock_main 254 334 +80 Signed-off-by: Denys Vlasenko --- util-linux/flock.c | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/util-linux/flock.c b/util-linux/flock.c index 05a747f72..539a835b7 100644 --- a/util-linux/flock.c +++ b/util-linux/flock.c @@ -57,7 +57,6 @@ int flock_main(int argc UNUSED_PARAM, char **argv) /* If it is "flock FILE -c PROG", then -c isn't caught by getopt32: * we use "+" in order to support "flock -opt FILE PROG -with-opts", * we need to remove -c by hand. - * TODO: in upstream, -c 'PROG ARGS' means "run sh -c 'PROG ARGS'" */ if (argv[0] && argv[0][0] == '-' @@ -66,6 +65,9 @@ int flock_main(int argc UNUSED_PARAM, char **argv) ) ) { argv++; + if (argv[1]) + bb_error_msg_and_die("-c takes only one argument"); + opt |= OPT_c; } if (OPT_s == LOCK_SH && OPT_x == LOCK_EX && OPT_n == LOCK_NB && OPT_u == LOCK_UN) { @@ -90,8 +92,21 @@ int flock_main(int argc UNUSED_PARAM, char **argv) bb_perror_nomsg_and_die(); } - if (argv[0]) + if (argv[0]) { + if (!(opt & OPT_c)) { + int rc = spawn_and_wait(argv); + if (rc < 0) + bb_simple_perror_msg(argv[0]); + return rc; + } + /* -c 'PROG ARGS' means "run sh -c 'PROG ARGS'" */ + argv -= 2; + argv[0] = (char*)get_shell_name(); + argv[1] = (char*)"-c"; + /* argv[2] = "PROG ARGS"; */ + /* argv[3] = NULL; */ return spawn_and_wait(argv); + } return EXIT_SUCCESS; } From 2fbc3123a2d94a85317b2269c724939db7e18fbf Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Sun, 24 Apr 2016 18:21:32 +0200 Subject: [PATCH 239/260] flock: merge spawn_and_wait() code patchs for -c and sans-c uses function old new delta flock_main 334 319 -15 Signed-off-by: Denys Vlasenko --- util-linux/flock.c | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/util-linux/flock.c b/util-linux/flock.c index 539a835b7..1f7ade7c4 100644 --- a/util-linux/flock.c +++ b/util-linux/flock.c @@ -93,19 +93,19 @@ int flock_main(int argc UNUSED_PARAM, char **argv) } if (argv[0]) { - if (!(opt & OPT_c)) { - int rc = spawn_and_wait(argv); - if (rc < 0) - bb_simple_perror_msg(argv[0]); - return rc; + int rc; + if (opt & OPT_c) { + /* -c 'PROG ARGS' means "run sh -c 'PROG ARGS'" */ + argv -= 2; + argv[0] = (char*)get_shell_name(); + argv[1] = (char*)"-c"; + /* argv[2] = "PROG ARGS"; */ + /* argv[3] = NULL; */ } - /* -c 'PROG ARGS' means "run sh -c 'PROG ARGS'" */ - argv -= 2; - argv[0] = (char*)get_shell_name(); - argv[1] = (char*)"-c"; - /* argv[2] = "PROG ARGS"; */ - /* argv[3] = NULL; */ - return spawn_and_wait(argv); + rc = spawn_and_wait(argv); + if (rc < 0) + bb_simple_perror_msg(argv[0]); + return rc; } return EXIT_SUCCESS; From f2559e5c2b7bd2c5fa0dd8e88d0a931da92a23af Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Fri, 6 May 2016 18:25:56 +0200 Subject: [PATCH 240/260] sed: fix append command to match GNU sed 4.2.1 This closes one testcase failure Signed-off-by: Denys Vlasenko --- editors/sed.c | 29 +++++++++++++++++++---------- testsuite/sed.tests | 6 ++++-- 2 files changed, 23 insertions(+), 12 deletions(-) diff --git a/editors/sed.c b/editors/sed.c index 7f18fd0c4..f37c37d88 100644 --- a/editors/sed.c +++ b/editors/sed.c @@ -956,13 +956,22 @@ static void puts_maybe_newline(char *s, FILE *file, char *last_puts_char, char l *last_puts_char = lpc; } -static void flush_append(char *last_puts_char, char last_gets_char) +static void flush_append(char *last_puts_char) { char *data; /* Output appended lines. */ - while ((data = (char *)llist_pop(&G.append_head))) { - puts_maybe_newline(data, G.nonstdout, last_puts_char, last_gets_char); + while ((data = (char *)llist_pop(&G.append_head)) != NULL) { + /* Append command does not respect "nonterminated-ness" + * of last line. Try this: + * $ echo -n "woot" | sed -e '/woot/a woo' - + * woot + * woo + * (both lines are terminated with \n) + * Therefore we do not propagate "last_gets_char" here, + * pass '\n' instead: + */ + puts_maybe_newline(data, G.nonstdout, last_puts_char, '\n'); free(data); } } @@ -970,13 +979,13 @@ static void flush_append(char *last_puts_char, char last_gets_char) /* Get next line of input from G.input_file_list, flushing append buffer and * noting if we ran out of files without a newline on the last line we read. */ -static char *get_next_line(char *gets_char, char *last_puts_char, char last_gets_char) +static char *get_next_line(char *gets_char, char *last_puts_char) { char *temp = NULL; int len; char gc; - flush_append(last_puts_char, last_gets_char); + flush_append(last_puts_char); /* will be returned if last line in the file * doesn't end with either '\n' or '\0' */ @@ -1054,7 +1063,7 @@ static void process_files(void) int substituted; /* Prime the pump */ - next_line = get_next_line(&next_gets_char, &last_puts_char, '\n' /*last_gets_char*/); + next_line = get_next_line(&next_gets_char, &last_puts_char); /* Go through every line in each file */ again: @@ -1068,7 +1077,7 @@ static void process_files(void) /* Read one line in advance so we can act on the last line, * the '$' address */ - next_line = get_next_line(&next_gets_char, &last_puts_char, last_gets_char); + next_line = get_next_line(&next_gets_char, &last_puts_char); linenum++; /* For every line, go through all the commands */ @@ -1295,7 +1304,7 @@ static void process_files(void) free(pattern_space); pattern_space = next_line; last_gets_char = next_gets_char; - next_line = get_next_line(&next_gets_char, &last_puts_char, last_gets_char); + next_line = get_next_line(&next_gets_char, &last_puts_char); substituted = 0; linenum++; break; @@ -1331,7 +1340,7 @@ static void process_files(void) pattern_space[len] = '\n'; strcpy(pattern_space + len+1, next_line); last_gets_char = next_gets_char; - next_line = get_next_line(&next_gets_char, &last_puts_char, last_gets_char); + next_line = get_next_line(&next_gets_char, &last_puts_char); linenum++; break; } @@ -1435,7 +1444,7 @@ static void process_files(void) /* Delete and such jump here. */ discard_line: - flush_append(&last_puts_char, last_gets_char); + flush_append(&last_puts_char /*,last_gets_char*/); free(pattern_space); goto again; diff --git a/testsuite/sed.tests b/testsuite/sed.tests index c4b6fa278..a71f8b1f0 100755 --- a/testsuite/sed.tests +++ b/testsuite/sed.tests @@ -135,10 +135,12 @@ testing "sed empty file plus cat" "sed -e 's/nohit//' input -" "one\ntwo" \ "" "one\ntwo" testing "sed cat plus empty file" "sed -e 's/nohit//' input -" "one\ntwo" \ "one\ntwo" "" -test x"$SKIP_KNOWN_BUGS" = x"" && { testing "sed append autoinserts newline" "sed -e '/woot/a woo' -" \ "woot\nwoo\n" "" "woot" -} +testing "sed append autoinserts newline 2" "sed -e '/oot/a woo' - input" \ + "woot\nwoo\nboot\nwoo\n" "boot" "woot" +testing "sed append autoinserts newline 3" "sed -e '/oot/a woo' -i input && cat input" \ + "boot\nwoo\n" "boot" "" testing "sed insert doesn't autoinsert newline" "sed -e '/woot/i woo' -" \ "woo\nwoot" "" "woot" testing "sed print autoinsert newlines" "sed -e 'p' -" "one\none" "" "one" From 852e8dd734662d80aa82be802b066130af85b261 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Thu, 26 May 2016 21:35:46 +0200 Subject: [PATCH 241/260] arping: avoid use of ether_ntoa(). Closes 8926 This is the only non-debug use of ether_ntoa(). By not using it, we reduce bss: function old new delta arping_main 1568 1665 +97 static.asc 18 - -18 ether_ntoa 57 - -57 ------------------------------------------------------------------------------ (add/remove: 0/2 grow/shrink: 1/0 up/down: 97/-75) Total: 22 bytes text data bss dec hex filename 911020 493 7352 918865 e0551 busybox_old 911069 493 7336 918898 e0572 busybox_unstripped Also, "standard" arping zero-pads MAC. ether_ntoa() does not. Signed-off-by: Denys Vlasenko --- networking/arping.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/networking/arping.c b/networking/arping.c index 6b0de4de2..4f207eaa5 100644 --- a/networking/arping.c +++ b/networking/arping.c @@ -231,20 +231,23 @@ static void recv_pack(unsigned char *buf, int len, struct sockaddr_ll *FROM) if (!(option_mask32 & QUIET)) { int s_printed = 0; - printf("%scast re%s from %s [%s]", + printf("%scast re%s from %s [%02x:%02x:%02x:%02x:%02x:%02x]", FROM->sll_pkttype == PACKET_HOST ? "Uni" : "Broad", ah->ar_op == htons(ARPOP_REPLY) ? "ply" : "quest", inet_ntoa(src_ip), - ether_ntoa((struct ether_addr *) p)); + p[0], p[1], p[2], p[3], p[4], p[5] + ); if (dst_ip.s_addr != src.s_addr) { printf("for %s ", inet_ntoa(dst_ip)); s_printed = 1; } if (memcmp(p + ah->ar_hln + 4, me.sll_addr, ah->ar_hln)) { + unsigned char *pp = p + ah->ar_hln + 4; if (!s_printed) printf("for "); - printf("[%s]", - ether_ntoa((struct ether_addr *) p + ah->ar_hln + 4)); + printf("[%02x:%02x:%02x:%02x:%02x:%02x]", + pp[0], pp[1], pp[2], pp[3], pp[4], pp[5] + ); } if (last) { From 877dedb8251be47b3614a371434081ae9b7b358b Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Fri, 27 May 2016 00:46:38 +0200 Subject: [PATCH 242/260] cp: add -u/--update and --remove-destination Based on the patch by wdlkmpx@gmail.com function old new delta copy_file 1546 1644 +98 add_partition 1270 1362 +92 ask_and_unlink 95 133 +38 do_iproute 132 157 +25 decode_one_format 710 715 +5 cp_main 369 374 +5 ubirename_main 198 202 +4 read_package_field 232 230 -2 bb_make_directory 421 412 -9 packed_usage 30505 30476 -29 ------------------------------------------------------------------------------ (add/remove: 0/0 grow/shrink: 7/3 up/down: 267/-40) Total: 227 bytes Signed-off-by: Denys Vlasenko --- coreutils/cp.c | 30 ++++++++++++++++++------------ include/libbb.h | 24 +++++++++++++++++------- libbb/copy_file.c | 21 +++++++++++++++++++++ 3 files changed, 56 insertions(+), 19 deletions(-) diff --git a/coreutils/cp.c b/coreutils/cp.c index 247ed0fda..2630c0d59 100644 --- a/coreutils/cp.c +++ b/coreutils/cp.c @@ -31,6 +31,7 @@ //usage: "\n -f Overwrite" //usage: "\n -i Prompt before overwrite" //usage: "\n -l,-s Create (sym)links" +//usage: "\n -u Copy only newer files" #include "libbb.h" #include "libcoreutils/coreutils.h" @@ -49,12 +50,10 @@ int cp_main(int argc, char **argv) int flags; int status; enum { - OPT_a = 1 << (sizeof(FILEUTILS_CP_OPTSTR)-1), - OPT_r = 1 << (sizeof(FILEUTILS_CP_OPTSTR)), - OPT_P = 1 << (sizeof(FILEUTILS_CP_OPTSTR)+1), - OPT_v = 1 << (sizeof(FILEUTILS_CP_OPTSTR)+2), + FILEUTILS_CP_OPTNUM = sizeof(FILEUTILS_CP_OPTSTR)-1, #if ENABLE_FEATURE_CP_LONG_OPTIONS - OPT_parents = 1 << (sizeof(FILEUTILS_CP_OPTSTR)+3), + /*OPT_rmdest = FILEUTILS_RMDEST = 1 << FILEUTILS_CP_OPTNUM */ + OPT_parents = 1 << (FILEUTILS_CP_OPTNUM+1), #endif }; @@ -76,10 +75,12 @@ int cp_main(int argc, char **argv) "recursive\0" No_argument "R" "symbolic-link\0" No_argument "s" "verbose\0" No_argument "v" - "parents\0" No_argument "\xff" + "update\0" No_argument "u" + "remove-destination\0" No_argument "\xff" + "parents\0" No_argument "\xfe" ; #endif - flags = getopt32(argv, FILEUTILS_CP_OPTSTR "arPv"); + flags = getopt32(argv, FILEUTILS_CP_OPTSTR); /* Options of cp from GNU coreutils 6.10: * -a, --archive * -f, --force @@ -94,6 +95,11 @@ int cp_main(int argc, char **argv) * -d same as --no-dereference --preserve=links * -p same as --preserve=mode,ownership,timestamps * -c same as --preserve=context + * -u, --update + * copy only when the SOURCE file is newer than the destination + * file or when the destination file is missing + * --remove-destination + * remove each existing destination file before attempting to open * --parents * use full source file name under DIRECTORY * NOT SUPPORTED IN BBOX: @@ -106,8 +112,6 @@ int cp_main(int argc, char **argv) * preserve attributes (default: mode,ownership,timestamps), * if possible additional attributes: security context,links,all * --no-preserve=ATTR_LIST - * --remove-destination - * remove each existing destination file before attempting to open * --sparse=WHEN * control creation of sparse files * --strip-trailing-slashes @@ -118,9 +122,6 @@ int cp_main(int argc, char **argv) * copy all SOURCE arguments into DIRECTORY * -T, --no-target-directory * treat DEST as a normal file - * -u, --update - * copy only when the SOURCE file is newer than the destination - * file or when the destination file is missing * -x, --one-file-system * stay on this file system * -Z, --context=CONTEXT @@ -156,11 +157,16 @@ int cp_main(int argc, char **argv) return EXIT_FAILURE; #if ENABLE_FEATURE_CP_LONG_OPTIONS + //bb_error_msg("flags:%x FILEUTILS_RMDEST:%x OPT_parents:%x", + // flags, FILEUTILS_RMDEST, OPT_parents); if (flags & OPT_parents) { if (!(d_flags & 2)) { bb_error_msg_and_die("with --parents, the destination must be a directory"); } } + if (flags & FILEUTILS_RMDEST) { + flags |= FILEUTILS_FORCE; + } #endif /* ...if neither is a directory... */ diff --git a/include/libbb.h b/include/libbb.h index fd40ef74c..a21f4204a 100644 --- a/include/libbb.h +++ b/include/libbb.h @@ -351,7 +351,7 @@ extern char *strrstr(const char *haystack, const char *needle) FAST_FUNC; //TODO: supply a pointer to char[11] buffer (avoid statics)? extern const char *bb_mode_string(mode_t mode) FAST_FUNC; extern int is_directory(const char *name, int followLinks) FAST_FUNC; -enum { /* DO NOT CHANGE THESE VALUES! cp.c, mv.c, install.c depend on them. */ +enum { /* cp.c, mv.c, install.c depend on these values. CAREFUL when changing them! */ FILEUTILS_PRESERVE_STATUS = 1 << 0, /* -p */ FILEUTILS_DEREFERENCE = 1 << 1, /* !-d */ FILEUTILS_RECUR = 1 << 2, /* -R */ @@ -361,15 +361,25 @@ enum { /* DO NOT CHANGE THESE VALUES! cp.c, mv.c, install.c depend on them. */ FILEUTILS_MAKE_SOFTLINK = 1 << 6, /* -s */ FILEUTILS_DEREF_SOFTLINK = 1 << 7, /* -L */ FILEUTILS_DEREFERENCE_L0 = 1 << 8, /* -H */ + /* -a = -pdR (mapped in cp.c) */ + /* -r = -dR (mapped in cp.c) */ + /* -P = -d (mapped in cp.c) */ + FILEUTILS_VERBOSE = (1 << 12) * ENABLE_FEATURE_VERBOSE, /* -v */ + FILEUTILS_UPDATE = 1 << 13, /* -u */ #if ENABLE_SELINUX - FILEUTILS_PRESERVE_SECURITY_CONTEXT = 1 << 9, /* -c */ - FILEUTILS_SET_SECURITY_CONTEXT = 1 << 10, + FILEUTILS_PRESERVE_SECURITY_CONTEXT = 1 << 14, /* -c */ #endif - FILEUTILS_IGNORE_CHMOD_ERR = 1 << 11, - /* -v */ - FILEUTILS_VERBOSE = (1 << 12) * ENABLE_FEATURE_VERBOSE, + FILEUTILS_RMDEST = 1 << (15 - !ENABLE_SELINUX), /* --remove-destination */ + /* + * Hole. cp may have some bits set here, + * they should not affect remove_file()/copy_file() + */ +#if ENABLE_SELINUX + FILEUTILS_SET_SECURITY_CONTEXT = 1 << 30, +#endif + FILEUTILS_IGNORE_CHMOD_ERR = 1 << 31, }; -#define FILEUTILS_CP_OPTSTR "pdRfilsLH" IF_SELINUX("c") +#define FILEUTILS_CP_OPTSTR "pdRfilsLHarPvu" IF_SELINUX("c") extern int remove_file(const char *path, int flags) FAST_FUNC; /* NB: without FILEUTILS_RECUR in flags, it will basically "cat" * the source, not copy (unless "source" is a directory). diff --git a/libbb/copy_file.c b/libbb/copy_file.c index a4be875d2..23bcf2e82 100644 --- a/libbb/copy_file.c +++ b/libbb/copy_file.c @@ -64,6 +64,11 @@ static int ask_and_unlink(const char *dest, int flags) bb_perror_msg("can't create '%s'", dest); return -1; /* error */ } +#if ENABLE_FEATURE_CP_LONG_OPTIONS + if (flags & FILEUTILS_RMDEST) + if (flags & FILEUTILS_VERBOSE) + printf("removed '%s'\n", dest); +#endif return 1; /* ok (to try again) */ } @@ -210,6 +215,22 @@ int FAST_FUNC copy_file(const char *source, const char *dest, int flags) goto preserve_mode_ugid_time; } + if (dest_exists) { + if (flags & FILEUTILS_UPDATE) { + if (source_stat.st_mtime <= dest_stat.st_mtime) { + return 0; /* source file must be newer */ + } + } +#if ENABLE_FEATURE_CP_LONG_OPTIONS + if (flags & FILEUTILS_RMDEST) { + ovr = ask_and_unlink(dest, flags); + if (ovr <= 0) + return ovr; + dest_exists = 0; + } +#endif + } + if (flags & (FILEUTILS_MAKE_SOFTLINK|FILEUTILS_MAKE_HARDLINK)) { int (*lf)(const char *oldpath, const char *newpath); make_links: From 8e95068c7f28fe2a1e31b01636e3ed29eed09ef8 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Tue, 31 May 2016 02:42:49 +0200 Subject: [PATCH 243/260] Make busybox an optional applet If it's disabled, code shrinks by about 900 bytes: function old new delta usr_bin 10 - -10 usr_sbin 11 - -11 install_dir 20 - -20 applet_install_loc 184 - -184 run_applet_and_exit 686 21 -665 ------------------------------------------------------------------------------ (add/remove: 0/4 grow/shrink: 0/1 up/down: 0/-890) Total: -890 bytes text data bss dec hex filename 911327 493 7336 919156 e0674 busybox_old 909848 493 7336 917677 e00ad busybox_unstripped but busybox executable by itself does not say anything useful: $ busybox busybox: applet not found Based on the patch by Ron Yorston Signed-off-by: Denys Vlasenko --- Config.in | 12 ++++++++++++ libbb/appletlib.c | 10 +++++++--- 2 files changed, 19 insertions(+), 3 deletions(-) diff --git a/Config.in b/Config.in index 0a0b5d7cb..3d1870966 100644 --- a/Config.in +++ b/Config.in @@ -116,9 +116,21 @@ config FEATURE_COMPRESS_USAGE and have very little memory, this might not be a win. Otherwise, you probably want this. +config BUSYBOX + bool "Include busybox applet" + default y + help + The busybox applet provides general help regarding busybox and + allows the included applets to be listed. It's also required + if applet links are to be installed at runtime. + + If you can live without these features disabling this will save + some space. + config FEATURE_INSTALLER bool "Support --install [-s] to install applet links at runtime" default y + depends on BUSYBOX help Enable 'busybox --install [-s]' support. This will allow you to use busybox at runtime to create hard links or symlinks for all the diff --git a/libbb/appletlib.c b/libbb/appletlib.c index b682e6b85..281123c37 100644 --- a/libbb/appletlib.c +++ b/libbb/appletlib.c @@ -701,7 +701,7 @@ static void install_links(const char *busybox, int use_symbolic_links, continue; } } -# else +# elif ENABLE_BUSYBOX static void install_links(const char *busybox UNUSED_PARAM, int use_symbolic_links UNUSED_PARAM, char *custom_install_dir UNUSED_PARAM) @@ -709,6 +709,7 @@ static void install_links(const char *busybox UNUSED_PARAM, } # endif +# if ENABLE_BUSYBOX /* If we were called as "busybox..." */ static int busybox_main(char **argv) { @@ -784,10 +785,10 @@ static int busybox_main(char **argv) const char *a = applet_names; dup2(1, 2); while (*a) { -# if ENABLE_FEATURE_INSTALLER +# if ENABLE_FEATURE_INSTALLER if (argv[1][6]) /* --list-full? */ full_write2_str(install_dir[APPLET_INSTALL_LOC(i)] + 1); -# endif +# endif full_write2_str(a); full_write2_str("\n"); i++; @@ -843,6 +844,7 @@ static int busybox_main(char **argv) /* POSIX: "If a command is not found, the exit status shall be 127" */ exit(127); } +# endif void FAST_FUNC run_applet_no_and_exit(int applet_no, char **argv) { @@ -886,8 +888,10 @@ void FAST_FUNC run_applet_and_exit(const char *name, char **argv) { int applet; +# if ENABLE_BUSYBOX if (is_prefixed_with(name, "busybox")) exit(busybox_main(argv)); +# endif /* find_applet_by_name() search is more expensive, so goes second */ applet = find_applet_by_name(name); if (applet >= 0) From b684d1b1864ba9d7968de5565823f8e42f1dc448 Mon Sep 17 00:00:00 2001 From: Natanael Copa Date: Thu, 19 May 2016 17:31:59 +0200 Subject: [PATCH 244/260] libbb: fix time parsing of [[CC]YY]MMDDhhmm[.SS]. Closes 8951 If SS is not given a value, it is assumed to be zero. http://pubs.opengroup.org/onlinepubs/9699919799/utilities/touch.html Signed-off-by: Natanael Copa Signed-off-by: Denys Vlasenko --- libbb/time.c | 1 + 1 file changed, 1 insertion(+) diff --git a/libbb/time.c b/libbb/time.c index aa19a47d4..82e6cb172 100644 --- a/libbb/time.c +++ b/libbb/time.c @@ -186,6 +186,7 @@ void FAST_FUNC parse_datestr(const char *date_str, struct tm *ptm) } else { bb_error_msg_and_die(bb_msg_invalid_date, date_str); } + ptm->tm_sec = 0; /* assume zero if [.SS] is not given */ if (end == '.') { /* xxx.SS */ if (sscanf(strchr(date_str, '.') + 1, "%u%c", From e4caf1dd9ce8569371a0eeb77ccf02a572dc0f11 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Mon, 6 Jun 2016 02:26:49 +0200 Subject: [PATCH 245/260] ntpd: retry initial DNS resolution (forever, no timeout for now). Some users start ntpd on boot, and don't babysit it. If it dies because DNS is not yet up and therefore NTP servers can't be found, users are not happy. Example behavior with a peer name which can't be resolved: ntpd: bad address 'qwe.rty.ghj.kl' ...5 sec... ntpd: bad address 'qwe.rty.ghj.kl' ntpd: bad address 'qwe.rty.ghj.kl' ntpd: bad address 'qwe.rty.ghj.kl' ntpd: bad address 'qwe.rty.ghj.kl' ntpd: bad address 'qwe.rty.ghj.kl' ntpd: bad address 'qwe.rty.ghj.kl' ntpd: bad address 'qwe.rty.ghj.kl' ntpd: bad address 'qwe.rty.ghj.kl' ntpd: bad address 'qwe.rty.ghj.kl' ... Based on the patch by Kaarle Ritvanen function old new delta resolve_peer_hostname - 81 +81 ntpd_main 1130 1061 -69 ------------------------------------------------------------------------------ (add/remove: 1/0 grow/shrink: 0/1 up/down: 81/-69) Total: 12 bytes Signed-off-by: Denys Vlasenko --- networking/ntpd.c | 47 ++++++++++++++++++++++++++++++----------------- 1 file changed, 30 insertions(+), 17 deletions(-) diff --git a/networking/ntpd.c b/networking/ntpd.c index 410318979..98158a304 100644 --- a/networking/ntpd.c +++ b/networking/ntpd.c @@ -267,7 +267,6 @@ typedef struct { typedef struct { len_and_sockaddr *p_lsa; - char *p_hostname; char *p_dotted; int p_fd; int datapoint_idx; @@ -293,6 +292,7 @@ typedef struct { datapoint_t filter_datapoint[NUM_DATAPOINTS]; /* last sent packet: */ msg_t p_xmt_msg; + char p_hostname[1]; } peer_t; @@ -764,15 +764,39 @@ reset_peer_stats(peer_t *p, double offset) VERB6 bb_error_msg("%s->lastpkt_recv_time=%f", p->p_dotted, p->lastpkt_recv_time); } +static void +resolve_peer_hostname(peer_t *p, int loop_on_fail) +{ + len_and_sockaddr *lsa; + + again: + lsa = host2sockaddr(p->p_hostname, 123); + if (!lsa) { + /* error message already emitted by host2sockaddr() */ + if (!loop_on_fail) + return; +//FIXME: do this to avoid infinite looping on typo in a hostname? +//well... in which case, what is a good value for loop_on_fail? + //if (--loop_on_fail == 0) + // xfunc_die(); + sleep(5); + goto again; + } + free(p->p_lsa); + free(p->p_dotted); + p->p_lsa = lsa; + p->p_dotted = xmalloc_sockaddr2dotted_noport(&lsa->u.sa); +} + static void add_peers(const char *s) { llist_t *item; peer_t *p; - p = xzalloc(sizeof(*p)); - p->p_lsa = xhost2sockaddr(s, 123); - p->p_dotted = xmalloc_sockaddr2dotted_noport(&p->p_lsa->u.sa); + p = xzalloc(sizeof(*p) + strlen(s)); + strcpy(p->p_hostname, s); + resolve_peer_hostname(p, /*loop_on_fail=*/ 1); /* Names like N..pool.ntp.org are randomly resolved * to a pool of machines. Sometimes different N's resolve to the same IP. @@ -789,7 +813,6 @@ add_peers(const char *s) } } - p->p_hostname = xstrdup(s); p->p_fd = -1; p->p_xmt_msg.m_status = MODE_CLIENT | (NTP_VERSION << 3); p->next_action_time = G.cur_time; /* = set_next(p, 0); */ @@ -2338,18 +2361,8 @@ int ntpd_main(int argc UNUSED_PARAM, char **argv) p->p_dotted, p->reachable_bits, timeout); /* What if don't see it because it changed its IP? */ - if (p->reachable_bits == 0) { - len_and_sockaddr *lsa = host2sockaddr(p->p_hostname, 123); - if (lsa) { - char *dotted = xmalloc_sockaddr2dotted_noport(&lsa->u.sa); - //if (strcmp(dotted, p->p_dotted) != 0) - // bb_error_msg("peer IP changed"); - free(p->p_lsa); - free(p->p_dotted); - p->p_lsa = lsa; - p->p_dotted = dotted; - } - } + if (p->reachable_bits == 0) + resolve_peer_hostname(p, /*loop_on_fail=*/ 0); set_next(p, timeout); } From ba12081a9e9b2d90d1924546bc9097abf52cf2b5 Mon Sep 17 00:00:00 2001 From: Ron Yorston Date: Tue, 7 Jun 2016 10:26:24 +0100 Subject: [PATCH 246/260] Allow "busybox " to work when busybox is disabled A recent commit made it possible to disable BusyBox's --install and --list options. However it also stopped "busybox " from working. Signed-off-by: Ron Yorston Signed-off-by: Denys Vlasenko --- libbb/appletlib.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/libbb/appletlib.c b/libbb/appletlib.c index 281123c37..b6fe1dad2 100644 --- a/libbb/appletlib.c +++ b/libbb/appletlib.c @@ -956,6 +956,10 @@ int main(int argc UNUSED_PARAM, char **argv) #else lbb_prepare("busybox" IF_FEATURE_INDIVIDUAL(, argv)); +#if !ENABLE_BUSYBOX + if (argv[1] && is_prefixed_with(bb_basename(argv[0]), "busybox")) + argv++; +#endif applet_name = argv[0]; if (applet_name[0] == '-') applet_name++; From ce824aecf216536beed00d7817a614ffb8572239 Mon Sep 17 00:00:00 2001 From: Ron Yorston Date: Tue, 7 Jun 2016 12:12:07 +0100 Subject: [PATCH 247/260] libbb: move common code into run_applet_and_exit Both calls to run_applet_and_exit are followed by the same code to print an error message and return status 127. Remove this duplication and make run_applet_and_exit static. function old new delta run_applet_and_exit 675 667 -8 main 119 92 -27 ------------------------------------------------------------------------------ (add/remove: 0/0 grow/shrink: 0/2 up/down: 0/-35) Total: -35 bytes Signed-off-by: Ron Yorston Signed-off-by: Denys Vlasenko --- include/libbb.h | 2 -- libbb/appletlib.c | 21 ++++++++------------- 2 files changed, 8 insertions(+), 15 deletions(-) diff --git a/include/libbb.h b/include/libbb.h index a21f4204a..e39021eb1 100644 --- a/include/libbb.h +++ b/include/libbb.h @@ -1239,8 +1239,6 @@ const struct hwtype *get_hwntype(int type) FAST_FUNC; #ifndef BUILD_INDIVIDUAL extern int find_applet_by_name(const char *name) FAST_FUNC; -/* Returns only if applet is not found. */ -extern void run_applet_and_exit(const char *name, char **argv) FAST_FUNC; extern void run_applet_no_and_exit(int a, char **argv) NORETURN FAST_FUNC; #endif diff --git a/libbb/appletlib.c b/libbb/appletlib.c index b6fe1dad2..480bf50fc 100644 --- a/libbb/appletlib.c +++ b/libbb/appletlib.c @@ -52,6 +52,7 @@ #include "usage_compressed.h" +static void run_applet_and_exit(const char *name, char **argv) NORETURN; #if ENABLE_SHOW_USAGE && !ENABLE_FEATURE_COMPRESS_USAGE static const char usage_messages[] ALIGN1 = UNPACKED_USAGE; @@ -837,12 +838,6 @@ static int busybox_main(char **argv) * "#!/bin/busybox"-style wrappers */ applet_name = bb_get_last_path_component_nostrip(argv[0]); run_applet_and_exit(applet_name, argv); - - /*bb_error_msg_and_die("applet not found"); - sucks in printf */ - full_write2_str(applet_name); - full_write2_str(": applet not found\n"); - /* POSIX: "If a command is not found, the exit status shall be 127" */ - exit(127); } # endif @@ -884,7 +879,7 @@ void FAST_FUNC run_applet_no_and_exit(int applet_no, char **argv) exit(applet_main[applet_no](argc, argv)); } -void FAST_FUNC run_applet_and_exit(const char *name, char **argv) +static NORETURN void run_applet_and_exit(const char *name, char **argv) { int applet; @@ -896,6 +891,12 @@ void FAST_FUNC run_applet_and_exit(const char *name, char **argv) applet = find_applet_by_name(name); if (applet >= 0) run_applet_no_and_exit(applet, argv); + + /*bb_error_msg_and_die("applet not found"); - links in printf */ + full_write2_str(applet_name); + full_write2_str(": applet not found\n"); + /* POSIX: "If a command is not found, the exit status shall be 127" */ + exit(127); } #endif /* !defined(SINGLE_APPLET_MAIN) */ @@ -968,11 +969,5 @@ int main(int argc UNUSED_PARAM, char **argv) parse_config_file(); /* ...maybe, if FEATURE_SUID_CONFIG */ run_applet_and_exit(applet_name, argv); - - /*bb_error_msg_and_die("applet not found"); - sucks in printf */ - full_write2_str(applet_name); - full_write2_str(": applet not found\n"); - /* POSIX: "If a command is not found, the exit status shall be 127" */ - exit(127); #endif } From 015db5800ca7c6dd2d201eacb2951e72e6782b30 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Sun, 19 Jun 2016 18:15:33 +0200 Subject: [PATCH 248/260] randomconfig fixes Signed-off-by: Denys Vlasenko --- archival/libarchive/get_header_tar.c | 23 ++++++++++++++++------- archival/tar.c | 6 ++++-- miscutils/Kbuild.src | 9 +++++++-- modutils/modprobe-small.c | 1 - scripts/kconfig/zconf.hash.c_shipped | 14 ++------------ scripts/randomtest | 20 ++++++++++++++++++++ testsuite/busybox.tests | 16 ++++++++++------ testsuite/du/du-m-works | 2 +- util-linux/fbset.c | 5 +++-- util-linux/fdisk_osf.c | 3 ++- util-linux/fdisk_sgi.c | 27 +++++++++++++++------------ 11 files changed, 80 insertions(+), 46 deletions(-) diff --git a/archival/libarchive/get_header_tar.c b/archival/libarchive/get_header_tar.c index ac2be726f..ea91a883e 100644 --- a/archival/libarchive/get_header_tar.c +++ b/archival/libarchive/get_header_tar.c @@ -60,13 +60,21 @@ static unsigned long long getOctal(char *str, int len) } #define GET_OCTAL(a) getOctal((a), sizeof(a)) +#define TAR_EXTD (ENABLE_FEATURE_TAR_GNU_EXTENSIONS || ENABLE_FEATURE_TAR_SELINUX) +#if !TAR_EXTD +#define process_pax_hdr(archive_handle, sz, global) \ + process_pax_hdr(archive_handle, sz) +#endif /* "global" is 0 or 1 */ static void process_pax_hdr(archive_handle_t *archive_handle, unsigned sz, int global) { +#if !TAR_EXTD + unsigned blk_sz = (sz + 511) & (~511); + seek_by_read(archive_handle->src_fd, blk_sz); +#else + unsigned blk_sz = (sz + 511) & (~511); char *buf, *p; - unsigned blk_sz; - blk_sz = (sz + 511) & (~511); p = buf = xmalloc(blk_sz + 1); xread(archive_handle->src_fd, buf, blk_sz); archive_handle->offset += blk_sz; @@ -104,30 +112,31 @@ static void process_pax_hdr(archive_handle_t *archive_handle, unsigned sz, int g p[-1] = '\0'; value = end + 1; -#if ENABLE_FEATURE_TAR_GNU_EXTENSIONS +# if ENABLE_FEATURE_TAR_GNU_EXTENSIONS if (!global && is_prefixed_with(value, "path=")) { value += sizeof("path=") - 1; free(archive_handle->tar__longname); archive_handle->tar__longname = xstrdup(value); continue; } -#endif +# endif -#if ENABLE_FEATURE_TAR_SELINUX +# if ENABLE_FEATURE_TAR_SELINUX /* Scan for SELinux contexts, via "RHT.security.selinux" keyword. * This is what Red Hat's patched version of tar uses. */ -# define SELINUX_CONTEXT_KEYWORD "RHT.security.selinux" +# define SELINUX_CONTEXT_KEYWORD "RHT.security.selinux" if (is_prefixed_with(value, SELINUX_CONTEXT_KEYWORD"=")) { value += sizeof(SELINUX_CONTEXT_KEYWORD"=") - 1; free(archive_handle->tar__sctx[global]); archive_handle->tar__sctx[global] = xstrdup(value); continue; } -#endif +# endif } free(buf); +#endif } char FAST_FUNC get_header_tar(archive_handle_t *archive_handle) diff --git a/archival/tar.c b/archival/tar.c index 346a9404e..7434e22e4 100644 --- a/archival/tar.c +++ b/archival/tar.c @@ -1199,9 +1199,10 @@ int tar_main(int argc UNUSED_PARAM, char **argv) // /* We need to know whether child (gzip/bzip/etc) exits abnormally */ // signal(SIGCHLD, check_errors_in_children); +#if ENABLE_FEATURE_TAR_CREATE /* Create an archive */ if (opt & OPT_CREATE) { -#if SEAMLESS_COMPRESSION +# if SEAMLESS_COMPRESSION const char *zipMode = NULL; if (opt & OPT_COMPRESS) zipMode = "compress"; @@ -1213,7 +1214,7 @@ int tar_main(int argc UNUSED_PARAM, char **argv) zipMode = "lzma"; if (opt & OPT_XZ) zipMode = "xz"; -#endif +# endif /* NB: writeTarFile() closes tar_handle->src_fd */ return writeTarFile(tar_handle->src_fd, verboseFlag, (opt & OPT_DEREFERENCE ? ACTION_FOLLOWLINKS : 0) @@ -1221,6 +1222,7 @@ int tar_main(int argc UNUSED_PARAM, char **argv) tar_handle->accept, tar_handle->reject, zipMode); } +#endif if (opt & OPT_ANY_COMPRESS) { USE_FOR_MMU(IF_DESKTOP(long long) int FAST_FUNC (*xformer)(transformer_state_t *xstate);) diff --git a/miscutils/Kbuild.src b/miscutils/Kbuild.src index 7b449e6e8..503f54904 100644 --- a/miscutils/Kbuild.src +++ b/miscutils/Kbuild.src @@ -25,8 +25,13 @@ lib-$(CONFIG_FLASH_UNLOCK) += flash_lock_unlock.o lib-$(CONFIG_IONICE) += ionice.o lib-$(CONFIG_HDPARM) += hdparm.o lib-$(CONFIG_INOTIFYD) += inotifyd.o -lib-$(CONFIG_FEATURE_LAST_SMALL)+= last.o -lib-$(CONFIG_FEATURE_LAST_FANCY)+= last_fancy.o + +ifeq ($(CONFIG_FEATURE_LAST_FANCY),y) +lib-$(CONFIG_FEATURE_LAST_FANCY) += last_fancy.o +else +lib-$(CONFIG_LAST) += last.o +endif + lib-$(CONFIG_LESS) += less.o lib-$(CONFIG_MAKEDEVS) += makedevs.o lib-$(CONFIG_MAN) += man.o diff --git a/modutils/modprobe-small.c b/modutils/modprobe-small.c index 9c941064b..ffb46e6be 100644 --- a/modutils/modprobe-small.c +++ b/modutils/modprobe-small.c @@ -21,7 +21,6 @@ extern int init_module(void *module, unsigned long len, const char *options); extern int delete_module(const char *module, unsigned flags); -extern int query_module(const char *name, int which, void *buf, size_t bufsize, size_t *ret); /* linux/include/linux/module.h has limit of 64 chars on module names */ #undef MODULE_NAME_LEN #define MODULE_NAME_LEN 64 diff --git a/scripts/kconfig/zconf.hash.c_shipped b/scripts/kconfig/zconf.hash.c_shipped index d39cf189a..29d9cf6cc 100644 --- a/scripts/kconfig/zconf.hash.c_shipped +++ b/scripts/kconfig/zconf.hash.c_shipped @@ -32,14 +32,7 @@ struct kconf_id; /* maximum key range = 45, duplicates = 0 */ -#ifdef __GNUC__ -__inline -#else -#ifdef __cplusplus -inline -#endif -#endif -static unsigned int +unsigned int kconf_id_hash (register const char *str, register unsigned int len) { static unsigned char asso_values[] = @@ -119,7 +112,7 @@ struct kconf_id_strings_t char kconf_id_strings_str41[sizeof("choice")]; char kconf_id_strings_str46[sizeof("prompt")]; }; -static struct kconf_id_strings_t kconf_id_strings_contents = +struct kconf_id_strings_t kconf_id_strings_contents = { "if", "int", @@ -153,9 +146,6 @@ static struct kconf_id_strings_t kconf_id_strings_contents = "prompt" }; #define kconf_id_strings ((const char *) &kconf_id_strings_contents) -#ifdef __GNUC__ -__inline -#endif struct kconf_id * kconf_id_lookup (register const char *str, register unsigned int len) { diff --git a/scripts/randomtest b/scripts/randomtest index e2513d058..41f252ad7 100755 --- a/scripts/randomtest +++ b/scripts/randomtest @@ -52,9 +52,18 @@ echo '# CONFIG_RFKILL is not set' >>.config if test x"$LIBC" = x"glibc"; then cat .config \ | grep -v CONFIG_STATIC \ + \ + | grep -v CONFIG_FEATURE_2_4_MODULES \ + | grep -v CONFIG_FEATURE_USE_BSS_TAIL \ + | grep -v CONFIG_DEBUG_SANITIZE \ >.config.new mv .config.new .config echo '# CONFIG_STATIC is not set' >>.config + # newer glibc (at least 2.23) no longer supply query_module() ABI. + # People who target 2.4 kernels would likely use older glibc (and older bbox). + echo '# CONFIG_FEATURE_2_4_MODULES is not set' >>.config + echo '# CONFIG_FEATURE_USE_BSS_TAIL is not set' >>.config + echo '# CONFIG_DEBUG_SANITIZE is not set' >>.config fi # If uclibc, build static, and remove some things @@ -68,6 +77,11 @@ if test x"$LIBC" = x"uclibc"; then | grep -v CONFIG_FEATURE_2_4_MODULES \ | grep -v CONFIG_FEATURE_SYNC_FANCY \ | grep -v CONFIG_FEATURE_TOUCH_NODEREF \ + | grep -v CONFIG_NANDWRITE \ + | grep -v CONFIG_NANDDUMP \ + | grep -v CONFIG_BLKDISCARD \ + | grep -v CONFIG_NSENTER \ + | grep -v CONFIG_UNSHARE \ >.config.new mv .config.new .config echo 'CONFIG_STATIC=y' >>.config @@ -76,6 +90,12 @@ if test x"$LIBC" = x"uclibc"; then echo '# CONFIG_FEATURE_2_4_MODULES is not set' >>.config echo '# CONFIG_FEATURE_SYNC_FANCY is not set' >>.config echo '# CONFIG_FEATURE_TOUCH_NODEREF is not set' >>.config + # My uclibc installation does not support some needed APIs... + echo '# CONFIG_NANDWRITE is not set' >>.config + echo '# CONFIG_NANDDUMP is not set' >>.config + echo '# CONFIG_BLKDISCARD is not set' >>.config + echo '# CONFIG_NSENTER is not set' >>.config + echo '# CONFIG_UNSHARE is not set' >>.config fi # If STATIC, remove some things. diff --git a/testsuite/busybox.tests b/testsuite/busybox.tests index 04fea3ea2..545cad5c0 100755 --- a/testsuite/busybox.tests +++ b/testsuite/busybox.tests @@ -6,6 +6,16 @@ . ./testing.sh +ln -s `which busybox` unknown + +testing "busybox as unknown name" "./unknown 2>&1" \ + "unknown: applet not found\n" "" "" +rm unknown + +# We need busybox --help to be enabled for the rest of tests +test x"$CONFIG_BUSYBOX" = x"y" \ +|| { echo "SKIPPED: busybox --help"; exit 0; } + HELPDUMP=`true | busybox 2>&1 | cat` # We need to test under calling the binary under other names. @@ -38,10 +48,4 @@ do done rm busybox-suffix -ln -s `which busybox` unknown - -testing "busybox as unknown name" "./unknown 2>&1" \ - "unknown: applet not found\n" "" "" -rm unknown - exit $FAILCOUNT diff --git a/testsuite/du/du-m-works b/testsuite/du/du-m-works index 9fa7437ac..c96c3b359 100644 --- a/testsuite/du/du-m-works +++ b/testsuite/du/du-m-works @@ -1,4 +1,4 @@ # FEATURE: CONFIG_FEATURE_HUMAN_READABLE dd if=/dev/zero of=file bs=1M count=1 2>/dev/null -test x"`busybox du -m .`" = x"1 ." +test x"`busybox du -m file`" = x"1 ." diff --git a/util-linux/fbset.c b/util-linux/fbset.c index 09e96b763..b75ec1921 100644 --- a/util-linux/fbset.c +++ b/util-linux/fbset.c @@ -164,6 +164,7 @@ static const struct cmdoptions_t { const unsigned char code; } g_cmdoptions[] = { /*"12345678" + NUL */ +//TODO: convert to index_in_strings() { "fb" , 1, CMD_FB }, { "db" , 1, CMD_DB }, { "a" , 0, CMD_ALL }, @@ -416,7 +417,7 @@ int fbset_main(int argc, char **argv) unsigned options = 0; const char *fbdev = DEFAULTFBDEV; - const char *modefile = DEFAULTFBMODE; + IF_FEATURE_FBSET_READMODE(const char *modefile = DEFAULTFBMODE;) char *thisarg; char *mode = mode; /* for compiler */ @@ -444,7 +445,7 @@ int fbset_main(int argc, char **argv) fbdev = argv[1]; break; case CMD_DB: - modefile = argv[1]; + IF_FEATURE_FBSET_READMODE(modefile = argv[1];) break; case CMD_ALL: options |= OPT_ALL; diff --git a/util-linux/fdisk_osf.c b/util-linux/fdisk_osf.c index af04cfcc8..89f1f323c 100644 --- a/util-linux/fdisk_osf.c +++ b/util-linux/fdisk_osf.c @@ -366,10 +366,11 @@ bsd_select(void) } printf("Reading disklabel of %s at sector %u\n", partname(disk_device, t+1, 0), ss + BSD_LABELSECTOR); - if (xbsd_readlabel(xbsd_part) == 0) + if (xbsd_readlabel(xbsd_part) == 0) { if (xbsd_create_disklabel() == 0) return; break; + } } } diff --git a/util-linux/fdisk_sgi.c b/util-linux/fdisk_sgi.c index 23ebc56ef..30def09c6 100644 --- a/util-linux/fdisk_sgi.c +++ b/util-linux/fdisk_sgi.c @@ -504,17 +504,19 @@ verify_sgi(int verbose) if (sgi_get_sysid(Index[0]) == SGI_ENTIRE_DISK) { if ((Index[0] != 10) && verbose) printf("IRIX likes when Partition 11 covers the entire disk\n"); - if ((sgi_get_start_sector(Index[0]) != 0) && verbose) + if ((sgi_get_start_sector(Index[0]) != 0) && verbose) { printf("The entire disk partition should start " "at block 0,\n" "not at diskblock %u\n", sgi_get_start_sector(Index[0])); - if (SGI_DEBUG) /* I do not understand how some disks fulfil it */ + } + if (SGI_DEBUG) { /* I do not understand how some disks fulfil it */ if ((sgi_get_num_sectors(Index[0]) != lastblock) && verbose) printf("The entire disk partition is only %u diskblock large,\n" "but the disk is %u diskblocks long\n", sgi_get_num_sectors(Index[0]), lastblock); lastblock = sgi_get_num_sectors(Index[0]); + } } else { if (verbose) printf("One Partition (#11) should cover the entire disk\n"); @@ -669,16 +671,17 @@ sgi_set_volhdr(void) int n; for (n = 8; n < g_partitions; n++) { - if (!sgi_get_num_sectors(n)) { - /* - * 5 cylinders is an arbitrary value I like - * IRIX 5.3 stored files in the volume header - * (like sash, symmon, fx, ide) with ca. 3200 - * sectors. - */ - if (g_heads * g_sectors * 5 < sgi_get_lastblock()) - sgi_set_partition(n, 0, g_heads * g_sectors * 5, SGI_VOLHDR); - break; + if (!sgi_get_num_sectors(n)) { + /* + * 5 cylinders is an arbitrary value I like + * IRIX 5.3 stored files in the volume header + * (like sash, symmon, fx, ide) with ca. 3200 + * sectors. + */ + if (g_heads * g_sectors * 5 < sgi_get_lastblock()) { + sgi_set_partition(n, 0, g_heads * g_sectors * 5, SGI_VOLHDR); + break; + } } } } From bb0bf287d8fcb59a7d44661681576f77845dedbc Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Sun, 19 Jun 2016 21:54:04 +0200 Subject: [PATCH 249/260] randomconfig fixes 2 Signed-off-by: Denys Vlasenko --- libbb/Kbuild.src | 1 + scripts/randomtest | 2 ++ testsuite/ar.tests | 2 +- testsuite/tar.tests | 4 ++-- 4 files changed, 6 insertions(+), 3 deletions(-) diff --git a/libbb/Kbuild.src b/libbb/Kbuild.src index b08ce1158..52a90e9a1 100644 --- a/libbb/Kbuild.src +++ b/libbb/Kbuild.src @@ -145,6 +145,7 @@ lib-$(CONFIG_FTPD) += correct_password.o lib-$(CONFIG_PASSWD) += pw_encrypt.o update_passwd.o obscure.o lib-$(CONFIG_CHPASSWD) += pw_encrypt.o update_passwd.o lib-$(CONFIG_CRYPTPW) += pw_encrypt.o +lib-$(CONFIG_MKPASSWD) += pw_encrypt.o lib-$(CONFIG_SULOGIN) += pw_encrypt.o correct_password.o lib-$(CONFIG_VLOCK) += pw_encrypt.o correct_password.o lib-$(CONFIG_SU) += pw_encrypt.o correct_password.o diff --git a/scripts/randomtest b/scripts/randomtest index 41f252ad7..287f1c771 100755 --- a/scripts/randomtest +++ b/scripts/randomtest @@ -115,6 +115,8 @@ fi # Build! nice -n 10 make $MAKEOPTS 2>&1 | tee make.log +grep 'Rerun make' make.log \ +&& nice -n 10 make $MAKEOPTS 2>&1 | tee -a make.log # Return exitcode 1 if busybox executable does not exist test -x busybox diff --git a/testsuite/ar.tests b/testsuite/ar.tests index 0a8eb9b32..ad7b8fe5f 100755 --- a/testsuite/ar.tests +++ b/testsuite/ar.tests @@ -15,7 +15,7 @@ testing "ar creates archives" \ "$(md5sum /dev/null testing "ar replaces things in archives" \ "echo 'blah!' >file1 && echo 'blast!' >file2 && ar cr test.a README file1 file2 && mv file2 file1 && ar cr test.a file1 && ar p test.a file1" \ diff --git a/testsuite/tar.tests b/testsuite/tar.tests index 890a73dd5..e9021662e 100755 --- a/testsuite/tar.tests +++ b/testsuite/tar.tests @@ -266,7 +266,7 @@ SKIP= # The correct implementation unlinks target before # creating the second file. # We test that /tmp/passwd remains empty: -optional UUDECODE FEATURE_SEAMLESS_BZ2 +optional UUDECODE FEATURE_TAR_AUTODETECT FEATURE_SEAMLESS_BZ2 testing "tar does not extract into symlinks" "\ >>/tmp/passwd && uudecode -o input && tar xf input 2>&1 && rm passwd; cat /tmp/passwd; echo \$? " "\ @@ -282,7 +282,7 @@ l4/V8LDoe90yiWJhOJvIypgEfxdyRThQkBVn/bI= " SKIP= # And same with -k -optional UUDECODE FEATURE_SEAMLESS_BZ2 +optional UUDECODE FEATURE_TAR_AUTODETECT FEATURE_SEAMLESS_BZ2 testing "tar -k does not extract into symlinks" "\ >>/tmp/passwd && uudecode -o input && tar xf input -k 2>&1 && rm passwd; cat /tmp/passwd; echo \$? " "\ From 94046d04951e1e67ddfb7919d8f382dbbfc70a12 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Mon, 20 Jun 2016 00:36:21 +0200 Subject: [PATCH 250/260] randomconfig fixes 3 Signed-off-by: Denys Vlasenko --- findutils/grep.c | 1 + testsuite/du/du-m-works | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/findutils/grep.c b/findutils/grep.c index b072cd441..aeb7977e9 100644 --- a/findutils/grep.c +++ b/findutils/grep.c @@ -686,6 +686,7 @@ int grep_main(int argc UNUSED_PARAM, char **argv) #if ENABLE_FEATURE_GREP_CONTEXT int Copt, opts; #endif + INIT_G(); /* For grep, exitcode of 1 is "not found". Other errors are 2: */ xfunc_error_retval = 2; diff --git a/testsuite/du/du-m-works b/testsuite/du/du-m-works index c96c3b359..d9693c7bf 100644 --- a/testsuite/du/du-m-works +++ b/testsuite/du/du-m-works @@ -1,4 +1,4 @@ # FEATURE: CONFIG_FEATURE_HUMAN_READABLE dd if=/dev/zero of=file bs=1M count=1 2>/dev/null -test x"`busybox du -m file`" = x"1 ." +test x"`busybox du -m file`" = x"1 file" From 0ad872baf30b660ffb87265470d29f14cfc4b2d4 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Mon, 20 Jun 2016 01:40:19 +0200 Subject: [PATCH 251/260] randomconfig fixes 4 Signed-off-by: Denys Vlasenko --- archival/gzip.c | 4 +++- testsuite/tar.tests | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/archival/gzip.c b/archival/gzip.c index f9bb3c742..8f1e4ff29 100644 --- a/archival/gzip.c +++ b/archival/gzip.c @@ -77,13 +77,15 @@ aa: 85.1% -- replaced with aa.gz //kbuild:lib-$(CONFIG_GZIP) += gzip.o //usage:#define gzip_trivial_usage -//usage: "[-cfd" IF_FEATURE_GZIP_LEVELS("123456789") "] [FILE]..." +//usage: "[-cf" IF_GUNZIP("d") IF_FEATURE_GZIP_LEVELS("123456789") "] [FILE]..." //usage:#define gzip_full_usage "\n\n" //usage: "Compress FILEs (or stdin)\n" //usage: IF_FEATURE_GZIP_LEVELS( //usage: "\n -1..9 Compression level" //usage: ) +//usage: IF_GUNZIP( //usage: "\n -d Decompress" +//usage: ) //usage: "\n -c Write to stdout" //usage: "\n -f Force" //usage: diff --git a/testsuite/tar.tests b/testsuite/tar.tests index e9021662e..f19a53da2 100755 --- a/testsuite/tar.tests +++ b/testsuite/tar.tests @@ -24,7 +24,7 @@ tar: short read "" "" SKIP= -optional FEATURE_SEAMLESS_GZ +optional FEATURE_SEAMLESS_GZ GUNZIP # In NOMMU case, "invalid magic" message comes from gunzip child process. # Otherwise, it comes from tar. # Need to fix output up to avoid false positive. From 5c3e060604444b18303f55e631637c28d889704f Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Mon, 20 Jun 2016 10:59:06 +0200 Subject: [PATCH 252/260] modprobe-small: fix bogus handling of unpack errors "modprobe minix; echo $?" Was: modprobe: corrupted data modprobe: read error from 'kernel/fs/minix/minix.ko.xz': No such file or directory modprobe: corrupted data modprobe: read error from 'kernel/fs/minix/minix.ko.xz': No such file or directory modprobe: corrupted data modprobe: read error from 'kernel/fs/minix/minix.ko.xz' modprobe: 'kernel/fs/minix/minix.ko.xz': Success 0 Now: modprobe: corrupted data modprobe: read error from 'kernel/fs/minix/minix.ko.xz' 1 Signed-off-by: Denys Vlasenko --- modutils/modprobe-small.c | 40 +++++++++++++++++++++++++++------------ 1 file changed, 28 insertions(+), 12 deletions(-) diff --git a/modutils/modprobe-small.c b/modutils/modprobe-small.c index ffb46e6be..5936e48cf 100644 --- a/modutils/modprobe-small.c +++ b/modutils/modprobe-small.c @@ -45,6 +45,7 @@ typedef struct module_info { char *pathname; char *aliases; char *deps; + smallint open_read_failed; } module_info; /* @@ -222,7 +223,8 @@ static int load_module(const char *fname, const char *options) #endif } -static void parse_module(module_info *info, const char *pathname) +/* Returns !0 if open/read was unsuccessful */ +static int parse_module(module_info *info, const char *pathname) { char *module_image; char *ptr; @@ -231,6 +233,7 @@ static void parse_module(module_info *info, const char *pathname) dbg1_error_msg("parse_module('%s')", pathname); /* Read (possibly compressed) module */ + errno = 0; len = 64 * 1024 * 1024; /* 64 Mb at most */ module_image = xmalloc_open_zipped_read_close(pathname, &len); /* module_image == NULL is ok here, find_keyword handles it */ @@ -298,9 +301,11 @@ static void parse_module(module_info *info, const char *pathname) dbg2_error_msg("dep:'%s'", ptr); append(ptr); } + free(module_image); info->deps = copy_stringbuf(); - free(module_image); + info->open_read_failed = (module_image == NULL); + return info->open_read_failed; } static FAST_FUNC int fileAction(const char *pathname, @@ -331,7 +336,8 @@ static FAST_FUNC int fileAction(const char *pathname, dbg1_error_msg("'%s' module name matches", pathname); module_found_idx = cur; - parse_module(&modinfo[cur], pathname); + if (parse_module(&modinfo[cur], pathname) != 0) + return TRUE; /* failed to open/read it, no point in trying loading */ if (!(option_mask32 & OPT_r)) { if (load_module(pathname, module_load_options) == 0) { @@ -608,13 +614,14 @@ static int rmmod(const char *filename) #define process_module(a,b) process_module(a) #define cmdline_options "" #endif -static void process_module(char *name, const char *cmdline_options) +static int process_module(char *name, const char *cmdline_options) { char *s, *deps, *options; module_info **infovec; module_info *info; int infoidx; int is_remove = (option_mask32 & OPT_r) != 0; + int exitcode = EXIT_SUCCESS; dbg1_error_msg("process_module('%s','%s')", name, cmdline_options); @@ -628,7 +635,7 @@ static void process_module(char *name, const char *cmdline_options) * (compat note: this allows and strips .ko suffix) */ rmmod(name); - return; + return EXIT_SUCCESS; } /* @@ -639,7 +646,7 @@ static void process_module(char *name, const char *cmdline_options) */ if (!is_remove && already_loaded(name)) { dbg1_error_msg("nothing to do for '%s'", name); - return; + return EXIT_SUCCESS; } options = NULL; @@ -741,6 +748,11 @@ static void process_module(char *name, const char *cmdline_options) dbg1_error_msg("'%s': blacklisted", info->pathname); continue; } + if (info->open_read_failed) { + /* We already tried it, didn't work. Don't try load again */ + exitcode = EXIT_FAILURE; + continue; + } errno = 0; if (load_module(info->pathname, options) != 0) { if (EEXIST != errno) { @@ -752,13 +764,14 @@ static void process_module(char *name, const char *cmdline_options) info->pathname, moderror(errno)); } + exitcode = EXIT_FAILURE; } } ret: free(infovec); free(options); -//TODO: return load attempt result from process_module. -//If dep didn't load ok, continuing makes little sense. + + return exitcode; } #undef cmdline_options @@ -865,6 +878,7 @@ The following options are useful for people managing distributions: int modprobe_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; int modprobe_main(int argc UNUSED_PARAM, char **argv) { + int exitcode; struct utsname uts; char applet0 = applet_name[0]; IF_FEATURE_MODPROBE_SMALL_OPTIONS_ON_CMDLINE(char *options;) @@ -970,21 +984,23 @@ int modprobe_main(int argc UNUSED_PARAM, char **argv) bb_error_msg_and_die("can't insert '%s': %s", *argv, moderror(errno)); } - return 0; + return EXIT_SUCCESS; } /* Try to load modprobe.dep.bb */ - if ('r' != applet0) /* not rmmod */ + if ('r' != applet0) { /* not rmmod */ load_dep_bb(); + } /* Load/remove modules. * Only rmmod/modprobe -r loops here, insmod/modprobe has only argv[0] */ + exitcode = EXIT_SUCCESS; do { - process_module(*argv, options); + exitcode |= process_module(*argv, options); } while (*++argv); if (ENABLE_FEATURE_CLEAN_UP) { IF_FEATURE_MODPROBE_SMALL_OPTIONS_ON_CMDLINE(free(options);) } - return EXIT_SUCCESS; + return exitcode; } From ecf25cb5bce27ca5820e2895d8458f38c406d105 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Mon, 20 Jun 2016 11:04:04 +0200 Subject: [PATCH 253/260] randomconfig fixes 5: false positive for tar; mount emits corrupted message Signed-off-by: Denys Vlasenko --- testsuite/tar.tests | 2 +- util-linux/mount.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/testsuite/tar.tests b/testsuite/tar.tests index f19a53da2..c44b7ad07 100755 --- a/testsuite/tar.tests +++ b/testsuite/tar.tests @@ -204,7 +204,7 @@ SKIP= # Had a bug where on extract autodetect first "switched off" -z # and then failed to recognize .tgz extension -optional FEATURE_TAR_CREATE FEATURE_SEAMLESS_GZ +optional FEATURE_TAR_CREATE FEATURE_SEAMLESS_GZ GUNZIP testing "tar extract tgz" "\ dd count=1 bs=1M if=/dev/zero of=F0 2>/dev/null tar -czf F0.tgz F0 diff --git a/util-linux/mount.c b/util-linux/mount.c index c76f6ef61..cef4f7415 100644 --- a/util-linux/mount.c +++ b/util-linux/mount.c @@ -2058,7 +2058,7 @@ static int singlemount(struct mntent *mp, int ignore_busy) del_loop(mp->mnt_fsname); if (ENABLE_FEATURE_CLEAN_UP) { free(loopFile); - free(mp->mnt_fsname); + /* No, "rc != 0" needs it: free(mp->mnt_fsname); */ } } From 984b0a613aaf1cdf48c2e2af08c8466a7bad8307 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Mon, 20 Jun 2016 11:06:42 +0200 Subject: [PATCH 254/260] libarchive: fix xmalloc_open_zipped_read_close() on NOMMU The somewhat new "unpack in memory" code was broken for xmalloc_open_zipped_read_close() on NOMMU: we seek back over signature, but then expect it to be already consumed. Stop seeking back in this case. Signed-off-by: Denys Vlasenko --- archival/bbunzip.c | 2 +- archival/libarchive/decompress_gunzip.c | 4 +-- archival/libarchive/decompress_unxz.c | 2 +- archival/libarchive/open_transformer.c | 35 +++++++++++-------------- include/bb_archive.h | 8 +++--- 5 files changed, 23 insertions(+), 28 deletions(-) diff --git a/archival/bbunzip.c b/archival/bbunzip.c index b4f754e0b..07ef8617e 100644 --- a/archival/bbunzip.c +++ b/archival/bbunzip.c @@ -121,7 +121,7 @@ int FAST_FUNC bbunpack(char **argv, if (!(option_mask32 & SEAMLESS_MAGIC)) { init_transformer_state(&xstate); - xstate.check_signature = 1; + xstate.signature_skipped = 0; /*xstate.src_fd = STDIN_FILENO; - already is */ xstate.dst_fd = STDOUT_FILENO; status = unpacker(&xstate); diff --git a/archival/libarchive/decompress_gunzip.c b/archival/libarchive/decompress_gunzip.c index 20e4d9ac5..c7fa5b526 100644 --- a/archival/libarchive/decompress_gunzip.c +++ b/archival/libarchive/decompress_gunzip.c @@ -1201,7 +1201,7 @@ unpack_gz_stream(transformer_state_t *xstate) if (check_signature16(xstate, GZIP_MAGIC)) return -1; #else - if (xstate->check_signature) { + if (!xstate->signature_skipped) { uint16_t magic2; if (full_read(xstate->src_fd, &magic2, 2) != 2) { @@ -1210,7 +1210,7 @@ unpack_gz_stream(transformer_state_t *xstate) return -1; } if (magic2 == COMPRESS_MAGIC) { - xstate->check_signature = 0; + xstate->signature_skipped = 2; return unpack_Z_stream(xstate); } if (magic2 != GZIP_MAGIC) diff --git a/archival/libarchive/decompress_unxz.c b/archival/libarchive/decompress_unxz.c index 1f408abfd..cd32cc745 100644 --- a/archival/libarchive/decompress_unxz.c +++ b/archival/libarchive/decompress_unxz.c @@ -55,7 +55,7 @@ unpack_xz_stream(transformer_state_t *xstate) iobuf.out = membuf + BUFSIZ; iobuf.out_size = BUFSIZ; - if (!xstate || xstate->check_signature == 0) { + if (!xstate || xstate->signature_skipped) { /* Preload XZ file signature */ strcpy((char*)membuf, HEADER_MAGIC); iobuf.in_size = HEADER_MAGIC_SIZE; diff --git a/archival/libarchive/open_transformer.c b/archival/libarchive/open_transformer.c index be536a3d7..d93c8366f 100644 --- a/archival/libarchive/open_transformer.c +++ b/archival/libarchive/open_transformer.c @@ -13,16 +13,13 @@ void FAST_FUNC init_transformer_state(transformer_state_t *xstate) int FAST_FUNC check_signature16(transformer_state_t *xstate, unsigned magic16) { - if (xstate->check_signature) { + if (!xstate->signature_skipped) { uint16_t magic2; if (full_read(xstate->src_fd, &magic2, 2) != 2 || magic2 != magic16) { bb_error_msg("invalid magic"); -#if 0 /* possible future extension */ - if (xstate->check_signature > 1) - xfunc_die(); -#endif return -1; } + xstate->signature_skipped = 2; } return 0; } @@ -102,7 +99,7 @@ void check_errors_in_children(int signo) /* transformer(), more than meets the eye */ #if BB_MMU void FAST_FUNC fork_transformer(int fd, - int check_signature, + int signature_skipped, IF_DESKTOP(long long) int FAST_FUNC (*transformer)(transformer_state_t *xstate) ) #else @@ -123,7 +120,7 @@ void FAST_FUNC fork_transformer(int fd, const char *transform_prog) IF_DESKTOP(long long) int r; transformer_state_t xstate; init_transformer_state(&xstate); - xstate.check_signature = check_signature; + xstate.signature_skipped = signature_skipped; xstate.src_fd = fd; xstate.dst_fd = fd_pipe.wr; r = transformer(&xstate); @@ -168,12 +165,11 @@ static transformer_state_t *setup_transformer_on_fd(int fd, int fail_if_not_comp uint16_t b16[2]; uint32_t b32[1]; } magic; - int offset; transformer_state_t *xstate; - offset = -2; xstate = xzalloc(sizeof(*xstate)); xstate->src_fd = fd; + xstate->signature_skipped = 2; /* .gz and .bz2 both have 2-byte signature, and their * unpack_XXX_stream wants this header skipped. */ @@ -202,7 +198,7 @@ static transformer_state_t *setup_transformer_on_fd(int fd, int fail_if_not_comp if (ENABLE_FEATURE_SEAMLESS_XZ && magic.b16[0] == XZ_MAGIC1 ) { - offset = -6; + xstate->signature_skipped = 6; xread(fd, magic.b32, sizeof(magic.b32[0])); if (magic.b32[0] == XZ_MAGIC2) { xstate->xformer = unpack_xz_stream; @@ -226,16 +222,7 @@ static transformer_state_t *setup_transformer_on_fd(int fd, int fail_if_not_comp // USE_FOR_NOMMU(xstate->xformer_prog = "cat";) /* fall through to seeking bck over bytes we read earlier */ - USE_FOR_NOMMU(found_magic:) - /* NOMMU version of fork_transformer execs - * an external unzipper that wants - * file position at the start of the file. - */ - xlseek(fd, offset, SEEK_CUR); - - USE_FOR_MMU(found_magic:) - /* In MMU case, if magic was found, seeking back is not necessary */ - + found_magic: return xstate; } @@ -254,6 +241,12 @@ int FAST_FUNC setup_unzip_on_fd(int fd, int fail_if_not_compressed) # if BB_MMU fork_transformer_with_no_sig(xstate->src_fd, xstate->xformer); # else + /* NOMMU version of fork_transformer execs + * an external unzipper that wants + * file position at the start of the file. + */ + xlseek(fd, - xstate->signature_skipped, SEEK_CUR); + xstate->signature_skipped = 0; fork_transformer_with_sig(xstate->src_fd, xstate->xformer, xstate->xformer_prog); # endif free(xstate); @@ -300,6 +293,8 @@ int FAST_FUNC open_zipped(const char *fname, int fail_if_not_compressed) # if BB_MMU fork_transformer_with_no_sig(xstate->src_fd, xstate->xformer); # else + xlseek(fd, - xstate->signature_skipped, SEEK_CUR); + xstate->signature_skipped = 0; fork_transformer_with_sig(xstate->src_fd, xstate->xformer, xstate->xformer_prog); # endif } diff --git a/include/bb_archive.h b/include/bb_archive.h index 10969b567..2b9c5f04c 100644 --- a/include/bb_archive.h +++ b/include/bb_archive.h @@ -211,7 +211,7 @@ void dealloc_bunzip(bunzip_data *bd) FAST_FUNC; /* Meaning and direction (input/output) of the fields are transformer-specific */ typedef struct transformer_state_t { - smallint check_signature; /* most often referenced member */ + smallint signature_skipped; /* most often referenced member */ IF_DESKTOP(long long) int FAST_FUNC (*xformer)(struct transformer_state_t *xstate); USE_FOR_NOMMU(const char *xformer_prog;) @@ -252,11 +252,11 @@ int bbunpack(char **argv, void check_errors_in_children(int signo); #if BB_MMU void fork_transformer(int fd, - int check_signature, + int signature_skipped, IF_DESKTOP(long long) int FAST_FUNC (*transformer)(transformer_state_t *xstate) ) FAST_FUNC; -#define fork_transformer_with_sig(fd, transformer, transform_prog) fork_transformer((fd), 1, (transformer)) -#define fork_transformer_with_no_sig(fd, transformer) fork_transformer((fd), 0, (transformer)) +#define fork_transformer_with_sig(fd, transformer, transform_prog) fork_transformer((fd), 0, (transformer)) +#define fork_transformer_with_no_sig(fd, transformer) fork_transformer((fd), 1, (transformer)) #else void fork_transformer(int fd, const char *transform_prog) FAST_FUNC; #define fork_transformer_with_sig(fd, transformer, transform_prog) fork_transformer((fd), (transform_prog)) From df3ec0e2f70d67f1f880bee933985732b455ee76 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Mon, 20 Jun 2016 11:42:00 +0200 Subject: [PATCH 255/260] libarchive: fix open_zipped() Last commit broke it (on both MMU and NOMMU) Signed-off-by: Denys Vlasenko --- archival/libarchive/open_transformer.c | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/archival/libarchive/open_transformer.c b/archival/libarchive/open_transformer.c index d93c8366f..dd15a9b1f 100644 --- a/archival/libarchive/open_transformer.c +++ b/archival/libarchive/open_transformer.c @@ -220,7 +220,6 @@ static transformer_state_t *setup_transformer_on_fd(int fd, int fail_if_not_comp */ // USE_FOR_MMU(xstate->xformer = copy_stream;) // USE_FOR_NOMMU(xstate->xformer_prog = "cat";) - /* fall through to seeking bck over bytes we read earlier */ found_magic: return xstate; @@ -289,16 +288,22 @@ int FAST_FUNC open_zipped(const char *fname, int fail_if_not_compressed) return -1; fd = xstate->src_fd; - if (xstate->xformer) { # if BB_MMU - fork_transformer_with_no_sig(xstate->src_fd, xstate->xformer); -# else + if (xstate->xformer) { + fork_transformer_with_no_sig(fd, xstate->xformer); + } else { + /* the file is not compressed */ xlseek(fd, - xstate->signature_skipped, SEEK_CUR); xstate->signature_skipped = 0; - fork_transformer_with_sig(xstate->src_fd, xstate->xformer, xstate->xformer_prog); -# endif } - /* else: the file is not compressed */ +# else + /* NOMMU can't avoid the seek :( */ + xlseek(fd, - xstate->signature_skipped, SEEK_CUR); + xstate->signature_skipped = 0; + if (xstate->xformer) { + fork_transformer_with_sig(fd, xstate->xformer, xstate->xformer_prog); + } /* esle: the file is not compressed */ +# endif free(xstate); return fd; From ea9ebc011b3ee9b86b00646b91e73bb860d340b4 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Mon, 20 Jun 2016 12:23:35 +0200 Subject: [PATCH 256/260] scripts/trylink: libbusybox fix gcc 6.1.1 can emit empty line with spaces Signed-off-by: Denys Vlasenko --- scripts/trylink | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/trylink b/scripts/trylink index 129570a60..145df9959 100755 --- a/scripts/trylink +++ b/scripts/trylink @@ -293,7 +293,7 @@ if test "$CONFIG_FEATURE_INDIVIDUAL" = y; then echo "Linking individual applets against libbusybox (see $sharedlib_dir/*)" gcc -DNAME_MAIN -E -include include/autoconf.h include/applets.h \ | grep -v "^#" \ - | grep -v "^$" \ + | grep -v "^ *$" \ > applet_lst.tmp while read name main junk; do From e24e88697af81800060efc75e67777ef245b15cd Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Mon, 20 Jun 2016 16:28:53 +0200 Subject: [PATCH 257/260] typo fix Signed-off-by: Denys Vlasenko --- archival/libarchive/open_transformer.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/archival/libarchive/open_transformer.c b/archival/libarchive/open_transformer.c index dd15a9b1f..a3018d9ec 100644 --- a/archival/libarchive/open_transformer.c +++ b/archival/libarchive/open_transformer.c @@ -302,7 +302,7 @@ int FAST_FUNC open_zipped(const char *fname, int fail_if_not_compressed) xstate->signature_skipped = 0; if (xstate->xformer) { fork_transformer_with_sig(fd, xstate->xformer, xstate->xformer_prog); - } /* esle: the file is not compressed */ + } /* else: the file is not compressed */ # endif free(xstate); From 7cf45ae10e71d11ca53e7b0220c76562a8045113 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Mon, 20 Jun 2016 23:50:26 +0200 Subject: [PATCH 258/260] setsid: fix broken -c This did not work: setsid sh -c 'anything' Signed-off-by: Denys Vlasenko --- miscutils/setsid.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/miscutils/setsid.c b/miscutils/setsid.c index 1b27377b2..9bddc2fcf 100644 --- a/miscutils/setsid.c +++ b/miscutils/setsid.c @@ -29,7 +29,7 @@ int setsid_main(int argc UNUSED_PARAM, char **argv) unsigned opt; opt_complementary = "-1"; /* at least one arg */ - opt = getopt32(argv, "c"); + opt = getopt32(argv, "+c"); /* +: stop on first non-opt */ argv += optind; /* setsid() is allowed only when we are not a process group leader. From 10c0e9178606bb71a071c27dcda3fd2787e8303b Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Tue, 21 Jun 2016 02:04:16 +0200 Subject: [PATCH 259/260] libarchive: fix xmalloc_open_zipped_read_close() Signed-off-by: Denys Vlasenko --- archival/libarchive/open_transformer.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/archival/libarchive/open_transformer.c b/archival/libarchive/open_transformer.c index a3018d9ec..ac7e5db95 100644 --- a/archival/libarchive/open_transformer.c +++ b/archival/libarchive/open_transformer.c @@ -331,6 +331,9 @@ void* FAST_FUNC xmalloc_open_zipped_read_close(const char *fname, size_t *maxsz_ } } else { /* File is not compressed */ +//FIXME: avoid seek + xlseek(xstate->src_fd, - xstate->signature_skipped, SEEK_CUR); + xstate->signature_skipped = 0; image = xmalloc_read(xstate->src_fd, maxsz_p); } From c3b34d8b39cae35fec8c6fb644d90dc80e574236 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Tue, 21 Jun 2016 00:15:49 +0200 Subject: [PATCH 260/260] Bump version to 1.25.0 Signed-off-by: Denys Vlasenko --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index d5950230d..572da3d88 100644 --- a/Makefile +++ b/Makefile @@ -1,7 +1,7 @@ VERSION = 1 PATCHLEVEL = 25 SUBLEVEL = 0 -EXTRAVERSION = .git +EXTRAVERSION = NAME = Unnamed # *DOCUMENTATION*