[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