Index: trunk/src/wsock32/asyncapi.cpp
===================================================================
--- trunk/src/wsock32/asyncapi.cpp	(revision 3229)
+++ trunk/src/wsock32/asyncapi.cpp	(revision 3229)
@@ -0,0 +1,639 @@
+/* $Id: asyncapi.cpp,v 1.3 2000-03-24 19:28:03 sandervl Exp $ */
+
+/*
+ *
+ * Win32 SOCK32 for OS/2 (Async apis)
+ *
+ * Copyright (C) 2000 Sander van Leeuwen (sandervl@xs4all.nl)
+ *
+ * Parts based on Wine code: (dlls\winsock\async.c)
+ * (C) 1993,1994,1996,1997 John Brezak, Erik Bos, Alex Korobka.
+ * (C) 1999 Marcus Meissner
+ *
+ * Project Odin Software License can be found in LICENSE.TXT
+ *
+ */
+#define INCL_BASE
+#include <os2wrap.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <odin.h>
+#include <odinwrap.h>
+#include <os2sel.h>
+#include <misc.h>
+#include <win32api.h>
+#include "wsock32.h"
+#include "asyncthread.h"
+#include "wsastruct.h"
+
+#define DBG_LOCALLOG	DBG_async
+#include "dbglocal.h"
+
+ODINDEBUGCHANNEL(WSOCK32-ASYNC)
+
+//******************************************************************************
+//NOTE: Must execute RemoveFromQueue before returning
+//******************************************************************************
+void ASYNCCNV WSAsyncThreadProc(void *pparm)
+{
+ PASYNCTHREADPARM pThreadParm = (PASYNCTHREADPARM)pparm;
+ LPARAM           lParam;
+ int              size = 0;
+ int              fail = NO_ERROR;
+ 
+   if(!pThreadParm->fCancelled)
+   {
+	switch(pThreadParm->request)
+	{
+	case ASYNC_GETHOSTBYNAME:
+	case ASYNC_GETHOSTBYADDR:
+	{
+	  struct hostent  *ret;
+
+		if(pThreadParm->request == ASYNC_GETHOSTBYNAME) {
+	      		ret = gethostbyname(pThreadParm->u.gethostbyname.name);
+
+   			free(pThreadParm->u.gethostbyname.name);
+			pThreadParm->u.gethostbyname.name = 0;
+		}
+		else {
+			ret = gethostbyaddr(pThreadParm->u.gethostbyaddr.addr, 
+                                            pThreadParm->u.gethostbyaddr.len,
+                                            pThreadParm->u.gethostbyaddr.type);
+
+   			free(pThreadParm->u.gethostbyaddr.addr);
+			pThreadParm->u.gethostbyaddr.addr = 0;
+		}
+	      	if (ret != NULL) {
+			size = WS_copy_he((struct ws_hostent *)pThreadParm->buf,
+	                                  pThreadParm->buf,
+	                                  pThreadParm->buflen,
+	                                  ret);
+			if(size < 0) {
+	            		fail = WSAENOBUFS;
+				size = -size;
+	         	}
+	      	}
+	      	else  	fail = wsaHerrno();
+		break;
+	}
+
+	case ASYNC_GETPROTOBYNAME:
+	case ASYNC_GETPROTOBYNUMBER:
+	{
+	  struct protoent *ret;
+
+		if(pThreadParm->request == ASYNC_GETPROTOBYNAME) {
+	      		ret = getprotobyname(pThreadParm->u.getprotobyname.name);
+
+			free(pThreadParm->u.getprotobyname.name);
+			pThreadParm->u.getprotobyname.name = 0;
+		}
+      		else	ret = getprotobynumber(pThreadParm->u.getprotobynumber.number);
+
+	      	if (ret != NULL) {
+			size = WS_copy_pe((struct ws_protoent *)pThreadParm->buf,
+	                                  pThreadParm->buf,
+	                                  pThreadParm->buflen,
+	                                  ret);
+			if(size < 0) {
+	            		fail = WSAENOBUFS;
+				size = -size;
+	         	}
+	      	}
+	      	else  	fail = WSANO_DATA;
+
+		break;
+	}
+
+	case ASYNC_GETSERVBYNAME:
+	case ASYNC_GETSERVBYPORT:
+	{
+	  struct servent  *ret;
+
+		if(pThreadParm->request == ASYNC_GETSERVBYNAME) {
+	      		ret = getservbyname(pThreadParm->u.getservbyname.name, pThreadParm->u.getservbyname.proto);
+
+   			free(pThreadParm->u.getservbyname.name);
+			pThreadParm->u.getservbyname.name = 0;
+
+	   		if(pThreadParm->u.getservbyname.proto) {
+				free(pThreadParm->u.getservbyname.proto);
+				pThreadParm->u.getservbyname.proto = 0;
+   			}
+
+		}
+		else {
+			ret = getservbyport(pThreadParm->u.getservbyport.port, pThreadParm->u.getservbyport.proto);
+	   		if(pThreadParm->u.getservbyport.proto) {
+				free(pThreadParm->u.getservbyport.proto);
+				pThreadParm->u.getservbyport.proto = 0;
+   			}
+		}
+
+	      	if (ret != NULL) {
+			size = WS_copy_se((struct ws_servent *)pThreadParm->buf,
+	                                  pThreadParm->buf,
+	                                  pThreadParm->buflen,
+        	                          ret);
+			if(size < 0) {
+	            		fail = WSAENOBUFS;
+				size = -size;
+	         	}
+	      	}
+	      	else  	fail = WSANO_DATA;
+		break;
+	}
+	}
+   }
+   lParam = (fail << 16) | size;
+
+   if(!pThreadParm->fCancelled) {
+   	dprintf(("WSAsyncThreadProc %x %x %x %x", pThreadParm->hwnd, pThreadParm->msg, pThreadParm->hAsyncTaskHandle, lParam));
+  	PostMessageA(pThreadParm->hwnd, pThreadParm->msg, 
+                     (WPARAM)pThreadParm->hAsyncTaskHandle, lParam);
+   }
+   pThreadParm->fActive = FALSE;
+   RemoveFromQueue(pThreadParm); 
+}
+//******************************************************************************
+//******************************************************************************
+LHANDLE WSAAsyncRequest(AsyncRequestType requesttype, HWND hwnd, int msg, char *buf, 
+                        int buflen, PVOID param1, PVOID param2, PVOID param3,
+                        PVOID param4)
+{
+  PASYNCTHREADPARM pThreadParm;
+  LHANDLE          hAsyncRequest = 0;
+  LPSTR            tempname  = 0;
+  LPSTR            tempproto = 0;
+  LPSTR            tempaddr  = 0;
+
+   if(!fWSAInitialized)
+   {
+      	WSASetLastError(WSANOTINITIALISED);
+   }
+   else
+   if(WSAIsBlocking())
+   {
+        WSASetLastError(WSAEINPROGRESS);      	// blocking call in progress
+   }
+   else
+   if(!IsWindow(hwnd))
+   {
+        WSASetLastError(WSAEINVAL);           	// invalid parameter
+   }
+   else
+   if(buf == NULL || buflen == 0) {
+        WSASetLastError(WSAENOBUFS);         	// invalid parameter
+   }
+   else
+   {
+	pThreadParm = (PASYNCTHREADPARM)malloc(sizeof(ASYNCTHREADPARM));
+	if(pThreadParm == NULL) {
+		dprintf(("WSAAsyncRequest: malloc failure!"));
+		DebugInt3();
+		WSASetLastError(WSAEFAULT);
+		return 0;
+	}
+	memset(pThreadParm, 0, sizeof(*pThreadParm));
+	pThreadParm->request= requesttype;
+        pThreadParm->hwnd   = hwnd;
+        pThreadParm->msg    = msg;
+        pThreadParm->buf    = buf;
+        pThreadParm->buflen = buflen;
+
+	switch(requesttype) {
+	case ASYNC_GETHOSTBYNAME:
+		tempname = (LPSTR)malloc(strlen((char *)param1)+1);
+        	if(tempname == NULL)
+		{
+			dprintf(("WSAAsyncGetHostByName: malloc failure!"));
+			DebugInt3();
+			WSASetLastError(WSAEFAULT);
+			return 0;
+		}
+		pThreadParm->u.gethostbyname.name   = tempname;
+		strcpy(pThreadParm->u.gethostbyname.name, (char *)param1);
+		break;
+
+	case ASYNC_GETHOSTBYADDR:
+		tempaddr = (LPSTR)malloc(strlen((char *)param1)+1);
+	        if(tempaddr == NULL)
+		{
+			dprintf(("WSAAsyncGetHostByAddr: malloc failure!"));
+			DebugInt3();
+			WSASetLastError(WSAEFAULT);
+			return 0;
+		}
+
+        	pThreadParm->u.gethostbyaddr.len  = (int)param2;
+	        pThreadParm->u.gethostbyaddr.type = (int)param3;
+		pThreadParm->u.gethostbyaddr.addr = tempaddr;
+		strcpy(pThreadParm->u.gethostbyaddr.addr, (char *)param1);
+		break;
+
+	case ASYNC_GETPROTOBYNAME:
+		tempname = (LPSTR)malloc(strlen((char *)param1)+1);
+	        if(tempname == NULL)
+		{
+			dprintf(("WSAAsyncGetProtoByName: malloc failure!"));
+			DebugInt3();
+			WSASetLastError(WSAEFAULT);
+			return 0;
+		}
+		pThreadParm->u.getprotobyname.name = tempname;
+		strcpy(pThreadParm->u.getprotobyname.name, (char *)param1);
+		break;
+
+	case ASYNC_GETPROTOBYNUMBER:
+		pThreadParm->u.getprotobynumber.number = (int)param1;
+		break;
+
+	case ASYNC_GETSERVBYNAME:
+		tempname    = (LPSTR)malloc(strlen((char *)param1)+1);
+		tempproto   = NULL;
+		if(param2) {
+			tempproto = (LPSTR)malloc(strlen((char *)param2)+1);
+		}
+	        if(tempname == NULL || (param2 && !tempproto))
+		{
+			dprintf(("WSAAsyncGetServByName: malloc failure!"));
+			DebugInt3();
+			WSASetLastError(WSAEFAULT);
+			return 0;
+		}
+		pThreadParm->u.getservbyname.name   = tempname;
+		strcpy(pThreadParm->u.getservbyname.name, (char *)param1);
+		pThreadParm->u.getservbyname.proto   = tempproto;
+		if(param2)
+			strcpy(pThreadParm->u.getservbyname.proto, (char *)param2);
+		break;
+
+	case ASYNC_GETSERVBYPORT:
+		if(param2) {
+			tempproto = (LPSTR)malloc(strlen((char *)param2)+1);
+		}
+	        if(param2 && !tempproto)
+		{
+			dprintf(("WSAAsyncGetServByPort: malloc failure!"));
+			DebugInt3();
+			WSASetLastError(WSAEFAULT);
+			return 0;
+		}
+		pThreadParm->u.getservbyport.port   = (int)param1;
+		pThreadParm->u.getservbyport.proto  = tempproto;
+		if(param2)
+			strcpy(pThreadParm->u.getservbyport.proto, (char *)param2);
+		break;
+	}
+   	hAsyncRequest = (LHANDLE)QueueAsyncJob(WSAsyncThreadProc, pThreadParm);
+	if(hAsyncRequest == 0) {
+		free(pThreadParm);
+		if(tempname)	free(tempname);
+		if(tempaddr)	free(tempaddr);
+		if(tempproto)	free(tempproto);
+
+		dprintf(("WSAAsyncRequest: QueueAsyncJob failure!"));
+		DebugInt3();
+		WSASetLastError(WSAEFAULT);
+	 	return 0;
+	}
+	return hAsyncRequest;
+   }
+   return 0;
+}                      
+//******************************************************************************
+//******************************************************************************
+ODINFUNCTION5(LHANDLE,WSAAsyncGetHostByName,
+              HWND,hWnd,
+              u_int,wMsg,
+              const char *,name,
+              char *,buf,
+              int,buflen)
+{
+   dprintf(("WSAAsyncGetHostByName %s", name));
+
+   return WSAAsyncRequest(ASYNC_GETHOSTBYNAME, hWnd, wMsg, buf, buflen, 
+                          (PVOID)name, 0, 0, 0);
+}
+//******************************************************************************
+//******************************************************************************
+ODINFUNCTION7(LHANDLE,WSAAsyncGetHostByAddr,
+              HWND,hWnd,
+              u_int,wMsg,
+              const char *,addr,
+              int,len,
+              int,type,
+              char *,buf,
+              int,buflen)
+{
+   dprintf(("WSAAsyncGetHostByAddr %s", addr));
+
+   return WSAAsyncRequest(ASYNC_GETHOSTBYADDR, hWnd, wMsg, buf, buflen, 
+                          (PVOID)addr, (PVOID)len, (PVOID)type, 0);
+}
+//******************************************************************************
+//******************************************************************************
+ODINFUNCTION5(LHANDLE,WSAAsyncGetProtoByName,
+              HWND,hWnd,
+              u_int,wMsg,
+              const char *,name,
+              char *,buf,
+              int,buflen)
+{
+   dprintf(("WSAAsyncGetProtoByName %s", name));
+
+   return WSAAsyncRequest(ASYNC_GETPROTOBYNAME, hWnd, wMsg, buf, buflen, 
+                          (PVOID)name, 0, 0, 0);
+}
+//******************************************************************************
+//******************************************************************************
+ODINFUNCTION5(LHANDLE,WSAAsyncGetProtoByNumber,
+              HWND,hWnd,
+              u_int,wMsg,
+              int,number,
+              char *,buf,
+              int,buflen)
+{
+   dprintf(("WSAAsyncGetProtoByNumber %d", number));
+
+   return WSAAsyncRequest(ASYNC_GETPROTOBYNUMBER, hWnd, wMsg, buf, buflen, 
+                          (PVOID)number, 0, 0, 0);
+}
+//******************************************************************************
+//******************************************************************************
+ODINFUNCTION6(LHANDLE,WSAAsyncGetServByName,
+              HWND,hWnd,
+              u_int,wMsg,
+              const char *,name,
+              const char *,proto,
+              char *,buf,
+              int,buflen)
+{
+   dprintf(("WSAAsyncGetServByName %s", name));
+
+   return WSAAsyncRequest(ASYNC_GETSERVBYNAME, hWnd, wMsg, buf, buflen, 
+                          (PVOID)name, (PVOID)proto, 0, 0);
+}
+//******************************************************************************
+//******************************************************************************
+ODINFUNCTION6(LHANDLE,WSAAsyncGetServByPort,
+              HWND,hWnd,
+              u_int,wMsg,
+              int,port,
+              const char *,proto,
+              char *,buf,
+              int,buflen)
+{
+   dprintf(("WSAAsyncGetServByPort %d %s", port, proto));
+
+   return WSAAsyncRequest(ASYNC_GETSERVBYPORT, hWnd, wMsg, buf, buflen, 
+                          (PVOID)port, (PVOID)proto, 0, 0);
+}
+//******************************************************************************
+//******************************************************************************
+void AsyncNotifyEvent(PASYNCTHREADPARM pThreadParm, ULONG event, ULONG socket_error)
+{
+   pThreadParm->u.asyncselect.lEventsPending &= ~event;
+
+   event = WSAMAKESELECTREPLY(event, socket_error);
+
+   dprintf(("AsyncNotifyEvent %x %x %x %x", pThreadParm->u.asyncselect.s, pThreadParm->hwnd, pThreadParm->msg, event));
+   PostMessageA(pThreadParm->hwnd, pThreadParm->msg, (WPARAM)pThreadParm->u.asyncselect.s, 
+               (LPARAM)event);
+}
+//******************************************************************************
+#define  nr(i) 		((i != -1) ? 1 : 0)
+#define  ready(i)       ((i != -1) && (sockets[i] != -1))
+//NOTE: Must execute RemoveFromQueue before returning
+//******************************************************************************
+void ASYNCCNV WSAsyncSelectThreadProc(void *pparm)
+{
+ PASYNCTHREADPARM pThreadParm = (PASYNCTHREADPARM)pparm;
+ SOCKET           sockets[3];
+ SOCKET           s = pThreadParm->u.asyncselect.s;
+ int       	  noread, nowrite, noexcept, state, sockoptlen, sockoptval;
+ int              tmp, i, lEventsPending, ret, bytesread;
+  
+   while(TRUE)
+   {
+asyncloopstart:
+	i      = 0;
+	noread = nowrite = noexcept = -1;
+
+	//break if user cancelled request
+      	if(pThreadParm->u.asyncselect.lEvents == 0) {
+		break;
+      	}
+
+        lEventsPending = pThreadParm->u.asyncselect.lEventsPending;
+      	//block if no events are pending
+      	if(lEventsPending == 0)
+      	{
+		//wait for events to be enabled
+		pThreadParm->u.asyncselect.asyncSem->wait();
+		//reset event semaphore
+		pThreadParm->u.asyncselect.asyncSem->reset();
+         	continue;
+      	}
+
+	if(lEventsPending & (FD_READ | FD_CLOSE | FD_ACCEPT)) {
+		noread = i++;
+		sockets[noread] = s;
+	}
+	if((lEventsPending & FD_CONNECT) ||
+          ((lEventsPending & FD_WRITE) &&
+           (!(ioctl(s, FIOBSTATUS, (char *)&tmp, sizeof(tmp)) & SS_CANTSENDMORE))))
+        {
+		nowrite = i++;
+		sockets[nowrite] = s;
+	}
+	if(lEventsPending & FD_OOB) {
+		noexcept = i++;
+		sockets[noexcept] = s;
+	}
+
+////        dprintf(("WSAsyncSelectThreadProc %x rds=%d, wrs=%d, oos =%d, pending = %x", pThreadParm->u.asyncselect.s, noread, nowrite, noexcept, lEventsPending));
+
+	ret = select((int *)sockets, nr(noread), nr(nowrite), nr(noexcept), -1);
+	if(ret == SOCKET_ERROR) {
+		int selecterr = sock_errno();
+        	dprintf(("WSAsyncSelectThreadProc %x rds=%d, wrs=%d, oos =%d, pending = %x select returned %x", pThreadParm->u.asyncselect.s, noread, nowrite, noexcept, lEventsPending, selecterr));
+		switch(selecterr) 
+		{
+		case SOCEINTR:
+			goto asyncloopstart;	//so_cancel was called
+
+		case SOCECONNRESET:
+		case SOCEPIPE:
+       			if(lEventsPending & FD_CLOSE)
+       				AsyncNotifyEvent(pThreadParm, FD_CLOSE, WSAECONNRESET);
+
+			//remote connection broken (so can't receive data anymore)
+                        //but can still send
+       			pThreadParm->u.asyncselect.lEventsPending &= ~(FD_READ | FD_ACCEPT);
+			goto asyncloopstart; 
+
+		case SOCEINVAL:
+       			if(lEventsPending & FD_CLOSE)
+       				AsyncNotifyEvent(pThreadParm, FD_CLOSE, selecterr);
+      			break;
+		default:
+			dprintf(("WSAsyncSelectThreadProc: select SOCKET_ERROR %x", selecterr));
+			break; //something bad happened
+		}
+		break;
+	}
+
+      	if(ready(nowrite))
+ 	{
+        	state = ioctl(s, FIOBSTATUS, (char *)&tmp, sizeof(tmp));
+
+         	if(lEventsPending & FD_CONNECT) {
+	    		if(state & SS_ISCONNECTED) {
+				AsyncNotifyEvent(pThreadParm, FD_CONNECT, NO_ERROR);
+	    		}
+            		else {
+            			sockoptlen = sizeof(int);
+
+            			ret = getsockopt(s, SOL_SOCKET, SO_ERROR,
+                	        		 (char *) &sockoptval, &sockoptlen);
+				//SvL: WSeB returns SOCECONNREFUSED, Warp 4 0x3d
+				if(sockoptval == SOCECONNREFUSED || sockoptval == (SOCECONNREFUSED - SOCBASEERR)) {
+					AsyncNotifyEvent(pThreadParm, FD_CONNECT, WSAECONNREFUSED);
+				}
+            		}  
+        	}
+		else
+		if(!(state & SS_CANTSENDMORE) && (lEventsPending & FD_WRITE)) {
+			AsyncNotifyEvent(pThreadParm, FD_WRITE, NO_ERROR);
+		}
+        }
+
+      	if(ready(noread))
+      	{
+         	state = ioctl(s, FIONREAD, (CHAR *) &bytesread, sizeof(bytesread));
+         	if(state == SOCKET_ERROR) {
+            		if(lEventsPending & FD_CLOSE) 
+			{
+				AsyncNotifyEvent(pThreadParm, FD_CLOSE, NO_ERROR);
+				//remote connection broken (so can't receive data anymore)
+                        	//but can still send
+       				pThreadParm->u.asyncselect.lEventsPending &= ~(FD_READ | FD_ACCEPT);
+				continue;
+			}
+			else {
+				dprintf(("WSAsyncSelectThreadProc: ioctl SOCKET_ERROR!"));
+				break; //todo: correct???
+			}
+		}
+         	if(lEventsPending & FD_ACCEPT) 
+ 		{
+            		sockoptlen = sizeof(sockoptlen);
+
+            		ret = getsockopt(s, SOL_SOCKET, SO_OPTIONS,
+                                         (char *) &sockoptval, &sockoptlen);
+		        if(ret == SOCKET_ERROR) {
+				dprintf(("WSAsyncSelectThreadProc: getsockopt SOCKET_ERROR!"));
+               			break;
+			}
+			if((sockoptval & SO_ACCEPTCONN) == SO_ACCEPTCONN) {
+				AsyncNotifyEvent(pThreadParm, FD_ACCEPT, NO_ERROR);
+			}
+		}
+		if((lEventsPending & FD_READ) && bytesread > 0) {
+			AsyncNotifyEvent(pThreadParm, FD_READ, NO_ERROR);
+		}
+	}
+      	if(ready(noexcept))
+      	{
+		if(lEventsPending & FD_OOB) {
+         		AsyncNotifyEvent(pThreadParm, FD_OOB, NO_ERROR);
+		}
+      	}
+	if((pThreadParm->u.asyncselect.lEventsPending & (FD_ACCEPT|FD_CLOSE|FD_CONNECT)) == 
+            (lEventsPending & (FD_ACCEPT|FD_CLOSE|FD_CONNECT))) {
+		DosSleep(10);
+	}
+   }
+   //remove it first, then delete semaphore object
+   pThreadParm->fActive = FALSE;
+   RemoveFromQueue(pThreadParm); 
+   delete pThreadParm->u.asyncselect.asyncSem;
+   pThreadParm->u.asyncselect.asyncSem = 0;
+}
+//******************************************************************************
+//******************************************************************************
+ODINFUNCTION4(int,WSAAsyncSelect,
+              SOCKET,s,
+              HWND,hWnd,
+              u_int,wMsg,
+              long,lEvent)
+{
+  PASYNCTHREADPARM pThreadParm;
+  int              nonblock = 1;
+  int              ret;
+
+   if(!fWSAInitialized)
+   {
+      	WSASetLastError(WSANOTINITIALISED);
+	return SOCKET_ERROR;
+   }
+   else
+   if(WSAIsBlocking())
+   {
+        WSASetLastError(WSAEINPROGRESS);      	// blocking call in progress
+	return SOCKET_ERROR;
+   }
+   else
+   if(hWnd && !IsWindow(hWnd))
+   {
+        WSASetLastError(WSAEINVAL);           	// invalid parameter
+	return SOCKET_ERROR;
+   }
+   //Set socket to non-blocking mode
+   ret = ioctl(s, FIONBIO, (char *) &nonblock, sizeof(nonblock));
+   if(ret == SOCKET_ERROR) {
+ 	WSASetLastError(wsaErrno());
+	return SOCKET_ERROR;
+   }
+   if(FindAndSetAsyncEvent(s, hWnd, wMsg, lEvent) == TRUE) {
+	//found and changed active async event
+	WSASetLastError(NO_ERROR);
+	return NO_ERROR;
+   }
+   pThreadParm = (PASYNCTHREADPARM)malloc(sizeof(ASYNCTHREADPARM));
+   if(pThreadParm == NULL) {
+	dprintf(("WSAAsyncSelect: malloc failure!"));
+	DebugInt3();
+	WSASetLastError(WSAEFAULT);
+ 	return SOCKET_ERROR;
+   }
+   memset(pThreadParm, 0, sizeof(*pThreadParm));
+   pThreadParm->request= ASYNC_SELECT;
+   pThreadParm->hwnd   = hWnd;
+   pThreadParm->msg    = wMsg;
+   pThreadParm->u.asyncselect.lEvents        = lEvent;
+   pThreadParm->u.asyncselect.lEventsPending = lEvent;
+   pThreadParm->u.asyncselect.s              = s;
+   pThreadParm->u.asyncselect.asyncSem       = new VSemaphore;
+   if(pThreadParm->u.asyncselect.asyncSem == NULL) {
+	dprintf(("WSAAsyncSelect: VSemaphore alloc failure!"));
+	DebugInt3();
+	WSASetLastError(WSAEFAULT);
+ 	return SOCKET_ERROR;
+   }
+   if(QueueAsyncJob(WSAsyncSelectThreadProc, pThreadParm) == 0) {
+	delete pThreadParm->u.asyncselect.asyncSem;
+	free(pThreadParm);
+	dprintf(("WSAAsyncSelect: QueueAsyncJob failure!"));
+	DebugInt3();
+	WSASetLastError(WSAEFAULT);
+ 	return SOCKET_ERROR;
+   }
+   WSASetLastError(NO_ERROR);
+   return NO_ERROR;
+}
+//******************************************************************************
+//******************************************************************************
Index: trunk/src/wsock32/asyncthread.cpp
===================================================================
--- trunk/src/wsock32/asyncthread.cpp	(revision 3229)
+++ trunk/src/wsock32/asyncthread.cpp	(revision 3229)
@@ -0,0 +1,241 @@
+/* $Id: asyncthread.cpp,v 1.3 2000-03-24 19:28:04 sandervl Exp $ */
+
+/*
+ * Async thread help functions
+ *
+ * Copyright 2000 Sander van Leeuwen (sandervl@xs4all.nl)
+ *
+ * TODO: Not everything is 100% thread safe  (i.e. async parameter updates)
+ *
+ * Project Odin Software License can be found in LICENSE.TXT
+ *
+ */
+#define INCL_BASE
+#include <os2wrap.h>
+#include <os2sel.h>
+#include <stdlib.h>
+#include <wprocess.h>
+#include <win32api.h>
+#include <misc.h>
+#include <string.h>
+#include <vmutex.h>
+#include "wsock32.h"
+#include "asyncthread.h"
+
+static PASYNCTHREADPARM threadList = NULL;
+static VMutex           asyncThreadMutex;
+
+static void AddToQueue(PASYNCTHREADPARM pThreadParm);
+
+//******************************************************************************
+//******************************************************************************
+static void APIENTRY AsyncThread(ULONG arg)
+{
+ PASYNCTHREADPARM pThreadParm = (PASYNCTHREADPARM)arg;
+
+  pThreadParm->asyncProc((PVOID)arg);
+
+//only for blocking hooks (currently not implemented)
+////  if(pThreadParm->request == ASYNC_BLOCKHOOK)
+////	WSASetBlocking(FALSE, pThreadParm->hThread);
+
+  free((PVOID)pThreadParm);
+
+  DosExit(EXIT_THREAD, 0);
+}
+//******************************************************************************
+//******************************************************************************
+ULONG QueueAsyncJob(ASYNCTHREADPROC asyncproc, PASYNCTHREADPARM pThreadParm, BOOL fSetBlocking)
+{
+ APIRET rc;
+ TID    tid;
+
+   pThreadParm->asyncProc         = asyncproc;
+   pThreadParm->fActive           = TRUE;
+   pThreadParm->fCancelled        = FALSE;
+   pThreadParm->next              = NULL;
+   pThreadParm->hAsyncTaskHandle  = 0;
+
+   pThreadParm->hThread           = GetCurrentThread();
+   AddToQueue(pThreadParm);
+
+   if(fSetBlocking) WSASetBlocking(TRUE);
+
+   rc = DosCreateThread(&tid, AsyncThread, (ULONG)pThreadParm, CREATE_READY, 16384);
+   if(rc)
+   {
+   	dprintf(("QueueAsyncJob: DosCreateThread failed with error %x", rc));
+   	if(fSetBlocking) WSASetBlocking(FALSE);
+	RemoveFromQueue(pThreadParm);
+   	WSASetLastError(WSAEFAULT);
+	return 0;
+   }
+   pThreadParm->hAsyncTaskHandle = tid;
+   WSASetLastError(NO_ERROR);
+   return pThreadParm->hAsyncTaskHandle;
+}
+//******************************************************************************
+//******************************************************************************
+void AddToQueue(PASYNCTHREADPARM pThreadParm)
+{
+   asyncThreadMutex.enter();
+   pThreadParm->next = threadList;
+   threadList        = pThreadParm;
+   asyncThreadMutex.leave();
+}
+//******************************************************************************
+//******************************************************************************
+void RemoveFromQueue(PASYNCTHREADPARM pThreadParm)
+{
+ PASYNCTHREADPARM pThreadInfo;
+
+   asyncThreadMutex.enter();
+   pThreadInfo = threadList;
+
+   if(pThreadInfo == pThreadParm) {
+	threadList = pThreadParm->next;
+   }
+   else {
+	while(pThreadInfo->next) {
+		if(pThreadInfo->next == pThreadParm) {
+			pThreadInfo->next = pThreadParm->next;
+			break;
+		}
+		pThreadInfo = pThreadInfo->next;
+	}
+	if(pThreadInfo == NULL) {
+		dprintf(("RemoveFromQueue: parm %x not found!!", pThreadParm));
+		DebugInt3();
+	}
+   }   
+   memset(pThreadParm, 0, sizeof(*pThreadParm));
+   asyncThreadMutex.leave();
+}
+//******************************************************************************
+//******************************************************************************
+int WIN32API WSACancelAsyncRequest(LHANDLE hAsyncTaskHandle)
+{
+ PASYNCTHREADPARM pThreadInfo;
+ BOOL             found = FALSE;
+
+   dprintf(("WSACancelAsyncRequest: cancel task %x", hAsyncTaskHandle));
+   asyncThreadMutex.enter();
+   pThreadInfo = threadList;
+
+   while(pThreadInfo) {
+	if(pThreadInfo->hAsyncTaskHandle == hAsyncTaskHandle) {
+		pThreadInfo->fCancelled = TRUE;
+		found = TRUE;
+		break;
+	}
+	pThreadInfo = pThreadInfo->next;
+   }
+   asyncThreadMutex.leave();
+   if(found == FALSE) {
+      	WSASetLastError(WSAEINVAL);
+	dprintf(("WSACancelAsyncRequest: task not found!!"));
+   }
+   return (found) ? NO_ERROR : SOCKET_ERROR;
+}
+//******************************************************************************
+//Only to cancel blocking hooks
+//******************************************************************************
+int WIN32API WSACancelBlockingCall()
+{
+ HANDLE hThread = GetCurrentThread();
+
+   dprintf(("WSACancelBlockingCall"));
+#if 0
+   asyncThreadMutex.enter();
+   pThreadInfo = threadList;
+
+   while(pThreadInfo) {
+	if(pThreadInfo->hThread == hThread) {
+		pThreadInfo->fCancelled = TRUE;
+
+		if(pThreadInfo->request == ASYNC_BLOCKHOOK) {
+            		ret = so_cancel(pThreadInfo->blockedsocket);
+		}
+
+		found = TRUE;
+		break;
+	}
+	pThreadInfo = pThreadInfo->next;
+   }
+   asyncThreadMutex.leave();
+#endif
+   return SOCKET_ERROR;
+}
+//******************************************************************************
+//Assumes caller owns async thread mutex!
+//******************************************************************************
+static PASYNCTHREADPARM FindAsyncEvent(SOCKET s)
+{
+ PASYNCTHREADPARM pThreadInfo;
+
+   pThreadInfo = threadList;
+   while(pThreadInfo) {
+	if(pThreadInfo->u.asyncselect.s == s) {
+		return pThreadInfo;
+	}
+	pThreadInfo = pThreadInfo->next;
+   }
+   return NULL;
+}
+//******************************************************************************
+//******************************************************************************
+BOOL FindAndSetAsyncEvent(SOCKET s, HWND hwnd, int msg, ULONG lEvent)
+{
+ PASYNCTHREADPARM pThreadInfo;
+ 
+   asyncThreadMutex.enter();
+   pThreadInfo = FindAsyncEvent(s);
+   if(pThreadInfo) {
+	pThreadInfo->u.asyncselect.lEvents = lEvent;
+	pThreadInfo->hwnd                  = hwnd;
+	pThreadInfo->msg                   = msg;
+	//cancel pending select in async select thread (if any)
+	so_cancel(s);
+
+	//unblock async thread if it was waiting
+	pThreadInfo->u.asyncselect.asyncSem->post();
+   }
+   asyncThreadMutex.leave();
+   return(pThreadInfo != NULL);
+}
+//******************************************************************************
+//******************************************************************************
+void EnableAsyncEvent(SOCKET s, ULONG flags)
+{
+ PASYNCTHREADPARM pThreadInfo;
+
+   asyncThreadMutex.enter();
+   pThreadInfo = FindAsyncEvent(s);
+   if(pThreadInfo) {
+	pThreadInfo->u.asyncselect.lEventsPending |= (pThreadInfo->u.asyncselect.lEvents & flags);
+	//unblock async thread if it was waiting
+	pThreadInfo->u.asyncselect.asyncSem->post();
+
+	//cancel pending select in async select thread (if any)
+	so_cancel(s);
+   }
+   asyncThreadMutex.leave();
+}
+//******************************************************************************
+//******************************************************************************
+BOOL QueryAsyncEvent(SOCKET s, HWND *pHwnd, int *pMsg, ULONG *plEvent)
+{
+ PASYNCTHREADPARM pThreadInfo;
+
+   asyncThreadMutex.enter();
+   pThreadInfo = FindAsyncEvent(s);
+   if(pThreadInfo) {
+	*pHwnd   = pThreadInfo->hwnd;
+	*pMsg    = pThreadInfo->msg;
+	*plEvent = pThreadInfo->u.asyncselect.lEvents;
+   }
+   asyncThreadMutex.leave();
+   return(pThreadInfo != NULL);
+}
+//******************************************************************************
+//******************************************************************************
Index: trunk/src/wsock32/asyncthread.h
===================================================================
--- trunk/src/wsock32/asyncthread.h	(revision 3229)
+++ trunk/src/wsock32/asyncthread.h	(revision 3229)
@@ -0,0 +1,83 @@
+/* $Id: asyncthread.h,v 1.3 2000-03-24 19:28:04 sandervl Exp $ */
+
+/*
+ * Async thread help functions
+ *
+ * Copyright 2000 Sander van Leeuwen (sandervl@xs4all.nl)
+ *
+ * Project Odin Software License can be found in LICENSE.TXT
+ */
+#ifndef __ASYNCTHREAD_H__
+#define __ASYNCTHREAD_H__
+
+#include <vmutex.h>
+#include <vsemaphore.h>
+
+#define	ASYNCCNV	_Optlink
+
+typedef void (* ASYNCCNV ASYNCTHREADPROC)(void *);
+
+enum AsyncRequestType {
+  ASYNC_GETHOSTBYNAME,
+  ASYNC_GETHOSTBYADDR,
+  ASYNC_GETPROTOBYNAME,
+  ASYNC_GETPROTOBYNUMBER,
+  ASYNC_GETSERVBYNAME,
+  ASYNC_GETSERVBYPORT,
+  ASYNC_SELECT
+} ;
+
+typedef struct _ASYNCTHREADPARM
+{
+	BOOL 		fActive;
+	BOOL            fCancelled;
+	AsyncRequestType request;
+	LHANDLE		hAsyncTaskHandle;
+        HANDLE          hThread; //handle of thread that started the async request
+	ASYNCTHREADPROC asyncProc;
+        VMutex         *parmmutex;
+	HWND 		hwnd;
+	DWORD		msg;
+	LPSTR		buf;
+	DWORD		buflen;
+	union {
+		struct {
+			LPSTR	name;
+		} gethostbyname;
+		struct {
+			LPSTR	addr;
+			int	len;
+			int	type;
+		} gethostbyaddr;
+		struct {
+			LPSTR	name;
+		} getprotobyname;
+		struct {
+			int	number;
+		} getprotobynumber;
+		struct {
+			LPSTR	name;
+			LPSTR   proto;
+		} getservbyname;
+		struct {
+			int	port;
+			LPSTR   proto;
+		} getservbyport;
+		struct {
+			VSemaphore *asyncSem;
+			DWORD       lEvents;
+                        DWORD       lEventsPending;
+			SOCKET      s;
+		} asyncselect;
+        } u;
+        _ASYNCTHREADPARM *next;
+} ASYNCTHREADPARM, *PASYNCTHREADPARM;
+
+ULONG QueueAsyncJob(ASYNCTHREADPROC asyncproc, PASYNCTHREADPARM pThreadParm, BOOL fSetBlocking = FALSE);
+void  RemoveFromQueue(PASYNCTHREADPARM pThreadParm);
+
+void  EnableAsyncEvent(SOCKET s, ULONG flags);
+BOOL  QueryAsyncEvent(SOCKET s, HWND *pHwnd, int *pMsg, ULONG *plEvent);
+BOOL  FindAndSetAsyncEvent(SOCKET s, HWND hwnd, int msg, ULONG lEvent);
+
+#endif  //__ASYNCTHREAD_H__
Index: trunk/src/wsock32/dbglocal.cpp
===================================================================
--- trunk/src/wsock32/dbglocal.cpp	(revision 3228)
+++ trunk/src/wsock32/dbglocal.cpp	(revision 3229)
@@ -1,3 +1,3 @@
-/* $Id: dbglocal.cpp,v 1.3 2000-03-22 20:07:20 sandervl Exp $ */
+/* $Id: dbglocal.cpp,v 1.4 2000-03-24 19:28:05 sandervl Exp $ */
 
 /*
@@ -20,9 +20,10 @@
 {
 "initterm",
-"relaywin",
+"wsastruct",
 "wsock32",
 "unknown",
 "async",
-"asyncthread"
+"asyncthread",
+"wsa"
 };
 //******************************************************************************
Index: trunk/src/wsock32/dbglocal.h
===================================================================
--- trunk/src/wsock32/dbglocal.h	(revision 3228)
+++ trunk/src/wsock32/dbglocal.h	(revision 3229)
@@ -1,3 +1,3 @@
-/* $Id: dbglocal.h,v 1.3 2000-03-22 20:07:21 sandervl Exp $ */
+/* $Id: dbglocal.h,v 1.4 2000-03-24 19:28:05 sandervl Exp $ */
 
 /*
@@ -20,10 +20,11 @@
 
 #define DBG_initterm       0
-#define DBG_relaywin       1
+#define DBG_wsastruct      1
 #define DBG_wsock32        2
 #define DBG_unknown        3
 #define DBG_async          4
 #define DBG_asyncthread    5
-#define DBG_MAXFILES       6
+#define DBG_wsa            6
+#define DBG_MAXFILES       7
 
 extern USHORT DbgEnabled[DBG_MAXFILES];
Index: trunk/src/wsock32/initterm.cpp
===================================================================
--- trunk/src/wsock32/initterm.cpp	(revision 3228)
+++ trunk/src/wsock32/initterm.cpp	(revision 3229)
@@ -1,3 +1,3 @@
-/* $Id: initterm.cpp,v 1.10 2000-03-17 16:07:53 sandervl Exp $ */
+/* $Id: initterm.cpp,v 1.11 2000-03-24 19:28:05 sandervl Exp $ */
 
 /*
Index: trunk/src/wsock32/makefile
===================================================================
--- trunk/src/wsock32/makefile	(revision 3228)
+++ trunk/src/wsock32/makefile	(revision 3229)
@@ -1,3 +1,3 @@
-# $Id: makefile,v 1.24 2000-03-22 20:07:22 sandervl Exp $
+# $Id: makefile,v 1.25 2000-03-24 19:28:06 sandervl Exp $
 
 #
@@ -26,9 +26,10 @@
 $(OBJDIR)\wsock32.obj \
 $(OBJDIR)\unknown.obj \
-$(OBJDIR)\relaywin.obj \
+$(OBJDIR)\wsa.obj \
+$(OBJDIR)\wsastruct.obj \
 $(OBJDIR)\wsock32rsrc.obj \
 $(OBJDIR)\initterm.obj \
-#$(OBJDIR)\async.obj \
-#$(OBJDIR)\asyncthread.obj \
+$(OBJDIR)\asyncapi.obj \
+$(OBJDIR)\asyncthread.obj \
 $(OBJDIR)\dbglocal.obj
 
@@ -36,4 +37,6 @@
 # Target name - name of the dll without extention and path.
 TARGET = wsock32
+
+CXXFLAGS = $(CXXFLAGS) -DNEW_ASYNC
 
 
@@ -61,5 +64,5 @@
 $(OBJS)
 $(TARGET).def
-pmwsock.lib
+tcp32dll.lib so32dll.lib
 $(PDWIN32_LIB)\kernel32.lib
 $(PDWIN32_LIB)/user32.lib
Index: trunk/src/wsock32/relaywin.cpp
===================================================================
--- trunk/src/wsock32/relaywin.cpp	(revision 3228)
+++ 	(revision )
@@ -1,641 +1,0 @@
-/*
- *
- * Project Odin Software License can be found in LICENSE.TXT
- *
- * Win32 SOCK32 for OS/2
- *
- * Copyright (C) 1999 Patrick Haller <phaller@gmx.net>
- *
- */
-
-/* Remark:
- * - this is an object window that acts as "relay", this is
- *   it receives WSAAsyncSelect()'s messages and redirects
- *   them to the appropriate PostMessageA function of USER32.
- */
-
-
-/*****************************************************************************
- * Includes                                                                  *
- *****************************************************************************/
-
-/* object.c: the object window procedure on thread 2  */
-// os2 includes
-#define INCL_DOSPROCESS
-#define INCL_WIN
-#include <os2.h>
-// crt includes
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include <odin.h>
-#include <odinwrap.h>
-#include <misc.h>
-
-#include "relaywin.h"
-
-#include <pmwsock.h>
-#include <os2sel.h>
-#include <wprocess.h>
-#include <heapstring.h>
-#include <win32api.h>
-#include "wsock32.h"
-#include <vmutex.h>
-
-#define DBG_LOCALLOG	DBG_relaywin
-#include "dbglocal.h"
-
-ODINDEBUGCHANNEL(WSOCK32-RELAYWIN)
-
-
-/*****************************************************************************
- * Structures                                                                *
- *****************************************************************************/
-
-#define MAX_ASYNC_SOCKETS 64
-
-// static table for id / hwnd-msg translation
-static HWNDMSGPAIR arrHwndMsgPair[MAX_ASYNC_SOCKETS] = {0};
-static char*       ODIN_WSOCK_RELAY_CLASS = "ODIN_WSOCK_RELAY";
-static HWND        hwndRelay              = NULLHANDLE;
-static HAB         hab;
-static VMutex      relayMutex;
-
-/*****************************************************************************
- * Name      :
- * Purpose   :
- * Parameters:
- * Variables :
- * Result    :
- * Remark    :
- * Status    :
- *
- * Author    : Patrick Haller [Tue, 1999/11/30 23:00]
- *****************************************************************************/
-
-ULONG RelayAlloc(HWND  hwnd,
-                 ULONG ulMsg,
-                 ULONG ulRequestType,
-                 BOOL  fSingleRequestPerWindow,
-                 PVOID pvUserData1,
-                 PVOID pvUserData2,
-                 PVOID pvUserData3)
-{
-  ULONG ulCounter;
-
-  relayMutex.enter();
-  for(ulCounter = 0; ulCounter < MAX_ASYNC_SOCKETS; ulCounter++)
-  {
-    	if ( (arrHwndMsgPair[ulCounter].hwnd == 0) ||    // slot free?
-           ( (fSingleRequestPerWindow == TRUE) &&      // more than one request per window?
-           (arrHwndMsgPair[ulCounter].hwnd == hwnd) ) ) // same window?
-        {
-      		// occupy slot
-	      	arrHwndMsgPair[ulCounter].hwnd          = hwnd;
-	      	arrHwndMsgPair[ulCounter].ulMsg         = ulMsg;
-	      	arrHwndMsgPair[ulCounter].ulRequestType = ulRequestType;
-	      	arrHwndMsgPair[ulCounter].pvUserData1   = pvUserData1;
-	      	arrHwndMsgPair[ulCounter].pvUserData2   = pvUserData2;
-	      	arrHwndMsgPair[ulCounter].pvUserData3   = pvUserData3;
-	  	relayMutex.leave();
-	      	return ulCounter + 1; // return "id"
-    	}
-  }
-  relayMutex.leave();
-  return -1; // not found
-}
-
-
-/*****************************************************************************
- * Name      :
- * Purpose   :
- * Parameters:
- * Variables :
- * Result    :
- * Remark    :
- * Status    :
- *
- * Author    : Patrick Haller [Tue, 1999/11/30 23:00]
- *****************************************************************************/
-
-ULONG RelayFree(ULONG ulID)
-{
-  if ( (ulID < 1) ||  // check range
-       (ulID > MAX_ASYNC_SOCKETS) )
-    return -1; // error
-
-  relayMutex.enter();
-  arrHwndMsgPair[ulID-1].hwnd = 0; // mark free
-  arrHwndMsgPair[ulID-1].ulMsg = 0;
-  arrHwndMsgPair[ulID-1].ulRequestType = 0;
-  arrHwndMsgPair[ulID-1].pvUserData1 = 0;
-  arrHwndMsgPair[ulID-1].pvUserData2 = 0;
-  arrHwndMsgPair[ulID-1].pvUserData3 = 0;
-  relayMutex.leave();
-
-  return 0; // OK
-}
-
-
-/*****************************************************************************
- * Name      :
- * Purpose   :
- * Parameters:
- * Variables :
- * Result    :
- * Remark    :
- * Status    :
- *
- * Author    : Patrick Haller [Tue, 1999/11/30 23:00]
- *****************************************************************************/
-
-ULONG RelayFreeByHwnd(HWND hwnd)
-{
-  ULONG ulCounter;
-
-  relayMutex.enter();
-  for(ulCounter = 0; ulCounter < MAX_ASYNC_SOCKETS; ulCounter++)
-  {
-    	if ( arrHwndMsgPair[ulCounter].hwnd == hwnd )  // same window?
-    	{
-      		arrHwndMsgPair[ulCounter].hwnd  = 0; // free slot
-  		arrHwndMsgPair[ulCounter].ulMsg = 0;
-  		arrHwndMsgPair[ulCounter].ulRequestType = 0;
-  		arrHwndMsgPair[ulCounter].pvUserData1 = 0;
-  		arrHwndMsgPair[ulCounter].pvUserData2 = 0;
-  		arrHwndMsgPair[ulCounter].pvUserData3 = 0;
-  		relayMutex.leave();
-      		return 0; // OK
-    	}
-  }
-  relayMutex.leave();
-  dprintf(("RelayFreeByHwnd: window %x not found!", hwnd));
-  return -1; // not found
-}
-
-
-/*****************************************************************************
- * Name      :
- * Purpose   :
- * Parameters:
- * Variables :
- * Result    :
- * Remark    :
- * Status    :
- *
- * Author    : Patrick Haller [Tue, 1999/11/30 23:00]
- *****************************************************************************/
-
-PHWNDMSGPAIR RelayQuery(ULONG ulID)
-{
-  if ( (ulID < 1) ||  // check range
-       (ulID > MAX_ASYNC_SOCKETS) )
-    return NULL; // error
-
-  if (arrHwndMsgPair[ulID-1].hwnd == 0)
-    return NULL; // error, free entry
-  else
-    return (&arrHwndMsgPair[ulID-1]);
-}
-
-
-/*****************************************************************************
- * Name      :
- * Purpose   :
- * Parameters:
- * Variables :
- * Result    :
- * Remark    :
- * Status    :
- *
- * Author    : Patrick Haller [Tue, 1999/11/30 23:00]
- *****************************************************************************/
-
-MRESULT EXPENTRY RelayWindowProc(HWND   hwnd,
-                                 ULONG  ulMsg,
-                                 MPARAM mp1,
-                                 MPARAM mp2)
-{
-  PHWNDMSGPAIR pHM;
-  int          rc;
-
-  // termination flag handling?
-  // if (fTerminate)
-  //   WinDefWindowProc()
-
-  /* find registered message */
-  pHM = RelayQuery(ulMsg);
-  /* message pair found */
-  if (pHM != NULL)
-  {
-    rc = SHORT1FROMMP(mp2);                /* asynchronous operation result */
-
-//    dprintf(("WSOCK32: RelayWindowProc, message %x for window %x with "
-//             "mp1 = %d and mp2 = %d (rc = %d) (time = %x) received\n",
-//             ulMsg, hwnd, mp1, mp2, rc, WinQueryMsgTime(hab)));
-
-    /* check request type for special handling */
-    switch (pHM->ulRequestType)
-    {
-      /**********
-       * SELECT *
-       **********/
-      case ASYNCREQUEST_SELECT:
-      {
-        dprintf(("WSOCK32:RelayWindowProc, AsyncSelect notification %x %x (%d,%d) time %x\n", pHM->hwnd, pHM->ulMsg, mp1, mp2, WinQueryMsgTime(hab)));
-	if((ULONG)mp2 == 0x20) {
-		DebugInt3();
-	}
-        break;
-      }
-
-
-      /*****************
-       * GETHOSTBYNAME *
-       *****************/
-      case ASYNCREQUEST_GETHOSTBYNAME:
-      {
-        dprintf(("WSOCK32:RelayWindowProc, Converting hostent for "
-                 "WSAAyncGetHostByName\n"));
-
-        /* is there a valid result ? */
-        if (rc == 0)
-        {
-          /* we need to convert the hostent structure here */
-          Whostent *WinHostent             = (Whostent*)pHM->pvUserData1;
-          hostent  *OS2Hostent             = (hostent*)pHM->pvUserData1;
-
-          short    h_addrtype              = (short)OS2Hostent->h_addrtype;
-                   WinHostent->h_addrtype  = h_addrtype;
-          short    h_length                = (short)OS2Hostent->h_length;
-                   WinHostent->h_length    = h_length;
-          char     **h_addr_list           = OS2Hostent->h_addr_list;
-                   WinHostent->h_addr_list = h_addr_list;
-          //TODO: the size of OS/2 hostent is 4 bytes bigger
-          //      so the original buffer *might* be too small
-        }
-        break;
-      }
-
-
-      /*****************
-       * GETHOSTBYADDR *
-       *****************/
-      case ASYNCREQUEST_GETHOSTBYADDR:
-      {
-        dprintf(("WSOCK32:RelayWindowProc, Converting hostent for "
-                 "WSAAyncGetHostByAddr\n"));
-
-        if (rc == 0)
-        {
-          dprintf(("WSOCK32:RelayWindowProc, hostent buffer: %d\n", pHM->pvUserData1));
-          /* we need to convert the hostent structure here */
-          Whostent *WinHostent             = (Whostent*)pHM->pvUserData1;
-          hostent  *OS2Hostent             = (hostent*)pHM->pvUserData1;
-
-          short    h_addrtype              = (short)OS2Hostent->h_addrtype;
-                   WinHostent->h_addrtype  = h_addrtype;
-          short    h_length                = (short)OS2Hostent->h_length;
-                   WinHostent->h_length    = h_length;
-          char     **h_addr_list           = OS2Hostent->h_addr_list;
-                   WinHostent->h_addr_list = h_addr_list;
-          //TODO: the size of OS/2 hostent is 4 bytes bigger
-          //      so the original buffer *might* be too small
-        }
-        break;
-      }
-
-
-      /*****************
-       * GETSERVBYNAME *
-       *****************/
-      case ASYNCREQUEST_GETSERVBYNAME:
-      {
-        dprintf(("WSOCK32:RelayWindowProc, Converting servent for "
-                 "WSAAyncGetServByName\n"));
-
-        if (rc == 0)
-        {
-          /* we need to convert the servent structure here */
-          Wservent *WinServent             = (Wservent*)pHM->pvUserData1;
-          servent  *OS2Servent             = (servent*)pHM->pvUserData1;
-
-          WinServent->s_port  = OS2Servent->s_port;
-          WinServent->s_proto = OS2Servent->s_proto;
-          //TODO: the size of OS/2 servent is 2 bytes bigger
-          //      so the original buffer *might* be too small
-        }
-        break;
-      }
-
-
-      /*****************
-       * GETSERVBYPORT *
-       *****************/
-      case ASYNCREQUEST_GETSERVBYPORT:
-      {
-        dprintf(("WSOCK32:RelayWindowProc, Converting servent for "
-                 "WSAAyncGetServByPort\n"));
-
-        if (rc == 0)
-        {
-          /* we need to convert the servent structure here */
-          Wservent *WinServent             = (Wservent*)pHM->pvUserData1;
-          servent  *OS2Servent             = (servent*)pHM->pvUserData1;
-
-          WinServent->s_port  = OS2Servent->s_port;
-          WinServent->s_proto = OS2Servent->s_proto;
-          //TODO: the size of OS/2 servent is 2 bytes bigger
-          //      so the original buffer *might* be too small
-        }
-        break;
-      }
-
-
-      /******************
-       * GETPROTOBYNAME *
-       ******************/
-      case ASYNCREQUEST_GETPROTOBYNAME:
-      {
-        dprintf(("WSOCK32:RelayWindowProc, Converting protoent for "
-                 "WSAAyncGetProtoByName\n"));
-
-        if (rc == 0)
-        {
-          /* we need to convert the protoent structure here */
-          Wprotoent *WinProtoent             = (Wprotoent*)pHM->pvUserData1;
-          protoent  *OS2Protoent             = (protoent*)pHM->pvUserData1;
-
-          WinProtoent->p_proto = OS2Protoent->p_proto;
-
-          //TODO: the size of OS/2 hostent is 2 bytes bigger
-          //      so the original buffer *might* be too small
-        }
-        break;
-      }
-
-
-      /********************
-       * GETPROTOBYNUMBER *
-       ********************/
-      case ASYNCREQUEST_GETPROTOBYNUMBER:
-      {
-        dprintf(("WSOCK32:RelayWindowProc, Converting protoent for "
-                 "WSAAyncGetProtoByNumber\n"));
-
-        if (rc == 0)
-        {
-          /* we need to convert the protoent structure here */
-          Wprotoent *WinProtoent             = (Wprotoent*)pHM->pvUserData1;
-          protoent  *OS2Protoent             = (protoent*)pHM->pvUserData1;
-
-          WinProtoent->p_proto = OS2Protoent->p_proto;
-
-          //TODO: the size of OS/2 hostent is 2 bytes bigger
-          //      so the original buffer *might* be too small
-        }
-        break;
-      }
-
-      default:
-      {
-        dprintf(("WSOCK32:RelayWindowProc, Unknown request type!!!"
-                 "window: %d, msg: %d, mp1 %d, mp2%d\n", pHM->hwnd,
-                 pHM->ulMsg, mp1, mp2));
-        break;
-      }
-    }
-
-
-//    dprintf(("WSOCK32:RelayWinProc, Posting hwnd=%08xh, msg=%08xh, w=%08xh, l=%08xh\n",
-//             pHM->hwnd,
-//             pHM->ulMsg,
-//             mp1,
-//             mp2));
-
-    PostMessageA(pHM->hwnd,
-                 pHM->ulMsg,
-                 (ULONG)mp1,
-                 (ULONG)mp2);
-
-    // if socket close or non-select call, free entry
-    // @@@PH
-    if (pHM->ulRequestType != ASYNCREQUEST_SELECT)
-    {
-      dprintf(("WSOCK32:RelayWindowProc, Free handle %d\n", pHM->ulMsg));
-      RelayFree(pHM->ulMsg);
-    }
-
-    return FALSE;                                   // OK, message sent
-  } 
-  else
-  {
-    dprintf(("WSOCK32:AsyncRelayWindowProc: Handle not found, message ignored %x %x %x %x", hwnd, ulMsg, mp1, mp2));
-  }
-
-  // default message processing
-  return WinDefWindowProc( hwnd, ulMsg, mp1, mp2 );
-}
-
-
-
-
-#if 0
-/*****************************************************************************
- * Name      :
- * Purpose   :
- * Parameters:
- * Variables :
- * Result    :
- * Remark    :
- * Status    :
- *
- * Author    : Patrick Haller [Tue, 1999/11/30 23:00]
- *****************************************************************************/
-
-HWND RelayInitialize(HWND hwndPost)
-{
-  BOOL       fSuccess;
-  HWND       hwnd;
-
-
-  // thread initialization
-  hab = WinQueryAnchorBlock(hwndPost);
-  if (hab == NULLHANDLE)
-    return NULLHANDLE;
-
-
-  // register relay window class
-  fSuccess = WinRegisterClass(hab,
-                              ODIN_WSOCK_RELAY_CLASS,
-                              (PFNWP)RelayWindowProc,
-                              0,
-                              0);
-  if (fSuccess == FALSE)
-    return NULLHANDLE;
-
-  hwnd = WinCreateWindow(HWND_OBJECT,
-                         ODIN_WSOCK_RELAY_CLASS,
-                         "ODIN WSock Relay",
-                         0, 0, 0, 0, 0,
-                         HWND_OBJECT,
-                         HWND_BOTTOM,
-                         0,
-                         NULL,
-                         NULL );
-
-  //WinDestroyWindow( pg->hwndObject );
-  return hwnd;
-}
-
-#else
-
-/*****************************************************************************
- * Name      :
- * Purpose   :
- * Parameters:
- * Variables :
- * Result    :
- * Remark    :
- * Status    :
- *
- * Author    : Patrick Haller [Tue, 1999/11/30 23:00]
- *****************************************************************************/
-
-
-//----------------------------------------------------------------------
-// thread 2 entry point: gets and dispatches object window messages
-// _Optlink is an IBM C Set/2 function modifier
-void _Optlink RelayThreadMain(PVOID pParameter)
-{
-  BOOL       fSuccess;
-  HAB        hab;
-  HMQ        hmq;
-  QMSG       qmsg;
-
-  // thread initialization
-  hab = WinInitialize( 0 );
-  hmq = WinCreateMsgQueue( hab, 0 );
-
-  // prevent system from posting object window a WM_QUIT
-  // I'll post WM_QUIT when it's time.
-  fSuccess = WinCancelShutdown( hmq, TRUE );
-  if (fSuccess != TRUE)
-  {
-    dprintf(("WSOCK32:RelayWin: ERROR WinCancelShutdown failed\n"));
-    return;
-  }
-
-  // register relay window class
-  fSuccess = WinRegisterClass(hab,
-                              ODIN_WSOCK_RELAY_CLASS,
-                              (PFNWP)RelayWindowProc,
-                              0,
-                              0);
-  if (fSuccess == FALSE)
-  {
-    dprintf(("WSOCK32:RelayWin: ERROR WinRegisterClass failed\n"));
-    return;
-  }
-
-  hwndRelay = WinCreateWindow(HWND_OBJECT,
-                         ODIN_WSOCK_RELAY_CLASS,
-                         "ODIN WSock Relay",
-                         0, 0, 0, 0, 0,
-                         HWND_OBJECT,
-                         HWND_BOTTOM,
-                         0,
-                         NULL,
-                         NULL );
-  if (hwndRelay == NULLHANDLE)
-  {
-    dprintf(("WSOCK32:RelayWin: ERROR WinCreateWindow failed\n"));
-    return;
-  }
-
-  // get/dispatch messages; user messages, for the most part
-  while( WinGetMsg ( hab, &qmsg, 0, 0, 0 ))
-  {
-    WinDispatchMsg ( hab, &qmsg );
-  }
-
-  // clean up
-  WinDestroyWindow( hwndRelay );
-  WinDestroyMsgQueue( hmq );
-  WinTerminate( hab );
-
-  // reset relay window handle
-  hwndRelay = NULLHANDLE;
-  return;
-}
-
-
-/*****************************************************************************
- * Name      :
- * Purpose   :
- * Parameters:
- * Variables :
- * Result    :
- * Remark    :
- * Status    :
- *
- * Author    : Patrick Haller [Tue, 1999/11/30 23:00]
- *****************************************************************************/
-
-HWND RelayInitialize(HWND hwndPost)
-{
-  int tidRelay;  // thread identifier
-
-  if (hwndRelay != NULLHANDLE)
-  {
-    // relay thread has been initialized
-    return hwndRelay;
-  }
-
-  // else create new subsystem
-    // create thread
-#if defined(__IBMCPP__)
-    tidRelay  = _beginthread(RelayThreadMain,
-                             NULL,
-                             16384,
-                             (PVOID)0);
-#else
-    tidRelay  = _beginthread(RelayThreadMain,
-                             16384,
-                             (PVOID)0);
-#endif
-
-  // wait for thread to come up and send valid HWND
-  // @@@PH this is an ugly hack
-  dprintf(("WSOCK32:RELAYWIN:RelayInitialize wait for window handle\n"));
-  while (hwndRelay == NULL)
-  {
-    DosSleep(10);
-  }
-  dprintf(("WSOCK32:RELAYWIN:RelayInitialize window handle = %08xh",
-            hwndRelay));
-
-  return hwndRelay;
-}
-
-#endif
-
-
-/*****************************************************************************
- * Name      :
- * Purpose   :
- * Parameters:
- * Variables :
- * Result    :
- * Remark    :
- * Status    :
- *
- * Author    : Patrick Haller [Tue, 1999/11/30 23:00]
- *****************************************************************************/
-
-BOOL RelayTerminate(HWND hwndRelay)
-{
-  return WinDestroyWindow(hwndRelay);
-}
-
Index: trunk/src/wsock32/relaywin.h
===================================================================
--- trunk/src/wsock32/relaywin.h	(revision 3228)
+++ 	(revision )
@@ -1,89 +1,0 @@
-/* $Id: relaywin.h,v 1.4 2000-03-22 20:07:24 sandervl Exp $ */
-
-/*
- *
- * Project Odin Software License can be found in LICENSE.TXT
- *
- * Win32 SOCK32 for OS/2
- *
- * Copyright (C) 1999 Patrick Haller <phaller@gmx.net>
- *
- */
-
-/* Remark:
- * - this is an object window that acts as "relay", this is
- *   it receives WSAAsyncSelect()'s messages and redirects
- *   them to the appropriate PostMessageA function of USER32.
- */
-
-
-#ifndef _RELAYWIN_H_
-#define _RELAYWIN_H_
-
-
-/*****************************************************************************
- * Includes                                                                  *
- *****************************************************************************/
-
-/* object.c: the object window procedure on thread 2  */
-// os2 includes
-#define INCL_DOSPROCESS
-#define INCL_WIN
-#include <os2.h>
-
-/*****************************************************************************
- * Structures                                                                *
- *****************************************************************************/
-
-/* these are the request types so we can interpret the messages and convert the results */
-
-#define  ASYNCREQUEST_GETHOSTBYNAME     100
-#define  ASYNCREQUEST_GETHOSTBYADDR     101
-#define  ASYNCREQUEST_GETSERVBYNAME     102
-#define  ASYNCREQUEST_GETSERVBYPORT     103
-#define  ASYNCREQUEST_GETPROTOBYNAME    104
-#define  ASYNCREQUEST_GETPROTOBYNUMBER  105
-#define  ASYNCREQUEST_SELECT            106
-
-
-typedef struct tagHwndMsgPair
-{
-  HWND  hwnd;  /* target window            */
-  ULONG ulMsg; /* the message code to send */
-  ULONG ulRequestType; /* the type of request that this belongs to */
-  PVOID pvUserData1; /* request specific data field */
-  PVOID pvUserData2; /* request specific data field */
-  PVOID pvUserData3; /* request specific data field */
-} HWNDMSGPAIR, *PHWNDMSGPAIR;
-
-
-/*****************************************************************************
- * Prototypes                                                                *
- *****************************************************************************/
-
-ULONG            RelayAlloc     (HWND  hwnd,
-                                 ULONG ulMsg, 
-                                 ULONG ulRequestType,
-                                 BOOL  fSingleRequestPerWindow,
-                                 PVOID pvUserData1 = 0, 
-                                 PVOID pvUserData2 = 0,
-                                 PVOID pvUserData3 = 0);
-
-ULONG            RelayFree      (ULONG ulID);
-
-ULONG            RelayFreeByHwnd(HWND  hwnd);
-
-PHWNDMSGPAIR     RelayQuery     (ULONG ulID);
-
-MRESULT EXPENTRY RelayWindowProc(HWND   hwnd,
-                                 ULONG  ulMsg, 
-                                 MPARAM mp1, 
-                                 MPARAM mp2);
-
-HWND             RelayInitialize(HWND  hwndPost);
-
-BOOL             RelayTerminate (HWND  hwndRelay);
-
-
-#endif /* _RELAYWIN_H_ */
-
Index: trunk/src/wsock32/unknown.cpp
===================================================================
--- trunk/src/wsock32/unknown.cpp	(revision 3228)
+++ trunk/src/wsock32/unknown.cpp	(revision 3229)
@@ -1,3 +1,3 @@
-/* $Id: unknown.cpp,v 1.6 2000-03-22 20:07:25 sandervl Exp $ */
+/* $Id: unknown.cpp,v 1.7 2000-03-24 19:28:08 sandervl Exp $ */
 
 /*
@@ -15,4 +15,5 @@
 #include <misc.h>
 #include <odinwrap.h>
+#include "wsock32.h"
 
 #define DBG_LOCALLOG	DBG_unknown
@@ -20,14 +21,4 @@
 
 ODINDEBUGCHANNEL(WSOCK32-UNKNOWN)
-
-/*****************************************************************************
- * Prototypes & Types & Defines                                              *
- *****************************************************************************/
-
-typedef int SOCKET;
-
-int _System rexec(char **, int, char *, char *, char *, int *);
-int _System rcmd (char **, int, const char *, const char *, const char *, int *);
-
 
 /*****************************************************************************
@@ -107,5 +98,5 @@
  *****************************************************************************/
 
-ODINFUNCTION4(int, OS2WSARecvEx, SOCKET,    s,
+ODINFUNCTION4(int, WSARecvEx, SOCKET,    s,
                                  char FAR*, buf,
                                  int,       len,
Index: trunk/src/wsock32/wsa.cpp
===================================================================
--- trunk/src/wsock32/wsa.cpp	(revision 3229)
+++ trunk/src/wsock32/wsa.cpp	(revision 3229)
@@ -0,0 +1,260 @@
+/* $Id: wsa.cpp,v 1.3 2000-03-24 19:28:08 sandervl Exp $ */
+
+/*
+ *
+ * Win32 SOCK32 for OS/2 (WSA apis)
+ *
+ * Copyright (C) 2000 Sander van Leeuwen (sandervl@xs4all.nl)
+ *
+ * Based on Wine code: (dlls\winsock\async.c,socket.c)
+ * (C) 1993,1994,1996,1997 John Brezak, Erik Bos, Alex Korobka.
+ * (C) 1999 Marcus Meissner
+ *
+ * Project Odin Software License can be found in LICENSE.TXT
+ *
+ */
+#define INCL_BASE
+#include <os2wrap.h>
+#include <stdio.h>
+#include <string.h>
+#include <odin.h>
+#include <odinwrap.h>
+#include <os2sel.h>
+#include <misc.h>
+#include <win32api.h>
+
+#include "wsock32.h"
+#include "asyncthread.h"
+
+#define DBG_LOCALLOG	DBG_wsa
+#include "dbglocal.h"
+
+ODINDEBUGCHANNEL(WSOCK32-WSA)
+
+#ifndef winsockcleanupsockets
+// Exported by SO32DLL.  Used to close all open sockets.
+void _System winsockcleanupsockets(void);
+#endif
+
+static void WSASetBlocking(BOOL fBlock);
+
+BOOL fWSAInitialized = FALSE;
+
+//******************************************************************************
+WSADATA WINSOCK_data = { 0x0101, 0x0101,
+                        "Odin Sockets 1.1", "OS/2",
+		         WS_MAX_SOCKETS_PER_PROCESS,
+		         WS_MAX_UDP_DATAGRAM, NULL };
+//******************************************************************************
+ODINFUNCTION2(int, WSAStartup,
+              USHORT,wVersionRequested,
+              LPWSADATA,lpWSAData)
+{
+    LPWSINFO            pwsi;
+
+    if (LOBYTE(wVersionRequested) < 1 || (LOBYTE(wVersionRequested) == 1 &&
+        HIBYTE(wVersionRequested) < 1)) return WSAVERNOTSUPPORTED;
+
+    if (!lpWSAData) return WSAEINVAL;
+
+    if(fWSAInitialized == FALSE) 
+    {
+        WINSOCK_CreateIData();
+        pwsi = WINSOCK_GetIData();
+
+    	sock_init();
+    }
+    else pwsi = WINSOCK_GetIData();
+
+    if (!pwsi) return WSASYSNOTREADY;
+
+    pwsi->num_startup++;
+    fWSAInitialized = TRUE;
+
+    /* return winsock information */
+    memcpy(lpWSAData, &WINSOCK_data, sizeof(WINSOCK_data));
+
+    return 0;
+}
+//******************************************************************************
+//******************************************************************************
+ODINFUNCTION0(int,WSACleanup)
+{
+    LPWSINFO pwsi = WINSOCK_GetIData();
+    if( pwsi ) {
+	if( --pwsi->num_startup > 0 ) return 0;
+
+        winsockcleanupsockets();
+
+	fWSAInitialized = FALSE;
+	WINSOCK_DeleteIData();
+	return 0;
+    }
+    SetLastError(WSANOTINITIALISED);
+    return SOCKET_ERROR;
+}
+//******************************************************************************
+//TODO: Implement this
+//******************************************************************************
+ODINFUNCTION1(FARPROC,WSASetBlockingHook,
+              FARPROC,lpBlockFunc)
+{
+  FARPROC             prev;
+  LPWSINFO            pwsi = WINSOCK_GetIData();
+
+  if( pwsi ) {
+      prev = (FARPROC)pwsi->blocking_hook;
+      pwsi->blocking_hook = (DWORD)lpBlockFunc;
+      pwsi->flags |= WSI_BLOCKINGHOOK;
+      return prev;
+  }
+  return NULL;
+}
+//******************************************************************************
+//TODO: Implement this
+//******************************************************************************
+ODINFUNCTION0(int,WSAUnhookBlockingHook)
+{
+    LPWSINFO pwsi = WINSOCK_GetIData();
+
+    if( pwsi )
+    {
+	pwsi->blocking_hook = 0;
+	pwsi->flags &= ~WSI_BLOCKINGHOOK;
+	return 0;
+    }
+    return SOCKET_ERROR;
+}
+//******************************************************************************
+//******************************************************************************
+BOOL WIN32API WSAIsBlocking()
+{
+    LPWSINFO pwsi = WINSOCK_GetIData();
+
+    if( pwsi )
+    {
+      	return (pwsi->flags & WSI_BLOCKINGCALL) == WSI_BLOCKINGCALL;
+    }
+    DebugInt3();
+    return FALSE; //shouldn't happen
+}
+//******************************************************************************
+//******************************************************************************
+void WSASetBlocking(BOOL fBlock, HANDLE tid) 
+{
+    LPWSINFO pwsi = WINSOCK_GetIData(tid);
+
+    if( pwsi )
+    {
+	if(fBlock) {
+      		pwsi->flags |= WSI_BLOCKINGCALL;
+	}
+	else	pwsi->flags &= ~WSI_BLOCKINGCALL;
+	return;
+    }
+    DebugInt3();
+}
+//******************************************************************************
+//******************************************************************************
+ODINFUNCTION2(int,__WSAFDIsSet,SOCKET, s,
+                                  ws_fd_set*,set)
+{
+  int i = set->fd_count;
+    
+  while (i--)
+      if (set->fd_array[i] == s) return 1;
+
+  return 0;
+}
+//******************************************************************************
+//******************************************************************************
+UINT wsaErrno()
+{
+ int loc_errno = sock_errno();
+
+    switch(loc_errno)
+    {
+	case SOCEINTR:		return WSAEINTR;
+	case SOCEBADF:		return WSAEBADF;
+	case SOCEPERM:
+	case SOCEACCES:		return WSAEACCES;
+	case SOCEFAULT:		return WSAEFAULT;
+	case SOCEINVAL:		return WSAEINVAL;
+	case SOCEMFILE:		return WSAEMFILE;
+	case SOCEWOULDBLOCK:	return WSAEWOULDBLOCK;
+	case SOCEINPROGRESS:	return WSAEINPROGRESS;
+	case SOCEALREADY:	return WSAEALREADY;
+	case SOCENOTSOCK:	return WSAENOTSOCK;
+	case SOCEDESTADDRREQ:	return WSAEDESTADDRREQ;
+	case SOCEMSGSIZE:	return WSAEMSGSIZE;
+	case SOCEPROTOTYPE:	return WSAEPROTOTYPE;
+	case SOCENOPROTOOPT:	return WSAENOPROTOOPT;
+	case SOCEPROTONOSUPPORT:return WSAEPROTONOSUPPORT;
+	case SOCESOCKTNOSUPPORT:return WSAESOCKTNOSUPPORT;
+	case SOCEOPNOTSUPP:	return WSAEOPNOTSUPP;
+	case SOCEPFNOSUPPORT:	return WSAEPFNOSUPPORT;
+	case SOCEAFNOSUPPORT:	return WSAEAFNOSUPPORT;
+	case SOCEADDRINUSE:	return WSAEADDRINUSE;
+	case SOCEADDRNOTAVAIL:	return WSAEADDRNOTAVAIL;
+	case SOCENETDOWN:	return WSAENETDOWN;
+	case SOCENETUNREACH:	return WSAENETUNREACH;
+	case SOCENETRESET:	return WSAENETRESET;
+	case SOCECONNABORTED:	return WSAECONNABORTED;
+	case SOCEPIPE:	
+	case SOCECONNRESET:	return WSAECONNRESET;
+	case SOCENOBUFS:	return WSAENOBUFS;
+	case SOCEISCONN:	return WSAEISCONN;
+	case SOCENOTCONN:	return WSAENOTCONN;
+	case SOCESHUTDOWN:	return WSAESHUTDOWN;
+	case SOCETOOMANYREFS:	return WSAETOOMANYREFS;
+	case SOCETIMEDOUT:	return WSAETIMEDOUT;
+	case SOCECONNREFUSED:	return WSAECONNREFUSED;
+	case SOCELOOP:		return WSAELOOP;
+	case SOCENAMETOOLONG:	return WSAENAMETOOLONG;
+	case SOCEHOSTDOWN:	return WSAEHOSTDOWN;
+	case SOCEHOSTUNREACH:	return WSAEHOSTUNREACH;
+	case SOCENOTEMPTY:	return WSAENOTEMPTY;
+#ifdef EPROCLIM
+	case SOCEPROCLIM:	return WSAEPROCLIM;
+#endif
+#ifdef EUSERS
+	case SOCEUSERS:		return WSAEUSERS;
+#endif
+#ifdef EDQUOT
+	case SOCEDQUOT:		return WSAEDQUOT;
+#endif
+#ifdef ESTALE
+	case SOCESTALE:		return WSAESTALE;
+#endif
+#ifdef EREMOTE
+	case SOCEREMOTE:	return WSAEREMOTE;
+#endif
+
+        /* just in case we ever get here and there are no problems */
+	case 0:			return 0;
+        default:
+		dprintf(("Unknown errno %d!\n", loc_errno));
+		return WSAEOPNOTSUPP;
+    }
+}
+//******************************************************************************
+//******************************************************************************
+UINT wsaHerrno()
+{
+    int loc_errno = h_errno;
+
+    switch(loc_errno)
+    {
+	case HOST_NOT_FOUND:	return WSAHOST_NOT_FOUND;
+	case TRY_AGAIN:		return WSATRY_AGAIN;
+	case NO_RECOVERY:	return WSANO_RECOVERY;
+	case NO_DATA:		return WSANO_DATA; 
+
+	case 0:			return 0;
+        default:
+		dprintf(("Unknown h_errno %d!\n", loc_errno));
+		return WSAEOPNOTSUPP;
+    }
+}
+//******************************************************************************
+//******************************************************************************
Index: trunk/src/wsock32/wsastruct.cpp
===================================================================
--- trunk/src/wsock32/wsastruct.cpp	(revision 3229)
+++ trunk/src/wsock32/wsastruct.cpp	(revision 3229)
@@ -0,0 +1,311 @@
+/* $Id: wsastruct.cpp,v 1.3 2000-03-24 19:28:08 sandervl Exp $ */
+
+/*
+ *
+ * Win32 SOCK32 for OS/2 (WSA apis)
+ *
+ * Based on Wine code: (dlls\winsock\async.c,socket.c)
+ * (C) 1993,1994,1996,1997 John Brezak, Erik Bos, Alex Korobka.
+ * (C) 1999 Marcus Meissner
+ *
+ * Project Odin Software License can be found in LICENSE.TXT
+ *
+ */
+
+/* ----------------------------------- helper functions -
+ *
+ * TODO: Merge WS_dup_..() stuff into one function that
+ * would operate with a generic structure containing internal
+ * pointers (via a template of some kind).
+ */
+
+#define INCL_BASE
+#include <os2wrap.h>	//Odin32 OS/2 api wrappers
+
+#include <string.h>
+#include <odinwrap.h>
+#include <os2sel.h>
+#include <stdlib.h>
+#include <win32api.h>
+#include <misc.h>
+
+#include "wsock32.h"
+#include "wsastruct.h"
+
+struct ws_hostent* _check_buffer_he(LPWSINFO pwsi, int size)
+{
+    if( pwsi->he && pwsi->helen >= size ) return pwsi->he;
+    else free(pwsi->he);
+
+    pwsi->he = (struct ws_hostent*)malloc((pwsi->helen = size)); 
+    return pwsi->he;
+}
+
+struct ws_servent* _check_buffer_se(LPWSINFO pwsi, int size)
+{
+    if( pwsi->se && pwsi->selen >= size ) return pwsi->se;
+    else free(pwsi->se);
+
+    pwsi->se = (struct ws_servent*)malloc((pwsi->selen = size)); 
+    return pwsi->se;
+}
+
+struct ws_protoent* _check_buffer_pe(LPWSINFO pwsi, int size)
+{
+    if( pwsi->pe && pwsi->pelen >= size ) return pwsi->pe;
+    else free(pwsi->pe);
+
+    pwsi->pe = (struct ws_protoent*)malloc((pwsi->pelen = size)); 
+    return pwsi->pe;
+}
+
+static int list_size(char** l, int item_size)
+{
+  int i,j = 0;
+  if(l)
+  { for(i=0;l[i];i++) 
+	j += (item_size) ? item_size : strlen(l[i]) + 1;
+    j += (i + 1) * sizeof(char*); }
+  return j;
+}
+
+static int list_dup(char** l_src, char* ref, char* base, int item_size)
+{ 
+   /* base is either either equal to ref or 0 or SEGPTR */
+
+   char*		p = ref;
+   char**		l_to = (char**)ref;
+   int			i,j,k;
+
+   for(j=0;l_src[j];j++) ;
+   p += (j + 1) * sizeof(char*);
+   for(i=0;i<j;i++)
+   { l_to[i] = base + (p - ref);
+     k = ( item_size ) ? item_size : strlen(l_src[i]) + 1;
+     memcpy(p, l_src[i], k); p += k; }
+   l_to[i] = NULL;
+   return (p - ref);
+}
+
+/* ----- hostent */
+
+static int hostent_size(struct hostent* p_he)
+{
+  int size = 0;
+  if( p_he )
+  { size  = sizeof(struct hostent); 
+    size += strlen(p_he->h_name) + 1;
+    size += list_size(p_he->h_aliases, 0);  
+    size += list_size(p_he->h_addr_list, p_he->h_length ); }
+  return size;
+}
+
+int WS_dup_he(LPWSINFO pwsi, struct hostent* p_he, int flag)
+{
+   /* Convert hostent structure into ws_hostent so that the data fits 
+    * into pwsi->buffer. Internal pointers can be linear, SEGPTR, or 
+    * relative to pwsi->buffer depending on "flag" value. Returns size
+    * of the data copied (also in the pwsi->buflen).
+    */
+
+   int size = hostent_size(p_he);
+
+   if( size )
+   {
+     struct ws_hostent* p_to;
+     char* p_name,*p_aliases,*p_addr,*p_base,*p;
+
+     _check_buffer_he(pwsi, size);
+     p_to = (struct ws_hostent*)pwsi->he;
+     p = (char*)pwsi->he;
+     p_base = (flag & WS_DUP_OFFSET) ? NULL : p;
+////				     : ((flag & WS_DUP_SEGPTR) ? (char*)SEGPTR_GET(p) : p);
+     p += sizeof(struct ws_hostent);
+     p_name = p;
+     strcpy(p, p_he->h_name); p += strlen(p) + 1;
+     p_aliases = p;
+     p += list_dup(p_he->h_aliases, p, p_base + (p - (char*)pwsi->he), 0);
+     p_addr = p;
+     list_dup(p_he->h_addr_list, p, p_base + (p - (char*)pwsi->he), p_he->h_length);
+
+     p_to->h_addrtype = (INT16)p_he->h_addrtype; 
+     p_to->h_length = (INT16)p_he->h_length;
+     p_to->h_name = (char *)(p_base + (p_name - (char*)pwsi->he));
+     p_to->h_aliases = (char **)(p_base + (p_aliases - (char*)pwsi->he));
+     p_to->h_addr_list = (char **)(p_base + (p_addr - (char*)pwsi->he));
+
+     size += (sizeof(struct ws_hostent) - sizeof(struct hostent));
+   }
+   return size;
+}
+
+/* ----- protoent */
+
+static int protoent_size(struct protoent* p_pe)
+{
+  int size = 0;
+  if( p_pe )
+  { size  = sizeof(struct protoent);
+    size += strlen(p_pe->p_name) + 1;
+    size += list_size(p_pe->p_aliases, 0); }
+  return size;
+}
+
+int WS_dup_pe(LPWSINFO pwsi, struct protoent* p_pe, int flag)
+{
+   int size = protoent_size(p_pe);
+   if( size )
+   {
+     struct ws_protoent* p_to;
+     char* p_name,*p_aliases,*p_base,*p;
+
+     _check_buffer_pe(pwsi, size);
+     p_to = (struct ws_protoent*)pwsi->pe;
+     p = (char*)pwsi->pe; 
+     p_base = (flag & WS_DUP_OFFSET) ? NULL : p;
+////				     : ((flag & WS_DUP_SEGPTR) ? (char*)SEGPTR_GET(p) : p);
+     p += sizeof(struct ws_protoent);
+     p_name = p;
+     strcpy(p, p_pe->p_name); p += strlen(p) + 1;
+     p_aliases = p;
+     list_dup(p_pe->p_aliases, p, p_base + (p - (char*)pwsi->pe), 0);
+
+     p_to->p_proto = (INT16)p_pe->p_proto;
+     p_to->p_name = (char *)(p_base) + (p_name - (char*)pwsi->pe);
+     p_to->p_aliases = (char **)((p_base) + (p_aliases - (char*)pwsi->pe)); 
+
+     size += (sizeof(struct ws_protoent) - sizeof(struct protoent));
+   }
+   return size;
+}
+
+/* ----- servent */
+
+static int servent_size(struct servent* p_se)
+{
+  int size = 0;
+  if( p_se )
+  { size += sizeof(struct servent);
+    size += strlen(p_se->s_proto) + strlen(p_se->s_name) + 2;
+    size += list_size(p_se->s_aliases, 0); }
+  return size;
+}
+
+int WS_dup_se(LPWSINFO pwsi, struct servent* p_se, int flag)
+{
+   int size = servent_size(p_se);
+   if( size )
+   {
+     struct ws_servent* p_to;
+     char* p_name,*p_aliases,*p_proto,*p_base,*p;
+
+     _check_buffer_se(pwsi, size);
+     p_to = (struct ws_servent*)pwsi->se;
+     p = (char*)pwsi->se;
+     p_base = (flag & WS_DUP_OFFSET) ? NULL : p;
+////				     : ((flag & WS_DUP_SEGPTR) ? (char*)SEGPTR_GET(p) : p);
+     p += sizeof(struct ws_servent);
+     p_name = p;
+     strcpy(p, p_se->s_name); p += strlen(p) + 1;
+     p_proto = p;
+     strcpy(p, p_se->s_proto); p += strlen(p) + 1;
+     p_aliases = p;
+     list_dup(p_se->s_aliases, p, p_base + (p - (char*)pwsi->se), 0);
+
+     p_to->s_port = (INT16)p_se->s_port;
+     p_to->s_name = (char *)(p_base + (p_name - (char*)pwsi->se));
+     p_to->s_proto = (char *)(p_base + (p_proto - (char*)pwsi->se));
+     p_to->s_aliases = (char **)(p_base + (p_aliases - (char*)pwsi->se)); 
+
+     size += (sizeof(struct ws_servent) - sizeof(struct servent));
+   }
+   return size;
+}
+/* ----------------------------------- helper functions - */
+
+
+/* ----- hostent */
+
+/* Copy hostent to p_to, fix up inside pointers using p_base (different for
+ * Win16 (linear vs. segmented). Return -neededsize on overrun.
+ */
+int WS_copy_he(struct ws_hostent *p_to,char *p_base,int t_size,struct hostent* p_he)
+{
+	char* p_name,*p_aliases,*p_addr,*p;
+	int	size=hostent_size(p_he)+(sizeof(struct ws_hostent)-sizeof(struct hostent));
+
+	if (t_size < size)
+		return -size;
+	p = (char*)p_to;
+	p += sizeof(struct ws_hostent);
+	p_name = p;
+	strcpy(p, p_he->h_name); p += strlen(p) + 1;
+	p_aliases = p;
+	p += list_dup(p_he->h_aliases, p, p_base + (p - (char*)p_to), 0);
+	p_addr = p;
+	list_dup(p_he->h_addr_list, p, p_base + (p - (char*)p_to), p_he->h_length);
+
+	p_to->h_addrtype = (INT16)p_he->h_addrtype; 
+	p_to->h_length = (INT16)p_he->h_length;
+	p_to->h_name = (p_base + (p_name - (char*)p_to));
+	p_to->h_aliases = (char **)(p_base + (p_aliases - (char*)p_to));
+	p_to->h_addr_list = (char **)(p_base + (p_addr - (char*)p_to));
+
+	return size;
+}
+
+/* ----- protoent */
+
+/* Copy protoent to p_to, fix up inside pointers using p_base (different for
+ * Win16 (linear vs. segmented). Return -neededsize on overrun.
+ */
+int WS_copy_pe(struct ws_protoent *p_to,char *p_base,int t_size,struct protoent* p_pe)
+{
+	char* p_name,*p_aliases,*p;
+	int	size=protoent_size(p_pe)+(sizeof(struct ws_protoent)-sizeof(struct protoent));
+
+	if (t_size < size)
+		return -size;
+	p = (char*)p_to;
+	p += sizeof(struct ws_protoent);
+	p_name = p;
+	strcpy(p, p_pe->p_name); p += strlen(p) + 1;
+	p_aliases = p;
+	list_dup(p_pe->p_aliases, p, p_base + (p - (char*)p_to), 0);
+
+	p_to->p_proto = (INT16)p_pe->p_proto;
+	p_to->p_name = (p_base) + (p_name - (char*)p_to);
+	p_to->p_aliases = (char **)((p_base) + (p_aliases - (char*)p_to)); 
+
+
+	return size;
+}
+
+/* ----- servent */
+
+/* Copy servent to p_to, fix up inside pointers using p_base (different for
+ * Win16 (linear vs. segmented). Return -neededsize on overrun.
+ */
+int WS_copy_se(struct ws_servent *p_to, char *p_base, int t_size, struct servent* p_se)
+{
+	char* p_name,*p_aliases,*p_proto,*p;
+	int	size = servent_size(p_se)+(sizeof(struct ws_servent)-sizeof(struct servent));
+
+	if (t_size < size )
+		return -size;
+	p = (char*)p_to;
+	p += sizeof(struct ws_servent);
+	p_name = p;
+	strcpy(p, p_se->s_name); p += strlen(p) + 1;
+	p_proto = p;
+	strcpy(p, p_se->s_proto); p += strlen(p) + 1;
+	p_aliases = p;
+	list_dup(p_se->s_aliases, p, p_base + (p - (char*)p_to), 0);
+
+	p_to->s_port = (INT16)p_se->s_port;
+	p_to->s_name = (p_base + (p_name - (char*)p_to));
+	p_to->s_proto = (p_base + (p_proto - (char*)p_to));
+	p_to->s_aliases = (char **)(p_base + (p_aliases - (char*)p_to)); 
+
+	return size;
+}
Index: trunk/src/wsock32/wsastruct.h
===================================================================
--- trunk/src/wsock32/wsastruct.h	(revision 3229)
+++ trunk/src/wsock32/wsastruct.h	(revision 3229)
@@ -0,0 +1,28 @@
+/* $Id: wsastruct.h,v 1.3 2000-03-24 19:28:09 sandervl Exp $ */
+
+/*
+ *
+ * Win32 SOCK32 for OS/2
+ *
+ * Project Odin Software License can be found in LICENSE.TXT
+ *
+ */
+#ifndef __WSASTRUCT_H__
+#define __WSASTRUCT_H__
+
+#include "wsock32.h"
+
+#define WS_DUP_LINEAR           0x0001
+#define WS_DUP_NATIVE           0x0000          /* not used anymore */
+#define WS_DUP_OFFSET           0x0002          /* internal pointers are offsets */
+#define WS_DUP_SEGPTR           0x0004          /* internal pointers are SEGPTRs */
+
+int WS_copy_se(struct ws_servent *p_to, char *p_base, int t_size, struct servent* p_se);
+int WS_copy_pe(struct ws_protoent *p_to,char *p_base,int t_size,struct protoent* p_pe);
+int WS_copy_he(struct ws_hostent *p_to,char *p_base,int t_size,struct hostent* p_he);
+int WS_dup_se(LPWSINFO pwsi, struct servent* p_se, int flag = WS_DUP_LINEAR);
+int WS_dup_pe(LPWSINFO pwsi, struct protoent* p_pe, int flag = WS_DUP_LINEAR);
+int WS_dup_he(LPWSINFO pwsi, struct hostent* p_he, int flag = WS_DUP_LINEAR);
+
+
+#endif //__WSASTRUCT_H__
Index: trunk/src/wsock32/wsock32.cpp
===================================================================
--- trunk/src/wsock32/wsock32.cpp	(revision 3228)
+++ trunk/src/wsock32/wsock32.cpp	(revision 3229)
@@ -1,3 +1,3 @@
-/* $Id: wsock32.cpp,v 1.23 2000-03-22 20:07:28 sandervl Exp $ */
+/* $Id: wsock32.cpp,v 1.24 2000-03-24 19:28:09 sandervl Exp $ */
 
 /*
@@ -8,4 +8,8 @@
  *
  * Copyright (C) 1999 Patrick Haller <phaller@gmx.net>
+ * Copyright (C) 2000 Sander van Leeuwen (sandervl@xs4all.nl)
+ *
+ * Some parts based on Wine code: (dlls\winsock\socket.c)
+ * (C) 1993,1994,1996,1997 John Brezak, Erik Bos, Alex Korobka.
  *
  */
@@ -17,4 +21,6 @@
  *            -> open issue: WSASetLastError / WSAGetLastError
  *               call SetLastError / GetLastError according to docs
+ *
+ * 2000/22/03 Complete rewrite -> got rid of pmwsock
  *
  * identical structures:
@@ -38,17 +44,20 @@
  *****************************************************************************/
 
-#include <pmwsock.h>
-#include <odin.h>
+#define INCL_BASE
+#include <os2wrap.h>	//Odin32 OS/2 api wrappers
+
+#include <string.h>
 #include <odinwrap.h>
 #include <os2sel.h>
-#include <misc.h>
-#include <wprocess.h>
-#include <heapstring.h>
-#include <win32wnd.h>
 #include <stdlib.h>
 #include <win32api.h>
+#include <win32wnd.h>
+#include <wprocess.h>
+#include <misc.h>
 
 #include "wsock32.h"
-#include "relaywin.h"
+#include "wsastruct.h"
+#include "asyncthread.h"
+
 #define DBG_LOCALLOG	DBG_wsock32
 #include "dbglocal.h"
@@ -62,231 +71,419 @@
  *****************************************************************************/
 
-#define ERROR_SUCCESS 0
-
-
-static WSOCKTHREADDATA wstdFallthru; // for emergency only
-
-static HWND hwndRelay = NULL; // handle to our relay window
-
-BOOL fWSAInitialized = FALSE;
-
-/*****************************************************************************
- * Prototypes                                                                *
- *****************************************************************************/
-
-/*****************************************************************************
- * Name      :
- * Purpose   :
- * Parameters:
- * Variables :
- * Result    :
- * Remark    : free memory when thread dies
- * Status    : UNTESTED STUB
- *
- * Author    : Patrick Haller [Tue, 1998/06/16 23:00]
- *****************************************************************************/
-
-PWSOCKTHREADDATA iQueryWsockThreadData(void)
-{
-  struct _THDB*     pThreadDB = (struct _THDB*)GetThreadTHDB();
-  PWSOCKTHREADDATA pwstd;
-
-  // check for existing pointer
-  if (pThreadDB != NULL)
-  {
-    if (pThreadDB->pWsockData == NULL)
-    {
-      // allocate on demand + initialize
-      pwstd = (PWSOCKTHREADDATA)HEAP_malloc (sizeof(WSOCKTHREADDATA));
-      pThreadDB->pWsockData = (LPVOID)pwstd;
+static LPWSINFO lpFirstIData = NULL;
+
+//******************************************************************************
+//******************************************************************************
+LPWSINFO WINSOCK_GetIData(HANDLE tid)
+{
+    LPWSINFO iData;
+    BOOL     fCurrentThread = FALSE;
+
+    if(tid == CURRENT_THREAD) {
+	tid = GetCurrentThread();
+	fCurrentThread = TRUE;
     }
-    else
-      // use already allocated memory
-      pwstd = (PWSOCKTHREADDATA)pThreadDB->pWsockData;
-  }
-
-  if (pwstd == NULL)
-    pwstd = &wstdFallthru; // no memory and not allocated already
-
-  return pwstd;
-}
-
-
-#if 0
-/*****************************************************************************
- * Name      :
- * Purpose   :
- * Parameters:
- * Variables :
- * Result    :
- * Remark    :
- * Status    : UNTESTED STUB
- *
- * Author    : Patrick Haller [Thu, 1999/11/25 23:00]
- *****************************************************************************/
-
-#define CASEERR2(a) case SOC##a: case a: return WSA##a;
-#define CASEERR1(a) case SOC##a: return WSA##a;
-
-int iTranslateSockErrToWSock(int iError)
-{
-  switch(iError)
-  {
-    CASEERR2(EINTR)
-    CASEERR2(EBADF)
-    CASEERR2(EACCES)
-    CASEERR2(EINVAL)
-    CASEERR2(EMFILE)
-
-    CASEERR1(EWOULDBLOCK)
-    CASEERR1(EINPROGRESS)
-    CASEERR1(EALREADY)
-    CASEERR1(ENOTSOCK)
-//  CASEERR1(EDESTADRREQ)
-    CASEERR1(EMSGSIZE)
-    CASEERR1(EPROTOTYPE)
-    CASEERR1(ENOPROTOOPT)
-    CASEERR1(EPROTONOSUPPORT)
-    CASEERR1(ESOCKTNOSUPPORT)
-    CASEERR1(EOPNOTSUPP)
-    CASEERR1(EPFNOSUPPORT)
-    CASEERR1(EAFNOSUPPORT)
-    CASEERR1(EADDRINUSE)
-    CASEERR1(EADDRNOTAVAIL)
-    CASEERR1(ENETDOWN)
-    CASEERR1(ENETUNREACH)
-    CASEERR1(ENETRESET)
-    CASEERR1(ECONNABORTED)
-    CASEERR1(ECONNRESET)
-    CASEERR1(ENOBUFS)
-    CASEERR1(EISCONN)
-    CASEERR1(ENOTCONN)
-    CASEERR1(ESHUTDOWN)
-    CASEERR1(ETOOMANYREFS)
-    CASEERR1(ETIMEDOUT)
-    CASEERR1(ECONNREFUSED)
-    CASEERR1(ELOOP)
-    CASEERR1(ENAMETOOLONG)
-    CASEERR1(EHOSTDOWN)
-    CASEERR1(EHOSTUNREACH)
-
-    CASEERR1(ENOTEMPTY)
-//    CASEERR(EPROCLIM)
-//    CASEERR(EUSERS)
-//    CASEERR(EDQUOT)
-//    CASEERR(ESTALE)
-//    CASEERR(EREMOTE)
-//    CASEERR(EDISCON)
-
-
-    default:
-      dprintf(("WSOCK32: Unknown error condition: %d\n",
-               iError));
-      return iError;
-  }
-}
-
-#endif
-
-
-
-
-
-
-
-/*****************************************************************************
- * Name      :
- * Purpose   :
- * Parameters:
- * Variables :
- * Result    :
- * Remark    :
- * Status    : UNTESTED STUB
- *
- * Author    : Patrick Haller [Thu, 1999/11/25 23:00]
- *****************************************************************************/
-
-
-ODINPROCEDURE1(OS2WSASetLastError,
-               int,iError)
+tryagain:
+    for (iData = lpFirstIData; iData; iData = iData->lpNextIData) {
+	if (iData->dwThisThread == tid)
+	    break;
+    }
+    if(iData == NULL && fCurrentThread) {
+	WINSOCK_CreateIData();
+	fCurrentThread = FALSE; //just to prevent infinite loops
+	goto tryagain;
+    }
+    if(iData == NULL) {
+	dprintf(("WINSOCK_GetIData: couldn't find struct for thread %x", tid));
+	DebugInt3();// should never happen!!!!!!!
+    }
+    return iData;
+}
+//******************************************************************************
+//******************************************************************************
+BOOL WINSOCK_CreateIData(void)
+{
+    LPWSINFO iData;
+    
+    iData = (LPWSINFO)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(WSINFO));
+    if (!iData)
+	return FALSE;
+    iData->dwThisThread = GetCurrentThread();
+    iData->lpNextIData = lpFirstIData;
+    lpFirstIData = iData;
+    return TRUE;
+}
+//******************************************************************************
+//******************************************************************************
+void WINSOCK_DeleteIData(void)
+{
+    LPWSINFO ppid, iData;
+
+    if (iData) {
+	ppid = lpFirstIData;
+	while(ppid) 
+	{
+		iData = ppid;
+		ppid  = ppid->lpNextIData;
+
+		if( iData->flags & WSI_BLOCKINGCALL )
+	    		dprintf(("\tinside blocking call!\n"));
+
+		/* delete scratch buffers */
+
+		if(iData->he)	free(iData->he);
+		if(iData->se)	free(iData->se);
+		if(iData->pe)	free(iData->pe);
+
+	////	if( iData->buffer ) SEGPTR_FREE(iData->buffer);
+	////	if( iData->dbuffer ) SEGPTR_FREE(iData->dbuffer);
+
+		HeapFree(GetProcessHeap(), 0, iData);
+	}
+    }
+}
+//******************************************************************************
+//******************************************************************************
+void WIN32API WSASetLastError(int iError)
 {
   // according to the docs, WSASetLastError() is just a call-through
   // to SetLastError()
-  WSASetLastError(iError);
+  if(iError) {
+	dprintf(("WSASetLastError %x", iError));
+  }
   SetLastError(iError);
 }
-
-
-/*****************************************************************************
- * Name      :
- * Purpose   :
- * Parameters:
- * Variables :
- * Result    :
- * Remark    :
- * Status    : UNTESTED STUB
- *
- * Author    : Patrick Haller [Thu, 1999/11/25 23:00]
- *****************************************************************************/
-
-ODINFUNCTION0(int,OS2WSAGetLastError)
-{
-  // according to the docs, WSASetLastError() is just a call-through
-  // to SetLastError(). However, what can be implemented here?
-  return WSAGetLastError();
-}
-
-
-/*****************************************************************************
- * Name      :
- * Purpose   :
- * Parameters:
- * Variables :
- * Result    :
- * Remark    :
- * Status    : UNTESTED STUB
- *
- * Author    : Patrick Haller [Thu, 1999/11/25 23:00]
- *****************************************************************************/
-
-ODINFUNCTION2(int,OS2__WSAFDIsSet,SOCKET, s,
-                                  fd_set*,fds)
-{
-  return (__WSAFDIsSet(s,fds));
-}
-
-
-/*****************************************************************************
- * Name      :
- * Purpose   :
- * Parameters:
- * Variables :
- * Result    :
- * Remark    :
- * Status    : UNTESTED STUB
- *
- * Author    : Patrick Haller [Thu, 1999/11/25 23:00]
- *****************************************************************************/
-
+//******************************************************************************
+//******************************************************************************
+int WIN32API WSAGetLastError()
+{
+  return GetLastError();
+}
+//******************************************************************************
+//******************************************************************************
+ODINFUNCTION2(int,OS2shutdown,
+              SOCKET,s,
+              int,how)
+{
+ int ret;
+
+   if(!fWSAInitialized) {
+      	WSASetLastError(WSANOTINITIALISED);
+      	return SOCKET_ERROR;
+   } 
+   else 
+   if(WSAIsBlocking()) {
+      	WSASetLastError(WSAEINPROGRESS);
+      	return SOCKET_ERROR;
+   } 
+   ret = shutdown(s, how);
+   
+   if(ret == SOCKET_ERROR) {
+ 	WSASetLastError(wsaErrno());
+   }
+   else WSASetLastError(NO_ERROR);
+   return ret;
+}
+//******************************************************************************
+//******************************************************************************
+ODINFUNCTION3(SOCKET,OS2socket,
+              int,af,
+              int,type,
+              int,protocol)
+{
+ SOCKET s;
+
+   if(!fWSAInitialized) {
+      	WSASetLastError(WSANOTINITIALISED);
+      	return SOCKET_ERROR;
+   } 
+   else 
+   if(WSAIsBlocking()) {
+      	WSASetLastError(WSAEINPROGRESS);
+      	return SOCKET_ERROR;
+   } 
+   s = socket(af, type, protocol);
+   
+   if(s == SOCKET_ERROR && sock_errno() == SOCEPFNOSUPPORT) {
+	//map SOCEPFNOSUPPORT to SOCEPFNOSUPPORT
+       	WSASetLastError(SOCEPFNOSUPPORT);
+   }
+   else
+   if(s == SOCKET_ERROR) {
+ 	WSASetLastError(wsaErrno());
+   }
+   else WSASetLastError(NO_ERROR);
+   return s;
+}
+//******************************************************************************
+//******************************************************************************
+ODINFUNCTION1(int,OS2closesocket,SOCKET, s)
+{
+ int ret;
+
+   if(!fWSAInitialized) {
+      	WSASetLastError(WSANOTINITIALISED);
+      	return SOCKET_ERROR;
+   } 
+   else 
+   if(WSAIsBlocking()) {
+      	WSASetLastError(WSAEINPROGRESS);
+      	return SOCKET_ERROR;
+   } 
+   ret = soclose(s);
+   //Close WSAAsyncSelect thread if one was created for this socket
+   FindAndSetAsyncEvent(s, 0, 0, 0);
+  
+   if(ret == SOCKET_ERROR) {
+ 	WSASetLastError(wsaErrno());
+   }
+   else WSASetLastError(NO_ERROR);
+   return ret;
+}
+//******************************************************************************
+//******************************************************************************
+ODINFUNCTION3(int,OS2connect,
+              SOCKET, s,
+              const struct sockaddr *,name,
+              int, namelen)
+{
+ int ret;
+
+   if(!fWSAInitialized) {
+      	WSASetLastError(WSANOTINITIALISED);
+      	return SOCKET_ERROR;
+   } 
+   else 
+   if(WSAIsBlocking()) {
+      	WSASetLastError(WSAEINPROGRESS);
+      	return SOCKET_ERROR;
+   } 
+   ret = connect(s, (sockaddr *)name, namelen);
+   // map BSD error codes
+   if(ret == SOCKET_ERROR) {
+      	if(sock_errno() == SOCEINPROGRESS) {
+         	WSASetLastError(WSAEWOULDBLOCK);
+      	} 
+	else 
+	if (sock_errno() == SOCEOPNOTSUPP) {
+         	WSASetLastError(WSAEINVAL);
+      	}
+	else	WSASetLastError(wsaErrno());
+   }
+   else WSASetLastError(NO_ERROR);
+   return ret;
+}
+//******************************************************************************
+//******************************************************************************
+ODINFUNCTION3(int,OS2ioctlsocket,
+              SOCKET,s,
+              long, cmd,
+              u_long *,argp)
+{
+ int ret;
+
+   if(!fWSAInitialized) {
+      	WSASetLastError(WSANOTINITIALISED);
+      	return SOCKET_ERROR;
+   } 
+   else 
+   if(WSAIsBlocking()) {
+      	WSASetLastError(WSAEINPROGRESS);
+      	return SOCKET_ERROR;
+   } 
+   // clear high word (not used in OS/2's tcpip stack)
+   cmd = LOUSHORT(cmd);
+
+   if(cmd != FIONBIO && cmd != FIONREAD && cmd != SIOCATMARK) {
+        WSASetLastError(WSAEINVAL);
+      	return SOCKET_ERROR;
+   }
+
+   WSASetLastError(NO_ERROR);
+
+   //check if app want to set a socket, which has an outstanding async select,
+   //to blocking mode
+   if (cmd == FIONBIO) {
+	HWND  hwnd;
+	int   msg;
+ 	ULONG lEvent;
+
+	if(QueryAsyncEvent(s, &hwnd, &msg, &lEvent) == TRUE) {
+		if(*argp != 0) {
+			//nothing to do; already non-blocking
+			return NO_ERROR;
+		}
+		else {
+			dprintf(("Trying to set socket to blocking mode while async select active -> return error!"));
+                  	WSASetLastError(WSAEINVAL);
+                  	return SOCKET_ERROR;
+		}
+	}
+   }
+   ret = ioctl(s, cmd, (char *)argp, sizeof(int));
+
+   // Map EOPNOTSUPP to EINVAL
+   if(ret == SOCKET_ERROR && sock_errno() == SOCEOPNOTSUPP)
+     	WSASetLastError(WSAEINVAL);
+   else
+   if(ret == SOCKET_ERROR) {
+ 	WSASetLastError(wsaErrno());
+   }
+   else WSASetLastError(NO_ERROR);
+   return ret;
+}
+//******************************************************************************
+//******************************************************************************
+ODINFUNCTION3(int,OS2getpeername,
+              SOCKET, s,
+              struct sockaddr *,name,
+              int *, namelen)
+{
+ int ret;
+
+   if(!fWSAInitialized) {
+      	WSASetLastError(WSANOTINITIALISED);
+      	return SOCKET_ERROR;
+   } 
+   else 
+   if(WSAIsBlocking()) {
+      	WSASetLastError(WSAEINPROGRESS);
+      	return SOCKET_ERROR;
+   } 
+   else 
+   if (namelen == NULL || *namelen < (int)sizeof(struct sockaddr_in)) {
+      	WSASetLastError(WSAEFAULT);
+      	return SOCKET_ERROR;
+   }
+   ret = getsockname(s, name, namelen);
+   if(ret == SOCKET_ERROR) {
+ 	WSASetLastError(wsaErrno());
+   }
+   else WSASetLastError(NO_ERROR);
+   return ret;
+}
+//******************************************************************************
+//******************************************************************************
+ODINFUNCTION3(int,OS2getsockname,
+              SOCKET,s,
+              struct sockaddr *,name,
+              int *, namelen)
+{
+ int ret;
+
+   if(!fWSAInitialized) {
+      	WSASetLastError(WSANOTINITIALISED);
+      	return SOCKET_ERROR;
+   } 
+   else 
+   if(WSAIsBlocking()) {
+      	WSASetLastError(WSAEINPROGRESS);
+      	return SOCKET_ERROR;
+   } 
+   else 
+   if (namelen == NULL || *namelen < (int)sizeof(struct sockaddr_in)) {
+      	WSASetLastError(WSAEFAULT);
+      	return SOCKET_ERROR;
+   }
+   ret = getsockname(s, name, namelen);
+   if(ret == SOCKET_ERROR) {
+ 	WSASetLastError(wsaErrno());
+   }
+   else WSASetLastError(NO_ERROR);
+   return ret;
+}
+//******************************************************************************
+//******************************************************************************
+ODINFUNCTION1(u_long,OS2htonl,
+              u_long,hostlong)
+{
+  return(htonl(hostlong));
+}
+//******************************************************************************
+//******************************************************************************
+ODINFUNCTION1(u_short,OS2htons,
+              u_short,hostshort)
+{
+  return(htons(hostshort));
+}
+//******************************************************************************
+//******************************************************************************
+ODINFUNCTION1(u_long,OS2ntohl,
+              u_long,netlong)
+{
+  return(ntohl(netlong));
+}
+//******************************************************************************
+//******************************************************************************
+ODINFUNCTION1(u_short,OS2ntohs,
+              u_short,netshort)
+{
+  return(ntohs(netshort));
+}
+//******************************************************************************
+//******************************************************************************
+ODINFUNCTION1(unsigned long,OS2inet_addr,
+              const char *, cp)
+{
+  dprintf(("WSOCK32: OS2inet_addr(%s)\n",
+           cp));
+
+  return (inet_addr((char *)cp));
+}
+//******************************************************************************
+//******************************************************************************
+ODINFUNCTION1(char *,OS2inet_ntoa,
+              struct in_addr, in)
+{
+  return(inet_ntoa(in));
+}
+//******************************************************************************
+//******************************************************************************
 ODINFUNCTION3(SOCKET,OS2accept, SOCKET,           s,
                                 struct sockaddr *,addr,
                                 int *,            addrlen)
 {
-  return(accept(s,addr,addrlen));
-}
-
-
-/*****************************************************************************
- * Name      :
- * Purpose   :
- * Parameters:
- * Variables :
- * Result    :
- * Remark    :
- * Status    : UNTESTED STUB
- *
- * Author    : Patrick Haller [Thu, 1999/11/25 23:00]
- *****************************************************************************/
-
+ int   ret, msg;
+ HWND  hwnd;
+ ULONG lEvent;
+
+   if(!fWSAInitialized) {
+      	WSASetLastError(WSANOTINITIALISED);
+      	return SOCKET_ERROR;
+   } 
+   else 
+   if(WSAIsBlocking()) {
+      	WSASetLastError(WSAEINPROGRESS);
+      	return SOCKET_ERROR;
+   } 
+   else 
+   if ((addr != NULL) && (addrlen != NULL)) {
+        if (*addrlen < (int)sizeof(struct sockaddr_in)) {
+      		WSASetLastError(WSAEFAULT);
+      		return SOCKET_ERROR;
+        }
+   }
+   ret = accept(s, addr, addrlen);
+
+   if(ret != SOCKET_ERROR) {
+	//Enable FD_ACCEPT event flag if WSAAsyncSelect was called for this socket
+      	EnableAsyncEvent(s, FD_ACCEPT);
+
+	//if this socket has an active async. select pending, then call WSAAsyncSelect
+        //with the same parameters for the new socket (see docs)
+	if(QueryAsyncEvent(s, &hwnd, &msg, &lEvent) == TRUE) {
+        	if(WSAAsyncSelect(ret, hwnd, msg, lEvent) == SOCKET_ERROR) {
+            		ret = SOCKET_ERROR;
+		}
+	}
+   }
+   if(ret == SOCKET_ERROR) {
+   	WSASetLastError(wsaErrno());
+   }
+   else WSASetLastError(NO_ERROR);
+   return ret;
+}
+//******************************************************************************
+//******************************************************************************
 ODINFUNCTION3(int,OS2bind,
               SOCKET ,s,
@@ -294,286 +491,72 @@
               int, namelen)
 {
-  return(bind(s,addr,namelen));
-}
-
-
-/*****************************************************************************
- * Name      :
- * Purpose   :
- * Parameters:
- * Variables :
- * Result    :
- * Remark    :
- * Status    : UNTESTED STUB
- *
- * Author    : Patrick Haller [Thu, 1999/11/25 23:00]
- *****************************************************************************/
-
-ODINFUNCTION1(int,OS2closesocket,SOCKET, s)
-{
-  return(closesocket(s));
-}
-
-
-/*****************************************************************************
- * Name      :
- * Purpose   :
- * Parameters:
- * Variables :
- * Result    :
- * Remark    :
- * Status    : UNTESTED STUB
- *
- * Author    : Patrick Haller [Thu, 1999/11/25 23:00]
- *****************************************************************************/
-
-ODINFUNCTION3(int,OS2connect,
-              SOCKET, s,
-              const struct sockaddr *,name,
-              int, namelen)
-{
-  return(connect(s,name,namelen));
-}
-
-
-/*****************************************************************************
- * Name      :
- * Purpose   :
- * Parameters:
- * Variables :
- * Result    :
- * Remark    :
- * Status    : UNTESTED STUB
- *
- * Author    : Patrick Haller [Thu, 1999/11/25 23:00]
- *****************************************************************************/
-
-ODINFUNCTION3(int,OS2ioctlsocket,
-              SOCKET,s,
-              long, cmd,
-              u_long *,argp)
-{
-  return(ioctlsocket(s,cmd,argp));
-}
-
-
-/*****************************************************************************
- * Name      :
- * Purpose   :
- * Parameters:
- * Variables :
- * Result    :
- * Remark    :
- * Status    : UNTESTED STUB
- *
- * Author    : Patrick Haller [Thu, 1999/11/25 23:00]
- *****************************************************************************/
-
-ODINFUNCTION3(int,OS2getpeername,
-              SOCKET, s,
-              struct sockaddr *,name,
-              int *, namelen)
-{
-  return(getpeername(s,name,namelen));
-}
-
-
-/*****************************************************************************
- * Name      :
- * Purpose   :
- * Parameters:
- * Variables :
- * Result    :
- * Remark    :
- * Status    : UNTESTED STUB
- *
- * Author    : Patrick Haller [Thu, 1999/11/25 23:00]
- *****************************************************************************/
-
-ODINFUNCTION3(int,OS2getsockname,
-              SOCKET,s,
-              struct sockaddr *,name,
-              int *, namelen)
-{
-  return(getsockname(s,name,namelen));
-}
-
-
-/*****************************************************************************
- * Name      :
- * Purpose   :
- * Parameters:
- * Variables :
- * Result    :
- * Remark    :
- * Status    : UNTESTED STUB
- *
- * Author    : Patrick Haller [Thu, 1999/11/25 23:00]
- *****************************************************************************/
-
-ODINFUNCTION5(int,OS2getsockopt,
-              SOCKET, s,
-              int, level,
-              int, optname,
-              char *, optval,
-              int *,optlen)
-{
-  return(getsockopt(s,
-                    level,
-                    optname,
-                    optval,
-                    optlen));
-}
-
-
-/*****************************************************************************
- * Name      :
- * Purpose   :
- * Parameters:
- * Variables :
- * Result    :
- * Remark    :
- * Status    : UNTESTED STUB
- *
- * Author    : Patrick Haller [Thu, 1999/11/25 23:00]
- *****************************************************************************/
-
-ODINFUNCTION1(u_long,OS2htonl,
-              u_long,hostlong)
-{
-  return(htonl(hostlong));
-}
-
-
-/*****************************************************************************
- * Name      :
- * Purpose   :
- * Parameters:
- * Variables :
- * Result    :
- * Remark    :
- * Status    : UNTESTED STUB
- *
- * Author    : Patrick Haller [Thu, 1999/11/25 23:00]
- *****************************************************************************/
-
-ODINFUNCTION1(u_short,OS2htons,
-              u_short,hostshort)
-{
-  return(htons(hostshort));
-}
-
-
-/*****************************************************************************
- * Name      :
- * Purpose   :
- * Parameters:
- * Variables :
- * Result    :
- * Remark    :
- * Status    : UNTESTED STUB
- *
- * Author    : Patrick Haller [Thu, 1999/11/25 23:00]
- *****************************************************************************/
-
-ODINFUNCTION1(unsigned long,OS2inet_addr,
-              const char *, cp)
-{
-  dprintf(("WSOCK32: OS2inet_addr(%s)\n",
-           cp));
-
-  return (inet_addr(cp));
-}
-
-
-/*****************************************************************************
- * Name      :
- * Purpose   :
- * Parameters:
- * Variables :
- * Result    :
- * Remark    :
- * Status    : UNTESTED STUB
- *
- * Author    : Patrick Haller [Thu, 1999/11/25 23:00]
- *****************************************************************************/
-
-ODINFUNCTION1(char *,OS2inet_ntoa,
-              struct in_addr, in)
-{
-  return(inet_ntoa(in));
-}
-
-
-/*****************************************************************************
- * Name      :
- * Purpose   :
- * Parameters:
- * Variables :
- * Result    :
- * Remark    :
- * Status    : UNTESTED STUB
- *
- * Author    : Patrick Haller [Thu, 1999/11/25 23:00]
- *****************************************************************************/
-
+ int ret;
+
+   if(!fWSAInitialized) {
+      	WSASetLastError(WSANOTINITIALISED);
+      	return SOCKET_ERROR;
+   } 
+   else 
+   if(WSAIsBlocking()) {
+      	WSASetLastError(WSAEINPROGRESS);
+      	return SOCKET_ERROR;
+   } 
+   else 
+   if(namelen < (int)sizeof(struct sockaddr_in)) {
+      	WSASetLastError(WSAEFAULT);
+      	return SOCKET_ERROR;
+   }
+   ret = bind(s, (struct sockaddr *)addr, namelen);
+
+   if(ret == SOCKET_ERROR) {
+   	WSASetLastError(wsaErrno());
+   }
+   else WSASetLastError(NO_ERROR);
+   return ret;
+}
+//******************************************************************************
+//******************************************************************************
 ODINFUNCTION2(int,OS2listen,
               SOCKET, s,
               int, backlog)
 {
-  return(listen(s,backlog));
-}
-
-
-/*****************************************************************************
- * Name      :
- * Purpose   :
- * Parameters:
- * Variables :
- * Result    :
- * Remark    :
- * Status    : UNTESTED STUB
- *
- * Author    : Patrick Haller [Thu, 1999/11/25 23:00]
- *****************************************************************************/
-
-ODINFUNCTION1(u_long,OS2ntohl,
-              u_long,netlong)
-{
-  return(ntohl(netlong));
-}
-
-
-/*****************************************************************************
- * Name      :
- * Purpose   :
- * Parameters:
- * Variables :
- * Result    :
- * Remark    :
- * Status    : UNTESTED STUB
- *
- * Author    : Patrick Haller [Thu, 1999/11/25 23:00]
- *****************************************************************************/
-
-ODINFUNCTION1(u_short,OS2ntohs,
-              u_short,netshort)
-{
-  return(ntohs(netshort));
-}
-
-
-/*****************************************************************************
- * Name      :
- * Purpose   :
- * Parameters:
- * Variables :
- * Result    :
- * Remark    :
- * Status    : UNTESTED STUB
- *
- * Author    : Patrick Haller [Thu, 1999/11/25 23:00]
- *****************************************************************************/
-
+   int ret, tmp, namelen;
+   struct sockaddr_in name;
+
+   if(!fWSAInitialized) {
+      	WSASetLastError(WSANOTINITIALISED);
+      	return SOCKET_ERROR;
+   } 
+   else 
+   if(WSAIsBlocking()) {
+      	WSASetLastError(WSAEINPROGRESS);
+      	return SOCKET_ERROR;
+   } 
+   namelen = sizeof(name);
+   ret = getsockname(s, (struct sockaddr *)&name, &namelen);
+   if (ret == 0) {
+        if (name.sin_port == 0 && name.sin_addr.s_addr == 0) {
+            	// Socket is not bound
+            	WSASetLastError(WSAEINVAL);
+            	return SOCKET_ERROR;
+        } 
+      	ret = ioctl(s, FIOBSTATUS, (char *)&tmp, sizeof(tmp)) &
+                   (SS_ISCONNECTING | SS_ISCONNECTED | SS_ISDISCONNECTING);
+        if(ret) {
+        	// Socket is already connected
+            	WSASetLastError(WSAEISCONN);
+               	return SOCKET_ERROR;
+	}
+        ret = listen(s, backlog);
+	//todo: reset FD_ACCEPT bit? (wine seems to do this, but it's not documented)
+   }
+   if(ret == SOCKET_ERROR) {
+   	WSASetLastError(wsaErrno());
+   }
+   else WSASetLastError(NO_ERROR);
+   return ret;
+}
+//******************************************************************************
+//******************************************************************************
 ODINFUNCTION4(int,OS2recv,
               SOCKET,s,
@@ -582,23 +565,28 @@
               int,flags)
 {
-  return(recv(s,
-              buf,
-              len,
-              flags));
-}
-
-
-/*****************************************************************************
- * Name      :
- * Purpose   :
- * Parameters:
- * Variables :
- * Result    :
- * Remark    :
- * Status    : UNTESTED STUB
- *
- * Author    : Patrick Haller [Thu, 1999/11/25 23:00]
- *****************************************************************************/
-
+   int ret;
+
+   if(!fWSAInitialized) {
+      	WSASetLastError(WSANOTINITIALISED);
+      	return SOCKET_ERROR;
+   } 
+   else 
+   if(WSAIsBlocking()) {
+      	WSASetLastError(WSAEINPROGRESS);
+      	return SOCKET_ERROR;
+   } 
+   ret = recv(s, buf, len, flags);
+
+   if(ret == SOCKET_ERROR) {
+ 	WSASetLastError(wsaErrno());
+   }
+   else WSASetLastError(NO_ERROR);
+
+   //Reset FD_READ event flagfor  WSAAsyncSelect thread if one was created for this socket
+   EnableAsyncEvent(s, FD_READ);
+   return ret;
+}
+//******************************************************************************
+//******************************************************************************
 ODINFUNCTION6(int,OS2recvfrom,
               SOCKET,s,
@@ -609,53 +597,33 @@
               int *,fromlen)
 {
-
-  return(recvfrom(s,
-                buf,
-                len,
-                flags,
-                from,
-                fromlen));
-}
-
-
-/*****************************************************************************
- * Name      :
- * Purpose   :
- * Parameters:
- * Variables :
- * Result    :
- * Remark    :
- * Status    : UNTESTED STUB
- *
- * Author    : Patrick Haller [Thu, 1999/11/25 23:00]
- *****************************************************************************/
-
-ODINFUNCTION5(int,OS2select,
-              int,nfds,
-              fd_set *,readfds,
-              fd_set *,writefds,
-              fd_set *,exceptfds,
-              const struct timeval *,timeout)
-{
-  return(select(nfds,
-                readfds,
-                writefds,
-                exceptfds,
-                timeout));
-}
-
-
-/*****************************************************************************
- * Name      :
- * Purpose   :
- * Parameters:
- * Variables :
- * Result    :
- * Remark    :
- * Status    : UNTESTED STUB
- *
- * Author    : Patrick Haller [Thu, 1999/11/25 23:00]
- *****************************************************************************/
-
+   int ret;
+
+   if(!fWSAInitialized) {
+      	WSASetLastError(WSANOTINITIALISED);
+      	return SOCKET_ERROR;
+   } 
+   else 
+   if(WSAIsBlocking()) {
+      	WSASetLastError(WSAEINPROGRESS);
+      	return SOCKET_ERROR;
+   } 
+   else 
+   if(fromlen == NULL || *fromlen < (int)sizeof(struct sockaddr_in)) {
+      	WSASetLastError(WSAEFAULT);
+      	return SOCKET_ERROR;
+   }
+   ret = recvfrom(s, buf, len, flags, from, fromlen);
+
+   if(ret == SOCKET_ERROR) {
+ 	WSASetLastError(wsaErrno());
+   }
+   else WSASetLastError(NO_ERROR);
+
+   //Reset FD_READ event flagfor  WSAAsyncSelect thread if one was created for this socket
+   EnableAsyncEvent(s, FD_READ);
+   return ret;
+}
+//******************************************************************************
+//******************************************************************************
 ODINFUNCTION4(int,OS2send,
               SOCKET,s,
@@ -664,23 +632,28 @@
               int,flags)
 {
-  return(send(s,
-              buf,
-              len,
-              flags));
-}
-
-
-/*****************************************************************************
- * Name      :
- * Purpose   :
- * Parameters:
- * Variables :
- * Result    :
- * Remark    :
- * Status    : UNTESTED STUB
- *
- * Author    : Patrick Haller [Thu, 1999/11/25 23:00]
- *****************************************************************************/
-
+   int ret;
+
+   if(!fWSAInitialized) {
+      	WSASetLastError(WSANOTINITIALISED);
+      	return SOCKET_ERROR;
+   } 
+   else 
+   if(WSAIsBlocking()) {
+      	WSASetLastError(WSAEINPROGRESS);
+      	return SOCKET_ERROR;
+   } 
+   ret = send(s, (char *)buf, len, flags);
+
+   if(ret == SOCKET_ERROR) {
+ 	WSASetLastError(wsaErrno());
+   }
+   else WSASetLastError(NO_ERROR);
+
+   //Reset FD_WRITE event flagfor  WSAAsyncSelect thread if one was created for this socket
+   EnableAsyncEvent(s, FD_WRITE);
+   return ret;
+}
+//******************************************************************************
+//******************************************************************************
 ODINFUNCTION6(int,OS2sendto,
               SOCKET,s,
@@ -691,25 +664,155 @@
               int,tolen)
 {
-  return(sendto(s,
-              buf,
-              len,
-              flags,
-              to,
-              tolen));
-}
-
-
-/*****************************************************************************
- * Name      :
- * Purpose   :
- * Parameters:
- * Variables :
- * Result    :
- * Remark    :
- * Status    : UNTESTED STUB
- *
- * Author    : Patrick Haller [Thu, 1999/11/25 23:00]
- *****************************************************************************/
-
+   int ret;
+
+   if(!fWSAInitialized) {
+      	WSASetLastError(WSANOTINITIALISED);
+      	return SOCKET_ERROR;
+   } 
+   else 
+   if(WSAIsBlocking()) {
+      	WSASetLastError(WSAEINPROGRESS);
+      	return SOCKET_ERROR;
+   } 
+   else 
+   if(tolen < (int)sizeof(struct sockaddr_in)) {
+      	WSASetLastError(WSAEFAULT);
+      	return SOCKET_ERROR;
+   }
+   ret = sendto(s, (char *)buf, len, flags, (struct sockaddr *)to, tolen);
+
+   if(ret == SOCKET_ERROR) {
+ 	WSASetLastError(wsaErrno());
+   }
+   else WSASetLastError(NO_ERROR);
+
+   //Reset FD_WRITE event flagfor  WSAAsyncSelect thread if one was created for this socket
+   EnableAsyncEvent(s, FD_WRITE);
+   return ret;
+}
+//******************************************************************************
+//******************************************************************************
+ODINFUNCTION5(int,OS2select,
+              int,nfds,
+              ws_fd_set *,readfds,
+              ws_fd_set *,writefds,
+              ws_fd_set *,exceptfds,
+              const struct timeval *,timeout)
+{
+ int ret, i, j;
+ int *sockets, *socktmp;
+ int nrread, nrwrite, nrexcept;
+ ULONG ttimeout;
+
+   WSASetLastError(NO_ERROR);
+
+   if(!fWSAInitialized) {
+      	WSASetLastError(WSANOTINITIALISED);
+      	return SOCKET_ERROR;
+   } 
+   else 
+   if(WSAIsBlocking()) {
+      	WSASetLastError(WSAEINPROGRESS);
+      	return SOCKET_ERROR;
+   } 
+   else {
+	nrread = nrwrite = nrexcept = 0;
+	if(readfds) {
+		nrread += readfds->fd_count;
+	}
+	if(writefds) {
+		nrwrite += writefds->fd_count;
+	}
+	if(exceptfds) {
+		nrexcept += exceptfds->fd_count;
+	}
+      	if(nrread + nrwrite + nrexcept  == 0) {
+         	WSASetLastError(WSAEINVAL);
+         	return SOCKET_ERROR;
+	}
+      	if(timeout != NULL && (timeout->tv_sec < 0 || timeout->tv_usec < 0)) {
+         	WSASetLastError(WSAEINVAL);
+         	return SOCKET_ERROR;
+      	}
+        if(timeout == NULL) {
+            	ttimeout = -1L; // no timeout
+        } 
+	else    ttimeout = timeout->tv_sec * 1000 + timeout->tv_usec / 1000;
+	
+	sockets = (int *)malloc(sizeof(int) * (nrread+nrwrite+nrexcept));
+	if(readfds) {
+		memcpy(&sockets[0], readfds->fd_array, nrread * sizeof(SOCKET));
+	}
+	if(writefds) {
+		memcpy(&sockets[nrread], writefds->fd_array, nrwrite * sizeof(SOCKET));
+	}
+	if(exceptfds) {
+		memcpy(&sockets[nrread+nrwrite], exceptfds->fd_array, nrexcept * sizeof(SOCKET));
+	}
+
+        ret = select(sockets, nrread, nrwrite, nrexcept, ttimeout);
+
+      	if(ret == SOCKET_ERROR) 
+	{
+            	if(readfds != NULL)
+               		readfds->fd_count = 0;
+
+            	if(writefds != NULL)
+               		writefds->fd_count = 0;
+
+            	if(exceptfds != NULL)
+               		exceptfds->fd_count = 0;
+
+ 		WSASetLastError(wsaErrno());
+		free(sockets);
+		return SOCKET_ERROR;
+      	} 
+
+        if(ret != 0) {
+		socktmp = sockets;
+            	if(readfds != NULL) {
+               		for(i=0;i<nrread;i++) {
+                  		if(socktmp[i] != -1) {
+	                     		readfds->fd_array[j] = socktmp[i];
+				}
+	                }
+	               	readfds->fd_count = i;
+			socktmp += nrread;
+	        }
+
+            	if(writefds != NULL) {
+               		for(i=0;i<nrwrite;i++) {
+                  		if(socktmp[i] != -1) {
+	                     		writefds->fd_array[j] = socktmp[i];
+				}
+	                }
+	               	writefds->fd_count = i;
+			socktmp += nrwrite;
+            	}
+            	if(exceptfds != NULL) {
+               		for(i=0;i<nrexcept;i++) {
+                  		if(socktmp[i] != -1) {
+	                     		exceptfds->fd_array[j] = socktmp[i];
+				}
+	                }
+	               	exceptfds->fd_count = i;
+            	}
+         } 
+	else {
+            if(readfds != NULL)
+               readfds->fd_count = 0;
+
+            if(writefds != NULL)
+               writefds->fd_count = 0;
+
+            if(exceptfds != NULL)
+               exceptfds->fd_count = 0;
+        }
+	free(sockets);
+   }
+   return ret;
+}
+//******************************************************************************
+//******************************************************************************
 ODINFUNCTION5(int,OS2setsockopt,
               SOCKET,s,
@@ -719,840 +822,348 @@
               int,optlen)
 {
-  struct Wlinger *yy;
-  struct linger xx;
-  int    rc;
-
-  if(level   == SOL_SOCKET &&
-     optname == SO_LINGER)
-  {
-    yy = (struct Wlinger *)optval;
-    xx.l_onoff = (int)yy->l_onoff;
-    xx.l_linger = (int)yy->l_linger;
-
-    rc = setsockopt(s,level,optname,(char *)&xx, sizeof(xx));
-  }
-  else 
-  if(level == SOL_SOCKET && (optname == SO_SNDBUF || optname == SO_RCVBUF)) {
-	ULONG size;
-
-	size = *(ULONG *)optval;
+  struct ws_linger *yy;
+  struct linger     xx;
+  int               ret;
+  ULONG             size;
+
+   if(!fWSAInitialized) {
+      	WSASetLastError(WSANOTINITIALISED);
+      	return SOCKET_ERROR;
+   } 
+   else 
+   if(WSAIsBlocking()) {
+      	WSASetLastError(WSAEINPROGRESS);
+      	return SOCKET_ERROR;
+   } 
+   if (level == SOL_SOCKET) {
+	switch(optname) {
+	case SO_DONTLINGER:
+	case SO_LINGER:
+            	if(optlen < (int)sizeof(ws_linger)) {
+               		WSASetLastError(WSAEFAULT);
+               		return SOCKET_ERROR;
+            	}
+    		yy = (struct ws_linger *)optval;
+		xx.l_onoff  = (optname == SO_DONTLINGER) ? !yy->l_onoff : yy->l_onoff;
+		xx.l_linger = yy->l_linger;
+
+		ret = setsockopt(s,level,optname,(char *)&xx, sizeof(xx));
+		break;
+	case SO_SNDBUF:
+	case SO_RCVBUF:
+            	if(optlen < (int)sizeof(int)) {
+               		WSASetLastError(WSAEFAULT);
+               		return SOCKET_ERROR;
+            	}
+
+		size = *(ULONG *)optval;
 tryagain:
-	rc = setsockopt(s,level,optname, (char *)&size, sizeof(ULONG));
-	if(rc == SOCKET_ERROR && size > 65535) {
-		//SvL: Limit send & receive buffer length to 64k
-                //     (only happens with 16 bits tcpip stack?)
-		size = 65000;
-		goto tryagain;
-	}
-
-  }
-  else {
-    rc = setsockopt(s,level,optname,(char *)optval,optlen);
-  }
-
-  if (rc == SOCKET_ERROR)
-    //OS2WSASetLastError(iTranslateSockErrToWSock(sock_errno()));
-    OS2WSASetLastError(WSAEINVAL);
-  else
-    OS2WSASetLastError(ERROR_SUCCESS);
-
-  return rc;
-}
-
-
-/*****************************************************************************
- * Name      :
- * Purpose   :
- * Parameters:
- * Variables :
- * Result    :
- * Remark    :
- * Status    : UNTESTED STUB
- *
- * Author    : Patrick Haller [Thu, 1999/11/25 23:00]
- *****************************************************************************/
-
-ODINFUNCTION2(int,OS2shutdown,
-              SOCKET,s,
-              int,how)
-{
-  return(shutdown(s,
-                  how));
-}
-
-
-/*****************************************************************************
- * Name      :
- * Purpose   :
- * Parameters:
- * Variables :
- * Result    :
- * Remark    :
- * Status    : UNTESTED STUB
- *
- * Author    : Patrick Haller [Thu, 1999/11/25 23:00]
- *****************************************************************************/
-
-ODINFUNCTION3(SOCKET,OS2socket,
-              int,af,
-              int,type,
-              int,protocol)
-{
-  return(socket(af,
-                type,
-                protocol));
-}
-
-
+		ret = setsockopt(s,level,optname, (char *)&size, sizeof(ULONG));
+		if(ret == SOCKET_ERROR && size > 65535) {
+			dprintf(("setsockopt: change size from %d to 65000", size));
+			//SvL: Limit send & receive buffer length to 64k
+	                //     (only happens with 16 bits tcpip stack?)
+			size = 65000;
+			goto tryagain;
+		}
+		break;
+
+	case SO_BROADCAST:
+	case SO_DEBUG:
+	case SO_KEEPALIVE:
+	case SO_DONTROUTE:
+	case SO_OOBINLINE:
+	case SO_REUSEADDR:
+            	if(optlen < (int)sizeof(int)) {
+               		WSASetLastError(WSAEFAULT);
+               		return SOCKET_ERROR;
+            	}
+                ret = setsockopt(s, level, optname, (char *)optval, optlen);
+		break;
+	default: 
+		dprintf(("setsockopt: unknown option %x", optname));
+            	WSASetLastError(WSAENOPROTOOPT);
+            	return SOCKET_ERROR;
+        } 
+   }
+   else 
+   if(level == IPPROTO_TCP) {
+       	if(optname == TCP_NODELAY) {
+            	if(optlen < (int)sizeof(int)) {
+               		WSASetLastError(WSAEFAULT);
+               		return SOCKET_ERROR;
+            	}
+               	ret = setsockopt(s, level, optname, (char *)optval, optlen);
+        } 
+	else {
+		dprintf(("setsockopt: unknown option %x", optname));
+       		WSASetLastError(WSAENOPROTOOPT);
+      		return SOCKET_ERROR;
+        }
+   } 
+   else {
+       	WSASetLastError(WSAEINVAL);
+	return SOCKET_ERROR;
+   }
+
+   if(ret == SOCKET_ERROR) {
+ 	WSASetLastError(wsaErrno());
+   }
+   else WSASetLastError(NO_ERROR);
+   return ret;
+}
+//******************************************************************************
+//******************************************************************************
+ODINFUNCTION5(int,OS2getsockopt,
+              SOCKET, s,
+              int, level,
+              int, optname,
+              char *, optval,
+              int *,optlen)
+{
+  struct ws_linger *yy;
+  struct linger     xx;
+  int               ret;
+  int               size, options;
+
+   if(!fWSAInitialized) {
+      	WSASetLastError(WSANOTINITIALISED);
+      	return SOCKET_ERROR;
+   } 
+   else 
+   if(WSAIsBlocking()) {
+      	WSASetLastError(WSAEINPROGRESS);
+      	return SOCKET_ERROR;
+   } 
+   if (level == SOL_SOCKET) {
+	switch(optname) {
+	case SO_DONTLINGER:
+	case SO_LINGER:
+            	if(optlen == NULL || *optlen < sizeof(ws_linger)) {
+               		WSASetLastError(WSAEFAULT);
+               		return SOCKET_ERROR;
+            	}
+		size = sizeof(xx);
+		ret = getsockopt(s,level,optname,(char *)&xx, &size);
+    		yy = (struct ws_linger *)optval;
+		yy->l_onoff  = (optname == SO_DONTLINGER) ? !xx.l_onoff : xx.l_onoff;
+		yy->l_linger = xx.l_linger;
+		*optlen = size;
+		break;
+
+	case SO_SNDBUF:
+	case SO_RCVBUF:
+	case SO_BROADCAST:
+	case SO_DEBUG:
+	case SO_KEEPALIVE:
+	case SO_DONTROUTE:
+	case SO_OOBINLINE:
+	case SO_REUSEADDR:
+	case SO_TYPE:
+            	if(optlen == NULL || *optlen < sizeof(int)) {
+               		WSASetLastError(WSAEFAULT);
+               		return SOCKET_ERROR;
+            	}
+                ret = getsockopt(s, level, optname, (char *)optval, optlen);
+		break;
+	case SO_ACCEPTCONN:
+            	if(optlen == NULL || *optlen < sizeof(int)) {
+               		WSASetLastError(WSAEFAULT);
+               		return SOCKET_ERROR;
+            	}
+                size = sizeof(options);
+                ret = getsockopt(s, SOL_SOCKET, SO_OPTIONS, (char *)&options, &size);
+                if(ret != SOCKET_ERROR) {
+                   	*(BOOL *)optval = (options & SO_ACCEPTCONN) == SO_ACCEPTCONN;
+                   	*optlen = sizeof(BOOL);
+                }
+		break;
+	default: 
+		dprintf(("getsockopt: unknown option %x", optname));
+            	WSASetLastError(WSAENOPROTOOPT);
+            	return SOCKET_ERROR;
+        } 
+   }
+   else 
+   if(level == IPPROTO_TCP) {
+       	if(optname == TCP_NODELAY) {
+            	if(optlen == NULL || *optlen < sizeof(int)) {
+               		WSASetLastError(WSAEFAULT);
+               		return SOCKET_ERROR;
+            	}
+               	ret = getsockopt(s, level, optname, (char *)optval, optlen);
+        } 
+	else {
+		dprintf(("getsockopt: unknown option %x", optname));
+       		WSASetLastError(WSAENOPROTOOPT);
+      		return SOCKET_ERROR;
+        }
+   } 
+   else {
+       	WSASetLastError(WSAEINVAL);
+	return SOCKET_ERROR;
+   }
+
+   if(ret == SOCKET_ERROR) {
+ 	WSASetLastError(wsaErrno());
+   }
+   else WSASetLastError(NO_ERROR);
+   return ret;
+}
+//******************************************************************************
+//******************************************************************************
 /* Database function prototypes */
-
-/*****************************************************************************
- * Name      :
- * Purpose   :
- * Parameters:
- * Variables :
- * Result    :
- * Remark    :
- * Status    : UNTESTED STUB
- *
- * Author    : Patrick Haller [Thu, 1999/11/25 23:00]
- *****************************************************************************/
-
-ODINFUNCTION3(struct Whostent *,OS2gethostbyaddr,
+//******************************************************************************
+//******************************************************************************
+ODINFUNCTION2(int,OS2gethostname,
+              char *,name,
+              int,namelen)
+{
+ int ret;
+
+   ret = gethostname(name, namelen);
+   if(ret == NULL) {
+   	WSASetLastError(NO_ERROR);
+	return 0;
+   }
+   WSASetLastError((errno == EINVAL) ? WSAEFAULT : wsaErrno());
+   return SOCKET_ERROR;
+}
+//******************************************************************************
+//******************************************************************************
+ODINFUNCTION3(ws_hostent *,OS2gethostbyaddr,
               const char *,addr,
               int,len,
               int,type)
 {
-  WHOSTENT         *yy;
-  struct hostent   *xx;
-  PWSOCKTHREADDATA pwstd;
-
-  xx = gethostbyaddr((char *)addr,len,type);
-  //PH: we assume PMWSOCK sets WSASetLastError correctly!
-
-  if(xx == NULL)
-     return (WHOSTENT *)NULL;
-
-  // access current thread wsock data block
-  pwstd = iQueryWsockThreadData();
-
-  pwstd->whsnt.h_name      = xx->h_name;
-  pwstd->whsnt.h_aliases   = xx->h_aliases;
-  pwstd->whsnt.h_addrtype  = (short)xx->h_addrtype;
-  pwstd->whsnt.h_length    = (short)xx->h_length;
-  pwstd->whsnt.h_addr_list = xx->h_addr_list;
-
-  return &pwstd->whsnt;
-}
-
-
-/*****************************************************************************
- * Name      :
- * Purpose   :
- * Parameters:
- * Variables :
- * Result    :
- * Remark    :
- * Status    : UNTESTED STUB
- *
- * Author    : Patrick Haller [Thu, 1999/11/25 23:00]
- *****************************************************************************/
-
-ODINFUNCTION1(struct Whostent *,OS2gethostbyname,
+    LPWSINFO pwsi = WINSOCK_GetIData();
+
+    if( pwsi )
+    {
+	struct hostent*	host;
+	if( (host = gethostbyaddr((char *)addr, len, type)) != NULL ) {
+	    	if( WS_dup_he(pwsi, host) ) {
+			WSASetLastError(NO_ERROR);
+			return pwsi->he;
+		}
+		else 	WSASetLastError(WSAENOBUFS);
+	}
+	else 	WSASetLastError((h_errno < 0) ? wsaErrno() : wsaHerrno());
+    }
+    else WSASetLastError(WSANOTINITIALISED);
+    return NULL;
+}
+//******************************************************************************
+//******************************************************************************
+ODINFUNCTION1(ws_hostent *,OS2gethostbyname,
               const char *,name)
 {
-  WHOSTENT         *yy;
-  struct hostent   *xx;
-  PWSOCKTHREADDATA pwstd;
-
-
-  xx = gethostbyname((char *)name);
-  //PH: we assume PMWSOCK sets WSASetLastError correctly!
-
-  if(xx == NULL)
-    return (WHOSTENT *)NULL;
-
-  // access current thread wsock data block
-  pwstd = iQueryWsockThreadData();
-
-  pwstd->whsnt.h_name      = xx->h_name;
-  pwstd->whsnt.h_aliases   = xx->h_aliases;
-  pwstd->whsnt.h_addrtype  = (short)xx->h_addrtype;
-  pwstd->whsnt.h_length    = (short)xx->h_length;
-  pwstd->whsnt.h_addr_list = xx->h_addr_list;
-
-  return &pwstd->whsnt;
-}
-
-
-/*****************************************************************************
- * Name      :
- * Purpose   :
- * Parameters:
- * Variables :
- * Result    :
- * Remark    :
- * Status    : UNTESTED STUB
- *
- * Author    : Patrick Haller [Thu, 1999/11/25 23:00]
- *****************************************************************************/
-
-ODINFUNCTION2(int,OS2gethostname,
-              char *,name,
-              int,namelen)
-{
-   //PH: we assume PMWSOCK sets WSASetLastError correctly!
-   return(gethostname(name,
-                     namelen));
-}
-
-
-/*****************************************************************************
- * Name      :
- * Purpose   :
- * Parameters:
- * Variables :
- * Result    :
- * Remark    :
- * Status    : UNTESTED STUB
- *
- * Author    : Patrick Haller [Thu, 1999/11/25 23:00]
- *****************************************************************************/
-
-ODINFUNCTION2(struct Wservent *,OS2getservbyport,
+    LPWSINFO pwsi = WINSOCK_GetIData();
+
+    if( pwsi )
+    {
+	struct hostent*     host;
+	if( (host = gethostbyname((char *)name)) != NULL ) {
+	    	if( WS_dup_he(pwsi, host) ) {
+			WSASetLastError(NO_ERROR);
+			return pwsi->he;
+		}
+		else 	WSASetLastError(WSAENOBUFS);
+	}
+	else 	WSASetLastError((h_errno < 0) ? wsaErrno() : wsaHerrno());
+    }
+    else WSASetLastError(WSANOTINITIALISED);
+    return NULL;
+}
+//******************************************************************************
+//******************************************************************************
+ODINFUNCTION2(struct ws_servent *,OS2getservbyport,
               int,              port,
               const char *,     proto)
 {
-  struct servent   *xx;
-  PWSOCKTHREADDATA pwstd;
-
-  //PH: we assume PMWSOCK sets WSASetLastError correctly!
-  xx = getservbyport(port,(char *)proto);
-
-  if(xx == NULL)
-    return (WSERVENT *)NULL;
-
-  // access current thread wsock data block
-  pwstd = iQueryWsockThreadData();
-
-  pwstd->wsvnt.s_name    = xx->s_name;
-  pwstd->wsvnt.s_aliases = xx->s_aliases;
-  pwstd->wsvnt.s_port    = (short)xx->s_port;
-  pwstd->wsvnt.s_proto   = xx->s_proto;
-
-  return &pwstd->wsvnt;
-}
-
-
-/*****************************************************************************
- * Name      :
- * Purpose   :
- * Parameters:
- * Variables :
- * Result    :
- * Remark    :
- * Status    : UNTESTED STUB
- *
- * Author    : Patrick Haller [Thu, 1999/11/25 23:00]
- *****************************************************************************/
-
-ODINFUNCTION2(struct Wservent *,OS2getservbyname,
+    LPWSINFO pwsi = WINSOCK_GetIData();
+
+    if( pwsi )
+    {
+	struct servent* serv;
+	if( (serv = getservbyport(port, pwsi->buffer)) != NULL ) {
+		if( WS_dup_se(pwsi, serv) ) {
+			WSASetLastError(NO_ERROR);
+		    	return pwsi->se;
+		}
+		else 	WSASetLastError(WSAENOBUFS);
+	}
+	else 	WSASetLastError(WSANO_DATA);
+    } 
+    else WSASetLastError(WSANOTINITIALISED);
+    return NULL;
+}
+//******************************************************************************
+//******************************************************************************
+ODINFUNCTION2(struct ws_servent *,OS2getservbyname,
               const char *,     name,
               const char *,     proto)
 {
-  WSERVENT         *yy;
-  struct servent   *xx;
-  PWSOCKTHREADDATA pwstd;
-
-
-  //PH: we assume PMWSOCK sets WSASetLastError correctly!
-  xx = getservbyname((char *)name,(char *)proto);
-
-  if(xx == NULL)
-    return (WSERVENT *)NULL;
-
-  // access current thread wsock data block
-  pwstd = iQueryWsockThreadData();
-
-  pwstd->wsvnt.s_name    = xx->s_name;
-  pwstd->wsvnt.s_aliases = xx->s_aliases;
-  pwstd->wsvnt.s_port    = (short)xx->s_port;
-  pwstd->wsvnt.s_proto   = xx->s_proto;
-
-  return &pwstd->wsvnt;
-}
-
-
-/*****************************************************************************
- * Name      :
- * Purpose   :
- * Parameters:
- * Variables :
- * Result    :
- * Remark    :
- * Status    : UNTESTED STUB
- *
- * Author    : Patrick Haller [Thu, 1999/11/25 23:00]
- *****************************************************************************/
-
-ODINFUNCTION1(struct Wprotoent *,OS2getprotobynumber,
-              int,proto)
-{
-  struct protoent  *xx;
-  PWSOCKTHREADDATA pwstd;
-
-  //PH: we assume PMWSOCK sets WSASetLastError correctly!
-  xx = getprotobynumber(proto);
-
-  if(xx == NULL)
-    return (WPROTOENT *)NULL;
-
-  // access current thread wsock data block
-  pwstd = iQueryWsockThreadData();
-
-  pwstd->wptnt.p_name    = xx->p_name;
-  pwstd->wptnt.p_aliases = xx->p_aliases;
-  pwstd->wptnt.p_proto   = (short)xx->p_proto;
-
-  return &pwstd->wptnt;
-}
-
-
-/*****************************************************************************
- * Name      :
- * Purpose   :
- * Parameters:
- * Variables :
- * Result    :
- * Remark    :
- * Status    : UNTESTED STUB
- *
- * Author    : Patrick Haller [Thu, 1999/11/25 23:00]
- *****************************************************************************/
-
-ODINFUNCTION1(struct Wprotoent *,OS2getprotobyname,
+    LPWSINFO pwsi = WINSOCK_GetIData();
+
+    if( pwsi )
+    {
+	struct servent*     serv;
+	if( (serv = getservbyname(pwsi->buffer, pwsi->buffer)) != NULL ) {
+		if( WS_dup_se(pwsi, serv) ) {
+			WSASetLastError(NO_ERROR);
+		    	return pwsi->se;
+		}
+		else 	WSASetLastError(WSAENOBUFS);
+    	}
+   	else 	WSASetLastError(WSANO_DATA);
+    } 
+    else WSASetLastError(WSANOTINITIALISED);
+    return NULL;
+}
+//******************************************************************************
+//******************************************************************************
+ODINFUNCTION1(struct ws_protoent *,OS2getprotobynumber,
+              int,number)
+{
+    LPWSINFO pwsi = WINSOCK_GetIData();
+
+    if( pwsi )
+    {
+	struct protoent* proto;
+	if( (proto = getprotobynumber(number)) != NULL ) {
+	    	if( WS_dup_pe(pwsi, proto) ) {
+			WSASetLastError(NO_ERROR);
+			return pwsi->pe;
+		}
+	    	else 	WSASetLastError(WSAENOBUFS);
+	}
+	else 	WSASetLastError(WSANO_DATA);
+    }
+    else WSASetLastError(WSANOTINITIALISED);
+    return NULL;
+}
+//******************************************************************************
+//******************************************************************************
+ODINFUNCTION1(struct ws_protoent *,OS2getprotobyname,
               const char *,name)
 {
-  struct protoent  *xx;
-  PWSOCKTHREADDATA pwstd;
-
-  //PH: we assume PMWSOCK sets WSASetLastError correctly!
-  xx = getprotobyname((char *)name);
-
-  if(xx == NULL)
-    return (WPROTOENT *)NULL;
-
-  // access current thread wsock data block
-  pwstd = iQueryWsockThreadData();
-
-  pwstd->wptnt.p_name    = xx->p_name;
-  pwstd->wptnt.p_aliases = xx->p_aliases;
-  pwstd->wptnt.p_proto   = (short)xx->p_proto;
-
-  return &pwstd->wptnt;
-}
-
-
-
-/* Microsoft Windows Extension function prototypes */
-
-/*****************************************************************************
- * Name      :
- * Purpose   :
- * Parameters:
- * Variables :
- * Result    :
- * Remark    :
- * Status    : UNTESTED STUB
- *
- * Author    : Patrick Haller [Thu, 1999/11/25 23:00]
- *****************************************************************************/
-
-ODINFUNCTION2(int,OS2WSAStartup,
-              USHORT,wVersionRequired,
-              LPWSADATA,lpWSAData)
-{
-  fWSAInitialized = TRUE;
-  return(WSAStartup(wVersionRequired,
-                    lpWSAData));
-}
-
-
-/*****************************************************************************
- * Name      :
- * Purpose   :
- * Parameters:
- * Variables :
- * Result    :
- * Remark    :
- * Status    : UNTESTED STUB
- *
- * Author    : Patrick Haller [Thu, 1999/11/25 23:00]
- *****************************************************************************/
-
-ODINFUNCTION0(int,OS2WSACleanup)
-{
-  fWSAInitialized = FALSE;
-  return(WSACleanup());
-}
-
-
-/*****************************************************************************
- * Name      :
- * Purpose   :
- * Parameters:
- * Variables :
- * Result    :
- * Remark    :
- * Status    : UNTESTED STUB
- *
- * Author    : Patrick Haller [Thu, 1999/11/25 23:00]
- *****************************************************************************/
-
-ODINFUNCTION0(BOOL,OS2WSAIsBlocking)
-{
-  return WSAIsBlocking();
-}
-
-
-/*****************************************************************************
- * Name      :
- * Purpose   :
- * Parameters:
- * Variables :
- * Result    :
- * Remark    :
- * Status    : UNTESTED STUB
- *
- * Author    : Patrick Haller [Thu, 1999/11/25 23:00]
- *****************************************************************************/
-
-ODINFUNCTION0(int,OS2WSAUnhookBlockingHook)
-{
-  return WSAUnhookBlockingHook();
-}
-
-
-/*****************************************************************************
- * Name      :
- * Purpose   :
- * Parameters:
- * Variables :
- * Result    :
- * Remark    :
- * Status    : UNTESTED STUB
- *
- * Author    : Patrick Haller [Thu, 1999/11/25 23:00]
- *****************************************************************************/
-
-ODINFUNCTION1(PFN,OS2WSASetBlockingHook,
-              PFN,lpBlockFunc)
-{
-  return(WSASetBlockingHook(lpBlockFunc));
-}
-
-
-/*****************************************************************************
- * Name      :
- * Purpose   :
- * Parameters:
- * Variables :
- * Result    :
- * Remark    :
- * Status    : UNTESTED STUB
- *
- * Author    : Patrick Haller [Thu, 1999/11/25 23:00]
- *****************************************************************************/
-
-ODINFUNCTION0(int,OS2WSACancelBlockingCall)
-{
-  return(WSACancelBlockingCall());
-}
-
-
-/*****************************************************************************
- * Name      :
- * Purpose   :
- * Parameters:
- * Variables :
- * Result    :
- * Remark    :
- * Status    : UNTESTED STUB
- *
- * Author    : Patrick Haller [Thu, 1999/11/25 23:00]
- *****************************************************************************/
-
-ODINFUNCTION6(LHANDLE,OS2WSAAsyncGetServByName,
-              HWND,hWnd,
-              u_int,wMsg,
-              const char *,name,
-              const char *,proto,
-              char *,buf,
-              int,buflen)
-{
-  int   rc;
-  HWND  hwndOS2 = Win32ToOS2Handle(hWnd);
-  ULONG ulNewID;
-
-  if (hwndRelay == NULL) // already initialized ?
-    hwndRelay = RelayInitialize(hwndOS2);
-
-  // add entry to list, we need to store both our temp buffer and the apps buffer
-  ulNewID = RelayAlloc(hWnd,
-                       wMsg,
-                       ASYNCREQUEST_GETSERVBYNAME,
-                       FALSE,
-                       buf);
-
-  // call pmwsock function, will fill our temp buffer
-  rc = WSAAsyncGetServByName(hwndRelay,
-                              ulNewID,
-                              name,
-                              proto,
-                              buf,
-                              buflen);
-
-  // if an error occurs, free the allocated relay entry
-  if (rc == SOCKET_ERROR)
-    RelayFree(ulNewID);
-
-  return (rc);
-}
-
-
-/*****************************************************************************
- * Name      :
- * Purpose   :
- * Parameters:
- * Variables :
- * Result    :
- * Remark    :
- * Status    : UNTESTED STUB
- *
- * Author    : Patrick Haller [Thu, 1999/11/25 23:00]
- *****************************************************************************/
-
-ODINFUNCTION6(LHANDLE,OS2WSAAsyncGetServByPort,
-              HWND,hWnd,
-              u_int,wMsg,
-              int,port,
-              const char *,proto,
-              char *,buf,
-              int,buflen)
-{
-  int   rc;
-  HWND  hwndOS2 = Win32ToOS2Handle(hWnd);
-  ULONG ulNewID;
-
-  if (hwndRelay == NULL) // already initialized ?
-    hwndRelay = RelayInitialize(hwndOS2);
-
-  // add entry to list, we need to store both our temp buffer and the apps buffer
-  ulNewID = RelayAlloc(hWnd,
-                       wMsg,
-                       ASYNCREQUEST_GETSERVBYPORT,
-                       FALSE,
-                       buf);
-
-  // call pmwsock function, will fill our temp buffer
-  rc = WSAAsyncGetServByPort(hwndRelay,
-                             ulNewID,
-                             port,
-                             proto,
-                             buf,
-                             buflen);
-
-  // if an error occurs, free the allocated relay entry
-  if (rc == SOCKET_ERROR)
-    RelayFree(ulNewID);
-
-  return rc;
-}
-
-
-/*****************************************************************************
- * Name      :
- * Purpose   :
- * Parameters:
- * Variables :
- * Result    :
- * Remark    :
- * Status    : UNTESTED STUB
- *
- * Author    : Patrick Haller [Thu, 1999/11/25 23:00]
- *****************************************************************************/
-
-ODINFUNCTION5(LHANDLE,OS2WSAAsyncGetProtoByName,
-              HWND,hWnd,
-              u_int,wMsg,
-              const char *,name,
-              char *,buf,
-              int,buflen)
-{
-  int   rc;
-  HWND  hwndOS2 = Win32ToOS2Handle(hWnd);
-  ULONG ulNewID;
-
-  if (hwndRelay == NULL) // already initialized ?
-    hwndRelay = RelayInitialize(hwndOS2);
-
-  // add entry to list, we need to store both our temp buffer and the apps buffer
-  ulNewID = RelayAlloc(hWnd,
-                       wMsg,
-                       ASYNCREQUEST_GETPROTOBYNAME,
-                       FALSE,
-                       buf);
-
-  // call pmwsock function, will fill our temp buffer
-  rc = WSAAsyncGetProtoByName(hwndRelay,
-                              ulNewID,
-                              name,
-                              buf,
-                              buflen);
-
-  // if an error occurs, free the allocated relay entry
-  if (rc == SOCKET_ERROR)
-    RelayFree(ulNewID);
-
-  return (rc);
-}
-
-
-/*****************************************************************************
- * Name      :
- * Purpose   :
- * Parameters:
- * Variables :
- * Result    :
- * Remark    :
- * Status    : UNTESTED STUB
- *
- * Author    : Patrick Haller [Thu, 1999/11/25 23:00]
- *****************************************************************************/
-
-ODINFUNCTION5(LHANDLE,OS2WSAAsyncGetProtoByNumber,
-              HWND,hWnd,
-              u_int,wMsg,
-              int,number,
-              char *,buf,
-              int,buflen)
-{
-  int   rc;
-  HWND  hwndOS2 = Win32ToOS2Handle(hWnd);
-  ULONG ulNewID;
-
-  if (hwndRelay == NULL) // already initialized ?
-    hwndRelay = RelayInitialize(hwndOS2);
-
-  // add entry to list, we need to store both our temp buffer and the apps buffer
-  ulNewID = RelayAlloc(hWnd,
-                       wMsg,
-                       ASYNCREQUEST_GETPROTOBYNUMBER,
-                       FALSE,
-                       buf);
-
-  // call pmwsock function, will fill our temp buffer
-  rc = WSAAsyncGetProtoByNumber(hwndRelay,
-                                ulNewID,
-                                number,
-                                buf,
-                                buflen);
-
-  // if an error occurs, free the allocated relay entry
-  if (rc == SOCKET_ERROR)
-    RelayFree(ulNewID);
-
-  return rc;
-}
-
-
-/*****************************************************************************
- * Name      :
- * Purpose   :
- * Parameters:
- * Variables :
- * Result    :
- * Remark    :
- * Status    : UNTESTED STUB
- *
- * Author    : Patrick Haller [Thu, 1999/11/25 23:00]
- *****************************************************************************/
-
-ODINFUNCTION5(LHANDLE,OS2WSAAsyncGetHostByName,
-              HWND,hWnd,
-              u_int,wMsg,
-              const char *,name,
-              char *,buf,
-              int,buflen)
-{
-  int   rc;
-  HWND  hwndOS2 = Win32ToOS2Handle(hWnd);
-  ULONG ulNewID;
-
-  dprintf(("WSAAsyncGetHostByName %s", name));
-
-  if (hwndRelay == NULL) // already initialized ?
-    hwndRelay = RelayInitialize(hwndOS2);
-
-  // add entry to list, we need to store both our temp buffer and the apps buffer
-  ulNewID = RelayAlloc(hWnd,
-                       wMsg,
-                       ASYNCREQUEST_GETHOSTBYNAME,
-                       FALSE,
-                       (PVOID)buf, (PVOID)buflen);
-
-  // call pmwsock function, will fill our temp buffer
-  rc = WSAAsyncGetHostByName(hwndRelay,
-                             ulNewID,
-                             name,
-                             buf,
-                             buflen);
-
-  // if an error occurs, free the allocated relay entry
-  if (rc == SOCKET_ERROR)
-    RelayFree(ulNewID);
-
-  return rc;
-}
-
-
-/*****************************************************************************
- * Name      :
- * Purpose   :
- * Parameters:
- * Variables :
- * Result    :
- * Remark    :
- * Status    : UNTESTED STUB
- *
- * Author    : Patrick Haller [Thu, 1999/11/25 23:00]
- *****************************************************************************/
-
-ODINFUNCTION7(LHANDLE,OS2WSAAsyncGetHostByAddr,
-              HWND,hWnd,
-              u_int,wMsg,
-              const char *,addr,
-              int,len,
-              int,type,
-              char *,buf,
-              int,buflen)
-{
-  int   rc;
-  HWND  hwndOS2 = Win32ToOS2Handle(hWnd);
-  ULONG ulNewID;
-
-  if (hwndRelay == NULL) // already initialized ?
-    hwndRelay = RelayInitialize(hwndOS2);
-
-  // add entry to list, we need to store both our temp buffer and the apps buffer
-  ulNewID = RelayAlloc(hWnd,
-                       wMsg,
-                       ASYNCREQUEST_GETHOSTBYADDR,
-                       FALSE,
-                       buf);
-
-  // call pmwsock function, will fill our temp buffer
-  rc = WSAAsyncGetHostByAddr(hwndRelay,
-                             ulNewID,
-                             addr,
-                             len,
-                             type,
-                             buf,
-                             buflen);
-
-  // if an error occurs, free the allocated relay entry
-  if (rc == SOCKET_ERROR)
-    RelayFree(ulNewID);
-
-  return (rc);
-}
-
-
-/*****************************************************************************
- * Name      :
- * Purpose   :
- * Parameters:
- * Variables :
- * Result    :
- * Remark    :
- * Status    : UNTESTED STUB
- *
- * Author    : Patrick Haller [Thu, 1999/11/25 23:00]
- *****************************************************************************/
-
-ODINFUNCTION1(int,OS2WSACancelAsyncRequest,
-              LHANDLE,hAsyncTaskHandle)
-{
-  return(WSACancelAsyncRequest(hAsyncTaskHandle));
-}
-
-
-/*****************************************************************************
- * Name      :
- * Purpose   :
- * Parameters:
- * Variables :
- * Result    :
- * Remark    :
- * Status    : UNTESTED STUB
- *
- * Author    : Patrick Haller [Thu, 1999/11/25 23:00]
- *****************************************************************************/
-
-ODINFUNCTION4(int,OS2WSAAsyncSelect,
-              SOCKET,s,
-              HWND,hWnd,
-              u_int,wMsg,
-              long,lEvent)
-{
-  int   rc;
-//  int   iError;
-  HWND  hwndOS2 = Win32ToOS2Handle(hWnd);
-  ULONG ulNewID;
-
-  if (hwndRelay == NULL) // already initialized ?
-    hwndRelay = RelayInitialize(hwndOS2);
-
-  /* @@@PH: our source window doesn't seem to have an anchor block.
-            Docs suggest we've missed to call WinInitialize on the
-            caller thread.
-
-            Cause however is the Open32 handle is (of course!) invalid
-            in plain PM Window Manager! -> use DAPWSOCK
-
-            Unfortunately, DAPWSOCK calls WinQueryAnchorBlock(hOpen32), too.
-            So, we're stuck until I resolve hWnd to it's valid PM
-            counterpart.
-
-            new problem: we've ultimately got to use PostMessageA instead
-            anything else. => create invisible msg relay window:
-            - hMsg = registerMessage(hWnd, wMsg)
-            - call WSAAsyncSelect with object window handle
-            - overwrite hWnd relay for "same handles"
-   */
-
-  // add event to list or remove any list entry in case of WSAAsyncSelect(hwnd,0,0)
-  if ( (wMsg == 0) && (lEvent == 0) )
-  {
-    // remove entry from list
-    RelayFreeByHwnd(hWnd);
-  }
-  else
-    // add entry to list
-    ulNewID = RelayAlloc(hWnd,
-                         wMsg,
-                         ASYNCREQUEST_SELECT,
-			 FALSE); //SvL: allow multiple selects -> pmwsock should fail if it not allowed
-//                         TRUE);
-
-  rc = WSAAsyncSelect(s,
-                      hwndRelay,
-                      ulNewID,
-                      lEvent);
-
-  // if an error occurs, free the allocated relay entry
-  if (rc == SOCKET_ERROR)
-    RelayFree(ulNewID);
-
-  return (rc);
-}
+    LPWSINFO pwsi = WINSOCK_GetIData();
+
+    if( pwsi )
+    {
+	struct protoent * proto;
+	if( (proto = getprotobyname((char *)name)) != NULL ) {
+	    	if(WS_dup_pe(pwsi, proto)) {
+			WSASetLastError(NO_ERROR);
+			return pwsi->pe;
+	    	}
+	    	else 	WSASetLastError(WSAENOBUFS);
+	}
+	else 	WSASetLastError((h_errno < 0) ? wsaErrno() : wsaHerrno());
+    }
+    else WSASetLastError(WSANOTINITIALISED);
+    return NULL;
+}
+//******************************************************************************
+//******************************************************************************
Index: trunk/src/wsock32/wsock32.def
===================================================================
--- trunk/src/wsock32/wsock32.def	(revision 3228)
+++ trunk/src/wsock32/wsock32.def	(revision 3229)
@@ -1,3 +1,3 @@
-; $Id: wsock32.def,v 1.18 2000-03-22 20:11:03 sandervl Exp $
+; $Id: wsock32.def,v 1.19 2000-03-24 19:28:10 sandervl Exp $
 
 ;Created by BLAST for IBM's compiler
@@ -48,25 +48,25 @@
 ; ----------------------------
 
-   WSAAsyncSelect              = _OS2WSAAsyncSelect@16                    @101
-   WSAAsyncGetHostByAddr       = _OS2WSAAsyncGetHostByAddr@28             @102
-   WSAAsyncGetHostByName       = _OS2WSAAsyncGetHostByName@20             @103
-   WSAAsyncGetProtoByNumber    = _OS2WSAAsyncGetProtoByNumber@20          @104
-   WSAAsyncGetProtoByName      = _OS2WSAAsyncGetProtoByName@20            @105
-   WSAAsyncGetServByPort       = _OS2WSAAsyncGetServByPort@24             @106
-   WSAAsyncGetServByName       = _OS2WSAAsyncGetServByName@24             @107
-   WSACancelAsyncRequest       = _OS2WSACancelAsyncRequest@4              @108
-   WSASetBlockingHook          = _OS2WSASetBlockingHook@4                 @109
-   WSAUnhookBlockingHook       = _OS2WSAUnhookBlockingHook@0              @110
-   WSAGetLastError             = _OS2WSAGetLastError@0                    @111
-   WSASetLastError             = _OS2WSASetLastError@4                    @112
-   WSACancelBlockingCall       = _OS2WSACancelBlockingCall@0              @113
-   WSAIsBlocking               = _OS2WSAIsBlocking@0                      @114
-   WSAStartup                  = _OS2WSAStartup@8                         @115
-   WSACleanup                  = _OS2WSACleanup@0                         @116
-   __WSAFDIsSet                = _OS2__WSAFDIsSet@8                       @151
+   WSAAsyncSelect              = _WSAAsyncSelect@16                    @101
+   WSAAsyncGetHostByAddr       = _WSAAsyncGetHostByAddr@28             @102
+   WSAAsyncGetHostByName       = _WSAAsyncGetHostByName@20             @103
+   WSAAsyncGetProtoByNumber    = _WSAAsyncGetProtoByNumber@20          @104
+   WSAAsyncGetProtoByName      = _WSAAsyncGetProtoByName@20            @105
+   WSAAsyncGetServByPort       = _WSAAsyncGetServByPort@24             @106
+   WSAAsyncGetServByName       = _WSAAsyncGetServByName@24             @107
+   WSACancelAsyncRequest       = _WSACancelAsyncRequest@4              @108
+   WSASetBlockingHook          = _WSASetBlockingHook@4                 @109
+   WSAUnhookBlockingHook       = _WSAUnhookBlockingHook@0              @110
+   WSAGetLastError             = _WSAGetLastError@0                    @111
+   WSASetLastError             = _WSASetLastError@4                    @112
+   WSACancelBlockingCall       = _WSACancelBlockingCall@0              @113
+   WSAIsBlocking               = _WSAIsBlocking@0                      @114
+   WSAStartup                  = _WSAStartup@8                         @115
+   WSACleanup                  = _WSACleanup@0                         @116
+   __WSAFDIsSet                = ___WSAFDIsSet@8                       @151
 
    rcmd                        = _OS2rcmd@24                              @1102
    rexec                       = _OS2rexec@24                             @1103
-   WSARecvEx                   = _OS2WSARecvEx@16                         @1107
+   WSARecvEx                   = _WSARecvEx@16                         @1107
    s_perror                    = _OS2s_perror@8                           @1108
 
Index: trunk/src/wsock32/wsock32.h
===================================================================
--- trunk/src/wsock32/wsock32.h	(revision 3228)
+++ trunk/src/wsock32/wsock32.h	(revision 3229)
@@ -1,3 +1,3 @@
-// $Id: wsock32.h,v 1.13 2000-03-22 20:11:04 sandervl Exp $
+/* $Id: wsock32.h,v 1.14 2000-03-24 19:28:11 sandervl Exp $ */
 
 /* WSOCK32.H--definitions & conversions for Odin's wsock32.dll.
@@ -16,13 +16,138 @@
 #define _WINSOCK32CONST_
 
+#define TCPV40HDRS
+#include <sys\socket.h>
+#include <sys\ioctl.h>
+#include <netdb.h>
+#include <netinet\in.h>
+#include <netinet\tcp.h>
+#include <nerrno.h>
+#include <sys\time.h>
+
+#include <odinwrap.h>
+
+/*
+ * Socket state bits.
+ */
+#define SS_NOFDREF              0x0001  /* no file table ref any more */
+#define SS_ISCONNECTED          0x0002  /* socket connected to a peer */
+#define SS_ISCONNECTING         0x0004  /* in process of connecting to peer */
+#define SS_ISDISCONNECTING      0x0008  /* in process of disconnecting */
+#define SS_CANTSENDMORE         0x0010  /* can't send more data to peer */
+#define SS_CANTRCVMORE          0x0020  /* can't receive more data from peer */
+#define SS_RCVATMARK            0x0040  /* at mark on input */
+
+#define SS_NBIO                 0x0100  /* non-blocking ops */
+#define SS_ASYNC                0x0200  /* async i/o notify */
+#define SS_ISCONFIRMING         0x0400  /* deciding to accept connection req */
+
+#define SS_INCOMP               0x0800  /* unaccepted, incomplete connection */
+#define SS_COMP                 0x1000  /* unaccepted, complete connection */
+#define SS_ISDISCONNECTED       0x2000  /* socket disconnected from peer */
+
+//socketopt options
+#define SO_DONTLINGER   (u_int)(~SO_LINGER)
+
+#define WSAMAKESELECTREPLY(event,error)     MAKELONG(event,error)
+
+// WSAAsyncSelect flags
+#define FD_READ         0x01
+#define FD_WRITE        0x02
+#define FD_OOB          0x04
+#define FD_ACCEPT       0x08
+#define FD_CONNECT      0x10
+#define FD_CLOSE        0x20
+
+#define SOCKET_ERROR 		-1
+#define NO_ERROR		0
+
+#define WSABASEERR              10000
+
+#define WSAEINTR                (WSABASEERR+4)
+#define WSAEBADF                (WSABASEERR+9)
+#define WSAEACCES               (WSABASEERR+13)
+#define WSAEFAULT               (WSABASEERR+14)
+#define WSAEINVAL               (WSABASEERR+22)
+#define WSAEMFILE               (WSABASEERR+24)
+
+#define WSAEWOULDBLOCK          (WSABASEERR+35)
+#define WSAEINPROGRESS          (WSABASEERR+36)
+#define WSAEALREADY             (WSABASEERR+37)
+#define WSAENOTSOCK             (WSABASEERR+38)
+#define WSAEDESTADDRREQ         (WSABASEERR+39)
+#define WSAEMSGSIZE             (WSABASEERR+40)
+#define WSAEPROTOTYPE           (WSABASEERR+41)
+#define WSAENOPROTOOPT          (WSABASEERR+42)
+#define WSAEPROTONOSUPPORT      (WSABASEERR+43)
+#define WSAESOCKTNOSUPPORT      (WSABASEERR+44)
+#define WSAEOPNOTSUPP           (WSABASEERR+45)
+#define WSAEPFNOSUPPORT         (WSABASEERR+46)
+#define WSAEAFNOSUPPORT         (WSABASEERR+47)
+#define WSAEADDRINUSE           (WSABASEERR+48)
+#define WSAEADDRNOTAVAIL        (WSABASEERR+49)
+#define WSAENETDOWN             (WSABASEERR+50)
+#define WSAENETUNREACH          (WSABASEERR+51)
+#define WSAENETRESET            (WSABASEERR+52)
+#define WSAECONNABORTED         (WSABASEERR+53)
+#define WSAECONNRESET           (WSABASEERR+54)
+#define WSAENOBUFS              (WSABASEERR+55)
+#define WSAEISCONN              (WSABASEERR+56)
+#define WSAENOTCONN             (WSABASEERR+57)
+#define WSAESHUTDOWN            (WSABASEERR+58)
+#define WSAETOOMANYREFS         (WSABASEERR+59)
+#define WSAETIMEDOUT            (WSABASEERR+60)
+#define WSAECONNREFUSED         (WSABASEERR+61)
+#define WSAELOOP                (WSABASEERR+62)
+#define WSAENAMETOOLONG         (WSABASEERR+63)
+#define WSAEHOSTDOWN            (WSABASEERR+64)
+#define WSAEHOSTUNREACH         (WSABASEERR+65)
+#define WSAENOTEMPTY            (WSABASEERR+66)
+#define WSAEPROCLIM             (WSABASEERR+67)
+#define WSAEUSERS               (WSABASEERR+68)
+#define WSAEDQUOT               (WSABASEERR+69)
+#define WSAESTALE               (WSABASEERR+70)
+#define WSAEREMOTE              (WSABASEERR+71)
+#define WSASYSNOTREADY          (WSABASEERR+91)
+#define WSAVERNOTSUPPORTED      (WSABASEERR+92)
+#define WSANOTINITIALISED       (WSABASEERR+93)
+#define WSAHOST_NOT_FOUND       (WSABASEERR+1001)
+#define WSATRY_AGAIN            (WSABASEERR+1002)
+#define WSANO_RECOVERY          (WSABASEERR+1003)
+#define WSANO_DATA              (WSABASEERR+1004)
+#define WSANO_ADDRESS           WSANO_DATA
+
+typedef u_int           SOCKET;
+
+#define FD_SETSIZE      64
+
+#pragma pack(1)
+
+#define WSADESCRIPTION_LEN      256
+#define WSASYS_STATUS_LEN       128
+
+typedef struct WSAData {
+        USHORT              wVersion;
+        USHORT              wHighVersion;
+        char                szDescription[WSADESCRIPTION_LEN+1];
+        char                szSystemStatus[WSASYS_STATUS_LEN+1];
+        unsigned short      iMaxSockets;
+        unsigned short      iMaxUdpDg;
+        char *              lpVendorInfo;
+} WSADATA;
+typedef WSADATA *PWSADATA;
+typedef WSADATA *LPWSADATA;
+
+typedef struct ws_fd_set {
+        u_int   fd_count;
+        SOCKET  fd_array[FD_SETSIZE];
+} _ws_fd_set;
 
 /*
  * Structure used for manipulating linger option.
  */
-struct  Wlinger {
+typedef struct  ws_linger {
         u_short l_onoff;                /* option on/off */
         u_short l_linger;               /* linger time */
-};
-
+} _ws_linger;
 
 /*
@@ -32,64 +157,82 @@
  */
 
-struct  Whostent {
-        char     * h_name;           /* official name of host */
-        char     *  * h_aliases;  /* alias list */
-        short   h_addrtype;             /* host address type */
-        short   h_length;               /* length of address */
-        char     *  * h_addr_list; /* list of addresses */
-#define h_addr  h_addr_list[0]          /* address, for backward compat */
-};
-
-/*
- * It is assumed here that a network number
- * fits in 32 bits.
- */
-struct  Wnetent {
-        char     * n_name;           /* official name of net */
-        char     *  * n_aliases;  /* alias list */
-        short   n_addrtype;             /* net address type */
-        u_long  n_net;                  /* network # */
-};
-typedef struct Whostent WHOSTENT;
-typedef WHOSTENT *PWHOSTENT;
-
-struct  Wservent {
-        char     * s_name;           /* official service name */
-        char     *  * s_aliases;  /* alias list */
-        short   s_port;                 /* port # */
-        char     * s_proto;          /* protocol to use */
-};
-typedef struct Wservent WSERVENT;
-typedef WSERVENT *PWSERVENT;
-
-struct  Wprotoent {
-        char     * p_name;           /* official protocol name */
-        char     *  * p_aliases;  /* alias list */
-        short   p_proto;                /* protocol # */
-};
-typedef struct Wprotoent WPROTOENT;
-typedef WPROTOENT *PWPROTOENT;
-
-typedef struct tagWsockThreadData
-{
-  int              dwLastError; // Get/SetLastError
-  struct Whostent  whsnt;       // database conversion buffers
-  struct Wservent  wsvnt;
-  struct Wprotoent wptnt;
-  struct Wnetent   wntnt;
-  struct Wlinger   wlinger;
-} WSOCKTHREADDATA, *PWSOCKTHREADDATA;
-
-// internal prototype
-PWSOCKTHREADDATA iQueryWsockThreadData(void);
-
+typedef struct ws_hostent
+{
+        char *  h_name;         /* official name of host */
+        char ** h_aliases;      /* alias list */
+        INT16   h_addrtype;     /* host address type */
+        INT16   h_length;       /* length of address */
+        char ** h_addr_list;    /* list of addresses from name server */
+} _ws_hostent;
+
+typedef struct ws_protoent
+{
+        char *  p_name;         /* official protocol name */
+        char ** p_aliases;      /* alias list */
+        INT16   p_proto;        /* protocol # */
+} _ws_protoent;
+
+typedef struct ws_servent 
+{
+        char *  s_name;         /* official service name */
+        char ** s_aliases;      /* alias list */
+        INT16   s_port;         /* port # */
+        char *  s_proto;        /* protocol to use */
+} _ws_servent;
+
+typedef struct ws_netent
+{
+        char *  n_name;         /* official name of net */
+        char ** n_aliases;      /* alias list */
+        INT16   n_addrtype;     /* net address type */
+        INT     n_net;          /* network # */
+} _ws_netent;
+
+#pragma pack()
+
+#define WS_MAX_SOCKETS_PER_PROCESS      128     /* reasonable guess */
+#define WS_MAX_UDP_DATAGRAM             1024
+
+#define WSI_BLOCKINGCALL        0x00000001      /* per-thread info flags */
+#define WSI_BLOCKINGHOOK        0x00000002      /* 32-bit callback */
+
+typedef struct _WSINFO
+{
+  DWORD			dwThisThread;
+  struct _WSINFO       *lpNextIData;
+
+  unsigned		flags;
+  INT16			num_startup;		/* reference counter */
+  INT16			num_async_rq;
+  INT16			last_free;		/* entry in the socket table */
+  USHORT		buflen;
+  char*			buffer;			/* allocated from char * heap */
+  struct ws_hostent	*he;
+  int			helen;
+  struct ws_servent	*se;
+  int			selen;
+  struct ws_protoent	*pe;
+  int			pelen;
+  char*			dbuffer;		/* buffer for dummies (32 bytes) */
+
+  DWORD			blocking_hook;
+} WSINFO, *LPWSINFO;
+
+void WIN32API WSASetLastError(int iError);
+int  WIN32API WSAGetLastError(void);
+int  WIN32API WSAAsyncSelect(SOCKET s, HWND hWnd, u_int wMsg, long lEvent);
+BOOL WIN32API WSAIsBlocking(void);
 
 extern BOOL fWSAInitialized;
 
-void WIN32API OS2WSASetLastError(int iError);
-
-int  WIN32API OS2WSAGetLastError(void);
-
-BOOL WIN32API OS2WSAIsBlocking(void);
+UINT wsaErrno();
+UINT wsaHerrno();
+
+#define CURRENT_THREAD -1
+void WSASetBlocking(BOOL fBlock, HANDLE tid = CURRENT_THREAD);
+
+void WINSOCK_DeleteIData(void);
+BOOL WINSOCK_CreateIData(void);
+LPWSINFO WINSOCK_GetIData(HANDLE tid = CURRENT_THREAD);
 
 #endif  /* _WINSOCK32CONST_ */
Index: trunk/src/wsock32/wsock32rsrc.orc
===================================================================
--- trunk/src/wsock32/wsock32rsrc.orc	(revision 3228)
+++ trunk/src/wsock32/wsock32rsrc.orc	(revision 3229)
@@ -1,3 +1,3 @@
-/* $Id: wsock32rsrc.orc,v 1.1 2000-03-06 23:39:20 bird Exp $ */
+/* $Id: wsock32rsrc.orc,v 1.2 2000-03-24 19:28:12 sandervl Exp $ */
 
 #include "winuser.h"
