#define _XOPEN_SOURCE 500 #include #include #include #include #include #include #include <86box/86box.h> #include <86box/log.h> #include <86box/timer.h> #include <86box/plat.h> #include <86box/device.h> #include <86box/plat_netsocket.h> #include <86box/ui.h> #include #include #include SOCKET plat_netsocket_create(int type) { SOCKET socket = -1; u_long yes = 1; if (type != NET_SOCKET_TCP) return -1; socket = WSASocketA(AF_INET, SOCK_STREAM, IPPROTO_TCP, NULL, 0, WSA_FLAG_OVERLAPPED); if (socket == INVALID_SOCKET) return -1; ioctlsocket(socket, FIONBIO, &yes); return socket; } SOCKET plat_netsocket_create_server(int type, unsigned short port) { struct sockaddr_in sock_addr; SOCKET socket = plat_netsocket_create(type); if (socket == INVALID_SOCKET) return (SOCKET)-1; memset(&sock_addr, 0, sizeof(struct sockaddr_in)); sock_addr.sin_family = AF_INET; sock_addr.sin_addr.s_addr = INADDR_ANY; sock_addr.sin_port = port; if (bind(socket, (struct sockaddr *)&sock_addr, sizeof(struct sockaddr_in)) == SOCKET_ERROR) { plat_netsocket_close(socket); return (SOCKET)-1; } if (listen(socket, 5) == SOCKET_ERROR) { plat_netsocket_close(socket); return (SOCKET)-1; } return socket; } void plat_netsocket_close(SOCKET socket) { closesocket((SOCKET)socket); } SOCKET plat_netsocket_accept(SOCKET socket) { SOCKET clientsocket = accept(socket, NULL, NULL); if (clientsocket == INVALID_SOCKET) return -1; return clientsocket; } int plat_netsocket_connected(SOCKET socket) { struct sockaddr addr; socklen_t len = sizeof(struct sockaddr); if (getpeername(socket, &addr, &len) == SOCKET_ERROR) return 0; return 1; } int plat_netsocket_connect(SOCKET socket, const char* hostname, unsigned short port) { struct sockaddr_in sock_addr; int res = -1; sock_addr.sin_family = AF_INET; sock_addr.sin_addr.s_addr = inet_addr(hostname); sock_addr.sin_port = htons(port); if (sock_addr.sin_addr.s_addr == -1 || sock_addr.sin_addr.s_addr == 0) { struct hostent *hp; hp = gethostbyname(hostname); if (hp) memcpy(&sock_addr.sin_addr.s_addr, hp->h_addr_list[0], hp->h_length); else return -1; } res = connect(socket, (struct sockaddr *)&sock_addr, sizeof(struct sockaddr_in)); if (res == SOCKET_ERROR) { int error = WSAGetLastError(); if (error == WSAEISCONN) return 0; res = -1; } return res; } int plat_netsocket_send(SOCKET socket, const unsigned char* data, unsigned int size, int *wouldblock) { int res = send(socket, (const char*)data, size, 0); if (res == SOCKET_ERROR) { int error = WSAGetLastError(); if (wouldblock) *wouldblock = !!(error == WSAEWOULDBLOCK); return -1; } return res; } int plat_netsocket_receive(SOCKET socket, unsigned char* data, unsigned int size, int *wouldblock) { int res = recv(socket, (char*)data, size, 0); if (res == SOCKET_ERROR) { int error = WSAGetLastError(); if (wouldblock) *wouldblock = !!(error == WSAEWOULDBLOCK); return -1; } return res; }