X-Git-Url: https://git.librecmc.org/?a=blobdiff_plain;f=networking%2Fifplugd.c;h=4f8a274b0afde8ed45d6b54e13914c1c390e3dc1;hb=7fdb764e2e12119949cc17046d5ad4a13a9be4c6;hp=88bf448fa2abcf5032e75bba8ab5d1be464baa20;hpb=21f620f6e5f72c4cbecfecaf63a901c33911c00c;p=oweals%2Fbusybox.git diff --git a/networking/ifplugd.c b/networking/ifplugd.c index 88bf448fa..4f8a274b0 100644 --- a/networking/ifplugd.c +++ b/networking/ifplugd.c @@ -6,6 +6,16 @@ * * Licensed under GPLv2 or later, see file LICENSE in this source tree. */ +//config:config IFPLUGD +//config: bool "ifplugd" +//config: default y +//config: select PLATFORM_LINUX +//config: help +//config: Network interface plug detection daemon. + +//applet:IF_IFPLUGD(APPLET(ifplugd, BB_DIR_USR_SBIN, BB_SUID_DROP)) + +//kbuild:lib-$(CONFIG_IFPLUGD) += ifplugd.o //usage:#define ifplugd_trivial_usage //usage: "[OPTIONS]" @@ -38,7 +48,17 @@ #include #include #ifdef HAVE_NET_ETHERNET_H -# include +/* 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 + * and copy-pasting its definitions here ( is what pulls in + * conflicting definition of struct ethhdr on musl). + */ +/* # include */ #endif #include #include @@ -48,6 +68,10 @@ #define __user #include +#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 @@ -93,9 +117,9 @@ enum { #endif }; #if ENABLE_FEATURE_PIDFILE -# define OPTION_STR "+ansfFi:r:It:u:d:m:pqlx:Mk" +# define OPTION_STR "+ansfFi:r:It:+u:+d:+m:pqlx:Mk" #else -# define OPTION_STR "+ansfFi:r:It:u:d:m:pqlx:M" +# define OPTION_STR "+ansfFi:r:It:+u:+d:+m:pqlx:M" #endif enum { // interface status @@ -289,8 +313,6 @@ static const struct { { "IFF_RUNNING" , &detect_link_iff }, }; - - static const char *strstatus(int status) { if (status == IFSTATUS_ERR) @@ -346,8 +368,12 @@ static void up_iface(void) ifrequest.ifr_flags |= IFF_UP; /* Let user know we mess up with interface */ bb_error_msg("upping interface"); - if (network_ioctl(SIOCSIFFLAGS, &ifrequest, "setting interface flags") < 0) - xfunc_die(); + if (network_ioctl(SIOCSIFFLAGS, &ifrequest, "setting interface flags") < 0) { + if (errno != ENODEV) + xfunc_die(); + G.iface_exists = 0; + return; + } } #if 0 /* why do we mess with IP addr? It's not our business */ @@ -451,20 +477,24 @@ static smallint detect_link(void) static NOINLINE int check_existence_through_netlink(void) { int iface_len; - char replybuf[1024]; + /* Buffer was 1K, but on linux-3.9.9 it was reported to be too small. + * netlink.h: "limit to 8K to avoid MSG_TRUNC when PAGE_SIZE is very large". + * Note: on error returns (-1) we exit, no need to free replybuf. + */ + enum { BUF_SIZE = 8 * 1024 }; + char *replybuf = xmalloc(BUF_SIZE); iface_len = strlen(G.iface); while (1) { struct nlmsghdr *mhdr; ssize_t bytes; - bytes = recv(netlink_fd, &replybuf, sizeof(replybuf), MSG_DONTWAIT); + bytes = recv(netlink_fd, replybuf, BUF_SIZE, MSG_DONTWAIT); if (bytes < 0) { if (errno == EAGAIN) - return G.iface_exists; + goto ret; if (errno == EINTR) continue; - bb_perror_msg("netlink: recv"); return -1; } @@ -507,6 +537,8 @@ static NOINLINE int check_existence_through_netlink(void) } } + ret: + free(replybuf); return G.iface_exists; } @@ -542,7 +574,6 @@ int ifplugd_main(int argc UNUSED_PARAM, char **argv) INIT_G(); - opt_complementary = "t+:u+:d+"; opts = getopt32(argv, OPTION_STR, &G.iface, &G.script_name, &G.poll_time, &G.delay_up, &G.delay_down, &G.api_mode, &G.extra_arg); @@ -551,12 +582,13 @@ int ifplugd_main(int argc UNUSED_PARAM, char **argv) applet_name = xasprintf("ifplugd(%s)", G.iface); #if ENABLE_FEATURE_PIDFILE - pidfile_name = xasprintf(_PATH_VARRUN"ifplugd.%s.pid", G.iface); + pidfile_name = xasprintf(CONFIG_PID_FILE_PATH "/ifplugd.%s.pid", G.iface); pid_from_pidfile = read_pid(pidfile_name); if (opts & FLAG_KILL) { if (pid_from_pidfile > 0) - kill(pid_from_pidfile, SIGQUIT); + /* Upstream tool use SIGINT for -k */ + kill(pid_from_pidfile, SIGINT); return EXIT_SUCCESS; } @@ -645,7 +677,6 @@ int ifplugd_main(int argc UNUSED_PARAM, char **argv) delay_time = 0; while (1) { int iface_status_old; - int iface_exists_old; switch (bb_got_signal) { case SIGINT: @@ -671,12 +702,12 @@ int ifplugd_main(int argc UNUSED_PARAM, char **argv) goto exiting; } - iface_status_old = iface_status; - iface_exists_old = G.iface_exists; - if ((opts & FLAG_MONITOR) && (netlink_pollfd[0].revents & POLLIN) ) { + int iface_exists_old; + + iface_exists_old = G.iface_exists; G.iface_exists = check_existence_through_netlink(); if (G.iface_exists < 0) /* error */ goto exiting; @@ -689,6 +720,7 @@ int ifplugd_main(int argc UNUSED_PARAM, char **argv) } /* note: if !G.iface_exists, returns DOWN */ + iface_status_old = iface_status; iface_status = detect_link(); if (iface_status == IFSTATUS_ERR) { if (!(opts & FLAG_MONITOR)) @@ -702,7 +734,7 @@ int ifplugd_main(int argc UNUSED_PARAM, char **argv) if (delay_time) { /* link restored its old status before - * we run script. don't run the script: */ + * we ran script. don't run the script: */ delay_time = 0; } else { delay_time = monotonic_sec(); @@ -710,15 +742,19 @@ int ifplugd_main(int argc UNUSED_PARAM, char **argv) delay_time += G.delay_up; if (iface_status == IFSTATUS_DOWN) delay_time += G.delay_down; - if (delay_time == 0) - delay_time++; +#if 0 /* if you are back in 1970... */ + if (delay_time == 0) { + sleep(1); + delay_time = 1; + } +#endif } } if (delay_time && (int)(monotonic_sec() - delay_time) >= 0) { - delay_time = 0; if (run_script(iface_status_str) != 0) goto exiting; + delay_time = 0; } } /* while (1) */