diff options
Diffstat (limited to 'libX11/src/ConnDis.c')
-rw-r--r-- | libX11/src/ConnDis.c | 230 |
1 files changed, 104 insertions, 126 deletions
diff --git a/libX11/src/ConnDis.c b/libX11/src/ConnDis.c index e61e0f05b..0ecd71c37 100644 --- a/libX11/src/ConnDis.c +++ b/libX11/src/ConnDis.c @@ -1,7 +1,7 @@ /* $XdotOrg: lib/X11/src/ConnDis.c,v 1.10 2005-07-03 07:00:55 daniels Exp $ */ /* $Xorg: ConnDis.c,v 1.8 2001/02/09 02:03:31 xorgcvs Exp $ */ /* - + Copyright 1989, 1998 The Open Group Permission to use, copy, modify, distribute, and sell this software and its @@ -27,7 +27,7 @@ in this Software without prior written authorization from The Open Group. */ /* $XFree86: xc/lib/X11/ConnDis.c,v 3.28 2003/12/02 23:33:17 herrb Exp $ */ -/* +/* * This file contains operating system dependencies. */ @@ -58,10 +58,6 @@ in this Software without prior written authorization from The Open Group. #define X_CONNECTION_RETRIES 5 #endif -#ifdef LOCALCONN -#include <sys/utsname.h> -#endif - #include "Xintconn.h" /* prototypes */ @@ -77,7 +73,7 @@ static void GetAuthorization( int *auth_datalenp); /* functions */ -static char *copystring (char *src, int len) +static char *copystring (const char *src, int len) { char *dst = Xmalloc (len + 1); @@ -89,8 +85,19 @@ static char *copystring (char *src, int len) return dst; } +#define Xstrdup(s) copystring(s, strlen(s)) -/* +#ifdef TCPCONN +# define TCP_TRANS "tcp" +#endif +#ifdef UNIXCONN +# define UNIX_TRANS "unix" +#endif +#if defined(LOCALCONN) || defined(OS2PIPECONN) +# define LOCAL_TRANS "local" +#endif + +/* * Attempts to connect to server, given display name. Returns file descriptor * (network socket) or -1 if connection fails. Display names may be of the * following format: @@ -107,7 +114,7 @@ static char *copystring (char *src, int len) * by IETF RFC 2732. * * If no hostname and no protocol is specified, the string is interpreted - * as the most efficient local connection to a server on the same machine. + * as the most efficient local connection to a server on the same machine. * This is usually: * * o shared memory @@ -151,17 +158,11 @@ _X11TransConnectDisplay ( char* address = addrbuf; XtransConnInfo trans_conn = NULL; /* transport connection object */ int connect_stat; -#if defined(LOCALCONN) || defined(TCPCONN) +#if defined(LOCALCONN) || defined(UNIXCONN) || defined(TCPCONN) Bool reset_hostname = False; /* Reset hostname? */ -#endif -#ifdef LOCALCONN - struct utsname sys; -# ifdef UNIXCONN - Bool try_unix_socket = False; /* Try unix if local fails */ -# endif -#endif -#ifdef TCPCONN - char *tcphostname = NULL; /* A place to save hostname pointer */ + char *original_hostname = NULL; + int local_transport_index = -1; + const char *local_transport[] = { LOCAL_TRANSPORT_LIST, NULL }; #endif p = display_name; @@ -170,7 +171,7 @@ _X11TransConnectDisplay ( saddr = NULL; /* - * Step 0, find the protocol. This is delimited by the optional + * Step 0, find the protocol. This is delimited by the optional * slash ('/'). */ for (lastp = p; *p && *p != ':' && *p != '/'; p++) ; @@ -187,7 +188,7 @@ _X11TransConnectDisplay ( /* * Step 1, find the hostname. This is delimited by either one colon, * or two colons in the case of DECnet (DECnet Phase V allows a single - * colon in the hostname). (See note above regarding IPv6 numeric + * colon in the hostname). (See note above regarding IPv6 numeric * addresses with triple colons or [] brackets.) */ @@ -199,7 +200,7 @@ _X11TransConnectDisplay ( if (!lastc) return NULL; /* must have a colon */ - if ((lastp != lastc) && (*(lastc - 1) == ':') + if ((lastp != lastc) && (*(lastc - 1) == ':') #if defined(IPv6) && defined(AF_INET6) && ( ((lastc - 1) == lastp) || (*(lastc - 2) != ':')) #endif @@ -227,38 +228,23 @@ _X11TransConnectDisplay ( p = lastc; -#ifdef LOCALCONN +#if defined(LOCALCONN) || defined(UNIXCONN) || defined(TCPCONN) /* check if phostname == localnodename AND protocol not specified */ - if (!pprotocol && (!phostname || (phostname && uname(&sys) >= 0 && - !strncmp(phostname, sys.nodename, - (strlen(sys.nodename) < strlen(phostname) ? - strlen(phostname) : strlen(sys.nodename)))))) - { - /* - * We'll first attempt to connect using the local transport. If - * that fails, we'll try again using the Unix socket transport. If - * this fails (which is the case if sshd X protocol forwarding is - * being used), retry using tcp and this hostname. - */ -#ifdef UNIXCONN - try_unix_socket = True; -#endif -#ifdef TCPCONN - if (phostname) - tcphostname = copystring(phostname, strlen(phostname)); - else - tcphostname = copystring("localhost", 9); -#endif - if (!phostname) + if (!pprotocol && phostname) { + char localhostname[256]; + + if ((_XGetHostname (localhostname, sizeof localhostname) > 0) + && (strcmp(phostname, localhostname) == 0)) { + original_hostname = phostname; + phostname = NULL; reset_hostname = True; - Xfree (phostname); - phostname = copystring ("unix", 4); + } } #endif /* - * Step 2, find the display number. This field is required and is + * Step 2, find the display number. This field is required and is * delimited either by a nul or a period, depending on whether or not * a screen number is present. */ @@ -272,7 +258,7 @@ _X11TransConnectDisplay ( /* - * Step 3, find the screen number. This field is optional. It is + * Step 3, find the screen number. This field is optional. It is * present only if the display number was followed by a period (which * we've already verified is the only non-nul character). */ @@ -295,72 +281,51 @@ _X11TransConnectDisplay ( * idisplay display number * iscreen screen number * dnet DECnet boolean - * - * We can now decide which transport to use based on the ConnectionFlags - * build parameter the hostname string. If phostname is NULL or equals - * the string "local", then choose the best transport. If phostname - * is "unix", then choose BSD UNIX domain sockets (if configured). + * + * We can now decide which transport to use based on the defined + * connection types and the hostname string. + * If phostname & pprotocol are NULL, then choose the best transport. + * If phostname is "unix" & pprotocol is NULL, then choose UNIX domain + * sockets (if configured). */ #if defined(TCPCONN) || defined(UNIXCONN) || defined(LOCALCONN) || defined(MNX_TCPCONN) || defined(OS2PIPECONN) if (!pprotocol) { -#ifdef HAVE_LAUNCHD - if (!phostname || phostname[0]=='/') { -#else - if (!phostname) { -#endif -#if defined(UNIXCONN) || defined(LOCALCONN) || defined(OS2PIPECONN) - pprotocol = copystring ("local", 5); -#if defined(TCPCONN) - tcphostname = copystring("localhost", 9); +#if defined(UNIXCONN) + if (phostname && (strcmp (phostname, "unix") == 0)) { + Xfree(pprotocol); + pprotocol = copystring ("unix", 4); + } else #endif +#ifdef HAVE_LAUNCHD + if (phostname && phostname[0]=='/') { + pprotocol = copystring ("local", 5); } - else - { #endif + if (!phostname) + { + if (local_transport[0] != NULL) { + pprotocol = Xstrdup(local_transport[0]); + local_transport_index = 0; + } + } + + if (!pprotocol) { /* if still not found one, tcp is our last resort */ pprotocol = copystring ("tcp", 3); } } #endif -#if defined(UNIXCONN) || defined(LOCALCONN) || defined(OS2PIPECONN) - /* - * Now that the defaults have been established, see if we have any - * special names that we have to override: - * - * :N => if UNIXCONN then unix-domain-socket - * ::N => if UNIXCONN then unix-domain-socket - * unix:N => if UNIXCONN then unix-domain-socket - * - * Note that if UNIXCONN isn't defined, then we can use the default - * transport connection function set above. - */ - if (!phostname) { -#ifdef apollo - ; /* Unix domain sockets are *really* bad on apollos */ -#else - if( pprotocol ) Xfree(pprotocol); - pprotocol = copystring ("local", 5); -#endif - } - else if (strcmp (phostname, "unix") == 0) { - if( pprotocol ) Xfree(pprotocol); - pprotocol = copystring ("local", 5); - } -#endif - -#if defined(TCPCONN) connect: -#endif /* * This seems kind of backwards, but we need to put the protocol, * host, and port back together to pass to _X11TransOpenCOTSClient(). */ { - int olen = 3 + (pprotocol ? strlen(pprotocol) : 0) + - (phostname ? strlen(phostname) : 0) + + int olen = 3 + (pprotocol ? strlen(pprotocol) : 0) + + (phostname ? strlen(phostname) : 0) + (pdpynum ? strlen(pdpynum) : 0); if (olen > sizeof addrbuf) address = Xmalloc (olen); } @@ -435,14 +400,15 @@ _X11TransConnectDisplay ( * * [host] : [:] dpy . scr \0 */ -#if defined(LOCALCONN) || defined(TCPCONN) +#if defined(LOCALCONN) || defined(TCPCONN) || defined(UNIXCONN) /* * If we computed the host name, get rid of it so that * XDisplayString() and XDisplayName() agree. - */ - if (reset_hostname) { + */ + if (reset_hostname && (phostname != original_hostname)) { Xfree (phostname); - phostname = NULL; + phostname = original_hostname; + original_hostname = NULL; } #endif len = ((phostname ? strlen(phostname) : 0) + 1 + (dnet ? 1 : 0) + @@ -451,7 +417,7 @@ _X11TransConnectDisplay ( if (!*fullnamep) goto bad; #ifdef HAVE_LAUNCHD - if (phostname && strlen(phostname) > 11 && !strncmp(phostname, "/tmp/launch", 11)) + if (phostname && strlen(phostname) > 11 && !strncmp(phostname, "/tmp/launch", 11)) sprintf (*fullnamep, "%s%s%d", (phostname ? phostname : ""), (dnet ? "::" : ":"), @@ -469,8 +435,8 @@ _X11TransConnectDisplay ( if (phostname) Xfree (phostname); if (pdpynum) Xfree (pdpynum); if (pscrnum) Xfree (pscrnum); -#ifdef TCPCONN - if (tcphostname) Xfree (tcphostname); +#if defined(LOCALCONN) || defined(UNIXCONN) || defined(TCPCONN) + if (original_hostname) Xfree (original_hostname); #endif GetAuthorization(trans_conn, family, (char *) saddr, saddrlen, idisplay, @@ -488,24 +454,36 @@ _X11TransConnectDisplay ( if (phostname) Xfree (phostname); if (address && address != addrbuf) { Xfree(address); address = addrbuf; } -#if defined(LOCALCONN) && defined(UNIXCONN) - if (try_unix_socket) { - pprotocol = copystring ("unix", 4); - phostname = NULL; - try_unix_socket = False; /* Do this only once */ - goto connect; - } -#endif - -#if defined(TCPCONN) - if (tcphostname) { - pprotocol = copystring("tcp", 3); - phostname = tcphostname; - tcphostname = NULL; - reset_hostname = True; - goto connect; +#if defined(LOCALCONN) || defined(UNIXCONN) || defined(TCPCONN) + /* If connecting to the local machine, and we failed, try again with + * the next transport type available, if there is one. + */ + if (local_transport_index >= 0) { + if (local_transport[++local_transport_index] != NULL) { + pprotocol = Xstrdup(local_transport[local_transport_index]); +#ifdef TCPCONN + if (strcmp(pprotocol, "tcp") == 0) { + if (original_hostname != NULL) { + phostname = original_hostname; + original_hostname = NULL; + } else { + phostname = copystring("localhost", 9); + } + } else +#endif /* TCPCONN */ + { + if ((phostname != NULL) && (original_hostname == NULL)) { + original_hostname = phostname; + } + phostname = NULL; + } + goto connect; + } } -#endif + + /* No more to try, we've failed all available local transports */ + if (original_hostname) Xfree(original_hostname); +#endif /* LOCALCONN || UNIXCONN || TCPCONN */ if (pdpynum) Xfree (pdpynum); if (pscrnum) Xfree (pscrnum); @@ -552,7 +530,7 @@ int _XConnectDisplay ( * * *****************************************************************************/ -/* +/* * Disconnect from server. */ @@ -688,7 +666,7 @@ static _Xconst int default_xauth_lengths[] = { }; #define NUM_DEFAULT_AUTH (sizeof (default_xauth_names) / sizeof (default_xauth_names[0])) - + static char **xauth_names = default_xauth_names; static _Xconst int *xauth_lengths = default_xauth_lengths; @@ -1137,18 +1115,18 @@ GetAuthorization( { unsigned char ipv4mappedprefix[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xff, 0xff }; - - /* In the case of v4 mapped addresses send the v4 + + /* In the case of v4 mapped addresses send the v4 part of the address - addr is already in network byte order */ if (memcmp((char*)addr+8, ipv4mappedprefix, 12) == 0) { for (i = 20 ; i < 24; i++) xdmcp_data[j++] = ((char *)addr)[i]; - + /* Port number */ for (i=2; i<4; i++) xdmcp_data[j++] = ((char *)addr)[i]; } else { - /* Fake data to keep the data aligned. Otherwise the + /* Fake data to keep the data aligned. Otherwise the the server will bail about incorrect timing data */ for (i = 0; i < 6; i++) { xdmcp_data[j++] = 0; @@ -1172,14 +1150,14 @@ GetAuthorization( unsigned short the_port; unsigned long the_utime; struct timeval tp; - + X_GETTIMEOFDAY(&tp); _XLockMutex(_Xglobal_lock); the_addr = unix_addr--; _XUnlockMutex(_Xglobal_lock); the_utime = (unsigned long) tp.tv_usec; the_port = getpid (); - + xdmcp_data[j++] = (the_utime >> 24) & 0xFF; xdmcp_data[j++] = (the_utime >> 16) & 0xFF; xdmcp_data[j++] = ((the_utime >> 8) & 0xF0) |