diff --git a/ethsock.c b/ethsock.c index 3219a0d..1664f7f 100644 --- a/ethsock.c +++ b/ethsock.c @@ -100,7 +100,7 @@ static bool get_intf_info(const char *intf, uint8_t *hwaddr, void *dummy) bool found; if (getifaddrs(&ifas) != 0) { - perror("getifaddrs"); + xperror("getifaddrs"); return false; } @@ -152,7 +152,7 @@ static bool get_intf_info(const char *intf, uint8_t *hwaddr, DWORD *index) adapters = malloc(bufLen); if (!adapters) { - perror("malloc"); + xperror("malloc"); return false; } @@ -285,7 +285,7 @@ struct ethsock *ethsock_create(const char *intf, uint16_t protocol) sock = malloc(sizeof(struct ethsock)); if (!sock) { - perror("malloc"); + xperror("malloc"); return NULL; } @@ -492,7 +492,7 @@ static int ethsock_arp(struct ethsock *sock, uint8_t *hwaddr, uint32_t ipaddr, s *undo = malloc(sizeof(struct ethsock_arp_undo)); if (!*undo) { - perror("malloc"); + xperror("malloc"); return -1; } @@ -683,7 +683,7 @@ static bool set_interface_up(int fd, const char *intf, bool up) strncpy(ifr.ifr_name, intf, IFNAMSIZ); if (ioctl(fd, SIOCGIFFLAGS, &ifr) != 0) { - perror("ioctl(SIOCGIFFLAGS)"); + xperror("ioctl(SIOCGIFFLAGS)"); return false; } @@ -694,7 +694,7 @@ static bool set_interface_up(int fd, const char *intf, bool up) } if (ioctl(fd, SIOCSIFFLAGS, &ifr) != 0) { - perror("ioctl(SIOCSIFFLAGS)"); + xperror("ioctl(SIOCSIFFLAGS)"); return false; } @@ -706,7 +706,7 @@ static bool set_interface_up(int fd, const char *intf, bool up) int ethsock_ip_add(struct ethsock *sock, uint32_t ipaddr, uint32_t ipmask, struct ethsock_ip_undo **undo) { if (undo && !(*undo = malloc(sizeof(struct ethsock_ip_undo)))) { - perror("malloc"); + xperror("malloc"); return -1; } @@ -729,13 +729,13 @@ int ethsock_ip_add(struct ethsock *sock, uint32_t ipaddr, uint32_t ipmask, struc if (add) { set_addr(&ifr.ifr_addr, ipaddr); if (ioctl(fd, SIOCSIFADDR, &ifr) != 0) { - perror("ioctl(SIOSIFADDR)"); + xperror("ioctl(SIOSIFADDR)"); goto out; } set_addr(&ifr.ifr_netmask, ipmask); if (ioctl(fd, SIOCSIFNETMASK, &ifr) != 0) { - perror("ioctl(SIOCSIFNETMASK)"); + xperror("ioctl(SIOCSIFNETMASK)"); goto out; } @@ -756,7 +756,7 @@ int ethsock_ip_add(struct ethsock *sock, uint32_t ipaddr, uint32_t ipmask, struc //set_addr(&ifra.ifra_broadaddr, (ipaddr & ipmask) | ~ipmask); if (ioctl(fd, add ? SIOCAIFADDR : SIOCDIFADDR, &ifra) != 0) { - perror(add ? "ioctl(SIOCAIFADDR)" : "ioctl(SIOCDIFADDR)"); + xperroradd ? "ioctl(SIOCAIFADDR)" : "ioctl(SIOCDIFADDR)"); goto out; } diff --git a/nmrp.c b/nmrp.c index c1bfb9c..80dcb8f 100644 --- a/nmrp.c +++ b/nmrp.c @@ -385,21 +385,9 @@ static int is_valid_ip(struct ethsock *sock, struct in_addr *ipaddr, return status < 0 ? status : arg.result; } -static struct ethsock *gsock = NULL; -static struct ethsock_ip_undo *g_ip_undo = NULL; -static struct ethsock_arp_undo *g_arp_undo = NULL; - static void sigh(int sig) { - printf("\n"); - if (gsock) { - ethsock_arp_del(gsock, &g_arp_undo); - ethsock_ip_del(gsock, &g_ip_undo); - ethsock_close(gsock); - gsock = NULL; - } - - exit(1); + g_interrupted = 1; } static const char *spinner = "\\|/-"; @@ -413,6 +401,8 @@ int nmrp_do(struct nmrpd_args *args) time_t beg; int i, status, ulreqs, expect, upload_ok, autoip; struct ethsock *sock; + struct ethsock_ip_undo *ip_undo = NULL; + struct ethsock_arp_undo *arp_undo = NULL; uint32_t intf_addr; void (*sigh_orig)(int); struct { @@ -493,7 +483,6 @@ int nmrp_do(struct nmrpd_args *args) return 1; } - gsock = sock; sigh_orig = signal(SIGINT, sigh); if (!autoip) { @@ -510,7 +499,7 @@ int nmrp_do(struct nmrpd_args *args) printf("Adding %s to interface %s.\n", args->ipaddr_intf, args->intf); } - if (ethsock_ip_add(sock, intf_addr, ipconf.mask.s_addr, &g_ip_undo) != 0) { + if (ethsock_ip_add(sock, intf_addr, ipconf.mask.s_addr, &ip_undo) != 0) { goto out; } } @@ -536,14 +525,14 @@ int nmrp_do(struct nmrpd_args *args) upload_ok = 0; beg = time_monotonic(); - while (1) { + while (!g_interrupted) { printf("\rAdvertising NMRP server on %s ... %c", args->intf, spinner[i]); fflush(stdout); i = (i + 1) & 3; if (pkt_send(sock, &tx) < 0) { - perror("sendto"); + xperror("sendto"); goto out; } @@ -568,7 +557,7 @@ int nmrp_do(struct nmrpd_args *args) expect = NMRP_C_CONF_REQ; ulreqs = 0; - do { + while (!g_interrupted) { if (expect != NMRP_C_NONE && rx.msg.code != expect) { fprintf(stderr, "Received %s while waiting for %s!\n", msg_code_str(rx.msg.code), msg_code_str(expect)); @@ -606,7 +595,7 @@ int nmrp_do(struct nmrpd_args *args) printf("Sending configuration: %s, netmask %s.\n", args->ipaddr, args->ipmask); - if (ethsock_arp_add(sock, rx.eh.ether_shost, ipconf.addr.s_addr, &g_arp_undo) != 0) { + if (ethsock_arp_add(sock, rx.eh.ether_shost, ipconf.addr.s_addr, &arp_undo) != 0) { goto out; } @@ -714,7 +703,7 @@ int nmrp_do(struct nmrpd_args *args) msg_hton(&tx.msg); if (pkt_send(sock, &tx) < 0) { - perror("sendto"); + xperror("sendto"); goto out; } @@ -739,21 +728,21 @@ int nmrp_do(struct nmrpd_args *args) ethsock_set_timeout(sock, args->rx_timeout); - } while (1); + } - status = 0; - - if (ulreqs) { - printf("Reboot your device now.\n"); - } else { - printf("No upload request received.\n"); + if (!g_interrupted) { + status = 0; + if (ulreqs) { + printf("Reboot your device now.\n"); + } else { + printf("No upload request received.\n"); + } } out: signal(SIGINT, sigh_orig); - gsock = NULL; - ethsock_arp_del(sock, &g_arp_undo); - ethsock_ip_del(sock, &g_ip_undo); + ethsock_arp_del(sock, &arp_undo); + ethsock_ip_del(sock, &ip_undo); ethsock_close(sock); return status; } diff --git a/nmrpd.h b/nmrpd.h index ce424e3..8d2c730 100644 --- a/nmrpd.h +++ b/nmrpd.h @@ -20,24 +20,25 @@ #ifndef NMRPD_H #define NMRPD_H #include +#include #include #if defined(_WIN32) || defined(_WIN64) # define NMRPFLASH_WINDOWS -#else +#elif defined (__unix__) # define NMRPFLASH_UNIX # if defined(__linux__) # define NMRPFLASH_LINUX # elif defined(__APPLE__) && defined(__MACH__) # define NMRPFLASH_OSX # define NMRPFLASH_BSD -# elif defined(__unix__) -# if defined(__FreeBSD__) || defined(__NetBSD__) || defined(__DragonFly__) || defined(__OpenBSD__) +# elif defined(__FreeBSD__) || defined(__NetBSD__) || defined(__DragonFly__) || defined(__OpenBSD__) # define NMRPFLASH_BSD -# else -# warning "nmrpflash is not fully supported on your operating system" -# endif +# else +# warning "nmrpflash is not fully supported on this platform" # endif +#else +# warning "nmrpflash is not supported on this platform" #endif #ifndef NMRPFLASH_WINDOWS @@ -105,7 +106,7 @@ const char *mac_to_str(uint8_t *mac); void win_perror2(const char *msg, DWORD err); void sock_perror(const char *msg); #else -#define sock_perror(x) perror(x) +#define sock_perror(x) xperror(x) #endif extern int verbosity; @@ -142,4 +143,7 @@ time_t time_monotonic(); char *lltostr(long long ll, int base); uint32_t bitcount(uint32_t n); uint32_t netmask(uint32_t count); +void xperror(const char *msg); + +extern volatile sig_atomic_t g_interrupted; #endif diff --git a/tftp.c b/tftp.c index bb4d818..a291ac0 100644 --- a/tftp.c +++ b/tftp.c @@ -239,6 +239,10 @@ int tftp_put(struct nmrpd_args *args) sock = -1; ret = -1; + if (g_interrupted) { + goto cleanup; + } + if (!strcmp(args->file_local, "-")) { fd = STDIN_FILENO; if (!file_remote) { @@ -247,7 +251,7 @@ int tftp_put(struct nmrpd_args *args) } else { fd = open(args->file_local, O_RDONLY | O_BINARY); if (fd < 0) { - perror("open"); + xperror("open"); ret = fd; goto cleanup; } else if (!file_remote) { @@ -268,7 +272,7 @@ int tftp_put(struct nmrpd_args *args) if (args->ipaddr_intf) { if ((addr.sin_addr.s_addr = inet_addr(args->ipaddr_intf)) == INADDR_NONE) { - perror("inet_addr"); + xperror("inet_addr"); goto cleanup; } @@ -279,7 +283,7 @@ int tftp_put(struct nmrpd_args *args) } if ((addr.sin_addr.s_addr = inet_addr(args->ipaddr)) == INADDR_NONE) { - perror("inet_addr"); + xperror("inet_addr"); goto cleanup; } addr.sin_port = htons(args->port); @@ -293,7 +297,7 @@ int tftp_put(struct nmrpd_args *args) pkt_mkwrq(tx, file_remote); - do { + while (!g_interrupted) { if (!timeout && pkt_num(rx) == ACK) { ackblock = pkt_num(rx + 2); } else { @@ -307,7 +311,7 @@ int tftp_put(struct nmrpd_args *args) pkt_mknum(tx + 2, block); len = read(fd, tx + 4, 512); if (len < 0) { - perror("read"); + xperror("read"); ret = len; goto cleanup; } else if (!len) { @@ -361,9 +365,9 @@ int tftp_put(struct nmrpd_args *args) addr.sin_port = htons(port); } } - } while(1); + } - ret = 0; + ret = !g_interrupted ? 0 : -1; cleanup: if (fd >= 0) { diff --git a/util.c b/util.c index a1b2c52..2529650 100644 --- a/util.c +++ b/util.c @@ -1,4 +1,5 @@ #include +#include #include #include #include "nmrpd.h" @@ -7,6 +8,8 @@ #include #endif +volatile sig_atomic_t g_interrupted = 0; + time_t time_monotonic() { #ifndef NMRPFLASH_WINDOWS @@ -49,3 +52,12 @@ uint32_t netmask(uint32_t count) { return htonl(count <= 32 ? 0xffffffff << (32 - count) : 0); } + +void xperror(const char *msg) +{ + if (errno != EINTR) { + perror(msg); + } else { + printf("\n"); + } +}