[kdbus] Don't serialize message to a blob when we use kdbus transport
[platform/upstream/glib.git] / gio / gdbusaddress.c
index 421b180..d82a09a 100644 (file)
@@ -39,6 +39,7 @@
 #include "gdbusprivate.h"
 #include "giomodule-priv.h"
 #include "gdbusdaemon.h"
+#include "gkdbus.h"
 
 #ifdef G_OS_UNIX
 #include <gio/gunixsocketaddress.h>
@@ -60,7 +61,7 @@
  *
  * Routines for working with D-Bus addresses. A D-Bus address is a string
  * like "unix:tmpdir=/tmp/my-app-name". The exact format of addresses
- * is explained in detail in the <link linkend="http://dbus.freedesktop.org/doc/dbus-specification.html&num;addresses">D-Bus specification</link>.
+ * is explained in detail in the [D-Bus specification](http://dbus.freedesktop.org/doc/dbus-specification.html\#addresses).
  */
 
 static gchar *get_session_address_platform_specific (GError **error);
@@ -521,8 +522,9 @@ out:
 
 /* ---------------------------------------------------------------------------------------------------- */
 
-static GIOStream *
+static GObject *
 g_dbus_address_try_connect_one (const gchar   *address_entry,
+                                gboolean       kdbus_okay,
                                 gchar        **out_guid,
                                 GCancellable  *cancellable,
                                 GError       **error);
@@ -532,14 +534,15 @@ g_dbus_address_try_connect_one (const gchar   *address_entry,
  * point. That way we can implement a D-Bus transport over X11 without
  * making libgio link to libX11...
  */
-static GIOStream *
+static GObject *
 g_dbus_address_connect (const gchar   *address_entry,
                         const gchar   *transport_name,
+                        gboolean       kdbus_okay,
                         GHashTable    *key_value_pairs,
                         GCancellable  *cancellable,
                         GError       **error)
 {
-  GIOStream *ret;
+  GObject *ret;
   GSocketConnectable *connectable;
   const gchar *nonce_file;
 
@@ -551,6 +554,29 @@ g_dbus_address_connect (const gchar   *address_entry,
     {
     }
 #ifdef G_OS_UNIX
+  else if (kdbus_okay && g_str_equal (transport_name, "kernel"))
+    {
+      GKDBusWorker *worker;
+      const gchar *path;
+
+      path = g_hash_table_lookup (key_value_pairs, "path");
+
+      if (path == NULL)
+        {
+          g_set_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT,
+                       _("Error in address '%s' - the kernel transport requires a path"),
+                       address_entry);
+        }
+      else
+        {
+          worker = g_kdbus_worker_new (path, error);
+
+          if (worker == NULL)
+            return NULL;
+
+          return G_OBJECT (worker);
+        }
+    }
   else if (g_strcmp0 (transport_name, "unix") == 0)
     {
       const gchar *path;
@@ -641,7 +667,7 @@ g_dbus_address_connect (const gchar   *address_entry,
       autolaunch_address = get_session_address_platform_specific (error);
       if (autolaunch_address != NULL)
         {
-          ret = g_dbus_address_try_connect_one (autolaunch_address, NULL, cancellable, error);
+          ret = g_dbus_address_try_connect_one (autolaunch_address, kdbus_okay, NULL, cancellable, error);
           g_free (autolaunch_address);
           goto out;
         }
@@ -676,7 +702,7 @@ g_dbus_address_connect (const gchar   *address_entry,
       if (connection == NULL)
         goto out;
 
-      ret = G_IO_STREAM (connection);
+      ret = G_OBJECT (connection);
 
       if (nonce_file != NULL)
         {
@@ -729,7 +755,7 @@ g_dbus_address_connect (const gchar   *address_entry,
             }
           fclose (f);
 
-          if (!g_output_stream_write_all (g_io_stream_get_output_stream (ret),
+          if (!g_output_stream_write_all (g_io_stream_get_output_stream (G_IO_STREAM (connection)),
                                           nonce_contents,
                                           16,
                                           NULL,
@@ -749,13 +775,14 @@ g_dbus_address_connect (const gchar   *address_entry,
   return ret;
 }
 
-static GIOStream *
+static GObject *
 g_dbus_address_try_connect_one (const gchar   *address_entry,
+                                gboolean       kdbus_okay,
                                 gchar        **out_guid,
                                 GCancellable  *cancellable,
                                 GError       **error)
 {
-  GIOStream *ret;
+  GObject *ret;
   GHashTable *key_value_pairs;
   gchar *transport_name;
   const gchar *guid;
@@ -772,6 +799,7 @@ g_dbus_address_try_connect_one (const gchar   *address_entry,
 
   ret = g_dbus_address_connect (address_entry,
                                 transport_name,
+                                kdbus_okay,
                                 key_value_pairs,
                                 cancellable,
                                 error);
@@ -939,7 +967,25 @@ g_dbus_address_get_stream_sync (const gchar   *address,
                                 GCancellable  *cancellable,
                                 GError       **error)
 {
-  GIOStream *ret;
+  GObject *result;
+
+  result = g_dbus_address_get_stream_internal (address, FALSE, out_guid, cancellable, error);
+  g_assert (result == NULL || G_IS_IO_STREAM (result));
+
+  if (result)
+    return G_IO_STREAM (result);
+
+  return NULL;
+}
+
+GObject *
+g_dbus_address_get_stream_internal (const gchar   *address,
+                                    gboolean       kdbus_okay,
+                                    gchar        **out_guid,
+                                    GCancellable  *cancellable,
+                                    GError       **error)
+{
+  GObject *ret;
   gchar **addr_array;
   guint n;
   GError *last_error;
@@ -966,6 +1012,7 @@ g_dbus_address_get_stream_sync (const gchar   *address,
 
       this_error = NULL;
       ret = g_dbus_address_try_connect_one (addr,
+                                            kdbus_okay,
                                             out_guid,
                                             cancellable,
                                             &this_error);
@@ -1452,15 +1499,16 @@ get_session_address_platform_specific (GError **error)
 
 /**
  * g_dbus_address_get_for_bus_sync:
- * @bus_type: A #GBusType.
- * @cancellable: (allow-none): A #GCancellable or %NULL.
- * @error: Return location for error or %NULL.
+ * @bus_type: a #GBusType
+ * @cancellable: (allow-none): a #GCancellable or %NULL
+ * @error: return location for error or %NULL
  *
  * Synchronously looks up the D-Bus address for the well-known message
  * bus instance specified by @bus_type. This may involve using various
  * platform specific mechanisms.
  *
- * Returns: A valid D-Bus address string for @bus_type or %NULL if @error is set.
+ * Returns: a valid D-Bus address string for @bus_type or %NULL if
+ *     @error is set
  *
  * Since: 2.26
  */
@@ -1470,6 +1518,8 @@ g_dbus_address_get_for_bus_sync (GBusType       bus_type,
                                  GError       **error)
 {
   gchar *ret;
+  const gchar *system_bus;
+  const gchar *session_bus;
   const gchar *starter_bus;
   GError *local_error;
 
@@ -1523,6 +1573,23 @@ g_dbus_address_get_for_bus_sync (GBusType       bus_type,
         }
       break;
 
+    case G_BUS_TYPE_MACHINE:
+      system_bus = g_getenv ("DBUS_SYSTEM_BUS_ADDRESS");
+      if (system_bus == NULL)
+        ret = g_strdup ("kernel:path=/sys/fs/kdbus/0-system/bus;unix:path=/var/run/dbus/system_bus_socket");
+      else
+        ret = g_strdup_printf ("kernel:path=/sys/fs/kdbus/0-system/bus;%s", system_bus);
+      break;
+
+    case G_BUS_TYPE_USER:
+      session_bus = g_getenv ("DBUS_SESSION_BUS_ADDRESS");
+      if (session_bus == NULL)
+        ret = g_strdup_printf ("kernel:path=%s/kdbus;%s", g_get_user_runtime_dir (),
+                                   get_session_address_platform_specific (&local_error));
+      else
+        ret = g_strdup_printf ("kernel:path=%s/kdbus;%s", g_get_user_runtime_dir (), session_bus);
+      break;
+
     case G_BUS_TYPE_STARTER:
       starter_bus = g_getenv ("DBUS_STARTER_BUS_TYPE");
       if (g_strcmp0 (starter_bus, "session") == 0)
@@ -1594,18 +1661,18 @@ g_dbus_address_get_for_bus_sync (GBusType       bus_type,
 /**
  * g_dbus_address_escape_value:
  * @string: an unescaped string to be included in a D-Bus address
- *  as the value in a key-value pair
+ *     as the value in a key-value pair
  *
  * Escape @string so it can appear in a D-Bus address as the value
  * part of a key-value pair.
  *
- * For instance, if @string is <code>/run/bus-for-:0</code>,
- * this function would return <code>/run/bus-for-%3A0</code>,
+ * For instance, if @string is "/run/bus-for-:0",
+ * this function would return "/run/bus-for-%3A0",
  * which could be used in a D-Bus address like
- * <code>unix:nonce-tcp:host=127.0.0.1,port=42,noncefile=/run/bus-for-%3A0</code>.
+ * "unix:nonce-tcp:host=127.0.0.1,port=42,noncefile=/run/bus-for-%3A0".
  *
  * Returns: (transfer full): a copy of @string with all
- *  non-optionally-escaped bytes escaped
+ *     non-optionally-escaped bytes escaped
  *
  * Since: 2.36
  */