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