+#define NOTHING
+#define DECL_WINSOCK_FUNCTION(linkage, rettype, name, params) \
+ typedef rettype (WINAPI *t_##name) params; \
+ linkage t_##name p_##name
+#define GET_WINSOCK_FUNCTION(name) \
+ p_##name = (t_##name) GetProcAddress(winsock_module, #name)
+
+DECL_WINSOCK_FUNCTION(NOTHING, int, WSAAsyncSelect,
+ (SOCKET, HWND, u_int, long));
+DECL_WINSOCK_FUNCTION(NOTHING, int, WSAEventSelect, (SOCKET, WSAEVENT, long));
+DECL_WINSOCK_FUNCTION(NOTHING, int, select,
+ (int, fd_set FAR *, fd_set FAR *,
+ fd_set FAR *, const struct timeval FAR *));
+DECL_WINSOCK_FUNCTION(NOTHING, int, WSAGetLastError, (void));
+DECL_WINSOCK_FUNCTION(NOTHING, int, WSAEnumNetworkEvents,
+ (SOCKET, WSAEVENT, LPWSANETWORKEVENTS));
+DECL_WINSOCK_FUNCTION(static, int, WSAStartup, (WORD, LPWSADATA));
+DECL_WINSOCK_FUNCTION(static, int, WSACleanup, (void));
+DECL_WINSOCK_FUNCTION(static, int, closesocket, (SOCKET));
+DECL_WINSOCK_FUNCTION(static, u_long, ntohl, (u_long));
+DECL_WINSOCK_FUNCTION(static, u_long, htonl, (u_long));
+DECL_WINSOCK_FUNCTION(static, u_short, htons, (u_short));
+DECL_WINSOCK_FUNCTION(static, u_short, ntohs, (u_short));
+DECL_WINSOCK_FUNCTION(static, struct hostent FAR *, gethostbyname,
+ (const char FAR *));
+DECL_WINSOCK_FUNCTION(static, struct servent FAR *, getservbyname,
+ (const char FAR *, const char FAR *));
+DECL_WINSOCK_FUNCTION(static, unsigned long, inet_addr, (const char FAR *));
+DECL_WINSOCK_FUNCTION(static, char FAR *, inet_ntoa, (struct in_addr));
+DECL_WINSOCK_FUNCTION(static, int, connect,
+ (SOCKET, const struct sockaddr FAR *, int));
+DECL_WINSOCK_FUNCTION(static, int, bind,
+ (SOCKET, const struct sockaddr FAR *, int));
+DECL_WINSOCK_FUNCTION(static, int, setsockopt,
+ (SOCKET, int, int, const char FAR *, int));
+DECL_WINSOCK_FUNCTION(static, SOCKET, socket, (int, int, int));
+DECL_WINSOCK_FUNCTION(static, int, listen, (SOCKET, int));
+DECL_WINSOCK_FUNCTION(static, int, send, (SOCKET, const char FAR *, int, int));
+DECL_WINSOCK_FUNCTION(static, int, ioctlsocket,
+ (SOCKET, long, u_long FAR *));
+DECL_WINSOCK_FUNCTION(static, SOCKET, accept,
+ (SOCKET, struct sockaddr FAR *, int FAR *));
+DECL_WINSOCK_FUNCTION(static, int, recv, (SOCKET, char FAR *, int, int));
+DECL_WINSOCK_FUNCTION(static, int, WSAIoctl,
+ (SOCKET, DWORD, LPVOID, DWORD, LPVOID, DWORD,
+ LPDWORD, LPWSAOVERLAPPED,
+ LPWSAOVERLAPPED_COMPLETION_ROUTINE));
+
+static HMODULE winsock_module;
+
+void sk_init(void)
+{
+ WORD winsock_ver;
+ WSADATA wsadata;
+
+ winsock_ver = MAKEWORD(2, 0);
+ winsock_module = LoadLibrary("WS2_32.DLL");
+ if (!winsock_module) {
+ winsock_module = LoadLibrary("WSOCK32.DLL");
+ winsock_ver = MAKEWORD(1, 1);
+ }
+ if (!winsock_module)
+ fatalbox("Unable to load any WinSock library");
+
+ GET_WINSOCK_FUNCTION(WSAAsyncSelect);
+ GET_WINSOCK_FUNCTION(WSAEventSelect);
+ GET_WINSOCK_FUNCTION(select);
+ GET_WINSOCK_FUNCTION(WSAGetLastError);
+ GET_WINSOCK_FUNCTION(WSAEnumNetworkEvents);
+ GET_WINSOCK_FUNCTION(WSAStartup);
+ GET_WINSOCK_FUNCTION(WSACleanup);
+ GET_WINSOCK_FUNCTION(closesocket);
+ GET_WINSOCK_FUNCTION(ntohl);
+ GET_WINSOCK_FUNCTION(htonl);
+ GET_WINSOCK_FUNCTION(htons);
+ GET_WINSOCK_FUNCTION(ntohs);
+ GET_WINSOCK_FUNCTION(gethostbyname);
+ GET_WINSOCK_FUNCTION(getservbyname);
+ GET_WINSOCK_FUNCTION(inet_addr);
+ GET_WINSOCK_FUNCTION(inet_ntoa);
+ GET_WINSOCK_FUNCTION(connect);
+ GET_WINSOCK_FUNCTION(bind);
+ GET_WINSOCK_FUNCTION(setsockopt);
+ GET_WINSOCK_FUNCTION(socket);
+ GET_WINSOCK_FUNCTION(listen);
+ GET_WINSOCK_FUNCTION(send);
+ GET_WINSOCK_FUNCTION(ioctlsocket);
+ GET_WINSOCK_FUNCTION(accept);
+ GET_WINSOCK_FUNCTION(recv);
+ GET_WINSOCK_FUNCTION(WSAIoctl);
+
+ if (p_WSAStartup(winsock_ver, &wsadata)) {
+ fatalbox("Unable to initialise WinSock");
+ }
+ if (LOBYTE(wsadata.wVersion) != LOBYTE(winsock_ver)) {
+ p_WSACleanup();
+ fatalbox("WinSock version is incompatible with %d.%d",
+ LOBYTE(winsock_ver), HIBYTE(winsock_ver));
+ }
+