2 * based on Windows Sockets 1.1 specs
3 * (ftp.microsoft.com:/Advsys/winsock/spec11/WINSOCK.TXT)
5 * (C) 1993,1994 John Brezak, Erik Bos.
11 #include <sys/types.h>
13 #include <sys/socket.h>
14 #include <netinet/in.h>
15 #include <arpa/inet.h>
25 static WORD wsa_errno
;
26 static int wsa_initted
;
27 static key_t wine_key
= 0;
28 static FARPROC BlockFunction
;
29 static fd_set fd_in_use
;
38 #define IPC_PACKET_SIZE (sizeof(struct ipc_packet) - sizeof(long))
40 #define MTYPE 0xb0b0eb05
45 struct hostent hostent_addr
;
46 struct hostent hostent_name
;
47 struct protoent protoent_name
;
48 struct protoent protoent_number
;
49 struct servent servent_name
;
50 struct servent servent_port
;
52 struct hostent WSAhostent_addr
;
53 struct hostent WSAhostent_name
;
54 struct protoent WSAprotoent_name
;
55 struct protoent WSAprotoent_number
;
56 struct servent WSAservent_name
;
57 struct servent WSAservent_port
;
59 static struct WinSockHeap
*heap
;
61 #define dump_sockaddr(a) \
62 fprintf(stderr, "sockaddr_in: family %d, address %s, port %d\n", \
63 ((struct sockaddr_in *)a)->sin_family, \
64 inet_ntoa(((struct sockaddr_in *)a)->sin_addr), \
65 ntohs(((struct sockaddr_in *)a)->sin_port))
67 static WORD
wsaerrno(void)
71 #if defined(__FreeBSD__)
72 fprintf(stderr
, "winsock: errno %d, (%s).\n",
73 errno
, sys_errlist
[errno
]);
75 fprintf(stderr
, "winsock: errno %d, (%s).\n",
76 errno
, strerror(errno
));
79 fprintf(stderr
, "winsock: errno %d\n", errno
);
85 case EINTR
: return WSAEINTR
;
86 case EACCES
: return WSAEACCES
;
87 case EFAULT
: return WSAEFAULT
;
88 case EINVAL
: return WSAEINVAL
;
89 case EMFILE
: return WSAEMFILE
;
90 case EWOULDBLOCK
: return WSAEWOULDBLOCK
;
91 case EINPROGRESS
: return WSAEINPROGRESS
;
92 case EALREADY
: return WSAEALREADY
;
94 case ENOTSOCK
: return WSAENOTSOCK
;
95 case EDESTADDRREQ
: return WSAEDESTADDRREQ
;
96 case EMSGSIZE
: return WSAEMSGSIZE
;
97 case EPROTOTYPE
: return WSAEPROTOTYPE
;
98 case ENOPROTOOPT
: return WSAENOPROTOOPT
;
99 case EPROTONOSUPPORT
: return WSAEPROTONOSUPPORT
;
100 case ESOCKTNOSUPPORT
: return WSAESOCKTNOSUPPORT
;
101 case EOPNOTSUPP
: return WSAEOPNOTSUPP
;
102 case EPFNOSUPPORT
: return WSAEPFNOSUPPORT
;
103 case EAFNOSUPPORT
: return WSAEAFNOSUPPORT
;
104 case EADDRINUSE
: return WSAEADDRINUSE
;
105 case EADDRNOTAVAIL
: return WSAEADDRNOTAVAIL
;
106 case ENETDOWN
: return WSAENETDOWN
;
107 case ENETUNREACH
: return WSAENETUNREACH
;
108 case ENETRESET
: return WSAENETRESET
;
109 case ECONNABORTED
: return WSAECONNABORTED
;
110 case ECONNRESET
: return WSAECONNRESET
;
111 case ENOBUFS
: return WSAENOBUFS
;
112 case EISCONN
: return WSAEISCONN
;
113 case ENOTCONN
: return WSAENOTCONN
;
114 case ESHUTDOWN
: return WSAESHUTDOWN
;
115 case ETOOMANYREFS
: return WSAETOOMANYREFS
;
116 case ETIMEDOUT
: return WSAETIMEDOUT
;
117 case ECONNREFUSED
: return WSAECONNREFUSED
;
118 case ELOOP
: return WSAELOOP
;
119 case ENAMETOOLONG
: return WSAENAMETOOLONG
;
120 case EHOSTDOWN
: return WSAEHOSTDOWN
;
121 case EHOSTUNREACH
: return WSAEHOSTUNREACH
;
122 case ENOTEMPTY
: return WSAENOTEMPTY
;
123 /* case EPROCLIM: return WSAEPROCLIM; */
124 case EUSERS
: return WSAEUSERS
;
125 case EDQUOT
: return WSAEDQUOT
;
126 case ESTALE
: return WSAESTALE
;
127 case EREMOTE
: return WSAEREMOTE
;
130 fprintf(stderr
, "winsock: unknown errorno %d!\n", errno
);
131 return WSAEOPNOTSUPP
;
135 static WORD
errno_to_wsaerrno(void)
137 wsa_errno
= wsaerrno();
140 SOCKET
Winsock_accept(SOCKET s
, struct sockaddr FAR
*addr
, INT FAR
*addrlen
)
145 fprintf(stderr
, "WSA_accept: socket %d, ptr %8x, length %d\n", s
, (int) addr
, addrlen
);
148 if ((sock
= accept(s
, addr
, (int *) addrlen
)) < 0) {
150 return INVALID_SOCKET
;
155 INT
Winsock_bind(SOCKET s
, struct sockaddr FAR
*name
, INT namelen
)
158 fprintf(stderr
, "WSA_bind: socket %d, ptr %8x, length %d\n", s
, (int) name
, namelen
);
162 if (bind(s
, name
, namelen
) < 0) {
169 INT
Winsock_closesocket(SOCKET s
)
172 fprintf(stderr
, "WSA_closesocket: socket %d\n", s
);
175 FD_CLR(s
, &fd_in_use
);
184 INT
Winsock_connect(SOCKET s
, struct sockaddr FAR
*name
, INT namelen
)
187 fprintf(stderr
, "WSA_connect: socket %d, ptr %8x, length %d\n", s
, (int) name
, namelen
);
191 if (connect(s
, name
, namelen
) < 0) {
198 INT
Winsock_getpeername(SOCKET s
, struct sockaddr FAR
*name
, INT FAR
*namelen
)
201 fprintf(stderr
, "WSA_getpeername: socket: %d, ptr %8x, ptr %8x\n", s
, (int) name
, *namelen
);
205 if (getpeername(s
, name
, (int *) namelen
) < 0) {
212 INT
Winsock_getsockname(SOCKET s
, struct sockaddr FAR
*name
, INT FAR
*namelen
)
215 fprintf(stderr
, "WSA_getsockname: socket: %d, ptr %8x, ptr %8x\n", s
, (int) name
, (int) *namelen
);
217 if (getsockname(s
, name
, (int *) namelen
) < 0) {
224 INT
Winsock_getsockopt(SOCKET s
, INT loptname
, char FAR
*optval
, INT FAR
*optlen
)
227 fprintf(stderr
, "WSA_getsockopt: socket: %d, opt %d, ptr %8x, ptr %8x\n", s
, loptname
, (int) optval
, (int) *optlen
);
229 if (getsockopt(s
, 0, (int) loptname
, optval
, (int *) optlen
) < 0) {
236 u_long
Winsock_htonl(u_long hostlong
)
238 return( htonl(hostlong
) );
241 u_short
Winsock_htons(u_short hostshort
)
243 return( htons(hostshort
) );
246 u_long
Winsock_inet_addr(char FAR
*cp
)
248 return( inet_addr(cp
) );
251 char *Winsock_inet_ntoa(struct in_addr in
)
256 fprintf(stderr
, "WSA_inet_ntoa: %8x\n", in
);
259 if ((s
= inet_ntoa(in
)) == NULL
) {
264 strncpy(heap
->ntoa_buffer
, s
, sizeof(heap
->ntoa_buffer
) );
266 return (char *) &heap
->ntoa_buffer
;
269 INT
Winsock_ioctlsocket(SOCKET s
, long cmd
, u_long FAR
*argp
)
272 fprintf(stderr
, "WSA_ioctl: socket %d, cmd %d, ptr %8x\n", s
, cmd
, (int) argp
);
275 if (ioctl(s
, cmd
, argp
) < 0) {
282 INT
Winsock_listen(SOCKET s
, INT backlog
)
285 fprintf(stderr
, "WSA_listen: socket %d, backlog %d\n", s
, backlog
);
288 if (listen(s
, backlog
) < 0) {
295 u_long
Winsock_ntohl(u_long netlong
)
297 return( ntohl(netlong
) );
300 u_short
Winsock_ntohs(u_short netshort
)
302 return( ntohs(netshort
) );
305 INT
Winsock_recv(SOCKET s
, char FAR
*buf
, INT len
, INT flags
)
310 fprintf(stderr
, "WSA_recv: socket %d, ptr %8x, length %d, flags %d\n", s
, (int) buf
, len
, flags
);
313 if ((length
= recv(s
, buf
, len
, flags
)) < 0) {
320 INT
Winsock_recvfrom(SOCKET s
, char FAR
*buf
, INT len
, INT flags
,
321 struct sockaddr FAR
*from
, int FAR
*fromlen
)
326 fprintf(stderr
, "WSA_recvfrom: socket %d, ptr %8x, length %d, flags %d\n", s
, buf
, len
, flags
);
329 if ((length
= recvfrom(s
, buf
, len
, flags
, from
, fromlen
)) < 0) {
336 INT
Winsock_select(INT nfds
, fd_set FAR
*readfds
, fd_set FAR
*writefds
,
337 fd_set FAR
*exceptfds
, struct timeval FAR
*timeout
)
340 fprintf(stderr
, "WSA_select: fd # %d, ptr %8x, ptr %8x, ptr %*X\n", nfds
, readfds
, writefds
, exceptfds
);
343 return(select(nfds
, readfds
, writefds
, exceptfds
, timeout
));
346 INT
Winsock_send(SOCKET s
, char FAR
*buf
, INT len
, INT flags
)
351 fprintf(stderr
, "WSA_send: socket %d, ptr %8x, length %d, flags %d\n", s
, buf
, len
, flags
);
354 if ((length
= send(s
, buf
, len
, flags
)) < 0) {
361 INT
Winsock_sendto(SOCKET s
, char FAR
*buf
, INT len
, INT flags
,
362 struct sockaddr FAR
*to
, INT tolen
)
367 fprintf(stderr
, "WSA_sendto: socket %d, ptr %8x, length %d, flags %d\n", s
, buf
, len
, flags
);
370 if ((length
= sendto(s
, buf
, len
, flags
, to
, tolen
)) < 0) {
377 INT
Winsock_setsockopt(SOCKET s
, INT level
, INT optname
, const char FAR
*optval
,
381 fprintf(stderr
, "WSA_setsockopt: socket %d, level %d, opt %d, ptr %8x, len %d\n", s
, level
, optname
, (int) optval
, optlen
);
384 if (setsockopt(s
, level
, optname
, optval
, optlen
) < 0) {
391 INT
Winsock_shutdown(SOCKET s
, INT how
)
394 fprintf(stderr
, "WSA_shutdown: socket s %d, how %d\n", s
, how
);
397 if (shutdown(s
, how
) < 0) {
404 SOCKET
Winsock_socket(INT af
, INT type
, INT protocol
)
409 fprintf(stderr
, "WSA_socket: af=%d type=%d protocol=%d\n", af
, type
, protocol
);
412 if ((sock
= socket(af
, type
, protocol
)) < 0) {
415 fprintf(stderr
, "WSA_socket: failed !\n");
417 return INVALID_SOCKET
;
421 wsa_errno
= WSAEMFILE
;
422 return INVALID_SOCKET
;
425 FD_SET(sock
, &fd_in_use
);
428 fprintf(stderr
, "WSA_socket: fd %d\n", sock
);
433 struct hostent
*Winsock_gethostbyaddr(const char FAR
*addr
, INT len
, INT type
)
435 struct hostent
*host
;
438 fprintf(stderr
, "WSA_gethostbyaddr: ptr %8x, len %d, type %d\n", (int) addr
, len
, type
);
441 if ((host
= gethostbyaddr(addr
, len
, type
)) == NULL
) {
445 memcpy(&heap
->hostent_addr
, host
, sizeof(struct hostent
));
447 return (struct hostent
*) &heap
->hostent_addr
;
450 struct hostent
*Winsock_gethostbyname(const char FAR
*name
)
452 struct hostent
*host
;
455 fprintf(stderr
, "WSA_gethostbyname: name %s\n", name
);
458 if ((host
= gethostbyname(name
)) == NULL
) {
462 memcpy(&heap
->hostent_name
, host
, sizeof(struct hostent
));
464 return (struct hostent
*) &heap
->hostent_name
;
467 int Winsock_gethostname(char FAR
*name
, INT namelen
)
471 fprintf(stderr
, "WSA_gethostname: name %d, len %d\n", name
, namelen
);
474 if (gethostname(name
, namelen
) < 0) {
481 struct protoent
*Winsock_getprotobyname(char FAR
*name
)
483 struct protoent
*proto
;
486 fprintf(stderr
, "WSA_getprotobyname: name %s\n", name
);
489 if ((proto
= getprotobyname(name
)) == NULL
) {
493 memcpy(&heap
->protoent_name
, proto
, sizeof(struct protoent
));
495 return (struct protoent
*) &heap
->protoent_name
;
498 struct protoent
*Winsock_getprotobynumber(INT number
)
500 struct protoent
*proto
;
503 fprintf(stderr
, "WSA_getprotobynumber: num %d\n", number
);
506 if ((proto
= getprotobynumber(number
)) == NULL
) {
510 memcpy(&heap
->protoent_number
, proto
, sizeof(struct protoent
));
512 return (struct protoent
*) &heap
->protoent_number
;
515 struct servent
*Winsock_getservbyname(const char FAR
*name
, const char FAR
*proto
)
517 struct servent
*service
;
520 fprintf(stderr
, "WSA_getservbyname: name %s, proto %s\n", name
, proto
);
523 if ((service
= getservbyname(name
, proto
)) == NULL
) {
527 memcpy(&heap
->servent_name
, service
, sizeof(struct servent
));
529 return (struct servent
*) &heap
->servent_name
;
532 struct servent
*Winsock_getservbyport(INT port
, const char FAR
*proto
)
534 struct servent
*service
;
537 fprintf(stderr
, "WSA_getservbyport: port %d, name %s\n", port
, proto
);
540 if ((service
= getservbyport(port
, proto
)) == NULL
) {
544 memcpy(&heap
->servent_port
, service
, sizeof(struct servent
));
546 return (struct servent
*) &heap
->servent_port
;
549 /******************** winsock specific functions ************************
552 static HANDLE new_handle
= 0;
554 HANDLE
AllocWSAHandle(void)
559 static void recv_message(int sig
)
561 struct ipc_packet message
;
563 if (msgrcv(wine_key
, &message
, IPC_PACKET_SIZE
, MTYPE
, IPC_NOWAIT
) == -1)
564 perror("wine: msgrcv");
567 "WSA: PostMessage (hwnd %d, wMsg %d, wParam %d, lParam %d)\n",
573 PostMessage(message
.hWnd
, message
.wMsg
, message
.handle
, message
.lParam
);
575 signal(SIGUSR1
, recv_message
);
579 static void send_message(HANDLE handle
, HWND hWnd
, u_int wMsg
, long lParam
)
581 struct ipc_packet message
;
583 message
.mtype
= MTYPE
;
584 message
.handle
= handle
;
587 message
.lParam
= lParam
;
590 "WSA: send (hwnd %d, wMsg %d, handle %d, lParam %d)\n",
591 hWnd
, wMsg
, handle
, lParam
);
593 if (msgsnd(wine_key
, &message
, IPC_PACKET_SIZE
, IPC_NOWAIT
) == -1)
594 perror("wine: msgsnd");
596 kill(getppid(), SIGUSR1
);
600 HANDLE
WSAAsyncGetHostByAddr(HWND hWnd
, u_int wMsg
, const char FAR
*addr
,
601 INT len
, INT type
, char FAR
*buf
, INT buflen
)
604 struct hostent
*host
;
606 handle
= AllocWSAHandle();
611 if ((host
= gethostbyaddr(addr
, len
, type
)) == NULL
) {
612 send_message(hWnd
, wMsg
, handle
, wsaerrno() << 16);
615 memcpy(buf
, host
, buflen
);
616 send_message(hWnd
, wMsg
, handle
, 0);
622 HANDLE
WSAAsyncGetHostByName(HWND hWnd
, u_int wMsg
, const char FAR
*name
,
623 char FAR
*buf
, INT buflen
)
626 struct hostent
*host
;
628 handle
= AllocWSAHandle();
633 if ((host
= gethostbyname(name
)) == NULL
) {
634 send_message(hWnd
, wMsg
, handle
, wsaerrno() << 16);
637 memcpy(buf
, host
, buflen
);
638 send_message(hWnd
, wMsg
, handle
, 0);
644 HANDLE
WSAAsyncGetProtoByName(HWND hWnd
, u_int wMsg
, const char FAR
*name
,
645 char FAR
*buf
, INT buflen
)
648 struct protoent
*proto
;
650 handle
= AllocWSAHandle();
655 if ((proto
= getprotobyname(name
)) == NULL
) {
656 send_message(hWnd
, wMsg
, handle
, wsaerrno() << 16);
659 memcpy(buf
, proto
, buflen
);
660 send_message(hWnd
, wMsg
, handle
, 0);
666 HANDLE
WSAAsyncGetProtoByNumber(HWND hWnd
, u_int wMsg
, INT number
,
667 char FAR
*buf
, INT buflen
)
670 struct protoent
*proto
;
672 handle
= AllocWSAHandle();
677 if ((proto
= getprotobynumber(number
)) == NULL
) {
678 send_message(hWnd
, wMsg
, handle
, wsaerrno() << 16);
681 memcpy(buf
, proto
, buflen
);
682 send_message(hWnd
, wMsg
, handle
, 0);
688 HANDLE
WSAAsyncGetServByName(HWND hWnd
, u_int wMsg
, const char FAR
*name
,
689 const char FAR
*proto
, char FAR
*buf
, INT buflen
)
692 struct servent
*service
;
694 handle
= AllocWSAHandle();
699 if ((service
= getservbyname(name
, proto
)) == NULL
) {
700 send_message(hWnd
, wMsg
, handle
, wsaerrno() << 16);
703 memcpy(buf
, service
, buflen
);
704 send_message(hWnd
, wMsg
, handle
, 0);
710 HANDLE
WSAAsyncGetServByPort(HWND hWnd
, u_int wMsg
, INT port
, const char FAR
711 *proto
, char FAR
*buf
, INT buflen
)
714 struct servent
*service
;
716 handle
= AllocWSAHandle();
721 if ((service
= getservbyport(port
, proto
)) == NULL
) {
722 send_message(hWnd
, wMsg
, handle
, wsaerrno() << 16);
725 memcpy(buf
, service
, buflen
);
726 send_message(hWnd
, wMsg
, handle
, 0);
731 INT
WSAAsyncSelect(SOCKET s
, HWND hWnd
, u_int wMsg
, long lEvent
)
734 fd_set read_fds
, write_fds
, except_fds
;
737 fprintf(stderr
, "WSA_AsyncSelect: socket %d, HWND %d, wMsg %d, event %d\n", s
, hWnd
, wMsg
, lEvent
);
740 /* remove outstanding asyncselect() processes */
743 if (wMsg
== 0 && lEvent
== 0)
752 FD_ZERO(&except_fds
);
754 if (lEvent
& FD_READ
)
755 FD_SET(s
, &read_fds
);
756 if (lEvent
& FD_WRITE
)
757 FD_SET(s
, &write_fds
);
759 fcntl(s
, F_SETFL
, O_NONBLOCK
);
760 select(s
+ 1, &read_fds
, &write_fds
, &except_fds
, NULL
);
763 if (FD_ISSET(s
, &read_fds
))
765 if (FD_ISSET(s
, &write_fds
))
768 send_message(hWnd
, wMsg
, s
, (wsaerrno() << 16) | event
);
773 INT
WSAFDIsSet(INT fd
, fd_set
*set
)
775 return( FD_ISSET(fd
, set
) );
778 INT
WSACancelAsyncRequest(HANDLE hAsyncTaskHandle
)
781 fprintf(stderr
, "WSA_AsyncRequest: handle %d\n", hAsyncTaskHandle
);
787 INT
WSACancelBlockingCall(void)
790 fprintf(stderr
, "WSA_CancelBlockCall\n");
795 INT
WSAGetLastError(void)
798 fprintf(stderr
, "WSA_GetLastError\n");
804 void WSASetLastError(INT iError
)
807 fprintf(stderr
, "WSA_SetLastErorr %d\n", iError
);
813 BOOL
WSAIsBlocking(void)
816 fprintf(stderr
, "WSA_IsBlocking\n");
820 FARPROC
WSASetBlockingHook(FARPROC lpBlockFunc
)
823 fprintf(stderr
, "WSA_SetBlockHook %8x, STUB!\n", lpBlockFunc
);
825 BlockFunction
= lpBlockFunc
;
830 INT
WSAUnhookBlockingHook(void)
833 fprintf(stderr
, "WSA_UnhookBlockingHook\n");
835 BlockFunction
= NULL
;
840 WSADATA Winsock_data
= {
858 INT
WSAStartup(WORD wVersionRequested
, LPWSADATA lpWSAData
)
864 fprintf(stderr
, "WSAStartup: verReq=%x\n", wVersionRequested
);
867 if (LOBYTE(wVersionRequested
) < 1 ||
868 (LOBYTE(wVersionRequested
) == 1 &&
869 HIBYTE(wVersionRequested
) < 1))
870 return WSAVERNOTSUPPORTED
;
875 /* alloc winsock heap */
877 if ((HeapHandle
= GlobalAlloc(GMEM_FIXED
,sizeof(struct WinSockHeap
))) == 0)
878 return WSASYSNOTREADY
;
880 heap
= (struct WinSockHeap
*) GlobalLock(HeapHandle
);
882 HEAP_Init(&MyHeap
, heap
, sizeof(struct WinSockHeap
));
884 bcopy(&Winsock_data
, lpWSAData
, sizeof(Winsock_data
));
888 if ((wine_key
= msgget(IPC_PRIVATE
, 0600)) == -1)
889 perror("wine: msgget");
891 signal(SIGUSR1
, recv_message
);
906 if (msgctl(wine_key
, IPC_RMID
, NULL
) == -1)
907 perror("wine: shmctl");
909 for (fd
= 0; fd
!= FD_SETSIZE
; fd
++)
910 if (FD_ISSET(fd
, &fd_in_use
))