Back to index

lightning-sunbird  0.9+nobinonly
mozock.c
Go to the documentation of this file.
00001 /* ***** BEGIN LICENSE BLOCK *****
00002  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
00003  *
00004  * The contents of this file are subject to the Mozilla Public License Version
00005  * 1.1 (the "License"); you may not use this file except in compliance with
00006  * the License. You may obtain a copy of the License at
00007  * http://www.mozilla.org/MPL/
00008  *
00009  * Software distributed under the License is distributed on an "AS IS" basis,
00010  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
00011  * for the specific language governing rights and limitations under the
00012  * License.
00013  *
00014  * The Original Code is Mozilla Communicator client code, released
00015  * March 31, 1998.
00016  *
00017  * The Initial Developer of the Original Code is
00018  * Netscape Communications Corporation.
00019  * Portions created by the Initial Developer are Copyright (C) 1998-1999
00020  * the Initial Developer. All Rights Reserved.
00021  *
00022  * Contributor(s):
00023  *
00024  * Alternatively, the contents of this file may be used under the terms of
00025  * either the GNU General Public License Version 2 or later (the "GPL"), or
00026  * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
00027  * in which case the provisions of the GPL or the LGPL are applicable instead
00028  * of those above. If you wish to allow use of your version of this file only
00029  * under the terms of either the GPL or the LGPL, and not to allow others to
00030  * use your version of this file under the terms of the MPL, indicate your
00031  * decision by deleting the provisions above and replace them with the notice
00032  * and other provisions required by the GPL or the LGPL. If you do not delete
00033  * the provisions above, a recipient may use your version of this file under
00034  * the terms of any one of the MPL, the GPL or the LGPL.
00035  *
00036  * ***** END LICENSE BLOCK ***** */
00037 
00038 #include <windows.h>
00039 #include <winsock.h>
00040 #include <string.h>
00041 
00042 //     Purpose of this file is to implement an intermediate layer to our network
00043 //            services, the winsock.
00044 //     This intermediate layer will be able to function with and without a working
00045 //            winsock being present.
00046 //     The attempt to activate the winsock happens as would normally be expected,
00047 //              through the calling application's entry point to us, WSAStartup.
00048 //     Name of the winsock we would like to load.
00049 //     Diffs between OSs, Win32s is out in the cold if running 32 bits unless
00050 //            they also have a winsock name wsock32.dll.
00051 #ifndef _WIN32
00052 #define SZWINSOCK "winsock.dll"
00053 #else
00054 #define SZWINSOCK "wsock32.dll"
00055 #endif
00056 
00057 //     Here is the enumeration for the winsock functions we have currently
00058 //            overridden (needed to run).  Add more when needed.
00059 //     We use these to access proc addresses, and to hold a table of strings
00060 //            to obtain the proc addresses.
00061 enum SockProc {
00062        sp_WSAAsyncGetHostByName = 0,
00063        sp_WSAAsyncSelect,
00064        sp_WSACleanup,
00065        sp_WSAGetLastError,
00066        sp_WSASetLastError,
00067        sp_WSAStartup,
00068        sp___WSAFDIsSet,
00069        sp_accept,
00070        sp_bind,
00071        sp_closesocket,
00072        sp_connect,
00073        sp_gethostbyname,
00074        sp_gethostbyaddr,
00075        sp_gethostname,
00076        sp_getpeername,
00077        sp_getsockname,
00078        sp_getsockopt,
00079        sp_getprotobyname,
00080        sp_htonl,
00081        sp_htons,
00082        sp_inet_addr,
00083        sp_ioctlsocket,
00084        sp_listen,
00085        sp_ntohl,
00086        sp_ntohs,
00087        sp_recv,
00088        sp_select,
00089        sp_send,
00090        sp_setsockopt,
00091        sp_shutdown,
00092        sp_socket,
00093        sp_inet_ntoa,
00094 
00095        sp_MaxProcs   //     Total count.
00096 };
00097 
00098 //     Array of function names used in GetProcAddress to fill in our
00099 //            proc array when needed.
00100 //     This array must match the enumerations exactly.
00101 char *spName[(int)sp_MaxProcs] =   {
00102         "WSAAsyncGetHostByName",
00103         "WSAAsyncSelect",
00104         "WSACleanup",
00105         "WSAGetLastError",
00106         "WSASetLastError",
00107         "WSAStartup",
00108         "__WSAFDIsSet",
00109         "accept",
00110         "bind",
00111         "closesocket",
00112         "connect",
00113         "gethostbyname",
00114         "gethostbyaddr",
00115         "gethostname",
00116         "getpeername",
00117         "getsockname",
00118         "getsockopt",
00119         "getprotobyname",
00120         "htonl",
00121         "htons",
00122         "inet_addr",
00123         "ioctlsocket",
00124         "listen",
00125         "ntohl",
00126         "ntohs",
00127         "recv",
00128         "select",
00129         "send",
00130         "setsockopt",
00131         "shutdown",
00132         "socket",
00133         "inet_ntoa"
00134 };
00135 
00136 //     Array of proc addresses to the winsock functions.
00137 //      These can be NULL, indicating their absence (as in the case we couldn't
00138 //              load the winsock.dll or one of the functions wasn't loaded).
00139 //     The procs assigned in must corellate with the enumerations exactly.
00140 FARPROC spArray[(int)sp_MaxProcs];
00141 
00142 //     Typedef all the different types of functions that we must cast the
00143 //            procs to in order to call without the compiler barfing.
00144 //     Prefix is always sp.
00145 //     Retval is next, spelled out.
00146 //     Parameters in their order are next, spelled out.
00147 typedef int (PASCAL FAR *sp_int_WORD_LPWSADATA)(WORD, LPWSADATA);
00148 typedef int (PASCAL FAR *sp_int_void)(void);
00149 typedef HANDLE (PASCAL FAR *sp_HANDLE_HWND_uint_ccharFARp_charFARp_int)(HWND, unsigned int, const char FAR *, char FAR *, int);
00150 typedef int (PASCAL FAR *sp_int_SOCKET_HWND_uint_long)(SOCKET, HWND, unsigned int, long);
00151 typedef void (PASCAL FAR *sp_void_int)(int);
00152 typedef int (PASCAL FAR *sp_int_SOCKET_fdsetFARp)(SOCKET, fd_set FAR *);
00153 typedef SOCKET(PASCAL FAR *sp_SOCKET_SOCKET_sockaddrFARp_intFARp)(SOCKET, struct sockaddr FAR *, int FAR *);
00154 typedef int (PASCAL FAR *sp_int_SOCKET_csockaddrFARp_int)(SOCKET, const struct sockaddr FAR *, int);
00155 typedef int (PASCAL FAR *sp_int_SOCKET)(SOCKET);
00156 typedef struct hostent FAR *(PASCAL FAR *sp_hostentFARp_ccharFARp)(const char FAR *);
00157 typedef struct hostent FAR *(PASCAL FAR *sp_hostentFARp_ccharFARp_int_int)(const char FAR *, int, int);
00158 typedef int (PASCAL FAR *sp_int_charFARp_int)(char FAR *, int);
00159 typedef int (PASCAL FAR *sp_int_SOCKET_sockaddrFARp_intFARp)(SOCKET, struct sockaddr FAR *, int FAR *);
00160 typedef int (PASCAL FAR *sp_int_SOCKET_int_int_charFARp_intFARp)(SOCKET, int, int, char FAR *, int FAR *);
00161 typedef u_long (PASCAL FAR *sp_ulong_ulong)(u_long);
00162 typedef u_short (PASCAL FAR *sp_ushort_ushort)(u_short);
00163 typedef unsigned long (PASCAL FAR *sp_ulong_ccharFARp)(const char FAR *);
00164 typedef int (PASCAL FAR *sp_int_SOCKET_long_ulongFARp)(SOCKET, long, u_long FAR *);
00165 typedef int (PASCAL FAR *sp_int_SOCKET_int)(SOCKET, int);
00166 typedef int (PASCAL FAR *sp_int_SOCKET_charFARp_int_int)(SOCKET, char FAR *, int, int);
00167 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*);
00168 typedef int (PASCAL FAR *sp_int_SOCKET_ccharFARp_int_int)(SOCKET, const char FAR *, int, int);
00169 typedef int (PASCAL FAR *sp_int_SOCKET_int_int_ccharFARp_int)(SOCKET, int, int, const char FAR *, int);
00170 typedef SOCKET (PASCAL FAR *sp_SOCKET_int_int_int)(int, int, int);
00171 typedef char FAR * (PASCAL FAR *sp_charFARp_in_addr)(struct in_addr in);
00172 typedef struct protoent FAR * (PASCAL FAR *sp_protoentFARcchar)(const char FAR *);
00173 
00174 //     Handle to the winsock, if loaded.
00175 HINSTANCE hWinsock = NULL;
00176 
00177 #ifndef _WIN32
00178 //     Last error code for the winsock.
00179 int ispError = 0;
00180 #endif
00181 
00182 
00183 BOOL IsWinsockLoaded (int sp)
00184 {
00185        if (hWinsock == NULL)
00186        {
00187               WSADATA wsaData;
00188               WSAStartup(0x0101, &wsaData);
00189        }
00190 //     Quick macro to tell if the winsock has actually loaded for a particular
00191 //            function.
00192 //  Debug version is a little more strict to make sure you get the names right.
00193 #ifdef DEBUG
00194        return hWinsock != NULL && spArray[(int)(sp)] != NULL;
00195 #else //  A little faster
00196        return hWinsock != NULL;
00197 #endif
00198 }
00199 
00200 //     Here are the functions that we have taken over by not directly linking
00201 //            with the winsock import library or importing through the def file.
00202 
00203 /* In win16 we simulate blocking commands as follows.  Prior to issuing the
00204  * command we make the socket not-blocking (WSAAsyncSelect does that).
00205  * We then issue the command and see if it would have blocked. If so, we
00206  * yield the processor and go to sleep until an event occurs that unblocks
00207  * us (WSAAsyncSelect allowed us to register what that condition is).  We
00208  * keep repeating until we do not get a would-block indication when issuing
00209  * the command.  At that time we unregister the notification condition and
00210  * return the result of the command to the caller.
00211  */
00212 
00213 //#ifndef _WIN32
00214 #if 0
00215 #define NON_BLOCKING(command,condition,index,type)                          \
00216     type iret;                                                              \
00217     HWND hWndFrame = AfxGetApp()->m_pMainWnd->m_hWnd;                       \
00218     while (TRUE) {                                                   \
00219        if (WSAAsyncSelect(s, hWndFrame, msg_NetActivity, condition)         \
00220               == SOCKET_ERROR) {                                     \
00221            break;                                                    \
00222        }                                                             \
00223        if(IsWinsockLoaded(index)) {                                         \
00224            iret=command;                                             \
00225            if (!(iret==SOCKET_ERROR && WSAGetLastError()==WSAEWOULDBLOCK)) { \
00226               WSAAsyncSelect(s, hWndFrame, msg_NetActivity, 0);             \
00227               return iret;                                           \
00228            }                                                         \
00229            PR_Yield();                                               \
00230        } else {                                                      \
00231            break;                                                    \
00232        }                                                             \
00233     }
00234 #else
00235 #define NON_BLOCKING(command,condition,index,type)                          \
00236     if(IsWinsockLoaded(index)) {                                     \
00237        return command;                                               \
00238     }
00239 #endif
00240 
00241 int PASCAL FAR WSAStartup(WORD wVersionRequested, LPWSADATA lpWSAData)       {
00242        //     Our default return value is failure, though we change this regardless.
00243        int iRetval = WSAVERNOTSUPPORTED;
00244 
00245        //     Before doing anything, clear out our proc array.
00246        memset(spArray, 0, sizeof(spArray));
00247 
00248        //     attempt to load the real winsock.
00249        hWinsock = LoadLibrary(SZWINSOCK);
00250 #ifdef _WIN32
00251        if(hWinsock != NULL) {
00252 #else
00253        if(hWinsock > HINSTANCE_ERROR)     {
00254 #endif
00255               //     Winsock was loaded.
00256               //     Get the proc addresses for each needed function next.
00257               int spTraverse;
00258               for(spTraverse = 0; spTraverse < (int)sp_MaxProcs; spTraverse++)      {
00259                      spArray[spTraverse] = GetProcAddress(hWinsock, spName[spTraverse]);
00260                      if ( NULL == spArray[spTraverse] )
00261                             return iRetval;//    Bad winsock?  Bad function name?
00262               }
00263 
00264               //     AllRight, attempt to make our first proxied call.
00265               if(IsWinsockLoaded(sp_WSAStartup)) {
00266                      iRetval = ((sp_int_WORD_LPWSADATA)spArray[sp_WSAStartup])(wVersionRequested, lpWSAData);
00267               }
00268 
00269               //     If the return value is still an error at this point, we unload the DLL,
00270               //            so that we can act as though nothing happened and the user
00271               //            gets no network access.
00272               if(iRetval != 0)     {
00273                      //     Clear out our proc array.
00274                      memset(spArray, 0, sizeof(spArray));
00275 
00276                      //     Free up the winsock.
00277                      FreeLibrary(hWinsock);
00278                      hWinsock = NULL;
00279               }
00280        }
00281 #ifndef _WIN32
00282        else   {
00283               //     Failed to load.
00284               //     Set this to NULL so it is clear.
00285               hWinsock = NULL;
00286        }
00287 #endif
00288 
00289         //      Check our return value, if it isn't success, then we need to fake
00290        //            our own winsock implementation.
00291        if(iRetval != 0)     {
00292               //     We always return success.
00293               iRetval = 0;
00294 
00295               //     Fill in the structure.
00296               //     Return the version requested as the version supported.
00297               lpWSAData->wVersion = wVersionRequested;
00298               lpWSAData->wHighVersion = wVersionRequested;
00299 
00300               //     Fill in a discription.
00301                 strcpy(lpWSAData->szDescription, "Mozock DLL internal implementation.");
00302                 strcpy(lpWSAData->szSystemStatus, "Winsock running, allowing no network access.");
00303 
00304               //     Report a nice round number for sockets and datagram sizes.
00305               lpWSAData->iMaxSockets = 4096;
00306               lpWSAData->iMaxUdpDg = 4096;
00307 
00308               //     No vendor information.
00309               lpWSAData->lpVendorInfo = NULL;
00310        }
00311 
00312        return(iRetval);
00313 }
00314 
00315 int PASCAL FAR WSACleanup(void) {
00316        int iRetval = 0;
00317 
00318        //     Handling normally or internally.
00319        // When IsWinsockLoaded() is called and hWinsock is NULL, it winds up calling WSAStartup
00320        // which wedges rpcrt4.dll on win95 with some winsock implementations. Bug: 81359.
00321        if(hWinsock && IsWinsockLoaded(sp_WSACleanup))   {
00322               //     Call their cleanup routine.
00323               //     We could set the return value here, but it is meaning less.
00324               //     We always return success.
00325               iRetval = ((sp_int_void)spArray[sp_WSACleanup])();
00326               //ASSERT(iRetval == 0);
00327               iRetval = 0;
00328        }
00329 
00330        //     Wether or not it succeeded, we free off the library here.
00331        //     Clear out our proc table too.
00332        memset(spArray, 0, sizeof(spArray));
00333        if(hWinsock != NULL) {
00334               FreeLibrary(hWinsock);
00335               hWinsock = NULL;
00336        }
00337 
00338        return(iRetval);
00339 }
00340 
00341 HANDLE PASCAL FAR WSAAsyncGetHostByName(HWND hWnd, unsigned int wMsg, const char FAR *name, char FAR *buf, int buflen) {
00342        // Normal or shim.
00343        if(IsWinsockLoaded(sp_WSAAsyncGetHostByName))    {
00344               return(((sp_HANDLE_HWND_uint_ccharFARp_charFARp_int)spArray[sp_WSAAsyncGetHostByName])(hWnd, wMsg, name, buf, buflen));
00345        }
00346 
00347        //     Must return error here.
00348        //     Set our last error value to be that the net is down.
00349        WSASetLastError(WSAENETDOWN);
00350        return(NULL);
00351 }
00352 
00353 int PASCAL FAR WSAAsyncSelect(SOCKET s, HWND hWnd, unsigned int wMsg, long lEvent)  {
00354        //     Normal or shim.
00355        if(IsWinsockLoaded(sp_WSAAsyncSelect))    {
00356               return(((sp_int_SOCKET_HWND_uint_long)spArray[sp_WSAAsyncSelect])(s, hWnd, wMsg, lEvent));
00357        }
00358 
00359        //     Must return error here.
00360        WSASetLastError(WSAENETDOWN);
00361        return(SOCKET_ERROR);
00362 }
00363 
00364 int PASCAL FAR WSAGetLastError(void)      {
00365        //     See if someone else can handle.
00366        if(IsWinsockLoaded(sp_WSAGetLastError)) {
00367               return(((sp_int_void)spArray[sp_WSAGetLastError])());
00368        }
00369 
00370 #ifndef _WIN32
00371        {
00372               //     Fake it.
00373               int iRetval = ispError;
00374               ispError = 0;
00375               return(iRetval);
00376        }
00377 #else
00378        //     Use default OS handler.
00379        return(GetLastError());
00380 #endif
00381 }
00382 
00383 void PASCAL FAR WSASetLastError(int iError)      {
00384        //     See if someone else can handle.
00385        if(IsWinsockLoaded(sp_WSASetLastError)) {
00386               ((sp_void_int)spArray[sp_WSASetLastError])(iError);
00387               return;
00388        }
00389 
00390 #ifndef _WIN32
00391        //     Fake it.
00392        ispError = iError;
00393        return;
00394 #else
00395        //     Use default OS handler.
00396        SetLastError(iError);
00397        return;
00398 #endif
00399 }
00400 
00401 int PASCAL FAR __WSAFDIsSet(SOCKET fd, fd_set FAR *set) {
00402        int i;
00403 
00404        //     See if someone else will handle.
00405        if(IsWinsockLoaded(sp___WSAFDIsSet))      {
00406               return(((sp_int_SOCKET_fdsetFARp)spArray[sp___WSAFDIsSet])(fd, set));
00407        }
00408 
00409        //     Default implementation.
00410        i = set->fd_count;
00411        while (i--)   {
00412               if (set->fd_array[i] == fd) {
00413                      return 1;
00414               }
00415        }
00416        return 0;
00417 }
00418 
00419 SOCKET PASCAL FAR accept(SOCKET s, struct sockaddr FAR *addr, int FAR *addrlen) {
00420        //     Internally or shim
00421        NON_BLOCKING(
00422            (((sp_SOCKET_SOCKET_sockaddrFARp_intFARp)spArray[sp_accept])(s, addr, addrlen)),
00423            FD_ACCEPT, sp_accept, SOCKET);
00424 
00425        //     Fail.
00426        WSASetLastError(WSAENETDOWN);
00427        return(INVALID_SOCKET);
00428 }
00429 
00430 int PASCAL FAR bind(SOCKET s, const struct sockaddr FAR *name, int namelen)  {
00431        //     Internally or shim
00432        if(IsWinsockLoaded(sp_bind))       {
00433               return(((sp_int_SOCKET_csockaddrFARp_int)spArray[sp_bind])(s, name, namelen));
00434        }
00435 
00436        //     Fail.
00437        WSASetLastError(WSAENETDOWN);
00438        return(SOCKET_ERROR);
00439 }
00440 
00441 int PASCAL FAR closesocket(SOCKET s)      {
00442        //     Internally or shim.
00443        NON_BLOCKING(
00444            (((sp_int_SOCKET)spArray[sp_closesocket])(s)),
00445            FD_CLOSE, sp_closesocket, int);
00446 
00447        //     Error.
00448        WSASetLastError(WSAENETDOWN);
00449        return(SOCKET_ERROR);
00450 }
00451 
00452 int PASCAL FAR connect(SOCKET s, const struct sockaddr FAR *name, int namelen)      {
00453        //     Internally or shim.
00454        if(IsWinsockLoaded(sp_connect)) {
00455               /* This could block and so it would seem that the NON_BLOCK
00456                * macro should be used here.  However it was causing a crash
00457                * and so it was decided to allow blocking here instead
00458                */
00459               return (((sp_int_SOCKET_csockaddrFARp_int)spArray[sp_connect])(s, name, namelen));
00460        }
00461 
00462        //     Err.
00463        WSASetLastError(WSAENETDOWN);
00464        return(SOCKET_ERROR);
00465 }
00466 
00467 struct hostent FAR * PASCAL FAR gethostbyname(const char FAR *name)   {
00468        if(IsWinsockLoaded(sp_gethostbyname))     {
00469               return(((sp_hostentFARp_ccharFARp)spArray[sp_gethostbyname])(name));
00470        }
00471 
00472        WSASetLastError(WSAENETDOWN);
00473        return(NULL);
00474 }
00475 
00476 struct hostent FAR * PASCAL FAR gethostbyaddr(const char FAR *addr, int len, int type)     {
00477        if(IsWinsockLoaded(sp_gethostbyaddr))     {
00478               return(((sp_hostentFARp_ccharFARp_int_int)spArray[sp_gethostbyaddr])(addr, len, type));
00479        }
00480 
00481        WSASetLastError(WSAENETDOWN);
00482        return(NULL);
00483 }
00484 
00485 int PASCAL FAR gethostname(char FAR *name, int namelen) {
00486        if(IsWinsockLoaded(sp_gethostname))       {
00487               return(((sp_int_charFARp_int)spArray[sp_gethostname])(name, namelen));
00488        }
00489 
00490        WSASetLastError(WSAENETDOWN);
00491        return(SOCKET_ERROR);
00492 }
00493 
00494 int PASCAL FAR getpeername(SOCKET s, struct sockaddr FAR *name, int FAR *namelen)   {
00495        if(IsWinsockLoaded(sp_getpeername))       {
00496               return(((sp_int_SOCKET_sockaddrFARp_intFARp)spArray[sp_getpeername])(s, name, namelen));
00497        }
00498 
00499        WSASetLastError(WSAENETDOWN);
00500        return(SOCKET_ERROR);
00501 }
00502 
00503 int PASCAL FAR getsockname(SOCKET s, struct sockaddr FAR *name, int FAR *namelen)   {
00504        if(IsWinsockLoaded(sp_getsockname))       {
00505               return(((sp_int_SOCKET_sockaddrFARp_intFARp)spArray[sp_getsockname])(s, name, namelen));
00506        }
00507 
00508        WSASetLastError(WSAENETDOWN);
00509        return(SOCKET_ERROR);
00510 }
00511 
00512 int PASCAL FAR getsockopt(SOCKET s, int level, int optname, char FAR *optval, int FAR *optlen)    {
00513        if(IsWinsockLoaded(sp_getsockopt)) {
00514               return(((sp_int_SOCKET_int_int_charFARp_intFARp)spArray[sp_getsockopt])(s, level, optname, optval, optlen));
00515        }
00516 
00517        WSASetLastError(WSAENETDOWN);
00518        return(SOCKET_ERROR);
00519 }
00520 
00521 struct protoent FAR * PASCAL getprotobyname(const char FAR * name) {
00522        if(IsWinsockLoaded(sp_getprotobyname))    {
00523               return(((sp_protoentFARcchar)spArray[sp_getprotobyname])(name));
00524        }
00525 
00526        WSASetLastError(WSAENETDOWN);
00527        return NULL;
00528 }
00529 
00530 u_long PASCAL FAR htonl(u_long hostlong)  {
00531        if(IsWinsockLoaded(sp_htonl))      {
00532               return(((sp_ulong_ulong)spArray[sp_htonl])(hostlong));
00533        }
00534 
00535 #ifndef _WIN32
00536        return
00537            (((hostlong&0xff)<<24) + ((hostlong&0xff00)<<8) +
00538             ((hostlong&0xff0000)>>8) + ((hostlong&0xff000000)>>24));
00539 
00540 #else
00541        //     Just return what was passed in.
00542        return(hostlong);
00543 #endif
00544 }
00545 
00546 u_short PASCAL FAR htons(u_short hostshort)      {
00547        if(IsWinsockLoaded(sp_htons))      {
00548               return(((sp_ushort_ushort)spArray[sp_htons])(hostshort));
00549        }
00550 
00551 #ifndef _WIN32
00552        return (((hostshort&0xff)<<8) + ((hostshort&0xff00)>>8));
00553 
00554 #else
00555        //     Just return what was passed in.
00556        return(hostshort);
00557 #endif
00558 }
00559 
00560 u_long PASCAL FAR ntohl(u_long hostlong)  {
00561        if(IsWinsockLoaded(sp_ntohl))      {
00562               return(((sp_ulong_ulong)spArray[sp_ntohl])(hostlong));
00563        }
00564 
00565 #ifndef _WIN32
00566        return
00567            (((hostlong&0xff)<<24) + ((hostlong&0xff00)<<8) +
00568             ((hostlong&0xff0000)>>8) + ((hostlong&0xff000000)>>24));
00569 
00570 #else
00571        //     Just return what was passed in.
00572        return(hostlong);
00573 #endif
00574 }
00575 
00576 u_short PASCAL FAR ntohs(u_short hostshort)      {
00577        if(IsWinsockLoaded(sp_ntohs))      {
00578               return(((sp_ushort_ushort)spArray[sp_ntohs])(hostshort));
00579        }
00580 
00581 #ifndef _WIN32
00582        return (((hostshort&0xff)<<8) + ((hostshort&0xff00)>>8));
00583 
00584 #else
00585        //     Just return what was passed in.
00586        return(hostshort);
00587 #endif
00588 }
00589 
00590 unsigned long PASCAL FAR inet_addr(const char FAR *cp)  {
00591        if(IsWinsockLoaded(sp_inet_addr))  {
00592               return(((sp_ulong_ccharFARp)spArray[sp_inet_addr])(cp));
00593        }
00594 
00595        return(INADDR_NONE);
00596 }
00597 
00598 int PASCAL FAR ioctlsocket(SOCKET s, long cmd, u_long FAR *argp)      {
00599        if(IsWinsockLoaded(sp_ioctlsocket))       {
00600               return(((sp_int_SOCKET_long_ulongFARp)spArray[sp_ioctlsocket])(s, cmd, argp));
00601        }
00602 
00603        WSASetLastError(WSAENETDOWN);
00604        return(SOCKET_ERROR);
00605 }
00606 
00607 int PASCAL FAR listen(SOCKET s, int backlog)     {
00608        if(IsWinsockLoaded(sp_listen))     {
00609               return(((sp_int_SOCKET_int)spArray[sp_listen])(s, backlog));
00610        }
00611 
00612        WSASetLastError(WSAENETDOWN);
00613        return(SOCKET_ERROR);
00614 }
00615 
00616 int PASCAL FAR recv(SOCKET s, char FAR *buf, int len, int flags)      {
00617        NON_BLOCKING(
00618            (((sp_int_SOCKET_charFARp_int_int)spArray[sp_recv])(s, buf, len, flags)),
00619            FD_READ, sp_recv, int);
00620 
00621        WSASetLastError(WSAENETDOWN);
00622        return(SOCKET_ERROR);
00623 }
00624 
00625 int PASCAL FAR select(int nfds, fd_set FAR *readfds, fd_set FAR *writefds, fd_set FAR *exceptfds, const struct timeval FAR *timeout) {
00626     //  If there's nothing to do, stop now before we go off into dll land.
00627     // Optimization, boyz.
00628     if((readfds && readfds->fd_count) || (writefds && writefds->fd_count) || (exceptfds && exceptfds->fd_count))    {
00629            if(IsWinsockLoaded(sp_select)) {
00630                      return(((sp_int_int_fdsetFARp_fdsetFARp_fdsetFARp_ctimevalFARp)spArray[sp_select])(nfds,readfds,writefds,exceptfds,timeout));
00631            }
00632 
00633            WSASetLastError(WSAENETDOWN);
00634            return(SOCKET_ERROR);
00635     }
00636 
00637     // No need to go to the DLL, there is nothing to do.
00638     return(0);
00639 }
00640 
00641 int PASCAL FAR send(SOCKET s, const char FAR *buf, int len, int flags)       {
00642        NON_BLOCKING(
00643 
00644            (((sp_int_SOCKET_ccharFARp_int_int)spArray[sp_send])(s, buf, len, flags)),
00645            FD_WRITE, sp_send, int);
00646 
00647        WSASetLastError(WSAENETDOWN);
00648        return(SOCKET_ERROR);
00649 }
00650 
00651 int PASCAL FAR setsockopt(SOCKET s, int level, int optname, const char FAR *optval, int optlen) {
00652        if(IsWinsockLoaded(sp_setsockopt)) {
00653               return(((sp_int_SOCKET_int_int_ccharFARp_int)spArray[sp_setsockopt])(s, level, optname, optval, optlen));
00654        }
00655 
00656        WSASetLastError(WSAENETDOWN);
00657        return(SOCKET_ERROR);
00658 }
00659 
00660 int PASCAL FAR shutdown(SOCKET s, int how)       {
00661        if(IsWinsockLoaded(sp_shutdown))   {
00662               return(((sp_int_SOCKET_int)spArray[sp_shutdown])(s, how));
00663        }
00664 
00665        WSASetLastError(WSAENETDOWN);
00666        return(SOCKET_ERROR);
00667 }
00668 
00669 SOCKET PASCAL FAR socket(int af, int type, int protocol)       {
00670        if(IsWinsockLoaded(sp_socket))     {
00671               return(((sp_SOCKET_int_int_int)spArray[sp_socket])(af, type, protocol));
00672        }
00673 
00674        WSASetLastError(WSAENETDOWN);
00675        return(INVALID_SOCKET);
00676 }
00677 
00678 char FAR * PASCAL FAR inet_ntoa(struct in_addr in) {
00679        if(IsWinsockLoaded(sp_inet_ntoa))  {
00680               return ((sp_charFARp_in_addr)spArray[sp_inet_ntoa])(in);
00681        }
00682 
00683        WSASetLastError(WSAENETDOWN);
00684        return NULL;
00685 }