--- /dev/null
+From 979bfb2448c3895a303041c1d422daf7930f3a51 Mon Sep 17 00:00:00 2001
+From: Christian Persch <chpe@gnome.org>
+Date: Sat, 8 May 2010 02:13:43 +0200
+Subject: [PATCH] Port gconfd-2 to GDBus
+
+Bug #618039.
+---
+ gconf/gconfd.c | 328 +++++++++++++++++++++++++++++---------------------------
+ 1 files changed, 170 insertions(+), 158 deletions(-)
+
+diff --git a/gconf/gconfd.c b/gconf/gconfd.c
+index b89e7a1..ee9d6ad 100644
+--- a/gconf/gconfd.c
++++ b/gconf/gconfd.c
+@@ -55,7 +55,7 @@
+ #endif
+ #include <locale.h>
+
+-#include <dbus/dbus-glib-lowlevel.h>
++#include <gio/gio.h>
+
+ #ifdef G_OS_WIN32
+ #include <io.h>
+@@ -518,152 +518,144 @@ gconf_get_poa (void)
+ return the_poa;
+ }
+
+-static const char *
+-get_introspection_xml (void)
+-{
+- return "<!DOCTYPE node PUBLIC \"-//freedesktop//DTD D-BUS Object Introspection 1.0//EN\"\n"
+- "\"http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd\">\n"
+- "<node>\n"
+- " <interface name=\"org.freedesktop.DBus.Introspectable\">\n"
+- " <method name=\"Introspect\">\n"
+- " <arg name=\"introspection_xml\" direction=\"out\" type=\"s\"/>\n"
+- " </method>\n"
+- " </interface>\n"
+- " <interface name=\"org.gnome.GConf\">\n"
+- " <method name=\"GetIOR\">\n"
+- " <arg name=\"ior\" direction=\"out\" type=\"s\"/>\n"
+- " </method>\n"
+- " </interface>\n"
+- "</node>\n";
+-}
+-
+-static DBusHandlerResult
+-bus_message_handler (DBusConnection *connection,
+- DBusMessage *message,
+- void *user_data)
++static void
++handle_method_call (GDBusConnection *connection,
++ const gchar *sender,
++ const gchar *object_path,
++ const gchar *interface_name,
++ const gchar *method_name,
++ GVariant *parameters,
++ GDBusMethodInvocation *invocation,
++ gpointer user_data)
+ {
+- DBusMessage *reply;
+-
+- reply = NULL;
+-
+- if (dbus_message_is_signal (message,
+- DBUS_INTERFACE_LOCAL,
+- "Disconnected"))
++ if (g_strcmp0 (method_name, "GetIOR") == 0)
+ {
+- gconf_main_quit ();
+- return DBUS_HANDLER_RESULT_HANDLED;
++ g_dbus_method_invocation_return_value (invocation,
++ g_variant_new ("(s)", gconf_get_daemon_ior ()));
+ }
+- else if (dbus_message_is_method_call (message,
+- "org.freedesktop.DBus.Introspectable",
+- "Introspect"))
+- {
+- const char *introspection_xml;
+-
+- introspection_xml = get_introspection_xml ();
+-
+- reply = dbus_message_new_method_return (message);
+- dbus_message_append_args (reply, DBUS_TYPE_STRING, &introspection_xml,
+- DBUS_TYPE_INVALID);
+-
+- }
+- else if (dbus_message_is_method_call (message,
+- "org.gnome.GConf",
+- "GetIOR"))
+- {
+- const char *ior;
++}
+
+- ior = gconf_get_daemon_ior ();
++static void
++on_name_acquired (GDBusConnection *connection,
++ const gchar *name,
++ gpointer user_data)
++{
++ * (gboolean *) user_data = TRUE;
++ gconf_main_quit ();
++}
+
+- reply = dbus_message_new_method_return (message);
+- dbus_message_append_args (reply, DBUS_TYPE_STRING, &ior, DBUS_TYPE_INVALID);
+- }
++static void
++on_name_lost (GDBusConnection *connection,
++ const gchar *name,
++ gpointer user_data)
++{
++ * (gboolean *) user_data = FALSE;
+
+- if (reply != NULL)
+- {
+- dbus_connection_send (connection, reply, NULL);
+- dbus_message_unref (reply);
+- return DBUS_HANDLER_RESULT_HANDLED;
+- }
++ gconf_log (GCL_WARNING,
++ _("Failed to get bus name for daemon, exiting."));
+
+- return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
++ gconf_main_quit ();
+ }
+
+-static DBusConnection *
+-get_on_d_bus (void)
++static GDBusConnection *
++own_org_gnome_GConf (void)
+ {
+- DBusConnection *connection;
+- DBusError bus_error;
+- int result;
+-
+- dbus_error_init (&bus_error);
+- connection = dbus_bus_get (DBUS_BUS_SESSION, &bus_error);
+-
+- if (dbus_error_is_set (&bus_error))
++ static const char introspection_xml[] =
++ "<node>"
++ "<interface name='org.gnome.GConf'>"
++ "<method name='GetIOR'>"
++ "<arg name='ior' direction='out' type='s'/>"
++ "</method>"
++ "</interface>"
++ "</node>";
++ static const GDBusInterfaceVTable interface_vtable =
++ {
++ handle_method_call,
++ NULL,
++ NULL
++ };
++
++ GDBusConnection *connection;
++ GDBusNodeInfo *introspection_data;
++ guint registration_id;
++ guint owner_id;
++ gboolean *do_own_ptr;
++ GError *error = NULL;
++
++ connection = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, &error);
++ if (connection == NULL)
+ {
+- gconf_log (GCL_ERR, _("Could not connect to session bus: %s"), bus_error.message);
+- dbus_error_free (&bus_error);
++ gconf_log (GCL_ERR, _("Could not connect to session bus: %s"), error->message);
++ g_error_free (error);
+ return NULL;
+ }
+
+- dbus_connection_setup_with_g_main (connection, NULL);
++ introspection_data = g_dbus_node_info_new_for_xml (introspection_xml, NULL);
++ g_assert (introspection_data != NULL);
+
+- if (!dbus_connection_add_filter (connection, (DBusHandleMessageFunction)
+- bus_message_handler, NULL, NULL))
++ registration_id = g_dbus_connection_register_object (connection,
++ "/org/gnome/GConf",
++ introspection_data->interfaces[0],
++ &interface_vtable,
++ introspection_data,
++ (GDestroyNotify) g_dbus_node_info_unref,
++ &error);
++ if (registration_id == 0)
+ {
+- dbus_connection_unref (connection);
++ gconf_log (GCL_ERR, "Failed to register object: %s", error->message);
++ g_error_free (error);
++ g_object_unref (connection);
+ return NULL;
+ }
+
+- dbus_connection_set_exit_on_disconnect (connection, FALSE);
++ g_dbus_connection_set_exit_on_close (connection, FALSE);
++ g_signal_connect (connection, "closed", G_CALLBACK (gconf_main_quit), NULL);
+
+- result = dbus_bus_request_name (connection, "org.gnome.GConf",
+- 0, &bus_error);
++ do_own_ptr = g_new (gboolean, 1);
++ *do_own_ptr = FALSE;
+
+- if (dbus_error_is_set (&bus_error))
+- {
+- gconf_log (GCL_WARNING,
+- _("Failed to get bus name for daemon, exiting: %s"),
+- bus_error.message);
+- dbus_error_free (&bus_error);
+- }
++ owner_id = g_bus_own_name_on_connection (connection,
++ "org.gnome.GConf",
++ G_BUS_NAME_OWNER_FLAGS_NONE,
++ on_name_acquired,
++ on_name_lost,
++ do_own_ptr, (GDestroyNotify) g_free);
+
+- if (result != DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER)
+- {
+- dbus_connection_unref (connection);
+- return NULL;
+- }
++ gconf_main ();
+
+- return connection;
++ if (*do_own_ptr)
++ return connection;
++
++ g_object_unref (connection);
++ return NULL;
+ }
+
+ #ifdef ENABLE_DEFAULTS_SERVICE
+ /* listen on system bus for defaults changes */
+
+-static DBusHandlerResult
+-system_bus_message_handler (DBusConnection *connection,
+- DBusMessage *message,
+- void *user_data)
+-{
+- DBusMessage *reply;
+-
+- reply = NULL;
+-
+- if (dbus_message_is_signal (message,
+- "org.gnome.GConf.Defaults",
+- "SystemSet"))
+- {
+- DBusError bus_error;
+- char **keys;
+- int n_keys;
++typedef struct {
++ guint watch_id;
++ guint subscription_id;
++} DefaultsData;
+
+- dbus_error_init (&bus_error);
+- if (dbus_message_get_args (message, &bus_error,
+- DBUS_TYPE_ARRAY, DBUS_TYPE_STRING, &keys, &n_keys,
+- DBUS_TYPE_INVALID))
++static void
++system_set_cb (GDBusConnection *connection,
++ const gchar *sender_name,
++ const gchar *object_path,
++ const gchar *interface_name,
++ const gchar *signal_name,
++ GVariant *parameters,
++ gpointer user_data)
++{
++ if (g_strcmp0 (interface_name, "org.gnome.GConf.Defaults") == 0 &&
++ g_strcmp0 (signal_name, "SystemSet") == 0)
++ {
++ if (g_variant_is_of_type (parameters, G_VARIANT_TYPE ("(as)")))
+ {
+- char **key;
+ GConfSources *system_sources;
+ GSList addresses;
++ GVariantIter *iter;
++ const char *key;
+
+ gconf_log (GCL_DEBUG, "System defaults changed. Notifying.");
+
+@@ -673,61 +665,72 @@ system_bus_message_handler (DBusConnection *connection,
+
+ gconfd_clear_cache_for_sources (system_sources);
+
+- for (key = keys; *key; key++)
+- gconfd_notify_other_listeners (NULL, system_sources, *key);
++ g_variant_get (parameters, "(as)", &iter);
++ while (g_variant_iter_loop (iter, "&s", &key))
++ gconfd_notify_other_listeners (NULL, system_sources, key);
++ g_variant_iter_free (iter);
+
+ gconf_sources_free (system_sources);
+-
+- dbus_free_string_array (keys);
+ }
+ else
+ {
+- gconf_log (GCL_DEBUG, "SystemSet signal received, but error getting message: %s", bus_error.message);
++ gconf_log (GCL_DEBUG, "SystemSet signal received, but wrong paramters type '%s'",
++ g_variant_get_type_string (parameters));
+ }
+- dbus_error_free (&bus_error);
+-
+- return DBUS_HANDLER_RESULT_HANDLED;
+ }
+-
+- return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
+ }
+
+-static DBusConnection *
+-get_on_system_bus (void)
++static void
++defaults_appeared_cb (GDBusConnection *connection,
++ const gchar *name,
++ const gchar *name_owner,
++ gpointer user_data)
+ {
+- DBusConnection *connection;
+- DBusError bus_error;
++ DefaultsData *data = (DefaultsData *) user_data;
+
+- dbus_error_init (&bus_error);
+- connection = dbus_bus_get (DBUS_BUS_SYSTEM, &bus_error);
++ gconf_log (GCL_DEBUG, "Defaults service appeared with name '%s'", name_owner);
+
+- if (dbus_error_is_set (&bus_error))
+- {
+- gconf_log (GCL_ERR, _("Could not connect to system bus: %s"), bus_error.message);
+- dbus_error_free (&bus_error);
+- return NULL;
+- }
++ g_assert (data->subscription_id == 0);
++ data->subscription_id = g_dbus_connection_signal_subscribe (connection,
++ name_owner,
++ "org.gnome.GConf.Defaults",
++ "SystemSet",
++ "/" /* really? */,
++ NULL,
++ G_DBUS_SIGNAL_FLAGS_NONE,
++ system_set_cb,
++ user_data, NULL);
++}
+
+- dbus_connection_setup_with_g_main (connection, NULL);
++static void
++defaults_vanished_cb (GDBusConnection *connection,
++ const gchar *name,
++ gpointer user_data)
++{
++ DefaultsData *data = (DefaultsData *) user_data;
+
+- dbus_bus_add_match (connection, "type='signal',interface='org.gnome.GConf.Defaults'", &bus_error);
+- dbus_connection_flush(connection);
+- if (dbus_error_is_set (&bus_error))
+- {
+- gconf_log (GCL_DEBUG, "Failed to add signal match to system bus: %s", bus_error.message);
+- dbus_connection_unref (connection);
+- return NULL;
+- }
++ gconf_log (GCL_DEBUG, "Defaults service disappeared");
+
+- if (!dbus_connection_add_filter (connection, (DBusHandleMessageFunction)
+- system_bus_message_handler, NULL, NULL))
+- {
+- gconf_log (GCL_DEBUG, "Failed to add message filter to system bus.");
+- dbus_connection_unref (connection);
+- return NULL;
+- }
++ if (data->subscription_id != 0) {
++ g_dbus_connection_signal_unsubscribe (connection , data->subscription_id);
++ data->subscription_id = 0;
++ }
++}
+
+- return connection;
++static DefaultsData *
++get_on_system_bus (void)
++{
++ DefaultsData *data = g_new (DefaultsData, 1);
++
++ data->subscription_id = 0;
++ data->watch_id = g_bus_watch_name (G_BUS_TYPE_SYSTEM,
++ "org.gnome.GConf.Defaults",
++ G_BUS_NAME_WATCHER_FLAGS_NONE,
++ defaults_appeared_cb,
++ defaults_vanished_cb,
++ data, NULL);
++
++ return data;
+ }
+ #endif /* ENABLE_DEFAULTS_SERVICE */
+
+@@ -759,7 +762,8 @@ main(int argc, char** argv)
+ GError *err;
+ int dev_null_fd;
+ int write_byte_fd;
+- DBusConnection *connection;
++ GDBusConnection *connection;
++ DefaultsData *defaults_data;
+
+ _gconf_init_i18n ();
+ setlocale (LC_ALL, "");
+@@ -896,8 +900,7 @@ main(int argc, char** argv)
+ gconf_set_daemon_ior (ior);
+ CORBA_free (ior);
+
+- connection = get_on_d_bus ();
+-
++ connection = own_org_gnome_GConf ();
+ if (connection != NULL)
+ {
+ /* This loads backends and so on. It needs to be done before
+@@ -934,11 +937,20 @@ main(int argc, char** argv)
+ logfile_read ();
+
+ #ifdef ENABLE_DEFAULTS_SERVICE
+- get_on_system_bus ();
++ defaults_data = get_on_system_bus ();
+ #endif
+
+ gconf_main ();
+
++ g_object_unref (connection);
++ connection = NULL;
++
++ if (defaults_data->subscription_id != 0) {
++ g_dbus_connection_signal_unsubscribe (connection , defaults_data->subscription_id);
++ }
++ g_bus_unwatch_name (defaults_data->watch_id);
++ g_free (defaults_data);
++
+ if (in_shutdown)
+ exit_code = 1; /* means someone already called enter_shutdown() */
+
+--
+1.6.6.1
+