[PATCH libxtrans] Add TRANS(Listen) function to re-enable specific listen sockets

Alan Coopersmith alan.coopersmith at oracle.com
Tue Sep 23 23:33:10 PDT 2014


I'd started working on a similar patch series last year, but never finished
it after getting sidetracked by our security fixes - for whatever it's worth,
I've attached the work-in-progress I had - I don't even remember at this
point what was still left to do.

-- 
	-Alan Coopersmith-              alan.coopersmith at oracle.com
	 Oracle Solaris Engineering - http://blogs.oracle.com/alanc
-------------- next part --------------
From ffafcb8745e430e7a09f967247da39aafaca1df6 Mon Sep 17 00:00:00 2001
From: Alan Coopersmith <alan.coopersmith at oracle.com>
Date: Sun, 27 Jan 2013 23:47:55 -0800
Subject: [PATCH:libxtrans 1/2] Set TRANS_LOCAL flag for "unix" and "local"
 socket families

Was previously only set for LOCALCONN transports

Signed-off-by: Alan Coopersmith <alan.coopersmith at oracle.com>
---
 Xtranssock.c   |   10 ++++------
 doc/xtrans.xml |    6 +++++-
 2 files changed, 9 insertions(+), 7 deletions(-)

diff --git a/Xtranssock.c b/Xtranssock.c
index 23150b2..4ea58dc 100644
--- a/Xtranssock.c
+++ b/Xtranssock.c
@@ -2582,10 +2582,9 @@ Xtransport	TRANS(SocketLocalFuncs) = {
 	/* Socket Interface */
 	"local",
 #ifdef HAVE_ABSTRACT_SOCKETS
-	TRANS_ABSTRACT,
-#else
-	0,
+	TRANS_ABSTRACT |
 #endif
+	TRANS_LOCAL,
 #ifdef TRANS_CLIENT
 	TRANS(SocketOpenCOTSClient),
 #endif /* TRANS_CLIENT */
@@ -2634,10 +2633,9 @@ Xtransport	TRANS(SocketUNIXFuncs) = {
 	/* Socket Interface */
 	"unix",
 #if !defined(LOCALCONN) && !defined(HAVE_ABSTRACT_SOCKETS)
-        TRANS_ALIAS,
-#else
-	0,
+	TRANS_ALIAS |
 #endif
+	TRANS_LOCAL,
 #ifdef TRANS_CLIENT
 	TRANS(SocketOpenCOTSClient),
 #endif /* TRANS_CLIENT */
diff --git a/doc/xtrans.xml b/doc/xtrans.xml
index 59daa3f..d9dba6a 100644
--- a/doc/xtrans.xml
+++ b/doc/xtrans.xml
@@ -298,7 +298,11 @@ not be used to create a listener.
   <varlistentry>
     <term><symbol>TRANS_LOCAL</symbol></term>
     <listitem><para>
-indicates that this is a <symbol>LOCALCONN</symbol> transport.
+in Xtrans 1.3 and later, indicates that this transport can only open
+connections to the local host, either via LOCALCONN or other non-networked
+methods such as a Unix domain socket or abstract socket.
+(In Xtrans 1.2 and earlier, this was limited to indicating that this is a
+<symbol>LOCALCONN</symbol> transport.)
     </para></listitem>
   </varlistentry>
   <varlistentry>
-- 
1.7.9.2

-------------- next part --------------
From f7403568d69015a1184a71a2624ce2718f4cef87 Mon Sep 17 00:00:00 2001
From: Alan Coopersmith <alan.coopersmith at oracle.com>
Date: Sun, 27 Jan 2013 23:55:35 -0800
Subject: [PATCH:libxtrans 2/2] Create public listener management API to
 replace undocumented TRANS(NoListen)

Allows enabling or disabling listening on a given transport type, and
querying current listening status.

Provides functions to operate on aliases and sets of transport types,
including "all", "all-local", and "all-remote".

Maintains backwards compatibility with TRANS(NoListen).

Bumps xtrans version to 1.3.99.0 to allow other packages to
depend on new APIs via pkg-config version checks.

Signed-off-by: Alan Coopersmith <alan.coopersmith at oracle.com>
---
 COPYING        |    3 +-
 Xtrans.c       |  182 ++++++++++++++++++++++++++++++++++++++++++++++++++------
 Xtrans.h       |   39 ++++++++++++
 configure.ac   |    2 +-
 doc/xtrans.xml |  176 +++++++++++++++++++++++++++++++++++++++++++++++++++++-
 5 files changed, 382 insertions(+), 20 deletions(-)

diff --git a/COPYING b/COPYING
index d2dbc2c..820f517 100644
--- a/COPYING
+++ b/COPYING
@@ -48,7 +48,8 @@ CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 
 ______________________________________________________________________________
 
-Copyright (c) 2002, 2005, Oracle and/or its affiliates. All rights reserved.
+Copyright (c) 2002, 2005, 2013, Oracle and/or its affiliates.
+All rights reserved.
 
 Permission is hereby granted, free of charge, to any person obtaining a
 copy of this software and associated documentation files (the "Software"),
diff --git a/Xtrans.c b/Xtrans.c
index 7c7967f..ac3e8af 100644
--- a/Xtrans.c
+++ b/Xtrans.c
@@ -47,6 +47,30 @@ from The Open Group.
  * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  */
 
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+
 #include <ctype.h>
 
 /*
@@ -737,38 +761,162 @@ TRANS(SetOption) (XtransConnInfo ciptr, int option, int arg)
 #ifdef TRANS_SERVER
 
 int
+TRANS(ForEachTransport)(const char *filter, TransportCallbackProc call,
+    void *closure)
+
+{
+    enum { NO_SET = 0, ALL, ALL_REMOTE, ALL_LOCAL } set = NO_SET;
+    int ret = 0;
+    int i;
+    Xtransport *trans;
+
+    /* Accept "all", "all-remote", and "all-local" as aliases for the
+       sets of all transports, all without TRANS_LOCAL set in flags,
+       and all with TRANS_LOCAL set in flags */
+    if (strcmp(filter, "all") == 0)
+        set = ALL;
+    else if (strcmp(filter, "all-remote") == 0)
+        set = ALL_REMOTE;
+    else if (strcmp(filter, "all-local") == 0)
+        set = ALL_LOCAL;
+    /* Accept "all-sets" as a special keyword to get a list of the aliases
+       for the sets of transports */
+    else if (strcmp(filter, "all-sets") == 0)
+    {
+        ret |= call("all", closure);
+        ret |= call("all-local", closure);
+        ret |= call("all-remote", closure);
+        return ret;
+    }
+    else
+    {
+        if ((trans = TRANS(SelectTransport)(filter)) == NULL)
+        {
+            prmsg (1,"TransForEachTransport: unable to find transport: %s\n",
+                   filter);
+            return -1;
+        }
+        if (trans->flags & TRANS_ALIAS) {
+            if (trans->nolisten) {
+                for (i = 0; trans->nolisten[i] != NULL; i++) {
+                    ret |= call(trans->nolisten[i], closure);
+                }
+            }
+        }
+        ret |= call(trans->TransName, closure);
+        return ret;
+    }
+
+    for (i = 0; i < NUMTRANS; i++)
+    {
+        trans = Xtransports[i].transport;
+        /* filter out non-matching transports, then fall through
+           to callback for the rest */
+        switch (set) {
+        case NO_SET:
+            /* shouldn't be possible, but gcc warns if case is not handled */
+            return -1;
+        case ALL:
+            /* always fall through to callback */
+            break;
+        case ALL_REMOTE:
+            if ((trans->flags & TRANS_LOCAL) != 0)
+                continue; /* Skip local */
+            break;
+        case ALL_LOCAL:
+            if ((trans->flags & TRANS_LOCAL) == 0)
+                continue; /* Skip non-local */
+            break;
+        }
+        ret |= call(trans->TransName, closure);
+    }
+    return ret;
+}
+
+int
 TRANS(CreateListener) (XtransConnInfo ciptr, char *port, unsigned int flags)
 
 {
     return ciptr->transptr->CreateListener (ciptr, port, flags);
 }
 
+/* maintained for backwards compatibility */
 int
 TRANS(NoListen) (const char * protocol)
 
 {
-   Xtransport *trans;
-   int i = 0, ret = 0;
+    int enabled = False;
+    return TRANS(ForEachTransport)(protocol, TRANS(SetListenProc), &enabled);
+}
 
-   if ((trans = TRANS(SelectTransport)(protocol)) == NULL)
-   {
-	prmsg (1,"TransNoListen: unable to find transport: %s\n",
-	       protocol);
+/* Suitable for passing to ForEachTransport */
+int
+TRANS(SetListenProc) (const char * protocol, void *closure)
+
+{
+    return TRANS(SetListen) (protocol, *(int *) closure);
+}
+
+int
+TRANS(SetListen) (const char * protocol, Bool enabled)
+
+{
+    Xtransport *trans;
+
+    prmsg (2, "SetListen(%s, %s)\n", protocol, enabled ? "True" : "False");
 
+    if ((trans = TRANS(SelectTransport)(protocol)) == NULL)
+    {
+	prmsg (1, "TransSetListen: unable to find transport: %s\n", protocol);
 	return -1;
-   }
-   if (trans->flags & TRANS_ALIAS) {
-       if (trans->nolisten)
-	   while (trans->nolisten[i]) {
-	       ret |= TRANS(NoListen)(trans->nolisten[i]);
-	       i++;
-       }
-   }
-
-   trans->flags |= TRANS_NOLISTEN;
-   return ret;
+    }
+
+    if (enabled)
+        trans->flags &= ~TRANS_NOLISTEN;
+    else
+        trans->flags |= TRANS_NOLISTEN;
+    return 0;
 }
 
+Bool
+TRANS(GetListen) (const char * protocol)
+
+{
+    Xtransport *trans;
+
+    prmsg (2, "GetListen(%s)\n", protocol);
+
+    if ((trans = TRANS(SelectTransport)(protocol)) == NULL)
+    {
+	prmsg (1, "TransGetListen: unable to find transport: %s\n", protocol);
+	return -1;
+    }
+
+    return (trans->flags & TRANS_NOLISTEN) ? False : True;
+}
+
+const char **
+TRANS(GetListenAliases) (const char * protocol)
+
+{
+    Xtransport *trans;
+
+    prmsg (2, "GetListenAliases(%s)\n", protocol);
+
+    if ((trans = TRANS(SelectTransport)(protocol)) == NULL)
+    {
+        prmsg (1, "TransGetListenAliases: unable to find transport: %s\n",
+               protocol);
+	return NULL;
+    }
+
+    if (trans->flags & TRANS_ALIAS)
+        return trans->nolisten;
+    else
+        return NULL;
+}
+
+
 int
 TRANS(ResetListener) (XtransConnInfo ciptr)
 
diff --git a/Xtrans.h b/Xtrans.h
index 53b8b62..d174421 100644
--- a/Xtrans.h
+++ b/Xtrans.h
@@ -57,6 +57,16 @@ from The Open Group.
 #include <sys/socket.h>
 #endif
 
+#ifndef Bool
+#define Bool int
+#endif
+#ifndef True
+#define True 1
+#endif
+#ifndef False
+#define False 0
+#endif
+
 #ifdef __clang__
 /* Not all clients make use of all provided statics */
 #pragma clang diagnostic push
@@ -295,6 +305,17 @@ int TRANS(SetOption)(
     int			/* arg */
 );
 
+typedef int (*TransportCallbackProc)(
+    const char * /* transport name */,
+    void *		/* closure */
+);
+
+_X_HIDDEN int TRANS(ForEachTransport)(
+    const char *	/* filter */,
+    TransportCallbackProc /* call */,
+    void *		/* closure */
+);
+
 #ifdef TRANS_SERVER
 
 int TRANS(CreateListener)(
@@ -307,6 +328,24 @@ int TRANS(NoListen) (
     const char*         /* protocol*/
 );
 
+_X_HIDDEN int TRANS(SetListen) (
+    const char *,	/* protocol */
+    Bool		/* enabled */
+);
+
+_X_HIDDEN int TRANS(SetListenProc) (
+    const char *,	/* protocol */
+    void *		/* closure - pointer to int enabled value */
+);
+
+_X_HIDDEN Bool TRANS(GetListen) (
+    const char *	/* protocol */
+);
+
+_X_HIDDEN const char ** TRANS(GetListenAliases) (
+    const char *	/* protocol */
+);
+
 int TRANS(ResetListener)(
     XtransConnInfo	/* ciptr */
 );
diff --git a/configure.ac b/configure.ac
index 8c3aa3d..137370a 100644
--- a/configure.ac
+++ b/configure.ac
@@ -21,7 +21,7 @@
 
 # Initialize Autoconf
 AC_PREREQ([2.60])
-AC_INIT([xtrans], [1.3.0],
+AC_INIT([xtrans], [1.3.99.0],
         [https://bugs.freedesktop.org/enter_bug.cgi?product=xorg], [xtrans])
 AC_CONFIG_SRCDIR([Makefile.am])
 
diff --git a/doc/xtrans.xml b/doc/xtrans.xml
index d9dba6a..75af9bb 100644
--- a/doc/xtrans.xml
+++ b/doc/xtrans.xml
@@ -24,7 +24,7 @@
      </othercredit>
    </authorgroup>
    <releaseinfo>X Version 11, Release &fullrelvers;</releaseinfo>
-   <releaseinfo>Version 1.2</releaseinfo>
+   <releaseinfo>Version 1.3</releaseinfo>
    <copyright><year>1993</year><year>1994</year>
      <holder>NCR Corporation - Dayton, Ohio, USA</holder>
    </copyright>
@@ -88,6 +88,33 @@ in this Software without prior written authorization from The Open Group.
 X Window System is a trademark of The Open Group, Inc.
 </para>
 </legalnotice>
+<legalnotice>
+<para role="multiLicensing">
+Copyright © 2013, Oracle and/or its affiliates. All rights reserved.
+</para>
+<para>
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the "Software"),
+to deal in the Software without restriction, including without limitation
+the rights to use, copy, modify, merge, publish, distribute, sublicense,
+and/or sell copies of the Software, and to permit persons to whom the
+Software is furnished to do so, subject to the following conditions:
+</para>
+<para>
+The above copyright notice and this permission notice (including the next
+paragraph) shall be included in all copies or substantial portions of the
+Software.
+</para>
+<para>
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+DEALINGS IN THE SOFTWARE.
+</para>
+</legalnotice>
 </bookinfo>
 
 <preface><title>The X Transport Interface</title>
@@ -750,6 +777,70 @@ the number of transports returned, and <parameter>connections_ret</parameter>
 is the list of transports.
     </para>
   </listitem>
+  <listitem>
+    <funcsynopsis id='TRANSGetListen'>
+      <funcprototype>
+        <funcdef>Bool <function>TRANS(GetListen)</function></funcdef>
+        <paramdef>const char *<parameter>protocol</parameter></paramdef>
+      </funcprototype>
+    </funcsynopsis>
+    <para>
+<emphasis>(Introduced in Xtrans 1.3.)</emphasis>
+This function returns whether or not a transport protocol is enabled in the
+transport table used for future calls to
+<function>TRANS(MakeAllCOTSServerListeners)</function>
+or <function>TRANS(MakeAllCLTSServerListeners)</function>.
+    </para>
+    <para>
+Since transports with <symbol>TRANS_ALIAS</symbol> set may alias to multiple
+underlying transports, this function will not work with them.  Callers
+will instead need to either use <function>TRANS(GetListenAliases)</function>
+to get the aliased list of transports to check individually, or use
+<function>TRANS(ForEachTransport)</function> to iterate over the alias list.
+    </para>
+  </listitem>
+  <listitem>
+    <funcsynopsis id='TRANSSetListen'>
+      <funcprototype>
+        <funcdef>int <function>TRANS(SetListen)</function></funcdef>
+        <paramdef>const char *<parameter>protocol</parameter></paramdef>
+        <paramdef>Bool <parameter>enabled</parameter></paramdef>
+      </funcprototype>
+    </funcsynopsis>
+    <para>
+<emphasis>(Introduced in Xtrans 1.3.)</emphasis>
+This function enables or disables a transport protocol in the transport table
+used for future calls to <function>TRANS(MakeAllCOTSServerListeners)</function>
+or <function>TRANS(MakeAllCLTSServerListeners)</function>, by setting or
+clearing the <symbol>TRANS_NOLISTEN</symbol> flag.  It does not affect
+existing open listening connections.  All known transport protocols currently
+default to enabled.
+    </para>
+    <para>
+Since transports with <symbol>TRANS_ALIAS</symbol> set may alias to multiple
+underlying transports, this function will not work with them.  Callers
+will instead need to either use <function>TRANS(GetListenAliases)</function>
+to get the aliased list of transports to set individually, or use
+<function>TRANS(ForEachTransport)</function> to iterate over the alias list.
+    </para>
+  </listitem>
+  <listitem>
+    <funcsynopsis id='TRANSGetListenAliases'>
+      <funcprototype>
+        <funcdef>const char ** <function>TRANS(GetListenAliases)</function></funcdef>
+        <paramdef>const char *<parameter>protocol</parameter></paramdef>
+      </funcprototype>
+    </funcsynopsis>
+    <para>
+<emphasis>(Introduced in Xtrans 1.3.)</emphasis>
+If <parameter>protocol</parameter> names a transport alias (a transport with
+TRANS_ALIAS set), this function returns a NULL terminated list of transports
+that it aliases to, such as <code>{ "inet", "inet6", NULL }</code> for
+<literal>"tcp"</literal>  If <parameter>protocol</parameter> is unrecognized
+or matches a transport without TRANS_ALIAS set, <constant>NULL</constant> is
+returned.
+    </para>
+  </listitem>
 </itemizedlist>
 </sect1>
 
@@ -777,6 +868,89 @@ protocol definition (ie <symbol>FamilyInternet</symbol>,
 <symbol>FamilyLocal</symbol>)).
     </para>
   </listitem>
+  <listitem>
+    <funcsynopsis id='TRANSForEachTransport'>
+      <funcprototype>
+        <funcdef>int <function>TRANS(ForEachTransport)</function></funcdef>
+        <paramdef>const char *<parameter>filter</parameter></paramdef>
+        <paramdef>TransportCallbackProc <parameter>call</parameter></paramdef>
+        <paramdef>void *<parameter>closure</parameter></paramdef>
+      </funcprototype>
+      <funcprototype>
+        <funcdef>typedef int <function>(*TransportCallbackProc)</function></funcdef>
+        <paramdef>const char *<parameter>transport</parameter></paramdef>
+        <paramdef>void *<parameter>closure</parameter></paramdef>
+      </funcprototype>
+    </funcsynopsis>
+    <para>
+<emphasis>(Introduced in Xtrans 1.3.)</emphasis>
+This function calls <parameter>call</parameter> once for each transport type,
+matching the specified <parameter>filter</parameter>, passing the transport
+name and <parameter>closure</parameter>.  The <parameter>filter</parameter>
+may be any recognized transport name, transport alias, or one of the
+following special filter set names:
+<informaltable frame='topbot'>
+  <tgroup cols='2' align='left' colsep='0' rowsep='0'>
+    <colspec colname='alias' colwidth='1.0*' />
+    <colspec colname='desc' colwidth='2.0*' />
+    <thead>
+      <row rowsep='1'>
+	<entry>Filter</entry>
+	<entry>Description</entry>
+      </row>
+    </thead>
+    <tbody>
+      <row>
+        <entry>all</entry>
+        <entry>All available transport types</entry>
+      </row>
+      <row>
+        <entry>all-local</entry>
+        <entry>All available local transport types, i.e. only allowing connection to the same host, as determined by the TRANS_LOCAL flag.</entry>
+      </row>
+      <row>
+        <entry>all-remote</entry>
+        <entry>All available remote transport types, allowing connections over networks to other hosts, as determined by lack of the TRANS_LOCAL flag.</entry>
+      </row>
+      <row>
+        <entry>all-sets</entry>
+        <entry>Instead of transports, calls <parameter>call</parameter> once
+        for each name which can be passed to the <parameter>filter</parameter>
+        argument, except for itself.  Currently iterates over the list
+        <literal>{ "all", "all-local", "all-remote" }</literal>. </entry>
+      </row>
+    </tbody>
+  </tgroup>
+</informaltable>
+    </para>
+  </listitem>
+  <listitem>
+    <funcsynopsis id='TRANSSetListenProc'>
+      <funcprototype>
+        <funcdef>int <function>TRANS(SetListenProc)</function></funcdef>
+        <paramdef>const char *<parameter>protocol</parameter></paramdef>
+        <paramdef>void *<parameter>closure</parameter></paramdef>
+      </funcprototype>
+    </funcsynopsis>
+    <para>
+<emphasis>(Introduced in Xtrans 1.3.)</emphasis>
+This function can be used with <function>TRANS(ForEachTransport)</function>
+to call <function>TRANS(SetListen)</function> for each transport matching a
+filter or alias.   The <parameter>closure</parameter> must be a pointer to
+an <type>int</type> containing the value to be passed as the
+<parameter>enabled</parameter> to <function>TRANS(SetListen)</function>.
+    </para>
+    <para>
+For instance, to implement a <parameter class='command'>--nolisten</parameter>
+option to a command, you could do:
+<programlisting language="C">
+int enable = False;
+
+if (_XSERVTransForEachTransport(argv[i], TRANS(SetListenProc), &enable))
+    fprintf(stderr, "Failed to disable listening on transport %s", argv[i]);
+</programlisting>
+    </para>
+  </listitem>
 </itemizedlist>
 </sect1>
 </chapter>
-- 
1.7.9.2

-------------- next part --------------
From b809f1e22dc10c205ef65b036e25ef3fdc5d6ced Mon Sep 17 00:00:00 2001
From: Alan Coopersmith <alan.coopersmith at oracle.com>
Date: Tue, 23 Sep 2014 23:26:55 -0700
Subject: [PATCH 3/3] WIP draft of -listen flag support for xserer

Signed-off-by: Alan Coopersmith <alan.coopersmith at oracle.com>
---
 configure.ac    |    2 +-
 man/Xserver.man |    7 +++++++
 os/connection.c |   52 +++++++++++++++++++++++++++++++++++++++++++++
 os/utils.c      |   63 ++++++++++++++++++++++++++++++++++++++++++++++++++-----
 4 files changed, 118 insertions(+), 6 deletions(-)

diff --git a/configure.ac b/configure.ac
index 435a38f..f595366 100644
--- a/configure.ac
+++ b/configure.ac
@@ -795,7 +795,7 @@ FIXESPROTO="fixesproto >= 5.0"
 DAMAGEPROTO="damageproto >= 1.1"
 XCMISCPROTO="xcmiscproto >= 1.2.0"
 BIGREQSPROTO="bigreqsproto >= 1.1.0"
-XTRANS="xtrans >= 1.2.2"
+XTRANS="xtrans >= 1.2.99"
 
 dnl List of libraries that require a specific version
 LIBAPPLEWM="applewm >= 1.4"
diff --git a/man/Xserver.man b/man/Xserver.man
index b103551..e5bef49 100644
--- a/man/Xserver.man
+++ b/man/Xserver.man
@@ -189,6 +189,13 @@ MB.
 .B \-nocursor
 disable the display of the pointer cursor.
 .TP 8
+.B \-listen \fItrans-type\fP
+enables a transport type. This option may be issued multiple times to enable
+listening to different transport types.  If both -listen & -nolisten flags
+are specified, they accumulate in left-to-right order.   A special trans-type
+name of "help" may be used to print a list of all known transport type names
+(including aliases to other types).
+.TP 8
 .B \-nolisten \fItrans-type\fP
 disables a transport type.  For example, TCP/IP connections can be disabled
 with
diff --git a/os/connection.c b/os/connection.c
index 6cd8bcf..5d343b7 100644
--- a/os/connection.c
+++ b/os/connection.c
@@ -378,6 +378,37 @@ TryCreateSocket(int num, int *partial)
                                                   &ListenTransConns) >= 0);
 }
 
+/* Callback for routine to get list of enabled & disabled transports */
+struct listen_entry {
+    const char *transport_name;
+    struct xorg_list entry;
+};
+
+struct listen_states {
+    struct xorg_list enabled_list;
+    struct xorg_list disabled_list;
+};
+
+static int
+GetListenState (const char * protocol, void *closure)
+{
+    Bool enabled = _XSERVTransGetListen(protocol);
+    struct listen_states *states = (struct listen_states *) closure;
+    struct listen_entry *new_entry;
+
+    BUG_RETURN_VAL(enabled == -1, -1);
+
+    new_entry = malloc(sizeof(struct listen_entry));
+    BUG_RETURN_VAL(new_entry == NULL, -1);
+
+    new_entry->transport_name = protocol;
+    if (enabled)
+        xorg_list_add(&new_entry->entry, &states->enabled_list);
+    else
+        xorg_list_add(&new_entry->entry, &states->disabled_list);
+    return 0;
+}
+
 /*****************
  * CreateWellKnownSockets
  *    At initialization, create the sockets to listen on for new clients.
@@ -388,6 +419,8 @@ CreateWellKnownSockets(void)
 {
     int i;
     int partial;
+    struct listen_states states;
+    struct listen_entry *iterator, *next;
 
     FD_ZERO(&AllSockets);
     FD_ZERO(&AllClients);
@@ -403,6 +436,25 @@ CreateWellKnownSockets(void)
 
     FD_ZERO(&WellKnownConnections);
 
+    /* Log list of enabled & disabled transports */
+    xorg_list_init(&states.enabled_list);
+    xorg_list_init(&states.disabled_list);
+    _XSERVTransForEachTransport("all", GetListenState, &states);
+    LogMessageVerb(X_NOTICE, 3, "Opening listening connections on:");
+    xorg_list_for_each_entry_safe(iterator, next, &states.enabled_list, entry) {
+        LogMessageVerb(X_NONE, 3, " %s", iterator->transport_name);
+        xorg_list_del(&iterator->entry);
+        free(iterator);
+    }
+    LogMessageVerb(X_NONE, 3, "\n");
+    LogMessageVerb(X_NOTICE, 3, "Listening disabled on:");
+    xorg_list_for_each_entry_safe(iterator, next, &states.disabled_list, entry) {
+        LogMessageVerb(X_NONE, 3, " %s", iterator->transport_name);
+        xorg_list_del(&iterator->entry);
+        free(iterator);
+    }
+    LogMessageVerb(X_NONE, 3, "\n");
+
     /* display is initialized to "0" by main(). It is then set to the display
      * number if specified on the command line, or to NULL when the -displayfd
      * option is used. */
diff --git a/os/utils.c b/os/utils.c
index e396ba4..1aa1ba6 100644
--- a/os/utils.c
+++ b/os/utils.c
@@ -485,6 +485,47 @@ AdjustWaitForDelay(pointer waitTime, unsigned long newdelay)
     }
 }
 
+static int
+PrintListeners (const char * protocol, _X_UNUSED void *closure)
+{
+    const char **aliases = _XSERVTransGetListenAliases(protocol);
+
+    if (aliases == NULL) { /* Not an alias */
+        Bool enabled = _XSERVTransGetListen(protocol);
+        BUG_RETURN_VAL(enabled == -1, -1);
+
+        ErrorF(" - %s (%s)\n", protocol, enabled ? "enabled" : "disabled");
+    } else {
+        int i;
+
+        ErrorF(" - %s (alias for:", protocol);
+        for (i = 0; aliases[i] != NULL; i++) {
+            ErrorF("%s %s", (i > 0) ? "," : "", aliases[i]);
+        }
+        ErrorF(")\n");
+    }
+    return 0;
+}
+
+static int
+PrintTransport (const char * protocol, _X_UNUSED void *closure)
+{
+    int *count = (int *) closure;
+    ErrorF("%s %s", (*count > 0) ? "," : "", protocol);
+    *count += 1;
+    return 0;
+}
+
+static int
+PrintTransportSet (const char *set, _X_UNUSED void *closure)
+{
+    int count = 0;
+    ErrorF(" - %s (alias for:", set);
+    _XSERVTransForEachTransport(set, PrintTransport, &count);
+    ErrorF(")\n");
+    return 0;
+}
+
 void
 UseMsg(void)
 {
@@ -522,10 +563,11 @@ UseMsg(void)
 #ifdef RLIMIT_STACK
     ErrorF("-ls int                limit stack space to N Kb\n");
 #endif
+    ErrorF("-listen string         enable listening on protocol\n");
+    ErrorF("-nolisten string       disable listening on protocol\n");
 #ifdef LOCK_SERVER
     ErrorF("-nolock                disable the locking mechanism\n");
 #endif
-    ErrorF("-nolisten string       don't listen on protocol\n");
     ErrorF("-noreset               don't reset after last client exists\n");
     ErrorF("-background [none]     create root window with no background\n");
     ErrorF("-reset                 reset after last client exists\n");
@@ -778,11 +820,22 @@ ProcessCommandLine(int argc, char *argv[])
                 nolock = TRUE;
         }
 #endif
-        else if (strcmp(argv[i], "-nolisten") == 0) {
+        else if ((strcmp(argv[i], "-listen") == 0) ||
+                 (strcmp(argv[i], "-nolisten") == 0)) {
+            int enable = (strcmp(argv[i], "-listen") == 0) ? True : False;
+
             if (++i < argc) {
-                if (_XSERVTransNoListen(argv[i]))
-                    ErrorF("Failed to disable listen for %s transport",
-                           argv[i]);
+                if (strcmp(argv[i], "help") == 0) {
+                    ErrorF("Transports available to listen on:\n");
+                    _XSERVTransForEachTransport("all", PrintListeners, NULL);
+                    _XSERVTransForEachTransport("all-sets", PrintTransportSet, NULL);
+                    exit(0);
+                }
+
+                if (_XSERVTransForEachTransport(
+                        argv[i], _XSERVTransSetListenProc, &enable))
+                    ErrorF("Failed to %s listening on transport %s",
+                           enable ? "enable" : "disable", argv[i]);
             }
             else
                 UseMsg();
-- 
1.7.9.2



More information about the xorg-devel mailing list