Catch up with latest gdbus-codegen and use this to make better drive paths
authorDavid Zeuthen <davidz@redhat.com>
Mon, 1 Nov 2010 14:59:25 +0000 (10:59 -0400)
committerDavid Zeuthen <davidz@redhat.com>
Mon, 1 Nov 2010 15:01:32 +0000 (11:01 -0400)
E.g.

 $ udisks info --object-path drives/ <TAB>
 drives/INTEL_20SSDSA2MH080G1GCCVEM842101HD080DGN
 drives/MATSHITADVD_2fCDRW_20UJDA775

Signed-off-by: David Zeuthen <davidz@redhat.com>
doc/udisks-sections.txt.in
src/udisksdaemon.c
src/udisksdaemonutil.c
src/udisksdaemonutil.h
src/udiskslinuxblock.c
src/udiskslinuxdrive.c
src/udiskslinuxprovider.c

index b7c6074..49bc40e 100644 (file)
@@ -242,5 +242,6 @@ udisks_persistent_store_get_type
 <SECTION>
 <FILE>udisksdaemonutil</FILE>
 udisks_decode_udev_string
+udisks_safe_append_to_object_path
 </SECTION>
 
index db21122..c27a822 100644 (file)
@@ -407,12 +407,15 @@ on_job_completed (UDisksJob    *job,
 {
   UDisksDaemon *daemon = UDISKS_DAEMON (user_data);
   GDBusObject *object;
+  gchar *object_path;
 
   object = g_dbus_interface_get_object (G_DBUS_INTERFACE (job));
   g_assert (object != NULL);
 
   /* Unexport job */
-  g_dbus_object_manager_unexport (daemon->object_manager, g_dbus_object_get_object_path (object));
+  object_path = g_dbus_object_get_object_path (object);
+  g_dbus_object_manager_unexport (daemon->object_manager, object_path);
+  g_free (object_path);
   g_dbus_object_remove_interface (object, G_DBUS_INTERFACE (job));
   g_object_unref (object);
 
index ea4f750..3ff28d8 100644 (file)
@@ -98,3 +98,37 @@ udisks_decode_udev_string (const gchar *str)
  out:
   return ret;
 }
+
+/**
+ * udisks_safe_append_to_object_path:
+ * @str: A #GString to append to.
+ * @s: A UTF-8 string.
+ *
+ * Appends @s to @str in a way such that only characters that can be
+ * used in a D-Bus object path will be used. E.g. a character not in
+ * <literal>[A-Z][a-z][0-9]_</literal> will be escaped as _HEX where
+ * HEX is a two-digit hexadecimal number.
+ */
+void
+udisks_safe_append_to_object_path (GString      *str,
+                                   const gchar  *s)
+{
+  guint n;
+  for (n = 0; s[n] != '\0'; n++)
+    {
+      gint c = s[n];
+      /* D-Bus spec sez:
+       *
+       * Each element must only contain the ASCII characters "[A-Z][a-z][0-9]_"
+       */
+      if ((c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z') || (c >= '0' && c <= '9'))
+        {
+          g_string_append_c (str, c);
+        }
+      else
+        {
+          /* Escape bytes not in [A-Z][a-z][0-9] as _<hex-with-two-digits> */
+          g_string_append_printf (str, "_%02x", c);
+        }
+    }
+}
index 75ce022..980349a 100644 (file)
@@ -27,6 +27,9 @@ G_BEGIN_DECLS
 
 gchar *udisks_decode_udev_string (const gchar *str);
 
+void udisks_safe_append_to_object_path (GString      *str,
+                                        const gchar  *s);
+
 
 G_END_DECLS
 
index 8a05727..a200131 100644 (file)
@@ -161,89 +161,11 @@ udisks_linux_block_init (UDisksLinuxBlock *block)
 {
 }
 
-static gchar *
-util_compute_object_path (const gchar *path)
-{
-  const gchar *basename;
-  GString *s;
-  guint n;
-
-  g_return_val_if_fail (path != NULL, NULL);
-
-  basename = strrchr (path, '/');
-  if (basename != NULL)
-    basename++;
-  else
-    basename = path;
-
-  s = g_string_new ("/org/freedesktop/UDisks/devices/");
-  for (n = 0; basename[n] != '\0'; n++)
-    {
-      gint c = basename[n];
-
-      /* D-Bus spec sez:
-       *
-       * Each element must only contain the ASCII characters "[A-Z][a-z][0-9]_"
-       */
-      if ((c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z') || (c >= '0' && c <= '9'))
-        {
-          g_string_append_c (s, c);
-        }
-      else
-        {
-          /* Escape bytes not in [A-Z][a-z][0-9] as _<hex-with-two-digits> */
-          g_string_append_printf (s, "_%02x", c);
-        }
-    }
-
-  return g_string_free (s, FALSE);
-}
-
-static GObjectConstructParam *
-find_construct_property (guint                  n_construct_properties,
-                         GObjectConstructParam *construct_properties,
-                         const gchar           *name)
-{
-  guint n;
-  for (n = 0; n < n_construct_properties; n++)
-    if (g_strcmp0 (g_param_spec_get_name (construct_properties[n].pspec), name) == 0)
-      return &construct_properties[n];
-  return NULL;
-}
-
-/* unless given, compute object path from sysfs path */
-static GObject *
-udisks_linux_block_constructor (GType                  type,
-                                guint                  n_construct_properties,
-                                GObjectConstructParam *construct_properties)
-{
-  GObjectConstructParam *device_cp;
-  GObjectConstructParam *object_path_cp;
-  GUdevDevice *device;
-  gchar *object_path;
-
-  device_cp = find_construct_property (n_construct_properties, construct_properties, "device");
-  object_path_cp = find_construct_property (n_construct_properties, construct_properties, "object-path");
-  g_assert (device_cp != NULL && object_path_cp != NULL);
-
-  device = G_UDEV_DEVICE (g_value_get_object (device_cp->value));
-  g_assert (device != NULL);
-
-  if (g_value_get_string (object_path_cp->value) == NULL)
-    {
-      object_path = util_compute_object_path (g_udev_device_get_sysfs_path (device));
-      g_value_take_string (object_path_cp->value, object_path);
-    }
-
-  return G_OBJECT_CLASS (udisks_linux_block_parent_class)->constructor (type,
-                                                                        n_construct_properties,
-                                                                        construct_properties);
-}
-
 static void
 udisks_linux_block_constructed (GObject *object)
 {
   UDisksLinuxBlock *block = UDISKS_LINUX_BLOCK (object);
+  GString *str;
 
   block->mount_monitor = udisks_daemon_get_mount_monitor (block->daemon);
   g_signal_connect (block->mount_monitor,
@@ -258,6 +180,12 @@ udisks_linux_block_constructed (GObject *object)
   /* initial coldplug */
   udisks_linux_block_uevent (block, "add", NULL);
 
+  /* compute the object path */
+  str = g_string_new ("/org/freedesktop/UDisks/devices/");
+  udisks_safe_append_to_object_path (str, g_udev_device_get_name (block->device));
+  g_dbus_object_set_object_path (G_DBUS_OBJECT (block), str->str);
+  g_string_free (str, TRUE);
+
   if (G_OBJECT_CLASS (udisks_linux_block_parent_class)->constructed != NULL)
     G_OBJECT_CLASS (udisks_linux_block_parent_class)->constructed (object);
 }
@@ -268,7 +196,6 @@ udisks_linux_block_class_init (UDisksLinuxBlockClass *klass)
   GObjectClass *gobject_class;
 
   gobject_class = G_OBJECT_CLASS (klass);
-  gobject_class->constructor  = udisks_linux_block_constructor;
   gobject_class->finalize     = udisks_linux_block_finalize;
   gobject_class->constructed  = udisks_linux_block_constructed;
   gobject_class->set_property = udisks_linux_block_set_property;
index 8aa9040..fa5f64a 100644 (file)
@@ -147,44 +147,6 @@ udisks_linux_drive_init (UDisksLinuxDrive *drive)
 {
 }
 
-static gchar *
-util_compute_object_path (const gchar *path)
-{
-  const gchar *basename;
-  GString *s;
-  guint n;
-
-  g_return_val_if_fail (path != NULL, NULL);
-
-  basename = strrchr (path, '/');
-  if (basename != NULL)
-    basename++;
-  else
-    basename = path;
-
-  s = g_string_new ("/org/freedesktop/UDisks/drives/");
-  for (n = 0; basename[n] != '\0'; n++)
-    {
-      gint c = basename[n];
-
-      /* D-Bus spec sez:
-       *
-       * Each element must only contain the ASCII characters "[A-Z][a-z][0-9]_"
-       */
-      if ((c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z') || (c >= '0' && c <= '9'))
-        {
-          g_string_append_c (s, c);
-        }
-      else
-        {
-          /* Escape bytes not in [A-Z][a-z][0-9] as _<hex-with-two-digits> */
-          g_string_append_printf (s, "_%02x", c);
-        }
-    }
-
-  return g_string_free (s, FALSE);
-}
-
 static GObjectConstructParam *
 find_construct_property (guint                  n_construct_properties,
                          GObjectConstructParam *construct_properties,
@@ -204,13 +166,10 @@ udisks_linux_drive_constructor (GType                  type,
                                 GObjectConstructParam *construct_properties)
 {
   GObjectConstructParam *device_cp;
-  GObjectConstructParam *object_path_cp;
   GUdevDevice *device;
-  gchar *object_path;
 
   device_cp = find_construct_property (n_construct_properties, construct_properties, "device");
-  object_path_cp = find_construct_property (n_construct_properties, construct_properties, "object-path");
-  g_assert (device_cp != NULL && object_path_cp != NULL);
+  g_assert (device_cp != NULL);
 
   device = G_UDEV_DEVICE (g_value_get_object (device_cp->value));
   g_assert (device != NULL);
@@ -221,11 +180,6 @@ udisks_linux_drive_constructor (GType                  type,
     }
   else
     {
-      if (g_value_get_string (object_path_cp->value) == NULL)
-        {
-          object_path = util_compute_object_path (g_udev_device_get_sysfs_path (device));
-          g_value_take_string (object_path_cp->value, object_path);
-        }
       return G_OBJECT_CLASS (udisks_linux_drive_parent_class)->constructor (type,
                                                                             n_construct_properties,
                                                                             construct_properties);
@@ -236,10 +190,35 @@ static void
 udisks_linux_drive_constructed (GObject *object)
 {
   UDisksLinuxDrive *drive = UDISKS_LINUX_DRIVE (object);
+  const gchar *vendor;
+  const gchar *model;
+  const gchar *serial;
+  GString *str;
 
   /* initial coldplug */
   udisks_linux_drive_uevent (drive, "add", NULL);
 
+  /* compute the object path */
+  vendor = udisks_drive_get_vendor (drive->iface_drive);
+  model = udisks_drive_get_model (drive->iface_drive);
+  serial = udisks_drive_get_serial (drive->iface_drive);
+  str = g_string_new ("/org/freedesktop/UDisks/drives/");
+  if (vendor == NULL && model == NULL && serial == NULL)
+    {
+      g_string_append (str, "drive");
+    }
+  else
+    {
+      if (vendor != NULL)
+        udisks_safe_append_to_object_path (str, vendor);
+      if (model != NULL)
+        udisks_safe_append_to_object_path (str, model);
+      if (serial != NULL)
+        udisks_safe_append_to_object_path (str, serial);
+    }
+  g_dbus_object_set_object_path (G_DBUS_OBJECT (drive), str->str);
+  g_string_free (str, TRUE);
+
   if (G_OBJECT_CLASS (udisks_linux_drive_parent_class)->constructed != NULL)
     G_OBJECT_CLASS (udisks_linux_drive_parent_class)->constructed (object);
 }
index beb4c11..82b8e22 100644 (file)
@@ -202,8 +202,11 @@ handle_block_uevent (UDisksLinuxProvider *provider,
       block = g_hash_table_lookup (provider->sysfs_to_block, sysfs_path);
       if (block != NULL)
         {
+          gchar *object_path;
+          object_path = g_dbus_object_get_object_path (G_DBUS_OBJECT (block));
           g_dbus_object_manager_unexport (udisks_daemon_get_object_manager (daemon),
-                                          g_dbus_object_get_object_path (G_DBUS_OBJECT (block)));
+                                          object_path);
+          g_free (object_path);
           g_warn_if_fail (g_hash_table_remove (provider->sysfs_to_block, sysfs_path));
         }
     }
@@ -217,8 +220,8 @@ handle_block_uevent (UDisksLinuxProvider *provider,
       else
         {
           block = udisks_linux_block_new (daemon, device);
-          g_dbus_object_manager_export (udisks_daemon_get_object_manager (daemon),
-                                        G_DBUS_OBJECT (block));
+          g_dbus_object_manager_export_and_uniquify (udisks_daemon_get_object_manager (daemon),
+                                                     G_DBUS_OBJECT (block));
           g_hash_table_insert (provider->sysfs_to_block, g_strdup (sysfs_path), block);
         }
     }
@@ -241,8 +244,11 @@ handle_scsi_uevent (UDisksLinuxProvider *provider,
       drive = g_hash_table_lookup (provider->sysfs_to_drive, sysfs_path);
       if (drive != NULL)
         {
+          gchar *object_path;
+          object_path = g_dbus_object_get_object_path (G_DBUS_OBJECT (drive));
           g_dbus_object_manager_unexport (udisks_daemon_get_object_manager (daemon),
-                                          g_dbus_object_get_object_path (G_DBUS_OBJECT (drive)));
+                                          object_path);
+          g_free (object_path);
           g_warn_if_fail (g_hash_table_remove (provider->sysfs_to_drive, sysfs_path));
         }
     }
@@ -258,8 +264,8 @@ handle_scsi_uevent (UDisksLinuxProvider *provider,
           drive = udisks_linux_drive_new (daemon, device);
           if (drive != NULL)
             {
-              g_dbus_object_manager_export (udisks_daemon_get_object_manager (daemon),
-                                            G_DBUS_OBJECT (drive));
+              g_dbus_object_manager_export_and_uniquify (udisks_daemon_get_object_manager (daemon),
+                                                         G_DBUS_OBJECT (drive));
               g_hash_table_insert (provider->sysfs_to_drive, g_strdup (sysfs_path), drive);
             }
         }