bool found;
if (getifaddrs(&ifas) != 0) {
- perror("getifaddrs");
+ xperror("getifaddrs");
return false;
}
adapters = malloc(bufLen);
if (!adapters) {
- perror("malloc");
+ xperror("malloc");
return false;
}
sock = malloc(sizeof(struct ethsock));
if (!sock) {
- perror("malloc");
+ xperror("malloc");
return NULL;
}
*undo = malloc(sizeof(struct ethsock_arp_undo));
if (!*undo) {
- perror("malloc");
+ xperror("malloc");
return -1;
}
strncpy(ifr.ifr_name, intf, IFNAMSIZ);
if (ioctl(fd, SIOCGIFFLAGS, &ifr) != 0) {
- perror("ioctl(SIOCGIFFLAGS)");
+ xperror("ioctl(SIOCGIFFLAGS)");
return false;
}
}
if (ioctl(fd, SIOCSIFFLAGS, &ifr) != 0) {
- perror("ioctl(SIOCSIFFLAGS)");
+ xperror("ioctl(SIOCSIFFLAGS)");
return false;
}
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;
}
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;
}
//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;
}
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 = "\\|/-";
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 {
return 1;
}
- gsock = sock;
sigh_orig = signal(SIGINT, sigh);
if (!autoip) {
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;
}
}
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;
}
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));
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;
}
msg_hton(&tx.msg);
if (pkt_send(sock, &tx) < 0) {
- perror("sendto");
+ xperror("sendto");
goto out;
}
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;
}
#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
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;
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
sock = -1;
ret = -1;
+ if (g_interrupted) {
+ goto cleanup;
+ }
+
if (!strcmp(args->file_local, "-")) {
fd = STDIN_FILENO;
if (!file_remote) {
} 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) {
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;
}
}
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);
pkt_mkwrq(tx, file_remote);
- do {
+ while (!g_interrupted) {
if (!timeout && pkt_num(rx) == ACK) {
ackblock = pkt_num(rx + 2);
} else {
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) {
addr.sin_port = htons(port);
}
}
- } while(1);
+ }
- ret = 0;
+ ret = !g_interrupted ? 0 : -1;
cleanup:
if (fd >= 0) {
#include <stdio.h>
+#include <errno.h>
#include <time.h>
#include <math.h>
#include "nmrpd.h"
#include <mach/mach_time.h>
#endif
+volatile sig_atomic_t g_interrupted = 0;
+
time_t time_monotonic()
{
#ifndef NMRPFLASH_WINDOWS
{
return htonl(count <= 32 ? 0xffffffff << (32 - count) : 0);
}
+
+void xperror(const char *msg)
+{
+ if (errno != EINTR) {
+ perror(msg);
+ } else {
+ printf("\n");
+ }
+}