diff --git a/CMakeLists.txt b/CMakeLists.txt
index 6579fb856caf984cb85cf239ba1b7c7f05a44a13..6e38fde6ecb11ffcb6bd829764ebc281bbffe883 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -30,13 +30,13 @@ set(PROJECT_DISTCONFIGURE_PARAMS
-DENABLE_VALA_BINDINGS=ON
-DENABLE_INSTALLED_TESTS=ON
-DENABLE_GTK_DOC=ON
- -DENABLE_DBUS_SESSION_TOOL=ON
-DWITH_PRIVATE_DOCS=ON
)
# ******************************
# D-Bus versioning
# ******************************
+# Actual name can be modified with DBUS_SERVICES_PREFIX option
set(ADDRESS_BOOK_DBUS_SERVICE_NAME "org.gnome.evolution.dataserver.AddressBook9")
set(CALENDAR_DBUS_SERVICE_NAME "org.gnome.evolution.dataserver.Calendar7")
set(SOURCES_DBUS_SERVICE_NAME "org.gnome.evolution.dataserver.Sources5")
@@ -170,6 +170,15 @@ ensure_default_value(SHARE_INSTALL_PREFIX "${CMAKE_INSTALL_PREFIX}/share")
ensure_default_value(LOCALE_INSTALL_DIR "${SHARE_INSTALL_PREFIX}/locale")
ensure_default_value(SYSCONF_INSTALL_DIR "${CMAKE_INSTALL_PREFIX}/etc")
+add_printable_variable(DBUS_SERVICES_PREFIX "Prefix for D-Bus services, usually left empty, without trailing dot" "")
+
+if(NOT ("${DBUS_SERVICES_PREFIX}" STREQUAL ""))
+ set(ADDRESS_BOOK_DBUS_SERVICE_NAME "${DBUS_SERVICES_PREFIX}.${ADDRESS_BOOK_DBUS_SERVICE_NAME}")
+ set(CALENDAR_DBUS_SERVICE_NAME "${DBUS_SERVICES_PREFIX}.${CALENDAR_DBUS_SERVICE_NAME}")
+ set(SOURCES_DBUS_SERVICE_NAME "${DBUS_SERVICES_PREFIX}.${SOURCES_DBUS_SERVICE_NAME}")
+ set(USER_PROMPTER_DBUS_SERVICE_NAME "${DBUS_SERVICES_PREFIX}.${USER_PROMPTER_DBUS_SERVICE_NAME}")
+endif(NOT ("${DBUS_SERVICES_PREFIX}" STREQUAL ""))
+
# ******************************
# Special directories
# ******************************
@@ -980,12 +989,6 @@ if(ENABLE_VALA_BINDINGS)
endif(ENABLE_VALA_BINDINGS)
-# ******************************
-# D-Bus session tool, a Flatpak helper
-# ******************************
-
-add_printable_option(ENABLE_DBUS_SESSION_TOOL "Build evolution-dbus-session tool" OFF)
-
# Generate the ${PROJECT_NAME}-config.h file
CONFIGURE_FILE(${CMAKE_SOURCE_DIR}/config.h.in ${CMAKE_BINARY_DIR}/${PROJECT_NAME}-config.h)
diff --git a/src/tools/CMakeLists.txt b/src/tools/CMakeLists.txt
index 796e02b6f39bac0b9c401d1333f1f72051e8a34d..e13c25f4f0a465b52a03b6daab184de68916222a 100644
--- a/src/tools/CMakeLists.txt
+++ b/src/tools/CMakeLists.txt
@@ -1,6 +1,2 @@
add_subdirectory(addressbook-export)
add_subdirectory(list-sources)
-
-if(ENABLE_DBUS_SESSION_TOOL)
- add_subdirectory(evolution-dbus-session)
-endif(ENABLE_DBUS_SESSION_TOOL)
diff --git a/src/tools/evolution-dbus-session/CMakeLists.txt b/src/tools/evolution-dbus-session/CMakeLists.txt
deleted file mode 100644
index 2f063589377130b77130fca99de2ed38d1401bab..0000000000000000000000000000000000000000
--- a/src/tools/evolution-dbus-session/CMakeLists.txt
+++ /dev/null
@@ -1,31 +0,0 @@
-set(SOURCES
- evolution-dbus-session.c
-)
-
-add_executable(evolution-dbus-session
- ${SOURCES}
-)
-
-target_compile_definitions(evolution-dbus-session PRIVATE
- -DG_LOG_DOMAIN=\"evolution-dbus-session\"
-)
-
-target_compile_options(edataserver PUBLIC
- ${GNOME_PLATFORM_CFLAGS}
-)
-
-target_include_directories(evolution-dbus-session PUBLIC
- ${CMAKE_BINARY_DIR}
- ${CMAKE_BINARY_DIR}/src
- ${CMAKE_SOURCE_DIR}/src
- ${CMAKE_CURRENT_BINARY_DIR}
- ${GNOME_PLATFORM_INCLUDE_DIRS}
-)
-
-target_link_libraries(evolution-dbus-session
- ${GNOME_PLATFORM_LDFLAGS}
-)
-
-install(TARGETS evolution-dbus-session
- DESTINATION ${privlibexecdir}
-)
diff --git a/src/tools/evolution-dbus-session/evolution-dbus-session.c b/src/tools/evolution-dbus-session/evolution-dbus-session.c
deleted file mode 100644
index f0c8e638c2554379dc1850a34a600006660ff511..0000000000000000000000000000000000000000
--- a/src/tools/evolution-dbus-session/evolution-dbus-session.c
+++ /dev/null
@@ -1,823 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
-/*
- * Copyright (C) 2018 Red Hat, Inc. (www.redhat.com)
- *
- * This program is free software: you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as published by
- * the Free Software Foundation.
- *
- * 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 Lesser General Public License
- * for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program. If not, see .
- */
-
-#include "evolution-data-server-config.h"
-
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-
-#define DBUS_CALL_TIMEOUT -1 /* as set by D-Bus settings */
-
-static void
-object_manager_object_added_cb (GDBusObjectManager *manager,
- GDBusObject *object,
- gpointer user_data);
-static void
-object_manager_object_removed_cb (GDBusObjectManager *manager,
- GDBusObject *object,
- gpointer user_data);
-
-typedef struct _ProxyData {
- gchar *iface_name;
- gchar *path;
-
- /* The original D-Bus session part */
- GDBusProxy *proxy;
- GDBusObjectManager *object_manager;
- GSList *sigids; /* GUINT_TO_POINTER(sigid) */
-
- /* The new D-Bus session part */
- GDBusConnection *regs_connection;
- guint ownid;
- GSList *regids; /* GUINT_TO_POINTER(regid) */
- GSList *object_manager_pds; /* ProxyData *, when object_manager is not NULL */
-} ProxyData;
-
-static void
-proxy_data_free (gpointer ptr)
-{
- ProxyData *pd = ptr;
-
- if (pd) {
- if (pd->object_manager)
- g_signal_handlers_disconnect_by_data (pd->object_manager, pd);
-
- g_slist_free_full (pd->object_manager_pds, proxy_data_free);
-
- if (pd->regs_connection && !g_dbus_connection_is_closed (pd->regs_connection)) {
- GSList *link;
-
- for (link = pd->regids; link; link = g_slist_next (link)) {
- guint regid = GPOINTER_TO_UINT (link->data);
-
- g_dbus_connection_unregister_object (pd->regs_connection, regid);
- }
-
- if (pd->object_manager) {
- GList *objects, *llink;
-
- objects = g_dbus_object_manager_get_objects (pd->object_manager);
-
- for (llink = objects; llink; llink = g_list_next (llink)) {
- GDBusObject *object = llink->data;
-
- object_manager_object_removed_cb (pd->object_manager, object, pd);
- }
-
- g_list_free_full (objects, g_object_unref);
- }
- }
-
- if (pd->ownid) {
- g_bus_unown_name (pd->ownid);
- pd->ownid = 0;
- }
-
- if (pd->proxy && pd->sigids) {
- GDBusConnection *connection;
-
- connection = g_dbus_proxy_get_connection (pd->proxy);
-
- if (connection && !g_dbus_connection_is_closed (connection)) {
- GSList *link;
-
- for (link = pd->sigids; link; link = g_slist_next (link)) {
- guint sigid = GPOINTER_TO_UINT (link->data);
-
- g_dbus_connection_signal_unsubscribe (connection, sigid);
- }
- }
- }
-
- g_clear_object (&pd->proxy);
- g_clear_object (&pd->object_manager);
- g_clear_object (&pd->regs_connection);
- g_slist_free (pd->regids);
- g_slist_free (pd->sigids);
- g_free (pd->iface_name);
- g_free (pd->path);
- g_free (pd);
- }
-}
-
-/* encoded_string :== iface_name + ":" + path */
-static ProxyData *
-proxy_data_new (const gchar *encoded_string)
-{
- ProxyData *pd;
- gchar **strv;
- GError *error = NULL;
-
- strv = g_strsplit (encoded_string, ":", -1);
- g_return_val_if_fail (strv != NULL, NULL);
- if (!strv[0] || !strv[1] || strv[2]) {
- g_warning ("Unexpected proxy data string format: '%s'", encoded_string);
- g_strfreev (strv);
- return NULL;
- }
-
- pd = g_new0 (ProxyData, 1);
- pd->iface_name = g_strdup (strv[0]); /* like "org.freedesktop.portal.Desktop" */
- pd->path = g_strdup (strv[1]); /* like "/org/freedesktop/portal/desktop" */
- pd->proxy = g_dbus_proxy_new_for_bus_sync (G_BUS_TYPE_SESSION, G_DBUS_PROXY_FLAGS_NONE, NULL,
- pd->iface_name, pd->path, pd->iface_name, NULL, &error);
-
- if (!pd->proxy) {
- g_warning ("Failed to open proxy for interface '%s' at path '%s': %s", pd->iface_name, pd->path, error ? error->message : "Unknown error");
- proxy_data_free (pd);
- pd = NULL;
- }
-
- g_clear_error (&error);
- g_strfreev (strv);
-
- return pd;
-}
-
-static void
-handle_method_call_cb (GDBusConnection *connection,
- const gchar *sender,
- const gchar *object_path,
- const gchar *interface_name,
- const gchar *method_name,
- GVariant *parameters,
- GDBusMethodInvocation *invocation,
- gpointer user_data)
-{
-#ifdef G_OS_UNIX
- GDBusMessage *message;
- GUnixFDList *in_fd_list, *out_fd_list = NULL;
-#endif
- ProxyData *pd = user_data;
- GVariant *result;
- GError *error = NULL;
-
- g_return_if_fail (pd != NULL);
-
-#ifdef G_OS_UNIX
- message = g_dbus_method_invocation_get_message (invocation);
- in_fd_list = g_dbus_message_get_unix_fd_list (message);
-
- result = g_dbus_connection_call_with_unix_fd_list_sync (g_dbus_proxy_get_connection (pd->proxy),
- g_dbus_proxy_get_name (pd->proxy),
- object_path,
- interface_name,
- method_name,
- parameters,
- NULL,
- G_DBUS_CALL_FLAGS_NONE,
- DBUS_CALL_TIMEOUT,
- in_fd_list,
- &out_fd_list,
- NULL, &error);
-#else
- result = g_dbus_connection_call_sync (g_dbus_proxy_get_connection (pd->proxy),
- g_dbus_proxy_get_name (pd->proxy),
- object_path,
- interface_name,
- method_name,
- parameters,
- NULL,
- G_DBUS_CALL_FLAGS_NONE,
- DBUS_CALL_TIMEOUT,
- NULL, &error);
-#endif
-
- if (result) {
- #ifdef G_OS_UNIX
- if (out_fd_list) {
- g_dbus_method_invocation_return_value_with_unix_fd_list (invocation, result, out_fd_list);
- g_object_unref (out_fd_list);
- } else {
- g_dbus_method_invocation_return_value (invocation, result);
- }
- #else
- g_dbus_method_invocation_return_value (invocation, result);
- #endif
- g_variant_unref (result);
- } else {
- g_dbus_method_invocation_return_gerror (invocation, error);
- }
-
- g_clear_error (&error);
-}
-
-static GVariant *
-handle_get_property_cb (GDBusConnection *connection,
- const gchar *sender,
- const gchar *object_path,
- const gchar *interface_name,
- const gchar *property_name,
- GError **error,
- gpointer user_data)
-{
- ProxyData *pd = user_data;
-
- g_return_val_if_fail (pd != NULL, NULL);
-
- return g_dbus_connection_call_sync (g_dbus_proxy_get_connection (pd->proxy),
- g_dbus_proxy_get_name (pd->proxy),
- object_path,
- "org.freedesktop.DBus.Properties",
- "Get",
- g_variant_new ("(ss)", interface_name, property_name),
- G_VARIANT_TYPE ("(s)"),
- G_DBUS_CALL_FLAGS_NONE,
- DBUS_CALL_TIMEOUT,
- NULL, error);
-}
-
-static gboolean
-handle_set_property_cb (GDBusConnection *connection,
- const gchar *sender,
- const gchar *object_path,
- const gchar *interface_name,
- const gchar *property_name,
- GVariant *value,
- GError **error,
- gpointer user_data)
-{
- ProxyData *pd = user_data;
- GVariant *result;
- GError *local_error = NULL;
-
- g_return_val_if_fail (pd != NULL, FALSE);
-
- result = g_dbus_connection_call_sync (g_dbus_proxy_get_connection (pd->proxy),
- g_dbus_proxy_get_name (pd->proxy),
- object_path,
- "org.freedesktop.DBus.Properties",
- "Set",
- g_variant_new ("(ssv)", interface_name, property_name, value),
- NULL,
- G_DBUS_CALL_FLAGS_NONE,
- DBUS_CALL_TIMEOUT,
- NULL, &local_error);
-
- if (result)
- g_variant_unref (result);
-
- if (local_error)
- g_propagate_error (error, local_error);
-
- return local_error != NULL;
-}
-
-static void
-handle_signal_cb (GDBusConnection *connection,
- const gchar *sender_name,
- const gchar *object_path,
- const gchar *interface_name,
- const gchar *signal_name,
- GVariant *parameters,
- gpointer user_data)
-{
- ProxyData *pd = user_data;
- GError *error = NULL;
-
- g_return_if_fail (pd != NULL);
-
- if (!g_dbus_connection_emit_signal (pd->regs_connection, NULL, object_path,
- interface_name, signal_name, parameters, &error)) {
- g_clear_error (&error);
- }
-}
-
-static void
-proxy_data_reg_interfaces_for_object_path (ProxyData *pd,
- GDBusConnection *connection,
- const gchar *object_path)
-{
- const GDBusInterfaceVTable interface_vtable = {
- handle_method_call_cb,
- handle_get_property_cb,
- handle_set_property_cb
- };
- GDBusNodeInfo *introspection_data;
- GVariant *result;
- const gchar *xml_data;
- guint regid;
- gint ii;
- gboolean is_object_manager = FALSE;
- GError *error = NULL;
-
- g_return_if_fail (pd != NULL);
- g_return_if_fail (pd->proxy != NULL);
- g_return_if_fail (connection != NULL);
-
- result = g_dbus_connection_call_sync (g_dbus_proxy_get_connection (pd->proxy),
- g_dbus_proxy_get_name (pd->proxy),
- object_path,
- "org.freedesktop.DBus.Introspectable",
- "Introspect",
- NULL,
- G_VARIANT_TYPE ("(s)"),
- G_DBUS_CALL_FLAGS_NONE,
- DBUS_CALL_TIMEOUT,
- NULL, &error);
-
- if (!result) {
- g_warning ("Failed to get introspected data for '%s': %s", g_dbus_proxy_get_name (pd->proxy), error ? error->message : "Unknown error");
- g_clear_error (&error);
- return;
- }
-
- g_variant_get (result, "(&s)", &xml_data);
- introspection_data = g_dbus_node_info_new_for_xml (xml_data, NULL);
- g_variant_unref (result);
-
- if (!introspection_data) {
- g_warning ("Failed to parse introspected data for '%s': %s", g_dbus_proxy_get_name (pd->proxy), error ? error->message : "Unknown error");
- g_clear_error (&error);
- return;
- }
-
- pd->regs_connection = g_object_ref (connection);
-
- for (ii = 0; introspection_data->interfaces && introspection_data->interfaces[ii]; ii++) {
- GDBusInterfaceInfo *iface_info = introspection_data->interfaces[ii];
-
- if (!iface_info)
- continue;
-
- regid = g_dbus_connection_register_object (pd->regs_connection, object_path,
- iface_info,
- &interface_vtable,
- pd,
- NULL,
- &error);
-
- if (regid) {
- pd->regids = g_slist_prepend (pd->regids, GUINT_TO_POINTER (regid));
-
- if (iface_info->signals) {
- gint jj;
-
- for (jj = 0; iface_info->signals[jj]; jj++) {
- guint sigid;
-
- sigid = g_dbus_connection_signal_subscribe (g_dbus_proxy_get_connection (pd->proxy), NULL,
- iface_info->name,
- iface_info->signals[jj]->name,
- object_path,
- NULL, G_DBUS_SIGNAL_FLAGS_NONE,
- handle_signal_cb, pd, NULL);
-
- if (sigid)
- pd->sigids = g_slist_prepend (pd->sigids, GUINT_TO_POINTER (sigid));
- }
- }
-
- if (g_strcmp0 (iface_info->name, "org.freedesktop.DBus.ObjectManager") == 0) {
- is_object_manager = TRUE;
-
- pd->object_manager = g_dbus_object_manager_client_new_sync (g_dbus_proxy_get_connection (pd->proxy),
- G_DBUS_OBJECT_MANAGER_CLIENT_FLAGS_NONE,
- g_dbus_proxy_get_name (pd->proxy),
- object_path,
- NULL, NULL, NULL, NULL, &error);
-
- if (pd->object_manager) {
- GList *objects, *link;
-
- g_signal_connect (pd->object_manager, "object-added",
- G_CALLBACK (object_manager_object_added_cb), pd);
- g_signal_connect (pd->object_manager, "object-removed",
- G_CALLBACK (object_manager_object_removed_cb), pd);
-
- objects = g_dbus_object_manager_get_objects (pd->object_manager);
- for (link = objects; link; link = g_list_next (link)) {
- GDBusObject *object = link->data;
-
- object_manager_object_added_cb (pd->object_manager, object, pd);
- }
-
- g_list_free_full (objects, g_object_unref);
- } else {
- g_clear_error (&error);
- }
- }
- } else {
- g_clear_error (&error);
- }
- }
-
- if (!is_object_manager && introspection_data->nodes) {
- for (ii = 0; introspection_data->nodes[ii]; ii++) {
- GDBusNodeInfo *node_info = introspection_data->nodes[ii];
-
- if (node_info && node_info->path) {
- gchar *path;
-
- if (node_info->path[0] == '/')
- path = g_strdup (node_info->path);
- else
- path = g_strconcat (object_path, "/", node_info->path, NULL);
-
- if (g_variant_is_object_path (path))
- proxy_data_reg_interfaces_for_object_path (pd, connection, path);
-
- g_free (path);
- }
- }
- }
-
- g_dbus_node_info_unref (introspection_data);
-}
-
-static void
-proxy_data_reg_interfaces (ProxyData *pd,
- GDBusConnection *connection)
-{
- g_return_if_fail (pd != NULL);
- g_return_if_fail (pd->proxy != NULL);
- g_return_if_fail (pd->regs_connection == NULL);
- g_return_if_fail (connection != NULL);
-
- proxy_data_reg_interfaces_for_object_path (pd, connection, g_dbus_proxy_get_object_path (pd->proxy));
-}
-
-static void
-bus_name_acquired_cb (GDBusConnection *connection,
- const gchar *name,
- gpointer user_data)
-{
- ProxyData *pd = user_data;
-
- g_return_if_fail (pd != NULL);
-
- proxy_data_reg_interfaces (pd, connection);
-}
-
-static void
-bus_name_lost_cb (GDBusConnection *connection,
- const gchar *name,
- gpointer user_data)
-{
- ProxyData *pd = user_data;
-
- g_return_if_fail (pd != NULL);
-}
-
-static void
-object_manager_object_added_cb (GDBusObjectManager *manager,
- GDBusObject *object,
- gpointer user_data)
-{
- ProxyData *parent_pd = user_data, *child_pd;
- gchar *encoded_string;
-
- encoded_string = g_strconcat (parent_pd->iface_name, ":", g_dbus_object_get_object_path (object), NULL);
- child_pd = proxy_data_new (encoded_string);
- g_free (encoded_string);
-
- if (child_pd) {
- proxy_data_reg_interfaces (child_pd, parent_pd->regs_connection);
- parent_pd->object_manager_pds = g_slist_prepend (parent_pd->object_manager_pds, child_pd);
- }
-}
-
-static void
-object_manager_object_removed_cb (GDBusObjectManager *manager,
- GDBusObject *object,
- gpointer user_data)
-{
- ProxyData *parent_pd = user_data;
- GSList *link;
- const gchar *obj_path;
-
- obj_path = g_dbus_object_get_object_path (object);
- for (link = parent_pd->object_manager_pds; link; link = g_slist_next (link)) {
- ProxyData *child_pd = link->data;
-
- if (child_pd && g_strcmp0 (child_pd->path, obj_path) == 0) {
- proxy_data_free (child_pd);
- parent_pd->object_manager_pds = g_slist_remove (parent_pd->object_manager_pds, child_pd);
- break;
- }
- }
-}
-
-static gpointer
-main_loop_thread (gpointer user_data)
-{
- GMainLoop *main_loop = user_data;
-
- g_main_loop_run (main_loop);
-
- return NULL;
-}
-
-/* Adapted from glib's gtestdbus.c */
-static gchar *
-write_config_file (const GSList *service_dirs)
-{
- GString *contents;
- gint fd;
- GSList *link;
- gchar *path = NULL;
- GError *error = NULL;
-
- fd = g_file_open_tmp ("evolution-bus-tunnel-XXXXXX", &path, &error);
- if (fd <= 0) {
- g_warning ("Failed to create tmp file for D-Bus configuration: %s", error ? error->message : "Unknown error");
- g_clear_error (&error);
- return NULL;
- }
-
- contents = g_string_new (NULL);
- g_string_append (contents,
- "\n"
- " session\n"
- " unix:tmpdir=/tmp\n");
-
- for (link = (GSList *) service_dirs; link; link = g_slist_next (link)) {
- const gchar *dir_path = link->data;
-
- g_string_append_printf (contents," %s\n", dir_path);
- }
-
- g_string_append (contents,
- " \n"
- " \n"
- " \n"
- " \n"
- " \n"
- " \n"
- " \n"
- " \n"
- "\n");
-
- close (fd);
- if (!g_file_set_contents (path, contents->str, contents->len, &error)) {
- g_warning ("Failed to write file '%s': %s", path, error ? error->message : "Unknown error");
- g_clear_error (&error);
- g_free (path);
- return NULL;
- }
-
- g_string_free (contents, TRUE);
-
- return path;
-}
-
-/* Adapted from glib's gtestdbus.c */
-static gboolean
-start_daemon (const GSList *service_dirs,
- GPid *pbus_pid,
- gint *pbus_stdout_fd,
- gchar **pbus_address)
-{
- const gchar *argv[] = {"dbus-daemon", "--print-address", "--config-file=foo", NULL};
- gchar *config_path;
- gchar *config_arg;
- GIOChannel *channel;
- gint stdout_fd2;
- gsize termpos;
- GError *error = NULL;
-
- /* Write config file and set its path in argv */
- config_path = write_config_file (service_dirs);
- config_arg = g_strdup_printf ("--config-file=%s", config_path);
- argv[2] = config_arg;
-
- /* Spawn dbus-daemon */
- g_spawn_async_with_pipes (NULL, (gchar **) argv, NULL,
- G_SPAWN_SEARCH_PATH, NULL, NULL, pbus_pid,
- NULL, pbus_stdout_fd, NULL, &error);
- if (error) {
- g_warning ("Failed to start D-Bus daemon: %s", error->message);
- g_clear_error (&error);
- g_free (config_path);
- g_free (config_arg);
- return FALSE;
- }
-
- /* Read bus address from daemon' stdout. We have to be careful to avoid
- * closing the FD, as it is passed to any D-Bus service activated processes,
- * and if we close it, they will get a SIGPIPE and die when they try to write
- * to their stdout. */
- stdout_fd2 = dup (*pbus_stdout_fd);
- g_assert_cmpint (stdout_fd2, >=, 0);
- channel = g_io_channel_unix_new (stdout_fd2);
-
- g_io_channel_read_line (channel, pbus_address, NULL, &termpos, &error);
- if (error) {
- g_warning ("Failed to read new D-Bus daemon address: %s", error->message);
- g_io_channel_shutdown (channel, FALSE, NULL);
- g_io_channel_unref (channel);
- g_clear_error (&error);
- g_free (config_path);
- g_free (config_arg);
- return FALSE;
- }
-
- (*pbus_address)[termpos] = '\0';
-
- /* Cleanup */
- g_io_channel_shutdown (channel, FALSE, &error);
- if (error) {
- g_debug ("Failed to shutdown io channel: %s", error->message);
- g_clear_error (&error);
- }
- g_io_channel_unref (channel);
-
- /* Don't use g_file_delete since it calls into gvfs */
- if (g_unlink (config_path) != 0)
- g_warning ("Failed to remove config file '%s'", config_path);
-
- g_free (config_path);
- g_free (config_arg);
-
- g_unsetenv ("DBUS_STARTER_ADDRESS");
- g_unsetenv ("DBUS_STARTER_BUS_TYPE");
- g_setenv ("DBUS_SESSION_BUS_ADDRESS", *pbus_address, TRUE);
-
- return TRUE;
-}
-
-/* Adapted from glib's gtestdbus.c */
-static void
-stop_daemon (GPid *pbus_pid,
- gint *pbus_stdout_fd,
- gchar **pbus_address)
-{
- kill (*pbus_pid, SIGTERM);
- g_spawn_close_pid (*pbus_pid);
- *pbus_pid = 0;
-
- close (*pbus_stdout_fd);
- *pbus_stdout_fd = -1;
-
- g_free (*pbus_address);
- *pbus_address = NULL;
-}
-
-static void
-print_help (void)
-{
- printf ("Usage: evolution-dbus-session --exec exec [ --service-dir dir ] [ --iface name:path ]\n");
- printf (" --help ... shows this help and exits\n");
- printf (" --exec exec ... a program to run in a dedicated D-Bus session\n");
- printf (" --service-dir dir ... adds a dir as a service directory for the new D-Bus session\n");
- printf (" --iface name:path ... adds an interface name and its D-Bus path to proxy into the new D-Bus session\n");
- printf ("\n");
- printf (" Both --service-dir and --iface arguments are optional and can be specified multiple times.\n");
-}
-
-gint
-main (gint argc,
- gchar *argv[])
-{
- GPid bus_pid = 0;
- gint bus_stdout_fd = -1, ii, res = 0;
- gchar *bus_address = NULL;
- GSList *service_dirs = NULL;
- GSList *pds = NULL; /* ProxyData * */
- const gchar *to_exec = NULL;
-
- if (argc == 1) {
- print_help ();
- return 0;
- }
-
- for (ii = 1; ii < argc; ii++) {
- if (g_str_equal (argv[ii], "--help")) {
- print_help ();
- g_slist_free_full (pds, proxy_data_free);
- g_slist_free (service_dirs);
- return 0;
- } else if (g_str_equal (argv[ii], "--exec")) {
- if (ii + 1 >= argc) {
- g_printerr ("Missing value for %s\n", argv[ii]);
- return 1;
- }
-
- ii++;
- to_exec = argv[ii];
- } else if (g_str_equal (argv[ii], "--service-dir")) {
- if (ii + 1 >= argc) {
- g_printerr ("Missing value for %s\n", argv[ii]);
- return 2;
- }
-
- ii++;
- service_dirs = g_slist_prepend (service_dirs, argv[ii]);
- } else if (g_str_equal (argv[ii], "--iface")) {
- ProxyData *pd;
-
- if (ii + 1 >= argc) {
- g_printerr ("Missing value for %s\n", argv[ii]);
- return 3;
- }
-
- ii++;
- pd = proxy_data_new (argv[ii]);
- if (pd) {
- pds = g_slist_prepend (pds, pd);
- }
- } else {
- g_printerr ("Unknown argument '%s'\n", argv[ii]);
- return 4;
- }
- }
-
- if (!pds) {
- g_printerr ("No --iface defined or cannot connect to any, exiting\n");
- g_slist_free_full (pds, proxy_data_free);
- g_slist_free (service_dirs);
- return 5;
- }
-
- if (!to_exec) {
- g_printerr ("No --exec defined, exiting\n");
- g_slist_free_full (pds, proxy_data_free);
- g_slist_free (service_dirs);
- return 6;
- }
-
- /* Preserve order as specified on the command line */
- pds = g_slist_reverse (pds);
- service_dirs = g_slist_reverse (service_dirs);
-
- if (start_daemon (service_dirs, &bus_pid, &bus_stdout_fd, &bus_address)) {
- GThread *thread;
- GMainLoop *main_loop;
- GDBusConnection *connection;
- GError *error = NULL;
-
- connection = g_dbus_connection_new_for_address_sync (bus_address,
- G_DBUS_CONNECTION_FLAGS_AUTHENTICATION_CLIENT | G_DBUS_CONNECTION_FLAGS_MESSAGE_BUS_CONNECTION, NULL, NULL, &error);
- if (connection) {
- GSList *link;
-
- for (link = pds; link; link = g_slist_next (link)) {
- ProxyData *pd = link->data;
-
- if (!pd)
- continue;
-
- pd->ownid = g_bus_own_name_on_connection (connection,
- pd->iface_name,
- G_BUS_NAME_OWNER_FLAGS_DO_NOT_QUEUE,
- bus_name_acquired_cb,
- bus_name_lost_cb,
- pd, NULL);
- }
-
- main_loop = g_main_loop_new (NULL, FALSE);
-
- thread = g_thread_new (NULL, main_loop_thread, main_loop);
-
- if (system (to_exec) == -1)
- g_warning ("Failed to execute '%s'", to_exec);
-
- if (!g_dbus_connection_is_closed (connection) &&
- !g_dbus_connection_close_sync (connection, NULL, &error)) {
- g_warning ("Failed to close connection: %s", error ? error->message : "Unknown error");
- g_clear_error (&error);
- }
-
- g_slist_free_full (pds, proxy_data_free);
- pds = NULL;
-
- stop_daemon (&bus_pid, &bus_stdout_fd, &bus_address);
- g_main_loop_quit (main_loop);
- g_thread_join (thread);
-
- g_main_loop_unref (main_loop);
- g_clear_object (&connection);
- } else {
- g_warning ("Failed to create connection for dedicated server address '%s': %s",
- bus_address, error ? error->message : "Unknown error");
- g_clear_error (&error);
- }
- } else {
- res = 7;
- }
-
- g_slist_free_full (pds, proxy_data_free);
- g_slist_free (service_dirs);
-
- return res;
-}