/*
 * 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>
#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 "heap.h"
#include "winsock.h"
#include "stddebug.h"
#include "debug.h"

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

struct ipc_packet {
	long	mtype;
	HANDLE	handle;
	HWND	hWnd;
	WORD	wMsg;
	LONG	lParam;
};
#define IPC_PACKET_SIZE (sizeof(struct ipc_packet) - sizeof(long))
#define MTYPE 0xb0b0eb05
#define WINE_PACKED __attribute__ ((packed))

struct WIN_hostent  {
	char	*h_name WINE_PACKED;		/* official name of host */
	char	**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 {
	char	*p_name WINE_PACKED;		/* official protocol name */
	char	**p_aliases WINE_PACKED;	/* alias list */
	int	p_proto WINE_PACKED;		/* protocol # */
};

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

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;
};
static struct WinSockHeap *heap;

#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))

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, (%s).\n", 
                			errno, strerror(errno));
#endif
#else
                fprintf(stderr, "winsock: errno %d\n", errno);
#endif
#endif

        switch(errno)
        {
	case EINTR:		return WSAEINTR;
	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 EBADF:
	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
	case EUSERS:		return WSAEUSERS;
	case EDQUOT:		return WSAEDQUOT;
	case ESTALE:		return WSAESTALE;
	case EREMOTE:		return WSAEREMOTE;

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

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

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 void CONVERT_HOSTENT(struct WIN_hostent *heap, struct hostent *host)
{

}

static void CONVERT_PROTOENT(struct WIN_protoent *heap, struct protoent *proto)
{

}

static void CONVERT_SERVENT(struct WIN_servent *heap, struct servent *serv)
{

}
#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 ((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 (bind(s, name, namelen) < 0) {
        	errno_to_wsaerrno();
        	return SOCKET_ERROR;
	}
	return 0;
}

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

	FD_CLR(s, &fd_in_use);

	if (close(s) < 0) {
        	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 (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 (getpeername(s, name, (int *) namelen) < 0) {
        	errno_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 (getsockname(s, name, (int *) namelen) < 0) {
        	errno_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);
	convert_sockopt(&level, &optname);

	if (getsockopt(s, (int) level, optname, optval, (int *) optlen) < 0) {
        	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 *) &heap->ntoa_buffer;
}

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

	if (ioctl(s, cmd, argp) < 0) {
        	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 (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 ((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 ((length = recvfrom(s, buf, len, flags, from, fromlen)) < 0) {
        	errno_to_wsaerrno();
        	return SOCKET_ERROR;
	}
	return length;
}

INT WINSOCK_select(INT nfds, fd_set *readfds, fd_set *writefds,
	fd_set *exceptfds, struct timeval *timeout)
{
	dprintf_winsock(stddeb, "WSA_select: fd # %d, ptr %8lx, ptr %8lx, ptr %8lX\n", nfds, (unsigned long) readfds, (unsigned long) writefds, (unsigned long) exceptfds);

	return(select(nfds, readfds, writefds, exceptfds, timeout));
}

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 ((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 ((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 (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 (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 ((sock = socket(af, type, protocol)) < 0) {
            errno_to_wsaerrno();
            dprintf_winsock(stddeb, "WSA_socket: failed !\n");
            return INVALID_SOCKET;
    }
    
    if (sock > 0xffff) {
	wsa_errno = WSAEMFILE;
	return INVALID_SOCKET;
    }

    FD_SET(sock, &fd_in_use);

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

struct WIN_hostent *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 ((host = gethostbyaddr(addr, len, type)) == NULL) {
        	errno_to_wsaerrno();
        	return NULL;
	}
	CONVERT_HOSTENT(&heap->hostent_addr, host);

	return &heap->hostent_addr;
}

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

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

	if ((host = gethostbyname(name)) == NULL) {
        	errno_to_wsaerrno();
        	return NULL;
	}
	CONVERT_HOSTENT(&heap->hostent_name, host);

	return &heap->hostent_name;
}

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

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

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

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

	if ((proto = getprotobyname(name)) == NULL) {
        	errno_to_wsaerrno();
        	return NULL;
	}
	CONVERT_PROTOENT(&heap->protoent_name, proto);

	return &heap->protoent_name;
}

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

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

	if ((proto = getprotobynumber(number)) == NULL) {
        	errno_to_wsaerrno();
        	return NULL;
	}
	CONVERT_PROTOENT(&heap->protoent_number, proto);

	return &heap->protoent_number;
}

struct WIN_servent *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 ((service = getservbyname(name, proto)) == NULL) {
        	errno_to_wsaerrno();
        	return NULL;
	}
	CONVERT_SERVENT(&heap->servent_name, service);

	return &heap->servent_name;
}

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

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

	if ((service = getservbyport(port, proto)) == NULL) {
        	errno_to_wsaerrno();
        	return NULL;
	}
	CONVERT_SERVENT(&heap->servent_port, service);

	return &heap->servent_port;
}

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

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

static void recv_message(int sig)
{
	struct ipc_packet message;

	if (msgrcv(wine_key, &message, IPC_PACKET_SIZE, MTYPE, IPC_NOWAIT) == -1)
		perror("wine: msgrcv");

	fprintf(stderr, 
		"WSA: PostMessage (hwnd %d, wMsg %d, wParam %d, lParam %ld)\n",
		message.hWnd,
		message.wMsg,
		message.handle,
		message.lParam);

	PostMessage(message.hWnd, message.wMsg, message.handle, message.lParam);
		
	signal(SIGUSR1, recv_message);
}


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

	fprintf(stderr, 
		"WSA: send (hwnd %d, wMsg %d, handle %d, lParam %ld)\n",
		hWnd, wMsg, handle, lParam);
	
	if (msgsnd(wine_key, &message,  IPC_PACKET_SIZE, IPC_NOWAIT) == -1)
		perror("wine: msgsnd");
		
	kill(getppid(), SIGUSR1);
}


HANDLE WSAAsyncGetHostByAddr(HWND hWnd, u_int wMsg, const char *addr,
		 INT len, INT type, char *buf, INT buflen)
{
	HANDLE handle;
	struct hostent *host;

	handle = AllocWSAHandle();

	if (fork()) {
		return handle;
	} else {
		if ((host = gethostbyaddr(addr, len, type)) == NULL) {
			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, const char *name, 
			char *buf, INT buflen)
{
	HANDLE handle;
	struct hostent *host;

	handle = AllocWSAHandle();

	if (fork()) {
		return handle;
	} else {
		if ((host = gethostbyname(name)) == NULL) {
			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, const char *name, 
			char *buf, INT buflen)
{
	HANDLE handle;
	struct protoent *proto;

	handle = AllocWSAHandle();

	if (fork()) {
		return handle;
	} else {
		if ((proto = getprotobyname(name)) == NULL) {
			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, 
			char *buf, INT buflen)
{
	HANDLE handle;
	struct protoent *proto;

	handle = AllocWSAHandle();

	if (fork()) {
		return handle;
	} else {
		if ((proto = getprotobynumber(number)) == NULL) {
			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, const char *name, 
			const char *proto, char *buf, INT buflen)
{
	HANDLE handle;
	struct servent *service;

	handle = AllocWSAHandle();

	if (fork()) {
		return handle;
	} else {
		if ((service = getservbyname(name, proto)) == NULL) {
			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, const char 
			*proto, char *buf, INT buflen)
{
	HANDLE handle;
	struct servent *service;

	handle = AllocWSAHandle();

	if (fork()) {
		return handle;
	} else {
		if ((service = getservbyport(port, proto)) == NULL) {
			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;

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

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

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

	if (fork()) {
		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);
			select(s + 1, &read_fds, &write_fds, &except_fds, NULL);

			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, (wsaerrno() << 16) | event);
		}
	}
}

INT WSAFDIsSet(INT fd, fd_set *set)
{
	return( FD_ISSET(fd, set) );
}

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

	return 0;
}

INT WSACancelBlockingCall(void)
{
	dprintf_winsock(stddeb, "WSA_CancelBlockCall\n");
	return 0;
}
          
INT WSAGetLastError(void)
{
	dprintf_winsock(stddeb, "WSA_GetLastError\n");

    return wsa_errno;
}

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

    wsa_errno = iError;
}

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

	return 0;
}

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

	return (FARPROC) lpBlockFunc;
}

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

	return 0;
}

WSADATA WINSOCK_data = {
        0x0101,
        0x0101,
        "WINE Sockets",
#ifdef linux
        "LINUX/i386",
#endif
#ifdef __NetBSD__
        "NetBSD/i386",
#endif
#ifdef sunos
	"SunOS",
#endif
        128,
	1024,
        NULL
};

INT WSAStartup(WORD wVersionRequested, LPWSADATA lpWSAData)
{
    int HeapHandle;
    MDESC *MyHeap;

    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 = GlobalAlloc(GMEM_FIXED,sizeof(struct WinSockHeap))) == 0)
	return WSASYSNOTREADY;

    heap = (struct WinSockHeap *) GlobalLock(HeapHandle);
#ifndef WINELIB
    HEAP_Init(&MyHeap, heap, sizeof(struct WinSockHeap));
#endif
    bcopy(&WINSOCK_data, lpWSAData, sizeof(WINSOCK_data));

    /* ipc stuff */

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

    signal(SIGUSR1, recv_message);

    /* clear */
    
    FD_ZERO(&fd_in_use);

    wsa_initted = 1;
    return(0);
}

INT WSACleanup(void)
{
	int fd;

	if (wine_key)
		if (msgctl(wine_key, IPC_RMID, NULL) == -1)
			perror("wine: shmctl");

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

	wsa_initted = 0;
	return 0;
}
