Support for IPX networking via winsock under Linux.
This commit is contained in:
parent
e2ed0c92b1
commit
dc163422a1
|
@ -2805,7 +2805,7 @@ else
|
|||
fi
|
||||
done
|
||||
|
||||
for ac_hdr in wctype.h sys/syscall.h syscall.h sys/param.h sys/vfs.h sys/mount.h sys/statfs.h float.h linux/cdrom.h linux/ucdrom.h sys/cdio.h sys/filio.h sys/modem.h strings.h sys/strtio.h dlfcn.h unistd.h sys/sockio.h net/if.h netinet/in.h
|
||||
for ac_hdr in wctype.h sys/syscall.h syscall.h sys/param.h sys/vfs.h sys/mount.h sys/statfs.h float.h linux/cdrom.h linux/ucdrom.h sys/cdio.h sys/filio.h sys/modem.h strings.h sys/strtio.h dlfcn.h unistd.h sys/sockio.h net/if.h netinet/in.h linux/ipx.h
|
||||
do
|
||||
ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
|
||||
echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
|
||||
|
|
|
@ -284,7 +284,7 @@ fi
|
|||
dnl **** Check for functions and header files ****
|
||||
|
||||
AC_CHECK_FUNCS(clone getpagesize memmove sendmsg sigaltstack strerror stricmp tcgetattr timegm usleep wait4 waitpid vfscanf)
|
||||
AC_CHECK_HEADERS(wctype.h sys/syscall.h syscall.h sys/param.h sys/vfs.h sys/mount.h sys/statfs.h float.h linux/cdrom.h linux/ucdrom.h sys/cdio.h sys/filio.h sys/modem.h strings.h sys/strtio.h dlfcn.h unistd.h sys/sockio.h net/if.h netinet/in.h)
|
||||
AC_CHECK_HEADERS(wctype.h sys/syscall.h syscall.h sys/param.h sys/vfs.h sys/mount.h sys/statfs.h float.h linux/cdrom.h linux/ucdrom.h sys/cdio.h sys/filio.h sys/modem.h strings.h sys/strtio.h dlfcn.h unistd.h sys/sockio.h net/if.h netinet/in.h linux/ipx.h)
|
||||
AC_HEADER_STAT()
|
||||
AC_C_CONST()
|
||||
AC_TYPE_SIZE_T()
|
||||
|
|
|
@ -120,6 +120,9 @@
|
|||
/* Define if you have the <linux/cdrom.h> header file. */
|
||||
#undef HAVE_LINUX_CDROM_H
|
||||
|
||||
/* Define if you have the <linux/ipx.h> header file. */
|
||||
#undef HAVE_LINUX_IPX_H
|
||||
|
||||
/* Define if you have the <linux/ucdrom.h> header file. */
|
||||
#undef HAVE_LINUX_UCDROM_H
|
||||
|
||||
|
|
|
@ -13,6 +13,10 @@
|
|||
#include <sys/time.h>
|
||||
#include <fcntl.h>
|
||||
#include <netdb.h>
|
||||
#ifdef HAVE_LINUX_IPX_H
|
||||
# include <asm/types.h>
|
||||
# include <linux/ipx.h>
|
||||
#endif
|
||||
#include <sys/socket.h>
|
||||
#include "windows.h"
|
||||
#include "task.h"
|
||||
|
@ -419,6 +423,22 @@ INT32 WINAPI WSAAsyncSelect32(SOCKET32 s, HWND32 hWnd, UINT32 uMsg, UINT32 l
|
|||
#define WSAAsyncSelect WINELIB_NAME(WSAAsyncSelect)
|
||||
|
||||
|
||||
#ifdef HAVE_LINUX_IPX_H
|
||||
|
||||
/*
|
||||
* socket domains
|
||||
*/
|
||||
#define WS_AF_IPX 6
|
||||
|
||||
struct ws_sockaddr_ipx
|
||||
{
|
||||
INT16 sipx_family __attribute__((packed));
|
||||
UINT32 sipx_network __attribute__((packed));
|
||||
CHAR sipx_node[6] __attribute__((packed));
|
||||
UINT16 sipx_port __attribute__((packed));
|
||||
};
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
191
misc/winsock.c
191
misc/winsock.c
|
@ -554,6 +554,9 @@ SOCKET32 WINAPI WINSOCK_accept32(SOCKET32 s, struct sockaddr *addr,
|
|||
{
|
||||
ws_socket* pws = (ws_socket*)WS_HANDLE2PTR((SOCKET16)s);
|
||||
LPWSINFO pwsi = wsi_find(GetCurrentTask());
|
||||
#ifdef HAVE_LINUX_IPX_H
|
||||
struct ws_sockaddr_ipx* addr2 = (struct ws_sockaddr_ipx *)addr;
|
||||
#endif
|
||||
|
||||
TRACE(winsock, "(%08x): socket %04x\n",
|
||||
(unsigned)pwsi, (UINT16)s );
|
||||
|
@ -577,12 +580,36 @@ SOCKET32 WINAPI WINSOCK_accept32(SOCKET32 s, struct sockaddr *addr,
|
|||
WSAAsyncSelect32( s, pws->psop->hWnd, pws->psop->uMsg,
|
||||
pws->flags & ~WS_FD_ACCEPT );
|
||||
}
|
||||
#ifdef HAVE_LINUX_IPX_H
|
||||
if (((struct sockaddr_ipx *)addr)->sipx_family == AF_IPX) {
|
||||
addr = (struct sockaddr *) malloc(*addrlen32);
|
||||
memcpy(addr, addr2, *addrlen32);
|
||||
addr2->sipx_family = WS_AF_IPX;
|
||||
addr2->sipx_network = ((struct sockaddr_ipx *)addr)->sipx_network;
|
||||
addr2->sipx_port = ((struct sockaddr_ipx *)addr)->sipx_port;
|
||||
memcpy(addr2->sipx_node,
|
||||
((struct sockaddr_ipx *)addr)->sipx_node, IPX_NODE_LEN);
|
||||
free(addr);
|
||||
}
|
||||
#endif
|
||||
return s;
|
||||
}
|
||||
else pwsi->err = WSAENOBUFS;
|
||||
}
|
||||
else pwsi->err = wsaErrno();
|
||||
}
|
||||
#ifdef HAVE_LINUX_IPX_H
|
||||
if (((struct sockaddr_ipx *)addr)->sipx_family == AF_IPX) {
|
||||
addr = (struct sockaddr *) malloc(*addrlen32);
|
||||
memcpy(addr, addr2, *addrlen32);
|
||||
addr2->sipx_family = WS_AF_IPX;
|
||||
addr2->sipx_network = ((struct sockaddr_ipx *)addr)->sipx_network;
|
||||
addr2->sipx_port = ((struct sockaddr_ipx *)addr)->sipx_port;
|
||||
memcpy(addr2->sipx_node,
|
||||
((struct sockaddr_ipx *)addr)->sipx_node, IPX_NODE_LEN);
|
||||
free(addr);
|
||||
}
|
||||
#endif
|
||||
return INVALID_SOCKET32;
|
||||
}
|
||||
|
||||
|
@ -605,6 +632,9 @@ INT32 WINAPI WINSOCK_bind32(SOCKET32 s, struct sockaddr *name, INT32 namelen)
|
|||
{
|
||||
ws_socket* pws = (ws_socket*)WS_HANDLE2PTR(s);
|
||||
LPWSINFO pwsi = wsi_find(GetCurrentTask());
|
||||
#ifdef HAVE_LINUX_IPX_H
|
||||
struct ws_sockaddr_ipx* name2 = (struct ws_sockaddr_ipx *)name;
|
||||
#endif
|
||||
|
||||
TRACE(winsock, "(%08x): socket %04x, ptr %8x, length %d\n",
|
||||
(unsigned)pwsi, s, (int) name, namelen);
|
||||
|
@ -614,9 +644,26 @@ INT32 WINAPI WINSOCK_bind32(SOCKET32 s, struct sockaddr *name, INT32 namelen)
|
|||
|
||||
if ( _check_ws(pwsi, pws) )
|
||||
{
|
||||
#ifdef HAVE_LINUX_IPX_H
|
||||
if (((struct ws_sockaddr_ipx *)name)->sipx_family == WS_AF_IPX)
|
||||
{
|
||||
name = (struct sockaddr *) malloc(sizeof(struct sockaddr_ipx));
|
||||
memset(name, '\0', sizeof(struct sockaddr_ipx));
|
||||
((struct sockaddr_ipx *)name)->sipx_family = AF_IPX;
|
||||
((struct sockaddr_ipx *)name)->sipx_port = name2->sipx_port;
|
||||
((struct sockaddr_ipx *)name)->sipx_network = name2->sipx_network;
|
||||
memcpy(((struct sockaddr_ipx *)name)->sipx_node,
|
||||
name2->sipx_node, IPX_NODE_LEN);
|
||||
namelen = sizeof(struct sockaddr_ipx);
|
||||
}
|
||||
#endif
|
||||
if ( namelen >= sizeof(*name) )
|
||||
{
|
||||
if ( ((struct ws_sockaddr_in *)name)->sin_family == AF_INET )
|
||||
if ( ((struct ws_sockaddr_in *)name)->sin_family == AF_INET
|
||||
#ifdef HAVE_LINUX_IPX_H
|
||||
|| ((struct sockaddr_ipx *)name)->sipx_family == AF_IPX
|
||||
#endif
|
||||
)
|
||||
{
|
||||
if ( bind(pws->fd, name, namelen) < 0 )
|
||||
{
|
||||
|
@ -689,6 +736,9 @@ INT32 WINAPI WINSOCK_connect32(SOCKET32 s, struct sockaddr *name, INT32 namelen)
|
|||
{
|
||||
ws_socket* pws = (ws_socket*)WS_HANDLE2PTR(s);
|
||||
LPWSINFO pwsi = wsi_find(GetCurrentTask());
|
||||
#ifdef HAVE_LINUX_IPX_H
|
||||
struct ws_sockaddr_ipx* name2 = (struct ws_sockaddr_ipx *)name;
|
||||
#endif
|
||||
|
||||
TRACE(winsock, "(%08x): socket %04x, ptr %8x, length %d\n",
|
||||
(unsigned)pwsi, s, (int) name, namelen);
|
||||
|
@ -698,6 +748,18 @@ INT32 WINAPI WINSOCK_connect32(SOCKET32 s, struct sockaddr *name, INT32 namelen)
|
|||
|
||||
if( _check_ws(pwsi, pws) )
|
||||
{
|
||||
#ifdef HAVE_LINUX_IPX_H
|
||||
if (((struct ws_sockaddr_ipx *)name)->sipx_family == WS_AF_IPX) {
|
||||
name = (struct sockaddr *) malloc(sizeof(struct sockaddr_ipx));
|
||||
memset(name, '\0', sizeof(struct sockaddr_ipx));
|
||||
((struct sockaddr_ipx *)name)->sipx_family = AF_IPX;
|
||||
((struct sockaddr_ipx *)name)->sipx_port = name2->sipx_port;
|
||||
((struct sockaddr_ipx *)name)->sipx_network = name2->sipx_network;
|
||||
memcpy(((struct sockaddr_ipx *)name)->sipx_node,
|
||||
name2->sipx_node, IPX_NODE_LEN);
|
||||
namelen = sizeof(struct sockaddr_ipx);
|
||||
}
|
||||
#endif
|
||||
if (connect(pws->fd, name, namelen) == 0)
|
||||
{
|
||||
if( pws->psop && (pws->flags & WS_FD_CONNECT) )
|
||||
|
@ -724,10 +786,18 @@ INT32 WINAPI WINSOCK_connect32(SOCKET32 s, struct sockaddr *name, INT32 namelen)
|
|||
}
|
||||
pws->flags |= WS_FD_CONNECTED;
|
||||
pws->flags &= ~(WS_FD_INACTIVE | WS_FD_CONNECT | WS_FD_LISTENING);
|
||||
#ifdef HAVE_LINUX_IPX_H
|
||||
if (((struct sockaddr_ipx *)name)->sipx_family == AF_IPX)
|
||||
free(name);
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
pwsi->err = (errno == EINPROGRESS) ? WSAEWOULDBLOCK : wsaErrno();
|
||||
}
|
||||
#ifdef HAVE_LINUX_IPX_H
|
||||
if (((struct sockaddr_ipx *)name)->sipx_family == AF_IPX)
|
||||
free(name);
|
||||
#endif
|
||||
return SOCKET_ERROR;
|
||||
}
|
||||
|
||||
|
@ -747,15 +817,43 @@ INT32 WINAPI WINSOCK_getpeername32(SOCKET32 s, struct sockaddr *name,
|
|||
{
|
||||
ws_socket* pws = (ws_socket*)WS_HANDLE2PTR(s);
|
||||
LPWSINFO pwsi = wsi_find(GetCurrentTask());
|
||||
#ifdef HAVE_LINUX_IPX_H
|
||||
struct ws_sockaddr_ipx* name2 = (struct ws_sockaddr_ipx *)name;
|
||||
#endif
|
||||
|
||||
TRACE(winsock, "(%08x): socket: %04x, ptr %8x, ptr %8x\n",
|
||||
(unsigned)pwsi, s, (int) name, *namelen);
|
||||
if( _check_ws(pwsi, pws) )
|
||||
{
|
||||
if (getpeername(pws->fd, name, namelen) == 0)
|
||||
if (getpeername(pws->fd, name, namelen) == 0) {
|
||||
#ifdef HAVE_LINUX_IPX_H
|
||||
if (((struct ws_sockaddr_ipx *)name)->sipx_family == AF_IPX) {
|
||||
name = (struct sockaddr *) malloc(*namelen);
|
||||
memcpy(name, name2, *namelen);
|
||||
name2->sipx_family = WS_AF_IPX;
|
||||
name2->sipx_network = ((struct sockaddr_ipx *)name)->sipx_network;
|
||||
name2->sipx_port = ((struct sockaddr_ipx *)name)->sipx_port;
|
||||
memcpy(name2->sipx_node,
|
||||
((struct sockaddr_ipx *)name)->sipx_node, IPX_NODE_LEN);
|
||||
free(name);
|
||||
}
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
pwsi->err = (h_errno < 0) ? wsaErrno() : wsaHerrno();
|
||||
}
|
||||
#ifdef HAVE_LINUX_IPX_H
|
||||
if (((struct ws_sockaddr_ipx *)name)->sipx_family == AF_IPX) {
|
||||
name = (struct sockaddr *) malloc(*namelen);
|
||||
memcpy(name, name2, *namelen);
|
||||
name2->sipx_family = WS_AF_IPX;
|
||||
name2->sipx_network = ((struct sockaddr_ipx *)name)->sipx_network;
|
||||
name2->sipx_port = ((struct sockaddr_ipx *)name)->sipx_port;
|
||||
memcpy(name2->sipx_node,
|
||||
((struct sockaddr_ipx *)name)->sipx_node, IPX_NODE_LEN);
|
||||
free(name);
|
||||
}
|
||||
#endif
|
||||
return SOCKET_ERROR;
|
||||
}
|
||||
|
||||
|
@ -784,15 +882,43 @@ INT32 WINAPI WINSOCK_getsockname32(SOCKET32 s, struct sockaddr *name,
|
|||
{
|
||||
ws_socket* pws = (ws_socket*)WS_HANDLE2PTR(s);
|
||||
LPWSINFO pwsi = wsi_find(GetCurrentTask());
|
||||
#ifdef HAVE_LINUX_IPX_H
|
||||
struct ws_sockaddr_ipx* name2 = (struct ws_sockaddr_ipx *)name;
|
||||
#endif
|
||||
|
||||
TRACE(winsock, "(%08x): socket: %04x, ptr %8x, ptr %8x\n",
|
||||
(unsigned)pwsi, s, (int) name, (int) *namelen);
|
||||
if( _check_ws(pwsi, pws) )
|
||||
{
|
||||
if (getsockname(pws->fd, name, namelen) == 0)
|
||||
if (getsockname(pws->fd, name, namelen) == 0) {
|
||||
#ifdef HAVE_LINUX_IPX_H
|
||||
if (((struct sockaddr_ipx *)name)->sipx_family == AF_IPX) {
|
||||
name = (struct sockaddr *) malloc(*namelen);
|
||||
memcpy(name, name2, *namelen);
|
||||
name2->sipx_family = WS_AF_IPX;
|
||||
name2->sipx_network = ((struct sockaddr_ipx *)name)->sipx_network;
|
||||
name2->sipx_port = ((struct sockaddr_ipx *)name)->sipx_port;
|
||||
memcpy(name2->sipx_node,
|
||||
((struct sockaddr_ipx *)name)->sipx_node, IPX_NODE_LEN);
|
||||
free(name);
|
||||
}
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
pwsi->err = (h_errno < 0) ? wsaErrno() : wsaHerrno();
|
||||
}
|
||||
#ifdef HAVE_LINUX_IPX_H
|
||||
if (((struct ws_sockaddr_ipx *)name)->sipx_family == AF_IPX) {
|
||||
name = (struct sockaddr *) malloc(*namelen);
|
||||
memcpy(name, name2, *namelen);
|
||||
name2->sipx_family = WS_AF_IPX;
|
||||
name2->sipx_network = ((struct sockaddr_ipx *)name)->sipx_network;
|
||||
name2->sipx_port = ((struct sockaddr_ipx *)name)->sipx_port;
|
||||
memcpy(name2->sipx_node,
|
||||
((struct sockaddr_ipx *)name)->sipx_node, IPX_NODE_LEN);
|
||||
free(name);
|
||||
}
|
||||
#endif
|
||||
return SOCKET_ERROR;
|
||||
}
|
||||
|
||||
|
@ -1057,6 +1183,9 @@ INT32 WINAPI WINSOCK_recvfrom32(SOCKET32 s, char *buf, INT32 len, INT32 flags,
|
|||
{
|
||||
ws_socket* pws = (ws_socket*)WS_HANDLE2PTR(s);
|
||||
LPWSINFO pwsi = wsi_find(GetCurrentTask());
|
||||
#ifdef HAVE_LINUX_IPX_H
|
||||
struct ws_sockaddr_ipx* from2 = (struct ws_sockaddr_ipx *)from;
|
||||
#endif
|
||||
|
||||
TRACE(winsock, "(%08x): socket %04x, ptr %08x, "
|
||||
"len %d, flags %d\n", (unsigned)pwsi, s, (unsigned)buf,
|
||||
|
@ -1077,12 +1206,36 @@ INT32 WINAPI WINSOCK_recvfrom32(SOCKET32 s, char *buf, INT32 len, INT32 flags,
|
|||
if( pws->psop && (pws->flags & (WS_FD_READ | WS_FD_CLOSE)) )
|
||||
EVENT_AddIO( pws->fd, EVENT_IO_READ ); /* reenabler */
|
||||
|
||||
#ifdef HAVE_LINUX_IPX_H
|
||||
if (((struct sockaddr_ipx *)from)->sipx_family == AF_IPX) {
|
||||
from = (struct sockaddr *) malloc(*fromlen32);
|
||||
memcpy(from, from2, *fromlen32);
|
||||
from2->sipx_family = WS_AF_IPX;
|
||||
from2->sipx_network = ((struct sockaddr_ipx *)from)->sipx_network;
|
||||
from2->sipx_port = ((struct sockaddr_ipx *)from)->sipx_port;
|
||||
memcpy(from2->sipx_node,
|
||||
((struct sockaddr_ipx *)from)->sipx_node, IPX_NODE_LEN);
|
||||
free(from);
|
||||
}
|
||||
#endif
|
||||
return (INT16)length;
|
||||
}
|
||||
pwsi->err = wsaErrno();
|
||||
}
|
||||
else if( pwsi ) pwsi->err = WSAENOTSOCK;
|
||||
WARN(winsock, " -> ERROR\n");
|
||||
#ifdef HAVE_LINUX_IPX_H
|
||||
if (((struct sockaddr_ipx *)from)->sipx_family == AF_IPX) {
|
||||
from = (struct sockaddr *) malloc(*fromlen32);
|
||||
memcpy(from, from2, *fromlen32);
|
||||
from2->sipx_family = WS_AF_IPX;
|
||||
from2->sipx_network = ((struct sockaddr_ipx *)from)->sipx_network;
|
||||
from2->sipx_port = ((struct sockaddr_ipx *)from)->sipx_port;
|
||||
memcpy(from2->sipx_node,
|
||||
((struct sockaddr_ipx *)from)->sipx_node, IPX_NODE_LEN);
|
||||
free(from);
|
||||
}
|
||||
#endif
|
||||
return SOCKET_ERROR;
|
||||
}
|
||||
|
||||
|
@ -1224,6 +1377,9 @@ INT32 WINAPI WINSOCK_sendto32(SOCKET32 s, char *buf, INT32 len, INT32 flags,
|
|||
{
|
||||
ws_socket* pws = (ws_socket*)WS_HANDLE2PTR(s);
|
||||
LPWSINFO pwsi = wsi_find(GetCurrentTask());
|
||||
#ifdef HAVE_LINUX_IPX_H
|
||||
struct ws_sockaddr_ipx* to2 = (struct ws_sockaddr_ipx *)to;
|
||||
#endif
|
||||
|
||||
TRACE(winsock, "(%08x): socket %04x, ptr %08x, length %d, flags %d\n",
|
||||
(unsigned)pwsi, s, (unsigned) buf, len, flags);
|
||||
|
@ -1231,6 +1387,18 @@ INT32 WINAPI WINSOCK_sendto32(SOCKET32 s, char *buf, INT32 len, INT32 flags,
|
|||
{
|
||||
INT32 length;
|
||||
|
||||
#ifdef HAVE_LINUX_IPX_H
|
||||
if (((struct ws_sockaddr_ipx *)to)->sipx_family == WS_AF_IPX) {
|
||||
to = (struct sockaddr *) malloc(sizeof(struct sockaddr_ipx));
|
||||
memset(to, '\0', sizeof(struct sockaddr_ipx));
|
||||
((struct sockaddr_ipx *)to)->sipx_family = AF_IPX;
|
||||
((struct sockaddr_ipx *)to)->sipx_port = to2->sipx_port;
|
||||
((struct sockaddr_ipx *)to)->sipx_network = to2->sipx_network;
|
||||
memcpy(((struct sockaddr_ipx *)to)->sipx_node,
|
||||
to2->sipx_node, IPX_NODE_LEN);
|
||||
tolen = sizeof(struct sockaddr_ipx);
|
||||
}
|
||||
#endif
|
||||
if ((length = sendto(pws->fd, buf, len, flags, to, tolen)) < 0 )
|
||||
{
|
||||
pwsi->err = wsaErrno();
|
||||
|
@ -1238,9 +1406,21 @@ INT32 WINAPI WINSOCK_sendto32(SOCKET32 s, char *buf, INT32 len, INT32 flags,
|
|||
pws->psop && pws->flags & WS_FD_WRITE )
|
||||
EVENT_AddIO( pws->fd, EVENT_IO_WRITE ); /* reenabler */
|
||||
}
|
||||
else return length;
|
||||
else {
|
||||
#ifdef HAVE_LINUX_IPX_H
|
||||
if (((struct sockaddr_ipx *)to)->sipx_family == AF_IPX) {
|
||||
free(to);
|
||||
}
|
||||
#endif
|
||||
return length;
|
||||
}
|
||||
}
|
||||
else if( pwsi ) pwsi->err = WSAENOTSOCK;
|
||||
#ifdef HAVE_LINUX_IPX_H
|
||||
if (((struct sockaddr_ipx *)to)->sipx_family == AF_IPX) {
|
||||
free(to);
|
||||
}
|
||||
#endif
|
||||
return SOCKET_ERROR;
|
||||
}
|
||||
|
||||
|
@ -1377,6 +1557,9 @@ SOCKET32 WINAPI WINSOCK_socket32(INT32 af, INT32 type, INT32 protocol)
|
|||
/* check the socket family */
|
||||
switch(af)
|
||||
{
|
||||
#ifdef HAVE_LINUX_IPX_H
|
||||
case WS_AF_IPX: af = AF_IPX;
|
||||
#endif
|
||||
case AF_INET:
|
||||
case AF_UNSPEC: break;
|
||||
default: pwsi->err = WSAEAFNOSUPPORT;
|
||||
|
|
Loading…
Reference in New Issue