summaryrefslogtreecommitdiff
path: root/win32/win32sck.c
diff options
context:
space:
mode:
Diffstat (limited to 'win32/win32sck.c')
-rw-r--r--win32/win32sck.c761
1 files changed, 761 insertions, 0 deletions
diff --git a/win32/win32sck.c b/win32/win32sck.c
new file mode 100644
index 0000000000..126ff1a246
--- /dev/null
+++ b/win32/win32sck.c
@@ -0,0 +1,761 @@
+// NTSock.C
+
+// (c) 1995 Microsoft Corporation. All rights reserved.
+// Developed by hip communications inc., http://info.hip.com/info/
+// Portions (c) 1993 Intergraph Corporation. All rights reserved.
+
+// You may distribute under the terms of either the GNU General Public
+// License or the Artistic License, as specified in the README file.
+
+#include <windows.h>
+#define WIN32_LEAN_AND_MEAN
+#include "EXTERN.h"
+#include "perl.h"
+#include <sys/socket.h>
+#include <fcntl.h>
+#include <sys/stat.h>
+#include <assert.h>
+
+#define CROAK croak
+
+#ifdef USE_SOCKETS_AS_HANDLES
+// thanks to Beverly Brown (beverly@datacube.com)
+
+# if defined(_WIN32) && !defined(WIN95_OSFHANDLE_FIXED) && defined(_M_IX86)
+//# define OPEN_SOCKET(x) _patch_open_osfhandle(x, _O_RDWR | _O_BINARY)
+# define OPEN_SOCKET(x) _open_osfhandle(x,_O_RDWR|_O_BINARY)
+# else
+# define OPEN_SOCKET(x) _open_osfhandle(x,_O_RDWR|_O_BINARY)
+# endif
+# define TO_SOCKET(x) _get_osfhandle(x)
+
+#else
+
+# define OPEN_SOCKET(x) (x)
+# define TO_SOCKET(x) (x)
+
+#endif // USE_SOCKETS_AS_HANDLES
+
+//
+// This is a clone of fdopen so that we can handle the version of sockets that NT gets to use.
+//
+// The problem is that sockets are not real file handles and
+// cannot be fdopen'ed. This causes problems in the do_socket
+// routine in doio.c, since it tries to create two file pointers
+// for the socket just created. We'll fake out an fdopen and see
+// if we can prevent perl from trying to do stdio on sockets.
+//
+
+#if defined(_WIN32) && !defined(WIN95_OSFHANDLE_FIXED) && defined(_M_IX86)
+
+# ifdef __cplusplus
+#define EXT_C_FUNC extern "C"
+# else
+#define EXT_C_FUNC extern
+# endif
+
+EXT_C_FUNC int __cdecl _alloc_osfhnd(void);
+EXT_C_FUNC int __cdecl _set_osfhnd(int fh, long value);
+EXT_C_FUNC void __cdecl _lock_fhandle(int);
+EXT_C_FUNC void __cdecl _unlock_fhandle(int);
+EXT_C_FUNC void __cdecl _unlock(int);
+EXT_C_FUNC struct servent* win32_savecopyservent(struct servent*d, struct servent*s, const char *proto);
+
+#if (_MSC_VER >= 1000)
+ typedef struct
+ {
+ long osfhnd; /* underlying OS file HANDLE */
+ char osfile; /* attributes of file (e.g., open in text mode?) */
+ char pipech; /* one char buffer for handles opened on pipes */
+#if defined (_MT) && !defined (DLL_FOR_WIN32S)
+ int lockinitflag;
+ CRITICAL_SECTION lock;
+#endif /* defined (_MT) && !defined (DLL_FOR_WIN32S) */
+ } ioinfo;
+
+ EXT_C_FUNC ioinfo * __pioinfo[];
+
+ #define IOINFO_L2E 5
+ #define IOINFO_ARRAY_ELTS (1 << IOINFO_L2E)
+ #define _pioinfo(i) (__pioinfo[i >> IOINFO_L2E] + (i & (IOINFO_ARRAY_ELTS - 1)))
+ #define _osfile(i) (_pioinfo(i)->osfile)
+#else
+ extern "C" extern char _osfile[];
+#endif // (_MSC_VER >= 1000)
+
+#define FOPEN 0x01 // file handle open
+#define FAPPEND 0x20 // file handle opened O_APPEND
+#define FDEV 0x40 // file handle refers to device
+#define FTEXT 0x80 // file handle is in text mode
+
+#define _STREAM_LOCKS 26 // Table of stream locks
+#define _LAST_STREAM_LOCK (_STREAM_LOCKS+_NSTREAM_-1) // Last stream lock
+#define _FH_LOCKS (_LAST_STREAM_LOCK+1) // Table of fh locks
+
+/***
+*int _patch_open_osfhandle(long osfhandle, int flags) - open C Runtime file handle
+*
+*Purpose:
+* This function allocates a free C Runtime file handle and associates
+* it with the Win32 HANDLE specified by the first parameter. This is a
+* temperary fix for WIN95's brain damage GetFileType() error on socket
+* we just bypass that call for socket
+*
+*Entry:
+* long osfhandle - Win32 HANDLE to associate with C Runtime file handle.
+* int flags - flags to associate with C Runtime file handle.
+*
+*Exit:
+* returns index of entry in fh, if successful
+* return -1, if no free entry is found
+*
+*Exceptions:
+*
+*******************************************************************************/
+
+int __cdecl _patch_open_osfhandle(long osfhandle, int flags)
+{
+ int fh;
+ char fileflags; // _osfile flags
+
+ // copy relevant flags from second parameter
+ fileflags = FDEV;
+
+ if(flags & _O_APPEND)
+ fileflags |= FAPPEND;
+
+ if(flags & _O_TEXT)
+ fileflags |= FTEXT;
+
+ // attempt to allocate a C Runtime file handle
+ if((fh = _alloc_osfhnd()) == -1)
+ {
+ errno = EMFILE; // too many open files
+ _doserrno = 0L; // not an OS error
+ return -1; // return error to caller
+ }
+
+ // the file is open. now, set the info in _osfhnd array
+ _set_osfhnd(fh, osfhandle);
+
+ fileflags |= FOPEN; // mark as open
+
+#if (_MSC_VER >= 1000)
+ _osfile(fh) = fileflags; // set osfile entry
+ _unlock_fhandle(fh);
+#else
+ _osfile[fh] = fileflags; // set osfile entry
+ _unlock(fh+_FH_LOCKS); // unlock handle
+#endif
+
+
+ return fh; // return handle
+}
+#endif // _M_IX86
+
+#define SOCKETAPI PASCAL
+
+typedef SOCKET (SOCKETAPI *LPSOCKACCEPT)(SOCKET, struct sockaddr *, int *);
+typedef int (SOCKETAPI *LPSOCKBIND)(SOCKET, const struct sockaddr *, int);
+typedef int (SOCKETAPI *LPSOCKCLOSESOCKET)(SOCKET);
+typedef int (SOCKETAPI *LPSOCKCONNECT)(SOCKET, const struct sockaddr *, int);
+typedef int (SOCKETAPI *LPSOCKIOCTLSOCKET)(SOCKET, long, u_long *);
+typedef int (SOCKETAPI *LPSOCKGETPEERNAME)(SOCKET, struct sockaddr *, int *);
+typedef int (SOCKETAPI *LPSOCKGETSOCKNAME)(SOCKET, struct sockaddr *, int *);
+typedef int (SOCKETAPI *LPSOCKGETSOCKOPT)(SOCKET, int, int, char *, int *);
+typedef u_long (SOCKETAPI *LPSOCKHTONL)(u_long);
+typedef u_short (SOCKETAPI *LPSOCKHTONS)(u_short);
+typedef int (SOCKETAPI *LPSOCKLISTEN)(SOCKET, int);
+typedef u_long (SOCKETAPI *LPSOCKNTOHL)(u_long);
+typedef u_short (SOCKETAPI *LPSOCKNTOHS)(u_short);
+typedef int (SOCKETAPI *LPSOCKRECV)(SOCKET, char *, int, int);
+typedef int (SOCKETAPI *LPSOCKRECVFROM)(SOCKET, char *, int, int, struct sockaddr *, int *);
+typedef int (SOCKETAPI *LPSOCKSELECT)(int, fd_set *, fd_set *, fd_set *, const struct timeval *);
+typedef int (SOCKETAPI *LPSOCKSEND)(SOCKET, const char *, int, int);
+typedef int (SOCKETAPI *LPSOCKSENDTO)(SOCKET, const char *, int, int, const struct sockaddr *, int);
+typedef int (SOCKETAPI *LPSOCKSETSOCKOPT)(SOCKET, int, int, const char *, int);
+typedef int (SOCKETAPI *LPSOCKSHUTDOWN)(SOCKET, int);
+typedef SOCKET (SOCKETAPI *LPSOCKSOCKET)(int, int, int);
+typedef char FAR *(SOCKETAPI *LPSOCKINETNTOA)(struct in_addr in);
+typedef unsigned long (SOCKETAPI *LPSOCKINETADDR)(const char FAR * cp);
+
+
+/* Database function prototypes */
+typedef struct hostent *(SOCKETAPI *LPSOCKGETHOSTBYADDR)(const char *, int, int);
+typedef struct hostent *(SOCKETAPI *LPSOCKGETHOSTBYNAME)(const char *);
+typedef int (SOCKETAPI *LPSOCKGETHOSTNAME)(char *, int);
+typedef struct servent *(SOCKETAPI *LPSOCKGETSERVBYPORT)(int, const char *);
+typedef struct servent *(SOCKETAPI *LPSOCKGETSERVBYNAME)(const char *, const char *);
+typedef struct protoent *(SOCKETAPI *LPSOCKGETPROTOBYNUMBER)(int);
+typedef struct protoent *(SOCKETAPI *LPSOCKGETPROTOBYNAME)(const char *);
+
+/* Microsoft Windows Extension function prototypes */
+typedef int (SOCKETAPI *LPSOCKWSASTARTUP)(unsigned short, LPWSADATA);
+typedef int (SOCKETAPI *LPSOCKWSACLEANUP)(void);
+typedef int (SOCKETAPI *LPSOCKWSAGETLASTERROR)(void);
+typedef int (SOCKETAPI *LPWSAFDIsSet)(SOCKET, fd_set *);
+
+static HINSTANCE hWinSockDll = 0;
+// extern CRITICAL_SECTION csSock;
+
+static LPSOCKACCEPT paccept = 0;
+static LPSOCKBIND pbind = 0;
+static LPSOCKCLOSESOCKET pclosesocket = 0;
+static LPSOCKCONNECT pconnect = 0;
+static LPSOCKIOCTLSOCKET pioctlsocket = 0;
+static LPSOCKGETPEERNAME pgetpeername = 0;
+static LPSOCKGETSOCKNAME pgetsockname = 0;
+static LPSOCKGETSOCKOPT pgetsockopt = 0;
+static LPSOCKHTONL phtonl = 0;
+static LPSOCKHTONS phtons = 0;
+static LPSOCKLISTEN plisten = 0;
+static LPSOCKNTOHL pntohl = 0;
+static LPSOCKNTOHS pntohs = 0;
+static LPSOCKRECV precv = 0;
+static LPSOCKRECVFROM precvfrom = 0;
+static LPSOCKSELECT pselect = 0;
+static LPSOCKSEND psend = 0;
+static LPSOCKSENDTO psendto = 0;
+static LPSOCKSETSOCKOPT psetsockopt = 0;
+static LPSOCKSHUTDOWN pshutdown = 0;
+static LPSOCKSOCKET psocket = 0;
+static LPSOCKGETHOSTBYADDR pgethostbyaddr = 0;
+static LPSOCKGETHOSTBYNAME pgethostbyname = 0;
+static LPSOCKGETHOSTNAME pgethostname = 0;
+static LPSOCKGETSERVBYPORT pgetservbyport = 0;
+static LPSOCKGETSERVBYNAME pgetservbyname = 0;
+static LPSOCKGETPROTOBYNUMBER pgetprotobynumber = 0;
+static LPSOCKGETPROTOBYNAME pgetprotobyname = 0;
+static LPSOCKWSASTARTUP pWSAStartup = 0;
+static LPSOCKWSACLEANUP pWSACleanup = 0;
+static LPSOCKWSAGETLASTERROR pWSAGetLastError = 0;
+static LPWSAFDIsSet pWSAFDIsSet = 0;
+static LPSOCKINETNTOA pinet_ntoa = 0;
+static LPSOCKINETADDR pinet_addr = 0;
+
+__declspec(thread) struct servent myservent;
+
+
+void *GetAddress(HINSTANCE hInstance, char *lpFunctionName)
+{
+ char buffer[512];
+ FARPROC proc = GetProcAddress(hInstance, lpFunctionName);
+ if(proc == 0)
+ {
+ sprintf(buffer, "Unable to get address of %s in WSock32.dll", lpFunctionName);
+ CROAK(buffer);
+ }
+ return proc;
+}
+
+void LoadWinSock(void)
+{
+// EnterCriticalSection(&csSock);
+ if(hWinSockDll == NULL)
+ {
+ HINSTANCE hLib = LoadLibrary("WSock32.DLL");
+ if(hLib == NULL)
+ CROAK("Could not load WSock32.dll\n");
+
+ paccept = (LPSOCKACCEPT)GetAddress(hLib, "accept");
+ pbind = (LPSOCKBIND)GetAddress(hLib, "bind");
+ pclosesocket = (LPSOCKCLOSESOCKET)GetAddress(hLib, "closesocket");
+ pconnect = (LPSOCKCONNECT)GetAddress(hLib, "connect");
+ pioctlsocket = (LPSOCKIOCTLSOCKET)GetAddress(hLib, "ioctlsocket");
+ pgetpeername = (LPSOCKGETPEERNAME)GetAddress(hLib, "getpeername");
+ pgetsockname = (LPSOCKGETSOCKNAME)GetAddress(hLib, "getsockname");
+ pgetsockopt = (LPSOCKGETSOCKOPT)GetAddress(hLib, "getsockopt");
+ phtonl = (LPSOCKHTONL)GetAddress(hLib, "htonl");
+ phtons = (LPSOCKHTONS)GetAddress(hLib, "htons");
+ plisten = (LPSOCKLISTEN)GetAddress(hLib, "listen");
+ pntohl = (LPSOCKNTOHL)GetAddress(hLib, "ntohl");
+ pntohs = (LPSOCKNTOHS)GetAddress(hLib, "ntohs");
+ precv = (LPSOCKRECV)GetAddress(hLib, "recv");
+ precvfrom = (LPSOCKRECVFROM)GetAddress(hLib, "recvfrom");
+ pselect = (LPSOCKSELECT)GetAddress(hLib, "select");
+ psend = (LPSOCKSEND)GetAddress(hLib, "send");
+ psendto = (LPSOCKSENDTO)GetAddress(hLib, "sendto");
+ psetsockopt = (LPSOCKSETSOCKOPT)GetAddress(hLib, "setsockopt");
+ pshutdown = (LPSOCKSHUTDOWN)GetAddress(hLib, "shutdown");
+ psocket = (LPSOCKSOCKET)GetAddress(hLib, "socket");
+ pgethostbyaddr = (LPSOCKGETHOSTBYADDR)GetAddress(hLib, "gethostbyaddr");
+ pgethostbyname = (LPSOCKGETHOSTBYNAME)GetAddress(hLib, "gethostbyname");
+ pgethostname = (LPSOCKGETHOSTNAME)GetAddress(hLib, "gethostname");
+ pgetservbyport = (LPSOCKGETSERVBYPORT)GetAddress(hLib, "getservbyport");
+ pgetservbyname = (LPSOCKGETSERVBYNAME)GetAddress(hLib, "getservbyname");
+ pgetprotobynumber = (LPSOCKGETPROTOBYNUMBER)GetAddress(hLib, "getprotobynumber");
+ pgetprotobyname = (LPSOCKGETPROTOBYNAME)GetAddress(hLib, "getprotobyname");
+ pWSAStartup = (LPSOCKWSASTARTUP)GetAddress(hLib, "WSAStartup");
+ pWSACleanup = (LPSOCKWSACLEANUP)GetAddress(hLib, "WSACleanup");
+ pWSAGetLastError = (LPSOCKWSAGETLASTERROR)GetAddress(hLib, "WSAGetLastError");
+ pWSAFDIsSet = (LPWSAFDIsSet)GetAddress(hLib, "__WSAFDIsSet");
+ pinet_addr = (LPSOCKINETADDR)GetAddress(hLib,"inet_addr");
+ pinet_ntoa = (LPSOCKINETNTOA)GetAddress(hLib,"inet_ntoa");
+
+ hWinSockDll = hLib;
+ }
+// LeaveCriticalSection(&csSock);
+}
+
+void EndSockets(void)
+{
+ if(hWinSockDll != NULL)
+ {
+ pWSACleanup();
+ FreeLibrary(hWinSockDll);
+ }
+ hWinSockDll = NULL;
+}
+
+void StartSockets(void)
+{
+ unsigned short version;
+ WSADATA retdata;
+ int ret;
+ int iSockOpt = SO_SYNCHRONOUS_NONALERT;
+
+ LoadWinSock();
+ //
+ // initalize the winsock interface and insure that it is
+ // cleaned up at exit.
+ //
+ version = 0x101;
+ if(ret = pWSAStartup(version, &retdata))
+ CROAK("Unable to locate winsock library!\n");
+ if(retdata.wVersion != version)
+ CROAK("Could not find version 1.1 of winsock dll\n");
+
+ // atexit((void (*)(void)) EndSockets);
+
+#ifdef USE_SOCKETS_AS_HANDLES
+ //
+ // Enable the use of sockets as filehandles
+ //
+ psetsockopt(INVALID_SOCKET, SOL_SOCKET, SO_OPENTYPE, (char *)&iSockOpt, sizeof(iSockOpt));
+#endif // USE_SOCKETS_AS_HANDLES
+}
+
+
+#ifndef USE_SOCKETS_AS_HANDLES
+FILE *myfdopen(int fd, char *mode)
+{
+ FILE *fp;
+ char sockbuf[256];
+ int optlen = sizeof(sockbuf);
+ int retval;
+
+
+ if(hWinSockDll == 0)
+ LoadWinSock();
+
+ retval = pgetsockopt((SOCKET)fd, SOL_SOCKET, SO_TYPE, sockbuf, &optlen);
+ if(retval == SOCKET_ERROR && pWSAGetLastError() == WSAENOTSOCK)
+ {
+ return(_fdopen(fd, mode));
+ }
+
+ //
+ // If we get here, then fd is actually a socket.
+ //
+ Newz(1601, fp, 1, FILE);
+ if(fp == NULL)
+ {
+ errno = ENOMEM;
+ return NULL;
+ }
+
+ fp->_file = fd;
+ if(*mode == 'r')
+ fp->_flag = _IOREAD;
+ else
+ fp->_flag = _IOWRT;
+
+ return fp;
+}
+#endif // USE_SOCKETS_AS_HANDLES
+
+
+u_long win32_htonl(u_long hostlong)
+{
+ if(hWinSockDll == 0)
+ LoadWinSock();
+
+ return phtonl(hostlong);
+}
+
+u_short win32_htons(u_short hostshort)
+{
+ if(hWinSockDll == 0)
+ LoadWinSock();
+
+ return phtons(hostshort);
+}
+
+u_long win32_ntohl(u_long netlong)
+{
+ if(hWinSockDll == 0)
+ LoadWinSock();
+
+ return pntohl(netlong);
+}
+
+u_short win32_ntohs(u_short netshort)
+{
+ if(hWinSockDll == 0)
+ LoadWinSock();
+
+ return pntohs(netshort);
+}
+
+
+#define SOCKET_TEST(x, y) if(hWinSockDll == 0) StartSockets();\
+ if((x) == (y)) errno = pWSAGetLastError()
+
+#define SOCKET_TEST_ERROR(x) SOCKET_TEST(x, SOCKET_ERROR)
+
+SOCKET win32_accept(SOCKET s, struct sockaddr *addr, int *addrlen)
+{
+ SOCKET r;
+
+ SOCKET_TEST((r = paccept(TO_SOCKET(s), addr, addrlen)), INVALID_SOCKET);
+ return OPEN_SOCKET(r);
+}
+
+int win32_bind(SOCKET s, const struct sockaddr *addr, int addrlen)
+{
+ int r;
+
+ SOCKET_TEST_ERROR(r = pbind(TO_SOCKET(s), addr, addrlen));
+ return r;
+}
+
+int win32_connect(SOCKET s, const struct sockaddr *addr, int addrlen)
+{
+ int r;
+
+ SOCKET_TEST_ERROR(r = pconnect(TO_SOCKET(s), addr, addrlen));
+ return r;
+}
+
+
+int win32_getpeername(SOCKET s, struct sockaddr *addr, int *addrlen)
+{
+ int r;
+
+ SOCKET_TEST_ERROR(r = pgetpeername(TO_SOCKET(s), addr, addrlen));
+ return r;
+}
+
+int win32_getsockname(SOCKET s, struct sockaddr *addr, int *addrlen)
+{
+ int r;
+
+ SOCKET_TEST_ERROR(r = pgetsockname(TO_SOCKET(s), addr, addrlen));
+ return r;
+}
+
+int win32_getsockopt(SOCKET s, int level, int optname, char *optval, int *optlen)
+{
+ int r;
+
+ SOCKET_TEST_ERROR(r = pgetsockopt(TO_SOCKET(s), level, optname, optval, optlen));
+ return r;
+}
+
+int win32_ioctlsocket(SOCKET s, long cmd, u_long *argp)
+{
+ int r;
+
+ SOCKET_TEST_ERROR(r = pioctlsocket(TO_SOCKET(s), cmd, argp));
+ return r;
+}
+
+int win32_listen(SOCKET s, int backlog)
+{
+ int r;
+
+ SOCKET_TEST_ERROR(r = plisten(TO_SOCKET(s), backlog));
+ return r;
+}
+
+int win32_recv(SOCKET s, char *buf, int len, int flags)
+{
+ int r;
+
+ SOCKET_TEST_ERROR(r = precv(TO_SOCKET(s), buf, len, flags));
+ return r;
+}
+
+int win32_recvfrom(SOCKET s, char *buf, int len, int flags, struct sockaddr *from, int *fromlen)
+{
+ int r;
+
+ SOCKET_TEST_ERROR(r = precvfrom(TO_SOCKET(s), buf, len, flags, from, fromlen));
+ return r;
+}
+
+// select contributed by Vincent R. Slyngstad (vrs@ibeam.intel.com)
+int win32_select(int nfds, int* rd, int* wr, int* ex, const struct timeval* timeout)
+{
+ long r;
+ int dummy = 0;
+ int i, fd, bit, offset;
+ FD_SET nrd, nwr, nex,*prd,*pwr,*pex;
+
+ if (!rd) rd = &dummy, prd = NULL;
+ else prd = &nrd;
+ if (!wr) wr = &dummy, pwr = NULL;
+ else pwr = &nwr;
+ if (!ex) ex = &dummy, pex = NULL;
+ else pex = &nex;
+
+ FD_ZERO(&nrd);
+ FD_ZERO(&nwr);
+ FD_ZERO(&nex);
+ for (i = 0; i < nfds; i++)
+ {
+ fd = TO_SOCKET(i);
+ bit = 1L<<(i % (sizeof(int)*8));
+ offset = i / (sizeof(int)*8);
+ if (rd[offset] & bit)
+ FD_SET(fd, &nrd);
+ if (wr[offset] & bit)
+ FD_SET(fd, &nwr);
+ if (ex[offset] & bit)
+ FD_SET(fd, &nex);
+ }
+
+ SOCKET_TEST_ERROR(r = pselect(nfds, prd, pwr, pex, timeout));
+
+ for (i = 0; i < nfds; i++)
+ {
+ fd = TO_SOCKET(i);
+ bit = 1L<<(i % (sizeof(int)*8));
+ offset = i / (sizeof(int)*8);
+ if (rd[offset] & bit)
+ {
+ if (!pWSAFDIsSet(fd, &nrd))
+ rd[offset] &= ~bit;
+ }
+ if (wr[offset] & bit)
+ {
+ if (!pWSAFDIsSet(fd, &nwr))
+ wr[offset] &= ~bit;
+ }
+ if (ex[offset] & bit)
+ {
+ if (!pWSAFDIsSet(fd, &nex))
+ ex[offset] &= ~bit;
+ }
+ }
+ return r;
+}
+
+int win32_send(SOCKET s, const char *buf, int len, int flags)
+{
+ int r;
+
+ SOCKET_TEST_ERROR(r = psend(TO_SOCKET(s), buf, len, flags));
+ return r;
+}
+
+int win32_sendto(SOCKET s, const char *buf, int len, int flags, const struct sockaddr *to, int tolen)
+{
+ int r;
+
+ SOCKET_TEST_ERROR(r = psendto(TO_SOCKET(s), buf, len, flags, to, tolen));
+ return r;
+}
+
+int win32_setsockopt(SOCKET s, int level, int optname, const char *optval, int optlen)
+{
+ int r;
+
+ SOCKET_TEST_ERROR(r = psetsockopt(TO_SOCKET(s), level, optname, optval, optlen));
+ return r;
+}
+
+int win32_shutdown(SOCKET s, int how)
+{
+ int r;
+
+ SOCKET_TEST_ERROR(r = pshutdown(TO_SOCKET(s), how));
+ return r;
+}
+
+SOCKET win32_socket(int af, int type, int protocol)
+{
+ SOCKET s;
+
+#ifndef USE_SOCKETS_AS_HANDLES
+ SOCKET_TEST(s = psocket(af, type, protocol), INVALID_SOCKET);
+#else
+ if(hWinSockDll == 0)
+ StartSockets();
+
+ if((s = psocket(af, type, protocol)) == INVALID_SOCKET)
+ errno = pWSAGetLastError();
+ else
+ s = OPEN_SOCKET(s);
+#endif // USE_SOCKETS_AS_HANDLES
+
+ return s;
+}
+
+struct hostent *win32_gethostbyaddr(const char *addr, int len, int type)
+{
+ struct hostent *r;
+
+ SOCKET_TEST(r = pgethostbyaddr(addr, len, type), NULL);
+ return r;
+}
+
+struct hostent *win32_gethostbyname(const char *name)
+{
+ struct hostent *r;
+
+ SOCKET_TEST(r = pgethostbyname(name), NULL);
+ return r;
+}
+
+int win32_gethostname(char *name, int len)
+{
+ int r;
+
+ SOCKET_TEST_ERROR(r = pgethostname(name, len));
+ return r;
+}
+
+struct protoent *win32_getprotobyname(const char *name)
+{
+ struct protoent *r;
+
+ SOCKET_TEST(r = pgetprotobyname(name), NULL);
+ return r;
+}
+
+struct protoent *win32_getprotobynumber(int num)
+{
+ struct protoent *r;
+
+ SOCKET_TEST(r = pgetprotobynumber(num), NULL);
+ return r;
+}
+
+struct servent *win32_getservbyname(const char *name, const char *proto)
+{
+ struct servent *r;
+
+ SOCKET_TEST(r = pgetservbyname(name, proto), NULL);
+ if (r) {
+ r = win32_savecopyservent(&myservent, r, proto);
+ }
+ return r;
+}
+
+struct servent *win32_getservbyport(int port, const char *proto)
+{
+ struct servent *r;
+
+ SOCKET_TEST(r = pgetservbyport(port, proto), NULL);
+ if (r) {
+ r = win32_savecopyservent(&myservent, r, proto);
+ }
+ return r;
+}
+
+char FAR *win32_inet_ntoa(struct in_addr in)
+{
+ if(hWinSockDll == 0) LoadWinSock();
+
+ return pinet_ntoa(in);
+}
+
+unsigned long win32_inet_addr(const char FAR *cp)
+{
+ if(hWinSockDll == 0) LoadWinSock();
+
+ return pinet_addr(cp);
+
+}
+//
+// Networking stubs
+//
+#undef CROAK
+#define CROAK croak
+
+void win32_endhostent()
+{
+ CROAK("endhostent not implemented!\n");
+}
+
+void win32_endnetent()
+{
+ CROAK("endnetent not implemented!\n");
+}
+
+void win32_endprotoent()
+{
+ CROAK("endprotoent not implemented!\n");
+}
+
+void win32_endservent()
+{
+ CROAK("endservent not implemented!\n");
+}
+
+
+struct netent *win32_getnetent(void)
+{
+ CROAK("getnetent not implemented!\n");
+ return (struct netent *) NULL;
+}
+
+struct netent *win32_getnetbyname(char *name)
+{
+ CROAK("getnetbyname not implemented!\n");
+ return (struct netent *)NULL;
+}
+
+struct netent *win32_getnetbyaddr(long net, int type)
+{
+ CROAK("getnetbyaddr not implemented!\n");
+ return (struct netent *)NULL;
+}
+
+struct protoent *win32_getprotoent(void)
+{
+ CROAK("getprotoent not implemented!\n");
+ return (struct protoent *) NULL;
+}
+
+struct servent *win32_getservent(void)
+{
+ CROAK("getservent not implemented!\n");
+ return (struct servent *) NULL;
+}
+
+void win32_sethostent(int stayopen)
+{
+ CROAK("sethostent not implemented!\n");
+}
+
+
+void win32_setnetent(int stayopen)
+{
+ CROAK("setnetent not implemented!\n");
+}
+
+
+void win32_setprotoent(int stayopen)
+{
+ CROAK("setprotoent not implemented!\n");
+}
+
+
+void win32_setservent(int stayopen)
+{
+ CROAK("setservent not implemented!\n");
+}
+
+