Xtrans.c revision fe567363
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 75af928962Smrg/* 12 used to be ISC, but that's gone. */ 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#endif /* sun */ 112af928962Smrg#if defined(__SCO__) || defined(__UNIXWARE__) 113af928962Smrg { &TRANS(SCOFuncs), TRANS_LOCAL_SCO_INDEX }, 114af928962Smrg#endif /* __SCO__ || __UNIXWARE__ */ 11573143b9aSmrg#endif /* LOCALCONN */ 11673143b9aSmrg}; 11773143b9aSmrg 11873143b9aSmrg#define NUMTRANS (sizeof(Xtransports)/sizeof(Xtransport_table)) 11973143b9aSmrg 12073143b9aSmrg 12173143b9aSmrg#ifdef WIN32 12273143b9aSmrg#define ioctl ioctlsocket 12373143b9aSmrg#endif 12473143b9aSmrg 12573143b9aSmrg 12673143b9aSmrg 12773143b9aSmrg/* 12873143b9aSmrg * These are a few utility function used by the public interface functions. 12973143b9aSmrg */ 13073143b9aSmrg 13173143b9aSmrgvoid 13273143b9aSmrgTRANS(FreeConnInfo) (XtransConnInfo ciptr) 13373143b9aSmrg 13473143b9aSmrg{ 135fe567363Smrg prmsg (3,"FreeConnInfo(%p)\n", ciptr); 13673143b9aSmrg 13773143b9aSmrg if (ciptr->addr) 138fe567363Smrg free (ciptr->addr); 13973143b9aSmrg 14073143b9aSmrg if (ciptr->peeraddr) 141fe567363Smrg free (ciptr->peeraddr); 14273143b9aSmrg 14373143b9aSmrg if (ciptr->port) 144fe567363Smrg free (ciptr->port); 14573143b9aSmrg 146fe567363Smrg free (ciptr); 14773143b9aSmrg} 14873143b9aSmrg 14973143b9aSmrg 15073143b9aSmrg#define PROTOBUFSIZE 20 15173143b9aSmrg 15273143b9aSmrgstatic Xtransport * 153fe567363SmrgTRANS(SelectTransport) (const char *protocol) 15473143b9aSmrg 15573143b9aSmrg{ 15673143b9aSmrg char protobuf[PROTOBUFSIZE]; 15773143b9aSmrg int i; 15873143b9aSmrg 159fe567363Smrg prmsg (3,"SelectTransport(%s)\n", protocol); 16073143b9aSmrg 16173143b9aSmrg /* 16273143b9aSmrg * Force Protocol to be lowercase as a way of doing 16373143b9aSmrg * a case insensitive match. 16473143b9aSmrg */ 16573143b9aSmrg 16673143b9aSmrg strncpy (protobuf, protocol, PROTOBUFSIZE - 1); 16773143b9aSmrg protobuf[PROTOBUFSIZE-1] = '\0'; 16873143b9aSmrg 16973143b9aSmrg for (i = 0; i < PROTOBUFSIZE && protobuf[i] != '\0'; i++) 17073143b9aSmrg if (isupper (protobuf[i])) 17173143b9aSmrg protobuf[i] = tolower (protobuf[i]); 17273143b9aSmrg 17373143b9aSmrg /* Look at all of the configured protocols */ 17473143b9aSmrg 17573143b9aSmrg for (i = 0; i < NUMTRANS; i++) 17673143b9aSmrg { 17773143b9aSmrg if (!strcmp (protobuf, Xtransports[i].transport->TransName)) 17873143b9aSmrg return Xtransports[i].transport; 17973143b9aSmrg } 18073143b9aSmrg 18173143b9aSmrg return NULL; 18273143b9aSmrg} 18373143b9aSmrg 18473143b9aSmrg#ifndef TEST_t 18573143b9aSmrgstatic 18673143b9aSmrg#endif /* TEST_t */ 18773143b9aSmrgint 18873143b9aSmrgTRANS(ParseAddress) (char *address, char **protocol, char **host, char **port) 18973143b9aSmrg 19073143b9aSmrg{ 19173143b9aSmrg /* 19273143b9aSmrg * For the font library, the address is a string formatted 19373143b9aSmrg * as "protocol/host:port[/catalogue]". Note that the catologue 19473143b9aSmrg * is optional. At this time, the catologue info is ignored, but 19573143b9aSmrg * we have to parse it anyways. 19673143b9aSmrg * 19773143b9aSmrg * Other than fontlib, the address is a string formatted 19873143b9aSmrg * as "protocol/host:port". 19973143b9aSmrg * 20073143b9aSmrg * If the protocol part is missing, then assume TCP. 20173143b9aSmrg * If the protocol part and host part are missing, then assume local. 20273143b9aSmrg * If a "::" is found then assume DNET. 20373143b9aSmrg */ 20473143b9aSmrg 20573143b9aSmrg char *mybuf, *tmpptr; 206fe567363Smrg const char *_protocol; 207fe567363Smrg char *_host, *_port; 20873143b9aSmrg char hostnamebuf[256]; 20973143b9aSmrg int _host_len; 21073143b9aSmrg 211fe567363Smrg prmsg (3,"ParseAddress(%s)\n", address); 21273143b9aSmrg 21373143b9aSmrg /* Copy the string so it can be changed */ 21473143b9aSmrg 215fe567363Smrg tmpptr = mybuf = strdup (address); 21673143b9aSmrg 21773143b9aSmrg /* Parse the string to get each component */ 218fe567363Smrg 21973143b9aSmrg /* Get the protocol part */ 22073143b9aSmrg 22173143b9aSmrg _protocol = mybuf; 22273143b9aSmrg 22373143b9aSmrg 22473143b9aSmrg if ( ((mybuf = strchr (mybuf,'/')) == NULL) && 22573143b9aSmrg ((mybuf = strrchr (tmpptr,':')) == NULL) ) 22673143b9aSmrg { 22773143b9aSmrg /* address is in a bad format */ 22873143b9aSmrg *protocol = NULL; 22973143b9aSmrg *host = NULL; 23073143b9aSmrg *port = NULL; 231fe567363Smrg free (tmpptr); 23273143b9aSmrg return 0; 23373143b9aSmrg } 23473143b9aSmrg 23573143b9aSmrg if (*mybuf == ':') 23673143b9aSmrg { 23773143b9aSmrg /* 23873143b9aSmrg * If there is a hostname, then assume tcp, otherwise 23973143b9aSmrg * it must be local. 24073143b9aSmrg */ 24173143b9aSmrg if (mybuf == tmpptr) 24273143b9aSmrg { 24373143b9aSmrg /* There is neither a protocol or host specified */ 24473143b9aSmrg _protocol = "local"; 24573143b9aSmrg } 24673143b9aSmrg else 24773143b9aSmrg { 24873143b9aSmrg /* There is a hostname specified */ 24973143b9aSmrg _protocol = "tcp"; 25073143b9aSmrg mybuf = tmpptr; /* reset to the begining of the host ptr */ 25173143b9aSmrg } 25273143b9aSmrg } 25373143b9aSmrg else 25473143b9aSmrg { 25573143b9aSmrg /* *mybuf == '/' */ 25673143b9aSmrg 25773143b9aSmrg *mybuf ++= '\0'; /* put a null at the end of the protocol */ 25873143b9aSmrg 25973143b9aSmrg if (strlen(_protocol) == 0) 26073143b9aSmrg { 26173143b9aSmrg /* 26273143b9aSmrg * If there is a hostname, then assume tcp, otherwise 26373143b9aSmrg * it must be local. 26473143b9aSmrg */ 26573143b9aSmrg if (*mybuf != ':') 26673143b9aSmrg _protocol = "tcp"; 26773143b9aSmrg else 26873143b9aSmrg _protocol = "local"; 26973143b9aSmrg } 27073143b9aSmrg } 27173143b9aSmrg 27273143b9aSmrg /* Get the host part */ 27373143b9aSmrg 27473143b9aSmrg _host = mybuf; 27573143b9aSmrg 27673143b9aSmrg if ((mybuf = strrchr (mybuf,':')) == NULL) 27773143b9aSmrg { 27873143b9aSmrg *protocol = NULL; 27973143b9aSmrg *host = NULL; 28073143b9aSmrg *port = NULL; 281fe567363Smrg free (tmpptr); 28273143b9aSmrg return 0; 28373143b9aSmrg } 28473143b9aSmrg 28573143b9aSmrg *mybuf ++= '\0'; 28673143b9aSmrg 28773143b9aSmrg _host_len = strlen(_host); 28873143b9aSmrg if (_host_len == 0) 28973143b9aSmrg { 29073143b9aSmrg TRANS(GetHostname) (hostnamebuf, sizeof (hostnamebuf)); 29173143b9aSmrg _host = hostnamebuf; 29273143b9aSmrg } 29373143b9aSmrg#if defined(IPv6) && defined(AF_INET6) 29473143b9aSmrg /* hostname in IPv6 [numeric_addr]:0 form? */ 295fe567363Smrg else if ( (_host_len > 3) && 29673143b9aSmrg ((strcmp(_protocol, "tcp") == 0) || (strcmp(_protocol, "inet6") == 0)) 297fe567363Smrg && (*_host == '[') && (*(_host + _host_len - 1) == ']') ) { 29873143b9aSmrg struct sockaddr_in6 sin6; 29973143b9aSmrg 30073143b9aSmrg *(_host + _host_len - 1) = '\0'; 30173143b9aSmrg 30273143b9aSmrg /* Verify address is valid IPv6 numeric form */ 30373143b9aSmrg if (inet_pton(AF_INET6, _host + 1, &sin6) == 1) { 30473143b9aSmrg /* It is. Use it as such. */ 30573143b9aSmrg _host++; 30673143b9aSmrg _protocol = "inet6"; 30773143b9aSmrg } else { 30873143b9aSmrg /* It's not, restore it just in case some other code can use it. */ 30973143b9aSmrg *(_host + _host_len - 1) = ']'; 31073143b9aSmrg } 31173143b9aSmrg } 31273143b9aSmrg#endif 31373143b9aSmrg 31473143b9aSmrg 31573143b9aSmrg /* Get the port */ 31673143b9aSmrg 31773143b9aSmrg _port = mybuf; 31873143b9aSmrg 31973143b9aSmrg#if defined(FONT_t) || defined(FS_t) 32073143b9aSmrg /* 32173143b9aSmrg * Is there an optional catalogue list? 32273143b9aSmrg */ 32373143b9aSmrg 32473143b9aSmrg if ((mybuf = strchr (mybuf,'/')) != NULL) 32573143b9aSmrg *mybuf ++= '\0'; 32673143b9aSmrg 32773143b9aSmrg /* 32873143b9aSmrg * The rest, if any, is the (currently unused) catalogue list. 32973143b9aSmrg * 33073143b9aSmrg * _catalogue = mybuf; 33173143b9aSmrg */ 33273143b9aSmrg#endif 33373143b9aSmrg 33473143b9aSmrg#ifdef HAVE_LAUNCHD 33573143b9aSmrg /* launchd sockets will look like 'local//tmp/launch-XgkNns/:0' */ 33673143b9aSmrg if(address != NULL && strlen(address)>8 && (!strncmp(address,"local//",7))) { 33773143b9aSmrg _protocol="local"; 33873143b9aSmrg _host=""; 33973143b9aSmrg _port=address+6; 34073143b9aSmrg } 34173143b9aSmrg#endif 34273143b9aSmrg 34373143b9aSmrg /* 34473143b9aSmrg * Now that we have all of the components, allocate new 34573143b9aSmrg * string space for them. 34673143b9aSmrg */ 34773143b9aSmrg 348fe567363Smrg if ((*protocol = strdup (_protocol)) == NULL) 34973143b9aSmrg { 35073143b9aSmrg /* Malloc failed */ 35173143b9aSmrg *port = NULL; 35273143b9aSmrg *host = NULL; 35373143b9aSmrg *protocol = NULL; 354fe567363Smrg free (tmpptr); 35573143b9aSmrg return 0; 35673143b9aSmrg } 35773143b9aSmrg 358fe567363Smrg if ((*host = strdup (_host)) == NULL) 35973143b9aSmrg { 36073143b9aSmrg /* Malloc failed */ 36173143b9aSmrg *port = NULL; 36273143b9aSmrg *host = NULL; 363fe567363Smrg free (*protocol); 36473143b9aSmrg *protocol = NULL; 365fe567363Smrg free (tmpptr); 36673143b9aSmrg return 0; 367fe567363Smrg } 36873143b9aSmrg 369fe567363Smrg if ((*port = strdup (_port)) == NULL) 37073143b9aSmrg { 37173143b9aSmrg /* Malloc failed */ 37273143b9aSmrg *port = NULL; 373fe567363Smrg free (*host); 37473143b9aSmrg *host = NULL; 375fe567363Smrg free (*protocol); 37673143b9aSmrg *protocol = NULL; 377fe567363Smrg free (tmpptr); 37873143b9aSmrg return 0; 37973143b9aSmrg } 38073143b9aSmrg 381fe567363Smrg free (tmpptr); 38273143b9aSmrg 38373143b9aSmrg return 1; 38473143b9aSmrg} 38573143b9aSmrg 38673143b9aSmrg 38773143b9aSmrg/* 38873143b9aSmrg * TRANS(Open) does all of the real work opening a connection. The only 38973143b9aSmrg * funny part about this is the type parameter which is used to decide which 39073143b9aSmrg * type of open to perform. 39173143b9aSmrg */ 39273143b9aSmrg 39373143b9aSmrgstatic XtransConnInfo 39473143b9aSmrgTRANS(Open) (int type, char *address) 39573143b9aSmrg 39673143b9aSmrg{ 39773143b9aSmrg char *protocol = NULL, *host = NULL, *port = NULL; 39873143b9aSmrg XtransConnInfo ciptr = NULL; 39973143b9aSmrg Xtransport *thistrans; 40073143b9aSmrg 401fe567363Smrg prmsg (2,"Open(%d,%s)\n", type, address); 40273143b9aSmrg 403fe567363Smrg#if defined(WIN32) && defined(TCPCONN) 40473143b9aSmrg if (TRANS(WSAStartup)()) 40573143b9aSmrg { 406fe567363Smrg prmsg (1,"Open: WSAStartup failed\n"); 40773143b9aSmrg return NULL; 40873143b9aSmrg } 40973143b9aSmrg#endif 41073143b9aSmrg 41173143b9aSmrg /* Parse the Address */ 41273143b9aSmrg 41373143b9aSmrg if (TRANS(ParseAddress) (address, &protocol, &host, &port) == 0) 41473143b9aSmrg { 415fe567363Smrg prmsg (1,"Open: Unable to Parse address %s\n", address); 41673143b9aSmrg return NULL; 41773143b9aSmrg } 41873143b9aSmrg 41973143b9aSmrg /* Determine the transport type */ 42073143b9aSmrg 42173143b9aSmrg if ((thistrans = TRANS(SelectTransport) (protocol)) == NULL) 42273143b9aSmrg { 423fe567363Smrg prmsg (1,"Open: Unable to find transport for %s\n", 424fe567363Smrg protocol); 42573143b9aSmrg 426fe567363Smrg free (protocol); 427fe567363Smrg free (host); 428fe567363Smrg free (port); 42973143b9aSmrg return NULL; 43073143b9aSmrg } 43173143b9aSmrg 43273143b9aSmrg /* Open the transport */ 43373143b9aSmrg 43473143b9aSmrg switch (type) 43573143b9aSmrg { 43673143b9aSmrg case XTRANS_OPEN_COTS_CLIENT: 43773143b9aSmrg#ifdef TRANS_CLIENT 43873143b9aSmrg ciptr = thistrans->OpenCOTSClient(thistrans, protocol, host, port); 43973143b9aSmrg#endif /* TRANS_CLIENT */ 44073143b9aSmrg break; 44173143b9aSmrg case XTRANS_OPEN_COTS_SERVER: 44273143b9aSmrg#ifdef TRANS_SERVER 44373143b9aSmrg ciptr = thistrans->OpenCOTSServer(thistrans, protocol, host, port); 44473143b9aSmrg#endif /* TRANS_SERVER */ 44573143b9aSmrg break; 44673143b9aSmrg case XTRANS_OPEN_CLTS_CLIENT: 44773143b9aSmrg#ifdef TRANS_CLIENT 44873143b9aSmrg ciptr = thistrans->OpenCLTSClient(thistrans, protocol, host, port); 44973143b9aSmrg#endif /* TRANS_CLIENT */ 45073143b9aSmrg break; 45173143b9aSmrg case XTRANS_OPEN_CLTS_SERVER: 45273143b9aSmrg#ifdef TRANS_SERVER 45373143b9aSmrg ciptr = thistrans->OpenCLTSServer(thistrans, protocol, host, port); 45473143b9aSmrg#endif /* TRANS_SERVER */ 45573143b9aSmrg break; 45673143b9aSmrg default: 457fe567363Smrg prmsg (1,"Open: Unknown Open type %d\n", type); 45873143b9aSmrg } 45973143b9aSmrg 46073143b9aSmrg if (ciptr == NULL) 46173143b9aSmrg { 462fe567363Smrg if (!(thistrans->flags & TRANS_DISABLED)) 46373143b9aSmrg { 464fe567363Smrg prmsg (1,"Open: transport open failed for %s/%s:%s\n", 46573143b9aSmrg protocol, host, port); 46673143b9aSmrg } 467fe567363Smrg free (protocol); 468fe567363Smrg free (host); 469fe567363Smrg free (port); 47073143b9aSmrg return NULL; 47173143b9aSmrg } 47273143b9aSmrg 47373143b9aSmrg ciptr->transptr = thistrans; 47473143b9aSmrg ciptr->port = port; /* We need this for TRANS(Reopen) */ 47573143b9aSmrg 476fe567363Smrg free (protocol); 477fe567363Smrg free (host); 47873143b9aSmrg 47973143b9aSmrg return ciptr; 48073143b9aSmrg} 48173143b9aSmrg 48273143b9aSmrg 48373143b9aSmrg#ifdef TRANS_REOPEN 48473143b9aSmrg 48573143b9aSmrg/* 48673143b9aSmrg * We might want to create an XtransConnInfo object based on a previously 48773143b9aSmrg * opened connection. For example, the font server may clone itself and 48873143b9aSmrg * pass file descriptors to the parent. 48973143b9aSmrg */ 49073143b9aSmrg 49173143b9aSmrgstatic XtransConnInfo 49273143b9aSmrgTRANS(Reopen) (int type, int trans_id, int fd, char *port) 49373143b9aSmrg 49473143b9aSmrg{ 49573143b9aSmrg XtransConnInfo ciptr = NULL; 49673143b9aSmrg Xtransport *thistrans = NULL; 49773143b9aSmrg char *save_port; 49873143b9aSmrg int i; 49973143b9aSmrg 500fe567363Smrg prmsg (2,"Reopen(%d,%d,%s)\n", trans_id, fd, port); 50173143b9aSmrg 50273143b9aSmrg /* Determine the transport type */ 50373143b9aSmrg 50473143b9aSmrg for (i = 0; i < NUMTRANS; i++) 50573143b9aSmrg if (Xtransports[i].transport_id == trans_id) 50673143b9aSmrg { 50773143b9aSmrg thistrans = Xtransports[i].transport; 50873143b9aSmrg break; 50973143b9aSmrg } 51073143b9aSmrg 51173143b9aSmrg if (thistrans == NULL) 51273143b9aSmrg { 513fe567363Smrg prmsg (1,"Reopen: Unable to find transport id %d\n", 514fe567363Smrg trans_id); 51573143b9aSmrg 51673143b9aSmrg return NULL; 51773143b9aSmrg } 51873143b9aSmrg 519fe567363Smrg if ((save_port = strdup (port)) == NULL) 52073143b9aSmrg { 521fe567363Smrg prmsg (1,"Reopen: Unable to malloc port string\n"); 52273143b9aSmrg 52373143b9aSmrg return NULL; 52473143b9aSmrg } 52573143b9aSmrg 52673143b9aSmrg /* Get a new XtransConnInfo object */ 52773143b9aSmrg 52873143b9aSmrg switch (type) 52973143b9aSmrg { 53073143b9aSmrg case XTRANS_OPEN_COTS_SERVER: 53173143b9aSmrg ciptr = thistrans->ReopenCOTSServer(thistrans, fd, port); 53273143b9aSmrg break; 53373143b9aSmrg case XTRANS_OPEN_CLTS_SERVER: 53473143b9aSmrg ciptr = thistrans->ReopenCLTSServer(thistrans, fd, port); 53573143b9aSmrg break; 53673143b9aSmrg default: 537fe567363Smrg prmsg (1,"Reopen: Bad Open type %d\n", type); 53873143b9aSmrg } 53973143b9aSmrg 54073143b9aSmrg if (ciptr == NULL) 54173143b9aSmrg { 542fe567363Smrg prmsg (1,"Reopen: transport open failed\n"); 543fe567363Smrg free (save_port); 54473143b9aSmrg return NULL; 54573143b9aSmrg } 54673143b9aSmrg 54773143b9aSmrg ciptr->transptr = thistrans; 54873143b9aSmrg ciptr->port = save_port; 54973143b9aSmrg 55073143b9aSmrg return ciptr; 55173143b9aSmrg} 55273143b9aSmrg 55373143b9aSmrg#endif /* TRANS_REOPEN */ 55473143b9aSmrg 55573143b9aSmrg 55673143b9aSmrg 55773143b9aSmrg/* 55873143b9aSmrg * These are the public interfaces to this Transport interface. 55973143b9aSmrg * These are the only functions that should have knowledge of the transport 56073143b9aSmrg * table. 56173143b9aSmrg */ 56273143b9aSmrg 56373143b9aSmrg#ifdef TRANS_CLIENT 56473143b9aSmrg 56573143b9aSmrgXtransConnInfo 56673143b9aSmrgTRANS(OpenCOTSClient) (char *address) 56773143b9aSmrg 56873143b9aSmrg{ 569fe567363Smrg prmsg (2,"OpenCOTSClient(%s)\n", address); 57073143b9aSmrg return TRANS(Open) (XTRANS_OPEN_COTS_CLIENT, address); 57173143b9aSmrg} 57273143b9aSmrg 57373143b9aSmrg#endif /* TRANS_CLIENT */ 57473143b9aSmrg 57573143b9aSmrg 57673143b9aSmrg#ifdef TRANS_SERVER 57773143b9aSmrg 57873143b9aSmrgXtransConnInfo 57973143b9aSmrgTRANS(OpenCOTSServer) (char *address) 58073143b9aSmrg 58173143b9aSmrg{ 582fe567363Smrg prmsg (2,"OpenCOTSServer(%s)\n", address); 58373143b9aSmrg return TRANS(Open) (XTRANS_OPEN_COTS_SERVER, address); 58473143b9aSmrg} 58573143b9aSmrg 58673143b9aSmrg#endif /* TRANS_SERVER */ 58773143b9aSmrg 58873143b9aSmrg 58973143b9aSmrg#ifdef TRANS_CLIENT 59073143b9aSmrg 59173143b9aSmrgXtransConnInfo 59273143b9aSmrgTRANS(OpenCLTSClient) (char *address) 59373143b9aSmrg 59473143b9aSmrg{ 595fe567363Smrg prmsg (2,"OpenCLTSClient(%s)\n", address); 59673143b9aSmrg return TRANS(Open) (XTRANS_OPEN_CLTS_CLIENT, address); 59773143b9aSmrg} 59873143b9aSmrg 59973143b9aSmrg#endif /* TRANS_CLIENT */ 60073143b9aSmrg 60173143b9aSmrg 60273143b9aSmrg#ifdef TRANS_SERVER 60373143b9aSmrg 60473143b9aSmrgXtransConnInfo 60573143b9aSmrgTRANS(OpenCLTSServer) (char *address) 60673143b9aSmrg 60773143b9aSmrg{ 608fe567363Smrg prmsg (2,"OpenCLTSServer(%s)\n", address); 60973143b9aSmrg return TRANS(Open) (XTRANS_OPEN_CLTS_SERVER, address); 61073143b9aSmrg} 61173143b9aSmrg 61273143b9aSmrg#endif /* TRANS_SERVER */ 61373143b9aSmrg 61473143b9aSmrg 61573143b9aSmrg#ifdef TRANS_REOPEN 61673143b9aSmrg 61773143b9aSmrgXtransConnInfo 61873143b9aSmrgTRANS(ReopenCOTSServer) (int trans_id, int fd, char *port) 61973143b9aSmrg 62073143b9aSmrg{ 621fe567363Smrg prmsg (2,"ReopenCOTSServer(%d, %d, %s)\n", trans_id, fd, port); 62273143b9aSmrg return TRANS(Reopen) (XTRANS_OPEN_COTS_SERVER, trans_id, fd, port); 62373143b9aSmrg} 62473143b9aSmrg 62573143b9aSmrgXtransConnInfo 62673143b9aSmrgTRANS(ReopenCLTSServer) (int trans_id, int fd, char *port) 62773143b9aSmrg 62873143b9aSmrg{ 629fe567363Smrg prmsg (2,"ReopenCLTSServer(%d, %d, %s)\n", trans_id, fd, port); 63073143b9aSmrg return TRANS(Reopen) (XTRANS_OPEN_CLTS_SERVER, trans_id, fd, port); 63173143b9aSmrg} 63273143b9aSmrg 63373143b9aSmrg 63473143b9aSmrgint 635fe567363SmrgTRANS(GetReopenInfo) (XtransConnInfo ciptr, 63673143b9aSmrg int *trans_id, int *fd, char **port) 63773143b9aSmrg 63873143b9aSmrg{ 63973143b9aSmrg int i; 64073143b9aSmrg 64173143b9aSmrg for (i = 0; i < NUMTRANS; i++) 64273143b9aSmrg if (Xtransports[i].transport == ciptr->transptr) 64373143b9aSmrg { 64473143b9aSmrg *trans_id = Xtransports[i].transport_id; 64573143b9aSmrg *fd = ciptr->fd; 64673143b9aSmrg 647fe567363Smrg if ((*port = strdup (ciptr->port)) == NULL) 64873143b9aSmrg return 0; 64973143b9aSmrg else 65073143b9aSmrg return 1; 65173143b9aSmrg } 65273143b9aSmrg 65373143b9aSmrg return 0; 65473143b9aSmrg} 65573143b9aSmrg 65673143b9aSmrg#endif /* TRANS_REOPEN */ 65773143b9aSmrg 65873143b9aSmrg 65973143b9aSmrgint 66073143b9aSmrgTRANS(SetOption) (XtransConnInfo ciptr, int option, int arg) 66173143b9aSmrg 66273143b9aSmrg{ 66373143b9aSmrg int fd = ciptr->fd; 66473143b9aSmrg int ret = 0; 66573143b9aSmrg 666fe567363Smrg prmsg (2,"SetOption(%d,%d,%d)\n", fd, option, arg); 66773143b9aSmrg 66873143b9aSmrg /* 66973143b9aSmrg * For now, all transport type use the same stuff for setting options. 67073143b9aSmrg * As long as this is true, we can put the common code here. Once a more 67173143b9aSmrg * complicated transport such as shared memory or an OSI implementation 67273143b9aSmrg * that uses the session and application libraries is implemented, this 67373143b9aSmrg * code may have to move to a transport dependent function. 67473143b9aSmrg * 67573143b9aSmrg * ret = ciptr->transptr->SetOption (ciptr, option, arg); 67673143b9aSmrg */ 67773143b9aSmrg 67873143b9aSmrg switch (option) 67973143b9aSmrg { 68073143b9aSmrg case TRANS_NONBLOCKING: 68173143b9aSmrg switch (arg) 68273143b9aSmrg { 68373143b9aSmrg case 0: 68473143b9aSmrg /* Set to blocking mode */ 68573143b9aSmrg break; 68673143b9aSmrg case 1: /* Set to non-blocking mode */ 68773143b9aSmrg 688fe567363Smrg#if defined(O_NONBLOCK) && !defined(SCO325) 68973143b9aSmrg ret = fcntl (fd, F_GETFL, 0); 69073143b9aSmrg if (ret != -1) 69173143b9aSmrg ret = fcntl (fd, F_SETFL, ret | O_NONBLOCK); 69273143b9aSmrg#else 69373143b9aSmrg#ifdef FIOSNBIO 69473143b9aSmrg { 69573143b9aSmrg int arg; 69673143b9aSmrg arg = 1; 69773143b9aSmrg ret = ioctl (fd, FIOSNBIO, &arg); 69873143b9aSmrg } 69973143b9aSmrg#else 700fe567363Smrg#if defined(WIN32) 70173143b9aSmrg { 70273143b9aSmrg#ifdef WIN32 70373143b9aSmrg u_long arg; 70473143b9aSmrg#else 70573143b9aSmrg int arg; 70673143b9aSmrg#endif 70773143b9aSmrg arg = 1; 70873143b9aSmrg/* IBM TCP/IP understands this option too well: it causes TRANS(Read) to fail 70973143b9aSmrg * eventually with EWOULDBLOCK */ 71073143b9aSmrg ret = ioctl (fd, FIONBIO, &arg); 71173143b9aSmrg } 71273143b9aSmrg#else 71373143b9aSmrg ret = fcntl (fd, F_GETFL, 0); 71473143b9aSmrg#ifdef FNDELAY 71573143b9aSmrg ret = fcntl (fd, F_SETFL, ret | FNDELAY); 71673143b9aSmrg#else 71773143b9aSmrg ret = fcntl (fd, F_SETFL, ret | O_NDELAY); 71873143b9aSmrg#endif 71973143b9aSmrg#endif /* AIXV3 || uniosu */ 72073143b9aSmrg#endif /* FIOSNBIO */ 72173143b9aSmrg#endif /* O_NONBLOCK */ 72273143b9aSmrg break; 72373143b9aSmrg default: 72473143b9aSmrg /* Unknown option */ 72573143b9aSmrg break; 72673143b9aSmrg } 72773143b9aSmrg break; 72873143b9aSmrg case TRANS_CLOSEONEXEC: 72973143b9aSmrg#ifdef F_SETFD 73073143b9aSmrg#ifdef FD_CLOEXEC 73173143b9aSmrg ret = fcntl (fd, F_SETFD, FD_CLOEXEC); 73273143b9aSmrg#else 73373143b9aSmrg ret = fcntl (fd, F_SETFD, 1); 73473143b9aSmrg#endif /* FD_CLOEXEC */ 73573143b9aSmrg#endif /* F_SETFD */ 73673143b9aSmrg break; 73773143b9aSmrg } 738fe567363Smrg 73973143b9aSmrg return ret; 74073143b9aSmrg} 74173143b9aSmrg 74273143b9aSmrg#ifdef TRANS_SERVER 74373143b9aSmrg 74473143b9aSmrgint 74573143b9aSmrgTRANS(CreateListener) (XtransConnInfo ciptr, char *port, unsigned int flags) 74673143b9aSmrg 74773143b9aSmrg{ 74873143b9aSmrg return ciptr->transptr->CreateListener (ciptr, port, flags); 74973143b9aSmrg} 75073143b9aSmrg 75173143b9aSmrgint 752fe567363SmrgTRANS(NoListen) (const char * protocol) 753fe567363Smrg 75473143b9aSmrg{ 75573143b9aSmrg Xtransport *trans; 75673143b9aSmrg int i = 0, ret = 0; 757fe567363Smrg 758fe567363Smrg if ((trans = TRANS(SelectTransport)(protocol)) == NULL) 75973143b9aSmrg { 760fe567363Smrg prmsg (1,"TransNoListen: unable to find transport: %s\n", 761fe567363Smrg protocol); 76273143b9aSmrg 76373143b9aSmrg return -1; 76473143b9aSmrg } 76573143b9aSmrg if (trans->flags & TRANS_ALIAS) { 76673143b9aSmrg if (trans->nolisten) 76773143b9aSmrg while (trans->nolisten[i]) { 76873143b9aSmrg ret |= TRANS(NoListen)(trans->nolisten[i]); 76973143b9aSmrg i++; 77073143b9aSmrg } 77173143b9aSmrg } 77273143b9aSmrg 77373143b9aSmrg trans->flags |= TRANS_NOLISTEN; 77473143b9aSmrg return ret; 77573143b9aSmrg} 77673143b9aSmrg 77773143b9aSmrgint 77873143b9aSmrgTRANS(ResetListener) (XtransConnInfo ciptr) 77973143b9aSmrg 78073143b9aSmrg{ 78173143b9aSmrg if (ciptr->transptr->ResetListener) 78273143b9aSmrg return ciptr->transptr->ResetListener (ciptr); 78373143b9aSmrg else 78473143b9aSmrg return TRANS_RESET_NOOP; 78573143b9aSmrg} 78673143b9aSmrg 78773143b9aSmrg 78873143b9aSmrgXtransConnInfo 78973143b9aSmrgTRANS(Accept) (XtransConnInfo ciptr, int *status) 79073143b9aSmrg 79173143b9aSmrg{ 79273143b9aSmrg XtransConnInfo newciptr; 79373143b9aSmrg 794fe567363Smrg prmsg (2,"Accept(%d)\n", ciptr->fd); 79573143b9aSmrg 79673143b9aSmrg newciptr = ciptr->transptr->Accept (ciptr, status); 79773143b9aSmrg 79873143b9aSmrg if (newciptr) 79973143b9aSmrg newciptr->transptr = ciptr->transptr; 80073143b9aSmrg 80173143b9aSmrg return newciptr; 80273143b9aSmrg} 80373143b9aSmrg 80473143b9aSmrg#endif /* TRANS_SERVER */ 80573143b9aSmrg 80673143b9aSmrg 80773143b9aSmrg#ifdef TRANS_CLIENT 80873143b9aSmrg 80973143b9aSmrgint 81073143b9aSmrgTRANS(Connect) (XtransConnInfo ciptr, char *address) 81173143b9aSmrg 81273143b9aSmrg{ 81373143b9aSmrg char *protocol; 81473143b9aSmrg char *host; 81573143b9aSmrg char *port; 81673143b9aSmrg int ret; 81773143b9aSmrg 818fe567363Smrg prmsg (2,"Connect(%d,%s)\n", ciptr->fd, address); 81973143b9aSmrg 82073143b9aSmrg if (TRANS(ParseAddress) (address, &protocol, &host, &port) == 0) 82173143b9aSmrg { 822fe567363Smrg prmsg (1,"Connect: Unable to Parse address %s\n", 823fe567363Smrg address); 82473143b9aSmrg return -1; 82573143b9aSmrg } 82673143b9aSmrg 82773143b9aSmrg#ifdef HAVE_LAUNCHD 8288d4c0f7bSmrg if (!host) host=strdup(""); 82973143b9aSmrg#endif 83073143b9aSmrg 83173143b9aSmrg if (!port || !*port) 83273143b9aSmrg { 833fe567363Smrg prmsg (1,"Connect: Missing port specification in %s\n", 834fe567363Smrg address); 835fe567363Smrg if (protocol) free (protocol); 836fe567363Smrg if (host) free (host); 83773143b9aSmrg return -1; 83873143b9aSmrg } 83973143b9aSmrg 84073143b9aSmrg ret = ciptr->transptr->Connect (ciptr, host, port); 84173143b9aSmrg 842fe567363Smrg if (protocol) free (protocol); 843fe567363Smrg if (host) free (host); 844fe567363Smrg if (port) free (port); 845fe567363Smrg 84673143b9aSmrg return ret; 84773143b9aSmrg} 84873143b9aSmrg 84973143b9aSmrg#endif /* TRANS_CLIENT */ 85073143b9aSmrg 85173143b9aSmrg 85273143b9aSmrgint 85373143b9aSmrgTRANS(BytesReadable) (XtransConnInfo ciptr, BytesReadable_t *pend) 85473143b9aSmrg 85573143b9aSmrg{ 85673143b9aSmrg return ciptr->transptr->BytesReadable (ciptr, pend); 85773143b9aSmrg} 85873143b9aSmrg 85973143b9aSmrgint 86073143b9aSmrgTRANS(Read) (XtransConnInfo ciptr, char *buf, int size) 86173143b9aSmrg 86273143b9aSmrg{ 86373143b9aSmrg return ciptr->transptr->Read (ciptr, buf, size); 86473143b9aSmrg} 86573143b9aSmrg 86673143b9aSmrgint 86773143b9aSmrgTRANS(Write) (XtransConnInfo ciptr, char *buf, int size) 86873143b9aSmrg 86973143b9aSmrg{ 87073143b9aSmrg return ciptr->transptr->Write (ciptr, buf, size); 87173143b9aSmrg} 87273143b9aSmrg 87373143b9aSmrgint 87473143b9aSmrgTRANS(Readv) (XtransConnInfo ciptr, struct iovec *buf, int size) 87573143b9aSmrg 87673143b9aSmrg{ 87773143b9aSmrg return ciptr->transptr->Readv (ciptr, buf, size); 87873143b9aSmrg} 87973143b9aSmrg 88073143b9aSmrgint 88173143b9aSmrgTRANS(Writev) (XtransConnInfo ciptr, struct iovec *buf, int size) 88273143b9aSmrg 88373143b9aSmrg{ 88473143b9aSmrg return ciptr->transptr->Writev (ciptr, buf, size); 88573143b9aSmrg} 88673143b9aSmrg 88773143b9aSmrgint 88873143b9aSmrgTRANS(Disconnect) (XtransConnInfo ciptr) 88973143b9aSmrg 89073143b9aSmrg{ 89173143b9aSmrg return ciptr->transptr->Disconnect (ciptr); 89273143b9aSmrg} 89373143b9aSmrg 89473143b9aSmrgint 89573143b9aSmrgTRANS(Close) (XtransConnInfo ciptr) 89673143b9aSmrg 89773143b9aSmrg{ 89873143b9aSmrg int ret; 89973143b9aSmrg 900fe567363Smrg prmsg (2,"Close(%d)\n", ciptr->fd); 90173143b9aSmrg 90273143b9aSmrg ret = ciptr->transptr->Close (ciptr); 90373143b9aSmrg 90473143b9aSmrg TRANS(FreeConnInfo) (ciptr); 90573143b9aSmrg 90673143b9aSmrg return ret; 90773143b9aSmrg} 90873143b9aSmrg 90973143b9aSmrgint 91073143b9aSmrgTRANS(CloseForCloning) (XtransConnInfo ciptr) 91173143b9aSmrg 91273143b9aSmrg{ 91373143b9aSmrg int ret; 91473143b9aSmrg 915fe567363Smrg prmsg (2,"CloseForCloning(%d)\n", ciptr->fd); 91673143b9aSmrg 91773143b9aSmrg ret = ciptr->transptr->CloseForCloning (ciptr); 91873143b9aSmrg 91973143b9aSmrg TRANS(FreeConnInfo) (ciptr); 92073143b9aSmrg 92173143b9aSmrg return ret; 92273143b9aSmrg} 92373143b9aSmrg 92473143b9aSmrgint 92573143b9aSmrgTRANS(IsLocal) (XtransConnInfo ciptr) 92673143b9aSmrg 92773143b9aSmrg{ 92873143b9aSmrg return (ciptr->family == AF_UNIX); 92973143b9aSmrg} 93073143b9aSmrg 93173143b9aSmrg 93273143b9aSmrgint 933fe567363SmrgTRANS(GetMyAddr) (XtransConnInfo ciptr, int *familyp, int *addrlenp, 93473143b9aSmrg Xtransaddr **addrp) 93573143b9aSmrg 93673143b9aSmrg{ 937fe567363Smrg prmsg (2,"GetMyAddr(%d)\n", ciptr->fd); 93873143b9aSmrg 93973143b9aSmrg *familyp = ciptr->family; 94073143b9aSmrg *addrlenp = ciptr->addrlen; 94173143b9aSmrg 942fe567363Smrg if ((*addrp = malloc (ciptr->addrlen)) == NULL) 94373143b9aSmrg { 944fe567363Smrg prmsg (1,"GetMyAddr: malloc failed\n"); 94573143b9aSmrg return -1; 94673143b9aSmrg } 94773143b9aSmrg memcpy(*addrp, ciptr->addr, ciptr->addrlen); 94873143b9aSmrg 94973143b9aSmrg return 0; 95073143b9aSmrg} 95173143b9aSmrg 95273143b9aSmrgint 953fe567363SmrgTRANS(GetPeerAddr) (XtransConnInfo ciptr, int *familyp, int *addrlenp, 95473143b9aSmrg Xtransaddr **addrp) 95573143b9aSmrg 95673143b9aSmrg{ 957fe567363Smrg prmsg (2,"GetPeerAddr(%d)\n", ciptr->fd); 95873143b9aSmrg 95973143b9aSmrg *familyp = ciptr->family; 96073143b9aSmrg *addrlenp = ciptr->peeraddrlen; 96173143b9aSmrg 962fe567363Smrg if ((*addrp = malloc (ciptr->peeraddrlen)) == NULL) 96373143b9aSmrg { 964fe567363Smrg prmsg (1,"GetPeerAddr: malloc failed\n"); 96573143b9aSmrg return -1; 96673143b9aSmrg } 96773143b9aSmrg memcpy(*addrp, ciptr->peeraddr, ciptr->peeraddrlen); 96873143b9aSmrg 96973143b9aSmrg return 0; 97073143b9aSmrg} 97173143b9aSmrg 97273143b9aSmrg 97373143b9aSmrgint 97473143b9aSmrgTRANS(GetConnectionNumber) (XtransConnInfo ciptr) 97573143b9aSmrg 97673143b9aSmrg{ 97773143b9aSmrg return ciptr->fd; 97873143b9aSmrg} 97973143b9aSmrg 98073143b9aSmrg 98173143b9aSmrg/* 98273143b9aSmrg * These functions are really utility functions, but they require knowledge 98373143b9aSmrg * of the internal data structures, so they have to be part of the Transport 98473143b9aSmrg * Independant API. 98573143b9aSmrg */ 98673143b9aSmrg 98773143b9aSmrg#ifdef TRANS_SERVER 98873143b9aSmrg 98973143b9aSmrgstatic int 99073143b9aSmrgcomplete_network_count (void) 99173143b9aSmrg 99273143b9aSmrg{ 99373143b9aSmrg int count = 0; 99473143b9aSmrg int found_local = 0; 99573143b9aSmrg int i; 99673143b9aSmrg 99773143b9aSmrg /* 99873143b9aSmrg * For a complete network, we only need one LOCALCONN transport to work 99973143b9aSmrg */ 100073143b9aSmrg 100173143b9aSmrg for (i = 0; i < NUMTRANS; i++) 100273143b9aSmrg { 100373143b9aSmrg if (Xtransports[i].transport->flags & TRANS_ALIAS 100473143b9aSmrg || Xtransports[i].transport->flags & TRANS_NOLISTEN) 100573143b9aSmrg continue; 100673143b9aSmrg 100773143b9aSmrg if (Xtransports[i].transport->flags & TRANS_LOCAL) 100873143b9aSmrg found_local = 1; 100973143b9aSmrg else 101073143b9aSmrg count++; 101173143b9aSmrg } 101273143b9aSmrg 101373143b9aSmrg return (count + found_local); 101473143b9aSmrg} 101573143b9aSmrg 101673143b9aSmrg 10178d4c0f7bSmrg#ifdef XQUARTZ_EXPORTS_LAUNCHD_FD 10188d4c0f7bSmrgextern int xquartz_launchd_fd; 10198d4c0f7bSmrg#endif 102073143b9aSmrg 102173143b9aSmrgint 1022fe567363SmrgTRANS(MakeAllCOTSServerListeners) (char *port, int *partial, int *count_ret, 102373143b9aSmrg XtransConnInfo **ciptrs_ret) 102473143b9aSmrg 102573143b9aSmrg{ 102673143b9aSmrg char buffer[256]; /* ??? What size ?? */ 102773143b9aSmrg XtransConnInfo ciptr, temp_ciptrs[NUMTRANS]; 102873143b9aSmrg int status, i, j; 102973143b9aSmrg 103073143b9aSmrg#if defined(IPv6) && defined(AF_INET6) 103173143b9aSmrg int ipv6_succ = 0; 103273143b9aSmrg#endif 1033fe567363Smrg prmsg (2,"MakeAllCOTSServerListeners(%s,%p)\n", 1034fe567363Smrg port ? port : "NULL", ciptrs_ret); 103573143b9aSmrg 103673143b9aSmrg *count_ret = 0; 103773143b9aSmrg 10388d4c0f7bSmrg#ifdef XQUARTZ_EXPORTS_LAUNCHD_FD 10398d4c0f7bSmrg fprintf(stderr, "Launchd socket fd: %d\n", xquartz_launchd_fd); 10408d4c0f7bSmrg if(xquartz_launchd_fd != -1) { 10418d4c0f7bSmrg if((ciptr = TRANS(ReopenCOTSServer(TRANS_SOCKET_LOCAL_INDEX, 10428d4c0f7bSmrg xquartz_launchd_fd, getenv("DISPLAY"))))==NULL) 10438d4c0f7bSmrg fprintf(stderr,"Got NULL while trying to Reopen launchd port\n"); 1044fe567363Smrg else 10458d4c0f7bSmrg temp_ciptrs[(*count_ret)++] = ciptr; 10468d4c0f7bSmrg } 104773143b9aSmrg#endif 104873143b9aSmrg 104973143b9aSmrg for (i = 0; i < NUMTRANS; i++) 105073143b9aSmrg { 105173143b9aSmrg Xtransport *trans = Xtransports[i].transport; 105273143b9aSmrg unsigned int flags = 0; 105373143b9aSmrg 105473143b9aSmrg if (trans->flags&TRANS_ALIAS || trans->flags&TRANS_NOLISTEN) 105573143b9aSmrg continue; 105673143b9aSmrg 105773143b9aSmrg snprintf(buffer, sizeof(buffer), "%s/:%s", 105873143b9aSmrg trans->TransName, port ? port : ""); 105973143b9aSmrg 1060fe567363Smrg prmsg (5,"MakeAllCOTSServerListeners: opening %s\n", 1061fe567363Smrg buffer); 106273143b9aSmrg 106373143b9aSmrg if ((ciptr = TRANS(OpenCOTSServer(buffer))) == NULL) 106473143b9aSmrg { 106573143b9aSmrg if (trans->flags & TRANS_DISABLED) 106673143b9aSmrg continue; 106773143b9aSmrg 1068fe567363Smrg prmsg (1, 106973143b9aSmrg "MakeAllCOTSServerListeners: failed to open listener for %s\n", 1070fe567363Smrg trans->TransName); 107173143b9aSmrg continue; 107273143b9aSmrg } 107373143b9aSmrg#if defined(IPv6) && defined(AF_INET6) 107473143b9aSmrg if ((Xtransports[i].transport_id == TRANS_SOCKET_INET_INDEX 107573143b9aSmrg && ipv6_succ)) 107673143b9aSmrg flags |= ADDR_IN_USE_ALLOWED; 107773143b9aSmrg#endif 107873143b9aSmrg 107973143b9aSmrg if ((status = TRANS(CreateListener (ciptr, port, flags))) < 0) 108073143b9aSmrg { 108173143b9aSmrg if (status == TRANS_ADDR_IN_USE) 108273143b9aSmrg { 108373143b9aSmrg /* 108473143b9aSmrg * We failed to bind to the specified address because the 108573143b9aSmrg * address is in use. It must be that a server is already 108673143b9aSmrg * running at this address, and this function should fail. 108773143b9aSmrg */ 108873143b9aSmrg 1089fe567363Smrg prmsg (1, 1090fe567363Smrg "MakeAllCOTSServerListeners: server already running\n"); 109173143b9aSmrg 109273143b9aSmrg for (j = 0; j < *count_ret; j++) 109373143b9aSmrg TRANS(Close) (temp_ciptrs[j]); 109473143b9aSmrg 109573143b9aSmrg *count_ret = 0; 109673143b9aSmrg *ciptrs_ret = NULL; 109773143b9aSmrg *partial = 0; 109873143b9aSmrg return -1; 109973143b9aSmrg } 110073143b9aSmrg else 110173143b9aSmrg { 1102fe567363Smrg prmsg (1, 110373143b9aSmrg "MakeAllCOTSServerListeners: failed to create listener for %s\n", 1104fe567363Smrg trans->TransName); 110573143b9aSmrg 110673143b9aSmrg continue; 110773143b9aSmrg } 110873143b9aSmrg } 110973143b9aSmrg 111073143b9aSmrg#if defined(IPv6) && defined(AF_INET6) 111173143b9aSmrg if (Xtransports[i].transport_id == TRANS_SOCKET_INET6_INDEX) 111273143b9aSmrg ipv6_succ = 1; 111373143b9aSmrg#endif 1114fe567363Smrg 1115fe567363Smrg prmsg (5, 111673143b9aSmrg "MakeAllCOTSServerListeners: opened listener for %s, %d\n", 1117fe567363Smrg trans->TransName, ciptr->fd); 111873143b9aSmrg 111973143b9aSmrg temp_ciptrs[*count_ret] = ciptr; 112073143b9aSmrg (*count_ret)++; 112173143b9aSmrg } 112273143b9aSmrg 112373143b9aSmrg *partial = (*count_ret < complete_network_count()); 112473143b9aSmrg 1125fe567363Smrg prmsg (5, 112673143b9aSmrg "MakeAllCOTSServerListeners: partial=%d, actual=%d, complete=%d \n", 112773143b9aSmrg *partial, *count_ret, complete_network_count()); 112873143b9aSmrg 112973143b9aSmrg if (*count_ret > 0) 113073143b9aSmrg { 1131fe567363Smrg if ((*ciptrs_ret = malloc ( 113273143b9aSmrg *count_ret * sizeof (XtransConnInfo))) == NULL) 113373143b9aSmrg { 113473143b9aSmrg return -1; 113573143b9aSmrg } 113673143b9aSmrg 113773143b9aSmrg for (i = 0; i < *count_ret; i++) 113873143b9aSmrg { 113973143b9aSmrg (*ciptrs_ret)[i] = temp_ciptrs[i]; 114073143b9aSmrg } 114173143b9aSmrg } 114273143b9aSmrg else 114373143b9aSmrg *ciptrs_ret = NULL; 1144fe567363Smrg 114573143b9aSmrg return 0; 114673143b9aSmrg} 114773143b9aSmrg 114873143b9aSmrgint 1149fe567363SmrgTRANS(MakeAllCLTSServerListeners) (char *port, int *partial, int *count_ret, 115073143b9aSmrg XtransConnInfo **ciptrs_ret) 115173143b9aSmrg 115273143b9aSmrg{ 115373143b9aSmrg char buffer[256]; /* ??? What size ?? */ 115473143b9aSmrg XtransConnInfo ciptr, temp_ciptrs[NUMTRANS]; 115573143b9aSmrg int status, i, j; 115673143b9aSmrg 1157fe567363Smrg prmsg (2,"MakeAllCLTSServerListeners(%s,%p)\n", 1158fe567363Smrg port ? port : "NULL", ciptrs_ret); 115973143b9aSmrg 116073143b9aSmrg *count_ret = 0; 116173143b9aSmrg 116273143b9aSmrg for (i = 0; i < NUMTRANS; i++) 116373143b9aSmrg { 116473143b9aSmrg Xtransport *trans = Xtransports[i].transport; 116573143b9aSmrg 116673143b9aSmrg if (trans->flags&TRANS_ALIAS || trans->flags&TRANS_NOLISTEN) 116773143b9aSmrg continue; 116873143b9aSmrg 116973143b9aSmrg snprintf(buffer, sizeof(buffer), "%s/:%s", 117073143b9aSmrg trans->TransName, port ? port : ""); 117173143b9aSmrg 1172fe567363Smrg prmsg (5,"MakeAllCLTSServerListeners: opening %s\n", 1173fe567363Smrg buffer); 117473143b9aSmrg 117573143b9aSmrg if ((ciptr = TRANS(OpenCLTSServer (buffer))) == NULL) 117673143b9aSmrg { 1177fe567363Smrg prmsg (1, 117873143b9aSmrg "MakeAllCLTSServerListeners: failed to open listener for %s\n", 1179fe567363Smrg trans->TransName); 118073143b9aSmrg continue; 118173143b9aSmrg } 118273143b9aSmrg 118373143b9aSmrg if ((status = TRANS(CreateListener (ciptr, port, 0))) < 0) 118473143b9aSmrg { 118573143b9aSmrg if (status == TRANS_ADDR_IN_USE) 118673143b9aSmrg { 118773143b9aSmrg /* 118873143b9aSmrg * We failed to bind to the specified address because the 118973143b9aSmrg * address is in use. It must be that a server is already 119073143b9aSmrg * running at this address, and this function should fail. 119173143b9aSmrg */ 119273143b9aSmrg 1193fe567363Smrg prmsg (1, 1194fe567363Smrg "MakeAllCLTSServerListeners: server already running\n"); 119573143b9aSmrg 119673143b9aSmrg for (j = 0; j < *count_ret; j++) 119773143b9aSmrg TRANS(Close) (temp_ciptrs[j]); 119873143b9aSmrg 119973143b9aSmrg *count_ret = 0; 120073143b9aSmrg *ciptrs_ret = NULL; 120173143b9aSmrg *partial = 0; 120273143b9aSmrg return -1; 120373143b9aSmrg } 120473143b9aSmrg else 120573143b9aSmrg { 1206fe567363Smrg prmsg (1, 120773143b9aSmrg "MakeAllCLTSServerListeners: failed to create listener for %s\n", 1208fe567363Smrg trans->TransName); 120973143b9aSmrg 121073143b9aSmrg continue; 121173143b9aSmrg } 121273143b9aSmrg } 121373143b9aSmrg 1214fe567363Smrg prmsg (5, 121573143b9aSmrg "MakeAllCLTSServerListeners: opened listener for %s, %d\n", 1216fe567363Smrg trans->TransName, ciptr->fd); 121773143b9aSmrg temp_ciptrs[*count_ret] = ciptr; 121873143b9aSmrg (*count_ret)++; 121973143b9aSmrg } 122073143b9aSmrg 122173143b9aSmrg *partial = (*count_ret < complete_network_count()); 122273143b9aSmrg 1223fe567363Smrg prmsg (5, 122473143b9aSmrg "MakeAllCLTSServerListeners: partial=%d, actual=%d, complete=%d \n", 122573143b9aSmrg *partial, *count_ret, complete_network_count()); 122673143b9aSmrg 122773143b9aSmrg if (*count_ret > 0) 122873143b9aSmrg { 1229fe567363Smrg if ((*ciptrs_ret = malloc ( 123073143b9aSmrg *count_ret * sizeof (XtransConnInfo))) == NULL) 123173143b9aSmrg { 123273143b9aSmrg return -1; 123373143b9aSmrg } 123473143b9aSmrg 123573143b9aSmrg for (i = 0; i < *count_ret; i++) 123673143b9aSmrg { 123773143b9aSmrg (*ciptrs_ret)[i] = temp_ciptrs[i]; 123873143b9aSmrg } 123973143b9aSmrg } 124073143b9aSmrg else 124173143b9aSmrg *ciptrs_ret = NULL; 1242fe567363Smrg 124373143b9aSmrg return 0; 124473143b9aSmrg} 124573143b9aSmrg 124673143b9aSmrg#endif /* TRANS_SERVER */ 124773143b9aSmrg 124873143b9aSmrg 124973143b9aSmrg 125073143b9aSmrg/* 125173143b9aSmrg * These routines are not part of the X Transport Interface, but they 125273143b9aSmrg * may be used by it. 125373143b9aSmrg */ 125473143b9aSmrg 125573143b9aSmrg 1256fe567363Smrg#if defined(SYSV) && defined(__i386__) && !defined(__SCO__) && !defined(sun) || defined(WIN32) 125773143b9aSmrg 125873143b9aSmrg/* 125973143b9aSmrg * emulate readv 126073143b9aSmrg */ 126173143b9aSmrg 126273143b9aSmrgstatic int TRANS(ReadV) (XtransConnInfo ciptr, struct iovec *iov, int iovcnt) 126373143b9aSmrg 126473143b9aSmrg{ 126573143b9aSmrg int i, len, total; 126673143b9aSmrg char *base; 126773143b9aSmrg 126873143b9aSmrg ESET(0); 126973143b9aSmrg for (i = 0, total = 0; i < iovcnt; i++, iov++) { 127073143b9aSmrg len = iov->iov_len; 127173143b9aSmrg base = iov->iov_base; 127273143b9aSmrg while (len > 0) { 127373143b9aSmrg register int nbytes; 127473143b9aSmrg nbytes = TRANS(Read) (ciptr, base, len); 127573143b9aSmrg if (nbytes < 0 && total == 0) return -1; 127673143b9aSmrg if (nbytes <= 0) return total; 127773143b9aSmrg ESET(0); 127873143b9aSmrg len -= nbytes; 127973143b9aSmrg total += nbytes; 128073143b9aSmrg base += nbytes; 128173143b9aSmrg } 128273143b9aSmrg } 128373143b9aSmrg return total; 128473143b9aSmrg} 128573143b9aSmrg 128673143b9aSmrg#endif /* SYSV && __i386__ || WIN32 || __sxg__ */ 128773143b9aSmrg 1288fe567363Smrg#if defined(SYSV) && defined(__i386__) && !defined(__SCO__) && !defined(sun) || defined(WIN32) 128973143b9aSmrg 129073143b9aSmrg/* 129173143b9aSmrg * emulate writev 129273143b9aSmrg */ 129373143b9aSmrg 129473143b9aSmrgstatic int TRANS(WriteV) (XtransConnInfo ciptr, struct iovec *iov, int iovcnt) 129573143b9aSmrg 129673143b9aSmrg{ 129773143b9aSmrg int i, len, total; 129873143b9aSmrg char *base; 129973143b9aSmrg 130073143b9aSmrg ESET(0); 130173143b9aSmrg for (i = 0, total = 0; i < iovcnt; i++, iov++) { 130273143b9aSmrg len = iov->iov_len; 130373143b9aSmrg base = iov->iov_base; 130473143b9aSmrg while (len > 0) { 130573143b9aSmrg register int nbytes; 130673143b9aSmrg nbytes = TRANS(Write) (ciptr, base, len); 130773143b9aSmrg if (nbytes < 0 && total == 0) return -1; 130873143b9aSmrg if (nbytes <= 0) return total; 130973143b9aSmrg ESET(0); 131073143b9aSmrg len -= nbytes; 131173143b9aSmrg total += nbytes; 131273143b9aSmrg base += nbytes; 131373143b9aSmrg } 131473143b9aSmrg } 131573143b9aSmrg return total; 131673143b9aSmrg} 131773143b9aSmrg 131873143b9aSmrg#endif /* SYSV && __i386__ || WIN32 || __sxg__ */ 131973143b9aSmrg 132073143b9aSmrg 1321e8a71cdfSmrg#if defined(_POSIX_SOURCE) || defined(USG) || defined(SVR4) || defined(__SVR4) || defined(__SCO__) 132273143b9aSmrg#ifndef NEED_UTSNAME 132373143b9aSmrg#define NEED_UTSNAME 132473143b9aSmrg#endif 132573143b9aSmrg#include <sys/utsname.h> 132673143b9aSmrg#endif 132773143b9aSmrg 132873143b9aSmrg/* 132973143b9aSmrg * TRANS(GetHostname) - similar to gethostname but allows special processing. 133073143b9aSmrg */ 133173143b9aSmrg 133273143b9aSmrgint TRANS(GetHostname) (char *buf, int maxlen) 133373143b9aSmrg 133473143b9aSmrg{ 133573143b9aSmrg int len; 133673143b9aSmrg 133773143b9aSmrg#ifdef NEED_UTSNAME 133873143b9aSmrg struct utsname name; 133973143b9aSmrg 134073143b9aSmrg uname (&name); 134173143b9aSmrg len = strlen (name.nodename); 134273143b9aSmrg if (len >= maxlen) len = maxlen - 1; 134373143b9aSmrg strncpy (buf, name.nodename, len); 134473143b9aSmrg buf[len] = '\0'; 134573143b9aSmrg#else 134673143b9aSmrg buf[0] = '\0'; 134773143b9aSmrg (void) gethostname (buf, maxlen); 134873143b9aSmrg buf [maxlen - 1] = '\0'; 134973143b9aSmrg len = strlen(buf); 135073143b9aSmrg#endif /* NEED_UTSNAME */ 135173143b9aSmrg return len; 135273143b9aSmrg} 1353