/*
 * based on Windows Sockets 1.1 specs
 * (ftp.microsoft.com:/Advsys/winsock/spec11/WINSOCK.TXT)
 * 
 * (C) 1993,1994 John Brezak, Erik Bos.
 */
 
#include <stdio.h>
#include <string.h>
#include <signal.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/ioctl.h>
#if defined(__svr4__)
#include <sys/filio.h>
#include <sys/ioccom.h>
#endif
#include <sys/msg.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <fcntl.h>
#include <errno.h>
#include <netdb.h>
#include <unistd.h>

#include "winsock.h"
#include "global.h"
#include "stddebug.h"
#include "debug.h"

#ifdef _SCO_DS
#define _IOR _IOSR
#define _IOW _IOSW
#endif

static WORD wsa_errno;
static int wsa_initted;
static key_t wine_key = 0;
static FARPROC16 BlockFunction;
static fd_set fd_in_use;

extern int h_errno;

struct ipc_packet {
	long	mtype;
	HANDLE	handle;
	HWND	hWnd;
	WORD	wMsg;
	LONG	lParam;
};

#ifndef WINELIB
#pragma pack(1)
#endif

#define WINSOCK_MAX_SOCKETS	256
#define WINSOCK_MAX_UDPDG	1024

/* we are out by two with the following, is it due to byte alignment?
 * #define IPC_PACKET_SIZE (sizeof(struct ipc_packet) - sizeof(long)) 
 */
#define IPC_PACKET_SIZE (sizeof(struct ipc_packet) - sizeof(long) - 2)
/*#define MTYPE 0xb0b0eb05*/
#define MTYPE 0x30b0eb05

/* These structures are Win16 only */

struct WIN_hostent  {
	SEGPTR	h_name WINE_PACKED;		/* official name of host */
	SEGPTR	h_aliases WINE_PACKED;	/* alias list */
	INT	h_addrtype WINE_PACKED;		/* host address type */
	INT	h_length WINE_PACKED;		/* length of address */
	char	**h_addr_list WINE_PACKED;	/* list of addresses from name server */
	char	*names[2];
	char    hostname[200];
};

struct	WIN_protoent {
	SEGPTR	p_name WINE_PACKED;		/* official protocol name */
	SEGPTR	p_aliases WINE_PACKED;	/* alias list */
	INT	p_proto WINE_PACKED;		/* protocol # */
};

struct	WIN_servent {
	SEGPTR	s_name WINE_PACKED;		/* official service name */
	SEGPTR	s_aliases WINE_PACKED;	/* alias list */
	INT	s_port WINE_PACKED;		/* port # */
	SEGPTR	s_proto WINE_PACKED;		/* protocol to use */
};

typedef struct WinSock_fd_set {
	u_short fd_count;               /* how many are SET? */
	SOCKET  fd_array[FD_SETSIZE];   /* an array of SOCKETs */
} WinSock_fd_set;
                
struct WinSockHeap {
	char	ntoa_buffer[32];

	struct	WIN_hostent hostent_addr;
	struct	WIN_hostent hostent_name;
	struct	WIN_protoent protoent_name;
	struct	WIN_protoent protoent_number;
	struct	WIN_servent servent_name;
	struct	WIN_servent servent_port;

	struct	WIN_hostent WSAhostent_addr;
	struct	WIN_hostent WSAhostent_name;
	struct	WIN_protoent WSAprotoent_name;
	struct	WIN_protoent WSAprotoent_number;	
	struct	WIN_servent WSAservent_name;
	struct	WIN_servent WSAservent_port;
	/* 8K scratch buffer for aliases and friends are hopefully enough */
	char scratch[8192];
};
static struct WinSockHeap *Heap;
static HANDLE HeapHandle;
#ifndef WINELIB32
static int ScratchPtr;
#endif

#ifndef WINELIB
#define GET_SEG_PTR(x)	MAKELONG((int)((char*)(x)-(char*)Heap),	\
							GlobalHandleToSel(HeapHandle))
#else
#define GET_SEG_PTR(x)	((SEGPTR)x)
#endif

#ifndef WINELIB
#pragma pack(4)
#endif

#define dump_sockaddr(a) \
	fprintf(stderr, "sockaddr_in: family %d, address %s, port %d\n", \
			((struct sockaddr_in *)a)->sin_family, \
			inet_ntoa(((struct sockaddr_in *)a)->sin_addr), \
			ntohs(((struct sockaddr_in *)a)->sin_port))

#ifndef WINELIB32
static void ResetScratch()
{
	ScratchPtr=0;
}

static void *scratch_alloc(int size)
{
	char *ret;
	if(ScratchPtr+size > sizeof(Heap->scratch))
		return 0;
	ret = Heap->scratch + ScratchPtr;
	ScratchPtr += size;
	return ret;
}

static SEGPTR scratch_strdup(char * s)
{
	char *ret=scratch_alloc(strlen(s)+1);
	strcpy(ret,s);
	return GET_SEG_PTR(ret);
}
#endif

static WORD wsaerrno(void)
{
#ifdef DEBUG_WINSOCK
#ifndef sun
#if defined(__FreeBSD__)
                fprintf(stderr, "winsock: errno %d, (%s).\n", 
                			errno, sys_errlist[errno]);
#else
                fprintf(stderr, "winsock: errno %d\n", errno);
#endif
#else
                fprintf(stderr, "winsock: errno %d\n", errno);
#endif
#endif

        switch(errno)
        {
	case EINTR:		return WSAEINTR;
	case EBADF:		return WSAEBADF;
	case EACCES:		return WSAEACCES;
	case EFAULT:		return WSAEFAULT;
	case EINVAL:		return WSAEINVAL;
	case EMFILE:		return WSAEMFILE;
	case EWOULDBLOCK:	return WSAEWOULDBLOCK;
	case EINPROGRESS:	return WSAEINPROGRESS;
	case EALREADY:		return WSAEALREADY;
	case ENOTSOCK:		return WSAENOTSOCK;
	case EDESTADDRREQ:	return WSAEDESTADDRREQ;
	case EMSGSIZE:		return WSAEMSGSIZE;
	case EPROTOTYPE:	return WSAEPROTOTYPE;
	case ENOPROTOOPT:	return WSAENOPROTOOPT;
	case EPROTONOSUPPORT:	return WSAEPROTONOSUPPORT;
	case ESOCKTNOSUPPORT:	return WSAESOCKTNOSUPPORT;
	case EOPNOTSUPP:	return WSAEOPNOTSUPP;
	case EPFNOSUPPORT:	return WSAEPFNOSUPPORT;
	case EAFNOSUPPORT:	return WSAEAFNOSUPPORT;
	case EADDRINUSE:	return WSAEADDRINUSE;
	case EADDRNOTAVAIL:	return WSAEADDRNOTAVAIL;
	case ENETDOWN:		return WSAENETDOWN;
	case ENETUNREACH:	return WSAENETUNREACH;
	case ENETRESET:		return WSAENETRESET;
	case ECONNABORTED:	return WSAECONNABORTED;
	case ECONNRESET:	return WSAECONNRESET;
	case ENOBUFS:		return WSAENOBUFS;
	case EISCONN:		return WSAEISCONN;
	case ENOTCONN:		return WSAENOTCONN;
	case ESHUTDOWN:		return WSAESHUTDOWN;
	case ETOOMANYREFS:	return WSAETOOMANYREFS;
	case ETIMEDOUT:		return WSAETIMEDOUT;
	case ECONNREFUSED:	return WSAECONNREFUSED;
	case ELOOP:		return WSAELOOP;
	case ENAMETOOLONG:	return WSAENAMETOOLONG;
	case EHOSTDOWN:		return WSAEHOSTDOWN;
	case EHOSTUNREACH:	return WSAEHOSTUNREACH;
	case ENOTEMPTY:		return WSAENOTEMPTY;
#ifdef EPROCLIM
	case EPROCLIM:		return WSAEPROCLIM;
#endif
#ifdef EUSERS
	case EUSERS:		return WSAEUSERS;
#endif
#ifdef EDQUOT
	case EDQUOT:		return WSAEDQUOT;
#endif
	case ESTALE:		return WSAESTALE;
	case EREMOTE:		return WSAEREMOTE;
/* just in case we ever get here and there are no problems */
	case 0:			return 0;

        default:
		fprintf(stderr, "winsock: unknown errorno %d!\n", errno);
		return WSAEOPNOTSUPP;
	}
}

static void errno_to_wsaerrno(void)
{
	wsa_errno = wsaerrno();
}


static WORD wsaherrno(void)
{
#if DEBUG_WINSOCK
#ifndef sun
#if defined(__FreeBSD__)
                fprintf(stderr, "winsock: h_errno %d, (%s).\n", 
                			h_errno, sys_errlist[h_errno]);
#else
                fprintf(stderr, "winsock: h_errno %d.\n", h_errno);
		herror("wine: winsock: wsaherrno");
#endif
#else
                fprintf(stderr, "winsock: h_errno %d\n", h_errno);
#endif
#endif

        switch(h_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; 
/* just in case we ever get here and there are no problems */
	case 0:			return 0;


        default:
		fprintf(stderr, "winsock: unknown h_errorno %d!\n", h_errno);
		return WSAEOPNOTSUPP;
	}
}


static void herrno_to_wsaerrno(void)
{
	wsa_errno = wsaherrno();
}


static void convert_sockopt(INT *level, INT *optname)
{
/* $%#%!#! why couldn't they use the same values for both winsock and unix ? */

	switch (*level) {
		case -1: 
			*level = SOL_SOCKET;
			switch (*optname) {
			case 0x01:	*optname = SO_DEBUG;
					break;
			case 0x04:	*optname = SO_REUSEADDR;
					break;
			case 0x08:	*optname = SO_KEEPALIVE;
					break;
			case 0x10:	*optname = SO_DONTROUTE;
					break;
			case 0x20:	*optname = SO_BROADCAST;
					break;
			case 0x80:	*optname = SO_LINGER;
					break;
			case 0x100:	*optname = SO_OOBINLINE;
					break;
			case 0x1001:	*optname = SO_SNDBUF;
					break;
			case 0x1002:	*optname = SO_RCVBUF;
					break;
			case 0x1007:	*optname = SO_ERROR;
					break;
			case 0x1008:	*optname = SO_TYPE;
					break;
			default: 
					fprintf(stderr, "convert_sockopt() unknown optname %d\n", *optname);
					break;
			}
			break;
		case 6:	*optname = IPPROTO_TCP;
	}
}

#ifndef WINELIB
static SEGPTR copy_stringlist(char **list)
{
	SEGPTR *s_list;
	int i;
	for(i=0;list[i];i++)
		;
	s_list = scratch_alloc(sizeof(SEGPTR)*(i+1));
	for(i=0;list[i];i++)
	{
		void *copy = scratch_alloc(strlen(list[i])+1);
		strcpy(copy,list[i]);
		s_list[i]=GET_SEG_PTR(copy);
	}
	s_list[i]=0;
	return GET_SEG_PTR(s_list);
}
	

static void CONVERT_HOSTENT(struct WIN_hostent *heapent, struct hostent *host)
{
	SEGPTR *addr_list;
	int i;
	ResetScratch();
	strcpy(heapent->hostname,host->h_name);
	heapent->h_name = GET_SEG_PTR(heapent->hostname);
	/* Convert aliases. Have to create array with FAR pointers */
	if(!host->h_aliases)
		heapent->h_aliases = 0;
	else
		heapent->h_aliases = copy_stringlist(host->h_aliases);

	heapent->h_addrtype = host->h_addrtype;
	heapent->h_length = host->h_length;
	for(i=0;host->h_addr_list[i];i++)
		;
	addr_list=scratch_alloc(sizeof(SEGPTR)*(i+1));
	heapent->h_addr_list = (char**)GET_SEG_PTR(addr_list);
	for(i=0;host->h_addr_list[i];i++)
	{
		void *addr=scratch_alloc(host->h_length);
		memcpy(addr,host->h_addr_list[i],host->h_length);
		addr_list[i]=GET_SEG_PTR(addr);
	}
	addr_list[i]=0;
}

static void CONVERT_PROTOENT(struct WIN_protoent *heapent, 
	struct protoent *proto)
{
	ResetScratch();
	heapent->p_name= scratch_strdup(proto->p_name);
	heapent->p_aliases=proto->p_aliases ? 
			copy_stringlist(proto->p_aliases) : 0;
	heapent->p_proto = proto->p_proto;
}

static void CONVERT_SERVENT(struct WIN_servent *heapent, struct servent *serv)
{
	ResetScratch();
	heapent->s_name = scratch_strdup(serv->s_name);
	heapent->s_aliases = serv->s_aliases ?
			copy_stringlist(serv->s_aliases) : 0;
	heapent->s_port = serv->s_port;
	heapent->s_proto = scratch_strdup(serv->s_proto);
}
#else
#define CONVERT_HOSTENT(a,b)	memcpy(a, &b, sizeof(a))
#define CONVERT_PROTOENT(a,b)	memcpy(a, &b, sizeof(a))
#define CONVERT_SERVENT(a,b)	memcpy(a, &b, sizeof(a))
#endif

SOCKET WINSOCK_accept(SOCKET s, struct sockaddr *addr, INT *addrlen)
{
	int sock;

	dprintf_winsock(stddeb, "WSA_accept: socket %d, ptr %8x, length %d\n", s, (int) addr, *addrlen);

	if (!wsa_initted) { 
		WSASetLastError(WSANOTINITIALISED);
		return INVALID_SOCKET;
	}

	if ((sock = accept(s, addr, (int *) addrlen)) < 0) {
        	errno_to_wsaerrno();
        	return INVALID_SOCKET;
	}
	return sock;
}

INT WINSOCK_bind(SOCKET s, struct sockaddr *name, INT namelen)
{

	dprintf_winsock(stddeb, "WSA_bind: socket %d, ptr %8x, length %d\n", s, (int) name, namelen);
	dump_sockaddr(name);

	if (!wsa_initted) { 
		WSASetLastError(WSANOTINITIALISED);
		return SOCKET_ERROR;
	}

	if (namelen < sizeof(*name)) {
		WSASetLastError(WSAEFAULT);
		return SOCKET_ERROR;
	}

	/* check the socket family */
	if ( ((struct sockaddr_in *)name)->sin_family != AF_INET ) {
		WSASetLastError(WSAEAFNOSUPPORT);
		return SOCKET_ERROR;
	}

	if (bind(s, name, namelen) < 0) {
		switch(errno) {
		case EBADF:
			WSASetLastError(WSAENOTSOCK);
			break;
		case EADDRNOTAVAIL:
			WSASetLastError(WSAEINVAL);
			break;
		default:
			errno_to_wsaerrno();
			break;
		}
        	return SOCKET_ERROR;
	}
	return 0;
}

INT WINSOCK_closesocket(SOCKET s)
{
	dprintf_winsock(stddeb, "WSA_closesocket: socket %d\n", s);

	if (!wsa_initted) { 
		WSASetLastError(WSANOTINITIALISED);
		return SOCKET_ERROR;
	}

	FD_CLR(s, &fd_in_use);

	if (close(s) < 0) {
		if (errno == EBADF)
			WSASetLastError(WSAENOTSOCK);
		else
        		errno_to_wsaerrno();
        	return SOCKET_ERROR;
	}
	return 0;
}

INT WINSOCK_connect(SOCKET s, struct sockaddr *name, INT namelen)
{
	dprintf_winsock(stddeb, "WSA_connect: socket %d, ptr %8x, length %d\n", s, (int) name, namelen);
	dump_sockaddr(name);

	if (!wsa_initted) { 
		WSASetLastError(WSANOTINITIALISED);
		return SOCKET_ERROR;
	}

	if (connect(s, name, namelen) < 0) {
        	errno_to_wsaerrno();
        	return SOCKET_ERROR;
	}
	return 0;
}

INT WINSOCK_getpeername(SOCKET s, struct sockaddr *name, INT *namelen)
{
	dprintf_winsock(stddeb, "WSA_getpeername: socket: %d, ptr %8x, ptr %8x\n", s, (int) name, *namelen);
	dump_sockaddr(name);

	if (!wsa_initted) { 
		WSASetLastError(WSANOTINITIALISED);
		return SOCKET_ERROR;
	}

	if (getpeername(s, name, (int *) namelen) < 0) {
		if (h_errno < 0) {
        		errno_to_wsaerrno();
		} else {
			herrno_to_wsaerrno();
		}
        	return SOCKET_ERROR;
	}
	return 0;
}

INT WINSOCK_getsockname(SOCKET s, struct sockaddr *name, INT *namelen)
{
	dprintf_winsock(stddeb, "WSA_getsockname: socket: %d, ptr %8x, ptr %8x\n", s, (int) name, (int) *namelen);

	if (!wsa_initted) { 
		WSASetLastError(WSANOTINITIALISED);
		return SOCKET_ERROR;
	}

	if (getsockname(s, name, (int *) namelen) < 0) {
		if (h_errno < 0) {
        		errno_to_wsaerrno();
		} else {
			herrno_to_wsaerrno();
		}
        	return SOCKET_ERROR;
	}
	return 0;
}

INT
WINSOCK_getsockopt(SOCKET s, INT level, INT optname, char *optval, INT *optlen)
{
	dprintf_winsock(stddeb, "WSA_getsockopt: socket: %d, opt %d, ptr %8x, ptr %8x\n", s, level, (int) optval, (int) *optlen);

	if (!wsa_initted) { 
		WSASetLastError(WSANOTINITIALISED);
		return SOCKET_ERROR;
	}

	convert_sockopt(&level, &optname);

	if (getsockopt(s, (int) level, optname, optval, (int *) optlen) < 0) {
		if (errno == EBADF)
			WSASetLastError(WSAENOTSOCK);
		else
        		errno_to_wsaerrno();
        	return SOCKET_ERROR;
	}
	return 0;
}

u_long WINSOCK_htonl(u_long hostlong)
{
	return( htonl(hostlong) );
}         

u_short WINSOCK_htons(u_short hostshort)
{
	return( htons(hostshort) );
}

u_long WINSOCK_inet_addr(char *cp)
{
	return( inet_addr(cp) );
}

char *WINSOCK_inet_ntoa(struct in_addr in)
{
	char *s;

/*	dprintf_winsock(stddeb, "WSA_inet_ntoa: %8lx\n", (int) in);*/

	if ((s = inet_ntoa(in)) == NULL) {
        	errno_to_wsaerrno();
        	return NULL;
	}

	strncpy(Heap->ntoa_buffer, s, sizeof(Heap->ntoa_buffer) );

	return (char *) GET_SEG_PTR(&Heap->ntoa_buffer);
}

INT WINSOCK_ioctlsocket(SOCKET s, u_long cmd, u_long *argp)
{
	long newcmd;
	u_long *newargp;
	char *ctlname;
	dprintf_winsock(stddeb, "WSA_ioctl: socket %d, cmd %lX, ptr %8x\n", s, cmd, (int) argp);

	if (!wsa_initted) { 
		WSASetLastError(WSANOTINITIALISED);
		return SOCKET_ERROR;
	}

	/* Why can't they all use the same ioctl numbers */
	newcmd=cmd;
	newargp=argp;
	ctlname=0;
	if(cmd == _IOR('f',127,u_long))
	{
		ctlname="FIONREAD";
		newcmd=FIONREAD;
	}else 
	if(cmd == _IOW('f',126,u_long) || cmd == _IOR('f',126,u_long))
	{
		ctlname="FIONBIO";
		newcmd=FIONBIO;
	}else
	if(cmd == _IOW('f',125,u_long))
	{
		ctlname="FIOASYNC";
		newcmd=FIOASYNC;
	}

	if(!ctlname)
		fprintf(stderr,"Unknown winsock ioctl. Trying anyway\n");
	else
		dprintf_winsock(stddeb,"Recognized as %s\n", ctlname);
	

	if (ioctl(s, newcmd, newargp) < 0) {
		if (errno == EBADF)
			WSASetLastError(WSAENOTSOCK);
		else
        		errno_to_wsaerrno();
        	return SOCKET_ERROR;
	}
	return 0;
}

INT WINSOCK_listen(SOCKET s, INT backlog)
{
	dprintf_winsock(stddeb, "WSA_listen: socket %d, backlog %d\n", s, backlog);

	if (!wsa_initted) { 
		WSASetLastError(WSANOTINITIALISED);
		return SOCKET_ERROR;
	}

	if (listen(s, backlog) < 0) {
        	errno_to_wsaerrno();
        	return SOCKET_ERROR;
	}
	return 0;
}

u_long WINSOCK_ntohl(u_long netlong)
{
	return( ntohl(netlong) );
}

u_short WINSOCK_ntohs(u_short netshort)
{
	return( ntohs(netshort) );
}

INT WINSOCK_recv(SOCKET s, char *buf, INT len, INT flags)
{
	int length;

	dprintf_winsock(stddeb, "WSA_recv: socket %d, ptr %8x, length %d, flags %d\n", s, (int) buf, len, flags);

	if (!wsa_initted) { 
		WSASetLastError(WSANOTINITIALISED);
		return SOCKET_ERROR;
	}

	if ((length = recv(s, buf, len, flags)) < 0) {
        	errno_to_wsaerrno();
        	return SOCKET_ERROR;
	}
	return length;
}

INT WINSOCK_recvfrom(SOCKET s, char *buf, INT len, INT flags, 
		struct sockaddr *from, int *fromlen)
{
	int length;

	dprintf_winsock(stddeb, "WSA_recvfrom: socket %d, ptr %8lx, length %d, flags %d\n", s, (unsigned long)buf, len, flags);

	if (!wsa_initted) { 
		WSASetLastError(WSANOTINITIALISED);
		return SOCKET_ERROR;
	}

	if ((length = recvfrom(s, buf, len, flags, from, fromlen)) < 0) {
        	errno_to_wsaerrno();
        	return SOCKET_ERROR;
	}
	return length;
}

INT WINSOCK_select(INT nfds, WinSock_fd_set *ws_readfds,
	WinSock_fd_set *ws_writefds, WinSock_fd_set *ws_exceptfds,
	struct timeval *timeout)
{
	int ret;
	int i;
	int count;
	int highfd;
	fd_set readfds,writefds,exceptfds;
	FD_ZERO(&readfds);
	FD_ZERO(&writefds);
	FD_ZERO(&exceptfds);
	
	dprintf_winsock(stddeb, "WSA_select called: nfds %d (ignored), ptr %8lx, ptr %8lx, ptr %8lx\n", nfds, (unsigned long) ws_readfds, (unsigned long) ws_writefds, (unsigned long) ws_exceptfds);

	if (!wsa_initted) { 
		WSASetLastError(WSANOTINITIALISED);
		dprintf_winsock(stddeb, "WSA_select: returning error WSANOTINITIALISED\n");
		return SOCKET_ERROR;
	}
	
/* In some sort of attempt to be BSD-compatible, MS-Winsock accepts and
   discards the nfds parameter.  However, the format of windoze's fd_sets
   is totally different from the BSD standard.  So much for compatibility.
   Hence, we must convert the winsock array-of-ints fd_set to the UNIX
   bitmapped format. */

	if(ws_readfds!=NULL) {
		dprintf_winsock(stddeb, "readfds: (%d) ",ws_readfds->fd_count);
		for(i=0;i<(ws_readfds->fd_count);i++) {
			dprintf_winsock(stddeb, " %d",( (SOCKET *)&(((char *)ws_readfds)[2]) )[i]);
			/*FD_SET(((SOCKET *)&(((char *)ws_readfds)[2]))[i], &readfds);*/
			FD_SET(ws_readfds->fd_array[i], &readfds);
		}
		dprintf_winsock(stddeb, "\n");
	} else {
		dprintf_winsock(stddeb, "readfds: (null)\n");
	}
	if(ws_writefds!=NULL) {
		dprintf_winsock(stddeb, "writefds: (%d) ",ws_writefds->fd_count);
		for(i=0;i<(ws_writefds->fd_count);i++) {
			dprintf_winsock(stddeb, " %d",( (SOCKET *)&(((char *)ws_writefds)[2]) )[i]);
			/*FD_SET(((SOCKET *)&(((char *)ws_writefds)[2]))[i], &writefds);*/
			FD_SET(ws_writefds->fd_array[i], &writefds);
		}
		dprintf_winsock(stddeb, "\n");
	} else {
		dprintf_winsock(stddeb, "writefds: (null)\n");
	}
	if(ws_exceptfds!=NULL) {
		dprintf_winsock(stddeb, "exceptfds: (%d) ",ws_exceptfds->fd_count);
		for(i=0;i<(ws_exceptfds->fd_count);i++) {
			dprintf_winsock(stddeb, " %d",( (SOCKET *)&(((char *)ws_exceptfds)[2]) )[i]);
			/*FD_SET(((SOCKET *)&(((char *)ws_exceptfds)[2]))[i], &exceptfds);*/
			FD_SET(ws_exceptfds->fd_array[i], &exceptfds);
		}
		dprintf_winsock(stddeb, "\n");
	} else {
		dprintf_winsock(stddeb, "exceptfds: (null)\n");
	}
	
	/* Make the select() call */
	dprintf_winsock(stddeb, "WSA_select: calling select()\n");
	highfd=256; /* We should count them, but this works */
	ret=select(highfd, &readfds, &writefds, &exceptfds, timeout);
	dprintf_winsock(stddeb, "WSA_select: select() returned %d\n",ret);
	if(ret<0) {
		errno_to_wsaerrno();
		dprintf_winsock(stddeb, "WSA_select returning: Error %d\n",SOCKET_ERROR);
		return SOCKET_ERROR;
	}
	
	/* update the winsock fd sets */
	if(ws_readfds!=NULL) {
		dprintf_winsock(stddeb, "readfds: ");
		count=0;
		for(i=0;i<highfd;i++) {
			if(FD_ISSET(i,&readfds)) {
				dprintf_winsock(stddeb, " %d",i);
				ws_readfds->fd_array[count++]=i;
			}
		}
		dprintf_winsock(stddeb, "  (%d)\n",count);
		ws_readfds->fd_count=count;
	} else {
		dprintf_winsock(stddeb, "readfds: (null)\n");
	}
	if(ws_writefds!=NULL) {
		dprintf_winsock(stddeb, "writefds: ");
		count=0;
		for(i=0;i<highfd;i++) {
			if(FD_ISSET(i,&writefds)) {
				dprintf_winsock(stddeb, " %d",i);
				ws_writefds->fd_array[count++]=i;
			}
		}
		dprintf_winsock(stddeb, "  (%d)\n",count);
		ws_writefds->fd_count=count;
	} else {
		dprintf_winsock(stddeb, "writefds: (null)\n");
	}
	if(ws_exceptfds!=NULL) {
		dprintf_winsock(stddeb, "exceptfds: ");
		count=0;
		for(i=0;i<highfd;i++) {
			if(FD_ISSET(i,&exceptfds)) {
				dprintf_winsock(stddeb, " %d",i);
				ws_exceptfds->fd_array[count++]=i;
			}
		}
		dprintf_winsock(stddeb, "  (%d)\n",count);
		ws_exceptfds->fd_count=count;
	} else {
		dprintf_winsock(stddeb, "exceptfds: (null)\n");
	}
	
	dprintf_winsock(stddeb, "WSA_select returning: %d\n",ret);
	return(ret);	
}

INT WINSOCK_send(SOCKET s, char *buf, INT len, INT flags)
{
	int length;

	dprintf_winsock(stddeb, "WSA_send: socket %d, ptr %8lx, length %d, flags %d\n", s, (unsigned long) buf, len, flags);

	if (!wsa_initted) { 
		WSASetLastError(WSANOTINITIALISED);
		return SOCKET_ERROR;
	}

	if ((length = send(s, buf, len, flags)) < 0) {
        	errno_to_wsaerrno();
        	return SOCKET_ERROR;
	}
	return length;
}

INT WINSOCK_sendto(SOCKET s, char *buf, INT len, INT flags,
		struct sockaddr *to, INT tolen)
{
	int length;

	dprintf_winsock(stddeb, "WSA_sendto: socket %d, ptr %8lx, length %d, flags %d\n", s, (unsigned long) buf, len, flags);

	if (!wsa_initted) { 
		WSASetLastError(WSANOTINITIALISED);
		return SOCKET_ERROR;
	}

	if ((length = sendto(s, buf, len, flags, to, tolen)) < 0) {
        	errno_to_wsaerrno();
        	return SOCKET_ERROR;
	}
	return length;
}

INT WINSOCK_setsockopt(SOCKET s, INT level, INT optname, const char *optval, 
			INT optlen)
{
	dprintf_winsock(stddeb, "WSA_setsockopt: socket %d, level %d, opt %d, ptr %8x, len %d\n", s, level, optname, (int) optval, optlen);
	convert_sockopt(&level, &optname);
	
	if (!wsa_initted) { 
		WSASetLastError(WSANOTINITIALISED);
		return SOCKET_ERROR;
	}

	if (setsockopt(s, level, optname, optval, optlen) < 0) {
        	errno_to_wsaerrno();
        	return SOCKET_ERROR;
	}
	return 0;
}                                         

INT WINSOCK_shutdown(SOCKET s, INT how)
{
	dprintf_winsock(stddeb, "WSA_shutdown: socket s %d, how %d\n", s, how);

	if (!wsa_initted) { 
		WSASetLastError(WSANOTINITIALISED);
		return SOCKET_ERROR;
	}

	if (shutdown(s, how) < 0) {
        	errno_to_wsaerrno();
        	return SOCKET_ERROR;
	}
	return 0;
}

SOCKET WINSOCK_socket(INT af, INT type, INT protocol)
{
    int sock;

    dprintf_winsock(stddeb, "WSA_socket: af=%d type=%d protocol=%d\n", af, type, protocol);

	if (!wsa_initted) { 
		WSASetLastError(WSANOTINITIALISED);
		return INVALID_SOCKET;
	}

    /* check the socket family */
    switch(af) {
    case AF_INET:
    case AF_UNSPEC:
        break;
    default:
        WSASetLastError(WSAEAFNOSUPPORT);
        return INVALID_SOCKET;
        break;
    }

    /* check the socket type */
    switch(type) {
    case SOCK_STREAM:
    case SOCK_DGRAM:
    case SOCK_RAW:
        break;
    default:
        WSASetLastError(WSAESOCKTNOSUPPORT);
        return INVALID_SOCKET;
        break;
    }

    /* check the protocol type */
    if ( protocol < 0 ) { /* don't support negative values */
        WSASetLastError(WSAEPROTONOSUPPORT);
        return INVALID_SOCKET;
    }

    if ( af == AF_UNSPEC) { /* did they not specify the address family? */
        switch(protocol) {
        case IPPROTO_TCP:
             if (type == SOCK_STREAM) {
                 af = AF_INET;
                 break;
             }
        case IPPROTO_UDP:
             if (type == SOCK_DGRAM) {
                 af = AF_INET;
                 break;
             }
        default:
             WSASetLastError(WSAEPROTOTYPE);
             return INVALID_SOCKET;
             break;
        }
    }

    if ((sock = socket(af, type, protocol)) < 0) {
        if (errno == EPERM) {
            /* non super-user wants a raw socket */
            fprintf(stderr, "WSA_socket: not enough privileges\n");
            WSASetLastError(WSAESOCKTNOSUPPORT);
        } else
            errno_to_wsaerrno();
        dprintf_winsock(stddeb, "WSA_socket: failed !\n");
        return INVALID_SOCKET;
    }
    
    if (sock > WINSOCK_MAX_SOCKETS) {
	/* we only support socket numbers up to WINSOCK_MAX_SOCKETS.
	 * The return value indicates no more descriptors are available
	 */
        WSASetLastError(WSAEMFILE);
	return INVALID_SOCKET;
    }

    FD_SET(sock, &fd_in_use);

    dprintf_winsock(stddeb, "WSA_socket: fd %d\n", sock);
    return sock;
}

/*
struct WIN_hostent *
*/
SEGPTR WINSOCK_gethostbyaddr(const char *addr, INT len, INT type)
{
	struct hostent *host;

	dprintf_winsock(stddeb, "WSA_gethostbyaddr: ptr %8x, len %d, type %d\n", (int) addr, len, type);

	if (!wsa_initted) { 
		WSASetLastError(WSANOTINITIALISED);
		return NULL;
	}

	if ((host = gethostbyaddr(addr, len, type)) == NULL) {
		if (h_errno < 0) {
        		errno_to_wsaerrno();
		} else {
			herrno_to_wsaerrno();
		}
        	return NULL;
	}
	CONVERT_HOSTENT(&Heap->hostent_addr, host);

	return GET_SEG_PTR(&Heap->hostent_addr);
}

/*
struct WIN_hostent *
*/
SEGPTR WINSOCK_gethostbyname(const char *name)
{
	struct hostent *host;

	dprintf_winsock(stddeb, "WSA_gethostbyname: %s\n", name);

	if (!wsa_initted) { 
		WSASetLastError(WSANOTINITIALISED);
		return NULL;
	}

	if ((host = gethostbyname(name)) == NULL) {
		if (h_errno < 0) {
        		errno_to_wsaerrno();
		} else {
			herrno_to_wsaerrno();
		}
        	return NULL;
	}
	CONVERT_HOSTENT(&Heap->hostent_name, host);

	return GET_SEG_PTR(&Heap->hostent_name);
}

INT WINSOCK_gethostname(char *name, INT namelen)
{
	dprintf_winsock(stddeb, "WSA_gethostname: name %s, len %d\n", name, namelen);

	if (!wsa_initted) {
		WSASetLastError(WSANOTINITIALISED);
        	return SOCKET_ERROR;
	}

	if (gethostname(name, namelen) < 0) {
		if (errno == EINVAL)
			WSASetLastError(WSAEFAULT);
		else
			errno_to_wsaerrno();
        	return SOCKET_ERROR;
	}
	return 0;
}          

/*
struct WIN_protoent *
*/
SEGPTR WINSOCK_getprotobyname(char *name)
{
	struct protoent *proto;

	dprintf_winsock(stddeb, "WSA_getprotobyname: name %s\n", name);

	if (!wsa_initted) {
		WSASetLastError(WSANOTINITIALISED);
        	return NULL;
	}

	if ((proto = getprotobyname(name)) == NULL) {
		if (h_errno < 0) {
        		errno_to_wsaerrno();
		} else {
			herrno_to_wsaerrno();
		}
        	return NULL;
	}
	CONVERT_PROTOENT(&Heap->protoent_name, proto);

	return GET_SEG_PTR(&Heap->protoent_name);
}

/*
struct WIN_protoent *
*/
SEGPTR WINSOCK_getprotobynumber(INT number)
{
	struct protoent *proto;

	dprintf_winsock(stddeb, "WSA_getprotobynumber: num %d\n", number);

	if (!wsa_initted) {
		WSASetLastError(WSANOTINITIALISED);
        	return NULL;
	}

	if ((proto = getprotobynumber(number)) == NULL) {
#if 0
		if (h_errno < 0) {
        		errno_to_wsaerrno();
		} else {
			herrno_to_wsaerrno();
		}
#endif
		WSASetLastError(WSANO_DATA);
        	return NULL;
	}
	CONVERT_PROTOENT(&Heap->protoent_number, proto);

	return GET_SEG_PTR(&Heap->protoent_number);
}

/*
struct WIN_servent *
*/
SEGPTR WINSOCK_getservbyname(const char *name, const char *proto)
{
	struct servent *service;

	if (proto == NULL)
		proto = "tcp";

	dprintf_winsock(stddeb, "WSA_getservbyname: name %s, proto %s\n", name, proto);

	if (!wsa_initted) {
		WSASetLastError(WSANOTINITIALISED);
        	return NULL;
	}

	if ((service = getservbyname(name, proto)) == NULL) {
		if (h_errno < 0) {
        		errno_to_wsaerrno();
		} else {
			herrno_to_wsaerrno();
		}
        	return NULL;
	}
	CONVERT_SERVENT(&Heap->servent_name, service);

	return GET_SEG_PTR(&Heap->servent_name);
}

/*
struct WIN_servent *
*/
SEGPTR WINSOCK_getservbyport(INT port, const char *proto)
{
	struct servent *service;

	dprintf_winsock(stddeb, "WSA_getservbyport: port %d, name %s\n", port, proto);

	if (!wsa_initted) {
		WSASetLastError(WSANOTINITIALISED);
        	return NULL;
	}

	if ((service = getservbyport(port, proto)) == NULL) {
		if (h_errno < 0) {
        		errno_to_wsaerrno();
		} else {
			herrno_to_wsaerrno();
		}
        	return NULL;
	}
	CONVERT_SERVENT(&Heap->servent_port, service);

	return GET_SEG_PTR(&Heap->servent_port);
}

/******************** winsock specific functions ************************
 *
 */
static HANDLE new_handle = 1;

static HANDLE AllocWSAHandle(void)
{
	return new_handle++;
}

static void recv_message(int sig)
{
	static struct ipc_packet message;
	int message_is_valid = 0;
	BOOL result;

	message.mtype = MTYPE;

	signal(SIGUSR1, recv_message);
	while (1) {

		if (!message_is_valid) {
			if (msgrcv(wine_key, (struct msgbuf*)&(message), 
				   IPC_PACKET_SIZE, 0 /*MTYPE*/, IPC_NOWAIT) == -1) {
				perror("wine: winsock: msgrcv");
				break;
			}
		}

		result = PostMessage(message.hWnd, message.wMsg,
				     (WPARAM)message.handle, message.lParam);
		if (result != FALSE) {
			message_is_valid = 1;
			break;
		}
		else
			message_is_valid = 0;
		
	}
		
    if ((wine_key = msgget(IPC_PRIVATE, 0600)) == -1)
	perror("wine: winsock: msgget"); 
}


static void send_message( HWND hWnd, u_int wMsg, HANDLE handle, long lParam)
{
	struct ipc_packet message;
	
	message.mtype = MTYPE;
	message.handle = handle;
	message.hWnd = hWnd;
	message.wMsg = wMsg;
	message.lParam = lParam;

	if (msgsnd(wine_key, (struct msgbuf*)&(message),  
		   IPC_PACKET_SIZE, 0/*IPC_NOWAIT*/) == -1)
		perror("wine: winsock: msgsnd");

	kill(getppid(), SIGUSR1);
}


HANDLE WSAAsyncGetHostByAddr(HWND hWnd, u_int wMsg, LPCSTR addr,
                             INT len, INT type, LPSTR buf, INT buflen)
{
	HANDLE handle;
	struct hostent *host;
	int newpid;

	if (!wsa_initted) { 
		WSASetLastError(WSANOTINITIALISED);
		return 0;
	}

	handle = AllocWSAHandle();

	newpid = fork();
	if (newpid) {
		dprintf_winsock(stddeb, "forked, child is (%d)\n",newpid);
		return handle;
	} else {
		if ((host = gethostbyaddr(addr, len, type)) == NULL) {
			if (h_errno < 0) {
        			errno_to_wsaerrno();
			} else {
				herrno_to_wsaerrno();
			}
			send_message(hWnd, wMsg, handle, wsaerrno() << 16);
			exit(0);
		}
		memcpy(buf, host, buflen);
		send_message(hWnd, wMsg, handle, 0);
		exit(0);
	}
}


HANDLE WSAAsyncGetHostByName(HWND hWnd, u_int wMsg, LPCSTR name, 
                             LPSTR buf, INT buflen)
{
	HANDLE handle;
	struct hostent *host;
	int newpid;

	if (!wsa_initted) { 
		WSASetLastError(WSANOTINITIALISED);
		return 0;
	}

	handle = AllocWSAHandle();

	newpid = fork();
	if (newpid) {
		dprintf_winsock(stddeb, "forked, child is (%d)\n",newpid);
		return handle;
	} else {
		if ((host = gethostbyname(name)) == NULL) {
			if (h_errno < 0) {
        			errno_to_wsaerrno();
			} else {
				herrno_to_wsaerrno();
			}
			send_message(hWnd, wMsg, handle, wsaerrno() << 16);
			exit(0);
		}
		memcpy(buf, host, buflen);
		send_message(hWnd, wMsg, handle, 0);
		exit(0);
	}
}                     


HANDLE WSAAsyncGetProtoByName(HWND hWnd, u_int wMsg, LPCSTR name, 
                              LPSTR buf, INT buflen)
{
	HANDLE handle;
	struct protoent *proto;
	int newpid;

	if (!wsa_initted) { 
		WSASetLastError(WSANOTINITIALISED);
		return 0;
	}

	handle = AllocWSAHandle();

	newpid = fork();
	if (newpid) {
		dprintf_winsock(stddeb, "forked, child is (%d)\n",newpid);
		return handle;
	} else {
		if ((proto = getprotobyname(name)) == NULL) {
			if (h_errno < 0) {
        			errno_to_wsaerrno();
			} else {
				herrno_to_wsaerrno();
			}
			send_message(hWnd, wMsg, handle, wsaerrno() << 16);
			exit(0);
		}
		memcpy(buf, proto, buflen);
		send_message(hWnd, wMsg, handle, 0);
		exit(0);
	}
}


HANDLE WSAAsyncGetProtoByNumber(HWND hWnd, u_int wMsg, INT number, 
                                LPSTR buf, INT buflen)
{
	HANDLE handle;
	struct protoent *proto;
	int newpid;

	if (!wsa_initted) { 
		WSASetLastError(WSANOTINITIALISED);
		return 0;
	}

	handle = AllocWSAHandle();

	newpid = fork();
	if (newpid) {
		dprintf_winsock(stddeb, "forked, child is (%d)\n",newpid);
		return handle;
	} else {
		if ((proto = getprotobynumber(number)) == NULL) {
			if (h_errno < 0) {
        			errno_to_wsaerrno();
			} else {
				herrno_to_wsaerrno();
			}
			send_message(hWnd, wMsg, handle, wsaerrno() << 16);
			exit(0);
		}
		memcpy(buf, proto, buflen);
		send_message(hWnd, wMsg, handle, 0);
		exit(0);
	}
}


HANDLE WSAAsyncGetServByName(HWND hWnd, u_int wMsg, LPCSTR name, 
                             LPCSTR proto, LPSTR buf, INT buflen)
{
	HANDLE handle;
	struct servent *service;
	int newpid;

	if (!wsa_initted) { 
		WSASetLastError(WSANOTINITIALISED);
		return 0;
	}

	handle = AllocWSAHandle();

	newpid = fork();
	if (newpid) {
		dprintf_winsock(stddeb, "forked, child is (%d)\n",newpid);
		return handle;
	} else {
		if ((service = getservbyname(name, proto)) == NULL) {
			if (h_errno < 0) {
        			errno_to_wsaerrno();
			} else {
				herrno_to_wsaerrno();
			}
			send_message(hWnd, wMsg, handle, wsaerrno() << 16);
			exit(0);
		}
		memcpy(buf, service, buflen);
		send_message(hWnd, wMsg, handle, 0);
		exit(0);
	}
}


HANDLE WSAAsyncGetServByPort(HWND hWnd, u_int wMsg, INT port, LPCSTR proto,
                             LPSTR buf, INT buflen)
{
	HANDLE handle;
	struct servent *service;
	int newpid;

	if (!wsa_initted) { 
		WSASetLastError(WSANOTINITIALISED);
		return 0;
	}

	handle = AllocWSAHandle();

	newpid = fork();
	if (newpid) {
		dprintf_winsock(stddeb, "forked, child is (%d)\n",newpid);
		return handle;
	} else {
		if ((service = getservbyport(port, proto)) == NULL) {
			if (h_errno < 0) {
        			errno_to_wsaerrno();
			} else {
				herrno_to_wsaerrno();
			}
			send_message(hWnd, wMsg, handle, wsaerrno() << 16);
			exit(0);
		}
		memcpy(buf, service, buflen);
		send_message(hWnd, wMsg, handle, 0);
		exit(0);
	}
}

INT WSAAsyncSelect(SOCKET s, HWND hWnd, u_int wMsg, long lEvent)
{
    long event;
    fd_set read_fds, write_fds, except_fds;
    int errors = 0;
    int newpid;

	if (!wsa_initted) { 
		WSASetLastError(WSANOTINITIALISED);
		return SOCKET_ERROR;
	}

    dprintf_winsock(stddeb, "WSA_AsyncSelect: socket %d, HWND %04x, wMsg %d, event %ld\n", s, hWnd, wMsg, lEvent);

    /* remove outstanding asyncselect() processes */
    /* kill */

    if (wMsg == 0 && lEvent == 0) 
        return 0;

    newpid = fork();
    if (newpid) {
        dprintf_winsock(stddeb, "forked, child is (%d)\n",newpid);
        return 0;
    } else {
        while (1) {
            FD_ZERO(&read_fds);
            FD_ZERO(&write_fds);
            FD_ZERO(&except_fds);

            if (lEvent & FD_READ)
                FD_SET(s, &read_fds);
            if (lEvent & FD_WRITE)
                FD_SET(s, &write_fds);

            fcntl(s, F_SETFL, O_NONBLOCK);
            if (select(s + 1, &read_fds, &write_fds, &except_fds, NULL)<0) {
                errors = wsaerrno();
            }

            event = 0;
            if (FD_ISSET(s, &read_fds))
                event |= FD_READ;
            if (FD_ISSET(s, &write_fds))
                event |= FD_WRITE;
            send_message(hWnd, wMsg, s, WSAMAKESELECTREPLY(event,errors));
        }
    }
}

INT WSAFDIsSet(SOCKET fd, WinSock_fd_set *set)
{
  int i = set->fd_count;
  
  dprintf_winsock(stddeb, "__WSAFDIsSet(%d,%8lx)\n",fd,(unsigned long)set);
    
  while (i--)
    {
      if (set->fd_array[i] == fd)
        {
          dprintf_winsock(stddeb, "__WSAFDIsSet returning 1\n");
          return 1;
        }
    }
  dprintf_winsock(stddeb, "__WSAFDIsSet returning 0\n");
  return 0;
}                                                            

INT WSACancelAsyncRequest(HANDLE hAsyncTaskHandle)
{
	dprintf_winsock(stddeb, "WSA_AsyncRequest: handle %04x\n", hAsyncTaskHandle);

	if (!wsa_initted) { 
		WSASetLastError(WSANOTINITIALISED);
		return SOCKET_ERROR;
	}

	return 0;
}

INT WSACancelBlockingCall(void)
{
	dprintf_winsock(stddeb, "WSA_CancelBlockCall\n");

	if (!wsa_initted) { 
		WSASetLastError(WSANOTINITIALISED);
		return SOCKET_ERROR;
	}

	return 0;
}
          
INT WSAGetLastError(void)
{
	dprintf_winsock(stddeb, "WSA_GetLastError = %x\n", wsa_errno);

	return wsa_errno;
}

void WSASetLastError(INT iError)
{
	dprintf_winsock(stddeb, "WSA_SetLastErorr %d\n", iError);

	/* technically, we should make sure that WINESockets 
	* has been started up correctly. But since this function
	* is also used internally, it makes no sense.
	*
	*if (!wsa_initted) { 
	*	WSASetLastError(WSANOTINITIALISED);
	*	return SOCKET_ERROR;
	*}
	*/

	wsa_errno = iError;
}

BOOL WSAIsBlocking(void)
{
	dprintf_winsock(stddeb, "WSA_IsBlocking\n");

	return 0;
}

FARPROC16 WSASetBlockingHook(FARPROC16 lpBlockFunc)
{
	dprintf_winsock(stddeb, "WSA_SetBlockHook %8lx, STUB!\n", (unsigned long) lpBlockFunc);

	if (!wsa_initted) { 
		WSASetLastError(WSANOTINITIALISED);
		return NULL;
	}

	BlockFunction = lpBlockFunc;

	return (FARPROC16) lpBlockFunc;
}

INT WSAUnhookBlockingHook(void)
{
	dprintf_winsock(stddeb, "WSA_UnhookBlockingHook\n");

	if (!wsa_initted) { 
		WSASetLastError(WSANOTINITIALISED);
		return NULL;
	}

	BlockFunction = NULL;

	return 0;
}

#ifdef 0
WSADATA WINSOCK_data = {
        0x0101,
        0x0101,
        "WINE Sockets",
#ifdef linux
        "LINUX/i386",
#elif defined(__NetBSD__)
        "NetBSD/i386",
#elif defined(sunos)
	"SunOS",
#elif defined(__FreeBSD__)
	"FreeBSD",
#else
	"Unknown",
#endif
        WINSOCK_MAX_SOCKETS,
	WINSOCK_MAX_UDPDG,
        NULL
};
#endif

INT WSAStartup(WORD wVersionRequested, LPWSADATA lpWSAData)
{

	WSADATA WINSOCK_data = {
        			0x0101,
        			0x0101,
        			"WINE Sockets",
			#ifdef linux
        			"Linux/i386",
			#elif defined(__NetBSD__)
        			"NetBSD/i386",
			#elif defined(sunos)
				"SunOS",
			#elif defined(__FreeBSD__)
				"FreeBSD",
			#else
				"Unknown",
			#endif
        			WINSOCK_MAX_SOCKETS,
				WINSOCK_MAX_UDPDG,
				NULL
				};

    dprintf_winsock(stddeb, "WSAStartup: verReq=%x\n", wVersionRequested);

    if (LOBYTE(wVersionRequested) < 1 ||
        (LOBYTE(wVersionRequested) == 1 &&
         HIBYTE(wVersionRequested) < 1))
	return WSAVERNOTSUPPORTED;

    if (!lpWSAData)
        return WSAEINVAL;

	/* alloc winsock heap */

    if ((HeapHandle = GlobalAlloc16(GMEM_FIXED,sizeof(struct WinSockHeap))) == 0)
	return WSASYSNOTREADY;

    Heap = (struct WinSockHeap *) GlobalLock16(HeapHandle);

    /* return winsock information */
    memcpy(lpWSAData, &WINSOCK_data, sizeof(WINSOCK_data)); 

    /* ipc stuff */

    if ((wine_key = msgget(IPC_PRIVATE, 0600)) == -1)
	perror("wine: winsock: msgget"); 

    signal(SIGUSR1, recv_message);

    /* clear */
    
    FD_ZERO(&fd_in_use);

    /* increment our usage count */
    wsa_initted++;
    dprintf_winsock(stddeb, "WSAStartup: succeeded\n");
    return(0);
}

INT WSACleanup(void)
{
	int fd;

	dprintf_winsock(stddeb, "WSACleanup (%d)\n",getpid());

	if (!wsa_initted) { 
		WSASetLastError(WSANOTINITIALISED);
		return SOCKET_ERROR;
	}

	/* decrement usage count */
	wsa_initted--;

	if (wsa_initted == 0) {
		if (wine_key)
			if (msgctl(wine_key, IPC_RMID, NULL) == -1)
				perror("wine: winsock: msgctl");

		for (fd = 0; fd != FD_SETSIZE; fd++)
			if (FD_ISSET(fd, &fd_in_use))
				close(fd);

	}
	return 0;
}

VOID
WsControl(DWORD x1,DWORD x2,LPDWORD x3,LPDWORD x4,LPDWORD x5,LPDWORD x6) {
	fprintf(stdnimp,"WsControl(%lx,%lx,%p,%p,%p,%p)\n",
		x1,x2,x3,x4,x5,x6
	);
	fprintf(stdnimp,"WsControl(x,x,%lx,%lx,%lx,%lx)\n",
		x3?*x3:0,x4?*x4:0,x5?*x5:0,x6?*x6:0
	);
	return;
}
