diff options
Diffstat (limited to 'nx-X11/lib/xtrans/Xtransdnet.c')
-rw-r--r-- | nx-X11/lib/xtrans/Xtransdnet.c | 668 |
1 files changed, 668 insertions, 0 deletions
diff --git a/nx-X11/lib/xtrans/Xtransdnet.c b/nx-X11/lib/xtrans/Xtransdnet.c new file mode 100644 index 000000000..ac91695c7 --- /dev/null +++ b/nx-X11/lib/xtrans/Xtransdnet.c @@ -0,0 +1,668 @@ +/* $Xorg: Xtransdnet.c,v 1.4 2001/02/09 02:04:06 xorgcvs Exp $ */ +/* + +Copyright 1993, 1994, 1998 The Open Group + +Permission to use, copy, modify, distribute, and sell this software and its +documentation for any purpose is hereby granted without fee, provided that +the above copyright notice appear in all copies and that both that +copyright notice and this permission notice appear in supporting +documentation. + +The above copyright notice and this permission notice shall be included +in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR +OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of The Open Group shall +not be used in advertising or otherwise to promote the sale, use or +other dealings in this Software without prior written authorization +from The Open Group. + +*/ +/* $XFree86: xc/lib/xtrans/Xtransdnet.c,v 3.7tsi Exp $ */ + +/* Copyright 1993, 1994 NCR Corporation - Dayton, Ohio, USA + * + * All Rights Reserved + * + * Permission to use, copy, modify, and distribute this software and its + * documentation for any purpose and without fee is hereby granted, provided + * that the above copyright notice appear in all copies and that both that + * copyright notice and this permission notice appear in supporting + * documentation, and that the name NCR not be used in advertising + * or publicity pertaining to distribution of the software without specific, + * written prior permission. NCR and makes no representations about the + * suitability of this software for any purpose. It is provided "as is" + * without express or implied warranty. + * + * NCR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN + * NO EVENT SHALL NCR BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS + * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, + * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef WIN32 +#include <netdnet/dn.h> +#include <netdnet/dnetdb.h> +#include <sys/ioctl.h> +#endif /* !WIN32 */ + +#include <stdio.h> + +#ifdef WIN32 +#define _WILLWINSOCK_ +#define BOOL wBOOL +#undef Status +#define Status wStatus +#include <prgpre.h> /* PATHWORKS header normally in %MSTOOLS%\h\pathwork */ +#undef Status +#define Status int +#undef BOOL +#include <X11/Xw32defs.h> +#undef close +#define close closesocket +#endif /* WIN32 */ + + +#if defined(X11_t) +#define DNETOBJ "X$X" +#endif +#if defined(XIM_t) +#define DNETOBJ "IMSERVER$" +#endif +#if defined(FS_t) || defined(FONT_t) +#define DNETOBJ "X$FONT" +#endif +#if defined(ICE_t) +#define DNETOBJ "" +#endif +#if defined(TEST_t) +#define DNETOBJ "X$TEST" +#endif + + +/* + * This is the DNET implementation of the X Transport service layer + */ + +/* + * This function gets the local address of the socket and stores it in the + * XtransConnInfo structure for the connection. + */ + +static int +TRANS(DNETGetAddr) (XtransConnInfo ciptr) + +{ + struct sockaddr_dn sockname; + int namelen = sizeof(sockname); + + PRMSG (3,"DNETGetAddr(%x)\n", ciptr, 0, 0); + + if (getsockname (ciptr->fd, (struct sockaddr *) &sockname, &namelen) < 0) + { + PRMSG (1,"DNETGetAddr: getsockname() failed: %d\n", + EGET(), 0, 0); + return -1; + } + + + /* + * Everything looks good: fill in the XtransConnInfo structure. + */ + + if ((ciptr->addr = (char *) xalloc (namelen)) == NULL) + { + PRMSG (1, "DNETGetAddr: Can't allocate space for the addr\n", + 0, 0, 0); + return -1; + } + + ciptr->family = sockname.sdn_family; + ciptr->addrlen = namelen; + memcpy (ciptr->addr, &sockname, ciptr->addrlen); + + return 0; +} + + +/* + * This function gets the remote address of the socket and stores it in the + * XtransConnInfo structure for the connection. + */ + +static int +TRANS(DNETGetPeerAddr) (XtransConnInfo ciptr) + +{ + struct sockaddr_dn sockname; + int namelen = sizeof(sockname); + + PRMSG (3,"DNETGetPeerAddr(%x)\n", ciptr, 0, 0); + + if (getpeername (ciptr->fd, (struct sockaddr *) &sockname, &namelen) < 0) + { + PRMSG (1,"DNETGetPeerAddr: getpeername() failed: %d\n", + EGET(), 0, 0); + return -1; + } + + /* + * Everything looks good: fill in the XtransConnInfo structure. + */ + + if ((ciptr->peeraddr = (char *) xalloc (namelen)) == NULL) + { + PRMSG (1, + "DNETGetPeerAddr: Can't allocate space for the addr\n", + 0, 0, 0); + return -1; + } + + ciptr->peeraddrlen = namelen; + memcpy (ciptr->peeraddr, &sockname, ciptr->peeraddrlen); + + return 0; +} + + +#ifdef TRANS_CLIENT + +static XtransConnInfo +TRANS(DNETOpenCOTSClient) (Xtransport *thistrans, char *protocol, + char *host, char *port) + +{ + XtransConnInfo ciptr; + + PRMSG (2,"DNETOpenCOTSClient(%s,%s,%s)\n", protocol, host, port); + + if ((ciptr = (XtransConnInfo) xcalloc ( + 1, sizeof(struct _XtransConnInfo))) == NULL) + { + PRMSG (1, "DNETOpenCOTSClient: malloc failed\n", 0, 0, 0); + return NULL; + } + + ciptr->index = 0; /* only one form of DECnet */ + + /* nothing else to do here */ + + return ciptr; +} + +#endif /* TRANS_CLIENT */ + + +#ifdef TRANS_SERVER + +static XtransConnInfo +TRANS(DNETOpenCOTSServer) (Xtransport *thistrans, char *protocol, + char *host, char *port) + +{ + XtransConnInfo ciptr; + + PRMSG (2,"DNETOpenCOTSServer(%s,%s,%s)\n", protocol, host, port); + + if ((ciptr = (XtransConnInfo) xcalloc ( + 1, sizeof(struct _XtransConnInfo))) == NULL) + { + PRMSG (1, "DNETOpenCOTSServer: malloc failed\n", 0, 0, 0); + return NULL; + } + + if ((ciptr->fd = socket (AF_DECnet, SOCK_STREAM, 0)) < 0) + { + xfree ((char *) ciptr); + return NULL; + } + + ciptr->index = 0; /* only one form of DECnet */ + + return (ciptr); +} + +#endif /* TRANS_SERVER */ + + +#ifdef TRANS_CLIENT + +static XtransConnInfo +TRANS(DNETOpenCLTSClient) (Xtransport *thistrans, char *protocol, + char *host, char *port) + +{ + XtransConnInfo ciptr; + + PRMSG (2,"DNETOpenCLTSClient(%s,%s,%s)\n", protocol, host, port); + + if ((ciptr = (XtransConnInfo) xcalloc ( + 1, sizeof (struct _XtransConnInfo))) == NULL) + { + PRMSG (1, "DNETOpenCLTSClient: malloc failed\n", 0, 0, 0); + return NULL; + } + + ciptr->index = 0; /* only one form of DECnet */ + + /* nothing else to do here */ + + return ciptr; +} + +#endif /* TRANS_CLIENT */ + + +#ifdef TRANS_SERVER + +static XtransConnInfo +TRANS(DNETOpenCLTSServer) (Xtransport *thistrans, char *protocol, + char *host, char *port) + +{ + /* NEED TO IMPLEMENT */ + + PRMSG (2,"DNETOpenCLTSServer(%s,%s,%s)\n", protocol, host, port); + return NULL; +} + +#endif /* TRANS_SERVER */ + + +#ifdef TRANS_REOPEN + +static XtransConnInfo +TRANS(DNETReopenCOTSServer) (Xtransport *thistrans, int fd, char *port) + +{ + XtransConnInfo ciptr; + + PRMSG (2,"DNETReopenCOTSServer(%d,%s)\n", fd, port, 0); + + if ((ciptr = (XtransConnInfo) xcalloc ( + 1, sizeof(struct _XtransConnInfo))) == NULL) + { + PRMSG (1, "DNETReopenCOTSServer: malloc failed\n", 0, 0, 0); + return NULL; + } + + ciptr->fd = fd; + ciptr->index = 0; /* only one form of DECnet */ + + return (ciptr); +} + +static XtransConnInfo +TRANS(DNETReopenCLTSServer) (Xtransport *thistrans, int fd, char *port) + +{ + XtransConnInfo ciptr; + + PRMSG (2,"DNETReopenCLTSServer(%d,%s)\n", fd, port, 0); + + if ((ciptr = (XtransConnInfo) xcalloc ( + 1, sizeof(struct _XtransConnInfo))) == NULL) + { + PRMSG (1, "DNETReopenCLTSServer: malloc failed\n", 0, 0, 0); + return NULL; + } + + ciptr->fd = fd; + ciptr->index = 0; /* only one form of DECnet */ + + return (ciptr); +} + +#endif /* TRANS_REOPEN */ + + +static int +TRANS(DNETSetOption) (XtransConnInfo ciptr, int option, int arg) + +{ + PRMSG (2,"DNETSetOption(%d,%d,%d)\n", ciptr->fd, option, arg); + + return -1; +} + + +#ifdef TRANS_SERVER + +static int +TRANS(DNETCreateListener) (XtransConnInfo ciptr, char *port, unsigned int flags) + +{ + struct sockaddr_dn dnsock; + int fd = ciptr->fd; + + PRMSG (3, "DNETCreateListener(%x,%d)\n", ciptr, fd, 0); + + bzero ((char *) &dnsock, sizeof (dnsock)); + dnsock.sdn_family = AF_DECnet; + + if (port && *port ) + sprintf (dnsock.sdn_objname, "%s%s", DNETOBJ, port); + else +#ifdef X11_t + return -1; +#else + sprintf (dnsock.sdn_objname, "%s%d", DNETOBJ, getpid ()); +#endif + + dnsock.sdn_objnamel = strlen (dnsock.sdn_objname); + + if (bind (fd, (struct sockaddr *) &dnsock, sizeof (dnsock))) + { + close (fd); + return -1; + } + + if (listen (fd, 5)) + { + close (fd); + return (-1); + } + + + /* Set a flag to indicate that this connection is a listener */ + + ciptr->flags = 1 | (ciptr->flags & TRANS_KEEPFLAGS); + + return 0; +} + + +static XtransConnInfo +TRANS(DNETAccept) (XtransConnInfo ciptr, int *status) + +{ + XtransConnInfo newciptr; + struct sockaddr_dn sockname; + int namelen = sizeof(sockname); + + PRMSG (2, "DNETAccept(%x,%d)\n", ciptr, ciptr->fd, 0); + + if ((newciptr = (XtransConnInfo) xcalloc( + 1, sizeof (struct _XtransConnInfo))) == NULL) + { + PRMSG (1, "DNETAccept: malloc failed\n", 0, 0, 0); + *status = TRANS_ACCEPT_BAD_MALLOC; + return NULL; + } + + if((newciptr->fd = accept (ciptr->fd, + (struct sockaddr *) &sockname, &namelen)) < 0) + { + PRMSG (1, "DNETAccept: accept() failed\n", 0, 0, 0); + + xfree (newciptr); + *status = TRANS_ACCEPT_FAILED; + return NULL; + } + + /* + * Get this address again because the transport may give a more + * specific address now that a connection is established. + */ + + if (TRANS(DNETGetAddr) (newciptr) < 0) + { + PRMSG(1, + "DNETAccept: ...DNETGetAddr() failed:\n", 0, 0, 0); + close (newciptr->fd); + xfree (newciptr); + *status = TRANS_ACCEPT_MISC_ERROR; + return NULL; + } + + if (TRANS(DNETGetPeerAddr) (newciptr) < 0) + { + PRMSG(1, + "DNETAccept: ...DNETGetPeerAddr() failed:\n", 0, 0, 0); + + close (newciptr->fd); + if (newciptr->addr) xfree (newciptr->addr); + xfree (newciptr); + *status = TRANS_ACCEPT_MISC_ERROR; + return NULL; + } + + *status = 0; + + return newciptr; +} + +#endif /* TRANS_SERVER */ + + +#ifdef TRANS_CLIENT + +#define OBJBUFSIZE 64 + +static int +TRANS(DNETConnect) (XtransConnInfo ciptr, char *host, char *port) + +{ + char objname[OBJBUFSIZE]; + + extern int dnet_conn(); + + PRMSG (2,"DNETConnect(%d,%s,%s)\n", ciptr->fd, host, port); + +#ifdef X11_t + /* + * X has a well known port, that is transport dependent. It is easier + * to handle it here, than try and come up with a transport independent + * representation that can be passed in and resolved the usual way. + * + * The port that is passed here is really a string containing the idisplay + * from ConnectDisplay(). + */ + + if (is_numeric (port)) + { + short tmpport = (short) atoi (port); + + sprintf (objname, "X$X%d", tmpport); + } + else +#endif + strncpy(objname, port, OBJBUFSIZE); + + + /* + * Do the connect + */ + + if (!host) host = "0"; + + if ((ciptr->fd = dnet_conn (host, objname, SOCK_STREAM, 0, 0, 0, 0)) < 0) + { + return TRANS_CONNECT_FAILED; + } + + + /* + * Sync up the address fields of ciptr. + */ + + if (TRANS(DNETGetAddr) (ciptr) < 0) + { + PRMSG (1, + "DNETConnect: ...DNETGetAddr() failed:\n", 0, 0, 0); + return TRANS_CONNECT_FAILED; + } + + if (TRANS(DNETGetPeerAddr) (ciptr) < 0) + { + PRMSG (1, + "DNETConnect: ...DNETGetPeerAddr() failed:\n", + 0, 0, 0); + return TRANS_CONNECT_FAILED; + } + + return 0; +} + +#endif /* TRANS_CLIENT */ + + +static int +TRANS(DNETBytesReadable) (XtransConnInfo ciptr, BytesReadable_t *pend) + +{ + PRMSG (2,"DNETBytesReadable(%x,%d,%x)\n", ciptr, ciptr->fd, pend); + +#ifdef WIN32 + { + int ret = ioctlsocket ((SOCKET) ciptr->fd, FIONREAD, (u_long *) pend); + errno = WSAGetLastError(); + return ret; + } +#else + return ioctl(ciptr->fd, FIONREAD, (char *)pend); +#endif /* WIN32 */ +} + + +static int +TRANS(DNETRead) (XtransConnInfo ciptr, char *buf, int size) + +{ + PRMSG (2,"DNETRead(%d,%x,%d)\n", ciptr->fd, buf, size); + +#ifdef WIN32 + { + int ret = recv ((SOCKET)ciptr->fd, buf, size, 0); + errno = WSAGetLastError(); + return ret; + } +#else + return read (ciptr->fd, buf, size); +#endif /* WIN32 */ +} + + +static int +TRANS(DNETWrite) (XtransConnInfo ciptr, char *buf, int size) + +{ + PRMSG (2,"DNETWrite(%d,%x,%d)\n", ciptr->fd, buf, size); + +#ifdef WIN32 + { + int ret = send ((SOCKET)ciptr->fd, buf, size, 0); + errno = WSAGetLastError(); + return ret; + } +#else + return write (ciptr->fd, buf, size); +#endif /* WIN32 */ +} + + +static int +TRANS(DNETReadv) (XtransConnInfo ciptr, struct iovec *buf, int size) + +{ + PRMSG (2,"DNETReadv(%d,%x,%d)\n", ciptr->fd, buf, size); + + return READV (ciptr, buf, size); +} + + +static int +TRANS(DNETWritev) (XtransConnInfo ciptr, struct iovec *buf, int size) + +{ + PRMSG (2,"DNETWritev(%d,%x,%d)\n", ciptr->fd, buf, size); + + return WRITEV (ciptr, buf, size); +} + + +static int +TRANS(DNETDisconnect) (XtransConnInfo ciptr) + +{ + PRMSG (2,"DNETDisconnect(%x,%d)\n", ciptr, ciptr->fd, 0); + +#ifdef WIN32 + { + int ret = shutdown (ciptr->fd, 2); + errno = WSAGetLastError(); + return ret; + } +#else + return shutdown (ciptr->fd, 2); /* disallow further sends and receives */ +#endif +} + + +static int +TRANS(DNETClose) (XtransConnInfo ciptr) + +{ + PRMSG (2,"DNETClose(%x,%d)\n", ciptr, ciptr->fd, 0); + +#ifdef WIN32 + { + int ret = close (ciptr->fd); + errno = WSAGetLastError(); + return ret; + } +#else + return close (ciptr->fd); +#endif +} + + +Xtransport TRANS(DNETFuncs) = { + /* DNET Interface */ + "dnet", + 0, +#ifdef TRANS_CLIENT + TRANS(DNETOpenCOTSClient), +#endif /* TRANS_CLIENT */ +#ifdef TRANS_SERVER + TRANS(DNETOpenCOTSServer), +#endif /* TRANS_SERVER */ +#ifdef TRANS_CLIENT + TRANS(DNETOpenCLTSClient), +#endif /* TRANS_CLIENT */ +#ifdef TRANS_SERVER + TRANS(DNETOpenCLTSServer), +#endif /* TRANS_SERVER */ +#ifdef TRANS_REOPEN + TRANS(DNETReopenCOTSServer), + TRANS(DNETReopenCLTSServer), +#endif /* TRANS_REOPEN */ + TRANS(DNETSetOption), +#ifdef TRANS_SERVER + TRANS(DNETCreateListener), + NULL, /* ResetListener */ + TRANS(DNETAccept), +#endif /* TRANS_SERVER */ +#ifdef TRANS_CLIENT + TRANS(DNETConnect), +#endif /* TRANS_CLIENT */ + TRANS(DNETBytesReadable), + TRANS(DNETRead), + TRANS(DNETWrite), + TRANS(DNETReadv), + TRANS(DNETWritev), + TRANS(DNETDisconnect), + TRANS(DNETClose), + TRANS(DNETClose), +}; |