From 726cbb1be8620496cdf05d23bd98bdeb0983b4f0 Mon Sep 17 00:00:00 2001 From: Jack O'Sullivan Date: Tue, 28 May 2019 15:28:27 +0100 Subject: losetup: Add partition scanning option Add -P option from util-linux losetup to scan for partitions. function old new delta losetup_main 449 482 +33 packed_usage 33264 33292 +28 ------------------------------------------------------------------------------ (add/remove: 0/0 grow/shrink: 2/0 up/down: 61/0) Total: 61 bytes Signed-off-by: Jack O'Sullivan Signed-off-by: Denys Vlasenko --- include/libbb.h | 1 + util-linux/losetup.c | 27 +++++++++++++++++---------- 2 files changed, 18 insertions(+), 10 deletions(-) diff --git a/include/libbb.h b/include/libbb.h index 33766e989..3a870bf80 100644 --- a/include/libbb.h +++ b/include/libbb.h @@ -1471,6 +1471,7 @@ extern int set_loop(char **devname, const char *file, unsigned long long offset, /* These constants match linux/loop.h (without BB_ prefix): */ #define BB_LO_FLAGS_READ_ONLY 1 #define BB_LO_FLAGS_AUTOCLEAR 4 +#define BB_LO_FLAGS_PARTSCAN 8 /* Returns malloced str */ char *bb_ask_noecho(int fd, int timeout, const char *prompt) FAST_FUNC; diff --git a/util-linux/losetup.c b/util-linux/losetup.c index 2248f2cba..b52d693ec 100644 --- a/util-linux/losetup.c +++ b/util-linux/losetup.c @@ -20,13 +20,14 @@ //kbuild:lib-$(CONFIG_LOSETUP) += losetup.o //usage:#define losetup_trivial_usage -//usage: "[-r] [-o OFS] {-f|LOOPDEV} FILE: associate loop devices\n" +//usage: "[-rP] [-o OFS] {-f|LOOPDEV} FILE: associate loop devices\n" //usage: " losetup -c LOOPDEV: reread file size\n" //usage: " losetup -d LOOPDEV: disassociate\n" //usage: " losetup -a: show status\n" //usage: " losetup -f: show next free loop device" //usage:#define losetup_full_usage "\n\n" //usage: " -o OFS Start OFS bytes into FILE" +//usage: "\n -P Scan for partitions" //usage: "\n -r Read-only" //usage: "\n -f Show/use next free loop device" //usage: @@ -35,8 +36,9 @@ //usage: "(if any), or disassociate it (with -d). The display shows the offset\n" //usage: "and filename of the file the loop device is currently bound to.\n\n" //usage: "Two arguments (losetup /dev/loop1 file.img) create a new association,\n" -//usage: "with an optional offset (-o 12345). Encryption is not yet supported.\n" -//usage: "losetup -f will show the first loop free loop device\n\n" +//usage: "with optional partition scanning (creates /dev/loop1p1, /dev/loop1p2\n" +//usage: "etc. with -P) and with an optional offset (-o 12345). Encryption is\n" +//usage: "not yet supported. losetup -f will show the first free loop device\n\n" #include "libbb.h" @@ -53,13 +55,14 @@ int losetup_main(int argc UNUSED_PARAM, char **argv) enum { OPT_c = (1 << 0), OPT_d = (1 << 1), - OPT_o = (1 << 2), - OPT_f = (1 << 3), - OPT_a = (1 << 4), - OPT_r = (1 << 5), + OPT_P = (1 << 2), + OPT_o = (1 << 3), + OPT_f = (1 << 4), + OPT_a = (1 << 5), + OPT_r = (1 << 6), }; - opt = getopt32(argv, "^" "cdo:far" "\0" "?2:d--ofar:a--ofr", &opt_o); + opt = getopt32(argv, "^" "cdPo:far" "\0" "?2:d--Pofar:a--Pofr", &opt_o); argv += optind; /* LOOPDEV */ @@ -127,7 +130,7 @@ int losetup_main(int argc UNUSED_PARAM, char **argv) } } - /* [-r] [-o OFS] {-f|LOOPDEV} FILE */ + /* [-rP] [-o OFS] {-f|LOOPDEV} FILE */ if (argv[0] && ((opt & OPT_f) || argv[1])) { unsigned long long offset = 0; char *d = dev; @@ -138,7 +141,11 @@ int losetup_main(int argc UNUSED_PARAM, char **argv) d = *argv++; if (argv[0]) { - if (set_loop(&d, argv[0], offset, (opt & OPT_r) ? BB_LO_FLAGS_READ_ONLY : 0) < 0) + unsigned flags = (opt & OPT_r) ? BB_LO_FLAGS_READ_ONLY : 0; + if (opt & OPT_P) { + flags |= BB_LO_FLAGS_PARTSCAN; + } + if (set_loop(&d, argv[0], offset, flags) < 0) bb_simple_perror_msg_and_die(argv[0]); return EXIT_SUCCESS; } -- cgit v1.2.3-55-g6feb From 91755cb16d496d1094f5d81051a1e1e6f27a21c1 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Thu, 30 May 2019 16:23:34 +0200 Subject: udhcp: rename server_config to server_data Signed-off-by: Denys Vlasenko --- networking/udhcp/dhcpd.c | 150 +++++++++++++++++++++++------------------------ networking/udhcp/dhcpd.h | 8 +-- 2 files changed, 79 insertions(+), 79 deletions(-) diff --git a/networking/udhcp/dhcpd.c b/networking/udhcp/dhcpd.c index 058f86bca..6e426e6a2 100644 --- a/networking/udhcp/dhcpd.c +++ b/networking/udhcp/dhcpd.c @@ -46,7 +46,7 @@ /* globals */ #define g_leases ((struct dyn_lease*)ptr_to_globals) -/* struct server_config_t server_config is in bb_common_bufsiz1 */ +/* struct server_data_t server_data is in bb_common_bufsiz1 */ struct static_lease { struct static_lease *next; @@ -100,7 +100,7 @@ static void add_static_lease(struct static_lease **st_lease_pp, /* Find static lease IP by mac */ static uint32_t get_static_nip_by_mac(void *mac) { - struct static_lease *st_lease = server_config.static_leases; + struct static_lease *st_lease = server_data.static_leases; while (st_lease) { if (memcmp(st_lease->mac, mac, 6) == 0) @@ -113,7 +113,7 @@ static uint32_t get_static_nip_by_mac(void *mac) static int is_nip_reserved_as_static(uint32_t nip) { - struct static_lease *st_lease = server_config.static_leases; + struct static_lease *st_lease = server_data.static_leases; while (st_lease) { if (st_lease->nip == nip) @@ -133,7 +133,7 @@ static struct dyn_lease *oldest_expired_lease(void) /* Unexpired leases have g_leases[i].expires >= current time * and therefore can't ever match */ - for (i = 0; i < server_config.max_leases; i++) { + for (i = 0; i < server_data.max_leases; i++) { if (g_leases[i].expires == 0 /* empty entry */ || g_leases[i].expires < oldest_time ) { @@ -151,7 +151,7 @@ static void clear_leases(const uint8_t *chaddr, uint32_t yiaddr) { unsigned i; - for (i = 0; i < server_config.max_leases; i++) { + for (i = 0; i < server_data.max_leases; i++) { if ((chaddr && memcmp(g_leases[i].lease_mac, chaddr, 6) == 0) || (yiaddr && g_leases[i].lease_nip == yiaddr) ) { @@ -216,7 +216,7 @@ static struct dyn_lease *find_lease_by_mac(const uint8_t *mac) { unsigned i; - for (i = 0; i < server_config.max_leases; i++) + for (i = 0; i < server_data.max_leases; i++) if (memcmp(g_leases[i].lease_mac, mac, 6) == 0) return &g_leases[i]; @@ -228,7 +228,7 @@ static struct dyn_lease *find_lease_by_nip(uint32_t nip) { unsigned i; - for (i = 0; i < server_config.max_leases; i++) + for (i = 0; i < server_data.max_leases; i++) if (g_leases[i].lease_nip == nip) return &g_leases[i]; @@ -242,17 +242,17 @@ static int nobody_responds_to_arp(uint32_t nip, const uint8_t *safe_mac, unsigne int r; r = arpping(nip, safe_mac, - server_config.server_nip, - server_config.server_mac, - server_config.interface, + server_data.server_nip, + server_data.server_mac, + server_data.interface, arpping_ms); if (r) return r; temp.s_addr = nip; bb_info_msg("%s belongs to someone, reserving it for %u seconds", - inet_ntoa(temp), (unsigned)server_config.conflict_time); - add_lease(NULL, nip, server_config.conflict_time, NULL, 0); + inet_ntoa(temp), (unsigned)server_data.conflict_time); + add_lease(NULL, nip, server_data.conflict_time, NULL, 0); return 0; } @@ -274,12 +274,12 @@ static uint32_t find_free_or_expired_nip(const uint8_t *safe_mac, unsigned arppi hash += safe_mac[i] + (hash << 6) + (hash << 16) - hash; /* pick a seed based on hwaddr then iterate until we find a free address. */ - addr = server_config.start_ip - + (hash % (1 + server_config.end_ip - server_config.start_ip)); + addr = server_data.start_ip + + (hash % (1 + server_data.end_ip - server_data.start_ip)); stop = addr; #else - addr = server_config.start_ip; -#define stop (server_config.end_ip + 1) + addr = server_data.start_ip; +#define stop (server_data.end_ip + 1) #endif do { uint32_t nip; @@ -293,7 +293,7 @@ static uint32_t find_free_or_expired_nip(const uint8_t *safe_mac, unsigned arppi goto next_addr; nip = htonl(addr); /* skip our own address */ - if (nip == server_config.server_nip) + if (nip == server_data.server_nip) goto next_addr; /* is this a static lease addr? */ if (is_nip_reserved_as_static(nip)) @@ -312,8 +312,8 @@ static uint32_t find_free_or_expired_nip(const uint8_t *safe_mac, unsigned arppi next_addr: addr++; #if ENABLE_FEATURE_UDHCPD_BASE_IP_ON_MAC - if (addr > server_config.end_ip) - addr = server_config.start_ip; + if (addr > server_data.end_ip) + addr = server_data.start_ip; #endif } while (addr != stop); @@ -386,7 +386,7 @@ struct config_keyword { const char *def; }; -#define OFS(field) offsetof(struct server_config_t, field) +#define OFS(field) offsetof(struct server_data_t, field) static const struct config_keyword keywords[] = { /* keyword handler variable address default */ @@ -422,17 +422,17 @@ static NOINLINE void read_config(const char *file) char *token[2]; for (i = 0; i < KWS_WITH_DEFAULTS; i++) - keywords[i].handler(keywords[i].def, (char*)&server_config + keywords[i].ofs); + keywords[i].handler(keywords[i].def, (char*)&server_data + keywords[i].ofs); parser = config_open(file); while (config_read(parser, token, 2, 2, "# \t", PARSE_NORMAL)) { for (k = keywords, i = 0; i < ARRAY_SIZE(keywords); k++, i++) { if (strcasecmp(token[0], k->keyword) == 0) { - if (!k->handler(token[1], (char*)&server_config + k->ofs)) { + if (!k->handler(token[1], (char*)&server_data + k->ofs)) { bb_error_msg("can't parse line %u in %s", parser->lineno, file); /* reset back to the default value */ - k->handler(k->def, (char*)&server_config + k->ofs); + k->handler(k->def, (char*)&server_data + k->ofs); } break; } @@ -440,8 +440,8 @@ static NOINLINE void read_config(const char *file) } config_close(parser); - server_config.start_ip = ntohl(server_config.start_ip); - server_config.end_ip = ntohl(server_config.end_ip); + server_data.start_ip = ntohl(server_data.start_ip); + server_data.end_ip = ntohl(server_data.end_ip); } static void write_leases(void) @@ -451,7 +451,7 @@ static void write_leases(void) leasetime_t curr; int64_t written_at; - fd = open_or_warn(server_config.lease_file, O_WRONLY|O_CREAT|O_TRUNC); + fd = open_or_warn(server_data.lease_file, O_WRONLY|O_CREAT|O_TRUNC); if (fd < 0) return; @@ -460,7 +460,7 @@ static void write_leases(void) written_at = SWAP_BE64(written_at); full_write(fd, &written_at, sizeof(written_at)); - for (i = 0; i < server_config.max_leases; i++) { + for (i = 0; i < server_data.max_leases; i++) { leasetime_t tmp_time; if (g_leases[i].lease_nip == 0) @@ -483,10 +483,10 @@ static void write_leases(void) } close(fd); - if (server_config.notify_file) { + if (server_data.notify_file) { char *argv[3]; - argv[0] = server_config.notify_file; - argv[1] = server_config.lease_file; + argv[0] = server_data.notify_file; + argv[1] = server_data.lease_file; argv[2] = NULL; spawn_and_wait(argv); } @@ -517,7 +517,7 @@ static NOINLINE void read_leases(const char *file) while (full_read(fd, &lease, sizeof(lease)) == sizeof(lease)) { uint32_t y = ntohl(lease.lease_nip); - if (y >= server_config.start_ip && y <= server_config.end_ip) { + if (y >= server_data.start_ip && y <= server_data.end_ip) { signed_leasetime_t expires = ntohl(lease.expires) - (signed_leasetime_t)time_passed; uint32_t static_nip; @@ -590,9 +590,9 @@ static void send_packet_to_client(struct dhcp_packet *dhcp_pkt, int force_broadc } udhcp_send_raw_packet(dhcp_pkt, - /*src*/ server_config.server_nip, SERVER_PORT, + /*src*/ server_data.server_nip, SERVER_PORT, /*dst*/ ciaddr, CLIENT_PORT, chaddr, - server_config.ifindex); + server_data.ifindex); } /* Send a packet to gateway_nip using the kernel ip stack */ @@ -601,7 +601,7 @@ static void send_packet_to_relay(struct dhcp_packet *dhcp_pkt) log1("forwarding packet to relay"); udhcp_send_kernel_packet(dhcp_pkt, - server_config.server_nip, SERVER_PORT, + server_data.server_nip, SERVER_PORT, dhcp_pkt->gateway_nip, SERVER_PORT); } @@ -633,7 +633,7 @@ static void init_packet(struct dhcp_packet *packet, struct dhcp_packet *oldpacke packet->flags = oldpacket->flags; packet->gateway_nip = oldpacket->gateway_nip; packet->ciaddr = oldpacket->ciaddr; - udhcp_add_simple_option(packet, DHCP_SERVER_ID, server_config.server_nip); + udhcp_add_simple_option(packet, DHCP_SERVER_ID, server_data.server_nip); } /* Fill options field, siaddr_nip, and sname and boot_file fields. @@ -646,7 +646,7 @@ static void add_server_options(struct dhcp_packet *packet) client_hostname_opt = NULL; if (packet->yiaddr) { /* if we aren't from send_inform()... */ - struct static_lease *st_lease = server_config.static_leases; + struct static_lease *st_lease = server_data.static_leases; while (st_lease) { if (st_lease->nip == packet->yiaddr) { if (st_lease->opt[0] != 0) @@ -657,7 +657,7 @@ static void add_server_options(struct dhcp_packet *packet) } } - config_opts = server_config.options; + config_opts = server_data.options; while (config_opts) { if (config_opts->data[OPT_CODE] != DHCP_LEASE_TIME) { /* ^^^^ @@ -684,25 +684,25 @@ static void add_server_options(struct dhcp_packet *packet) if (client_hostname_opt) udhcp_add_binary_option(packet, client_hostname_opt); - packet->siaddr_nip = server_config.siaddr_nip; + packet->siaddr_nip = server_data.siaddr_nip; - if (server_config.sname) - strncpy((char*)packet->sname, server_config.sname, sizeof(packet->sname) - 1); - if (server_config.boot_file) - strncpy((char*)packet->file, server_config.boot_file, sizeof(packet->file) - 1); + if (server_data.sname) + strncpy((char*)packet->sname, server_data.sname, sizeof(packet->sname) - 1); + if (server_data.boot_file) + strncpy((char*)packet->file, server_data.boot_file, sizeof(packet->file) - 1); } static uint32_t select_lease_time(struct dhcp_packet *packet) { - uint32_t lease_time_sec = server_config.max_lease_sec; + uint32_t lease_time_sec = server_data.max_lease_sec; uint8_t *lease_time_opt = udhcp_get_option32(packet, DHCP_LEASE_TIME); if (lease_time_opt) { move_from_unaligned32(lease_time_sec, lease_time_opt); lease_time_sec = ntohl(lease_time_sec); - if (lease_time_sec > server_config.max_lease_sec) - lease_time_sec = server_config.max_lease_sec; - if (lease_time_sec < server_config.min_lease_sec) - lease_time_sec = server_config.min_lease_sec; + if (lease_time_sec > server_data.max_lease_sec) + lease_time_sec = server_data.max_lease_sec; + if (lease_time_sec < server_data.min_lease_sec) + lease_time_sec = server_data.min_lease_sec; } return lease_time_sec; } @@ -737,8 +737,8 @@ static NOINLINE void send_offer(struct dhcp_packet *oldpacket, /* Or: if client has requested an IP */ else if (requested_nip != 0 /* and the IP is in the lease range */ - && ntohl(requested_nip) >= server_config.start_ip - && ntohl(requested_nip) <= server_config.end_ip + && ntohl(requested_nip) >= server_data.start_ip + && ntohl(requested_nip) <= server_data.end_ip /* and */ && ( !(lease = find_lease_by_nip(requested_nip)) /* is not already taken */ || is_expired_lease(lease) /* or is taken, but expired */ @@ -758,7 +758,7 @@ static NOINLINE void send_offer(struct dhcp_packet *oldpacket, /* Reserve the IP for a short time hoping to get DHCPREQUEST soon */ p_host_name = (const char*) udhcp_get_option(oldpacket, DHCP_HOST_NAME); lease = add_lease(packet.chaddr, packet.yiaddr, - server_config.offer_time, + server_data.offer_time, p_host_name, p_host_name ? (unsigned char)p_host_name[OPT_LEN - OPT_DATA] : 0 ); @@ -886,7 +886,7 @@ int udhcpd_main(int argc UNUSED_PARAM, char **argv) } if (opt & 4) { /* -I */ len_and_sockaddr *lsa = xhost_and_af2sockaddr(str_I, 0, AF_INET); - server_config.server_nip = lsa->u.sin.sin_addr.s_addr; + server_data.server_nip = lsa->u.sin.sin_addr.s_addr; free(lsa); } #if ENABLE_FEATURE_UDHCP_PORT @@ -901,42 +901,42 @@ int udhcpd_main(int argc UNUSED_PARAM, char **argv) * otherwise NOMMU machines will parse config twice */ read_config(argv[0] ? argv[0] : DHCPD_CONF_FILE); /* prevent poll timeout overflow */ - if (server_config.auto_time > INT_MAX / 1000) - server_config.auto_time = INT_MAX / 1000; + if (server_data.auto_time > INT_MAX / 1000) + server_data.auto_time = INT_MAX / 1000; /* Make sure fd 0,1,2 are open */ bb_sanitize_stdio(); /* Create pidfile */ - write_pidfile(server_config.pidfile); + write_pidfile(server_data.pidfile); /* if (!..) bb_perror_msg("can't create pidfile %s", pidfile); */ bb_info_msg("started, v"BB_VER); - option = udhcp_find_option(server_config.options, DHCP_LEASE_TIME); - server_config.max_lease_sec = DEFAULT_LEASE_TIME; + option = udhcp_find_option(server_data.options, DHCP_LEASE_TIME); + server_data.max_lease_sec = DEFAULT_LEASE_TIME; if (option) { - move_from_unaligned32(server_config.max_lease_sec, option->data + OPT_DATA); - server_config.max_lease_sec = ntohl(server_config.max_lease_sec); + move_from_unaligned32(server_data.max_lease_sec, option->data + OPT_DATA); + server_data.max_lease_sec = ntohl(server_data.max_lease_sec); } /* Sanity check */ - num_ips = server_config.end_ip - server_config.start_ip + 1; - if (server_config.max_leases > num_ips) { + num_ips = server_data.end_ip - server_data.start_ip + 1; + if (server_data.max_leases > num_ips) { bb_error_msg("max_leases=%u is too big, setting to %u", - (unsigned)server_config.max_leases, num_ips); - server_config.max_leases = num_ips; + (unsigned)server_data.max_leases, num_ips); + server_data.max_leases = num_ips; } /* this sets g_leases */ - SET_PTR_TO_GLOBALS(xzalloc(server_config.max_leases * sizeof(g_leases[0]))); + SET_PTR_TO_GLOBALS(xzalloc(server_data.max_leases * sizeof(g_leases[0]))); - read_leases(server_config.lease_file); + read_leases(server_data.lease_file); - if (udhcp_read_interface(server_config.interface, - &server_config.ifindex, - (server_config.server_nip == 0 ? &server_config.server_nip : NULL), - server_config.server_mac) + if (udhcp_read_interface(server_data.interface, + &server_data.ifindex, + (server_data.server_nip == 0 ? &server_data.server_nip : NULL), + server_data.server_mac) ) { retval = 1; goto ret; @@ -946,7 +946,7 @@ int udhcpd_main(int argc UNUSED_PARAM, char **argv) udhcp_sp_setup(); continue_with_autotime: - timeout_end = monotonic_sec() + server_config.auto_time; + timeout_end = monotonic_sec() + server_data.auto_time; while (1) { /* loop until universe collapses */ struct pollfd pfds[2]; struct dhcp_packet packet; @@ -960,14 +960,14 @@ int udhcpd_main(int argc UNUSED_PARAM, char **argv) if (server_socket < 0) { server_socket = udhcp_listen_socket(/*INADDR_ANY,*/ SERVER_PORT, - server_config.interface); + server_data.interface); } udhcp_sp_fd_set(pfds, server_socket); new_tv: tv = -1; - if (server_config.auto_time) { + if (server_data.auto_time) { tv = timeout_end - monotonic_sec(); if (tv <= 0) { write_leases: @@ -1037,7 +1037,7 @@ int udhcpd_main(int argc UNUSED_PARAM, char **argv) if (server_id_opt) { uint32_t server_id_network_order; move_from_unaligned32(server_id_network_order, server_id_opt); - if (server_id_network_order != server_config.server_nip) { + if (server_id_network_order != server_data.server_nip) { /* client talks to somebody else */ log1("server ID doesn't match, ignoring"); continue; @@ -1204,7 +1204,7 @@ o DHCPREQUEST generated during REBINDING state: && requested_nip == lease->lease_nip ) { memset(lease->lease_mac, 0, sizeof(lease->lease_mac)); - lease->expires = time(NULL) + server_config.decline_time; + lease->expires = time(NULL) + server_data.decline_time; } break; @@ -1235,7 +1235,7 @@ o DHCPREQUEST generated during REBINDING state: ret0: retval = 0; ret: - /*if (server_config.pidfile) - server_config.pidfile is never NULL */ - remove_pidfile(server_config.pidfile); + /*if (server_data.pidfile) - server_data.pidfile is never NULL */ + remove_pidfile(server_data.pidfile); return retval; } diff --git a/networking/udhcp/dhcpd.h b/networking/udhcp/dhcpd.h index ba11d77e8..b42849bbb 100644 --- a/networking/udhcp/dhcpd.h +++ b/networking/udhcp/dhcpd.h @@ -17,7 +17,7 @@ PUSH_AND_SET_FUNCTION_VISIBILITY_TO_HIDDEN struct static_lease; -struct server_config_t { +struct server_data_t { char *interface; /* interface to use */ //TODO: ifindex, server_nip, server_mac // are obtained from interface name. @@ -53,12 +53,12 @@ struct server_config_t { struct static_lease *static_leases; /* List of ip/mac pairs to assign static leases */ } FIX_ALIASING; -#define server_config (*(struct server_config_t*)bb_common_bufsiz1) +#define server_data (*(struct server_data_t*)bb_common_bufsiz1) /* client_data sits in 2nd half of bb_common_bufsiz1 */ #if ENABLE_FEATURE_UDHCP_PORT -#define SERVER_PORT (server_config.port) -#define SERVER_PORT6 (server_config.port) +#define SERVER_PORT (server_data.port) +#define SERVER_PORT6 (server_data.port) #else #define SERVER_PORT 67 #define SERVER_PORT6 547 -- cgit v1.2.3-55-g6feb From 65c34c52df3ed46f0b811d1858c271a373ab6af5 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Fri, 31 May 2019 23:39:22 +0200 Subject: dhcp: get rid of static data signal_pipe function old new delta udhcp_sp_setup 65 110 +45 udhcp_sp_fd_set 60 59 -1 udhcpd_main 1442 1437 -5 udhcpc_main 2684 2679 -5 signal_pipe 8 - -8 packed_usage 33292 33284 -8 ------------------------------------------------------------------------------ (add/remove: 0/1 grow/shrink: 1/4 up/down: 45/-27) Total: 18 bytes text data bss dec hex filename 952746 481 7296 960523 ea80b busybox_old 952768 481 7288 960537 ea819 busybox_unstripped Signed-off-by: Denys Vlasenko --- networking/udhcp/d6_dhcpc.c | 8 ++++---- networking/udhcp/dhcpc.c | 8 ++++---- networking/udhcp/dhcpd.c | 12 ++++++------ networking/udhcp/signalpipe.c | 31 ++++++++++++++++++++++--------- 4 files changed, 36 insertions(+), 23 deletions(-) diff --git a/networking/udhcp/d6_dhcpc.c b/networking/udhcp/d6_dhcpc.c index 15e9f3924..02766ba16 100644 --- a/networking/udhcp/d6_dhcpc.c +++ b/networking/udhcp/d6_dhcpc.c @@ -1174,6 +1174,10 @@ int udhcpc6_main(int argc UNUSED_PARAM, char **argv) client_data.script = CONFIG_UDHCPC_DEFAULT_SCRIPT; client_data.sockfd = -1; + /* Make sure fd 0,1,2 are open */ + /* Set up the signal pipe on fds 3,4 - must be before openlog() */ + udhcp_sp_setup(); + /* Parse command line */ opt = getopt32long(argv, "^" /* O,x: list; -T,-t,-A take numeric param */ @@ -1268,14 +1272,10 @@ int udhcpc6_main(int argc UNUSED_PARAM, char **argv) logmode |= LOGMODE_SYSLOG; } - /* Make sure fd 0,1,2 are open */ - bb_sanitize_stdio(); /* Create pidfile */ write_pidfile(client_data.pidfile); /* Goes to stdout (unless NOMMU) and possibly syslog */ bb_info_msg("started, v"BB_VER); - /* Set up the signal pipe */ - udhcp_sp_setup(); client_data.state = INIT_SELECTING; d6_run_script_no_option("deconfig"); diff --git a/networking/udhcp/dhcpc.c b/networking/udhcp/dhcpc.c index cb85fa9e3..f040e93f7 100644 --- a/networking/udhcp/dhcpc.c +++ b/networking/udhcp/dhcpc.c @@ -1271,6 +1271,10 @@ int udhcpc_main(int argc UNUSED_PARAM, char **argv) client_data.sockfd = -1; str_V = "udhcp "BB_VER; + /* Make sure fd 0,1,2 are open */ + /* Set up the signal pipe on fds 3,4 - must be before openlog() */ + udhcp_sp_setup(); + /* Parse command line */ opt = getopt32long(argv, "^" /* O,x: list; -T,-t,-A take numeric param */ @@ -1385,14 +1389,10 @@ int udhcpc_main(int argc UNUSED_PARAM, char **argv) logmode |= LOGMODE_SYSLOG; } - /* Make sure fd 0,1,2 are open */ - bb_sanitize_stdio(); /* Create pidfile */ write_pidfile(client_data.pidfile); /* Goes to stdout (unless NOMMU) and possibly syslog */ bb_info_msg("started, v"BB_VER); - /* Set up the signal pipe */ - udhcp_sp_setup(); /* We want random_xid to be random... */ srand(monotonic_us()); diff --git a/networking/udhcp/dhcpd.c b/networking/udhcp/dhcpd.c index 6e426e6a2..022b8721b 100644 --- a/networking/udhcp/dhcpd.c +++ b/networking/udhcp/dhcpd.c @@ -37,6 +37,8 @@ //usage: IF_FEATURE_UDHCP_PORT( //usage: "\n -P N Use port N (default 67)" //usage: ) +//usage: "\nSignals:" +//usage: "\n USR1 Update lease file" #include #include @@ -863,6 +865,10 @@ int udhcpd_main(int argc UNUSED_PARAM, char **argv) IF_FEATURE_UDHCP_PORT(SERVER_PORT = 67;) IF_FEATURE_UDHCP_PORT(CLIENT_PORT = 68;) + /* Make sure fd 0,1,2 are open */ + /* Setup the signal pipe on fds 3,4 - must be before openlog() */ + udhcp_sp_setup(); + opt = getopt32(argv, "^" "fSI:va:"IF_FEATURE_UDHCP_PORT("P:") "\0" @@ -904,9 +910,6 @@ int udhcpd_main(int argc UNUSED_PARAM, char **argv) if (server_data.auto_time > INT_MAX / 1000) server_data.auto_time = INT_MAX / 1000; - /* Make sure fd 0,1,2 are open */ - bb_sanitize_stdio(); - /* Create pidfile */ write_pidfile(server_data.pidfile); /* if (!..) bb_perror_msg("can't create pidfile %s", pidfile); */ @@ -942,9 +945,6 @@ int udhcpd_main(int argc UNUSED_PARAM, char **argv) goto ret; } - /* Setup the signal pipe */ - udhcp_sp_setup(); - continue_with_autotime: timeout_end = monotonic_sec() + server_data.auto_time; while (1) { /* loop until universe collapses */ diff --git a/networking/udhcp/signalpipe.c b/networking/udhcp/signalpipe.c index 2ff78f0f2..81d1fc01a 100644 --- a/networking/udhcp/signalpipe.c +++ b/networking/udhcp/signalpipe.c @@ -20,14 +20,14 @@ */ #include "common.h" -/* Global variable: we access it from signal handler */ -static struct fd_pair signal_pipe; +#define READ_FD 3 +#define WRITE_FD 4 static void signal_handler(int sig) { int sv = errno; unsigned char ch = sig; /* use char, avoid dealing with partial writes */ - if (write(signal_pipe.wr, &ch, 1) != 1) + if (write(WRITE_FD, &ch, 1) != 1) bb_perror_msg("can't send signal"); errno = sv; } @@ -36,12 +36,25 @@ static void signal_handler(int sig) * and installs the signal handler */ void FAST_FUNC udhcp_sp_setup(void) { + struct fd_pair signal_pipe; + + /* All callers also want this, so... */ + bb_sanitize_stdio(); + /* was socketpair, but it needs AF_UNIX in kernel */ xpiped_pair(signal_pipe); - close_on_exec_on(signal_pipe.rd); - close_on_exec_on(signal_pipe.wr); - ndelay_on(signal_pipe.rd); - ndelay_on(signal_pipe.wr); + + /* usually we get fds 3 and 4, but if we get higher ones... */ + if (signal_pipe.rd != READ_FD) + xmove_fd(signal_pipe.rd, READ_FD); + if (signal_pipe.wr != WRITE_FD) + xmove_fd(signal_pipe.wr, WRITE_FD); + + close_on_exec_on(READ_FD); + close_on_exec_on(WRITE_FD); + ndelay_on(READ_FD); + ndelay_on(WRITE_FD); + bb_signals(0 + (1 << SIGUSR1) + (1 << SIGUSR2) @@ -54,7 +67,7 @@ void FAST_FUNC udhcp_sp_setup(void) */ void FAST_FUNC udhcp_sp_fd_set(struct pollfd pfds[2], int extra_fd) { - pfds[0].fd = signal_pipe.rd; + pfds[0].fd = READ_FD; pfds[0].events = POLLIN; pfds[1].fd = -1; if (extra_fd >= 0) { @@ -74,7 +87,7 @@ int FAST_FUNC udhcp_sp_read(void) unsigned char sig; /* Can't block here, fd is in nonblocking mode */ - if (safe_read(signal_pipe.rd, &sig, 1) != 1) + if (safe_read(READ_FD, &sig, 1) != 1) return 0; return sig; -- cgit v1.2.3-55-g6feb From 6eb6e6a1e9d6e7d4dd154014ce404ec1c8175fb2 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Fri, 31 May 2019 23:51:07 +0200 Subject: dhcp: downgrade "got raw socket fd" message to log3, make log2 default max log3 messages are very much redundant function old new delta change_listen_mode 322 302 -20 Signed-off-by: Denys Vlasenko --- networking/udhcp/Config.src | 2 +- networking/udhcp/d6_dhcpc.c | 2 +- networking/udhcp/dhcpc.c | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/networking/udhcp/Config.src b/networking/udhcp/Config.src index f16fc0a4f..8ef24748e 100644 --- a/networking/udhcp/Config.src +++ b/networking/udhcp/Config.src @@ -116,7 +116,7 @@ config FEATURE_UDHCP_PORT config UDHCP_DEBUG int "Maximum verbosity level (0..9)" - default 9 + default 2 range 0 9 depends on UDHCPD || UDHCPC || UDHCPC6 || DHCPRELAY help diff --git a/networking/udhcp/d6_dhcpc.c b/networking/udhcp/d6_dhcpc.c index 02766ba16..422b88882 100644 --- a/networking/udhcp/d6_dhcpc.c +++ b/networking/udhcp/d6_dhcpc.c @@ -981,7 +981,7 @@ static int d6_raw_socket(int ifindex) log2("opening raw socket on ifindex %d", ifindex); fd = xsocket(PF_PACKET, SOCK_DGRAM, htons(ETH_P_IPV6)); - log2("got raw socket fd %d", fd); + log3("got raw socket fd %d", fd); memset(&sock, 0, sizeof(sock)); /* let's be deterministic */ sock.sll_family = AF_PACKET; diff --git a/networking/udhcp/dhcpc.c b/networking/udhcp/dhcpc.c index f040e93f7..739870bee 100644 --- a/networking/udhcp/dhcpc.c +++ b/networking/udhcp/dhcpc.c @@ -1017,7 +1017,7 @@ static int udhcp_raw_socket(int ifindex) * SOCK_DGRAM: remove link-layer headers on input (SOCK_RAW keeps them) * ETH_P_IP: want to receive only packets with IPv4 eth type */ - log2("got raw socket fd"); + log3("got raw socket fd %d", fd); memset(&sock, 0, sizeof(sock)); /* let's be deterministic */ sock.sll_family = AF_PACKET; -- cgit v1.2.3-55-g6feb From 897475ab023040efed9f199af5daffe43451c1d2 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Sat, 1 Jun 2019 16:35:09 +0200 Subject: ash: allocate line editing structure only if needed function old new delta optschanged 91 128 +37 historycmd 13 17 +4 setcmd 80 78 -2 ash_main 1167 1150 -17 options 576 552 -24 ------------------------------------------------------------------------------ (add/remove: 0/0 grow/shrink: 2/3 up/down: 41/-43) Total: -2 bytes Signed-off-by: Denys Vlasenko --- shell/ash.c | 107 +++++++++++++++++++++++++++++++++++++++--------------------- 1 file changed, 70 insertions(+), 37 deletions(-) diff --git a/shell/ash.c b/shell/ash.c index 924e17f32..c8857366c 100644 --- a/shell/ash.c +++ b/shell/ash.c @@ -315,9 +315,16 @@ static const char *const optletters_optnames[] = { "e" "errexit", "f" "noglob", "I" "ignoreeof", +/* The below allows this invocation: + * ash -c 'set -i; echo $-; sleep 5; echo $-' + * to be ^C-ed and get to interactive ash prompt. + * bash does not support this "set -i". bash also has no + * "set -o interactive". + */ "i" "interactive", "m" "monitor", "n" "noexec", +/* Ditto: bash has no "set -s" and "set -o stdin" */ "s" "stdin", "x" "xtrace", "v" "verbose", @@ -334,10 +341,25 @@ static const char *const optletters_optnames[] = { ,"\0" "debug" #endif }; +//bash 4.4.23 also has these opts (with these defaults): +//braceexpand on +//emacs on +//errtrace off +//functrace off +//hashall on +//histexpand off +//history on +//interactive-comments on +//keyword off +//onecmd off +//physical off +//posix off +//privileged off #define optletters(n) optletters_optnames[n][0] #define optnames(n) (optletters_optnames[n] + 1) + enum { NOPTS = ARRAY_SIZE(optletters_optnames) }; @@ -9514,8 +9536,8 @@ setinteractive(int on) setsignal(SIGINT); setsignal(SIGQUIT); setsignal(SIGTERM); -#if !ENABLE_FEATURE_SH_EXTRA_QUIET if (is_interactive > 1) { +#if !ENABLE_FEATURE_SH_EXTRA_QUIET /* Looks like they want an interactive shell */ static smallint did_banner; @@ -9529,8 +9551,12 @@ setinteractive(int on) ); did_banner = 1; } - } #endif +#if ENABLE_FEATURE_EDITING + if (!line_input_state) + line_input_state = new_line_input_t(FOR_SHELL | WITH_PATH_LOOKUP); +#endif + } } static void @@ -9542,10 +9568,12 @@ optschanged(void) setinteractive(iflag); setjobctl(mflag); #if ENABLE_FEATURE_EDITING_VI - if (viflag) - line_input_state->flags |= VI_MODE; - else - line_input_state->flags &= ~VI_MODE; + if (line_input_state) { + if (viflag) + line_input_state->flags |= VI_MODE; + else + line_input_state->flags &= ~VI_MODE; + } #else viflag = 0; /* forcibly keep the option off */ #endif @@ -10519,13 +10547,11 @@ preadfd(void) else { # if ENABLE_ASH_IDLE_TIMEOUT int timeout = -1; - if (iflag) { - const char *tmout_var = lookupvar("TMOUT"); - if (tmout_var) { - timeout = atoi(tmout_var) * 1000; - if (timeout <= 0) - timeout = -1; - } + const char *tmout_var = lookupvar("TMOUT"); + if (tmout_var) { + timeout = atoi(tmout_var) * 1000; + if (timeout <= 0) + timeout = -1; } line_input_state->timeout = timeout; # endif @@ -11086,14 +11112,17 @@ setoption(int flag, int val) ash_msg_and_raise_error("illegal option %c%c", val ? '-' : '+', flag); /* NOTREACHED */ } +/* If login_sh is not NULL, we are called to parse command line opts, + * not "set -opts" + */ static int -options(int cmdline, int *login_sh) +options(int *login_sh) { char *p; int val; int c; - if (cmdline) + if (login_sh) minusc = NULL; while ((p = *argptr) != NULL) { c = *p++; @@ -11104,7 +11133,7 @@ options(int cmdline, int *login_sh) if (c == '-') { val = 1; if (p[0] == '\0' || LONE_DASH(p)) { - if (!cmdline) { + if (!login_sh) { /* "-" means turn off -x and -v */ if (p[0] == '\0') xflag = vflag = 0; @@ -11117,26 +11146,31 @@ options(int cmdline, int *login_sh) } /* first char was + or - */ while ((c = *p++) != '\0') { - /* bash 3.2 indeed handles -c CMD and +c CMD the same */ - if (c == 'c' && cmdline) { - minusc = p; /* command is after shell args */ - } else if (c == 'o') { + if (login_sh) { + /* bash 3.2 indeed handles -c CMD and +c CMD the same */ + if (c == 'c') { + minusc = p; /* command is after shell args */ + continue; + } + if (c == 'l') { + *login_sh = 1; /* -l or +l == --login */ + continue; + } + /* bash does not accept +-login, we also won't */ + if (val && (c == '-')) { /* long options */ + if (strcmp(p, "login") == 0) { + *login_sh = 1; + } + break; + } + } + if (c == 'o') { if (plus_minus_o(*argptr, val)) { /* it already printed err message */ return 1; /* error */ } if (*argptr) argptr++; - } else if (cmdline && (c == 'l')) { /* -l or +l == --login */ - if (login_sh) - *login_sh = 1; - /* bash does not accept +-login, we also won't */ - } else if (cmdline && val && (c == '-')) { /* long options */ - if (strcmp(p, "login") == 0) { - if (login_sh) - *login_sh = 1; - } - break; } else { setoption(c, val); } @@ -11227,7 +11261,7 @@ setcmd(int argc UNUSED_PARAM, char **argv UNUSED_PARAM) return showvars(nullstr, 0, VUNSET); INT_OFF; - retval = options(/*cmdline:*/ 0, NULL); + retval = options(/*login_sh:*/ NULL); if (retval == 0) { /* if no parse error... */ optschanged(); if (*argptr != NULL) { @@ -13685,7 +13719,8 @@ helpcmd(int argc UNUSED_PARAM, char **argv UNUSED_PARAM) static int FAST_FUNC historycmd(int argc UNUSED_PARAM, char **argv UNUSED_PARAM) { - show_history(line_input_state); + if (line_input_state) + show_history(line_input_state); return EXIT_SUCCESS; } #endif @@ -14001,7 +14036,8 @@ exitshell(void) int status; #if ENABLE_FEATURE_EDITING_SAVE_ON_EXIT - save_history(line_input_state); + if (line_input_state) + save_history(line_input_state); #endif status = exitstatus; TRACE(("pid %d, exitshell(%d)\n", getpid(), status)); @@ -14123,7 +14159,7 @@ procargs(char **argv) argptr = xargv; for (i = 0; i < NOPTS; i++) optlist[i] = 2; - if (options(/*cmdline:*/ 1, &login_sh)) { + if (options(&login_sh)) { /* it already printed err message */ raise_exception(EXERROR); } @@ -14249,9 +14285,6 @@ int ash_main(int argc UNUSED_PARAM, char **argv) monitor(4, etext, profile_buf, sizeof(profile_buf), 50); #endif -#if ENABLE_FEATURE_EDITING - line_input_state = new_line_input_t(FOR_SHELL | WITH_PATH_LOOKUP); -#endif state = 0; if (setjmp(jmploc.loc)) { smallint e; -- cgit v1.2.3-55-g6feb From f3634584d0fdeb4ae9e2fe0f5971d45b77e40296 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Mon, 3 Jun 2019 12:21:04 +0200 Subject: ash,hush: show 'c' in $- if run in "sh -c CMD" function old new delta options 552 599 +47 expand_one_var 2375 2385 +10 optletters_optnames 60 64 +4 hush_main 1108 1111 +3 ash_main 1150 1152 +2 ------------------------------------------------------------------------------ (add/remove: 0/0 grow/shrink: 5/0 up/down: 66/0) Total: 66 bytes Signed-off-by: Denys Vlasenko --- shell/ash.c | 62 ++++++++++++++++++++++++++++++++++++++++-------------------- shell/hush.c | 13 ++++++++----- 2 files changed, 50 insertions(+), 25 deletions(-) diff --git a/shell/ash.c b/shell/ash.c index c8857366c..e3bbac9a0 100644 --- a/shell/ash.c +++ b/shell/ash.c @@ -315,17 +315,18 @@ static const char *const optletters_optnames[] = { "e" "errexit", "f" "noglob", "I" "ignoreeof", -/* The below allows this invocation: +/* The below allowed this invocation: * ash -c 'set -i; echo $-; sleep 5; echo $-' * to be ^C-ed and get to interactive ash prompt. - * bash does not support this "set -i". bash also has no - * "set -o interactive". + * bash does not support such "set -i". + * In our code, this is denoted by empty long name: */ - "i" "interactive", + "i" "", "m" "monitor", "n" "noexec", -/* Ditto: bash has no "set -s" and "set -o stdin" */ - "s" "stdin", +/* Ditto: bash has no "set -s" */ + "s" "", + "c" "", "x" "xtrace", "v" "verbose", "C" "noclobber", @@ -359,7 +360,6 @@ static const char *const optletters_optnames[] = { #define optletters(n) optletters_optnames[n][0] #define optnames(n) (optletters_optnames[n] + 1) - enum { NOPTS = ARRAY_SIZE(optletters_optnames) }; @@ -419,21 +419,22 @@ struct globals_misc { #define mflag optlist[4] #define nflag optlist[5] #define sflag optlist[6] -#define xflag optlist[7] -#define vflag optlist[8] -#define Cflag optlist[9] -#define aflag optlist[10] -#define bflag optlist[11] -#define uflag optlist[12] -#define viflag optlist[13] +#define cflag optlist[7] +#define xflag optlist[8] +#define vflag optlist[9] +#define Cflag optlist[10] +#define aflag optlist[11] +#define bflag optlist[12] +#define uflag optlist[13] +#define viflag optlist[14] #if BASH_PIPEFAIL -# define pipefail optlist[14] +# define pipefail optlist[15] #else # define pipefail 0 #endif #if DEBUG -# define nolog optlist[14 + BASH_PIPEFAIL] -# define debug optlist[15 + BASH_PIPEFAIL] +# define nolog optlist[15 + BASH_PIPEFAIL] +# define debug optlist[16 + BASH_PIPEFAIL] #endif /* trap handler commands */ @@ -11104,7 +11105,7 @@ setoption(int flag, int val) int i; for (i = 0; i < NOPTS; i++) { - if (optletters(i) == flag) { + if (optletters(i) == flag && optnames(i)[0] != '\0') { optlist[i] = val; return; } @@ -11150,6 +11151,15 @@ options(int *login_sh) /* bash 3.2 indeed handles -c CMD and +c CMD the same */ if (c == 'c') { minusc = p; /* command is after shell args */ + cflag = 1; + continue; + } + if (c == 's') { /* -s, +s */ + sflag = 1; + continue; + } + if (c == 'i') { /* -i, +i */ + iflag = 1; continue; } if (c == 'l') { @@ -14170,8 +14180,13 @@ procargs(char **argv) ash_msg_and_raise_error(bb_msg_requires_arg, "-c"); sflag = 1; } - if (iflag == 2 && sflag == 1 && isatty(0) && isatty(1)) + if (iflag == 2 /* no explicit -i given */ + && sflag == 1 /* -s given (or implied) */ + && !minusc /* bash compat: ash -sc 'echo $-' is not interactive (dash is) */ + && isatty(0) && isatty(1) /* we are on tty */ + ) { iflag = 1; + } if (mflag == 2) mflag = iflag; for (i = 0; i < NOPTS; i++) @@ -14359,10 +14374,17 @@ int ash_main(int argc UNUSED_PARAM, char **argv) * Ensure we don't falsely claim that 0 (stdin) * is one of stacked source fds. * Testcase: ash -c 'exec 1>&0' must not complain. */ + // if (!sflag) g_parsefile->pf_fd = -1; // ^^ not necessary since now we special-case fd 0 // in save_fd_on_redirect() - evalstring(minusc, sflag ? 0 : EV_EXIT); + + // dash: evalstring(minusc, sflag ? 0 : EV_EXIT); + // The above makes + // ash -sc 'echo $-' + // continue reading input from stdin after running 'echo'. + // bash does not do this: it prints "hBcs" and exits. + evalstring(minusc, EV_EXIT); } if (sflag || minusc == NULL) { diff --git a/shell/hush.c b/shell/hush.c index 4b08232a4..f82747f74 100644 --- a/shell/hush.c +++ b/shell/hush.c @@ -903,6 +903,7 @@ struct globals { # define G_x_mode 0 #endif char opt_s; + char opt_c; #if ENABLE_HUSH_INTERACTIVE smallint promptmode; /* 0: PS1, 1: PS2 */ #endif @@ -1009,7 +1010,7 @@ struct globals { int debug_indent; #endif struct sigaction sa; - char optstring_buf[sizeof("eixs")]; + char optstring_buf[sizeof("eixcs")]; #if BASH_EPOCH_VARS char epoch_buf[sizeof("%lu.nnnnnn") + sizeof(long)*3]; #endif @@ -6414,9 +6415,10 @@ static NOINLINE int expand_one_var(o_string *output, int n, * commands read but are not executed, * so $- can not execute too, 'n' is never seen in $-. */ + if (G.opt_c) + *cp++ = 'c'; if (G.opt_s) *cp++ = 's'; -//TODO: show 'c' if executed via "hush -c 'CMDS'" (bash only, not ash) *cp = '\0'; break; } @@ -9859,7 +9861,6 @@ int hush_main(int argc, char **argv) { enum { OPT_login = (1 << 0), - OPT_s = (1 << 1), }; unsigned flags; unsigned builtin_argc; @@ -10029,6 +10030,7 @@ int hush_main(int argc, char **argv) } goto final_return; } + G.opt_c = 1; if (!G.global_argv[0]) { /* -c 'script' (no params): prevent empty $0 */ G.global_argv--; /* points to argv[i] of 'script' */ @@ -10044,7 +10046,7 @@ int hush_main(int argc, char **argv) /* G_interactive_fd++; */ break; case 's': - flags |= OPT_s; + G.opt_s = 1; break; case 'l': flags |= OPT_login; @@ -10154,7 +10156,7 @@ int hush_main(int argc, char **argv) } /* -s is: hush -s ARGV1 ARGV2 (no SCRIPT) */ - if (!(flags & OPT_s) && G.global_argv[1]) { + if (!G.opt_s && G.global_argv[1]) { HFILE *input; /* * "bash