Use safe SIGINT handler
This commit is contained in:
parent
b9504f17c8
commit
98fdb9e63c
5 changed files with 63 additions and 54 deletions
20
ethsock.c
20
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;
|
||||
}
|
||||
|
||||
|
|
49
nmrp.c
49
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;
|
||||
}
|
||||
|
|
18
nmrpd.h
18
nmrpd.h
|
@ -20,24 +20,25 @@
|
|||
#ifndef NMRPD_H
|
||||
#define NMRPD_H
|
||||
#include <stdint.h>
|
||||
#include <signal.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#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
|
||||
|
|
18
tftp.c
18
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) {
|
||||
|
|
12
util.c
12
util.c
|
@ -1,4 +1,5 @@
|
|||
#include <stdio.h>
|
||||
#include <errno.h>
|
||||
#include <time.h>
|
||||
#include <math.h>
|
||||
#include "nmrpd.h"
|
||||
|
@ -7,6 +8,8 @@
|
|||
#include <mach/mach_time.h>
|
||||
#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");
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue