summaryrefslogtreecommitdiffstats
path: root/ldap/c-sdk/libraries/libldap/mozock.c
diff options
context:
space:
mode:
Diffstat (limited to 'ldap/c-sdk/libraries/libldap/mozock.c')
-rw-r--r--ldap/c-sdk/libraries/libldap/mozock.c714
1 files changed, 714 insertions, 0 deletions
diff --git a/ldap/c-sdk/libraries/libldap/mozock.c b/ldap/c-sdk/libraries/libldap/mozock.c
new file mode 100644
index 000000000..4f0bc5750
--- /dev/null
+++ b/ldap/c-sdk/libraries/libldap/mozock.c
@@ -0,0 +1,714 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla Communicator client code, released
+ * March 31, 1998.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-1999
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of the GNU General Public License Version 2 or later (the "GPL"),
+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#ifdef _WINDOWS
+#define FD_SETSIZE 30000
+#endif
+
+#include <windows.h>
+#include <winsock.h>
+#include <string.h>
+
+// Purpose of this file is to implement an intermediate layer to our network
+// services, the winsock.
+// This intermediate layer will be able to function with and without a working
+// winsock being present.
+// The attempt to activate the winsock happens as would normally be expected,
+// through the calling application's entry point to us, WSAStartup.
+
+
+// Name of the winsock we would like to load.
+// Diffs between OSs, Win32s is out in the cold if running 32 bits unless
+// they also have a winsock name wsock32.dll.
+#ifndef _WIN32
+#define SZWINSOCK "winsock.dll"
+#else
+#define SZWINSOCK "wsock32.dll"
+#endif
+
+// Here is the enumeration for the winsock functions we have currently
+// overridden (needed to run). Add more when needed.
+// We use these to access proc addresses, and to hold a table of strings
+// to obtain the proc addresses.
+enum SockProc {
+ sp_WSAAsyncGetHostByName = 0,
+ sp_WSAAsyncSelect,
+ sp_WSACleanup,
+ sp_WSAGetLastError,
+ sp_WSASetLastError,
+ sp_WSAStartup,
+ sp___WSAFDIsSet,
+ sp_accept,
+ sp_bind,
+ sp_closesocket,
+ sp_connect,
+ sp_gethostbyname,
+ sp_gethostbyaddr,
+ sp_gethostname,
+ sp_getpeername,
+ sp_getsockname,
+ sp_getsockopt,
+ sp_getprotobyname,
+ sp_htonl,
+ sp_htons,
+ sp_inet_addr,
+ sp_ioctlsocket,
+ sp_listen,
+ sp_ntohl,
+ sp_ntohs,
+ sp_recv,
+ sp_select,
+ sp_send,
+ sp_setsockopt,
+ sp_shutdown,
+ sp_socket,
+ sp_inet_ntoa,
+
+ sp_MaxProcs // Total count.
+};
+
+// Array of function names used in GetProcAddress to fill in our
+// proc array when needed.
+// This array must match the enumerations exactly.
+char *spName[(int)sp_MaxProcs] = {
+ "WSAAsyncGetHostByName",
+ "WSAAsyncSelect",
+ "WSACleanup",
+ "WSAGetLastError",
+ "WSASetLastError",
+ "WSAStartup",
+ "__WSAFDIsSet",
+ "accept",
+ "bind",
+ "closesocket",
+ "connect",
+ "gethostbyname",
+ "gethostbyaddr",
+ "gethostname",
+ "getpeername",
+ "getsockname",
+ "getsockopt",
+ "getprotobyname",
+ "htonl",
+ "htons",
+ "inet_addr",
+ "ioctlsocket",
+ "listen",
+ "ntohl",
+ "ntohs",
+ "recv",
+ "select",
+ "send",
+ "setsockopt",
+ "shutdown",
+ "socket",
+ "inet_ntoa"
+};
+
+// Array of proc addresses to the winsock functions.
+// These can be NULL, indicating their absence (as in the case we couldn't
+// load the winsock.dll or one of the functions wasn't loaded).
+// The procs assigned in must corellate with the enumerations exactly.
+FARPROC spArray[(int)sp_MaxProcs];
+
+// Typedef all the different types of functions that we must cast the
+// procs to in order to call without the compiler barfing.
+// Prefix is always sp.
+// Retval is next, spelled out.
+// Parameters in their order are next, spelled out.
+typedef int (PASCAL FAR *sp_int_WORD_LPWSADATA)(WORD, LPWSADATA);
+typedef int (PASCAL FAR *sp_int_void)(void);
+typedef HANDLE (PASCAL FAR *sp_HANDLE_HWND_uint_ccharFARp_charFARp_int)(HWND, unsigned int, const char FAR *, char FAR *, int);
+typedef int (PASCAL FAR *sp_int_SOCKET_HWND_uint_long)(SOCKET, HWND, unsigned int, long);
+typedef void (PASCAL FAR *sp_void_int)(int);
+typedef int (PASCAL FAR *sp_int_SOCKET_fdsetFARp)(SOCKET, fd_set FAR *);
+typedef SOCKET(PASCAL FAR *sp_SOCKET_SOCKET_sockaddrFARp_intFARp)(SOCKET, struct sockaddr FAR *, int FAR *);
+typedef int (PASCAL FAR *sp_int_SOCKET_csockaddrFARp_int)(SOCKET, const struct sockaddr FAR *, int);
+typedef int (PASCAL FAR *sp_int_SOCKET)(SOCKET);
+typedef struct hostent FAR *(PASCAL FAR *sp_hostentFARp_ccharFARp)(const char FAR *);
+typedef struct hostent FAR *(PASCAL FAR *sp_hostentFARp_ccharFARp_int_int)(const char FAR *, int, int);
+typedef int (PASCAL FAR *sp_int_charFARp_int)(char FAR *, int);
+typedef int (PASCAL FAR *sp_int_SOCKET_sockaddrFARp_intFARp)(SOCKET, struct sockaddr FAR *, int FAR *);
+typedef int (PASCAL FAR *sp_int_SOCKET_int_int_charFARp_intFARp)(SOCKET, int, int, char FAR *, int FAR *);
+typedef u_long (PASCAL FAR *sp_ulong_ulong)(u_long);
+typedef u_short (PASCAL FAR *sp_ushort_ushort)(u_short);
+typedef unsigned long (PASCAL FAR *sp_ulong_ccharFARp)(const char FAR *);
+typedef int (PASCAL FAR *sp_int_SOCKET_long_ulongFARp)(SOCKET, long, u_long FAR *);
+typedef int (PASCAL FAR *sp_int_SOCKET_int)(SOCKET, int);
+typedef int (PASCAL FAR *sp_int_SOCKET_charFARp_int_int)(SOCKET, char FAR *, int, int);
+typedef int (PASCAL FAR *sp_int_int_fdsetFARp_fdsetFARp_fdsetFARp_ctimevalFARp)(int,fd_set FAR *,fd_set FAR *,fd_set FAR *,const struct timeval FAR*);
+typedef int (PASCAL FAR *sp_int_SOCKET_ccharFARp_int_int)(SOCKET, const char FAR *, int, int);
+typedef int (PASCAL FAR *sp_int_SOCKET_int_int_ccharFARp_int)(SOCKET, int, int, const char FAR *, int);
+typedef SOCKET (PASCAL FAR *sp_SOCKET_int_int_int)(int, int, int);
+typedef char FAR * (PASCAL FAR *sp_charFARp_in_addr)(struct in_addr in);
+typedef struct protoent FAR * (PASCAL FAR *sp_protoentFARcchar)(const char FAR *);
+
+// Handle to the winsock, if loaded.
+HINSTANCE hWinsock = NULL;
+
+#ifndef _WIN32
+// Last error code for the winsock.
+int ispError = 0;
+#endif
+
+
+BOOL IsWinsockLoaded (int sp)
+{
+ if (hWinsock == NULL)
+ {
+ WSADATA wsaData;
+#ifdef _WIN32
+ static LONG sc_init = 0;
+ static DWORD sc_done = 0;
+ static CRITICAL_SECTION sc;
+#endif
+ /* We need to wait here because another thread might be
+ in the routine already */
+#ifdef _WIN32
+ if (0 == InterlockedExchange(&sc_init,1)) {
+ InitializeCriticalSection(&sc);
+ sc_done = 1;
+ }
+ while (0 == sc_done) Sleep(0);
+ EnterCriticalSection(&sc);
+ if (hWinsock == NULL) {
+#endif
+ WSAStartup(0x0101, &wsaData);
+#ifdef _WIN32
+ }
+ LeaveCriticalSection(&sc);
+#endif
+ }
+// Quick macro to tell if the winsock has actually loaded for a particular
+// function.
+// Debug version is a little more strict to make sure you get the names right.
+#ifdef DEBUG
+ return hWinsock != NULL && spArray[(int)(sp)] != NULL;
+#else // A little faster
+ return hWinsock != NULL;
+#endif
+}
+
+// Here are the functions that we have taken over by not directly linking
+// with the winsock import library or importing through the def file.
+
+/* In win16 we simulate blocking commands as follows. Prior to issuing the
+ * command we make the socket not-blocking (WSAAsyncSelect does that).
+ * We then issue the command and see if it would have blocked. If so, we
+ * yield the processor and go to sleep until an event occurs that unblocks
+ * us (WSAAsyncSelect allowed us to register what that condition is). We
+ * keep repeating until we do not get a would-block indication when issuing
+ * the command. At that time we unregister the notification condition and
+ * return the result of the command to the caller.
+ */
+
+//#ifndef _WIN32
+#if 0
+#define NON_BLOCKING(command,condition,index,type) \
+ type iret; \
+ HWND hWndFrame = AfxGetApp()->m_pMainWnd->m_hWnd; \
+ while (TRUE) { \
+ if (WSAAsyncSelect(s, hWndFrame, msg_NetActivity, condition) \
+ == SOCKET_ERROR) { \
+ break; \
+ } \
+ if(IsWinsockLoaded(index)) { \
+ iret=command; \
+ if (!(iret==SOCKET_ERROR && WSAGetLastError()==WSAEWOULDBLOCK)) { \
+ WSAAsyncSelect(s, hWndFrame, msg_NetActivity, 0); \
+ return iret; \
+ } \
+ PR_Yield(); \
+ } else { \
+ break; \
+ } \
+ }
+#else
+#define NON_BLOCKING(command,condition,index,type) \
+ if(IsWinsockLoaded(index)) { \
+ return command; \
+ }
+#endif
+
+int PASCAL FAR WSAStartup(WORD wVersionRequested, LPWSADATA lpWSAData) {
+ // Our default return value is failure, though we change this regardless.
+ int iRetval = WSAVERNOTSUPPORTED;
+ HINSTANCE MyHandle;
+
+ // Before doing anything, clear out our proc array.
+ memset(spArray, 0, sizeof(spArray));
+
+ // attempt to load the real winsock.
+ MyHandle = LoadLibrary(SZWINSOCK);
+#ifdef _WIN32
+ if(MyHandle != NULL) {
+#else
+ if(MyHandle > HINSTANCE_ERROR) {
+#endif
+ // Winsock was loaded.
+ // Get the proc addresses for each needed function next.
+ int spTraverse;
+ for(spTraverse = 0; spTraverse < (int)sp_MaxProcs; spTraverse++) {
+ spArray[spTraverse] = GetProcAddress(MyHandle, spName[spTraverse]);
+ if ( NULL == spArray[spTraverse] )
+ return iRetval;// Bad winsock? Bad function name?
+ }
+
+ hWinsock = MyHandle;
+ // AllRight, attempt to make our first proxied call.
+ if(IsWinsockLoaded(sp_WSAStartup)) {
+ iRetval = ((sp_int_WORD_LPWSADATA)spArray[sp_WSAStartup])(wVersionRequested, lpWSAData);
+ }
+
+ // If the return value is still an error at this point, we unload the DLL,
+ // so that we can act as though nothing happened and the user
+ // gets no network access.
+ if(iRetval != 0) {
+ // Clear out our proc array.
+ memset(spArray, 0, sizeof(spArray));
+
+ // Free up the winsock.
+ FreeLibrary(MyHandle);
+ MyHandle = NULL;
+ }
+ }
+#ifndef _WIN32
+ else {
+ // Failed to load.
+ // Set this to NULL so it is clear.
+ hWinsock = NULL;
+ }
+#endif
+
+
+ // Check our return value, if it isn't success, then we need to fake
+ // our own winsock implementation.
+ if(iRetval != 0) {
+ // We always return success.
+ iRetval = 0;
+
+ // Fill in the structure.
+ // Return the version requested as the version supported.
+ lpWSAData->wVersion = wVersionRequested;
+ lpWSAData->wHighVersion = wVersionRequested;
+
+ // Fill in a discription.
+ strcpy(lpWSAData->szDescription, "Mozock DLL internal implementation.");
+ strcpy(lpWSAData->szSystemStatus, "Winsock running, allowing no network access.");
+
+ // Report a nice round number for sockets and datagram sizes.
+ lpWSAData->iMaxSockets = 4096;
+ lpWSAData->iMaxUdpDg = 4096;
+
+ // No vendor information.
+ lpWSAData->lpVendorInfo = NULL;
+ }
+
+ return(iRetval);
+}
+
+int PASCAL FAR WSACleanup(void) {
+ int iRetval = 0;
+
+ // Handling normally or internally.
+ // When IsWinsockLoaded() is called and hWinsock is NULL, it winds up calling WSAStartup
+ // which wedges rpcrt4.dll on win95 with some winsock implementations. Bug: 81359.
+ if(hWinsock && IsWinsockLoaded(sp_WSACleanup)) {
+ // Call their cleanup routine.
+ // We could set the return value here, but it is meaning less.
+ // We always return success.
+ iRetval = ((sp_int_void)spArray[sp_WSACleanup])();
+ //ASSERT(iRetval == 0);
+ iRetval = 0;
+ }
+
+ // Wether or not it succeeded, we free off the library here.
+ // Clear out our proc table too.
+ memset(spArray, 0, sizeof(spArray));
+ if(hWinsock != NULL) {
+ FreeLibrary(hWinsock);
+ hWinsock = NULL;
+ }
+
+ return(iRetval);
+}
+
+HANDLE PASCAL FAR WSAAsyncGetHostByName(HWND hWnd, unsigned int wMsg, const char FAR *name, char FAR *buf, int buflen) {
+ // Normal or shim.
+ if(IsWinsockLoaded(sp_WSAAsyncGetHostByName)) {
+ return(((sp_HANDLE_HWND_uint_ccharFARp_charFARp_int)spArray[sp_WSAAsyncGetHostByName])(hWnd, wMsg, name, buf, buflen));
+ }
+
+ // Must return error here.
+ // Set our last error value to be that the net is down.
+ WSASetLastError(WSAENETDOWN);
+ return(NULL);
+}
+
+int PASCAL FAR WSAAsyncSelect(SOCKET s, HWND hWnd, unsigned int wMsg, long lEvent) {
+ // Normal or shim.
+ if(IsWinsockLoaded(sp_WSAAsyncSelect)) {
+ return(((sp_int_SOCKET_HWND_uint_long)spArray[sp_WSAAsyncSelect])(s, hWnd, wMsg, lEvent));
+ }
+
+ // Must return error here.
+ WSASetLastError(WSAENETDOWN);
+ return(SOCKET_ERROR);
+}
+
+int PASCAL FAR WSAGetLastError(void) {
+ // See if someone else can handle.
+ if(IsWinsockLoaded(sp_WSAGetLastError)) {
+ return(((sp_int_void)spArray[sp_WSAGetLastError])());
+ }
+
+#ifndef _WIN32
+ {
+ // Fake it.
+ int iRetval = ispError;
+ ispError = 0;
+ return(iRetval);
+ }
+#else
+ // Use default OS handler.
+ return(GetLastError());
+#endif
+}
+
+void PASCAL FAR WSASetLastError(int iError) {
+ // See if someone else can handle.
+ if(IsWinsockLoaded(sp_WSASetLastError)) {
+ ((sp_void_int)spArray[sp_WSASetLastError])(iError);
+ return;
+ }
+
+#ifndef _WIN32
+ // Fake it.
+ ispError = iError;
+ return;
+#else
+ // Use default OS handler.
+ SetLastError(iError);
+ return;
+#endif
+}
+
+int PASCAL FAR __WSAFDIsSet(SOCKET fd, fd_set FAR *set) {
+ int i;
+
+ // See if someone else will handle.
+ if(IsWinsockLoaded(sp___WSAFDIsSet)) {
+ return(((sp_int_SOCKET_fdsetFARp)spArray[sp___WSAFDIsSet])(fd, set));
+ }
+
+ // Default implementation.
+ i = set->fd_count;
+ while (i--) {
+ if (set->fd_array[i] == fd) {
+ return 1;
+ }
+ }
+ return 0;
+}
+
+SOCKET PASCAL FAR accept(SOCKET s, struct sockaddr FAR *addr, int FAR *addrlen) {
+ // Internally or shim
+ NON_BLOCKING(
+ (((sp_SOCKET_SOCKET_sockaddrFARp_intFARp)spArray[sp_accept])(s, addr, addrlen)),
+ FD_ACCEPT, sp_accept, SOCKET);
+
+ // Fail.
+ WSASetLastError(WSAENETDOWN);
+ return(INVALID_SOCKET);
+}
+
+int PASCAL FAR bind(SOCKET s, const struct sockaddr FAR *name, int namelen) {
+ // Internally or shim
+ if(IsWinsockLoaded(sp_bind)) {
+ return(((sp_int_SOCKET_csockaddrFARp_int)spArray[sp_bind])(s, name, namelen));
+ }
+
+ // Fail.
+ WSASetLastError(WSAENETDOWN);
+ return(SOCKET_ERROR);
+}
+
+int PASCAL FAR closesocket(SOCKET s) {
+ // Internally or shim.
+ NON_BLOCKING(
+ (((sp_int_SOCKET)spArray[sp_closesocket])(s)),
+ FD_CLOSE, sp_closesocket, int);
+
+ // Error.
+ WSASetLastError(WSAENETDOWN);
+ return(SOCKET_ERROR);
+}
+
+int PASCAL FAR connect(SOCKET s, const struct sockaddr FAR *name, int namelen) {
+ // Internally or shim.
+ if(IsWinsockLoaded(sp_connect)) {
+ /* This could block and so it would seem that the NON_BLOCK
+ * macro should be used here. However it was causing a crash
+ * and so it was decided to allow blocking here instead
+ */
+ return (((sp_int_SOCKET_csockaddrFARp_int)spArray[sp_connect])(s, name, namelen));
+ }
+
+ // Err.
+ WSASetLastError(WSAENETDOWN);
+ return(SOCKET_ERROR);
+}
+
+struct hostent FAR * PASCAL FAR gethostbyname(const char FAR *name) {
+ if(IsWinsockLoaded(sp_gethostbyname)) {
+ return(((sp_hostentFARp_ccharFARp)spArray[sp_gethostbyname])(name));
+ }
+
+ WSASetLastError(WSAENETDOWN);
+ return(NULL);
+}
+
+struct hostent FAR * PASCAL FAR gethostbyaddr(const char FAR *addr, int len, int type) {
+ if(IsWinsockLoaded(sp_gethostbyaddr)) {
+ return(((sp_hostentFARp_ccharFARp_int_int)spArray[sp_gethostbyaddr])(addr, len, type));
+ }
+
+ WSASetLastError(WSAENETDOWN);
+ return(NULL);
+}
+
+int PASCAL FAR gethostname(char FAR *name, int namelen) {
+ if(IsWinsockLoaded(sp_gethostname)) {
+ return(((sp_int_charFARp_int)spArray[sp_gethostname])(name, namelen));
+ }
+
+ WSASetLastError(WSAENETDOWN);
+ return(SOCKET_ERROR);
+}
+
+int PASCAL FAR getpeername(SOCKET s, struct sockaddr FAR *name, int FAR *namelen) {
+ if(IsWinsockLoaded(sp_getpeername)) {
+ return(((sp_int_SOCKET_sockaddrFARp_intFARp)spArray[sp_getpeername])(s, name, namelen));
+ }
+
+ WSASetLastError(WSAENETDOWN);
+ return(SOCKET_ERROR);
+}
+
+int PASCAL FAR getsockname(SOCKET s, struct sockaddr FAR *name, int FAR *namelen) {
+ if(IsWinsockLoaded(sp_getsockname)) {
+ return(((sp_int_SOCKET_sockaddrFARp_intFARp)spArray[sp_getsockname])(s, name, namelen));
+ }
+
+ WSASetLastError(WSAENETDOWN);
+ return(SOCKET_ERROR);
+}
+
+int PASCAL FAR getsockopt(SOCKET s, int level, int optname, char FAR *optval, int FAR *optlen) {
+ if(IsWinsockLoaded(sp_getsockopt)) {
+ return(((sp_int_SOCKET_int_int_charFARp_intFARp)spArray[sp_getsockopt])(s, level, optname, optval, optlen));
+ }
+
+ WSASetLastError(WSAENETDOWN);
+ return(SOCKET_ERROR);
+}
+
+struct protoent FAR * PASCAL getprotobyname(const char FAR * name) {
+ if(IsWinsockLoaded(sp_getprotobyname)) {
+ return(((sp_protoentFARcchar)spArray[sp_getprotobyname])(name));
+ }
+
+ WSASetLastError(WSAENETDOWN);
+ return NULL;
+}
+
+u_long PASCAL FAR htonl(u_long hostlong) {
+ if(IsWinsockLoaded(sp_htonl)) {
+ return(((sp_ulong_ulong)spArray[sp_htonl])(hostlong));
+ }
+
+#ifndef _WIN32
+ return
+ (((hostlong&0xff)<<24) + ((hostlong&0xff00)<<8) +
+ ((hostlong&0xff0000)>>8) + ((hostlong&0xff000000)>>24));
+
+#else
+ // Just return what was passed in.
+ return(hostlong);
+#endif
+}
+
+u_short PASCAL FAR htons(u_short hostshort) {
+ if(IsWinsockLoaded(sp_htons)) {
+ return(((sp_ushort_ushort)spArray[sp_htons])(hostshort));
+ }
+
+#ifndef _WIN32
+ return (((hostshort&0xff)<<8) + ((hostshort&0xff00)>>8));
+
+#else
+ // Just return what was passed in.
+ return(hostshort);
+#endif
+}
+
+u_long PASCAL FAR ntohl(u_long hostlong) {
+ if(IsWinsockLoaded(sp_ntohl)) {
+ return(((sp_ulong_ulong)spArray[sp_ntohl])(hostlong));
+ }
+
+#ifndef _WIN32
+ return
+ (((hostlong&0xff)<<24) + ((hostlong&0xff00)<<8) +
+ ((hostlong&0xff0000)>>8) + ((hostlong&0xff000000)>>24));
+
+#else
+ // Just return what was passed in.
+ return(hostlong);
+#endif
+}
+
+u_short PASCAL FAR ntohs(u_short hostshort) {
+ if(IsWinsockLoaded(sp_ntohs)) {
+ return(((sp_ushort_ushort)spArray[sp_ntohs])(hostshort));
+ }
+
+#ifndef _WIN32
+ return (((hostshort&0xff)<<8) + ((hostshort&0xff00)>>8));
+
+#else
+ // Just return what was passed in.
+ return(hostshort);
+#endif
+}
+
+unsigned long PASCAL FAR inet_addr(const char FAR *cp) {
+ if(IsWinsockLoaded(sp_inet_addr)) {
+ return(((sp_ulong_ccharFARp)spArray[sp_inet_addr])(cp));
+ }
+
+ return(INADDR_NONE);
+}
+
+int PASCAL FAR ioctlsocket(SOCKET s, long cmd, u_long FAR *argp) {
+ if(IsWinsockLoaded(sp_ioctlsocket)) {
+ return(((sp_int_SOCKET_long_ulongFARp)spArray[sp_ioctlsocket])(s, cmd, argp));
+ }
+
+ WSASetLastError(WSAENETDOWN);
+ return(SOCKET_ERROR);
+}
+
+int PASCAL FAR listen(SOCKET s, int backlog) {
+ if(IsWinsockLoaded(sp_listen)) {
+ return(((sp_int_SOCKET_int)spArray[sp_listen])(s, backlog));
+ }
+
+ WSASetLastError(WSAENETDOWN);
+ return(SOCKET_ERROR);
+}
+
+int PASCAL FAR recv(SOCKET s, char FAR *buf, int len, int flags) {
+ NON_BLOCKING(
+ (((sp_int_SOCKET_charFARp_int_int)spArray[sp_recv])(s, buf, len, flags)),
+ FD_READ, sp_recv, int);
+
+ WSASetLastError(WSAENETDOWN);
+ return(SOCKET_ERROR);
+}
+
+int PASCAL FAR select(int nfds, fd_set FAR *readfds, fd_set FAR *writefds, fd_set FAR *exceptfds, const struct timeval FAR *timeout) {
+ // If there's nothing to do, stop now before we go off into dll land.
+ // Optimization, boyz.
+ if((readfds && readfds->fd_count) || (writefds && writefds->fd_count) || (exceptfds && exceptfds->fd_count)) {
+ if(IsWinsockLoaded(sp_select)) {
+ return(((sp_int_int_fdsetFARp_fdsetFARp_fdsetFARp_ctimevalFARp)spArray[sp_select])(nfds,readfds,writefds,exceptfds,timeout));
+ }
+
+ WSASetLastError(WSAENETDOWN);
+ return(SOCKET_ERROR);
+ }
+
+ // No need to go to the DLL, there is nothing to do.
+ return(0);
+}
+
+int PASCAL FAR send(SOCKET s, const char FAR *buf, int len, int flags) {
+ NON_BLOCKING(
+
+ (((sp_int_SOCKET_ccharFARp_int_int)spArray[sp_send])(s, buf, len, flags)),
+ FD_WRITE, sp_send, int);
+
+ WSASetLastError(WSAENETDOWN);
+ return(SOCKET_ERROR);
+}
+
+int PASCAL FAR setsockopt(SOCKET s, int level, int optname, const char FAR *optval, int optlen) {
+ if(IsWinsockLoaded(sp_setsockopt)) {
+ return(((sp_int_SOCKET_int_int_ccharFARp_int)spArray[sp_setsockopt])(s, level, optname, optval, optlen));
+ }
+
+ WSASetLastError(WSAENETDOWN);
+ return(SOCKET_ERROR);
+}
+
+int PASCAL FAR shutdown(SOCKET s, int how) {
+ if(IsWinsockLoaded(sp_shutdown)) {
+ return(((sp_int_SOCKET_int)spArray[sp_shutdown])(s, how));
+ }
+
+ WSASetLastError(WSAENETDOWN);
+ return(SOCKET_ERROR);
+}
+
+SOCKET PASCAL FAR socket(int af, int type, int protocol) {
+ if(IsWinsockLoaded(sp_socket)) {
+ return(((sp_SOCKET_int_int_int)spArray[sp_socket])(af, type, protocol));
+ }
+
+ WSASetLastError(WSAENETDOWN);
+ return(INVALID_SOCKET);
+}
+
+char FAR * PASCAL FAR inet_ntoa(struct in_addr in) {
+ if(IsWinsockLoaded(sp_inet_ntoa)) {
+ return ((sp_charFARp_in_addr)spArray[sp_inet_ntoa])(in);
+ }
+
+ WSASetLastError(WSAENETDOWN);
+ return NULL;
+}