E.g.
$ udisks info --object-path drives/ <TAB>
drives/INTEL_20SSDSA2MH080G1GCCVEM842101HD080DGN
drives/MATSHITADVD_2fCDRW_20UJDA775
Signed-off-by: David Zeuthen <davidz@redhat.com>
<SECTION>
<FILE>udisksdaemonutil</FILE>
udisks_decode_udev_string
+udisks_safe_append_to_object_path
</SECTION>
{
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);
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);
+ }
+ }
+}
gchar *udisks_decode_udev_string (const gchar *str);
+void udisks_safe_append_to_object_path (GString *str,
+ const gchar *s);
+
G_END_DECLS
{
}
-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,
/* 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);
}
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;
{
}
-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,
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);
}
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);
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);
}
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));
}
}
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);
}
}
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));
}
}
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);
}
}