From b3c22013b77d986e161fac2f5e685063f177c9ab Mon Sep 17 00:00:00 2001 From: Ralf Habacker Date: Thu, 17 Sep 2015 01:49:02 +0200 Subject: Add client config file support. The client config file is named client.conf and will be installed in the same directory as session.conf. In the build tree client.conf is located in the dbus subdir. --- cmake/CMakeLists.txt | 6 +- cmake/dbus/CMakeLists.txt | 29 ++++++++ cmake/doc/CMakeLists.txt | 1 + dbus/client.conf.in | 10 +++ dbus/dbus-config-loader-expat.c | 159 ++++++++++++++++++++++++++++++++++++++++ dbus/dbus-config-parser.c | 67 +++++++++++++++++ dbus/dbus-config-parser.h | 51 +++++++++++++ dbus/dbus-sysdeps-util-win.c | 8 ++ dbus/dbus-sysdeps-win.c | 102 ++++++++++++++++++-------- dbus/dbus-sysdeps.h | 1 + doc/clientconfig.dtd | 3 + doc/libdbus.xml | 97 ++++++++++++++++++++++++ 12 files changed, 500 insertions(+), 34 deletions(-) create mode 100644 dbus/client.conf.in create mode 100644 dbus/dbus-config-loader-expat.c create mode 100644 dbus/dbus-config-parser.c create mode 100644 dbus/dbus-config-parser.h create mode 100644 doc/clientconfig.dtd create mode 100644 doc/libdbus.xml diff --git a/cmake/CMakeLists.txt b/cmake/CMakeLists.txt index af6e12ff8..344b2f986 100644 --- a/cmake/CMakeLists.txt +++ b/cmake/CMakeLists.txt @@ -122,6 +122,8 @@ endif() # analogous to AC_USE_SYSTEM_EXTENSIONS in configure.ac add_definitions(-D_GNU_SOURCE) +OPTION(DBUS_ENABLE_CLIENT_CONFIG "Enable file based client configuration" OFF) + # do config checks INCLUDE(ConfigureChecks.cmake) @@ -480,8 +482,8 @@ if (DBUS_BUILD_TESTS) endif (WIN32) endif (DBUS_BUILD_TESTS) -set(DBUS_LIBRARIES dbus-1) -set(DBUS_INTERNAL_LIBRARIES dbus-internal) +set(DBUS_LIBRARIES dbus-1 ${XML_LIBRARY}) +set(DBUS_INTERNAL_LIBRARIES dbus-internal ${XML_LIBRARY}) # settings for building and using static internal lib # important note: DBUS_INTERNAL_xxxxx_DEFINITIONS must *not* be set when building dbus-1 library diff --git a/cmake/dbus/CMakeLists.txt b/cmake/dbus/CMakeLists.txt index a5481b784..cb6aa5157 100644 --- a/cmake/dbus/CMakeLists.txt +++ b/cmake/dbus/CMakeLists.txt @@ -1,6 +1,10 @@ SET(DBUS_DIR ${CMAKE_SOURCE_DIR}/../dbus) configure_file(${DBUS_DIR}/dbus-arch-deps.h.in ${CMAKE_CURRENT_BINARY_DIR}/dbus-arch-deps.h ) +if (DBUS_ENABLE_CLIENT_CONFIG) + configure_file(${DBUS_DIR}/client.conf.in ${CMAKE_CURRENT_BINARY_DIR}/client.conf ) + install(FILES ${CMAKE_CURRENT_BINARY_DIR}/client.conf DESTINATION etc/dbus-1) +endif (DBUS_ENABLE_CLIENT_CONFIG) add_definitions(-DDBUS_COMPILATION) @@ -239,6 +243,19 @@ set(libdbus_HEADERS ${DBUS_LIB_HEADERS} ${DBUS_SHARED_HEADERS} ) + +if (DBUS_ENABLE_CLIENT_CONFIG) + set (DBUS_CONFIG_SOURCES + ${DBUS_DIR}/dbus-config-parser.c + ${DBUS_DIR}/dbus-config-loader-expat.c + ${DBUS_UTIL_SOURCES} + ) + set (DBUS_CONFIG_HEADERS + ${DBUS_DIR}/dbus-config-parser.h + ${DBUS_UTIL_HEADERS} + ) +endif (DBUS_ENABLE_CLIENT_CONFIG) + if (MSVC) set (BUILD_FILEVERSION ${DBUS_MAJOR_VERSION},${DBUS_MINOR_VERSION},${DBUS_MICRO_VERSION},${DBUS_PATCH_VERSION}) set (BUILD_TIMESTAMP ${DBUS_BUILD_TIMESTAMP}) @@ -246,6 +263,7 @@ if (MSVC) configure_file(${DBUS_DIR}/versioninfo.rc.in ${CMAKE_CURRENT_BINARY_DIR}/versioninfo.rc) file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/afxres.h "") list(APPEND libdbus_SOURCES versioninfo.rc) + list(APPEND DBUS_UTIL_SOURCES versioninfo.rc) set_source_files_properties(versioninfo.rc COMPILE_FLAGS "-D__LINE__=1") endif (MSVC) @@ -260,6 +278,8 @@ endif(MSVC_IDE) add_library(dbus-1 SHARED ${libdbus_SOURCES} ${libdbus_HEADERS} + ${DBUS_CONFIG_SOURCES} + ${DBUS_CONFIG_HEADERS} ) if(WIN32) if(WINCE) @@ -271,7 +291,16 @@ else(WIN32) target_link_libraries(dbus-1 ${CMAKE_THREAD_LIBS_INIT} rt) endif(WIN32) +if(DBUS_ENABLE_CLIENT_CONFIG) + target_link_libraries(dbus-1 ${XML_LIBRARY}) +endif() + install(TARGETS dbus-1 ${INSTALL_TARGETS_DEFAULT_ARGS}) + +if (DBUS_ENABLE_CLIENT_CONFIG) + set_target_properties(dbus-1 PROPERTIES COMPILE_FLAGS -DDBUS_ENABLE_CLIENT_CONFIG) +endif (DBUS_ENABLE_CLIENT_CONFIG) + install_files(/include/dbus FILES ${dbusinclude_HEADERS}) ### Internal library, used for the daemon, tools and tests, compiled statically. diff --git a/cmake/doc/CMakeLists.txt b/cmake/doc/CMakeLists.txt index 7fdfc2196..c3f48c5e1 100644 --- a/cmake/doc/CMakeLists.txt +++ b/cmake/doc/CMakeLists.txt @@ -145,6 +145,7 @@ install(FILES ${CMAKE_CURRENT_BINARY_DIR}/index.html DESTINATION share/doc/dbus) set (EXTRA_DIST ${CMAKE_SOURCE_DIR}/../doc/busconfig.dtd + ${CMAKE_SOURCE_DIR}/../doc/clientconfig.dtd ${CMAKE_SOURCE_DIR}/../doc/introspect.dtd ${CMAKE_SOURCE_DIR}/../doc/introspect.xsl ) diff --git a/dbus/client.conf.in b/dbus/client.conf.in new file mode 100644 index 000000000..a6f0a564d --- /dev/null +++ b/dbus/client.conf.in @@ -0,0 +1,10 @@ + + + + + + + @DBUS_SESSION_BUS_CONNECT_ADDRESS@ + + diff --git a/dbus/dbus-config-loader-expat.c b/dbus/dbus-config-loader-expat.c new file mode 100644 index 000000000..f65ff889a --- /dev/null +++ b/dbus/dbus-config-loader-expat.c @@ -0,0 +1,159 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ +/* dbus-config-loader-expat.c expat XML loader + * + * Copyright (C) 2010 Ralf Habacker + * + * Licensed under the Academic Free License version 2.1 + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#include +#include +#include +#include +#include +#include + +#ifdef XML_LARGE_SIZE +#if defined(XML_USE_MSC_EXTENSIONS) && _MSC_VER < 1400 +#define XML_FMT_INT_MOD "I64" +#else +#define XML_FMT_INT_MOD "ll" +#endif +#else +#define XML_FMT_INT_MOD "l" +#endif + +typedef struct { + ClientConfigParser *parser; + DBusString content; + dbus_bool_t in_session_bus; + DBusError *error; + dbus_bool_t failed; +} ExpatClientParseContext; + +static void XMLCALL +client_config_start_element (void *userData, const char *name, const char **atts) +{ + ExpatClientParseContext *context = userData; + _dbus_string_set_length (&context->content, 0); + if (strcmp (name,"sessionbus") == 0) + context->in_session_bus = TRUE; +} + +static void XMLCALL +client_config_end_element (void *userData, const char *name) +{ + ExpatClientParseContext *context = userData; + + if (_dbus_string_get_length (&context->content) > 0) + { + if (context->in_session_bus && strcmp (name,"connect") == 0) + context->parser->session_bus_address = _dbus_strdup (_dbus_string_get_const_data (&context->content)); + _dbus_string_set_length (&context->content, 0); + } + if (strcmp (name,"sessionbus") == 0) + context->in_session_bus = FALSE; +} + +/* s is not 0 terminated. */ +static void +client_config_CharacterDataHandler (void *userData, + const XML_Char *s, + int len) +{ + ExpatClientParseContext *context = userData; + if (context->failed) + return; + + if (!_dbus_string_append_len (&context->content, + s, len)) + { + dbus_set_error (context->error, DBUS_ERROR_NO_MEMORY, NULL); + context->failed = TRUE; + return; + } +} + +ClientConfigParser* +client_config_load (const DBusString *file, + const ClientConfigParser *parent, + DBusError *error) +{ + ClientConfigParser *parser; + ExpatClientParseContext context; + DBusString data; + const char *data_str; + XML_Parser expat = XML_ParserCreate(NULL); + + parser = NULL; + context.error = error; + context.failed = FALSE; + context.in_session_bus = FALSE; + + if (!_dbus_string_init (&context.content)) + { + dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL); + return NULL; + } + + if (!_dbus_string_init (&data)) + { + dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL); + goto failed; + } + + if (!_dbus_file_get_contents (&data, file, error)) + { + _dbus_string_free (&data); + goto failed; + } + + data_str = _dbus_string_get_const_data (&data); + + context.parser = client_config_parser_new (0,0,0); + + XML_SetUserData (expat, &context); + XML_SetElementHandler (expat, client_config_start_element, client_config_end_element); + XML_SetCharacterDataHandler (expat, client_config_CharacterDataHandler); + if (!XML_Parse (expat, data_str, _dbus_string_get_length (&data), TRUE)) + { + if (context.error != NULL && + !dbus_error_is_set (context.error)) + { + enum XML_Error e; + + e = XML_GetErrorCode (expat); + if (e == XML_ERROR_NO_MEMORY) + dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL); + else + dbus_set_error (error, DBUS_ERROR_FAILED, + "Error in file %s, line %d, column %d: %s\n", + _dbus_string_get_const_data (file), + XML_GetCurrentLineNumber (expat), + XML_GetCurrentColumnNumber (expat), + XML_ErrorString (e)); + } + } + _dbus_string_free (&data); + + XML_ParserFree (expat); + return context.parser; +failed: + XML_ParserFree (expat); + return 0; +} diff --git a/dbus/dbus-config-parser.c b/dbus/dbus-config-parser.c new file mode 100644 index 000000000..a69e46d6a --- /dev/null +++ b/dbus/dbus-config-parser.c @@ -0,0 +1,67 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ +/* dbus-config-parser.c client config parser implementation + * + * Copyright (C) 2010 Ralf Habacker + * + * Licensed under the Academic Free License version 2.1 + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#include +#include "dbus-config-parser.h" +#include "dbus-internals.h" + +ClientConfigParser* client_config_parser_new (const DBusString *basedir, + dbus_bool_t is_toplevel, + const ClientConfigParser *parent) +{ + ClientConfigParser *parser = dbus_new0(ClientConfigParser,1); + if (parser == NULL) + return NULL; + + parser->session_bus_address = 0; + parser->refcount = 1; + return parser; +} + +ClientConfigParser *client_config_parser_ref (ClientConfigParser *parser) +{ + _dbus_assert (parser->refcount > 0); + + parser->refcount += 1; + + return parser; +} + +void client_config_parser_unref (ClientConfigParser *parser) +{ + _dbus_assert (parser->refcount > 0); + + parser->refcount -= 1; + + if (parser->refcount == 0) + { + if (parser->session_bus_address) + dbus_free(parser->session_bus_address); + dbus_free(parser); + } +} + +const char *client_config_parser_get_session_bus_address (ClientConfigParser *parser) +{ + return parser->session_bus_address; +} diff --git a/dbus/dbus-config-parser.h b/dbus/dbus-config-parser.h new file mode 100644 index 000000000..fc47e295e --- /dev/null +++ b/dbus/dbus-config-parser.h @@ -0,0 +1,51 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ +/* dbus-config-parser.h client config parser definitions + * + * Copyright (C) 2010 Ralf Habacker + * + * Licensed under the Academic Free License version 2.1 + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#ifndef DBUS_CONFIG_PARSER_H +#define DBUS_CONFIG_PARSER_H + +#include "dbus-string.h" +#include "dbus-errors.h" + +typedef struct { + char *session_bus_address; + int refcount; +} ClientConfigParser; + +ClientConfigParser* client_config_parser_new (const DBusString *basedir, + dbus_bool_t is_toplevel, + const ClientConfigParser *parent); + +const char *client_config_parser_get_session_bus_address (ClientConfigParser *parser); + +void client_config_parser_unref (ClientConfigParser *parser); + +ClientConfigParser *client_config_parser_ref (ClientConfigParser *parser); + +ClientConfigParser* +client_config_load (const DBusString *file, + const ClientConfigParser *parent, + DBusError *error); + + +#endif diff --git a/dbus/dbus-sysdeps-util-win.c b/dbus/dbus-sysdeps-util-win.c index ec9afbb6c..be63d5045 100644 --- a/dbus/dbus-sysdeps-util-win.c +++ b/dbus/dbus-sysdeps-util-win.c @@ -1767,3 +1767,11 @@ _dbus_append_session_config_file (DBusString *str) { return _dbus_get_config_file_name(str, "session.conf"); } + +#ifdef DBUS_ENABLE_CLIENT_CONFIG +dbus_bool_t +_dbus_append_client_config_file (DBusString *str) +{ + return _dbus_get_config_file_name(str, "client.conf"); +} +#endif diff --git a/dbus/dbus-sysdeps-win.c b/dbus/dbus-sysdeps-win.c index 75f07e9c4..144ffe42c 100644 --- a/dbus/dbus-sysdeps-win.c +++ b/dbus/dbus-sysdeps-win.c @@ -50,6 +50,9 @@ #include "dbus-list.h" #include "dbus-nonce.h" #include "dbus-credentials.h" +#ifdef DBUS_ENABLE_CLIENT_CONFIG +#include "dbus-config-parser.h" +#endif #include #include @@ -3343,41 +3346,43 @@ _dbus_get_config_file_name(DBusString *config_file, char *s) strcat(path,s); if (_dbus_file_exists(path)) { - // find path from executable - if (!_dbus_string_append (config_file, path)) - return FALSE; + // find path from executable + return _dbus_string_append (config_file, path); } - else + + if (!_dbus_get_install_root(path,path_size)) + return FALSE; + if(strlen(s) + 11 + strlen(path) > sizeof(path)-2) + return FALSE; + strcat(path,"etc\\dbus-1\\"); + strcat(path,s); + if (_dbus_file_exists(path)) { - if (!_dbus_get_install_root(path,path_size)) - return FALSE; - if(strlen(s) + 11 + strlen(path) > sizeof(path)-2) - return FALSE; - strcat(path,"etc\\dbus-1\\"); - strcat(path,s); - - if (_dbus_file_exists(path)) - { - if (!_dbus_string_append (config_file, path)) - return FALSE; - } - else - { - if (!_dbus_get_install_root(path,path_size)) - return FALSE; - if(strlen(s) + 4 + strlen(path) > sizeof(path)-2) - return FALSE; - strcat(path,"bus\\"); - strcat(path,s); - - if (_dbus_file_exists(path)) - { - if (!_dbus_string_append (config_file, path)) - return FALSE; - } - } + return _dbus_string_append (config_file, path); } - return TRUE; + + if (!_dbus_get_install_root(path,path_size)) + return FALSE; + if(strlen(s) + 4 + strlen(path) > sizeof(path)-2) + return FALSE; + strcat(path,"bus\\"); + strcat(path,s); + if (_dbus_file_exists(path)) + { + return _dbus_string_append (config_file, path); + } + + if (!_dbus_get_install_root(path,path_size)) + return FALSE; + if(strlen(s) + 4 + strlen(path) > sizeof(path)-2) + return FALSE; + strcat(path,"dbus\\"); + strcat(path,s); + if (_dbus_file_exists(path)) + { + return _dbus_string_append (config_file, path); + } + return FALSE; } /* See comment in dbus-sysdeps-unix.c */ @@ -3387,7 +3392,40 @@ _dbus_lookup_session_address (dbus_bool_t *supported, DBusError *error) { /* Probably fill this in with something based on COM? */ +#if DBUS_ENABLE_CLIENT_CONFIG + DBusString client_config_file; + ClientConfigParser *parser; + char *s; + *supported = TRUE; + + if (!_dbus_string_init (&client_config_file)) + { + _DBUS_SET_OOM (error); + return FALSE; + } + + if (!_dbus_append_client_config_file (&client_config_file)) + { + _DBUS_SET_OOM (error); + return FALSE; + } + + parser = client_config_load (&client_config_file,0,error); + if (!parser) + { + _dbus_warn ("Could not load client config file %s: %s\n", + _dbus_string_get_const_data (&client_config_file), + error->message); + dbus_error_free (error); + _dbus_string_free (&client_config_file); + return FALSE; + } + s = client_config_parser_get_session_bus_address (parser); + _dbus_string_append (address,s); + client_config_parser_unref (parser); +#else *supported = FALSE; +#endif return TRUE; } diff --git a/dbus/dbus-sysdeps.h b/dbus/dbus-sysdeps.h index 5465128e2..520208e80 100644 --- a/dbus/dbus-sysdeps.h +++ b/dbus/dbus-sysdeps.h @@ -345,6 +345,7 @@ dbus_bool_t _dbus_get_standard_system_servicedirs (DBusList **dirs); dbus_bool_t _dbus_append_system_config_file (DBusString *str); dbus_bool_t _dbus_append_session_config_file (DBusString *str); +dbus_bool_t _dbus_append_client_config_file (DBusString *str); /** Opaque type for reading a directory listing */ typedef struct DBusDirIter DBusDirIter; diff --git a/doc/clientconfig.dtd b/doc/clientconfig.dtd new file mode 100644 index 000000000..d79103a62 --- /dev/null +++ b/doc/clientconfig.dtd @@ -0,0 +1,3 @@ + + + diff --git a/doc/libdbus.xml b/doc/libdbus.xml new file mode 100644 index 000000000..7f282ca1f --- /dev/null +++ b/doc/libdbus.xml @@ -0,0 +1,97 @@ + + + + + + + + +libdbus configuration +1 + + +libdbus configuration +message bus library configuration + + +CONFIGURATION FILE +The dbus message bus library could be compiled to have a client configuration file. +The client configuration file allows to set client related parameters like bus addresses. + +The client configuration file is an alternative to the usage of environment variables. +The main cases for using this client configuration file are operating system environments +where environment variables are not usable or does not fit into the required use cases. + +The configuration file is not part of any interoperability +specification and its backward compatibility is not guaranteed; this +document is documentation, not specification. + +The standard message bus client setups are configured in the files "/etc/dbus-1/client.conf" on unix or +"<install-root>/etc/dbus-1/client.conf" on other systems. + +The configuration file is an XML document. It must have the following +doctype declaration: + + <!DOCTYPE clientconfig PUBLIC "-//freedesktop//DTD D-Bus Client Configuration 1.0//EN" + "http://www.freedesktop.org/standards/dbus/1.0/clientconfig.dtd"> + + +The following elements may be present in the configuration file. + + + + <clientconfig> + + + + + + +Root element. + + + + <sessionbus> + + + + + + + +Specifies that the following elements belongs to the message bus. The following elements are available: + + + + <connect> + + + + + + +Specifices the session bus address to which the client should connect. + +Example: <connect>tcp:host=localhost,port=1234</connect> +Example: <connect>autolaunch:</connect> + + + + <verbose> + + + + + + +AUTHOR +See http://www.freedesktop.org/software/dbus/doc/AUTHORS + + + +BUGS +Please send bug reports to the D-Bus mailing list or bug tracker, +see http://www.freedesktop.org/software/dbus/ + + -- cgit v1.2.3