mirror of
https://github.com/switchbrew/switch-tools.git
synced 2025-06-22 14:02:40 +02:00
Use poll to avoid busy-looping
This commit is contained in:
parent
72b9e5cc85
commit
1b660e22c3
361
src/nxlink.c
361
src/nxlink.c
@ -14,11 +14,20 @@
|
|||||||
#include <arpa/inet.h>
|
#include <arpa/inet.h>
|
||||||
#include <netinet/in.h>
|
#include <netinet/in.h>
|
||||||
#include <netdb.h>
|
#include <netdb.h>
|
||||||
|
#include <poll.h>
|
||||||
|
#define closesocket close
|
||||||
#else
|
#else
|
||||||
#include <winsock2.h>
|
#include <winsock2.h>
|
||||||
#include <ws2tcpip.h>
|
#include <ws2tcpip.h>
|
||||||
typedef int socklen_t;
|
typedef int socklen_t;
|
||||||
typedef uint32_t in_addr_t;
|
typedef uint32_t in_addr_t;
|
||||||
|
#define SHUT_RD SD_RECEIVE
|
||||||
|
#define SHUT_WR SD_SEND
|
||||||
|
#define SHUT_RDWR SD_BOTH
|
||||||
|
#ifndef EWOULDBLOCK
|
||||||
|
#define EWOULDBLOCK WSAEWOULDBLOCK
|
||||||
|
#define poll WSAPoll
|
||||||
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <zlib.h>
|
#include <zlib.h>
|
||||||
@ -30,25 +39,21 @@ typedef uint32_t in_addr_t;
|
|||||||
#define NETLOADER_CLIENT_PORT 28771
|
#define NETLOADER_CLIENT_PORT 28771
|
||||||
|
|
||||||
|
|
||||||
char cmdbuf[3072];
|
static char cmdbuf[3072];
|
||||||
uint32_t cmdlen=0;
|
static uint32_t cmdlen=0;
|
||||||
|
|
||||||
//---------------------------------------------------------------------------------
|
//---------------------------------------------------------------------------------
|
||||||
void shutdownSocket(int socket) {
|
static void shutdownSocket(int socket, int flags) {
|
||||||
//---------------------------------------------------------------------------------
|
//---------------------------------------------------------------------------------
|
||||||
#ifdef __WIN32__
|
if (flags)
|
||||||
shutdown (socket, SD_SEND);
|
shutdown(socket, flags);
|
||||||
closesocket(socket);
|
closesocket(socket);
|
||||||
#else
|
|
||||||
close(socket);
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//---------------------------------------------------------------------------------
|
//---------------------------------------------------------------------------------
|
||||||
static int set_socket_nonblocking(int sock) {
|
static int setSocketNonblocking(int sock) {
|
||||||
//---------------------------------------------------------------------------------
|
//---------------------------------------------------------------------------------
|
||||||
|
|
||||||
#ifndef __WIN32__
|
|
||||||
int flags = fcntl(sock, F_GETFL);
|
int flags = fcntl(sock, F_GETFL);
|
||||||
|
|
||||||
if (flags == -1) return -1;
|
if (flags == -1) return -1;
|
||||||
@ -57,73 +62,60 @@ static int set_socket_nonblocking(int sock) {
|
|||||||
|
|
||||||
if (rc != 0) return -1;
|
if (rc != 0) return -1;
|
||||||
|
|
||||||
#else
|
|
||||||
u_long opt = 1;
|
|
||||||
ioctlsocket(sock, FIONBIO, &opt);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void socket_error(const char *msg) {
|
//---------------------------------------------------------------------------------
|
||||||
|
static int socketError(const char *msg) {
|
||||||
|
//---------------------------------------------------------------------------------
|
||||||
#ifndef _WIN32
|
#ifndef _WIN32
|
||||||
|
int ret = errno;
|
||||||
|
if (ret == EAGAIN)
|
||||||
|
ret = EWOULDBLOCK;
|
||||||
perror(msg);
|
perror(msg);
|
||||||
#else
|
#else
|
||||||
|
int ret = WSAGetLastError();
|
||||||
wchar_t *s = NULL;
|
wchar_t *s = NULL;
|
||||||
FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
|
FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
|
||||||
NULL, WSAGetLastError(),
|
NULL, ret,
|
||||||
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
|
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
|
||||||
(LPWSTR)&s, 0, NULL);
|
(LPWSTR)&s, 0, NULL);
|
||||||
fprintf(stderr, "%S\n", s);
|
fprintf(stderr, "%S\n", s);
|
||||||
LocalFree(s);
|
LocalFree(s);
|
||||||
|
if (ret == WSAEWOULDBLOCK)
|
||||||
|
ret = EWOULDBLOCK;
|
||||||
#endif
|
#endif
|
||||||
}
|
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------------
|
return ret;
|
||||||
Subtract the `struct timeval' values Y from X,
|
|
||||||
storing the result in RESULT.
|
|
||||||
Return 1 if the difference is negative, otherwise 0.
|
|
||||||
|
|
||||||
From http://www.gnu.org/software/libtool/manual/libc/Elapsed-Time.html
|
|
||||||
---------------------------------------------------------------------------------*/
|
|
||||||
int timeval_subtract (struct timeval *result, struct timeval *x, struct timeval *y) {
|
|
||||||
//---------------------------------------------------------------------------------
|
|
||||||
struct timeval tmp;
|
|
||||||
tmp.tv_sec = y->tv_sec;
|
|
||||||
tmp.tv_usec = y->tv_usec;
|
|
||||||
|
|
||||||
/* Perform the carry for the later subtraction by updating y. */
|
|
||||||
if (x->tv_usec < tmp.tv_usec) {
|
|
||||||
int nsec = (tmp.tv_usec - x->tv_usec) / 1000000 + 1;
|
|
||||||
tmp.tv_usec -= 1000000 * nsec;
|
|
||||||
tmp.tv_sec += nsec;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (x->tv_usec - tmp.tv_usec > 1000000) {
|
|
||||||
int nsec = (x->tv_usec - tmp.tv_usec) / 1000000;
|
|
||||||
tmp.tv_usec += 1000000 * nsec;
|
|
||||||
tmp.tv_sec -= nsec;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Compute the time remaining to wait.
|
|
||||||
tv_usec is certainly positive. */
|
|
||||||
result->tv_sec = x->tv_sec - tmp.tv_sec;
|
|
||||||
result->tv_usec = x->tv_usec - tmp.tv_usec;
|
|
||||||
|
|
||||||
/* Return 1 if result is negative. */
|
|
||||||
return x->tv_sec < tmp.tv_sec;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//---------------------------------------------------------------------------------
|
//---------------------------------------------------------------------------------
|
||||||
void timeval_add (struct timeval *result, struct timeval *x, struct timeval *y) {
|
int pollSocket(int fd, int events, int timeout) {
|
||||||
//---------------------------------------------------------------------------------
|
//---------------------------------------------------------------------------------
|
||||||
result->tv_sec = x->tv_sec + y->tv_sec;
|
struct pollfd pfd;
|
||||||
result->tv_usec = x->tv_usec + y->tv_usec;
|
|
||||||
|
|
||||||
if ( result->tv_usec > 1000000) {
|
pfd.fd = fd;
|
||||||
result->tv_sec += result->tv_usec / 1000000;
|
pfd.events = events;
|
||||||
result->tv_usec = result->tv_usec % 1000000;
|
pfd.revents = 0;
|
||||||
|
|
||||||
|
int ret = poll(&pfd, 1, timeout);
|
||||||
|
if (ret < 0) {
|
||||||
|
socketError("poll");
|
||||||
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (ret == 0)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
if (!(pfd.revents & events)) {
|
||||||
|
int err = 0;
|
||||||
|
int len = sizeof(err);
|
||||||
|
getsockopt(fd, SOL_SOCKET, SO_ERROR, (char*)&err, &len);
|
||||||
|
fprintf(stderr, "socket error 0x%x on poll\n", err);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
//---------------------------------------------------------------------------------
|
//---------------------------------------------------------------------------------
|
||||||
@ -137,7 +129,7 @@ static struct in_addr findSwitch(int retries) {
|
|||||||
char mess[] = "nxboot";
|
char mess[] = "nxboot";
|
||||||
|
|
||||||
int broadcastSock = socket(PF_INET, SOCK_DGRAM, 0);
|
int broadcastSock = socket(PF_INET, SOCK_DGRAM, 0);
|
||||||
if(broadcastSock < 0) socket_error("create send socket");
|
if (broadcastSock < 0) socketError("create send socket");
|
||||||
|
|
||||||
int optval = 1, len;
|
int optval = 1, len;
|
||||||
setsockopt(broadcastSock, SOL_SOCKET, SO_BROADCAST, (char *)&optval, sizeof(optval));
|
setsockopt(broadcastSock, SOL_SOCKET, SO_BROADCAST, (char *)&optval, sizeof(optval));
|
||||||
@ -154,25 +146,16 @@ static struct in_addr findSwitch(int retries) {
|
|||||||
|
|
||||||
int recvSock = socket(PF_INET, SOCK_DGRAM, 0);
|
int recvSock = socket(PF_INET, SOCK_DGRAM, 0);
|
||||||
|
|
||||||
if (recvSock < 0) socket_error("create receive socket");
|
if (recvSock < 0) socketError("create receive socket");
|
||||||
|
|
||||||
if(bind(recvSock, (struct sockaddr*) &rs, sizeof(rs)) < 0) socket_error("bind receive socket");
|
if (bind(recvSock, (struct sockaddr*) &rs, sizeof(rs)) < 0) socketError("bind receive socket");
|
||||||
set_socket_nonblocking(recvSock);
|
setSocketNonblocking(recvSock);
|
||||||
|
|
||||||
struct timeval wanted, now, result;
|
while (retries) {
|
||||||
|
if (sendto(broadcastSock, mess, strlen(mess), 0, (struct sockaddr *)&s, sizeof(s)) < 0)
|
||||||
|
socketError("sendto");
|
||||||
|
|
||||||
gettimeofday(&wanted, NULL);
|
if (pollSocket(recvSock, POLLIN, 150) == 0) {
|
||||||
|
|
||||||
int timeout = retries;
|
|
||||||
while(timeout) {
|
|
||||||
gettimeofday(&now, NULL);
|
|
||||||
if ( timeval_subtract(&result,&wanted,&now)) {
|
|
||||||
if(sendto(broadcastSock, mess, strlen(mess), 0, (struct sockaddr *)&s, sizeof(s)) < 0) socket_error("sendto");
|
|
||||||
result.tv_sec=0;
|
|
||||||
result.tv_usec=150000;
|
|
||||||
timeval_add(&wanted,&now,&result);
|
|
||||||
timeout--;
|
|
||||||
}
|
|
||||||
socklen_t socklen = sizeof(remote);
|
socklen_t socklen = sizeof(remote);
|
||||||
len = recvfrom(recvSock, recvbuf, sizeof(recvbuf), 0, (struct sockaddr *)&remote, &socklen);
|
len = recvfrom(recvSock, recvbuf, sizeof(recvbuf), 0, (struct sockaddr *)&remote, &socklen);
|
||||||
if (len != -1) {
|
if (len != -1) {
|
||||||
@ -181,75 +164,71 @@ static struct in_addr findSwitch(int retries) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (timeout == 0) remote.sin_addr.s_addr = INADDR_NONE;
|
|
||||||
shutdownSocket(broadcastSock);
|
--retries;
|
||||||
shutdownSocket(recvSock);
|
}
|
||||||
|
|
||||||
|
if (retries == 0)
|
||||||
|
remote.sin_addr.s_addr = INADDR_NONE;
|
||||||
|
|
||||||
|
shutdownSocket(broadcastSock, 0);
|
||||||
|
shutdownSocket(recvSock, SHUT_RD);
|
||||||
|
|
||||||
return remote.sin_addr;
|
return remote.sin_addr;
|
||||||
}
|
}
|
||||||
|
|
||||||
//---------------------------------------------------------------------------------
|
//---------------------------------------------------------------------------------
|
||||||
int sendData(int sock, int sendsize, void *buffer) {
|
static int sendData(int sock, int sendsize, void *buffer) {
|
||||||
//---------------------------------------------------------------------------------
|
//---------------------------------------------------------------------------------
|
||||||
char *buf = (char*)buffer;
|
char *buf = (char*)buffer;
|
||||||
while (sendsize) {
|
while (sendsize) {
|
||||||
|
if (pollSocket(sock, POLLOUT, -1))
|
||||||
|
return 1;
|
||||||
|
|
||||||
int len = send(sock, buf, sendsize, 0);
|
int len = send(sock, buf, sendsize, 0);
|
||||||
if (len == 0) break;
|
if (len == 0)
|
||||||
if (len != -1) {
|
return 1;
|
||||||
|
|
||||||
|
if (len == -1) {
|
||||||
|
if (socketError("send") != EWOULDBLOCK)
|
||||||
|
return 1;
|
||||||
|
} else {
|
||||||
sendsize -= len;
|
sendsize -= len;
|
||||||
buf += len;
|
buf += len;
|
||||||
} else {
|
|
||||||
#ifdef _WIN32
|
|
||||||
int errcode = WSAGetLastError();
|
|
||||||
if (errcode != WSAEWOULDBLOCK) {
|
|
||||||
socket_error("sendData");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
if ( errno != EWOULDBLOCK && errno != EAGAIN) {
|
|
||||||
socket_error("sendData");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return sendsize != 0;
|
return sendsize != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
//---------------------------------------------------------------------------------
|
//---------------------------------------------------------------------------------
|
||||||
int recvData(int sock, void *buffer, int size, int flags) {
|
static int recvData(int sock, void *buffer, int size, int flags) {
|
||||||
//---------------------------------------------------------------------------------
|
//---------------------------------------------------------------------------------
|
||||||
int len, sizeleft = size;
|
int len, sizeleft = size;
|
||||||
char *buf = (char*)buffer;
|
char *buf = (char*)buffer;
|
||||||
while (sizeleft) {
|
while (sizeleft) {
|
||||||
|
if (pollSocket(sock, POLLIN, -1))
|
||||||
|
return 0;
|
||||||
|
|
||||||
len = recv(sock,buf,sizeleft,flags);
|
len = recv(sock,buf,sizeleft,flags);
|
||||||
if (len == 0) {
|
if (len == 0)
|
||||||
size = 0;
|
return 0;
|
||||||
break;
|
|
||||||
}
|
if (len == -1) {
|
||||||
if (len != -1) {
|
if (socketError("recv") != EWOULDBLOCK)
|
||||||
|
return 0;
|
||||||
|
} else {
|
||||||
sizeleft -=len;
|
sizeleft -=len;
|
||||||
buf +=len;
|
buf +=len;
|
||||||
} else {
|
|
||||||
#ifdef _WIN32
|
|
||||||
int errcode = WSAGetLastError();
|
|
||||||
if (errcode != WSAEWOULDBLOCK) {
|
|
||||||
printf("recvdata error %d\n",errcode);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
if ( errno != EWOULDBLOCK && errno != EAGAIN) {
|
|
||||||
socket_error("recvdata");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return size;
|
return size;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//---------------------------------------------------------------------------------
|
//---------------------------------------------------------------------------------
|
||||||
int sendInt32LE(int socket, uint32_t size) {
|
static int sendInt32LE(int socket, uint32_t size) {
|
||||||
//---------------------------------------------------------------------------------
|
//---------------------------------------------------------------------------------
|
||||||
unsigned char lenbuf[4];
|
unsigned char lenbuf[4];
|
||||||
lenbuf[0] = size & 0xff;
|
lenbuf[0] = size & 0xff;
|
||||||
@ -261,7 +240,7 @@ int sendInt32LE(int socket, uint32_t size) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
//---------------------------------------------------------------------------------
|
//---------------------------------------------------------------------------------
|
||||||
int recvInt32LE(int socket, int32_t *data) {
|
static int recvInt32LE(int socket, int32_t *data) {
|
||||||
//---------------------------------------------------------------------------------
|
//---------------------------------------------------------------------------------
|
||||||
unsigned char intbuf[4];
|
unsigned char intbuf[4];
|
||||||
int len = recvData(socket, intbuf, 4, 0);
|
int len = recvData(socket, intbuf, 4, 0);
|
||||||
@ -272,14 +251,13 @@ int recvInt32LE(int socket, int32_t *data) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned char in[ZLIB_CHUNK];
|
static unsigned char in[ZLIB_CHUNK];
|
||||||
unsigned char out[ZLIB_CHUNK];
|
static unsigned char out[ZLIB_CHUNK];
|
||||||
|
|
||||||
//---------------------------------------------------------------------------------
|
//---------------------------------------------------------------------------------
|
||||||
int sendNROFile(in_addr_t nxaddr, char *name, size_t filesize, FILE *fh) {
|
static int sendNROFile(in_addr_t nxaddr, char *name, size_t filesize, FILE *fh) {
|
||||||
//---------------------------------------------------------------------------------
|
//---------------------------------------------------------------------------------
|
||||||
|
|
||||||
int retval = 0;
|
int retval = 0;
|
||||||
@ -297,7 +275,7 @@ int sendNROFile(in_addr_t nxaddr, char *name, size_t filesize, FILE *fh) {
|
|||||||
|
|
||||||
int sock = socket(AF_INET,SOCK_STREAM,0);
|
int sock = socket(AF_INET,SOCK_STREAM,0);
|
||||||
if (sock < 0) {
|
if (sock < 0) {
|
||||||
socket_error("create connection socket");
|
socketError("create connection socket");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -421,12 +399,12 @@ int sendNROFile(in_addr_t nxaddr, char *name, size_t filesize, FILE *fh) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
error:
|
error:
|
||||||
shutdownSocket(sock);
|
shutdownSocket(sock, SHUT_WR);
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
//---------------------------------------------------------------------------------
|
//---------------------------------------------------------------------------------
|
||||||
void showHelp() {
|
static void showHelp() {
|
||||||
//---------------------------------------------------------------------------------
|
//---------------------------------------------------------------------------------
|
||||||
puts("Usage: nxlink [options] nrofile\n");
|
puts("Usage: nxlink [options] nrofile\n");
|
||||||
puts("--help, -h Display this information");
|
puts("--help, -h Display this information");
|
||||||
@ -440,7 +418,7 @@ void showHelp() {
|
|||||||
|
|
||||||
|
|
||||||
//---------------------------------------------------------------------------------
|
//---------------------------------------------------------------------------------
|
||||||
int add_extra_args(int len, char *buf, char *extra_args) {
|
static int addExtraArgs(int len, char *buf, char *extra_args) {
|
||||||
//---------------------------------------------------------------------------------
|
//---------------------------------------------------------------------------------
|
||||||
|
|
||||||
if (NULL==extra_args) return len;
|
if (NULL==extra_args) return len;
|
||||||
@ -498,7 +476,7 @@ int main(int argc, char **argv) {
|
|||||||
|
|
||||||
if (argc < 2) {
|
if (argc < 2) {
|
||||||
showHelp();
|
showHelp();
|
||||||
return 1;
|
return EXIT_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
while (1) {
|
while (1) {
|
||||||
@ -543,7 +521,7 @@ int main(int argc, char **argv) {
|
|||||||
break;
|
break;
|
||||||
case 'h':
|
case 'h':
|
||||||
showHelp();
|
showHelp();
|
||||||
return 1;
|
return EXIT_FAILURE;
|
||||||
case NRO_ARGS:
|
case NRO_ARGS:
|
||||||
extra_args=optarg;
|
extra_args=optarg;
|
||||||
break;
|
break;
|
||||||
@ -554,7 +532,7 @@ int main(int argc, char **argv) {
|
|||||||
char *filename = argv[optind++];
|
char *filename = argv[optind++];
|
||||||
if (filename== NULL) {
|
if (filename== NULL) {
|
||||||
showHelp();
|
showHelp();
|
||||||
return 1;
|
return EXIT_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
memset(cmdbuf, '\0', sizeof(cmdbuf));
|
memset(cmdbuf, '\0', sizeof(cmdbuf));
|
||||||
@ -562,7 +540,7 @@ int main(int argc, char **argv) {
|
|||||||
FILE *fh = fopen(filename,"rb");
|
FILE *fh = fopen(filename,"rb");
|
||||||
if (fh == NULL) {
|
if (fh == NULL) {
|
||||||
fprintf(stderr,"Failed to open %s\n",filename);
|
fprintf(stderr,"Failed to open %s\n",filename);
|
||||||
return -1;
|
return EXIT_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
@ -604,7 +582,7 @@ int main(int argc, char **argv) {
|
|||||||
cmdlen+= len + 1;
|
cmdlen+= len + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
cmdlen = add_extra_args(cmdlen, &cmdbuf[4], extra_args);
|
cmdlen = addExtraArgs(cmdlen, &cmdbuf[4], extra_args);
|
||||||
|
|
||||||
cmdbuf[0] = cmdlen & 0xff;
|
cmdbuf[0] = cmdlen & 0xff;
|
||||||
cmdbuf[1] = (cmdlen>>8) & 0xff;
|
cmdbuf[1] = (cmdlen>>8) & 0xff;
|
||||||
@ -615,8 +593,9 @@ int main(int argc, char **argv) {
|
|||||||
WSADATA wsa_data;
|
WSADATA wsa_data;
|
||||||
if (WSAStartup (MAKEWORD(2,2), &wsa_data)) {
|
if (WSAStartup (MAKEWORD(2,2), &wsa_data)) {
|
||||||
printf ("WSAStartup failed\n");
|
printf ("WSAStartup failed\n");
|
||||||
return 1;
|
return EXIT_FAILURE;
|
||||||
}
|
}
|
||||||
|
atexit(&WSACleanup);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
struct in_addr nxaddr;
|
struct in_addr nxaddr;
|
||||||
@ -627,7 +606,7 @@ int main(int argc, char **argv) {
|
|||||||
|
|
||||||
if (nxaddr.s_addr == INADDR_NONE) {
|
if (nxaddr.s_addr == INADDR_NONE) {
|
||||||
printf("No response from Switch!\n");
|
printf("No response from Switch!\n");
|
||||||
return 1;
|
return EXIT_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
@ -640,14 +619,19 @@ int main(int argc, char **argv) {
|
|||||||
|
|
||||||
if (nxaddr.s_addr == INADDR_NONE) {
|
if (nxaddr.s_addr == INADDR_NONE) {
|
||||||
fprintf(stderr,"Invalid address\n");
|
fprintf(stderr,"Invalid address\n");
|
||||||
return 1;
|
return EXIT_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
int res = sendNROFile(nxaddr.s_addr,finalpath,filesize,fh);
|
int res = sendNROFile(nxaddr.s_addr,finalpath,filesize,fh);
|
||||||
|
|
||||||
fclose(fh);
|
fclose(fh);
|
||||||
|
|
||||||
if ( res == 0 && server) {
|
if (res != 0)
|
||||||
|
return EXIT_FAILURE;
|
||||||
|
|
||||||
|
if (!server)
|
||||||
|
return EXIT_SUCCESS;
|
||||||
|
|
||||||
printf("starting server\n");
|
printf("starting server\n");
|
||||||
|
|
||||||
struct sockaddr_in serv_addr;
|
struct sockaddr_in serv_addr;
|
||||||
@ -658,97 +642,74 @@ int main(int argc, char **argv) {
|
|||||||
serv_addr.sin_port = htons(NETLOADER_CLIENT_PORT);
|
serv_addr.sin_port = htons(NETLOADER_CLIENT_PORT);
|
||||||
|
|
||||||
int listenfd = socket(AF_INET, SOCK_STREAM, 0);
|
int listenfd = socket(AF_INET, SOCK_STREAM, 0);
|
||||||
int rc;
|
|
||||||
|
|
||||||
if (listenfd < 0) {
|
if (listenfd < 0) {
|
||||||
socket_error("socket");
|
socketError("socket");
|
||||||
} else {
|
return EXIT_FAILURE;
|
||||||
|
}
|
||||||
rc = bind(listenfd, (struct sockaddr*)&serv_addr, sizeof(serv_addr));
|
|
||||||
|
|
||||||
|
int rc = bind(listenfd, (struct sockaddr*)&serv_addr, sizeof(serv_addr));
|
||||||
if (rc != 0) {
|
if (rc != 0) {
|
||||||
socket_error("bind listen socket");
|
socketError("bind listen socket");
|
||||||
} else {
|
shutdownSocket(listenfd, 0);
|
||||||
if (set_socket_nonblocking(listenfd) == -1) {
|
return EXIT_FAILURE;
|
||||||
socket_error("listen fcntl");
|
}
|
||||||
|
|
||||||
|
rc = setSocketNonblocking(listenfd);
|
||||||
|
if (rc == -1) {
|
||||||
|
socketError("listen fcntl");
|
||||||
|
shutdownSocket(listenfd, 0);
|
||||||
|
return EXIT_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
} else {
|
|
||||||
rc = listen(listenfd, 10);
|
rc = listen(listenfd, 10);
|
||||||
|
|
||||||
if (rc != 0) {
|
if (rc != 0) {
|
||||||
socket_error("listen");
|
socketError("listen");
|
||||||
} else {
|
shutdownSocket(listenfd, 0);
|
||||||
|
return EXIT_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
printf("server active ...\n");
|
printf("server active ...\n");
|
||||||
|
|
||||||
int datafd = -1;
|
int datafd = -1;
|
||||||
|
|
||||||
while (listenfd != -1 || datafd != -1) {
|
while (listenfd != -1 || datafd != -1) {
|
||||||
struct sockaddr_in sa_remote;
|
struct sockaddr_in sa_remote;
|
||||||
if(listenfd >= 0 && datafd < 0) {
|
|
||||||
|
if (pollSocket(listenfd >= 0 ? listenfd : datafd, POLLIN, -1))
|
||||||
|
break;
|
||||||
|
|
||||||
|
if (listenfd >= 0) {
|
||||||
socklen_t addrlen = sizeof(sa_remote);
|
socklen_t addrlen = sizeof(sa_remote);
|
||||||
datafd = accept(listenfd, (struct sockaddr*)&sa_remote, &addrlen);
|
datafd = accept(listenfd, (struct sockaddr*)&sa_remote, &addrlen);
|
||||||
|
|
||||||
if(datafd < 0) {
|
if (datafd < 0 && socketError("accept") != EWOULDBLOCK)
|
||||||
#ifdef _WIN32
|
break;
|
||||||
int errcode = WSAGetLastError();
|
|
||||||
if (errcode != WSAEWOULDBLOCK) {
|
|
||||||
socket_error("accept");
|
|
||||||
listenfd = -1;
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
if ( errno != EWOULDBLOCK && errno != EAGAIN) {
|
|
||||||
socket_error("accept");
|
|
||||||
listenfd = -1;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
} else {
|
|
||||||
shutdownSocket(listenfd);
|
|
||||||
listenfd = -1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
if (datafd >= 0) {
|
if (datafd >= 0) {
|
||||||
char recvbuf[256];
|
shutdownSocket(listenfd, 0);
|
||||||
int len = recv(datafd,recvbuf,256,0);
|
listenfd = -1;
|
||||||
|
}
|
||||||
if (len > 0 ) {
|
|
||||||
recvbuf[len] = 0;
|
|
||||||
printf("%s", recvbuf);
|
|
||||||
} else {
|
} else {
|
||||||
|
char recvbuf[256];
|
||||||
|
int len = recv(datafd, recvbuf, sizeof(recvbuf), 0);
|
||||||
|
|
||||||
if (len == -1) {
|
if (len == 0 || (len < 0 && socketError("recv") != EWOULDBLOCK)) {
|
||||||
#ifdef _WIN32
|
shutdownSocket(datafd, 0);
|
||||||
int errcode = WSAGetLastError();
|
|
||||||
if (errcode != WSAEWOULDBLOCK) {
|
|
||||||
socket_error("recvdata");
|
|
||||||
len = 0;
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
if ( errno != EWOULDBLOCK && errno != EAGAIN) {
|
|
||||||
perror("recvdata");
|
|
||||||
len = 0;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
if (len ==0 ) {
|
|
||||||
shutdownSocket(datafd);
|
|
||||||
datafd = -1;
|
datafd = -1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (len > 0)
|
||||||
|
fwrite(recvbuf, 1, len, stdout);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
if (listenfd >= 0)
|
||||||
|
shutdownSocket(listenfd, 0);
|
||||||
|
if (datafd >= 0)
|
||||||
|
shutdownSocket(datafd, SHUT_RD);
|
||||||
|
|
||||||
printf("exiting ... \n");
|
printf("exiting ... \n");
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef __WIN32__
|
return EXIT_SUCCESS;
|
||||||
WSACleanup ();
|
|
||||||
#endif
|
|
||||||
return res;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user