summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKaleb Keithley <kaleb@freedesktop.org>2003-11-14 15:54:40 +0000
committerKaleb Keithley <kaleb@freedesktop.org>2003-11-14 15:54:40 +0000
commit26781c4f009a4b448dca3ab4912cbf01182e3d92 (patch)
tree86fe1f75e6069f6534636a28b11ed5249ec71819
R6.6 is the Xorg base-lineXORG-MAIN
-rw-r--r--Xtrans.c1415
-rw-r--r--Xtrans.h489
-rw-r--r--Xtransdnet.c704
-rw-r--r--Xtransint.h432
-rw-r--r--Xtranslcl.c2715
-rw-r--r--Xtranssock.c1993
-rw-r--r--Xtranstli.c1494
-rw-r--r--Xtransutil.c462
-rw-r--r--transport.c71
9 files changed, 9775 insertions, 0 deletions
diff --git a/Xtrans.c b/Xtrans.c
new file mode 100644
index 0000000..3a1cacf
--- /dev/null
+++ b/Xtrans.c
@@ -0,0 +1,1415 @@
+/* $Xorg: Xtrans.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.
+
+*/
+
+/* 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 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.
+ */
+
+#include <ctype.h>
+
+/*
+ * The transport table contains a definition for every transport (protocol)
+ * family. All operations that can be made on the transport go through this
+ * table.
+ *
+ * Each transport is assigned a unique transport id.
+ *
+ * New transports can be added by adding an entry in this table.
+ * For compatiblity, the transport ids should never be renumbered.
+ * Always add to the end of the list.
+ */
+
+#define TRANS_TLI_INET_INDEX 1
+#define TRANS_TLI_TCP_INDEX 2
+#define TRANS_TLI_TLI_INDEX 3
+#define TRANS_SOCKET_UNIX_INDEX 4
+#define TRANS_SOCKET_LOCAL_INDEX 5
+#define TRANS_SOCKET_INET_INDEX 6
+#define TRANS_SOCKET_TCP_INDEX 7
+#define TRANS_DNET_INDEX 8
+#define TRANS_LOCAL_LOCAL_INDEX 9
+#define TRANS_LOCAL_PTS_INDEX 10
+#define TRANS_LOCAL_NAMED_INDEX 11
+#define TRANS_LOCAL_ISC_INDEX 12
+#define TRANS_LOCAL_SCO_INDEX 13
+#define TRANS_AMOEBA_INDEX 14
+
+
+static
+Xtransport_table Xtransports[] = {
+#if defined(STREAMSCONN)
+ &TRANS(TLITCPFuncs), TRANS_TLI_TCP_INDEX,
+ &TRANS(TLIINETFuncs), TRANS_TLI_INET_INDEX,
+ &TRANS(TLITLIFuncs), TRANS_TLI_TLI_INDEX,
+#endif /* STREAMSCONN */
+#if defined(TCPCONN)
+ &TRANS(SocketTCPFuncs), TRANS_SOCKET_TCP_INDEX,
+ &TRANS(SocketINETFuncs), TRANS_SOCKET_INET_INDEX,
+#endif /* TCPCONN */
+#if defined(DNETCONN)
+ &TRANS(DNETFuncs), TRANS_DNET_INDEX,
+#endif /* DNETCONN */
+#if defined(UNIXCONN)
+#if !defined(LOCALCONN)
+ &TRANS(SocketLocalFuncs), TRANS_SOCKET_LOCAL_INDEX,
+#endif /* !LOCALCONN */
+ &TRANS(SocketUNIXFuncs), TRANS_SOCKET_UNIX_INDEX,
+#endif /* UNIXCONN */
+#if defined(LOCALCONN)
+ &TRANS(LocalFuncs), TRANS_LOCAL_LOCAL_INDEX,
+#ifndef sun
+ &TRANS(PTSFuncs), TRANS_LOCAL_PTS_INDEX,
+#endif /* sun */
+ &TRANS(NAMEDFuncs), TRANS_LOCAL_NAMED_INDEX,
+#ifndef sun
+ &TRANS(ISCFuncs), TRANS_LOCAL_ISC_INDEX,
+ &TRANS(SCOFuncs), TRANS_LOCAL_SCO_INDEX,
+#endif /* sun */
+#endif /* LOCALCONN */
+#if defined(AMRPCCONN) || defined(AMTCPCONN)
+ &TRANS(AmConnFuncs), TRANS_AMOEBA_INDEX,
+#endif /* AMRPCCONN || AMTCPCONN */
+};
+
+#define NUMTRANS (sizeof(Xtransports)/sizeof(Xtransport_table))
+
+
+#ifdef WIN32
+#define ioctl ioctlsocket
+#endif
+
+
+
+/*
+ * These are a few utility function used by the public interface functions.
+ */
+
+void
+TRANS(FreeConnInfo) (ciptr)
+
+XtransConnInfo ciptr;
+
+{
+ PRMSG (3,"TRANS(FreeConnInfo) (%x)\n", ciptr, 0, 0);
+
+ if (ciptr->addr)
+ free (ciptr->addr);
+
+ if (ciptr->peeraddr)
+ free (ciptr->peeraddr);
+
+ if (ciptr->port)
+ free (ciptr->port);
+
+ free ((char *) ciptr);
+}
+
+
+#define PROTOBUFSIZE 20
+
+static Xtransport *
+TRANS(SelectTransport) (protocol)
+
+char *protocol;
+
+{
+ char protobuf[PROTOBUFSIZE];
+ int i;
+
+ PRMSG (3,"TRANS(SelectTransport) (%s)\n", protocol, 0, 0);
+
+ /*
+ * Force Protocol to be lowercase as a way of doing
+ * a case insensitive match.
+ */
+
+ strncpy (protobuf, protocol, PROTOBUFSIZE);
+
+ for (i = 0; i < PROTOBUFSIZE && protobuf[i] != '\0'; i++)
+ if (isupper (protobuf[i]))
+ protobuf[i] = tolower (protobuf[i]);
+
+ /* Look at all of the configured protocols */
+
+ for (i = 0; i < NUMTRANS; i++)
+ {
+ if (!strcmp (protobuf, Xtransports[i].transport->TransName))
+ return Xtransports[i].transport;
+ }
+
+ return NULL;
+}
+
+#ifndef TEST_t
+static
+#endif /* TEST_t */
+int
+TRANS(ParseAddress) (address, protocol, host, port)
+
+char *address;
+char **protocol;
+char **host;
+char **port;
+
+{
+ /*
+ * For the font library, the address is a string formatted
+ * as "protocol/host:port[/catalogue]". Note that the catologue
+ * is optional. At this time, the catologue info is ignored, but
+ * we have to parse it anyways.
+ *
+ * Other than fontlib, the address is a string formatted
+ * as "protocol/host:port".
+ *
+ * If the protocol part is missing, then assume INET.
+ * If the protocol part and host part are missing, then assume local.
+ * If a "::" is found then assume DNET.
+ */
+
+ char *mybuf, *tmpptr;
+ char *_protocol, *_host, *_port;
+ char hostnamebuf[256];
+
+ PRMSG (3,"TRANS(ParseAddress) (%s)\n", address, 0, 0);
+
+ /* Copy the string so it can be changed */
+
+ tmpptr = mybuf = (char *) malloc (strlen (address) + 1);
+ strcpy (mybuf, address);
+
+ /* Parse the string to get each component */
+
+ /* Get the protocol part */
+
+ _protocol = mybuf;
+
+ if ((mybuf = strpbrk (mybuf,"/:")) == NULL)
+ {
+ /* adress is in a bad format */
+ *protocol = NULL;
+ *host = NULL;
+ *port = NULL;
+ free (tmpptr);
+ return 0;
+ }
+
+ if (*mybuf == ':')
+ {
+ /*
+ * If there is a hostname, then assume inet, otherwise
+ * it must be local.
+ */
+ if (mybuf == tmpptr)
+ {
+ /* There is neither a protocol or host specified */
+ _protocol = "local";
+ }
+ else
+ {
+ /* Ther is a hostname specified */
+ _protocol = "inet";
+ mybuf = tmpptr; /* reset to the begining of the host ptr */
+ }
+ }
+ else
+ {
+ /* *mybuf == '/' */
+
+ *mybuf ++= '\0'; /* put a null at the end of the protocol */
+
+ if (strlen(_protocol) == 0)
+ {
+ /*
+ * If there is a hostname, then assume inet, otherwise
+ * it must be local.
+ */
+ if (*mybuf != ':')
+ _protocol = "inet";
+ else
+ _protocol = "local";
+ }
+ }
+
+ /* Get the host part */
+
+ _host = mybuf;
+
+ if ((mybuf = strchr (mybuf,':')) == NULL)
+ {
+ *protocol = NULL;
+ *host = NULL;
+ *port = NULL;
+ free (tmpptr);
+ return 0;
+ }
+
+ *mybuf ++= '\0';
+
+ if (strlen(_host) == 0)
+ {
+ TRANS(GetHostname) (hostnamebuf, sizeof (hostnamebuf));
+ _host = hostnamebuf;
+ }
+
+ /* Check for DECnet */
+
+ if (*mybuf == ':')
+ {
+ _protocol = "dnet";
+ mybuf++;
+ }
+
+ /* Get the port */
+
+get_port:
+
+ _port = mybuf;
+
+#if defined(FONT_t) || defined(FS_t)
+ /*
+ * Is there an optional catalogue list?
+ */
+
+ if ((mybuf = strchr (mybuf,'/')) != NULL)
+ *mybuf ++= '\0';
+
+ /*
+ * The rest, if any, is the (currently unused) catalogue list.
+ *
+ * _catalogue = mybuf;
+ */
+#endif
+
+ /*
+ * Now that we have all of the components, allocate new
+ * string space for them.
+ */
+
+ if ((*protocol = (char *) malloc(strlen (_protocol) + 1)) == NULL)
+ {
+ /* Malloc failed */
+ *port = NULL;
+ *host = NULL;
+ *protocol = NULL;
+ free (tmpptr);
+ return 0;
+ }
+ else
+ strcpy (*protocol, _protocol);
+
+ if ((*host = (char *) malloc (strlen (_host) + 1)) == NULL)
+ {
+ /* Malloc failed */
+ *port = NULL;
+ *host = NULL;
+ free (*protocol);
+ *protocol = NULL;
+ free (tmpptr);
+ return 0;
+ }
+ else
+ strcpy (*host, _host);
+
+ if ((*port = (char *) malloc (strlen (_port) + 1)) == NULL)
+ {
+ /* Malloc failed */
+ *port = NULL;
+ free (*host);
+ *host = NULL;
+ free (*protocol);
+ *protocol = NULL;
+ free (tmpptr);
+ return 0;
+ }
+ else
+ strcpy (*port, _port);
+
+ free (tmpptr);
+
+ return 1;
+}
+
+
+/*
+ * TRANS(Open) does all of the real work opening a connection. The only
+ * funny part about this is the type parameter which is used to decide which
+ * type of open to perform.
+ */
+
+static XtransConnInfo
+TRANS(Open) (type, address)
+
+int type;
+char *address;
+
+{
+ char *protocol = NULL, *host = NULL, *port = NULL;
+ XtransConnInfo ciptr = NULL;
+ Xtransport *thistrans;
+
+ PRMSG (2,"TRANS(Open) (%d,%s)\n", type, address, 0);
+
+#if defined(WIN32) && (defined(TCPCONN) || defined(DNETCONN))
+ if (TRANS(WSAStartup)())
+ {
+ PRMSG (1,"TRANS(Open): WSAStartup failed\n", 0, 0, 0);
+ return NULL;
+ }
+#endif
+
+ /* Parse the Address */
+
+ if (TRANS(ParseAddress) (address, &protocol, &host, &port) == 0)
+ {
+ PRMSG (1,"TRANS(Open): Unable to Parse address %s\n", address, 0, 0);
+ return NULL;
+ }
+
+ /* Determine the transport type */
+
+ if ((thistrans = TRANS(SelectTransport) (protocol)) == NULL)
+ {
+ PRMSG (1,"TRANS(Open): Unable to find transport for %s\n",
+ protocol, 0, 0);
+
+ free (protocol);
+ free (host);
+ free (port);
+ return NULL;
+ }
+
+ /* Open the transport */
+
+ switch (type)
+ {
+ case XTRANS_OPEN_COTS_CLIENT:
+#ifdef TRANS_CLIENT
+ ciptr = thistrans->OpenCOTSClient(thistrans, protocol, host, port);
+#endif /* TRANS_CLIENT */
+ break;
+ case XTRANS_OPEN_COTS_SERVER:
+#ifdef TRANS_SERVER
+ ciptr = thistrans->OpenCOTSServer(thistrans, protocol, host, port);
+#endif /* TRANS_SERVER */
+ break;
+ case XTRANS_OPEN_CLTS_CLIENT:
+#ifdef TRANS_CLIENT
+ ciptr = thistrans->OpenCLTSClient(thistrans, protocol, host, port);
+#endif /* TRANS_CLIENT */
+ break;
+ case XTRANS_OPEN_CLTS_SERVER:
+#ifdef TRANS_SERVER
+ ciptr = thistrans->OpenCLTSServer(thistrans, protocol, host, port);
+#endif /* TRANS_SERVER */
+ break;
+ default:
+ PRMSG (1,"TRANS(Open): Unknown Open type %d\n", type, 0, 0);
+ }
+
+ if (ciptr == NULL)
+ {
+ PRMSG (1,"TRANS(Open): transport open failed for %s/%s:%s\n",
+ protocol, host, port);
+ free (protocol);
+ free (host);
+ free (port);
+ return NULL;
+ }
+
+ ciptr->transptr = thistrans;
+ ciptr->port = port; /* We need this for TRANS(Reopen) */
+
+ free (protocol);
+ free (host);
+
+ return ciptr;
+}
+
+
+#ifdef TRANS_REOPEN
+
+/*
+ * We might want to create an XtransConnInfo object based on a previously
+ * opened connection. For example, the font server may clone itself and
+ * pass file descriptors to the parent.
+ */
+
+static XtransConnInfo
+TRANS(Reopen) (type, trans_id, fd, port)
+
+int type;
+int trans_id;
+int fd;
+char *port;
+
+{
+ XtransConnInfo ciptr = NULL;
+ Xtransport *thistrans = NULL;
+ char *save_port;
+ int i;
+
+ PRMSG (2,"TRANS(Reopen) (%d,%d,%s)\n", trans_id, fd, port);
+
+ /* Determine the transport type */
+
+ for (i = 0; i < NUMTRANS; i++)
+ if (Xtransports[i].transport_id == trans_id)
+ {
+ thistrans = Xtransports[i].transport;
+ break;
+ }
+
+ if (thistrans == NULL)
+ {
+ PRMSG (1,"TRANS(Reopen): Unable to find transport id %d\n",
+ trans_id, 0, 0);
+
+ return NULL;
+ }
+
+ if ((save_port = (char *) malloc (strlen (port) + 1)) == NULL)
+ {
+ PRMSG (1,"TRANS(Reopen): Unable to malloc port string\n", 0, 0, 0);
+
+ return NULL;
+ }
+
+ strcpy (save_port, port);
+
+ /* Get a new XtransConnInfo object */
+
+ switch (type)
+ {
+ case XTRANS_OPEN_COTS_SERVER:
+ ciptr = thistrans->ReopenCOTSServer(thistrans, fd, port);
+ break;
+ case XTRANS_OPEN_CLTS_SERVER:
+ ciptr = thistrans->ReopenCLTSServer(thistrans, fd, port);
+ break;
+ default:
+ PRMSG (1,"TRANS(Reopen): Bad Open type %d\n", type, 0, 0);
+ }
+
+ if (ciptr == NULL)
+ {
+ PRMSG (1,"TRANS(Reopen): transport open failed\n", 0, 0, 0);
+ return NULL;
+ }
+
+ ciptr->transptr = thistrans;
+ ciptr->port = save_port;
+
+ return ciptr;
+}
+
+#endif /* TRANS_REOPEN */
+
+
+
+/*
+ * These are the public interfaces to this Transport interface.
+ * These are the only functions that should have knowledge of the transport
+ * table.
+ */
+
+#ifdef TRANS_CLIENT
+
+XtransConnInfo
+TRANS(OpenCOTSClient) (address)
+
+char *address;
+
+{
+ PRMSG (2,"TRANS(OpenCOTSClient) (%s)\n", address, 0, 0);
+ return TRANS(Open) (XTRANS_OPEN_COTS_CLIENT, address);
+}
+
+#endif /* TRANS_CLIENT */
+
+
+#ifdef TRANS_SERVER
+
+XtransConnInfo
+TRANS(OpenCOTSServer) (address)
+
+char *address;
+
+{
+ PRMSG (2,"TRANS(OpenCOTSServer) (%s)\n", address, 0, 0);
+ return TRANS(Open) (XTRANS_OPEN_COTS_SERVER, address);
+}
+
+#endif /* TRANS_SERVER */
+
+
+#ifdef TRANS_CLIENT
+
+XtransConnInfo
+TRANS(OpenCLTSClient) (address)
+
+char *address;
+{
+ PRMSG (2,"TRANS(OpenCLTSClient) (%s)\n", address, 0, 0);
+ return TRANS(Open) (XTRANS_OPEN_CLTS_CLIENT, address);
+}
+
+#endif /* TRANS_CLIENT */
+
+
+#ifdef TRANS_SERVER
+
+XtransConnInfo
+TRANS(OpenCLTSServer) (address)
+
+char *address;
+
+{
+ PRMSG (2,"TRANS(OpenCLTSServer) (%s)\n", address, 0, 0);
+ return TRANS(Open) (XTRANS_OPEN_CLTS_SERVER, address);
+}
+
+#endif /* TRANS_SERVER */
+
+
+#ifdef TRANS_REOPEN
+
+XtransConnInfo
+TRANS(ReopenCOTSServer) (trans_id, fd, port)
+
+int trans_id;
+int fd;
+char *port;
+
+{
+ PRMSG (2,"TRANS(ReopenCOTSServer) (%d, %d, %s)\n", trans_id, fd, port);
+ return TRANS(Reopen) (XTRANS_OPEN_COTS_SERVER, trans_id, fd, port);
+}
+
+XtransConnInfo
+TRANS(ReopenCLTSServer) (trans_id, fd, port)
+
+int trans_id;
+int fd;
+char *port;
+
+{
+ PRMSG (2,"TRANS(ReopenCLTSServer) (%d, %d, %s)\n", trans_id, fd, port);
+ return TRANS(Reopen) (XTRANS_OPEN_CLTS_SERVER, trans_id, fd, port);
+}
+
+
+int
+TRANS(GetReopenInfo) (ciptr, trans_id, fd, port)
+
+XtransConnInfo ciptr;
+int *trans_id;
+int *fd;
+char **port;
+
+{
+ int i;
+
+ for (i = 0; i < NUMTRANS; i++)
+ if (Xtransports[i].transport == ciptr->transptr)
+ {
+ *trans_id = Xtransports[i].transport_id;
+ *fd = ciptr->fd;
+
+ if ((*port = (char *) malloc (strlen (ciptr->port) + 1)) == NULL)
+ return 0;
+ else
+ {
+ strcpy (*port, ciptr->port);
+ return 1;
+ }
+ }
+
+ return 0;
+}
+
+#endif /* TRANS_REOPEN */
+
+
+int
+TRANS(SetOption) (ciptr, option, arg)
+
+XtransConnInfo ciptr;
+int option;
+int arg;
+
+{
+ int fd = ciptr->fd;
+ int ret = 0;
+
+ PRMSG (2,"TRANS(SetOption) (%d,%d,%d)\n", fd, option, arg);
+
+ /*
+ * For now, all transport type use the same stuff for setting options.
+ * As long as this is true, we can put the common code here. Once a more
+ * complicated transport such as shared memory or an OSI implementation
+ * that uses the session and application libraries is implemented, this
+ * code may have to move to a transport dependent function.
+ *
+ * ret = ciptr->transptr->SetOption (ciptr, option, arg);
+ */
+
+ switch (option)
+ {
+ case TRANS_NONBLOCKING:
+ switch (arg)
+ {
+ case 0:
+ /* Set to blocking mode */
+ break;
+ case 1: /* Set to non-blocking mode */
+#if defined(O_NONBLOCK) && (!defined(ultrix) && !defined(hpux) && !defined(AIXV3) && !defined(uniosu))
+ ret = fcntl (fd, F_GETFL, 0);
+ if (ret != -1)
+ ret = fcntl (fd, F_SETFL, ret | O_NONBLOCK);
+#else
+#ifdef FIOSNBIO
+ {
+ int arg;
+ arg = 1;
+ ret = ioctl (fd, FIOSNBIO, &arg);
+ }
+#else
+#if (defined(AIXV3) || defined(uniosu) || defined(WIN32)) && defined(FIONBIO)
+ {
+ int arg;
+ arg = 1;
+ ret = ioctl (fd, FIONBIO, &arg);
+ }
+#else
+ ret = fcntl (fd, F_GETFL, 0);
+#ifdef FNDELAY
+ ret = fcntl (fd, F_SETFL, ret | FNDELAY);
+#else
+ ret = fcntl (fd, F_SETFL, ret | O_NDELAY);
+#endif
+#endif /* AIXV3 || uniosu */
+#endif /* FIOSNBIO */
+#endif /* O_NONBLOCK */
+ break;
+ default:
+ /* Unknown option */
+ break;
+ }
+ break;
+ case TRANS_CLOSEONEXEC:
+#ifdef F_SETFD
+#ifdef FD_CLOEXEC
+ ret = fcntl (fd, F_SETFD, FD_CLOEXEC);
+#else
+ ret = fcntl (fd, F_SETFD, 1);
+#endif /* FD_CLOEXEC */
+#endif /* F_SETFD */
+ break;
+ }
+
+ return ret;
+}
+
+#ifdef TRANS_SERVER
+
+int
+TRANS(CreateListener) (ciptr, port)
+
+XtransConnInfo ciptr;
+char *port;
+
+{
+ return ciptr->transptr->CreateListener (ciptr, port);
+}
+
+
+int
+TRANS(ResetListener) (ciptr)
+
+XtransConnInfo ciptr;
+
+{
+ if (ciptr->transptr->ResetListener)
+ return ciptr->transptr->ResetListener (ciptr);
+ else
+ return TRANS_RESET_NOOP;
+}
+
+
+XtransConnInfo
+TRANS(Accept) (ciptr, status)
+
+XtransConnInfo ciptr;
+int *status;
+
+{
+ XtransConnInfo newciptr;
+
+ PRMSG (2,"TRANS(Accept) (%d)\n", ciptr->fd, 0, 0);
+
+ newciptr = ciptr->transptr->Accept (ciptr, status);
+
+ if (newciptr)
+ newciptr->transptr = ciptr->transptr;
+
+ return newciptr;
+}
+
+#endif /* TRANS_SERVER */
+
+
+#ifdef TRANS_CLIENT
+
+int
+TRANS(Connect) (ciptr, address)
+
+XtransConnInfo ciptr;
+char *address;
+
+{
+ char *protocol;
+ char *host;
+ char *port;
+ int ret;
+
+ PRMSG (2,"TRANS(Connect) (%d,%s)\n", ciptr->fd, address, 0);
+
+ if (TRANS(ParseAddress) (address, &protocol, &host, &port) == 0)
+ {
+ PRMSG (1,"TRANS(Connect): Unable to Parse address %s\n",
+ address, 0, 0);
+ return -1;
+ }
+
+ if (!port || !*port)
+ {
+ PRMSG (1,"TRANS(Connect): Missing port specification in %s\n",
+ address, 0, 0);
+ if (protocol) free (protocol);
+ if (host) free (host);
+ return -1;
+ }
+
+ ret = ciptr->transptr->Connect (ciptr, host, port);
+
+ if (protocol) free (protocol);
+ if (host) free (host);
+ if (port) free (port);
+
+ return ret;
+}
+
+#endif /* TRANS_CLIENT */
+
+
+int
+TRANS(BytesReadable) (ciptr, pend)
+
+XtransConnInfo ciptr;
+BytesReadable_t *pend;
+
+{
+ return ciptr->transptr->BytesReadable (ciptr, pend);
+}
+
+int
+TRANS(Read) (ciptr, buf, size)
+
+XtransConnInfo ciptr;
+char *buf;
+int size;
+
+{
+ return ciptr->transptr->Read (ciptr, buf, size);
+}
+
+int
+TRANS(Write) (ciptr, buf, size)
+
+XtransConnInfo ciptr;
+char *buf;
+int size;
+
+{
+ return ciptr->transptr->Write (ciptr, buf, size);
+}
+
+int
+TRANS(Readv) (ciptr, buf, size)
+
+XtransConnInfo ciptr;
+struct iovec *buf;
+int size;
+{
+ return ciptr->transptr->Readv (ciptr, buf, size);
+}
+
+int
+TRANS(Writev) (ciptr, buf, size)
+
+XtransConnInfo ciptr;
+struct iovec *buf;
+int size;
+
+{
+ return ciptr->transptr->Writev (ciptr, buf, size);
+}
+
+int
+TRANS(Disconnect) (ciptr)
+
+XtransConnInfo ciptr;
+
+{
+ return ciptr->transptr->Disconnect (ciptr);
+}
+
+int
+TRANS(Close) (ciptr)
+
+XtransConnInfo ciptr;
+
+{
+ int ret;
+
+ PRMSG (2,"TRANS(Close) (%d)\n", ciptr->fd, 0, 0);
+
+ ret = ciptr->transptr->Close (ciptr);
+
+ TRANS(FreeConnInfo) (ciptr);
+
+ return ret;
+}
+
+int
+TRANS(CloseForCloning) (ciptr)
+
+XtransConnInfo ciptr;
+
+{
+ int ret;
+
+ PRMSG (2,"TRANS(CloseForCloning) (%d)\n", ciptr->fd, 0, 0);
+
+ ret = ciptr->transptr->CloseForCloning (ciptr);
+
+ TRANS(FreeConnInfo) (ciptr);
+
+ return ret;
+}
+
+int
+TRANS(IsLocal) (ciptr)
+
+XtransConnInfo ciptr;
+
+{
+ return (ciptr->family == AF_UNIX);
+}
+
+
+int
+TRANS(GetMyAddr) (ciptr, familyp, addrlenp, addrp)
+
+XtransConnInfo ciptr;
+int *familyp;
+int *addrlenp;
+Xtransaddr **addrp;
+
+{
+ PRMSG (2,"TRANS(GetMyAddr) (%d)\n", ciptr->fd, 0, 0);
+
+ *familyp = ciptr->family;
+ *addrlenp = ciptr->addrlen;
+
+ if ((*addrp = (Xtransaddr *) malloc (ciptr->addrlen)) == NULL)
+ {
+ PRMSG (1,"TRANS(GetMyAddr) malloc failed\n", 0, 0, 0);
+ return -1;
+ }
+ memcpy(*addrp, ciptr->addr, ciptr->addrlen);
+
+ return 0;
+}
+
+int
+TRANS(GetPeerAddr) (ciptr, familyp, addrlenp, addrp)
+
+XtransConnInfo ciptr;
+int *familyp;
+int *addrlenp;
+Xtransaddr **addrp;
+
+{
+ PRMSG (2,"TRANS(GetPeerAddr) (%d)\n", ciptr->fd, 0, 0);
+
+ *familyp = ciptr->family;
+ *addrlenp = ciptr->peeraddrlen;
+
+ if ((*addrp = (Xtransaddr *) malloc (ciptr->peeraddrlen)) == NULL)
+ {
+ PRMSG (1,"TRANS(GetPeerAddr) malloc failed\n", 0, 0, 0);
+ return -1;
+ }
+ memcpy(*addrp, ciptr->peeraddr, ciptr->peeraddrlen);
+
+ return 0;
+}
+
+
+int
+TRANS(GetConnectionNumber) (ciptr)
+
+XtransConnInfo ciptr;
+
+{
+ return ciptr->fd;
+}
+
+
+/*
+ * These functions are really utility functions, but they require knowledge
+ * of the internal data structures, so they have to be part of the Transport
+ * Independant API.
+ */
+
+static int
+complete_network_count ()
+
+{
+ int count = 0;
+ int found_local = 0;
+ int i;
+
+ /*
+ * For a complete network, we only need one LOCALCONN transport to work
+ */
+
+ for (i = 0; i < NUMTRANS; i++)
+ {
+ if (Xtransports[i].transport->flags & TRANS_ALIAS)
+ continue;
+
+ if (Xtransports[i].transport->flags & TRANS_LOCAL)
+ found_local = 1;
+ else
+ count++;
+ }
+
+ return (count + found_local);
+}
+
+
+#ifdef TRANS_SERVER
+
+int
+TRANS(MakeAllCOTSServerListeners) (port, partial, count_ret, ciptrs_ret)
+
+char *port;
+int *partial;
+int *count_ret;
+XtransConnInfo **ciptrs_ret;
+
+{
+ char buffer[256]; /* ??? What size ?? */
+ XtransConnInfo ciptr, temp_ciptrs[NUMTRANS];
+ int status, i, j;
+
+ PRMSG (2,"TRANS(MakeAllCOTSServerListeners) (%s,%x)\n",
+ port ? port : "NULL", ciptrs_ret, 0);
+
+ *count_ret = 0;
+
+ for (i = 0; i < NUMTRANS; i++)
+ {
+ Xtransport *trans = Xtransports[i].transport;
+
+ if (trans->flags&TRANS_ALIAS)
+ continue;
+
+ sprintf(buffer,"%s/:%s", trans->TransName, port ? port : "");
+
+ PRMSG (5,"TRANS(MakeAllCOTSServerListeners) opening %s\n",
+ buffer, 0, 0);
+
+ if ((ciptr = TRANS(OpenCOTSServer(buffer))) == NULL)
+ {
+ PRMSG (1,
+ "TRANS(MakeAllCOTSServerListeners) failed to open listener for %s\n",
+ trans->TransName, 0, 0);
+ continue;
+ }
+
+ if ((status = TRANS(CreateListener (ciptr, port))) < 0)
+ {
+ if (status == TRANS_ADDR_IN_USE)
+ {
+ /*
+ * We failed to bind to the specified address because the
+ * address is in use. It must be that a server is already
+ * running at this address, and this function should fail.
+ */
+
+ PRMSG (1,
+ "TRANS(MakeAllCOTSServerListeners) server already running\n",
+ 0, 0, 0);
+
+ for (j = 0; j < *count_ret; j++)
+ TRANS(Close) (temp_ciptrs[j]);
+
+ *count_ret = 0;
+ *ciptrs_ret = NULL;
+ *partial = 0;
+ return -1;
+ }
+ else
+ {
+ PRMSG (1,
+ "TRANS(MakeAllCOTSServerListeners) failed to create listener for %s\n",
+ trans->TransName, 0, 0);
+
+ continue;
+ }
+ }
+
+ PRMSG (5,
+ "TRANS(MakeAllCOTSServerListeners) opened listener for %s, %d\n",
+ trans->TransName, ciptr->fd, 0);
+
+ temp_ciptrs[*count_ret] = ciptr;
+ (*count_ret)++;
+ }
+
+ *partial = (*count_ret < complete_network_count());
+
+ PRMSG (5,
+ "TRANS(MakeAllCLTSServerListeners) partial=%d, actual=%d, complete=%d \n",
+ *partial, *count_ret, complete_network_count());
+
+ if (*count_ret > 0)
+ {
+ if ((*ciptrs_ret = (XtransConnInfo *) malloc (
+ *count_ret * sizeof (XtransConnInfo))) == NULL)
+ {
+ return -1;
+ }
+
+ for (i = 0; i < *count_ret; i++)
+ {
+ (*ciptrs_ret)[i] = temp_ciptrs[i];
+ }
+ }
+ else
+ *ciptrs_ret = NULL;
+
+ return 0;
+}
+
+int
+TRANS(MakeAllCLTSServerListeners) (port, partial, count_ret, ciptrs_ret)
+
+char *port;
+int *partial;
+int *count_ret;
+XtransConnInfo **ciptrs_ret;
+
+{
+ char buffer[256]; /* ??? What size ?? */
+ XtransConnInfo ciptr, temp_ciptrs[NUMTRANS];
+ int status, i, j;
+
+ PRMSG (2,"TRANS(MakeAllCLTSServerListeners) (%s,%x)\n",
+ port ? port : "NULL", ciptrs_ret, 0);
+
+ *count_ret = 0;
+
+ for (i = 0; i < NUMTRANS; i++)
+ {
+ Xtransport *trans = Xtransports[i].transport;
+
+ if (trans->flags&TRANS_ALIAS)
+ continue;
+
+ sprintf(buffer,"%s/:%s", trans->TransName, port ? port : "");
+
+ PRMSG (5,"TRANS(MakeAllCLTSServerListeners) opening %s\n",
+ buffer, 0, 0);
+
+ if ((ciptr = TRANS(OpenCLTSServer (buffer))) == NULL)
+ {
+ PRMSG (1,
+ "TRANS(MakeAllCLTSServerListeners) failed to open listener for %s\n",
+ trans->TransName, 0, 0);
+ continue;
+ }
+
+ if ((status = TRANS(CreateListener (ciptr, port))) < 0)
+ {
+ if (status == TRANS_ADDR_IN_USE)
+ {
+ /*
+ * We failed to bind to the specified address because the
+ * address is in use. It must be that a server is already
+ * running at this address, and this function should fail.
+ */
+
+ PRMSG (1,
+ "TRANS(MakeAllCLTSServerListeners) server already running\n",
+ 0, 0, 0);
+
+ for (j = 0; j < *count_ret; j++)
+ TRANS(Close) (temp_ciptrs[j]);
+
+ *count_ret = 0;
+ *ciptrs_ret = NULL;
+ *partial = 0;
+ return -1;
+ }
+ else
+ {
+ PRMSG (1,
+ "TRANS(MakeAllCLTSServerListeners) failed to create listener for %s\n",
+ trans->TransName, 0, 0);
+
+ continue;
+ }
+ }
+
+ PRMSG (5,
+ "TRANS(MakeAllCLTSServerListeners) opened listener for %s, %d\n",
+ trans->TransName, ciptr->fd, 0);
+ temp_ciptrs[*count_ret] = ciptr;
+ (*count_ret)++;
+ }
+
+ *partial = (*count_ret < complete_network_count());
+
+ PRMSG (5,
+ "TRANS(MakeAllCLTSServerListeners) partial=%d, actual=%d, complete=%d \n",
+ *partial, *count_ret, complete_network_count());
+
+ if (*count_ret > 0)
+ {
+ if ((*ciptrs_ret = (XtransConnInfo *) malloc (
+ *count_ret * sizeof (XtransConnInfo))) == NULL)
+ {
+ return -1;
+ }
+
+ for (i = 0; i < *count_ret; i++)
+ {
+ (*ciptrs_ret)[i] = temp_ciptrs[i];
+ }
+ }
+ else
+ *ciptrs_ret = NULL;
+
+ return 0;
+}
+
+#endif /* TRANS_SERVER */
+
+
+
+/*
+ * These routines are not part of the X Transport Interface, but they
+ * may be used by it.
+ */
+
+#ifdef CRAY
+
+/*
+ * Cray UniCOS does not have readv and writev so we emulate
+ */
+
+static int TRANS(ReadV) (ciptr, iov, iovcnt)
+
+XtransConnInfo ciptr;
+struct iovec *iov;
+int iovcnt;
+
+{
+ struct msghdr hdr;
+
+ hdr.msg_iov = iov;
+ hdr.msg_iovlen = iovcnt;
+ hdr.msg_accrights = 0;
+ hdr.msg_accrightslen = 0;
+ hdr.msg_name = 0;
+ hdr.msg_namelen = 0;
+
+ return (recvmsg (ciptr->fd, &hdr, 0));
+}
+
+static int TRANS(WriteV) (ciptr, iov, iovcnt)
+
+XtransConnInfo ciptr;
+struct iovec *iov;
+int iovcnt;
+
+{
+ struct msghdr hdr;
+
+ hdr.msg_iov = iov;
+ hdr.msg_iovlen = iovcnt;
+ hdr.msg_accrights = 0;
+ hdr.msg_accrightslen = 0;
+ hdr.msg_name = 0;
+ hdr.msg_namelen = 0;
+
+ return (sendmsg (ciptr->fd, &hdr, 0));
+}
+
+#endif /* CRAY */
+
+#if (defined(SYSV) && defined(i386)) || defined(WIN32) || defined(__sxg__) || defined(SCO)
+
+/*
+ * emulate readv
+ */
+
+static int TRANS(ReadV) (ciptr, iov, iovcnt)
+
+XtransConnInfo ciptr;
+struct iovec *iov;
+int iovcnt;
+
+{
+ int i, len, total;
+ char *base;
+
+ ESET(0);
+ for (i = 0, total = 0; i < iovcnt; i++, iov++) {
+ len = iov->iov_len;
+ base = iov->iov_base;
+ while (len > 0) {
+ register int nbytes;
+ nbytes = TRANS(Read) (ciptr, base, len);
+ if (nbytes < 0 && total == 0) return -1;
+ if (nbytes <= 0) return total;
+ ESET(0);
+ len -= nbytes;
+ total += nbytes;
+ base += nbytes;
+ }
+ }
+ return total;
+}
+
+#endif /* SYSV && SYSV386 || WIN32 || __sxg__ || SCO */
+
+#if defined(WIN32) || defined(__sxg__) || defined(SCO)
+
+/*
+ * emulate writev
+ */
+
+static int TRANS(WriteV) (ciptr, iov, iovcnt)
+
+XtransConnInfo ciptr;
+struct iovec *iov;
+int iovcnt;
+
+{
+ int i, len, total;
+ char *base;
+
+ ESET(0);
+ for (i = 0, total = 0; i < iovcnt; i++, iov++) {
+ len = iov->iov_len;
+ base = iov->iov_base;
+ while (len > 0) {
+ register int nbytes;
+ nbytes = TRANS(Write) (ciptr, base, len);
+ if (nbytes < 0 && total == 0) return -1;
+ if (nbytes <= 0) return total;
+ ESET(0);
+ len -= nbytes;
+ total += nbytes;
+ base += nbytes;
+ }
+ }
+ return total;
+}
+
+#endif /* WIN32 || __sxg__ || SCO */
+
+
+#if (defined(_POSIX_SOURCE) && !defined(AIXV3)) || defined(hpux) || defined(USG) || defined(SVR4)
+#define NEED_UTSNAME
+#include <sys/utsname.h>
+#endif
+
+/*
+ * TRANS(GetHostname) - similar to gethostname but allows special processing.
+ */
+
+int TRANS(GetHostname) (buf, maxlen)
+
+char *buf;
+int maxlen;
+
+{
+ int len;
+
+#ifdef NEED_UTSNAME
+ struct utsname name;
+
+ uname (&name);
+ len = strlen (name.nodename);
+ if (len >= maxlen) len = maxlen - 1;
+ strncpy (buf, name.nodename, len);
+ buf[len] = '\0';
+#else
+ buf[0] = '\0';
+ (void) gethostname (buf, maxlen);
+ buf [maxlen - 1] = '\0';
+ len = strlen(buf);
+#endif /* NEED_UTSNAME */
+ return len;
+}
diff --git a/Xtrans.h b/Xtrans.h
new file mode 100644
index 0000000..cdba474
--- /dev/null
+++ b/Xtrans.h
@@ -0,0 +1,489 @@
+/* $Xorg: Xtrans.h,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.
+
+*/
+
+/* 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 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 _XTRANS_H_
+#define _XTRANS_H_
+
+#include <X11/Xfuncproto.h>
+#include <X11/Xos.h>
+
+
+/*
+ * Set the functions names according to where this code is being compiled.
+ */
+
+#ifdef X11_t
+#if (defined(__STDC__) && !defined(UNIXCPP)) || defined(ANSICPP)
+#define TRANS(func) _X11Trans##func
+#else
+#define TRANS(func) _X11Trans/**/func
+#endif
+#endif /* X11_t */
+
+#ifdef XSERV_t
+#if (defined(__STDC__) && !defined(UNIXCPP)) || defined(ANSICPP)
+#define TRANS(func) _XSERVTrans##func
+#else
+#define TRANS(func) _XSERVTrans/**/func
+#endif
+#define X11_t
+#endif /* X11_t */
+
+#ifdef XIM_t
+#if (defined(__STDC__) && !defined(UNIXCPP)) || defined(ANSICPP)
+#define TRANS(func) _XimXTrans##func
+#else
+#define TRANS(func) _XimXTrans/**/func
+#endif
+#endif /* XIM_t */
+
+#ifdef FS_t
+#if (defined(__STDC__) && !defined(UNIXCPP)) || defined(ANSICPP)
+#define TRANS(func) _FSTrans##func
+#else
+#define TRANS(func) _FSTrans/**/func
+#endif
+#endif /* FS_t */
+
+#ifdef FONT_t
+#if (defined(__STDC__) && !defined(UNIXCPP)) || defined(ANSICPP)
+#define TRANS(func) _FontTrans##func
+#else
+#define TRANS(func) _FontTrans/**/func
+#endif
+#endif /* FONT_t */
+
+#ifdef ICE_t
+#if (defined(__STDC__) && !defined(UNIXCPP)) || defined(ANSICPP)
+#define TRANS(func) _IceTrans##func
+#else
+#define TRANS(func) _IceTrans/**/func
+#endif
+#endif /* ICE_t */
+
+#ifdef TEST_t
+#if (defined(__STDC__) && !defined(UNIXCPP)) || defined(ANSICPP)
+#define TRANS(func) _TESTTrans##func
+#else
+#define TRANS(func) _TESTTrans/**/func
+#endif
+#endif /* TEST_t */
+
+#ifdef LBXPROXY_t
+#if (defined(__STDC__) && !defined(UNIXCPP)) || defined(ANSICPP)
+#define TRANS(func) _LBXPROXYTrans##func
+#else
+#define TRANS(func) _LBXPROXYTrans/**/func
+#endif
+#define X11_t /* The server defines this - so should the LBX proxy */
+#endif /* LBXPROXY_t */
+
+#if !defined(TRANS)
+#if (defined(__STDC__) && !defined(UNIXCPP)) || defined(ANSICPP)
+#define TRANS(func) _XTrans##func
+#else
+#define TRANS(func) _XTrans/**/func
+#endif
+#endif /* !TRANS */
+
+
+/*
+ * Create a single address structure that can be used wherever
+ * an address structure is needed. struct sockaddr is not big enough
+ * to hold a sockadd_un, so we create this definition to have a single
+ * structure that is big enough for all the structures we might need.
+ *
+ * This structure needs to be independent of the socket/TLI interface used.
+ */
+
+#define XTRANS_MAX_ADDR_LEN 128 /* large enough to hold sun_path */
+
+typedef struct {
+ unsigned char addr[XTRANS_MAX_ADDR_LEN];
+} Xtransaddr;
+
+
+#ifdef LONG64
+typedef int BytesReadable_t;
+#else
+typedef long BytesReadable_t;
+#endif
+
+
+#if defined(WIN32) || (defined(USG) && !defined(CRAY) && !defined(umips) && !defined(MOTOROLA) && !defined(uniosu) && !defined(__sxg__))
+
+/*
+ * TRANS(Readv) and TRANS(Writev) use struct iovec, normally found
+ * in Berkeley systems in <sys/uio.h>. See the readv(2) and writev(2)
+ * manual pages for details.
+ */
+
+struct iovec {
+ caddr_t iov_base;
+ int iov_len;
+};
+
+#else
+#include <sys/uio.h>
+#endif
+
+typedef struct _XtransConnInfo *XtransConnInfo;
+
+
+/*
+ * Transport Option definitions
+ */
+
+#define TRANS_NONBLOCKING 1
+#define TRANS_CLOSEONEXEC 2
+
+
+/*
+ * Return values of Connect (0 is success)
+ */
+
+#define TRANS_CONNECT_FAILED -1
+#define TRANS_TRY_CONNECT_AGAIN -2
+
+
+/*
+ * Return values of CreateListener (0 is success)
+ */
+
+#define TRANS_CREATE_LISTENER_FAILED -1
+#define TRANS_ADDR_IN_USE -2
+
+
+/*
+ * Return values of Accept (0 is success)
+ */
+
+#define TRANS_ACCEPT_BAD_MALLOC -1
+#define TRANS_ACCEPT_FAILED -2
+#define TRANS_ACCEPT_MISC_ERROR -3
+
+
+/*
+ * ResetListener return values
+ */
+
+#define TRANS_RESET_NOOP 1
+#define TRANS_RESET_NEW_FD 2
+#define TRANS_RESET_FAILURE 3
+
+
+/*
+ * Function prototypes for the exposed interface
+ */
+
+#ifdef TRANS_CLIENT
+
+XtransConnInfo TRANS(OpenCOTSClient)(
+#if NeedFunctionPrototypes
+ char * /* address */
+#endif
+);
+
+#endif /* TRANS_CLIENT */
+
+#ifdef TRANS_SERVER
+
+XtransConnInfo TRANS(OpenCOTSServer)(
+#if NeedFunctionPrototypes
+ char * /* address */
+#endif
+);
+
+#endif /* TRANS_SERVER */
+
+#ifdef TRANS_CLIENT
+
+XtransConnInfo TRANS(OpenCLTSClient)(
+#if NeedFunctionPrototypes
+ char * /* address */
+#endif
+);
+
+#endif /* TRANS_CLIENT */
+
+#ifdef TRANS_SERVER
+
+XtransConnInfo TRANS(OpenCLTSServer)(
+#if NeedFunctionPrototypes
+ char * /* address */
+#endif
+);
+
+#endif /* TRANS_SERVER */
+
+#ifdef TRANS_REOPEN
+
+XtransConnInfo TRANS(ReopenCOTSServer)(
+#if NeedFunctionPrototypes
+ int, /* trans_id */
+ int, /* fd */
+ char * /* port */
+#endif
+);
+
+XtransConnInfo TRANS(ReopenCLTSServer)(
+#if NeedFunctionPrototypes
+ int, /* trans_id */
+ int, /* fd */
+ char * /* port */
+#endif
+);
+
+int TRANS(GetReopenInfo)(
+#if NeedFunctionPrototypes
+ XtransConnInfo, /* ciptr */
+ int *, /* trans_id */
+ int *, /* fd */
+ char ** /* port */
+#endif
+);
+
+#endif /* TRANS_REOPEN */
+
+
+int TRANS(SetOption)(
+#if NeedFunctionPrototypes
+ XtransConnInfo, /* ciptr */
+ int, /* option */
+ int /* arg */
+#endif
+);
+
+#ifdef TRANS_SERVER
+
+int TRANS(CreateListener)(
+#if NeedFunctionPrototypes
+ XtransConnInfo, /* ciptr */
+ char * /* port */
+#endif
+);
+
+int TRANS(ResetListener)(
+#if NeedFunctionPrototypes
+ XtransConnInfo /* ciptr */
+#endif
+);
+
+XtransConnInfo TRANS(Accept)(
+#if NeedFunctionPrototypes
+ XtransConnInfo, /* ciptr */
+ int * /* status */
+#endif
+);
+
+#endif /* TRANS_SERVER */
+
+#ifdef TRANS_CLIENT
+
+int TRANS(Connect)(
+#if NeedFunctionPrototypes
+ XtransConnInfo, /* ciptr */
+ char * /* address */
+#endif
+);
+
+#endif /* TRANS_CLIENT */
+
+int TRANS(BytesReadable)(
+#if NeedFunctionPrototypes
+ XtransConnInfo, /* ciptr */
+ BytesReadable_t * /* pend */
+#endif
+);
+
+int TRANS(Read)(
+#if NeedFunctionPrototypes
+ XtransConnInfo, /* ciptr */
+ char *, /* buf */
+ int /* size */
+#endif
+);
+
+int TRANS(Write)(
+#if NeedFunctionPrototypes
+ XtransConnInfo, /* ciptr */
+ char *, /* buf */
+ int /* size */
+#endif
+);
+
+int TRANS(Readv)(
+#if NeedFunctionPrototypes
+ XtransConnInfo, /* ciptr */
+ struct iovec *, /* buf */
+ int /* size */
+#endif
+);
+
+int TRANS(Writev)(
+#if NeedFunctionPrototypes
+ XtransConnInfo, /* ciptr */
+ struct iovec *, /* buf */
+ int /* size */
+#endif
+);
+
+int TRANS(Disconnect)(
+#if NeedFunctionPrototypes
+ XtransConnInfo /* ciptr */
+#endif
+);
+
+int TRANS(Close)(
+#if NeedFunctionPrototypes
+ XtransConnInfo /* ciptr */
+#endif
+);
+
+int TRANS(CloseForCloning)(
+#if NeedFunctionPrototypes
+ XtransConnInfo /* ciptr */
+#endif
+);
+
+int TRANS(IsLocal)(
+#if NeedFunctionPrototypes
+ XtransConnInfo /* ciptr */
+#endif
+);
+
+int TRANS(GetMyAddr)(
+#if NeedFunctionPrototypes
+ XtransConnInfo, /* ciptr */
+ int *, /* familyp */
+ int *, /* addrlenp */
+ Xtransaddr ** /* addrp */
+#endif
+);
+
+int TRANS(GetPeerAddr)(
+#if NeedFunctionPrototypes
+ XtransConnInfo, /* ciptr */
+ int *, /* familyp */
+ int *, /* addrlenp */
+ Xtransaddr ** /* addrp */
+#endif
+);
+
+int TRANS(GetConnectionNumber)(
+#if NeedFunctionPrototypes
+ XtransConnInfo /* ciptr */
+#endif
+);
+
+#ifdef TRANS_SERVER
+
+int TRANS(MakeAllCOTSServerListeners)(
+#if NeedFunctionPrototypes
+ char *, /* port */
+ int *, /* partial */
+ int *, /* count_ret */
+ XtransConnInfo ** /* ciptrs_ret */
+#endif
+);
+
+int TRANS(MakeAllCLTSServerListeners)(
+#if NeedFunctionPrototypes
+ char *, /* port */
+ int *, /* partial */
+ int *, /* count_ret */
+ XtransConnInfo ** /* ciptrs_ret */
+#endif
+);
+
+#endif /* TRANS_SERVER */
+
+
+/*
+ * Function Prototypes for Utility Functions.
+ */
+
+#ifdef X11_t
+
+int TRANS(ConvertAddress)(
+#if NeedFunctionPrototypes
+ int *, /* familyp */
+ int *, /* addrlenp */
+ Xtransaddr ** /* addrp */
+#endif
+);
+
+#endif /* X11_t */
+
+#ifdef ICE_t
+
+char *
+TRANS(GetMyNetworkId)(
+#if NeedFunctionPrototypes
+ XtransConnInfo /* ciptr */
+#endif
+);
+
+char *
+TRANS(GetPeerNetworkId)(
+#if NeedFunctionPrototypes
+ XtransConnInfo /* ciptr */
+#endif
+);
+
+#endif /* ICE_t */
+
+#if defined(WIN32) && (defined(TCPCONN) || defined(DNETCONN))
+int TRANS(WSAStartup)();
+#endif
+
+#endif /* _XTRANS_H_ */
diff --git a/Xtransdnet.c b/Xtransdnet.c
new file mode 100644
index 0000000..55a618c
--- /dev/null
+++ b/Xtransdnet.c
@@ -0,0 +1,704 @@
+/* $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.
+
+*/
+
+/* 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) (ciptr)
+
+XtransConnInfo ciptr;
+
+{
+ struct sockaddr_dn sockname;
+ int namelen = sizeof(sockname);
+
+ PRMSG (3,"TRANS(DNETGetAddr) (%x)\n", ciptr, 0, 0);
+
+ if (getsockname (ciptr->fd, (struct sockaddr *) &sockname, &namelen) < 0)
+ {
+ PRMSG (1,"TRANS(DNETGetAddr): getsockname() failed: %d\n",
+ EGET(), 0, 0);
+ return -1;
+ }
+
+
+ /*
+ * Everything looks good: fill in the XtransConnInfo structure.
+ */
+
+ if ((ciptr->addr = (char *) malloc (namelen)) == NULL)
+ {
+ PRMSG (1, "TRANS(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) (ciptr)
+
+XtransConnInfo ciptr;
+
+{
+ struct sockaddr_dn sockname;
+ int namelen = sizeof(sockname);
+
+ PRMSG (3,"TRANS(DNETGetPeerAddr) (%x)\n", ciptr, 0, 0);
+
+ if (getpeername (ciptr->fd, (struct sockaddr *) &sockname, &namelen) < 0)
+ {
+ PRMSG (1,"TRANS(DNETGetPeerAddr): getpeername() failed: %d\n",
+ EGET(), 0, 0);
+ return -1;
+ }
+
+ /*
+ * Everything looks good: fill in the XtransConnInfo structure.
+ */
+
+ if ((ciptr->peeraddr = (char *) malloc (namelen)) == NULL)
+ {
+ PRMSG (1,
+ "TRANS(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) (thistrans, protocol, host, port)
+
+Xtransport *thistrans;
+char *protocol;
+char *host;
+char *port;
+
+{
+ XtransConnInfo ciptr;
+
+ PRMSG (2,"TRANS(DNETOpenCOTSClient) (%s,%s,%s)\n", protocol, host, port);
+
+ if ((ciptr = (XtransConnInfo) calloc (
+ 1, sizeof(struct _XtransConnInfo))) == NULL)
+ {
+ PRMSG (1, "TRANS(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) (thistrans, protocol, host, port)
+
+Xtransport *thistrans;
+char *protocol;
+char *host;
+char *port;
+
+{
+ XtransConnInfo ciptr;
+
+ PRMSG (2,"TRANS(DNETOpenCOTSServer) (%s,%s,%s)\n", protocol, host, port);
+
+ if ((ciptr = (XtransConnInfo) calloc (
+ 1, sizeof(struct _XtransConnInfo))) == NULL)
+ {
+ PRMSG (1, "TRANS(DNETOpenCOTSServer): malloc failed\n", 0, 0, 0);
+ return NULL;
+ }
+
+ if ((ciptr->fd = socket (AF_DECnet, SOCK_STREAM, 0)) < 0)
+ {
+ free ((char *) ciptr);
+ return NULL;
+ }
+
+ ciptr->index = 0; /* only one form of DECnet */
+
+ return (ciptr);
+}
+
+#endif /* TRANS_SERVER */
+
+
+#ifdef TRANS_CLIENT
+
+static XtransConnInfo
+TRANS(DNETOpenCLTSClient) (thistrans, protocol, host, port)
+
+Xtransport *thistrans;
+char *protocol;
+char *host;
+char *port;
+
+{
+ XtransConnInfo ciptr;
+
+ PRMSG (2,"TRANS(DNETOpenCLTSClient) (%s,%s,%s)\n", protocol, host, port);
+
+ if ((ciptr = (XtransConnInfo) calloc (
+ 1, sizeof (struct _XtransConnInfo))) == NULL)
+ {
+ PRMSG (1, "TRANS(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) (thistrans, protocol, host, port)
+
+Xtransport *thistrans;
+char *protocol;
+char *host;
+char *port;
+
+{
+ /* NEED TO IMPLEMENT */
+
+ PRMSG (2,"TRANS(DNETOpenCLTSServer) (%s,%s,%s)\n", protocol, host, port);
+ return NULL;
+}
+
+#endif /* TRANS_SERVER */
+
+
+#ifdef TRANS_REOPEN
+
+static XtransConnInfo
+TRANS(DNETReopenCOTSServer) (thistrans, fd, port)
+
+Xtransport *thistrans;
+int fd;
+char *port;
+
+{
+ XtransConnInfo ciptr;
+
+ PRMSG (2,"TRANS(DNETReopenCOTSServer) (%d, %s)\n", fd, port, 0);
+
+ if ((ciptr = (XtransConnInfo) calloc (
+ 1, sizeof(struct _XtransConnInfo))) == NULL)
+ {
+ PRMSG (1, "TRANS(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) (thistrans, fd, port)
+
+Xtransport *thistrans;
+int fd;
+char *port;
+
+{
+ XtransConnInfo ciptr;
+
+ PRMSG (2,"TRANS(DNETReopenCLTSServer) (%d, %s)\n", fd, port, 0);
+
+ if ((ciptr = (XtransConnInfo) calloc (
+ 1, sizeof(struct _XtransConnInfo))) == NULL)
+ {
+ PRMSG (1, "TRANS(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) (ciptr, option, arg)
+
+XtransConnInfo ciptr;
+int option;
+int arg;
+
+{
+ PRMSG (2,"TRANS(DNETSetOption) (%d,%d,%d)\n", ciptr->fd, option, arg);
+
+ return -1;
+}
+
+
+#ifdef TRANS_SERVER
+
+static int
+TRANS(DNETCreateListener) (ciptr, port)
+
+XtransConnInfo ciptr;
+char *port;
+
+{
+ struct sockaddr_dn dnsock;
+ int fd = ciptr->fd;
+
+ PRMSG (3, "TRANS(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;
+
+ return 0;
+}
+
+
+static XtransConnInfo
+TRANS(DNETAccept) (ciptr, status)
+
+XtransConnInfo ciptr;
+int *status;
+
+{
+ XtransConnInfo newciptr;
+ struct sockaddr_dn sockname;
+ int namelen = sizeof(sockname);
+
+ PRMSG (2, "TRANS(DNETAccept) (%x,%d)\n", ciptr, ciptr->fd, 0);
+
+ if ((newciptr = (XtransConnInfo) calloc(
+ 1, sizeof (struct _XtransConnInfo))) == NULL)
+ {
+ PRMSG (1, "TRANS(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, "TRANS(DNETAccept): accept() failed\n", 0, 0, 0);
+
+ free (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,
+ "TRANS(DNETAccept): TRANS(DNETGetAddr)() failed:\n", 0, 0, 0);
+ close (newciptr->fd);
+ free (newciptr);
+ *status = TRANS_ACCEPT_MISC_ERROR;
+ return NULL;
+ }
+
+ if (TRANS(DNETGetPeerAddr) (newciptr) < 0)
+ {
+ PRMSG(1,
+ "TRANS(DNETAccept): TRANS(DNETGetPeerAddr)() failed:\n", 0, 0, 0);
+
+ close (newciptr->fd);
+ if (newciptr->addr) free (newciptr->addr);
+ free (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) (ciptr, host, port)
+
+XtransConnInfo ciptr;
+char *host;
+char *port;
+
+{
+ char objname[OBJBUFSIZE];
+
+ extern int dnet_conn();
+
+ PRMSG (2,"TRANS(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,
+ "TRANS(DNETConnect): TRANS(DNETGetAddr) () failed:\n", 0, 0, 0);
+ return TRANS_CONNECT_FAILED;
+ }
+
+ if (TRANS(DNETGetPeerAddr) (ciptr) < 0)
+ {
+ PRMSG (1,
+ "TRANS(DNETConnect): TRANS(DNETGetPeerAddr) () failed:\n",
+ 0, 0, 0);
+ return TRANS_CONNECT_FAILED;
+ }
+
+ return 0;
+}
+
+#endif /* TRANS_CLIENT */
+
+
+static int
+TRANS(DNETBytesReadable) (ciptr, pend)
+
+XtransConnInfo ciptr;
+BytesReadable_t *pend;
+
+{
+ PRMSG (2,"TRANS(DNETBytesReadable) (%x,%d,%x)\n", ciptr, ciptr->fd, pend);
+
+#ifdef WIN32
+ return ioctlsocket ((SOCKET) ciptr->fd, FIONREAD, (u_long *) pend);
+#else
+ return ioctl(ciptr->fd, FIONREAD, (char *)pend);
+#endif /* WIN32 */
+}
+
+
+static int
+TRANS(DNETRead) (ciptr, buf, size)
+
+XtransConnInfo ciptr;
+char *buf;
+int size;
+
+{
+ PRMSG (2,"TRANS(DNETRead) (%d,%x,%d)\n", ciptr->fd, buf, size);
+
+#ifdef WIN32
+ return recv ((SOCKET)ciptr->fd, buf, size, 0);
+#else
+ return read (ciptr->fd, buf, size);
+#endif /* WIN32 */
+}
+
+
+static int
+TRANS(DNETWrite) (ciptr, buf, size)
+
+XtransConnInfo ciptr;
+char *buf;
+int size;
+
+{
+ PRMSG (2,"TRANS(DNETWrite) (%d,%x,%d)\n", ciptr->fd, buf, size);
+
+#ifdef WIN32
+ return send ((SOCKET)ciptr->fd, buf, size, 0);
+#else
+ return write (ciptr->fd, buf, size);
+#endif /* WIN32 */
+}
+
+
+static int
+TRANS(DNETReadv) (ciptr, buf, size)
+
+XtransConnInfo ciptr;
+struct iovec *buf;
+int size;
+
+{
+ PRMSG (2,"TRANS(DNETReadv) (%d,%x,%d)\n", ciptr->fd, buf, size);
+
+ return READV (ciptr, buf, size);
+}
+
+
+static int
+TRANS(DNETWritev) (ciptr, buf, size)
+
+XtransConnInfo ciptr;
+struct iovec *buf;
+int size;
+
+{
+ PRMSG (2,"TRANS(DNETWritev) (%d,%x,%d)\n", ciptr->fd, buf, size);
+
+ return WRITEV (ciptr, buf, size);
+}
+
+
+static int
+TRANS(DNETDisconnect) (ciptr)
+
+XtransConnInfo ciptr;
+
+{
+ PRMSG (2,"TRANS(DNETDisconnect) (%x,%d)\n", ciptr, ciptr->fd, 0);
+
+ return shutdown (ciptr->fd, 2); /* disallow further sends and receives */
+}
+
+
+static int
+TRANS(DNETClose) (ciptr)
+
+XtransConnInfo ciptr;
+
+{
+ PRMSG (2,"TRANS(DNETClose) (%x,%d)\n", ciptr, ciptr->fd, 0);
+
+ return close (ciptr->fd);
+}
+
+
+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),
+};
diff --git a/Xtransint.h b/Xtransint.h
new file mode 100644
index 0000000..29c8522
--- /dev/null
+++ b/Xtransint.h
@@ -0,0 +1,432 @@
+/* $Xorg: Xtransint.h,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.
+
+*/
+
+/* 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 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.
+ */
+
+/*
+ * XTRANSDEBUG will enable the PRMSG() macros used in the X Transport
+ * Interface code. Each use of the PRMSG macro has a level associated with
+ * it. XTRANSDEBUG is defined to be a level. If the invocation level is =<
+ * the value of XTRANSDEBUG, then the message will be printed out to stderr.
+ * Recommended levels are:
+ *
+ * XTRANSDEBUG=1 Error messages
+ * XTRANSDEBUG=2 API Function Tracing
+ * XTRANSDEBUG=3 All Function Tracing
+ * XTRANSDEBUG=4 printing of intermediate values
+ * XTRANSDEBUG=5 really detailed stuff
+#define XTRANSDEBUG 2
+ */
+
+#ifndef _XTRANSINT_H_
+#define _XTRANSINT_H_
+
+#ifdef WIN32
+#define _WILLWINSOCK_
+#endif
+
+#include "Xtrans.h"
+
+#ifdef XTRANSDEBUG
+#include <stdio.h>
+#endif /* XTRANSDEBUG */
+
+#include <errno.h>
+#ifdef X_NOT_STDC_ENV
+extern int errno; /* Internal system error number. */
+#endif
+
+#ifndef WIN32
+#include <sys/socket.h>
+
+/*
+ * makedepend screws up on #undef OPEN_MAX, so we define a new symbol
+ */
+
+#ifndef TRANS_OPEN_MAX
+
+#ifndef X_NOT_POSIX
+#ifdef _POSIX_SOURCE
+#include <limits.h>
+#else
+#define _POSIX_SOURCE
+#include <limits.h>
+#undef _POSIX_SOURCE
+#endif
+#endif
+#ifndef OPEN_MAX
+#ifdef SVR4
+#define OPEN_MAX 256
+#else
+#include <sys/param.h>
+#ifndef OPEN_MAX
+#ifdef __OSF1__
+#define OPEN_MAX 256
+#else
+#ifdef NOFILE
+#define OPEN_MAX NOFILE
+#else
+#define OPEN_MAX NOFILES_MAX
+#endif
+#endif
+#endif
+#endif
+#endif
+
+#if OPEN_MAX > 256
+#define TRANS_OPEN_MAX 256
+#else
+#define TRANS_OPEN_MAX OPEN_MAX
+#endif
+
+#endif /* TRANS_OPEN_MAX */
+
+
+#define ESET(val) errno = val
+#define EGET() errno
+
+#else /* WIN32 */
+
+#include <limits.h> /* for USHRT_MAX */
+
+#define ESET(val) WSASetLastError(val)
+#define EGET() WSAGetLastError()
+
+#endif /* WIN32 */
+
+#ifndef NULL
+#define NULL 0
+#endif
+
+#ifdef X11_t
+#define X_TCP_PORT 6000
+#endif
+
+struct _XtransConnInfo {
+ struct _Xtransport *transptr;
+ int index;
+ char *priv;
+ int flags;
+ int fd;
+ char *port;
+ int family;
+ char *addr;
+ int addrlen;
+ char *peeraddr;
+ int peeraddrlen;
+};
+
+#define XTRANS_OPEN_COTS_CLIENT 1
+#define XTRANS_OPEN_COTS_SERVER 2
+#define XTRANS_OPEN_CLTS_CLIENT 3
+#define XTRANS_OPEN_CLTS_SERVER 4
+
+
+typedef struct _Xtransport {
+ char *TransName;
+ int flags;
+
+#ifdef TRANS_CLIENT
+
+ XtransConnInfo (*OpenCOTSClient)(
+#if NeedNestedPrototypes
+ struct _Xtransport *, /* transport */
+ char *, /* protocol */
+ char *, /* host */
+ char * /* port */
+#endif
+ );
+
+#endif /* TRANS_CLIENT */
+
+#ifdef TRANS_SERVER
+
+ XtransConnInfo (*OpenCOTSServer)(
+#if NeedNestedPrototypes
+ struct _Xtransport *, /* transport */
+ char *, /* protocol */
+ char *, /* host */
+ char * /* port */
+#endif
+ );
+
+#endif /* TRANS_SERVER */
+
+#ifdef TRANS_CLIENT
+
+ XtransConnInfo (*OpenCLTSClient)(
+#if NeedNestedPrototypes
+ struct _Xtransport *, /* transport */
+ char *, /* protocol */
+ char *, /* host */
+ char * /* port */
+#endif
+ );
+
+#endif /* TRANS_CLIENT */
+
+#ifdef TRANS_SERVER
+
+ XtransConnInfo (*OpenCLTSServer)(
+#if NeedNestedPrototypes
+ struct _Xtransport *, /* transport */
+ char *, /* protocol */
+ char *, /* host */
+ char * /* port */
+#endif
+ );
+
+#endif /* TRANS_SERVER */
+
+
+#ifdef TRANS_REOPEN
+
+ XtransConnInfo (*ReopenCOTSServer)(
+#if NeedNestedPrototypes
+ struct _Xtransport *, /* transport */
+ int, /* fd */
+ char * /* port */
+#endif
+ );
+
+ XtransConnInfo (*ReopenCLTSServer)(
+#if NeedNestedPrototypes
+ struct _Xtransport *, /* transport */
+ int, /* fd */
+ char * /* port */
+#endif
+ );
+
+#endif /* TRANS_REOPEN */
+
+
+ int (*SetOption)(
+#if NeedNestedPrototypes
+ XtransConnInfo, /* connection */
+ int, /* option */
+ int /* arg */
+#endif
+ );
+
+#ifdef TRANS_SERVER
+
+ int (*CreateListener)(
+#if NeedNestedPrototypes
+ XtransConnInfo, /* connection */
+ char * /* port */
+#endif
+ );
+
+ int (*ResetListener)(
+#if NeedNestedPrototypes
+ XtransConnInfo /* connection */
+#endif
+ );
+
+ XtransConnInfo (*Accept)(
+#if NeedNestedPrototypes
+ XtransConnInfo, /* connection */
+ int * /* status */
+#endif
+ );
+
+#endif /* TRANS_SERVER */
+
+#ifdef TRANS_CLIENT
+
+ int (*Connect)(
+#if NeedNestedPrototypes
+ XtransConnInfo, /* connection */
+ char *, /* host */
+ char * /* port */
+#endif
+ );
+
+#endif /* TRANS_CLIENT */
+
+ int (*BytesReadable)(
+#if NeedNestedPrototypes
+ XtransConnInfo, /* connection */
+ BytesReadable_t * /* pend */
+#endif
+ );
+
+ int (*Read)(
+#if NeedNestedPrototypes
+ XtransConnInfo, /* connection */
+ char *, /* buf */
+ int /* size */
+#endif
+ );
+
+ int (*Write)(
+#if NeedNestedPrototypes
+ XtransConnInfo, /* connection */
+ char *, /* buf */
+ int /* size */
+#endif
+ );
+
+ int (*Readv)(
+#if NeedNestedPrototypes
+ XtransConnInfo, /* connection */
+ struct iovec *, /* buf */
+ int /* size */
+#endif
+ );
+
+ int (*Writev)(
+#if NeedNestedPrototypes
+ XtransConnInfo, /* connection */
+ struct iovec *, /* buf */
+ int /* size */
+#endif
+ );
+
+ int (*Disconnect)(
+#if NeedNestedPrototypes
+ XtransConnInfo /* connection */
+#endif
+ );
+
+ int (*Close)(
+#if NeedNestedPrototypes
+ XtransConnInfo /* connection */
+#endif
+ );
+
+ int (*CloseForCloning)(
+#if NeedNestedPrototypes
+ XtransConnInfo /* connection */
+#endif
+ );
+
+} Xtransport;
+
+
+typedef struct _Xtransport_table {
+ Xtransport *transport;
+ int transport_id;
+} Xtransport_table;
+
+
+/*
+ * Flags for the flags member of Xtransport.
+ */
+
+#define TRANS_ALIAS (1<<0) /* record is an alias, don't create server */
+#define TRANS_LOCAL (1<<1) /* local transport */
+
+
+/*
+ * readv() and writev() don't exist or don't work correctly on some
+ * systems, so they may be emulated.
+ */
+
+#if defined(CRAY) || (defined(SYSV) && defined(SYSV386)) || defined(WIN32) || defined(__sxg__) || defined(sco324)
+
+#define READV(ciptr, iov, iovcnt) TRANS(ReadV)(ciptr, iov, iovcnt)
+
+static int TRANS(ReadV)(
+#if NeedFunctionPrototypes
+ XtransConnInfo, /* ciptr */
+ struct iovec *, /* iov */
+ int /* iovcnt */
+#endif
+);
+
+#else
+
+#define READV(ciptr, iov, iovcnt) readv(ciptr->fd, iov, iovcnt)
+
+#endif /* CRAY || (SYSV && SYSV386) || WIN32 || __sxg__ || sco324 */
+
+
+#if defined(CRAY) || defined(WIN32) || defined(__sxg__) || defined(sco324)
+
+#define WRITEV(ciptr, iov, iovcnt) TRANS(WriteV)(ciptr, iov, iovcnt)
+
+static int TRANS(WriteV)(
+#if NeedFunctionPrototypes
+ XtransConnInfo, /* ciptr */
+ struct iovec *, /* iov */
+ int /* iovcnt */
+#endif
+);
+
+#else
+
+#define WRITEV(ciptr, iov, iovcnt) writev(ciptr->fd, iov, iovcnt)
+
+#endif /* CRAY || WIN32 || __sxg__ || sco324 */
+
+
+static int is_numeric (
+#if NeedFunctionPrototypes
+ char * /* str */
+#endif
+);
+
+
+/*
+ * Some XTRANSDEBUG stuff
+ */
+
+#if defined(XTRANSDEBUG)
+#define PRMSG(lvl,x,a,b,c) if (lvl <= XTRANSDEBUG){ \
+ int saveerrno=errno; \
+ fprintf(stderr, x,a,b,c); fflush(stderr); \
+ errno=saveerrno; \
+ }
+#else
+#define PRMSG(lvl,x,a,b,c)
+#endif /* XTRANSDEBUG */
+
+#endif /* _XTRANSINT_H_ */
diff --git a/Xtranslcl.c b/Xtranslcl.c
new file mode 100644
index 0000000..1dde90f
--- /dev/null
+++ b/Xtranslcl.c
@@ -0,0 +1,2715 @@
+/* $Xorg: Xtranslcl.c,v 1.6 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.
+
+*/
+
+/* 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 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.
+ */
+
+/*
+ *
+ * The connection code/ideas in lib/X and server/os for SVR4/Intel
+ * environments was contributed by the following companies/groups:
+ *
+ * MetroLink Inc
+ * NCR
+ * Pittsburgh Powercomputing Corporation (PPc)/Quarterdeck Office Systems
+ * SGCS
+ * Unix System Laboratories (USL) / Novell
+ * XFree86
+ *
+ * The goal is to have common connection code among all SVR4/Intel vendors.
+ *
+ * ALL THE ABOVE COMPANIES DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS,
+ * IN NO EVENT SHALL THESE COMPANIES * 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.
+ */
+
+#include <errno.h>
+#include <ctype.h>
+#include <sys/signal.h>
+#include <sys/ioctl.h>
+#include <sys/stat.h>
+#if 0
+#include <sys/ptms.h> /* Maybe for SVR4 only?? */
+#endif
+#ifdef SVR4
+#include <sys/filio.h>
+#endif
+#include <sys/stropts.h>
+#include <sys/wait.h>
+#include <sys/types.h>
+
+/*
+ * The local transports should be treated the same as a UNIX domain socket
+ * wrt authentication, etc. Because of this, we will use struct sockaddr_un
+ * for the address format. This will simplify the code in other places like
+ * The X Server.
+ */
+
+#include <sys/socket.h>
+#include <sys/un.h>
+
+
+/*
+ * These functions actually implement the local connection mechanisms.
+ */
+
+/* Type Not Supported */
+
+static int
+TRANS(OpenFail)(ciptr, port)
+
+XtransConnInfo ciptr;
+char *port;
+
+{
+ return -1;
+}
+
+#ifdef TRANS_REOPEN
+
+static int
+TRANS(ReopenFail)(ciptr, fd, port)
+
+XtransConnInfo ciptr;
+int fd;
+char *port;
+
+{
+ return 0;
+}
+
+#endif /* TRANS_REOPEN */
+
+
+
+static int
+TRANS(FillAddrInfo)(ciptr, sun_path, peer_sun_path)
+
+XtransConnInfo ciptr;
+char *sun_path;
+char *peer_sun_path;
+
+{
+ struct sockaddr_un *sunaddr;
+ struct sockaddr_un *p_sunaddr;
+
+ ciptr->family = AF_UNIX;
+ ciptr->addrlen = sizeof (struct sockaddr_un);
+
+ if ((sunaddr = (struct sockaddr_un *) malloc (ciptr->addrlen)) == NULL)
+ {
+ PRMSG(1,"TRANS(FillAddrInfo)() failed to allocate memory for addr\n",
+ 0,0,0);
+ return 0;
+ }
+
+ sunaddr->sun_family = AF_UNIX;
+
+ strcpy (sunaddr->sun_path, sun_path);
+#ifdef BSD44SOCKETS
+ sunaddr->sun_len = strlen (sunaddr->sun_path);
+#endif
+
+ ciptr->addr = (char *) sunaddr;
+
+ ciptr->peeraddrlen = sizeof (struct sockaddr_un);
+
+ if ((p_sunaddr = (struct sockaddr_un *) malloc (
+ ciptr->peeraddrlen)) == NULL)
+ {
+ PRMSG(1,
+ "TRANS(FillAddrInfo)() failed to allocate memory for peer addr\n",
+ 0,0,0);
+ free ((char *) sunaddr);
+ ciptr->addr = NULL;
+
+ return 0;
+ }
+
+ p_sunaddr->sun_family = AF_UNIX;
+
+ strcpy (p_sunaddr->sun_path, peer_sun_path);
+#ifdef BSD44SOCKETS
+ p_sunaddr->sun_len = strlen (p_sunaddr->sun_path);
+#endif
+
+ ciptr->peeraddr = (char *) p_sunaddr;
+
+ return 1;
+}
+
+
+
+/* PTS */
+
+#if defined(SYSV) && !defined(sco)
+#define SIGNAL_T int
+#else
+#define SIGNAL_T void
+#endif /* SYSV */
+
+typedef SIGNAL_T (*PFV)();
+
+extern PFV signal();
+
+extern char *ptsname(
+#if NeedFunctionPrototypes
+ int
+#endif
+);
+
+static void _dummy(sig)
+
+int sig;
+
+{
+}
+
+#ifndef sun
+#define X_STREAMS_DIR "/dev/X"
+#define DEV_SPX "/dev/spx"
+#else
+#ifndef X11_t
+#define X_STREAMS_DIR "/dev/X"
+#else
+#define X_STREAMS_DIR "/tmp/.X11-pipe"
+#endif
+#endif
+#define DEV_PTMX "/dev/ptmx"
+
+#if defined(X11_t)
+
+#define PTSNODENAME "/dev/X/server."
+#ifndef sun
+#define NAMEDNODENAME "/dev/X/Nserver."
+#else
+#define NAMEDNODENAME "/tmp/.X11-pipe/X"
+#endif
+
+/*
+ * ISC and SCO are only defined for X11 since they are there for
+ * backwards binary compatability only.
+ */
+
+#define X_ISC_DIR "/dev/X"
+#define ISCDEVNODENAME "/dev/X/ISCCONN/X%s"
+#define ISCTMPNODENAME "/tmp/.X11-unix/X%s"
+#define SCORNODENAME "/dev/X%1sR"
+#define SCOSNODENAME "/dev/X%1sS"
+#endif
+#if defined(XIM_t)
+#define PTSNODENAME "/dev/X/XIM."
+#define NAMEDNODENAME "/dev/X/NXIM."
+#endif
+#if defined(FS_t) || defined (FONT_t)
+/*
+ * USL has already defined something here. We need to check with them
+ * and see if their choice is usable here.
+ */
+#define PTSNODENAME "/dev/X/fontserver."
+#define NAMEDNODENAME "/dev/X/Nfontserver."
+#endif
+#if defined(ICE_t)
+#define PTSNODENAME "/dev/X/ICE."
+#define NAMEDNODENAME "/dev/X/NICE."
+#endif
+#if defined(TEST_t)
+#define PTSNODENAME "/dev/X/transtest."
+#define NAMEDNODENAME "/dev/X/Ntranstest."
+#endif
+
+
+
+#ifndef sun
+#ifdef TRANS_CLIENT
+
+static int
+TRANS(PTSOpenClient)(ciptr, port)
+
+XtransConnInfo ciptr;
+char *port;
+
+{
+ int fd,server,exitval,alarm_time,ret;
+ char server_path[64];
+ char *slave, namelen;
+ char buf[20]; /* MAX_PATH_LEN?? */
+ PFV savef;
+ pid_t saved_pid;
+
+ PRMSG(2,"TRANS(PTSOpenClient)(%s)\n", port, 0,0 );
+
+#if !defined(PTSNODENAME)
+ PRMSG(1,"Protocol is not supported by a pts connection\n", 0,0,0);
+ return -1;
+#else
+ if (port && *port ) {
+ if( *port == '/' ) { /* A full pathname */
+ (void) sprintf(server_path, "%s", port);
+ } else {
+ (void) sprintf(server_path, "%s%s", PTSNODENAME, port);
+ }
+ } else {
+ (void) sprintf(server_path, "%s%d", PTSNODENAME, getpid());
+ }
+
+
+ /*
+ * Open the node the on which the server is listening.
+ */
+
+ if ((server = open (server_path, O_RDWR)) < 0) {
+ PRMSG(1,"TRANS(PTSOpenClient)() failed to open %s\n", server_path, 0,0);
+ return -1;
+ }
+
+
+ /*
+ * Open the streams based pipe that will be this connection.
+ */
+
+ if ((fd = open("/dev/ptmx", O_RDWR)) < 0) {
+ PRMSG(1,"TRANS(PTSOpenClient)() failed to open /dev/ptmx\n", 0,0,0);
+ return -1;
+ }
+
+ (void) grantpt(fd);
+ (void) unlockpt(fd);
+
+ slave = ptsname(fd); /* get name */
+
+ if( slave == NULL ) {
+ PRMSG(1,"TRANS(PTSOpenClient)() failed to get ptsname()\n", 0,0,0);
+ close(fd);
+ close(server);
+ return -1;
+ }
+
+ /*
+ * This is neccesary for the case where a program is setuid to non-root.
+ * grantpt() calls /usr/lib/pt_chmod which is set-uid root. This program will
+ * set the owner of the pt device incorrectly if the uid is not restored
+ * before it is called. The problem is that once it gets restored, it
+ * cannot be changed back to its original condition, hence the fork().
+ */
+
+ if(!(saved_pid=fork())) {
+ uid_t saved_euid;
+
+ saved_euid = geteuid();
+ setuid( getuid() ); /** sets the euid to the actual/real uid **/
+ if( chown( slave, saved_euid, -1 ) < 0 ) {
+ exit( 1 );
+ }
+
+ exit( 0 );
+ }
+
+ waitpid(saved_pid, &exitval, 0);
+
+ if (chmod(slave, 0666) < 0) {
+ close(fd);
+ close(server);
+ PRMSG(1,"Cannot chmod %s\n", slave, 0,0);
+ return(-1);
+ }
+
+ /*
+ * write slave name to server
+ */
+
+ namelen = strlen(slave);
+ buf[0] = namelen;
+ (void) sprintf(&buf[1], slave);
+ (void) write(server, buf, namelen+1);
+ (void) close(server);
+
+ /*
+ * wait for server to respond
+ */
+
+ savef = signal(SIGALRM, _dummy);
+ alarm_time = alarm (30); /* CONNECT_TIMEOUT */
+
+ ret = read(fd, buf, 1);
+
+ (void) alarm(alarm_time);
+ (void) signal(SIGALRM, savef);
+
+ if (ret != 1) {
+ PRMSG(1,
+ "TRANS(PTSOpenClient)() failed to get acknoledgement from server\n",
+ 0,0,0);
+ (void) close(fd);
+ fd = -1;
+ }
+
+ /*
+ * Everything looks good: fill in the XtransConnInfo structure.
+ */
+
+ if (TRANS(FillAddrInfo) (ciptr, slave, server_path) == 0)
+ {
+ PRMSG(1,"TRANS(PTSOpenClient)() failed to fill in addr info\n",
+ 0,0,0);
+ close(fd);
+ return -1;
+ }
+
+ return(fd);
+
+#endif /* !PTSNODENAME */
+}
+
+#endif /* TRANS_CLIENT */
+
+
+#ifdef TRANS_SERVER
+
+static int
+TRANS(PTSOpenServer)(ciptr, port)
+
+XtransConnInfo ciptr;
+char *port;
+
+{
+ int fd, server;
+ char server_path[64], *slave;
+
+ PRMSG(2,"TRANS(PTSOpenServer)(%s)\n", port, 0,0 );
+
+#if !defined(PTSNODENAME)
+ PRMSG(1,"Protocol is not supported by a pts connection\n", 0,0,0);
+ return -1;
+#else
+ if (port && *port ) {
+ if( *port == '/' ) { /* A full pathname */
+ (void) sprintf(server_path, "%s", port);
+ } else {
+ (void) sprintf(server_path, "%s%s", PTSNODENAME, port);
+ }
+ } else {
+ (void) sprintf(server_path, "%s%d", PTSNODENAME, getpid());
+ }
+
+#ifdef HAS_STICKY_DIR_BIT
+ mkdir(X_STREAMS_DIR, 01777);
+ chmod(X_STREAMS_DIR, 01777);
+#else
+ mkdir(X_STREAMS_DIR, 0777);
+ chmod(X_STREAMS_DIR, 0777);
+#endif
+
+ if( (fd=open(server_path, O_RDWR)) >= 0 ) {
+ PRMSG(1, "A server is already running on port %s\n", port, 0,0 );
+ PRMSG(1, "Remove %s if this is incorrect.\n", server_path, 0,0 );
+ close(fd);
+ return(-1);
+ }
+
+ unlink(server_path);
+
+ if( (fd=open(DEV_PTMX, O_RDWR)) < 0) {
+ PRMSG(1, "Unable to open %s\n", DEV_PTMX, 0,0 );
+ return(-1);
+ }
+
+ grantpt(fd);
+ unlockpt(fd);
+
+ if( (slave=ptsname(fd)) == NULL) {
+ PRMSG(1, "Unable to get slave device name\n", 0,0,0 );
+ close(fd);
+ return(-1);
+ }
+
+ if( link(slave,server_path) < 0 ) {
+ PRMSG(1, "Unable to link %s to %s\n", slave, server_path,0 );
+ close(fd);
+ return(-1);
+ }
+
+ if( chmod(server_path, 0666) < 0 ) {
+ PRMSG(1, "Unable to chmod %s to 0666\n", server_path,0,0 );
+ close(fd);
+ return(-1);
+ }
+
+ if( (server=open(server_path, O_RDWR)) < 0 ) {
+ PRMSG(1, "Unable to open server device %s\n", server_path,0,0 );
+ close(fd);
+ return(-1);
+ }
+
+ close(server);
+
+ /*
+ * Everything looks good: fill in the XtransConnInfo structure.
+ */
+
+ if (TRANS(FillAddrInfo) (ciptr, server_path, server_path) == 0)
+ {
+ PRMSG(1,"TRANS(PTSOpenServer)() failed to fill in addr info\n",
+ 0,0,0);
+ close(fd);
+ return -1;
+ }
+
+ return fd;
+
+#endif /* !PTSNODENAME */
+}
+
+static int
+TRANS(PTSAccept)(ciptr, newciptr, status)
+
+XtransConnInfo ciptr;
+XtransConnInfo newciptr;
+int *status;
+
+{
+ int newfd;
+ int in;
+ unsigned char length;
+ char buf[256];
+ struct sockaddr_un *sunaddr;
+
+ PRMSG(2,"TRANS(PTSAccept)(%x->%d)\n",ciptr,ciptr->fd,0);
+
+ if( (in=read(ciptr->fd,&length,1)) <= 0 ){
+ if( !in ) {
+ PRMSG(1,
+ "TRANS(PTSAccept)() Incoming connection closed\n",0,0,0);
+ }
+ else {
+ PRMSG(1,
+ "TRANS(PTSAccept)() Error reading incoming connection. errno=%d \n",
+ errno,0,0);
+ }
+ *status = TRANS_ACCEPT_MISC_ERROR;
+ return -1;
+ }
+
+ if( (in=read(ciptr->fd,buf,length)) <= 0 ){
+ if( !in ) {
+ PRMSG(1,
+ "TRANS(PTSAccept)() Incoming connection closed\n",0,0,0);
+ }
+ else {
+ PRMSG(1,
+"TRANS(PTSAccept)() Error reading device name for new connection. errno=%d \n",
+ errno,0,0);
+ }
+ *status = TRANS_ACCEPT_MISC_ERROR;
+ return -1;
+ }
+
+ buf[length] = '\0';
+
+ if( (newfd=open(buf,O_RDWR)) < 0 ) {
+ PRMSG(1, "TRANS(PTSAccept)() Failed to open %s\n",buf,0,0);
+ *status = TRANS_ACCEPT_MISC_ERROR;
+ return -1;
+ }
+
+ write(newfd,"1",1);
+
+ /*
+ * Everything looks good: fill in the XtransConnInfo structure.
+ */
+
+ newciptr->addrlen=ciptr->addrlen;
+ if( (newciptr->addr=(char *)malloc(newciptr->addrlen)) == NULL ) {
+ PRMSG(1,"TRANS(PTSAccept)() failed to allocate memory for peer addr\n",
+ 0,0,0);
+ close(newfd);
+ *status = TRANS_ACCEPT_BAD_MALLOC;
+ return -1;
+ }
+
+ memcpy(newciptr->addr,ciptr->addr,newciptr->addrlen);
+
+ newciptr->peeraddrlen=sizeof(struct sockaddr_un);
+ if( (sunaddr=(struct sockaddr_un *)malloc(newciptr->peeraddrlen)) == NULL ) {
+ PRMSG(1,"TRANS(PTSAccept)() failed to allocate memory for peer addr\n",
+ 0,0,0);
+ free(newciptr->addr);
+ close(newfd);
+ *status = TRANS_ACCEPT_BAD_MALLOC;
+ return -1;
+ }
+
+ sunaddr->sun_family=AF_UNIX;
+ strcpy(sunaddr->sun_path,buf);
+#ifdef BSD44SOCKETS
+ sunaddr->sun_len=strlen(sunaddr->sun_path);
+#endif
+
+ newciptr->peeraddr=(char *)sunaddr;
+
+ *status = 0;
+
+ return newfd;
+}
+
+#endif /* TRANS_SERVER */
+#endif /* sun */
+
+
+#ifdef SVR4
+
+/* NAMED */
+
+#ifdef TRANS_CLIENT
+
+static int
+TRANS(NAMEDOpenClient)(ciptr, port)
+
+XtransConnInfo ciptr;
+char *port;
+
+{
+ int fd;
+ char server_path[64];
+ struct stat filestat;
+ extern int isastream();
+
+ PRMSG(2,"TRANS(NAMEDOpenClient)(%s)\n", port, 0,0 );
+
+#if !defined(NAMEDNODENAME)
+ PRMSG(1,"Protocol is not supported by a NAMED connection\n", 0,0,0);
+ return -1;
+#else
+ if ( port && *port ) {
+ if( *port == '/' ) { /* A full pathname */
+ (void) sprintf(server_path, "%s", port);
+ } else {
+ (void) sprintf(server_path, "%s%s", NAMEDNODENAME, port);
+ }
+ } else {
+ (void) sprintf(server_path, "%s%d", NAMEDNODENAME, getpid());
+ }
+
+ if (stat(server_path, &filestat) < 0 ) {
+ PRMSG(1,"No device %s for NAMED connection\n", server_path, 0,0 );
+ return -1;
+ }
+
+ if ((filestat.st_mode & S_IFMT) != S_IFIFO) {
+ PRMSG(1,"Device %s is not a FIFO\n", server_path, 0,0 );
+ /* Is this really a failure? */
+ return -1;
+ }
+
+ if ((fd = open(server_path, O_RDWR)) < 0) {
+ PRMSG(1,"Cannot open %s for NAMED connection\n", server_path, 0,0 );
+ return -1;
+ }
+
+ if (isastream(fd) <= 0) {
+ PRMSG(1,"%s is not a streams device\n", server_path, 0,0 );
+ (void) close(fd);
+ return -1;
+ }
+
+ /*
+ * Everything looks good: fill in the XtransConnInfo structure.
+ */
+
+ if (TRANS(FillAddrInfo) (ciptr, server_path, server_path) == 0)
+ {
+ PRMSG(1,"TRANS(NAMEDOpenClient)() failed to fill in addr info\n",
+ 0,0,0);
+ close(fd);
+ return -1;
+ }
+
+ return(fd);
+
+#endif /* !NAMEDNODENAME */
+}
+
+#endif /* TRANS_CLIENT */
+
+
+#ifdef TRANS_SERVER
+
+static int
+TRANS(NAMEDOpenServer)(ciptr, port)
+
+XtransConnInfo ciptr;
+char *port;
+
+{
+ int fd, pipefd[2];
+ char server_path[64];
+ struct stat sbuf;
+
+ PRMSG(2,"TRANS(NAMEDOpenServer)(%s)\n", port, 0,0 );
+
+#if !defined(NAMEDNODENAME)
+ PRMSG(1,"Protocol is not supported by a NAMED connection\n", 0,0,0);
+ return -1;
+#else
+ if ( port && *port ) {
+ if( *port == '/' ) { /* A full pathname */
+ (void) sprintf(server_path, "%s", port);
+ } else {
+ (void) sprintf(server_path, "%s%s", NAMEDNODENAME, port);
+ }
+ } else {
+ (void) sprintf(server_path, "%s%d", NAMEDNODENAME, getpid());
+ }
+
+#ifdef HAS_STICKY_DIR_BIT
+ mkdir(X_STREAMS_DIR, 01777);
+ chmod(X_STREAMS_DIR, 01777);
+#else
+ mkdir(X_STREAMS_DIR, 0777);
+ chmod(X_STREAMS_DIR, 0777);
+#endif
+
+ if(stat(server_path, &sbuf) != 0) {
+ if (errno == ENOENT) {
+ if ((fd = creat(server_path, (mode_t)0666)) == -1) {
+ PRMSG(1, "Can't open %s\n", server_path, 0,0 );
+ return(-1);
+ }
+ close(fd);
+ if (chmod(server_path, (mode_t)0666) < 0) {
+ PRMSG(1, "Can't open %s\n", server_path, 0,0 );
+ return(-1);
+ }
+ } else {
+ PRMSG(1, "stat on %s failed\n", server_path, 0,0 );
+ return(-1);
+ }
+ }
+
+ if( pipe(pipefd) != 0) {
+ PRMSG(1, "pipe() failed, errno=%d\n",errno, 0,0 );
+ return(-1);
+ }
+
+ if( ioctl(pipefd[0], I_PUSH, "connld") != 0) {
+ PRMSG(1, "ioctl(I_PUSH,\"connld\") failed, errno=%d\n",errno, 0,0 );
+ close(pipefd[0]);
+ close(pipefd[1]);
+ return(-1);
+ }
+
+ if( fattach(pipefd[0], server_path) != 0) {
+ PRMSG(1, "fattach(%s) failed, errno=%d\n", server_path,errno, 0 );
+ close(pipefd[0]);
+ close(pipefd[1]);
+ return(-1);
+ }
+
+ /*
+ * Everything looks good: fill in the XtransConnInfo structure.
+ */
+
+ if (TRANS(FillAddrInfo) (ciptr, server_path, server_path) == 0)
+ {
+ PRMSG(1,"TRANS(NAMEDOpenServer)() failed to fill in addr info\n",
+ 0,0,0);
+ close(fd);
+ return -1;
+ }
+
+ return(pipefd[1]);
+
+#endif /* !NAMEDNODENAME */
+}
+
+static int
+TRANS(NAMEDAccept)(ciptr, newciptr, status)
+
+XtransConnInfo ciptr;
+XtransConnInfo newciptr;
+int *status;
+
+{
+ struct strrecvfd str;
+
+ PRMSG(2,"TRANS(NAMEDAccept)(%x->%d)\n", ciptr, ciptr->fd, 0 );
+
+ if( ioctl(ciptr->fd, I_RECVFD, &str ) < 0 ) {
+ PRMSG(1, "ioctl(I_RECVFD) failed, errno=%d\n", errno, 0,0 );
+ *status = TRANS_ACCEPT_MISC_ERROR;
+ return(-1);
+ }
+
+ /*
+ * Everything looks good: fill in the XtransConnInfo structure.
+ */
+
+ newciptr->addrlen=ciptr->addrlen;
+ if( (newciptr->addr=(char *)malloc(newciptr->addrlen)) == NULL ) {
+ PRMSG(1,
+ "TRANS(NAMEDAccept)() failed to allocate memory for peer addr\n",
+ 0,0,0);
+ close(str.fd);
+ *status = TRANS_ACCEPT_BAD_MALLOC;
+ return -1;
+ }
+
+ memcpy(newciptr->addr,ciptr->addr,newciptr->addrlen);
+
+ newciptr->peeraddrlen=newciptr->addrlen;
+ if( (newciptr->peeraddr=(char *)malloc(newciptr->peeraddrlen)) == NULL ) {
+ PRMSG(1,
+ "TRANS(NAMEDAccept)() failed to allocate memory for peer addr\n",
+ 0,0,0);
+ free(newciptr->addr);
+ close(str.fd);
+ *status = TRANS_ACCEPT_BAD_MALLOC;
+ return -1;
+ }
+
+ memcpy(newciptr->peeraddr,newciptr->addr,newciptr->peeraddrlen);
+
+ *status = 0;
+
+ return str.fd;
+}
+
+#endif /* TRANS_SERVER */
+
+#endif /* SVR4 */
+
+
+
+#ifndef sun
+/*
+ * connect_spipe is used by both the SCO and ISC connection types.
+ */
+static int
+connect_spipe(fd1, fd2)
+
+int fd1, fd2;
+
+{
+ long temp;
+ struct strfdinsert sbuf;
+
+ sbuf.databuf.maxlen = -1;
+ sbuf.databuf.len = -1;
+ sbuf.databuf.buf = NULL;
+ sbuf.ctlbuf.maxlen = sizeof(long);
+ sbuf.ctlbuf.len = sizeof(long);
+ sbuf.ctlbuf.buf = (caddr_t)&temp;
+ sbuf.offset = 0;
+ sbuf.fildes = fd2;
+ sbuf.flags = 0;
+
+ if( ioctl(fd1, I_FDINSERT, &sbuf) < 0 )
+ return(-1);
+
+ return(0);
+}
+
+/*
+ * connect_spipe is used by both the SCO and ISC connection types.
+ */
+
+static int
+named_spipe(fd, path)
+
+int fd;
+char *path;
+
+{
+ int oldUmask, ret;
+ struct stat sbuf;
+
+ oldUmask = umask(0);
+
+ (void) fstat(fd, &sbuf);
+ ret = mknod(path, 0020666, sbuf.st_rdev);
+
+ umask(oldUmask);
+
+ if (ret < 0) {
+ ret = -1;
+ } else {
+ ret = fd;
+ }
+
+ return(ret);
+}
+
+
+/* ISC */
+
+#ifdef TRANS_CLIENT
+
+static int
+TRANS(ISCOpenClient)(ciptr, port)
+
+XtransConnInfo ciptr;
+char *port;
+
+{
+ int fd,fds,server;
+ char server_path[64];
+ char server_dev_path[64];
+ struct strfdinsert buf;
+ long temp;
+ mode_t spmode;
+ struct stat filestat;
+
+ PRMSG(2,"TRANS(ISCOpenClient)(%s)\n", port, 0,0 );
+
+#if !defined(ISCDEVNODENAME)
+ PRMSG(1,"Protocol is not supported by a ISC connection\n", 0,0,0);
+ return -1;
+#else
+ (void) sprintf(server_path, ISCTMPNODENAME, port);
+ (void) sprintf(server_dev_path, ISCDEVNODENAME, port);
+
+ fd = fds = server = -1;
+
+ if (stat(DEV_SPX, &filestat) == -1) {
+ PRMSG(1, "stat(%s) failed, errno=%d\n", DEV_SPX, errno, 0 );
+ return(-1);
+ }
+
+ spmode = (filestat.st_mode & S_IFMT);
+
+ if (stat(server_path, &filestat) != -1) {
+ if ((filestat.st_mode & S_IFMT) == spmode) {
+ if ((server = open(server_path, O_RDWR)) < 0) {
+ PRMSG(1,"TRANS(ISCOpenClient): failed to open %s\n",
+ server_path, 0,0 );
+ }
+ }
+ }
+
+ if (server < 0) {
+ /* try the alternate path */
+ if (stat(server_dev_path, &filestat) != -1) {
+ if ((filestat.st_mode & S_IFMT) == spmode) {
+ if ((server = open(server_dev_path, O_RDWR)) < 0) {
+ PRMSG(1,"TRANS(ISCOpenClient): failed to open %s\n",
+ server_dev_path, 0,0 );
+ }
+ }
+ }
+ }
+
+ if (server < 0) {
+ PRMSG(1,"TRANS(ISCOpenClient): can't open either device %s or %s\n",
+ server_path, server_dev_path, 0 );
+ return -1;
+ }
+
+ if ((fds = open(DEV_SPX, O_RDWR)) < 0 ||
+ (fd = open(DEV_SPX, O_RDWR)) < 0) {
+ /* Failed to open all of the devices */
+ PRMSG(1,"TRANS(ISCOpenClient): can't open %s\n", DEV_SPX, 0,0 );
+ (void) close(server);
+ if (fds != -1)
+ (void) close(fds);
+ if (fd != -1)
+ (void) close(fd);
+ return -1;
+ }
+
+ /* make a STREAMS-pipe */
+
+ buf.databuf.maxlen = -1;
+ buf.databuf.len = -1;
+ buf.databuf.buf = NULL;
+ buf.ctlbuf.maxlen = sizeof(long);
+ buf.ctlbuf.len = sizeof(long);
+ buf.ctlbuf.buf = (caddr_t)&temp;
+ buf.offset = 0;
+ buf.fildes = fd;
+ buf.flags = 0;
+
+ if (ioctl(fds, I_FDINSERT, &buf) < 0 ||
+ ioctl(server, I_SENDFD, fds) < 0) {
+ PRMSG(1,"TRANS(ISCOpenClient): ioctl(I_FDINSERT or I_SENDFD) failed\n",
+ 0,0,0 );
+ (void) close(server);
+ (void) close(fds);
+ (void) close(fd);
+ return -1;
+ }
+
+ /*
+ * Everything looks good: fill in the XtransConnInfo structure.
+ */
+
+ if (TRANS(FillAddrInfo) (ciptr, server_path, server_path) == 0)
+ {
+ PRMSG(1,"TRANS(ISCOpenClient)() failed to fill in addr info\n",
+ 0,0,0);
+ close(fd);
+ return -1;
+ }
+
+ return (fd);
+
+#endif /* !ISCDEVNODENAME */
+}
+
+#endif /* TRANS_CLIENT */
+
+
+#ifdef TRANS_SERVER
+
+static int
+TRANS(ISCOpenServer)(ciptr, port)
+
+XtransConnInfo ciptr;
+char *port;
+
+{
+ int fd = -1,fds = -1;
+ char server_path[64],server_unix_path[64];
+
+ PRMSG(2,"TRANS(ISCOpenServer)(%s)\n", port, 0,0 );
+
+#if !defined(ISCDEVNODENAME)
+ PRMSG(1,"Protocol is not supported by a ISC connection\n", 0,0,0);
+ return -1;
+#else
+ (void) sprintf(server_path, ISCDEVNODENAME, port);
+ (void) sprintf(server_unix_path, ISCTMPNODENAME, port);
+
+#ifdef HAS_STICKY_DIR_BIT
+ mkdir(X_STREAMS_DIR, 01777); /* "/dev/X" */
+ chmod(X_STREAMS_DIR, 01777);
+ mkdir(X_ISC_DIR, 01777); /* "/dev/X/ISCCONN" */
+ chmod(X_ISC_DIR, 01777);
+#else
+ mkdir(X_STREAMS_DIR, 0777); /* "/dev/X" */
+ chmod(X_STREAMS_DIR, 0777);
+ mkdir(X_ISC_DIR, 0777); /* "/dev/X/ISCCONN" */
+ chmod(X_ISC_DIR, 0777);
+#endif
+
+ unlink(server_path);
+
+ if( ((fds=open(DEV_SPX, O_RDWR)) < 0) ||
+ ((fd =open(DEV_SPX, O_RDWR)) < 0)) {
+ PRMSG(1,"TRANS(ISCOpenServer): failed to open %s\n", DEV_SPX, 0,0 );
+ return -1;
+ }
+
+ if( (connect_spipe(fds, fd) < 0) ||
+ (named_spipe(fds, server_path) < 0)) {
+ PRMSG(1,"TRANS(ISCOpenServer): failed connect pipes\n", 0,0,0 );
+ close(fd);
+ close(fds);
+ return -1;
+ }
+
+#if !defined(UNIXCONN)
+ /*
+ * If the UNIX Domain socket transport is not being used, then link this
+ * device to the path /tmp/.X11-unix/X path.
+ */
+#define X_UNIX_DIR "/tmp/.X11-unix"
+
+#ifdef HAS_STICKY_DIR_BIT
+ if (!mkdir(X_UNIX_DIR, 01777))
+ chmod(X_UNIX_DIR, 01777);
+#else
+ if (!mkdir(X_UNIX_DIR, 0777))
+ chmod(X_UNIX_DIR, 0777);
+#endif
+
+ unlink(server_unix_path);
+
+#ifdef SVR4
+ /* we prefer symbolic links because hard links can't cross file systems */
+ if( symlink(server_path, server_unix_path) < 0 )
+ PRMSG(1,"TRANS(ISCOpenServer): failed to link %s to %s\n",
+ server_path, server_unix_path, 0 );
+ /*
+ * Don't make this failure fatal since the listener
+ * is already established, and this just for compatability
+ */
+#else
+ if( link(server_path, server_unix_path) < 0 )
+ PRMSG(1,"TRANS(ISCOpenServer): failed to link %s to %s\n",
+ server_path, server_unix_path, 0 );
+ /*
+ * Don't make this failure fatal since the listener
+ * is already established, and this just for compatability
+ */
+#endif /* SVR4 */
+#endif /* !UNIXCONN */
+
+ /*
+ * Everything looks good: fill in the XtransConnInfo structure.
+ */
+
+ if (TRANS(FillAddrInfo) (ciptr, server_path, server_path) == 0)
+ {
+ PRMSG(1,"TRANS(ISCOpenServer)() failed to fill in addr info\n",
+ 0,0,0);
+ close(fd);
+ return -1;
+ }
+
+ return fd;
+
+#endif /* !ISCDEVNODENAME */
+}
+
+static int
+TRANS(ISCAccept)(ciptr, newciptr, status)
+
+XtransConnInfo ciptr;
+XtransConnInfo newciptr;
+int *status;
+
+{
+ struct strrecvfd str;
+
+ PRMSG(2,"TRANS(ISCAccept)(%d)\n", ciptr->fd, 0,0 );
+
+ while (ioctl(ciptr->fd, I_RECVFD, &str) < 0) {
+ if (errno != EAGAIN) {
+ PRMSG(1,"TRANS(ISCAccept): Can't read fildes", 0,0,0 );
+ *status = TRANS_ACCEPT_MISC_ERROR;
+ return(-1);
+ }
+ }
+
+ /*
+ * Everything looks good: fill in the XtransConnInfo structure.
+ */
+
+ newciptr->addrlen=ciptr->addrlen;
+ if( (newciptr->addr=(char *)malloc(newciptr->addrlen)) == NULL ) {
+ PRMSG(1,
+ "TRANS(ISCAccept)() failed to allocate memory for peer addr\n",
+ 0,0,0);
+ close(str.fd);
+ *status = TRANS_ACCEPT_BAD_MALLOC;
+ return -1;
+ }
+
+ memcpy(newciptr->addr,ciptr->addr,newciptr->addrlen);
+
+ newciptr->peeraddrlen=newciptr->addrlen;
+ if( (newciptr->peeraddr=(char *)malloc(newciptr->peeraddrlen)) == NULL ) {
+ PRMSG(1,
+ "TRANS(ISCAccept)() failed to allocate memory for peer addr\n",
+ 0,0,0);
+ free(newciptr->addr);
+ close(str.fd);
+ *status = TRANS_ACCEPT_BAD_MALLOC;
+ return -1;
+ }
+
+ memcpy(newciptr->peeraddr,newciptr->addr,newciptr->peeraddrlen);
+
+ *status = 0;
+
+ return(str.fd);
+}
+
+#endif /* TRANS_SERVER */
+
+
+
+
+/* SCO */
+
+#ifdef TRANS_CLIENT
+
+static int
+TRANS(SCOOpenClient)(ciptr, port)
+
+XtransConnInfo ciptr;
+char *port;
+
+{
+ int fd, server, fl, ret;
+ char server_path[64];
+ struct strbuf ctlbuf;
+ unsigned long alarm_time;
+ void (*savef)();
+ long temp;
+ extern int getmsg(), putmsg();
+
+ PRMSG(2,"TRANS(SCOOpenClient)(%s)\n", port, 0,0 );
+
+#if !defined(SCORNODENAME)
+ PRMSG(1,"Protocol is not supported by a SCO connection\n", 0,0,0);
+ return -1;
+#else
+ (void) sprintf(server_path, SCORNODENAME, port);
+
+ if ((server = open(server_path, O_RDWR)) < 0) {
+ PRMSG(1,"TRANS(SCOOpenClient) failed to open %s\n", server_path, 0,0 );
+ return -1;
+ }
+
+ if ((fd = open(DEV_SPX, O_RDWR)) < 0) {
+ PRMSG(1,"TRANS(SCOOpenClient) failed to open %s\n", DEV_SPX, 0,0 );
+ close(server);
+ return -1;
+ }
+
+ (void) write(server, &server, 1);
+ ctlbuf.len = 0;
+ ctlbuf.maxlen = sizeof(long);
+ ctlbuf.buf = (caddr_t)&temp;
+ fl = 0;
+
+ savef = signal(SIGALRM, _dummy);
+ alarm_time = alarm(10);
+
+ ret = getmsg(server, &ctlbuf, 0, &fl);
+
+ (void) alarm(alarm_time);
+ (void) signal(SIGALRM, savef);
+
+ if (ret < 0) {
+ PRMSG(1,"TRANS(SCOOpenClient) error from getmsg\n", 0,0,0 );
+ close(fd);
+ close(server);
+ return -1;
+ }
+
+ /* The msg we got via getmsg is the result of an
+ * I_FDINSERT, so if we do a putmsg with whatever
+ * we recieved, we're doing another I_FDINSERT ...
+ */
+ (void) putmsg(fd, &ctlbuf, 0, 0);
+ (void) fcntl(fd,F_SETFL,fcntl(fd,F_GETFL,0)|O_NDELAY);
+
+ (void) close(server);
+
+ /*
+ * Everything looks good: fill in the XtransConnInfo structure.
+ */
+
+ if (TRANS(FillAddrInfo) (ciptr, server_path, server_path) == 0)
+ {
+ PRMSG(1,"TRANS(SCOOpenClient)() failed to fill addr info\n",
+ 0,0,0);
+ close(fd);
+ return -1;
+ }
+
+ return(fd);
+
+#endif /* !SCORNODENAME */
+}
+
+#endif /* TRANS_CLIENT */
+
+
+#ifdef TRANS_SERVER
+
+static int
+TRANS(SCOOpenServer)(ciptr, port)
+
+XtransConnInfo ciptr;
+char *port;
+
+{
+ char serverR_path[64];
+ char serverS_path[64];
+ int fdr = -1;
+ int fds = -1;
+
+ PRMSG(2,"TRANS(SCOOpenServer)(%s)\n", port, 0,0 );
+
+#if !defined(SCORNODENAME)
+ PRMSG(1,"Protocol is not supported by a SCO connection\n", 0,0,0);
+ return -1;
+#else
+ (void) sprintf(serverR_path, SCORNODENAME, port);
+ (void) sprintf(serverS_path, SCOSNODENAME, port);
+
+ unlink(serverR_path);
+ unlink(serverS_path);
+
+ if ((fds = open(DEV_SPX, O_RDWR)) < 0 ||
+ (fdr = open(DEV_SPX, O_RDWR)) < 0 ) {
+ PRMSG(2,"TRANS(SCOOpenServer) failed to open %s\n", DEV_SPX, 0,0 );
+ return -1;
+ }
+
+ if (connect_spipe(fds, fdr) != -1 &&
+ named_spipe(fds, serverS_path) != -1 &&
+ named_spipe(fdr, serverR_path) != -1) {
+ PRMSG(2,"TRANS(SCOOpenServer) connect pipes\n", 0,0,0 );
+ } else {
+ PRMSG(2,"TRANS(SCOOpenServer) failed to connect pipes\n", 0,0,0 );
+ close(fds);
+ close(fdr);
+ return -1;
+ }
+
+ /*
+ * Everything looks good: fill in the XtransConnInfo structure.
+ */
+
+ if (TRANS(FillAddrInfo) (ciptr, serverS_path, serverR_path) == 0)
+ {
+ PRMSG(1,"TRANS(SCOOpenServer)() failed to fill in addr info\n",
+ 0,0,0);
+ close(fds);
+ close(fdr);
+ return -1;
+ }
+
+ return(fds);
+
+#endif /* !SCORNODENAME */
+}
+
+static int
+TRANS(SCOAccept)(ciptr, newciptr, status)
+
+XtransConnInfo ciptr;
+XtransConnInfo newciptr;
+int *status;
+
+{
+ char c;
+ int fd;
+
+ PRMSG(2,"TRANS(SCOAccept)(%d)\n", ciptr->fd, 0,0 );
+
+ if (read(ciptr->fd, &c, 1) < 0) {
+ PRMSG(1,"TRANS(SCOAccept): can't read from client",0,0,0);
+ *status = TRANS_ACCEPT_MISC_ERROR;
+ return(-1);
+ }
+
+ if( (fd = open(DEV_SPX, O_RDWR)) < 0 ) {
+ PRMSG(1,"TRANS(SCOAccept)(): can't open \"%s\"",DEV_SPX, 0,0 );
+ *status = TRANS_ACCEPT_MISC_ERROR;
+ return(-1);
+ }
+
+ if (connect_spipe(ciptr->fd, fd) < 0) {
+ PRMSG(1,"TRANS(SCOAccept)(): can't connect pipes", 0,0,0 );
+ (void) close(fd);
+ *status = TRANS_ACCEPT_MISC_ERROR;
+ return(-1);
+ }
+
+ /*
+ * Everything looks good: fill in the XtransConnInfo structure.
+ */
+
+ newciptr->addrlen=ciptr->addrlen;
+ if( (newciptr->addr=(char *)malloc(newciptr->addrlen)) == NULL ) {
+ PRMSG(1,
+ "TRANS(SCOAccept)() failed to allocate memory for peer addr\n",
+ 0,0,0);
+ close(fd);
+ *status = TRANS_ACCEPT_BAD_MALLOC;
+ return -1;
+ }
+
+ memcpy(newciptr->addr,ciptr->addr,newciptr->addrlen);
+
+ newciptr->peeraddrlen=newciptr->addrlen;
+ if( (newciptr->peeraddr=(char *)malloc(newciptr->peeraddrlen)) == NULL ) {
+ PRMSG(1,
+ "TRANS(SCOAccept)() failed to allocate memory for peer addr\n",
+ 0,0,0);
+ free(newciptr->addr);
+ close(fd);
+ *status = TRANS_ACCEPT_BAD_MALLOC;
+ return -1;
+ }
+
+ memcpy(newciptr->peeraddr,newciptr->addr,newciptr->peeraddrlen);
+
+ *status = 0;
+
+ return(fd);
+}
+
+#endif /* TRANS_SERVER */
+#endif /* sun */
+
+
+
+#ifdef TRANS_REOPEN
+
+static int
+TRANS(PTSReopenServer)(ciptr, fd, port)
+
+XtransConnInfo ciptr;
+int fd;
+char *port;
+{
+ char server_path[64];
+
+ PRMSG(2,"TRANS(PTSReopenServer)(%d,%s)\n", fd, port, 0 );
+
+#if !defined(PTSNODENAME)
+ PRMSG(1,"Protocol is not supported by a pts connection\n", 0,0,0);
+ return 0;
+#else
+ if (port && *port ) {
+ if( *port == '/' ) { /* A full pathname */
+ (void) sprintf(server_path, "%s", port);
+ } else {
+ (void) sprintf(server_path, "%s%s", PTSNODENAME, port);
+ }
+ } else {
+ (void) sprintf(server_path, "%s%d", PTSNODENAME, getpid());
+ }
+
+ if (TRANS(FillAddrInfo) (ciptr, server_path, server_path) == 0)
+ {
+ PRMSG(1,"TRANS(PTSReopenServer)() failed to fill in addr info\n",
+ 0,0,0);
+ return 0;
+ }
+
+ return 1;
+
+#endif /* !PTSNODENAME */
+}
+
+
+static int
+TRANS(NAMEDReopenServer)(ciptr, fd, port)
+
+XtransConnInfo ciptr;
+int fd;
+char *port;
+
+{
+ char server_path[64];
+
+ PRMSG(2,"TRANS(NAMEDReopenServer)(%s)\n", port, 0,0 );
+
+#if !defined(NAMEDNODENAME)
+ PRMSG(1,"Protocol is not supported by a NAMED connection\n", 0,0,0);
+ return 0;
+#else
+ if ( port && *port ) {
+ if( *port == '/' ) { /* A full pathname */
+ (void) sprintf(server_path, "%s", port);
+ } else {
+ (void) sprintf(server_path, "%s%s", NAMEDNODENAME, port);
+ }
+ } else {
+ (void) sprintf(server_path, "%s%d", NAMEDNODENAME, getpid());
+ }
+
+ if (TRANS(FillAddrInfo) (ciptr, server_path, server_path) == 0)
+ {
+ PRMSG(1,"TRANS(NAMEDReopenServer)() failed to fill in addr info\n",
+ 0,0,0);
+ return 0;
+ }
+
+ return 1;
+
+#endif /* !NAMEDNODENAME */
+}
+
+
+static int
+TRANS(ISCReopenServer)(ciptr, fd, port)
+
+XtransConnInfo ciptr;
+int fd;
+char *port;
+
+{
+ char server_path[64],server_unix_path[64];
+
+ PRMSG(2,"TRANS(ISCReopenServer)(%s)\n", port, 0,0 );
+
+#if !defined(ISCDEVNODENAME)
+ PRMSG(1,"Protocol is not supported by a ISC connection\n", 0,0,0);
+ return 0;
+#else
+ (void) sprintf(server_path, ISCDEVNODENAME, port);
+ (void) sprintf(server_unix_path, ISCTMPNODENAME, port);
+
+ if (TRANS(FillAddrInfo) (ciptr, server_path, server_path) == 0)
+ {
+ PRMSG(1,"TRANS(ISCReopenServer)() failed to fill in addr info\n",
+ 0,0,0);
+ return 0;
+ }
+
+ return 1;
+
+#endif /* !ISCDEVNODENAME */
+}
+
+
+static int
+TRANS(SCOReopenServer)(ciptr, fd, port)
+
+XtransConnInfo ciptr;
+int fd;
+char *port;
+
+{
+ char serverR_path[64];
+ char serverS_path[64];
+
+ PRMSG(2,"TRANS(SCOReopenServer)(%s)\n", port, 0,0 );
+
+#if !defined(SCORNODENAME)
+ PRMSG(1,"Protocol is not supported by a SCO connection\n", 0,0,0);
+ return 0;
+#else
+ (void) sprintf(serverR_path, SCORNODENAME, port);
+ (void) sprintf(serverS_path, SCOSNODENAME, port);
+
+ if (TRANS(FillAddrInfo) (ciptr, serverS_path, serverR_path) == 0)
+ {
+ PRMSG(1,"TRANS(SCOReopenServer)() failed to fill in addr info\n",
+ 0,0,0);
+ return 0;
+ }
+
+ return 1;
+
+#endif /* SCORNODENAME */
+}
+
+#endif /* TRANS_REOPEN */
+
+
+
+/*
+ * This table contains all of the entry points for the different local
+ * connection mechanisms.
+ */
+
+typedef struct _LOCALtrans2dev {
+ char *transname;
+
+#ifdef TRANS_CLIENT
+
+ int (*devcotsopenclient)(
+#if NeedFunctionPrototypes
+ XtransConnInfo, char * /*port*/
+#endif
+);
+
+#endif /* TRANS_CLIENT */
+
+#ifdef TRANS_SERVER
+
+ int (*devcotsopenserver)(
+#if NeedFunctionPrototypes
+ XtransConnInfo, char * /*port*/
+#endif
+);
+
+#endif /* TRANS_SERVER */
+
+#ifdef TRANS_CLIENT
+
+ int (*devcltsopenclient)(
+#if NeedFunctionPrototypes
+ XtransConnInfo, char * /*port*/
+#endif
+);
+
+#endif /* TRANS_CLIENT */
+
+#ifdef TRANS_SERVER
+
+ int (*devcltsopenserver)(
+#if NeedFunctionPrototypes
+ XtransConnInfo, char * /*port*/
+#endif
+);
+
+#endif /* TRANS_SERVER */
+
+#ifdef TRANS_REOPEN
+
+ int (*devcotsreopenserver)(
+#if NeedFunctionPrototypes
+ XtransConnInfo,
+ int, /* fd */
+ char * /* port */
+#endif
+);
+
+ int (*devcltsreopenserver)(
+#if NeedFunctionPrototypes
+ XtransConnInfo,
+ int, /* fd */
+ char * /* port */
+#endif
+);
+
+#endif /* TRANS_REOPEN */
+
+#ifdef TRANS_SERVER
+
+ int (*devaccept)(
+#if NeedFunctionPrototypes
+ XtransConnInfo, XtransConnInfo, int *
+#endif
+
+);
+
+#endif /* TRANS_SERVER */
+
+} LOCALtrans2dev;
+
+static LOCALtrans2dev LOCALtrans2devtab[] = {
+#ifndef sun
+{"",
+#ifdef TRANS_CLIENT
+ TRANS(PTSOpenClient),
+#endif /* TRANS_CLIENT */
+#ifdef TRANS_SERVER
+ TRANS(PTSOpenServer),
+#endif /* TRANS_SERVER */
+#ifdef TRANS_CLIENT
+ TRANS(OpenFail),
+#endif /* TRANS_CLIENT */
+#ifdef TRANS_SERVER
+ TRANS(OpenFail),
+#endif /* TRANS_SERVER */
+#ifdef TRANS_REOPEN
+ TRANS(PTSReopenServer),
+ TRANS(ReopenFail),
+#endif
+#ifdef TRANS_SERVER
+ TRANS(PTSAccept)
+#endif /* TRANS_SERVER */
+},
+
+{"local",
+#ifdef TRANS_CLIENT
+ TRANS(PTSOpenClient),
+#endif /* TRANS_CLIENT */
+#ifdef TRANS_SERVER
+ TRANS(PTSOpenServer),
+#endif /* TRANS_SERVER */
+#ifdef TRANS_CLIENT
+ TRANS(OpenFail),
+#endif /* TRANS_CLIENT */
+#ifdef TRANS_SERVER
+ TRANS(OpenFail),
+#endif /* TRANS_SERVER */
+#ifdef TRANS_REOPEN
+ TRANS(PTSReopenServer),
+ TRANS(ReopenFail),
+#endif
+#ifdef TRANS_SERVER
+ TRANS(PTSAccept)
+#endif /* TRANS_SERVER */
+},
+
+{"pts",
+#ifdef TRANS_CLIENT
+ TRANS(PTSOpenClient),
+#endif /* TRANS_CLIENT */
+#ifdef TRANS_SERVER
+ TRANS(PTSOpenServer),
+#endif /* TRANS_SERVER */
+#ifdef TRANS_CLIENT
+ TRANS(OpenFail),
+#endif /* TRANS_CLIENT */
+#ifdef TRANS_SERVER
+ TRANS(OpenFail),
+#endif /* TRANS_SERVER */
+#ifdef TRANS_REOPEN
+ TRANS(PTSReopenServer),
+ TRANS(ReopenFail),
+#endif
+#ifdef TRANS_SERVER
+ TRANS(PTSAccept)
+#endif /* TRANS_SERVER */
+},
+#else /* sun */
+{"",
+#ifdef TRANS_CLIENT
+ TRANS(NAMEDOpenClient),
+#endif /* TRANS_CLIENT */
+#ifdef TRANS_SERVER
+ TRANS(NAMEDOpenServer),
+#endif /* TRANS_SERVER */
+#ifdef TRANS_CLIENT
+ TRANS(OpenFail),
+#endif /* TRANS_CLIENT */
+#ifdef TRANS_SERVER
+ TRANS(OpenFail),
+#endif /* TRANS_SERVER */
+#ifdef TRANS_REOPEN
+ TRANS(NAMEDReopenServer),
+ TRANS(ReopenFail),
+#endif
+#ifdef TRANS_SERVER
+ TRANS(NAMEDAccept)
+#endif /* TRANS_SERVER */
+},
+
+{"local",
+#ifdef TRANS_CLIENT
+ TRANS(NAMEDOpenClient),
+#endif /* TRANS_CLIENT */
+#ifdef TRANS_SERVER
+ TRANS(NAMEDOpenServer),
+#endif /* TRANS_SERVER */
+#ifdef TRANS_CLIENT
+ TRANS(OpenFail),
+#endif /* TRANS_CLIENT */
+#ifdef TRANS_SERVER
+ TRANS(OpenFail),
+#endif /* TRANS_SERVER */
+#ifdef TRANS_REOPEN
+ TRANS(NAMEDReopenServer),
+ TRANS(ReopenFail),
+#endif
+#ifdef TRANS_SERVER
+ TRANS(NAMEDAccept)
+#endif /* TRANS_SERVER */
+},
+#endif /* sun */
+
+#ifdef SVR4
+{"named",
+#ifdef TRANS_CLIENT
+ TRANS(NAMEDOpenClient),
+#endif /* TRANS_CLIENT */
+#ifdef TRANS_SERVER
+ TRANS(NAMEDOpenServer),
+#endif /* TRANS_SERVER */
+#ifdef TRANS_CLIENT
+ TRANS(OpenFail),
+#endif /* TRANS_CLIENT */
+#ifdef TRANS_SERVER
+ TRANS(OpenFail),
+#endif /* TRANS_SERVER */
+#ifdef TRANS_REOPEN
+ TRANS(NAMEDReopenServer),
+ TRANS(ReopenFail),
+#endif
+#ifdef TRANS_SERVER
+ TRANS(NAMEDAccept)
+#endif /* TRANS_SERVER */
+},
+#endif /* SVR4 */
+
+#ifndef sun
+{"isc",
+#ifdef TRANS_CLIENT
+ TRANS(ISCOpenClient),
+#endif /* TRANS_CLIENT */
+#ifdef TRANS_SERVER
+ TRANS(ISCOpenServer),
+#endif /* TRANS_SERVER */
+#ifdef TRANS_CLIENT
+ TRANS(OpenFail),
+#endif /* TRANS_CLIENT */
+#ifdef TRANS_SERVER
+ TRANS(OpenFail),
+#endif /* TRANS_SERVER */
+#ifdef TRANS_REOPEN
+ TRANS(ISCReopenServer),
+ TRANS(ReopenFail),
+#endif
+#ifdef TRANS_SERVER
+ TRANS(ISCAccept)
+#endif /* TRANS_SERVER */
+},
+
+{"sco",
+#ifdef TRANS_CLIENT
+ TRANS(SCOOpenClient),
+#endif /* TRANS_CLIENT */
+#ifdef TRANS_SERVER
+ TRANS(SCOOpenServer),
+#endif /* TRANS_SERVER */
+#ifdef TRANS_CLIENT
+ TRANS(OpenFail),
+#endif /* TRANS_CLIENT */
+#ifdef TRANS_SERVER
+ TRANS(OpenFail),
+#endif /* TRANS_SERVER */
+#ifdef TRANS_REOPEN
+ TRANS(SCOReopenServer),
+ TRANS(ReopenFail),
+#endif
+#ifdef TRANS_SERVER
+ TRANS(SCOAccept)
+#endif /* TRANS_SERVER */
+},
+#endif /* sun */
+};
+
+#define NUMTRANSPORTS (sizeof(LOCALtrans2devtab)/sizeof(LOCALtrans2dev))
+
+static char *XLOCAL=NULL;
+static char *workingXLOCAL=NULL;
+static char *freeXLOCAL=NULL;
+
+#ifdef sco
+#define DEF_XLOCAL "UNIX:SCO:PTS:NAMED:ISC"
+#else
+#define DEF_XLOCAL "UNIX:PTS:NAMED:ISC:SCO"
+#endif
+
+static void
+TRANS(LocalInitTransports)(protocol)
+
+char *protocol;
+
+{
+ PRMSG(3,"TRANS(LocalInitTransports)(%s)\n", protocol, 0,0 );
+
+ if( strcmp(protocol,"local") && strcmp(protocol,"LOCAL") )
+ {
+ workingXLOCAL=freeXLOCAL=(char *)malloc (strlen (protocol) + 1);
+ if (workingXLOCAL)
+ strcpy (workingXLOCAL, protocol);
+ }
+ else {
+ XLOCAL=(char *)getenv("XLOCAL");
+ if(XLOCAL==NULL)
+ XLOCAL=DEF_XLOCAL;
+ workingXLOCAL=freeXLOCAL=(char *)malloc (strlen (XLOCAL) + 1);
+ if (workingXLOCAL)
+ strcpy (workingXLOCAL, XLOCAL);
+ }
+}
+
+static void
+TRANS(LocalEndTransports)()
+
+{
+ PRMSG(3,"TRANS(LocalEndTransports)()\n", 0,0,0 );
+ free(freeXLOCAL);
+}
+
+static LOCALtrans2dev *
+TRANS(LocalGetNextTransport)()
+
+{
+ int i,j;
+ char *typetocheck;
+#define TYPEBUFSIZE 32
+ char typebuf[TYPEBUFSIZE];
+ PRMSG(3,"TRANS(LocalGetNextTransport)()\n", 0,0,0 );
+
+ while(1)
+ {
+ if( workingXLOCAL == NULL || *workingXLOCAL == '\0' )
+ return NULL;
+
+ typetocheck=workingXLOCAL;
+ workingXLOCAL=strchr(workingXLOCAL,':');
+ if(workingXLOCAL && *workingXLOCAL)
+ *workingXLOCAL++='\0';
+
+ for(i=0;i<NUMTRANSPORTS;i++)
+ {
+ /*
+ * This is equivilent to a case insensitive strcmp(),
+ * but should be more portable.
+ */
+ strncpy(typebuf,typetocheck,TYPEBUFSIZE);
+ for(j=0;j<TYPEBUFSIZE;j++)
+ if (isupper(typebuf[j]))
+ typebuf[j]=tolower(typebuf[j]);
+
+ /* Now, see if they match */
+ if(!strcmp(LOCALtrans2devtab[i].transname,typebuf))
+ return &LOCALtrans2devtab[i];
+ }
+ }
+ /*NOTREACHED*/
+ return NULL;
+}
+
+#ifdef TRANS_CLIENT
+
+#ifdef NEED_UTSNAME
+#include <sys/utsname.h>
+#endif
+
+/*
+ * Make sure 'host' is really local.
+ */
+
+static int
+HostReallyLocal (host)
+
+char *host;
+
+{
+ /*
+ * The 'host' passed to this function may have been generated
+ * by either uname() or gethostname(). We try both if possible.
+ */
+
+#ifdef NEED_UTSNAME
+ struct utsname name;
+#endif
+ char buf[256];
+
+#ifdef NEED_UTSNAME
+ if (uname (&name) >= 0 && strcmp (host, name.nodename) == 0)
+ return (1);
+#endif
+
+ buf[0] = '\0';
+ (void) gethostname (buf, 256);
+ buf[255] = '\0';
+
+ if (strcmp (host, buf) == 0)
+ return (1);
+
+ return (0);
+}
+
+
+static XtransConnInfo
+TRANS(LocalOpenClient)(type, protocol, host, port)
+
+int type;
+char *protocol;
+char *host;
+char *port;
+
+{
+ int fd = -1;
+ LOCALtrans2dev *transptr;
+ XtransConnInfo ciptr;
+ int index;
+
+ PRMSG(3,"TRANS(LocalOpenClient)()\n", 0,0,0 );
+
+ /*
+ * Make sure 'host' is really local. If not, we return failure.
+ * The reason we make this check is because a process may advertise
+ * a "local" address for which it can accept connections, but if a
+ * process on a remote machine tries to connect to this address,
+ * we know for sure it will fail.
+ */
+
+ if (strcmp (host, "unix") != 0 && !HostReallyLocal (host))
+ {
+ PRMSG (1,
+ "TRANS(LocalOpenClient): Cannot connect to non-local host %s\n",
+ host, 0, 0);
+ return NULL;
+ }
+
+
+#if defined(X11_t)
+ /*
+ * X has a well known port, that is transport dependant. 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(). Since that is what we want for the local transports,
+ * we don't have to do anything special.
+ */
+#endif /* X11_t */
+
+ if( (ciptr=(XtransConnInfo)calloc(1,sizeof(struct _XtransConnInfo))) == NULL )
+ {
+ PRMSG(1,"TRANS(LocalOpenClient)() calloc(1,%d) failed\n",
+ sizeof(struct _XtransConnInfo),0,0 );
+ return NULL;
+ }
+
+ ciptr->fd = -1;
+
+ TRANS(LocalInitTransports)(protocol);
+
+ index = 0;
+ for(transptr=TRANS(LocalGetNextTransport)();
+ transptr!=NULL;transptr=TRANS(LocalGetNextTransport)(), index++)
+ {
+ switch( type )
+ {
+ case XTRANS_OPEN_COTS_CLIENT:
+ ciptr->fd=transptr->devcotsopenclient(ciptr,port);
+ break;
+ case XTRANS_OPEN_CLTS_CLIENT:
+ ciptr->fd=transptr->devcltsopenclient(ciptr,port);
+ break;
+ case XTRANS_OPEN_COTS_SERVER:
+ case XTRANS_OPEN_CLTS_SERVER:
+ PRMSG(1,
+ "TRANS(LocalOpenClient): Should not be opening a server with this function\n",
+ 0,0,0);
+ break;
+ default:
+ PRMSG(1,
+ "TRANS(LocalOpenClient): Unknown Open type %d\n",
+ type, 0,0 );
+ }
+ if( ciptr->fd >= 0 )
+ break;
+ }
+
+ TRANS(LocalEndTransports)();
+
+ if( ciptr->fd < 0 )
+ {
+ free(ciptr);
+ return NULL;
+ }
+
+ ciptr->priv=(char *)transptr;
+ ciptr->index = index;
+
+ return ciptr;
+}
+
+#endif /* TRANS_CLIENT */
+
+
+#ifdef TRANS_SERVER
+
+static XtransConnInfo
+TRANS(LocalOpenServer)(type, protocol, host, port)
+
+int type;
+char *protocol;
+char *host;
+char *port;
+
+{
+ int i,fd = -1;
+ XtransConnInfo ciptr;
+
+ PRMSG(2,"TRANS(LocalOpenServer)(%d,%s,%s)\n", type, protocol, port);
+
+#if defined(X11_t)
+ /*
+ * For X11, the port will be in the format xserverN where N is the
+ * display number. All of the local connections just need to know
+ * the display number because they don't do any name resolution on
+ * the port. This just truncates port to the display portion.
+ */
+#endif /* X11_t */
+
+ if( (ciptr=(XtransConnInfo)calloc(1,sizeof(struct _XtransConnInfo))) == NULL )
+ {
+ PRMSG(1,"TRANS(LocalOpenServer)() calloc(1,%d) failed\n",
+ sizeof(struct _XtransConnInfo),0,0 );
+ return NULL;
+ }
+
+ for(i=1;i<NUMTRANSPORTS;i++)
+ {
+ if( strcmp(protocol,LOCALtrans2devtab[i].transname) != 0 )
+ continue;
+ switch( type )
+ {
+ case XTRANS_OPEN_COTS_CLIENT:
+ case XTRANS_OPEN_CLTS_CLIENT:
+ PRMSG(1,
+ "TRANS(LocalOpenServer): Should not be opening a client with this function\n",
+ 0,0,0);
+ break;
+ case XTRANS_OPEN_COTS_SERVER:
+ ciptr->fd=LOCALtrans2devtab[i].devcotsopenserver(ciptr,port);
+ break;
+ case XTRANS_OPEN_CLTS_SERVER:
+ ciptr->fd=LOCALtrans2devtab[i].devcltsopenserver(ciptr,port);
+ break;
+ default:
+ PRMSG(1,"TRANS(LocalOpenServer): Unknown Open type %d\n",
+ type ,0,0);
+ }
+ if( ciptr->fd >= 0 ) {
+ ciptr->priv=(char *)&LOCALtrans2devtab[i];
+ ciptr->index=i;
+ ciptr->flags=1;
+ return ciptr;
+ }
+ }
+
+ free(ciptr);
+ return NULL;
+}
+
+#endif /* TRANS_SERVER */
+
+
+#ifdef TRANS_REOPEN
+
+static XtransConnInfo
+TRANS(LocalReopenServer)(type, index, fd, port)
+
+int type;
+int index;
+int fd;
+char *port;
+
+{
+ XtransConnInfo ciptr;
+ int stat;
+
+ PRMSG(2,"TRANS(LocalReopenServer)(%d,%d,%d)\n", type, index, fd);
+
+ if( (ciptr=(XtransConnInfo)calloc(1,sizeof(struct _XtransConnInfo))) == NULL )
+ {
+ PRMSG(1,"TRANS(LocalReopenServer)() calloc(1,%d) failed\n",
+ sizeof(struct _XtransConnInfo),0,0 );
+ return NULL;
+ }
+
+ ciptr->fd = fd;
+
+ switch( type )
+ {
+ case XTRANS_OPEN_COTS_SERVER:
+ stat = LOCALtrans2devtab[index].devcotsreopenserver(ciptr,fd,port);
+ break;
+ case XTRANS_OPEN_CLTS_SERVER:
+ stat = LOCALtrans2devtab[index].devcltsreopenserver(ciptr,fd,port);
+ break;
+ default:
+ PRMSG(1,"TRANS(LocalReopenServer): Unknown Open type %d\n",
+ type ,0,0);
+ }
+
+ if( stat > 0 ) {
+ ciptr->priv=(char *)&LOCALtrans2devtab[index];
+ ciptr->index=index;
+ ciptr->flags=1;
+ return ciptr;
+ }
+
+ free(ciptr);
+ return NULL;
+}
+
+#endif /* TRANS_REOPEN */
+
+
+
+/*
+ * This is the Local implementation of the X Transport service layer
+ */
+
+#ifdef TRANS_CLIENT
+
+static XtransConnInfo
+TRANS(LocalOpenCOTSClient)(thistrans, protocol, host, port)
+
+Xtransport *thistrans;
+char *protocol;
+char *host;
+char *port;
+
+{
+ PRMSG(2,"TRANS(LocalOpenCOTSClient)(%s,%s,%s)\n",protocol,host,port);
+
+ return TRANS(LocalOpenClient)(XTRANS_OPEN_COTS_CLIENT, protocol, host, port);
+}
+
+#endif /* TRANS_CLIENT */
+
+
+#ifdef TRANS_SERVER
+
+static XtransConnInfo
+TRANS(LocalOpenCOTSServer)(thistrans, protocol, host, port)
+
+Xtransport *thistrans;
+char *protocol;
+char *host;
+char *port;
+
+{
+ PRMSG(2,"TRANS(LocalOpenCOTSServer)(%s,%s,%s)\n",protocol,host,port);
+
+ return TRANS(LocalOpenServer)(XTRANS_OPEN_COTS_SERVER, protocol, host, port);
+}
+
+#endif /* TRANS_SERVER */
+
+
+#ifdef TRANS_CLIENT
+
+static XtransConnInfo
+TRANS(LocalOpenCLTSClient)(thistrans, protocol, host, port)
+
+Xtransport *thistrans;
+char *protocol;
+char *host;
+char *port;
+
+{
+ PRMSG(2,"TRANS(LocalOpenCLTSClient)(%s,%s,%s)\n",protocol,host,port);
+
+ return TRANS(LocalOpenClient)(XTRANS_OPEN_CLTS_CLIENT, protocol, host, port);
+}
+
+#endif /* TRANS_CLIENT */
+
+
+#ifdef TRANS_SERVER
+
+static XtransConnInfo
+TRANS(LocalOpenCLTSServer)(thistrans, protocol, host, port)
+
+Xtransport *thistrans;
+char *protocol;
+char *host;
+char *port;
+
+{
+ PRMSG(2,"TRANS(LocalOpenCLTSServer)(%s,%s,%s)\n",protocol,host,port);
+
+ return TRANS(LocalOpenServer)(XTRANS_OPEN_CLTS_SERVER, protocol, host, port);
+}
+
+#endif /* TRANS_SERVER */
+
+
+#ifdef TRANS_REOPEN
+
+static XtransConnInfo
+TRANS(LocalReopenCOTSServer)(thistrans, fd, port)
+
+Xtransport *thistrans;
+int fd;
+char *port;
+
+{
+ int index;
+
+ PRMSG(2,"TRANS(LocalReopenCOTSServer)(%d,%s)\n", fd, port, 0);
+
+ for(index=1;index<NUMTRANSPORTS;index++)
+ {
+ if( strcmp(thistrans->TransName,
+ LOCALtrans2devtab[index].transname) == 0 )
+ break;
+ }
+
+ if (index >= NUMTRANSPORTS)
+ {
+ return (NULL);
+ }
+
+ return TRANS(LocalReopenServer)(XTRANS_OPEN_COTS_SERVER,
+ index, fd, port);
+}
+
+static XtransConnInfo
+TRANS(LocalReopenCLTSServer)(thistrans, fd, port)
+
+Xtransport *thistrans;
+int fd;
+char *port;
+
+{
+ int index;
+
+ PRMSG(2,"TRANS(LocalReopenCLTSServer)(%d,%s)\n", fd, port, 0);
+
+ for(index=1;index<NUMTRANSPORTS;index++)
+ {
+ if( strcmp(thistrans->TransName,
+ LOCALtrans2devtab[index].transname) == 0 )
+ break;
+ }
+
+ if (index >= NUMTRANSPORTS)
+ {
+ return (NULL);
+ }
+
+ return TRANS(LocalReopenServer)(XTRANS_OPEN_CLTS_SERVER,
+ index, fd, port);
+}
+
+#endif /* TRANS_REOPEN */
+
+
+
+static
+TRANS(LocalSetOption)(ciptr, option, arg)
+
+XtransConnInfo ciptr;
+int option;
+int arg;
+
+{
+ PRMSG(2,"TRANS(LocalSetOption)(%d,%d,%d)\n",ciptr->fd,option,arg);
+
+ return -1;
+}
+
+
+#ifdef TRANS_SERVER
+
+static
+TRANS(LocalCreateListener)(ciptr, port)
+
+XtransConnInfo ciptr;
+char *port;
+
+{
+ PRMSG(2,"TRANS(LocalCreateListener)(%x->%d,%s)\n",ciptr,ciptr->fd,port);
+
+ return 0;
+}
+
+static XtransConnInfo
+TRANS(LocalAccept)(ciptr, status)
+
+XtransConnInfo ciptr;
+int *status;
+
+{
+ XtransConnInfo newciptr;
+ LOCALtrans2dev *transptr;
+
+ PRMSG(2,"TRANS(LocalAccept)(%x->%d)\n", ciptr, ciptr->fd,0);
+
+ transptr=(LOCALtrans2dev *)ciptr->priv;
+
+ if( (newciptr=(XtransConnInfo)calloc(1,sizeof(struct _XtransConnInfo)))==NULL )
+ {
+ PRMSG(1,"TRANS(LocalAccept)() calloc(1,%d) failed\n",
+ sizeof(struct _XtransConnInfo),0,0 );
+ *status = TRANS_ACCEPT_BAD_MALLOC;
+ return NULL;
+ }
+
+ newciptr->fd=transptr->devaccept(ciptr,newciptr,status);
+
+ if( newciptr->fd < 0 )
+ {
+ free(newciptr);
+ return NULL;
+ }
+
+ newciptr->priv=(char *)transptr;
+ newciptr->index = ciptr->index;
+
+ *status = 0;
+
+ return newciptr;
+}
+
+#endif /* TRANS_SERVER */
+
+
+#ifdef TRANS_CLIENT
+
+static
+TRANS(LocalConnect)(ciptr, host, port)
+
+XtransConnInfo ciptr;
+char *host;
+char *port;
+
+{
+ PRMSG(2,"TRANS(LocalConnect)(%x->%d,%s)\n", ciptr, ciptr->fd, port);
+
+ return 0;
+}
+
+#endif /* TRANS_CLIENT */
+
+
+static int
+TRANS(LocalBytesReadable)(ciptr, pend )
+
+XtransConnInfo ciptr;
+BytesReadable_t *pend;
+
+{
+ PRMSG(2,"TRANS(LocalBytesReadable)(%x->%d,%x)\n", ciptr, ciptr->fd, pend);
+
+#ifdef sco
+ return ioctl(ciptr->fd, I_NREAD, (char *)pend);
+#else
+ return ioctl(ciptr->fd, FIONREAD, (char *)pend);
+#endif
+}
+
+static int
+TRANS(LocalRead)(ciptr, buf, size)
+
+XtransConnInfo ciptr;
+char *buf;
+int size;
+
+{
+ PRMSG(2,"TRANS(LocalRead)(%d,%x,%d)\n", ciptr->fd, buf, size );
+
+ return read(ciptr->fd,buf,size);
+}
+
+static int
+TRANS(LocalWrite)(ciptr, buf, size)
+
+XtransConnInfo ciptr;
+char *buf;
+int size;
+
+{
+ PRMSG(2,"TRANS(LocalWrite)(%d,%x,%d)\n", ciptr->fd, buf, size );
+
+ return write(ciptr->fd,buf,size);
+}
+
+static int
+TRANS(LocalReadv)(ciptr, buf, size)
+
+XtransConnInfo ciptr;
+struct iovec *buf;
+int size;
+
+{
+ PRMSG(2,"TRANS(LocalReadv)(%d,%x,%d)\n", ciptr->fd, buf, size );
+
+ return READV(ciptr,buf,size);
+}
+
+static int
+TRANS(LocalWritev)(ciptr, buf, size)
+
+XtransConnInfo ciptr;
+struct iovec *buf;
+int size;
+
+{
+ PRMSG(2,"TRANS(LocalWritev)(%d,%x,%d)\n", ciptr->fd, buf, size );
+
+ return WRITEV(ciptr,buf,size);
+}
+
+static int
+TRANS(LocalDisconnect)(ciptr)
+
+XtransConnInfo ciptr;
+
+{
+ PRMSG(2,"TRANS(LocalDisconnect)(%x->%d)\n", ciptr, ciptr->fd, 0);
+
+ return 0;
+}
+
+static int
+TRANS(LocalClose)(ciptr)
+
+XtransConnInfo ciptr;
+
+{
+ struct sockaddr_un *sockname=(struct sockaddr_un *) ciptr->addr;
+ char path[200]; /* > sizeof sun_path +1 */
+ int ret;
+
+ PRMSG(2,"TRANS(LocalClose)(%x->%d)\n", ciptr, ciptr->fd ,0);
+
+ ret=close(ciptr->fd);
+
+ if(ciptr->flags
+ && sockname
+ && sockname->sun_family == AF_UNIX
+ && sockname->sun_path[0] )
+ {
+ strncpy(path,sockname->sun_path,
+ ciptr->addrlen-sizeof(sockname->sun_family));
+ unlink(path);
+ }
+
+ return ret;
+}
+
+static int
+TRANS(LocalCloseForCloning)(ciptr)
+
+XtransConnInfo ciptr;
+
+{
+ int ret;
+
+ PRMSG(2,"TRANS(LocalCloseForCloning)(%x->%d)\n", ciptr, ciptr->fd ,0);
+
+ /* Don't unlink path */
+
+ ret=close(ciptr->fd);
+
+ return ret;
+}
+
+
+/*
+ * MakeAllCOTSServerListeners() will go through the entire Xtransports[]
+ * array defined in Xtrans.c and try to OpenCOTSServer() for each entry.
+ * We will add duplicate entries to that table so that the OpenCOTSServer()
+ * function will get called once for each type of local transport.
+ *
+ * The TransName is in lowercase, so it will never match during a normal
+ * call to SelectTransport() in Xtrans.c.
+ */
+
+Xtransport TRANS(LocalFuncs) = {
+ /* Local Interface */
+ "local",
+ TRANS_ALIAS | TRANS_LOCAL,
+#ifdef TRANS_CLIENT
+ TRANS(LocalOpenCOTSClient),
+#endif /* TRANS_CLIENT */
+#ifdef TRANS_SERVER
+ TRANS(LocalOpenCOTSServer),
+#endif /* TRANS_SERVER */
+#ifdef TRANS_CLIENT
+ TRANS(LocalOpenCLTSClient),
+#endif /* TRANS_CLIENT */
+#ifdef TRANS_SERVER
+ TRANS(LocalOpenCLTSServer),
+#endif /* TRANS_SERVER */
+#ifdef TRANS_REOPEN
+ TRANS(LocalReopenCOTSServer),
+ TRANS(LocalReopenCLTSServer),
+#endif
+ TRANS(LocalSetOption),
+#ifdef TRANS_SERVER
+ TRANS(LocalCreateListener),
+ NULL, /* ResetListener */
+ TRANS(LocalAccept),
+#endif /* TRANS_SERVER */
+#ifdef TRANS_CLIENT
+ TRANS(LocalConnect),
+#endif /* TRANS_CLIENT */
+ TRANS(LocalBytesReadable),
+ TRANS(LocalRead),
+ TRANS(LocalWrite),
+ TRANS(LocalReadv),
+ TRANS(LocalWritev),
+ TRANS(LocalDisconnect),
+ TRANS(LocalClose),
+ TRANS(LocalCloseForCloning),
+};
+
+#ifndef sun
+
+Xtransport TRANS(PTSFuncs) = {
+ /* Local Interface */
+ "pts",
+ TRANS_LOCAL,
+#ifdef TRANS_CLIENT
+ TRANS(LocalOpenCOTSClient),
+#endif /* TRANS_CLIENT */
+#ifdef TRANS_SERVER
+ TRANS(LocalOpenCOTSServer),
+#endif /* TRANS_SERVER */
+#ifdef TRANS_CLIENT
+ TRANS(LocalOpenCLTSClient),
+#endif /* TRANS_CLIENT */
+#ifdef TRANS_SERVER
+ TRANS(LocalOpenCLTSServer),
+#endif /* TRANS_SERVER */
+#ifdef TRANS_REOPEN
+ TRANS(LocalReopenCOTSServer),
+ TRANS(LocalReopenCLTSServer),
+#endif
+ TRANS(LocalSetOption),
+#ifdef TRANS_SERVER
+ TRANS(LocalCreateListener),
+ NULL, /* ResetListener */
+ TRANS(LocalAccept),
+#endif /* TRANS_SERVER */
+#ifdef TRANS_CLIENT
+ TRANS(LocalConnect),
+#endif /* TRANS_CLIENT */
+ TRANS(LocalBytesReadable),
+ TRANS(LocalRead),
+ TRANS(LocalWrite),
+ TRANS(LocalReadv),
+ TRANS(LocalWritev),
+ TRANS(LocalDisconnect),
+ TRANS(LocalClose),
+ TRANS(LocalCloseForCloning),
+};
+
+#endif /* sun */
+
+Xtransport TRANS(NAMEDFuncs) = {
+ /* Local Interface */
+ "named",
+ TRANS_LOCAL,
+#ifdef TRANS_CLIENT
+ TRANS(LocalOpenCOTSClient),
+#endif /* TRANS_CLIENT */
+#ifdef TRANS_SERVER
+ TRANS(LocalOpenCOTSServer),
+#endif /* TRANS_SERVER */
+#ifdef TRANS_CLIENT
+ TRANS(LocalOpenCLTSClient),
+#endif /* TRANS_CLIENT */
+#ifdef TRANS_SERVER
+ TRANS(LocalOpenCLTSServer),
+#endif /* TRANS_SERVER */
+#ifdef TRANS_REOPEN
+ TRANS(LocalReopenCOTSServer),
+ TRANS(LocalReopenCLTSServer),
+#endif
+ TRANS(LocalSetOption),
+#ifdef TRANS_SERVER
+ TRANS(LocalCreateListener),
+ NULL, /* ResetListener */
+ TRANS(LocalAccept),
+#endif /* TRANS_SERVER */
+#ifdef TRANS_CLIENT
+ TRANS(LocalConnect),
+#endif /* TRANS_CLIENT */
+ TRANS(LocalBytesReadable),
+ TRANS(LocalRead),
+ TRANS(LocalWrite),
+ TRANS(LocalReadv),
+ TRANS(LocalWritev),
+ TRANS(LocalDisconnect),
+ TRANS(LocalClose),
+ TRANS(LocalCloseForCloning),
+};
+
+#ifndef sun
+
+Xtransport TRANS(ISCFuncs) = {
+ /* Local Interface */
+ "isc",
+ TRANS_LOCAL,
+#ifdef TRANS_CLIENT
+ TRANS(LocalOpenCOTSClient),
+#endif /* TRANS_CLIENT */
+#ifdef TRANS_SERVER
+ TRANS(LocalOpenCOTSServer),
+#endif /* TRANS_SERVER */
+#ifdef TRANS_CLIENT
+ TRANS(LocalOpenCLTSClient),
+#endif /* TRANS_CLIENT */
+#ifdef TRANS_SERVER
+ TRANS(LocalOpenCLTSServer),
+#endif /* TRANS_SERVER */
+#ifdef TRANS_REOPEN
+ TRANS(LocalReopenCOTSServer),
+ TRANS(LocalReopenCLTSServer),
+#endif
+ TRANS(LocalSetOption),
+#ifdef TRANS_SERVER
+ TRANS(LocalCreateListener),
+ NULL, /* ResetListener */
+ TRANS(LocalAccept),
+#endif /* TRANS_SERVER */
+#ifdef TRANS_CLIENT
+ TRANS(LocalConnect),
+#endif /* TRANS_CLIENT */
+ TRANS(LocalBytesReadable),
+ TRANS(LocalRead),
+ TRANS(LocalWrite),
+ TRANS(LocalReadv),
+ TRANS(LocalWritev),
+ TRANS(LocalDisconnect),
+ TRANS(LocalClose),
+ TRANS(LocalCloseForCloning),
+};
+Xtransport TRANS(SCOFuncs) = {
+ /* Local Interface */
+ "sco",
+ TRANS_LOCAL,
+#ifdef TRANS_CLIENT
+ TRANS(LocalOpenCOTSClient),
+#endif /* TRANS_CLIENT */
+#ifdef TRANS_SERVER
+ TRANS(LocalOpenCOTSServer),
+#endif /* TRANS_SERVER */
+#ifdef TRANS_CLIENT
+ TRANS(LocalOpenCLTSClient),
+#endif /* TRANS_CLIENT */
+#ifdef TRANS_SERVER
+ TRANS(LocalOpenCLTSServer),
+#endif /* TRANS_SERVER */
+#ifdef TRANS_REOPEN
+ TRANS(LocalReopenCOTSServer),
+ TRANS(LocalReopenCLTSServer),
+#endif
+ TRANS(LocalSetOption),
+#ifdef TRANS_SERVER
+ TRANS(LocalCreateListener),
+ NULL, /* ResetListener */
+ TRANS(LocalAccept),
+#endif /* TRANS_SERVER */
+#ifdef TRANS_CLIENT
+ TRANS(LocalConnect),
+#endif /* TRANS_CLIENT */
+ TRANS(LocalBytesReadable),
+ TRANS(LocalRead),
+ TRANS(LocalWrite),
+ TRANS(LocalReadv),
+ TRANS(LocalWritev),
+ TRANS(LocalDisconnect),
+ TRANS(LocalClose),
+ TRANS(LocalCloseForCloning),
+};
+#endif /* sun */
diff --git a/Xtranssock.c b/Xtranssock.c
new file mode 100644
index 0000000..62033c9
--- /dev/null
+++ b/Xtranssock.c
@@ -0,0 +1,1993 @@
+/* $Xorg: Xtranssock.c,v 1.11 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.
+
+*/
+
+/* 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 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.
+ */
+
+#include <ctype.h>
+#ifdef XTHREADS
+#include <X11/Xthreads.h>
+#endif
+
+#ifndef WIN32
+
+#if defined(TCPCONN) || defined(UNIXCONN)
+#include <netinet/in.h>
+#else
+#ifdef ESIX
+#include <lan/in.h>
+#endif
+#endif
+
+#if defined(TCPCONN) || defined(UNIXCONN)
+#define X_INCLUDE_NETDB_H
+#define XOS_USE_NO_LOCKING
+#include <X11/Xos_r.h>
+#endif
+
+#ifdef UNIXCONN
+#include <sys/un.h>
+#include <sys/stat.h>
+#endif
+
+#if defined(hpux) || defined(__EMX__) || (defined(MOTOROLA) && defined(SYSV))
+#define NO_TCP_H
+#endif
+
+#ifndef NO_TCP_H
+#ifdef __osf__
+#include <sys/param.h>
+#endif /* osf */
+#if defined(__NetBSD__) || defined(__FreeBSD__)
+#include <machine/endian.h>
+#endif /* __NetBSD__ || __FreeBSD__ */
+#include <netinet/tcp.h>
+#endif /* !NO_TCP_H */
+
+#include <sys/ioctl.h>
+
+#if defined (SVR4) && !defined(SCO325) && !defined(_SEQUENT_)
+#include <sys/filio.h>
+#endif
+
+#if (defined(i386) && defined(SYSV)) && !defined(ESIX) && !defined(sco)
+#include <net/errno.h>
+#endif
+
+#if (defined(i386) && defined(SYSV)) && (!defined(ISC) || !defined(I_NREAD) || defined(SCO325)) || defined(_SEQUENT_)
+#include <sys/stropts.h>
+#endif
+
+#else /* !WIN32 */
+
+#include <X11/Xwinsock.h>
+#include <X11/Xw32defs.h>
+#undef close
+#define close closesocket
+#define ECONNREFUSED WSAECONNREFUSED
+#define EADDRINUSE WSAEADDRINUSE
+#define EPROTOTYPE WSAEPROTOTYPE
+#undef EWOULDBLOCK
+#define EWOULDBLOCK WSAEWOULDBLOCK
+#undef EINTR
+#define EINTR WSAEINTR
+#define X_INCLUDE_NETDB_H
+#define XOS_USE_MTSAFE_NETDBAPI
+#include <X11/Xos_r.h>
+#endif /* WIN32 */
+
+#if defined(SO_DONTLINGER) && defined(SO_LINGER)
+#undef SO_DONTLINGER
+#endif
+
+
+/*
+ * This is the Socket implementation of the X Transport service layer
+ *
+ * This file contains the implementation for both the UNIX and INET domains,
+ * and can be built for either one, or both.
+ *
+ */
+
+typedef struct _Sockettrans2dev {
+ char *transname;
+ int family;
+ int devcotsname;
+ int devcltsname;
+ int protocol;
+} Sockettrans2dev;
+
+static Sockettrans2dev Sockettrans2devtab[] = {
+#ifdef TCPCONN
+ {"inet",AF_INET,SOCK_STREAM,SOCK_DGRAM,0},
+ {"tcp",AF_INET,SOCK_STREAM,SOCK_DGRAM,0},
+#endif /* TCPCONN */
+#ifdef UNIXCONN
+ {"unix",AF_UNIX,SOCK_STREAM,SOCK_DGRAM,0},
+#if !defined(LOCALCONN)
+ {"local",AF_UNIX,SOCK_STREAM,SOCK_DGRAM,0},
+#endif /* !LOCALCONN */
+#endif /* UNIXCONN */
+};
+
+#define NUMSOCKETFAMILIES (sizeof(Sockettrans2devtab)/sizeof(Sockettrans2dev))
+
+
+#ifdef UNIXCONN
+
+#ifdef hpux
+
+#if defined(X11_t)
+#define UNIX_PATH "/usr/spool/sockets/X11/"
+#define UNIX_DIR "/usr/spool/sockets/X11"
+#define OLD_UNIX_PATH "/tmp/.X11-unix/X"
+#endif /* X11_t */
+#if defined(XIM_t)
+#define UNIX_PATH "/usr/spool/sockets/XIM/"
+#define UNIX_DIR "/usr/spool/sockets/XIM"
+#define OLD_UNIX_PATH "/tmp/.XIM-unix/XIM"
+#endif /* XIM_t */
+#if defined(FS_t) || defined(FONT_t)
+#define UNIX_PATH "/usr/spool/sockets/fontserv/"
+#define UNIX_DIR "/usr/spool/sockets/fontserv"
+#endif /* FS_t || FONT_t */
+#if defined(ICE_t)
+#define UNIX_PATH "/usr/spool/sockets/ICE/"
+#define UNIX_DIR "/usr/spool/sockets/ICE"
+#endif /* ICE_t */
+#if defined(TEST_t)
+#define UNIX_PATH "/usr/spool/sockets/xtrans_test/"
+#define UNIX_DIR "/usr/spool/sockets/xtrans_test"
+#endif
+#if defined(LBXPROXY_t)
+#define UNIX_PATH "/usr/spool/sockets/X11/"
+#define UNIX_DIR "/usr/spool/sockets/X11"
+#endif
+
+#else /* !hpux */
+
+#if defined(X11_t)
+#define UNIX_PATH "/tmp/.X11-unix/X"
+#define UNIX_DIR "/tmp/.X11-unix"
+#endif /* X11_t */
+#if defined(XIM_t)
+#define UNIX_PATH "/tmp/.XIM-unix/XIM"
+#define UNIX_DIR "/tmp/.XIM-unix"
+#endif /* XIM_t */
+#if defined(FS_t) || defined(FONT_t)
+#define UNIX_PATH "/tmp/.font-unix/fs"
+#define UNIX_DIR "/tmp/.font-unix"
+#endif /* FS_t || FONT_t */
+#if defined(ICE_t)
+#define UNIX_PATH "/tmp/.ICE-unix/"
+#define UNIX_DIR "/tmp/.ICE-unix"
+#endif /* ICE_t */
+#if defined(TEST_t)
+#define UNIX_PATH "/tmp/.Test-unix/test"
+#define UNIX_DIR "/tmp/.Test-unix"
+#endif
+#if defined(LBXPROXY_t)
+#define UNIX_PATH "/tmp/.X11-unix/X"
+#define UNIX_DIR "/tmp/.X11-unix"
+#endif
+
+#endif /* hpux */
+
+#endif /* UNIXCONN */
+
+#define PORTBUFSIZE 32
+
+/*
+ * These are some utility function used by the real interface function below.
+ */
+
+static int
+TRANS(SocketSelectFamily) (family)
+
+char *family;
+
+{
+ int i;
+
+ PRMSG (3,"TRANS(SocketSelectFamily) (%s)\n", family, 0, 0);
+
+ for (i = 0; i < NUMSOCKETFAMILIES;i++)
+ {
+ if (!strcmp (family, Sockettrans2devtab[i].transname))
+ return i;
+ }
+
+ return -1;
+}
+
+
+/*
+ * This function gets the local address of the socket and stores it in the
+ * XtransConnInfo structure for the connection.
+ */
+
+static int
+TRANS(SocketINETGetAddr) (ciptr)
+
+XtransConnInfo ciptr;
+
+{
+ struct sockaddr_in sockname;
+ int namelen = sizeof sockname;
+
+ PRMSG (3,"TRANS(SocketINETGetAddr) (%x)\n", ciptr, 0, 0);
+
+ if (getsockname (ciptr->fd,(struct sockaddr *) &sockname, &namelen) < 0)
+ {
+ PRMSG (1,"TRANS(SocketINETGetAddr): getsockname() failed: %d\n",
+ EGET(),0, 0);
+ return -1;
+ }
+
+ /*
+ * Everything looks good: fill in the XtransConnInfo structure.
+ */
+
+ if ((ciptr->addr = (char *) malloc (namelen)) == NULL)
+ {
+ PRMSG (1,
+ "TRANS(SocketINETGetAddr): Can't allocate space for the addr\n",
+ 0, 0, 0);
+ return -1;
+ }
+
+ ciptr->family = sockname.sin_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(SocketINETGetPeerAddr) (ciptr)
+
+XtransConnInfo ciptr;
+
+{
+ struct sockaddr_in sockname;
+ int namelen = sizeof(sockname);
+
+ PRMSG (3,"TRANS(SocketINETGetPeerAddr) (%x)\n", ciptr, 0, 0);
+
+ if (getpeername (ciptr->fd, (struct sockaddr *) &sockname, &namelen) < 0)
+ {
+ PRMSG (1,"TRANS(SocketINETGetPeerAddr): getpeername() failed: %d\n",
+ EGET(), 0, 0);
+ return -1;
+ }
+
+ /*
+ * Everything looks good: fill in the XtransConnInfo structure.
+ */
+
+ if ((ciptr->peeraddr = (char *) malloc (namelen)) == NULL)
+ {
+ PRMSG (1,
+ "TRANS(SocketINETGetPeerAddr): Can't allocate space for the addr\n",
+ 0, 0, 0);
+ return -1;
+ }
+
+ ciptr->peeraddrlen = namelen;
+ memcpy (ciptr->peeraddr, &sockname, ciptr->peeraddrlen);
+
+ return 0;
+}
+
+
+static XtransConnInfo
+TRANS(SocketOpen) (i, type)
+
+int i;
+int type;
+
+{
+ XtransConnInfo ciptr;
+
+ PRMSG (3,"TRANS(SocketOpen) (%d,%d)\n", i, type, 0);
+
+ if ((ciptr = (XtransConnInfo) calloc (
+ 1, sizeof(struct _XtransConnInfo))) == NULL)
+ {
+ PRMSG (1, "TRANS(SocketOpen): malloc failed\n", 0, 0, 0);
+ return NULL;
+ }
+
+ if ((ciptr->fd = socket(Sockettrans2devtab[i].family, type,
+ Sockettrans2devtab[i].protocol)) < 0
+#ifndef WIN32
+#if (defined(X11_t) && !defined(USE_POLL)) || defined(FS_t) || defined(FONT_t)
+ || ciptr->fd >= TRANS_OPEN_MAX
+#endif
+#endif
+ ) {
+ PRMSG (1, "TRANS(SocketOpen): socket() failed for %s\n",
+ Sockettrans2devtab[i].transname, 0, 0);
+
+ free ((char *) ciptr);
+ return NULL;
+ }
+
+#ifdef TCP_NODELAY
+ if (Sockettrans2devtab[i].family == AF_INET)
+ {
+ /*
+ * turn off TCP coalescence for INET sockets
+ */
+
+ int tmp = 1;
+ setsockopt (ciptr->fd, IPPROTO_TCP, TCP_NODELAY,
+ (char *) &tmp, sizeof (int));
+ }
+#endif
+
+ return ciptr;
+}
+
+
+#ifdef TRANS_REOPEN
+
+static XtransConnInfo
+TRANS(SocketReopen) (i, type, fd, port)
+
+int i;
+int type;
+int fd;
+char *port;
+
+{
+ XtransConnInfo ciptr;
+
+ PRMSG (3,"TRANS(SocketReopen) (%d,%d,%s)\n", type, fd, port);
+
+ if ((ciptr = (XtransConnInfo) calloc (
+ 1, sizeof(struct _XtransConnInfo))) == NULL)
+ {
+ PRMSG (1, "TRANS(SocketReopen): malloc failed\n", 0, 0, 0);
+ return NULL;
+ }
+
+ ciptr->fd = fd;
+
+ return ciptr;
+}
+
+#endif /* TRANS_REOPEN */
+
+
+/*
+ * These functions are the interface supplied in the Xtransport structure
+ */
+
+#ifdef TRANS_CLIENT
+
+static XtransConnInfo
+TRANS(SocketOpenCOTSClient) (thistrans, protocol, host, port)
+
+Xtransport *thistrans;
+char *protocol;
+char *host;
+char *port;
+
+{
+ XtransConnInfo ciptr;
+ int i;
+
+ PRMSG (2, "TRANS(SocketOpenCOTSClient) (%s,%s,%s)\n",
+ protocol, host, port);
+
+ if ((i = TRANS(SocketSelectFamily) (thistrans->TransName)) < 0)
+ {
+ PRMSG (1,
+ "TRANS(SocketOpenCOTSClient): Unable to determine socket type for %s\n",
+ thistrans->TransName, 0, 0);
+ return NULL;
+ }
+
+ if ((ciptr = TRANS(SocketOpen) (
+ i, Sockettrans2devtab[i].devcotsname)) == NULL)
+ {
+ PRMSG (1,"TRANS(SocketOpenCOTSClient): Unable to open socket for %s\n",
+ thistrans->TransName, 0, 0);
+ return NULL;
+ }
+
+ /* Save the index for later use */
+
+ ciptr->index = i;
+
+ return ciptr;
+}
+
+#endif /* TRANS_CLIENT */
+
+
+#ifdef TRANS_SERVER
+
+static XtransConnInfo
+TRANS(SocketOpenCOTSServer) (thistrans, protocol, host, port)
+
+Xtransport *thistrans;
+char *protocol;
+char *host;
+char *port;
+
+{
+ XtransConnInfo ciptr;
+ int i;
+
+ PRMSG (2,"TRANS(SocketOpenCOTSServer) (%s,%s,%s)\n", protocol, host, port);
+
+ if ((i = TRANS(SocketSelectFamily) (thistrans->TransName)) < 0)
+ {
+ PRMSG (1,
+ "TRANS(SocketOpenCOTSServer): Unable to determine socket type for %s\n",
+ thistrans->TransName, 0, 0);
+ return NULL;
+ }
+
+ if ((ciptr = TRANS(SocketOpen) (
+ i, Sockettrans2devtab[i].devcotsname)) == NULL)
+ {
+ PRMSG (1,"TRANS(SocketOpenCOTSServer): Unable to open socket for %s\n",
+ thistrans->TransName, 0, 0);
+ return NULL;
+ }
+
+#ifdef SO_REUSEADDR
+
+ /*
+ * SO_REUSEADDR only applied to AF_INET
+ */
+
+ if (Sockettrans2devtab[i].family == AF_INET)
+ {
+ int one = 1;
+ setsockopt (ciptr->fd, SOL_SOCKET, SO_REUSEADDR,
+ (char *) &one, sizeof (int));
+ }
+#endif
+
+ /* Save the index for later use */
+
+ ciptr->index = i;
+
+ return ciptr;
+}
+
+#endif /* TRANS_SERVER */
+
+
+#ifdef TRANS_CLIENT
+
+static XtransConnInfo
+TRANS(SocketOpenCLTSClient) (thistrans, protocol, host, port)
+
+Xtransport *thistrans;
+char *protocol;
+char *host;
+char *port;
+
+{
+ XtransConnInfo ciptr;
+ int i;
+
+ PRMSG (2,"TRANS(SocketOpenCLTSClient) (%s,%s,%s)\n", protocol, host, port);
+
+ if ((i = TRANS(SocketSelectFamily) (thistrans->TransName)) < 0)
+ {
+ PRMSG (1,
+ "TRANS(SocketOpenCLTSClient): Unable to determine socket type for %s\n",
+ thistrans->TransName, 0, 0);
+ return NULL;
+ }
+
+ if ((ciptr = TRANS(SocketOpen) (
+ i, Sockettrans2devtab[i].devcotsname)) == NULL)
+ {
+ PRMSG (1,"TRANS(SocketOpenCLTSClient): Unable to open socket for %s\n",
+ thistrans->TransName, 0, 0);
+ return NULL;
+ }
+
+ /* Save the index for later use */
+
+ ciptr->index = i;
+
+ return ciptr;
+}
+
+#endif /* TRANS_CLIENT */
+
+
+#ifdef TRANS_SERVER
+
+static XtransConnInfo
+TRANS(SocketOpenCLTSServer) (thistrans, protocol, host, port)
+
+Xtransport *thistrans;
+char *protocol;
+char *host;
+char *port;
+
+{
+ XtransConnInfo ciptr;
+ int i;
+
+ PRMSG (2,"TRANS(SocketOpenCLTSServer) (%s,%s,%s)\n", protocol, host, port);
+
+ if ((i = TRANS(SocketSelectFamily) (thistrans->TransName)) < 0)
+ {
+ PRMSG (1,
+ "TRANS(SocketOpenCLTSServer): Unable to determine socket type for %s\n",
+ thistrans->TransName, 0, 0);
+ return NULL;
+ }
+
+ if ((ciptr = TRANS(SocketOpen) (
+ i, Sockettrans2devtab[i].devcotsname)) == NULL)
+ {
+ PRMSG (1,"TRANS(SocketOpenCLTSServer): Unable to open socket for %s\n",
+ thistrans->TransName, 0, 0);
+ return NULL;
+ }
+
+ /* Save the index for later use */
+
+ ciptr->index = i;
+
+ return ciptr;
+}
+
+#endif /* TRANS_SERVER */
+
+
+#ifdef TRANS_REOPEN
+
+static XtransConnInfo
+TRANS(SocketReopenCOTSServer) (thistrans, fd, port)
+
+Xtransport *thistrans;
+int fd;
+char *port;
+
+{
+ XtransConnInfo ciptr;
+ int i;
+
+ PRMSG (2,
+ "TRANS(SocketReopenCOTSServer) (%d, %s)\n", fd, port, 0);
+
+ if ((i = TRANS(SocketSelectFamily) (thistrans->TransName)) < 0)
+ {
+ PRMSG (1,
+ "TRANS(SocketReopenCOTSServer): Unable to determine socket type for %s\n",
+ thistrans->TransName, 0, 0);
+ return NULL;
+ }
+
+ if ((ciptr = TRANS(SocketReopen) (
+ i, Sockettrans2devtab[i].devcotsname, fd, port)) == NULL)
+ {
+ PRMSG (1,
+ "TRANS(SocketReopenCOTSServer): Unable to reopen socket for %s\n",
+ thistrans->TransName, 0, 0);
+ return NULL;
+ }
+
+ /* Save the index for later use */
+
+ ciptr->index = i;
+
+ return ciptr;
+}
+
+static XtransConnInfo
+TRANS(SocketReopenCLTSServer) (thistrans, fd, port)
+
+Xtransport *thistrans;
+int fd;
+char *port;
+
+{
+ XtransConnInfo ciptr;
+ int i;
+
+
+ PRMSG (2,
+ "TRANS(SocketReopenCLTSServer) (%d, %s)\n", fd, port, 0);
+
+ if ((i = TRANS(SocketSelectFamily) (thistrans->TransName)) < 0)
+ {
+ PRMSG (1,
+ "TRANS(SocketReopenCLTSServer): Unable to determine socket type for %s\n",
+ thistrans->TransName, 0, 0);
+ return NULL;
+ }
+
+ if ((ciptr = TRANS(SocketReopen) (
+ i, Sockettrans2devtab[i].devcotsname, fd, port)) == NULL)
+ {
+ PRMSG (1,
+ "TRANS(SocketReopenCLTSServer): Unable to reopen socket for %s\n",
+ thistrans->TransName, 0, 0);
+ return NULL;
+ }
+
+ /* Save the index for later use */
+
+ ciptr->index = i;
+
+ return ciptr;
+}
+
+#endif /* TRANS_REOPEN */
+
+
+static int
+TRANS(SocketSetOption) (ciptr, option, arg)
+
+XtransConnInfo ciptr;
+int option;
+int arg;
+
+{
+ PRMSG (2,"TRANS(SocketSetOption) (%d,%d,%d)\n", ciptr->fd, option, arg);
+
+ return -1;
+}
+
+
+#ifdef UNIXCONN
+static int
+set_sun_path(const char *port, const char *upath, char *path)
+{
+ struct sockaddr_un s;
+ int maxlen = sizeof(s.sun_path) - 1;
+
+ if (!port || !*port || !path)
+ return -1;
+
+ if (*port == '/') { /* a full pathname */
+ if (strlen(port) > maxlen)
+ return -1;
+ sprintf(path, "%s", port);
+ } else {
+ if (strlen(port) + strlen(upath) > maxlen)
+ return -1;
+ sprintf(path, "%s%s", upath, port);
+ }
+ return 0;
+}
+#endif /* UNIXCONN */
+
+#ifdef TRANS_SERVER
+
+static int
+TRANS(SocketCreateListener) (ciptr, sockname, socknamelen)
+
+XtransConnInfo ciptr;
+struct sockaddr *sockname;
+int socknamelen;
+
+{
+ int namelen = socknamelen;
+ int fd = ciptr->fd;
+ int retry;
+
+ PRMSG (3, "TRANS(SocketCreateListener) (%x,%d)\n", ciptr, fd, 0);
+
+ if (Sockettrans2devtab[ciptr->index].family == AF_INET)
+ retry = 20;
+ else
+ retry = 0;
+
+ while (bind (fd, (struct sockaddr *) sockname, namelen) < 0)
+ {
+ if (errno == EADDRINUSE)
+ return TRANS_ADDR_IN_USE;
+
+ if (retry-- == 0) {
+ PRMSG (1, "TRANS(SocketCreateListener): failed to bind listener\n",
+ 0, 0, 0);
+ close (fd);
+ return TRANS_CREATE_LISTENER_FAILED;
+ }
+#ifdef SO_REUSEADDR
+ sleep (1);
+#else
+ sleep (10);
+#endif /* SO_REUSEDADDR */
+ }
+
+ if (Sockettrans2devtab[ciptr->index].family == AF_INET) {
+#ifdef SO_DONTLINGER
+ setsockopt (fd, SOL_SOCKET, SO_DONTLINGER, (char *) NULL, 0);
+#else
+#ifdef SO_LINGER
+ {
+ static int linger[2] = { 0, 0 };
+ setsockopt (fd, SOL_SOCKET, SO_LINGER,
+ (char *) linger, sizeof (linger));
+ }
+#endif
+#endif
+}
+
+ if (listen (fd, 5) < 0)
+ {
+ PRMSG (1, "TRANS(SocketCreateListener): listen() failed\n", 0, 0, 0);
+ close (fd);
+ return TRANS_CREATE_LISTENER_FAILED;
+ }
+
+ /* Set a flag to indicate that this connection is a listener */
+
+ ciptr->flags = 1;
+
+ return 0;
+}
+
+#ifdef TCPCONN
+static int
+TRANS(SocketINETCreateListener) (ciptr, port)
+
+XtransConnInfo ciptr;
+char *port;
+
+{
+ struct sockaddr_in sockname;
+ int namelen = sizeof(sockname);
+ int status;
+ long tmpport;
+ _Xgetservbynameparams sparams;
+ struct servent *servp;
+
+
+ char portbuf[PORTBUFSIZE];
+
+ PRMSG (2, "TRANS(SocketINETCreateListener) (%s)\n", port, 0, 0);
+
+#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))
+ {
+ /* fixup the server port address */
+ tmpport = X_TCP_PORT + strtol (port, (char**)NULL, 10);
+ sprintf (portbuf,"%u", tmpport);
+ port = portbuf;
+ }
+#endif
+
+ if (port && *port)
+ {
+ /* Check to see if the port string is just a number (handles X11) */
+
+ if (!is_numeric (port))
+ {
+ if ((servp = _XGetservbyname (port,"tcp",sparams)) == NULL)
+ {
+ PRMSG (1,
+ "TRANS(SocketINETCreateListener): Unable to get service for %s\n",
+ port, 0, 0);
+ return TRANS_CREATE_LISTENER_FAILED;
+ }
+ /* we trust getservbyname to return a valid number */
+ sockname.sin_port = htons (servp->s_port);
+ }
+ else
+ {
+ tmpport = strtol (port, (char**)NULL, 10);
+ /*
+ * check that somehow the port address isn't negative or in
+ * the range of reserved port addresses. This can happen and
+ * be very bad if the server is suid-root and the user does
+ * something (dumb) like `X :60049`.
+ */
+ if (tmpport < 1024 || tmpport > USHRT_MAX)
+ return TRANS_CREATE_LISTENER_FAILED;
+
+ sockname.sin_port = htons (((unsigned short) tmpport));
+ }
+ }
+ else
+ sockname.sin_port = htons (0);
+
+#ifdef BSD44SOCKETS
+ sockname.sin_len = sizeof (sockname);
+#endif
+ sockname.sin_family = AF_INET;
+ sockname.sin_addr.s_addr = htonl (INADDR_ANY);
+
+ if ((status = TRANS(SocketCreateListener) (ciptr,
+ (struct sockaddr *) &sockname, namelen)) < 0)
+ {
+ PRMSG (1,
+ "TRANS(SocketINETCreateListener): TRANS(SocketCreateListener) () failed\n",
+ 0, 0, 0);
+ return status;
+ }
+
+ if (TRANS(SocketINETGetAddr) (ciptr) < 0)
+ {
+ PRMSG (1,
+ "TRANS(SocketINETCreateListener): TRANS(SocketINETGetAddr) () failed\n",
+ 0, 0, 0);
+ return TRANS_CREATE_LISTENER_FAILED;
+ }
+
+ return 0;
+}
+
+#endif /* SOCKCONN */
+
+
+#ifdef UNIXCONN
+
+static
+TRANS(SocketUNIXCreateListener) (ciptr, port)
+
+XtransConnInfo ciptr;
+char *port;
+
+{
+ struct sockaddr_un sockname;
+ int namelen;
+ int oldUmask;
+ int status;
+
+ PRMSG (2, "TRANS(SocketUNIXCreateListener) (%s)\n",
+ port ? port : "NULL", 0, 0);
+
+ /* Make sure the directory is created */
+
+ oldUmask = umask (0);
+
+#ifdef UNIX_DIR
+# ifdef HAS_STICKY_DIR_BIT
+ if (!mkdir (UNIX_DIR, 01777))
+ chmod (UNIX_DIR, 01777);
+# else
+ if (!mkdir (UNIX_DIR, 0777))
+ chmod (UNIX_DIR, 0777);
+# endif
+#endif
+
+ sockname.sun_family = AF_UNIX;
+
+ if (port && *port) {
+ if (set_sun_path(port, UNIX_PATH, sockname.sun_path) != 0) {
+ PRMSG (1, "SocketUNIXCreateListener: path too long\n", 0, 0, 0);
+ return TRANS_CREATE_LISTENER_FAILED;
+ }
+ } else {
+ sprintf (sockname.sun_path, "%s%d", UNIX_PATH, getpid());
+ }
+
+#ifdef BSD44SOCKETS
+ sockname.sun_len = strlen(sockname.sun_path);
+ namelen = SUN_LEN(&sockname);
+#else
+ namelen = strlen(sockname.sun_path) + sizeof(sockname.sun_family);
+#endif
+
+ unlink (sockname.sun_path);
+
+ if ((status = TRANS(SocketCreateListener) (ciptr,
+ (struct sockaddr *) &sockname, namelen)) < 0)
+ {
+ PRMSG (1,
+ "TRANS(SocketUNIXCreateListener): TRANS(SocketCreateListener) () failed\n",
+ 0, 0, 0);
+ return status;
+ }
+
+ /*
+ * Now that the listener is esablished, create the addr info for
+ * this connection. getpeername() doesn't work for UNIX Domain Sockets
+ * on some systems (hpux at least), so we will just do it manually, instead
+ * of calling something like TRANS(SocketUNIXGetAddr).
+ */
+
+ namelen = sizeof (sockname); /* this will always make it the same size */
+
+ if ((ciptr->addr = (char *) malloc (namelen)) == NULL)
+ {
+ PRMSG (1,
+ "TRANS(SocketUNIXCreateListener): Can't allocate space for the addr\n",
+ 0, 0, 0);
+ return TRANS_CREATE_LISTENER_FAILED;
+ }
+
+ ciptr->family = sockname.sun_family;
+ ciptr->addrlen = namelen;
+ memcpy (ciptr->addr, &sockname, ciptr->addrlen);
+
+ (void) umask (oldUmask);
+
+ return 0;
+}
+
+
+static
+TRANS(SocketUNIXResetListener) (ciptr)
+
+XtransConnInfo ciptr;
+
+{
+ /*
+ * See if the unix domain socket has disappeared. If it has, recreate it.
+ */
+
+ struct sockaddr_un *unsock = (struct sockaddr_un *) ciptr->addr;
+ struct stat statb;
+ int status = TRANS_RESET_NOOP;
+ void TRANS(FreeConnInfo) ();
+
+ PRMSG (3, "TRANS(SocketUNIXResetListener) (%x,%d)\n", ciptr, ciptr->fd, 0);
+
+ if (stat (unsock->sun_path, &statb) == -1 ||
+ ((statb.st_mode & S_IFMT) !=
+#if (defined (sun) && defined(SVR4)) || defined(NCR) || defined(sco)
+ S_IFIFO))
+#else
+ S_IFSOCK))
+#endif
+ {
+ int oldUmask = umask (0);
+
+#ifdef UNIX_DIR
+# ifdef HAS_STICKY_DIR_BIT
+ if (!mkdir (UNIX_DIR, 01777))
+ chmod (UNIX_DIR, 01777);
+# else
+ if (!mkdir (UNIX_DIR, 0777))
+ chmod (UNIX_DIR, 0777);
+# endif
+#endif
+
+ close (ciptr->fd);
+ unlink (unsock->sun_path);
+
+ if ((ciptr->fd = socket (AF_UNIX, SOCK_STREAM, 0)) < 0)
+ {
+ TRANS(FreeConnInfo) (ciptr);
+ return TRANS_RESET_FAILURE;
+ }
+
+ if (bind (ciptr->fd, (struct sockaddr *) unsock, ciptr->addrlen) < 0)
+ {
+ close (ciptr->fd);
+ TRANS(FreeConnInfo) (ciptr);
+ return TRANS_RESET_FAILURE;
+ }
+
+ if (listen (ciptr->fd, 5) < 0)
+ {
+ close (ciptr->fd);
+ TRANS(FreeConnInfo) (ciptr);
+ return TRANS_RESET_FAILURE;
+ }
+
+ umask (oldUmask);
+
+ status = TRANS_RESET_NEW_FD;
+ }
+
+ return status;
+}
+
+#endif /* UNIXCONN */
+
+
+#ifdef TCPCONN
+
+static XtransConnInfo
+TRANS(SocketINETAccept) (ciptr, status)
+
+XtransConnInfo ciptr;
+int *status;
+
+{
+ XtransConnInfo newciptr;
+ struct sockaddr_in sockname;
+ int namelen = sizeof(sockname);
+
+ PRMSG (2, "TRANS(SocketINETAccept) (%x,%d)\n", ciptr, ciptr->fd, 0);
+
+ if ((newciptr = (XtransConnInfo) calloc (
+ 1, sizeof(struct _XtransConnInfo))) == NULL)
+ {
+ PRMSG (1, "TRANS(SocketINETAccept): 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, "TRANS(SocketINETAccept): accept() failed\n", 0, 0, 0);
+ free (newciptr);
+ *status = TRANS_ACCEPT_FAILED;
+ return NULL;
+ }
+
+#ifdef TCP_NODELAY
+ {
+ /*
+ * turn off TCP coalescence for INET sockets
+ */
+
+ int tmp = 1;
+ setsockopt (newciptr->fd, IPPROTO_TCP, TCP_NODELAY,
+ (char *) &tmp, sizeof (int));
+ }
+#endif
+
+ /*
+ * Get this address again because the transport may give a more
+ * specific address now that a connection is established.
+ */
+
+ if (TRANS(SocketINETGetAddr) (newciptr) < 0)
+ {
+ PRMSG (1,
+ "TRANS(SocketINETAccept): TRANS(SocketINETGetAddr) () failed:\n",
+ 0, 0, 0);
+ close (newciptr->fd);
+ free (newciptr);
+ *status = TRANS_ACCEPT_MISC_ERROR;
+ return NULL;
+ }
+
+ if (TRANS(SocketINETGetPeerAddr) (newciptr) < 0)
+ {
+ PRMSG (1,
+ "TRANS(SocketINETAccept): TRANS(SocketINETGetPeerAddr) () failed:\n",
+ 0, 0, 0);
+ close (newciptr->fd);
+ if (newciptr->addr) free (newciptr->addr);
+ free (newciptr);
+ *status = TRANS_ACCEPT_MISC_ERROR;
+ return NULL;
+ }
+
+ *status = 0;
+
+ return newciptr;
+}
+
+#endif /* TCPCONN */
+
+
+#ifdef UNIXCONN
+static XtransConnInfo
+TRANS(SocketUNIXAccept) (ciptr, status)
+
+XtransConnInfo ciptr;
+int *status;
+
+{
+ XtransConnInfo newciptr;
+ struct sockaddr_un sockname;
+ int namelen = sizeof(sockname);
+
+ PRMSG (2, "TRANS(SocketUNIXAccept) (%x,%d)\n", ciptr, ciptr->fd, 0);
+
+ if ((newciptr = (XtransConnInfo) calloc (
+ 1, sizeof(struct _XtransConnInfo))) == NULL)
+ {
+ PRMSG (1, "TRANS(SocketUNIXAccept): 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, "TRANS(SocketUNIXAccept): accept() failed\n", 0, 0, 0);
+ free (newciptr);
+ *status = TRANS_ACCEPT_FAILED;
+ return NULL;
+ }
+
+ /*
+ * Get the socket name and the peer name from the listener socket,
+ * since this is unix domain.
+ */
+
+ if ((newciptr->addr = (char *) malloc (ciptr->addrlen)) == NULL)
+ {
+ PRMSG (1,
+ "TRANS(SocketUNIXAccept): Can't allocate space for the addr\n",
+ 0, 0, 0);
+ close (newciptr->fd);
+ free (newciptr);
+ *status = TRANS_ACCEPT_BAD_MALLOC;
+ return NULL;
+ }
+
+
+ newciptr->addrlen = ciptr->addrlen;
+ memcpy (newciptr->addr, ciptr->addr, newciptr->addrlen);
+
+ if ((newciptr->peeraddr = (char *) malloc (ciptr->addrlen)) == NULL)
+ {
+ PRMSG (1,
+ "TRANS(SocketUNIXAccept): Can't allocate space for the addr\n",
+ 0, 0, 0);
+ close (newciptr->fd);
+ if (newciptr->addr) free (newciptr->addr);
+ free (newciptr);
+ *status = TRANS_ACCEPT_BAD_MALLOC;
+ return NULL;
+ }
+
+ newciptr->peeraddrlen = ciptr->addrlen;
+ memcpy (newciptr->peeraddr, ciptr->addr, newciptr->addrlen);
+
+ newciptr->family = AF_UNIX;
+
+ *status = 0;
+
+ return newciptr;
+}
+
+#endif /* UNIXCONN */
+
+#endif /* TRANS_SERVER */
+
+
+#ifdef TRANS_CLIENT
+
+#ifdef TCPCONN
+static int
+TRANS(SocketINETConnect) (ciptr, host, port)
+
+XtransConnInfo ciptr;
+char *host;
+char *port;
+
+{
+ struct sockaddr_in sockname;
+ int namelen = sizeof(sockname);
+ _Xgethostbynameparams hparams;
+ _Xgetservbynameparams sparams;
+ struct hostent *hostp;
+ struct servent *servp;
+
+ char portbuf[PORTBUFSIZE];
+
+ long tmpport;
+ unsigned long tmpaddr;
+ char hostnamebuf[256]; /* tmp space */
+
+ PRMSG (2,"TRANS(SocketINETConnect) (%d,%s,%s)\n", ciptr->fd, host, port);
+
+ if (!host)
+ {
+ hostnamebuf[0] = '\0';
+ (void) TRANS(GetHostname) (hostnamebuf, sizeof hostnamebuf);
+ host = hostnamebuf;
+ }
+
+#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))
+ {
+ tmpport = X_TCP_PORT + strtol (port, (char**)NULL, 10);
+ sprintf (portbuf, "%u", tmpport);
+ port = portbuf;
+ }
+#endif
+
+ /*
+ * Build the socket name.
+ */
+
+#ifdef BSD44SOCKETS
+ sockname.sin_len = sizeof (struct sockaddr_in);
+#endif
+ sockname.sin_family = AF_INET;
+
+ /*
+ * fill in sin_addr
+ */
+
+ /* check for ww.xx.yy.zz host string */
+
+ if (isascii (host[0]) && isdigit (host[0])) {
+ tmpaddr = inet_addr (host); /* returns network byte order */
+ } else {
+ tmpaddr = -1;
+ }
+
+ PRMSG (4,"TRANS(SocketINETConnect) inet_addr(%s) = %x\n",
+ host, tmpaddr, 0);
+
+ if (tmpaddr == -1)
+ {
+ if ((hostp = _XGethostbyname(host,hparams)) == NULL)
+ {
+ PRMSG (1,"TRANS(SocketINETConnect) () can't get address for %s\n",
+ host, 0, 0);
+ ESET(EINVAL);
+ return TRANS_CONNECT_FAILED;
+ }
+ if (hostp->h_addrtype != AF_INET) /* is IP host? */
+ {
+ PRMSG (1,"TRANS(SocketINETConnect) () not INET host%s\n",
+ host, 0, 0);
+ ESET(EPROTOTYPE);
+ return TRANS_CONNECT_FAILED;
+ }
+
+#if defined(CRAY) && defined(OLDTCP)
+ /* Only Cray UNICOS3 and UNICOS4 will define this */
+ {
+ long t;
+ memcpy ((char *)&t, (char *) hostp->h_addr, sizeof (t));
+ sockname.sin_addr = t;
+ }
+#else
+ memcpy ((char *) &sockname.sin_addr, (char *) hostp->h_addr,
+ sizeof (sockname.sin_addr));
+#endif /* CRAY and OLDTCP */
+
+ }
+else
+ {
+#if defined(CRAY) && defined(OLDTCP)
+ /* Only Cray UNICOS3 and UNICOS4 will define this */
+ sockname.sin_addr = tmpaddr;
+#else
+ sockname.sin_addr.s_addr = tmpaddr;
+#endif /* CRAY and OLDTCP */
+ }
+
+ /*
+ * fill in sin_port
+ */
+
+ /* Check for number in the port string */
+
+ if (!is_numeric (port))
+ {
+ if ((servp = _XGetservbyname (port,"tcp",sparams)) == NULL)
+ {
+ PRMSG (1,"TRANS(SocketINETConnect) () can't get service for %s\n",
+ port, 0, 0);
+ return TRANS_CONNECT_FAILED;
+ }
+ sockname.sin_port = htons (servp->s_port);
+ }
+ else
+ {
+ tmpport = strtol (port, (char**)NULL, 10);
+ if (tmpport < 1024 || tmpport > USHRT_MAX)
+ return TRANS_CONNECT_FAILED;
+ sockname.sin_port = htons (((unsigned short) tmpport));
+ }
+
+ PRMSG (4,"TRANS(SocketINETConnect) sockname.sin_port = %d\n",
+ ntohs(sockname.sin_port), 0, 0);
+
+ /*
+ * Turn on socket keepalive so the client process will eventually
+ * be notified with a SIGPIPE signal if the display server fails
+ * to respond to a periodic transmission of messages
+ * on the connected socket.
+ * This is useful to avoid hung application processes when the
+ * processes are not spawned from the xdm session and
+ * the display server terminates abnormally.
+ * (Someone turned off the power switch.)
+ */
+
+ {
+ int tmp = 1;
+ setsockopt (ciptr->fd, SOL_SOCKET, SO_KEEPALIVE,
+ (char *) &tmp, sizeof (int));
+ }
+
+ /*
+ * Do the connect()
+ */
+
+ if (connect (ciptr->fd, (struct sockaddr *) &sockname, namelen) < 0)
+ {
+#ifdef WIN32
+ int olderrno = WSAGetLastError();
+#else
+ int olderrno = errno;
+#endif
+
+ PRMSG (1,"TRANS(SocketINETConnect) () can't connect: errno = %d\n",
+ EGET(),0, 0);
+
+ /*
+ * If the error was ECONNREFUSED, the server may be overloaded
+ * and we should try again.
+ *
+ * If the error was EINTR, the connect was interrupted and we
+ * should try again.
+ */
+
+ if (olderrno == ECONNREFUSED || olderrno == EINTR)
+ return TRANS_TRY_CONNECT_AGAIN;
+ else
+ return TRANS_CONNECT_FAILED;
+ }
+
+
+ /*
+ * Sync up the address fields of ciptr.
+ */
+
+ if (TRANS(SocketINETGetAddr) (ciptr) < 0)
+ {
+ PRMSG (1,
+ "TRANS(SocketINETConnect): TRANS(SocketINETGetAddr) () failed:\n",
+ 0, 0, 0);
+ return TRANS_CONNECT_FAILED;
+ }
+
+ if (TRANS(SocketINETGetPeerAddr) (ciptr) < 0)
+ {
+ PRMSG (1,
+ "TRANS(SocketINETConnect): TRANS(SocketINETGetPeerAddr) () failed:\n",
+ 0, 0, 0);
+ return TRANS_CONNECT_FAILED;
+ }
+
+ return 0;
+}
+
+#endif /* TCPCONN */
+
+
+
+#ifdef UNIXCONN
+
+/*
+ * Make sure 'host' is really local.
+ */
+
+static int
+UnixHostReallyLocal (host)
+
+char *host;
+
+{
+ char hostnamebuf[256];
+
+ TRANS(GetHostname) (hostnamebuf, sizeof (hostnamebuf));
+
+ if (strcmp (hostnamebuf, host) == 0)
+ {
+ return (1);
+ }
+ else
+ {
+ /*
+ * A host may have more than one network address. If any of the
+ * network addresses of 'host' (specified to the connect call)
+ * match any of the network addresses of 'hostname' (determined
+ * by TRANS(GetHostname)), then the two hostnames are equivalent,
+ * and we know that 'host' is really a local host.
+ */
+ char specified_local_addr_list[10][4];
+ int scount, equiv, i, j;
+ _Xgethostbynameparams hparams;
+ struct hostent *hostp;
+
+ if ((hostp = _XGethostbyname (host,hparams)) == NULL)
+ return (0);
+
+ scount = 0;
+ while (hostp->h_addr_list[scount] && scount <= 8)
+ {
+ /*
+ * The 2nd call to gethostname() overrides the data
+ * from the 1st call, so we must save the address list.
+ */
+
+ specified_local_addr_list[scount][0] =
+ hostp->h_addr_list[scount][0];
+ specified_local_addr_list[scount][1] =
+ hostp->h_addr_list[scount][1];
+ specified_local_addr_list[scount][2] =
+ hostp->h_addr_list[scount][2];
+ specified_local_addr_list[scount][3] =
+ hostp->h_addr_list[scount][3];
+ scount++;
+ }
+ if ((hostp = _XGethostbyname (hostnamebuf,hparams)) == NULL)
+ return (0);
+
+ equiv = 0;
+ i = 0;
+
+ while (i < scount && !equiv)
+ {
+ j = 0;
+
+ while (hostp->h_addr_list[j])
+ {
+ if ((specified_local_addr_list[i][0] ==
+ hostp->h_addr_list[j][0]) &&
+ (specified_local_addr_list[i][1] ==
+ hostp->h_addr_list[j][1]) &&
+ (specified_local_addr_list[i][2] ==
+ hostp->h_addr_list[j][2]) &&
+ (specified_local_addr_list[i][3] ==
+ hostp->h_addr_list[j][3]))
+ {
+ /* They're equal, so we're done */
+
+ equiv = 1;
+ break;
+ }
+
+ j++;
+ }
+
+ i++;
+ }
+
+ return (equiv);
+ }
+}
+
+static int
+TRANS(SocketUNIXConnect) (ciptr, host, port)
+
+XtransConnInfo ciptr;
+char *host;
+char *port;
+
+{
+ struct sockaddr_un sockname;
+ int namelen;
+
+#if defined(hpux) && defined(X11_t)
+ struct sockaddr_un old_sockname;
+ int old_namelen;
+#endif
+
+
+ PRMSG (2,"TRANS(SocketUNIXConnect) (%d,%s,%s)\n", ciptr->fd, host, port);
+
+ /*
+ * Make sure 'host' is really local. If not, we return failure.
+ * The reason we make this check is because a process may advertise
+ * a "local" network ID for which it can accept connections, but if
+ * a process on a remote machine tries to connect to this network ID,
+ * we know for sure it will fail.
+ */
+
+ if (strcmp (host, "unix") != 0 && !UnixHostReallyLocal (host))
+ {
+ PRMSG (1,
+ "TRANS(SocketUNIXConnect): Cannot connect to non-local host %s\n",
+ host, 0, 0);
+ return TRANS_CONNECT_FAILED;
+ }
+
+
+ /*
+ * Check the port.
+ */
+
+ if (!port || !*port)
+ {
+ PRMSG (1,"TRANS(SocketUNIXConnect): Missing port specification\n",
+ 0, 0, 0);
+ return TRANS_CONNECT_FAILED;
+ }
+
+ /*
+ * Build the socket name.
+ */
+
+ sockname.sun_family = AF_UNIX;
+
+ if (set_sun_path(port, UNIX_PATH, sockname.sun_path) != 0) {
+ PRMSG (1, "SocketUNIXConnect: path too long\n", 0, 0, 0);
+ return TRANS_CONNECT_FAILED;
+ }
+
+#ifdef BSD44SOCKETS
+ sockname.sun_len = strlen (sockname.sun_path);
+ namelen = SUN_LEN (&sockname);
+#else
+ namelen = strlen (sockname.sun_path) + sizeof (sockname.sun_family);
+#endif
+
+
+#if defined(hpux) && defined(X11_t)
+ /*
+ * This is gross, but it was in Xlib
+ */
+ old_sockname.sun_family = AF_UNIX;
+ if (*port == '/') { /* a full pathname */
+ sprintf (old_sockname.sun_path, "%s", port);
+ } else {
+ sprintf (old_sockname.sun_path, "%s%s", OLD_UNIX_PATH, port);
+ }
+ old_namelen = strlen (old_sockname.sun_path) +
+ sizeof (old_sockname.sun_family);
+#endif
+
+
+ /*
+ * Do the connect()
+ */
+
+ if (connect (ciptr->fd, (struct sockaddr *) &sockname, namelen) < 0)
+ {
+ int olderrno = errno;
+ int connected = 0;
+
+#if defined(hpux) && defined(X11_t)
+ if (olderrno == ENOENT)
+ {
+ if (connect (ciptr->fd,
+ (struct sockaddr *) &old_sockname, old_namelen) >= 0)
+ {
+ connected = 1;
+ }
+ else
+ olderrno = errno;
+ }
+#endif
+ if (!connected)
+ {
+ errno = olderrno;
+
+ PRMSG (1,"TRANS(SocketUNIXConnect) () can't connect: errno = %d\n",
+ EGET(),0, 0);
+
+ if (olderrno == ENOENT || olderrno == EINTR)
+ return TRANS_TRY_CONNECT_AGAIN;
+ else
+ return TRANS_CONNECT_FAILED;
+ }
+ }
+
+ /*
+ * Get the socket name and the peer name from the connect socket,
+ * since this is unix domain.
+ */
+
+ if ((ciptr->addr = (char *) malloc(namelen)) == NULL ||
+ (ciptr->peeraddr = (char *) malloc(namelen)) == NULL)
+ {
+ PRMSG (1,
+ "TRANS(SocketUNIXCreateListener): Can't allocate space for the addr\n",
+ 0, 0, 0);
+ return TRANS_CONNECT_FAILED;
+ }
+
+ ciptr->family = AF_UNIX;
+ ciptr->addrlen = namelen;
+ ciptr->peeraddrlen = namelen;
+ memcpy (ciptr->addr, &sockname, ciptr->addrlen);
+ memcpy (ciptr->peeraddr, &sockname, ciptr->peeraddrlen);
+
+ return 0;
+}
+
+#endif /* UNIXCONN */
+
+#endif /* TRANS_CLIENT */
+
+
+static int
+TRANS(SocketBytesReadable) (ciptr, pend)
+
+XtransConnInfo ciptr;
+BytesReadable_t *pend;
+
+{
+ PRMSG (2,"TRANS(SocketBytesReadable) (%x,%d,%x)\n",
+ ciptr, ciptr->fd, pend);
+
+#ifdef WIN32
+ return ioctlsocket ((SOCKET) ciptr->fd, FIONREAD, (u_long *) pend);
+#else
+#if (defined(i386) && defined(SYSV) && !defined(sco)) || (defined(_SEQUENT_) && _SOCKET_VERSION == 1)
+ return ioctl (ciptr->fd, I_NREAD, (char *) pend);
+#else
+ return ioctl (ciptr->fd, FIONREAD, (char *) pend);
+#endif /* i386 && SYSV || _SEQUENT_ && _SOCKET_VERSION == 1 */
+#endif /* WIN32 */
+}
+
+
+static int
+TRANS(SocketRead) (ciptr, buf, size)
+
+XtransConnInfo ciptr;
+char *buf;
+int size;
+
+{
+ PRMSG (2,"TRANS(SocketRead) (%d,%x,%d)\n", ciptr->fd, buf, size);
+
+#ifdef WIN32
+ return recv ((SOCKET)ciptr->fd, buf, size, 0);
+#else
+ return read (ciptr->fd, buf, size);
+#endif /* WIN32 */
+}
+
+
+static int
+TRANS(SocketWrite) (ciptr, buf, size)
+
+XtransConnInfo ciptr;
+char *buf;
+int size;
+
+{
+ PRMSG (2,"TRANS(SocketWrite) (%d,%x,%d)\n", ciptr->fd, buf, size);
+
+#ifdef WIN32
+ return send ((SOCKET)ciptr->fd, buf, size, 0);
+#else
+ return write (ciptr->fd, buf, size);
+#endif /* WIN32 */
+}
+
+
+static int
+TRANS(SocketReadv) (ciptr, buf, size)
+
+XtransConnInfo ciptr;
+struct iovec *buf;
+int size;
+
+{
+ PRMSG (2,"TRANS(SocketReadv) (%d,%x,%d)\n", ciptr->fd, buf, size);
+
+ return READV (ciptr, buf, size);
+}
+
+
+static int
+TRANS(SocketWritev) (ciptr, buf, size)
+
+XtransConnInfo ciptr;
+struct iovec *buf;
+int size;
+
+{
+ PRMSG (2,"TRANS(SocketWritev) (%d,%x,%d)\n", ciptr->fd, buf, size);
+
+ return WRITEV (ciptr, buf, size);
+}
+
+
+static int
+TRANS(SocketDisconnect) (ciptr)
+
+XtransConnInfo ciptr;
+
+{
+ PRMSG (2,"TRANS(SocketDisconnect) (%x,%d)\n", ciptr, ciptr->fd, 0);
+
+ return shutdown (ciptr->fd, 2); /* disallow further sends and receives */
+}
+
+
+#ifdef TCPCONN
+static int
+TRANS(SocketINETClose) (ciptr)
+
+XtransConnInfo ciptr;
+
+{
+ PRMSG (2,"TRANS(SocketINETClose) (%x,%d)\n", ciptr, ciptr->fd, 0);
+
+ return close (ciptr->fd);
+}
+
+#endif /* TCPCONN */
+
+
+#ifdef UNIXCONN
+static int
+TRANS(SocketUNIXClose) (ciptr)
+
+XtransConnInfo ciptr;
+
+{
+ /*
+ * If this is the server side, then once the socket is closed,
+ * it must be unlinked to completely close it
+ */
+
+ struct sockaddr_un *sockname = (struct sockaddr_un *) ciptr->addr;
+ char path[200]; /* > sizeof sun_path +1 */
+ int ret;
+
+ PRMSG (2,"TRANS(SocketUNIXClose) (%x,%d)\n", ciptr, ciptr->fd, 0);
+
+ ret = close(ciptr->fd);
+
+ if (ciptr->flags
+ && sockname
+ && sockname->sun_family == AF_UNIX
+ && sockname->sun_path[0])
+ {
+ strncpy (path, sockname->sun_path,
+ ciptr->addrlen - sizeof (sockname->sun_family));
+ unlink (path);
+ }
+
+ return ret;
+}
+
+static int
+TRANS(SocketUNIXCloseForCloning) (ciptr)
+
+XtransConnInfo ciptr;
+
+{
+ /*
+ * Don't unlink path.
+ */
+
+ int ret;
+
+ PRMSG (2,"TRANS(SocketUNIXCloseForCloning) (%x,%d)\n",
+ ciptr, ciptr->fd, 0);
+
+ ret = close(ciptr->fd);
+
+ return ret;
+}
+
+#endif /* UNIXCONN */
+
+
+#ifdef TCPCONN
+Xtransport TRANS(SocketTCPFuncs) = {
+ /* Socket Interface */
+ "tcp",
+ 0,
+#ifdef TRANS_CLIENT
+ TRANS(SocketOpenCOTSClient),
+#endif /* TRANS_CLIENT */
+#ifdef TRANS_SERVER
+ TRANS(SocketOpenCOTSServer),
+#endif /* TRANS_SERVER */
+#ifdef TRANS_CLIENT
+ TRANS(SocketOpenCLTSClient),
+#endif /* TRANS_CLIENT */
+#ifdef TRANS_SERVER
+ TRANS(SocketOpenCLTSServer),
+#endif /* TRANS_SERVER */
+#ifdef TRANS_REOPEN
+ TRANS(SocketReopenCOTSServer),
+ TRANS(SocketReopenCLTSServer),
+#endif
+ TRANS(SocketSetOption),
+#ifdef TRANS_SERVER
+ TRANS(SocketINETCreateListener),
+ NULL, /* ResetListener */
+ TRANS(SocketINETAccept),
+#endif /* TRANS_SERVER */
+#ifdef TRANS_CLIENT
+ TRANS(SocketINETConnect),
+#endif /* TRANS_CLIENT */
+ TRANS(SocketBytesReadable),
+ TRANS(SocketRead),
+ TRANS(SocketWrite),
+ TRANS(SocketReadv),
+ TRANS(SocketWritev),
+ TRANS(SocketDisconnect),
+ TRANS(SocketINETClose),
+ TRANS(SocketINETClose),
+ };
+
+Xtransport TRANS(SocketINETFuncs) = {
+ /* Socket Interface */
+ "inet",
+ TRANS_ALIAS,
+#ifdef TRANS_CLIENT
+ TRANS(SocketOpenCOTSClient),
+#endif /* TRANS_CLIENT */
+#ifdef TRANS_SERVER
+ TRANS(SocketOpenCOTSServer),
+#endif /* TRANS_SERVER */
+#ifdef TRANS_CLIENT
+ TRANS(SocketOpenCLTSClient),
+#endif /* TRANS_CLIENT */
+#ifdef TRANS_SERVER
+ TRANS(SocketOpenCLTSServer),
+#endif /* TRANS_SERVER */
+#ifdef TRANS_REOPEN
+ TRANS(SocketReopenCOTSServer),
+ TRANS(SocketReopenCLTSServer),
+#endif
+ TRANS(SocketSetOption),
+#ifdef TRANS_SERVER
+ TRANS(SocketINETCreateListener),
+ NULL, /* ResetListener */
+ TRANS(SocketINETAccept),
+#endif /* TRANS_SERVER */
+#ifdef TRANS_CLIENT
+ TRANS(SocketINETConnect),
+#endif /* TRANS_CLIENT */
+ TRANS(SocketBytesReadable),
+ TRANS(SocketRead),
+ TRANS(SocketWrite),
+ TRANS(SocketReadv),
+ TRANS(SocketWritev),
+ TRANS(SocketDisconnect),
+ TRANS(SocketINETClose),
+ TRANS(SocketINETClose),
+ };
+
+#endif /* TCPCONN */
+
+#ifdef UNIXCONN
+#if !defined(LOCALCONN)
+Xtransport TRANS(SocketLocalFuncs) = {
+ /* Socket Interface */
+ "local",
+ 0,
+#ifdef TRANS_CLIENT
+ TRANS(SocketOpenCOTSClient),
+#endif /* TRANS_CLIENT */
+#ifdef TRANS_SERVER
+ TRANS(SocketOpenCOTSServer),
+#endif /* TRANS_SERVER */
+#ifdef TRANS_CLIENT
+ TRANS(SocketOpenCLTSClient),
+#endif /* TRANS_CLIENT */
+#ifdef TRANS_SERVER
+ TRANS(SocketOpenCLTSServer),
+#endif /* TRANS_SERVER */
+#ifdef TRANS_REOPEN
+ TRANS(SocketReopenCOTSServer),
+ TRANS(SocketReopenCLTSServer),
+#endif
+ TRANS(SocketSetOption),
+#ifdef TRANS_SERVER
+ TRANS(SocketUNIXCreateListener),
+ TRANS(SocketUNIXResetListener),
+ TRANS(SocketUNIXAccept),
+#endif /* TRANS_SERVER */
+#ifdef TRANS_CLIENT
+ TRANS(SocketUNIXConnect),
+#endif /* TRANS_CLIENT */
+ TRANS(SocketBytesReadable),
+ TRANS(SocketRead),
+ TRANS(SocketWrite),
+ TRANS(SocketReadv),
+ TRANS(SocketWritev),
+ TRANS(SocketDisconnect),
+ TRANS(SocketUNIXClose),
+ TRANS(SocketUNIXCloseForCloning),
+ };
+#endif /* !LOCALCONN */
+
+Xtransport TRANS(SocketUNIXFuncs) = {
+ /* Socket Interface */
+ "unix",
+#if !defined(LOCALCONN)
+ TRANS_ALIAS,
+#else
+ 0,
+#endif
+#ifdef TRANS_CLIENT
+ TRANS(SocketOpenCOTSClient),
+#endif /* TRANS_CLIENT */
+#ifdef TRANS_SERVER
+ TRANS(SocketOpenCOTSServer),
+#endif /* TRANS_SERVER */
+#ifdef TRANS_CLIENT
+ TRANS(SocketOpenCLTSClient),
+#endif /* TRANS_CLIENT */
+#ifdef TRANS_SERVER
+ TRANS(SocketOpenCLTSServer),
+#endif /* TRANS_SERVER */
+#ifdef TRANS_REOPEN
+ TRANS(SocketReopenCOTSServer),
+ TRANS(SocketReopenCLTSServer),
+#endif
+ TRANS(SocketSetOption),
+#ifdef TRANS_SERVER
+ TRANS(SocketUNIXCreateListener),
+ TRANS(SocketUNIXResetListener),
+ TRANS(SocketUNIXAccept),
+#endif /* TRANS_SERVER */
+#ifdef TRANS_CLIENT
+ TRANS(SocketUNIXConnect),
+#endif /* TRANS_CLIENT */
+ TRANS(SocketBytesReadable),
+ TRANS(SocketRead),
+ TRANS(SocketWrite),
+ TRANS(SocketReadv),
+ TRANS(SocketWritev),
+ TRANS(SocketDisconnect),
+ TRANS(SocketUNIXClose),
+ TRANS(SocketUNIXCloseForCloning),
+ };
+
+#endif /* UNIXCONN */
diff --git a/Xtranstli.c b/Xtranstli.c
new file mode 100644
index 0000000..b7daf70
--- /dev/null
+++ b/Xtranstli.c
@@ -0,0 +1,1494 @@
+/* $Xorg: Xtranstli.c,v 1.4 2001/02/09 02:04:07 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.
+
+*/
+
+/* 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 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.
+ */
+
+#include <sys/un.h>
+#include <stropts.h>
+#include <poll.h>
+#include <tiuser.h>
+
+#include <netdir.h>
+#include <netconfig.h>
+
+
+/*
+ * This is the TLI implementation of the X Transport service layer
+ */
+
+typedef struct _TLItrans2dev {
+ char *transname;
+ char *protofamily;
+ char *devcotsname;
+ char *devcltsname;
+ int family;
+} TLItrans2dev;
+
+static TLItrans2dev TLItrans2devtab[] = {
+ {"inet","inet","/dev/tcp","/dev/udp",AF_INET},
+ {"tcp","inet","/dev/tcp","/dev/udp",AF_INET},
+ {"tli","loopback","/dev/ticots","/dev/ticlts",AF_UNIX},
+};
+
+#define NUMTLIFAMILIES (sizeof(TLItrans2devtab)/sizeof(TLItrans2dev))
+
+/*
+ * The local TLI connection, is a form of a local connection, so use a
+ * sockaddr_un for the address so that it will be treated just like the other
+ * local transports such as UNIX domain sockets, pts, and named.
+ */
+
+#if defined(X11_t)
+#define TLINODENAME "TLI:xserver"
+#endif
+
+#if defined(XIM_t)
+#define TLINODENAME "TLI:xim"
+#endif
+
+#if defined(FS_t) || defined(FONT_t)
+#define TLINODENAME "TLI:fontserver"
+#endif
+
+#if defined(ICE_t)
+#define TLINODENAME "TLI:ICE"
+#endif
+
+#if defined(TEST_t)
+#define TLINODENAME "TLI:test"
+#endif
+
+#ifndef PORTBUFSIZE
+#ifdef TRANS_SERVER
+#define PORTBUFSIZE 64
+#else
+#ifdef TRANS_CLIENT
+#define PORTBUFSIZE 64
+#endif
+#endif
+#endif
+
+
+/*
+ * These are some utility function used by the real interface function below.
+ */
+
+static int
+TRANS(TLISelectFamily)(family)
+
+char *family;
+
+{
+ int i;
+
+ PRMSG(3,"TRANS(TLISelectFamily)(%s)\n", family, 0,0 );
+
+ for(i=0;i<NUMTLIFAMILIES;i++)
+ {
+ if( !strcmp(family,TLItrans2devtab[i].transname) )
+ return i;
+ }
+ return -1;
+}
+
+
+/*
+ * This function gets the local address of the transport and stores it in the
+ * XtransConnInfo structure for the connection.
+ */
+
+static int
+TRANS(TLIGetAddr)(ciptr)
+
+XtransConnInfo ciptr;
+
+{
+ Xtransaddr sockname;
+ struct netbuf netbuf;
+
+ PRMSG(3,"TRANS(TLIGetAddr)(%x)\n", ciptr, 0,0 );
+
+ netbuf.buf=(char *)&sockname;
+ netbuf.len=sizeof(sockname);
+ netbuf.maxlen=sizeof(sockname);
+
+ if( t_getname(ciptr->fd,&netbuf,LOCALNAME) < 0 )
+ {
+ PRMSG(1,"TRANS(TLIGetAddr): t_getname(LOCALNAME) failed: %d\n",
+ errno, 0,0 );
+ return -1;
+ }
+
+ PRMSG(4,"TRANS(TLIGetAddr): got family %d len %d\n",
+ ((struct sockaddr *) &sockname)->sa_family ,netbuf.len, 0 );
+
+ /*
+ * Everything looks good: fill in the XtransConnInfo structure.
+ */
+
+ if( ciptr->addr )
+ free(ciptr->addr);
+
+ if( (ciptr->addr=(char *)malloc(netbuf.len)) == NULL )
+ {
+ PRMSG(1, "TRANS(TLIGetAddr): Can't allocate space for the addr\n",
+ 0,0,0);
+ return -1;
+ }
+
+ ciptr->family=((struct sockaddr *) &sockname)->sa_family;
+ ciptr->addrlen=netbuf.len;
+ 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(TLIGetPeerAddr)(ciptr)
+
+XtransConnInfo ciptr;
+
+{
+ Xtransaddr sockname;
+ struct netbuf netbuf;
+
+ PRMSG(3,"TRANS(TLIGetPeerAddr)(%x)\n", ciptr, 0,0 );
+
+ netbuf.buf=(char *)&sockname;
+ netbuf.len=sizeof(sockname);
+ netbuf.maxlen=sizeof(sockname);
+
+ if( t_getname(ciptr->fd,&netbuf,REMOTENAME) < 0 )
+ {
+ PRMSG(1,"TRANS(TLIGetPeerAddr): t_getname(REMOTENAME) failed: %d\n",
+ errno, 0,0 );
+ return -1;
+ }
+
+ PRMSG(4,"TRANS(TLIGetPeerAddr): got family %d len %d\n",
+ ((struct sockaddr *) &sockname)->sa_family ,netbuf.len, 0 );
+
+ /*
+ * Everything looks good: fill in the XtransConnInfo structure.
+ */
+
+ if( ciptr->peeraddr )
+ free(ciptr->peeraddr);
+
+ if( (ciptr->peeraddr=(char *)malloc(netbuf.len)) == NULL )
+ {
+ PRMSG(1,
+ "TRANS(TLIGetPeerAddr): Can't allocate space for the addr\n",
+ 0,0,0);
+ return -1;
+ }
+
+ ciptr->peeraddrlen=netbuf.len;
+ memcpy(ciptr->peeraddr,&sockname,ciptr->peeraddrlen);
+
+ return 0;
+}
+
+
+/*
+ * This function will establish a local name for the transport. This function
+ * do extra work for the local tli connection. It must create a sockaddr_un
+ * format address so that it will look like an AF_UNIX connection to the
+ * higher layer.
+ *
+ * This function will only be called by the OPENC?TSClient() functions since
+ * the local address is set up in the CreateListner() for the server ends.
+ */
+
+static int
+TRANS(TLITLIBindLocal)(fd,family,port)
+
+int fd;
+int family;
+char *port;
+
+{
+ struct sockaddr_un *sunaddr=NULL;
+ struct t_bind *req=NULL;
+
+ PRMSG(2, "TRANS(TLITLIBindLocal)(%d,%d,%s)\n", fd, family, port);
+
+ if( family == AF_UNIX )
+ {
+ if( (req=(struct t_bind *)t_alloc(fd,T_BIND,T_OPT|T_UDATA)) == NULL )
+ {
+ PRMSG(1,
+ "TRANS(TLITLIBindLocal)() failed to allocate a t_bind\n",
+ 0,0,0 );
+ return -1;
+ }
+
+ if( (sunaddr=(struct sockaddr_un *)
+ malloc(sizeof(struct sockaddr_un))) == NULL )
+ {
+ PRMSG(1,
+ "TRANS(TLITLIBindLocal): failed to allocate a sockaddr_un\n",
+ 0,0,0 );
+ t_free((char *)req,T_BIND);
+ return -1;
+ }
+
+ sunaddr->sun_family=AF_UNIX;
+
+#ifdef nuke
+ if( *port == '/' ) { /* A full pathname */
+ (void) strcpy(sunaddr->sun_path, port);
+ } else {
+ (void) sprintf(sunaddr->sun_path,"%s%s", TLINODENAME, port );
+ }
+#endif /*NUKE*/
+
+ (void) sprintf(sunaddr->sun_path,"%s%d",
+ TLINODENAME, getpid()^time(NULL) );
+
+ PRMSG(4, "TRANS(TLITLIBindLocal): binding to %s\n",
+ sunaddr->sun_path, 0,0);
+
+ req->addr.buf=(char *)sunaddr;
+ req->addr.len=sizeof(*sunaddr);
+ req->addr.maxlen=sizeof(*sunaddr);
+ }
+
+ if( t_bind(fd, req, NULL) < 0 )
+ {
+ PRMSG(1,
+ "TRANS(TLIBindLocal): Unable to bind TLI device to %s\n",
+ port, 0,0 );
+ if (sunaddr)
+ free((char *) sunaddr);
+ if (req)
+ t_free((char *)req,T_BIND);
+ return -1;
+ }
+ return 0;
+}
+
+static XtransConnInfo
+TRANS(TLIOpen)(device)
+
+char *device;
+
+{
+ XtransConnInfo ciptr;
+
+ PRMSG(3,"TRANS(TLIOpen)(%s)\n", device, 0,0 );
+
+ if( (ciptr=(XtransConnInfo)calloc(1,sizeof(struct _XtransConnInfo))) == NULL )
+ {
+ PRMSG(1, "TRANS(TLIOpen): calloc failed\n", 0,0,0 );
+ return NULL;
+ }
+
+ if( (ciptr->fd=t_open( device, O_RDWR, NULL )) < 0 )
+ {
+ PRMSG(1, "TRANS(TLIOpen): t_open failed for %s\n", device, 0,0 );
+ free(ciptr);
+ return NULL;
+ }
+
+ return ciptr;
+}
+
+
+#ifdef TRANS_REOPEN
+
+static XtransConnInfo
+TRANS(TLIReopen)(device, fd, port)
+
+char *device;
+int fd;
+char *port;
+
+{
+ XtransConnInfo ciptr;
+
+ PRMSG(3,"TRANS(TLIReopen)(%s,%d, %s)\n", device, fd, port );
+
+ if (t_sync (fd) < 0)
+ {
+ PRMSG(1, "TRANS(TLIReopen): t_sync failed\n", 0,0,0 );
+ return NULL;
+ }
+
+ if( (ciptr=(XtransConnInfo)calloc(1,sizeof(struct _XtransConnInfo))) == NULL )
+ {
+ PRMSG(1, "TRANS(TLIReopen): calloc failed\n", 0,0,0 );
+ return NULL;
+ }
+
+ ciptr->fd = fd;
+
+ return ciptr;
+}
+
+#endif /* TRANS_REOPEN */
+
+
+static int
+TRANS(TLIAddrToNetbuf)(tlifamily, host, port, netbufp)
+
+int tlifamily;
+char *host;
+char *port;
+struct netbuf *netbufp;
+
+{
+ struct netconfig *netconfigp;
+ struct nd_hostserv nd_hostserv;
+ struct nd_addrlist *nd_addrlistp = NULL;
+ void *handlep;
+ long lport;
+
+ PRMSG(3,"TRANS(TLIAddrToNetbuf)(%d,%s,%s)\n", tlifamily, host, port );
+
+ if( (handlep=setnetconfig()) == NULL )
+ return -1;
+
+ lport = strtol (port, (char**)NULL, 10);
+ if (lport < 1024 || lport > USHRT_MAX)
+ return -1;
+
+ nd_hostserv.h_host = host;
+ if( port && *port ) {
+ nd_hostserv.h_serv = port;
+ } else {
+ nd_hostserv.h_serv = NULL;
+ }
+
+ while( (netconfigp=getnetconfig(handlep)) != NULL )
+ {
+ if( strcmp(netconfigp->nc_protofmly,
+ TLItrans2devtab[tlifamily].protofamily) != 0 )
+ continue;
+ PRMSG(5,"Trying to resolve %s.%s for %s\n",
+ host, port, TLItrans2devtab[tlifamily].protofamily );
+ if( netdir_getbyname(netconfigp,&nd_hostserv, &nd_addrlistp) == 0 )
+ {
+ /* we have at least one address to use */
+
+ PRMSG(5, "found address for %s.%s\n", host, port, 0 );
+ PRMSG(5, "%s\n",taddr2uaddr(netconfigp,nd_addrlistp->n_addrs),
+ 0,0 );
+
+ memcpy(netbufp->buf,nd_addrlistp->n_addrs->buf,
+ nd_addrlistp->n_addrs->len);
+ netbufp->len=nd_addrlistp->n_addrs->len;
+ endnetconfig(handlep);
+ return 0;
+ }
+ }
+ endnetconfig(handlep);
+
+ return -1;
+}
+
+/*
+ * These functions are the interface supplied in the Xtransport structure
+ */
+
+#ifdef TRANS_CLIENT
+
+static XtransConnInfo
+TRANS(TLIOpenCOTSClient)(thistrans, protocol, host, port)
+
+Xtransport *thistrans;
+char *protocol;
+char *host;
+char *port;
+
+{
+ XtransConnInfo ciptr;
+ int i;
+
+ PRMSG(2,"TRANS(TLIOpenCOTSClient)(%s,%s,%s)\n", protocol, host, port );
+
+ if( (i=TRANS(TLISelectFamily)(thistrans->TransName)) < 0 )
+ {
+ PRMSG(1,"TRANS(TLIOpenCOTSClient): Unable to determine device for %s\n",
+ thistrans->TransName, 0,0 );
+ return NULL;
+ }
+
+ if( (ciptr=TRANS(TLIOpen)(TLItrans2devtab[i].devcotsname)) == NULL )
+ {
+ PRMSG(1,"TRANS(TLIOpenCOTSClient): Unable to open device for %s\n",
+ thistrans->TransName, 0,0 );
+ return NULL;
+ }
+
+ if( TRANS(TLITLIBindLocal)(ciptr->fd,TLItrans2devtab[i].family,port) < 0 )
+ {
+ PRMSG(1,
+ "TRANS(TLIOpenCOTSClient): TRANS(TLITLIBindLocal)() failed: %d\n",
+ errno, 0,0 );
+ t_close(ciptr->fd);
+ free(ciptr);
+ return NULL;
+ }
+
+ if( TRANS(TLIGetAddr)(ciptr) < 0 )
+ {
+ PRMSG(1,
+ "TRANS(TLIOpenCOTSClient): TRANS(TLIGetAddr)() failed: %d\n",
+ errno, 0,0 );
+ t_close(ciptr->fd);
+ free(ciptr);
+ return NULL;
+ }
+
+ /* Save the TLIFamily for later use in TLIAddrToNetbuf() lookups */
+ ciptr->index = i;
+
+ return ciptr;
+}
+
+#endif /* TRANS_CLIENT */
+
+
+#ifdef TRANS_SERVER
+
+static XtransConnInfo
+TRANS(TLIOpenCOTSServer)(thistrans, protocol, host, port)
+
+Xtransport *thistrans;
+char *protocol;
+char *host;
+char *port;
+
+{
+ XtransConnInfo ciptr;
+ int i;
+
+ PRMSG(2,"TRANS(TLIOpenCOTSServer)(%s,%s,%s)\n", protocol, host, port );
+
+ if( (i=TRANS(TLISelectFamily)(thistrans->TransName)) < 0 )
+ {
+ PRMSG(1,
+ "TRANS(TLIOpenCOTSServer): Unable to determine device for %s\n",
+ thistrans->TransName, 0,0 );
+ return NULL;
+ }
+
+ if( (ciptr=TRANS(TLIOpen)(TLItrans2devtab[i].devcotsname)) == NULL )
+ {
+ PRMSG(1,
+ "TRANS(TLIOpenCOTSServer): Unable to open device for %s\n",
+ thistrans->TransName, 0,0 );
+ return NULL;
+ }
+
+ /* Set the family type */
+
+ ciptr->family = TLItrans2devtab[i].family;
+
+
+ /* Save the TLIFamily for later use in TLIAddrToNetbuf() lookups */
+
+ ciptr->index = i;
+
+ return ciptr;
+}
+
+#endif /* TRANS_SERVER */
+
+
+#ifdef TRANS_CLIENT
+
+static XtransConnInfo
+TRANS(TLIOpenCLTSClient)(thistrans, protocol, host, port)
+
+Xtransport *thistrans;
+char *protocol;
+char *host;
+char *port;
+
+{
+ XtransConnInfo ciptr;
+ int i;
+
+ PRMSG(2,"TRANS(TLIOpenCLTSClient)(%s,%s,%s)\n", protocol, host, port );
+
+ if( (i=TRANS(TLISelectFamily)(thistrans->TransName)) < 0 )
+ {
+ PRMSG(1,
+ "TRANS(TLIOpenCLTSClient): Unable to determine device for %s\n",
+ thistrans->TransName, 0,0 );
+ return NULL;
+ }
+
+ if( (ciptr=TRANS(TLIOpen)(TLItrans2devtab[i].devcltsname)) == NULL )
+ {
+ PRMSG(1,
+ "TRANS(TLIOpenCLTSClient): Unable to open device for %s\n",
+ thistrans->TransName, 0,0 );
+ return NULL;
+ }
+
+ if( TRANS(TLITLIBindLocal)(ciptr->fd,TLItrans2devtab[i].family,port) < 0 )
+ {
+ PRMSG(1,
+ "TRANS(TLIOpenCLTSClient): TRANS(TLITLIBindLocal)() failed: %d\n",
+ errno, 0,0 );
+ t_close(ciptr->fd);
+ free(ciptr);
+ return NULL;
+ }
+
+ if( TRANS(TLIGetAddr)(ciptr) < 0 )
+ {
+ PRMSG(1,
+ "TRANS(TLIOpenCLTSClient): TRANS(TLIGetPeerAddr)() failed: %d\n",
+ errno, 0,0 );
+ t_close(ciptr->fd);
+ free(ciptr);
+ return NULL;
+ }
+
+ return ciptr;
+}
+
+#endif /* TRANS_CLIENT */
+
+
+#ifdef TRANS_SERVER
+
+static XtransConnInfo
+TRANS(TLIOpenCLTSServer)(thistrans, protocol, host, port)
+
+Xtransport *thistrans;
+char *protocol;
+char *host;
+char *port;
+
+{
+ XtransConnInfo ciptr;
+ int i;
+
+ PRMSG(2,"TRANS(TLIOpenCLTSServer)(%s,%s,%s)\n", protocol, host, port );
+
+ if( (i=TRANS(TLISelectFamily)(thistrans->TransName)) < 0 )
+ {
+ PRMSG(1,
+ "TRANS(TLIOpenCLTSServer): Unable to determine device for %s\n",
+ thistrans->TransName, 0,0 );
+ return NULL;
+ }
+
+ if( (ciptr=TRANS(TLIOpen)(TLItrans2devtab[i].devcltsname)) == NULL )
+ {
+ PRMSG(1,
+ "TRANS(TLIOpenCLTSServer): Unable to open device for %s\n",
+ thistrans->TransName, 0,0 );
+ return NULL;
+ }
+
+ return ciptr;
+}
+
+#endif /* TRANS_SERVER */
+
+
+#ifdef TRANS_REOPEN
+
+static XtransConnInfo
+TRANS(TLIReopenCOTSServer)(thistrans, fd, port)
+
+Xtransport *thistrans;
+int fd;
+char *port;
+
+{
+ XtransConnInfo ciptr;
+ int i;
+
+ PRMSG(2,"TRANS(TLIReopenCOTSServer)(%d, %s)\n", fd, port, 0 );
+
+ if( (i=TRANS(TLISelectFamily)(thistrans->TransName)) < 0 )
+ {
+ PRMSG(1,
+ "TRANS(TLIReopenCOTSServer): Unable to determine device for %s\n",
+ thistrans->TransName, 0,0 );
+ return NULL;
+ }
+
+ if( (ciptr=TRANS(TLIReopen)(
+ TLItrans2devtab[i].devcotsname, fd, port)) == NULL )
+ {
+ PRMSG(1,
+ "TRANS(TLIReopenCOTSServer): Unable to open device for %s\n",
+ thistrans->TransName, 0,0 );
+ return NULL;
+ }
+
+ /* Save the TLIFamily for later use in TLIAddrToNetbuf() lookups */
+
+ ciptr->index = i;
+
+ return ciptr;
+}
+
+
+static XtransConnInfo
+TRANS(TLIReopenCLTSServer)(thistrans, fd, port)
+
+Xtransport *thistrans;
+int fd;
+char *port;
+
+{
+ XtransConnInfo ciptr;
+ int i;
+
+ PRMSG(2,"TRANS(TLIReopenCLTSServer)(%d, %s)\n", fd, port, 0 );
+
+ if( (i=TRANS(TLISelectFamily)(thistrans->TransName)) < 0 )
+ {
+ PRMSG(1,
+ "TRANS(TLIReopenCLTSServer): Unable to determine device for %s\n",
+ thistrans->TransName, 0,0 );
+ return NULL;
+ }
+
+ if( (ciptr=TRANS(TLIReopen)(
+ TLItrans2devtab[i].devcltsname, fd, port)) == NULL )
+ {
+ PRMSG(1,
+ "TRANS(TLIReopenCLTSServer): Unable to open device for %s\n",
+ thistrans->TransName, 0,0 );
+ return NULL;
+ }
+
+ ciptr->index = i;
+
+ return ciptr;
+}
+
+#endif /* TRANS_REOPEN */
+
+
+static
+TRANS(TLISetOption)(ciptr, option, arg)
+
+XtransConnInfo ciptr;
+int option;
+int arg;
+
+{
+ PRMSG(2,"TRANS(TLISetOption)(%d,%d,%d)\n", ciptr->fd, option, arg );
+
+ return -1;
+}
+
+
+#ifdef TRANS_SERVER
+
+static
+TRANS(TLICreateListener)(ciptr, req)
+
+XtransConnInfo ciptr;
+struct t_bind *req;
+
+{
+ struct t_bind *ret;
+
+ PRMSG(2,"TRANS(TLICreateListener)(%x->%d,%x)\n", ciptr, ciptr->fd, req );
+
+ if( (ret=(struct t_bind *)t_alloc(ciptr->fd,T_BIND,T_ALL)) == NULL )
+ {
+ PRMSG(1, "TRANS(TLICreateListener): failed to allocate a t_bind\n",
+ 0,0,0 );
+ t_free((char *)req,T_BIND);
+ return TRANS_CREATE_LISTENER_FAILED;
+ }
+
+ if( t_bind(ciptr->fd, req, ret) < 0 )
+ {
+ PRMSG(1, "TRANS(TLICreateListener): t_bind failed\n", 0,0,0 );
+ t_free((char *)req,T_BIND);
+ t_free((char *)ret,T_BIND);
+ return TRANS_CREATE_LISTENER_FAILED;
+ }
+
+ if( memcmp(req->addr.buf,ret->addr.buf,req->addr.len) != 0 )
+ {
+ PRMSG(1, "TRANS(TLICreateListener): unable to bind to %x\n",
+ req, 0,0 );
+ t_free((char *)req,T_BIND);
+ t_free((char *)ret,T_BIND);
+ return TRANS_ADDR_IN_USE;
+ }
+
+ /*
+ * Everything looks good: fill in the XtransConnInfo structure.
+ */
+
+ if( (ciptr->addr=(char *)malloc(ret->addr.len)) == NULL )
+ {
+ PRMSG(1,
+ "TRANS(TLICreateListener): Unable to allocate space for the address\n",
+ 0,0,0 );
+ t_free((char *)req,T_BIND);
+ t_free((char *)ret, T_BIND);
+ return TRANS_CREATE_LISTENER_FAILED;
+ }
+
+ ciptr->addrlen=ret->addr.len;
+ memcpy(ciptr->addr,ret->addr.buf,ret->addr.len);
+
+ t_free((char *)req,T_BIND);
+ t_free((char *)ret, T_BIND);
+
+ return 0;
+}
+
+
+static
+TRANS(TLIINETCreateListener)(ciptr, port)
+
+XtransConnInfo ciptr;
+char *port;
+
+{
+ char portbuf[PORTBUFSIZE];
+ struct t_bind *req;
+ struct sockaddr_in *sinaddr;
+ long tmpport;
+
+ PRMSG(2,"TRANS(TLIINETCreateListener)(%x->%d,%s)\n", ciptr,
+ ciptr->fd, port ? port : "NULL" );
+
+#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))
+ {
+ tmpport = X_TCP_PORT + strtol (port, (char**)NULL, 10);
+ sprintf(portbuf,"%u", tmpport);
+ port = portbuf;
+ }
+#endif
+
+ if( (req=(struct t_bind *)t_alloc(ciptr->fd,T_BIND,T_ALL)) == NULL )
+ {
+ PRMSG(1,
+ "TRANS(TLIINETCreateListener): failed to allocate a t_bind\n",
+ 0,0,0 );
+ return TRANS_CREATE_LISTENER_FAILED;
+ }
+
+ if( port && *port ) {
+ if(TRANS(TLIAddrToNetbuf)(ciptr->index,HOST_SELF,port,&(req->addr)) < 0)
+ {
+ PRMSG(1,
+ "TRANS(TLIINETCreateListener): can't resolve name:HOST_SELF.%s\n",
+ port, 0,0 );
+ t_free((char *)req,T_BIND);
+ return TRANS_CREATE_LISTENER_FAILED;
+ }
+ } else {
+ sinaddr=(struct sockaddr_in *) req->addr.buf;
+ sinaddr->sin_family=AF_INET;
+ sinaddr->sin_port=htons(0);
+ sinaddr->sin_addr.s_addr=0;
+ }
+
+ /* Set the qlen */
+
+ req->qlen=1;
+
+ return TRANS(TLICreateListener)(ciptr, req);
+}
+
+
+static
+TRANS(TLITLICreateListener)(ciptr, port)
+
+XtransConnInfo ciptr;
+char *port;
+
+{
+ struct t_bind *req;
+ struct sockaddr_un *sunaddr;
+ int ret_value;
+
+ PRMSG(2,"TRANS(TLITLICreateListener)(%x->%d,%s)\n", ciptr, ciptr->fd,
+ port ? port : "NULL");
+
+ if( (req=(struct t_bind *)t_alloc(ciptr->fd,T_BIND,T_OPT|T_UDATA)) == NULL )
+ {
+ PRMSG(1,
+ "TRANS(TLITLICreateListener): failed to allocate a t_bind\n",
+ 0,0,0 );
+ return TRANS_CREATE_LISTENER_FAILED;
+ }
+
+ if( (sunaddr=(struct sockaddr_un *)
+ malloc(sizeof(struct sockaddr_un))) == NULL )
+ {
+ PRMSG(1,
+ "TRANS(TLITLICreateListener): failed to allocate a sockaddr_un\n",
+ 0,0,0 );
+ t_free((char *)req,T_BIND);
+ return TRANS_CREATE_LISTENER_FAILED;
+ }
+
+ sunaddr->sun_family=AF_UNIX;
+ if( port && *port ) {
+ if( *port == '/' ) { /* A full pathname */
+ (void) strcpy(sunaddr->sun_path, port);
+ } else {
+ (void) sprintf(sunaddr->sun_path,"%s%s", TLINODENAME, port );
+ }
+ } else {
+ (void) sprintf(sunaddr->sun_path,"%s%d", TLINODENAME, getpid());
+ }
+
+ req->addr.buf=(char *)sunaddr;
+ req->addr.len=sizeof(*sunaddr);
+ req->addr.maxlen=sizeof(*sunaddr);
+
+ /* Set the qlen */
+
+ req->qlen=1;
+
+ ret_value = TRANS(TLICreateListener)(ciptr, req);
+
+ free((char *) sunaddr);
+
+ return ret_value;
+}
+
+
+static XtransConnInfo
+TRANS(TLIAccept)(ciptr, status)
+
+XtransConnInfo ciptr;
+int *status;
+
+{
+ struct t_call *call;
+ XtransConnInfo newciptr;
+ int i;
+
+ PRMSG(2,"TRANS(TLIAccept)(%x->%d)\n", ciptr, ciptr->fd, 0 );
+
+ if( (call=(struct t_call *)t_alloc(ciptr->fd,T_CALL,T_ALL)) == NULL )
+ {
+ PRMSG(1, "TRANS(TLIAccept)() failed to allocate a t_call\n", 0,0,0 );
+ *status = TRANS_ACCEPT_BAD_MALLOC;
+ return NULL;
+ }
+
+ if( t_listen(ciptr->fd,call) < 0 )
+ {
+ extern char *t_errlist[];
+ extern int t_errno;
+ PRMSG(1, "TRANS(TLIAccept)() t_listen() failed\n", 0,0,0 );
+ PRMSG(1, "%s\n", t_errlist[t_errno], 0,0 );
+ t_free((char *)call,T_CALL);
+ *status = TRANS_ACCEPT_MISC_ERROR;
+ return NULL;
+ }
+
+ /*
+ * Now we need to set up the new endpoint for the incoming connection.
+ */
+
+ i=ciptr->index; /* Makes the next line more readable */
+
+ if( (newciptr=TRANS(TLIOpen)(TLItrans2devtab[i].devcotsname)) == NULL )
+ {
+ PRMSG(1, "TRANS(TLIAccept)() failed to open a new endpoint\n", 0,0,0 );
+ t_free((char *)call,T_CALL);
+ *status = TRANS_ACCEPT_MISC_ERROR;
+ return NULL;
+ }
+
+ if( TRANS(TLITLIBindLocal)(newciptr->fd,TLItrans2devtab[i].family,"") < 0 )
+ {
+ PRMSG(1,
+ "TRANS(TLIAccept): TRANS(TLITLIBindLocal)() failed: %d\n",
+ errno, 0,0 );
+ t_free((char *)call,T_CALL);
+ t_close(newciptr->fd);
+ free(newciptr);
+ *status = TRANS_ACCEPT_MISC_ERROR;
+ return NULL;
+ }
+
+
+ if( t_accept(ciptr->fd,newciptr->fd,call) < 0 )
+ {
+ extern char *t_errlist[];
+ extern int t_errno;
+ PRMSG(1, "TRANS(TLIAccept)() t_accept() failed\n", 0,0,0 );
+ PRMSG(1, "%s\n", t_errlist[t_errno], 0,0 );
+ t_free((char *)call,T_CALL);
+ t_close(newciptr->fd);
+ free(newciptr);
+ *status = TRANS_ACCEPT_FAILED;
+ return NULL;
+ }
+
+ t_free((char *)call,T_CALL);
+
+ if( TRANS(TLIGetAddr)(newciptr) < 0 )
+ {
+ PRMSG(1,
+ "TRANS(TLIAccept): TRANS(TLIGetAddr)() failed: %d\n",
+ errno, 0,0 );
+ t_close(newciptr->fd);
+ free(newciptr);
+ *status = TRANS_ACCEPT_MISC_ERROR;
+ return NULL;
+ }
+
+ if( TRANS(TLIGetPeerAddr)(newciptr) < 0 )
+ {
+ PRMSG(1,
+ "TRANS(TLIAccept): TRANS(TLIGetPeerAddr)() failed: %d\n",
+ errno, 0,0 );
+ t_close(newciptr->fd);
+ free(newciptr->addr);
+ free(newciptr);
+ *status = TRANS_ACCEPT_MISC_ERROR;
+ return NULL;
+ }
+
+ if( ioctl(newciptr->fd, I_POP,"timod") < 0 )
+ {
+ PRMSG(1, "TRANS(TLIAccept)() ioctl(I_POP, \"timod\") failed %d\n",
+ errno,0,0 );
+ t_close(newciptr->fd);
+ free(newciptr->addr);
+ free(newciptr);
+ *status = TRANS_ACCEPT_MISC_ERROR;
+ return NULL;
+ }
+
+ if( ioctl(newciptr->fd, I_PUSH,"tirdwr") < 0 )
+ {
+ PRMSG(1, "TRANS(TLIAccept)() ioctl(I_PUSH,\"tirdwr\") failed %d\n",
+ errno,0,0 );
+ t_close(newciptr->fd);
+ free(newciptr->addr);
+ free(newciptr);
+ *status = TRANS_ACCEPT_MISC_ERROR;
+ return NULL;
+ }
+
+ *status = 0;
+
+ return newciptr;
+}
+
+#endif /* TRANS_SERVER */
+
+
+#ifdef TRANS_CLIENT
+
+static
+TRANS(TLIConnect)(ciptr, sndcall )
+
+XtransConnInfo ciptr;
+struct t_call *sndcall;
+
+{
+ PRMSG(2, "TRANS(TLIConnect)(%x->%d,%x)\n", ciptr, ciptr->fd, sndcall);
+
+ if( t_connect(ciptr->fd,sndcall,NULL) < 0 )
+ {
+ extern char *t_errlist[];
+ extern int t_errno;
+ PRMSG(1, "TRANS(TLIConnect)() t_connect() failed\n", 0,0,0 );
+ PRMSG(1, "%s\n", t_errlist[t_errno], 0,0 );
+ t_free((char *)sndcall,T_CALL);
+ if (t_errno == TLOOK && t_look(ciptr->fd) == T_DISCONNECT)
+ {
+ t_rcvdis(ciptr->fd,NULL);
+ return TRANS_TRY_CONNECT_AGAIN;
+ }
+ else
+ return TRANS_CONNECT_FAILED;
+ }
+
+ t_free((char *)sndcall,T_CALL);
+
+ /*
+ * Sync up the address fields of ciptr.
+ */
+
+ if( TRANS(TLIGetAddr)(ciptr) < 0 )
+ {
+ PRMSG(1,
+ "TRANS(TLIConnect): TRANS(TLIGetAddr)() failed: %d\n",
+ errno, 0,0 );
+ return TRANS_CONNECT_FAILED;
+ }
+
+ if( TRANS(TLIGetPeerAddr)(ciptr) < 0 )
+ {
+ PRMSG(1,
+ "TRANS(TLIConnect): TRANS(TLIGetPeerAddr)() failed: %d\n",
+ errno, 0,0 );
+ return TRANS_CONNECT_FAILED;
+ }
+
+ if( ioctl(ciptr->fd, I_POP,"timod") < 0 )
+ {
+ PRMSG(1, "TRANS(TLIConnect)() ioctl(I_POP,\"timod\") failed %d\n",
+ errno,0,0 );
+ return TRANS_CONNECT_FAILED;
+ }
+
+ if( ioctl(ciptr->fd, I_PUSH,"tirdwr") < 0 )
+ {
+ PRMSG(1, "TRANS(TLIConnect)() ioctl(I_PUSH,\"tirdwr\") failed %d\n",
+ errno,0,0 );
+ return TRANS_CONNECT_FAILED;
+ }
+
+ return 0;
+}
+
+
+static
+TRANS(TLIINETConnect)(ciptr, host, port)
+
+XtransConnInfo ciptr;
+char *host;
+char *port;
+
+{
+ char portbuf[PORTBUFSIZE];
+ struct t_call *sndcall;
+ long tmpport;
+
+ PRMSG(2, "TRANS(TLIINETConnect)(%s,%s)\n", host, port, 0);
+
+#ifdef X11_t
+ /*
+ * X has a well known port, that is transport dependant. 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))
+ {
+ tmpport = X_TCP_PORT + strtol (port, (char**)NULL, 10);
+ sprintf(portbuf,"%u", tmpport );
+ port = portbuf;
+ }
+#endif
+
+ if( (sndcall=(struct t_call *)t_alloc(ciptr->fd,T_CALL,T_ALL)) == NULL )
+ {
+ PRMSG(1, "TRANS(TLIINETConnect)() failed to allocate a t_call\n", 0,0,0 );
+ return TRANS_CONNECT_FAILED;
+ }
+
+ if( TRANS(TLIAddrToNetbuf)(ciptr->index, host, port, &(sndcall->addr) ) < 0 )
+ {
+ PRMSG(1, "TRANS(TLIINETConnect)() unable to resolve name:%s.%s\n",
+ host, port, 0 );
+ t_free((char *)sndcall,T_CALL);
+ return TRANS_CONNECT_FAILED;
+ }
+
+ return TRANS(TLIConnect)(ciptr, sndcall );
+}
+
+
+static
+TRANS(TLITLIConnect)(ciptr, host, port)
+
+XtransConnInfo ciptr;
+char *host;
+char *port;
+
+{
+ struct t_call *sndcall;
+ struct sockaddr_un *sunaddr;
+ int ret_value;
+
+ PRMSG(2, "TRANS(TLITLIConnect)(%s,%s)\n", host, port, 0);
+
+ if( (sndcall=(struct t_call *)t_alloc(ciptr->fd,T_CALL,T_OPT|T_UDATA)) == NULL )
+ {
+ PRMSG(1, "TRANS(TLITLIConnect)() failed to allocate a t_call\n", 0,0,0 );
+ return TRANS_CONNECT_FAILED;
+ }
+
+ if( (sunaddr=(struct sockaddr_un *)
+ malloc(sizeof(struct sockaddr_un))) == NULL )
+ {
+ PRMSG(1,
+ "TRANS(TLITLIConnect): failed to allocate a sockaddr_un\n",
+ 0,0,0 );
+ t_free((char *)sndcall,T_CALL);
+ return TRANS_CONNECT_FAILED;
+ }
+
+ sunaddr->sun_family=AF_UNIX;
+ if( *port == '/' ||
+ strncmp (port, TLINODENAME, strlen (TLINODENAME)) == 0) {
+ /* Use the port as is */
+ (void) strcpy(sunaddr->sun_path, port);
+ } else {
+ (void) sprintf(sunaddr->sun_path,"%s%s", TLINODENAME, port );
+ }
+
+ sndcall->addr.buf=(char *)sunaddr;
+ sndcall->addr.len=sizeof(*sunaddr);
+ sndcall->addr.maxlen=sizeof(*sunaddr);
+
+ ret_value = TRANS(TLIConnect)(ciptr, sndcall );
+
+ free((char *) sunaddr);
+
+ return ret_value;
+}
+
+#endif /* TRANS_CLIENT */
+
+
+static
+TRANS(TLIBytesReadable)(ciptr, pend)
+
+XtransConnInfo ciptr;
+BytesReadable_t *pend;
+
+{
+ int ret;
+ struct pollfd filedes;
+
+ PRMSG(2, "TRANS(TLIByteReadable)(%x->%d,%x)\n", ciptr, ciptr->fd, pend );
+
+ /*
+ * This function should detect hangup conditions. Use poll to check
+ * if no data is present. On SVR4, the M_HANGUP message sits on the
+ * streams head, and ioctl(N_READ) keeps returning 0 because there is
+ * no data available. The hangup goes undetected, and the client hangs.
+ */
+
+ ret=ioctl(ciptr->fd, I_NREAD, (char *)pend);
+
+ if( ret != 0 )
+ return ret; /* Data present or error */
+
+
+ /* Zero data, or POLLHUP message */
+
+ filedes.fd=ciptr->fd;
+ filedes.events=POLLIN;
+
+ ret=poll(&filedes, 1, 0);
+
+ if( ret == 0 ) {
+ *pend=0;
+ return 0; /* Really, no data */
+ }
+
+ if( ret < 0 )
+ return -1; /* just pass back the error */
+
+ if( filedes.revents & (POLLHUP|POLLERR) ) /* check for hangup */
+ return -1;
+
+ /* Should only get here if data arrived after the first ioctl() */
+ return ioctl(ciptr->fd, I_NREAD, (char *)pend);
+}
+
+
+static
+TRANS(TLIRead)(ciptr, buf, size)
+
+XtransConnInfo ciptr;
+char *buf;
+int size;
+
+{
+ PRMSG(2, "TRANS(TLIRead)(%d,%x,%d)\n", ciptr->fd, buf, size );
+
+ return read(ciptr->fd,buf,size);
+}
+
+
+static
+TRANS(TLIWrite)(ciptr, buf, size)
+
+XtransConnInfo ciptr;
+char *buf;
+int size;
+
+{
+ PRMSG(2, "TRANS(TLIWrite)(%d,%x,%d)\n", ciptr->fd, buf, size );
+
+ return write(ciptr->fd,buf,size);
+}
+
+
+static
+TRANS(TLIReadv)(ciptr, buf, size)
+
+XtransConnInfo ciptr;
+struct iovec *buf;
+int size;
+
+{
+ PRMSG(2, "TRANS(TLIReadv)(%d,%x,%d)\n", ciptr->fd, buf, size );
+
+ return READV(ciptr,buf,size);
+}
+
+
+static
+TRANS(TLIWritev)(ciptr, buf, size)
+
+XtransConnInfo ciptr;
+struct iovec *buf;
+int size;
+
+{
+ PRMSG(2, "TRANS(TLIWritev)(%d,%x,%d)\n", ciptr->fd, buf, size );
+
+ return WRITEV(ciptr,buf,size);
+}
+
+
+static
+TRANS(TLIDisconnect)(ciptr)
+
+XtransConnInfo ciptr;
+
+{
+ PRMSG(2, "TRANS(TLIDisconnect)(%x->%d)\n", ciptr, ciptr->fd, 0 );
+
+ /*
+ * Restore the TLI modules so that the connection can be properly shutdown.
+ * This avoids the situation where a connection goes into the TIME_WAIT
+ * state, and the address remains unavailable for a while.
+ */
+ ioctl(ciptr->fd, I_POP,"tirdwr");
+ ioctl(ciptr->fd, I_PUSH,"timod");
+
+ t_snddis(ciptr->fd,NULL);
+
+ return 0;
+}
+
+
+static
+TRANS(TLIClose)(ciptr)
+
+XtransConnInfo ciptr;
+
+{
+ PRMSG(2, "TRANS(TLIClose)(%x->%d)\n", ciptr, ciptr->fd, 0 );
+
+ t_unbind(ciptr->fd);
+
+ return (t_close(ciptr->fd));
+}
+
+
+static
+TRANS(TLICloseForCloning)(ciptr)
+
+XtransConnInfo ciptr;
+
+{
+ /*
+ * Don't unbind.
+ */
+
+ PRMSG(2, "TRANS(TLICloseForCloning)(%x->%d)\n", ciptr, ciptr->fd, 0 );
+
+ return (t_close(ciptr->fd));
+}
+
+
+Xtransport TRANS(TLITCPFuncs) = {
+ /* TLI Interface */
+ "tcp",
+ 0,
+#ifdef TRANS_CLIENT
+ TRANS(TLIOpenCOTSClient),
+#endif /* TRANS_CLIENT */
+#ifdef TRANS_SERVER
+ TRANS(TLIOpenCOTSServer),
+#endif /* TRANS_SERVER */
+#ifdef TRANS_CLIENT
+ TRANS(TLIOpenCLTSClient),
+#endif /* TRANS_CLIENT */
+#ifdef TRANS_SERVER
+ TRANS(TLIOpenCLTSServer),
+#endif /* TRANS_SERVER */
+#ifdef TRANS_REOPEN
+ TRANS(TLIReopenCOTSServer),
+ TRANS(TLIReopenCLTSServer),
+#endif
+ TRANS(TLISetOption),
+#ifdef TRANS_SERVER
+ TRANS(TLIINETCreateListener),
+ NULL, /* ResetListener */
+ TRANS(TLIAccept),
+#endif /* TRANS_SERVER */
+#ifdef TRANS_CLIENT
+ TRANS(TLIINETConnect),
+#endif /* TRANS_CLIENT */
+ TRANS(TLIBytesReadable),
+ TRANS(TLIRead),
+ TRANS(TLIWrite),
+ TRANS(TLIReadv),
+ TRANS(TLIWritev),
+ TRANS(TLIDisconnect),
+ TRANS(TLIClose),
+ TRANS(TLICloseForCloning),
+};
+
+Xtransport TRANS(TLIINETFuncs) = {
+ /* TLI Interface */
+ "inet",
+ TRANS_ALIAS,
+#ifdef TRANS_CLIENT
+ TRANS(TLIOpenCOTSClient),
+#endif /* TRANS_CLIENT */
+#ifdef TRANS_SERVER
+ TRANS(TLIOpenCOTSServer),
+#endif /* TRANS_SERVER */
+#ifdef TRANS_CLIENT
+ TRANS(TLIOpenCLTSClient),
+#endif /* TRANS_CLIENT */
+#ifdef TRANS_SERVER
+ TRANS(TLIOpenCLTSServer),
+#endif /* TRANS_SERVER */
+#ifdef TRANS_REOPEN
+ TRANS(TLIReopenCOTSServer),
+ TRANS(TLIReopenCLTSServer),
+#endif
+ TRANS(TLISetOption),
+#ifdef TRANS_SERVER
+ TRANS(TLIINETCreateListener),
+ NULL, /* ResetListener */
+ TRANS(TLIAccept),
+#endif /* TRANS_SERVER */
+#ifdef TRANS_CLIENT
+ TRANS(TLIINETConnect),
+#endif /* TRANS_CLIENT */
+ TRANS(TLIBytesReadable),
+ TRANS(TLIRead),
+ TRANS(TLIWrite),
+ TRANS(TLIReadv),
+ TRANS(TLIWritev),
+ TRANS(TLIDisconnect),
+ TRANS(TLIClose),
+ TRANS(TLICloseForCloning),
+};
+
+Xtransport TRANS(TLITLIFuncs) = {
+ /* TLI Interface */
+ "tli",
+ 0,
+#ifdef TRANS_CLIENT
+ TRANS(TLIOpenCOTSClient),
+#endif /* TRANS_CLIENT */
+#ifdef TRANS_SERVER
+ TRANS(TLIOpenCOTSServer),
+#endif /* TRANS_SERVER */
+#ifdef TRANS_CLIENT
+ TRANS(TLIOpenCLTSClient),
+#endif /* TRANS_CLIENT */
+#ifdef TRANS_SERVER
+ TRANS(TLIOpenCLTSServer),
+#endif /* TRANS_SERVER */
+#ifdef TRANS_REOPEN
+ TRANS(TLIReopenCOTSServer),
+ TRANS(TLIReopenCLTSServer),
+#endif
+ TRANS(TLISetOption),
+#ifdef TRANS_SERVER
+ TRANS(TLITLICreateListener),
+ NULL, /* ResetListener */
+ TRANS(TLIAccept),
+#endif /* TRANS_SERVER */
+#ifdef TRANS_CLIENT
+ TRANS(TLITLIConnect),
+#endif /* TRANS_CLIENT */
+ TRANS(TLIBytesReadable),
+ TRANS(TLIRead),
+ TRANS(TLIWrite),
+ TRANS(TLIReadv),
+ TRANS(TLIWritev),
+ TRANS(TLIDisconnect),
+ TRANS(TLIClose),
+ TRANS(TLICloseForCloning),
+};
diff --git a/Xtransutil.c b/Xtransutil.c
new file mode 100644
index 0000000..e2809b3
--- /dev/null
+++ b/Xtransutil.c
@@ -0,0 +1,462 @@
+/* $Xorg: Xtransutil.c,v 1.4 2001/02/09 02:04:07 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.
+
+*/
+
+/* 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 makes no representations about the
+ * suitability of this software for any purpose. It is provided "as is"
+ * without express or implied warranty.
+ *
+ * NCRS DISCLAIM 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.
+ */
+
+/*
+ * These are some utility functions created for convenience or to provide
+ * an interface that is similar to an existing interface. These are built
+ * only using the Transport Independant API, and have no knowledge of
+ * the internal implementation.
+ */
+
+#ifdef XTHREADS
+#include <X11/Xthreads.h>
+#endif
+
+#ifdef X11_t
+
+/*
+ * These values come from X.h and Xauth.h, and MUST match them. Some
+ * of these values are also defined by the ChangeHost protocol message.
+ */
+
+#define FamilyInternet 0
+#define FamilyDECnet 1
+#define FamilyChaos 2
+#define FamilyAmoeba 33
+#define FamilyLocalHost 252
+#define FamilyKrb5Principal 253
+#define FamilyNetname 254
+#define FamilyLocal 256
+#define FamilyWild 65535
+
+/*
+ * TRANS(ConvertAddress) converts a sockaddr based address to an
+ * X authorization based address. Some of this is defined as part of
+ * the ChangeHost protocol. The rest is just doen in a consistent manner.
+ */
+
+int
+TRANS(ConvertAddress)(familyp,addrlenp,addrp)
+int *familyp;
+int *addrlenp;
+Xtransaddr **addrp;
+{
+
+ PRMSG(2,"TRANS(ConvertAddress)(%d,%d,%x)\n",*familyp,*addrlenp,*addrp);
+
+ switch( *familyp )
+ {
+#if defined(TCPCONN) || defined(STREAMSCONN)
+ case AF_INET:
+ {
+ /*
+ * Check for the BSD hack localhost address 127.0.0.1.
+ * In this case, we are really FamilyLocal.
+ */
+
+ struct sockaddr_in saddr;
+#ifdef CRAY
+#ifdef OLDTCP
+ int len = sizeof(saddr.sin_addr);
+#else
+ int len = SIZEOF_in_addr;
+#endif /* OLDTCP */
+ char *cp = (char *) &saddr.sin_addr;
+#else /* else not CRAY */
+ int len = sizeof(saddr.sin_addr.s_addr);
+ char *cp = (char *) &saddr.sin_addr.s_addr;
+#endif /* CRAY */
+
+ memcpy (&saddr, *addrp, sizeof (struct sockaddr_in));
+
+ if ((len == 4) && (cp[0] == 127) && (cp[1] == 0) &&
+ (cp[2] == 0) && (cp[3] == 1))
+ {
+ *familyp=FamilyLocal;
+ }
+ else
+ {
+ *familyp=FamilyInternet;
+ *addrlenp=len;
+ memcpy(*addrp,&saddr.sin_addr,len);
+ }
+ break;
+ }
+#endif /* defined(TCPCONN) || defined(STREAMSCONN) */
+
+#if defined(DNETCONN)
+ case AF_DECnet:
+ {
+ struct sockaddr_dn saddr;
+
+ memcpy (&saddr, *addrp, sizeof (struct sockaddr_dn));
+
+ *familyp=FamilyDECnet;
+ *addrlenp=sizeof(struct dn_naddr);
+ memcpy(*addrp,&saddr.sdn_add,*addrlenp);
+
+ break;
+ }
+#endif /* defined(DNETCONN) */
+
+#if defined(UNIXCONN) || defined(LOCALCONN)
+ case AF_UNIX:
+ {
+ *familyp=FamilyLocal;
+ break;
+ }
+#endif /* defined(UNIXCONN) || defined(LOCALCONN) */
+
+#if defined(AMRPCCONN)
+ case AF_AMOEBA:
+ {
+ *familyp=FamilyAmoeba;
+ break;
+ }
+#endif
+#if defined(AMTCPCONN) && !(defined(TCPCONN) || defined(STREAMSCONN))
+ case AF_INET:
+ {
+ *familyp=FamilyInternet;
+ break;
+ }
+#endif
+
+ default:
+ PRMSG(1,"TRANS(ConvertFamily) Unknown family type %d\n",
+ *familyp, 0,0 );
+ return -1;
+ }
+
+
+ if (*familyp == FamilyLocal)
+ {
+ /*
+ * In the case of a local connection, we need to get the
+ * host name for authentication.
+ */
+
+ char hostnamebuf[256];
+ int len = TRANS(GetHostname) (hostnamebuf, sizeof hostnamebuf);
+
+ if (len > 0) {
+ if (*addrp && *addrlenp < (len + 1))
+ {
+ free ((char *) *addrp);
+ *addrp = NULL;
+ }
+ if (!*addrp)
+ *addrp = (Xtransaddr *) malloc (len + 1);
+ if (*addrp) {
+ strcpy ((char *) *addrp, hostnamebuf);
+ *addrlenp = len;
+ } else {
+ *addrlenp = 0;
+ }
+ }
+ else
+ {
+ if (*addrp)
+ free ((char *) *addrp);
+ *addrp = NULL;
+ *addrlenp = 0;
+ }
+ }
+
+ return 0;
+}
+
+#endif /* X11_t */
+
+#ifdef ICE_t
+
+#include <signal.h>
+
+char *
+TRANS(GetMyNetworkId) (ciptr)
+
+XtransConnInfo ciptr;
+
+{
+ int family = ciptr->family;
+ int addrlen = ciptr->addrlen;
+ char *addr = ciptr->addr;
+ char hostnamebuf[256];
+ char *networkId = NULL;
+ char *transName = ciptr->transptr->TransName;
+
+ if (gethostname (hostnamebuf, sizeof (hostnamebuf)) < 0)
+ {
+ return (NULL);
+ }
+
+ switch (family)
+ {
+#if defined(UNIXCONN) || defined(STREAMSCONN) || defined(LOCALCONN)
+ case AF_UNIX:
+ {
+ struct sockaddr_un *saddr = (struct sockaddr_un *) addr;
+ networkId = (char *) malloc (3 + strlen (transName) +
+ strlen (hostnamebuf) + strlen (saddr->sun_path));
+ sprintf (networkId, "%s/%s:%s", transName,
+ hostnamebuf, saddr->sun_path);
+ break;
+ }
+#endif /* defined(UNIXCONN) || defined(STREAMSCONN) || defined(LOCALCONN) */
+
+#if defined(TCPCONN) || defined(STREAMSCONN)
+ case AF_INET:
+ {
+ struct sockaddr_in *saddr = (struct sockaddr_in *) addr;
+ char portnumbuf[10];
+
+ sprintf (portnumbuf, "%d", ntohs (saddr->sin_port));
+ networkId = (char *) malloc (3 + strlen (transName) +
+ strlen (hostnamebuf) + strlen (portnumbuf));
+ sprintf (networkId, "%s/%s:%s", transName, hostnamebuf, portnumbuf);
+ break;
+ }
+#endif /* defined(TCPCONN) || defined(STREAMSCONN) */
+
+#if defined(DNETCONN)
+ case AF_DECnet:
+ {
+ struct sockaddr_dn *saddr = (struct sockaddr_dn *) addr;
+
+ networkId = (char *) malloc (
+ 13 + strlen (hostnamebuf) + saddr->sdn_objnamel);
+ sprintf (networkId, "dnet/%s::%s",
+ hostnamebuf, saddr->sdn_objname);
+ break;
+ }
+#endif /* defined(DNETCONN) */
+
+ default:
+ break;
+ }
+
+ return (networkId);
+}
+
+#include <setjmp.h>
+static jmp_buf env;
+
+#ifdef SIGALRM
+static int nameserver_timedout = 0;
+
+static
+#ifdef SIGNALRETURNSINT
+int
+#else
+void
+#endif
+nameserver_lost(sig)
+{
+ nameserver_timedout = 1;
+ longjmp (env, -1);
+ /* NOTREACHED */
+#ifdef SIGNALRETURNSINT
+ return -1; /* for picky compilers */
+#endif
+}
+#endif /* SIGALARM */
+
+
+char *
+TRANS(GetPeerNetworkId) (ciptr)
+
+XtransConnInfo ciptr;
+
+{
+ int family = ciptr->family;
+ int peer_addrlen = ciptr->peeraddrlen;
+ char *peer_addr = ciptr->peeraddr;
+ char *hostname;
+ char *networkId = NULL;
+ char addrbuf[256];
+ char *addr = NULL;
+
+ switch (family)
+ {
+ case AF_UNSPEC:
+#if defined(UNIXCONN) || defined(STREAMSCONN) || defined(LOCALCONN)
+ case AF_UNIX:
+ {
+ if (gethostname (addrbuf, sizeof (addrbuf)) == 0)
+ addr = addrbuf;
+ break;
+ }
+#endif /* defined(UNIXCONN) || defined(STREAMSCONN) || defined(LOCALCONN) */
+
+#if defined(TCPCONN) || defined(STREAMSCONN)
+ case AF_INET:
+ {
+ struct sockaddr_in *saddr = (struct sockaddr_in *) peer_addr;
+ _Xgethostbynameparams hparams;
+ struct hostent * hostp;
+
+#ifndef WIN32
+ char *inet_ntoa();
+#endif
+
+#ifdef SIGALRM
+ /*
+ * gethostbyaddr can take a LONG time if the host does not exist.
+ * Assume that if it does not respond in NAMESERVER_TIMEOUT seconds
+ * that something is wrong and do not make the user wait.
+ * gethostbyaddr will continue after a signal, so we have to
+ * jump out of it.
+ */
+
+ nameserver_timedout = 0;
+ signal (SIGALRM, nameserver_lost);
+ alarm (4);
+ if (setjmp(env) == 0) {
+#endif
+ hostp = _XGethostbyaddr ((char *) &saddr->sin_addr,
+ sizeof (saddr->sin_addr), AF_INET, hparams);
+#ifdef SIGALRM
+ }
+ alarm (0);
+#endif
+ if (hostp != NULL)
+ addr = hostp->h_name;
+ else
+ addr = inet_ntoa (saddr->sin_addr);
+ break;
+ }
+
+#endif /* defined(TCPCONN) || defined(STREAMSCONN) */
+
+#if defined(DNETCONN)
+ case AF_DECnet:
+ {
+ struct sockaddr_dn *saddr = (struct sockaddr_dn *) peer_addr;
+ struct nodeent *np;
+
+ if (np = getnodebyaddr(saddr->sdn_add.a_addr,
+ saddr->sdn_add.a_len, AF_DECnet)) {
+ sprintf(addrbuf, "%s:", np->n_name);
+ } else {
+ sprintf(addrbuf, "%s:", dnet_htoa(&saddr->sdn_add));
+ }
+ addr = addrbuf;
+ break;
+ }
+#endif /* defined(DNETCONN) */
+
+#if defined(AMRPCCONN)
+ case AF_AMOEBA:
+ {
+ addr = "Amoeba"; /* not really used */
+ break;
+ }
+#endif
+#if defined(AMTCPCONN) && !(defined(TCPCONN) || defined(STREAMSCONN))
+ case AF_INET:
+ {
+ if (gethostname (addrbuf, sizeof (addrbuf)) == 0) {
+ addr = addrbuf;
+ } else {
+ addr = "";
+ }
+ break;
+ }
+#endif
+
+ default:
+ return (NULL);
+ }
+
+
+ hostname = (char *) malloc (
+ strlen (ciptr->transptr->TransName) + strlen (addr) + 2);
+ strcpy (hostname, ciptr->transptr->TransName);
+ strcat (hostname, "/");
+ if (addr)
+ strcat (hostname, addr);
+
+ return (hostname);
+}
+
+#endif /* ICE_t */
+
+
+#if defined(WIN32) && (defined(TCPCONN) || defined(DNETCONN))
+int
+TRANS(WSAStartup) ()
+{
+ static WSADATA wsadata;
+
+ PRMSG (2,"TRANS(WSAStartup)()\n", 0, 0, 0);
+
+ if (!wsadata.wVersion && WSAStartup(MAKEWORD(1,1), &wsadata))
+ return 1;
+ return 0;
+}
+#endif
+
+
+static int
+is_numeric (str)
+
+char *str;
+
+{
+ int i;
+
+ for (i = 0; i < (int) strlen (str); i++)
+ if (!isdigit (str[i]))
+ return (0);
+
+ return (1);
+}
diff --git a/transport.c b/transport.c
new file mode 100644
index 0000000..be46eca
--- /dev/null
+++ b/transport.c
@@ -0,0 +1,71 @@
+/* $Xorg: transport.c,v 1.4 2001/02/09 02:04:07 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.
+
+*/
+
+/* 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 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.
+ */
+
+#include "Xtransint.h"
+
+#ifdef DNETCONN
+#include "Xtransdnet.c"
+#endif
+#ifdef LOCALCONN
+#include "Xtranslcl.c"
+#endif
+#if defined(TCPCONN) || defined(UNIXCONN)
+#include "Xtranssock.c"
+#endif
+#ifdef STREAMSCONN
+#include "Xtranstli.c"
+#endif
+#if defined(AMRPCCONN) || defined(AMTCPCONN)
+#include "Xtransam.c"
+#endif
+#include "Xtrans.c"
+#include "Xtransutil.c"