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