aboutsummaryrefslogtreecommitdiff
path: root/libX11/src/ConnDis.c
diff options
context:
space:
mode:
Diffstat (limited to 'libX11/src/ConnDis.c')
-rw-r--r--libX11/src/ConnDis.c230
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)