/*
 * 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 "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;
};

#pragma pack(1)

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

#pragma pack(4)

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

    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);
    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;
}
