From 99e30be38bc167a3b5729154a27ccdb15bbaadb2 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko <vda.linux@googlemail.com> Date: Tue, 4 Aug 2015 12:28:21 +0200 Subject: zcip: code shrink function old new delta zcip_main 1263 1230 -33 Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com> --- networking/zcip.c | 137 +++++++++++++++++++++++------------------------------- 1 file changed, 59 insertions(+), 78 deletions(-) diff --git a/networking/zcip.c b/networking/zcip.c index 69644b230..5877a8317 100644 --- a/networking/zcip.c +++ b/networking/zcip.c @@ -215,19 +215,17 @@ int zcip_main(int argc UNUSED_PARAM, char **argv) const struct ether_addr null_addr; struct ifreq ifr; uint32_t chosen_nip; - int timeout_ms; /* must be signed */ + int timeout_ms; // must be signed unsigned conflicts; - unsigned nprobes; - unsigned nclaims; + unsigned nsent; int verbose; } L; #define null_addr (L.null_addr ) -#define chosen_nip (L.chosen_nip) #define ifr (L.ifr ) +#define chosen_nip (L.chosen_nip) #define timeout_ms (L.timeout_ms) #define conflicts (L.conflicts ) -#define nprobes (L.nprobes ) -#define nclaims (L.nclaims ) +#define nsent (L.nsent ) #define verbose (L.verbose ) memset(&L, 0, sizeof(L)); @@ -351,8 +349,7 @@ int zcip_main(int argc UNUSED_PARAM, char **argv) struct pollfd fds[1]; unsigned deadline_us; struct arp_packet p; - int source_ip_conflict; - int target_ip_conflict; + int ip_conflict; fds[0].fd = sock_fd; fds[0].events = POLLIN; @@ -368,8 +365,8 @@ int zcip_main(int argc UNUSED_PARAM, char **argv) // set deadline_us to the point in time when we timeout deadline_us = MONOTONIC_US() + timeout_ms * 1000; - VDBG("...wait %d %s nprobes=%u, nclaims=%u\n", - timeout_ms, argv_intf, nprobes, nclaims); + VDBG("...wait %d %s nsent=%u\n", + timeout_ms, argv_intf, nsent); switch (safe_poll(fds, 1, timeout_ms)) { @@ -384,10 +381,10 @@ int zcip_main(int argc UNUSED_PARAM, char **argv) case PROBE: // timeouts in the PROBE state mean no conflicting ARP packets // have been received, so we can progress through the states - if (nprobes < PROBE_NUM) { - nprobes++; + if (nsent < PROBE_NUM) { + nsent++; VDBG("probe/%u %s@%s\n", - nprobes, argv_intf, nip_to_a(chosen_nip)); + nsent, argv_intf, nip_to_a(chosen_nip)); timeout_ms = PROBE_MIN * 1000; timeout_ms += random_delay_ms(PROBE_MAX - PROBE_MIN); arp(/* ARPOP_REQUEST, */ @@ -395,25 +392,25 @@ int zcip_main(int argc UNUSED_PARAM, char **argv) &null_addr, chosen_nip); break; } - // Switch to announce state. - nclaims = 0; + // Switch to announce state + nsent = 0; state = ANNOUNCE; goto send_announce; case ANNOUNCE: // timeouts in the ANNOUNCE state mean no conflicting ARP packets // have been received, so we can progress through the states - if (nclaims < ANNOUNCE_NUM) { + if (nsent < ANNOUNCE_NUM) { send_announce: - nclaims++; + nsent++; VDBG("announce/%u %s@%s\n", - nclaims, argv_intf, nip_to_a(chosen_nip)); + nsent, argv_intf, nip_to_a(chosen_nip)); timeout_ms = ANNOUNCE_INTERVAL * 1000; arp(/* ARPOP_REQUEST, */ /* &G.eth_addr, */ chosen_nip, &G.eth_addr, chosen_nip); break; } - // Switch to monitor state. + // Switch to monitor state // FIXME update filters run(argv, "config", chosen_nip); // NOTE: all other exit paths should deconfig... @@ -424,7 +421,7 @@ int zcip_main(int argc UNUSED_PARAM, char **argv) state = MONITOR; break; case DEFEND: - // Defend period ended with no ARP replies - we won. + // Defend period ended with no ARP replies - we won conflicts = 0; timeout_ms = -1; state = MONITOR; @@ -443,7 +440,7 @@ int zcip_main(int argc UNUSED_PARAM, char **argv) diff = 0; } VDBG("adjusting timeout\n"); - timeout_ms = (diff / 1000) | 1; /* never 0 */ + timeout_ms = (diff / 1000) | 1; // never 0 } if ((fds[0].revents & POLLIN) == 0) { @@ -452,7 +449,7 @@ int zcip_main(int argc UNUSED_PARAM, char **argv) // this shouldn't necessarily exit. bb_error_msg("iface %s is down", argv_intf); if (state >= MONITOR) { - /* only if we are in MONITOR or DEFEND */ + // only if we are in MONITOR or DEFEND run(argv, "deconfig", chosen_nip); } return EXIT_FAILURE; @@ -478,81 +475,65 @@ int zcip_main(int argc UNUSED_PARAM, char **argv) struct ether_addr *tha = (struct ether_addr *) p.arp.arp_tha; struct in_addr *spa = (struct in_addr *) p.arp.arp_spa; struct in_addr *tpa = (struct in_addr *) p.arp.arp_tpa; - VDBG("%s recv arp type=%d, op=%d,\n", - argv_intf, ntohs(p.eth.ether_type), - ntohs(p.arp.arp_op)); - VDBG("\tsource=%s %s\n", - ether_ntoa(sha), - inet_ntoa(*spa)); - VDBG("\ttarget=%s %s\n", - ether_ntoa(tha), - inet_ntoa(*tpa)); + VDBG("source=%s %s\n", ether_ntoa(sha), inet_ntoa(*spa)); + VDBG("target=%s %s\n", ether_ntoa(tha), inet_ntoa(*tpa)); } #endif - source_ip_conflict = 0; - target_ip_conflict = 0; - + ip_conflict = 0; if (memcmp(&p.arp.arp_sha, &G.eth_addr, ETH_ALEN) != 0) { if (memcmp(p.arp.arp_spa, &chosen_nip, 4) == 0) { - /* A probe or reply with source_ip == chosen ip */ - source_ip_conflict = 1; + // A probe or reply with source_ip == chosen ip + ip_conflict = 1; } if (p.arp.arp_op == htons(ARPOP_REQUEST) && memcmp(p.arp.arp_spa, &const_int_0, 4) == 0 && memcmp(p.arp.arp_tpa, &chosen_nip, 4) == 0 ) { - /* A probe with source_ip == 0.0.0.0, target_ip == chosen ip: - * another host trying to claim this ip! - */ - target_ip_conflict = 1; + // A probe with source_ip == 0.0.0.0, target_ip == chosen ip: + // another host trying to claim this ip! + ip_conflict |= 2; } } + VDBG("state:%d ip_conflict:%d\n", state, ip_conflict); + if (!ip_conflict) + break; - VDBG("state = %d, source ip conflict = %d, target ip conflict = %d\n", - state, source_ip_conflict, target_ip_conflict); - switch (state) { - case PROBE: - case ANNOUNCE: - // When probing or announcing, check for source IP conflicts - // and other hosts doing ARP probes (target IP conflicts). - if (source_ip_conflict || target_ip_conflict) { - conflicts++; - timeout_ms = PROBE_MIN * 1000 - + CONFLICT_MULTIPLIER * random_delay_ms(conflicts); - chosen_nip = pick_nip(); - nprobes = 0; - nclaims = 0; - state = PROBE; - } + // Either src or target IP conflict exists + if (state <= ANNOUNCE) { + // PROBE or ANNOUNCE + conflicts++; + timeout_ms = PROBE_MIN * 1000 + + CONFLICT_MULTIPLIER * random_delay_ms(conflicts); + chosen_nip = pick_nip(); + nsent = 0; + state = PROBE; break; - case MONITOR: - // If a conflict, we try to defend with a single ARP probe. - if (source_ip_conflict) { - VDBG("monitor conflict -- defending\n"); + } + // MONITOR or DEFEND: only src IP conflict is a problem + if (ip_conflict & 1) { + if (state == MONITOR) { + // Src IP conflict, defend with a single ARP probe + VDBG("monitor conflict - defending\n"); timeout_ms = DEFEND_INTERVAL * 1000; state = DEFEND; arp(/* ARPOP_REQUEST, */ /* &G.eth_addr, */ chosen_nip, &G.eth_addr, chosen_nip); + break; } - break; - case DEFEND: - // Well, we tried. Start over (on conflict). - if (source_ip_conflict) { - VDBG("defend conflict -- starting over\n"); - run(argv, "deconfig", chosen_nip); - - // restart the whole protocol - timeout_ms = 0; - chosen_nip = pick_nip(); - nprobes = 0; - nclaims = 0; - state = PROBE; - } - break; - } // switch state - break; // case 1 (packets arriving) - } // switch poll + // state == DEFEND + // Another src IP conflict, start over + VDBG("defend conflict - starting over\n"); + run(argv, "deconfig", chosen_nip); + + // restart the whole protocol + timeout_ms = 0; + chosen_nip = pick_nip(); + nsent = 0; + state = PROBE; + } + break; // case 1 (packet arrived) + } // switch (poll) } // while (1) #undef argv_intf } -- cgit v1.2.3-55-g6feb From e3475838354d6bba414ab8cdc2211313ad29dc9d Mon Sep 17 00:00:00 2001 From: Denys Vlasenko <vda.linux@googlemail.com> Date: Tue, 4 Aug 2015 14:30:31 +0200 Subject: zcip: another code shrink function old new delta send_arp_request - 185 +185 zcip_main 1273 1272 -1 pick_nip 40 - -40 arp 185 - -185 ------------------------------------------------------------------------------ (add/remove: 1/2 grow/shrink: 0/1 up/down: 185/-226) Total: -41 bytes Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com> --- networking/zcip.c | 307 ++++++++++++++++++++++++++---------------------------- 1 file changed, 148 insertions(+), 159 deletions(-) diff --git a/networking/zcip.c b/networking/zcip.c index 5877a8317..a167c7e91 100644 --- a/networking/zcip.c +++ b/networking/zcip.c @@ -90,7 +90,7 @@ enum { struct globals { struct sockaddr iface_sockaddr; - struct ether_addr eth_addr; + struct ether_addr our_ethaddr; uint32_t localnet_ip; } FIX_ALIASING; #define G (*(struct globals*)&bb_common_bufsiz1) @@ -121,14 +121,14 @@ static const char *nip_to_a(uint32_t nip) /** * Broadcast an ARP packet. */ -static void arp( +static void send_arp_request( /* int op, - always ARPOP_REQUEST */ - /* const struct ether_addr *source_eth, - always &G.eth_addr */ + /* const struct ether_addr *source_eth, - always &G.our_ethaddr */ uint32_t source_nip, const struct ether_addr *target_eth, uint32_t target_nip) { enum { op = ARPOP_REQUEST }; -#define source_eth (&G.eth_addr) +#define source_eth (&G.our_ethaddr) struct arp_packet p; memset(&p, 0, sizeof(p)); @@ -205,35 +205,34 @@ static ALWAYS_INLINE unsigned random_delay_ms(unsigned secs) int zcip_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; int zcip_main(int argc UNUSED_PARAM, char **argv) { - int state; char *r_opt; const char *l_opt = "169.254.0.0"; + int state; + int nsent; unsigned opts; - // ugly trick, but I want these zeroed in one go + // Ugly trick, but I want these zeroed in one go struct { - const struct ether_addr null_addr; + const struct ether_addr null_ethaddr; struct ifreq ifr; uint32_t chosen_nip; + int conflicts; int timeout_ms; // must be signed - unsigned conflicts; - unsigned nsent; int verbose; } L; -#define null_addr (L.null_addr ) -#define ifr (L.ifr ) -#define chosen_nip (L.chosen_nip) -#define timeout_ms (L.timeout_ms) -#define conflicts (L.conflicts ) -#define nsent (L.nsent ) -#define verbose (L.verbose ) +#define null_ethaddr (L.null_ethaddr) +#define ifr (L.ifr ) +#define chosen_nip (L.chosen_nip ) +#define conflicts (L.conflicts ) +#define timeout_ms (L.timeout_ms ) +#define verbose (L.verbose ) memset(&L, 0, sizeof(L)); INIT_G(); #define FOREGROUND (opts & 1) #define QUIT (opts & 2) - // parse commandline: prog [options] ifname script + // Parse commandline: prog [options] ifname script // exactly 2 args; -v accumulates and implies -f opt_complementary = "=2:vv:vf"; opts = getopt32(argv, "fqr:l:v", &r_opt, &l_opt, &verbose); @@ -242,7 +241,7 @@ int zcip_main(int argc UNUSED_PARAM, char **argv) if (!FOREGROUND) bb_daemonize_or_rexec(0 /*was: DAEMON_CHDIR_ROOT*/, argv); #endif - // open an ARP socket + // Open an ARP socket // (need to do it before openlog to prevent openlog from taking // fd 3 (sock_fd==3)) xmove_fd(xsocket(AF_PACKET, SOCK_PACKET, htons(ETH_P_ARP)), sock_fd); @@ -282,26 +281,26 @@ int zcip_main(int argc UNUSED_PARAM, char **argv) xsetenv("interface", argv_intf); - // initialize the interface (modprobe, ifup, etc) + // Initialize the interface (modprobe, ifup, etc) if (run(argv, "init", 0)) return EXIT_FAILURE; - // initialize G.iface_sockaddr + // Initialize G.iface_sockaddr // G.iface_sockaddr is: { u16 sa_family; u8 sa_data[14]; } //memset(&G.iface_sockaddr, 0, sizeof(G.iface_sockaddr)); //TODO: are we leaving sa_family == 0 (AF_UNSPEC)?! safe_strncpy(G.iface_sockaddr.sa_data, argv_intf, sizeof(G.iface_sockaddr.sa_data)); - // bind to the interface's ARP socket + // Bind to the interface's ARP socket xbind(sock_fd, &G.iface_sockaddr, sizeof(G.iface_sockaddr)); - // get the interface's ethernet address + // Get the interface's ethernet address //memset(&ifr, 0, sizeof(ifr)); strncpy_IFNAMSIZ(ifr.ifr_name, argv_intf); xioctl(sock_fd, SIOCGIFHWADDR, &ifr); - memcpy(&G.eth_addr, &ifr.ifr_hwaddr.sa_data, ETH_ALEN); + memcpy(&G.our_ethaddr, &ifr.ifr_hwaddr.sa_data, ETH_ALEN); - // start with some stable ip address, either a function of + // Start with some stable ip address, either a function of // the hardware address or else the last address we used. // we are taking low-order four bytes, as top-order ones // aren't random enough. @@ -309,17 +308,14 @@ int zcip_main(int argc UNUSED_PARAM, char **argv) // depending on when we detect conflicts. { uint32_t t; - move_from_unaligned32(t, ((char *)&G.eth_addr + 2)); + move_from_unaligned32(t, ((char *)&G.our_ethaddr + 2)); srand(t); } - if (chosen_nip == 0) - chosen_nip = pick_nip(); - // FIXME cases to handle: // - zcip already running! // - link already has local address... just defend/update - // daemonize now; don't delay system startup + // Daemonize now; don't delay system startup if (!FOREGROUND) { #if BB_MMU bb_daemonize(0 /*was: DAEMON_CHDIR_ROOT*/); @@ -327,14 +323,14 @@ int zcip_main(int argc UNUSED_PARAM, char **argv) bb_info_msg("start, interface %s", argv_intf); } - // run the dynamic address negotiation protocol, + // Run the dynamic address negotiation protocol, // restarting after address conflicts: // - start with some address we want to try // - short random delay // - arp probes to see if another host uses it - // 00:04:e2:64:23:c2 > ff:ff:ff:ff:ff:ff, ARP (0x0806): arp who-has 169.254.194.171 tell 0.0.0.0 + // 00:04:e2:64:23:c2 > ff:ff:ff:ff:ff:ff: arp who-has 169.254.194.171 tell 0.0.0.0 // - arp announcements that we're claiming it - // 00:04:e2:64:23:c2 > ff:ff:ff:ff:ff:ff, ARP (0x0806): arp who-has 169.254.194.171 (00:04:e2:64:23:c2) tell 169.254.194.171 + // 00:04:e2:64:23:c2 > ff:ff:ff:ff:ff:ff: arp who-has 169.254.194.171 (00:04:e2:64:23:c2) tell 169.254.194.171 // - use it // - defend it, within limits // exit if: @@ -342,73 +338,73 @@ int zcip_main(int argc UNUSED_PARAM, char **argv) // run "<script> config", then exit with exitcode 0 // - poll error (when does this happen?) // - read error (when does this happen?) - // - sendto error (in arp()) (when does this happen?) + // - sendto error (in send_arp_request()) (when does this happen?) // - revents & POLLERR (link down). run "<script> deconfig" first + if (chosen_nip == 0) { + new_nip_and_PROBE: + chosen_nip = pick_nip(); + } + nsent = 0; state = PROBE; while (1) { struct pollfd fds[1]; unsigned deadline_us; struct arp_packet p; int ip_conflict; + int n; fds[0].fd = sock_fd; fds[0].events = POLLIN; fds[0].revents = 0; - // poll, being ready to adjust current timeout + // Poll, being ready to adjust current timeout if (!timeout_ms) { timeout_ms = random_delay_ms(PROBE_WAIT); // FIXME setsockopt(sock_fd, SO_ATTACH_FILTER, ...) to // make the kernel filter out all packets except // ones we'd care about. } - // set deadline_us to the point in time when we timeout + // 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); - switch (safe_poll(fds, 1, timeout_ms)) { - - default: + n = safe_poll(fds, 1, timeout_ms); + if (n < 0) { //bb_perror_msg("poll"); - done in safe_poll return EXIT_FAILURE; - - // timeout - case 0: - VDBG("state = %d\n", state); + } + if (n == 0) { // timed out? + VDBG("state:%d\n", state); switch (state) { case PROBE: - // timeouts in the PROBE state mean no conflicting ARP packets - // have been received, so we can progress through the states + // No conflicting ARP packets were seen: + // we can progress through the states if (nsent < PROBE_NUM) { nsent++; VDBG("probe/%u %s@%s\n", nsent, argv_intf, nip_to_a(chosen_nip)); timeout_ms = PROBE_MIN * 1000; timeout_ms += random_delay_ms(PROBE_MAX - PROBE_MIN); - arp(/* ARPOP_REQUEST, */ - /* &G.eth_addr, */ 0, - &null_addr, chosen_nip); - break; + send_arp_request(0, &null_ethaddr, chosen_nip); + continue; } // Switch to announce state nsent = 0; state = ANNOUNCE; goto send_announce; case ANNOUNCE: - // timeouts in the ANNOUNCE state mean no conflicting ARP packets - // have been received, so we can progress through the states + // No conflicting ARP packets were seen: + // we can progress through the states if (nsent < ANNOUNCE_NUM) { send_announce: nsent++; VDBG("announce/%u %s@%s\n", nsent, argv_intf, nip_to_a(chosen_nip)); timeout_ms = ANNOUNCE_INTERVAL * 1000; - arp(/* ARPOP_REQUEST, */ - /* &G.eth_addr, */ chosen_nip, - &G.eth_addr, chosen_nip); - break; + send_arp_request(chosen_nip, &G.our_ethaddr, chosen_nip); + continue; } // Switch to monitor state // FIXME update filters @@ -416,124 +412,117 @@ int zcip_main(int argc UNUSED_PARAM, char **argv) // NOTE: all other exit paths should deconfig... if (QUIT) return EXIT_SUCCESS; - conflicts = 0; - timeout_ms = -1; // Never timeout in the monitor state. - state = MONITOR; - break; - case DEFEND: + // fall through: switch_to_MONITOR + default: + // case DEFEND: + // case MONITOR: (shouldn't happen, MONITOR timeout is infinite) // Defend period ended with no ARP replies - we won - conflicts = 0; - timeout_ms = -1; + timeout_ms = -1; // never timeout in monitor state state = MONITOR; - break; - } // switch (state) - break; // case 0 (timeout) - - // packets arriving, or link went down - case 1: - // We need to adjust the timeout in case we didn't receive - // a conflicting packet. - if (timeout_ms > 0) { - unsigned diff = deadline_us - MONOTONIC_US(); - if ((int)(diff) < 0) { - // Current time is greater than the expected timeout time. - diff = 0; - } - VDBG("adjusting timeout\n"); - timeout_ms = (diff / 1000) | 1; // never 0 - } - - if ((fds[0].revents & POLLIN) == 0) { - if (fds[0].revents & POLLERR) { - // FIXME: links routinely go down; - // this shouldn't necessarily exit. - bb_error_msg("iface %s is down", argv_intf); - if (state >= MONITOR) { - // only if we are in MONITOR or DEFEND - run(argv, "deconfig", chosen_nip); - } - return EXIT_FAILURE; - } continue; } + } - // read ARP packet - if (safe_read(sock_fd, &p, sizeof(p)) < 0) { - bb_perror_msg_and_die(bb_msg_read_error); + // Packet arrived, or link went down. + // We need to adjust the timeout in case we didn't receive + // a conflicting packet. + if (timeout_ms > 0) { + unsigned diff = deadline_us - MONOTONIC_US(); + if ((int)(diff) < 0) { + // Current time is greater than the expected timeout time. + diff = 0; } + VDBG("adjusting timeout\n"); + timeout_ms = (diff / 1000) | 1; // never 0 + } - if (p.eth.ether_type != htons(ETHERTYPE_ARP)) - continue; - if (p.arp.arp_op != htons(ARPOP_REQUEST) - && p.arp.arp_op != htons(ARPOP_REPLY) - ) { - continue; + if ((fds[0].revents & POLLIN) == 0) { + if (fds[0].revents & POLLERR) { + // FIXME: links routinely go down; + // this shouldn't necessarily exit. + bb_error_msg("iface %s is down", argv_intf); + if (state >= MONITOR) { + // Only if we are in MONITOR or DEFEND + run(argv, "deconfig", chosen_nip); + } + return EXIT_FAILURE; } + continue; + } + + // Read ARP packet + if (safe_read(sock_fd, &p, sizeof(p)) < 0) { + bb_perror_msg_and_die(bb_msg_read_error); + } + + if (p.eth.ether_type != htons(ETHERTYPE_ARP)) + continue; + if (p.arp.arp_op != htons(ARPOP_REQUEST) + && p.arp.arp_op != htons(ARPOP_REPLY) + ) { + continue; + } #ifdef DEBUG - { - struct ether_addr *sha = (struct ether_addr *) p.arp.arp_sha; - struct ether_addr *tha = (struct ether_addr *) p.arp.arp_tha; - struct in_addr *spa = (struct in_addr *) p.arp.arp_spa; - struct in_addr *tpa = (struct in_addr *) p.arp.arp_tpa; - VDBG("source=%s %s\n", ether_ntoa(sha), inet_ntoa(*spa)); - VDBG("target=%s %s\n", ether_ntoa(tha), inet_ntoa(*tpa)); - } + { + struct ether_addr *sha = (struct ether_addr *) p.arp.arp_sha; + struct ether_addr *tha = (struct ether_addr *) p.arp.arp_tha; + struct in_addr *spa = (struct in_addr *) p.arp.arp_spa; + struct in_addr *tpa = (struct in_addr *) p.arp.arp_tpa; + VDBG("source=%s %s\n", ether_ntoa(sha), inet_ntoa(*spa)); + VDBG("target=%s %s\n", ether_ntoa(tha), inet_ntoa(*tpa)); + } #endif - ip_conflict = 0; - if (memcmp(&p.arp.arp_sha, &G.eth_addr, ETH_ALEN) != 0) { - if (memcmp(p.arp.arp_spa, &chosen_nip, 4) == 0) { - // A probe or reply with source_ip == chosen ip - ip_conflict = 1; - } - if (p.arp.arp_op == htons(ARPOP_REQUEST) - && memcmp(p.arp.arp_spa, &const_int_0, 4) == 0 - && memcmp(p.arp.arp_tpa, &chosen_nip, 4) == 0 - ) { - // A probe with source_ip == 0.0.0.0, target_ip == chosen ip: - // another host trying to claim this ip! - ip_conflict |= 2; - } + ip_conflict = 0; + if (memcmp(&p.arp.arp_sha, &G.our_ethaddr, ETH_ALEN) != 0) { + if (memcmp(p.arp.arp_spa, &chosen_nip, 4) == 0) { + // A probe or reply with source_ip == chosen ip + ip_conflict = 1; } - VDBG("state:%d ip_conflict:%d\n", state, ip_conflict); - if (!ip_conflict) - break; - - // Either src or target IP conflict exists - if (state <= ANNOUNCE) { - // PROBE or ANNOUNCE - conflicts++; - timeout_ms = PROBE_MIN * 1000 - + CONFLICT_MULTIPLIER * random_delay_ms(conflicts); - chosen_nip = pick_nip(); - nsent = 0; - state = PROBE; - break; + if (p.arp.arp_op == htons(ARPOP_REQUEST) + && memcmp(p.arp.arp_spa, &const_int_0, 4) == 0 + && memcmp(p.arp.arp_tpa, &chosen_nip, 4) == 0 + ) { + // A probe with source_ip == 0.0.0.0, target_ip == chosen ip: + // another host trying to claim this ip! + ip_conflict |= 2; } - // MONITOR or DEFEND: only src IP conflict is a problem - if (ip_conflict & 1) { - if (state == MONITOR) { - // Src IP conflict, defend with a single ARP probe - VDBG("monitor conflict - defending\n"); - timeout_ms = DEFEND_INTERVAL * 1000; - state = DEFEND; - arp(/* ARPOP_REQUEST, */ - /* &G.eth_addr, */ chosen_nip, - &G.eth_addr, chosen_nip); - break; - } - // state == DEFEND - // Another src IP conflict, start over - VDBG("defend conflict - starting over\n"); - run(argv, "deconfig", chosen_nip); - - // restart the whole protocol - timeout_ms = 0; - chosen_nip = pick_nip(); - nsent = 0; - state = PROBE; + } + VDBG("state:%d ip_conflict:%d\n", state, ip_conflict); + if (!ip_conflict) + continue; + + // Either src or target IP conflict exists + if (state <= ANNOUNCE) { + // PROBE or ANNOUNCE + conflicts++; + timeout_ms = PROBE_MIN * 1000 + + CONFLICT_MULTIPLIER * random_delay_ms(conflicts); + goto new_nip_and_PROBE; + } + + // MONITOR or DEFEND: only src IP conflict is a problem + if (ip_conflict & 1) { + if (state == MONITOR) { + // Src IP conflict, defend with a single ARP probe + VDBG("monitor conflict - defending\n"); + timeout_ms = DEFEND_INTERVAL * 1000; + state = DEFEND; + send_arp_request(chosen_nip, &G.our_ethaddr, chosen_nip); + continue; } - break; // case 1 (packet arrived) - } // switch (poll) + // state == DEFEND + // Another src IP conflict, start over + VDBG("defend conflict - starting over\n"); + run(argv, "deconfig", chosen_nip); + conflicts = 0; + timeout_ms = 0; + goto new_nip_and_PROBE; + } + // Note: if we only have a target IP conflict here (ip_conflict & 2), + // IOW: if we just saw this sort of ARP packet: + // aa:bb:cc:dd:ee:ff > xx:xx:xx:xx:xx:xx: arp who-has <chosen_nip> tell 0.0.0.0 + // we expect _kernel_ to respond to that, because <chosen_nip> + // is (expected to be) configured on this iface. } // while (1) #undef argv_intf } -- cgit v1.2.3-55-g6feb From a83e3ae172dd516f8aa3e075a9cb292339606ed6 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko <vda.linux@googlemail.com> Date: Tue, 4 Aug 2015 15:06:38 +0200 Subject: zcip: tweak comments and make unsigned division more obvious Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com> --- networking/zcip.c | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/networking/zcip.c b/networking/zcip.c index a167c7e91..dba269bd8 100644 --- a/networking/zcip.c +++ b/networking/zcip.c @@ -56,9 +56,6 @@ struct arp_packet { } PACKED; enum { - /* 169.254.0.0 */ - LINKLOCAL_ADDR = 0xa9fe0000, - /* 0-1 seconds before sending 1st probe */ PROBE_WAIT = 1, /* 1-2 seconds between probes */ @@ -70,7 +67,7 @@ enum { /* if probe/announce sees a conflict, multiply RANDOM(NUM_CONFLICT) by... */ CONFLICT_MULTIPLIER = 2, /* if we monitor and see a conflict, how long is defend state? */ - DEFEND_INTERVAL = 10 + DEFEND_INTERVAL = 10, }; /* States during the configuration process. */ @@ -196,7 +193,7 @@ static int run(char *argv[3], const char *param, uint32_t nip) */ static ALWAYS_INLINE unsigned random_delay_ms(unsigned secs) { - return rand() % (secs * 1000); + return (unsigned)rand() % (secs * 1000); } /** @@ -328,9 +325,9 @@ int zcip_main(int argc UNUSED_PARAM, char **argv) // - start with some address we want to try // - short random delay // - arp probes to see if another host uses it - // 00:04:e2:64:23:c2 > ff:ff:ff:ff:ff:ff: arp who-has 169.254.194.171 tell 0.0.0.0 + // 00:04:e2:64:23:c2 > ff:ff:ff:ff:ff:ff arp who-has 169.254.194.171 tell 0.0.0.0 // - arp announcements that we're claiming it - // 00:04:e2:64:23:c2 > ff:ff:ff:ff:ff:ff: arp who-has 169.254.194.171 (00:04:e2:64:23:c2) tell 169.254.194.171 + // 00:04:e2:64:23:c2 > ff:ff:ff:ff:ff:ff arp who-has 169.254.194.171 (00:04:e2:64:23:c2) tell 169.254.194.171 // - use it // - defend it, within limits // exit if: @@ -412,7 +409,7 @@ int zcip_main(int argc UNUSED_PARAM, char **argv) // NOTE: all other exit paths should deconfig... if (QUIT) return EXIT_SUCCESS; - // fall through: switch_to_MONITOR + // fall through: switch to MONITOR default: // case DEFEND: // case MONITOR: (shouldn't happen, MONITOR timeout is infinite) @@ -520,7 +517,7 @@ int zcip_main(int argc UNUSED_PARAM, char **argv) } // Note: if we only have a target IP conflict here (ip_conflict & 2), // IOW: if we just saw this sort of ARP packet: - // aa:bb:cc:dd:ee:ff > xx:xx:xx:xx:xx:xx: arp who-has <chosen_nip> tell 0.0.0.0 + // aa:bb:cc:dd:ee:ff > xx:xx:xx:xx:xx:xx arp who-has <chosen_nip> tell 0.0.0.0 // we expect _kernel_ to respond to that, because <chosen_nip> // is (expected to be) configured on this iface. } // while (1) -- cgit v1.2.3-55-g6feb From 72dcbe4df7f02b2176daf70c68835fc8a053a219 Mon Sep 17 00:00:00 2001 From: Ron Yorston <rmy@frippery.org> Date: Sun, 12 Jul 2015 21:19:28 +0100 Subject: ipcalc: fix trivial usage message Signed-off-by: Ron Yorston <rmy@frippery.org> Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com> --- networking/ipcalc.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/networking/ipcalc.c b/networking/ipcalc.c index 3c8b8bfc9..f4bacd7dc 100644 --- a/networking/ipcalc.c +++ b/networking/ipcalc.c @@ -13,7 +13,8 @@ */ //usage:#define ipcalc_trivial_usage -//usage: "[OPTIONS] ADDRESS[[/]NETMASK] [NETMASK]" +//usage: "[OPTIONS] ADDRESS" +//usage: IF_FEATURE_IPCALC_FANCY("[/PREFIX]") " [NETMASK]" //usage:#define ipcalc_full_usage "\n\n" //usage: "Calculate IP network settings from a IP address\n" //usage: IF_FEATURE_IPCALC_LONG_OPTIONS( -- cgit v1.2.3-55-g6feb From 26ccd3d062a1949d3fd73b01cdf55e700bde1981 Mon Sep 17 00:00:00 2001 From: Ron Yorston <rmy@pobox.com> Date: Tue, 4 Aug 2015 17:10:37 +0100 Subject: less: fix botched attempt to use last column Commit 1ecb996 attempted to make read_lines() use the last column of the terminal (as re_wrap() did). There were two problems with this: - The size of the buffer allocated for lines wasn't increased to allow for the extra character. - The test for width overflow was moved after the point where the next character was added to the buffer. This caused a buffer overflow in certain circumstances. For example, if the line beyond the end of the display was wider than the display read_lines() would initially read the partial line into a buffer. When the user moved down read_lines() would be called again to ensure the rest of the line was read. This would place the next character in the partial line before checking for overflow. This can be fixed by moving the test for overflow back to where it was before commit 1ecb996 and changing the comparison to `>` rather than `>=`. There are two other places where buffers are created without allowing for width+1 characters. Signed-off-by: Ron Yorston <rmy@pobox.com> Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com> --- miscutils/less.c | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/miscutils/less.c b/miscutils/less.c index 7a441bf7e..ccdb15fdc 100644 --- a/miscutils/less.c +++ b/miscutils/less.c @@ -456,7 +456,7 @@ static void read_lines(void) if (option_mask32 & FLAG_N) w -= 8; - p = current_line = ((char*)xmalloc(w + 4)) + 4; + p = current_line = ((char*)xmalloc(w + 5)) + 4; if (!last_terminated) { const char *cp = flines[max_fline]; p = stpcpy(p, cp); @@ -509,6 +509,16 @@ static void read_lines(void) *--p = '\0'; continue; } + { + size_t new_last_line_pos = last_line_pos + 1; + if (c == '\t') { + new_last_line_pos += 7; + new_last_line_pos &= (~7); + } + if ((int)new_last_line_pos > w) + break; + last_line_pos = new_last_line_pos; + } /* ok, we will eat this char */ readpos++; if (c == '\n') { @@ -520,16 +530,6 @@ static void read_lines(void) if (c == '\0') c = '\n'; *p++ = c; *p = '\0'; - { - size_t new_last_line_pos = last_line_pos + 1; - if (c == '\t') { - new_last_line_pos += 7; - new_last_line_pos &= (~7); - } - if ((int)new_last_line_pos >= w) - break; - last_line_pos = new_last_line_pos; - } } /* end of "read chars until we have a line" loop */ #if 0 //BUG: also triggers on this: @@ -573,7 +573,7 @@ static void read_lines(void) break; } max_fline++; - current_line = ((char*)xmalloc(w + 4)) + 4; + current_line = ((char*)xmalloc(w + 5)) + 4; p = current_line; last_line_pos = 0; } /* end of "read lines until we reach cur_fline" loop */ @@ -755,7 +755,7 @@ static void print_found(const char *line) char *growline; regmatch_t match_structs; - char buf[width]; + char buf[width+1]; const char *str = line; char *p = buf; size_t n; @@ -814,7 +814,7 @@ void print_found(const char *line); static void print_ascii(const char *str) { - char buf[width]; + char buf[width+1]; char *p; size_t n; -- cgit v1.2.3-55-g6feb From fb52769f4a18920e597359962addf60858f158b5 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko <vda.linux@googlemail.com> Date: Sun, 16 Aug 2015 19:56:16 +0200 Subject: arping: make help text clearer Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com> --- networking/arping.c | 23 +++++++++++------------ 1 file changed, 11 insertions(+), 12 deletions(-) diff --git a/networking/arping.c b/networking/arping.c index dbfd75ef5..8be1aac2c 100644 --- a/networking/arping.c +++ b/networking/arping.c @@ -13,11 +13,11 @@ //usage: "\n -f Quit on first ARP reply" //usage: "\n -q Quiet" //usage: "\n -b Keep broadcasting, don't go unicast" -//usage: "\n -D Duplicated address detection mode" +//usage: "\n -D Exit with 1 if DST_IP replies" //usage: "\n -U Unsolicited ARP mode, update your neighbors" //usage: "\n -A ARP answer mode, update your neighbors" //usage: "\n -c N Stop after sending N ARP requests" -//usage: "\n -w TIMEOUT Time to wait for ARP reply, seconds" +//usage: "\n -w TIMEOUT Seconds to wait for ARP reply" //usage: "\n -I IFACE Interface to use (default eth0)" //usage: "\n -s SRC_IP Sender IP address" //usage: "\n DST_IP Target IP address" @@ -162,7 +162,7 @@ static void catcher(void) alarm(1); } -static bool recv_pack(unsigned char *buf, int len, struct sockaddr_ll *FROM) +static void recv_pack(unsigned char *buf, int len, struct sockaddr_ll *FROM) { struct arphdr *ah = (struct arphdr *) buf; unsigned char *p = (unsigned char *) (ah + 1); @@ -181,33 +181,33 @@ static bool recv_pack(unsigned char *buf, int len, struct sockaddr_ll *FROM) if (FROM->sll_pkttype != PACKET_HOST && FROM->sll_pkttype != PACKET_BROADCAST && FROM->sll_pkttype != PACKET_MULTICAST) - return false; + return; /* Only these types are recognized */ if (ah->ar_op != htons(ARPOP_REQUEST) && ah->ar_op != htons(ARPOP_REPLY)) - return false; + return; /* ARPHRD check and this darned FDDI hack here :-( */ if (ah->ar_hrd != htons(FROM->sll_hatype) && (FROM->sll_hatype != ARPHRD_FDDI || ah->ar_hrd != htons(ARPHRD_ETHER))) - return false; + return; /* Protocol must be IP. */ if (ah->ar_pro != htons(ETH_P_IP) || (ah->ar_pln != 4) || (ah->ar_hln != me.sll_halen) || (len < (int)(sizeof(*ah) + 2 * (4 + ah->ar_hln)))) - return false; + return; move_from_unaligned32(src_ip.s_addr, p + ah->ar_hln); move_from_unaligned32(dst_ip.s_addr, p + ah->ar_hln + 4 + ah->ar_hln); if (dst.s_addr != src_ip.s_addr) - return false; + return; if (!(option_mask32 & DAD)) { if ((src.s_addr != dst_ip.s_addr) - || (memcmp(p + ah->ar_hln + 4, &me.sll_addr, ah->ar_hln))) - return false; + || (memcmp(p + ah->ar_hln + 4, &me.sll_addr, ah->ar_hln))) + return; } else { /* DAD packet was: src_ip = 0 (or some src) @@ -224,7 +224,7 @@ static bool recv_pack(unsigned char *buf, int len, struct sockaddr_ll *FROM) */ if ((memcmp(p, &me.sll_addr, me.sll_halen) == 0) || (src.s_addr && src.s_addr != dst_ip.s_addr)) - return false; + return; } if (!(option_mask32 & QUIET)) { int s_printed = 0; @@ -264,7 +264,6 @@ static bool recv_pack(unsigned char *buf, int len, struct sockaddr_ll *FROM) memcpy(he.sll_addr, p, me.sll_halen); option_mask32 |= UNICASTING; } - return true; } int arping_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; -- cgit v1.2.3-55-g6feb From d077565bb27966c47ea6f0e9de092133954b5807 Mon Sep 17 00:00:00 2001 From: Bartosz Golaszewski <bartekgola@gmail.com> Date: Thu, 13 Aug 2015 15:57:21 +0200 Subject: unit-tests: remove unnecesary field from struct bbunit_listelem In the initial submission struct bbunit_listelem was manipulated by custom list functions implemented in bbunit.c. Since the tests are now added to the list by llist_add_to_end(), which allocates the llist_t objects behind the scenes, there's no need for the *next field. function old new delta unit_main 142 141 -1 bbunit_strrstr_elem 24 16 -8 bbunit_obscure_weak_pass_elem 24 16 -8 bbunit_obscure_strong_pass_elem 24 16 -8 ------------------------------------------------------------------------------ (add/remove: 0/0 grow/shrink: 0/4 up/down: 0/-25) Total: -25 bytes Signed-off-by: Bartosz Golaszewski <bartekgola@gmail.com> Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com> --- include/libbb.h | 1 - libbb/bbunit.c | 1 - 2 files changed, 2 deletions(-) diff --git a/include/libbb.h b/include/libbb.h index 54d01b75a..136d4fd87 100644 --- a/include/libbb.h +++ b/include/libbb.h @@ -1983,7 +1983,6 @@ static ALWAYS_INLINE unsigned char bb_ascii_tolower(unsigned char a) typedef void (*bbunit_testfunc)(void); struct bbunit_listelem { - struct bbunit_listelem* next; const char* name; bbunit_testfunc testfunc; }; diff --git a/libbb/bbunit.c b/libbb/bbunit.c index 4c692d59f..66a7df945 100644 --- a/libbb/bbunit.c +++ b/libbb/bbunit.c @@ -71,7 +71,6 @@ int unit_main(int argc UNUSED_PARAM, char **argv UNUSED_PARAM) tests_failed++; } tests_run++; - el = el->next; } #if WANT_TIMING -- cgit v1.2.3-55-g6feb From 718e228adcd7b9592b504b55217d13f4216a0450 Mon Sep 17 00:00:00 2001 From: Bartosz Golaszewski <bartekgola@gmail.com> Date: Thu, 13 Aug 2015 15:57:22 +0200 Subject: unit-tests: remove code depending on WANT_TIMING Since there is no interest in merging a config option for WANT_TIMING, remove the parts of code depending on it altogether. While we're at it: add some newlines to improve readability. Signed-off-by: Bartosz Golaszewski <bartekgola@gmail.com> Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com> --- libbb/bbunit.c | 30 +++--------------------------- 1 file changed, 3 insertions(+), 27 deletions(-) diff --git a/libbb/bbunit.c b/libbb/bbunit.c index 66a7df945..db67b1081 100644 --- a/libbb/bbunit.c +++ b/libbb/bbunit.c @@ -17,8 +17,6 @@ #include "libbb.h" -#define WANT_TIMING 0 - static llist_t *tests = NULL; static unsigned tests_registered = 0; static int test_retval; @@ -34,38 +32,22 @@ void bbunit_settestfailed(void) test_retval = -1; } -#if WANT_TIMING -static void timeval_diff(struct timeval* res, - const struct timeval* x, - const struct timeval* y) -{ - long udiff = x->tv_usec - y->tv_usec; - - res->tv_sec = x->tv_sec - y->tv_sec - (udiff < 0); - res->tv_usec = (udiff >= 0 ? udiff : udiff + 1000000); -} -#endif - int unit_main(int argc UNUSED_PARAM, char **argv UNUSED_PARAM) MAIN_EXTERNALLY_VISIBLE; int unit_main(int argc UNUSED_PARAM, char **argv UNUSED_PARAM) { unsigned tests_run = 0; unsigned tests_failed = 0; -#if WANT_TIMING - struct timeval begin; - struct timeval end; - struct timeval time_spent; - gettimeofday(&begin, NULL); -#endif bb_error_msg("Running %d test(s)...", tests_registered); for (;;) { struct bbunit_listelem* el = llist_pop(&tests); if (!el) break; + bb_error_msg("Case: [%s]", el->name); test_retval = 0; el->testfunc(); + if (test_retval < 0) { bb_error_msg("[ERROR] [%s]: TEST FAILED", el->name); tests_failed++; @@ -73,17 +55,11 @@ int unit_main(int argc UNUSED_PARAM, char **argv UNUSED_PARAM) tests_run++; } -#if WANT_TIMING - gettimeofday(&end, NULL); - timeval_diff(&time_spent, &end, &begin); - bb_error_msg("Elapsed time %u.%06u seconds", - (int)time_spent.tv_sec, - (int)time_spent.tv_usec); -#endif if (tests_failed > 0) { bb_error_msg("[ERROR] %u test(s) FAILED", tests_failed); return EXIT_FAILURE; } + bb_error_msg("All tests passed"); return EXIT_SUCCESS; } -- cgit v1.2.3-55-g6feb From bb2fd67d0bfe16441d4b1d2e6ece83b04955b379 Mon Sep 17 00:00:00 2001 From: Bartosz Golaszewski <bartekgola@gmail.com> Date: Fri, 14 Aug 2015 08:50:00 +0200 Subject: Makefile: add missing libraries to LDLIBS Static build with CONFIG_PAM fails on Debian Jessie due to undefined references to libdl and libaudit. Static build without pam, but with libcrypt required fails as well due to undefined references to libpthread. Fix these two cases by adding the missing libraries to LDLIBS when appropriate. Signed-off-by: Bartosz Golaszewski <bartekgola@gmail.com> Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com> --- Makefile.flags | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/Makefile.flags b/Makefile.flags index a1ed1480a..bb90a08de 100644 --- a/Makefile.flags +++ b/Makefile.flags @@ -121,20 +121,20 @@ endif # fall back to using a temp file: CRYPT_AVAILABLE := $(shell echo 'int main(void){return 0;}' >crypttest.c; $(CC) $(CFLAGS) -lcrypt -o /dev/null crypttest.c >/dev/null 2>&1 && echo "y"; rm crypttest.c) ifeq ($(CRYPT_AVAILABLE),y) -LDLIBS += m crypt +LDLIBS += m crypt pthread else LDLIBS += m endif ifeq ($(CONFIG_PAM),y) -# libpam uses libpthread, so for static builds busybox must be linked to -# libpthread. On some platforms that requires an explicit -lpthread, so -# it should be in LDLIBS. For non-static builds, scripts/trylink will -# take care of removing -lpthread if possible. (Not bothering to check -# CONFIG_STATIC because even in a non-static build it could be that the -# only libpam available is libpam.a, so -lpthread could still be -# needed.) -LDLIBS += pam pam_misc pthread +# libpam uses libpthread, libdl and libaudit, so for static builds busybox +# must be linked to libpthread, libdl and libaudit. On some platforms that +# requires an explicit -lpthread, -ldl and -laudit, so it should be in +# LDLIBS. For non-static builds, scripts/trylink will take care of removing +# these flags if possible. (Not bothering to check CONFIG_STATIC because +# even in a non-static build it could be that the only libpam available is +# libpam.a, so -lpthread & Co. could still be needed.) +LDLIBS += pam pam_misc pthread dl audit endif ifeq ($(CONFIG_SELINUX),y) -- cgit v1.2.3-55-g6feb From 729b70646cc748e1e88ddaec3ed542adcf7fa3da Mon Sep 17 00:00:00 2001 From: Denys Vlasenko <vda.linux@googlemail.com> Date: Mon, 24 Aug 2015 18:56:46 +0200 Subject: traceroute: fix help text Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com> --- networking/traceroute.c | 66 +++++++++++++++++++++++++------------------------ 1 file changed, 34 insertions(+), 32 deletions(-) diff --git a/networking/traceroute.c b/networking/traceroute.c index 12ba614e8..855713605 100644 --- a/networking/traceroute.c +++ b/networking/traceroute.c @@ -211,60 +211,62 @@ */ //usage:#define traceroute_trivial_usage -//usage: "[-"IF_TRACEROUTE6("46")"FIldnrv] [-f 1ST_TTL] [-m MAXTTL] [-p PORT] [-q PROBES]\n" -//usage: " [-s SRC_IP] [-t TOS] [-w WAIT_SEC] [-g GATEWAY] [-i IFACE]\n" +//usage: "[-"IF_TRACEROUTE6("46")"FIlnrv] [-f 1ST_TTL] [-m MAXTTL] [-q PROBES] [-p PORT]\n" +//usage: " [-t TOS] [-w WAIT_SEC]" +//usage: IF_FEATURE_TRACEROUTE_SOURCE_ROUTE(" [-g GATEWAY]")" [-s SRC_IP] [-i IFACE]\n" //usage: " [-z PAUSE_MSEC] HOST [BYTES]" //usage:#define traceroute_full_usage "\n\n" //usage: "Trace the route to HOST\n" //usage: IF_TRACEROUTE6( //usage: "\n -4,-6 Force IP or IPv6 name resolution" //usage: ) -//usage: "\n -F Set the don't fragment bit" +//usage: "\n -F Set don't fragment bit" +//usage: IF_FEATURE_TRACEROUTE_USE_ICMP( //usage: "\n -I Use ICMP ECHO instead of UDP datagrams" -//usage: "\n -l Display the TTL value of the returned packet" -//usage: "\n -d Set SO_DEBUG options to socket" +//usage: ) +//usage: "\n -l Display TTL value of the returned packet" +//Currently disabled (TRACEROUTE_SO_DEBUG==0) +////usage: "\n -d Set SO_DEBUG options to socket" //usage: "\n -n Print numeric addresses" //usage: "\n -r Bypass routing tables, send directly to HOST" +//usage: IF_FEATURE_TRACEROUTE_VERBOSE( //usage: "\n -v Verbose" -//usage: "\n -m Max time-to-live (max number of hops)" -//usage: "\n -p Base UDP port number used in probes" +//usage: ) +//usage: "\n -f N First number of hops (default 1)" +//usage: "\n -m N Max number of hops" +//usage: "\n -q N Number of probes per hop (default 3)" +//usage: "\n -p N Base UDP port number used in probes" //usage: "\n (default 33434)" -//usage: "\n -q Number of probes per TTL (default 3)" -//usage: "\n -s IP address to use as the source address" -//usage: "\n -t Type-of-service in probe packets (default 0)" -//usage: "\n -w Time in seconds to wait for a response (default 3)" -//usage: "\n -g Loose source route gateway (8 max)" +//usage: "\n -s IP Source address" +//usage: "\n -i IFACE Source interface" +//usage: "\n -t N Type-of-service in probe packets (default 0)" +//usage: "\n -w SEC Time to wait for a response (default 3)" +//usage: "\n -g IP Loose source route gateway (8 max)" //usage: //usage:#define traceroute6_trivial_usage -//usage: "[-dnrv] [-m MAXTTL] [-p PORT] [-q PROBES]\n" -//usage: " [-s SRC_IP] [-t TOS] [-w WAIT_SEC] [-i IFACE]\n" +//usage: "[-nrv] [-m MAXTTL] [-q PROBES] [-p PORT]\n" +//usage: " [-t TOS] [-w WAIT_SEC] [-s SRC_IP] [-i IFACE]\n" //usage: " HOST [BYTES]" //usage:#define traceroute6_full_usage "\n\n" //usage: "Trace the route to HOST\n" -//usage: "\n -d Set SO_DEBUG options to socket" +//Currently disabled (TRACEROUTE_SO_DEBUG==0) +////usage: "\n -d Set SO_DEBUG options to socket" //usage: "\n -n Print numeric addresses" //usage: "\n -r Bypass routing tables, send directly to HOST" +//usage: IF_FEATURE_TRACEROUTE_VERBOSE( //usage: "\n -v Verbose" -//usage: "\n -m Max time-to-live (max number of hops)" -//usage: "\n -p Base UDP port number used in probes" -//usage: "\n (default is 33434)" -//usage: "\n -q Number of probes per TTL (default 3)" -//usage: "\n -s IP address to use as the source address" -//usage: "\n -t Type-of-service in probe packets (default 0)" -//usage: "\n -w Time in seconds to wait for a response (default 3)" +//usage: ) +//usage: "\n -m N Max number of hops" +//usage: "\n -q N Number of probes per hop (default 3)" +//usage: "\n -p N Base UDP port number used in probes" +//usage: "\n (default 33434)" +//usage: "\n -s IP Source address" +//usage: "\n -i IFACE Source interface" +//usage: "\n -t N Type-of-service in probe packets (default 0)" +//usage: "\n -w SEC Time wait for a response (default 3)" #define TRACEROUTE_SO_DEBUG 0 -/* TODO: undefs were uncommented - ??! we have config system for that! */ -/* probably ok to remove altogether */ -//#undef CONFIG_FEATURE_TRACEROUTE_VERBOSE -//#define CONFIG_FEATURE_TRACEROUTE_VERBOSE -//#undef CONFIG_FEATURE_TRACEROUTE_SOURCE_ROUTE -//#define CONFIG_FEATURE_TRACEROUTE_SOURCE_ROUTE -//#undef CONFIG_FEATURE_TRACEROUTE_USE_ICMP -//#define CONFIG_FEATURE_TRACEROUTE_USE_ICMP - - #include <net/if.h> #include <arpa/inet.h> #include <netinet/in.h> -- cgit v1.2.3-55-g6feb From 2db782bc7be70c34a756e2bc6d4a53e8f47bab20 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko <vda.linux@googlemail.com> Date: Mon, 24 Aug 2015 19:08:14 +0200 Subject: Merge setsockopt error messages Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com> --- networking/arping.c | 2 +- networking/ping.c | 2 +- networking/traceroute.c | 8 ++++---- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/networking/arping.c b/networking/arping.c index 8be1aac2c..9ac4a7cee 100644 --- a/networking/arping.c +++ b/networking/arping.c @@ -358,7 +358,7 @@ int arping_main(int argc UNUSED_PARAM, char **argv) saddr.sin_addr = dst; if (setsockopt(probe_fd, SOL_SOCKET, SO_DONTROUTE, &const_int_1, sizeof(const_int_1)) == -1) - bb_perror_msg("setsockopt(SO_DONTROUTE)"); + bb_perror_msg("setsockopt(%s)", "SO_DONTROUTE"); xconnect(probe_fd, (struct sockaddr *) &saddr, sizeof(saddr)); getsockname(probe_fd, (struct sockaddr *) &saddr, &alen); //never happens: diff --git a/networking/ping.c b/networking/ping.c index c475395e7..20489a070 100644 --- a/networking/ping.c +++ b/networking/ping.c @@ -756,7 +756,7 @@ static void ping6(len_and_sockaddr *lsa) } if (setsockopt(pingsock, IPPROTO_ICMPV6, ICMP6_FILTER, &filt, sizeof(filt)) < 0) - bb_error_msg_and_die("setsockopt(ICMP6_FILTER)"); + bb_error_msg_and_die("setsockopt(%s)", "ICMP6_FILTER"); } #endif /*ICMP6_FILTER*/ diff --git a/networking/traceroute.c b/networking/traceroute.c index 855713605..e41d89e9f 100644 --- a/networking/traceroute.c +++ b/networking/traceroute.c @@ -475,7 +475,7 @@ send_probe(int seq, int ttl) if (dest_lsa->u.sa.sa_family == AF_INET6) { res = setsockopt(sndsock, SOL_IPV6, IPV6_UNICAST_HOPS, &ttl, sizeof(ttl)); if (res < 0) - bb_perror_msg_and_die("setsockopt UNICAST_HOPS %d", ttl); + bb_perror_msg_and_die("setsockopt(%s) %d", "UNICAST_HOPS", ttl); out = outip; len = packlen; } else @@ -484,7 +484,7 @@ send_probe(int seq, int ttl) #if defined IP_TTL res = setsockopt(sndsock, IPPROTO_IP, IP_TTL, &ttl, sizeof(ttl)); if (res < 0) - bb_perror_msg_and_die("setsockopt ttl %d", ttl); + bb_perror_msg_and_die("setsockopt(%s) %d", "TTL", ttl); #endif out = outicmp; len = packlen - sizeof(*outip); @@ -929,7 +929,7 @@ common_traceroute_main(int op, char **argv) if (af == AF_INET6) { static const int two = 2; if (setsockopt(rcvsock, SOL_RAW, IPV6_CHECKSUM, &two, sizeof(two)) < 0) - bb_perror_msg_and_die("setsockopt RAW_CHECKSUM"); + bb_perror_msg_and_die("setsockopt(%s)", "IPV6_CHECKSUM"); xmove_fd(xsocket(af, SOCK_DGRAM, 0), sndsock); } else #endif @@ -972,7 +972,7 @@ common_traceroute_main(int op, char **argv) #endif #ifdef IP_TOS if ((op & OPT_TOS) && setsockopt(sndsock, IPPROTO_IP, IP_TOS, &tos, sizeof(tos)) < 0) { - bb_perror_msg_and_die("setsockopt tos %d", tos); + bb_perror_msg_and_die("setsockopt(%s) %d", "TOS", tos); } #endif #ifdef IP_DONTFRAG -- cgit v1.2.3-55-g6feb From c52cbea2bba6582b44facb424a15dc544b54fb28 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko <vda.linux@googlemail.com> Date: Mon, 24 Aug 2015 19:48:03 +0200 Subject: libbb: add setsockopt_foo helpers function old new delta setsockopt_int - 23 +23 do_load 918 934 +16 setsockopt_SOL_SOCKET_int - 14 +14 setsockopt_keepalive - 10 +10 setsockopt_SOL_SOCKET_1 - 10 +10 buffer_fill_and_print 169 178 +9 setsockopt_1 - 8 +8 nfsmount 3560 3566 +6 redirect 1277 1282 +5 tcpudpsvd_main 1782 1786 +4 d6_send_kernel_packet 272 275 +3 i2cget_main 380 382 +2 ed_main 2544 2545 +1 scan_recursive 380 378 -2 nbdclient_main 492 490 -2 hash_find 235 233 -2 cmdputs 334 332 -2 parse_command 1443 1440 -3 static.two 4 - -4 ntpd_main 1039 1035 -4 const_int_1 4 - -4 const_IPTOS_LOWDELAY 4 - -4 RCVBUF 4 - -4 ntp_init 474 469 -5 change_listen_mode 316 310 -6 uevent_main 416 409 -7 arping_main 1697 1690 -7 telnet_main 1612 1603 -9 socket_want_pktinfo 42 33 -9 setsockopt_reuseaddr 21 10 -11 setsockopt_broadcast 21 10 -11 httpd_main 772 757 -15 get_remote_transfer_fd 109 94 -15 make_new_session 503 487 -16 ftpd_main 2177 2160 -17 read_bunzip 1896 1866 -30 common_traceroute_main 4099 4058 -41 common_ping_main 1836 1783 -53 ------------------------------------------------------------------------------ (add/remove: 5/4 grow/shrink: 8/21 up/down: 111/-283) Total: -172 bytes Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com> --- include/libbb.h | 8 +++++++- libbb/messages.c | 2 +- libbb/udp_io.c | 4 ++-- libbb/xconnect.c | 25 +++++++++++++++++++++++-- networking/arping.c | 2 +- networking/ftpd.c | 8 ++++---- networking/httpd.c | 4 ++-- networking/nbd-client.c | 2 +- networking/nc_bloaty.c | 4 ++-- networking/ntpd.c | 6 ++---- networking/ping.c | 16 ++++++++-------- networking/telnet.c | 2 +- networking/telnetd.c | 2 +- networking/traceroute.c | 41 ++++++++++++++++------------------------- networking/udhcp/dhcpc.c | 4 +--- util-linux/uevent.c | 6 +++--- 16 files changed, 75 insertions(+), 61 deletions(-) diff --git a/include/libbb.h b/include/libbb.h index 136d4fd87..2e20706e7 100644 --- a/include/libbb.h +++ b/include/libbb.h @@ -561,6 +561,11 @@ void xlisten(int s, int backlog) FAST_FUNC; void xconnect(int s, const struct sockaddr *s_addr, socklen_t addrlen) FAST_FUNC; ssize_t xsendto(int s, const void *buf, size_t len, const struct sockaddr *to, socklen_t tolen) FAST_FUNC; + +int setsockopt_int(int fd, int level, int optname, int optval) FAST_FUNC; +int setsockopt_1(int fd, int level, int optname) FAST_FUNC; +int setsockopt_SOL_SOCKET_int(int fd, int optname, int optval) FAST_FUNC; +int setsockopt_SOL_SOCKET_1(int fd, int optname) FAST_FUNC; /* SO_REUSEADDR allows a server to rebind to an address that is already * "in use" by old connections to e.g. previous server instance which is * killed or crashed. Without it bind will fail until all such connections @@ -568,6 +573,7 @@ ssize_t xsendto(int s, const void *buf, size_t len, const struct sockaddr *to, * regardless of SO_REUSEADDR (unlike some other flavors of Unix). * Turn it on before you call bind(). */ void setsockopt_reuseaddr(int fd) FAST_FUNC; /* On Linux this never fails. */ +int setsockopt_keepalive(int fd) FAST_FUNC; int setsockopt_broadcast(int fd) FAST_FUNC; int setsockopt_bindtodevice(int fd, const char *iface) FAST_FUNC; /* NB: returns port in host byte order */ @@ -1807,7 +1813,7 @@ extern const char bb_PATH_root_path[] ALIGN1; /* "PATH=/sbin:/usr/sbin:/bin:/usr #define bb_default_path (bb_PATH_root_path + sizeof("PATH=/sbin:/usr/sbin")) extern const int const_int_0; -extern const int const_int_1; +//extern const int const_int_1; /* Providing hard guarantee on minimum size (think of BUFSIZ == 128) */ diff --git a/libbb/messages.c b/libbb/messages.c index fad82c9da..c1b7ba252 100644 --- a/libbb/messages.c +++ b/libbb/messages.c @@ -43,7 +43,7 @@ const char bb_PATH_root_path[] ALIGN1 = "PATH=/sbin:/usr/sbin:/bin:/usr/bin" BB_ADDITIONAL_PATH; -const int const_int_1 = 1; +//const int const_int_1 = 1; /* explicitly = 0, otherwise gcc may make it a common variable * and it will end up in bss */ const int const_int_0 = 0; diff --git a/libbb/udp_io.c b/libbb/udp_io.c index 7985a9723..a32af9bd2 100644 --- a/libbb/udp_io.c +++ b/libbb/udp_io.c @@ -16,10 +16,10 @@ void FAST_FUNC socket_want_pktinfo(int fd UNUSED_PARAM) { #ifdef IP_PKTINFO - setsockopt(fd, IPPROTO_IP, IP_PKTINFO, &const_int_1, sizeof(int)); + setsockopt_1(fd, IPPROTO_IP, IP_PKTINFO); #endif #if ENABLE_FEATURE_IPV6 && defined(IPV6_PKTINFO) - setsockopt(fd, IPPROTO_IPV6, IPV6_PKTINFO, &const_int_1, sizeof(int)); + setsockopt_1(fd, IPPROTO_IPV6, IPV6_PKTINFO); #endif } diff --git a/libbb/xconnect.c b/libbb/xconnect.c index 2a96e03dc..6e78e6363 100644 --- a/libbb/xconnect.c +++ b/libbb/xconnect.c @@ -14,13 +14,34 @@ #include <sys/un.h> #include "libbb.h" +int FAST_FUNC setsockopt_int(int fd, int level, int optname, int optval) +{ + return setsockopt(fd, level, optname, &optval, sizeof(int)); +} +int FAST_FUNC setsockopt_1(int fd, int level, int optname) +{ + return setsockopt_int(fd, level, optname, 1); +} +int FAST_FUNC setsockopt_SOL_SOCKET_int(int fd, int optname, int optval) +{ + return setsockopt_int(fd, SOL_SOCKET, optname, optval); +} +int FAST_FUNC setsockopt_SOL_SOCKET_1(int fd, int optname) +{ + return setsockopt_SOL_SOCKET_int(fd, optname, 1); +} + void FAST_FUNC setsockopt_reuseaddr(int fd) { - setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &const_int_1, sizeof(const_int_1)); + setsockopt_SOL_SOCKET_1(fd, SO_REUSEADDR); } int FAST_FUNC setsockopt_broadcast(int fd) { - return setsockopt(fd, SOL_SOCKET, SO_BROADCAST, &const_int_1, sizeof(const_int_1)); + return setsockopt_SOL_SOCKET_1(fd, SO_BROADCAST); +} +int FAST_FUNC setsockopt_keepalive(int fd) +{ + return setsockopt_SOL_SOCKET_1(fd, SO_KEEPALIVE); } #ifdef SO_BINDTODEVICE diff --git a/networking/arping.c b/networking/arping.c index 9ac4a7cee..ce7fa299c 100644 --- a/networking/arping.c +++ b/networking/arping.c @@ -357,7 +357,7 @@ int arping_main(int argc UNUSED_PARAM, char **argv) saddr.sin_port = htons(1025); saddr.sin_addr = dst; - if (setsockopt(probe_fd, SOL_SOCKET, SO_DONTROUTE, &const_int_1, sizeof(const_int_1)) == -1) + if (setsockopt_SOL_SOCKET_1(probe_fd, SO_DONTROUTE) != 0) bb_perror_msg("setsockopt(%s)", "SO_DONTROUTE"); xconnect(probe_fd, (struct sockaddr *) &saddr, sizeof(saddr)); getsockname(probe_fd, (struct sockaddr *) &saddr, &alen); diff --git a/networking/ftpd.c b/networking/ftpd.c index 2351d6dd3..7735b7233 100644 --- a/networking/ftpd.c +++ b/networking/ftpd.c @@ -377,7 +377,7 @@ ftpdataio_get_pasv_fd(void) return remote_fd; } - setsockopt(remote_fd, SOL_SOCKET, SO_KEEPALIVE, &const_int_1, sizeof(const_int_1)); + setsockopt_keepalive(remote_fd); return remote_fd; } @@ -1186,11 +1186,11 @@ int ftpd_main(int argc UNUSED_PARAM, char **argv) , SIG_IGN); /* Set up options on the command socket (do we need these all? why?) */ - setsockopt(STDIN_FILENO, IPPROTO_TCP, TCP_NODELAY, &const_int_1, sizeof(const_int_1)); - setsockopt(STDIN_FILENO, SOL_SOCKET, SO_KEEPALIVE, &const_int_1, sizeof(const_int_1)); + setsockopt_1(STDIN_FILENO, IPPROTO_TCP, TCP_NODELAY); + setsockopt_keepalive(STDIN_FILENO); /* Telnet protocol over command link may send "urgent" data, * we prefer it to be received in the "normal" data stream: */ - setsockopt(STDIN_FILENO, SOL_SOCKET, SO_OOBINLINE, &const_int_1, sizeof(const_int_1)); + setsockopt_1(STDIN_FILENO, SOL_SOCKET, SO_OOBINLINE); WRITE_OK(FTP_GREET); signal(SIGALRM, timeout_handler); diff --git a/networking/httpd.c b/networking/httpd.c index 7a9065fcc..feaaa94d5 100644 --- a/networking/httpd.c +++ b/networking/httpd.c @@ -2352,7 +2352,7 @@ static void mini_httpd(int server_socket) continue; /* set the KEEPALIVE option to cull dead connections */ - setsockopt(n, SOL_SOCKET, SO_KEEPALIVE, &const_int_1, sizeof(const_int_1)); + setsockopt_keepalive(n); if (fork() == 0) { /* child */ @@ -2395,7 +2395,7 @@ static void mini_httpd_nommu(int server_socket, int argc, char **argv) continue; /* set the KEEPALIVE option to cull dead connections */ - setsockopt(n, SOL_SOCKET, SO_KEEPALIVE, &const_int_1, sizeof(const_int_1)); + setsockopt_keepalive(n); if (vfork() == 0) { /* child */ diff --git a/networking/nbd-client.c b/networking/nbd-client.c index cadda5261..a601430b6 100644 --- a/networking/nbd-client.c +++ b/networking/nbd-client.c @@ -83,7 +83,7 @@ int nbdclient_main(int argc, char **argv) // Find and connect to server sock = create_and_connect_stream_or_die(host, xatou16(port)); - setsockopt(sock, IPPROTO_TCP, TCP_NODELAY, &const_int_1, sizeof(const_int_1)); + setsockopt_1(sock, IPPROTO_TCP, TCP_NODELAY); // Log on to the server xread(sock, &nbd_header, 8+8+8+4 + 124); diff --git a/networking/nc_bloaty.c b/networking/nc_bloaty.c index b28d05f51..471ae1a12 100644 --- a/networking/nc_bloaty.c +++ b/networking/nc_bloaty.c @@ -863,8 +863,8 @@ int nc_main(int argc UNUSED_PARAM, char **argv) xbind(netfd, &ouraddr->u.sa, ouraddr->len); } #if 0 - setsockopt(netfd, SOL_SOCKET, SO_RCVBUF, &o_rcvbuf, sizeof o_rcvbuf); - setsockopt(netfd, SOL_SOCKET, SO_SNDBUF, &o_sndbuf, sizeof o_sndbuf); + setsockopt_SOL_SOCKET_int(netfd, SO_RCVBUF, o_rcvbuf); + setsockopt_SOL_SOCKET_int(netfd, SO_SNDBUF, o_sndbuf); #endif #ifdef BLOAT diff --git a/networking/ntpd.c b/networking/ntpd.c index b5120a70d..9732c9b1a 100644 --- a/networking/ntpd.c +++ b/networking/ntpd.c @@ -405,8 +405,6 @@ struct globals { }; #define G (*ptr_to_globals) -static const int const_IPTOS_LOWDELAY = IPTOS_LOWDELAY; - #define VERB1 if (MAX_VERBOSE && G.verbose) #define VERB2 if (MAX_VERBOSE >= 2 && G.verbose >= 2) @@ -837,7 +835,7 @@ send_query_to_peer(peer_t *p) #if ENABLE_FEATURE_IPV6 if (family == AF_INET) #endif - setsockopt(fd, IPPROTO_IP, IP_TOS, &const_IPTOS_LOWDELAY, sizeof(const_IPTOS_LOWDELAY)); + setsockopt_int(fd, IPPROTO_IP, IP_TOS, IPTOS_LOWDELAY); free(local_lsa); } @@ -2186,7 +2184,7 @@ static NOINLINE void ntp_init(char **argv) xfunc_die(); } socket_want_pktinfo(G_listen_fd); - setsockopt(G_listen_fd, IPPROTO_IP, IP_TOS, &const_IPTOS_LOWDELAY, sizeof(const_IPTOS_LOWDELAY)); + setsockopt_int(G_listen_fd, IPPROTO_IP, IP_TOS, IPTOS_LOWDELAY); } #endif if (!(opts & OPT_n)) { diff --git a/networking/ping.c b/networking/ping.c index 20489a070..e1f9ebc3a 100644 --- a/networking/ping.c +++ b/networking/ping.c @@ -247,7 +247,7 @@ static void ping6(len_and_sockaddr *lsa) pkt->icmp6_type = ICMP6_ECHO_REQUEST; sockopt = offsetof(struct icmp6_hdr, icmp6_cksum); - setsockopt(pingsock, SOL_RAW, IPV6_CHECKSUM, &sockopt, sizeof(sockopt)); + setsockopt_int(pingsock, SOL_RAW, IPV6_CHECKSUM, sockopt); xsendto(pingsock, G.packet, DEFDATALEN + sizeof(struct icmp6_hdr), &lsa->u.sa, lsa->len); @@ -700,12 +700,12 @@ static void ping4(len_and_sockaddr *lsa) /* set recv buf (needed if we can get lots of responses: flood ping, * broadcast ping etc) */ sockopt = (datalen * 2) + 7 * 1024; /* giving it a bit of extra room */ - setsockopt(pingsock, SOL_SOCKET, SO_RCVBUF, &sockopt, sizeof(sockopt)); + setsockopt_SOL_SOCKET_int(pingsock, SO_RCVBUF, sockopt); if (opt_ttl != 0) { - setsockopt(pingsock, IPPROTO_IP, IP_TTL, &opt_ttl, sizeof(opt_ttl)); + setsockopt_int(pingsock, IPPROTO_IP, IP_TTL, opt_ttl); /* above doesnt affect packets sent to bcast IP, so... */ - setsockopt(pingsock, IPPROTO_IP, IP_MULTICAST_TTL, &opt_ttl, sizeof(opt_ttl)); + setsockopt_int(pingsock, IPPROTO_IP, IP_MULTICAST_TTL, opt_ttl); } signal(SIGINT, print_stats_and_exit); @@ -766,15 +766,15 @@ static void ping6(len_and_sockaddr *lsa) /* set recv buf (needed if we can get lots of responses: flood ping, * broadcast ping etc) */ sockopt = (datalen * 2) + 7 * 1024; /* giving it a bit of extra room */ - setsockopt(pingsock, SOL_SOCKET, SO_RCVBUF, &sockopt, sizeof(sockopt)); + setsockopt_SOL_SOCKET_int(pingsock, SO_RCVBUF, sockopt); sockopt = offsetof(struct icmp6_hdr, icmp6_cksum); - if (offsetof(struct icmp6_hdr, icmp6_cksum) != 2) + if (sockopt != 2) BUG_bad_offsetof_icmp6_cksum(); - setsockopt(pingsock, SOL_RAW, IPV6_CHECKSUM, &sockopt, sizeof(sockopt)); + setsockopt_int(pingsock, SOL_RAW, IPV6_CHECKSUM, sockopt); /* request ttl info to be returned in ancillary data */ - setsockopt(pingsock, SOL_IPV6, IPV6_HOPLIMIT, &const_int_1, sizeof(const_int_1)); + setsockopt_1(pingsock, SOL_IPV6, IPV6_HOPLIMIT); if (if_index) pingaddr.sin6.sin6_scope_id = if_index; diff --git a/networking/telnet.c b/networking/telnet.c index a25579773..3bb6fb1ba 100644 --- a/networking/telnet.c +++ b/networking/telnet.c @@ -623,7 +623,7 @@ int telnet_main(int argc UNUSED_PARAM, char **argv) xmove_fd(create_and_connect_stream_or_die(host, port), netfd); - setsockopt(netfd, SOL_SOCKET, SO_KEEPALIVE, &const_int_1, sizeof(const_int_1)); + setsockopt_keepalive(netfd); signal(SIGINT, record_signo); diff --git a/networking/telnetd.c b/networking/telnetd.c index 6aee95871..25d05fe7a 100644 --- a/networking/telnetd.c +++ b/networking/telnetd.c @@ -265,7 +265,7 @@ make_new_session( close_on_exec_on(fd); /* SO_KEEPALIVE by popular demand */ - setsockopt(sock, SOL_SOCKET, SO_KEEPALIVE, &const_int_1, sizeof(const_int_1)); + setsockopt_keepalive(sock); #if ENABLE_FEATURE_TELNETD_STANDALONE ts->sockfd_read = sock; ndelay_on(sock); diff --git a/networking/traceroute.c b/networking/traceroute.c index e41d89e9f..642110c54 100644 --- a/networking/traceroute.c +++ b/networking/traceroute.c @@ -473,8 +473,8 @@ send_probe(int seq, int ttl) #if ENABLE_TRACEROUTE6 if (dest_lsa->u.sa.sa_family == AF_INET6) { - res = setsockopt(sndsock, SOL_IPV6, IPV6_UNICAST_HOPS, &ttl, sizeof(ttl)); - if (res < 0) + res = setsockopt_int(sndsock, SOL_IPV6, IPV6_UNICAST_HOPS, ttl); + if (res != 0) bb_perror_msg_and_die("setsockopt(%s) %d", "UNICAST_HOPS", ttl); out = outip; len = packlen; @@ -482,8 +482,8 @@ send_probe(int seq, int ttl) #endif { #if defined IP_TTL - res = setsockopt(sndsock, IPPROTO_IP, IP_TTL, &ttl, sizeof(ttl)); - if (res < 0) + res = setsockopt_int(sndsock, IPPROTO_IP, IP_TTL, ttl); + if (res != 0) bb_perror_msg_and_die("setsockopt(%s) %d", "TTL", ttl); #endif out = outicmp; @@ -902,13 +902,10 @@ common_traceroute_main(int op, char **argv) if (af == AF_INET6) { xmove_fd(xsocket(AF_INET6, SOCK_RAW, IPPROTO_ICMPV6), rcvsock); # ifdef IPV6_RECVPKTINFO - setsockopt(rcvsock, SOL_IPV6, IPV6_RECVPKTINFO, - &const_int_1, sizeof(const_int_1)); - setsockopt(rcvsock, SOL_IPV6, IPV6_2292PKTINFO, - &const_int_1, sizeof(const_int_1)); + setsockopt_1(rcvsock, SOL_IPV6, IPV6_RECVPKTINFO); + setsockopt_1(rcvsock, SOL_IPV6, IPV6_2292PKTINFO); # else - setsockopt(rcvsock, SOL_IPV6, IPV6_PKTINFO, - &const_int_1, sizeof(const_int_1)); + setsockopt_1(rcvsock, SOL_IPV6, IPV6_PKTINFO); # endif } else #endif @@ -918,17 +915,14 @@ common_traceroute_main(int op, char **argv) #if TRACEROUTE_SO_DEBUG if (op & OPT_DEBUG) - setsockopt(rcvsock, SOL_SOCKET, SO_DEBUG, - &const_int_1, sizeof(const_int_1)); + setsockopt_SOL_SOCKET_1(rcvsock, SO_DEBUG); #endif if (op & OPT_BYPASS_ROUTE) - setsockopt(rcvsock, SOL_SOCKET, SO_DONTROUTE, - &const_int_1, sizeof(const_int_1)); + setsockopt_SOL_SOCKET_1(rcvsock, SO_DONTROUTE); #if ENABLE_TRACEROUTE6 if (af == AF_INET6) { - static const int two = 2; - if (setsockopt(rcvsock, SOL_RAW, IPV6_CHECKSUM, &two, sizeof(two)) < 0) + if (setsockopt_int(rcvsock, SOL_RAW, IPV6_CHECKSUM, 2) != 0) bb_perror_msg_and_die("setsockopt(%s)", "IPV6_CHECKSUM"); xmove_fd(xsocket(af, SOCK_DGRAM, 0), sndsock); } else @@ -966,28 +960,25 @@ common_traceroute_main(int op, char **argv) } #ifdef SO_SNDBUF - if (setsockopt(sndsock, SOL_SOCKET, SO_SNDBUF, &packlen, sizeof(packlen)) < 0) { - bb_perror_msg_and_die("SO_SNDBUF"); + if (setsockopt_SOL_SOCKET_int(sndsock, SO_SNDBUF, packlen) != 0) { + bb_perror_msg_and_die("setsockopt(%s)", "SO_SNDBUF"); } #endif #ifdef IP_TOS - if ((op & OPT_TOS) && setsockopt(sndsock, IPPROTO_IP, IP_TOS, &tos, sizeof(tos)) < 0) { + if ((op & OPT_TOS) && setsockopt_int(sndsock, IPPROTO_IP, IP_TOS, tos) != 0) { bb_perror_msg_and_die("setsockopt(%s) %d", "TOS", tos); } #endif #ifdef IP_DONTFRAG if (op & OPT_DONT_FRAGMNT) - setsockopt(sndsock, IPPROTO_IP, IP_DONTFRAG, - &const_int_1, sizeof(const_int_1)); + setsockopt_1(sndsock, IPPROTO_IP, IP_DONTFRAG); #endif #if TRACEROUTE_SO_DEBUG if (op & OPT_DEBUG) - setsockopt(sndsock, SOL_SOCKET, SO_DEBUG, - &const_int_1, sizeof(const_int_1)); + setsockopt_SOL_SOCKET_1(sndsock, SO_DEBUG); #endif if (op & OPT_BYPASS_ROUTE) - setsockopt(sndsock, SOL_SOCKET, SO_DONTROUTE, - &const_int_1, sizeof(const_int_1)); + setsockopt_SOL_SOCKET_1(sndsock, SO_DONTROUTE); outip = xzalloc(packlen); diff --git a/networking/udhcp/dhcpc.c b/networking/udhcp/dhcpc.c index 811a1a1ee..11f7b2d49 100644 --- a/networking/udhcp/dhcpc.c +++ b/networking/udhcp/dhcpc.c @@ -1043,9 +1043,7 @@ static int udhcp_raw_socket(int ifindex) } #endif - if (setsockopt(fd, SOL_PACKET, PACKET_AUXDATA, - &const_int_1, sizeof(int)) < 0 - ) { + if (setsockopt_1(fd, SOL_PACKET, PACKET_AUXDATA) != 0) { if (errno != ENOPROTOOPT) log1("Can't set PACKET_AUXDATA on raw socket"); } diff --git a/util-linux/uevent.c b/util-linux/uevent.c index fb98b4845..514a9e934 100644 --- a/util-linux/uevent.c +++ b/util-linux/uevent.c @@ -37,7 +37,7 @@ enum { #ifndef SO_RCVBUFFORCE #define SO_RCVBUFFORCE 33 #endif -static const int RCVBUF = 2 * 1024 * 1024; +enum { RCVBUF = 2 * 1024 * 1024 }; int uevent_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; int uevent_main(int argc UNUSED_PARAM, char **argv) @@ -63,8 +63,8 @@ int uevent_main(int argc UNUSED_PARAM, char **argv) // find /sys -name uevent -exec sh -c 'echo add >"{}"' ';' // // SO_RCVBUFFORCE (root only) can go above net.core.rmem_max sysctl - setsockopt(fd, SOL_SOCKET, SO_RCVBUF, &RCVBUF, sizeof(RCVBUF)); - setsockopt(fd, SOL_SOCKET, SO_RCVBUFFORCE, &RCVBUF, sizeof(RCVBUF)); + setsockopt_SOL_SOCKET_int(fd, SO_RCVBUF, RCVBUF); + setsockopt_SOL_SOCKET_int(fd, SO_RCVBUFFORCE, RCVBUF); if (0) { int z; socklen_t zl = sizeof(z); -- cgit v1.2.3-55-g6feb From 65c501a093b6ae1f8344a71378fd99f27177adaf Mon Sep 17 00:00:00 2001 From: Alex Dowad <alexinbeijing@gmail.com> Date: Fri, 7 Aug 2015 11:53:26 +0200 Subject: ifupdown: 'prio' should have been 'metric' in static_up and static_up6 When a static interface with explicit gateway and metric in /etc/network/interfaces is enabled using 'ifup', and further, the BusyBox 'ip' applet is enabled, the following error message appears at the console (and no default route is added): ip: either "to" is duplicate, or "prio" is garbage Tracing ifup reveals that it is attempting to run the following shell command: ip route add default via <GW> dev <DEVICE> prio <METRIC> 'ip' does not understand the 'prio' argument, causing this error. With 'metric', it works fine. Signed-off-by: Alex Dowad <alexinbeijing@gmail.com> Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com> --- networking/ifupdown.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/networking/ifupdown.c b/networking/ifupdown.c index 606fc049f..7c45e8927 100644 --- a/networking/ifupdown.c +++ b/networking/ifupdown.c @@ -395,7 +395,7 @@ static int FAST_FUNC static_up6(struct interface_defn_t *ifd, execfn *exec) 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%]][[ prio %metric%]]", ifd, exec); + result += execute("[[ip route add ::/0 via %gateway%]][[ 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); @@ -482,7 +482,7 @@ static int FAST_FUNC static_up(struct interface_defn_t *ifd, execfn *exec) result = execute("ip addr add %address%/%bnmask%[[ broadcast %broadcast%]] " "dev %iface%[[ peer %pointopoint%]][[ label %label%]]", ifd, exec); result += execute("ip link set[[ mtu %mtu%]][[ addr %hwaddress%]] %iface% up", ifd, exec); - result += execute("[[ip route add default via %gateway% dev %iface%[[ prio %metric%]]]]", ifd, exec); + result += execute("[[ip route add default via %gateway% dev %iface%[[ metric %metric%]]]]", ifd, exec); return ((result == 3) ? 3 : 0); # else /* ifconfig said to set iface up before it processes hw %hwaddress%, -- cgit v1.2.3-55-g6feb From 864d1b7a1506002ef5804305b31e0fd7197c1ea4 Mon Sep 17 00:00:00 2001 From: Peter Korsgaard <peter@korsgaard.com> Date: Mon, 24 Aug 2015 15:54:49 +0200 Subject: dmesg: add -r option to print raw format even when FEATURE_DMESG_PRETTY is enabled Similar to the "big" util-linux version. For !DMESG_PRETTY, the option is accepted (but ignored) as well, for compatibility reasons. Signed-off-by: Peter Korsgaard <peter@korsgaard.com> Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com> --- util-linux/dmesg.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/util-linux/dmesg.c b/util-linux/dmesg.c index 81ba1c9d1..e543446c1 100644 --- a/util-linux/dmesg.c +++ b/util-linux/dmesg.c @@ -16,6 +16,7 @@ //usage: "\n -c Clear ring buffer after printing" //usage: "\n -n LEVEL Set console logging level" //usage: "\n -s SIZE Buffer size" +//usage: "\n -r Print raw message buffer" #include <sys/klog.h> #include "libbb.h" @@ -29,11 +30,12 @@ int dmesg_main(int argc UNUSED_PARAM, char **argv) enum { OPT_c = 1 << 0, OPT_s = 1 << 1, - OPT_n = 1 << 2 + OPT_n = 1 << 2, + OPT_r = 1 << 3 }; opt_complementary = "s+:n+"; /* numeric */ - opts = getopt32(argv, "cs:n:", &len, &level); + opts = getopt32(argv, "cs:n:r", &len, &level); if (opts & OPT_n) { if (klogctl(8, NULL, (long) level)) bb_perror_msg_and_die("klogctl"); @@ -55,7 +57,7 @@ int dmesg_main(int argc UNUSED_PARAM, char **argv) return EXIT_SUCCESS; - if (ENABLE_FEATURE_DMESG_PRETTY) { + if (ENABLE_FEATURE_DMESG_PRETTY && !(opts & OPT_r)) { int last = '\n'; int in = 0; -- cgit v1.2.3-55-g6feb From d86271732828117d32270e9f7b3d128d77e9fa57 Mon Sep 17 00:00:00 2001 From: Sören Tempel <soeren@soeren-tempel.net> Date: Mon, 24 Aug 2015 22:16:48 +0200 Subject: login: don't print motd if .hushlogin exists in users home MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit function old new delta login_main 978 996 +18 Signed-off-by: Sören Tempel <soeren@soeren-tempel.net> Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com> --- loginutils/login.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/loginutils/login.c b/loginutils/login.c index b9d910331..1700cfcb5 100644 --- a/loginutils/login.c +++ b/loginutils/login.c @@ -489,7 +489,8 @@ int login_main(int argc UNUSED_PARAM, char **argv) } #endif - motd(); + if (access(".hushlogin", F_OK) != 0) + motd(); if (pw->pw_uid == 0) syslog(LOG_INFO, "root login%s", fromhost); -- cgit v1.2.3-55-g6feb From b432923e29dcd8c6f3a528bb9d61952de68e790c Mon Sep 17 00:00:00 2001 From: Bartosz Golaszewski <bartekgola@gmail.com> Date: Tue, 25 Aug 2015 13:09:59 +0200 Subject: libbb: add unit tests for is_prefixed_with() Test corner cases too like looking for an empty prefix etc. Signed-off-by: Bartosz Golaszewski <bartekgola@gmail.com> Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com> --- libbb/compare_string_array.c | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/libbb/compare_string_array.c b/libbb/compare_string_array.c index e24815a03..450916c3a 100644 --- a/libbb/compare_string_array.c +++ b/libbb/compare_string_array.c @@ -110,3 +110,22 @@ smallint FAST_FUNC yesno(const char *str) return ret / 3; } #endif + +#if ENABLE_UNIT_TEST + +BBUNIT_DEFINE_TEST(is_prefixed_with) +{ + BBUNIT_ASSERT_STREQ(" bar", is_prefixed_with("foo bar", "foo")); + BBUNIT_ASSERT_STREQ("bar", is_prefixed_with("foo bar", "foo ")); + BBUNIT_ASSERT_STREQ("", is_prefixed_with("foo", "foo")); + BBUNIT_ASSERT_STREQ("foo", is_prefixed_with("foo", "")); + BBUNIT_ASSERT_STREQ("", is_prefixed_with("", "")); + + BBUNIT_ASSERT_NULL(is_prefixed_with("foo", "bar foo")); + BBUNIT_ASSERT_NULL(is_prefixed_with("foo foo", "bar")); + BBUNIT_ASSERT_NULL(is_prefixed_with("", "foo")); + + BBUNIT_ENDTEST; +} + +#endif /* ENABLE_UNIT_TEST */ -- cgit v1.2.3-55-g6feb From 0a4d0e8fbf119e61f7223ac00a42505abf7eb168 Mon Sep 17 00:00:00 2001 From: Bartosz Golaszewski <bartekgola@gmail.com> Date: Tue, 25 Aug 2015 13:10:00 +0200 Subject: libbb: add a comment describing the way is_prefixed_with() works Signed-off-by: Bartosz Golaszewski <bartekgola@gmail.com> Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com> --- libbb/compare_string_array.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/libbb/compare_string_array.c b/libbb/compare_string_array.c index 450916c3a..cdcb2718d 100644 --- a/libbb/compare_string_array.c +++ b/libbb/compare_string_array.c @@ -5,6 +5,11 @@ #include "libbb.h" +/* + * Return NULL if string is not prefixed with key. Return pointer to the + * first character in string after the prefix key. If key is an empty string, + * return pointer to the beginning of string. + */ char* FAST_FUNC is_prefixed_with(const char *string, const char *key) { #if 0 /* Two passes over key - probably slower */ -- cgit v1.2.3-55-g6feb From 5b865deb3f2eafa1dcefabedf4af17a4c72f6cb8 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko <vda.linux@googlemail.com> Date: Tue, 25 Aug 2015 16:26:31 +0200 Subject: ping: fix recently introduced build breakage for non-optimizing builds Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com> --- networking/ping.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/networking/ping.c b/networking/ping.c index e1f9ebc3a..dcbf19682 100644 --- a/networking/ping.c +++ b/networking/ping.c @@ -769,7 +769,7 @@ static void ping6(len_and_sockaddr *lsa) setsockopt_SOL_SOCKET_int(pingsock, SO_RCVBUF, sockopt); sockopt = offsetof(struct icmp6_hdr, icmp6_cksum); - if (sockopt != 2) + if (offsetof(struct icmp6_hdr, icmp6_cksum) != 2) BUG_bad_offsetof_icmp6_cksum(); setsockopt_int(pingsock, SOL_RAW, IPV6_CHECKSUM, sockopt); -- cgit v1.2.3-55-g6feb From 7448b513c84feb3fd06fc57b39f5ab450970c01e Mon Sep 17 00:00:00 2001 From: Bartosz Golaszewski <bartekgola@gmail.com> Date: Tue, 25 Aug 2015 16:36:43 +0200 Subject: libbb: add is_suffixed_with() function Signed-off-by: Bartosz Golaszewski <bartekgola@gmail.com> Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com> --- include/libbb.h | 1 + libbb/compare_string_array.c | 33 +++++++++++++++++++++++++++++++++ 2 files changed, 34 insertions(+) diff --git a/include/libbb.h b/include/libbb.h index 2e20706e7..543214ea4 100644 --- a/include/libbb.h +++ b/include/libbb.h @@ -413,6 +413,7 @@ const char *bb_basename(const char *name) FAST_FUNC; char *last_char_is(const char *s, int c) FAST_FUNC; const char* endofname(const char *name) FAST_FUNC; char *is_prefixed_with(const char *string, const char *key) FAST_FUNC; +char *is_suffixed_with(const char *string, const char *key) FAST_FUNC; int ndelay_on(int fd) FAST_FUNC; int ndelay_off(int fd) FAST_FUNC; diff --git a/libbb/compare_string_array.c b/libbb/compare_string_array.c index cdcb2718d..e0d8e421b 100644 --- a/libbb/compare_string_array.c +++ b/libbb/compare_string_array.c @@ -28,6 +28,25 @@ char* FAST_FUNC is_prefixed_with(const char *string, const char *key) #endif } +/* + * Return NULL if string is not suffixed with key. Return pointer to the + * beginning of prefix key in string. If key is an empty string return pointer + * to the end of string. + */ +char* FAST_FUNC is_suffixed_with(const char *string, const char *key) +{ + size_t key_len = strlen(key); + ssize_t len_diff = strlen(string) - key_len; + + if (len_diff >= 0) { + if (strcmp(string + len_diff, key) == 0) { + return (char*)key; + } + } + + return NULL; +} + /* returns the array index of the string */ /* (index of first match is returned, or -1) */ int FAST_FUNC index_in_str_array(const char *const string_array[], const char *key) @@ -133,4 +152,18 @@ BBUNIT_DEFINE_TEST(is_prefixed_with) BBUNIT_ENDTEST; } +BBUNIT_DEFINE_TEST(is_suffixed_with) +{ + BBUNIT_ASSERT_STREQ("bar", is_suffixed_with("foo bar", "bar")); + BBUNIT_ASSERT_STREQ("foo", is_suffixed_with("foo", "foo")); + BBUNIT_ASSERT_STREQ("", is_suffixed_with("foo", "")); + BBUNIT_ASSERT_STREQ("", is_suffixed_with("", "")); + + BBUNIT_ASSERT_NULL(is_suffixed_with("foo", "bar foo")); + BBUNIT_ASSERT_NULL(is_suffixed_with("foo foo", "bar")); + BBUNIT_ASSERT_NULL(is_suffixed_with("", "foo")); + + BBUNIT_ENDTEST; +} + #endif /* ENABLE_UNIT_TEST */ -- cgit v1.2.3-55-g6feb From 68acc0f835360d439c65d349812b817b1ce5dc61 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko <vda.linux@googlemail.com> Date: Tue, 25 Aug 2015 21:47:33 +0200 Subject: libbb: make is_suffixed_with() return pointer inside string, not key. Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com> --- libbb/compare_string_array.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/libbb/compare_string_array.c b/libbb/compare_string_array.c index e0d8e421b..3dbd3eb1a 100644 --- a/libbb/compare_string_array.c +++ b/libbb/compare_string_array.c @@ -39,8 +39,9 @@ char* FAST_FUNC is_suffixed_with(const char *string, const char *key) ssize_t len_diff = strlen(string) - key_len; if (len_diff >= 0) { - if (strcmp(string + len_diff, key) == 0) { - return (char*)key; + string += len_diff; + if (strcmp(string, key) == 0) { + return (char*)string; } } -- cgit v1.2.3-55-g6feb From 66a781acb9c3a78f3063d1e691a1b18a5f9f68ab Mon Sep 17 00:00:00 2001 From: Denys Vlasenko <vda.linux@googlemail.com> Date: Fri, 4 Sep 2015 03:27:08 +0200 Subject: ash: add tests adapted from hush glob tests. glob2.tests currently fails Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com> --- shell/ash_test/ash-glob/glob1.right | 2 ++ shell/ash_test/ash-glob/glob1.tests | 2 ++ shell/ash_test/ash-glob/glob2.right | 18 ++++++++++++++++++ shell/ash_test/ash-glob/glob2.tests | 27 +++++++++++++++++++++++++++ shell/ash_test/ash-glob/glob_and_assign.right | 6 ++++++ shell/ash_test/ash-glob/glob_and_assign.tests | 10 ++++++++++ shell/ash_test/ash-glob/glob_redir.right | 2 ++ shell/ash_test/ash-glob/glob_redir.tests | 9 +++++++++ 8 files changed, 76 insertions(+) create mode 100644 shell/ash_test/ash-glob/glob1.right create mode 100755 shell/ash_test/ash-glob/glob1.tests create mode 100644 shell/ash_test/ash-glob/glob2.right create mode 100755 shell/ash_test/ash-glob/glob2.tests create mode 100644 shell/ash_test/ash-glob/glob_and_assign.right create mode 100755 shell/ash_test/ash-glob/glob_and_assign.tests create mode 100644 shell/ash_test/ash-glob/glob_redir.right create mode 100755 shell/ash_test/ash-glob/glob_redir.tests diff --git a/shell/ash_test/ash-glob/glob1.right b/shell/ash_test/ash-glob/glob1.right new file mode 100644 index 000000000..f29ab4e65 --- /dev/null +++ b/shell/ash_test/ash-glob/glob1.right @@ -0,0 +1,2 @@ +glob1.tests +glob1.tests diff --git a/shell/ash_test/ash-glob/glob1.tests b/shell/ash_test/ash-glob/glob1.tests new file mode 100755 index 000000000..f980ce064 --- /dev/null +++ b/shell/ash_test/ash-glob/glob1.tests @@ -0,0 +1,2 @@ +echo *glob1?t[e]sts* +echo "glob1"?'t'[e]s* diff --git a/shell/ash_test/ash-glob/glob2.right b/shell/ash_test/ash-glob/glob2.right new file mode 100644 index 000000000..7a70c2263 --- /dev/null +++ b/shell/ash_test/ash-glob/glob2.right @@ -0,0 +1,18 @@ +Expected Actual +Z\* : Z\* +Z* : Z* +Z\f : Z\f +Z\* : Z\* + +Z\z : Z\z +Zz : Zz +Z\z : Z\z +Z\z : Z\z + +Z\ : Z\ +Z\ : Z\ + +Z\f Zf : Z\f Zf +Z\f Zf : Z\f Zf + +Done: 0 diff --git a/shell/ash_test/ash-glob/glob2.tests b/shell/ash_test/ash-glob/glob2.tests new file mode 100755 index 000000000..00618b9db --- /dev/null +++ b/shell/ash_test/ash-glob/glob2.tests @@ -0,0 +1,27 @@ +# This test demonstrates that in unquoted $v, backslashes expand by this rule: +# \z -> \\\z; \<eol> -> \\<eol> (for any z, special or not), +# and subsequently globbing converts \\ to \ and treats \z as literal z +# even if it is a special char. + +>'Zf' +>'Z\f' + echo 'Expected' 'Actual' +v='\*'; echo 'Z\* :' Z$v # ash is buggy here: prints 'Z\f' + echo 'Z* :' Z\* + echo 'Z\f :' Z\\* + echo 'Z\* :' Z\\\* # NB! only this matches Z$v output +echo +v='\z'; echo 'Z\z :' Z$v + echo 'Zz :' Z\z + echo 'Z\z :' Z\\z + echo 'Z\z :' Z\\\z +echo +v='\'; echo 'Z\ :' Z$v + echo 'Z\ :' Z\\ +echo +v='*'; echo 'Z\f Zf :' Z$v + echo 'Z\f Zf :' Z* +echo + +rm 'Z\f' 'Zf' +echo Done: $? diff --git a/shell/ash_test/ash-glob/glob_and_assign.right b/shell/ash_test/ash-glob/glob_and_assign.right new file mode 100644 index 000000000..d46e44363 --- /dev/null +++ b/shell/ash_test/ash-glob/glob_and_assign.right @@ -0,0 +1,6 @@ +ZVAR=z.tmp ZVAR=*.tmp ZVAR=[z].tmp +ZVAR=z.tmp ZVAR=*.tmp ZVAR=[z].tmp +*.tmp +ZVAR=z.tmp z.tmp +ZVAR=z.tmp ZVAR=*.tmp ZVAR=[z].tmp +ZVAR=z.tmp ZVAR=*.tmp ZVAR=[z].tmp diff --git a/shell/ash_test/ash-glob/glob_and_assign.tests b/shell/ash_test/ash-glob/glob_and_assign.tests new file mode 100755 index 000000000..0b158f20f --- /dev/null +++ b/shell/ash_test/ash-glob/glob_and_assign.tests @@ -0,0 +1,10 @@ +>ZVAR=z.tmp +>z.tmp +ZVAR=*.tmp echo ZVAR=*.tmp "ZVAR=*.tmp" "ZVAR=[z].tmp" +ZVAR=*.tmp /bin/echo ZVAR=*.tmp "ZVAR=*.tmp" "ZVAR=[z].tmp" +ZVAR=*.tmp +echo "$ZVAR" +echo $ZVAR +echo ZVAR=*.tmp "ZVAR=*.tmp" "ZVAR=[z].tmp" +/bin/echo ZVAR=*.tmp "ZVAR=*.tmp" "ZVAR=[z].tmp" +rm ZVAR=z.tmp z.tmp diff --git a/shell/ash_test/ash-glob/glob_redir.right b/shell/ash_test/ash-glob/glob_redir.right new file mode 100644 index 000000000..fbd0309b0 --- /dev/null +++ b/shell/ash_test/ash-glob/glob_redir.right @@ -0,0 +1,2 @@ +z.tmp: +?.tmp: TEST diff --git a/shell/ash_test/ash-glob/glob_redir.tests b/shell/ash_test/ash-glob/glob_redir.tests new file mode 100755 index 000000000..621d12017 --- /dev/null +++ b/shell/ash_test/ash-glob/glob_redir.tests @@ -0,0 +1,9 @@ +# Redirections are not globbed. +# bash: +# if run as "sh", they are not globbed, but +# if run as "bash", they are! +>z.tmp +echo TEST >?.tmp +echo 'z.tmp:' `cat 'z.tmp'` +echo '?.tmp:' `cat '?.tmp'` +rm 'z.tmp' '?.tmp' -- cgit v1.2.3-55-g6feb From 26c423d9a8d455af59cbce70ff932c95842a2ba1 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko <vda.linux@googlemail.com> Date: Fri, 4 Sep 2015 03:33:02 +0200 Subject: ash,hush: add a test which fails for ash since commit 549deab Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com> --- shell/ash_test/ash-glob/glob3.right | 2 ++ shell/ash_test/ash-glob/glob3.tests | 2 ++ shell/hush_test/hush-glob/glob3.right | 2 ++ shell/hush_test/hush-glob/glob3.tests | 2 ++ 4 files changed, 8 insertions(+) create mode 100644 shell/ash_test/ash-glob/glob3.right create mode 100755 shell/ash_test/ash-glob/glob3.tests create mode 100644 shell/hush_test/hush-glob/glob3.right create mode 100755 shell/hush_test/hush-glob/glob3.tests diff --git a/shell/ash_test/ash-glob/glob3.right b/shell/ash_test/ash-glob/glob3.right new file mode 100644 index 000000000..161b589e0 --- /dev/null +++ b/shell/ash_test/ash-glob/glob3.right @@ -0,0 +1,2 @@ +glob3.tests +./glob3.tests diff --git a/shell/ash_test/ash-glob/glob3.tests b/shell/ash_test/ash-glob/glob3.tests new file mode 100755 index 000000000..bdf54001e --- /dev/null +++ b/shell/ash_test/ash-glob/glob3.tests @@ -0,0 +1,2 @@ +echo "glob3.test"* +echo "./glob3.test"* diff --git a/shell/hush_test/hush-glob/glob3.right b/shell/hush_test/hush-glob/glob3.right new file mode 100644 index 000000000..161b589e0 --- /dev/null +++ b/shell/hush_test/hush-glob/glob3.right @@ -0,0 +1,2 @@ +glob3.tests +./glob3.tests diff --git a/shell/hush_test/hush-glob/glob3.tests b/shell/hush_test/hush-glob/glob3.tests new file mode 100755 index 000000000..bdf54001e --- /dev/null +++ b/shell/hush_test/hush-glob/glob3.tests @@ -0,0 +1,2 @@ +echo "glob3.test"* +echo "./glob3.test"* -- cgit v1.2.3-55-g6feb From 2156e228537065f04e5f862e186421df0db36612 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko <vda.linux@googlemail.com> Date: Fri, 4 Sep 2015 04:20:51 +0200 Subject: Makefile.flags: survive a build system which has no pthread Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com> --- Makefile.flags | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/Makefile.flags b/Makefile.flags index bb90a08de..b29b06839 100644 --- a/Makefile.flags +++ b/Makefile.flags @@ -121,11 +121,16 @@ endif # fall back to using a temp file: CRYPT_AVAILABLE := $(shell echo 'int main(void){return 0;}' >crypttest.c; $(CC) $(CFLAGS) -lcrypt -o /dev/null crypttest.c >/dev/null 2>&1 && echo "y"; rm crypttest.c) ifeq ($(CRYPT_AVAILABLE),y) -LDLIBS += m crypt pthread +LDLIBS += m crypt else LDLIBS += m endif +PTHREAD_AVAILABLE := $(shell echo 'int main(void){return 0;}' >pthreadtest.c; $(CC) $(CFLAGS) -lpthread -o /dev/null pthreadtest.c >/dev/null 2>&1 && echo "y"; rm pthreadtest.c) +ifeq ($(PTHREAD_AVAILABLE),y) +LDLIBS += pthread +endif + ifeq ($(CONFIG_PAM),y) # libpam uses libpthread, libdl and libaudit, so for static builds busybox # must be linked to libpthread, libdl and libaudit. On some platforms that -- cgit v1.2.3-55-g6feb From b5be13ccd9ce2120468a381a5475955013c0f049 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko <vda.linux@googlemail.com> Date: Fri, 4 Sep 2015 06:22:10 +0200 Subject: hush: fix a nommu bug where a part of function body is lost if run in a pipe Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com> --- shell/hush.c | 35 ++++++++++++++++++++++++---------- shell/hush_test/hush-misc/nommu3.right | 2 ++ shell/hush_test/hush-misc/nommu3.tests | 15 +++++++++++++++ 3 files changed, 42 insertions(+), 10 deletions(-) create mode 100644 shell/hush_test/hush-misc/nommu3.right create mode 100755 shell/hush_test/hush-misc/nommu3.tests diff --git a/shell/hush.c b/shell/hush.c index 3ca04494c..752080a64 100644 --- a/shell/hush.c +++ b/shell/hush.c @@ -3161,11 +3161,29 @@ static int reserved_word(o_string *word, struct parse_context *ctx) old->command->group = ctx->list_head; old->command->cmd_type = CMD_NORMAL; # if !BB_MMU - o_addstr(&old->as_string, ctx->as_string.data); - o_free_unsafe(&ctx->as_string); - old->command->group_as_string = xstrdup(old->as_string.data); - debug_printf_parse("pop, remembering as:'%s'\n", - old->command->group_as_string); + /* At this point, the compound command's string is in + * ctx->as_string... except for the leading keyword! + * Consider this example: "echo a | if true; then echo a; fi" + * ctx->as_string will contain "true; then echo a; fi", + * with "if " remaining in old->as_string! + */ + { + char *str; + int len = old->as_string.length; + /* Concatenate halves */ + o_addstr(&old->as_string, ctx->as_string.data); + o_free_unsafe(&ctx->as_string); + /* Find where leading keyword starts in first half */ + str = old->as_string.data + len; + if (str > old->as_string.data) + str--; /* skip whitespace after keyword */ + while (str > old->as_string.data && isalpha(str[-1])) + str--; + /* Ugh, we're done with this horrid hack */ + old->command->group_as_string = xstrdup(str); + debug_printf_parse("pop, remembering as:'%s'\n", + old->command->group_as_string); + } # endif *ctx = *old; /* physical copy */ free(old); @@ -4248,7 +4266,7 @@ static struct pipe *parse_stream(char **pstring, pi = NULL; } #if !BB_MMU - debug_printf_parse("as_string '%s'\n", ctx.as_string.data); + debug_printf_parse("as_string1 '%s'\n", ctx.as_string.data); if (pstring) *pstring = ctx.as_string.data; else @@ -4399,7 +4417,7 @@ static struct pipe *parse_stream(char **pstring, ) { o_free(&dest); #if !BB_MMU - debug_printf_parse("as_string '%s'\n", ctx.as_string.data); + debug_printf_parse("as_string2 '%s'\n", ctx.as_string.data); if (pstring) *pstring = ctx.as_string.data; else @@ -4639,9 +4657,6 @@ static struct pipe *parse_stream(char **pstring, * with redirect_opt_num(), but bash doesn't do it. * "echo foo 2| cat" yields "foo 2". */ done_command(&ctx); -#if !BB_MMU - o_reset_to_empty_unquoted(&ctx.as_string); -#endif } goto new_cmd; case '(': diff --git a/shell/hush_test/hush-misc/nommu3.right b/shell/hush_test/hush-misc/nommu3.right new file mode 100644 index 000000000..da1534bef --- /dev/null +++ b/shell/hush_test/hush-misc/nommu3.right @@ -0,0 +1,2 @@ +Ok +0 diff --git a/shell/hush_test/hush-misc/nommu3.tests b/shell/hush_test/hush-misc/nommu3.tests new file mode 100755 index 000000000..0aca67a67 --- /dev/null +++ b/shell/hush_test/hush-misc/nommu3.tests @@ -0,0 +1,15 @@ +#!/bin/sh + +func() +{ + while read p; do echo "$p"; done +} + +pipe_to_func() +{ + # We had a NOMMU bug which caused "echo Ok |" part ot be lost + echo Ok | func +} + +pipe_to_func | cat +echo $? -- cgit v1.2.3-55-g6feb From ca25af9b06b0c3ded77ac70087227896b34003c4 Mon Sep 17 00:00:00 2001 From: Ron Yorston <rmy@pobox.com> Date: Fri, 4 Sep 2015 10:32:41 +0100 Subject: ash: fix slash treatment in expmeta Commit 549deab caused this sequence of commands: mkdir foo cd foo touch a b echo "./"* to return './*' instead of the expected './a ./b'. The problem was caused by the backport of commit 880d952 from dash. In dash the issue was fixed by two further commits by Herbert Xu: <d6d06ff> [EXPAND] Fixed non-leading slash treatment in expmeta <36f0fa8> [EXPAND] Fix slash treatment in expmeta (See git://git.kernel.org/pub/scm/utils/dash/dash.git) Apply these fixes to BusyBox ash, thus causing the new test glob3.tests to succeed. function old new delta expmeta 469 528 +59 Reported-by: Aaro Koskinen <aaro.koskinen@iki.fi> Signed-off-by: Ron Yorston <rmy@pobox.com> Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com> --- shell/ash.c | 23 +++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/shell/ash.c b/shell/ash.c index f6190c3e2..42c91257e 100644 --- a/shell/ash.c +++ b/shell/ash.c @@ -6992,10 +6992,11 @@ expmeta(char *expdir, char *enddir, char *name) struct dirent *dp; int atend; int matchdot; + int esc; metaflag = 0; start = name; - for (p = name; *p; p++) { + for (p = name; esc = 0, *p; p += esc + 1) { if (*p == '*' || *p == '?') metaflag = 1; else if (*p == '[') { @@ -7012,15 +7013,16 @@ expmeta(char *expdir, char *enddir, char *name) break; } } - } else if (*p == '\\') - p++; - else if (*p == '/') { - if (metaflag) - goto out; - start = p + 1; + } else { + if (*p == '\\') + esc++; + if (p[esc] == '/') { + if (metaflag) + break; + start = p + esc + 1; + } } } - out: if (metaflag == 0) { /* we've reached the end of the file name */ if (enddir != expdir) metaflag++; @@ -7060,7 +7062,8 @@ expmeta(char *expdir, char *enddir, char *name) atend = 1; } else { atend = 0; - *endname++ = '\0'; + *endname = '\0'; + endname += esc + 1; } matchdot = 0; p = start; @@ -7085,7 +7088,7 @@ expmeta(char *expdir, char *enddir, char *name) } closedir(dirp); if (!atend) - endname[-1] = '/'; + endname[-esc - 1] = esc ? '\\' : '/'; } static struct strlist * -- cgit v1.2.3-55-g6feb From 875297378cdbebb1278a4595f9fffffca3fc2303 Mon Sep 17 00:00:00 2001 From: Peter Korsgaard <peter@korsgaard.com> Date: Wed, 9 Sep 2015 14:55:07 +0200 Subject: modprobe: handle module arguments containing spaces Modprobe wasn't correctly parsing module arguments containing spaces from /proc/cmdline - E.G. module.property="some text". Extend the parsing to correctly handle quoted text. Signed-off-by: Peter Korsgaard <peter@korsgaard.com> Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com> --- modutils/modprobe.c | 34 +++++++++++++++++++++++++++++++++- 1 file changed, 33 insertions(+), 1 deletion(-) diff --git a/modutils/modprobe.c b/modutils/modprobe.c index 996de4074..314a7a1cb 100644 --- a/modutils/modprobe.c +++ b/modutils/modprobe.c @@ -348,6 +348,38 @@ static const char *humanly_readable_name(struct module_entry *m) return m->probed_name ? m->probed_name : m->modname; } +/* Like strsep(&stringp, "\n\t ") but quoted text goes to single token + * even if it contains whitespace. + */ +static char *strsep_quotes(char **stringp) +{ + char *s, *start = *stringp; + + if (!start) + return NULL; + + for (s = start; ; s++) { + switch (*s) { + case '"': + s = strchrnul(s + 1, '"'); /* find trailing quote */ + if (*s != '\0') + s++; /* skip trailing quote */ + /* fall through */ + case '\0': + case '\n': + case '\t': + case ' ': + if (*s != '\0') { + *s = '\0'; + *stringp = s + 1; + } else { + *stringp = NULL; + } + return start; + } + } +} + static char *parse_and_add_kcmdline_module_options(char *options, const char *modulename) { char *kcmdline_buf; @@ -359,7 +391,7 @@ static char *parse_and_add_kcmdline_module_options(char *options, const char *mo return options; kcmdline = kcmdline_buf; - while ((kptr = strsep(&kcmdline, "\n\t ")) != NULL) { + while ((kptr = strsep_quotes(&kcmdline)) != NULL) { char *after_modulename = is_prefixed_with(kptr, modulename); if (!after_modulename || *after_modulename != '.') continue; -- cgit v1.2.3-55-g6feb From f085344d5c4de46d0ef3e15a97ef444fd7cc3194 Mon Sep 17 00:00:00 2001 From: Tito Ragusa <farmatito@tiscali.it> Date: Tue, 15 Sep 2015 23:38:01 +0200 Subject: libbb: another unit test for is_suffixed_with Suggested by Bartosz Golaszewski. Signed-off-by: Tito Ragusa <farmatito@tiscali.it> Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com> --- libbb/compare_string_array.c | 1 + 1 file changed, 1 insertion(+) diff --git a/libbb/compare_string_array.c b/libbb/compare_string_array.c index 3dbd3eb1a..2f51237a3 100644 --- a/libbb/compare_string_array.c +++ b/libbb/compare_string_array.c @@ -159,6 +159,7 @@ BBUNIT_DEFINE_TEST(is_suffixed_with) BBUNIT_ASSERT_STREQ("foo", is_suffixed_with("foo", "foo")); BBUNIT_ASSERT_STREQ("", is_suffixed_with("foo", "")); BBUNIT_ASSERT_STREQ("", is_suffixed_with("", "")); + BBUNIT_ASSERT_STREQ("foo", is_suffixed_with("barfoofoo", "foo")); BBUNIT_ASSERT_NULL(is_suffixed_with("foo", "bar foo")); BBUNIT_ASSERT_NULL(is_suffixed_with("foo foo", "bar")); -- cgit v1.2.3-55-g6feb From 8aa7cf305ba5133721aa9852b398cbf1867fc857 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko <vda.linux@googlemail.com> Date: Sat, 19 Sep 2015 22:06:40 +0200 Subject: sort: fix -kN,M handling (was including last separator into the comparison) Testcase: $ printf '%s\n' a/a:a a:b | sort -t: -k1,1 a:b a/a:a Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com> --- coreutils/sort.c | 12 ++++++++---- testsuite/sort.tests | 8 ++++++++ 2 files changed, 16 insertions(+), 4 deletions(-) diff --git a/coreutils/sort.c b/coreutils/sort.c index 1cb4c3e3f..36f02543b 100644 --- a/coreutils/sort.c +++ b/coreutils/sort.c @@ -25,14 +25,14 @@ //usage: "\n -f Ignore case" //usage: "\n -g General numerical sort" //usage: "\n -i Ignore unprintable characters" -//usage: "\n -k Sort key" //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 -k Sort by key" -//usage: "\n -t CHAR Key separator" +//usage: "\n -t CHAR Field separator" +//usage: "\n -k N[,M] Sort by Nth field" //usage: ) //usage: "\n -r Reverse sort order" //usage: IF_FEATURE_SORT_BIG( @@ -143,6 +143,9 @@ 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) + end--; } if (!j) start = end; } @@ -163,7 +166,8 @@ static char *get_key(char *str, struct sort_key *key, int flags) if (start > len) start = len; } /* Make the copy */ - if (end < start) end = start; + if (end < start) + end = start; str = xstrndup(str+start, end-start); /* Handle -d */ if (flags & FLAG_d) { diff --git a/testsuite/sort.tests b/testsuite/sort.tests index 68fa3e405..c4b223464 100755 --- a/testsuite/sort.tests +++ b/testsuite/sort.tests @@ -98,6 +98,14 @@ testing "sort with non-default leading delim 3" "sort -n -k3 -t/ input" "\ //b/1 " "" +testing "sort with non-default leading delim 4" "sort -t: -k1,1 input" "\ +a:b +a/a:a +" "\ +a/a:a +a:b +" "" + testing "sort -u should consider field only when discarding" "sort -u -k2 input" "\ a c " "\ -- cgit v1.2.3-55-g6feb From d9892fa0c3abf28b71996e5bc7c133f29f987a7b Mon Sep 17 00:00:00 2001 From: Bartosz Golaszewski <bartekgola@gmail.com> Date: Fri, 4 Sep 2015 10:35:22 +0200 Subject: i2c-tools: remove duplicate definitions Most applets include linux' user API headers instead of duplicating the definitions. Make it the case for i2c-tools as well. Signed-off-by: Bartosz Golaszewski <bartekgola@gmail.com> Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com> --- miscutils/i2c_tools.c | 102 +------------------------------------------------- 1 file changed, 2 insertions(+), 100 deletions(-) diff --git a/miscutils/i2c_tools.c b/miscutils/i2c_tools.c index 38d90ff10..b78860277 100644 --- a/miscutils/i2c_tools.c +++ b/miscutils/i2c_tools.c @@ -61,113 +61,15 @@ #include "libbb.h" -/* - * /dev/i2c-X ioctl commands. The ioctl's parameter is always an unsigned long, - * except for: - * - I2C_FUNCS, takes pointer to an unsigned long - * - I2C_RDWR, takes pointer to struct i2c_rdwr_ioctl_data - * - I2C_SMBUS, takes pointer to struct i2c_smbus_ioctl_data - */ - -/* - * NOTE: Slave address is 7 or 10 bits, but 10-bit addresses - * are not supported due to code brokenness. - */ - -/* Use this slave address. */ -#define I2C_SLAVE 0x0703 -/* Use this slave address, even if it is already in use by a driver. */ -#define I2C_SLAVE_FORCE 0x0706 -/* 0 for 7 bit addrs, != 0 for 10 bit. */ -#define I2C_TENBIT 0x0704 -/* Get the adapter functionality mask. */ -#define I2C_FUNCS 0x0705 -/* Combined R/W transfer (one STOP only). */ -#define I2C_RDWR 0x0707 -/* != 0 to use PEC with SMBus. */ -#define I2C_PEC 0x0708 -/* SMBus transfer. */ -#define I2C_SMBUS 0x0720 - -/* Structure used in the I2C_SMBUS ioctl call. */ -struct i2c_smbus_ioctl_data { - uint8_t read_write; - uint8_t command; - uint32_t size; - union i2c_smbus_data *data; -}; +#include <linux/i2c.h> +#include <linux/i2c-dev.h> -/* Structure used in the I2C_RDWR ioctl call. */ -struct i2c_rdwr_ioctl_data { - struct i2c_msg *msgs; /* Pointers to i2c_msgs. */ - uint32_t nmsgs; /* Number of i2c_msgs. */ -}; - -/* As specified in SMBus standard. */ -#define I2C_SMBUS_BLOCK_MAX 32 -/* Not specified but we use same structure. */ -#define I2C_SMBUS_I2C_BLOCK_MAX 32 - -/* Data for SMBus Messages. */ -union i2c_smbus_data { - uint8_t byte; - uint16_t word; - /* block[0] is used for length and one more for PEC */ - uint8_t block[I2C_SMBUS_BLOCK_MAX + 2]; -}; - -#define I2C_RDRW_IOCTL_MAX_MSGS 42 #define I2C_MAX_REGS 256 -/* Smbus_access read or write markers. */ -#define I2C_SMBUS_READ 1 -#define I2C_SMBUS_WRITE 0 - -/* SMBus transaction types (size parameter in the below functions). */ -#define I2C_SMBUS_QUICK 0 -#define I2C_SMBUS_BYTE 1 -#define I2C_SMBUS_BYTE_DATA 2 -#define I2C_SMBUS_WORD_DATA 3 -#define I2C_SMBUS_PROC_CALL 4 -#define I2C_SMBUS_BLOCK_DATA 5 -#define I2C_SMBUS_I2C_BLOCK_BROKEN 6 -#define I2C_SMBUS_BLOCK_PROC_CALL 7 -#define I2C_SMBUS_I2C_BLOCK_DATA 8 - #define DETECT_MODE_AUTO 0 #define DETECT_MODE_QUICK 1 #define DETECT_MODE_READ 2 -/* Defines to determine what functionality is present. */ -#define I2C_FUNC_I2C 0x00000001 -#define I2C_FUNC_10BIT_ADDR 0x00000002 -#define I2C_FUNC_PROTOCOL_MANGLING 0x00000004 -#define I2C_FUNC_SMBUS_PEC 0x00000008 -#define I2C_FUNC_SMBUS_BLOCK_PROC_CALL 0x00008000 -#define I2C_FUNC_SMBUS_QUICK 0x00010000 -#define I2C_FUNC_SMBUS_READ_BYTE 0x00020000 -#define I2C_FUNC_SMBUS_WRITE_BYTE 0x00040000 -#define I2C_FUNC_SMBUS_READ_BYTE_DATA 0x00080000 -#define I2C_FUNC_SMBUS_WRITE_BYTE_DATA 0x00100000 -#define I2C_FUNC_SMBUS_READ_WORD_DATA 0x00200000 -#define I2C_FUNC_SMBUS_WRITE_WORD_DATA 0x00400000 -#define I2C_FUNC_SMBUS_PROC_CALL 0x00800000 -#define I2C_FUNC_SMBUS_READ_BLOCK_DATA 0x01000000 -#define I2C_FUNC_SMBUS_WRITE_BLOCK_DATA 0x02000000 -#define I2C_FUNC_SMBUS_READ_I2C_BLOCK 0x04000000 -#define I2C_FUNC_SMBUS_WRITE_I2C_BLOCK 0x08000000 - -#define I2C_FUNC_SMBUS_BYTE (I2C_FUNC_SMBUS_READ_BYTE | \ - I2C_FUNC_SMBUS_WRITE_BYTE) -#define I2C_FUNC_SMBUS_BYTE_DATA (I2C_FUNC_SMBUS_READ_BYTE_DATA | \ - I2C_FUNC_SMBUS_WRITE_BYTE_DATA) -#define I2C_FUNC_SMBUS_WORD_DATA (I2C_FUNC_SMBUS_READ_WORD_DATA | \ - I2C_FUNC_SMBUS_WRITE_WORD_DATA) -#define I2C_FUNC_SMBUS_BLOCK_DATA (I2C_FUNC_SMBUS_READ_BLOCK_DATA | \ - I2C_FUNC_SMBUS_WRITE_BLOCK_DATA) -#define I2C_FUNC_SMBUS_I2C_BLOCK (I2C_FUNC_SMBUS_READ_I2C_BLOCK | \ - I2C_FUNC_SMBUS_WRITE_I2C_BLOCK) - /* * This is needed for ioctl_or_perror_and_die() since it only accepts pointers. */ -- cgit v1.2.3-55-g6feb From 2beb52499eccaee26e7e5c6fc10df73f6802efd9 Mon Sep 17 00:00:00 2001 From: Bartosz Golaszewski <bartekgola@gmail.com> Date: Fri, 4 Sep 2015 10:38:48 +0200 Subject: i2c-tools: rename remaining defines Rename the defines not present in linux UAPI headers to better reflect their purpose. Signed-off-by: Bartosz Golaszewski <bartekgola@gmail.com> Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com> --- miscutils/i2c_tools.c | 46 +++++++++++++++++++++++----------------------- 1 file changed, 23 insertions(+), 23 deletions(-) diff --git a/miscutils/i2c_tools.c b/miscutils/i2c_tools.c index b78860277..4b26b7bdc 100644 --- a/miscutils/i2c_tools.c +++ b/miscutils/i2c_tools.c @@ -64,11 +64,11 @@ #include <linux/i2c.h> #include <linux/i2c-dev.h> -#define I2C_MAX_REGS 256 +#define I2CDUMP_NUM_REGS 256 -#define DETECT_MODE_AUTO 0 -#define DETECT_MODE_QUICK 1 -#define DETECT_MODE_READ 2 +#define I2CDETECT_MODE_AUTO 0 +#define I2CDETECT_MODE_QUICK 1 +#define I2CDETECT_MODE_READ 2 /* * This is needed for ioctl_or_perror_and_die() since it only accepts pointers. @@ -720,14 +720,14 @@ int i2cset_main(int argc, char **argv) #if ENABLE_I2CDUMP static int read_block_data(int buf_fd, int mode, int *block) { - uint8_t cblock[I2C_SMBUS_BLOCK_MAX + I2C_MAX_REGS]; + 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) { res = i2c_smbus_read_block_data(buf_fd, 0, cblock); blen = res; } else { - for (res = 0; res < I2C_MAX_REGS; res += tmp) { + 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); @@ -736,14 +736,14 @@ static int read_block_data(int buf_fd, int mode, int *block) } } - if (res >= I2C_MAX_REGS) - res = I2C_MAX_REGS; + if (res >= I2CDUMP_NUM_REGS) + res = I2CDUMP_NUM_REGS; for (i = 0; i < res; i++) block[i] = cblock[i]; if (mode != I2C_SMBUS_BLOCK_DATA) - for (i = res; i < I2C_MAX_REGS; i++) + for (i = res; i < I2CDUMP_NUM_REGS; i++) block[i] = -1; } @@ -759,7 +759,7 @@ static void dump_data(int bus_fd, int mode, unsigned first, printf(" 0 1 2 3 4 5 6 7 8 9 a b c d e f" " 0123456789abcdef\n"); - for (i = 0; i < I2C_MAX_REGS; i += 0x10) { + for (i = 0; i < I2CDUMP_NUM_REGS; i += 0x10) { if (mode == I2C_SMBUS_BLOCK_DATA && i >= blen) break; if (i/16 < first/16) @@ -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 = DETECT_MODE_AUTO, status; + int fd, bus_num, i, j, mode = I2CDETECT_MODE_AUTO, status; unsigned first = 0x03, last = 0x77, opts; unsigned long funcs; @@ -1231,9 +1231,9 @@ int i2cdetect_main(int argc UNUSED_PARAM, char **argv) } if (opts & opt_r) - mode = DETECT_MODE_READ; + mode = I2CDETECT_MODE_READ; else if (opts & opt_q) - mode = DETECT_MODE_QUICK; + mode = I2CDETECT_MODE_QUICK; if (opts & opt_a) { first = 0x00; @@ -1250,14 +1250,14 @@ int i2cdetect_main(int argc UNUSED_PARAM, char **argv) if (!(funcs & (I2C_FUNC_SMBUS_QUICK | I2C_FUNC_SMBUS_READ_BYTE))) { no_support("detection commands"); } else - if (mode == DETECT_MODE_QUICK && !(funcs & I2C_FUNC_SMBUS_QUICK)) { + if (mode == I2CDETECT_MODE_QUICK && !(funcs & I2C_FUNC_SMBUS_QUICK)) { no_support("SMBus Quick Write command"); } else - if (mode == DETECT_MODE_READ && !(funcs & I2C_FUNC_SMBUS_READ_BYTE)) { + if (mode == I2CDETECT_MODE_READ && !(funcs & I2C_FUNC_SMBUS_READ_BYTE)) { no_support("SMBus Receive Byte command"); } - if (mode == DETECT_MODE_AUTO) { + if (mode == I2CDETECT_MODE_AUTO) { if (!(funcs & I2C_FUNC_SMBUS_QUICK)) will_skip("SMBus Quick Write"); if (!(funcs & I2C_FUNC_SMBUS_READ_BYTE)) @@ -1273,19 +1273,19 @@ int i2cdetect_main(int argc UNUSED_PARAM, char **argv) for(j = 0; j < 16; j++) { fflush_all(); - if (mode == DETECT_MODE_AUTO) { + if (mode == I2CDETECT_MODE_AUTO) { if ((i+j >= 0x30 && i+j <= 0x37) || (i+j >= 0x50 && i+j <= 0x5F)) - mode = DETECT_MODE_READ; + mode = I2CDETECT_MODE_READ; else - mode = DETECT_MODE_QUICK; + mode = I2CDETECT_MODE_QUICK; } /* Skip unwanted addresses. */ if (i+j < first || i+j > last - || (mode == DETECT_MODE_READ && !(funcs & I2C_FUNC_SMBUS_READ_BYTE)) - || (mode == DETECT_MODE_QUICK && !(funcs & I2C_FUNC_SMBUS_QUICK))) + || (mode == I2CDETECT_MODE_READ && !(funcs & I2C_FUNC_SMBUS_READ_BYTE)) + || (mode == I2CDETECT_MODE_QUICK && !(funcs & I2C_FUNC_SMBUS_QUICK))) { printf(" "); continue; @@ -1303,14 +1303,14 @@ int i2cdetect_main(int argc UNUSED_PARAM, char **argv) } switch (mode) { - case DETECT_MODE_READ: + case I2CDETECT_MODE_READ: /* * This is known to lock SMBus on various * write-only chips (mainly clock chips). */ status = i2c_smbus_read_byte(fd); break; - default: /* DETECT_MODE_QUICK: */ + default: /* I2CDETECT_MODE_QUICK: */ /* * This is known to corrupt the Atmel * AT24RF08 EEPROM. -- cgit v1.2.3-55-g6feb From 65db14ec50305236b9750b898fd1b6d8a97b7a52 Mon Sep 17 00:00:00 2001 From: Bernhard Reutner-Fischer <rep.dot.nop@gmail.com> Date: Mon, 25 May 2015 23:25:19 +0200 Subject: adduser: Add -k /path/to/skel function old new delta .rodata 157069 157133 +64 adduser_main 921 936 +15 adduser_longopts 103 110 +7 packed_usage 30230 30236 +6 ------------------------------------------------------------------------------ (add/remove: 0/0 grow/shrink: 4/0 up/down: 92/0) Total: 92 bytes Signed-off-by: Bernhard Reutner-Fischer <rep.dot.nop@gmail.com> Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com> --- loginutils/adduser.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/loginutils/adduser.c b/loginutils/adduser.c index 568a3018e..6da29304c 100644 --- a/loginutils/adduser.c +++ b/loginutils/adduser.c @@ -20,6 +20,7 @@ //usage: "\n -D Don't assign a password" //usage: "\n -H Don't create home directory" //usage: "\n -u UID User id" +//usage: "\n -k SKEL directory (/etc/skel)" #include "libbb.h" @@ -39,6 +40,7 @@ #define OPT_SYSTEM_ACCOUNT (1 << 5) #define OPT_DONT_MAKE_HOME (1 << 6) #define OPT_UID (1 << 7) +#define OPT_SKEL (1 << 8) /* remix */ /* recoded such that the uid may be passed in *p */ @@ -134,6 +136,7 @@ static const char adduser_longopts[] ALIGN1 = "system\0" No_argument "S" "no-create-home\0" No_argument "H" "uid\0" Required_argument "u" + "skel\0" Required_argument "k" ; #endif @@ -150,6 +153,7 @@ int adduser_main(int argc UNUSED_PARAM, char **argv) char *p; unsigned opts; char *uid; + const char *skel = "/etc/skel"; #if ENABLE_FEATURE_ADDUSER_LONG_OPTIONS applet_long_options = adduser_longopts; @@ -168,7 +172,7 @@ int adduser_main(int argc UNUSED_PARAM, char **argv) /* at least one and at most two non-option args */ /* disable interactive passwd for system accounts */ opt_complementary = "-1:?2:SD"; - opts = getopt32(argv, "h:g:s:G:DSHu:", &pw.pw_dir, &pw.pw_gecos, &pw.pw_shell, &usegroup, &uid); + opts = getopt32(argv, "h:g:s:G:DSHu:k:", &pw.pw_dir, &pw.pw_gecos, &pw.pw_shell, &usegroup, &uid, &skel); if (opts & OPT_UID) pw.pw_uid = xatou_range(uid, 0, CONFIG_LAST_ID); @@ -250,8 +254,9 @@ int adduser_main(int argc UNUSED_PARAM, char **argv) NULL }; /* Be silent on any errors (like: no /etc/skel) */ - logmode = LOGMODE_NONE; - copy_file("/etc/skel", pw.pw_dir, FILEUTILS_RECUR); + if (!(opts & OPT_SKEL)) + logmode = LOGMODE_NONE; + copy_file(skel, pw.pw_dir, FILEUTILS_RECUR); logmode = LOGMODE_STDIO; chown_main(4, (char**)args); } -- cgit v1.2.3-55-g6feb From c65a7596df190124abd72d33e2c8c3d2bc8bff80 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko <vda.linux@googlemail.com> Date: Mon, 21 Sep 2015 21:11:12 +0200 Subject: adduser: fix help text Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com> --- loginutils/adduser.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/loginutils/adduser.c b/loginutils/adduser.c index 6da29304c..605e3363f 100644 --- a/loginutils/adduser.c +++ b/loginutils/adduser.c @@ -20,7 +20,7 @@ //usage: "\n -D Don't assign a password" //usage: "\n -H Don't create home directory" //usage: "\n -u UID User id" -//usage: "\n -k SKEL directory (/etc/skel)" +//usage: "\n -k SKEL Skeleton directory (/etc/skel)" #include "libbb.h" -- cgit v1.2.3-55-g6feb From c919d561adaf152d9b8834475539e2366c8aa484 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko <vda.linux@googlemail.com> Date: Thu, 1 Oct 2015 18:50:06 +0200 Subject: umount: always use umount2 syscall with specified flags Make umount -f more compatible with util-linux 2.22.2. Before: * 'umount -f': calls umount syscall, if it fails calls umount2 with 'MNT_FORCE' * 'mount -f -l': calls umount syscall, if it fails calls umount2 with 'MNT_LAZY'. 'MNT_FORCE' dropped After: * 'umount -f': calls umount2 syscall with 'MNT_FORCE' * 'mount -f -l': calls umount2 syscall with 'MNT_LAZY' and 'MNT_FORCE' function old new delta umount 45 - -45 umount_main 610 555 -55 Signed-off-by: Anton Bondarenko <anton.bondarenko@axis.com> Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com> --- util-linux/umount.c | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/util-linux/umount.c b/util-linux/umount.c index 4c2e8821e..c6c7441b8 100644 --- a/util-linux/umount.c +++ b/util-linux/umount.c @@ -81,8 +81,13 @@ int umount_main(int argc UNUSED_PARAM, char **argv) argv += optind; // MNT_FORCE and MNT_DETACH (from linux/fs.h) must match - // OPT_FORCE and OPT_LAZY, otherwise this trick won't work: - doForce = MAX((opt & OPT_FORCE), (opt & OPT_LAZY)); + // OPT_FORCE and OPT_LAZY. + { + typedef char bug[ + (OPT_FORCE != MNT_FORCE || OPT_LAZY != MNT_DETACH) ? -1 : 1 + ]; + } + doForce = opt & (OPT_FORCE|OPT_LAZY); /* Get a list of mount points from mtab. We read them all in now mostly * for umount -a (so we don't have to worry about the list changing while @@ -147,11 +152,18 @@ int umount_main(int argc UNUSED_PARAM, char **argv) // umount the directory even if we were given the block device. if (m) zapit = m->dir; +// umount from util-linux 2.22.2 does not do this: +// umount -f uses umount2(MNT_FORCE) immediately, +// not trying umount() first. +// (Strangely, umount -fl ignores -f: it is equivalent to umount -l. +// We do pass both flags in this case) +#if 0 // Let's ask the thing nicely to unmount. curstat = umount(zapit); - // Force the unmount, if necessary. + // Unmount with force and/or lazy flags, if necessary. if (curstat && doForce) +#endif curstat = umount2(zapit, doForce); // If still can't umount, maybe remount read-only? @@ -168,7 +180,7 @@ int umount_main(int argc UNUSED_PARAM, char **argv) bb_error_msg(msg, m->device); } else { status = EXIT_FAILURE; - bb_perror_msg("can't %sumount %s", (doForce ? "forcibly " : ""), zapit); + bb_perror_msg("can't unmount %s", zapit); } } else { // De-allocate the loop device. This ioctl should be ignored on -- cgit v1.2.3-55-g6feb From 28b00ce6ff8cde91f3e83632e705709b7cd2ab20 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko <vda.linux@googlemail.com> Date: Fri, 2 Oct 2015 02:41:39 +0200 Subject: awk: support "length" form of "length()". Closes 8371 function old new delta parse_expr 805 848 +43 tokenlist 447 448 +1 Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com> --- editors/awk.c | 115 ++++++++++++++++++++++++++++++---------------------- testsuite/awk.tests | 5 +++ 2 files changed, 72 insertions(+), 48 deletions(-) diff --git a/editors/awk.c b/editors/awk.c index 9c6819ad2..69816464d 100644 --- a/editors/awk.c +++ b/editors/awk.c @@ -207,7 +207,7 @@ typedef struct tsplitter_s { /* simple token classes */ /* Order and hex values are very important!!! See next_token() */ -#define TC_SEQSTART 1 /* ( */ +#define TC_SEQSTART (1 << 0) /* ( */ #define TC_SEQTERM (1 << 1) /* ) */ #define TC_REGEXP (1 << 2) /* /.../ */ #define TC_OUTRDR (1 << 3) /* | > >> */ @@ -227,16 +227,22 @@ typedef struct tsplitter_s { #define TC_WHILE (1 << 17) #define TC_ELSE (1 << 18) #define TC_BUILTIN (1 << 19) -#define TC_GETLINE (1 << 20) -#define TC_FUNCDECL (1 << 21) /* `function' `func' */ -#define TC_BEGIN (1 << 22) -#define TC_END (1 << 23) -#define TC_EOF (1 << 24) -#define TC_VARIABLE (1 << 25) -#define TC_ARRAY (1 << 26) -#define TC_FUNCTION (1 << 27) -#define TC_STRING (1 << 28) -#define TC_NUMBER (1 << 29) +/* This costs ~50 bytes of code. + * A separate class to support deprecated "length" form. If we don't need that + * (i.e. if we demand that only "length()" with () is valid), then TC_LENGTH + * can be merged with TC_BUILTIN: + */ +#define TC_LENGTH (1 << 20) +#define TC_GETLINE (1 << 21) +#define TC_FUNCDECL (1 << 22) /* `function' `func' */ +#define TC_BEGIN (1 << 23) +#define TC_END (1 << 24) +#define TC_EOF (1 << 25) +#define TC_VARIABLE (1 << 26) +#define TC_ARRAY (1 << 27) +#define TC_FUNCTION (1 << 28) +#define TC_STRING (1 << 29) +#define TC_NUMBER (1 << 30) #define TC_UOPPRE (TC_UOPPRE1 | TC_UOPPRE2) @@ -244,14 +250,16 @@ typedef struct tsplitter_s { #define TC_BINOP (TC_BINOPX | TC_COMMA | TC_PIPE | TC_IN) //#define TC_UNARYOP (TC_UOPPRE | TC_UOPPOST) #define TC_OPERAND (TC_VARIABLE | TC_ARRAY | TC_FUNCTION \ - | TC_BUILTIN | TC_GETLINE | TC_SEQSTART | TC_STRING | TC_NUMBER) + | TC_BUILTIN | TC_LENGTH | TC_GETLINE \ + | TC_SEQSTART | TC_STRING | TC_NUMBER) #define TC_STATEMNT (TC_STATX | TC_WHILE) #define TC_OPTERM (TC_SEMICOL | TC_NEWLINE) /* word tokens, cannot mean something else if not expected */ -#define TC_WORD (TC_IN | TC_STATEMNT | TC_ELSE | TC_BUILTIN \ - | TC_GETLINE | TC_FUNCDECL | TC_BEGIN | TC_END) +#define TC_WORD (TC_IN | TC_STATEMNT | TC_ELSE \ + | TC_BUILTIN | TC_LENGTH | TC_GETLINE \ + | TC_FUNCDECL | TC_BEGIN | TC_END) /* discard newlines after these */ #define TC_NOTERM (TC_COMMA | TC_GRPSTART | TC_GRPTERM \ @@ -346,54 +354,54 @@ enum { #define NTC "\377" /* switch to next token class (tc<<1) */ #define NTCC '\377' -#define OC_B OC_BUILTIN - static const char tokenlist[] ALIGN1 = - "\1(" NTC - "\1)" NTC - "\1/" NTC /* REGEXP */ - "\2>>" "\1>" "\1|" NTC /* OUTRDR */ - "\2++" "\2--" NTC /* UOPPOST */ - "\2++" "\2--" "\1$" NTC /* UOPPRE1 */ - "\2==" "\1=" "\2+=" "\2-=" /* BINOPX */ + "\1(" NTC /* TC_SEQSTART */ + "\1)" NTC /* TC_SEQTERM */ + "\1/" NTC /* TC_REGEXP */ + "\2>>" "\1>" "\1|" NTC /* TC_OUTRDR */ + "\2++" "\2--" NTC /* TC_UOPPOST */ + "\2++" "\2--" "\1$" NTC /* TC_UOPPRE1 */ + "\2==" "\1=" "\2+=" "\2-=" /* TC_BINOPX */ "\2*=" "\2/=" "\2%=" "\2^=" "\1+" "\1-" "\3**=" "\2**" "\1/" "\1%" "\1^" "\1*" "\2!=" "\2>=" "\2<=" "\1>" "\1<" "\2!~" "\1~" "\2&&" "\2||" "\1?" "\1:" NTC - "\2in" NTC - "\1," NTC - "\1|" NTC - "\1+" "\1-" "\1!" NTC /* UOPPRE2 */ - "\1]" NTC - "\1{" NTC - "\1}" NTC - "\1;" NTC - "\1\n" NTC - "\2if" "\2do" "\3for" "\5break" /* STATX */ + "\2in" NTC /* TC_IN */ + "\1," NTC /* TC_COMMA */ + "\1|" NTC /* TC_PIPE */ + "\1+" "\1-" "\1!" NTC /* TC_UOPPRE2 */ + "\1]" NTC /* TC_ARRTERM */ + "\1{" NTC /* TC_GRPSTART */ + "\1}" NTC /* TC_GRPTERM */ + "\1;" NTC /* TC_SEMICOL */ + "\1\n" NTC /* TC_NEWLINE */ + "\2if" "\2do" "\3for" "\5break" /* TC_STATX */ "\10continue" "\6delete" "\5print" "\6printf" "\4next" "\10nextfile" "\6return" "\4exit" NTC - "\5while" NTC - "\4else" NTC - - "\3and" "\5compl" "\6lshift" "\2or" + "\5while" NTC /* TC_WHILE */ + "\4else" NTC /* TC_ELSE */ + "\3and" "\5compl" "\6lshift" "\2or" /* TC_BUILTIN */ "\6rshift" "\3xor" - "\5close" "\6system" "\6fflush" "\5atan2" /* BUILTIN */ + "\5close" "\6system" "\6fflush" "\5atan2" "\3cos" "\3exp" "\3int" "\3log" "\4rand" "\3sin" "\4sqrt" "\5srand" - "\6gensub" "\4gsub" "\5index" "\6length" + "\6gensub" "\4gsub" "\5index" /* "\6length" was here */ "\5match" "\5split" "\7sprintf" "\3sub" "\6substr" "\7systime" "\10strftime" "\6mktime" "\7tolower" "\7toupper" NTC - "\7getline" NTC - "\4func" "\10function" NTC - "\5BEGIN" NTC - "\3END" + "\6length" NTC /* TC_LENGTH */ + "\7getline" NTC /* TC_GETLINE */ + "\4func" "\10function" NTC /* TC_FUNCDECL */ + "\5BEGIN" NTC /* TC_BEGIN */ + "\3END" /* TC_END */ /* compiler adds trailing "\0" */ ; +#define OC_B OC_BUILTIN + static const uint32_t tokeninfo[] = { 0, 0, @@ -408,7 +416,7 @@ static const uint32_t tokeninfo[] = { OC_COMPARE|VV|P(39)|4, OC_COMPARE|VV|P(39)|3, OC_COMPARE|VV|P(39)|0, OC_COMPARE|VV|P(39)|1, OC_COMPARE|VV|P(39)|2, OC_MATCH|Sx|P(45)|'!', OC_MATCH|Sx|P(45)|'~', OC_LAND|Vx|P(55), OC_LOR|Vx|P(59), OC_TERNARY|Vx|P(64)|'?', OC_COLON|xx|P(67)|':', - OC_IN|SV|P(49), /* in */ + OC_IN|SV|P(49), /* TC_IN */ OC_COMMA|SS|P(80), OC_PGETLINE|SV|P(37), OC_UNARY|xV|P(19)|'+', OC_UNARY|xV|P(19)|'-', OC_UNARY|xV|P(19)|'!', @@ -423,20 +431,20 @@ static const uint32_t tokeninfo[] = { OC_RETURN|Vx, OC_EXIT|Nx, ST_WHILE, 0, /* else */ - OC_B|B_an|P(0x83), OC_B|B_co|P(0x41), OC_B|B_ls|P(0x83), OC_B|B_or|P(0x83), OC_B|B_rs|P(0x83), OC_B|B_xo|P(0x83), OC_FBLTIN|Sx|F_cl, OC_FBLTIN|Sx|F_sy, OC_FBLTIN|Sx|F_ff, OC_B|B_a2|P(0x83), OC_FBLTIN|Nx|F_co, OC_FBLTIN|Nx|F_ex, OC_FBLTIN|Nx|F_in, OC_FBLTIN|Nx|F_lg, OC_FBLTIN|F_rn, OC_FBLTIN|Nx|F_si, OC_FBLTIN|Nx|F_sq, OC_FBLTIN|Nx|F_sr, - OC_B|B_ge|P(0xd6), OC_B|B_gs|P(0xb6), OC_B|B_ix|P(0x9b), OC_FBLTIN|Sx|F_le, + OC_B|B_ge|P(0xd6), OC_B|B_gs|P(0xb6), OC_B|B_ix|P(0x9b), /* OC_FBLTIN|Sx|F_le, was here */ OC_B|B_ma|P(0x89), OC_B|B_sp|P(0x8b), OC_SPRINTF, OC_B|B_su|P(0xb6), OC_B|B_ss|P(0x8f), OC_FBLTIN|F_ti, OC_B|B_ti|P(0x0b), OC_B|B_mt|P(0x0b), OC_B|B_lo|P(0x49), OC_B|B_up|P(0x49), + OC_FBLTIN|Sx|F_le, /* TC_LENGTH */ OC_GETLINE|SV|P(0), 0, 0, 0, - 0 /* END */ + 0 /* TC_END */ }; /* internal variable names and their initial values */ @@ -1202,9 +1210,10 @@ static uint32_t next_token(uint32_t expected) ltclass = t_tclass; /* Are we ready for this? */ - if (!(ltclass & expected)) + if (!(ltclass & expected)) { syntax_error((ltclass & (TC_NEWLINE | TC_EOF)) ? EMSG_UNEXP_EOS : EMSG_UNEXP_TOKEN); + } return ltclass; #undef concat_inserted @@ -1371,6 +1380,16 @@ static node *parse_expr(uint32_t iexp) debug_printf_parse("%s: TC_BUILTIN\n", __func__); cn->l.n = condition(); break; + + case TC_LENGTH: + debug_printf_parse("%s: TC_LENGTH\n", __func__); + next_token(TC_SEQSTART | TC_OPTERM | TC_GRPTERM); + rollback_token(); + if (t_tclass & TC_SEQSTART) { + /* It was a "(" token. Handle just like TC_BUILTIN */ + cn->l.n = condition(); + } + break; } } } diff --git a/testsuite/awk.tests b/testsuite/awk.tests index 9e6952ffd..adab4ae1e 100755 --- a/testsuite/awk.tests +++ b/testsuite/awk.tests @@ -281,6 +281,11 @@ testing "awk length(array)" \ "2\n" \ "" "" +testing "awk length()" \ + "awk '{print length; print length(); print length(\"qwe\"); print length(99+9)}'" \ + "3\n3\n3\n3\n" \ + "" "qwe" + testing "awk -f and ARGC" \ "awk -f - input" \ "re\n2\n" \ -- cgit v1.2.3-55-g6feb From 12efcf3285a75d197704d2eef23824b3e4f11e66 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko <vda.linux@googlemail.com> Date: Mon, 5 Oct 2015 09:04:04 +0200 Subject: Add qemu_multiarch_testing/ Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com> --- qemu_multiarch_testing/README | 63 ++++++++++++++++++++++++ qemu_multiarch_testing/extract_od_binary.sh | 6 +++ qemu_multiarch_testing/hdc.dir/build | 45 +++++++++++++++++ qemu_multiarch_testing/hdc.dir/init | 9 ++++ qemu_multiarch_testing/make-hdc-img.sh | 30 +++++++++++ qemu_multiarch_testing/parallel-build-hdc-img.sh | 40 +++++++++++++++ 6 files changed, 193 insertions(+) create mode 100644 qemu_multiarch_testing/README create mode 100755 qemu_multiarch_testing/extract_od_binary.sh create mode 100755 qemu_multiarch_testing/hdc.dir/build create mode 100755 qemu_multiarch_testing/hdc.dir/init create mode 100755 qemu_multiarch_testing/make-hdc-img.sh create mode 100755 qemu_multiarch_testing/parallel-build-hdc-img.sh diff --git a/qemu_multiarch_testing/README b/qemu_multiarch_testing/README new file mode 100644 index 000000000..69ddb76b8 --- /dev/null +++ b/qemu_multiarch_testing/README @@ -0,0 +1,63 @@ +How to test build using Aboriginal Linux system images. + +* Put a source tree into hdc.dir/. +For example, this should work: +git clone git://busybox.net/var/lib/git/busybox.git + +* Run ./make-hdc-img.sh: it will generate ext2 image file, +hdc.img, from hdc.dir/* data. This requires root for loop mount. + +* Download and unpack, or build from source and unpack +one or more system-image-ARCH directories into this directory +(the one which contains this README). + +* 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. + +* Observe system-image-*.log file(s) with growing log of the build. + +There is no automated detection of errors for now: you need to examine +logs yourself. + +Log files will also contain uuencoded (or if all else fails, od -tx1'ed) +binary, if build was successful. + +To debug a build problem in one of the sandboxes, change keep_hdb +to "keep_hdb=true" in parallel-build-hdc-img.sh +- this preserves system-image-ARCH/hdb.img after the build, +so you can go into system-image-ARCH and run +"HDB=hdb.img ./dev-environment.sh" to debug the problem. + +You can also run "./parallel-build-hdc-img.sh -s system-image-ARCH" +- single mode, output is to screen and serial input is from keyboard. + +If hdc.dir/bin/busybox-$ARCH exists, it will be used during build +to supply additional tools. + +For me, the following system images worked: +system-image-armv4l +system-image-armv4tl +system-image-armv5l + od is buggy on arm*: + # echo Hello-hello-hello-hello | od -b + 0000000 110 145 154 154 157 055 150 145 154 154 157 055 150 145 154 154 + 0000000 157 055 150 145 154 154 157 012 + 0000000 +system-image-i686 +system-image-mips +system-image-mipsel + od is buggy on mips[el]: + # echo Hello-hello-hello-hello | od -b + 0000000 110 145 154 154 157 055 150 145 154 154 157 055 150 145 154 154 + 17767153361 157 055 150 145 154 154 157 012 + 0000000 +system-image-x86_64 + +And these did not: +system-image-armv6l - hang on "Uncompressing Linux... done, booting the kernel" +system-image-powerpc - hang early in kernel boot +system-image-sparc - hang early in userspace +system-image-m68k - my qemu doesn't like "-M q800" +system-image-mips64 - init dies "Kernel panic - not syncing: Attempted to kill init! exitcode=0x0000000a" +system-image-sh4 - qemu segfaults early in kernel boot diff --git a/qemu_multiarch_testing/extract_od_binary.sh b/qemu_multiarch_testing/extract_od_binary.sh new file mode 100755 index 000000000..e4c2c2a0a --- /dev/null +++ b/qemu_multiarch_testing/extract_od_binary.sh @@ -0,0 +1,6 @@ +#!/bin/sh + +# Converts textual result of "od -tx1 <FILE" +# back into a binary FILE + +grep -a '^[0-7][0-7][0-7][0-7][0-7][0-7][0-7] [0-9a-f][0-9a-f] [0-9a-f][0-9a-f] [0-9a-f][0-9a-f] [0-9a-f][0-9a-f]' | busybox hexdump -R diff --git a/qemu_multiarch_testing/hdc.dir/build b/qemu_multiarch_testing/hdc.dir/build new file mode 100755 index 000000000..8a65a5582 --- /dev/null +++ b/qemu_multiarch_testing/hdc.dir/build @@ -0,0 +1,45 @@ +#!/bin/sh + +umount /mnt # optional + +test -x "bin/busybox-$HOST" && { + echo "Found bin/busybox-$HOST, using it" + cp -a "bin/busybox-$HOST" bin/busybox + bin/busybox --install -s bin/ + # Supply missing stuff (e.g. bzip2): + PATH="$PATH:$PWD/bin" + # Override known-buggy host binaries: + cp -af bin/od `which od` +} + +( + #set -e -x + cd busybox + make defconfig + # Want static build + sed 's/^.*CONFIG_STATIC.*$/CONFIG_STATIC=y/' -i .config + # Drats, newer Aboriginal Linux has no bzip2 + bzip2 </dev/null >/dev/null || { + sed 's/^.*CONFIG_FEATURE_COMPRESS_USAGE.*$/# CONFIG_FEATURE_COMPRESS_USAGE is not set/' -i .config + } + # These won't build because of toolchain/libc breakage: + sed 's/^.*CONFIG_FEATURE_SYNC_FANCY.*$/# CONFIG_FEATURE_SYNC_FANCY is not set/' -i .config # no syncfs() + sed 's/^.*CONFIG_FEATURE_WTMP.*$/# CONFIG_FEATURE_WTMP is not set/' -i .config + sed 's/^.*CONFIG_FEATURE_UTMP.*$/# CONFIG_FEATURE_UTMP is not set/' -i .config + sed 's/^.*CONFIG_FEATURE_INETD_RPC.*$/# CONFIG_FEATURE_INETD_RPC is not set/' -i .config + sed 's/^.*CONFIG_BRCTL.*$/# CONFIG_BRCTL is not set/' -i .config + sed 's/^.*CONFIG_IFPLUGD.*$/# CONFIG_IFPLUGD is not set/' -i .config + make #V=1 || sh + size busybox + ./busybox || echo "Exit code: $?" + if uuencode TEST </dev/null >/dev/null && bzip2 </dev/null >/dev/null; then + bzip2 <busybox | uuencode busybox.bz2 + else + od -tx1 <busybox + fi + #test "x$FTP_PORT" = x || + # ftpput -P "$FTP_PORT" "$FTP_SERVER" strace +) 2>&1 | tee build.log +mount -o remount,ro /home +sync +sleep 1 diff --git a/qemu_multiarch_testing/hdc.dir/init b/qemu_multiarch_testing/hdc.dir/init new file mode 100755 index 000000000..692371db6 --- /dev/null +++ b/qemu_multiarch_testing/hdc.dir/init @@ -0,0 +1,9 @@ +#!/bin/sh + +# Emit a msg to let user know this place was reached +echo "Copying to /home" +# Had a case where cp SEGVs, let's have diagnostics for it +cp -a /mnt /home || { echo "cp: $?"; exit 1; } +cd /home/mnt || { echo "cd: $?"; exit 1; } +exec ./build +echo "Failed to exec ./build" diff --git a/qemu_multiarch_testing/make-hdc-img.sh b/qemu_multiarch_testing/make-hdc-img.sh new file mode 100755 index 000000000..3c35f4ead --- /dev/null +++ b/qemu_multiarch_testing/make-hdc-img.sh @@ -0,0 +1,30 @@ +#!/bin/sh -ex + +mountpoint -q / +[ ! -e hdc.img.dir ] + +cleanup() +{ + trap - EXIT + if mountpoint -q hdc.img.dir; then + umount -d hdc.img.dir + fi + mountpoint -q hdc.img.dir || + rm -rf hdc.img.dir + exit $@ +} + +trap 'cleanup $?' EXIT +trap 'cleanup 1' HUP PIPE INT QUIT TERM + +size=$(du -ks hdc.dir | sed -rn 's/^([0-9]+).*/\1/p') +[ "$size" -gt 0 ] + +rm -f hdc.img +dd if=/dev/zero of=hdc.img count=1 bs=1024 seek=$(($size*2)) +mkfs.ext3 -q -F -b 1024 -i 4096 hdc.img +tune2fs -c 0 -i 0 hdc.img +mkdir hdc.img.dir +mount -o loop hdc.img hdc.img.dir +cp -a hdc.dir/* hdc.img.dir/ +umount -d hdc.img.dir diff --git a/qemu_multiarch_testing/parallel-build-hdc-img.sh b/qemu_multiarch_testing/parallel-build-hdc-img.sh new file mode 100755 index 000000000..9ee54ebb8 --- /dev/null +++ b/qemu_multiarch_testing/parallel-build-hdc-img.sh @@ -0,0 +1,40 @@ +#!/bin/sh + +export HDBMEGS=100 +keep_hdb=false + +build_in_dir() +{ + cd "$1" || exit 1 + rm -f hdb.img + nice -n10 time ./native-build.sh ../hdc.img + $keep_hdb || rm -f hdb.img + echo >&3 "Finished: $1" +} + +test "$1" = "-s" && { + dir="$2" + # single mode: build one directory, show output + test -d "$dir" || exit 1 + test -e "$dir/native-build.sh" || exit 1 + build_in_dir "$dir" + exit $? +} + +started=false +for dir; do + test -d "$dir" || continue + test -e "$dir/native-build.sh" || continue + echo "Starting: $dir" + build_in_dir "$dir" 3>&1 </dev/null >"$dir.log" 2>&1 & + started=true +done + +$started || { + echo "Give me system-image-ARCH directories on command line" + exit 1 +} + +echo "Waiting to finish" +wait +echo "Done, check the logs" -- cgit v1.2.3-55-g6feb From 5fa6d1a632505789409a2ba6cf8e112529f9db18 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko <vda.linux@googlemail.com> Date: Mon, 5 Oct 2015 11:15:43 +0200 Subject: Aboriginal linux/musl build fixes Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com> --- Config.in | 8 ++++++++ Makefile.flags | 2 ++ applets/usage_compressed | 9 +++++++++ networking/brctl.c | 52 +++++++++++++++++++++++++++++++++++++++++++++++- networking/ifplugd.c | 12 ++++++++++- 5 files changed, 81 insertions(+), 2 deletions(-) diff --git a/Config.in b/Config.in index 07b4bf36b..11371c783 100644 --- a/Config.in +++ b/Config.in @@ -514,6 +514,14 @@ config PIE Most people will leave this set to 'N'. +config LINK_WITH_PTHREAD + bool "Link with pthread library" + default n + help + On some systems, some libraries (such as crypt) also require pthread. + + Select this only if your build otherwise fails. + config NOMMU bool "Force NOMMU build" default n diff --git a/Makefile.flags b/Makefile.flags index b29b06839..2bc83d1d9 100644 --- a/Makefile.flags +++ b/Makefile.flags @@ -126,10 +126,12 @@ else LDLIBS += m endif +ifeq ($(CONFIG_LINK_WITH_PTHREAD),y) PTHREAD_AVAILABLE := $(shell echo 'int main(void){return 0;}' >pthreadtest.c; $(CC) $(CFLAGS) -lpthread -o /dev/null pthreadtest.c >/dev/null 2>&1 && echo "y"; rm pthreadtest.c) ifeq ($(PTHREAD_AVAILABLE),y) LDLIBS += pthread endif +endif ifeq ($(CONFIG_PAM),y) # libpam uses libpthread, libdl and libaudit, so for static builds busybox diff --git a/applets/usage_compressed b/applets/usage_compressed index fb6e1c286..186fcde77 100755 --- a/applets/usage_compressed +++ b/applets/usage_compressed @@ -20,6 +20,7 @@ exec >"$target.$$" echo '#define UNPACKED_USAGE "" \' "$loc/usage" | od -v -b \ +| grep -v '^ ' \ | $SED -e 's/^[^ ]*//' \ -e 's/ //g' \ -e '/^$/d' \ @@ -27,6 +28,13 @@ echo '#define UNPACKED_USAGE "" \' -e 's/^/"/' \ -e 's/$/" \\/' echo '' +# "grep -v '^ '" is for toybox's od bug: od -b prints some extra lines: +#0000000 010 000 010 000 133 055 144 146 135 040 133 055 143 040 103 117 +# 000010 000010 026533 063144 020135 026533 020143 047503 +#0000020 116 106 104 111 122 135 040 133 055 154 040 114 117 107 106 111 +# 043116 044504 056522 055440 066055 046040 043517 044506 +#0000040 114 105 135 040 133 055 141 040 101 103 124 111 117 116 106 111 +# 042514 020135 026533 020141 041501 044524 047117 044506 echo '#define PACKED_USAGE \' ## Breaks on big-endian systems! @@ -40,6 +48,7 @@ echo '#define PACKED_USAGE \' ## -e 's/\(..\)\(..\)/0x\2,0x\1,/g' ## -e 's/$/ \\/' "$loc/usage" | bzip2 -1 | $DD bs=2 skip=1 2>/dev/null | od -v -b \ +| grep -v '^ ' \ | $SED -e 's/^[^ ]*//' \ -e 's/ //g' \ -e '/^$/d' \ diff --git a/networking/brctl.c b/networking/brctl.c index 207b069aa..8043d600b 100644 --- a/networking/brctl.c +++ b/networking/brctl.c @@ -64,7 +64,57 @@ #define BRCTL_USE_INTERNAL 1 #if ENABLE_FEATURE_BRCTL_FANCY -# include <linux/if_bridge.h> +/* #include <linux/if_bridge.h> + * breaks on musl: we already included netinet/in.h in libbb.h, + * if we include <linux/if_bridge.h> here, we get this: + * In file included from /usr/include/linux/if_bridge.h:18, + * from networking/brctl.c:67: + * /usr/include/linux/in6.h:32: error: redefinition of 'struct in6_addr' + * /usr/include/linux/in6.h:49: error: redefinition of 'struct sockaddr_in6' + * /usr/include/linux/in6.h:59: error: redefinition of 'struct ipv6_mreq' + */ +/* From <linux/if_bridge.h> */ +#define BRCTL_GET_VERSION 0 +#define BRCTL_GET_BRIDGES 1 +#define BRCTL_ADD_BRIDGE 2 +#define BRCTL_DEL_BRIDGE 3 +#define BRCTL_ADD_IF 4 +#define BRCTL_DEL_IF 5 +#define BRCTL_GET_BRIDGE_INFO 6 +#define BRCTL_GET_PORT_LIST 7 +#define BRCTL_SET_BRIDGE_FORWARD_DELAY 8 +#define BRCTL_SET_BRIDGE_HELLO_TIME 9 +#define BRCTL_SET_BRIDGE_MAX_AGE 10 +#define BRCTL_SET_AGEING_TIME 11 +#define BRCTL_SET_GC_INTERVAL 12 +#define BRCTL_GET_PORT_INFO 13 +#define BRCTL_SET_BRIDGE_STP_STATE 14 +#define BRCTL_SET_BRIDGE_PRIORITY 15 +#define BRCTL_SET_PORT_PRIORITY 16 +#define BRCTL_SET_PATH_COST 17 +#define BRCTL_GET_FDB_ENTRIES 18 +struct __bridge_info { + uint64_t designated_root; + uint64_t bridge_id; + uint32_t root_path_cost; + uint32_t max_age; + uint32_t hello_time; + uint32_t forward_delay; + uint32_t bridge_max_age; + uint32_t bridge_hello_time; + uint32_t bridge_forward_delay; + uint8_t topology_change; + uint8_t topology_change_detected; + uint8_t root_port; + uint8_t stp_enabled; + uint32_t ageing_time; + uint32_t gc_interval; + uint32_t hello_timer_value; + uint32_t tcn_timer_value; + uint32_t topology_change_timer_value; + uint32_t gc_timer_value; +}; +/* end <linux/if_bridge.h> */ /* FIXME: These 4 funcs are not really clean and could be improved */ static ALWAYS_INLINE void bb_strtotimeval(struct timeval *tv, diff --git a/networking/ifplugd.c b/networking/ifplugd.c index fef7a5ac9..1e6c562e0 100644 --- a/networking/ifplugd.c +++ b/networking/ifplugd.c @@ -38,7 +38,17 @@ #include <linux/mii.h> #include <linux/ethtool.h> #ifdef HAVE_NET_ETHERNET_H -# include <net/ethernet.h> +/* musl breakage: + * In file included from /usr/include/net/ethernet.h:10, + * from networking/ifplugd.c:41: + * /usr/include/netinet/if_ether.h:96: error: redefinition of 'struct ethhdr' + * + * Build succeeds without it on musl. Commented it out. + * If on your system you need it, consider removing <linux/ethtool.h> + * and copy-pasting its definitions here (<linux/ethtool.h> is what pulls in + * conflicting definition of struct ethhdr on musl). + */ +/* # include <net/ethernet.h> */ #endif #include <linux/netlink.h> #include <linux/rtnetlink.h> -- cgit v1.2.3-55-g6feb From a779c6d63b6da04e923cb306fcc257264ed4502c Mon Sep 17 00:00:00 2001 From: Denys Vlasenko <vda.linux@googlemail.com> Date: Mon, 5 Oct 2015 12:34:24 +0200 Subject: qemu testing: fix hexdumping of binary Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com> --- qemu_multiarch_testing/hdc.dir/build | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/qemu_multiarch_testing/hdc.dir/build b/qemu_multiarch_testing/hdc.dir/build index 8a65a5582..b7fb61fc8 100755 --- a/qemu_multiarch_testing/hdc.dir/build +++ b/qemu_multiarch_testing/hdc.dir/build @@ -35,7 +35,7 @@ test -x "bin/busybox-$HOST" && { if uuencode TEST </dev/null >/dev/null && bzip2 </dev/null >/dev/null; then bzip2 <busybox | uuencode busybox.bz2 else - od -tx1 <busybox + od -v -tx1 <busybox fi #test "x$FTP_PORT" = x || # ftpput -P "$FTP_PORT" "$FTP_SERVER" strace -- cgit v1.2.3-55-g6feb From e6b578761a77a9b8d073b6b33a3c4e3d175a7c37 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko <vda.linux@googlemail.com> Date: Mon, 5 Oct 2015 12:43:04 +0200 Subject: qemu testing: Do build brctl and ifplugd; force mips32 dialect Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com> --- qemu_multiarch_testing/hdc.dir/build | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/qemu_multiarch_testing/hdc.dir/build b/qemu_multiarch_testing/hdc.dir/build index b7fb61fc8..a9981864a 100755 --- a/qemu_multiarch_testing/hdc.dir/build +++ b/qemu_multiarch_testing/hdc.dir/build @@ -15,20 +15,25 @@ test -x "bin/busybox-$HOST" && { ( #set -e -x cd busybox + make defconfig # Want static build sed 's/^.*CONFIG_STATIC.*$/CONFIG_STATIC=y/' -i .config - # Drats, newer Aboriginal Linux has no bzip2 bzip2 </dev/null >/dev/null || { + # Drats, newer Aboriginal Linux has no bzip2 sed 's/^.*CONFIG_FEATURE_COMPRESS_USAGE.*$/# CONFIG_FEATURE_COMPRESS_USAGE is not set/' -i .config } + test x"`uname -m`" = x"mips" && { + # Without this, I get MIPS-I binary instead of MIPS32. + # No idea what's the difference, but my router wants MIPS32. + sed 's/^.*CONFIG_EXTRA_CFLAGS.*$/CONFIG_EXTRA_CFLAGS="-mips32"/' -i .config + } # These won't build because of toolchain/libc breakage: sed 's/^.*CONFIG_FEATURE_SYNC_FANCY.*$/# CONFIG_FEATURE_SYNC_FANCY is not set/' -i .config # no syncfs() sed 's/^.*CONFIG_FEATURE_WTMP.*$/# CONFIG_FEATURE_WTMP is not set/' -i .config sed 's/^.*CONFIG_FEATURE_UTMP.*$/# CONFIG_FEATURE_UTMP is not set/' -i .config sed 's/^.*CONFIG_FEATURE_INETD_RPC.*$/# CONFIG_FEATURE_INETD_RPC is not set/' -i .config - sed 's/^.*CONFIG_BRCTL.*$/# CONFIG_BRCTL is not set/' -i .config - sed 's/^.*CONFIG_IFPLUGD.*$/# CONFIG_IFPLUGD is not set/' -i .config + make #V=1 || sh size busybox ./busybox || echo "Exit code: $?" -- cgit v1.2.3-55-g6feb From 2b48c38be60cf9033761365f40c05f2e6a41a1c4 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko <vda.linux@googlemail.com> Date: Mon, 5 Oct 2015 15:10:44 +0200 Subject: uudecode: tolerate text input with CR+LF line ends function old new delta read_stduu 265 308 +43 uudecode_main 313 317 +4 Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com> --- coreutils/uudecode.c | 13 ++++++++++++- qemu_multiarch_testing/README | 19 +++++++------------ 2 files changed, 19 insertions(+), 13 deletions(-) diff --git a/coreutils/uudecode.c b/coreutils/uudecode.c index 7aa5c67f2..37b254d30 100644 --- a/coreutils/uudecode.c +++ b/coreutils/uudecode.c @@ -29,9 +29,19 @@ static void FAST_FUNC read_stduu(FILE *src_stream, FILE *dst_stream, int flags U { char *line; - while ((line = xmalloc_fgetline(src_stream)) != NULL) { + for (;;) { int encoded_len, str_len; char *line_ptr, *dst; + size_t line_len; + + line_len = 64 * 1024; + line = xmalloc_fgets_str_len(src_stream, "\n", &line_len); + if (!line) + break; + /* Handle both Unix and MSDOS text, and stray trailing spaces */ + str_len = line_len; + while (--str_len >= 0 && isspace(line[str_len])) + line[str_len] = '\0'; if (strcmp(line, "end") == 0) { return; /* the only non-error exit */ @@ -128,6 +138,7 @@ int uudecode_main(int argc UNUSED_PARAM, char **argv) if (!outname) break; outname++; + trim(outname); /* remove trailing space (and '\r' for DOS text) */ if (!outname[0]) break; } diff --git a/qemu_multiarch_testing/README b/qemu_multiarch_testing/README index 69ddb76b8..9757ff0e4 100644 --- a/qemu_multiarch_testing/README +++ b/qemu_multiarch_testing/README @@ -33,7 +33,7 @@ You can also run "./parallel-build-hdc-img.sh -s system-image-ARCH" - single mode, output is to screen and serial input is from keyboard. If hdc.dir/bin/busybox-$ARCH exists, it will be used during build -to supply additional tools. +to supply additional tools (dir with all applets appended to $PATH). For me, the following system images worked: system-image-armv4l @@ -42,22 +42,17 @@ system-image-armv5l od is buggy on arm*: # echo Hello-hello-hello-hello | od -b 0000000 110 145 154 154 157 055 150 145 154 154 157 055 150 145 154 154 - 0000000 157 055 150 145 154 154 157 012 - 0000000 + 0000000 157 055 150 145 154 154 157 012 <= WRONG OFFSET + 0000000 (can also be even more bogus like 17767153361) system-image-i686 -system-image-mips -system-image-mipsel - od is buggy on mips[el]: - # echo Hello-hello-hello-hello | od -b - 0000000 110 145 154 154 157 055 150 145 154 154 157 055 150 145 154 154 - 17767153361 157 055 150 145 154 154 157 012 - 0000000 +system-image-mips - od is buggy +system-image-mipsel - od is buggy system-image-x86_64 +system-image-powerpc - qemu 1.2.2 didn't work, 2.4.0 worked; od is buggy +system-image-sparc - qemu 1.2.2 didn't work, 2.4.0 worked; od is buggy And these did not: system-image-armv6l - hang on "Uncompressing Linux... done, booting the kernel" -system-image-powerpc - hang early in kernel boot -system-image-sparc - hang early in userspace system-image-m68k - my qemu doesn't like "-M q800" system-image-mips64 - init dies "Kernel panic - not syncing: Attempted to kill init! exitcode=0x0000000a" system-image-sh4 - qemu segfaults early in kernel boot -- cgit v1.2.3-55-g6feb From 3b650c1e7b0bcbb4dfebab6fd87449e6b1e0b788 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko <vda.linux@googlemail.com> Date: Mon, 5 Oct 2015 16:46:29 +0200 Subject: qemu testing: extract_od_binary.sh: support huge files (and broken od) Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com> --- qemu_multiarch_testing/extract_od_binary.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/qemu_multiarch_testing/extract_od_binary.sh b/qemu_multiarch_testing/extract_od_binary.sh index e4c2c2a0a..1006e5153 100755 --- a/qemu_multiarch_testing/extract_od_binary.sh +++ b/qemu_multiarch_testing/extract_od_binary.sh @@ -3,4 +3,4 @@ # Converts textual result of "od -tx1 <FILE" # back into a binary FILE -grep -a '^[0-7][0-7][0-7][0-7][0-7][0-7][0-7] [0-9a-f][0-9a-f] [0-9a-f][0-9a-f] [0-9a-f][0-9a-f] [0-9a-f][0-9a-f]' | busybox hexdump -R +grep -a '^[0-7][0-7][0-7][0-7][0-7][0-7][0-7][0-7]* [0-9a-f][0-9a-f] [0-9a-f][0-9a-f] [0-9a-f][0-9a-f] [0-9a-f][0-9a-f]' | busybox hexdump -R -- cgit v1.2.3-55-g6feb From 1c6c670ed44a77ab4784ea0d4ac5411d7b0648d8 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko <vda.linux@googlemail.com> Date: Wed, 7 Oct 2015 01:39:40 +0200 Subject: wget: make openssl/ssl_helper choice configurable I got sick of not being able to wget a https file... Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com> --- include/applets.src.h | 1 - networking/Config.src | 42 -- networking/Kbuild.src | 1 - networking/ssl_helper-wolfssl/00cfg-wolfssl-3.6.8 | 22 + networking/ssl_helper-wolfssl/README | 15 + networking/ssl_helper-wolfssl/ssl_helper.c | 480 ++++++++++++++++++++++ networking/ssl_helper-wolfssl/ssl_helper.sh | 11 + networking/wget.c | 105 ++++- 8 files changed, 623 insertions(+), 54 deletions(-) create mode 100755 networking/ssl_helper-wolfssl/00cfg-wolfssl-3.6.8 create mode 100644 networking/ssl_helper-wolfssl/README create mode 100644 networking/ssl_helper-wolfssl/ssl_helper.c create mode 100755 networking/ssl_helper-wolfssl/ssl_helper.sh diff --git a/include/applets.src.h b/include/applets.src.h index 9f3ac78cb..dac83e7fb 100644 --- a/include/applets.src.h +++ b/include/applets.src.h @@ -382,7 +382,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_WGET(APPLET(wget, 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)) diff --git a/networking/Config.src b/networking/Config.src index da36e8627..76cbccf4a 100644 --- a/networking/Config.src +++ b/networking/Config.src @@ -947,48 +947,6 @@ config VCONFIG help Creates, removes, and configures VLAN interfaces -config WGET - bool "wget" - default y - help - wget is a utility for non-interactive download of files from HTTP - and FTP servers. - -config FEATURE_WGET_STATUSBAR - bool "Enable a nifty process meter (+2k)" - default y - depends on WGET - help - Enable the transfer progress bar for wget transfers. - -config FEATURE_WGET_AUTHENTICATION - bool "Enable HTTP authentication" - default y - depends on WGET - help - Support authenticated HTTP transfers. - -config FEATURE_WGET_LONG_OPTIONS - bool "Enable long options" - default y - depends on WGET && LONG_OPTS - help - Support long options for the wget applet. - -config FEATURE_WGET_TIMEOUT - bool "Enable timeout option -T SEC" - default y - depends on WGET - help - Supports network read and connect timeouts for wget, - so that wget will give up and timeout, through the -T - command line option. - - Currently only connect and network data read timeout are - supported (i.e., timeout is not applied to the DNS query). When - FEATURE_WGET_LONG_OPTIONS is also enabled, the --timeout option - will work in addition to -T. - config ZCIP bool "zcip" default y diff --git a/networking/Kbuild.src b/networking/Kbuild.src index 944f27be1..79f54824b 100644 --- a/networking/Kbuild.src +++ b/networking/Kbuild.src @@ -41,7 +41,6 @@ lib-$(CONFIG_TFTPD) += tftp.o lib-$(CONFIG_TRACEROUTE) += traceroute.o lib-$(CONFIG_TUNCTL) += tunctl.o lib-$(CONFIG_VCONFIG) += vconfig.o -lib-$(CONFIG_WGET) += wget.o lib-$(CONFIG_ZCIP) += zcip.o lib-$(CONFIG_TCPSVD) += tcpudp.o tcpudp_perhost.o diff --git a/networking/ssl_helper-wolfssl/00cfg-wolfssl-3.6.8 b/networking/ssl_helper-wolfssl/00cfg-wolfssl-3.6.8 new file mode 100755 index 000000000..27d0c41ee --- /dev/null +++ b/networking/ssl_helper-wolfssl/00cfg-wolfssl-3.6.8 @@ -0,0 +1,22 @@ +#!/bin/sh + +# How to configure & build a static wolfssl-3.6.8 library +# suitable for static build of ssl_helper. + +export CC="x86_64-gcc" +export CFLAGS="\ +-Os \ +-static \ +-fomit-frame-pointer \ +-falign-functions=1 -falign-labels=1 -falign-loops=1 -falign-jumps=1 \ +-ffunction-sections -fdata-sections \ +" + +./configure \ + --enable-static \ + --enable-singlethreaded \ + --disable-shared \ +|| exit $? + +make +exit $? diff --git a/networking/ssl_helper-wolfssl/README b/networking/ssl_helper-wolfssl/README new file mode 100644 index 000000000..17437606d --- /dev/null +++ b/networking/ssl_helper-wolfssl/README @@ -0,0 +1,15 @@ +Build instructions: + +* Unpack wolfssl-3.6.8.zip +* Build it: + ./configure --enable-static --disable-shared && make +* Drop this directory into wolfssl-3.6.8/ssl_helper +* Run ssl_helper.sh to compile and link the helper + +Usage: "ssl_helper -d FILE_DESCRIPTOR" where FILE_DESCRIPTOR is open to the peer. + +In bash, you can do it this way: +$ ssl_helper -d3 3<>/dev/tcp/HOST/PORT + +Stdin will be SSL-encrypted and sent to FILE_DESCRIPTOR. +Data from FILE_DESCRIPTOR will be decrypted and sent to stdout. diff --git a/networking/ssl_helper-wolfssl/ssl_helper.c b/networking/ssl_helper-wolfssl/ssl_helper.c new file mode 100644 index 000000000..38b7b56c6 --- /dev/null +++ b/networking/ssl_helper-wolfssl/ssl_helper.c @@ -0,0 +1,480 @@ +/* + * Adapted from: + * + * client.c + * + * Copyright (C) 2006-2015 wolfSSL Inc. + * + * This file is part of wolfSSL. (formerly known as CyaSSL) + * + * wolfSSL is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * wolfSSL is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ +#include <stdlib.h> +#include <unistd.h> +#include <stdarg.h> +#include <string.h> +#include <errno.h> +#include <fcntl.h> +#include <stdio.h> +#include <time.h> +#include <poll.h> +#include <sys/socket.h> + +#include <wolfssl/wolfcrypt/types.h> +#include <wolfssl/ssl.h> + +#if 0 +# define dbg(...) say(__VA_ARGS__) +#else +# define dbg(...) ((void)0) +#endif + +static ssize_t safe_write(int fd, const void *buf, size_t count) +{ + ssize_t n; + + do { + n = write(fd, buf, count); + } while (n < 0 && errno == EINTR); + + return n; +} + +static ssize_t full_write(int fd, const void *buf, size_t len) +{ + ssize_t cc; + ssize_t total; + + total = 0; + + while (len) { + cc = safe_write(fd, buf, len); + + if (cc < 0) { + if (total) { + /* we already wrote some! */ + /* user can do another write to know the error code */ + return total; + } + return cc; /* write() returns -1 on failure. */ + } + + total += cc; + buf = ((const char *)buf) + cc; + len -= cc; + } + + return total; +} + +static void say(const char *s, ...) +{ + char buf[256]; + va_list p; + int sz; + + va_start(p, s); + sz = vsnprintf(buf, sizeof(buf), s, p); + full_write(STDERR_FILENO, buf, sz >= 0 && sz < sizeof(buf) ? sz : strlen(buf)); + va_end(p); +} + +static void die(const char *s, ...) +{ + char buf[256]; + va_list p; + int sz; + + va_start(p, s); + sz = vsnprintf(buf, sizeof(buf), s, p); + full_write(STDERR_FILENO, buf, sz >= 0 && sz < sizeof(buf) ? sz : strlen(buf)); + exit(1); + va_end(p); +} + +static void err_sys(const char *msg) +{ + die("%s\n", msg); +} + +/* ==== */ + +#if 0 +static void showPeer(WOLFSSL* ssl) +{ + WOLFSSL_CIPHER* cipher; + WOLFSSL_X509* peer = wolfSSL_get_peer_certificate(ssl); + if (peer) + ShowX509(peer, "peer's cert info:"); + else + say("peer has no cert!\n"); + say("SSL version is %s\n", wolfSSL_get_version(ssl)); + + cipher = wolfSSL_get_current_cipher(ssl); + say("SSL cipher suite is %s\n", wolfSSL_CIPHER_get_name(cipher)); + + { + WOLFSSL_X509_CHAIN* chain = wolfSSL_get_peer_chain(ssl); + int count = wolfSSL_get_chain_count(chain); + int i; + + for (i = 0; i < count; i++) { + int length; + unsigned char buffer[3072]; + WOLFSSL_X509* chainX509; + + wolfSSL_get_chain_cert_pem(chain, i, buffer, sizeof(buffer), &length); + buffer[length] = 0; + say("cert %d has length %d data = \n%s\n", i, length, buffer); + + chainX509 = wolfSSL_get_chain_X509(chain, i); + if (chainX509) + ShowX509(chainX509, "session cert info:"); + else + say("get_chain_X509 failed\n"); + wolfSSL_FreeX509(chainX509); + } + } +} +#endif + +WOLFSSL *prepare(int sockfd) +{ + WOLFSSL_METHOD* method; + WOLFSSL_CTX* ctx; + WOLFSSL* ssl; + + wolfSSL_Init(); + + method = wolfTLSv1_1_client_method(); + if (method == NULL) + err_sys("out of memory"); + ctx = wolfSSL_CTX_new(method); + if (ctx == NULL) + err_sys("out of memory"); +// if (cipherList) +// if (wolfSSL_CTX_set_cipher_list(ctx, cipherList) != SSL_SUCCESS) +// err_sys("client can't set cipher list 1"); + +// if (fewerPackets) +// wolfSSL_CTX_set_group_messages(ctx); + +//#ifndef NO_DH +// wolfSSL_CTX_SetMinDhKey_Sz(ctx, (word16)minDhKeyBits); +//#endif + +// if (usePsk) { +// wolfSSL_CTX_set_psk_client_callback(ctx, my_psk_client_cb); +// if (cipherList == NULL) { +// const char *defaultCipherList; +//#if defined(HAVE_AESGCM) && !defined(NO_DH) +// defaultCipherList = "DHE-PSK-AES128-GCM-SHA256"; +//#elif defined(HAVE_NULL_CIPHER) +// defaultCipherList = "PSK-NULL-SHA256"; +//#else +// defaultCipherList = "PSK-AES128-CBC-SHA256"; +//#endif +// if (wolfSSL_CTX_set_cipher_list(ctx,defaultCipherList) != SSL_SUCCESS) +// err_sys("client can't set cipher list 2"); +// } +// useClientCert = 0; +// } + +// if (useAnon) { +// if (cipherList == NULL) { +// wolfSSL_CTX_allow_anon_cipher(ctx); +// if (wolfSSL_CTX_set_cipher_list(ctx,"ADH-AES128-SHA") != SSL_SUCCESS) +// err_sys("client can't set cipher list 4"); +// } +// useClientCert = 0; +// } + +//#if defined(OPENSSL_EXTRA) || defined(HAVE_WEBSERVER) +// wolfSSL_CTX_set_default_passwd_cb(ctx, PasswordCallBack); +//#endif + +// if (useOcsp) { +// if (ocspUrl != NULL) { +// wolfSSL_CTX_SetOCSP_OverrideURL(ctx, ocspUrl); +// wolfSSL_CTX_EnableOCSP(ctx, WOLFSSL_OCSP_NO_NONCE +// | WOLFSSL_OCSP_URL_OVERRIDE); +// } +// else +// wolfSSL_CTX_EnableOCSP(ctx, WOLFSSL_OCSP_NO_NONCE); +// } +// +//#ifdef USER_CA_CB +// wolfSSL_CTX_SetCACb(ctx, CaCb); +//#endif +// +//#ifdef VERIFY_CALLBACK +// wolfSSL_CTX_set_verify(ctx, SSL_VERIFY_PEER, myVerify); +//#endif +//#if !defined(NO_FILESYSTEM) && !defined(NO_CERTS) +// if (useClientCert) { +// if (wolfSSL_CTX_use_certificate_chain_file(ctx, ourCert) != SSL_SUCCESS) +// err_sys("can't load client cert file, check file and run from" +// " wolfSSL home dir"); +// if (wolfSSL_CTX_use_PrivateKey_file(ctx, ourKey, SSL_FILETYPE_PEM) != SSL_SUCCESS) +// err_sys("can't load client private key file, check file and run " +// "from wolfSSL home dir"); +// } +// +// if (!usePsk && !useAnon) { +// if (wolfSSL_CTX_load_verify_locations(ctx, verifyCert,0) != SSL_SUCCESS) +// err_sys("can't load ca file, Please run from wolfSSL home dir"); +//#ifdef HAVE_ECC +// /* load ecc verify too, echoserver uses it by default w/ ecc */ +// if (wolfSSL_CTX_load_verify_locations(ctx, eccCert, 0) != SSL_SUCCESS) +// err_sys("can't load ecc ca file, Please run from wolfSSL home dir"); +//#endif +// } +//#endif /* !NO_FILESYSTEM && !NO_CERTS */ + +//#if !defined(NO_CERTS) +// if (!usePsk && !useAnon && doPeerCheck == 0) +// wolfSSL_CTX_set_verify(ctx, SSL_VERIFY_NONE, 0); +// if (!usePsk && !useAnon && overrideDateErrors == 1) +// wolfSSL_CTX_set_verify(ctx, SSL_VERIFY_PEER, myDateCb); +//#endif + + wolfSSL_CTX_set_verify(ctx, SSL_VERIFY_NONE, 0); + +//#ifdef HAVE_SNI +// if (sniHostName) +// if (wolfSSL_CTX_UseSNI(ctx, 0, sniHostName, XSTRLEN(sniHostName)) != SSL_SUCCESS) +// err_sys("UseSNI failed"); +//#endif + +//#ifdef HAVE_MAX_FRAGMENT +// if (maxFragment) +// if (wolfSSL_CTX_UseMaxFragment(ctx, maxFragment) != SSL_SUCCESS) +// err_sys("UseMaxFragment failed"); +//#endif +//#ifdef HAVE_TRUNCATED_HMAC +// if (truncatedHMAC) +// if (wolfSSL_CTX_UseTruncatedHMAC(ctx) != SSL_SUCCESS) +// err_sys("UseTruncatedHMAC failed"); +//#endif +//#ifdef HAVE_SESSION_TICKET +// if (wolfSSL_CTX_UseSessionTicket(ctx) != SSL_SUCCESS) +// err_sys("UseSessionTicket failed"); +//#endif + +//#if defined(WOLFSSL_MDK_ARM) +// wolfSSL_CTX_set_verify(ctx, SSL_VERIFY_NONE, 0); +//#endif + + ssl = wolfSSL_new(ctx); + if (ssl == NULL) + err_sys("out of memory"); + +//#ifdef HAVE_SESSION_TICKET +// wolfSSL_set_SessionTicket_cb(ssl, sessionTicketCB, (void*)"initial session"); +//#endif + +// if (doDTLS) { +// SOCKADDR_IN_T addr; +// build_addr(&addr, host, port, 1); +// wolfSSL_dtls_set_peer(ssl, &addr, sizeof(addr)); +// tcp_socket(&sockfd, 1); +// } wlse { +// tcp_connect(&sockfd, host, port, 0); +// } + +//#ifdef HAVE_POLY1305 +// /* use old poly to connect with google server */ +// if (!XSTRNCMP(domain, "www.google.com", 14)) { +// if (wolfSSL_use_old_poly(ssl, 1) != 0) +// err_sys("unable to set to old poly"); +// } +//#endif + + wolfSSL_set_fd(ssl, sockfd); + +//#ifdef HAVE_CRL +// if (disableCRL == 0) { +// if (wolfSSL_EnableCRL(ssl, WOLFSSL_CRL_CHECKALL) != SSL_SUCCESS) +// err_sys("can't enable crl check"); +// if (wolfSSL_LoadCRL(ssl, crlPemDir, SSL_FILETYPE_PEM, 0) != SSL_SUCCESS) +// err_sys("can't load crl, check crlfile and date validity"); +// if (wolfSSL_SetCRL_Cb(ssl, CRL_CallBack) != SSL_SUCCESS) +// err_sys("can't set crl callback"); +// } +//#endif +//#ifdef HAVE_SECURE_RENEGOTIATION +// if (scr) { +// if (wolfSSL_UseSecureRenegotiation(ssl) != SSL_SUCCESS) +// err_sys("can't enable secure renegotiation"); +// } +//#endif +//#ifdef ATOMIC_USER +// if (atomicUser) +// SetupAtomicUser(ctx, ssl); +//#endif +//#ifdef HAVE_PK_CALLBACKS +// if (pkCallbacks) +// SetupPkCallbacks(ctx, ssl); +//#endif +// if (matchName && doPeerCheck) +// wolfSSL_check_domain_name(ssl, domain); + + if (wolfSSL_connect(ssl) != SSL_SUCCESS) { +// /* see note at top of README */ +// int err = wolfSSL_get_error(ssl, 0); +// char buffer[WOLFSSL_MAX_ERROR_SZ]; +// say("err = %d, %s\n", err, +// wolfSSL_ERR_error_string(err, buffer)); + err_sys("SSL_connect failed"); + } +// showPeer(ssl); + +//#ifdef HAVE_SECURE_RENEGOTIATION +// if (scr && forceScr) { +// if (wolfSSL_Rehandshake(ssl) != SSL_SUCCESS) { +// int err = wolfSSL_get_error(ssl, 0); +// char buffer[WOLFSSL_MAX_ERROR_SZ]; +// say("err = %d, %s\n", err, +// wolfSSL_ERR_error_string(err, buffer)); +// err_sys("wolfSSL_Rehandshake failed"); +// } +// } +//#endif + + return ssl; +} + +static struct pollfd pfd[2] = { + { -1, POLLIN|POLLERR|POLLHUP, 0 }, + { -1, POLLIN|POLLERR|POLLHUP, 0 }, +}; +#define STDIN pfd[0] +#define NETWORK pfd[1] +#define STDIN_READY() (pfd[0].revents & (POLLIN|POLLERR|POLLHUP)) +#define NETWORK_READY() (pfd[1].revents & (POLLIN|POLLERR|POLLHUP)) + +static void wait_for_input(void) +{ + if (STDIN.fd == NETWORK.fd) /* means both are -1 */ + exit(0); + dbg("polling\n"); + STDIN.revents = NETWORK.revents = 0; + while (poll(pfd, 2, -1) < 0 && errno == EINTR) + continue; +} + +static void do_io_until_eof_and_exit(WOLFSSL *ssl, int fd) +{ + int len; + char ibuf[4 * 1024]; + + NETWORK.fd = fd; + STDIN.fd = 0; + + len = 0; /* only to suppress compiler warning */ + for (;;) { + wait_for_input(); + + if (STDIN_READY()) { + dbg("reading stdin\n"); + len = read(STDIN_FILENO, ibuf, sizeof(ibuf)); + if (len < 0) + die("read error on stdin\n"); + if (len == 0) { + dbg("read len = 0, stdin not polled anymore\n"); + STDIN.fd = -1; + } else { + int n = wolfSSL_write(ssl, ibuf, len); + if (n != len) + die("SSL_write(%d) failed (returned %d)\n", len, n); + } + } + + if (NETWORK_READY()) { + dbg("%s%s%s\n", + (pfd[1].revents & POLLIN) ? "POLLIN" : "", + (pfd[1].revents & POLLERR) ? "|POLLERR" : "", + (pfd[1].revents & POLLHUP) ? "|POLLHUP" : "" + ); +/* We are using blocking socket here. + * (Nonblocking socket would complicate writing to it). + * Therefore, SSL_read _can block_ here. + * This is not what wget expects (it wants to see short reads). + * Therefore, we use smallish buffer here, to approximate that. + */ + len = wolfSSL_read(ssl, ibuf, + sizeof(ibuf) < 1024 ? sizeof(ibuf) : 1024 + ); + if (len < 0) + die("SSL_read error on network (%d)\n", len); + if (len > 0) { + int n; + n = full_write(STDOUT_FILENO, ibuf, len); + if (n != len) + die("write(%d) to stdout returned %d\n", len, n); + continue; + } +/* Blocking reads are easier wtr EOF detection (no EAGAIN error to check for) */ + dbg("read len = 0, network not polled anymore\n"); + NETWORK.fd = -1; + /* saw EOF on network, and we processed + * and wrote out all ssl data. Signal it: + */ + close(STDOUT_FILENO); + } + } +} + +int main(int argc, char **argv) +{ + WOLFSSL *ssl; + int fd; + char *fd_str; + + if (!argv[1]) + die("Syntax error\n"); + if (argv[1][0] != '-') + die("Syntax error\n"); + if (argv[1][1] != 'd') + die("Syntax error\n"); + fd_str = argv[1] + 2; + if (!fd_str[0]) + fd_str = argv[2]; + if (!fd_str || fd_str[0] < '0' || fd_str[0] > '9') + die("Syntax error\n"); + + fd = atoi(fd_str); + if (fd < 3) + die("Syntax error\n"); + + ssl = prepare(fd); + do_io_until_eof_and_exit(ssl, fd); + /* does not return */ + +// if (doDTLS == 0) { /* don't send alert after "break" command */ +// ret = wolfSSL_shutdown(ssl); +// if (wc_shutdown && ret == SSL_SHUTDOWN_NOT_DONE) +// wolfSSL_shutdown(ssl); /* bidirectional shutdown */ +// } +//#ifdef ATOMIC_USER +// if (atomicUser) +// FreeAtomicUser(ssl); +//#endif +// wolfSSL_free(ssl); +// CloseSocket(sockfd); +// wolfSSL_CTX_free(ctx); + + return 0; +} diff --git a/networking/ssl_helper-wolfssl/ssl_helper.sh b/networking/ssl_helper-wolfssl/ssl_helper.sh new file mode 100755 index 000000000..ddb4536c7 --- /dev/null +++ b/networking/ssl_helper-wolfssl/ssl_helper.sh @@ -0,0 +1,11 @@ +#!/bin/sh + +# I use this to build static uclibc based binary using Aboriginal Linux toolchain: +PREFIX=x86_64- +STATIC=-static +# Standard build: +#PREFIX="" +#STATIC="" + +${PREFIX}gcc -Os -Wall -I.. -c ssl_helper.c -o ssl_helper.o +${PREFIX}gcc $STATIC --start-group ssl_helper.o -lm ../src/.libs/libwolfssl.a --end-group -o ssl_helper diff --git a/networking/wget.c b/networking/wget.c index f744ea2de..baa7e0e78 100644 --- a/networking/wget.c +++ b/networking/wget.c @@ -9,6 +9,89 @@ * Kuhn's copyrights are licensed GPLv2-or-later. File as a whole remains GPLv2. */ +//config:config WGET +//config: bool "wget" +//config: default y +//config: help +//config: wget is a utility for non-interactive download of files from HTTP +//config: and FTP servers. +//config: +//config:config FEATURE_WGET_STATUSBAR +//config: bool "Enable a nifty process meter (+2k)" +//config: default y +//config: depends on WGET +//config: help +//config: Enable the transfer progress bar for wget transfers. +//config: +//config:config FEATURE_WGET_AUTHENTICATION +//config: bool "Enable HTTP authentication" +//config: default y +//config: depends on WGET +//config: help +//config: Support authenticated HTTP transfers. +//config: +//config:config FEATURE_WGET_LONG_OPTIONS +//config: bool "Enable long options" +//config: default y +//config: depends on WGET && LONG_OPTS +//config: help +//config: Support long options for the wget applet. +//config: +//config:config FEATURE_WGET_TIMEOUT +//config: bool "Enable timeout option -T SEC" +//config: default y +//config: depends on WGET +//config: help +//config: Supports network read and connect timeouts for wget, +//config: so that wget will give up and timeout, through the -T +//config: command line option. +//config: +//config: Currently only connect and network data read timeout are +//config: supported (i.e., timeout is not applied to the DNS query). When +//config: FEATURE_WGET_LONG_OPTIONS is also enabled, the --timeout option +//config: will work in addition to -T. +//config: +//config:choice +//config: prompt "Choose how to handle https:// URLs" +//config: depends on WGET +//config: default FEATURE_WGET_OPENSSL +//config: help +//config: Choose how wget establishes SSL connection for https:// URLs. +//config: +//config: Busybox itself contains no SSL code. wget will spawn +//config: a helper program to talk over HTTPS. +//config: +//config: OpenSSL has a simple SSL client for debug purposes. +//config: If you select "openssl" helper, wget will effectively call +//config: "openssl s_client -quiet -connect IP:443 2>/dev/null" +//config: and pipe its data through it. +//config: Note inconvenient API: host resolution is done twice, +//config: and there is no guarantee openssl's idea of IPv6 address +//config: format is the same as ours. +//config: Another problem is that s_client prints debug information +//config: to stderr, and it needs to be suppressed. This means +//config: all error messages get suppressed too. +//config: openssl is also a big binary, often dynamically linked +//config: against ~15 libraries. +//config: +//config: ssl_helper is a tool which can be built statically +//config: from busybox sources against a small embedded SSL library. +//config: Please see networking/ssl_helper/README. +//config: It does not require double host resolution and emits +//config: error messages to stderr. +//config: +//config:config FEATURE_WGET_OPENSSL +//config: bool "openssl" +//config: +//config:config FEATURE_WGET_SSL_HELPER +//config: bool "ssl_helper" +//config: +//config:endchoice + +//applet:IF_WGET(APPLET(wget, BB_DIR_USR_BIN, BB_SUID_DROP)) + +//kbuild:lib-$(CONFIG_WGET) += wget.o + //usage:#define wget_trivial_usage //usage: IF_FEATURE_WGET_LONG_OPTIONS( //usage: "[-c|--continue] [-s|--spider] [-q|--quiet] [-O|--output-document FILE]\n" @@ -520,6 +603,7 @@ static FILE* prepare_ftp_session(FILE **dfpp, struct host_info *target, len_and_ return sfp; } +#if ENABLE_FEATURE_WGET_OPENSSL static int spawn_https_helper(const char *host, unsigned port) { char *allocated = NULL; @@ -569,12 +653,11 @@ static int spawn_https_helper(const char *host, unsigned port) close(sp[1]); return sp[0]; } +#endif -/* See networking/ssl_helper/README */ -#define SSL_HELPER 0 - -#if SSL_HELPER -static void spawn_https_helper1(int network_fd) +/* See networking/ssl_helper/README how to build one */ +#if ENABLE_FEATURE_WGET_SSL_HELPER +static void spawn_https_helper(int network_fd) { int sp[2]; int pid; @@ -851,19 +934,21 @@ static void download_one_url(const char *url) int status; /* Open socket to http(s) server */ +#if ENABLE_FEATURE_WGET_OPENSSL if (target.protocol == P_HTTPS) { -/* openssl-based helper - * Inconvenient API since we can't give it an open fd - */ + /* openssl-based helper + * Inconvenient API since we can't give it an open fd + */ int fd = spawn_https_helper(server.host, server.port); sfp = fdopen(fd, "r+"); if (!sfp) bb_perror_msg_and_die(bb_msg_memory_exhausted); } else +#endif sfp = open_socket(lsa); -#if SSL_HELPER +#if ENABLE_FEATURE_WGET_SSL_HELPER if (target.protocol == P_HTTPS) - spawn_https_helper1(fileno(sfp)); + spawn_https_helper(fileno(sfp)); #endif /* Send HTTP request */ if (use_proxy) { -- cgit v1.2.3-55-g6feb From 78fb6ea63a1421be106baf87f8155e701da9a2dc Mon Sep 17 00:00:00 2001 From: Denys Vlasenko <vda.linux@googlemail.com> Date: Wed, 7 Oct 2015 02:00:11 +0200 Subject: ssl_helper: tweaks discovered while building 32-bit version Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com> --- networking/ssl_helper-wolfssl/00cfg-wolfssl-3.6.8 | 4 ++-- networking/ssl_helper-wolfssl/README | 5 +++++ networking/ssl_helper-wolfssl/ssl_helper.sh | 5 +++-- 3 files changed, 10 insertions(+), 4 deletions(-) diff --git a/networking/ssl_helper-wolfssl/00cfg-wolfssl-3.6.8 b/networking/ssl_helper-wolfssl/00cfg-wolfssl-3.6.8 index 27d0c41ee..50b6102d9 100755 --- a/networking/ssl_helper-wolfssl/00cfg-wolfssl-3.6.8 +++ b/networking/ssl_helper-wolfssl/00cfg-wolfssl-3.6.8 @@ -3,7 +3,7 @@ # How to configure & build a static wolfssl-3.6.8 library # suitable for static build of ssl_helper. -export CC="x86_64-gcc" +export CC="i686-gcc" export CFLAGS="\ -Os \ -static \ @@ -13,10 +13,10 @@ export CFLAGS="\ " ./configure \ + --host=i686 \ --enable-static \ --enable-singlethreaded \ --disable-shared \ || exit $? make -exit $? diff --git a/networking/ssl_helper-wolfssl/README b/networking/ssl_helper-wolfssl/README index 17437606d..58a381c20 100644 --- a/networking/ssl_helper-wolfssl/README +++ b/networking/ssl_helper-wolfssl/README @@ -1,3 +1,8 @@ +A small SSL helper for busybox wget. + +Precompiled static binary may be found in +http://busybox.net/downloads/binaries/ + Build instructions: * Unpack wolfssl-3.6.8.zip diff --git a/networking/ssl_helper-wolfssl/ssl_helper.sh b/networking/ssl_helper-wolfssl/ssl_helper.sh index ddb4536c7..184ffe67e 100755 --- a/networking/ssl_helper-wolfssl/ssl_helper.sh +++ b/networking/ssl_helper-wolfssl/ssl_helper.sh @@ -1,11 +1,12 @@ #!/bin/sh # I use this to build static uclibc based binary using Aboriginal Linux toolchain: -PREFIX=x86_64- -STATIC=-static +PREFIX="i686-" +STATIC="-static" # Standard build: #PREFIX="" #STATIC="" ${PREFIX}gcc -Os -Wall -I.. -c ssl_helper.c -o ssl_helper.o ${PREFIX}gcc $STATIC --start-group ssl_helper.o -lm ../src/.libs/libwolfssl.a --end-group -o ssl_helper +${PREFIX}-strip ssl_helper -- cgit v1.2.3-55-g6feb From 4271698fea42a51e48a5d761e8c00a5fd57661de Mon Sep 17 00:00:00 2001 From: Denys Vlasenko <vda.linux@googlemail.com> Date: Wed, 7 Oct 2015 02:02:56 +0200 Subject: ifplugd: discovered why it needed net/ethernet.h: just for ETH_ALEN Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com> --- networking/ifplugd.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/networking/ifplugd.c b/networking/ifplugd.c index 1e6c562e0..f0defb5c8 100644 --- a/networking/ifplugd.c +++ b/networking/ifplugd.c @@ -58,6 +58,10 @@ #define __user #include <linux/wireless.h> +#ifndef ETH_ALEN +# define ETH_ALEN 6 +#endif + /* From initial port to busybox, removed most of the redundancy by converting implementation of a polymorphic interface to the strict -- cgit v1.2.3-55-g6feb From 2007ef5c3cd351ab15b9cb70dd65bf9105403822 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko <vda.linux@googlemail.com> Date: Wed, 7 Oct 2015 02:40:53 +0200 Subject: wget: make it possible to have both SSL helpers configured Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com> --- networking/wget.c | 76 ++++++++++++++++++++++++++++++++++++++----------------- 1 file changed, 53 insertions(+), 23 deletions(-) diff --git a/networking/wget.c b/networking/wget.c index baa7e0e78..d4a9c0cb1 100644 --- a/networking/wget.c +++ b/networking/wget.c @@ -51,10 +51,10 @@ //config: FEATURE_WGET_LONG_OPTIONS is also enabled, the --timeout option //config: will work in addition to -T. //config: -//config:choice -//config: prompt "Choose how to handle https:// URLs" +//config:config FEATURE_WGET_OPENSSL +//config: bool "Try to connect to HTTPS using openssl" +//config: default y //config: depends on WGET -//config: default FEATURE_WGET_OPENSSL //config: help //config: Choose how wget establishes SSL connection for https:// URLs. //config: @@ -74,19 +74,24 @@ //config: openssl is also a big binary, often dynamically linked //config: against ~15 libraries. //config: +//config:config FEATURE_WGET_SSL_HELPER +//config: bool "Try to connect to HTTPS using ssl_helper" +//config: default y +//config: depends on WGET +//config: help +//config: Choose how wget establishes SSL connection for https:// URLs. +//config: +//config: Busybox itself contains no SSL code. wget will spawn +//config: a helper program to talk over HTTPS. +//config: //config: ssl_helper is a tool which can be built statically //config: from busybox sources against a small embedded SSL library. //config: Please see networking/ssl_helper/README. //config: It does not require double host resolution and emits //config: error messages to stderr. //config: -//config:config FEATURE_WGET_OPENSSL -//config: bool "openssl" -//config: -//config:config FEATURE_WGET_SSL_HELPER -//config: bool "ssl_helper" -//config: -//config:endchoice +//config: Precompiled static binary may be available at +//config: http://busybox.net/downloads/binaries/ //applet:IF_WGET(APPLET(wget, BB_DIR_USR_BIN, BB_SUID_DROP)) @@ -604,11 +609,12 @@ static FILE* prepare_ftp_session(FILE **dfpp, struct host_info *target, len_and_ } #if ENABLE_FEATURE_WGET_OPENSSL -static int spawn_https_helper(const char *host, unsigned port) +static int spawn_https_helper_openssl(const char *host, unsigned port) { char *allocated = NULL; int sp[2]; int pid; + IF_FEATURE_WGET_SSL_HELPER(volatile int child_failed = 0;) if (socketpair(AF_UNIX, SOCK_STREAM, 0, sp) != 0) /* Kernel can have AF_UNIX support disabled */ @@ -617,7 +623,8 @@ static int spawn_https_helper(const char *host, unsigned port) if (!strchr(host, ':')) host = allocated = xasprintf("%s:%u", host, port); - pid = BB_MMU ? xfork() : xvfork(); + fflush_all(); + pid = xvfork(); if (pid == 0) { /* Child */ char *argv[6]; @@ -625,10 +632,6 @@ static int spawn_https_helper(const char *host, unsigned port) close(sp[0]); xmove_fd(sp[1], 0); xdup2(0, 1); - /* - * TODO: develop a tiny ssl/tls helper (using matrixssl?), - * try to exec it here before falling back to big fat openssl. - */ /* * openssl s_client -quiet -connect www.kernel.org:443 2>/dev/null * It prints some debug stuff on stderr, don't know how to suppress it. @@ -644,20 +647,31 @@ static int spawn_https_helper(const char *host, unsigned port) argv[5] = NULL; BB_EXECVP(argv[0], argv); xmove_fd(3, 2); +# if ENABLE_FEATURE_WGET_SSL_HELPER + child_failed = 1; + xfunc_die(); +# else bb_perror_msg_and_die("can't execute '%s'", argv[0]); +# endif /* notreached */ } /* Parent */ free(allocated); close(sp[1]); +# if ENABLE_FEATURE_WGET_SSL_HELPER + if (child_failed) { + close(sp[0]); + return -1; + } +# endif return sp[0]; } #endif /* See networking/ssl_helper/README how to build one */ #if ENABLE_FEATURE_WGET_SSL_HELPER -static void spawn_https_helper(int network_fd) +static void spawn_https_helper_small(int network_fd) { int sp[2]; int pid; @@ -935,20 +949,36 @@ static void download_one_url(const char *url) /* Open socket to http(s) server */ #if ENABLE_FEATURE_WGET_OPENSSL + /* openssl (and maybe ssl_helper) support is configured */ if (target.protocol == P_HTTPS) { /* openssl-based helper * Inconvenient API since we can't give it an open fd */ - int fd = spawn_https_helper(server.host, server.port); + int fd = spawn_https_helper_openssl(server.host, server.port); +# if ENABLE_FEATURE_WGET_SSL_HELPER + if (fd < 0) { /* no openssl? try ssl_helper */ + sfp = open_socket(lsa); + spawn_https_helper_small(fileno(sfp)); + goto socket_opened; + } +# else + /* We don't check for exec("openssl") failure in this case */ +# endif sfp = fdopen(fd, "r+"); if (!sfp) bb_perror_msg_and_die(bb_msg_memory_exhausted); - } else -#endif - sfp = open_socket(lsa); -#if ENABLE_FEATURE_WGET_SSL_HELPER + goto socket_opened; + } + sfp = open_socket(lsa); + socket_opened: +#elif ENABLE_FEATURE_WGET_SSL_HELPER + /* Only ssl_helper support is configured */ + sfp = open_socket(lsa); if (target.protocol == P_HTTPS) - spawn_https_helper(fileno(sfp)); + spawn_https_helper_small(fileno(sfp)); +#else + /* ssl (https) support is not configured */ + sfp = open_socket(lsa); #endif /* Send HTTP request */ if (use_proxy) { -- cgit v1.2.3-55-g6feb From 9c5410023a9d1920c336ed4d9ceaad586ce43328 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko <vda.linux@googlemail.com> Date: Wed, 7 Oct 2015 15:44:36 +0200 Subject: ash: a bunch of trivial simplifications Also, in a few places made code more reliable wrt large sizeof(int) and sizeof(arith_t).. function old new delta sprint_status48 - 143 +143 newline_and_flush - 56 +56 showjob 365 382 +17 parse_command 1440 1443 +3 cmdputs 334 332 -2 cmdloop 434 429 -5 showjobs 70 64 -6 fg_bgcmd 296 290 -6 ash_vmsg 159 153 -6 ash_main 1487 1481 -6 jobscmd 94 82 -12 getoptscmd 687 632 -55 outcslow 56 - -56 sprint_status 156 - -156 ------------------------------------------------------------------------------ (add/remove: 2/2 grow/shrink: 2/8 up/down: 219/-310) Total: -91 bytes Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com> --- shell/ash.c | 72 +++++++++++++++++++++++++++++++------------------------------ 1 file changed, 37 insertions(+), 35 deletions(-) diff --git a/shell/ash.c b/shell/ash.c index 42c91257e..b34dcc149 100644 --- a/shell/ash.c +++ b/shell/ash.c @@ -537,11 +537,12 @@ flush_stdout_stderr(void) INT_ON; } +/* Was called outcslow(c,FILE*), but c was always '\n' */ static void -outcslow(int c, FILE *dest) +newline_and_flush(FILE *dest) { INT_OFF; - putc(c, dest); + putc('\n', dest); fflush(dest); INT_ON; } @@ -1202,7 +1203,7 @@ ash_vmsg(const char *msg, va_list ap) fprintf(stderr, "line %d: ", startlinno); } vfprintf(stderr, msg, ap); - outcslow('\n', stderr); + newline_and_flush(stderr); } /* @@ -3336,6 +3337,7 @@ unaliascmd(int argc UNUSED_PARAM, char **argv UNUSED_PARAM) #define SHOW_ONLY_PGID 0x01 /* show only pgid (jobs -p) */ #define SHOW_PIDS 0x02 /* show individual pids, not just one line per job */ #define SHOW_CHANGED 0x04 /* only jobs whose state has changed */ +#define SHOW_STDERR 0x08 /* print to stderr (else stdout) */ /* * A job structure contains information about a job. A job is either a @@ -3850,7 +3852,7 @@ showpipe(struct job *jp /*, FILE *out*/) psend = jp->ps + jp->nprocs; for (ps = jp->ps + 1; ps < psend; ps++) printf(" | %s", ps->ps_cmd); - outcslow('\n', stdout); + newline_and_flush(stdout); flush_stdout_stderr(); } @@ -3910,7 +3912,7 @@ fg_bgcmd(int argc UNUSED_PARAM, char **argv) #endif static int -sprint_status(char *s, int status, int sigonly) +sprint_status48(char *s, int status, int sigonly) { int col; int st; @@ -3935,14 +3937,12 @@ sprint_status(char *s, int status, int sigonly) //TODO: use bbox's get_signame? strsignal adds ~600 bytes to text+rodata col = fmtstr(s, 32, strsignal(st)); if (WCOREDUMP(status)) { - col += fmtstr(s + col, 16, " (core dumped)"); + strcpy(s + col, " (core dumped)"); + col += sizeof(" (core dumped)")-1; } } else if (!sigonly) { st = WEXITSTATUS(status); - if (st) - col = fmtstr(s, 16, "Done(%d)", st); - else - col = fmtstr(s, 16, "Done"); + col = fmtstr(s, 16, (st ? "Done(%d)" : "Done"), st); } out: return col; @@ -4031,7 +4031,7 @@ dowait(int wait_flags, struct job *job) char s[48 + 1]; int len; - len = sprint_status(s, status, 1); + len = sprint_status48(s, status, 1); if (len) { s[len] = '\n'; s[len + 1] = '\0'; @@ -4052,13 +4052,14 @@ blocking_wait_with_raise_on_sig(void) #if JOBS static void -showjob(FILE *out, struct job *jp, int mode) +showjob(struct job *jp, int mode) { struct procstat *ps; struct procstat *psend; int col; int indent_col; - char s[80]; + char s[16 + 16 + 48]; + FILE *out = (mode & SHOW_STDERR ? stderr : stdout); ps = jp->ps; @@ -4088,7 +4089,7 @@ showjob(FILE *out, struct job *jp, int mode) int status = psend[-1].ps_status; if (jp->state == JOBSTOPPED) status = jp->stopstatus; - col += sprint_status(s + col, status, 0); + col += sprint_status48(s + col, status, 0); } /* By now, "[JOBID]* [maybe PID] STATUS" is printed */ @@ -4115,7 +4116,7 @@ showjob(FILE *out, struct job *jp, int mode) ps->ps_cmd ); } while (++ps != psend); - outcslow('\n', out); + newline_and_flush(out); jp->changed = 0; @@ -4130,7 +4131,7 @@ showjob(FILE *out, struct job *jp, int mode) * statuses have changed since the last call to showjobs. */ static void -showjobs(FILE *out, int mode) +showjobs(int mode) { struct job *jp; @@ -4142,7 +4143,7 @@ showjobs(FILE *out, int mode) for (jp = curjob; jp; jp = jp->prev_job) { if (!(mode & SHOW_CHANGED) || jp->changed) { - showjob(out, jp, mode); + showjob(jp, mode); } } } @@ -4163,10 +4164,10 @@ jobscmd(int argc UNUSED_PARAM, char **argv) argv = argptr; if (*argv) { do - showjob(stdout, getjob(*argv, 0), mode); + showjob(getjob(*argv, 0), mode); while (*++argv); } else { - showjobs(stdout, mode); + showjobs(mode); } return 0; @@ -5572,8 +5573,8 @@ cvtnum(arith_t num) { int len; - expdest = makestrspace(32, expdest); - len = fmtstr(expdest, 32, ARITH_FMT, num); + expdest = makestrspace(sizeof(arith_t)*3 + 2, expdest); + len = fmtstr(expdest, sizeof(arith_t)*3 + 2, ARITH_FMT, num); STADJUST(len, expdest); return len; } @@ -10352,9 +10353,11 @@ getopts(char *optstr, char *optvar, char **optfirst, int *param_optind, int *opt char c = '?'; int done = 0; int err = 0; - char s[12]; + char sbuf[2]; char **optnext; + sbuf[1] = '\0'; + if (*param_optind < 1) return 1; optnext = optfirst + *param_optind - 1; @@ -10381,9 +10384,9 @@ getopts(char *optstr, char *optvar, char **optfirst, int *param_optind, int *opt for (q = optstr; *q != c;) { if (*q == '\0') { if (optstr[0] == ':') { - s[0] = c; - s[1] = '\0'; - err |= setvarsafe("OPTARG", s, 0); + sbuf[0] = c; + /*sbuf[1] = '\0'; - already is */ + err |= setvarsafe("OPTARG", sbuf, 0); } else { fprintf(stderr, "Illegal option -%c\n", c); unsetvar("OPTARG"); @@ -10398,9 +10401,9 @@ getopts(char *optstr, char *optvar, char **optfirst, int *param_optind, int *opt if (*++q == ':') { if (*p == '\0' && (p = *optnext) == NULL) { if (optstr[0] == ':') { - s[0] = c; - s[1] = '\0'; - err |= setvarsafe("OPTARG", s, 0); + sbuf[0] = c; + /*sbuf[1] = '\0'; - already is */ + err |= setvarsafe("OPTARG", sbuf, 0); c = ':'; } else { fprintf(stderr, "No arg for -%c option\n", c); @@ -10419,11 +10422,10 @@ getopts(char *optstr, char *optvar, char **optfirst, int *param_optind, int *opt out: *optoff = p ? p - *(optnext - 1) : -1; *param_optind = optnext - optfirst + 1; - fmtstr(s, sizeof(s), "%d", *param_optind); - err |= setvarsafe("OPTIND", s, VNOFUNC); - s[0] = c; - s[1] = '\0'; - err |= setvarsafe(optvar, s, 0); + err |= setvarsafe("OPTIND", itoa(*param_optind), VNOFUNC); + sbuf[0] = c; + /*sbuf[1] = '\0'; - already is */ + err |= setvarsafe(optvar, sbuf, 0); if (err) { *param_optind = 1; *optoff = -1; @@ -12119,7 +12121,7 @@ cmdloop(int top) setstackmark(&smark); #if JOBS if (doing_jobctl) - showjobs(stderr, SHOW_CHANGED); + showjobs(SHOW_CHANGED|SHOW_STDERR); #endif inter = 0; if (iflag && top) { @@ -13143,7 +13145,7 @@ int ash_main(int argc UNUSED_PARAM, char **argv) exitshell(); } if (e == EXINT) { - outcslow('\n', stderr); + newline_and_flush(stderr); } popstackmark(&smark); -- cgit v1.2.3-55-g6feb From 6283f9828320ef5e0be0b060b7f26522b529ed42 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko <vda.linux@googlemail.com> Date: Wed, 7 Oct 2015 16:56:20 +0200 Subject: hush: fix umask: umask(022) was setting umask(755) Based on the patch by Rich Felker <dalias@libc.org> function old new delta builtin_umask 121 161 +40 umaskcmd 318 279 -39 Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com> --- shell/ash.c | 36 ++++++++++++++---------------------- shell/hush.c | 10 +++++++--- 2 files changed, 21 insertions(+), 25 deletions(-) diff --git a/shell/ash.c b/shell/ash.c index b34dcc149..2669157bc 100644 --- a/shell/ash.c +++ b/shell/ash.c @@ -12814,7 +12814,7 @@ readcmd(int argc UNUSED_PARAM, char **argv UNUSED_PARAM) } static int FAST_FUNC -umaskcmd(int argc UNUSED_PARAM, char **argv) +umaskcmd(int argc UNUSED_PARAM, char **argv UNUSED_PARAM) { static const char permuser[3] ALIGN1 = "ugo"; static const char permmode[3] ALIGN1 = "rwx"; @@ -12824,9 +12824,6 @@ umaskcmd(int argc UNUSED_PARAM, char **argv) S_IROTH, S_IWOTH, S_IXOTH }; - /* TODO: use bb_parse_mode() instead */ - - char *ap; mode_t mask; int i; int symbolic_mode = 0; @@ -12840,8 +12837,7 @@ umaskcmd(int argc UNUSED_PARAM, char **argv) umask(mask); INT_ON; - ap = *argptr; - if (ap == NULL) { + if (*argptr == NULL) { if (symbolic_mode) { char buf[18]; char *p = buf; @@ -12858,27 +12854,23 @@ umaskcmd(int argc UNUSED_PARAM, char **argv) } *p++ = ','; } - *--p = 0; + *--p = '\0'; puts(buf); } else { out1fmt("%.4o\n", mask); } } else { - if (isdigit((unsigned char) *ap)) { - mask = 0; - do { - if (*ap >= '8' || *ap < '0') - ash_msg_and_raise_error(msg_illnum, argv[1]); - mask = (mask << 3) + (*ap - '0'); - } while (*++ap != '\0'); - umask(mask); - } else { - mask = ~mask & 0777; - if (!bb_parse_mode(ap, &mask)) { - ash_msg_and_raise_error("illegal mode: %s", ap); - } - umask(~mask & 0777); - } + char *modestr = *argptr; + /* numeric umasks are taken as-is */ + /* symbolic umasks are inverted: "umask a=rx" calls umask(222) */ + if (!isdigit(modestr[0])) + mask ^= 0777; + if (!bb_parse_mode(modestr, &mask) || (unsigned)mask > 0777) { + ash_msg_and_raise_error("illegal mode: %s", modestr); + } + if (!isdigit(modestr[0])) + mask ^= 0777; + umask(mask); } return 0; } diff --git a/shell/hush.c b/shell/hush.c index 752080a64..8b8d5fc8b 100644 --- a/shell/hush.c +++ b/shell/hush.c @@ -8970,10 +8970,14 @@ static int FAST_FUNC builtin_umask(char **argv) if (argv[0]) { mode_t old_mask = mask; - mask ^= 0777; + /* numeric umasks are taken as-is */ + /* symbolic umasks are inverted: "umask a=rx" calls umask(222) */ + if (!isdigit(argv[0][0])) + mask ^= 0777; rc = bb_parse_mode(argv[0], &mask); - mask ^= 0777; - if (rc == 0) { + if (!isdigit(argv[0][0])) + mask ^= 0777; + if (rc == 0 || (unsigned)mask > 0777) { mask = old_mask; /* bash messages: * bash: umask: 'q': invalid symbolic mode operator -- cgit v1.2.3-55-g6feb From c1e2e005b4e99070f58a3545bad54ef41a634ad1 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko <vda.linux@googlemail.com> Date: Wed, 7 Oct 2015 17:32:56 +0200 Subject: ash: shrink "umask -S" code function old new delta umaskcmd 279 286 +7 static.permmode 3 - -3 static.permmask 18 - -18 Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com> --- shell/ash.c | 31 ++++++++++++++----------------- 1 file changed, 14 insertions(+), 17 deletions(-) diff --git a/shell/ash.c b/shell/ash.c index 2669157bc..80dfc1d6a 100644 --- a/shell/ash.c +++ b/shell/ash.c @@ -12816,16 +12816,9 @@ readcmd(int argc UNUSED_PARAM, char **argv UNUSED_PARAM) static int FAST_FUNC umaskcmd(int argc UNUSED_PARAM, char **argv UNUSED_PARAM) { - static const char permuser[3] ALIGN1 = "ugo"; - static const char permmode[3] ALIGN1 = "rwx"; - static const short permmask[] ALIGN2 = { - S_IRUSR, S_IWUSR, S_IXUSR, - S_IRGRP, S_IWGRP, S_IXGRP, - S_IROTH, S_IWOTH, S_IXOTH - }; + static const char permuser[3] ALIGN1 = "ogu"; mode_t mask; - int i; int symbolic_mode = 0; while (nextopt("S") != '\0') { @@ -12839,22 +12832,26 @@ umaskcmd(int argc UNUSED_PARAM, char **argv UNUSED_PARAM) if (*argptr == NULL) { if (symbolic_mode) { - char buf[18]; + char buf[sizeof("u=rwx,g=rwx,o=rwx")]; char *p = buf; + int i; - for (i = 0; i < 3; i++) { - int j; + i = 2; + for (;;) { + unsigned bits; *p++ = permuser[i]; *p++ = '='; - for (j = 0; j < 3; j++) { - if ((mask & permmask[3 * i + j]) == 0) { - *p++ = permmode[j]; - } - } + /* mask is 0..0uuugggooo. i=2 selects uuu bits */ + bits = (mask >> (i*3)); + if (!(bits & 4)) *p++ = 'r'; + if (!(bits & 2)) *p++ = 'w'; + if (!(bits & 1)) *p++ = 'x'; + if (--i < 0) + break; *p++ = ','; } - *--p = '\0'; + *p = '\0'; puts(buf); } else { out1fmt("%.4o\n", mask); -- cgit v1.2.3-55-g6feb From 5711a2a4ad51ad203a2ed4ffc72593e83920b36a Mon Sep 17 00:00:00 2001 From: Denys Vlasenko <vda.linux@googlemail.com> Date: Wed, 7 Oct 2015 17:55:33 +0200 Subject: libbb: more compact API for bb_parse_mode() function old new delta make_device 2182 2188 +6 parse_command 1440 1443 +3 parse_params 1497 1499 +2 install_main 773 769 -4 mkdir_main 168 160 -8 getoptscmd 641 632 -9 builtin_umask 158 147 -11 bb_parse_mode 431 410 -21 umaskcmd 286 258 -28 ------------------------------------------------------------------------------ (add/remove: 0/0 grow/shrink: 3/6 up/down: 11/-81) Total: -70 bytes Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com> --- coreutils/chmod.c | 4 ++-- coreutils/install.c | 2 +- coreutils/libcoreutils/getopt_mk_fifo_nod.c | 4 +++- coreutils/mkdir.c | 4 ++-- findutils/find.c | 3 ++- include/libbb.h | 3 ++- libbb/parse_mode.c | 16 +++++++--------- shell/ash.c | 3 ++- shell/hush.c | 7 ++++--- util-linux/mdev.c | 2 +- 10 files changed, 26 insertions(+), 22 deletions(-) diff --git a/coreutils/chmod.c b/coreutils/chmod.c index 5ee45b942..a21c6d501 100644 --- a/coreutils/chmod.c +++ b/coreutils/chmod.c @@ -69,9 +69,9 @@ static int FAST_FUNC fileAction(const char *fileName, struct stat *statbuf, void if (S_ISLNK(statbuf->st_mode)) return TRUE; } - newmode = statbuf->st_mode; - if (!bb_parse_mode((char *)param, &newmode)) + newmode = bb_parse_mode((char *)param, statbuf->st_mode); + if (newmode == (mode_t)-1) bb_error_msg_and_die("invalid mode '%s'", (char *)param); if (chmod(fileName, newmode) == 0) { diff --git a/coreutils/install.c b/coreutils/install.c index 73f9c70d5..8aa51cc34 100644 --- a/coreutils/install.c +++ b/coreutils/install.c @@ -159,7 +159,7 @@ int install_main(int argc, char **argv) } mode = 0755; /* GNU coreutils 6.10 compat */ if (opts & OPT_MODE) - bb_parse_mode(mode_str, &mode); + mode = bb_parse_mode(mode_str, mode); uid = (opts & OPT_OWNER) ? get_ug_id(uid_str, xuname2uid) : getuid(); gid = (opts & OPT_GROUP) ? get_ug_id(gid_str, xgroup2gid) : getgid(); diff --git a/coreutils/libcoreutils/getopt_mk_fifo_nod.c b/coreutils/libcoreutils/getopt_mk_fifo_nod.c index 222717149..47375ff91 100644 --- a/coreutils/libcoreutils/getopt_mk_fifo_nod.c +++ b/coreutils/libcoreutils/getopt_mk_fifo_nod.c @@ -33,7 +33,9 @@ mode_t FAST_FUNC getopt_mk_fifo_nod(char **argv) int opt; opt = getopt32(argv, "m:" IF_SELINUX("Z:"), &smode IF_SELINUX(,&scontext)); if (opt & 1) { - if (bb_parse_mode(smode, &mode)) + mode = bb_parse_mode(smode, mode); + if (mode != (mode_t)-1) /* if mode is valid */ + /* make future mknod/mkfifo set mode bits exactly */ umask(0); } diff --git a/coreutils/mkdir.c b/coreutils/mkdir.c index 864edfb0a..6f7b004dd 100644 --- a/coreutils/mkdir.c +++ b/coreutils/mkdir.c @@ -71,8 +71,8 @@ int mkdir_main(int argc UNUSED_PARAM, char **argv) #endif opt = getopt32(argv, "m:pv" IF_SELINUX("Z:"), &smode IF_SELINUX(,&scontext)); if (opt & 1) { - mode_t mmode = 0777; - if (!bb_parse_mode(smode, &mmode)) { + mode_t mmode = bb_parse_mode(smode, 0777); + if (mmode == (mode_t)-1) { bb_error_msg_and_die("invalid mode '%s'", smode); } mode = mmode; diff --git a/findutils/find.c b/findutils/find.c index ced8922e7..f72cad7d1 100644 --- a/findutils/find.c +++ b/findutils/find.c @@ -1261,7 +1261,8 @@ static action*** parse_params(char **argv) ap->perm_char = arg1[0]; arg1 = (arg1[0] == '/' ? arg1+1 : plus_minus_num(arg1)); /*ap->perm_mask = 0; - ALLOC_ACTION did it */ - if (!bb_parse_mode(arg1, &ap->perm_mask)) + ap->perm_mask = bb_parse_mode(arg1, ap->perm_mask); + if (ap->perm_mask == (mode_t)-1) bb_error_msg_and_die("invalid mode '%s'", arg1); } #endif diff --git a/include/libbb.h b/include/libbb.h index 543214ea4..d79843a2d 100644 --- a/include/libbb.h +++ b/include/libbb.h @@ -1251,7 +1251,8 @@ char *bb_ask_stdin(const char * prompt) FAST_FUNC; char *bb_ask(const int fd, int timeout, const char * prompt) FAST_FUNC; int bb_ask_confirmation(void) FAST_FUNC; -int bb_parse_mode(const char* s, mode_t* theMode) FAST_FUNC; +/* Returns -1 if input is invalid. current_mode is a base for e.g. "u+rw" */ +int bb_parse_mode(const char* s, unsigned cur_mode) FAST_FUNC; /* * Config file parser diff --git a/libbb/parse_mode.c b/libbb/parse_mode.c index 5a4e1c579..bddd39bca 100644 --- a/libbb/parse_mode.c +++ b/libbb/parse_mode.c @@ -15,7 +15,7 @@ #define FILEMODEBITS (S_ISUID | S_ISGID | S_ISVTX | S_IRWXU | S_IRWXG | S_IRWXO) -int FAST_FUNC bb_parse_mode(const char *s, mode_t *current_mode) +int FAST_FUNC bb_parse_mode(const char *s, unsigned current_mode) { static const mode_t who_mask[] = { S_ISUID | S_ISGID | S_ISVTX | S_IRWXU | S_IRWXG | S_IRWXO, /* a */ @@ -46,13 +46,12 @@ int FAST_FUNC bb_parse_mode(const char *s, mode_t *current_mode) tmp = strtoul(s, &e, 8); if (*e || (tmp > 07777U)) { /* Check range and trailing chars. */ - return 0; + return -1; } - *current_mode = tmp; - return 1; + return tmp; } - new_mode = *current_mode; + new_mode = current_mode; /* Note: we allow empty clauses, and hence empty modes. * We treat an empty mode as no change to perms. */ @@ -71,7 +70,7 @@ int FAST_FUNC bb_parse_mode(const char *s, mode_t *current_mode) if (*p == *s) { wholist |= who_mask[(int)(p-who_chars)]; if (!*++s) { - return 0; + return -1; } goto WHO_LIST; } @@ -80,7 +79,7 @@ int FAST_FUNC bb_parse_mode(const char *s, mode_t *current_mode) do { /* Process action list. */ if ((*s != '+') && (*s != '-')) { if (*s != '=') { - return 0; + return -1; } /* Since op is '=', clear all bits corresponding to the * wholist, or all file bits if wholist is empty. */ @@ -145,6 +144,5 @@ int FAST_FUNC bb_parse_mode(const char *s, mode_t *current_mode) } while (*s && (*s != ',')); } - *current_mode = new_mode; - return 1; + return new_mode; } diff --git a/shell/ash.c b/shell/ash.c index 80dfc1d6a..ab8ec006f 100644 --- a/shell/ash.c +++ b/shell/ash.c @@ -12862,7 +12862,8 @@ umaskcmd(int argc UNUSED_PARAM, char **argv UNUSED_PARAM) /* symbolic umasks are inverted: "umask a=rx" calls umask(222) */ if (!isdigit(modestr[0])) mask ^= 0777; - if (!bb_parse_mode(modestr, &mask) || (unsigned)mask > 0777) { + mask = bb_parse_mode(modestr, mask); + if ((unsigned)mask > 0777) { ash_msg_and_raise_error("illegal mode: %s", modestr); } if (!isdigit(modestr[0])) diff --git a/shell/hush.c b/shell/hush.c index 8b8d5fc8b..bccd9c1e9 100644 --- a/shell/hush.c +++ b/shell/hush.c @@ -8965,6 +8965,7 @@ static int FAST_FUNC builtin_umask(char **argv) int rc; mode_t mask; + rc = 1; mask = umask(0); argv = skip_dash_dash(argv); if (argv[0]) { @@ -8974,19 +8975,19 @@ static int FAST_FUNC builtin_umask(char **argv) /* symbolic umasks are inverted: "umask a=rx" calls umask(222) */ if (!isdigit(argv[0][0])) mask ^= 0777; - rc = bb_parse_mode(argv[0], &mask); + mask = bb_parse_mode(argv[0], mask); if (!isdigit(argv[0][0])) mask ^= 0777; - if (rc == 0 || (unsigned)mask > 0777) { + if ((unsigned)mask > 0777) { mask = old_mask; /* bash messages: * bash: umask: 'q': invalid symbolic mode operator * bash: umask: 999: octal number out of range */ bb_error_msg("%s: invalid mode '%s'", "umask", argv[0]); + rc = 0; } } else { - rc = 1; /* Mimic bash */ printf("%04o\n", (unsigned) mask); /* fall through and restore mask which we set to 0 */ diff --git a/util-linux/mdev.c b/util-linux/mdev.c index 662e8ab38..51781d597 100644 --- a/util-linux/mdev.c +++ b/util-linux/mdev.c @@ -406,7 +406,7 @@ static void parse_next_rule(void) } /* 3rd field: mode - device permissions */ - bb_parse_mode(tokens[2], &G.cur_rule.mode); + G.cur_rule.mode = bb_parse_mode(tokens[2], G.cur_rule.mode); /* 4th field (opt): ">|=alias" or "!" to not create the node */ val = tokens[3]; -- cgit v1.2.3-55-g6feb From ec046f74a31e4315f4546ec5602f56e7d467082d Mon Sep 17 00:00:00 2001 From: Denys Vlasenko <vda.linux@googlemail.com> Date: Wed, 7 Oct 2015 17:57:53 +0200 Subject: ash: use a more typical form of "print four octal digits" format Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com> --- shell/ash.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/shell/ash.c b/shell/ash.c index ab8ec006f..b835415b5 100644 --- a/shell/ash.c +++ b/shell/ash.c @@ -12854,7 +12854,7 @@ umaskcmd(int argc UNUSED_PARAM, char **argv UNUSED_PARAM) *p = '\0'; puts(buf); } else { - out1fmt("%.4o\n", mask); + out1fmt("%04o\n", mask); } } else { char *modestr = *argptr; -- cgit v1.2.3-55-g6feb From 305958dbd456d463a92c1fa4c85ceb69a8c7db32 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko <vda.linux@googlemail.com> Date: Wed, 7 Oct 2015 19:17:01 +0200 Subject: md5sum: code shrink For CONFIG_MD5_SMALL=1: function old new delta md5_process_block64 925 881 -44 For CONFIG_MD5_SMALL=0: function old new delta md5_process_block64 1603 1586 -17 Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com> --- libbb/hash_md5_sha.c | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) diff --git a/libbb/hash_md5_sha.c b/libbb/hash_md5_sha.c index 1f63ccdee..d08c6b2f7 100644 --- a/libbb/hash_md5_sha.c +++ b/libbb/hash_md5_sha.c @@ -137,7 +137,7 @@ static void FAST_FUNC md5_process_block64(md5_ctx_t *ctx) #if MD5_SMALL > 0 /* Before we start, one word to the strange constants. They are defined in RFC 1321 as - T[i] = (int)(4294967296.0 * fabs(sin(i))), i=1..64 + T[i] = (int)(2^32 * fabs(sin(i))), i=1..64 */ static const uint32_t C_array[] = { /* round 1 */ @@ -213,7 +213,7 @@ static void FAST_FUNC md5_process_block64(md5_ctx_t *ctx) case 2: temp += FH(B, C, D); break; - case 3: + default: /* case 3 */ temp += FI(B, C, D); } temp += words[(int) (*pp++)] + *pc++; @@ -277,10 +277,6 @@ static void FAST_FUNC md5_process_block64(md5_ctx_t *ctx) #else /* MD5_SMALL == 0 or 1 */ - uint32_t A_save = A; - uint32_t B_save = B; - uint32_t C_save = C; - uint32_t D_save = D; # if MD5_SMALL == 1 const uint32_t *pc; const char *pp; @@ -425,10 +421,10 @@ static void FAST_FUNC md5_process_block64(md5_ctx_t *ctx) # undef OP # endif /* Add checksum to the starting values */ - ctx->hash[0] = A_save + A; - ctx->hash[1] = B_save + B; - ctx->hash[2] = C_save + C; - ctx->hash[3] = D_save + D; + ctx->hash[0] += A; + ctx->hash[1] += B; + ctx->hash[2] += C; + ctx->hash[3] += D; #endif } #undef FF -- cgit v1.2.3-55-g6feb From 8c0708a329618b20089eb9cedbe06522dd25d9be Mon Sep 17 00:00:00 2001 From: Denys Vlasenko <vda.linux@googlemail.com> Date: Wed, 7 Oct 2015 21:01:47 +0200 Subject: find: support "find . -delete" idiom - do not try rmdir(".") Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com> --- findutils/find.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/findutils/find.c b/findutils/find.c index f72cad7d1..bd7ccc323 100644 --- a/findutils/find.c +++ b/findutils/find.c @@ -768,7 +768,10 @@ ACTF(delete) { int rc; if (S_ISDIR(statbuf->st_mode)) { - rc = rmdir(fileName); + /* "find . -delete" skips rmdir(".") */ + rc = 0; + if (NOT_LONE_CHAR(fileName, '.')) + rc = rmdir(fileName); } else { rc = unlink(fileName); } -- cgit v1.2.3-55-g6feb From d60752f8c9be5689a249ad518deb38061d4bc45e Mon Sep 17 00:00:00 2001 From: Denys Vlasenko <vda.linux@googlemail.com> Date: Wed, 7 Oct 2015 22:42:45 +0200 Subject: build system: -fno-builtin-printf Benefits are: drops reference to out-of-line putchar(), fixes a few cases of failed string merge. function old new delta i2cdump_main 1488 1502 +14 sha256_process_block64 423 433 +10 sendmail_main 1183 1185 +2 list_table 1114 1116 +2 i2cdetect_main 1235 1237 +2 fdisk_main 2852 2854 +2 builtin_type 119 121 +2 unicode_conv_to_printable2 325 324 -1 scan_recursive 380 378 -2 mkfs_minix_main 2687 2684 -3 buffer_fill_and_print 178 169 -9 putchar 152 - -152 ------------------------------------------------------------------------------ (add/remove: 0/2 grow/shrink: 7/4 up/down: 34/-167) Total: -133 bytes text data bss dec hex filename 937788 932 17676 956396 e97ec busybox_old 937564 932 17676 956172 e970c busybox_unstripped Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com> --- Makefile.flags | 3 ++ coreutils/uniq.c | 2 +- coreutils/who.c | 2 +- editors/diff.c | 4 +- editors/ed.c | 2 +- loginutils/add-remove-shell.c | 4 +- mailutils/mail.c | 2 +- mailutils/sendmail.c | 2 +- miscutils/hdparm.c | 58 +++++++++++++------------- miscutils/i2c_tools.c | 26 ++++++------ networking/arping.c | 2 +- networking/brctl.c | 4 +- printutils/lpd.c | 8 ++-- procps/iostat.c | 2 +- procps/powertop.c | 2 +- shell/ash.c | 2 +- shell/hush.c | 2 +- shell/shell_common.c | 2 +- util-linux/fdformat.c | 4 +- util-linux/fdisk.c | 94 +++++++++++++++++++++---------------------- util-linux/fdisk_gpt.c | 4 +- util-linux/fsck_minix.c | 16 ++++---- util-linux/getopt.c | 2 +- util-linux/ipcrm.c | 2 +- 24 files changed, 127 insertions(+), 124 deletions(-) diff --git a/Makefile.flags b/Makefile.flags index 2bc83d1d9..b6cd32e42 100644 --- a/Makefile.flags +++ b/Makefile.flags @@ -56,6 +56,9 @@ CFLAGS += $(call cc-option,-falign-functions=1 -falign-jumps=1 -falign-labels=1 # Defeat .eh_frame bloat (gcc 4.6.3 x86-32 defconfig: 20% smaller busybox binary): CFLAGS += $(call cc-option,-fno-unwind-tables,) CFLAGS += $(call cc-option,-fno-asynchronous-unwind-tables,) +# No automatic printf->puts,putchar conversions +# (try disabling this and comparing assembly, it's instructive) +CFLAGS += $(call cc-option,-fno-builtin-printf,) # FIXME: These warnings are at least partially to be concerned about and should # be fixed.. diff --git a/coreutils/uniq.c b/coreutils/uniq.c index 9208d34ec..e0133998a 100644 --- a/coreutils/uniq.c +++ b/coreutils/uniq.c @@ -112,7 +112,7 @@ int uniq_main(int argc UNUSED_PARAM, char **argv) /* %7lu matches GNU coreutils 6.9 */ printf("%7lu ", dups + 1); } - printf("%s\n", old_line); + puts(old_line); } free(old_line); } diff --git a/coreutils/who.c b/coreutils/who.c index 8337212c9..f694d0c60 100644 --- a/coreutils/who.c +++ b/coreutils/who.c @@ -81,7 +81,7 @@ int who_main(int argc UNUSED_PARAM, char **argv) opt_complementary = "=0"; opt = getopt32(argv, do_users ? "" : "aH"); if (opt & 2) // -H - printf("USER\t\tTTY\t\tIDLE\tTIME\t\t HOST\n"); + puts("USER\t\tTTY\t\tIDLE\tTIME\t\t HOST"); setutxent(); while ((ut = getutxent()) != NULL) { diff --git a/editors/diff.c b/editors/diff.c index e0adcee59..a892cfdf2 100644 --- a/editors/diff.c +++ b/editors/diff.c @@ -433,7 +433,7 @@ static void fetch(FILE_and_pos_t *ft, const off_t *ix, int a, int b, int ch) for (j = 0, col = 0; j < ix[i] - ix[i - 1]; j++) { int c = fgetc(ft->ft_fp); if (c == EOF) { - printf("\n\\ No newline at end of file\n"); + puts("\n\\ No newline at end of file"); return; } ft->ft_pos++; @@ -692,7 +692,7 @@ static bool diff(FILE* fp[2], char *file[2]) continue; printf(",%d", (a < b) ? b - a + 1 : 0); } - printf(" @@\n"); + puts(" @@"); /* * Output changes in "unified" diff format--the old and new lines * are printed together. diff --git a/editors/ed.c b/editors/ed.c index f0e5e4d5d..a4c419099 100644 --- a/editors/ed.c +++ b/editors/ed.c @@ -206,7 +206,7 @@ static void doCommands(void) if (fileName) printf("\"%s\"\n", fileName); else - printf("No file name\n"); + puts("No file name"); break; } free(fileName); diff --git a/loginutils/add-remove-shell.c b/loginutils/add-remove-shell.c index e492b6e5a..9419ff5e7 100644 --- a/loginutils/add-remove-shell.c +++ b/loginutils/add-remove-shell.c @@ -100,7 +100,7 @@ int add_remove_shell_main(int argc UNUSED_PARAM, char **argv) cpp++; } /* copy shell name from old to new file */ - printf("%s\n", line); + puts(line); next_line: free(line); } @@ -112,7 +112,7 @@ int add_remove_shell_main(int argc UNUSED_PARAM, char **argv) char **cpp = argv; while (*cpp) { if (*cpp != dont_add) - printf("%s\n", *cpp); + puts(*cpp); cpp++; } } diff --git a/mailutils/mail.c b/mailutils/mail.c index 199f64407..a7e43c0d1 100644 --- a/mailutils/mail.c +++ b/mailutils/mail.c @@ -154,7 +154,7 @@ void FAST_FUNC encode_base64(char *fname, const char *text, const char *eol) // encode the buffer we just read in bb_uuencode(dst_buf, src_buf, size, bb_uuenc_tbl_base64); if (fname) { - printf("%s\n", eol); + puts(eol); } else { src_buf += size; len -= size; diff --git a/mailutils/sendmail.c b/mailutils/sendmail.c index 9455b4e7a..4355e4dc5 100644 --- a/mailutils/sendmail.c +++ b/mailutils/sendmail.c @@ -375,7 +375,7 @@ int sendmail_main(int argc UNUSED_PARAM, char **argv) // N.B. we need to escape the leading dot regardless of // whether it is single or not character on the line if ('.' == s[0] /*&& '\0' == s[1] */) - printf("."); + bb_putchar('.'); // dump read line send_r_n(s); free(s); diff --git a/miscutils/hdparm.c b/miscutils/hdparm.c index f0e9c9d75..9c486e7aa 100644 --- a/miscutils/hdparm.c +++ b/miscutils/hdparm.c @@ -763,9 +763,9 @@ static void identify(uint16_t *val) ) { like_std = 5; if ((val[CONFIG]==STBY_NID_VAL) || (val[CONFIG]==STBY_ID_VAL)) - printf("powers-up in standby; SET FEATURES subcmd spins-up.\n"); + puts("powers-up in standby; SET FEATURES subcmd spins-up."); if (((val[CONFIG]==STBY_NID_VAL) || (val[CONFIG]==PWRD_NID_VAL)) && (val[GEN_CONFIG] & INCOMPLETE)) - printf("\n\tWARNING: ID response incomplete.\n\tFollowing data may be incorrect.\n\n"); + puts("\n\tWARNING: ID response incomplete.\n\tFollowing data may be incorrect.\n"); } /* output the model and serial numbers and the fw revision */ @@ -875,7 +875,7 @@ static void identify(uint16_t *val) if (min_std == 0xffff) min_std = like_std > 4 ? like_std - 3 : 1; - printf("Configuration:\n"); + puts("Configuration:"); /* more info from the general configuration word */ if ((eqpt != CDROM) && (like_std == 1)) { jj = val[GEN_CONFIG] >> 1; @@ -909,7 +909,7 @@ static void identify(uint16_t *val) mm = 0; bbbig = 0; if ((ll > 0x00FBFC10) && (!val[LCYLS])) - printf("\tCHS addressing not supported\n"); + puts("\tCHS addressing not supported"); else { jj = val[WHATS_VALID] & OK_W54_58; printf("\tLogical\t\tmax\tcurrent\n" @@ -980,7 +980,7 @@ static void identify(uint16_t *val) !(val[CAPAB_0] & IORDY_SUP) ? "(may be)" : "", (val[CAPAB_0] & IORDY_OFF) ? "" :"not"); } else - printf("no IORDY\n"); + puts("no IORDY"); if ((like_std == 1) && val[BUF_TYPE]) { printf("\tBuffer type: %04x: %s%s\n", val[BUF_TYPE], @@ -1012,13 +1012,13 @@ static void identify(uint16_t *val) } printf("\tR/W multiple sector transfer: "); if ((like_std < 3) && !(val[SECTOR_XFER_MAX] & SECTOR_XFER)) - printf("not supported\n"); + puts("not supported"); else { printf("Max = %u\tCurrent = ", val[SECTOR_XFER_MAX] & SECTOR_XFER); if (val[SECTOR_XFER_CUR] & MULTIPLE_SETTING_VALID) printf("%u\n", val[SECTOR_XFER_CUR] & SECTOR_XFER); else - printf("?\n"); + puts("?"); } if ((like_std > 3) && (val[CMDS_SUPP_1] & 0x0008)) { /* We print out elsewhere whether the APM feature is enabled or @@ -1040,7 +1040,7 @@ static void identify(uint16_t *val) } else { /* ATAPI */ if (eqpt != CDROM && (val[CAPAB_0] & SWRST_REQ)) - printf("\tATA sw reset required\n"); + puts("\tATA sw reset required"); if (val[PKT_REL] || val[SVC_NBSY]) { printf("\tOverlap support:"); @@ -1056,7 +1056,7 @@ static void identify(uint16_t *val) /* DMA stuff. Check that only one DMA mode is selected. */ printf("\tDMA: "); if (!(val[CAPAB_0] & DMA_SUP)) - printf("not supported\n"); + puts("not supported"); else { if (val[DMA_MODE] && !val[SINGLE_DMA] && !val[MULTI_DMA]) printf(" sdma%u\n", (val[DMA_MODE] & MODE) >> 8); @@ -1079,7 +1079,7 @@ static void identify(uint16_t *val) bb_putchar('\n'); if ((dev == ATAPI_DEV) && (eqpt != CDROM) && (val[CAPAB_0] & DMA_IL_SUP)) - printf("\t\tInterleaved DMA support\n"); + puts("\t\tInterleaved DMA support"); if ((val[WHATS_VALID] & OK_W64_70) && (val[DMA_TIME_MIN] || val[DMA_TIME_NORM]) @@ -1121,8 +1121,8 @@ static void identify(uint16_t *val) } if ((val[CMDS_SUPP_1] & VALID) == VALID_VAL) { - printf("Commands/features:\n" - "\tEnabled\tSupported:\n"); + puts("Commands/features:\n" + "\tEnabled\tSupported:"); jj = val[CMDS_SUPP_0]; kk = val[CMDS_EN_0]; for (ii = 0; ii < NUM_CMD_FEAT_STR; ii++) { @@ -1150,7 +1150,7 @@ static void identify(uint16_t *val) if ((eqpt != CDROM) && (like_std > 3) && (val[SECU_STATUS] || val[ERASE_TIME] || val[ENH_ERASE_TIME]) ) { - printf("Security:\n"); + puts("Security:"); if (val[PSWD_CODE] && (val[PSWD_CODE] != NOVAL_1)) printf("\tMaster password revision code = %u\n", val[PSWD_CODE]); jj = val[SECU_STATUS]; @@ -1366,7 +1366,7 @@ static NOINLINE void dump_identity(const struct hd_driveid *id) } } #endif /* __NEW_HD_DRIVE_ID */ - printf("\n\n * current active mode\n\n"); + puts("\n\n * current active mode\n"); } #endif @@ -1507,7 +1507,7 @@ static void bus_state_value(unsigned value) else if (value == BUSSTATE_OFF) on_off(0); else if (value == BUSSTATE_TRISTATE) - printf(" (tristate)\n"); + puts(" (tristate)"); else printf(" (unknown: %u)\n", value); } @@ -1531,7 +1531,7 @@ static void interpret_standby(uint8_t standby) printf("vendor-specific"); if (standby == 254) printf("reserved"); - printf(")\n"); + puts(")"); } static const uint8_t xfermode_val[] ALIGN1 = { @@ -1582,7 +1582,7 @@ static void interpret_xfermode(unsigned xfermode) printf("UltraDMA mode%u", xfermode - 64); else printf("unknown"); - printf(")\n"); + puts(")"); } #endif /* HDIO_DRIVE_CMD */ @@ -1633,7 +1633,7 @@ static void process_dev(char *devname) if (noisy_piomode) { printf(" attempting to "); if (piomode == 255) - printf("auto-tune PIO mode\n"); + puts("auto-tune PIO mode"); else if (piomode < 100) printf("set PIO mode to %d\n", piomode); else if (piomode < 200) @@ -1762,7 +1762,7 @@ static void process_dev(char *devname) #ifndef WIN_STANDBYNOW2 #define WIN_STANDBYNOW2 0x94 #endif - printf(" issuing standby command\n"); + puts(" issuing standby command"); args[0] = WIN_STANDBYNOW1; ioctl_alt_or_warn(HDIO_DRIVE_CMD, args, WIN_STANDBYNOW2); } @@ -1773,13 +1773,13 @@ static void process_dev(char *devname) #ifndef WIN_SLEEPNOW2 #define WIN_SLEEPNOW2 0x99 #endif - printf(" issuing sleep command\n"); + puts(" issuing sleep command"); args[0] = WIN_SLEEPNOW1; ioctl_alt_or_warn(HDIO_DRIVE_CMD, args, WIN_SLEEPNOW2); } if (set_seagate) { args[0] = 0xfb; - printf(" disabling Seagate auto powersaving mode\n"); + puts(" disabling Seagate auto powersaving mode"); ioctl_or_warn(fd, HDIO_DRIVE_CMD, &args); } if (getset_standby == IS_SET) { @@ -1815,17 +1815,17 @@ static void process_dev(char *devname) if (!ioctl_or_warn(fd, HDIO_GET_32BIT, &parm)) { printf(" IO_support\t=%3ld (", parm); if (parm == 0) - printf("default 16-bit)\n"); + puts("default 16-bit)"); else if (parm == 2) - printf("16-bit)\n"); + puts("16-bit)"); else if (parm == 1) - printf("32-bit)\n"); + puts("32-bit)"); else if (parm == 3) - printf("32-bit w/sync)\n"); + puts("32-bit w/sync)"); else if (parm == 8) - printf("Request-Queue-Bypass)\n"); + puts("Request-Queue-Bypass)"); else - printf("\?\?\?)\n"); + puts("\?\?\?)"); } } if (getset_unmask) { @@ -1837,7 +1837,7 @@ static void process_dev(char *devname) if (!ioctl_or_warn(fd, HDIO_GET_DMA, &parm)) { printf(fmt, "using_dma", parm); if (parm == 8) - printf(" (DMA-Assisted-PIO)\n"); + puts(" (DMA-Assisted-PIO)"); else on_off(parm != 0); } @@ -1921,7 +1921,7 @@ static void process_dev(char *devname) id.multsect_valid &= ~1; dump_identity(&id); } else if (errno == -ENOMSG) - printf(" no identification info available\n"); + puts(" no identification info available"); else if (ENABLE_IOCTL_HEX2STR_ERROR) /* To be coherent with ioctl_or_warn */ bb_perror_msg("HDIO_GET_IDENTITY"); else diff --git a/miscutils/i2c_tools.c b/miscutils/i2c_tools.c index 4b26b7bdc..292ff88dd 100644 --- a/miscutils/i2c_tools.c +++ b/miscutils/i2c_tools.c @@ -701,7 +701,7 @@ int i2cset_main(int argc, char **argv) } if (status < 0) { - printf("Warning - readback failed\n"); + puts("Warning - readback failed"); } else if (status != val) { printf("Warning - data mismatch - wrote " @@ -756,8 +756,8 @@ static void dump_data(int bus_fd, int mode, unsigned first, { int i, j, res; - printf(" 0 1 2 3 4 5 6 7 8 9 a b c d e f" - " 0123456789abcdef\n"); + puts(" 0 1 2 3 4 5 6 7 8 9 a b c d e f" + " 0123456789abcdef"); for (i = 0; i < I2CDUMP_NUM_REGS; i += 0x10) { if (mode == I2C_SMBUS_BLOCK_DATA && i >= blen) @@ -826,22 +826,22 @@ static void dump_data(int bus_fd, int mode, unsigned first, break; /* Skip unwanted registers */ if (i+j < first || i+j > last) { - printf(" "); + bb_putchar(' '); continue; } res = block[i+j]; if (res < 0) { - printf("X"); + bb_putchar('X'); } else if (res == 0x00 || res == 0xff) { - printf("."); + bb_putchar('.'); } else if (res < 32 || res >= 127) { - printf("?"); + bb_putchar('?'); } else { - printf("%c", res); + bb_putchar(res); } } - printf("\n"); + bb_putchar('\n'); } } @@ -850,7 +850,7 @@ static void dump_word_data(int bus_fd, unsigned first, unsigned last) int i, j, rv; /* Word data. */ - printf(" 0,8 1,9 2,a 3,b 4,c 5,d 6,e 7,f\n"); + puts(" 0,8 1,9 2,a 3,b 4,c 5,d 6,e 7,f"); for (i = 0; i < 256; i += 8) { if (i/8 < first/8) continue; @@ -871,7 +871,7 @@ static void dump_word_data(int bus_fd, unsigned first, unsigned last) else printf("%04x ", rv & 0xffff); } - printf("\n"); + bb_putchar('\n'); } } @@ -1267,7 +1267,7 @@ int i2cdetect_main(int argc UNUSED_PARAM, char **argv) if (!(opts & opt_y)) confirm_action(-1, -1, -1, 0); - printf(" 0 1 2 3 4 5 6 7 8 9 a b c d e f\n"); + 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++) { @@ -1325,7 +1325,7 @@ int i2cdetect_main(int argc UNUSED_PARAM, char **argv) else printf("%02x ", i+j); } - printf("\n"); + bb_putchar('\n'); } return 0; diff --git a/networking/arping.c b/networking/arping.c index ce7fa299c..ef205e5e6 100644 --- a/networking/arping.c +++ b/networking/arping.c @@ -249,7 +249,7 @@ static void recv_pack(unsigned char *buf, int len, struct sockaddr_ll *FROM) unsigned diff = MONOTONIC_US() - last; printf(" %u.%03ums\n", diff / 1000, diff % 1000); } else { - printf(" UNSOLICITED?\n"); + puts(" UNSOLICITED?"); } fflush_all(); } diff --git a/networking/brctl.c b/networking/brctl.c index 8043d600b..c01a86998 100644 --- a/networking/brctl.c +++ b/networking/brctl.c @@ -217,7 +217,7 @@ int brctl_main(int argc UNUSED_PARAM, char **argv) arm_ioctl(args, BRCTL_GET_BRIDGES, (unsigned long) bridx, MAX_PORTS); num = xioctl(fd, SIOCGIFBR, args); - printf("bridge name\tbridge id\t\tSTP enabled\tinterfaces\n"); + puts("bridge name\tbridge id\t\tSTP enabled\tinterfaces"); for (i = 0; i < num; i++) { char ifname[IFNAMSIZ]; int j, tabs; @@ -236,7 +236,7 @@ int brctl_main(int argc UNUSED_PARAM, char **argv) /* print bridge id */ x = (unsigned char *) &bi.bridge_id; for (j = 0; j < 8; j++) { - printf("%.2x", x[j]); + printf("%02x", x[j]); if (j == 1) bb_putchar('.'); } diff --git a/printutils/lpd.c b/printutils/lpd.c index eaf42c08b..c98bbb347 100644 --- a/printutils/lpd.c +++ b/printutils/lpd.c @@ -200,7 +200,7 @@ int lpd_main(int argc UNUSED_PARAM, char *argv[]) if (2 != s[0] && 3 != s[0]) goto unsupported_cmd; if (spooling & (1 << (s[0]-1))) { - printf("Duplicated subcommand\n"); + puts("Duplicated subcommand"); goto err_exit; } // get filename @@ -208,7 +208,7 @@ int lpd_main(int argc UNUSED_PARAM, char *argv[]) fname = strchr(s, ' '); if (!fname) { // bad_fname: - printf("No or bad filename\n"); + puts("No or bad filename"); goto err_exit; } *fname++ = '\0'; @@ -219,13 +219,13 @@ int lpd_main(int argc UNUSED_PARAM, char *argv[]) // get length expected_len = bb_strtou(s + 1, NULL, 10); if (errno || expected_len < 0) { - printf("Bad length\n"); + puts("Bad length"); goto err_exit; } if (2 == s[0] && expected_len > 16 * 1024) { // SECURITY: // ctrlfile can't be big (we want to read it back later!) - printf("File is too big\n"); + puts("File is too big"); goto err_exit; } diff --git a/procps/iostat.c b/procps/iostat.c index 8d272c87c..c290c594b 100644 --- a/procps/iostat.c +++ b/procps/iostat.c @@ -142,7 +142,7 @@ static void print_timestamp(void) /* %x: date representation for the current locale */ /* %X: time representation for the current locale */ strftime(buf, sizeof(buf), "%x %X", &G.tmtime); - printf("%s\n", buf); + puts(buf); } static cputime_t get_smp_uptime(void) diff --git a/procps/powertop.c b/procps/powertop.c index 1de5d329e..18418100f 100644 --- a/procps/powertop.c +++ b/procps/powertop.c @@ -704,7 +704,7 @@ int powertop_main(int UNUSED_PARAM argc, char UNUSED_PARAM **argv) /* Get number of CPUs */ G.total_cpus = get_cpu_count(); - printf("Collecting data for "DEFAULT_SLEEP_STR" seconds\n"); + puts("Collecting data for "DEFAULT_SLEEP_STR" seconds"); #if ENABLE_FEATURE_USE_TERMIOS tcgetattr(0, (void *)&G.init_settings); diff --git a/shell/ash.c b/shell/ash.c index b835415b5..7d20b8860 100644 --- a/shell/ash.c +++ b/shell/ash.c @@ -9681,7 +9681,7 @@ preadfd(void) } # if ENABLE_ASH_IDLE_TIMEOUT else if (errno == EAGAIN && timeout > 0) { - printf("\007timed out waiting for input: auto-logout\n"); + puts("\007timed out waiting for input: auto-logout"); exitshell(); } # endif diff --git a/shell/hush.c b/shell/hush.c index bccd9c1e9..f085ed3eb 100644 --- a/shell/hush.c +++ b/shell/hush.c @@ -6794,7 +6794,7 @@ static int checkjobs(struct pipe *fg_pipe) int sig = WTERMSIG(status); if (i == fg_pipe->num_cmds-1) /* TODO: use strsignal() instead for bash compat? but that's bloat... */ - printf("%s\n", sig == SIGINT || sig == SIGPIPE ? "" : get_signame(sig)); + puts(sig == SIGINT || sig == SIGPIPE ? "" : get_signame(sig)); /* TODO: if (WCOREDUMP(status)) + " (core dumped)"; */ /* TODO: MIPS has 128 sigs (1..128), what if sig==128 here? * Maybe we need to use sig | 128? */ diff --git a/shell/shell_common.c b/shell/shell_common.c index 2b6f7dc92..8c9607c8c 100644 --- a/shell/shell_common.c +++ b/shell/shell_common.c @@ -380,7 +380,7 @@ static void printlim(unsigned opts, const struct rlimit *limit, val = limit->rlim_cur; if (val == RLIM_INFINITY) - printf("unlimited\n"); + puts("unlimited"); else { val >>= l->factor_shift; printf("%llu\n", (long long) val); diff --git a/util-linux/fdformat.c b/util-linux/fdformat.c index 6f49cec8f..6ef6445e6 100644 --- a/util-linux/fdformat.c +++ b/util-linux/fdformat.c @@ -93,7 +93,7 @@ int fdformat_main(int argc UNUSED_PARAM, char **argv) } xioctl(fd, FDFMTEND, NULL); - printf("done\n"); + puts("Done"); /* VERIFY */ if (verify) { @@ -126,7 +126,7 @@ int fdformat_main(int argc UNUSED_PARAM, char **argv) if (ENABLE_FEATURE_CLEAN_UP) free(data); - printf("done\n"); + puts("Done"); } if (ENABLE_FEATURE_CLEAN_UP) close(fd); diff --git a/util-linux/fdisk.c b/util-linux/fdisk.c index 7fe70fb72..f49ce95a4 100644 --- a/util-linux/fdisk.c +++ b/util-linux/fdisk.c @@ -1102,11 +1102,11 @@ warn_geometry(void) printf(" sectors"); if (!g_cylinders) printf(" cylinders"); - printf( #if ENABLE_FEATURE_FDISK_WRITABLE - " (settable in the extra functions menu)" + puts(" (settable in the extra functions menu)"); +#else + bb_putchar('\n'); #endif - "\n"); return 1; } @@ -1150,7 +1150,7 @@ read_extended(int ext) p = pex->part_table; if (!get_start_sect(p)) { - printf("Bad offset in primary extended partition\n"); + puts("Bad offset in primary extended partition"); return; } @@ -1450,8 +1450,8 @@ static int get_boot(void) current_label_type = LABEL_OSF; return 0; } - printf("This disk has both DOS and BSD magic.\n" - "Give the 'b' command to go to BSD mode.\n"); + puts("This disk has both DOS and BSD magic.\n" + "Give the 'b' command to go to BSD mode."); } #endif @@ -1461,9 +1461,9 @@ static int get_boot(void) #else if (!valid_part_table_flag(MBRbuffer)) { if (what == OPEN_MAIN) { - printf("Device contains neither a valid DOS " - "partition table, nor Sun, SGI, OSF or GPT " - "disklabel\n"); + puts("Device contains neither a valid DOS " + "partition table, nor Sun, SGI, OSF or GPT " + "disklabel"); #ifdef __sparc__ IF_FEATURE_SUN_LABEL(create_sunlabel();) #else @@ -1596,7 +1596,7 @@ read_int(sector_t low, sector_t dflt, sector_t high, sector_t base, const char * } if (value >= low && value <= high) break; - printf("Value is out of range\n"); + puts("Value is out of range"); } return value; } @@ -1641,7 +1641,7 @@ get_existing_partition(int warn, unsigned max) printf("Selected partition %u\n", pno+1); return pno; } - printf("No partition is defined yet!\n"); + puts("No partition is defined yet!"); return -1; not_unique: @@ -1668,7 +1668,7 @@ get_nonexisting_partition(int warn, unsigned max) printf("Selected partition %u\n", pno+1); return pno; } - printf("All primary partitions have been defined already!\n"); + puts("All primary partitions have been defined already!"); return -1; not_unique: @@ -1703,10 +1703,10 @@ toggle_dos_compatibility_flag(void) dos_compatible_flag = 1 - dos_compatible_flag; if (dos_compatible_flag) { sector_offset = g_sectors; - printf("DOS Compatibility flag is set\n"); + printf("DOS Compatibility flag is %sset\n", ""); } else { sector_offset = 1; - printf("DOS Compatibility flag is not set\n"); + printf("DOS Compatibility flag is %sset\n", "not "); } } @@ -1813,16 +1813,16 @@ change_sysid(void) sys = read_hex(get_sys_types()); if (!sys && !LABEL_IS_SGI && !LABEL_IS_SUN) { - printf("Type 0 means free space to many systems\n" - "(but not to Linux). Having partitions of\n" - "type 0 is probably unwise.\n"); + puts("Type 0 means free space to many systems\n" + "(but not to Linux). Having partitions of\n" + "type 0 is probably unwise."); /* break; */ } if (!LABEL_IS_SUN && !LABEL_IS_SGI) { if (IS_EXTENDED(sys) != IS_EXTENDED(p->sys_ind)) { - printf("You cannot change a partition into" - " an extended one or vice versa\n"); + puts("You cannot change a partition into" + " an extended one or vice versa"); break; } } @@ -1830,10 +1830,10 @@ change_sysid(void) if (sys < 256) { #if ENABLE_FEATURE_SUN_LABEL if (LABEL_IS_SUN && i == 2 && sys != SUN_WHOLE_DISK) - printf("Consider leaving partition 3 " - "as Whole disk (5),\n" - "as SunOS/Solaris expects it and " - "even Linux likes it\n\n"); + puts("Consider leaving partition 3 " + "as Whole disk (5),\n" + "as SunOS/Solaris expects it and " + "even Linux likes it\n"); #endif #if ENABLE_FEATURE_SGI_LABEL if (LABEL_IS_SGI && @@ -1842,10 +1842,10 @@ change_sysid(void) (i == 8 && sys != 0) ) ) { - printf("Consider leaving partition 9 " - "as volume header (0),\nand " - "partition 11 as entire volume (6)" - "as IRIX expects it\n\n"); + puts("Consider leaving partition 9 " + "as volume header (0),\nand " + "partition 11 as entire volume (6)" + "as IRIX expects it\n"); } #endif if (sys == origsys) @@ -2067,7 +2067,7 @@ fix_partition_table_order(void) int i,k; if (!wrong_p_order(NULL)) { - printf("Ordering is already correct\n\n"); + puts("Ordering is already correct\n"); return; } @@ -2095,7 +2095,7 @@ fix_partition_table_order(void) if (i) fix_chain_of_logicals(); - printf("Done.\n"); + puts("Done"); } #endif @@ -2178,7 +2178,7 @@ list_table(int xtra) * if this is a sgi, sun or aix labeled disk... */ if (LABEL_IS_DOS && wrong_p_order(NULL)) { /* FIXME */ - printf("\nPartition table entries are not in disk order\n"); + puts("\nPartition table entries are not in disk order"); } } @@ -2192,7 +2192,7 @@ x_list_table(int extend) printf("\nDisk %s: %u heads, %u sectors, %u cylinders\n\n", disk_device, g_heads, g_sectors, g_cylinders); - printf("Nr AF Hd Sec Cyl Hd Sec Cyl Start Size ID\n"); + puts("Nr AF Hd Sec Cyl Hd Sec Cyl Start Size ID"); for (i = 0; i < g_partitions; i++) { pe = &ptes[i]; p = (extend ? pe->ext_pointer : pe->part_table); @@ -2419,7 +2419,7 @@ add_partition(int n, int sys) limit = first[i] - 1; } if (start > limit) { - printf("No free sectors available\n"); + puts("No free sectors available"); if (n > 4) g_partitions--; return; @@ -2490,9 +2490,9 @@ new_partition(void) return; } if (LABEL_IS_AIX) { - printf("Sorry - this fdisk cannot handle AIX disk labels.\n" + puts("Sorry - this fdisk cannot handle AIX disk labels.\n" "If you want to add DOS-type partitions, create a new empty DOS partition\n" -"table first (use 'o'). This will destroy the present disk contents.\n"); +"table first (use 'o'). This will destroy the present disk contents."); return; } @@ -2500,7 +2500,7 @@ new_partition(void) free_primary += !ptes[i].part_table->sys_ind; if (!free_primary && g_partitions >= MAXIMUM_PARTS) { - printf("The maximum number of partitions has been created\n"); + puts("The maximum number of partitions has been created"); return; } @@ -2508,8 +2508,8 @@ new_partition(void) if (extended_offset) add_logical(); else - printf("You must delete some partition and add " - "an extended partition first\n"); + puts("You must delete some partition and add " + "an extended partition first"); } else { char c, line[80]; snprintf(line, sizeof(line), @@ -2547,7 +2547,7 @@ reread_partition_table(int leave) { int i; - printf("Calling ioctl() to re-read partition table\n"); + puts("Calling ioctl() to re-read partition table"); sync(); /* Users with slow external USB disks on a 320MHz ARM system (year 2011) * report that sleep is needed, otherwise BLKRRPART may fail with -EIO: @@ -2558,10 +2558,10 @@ reread_partition_table(int leave) "failed, kernel still uses old table"); #if 0 if (dos_changed) - printf( + puts( "\nWARNING: If you have created or modified any DOS 6.x\n" "partitions, please see the fdisk manual page for additional\n" - "information\n"); + "information"); #endif if (leave) { @@ -2589,7 +2589,7 @@ write_table(void) } } else if (LABEL_IS_SGI) { - /* no test on change? the printf below might be mistaken */ + /* no test on change? the "altered" msg below might be mistaken */ sgi_write_table(); } else if (LABEL_IS_SUN) { @@ -2601,7 +2601,7 @@ write_table(void) } } - printf("The partition table has been altered.\n"); + puts("The partition table has been altered."); reread_partition_table(1); } #endif /* FEATURE_FDISK_WRITABLE */ @@ -2744,8 +2744,8 @@ xselect(void) user_sectors = g_sectors = read_int(1, g_sectors, 63, 0, "Number of sectors"); if (dos_compatible_flag) { sector_offset = g_sectors; - printf("Warning: setting sector offset for DOS " - "compatiblity\n"); + puts("Warning: setting sector offset for DOS " + "compatiblity"); } update_units(); break; @@ -3024,7 +3024,7 @@ int fdisk_main(int argc UNUSED_PARAM, char **argv) sgi_get_bootfile()); if (read_maybe_empty("Please enter the name of the " "new boot file: ") == '\n') - printf("Boot file unchanged\n"); + puts("Boot file unchanged"); else sgi_set_bootfile(line_ptr); } @@ -3106,8 +3106,8 @@ int fdisk_main(int argc UNUSED_PARAM, char **argv) #if ENABLE_FEATURE_FDISK_ADVANCED case 'x': if (LABEL_IS_SGI) { - printf("\n\tSorry, no experts menu for SGI " - "partition tables available\n\n"); + puts("\n\tSorry, no experts menu for SGI " + "partition tables available\n"); } else xselect(); break; diff --git a/util-linux/fdisk_gpt.c b/util-linux/fdisk_gpt.c index 5786d5f7d..715e227ca 100644 --- a/util-linux/fdisk_gpt.c +++ b/util-linux/fdisk_gpt.c @@ -106,7 +106,7 @@ gpt_list_table(int xtra UNUSED_PARAM) (unsigned long long)SWAP_LE64(gpt_hdr->first_usable_lba), (unsigned long long)SWAP_LE64(gpt_hdr->last_usable_lba)); - printf("Number Start (sector) End (sector) Size Code Name\n"); + puts("Number Start (sector) End (sector) Size Code Name"); for (i = 0; i < n_parts; i++) { gpt_partition *p = gpt_part(i); if (p->lba_start) { @@ -119,7 +119,7 @@ gpt_list_table(int xtra UNUSED_PARAM) numstr6, 0x0700 /* FIXME */); gpt_print_wide(p->name, 18); - printf("\n"); + bb_putchar('\n'); } } } diff --git a/util-linux/fsck_minix.c b/util-linux/fsck_minix.c index 33767a1af..d2f3524b4 100644 --- a/util-linux/fsck_minix.c +++ b/util-linux/fsck_minix.c @@ -371,9 +371,9 @@ static int ask(const char *string, int def) } } if (def) - printf("y\n"); + puts("y"); else { - printf("n\n"); + puts("n"); errors_uncorrected = 1; } return def; @@ -405,7 +405,7 @@ static void check_mount(void) if (isatty(0) && isatty(1)) cont = ask("Do you really want to continue", 0); if (!cont) { - printf("Check aborted\n"); + puts("Check aborted"); exit(EXIT_SUCCESS); } } @@ -470,8 +470,8 @@ static void write_block(unsigned nr, void *addr) if (!nr) return; if (nr < FIRSTZONE || nr >= ZONES) { - printf("Internal error: trying to write bad block\n" - "Write request ignored\n"); + puts("Internal error: trying to write bad block\n" + "Write request ignored"); errors_uncorrected = 1; return; } @@ -659,7 +659,7 @@ static void read_tables(void) if (INODE_BUFFER_SIZE != read(dev_fd, inode_buffer, INODE_BUFFER_SIZE)) die("can't read inodes"); if (NORM_FIRSTZONE != FIRSTZONE) { - printf("warning: firstzone!=norm_firstzone\n"); + puts("warning: firstzone!=norm_firstzone"); errors_uncorrected = 1; } get_dirsize(); @@ -713,7 +713,7 @@ static void get_inode_common(unsigned nr, uint16_t i_mode) } else links++; if (!++inode_count[nr]) { - printf("Warning: inode count too big\n"); + puts("Warning: inode count too big"); inode_count[nr]--; errors_uncorrected = 1; } @@ -1299,7 +1299,7 @@ int fsck_minix_main(int argc UNUSED_PARAM, char **argv) } if (changed) { write_tables(); - printf("FILE SYSTEM HAS BEEN CHANGED\n"); + puts("FILE SYSTEM HAS BEEN CHANGED"); sync(); } else if (OPT_repair) write_superblock(); diff --git a/util-linux/getopt.c b/util-linux/getopt.c index 58df1c823..b9dadf13c 100644 --- a/util-linux/getopt.c +++ b/util-linux/getopt.c @@ -378,7 +378,7 @@ int getopt_main(int argc, char **argv) if (compatible) { /* For some reason, the original getopt gave no error * when there were no arguments. */ - printf(" --\n"); + puts(" --"); return 0; } bb_error_msg_and_die("missing optstring argument"); diff --git a/util-linux/ipcrm.c b/util-linux/ipcrm.c index 888f70ef8..38d81af50 100644 --- a/util-linux/ipcrm.c +++ b/util-linux/ipcrm.c @@ -119,7 +119,7 @@ int ipcrm_main(int argc, char **argv) if (remove_ids(what, &argv[2])) fflush_stdout_and_exit(EXIT_FAILURE); - printf("resource(s) deleted\n"); + puts("resource(s) deleted"); return 0; } } -- cgit v1.2.3-55-g6feb From 7f3a2a22569eb8e4c9fcc1c7f4e51fe0c6155dae Mon Sep 17 00:00:00 2001 From: Denys Vlasenko <vda.linux@googlemail.com> Date: Thu, 8 Oct 2015 11:24:44 +0200 Subject: join some common strings, -400 bytes function old new delta print_intel_cstates 499 511 +12 file_insert 355 364 +9 dpkg_main 2944 2940 -4 ifenslave_main 645 640 -5 ------------------------------------------------------------------------------ (add/remove: 0/0 grow/shrink: 2/2 up/down: 21/-9) Total: 12 bytes text data bss dec hex filename 937564 932 17676 956172 e970c busybox_old 937164 932 17676 955772 e957c busybox_unstripped Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com> --- archival/dpkg.c | 8 +++--- archival/libarchive/data_extract_to_command.c | 2 +- debianutils/run_parts.c | 2 +- editors/vi.c | 8 +++--- findutils/xargs.c | 2 +- miscutils/i2c_tools.c | 36 +++++++++++++-------------- networking/httpd.c | 6 ++--- networking/ifenslave.c | 8 +++--- procps/powertop.c | 4 +-- runit/runsv.c | 4 +-- util-linux/mkfs_minix.c | 10 ++++---- 11 files changed, 45 insertions(+), 45 deletions(-) diff --git a/archival/dpkg.c b/archival/dpkg.c index 151f0ca43..df7a0db64 100644 --- a/archival/dpkg.c +++ b/archival/dpkg.c @@ -1151,13 +1151,13 @@ static int check_deps(deb_file_t **deb_file, int deb_start /*, int dep_max_count if (result && number_of_alternatives == 0) { if (root_of_alternatives) bb_error_msg_and_die( - "package %s %sdepends on %s, " - "which cannot be satisfied", + "package %s %sdepends on %s, which %s", name_hashtable[package_node->name], package_edge->type == EDGE_PRE_DEPENDS ? "pre-" : "", - name_hashtable[root_of_alternatives->name]); + name_hashtable[root_of_alternatives->name], + "cannot be satisfied"); bb_error_msg_and_die( - "package %s %sdepends on %s, which %s\n", + "package %s %sdepends on %s, which %s", name_hashtable[package_node->name], package_edge->type == EDGE_PRE_DEPENDS ? "pre-" : "", name_hashtable[package_edge->name], diff --git a/archival/libarchive/data_extract_to_command.c b/archival/libarchive/data_extract_to_command.c index 5b32c2ec8..6f5317a0e 100644 --- a/archival/libarchive/data_extract_to_command.c +++ b/archival/libarchive/data_extract_to_command.c @@ -118,7 +118,7 @@ void FAST_FUNC data_extract_to_command(archive_handle_t *archive_handle) bb_error_msg_and_die("'%s' returned status %d", archive_handle->tar__to_command, WEXITSTATUS(status)); if (WIFSIGNALED(status)) - bb_error_msg_and_die("'%s' terminated on signal %d", + bb_error_msg_and_die("'%s' terminated by signal %d", archive_handle->tar__to_command, WTERMSIG(status)); if (!BB_MMU) { diff --git a/debianutils/run_parts.c b/debianutils/run_parts.c index 527fae227..dd6fe7d49 100644 --- a/debianutils/run_parts.c +++ b/debianutils/run_parts.c @@ -189,7 +189,7 @@ int run_parts_main(int argc UNUSED_PARAM, char **argv) if (ret < 0) bb_perror_msg("can't execute '%s'", name); else /* ret > 0 */ - bb_error_msg("%s exited with code %d", name, ret & 0xff); + bb_error_msg("%s: exit status %u", name, ret & 0xff); if (option_mask32 & OPT_e) xfunc_die(); diff --git a/editors/vi.c b/editors/vi.c index 3db597ae1..f355712ab 100644 --- a/editors/vi.c +++ b/editors/vi.c @@ -2910,10 +2910,10 @@ static int file_insert(const char *fn, char *p, int initial) int fd, size; struct stat statbuf; - if (p < text || p > end) { - status_line_bold("Trying to insert file outside of memory"); - return cnt; - } + if (p < text) + p = text; + if (p > end) + p = end; fd = open(fn, O_RDONLY); if (fd < 0) { diff --git a/findutils/xargs.c b/findutils/xargs.c index 25e47ec89..5870b8a16 100644 --- a/findutils/xargs.c +++ b/findutils/xargs.c @@ -122,7 +122,7 @@ static int xargs_exec(void) return 124; } if (status >= 0x180) { - bb_error_msg("%s: terminated by signal %d", + bb_error_msg("'%s' terminated by signal %d", G.args[0], status - 0x180); return 125; } diff --git a/miscutils/i2c_tools.c b/miscutils/i2c_tools.c index 292ff88dd..d77e6bacf 100644 --- a/miscutils/i2c_tools.c +++ b/miscutils/i2c_tools.c @@ -358,7 +358,7 @@ static void check_read_funcs(int fd, int mode, int data_addr, int pec) break; #endif /* ENABLE_I2CDUMP */ default: - bb_error_msg_and_die("Programmer goofed!"); + bb_error_msg_and_die("internal error"); } check_funcs_test_end(funcs, pec, err); } @@ -1022,33 +1022,33 @@ static const struct i2c_func i2c_funcs_tab[] = { { .value = I2C_FUNC_I2C, .name = "I2C" }, { .value = I2C_FUNC_SMBUS_QUICK, - .name = "SMBus Quick Command" }, + .name = "SMBus quick command" }, { .value = I2C_FUNC_SMBUS_WRITE_BYTE, - .name = "SMBus Send Byte" }, + .name = "SMBus send byte" }, { .value = I2C_FUNC_SMBUS_READ_BYTE, - .name = "SMBus Receive Byte" }, + .name = "SMBus receive byte" }, { .value = I2C_FUNC_SMBUS_WRITE_BYTE_DATA, - .name = "SMBus Write Byte" }, + .name = "SMBus write byte" }, { .value = I2C_FUNC_SMBUS_READ_BYTE_DATA, - .name = "SMBus Read Byte" }, + .name = "SMBus read byte" }, { .value = I2C_FUNC_SMBUS_WRITE_WORD_DATA, - .name = "SMBus Write Word" }, + .name = "SMBus write word" }, { .value = I2C_FUNC_SMBUS_READ_WORD_DATA, - .name = "SMBus Read Word" }, + .name = "SMBus read word" }, { .value = I2C_FUNC_SMBUS_PROC_CALL, - .name = "SMBus Process Call" }, + .name = "SMBus process call" }, { .value = I2C_FUNC_SMBUS_WRITE_BLOCK_DATA, - .name = "SMBus Block Write" }, + .name = "SMBus block write" }, { .value = I2C_FUNC_SMBUS_READ_BLOCK_DATA, - .name = "SMBus Block Read" }, + .name = "SMBus block read" }, { .value = I2C_FUNC_SMBUS_BLOCK_PROC_CALL, - .name = "SMBus Block Process Call" }, + .name = "SMBus block process call" }, { .value = I2C_FUNC_SMBUS_PEC, .name = "SMBus PEC" }, { .value = I2C_FUNC_SMBUS_WRITE_I2C_BLOCK, - .name = "I2C Block Write" }, + .name = "I2C block write" }, { .value = I2C_FUNC_SMBUS_READ_I2C_BLOCK, - .name = "I2C Block Read" }, + .name = "I2C block read" }, { .value = 0, .name = NULL } }; @@ -1251,17 +1251,17 @@ int i2cdetect_main(int argc UNUSED_PARAM, char **argv) no_support("detection commands"); } else if (mode == I2CDETECT_MODE_QUICK && !(funcs & I2C_FUNC_SMBUS_QUICK)) { - no_support("SMBus Quick Write command"); + no_support("SMBus quick write"); } else if (mode == I2CDETECT_MODE_READ && !(funcs & I2C_FUNC_SMBUS_READ_BYTE)) { - no_support("SMBus Receive Byte command"); + no_support("SMBus receive byte"); } if (mode == I2CDETECT_MODE_AUTO) { if (!(funcs & I2C_FUNC_SMBUS_QUICK)) - will_skip("SMBus Quick Write"); + will_skip("SMBus quick write"); if (!(funcs & I2C_FUNC_SMBUS_READ_BYTE)) - will_skip("SMBus Receive Byte"); + will_skip("SMBus receive byte"); } if (!(opts & opt_y)) diff --git a/networking/httpd.c b/networking/httpd.c index feaaa94d5..00169c36d 100644 --- a/networking/httpd.c +++ b/networking/httpd.c @@ -1222,12 +1222,12 @@ static NOINLINE void cgi_io_loop_and_exit(int fromCgi_rd, int toCgi_wr, int post out_cnt += count; count = 0; /* "Status" header format is: "Status: 302 Redirected\r\n" */ - if (out_cnt >= 8 && memcmp(rbuf, "Status: ", 8) == 0) { + if (out_cnt >= 7 && memcmp(rbuf, "Status:", 7) == 0) { /* send "HTTP/1.0 " */ if (full_write(STDOUT_FILENO, HTTP_200, 9) != 9) break; - rbuf += 8; /* skip "Status: " */ - count = out_cnt - 8; + rbuf += 7; /* skip "Status:" */ + count = out_cnt - 7; out_cnt = -1; /* buffering off */ } else if (out_cnt >= 4) { /* Did CGI add "HTTP"? */ diff --git a/networking/ifenslave.c b/networking/ifenslave.c index c3be8180b..6b234adee 100644 --- a/networking/ifenslave.c +++ b/networking/ifenslave.c @@ -577,8 +577,8 @@ int ifenslave_main(int argc UNUSED_PARAM, char **argv) /* Can't work with this slave, */ /* remember the error and skip it */ bb_perror_msg( - "skipping %s: can't get flags", - slave_ifname); + "skipping %s: can't get %s", + slave_ifname, "flags"); res = rv; continue; } @@ -595,8 +595,8 @@ int ifenslave_main(int argc UNUSED_PARAM, char **argv) /* Can't work with this slave, */ /* remember the error and skip it */ bb_perror_msg( - "skipping %s: can't get settings", - slave_ifname); + "skipping %s: can't get %s", + slave_ifname, "settings"); res = rv; continue; } diff --git a/procps/powertop.c b/procps/powertop.c index 18418100f..ce85f4191 100644 --- a/procps/powertop.c +++ b/procps/powertop.c @@ -591,7 +591,7 @@ static NOINLINE void print_intel_cstates(void) if (!edx || !(ecx & 1)) return; - printf("Your CPU supports the following C-states: "); + printf("Your %s the following C-states: ", "CPU supports"); i = 0; while (edx) { if (edx & 7) @@ -602,7 +602,7 @@ static NOINLINE void print_intel_cstates(void) bb_putchar('\n'); /* Print BIOS C-States */ - printf("Your BIOS reports the following C-states: "); + printf("Your %s the following C-states: ", "BIOS reports"); for (i = 0; i < ARRAY_SIZE(bios_table); i++) if (bios_table[i]) printf("C%u ", i); diff --git a/runit/runsv.c b/runit/runsv.c index d941e897d..94d286059 100644 --- a/runit/runsv.c +++ b/runit/runsv.c @@ -114,7 +114,7 @@ struct globals { static void fatal2_cannot(const char *m1, const char *m2) { - bb_perror_msg_and_die("%s: fatal: cannot %s%s", dir, m1, m2); + bb_perror_msg_and_die("%s: fatal: can't %s%s", dir, m1, m2); /* was exiting 111 */ } static void fatal_cannot(const char *m) @@ -124,7 +124,7 @@ static void fatal_cannot(const char *m) } static void fatal2x_cannot(const char *m1, const char *m2) { - bb_error_msg_and_die("%s: fatal: cannot %s%s", dir, m1, m2); + bb_error_msg_and_die("%s: fatal: can't %s%s", dir, m1, m2); /* was exiting 111 */ } static void warn_cannot(const char *m) diff --git a/util-linux/mkfs_minix.c b/util-linux/mkfs_minix.c index d65a5161c..88d797584 100644 --- a/util-linux/mkfs_minix.c +++ b/util-linux/mkfs_minix.c @@ -576,11 +576,11 @@ static void setup_tables(void) for (i = MINIX_ROOT_INO; i <= SB_INODES; i++) unmark_inode(i); G.inode_buffer = xzalloc(INODE_BUFFER_SIZE); - printf("%ld inodes\n", (long)SB_INODES); - printf("%ld blocks\n", (long)SB_ZONES); - printf("Firstdatazone=%ld (%ld)\n", (long)SB_FIRSTZONE, (long)norm_firstzone); - printf("Zonesize=%d\n", BLOCK_SIZE << SB_ZONE_SIZE); - printf("Maxsize=%ld\n", (long)SB_MAXSIZE); + printf("%lu inodes\n", (unsigned long)SB_INODES); + printf("%lu blocks\n", (unsigned long)SB_ZONES); + printf("Firstdatazone=%lu (%lu)\n", (unsigned long)SB_FIRSTZONE, (unsigned long)norm_firstzone); + printf("Zonesize=%u\n", BLOCK_SIZE << SB_ZONE_SIZE); + printf("Maxsize=%lu\n", (unsigned long)SB_MAXSIZE); } int mkfs_minix_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; -- cgit v1.2.3-55-g6feb From 3d8d5e8ad4d2df71e0307c385b3784586b545cbc Mon Sep 17 00:00:00 2001 From: Denys Vlasenko <vda.linux@googlemail.com> Date: Thu, 8 Oct 2015 13:02:28 +0200 Subject: libiproute: use itoa() where appropriate function old new delta rtnl_rtprot_a2n 31 88 +57 print_tunnel 647 640 -7 print_route 1865 1858 -7 print_linkinfo 820 812 -8 print_addrinfo 1241 1227 -14 rtnl_rttable_n2a 53 38 -15 rtnl_rtscope_n2a 53 38 -15 rtnl_rtrealm_n2a 53 38 -15 rtnl_dsfield_n2a 61 38 -23 rtnl_rtntype_n2a 118 89 -29 print_rule 724 689 -35 ipaddr_list_or_flush 1293 1253 -40 rtnl_rtprot_n2a 53 - -53 rtnl_rtprot_initialize 63 - -63 ------------------------------------------------------------------------------ (add/remove: 0/2 grow/shrink: 1/11 up/down: 57/-324) Total: -267 bytes Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com> --- networking/libiproute/ipaddress.c | 14 +++++------- networking/libiproute/iproute.c | 3 +-- networking/libiproute/iprule.c | 11 +++++---- networking/libiproute/iptunnel.c | 3 +-- networking/libiproute/ll_map.c | 1 - networking/libiproute/rt_names.c | 47 ++++++++++++++------------------------- networking/libiproute/rt_names.h | 11 +++++---- networking/libiproute/rtm_map.c | 6 ++--- networking/libiproute/rtm_map.h | 2 +- 9 files changed, 37 insertions(+), 61 deletions(-) diff --git a/networking/libiproute/ipaddress.c b/networking/libiproute/ipaddress.c index a6d5129e7..8845cab91 100644 --- a/networking/libiproute/ipaddress.c +++ b/networking/libiproute/ipaddress.c @@ -137,12 +137,11 @@ static NOINLINE int print_linkinfo(const struct nlmsghdr *n) { unsigned m_flag = 0; if (tb[IFLA_LINK]) { - SPRINT_BUF(b1); int iflink = *(int*)RTA_DATA(tb[IFLA_LINK]); if (iflink == 0) printf("@NONE: "); else { - printf("@%s: ", ll_idx_n2a(iflink, b1)); + printf("@%s: ", ll_index_to_name(iflink)); m_flag = ll_index_to_flags(iflink); m_flag = !(m_flag & IFF_UP); } @@ -158,8 +157,7 @@ static NOINLINE int print_linkinfo(const struct nlmsghdr *n) printf("qdisc %s ", (char*)RTA_DATA(tb[IFLA_QDISC])); #ifdef IFLA_MASTER if (tb[IFLA_MASTER]) { - SPRINT_BUF(b1); - printf("master %s ", ll_idx_n2a(*(int*)RTA_DATA(tb[IFLA_MASTER]), b1)); + printf("master %s ", ll_index_to_name(*(int*)RTA_DATA(tb[IFLA_MASTER]))); } #endif /* IFLA_OPERSTATE was added to kernel with the same commit as IFF_DORMANT */ @@ -218,7 +216,6 @@ static int FAST_FUNC print_addrinfo(const struct sockaddr_nl *who UNUSED_PARAM, int len = n->nlmsg_len; struct rtattr * rta_tb[IFA_MAX+1]; char abuf[256]; - SPRINT_BUF(b1); if (n->nlmsg_type != RTM_NEWADDR && n->nlmsg_type != RTM_DELADDR) return 0; @@ -250,7 +247,7 @@ static int FAST_FUNC print_addrinfo(const struct sockaddr_nl *who UNUSED_PARAM, if (rta_tb[IFA_LABEL]) label = RTA_DATA(rta_tb[IFA_LABEL]); else - label = ll_idx_n2a(ifa->ifa_index, b1); + label = ll_index_to_name(ifa->ifa_index); if (fnmatch(G_filter.label, label, 0) != 0) return 0; } @@ -325,7 +322,7 @@ static int FAST_FUNC print_addrinfo(const struct sockaddr_nl *who UNUSED_PARAM, abuf, sizeof(abuf)) ); } - printf("scope %s ", rtnl_rtscope_n2a(ifa->ifa_scope, b1)); + printf("scope %s ", rtnl_rtscope_n2a(ifa->ifa_scope)); if (ifa->ifa_flags & IFA_F_SECONDARY) { ifa->ifa_flags &= ~IFA_F_SECONDARY; printf("secondary "); @@ -556,12 +553,11 @@ int FAST_FUNC ipaddr_list_or_flush(char **argv, int flush) continue; } if (G_filter.label) { - SPRINT_BUF(b1); const char *label; if (tb[IFA_LABEL]) label = RTA_DATA(tb[IFA_LABEL]); else - label = ll_idx_n2a(ifa->ifa_index, b1); + label = ll_index_to_name(ifa->ifa_index); if (fnmatch(G_filter.label, label, 0) != 0) continue; } diff --git a/networking/libiproute/iproute.c b/networking/libiproute/iproute.c index 170c67b30..6ecd5f719 100644 --- a/networking/libiproute/iproute.c +++ b/networking/libiproute/iproute.c @@ -87,7 +87,6 @@ static int FAST_FUNC print_route(const struct sockaddr_nl *who UNUSED_PARAM, inet_prefix dst; inet_prefix src; int host_len = -1; - SPRINT_BUF(b1); if (n->nlmsg_type != RTM_NEWROUTE && n->nlmsg_type != RTM_DELROUTE) { fprintf(stderr, "Not a route: %08x %08x %08x\n", @@ -236,7 +235,7 @@ static int FAST_FUNC print_route(const struct sockaddr_nl *who UNUSED_PARAM, printf("Deleted "); } if (r->rtm_type != RTN_UNICAST /* && !G_filter.type - always 0 */) { - printf("%s ", rtnl_rtntype_n2a(r->rtm_type, b1)); + printf("%s ", rtnl_rtntype_n2a(r->rtm_type)); } if (tb[RTA_DST]) { diff --git a/networking/libiproute/iprule.c b/networking/libiproute/iprule.c index 8dbe6bd92..774a3e220 100644 --- a/networking/libiproute/iprule.c +++ b/networking/libiproute/iprule.c @@ -45,7 +45,6 @@ static int FAST_FUNC print_rule(const struct sockaddr_nl *who UNUSED_PARAM, int host_len = -1; struct rtattr * tb[RTA_MAX+1]; char abuf[256]; - SPRINT_BUF(b1); if (n->nlmsg_type != RTM_NEWRULE) return 0; @@ -110,7 +109,7 @@ static int FAST_FUNC print_rule(const struct sockaddr_nl *who UNUSED_PARAM, } if (r->rtm_tos) { - printf("tos %s ", rtnl_dsfield_n2a(r->rtm_tos, b1)); + printf("tos %s ", rtnl_dsfield_n2a(r->rtm_tos)); } if (tb[RTA_PROTOINFO]) { printf("fwmark %#x ", *(uint32_t*)RTA_DATA(tb[RTA_PROTOINFO])); @@ -121,7 +120,7 @@ static int FAST_FUNC print_rule(const struct sockaddr_nl *who UNUSED_PARAM, } if (r->rtm_table) - printf("lookup %s ", rtnl_rttable_n2a(r->rtm_table, b1)); + printf("lookup %s ", rtnl_rttable_n2a(r->rtm_table)); if (tb[RTA_FLOW]) { uint32_t to = *(uint32_t*)RTA_DATA(tb[RTA_FLOW]); @@ -129,10 +128,10 @@ static int FAST_FUNC print_rule(const struct sockaddr_nl *who UNUSED_PARAM, to &= 0xFFFF; if (from) { printf("realms %s/", - rtnl_rtrealm_n2a(from, b1)); + rtnl_rtrealm_n2a(from)); } printf("%s ", - rtnl_rtrealm_n2a(to, b1)); + rtnl_rtrealm_n2a(to)); } if (r->rtm_type == RTN_NAT) { @@ -145,7 +144,7 @@ static int FAST_FUNC print_rule(const struct sockaddr_nl *who UNUSED_PARAM, } else printf("masquerade"); } else if (r->rtm_type != RTN_UNICAST) - fputs(rtnl_rtntype_n2a(r->rtm_type, b1), stdout); + fputs(rtnl_rtntype_n2a(r->rtm_type), stdout); bb_putchar('\n'); /*fflush_all();*/ diff --git a/networking/libiproute/iptunnel.c b/networking/libiproute/iptunnel.c index b54c3c53f..a65d5e579 100644 --- a/networking/libiproute/iptunnel.c +++ b/networking/libiproute/iptunnel.c @@ -432,13 +432,12 @@ static void print_tunnel(struct ip_tunnel_parm *p) else printf(" ttl inherit "); if (p->iph.tos) { - SPRINT_BUF(b1); printf(" tos"); if (p->iph.tos & 1) printf(" inherit"); if (p->iph.tos & ~1) printf("%c%s ", p->iph.tos & 1 ? '/' : ' ', - rtnl_dsfield_n2a(p->iph.tos & ~1, b1)); + rtnl_dsfield_n2a(p->iph.tos & ~1)); } if (!(p->iph.frag_off & htons(IP_DF))) printf(" nopmtudisc"); diff --git a/networking/libiproute/ll_map.c b/networking/libiproute/ll_map.c index 27cd90f34..feb6e8d22 100644 --- a/networking/libiproute/ll_map.c +++ b/networking/libiproute/ll_map.c @@ -99,7 +99,6 @@ const char FAST_FUNC *ll_idx_n2a(int idx, char *buf) return buf; } - const char FAST_FUNC *ll_index_to_name(int idx) { static char nbuf[16]; diff --git a/networking/libiproute/rt_names.c b/networking/libiproute/rt_names.c index c474ab903..375f14528 100644 --- a/networking/libiproute/rt_names.c +++ b/networking/libiproute/rt_names.c @@ -88,21 +88,20 @@ static void rtnl_rtprot_initialize(void) rtnl_tab_initialize("/etc/iproute2/rt_protos", rtnl_rtprot_tab->tab); } -const char* FAST_FUNC rtnl_rtprot_n2a(int id, char *buf) +#if 0 /* UNUSED */ +const char* FAST_FUNC rtnl_rtprot_n2a(int id) { if (id < 0 || id >= 256) { - sprintf(buf, "%d", id); - return buf; + return itoa(id); } rtnl_rtprot_initialize(); if (rtnl_rtprot_tab->tab[id]) return rtnl_rtprot_tab->tab[id]; - /* buf is SPRINT_BSIZE big */ - sprintf(buf, "%d", id); - return buf; + return itoa(id); } +#endif int FAST_FUNC rtnl_rtprot_a2n(uint32_t *id, char *arg) { @@ -126,20 +125,17 @@ static void rtnl_rtscope_initialize(void) rtnl_tab_initialize("/etc/iproute2/rt_scopes", rtnl_rtscope_tab->tab); } -const char* FAST_FUNC rtnl_rtscope_n2a(int id, char *buf) +const char* FAST_FUNC rtnl_rtscope_n2a(int id) { if (id < 0 || id >= 256) { - sprintf(buf, "%d", id); - return buf; + return itoa(id); } rtnl_rtscope_initialize(); if (rtnl_rtscope_tab->tab[id]) return rtnl_rtscope_tab->tab[id]; - /* buf is SPRINT_BSIZE big */ - sprintf(buf, "%d", id); - return buf; + return itoa(id); } int FAST_FUNC rtnl_rtscope_a2n(uint32_t *id, char *arg) @@ -166,20 +162,17 @@ int FAST_FUNC rtnl_rtrealm_a2n(uint32_t *id, char *arg) } #if ENABLE_FEATURE_IP_RULE -const char* FAST_FUNC rtnl_rtrealm_n2a(int id, char *buf) +const char* FAST_FUNC rtnl_rtrealm_n2a(int id) { if (id < 0 || id >= 256) { - sprintf(buf, "%d", id); - return buf; + return itoa(id); } rtnl_rtrealm_initialize(); if (rtnl_rtrealm_tab->tab[id]) return rtnl_rtrealm_tab->tab[id]; - /* buf is SPRINT_BSIZE big */ - sprintf(buf, "%d", id); - return buf; + return itoa(id); } #endif @@ -194,20 +187,17 @@ static void rtnl_rtdsfield_initialize(void) rtnl_tab_initialize("/etc/iproute2/rt_dsfield", rtnl_rtdsfield_tab->tab); } -const char* FAST_FUNC rtnl_dsfield_n2a(int id, char *buf) +const char* FAST_FUNC rtnl_dsfield_n2a(int id) { if (id < 0 || id >= 256) { - sprintf(buf, "%d", id); - return buf; + return itoa(id); } rtnl_rtdsfield_initialize(); if (rtnl_rtdsfield_tab->tab[id]) return rtnl_rtdsfield_tab->tab[id]; - /* buf is SPRINT_BSIZE big */ - sprintf(buf, "0x%02x", id); - return buf; + return itoa(id); } int FAST_FUNC rtnl_dsfield_a2n(uint32_t *id, char *arg) @@ -231,20 +221,17 @@ static void rtnl_rttable_initialize(void) rtnl_tab_initialize("/etc/iproute2/rt_tables", rtnl_rttable_tab->tab); } -const char* FAST_FUNC rtnl_rttable_n2a(int id, char *buf) +const char* FAST_FUNC rtnl_rttable_n2a(int id) { if (id < 0 || id >= 256) { - sprintf(buf, "%d", id); - return buf; + return itoa(id); } rtnl_rttable_initialize(); if (rtnl_rttable_tab->tab[id]) return rtnl_rttable_tab->tab[id]; - /* buf is SPRINT_BSIZE big */ - sprintf(buf, "%d", id); - return buf; + return itoa(id); } int FAST_FUNC rtnl_rttable_a2n(uint32_t *id, char *arg) diff --git a/networking/libiproute/rt_names.h b/networking/libiproute/rt_names.h index e73aa851c..29932d6a4 100644 --- a/networking/libiproute/rt_names.h +++ b/networking/libiproute/rt_names.h @@ -4,12 +4,11 @@ PUSH_AND_SET_FUNCTION_VISIBILITY_TO_HIDDEN -/* buf is SPRINT_BSIZE big */ -extern const char* rtnl_rtprot_n2a(int id, char *buf) FAST_FUNC; -extern const char* rtnl_rtscope_n2a(int id, char *buf) FAST_FUNC; -extern const char* rtnl_rtrealm_n2a(int id, char *buf) FAST_FUNC; -extern const char* rtnl_dsfield_n2a(int id, char *buf) FAST_FUNC; -extern const char* rtnl_rttable_n2a(int id, char *buf) FAST_FUNC; +extern const char* rtnl_rtprot_n2a(int id) FAST_FUNC; +extern const char* rtnl_rtscope_n2a(int id) FAST_FUNC; +extern const char* rtnl_rtrealm_n2a(int id) FAST_FUNC; +extern const char* rtnl_dsfield_n2a(int id) FAST_FUNC; +extern const char* rtnl_rttable_n2a(int id) FAST_FUNC; extern int rtnl_rtprot_a2n(uint32_t *id, char *arg) FAST_FUNC; extern int rtnl_rtscope_a2n(uint32_t *id, char *arg) FAST_FUNC; extern int rtnl_rtrealm_a2n(uint32_t *id, char *arg) FAST_FUNC; diff --git a/networking/libiproute/rtm_map.c b/networking/libiproute/rtm_map.c index 3bab53baf..c763da049 100644 --- a/networking/libiproute/rtm_map.c +++ b/networking/libiproute/rtm_map.c @@ -12,7 +12,7 @@ #include "rt_names.h" #include "utils.h" -const char* FAST_FUNC rtnl_rtntype_n2a(int id, char *buf) +const char* FAST_FUNC rtnl_rtntype_n2a(int id) { switch (id) { case RTN_UNSPEC: @@ -40,9 +40,7 @@ const char* FAST_FUNC rtnl_rtntype_n2a(int id, char *buf) case RTN_XRESOLVE: return "xresolve"; default: - /* buf is SPRINT_BSIZE big */ - sprintf(buf, "%d", id); - return buf; + return itoa(id); } } diff --git a/networking/libiproute/rtm_map.h b/networking/libiproute/rtm_map.h index 4377bd590..63b665169 100644 --- a/networking/libiproute/rtm_map.h +++ b/networking/libiproute/rtm_map.h @@ -4,7 +4,7 @@ PUSH_AND_SET_FUNCTION_VISIBILITY_TO_HIDDEN -const char *rtnl_rtntype_n2a(int id, char *buf) FAST_FUNC; +const char *rtnl_rtntype_n2a(int id) FAST_FUNC; int rtnl_rtntype_a2n(int *id, char *arg) FAST_FUNC; int get_rt_realms(uint32_t *realms, char *arg) FAST_FUNC; -- cgit v1.2.3-55-g6feb From 413feca279c21ef23a3b3d6f4ebc6c3d989bbdc6 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko <vda.linux@googlemail.com> Date: Thu, 8 Oct 2015 15:10:10 +0200 Subject: ip: increased max ID for /etc/iproute2/rt_tables to 1023 Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com> --- networking/libiproute/rt_names.c | 29 +++++++++++++++++++---------- 1 file changed, 19 insertions(+), 10 deletions(-) diff --git a/networking/libiproute/rt_names.c b/networking/libiproute/rt_names.c index 375f14528..8dea5ac52 100644 --- a/networking/libiproute/rt_names.c +++ b/networking/libiproute/rt_names.c @@ -13,7 +13,14 @@ typedef struct rtnl_tab_t { const char *cached_str; unsigned cached_result; - const char *tab[256]; + /* upstream version switched to a hash table and removed + * id < 256 limit. For now bbox bumps this array size from 256 + * to 1024. If you plan to change this to a hash table, + * consider merging several hash tables we have (for example, + * awk has resizable one! + */ +#define RT_TABLE_MAX 1023 + const char *tab[RT_TABLE_MAX+1]; } rtnl_tab_t; static void rtnl_tab_initialize(const char *file, const char **tab) @@ -23,7 +30,7 @@ static void rtnl_tab_initialize(const char *file, const char **tab) while (config_read(parser, token, 2, 2, "# \t", PARSE_NORMAL)) { unsigned id = bb_strtou(token[0], NULL, 0); - if (id > 256) { + if (id > RT_TABLE_MAX) { bb_error_msg("database %s is corrupted at line %d", file, parser->lineno); break; @@ -42,7 +49,7 @@ static int rtnl_a2n(rtnl_tab_t *tab, uint32_t *id, const char *arg, int base) return 0; } - for (i = 0; i < 256; i++) { + for (i = 0; i <= RT_TABLE_MAX; i++) { if (tab->tab[i] && strcmp(tab->tab[i], arg) == 0 ) { @@ -54,7 +61,7 @@ static int rtnl_a2n(rtnl_tab_t *tab, uint32_t *id, const char *arg, int base) } i = bb_strtou(arg, NULL, base); - if (i > 255) + if (i > RT_TABLE_MAX) return -1; *id = i; return 0; @@ -91,7 +98,7 @@ static void rtnl_rtprot_initialize(void) #if 0 /* UNUSED */ const char* FAST_FUNC rtnl_rtprot_n2a(int id) { - if (id < 0 || id >= 256) { + if (id < 0 || id > RT_TABLE_MAX) { return itoa(id); } @@ -127,7 +134,7 @@ static void rtnl_rtscope_initialize(void) const char* FAST_FUNC rtnl_rtscope_n2a(int id) { - if (id < 0 || id >= 256) { + if (id < 0 || id > RT_TABLE_MAX) { return itoa(id); } @@ -164,7 +171,7 @@ int FAST_FUNC rtnl_rtrealm_a2n(uint32_t *id, char *arg) #if ENABLE_FEATURE_IP_RULE const char* FAST_FUNC rtnl_rtrealm_n2a(int id) { - if (id < 0 || id >= 256) { + if (id < 0 || id > RT_TABLE_MAX) { return itoa(id); } @@ -189,7 +196,7 @@ static void rtnl_rtdsfield_initialize(void) const char* FAST_FUNC rtnl_dsfield_n2a(int id) { - if (id < 0 || id >= 256) { + if (id < 0 || id > RT_TABLE_MAX) { return itoa(id); } @@ -212,7 +219,9 @@ static rtnl_tab_t *rtnl_rttable_tab; static void rtnl_rttable_initialize(void) { - if (rtnl_rtdsfield_tab) return; + if (rtnl_rttable_tab) + return; + rtnl_rttable_tab = xzalloc(sizeof(*rtnl_rttable_tab)); rtnl_rttable_tab->tab[0] = "unspec"; rtnl_rttable_tab->tab[255] = "local"; @@ -223,7 +232,7 @@ static void rtnl_rttable_initialize(void) const char* FAST_FUNC rtnl_rttable_n2a(int id) { - if (id < 0 || id >= 256) { + if (id < 0 || id > RT_TABLE_MAX) { return itoa(id); } -- cgit v1.2.3-55-g6feb From d1eea8db92e963e3c482d96b10da2ec0f9c95770 Mon Sep 17 00:00:00 2001 From: "Christoph J. Thompson" <cjsthompson@gmail.com> Date: Thu, 8 Oct 2015 17:06:06 +0200 Subject: iproute: don't hardcode the path to config files Allows using an alternate path for config files. Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com> Signed-off-by: Christoph J. Thompson <cjsthompson@gmail.com> Signed-off-by: Michael Bestas <mikeioannina@gmail.com> --- networking/Config.src | 7 +++++++ networking/libiproute/rt_names.c | 12 +++++++----- 2 files changed, 14 insertions(+), 5 deletions(-) diff --git a/networking/Config.src b/networking/Config.src index 76cbccf4a..43ccbf385 100644 --- a/networking/Config.src +++ b/networking/Config.src @@ -533,6 +533,13 @@ config FEATURE_IP_ROUTE help Add support for routing table management to "ip". +config FEATURE_IP_ROUTE_DIR + string "ip route configuration directory" + default "/etc/iproute2" + depends on FEATURE_IP_ROUTE + help + Location of the "ip" applet routing configuration. + config FEATURE_IP_TUNNEL bool "ip tunnel" default y diff --git a/networking/libiproute/rt_names.c b/networking/libiproute/rt_names.c index 8dea5ac52..ca0bb5d4d 100644 --- a/networking/libiproute/rt_names.c +++ b/networking/libiproute/rt_names.c @@ -10,6 +10,8 @@ #include "libbb.h" #include "rt_names.h" +#define CONFDIR CONFIG_FEATURE_IP_ROUTE_DIR + typedef struct rtnl_tab_t { const char *cached_str; unsigned cached_result; @@ -92,7 +94,7 @@ static void rtnl_rtprot_initialize(void) return; rtnl_rtprot_tab = xzalloc(sizeof(*rtnl_rtprot_tab)); memcpy(rtnl_rtprot_tab->tab, init_tab, sizeof(init_tab)); - rtnl_tab_initialize("/etc/iproute2/rt_protos", rtnl_rtprot_tab->tab); + rtnl_tab_initialize(CONFDIR "/rt_protos", rtnl_rtprot_tab->tab); } #if 0 /* UNUSED */ @@ -129,7 +131,7 @@ static void rtnl_rtscope_initialize(void) rtnl_rtscope_tab->tab[254] = "host"; rtnl_rtscope_tab->tab[253] = "link"; rtnl_rtscope_tab->tab[200] = "site"; - rtnl_tab_initialize("/etc/iproute2/rt_scopes", rtnl_rtscope_tab->tab); + rtnl_tab_initialize(CONFDIR "/rt_scopes", rtnl_rtscope_tab->tab); } const char* FAST_FUNC rtnl_rtscope_n2a(int id) @@ -159,7 +161,7 @@ static void rtnl_rtrealm_initialize(void) if (rtnl_rtrealm_tab) return; rtnl_rtrealm_tab = xzalloc(sizeof(*rtnl_rtrealm_tab)); rtnl_rtrealm_tab->tab[0] = "unknown"; - rtnl_tab_initialize("/etc/iproute2/rt_realms", rtnl_rtrealm_tab->tab); + rtnl_tab_initialize(CONFDIR "/rt_realms", rtnl_rtrealm_tab->tab); } int FAST_FUNC rtnl_rtrealm_a2n(uint32_t *id, char *arg) @@ -191,7 +193,7 @@ static void rtnl_rtdsfield_initialize(void) if (rtnl_rtdsfield_tab) return; rtnl_rtdsfield_tab = xzalloc(sizeof(*rtnl_rtdsfield_tab)); rtnl_rtdsfield_tab->tab[0] = "0"; - rtnl_tab_initialize("/etc/iproute2/rt_dsfield", rtnl_rtdsfield_tab->tab); + rtnl_tab_initialize(CONFDIR "/rt_dsfield", rtnl_rtdsfield_tab->tab); } const char* FAST_FUNC rtnl_dsfield_n2a(int id) @@ -227,7 +229,7 @@ static void rtnl_rttable_initialize(void) rtnl_rttable_tab->tab[255] = "local"; rtnl_rttable_tab->tab[254] = "main"; rtnl_rttable_tab->tab[253] = "default"; - rtnl_tab_initialize("/etc/iproute2/rt_tables", rtnl_rttable_tab->tab); + rtnl_tab_initialize(CONFDIR "/rt_tables", rtnl_rttable_tab->tab); } const char* FAST_FUNC rtnl_rttable_n2a(int id) -- cgit v1.2.3-55-g6feb From 8403b01217d4dfc86e8603715eeb52f9993e09b7 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko <vda.linux@googlemail.com> Date: Thu, 8 Oct 2015 17:15:08 +0200 Subject: iproute: more string reuse text data bss dec hex filename 936892 932 17676 955500 e946c busybox_old 936843 932 17676 955451 e943b busybox_unstripped Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com> --- networking/libiproute/rt_names.c | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/networking/libiproute/rt_names.c b/networking/libiproute/rt_names.c index ca0bb5d4d..51f2e9bdb 100644 --- a/networking/libiproute/rt_names.c +++ b/networking/libiproute/rt_names.c @@ -28,8 +28,11 @@ typedef struct rtnl_tab_t { static void rtnl_tab_initialize(const char *file, const char **tab) { char *token[2]; - parser_t *parser = config_open2(file, fopen_for_read); + char fullname[sizeof(CONFDIR"/rt_dsfield") + 8]; + parser_t *parser; + sprintf(fullname, CONFDIR"/rt_%s", file); + parser = config_open2(fullname, fopen_for_read); while (config_read(parser, token, 2, 2, "# \t", PARSE_NORMAL)) { unsigned id = bb_strtou(token[0], NULL, 0); if (id > RT_TABLE_MAX) { @@ -94,7 +97,7 @@ static void rtnl_rtprot_initialize(void) return; rtnl_rtprot_tab = xzalloc(sizeof(*rtnl_rtprot_tab)); memcpy(rtnl_rtprot_tab->tab, init_tab, sizeof(init_tab)); - rtnl_tab_initialize(CONFDIR "/rt_protos", rtnl_rtprot_tab->tab); + rtnl_tab_initialize("protos", rtnl_rtprot_tab->tab); } #if 0 /* UNUSED */ @@ -131,7 +134,7 @@ static void rtnl_rtscope_initialize(void) rtnl_rtscope_tab->tab[254] = "host"; rtnl_rtscope_tab->tab[253] = "link"; rtnl_rtscope_tab->tab[200] = "site"; - rtnl_tab_initialize(CONFDIR "/rt_scopes", rtnl_rtscope_tab->tab); + rtnl_tab_initialize("scopes", rtnl_rtscope_tab->tab); } const char* FAST_FUNC rtnl_rtscope_n2a(int id) @@ -161,7 +164,7 @@ static void rtnl_rtrealm_initialize(void) if (rtnl_rtrealm_tab) return; rtnl_rtrealm_tab = xzalloc(sizeof(*rtnl_rtrealm_tab)); rtnl_rtrealm_tab->tab[0] = "unknown"; - rtnl_tab_initialize(CONFDIR "/rt_realms", rtnl_rtrealm_tab->tab); + rtnl_tab_initialize("realms", rtnl_rtrealm_tab->tab); } int FAST_FUNC rtnl_rtrealm_a2n(uint32_t *id, char *arg) @@ -193,7 +196,7 @@ static void rtnl_rtdsfield_initialize(void) if (rtnl_rtdsfield_tab) return; rtnl_rtdsfield_tab = xzalloc(sizeof(*rtnl_rtdsfield_tab)); rtnl_rtdsfield_tab->tab[0] = "0"; - rtnl_tab_initialize(CONFDIR "/rt_dsfield", rtnl_rtdsfield_tab->tab); + rtnl_tab_initialize("dsfield", rtnl_rtdsfield_tab->tab); } const char* FAST_FUNC rtnl_dsfield_n2a(int id) @@ -229,7 +232,7 @@ static void rtnl_rttable_initialize(void) rtnl_rttable_tab->tab[255] = "local"; rtnl_rttable_tab->tab[254] = "main"; rtnl_rttable_tab->tab[253] = "default"; - rtnl_tab_initialize(CONFDIR "/rt_tables", rtnl_rttable_tab->tab); + rtnl_tab_initialize("tables", rtnl_rttable_tab->tab); } const char* FAST_FUNC rtnl_rttable_n2a(int id) -- cgit v1.2.3-55-g6feb From f2bf20f5d54769ca3c4f83ac8fbcb7e697b2e66a Mon Sep 17 00:00:00 2001 From: Denys Vlasenko <vda.linux@googlemail.com> Date: Thu, 8 Oct 2015 18:13:57 +0200 Subject: udhcpc: fix for some Android toolchain breakage Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com> --- networking/udhcp/dhcpc.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/networking/udhcp/dhcpc.c b/networking/udhcp/dhcpc.c index 11f7b2d49..915f65935 100644 --- a/networking/udhcp/dhcpc.c +++ b/networking/udhcp/dhcpc.c @@ -29,6 +29,20 @@ #include <linux/filter.h> #include <linux/if_packet.h> +#ifndef PACKET_AUXDATA +# define PACKET_AUXDATA 8 +struct tpacket_auxdata { + uint32_t tp_status; + uint32_t tp_len; + uint32_t tp_snaplen; + uint16_t tp_mac; + uint16_t tp_net; + uint16_t tp_vlan_tci; + uint16_t tp_padding; +}; +#endif + + /* "struct client_config_t client_config" is in bb_common_bufsiz1 */ -- cgit v1.2.3-55-g6feb From e1603156ff96672375970f460716d37a50c63fae Mon Sep 17 00:00:00 2001 From: Denys Vlasenko <vda.linux@googlemail.com> Date: Thu, 8 Oct 2015 18:17:31 +0200 Subject: updated android_ndk_defconfig Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com> --- configs/android_ndk_defconfig | 181 ++++++++++++++++++++++++++---------------- 1 file changed, 112 insertions(+), 69 deletions(-) diff --git a/configs/android_ndk_defconfig b/configs/android_ndk_defconfig index 01cc2dd15..66c85268f 100644 --- a/configs/android_ndk_defconfig +++ b/configs/android_ndk_defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Busybox version: 1.21.0.git -# Mon May 28 21:51:18 2012 +# Busybox version: 1.24.0.git +# Fri Sep 18 20:39:29 2015 # CONFIG_HAVE_DOT_CONFIG=y @@ -36,12 +36,15 @@ CONFIG_LAST_SUPPORTED_WCHAR=0 # 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 is not set # CONFIG_FEATURE_CLEAN_UP is not set # CONFIG_FEATURE_UTMP is not set # CONFIG_FEATURE_WTMP is not set # CONFIG_FEATURE_PIDFILE is not set +CONFIG_PID_FILE_PATH="" # CONFIG_FEATURE_SUID is not set # CONFIG_FEATURE_SUID_CONFIG is not set # CONFIG_FEATURE_SUID_CONFIG_QUIET is not set @@ -63,7 +66,7 @@ CONFIG_FEATURE_SYSLOG=y # CONFIG_LFS is not set CONFIG_CROSS_COMPILER_PREFIX="arm-linux-androideabi-" CONFIG_SYSROOT="/opt/android-ndk/platforms/android-9/arch-arm" -CONFIG_EXTRA_CFLAGS="-DANDROID -D__ANDROID__ -DSK_RELEASE -nostdlib -march=armv7-a -msoft-float -mfloat-abi=softfp -mfpu=neon -mthumb -mthumb-interwork -fpic -fno-short-enums -fgcse-after-reload -frename-registers" +CONFIG_EXTRA_CFLAGS="-DANDROID -D__ANDROID__ -DSK_RELEASE -nostdlib -march=armv7-a -msoft-float -mfloat-abi=softfp -mfpu=neon -mthumb -mthumb-interwork -fpic -fno-short-enums -fgcse-after-reload -frename-registers -fuse-ld=bfd" CONFIG_EXTRA_LDFLAGS="-Xlinker -z -Xlinker muldefs -nostdlib -Bdynamic -Xlinker -dynamic-linker -Xlinker /system/bin/linker -Xlinker -z -Xlinker nocopyreloc -Xlinker --no-undefined ${SYSROOT}/usr/lib/crtbegin_dynamic.o ${SYSROOT}/usr/lib/crtend_android.o" CONFIG_EXTRA_LDLIBS="dl m c gcc" @@ -72,6 +75,7 @@ CONFIG_EXTRA_LDLIBS="dl m c gcc" # # CONFIG_DEBUG is not set # CONFIG_DEBUG_PESSIMIZE is not set +# CONFIG_UNIT_TEST is not set # CONFIG_WERROR is not set CONFIG_NO_DEBUG_LIB=y # CONFIG_DMALLOC is not set @@ -96,6 +100,7 @@ CONFIG_PREFIX="./_install" # CONFIG_FEATURE_RTMINMAX is not set 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 @@ -133,7 +138,14 @@ CONFIG_FEATURE_SEAMLESS_Z=y CONFIG_AR=y CONFIG_FEATURE_AR_LONG_FILENAMES=y CONFIG_FEATURE_AR_CREATE=y +CONFIG_UNCOMPRESS=y +CONFIG_GUNZIP=y CONFIG_BUNZIP2=y +CONFIG_UNLZMA=y +CONFIG_FEATURE_LZMA_FAST=y +CONFIG_LZMA=y +CONFIG_UNXZ=y +CONFIG_XZ=y CONFIG_BZIP2=y CONFIG_CPIO=y CONFIG_FEATURE_CPIO_O=y @@ -141,14 +153,14 @@ CONFIG_FEATURE_CPIO_P=y CONFIG_DPKG=y CONFIG_DPKG_DEB=y # CONFIG_FEATURE_DPKG_DEB_EXTRACT_ONLY is not set -CONFIG_GUNZIP=y CONFIG_GZIP=y # CONFIG_FEATURE_GZIP_LONG_OPTIONS is not set CONFIG_GZIP_FAST=0 +# CONFIG_FEATURE_GZIP_LEVELS is not set CONFIG_LZOP=y CONFIG_LZOP_COMPR_HIGH=y -CONFIG_RPM2CPIO=y CONFIG_RPM=y +CONFIG_RPM2CPIO=y CONFIG_TAR=y CONFIG_FEATURE_TAR_CREATE=y CONFIG_FEATURE_TAR_AUTODETECT=y @@ -161,12 +173,6 @@ CONFIG_FEATURE_TAR_GNU_EXTENSIONS=y CONFIG_FEATURE_TAR_UNAME_GNAME=y CONFIG_FEATURE_TAR_NOPRESERVE_TIME=y # CONFIG_FEATURE_TAR_SELINUX is not set -CONFIG_UNCOMPRESS=y -CONFIG_UNLZMA=y -CONFIG_FEATURE_LZMA_FAST=y -CONFIG_LZMA=y -CONFIG_UNXZ=y -CONFIG_XZ=y CONFIG_UNZIP=y # @@ -178,16 +184,27 @@ CONFIG_CAT=y # CONFIG_FEATURE_DATE_ISOFMT is not set # CONFIG_FEATURE_DATE_NANO is not set # CONFIG_FEATURE_DATE_COMPAT is not set +CONFIG_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 is not set # CONFIG_GROUPS is not set +CONFIG_SHUF=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 @@ -203,10 +220,6 @@ CONFIG_COMM=y CONFIG_CP=y # CONFIG_FEATURE_CP_LONG_OPTIONS is not set CONFIG_CUT=y -CONFIG_DD=y -CONFIG_FEATURE_DD_SIGNAL_HANDLING=y -CONFIG_FEATURE_DD_THIRD_STATUS_LINE=y -CONFIG_FEATURE_DD_IBS_OBS=y # CONFIG_DF is not set # CONFIG_FEATURE_DF_FANCY is not set CONFIG_DIRNAME=y @@ -263,6 +276,7 @@ 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 @@ -274,7 +288,6 @@ CONFIG_FEATURE_SPLIT_FANCY=y # CONFIG_FEATURE_STAT_FORMAT is not set CONFIG_STTY=y CONFIG_SUM=y -CONFIG_SYNC=y CONFIG_TAC=y CONFIG_TAIL=y CONFIG_FEATURE_FANCY_TAIL=y @@ -283,6 +296,7 @@ CONFIG_FEATURE_TEE_USE_BLOCK_IO=y CONFIG_TRUE=y # CONFIG_TTY is not set CONFIG_UNAME=y +CONFIG_UNAME_OSNAME="GNU/Linux" CONFIG_UNEXPAND=y # CONFIG_FEATURE_UNEXPAND_LONG_OPTIONS is not set CONFIG_UNIQ=y @@ -294,6 +308,11 @@ CONFIG_FEATURE_WC_LARGE=y CONFIG_WHOAMI=y CONFIG_YES=y +# +# Common options +# +CONFIG_FEATURE_VERBOSE=y + # # Common options for cp and mv # @@ -310,7 +329,7 @@ CONFIG_FEATURE_AUTOWIDTH=y CONFIG_FEATURE_HUMAN_READABLE=y # -# Common options for md5sum, sha1sum, sha256sum, sha512sum +# Common options for md5sum, sha1sum, sha256sum, sha512sum, sha3sum # CONFIG_FEATURE_MD5_SHA1_SUM_CHECK=y @@ -356,7 +375,16 @@ 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 is not set +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=y @@ -371,14 +399,9 @@ CONFIG_FEATURE_VI_SETOPTS=y CONFIG_FEATURE_VI_SET=y CONFIG_FEATURE_VI_WIN_RESIZE=y CONFIG_FEATURE_VI_ASK_TERMINAL=y -CONFIG_AWK=y -CONFIG_FEATURE_AWK_LIBM=y -CONFIG_CMP=y -CONFIG_DIFF=y -# CONFIG_FEATURE_DIFF_LONG_OPTIONS is not set -CONFIG_FEATURE_DIFF_DIR=y -CONFIG_ED=y -CONFIG_SED=y +CONFIG_FEATURE_VI_UNDO=y +CONFIG_FEATURE_VI_UNDO_QUEUE=y +CONFIG_FEATURE_VI_UNDO_QUEUE_MAX=256 CONFIG_FEATURE_ALLOW_EXEC=y # @@ -395,6 +418,7 @@ 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 @@ -416,6 +440,7 @@ 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 @@ -447,11 +472,12 @@ CONFIG_FEATURE_MESG_ENABLE_ONLY_GROUP=y # CONFIG_FEATURE_SHADOWPASSWDS is not set # CONFIG_USE_BB_PWD_GRP is not set # CONFIG_USE_BB_SHADOW is not set -# CONFIG_USE_BB_CRYPT is not set -# CONFIG_USE_BB_CRYPT_SHA is not set +CONFIG_USE_BB_CRYPT=y +CONFIG_USE_BB_CRYPT_SHA=y # 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_ADDGROUP is not set @@ -463,7 +489,6 @@ CONFIG_LAST_SYSTEM_ID=0 # CONFIG_GETTY is not set # CONFIG_LOGIN is not set # CONFIG_LOGIN_SESSION_AS_CHILD is not set -# CONFIG_PAM is not set # CONFIG_LOGIN_SCRIPTS is not set # CONFIG_FEATURE_NOLOGIN is not set # CONFIG_FEATURE_SECURETTY is not set @@ -521,13 +546,26 @@ CONFIG_DEFAULT_DEPMOD_FILE="modules.dep" # Linux System Utilities # CONFIG_BLOCKDEV=y -CONFIG_MDEV=y -CONFIG_FEATURE_MDEV_CONF=y -CONFIG_FEATURE_MDEV_RENAME=y -CONFIG_FEATURE_MDEV_RENAME_REGEXP=y -CONFIG_FEATURE_MDEV_EXEC=y -CONFIG_FEATURE_MDEV_LOAD_FIRMWARE=y +CONFIG_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 is not set +# CONFIG_FEATURE_MOUNT_FAKE is not set +# CONFIG_FEATURE_MOUNT_VERBOSE is not set +# CONFIG_FEATURE_MOUNT_HELPERS is not set +# CONFIG_FEATURE_MOUNT_LABEL is not set +# CONFIG_FEATURE_MOUNT_NFS is not set +# CONFIG_FEATURE_MOUNT_CIFS is not set +# CONFIG_FEATURE_MOUNT_FLAGS is not set +# CONFIG_FEATURE_MOUNT_FSTAB is not set +# CONFIG_FEATURE_MOUNT_OTHERTAB is not set CONFIG_REV=y +CONFIG_UEVENT=y # CONFIG_ACPID is not set # CONFIG_FEATURE_ACPID_COMPAT is not set CONFIG_BLKID=y @@ -573,15 +611,6 @@ CONFIG_LSUSB=y CONFIG_MKSWAP=y CONFIG_FEATURE_MKSWAP_UUID=y CONFIG_MORE=y -# CONFIG_MOUNT is not set -# CONFIG_FEATURE_MOUNT_FAKE is not set -# CONFIG_FEATURE_MOUNT_VERBOSE is not set -# CONFIG_FEATURE_MOUNT_HELPERS is not set -# CONFIG_FEATURE_MOUNT_LABEL is not set -# CONFIG_FEATURE_MOUNT_NFS is not set -# CONFIG_FEATURE_MOUNT_CIFS is not set -# CONFIG_FEATURE_MOUNT_FLAGS is not set -# CONFIG_FEATURE_MOUNT_FSTAB is not set # CONFIG_PIVOT_ROOT is not set # CONFIG_RDATE is not set CONFIG_RDEV=y @@ -591,6 +620,7 @@ CONFIG_SCRIPT=y CONFIG_SCRIPTREPLAY=y # CONFIG_SETARCH is not set # 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 is not set @@ -603,32 +633,45 @@ CONFIG_VOLUMEID=y # # Filesystem/Volume identification # -CONFIG_FEATURE_VOLUMEID_EXT=y CONFIG_FEATURE_VOLUMEID_BTRFS=y -CONFIG_FEATURE_VOLUMEID_REISERFS=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_JFS=y -CONFIG_FEATURE_VOLUMEID_XFS=y -CONFIG_FEATURE_VOLUMEID_NTFS=y CONFIG_FEATURE_VOLUMEID_ISO9660=y -CONFIG_FEATURE_VOLUMEID_UDF=y -CONFIG_FEATURE_VOLUMEID_LUKS=y +CONFIG_FEATURE_VOLUMEID_JFS=y +CONFIG_FEATURE_VOLUMEID_LINUXRAID=y CONFIG_FEATURE_VOLUMEID_LINUXSWAP=y -CONFIG_FEATURE_VOLUMEID_CRAMFS=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=y CONFIG_FEATURE_VOLUMEID_SYSV=y -CONFIG_FEATURE_VOLUMEID_OCFS2=y -CONFIG_FEATURE_VOLUMEID_LINUXRAID=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 @@ -637,13 +680,17 @@ CONFIG_FEATURE_LESS_DASHCMD=y CONFIG_FEATURE_LESS_LINENUMS=y # CONFIG_NANDWRITE is not set CONFIG_NANDDUMP=y +# CONFIG_RFKILL is not set CONFIG_SETSERIAL=y +# CONFIG_TASKSET is not set +# CONFIG_FEATURE_TASKSET_FANCY 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_WALL is not set # CONFIG_ADJTIMEX is not set CONFIG_BBCONFIG=y CONFIG_FEATURE_COMPRESS_BBCONFIG=y @@ -659,10 +706,6 @@ CONFIG_FEATURE_CHAT_SEND_ESCAPES=y CONFIG_FEATURE_CHAT_VAR_ABORT_LEN=y CONFIG_FEATURE_CHAT_CLR_ABORT=y CONFIG_CHRT=y -CONFIG_CROND=y -CONFIG_FEATURE_CROND_D=y -CONFIG_FEATURE_CROND_CALL_SENDMAIL=y -CONFIG_FEATURE_CROND_DIR="/var/spool/cron" CONFIG_CRONTAB=y CONFIG_DC=y CONFIG_FEATURE_DC_LIBM=y @@ -700,18 +743,14 @@ CONFIG_MAN=y # CONFIG_MT is not set CONFIG_RAIDAUTORUN=y # CONFIG_READAHEAD is not set -# CONFIG_RFKILL is not set # CONFIG_RUNLEVEL is not set CONFIG_RX=y CONFIG_SETSID=y CONFIG_STRINGS=y -# CONFIG_TASKSET is not set -# CONFIG_FEATURE_TASKSET_FANCY is not set CONFIG_TIME=y CONFIG_TIMEOUT=y CONFIG_TTYSIZE=y CONFIG_VOLNAME=y -# CONFIG_WALL is not set # CONFIG_WATCHDOG is not set # @@ -743,13 +782,13 @@ 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 is not set # CONFIG_HOSTNAME is not set CONFIG_HTTPD=y CONFIG_FEATURE_HTTPD_RANGES=y -CONFIG_FEATURE_HTTPD_USE_SENDFILE=y CONFIG_FEATURE_HTTPD_SETUID=y CONFIG_FEATURE_HTTPD_BASIC_AUTH=y # CONFIG_FEATURE_HTTPD_AUTH_MD5 is not set @@ -806,6 +845,7 @@ CONFIG_FEATURE_NETSTAT_PRG=y # CONFIG_NSLOOKUP is not set # CONFIG_NTPD is not set # CONFIG_FEATURE_NTPD_SERVER is not set +# CONFIG_FEATURE_NTPD_CONF is not set CONFIG_PSCAN=y CONFIG_ROUTE=y # CONFIG_SLATTACH is not set @@ -843,6 +883,7 @@ CONFIG_FEATURE_TUNCTL_UG=y CONFIG_DHCPD_LEASES_FILE="" CONFIG_UDHCPC=y CONFIG_FEATURE_UDHCPC_ARPING=y +CONFIG_FEATURE_UDHCPC_SANITIZEOPT=y CONFIG_FEATURE_UDHCP_PORT=y CONFIG_UDHCP_DEBUG=9 CONFIG_FEATURE_UDHCP_RFC3397=y @@ -889,6 +930,13 @@ 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 @@ -909,13 +957,6 @@ CONFIG_FEATURE_PS_ADDITIONAL_COLUMNS=y # CONFIG_FEATURE_PS_UNUSUAL_SYSTEMS is not set CONFIG_RENICE=y CONFIG_BB_SYSCTL=y -CONFIG_TOP=y -CONFIG_FEATURE_TOP_CPU_USAGE_PERCENTAGE=y -CONFIG_FEATURE_TOP_CPU_GLOBAL_PERCENTS=y -CONFIG_FEATURE_TOP_SMP_CPU=y -CONFIG_FEATURE_TOP_DECIMALS=y -CONFIG_FEATURE_TOP_SMP_PROCESS=y -CONFIG_FEATURE_TOPMEM=y CONFIG_FEATURE_SHOW_THREADS=y CONFIG_WATCH=y @@ -961,6 +1002,7 @@ CONFIG_SOFTLIMIT=y # CONFIG_ASH_BUILTIN_ECHO is not set # CONFIG_ASH_BUILTIN_PRINTF is not set # CONFIG_ASH_BUILTIN_TEST is not set +# CONFIG_ASH_HELP is not set # CONFIG_ASH_CMDCMD is not set # CONFIG_ASH_MAIL is not set # CONFIG_ASH_OPTIMIZE_FOR_SIZE is not set @@ -1010,6 +1052,7 @@ CONFIG_FEATURE_SYSLOGD_READ_BUFFER_SIZE=0 CONFIG_FEATURE_IPC_SYSLOG_BUFFER_SIZE=0 # CONFIG_LOGREAD is not set # CONFIG_FEATURE_LOGREAD_REDUCED_LOCKING is not set +# CONFIG_FEATURE_KMSG_SYSLOG is not set CONFIG_KLOGD=y CONFIG_FEATURE_KLOGD_KLOGCTL=y # CONFIG_LOGGER is not set -- cgit v1.2.3-55-g6feb From 4700fb5bead95d6457b943351b7dc6f49a09683e Mon Sep 17 00:00:00 2001 From: Denys Vlasenko <vda.linux@googlemail.com> Date: Fri, 9 Oct 2015 15:40:13 +0200 Subject: ash: make dowait() a bit more readable. Logic is unchanged Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com> --- shell/ash.c | 58 +++++++++++++++++++++++++++------------------------------- 1 file changed, 27 insertions(+), 31 deletions(-) diff --git a/shell/ash.c b/shell/ash.c index 7d20b8860..38ff4b62e 100644 --- a/shell/ash.c +++ b/shell/ash.c @@ -3919,19 +3919,15 @@ sprint_status48(char *s, int status, int sigonly) col = 0; if (!WIFEXITED(status)) { -#if JOBS - if (WIFSTOPPED(status)) + if (JOBS && WIFSTOPPED(status)) st = WSTOPSIG(status); else -#endif st = WTERMSIG(status); if (sigonly) { if (st == SIGINT || st == SIGPIPE) goto out; -#if JOBS - if (WIFSTOPPED(status)) + if (JOBS && WIFSTOPPED(status)) goto out; -#endif } st &= 0x7f; //TODO: use bbox's get_signame? strsignal adds ~600 bytes to text+rodata @@ -3955,7 +3951,6 @@ dowait(int wait_flags, struct job *job) int status; struct job *jp; struct job *thisjob; - int state; TRACE(("dowait(0x%x) called\n", wait_flags)); @@ -3973,11 +3968,12 @@ dowait(int wait_flags, struct job *job) INT_OFF; thisjob = NULL; for (jp = curjob; jp; jp = jp->prev_job) { + int jobstate; struct procstat *ps; struct procstat *psend; if (jp->state == JOBDONE) continue; - state = JOBDONE; + jobstate = JOBDONE; ps = jp->ps; psend = ps + jp->nprocs; do { @@ -3989,41 +3985,41 @@ dowait(int wait_flags, struct job *job) thisjob = jp; } if (ps->ps_status == -1) - state = JOBRUNNING; + jobstate = JOBRUNNING; #if JOBS - if (state == JOBRUNNING) + if (jobstate == JOBRUNNING) continue; if (WIFSTOPPED(ps->ps_status)) { jp->stopstatus = ps->ps_status; - state = JOBSTOPPED; + jobstate = JOBSTOPPED; } #endif } while (++ps < psend); - if (thisjob) - goto gotjob; - } -#if JOBS - if (!WIFSTOPPED(status)) -#endif - jobless--; - goto out; - - gotjob: - if (state != JOBRUNNING) { - thisjob->changed = 1; + if (!thisjob) + continue; - if (thisjob->state != state) { - TRACE(("Job %d: changing state from %d to %d\n", - jobno(thisjob), thisjob->state, state)); - thisjob->state = state; + /* Found the job where one of its processes changed its state. + * Is there at least one live and running process in this job? */ + if (jobstate != JOBRUNNING) { + /* No. All live processes in the job are stopped + * (JOBSTOPPED) or there are no live processes (JOBDONE) + */ + thisjob->changed = 1; + if (thisjob->state != jobstate) { + TRACE(("Job %d: changing state from %d to %d\n", + jobno(thisjob), thisjob->state, jobstate)); + thisjob->state = jobstate; #if JOBS - if (state == JOBSTOPPED) { - set_curjob(thisjob, CUR_STOPPED); - } + if (jobstate == JOBSTOPPED) + set_curjob(thisjob, CUR_STOPPED); #endif + } } + goto out; } - + /* The process wasn't found in job list */ + if (JOBS && !WIFSTOPPED(status)) + jobless--; out: INT_ON; -- cgit v1.2.3-55-g6feb From 2384162f6462f232a0d709e64f7d20bb3dbca503 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko <vda.linux@googlemail.com> Date: Fri, 9 Oct 2015 15:52:03 +0200 Subject: ash: simplify "you have mail" code function old new delta mailtime_hash - 4 +4 redirect 1282 1280 -2 mailtime 40 - -40 cmdloop 429 378 -51 ------------------------------------------------------------------------------ (add/remove: 1/1 grow/shrink: 0/2 up/down: 4/-93) Total: -89 bytes Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com> --- shell/ash.c | 25 +++++++++++-------------- 1 file changed, 11 insertions(+), 14 deletions(-) diff --git a/shell/ash.c b/shell/ash.c index 38ff4b62e..07e7f621a 100644 --- a/shell/ash.c +++ b/shell/ash.c @@ -10029,10 +10029,8 @@ setinputstring(char *string) #if ENABLE_ASH_MAIL -#define MAXMBOXES 10 - -/* times of mailboxes */ -static time_t mailtime[MAXMBOXES]; +/* Hash of mtimes of mailboxes */ +static unsigned mailtime_hash; /* Set if MAIL or MAILPATH is changed. */ static smallint mail_var_path_changed; @@ -10048,13 +10046,14 @@ chkmail(void) const char *mpath; char *p; char *q; - time_t *mtp; + unsigned new_hash; struct stackmark smark; struct stat statb; setstackmark(&smark); mpath = mpathset() ? mpathval() : mailval(); - for (mtp = mailtime; mtp < mailtime + MAXMBOXES; mtp++) { + new_hash = 0; + for (;;) { p = path_advance(&mpath, nullstr); if (p == NULL) break; @@ -10068,16 +10067,14 @@ chkmail(void) #endif q[-1] = '\0'; /* delete trailing '/' */ if (stat(p, &statb) < 0) { - *mtp = 0; continue; } - if (!mail_var_path_changed && statb.st_mtime != *mtp) { - fprintf( - stderr, "%s\n", - pathopt ? pathopt : "you have mail" - ); - } - *mtp = statb.st_mtime; + /* Very simplistic "hash": just a sum of all mtimes */ + new_hash += (unsigned)statb.st_mtime; + } + if (!mail_var_path_changed && mailtime_hash != new_hash) { + mailtime_hash = new_hash; + out2str("you have mail\n"); } mail_var_path_changed = 0; popstackmark(&smark); -- cgit v1.2.3-55-g6feb From 4cd99e7c6c1af77721b890ed5ae26d747796c4bd Mon Sep 17 00:00:00 2001 From: Denys Vlasenko <vda.linux@googlemail.com> Date: Fri, 9 Oct 2015 16:02:53 +0200 Subject: ash: "you have mail" should ignore first change in mtime Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com> --- shell/ash.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/shell/ash.c b/shell/ash.c index 07e7f621a..b09681296 100644 --- a/shell/ash.c +++ b/shell/ash.c @@ -10073,8 +10073,9 @@ chkmail(void) new_hash += (unsigned)statb.st_mtime; } if (!mail_var_path_changed && mailtime_hash != new_hash) { + if (mailtime_hash != 0) + out2str("you have mail\n"); mailtime_hash = new_hash; - out2str("you have mail\n"); } mail_var_path_changed = 0; popstackmark(&smark); -- cgit v1.2.3-55-g6feb From 550bf5b4a418378cd8f9fbbf5252fe57acdacb5a Mon Sep 17 00:00:00 2001 From: Denys Vlasenko <vda.linux@googlemail.com> Date: Fri, 9 Oct 2015 16:42:57 +0200 Subject: remove global "jmp_buf die_jmp" from !FEATURE_PREFER_APPLETS builds function old new delta xfunc_has_died - 21 +21 sleep_much - 12 +12 sleep10 - 9 +9 die_func - 4 +4 fflush_stdout_and_exit 35 36 +1 builtin_type 121 119 -2 die_sleep 4 - -4 xfunc_die 60 24 -36 hush_main 1128 1011 -117 die_jmp 156 - -156 ------------------------------------------------------------------------------ (add/remove: 4/2 grow/shrink: 1/3 up/down: 47/-315) Total: -268 bytes text data bss dec hex filename 939992 992 17652 958636 ea0ac busybox_old 939880 992 17496 958368 e9fa0 busybox_unstripped Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com> --- include/libbb.h | 3 +-- init/init.c | 9 +++++++-- libbb/fflush_stdout_and_exit.c | 13 ++++--------- libbb/vfork_daemon_rexec.c | 39 +++++++++++++++++++++++++-------------- libbb/xfunc_die.c | 26 ++++---------------------- loginutils/getty.c | 7 ++++++- shell/hush.c | 25 ++++++++++++++----------- 7 files changed, 61 insertions(+), 61 deletions(-) diff --git a/include/libbb.h b/include/libbb.h index d79843a2d..2f24ecbc3 100644 --- a/include/libbb.h +++ b/include/libbb.h @@ -1127,9 +1127,8 @@ enum { extern const char *msg_eol; extern smallint syslog_level; extern smallint logmode; -extern int die_sleep; extern uint8_t xfunc_error_retval; -extern jmp_buf die_jmp; +extern void (*die_func)(void); extern void xfunc_die(void) NORETURN FAST_FUNC; extern void bb_show_usage(void) NORETURN FAST_FUNC; extern void bb_error_msg(const char *s, ...) __attribute__ ((format (printf, 1, 2))) FAST_FUNC; diff --git a/init/init.c b/init/init.c index b2fe85635..80c5d0f74 100644 --- a/init/init.c +++ b/init/init.c @@ -1015,6 +1015,11 @@ void handle_sigsegv(int sig, siginfo_t *info, void *ucontext) } #endif +static void sleep_much(void) +{ + sleep(30 * 24*60*60); +} + int init_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; int init_main(int argc UNUSED_PARAM, char **argv) { @@ -1051,12 +1056,12 @@ int init_main(int argc UNUSED_PARAM, char **argv) /* If, say, xmalloc would ever die, we don't want to oops kernel * by exiting. - * NB: we set die_sleep *after* PID 1 check and bb_show_usage. + * NB: we set die_func *after* PID 1 check and bb_show_usage. * Otherwise, for example, "init u" ("please rexec yourself" * command for sysvinit) will show help text (which isn't too bad), * *and sleep forever* (which is bad!) */ - die_sleep = 30 * 24*60*60; + die_func = sleep_much; /* Figure out where the default console should be */ console_init(); diff --git a/libbb/fflush_stdout_and_exit.c b/libbb/fflush_stdout_and_exit.c index 9ad5dbf96..b4bed865f 100644 --- a/libbb/fflush_stdout_and_exit.c +++ b/libbb/fflush_stdout_and_exit.c @@ -15,15 +15,10 @@ void FAST_FUNC fflush_stdout_and_exit(int retval) { + xfunc_error_retval = retval; if (fflush(stdout)) bb_perror_msg_and_die(bb_msg_standard_output); - - if (ENABLE_FEATURE_PREFER_APPLETS && die_sleep < 0) { - /* We are in NOFORK applet. Do not exit() directly, - * but use xfunc_die() */ - xfunc_error_retval = retval; - xfunc_die(); - } - - exit(retval); + /* In case we are in NOFORK applet. Do not exit() directly, + * but use xfunc_die() */ + xfunc_die(); } diff --git a/libbb/vfork_daemon_rexec.c b/libbb/vfork_daemon_rexec.c index ed1f86f0c..d6ca7b263 100644 --- a/libbb/vfork_daemon_rexec.c +++ b/libbb/vfork_daemon_rexec.c @@ -69,28 +69,44 @@ pid_t FAST_FUNC xspawn(char **argv) } #if ENABLE_FEATURE_PREFER_APPLETS +static jmp_buf die_jmp; +static void jump(void) +{ + /* Special case. We arrive here if NOFORK applet + * calls xfunc, which then decides to die. + * We don't die, but jump instead back to caller. + * NOFORK applets still cannot carelessly call xfuncs: + * p = xmalloc(10); + * q = xmalloc(10); // BUG! if this dies, we leak p! + */ + /* | 0x100 allows to pass zero exitcode (longjmp can't pass 0). + * This works because exitcodes are bytes, + * run_nofork_applet() ensures that by "& 0xff" */ + longjmp(die_jmp, xfunc_error_retval | 0x100); +} + struct nofork_save_area { jmp_buf die_jmp; + void (*die_func)(void); const char *applet_name; uint32_t option_mask32; - int die_sleep; uint8_t xfunc_error_retval; }; static void save_nofork_data(struct nofork_save_area *save) { memcpy(&save->die_jmp, &die_jmp, sizeof(die_jmp)); + save->die_func = die_func; save->applet_name = applet_name; - save->xfunc_error_retval = xfunc_error_retval; save->option_mask32 = option_mask32; - save->die_sleep = die_sleep; + save->xfunc_error_retval = xfunc_error_retval; } static void restore_nofork_data(struct nofork_save_area *save) { memcpy(&die_jmp, &save->die_jmp, sizeof(die_jmp)); + die_func = save->die_func; applet_name = save->applet_name; - xfunc_error_retval = save->xfunc_error_retval; option_mask32 = save->option_mask32; - die_sleep = save->die_sleep; + xfunc_error_retval = save->xfunc_error_retval; } int FAST_FUNC run_nofork_applet(int applet_no, char **argv) @@ -133,11 +149,8 @@ int FAST_FUNC run_nofork_applet(int applet_no, char **argv) while (argv[argc]) argc++; - /* Special flag for xfunc_die(). If xfunc will "die" - * in NOFORK applet, xfunc_die() sees negative - * die_sleep and longjmp here instead. */ - die_sleep = -1; - + /* If xfunc "dies" in NOFORK applet, die_func longjmp's here instead */ + die_func = jump; rc = setjmp(die_jmp); if (!rc) { /* Some callers (xargs) @@ -146,10 +159,8 @@ int FAST_FUNC run_nofork_applet(int applet_no, char **argv) memcpy(tmp_argv, argv, (argc+1) * sizeof(tmp_argv[0])); /* Finally we can call NOFORK applet's main() */ rc = applet_main[applet_no](argc, tmp_argv); - } else { /* xfunc died in NOFORK applet */ - /* in case they meant to return 0... */ - if (rc == -2222) - rc = 0; + } else { + /* xfunc died in NOFORK applet */ } /* Restoring some globals */ diff --git a/libbb/xfunc_die.c b/libbb/xfunc_die.c index 204e5e49d..73f7998e5 100644 --- a/libbb/xfunc_die.c +++ b/libbb/xfunc_die.c @@ -7,34 +7,16 @@ * Licensed under GPLv2, see file LICENSE in this source tree. */ -/* Keeping it separate allows to NOT suck in stdio for VERY small applets. +/* Keeping it separate allows to NOT pull in stdio for VERY small applets. * Try building busybox with only "true" enabled... */ #include "libbb.h" -int die_sleep; -#if ENABLE_FEATURE_PREFER_APPLETS || ENABLE_HUSH -jmp_buf die_jmp; -#endif +void (*die_func)(void); void FAST_FUNC xfunc_die(void) { - if (die_sleep) { - if ((ENABLE_FEATURE_PREFER_APPLETS || ENABLE_HUSH) - && die_sleep < 0 - ) { - /* Special case. We arrive here if NOFORK applet - * calls xfunc, which then decides to die. - * We don't die, but jump instead back to caller. - * NOFORK applets still cannot carelessly call xfuncs: - * p = xmalloc(10); - * q = xmalloc(10); // BUG! if this dies, we leak p! - */ - /* -2222 means "zero" (longjmp can't pass 0) - * run_nofork_applet() catches -2222. */ - longjmp(die_jmp, xfunc_error_retval ? xfunc_error_retval : -2222); - } - sleep(die_sleep); - } + if (die_func) + die_func(); exit(xfunc_error_retval); } diff --git a/loginutils/getty.c b/loginutils/getty.c index 174542841..762d5c773 100644 --- a/loginutils/getty.c +++ b/loginutils/getty.c @@ -520,6 +520,11 @@ static void alarm_handler(int sig UNUSED_PARAM) _exit(EXIT_SUCCESS); } +static void sleep10(void) +{ + sleep(10); +} + int getty_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; int getty_main(int argc UNUSED_PARAM, char **argv) { @@ -599,7 +604,7 @@ int getty_main(int argc UNUSED_PARAM, char **argv) close(n--); /* Logging. We want special flavor of error_msg_and_die */ - die_sleep = 10; + die_func = sleep10; msg_eol = "\r\n"; /* most likely will internally use fd #3 in CLOEXEC mode: */ openlog(applet_name, LOG_PID, LOG_AUTH); diff --git a/shell/hush.c b/shell/hush.c index f085ed3eb..0d107715f 100644 --- a/shell/hush.c +++ b/shell/hush.c @@ -1479,10 +1479,11 @@ static sighandler_t install_sighandler(int sig, sighandler_t handler) #if ENABLE_HUSH_JOB +static void xfunc_has_died(void); /* After [v]fork, in child: do not restore tty pgrp on xfunc death */ -# define disable_restore_tty_pgrp_on_exit() (die_sleep = 0) +# define disable_restore_tty_pgrp_on_exit() (die_func = NULL) /* After [v]fork, in parent: restore tty pgrp on xfunc death */ -# define enable_restore_tty_pgrp_on_exit() (die_sleep = -1) +# define enable_restore_tty_pgrp_on_exit() (die_func = xfunc_has_died) /* Restores tty foreground process group, and exits. * May be called as signal handler for fatal signal @@ -1587,6 +1588,15 @@ static void hush_exit(int exitcode) #endif } +static void xfunc_has_died(void) NORETURN; +static void xfunc_has_died(void) +{ + /* xfunc has failed! die die die */ + /* no EXIT traps, this is an escape hatch! */ + G.exiting = 1; + hush_exit(xfunc_error_retval); +} + //TODO: return a mask of ALL handled sigs? static int check_and_run_traps(void) @@ -7866,12 +7876,7 @@ int hush_main(int argc, char **argv) /* Initialize some more globals to non-zero values */ cmdedit_update_prompt(); - if (setjmp(die_jmp)) { - /* xfunc has failed! die die die */ - /* no EXIT traps, this is an escape hatch! */ - G.exiting = 1; - hush_exit(xfunc_error_retval); - } + die_func = xfunc_has_died; /* Shell is non-interactive at first. We need to call * install_special_sighandlers() if we are going to execute "sh <script>", @@ -8129,9 +8134,7 @@ int hush_main(int argc, char **argv) /* Grab control of the terminal */ tcsetpgrp(G_interactive_fd, getpid()); } - /* -1 is special - makes xfuncs longjmp, not exit - * (we reset die_sleep = 0 whereever we [v]fork) */ - enable_restore_tty_pgrp_on_exit(); /* sets die_sleep = -1 */ + enable_restore_tty_pgrp_on_exit(); # if ENABLE_HUSH_SAVEHISTORY && MAX_HISTORY > 0 { -- cgit v1.2.3-55-g6feb From e52da5570eb93d6cb2950e55c48bd22edb5a9f18 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko <vda.linux@googlemail.com> Date: Fri, 9 Oct 2015 17:59:56 +0200 Subject: libbb: auto_string() for efficient handling of temporary malloced stirngs Use it in libiproute: get rid of one static string buffer. function old new delta auto_string - 51 +51 ll_index_to_name 10 49 +39 buffer_fill_and_print 169 178 +9 scan_recursive 378 380 +2 decode_one_format 732 734 +2 cmdputs 334 332 -2 static.cur_saved 4 1 -3 static.nbuf 16 - -16 printable_string 94 57 -37 ll_idx_n2a 53 - -53 ------------------------------------------------------------------------------ (add/remove: 2/2 grow/shrink: 4/3 up/down: 103/-111) Total: -8 bytes text data bss dec hex filename 939880 992 17496 958368 e9fa0 busybox_old 939880 992 17480 958352 e9f90 busybox_unstripped Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com> --- include/libbb.h | 1 + libbb/auto_string.c | 23 +++++++++++++++++++++++ libbb/printable_string.c | 10 +--------- networking/libiproute/ll_map.c | 13 +++++++------ networking/libiproute/ll_map.h | 2 +- 5 files changed, 33 insertions(+), 16 deletions(-) create mode 100644 libbb/auto_string.c diff --git a/include/libbb.h b/include/libbb.h index 2f24ecbc3..a8ceb449c 100644 --- a/include/libbb.h +++ b/include/libbb.h @@ -692,6 +692,7 @@ int bb_putchar(int ch) FAST_FUNC; /* Note: does not use stdio, writes to fd 2 directly */ int bb_putchar_stderr(char ch) FAST_FUNC; char *xasprintf(const char *format, ...) __attribute__ ((format(printf, 1, 2))) FAST_FUNC RETURNS_MALLOC; +char *auto_string(char *str) FAST_FUNC; // gcc-4.1.1 still isn't good enough at optimizing it // (+200 bytes compared to macro) //static ALWAYS_INLINE diff --git a/libbb/auto_string.c b/libbb/auto_string.c new file mode 100644 index 000000000..ae940069a --- /dev/null +++ b/libbb/auto_string.c @@ -0,0 +1,23 @@ +/* vi: set sw=4 ts=4: */ +/* + * Utility routines. + * + * Copyright (C) 2015 Denys Vlasenko + * + * Licensed under GPLv2, see file LICENSE in this source tree. + */ +//kbuild:lib-y += auto_string.o + +#include "libbb.h" + +char* FAST_FUNC auto_string(char *str) +{ + static char *saved[4]; + static uint8_t cur_saved; /* = 0 */ + + free(saved[cur_saved]); + saved[cur_saved] = str; + cur_saved = (cur_saved + 1) & (ARRAY_SIZE(saved)-1); + + return str; +} diff --git a/libbb/printable_string.c b/libbb/printable_string.c index a316f60de..077d58d32 100644 --- a/libbb/printable_string.c +++ b/libbb/printable_string.c @@ -11,9 +11,6 @@ const char* FAST_FUNC printable_string(uni_stat_t *stats, const char *str) { - static char *saved[4]; - static unsigned cur_saved; /* = 0 */ - char *dst; const char *s; @@ -56,10 +53,5 @@ const char* FAST_FUNC printable_string(uni_stat_t *stats, const char *str) } } #endif - - free(saved[cur_saved]); - saved[cur_saved] = dst; - cur_saved = (cur_saved + 1) & (ARRAY_SIZE(saved)-1); - - return dst; + return auto_string(dst); } diff --git a/networking/libiproute/ll_map.c b/networking/libiproute/ll_map.c index feb6e8d22..e2b85fc7b 100644 --- a/networking/libiproute/ll_map.c +++ b/networking/libiproute/ll_map.c @@ -86,7 +86,8 @@ int FAST_FUNC ll_remember_index(const struct sockaddr_nl *who UNUSED_PARAM, return 0; } -const char FAST_FUNC *ll_idx_n2a(int idx, char *buf) +static +const char FAST_FUNC *ll_idx_n2a(int idx/*, char *buf*/) { struct idxmap *im; @@ -95,15 +96,15 @@ const char FAST_FUNC *ll_idx_n2a(int idx, char *buf) im = find_by_index(idx); if (im) return im->name; - snprintf(buf, 16, "if%d", idx); - return buf; + //snprintf(buf, 16, "if%d", idx); + //return buf; + return auto_string(xasprintf("if%d", idx)); } const char FAST_FUNC *ll_index_to_name(int idx) { - static char nbuf[16]; - - return ll_idx_n2a(idx, nbuf); + //static char nbuf[16]; + return ll_idx_n2a(idx/*, nbuf*/); } #ifdef UNUSED diff --git a/networking/libiproute/ll_map.h b/networking/libiproute/ll_map.h index c5d383422..7ea383c81 100644 --- a/networking/libiproute/ll_map.h +++ b/networking/libiproute/ll_map.h @@ -7,8 +7,8 @@ PUSH_AND_SET_FUNCTION_VISIBILITY_TO_HIDDEN int ll_remember_index(const struct sockaddr_nl *who, struct nlmsghdr *n, void *arg) FAST_FUNC; int ll_init_map(struct rtnl_handle *rth) FAST_FUNC; int xll_name_to_index(const char *name) FAST_FUNC; +//static: const char *ll_idx_n2a(int idx, char *buf) FAST_FUNC; const char *ll_index_to_name(int idx) FAST_FUNC; -const char *ll_idx_n2a(int idx, char *buf) FAST_FUNC; /* int ll_index_to_type(int idx); */ unsigned ll_index_to_flags(int idx) FAST_FUNC; -- cgit v1.2.3-55-g6feb From 02859aaeb29fb83167364291f1ce26b54c23803b Mon Sep 17 00:00:00 2001 From: Denys Vlasenko <vda.linux@googlemail.com> Date: Fri, 9 Oct 2015 18:16:40 +0200 Subject: use auto_string() where appropriate to kill a few statics Custom linker script 'busybox_ldscript' found, using it function old new delta static.str 4 - -4 static.passwd 4 0 -4 bb_ask 322 311 -11 ether_print 63 47 -16 UNSPEC_print 82 66 -16 INET_sprint 59 38 -21 INET6_sprint 54 30 -24 make_human_readable_str 292 235 -57 ------------------------------------------------------------------------------ (add/remove: 0/1 grow/shrink: 0/7 up/down: 0/-153) Total: -153 bytes text data bss dec hex filename 939880 992 17480 958352 e9f90 busybox_old 939736 992 17456 958184 e9ee8 busybox_unstripped Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com> --- libbb/bb_askpass.c | 6 ++---- libbb/human_readable.c | 9 +-------- miscutils/devfsd.c | 19 +++++++++---------- networking/interface.c | 24 ++++++------------------ 4 files changed, 18 insertions(+), 40 deletions(-) diff --git a/libbb/bb_askpass.c b/libbb/bb_askpass.c index 1927ba9e9..c2580b9eb 100644 --- a/libbb/bb_askpass.c +++ b/libbb/bb_askpass.c @@ -1,7 +1,6 @@ /* vi: set sw=4 ts=4: */ /* * Ask for a password - * I use a static buffer in this function. Plan accordingly. * * Copyright (C) 1999-2004 by Erik Andersen <andersen@codepoet.org> * @@ -23,8 +22,8 @@ char* FAST_FUNC bb_ask(const int fd, int timeout, const char *prompt) { /* Was static char[BIGNUM] */ enum { sizeof_passwd = 128 }; - static char *passwd; + char *passwd; char *ret; int i; struct sigaction sa, oldsa; @@ -62,8 +61,7 @@ char* FAST_FUNC bb_ask(const int fd, int timeout, const char *prompt) alarm(timeout); } - if (!passwd) - passwd = xmalloc(sizeof_passwd); + passwd = auto_string(xmalloc(sizeof_passwd)); ret = passwd; i = 0; while (1) { diff --git a/libbb/human_readable.c b/libbb/human_readable.c index 0b2eb777e..5c7fc076f 100644 --- a/libbb/human_readable.c +++ b/libbb/human_readable.c @@ -37,8 +37,6 @@ const char* FAST_FUNC make_human_readable_str(unsigned long long val, '\0', 'K', 'M', 'G', 'T', 'P', 'E', 'Z', 'Y' }; - static char *str; - unsigned frac; /* 0..9 - the fractional digit */ const char *u; const char *fmt; @@ -81,12 +79,7 @@ const char* FAST_FUNC make_human_readable_str(unsigned long long val, #endif } - if (!str) { - /* sufficient for any width of val */ - str = xmalloc(sizeof(val)*3 + 2 + 3); - } - sprintf(str, fmt, val, frac, *u); - return str; + return auto_string(xasprintf(fmt, val, frac, *u)); } diff --git a/miscutils/devfsd.c b/miscutils/devfsd.c index 5a6aec6bd..9256567cc 100644 --- a/miscutils/devfsd.c +++ b/miscutils/devfsd.c @@ -1142,19 +1142,19 @@ static void signal_handler(int sig) static const char *get_variable(const char *variable, void *info) { - static char sbuf[sizeof(int)*3 + 2]; /* sign and NUL */ static char *hostname; struct get_variable_info *gv_info = info; const char *field_names[] = { - "hostname", "mntpt", "devpath", "devname", - "uid", "gid", "mode", hostname, mount_point, - gv_info->devpath, gv_info->devname, NULL + "hostname", "mntpt", "devpath", "devname", "uid", "gid", "mode", + NULL, mount_point, gv_info->devpath, gv_info->devname, NULL }; int i; if (!hostname) hostname = safe_gethostname(); + field_names[7] = hostname; + /* index_in_str_array returns i>=0 */ i = index_in_str_array(field_names, variable); @@ -1164,12 +1164,11 @@ static const char *get_variable(const char *variable, void *info) return field_names[i + 7]; if (i == 4) - sprintf(sbuf, "%u", gv_info->info->uid); - else if (i == 5) - sprintf(sbuf, "%u", gv_info->info->gid); - else if (i == 6) - sprintf(sbuf, "%o", gv_info->info->mode); - return sbuf; + return auto_string(xasprintf("%u", gv_info->info->uid)); + if (i == 5) + return auto_string(xasprintf("%u", gv_info->info->gid)); + /* i == 6 */ + return auto_string(xasprintf("%o", gv_info->info->mode)); } /* End Function get_variable */ static void service(struct stat statbuf, char *path) diff --git a/networking/interface.c b/networking/interface.c index b0572d04e..24bd13c57 100644 --- a/networking/interface.c +++ b/networking/interface.c @@ -89,13 +89,9 @@ struct in6_ifreq { /* Display an Internet socket address. */ static const char* FAST_FUNC INET_sprint(struct sockaddr *sap, int numeric) { - static char *buff; /* defaults to NULL */ - if (sap->sa_family == 0xFFFF || sap->sa_family == 0) return "[NONE SET]"; - free(buff); - buff = INET_rresolve((struct sockaddr_in *) sap, numeric, 0xffffff00); - return buff; + return auto_string(INET_rresolve((struct sockaddr_in *) sap, numeric, 0xffffff00)); } #ifdef UNUSED_AND_BUGGY @@ -171,13 +167,9 @@ static const struct aftype inet_aftype = { /* dirty! struct sockaddr usually doesn't suffer for inet6 addresses, fst. */ static const char* FAST_FUNC INET6_sprint(struct sockaddr *sap, int numeric) { - static char *buff; - if (sap->sa_family == 0xFFFF || sap->sa_family == 0) return "[NONE SET]"; - free(buff); - buff = INET6_rresolve((struct sockaddr_in6 *) sap, numeric); - return buff; + return auto_string(INET6_rresolve((struct sockaddr_in6 *) sap, numeric)); } #ifdef UNUSED @@ -223,13 +215,11 @@ static const struct aftype inet6_aftype = { /* Display an UNSPEC address. */ static char* FAST_FUNC UNSPEC_print(unsigned char *ptr) { - static char *buff; - + char *buff; char *pos; unsigned int i; - if (!buff) - buff = xmalloc(sizeof(struct sockaddr) * 3 + 1); + buff = auto_string(xmalloc(sizeof(struct sockaddr) * 3 + 1)); pos = buff; for (i = 0; i < sizeof(struct sockaddr); i++) { /* careful -- not every libc's sprintf returns # bytes written */ @@ -712,14 +702,12 @@ static const struct hwtype loop_hwtype = { /* Display an Ethernet address in readable format. */ static char* FAST_FUNC ether_print(unsigned char *ptr) { - static char *buff; - - free(buff); + char *buff; buff = xasprintf("%02X:%02X:%02X:%02X:%02X:%02X", (ptr[0] & 0377), (ptr[1] & 0377), (ptr[2] & 0377), (ptr[3] & 0377), (ptr[4] & 0377), (ptr[5] & 0377) ); - return buff; + return auto_string(buff); } static const struct hwtype ether_hwtype = { -- cgit v1.2.3-55-g6feb From 005c492c40ff833a99abd251872ec60661344474 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko <vda.linux@googlemail.com> Date: Sat, 10 Oct 2015 20:17:12 +0200 Subject: ash: shrink umask code function old new delta umaskcmd 258 248 -10 Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com> --- shell/ash.c | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/shell/ash.c b/shell/ash.c index b09681296..8a1628e81 100644 --- a/shell/ash.c +++ b/shell/ash.c @@ -12826,27 +12826,25 @@ umaskcmd(int argc UNUSED_PARAM, char **argv UNUSED_PARAM) if (*argptr == NULL) { if (symbolic_mode) { - char buf[sizeof("u=rwx,g=rwx,o=rwx")]; + char buf[sizeof(",u=rwx,g=rwx,o=rwx")]; char *p = buf; int i; i = 2; for (;;) { - unsigned bits; - + *p++ = ','; *p++ = permuser[i]; *p++ = '='; /* mask is 0..0uuugggooo. i=2 selects uuu bits */ - bits = (mask >> (i*3)); - if (!(bits & 4)) *p++ = 'r'; - if (!(bits & 2)) *p++ = 'w'; - if (!(bits & 1)) *p++ = 'x'; + if (!(mask & 0400)) *p++ = 'r'; + if (!(mask & 0200)) *p++ = 'w'; + if (!(mask & 0100)) *p++ = 'x'; + mask <<= 3; if (--i < 0) break; - *p++ = ','; } *p = '\0'; - puts(buf); + puts(buf + 1); } else { out1fmt("%04o\n", mask); } -- cgit v1.2.3-55-g6feb From 69c8c699aaa69e281e4a01be0f48a6498d3ac7cb Mon Sep 17 00:00:00 2001 From: Denys Vlasenko <vda.linux@googlemail.com> Date: Sun, 11 Oct 2015 16:27:55 +0200 Subject: randconfig fixes Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com> --- scripts/randomtest | 4 +++- testsuite/bzcat.tests | 16 +++++++++++----- testsuite/pwd/pwd-prints-working-directory | 5 ++++- testsuite/readlink.tests | 11 ++++++++--- 4 files changed, 26 insertions(+), 10 deletions(-) diff --git a/scripts/randomtest b/scripts/randomtest index d2b26bc76..e2513d058 100755 --- a/scripts/randomtest +++ b/scripts/randomtest @@ -65,14 +65,16 @@ if test x"$LIBC" = x"uclibc"; then | grep -v CONFIG_BUILD_LIBBUSYBOX \ | grep -v CONFIG_PIE \ \ - | grep -v CONFIG_FEATURE_TOUCH_NODEREF \ | grep -v CONFIG_FEATURE_2_4_MODULES \ + | grep -v CONFIG_FEATURE_SYNC_FANCY \ + | grep -v CONFIG_FEATURE_TOUCH_NODEREF \ >.config.new mv .config.new .config echo 'CONFIG_STATIC=y' >>.config echo '# CONFIG_BUILD_LIBBUSYBOX is not set' >>.config echo '# CONFIG_PIE is not set' >>.config 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 fi diff --git a/testsuite/bzcat.tests b/testsuite/bzcat.tests index 9a1c28425..2b38472ee 100755 --- a/testsuite/bzcat.tests +++ b/testsuite/bzcat.tests @@ -28,7 +28,10 @@ hello_bz2() { $ECHO -ne "\x17\x72\x45\x38\x50\x90\x5b\xb8\xe8\xa3" } -for ext in gz bz2 Z +for ext in \ + `test x"$CONFIG_GUNZIP=y = x"y" && echo gz` \ + `test x"$CONFIG_BUNZIP2=y = x"y" && echo bz2` \ + `test x"$CONFIG_UNCOMPRESS" = x"y" && echo Z` do prep() { rm -f t1.$ext t2.$ext t_actual @@ -49,11 +52,12 @@ do mkdir testdir 2>/dev/null ( cd testdir || { echo "cannot cd testdir!"; exit 1; } - expected="HELLO\nok\n" - prep; check "zcat: dont delete $ext src" "${bb}zcat t2.$ext; test -f t2.$ext && echo ok" - + prep + check "zcat: dont delete $ext src" "${bb}zcat t2.$ext; test -f t2.$ext && echo ok" + exit $FAILCOUNT ) + FAILCOUNT=$? rm -rf testdir done @@ -89,6 +93,7 @@ testing "bzcat can handle compressed zero-length bzip2 files" \ ## compress algorithm # "input" file is compressed (.Z) file with "a\n" data +test x"$CONFIG_UNCOMPRESS" = x"y" && \ testing "zcat can print many files" \ "$ECHO -ne '$hexdump' | zcat input input; echo \$?" \ "\ @@ -100,7 +105,8 @@ a " "" # "input" file is compressed (.Z) zero byte file -testing "zcat can handle compressed zero-length compressed (.Z) files" \ +test x"$CONFIG_UNCOMPRESS" = x"y" && \ +testing "zcat can handle compressed zero-length (.Z) files" \ "$ECHO -ne '$hexdump' | zcat input input; echo \$?" \ "0\n" \ "\x1f\x9d\x90\x00" "" diff --git a/testsuite/pwd/pwd-prints-working-directory b/testsuite/pwd/pwd-prints-working-directory index 8575347d6..971adb5a6 100644 --- a/testsuite/pwd/pwd-prints-working-directory +++ b/testsuite/pwd/pwd-prints-working-directory @@ -1 +1,4 @@ -test $(pwd) = $(busybox pwd) +# shell's $PWD may leave symlinks unresolved. +# "pwd" may be a built-in and have the same problem. +# External pwd _can't_ have that problem (current dir on Unix is physical). +test $(`which pwd`) = $(busybox pwd) diff --git a/testsuite/readlink.tests b/testsuite/readlink.tests index c7fc8adf0..e9d8da0fc 100755 --- a/testsuite/readlink.tests +++ b/testsuite/readlink.tests @@ -21,10 +21,15 @@ testing "readlink on a link" "readlink ./$TESTLINK" "./$TESTFILE\n" "" "" optional FEATURE_READLINK_FOLLOW -testing "readlink -f on a file" "readlink -f ./$TESTFILE" "$PWD/$TESTFILE\n" "" "" -testing "readlink -f on a link" "readlink -f ./$TESTLINK" "$PWD/$TESTFILE\n" "" "" +# shell's $PWD may leave symlinks unresolved. +# "pwd" may be a built-in and have the same problem. +# External pwd _can't_ have that problem (current dir on Unix is physical). +pwd=`which pwd` +pwd=`$pwd` +testing "readlink -f on a file" "readlink -f ./$TESTFILE" "$pwd/$TESTFILE\n" "" "" +testing "readlink -f on a link" "readlink -f ./$TESTLINK" "$pwd/$TESTFILE\n" "" "" testing "readlink -f on an invalid link" "readlink -f ./$FAILLINK" "" "" "" -testing "readlink -f on a wierd dir" "readlink -f $TESTDIR/../$TESTFILE" "$PWD/$TESTFILE\n" "" "" +testing "readlink -f on a wierd dir" "readlink -f $TESTDIR/../$TESTFILE" "$pwd/$TESTFILE\n" "" "" # clean up -- cgit v1.2.3-55-g6feb From 932302666b0354ede63504d1bef8393cab28db8b Mon Sep 17 00:00:00 2001 From: Denys Vlasenko <vda.linux@googlemail.com> Date: Sun, 11 Oct 2015 16:58:18 +0200 Subject: randconfig fix Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com> --- miscutils/last.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/miscutils/last.c b/miscutils/last.c index 6d8b58463..f8f34371a 100644 --- a/miscutils/last.c +++ b/miscutils/last.c @@ -34,7 +34,8 @@ && ((UT_LINESIZE != 32) || (UT_NAMESIZE != 32) || (UT_HOSTSIZE != 256)) #error struct utmpx member char[] size(s) have changed! #elif defined __UT_LINESIZE \ - && ((__UT_LINESIZE != 32) || (__UT_NAMESIZE != 64) || (__UT_HOSTSIZE != 256)) + && ((__UT_LINESIZE != 32) || (__UT_NAMESIZE != 32) || (__UT_HOSTSIZE != 256)) +/* __UT_NAMESIZE was checked with 64 above, but glibc-2.11 definitely uses 32! */ #error struct utmpx member char[] size(s) have changed! #endif -- cgit v1.2.3-55-g6feb From 85378cded7d088cbd048f6e6e127846f489d1fca Mon Sep 17 00:00:00 2001 From: Denys Vlasenko <vda.linux@googlemail.com> Date: Sun, 11 Oct 2015 21:47:11 +0200 Subject: hush: code shrink function old new delta builtin_wait 347 328 -19 Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com> --- shell/hush.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/shell/hush.c b/shell/hush.c index 0d107715f..eabe83ac6 100644 --- a/shell/hush.c +++ b/shell/hush.c @@ -9120,12 +9120,9 @@ static int FAST_FUNC builtin_wait(char **argv) return EXIT_FAILURE; } if (waitpid(pid, &status, 0) == pid) { + ret = WEXITSTATUS(status); if (WIFSIGNALED(status)) ret = 128 + WTERMSIG(status); - else if (WIFEXITED(status)) - ret = WEXITSTATUS(status); - else /* wtf? */ - ret = EXIT_FAILURE; } else { bb_perror_msg("wait %s", *argv); ret = 127; -- cgit v1.2.3-55-g6feb From 2dbbf823efe2e74458d5927e6b21310d72266b0f Mon Sep 17 00:00:00 2001 From: Denys Vlasenko <vda.linux@googlemail.com> Date: Sun, 11 Oct 2015 23:43:29 +0200 Subject: randconfig fixes Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com> --- testsuite/makedevs.tests | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/testsuite/makedevs.tests b/testsuite/makedevs.tests index fd12460ec..b51fe0798 100755 --- a/testsuite/makedevs.tests +++ b/testsuite/makedevs.tests @@ -25,7 +25,7 @@ FILTER_LS2="sed -e 's/, */,/g' -e 's/ */ /g' | cut -d' ' -f 1-4,9-" rm -rf makedevs.testdir mkdir makedevs.testdir -optional FEATURE_MAKEDEVS_TABLE FEATURE_FIND_NOT FEATURE_FIND_TYPE FEATURE_LS_RECURSIVE FEATURE_LS_SORTFILES +optional FEATURE_MAKEDEVS_TABLE FEATURE_FIND_NOT FEATURE_FIND_TYPE FEATURE_LS_RECURSIVE FEATURE_LS_SORTFILES FEATURE_LS_TIMESTAMPS testing "makedevs -d ../makedevs.device_table.txt ." \ "(cd makedevs.testdir && makedevs -d ../makedevs.device_table.txt . 2>&1); find makedevs.testdir ! -type d | sort | xargs ls -lnR | $FILTER_LS" \ -- cgit v1.2.3-55-g6feb From c8e5ead03ac97da5b8a864481c8a790cfe8dfe4d Mon Sep 17 00:00:00 2001 From: Denys Vlasenko <vda.linux@googlemail.com> Date: Mon, 12 Oct 2015 03:12:17 +0200 Subject: build system: remove special-casing for extra libs It is not reliable (tried on three systems, multiple problems). Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com> --- Config.in | 8 -------- Makefile.flags | 25 +++++++++++-------------- 2 files changed, 11 insertions(+), 22 deletions(-) diff --git a/Config.in b/Config.in index 11371c783..07b4bf36b 100644 --- a/Config.in +++ b/Config.in @@ -514,14 +514,6 @@ config PIE Most people will leave this set to 'N'. -config LINK_WITH_PTHREAD - bool "Link with pthread library" - default n - help - On some systems, some libraries (such as crypt) also require pthread. - - Select this only if your build otherwise fails. - config NOMMU bool "Force NOMMU build" default n diff --git a/Makefile.flags b/Makefile.flags index b6cd32e42..9f77674ba 100644 --- a/Makefile.flags +++ b/Makefile.flags @@ -129,22 +129,19 @@ else LDLIBS += m endif -ifeq ($(CONFIG_LINK_WITH_PTHREAD),y) -PTHREAD_AVAILABLE := $(shell echo 'int main(void){return 0;}' >pthreadtest.c; $(CC) $(CFLAGS) -lpthread -o /dev/null pthreadtest.c >/dev/null 2>&1 && echo "y"; rm pthreadtest.c) -ifeq ($(PTHREAD_AVAILABLE),y) -LDLIBS += pthread -endif -endif +# libpam may use libpthread, libdl and/or libaudit. +# On some platforms that requires an explicit -lpthread, -ldl, -laudit. +# However, on *other platforms* it fails when some of those flags +# given needlessly. On some systems, crypt needs pthread. +# +# I even had a system where a runtime test for pthread +# (similar to CRYPT_AVAILABLE test above) was not reliable. +# +# Do not propagate this mess by adding libraries to CONFIG_PAM/CRYPT_AVAILABLE blocks. +# Add libraries you need to CONFIG_EXTRA_LDLIBS instead. ifeq ($(CONFIG_PAM),y) -# libpam uses libpthread, libdl and libaudit, so for static builds busybox -# must be linked to libpthread, libdl and libaudit. On some platforms that -# requires an explicit -lpthread, -ldl and -laudit, so it should be in -# LDLIBS. For non-static builds, scripts/trylink will take care of removing -# these flags if possible. (Not bothering to check CONFIG_STATIC because -# even in a non-static build it could be that the only libpam available is -# libpam.a, so -lpthread & Co. could still be needed.) -LDLIBS += pam pam_misc pthread dl audit +LDLIBS += pam pam_misc endif ifeq ($(CONFIG_SELINUX),y) -- cgit v1.2.3-55-g6feb From 57aeb62f837f40deafd8896d0ae49e5e51a8d795 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko <vda.linux@googlemail.com> Date: Mon, 12 Oct 2015 03:15:36 +0200 Subject: randconfig fixes Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com> --- testsuite/bzcat.tests | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/testsuite/bzcat.tests b/testsuite/bzcat.tests index 2b38472ee..0ae530dc7 100755 --- a/testsuite/bzcat.tests +++ b/testsuite/bzcat.tests @@ -29,8 +29,8 @@ hello_bz2() { } for ext in \ - `test x"$CONFIG_GUNZIP=y = x"y" && echo gz` \ - `test x"$CONFIG_BUNZIP2=y = x"y" && echo bz2` \ + `test x"$CONFIG_GUNZIP" = x"y" && echo gz` \ + `test x"$CONFIG_BUNZIP2" = x"y" && echo bz2` \ `test x"$CONFIG_UNCOMPRESS" = x"y" && echo Z` do prep() { -- cgit v1.2.3-55-g6feb From 5de450237cf7ec63faa6ab4e019f66e053324c49 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko <vda.linux@googlemail.com> Date: Mon, 12 Oct 2015 04:06:18 +0200 Subject: libpwdgrp: do not require that /etc/passwd entries have nonempty home and shell Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com> --- libpwdgrp/pwd_grp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libpwdgrp/pwd_grp.c b/libpwdgrp/pwd_grp.c index 3886facf0..139b93007 100644 --- a/libpwdgrp/pwd_grp.c +++ b/libpwdgrp/pwd_grp.c @@ -58,7 +58,7 @@ struct passdb { * I = uid,gid, l = long maybe empty, m = members, * r = reserved */ -#define PW_DEF "SsIIsSS" +#define PW_DEF "SsIIsss" #define GR_DEF "SsIm" #define SP_DEF "Ssllllllr" -- cgit v1.2.3-55-g6feb From 7ab00a0de9cfeeacff70a74402808d225ba07397 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko <vda.linux@googlemail.com> Date: Mon, 12 Oct 2015 14:33:03 +0200 Subject: Bump version to 1.24.0 Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com> --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 65b2642f0..efb6d46b3 100644 --- a/Makefile +++ b/Makefile @@ -1,7 +1,7 @@ VERSION = 1 PATCHLEVEL = 24 SUBLEVEL = 0 -EXTRAVERSION = .git +EXTRAVERSION = NAME = Unnamed # *DOCUMENTATION* -- cgit v1.2.3-55-g6feb From 966423d4034067f52b419570a1016d1dfc4aeacd Mon Sep 17 00:00:00 2001 From: Denys Vlasenko <vda.linux@googlemail.com> Date: Mon, 12 Oct 2015 14:33:46 +0200 Subject: Start 1.25.0 development cycle Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com> --- 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* -- cgit v1.2.3-55-g6feb From b5dabd9078492c6b3366bab57a51e070b83f9b45 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko <vda.linux@googlemail.com> Date: Tue, 13 Oct 2015 00:31:02 +0200 Subject: libpwdgrp: fix comment discrepancies Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com> --- 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) }; -- cgit v1.2.3-55-g6feb From 450a367a11283d44811b8eec33afe5fa00a95f5f Mon Sep 17 00:00:00 2001 From: Denys Vlasenko <vda.linux@googlemail.com> Date: Tue, 13 Oct 2015 01:49:06 +0200 Subject: typo fix Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com> --- 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 } -- cgit v1.2.3-55-g6feb From 6390a3a4e5e44894a94b31b57a9b2a07a215f171 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko <vda.linux@googlemail.com> Date: Tue, 13 Oct 2015 01:51:37 +0200 Subject: whitespace fixes Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com> --- 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; -- cgit v1.2.3-55-g6feb From bf74fb44977d9b90c51dba19c1fd7f071147d955 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko <vda.linux@googlemail.com> Date: Tue, 13 Oct 2015 12:34:35 +0200 Subject: typo fix in comment Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com> --- 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 -- cgit v1.2.3-55-g6feb From f7ad927c2059ef9cd1cd6befeb43f26b92f6369f Mon Sep 17 00:00:00 2001 From: Denys Vlasenko <vda.linux@googlemail.com> Date: Tue, 13 Oct 2015 13:49:53 +0200 Subject: 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 <vda.linux@googlemail.com> --- 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 -- cgit v1.2.3-55-g6feb From ab3964db4e75e34f6f9347406c5fd2bced04f2dd Mon Sep 17 00:00:00 2001 From: Denys Vlasenko <vda.linux@googlemail.com> Date: Tue, 13 Oct 2015 14:50:20 +0200 Subject: libbb: introduce kernel-style BUILD_BUG_ON() Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com> --- 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 -- cgit v1.2.3-55-g6feb From 4d0c1ea4784c9844f8468d97ca5c26d3c70f9921 Mon Sep 17 00:00:00 2001 From: Ron Yorston <rmy@pobox.com> Date: Mon, 12 Oct 2015 10:51:25 +0100 Subject: 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 <rmy@pobox.com> Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com> --- 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); -- cgit v1.2.3-55-g6feb