Xtrans.c revision e8a71cdf
173143b9aSmrg/* 273143b9aSmrg 373143b9aSmrgCopyright 1993, 1994, 1998 The Open Group 473143b9aSmrg 573143b9aSmrgPermission to use, copy, modify, distribute, and sell this software and its 673143b9aSmrgdocumentation for any purpose is hereby granted without fee, provided that 773143b9aSmrgthe above copyright notice appear in all copies and that both that 873143b9aSmrgcopyright notice and this permission notice appear in supporting 973143b9aSmrgdocumentation. 1073143b9aSmrg 1173143b9aSmrgThe above copyright notice and this permission notice shall be included 1273143b9aSmrgin all copies or substantial portions of the Software. 1373143b9aSmrg 1473143b9aSmrgTHE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 1573143b9aSmrgOR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 1673143b9aSmrgMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 1773143b9aSmrgIN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR 1873143b9aSmrgOTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 1973143b9aSmrgARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 2073143b9aSmrgOTHER DEALINGS IN THE SOFTWARE. 2173143b9aSmrg 2273143b9aSmrgExcept as contained in this notice, the name of The Open Group shall 2373143b9aSmrgnot be used in advertising or otherwise to promote the sale, use or 2473143b9aSmrgother dealings in this Software without prior written authorization 2573143b9aSmrgfrom The Open Group. 2673143b9aSmrg 2773143b9aSmrg * Copyright 1993, 1994 NCR Corporation - Dayton, Ohio, USA 2873143b9aSmrg * 2973143b9aSmrg * All Rights Reserved 3073143b9aSmrg * 3173143b9aSmrg * Permission to use, copy, modify, and distribute this software and its 3273143b9aSmrg * documentation for any purpose and without fee is hereby granted, provided 3373143b9aSmrg * that the above copyright notice appear in all copies and that both that 3473143b9aSmrg * copyright notice and this permission notice appear in supporting 3573143b9aSmrg * documentation, and that the name NCR not be used in advertising 3673143b9aSmrg * or publicity pertaining to distribution of the software without specific, 3773143b9aSmrg * written prior permission. NCR makes no representations about the 3873143b9aSmrg * suitability of this software for any purpose. It is provided "as is" 3973143b9aSmrg * without express or implied warranty. 4073143b9aSmrg * 4173143b9aSmrg * NCR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, 4273143b9aSmrg * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN 4373143b9aSmrg * NO EVENT SHALL NCR BE LIABLE FOR ANY SPECIAL, INDIRECT OR 4473143b9aSmrg * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS 4573143b9aSmrg * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, 4673143b9aSmrg * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN 4773143b9aSmrg * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 4873143b9aSmrg */ 4973143b9aSmrg 5073143b9aSmrg#include <ctype.h> 5173143b9aSmrg 5273143b9aSmrg/* 5373143b9aSmrg * The transport table contains a definition for every transport (protocol) 5473143b9aSmrg * family. All operations that can be made on the transport go through this 5573143b9aSmrg * table. 5673143b9aSmrg * 5773143b9aSmrg * Each transport is assigned a unique transport id. 5873143b9aSmrg * 5973143b9aSmrg * New transports can be added by adding an entry in this table. 6073143b9aSmrg * For compatiblity, the transport ids should never be renumbered. 6173143b9aSmrg * Always add to the end of the list. 6273143b9aSmrg */ 6373143b9aSmrg 6473143b9aSmrg#define TRANS_TLI_INET_INDEX 1 6573143b9aSmrg#define TRANS_TLI_TCP_INDEX 2 6673143b9aSmrg#define TRANS_TLI_TLI_INDEX 3 6773143b9aSmrg#define TRANS_SOCKET_UNIX_INDEX 4 6873143b9aSmrg#define TRANS_SOCKET_LOCAL_INDEX 5 6973143b9aSmrg#define TRANS_SOCKET_INET_INDEX 6 7073143b9aSmrg#define TRANS_SOCKET_TCP_INDEX 7 7173143b9aSmrg#define TRANS_DNET_INDEX 8 7273143b9aSmrg#define TRANS_LOCAL_LOCAL_INDEX 9 7373143b9aSmrg#define TRANS_LOCAL_PTS_INDEX 10 7473143b9aSmrg#define TRANS_LOCAL_NAMED_INDEX 11 7573143b9aSmrg#define TRANS_LOCAL_ISC_INDEX 12 7673143b9aSmrg#define TRANS_LOCAL_SCO_INDEX 13 7773143b9aSmrg#define TRANS_SOCKET_INET6_INDEX 14 7873143b9aSmrg#define TRANS_LOCAL_PIPE_INDEX 15 7973143b9aSmrg 8073143b9aSmrg 8173143b9aSmrgstatic 8273143b9aSmrgXtransport_table Xtransports[] = { 8373143b9aSmrg#if defined(STREAMSCONN) 8473143b9aSmrg { &TRANS(TLITCPFuncs), TRANS_TLI_TCP_INDEX }, 8573143b9aSmrg { &TRANS(TLIINETFuncs), TRANS_TLI_INET_INDEX }, 8673143b9aSmrg { &TRANS(TLITLIFuncs), TRANS_TLI_TLI_INDEX }, 8773143b9aSmrg#endif /* STREAMSCONN */ 8873143b9aSmrg#if defined(TCPCONN) 8973143b9aSmrg { &TRANS(SocketTCPFuncs), TRANS_SOCKET_TCP_INDEX }, 9073143b9aSmrg#if defined(IPv6) && defined(AF_INET6) 9173143b9aSmrg { &TRANS(SocketINET6Funcs), TRANS_SOCKET_INET6_INDEX }, 9273143b9aSmrg#endif /* IPv6 */ 9373143b9aSmrg { &TRANS(SocketINETFuncs), TRANS_SOCKET_INET_INDEX }, 9473143b9aSmrg#endif /* TCPCONN */ 9573143b9aSmrg#if defined(UNIXCONN) 9673143b9aSmrg#if !defined(LOCALCONN) 9773143b9aSmrg { &TRANS(SocketLocalFuncs), TRANS_SOCKET_LOCAL_INDEX }, 9873143b9aSmrg#endif /* !LOCALCONN */ 9973143b9aSmrg { &TRANS(SocketUNIXFuncs), TRANS_SOCKET_UNIX_INDEX }, 10073143b9aSmrg#endif /* UNIXCONN */ 10173143b9aSmrg#if defined(LOCALCONN) 10273143b9aSmrg { &TRANS(LocalFuncs), TRANS_LOCAL_LOCAL_INDEX }, 10373143b9aSmrg#ifndef sun 10473143b9aSmrg { &TRANS(PTSFuncs), TRANS_LOCAL_PTS_INDEX }, 10573143b9aSmrg#endif /* sun */ 106e8a71cdfSmrg#if defined(SVR4) || defined(__SVR4) 10773143b9aSmrg { &TRANS(NAMEDFuncs), TRANS_LOCAL_NAMED_INDEX }, 10873143b9aSmrg#endif 10973143b9aSmrg#ifdef sun 11073143b9aSmrg { &TRANS(PIPEFuncs), TRANS_LOCAL_PIPE_INDEX }, 11173143b9aSmrg#else /* !sun */ 11273143b9aSmrg#if !defined(__SCO__) && !defined(__UNIXWARE__) 11373143b9aSmrg { &TRANS(ISCFuncs), TRANS_LOCAL_ISC_INDEX }, 11473143b9aSmrg#endif 11573143b9aSmrg { &TRANS(SCOFuncs), TRANS_LOCAL_SCO_INDEX }, 11673143b9aSmrg#endif /* sun */ 11773143b9aSmrg#endif /* LOCALCONN */ 11873143b9aSmrg}; 11973143b9aSmrg 12073143b9aSmrg#define NUMTRANS (sizeof(Xtransports)/sizeof(Xtransport_table)) 12173143b9aSmrg 12273143b9aSmrg 12373143b9aSmrg#ifdef WIN32 12473143b9aSmrg#define ioctl ioctlsocket 12573143b9aSmrg#endif 12673143b9aSmrg 12773143b9aSmrg 12873143b9aSmrg 12973143b9aSmrg/* 13073143b9aSmrg * These are a few utility function used by the public interface functions. 13173143b9aSmrg */ 13273143b9aSmrg 13373143b9aSmrgvoid 13473143b9aSmrgTRANS(FreeConnInfo) (XtransConnInfo ciptr) 13573143b9aSmrg 13673143b9aSmrg{ 13773143b9aSmrg PRMSG (3,"FreeConnInfo(%p)\n", ciptr, 0, 0); 13873143b9aSmrg 13973143b9aSmrg if (ciptr->addr) 14073143b9aSmrg xfree (ciptr->addr); 14173143b9aSmrg 14273143b9aSmrg if (ciptr->peeraddr) 14373143b9aSmrg xfree (ciptr->peeraddr); 14473143b9aSmrg 14573143b9aSmrg if (ciptr->port) 14673143b9aSmrg xfree (ciptr->port); 14773143b9aSmrg 14873143b9aSmrg xfree ((char *) ciptr); 14973143b9aSmrg} 15073143b9aSmrg 15173143b9aSmrg 15273143b9aSmrg#define PROTOBUFSIZE 20 15373143b9aSmrg 15473143b9aSmrgstatic Xtransport * 15573143b9aSmrgTRANS(SelectTransport) (char *protocol) 15673143b9aSmrg 15773143b9aSmrg{ 15873143b9aSmrg char protobuf[PROTOBUFSIZE]; 15973143b9aSmrg int i; 16073143b9aSmrg 16173143b9aSmrg PRMSG (3,"SelectTransport(%s)\n", protocol, 0, 0); 16273143b9aSmrg 16373143b9aSmrg /* 16473143b9aSmrg * Force Protocol to be lowercase as a way of doing 16573143b9aSmrg * a case insensitive match. 16673143b9aSmrg */ 16773143b9aSmrg 16873143b9aSmrg strncpy (protobuf, protocol, PROTOBUFSIZE - 1); 16973143b9aSmrg protobuf[PROTOBUFSIZE-1] = '\0'; 17073143b9aSmrg 17173143b9aSmrg for (i = 0; i < PROTOBUFSIZE && protobuf[i] != '\0'; i++) 17273143b9aSmrg if (isupper (protobuf[i])) 17373143b9aSmrg protobuf[i] = tolower (protobuf[i]); 17473143b9aSmrg 17573143b9aSmrg /* Look at all of the configured protocols */ 17673143b9aSmrg 17773143b9aSmrg for (i = 0; i < NUMTRANS; i++) 17873143b9aSmrg { 17973143b9aSmrg if (!strcmp (protobuf, Xtransports[i].transport->TransName)) 18073143b9aSmrg return Xtransports[i].transport; 18173143b9aSmrg } 18273143b9aSmrg 18373143b9aSmrg return NULL; 18473143b9aSmrg} 18573143b9aSmrg 18673143b9aSmrg#ifndef TEST_t 18773143b9aSmrgstatic 18873143b9aSmrg#endif /* TEST_t */ 18973143b9aSmrgint 19073143b9aSmrgTRANS(ParseAddress) (char *address, char **protocol, char **host, char **port) 19173143b9aSmrg 19273143b9aSmrg{ 19373143b9aSmrg /* 19473143b9aSmrg * For the font library, the address is a string formatted 19573143b9aSmrg * as "protocol/host:port[/catalogue]". Note that the catologue 19673143b9aSmrg * is optional. At this time, the catologue info is ignored, but 19773143b9aSmrg * we have to parse it anyways. 19873143b9aSmrg * 19973143b9aSmrg * Other than fontlib, the address is a string formatted 20073143b9aSmrg * as "protocol/host:port". 20173143b9aSmrg * 20273143b9aSmrg * If the protocol part is missing, then assume TCP. 20373143b9aSmrg * If the protocol part and host part are missing, then assume local. 20473143b9aSmrg * If a "::" is found then assume DNET. 20573143b9aSmrg */ 20673143b9aSmrg 20773143b9aSmrg char *mybuf, *tmpptr; 20873143b9aSmrg char *_protocol, *_host, *_port; 20973143b9aSmrg char hostnamebuf[256]; 21073143b9aSmrg int _host_len; 21173143b9aSmrg 21273143b9aSmrg PRMSG (3,"ParseAddress(%s)\n", address, 0, 0); 21373143b9aSmrg 21473143b9aSmrg /* Copy the string so it can be changed */ 21573143b9aSmrg 21673143b9aSmrg tmpptr = mybuf = (char *) xalloc (strlen (address) + 1); 21773143b9aSmrg strcpy (mybuf, address); 21873143b9aSmrg 21973143b9aSmrg /* Parse the string to get each component */ 22073143b9aSmrg 22173143b9aSmrg /* Get the protocol part */ 22273143b9aSmrg 22373143b9aSmrg _protocol = mybuf; 22473143b9aSmrg 22573143b9aSmrg 22673143b9aSmrg if ( ((mybuf = strchr (mybuf,'/')) == NULL) && 22773143b9aSmrg ((mybuf = strrchr (tmpptr,':')) == NULL) ) 22873143b9aSmrg { 22973143b9aSmrg /* address is in a bad format */ 23073143b9aSmrg *protocol = NULL; 23173143b9aSmrg *host = NULL; 23273143b9aSmrg *port = NULL; 23373143b9aSmrg xfree (tmpptr); 23473143b9aSmrg return 0; 23573143b9aSmrg } 23673143b9aSmrg 23773143b9aSmrg if (*mybuf == ':') 23873143b9aSmrg { 23973143b9aSmrg /* 24073143b9aSmrg * If there is a hostname, then assume tcp, otherwise 24173143b9aSmrg * it must be local. 24273143b9aSmrg */ 24373143b9aSmrg if (mybuf == tmpptr) 24473143b9aSmrg { 24573143b9aSmrg /* There is neither a protocol or host specified */ 24673143b9aSmrg _protocol = "local"; 24773143b9aSmrg } 24873143b9aSmrg else 24973143b9aSmrg { 25073143b9aSmrg /* There is a hostname specified */ 25173143b9aSmrg _protocol = "tcp"; 25273143b9aSmrg mybuf = tmpptr; /* reset to the begining of the host ptr */ 25373143b9aSmrg } 25473143b9aSmrg } 25573143b9aSmrg else 25673143b9aSmrg { 25773143b9aSmrg /* *mybuf == '/' */ 25873143b9aSmrg 25973143b9aSmrg *mybuf ++= '\0'; /* put a null at the end of the protocol */ 26073143b9aSmrg 26173143b9aSmrg if (strlen(_protocol) == 0) 26273143b9aSmrg { 26373143b9aSmrg /* 26473143b9aSmrg * If there is a hostname, then assume tcp, otherwise 26573143b9aSmrg * it must be local. 26673143b9aSmrg */ 26773143b9aSmrg if (*mybuf != ':') 26873143b9aSmrg _protocol = "tcp"; 26973143b9aSmrg else 27073143b9aSmrg _protocol = "local"; 27173143b9aSmrg } 27273143b9aSmrg } 27373143b9aSmrg 27473143b9aSmrg /* Get the host part */ 27573143b9aSmrg 27673143b9aSmrg _host = mybuf; 27773143b9aSmrg 27873143b9aSmrg if ((mybuf = strrchr (mybuf,':')) == NULL) 27973143b9aSmrg { 28073143b9aSmrg *protocol = NULL; 28173143b9aSmrg *host = NULL; 28273143b9aSmrg *port = NULL; 28373143b9aSmrg xfree (tmpptr); 28473143b9aSmrg return 0; 28573143b9aSmrg } 28673143b9aSmrg 28773143b9aSmrg /* Check for DECnet */ 28873143b9aSmrg 28973143b9aSmrg if ((mybuf != _host) && (*(mybuf - 1) == ':') 29073143b9aSmrg#if defined(IPv6) && defined(AF_INET6) 29173143b9aSmrg /* An IPv6 address can end in :: so three : in a row is assumed to be 29273143b9aSmrg an IPv6 host and not a DECnet node with a : in it's name, unless 29373143b9aSmrg DECnet is specifically requested */ 29473143b9aSmrg && ( ((mybuf - 1) == _host) || (*(mybuf - 2) != ':') || 29573143b9aSmrg ((_protocol != NULL) && (strcmp(_protocol, "dnet") == 0)) ) 29673143b9aSmrg#endif 29773143b9aSmrg ) 29873143b9aSmrg { 29973143b9aSmrg _protocol = "dnet"; 30073143b9aSmrg *(mybuf - 1) = '\0'; 30173143b9aSmrg } 30273143b9aSmrg 30373143b9aSmrg *mybuf ++= '\0'; 30473143b9aSmrg 30573143b9aSmrg _host_len = strlen(_host); 30673143b9aSmrg if (_host_len == 0) 30773143b9aSmrg { 30873143b9aSmrg TRANS(GetHostname) (hostnamebuf, sizeof (hostnamebuf)); 30973143b9aSmrg _host = hostnamebuf; 31073143b9aSmrg } 31173143b9aSmrg#if defined(IPv6) && defined(AF_INET6) 31273143b9aSmrg /* hostname in IPv6 [numeric_addr]:0 form? */ 31373143b9aSmrg else if ( (_host_len > 3) && 31473143b9aSmrg ((strcmp(_protocol, "tcp") == 0) || (strcmp(_protocol, "inet6") == 0)) 31573143b9aSmrg && (*_host == '[') && (*(_host + _host_len - 1) == ']') ) { 31673143b9aSmrg struct sockaddr_in6 sin6; 31773143b9aSmrg 31873143b9aSmrg *(_host + _host_len - 1) = '\0'; 31973143b9aSmrg 32073143b9aSmrg /* Verify address is valid IPv6 numeric form */ 32173143b9aSmrg if (inet_pton(AF_INET6, _host + 1, &sin6) == 1) { 32273143b9aSmrg /* It is. Use it as such. */ 32373143b9aSmrg _host++; 32473143b9aSmrg _protocol = "inet6"; 32573143b9aSmrg } else { 32673143b9aSmrg /* It's not, restore it just in case some other code can use it. */ 32773143b9aSmrg *(_host + _host_len - 1) = ']'; 32873143b9aSmrg } 32973143b9aSmrg } 33073143b9aSmrg#endif 33173143b9aSmrg 33273143b9aSmrg 33373143b9aSmrg /* Get the port */ 33473143b9aSmrg 33573143b9aSmrg _port = mybuf; 33673143b9aSmrg 33773143b9aSmrg#if defined(FONT_t) || defined(FS_t) 33873143b9aSmrg /* 33973143b9aSmrg * Is there an optional catalogue list? 34073143b9aSmrg */ 34173143b9aSmrg 34273143b9aSmrg if ((mybuf = strchr (mybuf,'/')) != NULL) 34373143b9aSmrg *mybuf ++= '\0'; 34473143b9aSmrg 34573143b9aSmrg /* 34673143b9aSmrg * The rest, if any, is the (currently unused) catalogue list. 34773143b9aSmrg * 34873143b9aSmrg * _catalogue = mybuf; 34973143b9aSmrg */ 35073143b9aSmrg#endif 35173143b9aSmrg 35273143b9aSmrg#ifdef HAVE_LAUNCHD 35373143b9aSmrg /* launchd sockets will look like 'local//tmp/launch-XgkNns/:0' */ 35473143b9aSmrg if(address != NULL && strlen(address)>8 && (!strncmp(address,"local//",7))) { 35573143b9aSmrg _protocol="local"; 35673143b9aSmrg _host=""; 35773143b9aSmrg _port=address+6; 35873143b9aSmrg } 35973143b9aSmrg#endif 36073143b9aSmrg 36173143b9aSmrg /* 36273143b9aSmrg * Now that we have all of the components, allocate new 36373143b9aSmrg * string space for them. 36473143b9aSmrg */ 36573143b9aSmrg 36673143b9aSmrg if ((*protocol = (char *) xalloc(strlen (_protocol) + 1)) == NULL) 36773143b9aSmrg { 36873143b9aSmrg /* Malloc failed */ 36973143b9aSmrg *port = NULL; 37073143b9aSmrg *host = NULL; 37173143b9aSmrg *protocol = NULL; 37273143b9aSmrg xfree (tmpptr); 37373143b9aSmrg return 0; 37473143b9aSmrg } 37573143b9aSmrg else 37673143b9aSmrg strcpy (*protocol, _protocol); 37773143b9aSmrg 37873143b9aSmrg if ((*host = (char *) xalloc (strlen (_host) + 1)) == NULL) 37973143b9aSmrg { 38073143b9aSmrg /* Malloc failed */ 38173143b9aSmrg *port = NULL; 38273143b9aSmrg *host = NULL; 38373143b9aSmrg xfree (*protocol); 38473143b9aSmrg *protocol = NULL; 38573143b9aSmrg xfree (tmpptr); 38673143b9aSmrg return 0; 38773143b9aSmrg } 38873143b9aSmrg else 38973143b9aSmrg strcpy (*host, _host); 39073143b9aSmrg 39173143b9aSmrg if ((*port = (char *) xalloc (strlen (_port) + 1)) == NULL) 39273143b9aSmrg { 39373143b9aSmrg /* Malloc failed */ 39473143b9aSmrg *port = NULL; 39573143b9aSmrg xfree (*host); 39673143b9aSmrg *host = NULL; 39773143b9aSmrg xfree (*protocol); 39873143b9aSmrg *protocol = NULL; 39973143b9aSmrg xfree (tmpptr); 40073143b9aSmrg return 0; 40173143b9aSmrg } 40273143b9aSmrg else 40373143b9aSmrg strcpy (*port, _port); 40473143b9aSmrg 40573143b9aSmrg xfree (tmpptr); 40673143b9aSmrg 40773143b9aSmrg return 1; 40873143b9aSmrg} 40973143b9aSmrg 41073143b9aSmrg 41173143b9aSmrg/* 41273143b9aSmrg * TRANS(Open) does all of the real work opening a connection. The only 41373143b9aSmrg * funny part about this is the type parameter which is used to decide which 41473143b9aSmrg * type of open to perform. 41573143b9aSmrg */ 41673143b9aSmrg 41773143b9aSmrgstatic XtransConnInfo 41873143b9aSmrgTRANS(Open) (int type, char *address) 41973143b9aSmrg 42073143b9aSmrg{ 42173143b9aSmrg char *protocol = NULL, *host = NULL, *port = NULL; 42273143b9aSmrg XtransConnInfo ciptr = NULL; 42373143b9aSmrg Xtransport *thistrans; 42473143b9aSmrg 42573143b9aSmrg PRMSG (2,"Open(%d,%s)\n", type, address, 0); 42673143b9aSmrg 4278d4c0f7bSmrg#if defined(WIN32) && defined(TCPCONN) 42873143b9aSmrg if (TRANS(WSAStartup)()) 42973143b9aSmrg { 43073143b9aSmrg PRMSG (1,"Open: WSAStartup failed\n", 0, 0, 0); 43173143b9aSmrg return NULL; 43273143b9aSmrg } 43373143b9aSmrg#endif 43473143b9aSmrg 43573143b9aSmrg /* Parse the Address */ 43673143b9aSmrg 43773143b9aSmrg if (TRANS(ParseAddress) (address, &protocol, &host, &port) == 0) 43873143b9aSmrg { 43973143b9aSmrg PRMSG (1,"Open: Unable to Parse address %s\n", address, 0, 0); 44073143b9aSmrg return NULL; 44173143b9aSmrg } 44273143b9aSmrg 44373143b9aSmrg /* Determine the transport type */ 44473143b9aSmrg 44573143b9aSmrg if ((thistrans = TRANS(SelectTransport) (protocol)) == NULL) 44673143b9aSmrg { 44773143b9aSmrg PRMSG (1,"Open: Unable to find transport for %s\n", 44873143b9aSmrg protocol, 0, 0); 44973143b9aSmrg 45073143b9aSmrg xfree (protocol); 45173143b9aSmrg xfree (host); 45273143b9aSmrg xfree (port); 45373143b9aSmrg return NULL; 45473143b9aSmrg } 45573143b9aSmrg 45673143b9aSmrg /* Open the transport */ 45773143b9aSmrg 45873143b9aSmrg switch (type) 45973143b9aSmrg { 46073143b9aSmrg case XTRANS_OPEN_COTS_CLIENT: 46173143b9aSmrg#ifdef TRANS_CLIENT 46273143b9aSmrg ciptr = thistrans->OpenCOTSClient(thistrans, protocol, host, port); 46373143b9aSmrg#endif /* TRANS_CLIENT */ 46473143b9aSmrg break; 46573143b9aSmrg case XTRANS_OPEN_COTS_SERVER: 46673143b9aSmrg#ifdef TRANS_SERVER 46773143b9aSmrg ciptr = thistrans->OpenCOTSServer(thistrans, protocol, host, port); 46873143b9aSmrg#endif /* TRANS_SERVER */ 46973143b9aSmrg break; 47073143b9aSmrg case XTRANS_OPEN_CLTS_CLIENT: 47173143b9aSmrg#ifdef TRANS_CLIENT 47273143b9aSmrg ciptr = thistrans->OpenCLTSClient(thistrans, protocol, host, port); 47373143b9aSmrg#endif /* TRANS_CLIENT */ 47473143b9aSmrg break; 47573143b9aSmrg case XTRANS_OPEN_CLTS_SERVER: 47673143b9aSmrg#ifdef TRANS_SERVER 47773143b9aSmrg ciptr = thistrans->OpenCLTSServer(thistrans, protocol, host, port); 47873143b9aSmrg#endif /* TRANS_SERVER */ 47973143b9aSmrg break; 48073143b9aSmrg default: 48173143b9aSmrg PRMSG (1,"Open: Unknown Open type %d\n", type, 0, 0); 48273143b9aSmrg } 48373143b9aSmrg 48473143b9aSmrg if (ciptr == NULL) 48573143b9aSmrg { 48673143b9aSmrg if (!(thistrans->flags & TRANS_DISABLED)) 48773143b9aSmrg { 48873143b9aSmrg PRMSG (1,"Open: transport open failed for %s/%s:%s\n", 48973143b9aSmrg protocol, host, port); 49073143b9aSmrg } 49173143b9aSmrg xfree (protocol); 49273143b9aSmrg xfree (host); 49373143b9aSmrg xfree (port); 49473143b9aSmrg return NULL; 49573143b9aSmrg } 49673143b9aSmrg 49773143b9aSmrg ciptr->transptr = thistrans; 49873143b9aSmrg ciptr->port = port; /* We need this for TRANS(Reopen) */ 49973143b9aSmrg 50073143b9aSmrg xfree (protocol); 50173143b9aSmrg xfree (host); 50273143b9aSmrg 50373143b9aSmrg return ciptr; 50473143b9aSmrg} 50573143b9aSmrg 50673143b9aSmrg 50773143b9aSmrg#ifdef TRANS_REOPEN 50873143b9aSmrg 50973143b9aSmrg/* 51073143b9aSmrg * We might want to create an XtransConnInfo object based on a previously 51173143b9aSmrg * opened connection. For example, the font server may clone itself and 51273143b9aSmrg * pass file descriptors to the parent. 51373143b9aSmrg */ 51473143b9aSmrg 51573143b9aSmrgstatic XtransConnInfo 51673143b9aSmrgTRANS(Reopen) (int type, int trans_id, int fd, char *port) 51773143b9aSmrg 51873143b9aSmrg{ 51973143b9aSmrg XtransConnInfo ciptr = NULL; 52073143b9aSmrg Xtransport *thistrans = NULL; 52173143b9aSmrg char *save_port; 52273143b9aSmrg int i; 52373143b9aSmrg 52473143b9aSmrg PRMSG (2,"Reopen(%d,%d,%s)\n", trans_id, fd, port); 52573143b9aSmrg 52673143b9aSmrg /* Determine the transport type */ 52773143b9aSmrg 52873143b9aSmrg for (i = 0; i < NUMTRANS; i++) 52973143b9aSmrg if (Xtransports[i].transport_id == trans_id) 53073143b9aSmrg { 53173143b9aSmrg thistrans = Xtransports[i].transport; 53273143b9aSmrg break; 53373143b9aSmrg } 53473143b9aSmrg 53573143b9aSmrg if (thistrans == NULL) 53673143b9aSmrg { 53773143b9aSmrg PRMSG (1,"Reopen: Unable to find transport id %d\n", 53873143b9aSmrg trans_id, 0, 0); 53973143b9aSmrg 54073143b9aSmrg return NULL; 54173143b9aSmrg } 54273143b9aSmrg 54373143b9aSmrg if ((save_port = (char *) xalloc (strlen (port) + 1)) == NULL) 54473143b9aSmrg { 54573143b9aSmrg PRMSG (1,"Reopen: Unable to malloc port string\n", 0, 0, 0); 54673143b9aSmrg 54773143b9aSmrg return NULL; 54873143b9aSmrg } 54973143b9aSmrg 55073143b9aSmrg strcpy (save_port, port); 55173143b9aSmrg 55273143b9aSmrg /* Get a new XtransConnInfo object */ 55373143b9aSmrg 55473143b9aSmrg switch (type) 55573143b9aSmrg { 55673143b9aSmrg case XTRANS_OPEN_COTS_SERVER: 55773143b9aSmrg ciptr = thistrans->ReopenCOTSServer(thistrans, fd, port); 55873143b9aSmrg break; 55973143b9aSmrg case XTRANS_OPEN_CLTS_SERVER: 56073143b9aSmrg ciptr = thistrans->ReopenCLTSServer(thistrans, fd, port); 56173143b9aSmrg break; 56273143b9aSmrg default: 56373143b9aSmrg PRMSG (1,"Reopen: Bad Open type %d\n", type, 0, 0); 56473143b9aSmrg } 56573143b9aSmrg 56673143b9aSmrg if (ciptr == NULL) 56773143b9aSmrg { 56873143b9aSmrg PRMSG (1,"Reopen: transport open failed\n", 0, 0, 0); 56973143b9aSmrg return NULL; 57073143b9aSmrg } 57173143b9aSmrg 57273143b9aSmrg ciptr->transptr = thistrans; 57373143b9aSmrg ciptr->port = save_port; 57473143b9aSmrg 57573143b9aSmrg return ciptr; 57673143b9aSmrg} 57773143b9aSmrg 57873143b9aSmrg#endif /* TRANS_REOPEN */ 57973143b9aSmrg 58073143b9aSmrg 58173143b9aSmrg 58273143b9aSmrg/* 58373143b9aSmrg * These are the public interfaces to this Transport interface. 58473143b9aSmrg * These are the only functions that should have knowledge of the transport 58573143b9aSmrg * table. 58673143b9aSmrg */ 58773143b9aSmrg 58873143b9aSmrg#ifdef TRANS_CLIENT 58973143b9aSmrg 59073143b9aSmrgXtransConnInfo 59173143b9aSmrgTRANS(OpenCOTSClient) (char *address) 59273143b9aSmrg 59373143b9aSmrg{ 59473143b9aSmrg PRMSG (2,"OpenCOTSClient(%s)\n", address, 0, 0); 59573143b9aSmrg return TRANS(Open) (XTRANS_OPEN_COTS_CLIENT, address); 59673143b9aSmrg} 59773143b9aSmrg 59873143b9aSmrg#endif /* TRANS_CLIENT */ 59973143b9aSmrg 60073143b9aSmrg 60173143b9aSmrg#ifdef TRANS_SERVER 60273143b9aSmrg 60373143b9aSmrgXtransConnInfo 60473143b9aSmrgTRANS(OpenCOTSServer) (char *address) 60573143b9aSmrg 60673143b9aSmrg{ 60773143b9aSmrg PRMSG (2,"OpenCOTSServer(%s)\n", address, 0, 0); 60873143b9aSmrg return TRANS(Open) (XTRANS_OPEN_COTS_SERVER, address); 60973143b9aSmrg} 61073143b9aSmrg 61173143b9aSmrg#endif /* TRANS_SERVER */ 61273143b9aSmrg 61373143b9aSmrg 61473143b9aSmrg#ifdef TRANS_CLIENT 61573143b9aSmrg 61673143b9aSmrgXtransConnInfo 61773143b9aSmrgTRANS(OpenCLTSClient) (char *address) 61873143b9aSmrg 61973143b9aSmrg{ 62073143b9aSmrg PRMSG (2,"OpenCLTSClient(%s)\n", address, 0, 0); 62173143b9aSmrg return TRANS(Open) (XTRANS_OPEN_CLTS_CLIENT, address); 62273143b9aSmrg} 62373143b9aSmrg 62473143b9aSmrg#endif /* TRANS_CLIENT */ 62573143b9aSmrg 62673143b9aSmrg 62773143b9aSmrg#ifdef TRANS_SERVER 62873143b9aSmrg 62973143b9aSmrgXtransConnInfo 63073143b9aSmrgTRANS(OpenCLTSServer) (char *address) 63173143b9aSmrg 63273143b9aSmrg{ 63373143b9aSmrg PRMSG (2,"OpenCLTSServer(%s)\n", address, 0, 0); 63473143b9aSmrg return TRANS(Open) (XTRANS_OPEN_CLTS_SERVER, address); 63573143b9aSmrg} 63673143b9aSmrg 63773143b9aSmrg#endif /* TRANS_SERVER */ 63873143b9aSmrg 63973143b9aSmrg 64073143b9aSmrg#ifdef TRANS_REOPEN 64173143b9aSmrg 64273143b9aSmrgXtransConnInfo 64373143b9aSmrgTRANS(ReopenCOTSServer) (int trans_id, int fd, char *port) 64473143b9aSmrg 64573143b9aSmrg{ 64673143b9aSmrg PRMSG (2,"ReopenCOTSServer(%d, %d, %s)\n", trans_id, fd, port); 64773143b9aSmrg return TRANS(Reopen) (XTRANS_OPEN_COTS_SERVER, trans_id, fd, port); 64873143b9aSmrg} 64973143b9aSmrg 65073143b9aSmrgXtransConnInfo 65173143b9aSmrgTRANS(ReopenCLTSServer) (int trans_id, int fd, char *port) 65273143b9aSmrg 65373143b9aSmrg{ 65473143b9aSmrg PRMSG (2,"ReopenCLTSServer(%d, %d, %s)\n", trans_id, fd, port); 65573143b9aSmrg return TRANS(Reopen) (XTRANS_OPEN_CLTS_SERVER, trans_id, fd, port); 65673143b9aSmrg} 65773143b9aSmrg 65873143b9aSmrg 65973143b9aSmrgint 66073143b9aSmrgTRANS(GetReopenInfo) (XtransConnInfo ciptr, 66173143b9aSmrg int *trans_id, int *fd, char **port) 66273143b9aSmrg 66373143b9aSmrg{ 66473143b9aSmrg int i; 66573143b9aSmrg 66673143b9aSmrg for (i = 0; i < NUMTRANS; i++) 66773143b9aSmrg if (Xtransports[i].transport == ciptr->transptr) 66873143b9aSmrg { 66973143b9aSmrg *trans_id = Xtransports[i].transport_id; 67073143b9aSmrg *fd = ciptr->fd; 67173143b9aSmrg 67273143b9aSmrg if ((*port = (char *) xalloc (strlen (ciptr->port) + 1)) == NULL) 67373143b9aSmrg return 0; 67473143b9aSmrg else 67573143b9aSmrg { 67673143b9aSmrg strcpy (*port, ciptr->port); 67773143b9aSmrg return 1; 67873143b9aSmrg } 67973143b9aSmrg } 68073143b9aSmrg 68173143b9aSmrg return 0; 68273143b9aSmrg} 68373143b9aSmrg 68473143b9aSmrg#endif /* TRANS_REOPEN */ 68573143b9aSmrg 68673143b9aSmrg 68773143b9aSmrgint 68873143b9aSmrgTRANS(SetOption) (XtransConnInfo ciptr, int option, int arg) 68973143b9aSmrg 69073143b9aSmrg{ 69173143b9aSmrg int fd = ciptr->fd; 69273143b9aSmrg int ret = 0; 69373143b9aSmrg 69473143b9aSmrg PRMSG (2,"SetOption(%d,%d,%d)\n", fd, option, arg); 69573143b9aSmrg 69673143b9aSmrg /* 69773143b9aSmrg * For now, all transport type use the same stuff for setting options. 69873143b9aSmrg * As long as this is true, we can put the common code here. Once a more 69973143b9aSmrg * complicated transport such as shared memory or an OSI implementation 70073143b9aSmrg * that uses the session and application libraries is implemented, this 70173143b9aSmrg * code may have to move to a transport dependent function. 70273143b9aSmrg * 70373143b9aSmrg * ret = ciptr->transptr->SetOption (ciptr, option, arg); 70473143b9aSmrg */ 70573143b9aSmrg 70673143b9aSmrg switch (option) 70773143b9aSmrg { 70873143b9aSmrg case TRANS_NONBLOCKING: 70973143b9aSmrg switch (arg) 71073143b9aSmrg { 71173143b9aSmrg case 0: 71273143b9aSmrg /* Set to blocking mode */ 71373143b9aSmrg break; 71473143b9aSmrg case 1: /* Set to non-blocking mode */ 71573143b9aSmrg 7168d4c0f7bSmrg#if defined(O_NONBLOCK) && !defined(SCO325) 71773143b9aSmrg ret = fcntl (fd, F_GETFL, 0); 71873143b9aSmrg if (ret != -1) 71973143b9aSmrg ret = fcntl (fd, F_SETFL, ret | O_NONBLOCK); 72073143b9aSmrg#else 72173143b9aSmrg#ifdef FIOSNBIO 72273143b9aSmrg { 72373143b9aSmrg int arg; 72473143b9aSmrg arg = 1; 72573143b9aSmrg ret = ioctl (fd, FIOSNBIO, &arg); 72673143b9aSmrg } 72773143b9aSmrg#else 7288d4c0f7bSmrg#if defined(WIN32) 72973143b9aSmrg { 73073143b9aSmrg#ifdef WIN32 73173143b9aSmrg u_long arg; 73273143b9aSmrg#else 73373143b9aSmrg int arg; 73473143b9aSmrg#endif 73573143b9aSmrg arg = 1; 73673143b9aSmrg/* IBM TCP/IP understands this option too well: it causes TRANS(Read) to fail 73773143b9aSmrg * eventually with EWOULDBLOCK */ 73873143b9aSmrg ret = ioctl (fd, FIONBIO, &arg); 73973143b9aSmrg } 74073143b9aSmrg#else 74173143b9aSmrg ret = fcntl (fd, F_GETFL, 0); 74273143b9aSmrg#ifdef FNDELAY 74373143b9aSmrg ret = fcntl (fd, F_SETFL, ret | FNDELAY); 74473143b9aSmrg#else 74573143b9aSmrg ret = fcntl (fd, F_SETFL, ret | O_NDELAY); 74673143b9aSmrg#endif 74773143b9aSmrg#endif /* AIXV3 || uniosu */ 74873143b9aSmrg#endif /* FIOSNBIO */ 74973143b9aSmrg#endif /* O_NONBLOCK */ 75073143b9aSmrg break; 75173143b9aSmrg default: 75273143b9aSmrg /* Unknown option */ 75373143b9aSmrg break; 75473143b9aSmrg } 75573143b9aSmrg break; 75673143b9aSmrg case TRANS_CLOSEONEXEC: 75773143b9aSmrg#ifdef F_SETFD 75873143b9aSmrg#ifdef FD_CLOEXEC 75973143b9aSmrg ret = fcntl (fd, F_SETFD, FD_CLOEXEC); 76073143b9aSmrg#else 76173143b9aSmrg ret = fcntl (fd, F_SETFD, 1); 76273143b9aSmrg#endif /* FD_CLOEXEC */ 76373143b9aSmrg#endif /* F_SETFD */ 76473143b9aSmrg break; 76573143b9aSmrg } 76673143b9aSmrg 76773143b9aSmrg return ret; 76873143b9aSmrg} 76973143b9aSmrg 77073143b9aSmrg#ifdef TRANS_SERVER 77173143b9aSmrg 77273143b9aSmrgint 77373143b9aSmrgTRANS(CreateListener) (XtransConnInfo ciptr, char *port, unsigned int flags) 77473143b9aSmrg 77573143b9aSmrg{ 77673143b9aSmrg return ciptr->transptr->CreateListener (ciptr, port, flags); 77773143b9aSmrg} 77873143b9aSmrg 77973143b9aSmrgint 78073143b9aSmrgTRANS(NoListen) (char * protocol) 78173143b9aSmrg 78273143b9aSmrg{ 78373143b9aSmrg Xtransport *trans; 78473143b9aSmrg int i = 0, ret = 0; 78573143b9aSmrg 78673143b9aSmrg if ((trans = TRANS(SelectTransport)(protocol)) == NULL) 78773143b9aSmrg { 78873143b9aSmrg PRMSG (1,"TransNoListen: unable to find transport: %s\n", 78973143b9aSmrg protocol, 0, 0); 79073143b9aSmrg 79173143b9aSmrg return -1; 79273143b9aSmrg } 79373143b9aSmrg if (trans->flags & TRANS_ALIAS) { 79473143b9aSmrg if (trans->nolisten) 79573143b9aSmrg while (trans->nolisten[i]) { 79673143b9aSmrg ret |= TRANS(NoListen)(trans->nolisten[i]); 79773143b9aSmrg i++; 79873143b9aSmrg } 79973143b9aSmrg } 80073143b9aSmrg 80173143b9aSmrg trans->flags |= TRANS_NOLISTEN; 80273143b9aSmrg return ret; 80373143b9aSmrg} 80473143b9aSmrg 80573143b9aSmrgint 80673143b9aSmrgTRANS(ResetListener) (XtransConnInfo ciptr) 80773143b9aSmrg 80873143b9aSmrg{ 80973143b9aSmrg if (ciptr->transptr->ResetListener) 81073143b9aSmrg return ciptr->transptr->ResetListener (ciptr); 81173143b9aSmrg else 81273143b9aSmrg return TRANS_RESET_NOOP; 81373143b9aSmrg} 81473143b9aSmrg 81573143b9aSmrg 81673143b9aSmrgXtransConnInfo 81773143b9aSmrgTRANS(Accept) (XtransConnInfo ciptr, int *status) 81873143b9aSmrg 81973143b9aSmrg{ 82073143b9aSmrg XtransConnInfo newciptr; 82173143b9aSmrg 82273143b9aSmrg PRMSG (2,"Accept(%d)\n", ciptr->fd, 0, 0); 82373143b9aSmrg 82473143b9aSmrg newciptr = ciptr->transptr->Accept (ciptr, status); 82573143b9aSmrg 82673143b9aSmrg if (newciptr) 82773143b9aSmrg newciptr->transptr = ciptr->transptr; 82873143b9aSmrg 82973143b9aSmrg return newciptr; 83073143b9aSmrg} 83173143b9aSmrg 83273143b9aSmrg#endif /* TRANS_SERVER */ 83373143b9aSmrg 83473143b9aSmrg 83573143b9aSmrg#ifdef TRANS_CLIENT 83673143b9aSmrg 83773143b9aSmrgint 83873143b9aSmrgTRANS(Connect) (XtransConnInfo ciptr, char *address) 83973143b9aSmrg 84073143b9aSmrg{ 84173143b9aSmrg char *protocol; 84273143b9aSmrg char *host; 84373143b9aSmrg char *port; 84473143b9aSmrg int ret; 84573143b9aSmrg 84673143b9aSmrg PRMSG (2,"Connect(%d,%s)\n", ciptr->fd, address, 0); 84773143b9aSmrg 84873143b9aSmrg if (TRANS(ParseAddress) (address, &protocol, &host, &port) == 0) 84973143b9aSmrg { 85073143b9aSmrg PRMSG (1,"Connect: Unable to Parse address %s\n", 85173143b9aSmrg address, 0, 0); 85273143b9aSmrg return -1; 85373143b9aSmrg } 85473143b9aSmrg 85573143b9aSmrg#ifdef HAVE_LAUNCHD 8568d4c0f7bSmrg if (!host) host=strdup(""); 85773143b9aSmrg#endif 85873143b9aSmrg 85973143b9aSmrg if (!port || !*port) 86073143b9aSmrg { 86173143b9aSmrg PRMSG (1,"Connect: Missing port specification in %s\n", 86273143b9aSmrg address, 0, 0); 86373143b9aSmrg if (protocol) xfree (protocol); 86473143b9aSmrg if (host) xfree (host); 86573143b9aSmrg return -1; 86673143b9aSmrg } 86773143b9aSmrg 86873143b9aSmrg ret = ciptr->transptr->Connect (ciptr, host, port); 86973143b9aSmrg 87073143b9aSmrg if (protocol) xfree (protocol); 87173143b9aSmrg if (host) xfree (host); 87273143b9aSmrg if (port) xfree (port); 87373143b9aSmrg 87473143b9aSmrg return ret; 87573143b9aSmrg} 87673143b9aSmrg 87773143b9aSmrg#endif /* TRANS_CLIENT */ 87873143b9aSmrg 87973143b9aSmrg 88073143b9aSmrgint 88173143b9aSmrgTRANS(BytesReadable) (XtransConnInfo ciptr, BytesReadable_t *pend) 88273143b9aSmrg 88373143b9aSmrg{ 88473143b9aSmrg return ciptr->transptr->BytesReadable (ciptr, pend); 88573143b9aSmrg} 88673143b9aSmrg 88773143b9aSmrgint 88873143b9aSmrgTRANS(Read) (XtransConnInfo ciptr, char *buf, int size) 88973143b9aSmrg 89073143b9aSmrg{ 89173143b9aSmrg return ciptr->transptr->Read (ciptr, buf, size); 89273143b9aSmrg} 89373143b9aSmrg 89473143b9aSmrgint 89573143b9aSmrgTRANS(Write) (XtransConnInfo ciptr, char *buf, int size) 89673143b9aSmrg 89773143b9aSmrg{ 89873143b9aSmrg return ciptr->transptr->Write (ciptr, buf, size); 89973143b9aSmrg} 90073143b9aSmrg 90173143b9aSmrgint 90273143b9aSmrgTRANS(Readv) (XtransConnInfo ciptr, struct iovec *buf, int size) 90373143b9aSmrg 90473143b9aSmrg{ 90573143b9aSmrg return ciptr->transptr->Readv (ciptr, buf, size); 90673143b9aSmrg} 90773143b9aSmrg 90873143b9aSmrgint 90973143b9aSmrgTRANS(Writev) (XtransConnInfo ciptr, struct iovec *buf, int size) 91073143b9aSmrg 91173143b9aSmrg{ 91273143b9aSmrg return ciptr->transptr->Writev (ciptr, buf, size); 91373143b9aSmrg} 91473143b9aSmrg 91573143b9aSmrgint 91673143b9aSmrgTRANS(Disconnect) (XtransConnInfo ciptr) 91773143b9aSmrg 91873143b9aSmrg{ 91973143b9aSmrg return ciptr->transptr->Disconnect (ciptr); 92073143b9aSmrg} 92173143b9aSmrg 92273143b9aSmrgint 92373143b9aSmrgTRANS(Close) (XtransConnInfo ciptr) 92473143b9aSmrg 92573143b9aSmrg{ 92673143b9aSmrg int ret; 92773143b9aSmrg 92873143b9aSmrg PRMSG (2,"Close(%d)\n", ciptr->fd, 0, 0); 92973143b9aSmrg 93073143b9aSmrg ret = ciptr->transptr->Close (ciptr); 93173143b9aSmrg 93273143b9aSmrg TRANS(FreeConnInfo) (ciptr); 93373143b9aSmrg 93473143b9aSmrg return ret; 93573143b9aSmrg} 93673143b9aSmrg 93773143b9aSmrgint 93873143b9aSmrgTRANS(CloseForCloning) (XtransConnInfo ciptr) 93973143b9aSmrg 94073143b9aSmrg{ 94173143b9aSmrg int ret; 94273143b9aSmrg 94373143b9aSmrg PRMSG (2,"CloseForCloning(%d)\n", ciptr->fd, 0, 0); 94473143b9aSmrg 94573143b9aSmrg ret = ciptr->transptr->CloseForCloning (ciptr); 94673143b9aSmrg 94773143b9aSmrg TRANS(FreeConnInfo) (ciptr); 94873143b9aSmrg 94973143b9aSmrg return ret; 95073143b9aSmrg} 95173143b9aSmrg 95273143b9aSmrgint 95373143b9aSmrgTRANS(IsLocal) (XtransConnInfo ciptr) 95473143b9aSmrg 95573143b9aSmrg{ 95673143b9aSmrg return (ciptr->family == AF_UNIX); 95773143b9aSmrg} 95873143b9aSmrg 95973143b9aSmrg 96073143b9aSmrgint 96173143b9aSmrgTRANS(GetMyAddr) (XtransConnInfo ciptr, int *familyp, int *addrlenp, 96273143b9aSmrg Xtransaddr **addrp) 96373143b9aSmrg 96473143b9aSmrg{ 96573143b9aSmrg PRMSG (2,"GetMyAddr(%d)\n", ciptr->fd, 0, 0); 96673143b9aSmrg 96773143b9aSmrg *familyp = ciptr->family; 96873143b9aSmrg *addrlenp = ciptr->addrlen; 96973143b9aSmrg 97073143b9aSmrg if ((*addrp = (Xtransaddr *) xalloc (ciptr->addrlen)) == NULL) 97173143b9aSmrg { 97273143b9aSmrg PRMSG (1,"GetMyAddr: malloc failed\n", 0, 0, 0); 97373143b9aSmrg return -1; 97473143b9aSmrg } 97573143b9aSmrg memcpy(*addrp, ciptr->addr, ciptr->addrlen); 97673143b9aSmrg 97773143b9aSmrg return 0; 97873143b9aSmrg} 97973143b9aSmrg 98073143b9aSmrgint 98173143b9aSmrgTRANS(GetPeerAddr) (XtransConnInfo ciptr, int *familyp, int *addrlenp, 98273143b9aSmrg Xtransaddr **addrp) 98373143b9aSmrg 98473143b9aSmrg{ 98573143b9aSmrg PRMSG (2,"GetPeerAddr(%d)\n", ciptr->fd, 0, 0); 98673143b9aSmrg 98773143b9aSmrg *familyp = ciptr->family; 98873143b9aSmrg *addrlenp = ciptr->peeraddrlen; 98973143b9aSmrg 99073143b9aSmrg if ((*addrp = (Xtransaddr *) xalloc (ciptr->peeraddrlen)) == NULL) 99173143b9aSmrg { 99273143b9aSmrg PRMSG (1,"GetPeerAddr: malloc failed\n", 0, 0, 0); 99373143b9aSmrg return -1; 99473143b9aSmrg } 99573143b9aSmrg memcpy(*addrp, ciptr->peeraddr, ciptr->peeraddrlen); 99673143b9aSmrg 99773143b9aSmrg return 0; 99873143b9aSmrg} 99973143b9aSmrg 100073143b9aSmrg 100173143b9aSmrgint 100273143b9aSmrgTRANS(GetConnectionNumber) (XtransConnInfo ciptr) 100373143b9aSmrg 100473143b9aSmrg{ 100573143b9aSmrg return ciptr->fd; 100673143b9aSmrg} 100773143b9aSmrg 100873143b9aSmrg 100973143b9aSmrg/* 101073143b9aSmrg * These functions are really utility functions, but they require knowledge 101173143b9aSmrg * of the internal data structures, so they have to be part of the Transport 101273143b9aSmrg * Independant API. 101373143b9aSmrg */ 101473143b9aSmrg 101573143b9aSmrg#ifdef TRANS_SERVER 101673143b9aSmrg 101773143b9aSmrgstatic int 101873143b9aSmrgcomplete_network_count (void) 101973143b9aSmrg 102073143b9aSmrg{ 102173143b9aSmrg int count = 0; 102273143b9aSmrg int found_local = 0; 102373143b9aSmrg int i; 102473143b9aSmrg 102573143b9aSmrg /* 102673143b9aSmrg * For a complete network, we only need one LOCALCONN transport to work 102773143b9aSmrg */ 102873143b9aSmrg 102973143b9aSmrg for (i = 0; i < NUMTRANS; i++) 103073143b9aSmrg { 103173143b9aSmrg if (Xtransports[i].transport->flags & TRANS_ALIAS 103273143b9aSmrg || Xtransports[i].transport->flags & TRANS_NOLISTEN) 103373143b9aSmrg continue; 103473143b9aSmrg 103573143b9aSmrg if (Xtransports[i].transport->flags & TRANS_LOCAL) 103673143b9aSmrg found_local = 1; 103773143b9aSmrg else 103873143b9aSmrg count++; 103973143b9aSmrg } 104073143b9aSmrg 104173143b9aSmrg return (count + found_local); 104273143b9aSmrg} 104373143b9aSmrg 104473143b9aSmrg 10458d4c0f7bSmrg#ifdef XQUARTZ_EXPORTS_LAUNCHD_FD 10468d4c0f7bSmrgextern int xquartz_launchd_fd; 10478d4c0f7bSmrg#endif 104873143b9aSmrg 104973143b9aSmrgint 105073143b9aSmrgTRANS(MakeAllCOTSServerListeners) (char *port, int *partial, int *count_ret, 105173143b9aSmrg XtransConnInfo **ciptrs_ret) 105273143b9aSmrg 105373143b9aSmrg{ 105473143b9aSmrg char buffer[256]; /* ??? What size ?? */ 105573143b9aSmrg XtransConnInfo ciptr, temp_ciptrs[NUMTRANS]; 105673143b9aSmrg int status, i, j; 105773143b9aSmrg 105873143b9aSmrg#if defined(IPv6) && defined(AF_INET6) 105973143b9aSmrg int ipv6_succ = 0; 106073143b9aSmrg#endif 106173143b9aSmrg PRMSG (2,"MakeAllCOTSServerListeners(%s,%p)\n", 106273143b9aSmrg port ? port : "NULL", ciptrs_ret, 0); 106373143b9aSmrg 106473143b9aSmrg *count_ret = 0; 106573143b9aSmrg 10668d4c0f7bSmrg#ifdef XQUARTZ_EXPORTS_LAUNCHD_FD 10678d4c0f7bSmrg fprintf(stderr, "Launchd socket fd: %d\n", xquartz_launchd_fd); 10688d4c0f7bSmrg if(xquartz_launchd_fd != -1) { 10698d4c0f7bSmrg if((ciptr = TRANS(ReopenCOTSServer(TRANS_SOCKET_LOCAL_INDEX, 10708d4c0f7bSmrg xquartz_launchd_fd, getenv("DISPLAY"))))==NULL) 10718d4c0f7bSmrg fprintf(stderr,"Got NULL while trying to Reopen launchd port\n"); 10728d4c0f7bSmrg else 10738d4c0f7bSmrg temp_ciptrs[(*count_ret)++] = ciptr; 10748d4c0f7bSmrg } 107573143b9aSmrg#endif 107673143b9aSmrg 107773143b9aSmrg for (i = 0; i < NUMTRANS; i++) 107873143b9aSmrg { 107973143b9aSmrg Xtransport *trans = Xtransports[i].transport; 108073143b9aSmrg unsigned int flags = 0; 108173143b9aSmrg 108273143b9aSmrg if (trans->flags&TRANS_ALIAS || trans->flags&TRANS_NOLISTEN) 108373143b9aSmrg continue; 108473143b9aSmrg 108573143b9aSmrg snprintf(buffer, sizeof(buffer), "%s/:%s", 108673143b9aSmrg trans->TransName, port ? port : ""); 108773143b9aSmrg 108873143b9aSmrg PRMSG (5,"MakeAllCOTSServerListeners: opening %s\n", 108973143b9aSmrg buffer, 0, 0); 109073143b9aSmrg 109173143b9aSmrg if ((ciptr = TRANS(OpenCOTSServer(buffer))) == NULL) 109273143b9aSmrg { 109373143b9aSmrg if (trans->flags & TRANS_DISABLED) 109473143b9aSmrg continue; 109573143b9aSmrg 109673143b9aSmrg PRMSG (1, 109773143b9aSmrg "MakeAllCOTSServerListeners: failed to open listener for %s\n", 109873143b9aSmrg trans->TransName, 0, 0); 109973143b9aSmrg continue; 110073143b9aSmrg } 110173143b9aSmrg#if defined(IPv6) && defined(AF_INET6) 110273143b9aSmrg if ((Xtransports[i].transport_id == TRANS_SOCKET_INET_INDEX 110373143b9aSmrg && ipv6_succ)) 110473143b9aSmrg flags |= ADDR_IN_USE_ALLOWED; 110573143b9aSmrg#endif 110673143b9aSmrg 110773143b9aSmrg if ((status = TRANS(CreateListener (ciptr, port, flags))) < 0) 110873143b9aSmrg { 110973143b9aSmrg if (status == TRANS_ADDR_IN_USE) 111073143b9aSmrg { 111173143b9aSmrg /* 111273143b9aSmrg * We failed to bind to the specified address because the 111373143b9aSmrg * address is in use. It must be that a server is already 111473143b9aSmrg * running at this address, and this function should fail. 111573143b9aSmrg */ 111673143b9aSmrg 111773143b9aSmrg PRMSG (1, 111873143b9aSmrg "MakeAllCOTSServerListeners: server already running\n", 111973143b9aSmrg 0, 0, 0); 112073143b9aSmrg 112173143b9aSmrg for (j = 0; j < *count_ret; j++) 112273143b9aSmrg TRANS(Close) (temp_ciptrs[j]); 112373143b9aSmrg 112473143b9aSmrg *count_ret = 0; 112573143b9aSmrg *ciptrs_ret = NULL; 112673143b9aSmrg *partial = 0; 112773143b9aSmrg return -1; 112873143b9aSmrg } 112973143b9aSmrg else 113073143b9aSmrg { 113173143b9aSmrg PRMSG (1, 113273143b9aSmrg "MakeAllCOTSServerListeners: failed to create listener for %s\n", 113373143b9aSmrg trans->TransName, 0, 0); 113473143b9aSmrg 113573143b9aSmrg continue; 113673143b9aSmrg } 113773143b9aSmrg } 113873143b9aSmrg 113973143b9aSmrg#if defined(IPv6) && defined(AF_INET6) 114073143b9aSmrg if (Xtransports[i].transport_id == TRANS_SOCKET_INET6_INDEX) 114173143b9aSmrg ipv6_succ = 1; 114273143b9aSmrg#endif 114373143b9aSmrg 114473143b9aSmrg PRMSG (5, 114573143b9aSmrg "MakeAllCOTSServerListeners: opened listener for %s, %d\n", 114673143b9aSmrg trans->TransName, ciptr->fd, 0); 114773143b9aSmrg 114873143b9aSmrg temp_ciptrs[*count_ret] = ciptr; 114973143b9aSmrg (*count_ret)++; 115073143b9aSmrg } 115173143b9aSmrg 115273143b9aSmrg *partial = (*count_ret < complete_network_count()); 115373143b9aSmrg 115473143b9aSmrg PRMSG (5, 115573143b9aSmrg "MakeAllCOTSServerListeners: partial=%d, actual=%d, complete=%d \n", 115673143b9aSmrg *partial, *count_ret, complete_network_count()); 115773143b9aSmrg 115873143b9aSmrg if (*count_ret > 0) 115973143b9aSmrg { 116073143b9aSmrg if ((*ciptrs_ret = (XtransConnInfo *) xalloc ( 116173143b9aSmrg *count_ret * sizeof (XtransConnInfo))) == NULL) 116273143b9aSmrg { 116373143b9aSmrg return -1; 116473143b9aSmrg } 116573143b9aSmrg 116673143b9aSmrg for (i = 0; i < *count_ret; i++) 116773143b9aSmrg { 116873143b9aSmrg (*ciptrs_ret)[i] = temp_ciptrs[i]; 116973143b9aSmrg } 117073143b9aSmrg } 117173143b9aSmrg else 117273143b9aSmrg *ciptrs_ret = NULL; 117373143b9aSmrg 117473143b9aSmrg return 0; 117573143b9aSmrg} 117673143b9aSmrg 117773143b9aSmrgint 117873143b9aSmrgTRANS(MakeAllCLTSServerListeners) (char *port, int *partial, int *count_ret, 117973143b9aSmrg XtransConnInfo **ciptrs_ret) 118073143b9aSmrg 118173143b9aSmrg{ 118273143b9aSmrg char buffer[256]; /* ??? What size ?? */ 118373143b9aSmrg XtransConnInfo ciptr, temp_ciptrs[NUMTRANS]; 118473143b9aSmrg int status, i, j; 118573143b9aSmrg 118673143b9aSmrg PRMSG (2,"MakeAllCLTSServerListeners(%s,%p)\n", 118773143b9aSmrg port ? port : "NULL", ciptrs_ret, 0); 118873143b9aSmrg 118973143b9aSmrg *count_ret = 0; 119073143b9aSmrg 119173143b9aSmrg for (i = 0; i < NUMTRANS; i++) 119273143b9aSmrg { 119373143b9aSmrg Xtransport *trans = Xtransports[i].transport; 119473143b9aSmrg 119573143b9aSmrg if (trans->flags&TRANS_ALIAS || trans->flags&TRANS_NOLISTEN) 119673143b9aSmrg continue; 119773143b9aSmrg 119873143b9aSmrg snprintf(buffer, sizeof(buffer), "%s/:%s", 119973143b9aSmrg trans->TransName, port ? port : ""); 120073143b9aSmrg 120173143b9aSmrg PRMSG (5,"MakeAllCLTSServerListeners: opening %s\n", 120273143b9aSmrg buffer, 0, 0); 120373143b9aSmrg 120473143b9aSmrg if ((ciptr = TRANS(OpenCLTSServer (buffer))) == NULL) 120573143b9aSmrg { 120673143b9aSmrg PRMSG (1, 120773143b9aSmrg "MakeAllCLTSServerListeners: failed to open listener for %s\n", 120873143b9aSmrg trans->TransName, 0, 0); 120973143b9aSmrg continue; 121073143b9aSmrg } 121173143b9aSmrg 121273143b9aSmrg if ((status = TRANS(CreateListener (ciptr, port, 0))) < 0) 121373143b9aSmrg { 121473143b9aSmrg if (status == TRANS_ADDR_IN_USE) 121573143b9aSmrg { 121673143b9aSmrg /* 121773143b9aSmrg * We failed to bind to the specified address because the 121873143b9aSmrg * address is in use. It must be that a server is already 121973143b9aSmrg * running at this address, and this function should fail. 122073143b9aSmrg */ 122173143b9aSmrg 122273143b9aSmrg PRMSG (1, 122373143b9aSmrg "MakeAllCLTSServerListeners: server already running\n", 122473143b9aSmrg 0, 0, 0); 122573143b9aSmrg 122673143b9aSmrg for (j = 0; j < *count_ret; j++) 122773143b9aSmrg TRANS(Close) (temp_ciptrs[j]); 122873143b9aSmrg 122973143b9aSmrg *count_ret = 0; 123073143b9aSmrg *ciptrs_ret = NULL; 123173143b9aSmrg *partial = 0; 123273143b9aSmrg return -1; 123373143b9aSmrg } 123473143b9aSmrg else 123573143b9aSmrg { 123673143b9aSmrg PRMSG (1, 123773143b9aSmrg "MakeAllCLTSServerListeners: failed to create listener for %s\n", 123873143b9aSmrg trans->TransName, 0, 0); 123973143b9aSmrg 124073143b9aSmrg continue; 124173143b9aSmrg } 124273143b9aSmrg } 124373143b9aSmrg 124473143b9aSmrg PRMSG (5, 124573143b9aSmrg "MakeAllCLTSServerListeners: opened listener for %s, %d\n", 124673143b9aSmrg trans->TransName, ciptr->fd, 0); 124773143b9aSmrg temp_ciptrs[*count_ret] = ciptr; 124873143b9aSmrg (*count_ret)++; 124973143b9aSmrg } 125073143b9aSmrg 125173143b9aSmrg *partial = (*count_ret < complete_network_count()); 125273143b9aSmrg 125373143b9aSmrg PRMSG (5, 125473143b9aSmrg "MakeAllCLTSServerListeners: partial=%d, actual=%d, complete=%d \n", 125573143b9aSmrg *partial, *count_ret, complete_network_count()); 125673143b9aSmrg 125773143b9aSmrg if (*count_ret > 0) 125873143b9aSmrg { 125973143b9aSmrg if ((*ciptrs_ret = (XtransConnInfo *) xalloc ( 126073143b9aSmrg *count_ret * sizeof (XtransConnInfo))) == NULL) 126173143b9aSmrg { 126273143b9aSmrg return -1; 126373143b9aSmrg } 126473143b9aSmrg 126573143b9aSmrg for (i = 0; i < *count_ret; i++) 126673143b9aSmrg { 126773143b9aSmrg (*ciptrs_ret)[i] = temp_ciptrs[i]; 126873143b9aSmrg } 126973143b9aSmrg } 127073143b9aSmrg else 127173143b9aSmrg *ciptrs_ret = NULL; 127273143b9aSmrg 127373143b9aSmrg return 0; 127473143b9aSmrg} 127573143b9aSmrg 127673143b9aSmrg#endif /* TRANS_SERVER */ 127773143b9aSmrg 127873143b9aSmrg 127973143b9aSmrg 128073143b9aSmrg/* 128173143b9aSmrg * These routines are not part of the X Transport Interface, but they 128273143b9aSmrg * may be used by it. 128373143b9aSmrg */ 128473143b9aSmrg 128573143b9aSmrg 12868d4c0f7bSmrg#if defined(SYSV) && defined(__i386__) && !defined(__SCO__) && !defined(sun) || defined(WIN32) 128773143b9aSmrg 128873143b9aSmrg/* 128973143b9aSmrg * emulate readv 129073143b9aSmrg */ 129173143b9aSmrg 129273143b9aSmrgstatic int TRANS(ReadV) (XtransConnInfo ciptr, struct iovec *iov, int iovcnt) 129373143b9aSmrg 129473143b9aSmrg{ 129573143b9aSmrg int i, len, total; 129673143b9aSmrg char *base; 129773143b9aSmrg 129873143b9aSmrg ESET(0); 129973143b9aSmrg for (i = 0, total = 0; i < iovcnt; i++, iov++) { 130073143b9aSmrg len = iov->iov_len; 130173143b9aSmrg base = iov->iov_base; 130273143b9aSmrg while (len > 0) { 130373143b9aSmrg register int nbytes; 130473143b9aSmrg nbytes = TRANS(Read) (ciptr, base, len); 130573143b9aSmrg if (nbytes < 0 && total == 0) return -1; 130673143b9aSmrg if (nbytes <= 0) return total; 130773143b9aSmrg ESET(0); 130873143b9aSmrg len -= nbytes; 130973143b9aSmrg total += nbytes; 131073143b9aSmrg base += nbytes; 131173143b9aSmrg } 131273143b9aSmrg } 131373143b9aSmrg return total; 131473143b9aSmrg} 131573143b9aSmrg 131673143b9aSmrg#endif /* SYSV && __i386__ || WIN32 || __sxg__ */ 131773143b9aSmrg 13188d4c0f7bSmrg#if defined(SYSV) && defined(__i386__) && !defined(__SCO__) && !defined(sun) || defined(WIN32) 131973143b9aSmrg 132073143b9aSmrg/* 132173143b9aSmrg * emulate writev 132273143b9aSmrg */ 132373143b9aSmrg 132473143b9aSmrgstatic int TRANS(WriteV) (XtransConnInfo ciptr, struct iovec *iov, int iovcnt) 132573143b9aSmrg 132673143b9aSmrg{ 132773143b9aSmrg int i, len, total; 132873143b9aSmrg char *base; 132973143b9aSmrg 133073143b9aSmrg ESET(0); 133173143b9aSmrg for (i = 0, total = 0; i < iovcnt; i++, iov++) { 133273143b9aSmrg len = iov->iov_len; 133373143b9aSmrg base = iov->iov_base; 133473143b9aSmrg while (len > 0) { 133573143b9aSmrg register int nbytes; 133673143b9aSmrg nbytes = TRANS(Write) (ciptr, base, len); 133773143b9aSmrg if (nbytes < 0 && total == 0) return -1; 133873143b9aSmrg if (nbytes <= 0) return total; 133973143b9aSmrg ESET(0); 134073143b9aSmrg len -= nbytes; 134173143b9aSmrg total += nbytes; 134273143b9aSmrg base += nbytes; 134373143b9aSmrg } 134473143b9aSmrg } 134573143b9aSmrg return total; 134673143b9aSmrg} 134773143b9aSmrg 134873143b9aSmrg#endif /* SYSV && __i386__ || WIN32 || __sxg__ */ 134973143b9aSmrg 135073143b9aSmrg 1351e8a71cdfSmrg#if defined(_POSIX_SOURCE) || defined(USG) || defined(SVR4) || defined(__SVR4) || defined(__SCO__) 135273143b9aSmrg#ifndef NEED_UTSNAME 135373143b9aSmrg#define NEED_UTSNAME 135473143b9aSmrg#endif 135573143b9aSmrg#include <sys/utsname.h> 135673143b9aSmrg#endif 135773143b9aSmrg 135873143b9aSmrg/* 135973143b9aSmrg * TRANS(GetHostname) - similar to gethostname but allows special processing. 136073143b9aSmrg */ 136173143b9aSmrg 136273143b9aSmrgint TRANS(GetHostname) (char *buf, int maxlen) 136373143b9aSmrg 136473143b9aSmrg{ 136573143b9aSmrg int len; 136673143b9aSmrg 136773143b9aSmrg#ifdef NEED_UTSNAME 136873143b9aSmrg struct utsname name; 136973143b9aSmrg 137073143b9aSmrg uname (&name); 137173143b9aSmrg len = strlen (name.nodename); 137273143b9aSmrg if (len >= maxlen) len = maxlen - 1; 137373143b9aSmrg strncpy (buf, name.nodename, len); 137473143b9aSmrg buf[len] = '\0'; 137573143b9aSmrg#else 137673143b9aSmrg buf[0] = '\0'; 137773143b9aSmrg (void) gethostname (buf, maxlen); 137873143b9aSmrg buf [maxlen - 1] = '\0'; 137973143b9aSmrg len = strlen(buf); 138073143b9aSmrg#endif /* NEED_UTSNAME */ 138173143b9aSmrg return len; 138273143b9aSmrg} 1383