From: David Zeuthen Date: Tue, 1 Dec 2009 19:29:37 +0000 (-0500) Subject: Reindent source code to adhere to the GNU-style X-Git-Tag: upstream/2.1.2~726 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=ea14b0318e92013a6e131d1f2b4b8b638927acd1;p=platform%2Fupstream%2Fudisks2.git Reindent source code to adhere to the GNU-style First I used the Eclipse indent tool. Then I ran c-indent- in Emacs. Finally, I fixed a couple of things up manually. --- diff --git a/src/adapter-private.c b/src/adapter-private.c index b6009ba..f02ed80 100644 --- a/src/adapter-private.c +++ b/src/adapter-private.c @@ -36,9 +36,7 @@ emit_changed_idle_cb (gpointer data) if (!adapter->priv->removed) { g_print ("**** EMITTING CHANGED for %s\n", adapter->priv->native_path); - g_signal_emit_by_name (adapter->priv->daemon, - "adapter-changed", - adapter->priv->object_path); + g_signal_emit_by_name (adapter->priv->daemon, "adapter-changed", adapter->priv->object_path); g_signal_emit_by_name (adapter, "changed"); } adapter->priv->emit_changed_idle_id = 0; @@ -48,7 +46,8 @@ emit_changed_idle_cb (gpointer data) } static void -emit_changed (Adapter *adapter, const gchar *name) +emit_changed (Adapter *adapter, + const gchar *name) { //g_debug ("property %s changed for %s", name, adapter->priv->adapter_file); @@ -58,15 +57,16 @@ emit_changed (Adapter *adapter, const gchar *name) if (adapter->priv->emit_changed_idle_id == 0) { adapter->priv->emit_changed_idle_id = g_idle_add_full (G_PRIORITY_DEFAULT, - emit_changed_idle_cb, - g_object_ref (adapter), - (GDestroyNotify) g_object_unref); + emit_changed_idle_cb, + g_object_ref (adapter), + (GDestroyNotify) g_object_unref); } } } void -adapter_set_vendor (Adapter *adapter, const gchar *value) +adapter_set_vendor (Adapter *adapter, + const gchar *value) { if (G_UNLIKELY (g_strcmp0 (adapter->priv->vendor, value) != 0)) { @@ -77,7 +77,8 @@ adapter_set_vendor (Adapter *adapter, const gchar *value) } void -adapter_set_model (Adapter *adapter, const gchar *value) +adapter_set_model (Adapter *adapter, + const gchar *value) { if (G_UNLIKELY (g_strcmp0 (adapter->priv->model, value) != 0)) { @@ -88,7 +89,8 @@ adapter_set_model (Adapter *adapter, const gchar *value) } void -adapter_set_driver (Adapter *adapter, const gchar *value) +adapter_set_driver (Adapter *adapter, + const gchar *value) { if (G_UNLIKELY (g_strcmp0 (adapter->priv->driver, value) != 0)) { @@ -99,7 +101,8 @@ adapter_set_driver (Adapter *adapter, const gchar *value) } void -adapter_set_num_ports (Adapter *adapter, guint value) +adapter_set_num_ports (Adapter *adapter, + guint value) { if (G_UNLIKELY (adapter->priv->num_ports != value)) { @@ -109,7 +112,8 @@ adapter_set_num_ports (Adapter *adapter, guint value) } void -adapter_set_fabric (Adapter *adapter, const gchar *value) +adapter_set_fabric (Adapter *adapter, + const gchar *value) { if (G_UNLIKELY (g_strcmp0 (adapter->priv->fabric, value) != 0)) { diff --git a/src/adapter-private.h b/src/adapter-private.h index 96de3a4..3409e21 100644 --- a/src/adapter-private.h +++ b/src/adapter-private.h @@ -31,26 +31,26 @@ G_BEGIN_DECLS struct AdapterPrivate { - DBusGConnection *system_bus_connection; - Daemon *daemon; - GUdevDevice *d; + DBusGConnection *system_bus_connection; + Daemon *daemon; + GUdevDevice *d; - gchar *object_path; - gchar *native_path; - gboolean removed; + gchar *object_path; + gchar *native_path; + gboolean removed; - /* if non-zero, the id of the idle for emitting a 'change' signal */ - guint emit_changed_idle_id; + /* if non-zero, the id of the idle for emitting a 'change' signal */ + guint emit_changed_idle_id; - /**************/ - /* Properties */ - /**************/ + /**************/ + /* Properties */ + /**************/ - gchar *vendor; - gchar *model; - gchar *driver; - guint num_ports; - gchar *fabric; + gchar *vendor; + gchar *model; + gchar *driver; + guint num_ports; + gchar *fabric; }; /* property setters */ diff --git a/src/adapter.c b/src/adapter.c index ff47b6c..e5a43ae 100644 --- a/src/adapter.c +++ b/src/adapter.c @@ -40,30 +40,31 @@ /*--------------------------------------------------------------------------------------------------------------*/ #include "adapter-glue.h" -static void adapter_class_init (AdapterClass *klass); -static void adapter_init (Adapter *seat); -static void adapter_finalize (GObject *object); +static void adapter_class_init (AdapterClass *klass); +static void adapter_init (Adapter *seat); +static void adapter_finalize (GObject *object); -static gboolean update_info (Adapter *adapter); +static gboolean update_info (Adapter *adapter); -static void drain_pending_changes (Adapter *adapter, gboolean force_update); +static void drain_pending_changes (Adapter *adapter, + gboolean force_update); enum { - PROP_0, - PROP_NATIVE_PATH, - - PROP_VENDOR, - PROP_MODEL, - PROP_DRIVER, - PROP_NUM_PORTS, - PROP_FABRIC, + PROP_0, + PROP_NATIVE_PATH, + + PROP_VENDOR, + PROP_MODEL, + PROP_DRIVER, + PROP_NUM_PORTS, + PROP_FABRIC, }; enum { - CHANGED_SIGNAL, - LAST_SIGNAL, + CHANGED_SIGNAL, + LAST_SIGNAL, }; static guint signals[LAST_SIGNAL] = { 0 }; @@ -73,125 +74,135 @@ G_DEFINE_TYPE (Adapter, adapter, G_TYPE_OBJECT) #define ADAPTER_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), TYPE_ADAPTER, AdapterPrivate)) static void -get_property (GObject *object, - guint prop_id, - GValue *value, - GParamSpec *pspec) +get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) { - Adapter *adapter = ADAPTER (object); - - switch (prop_id) { - case PROP_NATIVE_PATH: - g_value_set_string (value, adapter->priv->native_path); - break; - - case PROP_VENDOR: - g_value_set_string (value, adapter->priv->vendor); - break; - - case PROP_MODEL: - g_value_set_string (value, adapter->priv->model); - break; - - case PROP_DRIVER: - g_value_set_string (value, adapter->priv->driver); - break; - - case PROP_NUM_PORTS: - g_value_set_uint (value, adapter->priv->num_ports); - break; - - case PROP_FABRIC: - g_value_set_string (value, adapter->priv->fabric); - break; - - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } + Adapter *adapter = ADAPTER (object); + + switch (prop_id) + { + case PROP_NATIVE_PATH: + g_value_set_string (value, adapter->priv->native_path); + break; + + case PROP_VENDOR: + g_value_set_string (value, adapter->priv->vendor); + break; + + case PROP_MODEL: + g_value_set_string (value, adapter->priv->model); + break; + + case PROP_DRIVER: + g_value_set_string (value, adapter->priv->driver); + break; + + case PROP_NUM_PORTS: + g_value_set_uint (value, adapter->priv->num_ports); + break; + + case PROP_FABRIC: + g_value_set_string (value, adapter->priv->fabric); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } } static void adapter_class_init (AdapterClass *klass) { - GObjectClass *object_class = G_OBJECT_CLASS (klass); - - object_class->finalize = adapter_finalize; - object_class->get_property = get_property; - - g_type_class_add_private (klass, sizeof (AdapterPrivate)); - - signals[CHANGED_SIGNAL] = - g_signal_new ("changed", - G_OBJECT_CLASS_TYPE (klass), - G_SIGNAL_RUN_LAST | G_SIGNAL_DETAILED, - 0, - NULL, NULL, - g_cclosure_marshal_VOID__VOID, - G_TYPE_NONE, 0); - - dbus_g_object_type_install_info (TYPE_ADAPTER, &dbus_glib_adapter_object_info); - - g_object_class_install_property ( - object_class, - PROP_NATIVE_PATH, - g_param_spec_string ("native-path", NULL, NULL, NULL, G_PARAM_READABLE)); - g_object_class_install_property ( - object_class, - PROP_VENDOR, - g_param_spec_string ("vendor", NULL, NULL, NULL, G_PARAM_READABLE)); - g_object_class_install_property ( - object_class, - PROP_MODEL, - g_param_spec_string ("model", NULL, NULL, NULL, G_PARAM_READABLE)); - g_object_class_install_property ( - object_class, - PROP_DRIVER, - g_param_spec_string ("driver", NULL, NULL, NULL, G_PARAM_READABLE)); - g_object_class_install_property ( - object_class, - PROP_NUM_PORTS, - g_param_spec_uint ("num-ports", NULL, NULL, 0, G_MAXUINT, 0, G_PARAM_READABLE)); - g_object_class_install_property ( - object_class, - PROP_FABRIC, - g_param_spec_string ("fabric", NULL, NULL, NULL, G_PARAM_READABLE)); + GObjectClass *object_class = G_OBJECT_CLASS (klass); + + object_class->finalize = adapter_finalize; + object_class->get_property = get_property; + + g_type_class_add_private (klass, sizeof(AdapterPrivate)); + + signals[CHANGED_SIGNAL] = g_signal_new ("changed", + G_OBJECT_CLASS_TYPE (klass), + G_SIGNAL_RUN_LAST | G_SIGNAL_DETAILED, + 0, + NULL, + NULL, + g_cclosure_marshal_VOID__VOID, + G_TYPE_NONE, + 0); + + dbus_g_object_type_install_info (TYPE_ADAPTER, &dbus_glib_adapter_object_info); + + g_object_class_install_property (object_class, PROP_NATIVE_PATH, g_param_spec_string ("native-path", + NULL, + NULL, + NULL, + G_PARAM_READABLE)); + g_object_class_install_property (object_class, PROP_VENDOR, g_param_spec_string ("vendor", + NULL, + NULL, + NULL, + G_PARAM_READABLE)); + g_object_class_install_property (object_class, PROP_MODEL, g_param_spec_string ("model", + NULL, + NULL, + NULL, + G_PARAM_READABLE)); + g_object_class_install_property (object_class, PROP_DRIVER, g_param_spec_string ("driver", + NULL, + NULL, + NULL, + G_PARAM_READABLE)); + g_object_class_install_property (object_class, PROP_NUM_PORTS, g_param_spec_uint ("num-ports", + NULL, + NULL, + 0, + G_MAXUINT, + 0, + G_PARAM_READABLE)); + g_object_class_install_property (object_class, PROP_FABRIC, g_param_spec_string ("fabric", + NULL, + NULL, + NULL, + G_PARAM_READABLE)); } static void adapter_init (Adapter *adapter) { - adapter->priv = ADAPTER_GET_PRIVATE (adapter); + adapter->priv = ADAPTER_GET_PRIVATE (adapter); } static void adapter_finalize (GObject *object) { - Adapter *adapter; + Adapter *adapter; - g_return_if_fail (object != NULL); - g_return_if_fail (IS_ADAPTER (object)); + g_return_if_fail (object != NULL); + g_return_if_fail (IS_ADAPTER (object)); - adapter = ADAPTER (object); - g_return_if_fail (adapter->priv != NULL); + adapter = ADAPTER (object); + g_return_if_fail (adapter->priv != NULL); - /* g_debug ("finalizing %s", adapter->priv->native_path); */ + /* g_debug ("finalizing %s", adapter->priv->native_path); */ - g_object_unref (adapter->priv->d); - g_object_unref (adapter->priv->daemon); - g_free (adapter->priv->object_path); + g_object_unref (adapter->priv->d); + g_object_unref (adapter->priv->daemon); + g_free (adapter->priv->object_path); - g_free (adapter->priv->native_path); + g_free (adapter->priv->native_path); - if (adapter->priv->emit_changed_idle_id > 0) - g_source_remove (adapter->priv->emit_changed_idle_id); + if (adapter->priv->emit_changed_idle_id > 0) + g_source_remove (adapter->priv->emit_changed_idle_id); - /* free properties */ - g_free (adapter->priv->vendor); - g_free (adapter->priv->model); - g_free (adapter->priv->driver); + /* free properties */ + g_free (adapter->priv->vendor); + g_free (adapter->priv->model); + g_free (adapter->priv->driver); - G_OBJECT_CLASS (adapter_parent_class)->finalize (object); + G_OBJECT_CLASS (adapter_parent_class)->finalize (object); } /** @@ -205,36 +216,41 @@ adapter_finalize (GObject *object) static char * compute_object_path (const char *native_path) { - const gchar *basename; - GString *s; - guint n; - - basename = strrchr (native_path, '/'); - if (basename != NULL) { - basename++; - } else { - basename = native_path; + const gchar *basename; + GString *s; + guint n; + + basename = strrchr (native_path, '/'); + if (basename != NULL) + { + basename++; + } + else + { + basename = native_path; + } + + s = g_string_new ("/org/freedesktop/UDisks/adapters/"); + 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); } - - s = g_string_new ("/org/freedesktop/UDisks/adapters/"); - 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 _ */ - g_string_append_printf (s, "_%02x", c); - } + else + { + /* Escape bytes not in [A-Z][a-z][0-9] as _ */ + g_string_append_printf (s, "_%02x", c); } + } - return g_string_free (s, FALSE); + return g_string_free (s, FALSE); } /* ---------------------------------------------------------------------------------------------------- */ @@ -242,125 +258,134 @@ compute_object_path (const char *native_path) static gboolean register_disks_adapter (Adapter *adapter) { - DBusConnection *connection; - GError *error = NULL; - - adapter->priv->system_bus_connection = dbus_g_bus_get (DBUS_BUS_SYSTEM, &error); - if (adapter->priv->system_bus_connection == NULL) { - if (error != NULL) { - g_critical ("error getting system bus: %s", error->message); - g_error_free (error); - } - goto error; + DBusConnection *connection; + GError *error = NULL; + + adapter->priv->system_bus_connection = dbus_g_bus_get (DBUS_BUS_SYSTEM, &error); + if (adapter->priv->system_bus_connection == NULL) + { + if (error != NULL) + { + g_critical ("error getting system bus: %s", error->message); + g_error_free (error); } - connection = dbus_g_connection_get_connection (adapter->priv->system_bus_connection); + goto error; + } + connection = dbus_g_connection_get_connection (adapter->priv->system_bus_connection); - adapter->priv->object_path = compute_object_path (adapter->priv->native_path); + adapter->priv->object_path = compute_object_path (adapter->priv->native_path); - /* safety first */ - if (dbus_g_connection_lookup_g_object (adapter->priv->system_bus_connection, - adapter->priv->object_path) != NULL) { - g_error ("**** HACK: Wanting to register object at path `%s' but there is already an " - "object there. This is an internal error in the daemon. Aborting.\n", - adapter->priv->object_path); - } + /* safety first */ + if (dbus_g_connection_lookup_g_object (adapter->priv->system_bus_connection, adapter->priv->object_path) != NULL) + { + g_error ("**** HACK: Wanting to register object at path `%s' but there is already an " + "object there. This is an internal error in the daemon. Aborting.\n", adapter->priv->object_path); + } - dbus_g_connection_register_g_object (adapter->priv->system_bus_connection, - adapter->priv->object_path, - G_OBJECT (adapter)); + dbus_g_connection_register_g_object (adapter->priv->system_bus_connection, + adapter->priv->object_path, + G_OBJECT (adapter)); - return TRUE; + return TRUE; -error: - return FALSE; + error: + return FALSE; } void adapter_removed (Adapter *adapter) { - adapter->priv->removed = TRUE; + adapter->priv->removed = TRUE; - dbus_g_connection_unregister_g_object (adapter->priv->system_bus_connection, - G_OBJECT (adapter)); - g_assert (dbus_g_connection_lookup_g_object (adapter->priv->system_bus_connection, - adapter->priv->object_path) == NULL); + dbus_g_connection_unregister_g_object (adapter->priv->system_bus_connection, G_OBJECT (adapter)); + g_assert (dbus_g_connection_lookup_g_object (adapter->priv->system_bus_connection, adapter->priv->object_path) + == NULL); } Adapter * -adapter_new (Daemon *daemon, GUdevDevice *d) +adapter_new (Daemon *daemon, + GUdevDevice *d) { - Adapter *adapter; - const char *native_path; - - adapter = NULL; - native_path = g_udev_device_get_sysfs_path (d); - - adapter = ADAPTER (g_object_new (TYPE_ADAPTER, NULL)); - adapter->priv->d = g_object_ref (d); - adapter->priv->daemon = g_object_ref (daemon); - adapter->priv->native_path = g_strdup (native_path); - - if (!update_info (adapter)) { - g_object_unref (adapter); - adapter = NULL; - goto out; - } - - if (!register_disks_adapter (ADAPTER (adapter))) { - g_object_unref (adapter); - adapter = NULL; - goto out; - } - -out: - return adapter; + Adapter *adapter; + const char *native_path; + + adapter = NULL; + native_path = g_udev_device_get_sysfs_path (d); + + adapter = ADAPTER (g_object_new (TYPE_ADAPTER, NULL)); + adapter->priv->d = g_object_ref (d); + adapter->priv->daemon = g_object_ref (daemon); + adapter->priv->native_path = g_strdup (native_path); + + if (!update_info (adapter)) + { + g_object_unref (adapter); + adapter = NULL; + goto out; + } + + if (!register_disks_adapter (ADAPTER (adapter))) + { + g_object_unref (adapter); + adapter = NULL; + goto out; + } + + out: + return adapter; } static void -drain_pending_changes (Adapter *adapter, gboolean force_update) +drain_pending_changes (Adapter *adapter, + gboolean force_update) { - gboolean emit_changed; - - emit_changed = FALSE; - - /* the update-in-idle is set up if, and only if, there are pending changes - so - * we should emit a 'change' event only if it is set up - */ - if (adapter->priv->emit_changed_idle_id != 0) { - g_source_remove (adapter->priv->emit_changed_idle_id); - adapter->priv->emit_changed_idle_id = 0; - emit_changed = TRUE; - } - - if ((!adapter->priv->removed) && (emit_changed || force_update)) { - if (adapter->priv->object_path != NULL) { - g_print ("**** EMITTING CHANGED for %s\n", adapter->priv->native_path); - g_signal_emit_by_name (adapter, "changed"); - g_signal_emit_by_name (adapter->priv->daemon, "adapter-changed", adapter->priv->object_path); - } + gboolean emit_changed; + + emit_changed = FALSE; + + /* the update-in-idle is set up if, and only if, there are pending changes - so + * we should emit a 'change' event only if it is set up + */ + if (adapter->priv->emit_changed_idle_id != 0) + { + g_source_remove (adapter->priv->emit_changed_idle_id); + adapter->priv->emit_changed_idle_id = 0; + emit_changed = TRUE; + } + + if ((!adapter->priv->removed) && (emit_changed || force_update)) + { + if (adapter->priv->object_path != NULL) + { + g_print ("**** EMITTING CHANGED for %s\n", adapter->priv->native_path); + g_signal_emit_by_name (adapter, "changed"); + g_signal_emit_by_name (adapter->priv->daemon, "adapter-changed", adapter->priv->object_path); } + } } /* called by the daemon on the 'change' uevent */ gboolean -adapter_changed (Adapter *adapter, GUdevDevice *d, gboolean synthesized) +adapter_changed (Adapter *adapter, + GUdevDevice *d, + gboolean synthesized) { - gboolean keep_adapter; + gboolean keep_adapter; - g_object_unref (adapter->priv->d); - adapter->priv->d = g_object_ref (d); + g_object_unref (adapter->priv->d); + adapter->priv->d = g_object_ref (d); - keep_adapter = update_info (adapter); + keep_adapter = update_info (adapter); - /* this 'change' event might prompt us to remove the adapter */ - if (!keep_adapter) - goto out; + /* this 'change' event might prompt us to remove the adapter */ + if (!keep_adapter) + goto out; - /* no, it's good .. keep it.. and always force a 'change' signal if the event isn't synthesized */ - drain_pending_changes (adapter, !synthesized); + /* no, it's good .. keep it.. and always force a 'change' signal if the event isn't synthesized */ + drain_pending_changes (adapter, !synthesized); -out: - return keep_adapter; + out: + return keep_adapter; } /* ---------------------------------------------------------------------------------------------------- */ @@ -368,13 +393,13 @@ out: const char * adapter_local_get_object_path (Adapter *adapter) { - return adapter->priv->object_path; + return adapter->priv->object_path; } const char * adapter_local_get_native_path (Adapter *adapter) { - return adapter->priv->native_path; + return adapter->priv->native_path; } /* ---------------------------------------------------------------------------------------------------- */ @@ -386,127 +411,143 @@ adapter_local_get_native_path (Adapter *adapter) static gboolean update_info_fabric_and_num_ports (Adapter *adapter) { - gboolean ret; - const gchar *fabric; - GDir *dir; - guint num_scsi_host_objects; - guint num_ports; - guint64 device_class; - const gchar *driver; - guint class; - guint subclass; - guint interface; - gchar *scsi_host_name; - gchar *s; - gchar *s2; - - ret = FALSE; - fabric = NULL; - scsi_host_name = NULL; - num_ports = 0; - - device_class = g_udev_device_get_sysfs_attr_as_uint64 (adapter->priv->d, "class"); - driver = g_udev_device_get_driver (adapter->priv->d); - - class = (device_class & 0xff0000); - subclass = (device_class & 0x00ff00); - interface = (device_class & 0x0000ff); - - /* count number of scsi_host objects - this is to detect whether we are dealing with - * ATA - see comment in port.c:update_info_ata() for details about - * the hack we use here and how to fix this - */ - num_scsi_host_objects = 0; - dir = g_dir_open (adapter_local_get_native_path (adapter), 0, NULL); - if (dir != NULL) { - const gchar *name; - while ((name = g_dir_read_name (dir)) != NULL) { - gint number; - if (sscanf (name, "host%d", &number) != 1) - continue; - num_scsi_host_objects++; - - if (scsi_host_name == NULL) { - scsi_host_name = g_strdup (name); - } - } - - g_dir_close (dir); + gboolean ret; + const gchar *fabric; + GDir *dir; + guint num_scsi_host_objects; + guint num_ports; + guint64 device_class; + const gchar *driver; + guint class; + guint subclass; + guint interface; + gchar *scsi_host_name; + gchar *s; + gchar *s2; + + ret = FALSE; + fabric = NULL; + scsi_host_name = NULL; + num_ports = 0; + + device_class = g_udev_device_get_sysfs_attr_as_uint64 (adapter->priv->d, "class"); + driver = g_udev_device_get_driver (adapter->priv->d); + + class = (device_class & 0xff0000); + subclass = (device_class & 0x00ff00); + interface = (device_class & 0x0000ff); + + /* count number of scsi_host objects - this is to detect whether we are dealing with + * ATA - see comment in port.c:update_info_ata() for details about + * the hack we use here and how to fix this + */ + num_scsi_host_objects = 0; + dir = g_dir_open (adapter_local_get_native_path (adapter), 0, NULL); + if (dir != NULL) + { + const gchar *name; + while ((name = g_dir_read_name (dir)) != NULL) + { + gint number; + if (sscanf (name, "host%d", &number) != 1) + continue; + num_scsi_host_objects++; + + if (scsi_host_name == NULL) + { + scsi_host_name = g_strdup (name); + } } - if (num_scsi_host_objects > 1) { - /* we're dealing with ATA */ - num_ports = num_scsi_host_objects; - - /* use PCI class to zero in - maybe we also want to use driver names? */ - fabric = "ata"; - if (driver != NULL && - (g_str_has_prefix (driver, "pata_") || - g_strcmp0 (driver, "ata_piix") == 0)) { - fabric = "ata_pata"; - } else if (driver != NULL && - (g_str_has_prefix (driver, "sata_") || - g_strcmp0 (driver, "ahci") == 0)) { - fabric = "ata_sata"; - } else if (subclass == 0x01 || subclass == 0x05) { - fabric = "ata_pata"; - } else if (subclass == 0x06) { - fabric = "ata_sata"; - } - } else { - /* Not ATA */ - if (subclass == 0x00) { - fabric = "scsi"; - } else if (subclass == 0x07) { - fabric = "scsi_sas"; - } + g_dir_close (dir); + } + + if (num_scsi_host_objects > 1) + { + /* we're dealing with ATA */ + num_ports = num_scsi_host_objects; - /* SAS */ - if (scsi_host_name != NULL) { - s = g_strdup_printf ("%s/%s/sas_host/%s", - adapter_local_get_native_path (adapter), - scsi_host_name, - scsi_host_name); - g_debug ("foo = %s", s); - if (g_file_test (s, G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR)) { - fabric = "scsi_sas"; - - s = g_strdup_printf ("%s/%s", - adapter_local_get_native_path (adapter), - scsi_host_name); - /* Count number of phy objects in hostN/ */ - dir = g_dir_open (s, 0, NULL); - if (dir != NULL) { - const gchar *name; - while ((name = g_dir_read_name (dir)) != NULL) { - if (!g_str_has_prefix (name, "phy-")) - continue; - /* Check that it's really a sas_phy */ - s2 = g_strdup_printf ("%s/%s/sas_phy", s, name); - if (g_file_test (s2, G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR)) { - num_ports++; - } - g_free (s2); - } - - if (scsi_host_name == NULL) { - scsi_host_name = g_strdup (name); - } - g_dir_close (dir); - } + /* use PCI class to zero in - maybe we also want to use driver names? */ + fabric = "ata"; + if (driver != NULL && (g_str_has_prefix (driver, "pata_") || g_strcmp0 (driver, "ata_piix") == 0)) + { + fabric = "ata_pata"; + } + else if (driver != NULL && (g_str_has_prefix (driver, "sata_") || g_strcmp0 (driver, "ahci") == 0)) + { + fabric = "ata_sata"; + } + else if (subclass == 0x01 || subclass == 0x05) + { + fabric = "ata_pata"; + } + else if (subclass == 0x06) + { + fabric = "ata_sata"; + } + } + else + { + /* Not ATA */ + if (subclass == 0x00) + { + fabric = "scsi"; + } + else if (subclass == 0x07) + { + fabric = "scsi_sas"; + } + + /* SAS */ + if (scsi_host_name != NULL) + { + s = g_strdup_printf ("%s/%s/sas_host/%s", + adapter_local_get_native_path (adapter), + scsi_host_name, + scsi_host_name); + g_debug ("foo = %s", s); + if (g_file_test (s, G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR)) + { + fabric = "scsi_sas"; + + s = g_strdup_printf ("%s/%s", adapter_local_get_native_path (adapter), scsi_host_name); + /* Count number of phy objects in hostN/ */ + dir = g_dir_open (s, 0, NULL); + if (dir != NULL) + { + const gchar *name; + while ((name = g_dir_read_name (dir)) != NULL) + { + if (!g_str_has_prefix (name, "phy-")) + continue; + /* Check that it's really a sas_phy */ + s2 = g_strdup_printf ("%s/%s/sas_phy", s, name); + if (g_file_test (s2, G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR)) + { + num_ports++; } - g_free (s); + g_free (s2); + } + + if (scsi_host_name == NULL) + { + scsi_host_name = g_strdup (name); + } + g_dir_close (dir); } + } + g_free (s); } + } - ret = TRUE; + ret = TRUE; - adapter_set_fabric (adapter, fabric); - adapter_set_num_ports (adapter, num_ports); + adapter_set_fabric (adapter, fabric); + adapter_set_num_ports (adapter, num_ports); - //out: - g_free (scsi_host_name); - return ret; + //out: + g_free (scsi_host_name); + return ret; } /** @@ -524,83 +565,85 @@ update_info_fabric_and_num_ports (Adapter *adapter) static gboolean update_info (Adapter *adapter) { - gboolean ret; - guint64 device_class; - gchar *vendor; - gchar *model; - const gchar *driver; - - ret = FALSE; - vendor = NULL; - model = NULL; - - /* Only care about Mass Storage Adapter devices */ - device_class = g_udev_device_get_sysfs_attr_as_uint64 (adapter->priv->d, "class"); - if (((device_class & 0xff0000) >> 16) != 0x01) - goto out; - - driver = g_udev_device_get_driver (adapter->priv->d); - - g_print ("**** UPDATING %s\n", adapter->priv->native_path); - - vendor = g_strdup (g_udev_device_get_property (adapter->priv->d, "ID_VENDOR_FROM_DATABASE")); - model = g_strdup (g_udev_device_get_property (adapter->priv->d, "ID_MODEL_FROM_DATABASE")); - - /* TODO: probably want subsystem vendor and model - for the adapters in my Thinkpad X61 (not T61!) - * it looks like this - * - * 00:1f.1: vendor: Intel Corporation" - * model: 82801HBM/HEM (ICH8M/ICH8M-E) IDE Adapter - * subsys_vendor: Lenovo - * subsys_model: ThinkPad T61 - * - * 00:1f.2: vendor: Intel Corporation - * model: 82801HBM/HEM (ICH8M/ICH8M-E) SATA AHCI Adapter - * subsys_vendor: Lenovo - * subsys_model: ThinkPad T61 - * - * or maybe not... - */ - - /* TODO: we want some kind of "type" or "interconnect" for the - * adapter - e.g. SATA/PATA/SAS/FC/iSCSI - also want version - * (e.g. SATA1, SATA2) and speed (e.g. 150MB/s, 300MB/s) - */ - - /* TODO: want some kind of information about the number of ports - and for - * each port the "type" of connector - e.g. PATA, SATA, eSATA, SAS, - * SASx4 (wide lane), FC... and the role (initiator or target) - */ - - /* TODO: want to convey some kind of information about where the adapter - * is located (express-card, pc-card, pci-slot, onboard)... - */ - - /* TODO: also, enclosure information (needs thought re SES-2 enclosure support) */ - - if (vendor == NULL) { - vendor = g_strdup_printf ("[vendor=0x%04x subsys=0x%04x]", - g_udev_device_get_sysfs_attr_as_int (adapter->priv->d, "vendor"), - g_udev_device_get_sysfs_attr_as_int (adapter->priv->d, "subsystem_vendor")); - } - if (model == NULL) { - vendor = g_strdup_printf ("Storage Adapter [model=0x%04x subsys=0x%04x]", - g_udev_device_get_sysfs_attr_as_int (adapter->priv->d, "device"), - g_udev_device_get_sysfs_attr_as_int (adapter->priv->d, "subsystem_device")); - } - - adapter_set_vendor (adapter, vendor); - adapter_set_model (adapter, model); - adapter_set_driver (adapter, driver); - - if (!update_info_fabric_and_num_ports (adapter)) - goto out; - - ret = TRUE; + gboolean ret; + guint64 device_class; + gchar *vendor; + gchar *model; + const gchar *driver; + + ret = FALSE; + vendor = NULL; + model = NULL; + + /* Only care about Mass Storage Adapter devices */ + device_class = g_udev_device_get_sysfs_attr_as_uint64 (adapter->priv->d, "class"); + if (((device_class & 0xff0000) >> 16) != 0x01) + goto out; + + driver = g_udev_device_get_driver (adapter->priv->d); + + g_print ("**** UPDATING %s\n", adapter->priv->native_path); + + vendor = g_strdup (g_udev_device_get_property (adapter->priv->d, "ID_VENDOR_FROM_DATABASE")); + model = g_strdup (g_udev_device_get_property (adapter->priv->d, "ID_MODEL_FROM_DATABASE")); + + /* TODO: probably want subsystem vendor and model - for the adapters in my Thinkpad X61 (not T61!) + * it looks like this + * + * 00:1f.1: vendor: Intel Corporation" + * model: 82801HBM/HEM (ICH8M/ICH8M-E) IDE Adapter + * subsys_vendor: Lenovo + * subsys_model: ThinkPad T61 + * + * 00:1f.2: vendor: Intel Corporation + * model: 82801HBM/HEM (ICH8M/ICH8M-E) SATA AHCI Adapter + * subsys_vendor: Lenovo + * subsys_model: ThinkPad T61 + * + * or maybe not... + */ + + /* TODO: we want some kind of "type" or "interconnect" for the + * adapter - e.g. SATA/PATA/SAS/FC/iSCSI - also want version + * (e.g. SATA1, SATA2) and speed (e.g. 150MB/s, 300MB/s) + */ + + /* TODO: want some kind of information about the number of ports - and for + * each port the "type" of connector - e.g. PATA, SATA, eSATA, SAS, + * SASx4 (wide lane), FC... and the role (initiator or target) + */ + + /* TODO: want to convey some kind of information about where the adapter + * is located (express-card, pc-card, pci-slot, onboard)... + */ + + /* TODO: also, enclosure information (needs thought re SES-2 enclosure support) */ + + if (vendor == NULL) + { + vendor = g_strdup_printf ("[vendor=0x%04x subsys=0x%04x]", + g_udev_device_get_sysfs_attr_as_int (adapter->priv->d, "vendor"), + g_udev_device_get_sysfs_attr_as_int (adapter->priv->d, "subsystem_vendor")); + } + if (model == NULL) + { + vendor = g_strdup_printf ("Storage Adapter [model=0x%04x subsys=0x%04x]", + g_udev_device_get_sysfs_attr_as_int (adapter->priv->d, "device"), + g_udev_device_get_sysfs_attr_as_int (adapter->priv->d, "subsystem_device")); + } + + adapter_set_vendor (adapter, vendor); + adapter_set_model (adapter, model); + adapter_set_driver (adapter, driver); + + if (!update_info_fabric_and_num_ports (adapter)) + goto out; + + ret = TRUE; out: - g_free (vendor); - g_free (model); - return ret; + g_free (vendor); + g_free (model); + return ret; } diff --git a/src/adapter.h b/src/adapter.h index 2ea50b9..1a9f868 100644 --- a/src/adapter.h +++ b/src/adapter.h @@ -36,35 +36,35 @@ G_BEGIN_DECLS #define IS_ADAPTER_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), TYPE_ADAPTER)) #define ADAPTER_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), TYPE_ADAPTER, AdapterClass)) -typedef struct AdapterClass AdapterClass; +typedef struct AdapterClass AdapterClass; typedef struct AdapterPrivate AdapterPrivate; struct Adapter { - GObject parent; - AdapterPrivate *priv; + GObject parent; + AdapterPrivate *priv; }; struct AdapterClass { - GObjectClass parent_class; + GObjectClass parent_class; }; -GType adapter_get_type (void) G_GNUC_CONST; +GType adapter_get_type (void) G_GNUC_CONST; -Adapter *adapter_new (Daemon *daemon, - GUdevDevice *d); +Adapter *adapter_new (Daemon *daemon, + GUdevDevice *d); -gboolean adapter_changed (Adapter *adapter, - GUdevDevice *d, - gboolean synthesized); +gboolean adapter_changed (Adapter *adapter, + GUdevDevice *d, + gboolean synthesized); -void adapter_removed (Adapter *adapter); +void adapter_removed (Adapter *adapter); /* local methods */ -const char *adapter_local_get_object_path (Adapter *adapter); -const char *adapter_local_get_native_path (Adapter *adapter); +const char *adapter_local_get_object_path (Adapter *adapter); +const char *adapter_local_get_native_path (Adapter *adapter); G_END_DECLS diff --git a/src/daemon.c b/src/daemon.c index 9ea35cd..3cc54e9 100644 --- a/src/daemon.c +++ b/src/daemon.c @@ -30,9 +30,6 @@ /* update ATA SMART every 30 minutes */ #define ATA_SMART_REFRESH_INTERVAL_SECONDS (30*60) -/* clean up old ATA SMART entries every 24 hours (and on startup) */ -#define ATA_SMART_CLEANUP_INTERVAL_SECONDS (24*60*60) - /* ---------------------------------------------------------------------------------------------------- */ #include @@ -52,7 +49,6 @@ #include #include - #include #include #include @@ -78,84 +74,88 @@ #include "daemon-glue.h" #include "marshal.h" - /*--------------------------------------------------------------------------------------------------------------*/ enum -{ - PROP_0, - PROP_DAEMON_VERSION, - PROP_DAEMON_IS_INHIBITED, - PROP_SUPPORTS_LUKS_DEVICES, - PROP_KNOWN_FILESYSTEMS, -}; + { + PROP_0, + PROP_DAEMON_VERSION, + PROP_DAEMON_IS_INHIBITED, + PROP_SUPPORTS_LUKS_DEVICES, + PROP_KNOWN_FILESYSTEMS, + }; enum -{ - DEVICE_ADDED_SIGNAL, - DEVICE_REMOVED_SIGNAL, - DEVICE_CHANGED_SIGNAL, - DEVICE_JOB_CHANGED_SIGNAL, - ADAPTER_ADDED_SIGNAL, - ADAPTER_REMOVED_SIGNAL, - ADAPTER_CHANGED_SIGNAL, - EXPANDER_ADDED_SIGNAL, - EXPANDER_REMOVED_SIGNAL, - EXPANDER_CHANGED_SIGNAL, - PORT_ADDED_SIGNAL, - PORT_REMOVED_SIGNAL, - PORT_CHANGED_SIGNAL, - LAST_SIGNAL, -}; + { + DEVICE_ADDED_SIGNAL, + DEVICE_REMOVED_SIGNAL, + DEVICE_CHANGED_SIGNAL, + DEVICE_JOB_CHANGED_SIGNAL, + ADAPTER_ADDED_SIGNAL, + ADAPTER_REMOVED_SIGNAL, + ADAPTER_CHANGED_SIGNAL, + EXPANDER_ADDED_SIGNAL, + EXPANDER_REMOVED_SIGNAL, + EXPANDER_CHANGED_SIGNAL, + PORT_ADDED_SIGNAL, + PORT_REMOVED_SIGNAL, + PORT_CHANGED_SIGNAL, + LAST_SIGNAL, + }; static guint signals[LAST_SIGNAL] = { 0 }; struct DaemonPrivate { - DBusGConnection *system_bus_connection; - DBusGProxy *system_bus_proxy; + DBusGConnection *system_bus_connection; + DBusGProxy *system_bus_proxy; - PolkitAuthority *authority; + PolkitAuthority *authority; - GUdevClient *gudev_client; + GUdevClient *gudev_client; - GIOChannel *mdstat_channel; + GIOChannel *mdstat_channel; - GHashTable *map_dev_t_to_device; - GHashTable *map_device_file_to_device; - GHashTable *map_native_path_to_device; - GHashTable *map_object_path_to_device; + GHashTable *map_dev_t_to_device; + GHashTable *map_device_file_to_device; + GHashTable *map_native_path_to_device; + GHashTable *map_object_path_to_device; - GHashTable *map_native_path_to_adapter; - GHashTable *map_object_path_to_adapter; + GHashTable *map_native_path_to_adapter; + GHashTable *map_object_path_to_adapter; - GHashTable *map_native_path_to_expander; - GHashTable *map_object_path_to_expander; + GHashTable *map_native_path_to_expander; + GHashTable *map_object_path_to_expander; - GHashTable *map_native_path_to_port; - GHashTable *map_object_path_to_port; + GHashTable *map_native_path_to_port; + GHashTable *map_object_path_to_port; - MountMonitor *mount_monitor; + MountMonitor *mount_monitor; - guint ata_smart_refresh_timer_id; - guint ata_smart_cleanup_timer_id; + guint ata_smart_refresh_timer_id; + guint ata_smart_cleanup_timer_id; - GList *polling_inhibitors; + GList *polling_inhibitors; - GList *inhibitors; + GList *inhibitors; - GList *spindown_inhibitors; + GList *spindown_inhibitors; }; -static void daemon_class_init (DaemonClass *klass); -static void daemon_init (Daemon *seat); -static void daemon_finalize (GObject *object); +static void +daemon_class_init (DaemonClass *klass); +static void +daemon_init (Daemon *seat); +static void +daemon_finalize (GObject *object); -static void daemon_polling_inhibitor_disconnected_cb (Inhibitor *inhibitor, - Daemon *daemon); +static void +daemon_polling_inhibitor_disconnected_cb (Inhibitor *inhibitor, + Daemon *daemon); -static void daemon_inhibitor_disconnected_cb (Inhibitor *inhibitor, - Daemon *daemon); +static void +daemon_inhibitor_disconnected_cb (Inhibitor *inhibitor, + Daemon *daemon); G_DEFINE_TYPE (Daemon, daemon, G_TYPE_OBJECT) @@ -166,65 +166,64 @@ G_DEFINE_TYPE (Daemon, daemon, G_TYPE_OBJECT) GQuark error_quark (void) { - static GQuark ret = 0; + static GQuark ret = 0; - if (ret == 0) { - ret = g_quark_from_static_string ("udisks_error"); - } + if (ret == 0) + { + ret = g_quark_from_static_string ("udisks_error"); + } - return ret; + return ret; } - #define ENUM_ENTRY(NAME, DESC) { NAME, "" #NAME "", DESC } GType error_get_type (void) { - static GType etype = 0; + static GType etype = 0; - if (etype == 0) + if (etype == 0) + { + static const GEnumValue values[] = { - static const GEnumValue values[] = { - ENUM_ENTRY (ERROR_FAILED, "Failed"), - ENUM_ENTRY (ERROR_PERMISSION_DENIED, "PermissionDenied"), - ENUM_ENTRY (ERROR_INHIBITED, "Inhibited"), - ENUM_ENTRY (ERROR_BUSY, "Busy"), - ENUM_ENTRY (ERROR_CANCELLED, "Cancelled"), - ENUM_ENTRY (ERROR_INVALID_OPTION, "InvalidOption"), - ENUM_ENTRY (ERROR_NOT_SUPPORTED, "NotSupported"), - ENUM_ENTRY (ERROR_ATA_SMART_WOULD_WAKEUP, "AtaSmartWouldWakeup"), - ENUM_ENTRY (ERROR_FILESYSTEM_DRIVER_MISSING, "FilesystemDriverMissing"), - ENUM_ENTRY (ERROR_FILESYSTEM_TOOLS_MISSING, "FilesystemToolsMissing"), - { 0, 0, 0 } - }; - g_assert (NUM_ERRORS == G_N_ELEMENTS (values) - 1); - etype = g_enum_register_static ("Error", values); - } - return etype; + ENUM_ENTRY (ERROR_FAILED, "Failed"), + ENUM_ENTRY (ERROR_PERMISSION_DENIED, "PermissionDenied"), + ENUM_ENTRY (ERROR_INHIBITED, "Inhibited"), + ENUM_ENTRY (ERROR_BUSY, "Busy"), + ENUM_ENTRY (ERROR_CANCELLED, "Cancelled"), + ENUM_ENTRY (ERROR_INVALID_OPTION, "InvalidOption"), + ENUM_ENTRY (ERROR_NOT_SUPPORTED, "NotSupported"), + ENUM_ENTRY (ERROR_ATA_SMART_WOULD_WAKEUP, "AtaSmartWouldWakeup"), + ENUM_ENTRY (ERROR_FILESYSTEM_DRIVER_MISSING, "FilesystemDriverMissing"), + ENUM_ENTRY (ERROR_FILESYSTEM_TOOLS_MISSING, "FilesystemToolsMissing"), + { 0, 0, 0 } + }; + g_assert (NUM_ERRORS == G_N_ELEMENTS (values) - 1); + etype = g_enum_register_static ("Error", values); + } + return etype; } - static GObject * -daemon_constructor (GType type, - guint n_construct_properties, - GObjectConstructParam *construct_properties) +daemon_constructor (GType type, + guint n_construct_properties, + GObjectConstructParam *construct_properties) { - Daemon *daemon; - DaemonClass *klass; + Daemon *daemon; + DaemonClass *klass; - klass = DAEMON_CLASS (g_type_class_peek (TYPE_DAEMON)); + klass = DAEMON_CLASS (g_type_class_peek (TYPE_DAEMON)); - daemon = DAEMON ( - G_OBJECT_CLASS (daemon_parent_class)->constructor (type, - n_construct_properties, - construct_properties)); - return G_OBJECT (daemon); + daemon = DAEMON (G_OBJECT_CLASS (daemon_parent_class)->constructor (type, + n_construct_properties, + construct_properties)); + return G_OBJECT (daemon); } /*--------------------------------------------------------------------------------------------------------------*/ -#define KNOWN_FILESYSTEMS_STRUCT_TYPE (dbus_g_type_get_struct ("GValueArray", \ +#define KNOWN_FILESYSTEMS_STRUCT_TYPE (dbus_g_type_get_struct ("GValueArray", \ G_TYPE_STRING, \ G_TYPE_STRING, \ G_TYPE_BOOLEAN, \ @@ -241,229 +240,249 @@ daemon_constructor (GType type, G_TYPE_BOOLEAN, \ G_TYPE_INVALID)) -static const Filesystem known_file_systems[] = { - { - "vfat", /* id */ - "FAT", /* name */ - FALSE, /* supports_unix_owners */ - TRUE, /* can_mount */ - TRUE, /* can_create */ - 254, /* max_label_len */ - TRUE, /* supports_label_rename */ - FALSE, /* supports_online_label_rename*/ - TRUE, /* supports_fsck */ - FALSE, /* supports_online_fsck */ - FALSE, /* supports_resize_enlarge */ - FALSE, /* supports_online_resize_enlarge */ - FALSE, /* supports_resize_shrink */ - FALSE, /* supports_online_resize_shrink */ - }, - { - "ext2", /* id */ - "Linux Ext2", /* name */ - TRUE, /* supports_unix_owners */ - TRUE, /* can_mount */ - TRUE, /* can_create */ - 16, /* max_label_len */ - TRUE, /* supports_label_rename */ - TRUE, /* supports_online_label_rename*/ - TRUE, /* supports_fsck */ - FALSE, /* supports_online_fsck */ - TRUE, /* supports_resize_enlarge */ - TRUE, /* supports_online_resize_enlarge */ - TRUE, /* supports_resize_shrink */ - TRUE, /* supports_online_resize_shrink */ - }, - { - "ext3", /* id */ - "Linux Ext3", /* name */ - TRUE, /* supports_unix_owners */ - TRUE, /* can_mount */ - TRUE, /* can_create */ - 16, /* max_label_len */ - TRUE, /* supports_label_rename */ - TRUE, /* supports_online_label_rename*/ - TRUE, /* supports_fsck */ - FALSE, /* supports_online_fsck */ - TRUE, /* supports_resize_enlarge */ - TRUE, /* supports_online_resize_enlarge */ - TRUE, /* supports_resize_shrink */ - TRUE, /* supports_online_resize_shrink */ - }, - { - "ext4", /* id */ - "Linux Ext4", /* name */ - TRUE, /* supports_unix_owners */ - TRUE, /* can_mount */ - TRUE, /* can_create */ - 16, /* max_label_len */ - TRUE, /* supports_label_rename */ - TRUE, /* supports_online_label_rename*/ - TRUE, /* supports_fsck */ - FALSE, /* supports_online_fsck */ - TRUE, /* supports_resize_enlarge */ - TRUE, /* supports_online_resize_enlarge */ - TRUE, /* supports_resize_shrink */ - TRUE, /* supports_online_resize_shrink */ - }, - { - "xfs", /* id */ - "XFS", /* name */ - TRUE, /* supports_unix_owners */ - TRUE, /* can_mount */ - TRUE, /* can_create */ - 12, /* max_label_len */ - TRUE, /* supports_label_rename */ - FALSE, /* supports_online_label_rename*/ - TRUE, /* supports_fsck */ - FALSE, /* supports_online_fsck */ - FALSE, /* supports_resize_enlarge */ - TRUE, /* supports_online_resize_enlarge */ - FALSE, /* supports_resize_shrink */ - FALSE, /* supports_online_resize_shrink */ - }, - { - "minix", /* id */ - "Minix", /* name */ - TRUE, /* supports_unix_owners */ - TRUE, /* can_mount */ - TRUE, /* can_create */ - 0, /* max_label_len */ - FALSE, /* supports_label_rename */ - FALSE, /* supports_online_label_rename*/ - TRUE, /* supports_fsck */ - FALSE, /* supports_online_fsck */ - FALSE, /* supports_resize_enlarge */ - FALSE, /* supports_online_resize_enlarge */ - FALSE, /* supports_resize_shrink */ - FALSE, /* supports_online_resize_shrink */ - }, - { - "ntfs", /* id */ - "NTFS", /* name */ - FALSE, /* supports_unix_owners */ - TRUE, /* can_mount */ - TRUE, /* can_create */ - 128, /* max_label_len */ - TRUE, /* supports_label_rename */ - FALSE, /* supports_online_label_rename*/ - FALSE, /* supports_fsck (TODO: hmm.. ntfsck doesn't support -a yet?) */ - FALSE, /* supports_online_fsck */ - TRUE, /* supports_resize_enlarge */ - FALSE, /* supports_online_resize_enlarge */ - TRUE, /* supports_resize_shrink */ - FALSE, /* supports_online_resize_shrink */ - }, - { - "swap", /* id */ - "Swap Space", /* name */ - FALSE, /* supports_unix_owners */ - FALSE, /* can_mount */ - TRUE, /* can_create */ - 15, /* max_label_len */ - FALSE, /* supports_label_rename */ - FALSE, /* supports_online_label_rename*/ - FALSE, /* supports_fsck */ - FALSE, /* supports_online_fsck */ - FALSE, /* supports_resize_enlarge */ - FALSE, /* supports_online_resize_enlarge */ - FALSE, /* supports_resize_shrink */ - FALSE, /* supports_online_resize_shrink */ - }, -}; - -static const int num_known_file_systems = sizeof (known_file_systems) / sizeof (Filesystem); +static const Filesystem known_file_systems[] = + { + { + "vfat", /* id */ + "FAT", /* name */ + FALSE, /* supports_unix_owners */ + TRUE, /* can_mount */ + TRUE, /* can_create */ + 254, /* max_label_len */ + TRUE, /* supports_label_rename */ + FALSE, /* supports_online_label_rename*/ + TRUE, /* supports_fsck */ + FALSE, /* supports_online_fsck */ + FALSE, /* supports_resize_enlarge */ + FALSE, /* supports_online_resize_enlarge */ + FALSE, /* supports_resize_shrink */ + FALSE, /* supports_online_resize_shrink */ + }, + { + "ext2", /* id */ + "Linux Ext2", /* name */ + TRUE, /* supports_unix_owners */ + TRUE, /* can_mount */ + TRUE, /* can_create */ + 16, /* max_label_len */ + TRUE, /* supports_label_rename */ + TRUE, /* supports_online_label_rename*/ + TRUE, /* supports_fsck */ + FALSE, /* supports_online_fsck */ + TRUE, /* supports_resize_enlarge */ + TRUE, /* supports_online_resize_enlarge */ + TRUE, /* supports_resize_shrink */ + TRUE, /* supports_online_resize_shrink */ + }, + { + "ext3", /* id */ + "Linux Ext3", /* name */ + TRUE, /* supports_unix_owners */ + TRUE, /* can_mount */ + TRUE, /* can_create */ + 16, /* max_label_len */ + TRUE, /* supports_label_rename */ + TRUE, /* supports_online_label_rename*/ + TRUE, /* supports_fsck */ + FALSE, /* supports_online_fsck */ + TRUE, /* supports_resize_enlarge */ + TRUE, /* supports_online_resize_enlarge */ + TRUE, /* supports_resize_shrink */ + TRUE, /* supports_online_resize_shrink */ + }, + { + "ext4", /* id */ + "Linux Ext4", /* name */ + TRUE, /* supports_unix_owners */ + TRUE, /* can_mount */ + TRUE, /* can_create */ + 16, /* max_label_len */ + TRUE, /* supports_label_rename */ + TRUE, /* supports_online_label_rename*/ + TRUE, /* supports_fsck */ + FALSE, /* supports_online_fsck */ + TRUE, /* supports_resize_enlarge */ + TRUE, /* supports_online_resize_enlarge */ + TRUE, /* supports_resize_shrink */ + TRUE, /* supports_online_resize_shrink */ + }, + { + "xfs", /* id */ + "XFS", /* name */ + TRUE, /* supports_unix_owners */ + TRUE, /* can_mount */ + TRUE, /* can_create */ + 12, /* max_label_len */ + TRUE, /* supports_label_rename */ + FALSE, /* supports_online_label_rename*/ + TRUE, /* supports_fsck */ + FALSE, /* supports_online_fsck */ + FALSE, /* supports_resize_enlarge */ + TRUE, /* supports_online_resize_enlarge */ + FALSE, /* supports_resize_shrink */ + FALSE, /* supports_online_resize_shrink */ + }, + { + "minix", /* id */ + "Minix", /* name */ + TRUE, /* supports_unix_owners */ + TRUE, /* can_mount */ + TRUE, /* can_create */ + 0, /* max_label_len */ + FALSE, /* supports_label_rename */ + FALSE, /* supports_online_label_rename*/ + TRUE, /* supports_fsck */ + FALSE, /* supports_online_fsck */ + FALSE, /* supports_resize_enlarge */ + FALSE, /* supports_online_resize_enlarge */ + FALSE, /* supports_resize_shrink */ + FALSE, /* supports_online_resize_shrink */ + }, + { + "ntfs", /* id */ + "NTFS", /* name */ + FALSE, /* supports_unix_owners */ + TRUE, /* can_mount */ + TRUE, /* can_create */ + 128, /* max_label_len */ + TRUE, /* supports_label_rename */ + FALSE, /* supports_online_label_rename*/ + FALSE, /* supports_fsck (TODO: hmm.. ntfsck doesn't support -a yet?) */ + FALSE, /* supports_online_fsck */ + TRUE, /* supports_resize_enlarge */ + FALSE, /* supports_online_resize_enlarge */ + TRUE, /* supports_resize_shrink */ + FALSE, /* supports_online_resize_shrink */ + }, + { + "swap", /* id */ + "Swap Space", /* name */ + FALSE, /* supports_unix_owners */ + FALSE, /* can_mount */ + TRUE, /* can_create */ + 15, /* max_label_len */ + FALSE, /* supports_label_rename */ + FALSE, /* supports_online_label_rename*/ + FALSE, /* supports_fsck */ + FALSE, /* supports_online_fsck */ + FALSE, /* supports_resize_enlarge */ + FALSE, /* supports_online_resize_enlarge */ + FALSE, /* supports_resize_shrink */ + FALSE, /* supports_online_resize_shrink */ + } + }; + +static const int num_known_file_systems = sizeof(known_file_systems) / sizeof(Filesystem); const Filesystem * -daemon_local_get_fs_details (Daemon *daemon, - const gchar *filesystem_id) +daemon_local_get_fs_details (Daemon *daemon, + const gchar *filesystem_id) { - gint n; - const Filesystem *ret; + gint n; + const Filesystem *ret; - ret = NULL; + ret = NULL; - for (n = 0; n < num_known_file_systems; n++) { - if (strcmp (known_file_systems[n].id, filesystem_id) == 0) { - ret = &known_file_systems[n]; - break; - } + for (n = 0; n < num_known_file_systems; n++) + { + if (strcmp (known_file_systems[n].id, filesystem_id) == 0) + { + ret = &known_file_systems[n]; + break; } + } - return ret; + return ret; } static GPtrArray * get_known_filesystems (Daemon *daemon) { - int n; - GPtrArray *ret; - - ret = g_ptr_array_new (); - for (n = 0; n < num_known_file_systems; n++) { - GValue elem = {0}; - const Filesystem *fs = known_file_systems + n; - - g_value_init (&elem, KNOWN_FILESYSTEMS_STRUCT_TYPE); - g_value_take_boxed (&elem, dbus_g_type_specialized_construct (KNOWN_FILESYSTEMS_STRUCT_TYPE)); - dbus_g_type_struct_set (&elem, - 0, fs->id, - 1, fs->name, - 2, fs->supports_unix_owners, - 3, fs->can_mount, - 4, fs->can_create, - 5, fs->max_label_len, - 6, fs->supports_label_rename, - 7, fs->supports_online_label_rename, - 8, fs->supports_fsck, - 9, fs->supports_online_fsck, - 10, fs->supports_resize_enlarge, - 11, fs->supports_online_resize_enlarge, - 12, fs->supports_resize_shrink, - 13, fs->supports_online_resize_shrink, - G_MAXUINT); - g_ptr_array_add (ret, g_value_get_boxed (&elem)); - } + int n; + GPtrArray *ret; - return ret; + ret = g_ptr_array_new (); + for (n = 0; n < num_known_file_systems; n++) + { + GValue elem = + { 0 }; + const Filesystem *fs = known_file_systems + n; + + g_value_init (&elem, KNOWN_FILESYSTEMS_STRUCT_TYPE); + g_value_take_boxed (&elem, dbus_g_type_specialized_construct (KNOWN_FILESYSTEMS_STRUCT_TYPE)); + dbus_g_type_struct_set (&elem, + 0, + fs->id, + 1, + fs->name, + 2, + fs->supports_unix_owners, + 3, + fs->can_mount, + 4, + fs->can_create, + 5, + fs->max_label_len, + 6, + fs->supports_label_rename, + 7, + fs->supports_online_label_rename, + 8, + fs->supports_fsck, + 9, + fs->supports_online_fsck, + 10, + fs->supports_resize_enlarge, + 11, + fs->supports_online_resize_enlarge, + 12, + fs->supports_resize_shrink, + 13, + fs->supports_online_resize_shrink, + G_MAXUINT); + g_ptr_array_add (ret, g_value_get_boxed (&elem)); + } + + return ret; } /*--------------------------------------------------------------------------------------------------------------*/ static void -get_property (GObject *object, - guint prop_id, - GValue *value, - GParamSpec *pspec) -{ - Daemon *daemon = DAEMON (object); - GPtrArray *filesystems; - - switch (prop_id) { - case PROP_DAEMON_VERSION: - g_value_set_string (value, VERSION); - break; - - case PROP_DAEMON_IS_INHIBITED: - g_value_set_boolean (value, (daemon->priv->inhibitors != NULL)); - break; - - case PROP_SUPPORTS_LUKS_DEVICES: - /* TODO: probably Linux only */ - g_value_set_boolean (value, TRUE); - break; - - case PROP_KNOWN_FILESYSTEMS: - filesystems = get_known_filesystems (daemon); - g_value_set_boxed (value, filesystems); - g_ptr_array_foreach (filesystems, (GFunc) g_value_array_free, NULL); - g_ptr_array_free (filesystems, TRUE); - break; - - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } +get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + Daemon *daemon = DAEMON (object); + GPtrArray *filesystems; + + switch (prop_id) + { + case PROP_DAEMON_VERSION: + g_value_set_string (value, VERSION); + break; + + case PROP_DAEMON_IS_INHIBITED: + g_value_set_boolean (value, (daemon->priv->inhibitors != NULL)); + break; + + case PROP_SUPPORTS_LUKS_DEVICES: + /* TODO: probably Linux only */ + g_value_set_boolean (value, TRUE); + break; + + case PROP_KNOWN_FILESYSTEMS: + filesystems = get_known_filesystems (daemon); + g_value_set_boxed (value, filesystems); + g_ptr_array_foreach (filesystems, (GFunc) g_value_array_free, NULL); + g_ptr_array_free (filesystems, TRUE); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } } /*--------------------------------------------------------------------------------------------------------------*/ @@ -471,1486 +490,1524 @@ get_property (GObject *object, static void daemon_class_init (DaemonClass *klass) { - GObjectClass *object_class = G_OBJECT_CLASS (klass); + GObjectClass *object_class = G_OBJECT_CLASS (klass); - object_class->constructor = daemon_constructor; - object_class->finalize = daemon_finalize; - object_class->get_property = get_property; + object_class->constructor = daemon_constructor; + object_class->finalize = daemon_finalize; + object_class->get_property = get_property; - g_type_class_add_private (klass, sizeof (DaemonPrivate)); + g_type_class_add_private (klass, sizeof(DaemonPrivate)); - signals[DEVICE_ADDED_SIGNAL] = - g_signal_new ("device-added", - G_OBJECT_CLASS_TYPE (klass), - G_SIGNAL_RUN_LAST | G_SIGNAL_DETAILED, - 0, - NULL, NULL, - g_cclosure_marshal_VOID__BOXED, - G_TYPE_NONE, 1, DBUS_TYPE_G_OBJECT_PATH); - - signals[DEVICE_REMOVED_SIGNAL] = - g_signal_new ("device-removed", - G_OBJECT_CLASS_TYPE (klass), - G_SIGNAL_RUN_LAST | G_SIGNAL_DETAILED, - 0, - NULL, NULL, - g_cclosure_marshal_VOID__BOXED, - G_TYPE_NONE, 1, DBUS_TYPE_G_OBJECT_PATH); - - signals[DEVICE_CHANGED_SIGNAL] = - g_signal_new ("device-changed", - G_OBJECT_CLASS_TYPE (klass), - G_SIGNAL_RUN_LAST | G_SIGNAL_DETAILED, - 0, - NULL, NULL, - g_cclosure_marshal_VOID__BOXED, - G_TYPE_NONE, 1, DBUS_TYPE_G_OBJECT_PATH); - - signals[DEVICE_JOB_CHANGED_SIGNAL] = - g_signal_new ("device-job-changed", - G_OBJECT_CLASS_TYPE (klass), - G_SIGNAL_RUN_LAST | G_SIGNAL_DETAILED, - 0, - NULL, NULL, - marshal_VOID__BOXED_BOOLEAN_STRING_UINT_BOOLEAN_DOUBLE, - G_TYPE_NONE, - 6, - DBUS_TYPE_G_OBJECT_PATH, - G_TYPE_BOOLEAN, - G_TYPE_STRING, - G_TYPE_UINT, - G_TYPE_BOOLEAN, - G_TYPE_DOUBLE); - - signals[ADAPTER_ADDED_SIGNAL] = - g_signal_new ("adapter-added", - G_OBJECT_CLASS_TYPE (klass), - G_SIGNAL_RUN_LAST | G_SIGNAL_DETAILED, - 0, - NULL, NULL, - g_cclosure_marshal_VOID__BOXED, - G_TYPE_NONE, 1, DBUS_TYPE_G_OBJECT_PATH); - - signals[ADAPTER_REMOVED_SIGNAL] = - g_signal_new ("adapter-removed", - G_OBJECT_CLASS_TYPE (klass), - G_SIGNAL_RUN_LAST | G_SIGNAL_DETAILED, - 0, - NULL, NULL, - g_cclosure_marshal_VOID__BOXED, - G_TYPE_NONE, 1, DBUS_TYPE_G_OBJECT_PATH); - - signals[ADAPTER_CHANGED_SIGNAL] = - g_signal_new ("adapter-changed", - G_OBJECT_CLASS_TYPE (klass), - G_SIGNAL_RUN_LAST | G_SIGNAL_DETAILED, - 0, - NULL, NULL, - g_cclosure_marshal_VOID__BOXED, - G_TYPE_NONE, 1, DBUS_TYPE_G_OBJECT_PATH); - - signals[EXPANDER_ADDED_SIGNAL] = - g_signal_new ("expander-added", - G_OBJECT_CLASS_TYPE (klass), - G_SIGNAL_RUN_LAST | G_SIGNAL_DETAILED, - 0, - NULL, NULL, - g_cclosure_marshal_VOID__BOXED, - G_TYPE_NONE, 1, DBUS_TYPE_G_OBJECT_PATH); - - signals[EXPANDER_REMOVED_SIGNAL] = - g_signal_new ("expander-removed", - G_OBJECT_CLASS_TYPE (klass), - G_SIGNAL_RUN_LAST | G_SIGNAL_DETAILED, - 0, - NULL, NULL, - g_cclosure_marshal_VOID__BOXED, - G_TYPE_NONE, 1, DBUS_TYPE_G_OBJECT_PATH); - - signals[EXPANDER_CHANGED_SIGNAL] = - g_signal_new ("expander-changed", - G_OBJECT_CLASS_TYPE (klass), - G_SIGNAL_RUN_LAST | G_SIGNAL_DETAILED, - 0, - NULL, NULL, - g_cclosure_marshal_VOID__BOXED, - G_TYPE_NONE, 1, DBUS_TYPE_G_OBJECT_PATH); - - signals[PORT_ADDED_SIGNAL] = - g_signal_new ("port-added", - G_OBJECT_CLASS_TYPE (klass), - G_SIGNAL_RUN_LAST | G_SIGNAL_DETAILED, - 0, - NULL, NULL, - g_cclosure_marshal_VOID__BOXED, - G_TYPE_NONE, 1, DBUS_TYPE_G_OBJECT_PATH); - - signals[PORT_REMOVED_SIGNAL] = - g_signal_new ("port-removed", - G_OBJECT_CLASS_TYPE (klass), - G_SIGNAL_RUN_LAST | G_SIGNAL_DETAILED, - 0, - NULL, NULL, - g_cclosure_marshal_VOID__BOXED, - G_TYPE_NONE, 1, DBUS_TYPE_G_OBJECT_PATH); - - signals[PORT_CHANGED_SIGNAL] = - g_signal_new ("port-changed", - G_OBJECT_CLASS_TYPE (klass), - G_SIGNAL_RUN_LAST | G_SIGNAL_DETAILED, - 0, - NULL, NULL, - g_cclosure_marshal_VOID__BOXED, - G_TYPE_NONE, 1, DBUS_TYPE_G_OBJECT_PATH); + signals[DEVICE_ADDED_SIGNAL] = g_signal_new ("device-added", G_OBJECT_CLASS_TYPE (klass), G_SIGNAL_RUN_LAST + | G_SIGNAL_DETAILED, 0, NULL, NULL, g_cclosure_marshal_VOID__BOXED, G_TYPE_NONE, 1, DBUS_TYPE_G_OBJECT_PATH); + + signals[DEVICE_REMOVED_SIGNAL] = g_signal_new ("device-removed", G_OBJECT_CLASS_TYPE (klass), G_SIGNAL_RUN_LAST + | G_SIGNAL_DETAILED, 0, NULL, NULL, g_cclosure_marshal_VOID__BOXED, G_TYPE_NONE, 1, DBUS_TYPE_G_OBJECT_PATH); + + signals[DEVICE_CHANGED_SIGNAL] = g_signal_new ("device-changed", G_OBJECT_CLASS_TYPE (klass), G_SIGNAL_RUN_LAST + | G_SIGNAL_DETAILED, 0, NULL, NULL, g_cclosure_marshal_VOID__BOXED, G_TYPE_NONE, 1, DBUS_TYPE_G_OBJECT_PATH); + + signals[DEVICE_JOB_CHANGED_SIGNAL] = g_signal_new ("device-job-changed", + G_OBJECT_CLASS_TYPE (klass), + G_SIGNAL_RUN_LAST | G_SIGNAL_DETAILED, + 0, + NULL, + NULL, + marshal_VOID__BOXED_BOOLEAN_STRING_UINT_BOOLEAN_DOUBLE, + G_TYPE_NONE, + 6, + DBUS_TYPE_G_OBJECT_PATH, + G_TYPE_BOOLEAN, + G_TYPE_STRING, + G_TYPE_UINT, + G_TYPE_BOOLEAN, + G_TYPE_DOUBLE); + signals[ADAPTER_ADDED_SIGNAL] = g_signal_new ("adapter-added", G_OBJECT_CLASS_TYPE (klass), G_SIGNAL_RUN_LAST + | G_SIGNAL_DETAILED, 0, NULL, NULL, g_cclosure_marshal_VOID__BOXED, G_TYPE_NONE, 1, DBUS_TYPE_G_OBJECT_PATH); - dbus_g_object_type_install_info (TYPE_DAEMON, &dbus_glib_daemon_object_info); + signals[ADAPTER_REMOVED_SIGNAL] = g_signal_new ("adapter-removed", G_OBJECT_CLASS_TYPE (klass), G_SIGNAL_RUN_LAST + | G_SIGNAL_DETAILED, 0, NULL, NULL, g_cclosure_marshal_VOID__BOXED, G_TYPE_NONE, 1, DBUS_TYPE_G_OBJECT_PATH); - dbus_g_error_domain_register (ERROR, - "org.freedesktop.UDisks.Error", - TYPE_ERROR); + signals[ADAPTER_CHANGED_SIGNAL] = g_signal_new ("adapter-changed", G_OBJECT_CLASS_TYPE (klass), G_SIGNAL_RUN_LAST + | G_SIGNAL_DETAILED, 0, NULL, NULL, g_cclosure_marshal_VOID__BOXED, G_TYPE_NONE, 1, DBUS_TYPE_G_OBJECT_PATH); - g_object_class_install_property ( - object_class, - PROP_DAEMON_VERSION, - g_param_spec_string ("daemon-version", NULL, NULL, NULL, G_PARAM_READABLE)); + signals[EXPANDER_ADDED_SIGNAL] = g_signal_new ("expander-added", G_OBJECT_CLASS_TYPE (klass), G_SIGNAL_RUN_LAST + | G_SIGNAL_DETAILED, 0, NULL, NULL, g_cclosure_marshal_VOID__BOXED, G_TYPE_NONE, 1, DBUS_TYPE_G_OBJECT_PATH); - g_object_class_install_property ( - object_class, - PROP_DAEMON_IS_INHIBITED, - g_param_spec_boolean ("daemon-is-inhibited", NULL, NULL, FALSE, G_PARAM_READABLE)); + signals[EXPANDER_REMOVED_SIGNAL] = g_signal_new ("expander-removed", G_OBJECT_CLASS_TYPE (klass), G_SIGNAL_RUN_LAST + | G_SIGNAL_DETAILED, 0, NULL, NULL, g_cclosure_marshal_VOID__BOXED, G_TYPE_NONE, 1, DBUS_TYPE_G_OBJECT_PATH); - g_object_class_install_property ( - object_class, - PROP_SUPPORTS_LUKS_DEVICES, - g_param_spec_boolean ("supports-luks-devices", NULL, NULL, FALSE, G_PARAM_READABLE)); + signals[EXPANDER_CHANGED_SIGNAL] = g_signal_new ("expander-changed", G_OBJECT_CLASS_TYPE (klass), G_SIGNAL_RUN_LAST + | G_SIGNAL_DETAILED, 0, NULL, NULL, g_cclosure_marshal_VOID__BOXED, G_TYPE_NONE, 1, DBUS_TYPE_G_OBJECT_PATH); - g_object_class_install_property ( - object_class, - PROP_KNOWN_FILESYSTEMS, - g_param_spec_boxed ("known-filesystems", NULL, NULL, - dbus_g_type_get_collection ("GPtrArray", KNOWN_FILESYSTEMS_STRUCT_TYPE), - G_PARAM_READABLE)); + signals[PORT_ADDED_SIGNAL] = g_signal_new ("port-added", G_OBJECT_CLASS_TYPE (klass), G_SIGNAL_RUN_LAST + | G_SIGNAL_DETAILED, 0, NULL, NULL, g_cclosure_marshal_VOID__BOXED, G_TYPE_NONE, 1, DBUS_TYPE_G_OBJECT_PATH); + + signals[PORT_REMOVED_SIGNAL] = g_signal_new ("port-removed", G_OBJECT_CLASS_TYPE (klass), G_SIGNAL_RUN_LAST + | G_SIGNAL_DETAILED, 0, NULL, NULL, g_cclosure_marshal_VOID__BOXED, G_TYPE_NONE, 1, DBUS_TYPE_G_OBJECT_PATH); + + signals[PORT_CHANGED_SIGNAL] = g_signal_new ("port-changed", G_OBJECT_CLASS_TYPE (klass), G_SIGNAL_RUN_LAST + | G_SIGNAL_DETAILED, 0, NULL, NULL, g_cclosure_marshal_VOID__BOXED, G_TYPE_NONE, 1, DBUS_TYPE_G_OBJECT_PATH); + + dbus_g_object_type_install_info (TYPE_DAEMON, &dbus_glib_daemon_object_info); + + dbus_g_error_domain_register (ERROR, "org.freedesktop.UDisks.Error", TYPE_ERROR); + + g_object_class_install_property (object_class, PROP_DAEMON_VERSION, g_param_spec_string ("daemon-version", + NULL, + NULL, + NULL, + G_PARAM_READABLE)); + + g_object_class_install_property (object_class, PROP_DAEMON_IS_INHIBITED, g_param_spec_boolean ("daemon-is-inhibited", + NULL, + NULL, + FALSE, + G_PARAM_READABLE)); + + g_object_class_install_property (object_class, + PROP_SUPPORTS_LUKS_DEVICES, + g_param_spec_boolean ("supports-luks-devices", NULL, NULL, FALSE, G_PARAM_READABLE)); + + g_object_class_install_property (object_class, + PROP_KNOWN_FILESYSTEMS, + g_param_spec_boxed ("known-filesystems", + NULL, + NULL, + dbus_g_type_get_collection ("GPtrArray", + KNOWN_FILESYSTEMS_STRUCT_TYPE), + G_PARAM_READABLE)); } static void daemon_init (Daemon *daemon) { - daemon->priv = DAEMON_GET_PRIVATE (daemon); - - daemon->priv->map_dev_t_to_device = g_hash_table_new_full (g_direct_hash, - g_direct_equal, - NULL, - g_object_unref); - daemon->priv->map_device_file_to_device = g_hash_table_new_full (g_str_hash, - g_str_equal, - g_free, - g_object_unref); - - daemon->priv->map_native_path_to_device = g_hash_table_new_full (g_str_hash, - g_str_equal, - g_free, - g_object_unref); - daemon->priv->map_object_path_to_device = g_hash_table_new_full (g_str_hash, - g_str_equal, - g_free, - g_object_unref); - - daemon->priv->map_native_path_to_adapter = g_hash_table_new_full (g_str_hash, - g_str_equal, - g_free, - g_object_unref); - daemon->priv->map_object_path_to_adapter = g_hash_table_new_full (g_str_hash, - g_str_equal, - g_free, - g_object_unref); - - daemon->priv->map_native_path_to_expander = g_hash_table_new_full (g_str_hash, - g_str_equal, - g_free, - g_object_unref); - daemon->priv->map_object_path_to_expander = g_hash_table_new_full (g_str_hash, - g_str_equal, - g_free, - g_object_unref); - - daemon->priv->map_native_path_to_port = g_hash_table_new_full (g_str_hash, - g_str_equal, - g_free, - g_object_unref); - daemon->priv->map_object_path_to_port = g_hash_table_new_full (g_str_hash, - g_str_equal, - g_free, - g_object_unref); + daemon->priv = DAEMON_GET_PRIVATE (daemon); + + daemon->priv->map_dev_t_to_device = g_hash_table_new_full (g_direct_hash, g_direct_equal, NULL, g_object_unref); + daemon->priv->map_device_file_to_device = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_object_unref); + + daemon->priv->map_native_path_to_device = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_object_unref); + daemon->priv->map_object_path_to_device = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_object_unref); + + daemon->priv->map_native_path_to_adapter = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_object_unref); + daemon->priv->map_object_path_to_adapter = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_object_unref); + + daemon->priv->map_native_path_to_expander = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_object_unref); + daemon->priv->map_object_path_to_expander = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_object_unref); + + daemon->priv->map_native_path_to_port = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_object_unref); + daemon->priv->map_object_path_to_port = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_object_unref); } static void daemon_finalize (GObject *object) { - Daemon *daemon; - GList *l; - - g_return_if_fail (object != NULL); - g_return_if_fail (IS_DAEMON (object)); - - daemon = DAEMON (object); + Daemon *daemon; + GList *l; + + g_return_if_fail (object != NULL); + g_return_if_fail (IS_DAEMON (object)); + + daemon = DAEMON (object); + + g_return_if_fail (daemon->priv != NULL); + + if (daemon->priv->authority != NULL) + g_object_unref (daemon->priv->authority); + + if (daemon->priv->system_bus_proxy != NULL) + g_object_unref (daemon->priv->system_bus_proxy); + + if (daemon->priv->system_bus_connection != NULL) + dbus_g_connection_unref (daemon->priv->system_bus_connection); + + if (daemon->priv->mdstat_channel != NULL) + g_io_channel_unref (daemon->priv->mdstat_channel); + + if (daemon->priv->map_dev_t_to_device != NULL) + { + g_hash_table_unref (daemon->priv->map_dev_t_to_device); + } + if (daemon->priv->map_device_file_to_device != NULL) + { + g_hash_table_unref (daemon->priv->map_device_file_to_device); + } + + if (daemon->priv->map_native_path_to_device != NULL) + { + g_hash_table_unref (daemon->priv->map_native_path_to_device); + } + if (daemon->priv->map_object_path_to_device != NULL) + { + g_hash_table_unref (daemon->priv->map_object_path_to_device); + } + + if (daemon->priv->map_native_path_to_adapter != NULL) + { + g_hash_table_unref (daemon->priv->map_native_path_to_adapter); + } + if (daemon->priv->map_object_path_to_adapter != NULL) + { + g_hash_table_unref (daemon->priv->map_object_path_to_adapter); + } + + if (daemon->priv->map_native_path_to_expander != NULL) + { + g_hash_table_unref (daemon->priv->map_native_path_to_expander); + } + if (daemon->priv->map_object_path_to_expander != NULL) + { + g_hash_table_unref (daemon->priv->map_object_path_to_expander); + } + + if (daemon->priv->map_native_path_to_port != NULL) + { + g_hash_table_unref (daemon->priv->map_native_path_to_port); + } + if (daemon->priv->map_object_path_to_port != NULL) + { + g_hash_table_unref (daemon->priv->map_object_path_to_port); + } + + if (daemon->priv->mount_monitor != NULL) + { + g_object_unref (daemon->priv->mount_monitor); + } + + if (daemon->priv->gudev_client != NULL) + { + g_object_unref (daemon->priv->gudev_client); + } + + if (daemon->priv->ata_smart_cleanup_timer_id > 0) + { + g_source_remove (daemon->priv->ata_smart_cleanup_timer_id); + } + + if (daemon->priv->ata_smart_refresh_timer_id > 0) + { + g_source_remove (daemon->priv->ata_smart_refresh_timer_id); + } + + for (l = daemon->priv->polling_inhibitors; l != NULL; l = l->next) + { + Inhibitor *inhibitor = INHIBITOR (l->data); + g_signal_handlers_disconnect_by_func (inhibitor, daemon_polling_inhibitor_disconnected_cb, daemon); + g_object_unref (inhibitor); + } + g_list_free (daemon->priv->polling_inhibitors); + + for (l = daemon->priv->inhibitors; l != NULL; l = l->next) + { + Inhibitor *inhibitor = INHIBITOR (l->data); + g_signal_handlers_disconnect_by_func (inhibitor, daemon_inhibitor_disconnected_cb, daemon); + g_object_unref (inhibitor); + } + g_list_free (daemon->priv->inhibitors); + + G_OBJECT_CLASS (daemon_parent_class)->finalize (object); +} - g_return_if_fail (daemon->priv != NULL); +void +inhibitor_name_owner_changed (DBusMessage *message); - if (daemon->priv->authority != NULL) - g_object_unref (daemon->priv->authority); +static DBusHandlerResult +_filter (DBusConnection *connection, + DBusMessage *message, + void *user_data) +{ + //Daemon *daemon = DAEMON (user_data); + const char *interface; - if (daemon->priv->system_bus_proxy != NULL) - g_object_unref (daemon->priv->system_bus_proxy); + interface = dbus_message_get_interface (message); - if (daemon->priv->system_bus_connection != NULL) - dbus_g_connection_unref (daemon->priv->system_bus_connection); + if (dbus_message_is_signal (message, DBUS_INTERFACE_DBUS, "NameOwnerChanged")) + { + /* for now, pass NameOwnerChanged to Inhibitor */ + inhibitor_name_owner_changed (message); + } - if (daemon->priv->mdstat_channel != NULL) - g_io_channel_unref (daemon->priv->mdstat_channel); + /* other filters might want to process this message too */ + return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; +} - if (daemon->priv->map_dev_t_to_device != NULL) { - g_hash_table_unref (daemon->priv->map_dev_t_to_device); - } - if (daemon->priv->map_device_file_to_device != NULL) { - g_hash_table_unref (daemon->priv->map_device_file_to_device); - } +/* ---------------------------------------------------------------------------------------------------- */ - if (daemon->priv->map_native_path_to_device != NULL) { - g_hash_table_unref (daemon->priv->map_native_path_to_device); - } - if (daemon->priv->map_object_path_to_device != NULL) { - g_hash_table_unref (daemon->priv->map_object_path_to_device); - } +static void +device_add (Daemon *daemon, + GUdevDevice *d, + gboolean emit_event); +static void +device_remove (Daemon *daemon, + GUdevDevice *d); - if (daemon->priv->map_native_path_to_adapter != NULL) { - g_hash_table_unref (daemon->priv->map_native_path_to_adapter); - } - if (daemon->priv->map_object_path_to_adapter != NULL) { - g_hash_table_unref (daemon->priv->map_object_path_to_adapter); - } +/* ---------------------------------------------------------------------------------------------------- */ - if (daemon->priv->map_native_path_to_expander != NULL) { - g_hash_table_unref (daemon->priv->map_native_path_to_expander); - } - if (daemon->priv->map_object_path_to_expander != NULL) { - g_hash_table_unref (daemon->priv->map_object_path_to_expander); - } +static void +pci_device_changed (Daemon *daemon, + GUdevDevice *d, + gboolean synthesized) +{ + Adapter *adapter; + const char *native_path; - if (daemon->priv->map_native_path_to_port != NULL) { - g_hash_table_unref (daemon->priv->map_native_path_to_port); - } - if (daemon->priv->map_object_path_to_port != NULL) { - g_hash_table_unref (daemon->priv->map_object_path_to_port); - } + native_path = g_udev_device_get_sysfs_path (d); + adapter = g_hash_table_lookup (daemon->priv->map_native_path_to_adapter, native_path); + if (adapter != NULL) + { + gboolean keep_adapter; + g_print ("**** pci CHANGING %s\n", native_path); - if (daemon->priv->mount_monitor != NULL) { - g_object_unref (daemon->priv->mount_monitor); - } + /* The sysfs path ('move' uevent) may actually change so remove it and add + * it back after processing. The kernel name will never change so the object + * path will fortunately remain constant. + */ + g_warn_if_fail (g_hash_table_remove (daemon->priv->map_native_path_to_adapter, adapter->priv->native_path)); - if (daemon->priv->gudev_client != NULL) { - g_object_unref (daemon->priv->gudev_client); - } + keep_adapter = adapter_changed (adapter, d, synthesized); - if (daemon->priv->ata_smart_cleanup_timer_id > 0) { - g_source_remove (daemon->priv->ata_smart_cleanup_timer_id); - } + g_assert (adapter_local_get_native_path (adapter) != NULL); + g_assert (g_strcmp0 (native_path, adapter_local_get_native_path (adapter)) == 0); - if (daemon->priv->ata_smart_refresh_timer_id > 0) { - g_source_remove (daemon->priv->ata_smart_refresh_timer_id); - } + /* now add the things back to the global hashtables - it's important that we + * do this *before* calling adapter_remove() - otherwise it will never remove + * the adapter + */ + g_hash_table_insert (daemon->priv->map_native_path_to_adapter, + g_strdup (adapter_local_get_native_path (adapter)), + g_object_ref (adapter)); - for (l = daemon->priv->polling_inhibitors; l != NULL; l = l->next) { - Inhibitor *inhibitor = INHIBITOR (l->data); - g_signal_handlers_disconnect_by_func (inhibitor, daemon_polling_inhibitor_disconnected_cb, daemon); - g_object_unref (inhibitor); + if (!keep_adapter) + { + g_print ("**** pci CHANGE TRIGGERED REMOVE %s\n", native_path); + device_remove (daemon, d); } - g_list_free (daemon->priv->polling_inhibitors); - - for (l = daemon->priv->inhibitors; l != NULL; l = l->next) { - Inhibitor *inhibitor = INHIBITOR (l->data); - g_signal_handlers_disconnect_by_func (inhibitor, daemon_inhibitor_disconnected_cb, daemon); - g_object_unref (inhibitor); + else + { + g_print ("**** pci CHANGED %s\n", native_path); } - g_list_free (daemon->priv->inhibitors); - - G_OBJECT_CLASS (daemon_parent_class)->finalize (object); + } + else + { + g_print ("**** pci TREATING CHANGE AS ADD %s\n", native_path); + device_add (daemon, d, TRUE); + } } +/* ------------------------------ */ -void inhibitor_name_owner_changed (DBusMessage *message); - -static DBusHandlerResult -_filter (DBusConnection *connection, DBusMessage *message, void *user_data) +static void +scsi_host_device_changed (Daemon *daemon, + GUdevDevice *d, + gboolean synthesized) { - //Daemon *daemon = DAEMON (user_data); - const char *interface; + Port *port; + const char *native_path; - interface = dbus_message_get_interface (message); + native_path = g_udev_device_get_sysfs_path (d); + port = g_hash_table_lookup (daemon->priv->map_native_path_to_port, native_path); + if (port != NULL) + { + gboolean keep_port; - if (dbus_message_is_signal (message, DBUS_INTERFACE_DBUS, "NameOwnerChanged")) { - /* for now, pass NameOwnerChanged to Inhibitor */ - inhibitor_name_owner_changed (message); - } + g_print ("**** scsi_host CHANGING %s\n", native_path); - /* other filters might want to process this message too */ - return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; -} + /* The sysfs path ('move' uevent) may actually change so remove it and add + * it back after processing. The kernel name will never change so the object + * path will fortunately remain constant. + */ + g_warn_if_fail (g_hash_table_remove (daemon->priv->map_native_path_to_port, port->priv->native_path)); -/* ---------------------------------------------------------------------------------------------------- */ + keep_port = port_changed (port, d, synthesized); -static void device_add (Daemon *daemon, GUdevDevice *d, gboolean emit_event); -static void device_remove (Daemon *daemon, GUdevDevice *d); + g_assert (port_local_get_native_path (port) != NULL); + g_assert (g_strcmp0 (native_path, port_local_get_native_path (port)) == 0); -/* ---------------------------------------------------------------------------------------------------- */ + /* now add the things back to the global hashtables - it's important that we + * do this *before* calling port_remove() - otherwise it will never remove + * the port + */ + g_hash_table_insert (daemon->priv->map_native_path_to_port, + g_strdup (port_local_get_native_path (port)), + g_object_ref (port)); -static void -pci_device_changed (Daemon *daemon, GUdevDevice *d, gboolean synthesized) -{ - Adapter *adapter; - const char *native_path; - - native_path = g_udev_device_get_sysfs_path (d); - adapter = g_hash_table_lookup (daemon->priv->map_native_path_to_adapter, native_path); - if (adapter != NULL) { - gboolean keep_adapter; - - g_print ("**** pci CHANGING %s\n", native_path); - - /* The sysfs path ('move' uevent) may actually change so remove it and add - * it back after processing. The kernel name will never change so the object - * path will fortunately remain constant. - */ - g_warn_if_fail (g_hash_table_remove (daemon->priv->map_native_path_to_adapter, - adapter->priv->native_path)); - - keep_adapter = adapter_changed (adapter, d, synthesized); - - g_assert (adapter_local_get_native_path (adapter) != NULL); - g_assert (g_strcmp0 (native_path, adapter_local_get_native_path (adapter)) == 0); - - /* now add the things back to the global hashtables - it's important that we - * do this *before* calling adapter_remove() - otherwise it will never remove - * the adapter - */ - g_hash_table_insert (daemon->priv->map_native_path_to_adapter, - g_strdup (adapter_local_get_native_path (adapter)), - g_object_ref (adapter)); - - if (!keep_adapter) { - g_print ("**** pci CHANGE TRIGGERED REMOVE %s\n", native_path); - device_remove (daemon, d); - } else { - g_print ("**** pci CHANGED %s\n", native_path); - } - } else { - g_print ("**** pci TREATING CHANGE AS ADD %s\n", native_path); - device_add (daemon, d, TRUE); + if (!keep_port) + { + g_print ("**** scsi_host CHANGE TRIGGERED REMOVE %s\n", native_path); + device_remove (daemon, d); } + else + { + g_print ("**** scsi_host CHANGED %s\n", native_path); + } + } + else + { + g_print ("**** scsi_host TREATING CHANGE AS ADD %s\n", native_path); + device_add (daemon, d, TRUE); + } } /* ------------------------------ */ static void -scsi_host_device_changed (Daemon *daemon, GUdevDevice *d, gboolean synthesized) -{ - Port *port; - const char *native_path; - - native_path = g_udev_device_get_sysfs_path (d); - port = g_hash_table_lookup (daemon->priv->map_native_path_to_port, native_path); - if (port != NULL) { - gboolean keep_port; - - g_print ("**** scsi_host CHANGING %s\n", native_path); - - /* The sysfs path ('move' uevent) may actually change so remove it and add - * it back after processing. The kernel name will never change so the object - * path will fortunately remain constant. - */ - g_warn_if_fail (g_hash_table_remove (daemon->priv->map_native_path_to_port, - port->priv->native_path)); - - keep_port = port_changed (port, d, synthesized); - - g_assert (port_local_get_native_path (port) != NULL); - g_assert (g_strcmp0 (native_path, port_local_get_native_path (port)) == 0); - - /* now add the things back to the global hashtables - it's important that we - * do this *before* calling port_remove() - otherwise it will never remove - * the port - */ - g_hash_table_insert (daemon->priv->map_native_path_to_port, - g_strdup (port_local_get_native_path (port)), - g_object_ref (port)); - - if (!keep_port) { - g_print ("**** scsi_host CHANGE TRIGGERED REMOVE %s\n", native_path); - device_remove (daemon, d); - } else { - g_print ("**** scsi_host CHANGED %s\n", native_path); - } - } else { - g_print ("**** scsi_host TREATING CHANGE AS ADD %s\n", native_path); - device_add (daemon, d, TRUE); - } -} +sas_phy_device_changed (Daemon *daemon, + GUdevDevice *d, + gboolean synthesized) +{ + Port *port; + const char *native_path; -/* ------------------------------ */ + native_path = g_udev_device_get_sysfs_path (d); + port = g_hash_table_lookup (daemon->priv->map_native_path_to_port, native_path); + if (port != NULL) + { + gboolean keep_port; -static void -sas_phy_device_changed (Daemon *daemon, GUdevDevice *d, gboolean synthesized) -{ - Port *port; - const char *native_path; - - native_path = g_udev_device_get_sysfs_path (d); - port = g_hash_table_lookup (daemon->priv->map_native_path_to_port, native_path); - if (port != NULL) { - gboolean keep_port; - - g_print ("**** sas_phy CHANGING %s\n", native_path); - - /* The sysfs path ('move' uevent) may actually change so remove it and add - * it back after processing. The kernel name will never change so the object - * path will fortunately remain constant. - */ - g_warn_if_fail (g_hash_table_remove (daemon->priv->map_native_path_to_port, - port->priv->native_path)); - - keep_port = port_changed (port, d, synthesized); - - g_assert (port_local_get_native_path (port) != NULL); - g_assert (g_strcmp0 (native_path, port_local_get_native_path (port)) == 0); - - /* now add the things back to the global hashtables - it's important that we - * do this *before* calling port_remove() - otherwise it will never remove - * the port - */ - g_hash_table_insert (daemon->priv->map_native_path_to_port, - g_strdup (port_local_get_native_path (port)), - g_object_ref (port)); - - if (!keep_port) { - g_print ("**** sas_phy CHANGE TRIGGERED REMOVE %s\n", native_path); - device_remove (daemon, d); - } else { - g_print ("**** sas_phy CHANGED %s\n", native_path); - } - } else { - g_print ("**** sas_phy TREATING CHANGE AS ADD %s\n", native_path); - device_add (daemon, d, TRUE); + g_print ("**** sas_phy CHANGING %s\n", native_path); + + /* The sysfs path ('move' uevent) may actually change so remove it and add + * it back after processing. The kernel name will never change so the object + * path will fortunately remain constant. + */ + g_warn_if_fail (g_hash_table_remove (daemon->priv->map_native_path_to_port, port->priv->native_path)); + + keep_port = port_changed (port, d, synthesized); + + g_assert (port_local_get_native_path (port) != NULL); + g_assert (g_strcmp0 (native_path, port_local_get_native_path (port)) == 0); + + /* now add the things back to the global hashtables - it's important that we + * do this *before* calling port_remove() - otherwise it will never remove + * the port + */ + g_hash_table_insert (daemon->priv->map_native_path_to_port, + g_strdup (port_local_get_native_path (port)), + g_object_ref (port)); + + if (!keep_port) + { + g_print ("**** sas_phy CHANGE TRIGGERED REMOVE %s\n", native_path); + device_remove (daemon, d); } + else + { + g_print ("**** sas_phy CHANGED %s\n", native_path); + } + } + else + { + g_print ("**** sas_phy TREATING CHANGE AS ADD %s\n", native_path); + device_add (daemon, d, TRUE); + } } /* ------------------------------ */ static void -sas_expander_device_changed (Daemon *daemon, GUdevDevice *d, gboolean synthesized) -{ - Expander *expander; - const char *native_path; - - native_path = g_udev_device_get_sysfs_path (d); - expander = g_hash_table_lookup (daemon->priv->map_native_path_to_expander, native_path); - if (expander != NULL) { - gboolean keep_expander; - - g_print ("**** sas_expander CHANGING %s\n", native_path); - - /* The sysfs path ('move' uevent) may actually change so remove it and add - * it back after processing. The kernel name will never change so the object - * path will fortunately remain constant. - */ - g_warn_if_fail (g_hash_table_remove (daemon->priv->map_native_path_to_expander, - expander->priv->native_path)); - - keep_expander = expander_changed (expander, d, synthesized); - - g_assert (expander_local_get_native_path (expander) != NULL); - g_assert (g_strcmp0 (native_path, expander_local_get_native_path (expander)) == 0); - - /* now add the things back to the global hashtables - it's important that we - * do this *before* calling expander_remove() - otherwise it will never remove - * the expander - */ - g_hash_table_insert (daemon->priv->map_native_path_to_expander, - g_strdup (expander_local_get_native_path (expander)), - g_object_ref (expander)); - - if (!keep_expander) { - g_print ("**** sas_expander CHANGE TRIGGERED REMOVE %s\n", native_path); - device_remove (daemon, d); - } else { - g_print ("**** sas_expander CHANGED %s\n", native_path); - } - } else { - g_print ("**** sas_expander TREATING CHANGE AS ADD %s\n", native_path); - device_add (daemon, d, TRUE); +sas_expander_device_changed (Daemon *daemon, + GUdevDevice *d, + gboolean synthesized) +{ + Expander *expander; + const char *native_path; + + native_path = g_udev_device_get_sysfs_path (d); + expander = g_hash_table_lookup (daemon->priv->map_native_path_to_expander, native_path); + if (expander != NULL) + { + gboolean keep_expander; + + g_print ("**** sas_expander CHANGING %s\n", native_path); + + /* The sysfs path ('move' uevent) may actually change so remove it and add + * it back after processing. The kernel name will never change so the object + * path will fortunately remain constant. + */ + g_warn_if_fail (g_hash_table_remove (daemon->priv->map_native_path_to_expander, expander->priv->native_path)); + + keep_expander = expander_changed (expander, d, synthesized); + + g_assert (expander_local_get_native_path (expander) != NULL); + g_assert (g_strcmp0 (native_path, expander_local_get_native_path (expander)) == 0); + + /* now add the things back to the global hashtables - it's important that we + * do this *before* calling expander_remove() - otherwise it will never remove + * the expander + */ + g_hash_table_insert (daemon->priv->map_native_path_to_expander, + g_strdup (expander_local_get_native_path (expander)), + g_object_ref (expander)); + + if (!keep_expander) + { + g_print ("**** sas_expander CHANGE TRIGGERED REMOVE %s\n", native_path); + device_remove (daemon, d); + } + else + { + g_print ("**** sas_expander CHANGED %s\n", native_path); } + } + else + { + g_print ("**** sas_expander TREATING CHANGE AS ADD %s\n", native_path); + device_add (daemon, d, TRUE); + } } /* ------------------------------ */ static void -block_device_changed (Daemon *daemon, GUdevDevice *d, gboolean synthesized) -{ - Device *device; - const char *native_path; - - native_path = g_udev_device_get_sysfs_path (d); - device = g_hash_table_lookup (daemon->priv->map_native_path_to_device, native_path); - if (device != NULL) { - gboolean keep_device; - - g_print ("**** CHANGING %s\n", native_path); - - /* The device file (udev rules) and/or sysfs path ('move' uevent) may actually change so - * remove it and add it back after processing. The kernel name will never change so - * the object path will fortunately remain constant. - */ - g_warn_if_fail (g_hash_table_remove (daemon->priv->map_native_path_to_device, - device->priv->native_path)); - g_warn_if_fail (g_hash_table_remove (daemon->priv->map_device_file_to_device, - device->priv->device_file)); - - keep_device = device_changed (device, d, synthesized); - - g_assert (device_local_get_device_file (device) != NULL); - g_assert (device_local_get_native_path (device) != NULL); - g_assert (g_strcmp0 (native_path, device_local_get_native_path (device)) == 0); - - /* now add the things back to the global hashtables - it's important that we - * do this *before* calling device_remove() - otherwise it will never remove - * the device - */ - g_hash_table_insert (daemon->priv->map_device_file_to_device, - g_strdup (device_local_get_device_file (device)), - g_object_ref (device)); - g_hash_table_insert (daemon->priv->map_native_path_to_device, - g_strdup (device_local_get_native_path (device)), - g_object_ref (device)); - - if (!keep_device) { - g_print ("**** CHANGE TRIGGERED REMOVE %s\n", native_path); - device_remove (daemon, d); - } else { - g_print ("**** CHANGED %s\n", native_path); - - daemon_local_update_poller (daemon); - daemon_local_update_spindown (daemon); - } - } else { - g_print ("**** TREATING CHANGE AS ADD %s\n", native_path); - device_add (daemon, d, TRUE); +block_device_changed (Daemon *daemon, + GUdevDevice *d, + gboolean synthesized) +{ + Device *device; + const char *native_path; + + native_path = g_udev_device_get_sysfs_path (d); + device = g_hash_table_lookup (daemon->priv->map_native_path_to_device, native_path); + if (device != NULL) + { + gboolean keep_device; + + g_print ("**** CHANGING %s\n", native_path); + + /* The device file (udev rules) and/or sysfs path ('move' uevent) may actually change so + * remove it and add it back after processing. The kernel name will never change so + * the object path will fortunately remain constant. + */ + g_warn_if_fail (g_hash_table_remove (daemon->priv->map_native_path_to_device, device->priv->native_path)); + g_warn_if_fail (g_hash_table_remove (daemon->priv->map_device_file_to_device, device->priv->device_file)); + + keep_device = device_changed (device, d, synthesized); + + g_assert (device_local_get_device_file (device) != NULL); + g_assert (device_local_get_native_path (device) != NULL); + g_assert (g_strcmp0 (native_path, device_local_get_native_path (device)) == 0); + + /* now add the things back to the global hashtables - it's important that we + * do this *before* calling device_remove() - otherwise it will never remove + * the device + */ + g_hash_table_insert (daemon->priv->map_device_file_to_device, + g_strdup (device_local_get_device_file (device)), + g_object_ref (device)); + g_hash_table_insert (daemon->priv->map_native_path_to_device, + g_strdup (device_local_get_native_path (device)), + g_object_ref (device)); + + if (!keep_device) + { + g_print ("**** CHANGE TRIGGERED REMOVE %s\n", native_path); + device_remove (daemon, d); } + else + { + g_print ("**** CHANGED %s\n", native_path); + + daemon_local_update_poller (daemon); + daemon_local_update_spindown (daemon); + } + } + else + { + g_print ("**** TREATING CHANGE AS ADD %s\n", native_path); + device_add (daemon, d, TRUE); + } } static void -_device_changed (Daemon *daemon, GUdevDevice *d, gboolean synthesized) -{ - const gchar *subsystem; - - subsystem = g_udev_device_get_subsystem (d); - if (g_strcmp0 (subsystem, "block") == 0) - block_device_changed (daemon, d, synthesized); - else if (g_strcmp0 (subsystem, "pci") == 0) - pci_device_changed (daemon, d, synthesized); - else if (g_strcmp0 (subsystem, "scsi_host") == 0) - scsi_host_device_changed (daemon, d, synthesized); - else if (g_strcmp0 (subsystem, "sas_phy") == 0) - sas_phy_device_changed (daemon, d, synthesized); - else if (g_strcmp0 (subsystem, "sas_expander") == 0) - sas_expander_device_changed (daemon, d, synthesized); - else - g_warning ("Unhandled changed event from subsystem `%s'", subsystem); +_device_changed (Daemon *daemon, + GUdevDevice *d, + gboolean synthesized) +{ + const gchar *subsystem; + + subsystem = g_udev_device_get_subsystem (d); + if (g_strcmp0 (subsystem, "block") == 0) + block_device_changed (daemon, d, synthesized); + else if (g_strcmp0 (subsystem, "pci") == 0) + pci_device_changed (daemon, d, synthesized); + else if (g_strcmp0 (subsystem, "scsi_host") == 0) + scsi_host_device_changed (daemon, d, synthesized); + else if (g_strcmp0 (subsystem, "sas_phy") == 0) + sas_phy_device_changed (daemon, d, synthesized); + else if (g_strcmp0 (subsystem, "sas_expander") == 0) + sas_expander_device_changed (daemon, d, synthesized); + else + g_warning ("Unhandled changed event from subsystem `%s'", subsystem); } void daemon_local_synthesize_changed (Daemon *daemon, - Device *device) + Device *device) { - g_object_ref (device->priv->d); - _device_changed (daemon, device->priv->d, TRUE); - g_object_unref (device->priv->d); + g_object_ref (device->priv->d); + _device_changed (daemon, device->priv->d, TRUE); + g_object_unref (device->priv->d); } void daemon_local_synthesize_changed_on_all_devices (Daemon *daemon) { - GHashTableIter hash_iter; - Device *device; + GHashTableIter hash_iter; + Device *device; - g_hash_table_iter_init (&hash_iter, daemon->priv->map_object_path_to_device); - while (g_hash_table_iter_next (&hash_iter, NULL, (gpointer) &device)) { - daemon_local_synthesize_changed (daemon, device); - } + g_hash_table_iter_init (&hash_iter, daemon->priv->map_object_path_to_device); + while (g_hash_table_iter_next (&hash_iter, NULL, (gpointer) & device)) + { + daemon_local_synthesize_changed (daemon, device); + } } /* ---------------------------------------------------------------------------------------------------- */ static void -pci_device_add (Daemon *daemon, GUdevDevice *d, gboolean emit_event) -{ - Adapter *adapter; - const char *native_path; - - native_path = g_udev_device_get_sysfs_path (d); - adapter = g_hash_table_lookup (daemon->priv->map_native_path_to_adapter, native_path); - if (adapter != NULL) { - /* we already have the adapter; treat as change event */ - g_print ("**** pci TREATING ADD AS CHANGE %s\n", native_path); - _device_changed (daemon, d, FALSE); - } else { - g_print ("**** pci ADDING %s\n", native_path); - adapter = adapter_new (daemon, d); - - if (adapter != NULL) { - /* assert that the adapter is fully loaded with info */ - g_assert (adapter_local_get_native_path (adapter) != NULL); - g_assert (adapter_local_get_object_path (adapter) != NULL); - g_assert (g_strcmp0 (native_path, adapter_local_get_native_path (adapter)) == 0); - - g_hash_table_insert (daemon->priv->map_native_path_to_adapter, - g_strdup (adapter_local_get_native_path (adapter)), - g_object_ref (adapter)); - g_hash_table_insert (daemon->priv->map_object_path_to_adapter, - g_strdup (adapter_local_get_object_path (adapter)), - g_object_ref (adapter)); - g_print ("**** pci ADDED %s\n", native_path); - if (emit_event) { - const char *object_path; - object_path = adapter_local_get_object_path (adapter); - g_print ("**** pci EMITTING ADDED for %s\n", adapter->priv->native_path); - g_signal_emit (daemon, signals[ADAPTER_ADDED_SIGNAL], 0, object_path); - } - } else { - g_print ("**** pci IGNORING ADD %s\n", native_path); - } +pci_device_add (Daemon *daemon, + GUdevDevice *d, + gboolean emit_event) +{ + Adapter *adapter; + const char *native_path; + + native_path = g_udev_device_get_sysfs_path (d); + adapter = g_hash_table_lookup (daemon->priv->map_native_path_to_adapter, native_path); + if (adapter != NULL) + { + /* we already have the adapter; treat as change event */ + g_print ("**** pci TREATING ADD AS CHANGE %s\n", native_path); + _device_changed (daemon, d, FALSE); + } + else + { + g_print ("**** pci ADDING %s\n", native_path); + adapter = adapter_new (daemon, d); + + if (adapter != NULL) + { + /* assert that the adapter is fully loaded with info */ + g_assert (adapter_local_get_native_path (adapter) != NULL); + g_assert (adapter_local_get_object_path (adapter) != NULL); + g_assert (g_strcmp0 (native_path, adapter_local_get_native_path (adapter)) == 0); + + g_hash_table_insert (daemon->priv->map_native_path_to_adapter, + g_strdup (adapter_local_get_native_path (adapter)), + g_object_ref (adapter)); + g_hash_table_insert (daemon->priv->map_object_path_to_adapter, + g_strdup (adapter_local_get_object_path (adapter)), + g_object_ref (adapter)); + g_print ("**** pci ADDED %s\n", native_path); + if (emit_event) + { + const char *object_path; + object_path = adapter_local_get_object_path (adapter); + g_print ("**** pci EMITTING ADDED for %s\n", adapter->priv->native_path); + g_signal_emit (daemon, signals[ADAPTER_ADDED_SIGNAL], 0, object_path); + } + } + else + { + g_print ("**** pci IGNORING ADD %s\n", native_path); } + } } /* ------------------------------ */ static void -scsi_host_device_add (Daemon *daemon, GUdevDevice *d, gboolean emit_event) -{ - Port *port; - const char *native_path; - - native_path = g_udev_device_get_sysfs_path (d); - port = g_hash_table_lookup (daemon->priv->map_native_path_to_port, native_path); - if (port != NULL) { - /* we already have the port; treat as change event */ - g_print ("**** scsi_host TREATING ADD AS CHANGE %s\n", native_path); - _device_changed (daemon, d, FALSE); - } else { - g_print ("**** scsi_host ADDING %s\n", native_path); - port = port_new (daemon, d); - - if (port != NULL) { - /* assert that the port is fully loaded with info */ - g_assert (port_local_get_native_path (port) != NULL); - g_assert (port_local_get_object_path (port) != NULL); - g_assert (g_strcmp0 (native_path, port_local_get_native_path (port)) == 0); - - g_hash_table_insert (daemon->priv->map_native_path_to_port, - g_strdup (port_local_get_native_path (port)), - g_object_ref (port)); - g_hash_table_insert (daemon->priv->map_object_path_to_port, - g_strdup (port_local_get_object_path (port)), - g_object_ref (port)); - g_print ("**** scsi_host ADDED %s\n", native_path); - if (emit_event) { - const char *object_path; - object_path = port_local_get_object_path (port); - g_print ("**** scsi_host EMITTING ADDED for %s\n", port->priv->native_path); - g_signal_emit (daemon, signals[PORT_ADDED_SIGNAL], 0, object_path); - } - } else { - g_print ("**** scsi_host IGNORING ADD %s\n", native_path); - } +scsi_host_device_add (Daemon *daemon, + GUdevDevice *d, + gboolean emit_event) +{ + Port *port; + const char *native_path; + + native_path = g_udev_device_get_sysfs_path (d); + port = g_hash_table_lookup (daemon->priv->map_native_path_to_port, native_path); + if (port != NULL) + { + /* we already have the port; treat as change event */ + g_print ("**** scsi_host TREATING ADD AS CHANGE %s\n", native_path); + _device_changed (daemon, d, FALSE); + } + else + { + g_print ("**** scsi_host ADDING %s\n", native_path); + port = port_new (daemon, d); + + if (port != NULL) + { + /* assert that the port is fully loaded with info */ + g_assert (port_local_get_native_path (port) != NULL); + g_assert (port_local_get_object_path (port) != NULL); + g_assert (g_strcmp0 (native_path, port_local_get_native_path (port)) == 0); + + g_hash_table_insert (daemon->priv->map_native_path_to_port, + g_strdup (port_local_get_native_path (port)), + g_object_ref (port)); + g_hash_table_insert (daemon->priv->map_object_path_to_port, + g_strdup (port_local_get_object_path (port)), + g_object_ref (port)); + g_print ("**** scsi_host ADDED %s\n", native_path); + if (emit_event) + { + const char *object_path; + object_path = port_local_get_object_path (port); + g_print ("**** scsi_host EMITTING ADDED for %s\n", port->priv->native_path); + g_signal_emit (daemon, signals[PORT_ADDED_SIGNAL], 0, object_path); + } + } + else + { + g_print ("**** scsi_host IGNORING ADD %s\n", native_path); } + } } /* ------------------------------ */ static void -sas_phy_device_add (Daemon *daemon, GUdevDevice *d, gboolean emit_event) -{ - Port *port; - const char *native_path; - - native_path = g_udev_device_get_sysfs_path (d); - port = g_hash_table_lookup (daemon->priv->map_native_path_to_port, native_path); - if (port != NULL) { - /* we already have the port; treat as change event */ - g_print ("**** sas_phy TREATING ADD AS CHANGE %s\n", native_path); - _device_changed (daemon, d, FALSE); - } else { - g_print ("**** sas_phy ADDING %s\n", native_path); - port = port_new (daemon, d); - - if (port != NULL) { - /* assert that the port is fully loaded with info */ - g_assert (port_local_get_native_path (port) != NULL); - g_assert (port_local_get_object_path (port) != NULL); - g_assert (g_strcmp0 (native_path, port_local_get_native_path (port)) == 0); - - g_hash_table_insert (daemon->priv->map_native_path_to_port, - g_strdup (port_local_get_native_path (port)), - g_object_ref (port)); - g_hash_table_insert (daemon->priv->map_object_path_to_port, - g_strdup (port_local_get_object_path (port)), - g_object_ref (port)); - g_print ("**** sas_phy ADDED %s\n", native_path); - if (emit_event) { - const char *object_path; - object_path = port_local_get_object_path (port); - g_print ("**** sas_phy EMITTING ADDED for %s\n", port->priv->native_path); - g_signal_emit (daemon, signals[PORT_ADDED_SIGNAL], 0, object_path); - } - } else { - g_print ("**** sas_phy IGNORING ADD %s\n", native_path); - } +sas_phy_device_add (Daemon *daemon, + GUdevDevice *d, + gboolean emit_event) +{ + Port *port; + const char *native_path; + + native_path = g_udev_device_get_sysfs_path (d); + port = g_hash_table_lookup (daemon->priv->map_native_path_to_port, native_path); + if (port != NULL) + { + /* we already have the port; treat as change event */ + g_print ("**** sas_phy TREATING ADD AS CHANGE %s\n", native_path); + _device_changed (daemon, d, FALSE); + } + else + { + g_print ("**** sas_phy ADDING %s\n", native_path); + port = port_new (daemon, d); + + if (port != NULL) + { + /* assert that the port is fully loaded with info */ + g_assert (port_local_get_native_path (port) != NULL); + g_assert (port_local_get_object_path (port) != NULL); + g_assert (g_strcmp0 (native_path, port_local_get_native_path (port)) == 0); + + g_hash_table_insert (daemon->priv->map_native_path_to_port, + g_strdup (port_local_get_native_path (port)), + g_object_ref (port)); + g_hash_table_insert (daemon->priv->map_object_path_to_port, + g_strdup (port_local_get_object_path (port)), + g_object_ref (port)); + g_print ("**** sas_phy ADDED %s\n", native_path); + if (emit_event) + { + const char *object_path; + object_path = port_local_get_object_path (port); + g_print ("**** sas_phy EMITTING ADDED for %s\n", port->priv->native_path); + g_signal_emit (daemon, signals[PORT_ADDED_SIGNAL], 0, object_path); + } + } + else + { + g_print ("**** sas_phy IGNORING ADD %s\n", native_path); } + } } /* ------------------------------ */ static void -sas_expander_device_add (Daemon *daemon, GUdevDevice *d, gboolean emit_event) -{ - Expander *expander; - const char *native_path; - - native_path = g_udev_device_get_sysfs_path (d); - expander = g_hash_table_lookup (daemon->priv->map_native_path_to_expander, native_path); - if (expander != NULL) { - /* we already have the expander; treat as change event */ - g_print ("**** sas_expander TREATING ADD AS CHANGE %s\n", native_path); - _device_changed (daemon, d, FALSE); - } else { - g_print ("**** sas_expander ADDING %s\n", native_path); - expander = expander_new (daemon, d); - - if (expander != NULL) { - /* assert that the expander is fully loaded with info */ - g_assert (expander_local_get_native_path (expander) != NULL); - g_assert (expander_local_get_object_path (expander) != NULL); - g_assert (g_strcmp0 (native_path, expander_local_get_native_path (expander)) == 0); - - g_hash_table_insert (daemon->priv->map_native_path_to_expander, - g_strdup (expander_local_get_native_path (expander)), - g_object_ref (expander)); - g_hash_table_insert (daemon->priv->map_object_path_to_expander, - g_strdup (expander_local_get_object_path (expander)), - g_object_ref (expander)); - g_print ("**** sas_expander ADDED %s\n", native_path); - if (emit_event) { - const char *object_path; - object_path = expander_local_get_object_path (expander); - g_print ("**** sas_expander EMITTING ADDED for %s\n", expander->priv->native_path); - g_signal_emit (daemon, signals[EXPANDER_ADDED_SIGNAL], 0, object_path); - } - } else { - g_print ("**** sas_expander IGNORING ADD %s\n", native_path); - } +sas_expander_device_add (Daemon *daemon, + GUdevDevice *d, + gboolean emit_event) +{ + Expander *expander; + const char *native_path; + + native_path = g_udev_device_get_sysfs_path (d); + expander = g_hash_table_lookup (daemon->priv->map_native_path_to_expander, native_path); + if (expander != NULL) + { + /* we already have the expander; treat as change event */ + g_print ("**** sas_expander TREATING ADD AS CHANGE %s\n", native_path); + _device_changed (daemon, d, FALSE); + } + else + { + g_print ("**** sas_expander ADDING %s\n", native_path); + expander = expander_new (daemon, d); + + if (expander != NULL) + { + /* assert that the expander is fully loaded with info */ + g_assert (expander_local_get_native_path (expander) != NULL); + g_assert (expander_local_get_object_path (expander) != NULL); + g_assert (g_strcmp0 (native_path, expander_local_get_native_path (expander)) == 0); + + g_hash_table_insert (daemon->priv->map_native_path_to_expander, + g_strdup (expander_local_get_native_path (expander)), + g_object_ref (expander)); + g_hash_table_insert (daemon->priv->map_object_path_to_expander, + g_strdup (expander_local_get_object_path (expander)), + g_object_ref (expander)); + g_print ("**** sas_expander ADDED %s\n", native_path); + if (emit_event) + { + const char *object_path; + object_path = expander_local_get_object_path (expander); + g_print ("**** sas_expander EMITTING ADDED for %s\n", expander->priv->native_path); + g_signal_emit (daemon, signals[EXPANDER_ADDED_SIGNAL], 0, object_path); + } + } + else + { + g_print ("**** sas_expander IGNORING ADD %s\n", native_path); } + } } /* ------------------------------ */ static void -block_device_add (Daemon *daemon, GUdevDevice *d, gboolean emit_event) -{ - Device *device; - const char *native_path; - - native_path = g_udev_device_get_sysfs_path (d); - device = g_hash_table_lookup (daemon->priv->map_native_path_to_device, native_path); - if (device != NULL) { - /* we already have the device; treat as change event */ - g_print ("**** TREATING ADD AS CHANGE %s\n", native_path); - _device_changed (daemon, d, FALSE); - } else { - g_print ("**** ADDING %s\n", native_path); - device = device_new (daemon, d); - - if (device != NULL) { - /* assert that the device is fully loaded with info */ - g_assert (device_local_get_device_file (device) != NULL); - g_assert (device_local_get_native_path (device) != NULL); - g_assert (device_local_get_object_path (device) != NULL); - g_assert (g_strcmp0 (native_path, device_local_get_native_path (device)) == 0); - - g_hash_table_insert (daemon->priv->map_dev_t_to_device, - GINT_TO_POINTER (device_local_get_dev (device)), - g_object_ref (device)); - g_hash_table_insert (daemon->priv->map_device_file_to_device, - g_strdup (device_local_get_device_file (device)), - g_object_ref (device)); - g_hash_table_insert (daemon->priv->map_native_path_to_device, - g_strdup (device_local_get_native_path (device)), - g_object_ref (device)); - g_hash_table_insert (daemon->priv->map_object_path_to_device, - g_strdup (device_local_get_object_path (device)), - g_object_ref (device)); - g_print ("**** ADDED %s\n", native_path); - if (emit_event) { - const char *object_path; - object_path = device_local_get_object_path (device); - g_print ("**** EMITTING ADDED for %s\n", device->priv->native_path); - g_signal_emit (daemon, signals[DEVICE_ADDED_SIGNAL], 0, object_path); - } - daemon_local_update_poller (daemon); - daemon_local_update_spindown (daemon); - } else { - g_print ("**** IGNORING ADD %s\n", native_path); - } +block_device_add (Daemon *daemon, + GUdevDevice *d, + gboolean emit_event) +{ + Device *device; + const char *native_path; + + native_path = g_udev_device_get_sysfs_path (d); + device = g_hash_table_lookup (daemon->priv->map_native_path_to_device, native_path); + if (device != NULL) + { + /* we already have the device; treat as change event */ + g_print ("**** TREATING ADD AS CHANGE %s\n", native_path); + _device_changed (daemon, d, FALSE); + } + else + { + g_print ("**** ADDING %s\n", native_path); + device = device_new (daemon, d); + + if (device != NULL) + { + /* assert that the device is fully loaded with info */ + g_assert (device_local_get_device_file (device) != NULL); + g_assert (device_local_get_native_path (device) != NULL); + g_assert (device_local_get_object_path (device) != NULL); + g_assert (g_strcmp0 (native_path, device_local_get_native_path (device)) == 0); + + g_hash_table_insert (daemon->priv->map_dev_t_to_device, + GINT_TO_POINTER (device_local_get_dev (device)), + g_object_ref (device)); + g_hash_table_insert (daemon->priv->map_device_file_to_device, + g_strdup (device_local_get_device_file (device)), + g_object_ref (device)); + g_hash_table_insert (daemon->priv->map_native_path_to_device, + g_strdup (device_local_get_native_path (device)), + g_object_ref (device)); + g_hash_table_insert (daemon->priv->map_object_path_to_device, + g_strdup (device_local_get_object_path (device)), + g_object_ref (device)); + g_print ("**** ADDED %s\n", native_path); + if (emit_event) + { + const char *object_path; + object_path = device_local_get_object_path (device); + g_print ("**** EMITTING ADDED for %s\n", device->priv->native_path); + g_signal_emit (daemon, signals[DEVICE_ADDED_SIGNAL], 0, object_path); + } + daemon_local_update_poller (daemon); + daemon_local_update_spindown (daemon); + } + else + { + g_print ("**** IGNORING ADD %s\n", native_path); } + } } static void -device_add (Daemon *daemon, GUdevDevice *d, gboolean emit_event) -{ - const gchar *subsystem; - - subsystem = g_udev_device_get_subsystem (d); - if (g_strcmp0 (subsystem, "block") == 0) - block_device_add (daemon, d, emit_event); - else if (g_strcmp0 (subsystem, "pci") == 0) - pci_device_add (daemon, d, emit_event); - else if (g_strcmp0 (subsystem, "scsi_host") == 0) - scsi_host_device_add (daemon, d, emit_event); - else if (g_strcmp0 (subsystem, "sas_phy") == 0) - sas_phy_device_add (daemon, d, emit_event); - else if (g_strcmp0 (subsystem, "sas_expander") == 0) - sas_expander_device_add (daemon, d, emit_event); - else - g_warning ("Unhandled add event from subsystem `%s'", subsystem); +device_add (Daemon *daemon, + GUdevDevice *d, + gboolean emit_event) +{ + const gchar *subsystem; + + subsystem = g_udev_device_get_subsystem (d); + if (g_strcmp0 (subsystem, "block") == 0) + block_device_add (daemon, d, emit_event); + else if (g_strcmp0 (subsystem, "pci") == 0) + pci_device_add (daemon, d, emit_event); + else if (g_strcmp0 (subsystem, "scsi_host") == 0) + scsi_host_device_add (daemon, d, emit_event); + else if (g_strcmp0 (subsystem, "sas_phy") == 0) + sas_phy_device_add (daemon, d, emit_event); + else if (g_strcmp0 (subsystem, "sas_expander") == 0) + sas_expander_device_add (daemon, d, emit_event); + else + g_warning ("Unhandled add event from subsystem `%s'", subsystem); } /* ---------------------------------------------------------------------------------------------------- */ static void -pci_device_remove (Daemon *daemon, GUdevDevice *d) +pci_device_remove (Daemon *daemon, + GUdevDevice *d) { - Adapter *adapter; - const char *native_path; + Adapter *adapter; + const char *native_path; - native_path = g_udev_device_get_sysfs_path (d); - adapter = g_hash_table_lookup (daemon->priv->map_native_path_to_adapter, native_path); - if (adapter == NULL) { - g_print ("**** pci IGNORING REMOVE %s\n", native_path); - } else { - g_print ("**** pci REMOVING %s\n", native_path); + native_path = g_udev_device_get_sysfs_path (d); + adapter = g_hash_table_lookup (daemon->priv->map_native_path_to_adapter, native_path); + if (adapter == NULL) + { + g_print ("**** pci IGNORING REMOVE %s\n", native_path); + } + else + { + g_print ("**** pci REMOVING %s\n", native_path); - g_warn_if_fail (g_strcmp0 (native_path, adapter->priv->native_path) == 0); + g_warn_if_fail (g_strcmp0 (native_path, adapter->priv->native_path) == 0); - g_hash_table_remove (daemon->priv->map_native_path_to_adapter, - adapter->priv->native_path); - g_warn_if_fail (g_hash_table_remove (daemon->priv->map_object_path_to_adapter, - adapter->priv->object_path)); + g_hash_table_remove (daemon->priv->map_native_path_to_adapter, adapter->priv->native_path); + g_warn_if_fail (g_hash_table_remove (daemon->priv->map_object_path_to_adapter, adapter->priv->object_path)); - g_print ("**** pci EMITTING REMOVED for %s\n", adapter->priv->native_path); - g_signal_emit (daemon, signals[ADAPTER_REMOVED_SIGNAL], 0, - adapter_local_get_object_path (adapter)); + g_print ("**** pci EMITTING REMOVED for %s\n", adapter->priv->native_path); + g_signal_emit (daemon, signals[ADAPTER_REMOVED_SIGNAL], 0, adapter_local_get_object_path (adapter)); - adapter_removed (adapter); + adapter_removed (adapter); - g_object_unref (adapter); - } + g_object_unref (adapter); + } } /* ------------------------------ */ static void -scsi_host_device_remove (Daemon *daemon, GUdevDevice *d) +scsi_host_device_remove (Daemon *daemon, + GUdevDevice *d) { - Port *port; - const char *native_path; + Port *port; + const char *native_path; - native_path = g_udev_device_get_sysfs_path (d); - port = g_hash_table_lookup (daemon->priv->map_native_path_to_port, native_path); - if (port == NULL) { - g_print ("**** scsi_host IGNORING REMOVE %s\n", native_path); - } else { - g_print ("**** scsi_host REMOVING %s\n", native_path); + native_path = g_udev_device_get_sysfs_path (d); + port = g_hash_table_lookup (daemon->priv->map_native_path_to_port, native_path); + if (port == NULL) + { + g_print ("**** scsi_host IGNORING REMOVE %s\n", native_path); + } + else + { + g_print ("**** scsi_host REMOVING %s\n", native_path); - g_warn_if_fail (g_strcmp0 (native_path, port->priv->native_path) == 0); + g_warn_if_fail (g_strcmp0 (native_path, port->priv->native_path) == 0); - g_hash_table_remove (daemon->priv->map_native_path_to_port, - port->priv->native_path); - g_warn_if_fail (g_hash_table_remove (daemon->priv->map_object_path_to_port, - port->priv->object_path)); + g_hash_table_remove (daemon->priv->map_native_path_to_port, port->priv->native_path); + g_warn_if_fail (g_hash_table_remove (daemon->priv->map_object_path_to_port, port->priv->object_path)); - g_print ("**** scsi_host EMITTING REMOVED for %s\n", port->priv->native_path); - g_signal_emit (daemon, signals[PORT_REMOVED_SIGNAL], 0, - port_local_get_object_path (port)); + g_print ("**** scsi_host EMITTING REMOVED for %s\n", port->priv->native_path); + g_signal_emit (daemon, signals[PORT_REMOVED_SIGNAL], 0, port_local_get_object_path (port)); - port_removed (port); + port_removed (port); - g_object_unref (port); - } + g_object_unref (port); + } } /* ------------------------------ */ static void -sas_phy_device_remove (Daemon *daemon, GUdevDevice *d) +sas_phy_device_remove (Daemon *daemon, + GUdevDevice *d) { - Port *port; - const char *native_path; + Port *port; + const char *native_path; - native_path = g_udev_device_get_sysfs_path (d); - port = g_hash_table_lookup (daemon->priv->map_native_path_to_port, native_path); - if (port == NULL) { - g_print ("**** sas_phy IGNORING REMOVE %s\n", native_path); - } else { - g_print ("**** sas_phy REMOVING %s\n", native_path); + native_path = g_udev_device_get_sysfs_path (d); + port = g_hash_table_lookup (daemon->priv->map_native_path_to_port, native_path); + if (port == NULL) + { + g_print ("**** sas_phy IGNORING REMOVE %s\n", native_path); + } + else + { + g_print ("**** sas_phy REMOVING %s\n", native_path); - g_warn_if_fail (g_strcmp0 (native_path, port->priv->native_path) == 0); + g_warn_if_fail (g_strcmp0 (native_path, port->priv->native_path) == 0); - g_hash_table_remove (daemon->priv->map_native_path_to_port, - port->priv->native_path); - g_warn_if_fail (g_hash_table_remove (daemon->priv->map_object_path_to_port, - port->priv->object_path)); + g_hash_table_remove (daemon->priv->map_native_path_to_port, port->priv->native_path); + g_warn_if_fail (g_hash_table_remove (daemon->priv->map_object_path_to_port, port->priv->object_path)); - g_print ("**** sas_phy EMITTING REMOVED for %s\n", port->priv->native_path); - g_signal_emit (daemon, signals[PORT_REMOVED_SIGNAL], 0, - port_local_get_object_path (port)); + g_print ("**** sas_phy EMITTING REMOVED for %s\n", port->priv->native_path); + g_signal_emit (daemon, signals[PORT_REMOVED_SIGNAL], 0, port_local_get_object_path (port)); - port_removed (port); + port_removed (port); - g_object_unref (port); - } + g_object_unref (port); + } } /* ------------------------------ */ static void -sas_expander_device_remove (Daemon *daemon, GUdevDevice *d) +sas_expander_device_remove (Daemon *daemon, + GUdevDevice *d) { - Expander *expander; - const char *native_path; + Expander *expander; + const char *native_path; - native_path = g_udev_device_get_sysfs_path (d); - expander = g_hash_table_lookup (daemon->priv->map_native_path_to_expander, native_path); - if (expander == NULL) { - g_print ("**** sas_expander IGNORING REMOVE %s\n", native_path); - } else { - g_print ("**** sas_expander REMOVING %s\n", native_path); + native_path = g_udev_device_get_sysfs_path (d); + expander = g_hash_table_lookup (daemon->priv->map_native_path_to_expander, native_path); + if (expander == NULL) + { + g_print ("**** sas_expander IGNORING REMOVE %s\n", native_path); + } + else + { + g_print ("**** sas_expander REMOVING %s\n", native_path); - g_warn_if_fail (g_strcmp0 (native_path, expander->priv->native_path) == 0); + g_warn_if_fail (g_strcmp0 (native_path, expander->priv->native_path) == 0); - g_hash_table_remove (daemon->priv->map_native_path_to_expander, - expander->priv->native_path); - g_warn_if_fail (g_hash_table_remove (daemon->priv->map_object_path_to_expander, - expander->priv->object_path)); + g_hash_table_remove (daemon->priv->map_native_path_to_expander, expander->priv->native_path); + g_warn_if_fail (g_hash_table_remove (daemon->priv->map_object_path_to_expander, expander->priv->object_path)); - g_print ("**** sas_expander EMITTING REMOVED for %s\n", expander->priv->native_path); - g_signal_emit (daemon, signals[EXPANDER_REMOVED_SIGNAL], 0, - expander_local_get_object_path (expander)); + g_print ("**** sas_expander EMITTING REMOVED for %s\n", expander->priv->native_path); + g_signal_emit (daemon, signals[EXPANDER_REMOVED_SIGNAL], 0, expander_local_get_object_path (expander)); - expander_removed (expander); + expander_removed (expander); - g_object_unref (expander); - } + g_object_unref (expander); + } } /* ------------------------------ */ static void -block_device_remove (Daemon *daemon, GUdevDevice *d) -{ - Device *device; - const char *native_path; - - native_path = g_udev_device_get_sysfs_path (d); - device = g_hash_table_lookup (daemon->priv->map_native_path_to_device, native_path); - if (device == NULL) { - g_print ("**** IGNORING REMOVE %s\n", native_path); - } else { - g_print ("**** REMOVING %s\n", native_path); - - g_warn_if_fail (g_strcmp0 (native_path, device->priv->native_path) == 0); - - g_hash_table_remove (daemon->priv->map_native_path_to_device, - device->priv->native_path); - /* Note that the created device file may actually disappear under certain - * circumstances such as a 'change' event. In this case we discard the device - * in update_info() and then we end up here. - * - * See https://bugs.freedesktop.org/show_bug.cgi?id=24264 for details. - */ - if (device->priv->device_file != NULL) { - g_hash_table_remove (daemon->priv->map_device_file_to_device, - device->priv->device_file); - } - g_warn_if_fail (g_hash_table_remove (daemon->priv->map_object_path_to_device, - device->priv->object_path)); - g_warn_if_fail (g_hash_table_remove (daemon->priv->map_dev_t_to_device, - GINT_TO_POINTER (device->priv->dev))); - - g_print ("**** EMITTING REMOVED for %s\n", device->priv->native_path); - g_signal_emit (daemon, signals[DEVICE_REMOVED_SIGNAL], 0, - device_local_get_object_path (device)); - - device_removed (device); - - g_object_unref (device); - - daemon_local_update_poller (daemon); - daemon_local_update_spindown (daemon); +block_device_remove (Daemon *daemon, + GUdevDevice *d) +{ + Device *device; + const char *native_path; + + native_path = g_udev_device_get_sysfs_path (d); + device = g_hash_table_lookup (daemon->priv->map_native_path_to_device, native_path); + if (device == NULL) + { + g_print ("**** IGNORING REMOVE %s\n", native_path); + } + else + { + g_print ("**** REMOVING %s\n", native_path); + + g_warn_if_fail (g_strcmp0 (native_path, device->priv->native_path) == 0); + + g_hash_table_remove (daemon->priv->map_native_path_to_device, device->priv->native_path); + /* Note that the created device file may actually disappear under certain + * circumstances such as a 'change' event. In this case we discard the device + * in update_info() and then we end up here. + * + * See https://bugs.freedesktop.org/show_bug.cgi?id=24264 for details. + */ + if (device->priv->device_file != NULL) + { + g_hash_table_remove (daemon->priv->map_device_file_to_device, device->priv->device_file); } + g_warn_if_fail (g_hash_table_remove (daemon->priv->map_object_path_to_device, device->priv->object_path)); + g_warn_if_fail (g_hash_table_remove (daemon->priv->map_dev_t_to_device, GINT_TO_POINTER (device->priv->dev))); + + g_print ("**** EMITTING REMOVED for %s\n", device->priv->native_path); + g_signal_emit (daemon, signals[DEVICE_REMOVED_SIGNAL], 0, device_local_get_object_path (device)); + + device_removed (device); + + g_object_unref (device); + + daemon_local_update_poller (daemon); + daemon_local_update_spindown (daemon); + } } static void -device_remove (Daemon *daemon, GUdevDevice *d) -{ - const gchar *subsystem; - - subsystem = g_udev_device_get_subsystem (d); - if (g_strcmp0 (subsystem, "block") == 0) - block_device_remove (daemon, d); - else if (g_strcmp0 (subsystem, "pci") == 0) - pci_device_remove (daemon, d); - else if (g_strcmp0 (subsystem, "scsi_host") == 0) - scsi_host_device_remove (daemon, d); - else if (g_strcmp0 (subsystem, "sas_phy") == 0) - sas_phy_device_remove (daemon, d); - else if (g_strcmp0 (subsystem, "sas_expander") == 0) - sas_expander_device_remove (daemon, d); - else - g_warning ("Unhandled remove event from subsystem `%s'", subsystem); +device_remove (Daemon *daemon, + GUdevDevice *d) +{ + const gchar *subsystem; + + subsystem = g_udev_device_get_subsystem (d); + if (g_strcmp0 (subsystem, "block") == 0) + block_device_remove (daemon, d); + else if (g_strcmp0 (subsystem, "pci") == 0) + pci_device_remove (daemon, d); + else if (g_strcmp0 (subsystem, "scsi_host") == 0) + scsi_host_device_remove (daemon, d); + else if (g_strcmp0 (subsystem, "sas_phy") == 0) + sas_phy_device_remove (daemon, d); + else if (g_strcmp0 (subsystem, "sas_expander") == 0) + sas_expander_device_remove (daemon, d); + else + g_warning ("Unhandled remove event from subsystem `%s'", subsystem); } /* ---------------------------------------------------------------------------------------------------- */ static void -on_uevent (GUdevClient *client, - const char *action, - GUdevDevice *device, - gpointer user_data) -{ - Daemon *daemon = DAEMON (user_data); - - if (strcmp (action, "add") == 0) { - device_add (daemon, device, TRUE); - } else if (strcmp (action, "remove") == 0) { - device_remove (daemon, device); - } else if (strcmp (action, "change") == 0) { - _device_changed (daemon, device, FALSE); - } else { - g_print ("*** NOTE: unhandled action '%s' on %s\n", action, g_udev_device_get_sysfs_path (device)); - } +on_uevent (GUdevClient *client, + const char *action, + GUdevDevice *device, + gpointer user_data) +{ + Daemon *daemon = DAEMON (user_data); + + if (strcmp (action, "add") == 0) + { + device_add (daemon, device, TRUE); + } + else if (strcmp (action, "remove") == 0) + { + device_remove (daemon, device); + } + else if (strcmp (action, "change") == 0) + { + _device_changed (daemon, device, FALSE); + } + else + { + g_print ("*** NOTE: unhandled action '%s' on %s\n", action, g_udev_device_get_sysfs_path (device)); + } } Device * -daemon_local_find_by_dev (Daemon *daemon, dev_t dev) +daemon_local_find_by_dev (Daemon *daemon, + dev_t dev) { - return g_hash_table_lookup (daemon->priv->map_dev_t_to_device, GINT_TO_POINTER (dev)); + return g_hash_table_lookup (daemon->priv->map_dev_t_to_device, GINT_TO_POINTER (dev)); } Device * -daemon_local_find_by_device_file (Daemon *daemon, const char *device_file) +daemon_local_find_by_device_file (Daemon *daemon, + const char *device_file) { - return g_hash_table_lookup (daemon->priv->map_device_file_to_device, device_file); + return g_hash_table_lookup (daemon->priv->map_device_file_to_device, device_file); } Device * -daemon_local_find_by_native_path (Daemon *daemon, const char *native_path) +daemon_local_find_by_native_path (Daemon *daemon, + const char *native_path) { - return g_hash_table_lookup (daemon->priv->map_native_path_to_device, native_path); + return g_hash_table_lookup (daemon->priv->map_native_path_to_device, native_path); } Device * daemon_local_find_by_object_path (Daemon *daemon, - const char *object_path) + const char *object_path) { - return g_hash_table_lookup (daemon->priv->map_object_path_to_device, object_path); + return g_hash_table_lookup (daemon->priv->map_object_path_to_device, object_path); } GList * daemon_local_get_all_devices (Daemon *daemon) { - return g_hash_table_get_values (daemon->priv->map_native_path_to_device); + return g_hash_table_get_values (daemon->priv->map_native_path_to_device); } static void mount_removed (MountMonitor *monitor, - Mount *mount, - gpointer user_data) + Mount *mount, + gpointer user_data) { - Daemon *daemon = DAEMON (user_data); - Device *device; + Daemon *daemon = DAEMON (user_data); + Device *device; - device = g_hash_table_lookup (daemon->priv->map_dev_t_to_device, - GINT_TO_POINTER (mount_get_dev (mount))); - if (device != NULL) { - g_print ("**** UNMOUNTED %s\n", device->priv->native_path); - daemon_local_synthesize_changed (daemon, device); - } + device = g_hash_table_lookup (daemon->priv->map_dev_t_to_device, GINT_TO_POINTER (mount_get_dev (mount))); + if (device != NULL) + { + g_print ("**** UNMOUNTED %s\n", device->priv->native_path); + daemon_local_synthesize_changed (daemon, device); + } } static void mount_added (MountMonitor *monitor, - Mount *mount, - gpointer user_data) + Mount *mount, + gpointer user_data) { - Daemon *daemon = DAEMON (user_data); - Device *device; + Daemon *daemon = DAEMON (user_data); + Device *device; - device = g_hash_table_lookup (daemon->priv->map_dev_t_to_device, - GINT_TO_POINTER (mount_get_dev (mount))); - if (device != NULL) { - g_print ("**** MOUNTED %s\n", device->priv->native_path); - daemon_local_synthesize_changed (daemon, device); - } + device = g_hash_table_lookup (daemon->priv->map_dev_t_to_device, GINT_TO_POINTER (mount_get_dev (mount))); + if (device != NULL) + { + g_print ("**** MOUNTED %s\n", device->priv->native_path); + daemon_local_synthesize_changed (daemon, device); + } } static gboolean -mdstat_changed_event (GIOChannel *channel, GIOCondition cond, gpointer user_data) -{ - Daemon *daemon = DAEMON (user_data); - GHashTableIter iter; - char *str; - gsize len; - Device *device; - char *native_path; - GPtrArray *a; - int n; - - if (cond & ~G_IO_PRI) - goto out; - - if (g_io_channel_seek (channel, 0, G_SEEK_SET) != G_IO_ERROR_NONE) { - g_warning ("Cannot seek in /proc/mdstat"); - goto out; - } - - g_io_channel_read_to_end (channel, &str, &len, NULL); - - /* synthesize this as a change event on _all_ md devices; need to be careful; the change - * event might remove the device and thus change the hash table (e.g. invalidate our iterator) - */ - a = g_ptr_array_new (); - g_hash_table_iter_init (&iter, daemon->priv->map_native_path_to_device); - while (g_hash_table_iter_next (&iter, (gpointer *) &native_path, (gpointer *) &device)) { - if (device->priv->device_is_linux_md) { - g_ptr_array_add (a, g_object_ref (device->priv->d)); - } +mdstat_changed_event (GIOChannel *channel, + GIOCondition cond, + gpointer user_data) +{ + Daemon *daemon = DAEMON (user_data); + GHashTableIter iter; + char *str; + gsize len; + Device *device; + char *native_path; + GPtrArray *a; + int n; + + if (cond & ~G_IO_PRI) + goto out; + + if (g_io_channel_seek (channel, 0, G_SEEK_SET) != G_IO_ERROR_NONE) + { + g_warning ("Cannot seek in /proc/mdstat"); + goto out; + } + + g_io_channel_read_to_end (channel, &str, &len, NULL); + + /* synthesize this as a change event on _all_ md devices; need to be careful; the change + * event might remove the device and thus change the hash table (e.g. invalidate our iterator) + */ + a = g_ptr_array_new (); + g_hash_table_iter_init (&iter, daemon->priv->map_native_path_to_device); + while (g_hash_table_iter_next (&iter, (gpointer *) &native_path, (gpointer *) &device)) + { + if (device->priv->device_is_linux_md) + { + g_ptr_array_add (a, g_object_ref (device->priv->d)); } + } - for (n = 0; n < (int) a->len; n++) { - GUdevDevice *d = a->pdata[n]; - g_debug ("using change on /proc/mdstat to trigger change event on %s", native_path); - _device_changed (daemon, d, FALSE); - g_object_unref (d); - } + for (n = 0; n < (int) a->len; n++) + { + GUdevDevice *d = a->pdata[n]; + g_debug ("using change on /proc/mdstat to trigger change event on %s", native_path); + _device_changed (daemon, d, FALSE); + g_object_unref (d); + } - g_ptr_array_free (a, TRUE); + g_ptr_array_free (a, TRUE); -out: - return TRUE; + out: + return TRUE; } static gboolean refresh_ata_smart_data (Daemon *daemon) { - Device *device; - const char *native_path; - GHashTableIter iter; + Device *device; + const char *native_path; + GHashTableIter iter; - g_hash_table_iter_init (&iter, daemon->priv->map_native_path_to_device); - while (g_hash_table_iter_next (&iter, (gpointer *) &native_path, (gpointer *) &device)) { - if (device->priv->drive_ata_smart_is_available) { - char *options[] = {"nowakeup", NULL}; + g_hash_table_iter_init (&iter, daemon->priv->map_native_path_to_device); + while (g_hash_table_iter_next (&iter, (gpointer *) &native_path, (gpointer *) &device)) + { + if (device->priv->drive_ata_smart_is_available) + { + char *options[] = + { "nowakeup", NULL }; - g_print ("**** Refreshing ATA SMART data for %s\n", native_path); + g_print ("**** Refreshing ATA SMART data for %s\n", native_path); - device_drive_ata_smart_refresh_data (device, options, NULL); - } + device_drive_ata_smart_refresh_data (device, options, NULL); } + } + /* update in another N seconds */ + daemon->priv->ata_smart_refresh_timer_id = g_timeout_add_seconds (ATA_SMART_REFRESH_INTERVAL_SECONDS, + (GSourceFunc) refresh_ata_smart_data, + daemon); - /* update in another N seconds */ - daemon->priv->ata_smart_refresh_timer_id = g_timeout_add_seconds (ATA_SMART_REFRESH_INTERVAL_SECONDS, - (GSourceFunc) refresh_ata_smart_data, - daemon); - - return FALSE; + return FALSE; } - static gboolean register_disks_daemon (Daemon *daemon) { - DBusConnection *connection; - DBusError dbus_error; - GError *error = NULL; - const char *subsystems[] = {"block", /* Disks and partitions */ - "pci", /* Storage adapters */ - "scsi_host", /* ATA ports are represented by scsi_host */ - "sas_phy", /* SAS PHYs are represented by sas_phy */ - "sas_expander", /* SAS Expanders */ - NULL}; - - daemon->priv->authority = polkit_authority_get (); - - error = NULL; - daemon->priv->system_bus_connection = dbus_g_bus_get (DBUS_BUS_SYSTEM, &error); - if (daemon->priv->system_bus_connection == NULL) { - if (error != NULL) { - g_critical ("error getting system bus: %s", error->message); - g_error_free (error); - } - goto error; - } - connection = dbus_g_connection_get_connection (daemon->priv->system_bus_connection); - - dbus_g_connection_register_g_object (daemon->priv->system_bus_connection, "/org/freedesktop/UDisks", - G_OBJECT (daemon)); - - daemon->priv->system_bus_proxy = dbus_g_proxy_new_for_name (daemon->priv->system_bus_connection, - DBUS_SERVICE_DBUS, - DBUS_PATH_DBUS, - DBUS_INTERFACE_DBUS); - dbus_error_init (&dbus_error); - - /* need to listen to NameOwnerChanged */ - dbus_bus_add_match (connection, - "type='signal'" - ",interface='"DBUS_INTERFACE_DBUS"'" - ",sender='"DBUS_SERVICE_DBUS"'" - ",member='NameOwnerChanged'", - &dbus_error); - - if (dbus_error_is_set (&dbus_error)) { - g_warning ("Cannot add match rule: %s: %s", dbus_error.name, dbus_error.message); - dbus_error_free (&dbus_error); - goto error; - } - - if (!dbus_connection_add_filter (connection, - _filter, - daemon, - NULL)) { - g_warning ("Cannot add D-Bus filter: %s: %s", dbus_error.name, dbus_error.message); - goto error; - } - - /* listen to /proc/mdstat for md changes - * - * Linux 2.6.19 and onwards throws a POLLPRI event for every change - * - * TODO: Some people might have md as a module so if it's not there - * we need to set up a watch for it to appear when loaded and - * then poll it. Sigh. - */ - daemon->priv->mdstat_channel = g_io_channel_new_file ("/proc/mdstat", "r", &error); - if (daemon->priv->mdstat_channel != NULL) { - g_io_add_watch (daemon->priv->mdstat_channel, G_IO_PRI, mdstat_changed_event, daemon); - } else { - g_warning ("No /proc/mdstat file: %s", error->message); - g_error_free (error); - error = NULL; - } - - /* connect to udev */ - daemon->priv->gudev_client = g_udev_client_new (subsystems); - g_signal_connect (daemon->priv->gudev_client, - "uevent", - G_CALLBACK (on_uevent), - daemon); - - daemon->priv->mount_monitor = mount_monitor_new (); - g_signal_connect (daemon->priv->mount_monitor, "mount-added", (GCallback) mount_added, daemon); - g_signal_connect (daemon->priv->mount_monitor, "mount-removed", (GCallback) mount_removed, daemon); - - return TRUE; -error: - return FALSE; + DBusConnection *connection; + DBusError dbus_error; + GError *error = NULL; + const char *subsystems[] = + { "block", /* Disks and partitions */ + "pci", /* Storage adapters */ + "scsi_host", /* ATA ports are represented by scsi_host */ + "sas_phy", /* SAS PHYs are represented by sas_phy */ + "sas_expander", /* SAS Expanders */ + NULL }; + + daemon->priv->authority = polkit_authority_get (); + + error = NULL; + daemon->priv->system_bus_connection = dbus_g_bus_get (DBUS_BUS_SYSTEM, &error); + if (daemon->priv->system_bus_connection == NULL) + { + if (error != NULL) + { + g_critical ("error getting system bus: %s", error->message); + g_error_free (error); + } + goto error; + } + connection = dbus_g_connection_get_connection (daemon->priv->system_bus_connection); + + dbus_g_connection_register_g_object (daemon->priv->system_bus_connection, + "/org/freedesktop/UDisks", + G_OBJECT (daemon)); + + daemon->priv->system_bus_proxy = dbus_g_proxy_new_for_name (daemon->priv->system_bus_connection, + DBUS_SERVICE_DBUS, + DBUS_PATH_DBUS, + DBUS_INTERFACE_DBUS); + dbus_error_init (&dbus_error); + + /* need to listen to NameOwnerChanged */ + dbus_bus_add_match (connection, + "type='signal'" + ",interface='"DBUS_INTERFACE_DBUS"'" + ",sender='"DBUS_SERVICE_DBUS"'" + ",member='NameOwnerChanged'", + &dbus_error); + + if (dbus_error_is_set (&dbus_error)) + { + g_warning ("Cannot add match rule: %s: %s", dbus_error.name, dbus_error.message); + dbus_error_free (&dbus_error); + goto error; + } + + if (!dbus_connection_add_filter (connection, _filter, daemon, NULL)) + { + g_warning ("Cannot add D-Bus filter: %s: %s", dbus_error.name, dbus_error.message); + goto error; + } + + /* listen to /proc/mdstat for md changes + * + * Linux 2.6.19 and onwards throws a POLLPRI event for every change + * + * TODO: Some people might have md as a module so if it's not there + * we need to set up a watch for it to appear when loaded and + * then poll it. Sigh. + */ + daemon->priv->mdstat_channel = g_io_channel_new_file ("/proc/mdstat", "r", &error); + if (daemon->priv->mdstat_channel != NULL) + { + g_io_add_watch (daemon->priv->mdstat_channel, G_IO_PRI, mdstat_changed_event, daemon); + } + else + { + g_warning ("No /proc/mdstat file: %s", error->message); + g_error_free (error); + error = NULL; + } + + /* connect to udev */ + daemon->priv->gudev_client = g_udev_client_new (subsystems); + g_signal_connect (daemon->priv->gudev_client, "uevent", G_CALLBACK (on_uevent), daemon); + + daemon->priv->mount_monitor = mount_monitor_new (); + g_signal_connect (daemon->priv->mount_monitor, "mount-added", (GCallback) mount_added, daemon); + g_signal_connect (daemon->priv->mount_monitor, "mount-removed", (GCallback) mount_removed, daemon); + + return TRUE; + error: + return FALSE; } - Daemon * daemon_new (void) { - Daemon *daemon; - GList *devices; - GList *l; - Device *device; - GHashTableIter device_iter; - - daemon = DAEMON (g_object_new (TYPE_DAEMON, NULL)); - - if (!register_disks_daemon (DAEMON (daemon))) { - g_object_unref (daemon); - goto error; - } - - /* process storage adapters */ - devices = g_udev_client_query_by_subsystem (daemon->priv->gudev_client, "pci"); - for (l = devices; l != NULL; l = l->next) { - GUdevDevice *device = l->data; - device_add (daemon, device, FALSE); - } - g_list_foreach (devices, (GFunc) g_object_unref, NULL); - g_list_free (devices); - - /* process ATA ports */ - devices = g_udev_client_query_by_subsystem (daemon->priv->gudev_client, "scsi_host"); - for (l = devices; l != NULL; l = l->next) { - GUdevDevice *device = l->data; - device_add (daemon, device, FALSE); - } - g_list_foreach (devices, (GFunc) g_object_unref, NULL); - g_list_free (devices); - - /* process SAS Expanders */ - devices = g_udev_client_query_by_subsystem (daemon->priv->gudev_client, "sas_expander"); - for (l = devices; l != NULL; l = l->next) { - GUdevDevice *device = l->data; - device_add (daemon, device, FALSE); - } - g_list_foreach (devices, (GFunc) g_object_unref, NULL); - g_list_free (devices); - - /* process SAS PHYs */ - devices = g_udev_client_query_by_subsystem (daemon->priv->gudev_client, "sas_phy"); - for (l = devices; l != NULL; l = l->next) { - GUdevDevice *device = l->data; - device_add (daemon, device, FALSE); - } - g_list_foreach (devices, (GFunc) g_object_unref, NULL); - g_list_free (devices); - - /* reprocess SAS expanders to get the right Ports associated - * - * TODO: ideally there would be a way to properly traverse a whole subtree using gudev - * so we could visit everything in the proper order. - */ - devices = g_udev_client_query_by_subsystem (daemon->priv->gudev_client, "sas_expander"); - for (l = devices; l != NULL; l = l->next) { - GUdevDevice *device = l->data; - device_add (daemon, device, FALSE); - } - g_list_foreach (devices, (GFunc) g_object_unref, NULL); - g_list_free (devices); - - /* process block devices (disks and partitions) */ - devices = g_udev_client_query_by_subsystem (daemon->priv->gudev_client, "block"); - for (l = devices; l != NULL; l = l->next) { - GUdevDevice *device = l->data; - device_add (daemon, device, FALSE); - } - g_list_foreach (devices, (GFunc) g_object_unref, NULL); - g_list_free (devices); - - /* now refresh data for all devices just added to get slave/holder relationships - * properly initialized - */ - g_hash_table_iter_init (&device_iter, daemon->priv->map_object_path_to_device); - while (g_hash_table_iter_next (&device_iter, NULL, (gpointer) &device)) { - daemon_local_synthesize_changed (daemon, device); - } - - /* clean stale directories in /media as well as stale - * entries in /var/lib/udisks/mtab - */ - l = g_hash_table_get_values (daemon->priv->map_native_path_to_device); - mount_file_clean_stale (l); - g_list_free (l); - - /* set up timer for refreshing ATA SMART data - we don't want to refresh immediately because - * when adding a device we also do this... - */ - daemon->priv->ata_smart_refresh_timer_id = g_timeout_add_seconds (ATA_SMART_REFRESH_INTERVAL_SECONDS, - (GSourceFunc) refresh_ata_smart_data, - daemon); - - return daemon; + Daemon *daemon; + GList *devices; + GList *l; + Device *device; + GHashTableIter device_iter; + + daemon = DAEMON (g_object_new (TYPE_DAEMON, NULL)); + + if (!register_disks_daemon (DAEMON (daemon))) + { + g_object_unref (daemon); + goto error; + } + + /* process storage adapters */ + devices = g_udev_client_query_by_subsystem (daemon->priv->gudev_client, "pci"); + for (l = devices; l != NULL; l = l->next) + { + GUdevDevice *device = l->data; + device_add (daemon, device, FALSE); + } + g_list_foreach (devices, (GFunc) g_object_unref, NULL); + g_list_free (devices); + + /* process ATA ports */ + devices = g_udev_client_query_by_subsystem (daemon->priv->gudev_client, "scsi_host"); + for (l = devices; l != NULL; l = l->next) + { + GUdevDevice *device = l->data; + device_add (daemon, device, FALSE); + } + g_list_foreach (devices, (GFunc) g_object_unref, NULL); + g_list_free (devices); + + /* process SAS Expanders */ + devices = g_udev_client_query_by_subsystem (daemon->priv->gudev_client, "sas_expander"); + for (l = devices; l != NULL; l = l->next) + { + GUdevDevice *device = l->data; + device_add (daemon, device, FALSE); + } + g_list_foreach (devices, (GFunc) g_object_unref, NULL); + g_list_free (devices); + + /* process SAS PHYs */ + devices = g_udev_client_query_by_subsystem (daemon->priv->gudev_client, "sas_phy"); + for (l = devices; l != NULL; l = l->next) + { + GUdevDevice *device = l->data; + device_add (daemon, device, FALSE); + } + g_list_foreach (devices, (GFunc) g_object_unref, NULL); + g_list_free (devices); + + /* reprocess SAS expanders to get the right Ports associated + * + * TODO: ideally there would be a way to properly traverse a whole subtree using gudev + * so we could visit everything in the proper order. + */ + devices = g_udev_client_query_by_subsystem (daemon->priv->gudev_client, "sas_expander"); + for (l = devices; l != NULL; l = l->next) + { + GUdevDevice *device = l->data; + device_add (daemon, device, FALSE); + } + g_list_foreach (devices, (GFunc) g_object_unref, NULL); + g_list_free (devices); + + /* process block devices (disks and partitions) */ + devices = g_udev_client_query_by_subsystem (daemon->priv->gudev_client, "block"); + for (l = devices; l != NULL; l = l->next) + { + GUdevDevice *device = l->data; + device_add (daemon, device, FALSE); + } + g_list_foreach (devices, (GFunc) g_object_unref, NULL); + g_list_free (devices); + + /* now refresh data for all devices just added to get slave/holder relationships + * properly initialized + */ + g_hash_table_iter_init (&device_iter, daemon->priv->map_object_path_to_device); + while (g_hash_table_iter_next (&device_iter, NULL, (gpointer) & device)) + { + daemon_local_synthesize_changed (daemon, device); + } + + /* clean stale directories in /media as well as stale + * entries in /var/lib/udisks/mtab + */ + l = g_hash_table_get_values (daemon->priv->map_native_path_to_device); + mount_file_clean_stale (l); + g_list_free (l); + + /* set up timer for refreshing ATA SMART data - we don't want to refresh immediately because + * when adding a device we also do this... + */ + daemon->priv->ata_smart_refresh_timer_id = g_timeout_add_seconds (ATA_SMART_REFRESH_INTERVAL_SECONDS, + (GSourceFunc) refresh_ata_smart_data, + daemon); + + return daemon; error: - return NULL; + return NULL; } MountMonitor * daemon_local_get_mount_monitor (Daemon *daemon) { - return daemon->priv->mount_monitor; + return daemon->priv->mount_monitor; } /*--------------------------------------------------------------------------------------------------------------*/ static gboolean -throw_error (DBusGMethodInvocation *context, int error_code, const char *format, ...) -{ - GError *error; - va_list args; - char *message; - - va_start (args, format); - message = g_strdup_vprintf (format, args); - va_end (args); - - if (context != NULL) { - error = g_error_new (ERROR, - error_code, - "%s", message); - dbus_g_method_return_error (context, error); - g_error_free (error); - } else { - /* error from a daemon-internal method call */ - g_warning ("%s", message); - } - g_free (message); - return TRUE; +throw_error (DBusGMethodInvocation *context, + int error_code, + const char *format, + ...) +{ + GError *error; + va_list args; + char *message; + + va_start (args, format); + message = g_strdup_vprintf (format, args); + va_end (args); + + if (context != NULL) + { + error = g_error_new (ERROR, error_code, "%s", message); + dbus_g_method_return_error (context, error); + g_error_free (error); + } + else + { + /* error from a daemon-internal method call */ + g_warning ("%s", message); + } + g_free (message); + return TRUE; } /*--------------------------------------------------------------------------------------------------------------*/ gboolean -daemon_local_get_uid (Daemon *daemon, - uid_t *out_uid, - DBusGMethodInvocation *context) -{ - gchar *sender; - DBusError dbus_error; - DBusConnection *connection; - - /* context can be NULL for things called by the daemon itself e.g. ATA SMART refresh */ - if (context == NULL) { - *out_uid = 0; - goto out; - } - - /* TODO: right now this is synchronous and slow; when we switch to a better D-Bus - * binding a'la EggDBus there will be a utility class (with caching) where we - * can get this from - */ - - sender = dbus_g_method_get_sender (context); - connection = dbus_g_connection_get_connection (daemon->priv->system_bus_connection); - dbus_error_init (&dbus_error); - *out_uid = dbus_bus_get_unix_user (connection, - sender, - &dbus_error); - if (dbus_error_is_set (&dbus_error)) { - *out_uid = 0; - g_warning ("Cannot get uid for sender %s: %s: %s", - sender, - dbus_error.name, - dbus_error.message); - dbus_error_free (&dbus_error); - } - g_free (sender); +daemon_local_get_uid (Daemon *daemon, + uid_t *out_uid, + DBusGMethodInvocation *context) +{ + gchar *sender; + DBusError dbus_error; + DBusConnection *connection; + + /* context can be NULL for things called by the daemon itself e.g. ATA SMART refresh */ + if (context == NULL) + { + *out_uid = 0; + goto out; + } + + /* TODO: right now this is synchronous and slow; when we switch to a better D-Bus + * binding a'la EggDBus there will be a utility class (with caching) where we + * can get this from + */ + + sender = dbus_g_method_get_sender (context); + connection = dbus_g_connection_get_connection (daemon->priv->system_bus_connection); + dbus_error_init (&dbus_error); + *out_uid = dbus_bus_get_unix_user (connection, sender, &dbus_error); + if (dbus_error_is_set (&dbus_error)) + { + *out_uid = 0; + g_warning ("Cannot get uid for sender %s: %s: %s", sender, dbus_error.name, dbus_error.message); + dbus_error_free (&dbus_error); + } + g_free (sender); out: - return TRUE; + return TRUE; } /*--------------------------------------------------------------------------------------------------------------*/ @@ -1958,289 +2015,273 @@ daemon_local_get_uid (Daemon *daemon, void daemon_local_update_poller (Daemon *daemon) { - GHashTableIter hash_iter; - Device *device; - GList *devices_to_poll; + GHashTableIter hash_iter; + Device *device; + GList *devices_to_poll; - devices_to_poll = NULL; + devices_to_poll = NULL; - g_hash_table_iter_init (&hash_iter, daemon->priv->map_object_path_to_device); - while (g_hash_table_iter_next (&hash_iter, NULL, (gpointer) &device)) { - if (device->priv->device_is_media_change_detected && - device->priv->device_is_media_change_detection_polling) - devices_to_poll = g_list_prepend (devices_to_poll, device); - } + g_hash_table_iter_init (&hash_iter, daemon->priv->map_object_path_to_device); + while (g_hash_table_iter_next (&hash_iter, NULL, (gpointer) & device)) + { + if (device->priv->device_is_media_change_detected && device->priv->device_is_media_change_detection_polling) + devices_to_poll = g_list_prepend (devices_to_poll, device); + } - poller_set_devices (devices_to_poll); + poller_set_devices (devices_to_poll); - g_list_free (devices_to_poll); + g_list_free (devices_to_poll); } /*--------------------------------------------------------------------------------------------------------------*/ typedef struct { - gchar *action_id; - CheckAuthCallback check_auth_callback; - DBusGMethodInvocation *context; - Daemon *daemon; - Device *device; + gchar *action_id; + CheckAuthCallback check_auth_callback; + DBusGMethodInvocation *context; + Daemon *daemon; + Device *device; - GCancellable *cancellable; - guint num_user_data; - gpointer *user_data_elements; - GDestroyNotify *user_data_notifiers; + GCancellable *cancellable; + guint num_user_data; + gpointer *user_data_elements; + GDestroyNotify *user_data_notifiers; - Inhibitor *caller; + Inhibitor *caller; } CheckAuthData; /* invoked when device is removed during authorization check */ static void -lca_device_went_away (gpointer user_data, GObject *where_the_object_was) +lca_device_went_away (gpointer user_data, + GObject *where_the_object_was) { - CheckAuthData *data = user_data; + CheckAuthData *data = user_data; - g_object_weak_unref (G_OBJECT (data->device), lca_device_went_away, data); - data->device = NULL; + g_object_weak_unref (G_OBJECT (data->device), lca_device_went_away, data); + data->device = NULL; - /* this will trigger lca_check_authorization_callback() */ - g_cancellable_cancel (data->cancellable); + /* this will trigger lca_check_authorization_callback() */ + g_cancellable_cancel (data->cancellable); } /* invoked when caller disconnects during authorization check */ static void lca_caller_disconnected_cb (Inhibitor *inhibitor, - gpointer user_data) + gpointer user_data) { - CheckAuthData *data = user_data; + CheckAuthData *data = user_data; - /* this will trigger lca_check_authorization_callback() */ - g_cancellable_cancel (data->cancellable); + /* this will trigger lca_check_authorization_callback() */ + g_cancellable_cancel (data->cancellable); } static void check_auth_data_free (CheckAuthData *data) { - guint n; - - g_free (data->action_id); - g_object_unref (data->daemon); - if (data->device != NULL) - g_object_weak_unref (G_OBJECT (data->device), lca_device_went_away, data); - g_object_unref (data->cancellable); - for (n = 0; n < data->num_user_data; n++) { - if (data->user_data_notifiers[n] != NULL) - data->user_data_notifiers[n] (data->user_data_elements[n]); - } - g_free (data->user_data_elements); - g_free (data->user_data_notifiers); - if (data->caller != NULL) - g_object_unref (data->caller); - g_free (data); + guint n; + + g_free (data->action_id); + g_object_unref (data->daemon); + if (data->device != NULL) + g_object_weak_unref (G_OBJECT (data->device), lca_device_went_away, data); + g_object_unref (data->cancellable); + for (n = 0; n < data->num_user_data; n++) + { + if (data->user_data_notifiers[n] != NULL) + data->user_data_notifiers[n] (data->user_data_elements[n]); + } + g_free (data->user_data_elements); + g_free (data->user_data_notifiers); + if (data->caller != NULL) + g_object_unref (data->caller); + g_free (data); } static void lca_check_authorization_callback (PolkitAuthority *authority, - GAsyncResult *res, - gpointer user_data) -{ - CheckAuthData *data = user_data; - PolkitAuthorizationResult *result; - GError *error; - gboolean is_authorized; - - is_authorized = FALSE; - - error = NULL; - result = polkit_authority_check_authorization_finish (authority, - res, - &error); - if (error != NULL) { - throw_error (data->context, - ERROR_PERMISSION_DENIED, - "Not Authorized: %s", error->message); - g_error_free (error); - } else { - if (polkit_authorization_result_get_is_authorized (result)) { - is_authorized = TRUE; - } else if (polkit_authorization_result_get_is_challenge (result)) { - throw_error (data->context, - ERROR_PERMISSION_DENIED, - "Authentication is required"); - } else { - throw_error (data->context, - ERROR_PERMISSION_DENIED, - "Not Authorized"); - } - g_object_unref (result); + GAsyncResult *res, + gpointer user_data) +{ + CheckAuthData *data = user_data; + PolkitAuthorizationResult *result; + GError *error; + gboolean is_authorized; + + is_authorized = FALSE; + + error = NULL; + result = polkit_authority_check_authorization_finish (authority, res, &error); + if (error != NULL) + { + throw_error (data->context, ERROR_PERMISSION_DENIED, "Not Authorized: %s", error->message); + g_error_free (error); + } + else + { + if (polkit_authorization_result_get_is_authorized (result)) + { + is_authorized = TRUE; } - - if (is_authorized) { - data->check_auth_callback (data->daemon, - data->device, - data->context, - data->action_id, - data->num_user_data, - data->user_data_elements); + else if (polkit_authorization_result_get_is_challenge (result)) + { + throw_error (data->context, ERROR_PERMISSION_DENIED, "Authentication is required"); + } + else + { + throw_error (data->context, ERROR_PERMISSION_DENIED, "Not Authorized"); } + g_object_unref (result); + } + + if (is_authorized) + { + data->check_auth_callback (data->daemon, + data->device, + data->context, + data->action_id, + data->num_user_data, + data->user_data_elements); + } - check_auth_data_free (data); + check_auth_data_free (data); } /* num_user_data param is followed by @num_user_data (gpointer, GDestroyNotify) pairs.. */ void -daemon_local_check_auth (Daemon *daemon, - Device *device, - const gchar *action_id, - const gchar *operation, - gboolean allow_user_interaction, - CheckAuthCallback check_auth_callback, - DBusGMethodInvocation *context, - guint num_user_data, - ...) -{ - CheckAuthData *data; - va_list va_args; - guint n; - - data = g_new0 (CheckAuthData, 1); - data->action_id = g_strdup (action_id); - data->check_auth_callback = check_auth_callback; - data->context = context; - data->daemon = g_object_ref (daemon); - data->device = device; - if (device != NULL) - g_object_weak_ref (G_OBJECT (device), lca_device_went_away, data); - - data->cancellable = g_cancellable_new (); - data->num_user_data = num_user_data; - data->user_data_elements = g_new0 (gpointer, num_user_data); - data->user_data_notifiers = g_new0 (GDestroyNotify, num_user_data); - - va_start (va_args, num_user_data); - for (n = 0; n < num_user_data; n++) { - data->user_data_elements[n] = va_arg (va_args, gpointer); - data->user_data_notifiers[n] = va_arg (va_args, GDestroyNotify); - } - va_end (va_args); - - if (daemon_local_is_inhibited (daemon)) { - throw_error (data->context, - ERROR_INHIBITED, - "Daemon is inhibited"); - check_auth_data_free (data); - - } else if (action_id != NULL) { - PolkitSubject *subject; - PolkitDetails *details; - PolkitCheckAuthorizationFlags flags; - gchar partition_number_buf[32]; - - /* Set details - see polkit-action-lookup.c for where - * these key/value pairs are used - */ - details = polkit_details_new (); - if (operation != NULL) { - polkit_details_insert (details, - "operation", - (gpointer) operation); - } - if (device != NULL) { - Device *drive; - - polkit_details_insert (details, - "unix-device", - device->priv->device_file); - if (device->priv->device_file_by_id->len > 0) - polkit_details_insert (details, - "unix-device-by-id", - device->priv->device_file_by_id->pdata[0]); - if (device->priv->device_file_by_path->len > 0) - polkit_details_insert (details, - "unix-device-by-path", - device->priv->device_file_by_path->pdata[0]); - - if (device->priv->device_is_drive) { - drive = device; - } else if (device->priv->device_is_partition) { - polkit_details_insert (details, "is-partition", "1"); - g_snprintf (partition_number_buf, - sizeof partition_number_buf, - "%d", - device->priv->partition_number); - polkit_details_insert (details, "partition-number", partition_number_buf); - drive = daemon_local_find_by_object_path (device->priv->daemon, - device->priv->partition_slave); - } else { - drive = NULL; - } - - if (drive != NULL) { - polkit_details_insert (details, - "drive-unix-device", - drive->priv->device_file); - if (drive->priv->device_file_by_id->len > 0) - polkit_details_insert (details, - "drive-unix-device-by-id", - drive->priv->device_file_by_id->pdata[0]); - if (drive->priv->device_file_by_path->len > 0) - polkit_details_insert (details, - "drive-unix-device-by-path", - drive->priv->device_file_by_path->pdata[0]); - if (drive->priv->drive_vendor != NULL) - polkit_details_insert (details, - "drive-vendor", - drive->priv->drive_vendor); - if (drive->priv->drive_model != NULL) - polkit_details_insert (details, - "drive-model", - drive->priv->drive_model); - if (drive->priv->drive_revision != NULL) - polkit_details_insert (details, - "drive-revision", - drive->priv->drive_revision); - if (drive->priv->drive_serial != NULL) - polkit_details_insert (details, - "drive-serial", - drive->priv->drive_serial); - if (drive->priv->drive_connection_interface != NULL) - polkit_details_insert (details, - "drive-connection-interface", - drive->priv->drive_connection_interface); - } - } - - subject = polkit_system_bus_name_new (dbus_g_method_get_sender (context)); - - data->caller = inhibitor_new (context); - g_signal_connect (data->caller, - "disconnected", - G_CALLBACK (lca_caller_disconnected_cb), - data); - - flags = POLKIT_CHECK_AUTHORIZATION_FLAGS_NONE; - if (allow_user_interaction) - flags |= POLKIT_CHECK_AUTHORIZATION_FLAGS_ALLOW_USER_INTERACTION; - polkit_authority_check_authorization (daemon->priv->authority, - subject, - action_id, - details, - flags, - data->cancellable, - (GAsyncReadyCallback) lca_check_authorization_callback, - data); - - g_object_unref (subject); - g_object_unref (details); - } else { - data->check_auth_callback (data->daemon, - data->device, - data->context, - data->action_id, - data->num_user_data, - data->user_data_elements); - check_auth_data_free (data); +daemon_local_check_auth (Daemon *daemon, + Device *device, + const gchar *action_id, + const gchar *operation, + gboolean allow_user_interaction, + CheckAuthCallback check_auth_callback, + DBusGMethodInvocation *context, + guint num_user_data, + ...) +{ + CheckAuthData *data; + va_list va_args; + guint n; + + data = g_new0 (CheckAuthData, 1); + data->action_id = g_strdup (action_id); + data->check_auth_callback = check_auth_callback; + data->context = context; + data->daemon = g_object_ref (daemon); + data->device = device; + if (device != NULL) + g_object_weak_ref (G_OBJECT (device), lca_device_went_away, data); + + data->cancellable = g_cancellable_new (); + data->num_user_data = num_user_data; + data->user_data_elements = g_new0 (gpointer, num_user_data); + data->user_data_notifiers = g_new0 (GDestroyNotify, num_user_data); + + va_start (va_args, num_user_data); + for (n = 0; n < num_user_data; n++) + { + data->user_data_elements[n] = va_arg (va_args, gpointer); + data->user_data_notifiers[n] = va_arg (va_args, GDestroyNotify); + } + va_end (va_args); + + if (daemon_local_is_inhibited (daemon)) + { + throw_error (data->context, ERROR_INHIBITED, "Daemon is inhibited"); + check_auth_data_free (data); + + } + else if (action_id != NULL) + { + PolkitSubject *subject; + PolkitDetails *details; + PolkitCheckAuthorizationFlags flags; + gchar partition_number_buf[32]; + + /* Set details - see polkit-action-lookup.c for where + * these key/value pairs are used + */ + details = polkit_details_new (); + if (operation != NULL) + { + polkit_details_insert (details, "operation", (gpointer) operation); } + if (device != NULL) + { + Device *drive; + + polkit_details_insert (details, "unix-device", device->priv->device_file); + if (device->priv->device_file_by_id->len > 0) + polkit_details_insert (details, "unix-device-by-id", device->priv->device_file_by_id->pdata[0]); + if (device->priv->device_file_by_path->len > 0) + polkit_details_insert (details, "unix-device-by-path", device->priv->device_file_by_path->pdata[0]); + + if (device->priv->device_is_drive) + { + drive = device; + } + else if (device->priv->device_is_partition) + { + polkit_details_insert (details, "is-partition", "1"); + g_snprintf (partition_number_buf, sizeof partition_number_buf, "%d", device->priv->partition_number); + polkit_details_insert (details, "partition-number", partition_number_buf); + drive = daemon_local_find_by_object_path (device->priv->daemon, device->priv->partition_slave); + } + else + { + drive = NULL; + } + + if (drive != NULL) + { + polkit_details_insert (details, "drive-unix-device", drive->priv->device_file); + if (drive->priv->device_file_by_id->len > 0) + polkit_details_insert (details, "drive-unix-device-by-id", drive->priv->device_file_by_id->pdata[0]); + if (drive->priv->device_file_by_path->len > 0) + polkit_details_insert (details, "drive-unix-device-by-path", drive->priv->device_file_by_path->pdata[0]); + if (drive->priv->drive_vendor != NULL) + polkit_details_insert (details, "drive-vendor", drive->priv->drive_vendor); + if (drive->priv->drive_model != NULL) + polkit_details_insert (details, "drive-model", drive->priv->drive_model); + if (drive->priv->drive_revision != NULL) + polkit_details_insert (details, "drive-revision", drive->priv->drive_revision); + if (drive->priv->drive_serial != NULL) + polkit_details_insert (details, "drive-serial", drive->priv->drive_serial); + if (drive->priv->drive_connection_interface != NULL) + polkit_details_insert (details, "drive-connection-interface", drive->priv->drive_connection_interface); + } + } + + subject = polkit_system_bus_name_new (dbus_g_method_get_sender (context)); + + data->caller = inhibitor_new (context); + g_signal_connect (data->caller, "disconnected", G_CALLBACK (lca_caller_disconnected_cb), data); + + flags = POLKIT_CHECK_AUTHORIZATION_FLAGS_NONE; + if (allow_user_interaction) + flags |= POLKIT_CHECK_AUTHORIZATION_FLAGS_ALLOW_USER_INTERACTION; + polkit_authority_check_authorization (daemon->priv->authority, + subject, + action_id, + details, + flags, + data->cancellable, + (GAsyncReadyCallback) lca_check_authorization_callback, + data); + + g_object_unref (subject); + g_object_unref (details); + } + else + { + data->check_auth_callback (data->daemon, + data->device, + data->context, + data->action_id, + data->num_user_data, + data->user_data_elements); + check_auth_data_free (data); + } } /*--------------------------------------------------------------------------------------------------------------*/ @@ -2248,722 +2289,757 @@ daemon_local_check_auth (Daemon *daemon, #define SYSFS_BLOCK_STAT_MAX_SIZE 256 static void -disk_set_standby_timeout_child_watch_cb (GPid pid, - gint status, +disk_set_standby_timeout_child_watch_cb (GPid pid, + gint status, gpointer user_data) { - Device *device = DEVICE (user_data); + Device *device = DEVICE (user_data); - if (WIFEXITED (status) && WEXITSTATUS (status) == 0) { - g_print ("**** NOTE: standby helper for %s completed successfully\n", device->priv->device_file); - } else { - g_warning ("standby helper for %s failed with exit code %d (if_exited=%d)\n", - device->priv->device_file, - WEXITSTATUS (status), - WIFEXITED (status)); - } + if (WIFEXITED (status) && WEXITSTATUS (status) == 0) + { + g_print ("**** NOTE: standby helper for %s completed successfully\n", device->priv->device_file); + } + else + { + g_warning ("standby helper for %s failed with exit code %d (if_exited=%d)\n", + device->priv->device_file, + WEXITSTATUS (status), + WIFEXITED (status)); + } - g_object_unref (device); + g_object_unref (device); } static void disk_set_standby_timeout (Device *device) { - GError *error; - GPid pid; - gint value; - gchar *argv[5] = {"hdparm", - "-S", - NULL, /* argv[2]: timeout value */ - NULL, /* argv[3]: device_file */ - NULL}; - - if (device->priv->spindown_timeout == 0) { - value = 0; - } else if (device->priv->spindown_timeout <= 240*5) { - /* 1...240 are blocks of 5 secs */ - value = device->priv->spindown_timeout / 5; - } else if (device->priv->spindown_timeout <= (5*60 + 30)*60) { - /* 241...251 are blocks of 30 minutes */ - value = device->priv->spindown_timeout / (30 * 60) + 240; - if (value == 240) - value = 241; - } else { - /* so max timeout is 5.5 hours (252, 253, 244, 255 are vendor-specific / uninteresting) */ - value = 251; - } - - argv[2] = g_strdup_printf ("%d", value); - argv[3] = device->priv->device_file; - - error = NULL; - if (!g_spawn_async_with_pipes (NULL, - argv, - NULL, - G_SPAWN_SEARCH_PATH | G_SPAWN_DO_NOT_REAP_CHILD, - NULL, - NULL, - &pid, - NULL, - NULL, - NULL, - &error)) { - g_warning ("Error launching %s: %s", argv[0], error->message); - g_error_free (error); - goto out; - } - - g_child_watch_add (pid, disk_set_standby_timeout_child_watch_cb, g_object_ref (device)); + GError *error; + GPid pid; + gint value; + gchar *argv[5] = + { "hdparm", "-S", NULL, /* argv[2]: timeout value */ + NULL, /* argv[3]: device_file */ + NULL }; + + if (device->priv->spindown_timeout == 0) + { + value = 0; + } + else if (device->priv->spindown_timeout <= 240 * 5) + { + /* 1...240 are blocks of 5 secs */ + value = device->priv->spindown_timeout / 5; + } + else if (device->priv->spindown_timeout <= (5 * 60 + 30) * 60) + { + /* 241...251 are blocks of 30 minutes */ + value = device->priv->spindown_timeout / (30 * 60) + 240; + if (value == 240) + value = 241; + } + else + { + /* so max timeout is 5.5 hours (252, 253, 244, 255 are vendor-specific / uninteresting) */ + value = 251; + } + + argv[2] = g_strdup_printf ("%d", value); + argv[3] = device->priv->device_file; + + error = NULL; + if (!g_spawn_async_with_pipes (NULL, + argv, + NULL, + G_SPAWN_SEARCH_PATH | G_SPAWN_DO_NOT_REAP_CHILD, + NULL, + NULL, + &pid, + NULL, + NULL, + NULL, + &error)) + { + g_warning ("Error launching %s: %s", argv[0], error->message); + g_error_free (error); + goto out; + } + + g_child_watch_add (pid, disk_set_standby_timeout_child_watch_cb, g_object_ref (device)); out: - g_free (argv[2]); + g_free (argv[2]); } void daemon_local_update_spindown (Daemon *daemon) { - GHashTableIter hash_iter; - Device *device; - GList *l; + GHashTableIter hash_iter; + Device *device; + GList *l; - g_hash_table_iter_init (&hash_iter, daemon->priv->map_object_path_to_device); - while (g_hash_table_iter_next (&hash_iter, NULL, (gpointer) &device)) { - gint spindown_timeout; + g_hash_table_iter_init (&hash_iter, daemon->priv->map_object_path_to_device); + while (g_hash_table_iter_next (&hash_iter, NULL, (gpointer) & device)) + { + gint spindown_timeout; - if (!device->priv->device_is_drive || !device->priv->drive_can_spindown) - continue; + if (!device->priv->device_is_drive || !device->priv->drive_can_spindown) + continue; - spindown_timeout = 0; - if (device->priv->spindown_inhibitors == NULL && daemon->priv->spindown_inhibitors == NULL) { - /* no inhibitors */ - } else { + spindown_timeout = 0; + if (device->priv->spindown_inhibitors == NULL && daemon->priv->spindown_inhibitors == NULL) + { + /* no inhibitors */ + } + else + { - spindown_timeout = G_MAXINT; + spindown_timeout = G_MAXINT; - /* first go through all inhibitors on the device */ - for (l = device->priv->spindown_inhibitors; l != NULL; l = l->next) { - Inhibitor *inhibitor = INHIBITOR (l->data); - gint spindown_timeout_inhibitor; + /* first go through all inhibitors on the device */ + for (l = device->priv->spindown_inhibitors; l != NULL; l = l->next) + { + Inhibitor *inhibitor = INHIBITOR (l->data); + gint spindown_timeout_inhibitor; - spindown_timeout_inhibitor = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (inhibitor), - "spindown-timeout-seconds")); - g_warn_if_fail (spindown_timeout_inhibitor > 0); + spindown_timeout_inhibitor = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (inhibitor), + "spindown-timeout-seconds")); + g_warn_if_fail (spindown_timeout_inhibitor > 0); - if (spindown_timeout_inhibitor < spindown_timeout) - spindown_timeout = spindown_timeout_inhibitor; - } + if (spindown_timeout_inhibitor < spindown_timeout) + spindown_timeout = spindown_timeout_inhibitor; + } - /* then all inhibitors on the daemon */ - for (l = daemon->priv->spindown_inhibitors; l != NULL; l = l->next) { - Inhibitor *inhibitor = INHIBITOR (l->data); - gint spindown_timeout_inhibitor; + /* then all inhibitors on the daemon */ + for (l = daemon->priv->spindown_inhibitors; l != NULL; l = l->next) + { + Inhibitor *inhibitor = INHIBITOR (l->data); + gint spindown_timeout_inhibitor; - spindown_timeout_inhibitor = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (inhibitor), - "spindown-timeout-seconds")); - g_warn_if_fail (spindown_timeout_inhibitor > 0); + spindown_timeout_inhibitor = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (inhibitor), + "spindown-timeout-seconds")); + g_warn_if_fail (spindown_timeout_inhibitor > 0); - if (spindown_timeout_inhibitor < spindown_timeout) - spindown_timeout = spindown_timeout_inhibitor; - } - } + if (spindown_timeout_inhibitor < spindown_timeout) + spindown_timeout = spindown_timeout_inhibitor; + } + } - if (device->priv->spindown_timeout != spindown_timeout) { - device->priv->spindown_timeout = spindown_timeout; - /* just assume this always works... */ - disk_set_standby_timeout (device); - } + if (device->priv->spindown_timeout != spindown_timeout) + { + device->priv->spindown_timeout = spindown_timeout; + /* just assume this always works... */ + disk_set_standby_timeout (device); } + } } /*--------------------------------------------------------------------------------------------------------------*/ Adapter * -daemon_local_find_enclosing_adapter (Daemon *daemon, - const gchar *native_path) -{ - GHashTableIter iter; - const gchar *adapter_native_path; - Adapter *adapter; - Adapter *ret; - - ret = NULL; - - g_hash_table_iter_init (&iter, daemon->priv->map_native_path_to_adapter); - while (g_hash_table_iter_next (&iter, (gpointer) &adapter_native_path, (gpointer) &adapter)) { - if (g_str_has_prefix (native_path, adapter_native_path)) { - ret = adapter; - break; - } +daemon_local_find_enclosing_adapter (Daemon *daemon, + const gchar *native_path) +{ + GHashTableIter iter; + const gchar *adapter_native_path; + Adapter *adapter; + Adapter *ret; + + ret = NULL; + + g_hash_table_iter_init (&iter, daemon->priv->map_native_path_to_adapter); + while (g_hash_table_iter_next (&iter, (gpointer) & adapter_native_path, (gpointer) & adapter)) + { + if (g_str_has_prefix (native_path, adapter_native_path)) + { + ret = adapter; + break; } + } - return ret; + return ret; } Expander * -daemon_local_find_enclosing_expander (Daemon *daemon, - const gchar *native_path) +daemon_local_find_enclosing_expander (Daemon *daemon, + const gchar *native_path) { - GHashTableIter iter; - Expander *expander; - Expander *ret; + GHashTableIter iter; + Expander *expander; + Expander *ret; - ret = NULL; + ret = NULL; - g_hash_table_iter_init (&iter, daemon->priv->map_native_path_to_expander); - while (g_hash_table_iter_next (&iter, NULL, (gpointer) &expander)) { - if (local_expander_encloses_native_path (expander, native_path)) { - ret = expander; - break; - } + g_hash_table_iter_init (&iter, daemon->priv->map_native_path_to_expander); + while (g_hash_table_iter_next (&iter, NULL, (gpointer) & expander)) + { + if (local_expander_encloses_native_path (expander, native_path)) + { + ret = expander; + break; } + } - return ret; + return ret; } GList * -daemon_local_find_enclosing_ports (Daemon *daemon, - const gchar *native_path) +daemon_local_find_enclosing_ports (Daemon *daemon, + const gchar *native_path) { - GHashTableIter iter; - Port *port; - GList *ret; + GHashTableIter iter; + Port *port; + GList *ret; - ret = NULL; + ret = NULL; - g_hash_table_iter_init (&iter, daemon->priv->map_native_path_to_port); - while (g_hash_table_iter_next (&iter, NULL, (gpointer) &port)) { - if (local_port_encloses_native_path (port, native_path)) { - ret = g_list_append (ret, port); - } + g_hash_table_iter_init (&iter, daemon->priv->map_native_path_to_port); + while (g_hash_table_iter_next (&iter, NULL, (gpointer) & port)) + { + if (local_port_encloses_native_path (port, native_path)) + { + ret = g_list_append (ret, port); } + } - return ret; + return ret; } /*--------------------------------------------------------------------------------------------------------------*/ /* exported methods */ static void -enumerate_cb (gpointer key, gpointer value, gpointer user_data) +enumerate_cb (gpointer key, + gpointer value, + gpointer user_data) { - Device *device = DEVICE (value); - GPtrArray *object_paths = user_data; - g_ptr_array_add (object_paths, g_strdup (device_local_get_object_path (device))); + Device *device = DEVICE (value); + GPtrArray *object_paths = user_data; + g_ptr_array_add (object_paths, g_strdup (device_local_get_object_path (device))); } gboolean -daemon_enumerate_devices (Daemon *daemon, - DBusGMethodInvocation *context) +daemon_enumerate_devices (Daemon *daemon, + DBusGMethodInvocation *context) { - GPtrArray *object_paths; + GPtrArray *object_paths; - /* TODO: enumerate in the right order wrt. dm/md.. - * - * see also gdu_pool_new() in src/gdu-pool.c in g-d-u - */ + /* TODO: enumerate in the right order wrt. dm/md.. + * + * see also gdu_pool_new() in src/gdu-pool.c in g-d-u + */ - object_paths = g_ptr_array_new (); - g_hash_table_foreach (daemon->priv->map_native_path_to_device, enumerate_cb, object_paths); - dbus_g_method_return (context, object_paths); - g_ptr_array_foreach (object_paths, (GFunc) g_free, NULL); - g_ptr_array_free (object_paths, TRUE); - return TRUE; + object_paths = g_ptr_array_new (); + g_hash_table_foreach (daemon->priv->map_native_path_to_device, enumerate_cb, object_paths); + dbus_g_method_return (context, object_paths); + g_ptr_array_foreach (object_paths, (GFunc) g_free, NULL); + g_ptr_array_free (object_paths, TRUE); + return TRUE; } /*--------------------------------------------------------------------------------------------------------------*/ static void -enumerate_adapter_cb (gpointer key, gpointer value, gpointer user_data) +enumerate_adapter_cb (gpointer key, + gpointer value, + gpointer user_data) { - Adapter *adapter = ADAPTER (value); - GPtrArray *object_paths = user_data; - g_ptr_array_add (object_paths, g_strdup (adapter_local_get_object_path (adapter))); + Adapter *adapter = ADAPTER (value); + GPtrArray *object_paths = user_data; + g_ptr_array_add (object_paths, g_strdup (adapter_local_get_object_path (adapter))); } /* dbus-send --system --print-reply --dest=org.freedesktop.UDisks /org/freedesktop/UDisks org.freedesktop.UDisks.EnumerateAdapters */ gboolean -daemon_enumerate_adapters (Daemon *daemon, - DBusGMethodInvocation *context) +daemon_enumerate_adapters (Daemon *daemon, + DBusGMethodInvocation *context) { - GPtrArray *object_paths; + GPtrArray *object_paths; - object_paths = g_ptr_array_new (); - g_hash_table_foreach (daemon->priv->map_native_path_to_adapter, enumerate_adapter_cb, object_paths); - dbus_g_method_return (context, object_paths); - g_ptr_array_foreach (object_paths, (GFunc) g_free, NULL); - g_ptr_array_free (object_paths, TRUE); - return TRUE; + object_paths = g_ptr_array_new (); + g_hash_table_foreach (daemon->priv->map_native_path_to_adapter, enumerate_adapter_cb, object_paths); + dbus_g_method_return (context, object_paths); + g_ptr_array_foreach (object_paths, (GFunc) g_free, NULL); + g_ptr_array_free (object_paths, TRUE); + return TRUE; } /*--------------------------------------------------------------------------------------------------------------*/ static void -enumerate_expander_cb (gpointer key, gpointer value, gpointer user_data) +enumerate_expander_cb (gpointer key, + gpointer value, + gpointer user_data) { - Expander *expander = EXPANDER (value); - GPtrArray *object_paths = user_data; - g_ptr_array_add (object_paths, g_strdup (expander_local_get_object_path (expander))); + Expander *expander = EXPANDER (value); + GPtrArray *object_paths = user_data; + g_ptr_array_add (object_paths, g_strdup (expander_local_get_object_path (expander))); } /* dbus-send --system --print-reply --dest=org.freedesktop.UDisks /org/freedesktop/UDisks org.freedesktop.UDisks.EnumerateExpanders */ gboolean -daemon_enumerate_expanders (Daemon *daemon, - DBusGMethodInvocation *context) +daemon_enumerate_expanders (Daemon *daemon, + DBusGMethodInvocation *context) { - GPtrArray *object_paths; + GPtrArray *object_paths; - object_paths = g_ptr_array_new (); - g_hash_table_foreach (daemon->priv->map_native_path_to_expander, enumerate_expander_cb, object_paths); - dbus_g_method_return (context, object_paths); - g_ptr_array_foreach (object_paths, (GFunc) g_free, NULL); - g_ptr_array_free (object_paths, TRUE); - return TRUE; + object_paths = g_ptr_array_new (); + g_hash_table_foreach (daemon->priv->map_native_path_to_expander, enumerate_expander_cb, object_paths); + dbus_g_method_return (context, object_paths); + g_ptr_array_foreach (object_paths, (GFunc) g_free, NULL); + g_ptr_array_free (object_paths, TRUE); + return TRUE; } /*--------------------------------------------------------------------------------------------------------------*/ static void -enumerate_port_cb (gpointer key, gpointer value, gpointer user_data) +enumerate_port_cb (gpointer key, + gpointer value, + gpointer user_data) { - Port *port = PORT (value); - GPtrArray *object_paths = user_data; - g_ptr_array_add (object_paths, g_strdup (port_local_get_object_path (port))); + Port *port = PORT (value); + GPtrArray *object_paths = user_data; + g_ptr_array_add (object_paths, g_strdup (port_local_get_object_path (port))); } /* dbus-send --system --print-reply --dest=org.freedesktop.UDisks /org/freedesktop/UDisks org.freedesktop.UDisks.EnumeratePorts */ gboolean -daemon_enumerate_ports (Daemon *daemon, - DBusGMethodInvocation *context) +daemon_enumerate_ports (Daemon *daemon, + DBusGMethodInvocation *context) { - GPtrArray *object_paths; + GPtrArray *object_paths; - object_paths = g_ptr_array_new (); - g_hash_table_foreach (daemon->priv->map_native_path_to_port, enumerate_port_cb, object_paths); - dbus_g_method_return (context, object_paths); - g_ptr_array_foreach (object_paths, (GFunc) g_free, NULL); - g_ptr_array_free (object_paths, TRUE); - return TRUE; + object_paths = g_ptr_array_new (); + g_hash_table_foreach (daemon->priv->map_native_path_to_port, enumerate_port_cb, object_paths); + dbus_g_method_return (context, object_paths); + g_ptr_array_foreach (object_paths, (GFunc) g_free, NULL); + g_ptr_array_free (object_paths, TRUE); + return TRUE; } /*--------------------------------------------------------------------------------------------------------------*/ static void -enumerate_device_files_cb (gpointer key, gpointer value, gpointer user_data) +enumerate_device_files_cb (gpointer key, + gpointer value, + gpointer user_data) { - Device *device = DEVICE (value); - GPtrArray *device_files = user_data; - guint n; + Device *device = DEVICE (value); + GPtrArray *device_files = user_data; + guint n; - g_ptr_array_add (device_files, g_strdup (device_local_get_device_file (device))); + g_ptr_array_add (device_files, g_strdup (device_local_get_device_file (device))); - for (n = 0; n < device->priv->device_file_by_id->len; n++) { - g_ptr_array_add (device_files, - g_strdup (((gchar **) device->priv->device_file_by_id->pdata)[n])); - } + for (n = 0; n < device->priv->device_file_by_id->len; n++) + { + g_ptr_array_add (device_files, g_strdup (((gchar **) device->priv->device_file_by_id->pdata)[n])); + } - for (n = 0; n < device->priv->device_file_by_path->len; n++) { - g_ptr_array_add (device_files, - g_strdup (((gchar **) device->priv->device_file_by_path->pdata)[n])); - } + for (n = 0; n < device->priv->device_file_by_path->len; n++) + { + g_ptr_array_add (device_files, g_strdup (((gchar **) device->priv->device_file_by_path->pdata)[n])); + } } gboolean -daemon_enumerate_device_files (Daemon *daemon, - DBusGMethodInvocation *context) +daemon_enumerate_device_files (Daemon *daemon, + DBusGMethodInvocation *context) { - GPtrArray *device_files; + GPtrArray *device_files; - device_files = g_ptr_array_new (); - g_hash_table_foreach (daemon->priv->map_native_path_to_device, enumerate_device_files_cb, device_files); - g_ptr_array_add (device_files, NULL); - dbus_g_method_return (context, device_files->pdata); - g_ptr_array_foreach (device_files, (GFunc) g_free, NULL); - g_ptr_array_free (device_files, TRUE); - return TRUE; + device_files = g_ptr_array_new (); + g_hash_table_foreach (daemon->priv->map_native_path_to_device, enumerate_device_files_cb, device_files); + g_ptr_array_add (device_files, NULL); + dbus_g_method_return (context, device_files->pdata); + g_ptr_array_foreach (device_files, (GFunc) g_free, NULL); + g_ptr_array_free (device_files, TRUE); + return TRUE; } /*--------------------------------------------------------------------------------------------------------------*/ gboolean -daemon_find_device_by_device_file (Daemon *daemon, - const char *device_file, - DBusGMethodInvocation *context) -{ - const char *object_path; - Device *device; - gchar canonical_device_file[PATH_MAX]; - - realpath (device_file, canonical_device_file); - - object_path = NULL; - - device = daemon_local_find_by_device_file (daemon, canonical_device_file); - if (device != NULL) { - object_path = device_local_get_object_path (device); - dbus_g_method_return (context, object_path); - } else { - throw_error (context, - ERROR_FAILED, - "No such device"); - } +daemon_find_device_by_device_file (Daemon *daemon, + const char *device_file, + DBusGMethodInvocation *context) +{ + const char *object_path; + Device *device; + gchar canonical_device_file[PATH_MAX]; + + realpath (device_file, canonical_device_file); + + object_path = NULL; - return TRUE; + device = daemon_local_find_by_device_file (daemon, canonical_device_file); + if (device != NULL) + { + object_path = device_local_get_object_path (device); + dbus_g_method_return (context, object_path); + } + else + { + throw_error (context, ERROR_FAILED, "No such device"); + } + + return TRUE; } /*--------------------------------------------------------------------------------------------------------------*/ gboolean -daemon_find_device_by_major_minor (Daemon *daemon, - gint64 major, - gint64 minor, - DBusGMethodInvocation *context) -{ - const char *object_path; - Device *device; - dev_t dev; - - dev = makedev (major, minor); - - object_path = NULL; - - device = daemon_local_find_by_dev (daemon, dev); - if (device != NULL) { - object_path = device_local_get_object_path (device); - dbus_g_method_return (context, object_path); - } else { - throw_error (context, - ERROR_FAILED, - "No such device"); - } +daemon_find_device_by_major_minor (Daemon *daemon, + gint64 major, + gint64 minor, + DBusGMethodInvocation *context) +{ + const char *object_path; + Device *device; + dev_t dev; + + dev = makedev (major, minor); + + object_path = NULL; - return TRUE; + device = daemon_local_find_by_dev (daemon, dev); + if (device != NULL) + { + object_path = device_local_get_object_path (device); + dbus_g_method_return (context, object_path); + } + else + { + throw_error (context, ERROR_FAILED, "No such device"); + } + + return TRUE; } /*--------------------------------------------------------------------------------------------------------------*/ static void daemon_polling_inhibitor_disconnected_cb (Inhibitor *inhibitor, - Daemon *daemon) + Daemon *daemon) { - daemon->priv->polling_inhibitors = g_list_remove (daemon->priv->polling_inhibitors, inhibitor); - g_signal_handlers_disconnect_by_func (inhibitor, daemon_polling_inhibitor_disconnected_cb, daemon); - g_object_unref (inhibitor); + daemon->priv->polling_inhibitors = g_list_remove (daemon->priv->polling_inhibitors, inhibitor); + g_signal_handlers_disconnect_by_func (inhibitor, daemon_polling_inhibitor_disconnected_cb, daemon); + g_object_unref (inhibitor); - daemon_local_synthesize_changed_on_all_devices (daemon); - daemon_local_update_poller (daemon); + daemon_local_synthesize_changed_on_all_devices (daemon); + daemon_local_update_poller (daemon); } gboolean daemon_local_has_polling_inhibitors (Daemon *daemon) { - return daemon->priv->polling_inhibitors != NULL; + return daemon->priv->polling_inhibitors != NULL; } static void -daemon_drive_inhibit_all_polling_authorized_cb (Daemon *daemon, - Device *device, - DBusGMethodInvocation *context, - const gchar *action_id, - guint num_user_data, - gpointer *user_data_elements) -{ - gchar **options = user_data_elements[0]; - Inhibitor *inhibitor; - guint n; - - for (n = 0; options[n] != NULL; n++) { - const char *option = options[n]; - throw_error (context, - ERROR_INVALID_OPTION, - "Unknown option %s", option); - goto out; - } +daemon_drive_inhibit_all_polling_authorized_cb (Daemon *daemon, + Device *device, + DBusGMethodInvocation *context, + const gchar *action_id, + guint num_user_data, + gpointer *user_data_elements) +{ + gchar **options = user_data_elements[0]; + Inhibitor *inhibitor; + guint n; + + for (n = 0; options[n] != NULL; n++) + { + const char *option = options[n]; + throw_error (context, ERROR_INVALID_OPTION, "Unknown option %s", option); + goto out; + } - inhibitor = inhibitor_new (context); + inhibitor = inhibitor_new (context); - daemon->priv->polling_inhibitors = g_list_prepend (daemon->priv->polling_inhibitors, inhibitor); - g_signal_connect (inhibitor, "disconnected", G_CALLBACK (daemon_polling_inhibitor_disconnected_cb), daemon); + daemon->priv->polling_inhibitors = g_list_prepend (daemon->priv->polling_inhibitors, inhibitor); + g_signal_connect (inhibitor, "disconnected", G_CALLBACK (daemon_polling_inhibitor_disconnected_cb), daemon); - daemon_local_synthesize_changed_on_all_devices (daemon); - daemon_local_update_poller (daemon); + daemon_local_synthesize_changed_on_all_devices (daemon); + daemon_local_update_poller (daemon); - dbus_g_method_return (context, inhibitor_get_cookie (inhibitor)); + dbus_g_method_return (context, inhibitor_get_cookie (inhibitor)); -out: - ; + out: + ; } gboolean -daemon_drive_inhibit_all_polling (Daemon *daemon, - char **options, - DBusGMethodInvocation *context) -{ - daemon_local_check_auth (daemon, - NULL, - "org.freedesktop.devicekit.disks.inhibit-polling", - "InhibitAllPolling", - TRUE, - daemon_drive_inhibit_all_polling_authorized_cb, - context, - 1, - g_strdupv (options), g_strfreev); - return TRUE; +daemon_drive_inhibit_all_polling (Daemon *daemon, + char **options, + DBusGMethodInvocation *context) +{ + daemon_local_check_auth (daemon, + NULL, + "org.freedesktop.devicekit.disks.inhibit-polling", + "InhibitAllPolling", + TRUE, + daemon_drive_inhibit_all_polling_authorized_cb, + context, + 1, + g_strdupv (options), + g_strfreev); + return TRUE; } /*--------------------------------------------------------------------------------------------------------------*/ gboolean -daemon_drive_uninhibit_all_polling (Daemon *daemon, - char *cookie, - DBusGMethodInvocation *context) +daemon_drive_uninhibit_all_polling (Daemon *daemon, + char *cookie, + DBusGMethodInvocation *context) { - const gchar *sender; - Inhibitor *inhibitor; - GList *l; + const gchar *sender; + Inhibitor *inhibitor; + GList *l; - sender = dbus_g_method_get_sender (context); + sender = dbus_g_method_get_sender (context); - inhibitor = NULL; - for (l = daemon->priv->polling_inhibitors; l != NULL; l = l->next) { - Inhibitor *i = INHIBITOR (l->data); + inhibitor = NULL; + for (l = daemon->priv->polling_inhibitors; l != NULL; l = l->next) + { + Inhibitor *i = INHIBITOR (l->data); - if (g_strcmp0 (inhibitor_get_unique_dbus_name (i), sender) == 0 && - g_strcmp0 (inhibitor_get_cookie (i), cookie) == 0) { - inhibitor = i; - break; - } + if (g_strcmp0 (inhibitor_get_unique_dbus_name (i), sender) == 0 && g_strcmp0 (inhibitor_get_cookie (i), cookie) + == 0) + { + inhibitor = i; + break; } + } - if (inhibitor == NULL) { - throw_error (context, - ERROR_FAILED, - "No such inhibitor"); - goto out; - } + if (inhibitor == NULL) + { + throw_error (context, ERROR_FAILED, "No such inhibitor"); + goto out; + } - daemon->priv->polling_inhibitors = g_list_remove (daemon->priv->polling_inhibitors, inhibitor); - g_object_unref (inhibitor); + daemon->priv->polling_inhibitors = g_list_remove (daemon->priv->polling_inhibitors, inhibitor); + g_object_unref (inhibitor); - daemon_local_synthesize_changed_on_all_devices (daemon); - daemon_local_update_poller (daemon); + daemon_local_synthesize_changed_on_all_devices (daemon); + daemon_local_update_poller (daemon); - dbus_g_method_return (context); + dbus_g_method_return (context); out: - return TRUE; + return TRUE; } /*--------------------------------------------------------------------------------------------------------------*/ static void daemon_inhibitor_disconnected_cb (Inhibitor *inhibitor, - Daemon *daemon) + Daemon *daemon) { - daemon->priv->inhibitors = g_list_remove (daemon->priv->inhibitors, inhibitor); - g_signal_handlers_disconnect_by_func (inhibitor, daemon_inhibitor_disconnected_cb, daemon); - g_object_unref (inhibitor); + daemon->priv->inhibitors = g_list_remove (daemon->priv->inhibitors, inhibitor); + g_signal_handlers_disconnect_by_func (inhibitor, daemon_inhibitor_disconnected_cb, daemon); + g_object_unref (inhibitor); } gboolean daemon_local_is_inhibited (Daemon *daemon) { - return daemon->priv->inhibitors != NULL; + return daemon->priv->inhibitors != NULL; } gboolean -daemon_inhibit (Daemon *daemon, - DBusGMethodInvocation *context) +daemon_inhibit (Daemon *daemon, + DBusGMethodInvocation *context) { - Inhibitor *inhibitor; - uid_t uid; + Inhibitor *inhibitor; + uid_t uid; - if (!daemon_local_get_uid (daemon, &uid, context)) - goto out; + if (!daemon_local_get_uid (daemon, &uid, context)) + goto out; - if (uid != 0) { - throw_error (context, - ERROR_FAILED, - "Only uid 0 is authorized to inhibit the daemon"); - goto out; - } + if (uid != 0) + { + throw_error (context, ERROR_FAILED, "Only uid 0 is authorized to inhibit the daemon"); + goto out; + } - inhibitor = inhibitor_new (context); + inhibitor = inhibitor_new (context); - daemon->priv->inhibitors = g_list_prepend (daemon->priv->inhibitors, inhibitor); - g_signal_connect (inhibitor, "disconnected", G_CALLBACK (daemon_inhibitor_disconnected_cb), daemon); + daemon->priv->inhibitors = g_list_prepend (daemon->priv->inhibitors, inhibitor); + g_signal_connect (inhibitor, "disconnected", G_CALLBACK (daemon_inhibitor_disconnected_cb), daemon); - dbus_g_method_return (context, inhibitor_get_cookie (inhibitor)); + dbus_g_method_return (context, inhibitor_get_cookie (inhibitor)); -out: - return TRUE; + out: + return TRUE; } - /*--------------------------------------------------------------------------------------------------------------*/ gboolean -daemon_uninhibit (Daemon *daemon, - char *cookie, - DBusGMethodInvocation *context) +daemon_uninhibit (Daemon *daemon, + char *cookie, + DBusGMethodInvocation *context) { - const gchar *sender; - Inhibitor *inhibitor; - GList *l; + const gchar *sender; + Inhibitor *inhibitor; + GList *l; - sender = dbus_g_method_get_sender (context); + sender = dbus_g_method_get_sender (context); - inhibitor = NULL; - for (l = daemon->priv->inhibitors; l != NULL; l = l->next) { - Inhibitor *i = INHIBITOR (l->data); + inhibitor = NULL; + for (l = daemon->priv->inhibitors; l != NULL; l = l->next) + { + Inhibitor *i = INHIBITOR (l->data); - if (g_strcmp0 (inhibitor_get_unique_dbus_name (i), sender) == 0 && - g_strcmp0 (inhibitor_get_cookie (i), cookie) == 0) { - inhibitor = i; - break; - } + if (g_strcmp0 (inhibitor_get_unique_dbus_name (i), sender) == 0 && g_strcmp0 (inhibitor_get_cookie (i), cookie) + == 0) + { + inhibitor = i; + break; } + } - if (inhibitor == NULL) { - throw_error (context, - ERROR_FAILED, - "No such inhibitor"); - goto out; - } + if (inhibitor == NULL) + { + throw_error (context, ERROR_FAILED, "No such inhibitor"); + goto out; + } - daemon->priv->inhibitors = g_list_remove (daemon->priv->inhibitors, inhibitor); - g_object_unref (inhibitor); + daemon->priv->inhibitors = g_list_remove (daemon->priv->inhibitors, inhibitor); + g_object_unref (inhibitor); - dbus_g_method_return (context); + dbus_g_method_return (context); out: - return TRUE; + return TRUE; } /*--------------------------------------------------------------------------------------------------------------*/ - static void daemon_spindown_inhibitor_disconnected_cb (Inhibitor *inhibitor, - Daemon *daemon) + Daemon *daemon) { - daemon->priv->spindown_inhibitors = g_list_remove (daemon->priv->spindown_inhibitors, inhibitor); - g_signal_handlers_disconnect_by_func (inhibitor, daemon_spindown_inhibitor_disconnected_cb, daemon); - g_object_unref (inhibitor); + daemon->priv->spindown_inhibitors = g_list_remove (daemon->priv->spindown_inhibitors, inhibitor); + g_signal_handlers_disconnect_by_func (inhibitor, daemon_spindown_inhibitor_disconnected_cb, daemon); + g_object_unref (inhibitor); - daemon_local_update_spindown (daemon); + daemon_local_update_spindown (daemon); } static void -daemon_drive_set_all_spindown_timeouts_authorized_cb (Daemon *daemon, - Device *device, - DBusGMethodInvocation *context, - const gchar *action_id, - guint num_user_data, - gpointer *user_data_elements) -{ - gint timeout_seconds = GPOINTER_TO_INT (user_data_elements[0]); - gchar **options = user_data_elements[1]; - Inhibitor *inhibitor; - guint n; - - if (timeout_seconds < 1) { - throw_error (context, ERROR_FAILED, - "Timeout seconds must be at least 1"); - goto out; - } +daemon_drive_set_all_spindown_timeouts_authorized_cb (Daemon *daemon, + Device *device, + DBusGMethodInvocation *context, + const gchar *action_id, + guint num_user_data, + gpointer *user_data_elements) +{ + gint timeout_seconds = GPOINTER_TO_INT (user_data_elements[0]); + gchar **options = user_data_elements[1]; + Inhibitor *inhibitor; + guint n; - for (n = 0; options[n] != NULL; n++) { - const char *option = options[n]; - throw_error (context, - ERROR_INVALID_OPTION, - "Unknown option %s", option); - goto out; - } + if (timeout_seconds < 1) + { + throw_error (context, ERROR_FAILED, "Timeout seconds must be at least 1"); + goto out; + } + + for (n = 0; options[n] != NULL; n++) + { + const char *option = options[n]; + throw_error (context, ERROR_INVALID_OPTION, "Unknown option %s", option); + goto out; + } - inhibitor = inhibitor_new (context); + inhibitor = inhibitor_new (context); - g_object_set_data (G_OBJECT (inhibitor), "spindown-timeout-seconds", GINT_TO_POINTER (timeout_seconds)); + g_object_set_data (G_OBJECT (inhibitor), "spindown-timeout-seconds", GINT_TO_POINTER (timeout_seconds)); - daemon->priv->spindown_inhibitors = g_list_prepend (daemon->priv->spindown_inhibitors, inhibitor); - g_signal_connect (inhibitor, "disconnected", G_CALLBACK (daemon_spindown_inhibitor_disconnected_cb), daemon); + daemon->priv->spindown_inhibitors = g_list_prepend (daemon->priv->spindown_inhibitors, inhibitor); + g_signal_connect (inhibitor, "disconnected", G_CALLBACK (daemon_spindown_inhibitor_disconnected_cb), daemon); - daemon_local_update_spindown (daemon); + daemon_local_update_spindown (daemon); - dbus_g_method_return (context, inhibitor_get_cookie (inhibitor)); + dbus_g_method_return (context, inhibitor_get_cookie (inhibitor)); -out: - ; + out: + ; } gboolean -daemon_drive_set_all_spindown_timeouts (Daemon *daemon, - int timeout_seconds, - char **options, - DBusGMethodInvocation *context) -{ - if (timeout_seconds < 1) { - throw_error (context, ERROR_FAILED, - "Timeout seconds must be at least 1"); - goto out; - } - - daemon_local_check_auth (daemon, - NULL, - "org.freedesktop.devicekit.disks.drive-set-spindown", - "DriveSetAllSpindownTimeouts", - TRUE, - daemon_drive_set_all_spindown_timeouts_authorized_cb, - context, - 2, - GINT_TO_POINTER (timeout_seconds), NULL, - g_strdupv (options), g_strfreev); - +daemon_drive_set_all_spindown_timeouts (Daemon *daemon, + int timeout_seconds, + char **options, + DBusGMethodInvocation *context) +{ + if (timeout_seconds < 1) + { + throw_error (context, ERROR_FAILED, "Timeout seconds must be at least 1"); + goto out; + } + + daemon_local_check_auth (daemon, + NULL, + "org.freedesktop.devicekit.disks.drive-set-spindown", + "DriveSetAllSpindownTimeouts", + TRUE, + daemon_drive_set_all_spindown_timeouts_authorized_cb, + context, + 2, + GINT_TO_POINTER (timeout_seconds), + NULL, + g_strdupv (options), + g_strfreev); out: - return TRUE; + return TRUE; } gboolean -daemon_drive_unset_all_spindown_timeouts (Daemon *daemon, - char *cookie, - DBusGMethodInvocation *context) +daemon_drive_unset_all_spindown_timeouts (Daemon *daemon, + char *cookie, + DBusGMethodInvocation *context) { - const gchar *sender; - Inhibitor *inhibitor; - GList *l; + const gchar *sender; + Inhibitor *inhibitor; + GList *l; - sender = dbus_g_method_get_sender (context); + sender = dbus_g_method_get_sender (context); - inhibitor = NULL; - for (l = daemon->priv->spindown_inhibitors; l != NULL; l = l->next) { - Inhibitor *i = INHIBITOR (l->data); + inhibitor = NULL; + for (l = daemon->priv->spindown_inhibitors; l != NULL; l = l->next) + { + Inhibitor *i = INHIBITOR (l->data); - if (g_strcmp0 (inhibitor_get_unique_dbus_name (i), sender) == 0 && - g_strcmp0 (inhibitor_get_cookie (i), cookie) == 0) { - inhibitor = i; - break; - } + if (g_strcmp0 (inhibitor_get_unique_dbus_name (i), sender) == 0 && g_strcmp0 (inhibitor_get_cookie (i), cookie) + == 0) + { + inhibitor = i; + break; } + } - if (inhibitor == NULL) { - throw_error (context, - ERROR_FAILED, - "No such spindown configurator"); - goto out; - } + if (inhibitor == NULL) + { + throw_error (context, ERROR_FAILED, "No such spindown configurator"); + goto out; + } - daemon->priv->spindown_inhibitors = g_list_remove (daemon->priv->spindown_inhibitors, inhibitor); - g_object_unref (inhibitor); + daemon->priv->spindown_inhibitors = g_list_remove (daemon->priv->spindown_inhibitors, inhibitor); + g_object_unref (inhibitor); - daemon_local_update_spindown (daemon); + daemon_local_update_spindown (daemon); - dbus_g_method_return (context); + dbus_g_method_return (context); out: - return TRUE; + return TRUE; } /*--------------------------------------------------------------------------------------------------------------*/ diff --git a/src/daemon.h b/src/daemon.h index efd0619..621e734 100644 --- a/src/daemon.h +++ b/src/daemon.h @@ -36,190 +36,190 @@ G_BEGIN_DECLS #define IS_DAEMON_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), TYPE_DAEMON)) #define DAEMON_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), TYPE_DAEMON, DaemonClass)) -typedef struct DaemonClass DaemonClass; +typedef struct DaemonClass DaemonClass; typedef struct DaemonPrivate DaemonPrivate; struct Daemon { - GObject parent; - DaemonPrivate *priv; + GObject parent; + DaemonPrivate *priv; }; struct DaemonClass { - GObjectClass parent_class; + GObjectClass parent_class; }; typedef enum { - ERROR_FAILED, - ERROR_PERMISSION_DENIED, - ERROR_BUSY, - ERROR_CANCELLED, - ERROR_INHIBITED, - ERROR_INVALID_OPTION, - ERROR_NOT_SUPPORTED, - ERROR_ATA_SMART_WOULD_WAKEUP, - ERROR_FILESYSTEM_DRIVER_MISSING, - ERROR_FILESYSTEM_TOOLS_MISSING, - NUM_ERRORS + ERROR_FAILED, + ERROR_PERMISSION_DENIED, + ERROR_BUSY, + ERROR_CANCELLED, + ERROR_INHIBITED, + ERROR_INVALID_OPTION, + ERROR_NOT_SUPPORTED, + ERROR_ATA_SMART_WOULD_WAKEUP, + ERROR_FILESYSTEM_DRIVER_MISSING, + ERROR_FILESYSTEM_TOOLS_MISSING, + NUM_ERRORS } Error; #define ERROR error_quark () GType error_get_type (void); #define TYPE_ERROR (error_get_type ()) -GQuark error_quark (void); +GQuark error_quark (void); -GType daemon_get_type (void) G_GNUC_CONST; -Daemon *daemon_new (void); +GType daemon_get_type (void) G_GNUC_CONST; +Daemon * daemon_new (void); /* local methods */ -GList *daemon_local_get_all_devices (Daemon *daemon); +GList *daemon_local_get_all_devices (Daemon *daemon); -Device *daemon_local_find_by_native_path (Daemon *daemon, - const char *native_path); +Device * daemon_local_find_by_native_path (Daemon *daemon, + const char *native_path); -Device *daemon_local_find_by_object_path (Daemon *daemon, - const char *object_path); +Device * daemon_local_find_by_object_path (Daemon *daemon, + const char *object_path); -Device *daemon_local_find_by_device_file (Daemon *daemon, - const char *device_file); +Device * daemon_local_find_by_device_file (Daemon *daemon, + const char *device_file); -Device *daemon_local_find_by_dev (Daemon *daemon, - dev_t dev); +Device * daemon_local_find_by_dev (Daemon *daemon, + dev_t dev); -Adapter *daemon_local_find_enclosing_adapter (Daemon *daemon, - const gchar *native_path); +Adapter * daemon_local_find_enclosing_adapter (Daemon *daemon, + const gchar *native_path); -Expander *daemon_local_find_enclosing_expander (Daemon *daemon, - const gchar *native_path); +Expander * daemon_local_find_enclosing_expander (Daemon *daemon, + const gchar *native_path); -GList *daemon_local_find_enclosing_ports (Daemon *daemon, - const gchar *native_path); +GList * daemon_local_find_enclosing_ports (Daemon *daemon, + const gchar *native_path); -typedef void (*CheckAuthCallback) (Daemon *daemon, - Device *device, - DBusGMethodInvocation *context, - const gchar *action_id, - guint num_user_data, - gpointer *user_data_elements); +typedef void (*CheckAuthCallback) (Daemon *daemon, + Device *device, + DBusGMethodInvocation *context, + const gchar *action_id, + guint num_user_data, + gpointer *user_data_elements); /* num_user_data param is followed by @num_user_data (gpointer, GDestroyNotify) pairs.. */ -void daemon_local_check_auth (Daemon *daemon, - Device *device, - const gchar *action_id, - const gchar *operation, - gboolean allow_user_interaction, - CheckAuthCallback check_auth_callback, - DBusGMethodInvocation *context, - guint num_user_data, - ...); - +void daemon_local_check_auth (Daemon *daemon, + Device *device, + const gchar *action_id, + const gchar *operation, + gboolean allow_user_interaction, + CheckAuthCallback check_auth_callback, + DBusGMethodInvocation *context, + guint num_user_data, + ...); /* TODO: probably use G_GNUC_WARN_UNUSED_RESULT here and fix up callers */ -gboolean daemon_local_get_uid (Daemon *daemon, - uid_t *out_uid, - DBusGMethodInvocation *context); +gboolean daemon_local_get_uid (Daemon *daemon, + uid_t *out_uid, + DBusGMethodInvocation *context); -void daemon_local_synthesize_changed_on_all_devices (Daemon *daemon); +void daemon_local_synthesize_changed_on_all_devices (Daemon *daemon); -void daemon_local_synthesize_changed (Daemon *daemon, - Device *device); +void daemon_local_synthesize_changed (Daemon *daemon, + Device *device); -void daemon_local_update_poller (Daemon *daemon); +void daemon_local_update_poller (Daemon *daemon); -void daemon_local_update_spindown (Daemon *daemon); +void daemon_local_update_spindown (Daemon *daemon); -gboolean daemon_local_has_polling_inhibitors (Daemon *daemon); +gboolean daemon_local_has_polling_inhibitors (Daemon *daemon); -gboolean daemon_local_is_inhibited (Daemon *daemon); +gboolean daemon_local_is_inhibited (Daemon *daemon); -MountMonitor *daemon_local_get_mount_monitor (Daemon *daemon); +MountMonitor * daemon_local_get_mount_monitor (Daemon *daemon); -typedef struct { - const char *id; - const char *name; - gboolean supports_unix_owners; - gboolean can_mount; - gboolean can_create; - guint max_label_len; - gboolean supports_label_rename; - gboolean supports_online_label_rename; - gboolean supports_fsck; - gboolean supports_online_fsck; - gboolean supports_resize_enlarge; - gboolean supports_online_resize_enlarge; - gboolean supports_resize_shrink; - gboolean supports_online_resize_shrink; +typedef struct +{ + const char *id; + const char *name; + gboolean supports_unix_owners; + gboolean can_mount; + gboolean can_create; + guint max_label_len; + gboolean supports_label_rename; + gboolean supports_online_label_rename; + gboolean supports_fsck; + gboolean supports_online_fsck; + gboolean supports_resize_enlarge; + gboolean supports_online_resize_enlarge; + gboolean supports_resize_shrink; + gboolean supports_online_resize_shrink; } Filesystem; -const Filesystem *daemon_local_get_fs_details (Daemon *daemon, - const gchar *filesystem_id); +const Filesystem *daemon_local_get_fs_details (Daemon *daemon, + const gchar *filesystem_id); /* exported methods */ -gboolean daemon_enumerate_adapters (Daemon *daemon, - DBusGMethodInvocation *context); - -gboolean daemon_enumerate_expanders (Daemon *daemon, - DBusGMethodInvocation *context); - -gboolean daemon_enumerate_ports (Daemon *daemon, - DBusGMethodInvocation *context); +gboolean daemon_enumerate_adapters (Daemon *daemon, + DBusGMethodInvocation *context); -gboolean daemon_enumerate_devices (Daemon *daemon, - DBusGMethodInvocation *context); +gboolean daemon_enumerate_expanders (Daemon *daemon, + DBusGMethodInvocation *context); -gboolean daemon_enumerate_device_files (Daemon *daemon, - DBusGMethodInvocation *context); +gboolean daemon_enumerate_ports (Daemon *daemon, + DBusGMethodInvocation *context); -gboolean daemon_find_device_by_device_file (Daemon *daemon, - const char *device_file, - DBusGMethodInvocation *context); +gboolean daemon_enumerate_devices (Daemon *daemon, + DBusGMethodInvocation *context); -gboolean daemon_find_device_by_major_minor (Daemon *daemon, - gint64 major, - gint64 minor, - DBusGMethodInvocation *context); +gboolean daemon_enumerate_device_files (Daemon *daemon, + DBusGMethodInvocation *context); -gboolean daemon_linux_md_start (Daemon *daemon, - GPtrArray *components, - char **options, +gboolean daemon_find_device_by_device_file (Daemon *daemon, + const char *device_file, + DBusGMethodInvocation *context); + +gboolean daemon_find_device_by_major_minor (Daemon *daemon, + gint64 major, + gint64 minor, + DBusGMethodInvocation *context); + +gboolean daemon_linux_md_start (Daemon *daemon, + GPtrArray *components, + char **options, + DBusGMethodInvocation *context); + +gboolean daemon_linux_md_create (Daemon *daemon, + GPtrArray *components, + char *level, + guint64 stripe_size, + char *name, + char **options, + DBusGMethodInvocation *context); + +gboolean daemon_drive_inhibit_all_polling (Daemon *daemon, + char **options, + DBusGMethodInvocation *context); + +gboolean daemon_drive_uninhibit_all_polling (Daemon *daemon, + char *cookie, DBusGMethodInvocation *context); -gboolean daemon_linux_md_create (Daemon *daemon, - GPtrArray *components, - char *level, - guint64 stripe_size, - char *name, - char **options, - DBusGMethodInvocation *context); +gboolean daemon_inhibit (Daemon *daemon, + DBusGMethodInvocation *context); -gboolean daemon_drive_inhibit_all_polling (Daemon *daemon, - char **options, - DBusGMethodInvocation *context); +gboolean daemon_uninhibit (Daemon *daemon, + char *cookie, + DBusGMethodInvocation *context); -gboolean daemon_drive_uninhibit_all_polling (Daemon *daemon, - char *cookie, - DBusGMethodInvocation *context); - -gboolean daemon_inhibit (Daemon *daemon, - DBusGMethodInvocation *context); - -gboolean daemon_uninhibit (Daemon *daemon, - char *cookie, - DBusGMethodInvocation *context); - -gboolean daemon_drive_set_all_spindown_timeouts (Daemon *daemon, - int timeout_seconds, - char **options, - DBusGMethodInvocation *context); +gboolean daemon_drive_set_all_spindown_timeouts (Daemon *daemon, + int timeout_seconds, + char **options, + DBusGMethodInvocation *context); -gboolean daemon_drive_unset_all_spindown_timeouts (Daemon *daemon, - char *cookie, - DBusGMethodInvocation *context); +gboolean daemon_drive_unset_all_spindown_timeouts (Daemon *daemon, + char *cookie, + DBusGMethodInvocation *context); G_END_DECLS diff --git a/src/device-private.c b/src/device-private.c index 795b14e..9137405 100644 --- a/src/device-private.c +++ b/src/device-private.c @@ -36,9 +36,7 @@ emit_changed_idle_cb (gpointer data) if (!device->priv->removed) { g_print ("**** EMITTING CHANGED for %s\n", device->priv->native_path); - g_signal_emit_by_name (device->priv->daemon, - "device-changed", - device->priv->object_path); + g_signal_emit_by_name (device->priv->daemon, "device-changed", device->priv->object_path); g_signal_emit_by_name (device, "changed"); } device->priv->emit_changed_idle_id = 0; @@ -48,24 +46,27 @@ emit_changed_idle_cb (gpointer data) } static void -emit_changed (Device *device, const gchar *name) +emit_changed (Device *device, + const gchar *name) { //g_debug ("property %s changed for %s", name, device->priv->device_file); if (device->priv->object_path != NULL) { /* schedule a 'changed' signal in idle if one hasn't been scheduled already */ - if (device->priv->emit_changed_idle_id == 0) { - device->priv->emit_changed_idle_id = g_idle_add_full (G_PRIORITY_DEFAULT, - emit_changed_idle_cb, - g_object_ref (device), - (GDestroyNotify) g_object_unref); - } + if (device->priv->emit_changed_idle_id == 0) + { + device->priv->emit_changed_idle_id = g_idle_add_full (G_PRIORITY_DEFAULT, + emit_changed_idle_cb, + g_object_ref (device), + (GDestroyNotify) g_object_unref); + } } } static gboolean -ptr_str_array_equals_strv (GPtrArray *a, GStrv b) +ptr_str_array_equals_strv (GPtrArray *a, + GStrv b) { guint n; guint b_len; @@ -81,7 +82,7 @@ ptr_str_array_equals_strv (GPtrArray *a, GStrv b) for (n = 0; n < a->len; n++) { if (g_strcmp0 ((gchar *) a->pdata[n], b[n]) != 0) - return FALSE; + return FALSE; } return TRUE; @@ -108,7 +109,8 @@ ptr_str_array_from_strv (GStrv s) } void -device_set_device_detection_time (Device *device, guint64 value) +device_set_device_detection_time (Device *device, + guint64 value) { if (G_UNLIKELY (device->priv->device_detection_time != value)) { @@ -118,7 +120,8 @@ device_set_device_detection_time (Device *device, guint64 value) } void -device_set_device_media_detection_time (Device *device, guint64 value) +device_set_device_media_detection_time (Device *device, + guint64 value) { if (G_UNLIKELY (device->priv->device_media_detection_time != value)) { @@ -128,7 +131,8 @@ device_set_device_media_detection_time (Device *device, guint64 value) } void -device_set_job_in_progress (Device *device, gboolean value) +device_set_job_in_progress (Device *device, + gboolean value) { if (G_UNLIKELY (device->priv->job_in_progress != value)) { @@ -138,7 +142,8 @@ device_set_job_in_progress (Device *device, gboolean value) } void -device_set_job_id (Device *device, const gchar *value) +device_set_job_id (Device *device, + const gchar *value) { if (G_UNLIKELY (g_strcmp0 (device->priv->job_id, value) != 0)) { @@ -149,7 +154,8 @@ device_set_job_id (Device *device, const gchar *value) } void -device_set_job_initiated_by_uid (Device *device, guint value) +device_set_job_initiated_by_uid (Device *device, + guint value) { if (G_UNLIKELY (device->priv->job_initiated_by_uid != value)) { @@ -159,7 +165,8 @@ device_set_job_initiated_by_uid (Device *device, guint value) } void -device_set_job_is_cancellable (Device *device, gboolean value) +device_set_job_is_cancellable (Device *device, + gboolean value) { if (G_UNLIKELY (device->priv->job_is_cancellable != value)) { @@ -169,7 +176,8 @@ device_set_job_is_cancellable (Device *device, gboolean value) } void -device_set_job_percentage (Device *device, gdouble value) +device_set_job_percentage (Device *device, + gdouble value) { if (G_UNLIKELY (device->priv->job_percentage != value)) { @@ -179,7 +187,8 @@ device_set_job_percentage (Device *device, gdouble value) } void -device_set_device_file (Device *device, const gchar *value) +device_set_device_file (Device *device, + const gchar *value) { if (G_UNLIKELY (g_strcmp0 (device->priv->device_file, value) != 0)) { @@ -190,7 +199,8 @@ device_set_device_file (Device *device, const gchar *value) } void -device_set_device_file_by_id (Device *device, GStrv value) +device_set_device_file_by_id (Device *device, + GStrv value) { if (G_UNLIKELY (!ptr_str_array_equals_strv (device->priv->device_file_by_id, value))) { @@ -201,7 +211,8 @@ device_set_device_file_by_id (Device *device, GStrv value) } void -device_set_device_file_by_path (Device *device, GStrv value) +device_set_device_file_by_path (Device *device, + GStrv value) { if (G_UNLIKELY (!ptr_str_array_equals_strv (device->priv->device_file_by_path, value))) { @@ -212,7 +223,8 @@ device_set_device_file_by_path (Device *device, GStrv value) } void -device_set_device_is_system_internal (Device *device, gboolean value) +device_set_device_is_system_internal (Device *device, + gboolean value) { if (G_UNLIKELY (device->priv->device_is_system_internal != value)) { @@ -222,7 +234,8 @@ device_set_device_is_system_internal (Device *device, gboolean value) } void -device_set_device_is_partition (Device *device, gboolean value) +device_set_device_is_partition (Device *device, + gboolean value) { if (G_UNLIKELY (device->priv->device_is_partition != value)) { @@ -232,7 +245,8 @@ device_set_device_is_partition (Device *device, gboolean value) } void -device_set_device_is_partition_table (Device *device, gboolean value) +device_set_device_is_partition_table (Device *device, + gboolean value) { if (G_UNLIKELY (device->priv->device_is_partition_table != value)) { @@ -242,7 +256,8 @@ device_set_device_is_partition_table (Device *device, gboolean value) } void -device_set_device_is_removable (Device *device, gboolean value) +device_set_device_is_removable (Device *device, + gboolean value) { if (G_UNLIKELY (device->priv->device_is_removable != value)) { @@ -252,7 +267,8 @@ device_set_device_is_removable (Device *device, gboolean value) } void -device_set_device_is_media_available (Device *device, gboolean value) +device_set_device_is_media_available (Device *device, + gboolean value) { if (G_UNLIKELY (device->priv->device_is_media_available != value)) { @@ -262,7 +278,8 @@ device_set_device_is_media_available (Device *device, gboolean value) } void -device_set_device_is_media_change_detected (Device *device, gboolean value) +device_set_device_is_media_change_detected (Device *device, + gboolean value) { if (G_UNLIKELY (device->priv->device_is_media_change_detected != value)) { @@ -272,7 +289,8 @@ device_set_device_is_media_change_detected (Device *device, gboolean value) } void -device_set_device_is_media_change_detection_polling (Device *device, gboolean value) +device_set_device_is_media_change_detection_polling (Device *device, + gboolean value) { if (G_UNLIKELY (device->priv->device_is_media_change_detection_polling != value)) { @@ -282,7 +300,8 @@ device_set_device_is_media_change_detection_polling (Device *device, gboolean va } void -device_set_device_is_media_change_detection_inhibitable (Device *device, gboolean value) +device_set_device_is_media_change_detection_inhibitable (Device *device, + gboolean value) { if (G_UNLIKELY (device->priv->device_is_media_change_detection_inhibitable != value)) { @@ -292,7 +311,8 @@ device_set_device_is_media_change_detection_inhibitable (Device *device, gboolea } void -device_set_device_is_media_change_detection_inhibited (Device *device, gboolean value) +device_set_device_is_media_change_detection_inhibited (Device *device, + gboolean value) { if (G_UNLIKELY (device->priv->device_is_media_change_detection_inhibited != value)) { @@ -302,7 +322,8 @@ device_set_device_is_media_change_detection_inhibited (Device *device, gboolean } void -device_set_device_is_read_only (Device *device, gboolean value) +device_set_device_is_read_only (Device *device, + gboolean value) { if (G_UNLIKELY (device->priv->device_is_read_only != value)) { @@ -312,7 +333,8 @@ device_set_device_is_read_only (Device *device, gboolean value) } void -device_set_device_is_drive (Device *device, gboolean value) +device_set_device_is_drive (Device *device, + gboolean value) { if (G_UNLIKELY (device->priv->device_is_drive != value)) { @@ -322,7 +344,8 @@ device_set_device_is_drive (Device *device, gboolean value) } void -device_set_device_is_optical_disc (Device *device, gboolean value) +device_set_device_is_optical_disc (Device *device, + gboolean value) { if (G_UNLIKELY (device->priv->device_is_optical_disc != value)) { @@ -332,7 +355,8 @@ device_set_device_is_optical_disc (Device *device, gboolean value) } void -device_set_device_is_luks (Device *device, gboolean value) +device_set_device_is_luks (Device *device, + gboolean value) { if (G_UNLIKELY (device->priv->device_is_luks != value)) { @@ -342,7 +366,8 @@ device_set_device_is_luks (Device *device, gboolean value) } void -device_set_device_is_luks_cleartext (Device *device, gboolean value) +device_set_device_is_luks_cleartext (Device *device, + gboolean value) { if (G_UNLIKELY (device->priv->device_is_luks_cleartext != value)) { @@ -352,7 +377,8 @@ device_set_device_is_luks_cleartext (Device *device, gboolean value) } void -device_set_device_is_linux_md_component (Device *device, gboolean value) +device_set_device_is_linux_md_component (Device *device, + gboolean value) { if (G_UNLIKELY (device->priv->device_is_linux_md_component != value)) { @@ -362,7 +388,8 @@ device_set_device_is_linux_md_component (Device *device, gboolean value) } void -device_set_device_is_linux_md (Device *device, gboolean value) +device_set_device_is_linux_md (Device *device, + gboolean value) { if (G_UNLIKELY (device->priv->device_is_linux_md != value)) { @@ -372,7 +399,8 @@ device_set_device_is_linux_md (Device *device, gboolean value) } void -device_set_device_size (Device *device, guint64 value) +device_set_device_size (Device *device, + guint64 value) { if (G_UNLIKELY (device->priv->device_size != value)) { @@ -382,7 +410,8 @@ device_set_device_size (Device *device, guint64 value) } void -device_set_device_block_size (Device *device, guint64 value) +device_set_device_block_size (Device *device, + guint64 value) { if (G_UNLIKELY (device->priv->device_block_size != value)) { @@ -392,7 +421,8 @@ device_set_device_block_size (Device *device, guint64 value) } void -device_set_device_is_mounted (Device *device, gboolean value) +device_set_device_is_mounted (Device *device, + gboolean value) { if (G_UNLIKELY (device->priv->device_is_mounted != value)) { @@ -402,7 +432,8 @@ device_set_device_is_mounted (Device *device, gboolean value) } void -device_set_device_mount_paths (Device *device, GStrv value) +device_set_device_mount_paths (Device *device, + GStrv value) { if (G_UNLIKELY (!ptr_str_array_equals_strv (device->priv->device_mount_paths, value))) { @@ -413,7 +444,8 @@ device_set_device_mount_paths (Device *device, GStrv value) } void -device_set_device_presentation_hide (Device *device, gboolean value) +device_set_device_presentation_hide (Device *device, + gboolean value) { if (G_UNLIKELY (device->priv->device_presentation_hide != value)) { @@ -423,7 +455,8 @@ device_set_device_presentation_hide (Device *device, gboolean value) } void -device_set_device_presentation_nopolicy (Device *device, gboolean value) +device_set_device_presentation_nopolicy (Device *device, + gboolean value) { if (G_UNLIKELY (device->priv->device_presentation_nopolicy != value)) { @@ -433,7 +466,8 @@ device_set_device_presentation_nopolicy (Device *device, gboolean value) } void -device_set_device_presentation_name (Device *device, const gchar *value) +device_set_device_presentation_name (Device *device, + const gchar *value) { if (G_UNLIKELY (g_strcmp0 (device->priv->device_presentation_name, value) != 0)) { @@ -444,7 +478,8 @@ device_set_device_presentation_name (Device *device, const gchar *value) } void -device_set_device_presentation_icon_name (Device *device, const gchar *value) +device_set_device_presentation_icon_name (Device *device, + const gchar *value) { if (G_UNLIKELY (g_strcmp0 (device->priv->device_presentation_icon_name, value) != 0)) { @@ -455,7 +490,8 @@ device_set_device_presentation_icon_name (Device *device, const gchar *value) } void -device_set_device_mounted_by_uid (Device *device, guint value) +device_set_device_mounted_by_uid (Device *device, + guint value) { if (G_UNLIKELY (device->priv->device_mounted_by_uid != value)) { @@ -465,7 +501,8 @@ device_set_device_mounted_by_uid (Device *device, guint value) } void -device_set_id_usage (Device *device, const gchar *value) +device_set_id_usage (Device *device, + const gchar *value) { if (G_UNLIKELY (g_strcmp0 (device->priv->id_usage, value) != 0)) { @@ -476,7 +513,8 @@ device_set_id_usage (Device *device, const gchar *value) } void -device_set_id_type (Device *device, const gchar *value) +device_set_id_type (Device *device, + const gchar *value) { if (G_UNLIKELY (g_strcmp0 (device->priv->id_type, value) != 0)) { @@ -487,7 +525,8 @@ device_set_id_type (Device *device, const gchar *value) } void -device_set_id_version (Device *device, const gchar *value) +device_set_id_version (Device *device, + const gchar *value) { if (G_UNLIKELY (g_strcmp0 (device->priv->id_version, value) != 0)) { @@ -498,7 +537,8 @@ device_set_id_version (Device *device, const gchar *value) } void -device_set_id_uuid (Device *device, const gchar *value) +device_set_id_uuid (Device *device, + const gchar *value) { if (G_UNLIKELY (g_strcmp0 (device->priv->id_uuid, value) != 0)) { @@ -509,7 +549,8 @@ device_set_id_uuid (Device *device, const gchar *value) } void -device_set_id_label (Device *device, const gchar *value) +device_set_id_label (Device *device, + const gchar *value) { if (G_UNLIKELY (g_strcmp0 (device->priv->id_label, value) != 0)) { @@ -520,7 +561,8 @@ device_set_id_label (Device *device, const gchar *value) } void -device_set_partition_slave (Device *device, const gchar *value) +device_set_partition_slave (Device *device, + const gchar *value) { if (G_UNLIKELY (g_strcmp0 (device->priv->partition_slave, value) != 0)) { @@ -531,7 +573,8 @@ device_set_partition_slave (Device *device, const gchar *value) } void -device_set_partition_scheme (Device *device, const gchar *value) +device_set_partition_scheme (Device *device, + const gchar *value) { if (G_UNLIKELY (g_strcmp0 (device->priv->partition_scheme, value) != 0)) { @@ -542,7 +585,8 @@ device_set_partition_scheme (Device *device, const gchar *value) } void -device_set_partition_type (Device *device, const gchar *value) +device_set_partition_type (Device *device, + const gchar *value) { if (G_UNLIKELY (g_strcmp0 (device->priv->partition_type, value) != 0)) { @@ -553,7 +597,8 @@ device_set_partition_type (Device *device, const gchar *value) } void -device_set_partition_label (Device *device, const gchar *value) +device_set_partition_label (Device *device, + const gchar *value) { if (G_UNLIKELY (g_strcmp0 (device->priv->partition_label, value) != 0)) { @@ -564,7 +609,8 @@ device_set_partition_label (Device *device, const gchar *value) } void -device_set_partition_uuid (Device *device, const gchar *value) +device_set_partition_uuid (Device *device, + const gchar *value) { if (G_UNLIKELY (g_strcmp0 (device->priv->partition_uuid, value) != 0)) { @@ -575,7 +621,8 @@ device_set_partition_uuid (Device *device, const gchar *value) } void -device_set_partition_flags (Device *device, GStrv value) +device_set_partition_flags (Device *device, + GStrv value) { if (G_UNLIKELY (!ptr_str_array_equals_strv (device->priv->partition_flags, value))) { @@ -586,7 +633,8 @@ device_set_partition_flags (Device *device, GStrv value) } void -device_set_partition_number (Device *device, gint value) +device_set_partition_number (Device *device, + gint value) { if (G_UNLIKELY (device->priv->partition_number != value)) { @@ -596,7 +644,8 @@ device_set_partition_number (Device *device, gint value) } void -device_set_partition_offset (Device *device, guint64 value) +device_set_partition_offset (Device *device, + guint64 value) { if (G_UNLIKELY (device->priv->partition_offset != value)) { @@ -606,7 +655,8 @@ device_set_partition_offset (Device *device, guint64 value) } void -device_set_partition_size (Device *device, guint64 value) +device_set_partition_size (Device *device, + guint64 value) { if (G_UNLIKELY (device->priv->partition_size != value)) { @@ -616,7 +666,8 @@ device_set_partition_size (Device *device, guint64 value) } void -device_set_partition_table_scheme (Device *device, const gchar *value) +device_set_partition_table_scheme (Device *device, + const gchar *value) { if (G_UNLIKELY (g_strcmp0 (device->priv->partition_table_scheme, value) != 0)) { @@ -627,7 +678,8 @@ device_set_partition_table_scheme (Device *device, const gchar *value) } void -device_set_partition_table_count (Device *device, gint value) +device_set_partition_table_count (Device *device, + gint value) { if (G_UNLIKELY (device->priv->partition_table_count != value)) { @@ -637,7 +689,8 @@ device_set_partition_table_count (Device *device, gint value) } void -device_set_drive_vendor (Device *device, const gchar *value) +device_set_drive_vendor (Device *device, + const gchar *value) { if (G_UNLIKELY (g_strcmp0 (device->priv->drive_vendor, value) != 0)) { @@ -648,7 +701,8 @@ device_set_drive_vendor (Device *device, const gchar *value) } void -device_set_drive_model (Device *device, const gchar *value) +device_set_drive_model (Device *device, + const gchar *value) { if (G_UNLIKELY (g_strcmp0 (device->priv->drive_model, value) != 0)) { @@ -659,7 +713,8 @@ device_set_drive_model (Device *device, const gchar *value) } void -device_set_drive_revision (Device *device, const gchar *value) +device_set_drive_revision (Device *device, + const gchar *value) { if (G_UNLIKELY (g_strcmp0 (device->priv->drive_revision, value) != 0)) { @@ -670,7 +725,8 @@ device_set_drive_revision (Device *device, const gchar *value) } void -device_set_drive_serial (Device *device, const gchar *value) +device_set_drive_serial (Device *device, + const gchar *value) { if (G_UNLIKELY (g_strcmp0 (device->priv->drive_serial, value) != 0)) { @@ -681,7 +737,8 @@ device_set_drive_serial (Device *device, const gchar *value) } void -device_set_drive_wwn (Device *device, const gchar *value) +device_set_drive_wwn (Device *device, + const gchar *value) { if (G_UNLIKELY (g_strcmp0 (device->priv->drive_wwn, value) != 0)) { @@ -692,7 +749,8 @@ device_set_drive_wwn (Device *device, const gchar *value) } void -device_set_drive_connection_interface (Device *device, const gchar *value) +device_set_drive_connection_interface (Device *device, + const gchar *value) { if (G_UNLIKELY (g_strcmp0 (device->priv->drive_connection_interface, value) != 0)) { @@ -703,7 +761,8 @@ device_set_drive_connection_interface (Device *device, const gchar *value) } void -device_set_drive_connection_speed (Device *device, guint value) +device_set_drive_connection_speed (Device *device, + guint value) { if (G_UNLIKELY (device->priv->drive_connection_speed != value)) { @@ -713,7 +772,8 @@ device_set_drive_connection_speed (Device *device, guint value) } void -device_set_drive_media_compatibility (Device *device, GStrv value) +device_set_drive_media_compatibility (Device *device, + GStrv value) { if (G_UNLIKELY (!ptr_str_array_equals_strv (device->priv->drive_media_compatibility, value))) { @@ -724,7 +784,8 @@ device_set_drive_media_compatibility (Device *device, GStrv value) } void -device_set_drive_media (Device *device, const gchar *value) +device_set_drive_media (Device *device, + const gchar *value) { if (G_UNLIKELY (g_strcmp0 (device->priv->drive_media, value) != 0)) { @@ -735,7 +796,8 @@ device_set_drive_media (Device *device, const gchar *value) } void -device_set_drive_is_media_ejectable (Device *device, gboolean value) +device_set_drive_is_media_ejectable (Device *device, + gboolean value) { if (G_UNLIKELY (device->priv->drive_is_media_ejectable != value)) { @@ -745,7 +807,8 @@ device_set_drive_is_media_ejectable (Device *device, gboolean value) } void -device_set_drive_can_detach (Device *device, gboolean value) +device_set_drive_can_detach (Device *device, + gboolean value) { if (G_UNLIKELY (device->priv->drive_can_detach != value)) { @@ -755,7 +818,8 @@ device_set_drive_can_detach (Device *device, gboolean value) } void -device_set_drive_can_spindown (Device *device, gboolean value) +device_set_drive_can_spindown (Device *device, + gboolean value) { if (G_UNLIKELY (device->priv->drive_can_spindown != value)) { @@ -765,7 +829,8 @@ device_set_drive_can_spindown (Device *device, gboolean value) } void -device_set_drive_is_rotational (Device *device, gboolean value) +device_set_drive_is_rotational (Device *device, + gboolean value) { if (G_UNLIKELY (device->priv->drive_is_rotational != value)) { @@ -775,7 +840,8 @@ device_set_drive_is_rotational (Device *device, gboolean value) } void -device_set_drive_rotation_rate (Device *device, guint value) +device_set_drive_rotation_rate (Device *device, + guint value) { if (G_UNLIKELY (device->priv->drive_rotation_rate != value)) { @@ -785,7 +851,8 @@ device_set_drive_rotation_rate (Device *device, guint value) } void -device_set_drive_write_cache (Device *device, const gchar *value) +device_set_drive_write_cache (Device *device, + const gchar *value) { if (G_UNLIKELY (g_strcmp0 (device->priv->drive_write_cache, value) != 0)) { @@ -796,7 +863,8 @@ device_set_drive_write_cache (Device *device, const gchar *value) } void -device_set_drive_adapter (Device *device, const gchar *value) +device_set_drive_adapter (Device *device, + const gchar *value) { if (G_UNLIKELY (g_strcmp0 (device->priv->drive_adapter, value) != 0)) { @@ -807,7 +875,8 @@ device_set_drive_adapter (Device *device, const gchar *value) } void -device_set_drive_ports (Device *device, GStrv value) +device_set_drive_ports (Device *device, + GStrv value) { if (G_UNLIKELY (!ptr_str_array_equals_strv (device->priv->drive_ports, value))) { @@ -818,7 +887,8 @@ device_set_drive_ports (Device *device, GStrv value) } void -device_set_optical_disc_is_blank (Device *device, gboolean value) +device_set_optical_disc_is_blank (Device *device, + gboolean value) { if (G_UNLIKELY (device->priv->optical_disc_is_blank != value)) { @@ -828,7 +898,8 @@ device_set_optical_disc_is_blank (Device *device, gboolean value) } void -device_set_optical_disc_is_appendable (Device *device, gboolean value) +device_set_optical_disc_is_appendable (Device *device, + gboolean value) { if (G_UNLIKELY (device->priv->optical_disc_is_appendable != value)) { @@ -838,7 +909,8 @@ device_set_optical_disc_is_appendable (Device *device, gboolean value) } void -device_set_optical_disc_is_closed (Device *device, gboolean value) +device_set_optical_disc_is_closed (Device *device, + gboolean value) { if (G_UNLIKELY (device->priv->optical_disc_is_closed != value)) { @@ -848,7 +920,8 @@ device_set_optical_disc_is_closed (Device *device, gboolean value) } void -device_set_optical_disc_num_tracks (Device *device, guint value) +device_set_optical_disc_num_tracks (Device *device, + guint value) { if (G_UNLIKELY (device->priv->optical_disc_num_tracks != value)) { @@ -858,7 +931,8 @@ device_set_optical_disc_num_tracks (Device *device, guint value) } void -device_set_optical_disc_num_audio_tracks (Device *device, guint value) +device_set_optical_disc_num_audio_tracks (Device *device, + guint value) { if (G_UNLIKELY (device->priv->optical_disc_num_audio_tracks != value)) { @@ -868,7 +942,8 @@ device_set_optical_disc_num_audio_tracks (Device *device, guint value) } void -device_set_optical_disc_num_sessions (Device *device, guint value) +device_set_optical_disc_num_sessions (Device *device, + guint value) { if (G_UNLIKELY (device->priv->optical_disc_num_sessions != value)) { @@ -878,7 +953,8 @@ device_set_optical_disc_num_sessions (Device *device, guint value) } void -device_set_luks_holder (Device *device, const gchar *value) +device_set_luks_holder (Device *device, + const gchar *value) { if (G_UNLIKELY (g_strcmp0 (device->priv->luks_holder, value) != 0)) { @@ -889,7 +965,8 @@ device_set_luks_holder (Device *device, const gchar *value) } void -device_set_luks_cleartext_slave (Device *device, const gchar *value) +device_set_luks_cleartext_slave (Device *device, + const gchar *value) { if (G_UNLIKELY (g_strcmp0 (device->priv->luks_cleartext_slave, value) != 0)) { @@ -900,7 +977,8 @@ device_set_luks_cleartext_slave (Device *device, const gchar *value) } void -device_set_luks_cleartext_unlocked_by_uid (Device *device, guint value) +device_set_luks_cleartext_unlocked_by_uid (Device *device, + guint value) { if (G_UNLIKELY (device->priv->luks_cleartext_unlocked_by_uid != value)) { @@ -910,7 +988,8 @@ device_set_luks_cleartext_unlocked_by_uid (Device *device, guint value) } void -device_set_linux_md_component_level (Device *device, const gchar *value) +device_set_linux_md_component_level (Device *device, + const gchar *value) { if (G_UNLIKELY (g_strcmp0 (device->priv->linux_md_component_level, value) != 0)) { @@ -921,7 +1000,8 @@ device_set_linux_md_component_level (Device *device, const gchar *value) } void -device_set_linux_md_component_position (Device *device, gint value) +device_set_linux_md_component_position (Device *device, + gint value) { if (G_UNLIKELY (device->priv->linux_md_component_position != value)) { @@ -931,7 +1011,8 @@ device_set_linux_md_component_position (Device *device, gint value) } void -device_set_linux_md_component_num_raid_devices (Device *device, gint value) +device_set_linux_md_component_num_raid_devices (Device *device, + gint value) { if (G_UNLIKELY (device->priv->linux_md_component_num_raid_devices != value)) { @@ -941,7 +1022,8 @@ device_set_linux_md_component_num_raid_devices (Device *device, gint value) } void -device_set_linux_md_component_uuid (Device *device, const gchar *value) +device_set_linux_md_component_uuid (Device *device, + const gchar *value) { if (G_UNLIKELY (g_strcmp0 (device->priv->linux_md_component_uuid, value) != 0)) { @@ -952,7 +1034,8 @@ device_set_linux_md_component_uuid (Device *device, const gchar *value) } void -device_set_linux_md_component_home_host (Device *device, const gchar *value) +device_set_linux_md_component_home_host (Device *device, + const gchar *value) { if (G_UNLIKELY (g_strcmp0 (device->priv->linux_md_component_home_host, value) != 0)) { @@ -963,7 +1046,8 @@ device_set_linux_md_component_home_host (Device *device, const gchar *value) } void -device_set_linux_md_component_name (Device *device, const gchar *value) +device_set_linux_md_component_name (Device *device, + const gchar *value) { if (G_UNLIKELY (g_strcmp0 (device->priv->linux_md_component_name, value) != 0)) { @@ -974,7 +1058,8 @@ device_set_linux_md_component_name (Device *device, const gchar *value) } void -device_set_linux_md_component_version (Device *device, const gchar *value) +device_set_linux_md_component_version (Device *device, + const gchar *value) { if (G_UNLIKELY (g_strcmp0 (device->priv->linux_md_component_version, value) != 0)) { @@ -985,7 +1070,8 @@ device_set_linux_md_component_version (Device *device, const gchar *value) } void -device_set_linux_md_component_holder (Device *device, const gchar *value) +device_set_linux_md_component_holder (Device *device, + const gchar *value) { if (G_UNLIKELY (g_strcmp0 (device->priv->linux_md_component_holder, value) != 0)) { @@ -996,7 +1082,8 @@ device_set_linux_md_component_holder (Device *device, const gchar *value) } void -device_set_linux_md_component_state (Device *device, GStrv value) +device_set_linux_md_component_state (Device *device, + GStrv value) { if (G_UNLIKELY (!ptr_str_array_equals_strv (device->priv->linux_md_component_state, value))) { @@ -1007,7 +1094,8 @@ device_set_linux_md_component_state (Device *device, GStrv value) } void -device_set_linux_md_state (Device *device, const gchar *value) +device_set_linux_md_state (Device *device, + const gchar *value) { if (G_UNLIKELY (g_strcmp0 (device->priv->linux_md_state, value) != 0)) { @@ -1018,7 +1106,8 @@ device_set_linux_md_state (Device *device, const gchar *value) } void -device_set_linux_md_level (Device *device, const gchar *value) +device_set_linux_md_level (Device *device, + const gchar *value) { if (G_UNLIKELY (g_strcmp0 (device->priv->linux_md_level, value) != 0)) { @@ -1029,7 +1118,8 @@ device_set_linux_md_level (Device *device, const gchar *value) } void -device_set_linux_md_num_raid_devices (Device *device, gint value) +device_set_linux_md_num_raid_devices (Device *device, + gint value) { if (G_UNLIKELY (device->priv->linux_md_num_raid_devices != value)) { @@ -1039,7 +1129,8 @@ device_set_linux_md_num_raid_devices (Device *device, gint value) } void -device_set_linux_md_uuid (Device *device, const gchar *value) +device_set_linux_md_uuid (Device *device, + const gchar *value) { if (G_UNLIKELY (g_strcmp0 (device->priv->linux_md_uuid, value) != 0)) { @@ -1050,7 +1141,8 @@ device_set_linux_md_uuid (Device *device, const gchar *value) } void -device_set_linux_md_home_host (Device *device, const gchar *value) +device_set_linux_md_home_host (Device *device, + const gchar *value) { if (G_UNLIKELY (g_strcmp0 (device->priv->linux_md_home_host, value) != 0)) { @@ -1061,7 +1153,8 @@ device_set_linux_md_home_host (Device *device, const gchar *value) } void -device_set_linux_md_name (Device *device, const gchar *value) +device_set_linux_md_name (Device *device, + const gchar *value) { if (G_UNLIKELY (g_strcmp0 (device->priv->linux_md_name, value) != 0)) { @@ -1072,7 +1165,8 @@ device_set_linux_md_name (Device *device, const gchar *value) } void -device_set_linux_md_version (Device *device, const gchar *value) +device_set_linux_md_version (Device *device, + const gchar *value) { if (G_UNLIKELY (g_strcmp0 (device->priv->linux_md_version, value) != 0)) { @@ -1083,7 +1177,8 @@ device_set_linux_md_version (Device *device, const gchar *value) } void -device_set_linux_md_slaves (Device *device, GStrv value) +device_set_linux_md_slaves (Device *device, + GStrv value) { if (G_UNLIKELY (!ptr_str_array_equals_strv (device->priv->linux_md_slaves, value))) { @@ -1094,7 +1189,8 @@ device_set_linux_md_slaves (Device *device, GStrv value) } void -device_set_linux_md_is_degraded (Device *device, gboolean value) +device_set_linux_md_is_degraded (Device *device, + gboolean value) { if (G_UNLIKELY (device->priv->linux_md_is_degraded != value)) { @@ -1104,7 +1200,8 @@ device_set_linux_md_is_degraded (Device *device, gboolean value) } void -device_set_linux_md_sync_action (Device *device, const gchar *value) +device_set_linux_md_sync_action (Device *device, + const gchar *value) { if (G_UNLIKELY (g_strcmp0 (device->priv->linux_md_sync_action, value) != 0)) { @@ -1115,7 +1212,8 @@ device_set_linux_md_sync_action (Device *device, const gchar *value) } void -device_set_linux_md_sync_percentage (Device *device, gdouble value) +device_set_linux_md_sync_percentage (Device *device, + gdouble value) { if (G_UNLIKELY (device->priv->linux_md_sync_percentage != value)) { @@ -1125,7 +1223,8 @@ device_set_linux_md_sync_percentage (Device *device, gdouble value) } void -device_set_linux_md_sync_speed (Device *device, guint64 value) +device_set_linux_md_sync_speed (Device *device, + guint64 value) { if (G_UNLIKELY (device->priv->linux_md_sync_speed != value)) { @@ -1135,7 +1234,8 @@ device_set_linux_md_sync_speed (Device *device, guint64 value) } void -device_set_dm_name (Device *device, const gchar *value) +device_set_dm_name (Device *device, + const gchar *value) { if (G_UNLIKELY (g_strcmp0 (device->priv->dm_name, value) != 0)) { @@ -1146,7 +1246,8 @@ device_set_dm_name (Device *device, const gchar *value) } void -device_set_slaves_objpath (Device *device, GStrv value) +device_set_slaves_objpath (Device *device, + GStrv value) { if (G_UNLIKELY (!ptr_str_array_equals_strv (device->priv->slaves_objpath, value))) { @@ -1157,7 +1258,8 @@ device_set_slaves_objpath (Device *device, GStrv value) } void -device_set_holders_objpath (Device *device, GStrv value) +device_set_holders_objpath (Device *device, + GStrv value) { if (G_UNLIKELY (!ptr_str_array_equals_strv (device->priv->holders_objpath, value))) { @@ -1167,9 +1269,9 @@ device_set_holders_objpath (Device *device, GStrv value) } } - void -device_set_drive_ata_smart_is_available (Device *device, gboolean value) +device_set_drive_ata_smart_is_available (Device *device, + gboolean value) { if (G_UNLIKELY (device->priv->drive_ata_smart_is_available != value)) { @@ -1179,7 +1281,8 @@ device_set_drive_ata_smart_is_available (Device *device, gboolean value) } void -device_set_drive_ata_smart_time_collected (Device *device, guint64 value) +device_set_drive_ata_smart_time_collected (Device *device, + guint64 value) { if (G_UNLIKELY (device->priv->drive_ata_smart_time_collected != value)) { @@ -1189,7 +1292,8 @@ device_set_drive_ata_smart_time_collected (Device *device, guint64 value) } void -device_set_drive_ata_smart_status (Device *device, SkSmartOverall value) +device_set_drive_ata_smart_status (Device *device, + SkSmartOverall value) { if (G_UNLIKELY (device->priv->drive_ata_smart_status != value)) { @@ -1199,7 +1303,9 @@ device_set_drive_ata_smart_status (Device *device, SkSmartOverall value) } void -device_set_drive_ata_smart_blob_steal (Device *device, gchar *blob, gsize blob_size) +device_set_drive_ata_smart_blob_steal (Device *device, + gchar *blob, + gsize blob_size) { /* TODO: compare? Not really needed, this happens very rarely */ diff --git a/src/device-private.h b/src/device-private.h index de9ef76..37765ad 100644 --- a/src/device-private.h +++ b/src/device-private.h @@ -40,174 +40,174 @@ typedef struct Job Job; struct DevicePrivate { - DBusGConnection *system_bus_connection; - Daemon *daemon; - GUdevDevice *d; - - Job *job; - - char *object_path; - char *native_path; - guint64 device_detection_time; - guint64 device_media_detection_time; - - gboolean removed; - - gboolean job_in_progress; - char *job_id; - uid_t job_initiated_by_uid; - gboolean job_is_cancellable; - double job_percentage; - - guint linux_md_poll_timeout_id; - - /* A list of current polling inhibitors (Inhibitor objects) */ - GList *polling_inhibitors; - - /* if non-zero, the id of the idle for emitting a 'change' signal */ - guint emit_changed_idle_id; - - /*****************/ - /* Disk spindown */ - /*****************/ - - /* A list of current spindown configurators (Inhibitor objects) - * - * Each object will have a data element, @spindown-timeout-seconds, that is - * the requested timeout for the inhibitor in question. It can be read via - * - * GPOINTER_TO_INT (g_object_get_data (G_OBJECT (inhibitor), "spindown-timeout-seconds")); - */ - GList *spindown_inhibitors; - - /* The timeout the disk is currently configured with, in seconds. This is 0 if spindown - * is not enabled. Depending on the command-set used, a slightly different rounded value - * may have been sent to the disk - for example, the ATA command-set has a rather peculiar - * mapping, see the hdparm(1) man-page, option -S. - * - * This value is computed by considering all per-disk spindown inhibitors (set - * via the DriveSetSpindownTimeout() method on the device) and all global spindown - * inhibitors (set via the DriveSetAllSpindownTimeouts() method on the daemon). - */ - gint spindown_timeout; - - /**************/ - /* Properties */ - /**************/ - - char *device_file; - dev_t dev; - GPtrArray *device_file_by_id; - GPtrArray *device_file_by_path; - gboolean device_is_system_internal; - gboolean device_is_partition; - gboolean device_is_partition_table; - gboolean device_is_removable; - gboolean device_is_media_available; - gboolean device_is_media_change_detected; - gboolean device_is_media_change_detection_polling; - gboolean device_is_media_change_detection_inhibitable; - gboolean device_is_media_change_detection_inhibited; - gboolean device_is_read_only; - gboolean device_is_drive; - gboolean device_is_optical_disc; - gboolean device_is_luks; - gboolean device_is_luks_cleartext; - gboolean device_is_linux_md_component; - gboolean device_is_linux_md; - guint64 device_size; - guint64 device_block_size; - gboolean device_is_mounted; - GPtrArray *device_mount_paths; - uid_t device_mounted_by_uid; - gboolean device_presentation_hide; - gboolean device_presentation_nopolicy; - char *device_presentation_name; - char *device_presentation_icon_name; - - char *id_usage; - char *id_type; - char *id_version; - char *id_uuid; - char *id_label; - - char *partition_slave; - char *partition_scheme; - char *partition_type; - char *partition_label; - char *partition_uuid; - GPtrArray *partition_flags; - int partition_number; - guint64 partition_offset; - guint64 partition_size; - - char *partition_table_scheme; - int partition_table_count; - - char *drive_vendor; - char *drive_model; - char *drive_revision; - char *drive_serial; - char *drive_wwn; - char *drive_connection_interface; - guint drive_connection_speed; - GPtrArray *drive_media_compatibility; - char *drive_media; - gboolean drive_is_media_ejectable; - gboolean drive_can_detach; - gboolean drive_can_spindown; - gboolean drive_is_rotational; - guint drive_rotation_rate; - char *drive_write_cache; - char *drive_adapter; - GPtrArray *drive_ports; - - gboolean optical_disc_is_blank; - gboolean optical_disc_is_appendable; - gboolean optical_disc_is_closed; - guint optical_disc_num_tracks; - guint optical_disc_num_audio_tracks; - guint optical_disc_num_sessions; - - char *luks_holder; - - char *luks_cleartext_slave; - uid_t luks_cleartext_unlocked_by_uid; - - char *linux_md_component_level; - int linux_md_component_position; - int linux_md_component_num_raid_devices; - char *linux_md_component_uuid; - char *linux_md_component_home_host; - char *linux_md_component_name; - char *linux_md_component_version; - char *linux_md_component_holder; - GPtrArray *linux_md_component_state; - - char *linux_md_state; - char *linux_md_level; - int linux_md_num_raid_devices; - char *linux_md_uuid; - char *linux_md_home_host; - char *linux_md_name; - char *linux_md_version; - GPtrArray *linux_md_slaves; - GPtrArray *linux_md_slaves_state; - gboolean linux_md_is_degraded; - char *linux_md_sync_action; - double linux_md_sync_percentage; - guint64 linux_md_sync_speed; - - gboolean drive_ata_smart_is_available; - guint64 drive_ata_smart_time_collected; - SkSmartOverall drive_ata_smart_status; - void *drive_ata_smart_blob; - gsize drive_ata_smart_blob_size; - - /* the following properties are not (yet) exported */ - char *dm_name; - GPtrArray *slaves_objpath; - GPtrArray *holders_objpath; + DBusGConnection *system_bus_connection; + Daemon *daemon; + GUdevDevice *d; + + Job *job; + + char *object_path; + char *native_path; + guint64 device_detection_time; + guint64 device_media_detection_time; + + gboolean removed; + + gboolean job_in_progress; + char *job_id; + uid_t job_initiated_by_uid; + gboolean job_is_cancellable; + double job_percentage; + + guint linux_md_poll_timeout_id; + + /* A list of current polling inhibitors (Inhibitor objects) */ + GList *polling_inhibitors; + + /* if non-zero, the id of the idle for emitting a 'change' signal */ + guint emit_changed_idle_id; + + /*****************/ + /* Disk spindown */ + /*****************/ + + /* A list of current spindown configurators (Inhibitor objects) + * + * Each object will have a data element, @spindown-timeout-seconds, that is + * the requested timeout for the inhibitor in question. It can be read via + * + * GPOINTER_TO_INT (g_object_get_data (G_OBJECT (inhibitor), "spindown-timeout-seconds")); + */ + GList *spindown_inhibitors; + + /* The timeout the disk is currently configured with, in seconds. This is 0 if spindown + * is not enabled. Depending on the command-set used, a slightly different rounded value + * may have been sent to the disk - for example, the ATA command-set has a rather peculiar + * mapping, see the hdparm(1) man-page, option -S. + * + * This value is computed by considering all per-disk spindown inhibitors (set + * via the DriveSetSpindownTimeout() method on the device) and all global spindown + * inhibitors (set via the DriveSetAllSpindownTimeouts() method on the daemon). + */ + gint spindown_timeout; + + /**************/ + /* Properties */ + /**************/ + + char *device_file; + dev_t dev; + GPtrArray *device_file_by_id; + GPtrArray *device_file_by_path; + gboolean device_is_system_internal; + gboolean device_is_partition; + gboolean device_is_partition_table; + gboolean device_is_removable; + gboolean device_is_media_available; + gboolean device_is_media_change_detected; + gboolean device_is_media_change_detection_polling; + gboolean device_is_media_change_detection_inhibitable; + gboolean device_is_media_change_detection_inhibited; + gboolean device_is_read_only; + gboolean device_is_drive; + gboolean device_is_optical_disc; + gboolean device_is_luks; + gboolean device_is_luks_cleartext; + gboolean device_is_linux_md_component; + gboolean device_is_linux_md; + guint64 device_size; + guint64 device_block_size; + gboolean device_is_mounted; + GPtrArray *device_mount_paths; + uid_t device_mounted_by_uid; + gboolean device_presentation_hide; + gboolean device_presentation_nopolicy; + char *device_presentation_name; + char *device_presentation_icon_name; + + char *id_usage; + char *id_type; + char *id_version; + char *id_uuid; + char *id_label; + + char *partition_slave; + char *partition_scheme; + char *partition_type; + char *partition_label; + char *partition_uuid; + GPtrArray *partition_flags; + int partition_number; + guint64 partition_offset; + guint64 partition_size; + + char *partition_table_scheme; + int partition_table_count; + + char *drive_vendor; + char *drive_model; + char *drive_revision; + char *drive_serial; + char *drive_wwn; + char *drive_connection_interface; + guint drive_connection_speed; + GPtrArray *drive_media_compatibility; + char *drive_media; + gboolean drive_is_media_ejectable; + gboolean drive_can_detach; + gboolean drive_can_spindown; + gboolean drive_is_rotational; + guint drive_rotation_rate; + char *drive_write_cache; + char *drive_adapter; + GPtrArray *drive_ports; + + gboolean optical_disc_is_blank; + gboolean optical_disc_is_appendable; + gboolean optical_disc_is_closed; + guint optical_disc_num_tracks; + guint optical_disc_num_audio_tracks; + guint optical_disc_num_sessions; + + char *luks_holder; + + char *luks_cleartext_slave; + uid_t luks_cleartext_unlocked_by_uid; + + char *linux_md_component_level; + int linux_md_component_position; + int linux_md_component_num_raid_devices; + char *linux_md_component_uuid; + char *linux_md_component_home_host; + char *linux_md_component_name; + char *linux_md_component_version; + char *linux_md_component_holder; + GPtrArray *linux_md_component_state; + + char *linux_md_state; + char *linux_md_level; + int linux_md_num_raid_devices; + char *linux_md_uuid; + char *linux_md_home_host; + char *linux_md_name; + char *linux_md_version; + GPtrArray *linux_md_slaves; + GPtrArray *linux_md_slaves_state; + gboolean linux_md_is_degraded; + char *linux_md_sync_action; + double linux_md_sync_percentage; + guint64 linux_md_sync_speed; + + gboolean drive_ata_smart_is_available; + guint64 drive_ata_smart_time_collected; + SkSmartOverall drive_ata_smart_status; + void *drive_ata_smart_blob; + gsize drive_ata_smart_blob_size; + + /* the following properties are not (yet) exported */ + char *dm_name; + GPtrArray *slaves_objpath; + GPtrArray *holders_objpath; }; /* property setters */ @@ -330,7 +330,6 @@ void device_set_drive_ata_smart_time_collected (Device *device, guint64 value); void device_set_drive_ata_smart_status (Device *device, SkSmartOverall value); void device_set_drive_ata_smart_blob_steal (Device *device, gchar *blob, gsize blob_size); - G_END_DECLS #endif /* __DEVICE_PRIVATE_H__ */ diff --git a/src/device.c b/src/device.c index 7aa3013..8d2e11a 100644 --- a/src/device.c +++ b/src/device.c @@ -65,30 +65,31 @@ /*--------------------------------------------------------------------------------------------------------------*/ #include "device-glue.h" -static void device_class_init (DeviceClass *klass); -static void device_init (Device *seat); -static void device_finalize (GObject *object); +static void device_class_init (DeviceClass *klass); +static void device_init (Device *seat); +static void device_finalize (GObject *object); -static void polling_inhibitor_disconnected_cb (Inhibitor *inhibitor, - Device *device); +static void polling_inhibitor_disconnected_cb (Inhibitor *inhibitor, + Device *device); -static void spindown_inhibitor_disconnected_cb (Inhibitor *inhibitor, - Device *device); +static void spindown_inhibitor_disconnected_cb (Inhibitor *inhibitor, + Device *device); -static gboolean update_info (Device *device); +static gboolean update_info (Device *device); -static void drain_pending_changes (Device *device, gboolean force_update); +static void drain_pending_changes (Device *device, + gboolean force_update); static gboolean device_local_is_busy (Device *device, - gboolean check_partitions, - GError **error); + gboolean check_partitions, + GError **error); static gboolean device_local_partitions_are_busy (Device *device); static gboolean device_local_logical_partitions_are_busy (Device *device); static gboolean device_has_logical_partitions (Device *device); - -static gboolean luks_get_uid_from_dm_name (const char *dm_name, uid_t *out_uid); +static gboolean luks_get_uid_from_dm_name (const char *dm_name, + uid_t *out_uid); /* Returns the cleartext device. If device==NULL, unlocking failed and an error has * been reported back to the caller @@ -97,12 +98,12 @@ typedef void (*UnlockEncryptionHookFunc) (DBusGMethodInvocation *context, Device *device, gpointer user_data); -static gboolean device_luks_unlock_internal (Device *device, - const char *secret, - char **options, - UnlockEncryptionHookFunc hook_func, - gpointer hook_user_data, - DBusGMethodInvocation *context); +static gboolean device_luks_unlock_internal (Device *device, + const char *secret, + char **options, + UnlockEncryptionHookFunc hook_func, + gpointer hook_user_data, + DBusGMethodInvocation *context); /* if filesystem_create_succeeded==FALSE, mkfs failed and an error has been reported back to the caller */ typedef void (*FilesystemCreateHookFunc) (DBusGMethodInvocation *context, @@ -110,159 +111,158 @@ typedef void (*FilesystemCreateHookFunc) (DBusGMethodInvocation *context, gboolean filesystem_create_succeeded, gpointer user_data); -static gboolean -device_filesystem_create_internal (Device *device, - const char *fstype, - char **options, - FilesystemCreateHookFunc hook_func, - gpointer hook_user_data, - DBusGMethodInvocation *context); - -typedef void (*ForceRemovalCompleteFunc) (Device *device, - gboolean success, - gpointer user_data); - -static void force_removal (Device *device, - ForceRemovalCompleteFunc callback, - gpointer user_data); - -static void force_unmount (Device *device, - ForceRemovalCompleteFunc callback, - gpointer user_data); - -static void force_luks_teardown (Device *device, - Device *cleartext_device, - ForceRemovalCompleteFunc callback, - gpointer user_data); +static gboolean device_filesystem_create_internal (Device *device, + const char *fstype, + char **options, + FilesystemCreateHookFunc hook_func, + gpointer hook_user_data, + DBusGMethodInvocation *context); + +typedef void (*ForceRemovalCompleteFunc) (Device *device, + gboolean success, + gpointer user_data); + +static void force_removal (Device *device, + ForceRemovalCompleteFunc callback, + gpointer user_data); + +static void force_unmount (Device *device, + ForceRemovalCompleteFunc callback, + gpointer user_data); + +static void force_luks_teardown (Device *device, + Device *cleartext_device, + ForceRemovalCompleteFunc callback, + gpointer user_data); enum -{ - PROP_0, - PROP_NATIVE_PATH, - - PROP_DEVICE_DETECTION_TIME, - PROP_DEVICE_MEDIA_DETECTION_TIME, - PROP_DEVICE_MAJOR, - PROP_DEVICE_MINOR, - PROP_DEVICE_FILE, - PROP_DEVICE_FILE_BY_ID, - PROP_DEVICE_FILE_BY_PATH, - PROP_DEVICE_IS_SYSTEM_INTERNAL, - PROP_DEVICE_IS_PARTITION, - PROP_DEVICE_IS_PARTITION_TABLE, - PROP_DEVICE_IS_REMOVABLE, - PROP_DEVICE_IS_MEDIA_AVAILABLE, - PROP_DEVICE_IS_MEDIA_CHANGE_DETECTED, - PROP_DEVICE_IS_MEDIA_CHANGE_DETECTION_POLLING, - PROP_DEVICE_IS_MEDIA_CHANGE_DETECTION_INHIBITABLE, - PROP_DEVICE_IS_MEDIA_CHANGE_DETECTION_INHIBITED, - PROP_DEVICE_IS_READ_ONLY, - PROP_DEVICE_IS_DRIVE, - PROP_DEVICE_IS_OPTICAL_DISC, - PROP_DEVICE_IS_LUKS, - PROP_DEVICE_IS_LUKS_CLEARTEXT, - PROP_DEVICE_IS_LINUX_MD_COMPONENT, - PROP_DEVICE_IS_LINUX_MD, - PROP_DEVICE_SIZE, - PROP_DEVICE_BLOCK_SIZE, - PROP_DEVICE_IS_MOUNTED, - PROP_DEVICE_MOUNT_PATHS, - PROP_DEVICE_MOUNTED_BY_UID, - PROP_DEVICE_PRESENTATION_HIDE, - PROP_DEVICE_PRESENTATION_NOPOLICY, - PROP_DEVICE_PRESENTATION_NAME, - PROP_DEVICE_PRESENTATION_ICON_NAME, - - PROP_JOB_IN_PROGRESS, - PROP_JOB_ID, - PROP_JOB_INITIATED_BY_UID, - PROP_JOB_IS_CANCELLABLE, - PROP_JOB_PERCENTAGE, - - PROP_ID_USAGE, - PROP_ID_TYPE, - PROP_ID_VERSION, - PROP_ID_UUID, - PROP_ID_LABEL, - - PROP_PARTITION_SLAVE, - PROP_PARTITION_SCHEME, - PROP_PARTITION_TYPE, - PROP_PARTITION_LABEL, - PROP_PARTITION_UUID, - PROP_PARTITION_FLAGS, - PROP_PARTITION_NUMBER, - PROP_PARTITION_OFFSET, - PROP_PARTITION_SIZE, - - PROP_PARTITION_TABLE_SCHEME, - PROP_PARTITION_TABLE_COUNT, - - PROP_LUKS_HOLDER, - - PROP_LUKS_CLEARTEXT_SLAVE, - PROP_LUKS_CLEARTEXT_UNLOCKED_BY_UID, - - PROP_DRIVE_VENDOR, - PROP_DRIVE_MODEL, - PROP_DRIVE_REVISION, - PROP_DRIVE_SERIAL, - PROP_DRIVE_WWN, - PROP_DRIVE_CONNECTION_INTERFACE, - PROP_DRIVE_CONNECTION_SPEED, - PROP_DRIVE_MEDIA_COMPATIBILITY, - PROP_DRIVE_MEDIA, - PROP_DRIVE_IS_MEDIA_EJECTABLE, - PROP_DRIVE_CAN_DETACH, - PROP_DRIVE_CAN_SPINDOWN, - PROP_DRIVE_IS_ROTATIONAL, - PROP_DRIVE_ROTATION_RATE, - PROP_DRIVE_WRITE_CACHE, - PROP_DRIVE_ADAPTER, - PROP_DRIVE_PORTS, - - PROP_OPTICAL_DISC_IS_BLANK, - PROP_OPTICAL_DISC_IS_APPENDABLE, - PROP_OPTICAL_DISC_IS_CLOSED, - PROP_OPTICAL_DISC_NUM_TRACKS, - PROP_OPTICAL_DISC_NUM_AUDIO_TRACKS, - PROP_OPTICAL_DISC_NUM_SESSIONS, - - PROP_DRIVE_ATA_SMART_IS_AVAILABLE, - PROP_DRIVE_ATA_SMART_TIME_COLLECTED, - PROP_DRIVE_ATA_SMART_STATUS, - PROP_DRIVE_ATA_SMART_BLOB, - - PROP_LINUX_MD_COMPONENT_LEVEL, - PROP_LINUX_MD_COMPONENT_POSITION, - PROP_LINUX_MD_COMPONENT_NUM_RAID_DEVICES, - PROP_LINUX_MD_COMPONENT_UUID, - PROP_LINUX_MD_COMPONENT_HOME_HOST, - PROP_LINUX_MD_COMPONENT_NAME, - PROP_LINUX_MD_COMPONENT_VERSION, - PROP_LINUX_MD_COMPONENT_HOLDER, - PROP_LINUX_MD_COMPONENT_STATE, - - PROP_LINUX_MD_STATE, - PROP_LINUX_MD_LEVEL, - PROP_LINUX_MD_NUM_RAID_DEVICES, - PROP_LINUX_MD_UUID, - PROP_LINUX_MD_HOME_HOST, - PROP_LINUX_MD_NAME, - PROP_LINUX_MD_VERSION, - PROP_LINUX_MD_SLAVES, - PROP_LINUX_MD_IS_DEGRADED, - PROP_LINUX_MD_SYNC_ACTION, - PROP_LINUX_MD_SYNC_PERCENTAGE, - PROP_LINUX_MD_SYNC_SPEED, -}; + { + PROP_0, + PROP_NATIVE_PATH, + + PROP_DEVICE_DETECTION_TIME, + PROP_DEVICE_MEDIA_DETECTION_TIME, + PROP_DEVICE_MAJOR, + PROP_DEVICE_MINOR, + PROP_DEVICE_FILE, + PROP_DEVICE_FILE_BY_ID, + PROP_DEVICE_FILE_BY_PATH, + PROP_DEVICE_IS_SYSTEM_INTERNAL, + PROP_DEVICE_IS_PARTITION, + PROP_DEVICE_IS_PARTITION_TABLE, + PROP_DEVICE_IS_REMOVABLE, + PROP_DEVICE_IS_MEDIA_AVAILABLE, + PROP_DEVICE_IS_MEDIA_CHANGE_DETECTED, + PROP_DEVICE_IS_MEDIA_CHANGE_DETECTION_POLLING, + PROP_DEVICE_IS_MEDIA_CHANGE_DETECTION_INHIBITABLE, + PROP_DEVICE_IS_MEDIA_CHANGE_DETECTION_INHIBITED, + PROP_DEVICE_IS_READ_ONLY, + PROP_DEVICE_IS_DRIVE, + PROP_DEVICE_IS_OPTICAL_DISC, + PROP_DEVICE_IS_LUKS, + PROP_DEVICE_IS_LUKS_CLEARTEXT, + PROP_DEVICE_IS_LINUX_MD_COMPONENT, + PROP_DEVICE_IS_LINUX_MD, + PROP_DEVICE_SIZE, + PROP_DEVICE_BLOCK_SIZE, + PROP_DEVICE_IS_MOUNTED, + PROP_DEVICE_MOUNT_PATHS, + PROP_DEVICE_MOUNTED_BY_UID, + PROP_DEVICE_PRESENTATION_HIDE, + PROP_DEVICE_PRESENTATION_NOPOLICY, + PROP_DEVICE_PRESENTATION_NAME, + PROP_DEVICE_PRESENTATION_ICON_NAME, + + PROP_JOB_IN_PROGRESS, + PROP_JOB_ID, + PROP_JOB_INITIATED_BY_UID, + PROP_JOB_IS_CANCELLABLE, + PROP_JOB_PERCENTAGE, + + PROP_ID_USAGE, + PROP_ID_TYPE, + PROP_ID_VERSION, + PROP_ID_UUID, + PROP_ID_LABEL, + + PROP_PARTITION_SLAVE, + PROP_PARTITION_SCHEME, + PROP_PARTITION_TYPE, + PROP_PARTITION_LABEL, + PROP_PARTITION_UUID, + PROP_PARTITION_FLAGS, + PROP_PARTITION_NUMBER, + PROP_PARTITION_OFFSET, + PROP_PARTITION_SIZE, + + PROP_PARTITION_TABLE_SCHEME, + PROP_PARTITION_TABLE_COUNT, + + PROP_LUKS_HOLDER, + + PROP_LUKS_CLEARTEXT_SLAVE, + PROP_LUKS_CLEARTEXT_UNLOCKED_BY_UID, + + PROP_DRIVE_VENDOR, + PROP_DRIVE_MODEL, + PROP_DRIVE_REVISION, + PROP_DRIVE_SERIAL, + PROP_DRIVE_WWN, + PROP_DRIVE_CONNECTION_INTERFACE, + PROP_DRIVE_CONNECTION_SPEED, + PROP_DRIVE_MEDIA_COMPATIBILITY, + PROP_DRIVE_MEDIA, + PROP_DRIVE_IS_MEDIA_EJECTABLE, + PROP_DRIVE_CAN_DETACH, + PROP_DRIVE_CAN_SPINDOWN, + PROP_DRIVE_IS_ROTATIONAL, + PROP_DRIVE_ROTATION_RATE, + PROP_DRIVE_WRITE_CACHE, + PROP_DRIVE_ADAPTER, + PROP_DRIVE_PORTS, + + PROP_OPTICAL_DISC_IS_BLANK, + PROP_OPTICAL_DISC_IS_APPENDABLE, + PROP_OPTICAL_DISC_IS_CLOSED, + PROP_OPTICAL_DISC_NUM_TRACKS, + PROP_OPTICAL_DISC_NUM_AUDIO_TRACKS, + PROP_OPTICAL_DISC_NUM_SESSIONS, + + PROP_DRIVE_ATA_SMART_IS_AVAILABLE, + PROP_DRIVE_ATA_SMART_TIME_COLLECTED, + PROP_DRIVE_ATA_SMART_STATUS, + PROP_DRIVE_ATA_SMART_BLOB, + + PROP_LINUX_MD_COMPONENT_LEVEL, + PROP_LINUX_MD_COMPONENT_POSITION, + PROP_LINUX_MD_COMPONENT_NUM_RAID_DEVICES, + PROP_LINUX_MD_COMPONENT_UUID, + PROP_LINUX_MD_COMPONENT_HOME_HOST, + PROP_LINUX_MD_COMPONENT_NAME, + PROP_LINUX_MD_COMPONENT_VERSION, + PROP_LINUX_MD_COMPONENT_HOLDER, + PROP_LINUX_MD_COMPONENT_STATE, + + PROP_LINUX_MD_STATE, + PROP_LINUX_MD_LEVEL, + PROP_LINUX_MD_NUM_RAID_DEVICES, + PROP_LINUX_MD_UUID, + PROP_LINUX_MD_HOME_HOST, + PROP_LINUX_MD_NAME, + PROP_LINUX_MD_VERSION, + PROP_LINUX_MD_SLAVES, + PROP_LINUX_MD_IS_DEGRADED, + PROP_LINUX_MD_SYNC_ACTION, + PROP_LINUX_MD_SYNC_PERCENTAGE, + PROP_LINUX_MD_SYNC_SPEED, + }; enum -{ - CHANGED_SIGNAL, - JOB_CHANGED_SIGNAL, - LAST_SIGNAL, -}; + { + CHANGED_SIGNAL, + JOB_CHANGED_SIGNAL, + LAST_SIGNAL, + }; static guint signals[LAST_SIGNAL] = { 0 }; @@ -271,1017 +271,1216 @@ G_DEFINE_TYPE (Device, device, G_TYPE_OBJECT) #define DEVICE_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), TYPE_DEVICE, DevicePrivate)) static GObject * -device_constructor (GType type, - guint n_construct_properties, - GObjectConstructParam *construct_properties) +device_constructor (GType type, + guint n_construct_properties, + GObjectConstructParam *construct_properties) { - Device *device; - DeviceClass *klass; + Device *device; + DeviceClass *klass; - klass = DEVICE_CLASS (g_type_class_peek (TYPE_DEVICE)); + klass = DEVICE_CLASS (g_type_class_peek (TYPE_DEVICE)); - device = DEVICE ( - G_OBJECT_CLASS (device_parent_class)->constructor (type, - n_construct_properties, - construct_properties)); - return G_OBJECT (device); + device = DEVICE (G_OBJECT_CLASS (device_parent_class)->constructor (type, + n_construct_properties, + construct_properties)); + return G_OBJECT (device); } static void -get_property (GObject *object, - guint prop_id, - GValue *value, - GParamSpec *pspec) -{ - Device *device = DEVICE (object); - - switch (prop_id) { - case PROP_NATIVE_PATH: - g_value_set_string (value, device->priv->native_path); - break; - - case PROP_DEVICE_DETECTION_TIME: - g_value_set_uint64 (value, device->priv->device_detection_time); - break; - case PROP_DEVICE_MEDIA_DETECTION_TIME: - g_value_set_uint64 (value, device->priv->device_media_detection_time); - break; - case PROP_DEVICE_MAJOR: - g_value_set_int64 (value, major (device->priv->dev)); - break; - case PROP_DEVICE_MINOR: - g_value_set_int64 (value, minor (device->priv->dev)); - break; - case PROP_DEVICE_FILE: - g_value_set_string (value, device->priv->device_file); - break; - case PROP_DEVICE_FILE_BY_ID: - g_value_set_boxed (value, device->priv->device_file_by_id); - break; - case PROP_DEVICE_FILE_BY_PATH: - g_value_set_boxed (value, device->priv->device_file_by_path); - break; - case PROP_DEVICE_IS_SYSTEM_INTERNAL: - g_value_set_boolean (value, device->priv->device_is_system_internal); - break; - case PROP_DEVICE_IS_PARTITION: - g_value_set_boolean (value, device->priv->device_is_partition); - break; - case PROP_DEVICE_IS_PARTITION_TABLE: - g_value_set_boolean (value, device->priv->device_is_partition_table); - break; - case PROP_DEVICE_IS_REMOVABLE: - g_value_set_boolean (value, device->priv->device_is_removable); - break; - case PROP_DEVICE_IS_MEDIA_AVAILABLE: - g_value_set_boolean (value, device->priv->device_is_media_available); - break; - case PROP_DEVICE_IS_MEDIA_CHANGE_DETECTED: - g_value_set_boolean (value, device->priv->device_is_media_change_detected); - break; - case PROP_DEVICE_IS_MEDIA_CHANGE_DETECTION_POLLING: - g_value_set_boolean (value, device->priv->device_is_media_change_detection_polling); - break; - case PROP_DEVICE_IS_MEDIA_CHANGE_DETECTION_INHIBITABLE: - g_value_set_boolean (value, device->priv->device_is_media_change_detection_inhibitable); - break; - case PROP_DEVICE_IS_MEDIA_CHANGE_DETECTION_INHIBITED: - g_value_set_boolean (value, device->priv->device_is_media_change_detection_inhibited); - break; - case PROP_DEVICE_IS_READ_ONLY: - g_value_set_boolean (value, device->priv->device_is_read_only); - break; - case PROP_DEVICE_IS_DRIVE: - g_value_set_boolean (value, device->priv->device_is_drive); - break; - case PROP_DEVICE_IS_OPTICAL_DISC: - g_value_set_boolean (value, device->priv->device_is_optical_disc); - break; - case PROP_DEVICE_IS_LUKS: - g_value_set_boolean (value, device->priv->device_is_luks); - break; - case PROP_DEVICE_IS_LUKS_CLEARTEXT: - g_value_set_boolean (value, device->priv->device_is_luks_cleartext); - break; - case PROP_DEVICE_IS_LINUX_MD_COMPONENT: - g_value_set_boolean (value, device->priv->device_is_linux_md_component); - break; - case PROP_DEVICE_IS_LINUX_MD: - g_value_set_boolean (value, device->priv->device_is_linux_md); - break; - case PROP_DEVICE_SIZE: - g_value_set_uint64 (value, device->priv->device_size); - break; - case PROP_DEVICE_BLOCK_SIZE: - g_value_set_uint64 (value, device->priv->device_block_size); - break; - case PROP_DEVICE_IS_MOUNTED: - g_value_set_boolean (value, device->priv->device_is_mounted); - break; - case PROP_DEVICE_MOUNT_PATHS: - g_value_set_boxed (value, device->priv->device_mount_paths); - break; - case PROP_DEVICE_MOUNTED_BY_UID: - g_value_set_uint (value, device->priv->device_mounted_by_uid); - break; - case PROP_DEVICE_PRESENTATION_HIDE: - g_value_set_boolean (value, device->priv->device_presentation_hide); - break; - case PROP_DEVICE_PRESENTATION_NOPOLICY: - g_value_set_boolean (value, device->priv->device_presentation_nopolicy); - break; - case PROP_DEVICE_PRESENTATION_NAME: - g_value_set_string (value, device->priv->device_presentation_name); - break; - case PROP_DEVICE_PRESENTATION_ICON_NAME: - g_value_set_string (value, device->priv->device_presentation_icon_name); - break; - - case PROP_JOB_IN_PROGRESS: - g_value_set_boolean (value, device->priv->job_in_progress); - break; - case PROP_JOB_ID: - g_value_set_string (value, device->priv->job_id); - break; - case PROP_JOB_INITIATED_BY_UID: - g_value_set_uint (value, device->priv->job_initiated_by_uid); - break; - case PROP_JOB_IS_CANCELLABLE: - g_value_set_boolean (value, device->priv->job_is_cancellable); - break; - case PROP_JOB_PERCENTAGE: - g_value_set_double (value, device->priv->job_percentage); - break; - - case PROP_ID_USAGE: - g_value_set_string (value, device->priv->id_usage); - break; - case PROP_ID_TYPE: - g_value_set_string (value, device->priv->id_type); - break; - case PROP_ID_VERSION: - g_value_set_string (value, device->priv->id_version); - break; - case PROP_ID_UUID: - g_value_set_string (value, device->priv->id_uuid); - break; - case PROP_ID_LABEL: - g_value_set_string (value, device->priv->id_label); - break; - - case PROP_PARTITION_SLAVE: - if (device->priv->partition_slave != NULL) - g_value_set_boxed (value, device->priv->partition_slave); - else - g_value_set_boxed (value, "/"); - break; - case PROP_PARTITION_SCHEME: - g_value_set_string (value, device->priv->partition_scheme); - break; - case PROP_PARTITION_TYPE: - g_value_set_string (value, device->priv->partition_type); - break; - case PROP_PARTITION_LABEL: - g_value_set_string (value, device->priv->partition_label); - break; - case PROP_PARTITION_UUID: - g_value_set_string (value, device->priv->partition_uuid); - break; - case PROP_PARTITION_FLAGS: - g_value_set_boxed (value, device->priv->partition_flags); - break; - case PROP_PARTITION_NUMBER: - g_value_set_int (value, device->priv->partition_number); - break; - case PROP_PARTITION_OFFSET: - g_value_set_uint64 (value, device->priv->partition_offset); - break; - case PROP_PARTITION_SIZE: - g_value_set_uint64 (value, device->priv->partition_size); - break; - - case PROP_PARTITION_TABLE_SCHEME: - g_value_set_string (value, device->priv->partition_table_scheme); - break; - case PROP_PARTITION_TABLE_COUNT: - g_value_set_int (value, device->priv->partition_table_count); - break; - - case PROP_LUKS_HOLDER: - if (device->priv->luks_holder != NULL) - g_value_set_boxed (value, device->priv->luks_holder); - else - g_value_set_boxed (value, "/"); - break; - - case PROP_LUKS_CLEARTEXT_SLAVE: - if (device->priv->luks_cleartext_slave != NULL) - g_value_set_boxed (value, device->priv->luks_cleartext_slave); - else - g_value_set_boxed (value, "/"); - break; - case PROP_LUKS_CLEARTEXT_UNLOCKED_BY_UID: - g_value_set_uint (value, device->priv->luks_cleartext_unlocked_by_uid); - break; - - case PROP_DRIVE_VENDOR: - g_value_set_string (value, device->priv->drive_vendor); - break; - case PROP_DRIVE_MODEL: - g_value_set_string (value, device->priv->drive_model); - break; - case PROP_DRIVE_REVISION: - g_value_set_string (value, device->priv->drive_revision); - break; - case PROP_DRIVE_SERIAL: - g_value_set_string (value, device->priv->drive_serial); - break; - case PROP_DRIVE_WWN: - g_value_set_string (value, device->priv->drive_wwn); - break; - case PROP_DRIVE_CONNECTION_INTERFACE: - g_value_set_string (value, device->priv->drive_connection_interface); - break; - case PROP_DRIVE_CONNECTION_SPEED: - g_value_set_uint64 (value, device->priv->drive_connection_speed); - break; - case PROP_DRIVE_MEDIA_COMPATIBILITY: - g_value_set_boxed (value, device->priv->drive_media_compatibility); - break; - case PROP_DRIVE_MEDIA: - g_value_set_string (value, device->priv->drive_media); - break; - case PROP_DRIVE_IS_MEDIA_EJECTABLE: - g_value_set_boolean (value, device->priv->drive_is_media_ejectable); - break; - case PROP_DRIVE_CAN_DETACH: - g_value_set_boolean (value, device->priv->drive_can_detach); - break; - case PROP_DRIVE_CAN_SPINDOWN: - g_value_set_boolean (value, device->priv->drive_can_spindown); - break; - case PROP_DRIVE_IS_ROTATIONAL: - g_value_set_boolean (value, device->priv->drive_is_rotational); - break; - case PROP_DRIVE_WRITE_CACHE: - g_value_set_string (value, device->priv->drive_write_cache); - break; - case PROP_DRIVE_ROTATION_RATE: - g_value_set_uint (value, device->priv->drive_rotation_rate); - break; - case PROP_DRIVE_ADAPTER: - if (device->priv->drive_adapter != NULL) - g_value_set_boxed (value, device->priv->drive_adapter); - else - g_value_set_boxed (value, "/"); - break; - case PROP_DRIVE_PORTS: - g_value_set_boxed (value, device->priv->drive_ports); - break; - - case PROP_OPTICAL_DISC_IS_BLANK: - g_value_set_boolean (value, device->priv->optical_disc_is_blank); - break; - case PROP_OPTICAL_DISC_IS_APPENDABLE: - g_value_set_boolean (value, device->priv->optical_disc_is_appendable); - break; - case PROP_OPTICAL_DISC_IS_CLOSED: - g_value_set_boolean (value, device->priv->optical_disc_is_closed); - break; - case PROP_OPTICAL_DISC_NUM_TRACKS: - g_value_set_uint (value, device->priv->optical_disc_num_tracks); - break; - case PROP_OPTICAL_DISC_NUM_AUDIO_TRACKS: - g_value_set_uint (value, device->priv->optical_disc_num_audio_tracks); - break; - case PROP_OPTICAL_DISC_NUM_SESSIONS: - g_value_set_uint (value, device->priv->optical_disc_num_sessions); - break; - - case PROP_DRIVE_ATA_SMART_IS_AVAILABLE: - g_value_set_boolean (value, device->priv->drive_ata_smart_is_available); - break; - case PROP_DRIVE_ATA_SMART_TIME_COLLECTED: - g_value_set_uint64 (value, device->priv->drive_ata_smart_time_collected); - break; - case PROP_DRIVE_ATA_SMART_STATUS: - { - const gchar *status; - if (device->priv->drive_ata_smart_status == (SkSmartOverall) -1) - status = ""; - else - status = sk_smart_overall_to_string (device->priv->drive_ata_smart_status); - g_value_set_string (value, status); - } - break; - case PROP_DRIVE_ATA_SMART_BLOB: - { - GArray *a; - a = g_array_new (FALSE, FALSE, 1); - if (device->priv->drive_ata_smart_blob != NULL) { - g_array_append_vals (a, - device->priv->drive_ata_smart_blob, - device->priv->drive_ata_smart_blob_size); - } - g_value_set_boxed (value, a); - g_array_unref (a); - } - break; - - case PROP_LINUX_MD_COMPONENT_LEVEL: - g_value_set_string (value, device->priv->linux_md_component_level); - break; - case PROP_LINUX_MD_COMPONENT_POSITION: - g_value_set_int (value, device->priv->linux_md_component_position); - break; - case PROP_LINUX_MD_COMPONENT_NUM_RAID_DEVICES: - g_value_set_int (value, device->priv->linux_md_component_num_raid_devices); - break; - case PROP_LINUX_MD_COMPONENT_UUID: - g_value_set_string (value, device->priv->linux_md_component_uuid); - break; - case PROP_LINUX_MD_COMPONENT_HOME_HOST: - g_value_set_string (value, device->priv->linux_md_component_home_host); - break; - case PROP_LINUX_MD_COMPONENT_NAME: - g_value_set_string (value, device->priv->linux_md_component_name); - break; - case PROP_LINUX_MD_COMPONENT_VERSION: - g_value_set_string (value, device->priv->linux_md_component_version); - break; - case PROP_LINUX_MD_COMPONENT_HOLDER: - if (device->priv->linux_md_component_holder != NULL) - g_value_set_boxed (value, device->priv->linux_md_component_holder); - else - g_value_set_boxed (value, "/"); - break; - case PROP_LINUX_MD_COMPONENT_STATE: - g_value_set_boxed (value, device->priv->linux_md_component_state); - break; - - case PROP_LINUX_MD_STATE: - g_value_set_string (value, device->priv->linux_md_state); - break; - case PROP_LINUX_MD_LEVEL: - g_value_set_string (value, device->priv->linux_md_level); - break; - case PROP_LINUX_MD_NUM_RAID_DEVICES: - g_value_set_int (value, device->priv->linux_md_num_raid_devices); - break; - case PROP_LINUX_MD_UUID: - g_value_set_string (value, device->priv->linux_md_uuid); - break; - case PROP_LINUX_MD_HOME_HOST: - g_value_set_string (value, device->priv->linux_md_home_host); - break; - case PROP_LINUX_MD_NAME: - g_value_set_string (value, device->priv->linux_md_name); - break; - case PROP_LINUX_MD_VERSION: - g_value_set_string (value, device->priv->linux_md_version); - break; - case PROP_LINUX_MD_SLAVES: - g_value_set_boxed (value, device->priv->linux_md_slaves); - break; - case PROP_LINUX_MD_IS_DEGRADED: - g_value_set_boolean (value, device->priv->linux_md_is_degraded); - break; - case PROP_LINUX_MD_SYNC_ACTION: - g_value_set_string (value, device->priv->linux_md_sync_action); - break; - case PROP_LINUX_MD_SYNC_PERCENTAGE: - g_value_set_double (value, device->priv->linux_md_sync_percentage); - break; - case PROP_LINUX_MD_SYNC_SPEED: - g_value_set_uint64 (value, device->priv->linux_md_sync_speed); - break; - - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } +get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + Device *device = DEVICE (object); + + switch (prop_id) + { + case PROP_NATIVE_PATH: + g_value_set_string (value, device->priv->native_path); + break; + + case PROP_DEVICE_DETECTION_TIME: + g_value_set_uint64 (value, device->priv->device_detection_time); + break; + case PROP_DEVICE_MEDIA_DETECTION_TIME: + g_value_set_uint64 (value, device->priv->device_media_detection_time); + break; + case PROP_DEVICE_MAJOR: + g_value_set_int64 (value, major (device->priv->dev)); + break; + case PROP_DEVICE_MINOR: + g_value_set_int64 (value, minor (device->priv->dev)); + break; + case PROP_DEVICE_FILE: + g_value_set_string (value, device->priv->device_file); + break; + case PROP_DEVICE_FILE_BY_ID: + g_value_set_boxed (value, device->priv->device_file_by_id); + break; + case PROP_DEVICE_FILE_BY_PATH: + g_value_set_boxed (value, device->priv->device_file_by_path); + break; + case PROP_DEVICE_IS_SYSTEM_INTERNAL: + g_value_set_boolean (value, device->priv->device_is_system_internal); + break; + case PROP_DEVICE_IS_PARTITION: + g_value_set_boolean (value, device->priv->device_is_partition); + break; + case PROP_DEVICE_IS_PARTITION_TABLE: + g_value_set_boolean (value, device->priv->device_is_partition_table); + break; + case PROP_DEVICE_IS_REMOVABLE: + g_value_set_boolean (value, device->priv->device_is_removable); + break; + case PROP_DEVICE_IS_MEDIA_AVAILABLE: + g_value_set_boolean (value, device->priv->device_is_media_available); + break; + case PROP_DEVICE_IS_MEDIA_CHANGE_DETECTED: + g_value_set_boolean (value, device->priv->device_is_media_change_detected); + break; + case PROP_DEVICE_IS_MEDIA_CHANGE_DETECTION_POLLING: + g_value_set_boolean (value, device->priv->device_is_media_change_detection_polling); + break; + case PROP_DEVICE_IS_MEDIA_CHANGE_DETECTION_INHIBITABLE: + g_value_set_boolean (value, device->priv->device_is_media_change_detection_inhibitable); + break; + case PROP_DEVICE_IS_MEDIA_CHANGE_DETECTION_INHIBITED: + g_value_set_boolean (value, device->priv->device_is_media_change_detection_inhibited); + break; + case PROP_DEVICE_IS_READ_ONLY: + g_value_set_boolean (value, device->priv->device_is_read_only); + break; + case PROP_DEVICE_IS_DRIVE: + g_value_set_boolean (value, device->priv->device_is_drive); + break; + case PROP_DEVICE_IS_OPTICAL_DISC: + g_value_set_boolean (value, device->priv->device_is_optical_disc); + break; + case PROP_DEVICE_IS_LUKS: + g_value_set_boolean (value, device->priv->device_is_luks); + break; + case PROP_DEVICE_IS_LUKS_CLEARTEXT: + g_value_set_boolean (value, device->priv->device_is_luks_cleartext); + break; + case PROP_DEVICE_IS_LINUX_MD_COMPONENT: + g_value_set_boolean (value, device->priv->device_is_linux_md_component); + break; + case PROP_DEVICE_IS_LINUX_MD: + g_value_set_boolean (value, device->priv->device_is_linux_md); + break; + case PROP_DEVICE_SIZE: + g_value_set_uint64 (value, device->priv->device_size); + break; + case PROP_DEVICE_BLOCK_SIZE: + g_value_set_uint64 (value, device->priv->device_block_size); + break; + case PROP_DEVICE_IS_MOUNTED: + g_value_set_boolean (value, device->priv->device_is_mounted); + break; + case PROP_DEVICE_MOUNT_PATHS: + g_value_set_boxed (value, device->priv->device_mount_paths); + break; + case PROP_DEVICE_MOUNTED_BY_UID: + g_value_set_uint (value, device->priv->device_mounted_by_uid); + break; + case PROP_DEVICE_PRESENTATION_HIDE: + g_value_set_boolean (value, device->priv->device_presentation_hide); + break; + case PROP_DEVICE_PRESENTATION_NOPOLICY: + g_value_set_boolean (value, device->priv->device_presentation_nopolicy); + break; + case PROP_DEVICE_PRESENTATION_NAME: + g_value_set_string (value, device->priv->device_presentation_name); + break; + case PROP_DEVICE_PRESENTATION_ICON_NAME: + g_value_set_string (value, device->priv->device_presentation_icon_name); + break; + + case PROP_JOB_IN_PROGRESS: + g_value_set_boolean (value, device->priv->job_in_progress); + break; + case PROP_JOB_ID: + g_value_set_string (value, device->priv->job_id); + break; + case PROP_JOB_INITIATED_BY_UID: + g_value_set_uint (value, device->priv->job_initiated_by_uid); + break; + case PROP_JOB_IS_CANCELLABLE: + g_value_set_boolean (value, device->priv->job_is_cancellable); + break; + case PROP_JOB_PERCENTAGE: + g_value_set_double (value, device->priv->job_percentage); + break; + + case PROP_ID_USAGE: + g_value_set_string (value, device->priv->id_usage); + break; + case PROP_ID_TYPE: + g_value_set_string (value, device->priv->id_type); + break; + case PROP_ID_VERSION: + g_value_set_string (value, device->priv->id_version); + break; + case PROP_ID_UUID: + g_value_set_string (value, device->priv->id_uuid); + break; + case PROP_ID_LABEL: + g_value_set_string (value, device->priv->id_label); + break; + + case PROP_PARTITION_SLAVE: + if (device->priv->partition_slave != NULL) + g_value_set_boxed (value, device->priv->partition_slave); + else + g_value_set_boxed (value, "/"); + break; + case PROP_PARTITION_SCHEME: + g_value_set_string (value, device->priv->partition_scheme); + break; + case PROP_PARTITION_TYPE: + g_value_set_string (value, device->priv->partition_type); + break; + case PROP_PARTITION_LABEL: + g_value_set_string (value, device->priv->partition_label); + break; + case PROP_PARTITION_UUID: + g_value_set_string (value, device->priv->partition_uuid); + break; + case PROP_PARTITION_FLAGS: + g_value_set_boxed (value, device->priv->partition_flags); + break; + case PROP_PARTITION_NUMBER: + g_value_set_int (value, device->priv->partition_number); + break; + case PROP_PARTITION_OFFSET: + g_value_set_uint64 (value, device->priv->partition_offset); + break; + case PROP_PARTITION_SIZE: + g_value_set_uint64 (value, device->priv->partition_size); + break; + + case PROP_PARTITION_TABLE_SCHEME: + g_value_set_string (value, device->priv->partition_table_scheme); + break; + case PROP_PARTITION_TABLE_COUNT: + g_value_set_int (value, device->priv->partition_table_count); + break; + + case PROP_LUKS_HOLDER: + if (device->priv->luks_holder != NULL) + g_value_set_boxed (value, device->priv->luks_holder); + else + g_value_set_boxed (value, "/"); + break; + + case PROP_LUKS_CLEARTEXT_SLAVE: + if (device->priv->luks_cleartext_slave != NULL) + g_value_set_boxed (value, device->priv->luks_cleartext_slave); + else + g_value_set_boxed (value, "/"); + break; + case PROP_LUKS_CLEARTEXT_UNLOCKED_BY_UID: + g_value_set_uint (value, device->priv->luks_cleartext_unlocked_by_uid); + break; + + case PROP_DRIVE_VENDOR: + g_value_set_string (value, device->priv->drive_vendor); + break; + case PROP_DRIVE_MODEL: + g_value_set_string (value, device->priv->drive_model); + break; + case PROP_DRIVE_REVISION: + g_value_set_string (value, device->priv->drive_revision); + break; + case PROP_DRIVE_SERIAL: + g_value_set_string (value, device->priv->drive_serial); + break; + case PROP_DRIVE_WWN: + g_value_set_string (value, device->priv->drive_wwn); + break; + case PROP_DRIVE_CONNECTION_INTERFACE: + g_value_set_string (value, device->priv->drive_connection_interface); + break; + case PROP_DRIVE_CONNECTION_SPEED: + g_value_set_uint64 (value, device->priv->drive_connection_speed); + break; + case PROP_DRIVE_MEDIA_COMPATIBILITY: + g_value_set_boxed (value, device->priv->drive_media_compatibility); + break; + case PROP_DRIVE_MEDIA: + g_value_set_string (value, device->priv->drive_media); + break; + case PROP_DRIVE_IS_MEDIA_EJECTABLE: + g_value_set_boolean (value, device->priv->drive_is_media_ejectable); + break; + case PROP_DRIVE_CAN_DETACH: + g_value_set_boolean (value, device->priv->drive_can_detach); + break; + case PROP_DRIVE_CAN_SPINDOWN: + g_value_set_boolean (value, device->priv->drive_can_spindown); + break; + case PROP_DRIVE_IS_ROTATIONAL: + g_value_set_boolean (value, device->priv->drive_is_rotational); + break; + case PROP_DRIVE_WRITE_CACHE: + g_value_set_string (value, device->priv->drive_write_cache); + break; + case PROP_DRIVE_ROTATION_RATE: + g_value_set_uint (value, device->priv->drive_rotation_rate); + break; + case PROP_DRIVE_ADAPTER: + if (device->priv->drive_adapter != NULL) + g_value_set_boxed (value, device->priv->drive_adapter); + else + g_value_set_boxed (value, "/"); + break; + case PROP_DRIVE_PORTS: + g_value_set_boxed (value, device->priv->drive_ports); + break; + + case PROP_OPTICAL_DISC_IS_BLANK: + g_value_set_boolean (value, device->priv->optical_disc_is_blank); + break; + case PROP_OPTICAL_DISC_IS_APPENDABLE: + g_value_set_boolean (value, device->priv->optical_disc_is_appendable); + break; + case PROP_OPTICAL_DISC_IS_CLOSED: + g_value_set_boolean (value, device->priv->optical_disc_is_closed); + break; + case PROP_OPTICAL_DISC_NUM_TRACKS: + g_value_set_uint (value, device->priv->optical_disc_num_tracks); + break; + case PROP_OPTICAL_DISC_NUM_AUDIO_TRACKS: + g_value_set_uint (value, device->priv->optical_disc_num_audio_tracks); + break; + case PROP_OPTICAL_DISC_NUM_SESSIONS: + g_value_set_uint (value, device->priv->optical_disc_num_sessions); + break; + + case PROP_DRIVE_ATA_SMART_IS_AVAILABLE: + g_value_set_boolean (value, device->priv->drive_ata_smart_is_available); + break; + case PROP_DRIVE_ATA_SMART_TIME_COLLECTED: + g_value_set_uint64 (value, device->priv->drive_ata_smart_time_collected); + break; + case PROP_DRIVE_ATA_SMART_STATUS: + { + const gchar *status; + if (device->priv->drive_ata_smart_status == (SkSmartOverall) - 1) + status = ""; + else + status = sk_smart_overall_to_string (device->priv->drive_ata_smart_status); + g_value_set_string (value, status); + } + break; + case PROP_DRIVE_ATA_SMART_BLOB: + { + GArray *a; + a = g_array_new (FALSE, FALSE, 1); + if (device->priv->drive_ata_smart_blob != NULL) + { + g_array_append_vals (a, device->priv->drive_ata_smart_blob, device->priv->drive_ata_smart_blob_size); + } + g_value_set_boxed (value, a); + g_array_unref (a); + } + break; + + case PROP_LINUX_MD_COMPONENT_LEVEL: + g_value_set_string (value, device->priv->linux_md_component_level); + break; + case PROP_LINUX_MD_COMPONENT_POSITION: + g_value_set_int (value, device->priv->linux_md_component_position); + break; + case PROP_LINUX_MD_COMPONENT_NUM_RAID_DEVICES: + g_value_set_int (value, device->priv->linux_md_component_num_raid_devices); + break; + case PROP_LINUX_MD_COMPONENT_UUID: + g_value_set_string (value, device->priv->linux_md_component_uuid); + break; + case PROP_LINUX_MD_COMPONENT_HOME_HOST: + g_value_set_string (value, device->priv->linux_md_component_home_host); + break; + case PROP_LINUX_MD_COMPONENT_NAME: + g_value_set_string (value, device->priv->linux_md_component_name); + break; + case PROP_LINUX_MD_COMPONENT_VERSION: + g_value_set_string (value, device->priv->linux_md_component_version); + break; + case PROP_LINUX_MD_COMPONENT_HOLDER: + if (device->priv->linux_md_component_holder != NULL) + g_value_set_boxed (value, device->priv->linux_md_component_holder); + else + g_value_set_boxed (value, "/"); + break; + case PROP_LINUX_MD_COMPONENT_STATE: + g_value_set_boxed (value, device->priv->linux_md_component_state); + break; + + case PROP_LINUX_MD_STATE: + g_value_set_string (value, device->priv->linux_md_state); + break; + case PROP_LINUX_MD_LEVEL: + g_value_set_string (value, device->priv->linux_md_level); + break; + case PROP_LINUX_MD_NUM_RAID_DEVICES: + g_value_set_int (value, device->priv->linux_md_num_raid_devices); + break; + case PROP_LINUX_MD_UUID: + g_value_set_string (value, device->priv->linux_md_uuid); + break; + case PROP_LINUX_MD_HOME_HOST: + g_value_set_string (value, device->priv->linux_md_home_host); + break; + case PROP_LINUX_MD_NAME: + g_value_set_string (value, device->priv->linux_md_name); + break; + case PROP_LINUX_MD_VERSION: + g_value_set_string (value, device->priv->linux_md_version); + break; + case PROP_LINUX_MD_SLAVES: + g_value_set_boxed (value, device->priv->linux_md_slaves); + break; + case PROP_LINUX_MD_IS_DEGRADED: + g_value_set_boolean (value, device->priv->linux_md_is_degraded); + break; + case PROP_LINUX_MD_SYNC_ACTION: + g_value_set_string (value, device->priv->linux_md_sync_action); + break; + case PROP_LINUX_MD_SYNC_PERCENTAGE: + g_value_set_double (value, device->priv->linux_md_sync_percentage); + break; + case PROP_LINUX_MD_SYNC_SPEED: + g_value_set_uint64 (value, device->priv->linux_md_sync_speed); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } } static void device_class_init (DeviceClass *klass) { - GObjectClass *object_class = G_OBJECT_CLASS (klass); - - object_class->constructor = device_constructor; - object_class->finalize = device_finalize; - object_class->get_property = get_property; - - g_type_class_add_private (klass, sizeof (DevicePrivate)); - - signals[CHANGED_SIGNAL] = - g_signal_new ("changed", - G_OBJECT_CLASS_TYPE (klass), - G_SIGNAL_RUN_LAST | G_SIGNAL_DETAILED, - 0, - NULL, NULL, - g_cclosure_marshal_VOID__VOID, - G_TYPE_NONE, 0); - - signals[JOB_CHANGED_SIGNAL] = - g_signal_new ("job-changed", - G_OBJECT_CLASS_TYPE (klass), - G_SIGNAL_RUN_LAST | G_SIGNAL_DETAILED, - 0, - NULL, NULL, - marshal_VOID__BOOLEAN_STRING_UINT_BOOLEAN_DOUBLE, - G_TYPE_NONE, - 5, - G_TYPE_BOOLEAN, - G_TYPE_STRING, - G_TYPE_UINT, - G_TYPE_BOOLEAN, - G_TYPE_DOUBLE); - - dbus_g_object_type_install_info (TYPE_DEVICE, &dbus_glib_device_object_info); - - g_object_class_install_property ( - object_class, - PROP_NATIVE_PATH, - g_param_spec_string ("native-path", NULL, NULL, NULL, G_PARAM_READABLE)); - g_object_class_install_property ( - object_class, - PROP_DEVICE_DETECTION_TIME, - g_param_spec_uint64 ("device-detection-time", NULL, NULL, 0, G_MAXUINT64, 0, G_PARAM_READABLE)); - g_object_class_install_property ( - object_class, - PROP_DEVICE_MEDIA_DETECTION_TIME, - g_param_spec_uint64 ("device-media-detection-time", NULL, NULL, 0, G_MAXUINT64, 0, G_PARAM_READABLE)); - g_object_class_install_property ( - object_class, - PROP_DEVICE_MAJOR, - g_param_spec_int64 ("device-major", NULL, NULL, -G_MAXINT64, G_MAXINT64, 0, G_PARAM_READABLE)); - g_object_class_install_property ( - object_class, - PROP_DEVICE_MINOR, - g_param_spec_int64 ("device-minor", NULL, NULL, -G_MAXINT64, G_MAXINT64, 0, G_PARAM_READABLE)); - g_object_class_install_property ( - object_class, - PROP_DEVICE_FILE, - g_param_spec_string ("device-file", NULL, NULL, NULL, G_PARAM_READABLE)); - g_object_class_install_property ( - object_class, - PROP_DEVICE_FILE_BY_ID, - g_param_spec_boxed ("device-file-by-id", NULL, NULL, - dbus_g_type_get_collection ("GPtrArray", G_TYPE_STRING), - G_PARAM_READABLE)); - g_object_class_install_property ( - object_class, - PROP_DEVICE_FILE_BY_PATH, - g_param_spec_boxed ("device-file-by-path", NULL, NULL, - dbus_g_type_get_collection ("GPtrArray", G_TYPE_STRING), - G_PARAM_READABLE)); - g_object_class_install_property ( - object_class, - PROP_DEVICE_IS_SYSTEM_INTERNAL, - g_param_spec_boolean ("device-is-system-internal", NULL, NULL, FALSE, G_PARAM_READABLE)); - g_object_class_install_property ( - object_class, - PROP_DEVICE_IS_PARTITION, - g_param_spec_boolean ("device-is-partition", NULL, NULL, FALSE, G_PARAM_READABLE)); - g_object_class_install_property ( - object_class, - PROP_DEVICE_IS_PARTITION_TABLE, - g_param_spec_boolean ("device-is-partition-table", NULL, NULL, FALSE, G_PARAM_READABLE)); - g_object_class_install_property ( - object_class, - PROP_DEVICE_IS_REMOVABLE, - g_param_spec_boolean ("device-is-removable", NULL, NULL, FALSE, G_PARAM_READABLE)); - g_object_class_install_property ( - object_class, - PROP_DEVICE_IS_MEDIA_AVAILABLE, - g_param_spec_boolean ("device-is-media-available", NULL, NULL, FALSE, G_PARAM_READABLE)); - g_object_class_install_property ( - object_class, - PROP_DEVICE_IS_MEDIA_CHANGE_DETECTED, - g_param_spec_boolean ("device-is-media-change-detected", NULL, NULL, FALSE, G_PARAM_READABLE)); - g_object_class_install_property ( - object_class, - PROP_DEVICE_IS_MEDIA_CHANGE_DETECTION_POLLING, - g_param_spec_boolean ("device-is-media-change-detection-polling", NULL, NULL, FALSE, G_PARAM_READABLE)); - g_object_class_install_property ( - object_class, - PROP_DEVICE_IS_MEDIA_CHANGE_DETECTION_INHIBITABLE, - g_param_spec_boolean ("device-is-media-change-detection-inhibitable", NULL, NULL, FALSE, G_PARAM_READABLE)); - g_object_class_install_property ( - object_class, - PROP_DEVICE_IS_MEDIA_CHANGE_DETECTION_INHIBITED, - g_param_spec_boolean ("device-is-media-change-detection-inhibited", NULL, NULL, FALSE, G_PARAM_READABLE)); - g_object_class_install_property ( - object_class, - PROP_DEVICE_IS_READ_ONLY, - g_param_spec_boolean ("device-is-read-only", NULL, NULL, FALSE, G_PARAM_READABLE)); - g_object_class_install_property ( - object_class, - PROP_DEVICE_IS_DRIVE, - g_param_spec_boolean ("device-is-drive", NULL, NULL, FALSE, G_PARAM_READABLE)); - g_object_class_install_property ( - object_class, - PROP_DEVICE_IS_OPTICAL_DISC, - g_param_spec_boolean ("device-is-optical-disc", NULL, NULL, FALSE, G_PARAM_READABLE)); - g_object_class_install_property ( - object_class, - PROP_DEVICE_IS_LUKS, - g_param_spec_boolean ("device-is-luks", NULL, NULL, FALSE, G_PARAM_READABLE)); - g_object_class_install_property ( - object_class, - PROP_DEVICE_IS_LUKS_CLEARTEXT, - g_param_spec_boolean ("device-is-luks-cleartext", NULL, NULL, FALSE, G_PARAM_READABLE)); - g_object_class_install_property ( - object_class, - PROP_DEVICE_IS_LINUX_MD_COMPONENT, - g_param_spec_boolean ("device-is-linux-md-component", NULL, NULL, FALSE, G_PARAM_READABLE)); - g_object_class_install_property ( - object_class, - PROP_DEVICE_IS_LINUX_MD, - g_param_spec_boolean ("device-is-linux-md", NULL, NULL, FALSE, G_PARAM_READABLE)); - g_object_class_install_property ( - object_class, - PROP_DEVICE_SIZE, - g_param_spec_uint64 ("device-size", NULL, NULL, 0, G_MAXUINT64, 0, G_PARAM_READABLE)); - g_object_class_install_property ( - object_class, - PROP_DEVICE_BLOCK_SIZE, - g_param_spec_uint64 ("device-block-size", NULL, NULL, 0, G_MAXUINT64, 0, G_PARAM_READABLE)); - g_object_class_install_property ( - object_class, - PROP_DEVICE_IS_MOUNTED, - g_param_spec_boolean ("device-is-mounted", NULL, NULL, FALSE, G_PARAM_READABLE)); - g_object_class_install_property ( - object_class, - PROP_DEVICE_MOUNT_PATHS, - g_param_spec_boxed ("device-mount-paths", NULL, NULL, - dbus_g_type_get_collection ("GPtrArray", G_TYPE_STRING), - G_PARAM_READABLE)); - g_object_class_install_property ( - object_class, - PROP_DEVICE_MOUNTED_BY_UID, - g_param_spec_uint ("device-mounted-by-uid", NULL, NULL, 0, G_MAXUINT, 0, G_PARAM_READABLE)); - g_object_class_install_property ( - object_class, - PROP_DEVICE_PRESENTATION_HIDE, - g_param_spec_boolean ("device-presentation-hide", NULL, NULL, FALSE, G_PARAM_READABLE)); - g_object_class_install_property ( - object_class, - PROP_DEVICE_PRESENTATION_NOPOLICY, - g_param_spec_boolean ("device-presentation-nopolicy", NULL, NULL, FALSE, G_PARAM_READABLE)); - g_object_class_install_property ( - object_class, - PROP_DEVICE_PRESENTATION_NAME, - g_param_spec_string ("device-presentation-name", NULL, NULL, NULL, G_PARAM_READABLE)); - g_object_class_install_property ( - object_class, - PROP_DEVICE_PRESENTATION_ICON_NAME, - g_param_spec_string ("device-presentation-icon-name", NULL, NULL, NULL, G_PARAM_READABLE)); - - g_object_class_install_property ( - object_class, - PROP_JOB_IN_PROGRESS, - g_param_spec_boolean ("job-in-progress", NULL, NULL, FALSE, G_PARAM_READABLE)); - g_object_class_install_property ( - object_class, - PROP_JOB_ID, - g_param_spec_string ("job-id", NULL, NULL, NULL, G_PARAM_READABLE)); - g_object_class_install_property ( - object_class, - PROP_JOB_INITIATED_BY_UID, - g_param_spec_uint ("job-initiated-by-uid", NULL, NULL, 0, G_MAXUINT, 0, G_PARAM_READABLE)); - g_object_class_install_property ( - object_class, - PROP_JOB_IS_CANCELLABLE, - g_param_spec_boolean ("job-is-cancellable", NULL, NULL, FALSE, G_PARAM_READABLE)); - g_object_class_install_property ( - object_class, - PROP_JOB_PERCENTAGE, - g_param_spec_double ("job-percentage", NULL, NULL, -1, 100, -1, G_PARAM_READABLE)); - - g_object_class_install_property ( - object_class, - PROP_ID_USAGE, - g_param_spec_string ("id-usage", NULL, NULL, NULL, G_PARAM_READABLE)); - g_object_class_install_property ( - object_class, - PROP_ID_TYPE, - g_param_spec_string ("id-type", NULL, NULL, NULL, G_PARAM_READABLE)); - g_object_class_install_property ( - object_class, - PROP_ID_VERSION, - g_param_spec_string ("id-version", NULL, NULL, NULL, G_PARAM_READABLE)); - g_object_class_install_property ( - object_class, - PROP_ID_UUID, - g_param_spec_string ("id-uuid", NULL, NULL, NULL, G_PARAM_READABLE)); - g_object_class_install_property ( - object_class, - PROP_ID_LABEL, - g_param_spec_string ("id-label", NULL, NULL, NULL, G_PARAM_READABLE)); - - g_object_class_install_property ( - object_class, - PROP_PARTITION_SLAVE, - g_param_spec_boxed ("partition-slave", NULL, NULL, DBUS_TYPE_G_OBJECT_PATH, G_PARAM_READABLE)); - g_object_class_install_property ( - object_class, - PROP_PARTITION_SCHEME, - g_param_spec_string ("partition-scheme", NULL, NULL, NULL, G_PARAM_READABLE)); - g_object_class_install_property ( - object_class, - PROP_PARTITION_TYPE, - g_param_spec_string ("partition-type", NULL, NULL, NULL, G_PARAM_READABLE)); - g_object_class_install_property ( - object_class, - PROP_PARTITION_LABEL, - g_param_spec_string ("partition-label", NULL, NULL, NULL, G_PARAM_READABLE)); - g_object_class_install_property ( - object_class, - PROP_PARTITION_UUID, - g_param_spec_string ("partition-uuid", NULL, NULL, NULL, G_PARAM_READABLE)); - g_object_class_install_property ( - object_class, - PROP_PARTITION_FLAGS, - g_param_spec_boxed ("partition-flags", NULL, NULL, - dbus_g_type_get_collection ("GPtrArray", G_TYPE_STRING), - G_PARAM_READABLE)); - g_object_class_install_property ( - object_class, - PROP_PARTITION_NUMBER, - g_param_spec_int ("partition-number", NULL, NULL, 0, G_MAXINT, 0, G_PARAM_READABLE)); - g_object_class_install_property ( - object_class, - PROP_PARTITION_OFFSET, - g_param_spec_uint64 ("partition-offset", NULL, NULL, 0, G_MAXUINT64, 0, G_PARAM_READABLE)); - g_object_class_install_property ( - object_class, - PROP_PARTITION_SIZE, - g_param_spec_uint64 ("partition-size", NULL, NULL, 0, G_MAXUINT64, 0, G_PARAM_READABLE)); - - g_object_class_install_property ( - object_class, - PROP_PARTITION_TABLE_SCHEME, - g_param_spec_string ("partition-table-scheme", NULL, NULL, NULL, G_PARAM_READABLE)); - g_object_class_install_property ( - object_class, - PROP_PARTITION_TABLE_COUNT, - g_param_spec_int ("partition-table-count", NULL, NULL, 0, G_MAXINT, 0, G_PARAM_READABLE)); - - g_object_class_install_property ( - object_class, - PROP_LUKS_HOLDER, - g_param_spec_boxed ("luks-holder", NULL, NULL, DBUS_TYPE_G_OBJECT_PATH, G_PARAM_READABLE)); - - g_object_class_install_property ( - object_class, - PROP_LUKS_CLEARTEXT_SLAVE, - g_param_spec_boxed ("luks-cleartext-slave", NULL, NULL, DBUS_TYPE_G_OBJECT_PATH, G_PARAM_READABLE)); - g_object_class_install_property ( - object_class, - PROP_LUKS_CLEARTEXT_UNLOCKED_BY_UID, - g_param_spec_uint ("luks-cleartext-unlocked-by-uid", NULL, NULL, 0, G_MAXUINT, 0, G_PARAM_READABLE)); - - g_object_class_install_property ( - object_class, - PROP_DRIVE_VENDOR, - g_param_spec_string ("drive-vendor", NULL, NULL, NULL, G_PARAM_READABLE)); - g_object_class_install_property ( - object_class, - PROP_DRIVE_MODEL, - g_param_spec_string ("drive-model", NULL, NULL, NULL, G_PARAM_READABLE)); - g_object_class_install_property ( - object_class, - PROP_DRIVE_REVISION, - g_param_spec_string ("drive-revision", NULL, NULL, NULL, G_PARAM_READABLE)); - g_object_class_install_property ( - object_class, - PROP_DRIVE_SERIAL, - g_param_spec_string ("drive-serial", NULL, NULL, NULL, G_PARAM_READABLE)); - g_object_class_install_property ( - object_class, - PROP_DRIVE_WWN, - g_param_spec_string ("drive-wwn", NULL, NULL, NULL, G_PARAM_READABLE)); - g_object_class_install_property ( - object_class, - PROP_DRIVE_CONNECTION_INTERFACE, - g_param_spec_string ("drive-connection-interface", NULL, NULL, NULL, G_PARAM_READABLE)); - g_object_class_install_property ( - object_class, - PROP_DRIVE_CONNECTION_SPEED, - g_param_spec_uint64 ("drive-connection-speed", NULL, NULL, 0, G_MAXUINT64, 0, G_PARAM_READABLE)); - g_object_class_install_property ( - object_class, - PROP_DRIVE_MEDIA_COMPATIBILITY, - g_param_spec_boxed ("drive-media-compatibility", NULL, NULL, - dbus_g_type_get_collection ("GPtrArray", G_TYPE_STRING), - G_PARAM_READABLE)); - g_object_class_install_property ( - object_class, - PROP_DRIVE_MEDIA, - g_param_spec_string ("drive-media", NULL, NULL, NULL, G_PARAM_READABLE)); - g_object_class_install_property ( - object_class, - PROP_DRIVE_IS_MEDIA_EJECTABLE, - g_param_spec_boolean ("drive-is-media-ejectable", NULL, NULL, FALSE, G_PARAM_READABLE)); - g_object_class_install_property ( - object_class, - PROP_DRIVE_CAN_DETACH, - g_param_spec_boolean ("drive-can-detach", NULL, NULL, FALSE, G_PARAM_READABLE)); - g_object_class_install_property ( - object_class, - PROP_DRIVE_CAN_SPINDOWN, - g_param_spec_boolean ("drive-can-spindown", NULL, NULL, FALSE, G_PARAM_READABLE)); - g_object_class_install_property ( - object_class, - PROP_DRIVE_IS_ROTATIONAL, - g_param_spec_boolean ("drive-is-rotational", NULL, NULL, FALSE, G_PARAM_READABLE)); - g_object_class_install_property ( - object_class, - PROP_DRIVE_ROTATION_RATE, - g_param_spec_uint ("drive-rotation-rate", NULL, NULL, 0, G_MAXUINT, 0, G_PARAM_READABLE)); - g_object_class_install_property ( - object_class, - PROP_DRIVE_WRITE_CACHE, - g_param_spec_string ("drive-write-cache", NULL, NULL, FALSE, G_PARAM_READABLE)); - g_object_class_install_property ( - object_class, - PROP_DRIVE_ADAPTER, - g_param_spec_boxed ("drive-adapter", NULL, NULL, DBUS_TYPE_G_OBJECT_PATH, G_PARAM_READABLE)); - g_object_class_install_property ( - object_class, - PROP_DRIVE_PORTS, - g_param_spec_boxed ("drive-ports", NULL, NULL, - dbus_g_type_get_collection ("GPtrArray", DBUS_TYPE_G_OBJECT_PATH), - G_PARAM_READABLE)); - - g_object_class_install_property ( - object_class, - PROP_OPTICAL_DISC_IS_BLANK, - g_param_spec_boolean ("optical-disc-is-blank", NULL, NULL, FALSE, G_PARAM_READABLE)); - g_object_class_install_property ( - object_class, - PROP_OPTICAL_DISC_IS_APPENDABLE, - g_param_spec_boolean ("optical-disc-is-appendable", NULL, NULL, FALSE, G_PARAM_READABLE)); - g_object_class_install_property ( - object_class, - PROP_OPTICAL_DISC_IS_CLOSED, - g_param_spec_boolean ("optical-disc-is-closed", NULL, NULL, FALSE, G_PARAM_READABLE)); - g_object_class_install_property ( - object_class, - PROP_OPTICAL_DISC_NUM_TRACKS, - g_param_spec_uint ("optical-disc-num-tracks", NULL, NULL, 0, G_MAXUINT, 0, G_PARAM_READABLE)); - g_object_class_install_property ( - object_class, - PROP_OPTICAL_DISC_NUM_AUDIO_TRACKS, - g_param_spec_uint ("optical-disc-num-audio-tracks", NULL, NULL, 0, G_MAXUINT, 0, G_PARAM_READABLE)); - g_object_class_install_property ( - object_class, - PROP_OPTICAL_DISC_NUM_SESSIONS, - g_param_spec_uint ("optical-disc-num-sessions", NULL, NULL, 0, G_MAXUINT, 0, G_PARAM_READABLE)); - - g_object_class_install_property ( - object_class, - PROP_DRIVE_ATA_SMART_IS_AVAILABLE, - g_param_spec_boolean ("drive-ata-smart-is-available", NULL, NULL, FALSE, G_PARAM_READABLE)); - g_object_class_install_property ( - object_class, - PROP_DRIVE_ATA_SMART_TIME_COLLECTED, - g_param_spec_uint64 ("drive-ata-smart-time-collected", NULL, NULL, 0, G_MAXUINT64, 0, G_PARAM_READABLE)); - g_object_class_install_property ( - object_class, - PROP_DRIVE_ATA_SMART_STATUS, - g_param_spec_string ("drive-ata-smart-status", NULL, NULL, NULL, G_PARAM_READABLE)); - g_object_class_install_property ( - object_class, - PROP_DRIVE_ATA_SMART_BLOB, - g_param_spec_boxed ("drive-ata-smart-blob", NULL, NULL, - dbus_g_type_get_collection ("GArray", G_TYPE_UCHAR), - G_PARAM_READABLE)); - - - g_object_class_install_property ( - object_class, - PROP_LINUX_MD_COMPONENT_LEVEL, - g_param_spec_string ("linux-md-component-level", NULL, NULL, NULL, G_PARAM_READABLE)); - g_object_class_install_property ( - object_class, - PROP_LINUX_MD_COMPONENT_POSITION, - g_param_spec_int ("linux-md-component-position", NULL, NULL, 0, G_MAXINT, 0, G_PARAM_READABLE)); - g_object_class_install_property ( - object_class, - PROP_LINUX_MD_COMPONENT_NUM_RAID_DEVICES, - g_param_spec_int ("linux-md-component-num-raid-devices", NULL, NULL, 0, G_MAXINT, 0, G_PARAM_READABLE)); - g_object_class_install_property ( - object_class, - PROP_LINUX_MD_COMPONENT_UUID, - g_param_spec_string ("linux-md-component-uuid", NULL, NULL, NULL, G_PARAM_READABLE)); - g_object_class_install_property ( - object_class, - PROP_LINUX_MD_COMPONENT_HOME_HOST, - g_param_spec_string ("linux-md-component-home-host", NULL, NULL, NULL, G_PARAM_READABLE)); - g_object_class_install_property ( - object_class, - PROP_LINUX_MD_COMPONENT_NAME, - g_param_spec_string ("linux-md-component-name", NULL, NULL, NULL, G_PARAM_READABLE)); - g_object_class_install_property ( - object_class, - PROP_LINUX_MD_COMPONENT_VERSION, - g_param_spec_string ("linux-md-component-version", NULL, NULL, NULL, G_PARAM_READABLE)); - g_object_class_install_property ( - object_class, - PROP_LINUX_MD_COMPONENT_HOLDER, - g_param_spec_boxed ("linux-md-component-holder", NULL, NULL, DBUS_TYPE_G_OBJECT_PATH, G_PARAM_READABLE)); - g_object_class_install_property ( - object_class, - PROP_LINUX_MD_COMPONENT_STATE, - g_param_spec_boxed ("linux-md-component-state", NULL, NULL, - dbus_g_type_get_collection ("GPtrArray", G_TYPE_STRING), - G_PARAM_READABLE)); - - g_object_class_install_property ( - object_class, - PROP_LINUX_MD_STATE, - g_param_spec_string ("linux-md-state", NULL, NULL, NULL, G_PARAM_READABLE)); - g_object_class_install_property ( - object_class, - PROP_LINUX_MD_LEVEL, - g_param_spec_string ("linux-md-level", NULL, NULL, NULL, G_PARAM_READABLE)); - g_object_class_install_property ( - object_class, - PROP_LINUX_MD_NUM_RAID_DEVICES, - g_param_spec_int ("linux-md-num-raid-devices", NULL, NULL, 0, G_MAXINT, 0, G_PARAM_READABLE)); - g_object_class_install_property ( - object_class, - PROP_LINUX_MD_UUID, - g_param_spec_string ("linux-md-uuid", NULL, NULL, NULL, G_PARAM_READABLE)); - g_object_class_install_property ( - object_class, - PROP_LINUX_MD_HOME_HOST, - g_param_spec_string ("linux-md-home-host", NULL, NULL, NULL, G_PARAM_READABLE)); - g_object_class_install_property ( - object_class, - PROP_LINUX_MD_NAME, - g_param_spec_string ("linux-md-name", NULL, NULL, NULL, G_PARAM_READABLE)); - g_object_class_install_property ( - object_class, - PROP_LINUX_MD_VERSION, - g_param_spec_string ("linux-md-version", NULL, NULL, NULL, G_PARAM_READABLE)); - g_object_class_install_property ( - object_class, - PROP_LINUX_MD_SLAVES, - g_param_spec_boxed ("linux-md-slaves", NULL, NULL, - dbus_g_type_get_collection ("GPtrArray", DBUS_TYPE_G_OBJECT_PATH), - G_PARAM_READABLE)); - g_object_class_install_property ( - object_class, - PROP_LINUX_MD_IS_DEGRADED, - g_param_spec_boolean ("linux-md-is-degraded", NULL, NULL, FALSE, G_PARAM_READABLE)); - g_object_class_install_property ( - object_class, - PROP_LINUX_MD_SYNC_ACTION, - g_param_spec_string ("linux-md-sync-action", NULL, NULL, NULL, G_PARAM_READABLE)); - g_object_class_install_property ( - object_class, - PROP_LINUX_MD_SYNC_PERCENTAGE, - g_param_spec_double ("linux-md-sync-percentage", NULL, NULL, 0.0, 100.0, 0.0, G_PARAM_READABLE)); - g_object_class_install_property ( - object_class, - PROP_LINUX_MD_SYNC_SPEED, - g_param_spec_uint64 ("linux-md-sync-speed", NULL, NULL, 0, G_MAXUINT64, 0, G_PARAM_READABLE)); + GObjectClass *object_class = G_OBJECT_CLASS (klass); + + object_class->constructor = device_constructor; + object_class->finalize = device_finalize; + object_class->get_property = get_property; + + g_type_class_add_private (klass, sizeof(DevicePrivate)); + + signals[CHANGED_SIGNAL] = g_signal_new ("changed", + G_OBJECT_CLASS_TYPE (klass), + G_SIGNAL_RUN_LAST | G_SIGNAL_DETAILED, + 0, + NULL, + NULL, + g_cclosure_marshal_VOID__VOID, + G_TYPE_NONE, + 0); + + signals[JOB_CHANGED_SIGNAL] = g_signal_new ("job-changed", + G_OBJECT_CLASS_TYPE (klass), + G_SIGNAL_RUN_LAST | G_SIGNAL_DETAILED, + 0, + NULL, + NULL, + marshal_VOID__BOOLEAN_STRING_UINT_BOOLEAN_DOUBLE, + G_TYPE_NONE, + 5, + G_TYPE_BOOLEAN, + G_TYPE_STRING, + G_TYPE_UINT, + G_TYPE_BOOLEAN, + G_TYPE_DOUBLE); + + dbus_g_object_type_install_info (TYPE_DEVICE, &dbus_glib_device_object_info); + + g_object_class_install_property (object_class, PROP_NATIVE_PATH, g_param_spec_string ("native-path", + NULL, + NULL, + NULL, + G_PARAM_READABLE)); + g_object_class_install_property (object_class, + PROP_DEVICE_DETECTION_TIME, + g_param_spec_uint64 ("device-detection-time", + NULL, + NULL, + 0, + G_MAXUINT64, + 0, + G_PARAM_READABLE)); + g_object_class_install_property (object_class, + PROP_DEVICE_MEDIA_DETECTION_TIME, + g_param_spec_uint64 ("device-media-detection-time", + NULL, + NULL, + 0, + G_MAXUINT64, + 0, + G_PARAM_READABLE)); + g_object_class_install_property (object_class, PROP_DEVICE_MAJOR, g_param_spec_int64 ("device-major", + NULL, + NULL, + -G_MAXINT64, + G_MAXINT64, + 0, + G_PARAM_READABLE)); + g_object_class_install_property (object_class, PROP_DEVICE_MINOR, g_param_spec_int64 ("device-minor", + NULL, + NULL, + -G_MAXINT64, + G_MAXINT64, + 0, + G_PARAM_READABLE)); + g_object_class_install_property (object_class, PROP_DEVICE_FILE, g_param_spec_string ("device-file", + NULL, + NULL, + NULL, + G_PARAM_READABLE)); + g_object_class_install_property (object_class, + PROP_DEVICE_FILE_BY_ID, + g_param_spec_boxed ("device-file-by-id", + NULL, + NULL, + dbus_g_type_get_collection ("GPtrArray", G_TYPE_STRING), + G_PARAM_READABLE)); + g_object_class_install_property (object_class, + PROP_DEVICE_FILE_BY_PATH, + g_param_spec_boxed ("device-file-by-path", + NULL, + NULL, + dbus_g_type_get_collection ("GPtrArray", G_TYPE_STRING), + G_PARAM_READABLE)); + g_object_class_install_property (object_class, + PROP_DEVICE_IS_SYSTEM_INTERNAL, + g_param_spec_boolean ("device-is-system-internal", + NULL, + NULL, + FALSE, + G_PARAM_READABLE)); + g_object_class_install_property (object_class, PROP_DEVICE_IS_PARTITION, g_param_spec_boolean ("device-is-partition", + NULL, + NULL, + FALSE, + G_PARAM_READABLE)); + g_object_class_install_property (object_class, + PROP_DEVICE_IS_PARTITION_TABLE, + g_param_spec_boolean ("device-is-partition-table", + NULL, + NULL, + FALSE, + G_PARAM_READABLE)); + g_object_class_install_property (object_class, PROP_DEVICE_IS_REMOVABLE, g_param_spec_boolean ("device-is-removable", + NULL, + NULL, + FALSE, + G_PARAM_READABLE)); + g_object_class_install_property (object_class, + PROP_DEVICE_IS_MEDIA_AVAILABLE, + g_param_spec_boolean ("device-is-media-available", + NULL, + NULL, + FALSE, + G_PARAM_READABLE)); + g_object_class_install_property (object_class, + PROP_DEVICE_IS_MEDIA_CHANGE_DETECTED, + g_param_spec_boolean ("device-is-media-change-detected", + NULL, + NULL, + FALSE, + G_PARAM_READABLE)); + g_object_class_install_property (object_class, + PROP_DEVICE_IS_MEDIA_CHANGE_DETECTION_POLLING, + g_param_spec_boolean ("device-is-media-change-detection-polling", + NULL, + NULL, + FALSE, + G_PARAM_READABLE)); + g_object_class_install_property (object_class, + PROP_DEVICE_IS_MEDIA_CHANGE_DETECTION_INHIBITABLE, + g_param_spec_boolean ("device-is-media-change-detection-inhibitable", + NULL, + NULL, + FALSE, + G_PARAM_READABLE)); + g_object_class_install_property (object_class, + PROP_DEVICE_IS_MEDIA_CHANGE_DETECTION_INHIBITED, + g_param_spec_boolean ("device-is-media-change-detection-inhibited", + NULL, + NULL, + FALSE, + G_PARAM_READABLE)); + g_object_class_install_property (object_class, PROP_DEVICE_IS_READ_ONLY, g_param_spec_boolean ("device-is-read-only", + NULL, + NULL, + FALSE, + G_PARAM_READABLE)); + g_object_class_install_property (object_class, PROP_DEVICE_IS_DRIVE, g_param_spec_boolean ("device-is-drive", + NULL, + NULL, + FALSE, + G_PARAM_READABLE)); + g_object_class_install_property (object_class, + PROP_DEVICE_IS_OPTICAL_DISC, + g_param_spec_boolean ("device-is-optical-disc", NULL, NULL, FALSE, G_PARAM_READABLE)); + g_object_class_install_property (object_class, PROP_DEVICE_IS_LUKS, g_param_spec_boolean ("device-is-luks", + NULL, + NULL, + FALSE, + G_PARAM_READABLE)); + g_object_class_install_property (object_class, + PROP_DEVICE_IS_LUKS_CLEARTEXT, + g_param_spec_boolean ("device-is-luks-cleartext", + NULL, + NULL, + FALSE, + G_PARAM_READABLE)); + g_object_class_install_property (object_class, + PROP_DEVICE_IS_LINUX_MD_COMPONENT, + g_param_spec_boolean ("device-is-linux-md-component", + NULL, + NULL, + FALSE, + G_PARAM_READABLE)); + g_object_class_install_property (object_class, PROP_DEVICE_IS_LINUX_MD, g_param_spec_boolean ("device-is-linux-md", + NULL, + NULL, + FALSE, + G_PARAM_READABLE)); + g_object_class_install_property (object_class, PROP_DEVICE_SIZE, g_param_spec_uint64 ("device-size", + NULL, + NULL, + 0, + G_MAXUINT64, + 0, + G_PARAM_READABLE)); + g_object_class_install_property (object_class, PROP_DEVICE_BLOCK_SIZE, g_param_spec_uint64 ("device-block-size", + NULL, + NULL, + 0, + G_MAXUINT64, + 0, + G_PARAM_READABLE)); + g_object_class_install_property (object_class, PROP_DEVICE_IS_MOUNTED, g_param_spec_boolean ("device-is-mounted", + NULL, + NULL, + FALSE, + G_PARAM_READABLE)); + g_object_class_install_property (object_class, + PROP_DEVICE_MOUNT_PATHS, + g_param_spec_boxed ("device-mount-paths", + NULL, + NULL, + dbus_g_type_get_collection ("GPtrArray", G_TYPE_STRING), + G_PARAM_READABLE)); + g_object_class_install_property (object_class, + PROP_DEVICE_MOUNTED_BY_UID, + g_param_spec_uint ("device-mounted-by-uid", + NULL, + NULL, + 0, + G_MAXUINT, + 0, + G_PARAM_READABLE)); + g_object_class_install_property (object_class, + PROP_DEVICE_PRESENTATION_HIDE, + g_param_spec_boolean ("device-presentation-hide", + NULL, + NULL, + FALSE, + G_PARAM_READABLE)); + g_object_class_install_property (object_class, + PROP_DEVICE_PRESENTATION_NOPOLICY, + g_param_spec_boolean ("device-presentation-nopolicy", + NULL, + NULL, + FALSE, + G_PARAM_READABLE)); + g_object_class_install_property (object_class, + PROP_DEVICE_PRESENTATION_NAME, + g_param_spec_string ("device-presentation-name", NULL, NULL, NULL, G_PARAM_READABLE)); + g_object_class_install_property (object_class, + PROP_DEVICE_PRESENTATION_ICON_NAME, + g_param_spec_string ("device-presentation-icon-name", + NULL, + NULL, + NULL, + G_PARAM_READABLE)); + + g_object_class_install_property (object_class, PROP_JOB_IN_PROGRESS, g_param_spec_boolean ("job-in-progress", + NULL, + NULL, + FALSE, + G_PARAM_READABLE)); + g_object_class_install_property (object_class, PROP_JOB_ID, g_param_spec_string ("job-id", + NULL, + NULL, + NULL, + G_PARAM_READABLE)); + g_object_class_install_property (object_class, PROP_JOB_INITIATED_BY_UID, g_param_spec_uint ("job-initiated-by-uid", + NULL, + NULL, + 0, + G_MAXUINT, + 0, + G_PARAM_READABLE)); + g_object_class_install_property (object_class, PROP_JOB_IS_CANCELLABLE, g_param_spec_boolean ("job-is-cancellable", + NULL, + NULL, + FALSE, + G_PARAM_READABLE)); + g_object_class_install_property (object_class, PROP_JOB_PERCENTAGE, g_param_spec_double ("job-percentage", + NULL, + NULL, + -1, + 100, + -1, + G_PARAM_READABLE)); + + g_object_class_install_property (object_class, PROP_ID_USAGE, g_param_spec_string ("id-usage", + NULL, + NULL, + NULL, + G_PARAM_READABLE)); + g_object_class_install_property (object_class, PROP_ID_TYPE, g_param_spec_string ("id-type", + NULL, + NULL, + NULL, + G_PARAM_READABLE)); + g_object_class_install_property (object_class, PROP_ID_VERSION, g_param_spec_string ("id-version", + NULL, + NULL, + NULL, + G_PARAM_READABLE)); + g_object_class_install_property (object_class, PROP_ID_UUID, g_param_spec_string ("id-uuid", + NULL, + NULL, + NULL, + G_PARAM_READABLE)); + g_object_class_install_property (object_class, PROP_ID_LABEL, g_param_spec_string ("id-label", + NULL, + NULL, + NULL, + G_PARAM_READABLE)); + + g_object_class_install_property (object_class, PROP_PARTITION_SLAVE, g_param_spec_boxed ("partition-slave", + NULL, + NULL, + DBUS_TYPE_G_OBJECT_PATH, + G_PARAM_READABLE)); + g_object_class_install_property (object_class, PROP_PARTITION_SCHEME, g_param_spec_string ("partition-scheme", + NULL, + NULL, + NULL, + G_PARAM_READABLE)); + g_object_class_install_property (object_class, PROP_PARTITION_TYPE, g_param_spec_string ("partition-type", + NULL, + NULL, + NULL, + G_PARAM_READABLE)); + g_object_class_install_property (object_class, PROP_PARTITION_LABEL, g_param_spec_string ("partition-label", + NULL, + NULL, + NULL, + G_PARAM_READABLE)); + g_object_class_install_property (object_class, PROP_PARTITION_UUID, g_param_spec_string ("partition-uuid", + NULL, + NULL, + NULL, + G_PARAM_READABLE)); + g_object_class_install_property (object_class, + PROP_PARTITION_FLAGS, + g_param_spec_boxed ("partition-flags", + NULL, + NULL, + dbus_g_type_get_collection ("GPtrArray", G_TYPE_STRING), + G_PARAM_READABLE)); + g_object_class_install_property (object_class, PROP_PARTITION_NUMBER, g_param_spec_int ("partition-number", + NULL, + NULL, + 0, + G_MAXINT, + 0, + G_PARAM_READABLE)); + g_object_class_install_property (object_class, PROP_PARTITION_OFFSET, g_param_spec_uint64 ("partition-offset", + NULL, + NULL, + 0, + G_MAXUINT64, + 0, + G_PARAM_READABLE)); + g_object_class_install_property (object_class, PROP_PARTITION_SIZE, g_param_spec_uint64 ("partition-size", + NULL, + NULL, + 0, + G_MAXUINT64, + 0, + G_PARAM_READABLE)); + + g_object_class_install_property (object_class, + PROP_PARTITION_TABLE_SCHEME, + g_param_spec_string ("partition-table-scheme", NULL, NULL, NULL, G_PARAM_READABLE)); + g_object_class_install_property (object_class, PROP_PARTITION_TABLE_COUNT, g_param_spec_int ("partition-table-count", + NULL, + NULL, + 0, + G_MAXINT, + 0, + G_PARAM_READABLE)); + + g_object_class_install_property (object_class, PROP_LUKS_HOLDER, g_param_spec_boxed ("luks-holder", + NULL, + NULL, + DBUS_TYPE_G_OBJECT_PATH, + G_PARAM_READABLE)); + + g_object_class_install_property (object_class, + PROP_LUKS_CLEARTEXT_SLAVE, + g_param_spec_boxed ("luks-cleartext-slave", + NULL, + NULL, + DBUS_TYPE_G_OBJECT_PATH, + G_PARAM_READABLE)); + g_object_class_install_property (object_class, + PROP_LUKS_CLEARTEXT_UNLOCKED_BY_UID, + g_param_spec_uint ("luks-cleartext-unlocked-by-uid", + NULL, + NULL, + 0, + G_MAXUINT, + 0, + G_PARAM_READABLE)); + + g_object_class_install_property (object_class, PROP_DRIVE_VENDOR, g_param_spec_string ("drive-vendor", + NULL, + NULL, + NULL, + G_PARAM_READABLE)); + g_object_class_install_property (object_class, PROP_DRIVE_MODEL, g_param_spec_string ("drive-model", + NULL, + NULL, + NULL, + G_PARAM_READABLE)); + g_object_class_install_property (object_class, PROP_DRIVE_REVISION, g_param_spec_string ("drive-revision", + NULL, + NULL, + NULL, + G_PARAM_READABLE)); + g_object_class_install_property (object_class, PROP_DRIVE_SERIAL, g_param_spec_string ("drive-serial", + NULL, + NULL, + NULL, + G_PARAM_READABLE)); + g_object_class_install_property (object_class, PROP_DRIVE_WWN, g_param_spec_string ("drive-wwn", + NULL, + NULL, + NULL, + G_PARAM_READABLE)); + g_object_class_install_property (object_class, + PROP_DRIVE_CONNECTION_INTERFACE, + g_param_spec_string ("drive-connection-interface", + NULL, + NULL, + NULL, + G_PARAM_READABLE)); + g_object_class_install_property (object_class, + PROP_DRIVE_CONNECTION_SPEED, + g_param_spec_uint64 ("drive-connection-speed", + NULL, + NULL, + 0, + G_MAXUINT64, + 0, + G_PARAM_READABLE)); + g_object_class_install_property (object_class, + PROP_DRIVE_MEDIA_COMPATIBILITY, + g_param_spec_boxed ("drive-media-compatibility", + NULL, + NULL, + dbus_g_type_get_collection ("GPtrArray", G_TYPE_STRING), + G_PARAM_READABLE)); + g_object_class_install_property (object_class, PROP_DRIVE_MEDIA, g_param_spec_string ("drive-media", + NULL, + NULL, + NULL, + G_PARAM_READABLE)); + g_object_class_install_property (object_class, + PROP_DRIVE_IS_MEDIA_EJECTABLE, + g_param_spec_boolean ("drive-is-media-ejectable", + NULL, + NULL, + FALSE, + G_PARAM_READABLE)); + g_object_class_install_property (object_class, PROP_DRIVE_CAN_DETACH, g_param_spec_boolean ("drive-can-detach", + NULL, + NULL, + FALSE, + G_PARAM_READABLE)); + g_object_class_install_property (object_class, PROP_DRIVE_CAN_SPINDOWN, g_param_spec_boolean ("drive-can-spindown", + NULL, + NULL, + FALSE, + G_PARAM_READABLE)); + g_object_class_install_property (object_class, PROP_DRIVE_IS_ROTATIONAL, g_param_spec_boolean ("drive-is-rotational", + NULL, + NULL, + FALSE, + G_PARAM_READABLE)); + g_object_class_install_property (object_class, PROP_DRIVE_ROTATION_RATE, g_param_spec_uint ("drive-rotation-rate", + NULL, + NULL, + 0, + G_MAXUINT, + 0, + G_PARAM_READABLE)); + g_object_class_install_property (object_class, PROP_DRIVE_WRITE_CACHE, g_param_spec_string ("drive-write-cache", + NULL, + NULL, + FALSE, + G_PARAM_READABLE)); + g_object_class_install_property (object_class, PROP_DRIVE_ADAPTER, g_param_spec_boxed ("drive-adapter", + NULL, + NULL, + DBUS_TYPE_G_OBJECT_PATH, + G_PARAM_READABLE)); + g_object_class_install_property (object_class, + PROP_DRIVE_PORTS, + g_param_spec_boxed ("drive-ports", + NULL, + NULL, + dbus_g_type_get_collection ("GPtrArray", DBUS_TYPE_G_OBJECT_PATH), + G_PARAM_READABLE)); + + g_object_class_install_property (object_class, + PROP_OPTICAL_DISC_IS_BLANK, + g_param_spec_boolean ("optical-disc-is-blank", NULL, NULL, FALSE, G_PARAM_READABLE)); + g_object_class_install_property (object_class, + PROP_OPTICAL_DISC_IS_APPENDABLE, + g_param_spec_boolean ("optical-disc-is-appendable", + NULL, + NULL, + FALSE, + G_PARAM_READABLE)); + g_object_class_install_property (object_class, + PROP_OPTICAL_DISC_IS_CLOSED, + g_param_spec_boolean ("optical-disc-is-closed", NULL, NULL, FALSE, G_PARAM_READABLE)); + g_object_class_install_property (object_class, + PROP_OPTICAL_DISC_NUM_TRACKS, + g_param_spec_uint ("optical-disc-num-tracks", + NULL, + NULL, + 0, + G_MAXUINT, + 0, + G_PARAM_READABLE)); + g_object_class_install_property (object_class, + PROP_OPTICAL_DISC_NUM_AUDIO_TRACKS, + g_param_spec_uint ("optical-disc-num-audio-tracks", + NULL, + NULL, + 0, + G_MAXUINT, + 0, + G_PARAM_READABLE)); + g_object_class_install_property (object_class, + PROP_OPTICAL_DISC_NUM_SESSIONS, + g_param_spec_uint ("optical-disc-num-sessions", + NULL, + NULL, + 0, + G_MAXUINT, + 0, + G_PARAM_READABLE)); + + g_object_class_install_property (object_class, + PROP_DRIVE_ATA_SMART_IS_AVAILABLE, + g_param_spec_boolean ("drive-ata-smart-is-available", + NULL, + NULL, + FALSE, + G_PARAM_READABLE)); + g_object_class_install_property (object_class, + PROP_DRIVE_ATA_SMART_TIME_COLLECTED, + g_param_spec_uint64 ("drive-ata-smart-time-collected", + NULL, + NULL, + 0, + G_MAXUINT64, + 0, + G_PARAM_READABLE)); + g_object_class_install_property (object_class, + PROP_DRIVE_ATA_SMART_STATUS, + g_param_spec_string ("drive-ata-smart-status", NULL, NULL, NULL, G_PARAM_READABLE)); + g_object_class_install_property (object_class, + PROP_DRIVE_ATA_SMART_BLOB, + g_param_spec_boxed ("drive-ata-smart-blob", + NULL, + NULL, + dbus_g_type_get_collection ("GArray", G_TYPE_UCHAR), + G_PARAM_READABLE)); + + g_object_class_install_property (object_class, + PROP_LINUX_MD_COMPONENT_LEVEL, + g_param_spec_string ("linux-md-component-level", NULL, NULL, NULL, G_PARAM_READABLE)); + g_object_class_install_property (object_class, + PROP_LINUX_MD_COMPONENT_POSITION, + g_param_spec_int ("linux-md-component-position", + NULL, + NULL, + 0, + G_MAXINT, + 0, + G_PARAM_READABLE)); + g_object_class_install_property (object_class, + PROP_LINUX_MD_COMPONENT_NUM_RAID_DEVICES, + g_param_spec_int ("linux-md-component-num-raid-devices", + NULL, + NULL, + 0, + G_MAXINT, + 0, + G_PARAM_READABLE)); + g_object_class_install_property (object_class, + PROP_LINUX_MD_COMPONENT_UUID, + g_param_spec_string ("linux-md-component-uuid", NULL, NULL, NULL, G_PARAM_READABLE)); + g_object_class_install_property (object_class, + PROP_LINUX_MD_COMPONENT_HOME_HOST, + g_param_spec_string ("linux-md-component-home-host", + NULL, + NULL, + NULL, + G_PARAM_READABLE)); + g_object_class_install_property (object_class, + PROP_LINUX_MD_COMPONENT_NAME, + g_param_spec_string ("linux-md-component-name", NULL, NULL, NULL, G_PARAM_READABLE)); + g_object_class_install_property (object_class, + PROP_LINUX_MD_COMPONENT_VERSION, + g_param_spec_string ("linux-md-component-version", + NULL, + NULL, + NULL, + G_PARAM_READABLE)); + g_object_class_install_property (object_class, + PROP_LINUX_MD_COMPONENT_HOLDER, + g_param_spec_boxed ("linux-md-component-holder", + NULL, + NULL, + DBUS_TYPE_G_OBJECT_PATH, + G_PARAM_READABLE)); + g_object_class_install_property (object_class, + PROP_LINUX_MD_COMPONENT_STATE, + g_param_spec_boxed ("linux-md-component-state", + NULL, + NULL, + dbus_g_type_get_collection ("GPtrArray", G_TYPE_STRING), + G_PARAM_READABLE)); + + g_object_class_install_property (object_class, PROP_LINUX_MD_STATE, g_param_spec_string ("linux-md-state", + NULL, + NULL, + NULL, + G_PARAM_READABLE)); + g_object_class_install_property (object_class, PROP_LINUX_MD_LEVEL, g_param_spec_string ("linux-md-level", + NULL, + NULL, + NULL, + G_PARAM_READABLE)); + g_object_class_install_property (object_class, + PROP_LINUX_MD_NUM_RAID_DEVICES, + g_param_spec_int ("linux-md-num-raid-devices", + NULL, + NULL, + 0, + G_MAXINT, + 0, + G_PARAM_READABLE)); + g_object_class_install_property (object_class, PROP_LINUX_MD_UUID, g_param_spec_string ("linux-md-uuid", + NULL, + NULL, + NULL, + G_PARAM_READABLE)); + g_object_class_install_property (object_class, PROP_LINUX_MD_HOME_HOST, g_param_spec_string ("linux-md-home-host", + NULL, + NULL, + NULL, + G_PARAM_READABLE)); + g_object_class_install_property (object_class, PROP_LINUX_MD_NAME, g_param_spec_string ("linux-md-name", + NULL, + NULL, + NULL, + G_PARAM_READABLE)); + g_object_class_install_property (object_class, PROP_LINUX_MD_VERSION, g_param_spec_string ("linux-md-version", + NULL, + NULL, + NULL, + G_PARAM_READABLE)); + g_object_class_install_property (object_class, + PROP_LINUX_MD_SLAVES, + g_param_spec_boxed ("linux-md-slaves", + NULL, + NULL, + dbus_g_type_get_collection ("GPtrArray", DBUS_TYPE_G_OBJECT_PATH), + G_PARAM_READABLE)); + g_object_class_install_property (object_class, + PROP_LINUX_MD_IS_DEGRADED, + g_param_spec_boolean ("linux-md-is-degraded", NULL, NULL, FALSE, G_PARAM_READABLE)); + g_object_class_install_property (object_class, + PROP_LINUX_MD_SYNC_ACTION, + g_param_spec_string ("linux-md-sync-action", NULL, NULL, NULL, G_PARAM_READABLE)); + g_object_class_install_property (object_class, + PROP_LINUX_MD_SYNC_PERCENTAGE, + g_param_spec_double ("linux-md-sync-percentage", + NULL, + NULL, + 0.0, + 100.0, + 0.0, + G_PARAM_READABLE)); + g_object_class_install_property (object_class, PROP_LINUX_MD_SYNC_SPEED, g_param_spec_uint64 ("linux-md-sync-speed", + NULL, + NULL, + 0, + G_MAXUINT64, + 0, + G_PARAM_READABLE)); } static void device_init (Device *device) { - device->priv = DEVICE_GET_PRIVATE (device); + device->priv = DEVICE_GET_PRIVATE (device); - device->priv->device_file_by_id = g_ptr_array_new (); - device->priv->device_file_by_path = g_ptr_array_new (); - device->priv->device_mount_paths = g_ptr_array_new (); - device->priv->partition_flags = g_ptr_array_new (); - device->priv->drive_media_compatibility = g_ptr_array_new (); - device->priv->drive_ports = g_ptr_array_new (); - device->priv->linux_md_component_state = g_ptr_array_new (); - device->priv->linux_md_slaves = g_ptr_array_new (); - device->priv->slaves_objpath = g_ptr_array_new (); - device->priv->holders_objpath = g_ptr_array_new (); + device->priv->device_file_by_id = g_ptr_array_new (); + device->priv->device_file_by_path = g_ptr_array_new (); + device->priv->device_mount_paths = g_ptr_array_new (); + device->priv->partition_flags = g_ptr_array_new (); + device->priv->drive_media_compatibility = g_ptr_array_new (); + device->priv->drive_ports = g_ptr_array_new (); + device->priv->linux_md_component_state = g_ptr_array_new (); + device->priv->linux_md_slaves = g_ptr_array_new (); + device->priv->slaves_objpath = g_ptr_array_new (); + device->priv->holders_objpath = g_ptr_array_new (); - device->priv->drive_ata_smart_status = -1; + device->priv->drive_ata_smart_status = -1; } static void device_finalize (GObject *object) { - Device *device; - GList *l; - - g_return_if_fail (object != NULL); - g_return_if_fail (IS_DEVICE (object)); - - device = DEVICE (object); - g_return_if_fail (device->priv != NULL); - - /* g_debug ("finalizing %s", device->priv->native_path); */ - - g_object_unref (device->priv->d); - g_object_unref (device->priv->daemon); - g_free (device->priv->object_path); - - g_free (device->priv->native_path); - - for (l = device->priv->polling_inhibitors; l != NULL; l = l->next) { - Inhibitor *inhibitor = INHIBITOR (l->data); - g_signal_handlers_disconnect_by_func (inhibitor, polling_inhibitor_disconnected_cb, device); - g_object_unref (inhibitor); - } - g_list_free (device->priv->polling_inhibitors); - - for (l = device->priv->spindown_inhibitors; l != NULL; l = l->next) { - Inhibitor *inhibitor = INHIBITOR (l->data); - g_signal_handlers_disconnect_by_func (inhibitor, spindown_inhibitor_disconnected_cb, device); - g_object_unref (inhibitor); - } - g_list_free (device->priv->spindown_inhibitors); - - if (device->priv->linux_md_poll_timeout_id > 0) - g_source_remove (device->priv->linux_md_poll_timeout_id); - - if (device->priv->emit_changed_idle_id > 0) - g_source_remove (device->priv->emit_changed_idle_id); - - /* free properties */ - g_free (device->priv->device_file); - g_ptr_array_foreach (device->priv->device_file_by_id, (GFunc) g_free, NULL); - g_ptr_array_foreach (device->priv->device_file_by_path, (GFunc) g_free, NULL); - g_ptr_array_free (device->priv->device_file_by_id, TRUE); - g_ptr_array_free (device->priv->device_file_by_path, TRUE); - g_ptr_array_free (device->priv->device_mount_paths, TRUE); - g_free (device->priv->device_presentation_name); - g_free (device->priv->device_presentation_icon_name); - - g_free (device->priv->id_usage); - g_free (device->priv->id_type); - g_free (device->priv->id_version); - g_free (device->priv->id_uuid); - g_free (device->priv->id_label); - - g_free (device->priv->partition_slave); - g_free (device->priv->partition_scheme); - g_free (device->priv->partition_type); - g_free (device->priv->partition_label); - g_free (device->priv->partition_uuid); - g_ptr_array_foreach (device->priv->partition_flags, (GFunc) g_free, NULL); - g_ptr_array_free (device->priv->partition_flags, TRUE); - - g_free (device->priv->partition_table_scheme); - - g_free (device->priv->luks_holder); - - g_free (device->priv->luks_cleartext_slave); - - g_free (device->priv->drive_vendor); - g_free (device->priv->drive_model); - g_free (device->priv->drive_revision); - g_free (device->priv->drive_serial); - g_free (device->priv->drive_wwn); - g_free (device->priv->drive_connection_interface); - g_ptr_array_foreach (device->priv->drive_media_compatibility, (GFunc) g_free, NULL); - g_ptr_array_free (device->priv->drive_media_compatibility, TRUE); - g_free (device->priv->drive_media); - g_free (device->priv->drive_write_cache); - g_free (device->priv->drive_adapter); - g_ptr_array_foreach (device->priv->drive_ports, (GFunc) g_free, NULL); - g_ptr_array_free (device->priv->drive_ports, TRUE); - - g_free (device->priv->linux_md_component_level); - g_free (device->priv->linux_md_component_uuid); - g_free (device->priv->linux_md_component_home_host); - g_free (device->priv->linux_md_component_name); - g_free (device->priv->linux_md_component_version); - g_free (device->priv->linux_md_component_holder); - g_ptr_array_foreach (device->priv->linux_md_component_state, (GFunc) g_free, NULL); - g_ptr_array_free (device->priv->linux_md_component_state, TRUE); - - g_free (device->priv->linux_md_state); - g_free (device->priv->linux_md_level); - g_free (device->priv->linux_md_uuid); - g_free (device->priv->linux_md_home_host); - g_free (device->priv->linux_md_name); - g_free (device->priv->linux_md_version); - g_ptr_array_foreach (device->priv->linux_md_slaves, (GFunc) g_free, NULL); - g_ptr_array_free (device->priv->linux_md_slaves, TRUE); - - g_free (device->priv->drive_ata_smart_blob); - - g_free (device->priv->dm_name); - g_ptr_array_foreach (device->priv->slaves_objpath, (GFunc) g_free, NULL); - g_ptr_array_free (device->priv->slaves_objpath, TRUE); - g_ptr_array_foreach (device->priv->holders_objpath, (GFunc) g_free, NULL); - g_ptr_array_free (device->priv->holders_objpath, TRUE); - - - G_OBJECT_CLASS (device_parent_class)->finalize (object); + Device *device; + GList *l; + + g_return_if_fail (object != NULL); + g_return_if_fail (IS_DEVICE (object)); + + device = DEVICE (object); + g_return_if_fail (device->priv != NULL); + + /* g_debug ("finalizing %s", device->priv->native_path); */ + + g_object_unref (device->priv->d); + g_object_unref (device->priv->daemon); + g_free (device->priv->object_path); + + g_free (device->priv->native_path); + + for (l = device->priv->polling_inhibitors; l != NULL; l = l->next) + { + Inhibitor *inhibitor = INHIBITOR (l->data); + g_signal_handlers_disconnect_by_func (inhibitor, polling_inhibitor_disconnected_cb, device); + g_object_unref (inhibitor); + } + g_list_free (device->priv->polling_inhibitors); + + for (l = device->priv->spindown_inhibitors; l != NULL; l = l->next) + { + Inhibitor *inhibitor = INHIBITOR (l->data); + g_signal_handlers_disconnect_by_func (inhibitor, spindown_inhibitor_disconnected_cb, device); + g_object_unref (inhibitor); + } + g_list_free (device->priv->spindown_inhibitors); + + if (device->priv->linux_md_poll_timeout_id > 0) + g_source_remove (device->priv->linux_md_poll_timeout_id); + + if (device->priv->emit_changed_idle_id > 0) + g_source_remove (device->priv->emit_changed_idle_id); + + /* free properties */ + g_free (device->priv->device_file); + g_ptr_array_foreach (device->priv->device_file_by_id, (GFunc) g_free, NULL); + g_ptr_array_foreach (device->priv->device_file_by_path, (GFunc) g_free, NULL); + g_ptr_array_free (device->priv->device_file_by_id, TRUE); + g_ptr_array_free (device->priv->device_file_by_path, TRUE); + g_ptr_array_free (device->priv->device_mount_paths, TRUE); + g_free (device->priv->device_presentation_name); + g_free (device->priv->device_presentation_icon_name); + + g_free (device->priv->id_usage); + g_free (device->priv->id_type); + g_free (device->priv->id_version); + g_free (device->priv->id_uuid); + g_free (device->priv->id_label); + + g_free (device->priv->partition_slave); + g_free (device->priv->partition_scheme); + g_free (device->priv->partition_type); + g_free (device->priv->partition_label); + g_free (device->priv->partition_uuid); + g_ptr_array_foreach (device->priv->partition_flags, (GFunc) g_free, NULL); + g_ptr_array_free (device->priv->partition_flags, TRUE); + + g_free (device->priv->partition_table_scheme); + + g_free (device->priv->luks_holder); + + g_free (device->priv->luks_cleartext_slave); + + g_free (device->priv->drive_vendor); + g_free (device->priv->drive_model); + g_free (device->priv->drive_revision); + g_free (device->priv->drive_serial); + g_free (device->priv->drive_wwn); + g_free (device->priv->drive_connection_interface); + g_ptr_array_foreach (device->priv->drive_media_compatibility, (GFunc) g_free, NULL); + g_ptr_array_free (device->priv->drive_media_compatibility, TRUE); + g_free (device->priv->drive_media); + g_free (device->priv->drive_write_cache); + g_free (device->priv->drive_adapter); + g_ptr_array_foreach (device->priv->drive_ports, (GFunc) g_free, NULL); + g_ptr_array_free (device->priv->drive_ports, TRUE); + + g_free (device->priv->linux_md_component_level); + g_free (device->priv->linux_md_component_uuid); + g_free (device->priv->linux_md_component_home_host); + g_free (device->priv->linux_md_component_name); + g_free (device->priv->linux_md_component_version); + g_free (device->priv->linux_md_component_holder); + g_ptr_array_foreach (device->priv->linux_md_component_state, (GFunc) g_free, NULL); + g_ptr_array_free (device->priv->linux_md_component_state, TRUE); + + g_free (device->priv->linux_md_state); + g_free (device->priv->linux_md_level); + g_free (device->priv->linux_md_uuid); + g_free (device->priv->linux_md_home_host); + g_free (device->priv->linux_md_name); + g_free (device->priv->linux_md_version); + g_ptr_array_foreach (device->priv->linux_md_slaves, (GFunc) g_free, NULL); + g_ptr_array_free (device->priv->linux_md_slaves, TRUE); + + g_free (device->priv->drive_ata_smart_blob); + + g_free (device->priv->dm_name); + g_ptr_array_foreach (device->priv->slaves_objpath, (GFunc) g_free, NULL); + g_ptr_array_free (device->priv->slaves_objpath, TRUE); + g_ptr_array_foreach (device->priv->holders_objpath, (GFunc) g_free, NULL); + g_ptr_array_free (device->priv->holders_objpath, TRUE); + + G_OBJECT_CLASS (device_parent_class)->finalize (object); } /** @@ -1295,233 +1494,254 @@ device_finalize (GObject *object) static char * compute_object_path (const char *native_path) { - const gchar *basename; - GString *s; - guint n; - - basename = strrchr (native_path, '/'); - if (basename != NULL) { - basename++; - } else { - basename = native_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 _ */ - g_string_append_printf (s, "_%02x", c); - } + const gchar *basename; + GString *s; + guint n; + + basename = strrchr (native_path, '/'); + if (basename != NULL) + { + basename++; + } + else + { + basename = native_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 _ */ + g_string_append_printf (s, "_%02x", c); } + } - return g_string_free (s, FALSE); + return g_string_free (s, FALSE); } static gboolean register_disks_device (Device *device) { - DBusConnection *connection; - GError *error = NULL; + DBusConnection *connection; + GError *error = NULL; - device->priv->system_bus_connection = dbus_g_bus_get (DBUS_BUS_SYSTEM, &error); - if (device->priv->system_bus_connection == NULL) { - if (error != NULL) { - g_critical ("error getting system bus: %s", error->message); - g_error_free (error); - } - goto error; + device->priv->system_bus_connection = dbus_g_bus_get (DBUS_BUS_SYSTEM, &error); + if (device->priv->system_bus_connection == NULL) + { + if (error != NULL) + { + g_critical ("error getting system bus: %s", error->message); + g_error_free (error); } - connection = dbus_g_connection_get_connection (device->priv->system_bus_connection); + goto error; + } + connection = dbus_g_connection_get_connection (device->priv->system_bus_connection); - device->priv->object_path = compute_object_path (device->priv->native_path); + device->priv->object_path = compute_object_path (device->priv->native_path); - /* safety first */ - if (dbus_g_connection_lookup_g_object (device->priv->system_bus_connection, - device->priv->object_path) != NULL) { - g_error ("**** HACK: Wanting to register object at path `%s' but there is already an " - "object there. This is an internal error in the daemon. Aborting.\n", - device->priv->object_path); - } + /* safety first */ + if (dbus_g_connection_lookup_g_object (device->priv->system_bus_connection, device->priv->object_path) != NULL) + { + g_error ("**** HACK: Wanting to register object at path `%s' but there is already an " + "object there. This is an internal error in the daemon. Aborting.\n", device->priv->object_path); + } - dbus_g_connection_register_g_object (device->priv->system_bus_connection, - device->priv->object_path, - G_OBJECT (device)); + dbus_g_connection_register_g_object (device->priv->system_bus_connection, + device->priv->object_path, + G_OBJECT (device)); - return TRUE; + return TRUE; -error: - return FALSE; + error: + return FALSE; } static double -sysfs_get_double (const char *dir, const char *attribute) +sysfs_get_double (const char *dir, + const char *attribute) { - double result; - char *contents; - char *filename; - - result = 0.0; - filename = g_build_filename (dir, attribute, NULL); - if (g_file_get_contents (filename, &contents, NULL, NULL)) { - result = atof (contents); - g_free (contents); - } - g_free (filename); + double result; + char *contents; + char *filename; + result = 0.0; + filename = g_build_filename (dir, attribute, NULL); + if (g_file_get_contents (filename, &contents, NULL, NULL)) + { + result = atof (contents); + g_free (contents); + } + g_free (filename); - return result; + return result; } static char * -sysfs_get_string (const char *dir, const char *attribute) +sysfs_get_string (const char *dir, + const char *attribute) { - char *result; - char *filename; + char *result; + char *filename; - result = NULL; - filename = g_build_filename (dir, attribute, NULL); - if (!g_file_get_contents (filename, &result, NULL, NULL)) { - result = g_strdup (""); - } - g_free (filename); + result = NULL; + filename = g_build_filename (dir, attribute, NULL); + if (!g_file_get_contents (filename, &result, NULL, NULL)) + { + result = g_strdup (""); + } + g_free (filename); - return result; + return result; } static int -sysfs_get_int (const char *dir, const char *attribute) +sysfs_get_int (const char *dir, + const char *attribute) { - int result; - char *contents; - char *filename; - - result = 0; - filename = g_build_filename (dir, attribute, NULL); - if (g_file_get_contents (filename, &contents, NULL, NULL)) { - result = strtol (contents, NULL, 0); - g_free (contents); - } - g_free (filename); + int result; + char *contents; + char *filename; + result = 0; + filename = g_build_filename (dir, attribute, NULL); + if (g_file_get_contents (filename, &contents, NULL, NULL)) + { + result = strtol (contents, NULL, 0); + g_free (contents); + } + g_free (filename); - return result; + return result; } static guint64 -sysfs_get_uint64 (const char *dir, const char *attribute) +sysfs_get_uint64 (const char *dir, + const char *attribute) { - guint64 result; - char *contents; - char *filename; + guint64 result; + char *contents; + char *filename; - result = 0; - filename = g_build_filename (dir, attribute, NULL); - if (g_file_get_contents (filename, &contents, NULL, NULL)) { - result = strtoll (contents, NULL, 0); - g_free (contents); - } - g_free (filename); + result = 0; + filename = g_build_filename (dir, attribute, NULL); + if (g_file_get_contents (filename, &contents, NULL, NULL)) + { + result = strtoll (contents, NULL, 0); + g_free (contents); + } + g_free (filename); - return result; + return result; } static gboolean -sysfs_file_exists (const char *dir, const char *attribute) +sysfs_file_exists (const char *dir, + const char *attribute) { - gboolean result; - char *filename; + gboolean result; + char *filename; - result = FALSE; - filename = g_build_filename (dir, attribute, NULL); - if (g_file_test (filename, G_FILE_TEST_EXISTS)) { - result = TRUE; - } - g_free (filename); + result = FALSE; + filename = g_build_filename (dir, attribute, NULL); + if (g_file_test (filename, G_FILE_TEST_EXISTS)) + { + result = TRUE; + } + g_free (filename); - return result; + return result; } static void device_generate_kernel_change_event (Device *device) { - FILE *f; - char *filename; + FILE *f; + char *filename; - filename = g_build_filename (device->priv->native_path, "uevent", NULL); - f = fopen (filename, "w"); - if (f == NULL) { - g_warning ("error opening %s for writing: %m", filename); - } else { - if (fputs ("change", f) == EOF) { - g_warning ("error writing 'change' to %s: %m", filename); - } - fclose (f); + filename = g_build_filename (device->priv->native_path, "uevent", NULL); + f = fopen (filename, "w"); + if (f == NULL) + { + g_warning ("error opening %s for writing: %m", filename); + } + else + { + if (fputs ("change", f) == EOF) + { + g_warning ("error writing 'change' to %s: %m", filename); } - g_free (filename); + fclose (f); + } + g_free (filename); } static char * _dupv8 (const char *s) { - const char *end_valid; + const char *end_valid; - if (!g_utf8_validate (s, - -1, - &end_valid)) { - g_print ("**** NOTE: The string '%s' is not valid UTF-8. Invalid characters begins at '%s'\n", - s, end_valid); - return g_strndup (s, end_valid - s); - } else { - return g_strdup (s); - } + if (!g_utf8_validate (s, -1, &end_valid)) + { + g_print ("**** NOTE: The string '%s' is not valid UTF-8. Invalid characters begins at '%s'\n", s, end_valid); + return g_strndup (s, end_valid - s); + } + else + { + return g_strdup (s); + } } static char * -sysfs_resolve_link (const char *sysfs_path, const char *name) +sysfs_resolve_link (const char *sysfs_path, + const char *name) { - char *full_path; - char link_path[PATH_MAX]; - char resolved_path[PATH_MAX]; - ssize_t num; - gboolean found_it; + char *full_path; + char link_path[PATH_MAX]; + char resolved_path[PATH_MAX]; + ssize_t num; + gboolean found_it; - found_it = FALSE; + found_it = FALSE; - full_path = g_build_filename (sysfs_path, name, NULL); + full_path = g_build_filename (sysfs_path, name, NULL); - //g_debug ("name='%s'", name); - //g_debug ("full_path='%s'", full_path); - num = readlink (full_path, link_path, sizeof (link_path) - 1); - if (num != -1) { - char *absolute_path; + //g_debug ("name='%s'", name); + //g_debug ("full_path='%s'", full_path); + num = readlink (full_path, link_path, sizeof(link_path) - 1); + if (num != -1) + { + char *absolute_path; - link_path[num] = '\0'; + link_path[num] = '\0'; - //g_debug ("link_path='%s'", link_path); - absolute_path = g_build_filename (sysfs_path, link_path, NULL); - //g_debug ("absolute_path='%s'", absolute_path); - if (realpath (absolute_path, resolved_path) != NULL) { - //g_debug ("resolved_path='%s'", resolved_path); - found_it = TRUE; - } - g_free (absolute_path); + //g_debug ("link_path='%s'", link_path); + absolute_path = g_build_filename (sysfs_path, link_path, NULL); + //g_debug ("absolute_path='%s'", absolute_path); + if (realpath (absolute_path, resolved_path) != NULL) + { + //g_debug ("resolved_path='%s'", resolved_path); + found_it = TRUE; } - g_free (full_path); + g_free (absolute_path); + } + g_free (full_path); - if (found_it) - return g_strdup (resolved_path); - else - return NULL; + if (found_it) + return g_strdup (resolved_path); + else + return NULL; } /* unescapes things like \x20 to " " and ensures the returned string is valid UTF-8. @@ -1532,88 +1752,95 @@ sysfs_resolve_link (const char *sysfs_path, const char *name) static gchar * decode_udev_encoded_string (const gchar *str) { - GString *s; - gchar *ret; - const gchar *end_valid; - guint n; + GString *s; + gchar *ret; + const gchar *end_valid; + guint n; - s = g_string_new (NULL); - for (n = 0; str[n] != '\0'; n++) { - if (str[n] == '\\') { - gint val; + s = g_string_new (NULL); + for (n = 0; str[n] != '\0'; n++) + { + if (str[n] == '\\') + { + gint val; - if (str[n + 1] != 'x' || str[n + 2] == '\0' || str[n + 3] == '\0') { - g_print ("**** NOTE: malformed encoded string '%s'\n", str); - break; - } + if (str[n + 1] != 'x' || str[n + 2] == '\0' || str[n + 3] == '\0') + { + g_print ("**** NOTE: malformed encoded string '%s'\n", str); + break; + } - val = (g_ascii_xdigit_value (str[n + 2]) << 4) | g_ascii_xdigit_value (str[n + 3]); + val = (g_ascii_xdigit_value (str[n + 2]) << 4) | g_ascii_xdigit_value (str[n + 3]); - g_string_append_c (s, val); + g_string_append_c (s, val); - n += 3; - } else { - g_string_append_c (s, str[n]); - } + n += 3; } - - if (!g_utf8_validate (s->str, -1, &end_valid)) { - g_print ("**** NOTE: The string '%s' is not valid UTF-8. Invalid characters begins at '%s'\n", - s->str, end_valid); - ret = g_strndup (s->str, end_valid - s->str); - g_string_free (s, TRUE); - } else { - ret = g_string_free (s, FALSE); + else + { + g_string_append_c (s, str[n]); } + } + + if (!g_utf8_validate (s->str, -1, &end_valid)) + { + g_print ("**** NOTE: The string '%s' is not valid UTF-8. Invalid characters begins at '%s'\n", s->str, end_valid); + ret = g_strndup (s->str, end_valid - s->str); + g_string_free (s, TRUE); + } + else + { + ret = g_string_free (s, FALSE); + } - return ret; + return ret; } static gboolean poll_syncing_md_device (gpointer user_data) { - Device *device = DEVICE (user_data); + Device *device = DEVICE (user_data); - g_print ("**** POLL SYNCING MD %s\n", device->priv->native_path); + g_print ("**** POLL SYNCING MD %s\n", device->priv->native_path); - device->priv->linux_md_poll_timeout_id = 0; - daemon_local_synthesize_changed (device->priv->daemon, device); - return FALSE; + device->priv->linux_md_poll_timeout_id = 0; + daemon_local_synthesize_changed (device->priv->daemon, device); + return FALSE; } static GList * dup_list_from_ptrarray (GPtrArray *p) { - GList *ret; - guint n; + GList *ret; + guint n; - ret = NULL; + ret = NULL; - for (n = 0; n < p->len; n++) - ret = g_list_prepend (ret, g_strdup (((gchar **) p->pdata) [n])); + for (n = 0; n < p->len; n++) + ret = g_list_prepend (ret, g_strdup (((gchar **) p->pdata)[n])); - return ret; + return ret; } static gint -ptr_str_array_compare (const gchar **a, const gchar **b) +ptr_str_array_compare (const gchar **a, + const gchar **b) { - return g_strcmp0 (*a, *b); + return g_strcmp0 (*a, *b); } static void -diff_sorted_lists (GList *list1, - GList *list2, - GCompareFunc compare, - GList **added, - GList **removed) +diff_sorted_lists (GList *list1, + GList *list2, + GCompareFunc compare, + GList **added, + GList **removed) { int order; *added = *removed = NULL; - while (list1 != NULL && - list2 != NULL) + while (list1 != NULL && list2 != NULL) { order = (*compare) (list1->data, list2->data); if (order < 0) @@ -1651,26 +1878,25 @@ diff_sorted_lists (GList *list1, static gboolean update_info_presentation (Device *device) { - gboolean hide; - gboolean nopolicy; + gboolean hide; + gboolean nopolicy; - hide = FALSE; - if (g_udev_device_has_property (device->priv->d, "UDISKS_PRESENTATION_HIDE")) - hide = g_udev_device_get_property_as_boolean (device->priv->d, "UDISKS_PRESENTATION_HIDE"); - device_set_device_presentation_hide (device, hide); + hide = FALSE; + if (g_udev_device_has_property (device->priv->d, "UDISKS_PRESENTATION_HIDE")) + hide = g_udev_device_get_property_as_boolean (device->priv->d, "UDISKS_PRESENTATION_HIDE"); + device_set_device_presentation_hide (device, hide); - nopolicy = FALSE; - if (g_udev_device_has_property (device->priv->d, "UDISKS_PRESENTATION_NOPOLICY")) - nopolicy = g_udev_device_get_property_as_boolean (device->priv->d, "UDISKS_PRESENTATION_NOPOLICY"); - device_set_device_presentation_nopolicy (device, nopolicy); + nopolicy = FALSE; + if (g_udev_device_has_property (device->priv->d, "UDISKS_PRESENTATION_NOPOLICY")) + nopolicy = g_udev_device_get_property_as_boolean (device->priv->d, "UDISKS_PRESENTATION_NOPOLICY"); + device_set_device_presentation_nopolicy (device, nopolicy); - device_set_device_presentation_name (device, - g_udev_device_get_property (device->priv->d, "UDISKS_PRESENTATION_NAME")); + device_set_device_presentation_name (device, g_udev_device_get_property (device->priv->d, "UDISKS_PRESENTATION_NAME")); - device_set_device_presentation_icon_name (device, - g_udev_device_get_property (device->priv->d, "UDISKS_PRESENTATION_ICON_NAME")); + device_set_device_presentation_icon_name (device, g_udev_device_get_property (device->priv->d, + "UDISKS_PRESENTATION_ICON_NAME")); - return TRUE; + return TRUE; } /* ---------------------------------------------------------------------------------------------------- */ @@ -1679,36 +1905,40 @@ update_info_presentation (Device *device) static gboolean update_info_id (Device *device) { - gchar *decoded_string; - const gchar *partition_scheme; - gint partition_type; - - partition_scheme = g_udev_device_get_property (device->priv->d, "UDISKS_PARTITION_SCHEME"); - partition_type = g_udev_device_get_property_as_int (device->priv->d, "UDISKS_PARTITION_TYPE"); - if (g_strcmp0 (partition_scheme, "mbr") == 0 && - (partition_type == 0x05 || partition_type == 0x0f || partition_type == 0x85)) { - device_set_id_usage (device, ""); - device_set_id_type (device, ""); - device_set_id_version (device, ""); - device_set_id_label (device, ""); - device_set_id_uuid (device, ""); - goto out; - } - - device_set_id_usage (device, g_udev_device_get_property (device->priv->d, "ID_FS_USAGE")); - device_set_id_type (device, g_udev_device_get_property (device->priv->d, "ID_FS_TYPE")); - device_set_id_version (device, g_udev_device_get_property (device->priv->d, "ID_FS_VERSION")); - if (g_udev_device_has_property (device->priv->d, "ID_FS_LABEL_ENC")) { - decoded_string = decode_udev_encoded_string (g_udev_device_get_property (device->priv->d, "ID_FS_LABEL_ENC")); - device_set_id_label (device, decoded_string); - g_free (decoded_string); - } else { - device_set_id_label (device, g_udev_device_get_property (device->priv->d, "ID_FS_LABEL")); - } - device_set_id_uuid (device, g_udev_device_get_property (device->priv->d, "ID_FS_UUID")); + gchar *decoded_string; + const gchar *partition_scheme; + gint partition_type; + + partition_scheme = g_udev_device_get_property (device->priv->d, "UDISKS_PARTITION_SCHEME"); + partition_type = g_udev_device_get_property_as_int (device->priv->d, "UDISKS_PARTITION_TYPE"); + if (g_strcmp0 (partition_scheme, "mbr") == 0 && (partition_type == 0x05 || partition_type == 0x0f || partition_type + == 0x85)) + { + device_set_id_usage (device, ""); + device_set_id_type (device, ""); + device_set_id_version (device, ""); + device_set_id_label (device, ""); + device_set_id_uuid (device, ""); + goto out; + } + + device_set_id_usage (device, g_udev_device_get_property (device->priv->d, "ID_FS_USAGE")); + device_set_id_type (device, g_udev_device_get_property (device->priv->d, "ID_FS_TYPE")); + device_set_id_version (device, g_udev_device_get_property (device->priv->d, "ID_FS_VERSION")); + if (g_udev_device_has_property (device->priv->d, "ID_FS_LABEL_ENC")) + { + decoded_string = decode_udev_encoded_string (g_udev_device_get_property (device->priv->d, "ID_FS_LABEL_ENC")); + device_set_id_label (device, decoded_string); + g_free (decoded_string); + } + else + { + device_set_id_label (device, g_udev_device_get_property (device->priv->d, "ID_FS_LABEL")); + } + device_set_id_uuid (device, g_udev_device_get_property (device->priv->d, "ID_FS_UUID")); out: - return TRUE; + return TRUE; } /* ---------------------------------------------------------------------------------------------------- */ @@ -1717,29 +1947,34 @@ update_info_id (Device *device) static gboolean update_info_partition_table (Device *device) { - if (!device->priv->device_is_partition && - g_udev_device_has_property (device->priv->d, "UDISKS_PARTITION_TABLE") && - g_udev_device_get_property_as_boolean (device->priv->d, "UDISKS_PARTITION_TABLE")) { - - /* Some times we think that vfat on the main block device looks like a Master Boot Record - * partition table (the on-disk formats are extremely similar). So if we already have - * detected a file system on the main block device and don't have any partitions, then - * avoid tagging the device as a partition table. - * - * See e.g. https://bugzilla.redhat.com/show_bug.cgi?id=495876. - */ - if (device->priv->partition_table_count == 0 && - g_strcmp0 (device->priv->id_usage, "filesystem") == 0) { - device_set_device_is_partition_table (device, FALSE); - } else { - device_set_device_is_partition_table (device, TRUE); - device_set_partition_table_scheme (device, g_udev_device_get_property (device->priv->d, "UDISKS_PARTITION_TABLE_SCHEME")); - } - } else { - device_set_partition_table_scheme (device, NULL); + if (!device->priv->device_is_partition && g_udev_device_has_property (device->priv->d, "UDISKS_PARTITION_TABLE") + && g_udev_device_get_property_as_boolean (device->priv->d, "UDISKS_PARTITION_TABLE")) + { + + /* Some times we think that vfat on the main block device looks like a Master Boot Record + * partition table (the on-disk formats are extremely similar). So if we already have + * detected a file system on the main block device and don't have any partitions, then + * avoid tagging the device as a partition table. + * + * See e.g. https://bugzilla.redhat.com/show_bug.cgi?id=495876. + */ + if (device->priv->partition_table_count == 0 && g_strcmp0 (device->priv->id_usage, "filesystem") == 0) + { + device_set_device_is_partition_table (device, FALSE); + } + else + { + device_set_device_is_partition_table (device, TRUE); + device_set_partition_table_scheme (device, g_udev_device_get_property (device->priv->d, + "UDISKS_PARTITION_TABLE_SCHEME")); } + } + else + { + device_set_partition_table_scheme (device, NULL); + } - return TRUE; + return TRUE; } /* ---------------------------------------------------------------------------------------------------- */ @@ -1748,44 +1983,46 @@ update_info_partition_table (Device *device) static gboolean update_info_partition (Device *device) { - guint64 offset; - - offset = sysfs_get_uint64 (device->priv->native_path, "start") * device->priv->device_block_size; - device_set_partition_offset (device, offset); - - if (device->priv->device_is_partition && - g_udev_device_has_property (device->priv->d, "UDISKS_PARTITION")) { - guint64 size; - const gchar *scheme; - const gchar *type; - const gchar *label; - const gchar *uuid; - const gchar* const *flags; - - scheme = g_udev_device_get_property (device->priv->d, "UDISKS_PARTITION_SCHEME"); - size = g_udev_device_get_property_as_uint64 (device->priv->d, "UDISKS_PARTITION_SIZE"); - type = g_udev_device_get_property (device->priv->d, "UDISKS_PARTITION_TYPE"); - label = g_udev_device_get_property (device->priv->d, "UDISKS_PARTITION_LABEL"); - uuid = g_udev_device_get_property (device->priv->d, "UDISKS_PARTITION_UUID"); - flags = g_udev_device_get_property_as_strv (device->priv->d, "UDISKS_PARTITION_FLAGS"); - - device_set_partition_scheme (device, scheme); - device_set_partition_size (device, size); - device_set_partition_type (device, type); - device_set_partition_label (device, label); - device_set_partition_uuid (device, uuid); - device_set_partition_flags (device, (gchar **) flags); - } else { - /* if we don't have info from part_id, set the partition size to the same as the block device */ - device_set_partition_scheme (device, NULL); - device_set_partition_size (device, device->priv->device_size); - device_set_partition_type (device, NULL); - device_set_partition_label (device, NULL); - device_set_partition_uuid (device, NULL); - device_set_partition_flags (device, NULL); - } - - return TRUE; + guint64 offset; + + offset = sysfs_get_uint64 (device->priv->native_path, "start") * device->priv->device_block_size; + device_set_partition_offset (device, offset); + + if (device->priv->device_is_partition && g_udev_device_has_property (device->priv->d, "UDISKS_PARTITION")) + { + guint64 size; + const gchar *scheme; + const gchar *type; + const gchar *label; + const gchar *uuid; + const gchar* const *flags; + + scheme = g_udev_device_get_property (device->priv->d, "UDISKS_PARTITION_SCHEME"); + size = g_udev_device_get_property_as_uint64 (device->priv->d, "UDISKS_PARTITION_SIZE"); + type = g_udev_device_get_property (device->priv->d, "UDISKS_PARTITION_TYPE"); + label = g_udev_device_get_property (device->priv->d, "UDISKS_PARTITION_LABEL"); + uuid = g_udev_device_get_property (device->priv->d, "UDISKS_PARTITION_UUID"); + flags = g_udev_device_get_property_as_strv (device->priv->d, "UDISKS_PARTITION_FLAGS"); + + device_set_partition_scheme (device, scheme); + device_set_partition_size (device, size); + device_set_partition_type (device, type); + device_set_partition_label (device, label); + device_set_partition_uuid (device, uuid); + device_set_partition_flags (device, (gchar **) flags); + } + else + { + /* if we don't have info from part_id, set the partition size to the same as the block device */ + device_set_partition_scheme (device, NULL); + device_set_partition_size (device, device->priv->device_size); + device_set_partition_type (device, NULL); + device_set_partition_label (device, NULL); + device_set_partition_uuid (device, NULL); + device_set_partition_flags (device, NULL); + } + + return TRUE; } /* ---------------------------------------------------------------------------------------------------- */ @@ -1802,397 +2039,448 @@ update_info_partition (Device *device) static void update_drive_properties_from_sysfs (Device *device) { - char *s; - char *p; - char *q; - char *model; - char *vendor; - char *subsystem; - char *serial; - char *revision; - const char *connection_interface; - guint64 connection_speed; - - connection_interface = NULL; - connection_speed = 0; - - /* walk up the device tree to figure out the subsystem */ - s = g_strdup (device->priv->native_path); - do { - p = sysfs_resolve_link (s, "subsystem"); - if (p != NULL) { - subsystem = g_path_get_basename (p); - g_free (p); - - if (strcmp (subsystem, "scsi") == 0) { - connection_interface = "scsi"; - connection_speed = 0; - - /* continue walking up the chain; we just use scsi as a fallback */ - - /* grab the names from SCSI since the names from udev currently - * - replaces whitespace with _ - * - is missing for e.g. Firewire - */ - vendor = sysfs_get_string (s, "vendor"); - if (vendor != NULL) { - g_strstrip (vendor); - /* Don't overwrite what we set earlier from ID_VENDOR */ - if (device->priv->drive_vendor == NULL) { - q = _dupv8 (vendor); - device_set_drive_vendor (device, q); - g_free (q); - } - g_free (vendor); - } - - model = sysfs_get_string (s, "model"); - if (model != NULL) { - g_strstrip (model); - /* Don't overwrite what we set earlier from ID_MODEL */ - if (device->priv->drive_model == NULL) { - q = _dupv8 (model); - device_set_drive_model (device, q); - g_free (q); - } - g_free (model); - } - - /* TODO: need to improve this code; we probably need the kernel to export more - * information before we can properly get the type and speed. - */ - - if (device->priv->drive_vendor != NULL && - strcmp (device->priv->drive_vendor, "ATA") == 0) { - connection_interface = "ata"; - break; - } - - } else if (strcmp (subsystem, "usb") == 0) { - double usb_speed; - - /* both the interface and the device will be 'usb'. However only - * the device will have the 'speed' property. - */ - usb_speed = sysfs_get_double (s, "speed"); - if (usb_speed > 0) { - connection_interface = "usb"; - connection_speed = usb_speed * (1000 * 1000); - break; - - } - } else if (strcmp (subsystem, "firewire") == 0 || strcmp (subsystem, "ieee1394") == 0) { - - /* TODO: krh has promised a speed file in sysfs; theoretically, the speed can - * be anything from 100, 200, 400, 800 and 3200. Till then we just hardcode - * a resonable default of 400 Mbit/s. - */ - - connection_interface = "firewire"; - connection_speed = 400 * (1000 * 1000); - break; - - } else if (strcmp (subsystem, "mmc") == 0) { - - /* TODO: what about non-SD, e.g. MMC? Is that another bus? */ - connection_interface = "sdio"; - - /* Set vendor name. According to this MMC document - * - * http://www.mmca.org/membership/IAA_Agreement_10_12_06.pdf - * - * - manfid: the manufacturer id - * - oemid: the customer of the manufacturer - * - * Apparently these numbers are kept secret. It would be nice - * to map these into names for setting the manufacturer of the drive, - * e.g. Panasonic, Sandisk etc. - */ - - model = sysfs_get_string (s, "name"); - if (model != NULL) { - g_strstrip (model); - /* Don't overwrite what we set earlier from ID_MODEL */ - if (device->priv->drive_model == NULL) { - q = _dupv8 (model); - device_set_drive_model (device, q); - g_free (q); - } - g_free (model); - } - - serial = sysfs_get_string (s, "serial"); - if (serial != NULL) { - g_strstrip (serial); - /* Don't overwrite what we set earlier from ID_SERIAL */ - if (device->priv->drive_serial == NULL) { - /* this is formatted as a hexnumber; drop the leading 0x */ - q = _dupv8 (serial + 2); - device_set_drive_serial (device, q); - g_free (q); - } - g_free (serial); - } - - /* TODO: use hwrev and fwrev files? */ - revision = sysfs_get_string (s, "date"); - if (revision != NULL) { - g_strstrip (revision); - /* Don't overwrite what we set earlier from ID_REVISION */ - if (device->priv->drive_revision == NULL) { - q = _dupv8 (revision); - device_set_drive_revision (device, q); - g_free (q); - } - g_free (revision); - } - - /* TODO: interface speed; the kernel driver knows; would be nice - * if it could export it */ - - } else if (strcmp (subsystem, "platform") == 0) { - const gchar *sysfs_name; - - sysfs_name = g_strrstr (s, "/"); - if (g_str_has_prefix (sysfs_name + 1, "floppy.")) { - device_set_drive_vendor (device, "Floppy Drive"); - connection_interface = "platform"; - } - } - - g_free (subsystem); + char *s; + char *p; + char *q; + char *model; + char *vendor; + char *subsystem; + char *serial; + char *revision; + const char *connection_interface; + guint64 connection_speed; + + connection_interface = NULL; + connection_speed = 0; + + /* walk up the device tree to figure out the subsystem */ + s = g_strdup (device->priv->native_path); + do + { + p = sysfs_resolve_link (s, "subsystem"); + if (p != NULL) + { + subsystem = g_path_get_basename (p); + g_free (p); + + if (strcmp (subsystem, "scsi") == 0) + { + connection_interface = "scsi"; + connection_speed = 0; + + /* continue walking up the chain; we just use scsi as a fallback */ + + /* grab the names from SCSI since the names from udev currently + * - replaces whitespace with _ + * - is missing for e.g. Firewire + */ + vendor = sysfs_get_string (s, "vendor"); + if (vendor != NULL) + { + g_strstrip (vendor); + /* Don't overwrite what we set earlier from ID_VENDOR */ + if (device->priv->drive_vendor == NULL) + { + q = _dupv8 (vendor); + device_set_drive_vendor (device, q); + g_free (q); + } + g_free (vendor); + } + + model = sysfs_get_string (s, "model"); + if (model != NULL) + { + g_strstrip (model); + /* Don't overwrite what we set earlier from ID_MODEL */ + if (device->priv->drive_model == NULL) + { + q = _dupv8 (model); + device_set_drive_model (device, q); + g_free (q); + } + g_free (model); + } + + /* TODO: need to improve this code; we probably need the kernel to export more + * information before we can properly get the type and speed. + */ + + if (device->priv->drive_vendor != NULL && strcmp (device->priv->drive_vendor, "ATA") == 0) + { + connection_interface = "ata"; + break; } - /* advance up the chain */ - p = g_strrstr (s, "/"); - if (p == NULL) - break; - *p = '\0'; - - /* but stop at the root */ - if (strcmp (s, "/sys/devices") == 0) - break; + } + else if (strcmp (subsystem, "usb") == 0) + { + double usb_speed; - } while (TRUE); + /* both the interface and the device will be 'usb'. However only + * the device will have the 'speed' property. + */ + usb_speed = sysfs_get_double (s, "speed"); + if (usb_speed > 0) + { + connection_interface = "usb"; + connection_speed = usb_speed * (1000 * 1000); + break; + + } + } + else if (strcmp (subsystem, "firewire") == 0 || strcmp (subsystem, "ieee1394") == 0) + { + + /* TODO: krh has promised a speed file in sysfs; theoretically, the speed can + * be anything from 100, 200, 400, 800 and 3200. Till then we just hardcode + * a resonable default of 400 Mbit/s. + */ + + connection_interface = "firewire"; + connection_speed = 400 * (1000 * 1000); + break; + + } + else if (strcmp (subsystem, "mmc") == 0) + { + + /* TODO: what about non-SD, e.g. MMC? Is that another bus? */ + connection_interface = "sdio"; + + /* Set vendor name. According to this MMC document + * + * http://www.mmca.org/membership/IAA_Agreement_10_12_06.pdf + * + * - manfid: the manufacturer id + * - oemid: the customer of the manufacturer + * + * Apparently these numbers are kept secret. It would be nice + * to map these into names for setting the manufacturer of the drive, + * e.g. Panasonic, Sandisk etc. + */ + + model = sysfs_get_string (s, "name"); + if (model != NULL) + { + g_strstrip (model); + /* Don't overwrite what we set earlier from ID_MODEL */ + if (device->priv->drive_model == NULL) + { + q = _dupv8 (model); + device_set_drive_model (device, q); + g_free (q); + } + g_free (model); + } + + serial = sysfs_get_string (s, "serial"); + if (serial != NULL) + { + g_strstrip (serial); + /* Don't overwrite what we set earlier from ID_SERIAL */ + if (device->priv->drive_serial == NULL) + { + /* this is formatted as a hexnumber; drop the leading 0x */ + q = _dupv8 (serial + 2); + device_set_drive_serial (device, q); + g_free (q); + } + g_free (serial); + } + + /* TODO: use hwrev and fwrev files? */ + revision = sysfs_get_string (s, "date"); + if (revision != NULL) + { + g_strstrip (revision); + /* Don't overwrite what we set earlier from ID_REVISION */ + if (device->priv->drive_revision == NULL) + { + q = _dupv8 (revision); + device_set_drive_revision (device, q); + g_free (q); + } + g_free (revision); + } + + /* TODO: interface speed; the kernel driver knows; would be nice + * if it could export it */ + + } + else if (strcmp (subsystem, "platform") == 0) + { + const gchar *sysfs_name; + + sysfs_name = g_strrstr (s, "/"); + if (g_str_has_prefix (sysfs_name + 1, "floppy.")) + { + device_set_drive_vendor (device, "Floppy Drive"); + connection_interface = "platform"; + } + } - if (connection_interface != NULL) { - device_set_drive_connection_interface (device, connection_interface); - device_set_drive_connection_speed (device, connection_speed); + g_free (subsystem); } - g_free (s); + /* advance up the chain */ + p = g_strrstr (s, "/"); + if (p == NULL) + break; + *p = '\0'; + + /* but stop at the root */ + if (strcmp (s, "/sys/devices") == 0) + break; + + } + while (TRUE); + + if (connection_interface != NULL) + { + device_set_drive_connection_interface (device, connection_interface); + device_set_drive_connection_speed (device, connection_speed); + } + + g_free (s); } static const struct { - const gchar *udev_property; - const gchar *media_name; -} drive_media_mapping[] = { - {"ID_DRIVE_FLASH", "flash"}, - {"ID_DRIVE_FLASH_CF", "flash_cf"}, - {"ID_DRIVE_FLASH_MS", "flash_ms"}, - {"ID_DRIVE_FLASH_SM", "flash_sm"}, - {"ID_DRIVE_FLASH_SD", "flash_sd"}, - {"ID_DRIVE_FLASH_SDHC", "flash_sdhc"}, - {"ID_DRIVE_FLASH_MMC", "flash_mmc"}, - {"ID_DRIVE_FLOPPY", "floppy"}, - {"ID_DRIVE_FLOPPY_ZIP", "floppy_zip"}, - {"ID_DRIVE_FLOPPY_JAZ", "floppy_jaz"}, - {"ID_CDROM", "optical_cd"}, - {"ID_CDROM_CD_R", "optical_cd_r"}, - {"ID_CDROM_CD_RW", "optical_cd_rw"}, - {"ID_CDROM_DVD", "optical_dvd"}, - {"ID_CDROM_DVD_R", "optical_dvd_r"}, - {"ID_CDROM_DVD_RW", "optical_dvd_rw"}, - {"ID_CDROM_DVD_RAM", "optical_dvd_ram"}, - {"ID_CDROM_DVD_PLUS_R", "optical_dvd_plus_r"}, - {"ID_CDROM_DVD_PLUS_RW", "optical_dvd_plus_rw"}, - {"ID_CDROM_DVD_PLUS_R_DL", "optical_dvd_plus_r_dl"}, - {"ID_CDROM_DVD_PLUS_RW_DL", "optical_dvd_plus_rw_dl"}, - {"ID_CDROM_BD", "optical_bd"}, - {"ID_CDROM_BD_R", "optical_bd_r"}, - {"ID_CDROM_BD_RE", "optical_bd_re"}, - {"ID_CDROM_HDDVD", "optical_hddvd"}, - {"ID_CDROM_HDDVD_R", "optical_hddvd_r"}, - {"ID_CDROM_HDDVD_RW", "optical_hddvd_rw"}, - {"ID_CDROM_MO", "optical_mo"}, - {"ID_CDROM_MRW", "optical_mrw"}, - {"ID_CDROM_MRW_W", "optical_mrw_w"}, - {NULL, NULL}, -}; + const gchar *udev_property; + const gchar *media_name; +} drive_media_mapping[] = + { + { "ID_DRIVE_FLASH", "flash" }, + { "ID_DRIVE_FLASH_CF", "flash_cf" }, + { "ID_DRIVE_FLASH_MS", "flash_ms" }, + { "ID_DRIVE_FLASH_SM", "flash_sm" }, + { "ID_DRIVE_FLASH_SD", "flash_sd" }, + { "ID_DRIVE_FLASH_SDHC", "flash_sdhc" }, + { "ID_DRIVE_FLASH_MMC", "flash_mmc" }, + { "ID_DRIVE_FLOPPY", "floppy" }, + { "ID_DRIVE_FLOPPY_ZIP", "floppy_zip" }, + { "ID_DRIVE_FLOPPY_JAZ", "floppy_jaz" }, + { "ID_CDROM", "optical_cd" }, + { "ID_CDROM_CD_R", "optical_cd_r" }, + { "ID_CDROM_CD_RW", "optical_cd_rw" }, + { "ID_CDROM_DVD", "optical_dvd" }, + { "ID_CDROM_DVD_R", "optical_dvd_r" }, + { "ID_CDROM_DVD_RW", "optical_dvd_rw" }, + { "ID_CDROM_DVD_RAM", "optical_dvd_ram" }, + { "ID_CDROM_DVD_PLUS_R", "optical_dvd_plus_r" }, + { "ID_CDROM_DVD_PLUS_RW", "optical_dvd_plus_rw" }, + { "ID_CDROM_DVD_PLUS_R_DL", "optical_dvd_plus_r_dl" }, + { "ID_CDROM_DVD_PLUS_RW_DL", "optical_dvd_plus_rw_dl" }, + { "ID_CDROM_BD", "optical_bd" }, + { "ID_CDROM_BD_R", "optical_bd_r" }, + { "ID_CDROM_BD_RE", "optical_bd_re" }, + { "ID_CDROM_HDDVD", "optical_hddvd" }, + { "ID_CDROM_HDDVD_R", "optical_hddvd_r" }, + { "ID_CDROM_HDDVD_RW", "optical_hddvd_rw" }, + { "ID_CDROM_MO", "optical_mo" }, + { "ID_CDROM_MRW", "optical_mrw" }, + { "ID_CDROM_MRW_W", "optical_mrw_w" }, + { NULL, NULL }, }; static const struct { - const gchar *udev_property; - const gchar *media_name; -} media_mapping[] = { - {"ID_DRIVE_MEDIA_FLASH", "flash"}, - {"ID_DRIVE_MEDIA_FLASH_CF", "flash_cf"}, - {"ID_DRIVE_MEDIA_FLASH_MS", "flash_ms"}, - {"ID_DRIVE_MEDIA_FLASH_SM", "flash_sm"}, - {"ID_DRIVE_MEDIA_FLASH_SD", "flash_sd"}, - {"ID_DRIVE_MEDIA_FLASH_SDHC", "flash_sdhc"}, - {"ID_DRIVE_MEDIA_FLASH_MMC", "flash_mmc"}, - {"ID_DRIVE_MEDIA_FLOPPY", "floppy"}, - {"ID_DRIVE_MEDIA_FLOPPY_ZIP", "floppy_zip"}, - {"ID_DRIVE_MEDIA_FLOPPY_JAZ", "floppy_jaz"}, - {"ID_CDROM_MEDIA_CD", "optical_cd"}, - {"ID_CDROM_MEDIA_CD_R", "optical_cd_r"}, - {"ID_CDROM_MEDIA_CD_RW", "optical_cd_rw"}, - {"ID_CDROM_MEDIA_DVD", "optical_dvd"}, - {"ID_CDROM_MEDIA_DVD_R", "optical_dvd_r"}, - {"ID_CDROM_MEDIA_DVD_RW", "optical_dvd_rw"}, - {"ID_CDROM_MEDIA_DVD_RAM", "optical_dvd_ram"}, - {"ID_CDROM_MEDIA_DVD_PLUS_R", "optical_dvd_plus_r"}, - {"ID_CDROM_MEDIA_DVD_PLUS_RW", "optical_dvd_plus_rw"}, - {"ID_CDROM_MEDIA_DVD_PLUS_R_DL", "optical_dvd_plus_r_dl"}, - {"ID_CDROM_MEDIA_DVD_PLUS_RW_DL", "optical_dvd_plus_rw_dl"}, - {"ID_CDROM_MEDIA_BD", "optical_bd"}, - {"ID_CDROM_MEDIA_BD_R", "optical_bd_r"}, - {"ID_CDROM_MEDIA_BD_RE", "optical_bd_re"}, - {"ID_CDROM_MEDIA_HDDVD", "optical_hddvd"}, - {"ID_CDROM_MEDIA_HDDVD_R", "optical_hddvd_r"}, - {"ID_CDROM_MEDIA_HDDVD_RW", "optical_hddvd_rw"}, - {"ID_CDROM_MEDIA_MO", "optical_mo"}, - {"ID_CDROM_MEDIA_MRW", "optical_mrw"}, - {"ID_CDROM_MEDIA_MRW_W", "optical_mrw_w"}, - {NULL, NULL}, -}; + const gchar *udev_property; + const gchar *media_name; +} media_mapping[] = + { + { "ID_DRIVE_MEDIA_FLASH", "flash" }, + { "ID_DRIVE_MEDIA_FLASH_CF", "flash_cf" }, + { "ID_DRIVE_MEDIA_FLASH_MS", "flash_ms" }, + { "ID_DRIVE_MEDIA_FLASH_SM", "flash_sm" }, + { "ID_DRIVE_MEDIA_FLASH_SD", "flash_sd" }, + { "ID_DRIVE_MEDIA_FLASH_SDHC", "flash_sdhc" }, + { "ID_DRIVE_MEDIA_FLASH_MMC", "flash_mmc" }, + { "ID_DRIVE_MEDIA_FLOPPY", "floppy" }, + { "ID_DRIVE_MEDIA_FLOPPY_ZIP", "floppy_zip" }, + { "ID_DRIVE_MEDIA_FLOPPY_JAZ", "floppy_jaz" }, + { "ID_CDROM_MEDIA_CD", "optical_cd" }, + { "ID_CDROM_MEDIA_CD_R", "optical_cd_r" }, + { "ID_CDROM_MEDIA_CD_RW", "optical_cd_rw" }, + { "ID_CDROM_MEDIA_DVD", "optical_dvd" }, + { "ID_CDROM_MEDIA_DVD_R", "optical_dvd_r" }, + { "ID_CDROM_MEDIA_DVD_RW", "optical_dvd_rw" }, + { "ID_CDROM_MEDIA_DVD_RAM", "optical_dvd_ram" }, + { "ID_CDROM_MEDIA_DVD_PLUS_R", "optical_dvd_plus_r" }, + { "ID_CDROM_MEDIA_DVD_PLUS_RW", "optical_dvd_plus_rw" }, + { "ID_CDROM_MEDIA_DVD_PLUS_R_DL", "optical_dvd_plus_r_dl" }, + { "ID_CDROM_MEDIA_DVD_PLUS_RW_DL", "optical_dvd_plus_rw_dl" }, + { "ID_CDROM_MEDIA_BD", "optical_bd" }, + { "ID_CDROM_MEDIA_BD_R", "optical_bd_r" }, + { "ID_CDROM_MEDIA_BD_RE", "optical_bd_re" }, + { "ID_CDROM_MEDIA_HDDVD", "optical_hddvd" }, + { "ID_CDROM_MEDIA_HDDVD_R", "optical_hddvd_r" }, + { "ID_CDROM_MEDIA_HDDVD_RW", "optical_hddvd_rw" }, + { "ID_CDROM_MEDIA_MO", "optical_mo" }, + { "ID_CDROM_MEDIA_MRW", "optical_mrw" }, + { "ID_CDROM_MEDIA_MRW_W", "optical_mrw_w" }, + { NULL, NULL }, }; /* update drive_* properties */ static gboolean update_info_drive (Device *device) { - GPtrArray *media_compat_array; - const gchar *media_in_drive; - gboolean drive_is_ejectable; - gboolean drive_can_detach; - gchar *decoded_string; - guint n; - - if (g_udev_device_has_property (device->priv->d, "ID_VENDOR_ENC")) { - decoded_string = decode_udev_encoded_string (g_udev_device_get_property (device->priv->d, "ID_VENDOR_ENC")); - g_strstrip (decoded_string); - device_set_drive_vendor (device, decoded_string); - g_free (decoded_string); - } else if (g_udev_device_has_property (device->priv->d, "ID_VENDOR")) { - device_set_drive_vendor (device, g_udev_device_get_property (device->priv->d, "ID_VENDOR")); - } - - if (g_udev_device_has_property (device->priv->d, "ID_MODEL_ENC")) { - decoded_string = decode_udev_encoded_string (g_udev_device_get_property (device->priv->d, "ID_MODEL_ENC")); - g_strstrip (decoded_string); - device_set_drive_model (device, decoded_string); - g_free (decoded_string); - } else if (g_udev_device_has_property (device->priv->d, "ID_MODEL")) { - device_set_drive_model (device, g_udev_device_get_property (device->priv->d, "ID_MODEL")); - } - - if (g_udev_device_has_property (device->priv->d, "ID_REVISION")) - device_set_drive_revision (device, g_udev_device_get_property (device->priv->d, "ID_REVISION")); - if (g_udev_device_has_property (device->priv->d, "ID_SCSI_SERIAL")) { - /* scsi_id sometimes use the WWN as the serial - annoying - see - * http://git.kernel.org/?p=linux/hotplug/udev.git;a=commit;h=4e9fdfccbdd16f0cfdb5c8fa8484a8ba0f2e69d3 - * for details - */ - device_set_drive_serial (device, g_udev_device_get_property (device->priv->d, "ID_SCSI_SERIAL")); - } else if (g_udev_device_has_property (device->priv->d, "ID_SERIAL_SHORT")) { - device_set_drive_serial (device, g_udev_device_get_property (device->priv->d, "ID_SERIAL_SHORT")); - } - - if (g_udev_device_has_property (device->priv->d, "ID_WWN")) - device_set_drive_wwn (device, g_udev_device_get_property (device->priv->d, "ID_WWN") + 2); - - /* pick up some things (vendor, model, connection_interface, connection_speed) - * not (yet) exported by udev helpers - */ - update_drive_properties_from_sysfs (device); - - if (g_udev_device_has_property (device->priv->d, "ID_DRIVE_EJECTABLE")) { - drive_is_ejectable = g_udev_device_get_property_as_boolean (device->priv->d, "ID_DRIVE_EJECTABLE"); - } else { - drive_is_ejectable = FALSE; - drive_is_ejectable |= g_udev_device_has_property (device->priv->d, "ID_CDROM"); - drive_is_ejectable |= g_udev_device_has_property (device->priv->d, "ID_DRIVE_FLOPPY_ZIP"); - drive_is_ejectable |= g_udev_device_has_property (device->priv->d, "ID_DRIVE_FLOPPY_JAZ"); - } - device_set_drive_is_media_ejectable (device, drive_is_ejectable); - - media_compat_array = g_ptr_array_new (); - for (n = 0; drive_media_mapping[n].udev_property != NULL; n++) { - if (!g_udev_device_has_property (device->priv->d, drive_media_mapping[n].udev_property)) - continue; - - g_ptr_array_add (media_compat_array, (gpointer) drive_media_mapping[n].media_name); - } - /* special handling for SDIO since we don't yet have a sdio_id helper in udev to set properties */ - if (g_strcmp0 (device->priv->drive_connection_interface, "sdio") == 0) { - gchar *type; - - type = sysfs_get_string (device->priv->native_path, "../../type"); - g_strstrip (type); - if (g_strcmp0 (type, "MMC") == 0) { - g_ptr_array_add (media_compat_array, "flash_mmc"); - } else if (g_strcmp0 (type, "SD") == 0) { - g_ptr_array_add (media_compat_array, "flash_sd"); - } else if (g_strcmp0 (type, "SDHC") == 0) { - g_ptr_array_add (media_compat_array, "flash_sdhc"); - } - g_free (type); - } - g_ptr_array_sort (media_compat_array, (GCompareFunc) ptr_str_array_compare); - g_ptr_array_add (media_compat_array, NULL); - device_set_drive_media_compatibility (device, (GStrv) media_compat_array->pdata); + GPtrArray *media_compat_array; + const gchar *media_in_drive; + gboolean drive_is_ejectable; + gboolean drive_can_detach; + gchar *decoded_string; + guint n; + + if (g_udev_device_has_property (device->priv->d, "ID_VENDOR_ENC")) + { + decoded_string = decode_udev_encoded_string (g_udev_device_get_property (device->priv->d, "ID_VENDOR_ENC")); + g_strstrip (decoded_string); + device_set_drive_vendor (device, decoded_string); + g_free (decoded_string); + } + else if (g_udev_device_has_property (device->priv->d, "ID_VENDOR")) + { + device_set_drive_vendor (device, g_udev_device_get_property (device->priv->d, "ID_VENDOR")); + } + + if (g_udev_device_has_property (device->priv->d, "ID_MODEL_ENC")) + { + decoded_string = decode_udev_encoded_string (g_udev_device_get_property (device->priv->d, "ID_MODEL_ENC")); + g_strstrip (decoded_string); + device_set_drive_model (device, decoded_string); + g_free (decoded_string); + } + else if (g_udev_device_has_property (device->priv->d, "ID_MODEL")) + { + device_set_drive_model (device, g_udev_device_get_property (device->priv->d, "ID_MODEL")); + } + + if (g_udev_device_has_property (device->priv->d, "ID_REVISION")) + device_set_drive_revision (device, g_udev_device_get_property (device->priv->d, "ID_REVISION")); + if (g_udev_device_has_property (device->priv->d, "ID_SCSI_SERIAL")) + { + /* scsi_id sometimes use the WWN as the serial - annoying - see + * http://git.kernel.org/?p=linux/hotplug/udev.git;a=commit;h=4e9fdfccbdd16f0cfdb5c8fa8484a8ba0f2e69d3 + * for details + */ + device_set_drive_serial (device, g_udev_device_get_property (device->priv->d, "ID_SCSI_SERIAL")); + } + else if (g_udev_device_has_property (device->priv->d, "ID_SERIAL_SHORT")) + { + device_set_drive_serial (device, g_udev_device_get_property (device->priv->d, "ID_SERIAL_SHORT")); + } - media_in_drive = NULL; + if (g_udev_device_has_property (device->priv->d, "ID_WWN")) + device_set_drive_wwn (device, g_udev_device_get_property (device->priv->d, "ID_WWN") + 2); - if (device->priv->device_is_media_available) { - for (n = 0; media_mapping[n].udev_property != NULL; n++) { - if (!g_udev_device_has_property (device->priv->d, media_mapping[n].udev_property)) - continue; + /* pick up some things (vendor, model, connection_interface, connection_speed) + * not (yet) exported by udev helpers + */ + update_drive_properties_from_sysfs (device); - media_in_drive = drive_media_mapping[n].media_name; - break; - } - /* If the media isn't set (from e.g. udev rules), just pick the first one in media_compat - note - * that this may be NULL (if we don't know what media is compatible with the drive) which is OK. - */ - if (media_in_drive == NULL) - media_in_drive = ((const gchar **) media_compat_array->pdata)[0]; - } - device_set_drive_media (device, media_in_drive); + if (g_udev_device_has_property (device->priv->d, "ID_DRIVE_EJECTABLE")) + { + drive_is_ejectable = g_udev_device_get_property_as_boolean (device->priv->d, "ID_DRIVE_EJECTABLE"); + } + else + { + drive_is_ejectable = FALSE; + drive_is_ejectable |= g_udev_device_has_property (device->priv->d, "ID_CDROM"); + drive_is_ejectable |= g_udev_device_has_property (device->priv->d, "ID_DRIVE_FLOPPY_ZIP"); + drive_is_ejectable |= g_udev_device_has_property (device->priv->d, "ID_DRIVE_FLOPPY_JAZ"); + } + device_set_drive_is_media_ejectable (device, drive_is_ejectable); - g_ptr_array_free (media_compat_array, TRUE); + media_compat_array = g_ptr_array_new (); + for (n = 0; drive_media_mapping[n].udev_property != NULL; n++) + { + if (!g_udev_device_has_property (device->priv->d, drive_media_mapping[n].udev_property)) + continue; + + g_ptr_array_add (media_compat_array, (gpointer) drive_media_mapping[n].media_name); + } + /* special handling for SDIO since we don't yet have a sdio_id helper in udev to set properties */ + if (g_strcmp0 (device->priv->drive_connection_interface, "sdio") == 0) + { + gchar *type; - /* right now, we only offer to detach USB devices */ - drive_can_detach = FALSE; - if (g_strcmp0 (device->priv->drive_connection_interface, "usb") == 0) { - drive_can_detach = TRUE; + type = sysfs_get_string (device->priv->native_path, "../../type"); + g_strstrip (type); + if (g_strcmp0 (type, "MMC") == 0) + { + g_ptr_array_add (media_compat_array, "flash_mmc"); + } + else if (g_strcmp0 (type, "SD") == 0) + { + g_ptr_array_add (media_compat_array, "flash_sd"); } - if (g_udev_device_has_property (device->priv->d, "ID_DRIVE_DETACHABLE")) { - drive_can_detach = g_udev_device_get_property_as_boolean (device->priv->d, "ID_DRIVE_DETACHABLE"); + else if (g_strcmp0 (type, "SDHC") == 0) + { + g_ptr_array_add (media_compat_array, "flash_sdhc"); } - device_set_drive_can_detach (device, drive_can_detach); + g_free (type); + } + g_ptr_array_sort (media_compat_array, (GCompareFunc) ptr_str_array_compare); + g_ptr_array_add (media_compat_array, NULL); + device_set_drive_media_compatibility (device, (GStrv) media_compat_array->pdata); + + media_in_drive = NULL; - /* rotational is in sysfs */ - device_set_drive_is_rotational (device, - g_udev_device_get_sysfs_attr_as_boolean (device->priv->d, - "queue/rotational")); + if (device->priv->device_is_media_available) + { + for (n = 0; media_mapping[n].udev_property != NULL; n++) + { + if (!g_udev_device_has_property (device->priv->d, media_mapping[n].udev_property)) + continue; - if (g_udev_device_has_property (device->priv->d, "ID_ATA_ROTATION_RATE_RPM")) { - device_set_drive_rotation_rate (device, - g_udev_device_get_property_as_int (device->priv->d, "ID_ATA_ROTATION_RATE_RPM")); + media_in_drive = drive_media_mapping[n].media_name; + break; } + /* If the media isn't set (from e.g. udev rules), just pick the first one in media_compat - note + * that this may be NULL (if we don't know what media is compatible with the drive) which is OK. + */ + if (media_in_drive == NULL) + media_in_drive = ((const gchar **) media_compat_array->pdata)[0]; + } + device_set_drive_media (device, media_in_drive); - if (g_udev_device_get_property_as_boolean (device->priv->d, "ID_ATA_WRITE_CACHE")) { - if (g_udev_device_get_property_as_boolean (device->priv->d, "ID_ATA_WRITE_CACHE_ENABLED")) { - device_set_drive_write_cache (device, "enabled"); - } else { - device_set_drive_write_cache (device, "disabled"); - } + g_ptr_array_free (media_compat_array, TRUE); + + /* right now, we only offer to detach USB devices */ + drive_can_detach = FALSE; + if (g_strcmp0 (device->priv->drive_connection_interface, "usb") == 0) + { + drive_can_detach = TRUE; + } + if (g_udev_device_has_property (device->priv->d, "ID_DRIVE_DETACHABLE")) + { + drive_can_detach = g_udev_device_get_property_as_boolean (device->priv->d, "ID_DRIVE_DETACHABLE"); + } + device_set_drive_can_detach (device, drive_can_detach); + + /* rotational is in sysfs */ + device_set_drive_is_rotational (device, g_udev_device_get_sysfs_attr_as_boolean (device->priv->d, "queue/rotational")); + + if (g_udev_device_has_property (device->priv->d, "ID_ATA_ROTATION_RATE_RPM")) + { + device_set_drive_rotation_rate (device, g_udev_device_get_property_as_int (device->priv->d, + "ID_ATA_ROTATION_RATE_RPM")); + } + + if (g_udev_device_get_property_as_boolean (device->priv->d, "ID_ATA_WRITE_CACHE")) + { + if (g_udev_device_get_property_as_boolean (device->priv->d, "ID_ATA_WRITE_CACHE_ENABLED")) + { + device_set_drive_write_cache (device, "enabled"); + } + else + { + device_set_drive_write_cache (device, "disabled"); } + } - return TRUE; + return TRUE; } /* ---------------------------------------------------------------------------------------------------- */ @@ -2201,26 +2489,27 @@ update_info_drive (Device *device) static gboolean update_info_drive_can_spindown (Device *device) { - gboolean drive_can_spindown; - - /* Right now we only know how to spin down ATA devices (including those USB devices - * that can do ATA SMART) - * - * This would probably also work for SCSI devices (since the helper is doing SCSI - * STOP (which translated in libata to ATA's STANDBY IMMEDIATE) - but that needs - * testing... - */ - drive_can_spindown = FALSE; - if (g_strcmp0 (device->priv->drive_connection_interface, "ata") == 0 || - device->priv->drive_ata_smart_is_available) { - drive_can_spindown = TRUE; - } - if (g_udev_device_has_property (device->priv->d, "ID_DRIVE_CAN_SPINDOWN")) { - drive_can_spindown = g_udev_device_get_property_as_boolean (device->priv->d, "ID_DRIVE_CAN_SPINDOWN"); - } - device_set_drive_can_spindown (device, drive_can_spindown); + gboolean drive_can_spindown; + + /* Right now we only know how to spin down ATA devices (including those USB devices + * that can do ATA SMART) + * + * This would probably also work for SCSI devices (since the helper is doing SCSI + * STOP (which translated in libata to ATA's STANDBY IMMEDIATE) - but that needs + * testing... + */ + drive_can_spindown = FALSE; + if (g_strcmp0 (device->priv->drive_connection_interface, "ata") == 0 || device->priv->drive_ata_smart_is_available) + { + drive_can_spindown = TRUE; + } + if (g_udev_device_has_property (device->priv->d, "ID_DRIVE_CAN_SPINDOWN")) + { + drive_can_spindown = g_udev_device_get_property_as_boolean (device->priv->d, "ID_DRIVE_CAN_SPINDOWN"); + } + device_set_drive_can_spindown (device, drive_can_spindown); - return TRUE; + return TRUE; } /* ---------------------------------------------------------------------------------------------------- */ @@ -2229,44 +2518,48 @@ update_info_drive_can_spindown (Device *device) static gboolean update_info_optical_disc (Device *device) { - const gchar *cdrom_disc_state; - gint cdrom_track_count; - gint cdrom_track_count_audio; - gint cdrom_session_count; - - /* device_is_optical_disc and optical_disc_* */ - if (g_udev_device_has_property (device->priv->d, "ID_CDROM_MEDIA")) { - device_set_device_is_optical_disc (device, TRUE); - - cdrom_track_count = 0; - cdrom_track_count_audio = 0; - cdrom_session_count = 0; - - if (g_udev_device_has_property (device->priv->d, "ID_CDROM_MEDIA_TRACK_COUNT")) - cdrom_track_count = g_udev_device_get_property_as_int (device->priv->d, "ID_CDROM_MEDIA_TRACK_COUNT"); - if (g_udev_device_has_property (device->priv->d, "ID_CDROM_MEDIA_TRACK_COUNT_AUDIO")) - cdrom_track_count_audio = g_udev_device_get_property_as_int (device->priv->d, "ID_CDROM_MEDIA_TRACK_COUNT_AUDIO"); - if (g_udev_device_has_property (device->priv->d, "ID_CDROM_MEDIA_SESSION_COUNT")) - cdrom_session_count = g_udev_device_get_property_as_int (device->priv->d, "ID_CDROM_MEDIA_SESSION_COUNT"); - device_set_optical_disc_num_tracks (device, cdrom_track_count); - device_set_optical_disc_num_audio_tracks (device, cdrom_track_count_audio); - device_set_optical_disc_num_sessions (device, cdrom_session_count); - cdrom_disc_state = g_udev_device_get_property (device->priv->d, "ID_CDROM_MEDIA_STATE"); - device_set_optical_disc_is_blank (device, g_strcmp0 (cdrom_disc_state, "blank") == 0); - device_set_optical_disc_is_appendable (device, g_strcmp0 (cdrom_disc_state, "appendable") == 0); - device_set_optical_disc_is_closed (device, g_strcmp0 (cdrom_disc_state, "complete") == 0); - } else { - device_set_device_is_optical_disc (device, FALSE); - - device_set_optical_disc_num_tracks (device, 0); - device_set_optical_disc_num_audio_tracks (device, 0); - device_set_optical_disc_num_sessions (device, 0); - device_set_optical_disc_is_blank (device, FALSE); - device_set_optical_disc_is_appendable (device, FALSE); - device_set_optical_disc_is_closed (device, FALSE); - } - - return TRUE; + const gchar *cdrom_disc_state; + gint cdrom_track_count; + gint cdrom_track_count_audio; + gint cdrom_session_count; + + /* device_is_optical_disc and optical_disc_* */ + if (g_udev_device_has_property (device->priv->d, "ID_CDROM_MEDIA")) + { + device_set_device_is_optical_disc (device, TRUE); + + cdrom_track_count = 0; + cdrom_track_count_audio = 0; + cdrom_session_count = 0; + + if (g_udev_device_has_property (device->priv->d, "ID_CDROM_MEDIA_TRACK_COUNT")) + cdrom_track_count = g_udev_device_get_property_as_int (device->priv->d, "ID_CDROM_MEDIA_TRACK_COUNT"); + if (g_udev_device_has_property (device->priv->d, "ID_CDROM_MEDIA_TRACK_COUNT_AUDIO")) + cdrom_track_count_audio = g_udev_device_get_property_as_int (device->priv->d, + "ID_CDROM_MEDIA_TRACK_COUNT_AUDIO"); + if (g_udev_device_has_property (device->priv->d, "ID_CDROM_MEDIA_SESSION_COUNT")) + cdrom_session_count = g_udev_device_get_property_as_int (device->priv->d, "ID_CDROM_MEDIA_SESSION_COUNT"); + device_set_optical_disc_num_tracks (device, cdrom_track_count); + device_set_optical_disc_num_audio_tracks (device, cdrom_track_count_audio); + device_set_optical_disc_num_sessions (device, cdrom_session_count); + cdrom_disc_state = g_udev_device_get_property (device->priv->d, "ID_CDROM_MEDIA_STATE"); + device_set_optical_disc_is_blank (device, g_strcmp0 (cdrom_disc_state, "blank") == 0); + device_set_optical_disc_is_appendable (device, g_strcmp0 (cdrom_disc_state, "appendable") == 0); + device_set_optical_disc_is_closed (device, g_strcmp0 (cdrom_disc_state, "complete") == 0); + } + else + { + device_set_device_is_optical_disc (device, FALSE); + + device_set_optical_disc_num_tracks (device, 0); + device_set_optical_disc_num_audio_tracks (device, 0); + device_set_optical_disc_num_sessions (device, 0); + device_set_optical_disc_is_blank (device, FALSE); + device_set_optical_disc_is_appendable (device, FALSE); + device_set_optical_disc_is_closed (device, FALSE); + } + + return TRUE; } /* ---------------------------------------------------------------------------------------------------- */ @@ -2275,16 +2568,18 @@ update_info_optical_disc (Device *device) static gboolean update_info_luks (Device *device) { - if (g_strcmp0 (device->priv->id_type, "crypto_LUKS") == 0 && - device->priv->holders_objpath->len == 1) { - device_set_device_is_luks (device, TRUE); - device_set_luks_holder (device, device->priv->holders_objpath->pdata[0]); - } else { - device_set_device_is_luks (device, FALSE); - device_set_luks_holder (device, NULL); - } + if (g_strcmp0 (device->priv->id_type, "crypto_LUKS") == 0 && device->priv->holders_objpath->len == 1) + { + device_set_device_is_luks (device, TRUE); + device_set_luks_holder (device, device->priv->holders_objpath->pdata[0]); + } + else + { + device_set_device_is_luks (device, FALSE); + device_set_luks_holder (device, NULL); + } - return TRUE; + return TRUE; } /* ---------------------------------------------------------------------------------------------------- */ @@ -2293,45 +2588,49 @@ update_info_luks (Device *device) static gboolean update_info_luks_cleartext (Device *device) { - uid_t unlocked_by_uid; - const gchar *dkd_dm_name; - const gchar *dkd_dm_target_types; - gboolean ret; + uid_t unlocked_by_uid; + const gchar *dkd_dm_name; + const gchar *dkd_dm_target_types; + gboolean ret; - ret = FALSE; + ret = FALSE; - dkd_dm_name = g_udev_device_get_property (device->priv->d, "UDISKS_DM_NAME"); - dkd_dm_target_types = g_udev_device_get_property (device->priv->d, "UDISKS_DM_TARGET_TYPES"); - if (dkd_dm_name != NULL && g_strcmp0 (dkd_dm_target_types, "crypt") == 0 && - device->priv->slaves_objpath->len == 1) { - - /* TODO: might be racing with setting is_drive earlier */ - device_set_device_is_drive (device, FALSE); + dkd_dm_name = g_udev_device_get_property (device->priv->d, "UDISKS_DM_NAME"); + dkd_dm_target_types = g_udev_device_get_property (device->priv->d, "UDISKS_DM_TARGET_TYPES"); + if (dkd_dm_name != NULL && g_strcmp0 (dkd_dm_target_types, "crypt") == 0 && device->priv->slaves_objpath->len == 1) + { - if (g_str_has_prefix (dkd_dm_name, "temporary-cryptsetup-")) { - /* ignore temporary devices created by /sbin/cryptsetup */ - goto out; - } + /* TODO: might be racing with setting is_drive earlier */ + device_set_device_is_drive (device, FALSE); - device_set_device_is_luks_cleartext (device, TRUE); + if (g_str_has_prefix (dkd_dm_name, "temporary-cryptsetup-")) + { + /* ignore temporary devices created by /sbin/cryptsetup */ + goto out; + } - device_set_luks_cleartext_slave (device, ((gchar **) device->priv->slaves_objpath->pdata)[0]); + device_set_device_is_luks_cleartext (device, TRUE); - if (luks_get_uid_from_dm_name (dkd_dm_name, &unlocked_by_uid)) { - device_set_luks_cleartext_unlocked_by_uid (device, unlocked_by_uid); - } + device_set_luks_cleartext_slave (device, ((gchar **) device->priv->slaves_objpath->pdata)[0]); - /* TODO: export this at some point */ - device_set_dm_name (device, dkd_dm_name); - } else { - device_set_device_is_luks_cleartext (device, FALSE); - device_set_luks_cleartext_slave (device, NULL); + if (luks_get_uid_from_dm_name (dkd_dm_name, &unlocked_by_uid)) + { + device_set_luks_cleartext_unlocked_by_uid (device, unlocked_by_uid); } - ret = TRUE; + /* TODO: export this at some point */ + device_set_dm_name (device, dkd_dm_name); + } + else + { + device_set_device_is_luks_cleartext (device, FALSE); + device_set_luks_cleartext_slave (device, NULL); + } + + ret = TRUE; out: - return ret; + return ret; } /* ---------------------------------------------------------------------------------------------------- */ @@ -2340,106 +2639,116 @@ update_info_luks_cleartext (Device *device) static gboolean update_info_linux_md_component (Device *device) { - if (g_strcmp0 (device->priv->id_type, "linux_raid_member") == 0) { - const gchar *md_comp_level; - gint md_comp_num_raid_devices; - const gchar *md_comp_uuid; - const gchar *md_comp_home_host; - const gchar *md_comp_name; - const gchar *md_comp_version; - gchar *md_name; - gchar *s; - int md_comp_position; - - md_comp_position = -1; - - device_set_device_is_linux_md_component (device, TRUE); - - /* linux_md_component_holder and linux_md_component_state */ - if (device->priv->holders_objpath->len == 1) { - Device *holder; - gchar **state_tokens; - - device_set_linux_md_component_holder (device, device->priv->holders_objpath->pdata[0]); - state_tokens = NULL; - holder = daemon_local_find_by_object_path (device->priv->daemon, - device->priv->holders_objpath->pdata[0]); - if (holder != NULL && holder->priv->device_is_linux_md) { - gchar *dev_name; - gchar *md_dev_path; - gchar *state_contents; - gchar *slot_contents; - gint slot_number; - gchar *endp; - - dev_name = g_path_get_basename (device->priv->native_path); - md_dev_path = g_strdup_printf ("%s/md/dev-%s", holder->priv->native_path, dev_name); - state_contents = sysfs_get_string (md_dev_path, "state"); - g_strstrip (state_contents); - state_tokens = g_strsplit (state_contents, ",", 0); - - slot_contents = sysfs_get_string (md_dev_path, "slot"); - g_strstrip (slot_contents); - slot_number = strtol (slot_contents, &endp, 0); - if (endp != NULL && *endp == '\0') { - md_comp_position = slot_number; - } - - g_free (slot_contents); - g_free (state_contents); - g_free (md_dev_path); - g_free (dev_name); - } - - device_set_linux_md_component_state (device, state_tokens); - g_strfreev (state_tokens); - - } else { - /* no holder, nullify properties */ - device_set_linux_md_component_holder (device, NULL); - device_set_linux_md_component_state (device, NULL); + if (g_strcmp0 (device->priv->id_type, "linux_raid_member") == 0) + { + const gchar *md_comp_level; + gint md_comp_num_raid_devices; + const gchar *md_comp_uuid; + const gchar *md_comp_home_host; + const gchar *md_comp_name; + const gchar *md_comp_version; + gchar *md_name; + gchar *s; + int md_comp_position; + + md_comp_position = -1; + + device_set_device_is_linux_md_component (device, TRUE); + + /* linux_md_component_holder and linux_md_component_state */ + if (device->priv->holders_objpath->len == 1) + { + Device *holder; + gchar **state_tokens; + + device_set_linux_md_component_holder (device, device->priv->holders_objpath->pdata[0]); + state_tokens = NULL; + holder = daemon_local_find_by_object_path (device->priv->daemon, device->priv->holders_objpath->pdata[0]); + if (holder != NULL && holder->priv->device_is_linux_md) + { + gchar *dev_name; + gchar *md_dev_path; + gchar *state_contents; + gchar *slot_contents; + gint slot_number; + gchar *endp; + + dev_name = g_path_get_basename (device->priv->native_path); + md_dev_path = g_strdup_printf ("%s/md/dev-%s", holder->priv->native_path, dev_name); + state_contents = sysfs_get_string (md_dev_path, "state"); + g_strstrip (state_contents); + state_tokens = g_strsplit (state_contents, ",", 0); + + slot_contents = sysfs_get_string (md_dev_path, "slot"); + g_strstrip (slot_contents); + slot_number = strtol (slot_contents, &endp, 0); + if (endp != NULL && *endp == '\0') + { + md_comp_position = slot_number; } - md_comp_level = g_udev_device_get_property (device->priv->d, "MD_LEVEL"); - md_comp_num_raid_devices = g_udev_device_get_property_as_int (device->priv->d, "MD_DEVICES"); - md_comp_uuid = g_udev_device_get_property (device->priv->d, "MD_UUID"); - md_name = g_strdup (g_udev_device_get_property (device->priv->d, "MD_NAME")); - s = NULL; - if (md_name != NULL) - s = strstr (md_name, ":"); - if (s != NULL) { - *s = '\0'; - md_comp_home_host = md_name; - md_comp_name = s + 1; - } else { - md_comp_home_host = ""; - md_comp_name = md_name; - } - md_comp_version = device->priv->id_version; + g_free (slot_contents); + g_free (state_contents); + g_free (md_dev_path); + g_free (dev_name); + } - device_set_linux_md_component_level (device, md_comp_level); - device_set_linux_md_component_position (device, md_comp_position); - device_set_linux_md_component_num_raid_devices (device, md_comp_num_raid_devices); - device_set_linux_md_component_uuid (device, md_comp_uuid); - device_set_linux_md_component_home_host (device, md_comp_home_host); - device_set_linux_md_component_name (device, md_comp_name); - device_set_linux_md_component_version (device, md_comp_version); + device_set_linux_md_component_state (device, state_tokens); + g_strfreev (state_tokens); - g_free (md_name); - } else { - device_set_device_is_linux_md_component (device, FALSE); - device_set_linux_md_component_level (device, NULL); - device_set_linux_md_component_position (device, -1); - device_set_linux_md_component_num_raid_devices (device, 0); - device_set_linux_md_component_uuid (device, NULL); - device_set_linux_md_component_home_host (device, NULL); - device_set_linux_md_component_name (device, NULL); - device_set_linux_md_component_version (device, NULL); - device_set_linux_md_component_holder (device, NULL); - device_set_linux_md_component_state (device, NULL); } + else + { + /* no holder, nullify properties */ + device_set_linux_md_component_holder (device, NULL); + device_set_linux_md_component_state (device, NULL); + } + + md_comp_level = g_udev_device_get_property (device->priv->d, "MD_LEVEL"); + md_comp_num_raid_devices = g_udev_device_get_property_as_int (device->priv->d, "MD_DEVICES"); + md_comp_uuid = g_udev_device_get_property (device->priv->d, "MD_UUID"); + md_name = g_strdup (g_udev_device_get_property (device->priv->d, "MD_NAME")); + s = NULL; + if (md_name != NULL) + s = strstr (md_name, ":"); + if (s != NULL) + { + *s = '\0'; + md_comp_home_host = md_name; + md_comp_name = s + 1; + } + else + { + md_comp_home_host = ""; + md_comp_name = md_name; + } + md_comp_version = device->priv->id_version; + + device_set_linux_md_component_level (device, md_comp_level); + device_set_linux_md_component_position (device, md_comp_position); + device_set_linux_md_component_num_raid_devices (device, md_comp_num_raid_devices); + device_set_linux_md_component_uuid (device, md_comp_uuid); + device_set_linux_md_component_home_host (device, md_comp_home_host); + device_set_linux_md_component_name (device, md_comp_name); + device_set_linux_md_component_version (device, md_comp_version); + + g_free (md_name); + } + else + { + device_set_device_is_linux_md_component (device, FALSE); + device_set_linux_md_component_level (device, NULL); + device_set_linux_md_component_position (device, -1); + device_set_linux_md_component_num_raid_devices (device, 0); + device_set_linux_md_component_uuid (device, NULL); + device_set_linux_md_component_home_host (device, NULL); + device_set_linux_md_component_name (device, NULL); + device_set_linux_md_component_version (device, NULL); + device_set_linux_md_component_holder (device, NULL); + device_set_linux_md_component_state (device, NULL); + } - return TRUE; + return TRUE; } /* ---------------------------------------------------------------------------------------------------- */ @@ -2448,223 +2757,247 @@ update_info_linux_md_component (Device *device) static gboolean update_info_linux_md (Device *device) { - gboolean ret; - guint n; - gchar *s; - gchar *p; - - ret = FALSE; - - if (sysfs_file_exists (device->priv->native_path, "md")) { - gchar *uuid; - gint num_raid_devices; - gchar *raid_level; - gchar *array_state; - Device *slave; - GPtrArray *md_slaves; - const gchar *md_name; - const gchar *md_home_host; - - device_set_device_is_linux_md (device, TRUE); - - /* figure out if the array is active */ - array_state = sysfs_get_string (device->priv->native_path, "md/array_state"); - if (array_state == NULL) { - g_print ("**** NOTE: Linux MD array %s has no array_state file'; removing\n", device->priv->native_path); - goto out; - } - g_strstrip (array_state); + gboolean ret; + guint n; + gchar *s; + gchar *p; - /* ignore clear arrays since these have no devices, no size, no level */ - if (strcmp (array_state, "clear") == 0) { - g_print ("**** NOTE: Linux MD array %s is 'clear'; removing\n", device->priv->native_path); - g_free (array_state); - goto out; - } + ret = FALSE; - device_set_linux_md_state (device, array_state); - g_free (array_state); + if (sysfs_file_exists (device->priv->native_path, "md")) + { + gchar *uuid; + gint num_raid_devices; + gchar *raid_level; + gchar *array_state; + Device *slave; + GPtrArray *md_slaves; + const gchar *md_name; + const gchar *md_home_host; + + device_set_device_is_linux_md (device, TRUE); + + /* figure out if the array is active */ + array_state = sysfs_get_string (device->priv->native_path, "md/array_state"); + if (array_state == NULL) + { + g_print ("**** NOTE: Linux MD array %s has no array_state file'; removing\n", device->priv->native_path); + goto out; + } + g_strstrip (array_state); - /* find a slave from the array */ - slave = NULL; - for (n = 0; n < device->priv->slaves_objpath->len; n++) { - const gchar *slave_objpath; + /* ignore clear arrays since these have no devices, no size, no level */ + if (strcmp (array_state, "clear") == 0) + { + g_print ("**** NOTE: Linux MD array %s is 'clear'; removing\n", device->priv->native_path); + g_free (array_state); + goto out; + } - slave_objpath = device->priv->slaves_objpath->pdata[n]; - slave = daemon_local_find_by_object_path (device->priv->daemon, slave_objpath); - if (slave != NULL) - break; - } + device_set_linux_md_state (device, array_state); + g_free (array_state); - uuid = g_strdup (g_udev_device_get_property (device->priv->d, "MD_UUID")); - num_raid_devices = sysfs_get_int (device->priv->native_path, "md/raid_disks"); - raid_level = g_strstrip (sysfs_get_string (device->priv->native_path, "md/level")); - - if (slave != NULL) { - /* if the UUID isn't set by the udev rules (array may be inactive) get it from a slave */ - if (uuid == NULL || strlen (uuid) == 0) { - g_free (uuid); - uuid = g_strdup (slave->priv->linux_md_component_uuid); - } - - /* ditto for raid level */ - if (raid_level == NULL || strlen (raid_level) == 0) { - g_free (raid_level); - raid_level = g_strdup (slave->priv->linux_md_component_level); - } - - /* and num_raid_devices too */ - if (device->priv->linux_md_num_raid_devices == 0) { - num_raid_devices = slave->priv->linux_md_component_num_raid_devices; - } - } + /* find a slave from the array */ + slave = NULL; + for (n = 0; n < device->priv->slaves_objpath->len; n++) + { + const gchar *slave_objpath; - device_set_linux_md_uuid (device, uuid); - device_set_linux_md_num_raid_devices (device, num_raid_devices); - device_set_linux_md_level (device, raid_level); - g_free (raid_level); - g_free (uuid); - - /* infer the array name and homehost */ - p = g_strdup (g_udev_device_get_property (device->priv->d, "MD_NAME")); - s = NULL; - if (p != NULL) - s = strstr (p, ":"); - if (s != NULL) { - *s = '\0'; - md_home_host = p; - md_name = s + 1; - } else { - md_home_host = ""; - md_name = p; - } - device_set_linux_md_home_host (device, md_home_host); - device_set_linux_md_name (device, md_name); - g_free (p); - - s = g_strstrip (sysfs_get_string (device->priv->native_path, "md/metadata_version")); - device_set_linux_md_version (device, s); - g_free (s); - - /* Go through all block slaves and build up the linux_md_slaves property - * - * Also update the slaves since the slave state may have changed. - */ - md_slaves = g_ptr_array_new (); - for (n = 0; n < device->priv->slaves_objpath->len; n++) { - Device *slave_device; - const gchar *slave_objpath; - - slave_objpath = device->priv->slaves_objpath->pdata[n]; - g_ptr_array_add (md_slaves, (gpointer) slave_objpath); - slave_device = daemon_local_find_by_object_path (device->priv->daemon, slave_objpath); - if (slave_device != NULL) { - update_info (slave_device); - } + slave_objpath = device->priv->slaves_objpath->pdata[n]; + slave = daemon_local_find_by_object_path (device->priv->daemon, slave_objpath); + if (slave != NULL) + break; + } + + uuid = g_strdup (g_udev_device_get_property (device->priv->d, "MD_UUID")); + num_raid_devices = sysfs_get_int (device->priv->native_path, "md/raid_disks"); + raid_level = g_strstrip (sysfs_get_string (device->priv->native_path, "md/level")); + + if (slave != NULL) + { + /* if the UUID isn't set by the udev rules (array may be inactive) get it from a slave */ + if (uuid == NULL || strlen (uuid) == 0) + { + g_free (uuid); + uuid = g_strdup (slave->priv->linux_md_component_uuid); + } + + /* ditto for raid level */ + if (raid_level == NULL || strlen (raid_level) == 0) + { + g_free (raid_level); + raid_level = g_strdup (slave->priv->linux_md_component_level); + } + + /* and num_raid_devices too */ + if (device->priv->linux_md_num_raid_devices == 0) + { + num_raid_devices = slave->priv->linux_md_component_num_raid_devices; + } + } + + device_set_linux_md_uuid (device, uuid); + device_set_linux_md_num_raid_devices (device, num_raid_devices); + device_set_linux_md_level (device, raid_level); + g_free (raid_level); + g_free (uuid); + + /* infer the array name and homehost */ + p = g_strdup (g_udev_device_get_property (device->priv->d, "MD_NAME")); + s = NULL; + if (p != NULL) + s = strstr (p, ":"); + if (s != NULL) + { + *s = '\0'; + md_home_host = p; + md_name = s + 1; + } + else + { + md_home_host = ""; + md_name = p; + } + device_set_linux_md_home_host (device, md_home_host); + device_set_linux_md_name (device, md_name); + g_free (p); + + s = g_strstrip (sysfs_get_string (device->priv->native_path, "md/metadata_version")); + device_set_linux_md_version (device, s); + g_free (s); + + /* Go through all block slaves and build up the linux_md_slaves property + * + * Also update the slaves since the slave state may have changed. + */ + md_slaves = g_ptr_array_new (); + for (n = 0; n < device->priv->slaves_objpath->len; n++) + { + Device *slave_device; + const gchar *slave_objpath; + + slave_objpath = device->priv->slaves_objpath->pdata[n]; + g_ptr_array_add (md_slaves, (gpointer) slave_objpath); + slave_device = daemon_local_find_by_object_path (device->priv->daemon, slave_objpath); + if (slave_device != NULL) + { + update_info (slave_device); + } + } + g_ptr_array_sort (md_slaves, (GCompareFunc) ptr_str_array_compare); + g_ptr_array_add (md_slaves, NULL); + device_set_linux_md_slaves (device, (GStrv) md_slaves->pdata); + g_ptr_array_free (md_slaves, TRUE); + + /* TODO: may race */ + device_set_drive_vendor (device, "Linux"); + if (device->priv->linux_md_level != NULL) + s = g_strdup_printf ("Software RAID %s", device->priv->linux_md_level); + else + s = g_strdup_printf ("Software RAID"); + device_set_drive_model (device, s); + g_free (s); + device_set_drive_revision (device, device->priv->linux_md_version); + device_set_drive_connection_interface (device, "virtual"); + device_set_drive_serial (device, device->priv->linux_md_uuid); + + /* RAID-0 can never resync or run degraded */ + if (g_strcmp0 (device->priv->linux_md_level, "raid0") == 0 || g_strcmp0 (device->priv->linux_md_level, "linear") + == 0) + { + device_set_linux_md_sync_action (device, "idle"); + device_set_linux_md_is_degraded (device, FALSE); + } + else + { + gchar *degraded_file; + gint num_degraded_devices; + + degraded_file = sysfs_get_string (device->priv->native_path, "md/degraded"); + if (degraded_file == NULL) + { + num_degraded_devices = 0; + } + else + { + num_degraded_devices = strtol (degraded_file, NULL, 0); + } + g_free (degraded_file); + + device_set_linux_md_is_degraded (device, (num_degraded_devices > 0)); + + s = g_strstrip (sysfs_get_string (device->priv->native_path, "md/sync_action")); + device_set_linux_md_sync_action (device, s); + g_free (s); + + if (device->priv->linux_md_sync_action == NULL || strlen (device->priv->linux_md_sync_action) == 0) + { + device_set_linux_md_sync_action (device, "idle"); + } + + /* if not idle; update percentage and speed */ + if (g_strcmp0 (device->priv->linux_md_sync_action, "idle") != 0) + { + char *s; + guint64 done; + guint64 remaining; + + s = g_strstrip (sysfs_get_string (device->priv->native_path, "md/sync_completed")); + if (sscanf (s, "%" G_GUINT64_FORMAT " / %" G_GUINT64_FORMAT "", &done, &remaining) == 2) + { + device_set_linux_md_sync_percentage (device, 100.0 * ((double) done) / ((double) remaining)); } - g_ptr_array_sort (md_slaves, (GCompareFunc) ptr_str_array_compare); - g_ptr_array_add (md_slaves, NULL); - device_set_linux_md_slaves (device, (GStrv) md_slaves->pdata); - g_ptr_array_free (md_slaves, TRUE); - - /* TODO: may race */ - device_set_drive_vendor (device, "Linux"); - if (device->priv->linux_md_level != NULL) - s = g_strdup_printf ("Software RAID %s", device->priv->linux_md_level); - else - s = g_strdup_printf ("Software RAID"); - device_set_drive_model (device, s); - g_free (s); - device_set_drive_revision (device, device->priv->linux_md_version); - device_set_drive_connection_interface (device, "virtual"); - device_set_drive_serial (device, device->priv->linux_md_uuid); - - /* RAID-0 can never resync or run degraded */ - if (g_strcmp0 (device->priv->linux_md_level, "raid0") == 0 || - g_strcmp0 (device->priv->linux_md_level, "linear") == 0) { - device_set_linux_md_sync_action (device, "idle"); - device_set_linux_md_is_degraded (device, FALSE); - } else { - gchar *degraded_file; - gint num_degraded_devices; - - degraded_file = sysfs_get_string (device->priv->native_path, "md/degraded"); - if (degraded_file == NULL) { - num_degraded_devices = 0; - } else { - num_degraded_devices = strtol (degraded_file, NULL, 0); - } - g_free (degraded_file); - - device_set_linux_md_is_degraded (device, (num_degraded_devices > 0)); - - s = g_strstrip (sysfs_get_string (device->priv->native_path, "md/sync_action")); - device_set_linux_md_sync_action (device, s); - g_free (s); - - if (device->priv->linux_md_sync_action == NULL || - strlen (device->priv->linux_md_sync_action) == 0) { - device_set_linux_md_sync_action (device, "idle"); - } - - /* if not idle; update percentage and speed */ - if (g_strcmp0 (device->priv->linux_md_sync_action, "idle") != 0) { - char *s; - guint64 done; - guint64 remaining; - - s = g_strstrip (sysfs_get_string (device->priv->native_path, "md/sync_completed")); - if (sscanf (s, "%" G_GUINT64_FORMAT " / %" G_GUINT64_FORMAT "", &done, &remaining) == 2) { - device_set_linux_md_sync_percentage (device, - 100.0 * ((double) done) / ((double) remaining)); - } else { - g_warning ("cannot parse md/sync_completed for %s: '%s'", - device->priv->native_path, - s); - } - g_free (s); - - device_set_linux_md_sync_speed (device, - 1000L * sysfs_get_uint64 (device->priv->native_path, "md/sync_speed")); - - /* Since the kernel doesn't emit uevents while the job is pending, set up - * a timeout for every two seconds to synthesize the change event so we can - * refresh the completed/speed properties. - */ - if (device->priv->linux_md_poll_timeout_id == 0) { - device->priv->linux_md_poll_timeout_id = - g_timeout_add_seconds_full (G_PRIORITY_DEFAULT, - 2, - poll_syncing_md_device, - g_object_ref (device), - g_object_unref); - } - } else { - device_set_linux_md_sync_percentage (device, 0.0); - device_set_linux_md_sync_speed (device, 0); - } + else + { + g_warning ("cannot parse md/sync_completed for %s: '%s'", device->priv->native_path, s); } + g_free (s); - } else { - device_set_device_is_linux_md (device, FALSE); - device_set_linux_md_state (device, NULL); - device_set_linux_md_level (device, NULL); - device_set_linux_md_num_raid_devices (device, 0); - device_set_linux_md_uuid (device, NULL); - device_set_linux_md_home_host (device, NULL); - device_set_linux_md_name (device, NULL); - device_set_linux_md_version (device, NULL); - device_set_linux_md_slaves (device, NULL); - device_set_linux_md_is_degraded (device, FALSE); - device_set_linux_md_sync_action (device, NULL); - device_set_linux_md_sync_percentage (device, 0.0); - device_set_linux_md_sync_speed (device, 0); + device_set_linux_md_sync_speed (device, 1000L * sysfs_get_uint64 (device->priv->native_path, + "md/sync_speed")); + + /* Since the kernel doesn't emit uevents while the job is pending, set up + * a timeout for every two seconds to synthesize the change event so we can + * refresh the completed/speed properties. + */ + if (device->priv->linux_md_poll_timeout_id == 0) + { + device->priv->linux_md_poll_timeout_id = g_timeout_add_seconds_full (G_PRIORITY_DEFAULT, + 2, + poll_syncing_md_device, + g_object_ref (device), + g_object_unref); + } + } + else + { + device_set_linux_md_sync_percentage (device, 0.0); + device_set_linux_md_sync_speed (device, 0); + } } - ret = TRUE; + } + else + { + device_set_device_is_linux_md (device, FALSE); + device_set_linux_md_state (device, NULL); + device_set_linux_md_level (device, NULL); + device_set_linux_md_num_raid_devices (device, 0); + device_set_linux_md_uuid (device, NULL); + device_set_linux_md_home_host (device, NULL); + device_set_linux_md_name (device, NULL); + device_set_linux_md_version (device, NULL); + device_set_linux_md_slaves (device, NULL); + device_set_linux_md_is_degraded (device, FALSE); + device_set_linux_md_sync_action (device, NULL); + device_set_linux_md_sync_percentage (device, 0.0); + device_set_linux_md_sync_speed (device, 0); + } + + ret = TRUE; out: - return ret; + return ret; } /* ---------------------------------------------------------------------------------------------------- */ @@ -2673,21 +3006,20 @@ update_info_linux_md (Device *device) static gboolean update_info_drive_ata_smart (Device *device) { - gboolean ata_smart_is_available; + gboolean ata_smart_is_available; - ata_smart_is_available = FALSE; - if (device->priv->device_is_drive && - g_udev_device_has_property (device->priv->d, "UDISKS_ATA_SMART_IS_AVAILABLE")) - ata_smart_is_available = g_udev_device_get_property_as_boolean (device->priv->d, "UDISKS_ATA_SMART_IS_AVAILABLE"); + ata_smart_is_available = FALSE; + if (device->priv->device_is_drive && g_udev_device_has_property (device->priv->d, "UDISKS_ATA_SMART_IS_AVAILABLE")) + ata_smart_is_available = g_udev_device_get_property_as_boolean (device->priv->d, "UDISKS_ATA_SMART_IS_AVAILABLE"); - device_set_drive_ata_smart_is_available (device, ata_smart_is_available); + device_set_drive_ata_smart_is_available (device, ata_smart_is_available); - /* NOTE: we don't collect ATA SMART data here, we only set whether the device is ATA SMART capable; - * collecting data is done in separate routines, see the - * device_drive_ata_smart_refresh_data() function for details. - */ + /* NOTE: we don't collect ATA SMART data here, we only set whether the device is ATA SMART capable; + * collecting data is done in separate routines, see the + * device_drive_ata_smart_refresh_data() function for details. + */ - return TRUE; + return TRUE; } /* ---------------------------------------------------------------------------------------------------- */ @@ -2696,101 +3028,120 @@ update_info_drive_ata_smart (Device *device) static gboolean update_info_is_system_internal (Device *device) { - gboolean is_system_internal; - - /* TODO: make it possible to override this property from a udev property. - */ - - /* start out by assuming the device is system internal, then adjust depending on what kind of - * device we are dealing with - */ - is_system_internal = TRUE; - - /* A Linux MD device is system internal if, and only if - * - * - a single component is system internal - * - there are no components - */ - if (device->priv->device_is_linux_md) { - is_system_internal = FALSE; - - if (device->priv->slaves_objpath->len == 0) { - is_system_internal = TRUE; - } else { - guint n; - - for (n = 0; n < device->priv->slaves_objpath->len; n++) { - const gchar *slave_objpath; - Device *slave; - - slave_objpath = device->priv->slaves_objpath->pdata[n]; - slave = daemon_local_find_by_object_path (device->priv->daemon, slave_objpath); - if (slave == NULL) - continue; - - if (slave->priv->device_is_system_internal) { - is_system_internal = TRUE; - break; - } - } - } + gboolean is_system_internal; - goto determined; - } + /* TODO: make it possible to override this property from a udev property. + */ - /* a partition is system internal only if the drive it belongs to is system internal */ - if (device->priv->device_is_partition) { - Device *enclosing_device; + /* start out by assuming the device is system internal, then adjust depending on what kind of + * device we are dealing with + */ + is_system_internal = TRUE; - enclosing_device = daemon_local_find_by_object_path (device->priv->daemon, device->priv->partition_slave); - if (enclosing_device != NULL) { - is_system_internal = enclosing_device->priv->device_is_system_internal; - } else { - is_system_internal = TRUE; - } + /* A Linux MD device is system internal if, and only if + * + * - a single component is system internal + * - there are no components + */ + if (device->priv->device_is_linux_md) + { + is_system_internal = FALSE; - goto determined; + if (device->priv->slaves_objpath->len == 0) + { + is_system_internal = TRUE; } + else + { + guint n; - /* a LUKS cleartext device is system internal only if the underlying crypto-text - * device is system internal - */ - if (device->priv->device_is_luks_cleartext) { - Device *enclosing_device; - enclosing_device = daemon_local_find_by_object_path (device->priv->daemon, device->priv->luks_cleartext_slave); - if (enclosing_device != NULL) { - is_system_internal = enclosing_device->priv->device_is_system_internal; - } else { - is_system_internal = TRUE; + for (n = 0; n < device->priv->slaves_objpath->len; n++) + { + const gchar *slave_objpath; + Device *slave; + + slave_objpath = device->priv->slaves_objpath->pdata[n]; + slave = daemon_local_find_by_object_path (device->priv->daemon, slave_objpath); + if (slave == NULL) + continue; + + if (slave->priv->device_is_system_internal) + { + is_system_internal = TRUE; + break; } + } + } + + goto determined; + } + + /* a partition is system internal only if the drive it belongs to is system internal */ + if (device->priv->device_is_partition) + { + Device *enclosing_device; - goto determined; + enclosing_device = daemon_local_find_by_object_path (device->priv->daemon, device->priv->partition_slave); + if (enclosing_device != NULL) + { + is_system_internal = enclosing_device->priv->device_is_system_internal; + } + else + { + is_system_internal = TRUE; } - /* devices with removable media are never system internal */ - if (device->priv->device_is_removable) { - is_system_internal = FALSE; - goto determined; + goto determined; + } + + /* a LUKS cleartext device is system internal only if the underlying crypto-text + * device is system internal + */ + if (device->priv->device_is_luks_cleartext) + { + Device *enclosing_device; + enclosing_device = daemon_local_find_by_object_path (device->priv->daemon, device->priv->luks_cleartext_slave); + if (enclosing_device != NULL) + { + is_system_internal = enclosing_device->priv->device_is_system_internal; } + else + { + is_system_internal = TRUE; + } + + goto determined; + } - /* devices on certain buses are never system internal */ - if (device->priv->device_is_drive && device->priv->drive_connection_interface != NULL) { + /* devices with removable media are never system internal */ + if (device->priv->device_is_removable) + { + is_system_internal = FALSE; + goto determined; + } - if (strcmp (device->priv->drive_connection_interface, "ata_serial_esata") == 0 || - strcmp (device->priv->drive_connection_interface, "sdio") == 0 || - strcmp (device->priv->drive_connection_interface, "usb") == 0 || - strcmp (device->priv->drive_connection_interface, "firewire") == 0) { - is_system_internal = FALSE; - } else { - is_system_internal = TRUE; - } - goto determined; + /* devices on certain buses are never system internal */ + if (device->priv->device_is_drive && device->priv->drive_connection_interface != NULL) + { + + if (strcmp (device->priv->drive_connection_interface, "ata_serial_esata") == 0 + || strcmp (device->priv->drive_connection_interface, "sdio") == 0 + || strcmp (device->priv->drive_connection_interface, "usb") == 0 + || strcmp (device->priv->drive_connection_interface, "firewire") == 0) + { + is_system_internal = FALSE; + } + else + { + is_system_internal = TRUE; } + goto determined; + } determined: - device_set_device_is_system_internal (device, is_system_internal); + device_set_device_is_system_internal (device, is_system_internal); - return TRUE; + return TRUE; } /* ---------------------------------------------------------------------------------------------------- */ @@ -2799,80 +3150,86 @@ update_info_is_system_internal (Device *device) static gboolean update_info_mount_state (Device *device) { - MountMonitor *monitor; - GList *mounts; - gboolean was_mounted; + MountMonitor *monitor; + GList *mounts; + gboolean was_mounted; + + mounts = NULL; - mounts = NULL; + /* defer setting the mount point until FilesystemMount returns and + * the mounts file is written + */ + if (device->priv->job_in_progress && g_strcmp0 (device->priv->job_id, "FilesystemMount") == 0) + goto out; - /* defer setting the mount point until FilesystemMount returns and - * the mounts file is written - */ - if (device->priv->job_in_progress && g_strcmp0 (device->priv->job_id, "FilesystemMount") == 0) - goto out; + monitor = daemon_local_get_mount_monitor (device->priv->daemon); - monitor = daemon_local_get_mount_monitor (device->priv->daemon); + mounts = mount_monitor_get_mounts_for_dev (monitor, device->priv->dev); - mounts = mount_monitor_get_mounts_for_dev (monitor, device->priv->dev); + was_mounted = device->priv->device_is_mounted; - was_mounted = device->priv->device_is_mounted; + if (mounts != NULL) + { + GList *l; + guint n; + gchar **mount_paths; - if (mounts != NULL) { - GList *l; - guint n; - gchar **mount_paths; + mount_paths = g_new0 (gchar *, g_list_length (mounts) + 1); + for (l = mounts, n = 0; l != NULL; l = l->next, n++) + { + mount_paths[n] = g_strdup (mount_get_mount_path (MOUNT (l->data))); + } - mount_paths = g_new0 (gchar *, g_list_length (mounts) + 1); - for (l = mounts, n = 0; l != NULL; l = l->next, n++) { - mount_paths[n] = g_strdup (mount_get_mount_path (MOUNT (l->data))); - } + device_set_device_is_mounted (device, TRUE); + device_set_device_mount_paths (device, mount_paths); + if (!was_mounted) + { + uid_t mounted_by_uid; - device_set_device_is_mounted (device, TRUE); - device_set_device_mount_paths (device, mount_paths); - if (!was_mounted) { - uid_t mounted_by_uid; + if (!mount_file_has_device (device->priv->device_file, &mounted_by_uid, NULL)) + mounted_by_uid = 0; + device_set_device_mounted_by_uid (device, mounted_by_uid); + } - if (!mount_file_has_device (device->priv->device_file, &mounted_by_uid, NULL)) - mounted_by_uid = 0; - device_set_device_mounted_by_uid (device, mounted_by_uid); - } + g_strfreev (mount_paths); - g_strfreev (mount_paths); - - } else { - gboolean remove_dir_on_unmount; - gchar *old_mount_path; - - old_mount_path = NULL; - if (device->priv->device_mount_paths->len > 0) - old_mount_path = g_strdup (((gchar **) device->priv->device_mount_paths->pdata)[0]); - - device_set_device_is_mounted (device, FALSE); - device_set_device_mount_paths (device, NULL); - device_set_device_mounted_by_uid (device, 0); - - /* clean up stale mount directory */ - remove_dir_on_unmount = FALSE; - if (was_mounted && mount_file_has_device (device->priv->device_file, - NULL, - &remove_dir_on_unmount)) { - mount_file_remove (device->priv->device_file, old_mount_path); - if (remove_dir_on_unmount) { - if (g_rmdir (old_mount_path) != 0) { - g_warning ("Error removing dir '%s' on unmount: %m", old_mount_path); - } - } - } + } + else + { + gboolean remove_dir_on_unmount; + gchar *old_mount_path; - g_free (old_mount_path); + old_mount_path = NULL; + if (device->priv->device_mount_paths->len > 0) + old_mount_path = g_strdup (((gchar **) device->priv->device_mount_paths->pdata)[0]); + device_set_device_is_mounted (device, FALSE); + device_set_device_mount_paths (device, NULL); + device_set_device_mounted_by_uid (device, 0); + + /* clean up stale mount directory */ + remove_dir_on_unmount = FALSE; + if (was_mounted && mount_file_has_device (device->priv->device_file, NULL, &remove_dir_on_unmount)) + { + mount_file_remove (device->priv->device_file, old_mount_path); + if (remove_dir_on_unmount) + { + if (g_rmdir (old_mount_path) != 0) + { + g_warning ("Error removing dir '%s' on unmount: %m", old_mount_path); + } + } } + g_free (old_mount_path); + + } + out: - g_list_foreach (mounts, (GFunc) g_object_unref, NULL); - g_list_free (mounts); + g_list_foreach (mounts, (GFunc) g_object_unref, NULL); + g_list_free (mounts); - return TRUE; + return TRUE; } /* ---------------------------------------------------------------------------------------------------- */ @@ -2881,63 +3238,67 @@ update_info_mount_state (Device *device) static gboolean update_info_media_detection (Device *device) { - gboolean detected; - gboolean polling; - gboolean inhibitable; - gboolean inhibited; + gboolean detected; + gboolean polling; + gboolean inhibitable; + gboolean inhibited; - detected = FALSE; - polling = FALSE; - inhibitable = FALSE; - inhibited = FALSE; + detected = FALSE; + polling = FALSE; + inhibitable = FALSE; + inhibited = FALSE; - if (device->priv->device_is_removable) { - guint64 evt_media_change; - GUdevDevice *parent; + if (device->priv->device_is_removable) + { + guint64 evt_media_change; + GUdevDevice *parent; - evt_media_change = sysfs_get_uint64 (device->priv->native_path, "../../evt_media_change"); - if (evt_media_change & 1) { - /* SATA AN capabable drive */ + evt_media_change = sysfs_get_uint64 (device->priv->native_path, "../../evt_media_change"); + if (evt_media_change & 1) + { + /* SATA AN capabable drive */ - polling = FALSE; - detected = TRUE; - goto determined; - } + polling = FALSE; + detected = TRUE; + goto determined; + } - parent = g_udev_device_get_parent_with_subsystem (device->priv->d, - "platform", - NULL); - if (parent != NULL) { - /* never poll PC floppy drives, they are noisy (fdo #22149) */ - if (g_str_has_prefix (g_udev_device_get_name (parent), "floppy.")) { - g_object_unref (parent); - goto determined; - } - g_object_unref (parent); - } + parent = g_udev_device_get_parent_with_subsystem (device->priv->d, "platform", NULL); + if (parent != NULL) + { + /* never poll PC floppy drives, they are noisy (fdo #22149) */ + if (g_str_has_prefix (g_udev_device_get_name (parent), "floppy.")) + { + g_object_unref (parent); + goto determined; + } + g_object_unref (parent); + } - /* assume the device needs polling */ - polling = TRUE; - inhibitable = TRUE; + /* assume the device needs polling */ + polling = TRUE; + inhibitable = TRUE; - if (device->priv->polling_inhibitors != NULL || - daemon_local_has_polling_inhibitors (device->priv->daemon)) { + if (device->priv->polling_inhibitors != NULL || daemon_local_has_polling_inhibitors (device->priv->daemon)) + { - detected = FALSE; - inhibited = TRUE; - } else { - detected = TRUE; - inhibited = FALSE; - } + detected = FALSE; + inhibited = TRUE; + } + else + { + detected = TRUE; + inhibited = FALSE; } + } determined: - device_set_device_is_media_change_detected (device, detected); - device_set_device_is_media_change_detection_polling (device, polling); - device_set_device_is_media_change_detection_inhibitable (device, inhibitable); - device_set_device_is_media_change_detection_inhibited (device, inhibited); + device_set_device_is_media_change_detected (device, detected); + device_set_device_is_media_change_detection_polling (device, polling); + device_set_device_is_media_change_detection_inhibitable (device, inhibitable); + device_set_device_is_media_change_detection_inhibited (device, inhibited); - return TRUE; + return TRUE; } /* ---------------------------------------------------------------------------------------------------- */ @@ -2946,82 +3307,82 @@ update_info_media_detection (Device *device) static gboolean update_info_drive_adapter (Device *device) { - Adapter *adapter; - const gchar *adapter_object_path; + Adapter *adapter; + const gchar *adapter_object_path; - adapter_object_path = NULL; + adapter_object_path = NULL; - adapter = daemon_local_find_enclosing_adapter (device->priv->daemon, - device->priv->native_path); - if (adapter != NULL) { - adapter_object_path = adapter_local_get_object_path (adapter); - } + adapter = daemon_local_find_enclosing_adapter (device->priv->daemon, device->priv->native_path); + if (adapter != NULL) + { + adapter_object_path = adapter_local_get_object_path (adapter); + } - device_set_drive_adapter (device, adapter_object_path); + device_set_drive_adapter (device, adapter_object_path); - return TRUE; + return TRUE; } /* drive_ports property */ static gboolean update_info_drive_ports (Device *device) { - GList *ports; - GList *l; - GPtrArray *p; + GList *ports; + GList *l; + GPtrArray *p; - ports = daemon_local_find_enclosing_ports (device->priv->daemon, device->priv->native_path); + ports = daemon_local_find_enclosing_ports (device->priv->daemon, device->priv->native_path); - p = g_ptr_array_new (); - for (l = ports; l != NULL; l = l->next) { - Port *port = PORT (l->data); + p = g_ptr_array_new (); + for (l = ports; l != NULL; l = l->next) + { + Port *port = PORT (l->data); - g_ptr_array_add (p, (gpointer) port_local_get_object_path (port)); - } - g_ptr_array_add (p, NULL); - device_set_drive_ports (device, (GStrv) p->pdata); - g_ptr_array_unref (p); + g_ptr_array_add (p, (gpointer) port_local_get_object_path (port)); + } + g_ptr_array_add (p, NULL); + device_set_drive_ports (device, (GStrv) p->pdata); + g_ptr_array_unref (p); - g_list_free (ports); + g_list_free (ports); - return TRUE; + return TRUE; } /* ---------------------------------------------------------------------------------------------------- */ -typedef struct { - guint idle_id; - Device *device; +typedef struct +{ + guint idle_id; + Device *device; } UpdateInfoInIdleData; static void update_info_in_idle_device_unreffed (gpointer user_data, GObject *where_the_object_was) { - UpdateInfoInIdleData *data = user_data; - g_source_remove (data->idle_id); + UpdateInfoInIdleData *data = user_data; + g_source_remove (data->idle_id); } static void update_info_in_idle_data_free (UpdateInfoInIdleData *data) { - g_object_weak_unref (G_OBJECT (data->device), - update_info_in_idle_device_unreffed, - data); - g_free (data); + g_object_weak_unref (G_OBJECT (data->device), update_info_in_idle_device_unreffed, data); + g_free (data); } static gboolean update_info_in_idle_cb (gpointer user_data) { - UpdateInfoInIdleData *data = user_data; + UpdateInfoInIdleData *data = user_data; - /* this indirectly calls update_info and also removes the device - * if it wants to be removed (e.g. if update_info() returns FALSE) - */ - daemon_local_synthesize_changed (data->device->priv->daemon, data->device); + /* this indirectly calls update_info and also removes the device + * if it wants to be removed (e.g. if update_info() returns FALSE) + */ + daemon_local_synthesize_changed (data->device->priv->daemon, data->device); - return FALSE; /* remove source */ + return FALSE; /* remove source */ } /** @@ -3034,18 +3395,16 @@ update_info_in_idle_cb (gpointer user_data) static void update_info_in_idle (Device *device) { - UpdateInfoInIdleData *data; + UpdateInfoInIdleData *data; - data = g_new0 (UpdateInfoInIdleData, 1); - data->device = device; - data->idle_id = g_idle_add_full (G_PRIORITY_HIGH_IDLE, - update_info_in_idle_cb, - data, - (GDestroyNotify) update_info_in_idle_data_free); + data = g_new0 (UpdateInfoInIdleData, 1); + data->device = device; + data->idle_id = g_idle_add_full (G_PRIORITY_HIGH_IDLE, + update_info_in_idle_cb, + data, + (GDestroyNotify) update_info_in_idle_data_free); - g_object_weak_ref (G_OBJECT (device), - update_info_in_idle_device_unreffed, - data); + g_object_weak_ref (G_OBJECT (device), update_info_in_idle_device_unreffed, data); } /** @@ -3063,428 +3422,481 @@ update_info_in_idle (Device *device) static gboolean update_info (Device *device) { - guint64 start, size; - char *s; - guint n; - gboolean ret; - char *path; - GDir *dir; - const char *name; - GList *l; - GList *old_slaves_objpath; - GList *old_holders_objpath; - GList *cur_slaves_objpath; - GList *cur_holders_objpath; - GList *added_objpath; - GList *removed_objpath; - GPtrArray *symlinks_by_id; - GPtrArray *symlinks_by_path; - GPtrArray *slaves; - GPtrArray *holders; - gint major; - gint minor; - gboolean media_available; - - ret = FALSE; - - g_print ("**** UPDATING %s\n", device->priv->native_path); - - /* need the slaves/holders to synthesize 'change' events if a device goes away (since the kernel - * doesn't do generate these) - */ - old_slaves_objpath = dup_list_from_ptrarray (device->priv->slaves_objpath); - old_holders_objpath = dup_list_from_ptrarray (device->priv->holders_objpath); - - /* drive identification */ - if (sysfs_file_exists (device->priv->native_path, "range")) { - device_set_device_is_drive (device, TRUE); - } else { - device_set_device_is_drive (device, FALSE); - } - - if (!g_udev_device_has_property (device->priv->d, "MAJOR") || - !g_udev_device_has_property (device->priv->d, "MINOR")) { - g_warning ("No major/minor for %s", device->priv->native_path); - goto out; - } - - /* ignore dm devices that are not active */ - if (g_str_has_prefix (g_udev_device_get_name (device->priv->d), "dm-") && - g_udev_device_get_property (device->priv->d, "UDISKS_DM_STATE") == NULL) - goto out; - - major = g_udev_device_get_property_as_int (device->priv->d, "MAJOR"); - minor = g_udev_device_get_property_as_int (device->priv->d, "MINOR"); - device->priv->dev = makedev (major, minor); - - device_set_device_file (device, g_udev_device_get_device_file (device->priv->d)); - if (device->priv->device_file == NULL) { - g_warning ("No device file for %s", device->priv->native_path); - goto out; - } - - const char * const * symlinks; - symlinks = g_udev_device_get_device_file_symlinks (device->priv->d); - symlinks_by_id = g_ptr_array_new (); - symlinks_by_path = g_ptr_array_new (); - for (n = 0; symlinks[n] != NULL; n++) { - if (g_str_has_prefix (symlinks[n], "/dev/disk/by-id/") || - g_str_has_prefix (symlinks[n], "/dev/disk/by-uuid/")) { - g_ptr_array_add (symlinks_by_id, (gpointer) symlinks[n]); - } else if (g_str_has_prefix (symlinks[n], "/dev/disk/by-path/")) { - g_ptr_array_add (symlinks_by_path, (gpointer) symlinks[n]); - } + guint64 start, size; + char *s; + guint n; + gboolean ret; + char *path; + GDir *dir; + const char *name; + GList *l; + GList *old_slaves_objpath; + GList *old_holders_objpath; + GList *cur_slaves_objpath; + GList *cur_holders_objpath; + GList *added_objpath; + GList *removed_objpath; + GPtrArray *symlinks_by_id; + GPtrArray *symlinks_by_path; + GPtrArray *slaves; + GPtrArray *holders; + gint major; + gint minor; + gboolean media_available; + + ret = FALSE; + + g_print ("**** UPDATING %s\n", device->priv->native_path); + + /* need the slaves/holders to synthesize 'change' events if a device goes away (since the kernel + * doesn't do generate these) + */ + old_slaves_objpath = dup_list_from_ptrarray (device->priv->slaves_objpath); + old_holders_objpath = dup_list_from_ptrarray (device->priv->holders_objpath); + + /* drive identification */ + if (sysfs_file_exists (device->priv->native_path, "range")) + { + device_set_device_is_drive (device, TRUE); + } + else + { + device_set_device_is_drive (device, FALSE); + } + + if (!g_udev_device_has_property (device->priv->d, "MAJOR") || !g_udev_device_has_property (device->priv->d, "MINOR")) + { + g_warning ("No major/minor for %s", device->priv->native_path); + goto out; + } + + /* ignore dm devices that are not active */ + if (g_str_has_prefix (g_udev_device_get_name (device->priv->d), "dm-") + && g_udev_device_get_property (device->priv->d, "UDISKS_DM_STATE") == NULL) + goto out; + + major = g_udev_device_get_property_as_int (device->priv->d, "MAJOR"); + minor = g_udev_device_get_property_as_int (device->priv->d, "MINOR"); + device->priv->dev = makedev (major, minor); + + device_set_device_file (device, g_udev_device_get_device_file (device->priv->d)); + if (device->priv->device_file == NULL) + { + g_warning ("No device file for %s", device->priv->native_path); + goto out; + } + + const char * const * symlinks; + symlinks = g_udev_device_get_device_file_symlinks (device->priv->d); + symlinks_by_id = g_ptr_array_new (); + symlinks_by_path = g_ptr_array_new (); + for (n = 0; symlinks[n] != NULL; n++) + { + if (g_str_has_prefix (symlinks[n], "/dev/disk/by-id/") || g_str_has_prefix (symlinks[n], "/dev/disk/by-uuid/")) + { + g_ptr_array_add (symlinks_by_id, (gpointer) symlinks[n]); } - g_ptr_array_sort (symlinks_by_id, (GCompareFunc) ptr_str_array_compare); - g_ptr_array_sort (symlinks_by_path, (GCompareFunc) ptr_str_array_compare); - g_ptr_array_add (symlinks_by_id, NULL); - g_ptr_array_add (symlinks_by_path, NULL); - device_set_device_file_by_id (device, (GStrv) symlinks_by_id->pdata); - device_set_device_file_by_path (device, (GStrv) symlinks_by_path->pdata); - g_ptr_array_free (symlinks_by_id, TRUE); - g_ptr_array_free (symlinks_by_path, TRUE); - - device_set_device_is_removable (device, (sysfs_get_int (device->priv->native_path, "removable") != 0)); - - /* device_is_media_available and device_media_detection_time property */ - if (device->priv->device_is_removable) { - media_available = FALSE; - if (g_udev_device_has_property (device->priv->d, "UDISKS_MEDIA_AVAILABLE")) { - media_available = g_udev_device_get_property_as_boolean (device->priv->d, "UDISKS_MEDIA_AVAILABLE"); - } else { - if (g_udev_device_has_property (device->priv->d, "ID_CDROM_MEDIA_STATE")) { - media_available = TRUE; - } else { - media_available = FALSE; - } - } - } else { - media_available = TRUE; - } - device_set_device_is_media_available (device, media_available); - if (media_available) { - if (device->priv->device_media_detection_time == 0) - device_set_device_media_detection_time (device, (guint64) time (NULL)); - } else { - device_set_device_media_detection_time (device, 0); - } - - /* device_size, device_block_size and device_is_read_only properties */ - if (device->priv->device_is_media_available) { - guint64 block_size; - - device_set_device_size (device, sysfs_get_uint64 (device->priv->native_path, "size") * ((guint64) 512)); - device_set_device_is_read_only (device, (sysfs_get_int (device->priv->native_path, "ro") != 0)); - /* This is not available on all devices so fall back to 512 if unavailable. - * - * Another way to get this information is the BLKSSZGET ioctl but we don't want - * to open the device. Ideally vol_id would export it. - */ - block_size = sysfs_get_uint64 (device->priv->native_path, "queue/hw_sector_size"); - if (block_size == 0) - block_size = 512; - device_set_device_block_size (device, block_size); - - } else { - device_set_device_size (device, 0); - device_set_device_block_size (device, 0); - device_set_device_is_read_only (device, FALSE); - } - - /* figure out if we're a partition and, if so, who our slave is */ - if (sysfs_file_exists (device->priv->native_path, "start")) { - - /* we're partitioned by the kernel */ - device_set_device_is_partition (device, TRUE); - start = sysfs_get_uint64 (device->priv->native_path, "start"); - size = sysfs_get_uint64 (device->priv->native_path, "size"); - device_set_partition_offset (device, start * 512); /* device->priv->device_block_size; */ - device_set_partition_size (device, size * 512); /* device->priv->device_block_size; */ - - s = device->priv->native_path; - for (n = strlen (s) - 1; n >= 0 && g_ascii_isdigit (s[n]); n--) - ; - device_set_partition_number (device, strtol (s + n + 1, NULL, 0)); - - s = g_strdup (device->priv->native_path); - for (n = strlen (s) - 1; n >= 0 && s[n] != '/'; n--) - s[n] = '\0'; - s[n] = '\0'; - device_set_partition_slave (device, compute_object_path (s)); - g_free (s); - } else { - /* TODO: handle partitions created by kpartx / dm-linear */ - } - - /* Figure out if we are a partition table - we don't want to rely on udisks-part-id - * for this; it might not detect all partition table formats that the kernel supports. - * - * The kernel guarantees that all childs are created before the uevent for the parent - * is created. So if we have childs, we must be a partition table. - * - * To detect a child we check for the existance of a subdir that has the parents - * name as a prefix (e.g. for parent sda then sda1, sda2, sdap1 etc. will work). - */ - s = g_path_get_basename (device->priv->native_path); - if ((dir = g_dir_open (device->priv->native_path, 0, NULL)) != NULL) { - guint partition_count; - partition_count = 0; - while ((name = g_dir_read_name (dir)) != NULL) { - if (g_str_has_prefix (name, s)) { - partition_count++; - } - } - g_dir_close (dir); - device_set_partition_table_count (device, partition_count); - device_set_device_is_partition_table (device, (partition_count > 0)); - } - g_free (s); - - - /* Maintain (non-exported) properties holders and slaves for the holders resp. slaves - * directories in sysfs. The entries in these arrays are object paths - we ignore - * an entry unless it corresponds to an device in our local database. - */ - path = g_build_filename (device->priv->native_path, "slaves", NULL); - slaves = g_ptr_array_new (); - if((dir = g_dir_open (path, 0, NULL)) != NULL) { - while ((name = g_dir_read_name (dir)) != NULL) { - Device *device2; - - s = compute_object_path (name); - - device2 = daemon_local_find_by_object_path (device->priv->daemon, s); - if (device2 != NULL) { - //g_debug ("%s has slave %s", device->priv->object_path, s); - g_ptr_array_add (slaves, s); - } else { - //g_debug ("%s has non-existant slave %s", device->priv->object_path, s); - g_free (s); - } - } - g_dir_close (dir); - } - g_free (path); - g_ptr_array_sort (slaves, (GCompareFunc) ptr_str_array_compare); - g_ptr_array_add (slaves, NULL); - device_set_slaves_objpath (device, (GStrv) slaves->pdata); - g_ptr_array_foreach (slaves, (GFunc) g_free, NULL); - g_ptr_array_free (slaves, TRUE); - - path = g_build_filename (device->priv->native_path, "holders", NULL); - holders = g_ptr_array_new (); - if((dir = g_dir_open (path, 0, NULL)) != NULL) { - while ((name = g_dir_read_name (dir)) != NULL) { - Device *device2; - - s = compute_object_path (name); - device2 = daemon_local_find_by_object_path (device->priv->daemon, s); - if (device2 != NULL) { - //g_debug ("%s has holder %s", device->priv->object_path, s); - g_ptr_array_add (holders, s); - } else { - //g_debug ("%s has non-existant holder %s", device->priv->object_path, s); - g_free (s); - } - } - g_dir_close (dir); - } - g_free (path); - g_ptr_array_sort (holders, (GCompareFunc) ptr_str_array_compare); - g_ptr_array_add (holders, NULL); - device_set_holders_objpath (device, (GStrv) holders->pdata); - g_ptr_array_foreach (holders, (GFunc) g_free, NULL); - g_ptr_array_free (holders, TRUE); - - /* ------------------------------------- */ - /* Now set all properties from udev data */ - /* ------------------------------------- */ - - /* at this point we have - * - * - device_file - * - device_file_by_id - * - device_file_by_path - * - device_size - * - device_block_size - * - device_is_removable - * - device_is_read_only - * - device_is_drive - * - device_is_media_available - * - device_is_partition - * - device_is_partition_table - * - slaves_objpath - * - holders_objpath - * - * - partition_number - * - partition_slave - * - */ - - /* device_presentation_hide, device_presentation_name and device_presentation_icon_name properties */ - if (!update_info_presentation (device)) - goto out; - - /* id_* properties */ - if (!update_info_id (device)) - goto out; - - /* partition_table_* properties */ - if (!update_info_partition_table (device)) - goto out; - - /* partition_* properties */ - if (!update_info_partition (device)) - goto out; - - /* drive_* properties */ - if (!update_info_drive (device)) - goto out; - - /* device_is_optical_disc and optical_disc_* properties */ - if (!update_info_optical_disc (device)) - goto out; - - /* device_is_luks and luks_holder */ - if (!update_info_luks (device)) - goto out; - - /* device_is_luks_cleartext and luks_cleartext_* properties */ - if (!update_info_luks_cleartext (device)) - goto out; - - /* device_is_linux_md_component and linux_md_component_* properties */ - if (!update_info_linux_md_component (device)) - goto out; - - /* device_is_linux_md and linux_md_* properties */ - if (!update_info_linux_md (device)) - goto out; - - /* drive_ata_smart_* properties */ - if (!update_info_drive_ata_smart (device)) - goto out; - - /* drive_can_spindown property */ - if (!update_info_drive_can_spindown (device)) - goto out; - - /* device_is_system_internal property */ - if (!update_info_is_system_internal (device)) - goto out; - - /* device_is_mounted, device_mount, device_mounted_by_uid */ - if (!update_info_mount_state (device)) - goto out; - - /* device_is_media_change_detected, device_is_media_change_detection_* properties */ - if (!update_info_media_detection (device)) - goto out; - - /* drive_adapter proprety */ - if (!update_info_drive_adapter (device)) - goto out; - - /* drive_ports proprety */ - if (!update_info_drive_ports (device)) - goto out; - - ret = TRUE; - -out: - - /* Now check if holders/ or slaves/ has changed since last update. We compute - * the delta and do update_info() on each holder/slave that has been - * added/removed. - * - * Note that this won't trigger an endless loop since we look at the diffs. - * - * We have to do this because the kernel doesn't generate any 'change' event - * when slaves/ or holders/ change. This is unfortunate because we *need* such - * a change event to update properties devices (for example: luks_holder). - * - * We do the update in idle because the update may depend on the device - * currently being processed being added. - */ - - cur_slaves_objpath = dup_list_from_ptrarray (device->priv->slaves_objpath); - cur_holders_objpath = dup_list_from_ptrarray (device->priv->holders_objpath); - - old_slaves_objpath = g_list_sort (old_slaves_objpath, (GCompareFunc) g_strcmp0); - old_holders_objpath = g_list_sort (old_holders_objpath, (GCompareFunc) g_strcmp0); - cur_slaves_objpath = g_list_sort (cur_slaves_objpath, (GCompareFunc) g_strcmp0); - cur_holders_objpath = g_list_sort (cur_holders_objpath, (GCompareFunc) g_strcmp0); - - diff_sorted_lists (old_slaves_objpath, cur_slaves_objpath, - (GCompareFunc) g_strcmp0, - &added_objpath, &removed_objpath); - for (l = added_objpath; l != NULL; l = l->next) { - const gchar *objpath2 = l->data; - Device *device2; - - //g_debug ("### %s added slave %s", device->priv->object_path, objpath2); - device2 = daemon_local_find_by_object_path (device->priv->daemon, objpath2); - if (device2 != NULL) { - update_info_in_idle (device2); - } else { - g_print ("**** NOTE: %s added non-existant slave %s\n", device->priv->object_path, objpath2); - } + else if (g_str_has_prefix (symlinks[n], "/dev/disk/by-path/")) + { + g_ptr_array_add (symlinks_by_path, (gpointer) symlinks[n]); + } + } + g_ptr_array_sort (symlinks_by_id, (GCompareFunc) ptr_str_array_compare); + g_ptr_array_sort (symlinks_by_path, (GCompareFunc) ptr_str_array_compare); + g_ptr_array_add (symlinks_by_id, NULL); + g_ptr_array_add (symlinks_by_path, NULL); + device_set_device_file_by_id (device, (GStrv) symlinks_by_id->pdata); + device_set_device_file_by_path (device, (GStrv) symlinks_by_path->pdata); + g_ptr_array_free (symlinks_by_id, TRUE); + g_ptr_array_free (symlinks_by_path, TRUE); + + device_set_device_is_removable (device, (sysfs_get_int (device->priv->native_path, "removable") != 0)); + + /* device_is_media_available and device_media_detection_time property */ + if (device->priv->device_is_removable) + { + media_available = FALSE; + if (g_udev_device_has_property (device->priv->d, "UDISKS_MEDIA_AVAILABLE")) + { + media_available = g_udev_device_get_property_as_boolean (device->priv->d, "UDISKS_MEDIA_AVAILABLE"); + } + else + { + if (g_udev_device_has_property (device->priv->d, "ID_CDROM_MEDIA_STATE")) + { + media_available = TRUE; + } + else + { + media_available = FALSE; + } } - for (l = removed_objpath; l != NULL; l = l->next) { - const gchar *objpath2 = l->data; - Device *device2; + } + else + { + media_available = TRUE; + } + device_set_device_is_media_available (device, media_available); + if (media_available) + { + if (device->priv->device_media_detection_time == 0) + device_set_device_media_detection_time (device, (guint64) time (NULL)); + } + else + { + device_set_device_media_detection_time (device, 0); + } - //g_debug ("### %s removed slave %s", device->priv->object_path, objpath2); - device2 = daemon_local_find_by_object_path (device->priv->daemon, objpath2); - if (device2 != NULL) { - update_info_in_idle (device2); - } else { - //g_debug ("### %s removed non-existant slave %s", device->priv->object_path, objpath2); - } + /* device_size, device_block_size and device_is_read_only properties */ + if (device->priv->device_is_media_available) + { + guint64 block_size; + + device_set_device_size (device, sysfs_get_uint64 (device->priv->native_path, "size") * ((guint64) 512)); + device_set_device_is_read_only (device, (sysfs_get_int (device->priv->native_path, "ro") != 0)); + /* This is not available on all devices so fall back to 512 if unavailable. + * + * Another way to get this information is the BLKSSZGET ioctl but we don't want + * to open the device. Ideally vol_id would export it. + */ + block_size = sysfs_get_uint64 (device->priv->native_path, "queue/hw_sector_size"); + if (block_size == 0) + block_size = 512; + device_set_device_block_size (device, block_size); + + } + else + { + device_set_device_size (device, 0); + device_set_device_block_size (device, 0); + device_set_device_is_read_only (device, FALSE); + } + + /* figure out if we're a partition and, if so, who our slave is */ + if (sysfs_file_exists (device->priv->native_path, "start")) + { + + /* we're partitioned by the kernel */ + device_set_device_is_partition (device, TRUE); + start = sysfs_get_uint64 (device->priv->native_path, "start"); + size = sysfs_get_uint64 (device->priv->native_path, "size"); + device_set_partition_offset (device, start * 512); /* device->priv->device_block_size; */ + device_set_partition_size (device, size * 512); /* device->priv->device_block_size; */ + + s = device->priv->native_path; + for (n = strlen (s) - 1; n >= 0 && g_ascii_isdigit (s[n]); n--) + ; + device_set_partition_number (device, strtol (s + n + 1, NULL, 0)); + + s = g_strdup (device->priv->native_path); + for (n = strlen (s) - 1; n >= 0 && s[n] != '/'; n--) + s[n] = '\0'; + s[n] = '\0'; + device_set_partition_slave (device, compute_object_path (s)); + g_free (s); + } + else + { + /* TODO: handle partitions created by kpartx / dm-linear */ + } + + /* Figure out if we are a partition table - we don't want to rely on udisks-part-id + * for this; it might not detect all partition table formats that the kernel supports. + * + * The kernel guarantees that all childs are created before the uevent for the parent + * is created. So if we have childs, we must be a partition table. + * + * To detect a child we check for the existance of a subdir that has the parents + * name as a prefix (e.g. for parent sda then sda1, sda2, sdap1 etc. will work). + */ + s = g_path_get_basename (device->priv->native_path); + if ((dir = g_dir_open (device->priv->native_path, 0, NULL)) != NULL) + { + guint partition_count; + partition_count = 0; + while ((name = g_dir_read_name (dir)) != NULL) + { + if (g_str_has_prefix (name, s)) + { + partition_count++; + } + } + g_dir_close (dir); + device_set_partition_table_count (device, partition_count); + device_set_device_is_partition_table (device, (partition_count > 0)); + } + g_free (s); + + /* Maintain (non-exported) properties holders and slaves for the holders resp. slaves + * directories in sysfs. The entries in these arrays are object paths - we ignore + * an entry unless it corresponds to an device in our local database. + */ + path = g_build_filename (device->priv->native_path, "slaves", NULL); + slaves = g_ptr_array_new (); + if ((dir = g_dir_open (path, 0, NULL)) != NULL) + { + while ((name = g_dir_read_name (dir)) != NULL) + { + Device *device2; + + s = compute_object_path (name); + + device2 = daemon_local_find_by_object_path (device->priv->daemon, s); + if (device2 != NULL) + { + //g_debug ("%s has slave %s", device->priv->object_path, s); + g_ptr_array_add (slaves, s); + } + else + { + //g_debug ("%s has non-existant slave %s", device->priv->object_path, s); + g_free (s); + } + } + g_dir_close (dir); + } + g_free (path); + g_ptr_array_sort (slaves, (GCompareFunc) ptr_str_array_compare); + g_ptr_array_add (slaves, NULL); + device_set_slaves_objpath (device, (GStrv) slaves->pdata); + g_ptr_array_foreach (slaves, (GFunc) g_free, NULL); + g_ptr_array_free (slaves, TRUE); + + path = g_build_filename (device->priv->native_path, "holders", NULL); + holders = g_ptr_array_new (); + if ((dir = g_dir_open (path, 0, NULL)) != NULL) + { + while ((name = g_dir_read_name (dir)) != NULL) + { + Device *device2; + + s = compute_object_path (name); + device2 = daemon_local_find_by_object_path (device->priv->daemon, s); + if (device2 != NULL) + { + //g_debug ("%s has holder %s", device->priv->object_path, s); + g_ptr_array_add (holders, s); + } + else + { + //g_debug ("%s has non-existant holder %s", device->priv->object_path, s); + g_free (s); + } + } + g_dir_close (dir); + } + g_free (path); + g_ptr_array_sort (holders, (GCompareFunc) ptr_str_array_compare); + g_ptr_array_add (holders, NULL); + device_set_holders_objpath (device, (GStrv) holders->pdata); + g_ptr_array_foreach (holders, (GFunc) g_free, NULL); + g_ptr_array_free (holders, TRUE); + + /* ------------------------------------- */ + /* Now set all properties from udev data */ + /* ------------------------------------- */ + + /* at this point we have + * + * - device_file + * - device_file_by_id + * - device_file_by_path + * - device_size + * - device_block_size + * - device_is_removable + * - device_is_read_only + * - device_is_drive + * - device_is_media_available + * - device_is_partition + * - device_is_partition_table + * - slaves_objpath + * - holders_objpath + * + * - partition_number + * - partition_slave + * + */ + + /* device_presentation_hide, device_presentation_name and device_presentation_icon_name properties */ + if (!update_info_presentation (device)) + goto out; + + /* id_* properties */ + if (!update_info_id (device)) + goto out; + + /* partition_table_* properties */ + if (!update_info_partition_table (device)) + goto out; + + /* partition_* properties */ + if (!update_info_partition (device)) + goto out; + + /* drive_* properties */ + if (!update_info_drive (device)) + goto out; + + /* device_is_optical_disc and optical_disc_* properties */ + if (!update_info_optical_disc (device)) + goto out; + + /* device_is_luks and luks_holder */ + if (!update_info_luks (device)) + goto out; + + /* device_is_luks_cleartext and luks_cleartext_* properties */ + if (!update_info_luks_cleartext (device)) + goto out; + + /* device_is_linux_md_component and linux_md_component_* properties */ + if (!update_info_linux_md_component (device)) + goto out; + + /* device_is_linux_md and linux_md_* properties */ + if (!update_info_linux_md (device)) + goto out; + + /* drive_ata_smart_* properties */ + if (!update_info_drive_ata_smart (device)) + goto out; + + /* drive_can_spindown property */ + if (!update_info_drive_can_spindown (device)) + goto out; + + /* device_is_system_internal property */ + if (!update_info_is_system_internal (device)) + goto out; + + /* device_is_mounted, device_mount, device_mounted_by_uid */ + if (!update_info_mount_state (device)) + goto out; + + /* device_is_media_change_detected, device_is_media_change_detection_* properties */ + if (!update_info_media_detection (device)) + goto out; + + /* drive_adapter proprety */ + if (!update_info_drive_adapter (device)) + goto out; + + /* drive_ports proprety */ + if (!update_info_drive_ports (device)) + goto out; + + ret = TRUE; + + out: + + /* Now check if holders/ or slaves/ has changed since last update. We compute + * the delta and do update_info() on each holder/slave that has been + * added/removed. + * + * Note that this won't trigger an endless loop since we look at the diffs. + * + * We have to do this because the kernel doesn't generate any 'change' event + * when slaves/ or holders/ change. This is unfortunate because we *need* such + * a change event to update properties devices (for example: luks_holder). + * + * We do the update in idle because the update may depend on the device + * currently being processed being added. + */ + + cur_slaves_objpath = dup_list_from_ptrarray (device->priv->slaves_objpath); + cur_holders_objpath = dup_list_from_ptrarray (device->priv->holders_objpath); + + old_slaves_objpath = g_list_sort (old_slaves_objpath, (GCompareFunc) g_strcmp0); + old_holders_objpath = g_list_sort (old_holders_objpath, (GCompareFunc) g_strcmp0); + cur_slaves_objpath = g_list_sort (cur_slaves_objpath, (GCompareFunc) g_strcmp0); + cur_holders_objpath = g_list_sort (cur_holders_objpath, (GCompareFunc) g_strcmp0); + + diff_sorted_lists (old_slaves_objpath, cur_slaves_objpath, (GCompareFunc) g_strcmp0, &added_objpath, &removed_objpath); + for (l = added_objpath; l != NULL; l = l->next) + { + const gchar *objpath2 = l->data; + Device *device2; + + //g_debug ("### %s added slave %s", device->priv->object_path, objpath2); + device2 = daemon_local_find_by_object_path (device->priv->daemon, objpath2); + if (device2 != NULL) + { + update_info_in_idle (device2); } - g_list_free (added_objpath); - g_list_free (removed_objpath); - - diff_sorted_lists (old_holders_objpath, cur_holders_objpath, - (GCompareFunc) g_strcmp0, - &added_objpath, &removed_objpath); - for (l = added_objpath; l != NULL; l = l->next) { - const gchar *objpath2 = l->data; - Device *device2; - - //g_debug ("### %s added holder %s", device->priv->object_path, objpath2); - device2 = daemon_local_find_by_object_path (device->priv->daemon, objpath2); - if (device2 != NULL) { - update_info_in_idle (device2); - } else { - g_print ("**** NOTE: %s added non-existant holder %s\n", device->priv->object_path, objpath2); - } + else + { + g_print ("**** NOTE: %s added non-existant slave %s\n", device->priv->object_path, objpath2); } - for (l = removed_objpath; l != NULL; l = l->next) { - const gchar *objpath2 = l->data; - Device *device2; + } + for (l = removed_objpath; l != NULL; l = l->next) + { + const gchar *objpath2 = l->data; + Device *device2; - //g_debug ("### %s removed holder %s", device->priv->object_path, objpath2); - device2 = daemon_local_find_by_object_path (device->priv->daemon, objpath2); - if (device2 != NULL) { - update_info_in_idle (device2); - } else { - //g_debug ("### %s removed non-existant holder %s", device->priv->object_path, objpath2); - } + //g_debug ("### %s removed slave %s", device->priv->object_path, objpath2); + device2 = daemon_local_find_by_object_path (device->priv->daemon, objpath2); + if (device2 != NULL) + { + update_info_in_idle (device2); + } + else + { + //g_debug ("### %s removed non-existant slave %s", device->priv->object_path, objpath2); + } + } + g_list_free (added_objpath); + g_list_free (removed_objpath); + + diff_sorted_lists (old_holders_objpath, + cur_holders_objpath, + (GCompareFunc) g_strcmp0, + &added_objpath, + &removed_objpath); + for (l = added_objpath; l != NULL; l = l->next) + { + const gchar *objpath2 = l->data; + Device *device2; + + //g_debug ("### %s added holder %s", device->priv->object_path, objpath2); + device2 = daemon_local_find_by_object_path (device->priv->daemon, objpath2); + if (device2 != NULL) + { + update_info_in_idle (device2); + } + else + { + g_print ("**** NOTE: %s added non-existant holder %s\n", device->priv->object_path, objpath2); + } + } + for (l = removed_objpath; l != NULL; l = l->next) + { + const gchar *objpath2 = l->data; + Device *device2; + + //g_debug ("### %s removed holder %s", device->priv->object_path, objpath2); + device2 = daemon_local_find_by_object_path (device->priv->daemon, objpath2); + if (device2 != NULL) + { + update_info_in_idle (device2); + } + else + { + //g_debug ("### %s removed non-existant holder %s", device->priv->object_path, objpath2); } - g_list_free (added_objpath); - g_list_free (removed_objpath); + } + g_list_free (added_objpath); + g_list_free (removed_objpath); - g_list_foreach (old_slaves_objpath, (GFunc) g_free, NULL); - g_list_free (old_slaves_objpath); - g_list_foreach (old_holders_objpath, (GFunc) g_free, NULL); - g_list_free (old_holders_objpath); - g_list_foreach (cur_slaves_objpath, (GFunc) g_free, NULL); - g_list_free (cur_slaves_objpath); - g_list_foreach (cur_holders_objpath, (GFunc) g_free, NULL); - g_list_free (cur_holders_objpath); + g_list_foreach (old_slaves_objpath, (GFunc) g_free, NULL); + g_list_free (old_slaves_objpath); + g_list_foreach (old_holders_objpath, (GFunc) g_free, NULL); + g_list_free (old_holders_objpath); + g_list_foreach (cur_slaves_objpath, (GFunc) g_free, NULL); + g_list_free (cur_slaves_objpath); + g_list_foreach (cur_holders_objpath, (GFunc) g_free, NULL); + g_list_free (cur_holders_objpath); - return ret; + return ret; } /** @@ -3500,71 +3912,69 @@ out: */ static gboolean device_local_is_busy (Device *device, - gboolean check_partitions, - GError **error) -{ - gboolean ret; - - ret = TRUE; - - /* busy if a job is pending */ - if (device->priv->job != NULL) { - g_set_error (error, ERROR, ERROR_BUSY, - "A job is pending on %s", device->priv->device_file); - goto out; - } - - /* or if we're mounted */ - if (device->priv->device_is_mounted) { - g_set_error (error, ERROR, ERROR_BUSY, - "%s is mounted", device->priv->device_file); - goto out; - } - - /* or if another block device is using/holding us (e.g. if holders/ is non-empty in sysfs) */ - if (device->priv->holders_objpath->len > 0) { - g_set_error (error, ERROR, ERROR_BUSY, - "One or more block devices are holding %s", device->priv->device_file); - goto out; - } - - /* If we are an extended partition, we are also busy if one or more logical partitions are busy - * even if @check_partitions is FALSE... This is because an extended partition only really is - * a place holder. - */ - if (g_strcmp0 (device->priv->partition_scheme, "mbr") == 0 && device->priv->partition_type != NULL) { - gint partition_type; - partition_type = strtol (device->priv->partition_type, NULL, 0); - if (partition_type == 0x05 || - partition_type == 0x0f || - partition_type == 0x85) { - Device *drive_device; - drive_device = daemon_local_find_by_object_path (device->priv->daemon, - device->priv->partition_slave); - if (device_local_logical_partitions_are_busy (drive_device)) { - g_set_error (error, ERROR, ERROR_BUSY, - "%s is an MS-DOS extended partition and one or more " - "logical partitions are busy", - device->priv->device_file); - goto out; - } - } - } + gboolean check_partitions, + GError **error) +{ + gboolean ret; + ret = TRUE; - /* if we are a partition table, we are busy if one of our partitions are busy */ - if (check_partitions && device->priv->device_is_partition_table) { - if (device_local_partitions_are_busy (device)) { - g_set_error (error, ERROR, ERROR_BUSY, - "One or more partitions are busy on %s", device->priv->device_file); - goto out; - } + /* busy if a job is pending */ + if (device->priv->job != NULL) + { + g_set_error (error, ERROR, ERROR_BUSY, "A job is pending on %s", device->priv->device_file); + goto out; + } + + /* or if we're mounted */ + if (device->priv->device_is_mounted) + { + g_set_error (error, ERROR, ERROR_BUSY, "%s is mounted", device->priv->device_file); + goto out; + } + + /* or if another block device is using/holding us (e.g. if holders/ is non-empty in sysfs) */ + if (device->priv->holders_objpath->len > 0) + { + g_set_error (error, ERROR, ERROR_BUSY, "One or more block devices are holding %s", device->priv->device_file); + goto out; + } + + /* If we are an extended partition, we are also busy if one or more logical partitions are busy + * even if @check_partitions is FALSE... This is because an extended partition only really is + * a place holder. + */ + if (g_strcmp0 (device->priv->partition_scheme, "mbr") == 0 && device->priv->partition_type != NULL) + { + gint partition_type; + partition_type = strtol (device->priv->partition_type, NULL, 0); + if (partition_type == 0x05 || partition_type == 0x0f || partition_type == 0x85) + { + Device *drive_device; + drive_device = daemon_local_find_by_object_path (device->priv->daemon, device->priv->partition_slave); + if (device_local_logical_partitions_are_busy (drive_device)) + { + g_set_error (error, ERROR, ERROR_BUSY, "%s is an MS-DOS extended partition and one or more " + "logical partitions are busy", device->priv->device_file); + goto out; + } + } + } + + /* if we are a partition table, we are busy if one of our partitions are busy */ + if (check_partitions && device->priv->device_is_partition_table) + { + if (device_local_partitions_are_busy (device)) + { + g_set_error (error, ERROR, ERROR_BUSY, "One or more partitions are busy on %s", device->priv->device_file); + goto out; } + } - ret = FALSE; + ret = FALSE; -out: - return ret; + out: + return ret; } /* note: this only checks whether the actual partitions are busy; @@ -3573,294 +3983,314 @@ out: static gboolean device_local_partitions_are_busy (Device *device) { - gboolean ret; - GList *l; - GList *devices; + gboolean ret; + GList *l; + GList *devices; - ret = FALSE; + ret = FALSE; - devices = daemon_local_get_all_devices (device->priv->daemon); - for (l = devices; l != NULL; l = l->next) { - Device *d = DEVICE (l->data); + devices = daemon_local_get_all_devices (device->priv->daemon); + for (l = devices; l != NULL; l = l->next) + { + Device *d = DEVICE (l->data); - if (d->priv->device_is_partition && - d->priv->partition_slave != NULL && - g_strcmp0 (d->priv->partition_slave, device->priv->object_path) == 0) { + if (d->priv->device_is_partition && d->priv->partition_slave != NULL && g_strcmp0 (d->priv->partition_slave, + device->priv->object_path) + == 0) + { - if (device_local_is_busy (d, FALSE, NULL)) { - ret = TRUE; - break; - } - } + if (device_local_is_busy (d, FALSE, NULL)) + { + ret = TRUE; + break; + } } + } - g_list_free (devices); + g_list_free (devices); - return ret; + return ret; } static gboolean device_local_logical_partitions_are_busy (Device *device) { - gboolean ret; - GList *l; - GList *devices; + gboolean ret; + GList *l; + GList *devices; - ret = FALSE; + ret = FALSE; - devices = daemon_local_get_all_devices (device->priv->daemon); - for (l = devices; l != NULL; l = l->next) { - Device *d = DEVICE (l->data); + devices = daemon_local_get_all_devices (device->priv->daemon); + for (l = devices; l != NULL; l = l->next) + { + Device *d = DEVICE (l->data); - if (d->priv->device_is_partition && - d->priv->partition_slave != NULL && - g_strcmp0 (d->priv->partition_slave, device->priv->object_path) == 0 && - g_strcmp0 (d->priv->partition_scheme, "mbr") == 0 && - d->priv->partition_number >= 5) { + if (d->priv->device_is_partition && d->priv->partition_slave != NULL && g_strcmp0 (d->priv->partition_slave, + device->priv->object_path) + == 0 && g_strcmp0 (d->priv->partition_scheme, "mbr") == 0 && d->priv->partition_number >= 5) + { - if (device_local_is_busy (d, FALSE, NULL)) { - ret = TRUE; - break; - } - } + if (device_local_is_busy (d, FALSE, NULL)) + { + ret = TRUE; + break; + } } + } - g_list_free (devices); + g_list_free (devices); - return ret; + return ret; } static gboolean device_has_logical_partitions (Device *device) { - gboolean ret; - GList *l; - GList *devices; + gboolean ret; + GList *l; + GList *devices; - ret = FALSE; + ret = FALSE; - devices = daemon_local_get_all_devices (device->priv->daemon); - for (l = devices; l != NULL; l = l->next) { - Device *d = DEVICE (l->data); + devices = daemon_local_get_all_devices (device->priv->daemon); + for (l = devices; l != NULL; l = l->next) + { + Device *d = DEVICE (l->data); - if (d->priv->device_is_partition && - d->priv->partition_slave != NULL && - g_strcmp0 (d->priv->partition_slave, device->priv->object_path) == 0 && - g_strcmp0 (d->priv->partition_scheme, "mbr") == 0 && - d->priv->partition_number >= 5) { + if (d->priv->device_is_partition && d->priv->partition_slave != NULL && g_strcmp0 (d->priv->partition_slave, + device->priv->object_path) + == 0 && g_strcmp0 (d->priv->partition_scheme, "mbr") == 0 && d->priv->partition_number >= 5) + { - ret = TRUE; - } + ret = TRUE; } + } - g_list_free (devices); + g_list_free (devices); - return ret; + return ret; } void device_removed (Device *device) { - guint n; + guint n; - device->priv->removed = TRUE; + device->priv->removed = TRUE; - dbus_g_connection_unregister_g_object (device->priv->system_bus_connection, - G_OBJECT (device)); - g_assert (dbus_g_connection_lookup_g_object (device->priv->system_bus_connection, - device->priv->object_path) == NULL); + dbus_g_connection_unregister_g_object (device->priv->system_bus_connection, G_OBJECT (device)); + g_assert (dbus_g_connection_lookup_g_object (device->priv->system_bus_connection, device->priv->object_path) == NULL); - /* device is now removed; update all slaves and holders */ - for (n = 0; n < device->priv->slaves_objpath->len; n++) { - const gchar *objpath2 = ((gchar **) device->priv->slaves_objpath->pdata)[n]; - Device *device2; + /* device is now removed; update all slaves and holders */ + for (n = 0; n < device->priv->slaves_objpath->len; n++) + { + const gchar *objpath2 = ((gchar **) device->priv->slaves_objpath->pdata)[n]; + Device *device2; - device2 = daemon_local_find_by_object_path (device->priv->daemon, objpath2); - if (device2 != NULL) { - update_info (device2); - } + device2 = daemon_local_find_by_object_path (device->priv->daemon, objpath2); + if (device2 != NULL) + { + update_info (device2); } - for (n = 0; n < device->priv->holders_objpath->len; n++) { - const gchar *objpath2 = ((gchar **) device->priv->holders_objpath->pdata)[n]; - Device *device2; + } + for (n = 0; n < device->priv->holders_objpath->len; n++) + { + const gchar *objpath2 = ((gchar **) device->priv->holders_objpath->pdata)[n]; + Device *device2; - device2 = daemon_local_find_by_object_path (device->priv->daemon, objpath2); - if (device2 != NULL) { - update_info (device2); - } + device2 = daemon_local_find_by_object_path (device->priv->daemon, objpath2); + if (device2 != NULL) + { + update_info (device2); } + } - /* If the device is busy, we possibly need to clean up if the - * device itself is busy. This includes - * - * - force unmounting the device and/or all it's partitions - * - * - tearing down a luks mapping if it's a cleartext device - * backed by a crypted device - * - * but see force_removal() for details. - * - * This is the normally the path where the enclosing device is - * removed. Compare with device_changed() for the - * other path. - */ - force_removal (device, NULL, NULL); + /* If the device is busy, we possibly need to clean up if the + * device itself is busy. This includes + * + * - force unmounting the device and/or all it's partitions + * + * - tearing down a luks mapping if it's a cleartext device + * backed by a crypted device + * + * but see force_removal() for details. + * + * This is the normally the path where the enclosing device is + * removed. Compare with device_changed() for the + * other path. + */ + force_removal (device, NULL, NULL); } Device * -device_new (Daemon *daemon, GUdevDevice *d) +device_new (Daemon *daemon, + GUdevDevice *d) { - Device *device; - const char *native_path; + Device *device; + const char *native_path; - device = NULL; - native_path = g_udev_device_get_sysfs_path (d); + device = NULL; + native_path = g_udev_device_get_sysfs_path (d); - /* ignore ram and loop devices */ - if (g_str_has_prefix (native_path, "/sys/devices/virtual/block/ram") || - g_str_has_prefix (native_path, "/sys/devices/virtual/block/loop")) - goto out; + /* ignore ram and loop devices */ + if (g_str_has_prefix (native_path, "/sys/devices/virtual/block/ram") + || g_str_has_prefix (native_path, "/sys/devices/virtual/block/loop")) + goto out; - device = DEVICE (g_object_new (TYPE_DEVICE, NULL)); - device->priv->d = g_object_ref (d); - device->priv->daemon = g_object_ref (daemon); - device->priv->native_path = g_strdup (native_path); + device = DEVICE (g_object_new (TYPE_DEVICE, NULL)); + device->priv->d = g_object_ref (d); + device->priv->daemon = g_object_ref (daemon); + device->priv->native_path = g_strdup (native_path); - /* TODO: we might want to get this from udev or the kernel... to get the time when the device - * was initially detected... as opposed to this value which is when the device was detected - * by our daemon... but this will do for now... - */ - device->priv->device_detection_time = (guint64) time (NULL); + /* TODO: we might want to get this from udev or the kernel... to get the time when the device + * was initially detected... as opposed to this value which is when the device was detected + * by our daemon... but this will do for now... + */ + device->priv->device_detection_time = (guint64) time (NULL); - if (!update_info (device)) { - g_object_unref (device); - device = NULL; - goto out; - } + if (!update_info (device)) + { + g_object_unref (device); + device = NULL; + goto out; + } - if (!register_disks_device (DEVICE (device))) { - g_object_unref (device); - device = NULL; - goto out; - } + if (!register_disks_device (DEVICE (device))) + { + g_object_unref (device); + device = NULL; + goto out; + } - /* if just added, update the smart data if applicable */ - if (device->priv->drive_ata_smart_is_available) { - gchar *ata_smart_refresh_data_options[] = {NULL}; - device_drive_ata_smart_refresh_data (device, - ata_smart_refresh_data_options, - NULL); - } + /* if just added, update the smart data if applicable */ + if (device->priv->drive_ata_smart_is_available) + { + gchar *ata_smart_refresh_data_options[] = { NULL }; + device_drive_ata_smart_refresh_data (device, ata_smart_refresh_data_options, NULL); + } -out: - return device; + out: + return device; } static void -drain_pending_changes (Device *device, gboolean force_update) +drain_pending_changes (Device *device, + gboolean force_update) { - gboolean emit_changed; + gboolean emit_changed; - emit_changed = FALSE; - - /* the update-in-idle is set up if, and only if, there are pending changes - so - * we should emit a 'change' event only if it is set up - */ - if (device->priv->emit_changed_idle_id != 0) { - g_source_remove (device->priv->emit_changed_idle_id); - device->priv->emit_changed_idle_id = 0; - emit_changed = TRUE; - } + emit_changed = FALSE; - if ((!device->priv->removed) && (emit_changed || force_update)) { - if (device->priv->object_path != NULL) { - g_print ("**** EMITTING CHANGED for %s\n", device->priv->native_path); - g_signal_emit_by_name (device, "changed"); - g_signal_emit_by_name (device->priv->daemon, "device-changed", device->priv->object_path); - } + /* the update-in-idle is set up if, and only if, there are pending changes - so + * we should emit a 'change' event only if it is set up + */ + if (device->priv->emit_changed_idle_id != 0) + { + g_source_remove (device->priv->emit_changed_idle_id); + device->priv->emit_changed_idle_id = 0; + emit_changed = TRUE; + } + + if ((!device->priv->removed) && (emit_changed || force_update)) + { + if (device->priv->object_path != NULL) + { + g_print ("**** EMITTING CHANGED for %s\n", device->priv->native_path); + g_signal_emit_by_name (device, "changed"); + g_signal_emit_by_name (device->priv->daemon, "device-changed", device->priv->object_path); } + } } static void emit_job_changed (Device *device) { - drain_pending_changes (device, FALSE); + drain_pending_changes (device, FALSE); - if (!device->priv->removed) { - g_print ("**** EMITTING JOB-CHANGED for %s\n", device->priv->native_path); - g_signal_emit_by_name (device->priv->daemon, - "device-job-changed", - device->priv->object_path, - device->priv->job_in_progress, - device->priv->job_id, - device->priv->job_initiated_by_uid, - device->priv->job_is_cancellable, - device->priv->job_percentage, - NULL); - g_signal_emit (device, signals[JOB_CHANGED_SIGNAL], 0, - device->priv->job_in_progress, - device->priv->job_id, - device->priv->job_initiated_by_uid, - device->priv->job_is_cancellable, - device->priv->job_percentage); - } + if (!device->priv->removed) + { + g_print ("**** EMITTING JOB-CHANGED for %s\n", device->priv->native_path); + g_signal_emit_by_name (device->priv->daemon, + "device-job-changed", + device->priv->object_path, + device->priv->job_in_progress, + device->priv->job_id, + device->priv->job_initiated_by_uid, + device->priv->job_is_cancellable, + device->priv->job_percentage, + NULL); + g_signal_emit (device, + signals[JOB_CHANGED_SIGNAL], + 0, + device->priv->job_in_progress, + device->priv->job_id, + device->priv->job_initiated_by_uid, + device->priv->job_is_cancellable, + device->priv->job_percentage); + } } /* called by the daemon on the 'change' uevent */ gboolean -device_changed (Device *device, GUdevDevice *d, gboolean synthesized) -{ - gboolean keep_device; - - g_object_unref (device->priv->d); - device->priv->d = g_object_ref (d); - - keep_device = update_info (device); - - /* this 'change' event might prompt us to remove the device */ - if (!keep_device) - goto out; - - /* no, it's good .. keep it.. and always force a 'change' signal if the event isn't synthesized */ - drain_pending_changes (device, !synthesized); - - /* Check if media was removed. If so, we possibly need to clean up - * if the device itself is busy. This includes - * - * - force unmounting the device - * - * - tearing down a luks mapping if it's a cleartext device - * backed by a crypted device - * - * but see force_removal() for details. - * - * This is the normally the path where the media is removed but the enclosing - * device is still present. Compare with device_removed() for - * the other path. - */ - if (!device->priv->device_is_media_available) { - GList *l; - GList *devices; - - force_removal (device, NULL, NULL); - - /* check all partitions */ - devices = daemon_local_get_all_devices (device->priv->daemon); - for (l = devices; l != NULL; l = l->next) { - Device *d = DEVICE (l->data); - - if (d->priv->device_is_partition && - d->priv->partition_slave != NULL && - strcmp (d->priv->partition_slave, device->priv->object_path) == 0) { - - force_removal (d, NULL, NULL); - } - } +device_changed (Device *device, + GUdevDevice *d, + gboolean synthesized) +{ + gboolean keep_device; + + g_object_unref (device->priv->d); + device->priv->d = g_object_ref (d); + + keep_device = update_info (device); + + /* this 'change' event might prompt us to remove the device */ + if (!keep_device) + goto out; + + /* no, it's good .. keep it.. and always force a 'change' signal if the event isn't synthesized */ + drain_pending_changes (device, !synthesized); + + /* Check if media was removed. If so, we possibly need to clean up + * if the device itself is busy. This includes + * + * - force unmounting the device + * + * - tearing down a luks mapping if it's a cleartext device + * backed by a crypted device + * + * but see force_removal() for details. + * + * This is the normally the path where the media is removed but the enclosing + * device is still present. Compare with device_removed() for + * the other path. + */ + if (!device->priv->device_is_media_available) + { + GList *l; + GList *devices; + + force_removal (device, NULL, NULL); + + /* check all partitions */ + devices = daemon_local_get_all_devices (device->priv->daemon); + for (l = devices; l != NULL; l = l->next) + { + Device *d = DEVICE (l->data); - g_list_free (devices); + if (d->priv->device_is_partition && d->priv->partition_slave != NULL && strcmp (d->priv->partition_slave, + device->priv->object_path) + == 0) + { + + force_removal (d, NULL, NULL); + } } -out: - return keep_device; + + g_list_free (devices); + } + out: + return keep_device; } /*--------------------------------------------------------------------------------------------------------------*/ @@ -3868,221 +4298,237 @@ out: const char * device_local_get_object_path (Device *device) { - return device->priv->object_path; + return device->priv->object_path; } const char * device_local_get_native_path (Device *device) { - return device->priv->native_path; + return device->priv->native_path; } dev_t device_local_get_dev (Device *device) { - return device->priv->dev; + return device->priv->dev; } const char * device_local_get_device_file (Device *device) { - return device->priv->device_file; + return device->priv->device_file; } /*--------------------------------------------------------------------------------------------------------------*/ static gboolean -throw_error (DBusGMethodInvocation *context, int error_code, const char *format, ...) +throw_error (DBusGMethodInvocation *context, + int error_code, + const char *format, + ...) { - GError *error; - va_list args; - char *message; + GError *error; + va_list args; + char *message; - if (context == NULL) - return TRUE; + if (context == NULL) + return TRUE; - va_start (args, format); - message = g_strdup_vprintf (format, args); - va_end (args); + va_start (args, format); + message = g_strdup_vprintf (format, args); + va_end (args); - error = g_error_new (ERROR, - error_code, - "%s", message); - dbus_g_method_return_error (context, error); - g_error_free (error); - g_free (message); - return TRUE; + error = g_error_new (ERROR, error_code, "%s", message); + dbus_g_method_return_error (context, error); + g_error_free (error); + g_free (message); + return TRUE; } /*--------------------------------------------------------------------------------------------------------------*/ -typedef void (*JobCompletedFunc) (DBusGMethodInvocation *context, - Device *device, - gboolean was_cancelled, - int status, - const char *stderr, - const char *stdout, - gpointer user_data); - -struct Job { - char *job_id; - - Device *device; - DBusGMethodInvocation *context; - JobCompletedFunc job_completed_func; - GPid pid; - gpointer user_data; - GDestroyNotify user_data_destroy_func; - gboolean was_cancelled; - gboolean udev_settle; - int status; - - int stderr_fd; - GIOChannel *error_channel; - guint error_channel_source_id; - GString *error_string; - - int stdout_fd; - GIOChannel *out_channel; - guint out_channel_source_id; - GString *stdout_string; - int stdout_string_cursor; - - char *stdin_str; - char *stdin_cursor; - int stdin_fd; - GIOChannel *in_channel; - guint in_channel_source_id; +typedef void +(*JobCompletedFunc) (DBusGMethodInvocation *context, + Device *device, + gboolean was_cancelled, + int status, + const char *stderr, + const char *stdout, + gpointer user_data); + +struct Job +{ + char *job_id; + + Device *device; + DBusGMethodInvocation *context; + JobCompletedFunc job_completed_func; + GPid pid; + gpointer user_data; + GDestroyNotify user_data_destroy_func; + gboolean was_cancelled; + gboolean udev_settle; + int status; + + int stderr_fd; + GIOChannel *error_channel; + guint error_channel_source_id; + GString *error_string; + + int stdout_fd; + GIOChannel *out_channel; + guint out_channel_source_id; + GString *stdout_string; + int stdout_string_cursor; + + char *stdin_str; + char *stdin_cursor; + int stdin_fd; + GIOChannel *in_channel; + guint in_channel_source_id; }; static void job_free (Job *job) { - if (job->user_data_destroy_func != NULL) - job->user_data_destroy_func (job->user_data); - if (job->device != NULL) - g_object_unref (job->device); - if (job->stderr_fd >= 0) - close (job->stderr_fd); - if (job->stdout_fd >= 0) - close (job->stdout_fd); - if (job->stdin_fd >= 0) { - close (job->stdin_fd); - g_source_remove (job->in_channel_source_id); - g_io_channel_unref (job->in_channel); - } - g_source_remove (job->error_channel_source_id); - g_source_remove (job->out_channel_source_id); - g_io_channel_unref (job->error_channel); - g_io_channel_unref (job->out_channel); - g_string_free (job->error_string, TRUE); - /* scrub stdin (may contain secrets) */ - if (job->stdin_str != NULL) { - memset (job->stdin_str, '\0', strlen (job->stdin_str)); - } - g_string_free (job->stdout_string, TRUE); - g_free (job->stdin_str); - g_free (job->job_id); - g_free (job); + if (job->user_data_destroy_func != NULL) + job->user_data_destroy_func (job->user_data); + if (job->device != NULL) + g_object_unref (job->device); + if (job->stderr_fd >= 0) + close (job->stderr_fd); + if (job->stdout_fd >= 0) + close (job->stdout_fd); + if (job->stdin_fd >= 0) + { + close (job->stdin_fd); + g_source_remove (job->in_channel_source_id); + g_io_channel_unref (job->in_channel); + } + g_source_remove (job->error_channel_source_id); + g_source_remove (job->out_channel_source_id); + g_io_channel_unref (job->error_channel); + g_io_channel_unref (job->out_channel); + g_string_free (job->error_string, TRUE); + /* scrub stdin (may contain secrets) */ + if (job->stdin_str != NULL) + { + memset (job->stdin_str, '\0', strlen (job->stdin_str)); + } + g_string_free (job->stdout_string, TRUE); + g_free (job->stdin_str); + g_free (job->job_id); + g_free (job); } static void job_complete (Job *job) { - if (job->device != NULL && job->job_id != NULL) { - job->device->priv->job_in_progress = FALSE; - g_free (job->device->priv->job_id); - job->device->priv->job_id = NULL; - job->device->priv->job_initiated_by_uid = 0; - job->device->priv->job_is_cancellable = FALSE; - job->device->priv->job_percentage = -1.0; - - job->device->priv->job = NULL; - } + if (job->device != NULL && job->job_id != NULL) + { + job->device->priv->job_in_progress = FALSE; + g_free (job->device->priv->job_id); + job->device->priv->job_id = NULL; + job->device->priv->job_initiated_by_uid = 0; + job->device->priv->job_is_cancellable = FALSE; + job->device->priv->job_percentage = -1.0; + + job->device->priv->job = NULL; + } - job->job_completed_func (job->context, - job->device, - job->was_cancelled, - job->status, - job->error_string->str, - job->stdout_string->str, - job->user_data); + job->job_completed_func (job->context, + job->device, + job->was_cancelled, + job->status, + job->error_string->str, + job->stdout_string->str, + job->user_data); - if (job->device != NULL && job->job_id != NULL) { - emit_job_changed (job->device); - } + if (job->device != NULL && job->job_id != NULL) + { + emit_job_changed (job->device); + } - job_free (job); + job_free (job); } static void -job_udevadm_settle_child_cb (GPid pid, - gint status, +job_udevadm_settle_child_cb (GPid pid, + gint status, gpointer user_data) { - Job *job = user_data; - job_complete (job); + Job *job = user_data; + job_complete (job); } static void -job_child_watch_cb (GPid pid, int status, gpointer user_data) -{ - char *buf; - gsize buf_size; - Job *job = user_data; - - if (g_io_channel_read_to_end (job->error_channel, &buf, &buf_size, NULL) == G_IO_STATUS_NORMAL) { - g_string_append_len (job->error_string, buf, buf_size); - g_free (buf); - } - if (g_io_channel_read_to_end (job->out_channel, &buf, &buf_size, NULL) == G_IO_STATUS_NORMAL) { - g_string_append_len (job->stdout_string, buf, buf_size); - g_free (buf); - } - - g_print ("helper(pid %5d): completed with exit code %d\n", job->pid, WEXITSTATUS (status)); - - job->status = status; - - /* if requested, run 'udevadm settle' on success */ - if (!job->was_cancelled && WIFEXITED (status) && WEXITSTATUS (status) == 0 && job->udev_settle) { - GError *error; - gchar *argv[] = {"udevadm", "settle", "--quiet", NULL}; - GPid udevadm_pid; - - error = NULL; - if (!g_spawn_async (NULL, - argv, - NULL, - G_SPAWN_SEARCH_PATH | G_SPAWN_DO_NOT_REAP_CHILD, - NULL, - NULL, - &udevadm_pid, - &error)) { - g_warning ("Error running 'udevadm settle --quiet': %s", error->message); - g_error_free (error); - - job_complete (job); - } else { - g_child_watch_add (udevadm_pid, - job_udevadm_settle_child_cb, - job); - } - } else { - /* return immediately on error */ - job_complete (job); +job_child_watch_cb (GPid pid, + int status, + gpointer user_data) +{ + char *buf; + gsize buf_size; + Job *job = user_data; + + if (g_io_channel_read_to_end (job->error_channel, &buf, &buf_size, NULL) == G_IO_STATUS_NORMAL) + { + g_string_append_len (job->error_string, buf, buf_size); + g_free (buf); + } + if (g_io_channel_read_to_end (job->out_channel, &buf, &buf_size, NULL) == G_IO_STATUS_NORMAL) + { + g_string_append_len (job->stdout_string, buf, buf_size); + g_free (buf); + } + + g_print ("helper(pid %5d): completed with exit code %d\n", job->pid, WEXITSTATUS (status)); + + job->status = status; + + /* if requested, run 'udevadm settle' on success */ + if (!job->was_cancelled && WIFEXITED (status) && WEXITSTATUS (status) == 0 && job->udev_settle) + { + GError *error; + gchar *argv[] = + { "udevadm", "settle", "--quiet", NULL }; + GPid udevadm_pid; + + error = NULL; + if (!g_spawn_async (NULL, + argv, + NULL, + G_SPAWN_SEARCH_PATH | G_SPAWN_DO_NOT_REAP_CHILD, + NULL, + NULL, + &udevadm_pid, + &error)) + { + g_warning ("Error running 'udevadm settle --quiet': %s", error->message); + g_error_free (error); + + job_complete (job); } + else + { + g_child_watch_add (udevadm_pid, job_udevadm_settle_child_cb, job); + } + } + else + { + /* return immediately on error */ + job_complete (job); + } } static void job_cancel (Device *device) { - g_return_if_fail (device->priv->job != NULL); + g_return_if_fail (device->priv->job != NULL); - device->priv->job->was_cancelled = TRUE; + device->priv->job->was_cancelled = TRUE; - /* TODO: maybe wait and user a bigger hammer? (SIGKILL) */ - kill (device->priv->job->pid, SIGTERM); + /* TODO: maybe wait and user a bigger hammer? (SIGKILL) */ + kill (device->priv->job->pid, SIGTERM); } static gboolean @@ -4090,13 +4536,13 @@ job_read_error (GIOChannel *channel, GIOCondition condition, gpointer user_data) { - char buf[1024]; - gsize bytes_read; - Job *job = user_data; + char buf[1024]; + gsize bytes_read; + Job *job = user_data; - g_io_channel_read_chars (channel, buf, sizeof buf, &bytes_read, NULL); - g_string_append_len (job->error_string, buf, bytes_read); - return TRUE; + g_io_channel_read_chars (channel, buf, sizeof buf, &bytes_read, NULL); + g_string_append_len (job->error_string, buf, bytes_read); + return TRUE; } static gboolean @@ -4104,19 +4550,19 @@ job_write_in (GIOChannel *channel, GIOCondition condition, gpointer user_data) { - Job *job = user_data; - gsize bytes_written; + Job *job = user_data; + gsize bytes_written; - if (job->stdin_cursor == NULL || job->stdin_cursor[0] == '\0') { - /* nothing left to write; remove ourselves */ - return FALSE; - } + if (job->stdin_cursor == NULL || job->stdin_cursor[0] == '\0') + { + /* nothing left to write; remove ourselves */ + return FALSE; + } - g_io_channel_write_chars (channel, job->stdin_cursor, strlen (job->stdin_cursor), - &bytes_written, NULL); - g_io_channel_flush (channel, NULL); - job->stdin_cursor += bytes_written; - return TRUE; + g_io_channel_write_chars (channel, job->stdin_cursor, strlen (job->stdin_cursor), &bytes_written, NULL); + g_io_channel_flush (channel, NULL); + job->stdin_cursor += bytes_written; + return TRUE; } static gboolean @@ -4124,460 +4570,450 @@ job_read_out (GIOChannel *channel, GIOCondition condition, gpointer user_data) { - char *s; - char *line; - char buf[1024]; - gsize bytes_read; - Job *job = user_data; + char *s; + char *line; + char buf[1024]; + gsize bytes_read; + Job *job = user_data; - g_io_channel_read_chars (channel, buf, sizeof buf, &bytes_read, NULL); - g_string_append_len (job->stdout_string, buf, bytes_read); + g_io_channel_read_chars (channel, buf, sizeof buf, &bytes_read, NULL); + g_string_append_len (job->stdout_string, buf, bytes_read); - do { - gsize line_len; + do + { + gsize line_len; - s = strstr (job->stdout_string->str + job->stdout_string_cursor, "\n"); - if (s == NULL) - break; + s = strstr (job->stdout_string->str + job->stdout_string_cursor, "\n"); + if (s == NULL) + break; - line_len = s - (job->stdout_string->str + job->stdout_string_cursor); - line = g_strndup (job->stdout_string->str + job->stdout_string_cursor, line_len); - job->stdout_string_cursor += line_len + 1; + line_len = s - (job->stdout_string->str + job->stdout_string_cursor); + line = g_strndup (job->stdout_string->str + job->stdout_string_cursor, line_len); + job->stdout_string_cursor += line_len + 1; - //g_print ("helper(pid %5d): '%s'\n", job->pid, line); + //g_print ("helper(pid %5d): '%s'\n", job->pid, line); - if (strlen (line) < 256) { - double cur_percentage;; + if (strlen (line) < 256) + { + double cur_percentage; + ; - if (sscanf (line, "udisks-helper-progress: %lg", &cur_percentage) == 1) { - if (job->device != NULL && job->job_id != NULL) { - job->device->priv->job_percentage = cur_percentage; - emit_job_changed (job->device); - } - } + if (sscanf (line, "udisks-helper-progress: %lg", &cur_percentage) == 1) + { + if (job->device != NULL && job->job_id != NULL) + { + job->device->priv->job_percentage = cur_percentage; + emit_job_changed (job->device); } + } + } - g_free (line); - } while (TRUE); + g_free (line); + } + while (TRUE); - return TRUE; + return TRUE; } static void job_local_start (Device *device, const char *job_id) { - if (device->priv->job != NULL || device->priv->job_in_progress) { - g_warning ("There is already a job running"); - goto out; - } + if (device->priv->job != NULL || device->priv->job_in_progress) + { + g_warning ("There is already a job running"); + goto out; + } - g_free (device->priv->job_id); - device->priv->job_id = g_strdup (job_id); - device->priv->job_initiated_by_uid = 0; - device->priv->job_in_progress = TRUE; - device->priv->job_is_cancellable = FALSE; - device->priv->job_percentage = -1.0; + g_free (device->priv->job_id); + device->priv->job_id = g_strdup (job_id); + device->priv->job_initiated_by_uid = 0; + device->priv->job_in_progress = TRUE; + device->priv->job_is_cancellable = FALSE; + device->priv->job_percentage = -1.0; - emit_job_changed (device); -out: - ; + emit_job_changed (device); + out: + ; } static void job_local_end (Device *device) { - if (!device->priv->job_in_progress || device->priv->job != NULL) { - g_warning ("There is no job running"); - goto out; - } + if (!device->priv->job_in_progress || device->priv->job != NULL) + { + g_warning ("There is no job running"); + goto out; + } - device->priv->job_in_progress = FALSE; - g_free (device->priv->job_id); - device->priv->job_id = NULL; - device->priv->job_initiated_by_uid = 0; - device->priv->job_is_cancellable = FALSE; - device->priv->job_percentage = -1.0; - emit_job_changed (device); -out: - ; + device->priv->job_in_progress = FALSE; + g_free (device->priv->job_id); + device->priv->job_id = NULL; + device->priv->job_initiated_by_uid = 0; + device->priv->job_is_cancellable = FALSE; + device->priv->job_percentage = -1.0; + emit_job_changed (device); + out: + ; } static gboolean job_new (DBusGMethodInvocation *context, - const char *job_id, - gboolean is_cancellable, - Device *device, - char **argv, - const char *stdin_str, - JobCompletedFunc job_completed_func, - gboolean udev_settle, /* if TRUE, runs udevsettle before returning if the command succeeded */ - gpointer user_data, - GDestroyNotify user_data_destroy_func) -{ - Job *job; - gboolean ret; - GError *error; - - ret = FALSE; - job = NULL; - - if (device != NULL) { - if (device->priv->job != NULL || device->priv->job_in_progress) { - throw_error (context, - ERROR_BUSY, - "There is already a job running"); - goto out; - } + const char *job_id, + gboolean is_cancellable, + Device *device, + char **argv, + const char *stdin_str, + JobCompletedFunc job_completed_func, + gboolean udev_settle, /* if TRUE, runs udevsettle before returning if the command succeeded */ + gpointer user_data, + GDestroyNotify user_data_destroy_func) +{ + Job *job; + gboolean ret; + GError *error; + + ret = FALSE; + job = NULL; + + if (device != NULL) + { + if (device->priv->job != NULL || device->priv->job_in_progress) + { + throw_error (context, ERROR_BUSY, "There is already a job running"); + goto out; } + } - job = g_new0 (Job, 1); - job->context = context; - job->device = device != NULL ? DEVICE (g_object_ref (device)) : NULL; - job->job_completed_func = job_completed_func; - job->user_data = user_data; - job->user_data_destroy_func = user_data_destroy_func; - job->stderr_fd = -1; - job->stdout_fd = -1; - job->stdin_fd = -1; - job->stdin_str = g_strdup (stdin_str); - job->stdin_cursor = job->stdin_str; - job->stdout_string = g_string_sized_new (1024); - job->job_id = g_strdup (job_id); - job->udev_settle = udev_settle; - - if (device != NULL && job_id != NULL) { - g_free (job->device->priv->job_id); - job->device->priv->job_id = g_strdup (job_id); - } - - error = NULL; - if (!g_spawn_async_with_pipes (NULL, - argv, - NULL, - G_SPAWN_SEARCH_PATH | G_SPAWN_DO_NOT_REAP_CHILD, - NULL, - NULL, - &(job->pid), - stdin_str != NULL ? &(job->stdin_fd) : NULL, - &(job->stdout_fd), - &(job->stderr_fd), - &error)) { - throw_error (context, ERROR_FAILED, "Error starting job: %s", error->message); - g_error_free (error); - goto out; - } - - g_child_watch_add (job->pid, job_child_watch_cb, job); - - job->error_string = g_string_new (""); - job->error_channel = g_io_channel_unix_new (job->stderr_fd); - error = NULL; - if (g_io_channel_set_flags (job->error_channel, G_IO_FLAG_NONBLOCK, &error) != G_IO_STATUS_NORMAL) { - g_warning ("Cannon set stderr fd for child to be non blocking: %s", error->message); - g_error_free (error); - } - job->error_channel_source_id = g_io_add_watch (job->error_channel, G_IO_IN, job_read_error, job); - - job->out_channel = g_io_channel_unix_new (job->stdout_fd); - error = NULL; - if (g_io_channel_set_flags (job->out_channel, G_IO_FLAG_NONBLOCK, &error) != G_IO_STATUS_NORMAL) { - g_warning ("Cannon set stdout fd for child to be non blocking: %s", error->message); - g_error_free (error); - } - job->out_channel_source_id = g_io_add_watch (job->out_channel, G_IO_IN, job_read_out, job); - - if (job->stdin_fd >= 0) { - job->in_channel = g_io_channel_unix_new (job->stdin_fd); - if (g_io_channel_set_flags (job->in_channel, G_IO_FLAG_NONBLOCK, &error) != G_IO_STATUS_NORMAL) { - g_warning ("Cannon set stdin fd for child to be non blocking: %s", error->message); - g_error_free (error); - } - job->in_channel_source_id = g_io_add_watch (job->in_channel, G_IO_OUT, job_write_in, job); - } + job = g_new0 (Job, 1); + job->context = context; + job->device = device != NULL ? DEVICE (g_object_ref (device)) : NULL; + job->job_completed_func = job_completed_func; + job->user_data = user_data; + job->user_data_destroy_func = user_data_destroy_func; + job->stderr_fd = -1; + job->stdout_fd = -1; + job->stdin_fd = -1; + job->stdin_str = g_strdup (stdin_str); + job->stdin_cursor = job->stdin_str; + job->stdout_string = g_string_sized_new (1024); + job->job_id = g_strdup (job_id); + job->udev_settle = udev_settle; + + if (device != NULL && job_id != NULL) + { + g_free (job->device->priv->job_id); + job->device->priv->job_id = g_strdup (job_id); + } - ret = TRUE; + error = NULL; + if (!g_spawn_async_with_pipes (NULL, + argv, + NULL, + G_SPAWN_SEARCH_PATH | G_SPAWN_DO_NOT_REAP_CHILD, + NULL, + NULL, + &(job->pid), + stdin_str != NULL ? &(job->stdin_fd) : NULL, + &(job->stdout_fd), + &(job->stderr_fd), + &error)) + { + throw_error (context, ERROR_FAILED, "Error starting job: %s", error->message); + g_error_free (error); + goto out; + } - if (device != NULL && job_id != NULL) { - device->priv->job_in_progress = TRUE; - device->priv->job_is_cancellable = is_cancellable; - device->priv->job_percentage = -1.0; - device->priv->job_initiated_by_uid = 0; - if (context != NULL) { - daemon_local_get_uid (device->priv->daemon, - &(device->priv->job_initiated_by_uid), - context); - } + g_child_watch_add (job->pid, job_child_watch_cb, job); + + job->error_string = g_string_new (""); + job->error_channel = g_io_channel_unix_new (job->stderr_fd); + error = NULL; + if (g_io_channel_set_flags (job->error_channel, G_IO_FLAG_NONBLOCK, &error) != G_IO_STATUS_NORMAL) + { + g_warning ("Cannon set stderr fd for child to be non blocking: %s", error->message); + g_error_free (error); + } + job->error_channel_source_id = g_io_add_watch (job->error_channel, G_IO_IN, job_read_error, job); - device->priv->job = job; + job->out_channel = g_io_channel_unix_new (job->stdout_fd); + error = NULL; + if (g_io_channel_set_flags (job->out_channel, G_IO_FLAG_NONBLOCK, &error) != G_IO_STATUS_NORMAL) + { + g_warning ("Cannon set stdout fd for child to be non blocking: %s", error->message); + g_error_free (error); + } + job->out_channel_source_id = g_io_add_watch (job->out_channel, G_IO_IN, job_read_out, job); - emit_job_changed (device); + if (job->stdin_fd >= 0) + { + job->in_channel = g_io_channel_unix_new (job->stdin_fd); + if (g_io_channel_set_flags (job->in_channel, G_IO_FLAG_NONBLOCK, &error) != G_IO_STATUS_NORMAL) + { + g_warning ("Cannon set stdin fd for child to be non blocking: %s", error->message); + g_error_free (error); } + job->in_channel_source_id = g_io_add_watch (job->in_channel, G_IO_OUT, job_write_in, job); + } + + ret = TRUE; - if (device != NULL) { - g_print ("helper(pid %5d): launched job %s on %s\n", job->pid, argv[0], device->priv->device_file); - } else { - g_print ("helper(pid %5d): launched job %s on daemon\n", job->pid, argv[0]); + if (device != NULL && job_id != NULL) + { + device->priv->job_in_progress = TRUE; + device->priv->job_is_cancellable = is_cancellable; + device->priv->job_percentage = -1.0; + device->priv->job_initiated_by_uid = 0; + if (context != NULL) + { + daemon_local_get_uid (device->priv->daemon, &(device->priv->job_initiated_by_uid), context); } -out: - if (!ret && job != NULL) - job_free (job); - return ret; + device->priv->job = job; + + emit_job_changed (device); + } + + if (device != NULL) + { + g_print ("helper(pid %5d): launched job %s on %s\n", job->pid, argv[0], device->priv->device_file); + } + else + { + g_print ("helper(pid %5d): launched job %s on daemon\n", job->pid, argv[0]); + } + + out: + if (!ret && job != NULL) + job_free (job); + return ret; } /*--------------------------------------------------------------------------------------------------------------*/ /* exported methods */ -typedef struct { - char *mount_point; - gboolean remove_dir_on_unmount; +typedef struct +{ + char *mount_point; + gboolean remove_dir_on_unmount; } MountData; static MountData * -filesystem_mount_data_new (const char *mount_point, gboolean remove_dir_on_unmount) +filesystem_mount_data_new (const char *mount_point, + gboolean remove_dir_on_unmount) { - MountData *data; - data = g_new0 (MountData, 1); - data->mount_point = g_strdup (mount_point); - data->remove_dir_on_unmount = remove_dir_on_unmount; - return data; + MountData *data; + data = g_new0 (MountData, 1); + data->mount_point = g_strdup (mount_point); + data->remove_dir_on_unmount = remove_dir_on_unmount; + return data; } static void filesystem_mount_data_free (MountData *data) { - g_free (data->mount_point); - g_free (data); + g_free (data->mount_point); + g_free (data); } static gboolean -is_device_in_fstab (Device *device, char **out_mount_point) -{ - GList *l; - GList *mount_points; - gboolean ret; - - ret = FALSE; - - mount_points = g_unix_mount_points_get (NULL); - for (l = mount_points; l != NULL; l = l->next) { - GUnixMountPoint *mount_point = l->data; - char canonical_device_file[PATH_MAX]; - char *device_path; - char *s; - - device_path = g_strdup (g_unix_mount_point_get_device_path (mount_point)); - - /* get the canonical path; e.g. resolve - * - * /dev/disk/by-path/pci-0000:00:1d.7-usb-0:3:1.0-scsi-0:0:0:3-part5 - * UUID=78af6939-adac-4ea5-a2a8-576e141da010 - * LABEL=foobar - * - * into something like /dev/sde5. - */ - if (g_str_has_prefix (device_path, "UUID=")) { - s = device_path; - device_path = g_strdup_printf ("/dev/disk/by-uuid/%s", device_path + 5); - g_free (s); - } else if (g_str_has_prefix (device_path, "LABEL=")) { - s = device_path; - device_path = g_strdup_printf ("/dev/disk/by-label/%s", device_path + 6); - g_free (s); - } +is_device_in_fstab (Device *device, + char **out_mount_point) +{ + GList *l; + GList *mount_points; + gboolean ret; - if (realpath (device_path, canonical_device_file) == NULL) { - g_free (device_path); - continue; - } - g_free (device_path); + ret = FALSE; - if (strcmp (device->priv->device_file, canonical_device_file) == 0) { - ret = TRUE; - if (out_mount_point != NULL) - *out_mount_point = g_strdup (g_unix_mount_point_get_mount_path (mount_point)); - break; - } + mount_points = g_unix_mount_points_get (NULL); + for (l = mount_points; l != NULL; l = l->next) + { + GUnixMountPoint *mount_point = l->data; + char canonical_device_file[PATH_MAX]; + char *device_path; + char *s; + + device_path = g_strdup (g_unix_mount_point_get_device_path (mount_point)); + + /* get the canonical path; e.g. resolve + * + * /dev/disk/by-path/pci-0000:00:1d.7-usb-0:3:1.0-scsi-0:0:0:3-part5 + * UUID=78af6939-adac-4ea5-a2a8-576e141da010 + * LABEL=foobar + * + * into something like /dev/sde5. + */ + if (g_str_has_prefix (device_path, "UUID=")) + { + s = device_path; + device_path = g_strdup_printf ("/dev/disk/by-uuid/%s", device_path + 5); + g_free (s); + } + else if (g_str_has_prefix (device_path, "LABEL=")) + { + s = device_path; + device_path = g_strdup_printf ("/dev/disk/by-label/%s", device_path + 6); + g_free (s); } - g_list_foreach (mount_points, (GFunc) g_unix_mount_point_free, NULL); - g_list_free (mount_points); - return ret; + if (realpath (device_path, canonical_device_file) == NULL) + { + g_free (device_path); + continue; + } + g_free (device_path); + + if (strcmp (device->priv->device_file, canonical_device_file) == 0) + { + ret = TRUE; + if (out_mount_point != NULL) + *out_mount_point = g_strdup (g_unix_mount_point_get_mount_path (mount_point)); + break; + } + } + g_list_foreach (mount_points, (GFunc) g_unix_mount_point_free, NULL); + g_list_free (mount_points); + + return ret; } -typedef struct { - const char *fstype; - const char * const *defaults; - const char * const *allow; - const char * const *allow_uid_self; - const char * const *allow_gid_self; +typedef struct +{ + const char *fstype; + const char * const *defaults; + const char * const *allow; + const char * const *allow_uid_self; + const char * const *allow_gid_self; } FSMountOptions; /* ---------------------- vfat -------------------- */ -static const char *vfat_defaults[] = {"uid=", - "gid=", - "shortname=mixed", - "dmask=0077", - "utf8=1", - NULL}; -static const char *vfat_allow[] = {"flush", - "utf8=", - "shortname=", - "umask=", - "dmask=", - "fmask=", - "codepage=", - "iocharset=", - NULL}; -static const char *vfat_allow_uid_self[] = {"uid=", NULL}; -static const char *vfat_allow_gid_self[] = {"gid=", NULL}; +static const char *vfat_defaults[] = { "uid=", "gid=", "shortname=mixed", "dmask=0077", "utf8=1", NULL }; +static const char *vfat_allow[] = { "flush", "utf8=", "shortname=", "umask=", "dmask=", "fmask=", "codepage=", "iocharset=", NULL }; +static const char *vfat_allow_uid_self[] = { "uid=", NULL }; +static const char *vfat_allow_gid_self[] = { "gid=", NULL }; /* ---------------------- ntfs -------------------- */ /* this is assuming that ntfs-3g is used */ -static const char *ntfs_defaults[] = {"uid=", - "gid=", - "dmask=0077", - NULL}; -static const char *ntfs_allow[] = {"umask=", - "dmask=", - "fmask=", - NULL}; -static const char *ntfs_allow_uid_self[] = {"uid=", NULL}; -static const char *ntfs_allow_gid_self[] = {"gid=", NULL}; +static const char *ntfs_defaults[] = { "uid=", "gid=", "dmask=0077", NULL }; +static const char *ntfs_allow[] = { "umask=", "dmask=", "fmask=", NULL }; +static const char *ntfs_allow_uid_self[] = { "uid=", NULL }; +static const char *ntfs_allow_gid_self[] = { "gid=", NULL }; /* ---------------------- iso9660 -------------------- */ -static const char *iso9660_defaults[] = {"uid=", - "gid=", - "iocharset=utf8", - "mode=0400", - "dmode=0500", - NULL}; -static const char *iso9660_allow[] = {"norock", - "nojoliet", - "iocharset=", - "mode=", - "dmode=", - NULL}; -static const char *iso9660_allow_uid_self[] = {"uid=", NULL}; -static const char *iso9660_allow_gid_self[] = {"gid=", NULL}; +static const char *iso9660_defaults[] = { "uid=", "gid=", "iocharset=utf8", "mode=0400", "dmode=0500", NULL }; +static const char *iso9660_allow[] = { "norock", "nojoliet", "iocharset=", "mode=", "dmode=", NULL }; +static const char *iso9660_allow_uid_self[] = { "uid=", NULL }; +static const char *iso9660_allow_gid_self[] = { "gid=", NULL }; /* ---------------------- udf -------------------- */ -static const char *udf_defaults[] = {"uid=", - "gid=", - "iocharset=utf8", - "umask=0077", - NULL}; -static const char *udf_allow[] = {"iocharset=", - "umask=", - NULL}; -static const char *udf_allow_uid_self[] = {"uid=", NULL}; -static const char *udf_allow_gid_self[] = {"gid=", NULL}; +static const char *udf_defaults[] = { "uid=", "gid=", "iocharset=utf8", "umask=0077", NULL }; +static const char *udf_allow[] = { "iocharset=", "umask=", NULL }; +static const char *udf_allow_uid_self[] = { "uid=", NULL }; +static const char *udf_allow_gid_self[] = { "gid=", NULL }; /* ------------------------------------------------ */ /* TODO: support context= */ -static const char *any_allow[] = {"exec", - "noexec", - "nodev", - "nosuid", - "atime", - "noatime", - "nodiratime", - "ro", - "rw", - "sync", - "dirsync", - NULL}; - -static const FSMountOptions fs_mount_options[] = { - {"vfat", vfat_defaults, vfat_allow, vfat_allow_uid_self, vfat_allow_gid_self}, - {"ntfs", ntfs_defaults, ntfs_allow, ntfs_allow_uid_self, ntfs_allow_gid_self}, - {"iso9660", iso9660_defaults, iso9660_allow, iso9660_allow_uid_self, iso9660_allow_gid_self}, - {"udf", udf_defaults, udf_allow, udf_allow_uid_self, udf_allow_gid_self}, -}; +static const char *any_allow[] = { "exec", "noexec", "nodev", "nosuid", "atime", "noatime", "nodiratime", "ro", "rw", "sync", "dirsync", NULL }; + +static const FSMountOptions fs_mount_options[] = + { + { "vfat", vfat_defaults, vfat_allow, vfat_allow_uid_self, vfat_allow_gid_self }, + { "ntfs", ntfs_defaults, ntfs_allow, ntfs_allow_uid_self, ntfs_allow_gid_self }, + { "iso9660", iso9660_defaults, iso9660_allow, iso9660_allow_uid_self, iso9660_allow_gid_self }, + { "udf", udf_defaults, udf_allow, udf_allow_uid_self, udf_allow_gid_self }, + }; /* ------------------------------------------------ */ -static int num_fs_mount_options = sizeof (fs_mount_options) / sizeof (FSMountOptions); +static int num_fs_mount_options = sizeof(fs_mount_options) / sizeof(FSMountOptions); static const FSMountOptions * find_mount_options_for_fs (const char *fstype) { - int n; - const FSMountOptions *fsmo; + int n; + const FSMountOptions *fsmo; - for (n = 0; n < num_fs_mount_options; n++) { - fsmo = fs_mount_options + n; - if (strcmp (fsmo->fstype, fstype) == 0) - goto out; - } + for (n = 0; n < num_fs_mount_options; n++) + { + fsmo = fs_mount_options + n; + if (strcmp (fsmo->fstype, fstype) == 0) + goto out; + } - fsmo = NULL; -out: - return fsmo; + fsmo = NULL; + out: + return fsmo; } static gid_t find_primary_gid (uid_t uid) { - struct passwd *pw; - gid_t gid; + struct passwd *pw; + gid_t gid; - gid = (gid_t) -1; + gid = (gid_t) - 1; - pw = getpwuid (uid); - if (pw == NULL) { - g_warning ("Couldn't look up uid %d: %m", uid); - goto out; - } - gid = pw->pw_gid; + pw = getpwuid (uid); + if (pw == NULL) + { + g_warning ("Couldn't look up uid %d: %m", uid); + goto out; + } + gid = pw->pw_gid; -out: - return gid; + out: + return gid; } static gboolean -is_uid_in_gid (uid_t uid, gid_t gid) +is_uid_in_gid (uid_t uid, + gid_t gid) { - gboolean ret; - struct passwd *pw; - static gid_t supplementary_groups[128]; - int num_supplementary_groups = 128; - int n; + gboolean ret; + struct passwd *pw; + static gid_t supplementary_groups[128]; + int num_supplementary_groups = 128; + int n; - /* TODO: use some #define instead of harcoding some random number like 128 */ + /* TODO: use some #define instead of harcoding some random number like 128 */ - ret = FALSE; + ret = FALSE; - pw = getpwuid (uid); - if (pw == NULL) { - g_warning ("Couldn't look up uid %d: %m", uid); - goto out; - } - if (pw->pw_gid == gid) { - ret = TRUE; - goto out; - } + pw = getpwuid (uid); + if (pw == NULL) + { + g_warning ("Couldn't look up uid %d: %m", uid); + goto out; + } + if (pw->pw_gid == gid) + { + ret = TRUE; + goto out; + } - if (getgrouplist (pw->pw_name, pw->pw_gid, supplementary_groups, &num_supplementary_groups) < 0) { - g_warning ("Couldn't find supplementary groups for uid %d: %m", uid); - goto out; - } + if (getgrouplist (pw->pw_name, pw->pw_gid, supplementary_groups, &num_supplementary_groups) < 0) + { + g_warning ("Couldn't find supplementary groups for uid %d: %m", uid); + goto out; + } - for (n = 0; n < num_supplementary_groups; n++) { - if (supplementary_groups[n] == gid) { - ret = TRUE; - goto out; - } + for (n = 0; n < num_supplementary_groups; n++) + { + if (supplementary_groups[n] == gid) + { + ret = TRUE; + goto out; } + } -out: - return ret; + out: + return ret; } static gboolean @@ -4585,140 +5021,178 @@ is_mount_option_allowed (const FSMountOptions *fsmo, const char *option, uid_t caller_uid) { - int n; - char *endp; - uid_t uid; - gid_t gid; - gboolean allowed; - const char *ep; - gsize ep_len; - - allowed = FALSE; - - /* first run through the allowed mount options */ - if (fsmo != NULL) { - for (n = 0; fsmo->allow != NULL && fsmo->allow[n] != NULL; n++) { - ep = strstr (fsmo->allow[n], "="); - if (ep != NULL && ep[1] == '\0') { - ep_len = ep - fsmo->allow[n] + 1; - if (strncmp (fsmo->allow[n], option, ep_len) == 0) { - allowed = TRUE; - goto out; - } - } else { - if (strcmp (fsmo->allow[n], option) == 0) { - allowed = TRUE; - goto out; - } - } + int n; + char *endp; + uid_t uid; + gid_t gid; + gboolean allowed; + const char *ep; + gsize ep_len; + + allowed = FALSE; + + /* first run through the allowed mount options */ + if (fsmo != NULL) + { + for (n = 0; fsmo->allow != NULL && fsmo->allow[n] != NULL; n++) + { + ep = strstr (fsmo->allow[n], "="); + if (ep != NULL && ep[1] == '\0') + { + ep_len = ep - fsmo->allow[n] + 1; + if (strncmp (fsmo->allow[n], option, ep_len) == 0) + { + allowed = TRUE; + goto out; } - } - for (n = 0; any_allow[n] != NULL; n++) { - ep = strstr (any_allow[n], "="); - if (ep != NULL && ep[1] == '\0') { - ep_len = ep - any_allow[n] + 1; - if (strncmp (any_allow[n], option, ep_len) == 0) { - allowed = TRUE; - goto out; - } - } else { - if (strcmp (any_allow[n], option) == 0) { - allowed = TRUE; - goto out; - } + } + else + { + if (strcmp (fsmo->allow[n], option) == 0) + { + allowed = TRUE; + goto out; } + } + } + } + for (n = 0; any_allow[n] != NULL; n++) + { + ep = strstr (any_allow[n], "="); + if (ep != NULL && ep[1] == '\0') + { + ep_len = ep - any_allow[n] + 1; + if (strncmp (any_allow[n], option, ep_len) == 0) + { + allowed = TRUE; + goto out; + } + } + else + { + if (strcmp (any_allow[n], option) == 0) + { + allowed = TRUE; + goto out; + } } + } - /* .. then check for mount options where the caller is allowed to pass - * in his own uid - */ - if (fsmo != NULL) { - for (n = 0; fsmo->allow_uid_self != NULL && fsmo->allow_uid_self[n] != NULL; n++) { - const char *r_mount_option = fsmo->allow_uid_self[n]; - if (g_str_has_prefix (option, r_mount_option)) { - uid = strtol (option + strlen (r_mount_option), &endp, 10); - if (*endp != '\0') - continue; - if (uid == caller_uid) { - allowed = TRUE; - goto out; - } - } + /* .. then check for mount options where the caller is allowed to pass + * in his own uid + */ + if (fsmo != NULL) + { + for (n = 0; fsmo->allow_uid_self != NULL && fsmo->allow_uid_self[n] != NULL; n++) + { + const char *r_mount_option = fsmo->allow_uid_self[n]; + if (g_str_has_prefix (option, r_mount_option)) + { + uid = strtol (option + strlen (r_mount_option), &endp, 10); + if (*endp != '\0') + continue; + if (uid == caller_uid) + { + allowed = TRUE; + goto out; } + } } + } - /* .. ditto for gid - */ - if (fsmo != NULL) { - for (n = 0; fsmo->allow_gid_self != NULL && fsmo->allow_gid_self[n] != NULL; n++) { - const char *r_mount_option = fsmo->allow_gid_self[n]; - if (g_str_has_prefix (option, r_mount_option)) { - gid = strtol (option + strlen (r_mount_option), &endp, 10); - if (*endp != '\0') - continue; - if (is_uid_in_gid (caller_uid, gid)) { - allowed = TRUE; - goto out; - } - } + /* .. ditto for gid + */ + if (fsmo != NULL) + { + for (n = 0; fsmo->allow_gid_self != NULL && fsmo->allow_gid_self[n] != NULL; n++) + { + const char *r_mount_option = fsmo->allow_gid_self[n]; + if (g_str_has_prefix (option, r_mount_option)) + { + gid = strtol (option + strlen (r_mount_option), &endp, 10); + if (*endp != '\0') + continue; + if (is_uid_in_gid (caller_uid, gid)) + { + allowed = TRUE; + goto out; } + } } + } -out: - return allowed; + out: + return allowed; } static char ** -prepend_default_mount_options (const FSMountOptions *fsmo, uid_t caller_uid, char **given_options) -{ - GPtrArray *options; - int n; - char *s; - gid_t gid; - - options = g_ptr_array_new (); - if (fsmo != NULL) { - for (n = 0; fsmo->defaults != NULL && fsmo->defaults[n] != NULL; n++) { - const char *option = fsmo->defaults[n]; - - if (strcmp (option, "uid=") == 0) { - s = g_strdup_printf ("uid=%d", caller_uid); - g_ptr_array_add (options, s); - } else if (strcmp (option, "gid=") == 0) { - gid = find_primary_gid (caller_uid); - if (gid != (gid_t) -1) { - s = g_strdup_printf ("gid=%d", gid); - g_ptr_array_add (options, s); - } - } else { - g_ptr_array_add (options, g_strdup (option)); - } +prepend_default_mount_options (const FSMountOptions *fsmo, + uid_t caller_uid, + char **given_options) +{ + GPtrArray *options; + int n; + char *s; + gid_t gid; + + options = g_ptr_array_new (); + if (fsmo != NULL) + { + for (n = 0; fsmo->defaults != NULL && fsmo->defaults[n] != NULL; n++) + { + const char *option = fsmo->defaults[n]; + + if (strcmp (option, "uid=") == 0) + { + s = g_strdup_printf ("uid=%d", caller_uid); + g_ptr_array_add (options, s); + } + else if (strcmp (option, "gid=") == 0) + { + gid = find_primary_gid (caller_uid); + if (gid != (gid_t) - 1) + { + s = g_strdup_printf ("gid=%d", gid); + g_ptr_array_add (options, s); } + } + else + { + g_ptr_array_add (options, g_strdup (option)); + } } - for (n = 0; given_options[n] != NULL; n++) { - g_ptr_array_add (options, g_strdup (given_options[n])); - } + } + for (n = 0; given_options[n] != NULL; n++) + { + g_ptr_array_add (options, g_strdup (given_options[n])); + } - g_ptr_array_add (options, NULL); + g_ptr_array_add (options, NULL); - return (char **) g_ptr_array_free (options, FALSE); + return (char **) g_ptr_array_free (options, FALSE); } static void unlock_cd_tray (Device *device) { - /* Unlock CD tray to keep the hardware eject button working */ - if (g_udev_device_has_property (device->priv->d, "ID_CDROM")) { - g_print ("**** Unlocking CD-ROM door for %s\n", device->priv->device_file); - int fd = open(device->priv->device_file, O_RDONLY); - if (fd > 0) { - if (ioctl (fd, CDROM_LOCKDOOR, 0) != 0) - g_warning ("Could not unlock CD-ROM door: %s", strerror (errno)); - close (fd); - } else { - g_warning ("Could not open CD-ROM device: %s", strerror (errno)); - } + /* Unlock CD tray to keep the hardware eject button working */ + if (g_udev_device_has_property (device->priv->d, "ID_CDROM")) + { + gint fd; + + g_print ("**** Unlocking CD-ROM door for %s\n", device->priv->device_file); + fd = open (device->priv->device_file, O_RDONLY); + if (fd > 0) + { + if (ioctl (fd, CDROM_LOCKDOOR, 0) != 0) + g_warning ("Could not unlock CD-ROM door: %s", strerror (errno)); + close (fd); + } + else + { + g_warning ("Could not open CD-ROM device: %s", strerror (errno)); } + } } static void @@ -4730,489 +5204,533 @@ filesystem_mount_completed_cb (DBusGMethodInvocation *context, const char *stdout, gpointer user_data) { - MountData *data = (MountData *) user_data; - uid_t uid; + MountData *data = (MountData *) user_data; + uid_t uid; - daemon_local_get_uid (device->priv->daemon, &uid, context); + daemon_local_get_uid (device->priv->daemon, &uid, context); - if (WEXITSTATUS (status) == 0 && !job_was_cancelled) { + if (WEXITSTATUS (status) == 0 && !job_was_cancelled) + { - update_info (device); - drain_pending_changes (device, FALSE); - unlock_cd_tray (device); + update_info (device); + drain_pending_changes (device, FALSE); + unlock_cd_tray (device); - dbus_g_method_return (context, data->mount_point); - } else { - if (data->remove_dir_on_unmount) { - mount_file_remove (device->priv->device_file, data->mount_point); - if (g_rmdir (data->mount_point) != 0) { - g_warning ("Error removing dir in late mount error path: %m"); - } - } + dbus_g_method_return (context, data->mount_point); + } + else + { + if (data->remove_dir_on_unmount) + { + mount_file_remove (device->priv->device_file, data->mount_point); + if (g_rmdir (data->mount_point) != 0) + { + g_warning ("Error removing dir in late mount error path: %m"); + } + } - if (job_was_cancelled) { - throw_error (context, - ERROR_CANCELLED, - "Job was cancelled"); - } else if (WEXITSTATUS (status) == 32) { - throw_error (context, - ERROR_FILESYSTEM_DRIVER_MISSING , - "Error mounting: %s", - stderr); - } else { - throw_error (context, - ERROR_FAILED, - "Error mounting: mount exited with exit code %d: %s", - WEXITSTATUS (status), stderr); - } + if (job_was_cancelled) + { + throw_error (context, ERROR_CANCELLED, "Job was cancelled"); + } + else if (WEXITSTATUS (status) == 32) + { + throw_error (context, ERROR_FILESYSTEM_DRIVER_MISSING, "Error mounting: %s", stderr); + } + else + { + throw_error (context, + ERROR_FAILED, + "Error mounting: mount exited with exit code %d: %s", + WEXITSTATUS (status), + stderr); } + } } static void -device_filesystem_mount_authorized_cb (Daemon *daemon, - Device *device, - DBusGMethodInvocation *context, - const gchar *action_id, - guint num_user_data, - gpointer *user_data_elements) -{ - const gchar *filesystem_type = user_data_elements[0]; - gchar **given_options = user_data_elements[1]; - int n; - GString *s; - char *argv[10]; - char *mount_point; - char *fstype; - char *mount_options; - GError *error; - uid_t caller_uid; - gboolean remove_dir_on_unmount; - const FSMountOptions *fsmo; - char **options; - char uid_buf[32]; - - fstype = NULL; - options = NULL; - mount_options = NULL; - mount_point = NULL; - remove_dir_on_unmount = FALSE; - error = NULL; - - daemon_local_get_uid (device->priv->daemon, &caller_uid, context); - - if (device->priv->id_usage == NULL || - strcmp (device->priv->id_usage, "filesystem") != 0) { - if ((g_strcmp0 (filesystem_type, "auto") == 0 || g_strcmp0 (filesystem_type, "") == 0) && - device->priv->id_usage == NULL) { - /* if we don't know the usage of the device and 'auto' or '' is passed for fstype - * then just try that.. this is to make, for example, mounting /dev/fd0 work (we - * don't probe such devices for filesystems in udev) - */ - } else { - throw_error (context, ERROR_FAILED, - "Not a mountable file system"); - goto out; - } +device_filesystem_mount_authorized_cb (Daemon *daemon, + Device *device, + DBusGMethodInvocation *context, + const gchar *action_id, + guint num_user_data, + gpointer *user_data_elements) +{ + const gchar *filesystem_type = user_data_elements[0]; + gchar **given_options = user_data_elements[1]; + int n; + GString *s; + char *argv[10]; + char *mount_point; + char *fstype; + char *mount_options; + GError *error; + uid_t caller_uid; + gboolean remove_dir_on_unmount; + const FSMountOptions *fsmo; + char **options; + char uid_buf[32]; + + fstype = NULL; + options = NULL; + mount_options = NULL; + mount_point = NULL; + remove_dir_on_unmount = FALSE; + error = NULL; + + daemon_local_get_uid (device->priv->daemon, &caller_uid, context); + + if (device->priv->id_usage == NULL || strcmp (device->priv->id_usage, "filesystem") != 0) + { + if ((g_strcmp0 (filesystem_type, "auto") == 0 || g_strcmp0 (filesystem_type, "") == 0) && device->priv->id_usage + == NULL) + { + /* if we don't know the usage of the device and 'auto' or '' is passed for fstype + * then just try that.. this is to make, for example, mounting /dev/fd0 work (we + * don't probe such devices for filesystems in udev) + */ } - - if (device_local_is_busy (device, FALSE, &error)) { - dbus_g_method_return_error (context, error); - g_error_free (error); - goto out; - } - - /* Check if the device is referenced in /etc/fstab; if so, attempt to - * mount the device as the user - */ - if (is_device_in_fstab (device, &mount_point)) { - n = 0; - snprintf (uid_buf, sizeof uid_buf, "%d", caller_uid); - argv[n++] = PACKAGE_LIBEXEC_DIR "/udisks-helper-fstab-mounter"; - argv[n++] = "mount"; - argv[n++] = device->priv->device_file; - argv[n++] = uid_buf; - argv[n++] = NULL; - goto run_job; - } - - /* set the fstype */ - fstype = NULL; - if (strlen (filesystem_type) == 0) { - if (device->priv->id_type != NULL && strlen (device->priv->id_type) > 0) { - fstype = g_strdup (device->priv->id_type); - } else { - fstype = g_strdup ("auto"); - } - } else { - fstype = g_strdup (filesystem_type); + else + { + throw_error (context, ERROR_FAILED, "Not a mountable file system"); + goto out; } + } - fsmo = find_mount_options_for_fs (fstype); - - /* always prepend some reasonable default mount options; these are - * chosen here; the user can override them if he wants to - */ - options = prepend_default_mount_options (fsmo, caller_uid, given_options); + if (device_local_is_busy (device, FALSE, &error)) + { + dbus_g_method_return_error (context, error); + g_error_free (error); + goto out; + } - /* validate mount options and check for authorizations */ - s = g_string_new ("uhelper=udisks,nodev,nosuid"); - for (n = 0; options[n] != NULL; n++) { - const char *option = options[n]; + /* Check if the device is referenced in /etc/fstab; if so, attempt to + * mount the device as the user + */ + if (is_device_in_fstab (device, &mount_point)) + { + n = 0; + snprintf (uid_buf, sizeof uid_buf, "%d", caller_uid); + argv[n++] = PACKAGE_LIBEXEC_DIR "/udisks-helper-fstab-mounter"; + argv[n++] = "mount"; + argv[n++] = device->priv->device_file; + argv[n++] = uid_buf; + argv[n++] = NULL; + goto run_job; + } - /* avoid attacks like passing "shortname=lower,uid=0" as a single mount option */ - if (strstr (option, ",") != NULL) { - throw_error (context, - ERROR_INVALID_OPTION, - "Malformed mount option: ", option); - g_string_free (s, TRUE); - goto out; - } + /* set the fstype */ + fstype = NULL; + if (strlen (filesystem_type) == 0) + { + if (device->priv->id_type != NULL && strlen (device->priv->id_type) > 0) + { + fstype = g_strdup (device->priv->id_type); + } + else + { + fstype = g_strdup ("auto"); + } + } + else + { + fstype = g_strdup (filesystem_type); + } - /* first check if the mount option is allowed */ - if (!is_mount_option_allowed (fsmo, option, caller_uid)) { - throw_error (context, - ERROR_INVALID_OPTION, - "Mount option %s is not allowed", option); - g_string_free (s, TRUE); - goto out; - } + fsmo = find_mount_options_for_fs (fstype); - g_string_append_c (s, ','); - g_string_append (s, option); - } - mount_options = g_string_free (s, FALSE); + /* always prepend some reasonable default mount options; these are + * chosen here; the user can override them if he wants to + */ + options = prepend_default_mount_options (fsmo, caller_uid, given_options); - g_print ("**** USING MOUNT OPTIONS '%s' FOR DEVICE %s\n", mount_options, device->priv->device_file); + /* validate mount options and check for authorizations */ + s = g_string_new ("uhelper=udisks,nodev,nosuid"); + for (n = 0; options[n] != NULL; n++) + { + const char *option = options[n]; - if (device->priv->device_is_mounted) { - throw_error (context, ERROR_FAILED, - "Device is already mounted"); - goto out; + /* avoid attacks like passing "shortname=lower,uid=0" as a single mount option */ + if (strstr (option, ",") != NULL) + { + throw_error (context, ERROR_INVALID_OPTION, "Malformed mount option: ", option); + g_string_free (s, TRUE); + goto out; } - /* Determine the mount point to use. - * - * TODO: use characteristics of the drive such as the name, connection etc. - * to get better names (/media/disk is kinda lame). - */ - if (device->priv->id_label != NULL && strlen (device->priv->id_label) > 0 ) { - GString *s; + /* first check if the mount option is allowed */ + if (!is_mount_option_allowed (fsmo, option, caller_uid)) + { + throw_error (context, ERROR_INVALID_OPTION, "Mount option %s is not allowed", option); + g_string_free (s, TRUE); + goto out; + } - s = g_string_new ("/media/"); - for (n = 0; device->priv->id_label[n] != '\0'; n++) { - gint c = device->priv->id_label[n]; - if (c == '/') - g_string_append_c (s, '_'); - else - g_string_append_c (s, c); - } + g_string_append_c (s, ','); + g_string_append (s, option); + } + mount_options = g_string_free (s, FALSE); - mount_point = g_string_free (s, FALSE); - } else if (device->priv->id_uuid != NULL && strlen (device->priv->id_uuid) > 0) { + g_print ("**** USING MOUNT OPTIONS '%s' FOR DEVICE %s\n", mount_options, device->priv->device_file); - GString *s; + if (device->priv->device_is_mounted) + { + throw_error (context, ERROR_FAILED, "Device is already mounted"); + goto out; + } - s = g_string_new ("/media/"); - for (n = 0; device->priv->id_uuid[n] != '\0'; n++) { - gint c = device->priv->id_uuid[n]; - if (c == '/') - g_string_append_c (s, '_'); - else - g_string_append_c (s, c); - } + /* Determine the mount point to use. + * + * TODO: use characteristics of the drive such as the name, connection etc. + * to get better names (/media/disk is kinda lame). + */ + if (device->priv->id_label != NULL && strlen (device->priv->id_label) > 0) + { + GString * s; - mount_point = g_string_free (s, FALSE); - - } else { - mount_point = g_strdup ("/media/disk"); - } - -try_another_mount_point: - /* ... then uniqify the mount point and mkdir it */ - if (g_file_test (mount_point, G_FILE_TEST_EXISTS)) { - char *s = mount_point; - /* TODO: append numbers instead of _, __ and so on */ - mount_point = g_strdup_printf ("%s_", mount_point); - g_free (s); - goto try_another_mount_point; - } - - remove_dir_on_unmount = TRUE; - - if (g_mkdir (mount_point, 0700) != 0) { - throw_error (context, ERROR_FAILED, "Error creating moint point: %m"); - goto out; - } - - /* now that we have a mount point, immediately add it to the - * /var/lib/udisks/mtab file. - * - * If mounting fails we'll clean it up in filesystem_mount_completed_cb. If it - * hangs we'll clean it up the next time we start up. - */ - mount_file_add (device->priv->device_file, - mount_point, - caller_uid, - remove_dir_on_unmount); - - n = 0; - argv[n++] = "mount"; - argv[n++] = "-t"; - argv[n++] = fstype; - argv[n++] = "-o"; - argv[n++] = mount_options; - argv[n++] = device->priv->device_file; - argv[n++] = mount_point; - argv[n++] = NULL; - -run_job: - - error = NULL; - if (!job_new (context, - "FilesystemMount", - FALSE, - device, - argv, - NULL, - filesystem_mount_completed_cb, - FALSE, - filesystem_mount_data_new (mount_point, remove_dir_on_unmount), - (GDestroyNotify) filesystem_mount_data_free)) { - if (remove_dir_on_unmount) { - mount_file_remove (device->priv->device_file, mount_point); - if (g_rmdir (mount_point) != 0) { - g_warning ("Error removing dir in early mount error path: %m"); - } - } - goto out; + s = g_string_new ("/media/"); + for (n = 0; device->priv->id_label[n] != '\0'; n++) + { + gint c = device->priv->id_label[n]; + if (c == '/') + g_string_append_c (s, '_'); + else + g_string_append_c (s, c); } -out: - g_free (fstype); - g_free (mount_options); - g_free (mount_point); - g_strfreev (options); -} + mount_point = g_string_free (s, FALSE); + } + else if (device->priv->id_uuid != NULL && strlen (device->priv->id_uuid) > 0) + { -gboolean -device_filesystem_mount (Device *device, - const char *filesystem_type, - char **given_options, - DBusGMethodInvocation *context) -{ - const gchar *action_id; - gboolean auth_no_user_interaction; - gchar **options_to_pass; - guint n; - guint m; - - if (is_device_in_fstab (device, NULL)) { - action_id = NULL; - } else { - if (device->priv->device_is_system_internal) - action_id = "org.freedesktop.devicekit.disks.filesystem-mount-system-internal"; - else - action_id = "org.freedesktop.devicekit.disks.filesystem-mount"; - } - - auth_no_user_interaction = FALSE; - options_to_pass = g_strdupv (given_options); - for (n = 0; options_to_pass != NULL && options_to_pass[n] != NULL; n++) { - if (g_strcmp0 (options_to_pass[n], "auth_no_user_interaction") == 0) { - auth_no_user_interaction = TRUE; - g_free (options_to_pass[n]); - for (m = n; options_to_pass[m + 1] != NULL; m++) - options_to_pass[m] = options_to_pass[m + 1]; - options_to_pass[m] = NULL; - break; - } + GString * s; + + s = g_string_new ("/media/"); + for (n = 0; device->priv->id_uuid[n] != '\0'; n++) + { + gint c = device->priv->id_uuid[n]; + if (c == '/') + g_string_append_c (s, '_'); + else + g_string_append_c (s, c); } - daemon_local_check_auth (device->priv->daemon, - device, - action_id, - "FilesystemMount", - !auth_no_user_interaction, - device_filesystem_mount_authorized_cb, - context, - 2, - g_strdup (filesystem_type), g_free, - options_to_pass, g_strfreev); + mount_point = g_string_free (s, FALSE); - return TRUE; -} + } + else + { + mount_point = g_strdup ("/media/disk"); + } -/*--------------------------------------------------------------------------------------------------------------*/ + try_another_mount_point: + /* ... then uniqify the mount point and mkdir it */ + if (g_file_test (mount_point, G_FILE_TEST_EXISTS)) + { + char *s = mount_point; + /* TODO: append numbers instead of _, __ and so on */ + mount_point = g_strdup_printf ("%s_", mount_point); + g_free (s); + goto try_another_mount_point; + } -static void -filesystem_unmount_completed_cb (DBusGMethodInvocation *context, - Device *device, - gboolean job_was_cancelled, - int status, - const char *stderr, - const char *stdout, - gpointer user_data) -{ - if (WEXITSTATUS (status) == 0 && !job_was_cancelled) { - /* update_info_mount_state() will update the mounts file and clean up the directory if needed */ - update_info (device); - dbus_g_method_return (context); - } else { - if (job_was_cancelled) { - throw_error (context, - ERROR_CANCELLED, - "Job was cancelled"); - } else { - if (strstr (stderr, "device is busy") != NULL) { - throw_error (context, - ERROR_BUSY, - "Cannot unmount because file system on device is busy"); - } else { - throw_error (context, - ERROR_FAILED, - "Error unmounting: umount exited with exit code %d: %s", - WEXITSTATUS (status), - stderr); - } - } + remove_dir_on_unmount = TRUE; + + if (g_mkdir (mount_point, 0700) != 0) + { + throw_error (context, ERROR_FAILED, "Error creating moint point: %m"); + goto out; + } + + /* now that we have a mount point, immediately add it to the + * /var/lib/udisks/mtab file. + * + * If mounting fails we'll clean it up in filesystem_mount_completed_cb. If it + * hangs we'll clean it up the next time we start up. + */ + mount_file_add (device->priv->device_file, mount_point, caller_uid, remove_dir_on_unmount); + + n = 0; + argv[n++] = "mount"; + argv[n++] = "-t"; + argv[n++] = fstype; + argv[n++] = "-o"; + argv[n++] = mount_options; + argv[n++] = device->priv->device_file; + argv[n++] = mount_point; + argv[n++] = NULL; + + run_job: + + error = NULL; + if (!job_new (context, + "FilesystemMount", + FALSE, + device, + argv, + NULL, + filesystem_mount_completed_cb, + FALSE, + filesystem_mount_data_new (mount_point, remove_dir_on_unmount), + (GDestroyNotify) filesystem_mount_data_free)) + { + if (remove_dir_on_unmount) + { + mount_file_remove (device->priv->device_file, mount_point); + if (g_rmdir (mount_point) != 0) + { + g_warning ("Error removing dir in early mount error path: %m"); + } } + goto out; + } + + out: + g_free (fstype); + g_free (mount_options); + g_free (mount_point); + g_strfreev (options); } -static void -device_filesystem_unmount_authorized_cb (Daemon *daemon, - Device *device, - DBusGMethodInvocation *context, - const gchar *action_id, - guint num_user_data, - gpointer *user_data_elements) -{ - gchar **options = user_data_elements[0]; - int n; - char *argv[16]; - GError *error; - gboolean force_unmount; - char *mount_path; - uid_t uid; - gchar uid_buf[32]; - - mount_path = NULL; - - if (!device->priv->device_is_mounted || - device->priv->device_mount_paths->len == 0) { - throw_error (context, - ERROR_FAILED, - "Device is not mounted"); - goto out; - } - - force_unmount = FALSE; - for (n = 0; options[n] != NULL; n++) { - char *option = options[n]; - if (strcmp ("force", option) == 0) { - force_unmount = TRUE; - } else { - throw_error (context, - ERROR_INVALID_OPTION, - "Unknown option %s", option); - goto out; - } +gboolean +device_filesystem_mount (Device *device, + const char *filesystem_type, + char **given_options, + DBusGMethodInvocation *context) +{ + const gchar *action_id; + gboolean auth_no_user_interaction; + gchar **options_to_pass; + guint n; + guint m; + + if (is_device_in_fstab (device, NULL)) + { + action_id = NULL; + } + else + { + if (device->priv->device_is_system_internal) + action_id = "org.freedesktop.devicekit.disks.filesystem-mount-system-internal"; + else + action_id = "org.freedesktop.devicekit.disks.filesystem-mount"; + } + + auth_no_user_interaction = FALSE; + options_to_pass = g_strdupv (given_options); + for (n = 0; options_to_pass != NULL && options_to_pass[n] != NULL; n++) + { + if (g_strcmp0 (options_to_pass[n], "auth_no_user_interaction") == 0) + { + auth_no_user_interaction = TRUE; + g_free (options_to_pass[n]); + for (m = n; options_to_pass[m + 1] != NULL; m++) + options_to_pass[m] = options_to_pass[m + 1]; + options_to_pass[m] = NULL; + break; } + } - daemon_local_get_uid (device->priv->daemon, &uid, context); - g_snprintf (uid_buf, sizeof uid_buf, "%d", uid); + daemon_local_check_auth (device->priv->daemon, + device, + action_id, + "FilesystemMount", + !auth_no_user_interaction, + device_filesystem_mount_authorized_cb, + context, + 2, + g_strdup (filesystem_type), + g_free, + options_to_pass, + g_strfreev); - if (!mount_file_has_device (device->priv->device_file, NULL, NULL)) { - if (is_device_in_fstab (device, &mount_path)) { + return TRUE; +} - n = 0; - argv[n++] = PACKAGE_LIBEXEC_DIR "/udisks-helper-fstab-mounter"; - if (force_unmount) - argv[n++] = "force_unmount"; - else - argv[n++] = "unmount"; - argv[n++] = device->priv->device_file; - argv[n++] = uid_buf; - argv[n++] = NULL; - goto run_job; - } +/*--------------------------------------------------------------------------------------------------------------*/ - /* otherwise the user will have the .unmount-others authorization per the logic in - * device_filesystem_unmount() - */ +static void +filesystem_unmount_completed_cb (DBusGMethodInvocation *context, + Device *device, + gboolean job_was_cancelled, + int status, + const char *stderr, + const char *stdout, + gpointer user_data) +{ + if (WEXITSTATUS (status) == 0 && !job_was_cancelled) + { + /* update_info_mount_state() will update the mounts file and clean up the directory if needed */ + update_info (device); + dbus_g_method_return (context); + } + else + { + if (job_was_cancelled) + { + throw_error (context, ERROR_CANCELLED, "Job was cancelled"); } + else + { + if (strstr (stderr, "device is busy") != NULL) + { + throw_error (context, ERROR_BUSY, "Cannot unmount because file system on device is busy"); + } + else + { + throw_error (context, + ERROR_FAILED, + "Error unmounting: umount exited with exit code %d: %s", + WEXITSTATUS (status), + stderr); + } + } + } +} - mount_path = g_strdup (((gchar **) device->priv->device_mount_paths->pdata)[0]); +static void +device_filesystem_unmount_authorized_cb (Daemon *daemon, + Device *device, + DBusGMethodInvocation *context, + const gchar *action_id, + guint num_user_data, + gpointer *user_data_elements) +{ + gchar **options = user_data_elements[0]; + int n; + char *argv[16]; + GError *error; + gboolean force_unmount; + char *mount_path; + uid_t uid; + gchar uid_buf[32]; + + mount_path = NULL; + + if (!device->priv->device_is_mounted || device->priv->device_mount_paths->len == 0) + { + throw_error (context, ERROR_FAILED, "Device is not mounted"); + goto out; + } - n = 0; - argv[n++] = "umount"; - if (force_unmount) { - /* on Linux we currently only have lazy unmount to emulate this */ - argv[n++] = "-l"; + force_unmount = FALSE; + for (n = 0; options[n] != NULL; n++) + { + char *option = options[n]; + if (strcmp ("force", option) == 0) + { + force_unmount = TRUE; } - argv[n++] = mount_path; - argv[n++] = NULL; - -run_job: - error = NULL; - if (!job_new (context, - "FilesystemUnmount", - FALSE, - device, - argv, - NULL, - filesystem_unmount_completed_cb, - FALSE, - g_strdup (mount_path), - g_free)) { - goto out; + else + { + throw_error (context, ERROR_INVALID_OPTION, "Unknown option %s", option); + goto out; } + } + + daemon_local_get_uid (device->priv->daemon, &uid, context); + g_snprintf (uid_buf, sizeof uid_buf, "%d", uid); + + if (!mount_file_has_device (device->priv->device_file, NULL, NULL)) + { + if (is_device_in_fstab (device, &mount_path)) + { + + n = 0; + argv[n++] = PACKAGE_LIBEXEC_DIR "/udisks-helper-fstab-mounter"; + if (force_unmount) + argv[n++] = "force_unmount"; + else + argv[n++] = "unmount"; + argv[n++] = device->priv->device_file; + argv[n++] = uid_buf; + argv[n++] = NULL; + goto run_job; + } + + /* otherwise the user will have the .unmount-others authorization per the logic in + * device_filesystem_unmount() + */ + } -out: - g_free (mount_path); + mount_path = g_strdup (((gchar **) device->priv->device_mount_paths->pdata)[0]); + + n = 0; + argv[n++] = "umount"; + if (force_unmount) + { + /* on Linux we currently only have lazy unmount to emulate this */ + argv[n++] = "-l"; + } + argv[n++] = mount_path; + argv[n++] = NULL; + + run_job: + error = NULL; + if (!job_new (context, + "FilesystemUnmount", + FALSE, + device, + argv, + NULL, + filesystem_unmount_completed_cb, + FALSE, + g_strdup (mount_path), + g_free)) + { + goto out; + } + + out: + g_free (mount_path); } gboolean -device_filesystem_unmount (Device *device, - char **options, - DBusGMethodInvocation *context) -{ - const gchar *action_id; - uid_t uid_of_mount; - - if (!device->priv->device_is_mounted || - device->priv->device_mount_paths->len == 0) { - throw_error (context, - ERROR_FAILED, - "Device is not mounted"); - goto out; - } - - /* if device is in /etc/fstab, then we'll run unmount as the calling user */ - action_id = NULL; - if (!mount_file_has_device (device->priv->device_file, &uid_of_mount, NULL)) { - if (!is_device_in_fstab (device, NULL)) { - action_id = "org.freedesktop.devicekit.disks.filesystem-unmount-others"; - } - } else { - uid_t uid; - daemon_local_get_uid (device->priv->daemon, &uid, context); - if (uid_of_mount != uid) { - action_id = "org.freedesktop.devicekit.disks.filesystem-unmount-others"; - } +device_filesystem_unmount (Device *device, + char **options, + DBusGMethodInvocation *context) +{ + const gchar *action_id; + uid_t uid_of_mount; + + if (!device->priv->device_is_mounted || device->priv->device_mount_paths->len == 0) + { + throw_error (context, ERROR_FAILED, "Device is not mounted"); + goto out; + } + + /* if device is in /etc/fstab, then we'll run unmount as the calling user */ + action_id = NULL; + if (!mount_file_has_device (device->priv->device_file, &uid_of_mount, NULL)) + { + if (!is_device_in_fstab (device, NULL)) + { + action_id = "org.freedesktop.devicekit.disks.filesystem-unmount-others"; + } + } + else + { + uid_t uid; + daemon_local_get_uid (device->priv->daemon, &uid, context); + if (uid_of_mount != uid) + { + action_id = "org.freedesktop.devicekit.disks.filesystem-unmount-others"; } + } - daemon_local_check_auth (device->priv->daemon, - device, - action_id, - "FilesystemUnmount", - TRUE, - device_filesystem_unmount_authorized_cb, - context, - 1, - g_strdupv (options), g_strfreev); + daemon_local_check_auth (device->priv->daemon, + device, + action_id, + "FilesystemUnmount", + TRUE, + device_filesystem_unmount_authorized_cb, + context, + 1, + g_strdupv (options), + g_strfreev); out: - return TRUE; + return TRUE; } /*--------------------------------------------------------------------------------------------------------------*/ @@ -5220,76 +5738,78 @@ device_filesystem_unmount (Device *device, static uid_t get_uid_for_pid (pid_t pid) { - uid_t ret; - char proc_name[32]; - struct stat statbuf; + uid_t ret; + char proc_name[32]; + struct stat statbuf; - ret = 0; + ret = 0; - snprintf (proc_name, sizeof (proc_name), "/proc/%d/stat", pid); - if (stat (proc_name, &statbuf) == 0) { - ret = statbuf.st_uid; - } + snprintf (proc_name, sizeof(proc_name), "/proc/%d/stat", pid); + if (stat (proc_name, &statbuf) == 0) + { + ret = statbuf.st_uid; + } - return ret; + return ret; } static char * get_command_line_for_pid (pid_t pid) { - char proc_name[32]; - char *buf; - gsize len; - char *ret; - unsigned int n; + char proc_name[32]; + char *buf; + gsize len; + char *ret; + unsigned int n; - ret = NULL; + ret = NULL; - snprintf (proc_name, sizeof (proc_name), "/proc/%d/cmdline", pid); - if (g_file_get_contents (proc_name, &buf, &len, NULL)) { - for (n = 0; n < len; n++) { - if (buf[n] == '\0') - buf[n] = ' '; - } - g_strstrip (buf); - ret = buf; + snprintf (proc_name, sizeof(proc_name), "/proc/%d/cmdline", pid); + if (g_file_get_contents (proc_name, &buf, &len, NULL)) + { + for (n = 0; n < len; n++) + { + if (buf[n] == '\0') + buf[n] = ' '; } + g_strstrip (buf); + ret = buf; + } - return ret; + return ret; } static void -lsof_parse (const char *stdout, GPtrArray *processes) +lsof_parse (const char *stdout, + GPtrArray *processes) { - int n; - char **tokens; + int n; + char **tokens; - tokens = g_strsplit (stdout, "\n", 0); - for (n = 0; tokens[n] != NULL; n++) { - pid_t pid; - uid_t uid; - char *command_line; - GValue elem = {0}; + tokens = g_strsplit (stdout, "\n", 0); + for (n = 0; tokens[n] != NULL; n++) + { + pid_t pid; + uid_t uid; + char *command_line; + GValue elem = + { 0 }; - if (strlen (tokens[n]) == 0) - continue; + if (strlen (tokens[n]) == 0) + continue; - pid = strtol (tokens[n], NULL, 0); - uid = get_uid_for_pid (pid); - command_line = get_command_line_for_pid (pid); + pid = strtol (tokens[n], NULL, 0); + uid = get_uid_for_pid (pid); + command_line = get_command_line_for_pid (pid); - g_value_init (&elem, LSOF_DATA_STRUCT_TYPE); - g_value_take_boxed (&elem, dbus_g_type_specialized_construct (LSOF_DATA_STRUCT_TYPE)); - dbus_g_type_struct_set (&elem, - 0, pid, - 1, uid, - 2, command_line != NULL ? command_line : "", - G_MAXUINT); - g_ptr_array_add (processes, g_value_get_boxed (&elem)); + g_value_init (&elem, LSOF_DATA_STRUCT_TYPE); + g_value_take_boxed (&elem, dbus_g_type_specialized_construct (LSOF_DATA_STRUCT_TYPE)); + dbus_g_type_struct_set (&elem, 0, pid, 1, uid, 2, command_line != NULL ? command_line : "", G_MAXUINT); + g_ptr_array_add (processes, g_value_get_boxed (&elem)); - g_free (command_line); - } - g_strfreev (tokens); + g_free (command_line); + } + g_strfreev (tokens); } static void @@ -5301,92 +5821,83 @@ filesystem_list_open_files_completed_cb (DBusGMethodInvocation *context, const char *stdout, gpointer user_data) { - if ((WEXITSTATUS (status) == 0 || WEXITSTATUS (status) == 1) && !job_was_cancelled) { - GPtrArray *processes; + if ((WEXITSTATUS (status) == 0 || WEXITSTATUS (status) == 1) && !job_was_cancelled) + { + GPtrArray *processes; - processes = g_ptr_array_new (); - lsof_parse (stdout, processes); - dbus_g_method_return (context, processes); - g_ptr_array_foreach (processes, (GFunc) g_value_array_free, NULL); - g_ptr_array_free (processes, TRUE); - } else { - throw_error (context, - ERROR_FAILED, - "Error listing open files: lsof exited with exit code %d: %s", - WEXITSTATUS (status), - stderr); - } + processes = g_ptr_array_new (); + lsof_parse (stdout, processes); + dbus_g_method_return (context, processes); + g_ptr_array_foreach (processes, (GFunc) g_value_array_free, NULL); + g_ptr_array_free (processes, TRUE); + } + else + { + throw_error (context, + ERROR_FAILED, + "Error listing open files: lsof exited with exit code %d: %s", + WEXITSTATUS (status), + stderr); + } } static void -device_filesystem_list_open_files_authorized_cb (Daemon *daemon, - Device *device, - DBusGMethodInvocation *context, - const gchar *action_id, - guint num_user_data, - gpointer *user_data_elements) -{ - int n; - char *argv[16]; - GError *error; - - if (!device->priv->device_is_mounted || - device->priv->device_mount_paths->len == 0) { - throw_error (context, - ERROR_FAILED, - "Device is not mounted"); - goto out; - } - - n = 0; - argv[n++] = "lsof"; - argv[n++] = "-t"; - argv[n++] = ((gchar **) device->priv->device_mount_paths->pdata)[0]; - argv[n++] = NULL; - - error = NULL; - if (!job_new (context, - NULL, /* don't run this as a job */ - FALSE, - device, - argv, - NULL, - filesystem_list_open_files_completed_cb, - FALSE, - NULL, - NULL)) { - goto out; - } - -out: - ; +device_filesystem_list_open_files_authorized_cb (Daemon *daemon, + Device *device, + DBusGMethodInvocation *context, + const gchar *action_id, + guint num_user_data, + gpointer *user_data_elements) +{ + int n; + char *argv[16]; + GError *error; + + if (!device->priv->device_is_mounted || device->priv->device_mount_paths->len == 0) + { + throw_error (context, ERROR_FAILED, "Device is not mounted"); + goto out; + } + + n = 0; + argv[n++] = "lsof"; + argv[n++] = "-t"; + argv[n++] = ((gchar **) device->priv->device_mount_paths->pdata)[0]; + argv[n++] = NULL; + + error = NULL; + if (!job_new (context, NULL, /* don't run this as a job */ + FALSE, device, argv, NULL, filesystem_list_open_files_completed_cb, FALSE, NULL, NULL)) + { + goto out; + } + + out: + ; } gboolean -device_filesystem_list_open_files (Device *device, - DBusGMethodInvocation *context) -{ - if (!device->priv->device_is_mounted || - device->priv->device_mount_paths->len == 0) { - throw_error (context, - ERROR_FAILED, - "Device is not mounted"); - goto out; - } - - daemon_local_check_auth (device->priv->daemon, - device, - device->priv->device_is_system_internal ? - "org.freedesktop.devicekit.disks.filesystem-lsof-system-internal" : - "org.freedesktop.devicekit.disks.filesystem-lsof", - "FilesystemListOpenFiles", - TRUE, - device_filesystem_list_open_files_authorized_cb, - context, - 0); +device_filesystem_list_open_files (Device *device, + DBusGMethodInvocation *context) +{ + if (!device->priv->device_is_mounted || device->priv->device_mount_paths->len == 0) + { + throw_error (context, ERROR_FAILED, "Device is not mounted"); + goto out; + } + + daemon_local_check_auth (device->priv->daemon, + device, + device->priv->device_is_system_internal ? "org.freedesktop.devicekit.disks.filesystem-lsof-system-internal" + : "org.freedesktop.devicekit.disks.filesystem-lsof", + "FilesystemListOpenFiles", + TRUE, + device_filesystem_list_open_files_authorized_cb, + context, + 0); out: - return TRUE; + return TRUE; } /*--------------------------------------------------------------------------------------------------------------*/ @@ -5400,244 +5911,238 @@ drive_eject_completed_cb (DBusGMethodInvocation *context, const char *stdout, gpointer user_data) { - if (WEXITSTATUS (status) == 0 && !job_was_cancelled) { - /* TODO: probably wait for has_media to change to FALSE */ - dbus_g_method_return (context); - } else { - if (job_was_cancelled) { - throw_error (context, - ERROR_CANCELLED, - "Job was cancelled"); - } else { - throw_error (context, - ERROR_FAILED, - "Error ejecting: eject exited with exit code %d: %s", - WEXITSTATUS (status), - stderr); - } + if (WEXITSTATUS (status) == 0 && !job_was_cancelled) + { + /* TODO: probably wait for has_media to change to FALSE */ + dbus_g_method_return (context); + } + else + { + if (job_was_cancelled) + { + throw_error (context, ERROR_CANCELLED, "Job was cancelled"); + } + else + { + throw_error (context, + ERROR_FAILED, + "Error ejecting: eject exited with exit code %d: %s", + WEXITSTATUS (status), + stderr); } + } } static void -device_drive_eject_authorized_cb (Daemon *daemon, - Device *device, - DBusGMethodInvocation *context, - const gchar *action_id, - guint num_user_data, - gpointer *user_data_elements) -{ - gchar **options = user_data_elements[0]; - int n; - char *argv[16]; - GError *error; - char *mount_path; - - error = NULL; - mount_path = NULL; - - if (!device->priv->device_is_drive) { - throw_error (context, ERROR_FAILED, - "Device is not a drive"); - goto out; - } - - if (!device->priv->device_is_media_available) { - throw_error (context, ERROR_FAILED, - "No media in drive"); - goto out; - } - - if (device_local_is_busy (device, TRUE, &error)) { - dbus_g_method_return_error (context, error); - g_error_free (error); - goto out; - } - - for (n = 0; options[n] != NULL; n++) { - const char *option = options[n]; - throw_error (context, - ERROR_INVALID_OPTION, - "Unknown option %s", option); - goto out; - } - - n = 0; - argv[n++] = "eject"; - argv[n++] = device->priv->device_file; - argv[n++] = NULL; - - if (!job_new (context, - "DriveEject", - FALSE, - device, - argv, - NULL, - drive_eject_completed_cb, - FALSE, - NULL, - NULL)) { - goto out; - } - -out: - ; +device_drive_eject_authorized_cb (Daemon *daemon, + Device *device, + DBusGMethodInvocation *context, + const gchar *action_id, + guint num_user_data, + gpointer *user_data_elements) +{ + gchar **options = user_data_elements[0]; + int n; + char *argv[16]; + GError *error; + char *mount_path; + + error = NULL; + mount_path = NULL; + + if (!device->priv->device_is_drive) + { + throw_error (context, ERROR_FAILED, "Device is not a drive"); + goto out; + } + + if (!device->priv->device_is_media_available) + { + throw_error (context, ERROR_FAILED, "No media in drive"); + goto out; + } + + if (device_local_is_busy (device, TRUE, &error)) + { + dbus_g_method_return_error (context, error); + g_error_free (error); + goto out; + } + + for (n = 0; options[n] != NULL; n++) + { + const char *option = options[n]; + throw_error (context, ERROR_INVALID_OPTION, "Unknown option %s", option); + goto out; + } + + n = 0; + argv[n++] = "eject"; + argv[n++] = device->priv->device_file; + argv[n++] = NULL; + + if (!job_new (context, "DriveEject", FALSE, device, argv, NULL, drive_eject_completed_cb, FALSE, NULL, NULL)) + { + goto out; + } + + out: + ; } gboolean -device_drive_eject (Device *device, - char **options, - DBusGMethodInvocation *context) +device_drive_eject (Device *device, + char **options, + DBusGMethodInvocation *context) { - if (!device->priv->device_is_drive) { - throw_error (context, ERROR_FAILED, - "Device is not a drive"); - goto out; - } + if (!device->priv->device_is_drive) + { + throw_error (context, ERROR_FAILED, "Device is not a drive"); + goto out; + } - if (!device->priv->device_is_media_available) { - throw_error (context, ERROR_FAILED, - "No media in drive"); - goto out; - } + if (!device->priv->device_is_media_available) + { + throw_error (context, ERROR_FAILED, "No media in drive"); + goto out; + } - daemon_local_check_auth (device->priv->daemon, - device, - "org.freedesktop.devicekit.disks.drive-eject", - "DriveEject", - TRUE, - device_drive_eject_authorized_cb, - context, - 1, - g_strdupv (options), g_strfreev); + daemon_local_check_auth (device->priv->daemon, + device, + "org.freedesktop.devicekit.disks.drive-eject", + "DriveEject", + TRUE, + device_drive_eject_authorized_cb, + context, + 1, + g_strdupv (options), + g_strfreev); out: - return TRUE; + return TRUE; } /*--------------------------------------------------------------------------------------------------------------*/ static void drive_detach_completed_cb (DBusGMethodInvocation *context, - Device *device, - gboolean job_was_cancelled, - int status, - const char *stderr, - const char *stdout, - gpointer user_data) + Device *device, + gboolean job_was_cancelled, + int status, + const char *stderr, + const char *stdout, + gpointer user_data) { - if (WEXITSTATUS (status) == 0 && !job_was_cancelled) { - /* TODO: probably wait for has_media to change to FALSE */ - dbus_g_method_return (context); - } else { - if (job_was_cancelled) { - throw_error (context, - ERROR_CANCELLED, - "Job was cancelled"); - } else { - throw_error (context, - ERROR_FAILED, - "Error detaching: helper exited with exit code %d: %s", - WEXITSTATUS (status), - stderr); - } + if (WEXITSTATUS (status) == 0 && !job_was_cancelled) + { + /* TODO: probably wait for has_media to change to FALSE */ + dbus_g_method_return (context); + } + else + { + if (job_was_cancelled) + { + throw_error (context, ERROR_CANCELLED, "Job was cancelled"); } + else + { + throw_error (context, + ERROR_FAILED, + "Error detaching: helper exited with exit code %d: %s", + WEXITSTATUS (status), + stderr); + } + } } static void -device_drive_detach_authorized_cb (Daemon *daemon, - Device *device, - DBusGMethodInvocation *context, - const gchar *action_id, - guint num_user_data, - gpointer *user_data_elements) -{ - gchar **options = user_data_elements[0]; - int n; - char *argv[16]; - GError *error; - char *mount_path; - - error = NULL; - mount_path = NULL; - - if (!device->priv->device_is_drive) { - throw_error (context, ERROR_FAILED, - "Device is not a drive"); - goto out; - } - - if (!device->priv->drive_can_detach) { - throw_error (context, ERROR_FAILED, - "Device is not detachable"); - goto out; - } - - if (device_local_is_busy (device, TRUE, &error)) { - dbus_g_method_return_error (context, error); - g_error_free (error); - goto out; - } - - for (n = 0; options[n] != NULL; n++) { - const char *option = options[n]; - throw_error (context, - ERROR_INVALID_OPTION, - "Unknown option %s", option); - goto out; - } - - n = 0; - argv[n++] = PACKAGE_LIBEXEC_DIR "/udisks-helper-drive-detach"; - argv[n++] = device->priv->device_file; - argv[n++] = device->priv->native_path; - argv[n++] = NULL; - - if (!job_new (context, - "DriveDetach", - FALSE, - device, - argv, - NULL, - drive_detach_completed_cb, - FALSE, - NULL, - NULL)) { - goto out; - } - -out: - ; +device_drive_detach_authorized_cb (Daemon *daemon, + Device *device, + DBusGMethodInvocation *context, + const gchar *action_id, + guint num_user_data, + gpointer *user_data_elements) +{ + gchar **options = user_data_elements[0]; + int n; + char *argv[16]; + GError *error; + char *mount_path; + + error = NULL; + mount_path = NULL; + + if (!device->priv->device_is_drive) + { + throw_error (context, ERROR_FAILED, "Device is not a drive"); + goto out; + } + + if (!device->priv->drive_can_detach) + { + throw_error (context, ERROR_FAILED, "Device is not detachable"); + goto out; + } + + if (device_local_is_busy (device, TRUE, &error)) + { + dbus_g_method_return_error (context, error); + g_error_free (error); + goto out; + } + + for (n = 0; options[n] != NULL; n++) + { + const char *option = options[n]; + throw_error (context, ERROR_INVALID_OPTION, "Unknown option %s", option); + goto out; + } + + n = 0; + argv[n++] = PACKAGE_LIBEXEC_DIR "/udisks-helper-drive-detach"; + argv[n++] = device->priv->device_file; + argv[n++] = device->priv->native_path; + argv[n++] = NULL; + + if (!job_new (context, "DriveDetach", FALSE, device, argv, NULL, drive_detach_completed_cb, FALSE, NULL, NULL)) + { + goto out; + } + + out: + ; } gboolean -device_drive_detach (Device *device, - char **options, - DBusGMethodInvocation *context) +device_drive_detach (Device *device, + char **options, + DBusGMethodInvocation *context) { - if (!device->priv->device_is_drive) { - throw_error (context, ERROR_FAILED, - "Device is not a drive"); - goto out; - } + if (!device->priv->device_is_drive) + { + throw_error (context, ERROR_FAILED, "Device is not a drive"); + goto out; + } - if (!device->priv->drive_can_detach) { - throw_error (context, ERROR_FAILED, - "Device is not detachable"); - goto out; - } + if (!device->priv->drive_can_detach) + { + throw_error (context, ERROR_FAILED, "Device is not detachable"); + goto out; + } - daemon_local_check_auth (device->priv->daemon, - device, - "org.freedesktop.devicekit.disks.drive-detach", - "DriveDetach", - TRUE, - device_drive_detach_authorized_cb, - context, - 1, - g_strdupv (options), g_strfreev); + daemon_local_check_auth (device->priv->daemon, + device, + "org.freedesktop.devicekit.disks.drive-detach", + "DriveDetach", + TRUE, + device_drive_detach_authorized_cb, + context, + 1, + g_strdupv (options), + g_strfreev); out: - return TRUE; + return TRUE; } /*--------------------------------------------------------------------------------------------------------------*/ @@ -5651,97 +6156,93 @@ filesystem_check_completed_cb (DBusGMethodInvocation *context, const char *stdout, gpointer user_data) { - if (WIFEXITED (status) && !job_was_cancelled) { - int rc; - gboolean fs_is_clean; + if (WIFEXITED (status) && !job_was_cancelled) + { + int rc; + gboolean fs_is_clean; - fs_is_clean = FALSE; + fs_is_clean = FALSE; - rc = WEXITSTATUS (status); - if ((rc == 0) || - (((rc & 1) != 0) && ((rc & 4) == 0))) { - fs_is_clean = TRUE; - } + rc = WEXITSTATUS (status); + if ((rc == 0) || (((rc & 1) != 0) && ((rc & 4) == 0))) + { + fs_is_clean = TRUE; + } - dbus_g_method_return (context, fs_is_clean); - } else { - if (job_was_cancelled) { - throw_error (context, - ERROR_CANCELLED, - "Job was cancelled"); - } else { - throw_error (context, - ERROR_FAILED, - "Error fsck'ing: fsck exited with exit code %d: %s", - WEXITSTATUS (status), - stderr); - } + dbus_g_method_return (context, fs_is_clean); + } + else + { + if (job_was_cancelled) + { + throw_error (context, ERROR_CANCELLED, "Job was cancelled"); } + else + { + throw_error (context, + ERROR_FAILED, + "Error fsck'ing: fsck exited with exit code %d: %s", + WEXITSTATUS (status), + stderr); + } + } } static void -device_filesystem_check_authorized_cb (Daemon *daemon, - Device *device, - DBusGMethodInvocation *context, - const gchar *action_id, - guint num_user_data, - gpointer *user_data_elements) -{ - /* TODO: use options! */ - //gchar **options = user_data_elements[0]; - int n; - char *argv[16]; - GError *error; - - /* TODO: change when we have a file system that supports online fsck */ - if (device->priv->device_is_mounted) { - throw_error (context, - ERROR_BUSY, - "Device is mounted and no online capability in fsck tool for file system"); - goto out; - } - - n = 0; - argv[n++] = "fsck"; - argv[n++] = "-a"; - argv[n++] = device->priv->device_file; - argv[n++] = NULL; - - error = NULL; - if (!job_new (context, - "FilesystemCheck", - FALSE, - device, - argv, - NULL, - filesystem_check_completed_cb, - FALSE, - NULL, - NULL)) { - goto out; - } - -out: - ; +device_filesystem_check_authorized_cb (Daemon *daemon, + Device *device, + DBusGMethodInvocation *context, + const gchar *action_id, + guint num_user_data, + gpointer *user_data_elements) +{ + /* TODO: use options! */ + //gchar **options = user_data_elements[0]; + int n; + char *argv[16]; + GError *error; + + /* TODO: change when we have a file system that supports online fsck */ + if (device->priv->device_is_mounted) + { + throw_error (context, ERROR_BUSY, "Device is mounted and no online capability in fsck tool for file system"); + goto out; + } + + n = 0; + argv[n++] = "fsck"; + argv[n++] = "-a"; + argv[n++] = device->priv->device_file; + argv[n++] = NULL; + + error = NULL; + if (!job_new (context, "FilesystemCheck", FALSE, device, argv, NULL, filesystem_check_completed_cb, FALSE, NULL, NULL)) + { + goto out; + } + + out: + ; } gboolean -device_filesystem_check (Device *device, - char **options, - DBusGMethodInvocation *context) -{ - daemon_local_check_auth (device->priv->daemon, - device, - device->priv->device_is_system_internal ? - "org.freedesktop.devicekit.disks.filesystem-check-system-internal" : - "org.freedesktop.devicekit.disks.filesystem-check", - "FilesystemCheck", - TRUE, - device_filesystem_check_authorized_cb, - context, - 1, - g_strdupv (options), g_strfreev); - return TRUE; +device_filesystem_check (Device *device, + char **options, + DBusGMethodInvocation *context) +{ + daemon_local_check_auth (device->priv->daemon, + device, + device->priv->device_is_system_internal ? + "org.freedesktop.devicekit.disks.filesystem-check-system-internal" : + "org.freedesktop.devicekit.disks.filesystem-check", + "FilesystemCheck", + TRUE, + device_filesystem_check_authorized_cb, + context, + 1, + g_strdupv (options), + g_strfreev); + return TRUE; } /*--------------------------------------------------------------------------------------------------------------*/ @@ -5755,166 +6256,171 @@ partition_delete_completed_cb (DBusGMethodInvocation *context, const char *stdout, gpointer user_data) { - Device *enclosing_device = DEVICE (user_data); - - /* poke the kernel about the enclosing disk so we can reread the partitioning table */ - device_generate_kernel_change_event (enclosing_device); - - if (WEXITSTATUS (status) == 0 && !job_was_cancelled) { - dbus_g_method_return (context); - } else { - if (job_was_cancelled) { - throw_error (context, - ERROR_CANCELLED, - "Job was cancelled"); - } else { - throw_error (context, - ERROR_FAILED, - "Error erasing: helper exited with exit code %d: %s", - WEXITSTATUS (status), - stderr); - } + Device *enclosing_device = DEVICE (user_data); + + /* poke the kernel about the enclosing disk so we can reread the partitioning table */ + device_generate_kernel_change_event (enclosing_device); + + if (WEXITSTATUS (status) == 0 && !job_was_cancelled) + { + dbus_g_method_return (context); + } + else + { + if (job_was_cancelled) + { + throw_error (context, ERROR_CANCELLED, "Job was cancelled"); + } + else + { + throw_error (context, + ERROR_FAILED, + "Error erasing: helper exited with exit code %d: %s", + WEXITSTATUS (status), + stderr); } + } } static void -device_partition_delete_authorized_cb (Daemon *daemon, - Device *device, - DBusGMethodInvocation *context, - const gchar *action_id, - guint num_user_data, - gpointer *user_data_elements) -{ - gchar **options = user_data_elements[0]; - int n; - int m; - char *argv[16]; - GError *error; - char *offset_as_string; - char *size_as_string; - char *part_number_as_string; - Device *enclosing_device; - const gchar *partition_scheme; - gint partition_type; - - offset_as_string = NULL; - size_as_string = NULL; - part_number_as_string = NULL; - error = NULL; - - if (device_local_is_busy (device, FALSE, &error)) { - dbus_g_method_return_error (context, error); - g_error_free (error); - goto out; - } - - if (!device->priv->device_is_partition) { - throw_error (context, - ERROR_FAILED, - "Device is not a partition"); - goto out; - } - - enclosing_device = daemon_local_find_by_object_path (device->priv->daemon, - device->priv->partition_slave); - if (enclosing_device == NULL) { - throw_error (context, - ERROR_FAILED, - "Cannot find enclosing device"); - goto out; - } - - if (device_local_is_busy (enclosing_device, FALSE, &error)) { - dbus_g_method_return_error (context, error); - g_error_free (error); - goto out; - } - - /* don't allow deleting an extended partition if we have any logical partitions */ - partition_scheme = g_udev_device_get_property (device->priv->d, "UDISKS_PARTITION_SCHEME"); - partition_type = g_udev_device_get_property_as_int (device->priv->d, "UDISKS_PARTITION_TYPE"); - if (g_strcmp0 (partition_scheme, "mbr") == 0 && - (partition_type == 0x05 || partition_type == 0x0f || partition_type == 0x85)) { - if (device_has_logical_partitions (enclosing_device)) { - throw_error (context, - ERROR_FAILED, - "Cannot delete extended partition while logical partitions exist"); - goto out; - } - } +device_partition_delete_authorized_cb (Daemon *daemon, + Device *device, + DBusGMethodInvocation *context, + const gchar *action_id, + guint num_user_data, + gpointer *user_data_elements) +{ + gchar **options = user_data_elements[0]; + int n; + int m; + char *argv[16]; + GError *error; + char *offset_as_string; + char *size_as_string; + char *part_number_as_string; + Device *enclosing_device; + const gchar *partition_scheme; + gint partition_type; + + offset_as_string = NULL; + size_as_string = NULL; + part_number_as_string = NULL; + error = NULL; + + if (device_local_is_busy (device, FALSE, &error)) + { + dbus_g_method_return_error (context, error); + g_error_free (error); + goto out; + } - offset_as_string = g_strdup_printf ("%" G_GINT64_FORMAT "", device->priv->partition_offset); - size_as_string = g_strdup_printf ("%" G_GINT64_FORMAT "", device->priv->partition_size); - part_number_as_string = g_strdup_printf ("%d", device->priv->partition_number); - - n = 0; - argv[n++] = PACKAGE_LIBEXEC_DIR "/udisks-helper-delete-partition"; - argv[n++] = enclosing_device->priv->device_file; - argv[n++] = device->priv->device_file; - argv[n++] = offset_as_string; - argv[n++] = size_as_string; - argv[n++] = part_number_as_string; - for (m = 0; options[m] != NULL; m++) { - if (n >= (int) sizeof (argv) - 1) { - throw_error (context, - ERROR_FAILED, - "Too many options"); - goto out; - } - /* the helper will validate each option */ - argv[n++] = (char *) options[m]; + if (!device->priv->device_is_partition) + { + throw_error (context, ERROR_FAILED, "Device is not a partition"); + goto out; + } + + enclosing_device = daemon_local_find_by_object_path (device->priv->daemon, device->priv->partition_slave); + if (enclosing_device == NULL) + { + throw_error (context, ERROR_FAILED, "Cannot find enclosing device"); + goto out; + } + + if (device_local_is_busy (enclosing_device, FALSE, &error)) + { + dbus_g_method_return_error (context, error); + g_error_free (error); + goto out; + } + + /* don't allow deleting an extended partition if we have any logical partitions */ + partition_scheme = g_udev_device_get_property (device->priv->d, "UDISKS_PARTITION_SCHEME"); + partition_type = g_udev_device_get_property_as_int (device->priv->d, "UDISKS_PARTITION_TYPE"); + if (g_strcmp0 (partition_scheme, "mbr") == 0 && (partition_type == 0x05 || partition_type == 0x0f || partition_type + == 0x85)) + { + if (device_has_logical_partitions (enclosing_device)) + { + throw_error (context, ERROR_FAILED, "Cannot delete extended partition while logical partitions exist"); + goto out; } - argv[n++] = NULL; + } - if (!job_new (context, - "PartitionDelete", - TRUE, - device, - argv, - NULL, - partition_delete_completed_cb, - FALSE, - g_object_ref (enclosing_device), - g_object_unref)) { - goto out; + offset_as_string = g_strdup_printf ("%" G_GINT64_FORMAT "", device->priv->partition_offset); + size_as_string = g_strdup_printf ("%" G_GINT64_FORMAT "", device->priv->partition_size); + part_number_as_string = g_strdup_printf ("%d", device->priv->partition_number); + + n = 0; + argv[n++] = PACKAGE_LIBEXEC_DIR "/udisks-helper-delete-partition"; + argv[n++] = enclosing_device->priv->device_file; + argv[n++] = device->priv->device_file; + argv[n++] = offset_as_string; + argv[n++] = size_as_string; + argv[n++] = part_number_as_string; + for (m = 0; options[m] != NULL; m++) + { + if (n >= (int) sizeof(argv) - 1) + { + throw_error (context, ERROR_FAILED, "Too many options"); + goto out; } + /* the helper will validate each option */ + argv[n++] = (char *) options[m]; + } + argv[n++] = NULL; + + if (!job_new (context, + "PartitionDelete", + TRUE, + device, + argv, + NULL, + partition_delete_completed_cb, + FALSE, + g_object_ref (enclosing_device), + g_object_unref)) + { + goto out; + } -out: - g_free (offset_as_string); - g_free (size_as_string); - g_free (part_number_as_string); + out: + g_free (offset_as_string); + g_free (size_as_string); + g_free (part_number_as_string); } gboolean -device_partition_delete (Device *device, - char **options, - DBusGMethodInvocation *context) -{ - daemon_local_check_auth (device->priv->daemon, - device, - device->priv->device_is_system_internal ? - "org.freedesktop.devicekit.disks.change-system-internal" : - "org.freedesktop.devicekit.disks.change", - "PartitionDelete", - TRUE, - device_partition_delete_authorized_cb, - context, - 1, - g_strdupv (options), g_strfreev); - return TRUE; +device_partition_delete (Device *device, + char **options, + DBusGMethodInvocation *context) +{ + daemon_local_check_auth (device->priv->daemon, + device, + device->priv->device_is_system_internal ? "org.freedesktop.devicekit.disks.change-system-internal" + : "org.freedesktop.devicekit.disks.change", + "PartitionDelete", + TRUE, + device_partition_delete_authorized_cb, + context, + 1, + g_strdupv (options), + g_strfreev); + return TRUE; } /*--------------------------------------------------------------------------------------------------------------*/ -typedef struct { - FilesystemCreateHookFunc hook_func; - gpointer hook_user_data; +typedef struct +{ + FilesystemCreateHookFunc hook_func; + gpointer hook_user_data; } MkfsData; static void mkfs_data_unref (MkfsData *data) { - g_free (data); + g_free (data); } static void @@ -5926,79 +6432,88 @@ filesystem_create_completed_cb (DBusGMethodInvocation *context, const char *stdout, gpointer user_data) { - MkfsData *data = user_data; - - /* poke the kernel so we can reread the data */ - device_generate_kernel_change_event (device); - - if (WEXITSTATUS (status) == 0 && !job_was_cancelled) { - if (data->hook_func != NULL) - data->hook_func (context, device, TRUE, data->hook_user_data); - else - dbus_g_method_return (context); - } else { - if (job_was_cancelled) { - throw_error (context, - ERROR_CANCELLED, - "Job was cancelled"); - } else if (WEXITSTATUS (status) == 3) { - throw_error (context, - ERROR_FILESYSTEM_TOOLS_MISSING , - "Error creating file system: Cannot run mkfs: %s", - stderr); - } else { - throw_error (context, - ERROR_FAILED, - "Error creating file system: helper exited with exit code %d: %s", - WEXITSTATUS (status), - stderr); - } + MkfsData *data = user_data; - if (data->hook_func != NULL) - data->hook_func (context, device, FALSE, data->hook_user_data); + /* poke the kernel so we can reread the data */ + device_generate_kernel_change_event (device); + + if (WEXITSTATUS (status) == 0 && !job_was_cancelled) + { + if (data->hook_func != NULL) + data->hook_func (context, device, TRUE, data->hook_user_data); + else + dbus_g_method_return (context); + } + else + { + if (job_was_cancelled) + { + throw_error (context, ERROR_CANCELLED, "Job was cancelled"); + } + else if (WEXITSTATUS (status) == 3) + { + throw_error (context, + ERROR_FILESYSTEM_TOOLS_MISSING, + "Error creating file system: Cannot run mkfs: %s", + stderr); + } + else + { + throw_error (context, + ERROR_FAILED, + "Error creating file system: helper exited with exit code %d: %s", + WEXITSTATUS (status), + stderr); } + + if (data->hook_func != NULL) + data->hook_func (context, device, FALSE, data->hook_user_data); + } } -typedef struct { - int refcount; +typedef struct +{ + int refcount; - DBusGMethodInvocation *context; - Device *device; + DBusGMethodInvocation *context; + Device *device; - char *passphrase; + char *passphrase; - char **options; - char *fstype; + char **options; + char *fstype; - FilesystemCreateHookFunc mkfs_hook_func; - gpointer mkfs_hook_user_data; + FilesystemCreateHookFunc mkfs_hook_func; + gpointer mkfs_hook_user_data; - guint device_changed_signal_handler_id; - guint device_changed_timeout_id; + guint device_changed_signal_handler_id; + guint device_changed_timeout_id; } MkfsLuksData; static MkfsLuksData * mkfse_data_ref (MkfsLuksData *data) { - data->refcount++; - return data; + data->refcount++; + return data; } static void mkfse_data_unref (MkfsLuksData *data) { - data->refcount--; - if (data->refcount == 0) { - if (data->passphrase != NULL) { - memset (data->passphrase, '\0', strlen (data->passphrase)); - g_free (data->passphrase); - } - if (data->device != NULL) - g_object_unref (data->device); - g_strfreev (data->options); - g_free (data->fstype); - g_free (data); + data->refcount--; + if (data->refcount == 0) + { + if (data->passphrase != NULL) + { + memset (data->passphrase, '\0', strlen (data->passphrase)); + g_free (data->passphrase); } + if (data->device != NULL) + g_object_unref (data->device); + g_strfreev (data->options); + g_free (data->fstype); + g_free (data); + } } static void @@ -6006,371 +6521,379 @@ filesystem_create_wait_for_cleartext_device_hook (DBusGMethodInvocation *context Device *device, gpointer user_data) { - MkfsLuksData *data = user_data; + MkfsLuksData *data = user_data; - if (device == NULL) { - /* Dang, unlocking failed. The unlock method have already thrown an exception for us. */ - } else { - /* We're unlocked.. awesome.. Now we can _finally_ create the file system. - * What a ride. We're returning to exactly to where we came from. Back to - * the source. Only the device is different. - */ - - device_filesystem_create_internal (device, - data->fstype, - data->options, - data->mkfs_hook_func, - data->mkfs_hook_user_data, - data->context); - mkfse_data_unref (data); - } + if (device == NULL) + { + /* Dang, unlocking failed. The unlock method have already thrown an exception for us. */ + } + else + { + /* We're unlocked.. awesome.. Now we can _finally_ create the file system. + * What a ride. We're returning to exactly to where we came from. Back to + * the source. Only the device is different. + */ + + device_filesystem_create_internal (device, + data->fstype, + data->options, + data->mkfs_hook_func, + data->mkfs_hook_user_data, + data->context); + mkfse_data_unref (data); + } } static void filesystem_create_wait_for_luks_device_changed_cb (Daemon *daemon, - const char *object_path, - gpointer user_data) + const char *object_path, + gpointer user_data) { - MkfsLuksData *data = user_data; - Device *device; + MkfsLuksData *data = user_data; + Device *device; - /* check if we're now a LUKS crypto device */ - device = daemon_local_find_by_object_path (daemon, object_path); - if (device == data->device && - (device->priv->id_usage != NULL && strcmp (device->priv->id_usage, "crypto") == 0) && - (device->priv->id_type != NULL && strcmp (device->priv->id_type, "crypto_LUKS") == 0)) { + /* check if we're now a LUKS crypto device */ + device = daemon_local_find_by_object_path (daemon, object_path); + if (device == data->device && (device->priv->id_usage != NULL && strcmp (device->priv->id_usage, "crypto") == 0) + && (device->priv->id_type != NULL && strcmp (device->priv->id_type, "crypto_LUKS") == 0)) + { - /* yay! we are now set up the corresponding cleartext device */ + /* yay! we are now set up the corresponding cleartext device */ - device_luks_unlock_internal (data->device, - data->passphrase, - NULL, - filesystem_create_wait_for_cleartext_device_hook, - data, - data->context); + device_luks_unlock_internal (data->device, + data->passphrase, + NULL, + filesystem_create_wait_for_cleartext_device_hook, + data, + data->context); - g_signal_handler_disconnect (daemon, data->device_changed_signal_handler_id); - g_source_remove (data->device_changed_timeout_id); - } + g_signal_handler_disconnect (daemon, data->device_changed_signal_handler_id); + g_source_remove (data->device_changed_timeout_id); + } } static gboolean filesystem_create_wait_for_luks_device_not_seen_cb (gpointer user_data) { - MkfsLuksData *data = user_data; + MkfsLuksData *data = user_data; - throw_error (data->context, - ERROR_FAILED, - "Error creating luks encrypted file system: timeout (10s) waiting for luks device to show up"); + throw_error (data->context, + ERROR_FAILED, + "Error creating luks encrypted file system: timeout (10s) waiting for luks device to show up"); - g_signal_handler_disconnect (data->device->priv->daemon, data->device_changed_signal_handler_id); - mkfse_data_unref (data); + g_signal_handler_disconnect (data->device->priv->daemon, data->device_changed_signal_handler_id); + mkfse_data_unref (data); - return FALSE; + return FALSE; } - - static void filesystem_create_create_luks_device_completed_cb (DBusGMethodInvocation *context, - Device *device, - gboolean job_was_cancelled, - int status, - const char *stderr, - const char *stdout, - gpointer user_data) -{ - MkfsLuksData *data = user_data; - - /* poke the kernel so we can reread the data (new uuid etc.) */ - device_generate_kernel_change_event (device); - - if (WEXITSTATUS (status) == 0 && !job_was_cancelled) { - - /* OK! So we've got ourselves an luks device. Let's set it up so we can create a file - * system. Sit and wait for the change event to appear so we can setup with the right UUID. - */ - - data->device_changed_signal_handler_id = g_signal_connect_after ( - device->priv->daemon, - "device-changed", - (GCallback) filesystem_create_wait_for_luks_device_changed_cb, - mkfse_data_ref (data)); - - /* set up timeout for error reporting if waiting failed - * - * (the signal handler and the timeout handler share the ref to data - * as one will cancel the other) - */ - data->device_changed_timeout_id = g_timeout_add ( - 10 * 1000, - filesystem_create_wait_for_luks_device_not_seen_cb, - data); - - - } else { - if (job_was_cancelled) { - throw_error (context, - ERROR_CANCELLED, - "Job was cancelled"); - } else { - throw_error (context, - ERROR_FAILED, - "Error creating file system: cryptsetup exited with exit code %d: %s", - WEXITSTATUS (status), - stderr); - } + Device *device, + gboolean job_was_cancelled, + int status, + const char *stderr, + const char *stdout, + gpointer user_data) +{ + MkfsLuksData *data = user_data; + + /* poke the kernel so we can reread the data (new uuid etc.) */ + device_generate_kernel_change_event (device); + + if (WEXITSTATUS (status) == 0 && !job_was_cancelled) + { + + /* OK! So we've got ourselves an luks device. Let's set it up so we can create a file + * system. Sit and wait for the change event to appear so we can setup with the right UUID. + */ + + data->device_changed_signal_handler_id + = g_signal_connect_after (device->priv->daemon, + "device-changed", + (GCallback) filesystem_create_wait_for_luks_device_changed_cb, + mkfse_data_ref (data)); + + /* set up timeout for error reporting if waiting failed + * + * (the signal handler and the timeout handler share the ref to data + * as one will cancel the other) + */ + data->device_changed_timeout_id = g_timeout_add (10 * 1000, + filesystem_create_wait_for_luks_device_not_seen_cb, + data); + + } + else + { + if (job_was_cancelled) + { + throw_error (context, ERROR_CANCELLED, "Job was cancelled"); + } + else + { + throw_error (context, + ERROR_FAILED, + "Error creating file system: cryptsetup exited with exit code %d: %s", + WEXITSTATUS (status), + stderr); } + } } static gboolean -device_filesystem_create_internal (Device *device, - const char *fstype, - char **options, - FilesystemCreateHookFunc hook_func, - gpointer hook_user_data, - DBusGMethodInvocation *context) -{ - int n, m; - char *argv[128]; - GError *error; - char *s; - char *options_for_stdin; - char *passphrase_stdin; - MkfsData *mkfs_data; - - options_for_stdin = NULL; - passphrase_stdin = NULL; - error = NULL; - - if (device_local_is_busy (device, TRUE, &error)) { - dbus_g_method_return_error (context, error); - g_error_free (error); - goto out; - } - - if (strlen (fstype) == 0) { - throw_error (context, - ERROR_FAILED, - "fstype not specified"); - goto out; - } - - /* search for luks_encrypt= and do a detour if that's specified */ - for (n = 0; options[n] != NULL; n++) { - if (g_str_has_prefix (options[n], "luks_encrypt=")) { - MkfsLuksData *mkfse_data; - - /* So this is a request to create an luks device to put the - * file system on; save all options for mkfs (except luks_encrypt=) for - * later invocation once we have a cleartext device. - */ - - mkfse_data = g_new0 (MkfsLuksData, 1); - mkfse_data->refcount = 1; - mkfse_data->context = context; - mkfse_data->device = g_object_ref (device); - mkfse_data->passphrase = g_strdup (options[n] + sizeof ("luks_encrypt=") - 1); - mkfse_data->mkfs_hook_func = hook_func; - mkfse_data->mkfs_hook_user_data = hook_user_data; - mkfse_data->fstype = g_strdup (fstype); - mkfse_data->options = g_strdupv (options); - g_free (mkfse_data->options[n]); - for (m = n; mkfse_data->options[m] != NULL; m++) { - mkfse_data->options[m] = mkfse_data->options[m + 1]; - } - - passphrase_stdin = g_strdup_printf ("%s\n", mkfse_data->passphrase); - - n = 0; - argv[n++] = "cryptsetup"; - argv[n++] = "-q"; - argv[n++] = "luksFormat"; - argv[n++] = device->priv->device_file; - argv[n++] = NULL; - - error = NULL; - if (!job_new (context, - "LuksFormat", - TRUE, - device, - argv, - passphrase_stdin, - filesystem_create_create_luks_device_completed_cb, - FALSE, - mkfse_data, - (GDestroyNotify) mkfse_data_unref)) { - goto out; - } - - goto out; - } - } +device_filesystem_create_internal (Device *device, + const char *fstype, + char **options, + FilesystemCreateHookFunc hook_func, + gpointer hook_user_data, + DBusGMethodInvocation *context) +{ + int n, m; + char *argv[128]; + GError *error; + char *s; + char *options_for_stdin; + char *passphrase_stdin; + MkfsData *mkfs_data; - mkfs_data = g_new (MkfsData, 1); - mkfs_data->hook_func = hook_func; - mkfs_data->hook_user_data = hook_user_data; + options_for_stdin = NULL; + passphrase_stdin = NULL; + error = NULL; - /* pass options on stdin as it may contain secrets */ - s = g_strjoinv ("\n", options); - options_for_stdin = g_strconcat (s, "\n\n", NULL); - g_free (s); + if (device_local_is_busy (device, TRUE, &error)) + { + dbus_g_method_return_error (context, error); + g_error_free (error); + goto out; + } - n = 0; - argv[n++] = PACKAGE_LIBEXEC_DIR "/udisks-helper-mkfs"; - argv[n++] = (char *) fstype; - argv[n++] = device->priv->device_file; - argv[n++] = device->priv->device_is_partition_table ? "1" : "0"; - argv[n++] = NULL; + if (strlen (fstype) == 0) + { + throw_error (context, ERROR_FAILED, "fstype not specified"); + goto out; + } - if (!job_new (context, - "FilesystemCreate", - TRUE, - device, - argv, - options_for_stdin, - filesystem_create_completed_cb, - FALSE, - mkfs_data, - (GDestroyNotify) mkfs_data_unref)) { - goto out; + /* search for luks_encrypt= and do a detour if that's specified */ + for (n = 0; options[n] != NULL; n++) + { + if (g_str_has_prefix (options[n], "luks_encrypt=")) + { + MkfsLuksData *mkfse_data; + + /* So this is a request to create an luks device to put the + * file system on; save all options for mkfs (except luks_encrypt=) for + * later invocation once we have a cleartext device. + */ + + mkfse_data = g_new0 (MkfsLuksData, 1); + mkfse_data->refcount = 1; + mkfse_data->context = context; + mkfse_data->device = g_object_ref (device); + mkfse_data->passphrase = g_strdup (options[n] + sizeof("luks_encrypt=") - 1); + mkfse_data->mkfs_hook_func = hook_func; + mkfse_data->mkfs_hook_user_data = hook_user_data; + mkfse_data->fstype = g_strdup (fstype); + mkfse_data->options = g_strdupv (options); + g_free (mkfse_data->options[n]); + for (m = n; mkfse_data->options[m] != NULL; m++) + { + mkfse_data->options[m] = mkfse_data->options[m + 1]; + } + + passphrase_stdin = g_strdup_printf ("%s\n", mkfse_data->passphrase); + + n = 0; + argv[n++] = "cryptsetup"; + argv[n++] = "-q"; + argv[n++] = "luksFormat"; + argv[n++] = device->priv->device_file; + argv[n++] = NULL; + + error = NULL; + if (!job_new (context, + "LuksFormat", + TRUE, + device, + argv, + passphrase_stdin, + filesystem_create_create_luks_device_completed_cb, + FALSE, + mkfse_data, + (GDestroyNotify) mkfse_data_unref)) + { + goto out; + } + + goto out; } + } -out: - g_free (options_for_stdin); - if (passphrase_stdin != NULL) { - memset (passphrase_stdin, '\0', strlen (passphrase_stdin)); - g_free (passphrase_stdin); - } - return TRUE; + mkfs_data = g_new (MkfsData, 1); + mkfs_data->hook_func = hook_func; + mkfs_data->hook_user_data = hook_user_data; + + /* pass options on stdin as it may contain secrets */ + s = g_strjoinv ("\n", options); + options_for_stdin = g_strconcat (s, "\n\n", NULL); + g_free (s); + + n = 0; + argv[n++] = PACKAGE_LIBEXEC_DIR "/udisks-helper-mkfs"; + argv[n++] = (char *) fstype; + argv[n++] = device->priv->device_file; + argv[n++] = device->priv->device_is_partition_table ? "1" : "0"; + argv[n++] = NULL; + + if (!job_new (context, + "FilesystemCreate", + TRUE, + device, + argv, + options_for_stdin, + filesystem_create_completed_cb, + FALSE, + mkfs_data, + (GDestroyNotify) mkfs_data_unref)) + { + goto out; + } + + out: + g_free (options_for_stdin); + if (passphrase_stdin != NULL) + { + memset (passphrase_stdin, '\0', strlen (passphrase_stdin)); + g_free (passphrase_stdin); + } + return TRUE; } static void -device_filesystem_create_authorized_cb (Daemon *daemon, - Device *device, - DBusGMethodInvocation *context, - const gchar *action_id, - guint num_user_data, - gpointer *user_data_elements) +device_filesystem_create_authorized_cb (Daemon *daemon, + Device *device, + DBusGMethodInvocation *context, + const gchar *action_id, + guint num_user_data, + gpointer *user_data_elements) { - const gchar *fstype = user_data_elements[0]; - gchar **options = user_data_elements[1]; - device_filesystem_create_internal (device, fstype, options, NULL, NULL, context); + const gchar *fstype = user_data_elements[0]; + gchar **options = user_data_elements[1]; + device_filesystem_create_internal (device, fstype, options, NULL, NULL, context); } gboolean -device_filesystem_create (Device *device, - const char *fstype, - char **options, - DBusGMethodInvocation *context) -{ - daemon_local_check_auth (device->priv->daemon, - device, - device->priv->device_is_system_internal ? - "org.freedesktop.devicekit.disks.change-system-internal" : - "org.freedesktop.devicekit.disks.change", - "FilesystemCreate", - TRUE, - device_filesystem_create_authorized_cb, - context, - 2, - g_strdup (fstype), g_free, - g_strdupv (options), g_strfreev); - return TRUE; +device_filesystem_create (Device *device, + const char *fstype, + char **options, + DBusGMethodInvocation *context) +{ + daemon_local_check_auth (device->priv->daemon, + device, + device->priv->device_is_system_internal ? "org.freedesktop.devicekit.disks.change-system-internal" + : "org.freedesktop.devicekit.disks.change", + "FilesystemCreate", + TRUE, + device_filesystem_create_authorized_cb, + context, + 2, + g_strdup (fstype), + g_free, + g_strdupv (options), + g_strfreev); + return TRUE; } /*--------------------------------------------------------------------------------------------------------------*/ static void -device_job_cancel_authorized_cb (Daemon *daemon, - Device *device, - DBusGMethodInvocation *context, - const gchar *action_id, - guint num_user_data, - gpointer *user_data_elements) +device_job_cancel_authorized_cb (Daemon *daemon, + Device *device, + DBusGMethodInvocation *context, + const gchar *action_id, + guint num_user_data, + gpointer *user_data_elements) { - if (!device->priv->job_in_progress) { - throw_error (context, - ERROR_FAILED, - "There is no job to cancel"); - goto out; - } + if (!device->priv->job_in_progress) + { + throw_error (context, ERROR_FAILED, "There is no job to cancel"); + goto out; + } - if (!device->priv->job_is_cancellable) { - throw_error (context, - ERROR_FAILED, - "Job cannot be cancelled"); - goto out; - } + if (!device->priv->job_is_cancellable) + { + throw_error (context, ERROR_FAILED, "Job cannot be cancelled"); + goto out; + } - job_cancel (device); + job_cancel (device); - /* TODO: wait returning once the job is actually cancelled? */ - dbus_g_method_return (context); + /* TODO: wait returning once the job is actually cancelled? */ + dbus_g_method_return (context); out: - ; + ; } gboolean -device_job_cancel (Device *device, - DBusGMethodInvocation *context) +device_job_cancel (Device *device, + DBusGMethodInvocation *context) { - uid_t uid; - const gchar *action_id; + uid_t uid; + const gchar *action_id; - if (!device->priv->job_in_progress) { - throw_error (context, - ERROR_FAILED, - "There is no job to cancel"); - goto out; - } + if (!device->priv->job_in_progress) + { + throw_error (context, ERROR_FAILED, "There is no job to cancel"); + goto out; + } - if (!device->priv->job_is_cancellable) { - throw_error (context, - ERROR_FAILED, - "Job cannot be cancelled"); - goto out; - } + if (!device->priv->job_is_cancellable) + { + throw_error (context, ERROR_FAILED, "Job cannot be cancelled"); + goto out; + } - daemon_local_get_uid (device->priv->daemon, &uid, context); + daemon_local_get_uid (device->priv->daemon, &uid, context); - action_id = NULL; - if (device->priv->job_initiated_by_uid != uid) { - action_id = "org.freedesktop.devicekit.disks.cancel-job-others"; - } + action_id = NULL; + if (device->priv->job_initiated_by_uid != uid) + { + action_id = "org.freedesktop.devicekit.disks.cancel-job-others"; + } - daemon_local_check_auth (device->priv->daemon, - device, - action_id, - "JobCancel", - TRUE, - device_job_cancel_authorized_cb, - context, - 0); + daemon_local_check_auth (device->priv->daemon, + device, + action_id, + "JobCancel", + TRUE, + device_job_cancel_authorized_cb, + context, + 0); out: - return TRUE; + return TRUE; } /*--------------------------------------------------------------------------------------------------------------*/ -typedef struct { - int refcount; +typedef struct +{ + int refcount; - guint device_added_signal_handler_id; - guint device_added_timeout_id; + guint device_added_signal_handler_id; + guint device_added_timeout_id; - DBusGMethodInvocation *context; - Device *device; - guint64 offset; - guint64 size; + DBusGMethodInvocation *context; + Device *device; + guint64 offset; + guint64 size; - guint64 created_offset; - guint64 created_size; + guint64 created_offset; + guint64 created_size; - char *fstype; - char **fsoptions; + char *fstype; + char **fsoptions; } CreatePartitionData; @@ -6382,38 +6905,39 @@ partition_create_data_new (DBusGMethodInvocation *context, const char *fstype, char **fsoptions) { - CreatePartitionData *data; + CreatePartitionData *data; - data = g_new0 (CreatePartitionData, 1); - data->refcount = 1; + data = g_new0 (CreatePartitionData, 1); + data->refcount = 1; - data->context = context; - data->device = g_object_ref (device); - data->offset = offset; - data->size = size; - data->fstype = g_strdup (fstype); - data->fsoptions = g_strdupv (fsoptions); + data->context = context; + data->device = g_object_ref (device); + data->offset = offset; + data->size = size; + data->fstype = g_strdup (fstype); + data->fsoptions = g_strdupv (fsoptions); - return data; + return data; } static CreatePartitionData * partition_create_data_ref (CreatePartitionData *data) { - data->refcount++; - return data; + data->refcount++; + return data; } static void partition_create_data_unref (CreatePartitionData *data) { - data->refcount--; - if (data->refcount == 0) { - g_object_unref (data->device); - g_free (data->fstype); - g_strfreev (data->fsoptions); - g_free (data); - } + data->refcount--; + if (data->refcount == 0) + { + g_object_unref (data->device); + g_free (data->fstype); + g_strfreev (data->fsoptions); + g_free (data); + } } static void @@ -6422,28 +6946,34 @@ partition_create_filesystem_create_hook (DBusGMethodInvocation *context, gboolean filesystem_create_succeeded, gpointer user_data) { - if (!filesystem_create_succeeded) { - /* dang.. FilesystemCreate already reported an error */ - } else { - /* it worked.. */ - dbus_g_method_return (context, device->priv->object_path); - } + if (!filesystem_create_succeeded) + { + /* dang.. FilesystemCreate already reported an error */ + } + else + { + /* it worked.. */ + dbus_g_method_return (context, device->priv->object_path); + } } static void -partition_create_found_device (Device *device, +partition_create_found_device (Device *device, CreatePartitionData *data) { - if (strlen (data->fstype) > 0) { - device_filesystem_create_internal (device, - data->fstype, - data->fsoptions, - partition_create_filesystem_create_hook, - NULL, - data->context); - } else { - dbus_g_method_return (data->context, device->priv->object_path); - } + if (strlen (data->fstype) > 0) + { + device_filesystem_create_internal (device, + data->fstype, + data->fsoptions, + partition_create_filesystem_create_hook, + NULL, + data->context); + } + else + { + dbus_g_method_return (data->context, device->priv->object_path); + } } static void @@ -6451,39 +6981,36 @@ partition_create_device_added_cb (Daemon *daemon, const char *object_path, gpointer user_data) { - CreatePartitionData *data = user_data; - Device *device; + CreatePartitionData *data = user_data; + Device *device; - /* check the device added is the partition we've created */ - device = daemon_local_find_by_object_path (daemon, object_path); - if (device != NULL && - device->priv->device_is_partition && - strcmp (device->priv->partition_slave, data->device->priv->object_path) == 0 && - data->created_offset == device->priv->partition_offset && - data->created_size == device->priv->partition_size) { + /* check the device added is the partition we've created */ + device = daemon_local_find_by_object_path (daemon, object_path); + if (device != NULL && device->priv->device_is_partition && strcmp (device->priv->partition_slave, + data->device->priv->object_path) == 0 + && data->created_offset == device->priv->partition_offset && data->created_size == device->priv->partition_size) + { - /* yay! it is.. now create the file system if requested */ - partition_create_found_device (device, data); + /* yay! it is.. now create the file system if requested */ + partition_create_found_device (device, data); - g_signal_handler_disconnect (daemon, data->device_added_signal_handler_id); - g_source_remove (data->device_added_timeout_id); - partition_create_data_unref (data); - } + g_signal_handler_disconnect (daemon, data->device_added_signal_handler_id); + g_source_remove (data->device_added_timeout_id); + partition_create_data_unref (data); + } } static gboolean partition_create_device_not_seen_cb (gpointer user_data) { - CreatePartitionData *data = user_data; + CreatePartitionData *data = user_data; - throw_error (data->context, - ERROR_FAILED, - "Error creating partition: timeout (10s) waiting for partition to show up"); + throw_error (data->context, ERROR_FAILED, "Error creating partition: timeout (10s) waiting for partition to show up"); - g_signal_handler_disconnect (data->device->priv->daemon, data->device_added_signal_handler_id); - partition_create_data_unref (data); + g_signal_handler_disconnect (data->device->priv->daemon, data->device_added_signal_handler_id); + partition_create_data_unref (data); - return FALSE; + return FALSE; } static void @@ -6495,255 +7022,273 @@ partition_create_completed_cb (DBusGMethodInvocation *context, const char *stdout, gpointer user_data) { - CreatePartitionData *data = user_data; - - /* poke the kernel so we can reread the data */ - device_generate_kernel_change_event (device); - - if (WEXITSTATUS (status) == 0 && !job_was_cancelled) { - int n; - int m; - guint64 offset; - guint64 size; - char **tokens; - - /* Find the - * - * job-create-partition-offset: - * job-create-partition-size: - * - * lines and parse the new start and end. We need this - * for waiting on the created partition (since the requested - * start and size passed may not be honored due to disk/cylinder/sector - * alignment reasons). - */ - offset = 0; - size = 0; - m = 0; - tokens = g_strsplit (stderr, "\n", 0); - for (n = 0; tokens[n] != NULL; n++) { - char *line = tokens[n]; - char *endp; - - if (m == 2) - break; - - if (g_str_has_prefix (line, "job-create-partition-offset: ")) { - offset = strtoll (line + sizeof ("job-create-partition-offset: ") - 1, &endp, 10); - if (*endp == '\0') - m++; - } else if (g_str_has_prefix (line, "job-create-partition-size: ")) { - size = strtoll (line + sizeof ("job-create-partition-size: ") - 1, &endp, 10); - if (*endp == '\0') - m++; - } - } - g_strfreev (tokens); - - if (m != 2) { - throw_error (context, - ERROR_FAILED, - "Error creating partition: internal error, expected to find new " - "start and end but m=%d", m); - } else { - gboolean found_device; - GList *devices; - GList *l; - - data->created_offset = offset; - data->created_size = size; - - /* check if the device is already there */ - found_device = FALSE; - devices = daemon_local_get_all_devices (device->priv->daemon); - for (l = devices; l != NULL; l = l->next) { - Device *d = DEVICE (l->data); - - if (d->priv->device_is_partition && - strcmp (d->priv->partition_slave, data->device->priv->object_path) == 0 && - data->created_offset == d->priv->partition_offset && - data->created_size == d->priv->partition_size) { - /* yay! it is.. now create the file system if requested */ - partition_create_found_device (d, data); - found_device = TRUE; - break; - } - } - - if (!found_device) { - /* otherwise sit around and wait for the new partition to appear */ - data->device_added_signal_handler_id = g_signal_connect_after ( - device->priv->daemon, - "device-added", - (GCallback) partition_create_device_added_cb, - partition_create_data_ref (data)); - - /* set up timeout for error reporting if waiting failed - * - * (the signal handler and the timeout handler share the ref to data - * as one will cancel the other) - */ - data->device_added_timeout_id = g_timeout_add (10 * 1000, - partition_create_device_not_seen_cb, - data); - } - } - } else { - if (job_was_cancelled) { - throw_error (context, - ERROR_CANCELLED, - "Job was cancelled"); - } else { - throw_error (context, - ERROR_FAILED, - "Error creating partition: helper exited with exit code %d: %s", - WEXITSTATUS (status), - stderr); - } + CreatePartitionData *data = user_data; + + /* poke the kernel so we can reread the data */ + device_generate_kernel_change_event (device); + + if (WEXITSTATUS (status) == 0 && !job_was_cancelled) + { + int n; + int m; + guint64 offset; + guint64 size; + char **tokens; + + /* Find the + * + * job-create-partition-offset: + * job-create-partition-size: + * + * lines and parse the new start and end. We need this + * for waiting on the created partition (since the requested + * start and size passed may not be honored due to disk/cylinder/sector + * alignment reasons). + */ + offset = 0; + size = 0; + m = 0; + tokens = g_strsplit (stderr, "\n", 0); + for (n = 0; tokens[n] != NULL; n++) + { + char *line = tokens[n]; + char *endp; + + if (m == 2) + break; + + if (g_str_has_prefix (line, "job-create-partition-offset: ")) + { + offset = strtoll (line + sizeof("job-create-partition-offset: ") - 1, &endp, 10); + if (*endp == '\0') + m++; + } + else if (g_str_has_prefix (line, "job-create-partition-size: ")) + { + size = strtoll (line + sizeof("job-create-partition-size: ") - 1, &endp, 10); + if (*endp == '\0') + m++; + } + } + g_strfreev (tokens); + + if (m != 2) + { + throw_error (context, ERROR_FAILED, "Error creating partition: internal error, expected to find new " + "start and end but m=%d", m); + } + else + { + gboolean found_device; + GList *devices; + GList *l; + + data->created_offset = offset; + data->created_size = size; + + /* check if the device is already there */ + found_device = FALSE; + devices = daemon_local_get_all_devices (device->priv->daemon); + for (l = devices; l != NULL; l = l->next) + { + Device *d = DEVICE (l->data); + + if (d->priv->device_is_partition && strcmp (d->priv->partition_slave, data->device->priv->object_path) + == 0 && data->created_offset == d->priv->partition_offset && data->created_size + == d->priv->partition_size) + { + /* yay! it is.. now create the file system if requested */ + partition_create_found_device (d, data); + found_device = TRUE; + break; + } + } + + if (!found_device) + { + /* otherwise sit around and wait for the new partition to appear */ + data->device_added_signal_handler_id + = g_signal_connect_after (device->priv->daemon, + "device-added", + (GCallback) partition_create_device_added_cb, + partition_create_data_ref (data)); + + /* set up timeout for error reporting if waiting failed + * + * (the signal handler and the timeout handler share the ref to data + * as one will cancel the other) + */ + data->device_added_timeout_id = g_timeout_add (10 * 1000, partition_create_device_not_seen_cb, data); + } + } + } + else + { + if (job_was_cancelled) + { + throw_error (context, ERROR_CANCELLED, "Job was cancelled"); + } + else + { + throw_error (context, + ERROR_FAILED, + "Error creating partition: helper exited with exit code %d: %s", + WEXITSTATUS (status), + stderr); } + } } static void -device_partition_create_authorized_cb (Daemon *daemon, - Device *device, - DBusGMethodInvocation *context, - const gchar *action_id, - guint num_user_data, - gpointer *user_data_elements) -{ - guint64 offset = *((guint64*) user_data_elements[0]); - guint64 size = *((guint64*) user_data_elements[1]);; - const char *type = user_data_elements[2]; - const char *label = user_data_elements[3]; - char **flags = user_data_elements[4]; - char **options = user_data_elements[5]; - const char *fstype = user_data_elements[6]; - char **fsoptions = user_data_elements[7]; - int n; - int m; - char *argv[128]; - GError *error; - char *offset_as_string; - char *size_as_string; - char *flags_as_string; - - offset_as_string = NULL; - size_as_string = NULL; - flags_as_string = NULL; - error = NULL; - - if (!device->priv->device_is_partition_table) { - throw_error (context, - ERROR_FAILED, - "Device is not partitioned"); - goto out; - } - - if (device_local_is_busy (device, FALSE, &error)) { - dbus_g_method_return_error (context, error); - g_error_free (error); - goto out; - } - - /* partutil.c / libparted will check there are no partitions in the requested slice */ - - offset_as_string = g_strdup_printf ("%" G_GINT64_FORMAT "", offset); - size_as_string = g_strdup_printf ("%" G_GINT64_FORMAT "", size); - /* TODO: check that neither of the flags include ',' */ - flags_as_string = g_strjoinv (",", flags); - - n = 0; - argv[n++] = PACKAGE_LIBEXEC_DIR "/udisks-helper-create-partition"; - argv[n++] = device->priv->device_file;; - argv[n++] = offset_as_string; - argv[n++] = size_as_string; - argv[n++] = (char *) type; - argv[n++] = (char *) label; - argv[n++] = (char *) flags_as_string; - for (m = 0; options[m] != NULL; m++) { - if (n >= (int) sizeof (argv) - 1) { - throw_error (context, - ERROR_FAILED, - "Too many options"); - goto out; - } - /* the helper will validate each option */ - argv[n++] = (char *) options[m]; - } - argv[n++] = NULL; +device_partition_create_authorized_cb (Daemon *daemon, + Device *device, + DBusGMethodInvocation *context, + const gchar *action_id, + guint num_user_data, + gpointer *user_data_elements) +{ + guint64 offset = *((guint64*) user_data_elements[0]); + guint64 size = *((guint64*) user_data_elements[1]); + ; + const char *type = user_data_elements[2]; + const char *label = user_data_elements[3]; + char **flags = user_data_elements[4]; + char **options = user_data_elements[5]; + const char *fstype = user_data_elements[6]; + char **fsoptions = user_data_elements[7]; + int n; + int m; + char *argv[128]; + GError *error; + char *offset_as_string; + char *size_as_string; + char *flags_as_string; + + offset_as_string = NULL; + size_as_string = NULL; + flags_as_string = NULL; + error = NULL; + + if (!device->priv->device_is_partition_table) + { + throw_error (context, ERROR_FAILED, "Device is not partitioned"); + goto out; + } + + if (device_local_is_busy (device, FALSE, &error)) + { + dbus_g_method_return_error (context, error); + g_error_free (error); + goto out; + } - if (!job_new (context, - "PartitionCreate", - TRUE, - device, - argv, - NULL, - partition_create_completed_cb, - FALSE, - partition_create_data_new (context, device, offset, size, fstype, fsoptions), - (GDestroyNotify) partition_create_data_unref)) { - goto out; + /* partutil.c / libparted will check there are no partitions in the requested slice */ + + offset_as_string = g_strdup_printf ("%" G_GINT64_FORMAT "", offset); + size_as_string = g_strdup_printf ("%" G_GINT64_FORMAT "", size); + /* TODO: check that neither of the flags include ',' */ + flags_as_string = g_strjoinv (",", flags); + + n = 0; + argv[n++] = PACKAGE_LIBEXEC_DIR "/udisks-helper-create-partition"; + argv[n++] = device->priv->device_file; + ; + argv[n++] = offset_as_string; + argv[n++] = size_as_string; + argv[n++] = (char *) type; + argv[n++] = (char *) label; + argv[n++] = (char *) flags_as_string; + for (m = 0; options[m] != NULL; m++) + { + if (n >= (int) sizeof(argv) - 1) + { + throw_error (context, ERROR_FAILED, "Too many options"); + goto out; } + /* the helper will validate each option */ + argv[n++] = (char *) options[m]; + } + argv[n++] = NULL; + + if (!job_new (context, + "PartitionCreate", + TRUE, + device, + argv, + NULL, + partition_create_completed_cb, + FALSE, + partition_create_data_new (context, device, offset, size, fstype, fsoptions), + (GDestroyNotify) partition_create_data_unref)) + { + goto out; + } -out: - g_free (offset_as_string); - g_free (size_as_string); - g_free (flags_as_string); + out: + g_free (offset_as_string); + g_free (size_as_string); + g_free (flags_as_string); } gboolean -device_partition_create (Device *device, - guint64 offset, - guint64 size, - const char *type, - const char *label, - char **flags, - char **options, - const char *fstype, - char **fsoptions, - DBusGMethodInvocation *context) -{ - if (!device->priv->device_is_partition_table) { - throw_error (context, - ERROR_FAILED, - "Device is not partitioned"); - goto out; - } - - daemon_local_check_auth (device->priv->daemon, - device, - device->priv->device_is_system_internal ? - "org.freedesktop.devicekit.disks.change-system-internal" : - "org.freedesktop.devicekit.disks.change", - "PartitionCreate", - TRUE, - device_partition_create_authorized_cb, - context, - 8, - g_memdup (&offset, sizeof (guint64)), g_free, - g_memdup (&size, sizeof (guint64)), g_free, - g_strdup (type), g_free, - g_strdup (label), g_free, - g_strdupv (flags), g_strfreev, - g_strdupv (options), g_strfreev, - g_strdup (fstype), g_free, - g_strdupv (fsoptions), g_strfreev); +device_partition_create (Device *device, + guint64 offset, + guint64 size, + const char *type, + const char *label, + char **flags, + char **options, + const char *fstype, + char **fsoptions, + DBusGMethodInvocation *context) +{ + if (!device->priv->device_is_partition_table) + { + throw_error (context, ERROR_FAILED, "Device is not partitioned"); + goto out; + } + + daemon_local_check_auth (device->priv->daemon, + device, + device->priv->device_is_system_internal ? "org.freedesktop.devicekit.disks.change-system-internal" + : "org.freedesktop.devicekit.disks.change", + "PartitionCreate", + TRUE, + device_partition_create_authorized_cb, + context, + 8, + g_memdup (&offset, sizeof(guint64)), + g_free, + g_memdup (&size, sizeof(guint64)), + g_free, + g_strdup (type), + g_free, + g_strdup (label), + g_free, + g_strdupv (flags), + g_strfreev, + g_strdupv (options), + g_strfreev, + g_strdup (fstype), + g_free, + g_strdupv (fsoptions), + g_strfreev); out: - return TRUE; + return TRUE; } - /*--------------------------------------------------------------------------------------------------------------*/ -typedef struct { - DBusGMethodInvocation *context; - Device *device; - Device *enclosing_device; +typedef struct +{ + DBusGMethodInvocation *context; + Device *device; + Device *enclosing_device; - char *type; - char *label; - char **flags; + char *type; + char *label; + char **flags; } ModifyPartitionData; static ModifyPartitionData * @@ -6754,29 +7299,29 @@ partition_modify_data_new (DBusGMethodInvocation *context, const char *label, char **flags) { - ModifyPartitionData *data; + ModifyPartitionData *data; - data = g_new0 (ModifyPartitionData, 1); + data = g_new0 (ModifyPartitionData, 1); - data->context = context; - data->device = g_object_ref (device); - data->enclosing_device = g_object_ref (enclosing_device); - data->type = g_strdup (type); - data->label = g_strdup (label); - data->flags = g_strdupv (flags); + data->context = context; + data->device = g_object_ref (device); + data->enclosing_device = g_object_ref (enclosing_device); + data->type = g_strdup (type); + data->label = g_strdup (label); + data->flags = g_strdupv (flags); - return data; + return data; } static void partition_modify_data_unref (ModifyPartitionData *data) { - g_object_unref (data->device); - g_object_unref (data->enclosing_device); - g_free (data->type); - g_free (data->label); - g_free (data->flags); - g_free (data); + g_object_unref (data->device); + g_object_unref (data->enclosing_device); + g_free (data->type); + g_free (data->label); + g_free (data->flags); + g_free (data); } static void @@ -6788,169 +7333,173 @@ partition_modify_completed_cb (DBusGMethodInvocation *context, const char *stdout, gpointer user_data) { - ModifyPartitionData *data = user_data; + ModifyPartitionData *data = user_data; - /* poke the kernel so we can reread the data */ - device_generate_kernel_change_event (data->enclosing_device); - device_generate_kernel_change_event (data->device); + /* poke the kernel so we can reread the data */ + device_generate_kernel_change_event (data->enclosing_device); + device_generate_kernel_change_event (data->device); - if (WEXITSTATUS (status) == 0 && !job_was_cancelled) { - /* update local copy, don't wait for the kernel */ + if (WEXITSTATUS (status) == 0 && !job_was_cancelled) + { + /* update local copy, don't wait for the kernel */ - device_set_partition_type (device, data->type); - device_set_partition_label (device, data->label); - device_set_partition_flags (device, data->flags); + device_set_partition_type (device, data->type); + device_set_partition_label (device, data->label); + device_set_partition_flags (device, data->flags); - drain_pending_changes (device, FALSE); + drain_pending_changes (device, FALSE); - dbus_g_method_return (context); + dbus_g_method_return (context); - } else { - if (job_was_cancelled) { - throw_error (context, - ERROR_CANCELLED, - "Job was cancelled"); - } else { - throw_error (context, - ERROR_FAILED, - "Error modifying partition: helper exited with exit code %d: %s", - WEXITSTATUS (status), - stderr); - } + } + else + { + if (job_was_cancelled) + { + throw_error (context, ERROR_CANCELLED, "Job was cancelled"); + } + else + { + throw_error (context, + ERROR_FAILED, + "Error modifying partition: helper exited with exit code %d: %s", + WEXITSTATUS (status), + stderr); } + } } static void -device_partition_modify_authorized_cb (Daemon *daemon, - Device *device, - DBusGMethodInvocation *context, - const gchar *action_id, - guint num_user_data, - gpointer *user_data_elements) -{ - const char *type = user_data_elements[0]; - const char *label = user_data_elements[1]; - char **flags = user_data_elements[2]; - int n; - char *argv[128]; - GError *error; - char *offset_as_string; - char *size_as_string; - char *flags_as_string; - Device *enclosing_device; - - offset_as_string = NULL; - size_as_string = NULL; - flags_as_string = NULL; - error = NULL; - - if (!device->priv->device_is_partition) { - throw_error (context, - ERROR_FAILED, - "Device is not a partition"); - goto out; - } - - enclosing_device = daemon_local_find_by_object_path (device->priv->daemon, - device->priv->partition_slave); - if (enclosing_device == NULL) { - throw_error (context, - ERROR_FAILED, - "Cannot find enclosing device"); - goto out; - } - - if (device_local_is_busy (enclosing_device, FALSE, &error)) { - dbus_g_method_return_error (context, error); - g_error_free (error); - goto out; - } - - if (strlen (type) == 0) { - throw_error (context, - ERROR_FAILED, - "type not specified"); - goto out; - } - - offset_as_string = g_strdup_printf ("%" G_GINT64_FORMAT "", device->priv->partition_offset); - size_as_string = g_strdup_printf ("%" G_GINT64_FORMAT "", device->priv->partition_size); - /* TODO: check that neither of the flags include ',' */ - flags_as_string = g_strjoinv (",", flags); - - n = 0; - argv[n++] = PACKAGE_LIBEXEC_DIR "/udisks-helper-modify-partition"; - argv[n++] = enclosing_device->priv->device_file; - argv[n++] = offset_as_string; - argv[n++] = size_as_string; - argv[n++] = (char *) type; - argv[n++] = (char *) label; - argv[n++] = (char *) flags_as_string; - argv[n++] = NULL; - - if (!job_new (context, - "PartitionModify", - TRUE, - device, - argv, - NULL, - partition_modify_completed_cb, - FALSE, - partition_modify_data_new (context, device, enclosing_device, type, label, flags), - (GDestroyNotify) partition_modify_data_unref)) { - goto out; - } - -out: - g_free (offset_as_string); - g_free (size_as_string); - g_free (flags_as_string); +device_partition_modify_authorized_cb (Daemon *daemon, + Device *device, + DBusGMethodInvocation *context, + const gchar *action_id, + guint num_user_data, + gpointer *user_data_elements) +{ + const char *type = user_data_elements[0]; + const char *label = user_data_elements[1]; + char **flags = user_data_elements[2]; + int n; + char *argv[128]; + GError *error; + char *offset_as_string; + char *size_as_string; + char *flags_as_string; + Device *enclosing_device; + + offset_as_string = NULL; + size_as_string = NULL; + flags_as_string = NULL; + error = NULL; + + if (!device->priv->device_is_partition) + { + throw_error (context, ERROR_FAILED, "Device is not a partition"); + goto out; + } + + enclosing_device = daemon_local_find_by_object_path (device->priv->daemon, device->priv->partition_slave); + if (enclosing_device == NULL) + { + throw_error (context, ERROR_FAILED, "Cannot find enclosing device"); + goto out; + } + + if (device_local_is_busy (enclosing_device, FALSE, &error)) + { + dbus_g_method_return_error (context, error); + g_error_free (error); + goto out; + } + + if (strlen (type) == 0) + { + throw_error (context, ERROR_FAILED, "type not specified"); + goto out; + } + + offset_as_string = g_strdup_printf ("%" G_GINT64_FORMAT "", device->priv->partition_offset); + size_as_string = g_strdup_printf ("%" G_GINT64_FORMAT "", device->priv->partition_size); + /* TODO: check that neither of the flags include ',' */ + flags_as_string = g_strjoinv (",", flags); + + n = 0; + argv[n++] = PACKAGE_LIBEXEC_DIR "/udisks-helper-modify-partition"; + argv[n++] = enclosing_device->priv->device_file; + argv[n++] = offset_as_string; + argv[n++] = size_as_string; + argv[n++] = (char *) type; + argv[n++] = (char *) label; + argv[n++] = (char *) flags_as_string; + argv[n++] = NULL; + + if (!job_new (context, + "PartitionModify", + TRUE, + device, + argv, + NULL, + partition_modify_completed_cb, + FALSE, + partition_modify_data_new (context, device, enclosing_device, type, label, flags), + (GDestroyNotify) partition_modify_data_unref)) + { + goto out; + } + + out: + g_free (offset_as_string); + g_free (size_as_string); + g_free (flags_as_string); } gboolean -device_partition_modify (Device *device, - const char *type, - const char *label, - char **flags, - DBusGMethodInvocation *context) -{ - if (!device->priv->device_is_partition) { - throw_error (context, - ERROR_FAILED, - "Device is not a partition"); - goto out; - } - - daemon_local_check_auth (device->priv->daemon, - device, - device->priv->device_is_system_internal ? - "org.freedesktop.devicekit.disks.change-system-internal" : - "org.freedesktop.devicekit.disks.change", - "PartitionModify", - TRUE, - device_partition_modify_authorized_cb, - context, - 3, - g_strdup (type), g_free, - g_strdup (label), g_free, - g_strdupv (flags), g_strfreev); +device_partition_modify (Device *device, + const char *type, + const char *label, + char **flags, + DBusGMethodInvocation *context) +{ + if (!device->priv->device_is_partition) + { + throw_error (context, ERROR_FAILED, "Device is not a partition"); + goto out; + } + + daemon_local_check_auth (device->priv->daemon, + device, + device->priv->device_is_system_internal ? "org.freedesktop.devicekit.disks.change-system-internal" + : "org.freedesktop.devicekit.disks.change", + "PartitionModify", + TRUE, + device_partition_modify_authorized_cb, + context, + 3, + g_strdup (type), + g_free, + g_strdup (label), + g_free, + g_strdupv (flags), + g_strfreev); out: - return TRUE; + return TRUE; } /*--------------------------------------------------------------------------------------------------------------*/ -typedef struct { - int refcount; +typedef struct +{ + int refcount; - guint device_changed_signal_handler_id; - guint device_changed_timeout_id; + guint device_changed_signal_handler_id; + guint device_changed_timeout_id; - DBusGMethodInvocation *context; - Device *device; + DBusGMethodInvocation *context; + Device *device; - char *scheme; + char *scheme; } CreatePartitionTableData; @@ -6959,34 +7508,35 @@ partition_table_create_data_new (DBusGMethodInvocation *context, Device *device, const char *scheme) { - CreatePartitionTableData *data; + CreatePartitionTableData *data; - data = g_new0 (CreatePartitionTableData, 1); - data->refcount = 1; + data = g_new0 (CreatePartitionTableData, 1); + data->refcount = 1; - data->context = context; - data->device = g_object_ref (device); - data->scheme = g_strdup (scheme); + data->context = context; + data->device = g_object_ref (device); + data->scheme = g_strdup (scheme); - return data; + return data; } static CreatePartitionTableData * partition_table_create_data_ref (CreatePartitionTableData *data) { - data->refcount++; - return data; + data->refcount++; + return data; } static void partition_table_create_data_unref (CreatePartitionTableData *data) { - data->refcount--; - if (data->refcount == 0) { - g_object_unref (data->device); - g_free (data->scheme); - g_free (data); - } + data->refcount--; + if (data->refcount == 0) + { + g_object_unref (data->device); + g_free (data->scheme); + g_free (data); + } } static void @@ -6994,35 +7544,35 @@ partition_table_create_device_changed_cb (Daemon *daemon, const char *object_path, gpointer user_data) { - CreatePartitionTableData *data = user_data; - Device *device; + CreatePartitionTableData *data = user_data; + Device *device; - device = daemon_local_find_by_object_path (daemon, object_path); - if (device == data->device) { - if (g_strcmp0 (device->priv->partition_table_scheme, data->scheme) == 0 || - (device->priv->partition_table_scheme == NULL && g_strcmp0 (data->scheme, "none") == 0)) { - dbus_g_method_return (data->context); + device = daemon_local_find_by_object_path (daemon, object_path); + if (device == data->device) + { + if (g_strcmp0 (device->priv->partition_table_scheme, data->scheme) == 0 || (device->priv->partition_table_scheme + == NULL && g_strcmp0 (data->scheme, "none") == 0)) + { + dbus_g_method_return (data->context); - g_signal_handler_disconnect (daemon, data->device_changed_signal_handler_id); - g_source_remove (data->device_changed_timeout_id); - partition_table_create_data_unref (data); - } + g_signal_handler_disconnect (daemon, data->device_changed_signal_handler_id); + g_source_remove (data->device_changed_timeout_id); + partition_table_create_data_unref (data); } + } } static gboolean partition_table_create_device_not_changed_cb (gpointer user_data) { - CreatePartitionTableData *data = user_data; + CreatePartitionTableData *data = user_data; - throw_error (data->context, - ERROR_FAILED, - "Error creating partition table: timeout (10s) waiting for change"); + throw_error (data->context, ERROR_FAILED, "Error creating partition table: timeout (10s) waiting for change"); - g_signal_handler_disconnect (data->device->priv->daemon, data->device_changed_signal_handler_id); - partition_table_create_data_unref (data); + g_signal_handler_disconnect (data->device->priv->daemon, data->device_changed_signal_handler_id); + partition_table_create_data_unref (data); - return FALSE; + return FALSE; } static void @@ -7034,130 +7584,139 @@ partition_table_create_completed_cb (DBusGMethodInvocation *context, const char *stdout, gpointer user_data) { - CreatePartitionTableData *data = user_data; - - /* poke the kernel so we can reread the data */ - device_generate_kernel_change_event (device); - - if (WEXITSTATUS (status) == 0 && !job_was_cancelled) { - - if (g_strcmp0 (device->priv->partition_table_scheme, data->scheme) == 0) { - dbus_g_method_return (context); - } else { - /* sit around and wait for the new partition table to appear */ - data->device_changed_signal_handler_id = g_signal_connect_after ( - device->priv->daemon, - "device-changed", - (GCallback) partition_table_create_device_changed_cb, - partition_table_create_data_ref (data)); - - /* set up timeout for error reporting if waiting failed - * - * (the signal handler and the timeout handler share the ref to data - * as one will cancel the other) - */ - data->device_changed_timeout_id = g_timeout_add (10 * 1000, - partition_table_create_device_not_changed_cb, - data); - } + CreatePartitionTableData *data = user_data; - } else { - if (job_was_cancelled) { - throw_error (context, - ERROR_CANCELLED, - "Job was cancelled"); - } else { - throw_error (context, - ERROR_FAILED, - "Error creating partition table: helper exited with exit code %d: %s", - WEXITSTATUS (status), - stderr); - } + /* poke the kernel so we can reread the data */ + device_generate_kernel_change_event (device); + + if (WEXITSTATUS (status) == 0 && !job_was_cancelled) + { + + if (g_strcmp0 (device->priv->partition_table_scheme, data->scheme) == 0) + { + dbus_g_method_return (context); + } + else + { + /* sit around and wait for the new partition table to appear */ + data->device_changed_signal_handler_id + = g_signal_connect_after (device->priv->daemon, + "device-changed", + (GCallback) partition_table_create_device_changed_cb, + partition_table_create_data_ref (data)); + + /* set up timeout for error reporting if waiting failed + * + * (the signal handler and the timeout handler share the ref to data + * as one will cancel the other) + */ + data->device_changed_timeout_id = g_timeout_add (10 * 1000, + partition_table_create_device_not_changed_cb, + data); + } + + } + else + { + if (job_was_cancelled) + { + throw_error (context, ERROR_CANCELLED, "Job was cancelled"); + } + else + { + throw_error (context, + ERROR_FAILED, + "Error creating partition table: helper exited with exit code %d: %s", + WEXITSTATUS (status), + stderr); } + } } static void -device_partition_table_create_authorized_cb (Daemon *daemon, - Device *device, - DBusGMethodInvocation *context, - const gchar *action_id, - guint num_user_data, - gpointer *user_data_elements) -{ - const char *scheme = user_data_elements[0]; - char **options = user_data_elements[1]; - int n; - int m; - char *argv[128]; - GError *error; - - error = NULL; - - if (device_local_is_busy (device, TRUE, &error)) { - dbus_g_method_return_error (context, error); - g_error_free (error); - goto out; - } - - if (strlen (scheme) == 0) { - throw_error (context, - ERROR_FAILED, - "type not specified"); - goto out; - } - - n = 0; - argv[n++] = PACKAGE_LIBEXEC_DIR "/udisks-helper-create-partition-table"; - argv[n++] = device->priv->device_file; - argv[n++] = (char *) scheme; - for (m = 0; options[m] != NULL; m++) { - if (n >= (int) sizeof (argv) - 1) { - throw_error (context, - ERROR_FAILED, - "Too many options"); - goto out; - } - /* the helper will validate each option */ - argv[n++] = (char *) options[m]; - } - argv[n++] = NULL; +device_partition_table_create_authorized_cb (Daemon *daemon, + Device *device, + DBusGMethodInvocation *context, + const gchar *action_id, + guint num_user_data, + gpointer *user_data_elements) +{ + const char *scheme = user_data_elements[0]; + char **options = user_data_elements[1]; + int n; + int m; + char *argv[128]; + GError *error; + + error = NULL; + + if (device_local_is_busy (device, TRUE, &error)) + { + dbus_g_method_return_error (context, error); + g_error_free (error); + goto out; + } + + if (strlen (scheme) == 0) + { + throw_error (context, ERROR_FAILED, "type not specified"); + goto out; + } - if (!job_new (context, - "PartitionTableCreate", - TRUE, - device, - argv, - NULL, - partition_table_create_completed_cb, - FALSE, - partition_table_create_data_new (context, device, scheme), - (GDestroyNotify) partition_table_create_data_unref)) { - goto out; + n = 0; + argv[n++] = PACKAGE_LIBEXEC_DIR "/udisks-helper-create-partition-table"; + argv[n++] = device->priv->device_file; + argv[n++] = (char *) scheme; + for (m = 0; options[m] != NULL; m++) + { + if (n >= (int) sizeof(argv) - 1) + { + throw_error (context, ERROR_FAILED, "Too many options"); + goto out; } + /* the helper will validate each option */ + argv[n++] = (char *) options[m]; + } + argv[n++] = NULL; + + if (!job_new (context, + "PartitionTableCreate", + TRUE, + device, + argv, + NULL, + partition_table_create_completed_cb, + FALSE, + partition_table_create_data_new (context, device, scheme), + (GDestroyNotify) partition_table_create_data_unref)) + { + goto out; + } -out: - ; + out: + ; } gboolean -device_partition_table_create (Device *device, - const char *scheme, - char **options, - DBusGMethodInvocation *context) -{ - daemon_local_check_auth (device->priv->daemon, - device, - device->priv->device_is_system_internal ? - "org.freedesktop.devicekit.disks.change-system-internal" : - "org.freedesktop.devicekit.disks.change", - "PartitionTableCreate", - TRUE, - device_partition_table_create_authorized_cb, - context, - 2, - g_strdup (scheme), g_free, - g_strdupv (options), g_strfreev); - return TRUE; +device_partition_table_create (Device *device, + const char *scheme, + char **options, + DBusGMethodInvocation *context) +{ + daemon_local_check_auth (device->priv->daemon, + device, + device->priv->device_is_system_internal ? "org.freedesktop.devicekit.disks.change-system-internal" + : "org.freedesktop.devicekit.disks.change", + "PartitionTableCreate", + TRUE, + device_partition_table_create_authorized_cb, + context, + 2, + g_strdup (scheme), + g_free, + g_strdupv (options), + g_strfreev); + return TRUE; } /*--------------------------------------------------------------------------------------------------------------*/ @@ -7165,177 +7724,186 @@ device_partition_table_create (Device *device, static Device * find_cleartext_device (Device *device) { - GList *devices; - GList *l; - Device *ret; - - ret = NULL; - - /* check that there isn't a cleartext device already */ - devices = daemon_local_get_all_devices (device->priv->daemon); - for (l = devices; l != NULL; l = l->next) { - Device *d = DEVICE (l->data); - if (d->priv->device_is_luks_cleartext && - d->priv->luks_cleartext_slave != NULL && - strcmp (d->priv->luks_cleartext_slave, device->priv->object_path) == 0) { - ret = d; - goto out; - } + GList *devices; + GList *l; + Device *ret; + + ret = NULL; + + /* check that there isn't a cleartext device already */ + devices = daemon_local_get_all_devices (device->priv->daemon); + for (l = devices; l != NULL; l = l->next) + { + Device *d = DEVICE (l->data); + if (d->priv->device_is_luks_cleartext && d->priv->luks_cleartext_slave != NULL + && strcmp (d->priv->luks_cleartext_slave, device->priv->object_path) == 0) + { + ret = d; + goto out; } + } -out: + out: - g_list_free (devices); + g_list_free (devices); - return ret; + return ret; } -typedef struct { - int refcount; +typedef struct +{ + int refcount; - gulong device_added_signal_handler_id; - gulong device_changed_signal_handler_id; - guint device_added_timeout_id; + gulong device_added_signal_handler_id; + gulong device_changed_signal_handler_id; + guint device_added_timeout_id; - DBusGMethodInvocation *context; - Device *device; + DBusGMethodInvocation *context; + Device *device; - UnlockEncryptionHookFunc hook_func; - gpointer hook_user_data; + UnlockEncryptionHookFunc hook_func; + gpointer hook_user_data; } UnlockEncryptionData; static UnlockEncryptionData * -unlock_encryption_data_new (DBusGMethodInvocation *context, - Device *device, - UnlockEncryptionHookFunc hook_func, - gpointer hook_user_data) +unlock_encryption_data_new (DBusGMethodInvocation *context, + Device *device, + UnlockEncryptionHookFunc hook_func, + gpointer hook_user_data) { - UnlockEncryptionData *data; + UnlockEncryptionData *data; - data = g_new0 (UnlockEncryptionData, 1); - data->refcount = 1; + data = g_new0 (UnlockEncryptionData, 1); + data->refcount = 1; - data->context = context; - data->device = g_object_ref (device); - data->hook_func = hook_func; - data->hook_user_data = hook_user_data; - return data; + data->context = context; + data->device = g_object_ref (device); + data->hook_func = hook_func; + data->hook_user_data = hook_user_data; + return data; } static UnlockEncryptionData * unlock_encryption_data_ref (UnlockEncryptionData *data) { - data->refcount++; - return data; + data->refcount++; + return data; } static void unlock_encryption_data_unref (UnlockEncryptionData *data) { - data->refcount--; - if (data->refcount == 0) { - g_object_unref (data->device); - g_free (data); - } + data->refcount--; + if (data->refcount == 0) + { + g_object_unref (data->device); + g_free (data); + } } - static void luks_unlock_device_added_cb (Daemon *daemon, const char *object_path, gpointer user_data) { - UnlockEncryptionData *data = user_data; - Device *device; + UnlockEncryptionData *data = user_data; + Device *device; - /* check the device is a cleartext partition for us */ - device = daemon_local_find_by_object_path (daemon, object_path); + /* check the device is a cleartext partition for us */ + device = daemon_local_find_by_object_path (daemon, object_path); - if (device != NULL && - device->priv->device_is_luks_cleartext && - strcmp (device->priv->luks_cleartext_slave, data->device->priv->object_path) == 0) { - - g_signal_handler_disconnect (daemon, data->device_added_signal_handler_id); - g_signal_handler_disconnect (daemon, data->device_changed_signal_handler_id); - g_source_remove (data->device_added_timeout_id); + if (device != NULL && device->priv->device_is_luks_cleartext && strcmp (device->priv->luks_cleartext_slave, + data->device->priv->object_path) == 0) + { - /* update and emit a Changed() signal on the holder since the luks-holder - * property indicates the cleartext device - */ - update_info (data->device); - drain_pending_changes (data->device, FALSE); + g_signal_handler_disconnect (daemon, data->device_added_signal_handler_id); + g_signal_handler_disconnect (daemon, data->device_changed_signal_handler_id); + g_source_remove (data->device_added_timeout_id); - if (data->hook_func != NULL) { - data->hook_func (data->context, device, data->hook_user_data); - } else { - dbus_g_method_return (data->context, object_path); - } + /* update and emit a Changed() signal on the holder since the luks-holder + * property indicates the cleartext device + */ + update_info (data->device); + drain_pending_changes (data->device, FALSE); - unlock_encryption_data_unref (data); + if (data->hook_func != NULL) + { + data->hook_func (data->context, device, data->hook_user_data); + } + else + { + dbus_g_method_return (data->context, object_path); } + + unlock_encryption_data_unref (data); + } } static gboolean luks_unlock_device_not_seen_cb (gpointer user_data) { - UnlockEncryptionData *data = user_data; + UnlockEncryptionData *data = user_data; - g_signal_handler_disconnect (data->device->priv->daemon, data->device_added_signal_handler_id); - g_signal_handler_disconnect (data->device->priv->daemon, data->device_changed_signal_handler_id); + g_signal_handler_disconnect (data->device->priv->daemon, data->device_added_signal_handler_id); + g_signal_handler_disconnect (data->device->priv->daemon, data->device_changed_signal_handler_id); - throw_error (data->context, - ERROR_FAILED, - "Error unlocking device: timeout (10s) waiting for cleartext device to show up"); + throw_error (data->context, + ERROR_FAILED, + "Error unlocking device: timeout (10s) waiting for cleartext device to show up"); - if (data->hook_func != NULL) { - data->hook_func (data->context, NULL, data->hook_user_data); - } + if (data->hook_func != NULL) + { + data->hook_func (data->context, NULL, data->hook_user_data); + } - unlock_encryption_data_unref (data); - return FALSE; + unlock_encryption_data_unref (data); + return FALSE; } static void luks_unlock_start_waiting_for_cleartext_device (UnlockEncryptionData *data) { - Device *cleartext_device; + Device *cleartext_device; - cleartext_device = find_cleartext_device (data->device); - if (cleartext_device != NULL) { - /* update and emit a Changed() signal on the holder since the luks-holder - * property indicates the cleartext device - */ - update_info (data->device); - drain_pending_changes (data->device, FALSE); + cleartext_device = find_cleartext_device (data->device); + if (cleartext_device != NULL) + { + /* update and emit a Changed() signal on the holder since the luks-holder + * property indicates the cleartext device + */ + update_info (data->device); + drain_pending_changes (data->device, FALSE); - if (data->hook_func != NULL) { - data->hook_func (data->context, cleartext_device, data->hook_user_data); - } else { - dbus_g_method_return (data->context, cleartext_device->priv->object_path); - } + if (data->hook_func != NULL) + { + data->hook_func (data->context, cleartext_device, data->hook_user_data); + } + else + { + dbus_g_method_return (data->context, cleartext_device->priv->object_path); + } - unlock_encryption_data_unref (data); - } else { - /* sit around wait for the cleartext device to appear */ - data->device_added_signal_handler_id = g_signal_connect_after (data->device->priv->daemon, - "device-added", - (GCallback) luks_unlock_device_added_cb, - data); - data->device_changed_signal_handler_id = g_signal_connect_after (data->device->priv->daemon, - "device-changed", - (GCallback) luks_unlock_device_added_cb, - data); + unlock_encryption_data_unref (data); + } + else + { + /* sit around wait for the cleartext device to appear */ + data->device_added_signal_handler_id = g_signal_connect_after (data->device->priv->daemon, + "device-added", + (GCallback) luks_unlock_device_added_cb, + data); + data->device_changed_signal_handler_id = g_signal_connect_after (data->device->priv->daemon, + "device-changed", + (GCallback) luks_unlock_device_added_cb, + data); - /* set up timeout for error reporting if waiting failed */ - data->device_added_timeout_id = g_timeout_add (15 * 1000, - luks_unlock_device_not_seen_cb, - data); + /* set up timeout for error reporting if waiting failed */ + data->device_added_timeout_id = g_timeout_add (15 * 1000, luks_unlock_device_not_seen_cb, data); - /* Note that the signal and timeout handlers share the ref to data - one will cancel the other */ - } + /* Note that the signal and timeout handlers share the ref to data - one will cancel the other */ + } } - static void luks_unlock_completed_cb (DBusGMethodInvocation *context, Device *device, @@ -7345,179 +7913,187 @@ luks_unlock_completed_cb (DBusGMethodInvocation *context, const char *stdout, gpointer user_data) { - UnlockEncryptionData *data = user_data; + UnlockEncryptionData *data = user_data; - if (WEXITSTATUS (status) == 0 && !job_was_cancelled) { + if (WEXITSTATUS (status) == 0 && !job_was_cancelled) + { - luks_unlock_start_waiting_for_cleartext_device (unlock_encryption_data_ref (data)); + luks_unlock_start_waiting_for_cleartext_device (unlock_encryption_data_ref (data)); - } else { - if (job_was_cancelled) { - throw_error (context, - ERROR_CANCELLED, - "Job was cancelled"); - } else { - throw_error (context, - ERROR_FAILED, - "Error unlocking device: cryptsetup exited with exit code %d: %s", - WEXITSTATUS (status), stderr); - } - if (data->hook_func != NULL) { - data->hook_func (data->context, NULL, data->hook_user_data); - } + } + else + { + if (job_was_cancelled) + { + throw_error (context, ERROR_CANCELLED, "Job was cancelled"); + } + else + { + throw_error (context, + ERROR_FAILED, + "Error unlocking device: cryptsetup exited with exit code %d: %s", + WEXITSTATUS (status), + stderr); } + if (data->hook_func != NULL) + { + data->hook_func (data->context, NULL, data->hook_user_data); + } + } } static gboolean -device_luks_unlock_internal (Device *device, - const char *secret, - char **options, - UnlockEncryptionHookFunc hook_func, - gpointer hook_user_data, - DBusGMethodInvocation *context) -{ - int n; - char *argv[10]; - char *luks_name; - GError *error; - char *secret_as_stdin; - uid_t uid; - - luks_name = NULL; - secret_as_stdin = NULL; - error = NULL; - - daemon_local_get_uid (device->priv->daemon, &uid, context); - - if (device_local_is_busy (device, FALSE, &error)) { - dbus_g_method_return_error (context, error); - g_error_free (error); - goto out; - } - - if (device->priv->id_usage == NULL || - strcmp (device->priv->id_usage, "crypto") != 0) { - throw_error (context, ERROR_FAILED, - "Not a LUKS device"); - goto out; - } - - if (find_cleartext_device (device) != NULL) { - throw_error (context, ERROR_FAILED, - "Cleartext device is already unlocked"); - goto out; - } - - luks_name = g_strdup_printf ("udisks-luks-uuid-%s-uid%d", - device->priv->id_uuid, - uid); - secret_as_stdin = g_strdup_printf ("%s\n", secret); - - n = 0; - argv[n++] = "cryptsetup"; - argv[n++] = "-T"; - argv[n++] = "1"; - argv[n++] = "luksOpen"; - argv[n++] = device->priv->device_file; - argv[n++] = luks_name; - argv[n++] = NULL; - - /* yay, so it turns out /sbin/cryptsetup returns way too early; what happens is this - * - * - invoke /sbin/cryptsetup - * - temporary dm node with name temporary-cryptsetup-* appears. We ignore these, - * see above - * - temporary dm node removed - * - /sbin/cryptsetup returns with success (brings us here) - * - proper dm node appears - * - with the name we requested, e.g. udisks-luks-uuid-%s-uid%d - * - proper dm node disappears - * - proper dm node reappears - * - * Obiviously /sbin/cryptsetup shouldn't return before the dm node we are - * looking for is really there or ready to use. But that's not how things - * work. - * - * This bug has been reported here: - * - * https://bugzilla.redhat.com/show_bug.cgi?id=530721 - * - * WORKAROUND: wait for the udev queue to settle before returning. Long - * term fix is device-mapper/udev integration. - */ - if (!job_new (context, - "LuksUnlock", - FALSE, - device, - argv, - secret_as_stdin, - luks_unlock_completed_cb, - TRUE, /* see note above */ - unlock_encryption_data_new (context, device, hook_func, hook_user_data), - (GDestroyNotify) unlock_encryption_data_unref)) { - goto out; - } - -out: - /* scrub the secret */ - if (secret_as_stdin != NULL) { - memset (secret_as_stdin, '\0', strlen (secret_as_stdin)); - } - g_free (secret_as_stdin); - g_free (luks_name); - return TRUE; +device_luks_unlock_internal (Device *device, + const char *secret, + char **options, + UnlockEncryptionHookFunc hook_func, + gpointer hook_user_data, + DBusGMethodInvocation *context) +{ + int n; + char *argv[10]; + char *luks_name; + GError *error; + char *secret_as_stdin; + uid_t uid; + + luks_name = NULL; + secret_as_stdin = NULL; + error = NULL; + + daemon_local_get_uid (device->priv->daemon, &uid, context); + + if (device_local_is_busy (device, FALSE, &error)) + { + dbus_g_method_return_error (context, error); + g_error_free (error); + goto out; + } + + if (device->priv->id_usage == NULL || strcmp (device->priv->id_usage, "crypto") != 0) + { + throw_error (context, ERROR_FAILED, "Not a LUKS device"); + goto out; + } + + if (find_cleartext_device (device) != NULL) + { + throw_error (context, ERROR_FAILED, "Cleartext device is already unlocked"); + goto out; + } + + luks_name = g_strdup_printf ("udisks-luks-uuid-%s-uid%d", device->priv->id_uuid, uid); + secret_as_stdin = g_strdup_printf ("%s\n", secret); + + n = 0; + argv[n++] = "cryptsetup"; + argv[n++] = "-T"; + argv[n++] = "1"; + argv[n++] = "luksOpen"; + argv[n++] = device->priv->device_file; + argv[n++] = luks_name; + argv[n++] = NULL; + + /* yay, so it turns out /sbin/cryptsetup returns way too early; what happens is this + * + * - invoke /sbin/cryptsetup + * - temporary dm node with name temporary-cryptsetup-* appears. We ignore these, + * see above + * - temporary dm node removed + * - /sbin/cryptsetup returns with success (brings us here) + * - proper dm node appears + * - with the name we requested, e.g. udisks-luks-uuid-%s-uid%d + * - proper dm node disappears + * - proper dm node reappears + * + * Obiviously /sbin/cryptsetup shouldn't return before the dm node we are + * looking for is really there or ready to use. But that's not how things + * work. + * + * This bug has been reported here: + * + * https://bugzilla.redhat.com/show_bug.cgi?id=530721 + * + * WORKAROUND: wait for the udev queue to settle before returning. Long + * term fix is device-mapper/udev integration. + */ + if (!job_new (context, + "LuksUnlock", + FALSE, + device, + argv, + secret_as_stdin, + luks_unlock_completed_cb, + TRUE, /* see note above */ + unlock_encryption_data_new (context, device, hook_func, hook_user_data), + (GDestroyNotify) unlock_encryption_data_unref)) + { + goto out; + } + + out: + /* scrub the secret */ + if (secret_as_stdin != NULL) + { + memset (secret_as_stdin, '\0', strlen (secret_as_stdin)); + } + g_free (secret_as_stdin); + g_free (luks_name); + return TRUE; } static void -device_luks_unlock_authorized_cb (Daemon *daemon, - Device *device, - DBusGMethodInvocation *context, - const gchar *action_id, - guint num_user_data, - gpointer *user_data_elements) +device_luks_unlock_authorized_cb (Daemon *daemon, + Device *device, + DBusGMethodInvocation *context, + const gchar *action_id, + guint num_user_data, + gpointer *user_data_elements) { - const char *secret = user_data_elements[0]; - char **options = user_data_elements[1]; - device_luks_unlock_internal (device, secret, options, NULL, NULL, context); + const char *secret = user_data_elements[0]; + char **options = user_data_elements[1]; + device_luks_unlock_internal (device, secret, options, NULL, NULL, context); } gboolean -device_luks_unlock (Device *device, - const char *secret, - char **options, - DBusGMethodInvocation *context) -{ - if (device->priv->id_usage == NULL || - strcmp (device->priv->id_usage, "crypto") != 0) { - throw_error (context, ERROR_FAILED, - "Not a LUKS device"); - goto out; - } - - daemon_local_check_auth (device->priv->daemon, - device, - "org.freedesktop.devicekit.disks.luks-unlock", - "LuksUnlock", - TRUE, - device_luks_unlock_authorized_cb, - context, - 2, - g_strdup (secret), g_free, - g_strdupv (options), g_strfreev); +device_luks_unlock (Device *device, + const char *secret, + char **options, + DBusGMethodInvocation *context) +{ + if (device->priv->id_usage == NULL || strcmp (device->priv->id_usage, "crypto") != 0) + { + throw_error (context, ERROR_FAILED, "Not a LUKS device"); + goto out; + } + + daemon_local_check_auth (device->priv->daemon, + device, + "org.freedesktop.devicekit.disks.luks-unlock", + "LuksUnlock", + TRUE, + device_luks_unlock_authorized_cb, + context, + 2, + g_strdup (secret), + g_free, + g_strdupv (options), + g_strfreev); out: - return TRUE; + return TRUE; } /*--------------------------------------------------------------------------------------------------------------*/ -typedef struct { - int refcount; - DBusGMethodInvocation *context; - Device *luks_device; - Device *cleartext_device; - guint device_removed_signal_handler_id; - guint device_removed_timeout_id; +typedef struct +{ + int refcount; + DBusGMethodInvocation *context; + Device *luks_device; + Device *cleartext_device; + guint device_removed_signal_handler_id; + guint device_removed_timeout_id; } LockEncryptionData; static LockEncryptionData * @@ -7525,556 +8101,582 @@ lock_encryption_data_new (DBusGMethodInvocation *context, Device *luks_device, Device *cleartext_device) { - LockEncryptionData *data; + LockEncryptionData *data; - data = g_new0 (LockEncryptionData, 1); - data->refcount = 1; + data = g_new0 (LockEncryptionData, 1); + data->refcount = 1; - data->context = context; - data->luks_device = g_object_ref (luks_device); - data->cleartext_device = g_object_ref (cleartext_device); - return data; + data->context = context; + data->luks_device = g_object_ref (luks_device); + data->cleartext_device = g_object_ref (cleartext_device); + return data; } static LockEncryptionData * lock_encryption_data_ref (LockEncryptionData *data) { - data->refcount++; - return data; + data->refcount++; + return data; } static void lock_encryption_data_unref (LockEncryptionData *data) { - data->refcount--; - if (data->refcount == 0) { - g_object_unref (data->luks_device); - g_object_unref (data->cleartext_device); - g_free (data); - } + data->refcount--; + if (data->refcount == 0) + { + g_object_unref (data->luks_device); + g_object_unref (data->cleartext_device); + g_free (data); + } } - static void luks_lock_wait_for_cleartext_device_removed_cb (Daemon *daemon, - const char *object_path, - gpointer user_data) + const char *object_path, + gpointer user_data) { - Device *device; - LockEncryptionData *data = user_data; + Device *device; + LockEncryptionData *data = user_data; - device = daemon_local_find_by_object_path (daemon, object_path); - if (device == data->cleartext_device) { + device = daemon_local_find_by_object_path (daemon, object_path); + if (device == data->cleartext_device) + { - job_local_end (data->luks_device); + job_local_end (data->luks_device); - /* update and emit a Changed() signal on the holder since the luks-holder - * property indicates the cleartext device - */ - update_info (data->luks_device); - drain_pending_changes (data->luks_device, FALSE); + /* update and emit a Changed() signal on the holder since the luks-holder + * property indicates the cleartext device + */ + update_info (data->luks_device); + drain_pending_changes (data->luks_device, FALSE); - dbus_g_method_return (data->context); + dbus_g_method_return (data->context); - g_signal_handler_disconnect (daemon, data->device_removed_signal_handler_id); - g_source_remove (data->device_removed_timeout_id); - lock_encryption_data_unref (data); - } + g_signal_handler_disconnect (daemon, data->device_removed_signal_handler_id); + g_source_remove (data->device_removed_timeout_id); + lock_encryption_data_unref (data); + } } - static gboolean luks_lock_wait_for_cleartext_device_not_seen_cb (gpointer user_data) { - LockEncryptionData *data = user_data; + LockEncryptionData *data = user_data; - job_local_end (data->luks_device); + job_local_end (data->luks_device); - throw_error (data->context, - ERROR_FAILED, - "Error locking luks device: timeout (10s) waiting for cleartext device to be removed"); + throw_error (data->context, + ERROR_FAILED, + "Error locking luks device: timeout (10s) waiting for cleartext device to be removed"); - g_signal_handler_disconnect (data->cleartext_device->priv->daemon, data->device_removed_signal_handler_id); - lock_encryption_data_unref (data); - return FALSE; + g_signal_handler_disconnect (data->cleartext_device->priv->daemon, data->device_removed_signal_handler_id); + lock_encryption_data_unref (data); + return FALSE; } static void luks_lock_completed_cb (DBusGMethodInvocation *context, - Device *device, - gboolean job_was_cancelled, - int status, - const char *stderr, - const char *stdout, - gpointer user_data) + Device *device, + gboolean job_was_cancelled, + int status, + const char *stderr, + const char *stdout, + gpointer user_data) { - LockEncryptionData *data = user_data; - - if (WEXITSTATUS (status) == 0 && !job_was_cancelled) { - - /* if device is already removed, just return */ - if (data->cleartext_device->priv->removed) { - /* update and emit a Changed() signal on the holder since the luks-holder - * property indicates the cleartext device - */ - update_info (data->luks_device); - drain_pending_changes (data->luks_device, FALSE); - - dbus_g_method_return (context); - } else { - /* otherwise sit and wait for the device to disappear */ - - data->device_removed_signal_handler_id = g_signal_connect_after ( - device->priv->daemon, - "device-removed", - (GCallback) luks_lock_wait_for_cleartext_device_removed_cb, - lock_encryption_data_ref (data)); - - /* set up timeout for error reporting if waiting failed - * - * (the signal handler and the timeout handler share the ref to data - * as one will cancel the other) - */ - data->device_removed_timeout_id = g_timeout_add ( - 10 * 1000, - luks_lock_wait_for_cleartext_device_not_seen_cb, - data); - - job_local_start (device, "LuksLock"); - } - } else { - if (job_was_cancelled) { - throw_error (context, - ERROR_CANCELLED, - "Job was cancelled"); - } else { - throw_error (context, - ERROR_FAILED, - "Error locking device: cryptsetup exited with exit code %d: %s", - WEXITSTATUS (status), stderr); - } + LockEncryptionData *data = user_data; + + if (WEXITSTATUS (status) == 0 && !job_was_cancelled) + { + + /* if device is already removed, just return */ + if (data->cleartext_device->priv->removed) + { + /* update and emit a Changed() signal on the holder since the luks-holder + * property indicates the cleartext device + */ + update_info (data->luks_device); + drain_pending_changes (data->luks_device, FALSE); + + dbus_g_method_return (context); + } + else + { + /* otherwise sit and wait for the device to disappear */ + + data->device_removed_signal_handler_id + = g_signal_connect_after (device->priv->daemon, + "device-removed", + (GCallback) luks_lock_wait_for_cleartext_device_removed_cb, + lock_encryption_data_ref (data)); + + /* set up timeout for error reporting if waiting failed + * + * (the signal handler and the timeout handler share the ref to data + * as one will cancel the other) + */ + data->device_removed_timeout_id = g_timeout_add (10 * 1000, + luks_lock_wait_for_cleartext_device_not_seen_cb, + data); + + job_local_start (device, "LuksLock"); + } + } + else + { + if (job_was_cancelled) + { + throw_error (context, ERROR_CANCELLED, "Job was cancelled"); } + else + { + throw_error (context, + ERROR_FAILED, + "Error locking device: cryptsetup exited with exit code %d: %s", + WEXITSTATUS (status), + stderr); + } + } } static gboolean -luks_get_uid_from_dm_name (const char *dm_name, uid_t *out_uid) +luks_get_uid_from_dm_name (const char *dm_name, + uid_t *out_uid) { - int n; - gboolean ret; - uid_t uid; - char *endp; + int n; + gboolean ret; + uid_t uid; + char *endp; - ret = FALSE; + ret = FALSE; - if (!g_str_has_prefix (dm_name, "udisks-luks-uuid")) - goto out; + if (!g_str_has_prefix (dm_name, "udisks-luks-uuid")) + goto out; - /* determine who unlocked the device */ - for (n = strlen (dm_name) - 1; n >= 0; n--) { - if (dm_name[n] == '-') - break; - } - if (strncmp (dm_name + n, "-uid", 4) != 0) - goto out; + /* determine who unlocked the device */ + for (n = strlen (dm_name) - 1; n >= 0; n--) + { + if (dm_name[n] == '-') + break; + } + if (strncmp (dm_name + n, "-uid", 4) != 0) + goto out; - uid = strtol (dm_name + n + 4, &endp, 10); - if (endp == NULL || *endp != '\0') - goto out; + uid = strtol (dm_name + n + 4, &endp, 10); + if (endp == NULL || *endp != '\0') + goto out; - if (out_uid != NULL) - *out_uid = uid; + if (out_uid != NULL) + *out_uid = uid; - ret = TRUE; -out: - return ret; + ret = TRUE; + out: + return ret; } static void -device_luks_lock_authorized_cb (Daemon *daemon, - Device *device, - DBusGMethodInvocation *context, - const gchar *action_id, - guint num_user_data, - gpointer *user_data_elements) -{ - /* TODO: use options */ - //char **options = user_data_elements[0]; - Device *cleartext_device; - int n; - char *argv[10]; - GError *error; - - if (device->priv->id_usage == NULL || - strcmp (device->priv->id_usage, "crypto") != 0) { - throw_error (context, ERROR_FAILED, - "Not a LUKS crypto device"); - goto out; - } - - cleartext_device = find_cleartext_device (device); - if (cleartext_device == NULL) { - throw_error (context, ERROR_FAILED, - "Cleartext device is not unlocked"); - goto out; - } - - if (cleartext_device->priv->dm_name == NULL || strlen (cleartext_device->priv->dm_name) == 0) { - throw_error (context, ERROR_FAILED, - "Cannot determine device-mapper name"); - goto out; - } - - n = 0; - argv[n++] = "cryptsetup"; - argv[n++] = "luksClose"; - argv[n++] = cleartext_device->priv->dm_name; - argv[n++] = NULL; - - error = NULL; - if (!job_new (context, - "LuksLock", - FALSE, - device, - argv, - NULL, - luks_lock_completed_cb, - FALSE, - lock_encryption_data_new (context, device, cleartext_device), - (GDestroyNotify) lock_encryption_data_unref)) { - goto out; - } - -out: - ; +device_luks_lock_authorized_cb (Daemon *daemon, + Device *device, + DBusGMethodInvocation *context, + const gchar *action_id, + guint num_user_data, + gpointer *user_data_elements) +{ + /* TODO: use options */ + //char **options = user_data_elements[0]; + Device *cleartext_device; + int n; + char *argv[10]; + GError *error; + + if (device->priv->id_usage == NULL || strcmp (device->priv->id_usage, "crypto") != 0) + { + throw_error (context, ERROR_FAILED, "Not a LUKS crypto device"); + goto out; + } + + cleartext_device = find_cleartext_device (device); + if (cleartext_device == NULL) + { + throw_error (context, ERROR_FAILED, "Cleartext device is not unlocked"); + goto out; + } + + if (cleartext_device->priv->dm_name == NULL || strlen (cleartext_device->priv->dm_name) == 0) + { + throw_error (context, ERROR_FAILED, "Cannot determine device-mapper name"); + goto out; + } + + n = 0; + argv[n++] = "cryptsetup"; + argv[n++] = "luksClose"; + argv[n++] = cleartext_device->priv->dm_name; + argv[n++] = NULL; + + error = NULL; + if (!job_new (context, + "LuksLock", + FALSE, + device, + argv, + NULL, + luks_lock_completed_cb, + FALSE, + lock_encryption_data_new (context, device, cleartext_device), + (GDestroyNotify) lock_encryption_data_unref)) + { + goto out; + } + + out: + ; } gboolean -device_luks_lock (Device *device, - char **options, - DBusGMethodInvocation *context) +device_luks_lock (Device *device, + char **options, + DBusGMethodInvocation *context) { - uid_t unlocked_by_uid; - uid_t uid; - Device *cleartext_device; - const gchar *action_id; + uid_t unlocked_by_uid; + uid_t uid; + Device *cleartext_device; + const gchar *action_id; - daemon_local_get_uid (device->priv->daemon, &uid, context); + daemon_local_get_uid (device->priv->daemon, &uid, context); - if (device->priv->id_usage == NULL || - strcmp (device->priv->id_usage, "crypto") != 0) { - throw_error (context, ERROR_FAILED, - "Not a LUKS crypto device"); - goto out; - } + if (device->priv->id_usage == NULL || strcmp (device->priv->id_usage, "crypto") != 0) + { + throw_error (context, ERROR_FAILED, "Not a LUKS crypto device"); + goto out; + } - cleartext_device = find_cleartext_device (device); - if (cleartext_device == NULL) { - throw_error (context, ERROR_FAILED, - "Cleartext device is not unlocked"); - goto out; - } + cleartext_device = find_cleartext_device (device); + if (cleartext_device == NULL) + { + throw_error (context, ERROR_FAILED, "Cleartext device is not unlocked"); + goto out; + } - if (cleartext_device->priv->dm_name == NULL || strlen (cleartext_device->priv->dm_name) == 0) { - throw_error (context, ERROR_FAILED, - "Cannot determine device-mapper name"); - goto out; - } + if (cleartext_device->priv->dm_name == NULL || strlen (cleartext_device->priv->dm_name) == 0) + { + throw_error (context, ERROR_FAILED, "Cannot determine device-mapper name"); + goto out; + } - /* see if we (e.g. udisks) set up this clear text device */ - if (!luks_get_uid_from_dm_name (cleartext_device->priv->dm_name, &unlocked_by_uid)) { - /* nope.. so assume uid 0 set it up.. we still allow locking - * the device... given enough privilege - */ - unlocked_by_uid = 0; - } + /* see if we (e.g. udisks) set up this clear text device */ + if (!luks_get_uid_from_dm_name (cleartext_device->priv->dm_name, &unlocked_by_uid)) + { + /* nope.. so assume uid 0 set it up.. we still allow locking + * the device... given enough privilege + */ + unlocked_by_uid = 0; + } - /* require authorization if unlocked by someone else */ - action_id = NULL; - if (unlocked_by_uid != uid) { - action_id = "org.freedesktop.devicekit.disks.luks-lock-others"; - } + /* require authorization if unlocked by someone else */ + action_id = NULL; + if (unlocked_by_uid != uid) + { + action_id = "org.freedesktop.devicekit.disks.luks-lock-others"; + } - daemon_local_check_auth (device->priv->daemon, - device, - action_id, - "LuksLock", - TRUE, - device_luks_lock_authorized_cb, - context, - 1, - g_strdupv (options), g_strfreev); + daemon_local_check_auth (device->priv->daemon, + device, + action_id, + "LuksLock", + TRUE, + device_luks_lock_authorized_cb, + context, + 1, + g_strdupv (options), + g_strfreev); out: - return TRUE; + return TRUE; } - /*--------------------------------------------------------------------------------------------------------------*/ static void luks_change_passphrase_completed_cb (DBusGMethodInvocation *context, - Device *device, - gboolean job_was_cancelled, - int status, - const char *stderr, - const char *stdout, - gpointer user_data) + Device *device, + gboolean job_was_cancelled, + int status, + const char *stderr, + const char *stdout, + gpointer user_data) { - if (WEXITSTATUS (status) == 0 && !job_was_cancelled) { - dbus_g_method_return (context); - } else { - if (job_was_cancelled) { - throw_error (context, - ERROR_CANCELLED, - "Job was cancelled"); - } else if (WEXITSTATUS (status) == 3) { - throw_error (context, - ERROR_FILESYSTEM_TOOLS_MISSING , - "Error changing fs label: tool not available: %s", - stderr); - } else { - throw_error (context, - ERROR_FAILED, - "Error changing secret on device: helper exited with exit code %d: %s", - WEXITSTATUS (status), stderr); - } + if (WEXITSTATUS (status) == 0 && !job_was_cancelled) + { + dbus_g_method_return (context); + } + else + { + if (job_was_cancelled) + { + throw_error (context, ERROR_CANCELLED, "Job was cancelled"); + } + else if (WEXITSTATUS (status) == 3) + { + throw_error (context, + ERROR_FILESYSTEM_TOOLS_MISSING, + "Error changing fs label: tool not available: %s", + stderr); } + else + { + throw_error (context, + ERROR_FAILED, + "Error changing secret on device: helper exited with exit code %d: %s", + WEXITSTATUS (status), + stderr); + } + } } static void -device_luks_change_passphrase_authorized_cb (Daemon *daemon, - Device *device, - DBusGMethodInvocation *context, - const gchar *action_id, - guint num_user_data, - gpointer *user_data_elements) -{ - const char *old_secret = user_data_elements[0]; - const char *new_secret = user_data_elements[1]; - int n; - char *argv[10]; - GError *error; - char *secrets_as_stdin; - - secrets_as_stdin = NULL; - - if (device->priv->id_usage == NULL || - strcmp (device->priv->id_usage, "crypto") != 0) { - throw_error (context, ERROR_FAILED, - "Not a LUKS crypto device"); - goto out; - } - - secrets_as_stdin = g_strdup_printf ("%s\n%s\n", old_secret, new_secret); - - n = 0; - argv[n++] = "udisks-helper-change-luks-password"; - argv[n++] = device->priv->device_file; - argv[n++] = NULL; - - error = NULL; - if (!job_new (context, - "LuksChangePassphrase", - FALSE, - device, - argv, - secrets_as_stdin, - luks_change_passphrase_completed_cb, - FALSE, - NULL, - NULL)) { - goto out; - } - -out: - /* scrub the secrets */ - if (secrets_as_stdin != NULL) { - memset (secrets_as_stdin, '\0', strlen (secrets_as_stdin)); - } - g_free (secrets_as_stdin); +device_luks_change_passphrase_authorized_cb (Daemon *daemon, + Device *device, + DBusGMethodInvocation *context, + const gchar *action_id, + guint num_user_data, + gpointer *user_data_elements) +{ + const char *old_secret = user_data_elements[0]; + const char *new_secret = user_data_elements[1]; + int n; + char *argv[10]; + GError *error; + char *secrets_as_stdin; + + secrets_as_stdin = NULL; + + if (device->priv->id_usage == NULL || strcmp (device->priv->id_usage, "crypto") != 0) + { + throw_error (context, ERROR_FAILED, "Not a LUKS crypto device"); + goto out; + } + + secrets_as_stdin = g_strdup_printf ("%s\n%s\n", old_secret, new_secret); + + n = 0; + argv[n++] = "udisks-helper-change-luks-password"; + argv[n++] = device->priv->device_file; + argv[n++] = NULL; + + error = NULL; + if (!job_new (context, + "LuksChangePassphrase", + FALSE, + device, + argv, + secrets_as_stdin, + luks_change_passphrase_completed_cb, + FALSE, + NULL, + NULL)) + { + goto out; + } + + out: + /* scrub the secrets */ + if (secrets_as_stdin != NULL) + { + memset (secrets_as_stdin, '\0', strlen (secrets_as_stdin)); + } + g_free (secrets_as_stdin); } gboolean -device_luks_change_passphrase (Device *device, - const char *old_secret, - const char *new_secret, - DBusGMethodInvocation *context) -{ - /* No need to check for busy; we can actually do this while the device is unlocked as - * only LUKS metadata is modified. - */ - - if (device->priv->id_usage == NULL || - strcmp (device->priv->id_usage, "crypto") != 0) { - throw_error (context, ERROR_FAILED, - "Not a LUKS crypto device"); - goto out; - } - - daemon_local_check_auth (device->priv->daemon, - device, - device->priv->device_is_system_internal ? - "org.freedesktop.devicekit.disks.change-system-internal" : - "org.freedesktop.devicekit.disks.change", - "LuksChangePassphrase", - TRUE, - device_luks_change_passphrase_authorized_cb, - context, - 2, - g_strdup (old_secret), g_free, - g_strdup (new_secret), g_free); +device_luks_change_passphrase (Device *device, + const char *old_secret, + const char *new_secret, + DBusGMethodInvocation *context) +{ + /* No need to check for busy; we can actually do this while the device is unlocked as + * only LUKS metadata is modified. + */ + + if (device->priv->id_usage == NULL || strcmp (device->priv->id_usage, "crypto") != 0) + { + throw_error (context, ERROR_FAILED, "Not a LUKS crypto device"); + goto out; + } + + daemon_local_check_auth (device->priv->daemon, + device, + device->priv->device_is_system_internal ? "org.freedesktop.devicekit.disks.change-system-internal" + : "org.freedesktop.devicekit.disks.change", + "LuksChangePassphrase", + TRUE, + device_luks_change_passphrase_authorized_cb, + context, + 2, + g_strdup (old_secret), + g_free, + g_strdup (new_secret), + g_free); out: - return TRUE; + return TRUE; } /*--------------------------------------------------------------------------------------------------------------*/ static void filesystem_set_label_completed_cb (DBusGMethodInvocation *context, - Device *device, - gboolean job_was_cancelled, - int status, - const char *stderr, - const char *stdout, - gpointer user_data) + Device *device, + gboolean job_was_cancelled, + int status, + const char *stderr, + const char *stdout, + gpointer user_data) { - char *new_label = user_data; + char *new_label = user_data; - /* poke the kernel so we can reread the data */ - device_generate_kernel_change_event (device); + /* poke the kernel so we can reread the data */ + device_generate_kernel_change_event (device); - if (WEXITSTATUS (status) == 0 && !job_was_cancelled) { + if (WEXITSTATUS (status) == 0 && !job_was_cancelled) + { - /* update local copy, don't wait for the kernel */ - device_set_id_label (device, new_label); + /* update local copy, don't wait for the kernel */ + device_set_id_label (device, new_label); - drain_pending_changes (device, FALSE); + drain_pending_changes (device, FALSE); - dbus_g_method_return (context); + dbus_g_method_return (context); - } else { - if (job_was_cancelled) { - throw_error (context, - ERROR_CANCELLED, - "Job was cancelled"); - } else { - throw_error (context, - ERROR_FAILED, - "Error changing fslabel: helper exited with exit code %d: %s", - WEXITSTATUS (status), stderr); - } + } + else + { + if (job_was_cancelled) + { + throw_error (context, ERROR_CANCELLED, "Job was cancelled"); + } + else + { + throw_error (context, + ERROR_FAILED, + "Error changing fslabel: helper exited with exit code %d: %s", + WEXITSTATUS (status), + stderr); } + } } static void -device_filesystem_set_label_authorized_cb (Daemon *daemon, - Device *device, - DBusGMethodInvocation *context, - const gchar *action_id, - guint num_user_data, - gpointer *user_data_elements) +device_filesystem_set_label_authorized_cb (Daemon *daemon, + Device *device, + DBusGMethodInvocation *context, + const gchar *action_id, + guint num_user_data, + gpointer *user_data_elements) { - const gchar *new_label = user_data_elements[0]; - int n; - char *argv[10]; - const Filesystem *fs_details; - GError *error; + const gchar *new_label = user_data_elements[0]; + int n; + char *argv[10]; + const Filesystem *fs_details; + GError *error; - error = NULL; + error = NULL; - if (device->priv->id_usage == NULL || - strcmp (device->priv->id_usage, "filesystem") != 0) { - throw_error (context, ERROR_FAILED, - "Not a mountable file system"); - goto out; - } + if (device->priv->id_usage == NULL || strcmp (device->priv->id_usage, "filesystem") != 0) + { + throw_error (context, ERROR_FAILED, "Not a mountable file system"); + goto out; + } - fs_details = daemon_local_get_fs_details (device->priv->daemon, - device->priv->id_type); - if (fs_details == NULL) { - throw_error (context, ERROR_BUSY, "Unknown filesystem"); - goto out; - } + fs_details = daemon_local_get_fs_details (device->priv->daemon, device->priv->id_type); + if (fs_details == NULL) + { + throw_error (context, ERROR_BUSY, "Unknown filesystem"); + goto out; + } - if (!fs_details->supports_online_label_rename) { - if (device_local_is_busy (device, FALSE, &error)) { - dbus_g_method_return_error (context, error); - g_error_free (error); - goto out; - } + if (!fs_details->supports_online_label_rename) + { + if (device_local_is_busy (device, FALSE, &error)) + { + dbus_g_method_return_error (context, error); + g_error_free (error); + goto out; } + } - n = 0; - argv[n++] = "udisks-helper-change-filesystem-label"; - argv[n++] = device->priv->device_file; - argv[n++] = device->priv->id_type; - argv[n++] = (char *) new_label; - argv[n++] = NULL; - - if (!job_new (context, - "FilesystemSetLabel", - FALSE, - device, - argv, - NULL, - filesystem_set_label_completed_cb, - FALSE, - g_strdup (new_label), - g_free)) { - goto out; - } + n = 0; + argv[n++] = "udisks-helper-change-filesystem-label"; + argv[n++] = device->priv->device_file; + argv[n++] = device->priv->id_type; + argv[n++] = (char *) new_label; + argv[n++] = NULL; + + if (!job_new (context, + "FilesystemSetLabel", + FALSE, + device, + argv, + NULL, + filesystem_set_label_completed_cb, + FALSE, + g_strdup (new_label), + g_free)) + { + goto out; + } -out: - ; + out: + ; } gboolean -device_filesystem_set_label (Device *device, - const char *new_label, - DBusGMethodInvocation *context) +device_filesystem_set_label (Device *device, + const char *new_label, + DBusGMethodInvocation *context) { - const Filesystem *fs_details; - GError *error; + const Filesystem *fs_details; + GError *error; - error = NULL; + error = NULL; - if (device->priv->id_usage == NULL || - strcmp (device->priv->id_usage, "filesystem") != 0) { - throw_error (context, ERROR_FAILED, - "Not a mountable file system"); - goto out; - } + if (device->priv->id_usage == NULL || strcmp (device->priv->id_usage, "filesystem") != 0) + { + throw_error (context, ERROR_FAILED, "Not a mountable file system"); + goto out; + } - fs_details = daemon_local_get_fs_details (device->priv->daemon, - device->priv->id_type); - if (fs_details == NULL) { - throw_error (context, ERROR_BUSY, "Unknown filesystem"); - goto out; - } + fs_details = daemon_local_get_fs_details (device->priv->daemon, device->priv->id_type); + if (fs_details == NULL) + { + throw_error (context, ERROR_BUSY, "Unknown filesystem"); + goto out; + } - if (!fs_details->supports_online_label_rename) { - if (device_local_is_busy (device, FALSE, &error)) { - dbus_g_method_return_error (context, error); - g_error_free (error); - goto out; - } + if (!fs_details->supports_online_label_rename) + { + if (device_local_is_busy (device, FALSE, &error)) + { + dbus_g_method_return_error (context, error); + g_error_free (error); + goto out; } + } - daemon_local_check_auth (device->priv->daemon, - device, - device->priv->device_is_system_internal ? - "org.freedesktop.devicekit.disks.change-system-internal" : - "org.freedesktop.devicekit.disks.change", - "FilesystemSetLabel", - TRUE, - device_filesystem_set_label_authorized_cb, - context, - 1, - g_strdup (new_label), g_free); + daemon_local_check_auth (device->priv->daemon, + device, + device->priv->device_is_system_internal ? "org.freedesktop.devicekit.disks.change-system-internal" + : "org.freedesktop.devicekit.disks.change", + "FilesystemSetLabel", + TRUE, + device_filesystem_set_label_authorized_cb, + context, + 1, + g_strdup (new_label), + g_free); out: - return TRUE; + return TRUE; } /*--------------------------------------------------------------------------------------------------------------*/ @@ -8089,215 +8691,221 @@ drive_ata_smart_refresh_data_completed_cb (DBusGMethodInvocation *context, const char *stdout, gpointer user_data) { - gint rc; - SkDisk *d; - gchar *blob; - gsize blob_size; - time_t time_collected; - SkSmartOverall overall; - - d = NULL; - blob = NULL; - - if (job_was_cancelled || stdout == NULL) { - if (job_was_cancelled) { - if (context != NULL) - throw_error (context, - ERROR_CANCELLED, - "Job was cancelled"); - } else { - if (context != NULL) - throw_error (context, - ERROR_FAILED, - "Error retrieving ATA SMART data: no output", - WEXITSTATUS (status), stderr); - } - goto out; - } - - rc = WEXITSTATUS (status); - - if (rc != 0) { - if (rc == 2) { - if (context != NULL) { - throw_error (context, - ERROR_ATA_SMART_WOULD_WAKEUP, - "Error retrieving ATA SMART data: %s", - stderr); - } - } else { - if (context != NULL) { - throw_error (context, - ERROR_FAILED, - "Error retrieving ATA SMART data: helper failed with exit code %d: %s", - rc, stderr); - } - } - goto out; + gint rc; + SkDisk *d; + gchar *blob; + gsize blob_size; + time_t time_collected; + SkSmartOverall overall; + + d = NULL; + blob = NULL; + + if (job_was_cancelled || stdout == NULL) + { + if (job_was_cancelled) + { + if (context != NULL) + throw_error (context, ERROR_CANCELLED, "Job was cancelled"); } + else + { + if (context != NULL) + throw_error (context, + ERROR_FAILED, + "Error retrieving ATA SMART data: no output", + WEXITSTATUS (status), + stderr); + } + goto out; + } - blob = (gchar *) g_base64_decode (stdout, &blob_size); + rc = WEXITSTATUS (status); - if (blob == NULL) { - if (context != NULL) { - throw_error (context, - ERROR_FAILED, - "Error decoding ATA SMART data: invalid base64 format: %s", - stdout); - } else { - g_warning ("Error decoding ATA SMART data: invalid base64 format: %s", - stdout); - } - goto out; + if (rc != 0) + { + if (rc == 2) + { + if (context != NULL) + { + throw_error (context, ERROR_ATA_SMART_WOULD_WAKEUP, "Error retrieving ATA SMART data: %s", stderr); + } } + else + { + if (context != NULL) + { + throw_error (context, + ERROR_FAILED, + "Error retrieving ATA SMART data: helper failed with exit code %d: %s", + rc, + stderr); + } + } + goto out; + } - if (sk_disk_open (NULL, &d) != 0) { - if (context != NULL) { - throw_error (context, - ERROR_FAILED, - "unable to open a SkDisk"); - } - goto out; + blob = (gchar *) g_base64_decode (stdout, &blob_size); + + if (blob == NULL) + { + if (context != NULL) + { + throw_error (context, ERROR_FAILED, "Error decoding ATA SMART data: invalid base64 format: %s", stdout); + } + else + { + g_warning ("Error decoding ATA SMART data: invalid base64 format: %s", stdout); } + goto out; + } - if (sk_disk_set_blob (d, blob, blob_size) != 0) { - if (context != NULL) { - throw_error (context, - ERROR_FAILED, - "error parsing blob: %s", - strerror (errno)); - } - goto out; + if (sk_disk_open (NULL, &d) != 0) + { + if (context != NULL) + { + throw_error (context, ERROR_FAILED, "unable to open a SkDisk"); } + goto out; + } + + if (sk_disk_set_blob (d, blob, blob_size) != 0) + { + if (context != NULL) + { + throw_error (context, ERROR_FAILED, "error parsing blob: %s", strerror (errno)); + } + goto out; + } - time_collected = time (NULL); - device_set_drive_ata_smart_time_collected (device, time_collected); + time_collected = time (NULL); + device_set_drive_ata_smart_time_collected (device, time_collected); - if (sk_disk_smart_get_overall (d, &overall) != 0) - overall = -1; - device_set_drive_ata_smart_status (device, overall); - device_set_drive_ata_smart_blob_steal (device, blob, blob_size); - blob = NULL; + if (sk_disk_smart_get_overall (d, &overall) != 0) + overall = -1; + device_set_drive_ata_smart_status (device, overall); + device_set_drive_ata_smart_blob_steal (device, blob, blob_size); + blob = NULL; - /* emit change event since we've updated the smart data */ - drain_pending_changes (device, FALSE); + /* emit change event since we've updated the smart data */ + drain_pending_changes (device, FALSE); - if (context != NULL) - dbus_g_method_return (context); + if (context != NULL) + dbus_g_method_return (context); -out: - g_free (blob); - if (d != NULL) - sk_disk_free (d); + out: + g_free (blob); + if (d != NULL) + sk_disk_free (d); } static void -device_drive_ata_smart_refresh_data_authorized_cb (Daemon *daemon, - Device *device, - DBusGMethodInvocation *context, - const gchar *action_id, - guint num_user_data, - gpointer *user_data_elements) -{ - char **options = user_data_elements[0]; - int n; - char *argv[10]; - GError *error; - const char *simuldata; - gboolean nowakeup; - uid_t caller_uid; - - daemon_local_get_uid (device->priv->daemon, &caller_uid, context); - - if (!device->priv->drive_ata_smart_is_available) { - throw_error (context, - ERROR_FAILED, - "Device does not support ATA SMART"); - goto out; - } - - simuldata = NULL; - nowakeup = FALSE; - for (n = 0; options[n] != NULL; n++) { - if (g_str_has_prefix (options[n], "simulate=")) { - if (context != NULL) { - if (caller_uid != 0) { - throw_error (context, - ERROR_FAILED, - "Only uid 0 may use the simulate= option"); - goto out; - } - } - simuldata = (const char *) options[n] + 9; - } else if (strcmp (options[n], "nowakeup") == 0) { - nowakeup = TRUE; +device_drive_ata_smart_refresh_data_authorized_cb (Daemon *daemon, + Device *device, + DBusGMethodInvocation *context, + const gchar *action_id, + guint num_user_data, + gpointer *user_data_elements) +{ + char **options = user_data_elements[0]; + int n; + char *argv[10]; + GError *error; + const char *simuldata; + gboolean nowakeup; + uid_t caller_uid; + + daemon_local_get_uid (device->priv->daemon, &caller_uid, context); + + if (!device->priv->drive_ata_smart_is_available) + { + throw_error (context, ERROR_FAILED, "Device does not support ATA SMART"); + goto out; + } + + simuldata = NULL; + nowakeup = FALSE; + for (n = 0; options[n] != NULL; n++) + { + if (g_str_has_prefix (options[n], "simulate=")) + { + if (context != NULL) + { + if (caller_uid != 0) + { + throw_error (context, ERROR_FAILED, "Only uid 0 may use the simulate= option"); + goto out; } + } + simuldata = (const char *) options[n] + 9; } - - if (simuldata != NULL) { - n = 0; - argv[n++] = "base64"; /* provided by coreutils */ - argv[n++] = (char *) simuldata; - argv[n++] = NULL; - } else { - n = 0; - argv[n++] = PACKAGE_LIBEXEC_DIR "/udisks-helper-ata-smart-collect"; - argv[n++] = device->priv->device_file; - argv[n++] = nowakeup ? "1" : "0"; - argv[n++] = NULL; + else if (strcmp (options[n], "nowakeup") == 0) + { + nowakeup = TRUE; } + } + + if (simuldata != NULL) + { + n = 0; + argv[n++] = "base64"; /* provided by coreutils */ + argv[n++] = (char *) simuldata; + argv[n++] = NULL; + } + else + { + n = 0; + argv[n++] = PACKAGE_LIBEXEC_DIR "/udisks-helper-ata-smart-collect"; + argv[n++] = device->priv->device_file; + argv[n++] = nowakeup ? "1" : "0"; + argv[n++] = NULL; + } - error = NULL; + error = NULL; - if (!job_new (context, - NULL, /* don't run this as a job */ - FALSE, - device, - argv, - NULL, - drive_ata_smart_refresh_data_completed_cb, - FALSE, - NULL, - NULL)) { - goto out; - } + if (!job_new (context, NULL, /* don't run this as a job */ + FALSE, device, argv, NULL, drive_ata_smart_refresh_data_completed_cb, FALSE, NULL, NULL)) + { + goto out; + } -out: - ; + out: + ; } /* may be called with context==NULL */ gboolean -device_drive_ata_smart_refresh_data (Device *device, - char **options, - DBusGMethodInvocation *context) +device_drive_ata_smart_refresh_data (Device *device, + char **options, + DBusGMethodInvocation *context) { - const gchar *action_id; + const gchar *action_id; - if (!device->priv->drive_ata_smart_is_available) { - throw_error (context, - ERROR_FAILED, - "Device does not support ATA SMART"); - goto out; - } + if (!device->priv->drive_ata_smart_is_available) + { + throw_error (context, ERROR_FAILED, "Device does not support ATA SMART"); + goto out; + } - action_id = NULL; - if (context != NULL) { - action_id = "org.freedesktop.devicekit.disks.drive-ata-smart-refresh"; - } + action_id = NULL; + if (context != NULL) + { + action_id = "org.freedesktop.devicekit.disks.drive-ata-smart-refresh"; + } - daemon_local_check_auth (device->priv->daemon, - device, - action_id, - "DriveAtaSmartRefreshData", - TRUE, - device_drive_ata_smart_refresh_data_authorized_cb, - context, - 1, - g_strdupv (options), g_strfreev); + daemon_local_check_auth (device->priv->daemon, + device, + action_id, + "DriveAtaSmartRefreshData", + TRUE, + device_drive_ata_smart_refresh_data_authorized_cb, + context, + 1, + g_strdupv (options), + g_strfreev); out: - return TRUE; + return TRUE; } /*--------------------------------------------------------------------------------------------------------------*/ @@ -8311,206 +8919,217 @@ drive_ata_smart_initiate_selftest_completed_cb (DBusGMethodInvocation *context, const char *stdout, gpointer user_data) { - char *options[] = {NULL}; + char *options[] = + { NULL }; + + /* no matter what happened, refresh the data */ + device_drive_ata_smart_refresh_data (device, options, NULL); + + if (WEXITSTATUS (status) == 0 && !job_was_cancelled) + { - /* no matter what happened, refresh the data */ - device_drive_ata_smart_refresh_data (device, options, NULL); + dbus_g_method_return (context); - if (WEXITSTATUS (status) == 0 && !job_was_cancelled) { + } + else + { + if (job_was_cancelled) + { + throw_error (context, ERROR_CANCELLED, "Job was cancelled"); + } + else + { + throw_error (context, + ERROR_FAILED, + "Error running self test: helper exited with exit code %d: %s", + WEXITSTATUS (status), + stderr); + } + } +} - dbus_g_method_return (context); +static void +device_drive_ata_smart_initiate_selftest_authorized_cb (Daemon *daemon, + Device *device, + DBusGMethodInvocation *context, + const gchar *action_id, + guint num_user_data, + gpointer *user_data_elements) +{ + const gchar *test = user_data_elements[0]; + /* TODO: use options */ + //gchar **options = user_data_elements[1]; + int n; + char *argv[10]; + GError *error; + const gchar *job_name; + + if (g_strcmp0 (test, "short") == 0) + { + job_name = "DriveAtaSmartSelftestShort"; + } + else if (g_strcmp0 (test, "extended") == 0) + { + job_name = "DriveAtaSmartSelftestExtended"; + } + else if (g_strcmp0 (test, "conveyance") == 0) + { + job_name = "DriveAtaSmartSelftestConveyance"; + } + else + { + throw_error (context, ERROR_FAILED, "Malformed test"); + goto out; + } - } else { - if (job_was_cancelled) { - throw_error (context, - ERROR_CANCELLED, - "Job was cancelled"); - } else { - throw_error (context, - ERROR_FAILED, - "Error running self test: helper exited with exit code %d: %s", - WEXITSTATUS (status), stderr); - } - } -} + n = 0; + argv[n++] = PACKAGE_LIBEXEC_DIR "/udisks-helper-ata-smart-selftest"; + argv[n++] = device->priv->device_file; + argv[n++] = (char *) test; + argv[n++] = NULL; + + error = NULL; + if (!job_new (context, + job_name, + TRUE, + device, + argv, + NULL, + drive_ata_smart_initiate_selftest_completed_cb, + FALSE, + NULL, + NULL)) + { + goto out; + } -static void -device_drive_ata_smart_initiate_selftest_authorized_cb (Daemon *daemon, - Device *device, - DBusGMethodInvocation *context, - const gchar *action_id, - guint num_user_data, - gpointer *user_data_elements) -{ - const gchar *test = user_data_elements[0]; - /* TODO: use options */ - //gchar **options = user_data_elements[1]; - int n; - char *argv[10]; - GError *error; - const gchar *job_name; - - if (g_strcmp0 (test, "short") == 0) { - job_name = "DriveAtaSmartSelftestShort"; - } else if (g_strcmp0 (test, "extended") == 0) { - job_name = "DriveAtaSmartSelftestExtended"; - } else if (g_strcmp0 (test, "conveyance") == 0) { - job_name = "DriveAtaSmartSelftestConveyance"; - } else { - throw_error (context, - ERROR_FAILED, - "Malformed test"); - goto out; - } - - n = 0; - argv[n++] = PACKAGE_LIBEXEC_DIR "/udisks-helper-ata-smart-selftest"; - argv[n++] = device->priv->device_file; - argv[n++] = (char *) test; - argv[n++] = NULL; - - error = NULL; - if (!job_new (context, - job_name, - TRUE, - device, - argv, - NULL, - drive_ata_smart_initiate_selftest_completed_cb, - FALSE, - NULL, - NULL)) { - goto out; - } - -out: - ; + out: + ; } gboolean -device_drive_ata_smart_initiate_selftest (Device *device, - const char *test, - gchar **options, - DBusGMethodInvocation *context) -{ - if (!device->priv->drive_ata_smart_is_available) { - throw_error (context, - ERROR_FAILED, - "Device does not support ATA SMART"); - goto out; - } - - daemon_local_check_auth (device->priv->daemon, - device, - "org.freedesktop.devicekit.disks.drive-ata-smart-selftest", - "DriveAtaSmartInitiateSelftest", - TRUE, - device_drive_ata_smart_initiate_selftest_authorized_cb, - context, - 2, - g_strdup (test), g_free, - g_strdupv (options), g_strfreev); +device_drive_ata_smart_initiate_selftest (Device *device, + const char *test, + gchar **options, + DBusGMethodInvocation *context) +{ + if (!device->priv->drive_ata_smart_is_available) + { + throw_error (context, ERROR_FAILED, "Device does not support ATA SMART"); + goto out; + } + + daemon_local_check_auth (device->priv->daemon, + device, + "org.freedesktop.devicekit.disks.drive-ata-smart-selftest", + "DriveAtaSmartInitiateSelftest", + TRUE, + device_drive_ata_smart_initiate_selftest_authorized_cb, + context, + 2, + g_strdup (test), + g_free, + g_strdupv (options), + g_strfreev); out: - return TRUE; + return TRUE; } /*--------------------------------------------------------------------------------------------------------------*/ static void linux_md_stop_completed_cb (DBusGMethodInvocation *context, - Device *device, - gboolean job_was_cancelled, - int status, - const char *stderr, - const char *stdout, - gpointer user_data) + Device *device, + gboolean job_was_cancelled, + int status, + const char *stderr, + const char *stdout, + gpointer user_data) { - if (WEXITSTATUS (status) == 0 && !job_was_cancelled) { - - /* the kernel side of md currently doesn't emit a 'changed' event so - * generate one such that the md device can disappear from our - * database - */ - device_generate_kernel_change_event (device); - - dbus_g_method_return (context); - - } else { - if (job_was_cancelled) { - throw_error (context, - ERROR_CANCELLED, - "Job was cancelled"); - } else { - throw_error (context, - ERROR_FAILED, - "Error stopping array: mdadm exited with exit code %d: %s", - WEXITSTATUS (status), stderr); - } + if (WEXITSTATUS (status) == 0 && !job_was_cancelled) + { + + /* the kernel side of md currently doesn't emit a 'changed' event so + * generate one such that the md device can disappear from our + * database + */ + device_generate_kernel_change_event (device); + + dbus_g_method_return (context); + + } + else + { + if (job_was_cancelled) + { + throw_error (context, ERROR_CANCELLED, "Job was cancelled"); + } + else + { + throw_error (context, + ERROR_FAILED, + "Error stopping array: mdadm exited with exit code %d: %s", + WEXITSTATUS (status), + stderr); } + } } static void -device_linux_md_stop_authorized_cb (Daemon *daemon, - Device *device, - DBusGMethodInvocation *context, - const gchar *action_id, - guint num_user_data, - gpointer *user_data_elements) -{ - /* TODO: use options */ - //gchar **options = user_data_elements[0]; - int n; - char *argv[10]; - GError *error; - - n = 0; - argv[n++] = "mdadm"; - argv[n++] = "--stop"; - argv[n++] = device->priv->device_file; - argv[n++] = NULL; - - error = NULL; - if (!job_new (context, - "LinuxMdStop", - TRUE, - device, - argv, - NULL, - linux_md_stop_completed_cb, - FALSE, - NULL, - NULL)) { - goto out; - } - -out: - ; +device_linux_md_stop_authorized_cb (Daemon *daemon, + Device *device, + DBusGMethodInvocation *context, + const gchar *action_id, + guint num_user_data, + gpointer *user_data_elements) +{ + /* TODO: use options */ + //gchar **options = user_data_elements[0]; + int n; + char *argv[10]; + GError *error; + + n = 0; + argv[n++] = "mdadm"; + argv[n++] = "--stop"; + argv[n++] = device->priv->device_file; + argv[n++] = NULL; + + error = NULL; + if (!job_new (context, "LinuxMdStop", TRUE, device, argv, NULL, linux_md_stop_completed_cb, FALSE, NULL, NULL)) + { + goto out; + } + + out: + ; } gboolean -device_linux_md_stop (Device *device, - char **options, - DBusGMethodInvocation *context) +device_linux_md_stop (Device *device, + char **options, + DBusGMethodInvocation *context) { - if (!device->priv->device_is_linux_md) { - throw_error (context, ERROR_FAILED, - "Device is not a Linux md drive"); - goto out; - } + if (!device->priv->device_is_linux_md) + { + throw_error (context, ERROR_FAILED, "Device is not a Linux md drive"); + goto out; + } - daemon_local_check_auth (device->priv->daemon, - device, - "org.freedesktop.devicekit.disks.linux-md", - "LinuxMdStop", - TRUE, - device_linux_md_stop_authorized_cb, - context, - 1, - g_strdupv (options), g_strfreev); + daemon_local_check_auth (device->priv->daemon, + device, + "org.freedesktop.devicekit.disks.linux-md", + "LinuxMdStop", + TRUE, + device_linux_md_stop_authorized_cb, + context, + 1, + g_strdupv (options), + g_strfreev); out: - return TRUE; + return TRUE; } /*--------------------------------------------------------------------------------------------------------------*/ @@ -8524,553 +9143,568 @@ linux_md_check_completed_cb (DBusGMethodInvocation *context, const char *stdout, gpointer user_data) { - if (WEXITSTATUS (status) == 0 && !job_was_cancelled) { - guint64 num_errors; - - num_errors = sysfs_get_uint64 (device->priv->native_path, "md/mismatch_cnt"); - - dbus_g_method_return (context, num_errors); - } else { - if (job_was_cancelled) { - throw_error (context, - ERROR_CANCELLED, - "Job was cancelled"); - } else { - throw_error (context, - ERROR_FAILED, - "Error checking array: helper exited with exit code %d: %s", - WEXITSTATUS (status), stderr); - } + if (WEXITSTATUS (status) == 0 && !job_was_cancelled) + { + guint64 num_errors; + + num_errors = sysfs_get_uint64 (device->priv->native_path, "md/mismatch_cnt"); + + dbus_g_method_return (context, num_errors); + } + else + { + if (job_was_cancelled) + { + throw_error (context, ERROR_CANCELLED, "Job was cancelled"); } + else + { + throw_error (context, + ERROR_FAILED, + "Error checking array: helper exited with exit code %d: %s", + WEXITSTATUS (status), + stderr); + } + } } static void -device_linux_md_check_authorized_cb (Daemon *daemon, - Device *device, - DBusGMethodInvocation *context, - const gchar *action_id, - guint num_user_data, - gpointer *user_data_elements) -{ - gchar **options = user_data_elements[0]; - gchar *filename; - int n, m; - char *argv[128]; - const gchar *job_name; - - filename = NULL; - - if (!device->priv->device_is_linux_md) { - throw_error (context, ERROR_FAILED, - "Device is not a Linux md drive"); - goto out; - } - - if (g_strcmp0 (device->priv->linux_md_sync_action, "idle") != 0) { - throw_error (context, ERROR_FAILED, - "Array is not idle"); - goto out; - } - - n = 0; - argv[n++] = PACKAGE_LIBEXEC_DIR "/udisks-helper-linux-md-check"; - argv[n++] = device->priv->device_file; - argv[n++] = device->priv->native_path; - for (m = 0; options[m] != NULL; m++) { - if (n >= (int) sizeof (argv) - 1) { - throw_error (context, - ERROR_FAILED, - "Too many options"); - goto out; - } - /* the helper will validate each option */ - argv[n++] = (char *) options[m]; - } - argv[n++] = NULL; +device_linux_md_check_authorized_cb (Daemon *daemon, + Device *device, + DBusGMethodInvocation *context, + const gchar *action_id, + guint num_user_data, + gpointer *user_data_elements) +{ + gchar **options = user_data_elements[0]; + gchar *filename; + int n, m; + char *argv[128]; + const gchar *job_name; + + filename = NULL; + + if (!device->priv->device_is_linux_md) + { + throw_error (context, ERROR_FAILED, "Device is not a Linux md drive"); + goto out; + } - job_name = "LinuxMdCheck"; - for (n = 0; options != NULL && options[n] != NULL; n++) - if (strcmp (options[n], "repair") == 0) - job_name = "LinuxMdRepair"; + if (g_strcmp0 (device->priv->linux_md_sync_action, "idle") != 0) + { + throw_error (context, ERROR_FAILED, "Array is not idle"); + goto out; + } - if (!job_new (context, - job_name, - TRUE, - device, - argv, - NULL, - linux_md_check_completed_cb, - FALSE, - NULL, - NULL)) { - goto out; + n = 0; + argv[n++] = PACKAGE_LIBEXEC_DIR "/udisks-helper-linux-md-check"; + argv[n++] = device->priv->device_file; + argv[n++] = device->priv->native_path; + for (m = 0; options[m] != NULL; m++) + { + if (n >= (int) sizeof(argv) - 1) + { + throw_error (context, ERROR_FAILED, "Too many options"); + goto out; } + /* the helper will validate each option */ + argv[n++] = (char *) options[m]; + } + argv[n++] = NULL; + + job_name = "LinuxMdCheck"; + for (n = 0; options != NULL && options[n] != NULL; n++) + if (strcmp (options[n], "repair") == 0) + job_name = "LinuxMdRepair"; + + if (!job_new (context, job_name, TRUE, device, argv, NULL, linux_md_check_completed_cb, FALSE, NULL, NULL)) + { + goto out; + } out: - ; + ; } gboolean -device_linux_md_check (Device *device, - char **options, - DBusGMethodInvocation *context) +device_linux_md_check (Device *device, + char **options, + DBusGMethodInvocation *context) { - guint n; - const gchar *job_name; + guint n; + const gchar *job_name; - job_name = "LinuxMdCheck"; - for (n = 0; options != NULL && options[n] != NULL; n++) - if (strcmp (options[n], "repair") == 0) - job_name = "LinuxMdRepair"; + job_name = "LinuxMdCheck"; + for (n = 0; options != NULL && options[n] != NULL; n++) + if (strcmp (options[n], "repair") == 0) + job_name = "LinuxMdRepair"; - if (!device->priv->device_is_linux_md) { - throw_error (context, ERROR_FAILED, - "Device is not a Linux md drive"); - goto out; - } + if (!device->priv->device_is_linux_md) + { + throw_error (context, ERROR_FAILED, "Device is not a Linux md drive"); + goto out; + } - if (g_strcmp0 (device->priv->linux_md_sync_action, "idle") != 0) { - throw_error (context, ERROR_FAILED, - "Array is not idle"); - goto out; - } + if (g_strcmp0 (device->priv->linux_md_sync_action, "idle") != 0) + { + throw_error (context, ERROR_FAILED, "Array is not idle"); + goto out; + } - daemon_local_check_auth (device->priv->daemon, - device, - "org.freedesktop.devicekit.disks.linux-md", - job_name, - TRUE, - device_linux_md_check_authorized_cb, - context, - 1, - g_strdupv (options), g_strfreev); + daemon_local_check_auth (device->priv->daemon, + device, + "org.freedesktop.devicekit.disks.linux-md", + job_name, + TRUE, + device_linux_md_check_authorized_cb, + context, + 1, + g_strdupv (options), + g_strfreev); out: - return TRUE; + return TRUE; } /*--------------------------------------------------------------------------------------------------------------*/ static void linux_md_add_component_completed_cb (DBusGMethodInvocation *context, - Device *device, - gboolean job_was_cancelled, - int status, - const char *stderr, - const char *stdout, - gpointer user_data) -{ - Device *slave = DEVICE (user_data); - - if (WEXITSTATUS (status) == 0 && !job_was_cancelled) { - - /* the slave got new metadata on it; reread that */ - device_generate_kernel_change_event (slave); - - /* the kernel side of md currently doesn't emit a 'changed' event so - * generate one since state may have changed (e.g. rebuild started etc.) - */ - device_generate_kernel_change_event (device); - - dbus_g_method_return (context); - - } else { - if (job_was_cancelled) { - throw_error (context, - ERROR_CANCELLED, - "Job was cancelled"); - } else { - throw_error (context, - ERROR_FAILED, - "Error adding component: mdadm exited with exit code %d: %s", - WEXITSTATUS (status), stderr); - } + Device *device, + gboolean job_was_cancelled, + int status, + const char *stderr, + const char *stdout, + gpointer user_data) +{ + Device *slave = DEVICE (user_data); + + if (WEXITSTATUS (status) == 0 && !job_was_cancelled) + { + + /* the slave got new metadata on it; reread that */ + device_generate_kernel_change_event (slave); + + /* the kernel side of md currently doesn't emit a 'changed' event so + * generate one since state may have changed (e.g. rebuild started etc.) + */ + device_generate_kernel_change_event (device); + + dbus_g_method_return (context); + + } + else + { + if (job_was_cancelled) + { + throw_error (context, ERROR_CANCELLED, "Job was cancelled"); + } + else + { + throw_error (context, + ERROR_FAILED, + "Error adding component: mdadm exited with exit code %d: %s", + WEXITSTATUS (status), + stderr); } + } } static void -device_linux_md_add_component_authorized_cb (Daemon *daemon, - Device *device, - DBusGMethodInvocation *context, - const gchar *action_id, - guint num_user_data, - gpointer *user_data_elements) -{ - char *component = user_data_elements[0]; - /* TODO: use options */ - //char **options = user_data_elements[1]; - int n; - char *argv[10]; - GError *error; - Device *slave; - - error = NULL; - - slave = daemon_local_find_by_object_path (device->priv->daemon, component); - if (slave == NULL) { - throw_error (context, ERROR_FAILED, - "Component doesn't exist"); - goto out; - } - - /* it's fine if the given device isn't a Linux md component _yet_; think - * hot adding a new disk if an old one failed - */ - - if (device_local_is_busy (slave, TRUE, &error)) { - dbus_g_method_return_error (context, error); - g_error_free (error); - goto out; - } - - /* TODO: check component size is OK */ - - n = 0; - argv[n++] = "mdadm"; - argv[n++] = "--manage"; - argv[n++] = device->priv->device_file; - argv[n++] = "--add"; - argv[n++] = slave->priv->device_file; - argv[n++] = "--force"; - argv[n++] = NULL; - - if (!job_new (context, - "LinuxMdAddComponent", - TRUE, - device, - argv, - NULL, - linux_md_add_component_completed_cb, - FALSE, - g_object_ref (slave), - g_object_unref)) { - goto out; - } - -out: - ; +device_linux_md_add_component_authorized_cb (Daemon *daemon, + Device *device, + DBusGMethodInvocation *context, + const gchar *action_id, + guint num_user_data, + gpointer *user_data_elements) +{ + char *component = user_data_elements[0]; + /* TODO: use options */ + //char **options = user_data_elements[1]; + int n; + char *argv[10]; + GError *error; + Device *slave; + + error = NULL; + + slave = daemon_local_find_by_object_path (device->priv->daemon, component); + if (slave == NULL) + { + throw_error (context, ERROR_FAILED, "Component doesn't exist"); + goto out; + } + + /* it's fine if the given device isn't a Linux md component _yet_; think + * hot adding a new disk if an old one failed + */ + + if (device_local_is_busy (slave, TRUE, &error)) + { + dbus_g_method_return_error (context, error); + g_error_free (error); + goto out; + } + + /* TODO: check component size is OK */ + + n = 0; + argv[n++] = "mdadm"; + argv[n++] = "--manage"; + argv[n++] = device->priv->device_file; + argv[n++] = "--add"; + argv[n++] = slave->priv->device_file; + argv[n++] = "--force"; + argv[n++] = NULL; + + if (!job_new (context, + "LinuxMdAddComponent", + TRUE, + device, + argv, + NULL, + linux_md_add_component_completed_cb, + FALSE, + g_object_ref (slave), + g_object_unref)) + { + goto out; + } + + out: + ; } gboolean -device_linux_md_add_component (Device *device, - char *component, - char **options, - DBusGMethodInvocation *context) -{ - if (!device->priv->device_is_linux_md) { - throw_error (context, ERROR_FAILED, - "Device is not a Linux md drive"); - goto out; - } - - daemon_local_check_auth (device->priv->daemon, - device, - "org.freedesktop.devicekit.disks.linux-md", - "LinuxMdAddComponent", - TRUE, - device_linux_md_add_component_authorized_cb, - context, - 2, - g_strdup (component), g_free, - g_strdupv (options), g_strfreev); +device_linux_md_add_component (Device *device, + char *component, + char **options, + DBusGMethodInvocation *context) +{ + if (!device->priv->device_is_linux_md) + { + throw_error (context, ERROR_FAILED, "Device is not a Linux md drive"); + goto out; + } + + daemon_local_check_auth (device->priv->daemon, + device, + "org.freedesktop.devicekit.disks.linux-md", + "LinuxMdAddComponent", + TRUE, + device_linux_md_add_component_authorized_cb, + context, + 2, + g_strdup (component), + g_free, + g_strdupv (options), + g_strfreev); out: - return TRUE; + return TRUE; } - /*--------------------------------------------------------------------------------------------------------------*/ +typedef struct +{ + int refcount; -typedef struct { - int refcount; - - DBusGMethodInvocation *context; - Device *slave; - char **options; + DBusGMethodInvocation *context; + Device *slave; + char **options; - guint device_changed_signal_handler_id; - guint device_changed_timeout_id; + guint device_changed_signal_handler_id; + guint device_changed_timeout_id; } RemoveComponentData; static RemoveComponentData * -remove_component_data_new (DBusGMethodInvocation *context, - Device *slave, - char **options) +remove_component_data_new (DBusGMethodInvocation *context, + Device *slave, + char **options) { - RemoveComponentData *data; + RemoveComponentData *data; - data = g_new0 (RemoveComponentData, 1); - data->refcount = 1; + data = g_new0 (RemoveComponentData, 1); + data->refcount = 1; - data->context = context; - data->slave = g_object_ref (slave); - data->options = g_strdupv (options); - return data; + data->context = context; + data->slave = g_object_ref (slave); + data->options = g_strdupv (options); + return data; } static RemoveComponentData * remove_component_data_ref (RemoveComponentData *data) { - data->refcount++; - return data; + data->refcount++; + return data; } static void remove_component_data_unref (RemoveComponentData *data) { - data->refcount--; - if (data->refcount == 0) { - g_object_unref (data->slave); - g_free (data->options); - g_free (data); - } + data->refcount--; + if (data->refcount == 0) + { + g_object_unref (data->slave); + g_free (data->options); + g_free (data); + } } - static void linux_md_remove_component_device_changed_cb (Daemon *daemon, const char *object_path, gpointer user_data) { - RemoveComponentData *data = user_data; - Device *device; - GError *error; + RemoveComponentData *data = user_data; + Device *device; + GError *error; - error = NULL; + error = NULL; - device = daemon_local_find_by_object_path (daemon, object_path); - if (device == data->slave) { + device = daemon_local_find_by_object_path (daemon, object_path); + if (device == data->slave) + { - if (device_local_is_busy (data->slave, FALSE, &error)) { - dbus_g_method_return_error (data->context, error); - g_error_free (error); - } else { - gchar *fs_create_options[] = {NULL}; + if (device_local_is_busy (data->slave, FALSE, &error)) + { + dbus_g_method_return_error (data->context, error); + g_error_free (error); + } + else + { + gchar *fs_create_options[] = + { NULL }; - /* yay! now scrub it! */ - device_filesystem_create (data->slave, - "empty", - fs_create_options, - data->context); + /* yay! now scrub it! */ + device_filesystem_create (data->slave, "empty", fs_create_options, data->context); - /* TODO: leaking data? */ + /* TODO: leaking data? */ - g_signal_handler_disconnect (daemon, data->device_changed_signal_handler_id); - g_source_remove (data->device_changed_timeout_id); - } + g_signal_handler_disconnect (daemon, data->device_changed_signal_handler_id); + g_source_remove (data->device_changed_timeout_id); } + } } static gboolean linux_md_remove_component_device_not_seen_cb (gpointer user_data) { - RemoveComponentData *data = user_data; + RemoveComponentData *data = user_data; - throw_error (data->context, - ERROR_FAILED, - "Error removing component: timeout (10s) waiting for slave to stop being busy"); + throw_error (data->context, + ERROR_FAILED, + "Error removing component: timeout (10s) waiting for slave to stop being busy"); - g_signal_handler_disconnect (data->slave->priv->daemon, data->device_changed_signal_handler_id); - remove_component_data_unref (data); + g_signal_handler_disconnect (data->slave->priv->daemon, data->device_changed_signal_handler_id); + remove_component_data_unref (data); - return FALSE; + return FALSE; } - static void linux_md_remove_component_completed_cb (DBusGMethodInvocation *context, - Device *device, - gboolean job_was_cancelled, - int status, - const char *stderr, - const char *stdout, - gpointer user_data) + Device *device, + gboolean job_was_cancelled, + int status, + const char *stderr, + const char *stdout, + gpointer user_data) { - RemoveComponentData *data = user_data; - - /* the slave got new metadata on it; reread that */ - device_generate_kernel_change_event (data->slave); - - /* the kernel side of md currently doesn't emit a 'changed' event so - * generate one since state may have changed (e.g. rebuild started etc.) - */ - device_generate_kernel_change_event (device); - - if (WEXITSTATUS (status) == 0 && !job_was_cancelled) { - - /* wait for the slave to be busy, then start erasing it */ - - data->device_changed_signal_handler_id = g_signal_connect_after ( - device->priv->daemon, - "device-changed", - (GCallback) linux_md_remove_component_device_changed_cb, - remove_component_data_ref (data)); - - /* set up timeout for error reporting if waiting failed - * - * (the signal handler and the timeout handler share the ref to data - * as one will cancel the other) - */ - data->device_changed_timeout_id = g_timeout_add ( - 10 * 1000, - linux_md_remove_component_device_not_seen_cb, - data); - - } else { - if (job_was_cancelled) { - throw_error (context, - ERROR_CANCELLED, - "Job was cancelled"); - } else { - throw_error (context, - ERROR_FAILED, - "Error removing component: helper exited with exit code %d: %s", - WEXITSTATUS (status), stderr); - } + RemoveComponentData *data = user_data; + + /* the slave got new metadata on it; reread that */ + device_generate_kernel_change_event (data->slave); + + /* the kernel side of md currently doesn't emit a 'changed' event so + * generate one since state may have changed (e.g. rebuild started etc.) + */ + device_generate_kernel_change_event (device); + + if (WEXITSTATUS (status) == 0 && !job_was_cancelled) + { + + /* wait for the slave to be busy, then start erasing it */ + + data->device_changed_signal_handler_id + = g_signal_connect_after (device->priv->daemon, + "device-changed", + (GCallback) linux_md_remove_component_device_changed_cb, + remove_component_data_ref (data)); + + /* set up timeout for error reporting if waiting failed + * + * (the signal handler and the timeout handler share the ref to data + * as one will cancel the other) + */ + data->device_changed_timeout_id = g_timeout_add (10 * 1000, linux_md_remove_component_device_not_seen_cb, data); + + } + else + { + if (job_was_cancelled) + { + throw_error (context, ERROR_CANCELLED, "Job was cancelled"); } + else + { + throw_error (context, + ERROR_FAILED, + "Error removing component: helper exited with exit code %d: %s", + WEXITSTATUS (status), + stderr); + } + } } static void -device_linux_md_remove_component_authorized_cb (Daemon *daemon, - Device *device, - DBusGMethodInvocation *context, - const gchar *action_id, - guint num_user_data, - gpointer *user_data_elements) -{ - char *component = user_data_elements[0]; - char **options = user_data_elements[1]; - int n, m; - char *argv[128]; - GError *error; - Device *slave; - - slave = daemon_local_find_by_object_path (device->priv->daemon, component); - if (slave == NULL) { - throw_error (context, ERROR_FAILED, - "Component doesn't exist"); - goto out; - } - - /* check that it really is a component of the md device */ - for (n = 0; n < (int) device->priv->linux_md_slaves->len; n++) { - if (strcmp (component, device->priv->linux_md_slaves->pdata[n]) == 0) - break; - } - if (n == (int) device->priv->linux_md_slaves->len) { - throw_error (context, ERROR_FAILED, - "Component isn't part of the running array"); - goto out; - } - - n = 0; - argv[n++] = PACKAGE_LIBEXEC_DIR "/udisks-helper-linux-md-remove-component"; - argv[n++] = device->priv->device_file; - argv[n++] = slave->priv->device_file; - for (m = 0; options[m] != NULL; m++) { - if (n >= (int) sizeof (argv) - 1) { - throw_error (context, - ERROR_FAILED, - "Too many options"); - goto out; - } - /* the helper will validate each option */ - argv[n++] = (char *) options[m]; - } - argv[n++] = NULL; - - error = NULL; - if (!job_new (context, - "LinuxMdRemoveComponent", - TRUE, - device, - argv, - NULL, - linux_md_remove_component_completed_cb, - FALSE, - remove_component_data_new (context, slave, options), - (GDestroyNotify) remove_component_data_unref)) { - goto out; - } - -out: - ; +device_linux_md_remove_component_authorized_cb (Daemon *daemon, + Device *device, + DBusGMethodInvocation *context, + const gchar *action_id, + guint num_user_data, + gpointer *user_data_elements) +{ + char *component = user_data_elements[0]; + char **options = user_data_elements[1]; + int n, m; + char *argv[128]; + GError *error; + Device *slave; + + slave = daemon_local_find_by_object_path (device->priv->daemon, component); + if (slave == NULL) + { + throw_error (context, ERROR_FAILED, "Component doesn't exist"); + goto out; + } + + /* check that it really is a component of the md device */ + for (n = 0; n < (int) device->priv->linux_md_slaves->len; n++) + { + if (strcmp (component, device->priv->linux_md_slaves->pdata[n]) == 0) + break; + } + if (n == (int) device->priv->linux_md_slaves->len) + { + throw_error (context, ERROR_FAILED, "Component isn't part of the running array"); + goto out; + } + + n = 0; + argv[n++] = PACKAGE_LIBEXEC_DIR "/udisks-helper-linux-md-remove-component"; + argv[n++] = device->priv->device_file; + argv[n++] = slave->priv->device_file; + for (m = 0; options[m] != NULL; m++) + { + if (n >= (int) sizeof(argv) - 1) + { + throw_error (context, ERROR_FAILED, "Too many options"); + goto out; + } + /* the helper will validate each option */ + argv[n++] = (char *) options[m]; + } + argv[n++] = NULL; + + error = NULL; + if (!job_new (context, + "LinuxMdRemoveComponent", + TRUE, + device, + argv, + NULL, + linux_md_remove_component_completed_cb, + FALSE, + remove_component_data_new (context, slave, options), + (GDestroyNotify) remove_component_data_unref)) + { + goto out; + } + + out: + ; } gboolean -device_linux_md_remove_component (Device *device, - char *component, - char **options, - DBusGMethodInvocation *context) -{ - if (!device->priv->device_is_linux_md) { - throw_error (context, ERROR_FAILED, - "Device is not a Linux md drive"); - goto out; - } - - daemon_local_check_auth (device->priv->daemon, - device, - "org.freedesktop.devicekit.disks.linux-md", - "LinuxMdRemoveComponent", - TRUE, - device_linux_md_remove_component_authorized_cb, - context, - 2, - g_strdup (component), g_free, - g_strdupv (options), g_strfreev); +device_linux_md_remove_component (Device *device, + char *component, + char **options, + DBusGMethodInvocation *context) +{ + if (!device->priv->device_is_linux_md) + { + throw_error (context, ERROR_FAILED, "Device is not a Linux md drive"); + goto out; + } + + daemon_local_check_auth (device->priv->daemon, + device, + "org.freedesktop.devicekit.disks.linux-md", + "LinuxMdRemoveComponent", + TRUE, + device_linux_md_remove_component_authorized_cb, + context, + 2, + g_strdup (component), + g_free, + g_strdupv (options), + g_strfreev); out: - return TRUE; + return TRUE; } /*--------------------------------------------------------------------------------------------------------------*/ -typedef struct { - int refcount; +typedef struct +{ + int refcount; - guint device_added_signal_handler_id; - guint device_added_timeout_id; + guint device_added_signal_handler_id; + guint device_added_timeout_id; - DBusGMethodInvocation *context; + DBusGMethodInvocation *context; - Daemon *daemon; - char *uuid; + Daemon *daemon; + char *uuid; } LinuxMdStartData; static LinuxMdStartData * linux_md_start_data_new (DBusGMethodInvocation *context, - Daemon *daemon, - const char *uuid) + Daemon *daemon, + const char *uuid) { - LinuxMdStartData *data; + LinuxMdStartData *data; - data = g_new0 (LinuxMdStartData, 1); - data->refcount = 1; + data = g_new0 (LinuxMdStartData, 1); + data->refcount = 1; - data->context = context; - data->daemon = g_object_ref (daemon); - data->uuid = g_strdup (uuid); - return data; + data->context = context; + data->daemon = g_object_ref (daemon); + data->uuid = g_strdup (uuid); + return data; } static LinuxMdStartData * linux_md_start_data_ref (LinuxMdStartData *data) { - data->refcount++; - return data; + data->refcount++; + return data; } static void linux_md_start_data_unref (LinuxMdStartData *data) { - data->refcount--; - if (data->refcount == 0) { - g_object_unref (data->daemon); - g_free (data->uuid); - g_free (data); - } + data->refcount--; + if (data->refcount == 0) + { + g_object_unref (data->daemon); + g_free (data->uuid); + g_free (data); + } } static void @@ -9078,38 +9712,36 @@ linux_md_start_device_added_cb (Daemon *daemon, const char *object_path, gpointer user_data) { - LinuxMdStartData *data = user_data; - Device *device; + LinuxMdStartData *data = user_data; + Device *device; - /* check the device is the one we're looking for */ - device = daemon_local_find_by_object_path (daemon, object_path); + /* check the device is the one we're looking for */ + device = daemon_local_find_by_object_path (daemon, object_path); - if (device != NULL && - device->priv->device_is_linux_md) { + if (device != NULL && device->priv->device_is_linux_md) + { - /* TODO: actually check this properly by looking at slaves vs. components */ + /* TODO: actually check this properly by looking at slaves vs. components */ - /* yay! it is.. return value to the user */ - dbus_g_method_return (data->context, object_path); + /* yay! it is.. return value to the user */ + dbus_g_method_return (data->context, object_path); - g_signal_handler_disconnect (daemon, data->device_added_signal_handler_id); - g_source_remove (data->device_added_timeout_id); - linux_md_start_data_unref (data); - } + g_signal_handler_disconnect (daemon, data->device_added_signal_handler_id); + g_source_remove (data->device_added_timeout_id); + linux_md_start_data_unref (data); + } } static gboolean linux_md_start_device_not_seen_cb (gpointer user_data) { - LinuxMdStartData *data = user_data; + LinuxMdStartData *data = user_data; - throw_error (data->context, - ERROR_FAILED, - "Error assembling array: timeout (10s) waiting for array to show up"); + throw_error (data->context, ERROR_FAILED, "Error assembling array: timeout (10s) waiting for array to show up"); - g_signal_handler_disconnect (data->daemon, data->device_added_signal_handler_id); - linux_md_start_data_unref (data); - return FALSE; + g_signal_handler_disconnect (data->daemon, data->device_added_signal_handler_id); + linux_md_start_data_unref (data); + return FALSE; } /* NOTE: This is job completion callback from a method on the daemon, not the device. */ @@ -9123,635 +9755,679 @@ linux_md_start_completed_cb (DBusGMethodInvocation *context, const char *stdout, gpointer user_data) { - LinuxMdStartData *data = user_data; + LinuxMdStartData *data = user_data; - if (WEXITSTATUS (status) == 0 && !job_was_cancelled) { - GList *l; - GList *devices; - char *objpath; + if (WEXITSTATUS (status) == 0 && !job_was_cancelled) + { + GList *l; + GList *devices; + char *objpath; - /* see if the component appeared already */ + /* see if the component appeared already */ - objpath = NULL; + objpath = NULL; - devices = daemon_local_get_all_devices (data->daemon); - for (l = devices; l != NULL; l = l->next) { - Device *device = DEVICE (l->data); + devices = daemon_local_get_all_devices (data->daemon); + for (l = devices; l != NULL; l = l->next) + { + Device *device = DEVICE (l->data); - if (device->priv->device_is_linux_md) { + if (device->priv->device_is_linux_md) + { - /* TODO: check properly */ + /* TODO: check properly */ - /* yup, return to caller */ - objpath = device->priv->object_path; - break; - } - } + /* yup, return to caller */ + objpath = device->priv->object_path; + break; + } + } - g_list_free (devices); - - if (objpath != NULL) { - dbus_g_method_return (context, objpath); - } else { - /* sit around and wait for the md array to appear */ - - /* sit around wait for the cleartext device to appear */ - data->device_added_signal_handler_id = g_signal_connect_after ( - data->daemon, - "device-added", - (GCallback) linux_md_start_device_added_cb, - linux_md_start_data_ref (data)); - - /* set up timeout for error reporting if waiting failed - * - * (the signal handler and the timeout handler share the ref to data - * as one will cancel the other) - */ - data->device_added_timeout_id = g_timeout_add (10 * 1000, - linux_md_start_device_not_seen_cb, - data); - } + g_list_free (devices); + if (objpath != NULL) + { + dbus_g_method_return (context, objpath); + } + else + { + /* sit around and wait for the md array to appear */ - } else { - if (job_was_cancelled) { - throw_error (context, - ERROR_CANCELLED, - "Job was cancelled"); - } else { - throw_error (context, - ERROR_FAILED, - "Error assembling array: mdadm exited with exit code %d: %s", - WEXITSTATUS (status), stderr); - } + /* sit around wait for the cleartext device to appear */ + data->device_added_signal_handler_id = g_signal_connect_after (data->daemon, + "device-added", + (GCallback) linux_md_start_device_added_cb, + linux_md_start_data_ref (data)); + + /* set up timeout for error reporting if waiting failed + * + * (the signal handler and the timeout handler share the ref to data + * as one will cancel the other) + */ + data->device_added_timeout_id = g_timeout_add (10 * 1000, linux_md_start_device_not_seen_cb, data); + } + + } + else + { + if (job_was_cancelled) + { + throw_error (context, ERROR_CANCELLED, "Job was cancelled"); + } + else + { + throw_error (context, + ERROR_FAILED, + "Error assembling array: mdadm exited with exit code %d: %s", + WEXITSTATUS (status), + stderr); } + } } /* NOTE: This is a method on the daemon, not the device. */ static void -daemon_linux_md_start_authorized_cb (Daemon *daemon, - Device *device, - DBusGMethodInvocation *context, - const gchar *action_id, - guint num_user_data, - gpointer *user_data_elements) -{ - gchar **components_as_strv = user_data_elements[0]; - /* TODO: use options */ - //gchar **options = user_data_elements[1]; - int n; - int m; - char *argv[128]; - GError *error; - char *uuid; - char *md_device_file; - - uuid = NULL; - md_device_file = NULL; - error = NULL; - - /* check that all given components exist, that they are indeed linux-md-components and - * that their uuid agrees - */ - for (n = 0; components_as_strv[n] != NULL; n++) { - Device *slave; - const char *component_objpath = components_as_strv[n]; - - slave = daemon_local_find_by_object_path (daemon, component_objpath); - if (slave == NULL) { - throw_error (context, ERROR_FAILED, - "Component %s doesn't exist", component_objpath); - goto out; - } +daemon_linux_md_start_authorized_cb (Daemon *daemon, + Device *device, + DBusGMethodInvocation *context, + const gchar *action_id, + guint num_user_data, + gpointer *user_data_elements) +{ + gchar **components_as_strv = user_data_elements[0]; + /* TODO: use options */ + //gchar **options = user_data_elements[1]; + int n; + int m; + char *argv[128]; + GError *error; + char *uuid; + char *md_device_file; + + uuid = NULL; + md_device_file = NULL; + error = NULL; + + /* check that all given components exist, that they are indeed linux-md-components and + * that their uuid agrees + */ + for (n = 0; components_as_strv[n] != NULL; n++) + { + Device *slave; + const char *component_objpath = components_as_strv[n]; - if (!slave->priv->device_is_linux_md_component) { - throw_error (context, ERROR_FAILED, - "%s is not a linux-md component", component_objpath); - goto out; - } + slave = daemon_local_find_by_object_path (daemon, component_objpath); + if (slave == NULL) + { + throw_error (context, ERROR_FAILED, "Component %s doesn't exist", component_objpath); + goto out; + } - if (n == 0) { - uuid = g_strdup (slave->priv->linux_md_component_uuid); - if (uuid == NULL) { - throw_error (context, ERROR_FAILED, - "no uuid for one of the components"); - goto out; - } - } else { - const char *this_uuid; - this_uuid = slave->priv->linux_md_component_uuid; - - if (this_uuid == NULL || strcmp (uuid, this_uuid) != 0) { - throw_error (context, ERROR_FAILED, - "uuid mismatch between given components"); - goto out; - } - } + if (!slave->priv->device_is_linux_md_component) + { + throw_error (context, ERROR_FAILED, "%s is not a linux-md component", component_objpath); + goto out; + } - if (device_local_is_busy (slave, FALSE, &error)) { - dbus_g_method_return_error (context, error); - g_error_free (error); - goto out; - } + if (n == 0) + { + uuid = g_strdup (slave->priv->linux_md_component_uuid); + if (uuid == NULL) + { + throw_error (context, ERROR_FAILED, "no uuid for one of the components"); + goto out; + } } + else + { + const char *this_uuid; + this_uuid = slave->priv->linux_md_component_uuid; - /* find an unused md minor... Man, I wish mdadm could do this itself; this is slightly racy */ - for (n = 0; TRUE; n++) { - char *native_path; - char *array_state; - - /* TODO: move to /sys/class/block instead */ - native_path = g_strdup_printf ("/sys/block/md%d", n); - if (!sysfs_file_exists (native_path, "md/array_state")) { - /* Apparently this slot is free since there is no such file. So let's peruse it. */ - g_free (native_path); - break; - } else { - array_state = sysfs_get_string (native_path, "md/array_state"); - g_strstrip (array_state); - if (strcmp (array_state, "clear") == 0) { - /* It's clear! Let's use it! */ - g_free (array_state); - g_free (native_path); - break; - } - g_free (array_state); - } - g_free (native_path); + if (this_uuid == NULL || strcmp (uuid, this_uuid) != 0) + { + throw_error (context, ERROR_FAILED, "uuid mismatch between given components"); + goto out; + } } - md_device_file = g_strdup_printf ("/dev/md%d", n); + if (device_local_is_busy (slave, FALSE, &error)) + { + dbus_g_method_return_error (context, error); + g_error_free (error); + goto out; + } + } - n = 0; - argv[n++] = "mdadm"; - argv[n++] = "--assemble"; - argv[n++] = md_device_file; - argv[n++] = "--run"; - for (m = 0; components_as_strv[m] != NULL; m++) { - Device *slave; - const char *component_objpath = components_as_strv[m]; + /* find an unused md minor... Man, I wish mdadm could do this itself; this is slightly racy */ + for (n = 0; TRUE; n++) + { + char *native_path; + char *array_state; - slave = daemon_local_find_by_object_path (daemon, component_objpath); - if (slave == NULL) { - throw_error (context, ERROR_FAILED, - "Component %s doesn't exist", component_objpath); - goto out; - } + /* TODO: move to /sys/class/block instead */ + native_path = g_strdup_printf ("/sys/block/md%d", n); + if (!sysfs_file_exists (native_path, "md/array_state")) + { + /* Apparently this slot is free since there is no such file. So let's peruse it. */ + g_free (native_path); + break; + } + else + { + array_state = sysfs_get_string (native_path, "md/array_state"); + g_strstrip (array_state); + if (strcmp (array_state, "clear") == 0) + { + /* It's clear! Let's use it! */ + g_free (array_state); + g_free (native_path); + break; + } + g_free (array_state); + } + g_free (native_path); + } - if (n >= (int) sizeof (argv) - 1) { - throw_error (context, - ERROR_FAILED, - "Too many components"); - goto out; - } + md_device_file = g_strdup_printf ("/dev/md%d", n); - argv[n++] = (char *) slave->priv->device_file; - } - argv[n++] = NULL; + n = 0; + argv[n++] = "mdadm"; + argv[n++] = "--assemble"; + argv[n++] = md_device_file; + argv[n++] = "--run"; + for (m = 0; components_as_strv[m] != NULL; m++) + { + Device *slave; + const char *component_objpath = components_as_strv[m]; - if (!job_new (context, - "LinuxMdStart", - TRUE, - NULL, - argv, - NULL, - linux_md_start_completed_cb, - FALSE, - linux_md_start_data_new (context, daemon, uuid), - (GDestroyNotify) linux_md_start_data_unref)) { - goto out; + slave = daemon_local_find_by_object_path (daemon, component_objpath); + if (slave == NULL) + { + throw_error (context, ERROR_FAILED, "Component %s doesn't exist", component_objpath); + goto out; } -out: - g_free (uuid); - g_free (md_device_file); -} - -/* NOTE: This is a method on the daemon, not the device. */ -gboolean -daemon_linux_md_start (Daemon *daemon, - GPtrArray *components, - char **options, - DBusGMethodInvocation *context) -{ - gchar **components_as_strv; - guint n; + if (n >= (int) sizeof(argv) - 1) + { + throw_error (context, ERROR_FAILED, "Too many components"); + goto out; + } - components_as_strv = g_new0 (gchar *, components->len + 1); - for (n = 0; n < components->len; n++) - components_as_strv[n] = g_strdup (components->pdata[n]); + argv[n++] = (char *) slave->priv->device_file; + } + argv[n++] = NULL; + + if (!job_new (context, + "LinuxMdStart", + TRUE, + NULL, + argv, + NULL, + linux_md_start_completed_cb, + FALSE, + linux_md_start_data_new (context, daemon, uuid), + (GDestroyNotify) linux_md_start_data_unref)) + { + goto out; + } - daemon_local_check_auth (daemon, - NULL, - "org.freedesktop.devicekit.disks.linux-md", - "LinuxMdStart", - TRUE, - daemon_linux_md_start_authorized_cb, - context, - 2, - components_as_strv, g_strfreev, - g_strdupv (options), g_strfreev); + out: + g_free (uuid); + g_free (md_device_file); +} - return TRUE; +/* NOTE: This is a method on the daemon, not the device. */ +gboolean +daemon_linux_md_start (Daemon *daemon, + GPtrArray *components, + char **options, + DBusGMethodInvocation *context) +{ + gchar **components_as_strv; + guint n; + + components_as_strv = g_new0 (gchar *, components->len + 1); + for (n = 0; n < components->len; n++) + components_as_strv[n] = g_strdup (components->pdata[n]); + + daemon_local_check_auth (daemon, + NULL, + "org.freedesktop.devicekit.disks.linux-md", + "LinuxMdStart", + TRUE, + daemon_linux_md_start_authorized_cb, + context, + 2, + components_as_strv, + g_strfreev, + g_strdupv (options), + g_strfreev); + + return TRUE; } /*--------------------------------------------------------------------------------------------------------------*/ -typedef struct { - int refcount; +typedef struct +{ + int refcount; - guint device_added_signal_handler_id; - guint device_added_timeout_id; + guint device_added_signal_handler_id; + guint device_added_timeout_id; - DBusGMethodInvocation *context; + DBusGMethodInvocation *context; - Daemon *daemon; - char *first_component_objpath; + Daemon *daemon; + char *first_component_objpath; } LinuxMdCreateData; static LinuxMdCreateData * linux_md_create_data_new (DBusGMethodInvocation *context, - Daemon *daemon, - const char *first_component_objpath) + Daemon *daemon, + const char *first_component_objpath) { - LinuxMdCreateData *data; + LinuxMdCreateData *data; - data = g_new0 (LinuxMdCreateData, 1); - data->refcount = 1; + data = g_new0 (LinuxMdCreateData, 1); + data->refcount = 1; - data->context = context; - data->daemon = g_object_ref (daemon); - data->first_component_objpath = g_strdup (first_component_objpath); - return data; + data->context = context; + data->daemon = g_object_ref (daemon); + data->first_component_objpath = g_strdup (first_component_objpath); + return data; } static LinuxMdCreateData * linux_md_create_data_ref (LinuxMdCreateData *data) { - data->refcount++; - return data; + data->refcount++; + return data; } static void linux_md_create_data_unref (LinuxMdCreateData *data) { - data->refcount--; - if (data->refcount == 0) { - g_object_unref (data->daemon); - g_free (data->first_component_objpath); - g_free (data); - } + data->refcount--; + if (data->refcount == 0) + { + g_object_unref (data->daemon); + g_free (data->first_component_objpath); + g_free (data); + } } static void linux_md_create_device_added_cb (Daemon *daemon, - const char *object_path, - gpointer user_data) + const char *object_path, + gpointer user_data) { - LinuxMdCreateData *data = user_data; - Device *device; + LinuxMdCreateData *data = user_data; + Device *device; - /* check the device is the one we're looking for */ - device = daemon_local_find_by_object_path (daemon, object_path); + /* check the device is the one we're looking for */ + device = daemon_local_find_by_object_path (daemon, object_path); - if (device != NULL && - device->priv->device_is_linux_md) { + if (device != NULL && device->priv->device_is_linux_md) + { - /* TODO: actually check this properly by looking at slaves vs. components */ + /* TODO: actually check this properly by looking at slaves vs. components */ - /* yay! it is.. return value to the user */ - dbus_g_method_return (data->context, object_path); + /* yay! it is.. return value to the user */ + dbus_g_method_return (data->context, object_path); - g_signal_handler_disconnect (daemon, data->device_added_signal_handler_id); - g_source_remove (data->device_added_timeout_id); - linux_md_create_data_unref (data); - } + g_signal_handler_disconnect (daemon, data->device_added_signal_handler_id); + g_source_remove (data->device_added_timeout_id); + linux_md_create_data_unref (data); + } } static gboolean linux_md_create_device_not_seen_cb (gpointer user_data) { - LinuxMdCreateData *data = user_data; + LinuxMdCreateData *data = user_data; - throw_error (data->context, - ERROR_FAILED, - "Error assembling array: timeout (10s) waiting for array to show up"); + throw_error (data->context, ERROR_FAILED, "Error assembling array: timeout (10s) waiting for array to show up"); - g_signal_handler_disconnect (data->daemon, data->device_added_signal_handler_id); - linux_md_create_data_unref (data); - return FALSE; + g_signal_handler_disconnect (data->daemon, data->device_added_signal_handler_id); + linux_md_create_data_unref (data); + return FALSE; } /* NOTE: This is job completion callback from a method on the daemon, not the device. */ static void linux_md_create_completed_cb (DBusGMethodInvocation *context, - Device *device, - gboolean job_was_cancelled, - int status, - const char *stderr, - const char *stdout, - gpointer user_data) + Device *device, + gboolean job_was_cancelled, + int status, + const char *stderr, + const char *stdout, + gpointer user_data) { - LinuxMdCreateData *data = user_data; + LinuxMdCreateData *data = user_data; + + if (WEXITSTATUS (status) == 0 && !job_was_cancelled) + { + GList *l; + GList *devices; + char *objpath; - if (WEXITSTATUS (status) == 0 && !job_was_cancelled) { - GList *l; - GList *devices; - char *objpath; + /* see if the component appeared already */ - /* see if the component appeared already */ + objpath = NULL; - objpath = NULL; + devices = daemon_local_get_all_devices (data->daemon); + for (l = devices; l != NULL; l = l->next) + { + Device *device = DEVICE (l->data); - devices = daemon_local_get_all_devices (data->daemon); - for (l = devices; l != NULL; l = l->next) { - Device *device = DEVICE (l->data); + if (device->priv->device_is_linux_md) + { - if (device->priv->device_is_linux_md) { + /* TODO: check properly */ - /* TODO: check properly */ + /* yup, return to caller */ + objpath = device->priv->object_path; + break; + } + } - /* yup, return to caller */ - objpath = device->priv->object_path; - break; - } - } + g_list_free (devices); - g_list_free (devices); - - if (objpath != NULL) { - dbus_g_method_return (context, objpath); - } else { - /* sit around and wait for the md array to appear */ - - /* sit around wait for the cleartext device to appear */ - data->device_added_signal_handler_id = g_signal_connect_after ( - data->daemon, - "device-added", - (GCallback) linux_md_create_device_added_cb, - linux_md_create_data_ref (data)); - - /* set up timeout for error reporting if waiting failed - * - * (the signal handler and the timeout handler share the ref to data - * as one will cancel the other) - */ - data->device_added_timeout_id = g_timeout_add (10 * 1000, - linux_md_create_device_not_seen_cb, - data); - } + if (objpath != NULL) + { + dbus_g_method_return (context, objpath); + } + else + { + /* sit around and wait for the md array to appear */ + /* sit around wait for the cleartext device to appear */ + data->device_added_signal_handler_id = g_signal_connect_after (data->daemon, + "device-added", + (GCallback) linux_md_create_device_added_cb, + linux_md_create_data_ref (data)); - } else { - if (job_was_cancelled) { - throw_error (context, - ERROR_CANCELLED, - "Job was cancelled"); - } else { - throw_error (context, - ERROR_FAILED, - "Error assembling array: mdadm exited with exit code %d: %s", - WEXITSTATUS (status), stderr); - } + /* set up timeout for error reporting if waiting failed + * + * (the signal handler and the timeout handler share the ref to data + * as one will cancel the other) + */ + data->device_added_timeout_id = g_timeout_add (10 * 1000, linux_md_create_device_not_seen_cb, data); + } + + } + else + { + if (job_was_cancelled) + { + throw_error (context, ERROR_CANCELLED, "Job was cancelled"); + } + else + { + throw_error (context, + ERROR_FAILED, + "Error assembling array: mdadm exited with exit code %d: %s", + WEXITSTATUS (status), + stderr); } + } } /* NOTE: This is a method on the daemon, not the device. */ static void -daemon_linux_md_create_authorized_cb (Daemon *daemon, - Device *device, - DBusGMethodInvocation *context, - const gchar *action_id, - guint num_user_data, - gpointer *user_data_elements) -{ - gchar **components_as_strv = user_data_elements[0]; - gchar *level = user_data_elements[1]; - guint64 stripe_size = *((guint64*) user_data_elements[2]); - gchar *name = user_data_elements[3]; - /* TODO: use options */ - //gchar **options = user_data_elements[4]; - int n; - int m; - char *argv[128]; - GError *error; - gchar *md_device_file; - gchar *num_raid_devices_as_str; - gchar *stripe_size_as_str; - gboolean use_bitmap; - gboolean use_chunk; - - md_device_file = NULL; - num_raid_devices_as_str = NULL; - stripe_size_as_str = NULL; - error = NULL; - - /* sanity-check level */ - use_bitmap = FALSE; - use_chunk = FALSE; - if (g_strcmp0 (level, "raid0") == 0) { - use_chunk = TRUE; - } else if (g_strcmp0 (level, "raid1") == 0) { - if (stripe_size > 0) { - throw_error (context, ERROR_FAILED, - "Stripe size doesn't make sense for RAID-1"); - goto out; - } - } else if (g_strcmp0 (level, "raid4") == 0 || - g_strcmp0 (level, "raid5") == 0 || - g_strcmp0 (level, "raid6") == 0 || - g_strcmp0 (level, "raid10") == 0) { - use_bitmap = TRUE; - use_chunk = TRUE; - } else { - throw_error (context, ERROR_FAILED, - "Invalid level `%s'", - level); - goto out; - } - - /* check that all given components exist and that they are not busy - */ - for (n = 0; components_as_strv[n] != NULL; n++) { - Device *slave; - const char *component_objpath = components_as_strv[n]; - - slave = daemon_local_find_by_object_path (daemon, component_objpath); - if (slave == NULL) { - throw_error (context, ERROR_FAILED, - "Component %s doesn't exist", component_objpath); - goto out; - } +daemon_linux_md_create_authorized_cb (Daemon *daemon, + Device *device, + DBusGMethodInvocation *context, + const gchar *action_id, + guint num_user_data, + gpointer *user_data_elements) +{ + gchar **components_as_strv = user_data_elements[0]; + gchar *level = user_data_elements[1]; + guint64 stripe_size = *((guint64*) user_data_elements[2]); + gchar *name = user_data_elements[3]; + /* TODO: use options */ + //gchar **options = user_data_elements[4]; + int n; + int m; + char *argv[128]; + GError *error; + gchar *md_device_file; + gchar *num_raid_devices_as_str; + gchar *stripe_size_as_str; + gboolean use_bitmap; + gboolean use_chunk; + + md_device_file = NULL; + num_raid_devices_as_str = NULL; + stripe_size_as_str = NULL; + error = NULL; + + /* sanity-check level */ + use_bitmap = FALSE; + use_chunk = FALSE; + if (g_strcmp0 (level, "raid0") == 0) + { + use_chunk = TRUE; + } + else if (g_strcmp0 (level, "raid1") == 0) + { + if (stripe_size > 0) + { + throw_error (context, ERROR_FAILED, "Stripe size doesn't make sense for RAID-1"); + goto out; + } + } + else if (g_strcmp0 (level, "raid4") == 0 || g_strcmp0 (level, "raid5") == 0 || g_strcmp0 (level, "raid6") == 0 + || g_strcmp0 (level, "raid10") == 0) + { + use_bitmap = TRUE; + use_chunk = TRUE; + } + else + { + throw_error (context, ERROR_FAILED, "Invalid level `%s'", level); + goto out; + } - if (device_local_is_busy (slave, FALSE, &error)) { - dbus_g_method_return_error (context, error); - g_error_free (error); - goto out; - } + /* check that all given components exist and that they are not busy + */ + for (n = 0; components_as_strv[n] != NULL; n++) + { + Device *slave; + const char *component_objpath = components_as_strv[n]; + + slave = daemon_local_find_by_object_path (daemon, component_objpath); + if (slave == NULL) + { + throw_error (context, ERROR_FAILED, "Component %s doesn't exist", component_objpath); + goto out; } - /* find an unused md minor... Man, I wish mdadm could do this itself; this is slightly racy */ - for (n = 0; TRUE; n++) { - char *native_path; - char *array_state; - - /* TODO: move to /sys/class/block instead */ - native_path = g_strdup_printf ("/sys/block/md%d", n); - if (!sysfs_file_exists (native_path, "md/array_state")) { - /* Apparently this slot is free since there is no such file. So let's peruse it. */ - g_free (native_path); - break; - } else { - array_state = sysfs_get_string (native_path, "md/array_state"); - g_strstrip (array_state); - if (strcmp (array_state, "clear") == 0) { - /* It's clear! Let's use it! */ - g_free (array_state); - g_free (native_path); - break; - } - g_free (array_state); - } - g_free (native_path); - } - - md_device_file = g_strdup_printf ("/dev/md%d", n); - - num_raid_devices_as_str = g_strdup_printf ("%d", g_strv_length (components_as_strv)); - - if (stripe_size > 0) - stripe_size_as_str = g_strdup_printf ("%d", ((gint) stripe_size) / 1024); - - n = 0; - argv[n++] = "mdadm"; - argv[n++] = "--create"; - argv[n++] = md_device_file; - argv[n++] = "--level"; - argv[n++] = level; - argv[n++] = "--raid-devices"; - argv[n++] = num_raid_devices_as_str; - argv[n++] = "--metadata"; - argv[n++] = "1.2"; - argv[n++] = "--name"; - argv[n++] = name; - argv[n++] = "--homehost"; - argv[n++] = ""; - if (use_bitmap) { - argv[n++] = "--bitmap"; - argv[n++] = "internal"; - } - if (use_chunk && stripe_size_as_str != NULL) { - argv[n++] = "--chunk"; - argv[n++] = stripe_size_as_str; - } - for (m = 0; components_as_strv[m] != NULL; m++) { - Device *slave; - const char *component_objpath = components_as_strv[m]; - - slave = daemon_local_find_by_object_path (daemon, component_objpath); - if (slave == NULL) { - throw_error (context, ERROR_FAILED, - "Component %s doesn't exist", component_objpath); - goto out; - } + if (device_local_is_busy (slave, FALSE, &error)) + { + dbus_g_method_return_error (context, error); + g_error_free (error); + goto out; + } + } - if (n >= (int) sizeof (argv) - 1) { - throw_error (context, - ERROR_FAILED, - "Too many components"); - goto out; - } + /* find an unused md minor... Man, I wish mdadm could do this itself; this is slightly racy */ + for (n = 0; TRUE; n++) + { + char *native_path; + char *array_state; - argv[n++] = (char *) slave->priv->device_file; + /* TODO: move to /sys/class/block instead */ + native_path = g_strdup_printf ("/sys/block/md%d", n); + if (!sysfs_file_exists (native_path, "md/array_state")) + { + /* Apparently this slot is free since there is no such file. So let's peruse it. */ + g_free (native_path); + break; } - argv[n++] = NULL; + else + { + array_state = sysfs_get_string (native_path, "md/array_state"); + g_strstrip (array_state); + if (strcmp (array_state, "clear") == 0) + { + /* It's clear! Let's use it! */ + g_free (array_state); + g_free (native_path); + break; + } + g_free (array_state); + } + g_free (native_path); + } - //for (m = 0; argv[m] != NULL; m++) - // g_debug ("arg[%d] = `%s'", m, argv[m]); + md_device_file = g_strdup_printf ("/dev/md%d", n); + + num_raid_devices_as_str = g_strdup_printf ("%d", g_strv_length (components_as_strv)); + + if (stripe_size > 0) + stripe_size_as_str = g_strdup_printf ("%d", ((gint) stripe_size) / 1024); + + n = 0; + argv[n++] = "mdadm"; + argv[n++] = "--create"; + argv[n++] = md_device_file; + argv[n++] = "--level"; + argv[n++] = level; + argv[n++] = "--raid-devices"; + argv[n++] = num_raid_devices_as_str; + argv[n++] = "--metadata"; + argv[n++] = "1.2"; + argv[n++] = "--name"; + argv[n++] = name; + argv[n++] = "--homehost"; + argv[n++] = ""; + if (use_bitmap) + { + argv[n++] = "--bitmap"; + argv[n++] = "internal"; + } + if (use_chunk && stripe_size_as_str != NULL) + { + argv[n++] = "--chunk"; + argv[n++] = stripe_size_as_str; + } + for (m = 0; components_as_strv[m] != NULL; m++) + { + Device *slave; + const char *component_objpath = components_as_strv[m]; + + slave = daemon_local_find_by_object_path (daemon, component_objpath); + if (slave == NULL) + { + throw_error (context, ERROR_FAILED, "Component %s doesn't exist", component_objpath); + goto out; + } - if (!job_new (context, - "LinuxMdCreate", - TRUE, - NULL, - argv, - NULL, - linux_md_create_completed_cb, - FALSE, - linux_md_create_data_new (context, daemon, components_as_strv[0]), - (GDestroyNotify) linux_md_create_data_unref)) { - goto out; + if (n >= (int) sizeof(argv) - 1) + { + throw_error (context, ERROR_FAILED, "Too many components"); + goto out; } -out: - g_free (md_device_file); - g_free (num_raid_devices_as_str); - g_free (stripe_size_as_str); + argv[n++] = (char *) slave->priv->device_file; + } + argv[n++] = NULL; + + //for (m = 0; argv[m] != NULL; m++) + // g_debug ("arg[%d] = `%s'", m, argv[m]); + + if (!job_new (context, + "LinuxMdCreate", + TRUE, + NULL, + argv, + NULL, + linux_md_create_completed_cb, + FALSE, + linux_md_create_data_new (context, daemon, components_as_strv[0]), + (GDestroyNotify) linux_md_create_data_unref)) + { + goto out; + } + + out: + g_free (md_device_file); + g_free (num_raid_devices_as_str); + g_free (stripe_size_as_str); } /* NOTE: This is a method on the daemon, not the device. */ gboolean -daemon_linux_md_create (Daemon *daemon, - GPtrArray *components, - char *level, - guint64 stripe_size, - char *name, - char **options, - DBusGMethodInvocation *context) -{ - gchar **components_as_strv; - guint n; - - components_as_strv = g_new0 (gchar *, components->len + 1); - for (n = 0; n < components->len; n++) - components_as_strv[n] = g_strdup (components->pdata[n]); - - daemon_local_check_auth (daemon, - NULL, - "org.freedesktop.devicekit.disks.linux-md", - "LinuxMdCreate", - TRUE, - daemon_linux_md_create_authorized_cb, - context, - 4, - components_as_strv, g_strfreev, - g_strdup (level), g_free, - g_memdup (&stripe_size, sizeof (guint64)), g_free, - g_strdup (name), g_free, - g_strdupv (options), g_strfreev); - - return TRUE; +daemon_linux_md_create (Daemon *daemon, + GPtrArray *components, + char *level, + guint64 stripe_size, + char *name, + char **options, + DBusGMethodInvocation *context) +{ + gchar **components_as_strv; + guint n; + + components_as_strv = g_new0 (gchar *, components->len + 1); + for (n = 0; n < components->len; n++) + components_as_strv[n] = g_strdup (components->pdata[n]); + + daemon_local_check_auth (daemon, + NULL, + "org.freedesktop.devicekit.disks.linux-md", + "LinuxMdCreate", + TRUE, + daemon_linux_md_create_authorized_cb, + context, + 4, + components_as_strv, + g_strfreev, + g_strdup (level), + g_free, + g_memdup (&stripe_size, sizeof(guint64)), + g_free, + g_strdup (name), + g_free, + g_strdupv (options), + g_strfreev); + + return TRUE; } /*--------------------------------------------------------------------------------------------------------------*/ -typedef struct { - char *mount_path; - ForceRemovalCompleteFunc fr_callback; - gpointer fr_user_data; +typedef struct +{ + char *mount_path; + ForceRemovalCompleteFunc fr_callback; + gpointer fr_user_data; } ForceUnmountData; static ForceUnmountData * -force_unmount_data_new (const gchar *mount_path, - ForceRemovalCompleteFunc fr_callback, - gpointer fr_user_data) +force_unmount_data_new (const gchar *mount_path, + ForceRemovalCompleteFunc fr_callback, + gpointer fr_user_data) { - ForceUnmountData *data; + ForceUnmountData *data; - data = g_new0 (ForceUnmountData, 1); - data->mount_path = g_strdup (mount_path); - data->fr_callback = fr_callback; - data->fr_user_data = fr_user_data; + data = g_new0 (ForceUnmountData, 1); + data->mount_path = g_strdup (mount_path); + data->fr_callback = fr_callback; + data->fr_user_data = fr_user_data; - return data; + return data; } static void force_unmount_data_unref (ForceUnmountData *data) { - g_free (data->mount_path); - g_free (data); + g_free (data->mount_path); + g_free (data); } static void @@ -9763,367 +10439,376 @@ force_unmount_completed_cb (DBusGMethodInvocation *context, const char *stdout, gpointer user_data) { - ForceUnmountData *data = user_data; + ForceUnmountData *data = user_data; - if (WEXITSTATUS (status) == 0 && !job_was_cancelled) { + if (WEXITSTATUS (status) == 0 && !job_was_cancelled) + { - g_print ("**** NOTE: Successfully force unmounted device %s\n", device->priv->device_file); - /* update_info_mount_state() will update the mounts file and clean up the directory if needed */ - update_info (device); + g_print ("**** NOTE: Successfully force unmounted device %s\n", device->priv->device_file); + /* update_info_mount_state() will update the mounts file and clean up the directory if needed */ + update_info (device); - if (data->fr_callback != NULL) - data->fr_callback (device, TRUE, data->fr_user_data); - } else { - g_print ("**** NOTE: force unmount failed: %s\n", stderr); - if (data->fr_callback != NULL) - data->fr_callback (device, FALSE, data->fr_user_data); - } + if (data->fr_callback != NULL) + data->fr_callback (device, TRUE, data->fr_user_data); + } + else + { + g_print ("**** NOTE: force unmount failed: %s\n", stderr); + if (data->fr_callback != NULL) + data->fr_callback (device, FALSE, data->fr_user_data); + } } static void -force_unmount (Device *device, - ForceRemovalCompleteFunc callback, - gpointer user_data) -{ - int n; - char *argv[16]; - const gchar *mount_path; - - mount_path = ((gchar **) device->priv->device_mount_paths->pdata)[0]; - - n = 0; - argv[n++] = "umount"; - /* on Linux, we only have lazy unmount for now */ - argv[n++] = "-l"; - argv[n++] = (gchar *) mount_path; - argv[n++] = NULL; - - if (!job_new (NULL, - "ForceUnmount", - FALSE, - device, - argv, - NULL, - force_unmount_completed_cb, - FALSE, - force_unmount_data_new (mount_path, callback, user_data), - (GDestroyNotify) force_unmount_data_unref)) { - g_warning ("Couldn't spawn unmount for force unmounting %s", mount_path); - if (callback != NULL) - callback (device, FALSE, user_data); - } +force_unmount (Device *device, + ForceRemovalCompleteFunc callback, + gpointer user_data) +{ + int n; + char *argv[16]; + const gchar *mount_path; + + mount_path = ((gchar **) device->priv->device_mount_paths->pdata)[0]; + + n = 0; + argv[n++] = "umount"; + /* on Linux, we only have lazy unmount for now */ + argv[n++] = "-l"; + argv[n++] = (gchar *) mount_path; + argv[n++] = NULL; + + if (!job_new (NULL, + "ForceUnmount", + FALSE, + device, + argv, + NULL, + force_unmount_completed_cb, + FALSE, + force_unmount_data_new (mount_path, callback, user_data), + (GDestroyNotify) force_unmount_data_unref)) + { + g_warning ("Couldn't spawn unmount for force unmounting %s", mount_path); + if (callback != NULL) + callback (device, FALSE, user_data); + } } /*--------------------------------------------------------------------------------------------------------------*/ -typedef struct { - Device *device; - char *dm_name; - ForceRemovalCompleteFunc fr_callback; - gpointer fr_user_data; +typedef struct +{ + Device *device; + char *dm_name; + ForceRemovalCompleteFunc fr_callback; + gpointer fr_user_data; } ForceLuksTeardownData; static void force_luks_teardown_completed_cb (DBusGMethodInvocation *context, - Device *device, - gboolean job_was_cancelled, - int status, - const char *stderr, - const char *stdout, - gpointer user_data) + Device *device, + gboolean job_was_cancelled, + int status, + const char *stderr, + const char *stdout, + gpointer user_data) { - ForceLuksTeardownData *data = user_data; + ForceLuksTeardownData *data = user_data; - if (WEXITSTATUS (status) == 0 && !job_was_cancelled) { + if (WEXITSTATUS (status) == 0 && !job_was_cancelled) + { - g_print ("**** NOTE: Successfully teared down luks device %s\n", device->priv->device_file); + g_print ("**** NOTE: Successfully teared down luks device %s\n", device->priv->device_file); - if (data->fr_callback != NULL) - data->fr_callback (device, TRUE, data->fr_user_data); - } else { - g_print ("**** NOTE: force luks teardown failed: %s\n", stderr); - if (data->fr_callback != NULL) - data->fr_callback (device, FALSE, data->fr_user_data); - } + if (data->fr_callback != NULL) + data->fr_callback (device, TRUE, data->fr_user_data); + } + else + { + g_print ("**** NOTE: force luks teardown failed: %s\n", stderr); + if (data->fr_callback != NULL) + data->fr_callback (device, FALSE, data->fr_user_data); + } } static ForceLuksTeardownData * -force_luks_teardown_data_new (Device *device, - const char *dm_name, - ForceRemovalCompleteFunc fr_callback, - gpointer fr_user_data) +force_luks_teardown_data_new (Device *device, + const char *dm_name, + ForceRemovalCompleteFunc fr_callback, + gpointer fr_user_data) { - ForceLuksTeardownData *data; + ForceLuksTeardownData *data; - data = g_new0 (ForceLuksTeardownData, 1); - data->device = g_object_ref (device); - data->dm_name = g_strdup (dm_name); - data->fr_callback = fr_callback; - data->fr_user_data = fr_user_data; - return data; + data = g_new0 (ForceLuksTeardownData, 1); + data->device = g_object_ref (device); + data->dm_name = g_strdup (dm_name); + data->fr_callback = fr_callback; + data->fr_user_data = fr_user_data; + return data; } static void force_luks_teardown_data_unref (ForceLuksTeardownData *data) { - if (data->device != NULL) - g_object_unref (data->device); - g_free (data->dm_name); - g_free (data); + if (data->device != NULL) + g_object_unref (data->device); + g_free (data->dm_name); + g_free (data); } static void force_luks_teardown_cleartext_done (Device *device, - gboolean success, - gpointer user_data) + gboolean success, + gpointer user_data) { - int n; - char *argv[16]; - ForceLuksTeardownData *data = user_data; - - if (!success) { - if (data->fr_callback != NULL) - data->fr_callback (data->device, FALSE, data->fr_user_data); - - force_luks_teardown_data_unref (data); - goto out; - } - - /* ok, clear text device is out of the way; now tear it down */ + int n; + char *argv[16]; + ForceLuksTeardownData *data = user_data; - n = 0; - argv[n++] = "cryptsetup"; - argv[n++] = "luksClose"; - argv[n++] = data->dm_name; - argv[n++] = NULL; + if (!success) + { + if (data->fr_callback != NULL) + data->fr_callback (data->device, FALSE, data->fr_user_data); - //g_debug ("doing cryptsetup luksClose %s", data->dm_name); + force_luks_teardown_data_unref (data); + goto out; + } - if (!job_new (NULL, - "ForceLuksTeardown", - FALSE, - data->device, - argv, - NULL, - force_luks_teardown_completed_cb, - FALSE, - data, - (GDestroyNotify) force_luks_teardown_data_unref)) { + /* ok, clear text device is out of the way; now tear it down */ + + n = 0; + argv[n++] = "cryptsetup"; + argv[n++] = "luksClose"; + argv[n++] = data->dm_name; + argv[n++] = NULL; + + //g_debug ("doing cryptsetup luksClose %s", data->dm_name); + + if (!job_new (NULL, + "ForceLuksTeardown", + FALSE, + data->device, + argv, + NULL, + force_luks_teardown_completed_cb, + FALSE, + data, + (GDestroyNotify) force_luks_teardown_data_unref)) + { - g_warning ("Couldn't spawn cryptsetup for force teardown for device %s", data->dm_name); - if (data->fr_callback != NULL) - data->fr_callback (data->device, FALSE, data->fr_user_data); + g_warning ("Couldn't spawn cryptsetup for force teardown for device %s", data->dm_name); + if (data->fr_callback != NULL) + data->fr_callback (data->device, FALSE, data->fr_user_data); - force_luks_teardown_data_unref (data); - } -out: - ; + force_luks_teardown_data_unref (data); + } + out: + ; } static void -force_luks_teardown (Device *device, - Device *cleartext_device, - ForceRemovalCompleteFunc callback, - gpointer user_data) +force_luks_teardown (Device *device, + Device *cleartext_device, + ForceRemovalCompleteFunc callback, + gpointer user_data) { - /* first we gotta force remove the clear text device */ - force_removal (cleartext_device, - force_luks_teardown_cleartext_done, - force_luks_teardown_data_new (device, - cleartext_device->priv->dm_name, - callback, - user_data)); + /* first we gotta force remove the clear text device */ + force_removal (cleartext_device, + force_luks_teardown_cleartext_done, + force_luks_teardown_data_new (device, cleartext_device->priv->dm_name, callback, user_data)); } /*--------------------------------------------------------------------------------------------------------------*/ static void -force_removal (Device *device, - ForceRemovalCompleteFunc callback, - gpointer user_data) -{ - //g_debug ("in force removal for %s", device->priv->device_file); - - /* Device is going bye bye. If this device is - * - * - Mounted by us, then forcibly unmount it. - * - * - If it's a luks device, check if there's cleartext - * companion. If so, tear it down if it was setup by us. - * - */ - if (device->priv->device_is_mounted && device->priv->device_mount_paths->len > 0) { - gboolean remove_dir_on_unmount; - - if (mount_file_has_device (device->priv->device_file, NULL, &remove_dir_on_unmount)) { - g_print ("**** NOTE: Force unmounting device %s\n", device->priv->device_file); - force_unmount (device, callback, user_data); - goto pending; - } +force_removal (Device *device, + ForceRemovalCompleteFunc callback, + gpointer user_data) +{ + //g_debug ("in force removal for %s", device->priv->device_file); + + /* Device is going bye bye. If this device is + * + * - Mounted by us, then forcibly unmount it. + * + * - If it's a luks device, check if there's cleartext + * companion. If so, tear it down if it was setup by us. + * + */ + if (device->priv->device_is_mounted && device->priv->device_mount_paths->len > 0) + { + gboolean remove_dir_on_unmount; + + if (mount_file_has_device (device->priv->device_file, NULL, &remove_dir_on_unmount)) + { + g_print ("**** NOTE: Force unmounting device %s\n", device->priv->device_file); + force_unmount (device, callback, user_data); + goto pending; } + } - if (device->priv->id_usage != NULL && strcmp (device->priv->id_usage, "crypto") == 0) { - GList *devices; - GList *l; + if (device->priv->id_usage != NULL && strcmp (device->priv->id_usage, "crypto") == 0) + { + GList *devices; + GList *l; - /* look for cleartext device */ - devices = daemon_local_get_all_devices (device->priv->daemon); - for (l = devices; l != NULL; l = l->next) { - Device *d = DEVICE (l->data); - if (d->priv->device_is_luks_cleartext && - d->priv->luks_cleartext_slave != NULL && - strcmp (d->priv->luks_cleartext_slave, device->priv->object_path) == 0) { + /* look for cleartext device */ + devices = daemon_local_get_all_devices (device->priv->daemon); + for (l = devices; l != NULL; l = l->next) + { + Device *d = DEVICE (l->data); + if (d->priv->device_is_luks_cleartext && d->priv->luks_cleartext_slave != NULL + && strcmp (d->priv->luks_cleartext_slave, device->priv->object_path) == 0) + { - /* Check whether it is set up by us */ - if (d->priv->dm_name != NULL && - g_str_has_prefix (d->priv->dm_name, "udisks-luks-uuid-")) { + /* Check whether it is set up by us */ + if (d->priv->dm_name != NULL && g_str_has_prefix (d->priv->dm_name, "udisks-luks-uuid-")) + { - g_print ("**** NOTE: Force luks teardown device %s (cleartext %s)\n", - device->priv->device_file, - d->priv->device_file); + g_print ("**** NOTE: Force luks teardown device %s (cleartext %s)\n", + device->priv->device_file, + d->priv->device_file); - /* Gotcha */ - force_luks_teardown (device, d, callback, user_data); - goto pending; - } - } + /* Gotcha */ + force_luks_teardown (device, d, callback, user_data); + goto pending; } + } } + } - /* nothing to force remove */ - if (callback != NULL) - callback (device, TRUE, user_data); + /* nothing to force remove */ + if (callback != NULL) + callback (device, TRUE, user_data); -pending: - ; + pending: + ; } - /*--------------------------------------------------------------------------------------------------------------*/ static void polling_inhibitor_disconnected_cb (Inhibitor *inhibitor, - Device *device) + Device *device) { - device->priv->polling_inhibitors = g_list_remove (device->priv->polling_inhibitors, inhibitor); - g_signal_handlers_disconnect_by_func (inhibitor, polling_inhibitor_disconnected_cb, device); - g_object_unref (inhibitor); + device->priv->polling_inhibitors = g_list_remove (device->priv->polling_inhibitors, inhibitor); + g_signal_handlers_disconnect_by_func (inhibitor, polling_inhibitor_disconnected_cb, device); + g_object_unref (inhibitor); - update_info (device); - drain_pending_changes (device, FALSE); - daemon_local_update_poller (device->priv->daemon); + update_info (device); + drain_pending_changes (device, FALSE); + daemon_local_update_poller (device->priv->daemon); } static void -device_drive_inhibit_polling_authorized_cb (Daemon *daemon, - Device *device, - DBusGMethodInvocation *context, - const gchar *action_id, - guint num_user_data, - gpointer *user_data_elements) -{ - gchar **options = user_data_elements[0]; - Inhibitor *inhibitor; - guint n; - - for (n = 0; options[n] != NULL; n++) { - const char *option = options[n]; - throw_error (context, - ERROR_INVALID_OPTION, - "Unknown option %s", option); - goto out; - } +device_drive_inhibit_polling_authorized_cb (Daemon *daemon, + Device *device, + DBusGMethodInvocation *context, + const gchar *action_id, + guint num_user_data, + gpointer *user_data_elements) +{ + gchar **options = user_data_elements[0]; + Inhibitor *inhibitor; + guint n; + + for (n = 0; options[n] != NULL; n++) + { + const char *option = options[n]; + throw_error (context, ERROR_INVALID_OPTION, "Unknown option %s", option); + goto out; + } - inhibitor = inhibitor_new (context); + inhibitor = inhibitor_new (context); - device->priv->polling_inhibitors = g_list_prepend (device->priv->polling_inhibitors, inhibitor); - g_signal_connect (inhibitor, "disconnected", G_CALLBACK (polling_inhibitor_disconnected_cb), device); + device->priv->polling_inhibitors = g_list_prepend (device->priv->polling_inhibitors, inhibitor); + g_signal_connect (inhibitor, "disconnected", G_CALLBACK (polling_inhibitor_disconnected_cb), device); - update_info (device); - drain_pending_changes (device, FALSE); - daemon_local_update_poller (device->priv->daemon); + update_info (device); + drain_pending_changes (device, FALSE); + daemon_local_update_poller (device->priv->daemon); - dbus_g_method_return (context, inhibitor_get_cookie (inhibitor)); + dbus_g_method_return (context, inhibitor_get_cookie (inhibitor)); -out: - ; + out: + ; } gboolean -device_drive_inhibit_polling (Device *device, - char **options, - DBusGMethodInvocation *context) +device_drive_inhibit_polling (Device *device, + char **options, + DBusGMethodInvocation *context) { - if (!device->priv->device_is_drive) { - throw_error (context, ERROR_FAILED, - "Device is not a drive"); - goto out; - } - - if (!device->priv->device_is_media_change_detection_inhibitable) { - throw_error (context, ERROR_FAILED, - "Media detection cannot be inhibited"); - goto out; - } + if (!device->priv->device_is_drive) + { + throw_error (context, ERROR_FAILED, "Device is not a drive"); + goto out; + } - daemon_local_check_auth (device->priv->daemon, - device, - "org.freedesktop.devicekit.disks.inhibit-polling", - "DriveInhibitPolling", - TRUE, - device_drive_inhibit_polling_authorized_cb, - context, - 1, - g_strdupv (options), g_strfreev); + if (!device->priv->device_is_media_change_detection_inhibitable) + { + throw_error (context, ERROR_FAILED, "Media detection cannot be inhibited"); + goto out; + } + daemon_local_check_auth (device->priv->daemon, + device, + "org.freedesktop.devicekit.disks.inhibit-polling", + "DriveInhibitPolling", + TRUE, + device_drive_inhibit_polling_authorized_cb, + context, + 1, + g_strdupv (options), + g_strfreev); out: - return TRUE; + return TRUE; } - /*--------------------------------------------------------------------------------------------------------------*/ gboolean -device_drive_uninhibit_polling (Device *device, - char *cookie, - DBusGMethodInvocation *context) +device_drive_uninhibit_polling (Device *device, + char *cookie, + DBusGMethodInvocation *context) { - const gchar *sender; - Inhibitor *inhibitor; - GList *l; + const gchar *sender; + Inhibitor *inhibitor; + GList *l; - sender = dbus_g_method_get_sender (context); + sender = dbus_g_method_get_sender (context); - inhibitor = NULL; - for (l = device->priv->polling_inhibitors; l != NULL; l = l->next) { - Inhibitor *i = INHIBITOR (l->data); + inhibitor = NULL; + for (l = device->priv->polling_inhibitors; l != NULL; l = l->next) + { + Inhibitor *i = INHIBITOR (l->data); - if (g_strcmp0 (inhibitor_get_unique_dbus_name (i), sender) == 0 && - g_strcmp0 (inhibitor_get_cookie (i), cookie) == 0) { - inhibitor = i; - break; - } + if (g_strcmp0 (inhibitor_get_unique_dbus_name (i), sender) == 0 && g_strcmp0 (inhibitor_get_cookie (i), cookie) + == 0) + { + inhibitor = i; + break; } + } - if (inhibitor == NULL) { - throw_error (context, - ERROR_FAILED, - "No such inhibitor"); - goto out; - } + if (inhibitor == NULL) + { + throw_error (context, ERROR_FAILED, "No such inhibitor"); + goto out; + } - device->priv->polling_inhibitors = g_list_remove (device->priv->polling_inhibitors, inhibitor); - g_object_unref (inhibitor); + device->priv->polling_inhibitors = g_list_remove (device->priv->polling_inhibitors, inhibitor); + g_object_unref (inhibitor); - update_info (device); - drain_pending_changes (device, FALSE); - daemon_local_update_poller (device->priv->daemon); + update_info (device); + drain_pending_changes (device, FALSE); + daemon_local_update_poller (device->priv->daemon); - dbus_g_method_return (context); + dbus_g_method_return (context); out: - return TRUE; + return TRUE; } /*--------------------------------------------------------------------------------------------------------------*/ @@ -10137,235 +10822,231 @@ drive_poll_media_completed_cb (DBusGMethodInvocation *context, const char *stdout, gpointer user_data) { - if (WEXITSTATUS (status) == 0 && !job_was_cancelled) { - - device_generate_kernel_change_event (device); - - dbus_g_method_return (context); - } else { - if (job_was_cancelled) { - throw_error (context, - ERROR_CANCELLED, - "Job was cancelled"); - } else { - throw_error (context, - ERROR_FAILED, - "Error detaching: helper exited with exit code %d: %s", - WEXITSTATUS (status), - stderr); - } + if (WEXITSTATUS (status) == 0 && !job_was_cancelled) + { + + device_generate_kernel_change_event (device); + + dbus_g_method_return (context); + } + else + { + if (job_was_cancelled) + { + throw_error (context, ERROR_CANCELLED, "Job was cancelled"); + } + else + { + throw_error (context, + ERROR_FAILED, + "Error detaching: helper exited with exit code %d: %s", + WEXITSTATUS (status), + stderr); } + } } static void -device_drive_poll_media_authorized_cb (Daemon *daemon, - Device *device, - DBusGMethodInvocation *context, - const gchar *action_id, - guint num_user_data, - gpointer *user_data_elements) -{ - int n; - char *argv[16]; - - n = 0; - argv[n++] = PACKAGE_LIBEXEC_DIR "/udisks-helper-drive-poll"; - argv[n++] = device->priv->device_file; - argv[n++] = NULL; - - if (!job_new (context, - "DrivePollMedia", - FALSE, - device, - argv, - NULL, - drive_poll_media_completed_cb, - FALSE, - NULL, - NULL)) { - goto out; - } +device_drive_poll_media_authorized_cb (Daemon *daemon, + Device *device, + DBusGMethodInvocation *context, + const gchar *action_id, + guint num_user_data, + gpointer *user_data_elements) +{ + int n; + char *argv[16]; + + n = 0; + argv[n++] = PACKAGE_LIBEXEC_DIR "/udisks-helper-drive-poll"; + argv[n++] = device->priv->device_file; + argv[n++] = NULL; + + if (!job_new (context, "DrivePollMedia", FALSE, device, argv, NULL, drive_poll_media_completed_cb, FALSE, NULL, NULL)) + { + goto out; + } out: - ; + ; } gboolean -device_drive_poll_media (Device *device, - DBusGMethodInvocation *context) -{ - if (!device->priv->device_is_drive) { - throw_error (context, ERROR_FAILED, - "Device is not a drive"); - goto out; - } - - daemon_local_check_auth (device->priv->daemon, - device, - "org.freedesktop.devicekit.disks.inhibit-polling", - "DrivePollMedia", - TRUE, - device_drive_poll_media_authorized_cb, - context, - 0); +device_drive_poll_media (Device *device, + DBusGMethodInvocation *context) +{ + if (!device->priv->device_is_drive) + { + throw_error (context, ERROR_FAILED, "Device is not a drive"); + goto out; + } + + daemon_local_check_auth (device->priv->daemon, + device, + "org.freedesktop.devicekit.disks.inhibit-polling", + "DrivePollMedia", + TRUE, + device_drive_poll_media_authorized_cb, + context, + 0); out: - return TRUE; + return TRUE; } /*--------------------------------------------------------------------------------------------------------------*/ static void spindown_inhibitor_disconnected_cb (Inhibitor *inhibitor, - Device *device) + Device *device) { - device->priv->spindown_inhibitors = g_list_remove (device->priv->spindown_inhibitors, inhibitor); - g_signal_handlers_disconnect_by_func (inhibitor, spindown_inhibitor_disconnected_cb, device); - g_object_unref (inhibitor); + device->priv->spindown_inhibitors = g_list_remove (device->priv->spindown_inhibitors, inhibitor); + g_signal_handlers_disconnect_by_func (inhibitor, spindown_inhibitor_disconnected_cb, device); + g_object_unref (inhibitor); - update_info (device); - drain_pending_changes (device, FALSE); - daemon_local_update_spindown (device->priv->daemon); + update_info (device); + drain_pending_changes (device, FALSE); + daemon_local_update_spindown (device->priv->daemon); } static void -device_drive_set_spindown_timeout_authorized_cb (Daemon *daemon, - Device *device, - DBusGMethodInvocation *context, - const gchar *action_id, - guint num_user_data, - gpointer *user_data_elements) +device_drive_set_spindown_timeout_authorized_cb (Daemon *daemon, + Device *device, + DBusGMethodInvocation *context, + const gchar *action_id, + guint num_user_data, + gpointer *user_data_elements) { - gint timeout_seconds = GPOINTER_TO_INT (user_data_elements[0]); - gchar **options = user_data_elements[1]; - Inhibitor *inhibitor; - guint n; + gint timeout_seconds = GPOINTER_TO_INT (user_data_elements[0]); + gchar **options = user_data_elements[1]; + Inhibitor *inhibitor; + guint n; - if (!device->priv->device_is_drive) { - throw_error (context, ERROR_FAILED, - "Device is not a drive"); - goto out; - } + if (!device->priv->device_is_drive) + { + throw_error (context, ERROR_FAILED, "Device is not a drive"); + goto out; + } - if (!device->priv->drive_can_spindown) { - throw_error (context, ERROR_FAILED, - "Cannot spindown device"); - goto out; - } + if (!device->priv->drive_can_spindown) + { + throw_error (context, ERROR_FAILED, "Cannot spindown device"); + goto out; + } - if (timeout_seconds < 1) { - throw_error (context, ERROR_FAILED, - "Timeout seconds must be at least 1"); - goto out; - } + if (timeout_seconds < 1) + { + throw_error (context, ERROR_FAILED, "Timeout seconds must be at least 1"); + goto out; + } - for (n = 0; options[n] != NULL; n++) { - const char *option = options[n]; - throw_error (context, - ERROR_INVALID_OPTION, - "Unknown option %s", option); - goto out; - } + for (n = 0; options[n] != NULL; n++) + { + const char *option = options[n]; + throw_error (context, ERROR_INVALID_OPTION, "Unknown option %s", option); + goto out; + } - inhibitor = inhibitor_new (context); + inhibitor = inhibitor_new (context); - g_object_set_data (G_OBJECT (inhibitor), "spindown-timeout-seconds", GINT_TO_POINTER (timeout_seconds)); + g_object_set_data (G_OBJECT (inhibitor), "spindown-timeout-seconds", GINT_TO_POINTER (timeout_seconds)); - device->priv->spindown_inhibitors = g_list_prepend (device->priv->spindown_inhibitors, inhibitor); - g_signal_connect (inhibitor, "disconnected", G_CALLBACK (spindown_inhibitor_disconnected_cb), device); + device->priv->spindown_inhibitors = g_list_prepend (device->priv->spindown_inhibitors, inhibitor); + g_signal_connect (inhibitor, "disconnected", G_CALLBACK (spindown_inhibitor_disconnected_cb), device); - update_info (device); - drain_pending_changes (device, FALSE); - daemon_local_update_spindown (device->priv->daemon); + update_info (device); + drain_pending_changes (device, FALSE); + daemon_local_update_spindown (device->priv->daemon); - dbus_g_method_return (context, inhibitor_get_cookie (inhibitor)); + dbus_g_method_return (context, inhibitor_get_cookie (inhibitor)); -out: - ; + out: + ; } gboolean -device_drive_set_spindown_timeout (Device *device, - int timeout_seconds, - char **options, - DBusGMethodInvocation *context) +device_drive_set_spindown_timeout (Device *device, + int timeout_seconds, + char **options, + DBusGMethodInvocation *context) { - if (!device->priv->device_is_drive) { - throw_error (context, ERROR_FAILED, - "Device is not a drive"); - goto out; - } - - if (!device->priv->drive_can_spindown) { - throw_error (context, ERROR_FAILED, - "Cannot spindown device"); - goto out; - } + if (!device->priv->device_is_drive) + { + throw_error (context, ERROR_FAILED, "Device is not a drive"); + goto out; + } - if (timeout_seconds < 1) { - throw_error (context, ERROR_FAILED, - "Timeout seconds must be at least 1"); - goto out; - } + if (!device->priv->drive_can_spindown) + { + throw_error (context, ERROR_FAILED, "Cannot spindown device"); + goto out; + } - daemon_local_check_auth (device->priv->daemon, - device, - "org.freedesktop.devicekit.disks.drive-set-spindown", - "DriveSetSpindownTimeout", - TRUE, - device_drive_set_spindown_timeout_authorized_cb, - context, - 2, - GINT_TO_POINTER (timeout_seconds), NULL, - g_strdupv (options), g_strfreev); + if (timeout_seconds < 1) + { + throw_error (context, ERROR_FAILED, "Timeout seconds must be at least 1"); + goto out; + } + daemon_local_check_auth (device->priv->daemon, + device, + "org.freedesktop.devicekit.disks.drive-set-spindown", + "DriveSetSpindownTimeout", + TRUE, + device_drive_set_spindown_timeout_authorized_cb, + context, + 2, + GINT_TO_POINTER (timeout_seconds), + NULL, + g_strdupv (options), + g_strfreev); out: - return TRUE; + return TRUE; } - /*--------------------------------------------------------------------------------------------------------------*/ gboolean -device_drive_unset_spindown_timeout (Device *device, - char *cookie, - DBusGMethodInvocation *context) +device_drive_unset_spindown_timeout (Device *device, + char *cookie, + DBusGMethodInvocation *context) { - const gchar *sender; - Inhibitor *inhibitor; - GList *l; + const gchar *sender; + Inhibitor *inhibitor; + GList *l; - sender = dbus_g_method_get_sender (context); + sender = dbus_g_method_get_sender (context); - inhibitor = NULL; - for (l = device->priv->spindown_inhibitors; l != NULL; l = l->next) { - Inhibitor *i = INHIBITOR (l->data); + inhibitor = NULL; + for (l = device->priv->spindown_inhibitors; l != NULL; l = l->next) + { + Inhibitor *i = INHIBITOR (l->data); - if (g_strcmp0 (inhibitor_get_unique_dbus_name (i), sender) == 0 && - g_strcmp0 (inhibitor_get_cookie (i), cookie) == 0) { - inhibitor = i; - break; - } + if (g_strcmp0 (inhibitor_get_unique_dbus_name (i), sender) == 0 && g_strcmp0 (inhibitor_get_cookie (i), cookie) + == 0) + { + inhibitor = i; + break; } + } - if (inhibitor == NULL) { - throw_error (context, - ERROR_FAILED, - "No such spindown configurator"); - goto out; - } + if (inhibitor == NULL) + { + throw_error (context, ERROR_FAILED, "No such spindown configurator"); + goto out; + } - device->priv->spindown_inhibitors = g_list_remove (device->priv->spindown_inhibitors, inhibitor); - g_object_unref (inhibitor); + device->priv->spindown_inhibitors = g_list_remove (device->priv->spindown_inhibitors, inhibitor); + g_object_unref (inhibitor); - update_info (device); - drain_pending_changes (device, FALSE); - daemon_local_update_spindown (device->priv->daemon); + update_info (device); + drain_pending_changes (device, FALSE); + daemon_local_update_spindown (device->priv->daemon); - dbus_g_method_return (context); + dbus_g_method_return (context); out: - return TRUE; + return TRUE; } /*--------------------------------------------------------------------------------------------------------------*/ @@ -10379,192 +11060,180 @@ drive_benchmark_completed_cb (DBusGMethodInvocation *context, const gchar *stdout, gpointer user_data) { - if (WEXITSTATUS (status) == 0 && !job_was_cancelled) { - GPtrArray *read_transfer_rate_array; - GPtrArray *write_transfer_rate_array; - GPtrArray *access_time_array; - gchar **lines; - guint n; - GType elem_gtype; - - elem_gtype = dbus_g_type_get_struct ("GValueArray", - G_TYPE_UINT64, - G_TYPE_DOUBLE, - G_TYPE_INVALID); - - read_transfer_rate_array = g_ptr_array_new_with_free_func ((GDestroyNotify) g_value_array_free); - write_transfer_rate_array = g_ptr_array_new_with_free_func ((GDestroyNotify) g_value_array_free); - access_time_array = g_ptr_array_new_with_free_func ((GDestroyNotify) g_value_array_free); - - lines = g_strsplit (stdout, "\n", 0); - for (n = 0; lines != NULL && lines[n] != NULL; n++) { - const gchar *line = lines[n]; - guint64 offset; - gdouble rate; - gdouble access_time; - GValue elem = {0}; - - if (sscanf (line, "read_transfer_rate: offset %" G_GUINT64_FORMAT " rate %lf", - &offset, - &rate) == 2) { - - g_value_init (&elem, elem_gtype); - g_value_take_boxed (&elem, dbus_g_type_specialized_construct (elem_gtype)); - dbus_g_type_struct_set (&elem, - 0, offset, - 1, rate, - G_MAXUINT); - g_ptr_array_add (read_transfer_rate_array, g_value_get_boxed (&elem)); - - } else if (sscanf (line, "write_transfer_rate: offset %" G_GUINT64_FORMAT " rate %lf", - &offset, - &rate) == 2) { - - g_value_init (&elem, elem_gtype); - g_value_take_boxed (&elem, dbus_g_type_specialized_construct (elem_gtype)); - dbus_g_type_struct_set (&elem, - 0, offset, - 1, rate, - G_MAXUINT); - g_ptr_array_add (write_transfer_rate_array, g_value_get_boxed (&elem)); - - } else if (sscanf (line, "access_time: offset %" G_GUINT64_FORMAT " time %lf", - &offset, - &access_time) == 2) { - - g_value_init (&elem, elem_gtype); - g_value_take_boxed (&elem, dbus_g_type_specialized_construct (elem_gtype)); - dbus_g_type_struct_set (&elem, - 0, offset, - 1, access_time, - G_MAXUINT); - g_ptr_array_add (access_time_array, g_value_get_boxed (&elem)); - - } else { - g_warning ("unhandled line %d: `%s'", n, line); - } + if (WEXITSTATUS (status) == 0 && !job_was_cancelled) + { + GPtrArray *read_transfer_rate_array; + GPtrArray *write_transfer_rate_array; + GPtrArray *access_time_array; + gchar **lines; + guint n; + GType elem_gtype; + elem_gtype = dbus_g_type_get_struct ("GValueArray", G_TYPE_UINT64, G_TYPE_DOUBLE, G_TYPE_INVALID); - } - g_strfreev (lines); - - dbus_g_method_return (context, - read_transfer_rate_array, - write_transfer_rate_array, - access_time_array); - - g_ptr_array_unref (read_transfer_rate_array); - g_ptr_array_unref (write_transfer_rate_array); - g_ptr_array_unref (access_time_array); - } else { - if (job_was_cancelled) { - throw_error (context, - ERROR_CANCELLED, - "Job was cancelled"); - } else { - throw_error (context, - ERROR_FAILED, - "Error benchmarking: helper exited with exit code %d: %s", - WEXITSTATUS (status), - stderr); - } + read_transfer_rate_array = g_ptr_array_new_with_free_func ((GDestroyNotify) g_value_array_free); + write_transfer_rate_array = g_ptr_array_new_with_free_func ((GDestroyNotify) g_value_array_free); + access_time_array = g_ptr_array_new_with_free_func ((GDestroyNotify) g_value_array_free); + + lines = g_strsplit (stdout, "\n", 0); + for (n = 0; lines != NULL && lines[n] != NULL; n++) + { + const gchar *line = lines[n]; + guint64 offset; + gdouble rate; + gdouble access_time; + GValue elem = + { 0 }; + + if (sscanf (line, "read_transfer_rate: offset %" G_GUINT64_FORMAT " rate %lf", + &offset, + &rate) == 2) + { + + g_value_init (&elem, elem_gtype); + g_value_take_boxed (&elem, dbus_g_type_specialized_construct (elem_gtype)); + dbus_g_type_struct_set (&elem, 0, offset, 1, rate, G_MAXUINT); + g_ptr_array_add (read_transfer_rate_array, g_value_get_boxed (&elem)); + + } + else if (sscanf (line, "write_transfer_rate: offset %" G_GUINT64_FORMAT " rate %lf", + &offset, + &rate) == 2) + { + + g_value_init (&elem, elem_gtype); + g_value_take_boxed (&elem, dbus_g_type_specialized_construct (elem_gtype)); + dbus_g_type_struct_set (&elem, 0, offset, 1, rate, G_MAXUINT); + g_ptr_array_add (write_transfer_rate_array, g_value_get_boxed (&elem)); + + } + else if (sscanf (line, "access_time: offset %" G_GUINT64_FORMAT " time %lf", + &offset, + &access_time) == 2) + { + + g_value_init (&elem, elem_gtype); + g_value_take_boxed (&elem, dbus_g_type_specialized_construct (elem_gtype)); + dbus_g_type_struct_set (&elem, 0, offset, 1, access_time, G_MAXUINT); + g_ptr_array_add (access_time_array, g_value_get_boxed (&elem)); + + } + else + { + g_warning ("unhandled line %d: `%s'", n, line); + } + + } + g_strfreev (lines); + + dbus_g_method_return (context, read_transfer_rate_array, write_transfer_rate_array, access_time_array); + + g_ptr_array_unref (read_transfer_rate_array); + g_ptr_array_unref (write_transfer_rate_array); + g_ptr_array_unref (access_time_array); + } + else + { + if (job_was_cancelled) + { + throw_error (context, ERROR_CANCELLED, "Job was cancelled"); + } + else + { + throw_error (context, + ERROR_FAILED, + "Error benchmarking: helper exited with exit code %d: %s", + WEXITSTATUS (status), + stderr); } + } } static void -device_drive_benchmark_authorized_cb (Daemon *daemon, - Device *device, - DBusGMethodInvocation *context, - const gchar *action_id, - guint num_user_data, - gpointer *user_data_elements) +device_drive_benchmark_authorized_cb (Daemon *daemon, + Device *device, + DBusGMethodInvocation *context, + const gchar *action_id, + guint num_user_data, + gpointer *user_data_elements) { - gboolean do_write_benchmark = GPOINTER_TO_INT (user_data_elements[0]); - gchar **options = user_data_elements[1]; - gchar *argv[16]; - guint n; - - if (!device->priv->device_is_drive) { - throw_error (context, ERROR_FAILED, - "Device is not a drive"); - goto out; - } - + gboolean do_write_benchmark = GPOINTER_TO_INT (user_data_elements[0]); + gchar **options = user_data_elements[1]; + gchar *argv[16]; + guint n; - if (do_write_benchmark) { - if (device->priv->device_is_partition_table) { - throw_error (context, ERROR_FAILED, - "A partition table was detected - write benchmarking requires " - "the disk to be completely empty"); - goto out; - } + if (!device->priv->device_is_drive) + { + throw_error (context, ERROR_FAILED, "Device is not a drive"); + goto out; + } - if (device->priv->id_usage != NULL) { - throw_error (context, ERROR_FAILED, - "The disk seems to have usage `%s' - write benchmarking requires " - "the disk to be completely empty", - device->priv->id_usage); - goto out; - } + if (do_write_benchmark) + { + if (device->priv->device_is_partition_table) + { + throw_error (context, ERROR_FAILED, "A partition table was detected - write benchmarking requires " + "the disk to be completely empty"); + goto out; } - for (n = 0; options[n] != NULL; n++) { - const char *option = options[n]; - throw_error (context, - ERROR_INVALID_OPTION, - "Unknown option %s", option); - goto out; + if (device->priv->id_usage != NULL) + { + throw_error (context, ERROR_FAILED, "The disk seems to have usage `%s' - write benchmarking requires " + "the disk to be completely empty", device->priv->id_usage); + goto out; } + } - n = 0; - argv[n++] = PACKAGE_LIBEXEC_DIR "/udisks-helper-drive-benchmark"; - argv[n++] = device->priv->device_file; - argv[n++] = do_write_benchmark ? "1" : "0"; - argv[n++] = NULL; + for (n = 0; options[n] != NULL; n++) + { + const char *option = options[n]; + throw_error (context, ERROR_INVALID_OPTION, "Unknown option %s", option); + goto out; + } - if (!job_new (context, - "DriveBenchmark", - TRUE, - device, - argv, - NULL, - drive_benchmark_completed_cb, - FALSE, - NULL, - NULL)) { - goto out; - } + n = 0; + argv[n++] = PACKAGE_LIBEXEC_DIR "/udisks-helper-drive-benchmark"; + argv[n++] = device->priv->device_file; + argv[n++] = do_write_benchmark ? "1" : "0"; + argv[n++] = NULL; -out: - ; + if (!job_new (context, "DriveBenchmark", TRUE, device, argv, NULL, drive_benchmark_completed_cb, FALSE, NULL, NULL)) + { + goto out; + } + + out: + ; } -gboolean device_drive_benchmark (Device *device, - gboolean do_write_benchmark, - char **options, - DBusGMethodInvocation *context) +gboolean +device_drive_benchmark (Device *device, + gboolean do_write_benchmark, + char **options, + DBusGMethodInvocation *context) { - if (!device->priv->device_is_drive) { - throw_error (context, ERROR_FAILED, - "Device is not a drive"); - goto out; - } - - daemon_local_check_auth (device->priv->daemon, - device, - "org.freedesktop.devicekit.disks.change", - "DriveBenchmark", - TRUE, - device_drive_benchmark_authorized_cb, - context, - 2, - GINT_TO_POINTER (do_write_benchmark), NULL, - g_strdupv (options), g_strfreev); + if (!device->priv->device_is_drive) + { + throw_error (context, ERROR_FAILED, "Device is not a drive"); + goto out; + } + daemon_local_check_auth (device->priv->daemon, + device, + "org.freedesktop.devicekit.disks.change", + "DriveBenchmark", + TRUE, + device_drive_benchmark_authorized_cb, + context, + 2, + GINT_TO_POINTER (do_write_benchmark), + NULL, + g_strdupv (options), + g_strfreev); out: - return TRUE; + return TRUE; } - /*--------------------------------------------------------------------------------------------------------------*/ diff --git a/src/device.h b/src/device.h index d6fff40..2d21698 100644 --- a/src/device.h +++ b/src/device.h @@ -36,174 +36,173 @@ G_BEGIN_DECLS #define IS_DEVICE_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), TYPE_DEVICE)) #define DEVICE_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), TYPE_DEVICE, DeviceClass)) -typedef struct DeviceClass DeviceClass; +typedef struct DeviceClass DeviceClass; typedef struct DevicePrivate DevicePrivate; struct Device { - GObject parent; - DevicePrivate *priv; + GObject parent; + DevicePrivate *priv; }; struct DeviceClass { - GObjectClass parent_class; + GObjectClass parent_class; }; -GType device_get_type (void) G_GNUC_CONST; +GType +device_get_type (void) +G_GNUC_CONST; -Device *device_new (Daemon *daemon, - GUdevDevice *d); +Device *device_new (Daemon *daemon, GUdevDevice *d); -gboolean device_changed (Device *device, - GUdevDevice *d, - gboolean synthesized); +gboolean device_changed (Device *device, GUdevDevice *d, gboolean synthesized); -void device_removed (Device *device); +void device_removed (Device *device); /* local methods */ -const char *device_local_get_object_path (Device *device); -const char *device_local_get_native_path (Device *device); +const char *device_local_get_object_path (Device *device); +const char * device_local_get_native_path (Device *device); -dev_t device_local_get_dev (Device *device); -const char *device_local_get_device_file (Device *device); +dev_t device_local_get_dev (Device *device); +const char *device_local_get_device_file (Device *device); /* exported methods */ -gboolean device_job_cancel (Device *device, - DBusGMethodInvocation *context); +gboolean device_job_cancel (Device *device, + DBusGMethodInvocation *context); -gboolean device_filesystem_mount (Device *device, - const char *filesystem_type, - char **options, - DBusGMethodInvocation *context); - -gboolean device_filesystem_unmount (Device *device, - char **options, - DBusGMethodInvocation *context); - -gboolean device_filesystem_list_open_files (Device *device, - DBusGMethodInvocation *context); - -gboolean device_drive_eject (Device *device, - char **options, - DBusGMethodInvocation *context); - -gboolean device_filesystem_check (Device *device, - char **options, - DBusGMethodInvocation *context); - -gboolean device_filesystem_create (Device *device, - const char *fstype, - char **options, - DBusGMethodInvocation *context); - -gboolean device_partition_delete (Device *device, - char **options, - DBusGMethodInvocation *context); - -gboolean device_partition_create (Device *device, - guint64 offset, - guint64 size, - const char *type, - const char *label, - char **flags, - char **options, - const char *fstype, - char **fsoptions, - DBusGMethodInvocation *context); - -gboolean device_partition_modify (Device *device, - const char *type, - const char *label, - char **flags, - DBusGMethodInvocation *context); - -gboolean device_partition_table_create (Device *device, - const char *scheme, - char **options, - DBusGMethodInvocation *context); +gboolean device_filesystem_mount (Device *device, + const char *filesystem_type, + char **options, + DBusGMethodInvocation *context); + +gboolean device_filesystem_unmount (Device *device, + char **options, + DBusGMethodInvocation *context); -gboolean device_luks_unlock (Device *device, - const char *secret, - char **options, - DBusGMethodInvocation *context); +gboolean device_filesystem_list_open_files (Device *device, + DBusGMethodInvocation *context); -gboolean device_luks_lock (Device *device, - char **options, +gboolean device_drive_eject (Device *device, + char **options, + DBusGMethodInvocation *context); + +gboolean device_filesystem_check (Device *device, + char **options, + DBusGMethodInvocation *context); + +gboolean device_filesystem_create (Device *device, + const char *fstype, + char **options, + DBusGMethodInvocation *context); + +gboolean device_partition_delete (Device *device, + char **options, + DBusGMethodInvocation *context); + +gboolean device_partition_create (Device *device, + guint64 offset, + guint64 size, + const char *type, + const char *label, + char **flags, + char **options, + const char *fstype, + char **fsoptions, + DBusGMethodInvocation *context); + +gboolean device_partition_modify (Device *device, + const char *type, + const char *label, + char **flags, + DBusGMethodInvocation *context); + +gboolean device_partition_table_create (Device *device, + const char *scheme, + char **options, DBusGMethodInvocation *context); -gboolean device_luks_change_passphrase (Device *device, - const char *old_secret, - const char *new_secret, - DBusGMethodInvocation *context); +gboolean device_luks_unlock (Device *device, + const char *secret, + char **options, + DBusGMethodInvocation *context); -gboolean device_filesystem_set_label (Device *device, - const char *new_label, - DBusGMethodInvocation *context); +gboolean device_luks_lock (Device *device, + char **options, + DBusGMethodInvocation *context); -gboolean device_drive_ata_smart_refresh_data (Device *device, - char **options, - DBusGMethodInvocation *context); - -gboolean device_drive_ata_smart_get_historical_data (Device *device, - guint64 since, - guint64 until, - guint64 spacing, - DBusGMethodInvocation *context); +gboolean device_luks_change_passphrase (Device *device, + const char *old_secret, + const char *new_secret, + DBusGMethodInvocation *context); -gboolean device_drive_ata_smart_initiate_selftest (Device *device, - const char *test, - char **options, - DBusGMethodInvocation *context); +gboolean device_filesystem_set_label (Device *device, + const char *new_label, + DBusGMethodInvocation *context); -gboolean device_drive_benchmark (Device *device, - gboolean do_write_benchmark, - char **options, +gboolean device_drive_ata_smart_refresh_data (Device *device, + char **options, DBusGMethodInvocation *context); -gboolean device_linux_md_stop (Device *device, - char **options, - DBusGMethodInvocation *context); - -gboolean device_linux_md_check (Device *device, - char **options, - DBusGMethodInvocation *context); - -gboolean device_linux_md_add_component (Device *device, - char *component, - char **options, +gboolean device_drive_ata_smart_get_historical_data (Device *device, + guint64 since, + guint64 until, + guint64 spacing, DBusGMethodInvocation *context); -gboolean device_linux_md_remove_component (Device *device, - char *component, - char **options, - DBusGMethodInvocation *context); +gboolean device_drive_ata_smart_initiate_selftest (Device *device, + const char *test, + char **options, + DBusGMethodInvocation *context); + +gboolean device_drive_benchmark (Device *device, + gboolean do_write_benchmark, + char **options, + DBusGMethodInvocation *context); -gboolean device_drive_inhibit_polling (Device *device, - char **options, - DBusGMethodInvocation *context); +gboolean device_linux_md_stop (Device *device, + char **options, + DBusGMethodInvocation *context); -gboolean device_drive_uninhibit_polling (Device *device, - char *cookie, - DBusGMethodInvocation *context); +gboolean device_linux_md_check (Device *device, + char **options, + DBusGMethodInvocation *context); -gboolean device_drive_poll_media (Device *device, - DBusGMethodInvocation *context); +gboolean device_linux_md_add_component (Device *device, + char *component, + char **options, + DBusGMethodInvocation *context); -gboolean device_drive_detach (Device *device, - char **options, +gboolean device_linux_md_remove_component (Device *device, + char *component, + char **options, DBusGMethodInvocation *context); -gboolean device_drive_set_spindown_timeout (Device *device, - int timeout_seconds, - char **options, - DBusGMethodInvocation *context); +gboolean device_drive_inhibit_polling (Device *device, + char **options, + DBusGMethodInvocation *context); + +gboolean device_drive_uninhibit_polling (Device *device, + char *cookie, + DBusGMethodInvocation *context); + +gboolean device_drive_poll_media (Device *device, + DBusGMethodInvocation *context); + +gboolean device_drive_detach (Device *device, + char **options, + DBusGMethodInvocation *context); -gboolean device_drive_unset_spindown_timeout (Device *device, - char *cookie, - DBusGMethodInvocation *context); +gboolean device_drive_set_spindown_timeout (Device *device, + int timeout_seconds, + char **options, + DBusGMethodInvocation *context); + +gboolean device_drive_unset_spindown_timeout (Device *device, + char *cookie, + DBusGMethodInvocation *context); G_END_DECLS diff --git a/src/expander-private.c b/src/expander-private.c index 99aee62..772306c 100644 --- a/src/expander-private.c +++ b/src/expander-private.c @@ -36,9 +36,7 @@ emit_changed_idle_cb (gpointer data) if (!expander->priv->removed) { g_print ("**** EMITTING CHANGED for %s\n", expander->priv->native_path); - g_signal_emit_by_name (expander->priv->daemon, - "expander-changed", - expander->priv->object_path); + g_signal_emit_by_name (expander->priv->daemon, "expander-changed", expander->priv->object_path); g_signal_emit_by_name (expander, "changed"); } expander->priv->emit_changed_idle_id = 0; @@ -48,7 +46,8 @@ emit_changed_idle_cb (gpointer data) } static void -emit_changed (Expander *expander, const gchar *name) +emit_changed (Expander *expander, + const gchar *name) { //g_debug ("property %s changed for %s", name, expander->priv->expander_file); @@ -58,18 +57,18 @@ emit_changed (Expander *expander, const gchar *name) if (expander->priv->emit_changed_idle_id == 0) { expander->priv->emit_changed_idle_id = g_idle_add_full (G_PRIORITY_DEFAULT, - emit_changed_idle_cb, - g_object_ref (expander), - (GDestroyNotify) g_object_unref); + emit_changed_idle_cb, + g_object_ref (expander), + (GDestroyNotify) g_object_unref); } } } /* ---------------------------------------------------------------------------------------------------- */ - static gboolean -ptr_str_array_equals_strv (GPtrArray *a, GStrv b) +ptr_str_array_equals_strv (GPtrArray *a, + GStrv b) { guint n; guint b_len; @@ -85,7 +84,7 @@ ptr_str_array_equals_strv (GPtrArray *a, GStrv b) for (n = 0; n < a->len; n++) { if (g_strcmp0 ((gchar *) a->pdata[n], b[n]) != 0) - return FALSE; + return FALSE; } return TRUE; @@ -114,7 +113,8 @@ ptr_str_array_from_strv (GStrv s) /* ---------------------------------------------------------------------------------------------------- */ void -expander_set_vendor (Expander *expander, const gchar *value) +expander_set_vendor (Expander *expander, + const gchar *value) { if (G_UNLIKELY (g_strcmp0 (expander->priv->vendor, value) != 0)) { @@ -125,7 +125,8 @@ expander_set_vendor (Expander *expander, const gchar *value) } void -expander_set_model (Expander *expander, const gchar *value) +expander_set_model (Expander *expander, + const gchar *value) { if (G_UNLIKELY (g_strcmp0 (expander->priv->model, value) != 0)) { @@ -136,7 +137,8 @@ expander_set_model (Expander *expander, const gchar *value) } void -expander_set_revision (Expander *expander, const gchar *value) +expander_set_revision (Expander *expander, + const gchar *value) { if (G_UNLIKELY (g_strcmp0 (expander->priv->revision, value) != 0)) { @@ -147,7 +149,8 @@ expander_set_revision (Expander *expander, const gchar *value) } void -expander_set_num_ports (Expander *expander, guint value) +expander_set_num_ports (Expander *expander, + guint value) { if (G_UNLIKELY (expander->priv->num_ports != value)) { @@ -157,7 +160,8 @@ expander_set_num_ports (Expander *expander, guint value) } void -expander_set_upstream_ports (Expander *expander, GStrv value) +expander_set_upstream_ports (Expander *expander, + GStrv value) { if (G_UNLIKELY (!ptr_str_array_equals_strv (expander->priv->upstream_ports, value))) { @@ -168,7 +172,8 @@ expander_set_upstream_ports (Expander *expander, GStrv value) } void -expander_set_adapter (Expander *expander, const gchar *value) +expander_set_adapter (Expander *expander, + const gchar *value) { if (G_UNLIKELY (g_strcmp0 (expander->priv->adapter, value) != 0)) { diff --git a/src/expander-private.h b/src/expander-private.h index dee3b9e..ef4f440 100644 --- a/src/expander-private.h +++ b/src/expander-private.h @@ -31,29 +31,29 @@ G_BEGIN_DECLS struct ExpanderPrivate { - DBusGConnection *system_bus_connection; - Daemon *daemon; - GUdevDevice *d; + DBusGConnection *system_bus_connection; + Daemon *daemon; + GUdevDevice *d; - gchar *object_path; - gchar *native_path; - gboolean removed; + gchar *object_path; + gchar *native_path; + gboolean removed; - gchar *native_path_for_sysfs_prefix; + gchar *native_path_for_sysfs_prefix; - /* if non-zero, the id of the idle for emitting a 'change' signal */ - guint emit_changed_idle_id; + /* if non-zero, the id of the idle for emitting a 'change' signal */ + guint emit_changed_idle_id; - /**************/ - /* Properties */ - /**************/ + /**************/ + /* Properties */ + /**************/ - gchar *vendor; - gchar *model; - gchar *revision; - guint num_ports; - GPtrArray *upstream_ports; - gchar *adapter; + gchar *vendor; + gchar *model; + gchar *revision; + guint num_ports; + GPtrArray *upstream_ports; + gchar *adapter; }; /* property setters */ diff --git a/src/expander.c b/src/expander.c index 5d8f16b..80e75b7 100644 --- a/src/expander.c +++ b/src/expander.c @@ -48,32 +48,38 @@ /*--------------------------------------------------------------------------------------------------------------*/ #include "expander-glue.h" -static void expander_class_init (ExpanderClass *klass); -static void expander_init (Expander *seat); -static void expander_finalize (GObject *object); +static void +expander_class_init (ExpanderClass *klass); +static void +expander_init (Expander *seat); +static void +expander_finalize (GObject *object); -static gboolean update_info (Expander *expander); +static gboolean +update_info (Expander *expander); -static void drain_pending_changes (Expander *expander, gboolean force_update); +static void +drain_pending_changes (Expander *expander, + gboolean force_update); enum -{ - PROP_0, - PROP_NATIVE_PATH, - - PROP_VENDOR, - PROP_MODEL, - PROP_REVISION, - PROP_NUM_PORTS, - PROP_UPSTREAM_PORTS, - PROP_ADAPTER -}; + { + PROP_0, + PROP_NATIVE_PATH, + + PROP_VENDOR, + PROP_MODEL, + PROP_REVISION, + PROP_NUM_PORTS, + PROP_UPSTREAM_PORTS, + PROP_ADAPTER + }; enum -{ - CHANGED_SIGNAL, - LAST_SIGNAL, -}; + { + CHANGED_SIGNAL, + LAST_SIGNAL, + }; static guint signals[LAST_SIGNAL] = { 0 }; @@ -82,143 +88,153 @@ G_DEFINE_TYPE (Expander, expander, G_TYPE_OBJECT) #define EXPANDER_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), TYPE_EXPANDER, ExpanderPrivate)) static void -get_property (GObject *object, - guint prop_id, - GValue *value, - GParamSpec *pspec) +get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) { - Expander *expander = EXPANDER (object); - - switch (prop_id) { - case PROP_NATIVE_PATH: - g_value_set_string (value, expander->priv->native_path); - break; - - case PROP_VENDOR: - g_value_set_string (value, expander->priv->vendor); - break; - - case PROP_MODEL: - g_value_set_string (value, expander->priv->model); - break; - - case PROP_REVISION: - g_value_set_string (value, expander->priv->revision); - break; - - case PROP_NUM_PORTS: - g_value_set_uint (value, expander->priv->num_ports); - break; - - case PROP_UPSTREAM_PORTS: - g_value_set_boxed (value, expander->priv->upstream_ports); - break; - - case PROP_ADAPTER: - if (expander->priv->adapter == NULL) - g_value_set_boxed (value, "/"); - else - g_value_set_boxed (value, expander->priv->adapter); - break; - - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } + Expander *expander = EXPANDER (object); + + switch (prop_id) + { + case PROP_NATIVE_PATH: + g_value_set_string (value, expander->priv->native_path); + break; + + case PROP_VENDOR: + g_value_set_string (value, expander->priv->vendor); + break; + + case PROP_MODEL: + g_value_set_string (value, expander->priv->model); + break; + + case PROP_REVISION: + g_value_set_string (value, expander->priv->revision); + break; + + case PROP_NUM_PORTS: + g_value_set_uint (value, expander->priv->num_ports); + break; + + case PROP_UPSTREAM_PORTS: + g_value_set_boxed (value, expander->priv->upstream_ports); + break; + + case PROP_ADAPTER: + if (expander->priv->adapter == NULL) + g_value_set_boxed (value, "/"); + else + g_value_set_boxed (value, expander->priv->adapter); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } } static void expander_class_init (ExpanderClass *klass) { - GObjectClass *object_class = G_OBJECT_CLASS (klass); - - object_class->finalize = expander_finalize; - object_class->get_property = get_property; - - g_type_class_add_private (klass, sizeof (ExpanderPrivate)); - - signals[CHANGED_SIGNAL] = - g_signal_new ("changed", - G_OBJECT_CLASS_TYPE (klass), - G_SIGNAL_RUN_LAST | G_SIGNAL_DETAILED, - 0, - NULL, NULL, - g_cclosure_marshal_VOID__VOID, - G_TYPE_NONE, 0); - - dbus_g_object_type_install_info (TYPE_EXPANDER, &dbus_glib_expander_object_info); - - g_object_class_install_property ( - object_class, - PROP_NATIVE_PATH, - g_param_spec_string ("native-path", NULL, NULL, NULL, G_PARAM_READABLE)); - g_object_class_install_property ( - object_class, - PROP_VENDOR, - g_param_spec_string ("vendor", NULL, NULL, NULL, G_PARAM_READABLE)); - g_object_class_install_property ( - object_class, - PROP_MODEL, - g_param_spec_string ("model", NULL, NULL, NULL, G_PARAM_READABLE)); - g_object_class_install_property ( - object_class, - PROP_REVISION, - g_param_spec_string ("revision", NULL, NULL, NULL, G_PARAM_READABLE)); - g_object_class_install_property ( - object_class, - PROP_NUM_PORTS, - g_param_spec_uint ("num-ports", NULL, NULL, 0, G_MAXUINT, 0, G_PARAM_READABLE)); - g_object_class_install_property ( - object_class, - PROP_UPSTREAM_PORTS, - g_param_spec_boxed ("upstream-ports", NULL, NULL, - dbus_g_type_get_collection ("GPtrArray", DBUS_TYPE_G_OBJECT_PATH), - G_PARAM_READABLE)); - g_object_class_install_property ( - object_class, - PROP_ADAPTER, - g_param_spec_boxed ("adapter", NULL, NULL, DBUS_TYPE_G_OBJECT_PATH, G_PARAM_READABLE)); + GObjectClass *object_class = G_OBJECT_CLASS (klass); + + object_class->finalize = expander_finalize; + object_class->get_property = get_property; + + g_type_class_add_private (klass, sizeof(ExpanderPrivate)); + + signals[CHANGED_SIGNAL] = g_signal_new ("changed", + G_OBJECT_CLASS_TYPE (klass), + G_SIGNAL_RUN_LAST | G_SIGNAL_DETAILED, + 0, + NULL, + NULL, + g_cclosure_marshal_VOID__VOID, + G_TYPE_NONE, + 0); + + dbus_g_object_type_install_info (TYPE_EXPANDER, &dbus_glib_expander_object_info); + + g_object_class_install_property (object_class, PROP_NATIVE_PATH, g_param_spec_string ("native-path", + NULL, + NULL, + NULL, + G_PARAM_READABLE)); + g_object_class_install_property (object_class, PROP_VENDOR, g_param_spec_string ("vendor", + NULL, + NULL, + NULL, + G_PARAM_READABLE)); + g_object_class_install_property (object_class, PROP_MODEL, g_param_spec_string ("model", + NULL, + NULL, + NULL, + G_PARAM_READABLE)); + g_object_class_install_property (object_class, PROP_REVISION, g_param_spec_string ("revision", + NULL, + NULL, + NULL, + G_PARAM_READABLE)); + g_object_class_install_property (object_class, PROP_NUM_PORTS, g_param_spec_uint ("num-ports", + NULL, + NULL, + 0, + G_MAXUINT, + 0, + G_PARAM_READABLE)); + g_object_class_install_property (object_class, + PROP_UPSTREAM_PORTS, + g_param_spec_boxed ("upstream-ports", + NULL, + NULL, + dbus_g_type_get_collection ("GPtrArray", DBUS_TYPE_G_OBJECT_PATH), + G_PARAM_READABLE)); + g_object_class_install_property (object_class, PROP_ADAPTER, g_param_spec_boxed ("adapter", + NULL, + NULL, + DBUS_TYPE_G_OBJECT_PATH, + G_PARAM_READABLE)); } static void expander_init (Expander *expander) { - expander->priv = EXPANDER_GET_PRIVATE (expander); - - expander->priv->upstream_ports = g_ptr_array_new (); + expander->priv = EXPANDER_GET_PRIVATE (expander); + expander->priv->upstream_ports = g_ptr_array_new (); } static void expander_finalize (GObject *object) { - Expander *expander; + Expander *expander; - g_return_if_fail (object != NULL); - g_return_if_fail (IS_EXPANDER (object)); + g_return_if_fail (object != NULL); + g_return_if_fail (IS_EXPANDER (object)); - expander = EXPANDER (object); - g_return_if_fail (expander->priv != NULL); + expander = EXPANDER (object); + g_return_if_fail (expander->priv != NULL); - /* g_debug ("finalizing %s", expander->priv->native_path); */ + /* g_debug ("finalizing %s", expander->priv->native_path); */ - g_object_unref (expander->priv->d); - g_object_unref (expander->priv->daemon); - g_free (expander->priv->object_path); - g_free (expander->priv->native_path); - g_free (expander->priv->native_path_for_sysfs_prefix); + g_object_unref (expander->priv->d); + g_object_unref (expander->priv->daemon); + g_free (expander->priv->object_path); + g_free (expander->priv->native_path); + g_free (expander->priv->native_path_for_sysfs_prefix); - if (expander->priv->emit_changed_idle_id > 0) - g_source_remove (expander->priv->emit_changed_idle_id); + if (expander->priv->emit_changed_idle_id > 0) + g_source_remove (expander->priv->emit_changed_idle_id); - /* free properties */ - g_free (expander->priv->vendor); - g_free (expander->priv->model); - g_free (expander->priv->revision); - g_ptr_array_foreach (expander->priv->upstream_ports, (GFunc) g_free, NULL); - g_ptr_array_free (expander->priv->upstream_ports, TRUE); - g_free (expander->priv->adapter); + /* free properties */ + g_free (expander->priv->vendor); + g_free (expander->priv->model); + g_free (expander->priv->revision); + g_ptr_array_foreach (expander->priv->upstream_ports, (GFunc) g_free, NULL); + g_ptr_array_free (expander->priv->upstream_ports, TRUE); + g_free (expander->priv->adapter); - G_OBJECT_CLASS (expander_parent_class)->finalize (object); + G_OBJECT_CLASS (expander_parent_class)->finalize (object); } /** @@ -232,36 +248,41 @@ expander_finalize (GObject *object) static char * compute_object_path (const char *native_path) { - const gchar *basename; - GString *s; - guint n; - - basename = strrchr (native_path, '/'); - if (basename != NULL) { - basename++; - } else { - basename = native_path; + const gchar *basename; + GString *s; + guint n; + + basename = strrchr (native_path, '/'); + if (basename != NULL) + { + basename++; + } + else + { + basename = native_path; + } + + s = g_string_new ("/org/freedesktop/UDisks/expanders/"); + 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); } - - s = g_string_new ("/org/freedesktop/UDisks/expanders/"); - 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 _ */ - g_string_append_printf (s, "_%02x", c); - } + else + { + /* Escape bytes not in [A-Z][a-z][0-9] as _ */ + g_string_append_printf (s, "_%02x", c); } + } - return g_string_free (s, FALSE); + return g_string_free (s, FALSE); } /* ---------------------------------------------------------------------------------------------------- */ @@ -269,125 +290,134 @@ compute_object_path (const char *native_path) static gboolean register_disks_expander (Expander *expander) { - DBusConnection *connection; - GError *error = NULL; - - expander->priv->system_bus_connection = dbus_g_bus_get (DBUS_BUS_SYSTEM, &error); - if (expander->priv->system_bus_connection == NULL) { - if (error != NULL) { - g_critical ("error getting system bus: %s", error->message); - g_error_free (error); - } - goto error; + DBusConnection *connection; + GError *error = NULL; + + expander->priv->system_bus_connection = dbus_g_bus_get (DBUS_BUS_SYSTEM, &error); + if (expander->priv->system_bus_connection == NULL) + { + if (error != NULL) + { + g_critical ("error getting system bus: %s", error->message); + g_error_free (error); } - connection = dbus_g_connection_get_connection (expander->priv->system_bus_connection); + goto error; + } + connection = dbus_g_connection_get_connection (expander->priv->system_bus_connection); - expander->priv->object_path = compute_object_path (expander->priv->native_path); + expander->priv->object_path = compute_object_path (expander->priv->native_path); - /* safety first */ - if (dbus_g_connection_lookup_g_object (expander->priv->system_bus_connection, - expander->priv->object_path) != NULL) { - g_error ("**** HACK: Wanting to register object at path `%s' but there is already an " - "object there. This is an internal error in the daemon. Aborting.\n", - expander->priv->object_path); - } + /* safety first */ + if (dbus_g_connection_lookup_g_object (expander->priv->system_bus_connection, expander->priv->object_path) != NULL) + { + g_error ("**** HACK: Wanting to register object at path `%s' but there is already an " + "object there. This is an internal error in the daemon. Aborting.\n", + expander->priv->object_path); + } - dbus_g_connection_register_g_object (expander->priv->system_bus_connection, - expander->priv->object_path, - G_OBJECT (expander)); + dbus_g_connection_register_g_object (expander->priv->system_bus_connection, + expander->priv->object_path, + G_OBJECT (expander)); - return TRUE; + return TRUE; -error: - return FALSE; + error: + return FALSE; } void expander_removed (Expander *expander) { - expander->priv->removed = TRUE; + expander->priv->removed = TRUE; - dbus_g_connection_unregister_g_object (expander->priv->system_bus_connection, - G_OBJECT (expander)); - g_assert (dbus_g_connection_lookup_g_object (expander->priv->system_bus_connection, - expander->priv->object_path) == NULL); + dbus_g_connection_unregister_g_object (expander->priv->system_bus_connection, G_OBJECT (expander)); + g_assert (dbus_g_connection_lookup_g_object (expander->priv->system_bus_connection, expander->priv->object_path) == NULL); } Expander * -expander_new (Daemon *daemon, GUdevDevice *d) +expander_new (Daemon *daemon, + GUdevDevice *d) { - Expander *expander; - const char *native_path; - - expander = NULL; - native_path = g_udev_device_get_sysfs_path (d); - - expander = EXPANDER (g_object_new (TYPE_EXPANDER, NULL)); - expander->priv->d = g_object_ref (d); - expander->priv->daemon = g_object_ref (daemon); - expander->priv->native_path = g_strdup (native_path); + Expander *expander; + const char *native_path; + + expander = NULL; + native_path = g_udev_device_get_sysfs_path (d); + + expander = EXPANDER (g_object_new (TYPE_EXPANDER, NULL)); + expander->priv->d = g_object_ref (d); + expander->priv->daemon = g_object_ref (daemon); + expander->priv->native_path = g_strdup (native_path); + + if (!update_info (expander)) + { + g_object_unref (expander); + expander = NULL; + goto out; + } + + if (!register_disks_expander (EXPANDER (expander))) + { + g_object_unref (expander); + expander = NULL; + goto out; + } - if (!update_info (expander)) { - g_object_unref (expander); - expander = NULL; - goto out; - } - - if (!register_disks_expander (EXPANDER (expander))) { - g_object_unref (expander); - expander = NULL; - goto out; - } - -out: - return expander; + out: + return expander; } static void -drain_pending_changes (Expander *expander, gboolean force_update) +drain_pending_changes (Expander *expander, + gboolean force_update) { - gboolean emit_changed; - - emit_changed = FALSE; - - /* the update-in-idle is set up if, and only if, there are pending changes - so - * we should emit a 'change' event only if it is set up - */ - if (expander->priv->emit_changed_idle_id != 0) { - g_source_remove (expander->priv->emit_changed_idle_id); - expander->priv->emit_changed_idle_id = 0; - emit_changed = TRUE; - } - - if ((!expander->priv->removed) && (emit_changed || force_update)) { - if (expander->priv->object_path != NULL) { - g_print ("**** EMITTING CHANGED for %s\n", expander->priv->native_path); - g_signal_emit_by_name (expander, "changed"); - g_signal_emit_by_name (expander->priv->daemon, "expander-changed", expander->priv->object_path); - } + gboolean emit_changed; + + emit_changed = FALSE; + + /* the update-in-idle is set up if, and only if, there are pending changes - so + * we should emit a 'change' event only if it is set up + */ + if (expander->priv->emit_changed_idle_id != 0) + { + g_source_remove (expander->priv->emit_changed_idle_id); + expander->priv->emit_changed_idle_id = 0; + emit_changed = TRUE; + } + + if ((!expander->priv->removed) && (emit_changed || force_update)) + { + if (expander->priv->object_path != NULL) + { + g_print ("**** EMITTING CHANGED for %s\n", expander->priv->native_path); + g_signal_emit_by_name (expander, "changed"); + g_signal_emit_by_name (expander->priv->daemon, "expander-changed", expander->priv->object_path); } + } } /* called by the daemon on the 'change' uevent */ gboolean -expander_changed (Expander *expander, GUdevDevice *d, gboolean synthesized) +expander_changed (Expander *expander, + GUdevDevice *d, + gboolean synthesized) { - gboolean keep_expander; + gboolean keep_expander; - g_object_unref (expander->priv->d); - expander->priv->d = g_object_ref (d); + g_object_unref (expander->priv->d); + expander->priv->d = g_object_ref (d); - keep_expander = update_info (expander); + keep_expander = update_info (expander); - /* this 'change' event might prompt us to remove the expander */ - if (!keep_expander) - goto out; + /* this 'change' event might prompt us to remove the expander */ + if (!keep_expander) + goto out; - /* no, it's good .. keep it.. and always force a 'change' signal if the event isn't synthesized */ - drain_pending_changes (expander, !synthesized); + /* no, it's good .. keep it.. and always force a 'change' signal if the event isn't synthesized */ + drain_pending_changes (expander, !synthesized); -out: - return keep_expander; + out: + return keep_expander; } /* ---------------------------------------------------------------------------------------------------- */ @@ -395,62 +425,65 @@ out: const char * expander_local_get_object_path (Expander *expander) { - return expander->priv->object_path; + return expander->priv->object_path; } const char * expander_local_get_native_path (Expander *expander) { - return expander->priv->native_path; + return expander->priv->native_path; } gboolean -local_expander_encloses_native_path (Expander *expander, - const gchar *native_path) +local_expander_encloses_native_path (Expander *expander, + const gchar *native_path) { - gboolean ret; - ret = g_str_has_prefix (native_path, expander->priv->native_path_for_sysfs_prefix); - return ret; + gboolean ret; + ret = g_str_has_prefix (native_path, expander->priv->native_path_for_sysfs_prefix); + return ret; } /* ---------------------------------------------------------------------------------------------------- */ static char * -sysfs_resolve_link (const char *sysfs_path, const char *name) +sysfs_resolve_link (const char *sysfs_path, + const char *name) { - char *full_path; - char link_path[PATH_MAX]; - char resolved_path[PATH_MAX]; - ssize_t num; - gboolean found_it; - - found_it = FALSE; - - full_path = g_build_filename (sysfs_path, name, NULL); - - //g_debug ("name='%s'", name); - //g_debug ("full_path='%s'", full_path); - num = readlink (full_path, link_path, sizeof (link_path) - 1); - if (num != -1) { - char *absolute_path; - - link_path[num] = '\0'; - - //g_debug ("link_path='%s'", link_path); - absolute_path = g_build_filename (sysfs_path, link_path, NULL); - //g_debug ("absolute_path='%s'", absolute_path); - if (realpath (absolute_path, resolved_path) != NULL) { - //g_debug ("resolved_path='%s'", resolved_path); - found_it = TRUE; - } - g_free (absolute_path); + char *full_path; + char link_path[PATH_MAX]; + char resolved_path[PATH_MAX]; + ssize_t num; + gboolean found_it; + + found_it = FALSE; + + full_path = g_build_filename (sysfs_path, name, NULL); + + //g_debug ("name='%s'", name); + //g_debug ("full_path='%s'", full_path); + num = readlink (full_path, link_path, sizeof(link_path) - 1); + if (num != -1) + { + char *absolute_path; + + link_path[num] = '\0'; + + //g_debug ("link_path='%s'", link_path); + absolute_path = g_build_filename (sysfs_path, link_path, NULL); + //g_debug ("absolute_path='%s'", absolute_path); + if (realpath (absolute_path, resolved_path) != NULL) + { + //g_debug ("resolved_path='%s'", resolved_path); + found_it = TRUE; } - g_free (full_path); - - if (found_it) - return g_strdup (resolved_path); - else - return NULL; + g_free (absolute_path); + } + g_free (full_path); + + if (found_it) + return g_strdup (resolved_path); + else + return NULL; } /* ---------------------------------------------------------------------------------------------------- */ @@ -470,82 +503,84 @@ sysfs_resolve_link (const char *sysfs_path, const char *name) static gboolean update_info (Expander *expander) { - Adapter *adapter; - gboolean ret; - GList *ports; - GList *l; - GPtrArray *p; - gchar *s; - GDir *dir; - guint num_ports; - const gchar *vendor; - const gchar *model; - const gchar *revision; - - /* NOTE: Only sas expanders are supported for now */ - - ret = FALSE; - num_ports = 0; - - /* First, figure out prefix used for matching the sysfs devices below the expander */ - if (expander->priv->native_path_for_sysfs_prefix == NULL) { - expander->priv->native_path_for_sysfs_prefix = - sysfs_resolve_link (g_udev_device_get_sysfs_path (expander->priv->d), "device"); - if (expander->priv->native_path_for_sysfs_prefix == NULL) { - g_warning ("Unable to resolve 'device' symlink for %s", - g_udev_device_get_sysfs_path (expander->priv->d)); - goto out; - } - } - - /* Set adapter */ - adapter = daemon_local_find_enclosing_adapter (expander->priv->daemon, - expander->priv->native_path); - if (adapter == NULL) - goto out; - expander_set_adapter (expander, adapter_local_get_object_path (adapter)); - - /* Figure out the upstream ports for the expander */ - ports = daemon_local_find_enclosing_ports (expander->priv->daemon, - expander->priv->native_path_for_sysfs_prefix); - p = g_ptr_array_new (); - for (l = ports; l != NULL; l = l->next) { - Port *port = PORT (l->data); - g_ptr_array_add (p, (gpointer) port_local_get_object_path (port)); + Adapter *adapter; + gboolean ret; + GList *ports; + GList *l; + GPtrArray *p; + gchar *s; + GDir *dir; + guint num_ports; + const gchar *vendor; + const gchar *model; + const gchar *revision; + + /* NOTE: Only sas expanders are supported for now */ + + ret = FALSE; + num_ports = 0; + + /* First, figure out prefix used for matching the sysfs devices below the expander */ + if (expander->priv->native_path_for_sysfs_prefix == NULL) + { + expander->priv->native_path_for_sysfs_prefix = sysfs_resolve_link (g_udev_device_get_sysfs_path (expander->priv->d), "device"); + if (expander->priv->native_path_for_sysfs_prefix == NULL) + { + g_warning ("Unable to resolve 'device' symlink for %s", g_udev_device_get_sysfs_path (expander->priv->d)); + goto out; } - g_ptr_array_add (p, NULL); - expander_set_upstream_ports (expander, (GStrv) p->pdata); - g_ptr_array_unref (p); - g_list_free (ports); - - /* Count the number of ports (e.g. PHYs) */ - dir = g_dir_open (expander->priv->native_path_for_sysfs_prefix, 0, NULL); - if (dir != NULL) { - const gchar *name; - while ((name = g_dir_read_name (dir)) != NULL) { - if (!g_str_has_prefix (name, "phy-")) - continue; - /* Check that it's really a sas_phy */ - s = g_strdup_printf ("%s/%s/sas_phy", expander->priv->native_path_for_sysfs_prefix, name); - if (g_file_test (s, G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR)) { - num_ports++; - } - g_free (s); - } - g_dir_close (dir); + } + + /* Set adapter */ + adapter = daemon_local_find_enclosing_adapter (expander->priv->daemon, expander->priv->native_path); + if (adapter == NULL) + goto out; + expander_set_adapter (expander, adapter_local_get_object_path (adapter)); + + /* Figure out the upstream ports for the expander */ + ports = daemon_local_find_enclosing_ports (expander->priv->daemon, expander->priv->native_path_for_sysfs_prefix); + p = g_ptr_array_new (); + for (l = ports; l != NULL; l = l->next) + { + Port *port = PORT (l->data); + g_ptr_array_add (p, (gpointer) port_local_get_object_path (port)); + } + g_ptr_array_add (p, NULL); + expander_set_upstream_ports (expander, (GStrv) p->pdata); + g_ptr_array_unref (p); + g_list_free (ports); + + /* Count the number of ports (e.g. PHYs) */ + dir = g_dir_open (expander->priv->native_path_for_sysfs_prefix, 0, NULL); + if (dir != NULL) + { + const gchar *name; + while ((name = g_dir_read_name (dir)) != NULL) + { + if (!g_str_has_prefix (name, "phy-")) + continue; + /* Check that it's really a sas_phy */ + s = g_strdup_printf ("%s/%s/sas_phy", expander->priv->native_path_for_sysfs_prefix, name); + if (g_file_test (s, G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR)) + { + num_ports++; + } + g_free (s); } - expander_set_num_ports (expander, num_ports); + g_dir_close (dir); + } + expander_set_num_ports (expander, num_ports); - vendor = g_udev_device_get_property (expander->priv->d, "ID_VENDOR"); - model = g_udev_device_get_property (expander->priv->d, "ID_MODEL"); - revision = g_udev_device_get_property (expander->priv->d, "ID_REVISION"); - expander_set_vendor (expander, vendor); - expander_set_model (expander, model); - expander_set_revision (expander, revision); + vendor = g_udev_device_get_property (expander->priv->d, "ID_VENDOR"); + model = g_udev_device_get_property (expander->priv->d, "ID_MODEL"); + revision = g_udev_device_get_property (expander->priv->d, "ID_REVISION"); + expander_set_vendor (expander, vendor); + expander_set_model (expander, model); + expander_set_revision (expander, revision); - ret = TRUE; + ret = TRUE; out: - return ret; + return ret; } diff --git a/src/expander.h b/src/expander.h index 4106dee..c36d719 100644 --- a/src/expander.h +++ b/src/expander.h @@ -36,38 +36,35 @@ G_BEGIN_DECLS #define IS_EXPANDER_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), TYPE_EXPANDER)) #define EXPANDER_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), TYPE_EXPANDER, ExpanderClass)) -typedef struct ExpanderClass ExpanderClass; +typedef struct ExpanderClass ExpanderClass; typedef struct ExpanderPrivate ExpanderPrivate; struct Expander { - GObject parent; - ExpanderPrivate *priv; + GObject parent; + ExpanderPrivate *priv; }; struct ExpanderClass { - GObjectClass parent_class; + GObjectClass parent_class; }; -GType expander_get_type (void) G_GNUC_CONST; +GType expander_get_type (void) G_GNUC_CONST; -Expander *expander_new (Daemon *daemon, - GUdevDevice *d); +Expander *expander_new (Daemon *daemon, GUdevDevice *d); -gboolean expander_changed (Expander *expander, - GUdevDevice *d, - gboolean synthesized); +gboolean expander_changed (Expander *expander, GUdevDevice *d, gboolean synthesized); -void expander_removed (Expander *expander); +void expander_removed (Expander *expander); /* local methods */ -const char *expander_local_get_object_path (Expander *expander); -const char *expander_local_get_native_path (Expander *expander); +const char *expander_local_get_object_path (Expander *expander); +const char *expander_local_get_native_path (Expander *expander); + +gboolean local_expander_encloses_native_path (Expander *expander, const gchar *native_path); -gboolean local_expander_encloses_native_path (Expander *expander, - const gchar *native_path); G_END_DECLS #endif /* __EXPANDER_H__ */ diff --git a/src/helpers/job-ata-smart-collect.c b/src/helpers/job-ata-smart-collect.c index b2c4219..c0f3e35 100644 --- a/src/helpers/job-ata-smart-collect.c +++ b/src/helpers/job-ata-smart-collect.c @@ -30,76 +30,84 @@ static void usage (void) { - fprintf (stderr, "incorrect usage\n"); + fprintf (stderr, "incorrect usage\n"); } int -main (int argc, char *argv[]) +main (int argc, + char *argv[]) { - int ret; - const char *device; - SkDisk *d; - SkBool smart_is_available; - SkBool awake; - gboolean nowakeup; - const void *blob; - size_t blob_size; - gchar *encoded_blob; - - d = NULL; - ret = 1; - - if (argc != 3) { - usage (); - goto out; - } - - device = argv[1]; - - nowakeup = atoi (argv[2]); - - if (sk_disk_open (device, &d) != 0) { - g_printerr ("Failed to open disk %s: %m\n", device); - goto out; - } - - if (sk_disk_check_sleep_mode (d, &awake) != 0) { - g_printerr ("Failed to check if disk %s is awake: %m\n", device); - goto out; - } - - /* don't wake up disk unless specically asked to */ - if (nowakeup && !awake) { - g_printerr ("Disk %s is asleep and nowakeup option was passed\n", device); - ret = 2; - goto out; - } - - if (sk_disk_smart_is_available (d, &smart_is_available) != 0) { - g_printerr ("Failed to determine if smart is available for %s: %m\n", device); - goto out; - } - - /* main smart data */ - if (sk_disk_smart_read_data (d) != 0) { - g_printerr ("Failed to read smart data for %s: %m\n", device); - goto out; - } - - if (sk_disk_get_blob (d, &blob, &blob_size) != 0) { - g_printerr ("Failed to read smart data for %s: %m\n", device); - goto out; - } - - encoded_blob = g_base64_encode ((const guchar *) blob, (gsize) blob_size); - g_print ("%s\n", encoded_blob); - g_free (encoded_blob); - - ret = 0; + int ret; + const char *device; + SkDisk *d; + SkBool smart_is_available; + SkBool awake; + gboolean nowakeup; + const void *blob; + size_t blob_size; + gchar *encoded_blob; + + d = NULL; + ret = 1; + + if (argc != 3) + { + usage (); + goto out; + } + + device = argv[1]; + + nowakeup = atoi (argv[2]); + + if (sk_disk_open (device, &d) != 0) + { + g_printerr ("Failed to open disk %s: %m\n", device); + goto out; + } + + if (sk_disk_check_sleep_mode (d, &awake) != 0) + { + g_printerr ("Failed to check if disk %s is awake: %m\n", device); + goto out; + } + + /* don't wake up disk unless specically asked to */ + if (nowakeup && !awake) + { + g_printerr ("Disk %s is asleep and nowakeup option was passed\n", device); + ret = 2; + goto out; + } + + if (sk_disk_smart_is_available (d, &smart_is_available) != 0) + { + g_printerr ("Failed to determine if smart is available for %s: %m\n", device); + goto out; + } + + /* main smart data */ + if (sk_disk_smart_read_data (d) != 0) + { + g_printerr ("Failed to read smart data for %s: %m\n", device); + goto out; + } + + if (sk_disk_get_blob (d, &blob, &blob_size) != 0) + { + g_printerr ("Failed to read smart data for %s: %m\n", device); + goto out; + } + + encoded_blob = g_base64_encode ((const guchar *) blob, (gsize) blob_size); + g_print ("%s\n", encoded_blob); + g_free (encoded_blob); + + ret = 0; out: - if (d != NULL) - sk_disk_free (d); - return ret; + if (d != NULL) + sk_disk_free (d); + return ret; } diff --git a/src/helpers/job-ata-smart-selftest.c b/src/helpers/job-ata-smart-selftest.c index b40a986..c920804 100644 --- a/src/helpers/job-ata-smart-selftest.c +++ b/src/helpers/job-ata-smart-selftest.c @@ -31,7 +31,7 @@ static void usage (void) { - g_printerr ("incorrect usage\n"); + g_printerr ("incorrect usage\n"); } static const gchar *device; @@ -40,94 +40,111 @@ static gboolean cancelled = FALSE; static void sigterm_handler (int signum) { - cancelled = TRUE; + cancelled = TRUE; } int -main (int argc, char *argv[]) +main (int argc, + char *argv[]) { - int ret; - SkDisk *d; - SkBool smart_is_available; - SkSmartSelfTest test; - - d = NULL; - ret = 1; - - if (argc != 3) { - usage (); - goto out; - } - - device = argv[1]; - - if (strcmp (argv[2], "short") == 0) { - test = SK_SMART_SELF_TEST_SHORT; - } else if (strcmp (argv[2], "extended") == 0) { - test = SK_SMART_SELF_TEST_EXTENDED; - } else if (strcmp (argv[2], "conveyance") == 0) { - test = SK_SMART_SELF_TEST_CONVEYANCE; - } else { - g_printerr ("Unknown test '%s'\n", argv[2]); - goto out; + int ret; + SkDisk *d; + SkBool smart_is_available; + SkSmartSelfTest test; + + d = NULL; + ret = 1; + + if (argc != 3) + { + usage (); + goto out; + } + + device = argv[1]; + + if (strcmp (argv[2], "short") == 0) + { + test = SK_SMART_SELF_TEST_SHORT; + } + else if (strcmp (argv[2], "extended") == 0) + { + test = SK_SMART_SELF_TEST_EXTENDED; + } + else if (strcmp (argv[2], "conveyance") == 0) + { + test = SK_SMART_SELF_TEST_CONVEYANCE; + } + else + { + g_printerr ("Unknown test '%s'\n", argv[2]); + goto out; + } + + if (sk_disk_open (device, &d) != 0) + { + g_printerr ("Failed to open disk %s: %s\n", device, strerror (errno)); + goto out; + } + + if (sk_disk_smart_is_available (d, &smart_is_available) != 0) + { + g_printerr ("Failed to determine if smart is available for %s: %s\n", device, strerror (errno)); + goto out; + } + + /* if the user cancels, catch that and abort the test */ + signal (SIGTERM, sigterm_handler); + + /* progress at 0% initially */ + g_print ("udisks-helper-progress: 0\n"); + + /* start the test */ + if (sk_disk_smart_self_test (d, test) != 0) + { + g_printerr ("Error initiating test on disk %s: %s\n", device, strerror (errno)); + goto out; + } + + /* poll for completion */ + while (TRUE && !cancelled) + { + const SkSmartParsedData *data; + + sleep (2); + + if (sk_disk_smart_read_data (d) != 0) + { + g_printerr ("Failed to read smart data for %s: %s\n", device, strerror (errno)); + goto out; } - - if (sk_disk_open (device, &d) != 0) { - g_printerr ("Failed to open disk %s: %s\n", device, strerror (errno)); - goto out; - } - - if (sk_disk_smart_is_available (d, &smart_is_available) != 0) { - g_printerr ("Failed to determine if smart is available for %s: %s\n", device, strerror (errno)); - goto out; + if (sk_disk_smart_parse (d, &data) != 0) + { + g_printerr ("Failed to parse smart data for %s: %s\n", device, strerror (errno)); + goto out; } - /* if the user cancels, catch that and abort the test */ - signal (SIGTERM, sigterm_handler); - - /* progress at 0% initially */ - g_print ("udisks-helper-progress: 0\n"); + if (data->self_test_execution_status != SK_SMART_SELF_TEST_EXECUTION_STATUS_INPROGRESS) + break; - /* start the test */ - if (sk_disk_smart_self_test (d, test) != 0) { - g_printerr ("Error initiating test on disk %s: %s\n", device, strerror (errno)); - goto out; - } - - /* poll for completion */ - while (TRUE && !cancelled) { - const SkSmartParsedData *data; - - sleep (2); - - if (sk_disk_smart_read_data (d) != 0) { - g_printerr ("Failed to read smart data for %s: %s\n", device, strerror (errno)); - goto out; - } - if (sk_disk_smart_parse (d, &data) != 0) { - g_printerr ("Failed to parse smart data for %s: %s\n", device, strerror (errno)); - goto out; - } - - if (data->self_test_execution_status != SK_SMART_SELF_TEST_EXECUTION_STATUS_INPROGRESS) - break; - - /* update progress */ - g_print ("udisks-helper-progress: %d\n", 100 - data->self_test_execution_percent_remaining); - } + /* update progress */ + g_print ("udisks-helper-progress: %d\n", 100 - data->self_test_execution_percent_remaining); + } - /* abort test if cancelled */ - if (cancelled) { - if (sk_disk_smart_self_test (d, SK_SMART_SELF_TEST_ABORT) != 0) { - g_printerr ("Error cancelling test on disk %s: %s\n", device, strerror (errno)); - goto out; - } + /* abort test if cancelled */ + if (cancelled) + { + if (sk_disk_smart_self_test (d, SK_SMART_SELF_TEST_ABORT) != 0) + { + g_printerr ("Error cancelling test on disk %s: %s\n", device, strerror (errno)); + goto out; } + } - ret = 0; + ret = 0; out: - if (d != NULL) - sk_disk_free (d); - return ret; + if (d != NULL) + sk_disk_free (d); + return ret; } diff --git a/src/helpers/job-change-filesystem-label.c b/src/helpers/job-change-filesystem-label.c index c3bff0f..0c2c0c7 100644 --- a/src/helpers/job-change-filesystem-label.c +++ b/src/helpers/job-change-filesystem-label.c @@ -40,81 +40,91 @@ #include "job-shared.h" int -main (int argc, char **argv) +main (int argc, + char **argv) { - int ret; - int exit_status; - GError *error; - const char *device; - const char *fstype; - char *command_line; - char *standard_error; - char *new_label; + int ret; + int exit_status; + GError *error; + const char *device; + const char *fstype; + char *command_line; + char *standard_error; + char *new_label; - ret = 1; - command_line = NULL; - standard_error = NULL; - new_label = NULL; + ret = 1; + command_line = NULL; + standard_error = NULL; + new_label = NULL; - if (argc != 4) { - g_printerr ("wrong usage\n"); - goto out; - } - device = argv[1]; - fstype = argv[2]; - new_label = g_strdup (argv[3]); + if (argc != 4) + { + g_printerr ("wrong usage\n"); + goto out; + } + device = argv[1]; + fstype = argv[2]; + new_label = g_strdup (argv[3]); - if (strcmp (fstype, "ext2") == 0 || strcmp (fstype, "ext3") == 0 || strcmp (fstype, "ext4") == 0) { - if (!validate_and_escape_label (&new_label, 16)) - goto out; - command_line = g_strdup_printf ("e2label %s \"%s\"", device, new_label); - } else if (strcmp (fstype, "xfs") == 0) { - if (!validate_and_escape_label (&new_label, 12)) - goto out; - if (strlen (new_label) == 0) - command_line = g_strdup_printf ("xfs_admin -L -- %s", device); - else - command_line = g_strdup_printf ("xfs_admin -L \"%s\" %s", new_label, device); + if (strcmp (fstype, "ext2") == 0 || strcmp (fstype, "ext3") == 0 || strcmp (fstype, "ext4") == 0) + { + if (!validate_and_escape_label (&new_label, 16)) + goto out; + command_line = g_strdup_printf ("e2label %s \"%s\"", device, new_label); + } + else if (strcmp (fstype, "xfs") == 0) + { + if (!validate_and_escape_label (&new_label, 12)) + goto out; + if (strlen (new_label) == 0) + command_line = g_strdup_printf ("xfs_admin -L -- %s", device); + else + command_line = g_strdup_printf ("xfs_admin -L \"%s\" %s", new_label, device); - } else if (strcmp (fstype, "vfat") == 0) { - if (!validate_and_escape_label (&new_label, 254)) - goto out; - g_setenv ("MTOOLS_SKIP_CHECK", "1", TRUE); - if (strlen (new_label) == 0) - command_line = g_strdup_printf ("mlabel -c -i %s ::", device); - else - command_line = g_strdup_printf ("mlabel -i %s \"::%s\"", device, new_label); + } + else if (strcmp (fstype, "vfat") == 0) + { + if (!validate_and_escape_label (&new_label, 254)) + goto out; + g_setenv ("MTOOLS_SKIP_CHECK", "1", TRUE); + if (strlen (new_label) == 0) + command_line = g_strdup_printf ("mlabel -c -i %s ::", device); + else + command_line = g_strdup_printf ("mlabel -i %s \"::%s\"", device, new_label); - } else if (strcmp (fstype, "ntfs") == 0) { - command_line = g_strdup_printf ("ntfslabel %s \"%s\"", device, new_label); - } else { - g_printerr ("fstype %s not supported\n", fstype); - goto out; - } + } + else if (strcmp (fstype, "ntfs") == 0) + { + command_line = g_strdup_printf ("ntfslabel %s \"%s\"", device, new_label); + } + else + { + g_printerr ("fstype %s not supported\n", fstype); + goto out; + } - if (command_line != NULL) { - error = NULL; - if (!g_spawn_command_line_sync (command_line, - NULL, - &standard_error, - &exit_status, - &error)) { - g_printerr ("cannot spawn '%s': %s\n", command_line, error->message); - g_error_free (error); - ret = 3; /* indicate FilesystemToolsMissing error */ - goto out; - } - if (WEXITSTATUS (exit_status) != 0) { - g_printerr ("helper failed with:\n%s", standard_error); - goto out; - } + if (command_line != NULL) + { + error = NULL; + if (!g_spawn_command_line_sync (command_line, NULL, &standard_error, &exit_status, &error)) + { + g_printerr ("cannot spawn '%s': %s\n", command_line, error->message); + g_error_free (error); + ret = 3; /* indicate FilesystemToolsMissing error */ + goto out; + } + if (WEXITSTATUS (exit_status) != 0) + { + g_printerr ("helper failed with:\n%s", standard_error); + goto out; } + } - ret = 0; + ret = 0; -out: - g_free (new_label); - g_free (standard_error); - g_free (command_line); - return ret; + out: + g_free (new_label); + g_free (standard_error); + g_free (command_line); + return ret; } diff --git a/src/helpers/job-create-partition-table.c b/src/helpers/job-create-partition-table.c index a750a30..2051c08 100644 --- a/src/helpers/job-create-partition-table.c +++ b/src/helpers/job-create-partition-table.c @@ -41,63 +41,79 @@ #include "partutil.h" int -main (int argc, char **argv) +main (int argc, + char **argv) { - int ret; - const char *device; - const char *scheme; - char **options; - int n; - PartitionScheme pscheme; - gboolean no_partition_table; + int ret; + const char *device; + const char *scheme; + char **options; + int n; + PartitionScheme pscheme; + gboolean no_partition_table; - ret = 1; - no_partition_table = FALSE; - pscheme = PART_TYPE_MSDOS; + ret = 1; + no_partition_table = FALSE; + pscheme = PART_TYPE_MSDOS; - if (argc < 3) { - g_printerr ("wrong usage\n"); - goto out; - } - device = argv[1]; - scheme = argv[2]; - options = argv + 3; + if (argc < 3) + { + g_printerr ("wrong usage\n"); + goto out; + } + device = argv[1]; + scheme = argv[2]; + options = argv + 3; - for (n = 0; options[n] != NULL; n++) { - g_printerr ("option %s not supported\n", options[n]); - goto out; - } + for (n = 0; options[n] != NULL; n++) + { + g_printerr ("option %s not supported\n", options[n]); + goto out; + } - if (strcmp (scheme, "mbr") == 0) { - pscheme = PART_TYPE_MSDOS; - } else if (strcmp (scheme, "gpt") == 0) { - pscheme = PART_TYPE_GPT; - } else if (strcmp (scheme, "apm") == 0) { - pscheme = PART_TYPE_APPLE; - } else if (strcmp (scheme, "none") == 0) { - no_partition_table = TRUE; - } else { - g_printerr ("partitioning scheme %s not supported\n", scheme); - goto out; - } + if (strcmp (scheme, "mbr") == 0) + { + pscheme = PART_TYPE_MSDOS; + } + else if (strcmp (scheme, "gpt") == 0) + { + pscheme = PART_TYPE_GPT; + } + else if (strcmp (scheme, "apm") == 0) + { + pscheme = PART_TYPE_APPLE; + } + else if (strcmp (scheme, "none") == 0) + { + no_partition_table = TRUE; + } + else + { + g_printerr ("partitioning scheme %s not supported\n", scheme); + goto out; + } - /* scrub signatures */ - if (!scrub_signatures (device, 0, 0)) - goto out; + /* scrub signatures */ + if (!scrub_signatures (device, 0, 0)) + goto out; - if (no_partition_table) { - ret = 0; - } else { - if (part_create_partition_table ((char *) device, pscheme)) - ret = 0; - } + if (no_partition_table) + { + ret = 0; + } + else + { + if (part_create_partition_table ((char *) device, pscheme)) + ret = 0; + } - /* reread partition table */ - if (!reread_partition_table (device)) { - ret = 1; - goto out; - } + /* reread partition table */ + if (!reread_partition_table (device)) + { + ret = 1; + goto out; + } -out: - return ret; + out: + return ret; } diff --git a/src/helpers/job-create-partition.c b/src/helpers/job-create-partition.c index fc9ed6b..8a8ee6b 100644 --- a/src/helpers/job-create-partition.c +++ b/src/helpers/job-create-partition.c @@ -42,125 +42,136 @@ #include "partutil.h" int -main (int argc, char **argv) +main (int argc, + char **argv) { - int n; - int ret; - const char *device; - char **options; - char *label; - char *type; - char *flags_as_string; - char **flags; - guint64 offset; - guint64 size; - guint64 out_start; - guint64 out_size; - guint out_num; - char *endp; - - ret = 1; - flags = NULL; - - if (argc < 7) { - g_printerr ("wrong usage\n"); - goto out; + int n; + int ret; + const char *device; + char **options; + char *label; + char *type; + char *flags_as_string; + char **flags; + guint64 offset; + guint64 size; + guint64 out_start; + guint64 out_size; + guint out_num; + char *endp; + + ret = 1; + flags = NULL; + + if (argc < 7) + { + g_printerr ("wrong usage\n"); + goto out; + } + device = argv[1]; + offset = strtoll (argv[2], &endp, 10); + if (*endp != '\0') + { + g_printerr ("malformed offset '%s'\n", argv[2]); + goto out; + } + size = strtoll (argv[3], &endp, 10); + if (*endp != '\0') + { + g_printerr ("malformed size '%s'\n", argv[3]); + goto out; + } + type = argv[4]; + label = argv[5]; + flags_as_string = argv[6]; + options = argv + 7; + + flags = g_strsplit (flags_as_string, ",", 0); + + /* we trust the caller have verified that the given slice doesn't overlap + * with existing partitions + */ + + g_print ("type: '%s'\n", type); + g_print ("label: '%s'\n", label); + g_print ("flags_as_string: '%s'\n", flags_as_string); + + /* don't ask libparted to poke the kernel - it won't work if other partitions are mounted/busy */ + if (part_add_partition ((char *) device, + offset, + size, + &out_start, + &out_size, + &out_num, + type, + strlen (label) > 0 ? label : NULL, + flags, + -1, + -1, + FALSE)) + { + gint fd; + struct blkpg_ioctl_arg a; + struct blkpg_partition p; + + /* now clear out file system signatures in the newly created + * partition... Unless it's an extended partition! + */ + n = strtoll (type, &endp, 0); + if (*endp == '\0' && (n == 0x05 || n == 0x0f || n == 0x85)) + { + /* do nothing */ } - device = argv[1]; - offset = strtoll (argv[2], &endp, 10); - if (*endp != '\0') { - g_printerr ("malformed offset '%s'\n", argv[2]); - goto out; + else + { + if (!scrub_signatures (device, out_start, out_size)) + { + g_printerr ("Cannot scrub filesystem signatures at " + "offset=%" G_GINT64_FORMAT " and size=%" G_GINT64_FORMAT "\n", + out_start, out_size); + goto out; + } } - size = strtoll (argv[3], &endp, 10); - if (*endp != '\0') { - g_printerr ("malformed size '%s'\n", argv[3]); - goto out; + + /* OK, now tell the kernel about the newly added partition */ + fd = open (device, O_RDONLY); + if (fd < 0) + { + g_printerr ("Cannot open %s: %m\n", device); + goto out; } - type = argv[4]; - label = argv[5]; - flags_as_string = argv[6]; - options = argv + 7; - - flags = g_strsplit (flags_as_string, ",", 0); - - /* we trust the caller have verified that the given slice doesn't overlap - * with existing partitions - */ - - g_print ("type: '%s'\n", type); - g_print ("label: '%s'\n", label); - g_print ("flags_as_string: '%s'\n", flags_as_string); - - /* don't ask libparted to poke the kernel - it won't work if other partitions are mounted/busy */ - if (part_add_partition ((char *) device, - offset, - size, - &out_start, - &out_size, - &out_num, - type, - strlen (label) > 0 ? label : NULL, - flags, - -1, - -1, - FALSE)) { - gint fd; - struct blkpg_ioctl_arg a; - struct blkpg_partition p; - - /* now clear out file system signatures in the newly created - * partition... Unless it's an extended partition! - */ - n = strtoll (type, &endp, 0); - if (*endp == '\0' && (n == 0x05 || n == 0x0f || n == 0x85)) { - /* do nothing */ - } else { - if (!scrub_signatures (device, out_start, out_size)) { - g_printerr ("Cannot scrub filesystem signatures at " - "offset=%" G_GINT64_FORMAT " and size=%" G_GINT64_FORMAT "\n", - out_start, out_size); - goto out; - } - } - - /* OK, now tell the kernel about the newly added partition */ - fd = open (device, O_RDONLY); - if (fd < 0) { - g_printerr ("Cannot open %s: %m\n", device); - goto out; - } - memset (&a, '\0', sizeof (struct blkpg_ioctl_arg)); - memset (&p, '\0', sizeof (struct blkpg_partition)); - p.pno = out_num; - p.start = out_start; - p.length = out_size; - a.op = BLKPG_ADD_PARTITION; - a.datalen = sizeof (p); - a.data = &p; - if (ioctl (fd, BLKPG, &a) == -1) { - g_printerr ("Error doing BLKPG ioctl with BLKPG_ADD_PARTITION for partition %d " - "of size %" G_GUINT64_FORMAT " at offset %" G_GUINT64_FORMAT " on %s: %m\n", - out_num, - out_start, - out_size, - device); - close (fd); - goto out; - } - close (fd); - - /* send the start and size back to the daemon - it needs to know, to - * wait for the created partition, because the partition may not have - * been created exactly where it was requested.... - */ - g_printerr ("job-create-partition-offset: %" G_GINT64_FORMAT "\n", out_start); - g_printerr ("job-create-partition-size: %" G_GINT64_FORMAT "\n", out_size); - - ret = 0; + memset (&a, '\0', sizeof(struct blkpg_ioctl_arg)); + memset (&p, '\0', sizeof(struct blkpg_partition)); + p.pno = out_num; + p.start = out_start; + p.length = out_size; + a.op = BLKPG_ADD_PARTITION; + a.datalen = sizeof(p); + a.data = &p; + if (ioctl (fd, BLKPG, &a) == -1) + { + g_printerr ("Error doing BLKPG ioctl with BLKPG_ADD_PARTITION for partition %d " + "of size %" G_GUINT64_FORMAT " at offset %" G_GUINT64_FORMAT " on %s: %m\n", + out_num, + out_start, + out_size, + device); + close (fd); + goto out; } + close (fd); + + /* send the start and size back to the daemon - it needs to know, to + * wait for the created partition, because the partition may not have + * been created exactly where it was requested.... + */ + g_printerr ("job-create-partition-offset: %" G_GINT64_FORMAT "\n", out_start); + g_printerr ("job-create-partition-size: %" G_GINT64_FORMAT "\n", out_size); + + ret = 0; + } -out: - g_strfreev (flags); - return ret; + out: + g_strfreev (flags); + return ret; } diff --git a/src/helpers/job-delete-partition.c b/src/helpers/job-delete-partition.c index 91aaa7b..1eca3fd 100644 --- a/src/helpers/job-delete-partition.c +++ b/src/helpers/job-delete-partition.c @@ -42,91 +42,103 @@ #include "partutil.h" int -main (int argc, char **argv) +main (int argc, + char **argv) { - int ret; - const char *device; - const char *partition_device; - char **options; - int n; - guint64 offset; - guint64 size; - int part_number; - char *endp; + int ret; + const char *device; + const char *partition_device; + char **options; + int n; + guint64 offset; + guint64 size; + int part_number; + char *endp; - ret = 1; + ret = 1; - if (argc < 5) { - g_printerr ("wrong usage\n"); - goto out; - } - device = argv[1]; - partition_device = argv[2]; - offset = strtoll (argv[3], &endp, 10); - if (*endp != '\0') { - g_printerr ("malformed offset '%s'\n", argv[3]); - goto out; - } - size = strtoll (argv[4], &endp, 10); - if (*endp != '\0') { - g_printerr ("malformed size '%s'\n", argv[4]); - goto out; - } - part_number = strtol (argv[5], &endp, 10); - if (*endp != '\0') { - g_printerr ("malformed partition number '%s'\n", argv[5]); - goto out; - } + if (argc < 5) + { + g_printerr ("wrong usage\n"); + goto out; + } + device = argv[1]; + partition_device = argv[2]; + offset = strtoll (argv[3], &endp, 10); + if (*endp != '\0') + { + g_printerr ("malformed offset '%s'\n", argv[3]); + goto out; + } + size = strtoll (argv[4], &endp, 10); + if (*endp != '\0') + { + g_printerr ("malformed size '%s'\n", argv[4]); + goto out; + } + part_number = strtol (argv[5], &endp, 10); + if (*endp != '\0') + { + g_printerr ("malformed partition number '%s'\n", argv[5]); + goto out; + } - options = argv + 6; + options = argv + 6; - for (n = 0; options[n] != NULL; n++) { - g_printerr ("option %s not supported\n", options[n]); - goto out; - } + for (n = 0; options[n] != NULL; n++) + { + g_printerr ("option %s not supported\n", options[n]); + goto out; + } - /* don't ask libparted to poke the kernel - it won't work if other partitions are mounted/busy */ - if (part_del_partition ((char *) device, offset, FALSE)) { - gint fd; - struct blkpg_ioctl_arg a; - struct blkpg_partition p; + /* don't ask libparted to poke the kernel - it won't work if other partitions are mounted/busy */ + if (part_del_partition ((char *) device, offset, FALSE)) + { + gint fd; + struct blkpg_ioctl_arg a; + struct blkpg_partition p; - /* now, ask the kernel to delete the partition */ - fd = open (device, O_RDONLY); - if (fd < 0) { - g_printerr ("Cannot open %s: %m\n", device); - goto out; - } - memset (&a, '\0', sizeof (struct blkpg_ioctl_arg)); - memset (&p, '\0', sizeof (struct blkpg_partition)); - p.pno = part_number; - a.op = BLKPG_DEL_PARTITION; - a.datalen = sizeof (p); - a.data = &p; - if (ioctl (fd, BLKPG, &a) == -1) { - g_printerr ("Error doing BLKPG ioctl with BLKPG_DEL_PARTITION for partition %d on %s: %m\n", - part_number, - device); - close (fd); - goto out; - } - close (fd); + /* now, ask the kernel to delete the partition */ + fd = open (device, O_RDONLY); + if (fd < 0) + { + g_printerr ("Cannot open %s: %m\n", device); + goto out; + } + memset (&a, '\0', sizeof(struct blkpg_ioctl_arg)); + memset (&p, '\0', sizeof(struct blkpg_partition)); + p.pno = part_number; + a.op = BLKPG_DEL_PARTITION; + a.datalen = sizeof(p); + a.data = &p; + if (ioctl (fd, BLKPG, &a) == -1) + { + g_printerr ("Error doing BLKPG ioctl with BLKPG_DEL_PARTITION for partition %d on %s: %m\n", + part_number, + device); + close (fd); + goto out; + } + close (fd); - /* zero the contents of what was the _partition_ - * - *... but only after removing it from the partition table - * (since it may contain meta data if it's an extended partition) - */ - /* scrub signatures */ - if (!scrub_signatures (device, offset, size)) { - g_printerr ("Cannot scrub filesystem signatures at " - "offset=%" G_GINT64_FORMAT " and size=%" G_GINT64_FORMAT "\n", - offset, size); - } else { - ret = 0; - } + /* zero the contents of what was the _partition_ + * + *... but only after removing it from the partition table + * (since it may contain meta data if it's an extended partition) + */ + /* scrub signatures */ + if (!scrub_signatures (device, offset, size)) + { + g_printerr ("Cannot scrub filesystem signatures at " + "offset=%" G_GINT64_FORMAT " and size=%" G_GINT64_FORMAT "\n", + offset, size); + } + else + { + ret = 0; } + } -out: - return ret; + out: + return ret; } diff --git a/src/helpers/job-drive-benchmark.c b/src/helpers/job-drive-benchmark.c index 2ddbbc0..766f300 100644 --- a/src/helpers/job-drive-benchmark.c +++ b/src/helpers/job-drive-benchmark.c @@ -86,8 +86,7 @@ guesstimate_optimal_buffer_size (guint num_samples) if (lseek (fd, 0, SEEK_SET) == -1) { - g_printerr ("Error seeking to start of disk for %s when guesstimating buffer size: %m\n", - device_file); + g_printerr ("Error seeking to start of disk for %s when guesstimating buffer size: %m\n", device_file); goto out; } @@ -118,8 +117,8 @@ guesstimate_optimal_buffer_size (guint num_samples) } g_get_current_time (&end_time); - duration_secs = ((end_time.tv_sec * G_USEC_PER_SEC + end_time.tv_usec) - - (begin_time.tv_sec * G_USEC_PER_SEC + begin_time.tv_usec)) / ((gdouble) G_USEC_PER_SEC); + duration_secs = ((end_time.tv_sec * G_USEC_PER_SEC + end_time.tv_usec) - (begin_time.tv_sec * G_USEC_PER_SEC + + begin_time.tv_usec)) / ((gdouble) G_USEC_PER_SEC); /* duration_secs is (approx) the number of seconds needed to do one sample */ if (duration_secs * num_samples > 30.0) @@ -213,8 +212,8 @@ measure_transfer_rate (guint num_samples, } g_get_current_time (&end_time); - duration_secs = ((end_time.tv_sec * G_USEC_PER_SEC + end_time.tv_usec) - - (begin_time.tv_sec * G_USEC_PER_SEC + begin_time.tv_usec)) / ((gdouble) G_USEC_PER_SEC); + duration_secs = ((end_time.tv_sec * G_USEC_PER_SEC + end_time.tv_usec) - (begin_time.tv_sec * G_USEC_PER_SEC + + begin_time.tv_usec)) / ((gdouble) G_USEC_PER_SEC); g_print ("read_transfer_rate: offset %" G_GOFFSET_FORMAT " rate %f\n", pos, @@ -256,7 +255,7 @@ measure_write_transfer_rate (guint num_samples, pos = n * size / num_samples; /* O_DIRECT also only wants to read from page offsets */ - pos &= ~(page_size -1); + pos &= ~(page_size - 1); if (lseek (fd, pos, SEEK_SET) == -1) { @@ -297,17 +296,18 @@ measure_write_transfer_rate (guint num_samples, } - if (fsync (fd) != 0) { - g_printerr ("Error fsync()'ing after writing at %" G_GOFFSET_FORMAT " to %s: %m\n", - pos + (remaining - total_written), - device_file); - goto out; - } + if (fsync (fd) != 0) + { + g_printerr ("Error fsync()'ing after writing at %" G_GOFFSET_FORMAT " to %s: %m\n", + pos + (remaining - total_written), + device_file); + goto out; + } g_get_current_time (&end_time); - duration_secs = ((end_time.tv_sec * G_USEC_PER_SEC + end_time.tv_usec) - - (begin_time.tv_sec * G_USEC_PER_SEC + begin_time.tv_usec)) / ((gdouble) G_USEC_PER_SEC); + duration_secs = ((end_time.tv_sec * G_USEC_PER_SEC + end_time.tv_usec) - (begin_time.tv_sec * G_USEC_PER_SEC + + begin_time.tv_usec)) / ((gdouble) G_USEC_PER_SEC); g_print ("write_transfer_rate: offset %" G_GOFFSET_FORMAT " rate %f\n", pos, @@ -344,7 +344,7 @@ measure_access_time (guint num_samples, guint64 pos; pos = (guint64) g_rand_double_range (rand, 0, (gdouble) (size - page_size)); - pos &= ~(page_size -1); + pos &= ~(page_size - 1); g_get_current_time (&begin_time); if (lseek (fd, pos, SEEK_SET) == -1) @@ -364,8 +364,8 @@ measure_access_time (guint num_samples, } g_get_current_time (&end_time); - duration_secs = ((end_time.tv_sec * G_USEC_PER_SEC + end_time.tv_usec) - - (begin_time.tv_sec * G_USEC_PER_SEC + begin_time.tv_usec)) / ((gdouble) G_USEC_PER_SEC); + duration_secs = ((end_time.tv_sec * G_USEC_PER_SEC + end_time.tv_usec) - (begin_time.tv_sec * G_USEC_PER_SEC + + begin_time.tv_usec)) / ((gdouble) G_USEC_PER_SEC); g_print ("access_time: offset %" G_GOFFSET_FORMAT " time %f\n", pos, @@ -384,7 +384,8 @@ measure_access_time (guint num_samples, } int -main (int argc, char *argv[]) +main (int argc, + char *argv[]) { gint ret; guchar *buf_unaligned; @@ -412,11 +413,14 @@ main (int argc, char *argv[]) do_write_benchmark = atoi (argv[2]); - if (do_write_benchmark) { - fd = open (device_file, O_RDWR | O_DIRECT); - } else { - fd = open (device_file, O_RDONLY | O_DIRECT); - } + if (do_write_benchmark) + { + fd = open (device_file, O_RDWR | O_DIRECT); + } + else + { + fd = open (device_file, O_RDONLY | O_DIRECT); + } if (fd < 0) { g_printerr ("Error opening %s: %m\n", device_file); @@ -460,10 +464,11 @@ main (int argc, char *argv[]) if (!measure_transfer_rate (num_transfer_rate_samples, cur_task++, num_tasks)) goto out; - if (do_write_benchmark) { - if (!measure_write_transfer_rate (num_transfer_rate_samples, cur_task++, num_tasks)) - goto out; - } + if (do_write_benchmark) + { + if (!measure_write_transfer_rate (num_transfer_rate_samples, cur_task++, num_tasks)) + goto out; + } if (!measure_access_time (num_access_time_samples, cur_task++, num_tasks)) goto out; diff --git a/src/helpers/job-drive-detach.c b/src/helpers/job-drive-detach.c index 26a2a11..25d9079 100644 --- a/src/helpers/job-drive-detach.c +++ b/src/helpers/job-drive-detach.c @@ -39,7 +39,8 @@ usage (void) } int -main (int argc, char *argv[]) +main (int argc, + char *argv[]) { int ret; int sg_fd; @@ -82,29 +83,27 @@ main (int argc, char *argv[]) goto out; } - if (sg_ll_sync_cache_10 (sg_fd, - 0, /* sync_nv */ - 0, /* immed */ - 0, /* group */ - 0, /* lba */ - 0, /* count */ - 1, /* noisy */ - 0 /* verbose */ + if (sg_ll_sync_cache_10 (sg_fd, 0, /* sync_nv */ + 0, /* immed */ + 0, /* group */ + 0, /* lba */ + 0, /* count */ + 1, /* noisy */ + 0 /* verbose */ ) != 0) { g_printerr ("Error SYNCHRONIZE CACHE for %s: %m\n", device); /* this is not a catastrophe, carry on */ } - if (sg_ll_start_stop_unit (sg_fd, - 0, /* immed */ - 0, /* pc_mod__fl_num */ - 0, /* power_cond */ - 0, /* noflush__fl */ - 0, /* loej */ - 0, /* start */ - 1, /* noisy */ - 0 /* verbose */ + if (sg_ll_start_stop_unit (sg_fd, 0, /* immed */ + 0, /* pc_mod__fl_num */ + 0, /* power_cond */ + 0, /* noflush__fl */ + 0, /* loej */ + 0, /* start */ + 1, /* noisy */ + 0 /* verbose */ ) != 0) { g_printerr ("Error STOP UNIT for %s: %m\n", device); @@ -148,7 +147,7 @@ main (int argc, char *argv[]) g_printerr ("Cannot open %s for writing: %m\n", unbind_path); goto out; } - if (fwrite (usb_interface_name, sizeof (char), usb_interface_name_len, f) < usb_interface_name_len) + if (fwrite (usb_interface_name, sizeof(char), usb_interface_name_len, f) < usb_interface_name_len) { g_printerr ("Error writing %s to %s: %m\n", unbind_path, usb_interface_name); fclose (f); @@ -170,7 +169,7 @@ main (int argc, char *argv[]) const char *bNumInterfaces; char *endp; int num_interfaces; - gchar *power_level_path; + gchar * power_level_path; gchar suspend_str[] = "suspend"; bNumInterfaces = udev_device_get_sysattr_value (udevice_usb_device, "bNumInterfaces"); @@ -185,7 +184,7 @@ main (int argc, char *argv[]) } else { - if (fwrite (suspend_str, sizeof (char), strlen (suspend_str), f) < strlen (suspend_str)) + if (fwrite (suspend_str, sizeof(char), strlen (suspend_str), f) < strlen (suspend_str)) { g_printerr ("Error writing %s to %s: %m\n", power_level_path, suspend_str); } diff --git a/src/helpers/job-drive-poll.c b/src/helpers/job-drive-poll.c index 088fa78..2844d02 100644 --- a/src/helpers/job-drive-poll.c +++ b/src/helpers/job-drive-poll.c @@ -37,7 +37,8 @@ usage (void) } int -main (int argc, char *argv[]) +main (int argc, + char *argv[]) { int ret; const gchar *device_file; diff --git a/src/helpers/job-fstab-mounter.c b/src/helpers/job-fstab-mounter.c index 594770c..b532bdb 100644 --- a/src/helpers/job-fstab-mounter.c +++ b/src/helpers/job-fstab-mounter.c @@ -40,88 +40,105 @@ #include "job-shared.h" int -main (int argc, char **argv) +main (int argc, + char **argv) { - int ret; - int exit_status; - GError *error; - const char *action; - const char *device; - uid_t uid; - char *command_line; - char *standard_error; - char *endp; - gboolean do_mount; - gboolean do_unmount; - gboolean do_force_unmount; + int ret; + int exit_status; + GError *error; + const char *action; + const char *device; + uid_t uid; + char *command_line; + char *standard_error; + char *endp; + gboolean do_mount; + gboolean do_unmount; + gboolean do_force_unmount; - ret = 1; - command_line = NULL; - standard_error = NULL; - do_mount = FALSE; - do_unmount = FALSE; - do_force_unmount = FALSE; + ret = 1; + command_line = NULL; + standard_error = NULL; + do_mount = FALSE; + do_unmount = FALSE; + do_force_unmount = FALSE; - if (argc != 4) { - g_printerr ("wrong usage: expected 3 parameters, got %d\n", argc); - goto out; - } - action = argv[1]; - device = argv[2]; - uid = strtol (argv[3], &endp, 10); - if (endp == NULL || *endp != '\0') { - g_printerr ("wrong usage: malformed uid '%s'\n", argv[3]); - goto out; - } - if (strcmp (action, "mount") == 0) { - do_mount = TRUE; - } else if (strcmp (action, "unmount") == 0) { - do_unmount = TRUE; - } else if (strcmp (action, "force_unmount") == 0) { - do_force_unmount = TRUE; - } else { - g_printerr ("wrong usage: malformed action '%s'\n", action); - goto out; - } + if (argc != 4) + { + g_printerr ("wrong usage: expected 3 parameters, got %d\n", argc); + goto out; + } + action = argv[1]; + device = argv[2]; + uid = strtol (argv[3], &endp, 10); + if (endp == NULL || *endp != '\0') + { + g_printerr ("wrong usage: malformed uid '%s'\n", argv[3]); + goto out; + } + if (strcmp (action, "mount") == 0) + { + do_mount = TRUE; + } + else if (strcmp (action, "unmount") == 0) + { + do_unmount = TRUE; + } + else if (strcmp (action, "force_unmount") == 0) + { + do_force_unmount = TRUE; + } + else + { + g_printerr ("wrong usage: malformed action '%s'\n", action); + goto out; + } - /* become the user; right now we are uid 0.. so after the setuid() call we - * can never gain root again - */ - if (uid != 0) { - if (setuid (uid) != 0) { - g_printerr ("cannot switch to uid %d: %m\n", uid); - goto out; - } + /* become the user; right now we are uid 0.. so after the setuid() call we + * can never gain root again + */ + if (uid != 0) + { + if (setuid (uid) != 0) + { + g_printerr ("cannot switch to uid %d: %m\n", uid); + goto out; } + } - if (do_mount) { - command_line = g_strdup_printf ("mount %s", device); - } else if (do_unmount) { - command_line = g_strdup_printf ("umount %s", device); - } else if (do_force_unmount) { - command_line = g_strdup_printf ("umount -l %s", device); - } else { - g_assert_not_reached (); - } + if (do_mount) + { + command_line = g_strdup_printf ("mount %s", device); + } + else if (do_unmount) + { + command_line = g_strdup_printf ("umount %s", device); + } + else if (do_force_unmount) + { + command_line = g_strdup_printf ("umount -l %s", device); + } + else + { + g_assert_not_reached (); + } - error = NULL; - if (!g_spawn_command_line_sync (command_line, - NULL, - &standard_error, - &exit_status, - &error)) { - g_printerr ("cannot spawn '%s': %s\n", command_line, error->message); - g_error_free (error); - goto out; - } - if (WEXITSTATUS (exit_status) != 0) { - g_printerr ("helper failed with:\n%s", standard_error); - goto out; - } - ret = 0; + error = NULL; + if (!g_spawn_command_line_sync (command_line, NULL, &standard_error, &exit_status, &error)) + { + g_printerr ("cannot spawn '%s': %s\n", command_line, error->message); + g_error_free (error); + goto out; + } + if (WEXITSTATUS (exit_status) != 0) + { + g_printerr ("helper failed with:\n%s", standard_error); + goto out; + } + ret = 0; -out: - g_free (standard_error); - g_free (command_line); - return ret; + out: + g_free (standard_error); + g_free (command_line); + return ret; } diff --git a/src/helpers/job-linux-md-check.c b/src/helpers/job-linux-md-check.c index e9e2ee1..ba19c7d 100644 --- a/src/helpers/job-linux-md-check.c +++ b/src/helpers/job-linux-md-check.c @@ -45,48 +45,53 @@ sysfs_put_string (const gchar *sysfs_path, const gchar *file, const gchar *value) { - FILE *f; - gchar *filename; - gboolean ret; - - ret = FALSE; - filename = NULL; - - filename = g_build_filename (sysfs_path, file, NULL); - f = fopen (filename, "w"); - if (f == NULL) { - g_printerr ("error opening %s for writing: %m\n", filename); - goto out; - } else { - if (fputs (value, f) == EOF) { - g_printerr ("error writing '%s' to %s: %m\n", value, filename); - fclose (f); - goto out; - } - fclose (f); + FILE *f; + gchar *filename; + gboolean ret; + + ret = FALSE; + filename = NULL; + + filename = g_build_filename (sysfs_path, file, NULL); + f = fopen (filename, "w"); + if (f == NULL) + { + g_printerr ("error opening %s for writing: %m\n", filename); + goto out; + } + else + { + if (fputs (value, f) == EOF) + { + g_printerr ("error writing '%s' to %s: %m\n", value, filename); + fclose (f); + goto out; } + fclose (f); + } - ret = TRUE; + ret = TRUE; out: - g_free (filename); - return ret; + g_free (filename); + return ret; } static char * sysfs_get_string (const gchar *sysfs_path, const gchar *file) { - gchar *result; - gchar *filename; - - result = NULL; - filename = g_build_filename (sysfs_path, file, NULL); - if (!g_file_get_contents (filename, &result, NULL, NULL)) { - result = g_strdup (""); - } - g_free (filename); - - return result; + gchar *result; + gchar *filename; + + result = NULL; + filename = g_build_filename (sysfs_path, file, NULL); + if (!g_file_get_contents (filename, &result, NULL, NULL)) + { + result = g_strdup (""); + } + g_free (filename); + + return result; } static gboolean cancelled = FALSE; @@ -94,92 +99,106 @@ static gboolean cancelled = FALSE; static void sigterm_handler (int signum) { - cancelled = TRUE; + cancelled = TRUE; } int -main (int argc, char **argv) +main (int argc, + char **argv) { - gint ret; - const gchar *device; - const gchar *sysfs_path; - gchar *sync_action; - gboolean repair; - gchar **options; - gint n; - - ret = 1; - repair = FALSE; - sync_action = NULL; - - if (argc < 3) { - g_printerr ("wrong usage\n"); - goto out; + gint ret; + const gchar *device; + const gchar *sysfs_path; + gchar *sync_action; + gboolean repair; + gchar **options; + gint n; + + ret = 1; + repair = FALSE; + sync_action = NULL; + + if (argc < 3) + { + g_printerr ("wrong usage\n"); + goto out; + } + device = argv[1]; + sysfs_path = argv[2]; + options = argv + 3; + + for (n = 0; options[n] != NULL; n++) + { + if (strcmp (options[n], "repair") == 0) + { + repair = TRUE; } - device = argv[1]; - sysfs_path = argv[2]; - options = argv + 3; - - for (n = 0; options[n] != NULL; n++) { - if (strcmp (options[n], "repair") == 0) { - repair = TRUE; - } else { - g_printerr ("option %s not supported\n", options[n]); - goto out; - } + else + { + g_printerr ("option %s not supported\n", options[n]); + goto out; } - - g_print ("device = '%s'\n", device); - g_print ("repair = %d\n", repair); - - sync_action = sysfs_get_string (sysfs_path, "md/sync_action"); - g_strstrip (sync_action); - if (g_strcmp0 (sync_action, "idle") != 0) { - g_printerr ("device %s is not idle\n", device); - goto out; + } + + g_print ("device = '%s'\n", device); + g_print ("repair = %d\n", repair); + + sync_action = sysfs_get_string (sysfs_path, "md/sync_action"); + g_strstrip (sync_action); + if (g_strcmp0 (sync_action, "idle") != 0) + { + g_printerr ("device %s is not idle\n", device); + goto out; + } + + /* if the user cancels, catch that and make the array idle */ + signal (SIGTERM, sigterm_handler); + + if (!sysfs_put_string (sysfs_path, "md/sync_action", repair ? "repair" : "check")) + { + goto out; + } + + g_print ("udisks-helper-progress: 0\n"); + while (!cancelled) + { + guint64 done; + guint64 remaining; + gchar *s; + + sleep (2); + + sync_action = sysfs_get_string (sysfs_path, "md/sync_action"); + g_strstrip (sync_action); + if (g_strcmp0 (sync_action, "idle") == 0) + { + break; } + g_free (sync_action); + sync_action = NULL; - /* if the user cancels, catch that and make the array idle */ - signal (SIGTERM, sigterm_handler); - - if (!sysfs_put_string (sysfs_path, "md/sync_action", repair ? "repair" : "check")) { - goto out; + s = g_strstrip (sysfs_get_string (sysfs_path, "md/sync_completed")); + if (sscanf (s, "%" G_GUINT64_FORMAT " / %" G_GUINT64_FORMAT "", &done, &remaining) == 2) + { + g_print ("udisks-helper-progress: %d\n", (gint) (100L * done / remaining)); } - - g_print ("udisks-helper-progress: 0\n"); - while (!cancelled) { - guint64 done; - guint64 remaining; - gchar *s; - - sleep (2); - - sync_action = sysfs_get_string (sysfs_path, "md/sync_action"); - g_strstrip (sync_action); - if (g_strcmp0 (sync_action, "idle") == 0) { - break; - } - g_free (sync_action); - sync_action = NULL; - - s = g_strstrip (sysfs_get_string (sysfs_path, "md/sync_completed")); - if (sscanf (s, "%" G_GUINT64_FORMAT " / %" G_GUINT64_FORMAT "", &done, &remaining) == 2) { - g_print ("udisks-helper-progress: %d\n", (gint) (100L * done / remaining)); - } else { - g_printerr ("Cannot parse md/sync_completed: '%s'", s); - goto out; - } - g_free (s); + else + { + g_printerr ("Cannot parse md/sync_completed: '%s'", s); + goto out; } + g_free (s); + } - if (cancelled) { - sysfs_put_string (sysfs_path, "md/sync_action", "idle"); - goto out; - } + if (cancelled) + { + sysfs_put_string (sysfs_path, "md/sync_action", "idle"); + goto out; + } - ret = 0; + ret = 0; -out: - g_free (sync_action); - return ret; + out: + g_free (sync_action); + return ret; } diff --git a/src/helpers/job-linux-md-remove-component.c b/src/helpers/job-linux-md-remove-component.c index 21f6024..031b340 100644 --- a/src/helpers/job-linux-md-remove-component.c +++ b/src/helpers/job-linux-md-remove-component.c @@ -41,103 +41,101 @@ #include "job-shared.h" int -main (int argc, char **argv) +main (int argc, + char **argv) { - int ret; - int exit_status; - GError *error; - char *command_line; - char *standard_error; - char *device; - char *slave; - char *erase; - char **options; - int n; - - ret = 1; - command_line = NULL; - standard_error = NULL; - erase = NULL; - - if (argc < 3) { - g_printerr ("wrong usage\n"); - goto out; + int ret; + int exit_status; + GError *error; + char *command_line; + char *standard_error; + char *device; + char *slave; + char *erase; + char **options; + int n; + + ret = 1; + command_line = NULL; + standard_error = NULL; + erase = NULL; + + if (argc < 3) + { + g_printerr ("wrong usage\n"); + goto out; + } + device = argv[1]; + slave = argv[2]; + options = argv + 3; + + for (n = 0; options[n] != NULL; n++) + { + if (g_str_has_prefix (options[n], "erase=")) + { + erase = strdup (options[n] + sizeof("erase=") - 1); } - device = argv[1]; - slave = argv[2]; - options = argv + 3; - - for (n = 0; options[n] != NULL; n++) { - if (g_str_has_prefix (options[n], "erase=")) { - erase = strdup (options[n] + sizeof ("erase=") - 1); - } else { - g_printerr ("option %s not supported\n", options[n]); - goto out; - } + else + { + g_printerr ("option %s not supported\n", options[n]); + goto out; } - - g_print ("device = '%s'\n", device); - g_print ("slave = '%s'\n", slave); - g_print ("erase = '%s'\n", erase); - - /* first we fail it... */ - command_line = g_strdup_printf ("mdadm --manage %s --fail %s", - device, - slave); - - error = NULL; - if (!g_spawn_command_line_sync (command_line, - NULL, - &standard_error, - &exit_status, - &error)) { - g_printerr ("cannot spawn '%s': %s\n", command_line, error->message); - g_error_free (error); - goto out; - } - if (WEXITSTATUS (exit_status) != 0) { - g_printerr ("'%s' failed with: '%s'\n", command_line, standard_error); - goto out; - } - g_free (standard_error); - g_free (command_line); - standard_error = NULL; - command_line = NULL; - - /* TODO: Seems like a kernel bug that you can't immediately remove a component - * that you just failed. For now sleeping seems to work. - */ - sleep (1); - - /* ...then we remove it */ - command_line = g_strdup_printf ("mdadm --manage %s --remove %s", - device, - slave); - - error = NULL; - if (!g_spawn_command_line_sync (command_line, - NULL, - &standard_error, - &exit_status, - &error)) { - g_printerr ("cannot spawn '%s': %s\n", command_line, error->message); - g_error_free (error); - goto out; - } - if (WEXITSTATUS (exit_status) != 0) { - g_printerr ("'%s' failed with: '%s'\n", command_line, standard_error); - goto out; - } - g_free (standard_error); - g_free (command_line); - standard_error = NULL; - command_line = NULL; - - ret = 0; - -out: - g_free (standard_error); - g_free (command_line); - g_free (erase); - return ret; + } + + g_print ("device = '%s'\n", device); + g_print ("slave = '%s'\n", slave); + g_print ("erase = '%s'\n", erase); + + /* first we fail it... */ + command_line = g_strdup_printf ("mdadm --manage %s --fail %s", device, slave); + + error = NULL; + if (!g_spawn_command_line_sync (command_line, NULL, &standard_error, &exit_status, &error)) + { + g_printerr ("cannot spawn '%s': %s\n", command_line, error->message); + g_error_free (error); + goto out; + } + if (WEXITSTATUS (exit_status) != 0) + { + g_printerr ("'%s' failed with: '%s'\n", command_line, standard_error); + goto out; + } + g_free (standard_error); + g_free (command_line); + standard_error = NULL; + command_line = NULL; + + /* TODO: Seems like a kernel bug that you can't immediately remove a component + * that you just failed. For now sleeping seems to work. + */ + sleep (1); + + /* ...then we remove it */ + command_line = g_strdup_printf ("mdadm --manage %s --remove %s", device, slave); + + error = NULL; + if (!g_spawn_command_line_sync (command_line, NULL, &standard_error, &exit_status, &error)) + { + g_printerr ("cannot spawn '%s': %s\n", command_line, error->message); + g_error_free (error); + goto out; + } + if (WEXITSTATUS (exit_status) != 0) + { + g_printerr ("'%s' failed with: '%s'\n", command_line, standard_error); + goto out; + } + g_free (standard_error); + g_free (command_line); + standard_error = NULL; + command_line = NULL; + + ret = 0; + + out: + g_free (standard_error); + g_free (command_line); + g_free (erase); + return ret; } diff --git a/src/helpers/job-mkfs.c b/src/helpers/job-mkfs.c index 431cb97..490258c 100644 --- a/src/helpers/job-mkfs.c +++ b/src/helpers/job-mkfs.c @@ -41,354 +41,423 @@ #include "job-shared.h" int -main (int argc, char **argv) +main (int argc, + char **argv) { - int fd; - int ret; - int exit_status; - GError *error; - const char *fstype; - const char *device; - char *command_line; - char *standard_error; - char **options; - GString *s; - char *label; - int n; - gboolean is_kernel_partitioned; - GIOChannel *stdin_channel; - GPtrArray *options_array; - char *option; - gsize option_len; - char *endp; - uid_t take_ownership_uid; - gid_t take_ownership_gid; - - ret = 1; - command_line = NULL; - standard_error = NULL; - take_ownership_uid = 0; - take_ownership_gid = 0; - label = NULL; - - if (argc != 4) { - g_printerr ("wrong usage\n"); - goto out; - } - fstype = argv[1]; - device = argv[2]; - is_kernel_partitioned = (strcmp (argv[3], "1") == 0); - - options_array = g_ptr_array_new (); - stdin_channel = g_io_channel_unix_new (0); - if (stdin_channel == NULL) { - g_printerr ("cannot open stdin\n"); - goto out; - } - while (g_io_channel_read_line (stdin_channel, - &option, - &option_len, - NULL, - NULL) == G_IO_STATUS_NORMAL) { - option[option_len - 1] = '\0'; - if (strlen (option) == 0) - break; - g_ptr_array_add (options_array, option); - } - g_io_channel_unref (stdin_channel); - g_ptr_array_add (options_array, NULL); - options = (char **) g_ptr_array_free (options_array, FALSE); - - if (strcmp (fstype, "vfat") == 0) { - - /* allow to create an fs on the main block device */ - s = g_string_new ("mkfs.vfat -I"); - for (n = 0; options[n] != NULL; n++) { - if (g_str_has_prefix (options[n], "label=")) { - label = strdup (options[n] + sizeof ("label=") - 1); - if (!validate_and_escape_label (&label, 254)) { - g_string_free (s, TRUE); - goto out; - } - if (strlen (label) <= 11) { - g_string_append_printf (s, " -n \"%s\"", label); - g_free (label); - label = NULL; - } - } else { - g_printerr ("option %s not supported\n", options[n]); - goto out; - } + int fd; + int ret; + int exit_status; + GError *error; + const char *fstype; + const char *device; + char *command_line; + char *standard_error; + char **options; + GString *s; + char *label; + int n; + gboolean is_kernel_partitioned; + GIOChannel *stdin_channel; + GPtrArray *options_array; + char *option; + gsize option_len; + char *endp; + uid_t take_ownership_uid; + gid_t take_ownership_gid; + + ret = 1; + command_line = NULL; + standard_error = NULL; + take_ownership_uid = 0; + take_ownership_gid = 0; + label = NULL; + + if (argc != 4) + { + g_printerr ("wrong usage\n"); + goto out; + } + fstype = argv[1]; + device = argv[2]; + is_kernel_partitioned = (strcmp (argv[3], "1") == 0); + + options_array = g_ptr_array_new (); + stdin_channel = g_io_channel_unix_new (0); + if (stdin_channel == NULL) + { + g_printerr ("cannot open stdin\n"); + goto out; + } + while (g_io_channel_read_line (stdin_channel, &option, &option_len, NULL, NULL) == G_IO_STATUS_NORMAL) + { + option[option_len - 1] = '\0'; + if (strlen (option) == 0) + break; + g_ptr_array_add (options_array, option); + } + g_io_channel_unref (stdin_channel); + g_ptr_array_add (options_array, NULL); + options = (char **) g_ptr_array_free (options_array, FALSE); + + if (strcmp (fstype, "vfat") == 0) + { + + /* allow to create an fs on the main block device */ + s = g_string_new ("mkfs.vfat -I"); + for (n = 0; options[n] != NULL; n++) + { + if (g_str_has_prefix (options[n], "label=")) + { + label = strdup (options[n] + sizeof("label=") - 1); + if (!validate_and_escape_label (&label, 254)) + { + g_string_free (s, TRUE); + goto out; } - g_string_append_printf (s, " %s", device); - command_line = g_string_free (s, FALSE); - - } else if (strcmp (fstype, "ext2") == 0 || strcmp (fstype, "ext3") == 0 || strcmp (fstype, "ext4") == 0) { - - s = g_string_new ("mkfs."); - g_string_append (s, fstype); - for (n = 0; options[n] != NULL; n++) { - g_string_append (s, " -F "); - if (g_str_has_prefix (options[n], "label=")) { - label = strdup (options[n] + sizeof ("label=") - 1); - if (!validate_and_escape_label (&label, 16)) { - g_string_free (s, TRUE); - goto out; - } - g_string_append_printf (s, " -L \"%s\"", label); - g_free (label); - label = NULL; - } else if (g_str_has_prefix (options[n], "take_ownership_uid=")) { - take_ownership_uid = strtol (options[n] + sizeof ("take_ownership_uid=") - 1, &endp, 10); - if (endp == NULL || *endp != '\0') { - g_printerr ("option %s is malformed\n", options[n]); - goto out; - } - } else if (g_str_has_prefix (options[n], "take_ownership_gid=")) { - take_ownership_gid = strtol (options[n] + sizeof ("take_ownership_gid=") - 1, &endp, 10); - if (endp == NULL || *endp != '\0') { - g_printerr ("option %s is malformed\n", options[n]); - goto out; - } - } else { - g_printerr ("option %s not supported\n", options[n]); - goto out; - } + if (strlen (label) <= 11) + { + g_string_append_printf (s, " -n \"%s\"", label); + g_free (label); + label = NULL; } - g_string_append_printf (s, " %s", device); - command_line = g_string_free (s, FALSE); - - } else if (strcmp (fstype, "xfs") == 0) { - - s = g_string_new ("mkfs.xfs"); - for (n = 0; options[n] != NULL; n++) { - if (g_str_has_prefix (options[n], "label=")) { - label = strdup (options[n] + sizeof ("label=") - 1); - if (!validate_and_escape_label (&label, 12)) { - g_string_free (s, TRUE); - goto out; - } - g_string_append_printf (s, " -L \"%s\"", label); - g_free (label); - label = NULL; - } else if (g_str_has_prefix (options[n], "take_ownership_uid=")) { - take_ownership_uid = strtol (options[n] + sizeof ("take_ownership_uid=") - 1, &endp, 10); - if (endp == NULL || *endp != '\0') { - g_printerr ("option %s is malformed\n", options[n]); - goto out; - } - } else if (g_str_has_prefix (options[n], "take_ownership_gid=")) { - take_ownership_gid = strtol (options[n] + sizeof ("take_ownership_gid=") - 1, &endp, 10); - if (endp == NULL || *endp != '\0') { - g_printerr ("option %s is malformed\n", options[n]); - goto out; - } - } else { - g_printerr ("option %s not supported\n", options[n]); - goto out; - } + } + else + { + g_printerr ("option %s not supported\n", options[n]); + goto out; + } + } + g_string_append_printf (s, " %s", device); + command_line = g_string_free (s, FALSE); + + } + else if (strcmp (fstype, "ext2") == 0 || strcmp (fstype, "ext3") == 0 || strcmp (fstype, "ext4") == 0) + { + + s = g_string_new ("mkfs."); + g_string_append (s, fstype); + for (n = 0; options[n] != NULL; n++) + { + g_string_append (s, " -F "); + if (g_str_has_prefix (options[n], "label=")) + { + label = strdup (options[n] + sizeof("label=") - 1); + if (!validate_and_escape_label (&label, 16)) + { + g_string_free (s, TRUE); + goto out; } - g_string_append_printf (s, " %s", device); - command_line = g_string_free (s, FALSE); - - } else if (strcmp (fstype, "ntfs") == 0) { - - /* skip zeroing (we do that ourselves) and bad sector checking (will - * eventually be handled on a higher level) - */ - s = g_string_new ("mkntfs -f"); - for (n = 0; options[n] != NULL; n++) { - if (g_str_has_prefix (options[n], "label=")) { - label = strdup (options[n] + sizeof ("label=") - 1); - if (!validate_and_escape_label (&label, 255)) { - g_string_free (s, TRUE); - goto out; - } - g_string_append_printf (s, " -L \"%s\"", label); - g_free (label); - label = NULL; - } else { - g_printerr ("option %s not supported\n", options[n]); - goto out; - } + g_string_append_printf (s, " -L \"%s\"", label); + g_free (label); + label = NULL; + } + else if (g_str_has_prefix (options[n], "take_ownership_uid=")) + { + take_ownership_uid = strtol (options[n] + sizeof("take_ownership_uid=") - 1, &endp, 10); + if (endp == NULL || *endp != '\0') + { + g_printerr ("option %s is malformed\n", options[n]); + goto out; } - g_string_append_printf (s, " %s", device); - command_line = g_string_free (s, FALSE); - - } else if (strcmp (fstype, "minix") == 0) { - - s = g_string_new ("mkfs.minix"); - /* minix does not support labels */ - for (n = 0; options[n] != NULL; n++) { - if (g_str_has_prefix (options[n], "take_ownership_uid=")) { - take_ownership_uid = strtol (options[n] + sizeof ("take_ownership_uid=") - 1, &endp, 10); - if (endp == NULL || *endp != '\0') { - g_printerr ("option %s is malformed\n", options[n]); - goto out; - } - } else if (g_str_has_prefix (options[n], "take_ownership_gid=")) { - take_ownership_gid = strtol (options[n] + sizeof ("take_ownership_gid=") - 1, &endp, 10); - if (endp == NULL || *endp != '\0') { - g_printerr ("option %s is malformed\n", options[n]); - goto out; - } - } else { - g_printerr ("option %s not supported\n", options[n]); - goto out; - } + } + else if (g_str_has_prefix (options[n], "take_ownership_gid=")) + { + take_ownership_gid = strtol (options[n] + sizeof("take_ownership_gid=") - 1, &endp, 10); + if (endp == NULL || *endp != '\0') + { + g_printerr ("option %s is malformed\n", options[n]); + goto out; } - g_string_append_printf (s, " %s", device); - command_line = g_string_free (s, FALSE); - - } else if (strcmp (fstype, "swap") == 0) { - - s = g_string_new ("mkswap"); - for (n = 0; options[n] != NULL; n++) { - if (g_str_has_prefix (options[n], "label=")) { - label = strdup (options[n] + sizeof ("label=") - 1); - if (!validate_and_escape_label (&label, 15)) { - g_string_free (s, TRUE); - goto out; - } - g_string_append_printf (s, " -L \"%s\"", label); - g_free (label); - label = NULL; - } else { - g_printerr ("option %s not supported\n", options[n]); - goto out; - } + } + else + { + g_printerr ("option %s not supported\n", options[n]); + goto out; + } + } + g_string_append_printf (s, " %s", device); + command_line = g_string_free (s, FALSE); + + } + else if (strcmp (fstype, "xfs") == 0) + { + + s = g_string_new ("mkfs.xfs"); + for (n = 0; options[n] != NULL; n++) + { + if (g_str_has_prefix (options[n], "label=")) + { + label = strdup (options[n] + sizeof("label=") - 1); + if (!validate_and_escape_label (&label, 12)) + { + g_string_free (s, TRUE); + goto out; } - g_string_append_printf (s, " %s", device); - command_line = g_string_free (s, FALSE); - - } else if (strcmp (fstype, "empty") == 0) { - command_line = NULL; - for (n = 0; options[n] != NULL; n++) { - g_printerr ("option %s not supported\n", options[n]); - goto out; + g_string_append_printf (s, " -L \"%s\"", label); + g_free (label); + label = NULL; + } + else if (g_str_has_prefix (options[n], "take_ownership_uid=")) + { + take_ownership_uid = strtol (options[n] + sizeof("take_ownership_uid=") - 1, &endp, 10); + if (endp == NULL || *endp != '\0') + { + g_printerr ("option %s is malformed\n", options[n]); + goto out; } - } else { - g_printerr ("fstype %s not supported\n", fstype); - goto out; - } - - /* scrub signatures */ - if (!scrub_signatures (device, 0, 0)) - goto out; - - if (command_line != NULL) { - error = NULL; - if (!g_spawn_command_line_sync (command_line, - NULL, - &standard_error, - &exit_status, - &error)) { - g_printerr ("cannot spawn '%s': %s\n", command_line, error->message); - ret = 3; /* indicate FilesystemToolsMissing error */ - g_error_free (error); - goto out; + } + else if (g_str_has_prefix (options[n], "take_ownership_gid=")) + { + take_ownership_gid = strtol (options[n] + sizeof("take_ownership_gid=") - 1, &endp, 10); + if (endp == NULL || *endp != '\0') + { + g_printerr ("option %s is malformed\n", options[n]); + goto out; } - if (WEXITSTATUS (exit_status) != 0) { - g_printerr ("helper failed with:\n%s", standard_error); - goto out; + } + else + { + g_printerr ("option %s not supported\n", options[n]); + goto out; + } + } + g_string_append_printf (s, " %s", device); + command_line = g_string_free (s, FALSE); + + } + else if (strcmp (fstype, "ntfs") == 0) + { + + /* skip zeroing (we do that ourselves) and bad sector checking (will + * eventually be handled on a higher level) + */ + s = g_string_new ("mkntfs -f"); + for (n = 0; options[n] != NULL; n++) + { + if (g_str_has_prefix (options[n], "label=")) + { + label = strdup (options[n] + sizeof("label=") - 1); + if (!validate_and_escape_label (&label, 255)) + { + g_string_free (s, TRUE); + goto out; } + g_string_append_printf (s, " -L \"%s\"", label); + g_free (label); + label = NULL; + } + else + { + g_printerr ("option %s not supported\n", options[n]); + goto out; + } } - - if (label != NULL) { - g_free (command_line); - - if (strcmp (fstype, "vfat") == 0) { - command_line = g_strdup_printf ("mlabel -i %s \"::%s\"", device, label); - } else { - g_printerr ("label change for fstype '%s' requested but not implemented", fstype); - goto out; + g_string_append_printf (s, " %s", device); + command_line = g_string_free (s, FALSE); + + } + else if (strcmp (fstype, "minix") == 0) + { + + s = g_string_new ("mkfs.minix"); + /* minix does not support labels */ + for (n = 0; options[n] != NULL; n++) + { + if (g_str_has_prefix (options[n], "take_ownership_uid=")) + { + take_ownership_uid = strtol (options[n] + sizeof("take_ownership_uid=") - 1, &endp, 10); + if (endp == NULL || *endp != '\0') + { + g_printerr ("option %s is malformed\n", options[n]); + goto out; } - - error = NULL; - if (!g_spawn_command_line_sync (command_line, - NULL, - &standard_error, - &exit_status, - &error)) { - g_printerr ("cannot spawn '%s': %s\n", command_line, error->message); - g_error_free (error); - ret = 3; /* indicate FilesystemToolsMissing error */ - goto out; + } + else if (g_str_has_prefix (options[n], "take_ownership_gid=")) + { + take_ownership_gid = strtol (options[n] + sizeof("take_ownership_gid=") - 1, &endp, 10); + if (endp == NULL || *endp != '\0') + { + g_printerr ("option %s is malformed\n", options[n]); + goto out; } - if (WEXITSTATUS (exit_status) != 0) { - g_printerr ("helper failed with:\n%s", standard_error); - goto out; + } + else + { + g_printerr ("option %s not supported\n", options[n]); + goto out; + } + } + g_string_append_printf (s, " %s", device); + command_line = g_string_free (s, FALSE); + + } + else if (strcmp (fstype, "swap") == 0) + { + + s = g_string_new ("mkswap"); + for (n = 0; options[n] != NULL; n++) + { + if (g_str_has_prefix (options[n], "label=")) + { + label = strdup (options[n] + sizeof("label=") - 1); + if (!validate_and_escape_label (&label, 15)) + { + g_string_free (s, TRUE); + goto out; } - - g_free (label); + g_string_append_printf (s, " -L \"%s\"", label); + g_free (label); + label = NULL; + } + else + { + g_printerr ("option %s not supported\n", options[n]); + goto out; + } } + g_string_append_printf (s, " %s", device); + command_line = g_string_free (s, FALSE); + + } + else if (strcmp (fstype, "empty") == 0) + { + command_line = NULL; + for (n = 0; options[n] != NULL; n++) + { + g_printerr ("option %s not supported\n", options[n]); + goto out; + } + } + else + { + g_printerr ("fstype %s not supported\n", fstype); + goto out; + } + + /* scrub signatures */ + if (!scrub_signatures (device, 0, 0)) + goto out; + + if (command_line != NULL) + { + error = NULL; + if (!g_spawn_command_line_sync (command_line, NULL, &standard_error, &exit_status, &error)) + { + g_printerr ("cannot spawn '%s': %s\n", command_line, error->message); + ret = 3; /* indicate FilesystemToolsMissing error */ + g_error_free (error); + goto out; + } + if (WEXITSTATUS (exit_status) != 0) + { + g_printerr ("helper failed with:\n%s", standard_error); + goto out; + } + } + if (label != NULL) + { + g_free (command_line); - /* If we've created an fs on a partitioned device, then signal the - * kernel to reread the (now missing) partition table. - */ - if (is_kernel_partitioned) { - fd = open (device, O_RDONLY); - if (fd < 0) { - g_printerr ("cannot open %s (for BLKRRPART): %m\n", device); - goto out; - } - if (ioctl (fd, BLKRRPART) != 0) { - close (fd); - g_printerr ("BLKRRPART ioctl failed for %s: %m\n", device); - goto out; - } - close (fd); + if (strcmp (fstype, "vfat") == 0) + { + command_line = g_strdup_printf ("mlabel -i %s \"::%s\"", device, label); + } + else + { + g_printerr ("label change for fstype '%s' requested but not implemented", fstype); + goto out; } - /* take ownership of the device if requested */ - if (take_ownership_uid != 0 || take_ownership_gid != 0) { - char dir[256] = PACKAGE_LOCALSTATE_DIR "/run/udisks/job-mkfs-XXXXXX"; + error = NULL; + if (!g_spawn_command_line_sync (command_line, NULL, &standard_error, &exit_status, &error)) + { + g_printerr ("cannot spawn '%s': %s\n", command_line, error->message); + g_error_free (error); + ret = 3; /* indicate FilesystemToolsMissing error */ + goto out; + } + if (WEXITSTATUS (exit_status) != 0) + { + g_printerr ("helper failed with:\n%s", standard_error); + goto out; + } - if (mkdtemp (dir) == NULL) { - g_printerr ("cannot create directory %s: %m\n", dir); - goto out; - } + g_free (label); + } + + /* If we've created an fs on a partitioned device, then signal the + * kernel to reread the (now missing) partition table. + */ + if (is_kernel_partitioned) + { + fd = open (device, O_RDONLY); + if (fd < 0) + { + g_printerr ("cannot open %s (for BLKRRPART): %m\n", device); + goto out; + } + if (ioctl (fd, BLKRRPART) != 0) + { + close (fd); + g_printerr ("BLKRRPART ioctl failed for %s: %m\n", device); + goto out; + } + close (fd); + } + + /* take ownership of the device if requested */ + if (take_ownership_uid != 0 || take_ownership_gid != 0) + { + char dir[256] = PACKAGE_LOCALSTATE_DIR "/run/udisks/job-mkfs-XXXXXX"; + + if (mkdtemp (dir) == NULL) + { + g_printerr ("cannot create directory %s: %m\n", dir); + goto out; + } - if (mount (device, dir, fstype, 0, NULL) != 0) { - g_printerr ("cannot mount %s at %s: %m\n", device, dir); - ret = 2; - goto tos_err0; - } + if (mount (device, dir, fstype, 0, NULL) != 0) + { + g_printerr ("cannot mount %s at %s: %m\n", device, dir); + ret = 2; + goto tos_err0; + } - if (chown (dir, take_ownership_uid, take_ownership_gid) != 0) { - g_printerr ("cannot chown %s to uid=%d and gid=%d: %m\n", - dir, - take_ownership_uid, - take_ownership_gid); - ret = 2; - } + if (chown (dir, take_ownership_uid, take_ownership_gid) != 0) + { + g_printerr ("cannot chown %s to uid=%d and gid=%d: %m\n", dir, take_ownership_uid, take_ownership_gid); + ret = 2; + } - if (chmod (dir, 0700) != 0) { - g_printerr ("cannot chmod %s to mode 0700: %m\n", dir); - ret = 2; - } + if (chmod (dir, 0700) != 0) + { + g_printerr ("cannot chmod %s to mode 0700: %m\n", dir); + ret = 2; + } - if (umount (dir) != 0) { - g_printerr ("cannot unmount %s: %m\n", dir); - ret = 2; - goto tos_err0; - } + if (umount (dir) != 0) + { + g_printerr ("cannot unmount %s: %m\n", dir); + ret = 2; + goto tos_err0; + } - tos_err0: - if (rmdir (dir) != 0) { - g_printerr ("cannot remove directory %s: %m\n", dir); - goto out; - } + tos_err0: + if (rmdir (dir) != 0) + { + g_printerr ("cannot remove directory %s: %m\n", dir); + goto out; } + } - if (ret == 2) - ret = 1; - else - ret = 0; + if (ret == 2) + ret = 1; + else + ret = 0; -out: - g_free (standard_error); - g_free (command_line); - return ret; + out: + g_free (standard_error); + g_free (command_line); + return ret; } diff --git a/src/helpers/job-modify-partition.c b/src/helpers/job-modify-partition.c index 11fb5bb..2ea87b4 100644 --- a/src/helpers/job-modify-partition.c +++ b/src/helpers/job-modify-partition.c @@ -41,79 +41,86 @@ #include "partutil.h" int -main (int argc, char **argv) +main (int argc, + char **argv) { - int ret; - const char *device; - char *label; - char *type; - char *flags_as_string; - char **flags; - guint64 offset; - guint64 size; - guint64 out_start; - guint64 out_size; - char *endp; + int ret; + const char *device; + char *label; + char *type; + char *flags_as_string; + char **flags; + guint64 offset; + guint64 size; + guint64 out_start; + guint64 out_size; + char *endp; - ret = 1; - flags = NULL; + ret = 1; + flags = NULL; - if (argc < 7) { - g_printerr ("wrong usage\n"); - goto out; - } - device = argv[1]; - offset = strtoll (argv[2], &endp, 10); - if (*endp != '\0') { - g_printerr ("malformed offset '%s'\n", argv[2]); - goto out; - } - size = strtoll (argv[3], &endp, 10); - if (*endp != '\0') { - g_printerr ("malformed size '%s'\n", argv[3]); - goto out; - } - type = argv[4]; - label = argv[5]; - flags_as_string = argv[6]; + if (argc < 7) + { + g_printerr ("wrong usage\n"); + goto out; + } + device = argv[1]; + offset = strtoll (argv[2], &endp, 10); + if (*endp != '\0') + { + g_printerr ("malformed offset '%s'\n", argv[2]); + goto out; + } + size = strtoll (argv[3], &endp, 10); + if (*endp != '\0') + { + g_printerr ("malformed size '%s'\n", argv[3]); + goto out; + } + type = argv[4]; + label = argv[5]; + flags_as_string = argv[6]; - flags = g_strsplit (flags_as_string, ",", 0); + flags = g_strsplit (flags_as_string, ",", 0); - /* we trust the caller have verified that the given slice doesn't overlap - * with existing partitions - */ + /* we trust the caller have verified that the given slice doesn't overlap + * with existing partitions + */ - g_print ("type: '%s'\n", type); - g_print ("label: '%s'\n", label); - g_print ("flags_as_string: '%s'\n", flags_as_string); + g_print ("type: '%s'\n", type); + g_print ("label: '%s'\n", label); + g_print ("flags_as_string: '%s'\n", flags_as_string); - if (part_change_partition ((char *) device, - offset, - offset, - size, - &out_start, - &out_size, - type, - strlen (label) > 0 ? label : NULL, - flags, - -1, - -1)) { - if (out_start != offset || - out_size != size) { - g_printerr ("ugh, offset or size changed\n"); - g_printerr ("offset: %" G_GINT64_FORMAT "\n", offset); - g_printerr ("size: %" G_GINT64_FORMAT "\n", size); - g_printerr ("new_offset: %" G_GINT64_FORMAT "\n", out_start); - g_printerr ("new_size: %" G_GINT64_FORMAT "\n", out_size); - } else { - /* success */ - ret = 0; - } + if (part_change_partition ((char *) device, + offset, + offset, + size, + &out_start, + &out_size, + type, + strlen (label) > 0 ? label : NULL, + flags, + -1, + -1)) + { + if (out_start != offset || out_size != size) + { + g_printerr ("ugh, offset or size changed\n"); + g_printerr ("offset: %" G_GINT64_FORMAT "\n", offset); + g_printerr ("size: %" G_GINT64_FORMAT "\n", size); + g_printerr ("new_offset: %" G_GINT64_FORMAT "\n", out_start); + g_printerr ("new_size: %" G_GINT64_FORMAT "\n", out_size); + } + else + { + /* success */ + ret = 0; } + } - /* no need to reread partition table as sizes didn't change */ + /* no need to reread partition table as sizes didn't change */ -out: - g_strfreev (flags); - return ret; + out: + g_strfreev (flags); + return ret; } diff --git a/src/helpers/job-shared.h b/src/helpers/job-shared.h index daeba2e..bd66c32 100644 --- a/src/helpers/job-shared.h +++ b/src/helpers/job-shared.h @@ -40,22 +40,28 @@ /* TODO: maybe move to private static library if there's a lot of shared stuff */ static inline gboolean -_do_write (int fd, void *buf, int num) +_do_write (int fd, + void *buf, + int num) { - gboolean ret; - ret = FALSE; -again: - if (write (fd, buf, num) != (int) num) { - if (errno == EAGAIN) { - goto again; - } else { - g_printerr ("%d: error writing %d bytes: %m\n", getpid (), num); - goto out; - } + gboolean ret; + ret = FALSE; + again: + if (write (fd, buf, num) != (int) num) + { + if (errno == EAGAIN) + { + goto again; } - ret = TRUE; -out: - return ret; + else + { + g_printerr ("%d: error writing %d bytes: %m\n", getpid (), num); + goto out; + } + } + ret = TRUE; + out: + return ret; } #if 0 @@ -63,40 +69,43 @@ out: static inline gboolean _scrub_signatures (int fd, guint64 offset, guint64 size) { - gboolean ret; - guint64 wipe_size; - char buf[ERASE_SIZE]; + gboolean ret; + guint64 wipe_size; + char buf[ERASE_SIZE]; - ret = FALSE; + ret = FALSE; - /* wipe first and last 128KB. Note that btrfs keeps signatures at 0x10000 == 64KB. */ - wipe_size = 128 * 1024; - g_assert (sizeof (buf) >= wipe_size); + /* wipe first and last 128KB. Note that btrfs keeps signatures at 0x10000 == 64KB. */ + wipe_size = 128 * 1024; + g_assert (sizeof (buf) >= wipe_size); - if (wipe_size > size) { - wipe_size = size; - } + if (wipe_size > size) + { + wipe_size = size; + } - if (lseek64 (fd, offset, SEEK_SET) == (off64_t) -1) { - g_printerr ("cannot seek to %" G_GINT64_FORMAT ": %m", offset); - goto out; - } + if (lseek64 (fd, offset, SEEK_SET) == (off64_t) -1) + { + g_printerr ("cannot seek to %" G_GINT64_FORMAT ": %m", offset); + goto out; + } - if (!_do_write (fd, buf, wipe_size)) - goto out; + if (!_do_write (fd, buf, wipe_size)) + goto out; - if (lseek64 (fd, offset + size - wipe_size, SEEK_SET) == (off64_t) -1) { - g_printerr ("cannot seek to %" G_GINT64_FORMAT ": %m", offset + size - wipe_size); - goto out; - } + if (lseek64 (fd, offset + size - wipe_size, SEEK_SET) == (off64_t) -1) + { + g_printerr ("cannot seek to %" G_GINT64_FORMAT ": %m", offset + size - wipe_size); + goto out; + } - if (!_do_write (fd, buf, wipe_size)) - goto out; + if (!_do_write (fd, buf, wipe_size)) + goto out; - ret = TRUE; + ret = TRUE; -out: - return ret; + out: + return ret; } #endif @@ -110,127 +119,140 @@ out: * signatures. **/ static inline gboolean -scrub_signatures (const char *device, guint64 offset, guint64 size) +scrub_signatures (const char *device, + guint64 offset, + guint64 size) { - int fd; - gboolean ret; - char buf[128 * 1024]; - guint64 wipe_size; - - fd = 0; - ret = FALSE; - - fd = open (device, O_WRONLY); - if (fd < 0) { - g_printerr ("cannot open device: %m\n"); - goto out; + int fd; + gboolean ret; + char buf[128 * 1024]; + guint64 wipe_size; + + fd = 0; + ret = FALSE; + + fd = open (device, O_WRONLY); + if (fd < 0) + { + g_printerr ("cannot open device: %m\n"); + goto out; + } + + if (size == 0) + { + if (ioctl (fd, BLKGETSIZE64, &size) != 0) + { + g_printerr ("cannot determine size of device: %m\n"); + goto out; } + } - if (size == 0) { - if (ioctl (fd, BLKGETSIZE64, &size) != 0) { - g_printerr ("cannot determine size of device: %m\n"); - goto out; - } - } + memset (buf, '\0', sizeof(buf)); - memset (buf, '\0', sizeof (buf)); + /* wipe first and last 128KB. Note that btrfs keeps signatures at 0x10000 == 64KB. */ + wipe_size = 128 * 1024; + memset (buf, '\0', sizeof(buf)); - /* wipe first and last 128KB. Note that btrfs keeps signatures at 0x10000 == 64KB. */ - wipe_size = 128 * 1024; - memset (buf, '\0', sizeof (buf)); + if (wipe_size > size) + { + wipe_size = size; + } - if (wipe_size > size) { - wipe_size = size; - } + if (lseek64 (fd, offset, SEEK_SET) == (off64_t) - 1) + { + g_printerr ("cannot seek to %" G_GINT64_FORMAT ": %m", offset); + goto out; + } - if (lseek64 (fd, offset, SEEK_SET) == (off64_t) -1) { - g_printerr ("cannot seek to %" G_GINT64_FORMAT ": %m", offset); - goto out; - } + if (!_do_write (fd, buf, wipe_size)) + goto out; - if (!_do_write (fd, buf, wipe_size)) - goto out; - - if (lseek64 (fd, offset + size - wipe_size, SEEK_SET) == (off64_t) -1) { - g_printerr ("cannot seek to %" G_GINT64_FORMAT ": %m", offset + size - wipe_size); - goto out; - } + if (lseek64 (fd, offset + size - wipe_size, SEEK_SET) == (off64_t) - 1) + { + g_printerr ("cannot seek to %" G_GINT64_FORMAT ": %m", offset + size - wipe_size); + goto out; + } - if (!_do_write (fd, buf, wipe_size)) - goto out; + if (!_do_write (fd, buf, wipe_size)) + goto out; - ret = TRUE; + ret = TRUE; -out: - if (fd >= 0) - close (fd); - return ret; + out: + if (fd >= 0) + close (fd); + return ret; } - static inline gboolean -validate_and_escape_label (char **label, int max_len) +validate_and_escape_label (char **label, + int max_len) { - int n; - gboolean ret; - GString *s; - - ret = FALSE; - - if ((int) strlen (*label) > max_len) { - g_printerr ("given file system label exceeds %d characters\n", max_len); - goto out; - } - - /* escape '"' */ - s = g_string_new (*label); - for (n = 0; n < (int) s->len; n++) { - if (s->str[n] == '"') { - g_string_insert_c (s, n, '\\'); - n++; - } + int n; + gboolean ret; + GString *s; + + ret = FALSE; + + if ((int) strlen (*label) > max_len) + { + g_printerr ("given file system label exceeds %d characters\n", max_len); + goto out; + } + + /* escape '"' */ + s = g_string_new (*label); + for (n = 0; n < (int) s->len; n++) + { + if (s->str[n] == '"') + { + g_string_insert_c (s, n, '\\'); + n++; } - g_free (*label); - *label = g_string_free (s, FALSE); + } + g_free (*label); + *label = g_string_free (s, FALSE); - ret = TRUE; -out: - return ret; + ret = TRUE; + out: + return ret; } static inline gboolean reread_partition_table (const gchar *device_file) { - gint fd; - gboolean ret; - guint num_retries; - - ret = FALSE; - num_retries = 0; - - fd = open (device_file, O_RDONLY); - if (fd < 0) { - g_printerr ("cannot open %s (for BLKRRPART): %m\n", device_file); - goto out; - } + gint fd; + gboolean ret; + guint num_retries; + + ret = FALSE; + num_retries = 0; + + fd = open (device_file, O_RDONLY); + if (fd < 0) + { + g_printerr ("cannot open %s (for BLKRRPART): %m\n", device_file); + goto out; + } try_again: - if (ioctl (fd, BLKRRPART) != 0) { - if (errno == EBUSY && num_retries < 20) { - usleep (250 * 1000); - num_retries++; - goto try_again; - } - close (fd); - g_printerr ("BLKRRPART ioctl failed for %s: %m\n", device_file); - goto out; + if (ioctl (fd, BLKRRPART) != 0) + { + if (errno == EBUSY && num_retries < 20) + { + usleep (250 * 1000); + num_retries++; + goto try_again; } - close (fd); + close (fd); + g_printerr ("BLKRRPART ioctl failed for %s: %m\n", device_file); + goto out; + } + close (fd); - ret = TRUE; + ret = TRUE; out: - return ret; + return ret; } - #endif /* __JOB_SHARED_H__ */ diff --git a/src/helpers/partutil.c b/src/helpers/partutil.c index ec2b52b..f42587a 100644 --- a/src/helpers/partutil.c +++ b/src/helpers/partutil.c @@ -44,7 +44,8 @@ #include "partutil.h" static void -DEBUG (const gchar *format, ...) +DEBUG (const gchar *format, + ...) { #if 1 va_list args; @@ -52,16 +53,14 @@ DEBUG (const gchar *format, ...) g_vfprintf (stderr, format, args); va_end (args); g_fprintf (stderr, "\n"); - fflush (stderr); + fflush ( stderr); #endif } - #ifdef HAVE_CONFIG_H # include #endif - #define USE_PARTED #ifdef USE_PARTED #include @@ -70,27 +69,28 @@ DEBUG (const gchar *format, ...) const char * part_get_scheme_name (PartitionScheme scheme) { - const char *s; - - switch (scheme) { - case PART_TYPE_GPT: - s = "gpt"; - break; - case PART_TYPE_MSDOS: - s = "mbr"; - break; - case PART_TYPE_MSDOS_EXTENDED: - s = "embr"; - break; - case PART_TYPE_APPLE: - s = "apm"; - break; - default: - s = NULL; - break; - } - - return s; + const char *s; + + switch (scheme) + { + case PART_TYPE_GPT: + s = "gpt"; + break; + case PART_TYPE_MSDOS: + s = "mbr"; + break; + case PART_TYPE_MSDOS_EXTENDED: + s = "embr"; + break; + case PART_TYPE_APPLE: + s = "apm"; + break; + default: + s = NULL; + break; + } + + return s; } struct PartitionEntry_s; @@ -98,97 +98,101 @@ typedef struct PartitionEntry_s PartitionEntry; struct PartitionEntry_s { - gboolean is_part_table; + gboolean is_part_table; - /* NULL iff is_part_table==FALSE */ - PartitionTable *part_table; + /* NULL iff is_part_table==FALSE */ + PartitionTable *part_table; - /* these are always set */ - guint8 *data; - int length; + /* these are always set */ + guint8 *data; + int length; - /* offset _on disk_ where the entry starts */ - guint64 offset; + /* offset _on disk_ where the entry starts */ + guint64 offset; }; struct PartitionTable_s { - /* partitioning scheme used */ - PartitionScheme scheme; + /* partitioning scheme used */ + PartitionScheme scheme; - /* offset of table on disk */ - guint64 offset; - guint64 size; + /* offset of table on disk */ + guint64 offset; + guint64 size; - /* block size */ - guint64 block_size; + /* block size */ + guint64 block_size; - /* entries in partition table */ - GSList *entries; + /* entries in partition table */ + GSList *entries; }; void -part_table_find (PartitionTable *p, guint64 offset, - PartitionTable **out_part_table, int *out_entry) +part_table_find (PartitionTable *p, + guint64 offset, + PartitionTable **out_part_table, + int *out_entry) { - int n; - int num_entries; - - *out_part_table = p; - *out_entry = -1; - - num_entries = part_table_get_num_entries (p); - for (n = 0; n < num_entries; n++) { - guint64 pe_offset; - guint64 pe_size; - - pe_offset = part_table_entry_get_offset (p, n); - pe_size = part_table_entry_get_size (p, n); - - if ((offset >= pe_offset) && (offset < pe_offset + pe_size)) { - PartitionTable *part_table_nested; - - part_table_nested = part_table_entry_get_nested (p, n); - /* return the extended partition only if the offset points to it - otherwise - * look for a logical partition - */ - if (part_table_nested != NULL && offset > pe_offset) { - part_table_find (part_table_nested, offset, out_part_table, out_entry); - } else { - *out_entry = n; - } - - /* and we're done... */ - break; - } - } + int n; + int num_entries; + + *out_part_table = p; + *out_entry = -1; + + num_entries = part_table_get_num_entries (p); + for (n = 0; n < num_entries; n++) + { + guint64 pe_offset; + guint64 pe_size; + + pe_offset = part_table_entry_get_offset (p, n); + pe_size = part_table_entry_get_size (p, n); + + if ((offset >= pe_offset) && (offset < pe_offset + pe_size)) + { + PartitionTable *part_table_nested; + + part_table_nested = part_table_entry_get_nested (p, n); + /* return the extended partition only if the offset points to it - otherwise + * look for a logical partition + */ + if (part_table_nested != NULL && offset > pe_offset) + { + part_table_find (part_table_nested, offset, out_part_table, out_entry); + } + else + { + *out_entry = n; + } + + /* and we're done... */ + break; + } + } } - static guint16 get_le16 (const void *buf) { - return GUINT16_FROM_LE ( * ((guint16 *) buf) ); + return GUINT16_FROM_LE (*((guint16 *) buf)); } - static guint32 get_le32 (const void *buf) { - return GUINT32_FROM_LE ( * ((guint32 *) buf) ); + return GUINT32_FROM_LE (*((guint32 *) buf)); } static guint64 get_le64 (const void *buf) { - return GUINT64_FROM_LE ( * ((guint64 *) buf) ); + return GUINT64_FROM_LE (*((guint64 *) buf)); } - static guint32 get_be32 (const void *buf) { - return GUINT32_FROM_BE ( * ((guint32 *) buf) ); + return GUINT32_FROM_BE (*((guint32 *) buf)); } /* see http://en.wikipedia.org/wiki/Globally_Unique_Identifier - excerpt @@ -221,161 +225,170 @@ get_be32 (const void *buf) * 7QDBkvCA1+B9K/U0vrQx1A== */ -typedef struct efi_guid_s { - guint32 data1; - guint16 data2; - guint16 data3; - guint8 data4[8]; -} __attribute__ ((packed)) efi_guid; +typedef struct efi_guid_s +{ + guint32 data1; + guint16 data2; + guint16 data3; + guint8 data4[8]; +}__attribute__ ((packed)) efi_guid; static char * get_le_guid (const guint8 *buf) { - efi_guid *guid = (efi_guid *) buf; - - return g_strdup_printf("%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X", - get_le32 (&(guid->data1)), - get_le16 (&(guid->data2)), - get_le16 (&(guid->data3)), - guid->data4[0], - guid->data4[1], - guid->data4[2], - guid->data4[3], - guid->data4[4], - guid->data4[5], - guid->data4[6], - guid->data4[7]); + efi_guid *guid = (efi_guid *) buf; + + return g_strdup_printf ("%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X", + get_le32 (&(guid->data1)), + get_le16 (&(guid->data2)), + get_le16 (&(guid->data3)), + guid->data4[0], + guid->data4[1], + guid->data4[2], + guid->data4[3], + guid->data4[4], + guid->data4[5], + guid->data4[6], + guid->data4[7]); } #ifdef USE_PARTED static gboolean -set_le_guid (guint8 *buf, const char *source) +set_le_guid (guint8 *buf, + const char *source) { - efi_guid *guid = (efi_guid *) buf; - guint32 __attribute__((__unused__)) data1; - guint16 __attribute__((__unused__)) data2; - guint16 __attribute__((__unused__)) data3; - guint8 __attribute__((__unused__)) data4[8]; - gboolean ret; - int n; - - ret = FALSE; - - n = sscanf (source, "%x-%hx-%hx-%02hhx%02hhx-%02hhx%02hhx%02hhx%02hhx%02hhx%02hhx", - &guid->data1, - &guid->data2, - &guid->data3, - &(guid->data4[0]), - &(guid->data4[1]), - &(guid->data4[2]), - &(guid->data4[3]), - &(guid->data4[4]), - &(guid->data4[5]), - &(guid->data4[6]), - &(guid->data4[7])); - - if (n != 11) { - DEBUG ("guid '%s' is not valid", source); - goto out; - } + efi_guid *guid = (efi_guid *) buf; + guint32 __attribute__((__unused__)) data1; + guint16 __attribute__((__unused__)) data2; + guint16 __attribute__((__unused__)) data3; + guint8 __attribute__((__unused__)) data4[8]; + gboolean ret; + int n; + + ret = FALSE; + + n = sscanf (source, + "%x-%hx-%hx-%02hhx%02hhx-%02hhx%02hhx%02hhx%02hhx%02hhx%02hhx", + &guid->data1, + &guid->data2, + &guid->data3, + &(guid->data4[0]), + &(guid->data4[1]), + &(guid->data4[2]), + &(guid->data4[3]), + &(guid->data4[4]), + &(guid->data4[5]), + &(guid->data4[6]), + &(guid->data4[7])); + + if (n != 11) + { + DEBUG ("guid '%s' is not valid", source); + goto out; + } #if 0 - DEBUG ("source = %s", source)); - DEBUG ("data1 = %08x", guid->data1)); - DEBUG ("data2 = %04x", guid->data2)); - DEBUG ("data3 = %04x", guid->data3)); - DEBUG ("data4[0] = %02x", guid->data4[0])); - DEBUG ("data4[1] = %02x", guid->data4[1])); - DEBUG ("data4[2] = %02x", guid->data4[2])); - DEBUG ("data4[3] = %02x", guid->data4[3])); - DEBUG ("data4[4] = %02x", guid->data4[4])); - DEBUG ("data4[5] = %02x", guid->data4[5])); - DEBUG ("data4[6] = %02x", guid->data4[6])); - DEBUG ("data4[7] = %02x", guid->data4[7])); + DEBUG ("source = %s", source); + DEBUG ("data1 = %08x", guid->data1); + DEBUG ("data2 = %04x", guid->data2); + DEBUG ("data3 = %04x", guid->data3); + DEBUG ("data4[0] = %02x", guid->data4[0]); + DEBUG ("data4[1] = %02x", guid->data4[1]); + DEBUG ("data4[2] = %02x", guid->data4[2]); + DEBUG ("data4[3] = %02x", guid->data4[3]); + DEBUG ("data4[4] = %02x", guid->data4[4]); + DEBUG ("data4[5] = %02x", guid->data4[5]); + DEBUG ("data4[6] = %02x", guid->data4[6]); + DEBUG ("data4[7] = %02x", guid->data4[7]); #endif - guid->data1 = GUINT32_TO_LE (guid->data1); - guid->data2 = GUINT16_TO_LE (guid->data2); - guid->data3 = GUINT16_TO_LE (guid->data3); + guid->data1 = GUINT32_TO_LE (guid->data1); + guid->data2 = GUINT16_TO_LE (guid->data2); + guid->data3 = GUINT16_TO_LE (guid->data3); - ret = TRUE; + ret = TRUE; out: - return ret; + return ret; } #endif static PartitionEntry * -part_entry_new (PartitionTable *e_part_table, const guint8 *data, int length, guint64 offset) +part_entry_new (PartitionTable *e_part_table, + const guint8 *data, + int length, + guint64 offset) { - PartitionEntry *pe; + PartitionEntry *pe; - pe = g_new0 (PartitionEntry, 1); - pe->is_part_table = (e_part_table != NULL); - pe->part_table = e_part_table; - pe->offset = offset; - pe->length = length; - pe->data = g_new0 (guint8, length); - memcpy (pe->data, data, length); + pe = g_new0 (PartitionEntry, 1); + pe->is_part_table = (e_part_table != NULL); + pe->part_table = e_part_table; + pe->offset = offset; + pe->length = length; + pe->data = g_new0 (guint8, length); + memcpy (pe->data, data, length); - return pe; + return pe; } static void part_entry_free (PartitionEntry *pe) { - if (pe->part_table != NULL) { - part_table_free (pe->part_table); - } - g_free (pe->data); - g_free (pe); + if (pe->part_table != NULL) + { + part_table_free (pe->part_table); + } + g_free (pe->data); + g_free (pe); } static PartitionTable * -part_table_new_empty (PartitionScheme scheme, int block_size) +part_table_new_empty (PartitionScheme scheme, + int block_size) { - PartitionTable *p; + PartitionTable *p; - p = g_new0 (PartitionTable, 1); - p->scheme = scheme; - p->offset = 0; - p->entries = NULL; - p->block_size = block_size; + p = g_new0 (PartitionTable, 1); + p->scheme = scheme; + p->offset = 0; + p->entries = NULL; + p->block_size = block_size; - return p; + return p; } void part_table_free (PartitionTable *p) { - GSList *i; - - if (p == NULL) - return; - - for (i = p->entries; i != NULL; i = i->next) { - PartitionEntry *pe = i->data; - part_entry_free (pe); - } - g_slist_free (p->entries); - g_free (p); + GSList *i; + + if (p == NULL) + return; + + for (i = p->entries; i != NULL; i = i->next) + { + PartitionEntry *pe = i->data; + part_entry_free (pe); + } + g_slist_free (p->entries); + g_free (p); } #if 0 static PartitionTable * part_table_parse_bsd (int fd, guint64 offset, guint64 size, int block_size) { - PartitionTable *p; + PartitionTable *p; - p = NULL; + p = NULL; - /* TODO */ + /* TODO */ - return p; + return p; } #endif - #define MSDOS_MAGIC "\x55\xaa" #define MSDOS_PARTTABLE_OFFSET 0x1be #define MSDOS_SIG_OFF 0x1fe @@ -384,247 +397,271 @@ part_table_parse_bsd (int fd, guint64 offset, guint64 size, int block_size) static void hexdump (const guint8 *mem, int size) { - int i; - int j; - int n; - const guint8 *buf = (const guint8 *) mem; - - n = 0; - printf ("Dumping %d=0x%x bytes\n", size, size); - while (n < size) { - - fprintf (stderr, "0x%04x: ", n); - - j = n; - for (i = 0; i < 16; i++) { - if (j >= size) - break; - fprintf (stderr, "%02x ", buf[j]); - j++; - } - - for ( ; i < 16; i++) { - fprintf (stderr, " "); - } - - fprintf (stderr, " "); - - j = n; - for (i = 0; i < 16; i++) { - if (j >= size) - break; - fprintf (stderr, "%c", isprint(buf[j]) ? buf[j] : '.'); - j++; - } - - fprintf (stderr, "\n"); - - n += 16; - } + int i; + int j; + int n; + const guint8 *buf = (const guint8 *) mem; + + n = 0; + printf ("Dumping %d=0x%x bytes\n", size, size); + while (n < size) + { + + fprintf (stderr, "0x%04x: ", n); + + j = n; + for (i = 0; i < 16; i++) + { + if (j >= size) + break; + fprintf (stderr, "%02x ", buf[j]); + j++; + } + + for (; i < 16; i++) + { + fprintf (stderr, " "); + } + + fprintf (stderr, " "); + + j = n; + for (i = 0; i < 16; i++) + { + if (j >= size) + break; + fprintf (stderr, "%c", isprint(buf[j]) ? buf[j] : '.'); + j++; + } + + fprintf (stderr, "\n"); + + n += 16; + } } #endif static PartitionTable * -part_table_parse_msdos_extended (int fd, guint64 offset, guint64 size, int block_size) +part_table_parse_msdos_extended (int fd, + guint64 offset, + guint64 size, + int block_size) { - int n; - PartitionTable *p; - guint64 next; + int n; + PartitionTable *p; + guint64 next; - DEBUG ("Entering MS-DOS extended parser (offset=%lld, size=%lld)", offset, size); + DEBUG ("Entering MS-DOS extended parser (offset=%lld, size=%lld)", offset, size); - p = NULL; + p = NULL; - next = offset; + next = offset; - while (next != 0) { - guint64 readfrom; - const guint8 embr[512]; + while (next != 0) + { + guint64 readfrom; + const guint8 embr[512]; - readfrom = next; - next = 0; + readfrom = next; + next = 0; - DEBUG ("readfrom = %lld", readfrom); + DEBUG ("readfrom = %lld", readfrom); - if ((guint64) lseek64 (fd, readfrom, SEEK_SET) != readfrom) { - DEBUG ("lseek failed (%s)", strerror (errno)); - goto out; - } - if (read (fd, &embr, sizeof (embr)) != sizeof (embr)) { - DEBUG ("read failed (%s)", strerror (errno)); - goto out; - } - - //hexdump (embr, 512); + if ((guint64) lseek64 (fd, readfrom, SEEK_SET) != readfrom) + { + DEBUG ("lseek failed (%s)", strerror (errno)); + goto out; + } + if (read (fd, &embr, sizeof(embr)) != sizeof(embr)) + { + DEBUG ("read failed (%s)", strerror (errno)); + goto out; + } - if (memcmp (&embr[MSDOS_SIG_OFF], MSDOS_MAGIC, 2) != 0) { - DEBUG ("No MSDOS_MAGIC found"); - goto out; - } + //hexdump (embr, 512); - DEBUG ("MSDOS_MAGIC found"); + if (memcmp (&embr[MSDOS_SIG_OFF], MSDOS_MAGIC, 2) != 0) + { + DEBUG ("No MSDOS_MAGIC found"); + goto out; + } - if (p == NULL) { - p = part_table_new_empty (PART_TYPE_MSDOS_EXTENDED, block_size); - p->offset = offset; - p->size = size; - } + DEBUG ("MSDOS_MAGIC found"); + if (p == NULL) + { + p = part_table_new_empty (PART_TYPE_MSDOS_EXTENDED, block_size); + p->offset = offset; + p->size = size; + } - for (n = 0; n < 2; n++) { - PartitionEntry *pe; - guint64 pstart; - guint64 psize; + for (n = 0; n < 2; n++) + { + PartitionEntry *pe; + guint64 pstart; + guint64 psize; - pstart = block_size * ((guint64) get_le32 (&(embr[MSDOS_PARTTABLE_OFFSET + n * 16 + 8]))); - psize = block_size * ((guint64) get_le32 (&(embr[MSDOS_PARTTABLE_OFFSET + n * 16 + 12]))); + pstart = block_size * ((guint64) get_le32 (&(embr[MSDOS_PARTTABLE_OFFSET + n * 16 + 8]))); + psize = block_size * ((guint64) get_le32 (&(embr[MSDOS_PARTTABLE_OFFSET + n * 16 + 12]))); - if (psize == 0) - continue; + if (psize == 0) + continue; - pe = NULL; + pe = NULL; - if (n == 0) { - //DEBUG ("part %d (offset %lld, size %lld, type 0x%02x)", - // n, readfrom + pstart, psize, ptype)); + if (n == 0) + { + //DEBUG ("part %d (offset %lld, size %lld, type 0x%02x)", + // n, readfrom + pstart, psize, ptype)); - //DEBUG ("pstart = %lld", pstart)); + //DEBUG ("pstart = %lld", pstart)); - //hexdump (&(embr[MSDOS_PARTTABLE_OFFSET + n * 16]), 16); + //hexdump (&(embr[MSDOS_PARTTABLE_OFFSET + n * 16]), 16); - pe = part_entry_new (NULL, - &(embr[MSDOS_PARTTABLE_OFFSET + n * 16]), - 16, - readfrom + MSDOS_PARTTABLE_OFFSET + n * 16); - } else { - if (pstart != 0) { - //DEBUG ("found chain at offset %lld", offset + pstart); - next = offset + pstart; - } - } + pe = part_entry_new (NULL, &(embr[MSDOS_PARTTABLE_OFFSET + n * 16]), 16, readfrom + + MSDOS_PARTTABLE_OFFSET + n * 16); + } + else + { + if (pstart != 0) + { + //DEBUG ("found chain at offset %lld", offset + pstart); + next = offset + pstart; + } + } - //DEBUG ("pe = %p", pe)); + //DEBUG ("pe = %p", pe)); - if (pe != NULL) { - p->entries = g_slist_append (p->entries, pe); - } - } + if (pe != NULL) + { + p->entries = g_slist_append (p->entries, pe); + } + } - } + } -out: - DEBUG ("Exiting MS-DOS extended parser"); - return p; + out: + DEBUG ("Exiting MS-DOS extended parser"); + return p; } static PartitionTable * -part_table_parse_msdos (int fd, guint64 offset, guint64 size, int block_size, gboolean *found_gpt) +part_table_parse_msdos (int fd, + guint64 offset, + guint64 size, + int block_size, + gboolean *found_gpt) { - int n; - const guint8 mbr[512] __attribute__ ((aligned)); - PartitionTable *p; - - DEBUG ("Entering MS-DOS parser (offset=%lld, size=%lld)", offset, size); - - *found_gpt = FALSE; - - p = NULL; - - if (lseek64 (fd, offset, SEEK_SET) < 0) { - DEBUG ("lseek failed (%s)", strerror (errno)); - goto out; - } - if (read (fd, &mbr, sizeof (mbr)) != sizeof (mbr)) { - DEBUG ("read failed (%s)", strerror (errno)); - goto out; - } - - //hexdump (mbr, 512); - - if (memcmp (&mbr[MSDOS_SIG_OFF], MSDOS_MAGIC, 2) != 0) { - DEBUG ("No MSDOS_MAGIC found"); - goto out; - } - - DEBUG ("MSDOS_MAGIC found"); - - /* sanity checks */ - for (n = 0; n < 4; n++) { - if (mbr[MSDOS_PARTTABLE_OFFSET + n * 16 + 0] != 0 && - mbr[MSDOS_PARTTABLE_OFFSET + n * 16 + 0] != 0x80) { - DEBUG ("partitioning flag for part %d is not 0x00 or 0x80", n); - goto out; - } - /* protective MBR for GPT => GPT, not MS-DOS */ - if (mbr[MSDOS_PARTTABLE_OFFSET + n * 16 + 4] == 0xee) { - DEBUG ("found partition type 0xee => protective MBR for GPT"); - *found_gpt = TRUE; - goto out; - } - } - - p = part_table_new_empty (PART_TYPE_MSDOS, block_size); - p->offset = offset; - p->size = size; - - /* we _always_ want to create four partitions */ - for (n = 0; n < 4; n++) { - PartitionEntry *pe; - guint64 pstart; - guint64 psize; - guint8 ptype; - PartitionTable *e_part_table; - - pstart = block_size * ((guint64) get_le32 (&(mbr[MSDOS_PARTTABLE_OFFSET + n * 16 + 8]))); - psize = block_size * ((guint64) get_le32 (&(mbr[MSDOS_PARTTABLE_OFFSET + n * 16 + 12]))); - ptype = mbr[MSDOS_PARTTABLE_OFFSET + n * 16 + 4]; - - DEBUG ("looking at part %d (offset %lld, size %lld, type 0x%02x)", n, pstart, psize, ptype); - - pe = NULL; - e_part_table = NULL; - - /* look for embedded partition tables */ - switch (ptype) { - - /* extended partitions */ - case 0x05: /* MS-DOS */ - case 0x0f: /* Win95 */ - case 0x85: /* Linux */ - e_part_table = part_table_parse_msdos_extended (fd, pstart, psize, block_size); - if (e_part_table != NULL) { - pe = part_entry_new (e_part_table, - &(mbr[MSDOS_PARTTABLE_OFFSET + n * 16]), - 16, - offset + MSDOS_PARTTABLE_OFFSET + n * 16); - } - break; - - case 0xa5: /* FreeBSD */ - case 0xa6: /* OpenBSD */ - case 0xa9: /* NetBSD */ - //e_part_table = part_table_parse_bsd (fd, pstart, psize, block_size); - //break; - - default: - DEBUG ("new part entry"); - pe = part_entry_new (NULL, - &(mbr[MSDOS_PARTTABLE_OFFSET + n * 16]), - 16, - offset + MSDOS_PARTTABLE_OFFSET + n * 16); - break; - } - - //DEBUG ("pe = %p", pe)); - - if (pe != NULL) { - p->entries = g_slist_append (p->entries, pe); - } - } + int n; + const guint8 mbr[512] __attribute__ ((aligned)); + PartitionTable *p; + + DEBUG ("Entering MS-DOS parser (offset=%lld, size=%lld)", offset, size); + + *found_gpt = FALSE; + + p = NULL; + + if (lseek64 (fd, offset, SEEK_SET) < 0) + { + DEBUG ("lseek failed (%s)", strerror (errno)); + goto out; + } + if (read (fd, &mbr, sizeof(mbr)) != sizeof(mbr)) + { + DEBUG ("read failed (%s)", strerror (errno)); + goto out; + } + + //hexdump (mbr, 512); + + if (memcmp (&mbr[MSDOS_SIG_OFF], MSDOS_MAGIC, 2) != 0) + { + DEBUG ("No MSDOS_MAGIC found"); + goto out; + } + + DEBUG ("MSDOS_MAGIC found"); + + /* sanity checks */ + for (n = 0; n < 4; n++) + { + if (mbr[MSDOS_PARTTABLE_OFFSET + n * 16 + 0] != 0 && mbr[MSDOS_PARTTABLE_OFFSET + n * 16 + 0] != 0x80) + { + DEBUG ("partitioning flag for part %d is not 0x00 or 0x80", n); + goto out; + } + /* protective MBR for GPT => GPT, not MS-DOS */ + if (mbr[MSDOS_PARTTABLE_OFFSET + n * 16 + 4] == 0xee) + { + DEBUG ("found partition type 0xee => protective MBR for GPT"); + *found_gpt = TRUE; + goto out; + } + } + + p = part_table_new_empty (PART_TYPE_MSDOS, block_size); + p->offset = offset; + p->size = size; + + /* we _always_ want to create four partitions */ + for (n = 0; n < 4; n++) + { + PartitionEntry *pe; + guint64 pstart; + guint64 psize; + guint8 ptype; + PartitionTable *e_part_table; + + pstart = block_size * ((guint64) get_le32 (&(mbr[MSDOS_PARTTABLE_OFFSET + n * 16 + 8]))); + psize = block_size * ((guint64) get_le32 (&(mbr[MSDOS_PARTTABLE_OFFSET + n * 16 + 12]))); + ptype = mbr[MSDOS_PARTTABLE_OFFSET + n * 16 + 4]; + + DEBUG ("looking at part %d (offset %lld, size %lld, type 0x%02x)", n, pstart, psize, ptype); + + pe = NULL; + e_part_table = NULL; + + /* look for embedded partition tables */ + switch (ptype) + { + + /* extended partitions */ + case 0x05: /* MS-DOS */ + case 0x0f: /* Win95 */ + case 0x85: /* Linux */ + e_part_table = part_table_parse_msdos_extended (fd, pstart, psize, block_size); + if (e_part_table != NULL) + { + pe = part_entry_new (e_part_table, &(mbr[MSDOS_PARTTABLE_OFFSET + n * 16]), 16, offset + + MSDOS_PARTTABLE_OFFSET + n * 16); + } + break; + + case 0xa5: /* FreeBSD */ + case 0xa6: /* OpenBSD */ + case 0xa9: /* NetBSD */ + //e_part_table = part_table_parse_bsd (fd, pstart, psize, block_size); + //break; + + default: + DEBUG ("new part entry"); + pe = part_entry_new (NULL, &(mbr[MSDOS_PARTTABLE_OFFSET + n * 16]), 16, offset + MSDOS_PARTTABLE_OFFSET + n + * 16); + break; + } -out: - DEBUG ("Exiting MS-DOS parser"); - return p; + //DEBUG ("pe = %p", pe)); + + if (pe != NULL) + { + p->entries = g_slist_append (p->entries, pe); + } + } + + out: + DEBUG ("Exiting MS-DOS parser"); + return p; } #define GPT_MAGIC "EFI PART" @@ -632,625 +669,675 @@ out: #define GPT_PART_TYPE_GUID_EMPTY "00000000-0000-0000-0000-000000000000" static PartitionTable * -part_table_parse_gpt (int fd, guint64 offset, guint64 size, int block_size) +part_table_parse_gpt (int fd, + guint64 offset, + guint64 size, + int block_size) { - int n; - PartitionTable *p; - guint8 buf[16]; - guint64 partition_entry_lba; - int num_entries; - int size_of_entry; - - DEBUG ("Entering EFI GPT parser"); - - /* by way of getting here, we've already checked for a protective MBR */ - - p = NULL; - - /* Check GPT signature */ - if (lseek64 (fd, offset + 512 + 0, SEEK_SET) < 0) { - DEBUG ("lseek failed (%s)", strerror (errno)); - goto out; - } - if (read (fd, buf, 8) != 8) { - DEBUG ("read failed (%s)", strerror (errno)); - goto out; - } - if (memcmp (buf, GPT_MAGIC, 8) != 0) { - DEBUG ("No GPT_MAGIC found"); - goto out; - } - - DEBUG ("GPT magic found"); - - /* Disk UUID */ - if (lseek64 (fd, offset + 512 + 56, SEEK_SET) < 0) { - DEBUG ("lseek failed (%s)", strerror (errno)); - goto out; - } - if (read (fd, buf, 16) != 16) { - DEBUG ("read failed (%s)", strerror (errno)); - goto out; - } - //hexdump ((guint8*) buf, 16); - - if (lseek64 (fd, offset + 512 + 72, SEEK_SET) < 0) { - DEBUG ("lseek failed (%s)", strerror (errno)); - goto out; - } - if (read (fd, buf, 8) != 8) { - DEBUG ("read failed (%s)", strerror (errno)); - goto out; - } - partition_entry_lba = get_le64 (buf); - - if (lseek64 (fd, offset + 512 + 80, SEEK_SET) < 0) { - DEBUG ("lseek failed (%s)", strerror (errno)); - goto out; - } - if (read (fd, buf, 4) != 4) { - DEBUG ("read failed (%s)", strerror (errno)); - goto out; - } - num_entries = get_le32 (buf); - - if (lseek64 (fd, offset + 512 + 84, SEEK_SET) < 0) { - DEBUG ("lseek failed (%s)", strerror (errno)); - goto out; - } - if (read (fd, buf, 4) != 4) { - DEBUG ("read failed (%s)", strerror (errno)); - goto out; - } - size_of_entry = get_le32(buf); - - - p = part_table_new_empty (PART_TYPE_GPT, block_size); - p->offset = offset; - p->size = size; - - DEBUG ("partition_entry_lba=%lld", partition_entry_lba); - DEBUG ("num_entries=%d", num_entries); - DEBUG ("size_of_entry=%d", size_of_entry); - - for (n = 0; n < num_entries; n++) { - PartitionEntry *pe; - struct { - guint8 partition_type_guid[16]; - guint8 partition_guid[16]; - guint8 starting_lba[8]; - guint8 ending_lba[8]; - guint8 attributes[8]; - guint8 partition_name[72]; - } gpt_part_entry; - char *partition_type_guid; - - if (lseek64 (fd, offset + partition_entry_lba * 512 + n * size_of_entry, SEEK_SET) < 0) { - DEBUG ("lseek failed (%s)", strerror (errno)); - goto out; - } - if (read (fd, &gpt_part_entry, 128) != 128) { - DEBUG ("read failed (%s)", strerror (errno)); - goto out; - } - - partition_type_guid = get_le_guid (gpt_part_entry.partition_type_guid); - - if (strcmp (partition_type_guid, GPT_PART_TYPE_GUID_EMPTY) == 0) - continue; - - pe = part_entry_new (NULL, - (guint8*) &gpt_part_entry, - 128, - offset + partition_entry_lba * 512 + n * size_of_entry); - p->entries = g_slist_append (p->entries, pe); - - g_free (partition_type_guid); - - //hexdump ((guint8 *) &gpt_part_entry, 128); - - } + int n; + PartitionTable *p; + guint8 buf[16]; + guint64 partition_entry_lba; + int num_entries; + int size_of_entry; + + DEBUG ("Entering EFI GPT parser"); + + /* by way of getting here, we've already checked for a protective MBR */ + + p = NULL; + + /* Check GPT signature */ + if (lseek64 (fd, offset + 512 + 0, SEEK_SET) < 0) + { + DEBUG ("lseek failed (%s)", strerror (errno)); + goto out; + } + if (read (fd, buf, 8) != 8) + { + DEBUG ("read failed (%s)", strerror (errno)); + goto out; + } + if (memcmp (buf, GPT_MAGIC, 8) != 0) + { + DEBUG ("No GPT_MAGIC found"); + goto out; + } + + DEBUG ("GPT magic found"); + + /* Disk UUID */ + if (lseek64 (fd, offset + 512 + 56, SEEK_SET) < 0) + { + DEBUG ("lseek failed (%s)", strerror (errno)); + goto out; + } + if (read (fd, buf, 16) != 16) + { + DEBUG ("read failed (%s)", strerror (errno)); + goto out; + } + //hexdump ((guint8*) buf, 16); + + if (lseek64 (fd, offset + 512 + 72, SEEK_SET) < 0) + { + DEBUG ("lseek failed (%s)", strerror (errno)); + goto out; + } + if (read (fd, buf, 8) != 8) + { + DEBUG ("read failed (%s)", strerror (errno)); + goto out; + } + partition_entry_lba = get_le64 (buf); + + if (lseek64 (fd, offset + 512 + 80, SEEK_SET) < 0) + { + DEBUG ("lseek failed (%s)", strerror (errno)); + goto out; + } + if (read (fd, buf, 4) != 4) + { + DEBUG ("read failed (%s)", strerror (errno)); + goto out; + } + num_entries = get_le32 (buf); + + if (lseek64 (fd, offset + 512 + 84, SEEK_SET) < 0) + { + DEBUG ("lseek failed (%s)", strerror (errno)); + goto out; + } + if (read (fd, buf, 4) != 4) + { + DEBUG ("read failed (%s)", strerror (errno)); + goto out; + } + size_of_entry = get_le32 (buf); + + p = part_table_new_empty (PART_TYPE_GPT, block_size); + p->offset = offset; + p->size = size; + + DEBUG ("partition_entry_lba=%lld", partition_entry_lba); + DEBUG ("num_entries=%d", num_entries); + DEBUG ("size_of_entry=%d", size_of_entry); + + for (n = 0; n < num_entries; n++) + { + PartitionEntry *pe; + struct + { + guint8 partition_type_guid[16]; + guint8 partition_guid[16]; + guint8 starting_lba[8]; + guint8 ending_lba[8]; + guint8 attributes[8]; + guint8 partition_name[72]; + } gpt_part_entry; + char *partition_type_guid; + + if (lseek64 (fd, offset + partition_entry_lba * 512 + n * size_of_entry, SEEK_SET) < 0) + { + DEBUG ("lseek failed (%s)", strerror (errno)); + goto out; + } + if (read (fd, &gpt_part_entry, 128) != 128) + { + DEBUG ("read failed (%s)", strerror (errno)); + goto out; + } + partition_type_guid = get_le_guid (gpt_part_entry.partition_type_guid); -out: - DEBUG ("Leaving EFI GPT parser"); - return p; + if (strcmp (partition_type_guid, GPT_PART_TYPE_GUID_EMPTY) == 0) + continue; + + pe + = part_entry_new (NULL, (guint8*) &gpt_part_entry, 128, offset + partition_entry_lba * 512 + n + * size_of_entry); + p->entries = g_slist_append (p->entries, pe); + + g_free (partition_type_guid); + + //hexdump ((guint8 *) &gpt_part_entry, 128); + + } + + out: + DEBUG ("Leaving EFI GPT parser"); + return p; } #define MAC_MAGIC "ER" #define MAC_PART_MAGIC "PM" static PartitionTable * -part_table_parse_apple (int fd, guint64 offset, guint64 size, int device_block_size) +part_table_parse_apple (int fd, + guint64 offset, + guint64 size, + int device_block_size) { - int n; - PartitionTable *p; - struct { - guint16 signature; - guint16 block_size; - guint32 block_count; - /* more stuff */ - } __attribute__ ((packed)) mac_header; - struct { - guint16 signature; - guint16 res1; - guint32 map_count; - guint32 start_block; - guint32 block_count; - char name[32]; - char type[32]; - guint32 data_start; - guint32 data_count; - guint32 status; - guint32 boot_start; - guint32 boot_size; - guint32 boot_load; - guint32 boot_load2; - guint32 boot_entry; - guint32 boot_entry2; - guint32 boot_cksum; - char processor[16]; /* identifies ISA of boot */ - /* more stuff */ - } __attribute__ ((packed)) mac_part; - int block_size; - int block_count; - int map_count; - - DEBUG ("Entering Apple parser"); - - p = NULL; - - /* Check Mac start of disk signature */ - if (lseek64 (fd, offset + 0, SEEK_SET) < 0) { - DEBUG ("lseek failed (%s)", strerror (errno)); - goto out; - } - if (read (fd, &mac_header, sizeof (mac_header)) != sizeof (mac_header)) { - DEBUG ("read failed (%s)", strerror (errno)); - goto out; - } - if (memcmp (&(mac_header.signature), MAC_MAGIC, 2) != 0) { - DEBUG ("No MAC_MAGIC found"); - goto out; - } - - block_size = GUINT16_FROM_BE (mac_header.block_size); - block_count = GUINT32_FROM_BE (mac_header.block_count); /* num blocks on whole disk */ - - DEBUG ("Mac MAGIC found, block_size=%d", block_size); - - p = part_table_new_empty (PART_TYPE_APPLE, block_size); - p->offset = offset; - p->size = size; - - /* get number of entries from first entry */ - if (lseek64 (fd, offset + block_size, SEEK_SET) < 0) { - DEBUG ("lseek failed (%s)", strerror (errno)); - goto out; - } - if (read (fd, &mac_part, sizeof (mac_part)) != sizeof (mac_part)) { - DEBUG ("read failed (%s)", strerror (errno)); - goto out; - } - map_count = GUINT32_FROM_BE (mac_part.map_count); /* num blocks in part map */ - - DEBUG ("map_count = %d", map_count); - - for (n = 0; n < map_count; n++) { - PartitionEntry *pe; - - if (memcmp (&(mac_part.signature), MAC_PART_MAGIC, 2) != 0) { - DEBUG ("No MAC_PART_MAGIC found"); - break; - } - - if (lseek64 (fd, offset + (n + 1) * block_size, SEEK_SET) < 0) { - DEBUG ("lseek failed (%s)", strerror (errno)); - goto out; - } - if (read (fd, &mac_part, sizeof (mac_part)) != sizeof (mac_part)) { - DEBUG ("read failed (%s)", strerror (errno)); - goto out; - } - - pe = part_entry_new (NULL, - (guint8*) &mac_part, - sizeof (mac_part), - offset + (n + 1) * block_size); - p->entries = g_slist_append (p->entries, pe); - - } + int n; + PartitionTable *p; + struct + { + guint16 signature; + guint16 block_size; + guint32 block_count; + /* more stuff */ + }__attribute__ ((packed)) mac_header; + struct + { + guint16 signature; + guint16 res1; + guint32 map_count; + guint32 start_block; + guint32 block_count; + char name[32]; + char type[32]; + guint32 data_start; + guint32 data_count; + guint32 status; + guint32 boot_start; + guint32 boot_size; + guint32 boot_load; + guint32 boot_load2; + guint32 boot_entry; + guint32 boot_entry2; + guint32 boot_cksum; + char processor[16]; /* identifies ISA of boot */ + /* more stuff */ + }__attribute__ ((packed)) mac_part; + int block_size; + int block_count; + int map_count; + + DEBUG ("Entering Apple parser"); + + p = NULL; + + /* Check Mac start of disk signature */ + if (lseek64 (fd, offset + 0, SEEK_SET) < 0) + { + DEBUG ("lseek failed (%s)", strerror (errno)); + goto out; + } + if (read (fd, &mac_header, sizeof(mac_header)) != sizeof(mac_header)) + { + DEBUG ("read failed (%s)", strerror (errno)); + goto out; + } + if (memcmp (&(mac_header.signature), MAC_MAGIC, 2) != 0) + { + DEBUG ("No MAC_MAGIC found"); + goto out; + } + + block_size = GUINT16_FROM_BE (mac_header.block_size); + block_count = GUINT32_FROM_BE (mac_header.block_count); /* num blocks on whole disk */ + + DEBUG ("Mac MAGIC found, block_size=%d", block_size); + + p = part_table_new_empty (PART_TYPE_APPLE, block_size); + p->offset = offset; + p->size = size; + + /* get number of entries from first entry */ + if (lseek64 (fd, offset + block_size, SEEK_SET) < 0) + { + DEBUG ("lseek failed (%s)", strerror (errno)); + goto out; + } + if (read (fd, &mac_part, sizeof(mac_part)) != sizeof(mac_part)) + { + DEBUG ("read failed (%s)", strerror (errno)); + goto out; + } + map_count = GUINT32_FROM_BE (mac_part.map_count); /* num blocks in part map */ + + DEBUG ("map_count = %d", map_count); + + for (n = 0; n < map_count; n++) + { + PartitionEntry *pe; + + if (memcmp (&(mac_part.signature), MAC_PART_MAGIC, 2) != 0) + { + DEBUG ("No MAC_PART_MAGIC found"); + break; + } -out: - DEBUG ("Leaving Apple parser"); - return p; + if (lseek64 (fd, offset + (n + 1) * block_size, SEEK_SET) < 0) + { + DEBUG ("lseek failed (%s)", strerror (errno)); + goto out; + } + if (read (fd, &mac_part, sizeof(mac_part)) != sizeof(mac_part)) + { + DEBUG ("read failed (%s)", strerror (errno)); + goto out; + } + + pe = part_entry_new (NULL, (guint8*) &mac_part, sizeof(mac_part), offset + (n + 1) * block_size); + p->entries = g_slist_append (p->entries, pe); + + } + + out: + DEBUG ("Leaving Apple parser"); + return p; } static PartitionTable * part_table_load_from_disk_from_file (char *device_file) { - int fd; - PartitionTable *ret; - - ret = NULL; - - fd = open (device_file, O_RDONLY); - if (fd < 0) { - DEBUG ("Cannot open '%s': %m", device_file); - goto out; - } - - ret = part_table_load_from_disk (fd); - close (fd); -out: - return ret; + int fd; + PartitionTable *ret; + + ret = NULL; + + fd = open (device_file, O_RDONLY); + if (fd < 0) + { + DEBUG ("Cannot open '%s': %m", device_file); + goto out; + } + + ret = part_table_load_from_disk (fd); + close (fd); + out: + return ret; } PartitionTable * part_table_load_from_disk (int fd) { - int block_size; - guint64 size; - PartitionTable *p; - gboolean found_gpt; - - p = NULL; - - if (ioctl (fd, BLKGETSIZE64, &size) != 0) { - DEBUG ("Cannot determine size of device"); - goto out; - } - - if (ioctl (fd, BLKSSZGET, &block_size) != 0) { - DEBUG ("Cannot determine block size"); - goto out; - } - - p = part_table_parse_msdos (fd, 0, size, block_size, &found_gpt); - if (p != NULL) { - DEBUG ("MSDOS partition table detected"); - goto out; - } - - if (found_gpt) { - p = part_table_parse_gpt (fd, 0, size, block_size); - if (p != NULL) { - DEBUG ("EFI GPT partition table detected"); - goto out; - } - } - - p = part_table_parse_apple (fd, 0, size, block_size); - if (p != NULL) { - DEBUG ("Apple partition table detected"); - goto out; - } - - DEBUG ("No known partition table found"); - + int block_size; + guint64 size; + PartitionTable *p; + gboolean found_gpt; + + p = NULL; + + if (ioctl (fd, BLKGETSIZE64, &size) != 0) + { + DEBUG ("Cannot determine size of device"); + goto out; + } + + if (ioctl (fd, BLKSSZGET, &block_size) != 0) + { + DEBUG ("Cannot determine block size"); + goto out; + } + + p = part_table_parse_msdos (fd, 0, size, block_size, &found_gpt); + if (p != NULL) + { + DEBUG ("MSDOS partition table detected"); + goto out; + } + + if (found_gpt) + { + p = part_table_parse_gpt (fd, 0, size, block_size); + if (p != NULL) + { + DEBUG ("EFI GPT partition table detected"); + goto out; + } + } -out: - return p; -} + p = part_table_parse_apple (fd, 0, size, block_size); + if (p != NULL) + { + DEBUG ("Apple partition table detected"); + goto out; + } + DEBUG ("No known partition table found"); + out: + return p; +} PartitionScheme part_table_get_scheme (PartitionTable *p) { - return p->scheme; + return p->scheme; } int part_table_get_num_entries (PartitionTable *p) { - return g_slist_length (p->entries); + return g_slist_length (p->entries); } guint64 part_table_get_offset (PartitionTable *p) { - return p->offset; + return p->offset; } guint64 part_table_get_size (PartitionTable *p) { - return p->size; + return p->size; } PartitionTable * -part_table_entry_get_nested (PartitionTable *p, int entry) +part_table_entry_get_nested (PartitionTable *p, + int entry) { - PartitionEntry *pe; + PartitionEntry *pe; - if (p == NULL) - return NULL; + if (p == NULL) + return NULL; - if ((pe = g_slist_nth_data (p->entries, entry)) == NULL) - return NULL; + if ((pe = g_slist_nth_data (p->entries, entry)) == NULL) + return NULL; - if (pe->is_part_table) - return pe->part_table; - else - return NULL; + if (pe->is_part_table) + return pe->part_table; + else + return NULL; } /**************************************************************************/ gboolean -part_table_entry_is_in_use (PartitionTable *p, int entry) +part_table_entry_is_in_use (PartitionTable *p, + int entry) { - gboolean ret; - PartitionEntry *pe; + gboolean ret; + PartitionEntry *pe; - ret = FALSE; + ret = FALSE; - if (p == NULL) - goto out; - - if ((pe = g_slist_nth_data (p->entries, entry)) == NULL) - goto out; - - switch (p->scheme) { - case PART_TYPE_GPT: - ret = TRUE; - break; - case PART_TYPE_MSDOS: - case PART_TYPE_MSDOS_EXTENDED: - if (part_table_entry_get_offset (p, entry) == 0) - ret = FALSE; - else - ret = TRUE; - break; - case PART_TYPE_APPLE: - ret = TRUE; - break; - default: - break; - } -out: - return ret; + if (p == NULL) + goto out; + + if ((pe = g_slist_nth_data (p->entries, entry)) == NULL) + goto out; + + switch (p->scheme) + { + case PART_TYPE_GPT: + ret = TRUE; + break; + case PART_TYPE_MSDOS: + case PART_TYPE_MSDOS_EXTENDED: + if (part_table_entry_get_offset (p, entry) == 0) + ret = FALSE; + else + ret = TRUE; + break; + case PART_TYPE_APPLE: + ret = TRUE; + break; + default: + break; + } + out: + return ret; } char * -part_table_entry_get_type (PartitionTable *p, int entry) +part_table_entry_get_type (PartitionTable *p, + int entry) { - char *s = NULL; - PartitionEntry *pe; - - if (p == NULL) - goto out; - - if ((pe = g_slist_nth_data (p->entries, entry)) == NULL) - goto out; - - switch (p->scheme) { - case PART_TYPE_GPT: - s = get_le_guid (&(pe->data[0])); - break; - case PART_TYPE_MSDOS: - case PART_TYPE_MSDOS_EXTENDED: - s = g_strdup_printf ("0x%02x", pe->data[4]); - break; - case PART_TYPE_APPLE: - s = g_strdup ((char *) pe->data + 2*2 + 3*4 + 32); - g_strchomp (s); - break; - default: - break; - } -out: - if (s != NULL) { - g_strchomp (s); - } - return s; + char *s = NULL; + PartitionEntry *pe; + + if (p == NULL) + goto out; + + if ((pe = g_slist_nth_data (p->entries, entry)) == NULL) + goto out; + + switch (p->scheme) + { + case PART_TYPE_GPT: + s = get_le_guid (&(pe->data[0])); + break; + case PART_TYPE_MSDOS: + case PART_TYPE_MSDOS_EXTENDED: + s = g_strdup_printf ("0x%02x", pe->data[4]); + break; + case PART_TYPE_APPLE: + s = g_strdup ((char *) pe->data + 2 * 2 + 3 * 4 + 32); + g_strchomp (s); + break; + default: + break; + } + out: + if (s != NULL) + { + g_strchomp (s); + } + return s; } char * -part_table_entry_get_uuid (PartitionTable *p, int entry) +part_table_entry_get_uuid (PartitionTable *p, + int entry) { - char *s = NULL; - PartitionEntry *pe; - - if (p == NULL) - goto out; - - if ((pe = g_slist_nth_data (p->entries, entry)) == NULL) - goto out; - - switch (p->scheme) { - case PART_TYPE_GPT: - s = get_le_guid (&(pe->data[16])); - break; - default: - break; - } -out: - if (s != NULL) { - g_strchomp (s); - } - return s; + char *s = NULL; + PartitionEntry *pe; + + if (p == NULL) + goto out; + + if ((pe = g_slist_nth_data (p->entries, entry)) == NULL) + goto out; + + switch (p->scheme) + { + case PART_TYPE_GPT: + s = get_le_guid (&(pe->data[16])); + break; + default: + break; + } + out: + if (s != NULL) + { + g_strchomp (s); + } + return s; } char * -part_table_entry_get_label (PartitionTable *p, int entry) +part_table_entry_get_label (PartitionTable *p, + int entry) { - char *s = NULL; - PartitionEntry *pe; - - if (p == NULL) - goto out; - - if ((pe = g_slist_nth_data (p->entries, entry)) == NULL) - goto out; - - switch (p->scheme) { - case PART_TYPE_GPT: - s = g_utf16_to_utf8 ((const gunichar2 *) &(pe->data[56]), 36, NULL, NULL, NULL); - break; - case PART_TYPE_APPLE: - s = g_strdup ((char *) pe->data + 2*2 + 3*4); - g_strchomp (s); - break; - default: - break; - } -out: - if (s != NULL) { - g_strchomp (s); - } - return s; + char *s = NULL; + PartitionEntry *pe; + + if (p == NULL) + goto out; + + if ((pe = g_slist_nth_data (p->entries, entry)) == NULL) + goto out; + + switch (p->scheme) + { + case PART_TYPE_GPT: + s = g_utf16_to_utf8 ((const gunichar2 *) &(pe->data[56]), 36, NULL, NULL, NULL); + break; + case PART_TYPE_APPLE: + s = g_strdup ((char *) pe->data + 2 * 2 + 3 * 4); + g_strchomp (s); + break; + default: + break; + } + out: + if (s != NULL) + { + g_strchomp (s); + } + return s; } char ** -part_table_entry_get_flags (PartitionTable *p, int entry) +part_table_entry_get_flags (PartitionTable *p, + int entry) { - int n; - char **ss = NULL; - guint32 apm_status; - guint64 gpt_attributes; - PartitionEntry *pe; - - if (p == NULL) - goto out; - - if ((pe = g_slist_nth_data (p->entries, entry)) == NULL) - goto out; - - ss = g_new0 (char*, 6 + 1); /* hard coded to max items we'll return */ - ss[0] = NULL; - n = 0; - - switch (p->scheme) { - case PART_TYPE_GPT: - gpt_attributes = get_le64 (&(pe->data[48])); - - /* From Table 16 of EFI 2.0 spec, bit zero means: - * - * "Required for the platform to function. The system - * cannot function normally if this partition is - * removed. This partition should be considered as - * part of the hardware of the system, and if it is - * removed the system may not boot. It may contain - * diagnostics, recovery tools, or other code or data - * that is critical to the functioning of a system - * independent of any OS." - * - */ - if (gpt_attributes & (1<<0)) { - ss[n++] = g_strdup ("required"); - } - - /* TODO: handle partition type specific attributes - * - * Found on the Internet: "For basic data partitions, the following attribute is - * defined:0x8000000000000000 prevents the partition from having a drive letter automatically - * assigned. By default, each partition is assigned a new drive letter. Setting this - * attribute ensures that when a disk is moved to a new computer, a new drive letter - * will not be automatically generated. Instead, the user can manually assign drive - * letters. Note: Other attributes can be added at any time." - */ - break; - - case PART_TYPE_MSDOS: - case PART_TYPE_MSDOS_EXTENDED: - if (pe->data[0] == 0x80) { - ss[n++] = g_strdup ("boot"); - } - break; - - case PART_TYPE_APPLE: - apm_status = get_be32 (&(pe->data[2*2 + 3*4 + 2*32 + 2*4])); - if (apm_status&(1<<1)) - ss[n++] = g_strdup ("allocated"); - if (apm_status&(1<<2)) - ss[n++] = g_strdup ("in_use"); - if (apm_status&(1<<3)) - ss[n++] = g_strdup ("boot"); - if (apm_status&(1<<4)) - ss[n++] = g_strdup ("allow_read"); - if (apm_status&(1<<5)) - ss[n++] = g_strdup ("allow_write"); - if (apm_status&(1<<6)) - ss[n++] = g_strdup ("boot_code_is_pic"); - break; - default: - break; - } - ss[n] = NULL; + int n; + char **ss = NULL; + guint32 apm_status; + guint64 gpt_attributes; + PartitionEntry *pe; + + if (p == NULL) + goto out; + + if ((pe = g_slist_nth_data (p->entries, entry)) == NULL) + goto out; + + ss = g_new0 (char*, 6 + 1); /* hard coded to max items we'll return */ + ss[0] = NULL; + n = 0; + + switch (p->scheme) + { + case PART_TYPE_GPT: + gpt_attributes = get_le64 (&(pe->data[48])); + + /* From Table 16 of EFI 2.0 spec, bit zero means: + * + * "Required for the platform to function. The system + * cannot function normally if this partition is + * removed. This partition should be considered as + * part of the hardware of the system, and if it is + * removed the system may not boot. It may contain + * diagnostics, recovery tools, or other code or data + * that is critical to the functioning of a system + * independent of any OS." + * + */ + if (gpt_attributes & (1 << 0)) + { + ss[n++] = g_strdup ("required"); + } -out: - return ss; + /* TODO: handle partition type specific attributes + * + * Found on the Internet: "For basic data partitions, the following attribute is + * defined:0x8000000000000000 prevents the partition from having a drive letter automatically + * assigned. By default, each partition is assigned a new drive letter. Setting this + * attribute ensures that when a disk is moved to a new computer, a new drive letter + * will not be automatically generated. Instead, the user can manually assign drive + * letters. Note: Other attributes can be added at any time." + */ + break; + + case PART_TYPE_MSDOS: + case PART_TYPE_MSDOS_EXTENDED: + if (pe->data[0] == 0x80) + { + ss[n++] = g_strdup ("boot"); + } + break; + + case PART_TYPE_APPLE: + apm_status = get_be32 (&(pe->data[2 * 2 + 3 * 4 + 2 * 32 + 2 * 4])); + if (apm_status & (1 << 1)) + ss[n++] = g_strdup ("allocated"); + if (apm_status & (1 << 2)) + ss[n++] = g_strdup ("in_use"); + if (apm_status & (1 << 3)) + ss[n++] = g_strdup ("boot"); + if (apm_status & (1 << 4)) + ss[n++] = g_strdup ("allow_read"); + if (apm_status & (1 << 5)) + ss[n++] = g_strdup ("allow_write"); + if (apm_status & (1 << 6)) + ss[n++] = g_strdup ("boot_code_is_pic"); + break; + default: + break; + } + ss[n] = NULL; + + out: + return ss; } guint64 -part_table_entry_get_offset (PartitionTable *p, int entry) +part_table_entry_get_offset (PartitionTable *p, + int entry) { - guint64 val; - PartitionEntry *pe; - - val = G_MAXUINT64; - if (p == NULL) - goto out; - - if ((pe = g_slist_nth_data (p->entries, entry)) == NULL) - goto out; - - switch (p->scheme) { - case PART_TYPE_GPT: - val = p->block_size * ((guint64) get_le64 (pe->data + 32)); - break; - - case PART_TYPE_MSDOS: - val = p->block_size * ((guint64) get_le32 (pe->data + 8)); - break; - case PART_TYPE_MSDOS_EXTENDED: - /* tricky here.. the offset in the EMBR is from the start of the EMBR and they are - * scattered around the ext partition... Hence, just use the entry's offset and subtract - * it's offset from the EMBR.. - */ - val = p->block_size * ((guint64) get_le32 (pe->data + 8)) + pe->offset - MSDOS_PARTTABLE_OFFSET; - break; - case PART_TYPE_APPLE: - val = p->block_size * ((guint64) get_be32 (pe->data + 2*2 + 1*4)); - break; - default: - break; - } -out: - return val; + guint64 val; + PartitionEntry *pe; + + val = G_MAXUINT64; + if (p == NULL) + goto out; + + if ((pe = g_slist_nth_data (p->entries, entry)) == NULL) + goto out; + + switch (p->scheme) + { + case PART_TYPE_GPT: + val = p->block_size * ((guint64) get_le64 (pe->data + 32)); + break; + + case PART_TYPE_MSDOS: + val = p->block_size * ((guint64) get_le32 (pe->data + 8)); + break; + case PART_TYPE_MSDOS_EXTENDED: + /* tricky here.. the offset in the EMBR is from the start of the EMBR and they are + * scattered around the ext partition... Hence, just use the entry's offset and subtract + * it's offset from the EMBR.. + */ + val = p->block_size * ((guint64) get_le32 (pe->data + 8)) + pe->offset - MSDOS_PARTTABLE_OFFSET; + break; + case PART_TYPE_APPLE: + val = p->block_size * ((guint64) get_be32 (pe->data + 2 * 2 + 1 * 4)); + break; + default: + break; + } + out: + return val; } guint64 -part_table_entry_get_size (PartitionTable *p, int entry) +part_table_entry_get_size (PartitionTable *p, + int entry) { - guint64 val; - PartitionEntry *pe; - - val = G_MAXUINT64; - if (p == NULL) - goto out; - - if ((pe = g_slist_nth_data (p->entries, entry)) == NULL) - goto out; - - switch (p->scheme) { - case PART_TYPE_GPT: - val = p->block_size * (((guint64) get_le64 (pe->data + 40)) - ((guint64) get_le64 (pe->data + 32)) + 1); - break; - case PART_TYPE_MSDOS: - case PART_TYPE_MSDOS_EXTENDED: - val = p->block_size * ((guint64) get_le32 (pe->data + 12)); - break; - case PART_TYPE_APPLE: - val = p->block_size * ((guint64) get_be32 (pe->data + 2*2 + 2*4)); - break; - default: - break; - } -out: - return val; + guint64 val; + PartitionEntry *pe; + + val = G_MAXUINT64; + if (p == NULL) + goto out; + + if ((pe = g_slist_nth_data (p->entries, entry)) == NULL) + goto out; + + switch (p->scheme) + { + case PART_TYPE_GPT: + val = p->block_size * (((guint64) get_le64 (pe->data + 40)) - ((guint64) get_le64 (pe->data + 32)) + 1); + break; + case PART_TYPE_MSDOS: + case PART_TYPE_MSDOS_EXTENDED: + val = p->block_size * ((guint64) get_le32 (pe->data + 12)); + break; + case PART_TYPE_APPLE: + val = p->block_size * ((guint64) get_be32 (pe->data + 2 * 2 + 2 * 4)); + break; + default: + break; + } + out: + return val; } /**************************************************************************/ @@ -1263,646 +1350,790 @@ out: static gboolean part_add_change_partition (char *device_file, - guint64 start, guint64 size, - guint64 new_start, guint64 new_size, - guint64 *out_start, guint64 *out_size, guint *out_num, - char *type, char *label, char **flags, - int geometry_hps, int geometry_spt, + guint64 start, + guint64 size, + guint64 new_start, + guint64 new_size, + guint64 *out_start, + guint64 *out_size, + guint *out_num, + char *type, + char *label, + char **flags, + int geometry_hps, + int geometry_spt, gboolean poke_kernel) { - int n; - gboolean is_change; - gboolean res; - PedDevice *device; - PedDisk *disk; - PedPartition *part; - PedConstraint* constraint; - PedPartitionType ped_type; - guint64 start_sector; - guint64 end_sector; - guint64 new_start_sector; - guint64 new_end_sector; - PartitionScheme scheme; - guint8 mbr_flags = 0; - guint8 mbr_part_type = 0; - char *endp; - guint64 gpt_attributes = 0; - guint32 apm_status = 0; - - res = FALSE; - - is_change = FALSE; - if (size == 0) { - is_change = TRUE; - } - - if (is_change) { - DEBUG ("In part_change_partition: device_file=%s, start=%lld, new_start=%lld, new_size=%lld, type=%s", device_file, start, new_start, new_size, type); - } else { - DEBUG ("In part_add_partition: device_file=%s, start=%lld, size=%lld, type=%s", device_file, start, size, type); - } - - scheme = -1; - if (is_change) { - PartitionTable *p; - PartitionTable *container_p; - int container_entry; - - /* if changing something, make sure the partition to change actually exists */ - - p = part_table_load_from_disk_from_file (device_file); - if (p == NULL) { - DEBUG ("Cannot load partition table from %s", device_file); - goto out; + int n; + gboolean is_change; + gboolean res; + PedDevice *device; + PedDisk *disk; + PedPartition *part; + PedConstraint* constraint; + PedPartitionType ped_type; + guint64 start_sector; + guint64 end_sector; + guint64 new_start_sector; + guint64 new_end_sector; + PartitionScheme scheme; + guint8 mbr_flags = 0; + guint8 mbr_part_type = 0; + char *endp; + guint64 gpt_attributes = 0; + guint32 apm_status = 0; + + res = FALSE; + + is_change = FALSE; + if (size == 0) + { + is_change = TRUE; + } + + if (is_change) + { + DEBUG ("In part_change_partition: device_file=%s, start=%lld, new_start=%lld, new_size=%lld, type=%s", + device_file, + start, + new_start, + new_size, + type); + } + else + { + DEBUG ("In part_add_partition: device_file=%s, start=%lld, size=%lld, type=%s", device_file, start, size, type); + } + + scheme = -1; + if (is_change) + { + PartitionTable *p; + PartitionTable *container_p; + int container_entry; + + /* if changing something, make sure the partition to change actually exists */ + + p = part_table_load_from_disk_from_file (device_file); + if (p == NULL) + { + DEBUG ("Cannot load partition table from %s", device_file); + goto out; + } + part_table_find (p, start + 512, &container_p, &container_entry); + scheme = part_table_get_scheme (container_p); + DEBUG ("containing partition table scheme = %d", scheme); + part_table_free (p); + + if (container_entry < 0) + { + DEBUG ("Couldn't find partition to change"); + goto out; + } + } + else + { + PartitionTable *p; + PartitionTable *container_p; + int container_entry; + + /* if adding, try to find the scheme of the partition table.. don't error out if we can't find it */ + p = part_table_load_from_disk_from_file (device_file); + if (p != NULL) + { + part_table_find (p, start + 512, &container_p, &container_entry); + scheme = part_table_get_scheme (container_p); + DEBUG ("containing partition table scheme = %d", scheme); + part_table_free (p); + } + } + + /* now that we know the partitoning scheme, sanity check type and flags */ + switch (scheme) + { + case -1: + /* unknown partition table format; error out if any type, label or flags are given */ + if ((flags != NULL && flags[0] != NULL)) + { + DEBUG ("unknown partition table format and flags is not empty"); + goto out; + } + + if (type != NULL && strlen (type) > 0) + { + DEBUG ("unknown partition table format and type is not empty"); + goto out; + } + + if (label != NULL && strlen (label) > 0) + { + DEBUG ("unknown partition table format and label is not empty"); + goto out; + } + break; + + case PART_TYPE_MSDOS: + case PART_TYPE_MSDOS_EXTENDED: + mbr_flags = 0; + if (flags != NULL) + { + for (n = 0; flags[n] != NULL; n++) + { + if (strcmp (flags[n], "boot") == 0) + { + mbr_flags |= 0x80; } - part_table_find (p, start + 512, &container_p, &container_entry); - scheme = part_table_get_scheme (container_p); - DEBUG ("containing partition table scheme = %d", scheme); - part_table_free (p); - - if (container_entry < 0) { - DEBUG ("Couldn't find partition to change"); - goto out; - } - } else { - PartitionTable *p; - PartitionTable *container_p; - int container_entry; - - /* if adding, try to find the scheme of the partition table.. don't error out if we can't find it */ - p = part_table_load_from_disk_from_file (device_file); - if (p != NULL) { - part_table_find (p, start + 512, &container_p, &container_entry); - scheme = part_table_get_scheme (container_p); - DEBUG ("containing partition table scheme = %d", scheme); - part_table_free (p); + else + { + DEBUG ("unknown flag '%s'", flags[n]); + goto out; } + } } - /* now that we know the partitoning scheme, sanity check type and flags */ - switch (scheme) { - case -1: - /* unknown partition table format; error out if any type, label or flags are given */ - if ((flags != NULL && flags[0] != NULL)) { - DEBUG ("unknown partition table format and flags is not empty"); - goto out; - } + if (type != NULL) + { + mbr_part_type = (guint8) (strtol (type, &endp, 0)); + if (*endp != '\0') + { + DEBUG ("invalid type '%s' given", type); + goto out; + } + } - if (type != NULL && strlen (type) > 0) { - DEBUG ("unknown partition table format and type is not empty"); - goto out; - } + if (label != NULL) + { + DEBUG ("labeled partitions not supported on MSDOS or MSDOS_EXTENDED"); + goto out; + } - if (label != NULL && strlen (label) > 0) { - DEBUG ("unknown partition table format and label is not empty"); - goto out; + break; + + case PART_TYPE_GPT: + gpt_attributes = 0; + if (flags != NULL) + { + for (n = 0; flags[n] != NULL; n++) + { + if (strcmp (flags[n], "required") == 0) + { + gpt_attributes |= 1; + } + else + { + DEBUG ("unknown flag '%s'", flags[n]); + goto out; + } + } + } + break; + + case PART_TYPE_APPLE: + apm_status = 0; + if (flags != NULL) + { + for (n = 0; flags[n] != NULL; n++) + { + if (strcmp (flags[n], "allocated") == 0) + { + apm_status |= (1 << 1); + } + else if (strcmp (flags[n], "in_use") == 0) + { + apm_status |= (1 << 2); + } + else if (strcmp (flags[n], "boot") == 0) + { + apm_status |= (1 << 3); } - break; - - case PART_TYPE_MSDOS: - case PART_TYPE_MSDOS_EXTENDED: - mbr_flags = 0; - if (flags != NULL) { - for (n = 0; flags[n] != NULL; n++) { - if (strcmp (flags[n], "boot") == 0) { - mbr_flags |= 0x80; - } else { - DEBUG ("unknown flag '%s'", flags[n]); - goto out; - } - } - } - - if (type != NULL) { - mbr_part_type = (guint8) (strtol (type, &endp, 0)); - if (*endp != '\0') { - DEBUG ("invalid type '%s' given", type); - goto out; - } - } - - if (label != NULL) { - DEBUG ("labeled partitions not supported on MSDOS or MSDOS_EXTENDED"); - goto out; - } - - break; - - case PART_TYPE_GPT: - gpt_attributes = 0; - if (flags != NULL) { - for (n = 0; flags[n] != NULL; n++) { - if (strcmp (flags[n], "required") == 0) { - gpt_attributes |= 1; - } else { - DEBUG ("unknown flag '%s'", flags[n]); - goto out; - } - } - } - break; - - case PART_TYPE_APPLE: - apm_status = 0; - if (flags != NULL) { - for (n = 0; flags[n] != NULL; n++) { - if (strcmp (flags[n], "allocated") == 0) { - apm_status |= (1<<1); - } else if (strcmp (flags[n], "in_use") == 0) { - apm_status |= (1<<2); - } else if (strcmp (flags[n], "boot") == 0) { - apm_status |= (1<<3); - } else if (strcmp (flags[n], "allow_read") == 0) { - apm_status |= (1<<4); - } else if (strcmp (flags[n], "allow_write") == 0) { - apm_status |= (1<<5); - } else if (strcmp (flags[n], "boot_code_is_pic") == 0) { - apm_status |= (1<<6); - } else { - DEBUG ("unknown flag '%s'", flags[n]); - goto out; - } - } - } - break; - - default: - DEBUG ("partitioning scheme %d not supported", scheme); - goto out; - } - - switch (scheme) { - case PART_TYPE_MSDOS: - if (mbr_part_type == 0x05 || mbr_part_type == 0x85 || mbr_part_type == 0x0f) { - ped_type = PED_PARTITION_EXTENDED; - } else { - ped_type = PED_PARTITION_NORMAL; - } - break; - - case PART_TYPE_MSDOS_EXTENDED: - ped_type = PED_PARTITION_LOGICAL; - if (mbr_part_type == 0x05 || mbr_part_type == 0x85 || mbr_part_type == 0x0f) { - DEBUG ("Cannot create an extended partition inside an extended partition"); - goto out; - } - break; - - default: - ped_type = PED_PARTITION_NORMAL; - break; - } - - /* now, create the partition */ - - start_sector = start / 512; - end_sector = (start + size) / 512 - 1; - new_start_sector = new_start / 512; - new_end_sector = (new_start + new_size) / 512 - 1; - - device = ped_device_get (device_file); - if (device == NULL) { - DEBUG ("ped_device_get() failed"); - goto out; - } - DEBUG ("got it"); - - /* set drive geometry on libparted object if the user requested it */ - if (geometry_hps > 0 && geometry_spt > 0 ) { - /* not sure this is authorized use of libparted, but, eh, it seems to work */ - device->hw_geom.cylinders = device->bios_geom.cylinders = device->length / geometry_hps / geometry_spt; - device->hw_geom.heads = device->bios_geom.heads = geometry_hps; - device->hw_geom.sectors = device->bios_geom.sectors = geometry_spt; - } - - disk = ped_disk_new (device); - if (disk == NULL) { - DEBUG ("ped_disk_new() failed"); - goto out_ped_device; - } - DEBUG ("got disk"); - - if (!is_change) { - part = ped_partition_new (disk, - ped_type, - NULL, - start_sector, - end_sector); - if (part == NULL) { - DEBUG ("ped_partition_new() failed"); - goto out_ped_disk; - } - DEBUG ("new partition"); - } else { - part = ped_disk_get_partition_by_sector (disk, - start_sector); - if (part == NULL) { - DEBUG ("ped_partition_get_by_sector() failed"); - goto out_ped_disk; - } - DEBUG ("got partition"); - } - - - /* TODO HACK XXX FIXME UGLY BAD: This is super ugly abuse of - * libparted - we poke at their internal data structures - but - * there ain't nothing we can do about it until libparted - * provides API for this... - */ - if (scheme == PART_TYPE_GPT) { - struct { - efi_guid type; - /* more stuff */ - } *gpt_data = (void *) part->disk_specific; - - if (type != NULL) { - if (!set_le_guid ((guint8*) &gpt_data->type, type)) { - DEBUG ("type '%s' for GPT appear to be malformed", type); - goto out_ped_partition; - } - } - - ped_partition_set_flag (part, PED_PARTITION_HIDDEN, (gpt_attributes & 1) != 0); - - } else if (scheme == PART_TYPE_MSDOS || scheme == PART_TYPE_MSDOS_EXTENDED) { - struct { - unsigned char system; - /* more stuff */ - } *dos_data = (void *) part->disk_specific; - - if (type != NULL) { - dos_data->system = mbr_part_type; - } - - ped_partition_set_flag (part, PED_PARTITION_BOOT, (mbr_flags & 0x80) != 0); - - } else if (scheme == PART_TYPE_APPLE) { - struct { - char volume_name[33]; /* eg: "Games" */ - char system_name[33]; /* eg: "Apple_Unix_SVR2" */ - char processor_name[17]; - int is_boot; - int is_driver; - int has_driver; - int is_root; - int is_swap; - int is_lvm; - int is_raid; - PedSector data_region_length; - PedSector boot_region_length; - guint32 boot_base_address; - guint32 boot_entry_address; - guint32 boot_checksum; - guint32 status; - /* more stuff */ - } *mac_data = (void *) part->disk_specific; - - if (type != NULL) { - memset (mac_data->system_name, 0, 33); - strncpy (mac_data->system_name, type, 32); - } - - if (flags != NULL) { - mac_data->status = apm_status; - } - } - - if (label != NULL) { - ped_partition_set_name (part, label); - } - - if (geometry_hps > 0 && geometry_spt > 0 ) { - /* respect drive geometry */ - constraint = ped_constraint_any (device); - } else if (geometry_hps == -1 && geometry_spt == -1 ) { - - /* undocumented (or is it?) libparted usage again.. it appears that - * the probed geometry is stored in hw_geom - */ - device->bios_geom.cylinders = device->hw_geom.cylinders; - device->bios_geom.heads = device->hw_geom.heads; - device->bios_geom.sectors = device->hw_geom.sectors; - - constraint = ped_constraint_any (device); - } else { - PedGeometry *geo_start; - PedGeometry *geo_end; - - /* ignore drive geometry */ - if (is_change) { - geo_start = ped_geometry_new (device, new_start_sector, 1); - geo_end = ped_geometry_new (device, new_end_sector, 1); - } else { - geo_start = ped_geometry_new (device, start_sector, 1); - geo_end = ped_geometry_new (device, end_sector, 1); - } - - constraint = ped_constraint_new (ped_alignment_any, ped_alignment_any, - geo_start, geo_end, 1, device->length); - } - -try_change_again: - if (is_change) { - if (ped_disk_set_partition_geom (disk, - part, - constraint, - new_start_sector, new_end_sector) == 0) { - DEBUG ("ped_disk_set_partition_geom() failed"); - goto out_ped_constraint; - } - } else { - if (ped_disk_add_partition (disk, - part, - constraint) == 0) { - DEBUG ("ped_disk_add_partition() failed"); - goto out_ped_constraint; - } - } - - if (out_start != NULL) - *out_start = part->geom.start * 512; - if (out_size != NULL) - *out_size = part->geom.length * 512; - if (out_num != NULL) - *out_num = part->num; - - if (is_change) { - /* make sure the resulting size is never smaller than requested - * (this is because one will resize the FS and *then* change the partition table) - */ - if (*out_size < new_size) { - DEBUG ("new_size=%lld but resulting size, %lld, smaller than requested", new_size, *out_size); - new_end_sector++; - goto try_change_again; - } else { - DEBUG ("changed partition to start=%lld size=%lld", *out_start, *out_size); - } - } else { - DEBUG ("added partition start=%lld size=%lld", *out_start, *out_size); - } - - - /* hmm, if we don't do this libparted crashes.. I assume that - * ped_disk_add_partition assumes ownership of the - * PedPartition when adding it... sadly this is not documented - * anywhere.. sigh.. - */ - part = NULL; - - if (poke_kernel) { - if (ped_disk_commit (disk) == 0) { - DEBUG ("ped_disk_commit() failed"); - goto out_ped_disk; + else if (strcmp (flags[n], "allow_read") == 0) + { + apm_status |= (1 << 4); } - } else { - if (ped_disk_commit_to_dev (disk) == 0) { - DEBUG ("ped_disk_commit_to_dev() failed"); - goto out_ped_constraint; + else if (strcmp (flags[n], "allow_write") == 0) + { + apm_status |= (1 << 5); } + else if (strcmp (flags[n], "boot_code_is_pic") == 0) + { + apm_status |= (1 << 6); + } + else + { + DEBUG ("unknown flag '%s'", flags[n]); + goto out; + } + } + } + break; + + default: + DEBUG ("partitioning scheme %d not supported", scheme); + goto out; + } + + switch (scheme) + { + case PART_TYPE_MSDOS: + if (mbr_part_type == 0x05 || mbr_part_type == 0x85 || mbr_part_type == 0x0f) + { + ped_type = PED_PARTITION_EXTENDED; + } + else + { + ped_type = PED_PARTITION_NORMAL; + } + break; + + case PART_TYPE_MSDOS_EXTENDED: + ped_type = PED_PARTITION_LOGICAL; + if (mbr_part_type == 0x05 || mbr_part_type == 0x85 || mbr_part_type == 0x0f) + { + DEBUG ("Cannot create an extended partition inside an extended partition"); + goto out; + } + break; + + default: + ped_type = PED_PARTITION_NORMAL; + break; + } + + /* now, create the partition */ + + start_sector = start / 512; + end_sector = (start + size) / 512 - 1; + new_start_sector = new_start / 512; + new_end_sector = (new_start + new_size) / 512 - 1; + + device = ped_device_get (device_file); + if (device == NULL) + { + DEBUG ("ped_device_get() failed"); + goto out; + } + DEBUG ("got it"); + + /* set drive geometry on libparted object if the user requested it */ + if (geometry_hps > 0 && geometry_spt > 0) + { + /* not sure this is authorized use of libparted, but, eh, it seems to work */ + device->hw_geom.cylinders = device->bios_geom.cylinders = device->length / geometry_hps / geometry_spt; + device->hw_geom.heads = device->bios_geom.heads = geometry_hps; + device->hw_geom.sectors = device->bios_geom.sectors = geometry_spt; + } + + disk = ped_disk_new (device); + if (disk == NULL) + { + DEBUG ("ped_disk_new() failed"); + goto out_ped_device; + } + DEBUG ("got disk"); + + if (!is_change) + { + part = ped_partition_new (disk, ped_type, NULL, start_sector, end_sector); + if (part == NULL) + { + DEBUG ("ped_partition_new() failed"); + goto out_ped_disk; + } + DEBUG ("new partition"); + } + else + { + part = ped_disk_get_partition_by_sector (disk, start_sector); + if (part == NULL) + { + DEBUG ("ped_partition_get_by_sector() failed"); + goto out_ped_disk; + } + DEBUG ("got partition"); + } + + /* TODO HACK XXX FIXME UGLY BAD: This is super ugly abuse of + * libparted - we poke at their internal data structures - but + * there ain't nothing we can do about it until libparted + * provides API for this... + */ + if (scheme == PART_TYPE_GPT) + { + struct + { + efi_guid type; + /* more stuff */ + }*gpt_data = (void *) part->disk_specific; + + if (type != NULL) + { + if (!set_le_guid ((guint8*) &gpt_data->type, type)) + { + DEBUG ("type '%s' for GPT appear to be malformed", type); + goto out_ped_partition; + } } - DEBUG ("committed to disk"); - res = TRUE; + ped_partition_set_flag (part, PED_PARTITION_HIDDEN, (gpt_attributes & 1) != 0); - ped_constraint_destroy (constraint); - ped_disk_destroy (disk); - ped_device_destroy (device); - goto out; + } + else if (scheme == PART_TYPE_MSDOS || scheme == PART_TYPE_MSDOS_EXTENDED) + { + struct + { + unsigned char system; + /* more stuff */ + }*dos_data = (void *) part->disk_specific; -out_ped_constraint: - ped_constraint_destroy (constraint); + if (type != NULL) + { + dos_data->system = mbr_part_type; + } -out_ped_partition: - if (part != NULL) { - ped_partition_destroy (part); - } + ped_partition_set_flag (part, PED_PARTITION_BOOT, (mbr_flags & 0x80) != 0); + + } + else if (scheme == PART_TYPE_APPLE) + { + struct + { + char volume_name[33]; /* eg: "Games" */ + char system_name[33]; /* eg: "Apple_Unix_SVR2" */ + char processor_name[17]; + int is_boot; + int is_driver; + int has_driver; + int is_root; + int is_swap; + int is_lvm; + int is_raid; + PedSector data_region_length; + PedSector boot_region_length; + guint32 boot_base_address; + guint32 boot_entry_address; + guint32 boot_checksum; + guint32 status; + /* more stuff */ + }*mac_data = (void *) part->disk_specific; + + if (type != NULL) + { + memset (mac_data->system_name, 0, 33); + strncpy (mac_data->system_name, type, 32); + } -out_ped_disk: - ped_disk_destroy (disk); + if (flags != NULL) + { + mac_data->status = apm_status; + } + } + + if (label != NULL) + { + ped_partition_set_name (part, label); + } + + if (geometry_hps > 0 && geometry_spt > 0) + { + /* respect drive geometry */ + constraint = ped_constraint_any (device); + } + else if (geometry_hps == -1 && geometry_spt == -1) + { + + /* undocumented (or is it?) libparted usage again.. it appears that + * the probed geometry is stored in hw_geom + */ + device->bios_geom.cylinders = device->hw_geom.cylinders; + device->bios_geom.heads = device->hw_geom.heads; + device->bios_geom.sectors = device->hw_geom.sectors; + + constraint = ped_constraint_any (device); + } + else + { + PedGeometry *geo_start; + PedGeometry *geo_end; + + /* ignore drive geometry */ + if (is_change) + { + geo_start = ped_geometry_new (device, new_start_sector, 1); + geo_end = ped_geometry_new (device, new_end_sector, 1); + } + else + { + geo_start = ped_geometry_new (device, start_sector, 1); + geo_end = ped_geometry_new (device, end_sector, 1); + } -out_ped_device: - ped_device_destroy (device); + constraint = ped_constraint_new (ped_alignment_any, ped_alignment_any, geo_start, geo_end, 1, device->length); + } -out: - return res; + try_change_again: + if (is_change) + { + if (ped_disk_set_partition_geom (disk, part, constraint, new_start_sector, new_end_sector) == 0) + { + DEBUG ("ped_disk_set_partition_geom() failed"); + goto out_ped_constraint; + } + } + else + { + if (ped_disk_add_partition (disk, part, constraint) == 0) + { + DEBUG ("ped_disk_add_partition() failed"); + goto out_ped_constraint; + } + } + + if (out_start != NULL) + *out_start = part->geom.start * 512; + if (out_size != NULL) + *out_size = part->geom.length * 512; + if (out_num != NULL) + *out_num = part->num; + + if (is_change) + { + /* make sure the resulting size is never smaller than requested + * (this is because one will resize the FS and *then* change the partition table) + */ + if (*out_size < new_size) + { + DEBUG ("new_size=%lld but resulting size, %lld, smaller than requested", new_size, *out_size); + new_end_sector++; + goto try_change_again; + } + else + { + DEBUG ("changed partition to start=%lld size=%lld", *out_start, *out_size); + } + } + else + { + DEBUG ("added partition start=%lld size=%lld", *out_start, *out_size); + } + + /* hmm, if we don't do this libparted crashes.. I assume that + * ped_disk_add_partition assumes ownership of the + * PedPartition when adding it... sadly this is not documented + * anywhere.. sigh.. + */ + part = NULL; + + if (poke_kernel) + { + if (ped_disk_commit (disk) == 0) + { + DEBUG ("ped_disk_commit() failed"); + goto out_ped_disk; + } + } + else + { + if (ped_disk_commit_to_dev (disk) == 0) + { + DEBUG ("ped_disk_commit_to_dev() failed"); + goto out_ped_constraint; + } + } + DEBUG ("committed to disk"); + + res = TRUE; + + ped_constraint_destroy (constraint); + ped_disk_destroy (disk); + ped_device_destroy (device); + goto out; + + out_ped_constraint: + ped_constraint_destroy (constraint); + + out_ped_partition: + if (part != NULL) + { + ped_partition_destroy (part); + } + + out_ped_disk: + ped_disk_destroy (disk); + + out_ped_device: + ped_device_destroy (device); + + out: + return res; } gboolean part_add_partition (char *device_file, - guint64 start, guint64 size, - guint64 *out_start, guint64 *out_size, guint *out_num, - char *type, char *label, char **flags, - int geometry_hps, int geometry_spt, + guint64 start, + guint64 size, + guint64 *out_start, + guint64 *out_size, + guint *out_num, + char *type, + char *label, + char **flags, + int geometry_hps, + int geometry_spt, gboolean poke_kernel) { - return part_add_change_partition (device_file, - start, size, - 0, 0, - out_start, out_size, out_num, - type, label, flags, - geometry_hps, geometry_spt, - poke_kernel); + return part_add_change_partition (device_file, + start, + size, + 0, + 0, + out_start, + out_size, + out_num, + type, + label, + flags, + geometry_hps, + geometry_spt, + poke_kernel); } gboolean part_change_partition (char *device_file, - guint64 start, - guint64 new_start, guint64 new_size, - guint64 *out_start, guint64 *out_size, - char *type, char *label, char **flags, - int geometry_hps, int geometry_spt) + guint64 start, + guint64 new_start, + guint64 new_size, + guint64 *out_start, + guint64 *out_size, + char *type, + char *label, + char **flags, + int geometry_hps, + int geometry_spt) { - return part_add_change_partition (device_file, - start, 0, - new_start, new_size, - out_start, out_size, NULL, - type, label, flags, - geometry_hps, geometry_spt, - FALSE); + return part_add_change_partition (device_file, + start, + 0, + new_start, + new_size, + out_start, + out_size, + NULL, + type, + label, + flags, + geometry_hps, + geometry_spt, + FALSE); } gboolean -part_del_partition (char *device_file, guint64 offset, gboolean poke_kernel) +part_del_partition (char *device_file, + guint64 offset, + gboolean poke_kernel) { - gboolean ret; - PedDevice *device; - PedDisk *disk; - PedPartition *part; - PartitionTable *p; - gboolean is_extended; - int n; - - DEBUG ("In part_del_partition: device_file=%s, offset=%lld", device_file, offset); - ret = FALSE; - - - /* sigh.. one would think that if you passed the sector of where the - * the beginning of the extended partition starts, then _by_sector - * would return the same as _extended_partition. - * - * Sadly it's not so.. - * - * So, check if the passed offset actually corresponds to a nested - * partition table... - */ - is_extended = FALSE; - p = part_table_load_from_disk_from_file (device_file); - if (p != NULL) { - for (n = 0; n < part_table_get_num_entries (p); n++) { - PartitionTable *nested; - nested = part_table_entry_get_nested (p, n); - if (nested != NULL) { - if (part_table_get_offset (nested) == offset) { - DEBUG ("partition to delete is an extended partition"); - is_extended = TRUE; - } - } + gboolean ret; + PedDevice *device; + PedDisk *disk; + PedPartition *part; + PartitionTable *p; + gboolean is_extended; + int n; + + DEBUG ("In part_del_partition: device_file=%s, offset=%lld", device_file, offset); + ret = FALSE; + + /* sigh.. one would think that if you passed the sector of where the + * the beginning of the extended partition starts, then _by_sector + * would return the same as _extended_partition. + * + * Sadly it's not so.. + * + * So, check if the passed offset actually corresponds to a nested + * partition table... + */ + is_extended = FALSE; + p = part_table_load_from_disk_from_file (device_file); + if (p != NULL) + { + for (n = 0; n < part_table_get_num_entries (p); n++) + { + PartitionTable *nested; + nested = part_table_entry_get_nested (p, n); + if (nested != NULL) + { + if (part_table_get_offset (nested) == offset) + { + DEBUG ("partition to delete is an extended partition"); + is_extended = TRUE; } - part_table_free (p); - } - - device = ped_device_get (device_file); - if (device == NULL) { - DEBUG ("ped_device_get() failed"); - goto out; - } - DEBUG ("got it"); - - disk = ped_disk_new (device); - if (disk == NULL) { - DEBUG ("ped_disk_new() failed"); - goto out_ped_device; - } - DEBUG ("got disk"); - - if (is_extended) { - part = ped_disk_extended_partition (disk); - } else { - part = ped_disk_get_partition_by_sector (disk, offset / 512); - } - - if (part == NULL) { - DEBUG ("ped_disk_get_partition_by_sector() failed"); - goto out_ped_disk; - } - - DEBUG ("got partition - part->type=%d", part->type); - - if (part->type & PED_PARTITION_METADATA) { - DEBUG ("refusing to delete a metadata partition"); - goto out_ped_disk; - } - - if (part->type & PED_PARTITION_PROTECTED) { - DEBUG ("refusing to delete a protected partition"); - goto out_ped_disk; + } } - - if (part->type & PED_PARTITION_FREESPACE) { - DEBUG ("refusing to delete a protected partition"); - goto out_ped_disk; + part_table_free (p); + } + + device = ped_device_get (device_file); + if (device == NULL) + { + DEBUG ("ped_device_get() failed"); + goto out; + } + DEBUG ("got it"); + + disk = ped_disk_new (device); + if (disk == NULL) + { + DEBUG ("ped_disk_new() failed"); + goto out_ped_device; + } + DEBUG ("got disk"); + + if (is_extended) + { + part = ped_disk_extended_partition (disk); + } + else + { + part = ped_disk_get_partition_by_sector (disk, offset / 512); + } + + if (part == NULL) + { + DEBUG ("ped_disk_get_partition_by_sector() failed"); + goto out_ped_disk; + } + + DEBUG ("got partition - part->type=%d", part->type); + + if (part->type & PED_PARTITION_METADATA) + { + DEBUG ("refusing to delete a metadata partition"); + goto out_ped_disk; + } + + if (part->type & PED_PARTITION_PROTECTED) + { + DEBUG ("refusing to delete a protected partition"); + goto out_ped_disk; + } + + if (part->type & PED_PARTITION_FREESPACE) + { + DEBUG ("refusing to delete a protected partition"); + goto out_ped_disk; + } + + if (ped_disk_delete_partition (disk, part) == 0) + { + DEBUG ("ped_disk_delete_partition() failed"); + goto out_ped_disk; + } + + if (poke_kernel) + { + if (ped_disk_commit (disk) == 0) + { + DEBUG ("ped_disk_commit() failed"); + goto out_ped_disk; } - - if (ped_disk_delete_partition (disk, part) == 0) { - DEBUG ("ped_disk_delete_partition() failed"); - goto out_ped_disk; - } - - if (poke_kernel) { - if (ped_disk_commit (disk) == 0) { - DEBUG ("ped_disk_commit() failed"); - goto out_ped_disk; - } - } else { - if (ped_disk_commit_to_dev (disk) == 0) { - DEBUG ("ped_disk_commit_to_dev() failed"); - goto out_ped_disk; - } + } + else + { + if (ped_disk_commit_to_dev (disk) == 0) + { + DEBUG ("ped_disk_commit_to_dev() failed"); + goto out_ped_disk; } - DEBUG ("committed to disk"); + } + DEBUG ("committed to disk"); - ret = TRUE; + ret = TRUE; - ped_disk_destroy (disk); - ped_device_destroy (device); - goto out; + ped_disk_destroy (disk); + ped_device_destroy (device); + goto out; -out_ped_disk: - ped_disk_destroy (disk); + out_ped_disk: + ped_disk_destroy (disk); -out_ped_device: - ped_device_destroy (device); + out_ped_device: + ped_device_destroy (device); -out: - return ret; + out: + return ret; } gboolean -part_create_partition_table (char *device_file, PartitionScheme scheme) +part_create_partition_table (char *device_file, + PartitionScheme scheme) { - PedDevice *device; - PedDisk *disk; - PedDiskType *disk_type; - gboolean ret; - - ret = FALSE; - - DEBUG ("In part_create_partition_table: device_file=%s, scheme=%d", device_file, scheme); - - device = ped_device_get (device_file); - if (device == NULL) { - DEBUG ("ped_device_get() failed"); - goto out; - } - DEBUG ("got it"); - - switch (scheme) { - case PART_TYPE_MSDOS: - disk_type = ped_disk_type_get ("msdos"); - break; - case PART_TYPE_APPLE: - disk_type = ped_disk_type_get ("mac"); - break; - case PART_TYPE_GPT: - disk_type = ped_disk_type_get ("gpt"); - break; - default: - disk_type = NULL; - break; - } - - if (disk_type == NULL) { - DEBUG ("Unknown or unsupported partitioning scheme %d", scheme); - goto out; - } - - disk = ped_disk_new_fresh (device, disk_type); - if (disk == NULL) { - DEBUG ("ped_disk_new_fresh() failed"); - goto out_ped_device; - } - DEBUG ("got disk"); - - if (ped_disk_commit_to_dev (disk) == 0) { - DEBUG ("ped_disk_commit_to_dev() failed"); - goto out_ped_disk; - } - DEBUG ("committed to disk"); - - ret = TRUE; - - ped_disk_destroy (disk); - ped_device_destroy (device); - goto out; - -out_ped_disk: - ped_disk_destroy (disk); - -out_ped_device: - ped_device_destroy (device); - -out: - return ret; + PedDevice *device; + PedDisk *disk; + PedDiskType *disk_type; + gboolean ret; + + ret = FALSE; + + DEBUG ("In part_create_partition_table: device_file=%s, scheme=%d", device_file, scheme); + + device = ped_device_get (device_file); + if (device == NULL) + { + DEBUG ("ped_device_get() failed"); + goto out; + } + DEBUG ("got it"); + + switch (scheme) + { + case PART_TYPE_MSDOS: + disk_type = ped_disk_type_get ("msdos"); + break; + case PART_TYPE_APPLE: + disk_type = ped_disk_type_get ("mac"); + break; + case PART_TYPE_GPT: + disk_type = ped_disk_type_get ("gpt"); + break; + default: + disk_type = NULL; + break; + } + + if (disk_type == NULL) + { + DEBUG ("Unknown or unsupported partitioning scheme %d", scheme); + goto out; + } + + disk = ped_disk_new_fresh (device, disk_type); + if (disk == NULL) + { + DEBUG ("ped_disk_new_fresh() failed"); + goto out_ped_device; + } + DEBUG ("got disk"); + + if (ped_disk_commit_to_dev (disk) == 0) + { + DEBUG ("ped_disk_commit_to_dev() failed"); + goto out_ped_disk; + } + DEBUG ("committed to disk"); + + ret = TRUE; + + ped_disk_destroy (disk); + ped_device_destroy (device); + goto out; + + out_ped_disk: + ped_disk_destroy (disk); + + out_ped_device: + ped_device_destroy (device); + + out: + return ret; } #endif /* USE_PARTED */ diff --git a/src/helpers/partutil.h b/src/helpers/partutil.h index 8444337..cbd8c9b 100644 --- a/src/helpers/partutil.h +++ b/src/helpers/partutil.h @@ -30,12 +30,13 @@ #include /* Partition schemes understood by this library */ -typedef enum { - PART_TYPE_MSDOS = 0, - PART_TYPE_MSDOS_EXTENDED = 1, - PART_TYPE_APPLE = 2, - PART_TYPE_GPT = 3 -} PartitionScheme; +typedef enum + { + PART_TYPE_MSDOS = 0, + PART_TYPE_MSDOS_EXTENDED = 1, + PART_TYPE_APPLE = 2, + PART_TYPE_GPT = 3 + } PartitionScheme; /** * part_get_scheme_name: @@ -50,12 +51,12 @@ typedef enum { * * Returns: Name of scheme or NULL for unknown scheme. Caller shall not free this string. */ -const char *part_get_scheme_name (PartitionScheme scheme); +const char * +part_get_scheme_name (PartitionScheme scheme); struct PartitionTable_s; typedef struct PartitionTable_s PartitionTable; - /** * part_table_load_from_disk: * @fd: a file descriptor for the disk @@ -64,7 +65,8 @@ typedef struct PartitionTable_s PartitionTable; * * Returns: A partition table object. Use part_table_free() to free this object. */ -PartitionTable *part_table_load_from_disk (int fd); +PartitionTable * +part_table_load_from_disk (int fd); /** * part_table_free: @@ -72,7 +74,8 @@ PartitionTable *part_table_load_from_disk (int fd); * * Frees the partition table returned from part_table_load_from_disk(). */ -void part_table_free (PartitionTable *part_table); +void +part_table_free (PartitionTable *part_table); /* partition table inspection */ @@ -80,11 +83,12 @@ void part_table_free (PartitionTable *part_table); * part_table_get_scheme: * @part_table: the partition table * - * Get partitioning scheme. + * Get partitioning scheme. * * Returns: The partitioning scheme. */ -PartitionScheme part_table_get_scheme (PartitionTable *part_table); +PartitionScheme +part_table_get_scheme (PartitionTable *part_table); /** * part_table_get_num_entries: @@ -94,7 +98,8 @@ PartitionScheme part_table_get_scheme (PartitionTable *part_table); * * Returns: Number of entries. */ -int part_table_get_num_entries (PartitionTable *part_table); +int +part_table_get_num_entries (PartitionTable *part_table); /** * part_table_get_offset: @@ -106,7 +111,8 @@ int part_table_get_num_entries (PartitionTable *part_table); * * Returns: offset, from start of disk, in bytes */ -guint64 part_table_get_offset (PartitionTable *part_table); +guint64 +part_table_get_offset (PartitionTable *part_table); /** * part_table_get_size: @@ -118,7 +124,8 @@ guint64 part_table_get_offset (PartitionTable *part_table); * * Returns: size of partition, in bytes */ -guint64 part_table_get_size (PartitionTable *part_table); +guint64 +part_table_get_size (PartitionTable *part_table); /** * part_table_find: @@ -133,18 +140,18 @@ guint64 part_table_get_size (PartitionTable *part_table); * the one passed. If the offset belongs to a primary partition then the * return partition_table will be the same as the passed one. * - * If there is no partition at the given offset (might be free space), + * If there is no partition at the given offset (might be free space), * out_entry will be set to -1. Note that out_part_table will always - * be set though and free space in the primary disk space and the + * be set though and free space in the primary disk space and the * extended partition space differs. * * This is a convenience function. */ -void part_table_find (PartitionTable *part_table, - guint64 offset, - PartitionTable **out_part_table, - int *out_entry); - +void +part_table_find (PartitionTable *part_table, + guint64 offset, + PartitionTable **out_part_table, + int *out_entry); /** * part_table_entry_get_nested: @@ -158,7 +165,9 @@ void part_table_find (PartitionTable *part_table, * Do not free with part_table_free() - the object will be freed when * freeing the root object. */ -PartitionTable *part_table_entry_get_nested (PartitionTable *part_table, int entry); +PartitionTable * +part_table_entry_get_nested (PartitionTable *part_table, + int entry); /** * part_table_entry_is_in_use: @@ -175,7 +184,9 @@ PartitionTable *part_table_entry_get_nested (PartitionTable *part_table, i * * Returns: Whether the partition table entry is in use */ -gboolean part_table_entry_is_in_use (PartitionTable *part_table, int entry); +gboolean +part_table_entry_is_in_use (PartitionTable *part_table, + int entry); /** * part_table_entry_get_type: @@ -193,15 +204,17 @@ gboolean part_table_entry_is_in_use (PartitionTable *part_table, int * For PART_TYPE_GPT, this is the GUID encoded as a string, see * http://en.wikipedia.org/wiki/GUID_Partition_Table for details. * - * For PART_TYPE_APPLE, this is a string as defined in + * For PART_TYPE_APPLE, this is a string as defined in * http://developer.apple.com/documentation/mac/Devices/Devices-126.html. * For FAT file systems, it appears that "DOS_FAT_32", "DOS_FAT_16" and - * "DOS_FAT_12" are also recognized under Mac OS X (I've tested this too) cf. + * "DOS_FAT_12" are also recognized under Mac OS X (I've tested this too) cf. * http://lists.apple.com/archives/Darwin-drivers/2003/May/msg00021.html * * Returns: The partition table type. Caller shall free this with g_free(). */ -char *part_table_entry_get_type (PartitionTable *part_table, int entry); +char * +part_table_entry_get_type (PartitionTable *part_table, + int entry); /** * part_table_entry_get_label: @@ -215,7 +228,9 @@ char *part_table_entry_get_type (PartitionTable *part_table, i * Returns: The label or NULL if the partitioning scheme does not support * labels. Caller shall free this with g_free(). */ -char *part_table_entry_get_label (PartitionTable *part_table, int entry); +char * +part_table_entry_get_label (PartitionTable *part_table, + int entry); /** * part_table_entry_get_uuid: @@ -227,7 +242,9 @@ char *part_table_entry_get_label (PartitionTable *part_table, i * Returns: The UUID or NULL if the partitioning scheme does not support * UUID/GUID. Caller shall free this with g_free(). */ -char *part_table_entry_get_uuid (PartitionTable *part_table, int entry); +char * +part_table_entry_get_uuid (PartitionTable *part_table, + int entry); /** * part_table_entry_get_flags: @@ -238,7 +255,7 @@ char *part_table_entry_get_uuid (PartitionTable *part_table, in * scheme. * * For PART_TYPE_MSDOS and PART_TYPE_MSDOS_EXTENDED the following flags are - * recognized: + * recognized: * - "boot"; meaning that the bootable flag is set. This is used by some * BIOS'es and boot loaders to populate a boot menu. * @@ -263,7 +280,9 @@ char *part_table_entry_get_uuid (PartitionTable *part_table, in * Returns: An array of strings, one per flag, terminated by NULL. Caller * shall free this with g_strfreev(). */ -char **part_table_entry_get_flags (PartitionTable *part_table, int entry); +char ** +part_table_entry_get_flags (PartitionTable *part_table, + int entry); /** * part_table_entry_get_offset: @@ -275,7 +294,9 @@ char **part_table_entry_get_flags (PartitionTable *part_table, i * * Returns: offset, from start of disk, in bytes */ -guint64 part_table_entry_get_offset (PartitionTable *part_table, int entry); +guint64 +part_table_entry_get_offset (PartitionTable *part_table, + int entry); /** * part_table_entry_get_size: @@ -286,8 +307,9 @@ guint64 part_table_entry_get_offset (PartitionTable *part_table, i * * Returns: size of partition, in bytes */ -guint64 part_table_entry_get_size (PartitionTable *part_table, int entry); - +guint64 +part_table_entry_get_size (PartitionTable *part_table, + int entry); /** * part_create_partition_table: @@ -295,11 +317,12 @@ guint64 part_table_entry_get_size (PartitionTable *part_table, i * @scheme: the partitioning scheme * * Create a new fresh partition on a disk. - * + * * Returns: TRUE if the operation was succesful, otherwise FALSE */ -gboolean part_create_partition_table (char *device, PartitionScheme scheme); - +gboolean +part_create_partition_table (char *device, + PartitionScheme scheme); /** * part_add_partition: @@ -316,14 +339,14 @@ gboolean part_create_partition_table (char *device, PartitionScheme * @poke_kernel: whether to update the kernels in-memory representation of * the partition table * - * Adds a new partition to a disk. + * Adds a new partition to a disk. * * If geometry_hps and geomtry_spt are both positive, they will be * used as the geometry of the disk for CHS<->LBA conversions. Notably * this is only applicable for MSDOS / MSDOS_EXTENDED partition * tables. Also, in this case, geometry is enforced to ensure that * partitions start and end at cylinder boundaries. - * + * * If either geometry_hps or geomtry_spt are zero, geometry is * simply ignored and partitions will only be aligned to blocks, e.g. * normally 512 byte boundaries. @@ -356,12 +379,19 @@ gboolean part_create_partition_table (char *device, PartitionScheme * * Returns: TRUE if the operation was succesful, otherwise FALSE */ -gboolean part_add_partition (char *device, - guint64 start, guint64 size, - guint64 *out_start, guint64 *out_size, guint *out_num, - char *type, char *label, char **flags, - int geometry_hps, int geometry_spt, - gboolean poke_kernel); +gboolean +part_add_partition (char *device, + guint64 start, + guint64 size, + guint64 *out_start, + guint64 *out_size, + guint *out_num, + char *type, + char *label, + char **flags, + int geometry_hps, + int geometry_spt, + gboolean poke_kernel); /** * part_change_partition: @@ -378,8 +408,8 @@ gboolean part_add_partition (char *device, * @geometry_spt: sectors-per-track used for LBA<->CHS conversions * * Changes an existing partition table entry on disk. The contents of - * the partition will not be touched. - * + * the partition will not be touched. + * * XXX TODO FIXME: probably be careful with overlapping partitions as * e.g. extended MS-DOS partitions have the partition information just * before the partition data itself. Need to look into this. @@ -407,12 +437,18 @@ gboolean part_add_partition (char *device, * * Returns: TRUE if the operation was succesful, otherwise FALSE */ -gboolean part_change_partition (char *device_file, - guint64 start, - guint64 new_start, guint64 new_size, - guint64 *out_start, guint64 *out_size, - char *type, char *label, char **flags, - int geometry_hps, int geometry_spt); +gboolean +part_change_partition (char *device_file, + guint64 start, + guint64 new_start, + guint64 new_size, + guint64 *out_start, + guint64 *out_size, + char *type, + char *label, + char **flags, + int geometry_hps, + int geometry_spt); /** * part_del_partition: @@ -431,7 +467,9 @@ gboolean part_change_partition (char *device_file, * * Returns: TRUE if the operation was succesful, otherwise FALSE */ -gboolean part_del_partition (char *device, guint64 offset, gboolean poke_kernel); - +gboolean +part_del_partition (char *device, + guint64 offset, + gboolean poke_kernel); #endif /* PARTUTIL_H */ diff --git a/src/inhibitor.c b/src/inhibitor.c index a3147c6..6646a80 100644 --- a/src/inhibitor.c +++ b/src/inhibitor.c @@ -29,15 +29,15 @@ struct InhibitorPrivate { - gchar *unique_dbus_name; - gchar *cookie; + gchar *unique_dbus_name; + gchar *cookie; }; enum -{ - DISCONNECTED_SIGNAL, - LAST_SIGNAL -}; + { + DISCONNECTED_SIGNAL, + LAST_SIGNAL + }; static guint signals[LAST_SIGNAL] = { 0 }; @@ -48,16 +48,16 @@ static GList *inhibitors = NULL; static void inhibitor_finalize (GObject *object) { - Inhibitor *inhibitor; + Inhibitor *inhibitor; - inhibitor = INHIBITOR (object); + inhibitor = INHIBITOR (object); - inhibitors = g_list_remove (inhibitors, inhibitor); + inhibitors = g_list_remove (inhibitors, inhibitor); - g_free (inhibitor->priv->unique_dbus_name); - g_free (inhibitor->priv->cookie); + g_free (inhibitor->priv->unique_dbus_name); + g_free (inhibitor->priv->cookie); - G_OBJECT_CLASS (inhibitor_parent_class)->finalize (object); + G_OBJECT_CLASS (inhibitor_parent_class)->finalize (object); } static void @@ -69,89 +69,98 @@ inhibitor_init (Inhibitor *inhibitor) static void inhibitor_class_init (InhibitorClass *klass) { - GObjectClass *object_class = G_OBJECT_CLASS (klass); + GObjectClass *object_class = G_OBJECT_CLASS (klass); - object_class->finalize = inhibitor_finalize; + object_class->finalize = inhibitor_finalize; - g_type_class_add_private (klass, sizeof (InhibitorPrivate)); + g_type_class_add_private (klass, sizeof(InhibitorPrivate)); - signals[DISCONNECTED_SIGNAL] = - g_signal_new ("disconnected", - G_OBJECT_CLASS_TYPE (klass), - G_SIGNAL_RUN_LAST | G_SIGNAL_DETAILED, - 0, - NULL, NULL, - g_cclosure_marshal_VOID__VOID, - G_TYPE_NONE, 0); + signals[DISCONNECTED_SIGNAL] = g_signal_new ("disconnected", + G_OBJECT_CLASS_TYPE (klass), + G_SIGNAL_RUN_LAST | G_SIGNAL_DETAILED, + 0, + NULL, + NULL, + g_cclosure_marshal_VOID__VOID, + G_TYPE_NONE, + 0); } Inhibitor * inhibitor_new (DBusGMethodInvocation *context) { - Inhibitor *inhibitor; - static gint inhibitor_count = 0; + Inhibitor *inhibitor; + static gint inhibitor_count = 0; - inhibitor = INHIBITOR (g_object_new (TYPE_INHIBITOR, NULL)); + inhibitor = INHIBITOR (g_object_new (TYPE_INHIBITOR, NULL)); - inhibitor->priv->unique_dbus_name = g_strdup (dbus_g_method_get_sender (context)); + inhibitor->priv->unique_dbus_name = g_strdup (dbus_g_method_get_sender (context)); - /* TODO: maybe use a real random number (if it turns out we need this to be cryptographically secure etc.) */ - inhibitor->priv->cookie = g_strdup_printf ("udisks_inhibitor_%d", inhibitor_count++); + /* TODO: maybe use a real random number (if it turns out we need this to be cryptographically secure etc.) */ + inhibitor->priv->cookie = g_strdup_printf ("udisks_inhibitor_%d", inhibitor_count++); - inhibitors = g_list_prepend (inhibitors, inhibitor); + inhibitors = g_list_prepend (inhibitors, inhibitor); - return inhibitor; + return inhibitor; } const gchar * inhibitor_get_unique_dbus_name (Inhibitor *inhibitor) { - return inhibitor->priv->unique_dbus_name; + return inhibitor->priv->unique_dbus_name; } const gchar * inhibitor_get_cookie (Inhibitor *inhibitor) { - return inhibitor->priv->cookie; + return inhibitor->priv->cookie; } - -void inhibitor_name_owner_changed (DBusMessage *message); +void +inhibitor_name_owner_changed (DBusMessage *message); void inhibitor_name_owner_changed (DBusMessage *message) { - if (dbus_message_is_signal (message, DBUS_INTERFACE_DBUS, "NameOwnerChanged")) { - char *name; - char *new_owner; - char *old_owner; - - if (!dbus_message_get_args (message, NULL, - DBUS_TYPE_STRING, &name, - DBUS_TYPE_STRING, &old_owner, - DBUS_TYPE_STRING, &new_owner, - DBUS_TYPE_INVALID)) { - - g_warning ("The NameOwnerChanged signal has the wrong signature."); - goto out; - } + if (dbus_message_is_signal (message, DBUS_INTERFACE_DBUS, "NameOwnerChanged")) + { + char *name; + char *new_owner; + char *old_owner; + + if (!dbus_message_get_args (message, + NULL, + DBUS_TYPE_STRING, + &name, + DBUS_TYPE_STRING, + &old_owner, + DBUS_TYPE_STRING, + &new_owner, + DBUS_TYPE_INVALID)) + { + + g_warning ("The NameOwnerChanged signal has the wrong signature."); + goto out; + } - if (strlen (new_owner) == 0) { - GList *l; + if (strlen (new_owner) == 0) + { + GList *l; - for (l = inhibitors; l != NULL; l = l->next) { - Inhibitor *inhibitor = INHIBITOR (l->data); + for (l = inhibitors; l != NULL; l = l->next) + { + Inhibitor *inhibitor = INHIBITOR (l->data); - //g_debug (" looking at %s", inhibitor->priv->unique_dbus_name); - if (g_strcmp0 (name, inhibitor->priv->unique_dbus_name) == 0) { - g_signal_emit_by_name (inhibitor, "disconnected"); - } - } + //g_debug (" looking at %s", inhibitor->priv->unique_dbus_name); + if (g_strcmp0 (name, inhibitor->priv->unique_dbus_name) == 0) + { + g_signal_emit_by_name (inhibitor, "disconnected"); } + } } + } out: - ; + ; } - diff --git a/src/inhibitor.h b/src/inhibitor.h index 7ac58d4..e2d9803 100644 --- a/src/inhibitor.h +++ b/src/inhibitor.h @@ -34,24 +34,24 @@ G_BEGIN_DECLS #define IS_INHIBITOR_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), TYPE_INHIBITOR)) #define INHIBITOR_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), TYPE_INHIBITOR, InhibitorClass)) -typedef struct InhibitorClass InhibitorClass; +typedef struct InhibitorClass InhibitorClass; typedef struct InhibitorPrivate InhibitorPrivate; struct Inhibitor { - GObject parent; - InhibitorPrivate *priv; + GObject parent; + InhibitorPrivate *priv; }; struct InhibitorClass { - GObjectClass parent_class; + GObjectClass parent_class; }; -GType inhibitor_get_type (void) G_GNUC_CONST; -Inhibitor *inhibitor_new (DBusGMethodInvocation *context); -const gchar *inhibitor_get_unique_dbus_name (Inhibitor *inhibitor); -const gchar *inhibitor_get_cookie (Inhibitor *inhibitor); +GType inhibitor_get_type (void) G_GNUC_CONST; +Inhibitor *inhibitor_new (DBusGMethodInvocation *context); +const gchar *inhibitor_get_unique_dbus_name (Inhibitor *inhibitor); +const gchar *inhibitor_get_cookie (Inhibitor *inhibitor); G_END_DECLS diff --git a/src/main.c b/src/main.c index ad5ab18..66b0d7d 100644 --- a/src/main.c +++ b/src/main.c @@ -45,154 +45,173 @@ #include "poller.h" #include "daemon.h" - #define NAME_TO_CLAIM "org.freedesktop.UDisks" static GMainLoop *loop; static void -name_lost (DBusGProxy *system_bus_proxy, const char *name_which_was_lost, gpointer user_data) +name_lost (DBusGProxy *system_bus_proxy, + const char *name_which_was_lost, + gpointer user_data) { - g_warning ("got NameLost, exiting"); - g_main_loop_quit (loop); + g_warning ("got NameLost, exiting"); + g_main_loop_quit (loop); } static gboolean -acquire_name_on_proxy (DBusGProxy *system_bus_proxy, gboolean replace) +acquire_name_on_proxy (DBusGProxy *system_bus_proxy, + gboolean replace) { - GError *error; - guint result; - gboolean res; - gboolean ret; - guint flags; - - ret = FALSE; - - flags = DBUS_NAME_FLAG_ALLOW_REPLACEMENT; - if (replace) - flags |= DBUS_NAME_FLAG_REPLACE_EXISTING; - - if (system_bus_proxy == NULL) { - goto out; + GError *error; + guint result; + gboolean res; + gboolean ret; + guint flags; + + ret = FALSE; + + flags = DBUS_NAME_FLAG_ALLOW_REPLACEMENT; + if (replace) + flags |= DBUS_NAME_FLAG_REPLACE_EXISTING; + + if (system_bus_proxy == NULL) + { + goto out; + } + + error = NULL; + res = dbus_g_proxy_call (system_bus_proxy, + "RequestName", + &error, + G_TYPE_STRING, + NAME_TO_CLAIM, + G_TYPE_UINT, + flags, + G_TYPE_INVALID, + G_TYPE_UINT, + &result, + G_TYPE_INVALID); + if (!res) + { + if (error != NULL) + { + g_warning ("Failed to acquire %s: %s", NAME_TO_CLAIM, error->message); + g_error_free (error); } - - error = NULL; - res = dbus_g_proxy_call (system_bus_proxy, - "RequestName", - &error, - G_TYPE_STRING, NAME_TO_CLAIM, - G_TYPE_UINT, flags, - G_TYPE_INVALID, - G_TYPE_UINT, &result, - G_TYPE_INVALID); - if (! res) { - if (error != NULL) { - g_warning ("Failed to acquire %s: %s", NAME_TO_CLAIM, error->message); - g_error_free (error); - } else { - g_warning ("Failed to acquire %s", NAME_TO_CLAIM); - } - goto out; - } - - if (result != DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER) { - if (error != NULL) { - g_warning ("Failed to acquire %s: %s", NAME_TO_CLAIM, error->message); - g_error_free (error); - } else { - g_warning ("Failed to acquire %s", NAME_TO_CLAIM); - } - goto out; + else + { + g_warning ("Failed to acquire %s", NAME_TO_CLAIM); + } + goto out; + } + + if (result != DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER) + { + if (error != NULL) + { + g_warning ("Failed to acquire %s: %s", NAME_TO_CLAIM, error->message); + g_error_free (error); + } + else + { + g_warning ("Failed to acquire %s", NAME_TO_CLAIM); } + goto out; + } - dbus_g_proxy_add_signal (system_bus_proxy, "NameLost", G_TYPE_STRING, G_TYPE_INVALID); - dbus_g_proxy_connect_signal (system_bus_proxy, "NameLost", G_CALLBACK (name_lost), NULL, NULL); + dbus_g_proxy_add_signal (system_bus_proxy, "NameLost", G_TYPE_STRING, G_TYPE_INVALID); + dbus_g_proxy_connect_signal (system_bus_proxy, "NameLost", G_CALLBACK (name_lost), NULL, NULL); - ret = TRUE; + ret = TRUE; out: - return ret; + return ret; } int -main (int argc, char **argv) +main (int argc, + char **argv) { - GError *error; - Daemon *daemon; - GOptionContext *context; - DBusGProxy *system_bus_proxy; - DBusGConnection *bus; - int ret; - static gboolean replace; - static GOptionEntry entries [] = { - { "replace", 0, 0, G_OPTION_ARG_NONE, &replace, "Replace existing daemon", NULL }, - { NULL } - }; - - ret = 1; - error = NULL; - - g_type_init (); - - /* fork the polling process early */ - if (!poller_setup (argc, argv)) { - goto out; - } - - /* run with a controlled path */ - if (!g_setenv ("PATH", PACKAGE_LIBEXEC_DIR ":/sbin:/bin:/usr/sbin:/usr/bin", TRUE)) { - g_warning ("Couldn't set PATH"); - goto out; - } + GError *error; + Daemon *daemon; + GOptionContext *context; + DBusGProxy *system_bus_proxy; + DBusGConnection *bus; + int ret; + static gboolean replace; + static GOptionEntry entries[] = + { + { "replace", 0, 0, G_OPTION_ARG_NONE, &replace, "Replace existing daemon", NULL }, + { NULL } }; + + ret = 1; + error = NULL; + + g_type_init (); + + /* fork the polling process early */ + if (!poller_setup (argc, argv)) + { + goto out; + } + + /* run with a controlled path */ + if (!g_setenv ("PATH", PACKAGE_LIBEXEC_DIR ":/sbin:/bin:/usr/sbin:/usr/bin", TRUE)) + { + g_warning ("Couldn't set PATH"); + goto out; + } + + /* avoid gvfs (http://bugzilla.gnome.org/show_bug.cgi?id=526454) */ + if (!g_setenv ("GIO_USE_VFS", "local", TRUE)) + { + g_warning ("Couldn't set GIO_USE_GVFS"); + goto out; + } + + context = g_option_context_new ("udisks storage daemon"); + g_option_context_add_main_entries (context, entries, NULL); + g_option_context_parse (context, &argc, &argv, NULL); + g_option_context_free (context); + + bus = dbus_g_bus_get (DBUS_BUS_SYSTEM, &error); + if (bus == NULL) + { + g_warning ("Couldn't connect to system bus: %s", error->message); + g_error_free (error); + goto out; + } + + system_bus_proxy = dbus_g_proxy_new_for_name (bus, DBUS_SERVICE_DBUS, DBUS_PATH_DBUS, DBUS_INTERFACE_DBUS); + if (system_bus_proxy == NULL) + { + g_warning ("Could not construct system_bus_proxy object; bailing out"); + goto out; + } + + if (!acquire_name_on_proxy (system_bus_proxy, replace)) + { + g_warning ("Could not acquire name; bailing out"); + goto out; + } + + g_debug ("Starting daemon version %s", VERSION); + + daemon = daemon_new (); + + if (daemon == NULL) + { + goto out; + } + + loop = g_main_loop_new (NULL, FALSE); + + g_main_loop_run (loop); + + g_object_unref (daemon); + g_main_loop_unref (loop); + ret = 0; - /* avoid gvfs (http://bugzilla.gnome.org/show_bug.cgi?id=526454) */ - if (!g_setenv ("GIO_USE_VFS", "local", TRUE)) { - g_warning ("Couldn't set GIO_USE_GVFS"); - goto out; - } - - context = g_option_context_new ("udisks storage daemon"); - g_option_context_add_main_entries (context, entries, NULL); - g_option_context_parse (context, &argc, &argv, NULL); - g_option_context_free (context); - - bus = dbus_g_bus_get (DBUS_BUS_SYSTEM, &error); - if (bus == NULL) { - g_warning ("Couldn't connect to system bus: %s", error->message); - g_error_free (error); - goto out; - } - - system_bus_proxy = dbus_g_proxy_new_for_name (bus, - DBUS_SERVICE_DBUS, - DBUS_PATH_DBUS, - DBUS_INTERFACE_DBUS); - if (system_bus_proxy == NULL) { - g_warning ("Could not construct system_bus_proxy object; bailing out"); - goto out; - } - - if (!acquire_name_on_proxy (system_bus_proxy, replace) ) { - g_warning ("Could not acquire name; bailing out"); - goto out; - } - - g_debug ("Starting daemon version %s", VERSION); - - daemon = daemon_new (); - - if (daemon == NULL) { - goto out; - } - - loop = g_main_loop_new (NULL, FALSE); - - g_main_loop_run (loop); - - g_object_unref (daemon); - g_main_loop_unref (loop); - ret = 0; - -out: - return ret; + out: + return ret; } diff --git a/src/mount-file.c b/src/mount-file.c index bf1897d..c1c6dc9 100644 --- a/src/mount-file.c +++ b/src/mount-file.c @@ -44,305 +44,333 @@ #include "device.h" #include "device-private.h" -enum { - MOUNT_FILE_DEVICE_FILE, - MOUNT_FILE_MOUNT_PATH, - MOUNT_FILE_MOUNTED_BY_UID, - MOUNT_FILE_REMOVE_DIR_ON_UNMOUNT, - MOUNT_FILE_NUM_TOKENS, -}; +enum + { + MOUNT_FILE_DEVICE_FILE, + MOUNT_FILE_MOUNT_PATH, + MOUNT_FILE_MOUNTED_BY_UID, + MOUNT_FILE_REMOVE_DIR_ON_UNMOUNT, + MOUNT_FILE_NUM_TOKENS, + }; gboolean mount_file_has_device (const gchar *device_file, - uid_t *mounted_by_uid, - gboolean *remove_dir_on_unmount) + uid_t *mounted_by_uid, + gboolean *remove_dir_on_unmount) { - gboolean ret; - char *contents; - char **lines; - GError *error; - int n; - char *device_file_escaped; - - contents = NULL; - ret = FALSE; - device_file_escaped = g_uri_escape_string (device_file, NULL, TRUE); - - error = NULL; - if (!g_file_get_contents (PACKAGE_LOCALSTATE_DIR "/lib/udisks/mtab", - &contents, - NULL, - &error)) { - /* not having the file is fine */ - if (error->code != G_FILE_ERROR_NOENT) { - g_warning ("Error reading " - PACKAGE_LOCALSTATE_DIR "/lib/udisks/mtab: %s", - error->message); - } - g_error_free (error); - goto out; + gboolean ret; + char *contents; + char **lines; + GError *error; + int n; + char *device_file_escaped; + + contents = NULL; + ret = FALSE; + device_file_escaped = g_uri_escape_string (device_file, NULL, TRUE); + + error = NULL; + if (!g_file_get_contents (PACKAGE_LOCALSTATE_DIR "/lib/udisks/mtab", + &contents, + NULL, + &error)) + { + /* not having the file is fine */ + if (error->code != G_FILE_ERROR_NOENT) + { + g_warning ("Error reading " + PACKAGE_LOCALSTATE_DIR "/lib/udisks/mtab: %s", + error->message); } - - lines = g_strsplit (contents, "\n", 0); - for (n = 0; lines[n] != NULL; n++) { - const char *line = lines[n]; - char **tokens; - - tokens = g_strsplit (line, " ", 0); - if (g_strv_length (tokens) == MOUNT_FILE_NUM_TOKENS) { - const char *line_device_file = tokens[MOUNT_FILE_DEVICE_FILE]; - - if (strcmp (line_device_file, device_file_escaped) == 0) { - - ret = TRUE; - - if (mounted_by_uid != NULL) - *mounted_by_uid = atoi (tokens[MOUNT_FILE_MOUNTED_BY_UID]); - if (remove_dir_on_unmount != NULL) - if (strcmp (tokens[MOUNT_FILE_REMOVE_DIR_ON_UNMOUNT], "1") == 0) - *remove_dir_on_unmount = TRUE; - - g_strfreev (lines); - g_strfreev (tokens); - goto out; - } - } - g_strfreev (tokens); + g_error_free (error); + goto out; + } + + lines = g_strsplit (contents, "\n", 0); + for (n = 0; lines[n] != NULL; n++) + { + const char *line = lines[n]; + char **tokens; + + tokens = g_strsplit (line, " ", 0); + if (g_strv_length (tokens) == MOUNT_FILE_NUM_TOKENS) + { + const char *line_device_file = tokens[MOUNT_FILE_DEVICE_FILE]; + + if (strcmp (line_device_file, device_file_escaped) == 0) + { + ret = TRUE; + + if (mounted_by_uid != NULL) + *mounted_by_uid = atoi (tokens[MOUNT_FILE_MOUNTED_BY_UID]); + if (remove_dir_on_unmount != NULL) + if (strcmp (tokens[MOUNT_FILE_REMOVE_DIR_ON_UNMOUNT], "1") == 0) + *remove_dir_on_unmount = TRUE; + + g_strfreev (lines); + g_strfreev (tokens); + goto out; + } } - g_strfreev (lines); - -out: - g_free (contents); - g_free (device_file_escaped); - return ret; + g_strfreev (tokens); + } + g_strfreev (lines); + + out: + g_free (contents); + g_free (device_file_escaped); + return ret; } void mount_file_add (const gchar *device_file, - const gchar *mount_path, - uid_t mounted_by_uid, - gboolean remove_dir_on_unmount) + const gchar *mount_path, + uid_t mounted_by_uid, + gboolean remove_dir_on_unmount) { - char *contents; - char *new_contents; - char *added_line; - GError *error; - char *device_file_escaped; - char *mount_path_escaped; - - g_return_if_fail (device_file != NULL); - g_return_if_fail (mount_path != NULL); - - /* on error resp. contents and size will be set to resp. NULL and 0 */ - error = NULL; - if (!g_file_get_contents (PACKAGE_LOCALSTATE_DIR "/lib/udisks/mtab", - &contents, - NULL, - &error)) { - /* not having the file is fine */ - if (error->code != G_FILE_ERROR_NOENT) { - g_warning ("Error reading " - PACKAGE_LOCALSTATE_DIR "/lib/udisks/mtab: %s", - error->message); - } - g_error_free (error); + char *contents; + char *new_contents; + char *added_line; + GError *error; + char *device_file_escaped; + char *mount_path_escaped; + + g_return_if_fail (device_file != NULL); + g_return_if_fail (mount_path != NULL); + + /* on error resp. contents and size will be set to resp. NULL and 0 */ + error = NULL; + if (!g_file_get_contents (PACKAGE_LOCALSTATE_DIR "/lib/udisks/mtab", + &contents, + NULL, + &error)) + { + /* not having the file is fine */ + if (error->code != G_FILE_ERROR_NOENT) + { + g_warning ("Error reading " + PACKAGE_LOCALSTATE_DIR "/lib/udisks/mtab: %s", + error->message); } - - device_file_escaped = g_uri_escape_string (device_file, NULL, TRUE); - mount_path_escaped = g_uri_escape_string (mount_path, NULL, TRUE); - added_line = g_strdup_printf ("%s %s %d %d\n", - device_file_escaped, - mount_path_escaped, - mounted_by_uid, - remove_dir_on_unmount); - g_free (device_file_escaped); - g_free (mount_path_escaped); - - if (contents == NULL) { - new_contents = added_line; - } else { - new_contents = g_strconcat (contents, added_line, NULL); - g_free (contents); - g_free (added_line); - } - - error = NULL; - if (!g_file_set_contents (PACKAGE_LOCALSTATE_DIR "/lib/udisks/mtab", - new_contents, - strlen (new_contents), - &error)) { - g_warning ("Error writing " PACKAGE_LOCALSTATE_DIR "/lib/udisks/mtab: %s", error->message); - g_error_free (error); - } - - g_free (new_contents); + g_error_free (error); + } + + device_file_escaped = g_uri_escape_string (device_file, NULL, TRUE); + mount_path_escaped = g_uri_escape_string (mount_path, NULL, TRUE); + added_line = g_strdup_printf ("%s %s %d %d\n", + device_file_escaped, + mount_path_escaped, + mounted_by_uid, + remove_dir_on_unmount); + g_free (device_file_escaped); + g_free (mount_path_escaped); + + if (contents == NULL) + { + new_contents = added_line; + } + else + { + new_contents = g_strconcat (contents, added_line, NULL); + g_free (contents); + g_free (added_line); + } + + error = NULL; + if (!g_file_set_contents (PACKAGE_LOCALSTATE_DIR "/lib/udisks/mtab", + new_contents, + strlen (new_contents), + &error)) + { + g_warning ("Error writing " PACKAGE_LOCALSTATE_DIR "/lib/udisks/mtab: %s", error->message); + g_error_free (error); + } + + g_free (new_contents); } void mount_file_remove (const gchar *device_file, - const gchar *mount_path) + const gchar *mount_path) { - char *contents; - char **lines; - char *new_contents; - GString *str; - GError *error; - char *device_file_escaped; - char *mount_path_escaped; - int n; - - contents = NULL; - new_contents = NULL; - device_file_escaped = NULL; - mount_path_escaped = NULL; - - device_file_escaped = g_uri_escape_string (device_file, NULL, TRUE); - mount_path_escaped = g_uri_escape_string (mount_path, NULL, TRUE); - - error = NULL; - if (!g_file_get_contents (PACKAGE_LOCALSTATE_DIR "/lib/udisks/mtab", - &contents, - NULL, - &error)) { - g_warning ("Error reading " - PACKAGE_LOCALSTATE_DIR "/lib/udisks/mtab: %s", - error->message); - g_error_free (error); - goto out; + char *contents; + char **lines; + char *new_contents; + GString *str; + GError *error; + char *device_file_escaped; + char *mount_path_escaped; + int n; + + contents = NULL; + new_contents = NULL; + device_file_escaped = NULL; + mount_path_escaped = NULL; + + device_file_escaped = g_uri_escape_string (device_file, NULL, TRUE); + mount_path_escaped = g_uri_escape_string (mount_path, NULL, TRUE); + + error = NULL; + if (!g_file_get_contents (PACKAGE_LOCALSTATE_DIR "/lib/udisks/mtab", + &contents, + NULL, + &error)) + { + g_warning ("Error reading " + PACKAGE_LOCALSTATE_DIR "/lib/udisks/mtab: %s", + error->message); + g_error_free (error); + goto out; + } + + str = g_string_new (""); + lines = g_strsplit (contents, "\n", 0); + for (n = 0; lines[n] != NULL; n++) + { + const char *line = lines[n]; + char **tokens; + + tokens = g_strsplit (line, " ", 0); + if (g_strv_length (tokens) == MOUNT_FILE_NUM_TOKENS) + { + const char *line_device_file = tokens[MOUNT_FILE_DEVICE_FILE]; + const char *line_mount_path = tokens[MOUNT_FILE_MOUNT_PATH]; + + if (strcmp (line_device_file, device_file_escaped) == 0 && strcmp (line_mount_path, mount_path_escaped) == 0) + { + /* this is the one... ignore this line and pile on with the others */ + } + else + { + g_string_append_printf (str, "%s\n", line); + } } - - str = g_string_new (""); - lines = g_strsplit (contents, "\n", 0); - for (n = 0; lines[n] != NULL; n++) { - const char *line = lines[n]; - char **tokens; - - tokens = g_strsplit (line, " ", 0); - if (g_strv_length (tokens) == MOUNT_FILE_NUM_TOKENS) { - const char *line_device_file = tokens[MOUNT_FILE_DEVICE_FILE]; - const char *line_mount_path = tokens[MOUNT_FILE_MOUNT_PATH]; - - if (strcmp (line_device_file, device_file_escaped) == 0 && - strcmp (line_mount_path, mount_path_escaped) == 0) { - /* this is the one... ignore this line and pile on with the others */ - } else { - g_string_append_printf (str, "%s\n", line); - } - } - g_strfreev (tokens); - } - g_strfreev (lines); - - new_contents = g_string_free (str, FALSE); - - error = NULL; - if (!g_file_set_contents (PACKAGE_LOCALSTATE_DIR "/lib/udisks/mtab", - new_contents, - strlen (new_contents), - &error)) { - g_warning ("Error writing " PACKAGE_LOCALSTATE_DIR "/lib/udisks/mtab: %s", error->message); - g_error_free (error); - } - -out: - g_free (new_contents); - g_free (contents); - g_free (device_file_escaped); - g_free (mount_path_escaped); + g_strfreev (tokens); + } + g_strfreev (lines); + + new_contents = g_string_free (str, FALSE); + + error = NULL; + if (!g_file_set_contents (PACKAGE_LOCALSTATE_DIR "/lib/udisks/mtab", + new_contents, + strlen (new_contents), + &error)) + { + g_warning ("Error writing " PACKAGE_LOCALSTATE_DIR "/lib/udisks/mtab: %s", error->message); + g_error_free (error); + } + + out: + g_free (new_contents); + g_free (contents); + g_free (device_file_escaped); + g_free (mount_path_escaped); } void mount_file_clean_stale (GList *existing_devices) { - GList *l; - char *contents; - char **lines; - GError *error; - int n; - char *new_contents; - GString *str; - - contents = NULL; - new_contents = NULL; - - error = NULL; - if (!g_file_get_contents (PACKAGE_LOCALSTATE_DIR "/lib/udisks/mtab", - &contents, - NULL, - &error)) { - /* not having the file is fine */ - if (error->code != G_FILE_ERROR_NOENT) { - g_warning ("Error reading " - PACKAGE_LOCALSTATE_DIR "/lib/udisks/mtab: %s", - error->message); - } - g_error_free (error); - goto out; + GList *l; + char *contents; + char **lines; + GError *error; + int n; + char *new_contents; + GString *str; + + contents = NULL; + new_contents = NULL; + + error = NULL; + if (!g_file_get_contents (PACKAGE_LOCALSTATE_DIR "/lib/udisks/mtab", + &contents, + NULL, + &error)) + { + /* not having the file is fine */ + if (error->code != G_FILE_ERROR_NOENT) + { + g_warning ("Error reading " + PACKAGE_LOCALSTATE_DIR "/lib/udisks/mtab: %s", + error->message); } - - str = g_string_new (""); - lines = g_strsplit (contents, "\n", 0); - for (n = 0; lines[n] != NULL; n++) { - const char *line = lines[n]; - char **tokens; - - tokens = g_strsplit (line, " ", 0); - if (g_strv_length (tokens) == MOUNT_FILE_NUM_TOKENS) { - const char *line_mount_path = tokens[MOUNT_FILE_MOUNT_PATH]; - gboolean entry_is_valid; - - entry_is_valid = FALSE; - - for (l = existing_devices; l != NULL && !entry_is_valid; l = l->next) { - Device *device = l->data; - char *mount_path_escaped; - - if (!device->priv->device_is_mounted || - device->priv->device_mount_paths == NULL) - continue; - - mount_path_escaped = g_uri_escape_string (((gchar **) device->priv->device_mount_paths->pdata)[0], NULL, TRUE); - - if (strcmp (line_mount_path, mount_path_escaped) == 0) { - entry_is_valid = TRUE; - } - g_free (mount_path_escaped); - } - - if (entry_is_valid) { - g_string_append_printf (str, "%s\n", line); - } else { - char *line_mount_path_unescaped; - - line_mount_path_unescaped = g_uri_unescape_string (line_mount_path, NULL); - - g_print ("Removing stale mounts entry and directory for '%s'\n", - line_mount_path_unescaped); - - if (g_rmdir (line_mount_path_unescaped) != 0) { - g_warning ("Error removing dir '%s' in stale cleanup: %m", - line_mount_path_unescaped); - } - - } + g_error_free (error); + goto out; + } + + str = g_string_new (""); + lines = g_strsplit (contents, "\n", 0); + for (n = 0; lines[n] != NULL; n++) + { + const char *line = lines[n]; + char **tokens; + + tokens = g_strsplit (line, " ", 0); + if (g_strv_length (tokens) == MOUNT_FILE_NUM_TOKENS) + { + const char *line_mount_path = tokens[MOUNT_FILE_MOUNT_PATH]; + gboolean entry_is_valid; + + entry_is_valid = FALSE; + + for (l = existing_devices; l != NULL && !entry_is_valid; l = l->next) + { + Device *device = l->data; + char *mount_path_escaped; + + if (!device->priv->device_is_mounted || + device->priv->device_mount_paths == NULL) + continue; + + mount_path_escaped = g_uri_escape_string (((gchar **) device->priv->device_mount_paths->pdata)[0], NULL, TRUE); + + if (strcmp (line_mount_path, mount_path_escaped) == 0) + { + entry_is_valid = TRUE; + } + g_free (mount_path_escaped); + } + + if (entry_is_valid) + { + g_string_append_printf (str, "%s\n", line); + } + else + { + char *line_mount_path_unescaped; + + line_mount_path_unescaped = g_uri_unescape_string (line_mount_path, NULL); + + g_print ("Removing stale mounts entry and directory for '%s'\n", + line_mount_path_unescaped); + + if (g_rmdir (line_mount_path_unescaped) != 0) + { + g_warning ("Error removing dir '%s' in stale cleanup: %m", + line_mount_path_unescaped); } - g_strfreev (tokens); - } - g_strfreev (lines); - - new_contents = g_string_free (str, FALSE); - error = NULL; - if (!g_file_set_contents (PACKAGE_LOCALSTATE_DIR "/lib/udisks/mtab", - new_contents, - strlen (new_contents), - &error)) { - g_warning ("Error writing " PACKAGE_LOCALSTATE_DIR "/lib/udisks/mtab: %s", error->message); - g_error_free (error); + } } - -out: - g_free (new_contents); - g_free (contents); + g_strfreev (tokens); + } + g_strfreev (lines); + + new_contents = g_string_free (str, FALSE); + + error = NULL; + if (!g_file_set_contents (PACKAGE_LOCALSTATE_DIR "/lib/udisks/mtab", + new_contents, + strlen (new_contents), + &error)) + { + g_warning ("Error writing " PACKAGE_LOCALSTATE_DIR "/lib/udisks/mtab: %s", error->message); + g_error_free (error); + } + + out: + g_free (new_contents); + g_free (contents); } diff --git a/src/mount-file.h b/src/mount-file.h index 17051ab..cbd8637 100644 --- a/src/mount-file.h +++ b/src/mount-file.h @@ -25,16 +25,16 @@ G_BEGIN_DECLS -gboolean mount_file_has_device (const gchar *device_file, - uid_t *mounted_by_uid, - gboolean *remove_dir_on_unmount); -void mount_file_add (const gchar *device_file, - const gchar *mount_path, - uid_t mounted_by_uid, - gboolean remove_dir_on_unmount); -void mount_file_remove (const gchar *device_file, - const char *mount_path); -void mount_file_clean_stale (GList *existing_devices); +gboolean mount_file_has_device (const gchar *device_file, + uid_t *mounted_by_uid, + gboolean *remove_dir_on_unmount); +void mount_file_add (const gchar *device_file, + const gchar *mount_path, + uid_t mounted_by_uid, + gboolean remove_dir_on_unmount); +void mount_file_remove (const gchar *device_file, + const char *mount_path); +void mount_file_clean_stale (GList *existing_devices); G_END_DECLS diff --git a/src/mount-monitor.c b/src/mount-monitor.c index b436896..d541deb 100644 --- a/src/mount-monitor.c +++ b/src/mount-monitor.c @@ -42,19 +42,19 @@ /*--------------------------------------------------------------------------------------------------------------*/ enum -{ - MOUNT_ADDED_SIGNAL, - MOUNT_REMOVED_SIGNAL, - LAST_SIGNAL, -}; + { + MOUNT_ADDED_SIGNAL, + MOUNT_REMOVED_SIGNAL, + LAST_SIGNAL, + }; static guint signals[LAST_SIGNAL] = { 0 }; struct MountMonitorPrivate { - GIOChannel *mounts_channel; - gboolean have_data; - GList *mounts; + GIOChannel *mounts_channel; + gboolean have_data; + GList *mounts; }; G_DEFINE_TYPE (MountMonitor, mount_monitor, G_TYPE_OBJECT) @@ -64,89 +64,84 @@ static void mount_monitor_ensure (MountMonitor *monitor); static void mount_monitor_finalize (GObject *object) { - MountMonitor *monitor = MOUNT_MONITOR (object); + MountMonitor *monitor = MOUNT_MONITOR (object); - if (monitor->priv->mounts_channel != NULL) - g_io_channel_unref (monitor->priv->mounts_channel); + if (monitor->priv->mounts_channel != NULL) + g_io_channel_unref (monitor->priv->mounts_channel); - g_list_foreach (monitor->priv->mounts, (GFunc) g_object_unref, NULL); - g_list_free (monitor->priv->mounts); + g_list_foreach (monitor->priv->mounts, (GFunc) g_object_unref, NULL); + g_list_free (monitor->priv->mounts); - if (G_OBJECT_CLASS (mount_monitor_parent_class)->finalize != NULL) - (* G_OBJECT_CLASS (mount_monitor_parent_class)->finalize) (object); + if (G_OBJECT_CLASS (mount_monitor_parent_class)->finalize != NULL) + (*G_OBJECT_CLASS (mount_monitor_parent_class)->finalize) (object); } static void mount_monitor_init (MountMonitor *monitor) { - monitor->priv = G_TYPE_INSTANCE_GET_PRIVATE (monitor, - TYPE_MOUNT_MONITOR, - MountMonitorPrivate); + monitor->priv = G_TYPE_INSTANCE_GET_PRIVATE (monitor, TYPE_MOUNT_MONITOR, MountMonitorPrivate); - monitor->priv->mounts = NULL; + monitor->priv->mounts = NULL; } static void mount_monitor_class_init (MountMonitorClass *klass) { - GObjectClass *gobject_class = (GObjectClass *) klass; - - gobject_class->finalize = mount_monitor_finalize; - - g_type_class_add_private (klass, sizeof (MountMonitorPrivate)); - - /** - * MountMonitor::mount-added - * @monitor: A #MountMonitor. - * @mount: The #Mount that was added. - * - * Emitted when a mount is added. - */ - signals[MOUNT_ADDED_SIGNAL] = - g_signal_new ("mount-added", - G_OBJECT_CLASS_TYPE (klass), - G_SIGNAL_RUN_LAST | G_SIGNAL_DETAILED, - G_STRUCT_OFFSET (MountMonitorClass, mount_added), - NULL, - NULL, - g_cclosure_marshal_VOID__OBJECT, - G_TYPE_NONE, - 1, - TYPE_MOUNT); - - /** - * MountMonitor::mount-removed - * @monitor: A #MountMonitor. - * @mount: The #Mount that was removed. - * - * Emitted when a mount is removed. - */ - signals[MOUNT_REMOVED_SIGNAL] = - g_signal_new ("mount-removed", - G_OBJECT_CLASS_TYPE (klass), - G_SIGNAL_RUN_LAST | G_SIGNAL_DETAILED, - G_STRUCT_OFFSET (MountMonitorClass, mount_removed), - NULL, - NULL, - g_cclosure_marshal_VOID__OBJECT, - G_TYPE_NONE, - 1, - TYPE_MOUNT); + GObjectClass *gobject_class = (GObjectClass *) klass; + + gobject_class->finalize = mount_monitor_finalize; + + g_type_class_add_private (klass, sizeof(MountMonitorPrivate)); + + /** + * MountMonitor::mount-added + * @monitor: A #MountMonitor. + * @mount: The #Mount that was added. + * + * Emitted when a mount is added. + */ + signals[MOUNT_ADDED_SIGNAL] = g_signal_new ("mount-added", + G_OBJECT_CLASS_TYPE (klass), + G_SIGNAL_RUN_LAST | G_SIGNAL_DETAILED, + G_STRUCT_OFFSET (MountMonitorClass, mount_added), + NULL, + NULL, + g_cclosure_marshal_VOID__OBJECT, + G_TYPE_NONE, + 1, + TYPE_MOUNT); + + /** + * MountMonitor::mount-removed + * @monitor: A #MountMonitor. + * @mount: The #Mount that was removed. + * + * Emitted when a mount is removed. + */ + signals[MOUNT_REMOVED_SIGNAL] = g_signal_new ("mount-removed", + G_OBJECT_CLASS_TYPE (klass), + G_SIGNAL_RUN_LAST | G_SIGNAL_DETAILED, + G_STRUCT_OFFSET (MountMonitorClass, mount_removed), + NULL, + NULL, + g_cclosure_marshal_VOID__OBJECT, + G_TYPE_NONE, + 1, + TYPE_MOUNT); } static void -diff_sorted_lists (GList *list1, - GList *list2, - GCompareFunc compare, - GList **added, - GList **removed) +diff_sorted_lists (GList *list1, + GList *list2, + GCompareFunc compare, + GList **added, + GList **removed) { int order; *added = *removed = NULL; - while (list1 != NULL && - list2 != NULL) + while (list1 != NULL && list2 != NULL) { order = (*compare) (list1->data, list2->data); if (order < 0) @@ -179,263 +174,274 @@ diff_sorted_lists (GList *list1, } static gboolean -mounts_changed_event (GIOChannel *channel, GIOCondition cond, gpointer user_data) +mounts_changed_event (GIOChannel *channel, + GIOCondition cond, + gpointer user_data) { - MountMonitor *monitor = MOUNT_MONITOR (user_data); - GList *old_mounts; - GList *cur_mounts; - GList *added; - GList *removed; - GList *l; - - if (cond & ~G_IO_ERR) - goto out; + MountMonitor *monitor = MOUNT_MONITOR (user_data); + GList *old_mounts; + GList *cur_mounts; + GList *added; + GList *removed; + GList *l; - g_print ("**** /proc/self/mountinfo changed\n"); + if (cond & ~G_IO_ERR) + goto out; - mount_monitor_ensure (monitor); + g_print ("**** /proc/self/mountinfo changed\n"); - old_mounts = g_list_copy (monitor->priv->mounts); - g_list_foreach (old_mounts, (GFunc) g_object_ref, NULL); + mount_monitor_ensure (monitor); - mount_monitor_invalidate (monitor); - mount_monitor_ensure (monitor); + old_mounts = g_list_copy (monitor->priv->mounts); + g_list_foreach (old_mounts, (GFunc) g_object_ref, NULL); - cur_mounts = g_list_copy (monitor->priv->mounts); + mount_monitor_invalidate (monitor); + mount_monitor_ensure (monitor); - old_mounts = g_list_sort (old_mounts, (GCompareFunc) mount_compare); - cur_mounts = g_list_sort (cur_mounts, (GCompareFunc) mount_compare); + cur_mounts = g_list_copy (monitor->priv->mounts); - diff_sorted_lists (old_mounts, - cur_mounts, - (GCompareFunc) mount_compare, - &added, - &removed); + old_mounts = g_list_sort (old_mounts, (GCompareFunc) mount_compare); + cur_mounts = g_list_sort (cur_mounts, (GCompareFunc) mount_compare); - for (l = removed; l != NULL; l = l->next) { - Mount *mount = MOUNT (l->data); - g_signal_emit (monitor, - signals[MOUNT_REMOVED_SIGNAL], - 0, - mount); - } + diff_sorted_lists (old_mounts, cur_mounts, (GCompareFunc) mount_compare, &added, &removed); - for (l = added; l != NULL; l = l->next) { - Mount *mount = MOUNT (l->data); - g_signal_emit (monitor, - signals[MOUNT_ADDED_SIGNAL], - 0, - mount); - } + for (l = removed; l != NULL; l = l->next) + { + Mount *mount = MOUNT (l->data); + g_signal_emit (monitor, signals[MOUNT_REMOVED_SIGNAL], 0, mount); + } + for (l = added; l != NULL; l = l->next) + { + Mount *mount = MOUNT (l->data); + g_signal_emit (monitor, signals[MOUNT_ADDED_SIGNAL], 0, mount); + } - g_list_foreach (old_mounts, (GFunc) g_object_unref, NULL); - g_list_free (old_mounts); - g_list_free (cur_mounts); - g_list_free (removed); - g_list_free (added); + g_list_foreach (old_mounts, (GFunc) g_object_unref, NULL); + g_list_free (old_mounts); + g_list_free (cur_mounts); + g_list_free (removed); + g_list_free (added); -out: - return TRUE; + out: + return TRUE; } MountMonitor * mount_monitor_new (void) { - MountMonitor *mount_monitor; - GError *error; - - mount_monitor = MOUNT_MONITOR (g_object_new (TYPE_MOUNT_MONITOR, NULL)); - - error = NULL; - mount_monitor->priv->mounts_channel = g_io_channel_new_file ("/proc/self/mountinfo", "r", &error); - if (mount_monitor->priv->mounts_channel != NULL) { - g_io_add_watch (mount_monitor->priv->mounts_channel, G_IO_ERR, mounts_changed_event, mount_monitor); - } else { - g_warning ("No /proc/self/mountinfo file: %s", error->message); - g_error_free (error); - g_object_unref (mount_monitor); - mount_monitor = NULL; - goto out; - } - -out: - return mount_monitor; + MountMonitor *mount_monitor; + GError *error; + + mount_monitor = MOUNT_MONITOR (g_object_new (TYPE_MOUNT_MONITOR, NULL)); + + error = NULL; + mount_monitor->priv->mounts_channel = g_io_channel_new_file ("/proc/self/mountinfo", "r", &error); + if (mount_monitor->priv->mounts_channel != NULL) + { + g_io_add_watch (mount_monitor->priv->mounts_channel, G_IO_ERR, mounts_changed_event, mount_monitor); + } + else + { + g_warning ("No /proc/self/mountinfo file: %s", error->message); + g_error_free (error); + g_object_unref (mount_monitor); + mount_monitor = NULL; + goto out; + } + + out: + return mount_monitor; } void mount_monitor_invalidate (MountMonitor *monitor) { - monitor->priv->have_data = FALSE; + monitor->priv->have_data = FALSE; - g_list_foreach (monitor->priv->mounts, (GFunc) g_object_unref, NULL); - g_list_free (monitor->priv->mounts); - monitor->priv->mounts = NULL; + g_list_foreach (monitor->priv->mounts, (GFunc) g_object_unref, NULL); + g_list_free (monitor->priv->mounts); + monitor->priv->mounts = NULL; } static gboolean have_mount (MountMonitor *monitor, - dev_t dev, - const gchar *mount_point) + dev_t dev, + const gchar *mount_point) { - GList *l; - gboolean ret; + GList *l; + gboolean ret; - ret = FALSE; + ret = FALSE; - for (l = monitor->priv->mounts; l != NULL; l = l->next) { - Mount *mount = MOUNT (l->data); - if (mount_get_dev (mount) == dev && - g_strcmp0 (mount_get_mount_path (mount), mount_point) == 0) { - ret = TRUE; - break; - } + for (l = monitor->priv->mounts; l != NULL; l = l->next) + { + Mount *mount = MOUNT (l->data); + if (mount_get_dev (mount) == dev && g_strcmp0 (mount_get_mount_path (mount), mount_point) == 0) + { + ret = TRUE; + break; } + } - return ret; + return ret; } static void mount_monitor_ensure (MountMonitor *monitor) { - gchar *contents; - gchar **lines; - GError *error; - guint n; - - contents = NULL; - lines = NULL; - - if (monitor->priv->have_data) - goto out; - - error = NULL; - if (!g_file_get_contents ("/proc/self/mountinfo", &contents, NULL, &error)) { - g_warning ("Error reading /proc/self/mountinfo: %s", error->message); - g_error_free (error); - goto out; + gchar *contents; + gchar **lines; + GError *error; + guint n; + + contents = NULL; + lines = NULL; + + if (monitor->priv->have_data) + goto out; + + error = NULL; + if (!g_file_get_contents ("/proc/self/mountinfo", &contents, NULL, &error)) + { + g_warning ("Error reading /proc/self/mountinfo: %s", error->message); + g_error_free (error); + goto out; + } + + /* See Documentation/filesystems/proc.txt for the format of /proc/self/mountinfo + * + * Note that things like space are encoded as \020. + */ + + lines = g_strsplit (contents, "\n", 0); + for (n = 0; lines[n] != NULL; n++) + { + guint mount_id; + guint parent_id; + guint major, minor; + gchar encoded_root[PATH_MAX]; + gchar encoded_mount_point[PATH_MAX]; + gchar *mount_point; + dev_t dev; + + if (strlen (lines[n]) == 0) + continue; + + if (sscanf (lines[n], + "%d %d %d:%d %s %s", + &mount_id, + &parent_id, + &major, + &minor, + encoded_root, + encoded_mount_point) != 6) + { + g_warning ("Error parsing line '%s'", lines[n]); + continue; } - /* See Documentation/filesystems/proc.txt for the format of /proc/self/mountinfo - * - * Note that things like space are encoded as \020. - */ - - lines = g_strsplit (contents, "\n", 0); - for (n = 0; lines[n] != NULL; n++) { - guint mount_id; - guint parent_id; - guint major, minor; - gchar encoded_root[PATH_MAX]; - gchar encoded_mount_point[PATH_MAX]; - gchar *mount_point; - dev_t dev; - - if (strlen (lines[n]) == 0) - continue; - - if (sscanf (lines[n], "%d %d %d:%d %s %s", - &mount_id, - &parent_id, - &major, - &minor, - encoded_root, - encoded_mount_point) != 6) { - g_warning ("Error parsing line '%s'", lines[n]); - continue; + /* ignore mounts where only a subtree of a filesystem is mounted */ + if (g_strcmp0 (encoded_root, "/") != 0) + continue; + + /* Temporary work-around for btrfs, see + * + * https://bugzilla.redhat.com/show_bug.cgi?id=495152#c31 + * http://article.gmane.org/gmane.comp.file-systems.btrfs/2851 + * + * for details. + */ + if (major == 0) + { + const gchar *sep; + sep = strstr (lines[n], " - "); + if (sep != NULL) + { + gchar fstype[PATH_MAX]; + gchar mount_source[PATH_MAX]; + struct stat statbuf; + + if (sscanf (sep + 3, "%s %s", fstype, mount_source) != 2) + { + g_warning ("Error parsing things past - for '%s'", lines[n]); + continue; } - /* ignore mounts where only a subtree of a filesystem is mounted */ - if (g_strcmp0 (encoded_root, "/") != 0) - continue; - - /* Temporary work-around for btrfs, see - * - * https://bugzilla.redhat.com/show_bug.cgi?id=495152#c31 - * http://article.gmane.org/gmane.comp.file-systems.btrfs/2851 - * - * for details. - */ - if (major == 0) { - const gchar *sep; - sep = strstr (lines[n], " - "); - if (sep != NULL) { - gchar fstype[PATH_MAX]; - gchar mount_source[PATH_MAX]; - struct stat statbuf; - - if (sscanf (sep + 3, "%s %s", - fstype, - mount_source) != 2) { - g_warning ("Error parsing things past - for '%s'", lines[n]); - continue; - } - - if (g_strcmp0 (fstype, "btrfs") != 0) - continue; - - if (!g_str_has_prefix (mount_source, "/dev/")) - continue; - - if (stat (mount_source, &statbuf) != 0) { - g_warning ("Error statting %s: %m", mount_source); - continue; - } - - if (!S_ISBLK (statbuf.st_mode)) { - g_warning ("%s is not a block device", mount_source); - continue; - } - - dev = statbuf.st_rdev; - } else { - continue; - } - } else { - dev = makedev (major, minor); - } + if (g_strcmp0 (fstype, "btrfs") != 0) + continue; + + if (!g_str_has_prefix (mount_source, "/dev/")) + continue; - mount_point = g_strcompress (encoded_mount_point); + if (stat (mount_source, &statbuf) != 0) + { + g_warning ("Error statting %s: %m", mount_source); + continue; + } - /* TODO: we can probably use a hash table or something if this turns out to be slow */ - if (!have_mount (monitor, dev, mount_point)) { - Mount *mount; - mount = _mount_new (dev, mount_point); - monitor->priv->mounts = g_list_prepend (monitor->priv->mounts, mount); - //g_debug ("SUP ADDING %d:%d on %s", major, minor, mount_point); + if (!S_ISBLK (statbuf.st_mode)) + { + g_warning ("%s is not a block device", mount_source); + continue; } - g_free (mount_point); + dev = statbuf.st_rdev; + } + else + { + continue; + } + } + else + { + dev = makedev (major, minor); + } + + mount_point = g_strcompress (encoded_mount_point); + + /* TODO: we can probably use a hash table or something if this turns out to be slow */ + if (!have_mount (monitor, dev, mount_point)) + { + Mount *mount; + mount = _mount_new (dev, mount_point); + monitor->priv->mounts = g_list_prepend (monitor->priv->mounts, mount); + //g_debug ("SUP ADDING %d:%d on %s", major, minor, mount_point); } - monitor->priv->have_data = TRUE; + g_free (mount_point); + } -out: - g_free (contents); - g_strfreev (lines); + monitor->priv->have_data = TRUE; + + out: + g_free (contents); + g_strfreev (lines); } GList * mount_monitor_get_mounts_for_dev (MountMonitor *monitor, - dev_t dev) + dev_t dev) { - GList *ret; - GList *l; + GList *ret; + GList *l; - ret = NULL; + ret = NULL; - mount_monitor_ensure (monitor); + mount_monitor_ensure (monitor); - for (l = monitor->priv->mounts; l != NULL; l = l->next) { - Mount *mount = MOUNT (l->data); + for (l = monitor->priv->mounts; l != NULL; l = l->next) + { + Mount *mount = MOUNT (l->data); - if (mount_get_dev (mount) == dev) { - ret = g_list_prepend (ret, g_object_ref (mount)); - } + if (mount_get_dev (mount) == dev) + { + ret = g_list_prepend (ret, g_object_ref (mount)); } + } - /* Sort the list to ensure that shortest mount paths appear first */ - ret = g_list_sort (ret, (GCompareFunc) mount_compare); + /* Sort the list to ensure that shortest mount paths appear first */ + ret = g_list_sort (ret, (GCompareFunc) mount_compare); - return ret; + return ret; } diff --git a/src/mount-monitor.h b/src/mount-monitor.h index 68631d0..c67a5fd 100644 --- a/src/mount-monitor.h +++ b/src/mount-monitor.h @@ -32,34 +32,34 @@ G_BEGIN_DECLS #define IS_MOUNT_MONITOR_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), TYPE_MOUNT_MONITOR)) #define MOUNT_MONITOR_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), TYPE_MOUNT_MONITOR, MountMonitorClass)) -typedef struct MountMonitorClass MountMonitorClass; +typedef struct MountMonitorClass MountMonitorClass; typedef struct MountMonitorPrivate MountMonitorPrivate; struct MountMonitor { - GObject parent; + GObject parent; - /*< private >*/ - MountMonitorPrivate *priv; + /*< private >*/ + MountMonitorPrivate *priv; }; struct MountMonitorClass { - GObjectClass parent_class; + GObjectClass parent_class; - /*< public >*/ - /* signals */ - void (*mount_added) (MountMonitor *monitor, - Mount *mount); - void (*mount_removed) (MountMonitor *monitor, - Mount *mount); + /*< public >*/ + /* signals */ + void (*mount_added) (MountMonitor *monitor, + Mount *mount); + void (*mount_removed) (MountMonitor *monitor, + Mount *mount); }; -GType mount_monitor_get_type (void) G_GNUC_CONST; -MountMonitor *mount_monitor_new (void); -GList *mount_monitor_get_mounts_for_dev (MountMonitor *monitor, - dev_t dev); -void mount_monitor_invalidate (MountMonitor *monitor); +GType mount_monitor_get_type (void) G_GNUC_CONST; +MountMonitor *mount_monitor_new (void); +GList *mount_monitor_get_mounts_for_dev (MountMonitor *monitor, + dev_t dev); +void mount_monitor_invalidate (MountMonitor *monitor); G_END_DECLS diff --git a/src/mount.c b/src/mount.c index d5f43c0..41f0e64 100644 --- a/src/mount.c +++ b/src/mount.c @@ -42,8 +42,8 @@ struct MountPrivate { - gchar *mount_path; - dev_t dev; + gchar *mount_path; + dev_t dev; }; G_DEFINE_TYPE (Mount, mount, G_TYPE_OBJECT) @@ -53,69 +53,69 @@ G_DEFINE_TYPE (Mount, mount, G_TYPE_OBJECT) static void mount_finalize (GObject *object) { - Mount *mount = MOUNT (object); + Mount *mount = MOUNT (object); - g_free (mount->priv->mount_path); + g_free (mount->priv->mount_path); - if (G_OBJECT_CLASS (mount_parent_class)->finalize) - (* G_OBJECT_CLASS (mount_parent_class)->finalize) (object); + if (G_OBJECT_CLASS (mount_parent_class)->finalize) + (* G_OBJECT_CLASS (mount_parent_class)->finalize) (object); } static void mount_init (Mount *mount) { - mount->priv = MOUNT_GET_PRIVATE (mount); + mount->priv = MOUNT_GET_PRIVATE (mount); } static void mount_class_init (MountClass *klass) { - GObjectClass *obj_class = (GObjectClass *) klass; + GObjectClass *obj_class = (GObjectClass *) klass; - obj_class->finalize = mount_finalize; + obj_class->finalize = mount_finalize; - g_type_class_add_private (klass, sizeof (MountPrivate)); + g_type_class_add_private (klass, sizeof(MountPrivate)); } - Mount * -_mount_new (dev_t dev, const gchar *mount_path) +_mount_new (dev_t dev, + const gchar *mount_path) { - Mount *mount; + Mount *mount; - mount = MOUNT (g_object_new (TYPE_MOUNT, NULL)); - mount->priv->dev = dev; - mount->priv->mount_path = g_strdup (mount_path); + mount = MOUNT (g_object_new (TYPE_MOUNT, NULL)); + mount->priv->dev = dev; + mount->priv->mount_path = g_strdup (mount_path); - return mount; + return mount; } const gchar * mount_get_mount_path (Mount *mount) { - g_return_val_if_fail (IS_MOUNT (mount), NULL); - return mount->priv->mount_path; + g_return_val_if_fail (IS_MOUNT (mount), NULL); + return mount->priv->mount_path; } dev_t mount_get_dev (Mount *mount) { - g_return_val_if_fail (IS_MOUNT (mount), 0); - return mount->priv->dev; + g_return_val_if_fail (IS_MOUNT (mount), 0); + return mount->priv->dev; } gint mount_compare (Mount *a, - Mount *b) + Mount *b) { - gint ret; + gint ret; - ret = g_strcmp0 (b->priv->mount_path, a->priv->mount_path); - if (ret != 0) - goto out; + ret = g_strcmp0 (b->priv->mount_path, a->priv->mount_path); + if (ret != 0) + goto out; - ret = (a->priv->dev - b->priv->dev); + ret = (a->priv->dev - b->priv->dev); out: - return ret; + return ret; } diff --git a/src/mount.h b/src/mount.h index 5546e5c..033703c 100644 --- a/src/mount.h +++ b/src/mount.h @@ -34,26 +34,25 @@ G_BEGIN_DECLS #define IS_MOUNT_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), TYPE_MOUNT)) #define MOUNT_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), TYPE_MOUNT, MountClass)) -typedef struct MountClass MountClass; +typedef struct MountClass MountClass; typedef struct MountPrivate MountPrivate; struct Mount { - GObject parent; - MountPrivate *priv; + GObject parent; + MountPrivate *priv; }; struct MountClass { - GObjectClass parent_class; + GObjectClass parent_class; }; -GType mount_get_type (void) G_GNUC_CONST; -const gchar *mount_get_mount_path (Mount *mount); -dev_t mount_get_dev (Mount *mount); +GType mount_get_type (void) G_GNUC_CONST; +const gchar * mount_get_mount_path (Mount *mount); +dev_t mount_get_dev (Mount *mount); -gint mount_compare (Mount *a, - Mount *b); +gint mount_compare (Mount *a, Mount *b); G_END_DECLS diff --git a/src/polkit-action-lookup.c b/src/polkit-action-lookup.c index 7e9db20..d1fea9c 100644 --- a/src/polkit-action-lookup.c +++ b/src/polkit-action-lookup.c @@ -38,32 +38,33 @@ typedef struct _UDisksActionLookupClass UDisksActionLookupClass; struct _UDisksActionLookup { - GObject parent; + GObject parent; }; struct _UDisksActionLookupClass { - GObjectClass parent_class; + GObjectClass parent_class; }; -GType udisks_action_lookup_get_type (void) G_GNUC_CONST; +GType udisks_action_lookup_get_type (void) G_GNUC_CONST; -static void polkit_backend_action_lookup_iface_init (PolkitBackendActionLookupIface *iface); - -#define _G_IMPLEMENT_INTERFACE_DYNAMIC(TYPE_IFACE, iface_init) \ -{ \ - const GInterfaceInfo g_implement_interface_info = { \ - (GInterfaceInitFunc) iface_init, NULL, NULL \ - }; \ - g_type_module_add_interface (type_module, g_define_type_id, TYPE_IFACE, &g_implement_interface_info); \ +static void +polkit_backend_action_lookup_iface_init (PolkitBackendActionLookupIface *iface); + +#define _G_IMPLEMENT_INTERFACE_DYNAMIC(TYPE_IFACE, iface_init) \ + { \ + const GInterfaceInfo g_implement_interface_info = { \ + (GInterfaceInitFunc) iface_init, NULL, NULL \ + }; \ + g_type_module_add_interface (type_module, g_define_type_id, TYPE_IFACE, &g_implement_interface_info); \ } G_DEFINE_DYNAMIC_TYPE_EXTENDED (UDisksActionLookup, - udisks_action_lookup, - G_TYPE_OBJECT, - 0, - _G_IMPLEMENT_INTERFACE_DYNAMIC (POLKIT_BACKEND_TYPE_ACTION_LOOKUP, - polkit_backend_action_lookup_iface_init)) + udisks_action_lookup, + G_TYPE_OBJECT, + 0, + _G_IMPLEMENT_INTERFACE_DYNAMIC (POLKIT_BACKEND_TYPE_ACTION_LOOKUP, + polkit_backend_action_lookup_iface_init)) static void udisks_action_lookup_init (UDisksActionLookup *lookup) @@ -84,189 +85,143 @@ udisks_action_lookup_class_init (UDisksActionLookupClass *klass) typedef struct { - const gchar *name; - const gchar *message; + const gchar *name; + const gchar *message; } Map; -static const Map map[] = { - { - "PartitionDelete", - N_("Authentication is required to delete a partition"), - }, - { - "FilesystemCreate", - N_("Authentication is required to create a filesystem") - }, - { - "PartitionCreate", - N_("Authentication is required to create a partition") - }, - { - "PartitionModify", - N_("Authentication is required to modify a partition") - }, - { - "PartitionTableCreate", - N_("Authentication is required to create a partition table") - }, - { - "FilesystemSetLabel", - N_("Authentication is required to set the file system label") - }, - { - "LinuxMdStop", - N_("Authentication is required to stop a Software RAID device") - }, - { - "LinuxMdCheck", - N_("Authentication is required to check a Software RAID device") - }, - { - "LinuxMdRepair", - N_("Authentication is required to repair a Software RAID device") - }, - { - "LinuxMdAddComponent", - N_("Authentication is required to add a new component to a Software RAID device") - }, - { - "LinuxMdRemoveComponent", - N_("Authentication is required to remove a component from a Software RAID device") - }, - { - "LinuxMdStart", - N_("Authentication is required to start a Software RAID device") - }, - { - "LinuxMdCreate", - N_("Authentication is required to create a Software RAID device") - }, - { - "DriveInhibitPolling", - N_("Authentication is required to inhibit polling on a drive") - }, - { - "DrivePollMedia", - N_("Authentication is required to poll for media") - }, - { - "InhibitAllPolling", - N_("Authentication is required to inhibit all drive polling") - }, - { - NULL, - NULL, - } -}; - +static const Map map[] = + { + { "PartitionDelete", N_ ("Authentication is required to delete a partition"), }, + { "FilesystemCreate", N_ ("Authentication is required to create a filesystem") }, + { "PartitionCreate", N_ ("Authentication is required to create a partition") }, + { "PartitionModify", N_ ("Authentication is required to modify a partition") }, + { "PartitionTableCreate", N_ ("Authentication is required to create a partition table") }, + { "FilesystemSetLabel", N_ ("Authentication is required to set the file system label") }, + { "LinuxMdStop", N_ ("Authentication is required to stop a Software RAID device") }, + { "LinuxMdCheck", N_ ("Authentication is required to check a Software RAID device") }, + { "LinuxMdRepair", N_ ("Authentication is required to repair a Software RAID device") }, + { "LinuxMdAddComponent", N_ ("Authentication is required to add a new component to a Software RAID device") }, + { "LinuxMdRemoveComponent", N_ ("Authentication is required to remove a component from a Software RAID device") }, + { "LinuxMdStart", N_ ("Authentication is required to start a Software RAID device") }, + { "LinuxMdCreate", N_ ("Authentication is required to create a Software RAID device") }, + { "DriveInhibitPolling", N_ ("Authentication is required to inhibit polling on a drive") }, + { "DrivePollMedia", N_ ("Authentication is required to poll for media") }, + { "InhibitAllPolling", N_ ("Authentication is required to inhibit all drive polling") }, + { NULL, NULL, } + }; static gchar * -udisks_action_lookup_get_message (PolkitBackendActionLookup *lookup, - const gchar *action_id, - PolkitDetails *details, - PolkitActionDescription *action_description) +udisks_action_lookup_get_message (PolkitBackendActionLookup *lookup, + const gchar *action_id, + PolkitDetails *details, + PolkitActionDescription *action_description) { - const gchar *operation; - gchar *ret; - guint n; + const gchar *operation; + gchar *ret; + guint n; - ret = NULL; + ret = NULL; - if (!g_str_has_prefix (action_id, "org.freedesktop.devicekit.disks.")) - goto out; + if (!g_str_has_prefix (action_id, "org.freedesktop.devicekit.disks.")) + goto out; - operation = polkit_details_lookup (details, "operation"); - if (operation == NULL) - goto out; + operation = polkit_details_lookup (details, "operation"); + if (operation == NULL) + goto out; - for (n = 0; map[n].name != NULL; n++) { - if (g_strcmp0 (map[n].name, operation) != 0) - continue; + for (n = 0; map[n].name != NULL; n++) + { + if (g_strcmp0 (map[n].name, operation) != 0) + continue; - ret = g_strdup (g_dgettext (GETTEXT_PACKAGE, map[n].message)); - break; - } + ret = g_strdup (g_dgettext (GETTEXT_PACKAGE, map[n].message)); + break; + } out: - return ret; + return ret; } static gchar * udisks_action_lookup_get_icon_name (PolkitBackendActionLookup *lookup, - const gchar *action_id, - PolkitDetails *details, - PolkitActionDescription *action_description) + const gchar *action_id, + PolkitDetails *details, + PolkitActionDescription *action_description) { - gchar *ret; + gchar *ret; - ret = NULL; + ret = NULL; - if (!g_str_has_prefix (action_id, "org.freedesktop.devicekit.disks.")) - goto out; + if (!g_str_has_prefix (action_id, "org.freedesktop.devicekit.disks.")) + goto out; - /* explicitly left blank for now */ + /* explicitly left blank for now */ - out: - return ret; + out: + return ret; } static PolkitDetails * -udisks_action_lookup_get_details (PolkitBackendActionLookup *lookup, - const gchar *action_id, - PolkitDetails *details, - PolkitActionDescription *action_description) +udisks_action_lookup_get_details (PolkitBackendActionLookup *lookup, + const gchar *action_id, + PolkitDetails *details, + PolkitActionDescription *action_description) { - const gchar *s; - const gchar *s2; - const gchar *s3; - GString *str; - PolkitDetails *ret; - - if (!g_str_has_prefix (action_id, "org.freedesktop.devicekit.disks.")) - return NULL; - - ret = polkit_details_new (); - - /* see daemon_local_check_auth() in daemon.c - * for where these keys are set - */ - - s = polkit_details_lookup (details, "unix-device"); - if (s != NULL) - polkit_details_insert (ret, _("Device"), s); - - s = polkit_details_lookup (details, "drive-vendor"); - s2 = polkit_details_lookup (details, "drive-model"); - s3 = polkit_details_lookup (details, "drive-revision"); - str = g_string_new (NULL); - if (s != NULL) { - g_string_append (str, s); - } - if (s2 != NULL) { - if (str->len > 0) - g_string_append_c (str, ' '); - g_string_append (str, s2); - } - if (s3 != NULL) { - if (str->len > 0) - g_string_append_c (str, ' '); - g_string_append_printf (str, "(%s)", s3); - } - - if (str->len > 0) { - polkit_details_insert (ret, _("Drive"), str->str); - } - g_string_free (str, TRUE); - - return ret; + const gchar *s; + const gchar *s2; + const gchar *s3; + GString *str; + PolkitDetails *ret; + + if (!g_str_has_prefix (action_id, "org.freedesktop.devicekit.disks.")) + return NULL; + + ret = polkit_details_new (); + + /* see daemon_local_check_auth() in daemon.c + * for where these keys are set + */ + + s = polkit_details_lookup (details, "unix-device"); + if (s != NULL) + polkit_details_insert (ret, _ ("Device"), s); + + s = polkit_details_lookup (details, "drive-vendor"); + s2 = polkit_details_lookup (details, "drive-model"); + s3 = polkit_details_lookup (details, "drive-revision"); + str = g_string_new (NULL); + if (s != NULL) + { + g_string_append (str, s); + } + if (s2 != NULL) + { + if (str->len > 0) + g_string_append_c (str, ' '); + g_string_append (str, s2); + } + if (s3 != NULL) + { + if (str->len > 0) + g_string_append_c (str, ' '); + g_string_append_printf (str, "(%s)", s3); + } + + if (str->len > 0) + { + polkit_details_insert (ret, _ ("Drive"), str->str); + } + g_string_free (str, TRUE); + + return ret; } static void polkit_backend_action_lookup_iface_init (PolkitBackendActionLookupIface *iface) { - iface->get_message = udisks_action_lookup_get_message; - iface->get_icon_name = udisks_action_lookup_get_icon_name; - iface->get_details = udisks_action_lookup_get_details; + iface->get_message = udisks_action_lookup_get_message; + iface->get_icon_name = udisks_action_lookup_get_icon_name; + iface->get_details = udisks_action_lookup_get_details; } /* ---------------------------------------------------------------------------------------------------- */ @@ -274,15 +229,15 @@ polkit_backend_action_lookup_iface_init (PolkitBackendActionLookupIface *iface) void g_io_module_load (GIOModule *module) { - bindtextdomain (GETTEXT_PACKAGE, PACKAGE_LOCALE_DIR); - bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8"); + bindtextdomain (GETTEXT_PACKAGE, PACKAGE_LOCALE_DIR); + bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8"); - udisks_action_lookup_register_type (G_TYPE_MODULE (module)); + udisks_action_lookup_register_type (G_TYPE_MODULE (module)); - g_io_extension_point_implement (POLKIT_BACKEND_ACTION_LOOKUP_EXTENSION_POINT_NAME, - UDISKS_TYPE_ACTION_LOOKUP, - "udisks action lookup extension " PACKAGE_VERSION, - 0); + g_io_extension_point_implement (POLKIT_BACKEND_ACTION_LOOKUP_EXTENSION_POINT_NAME, + UDISKS_TYPE_ACTION_LOOKUP, + "udisks action lookup extension " PACKAGE_VERSION, + 0); } void diff --git a/src/poller.c b/src/poller.c index 965ddc2..998a709 100644 --- a/src/poller.c +++ b/src/poller.c @@ -47,53 +47,54 @@ static void set_proc_title_init (int argc, char *argv[]) { #ifdef __linux__ - unsigned int i; - char **new_environ, *endptr; + unsigned int i; + char **new_environ, *endptr; - /* This code is really really ugly. We make some memory layout - * assumptions and reuse the environment array as memory to store - * our process title in */ + /* This code is really really ugly. We make some memory layout + * assumptions and reuse the environment array as memory to store + * our process title in */ - for (i = 0; environ[i] != NULL; i++) - ; + for (i = 0; environ[i] != NULL; i++) + ; - endptr = i ? environ[i-1] + strlen (environ[i-1]) : argv[argc-1] + strlen (argv[argc-1]); + endptr = i ? environ[i-1] + strlen (environ[i-1]) : argv[argc-1] + strlen (argv[argc-1]); - argv_buffer = argv; - argv_size = endptr - argv_buffer[0]; + argv_buffer = argv; + argv_size = endptr - argv_buffer[0]; - /* Make a copy of environ */ + /* Make a copy of environ */ - new_environ = malloc (sizeof(char*) * (i + 1)); - for (i = 0; environ[i] != NULL; i++) - new_environ[i] = strdup (environ[i]); - new_environ[i] = NULL; + new_environ = malloc (sizeof(char*) * (i + 1)); + for (i = 0; environ[i] != NULL; i++) + new_environ[i] = strdup (environ[i]); + new_environ[i] = NULL; - environ = new_environ; + environ = new_environ; #endif } /* this code borrowed from avahi-daemon's setproctitle.c (LGPL v2) */ static void -set_proc_title (const char *format, ...) +set_proc_title (const char *format, + ...) { #ifdef __linux__ - size_t len; - va_list ap; + size_t len; + va_list ap; - if (argv_buffer == NULL) - goto out; + if (argv_buffer == NULL) + goto out; - va_start (ap, format); - vsnprintf (argv_buffer[0], argv_size, format, ap); - va_end (ap); + va_start (ap, format); + vsnprintf (argv_buffer[0], argv_size, format, ap); + va_end (ap); - len = strlen (argv_buffer[0]); + len = strlen (argv_buffer[0]); - memset (argv_buffer[0] + len, 0, argv_size - len); - argv_buffer[1] = NULL; -out: - ; + memset (argv_buffer[0] + len, 0, argv_size - len); + argv_buffer[1] = NULL; + out: + ; #endif } @@ -106,37 +107,42 @@ static guint poller_timeout_id = 0; static void poller_poll_device (const gchar *device_file) { - gboolean is_cdrom; - int fd, fd2; + gboolean is_cdrom; + int fd, fd2; - /* the device file is the canonical device file from udev */ - is_cdrom = (g_str_has_prefix (device_file, "/dev/sr") || g_str_has_prefix (device_file, "/dev/scd")); + /* the device file is the canonical device file from udev */ + is_cdrom = (g_str_has_prefix (device_file, "/dev/sr") || g_str_has_prefix (device_file, "/dev/scd")); #ifdef POLL_SHOW_DEBUG - g_print ("**** POLLER (%d): polling %s\n", getpid (), device_file); + g_print ("**** POLLER (%d): polling %s\n", getpid (), device_file); #endif - if (is_cdrom) { - /* optical drives need special care - * - * - use O_NONBLOCK to avoid closing the door - * - use O_EXCL to avoid interferring with cd burning software / audio playback / etc - */ - fd = open (device_file, O_RDONLY | O_NONBLOCK | O_EXCL); - if (fd != -1) { - close (fd); - } - - } else { - fd = open (device_file, O_RDONLY); - fd2 = open (device_file, O_RDONLY | O_NONBLOCK); - if (fd != -1) { - close (fd); - } - if (fd2 != -1) { - close (fd2); - } + if (is_cdrom) + { + /* optical drives need special care + * + * - use O_NONBLOCK to avoid closing the door + * - use O_EXCL to avoid interferring with cd burning software / audio playback / etc + */ + fd = open (device_file, O_RDONLY | O_NONBLOCK | O_EXCL); + if (fd != -1) + { + close (fd); + } + } + else + { + fd = open (device_file, O_RDONLY); + fd2 = open (device_file, O_RDONLY | O_NONBLOCK); + if (fd != -1) + { + close (fd); + } + if (fd2 != -1) + { + close (fd2); } + } } /* ---------------------------------------------------------------------------------------------------- */ @@ -144,85 +150,92 @@ poller_poll_device (const gchar *device_file) static gboolean poller_timeout_cb (gpointer user_data) { - guint n; + guint n; - for (n = 0; poller_devices_to_poll != NULL && poller_devices_to_poll[n] != NULL; n++) { - const gchar *device_file = poller_devices_to_poll[n]; + for (n = 0; poller_devices_to_poll != NULL && poller_devices_to_poll[n] != NULL; n++) + { + const gchar *device_file = poller_devices_to_poll[n]; + poller_poll_device (device_file); + } - poller_poll_device (device_file); - } - - /* don't remove the source */ - return TRUE; + /* don't remove the source */ + return TRUE; } /* ---------------------------------------------------------------------------------------------------- */ static gboolean -poller_have_data (GIOChannel *channel, - GIOCondition condition, - gpointer user_data) +poller_have_data (GIOChannel *channel, + GIOCondition condition, + gpointer user_data) { - gchar *line; - gsize line_length; - GError *error; - gint status; - - error = NULL; - - /* Exit if parent dies */ - if (condition == G_IO_HUP) { - exit (1); - } - -read_more: - status = g_io_channel_read_line (channel, - &line, - &line_length, - NULL, - &error); - if (error != NULL) { - g_warning ("Error reading line from daemon: %s", error->message); - g_error_free (error); - goto out; - } - if (status == G_IO_STATUS_EOF || status == G_IO_STATUS_AGAIN) { - goto out; - } - - g_strstrip (line); + gchar *line; + gsize line_length; + GError *error; + gint status; + + error = NULL; + + /* Exit if parent dies */ + if (condition == G_IO_HUP) + { + exit (1); + } + + read_more: + status = g_io_channel_read_line (channel, &line, &line_length, NULL, &error); + if (error != NULL) + { + g_warning ("Error reading line from daemon: %s", error->message); + g_error_free (error); + goto out; + } + if (status == G_IO_STATUS_EOF || status == G_IO_STATUS_AGAIN) + { + goto out; + } + + g_strstrip (line); #ifdef POLL_SHOW_DEBUG - g_print ("**** POLLER (%d): polling process read '%s'\n", getpid (), line); + g_print ("**** POLLER (%d): polling process read '%s'\n", getpid (), line); #endif - if (g_str_has_prefix (line, "set-poll:")) { - g_strfreev (poller_devices_to_poll); - poller_devices_to_poll = g_strsplit (line + strlen ("set-poll:"), " ", 0); - } else { - g_printerr ("**** POLLER (%d): unknown command '%s'\n", getpid (), line); + if (g_str_has_prefix (line, "set-poll:")) + { + g_strfreev (poller_devices_to_poll); + poller_devices_to_poll = g_strsplit (line + strlen ("set-poll:"), " ", 0); + } + else + { + g_printerr ("**** POLLER (%d): unknown command '%s'\n", getpid (), line); + } + + if (g_strv_length (poller_devices_to_poll) == 0) + { + if (poller_timeout_id > 0) + { + g_source_remove (poller_timeout_id); + poller_timeout_id = 0; } - if (g_strv_length (poller_devices_to_poll) == 0) { - if (poller_timeout_id > 0) { - g_source_remove (poller_timeout_id); - poller_timeout_id = 0; - } - - set_proc_title ("udisks-daemon: not polling any devices"); - } else { - set_proc_title ("udisks-daemon: polling %s", line + strlen ("set-poll:")); + set_proc_title ("udisks-daemon: not polling any devices"); + } + else + { + set_proc_title ("udisks-daemon: polling %s", line + strlen ("set-poll:")); - if (poller_timeout_id == 0) { - poller_timeout_id = g_timeout_add_seconds (2, poller_timeout_cb, NULL); - } + if (poller_timeout_id == 0) + { + poller_timeout_id = g_timeout_add_seconds (2, poller_timeout_cb, NULL); } + } - g_free (line); - goto read_more; + g_free (line); + goto read_more; out: - /* keep the IOChannel around */ - return TRUE; + /* keep the IOChannel around */ + return TRUE; } /* ---------------------------------------------------------------------------------------------------- */ @@ -230,16 +243,16 @@ read_more: static void poller_run (gint fd) { - GMainLoop *loop; - GIOChannel *io_channel; + GMainLoop *loop; + GIOChannel *io_channel; - loop = g_main_loop_new (NULL, FALSE); + loop = g_main_loop_new (NULL, FALSE); - io_channel = g_io_channel_unix_new (fd); - g_io_channel_set_flags (io_channel, G_IO_FLAG_NONBLOCK, NULL); - g_io_add_watch (io_channel, G_IO_IN | G_IO_HUP, poller_have_data, NULL); + io_channel = g_io_channel_unix_new (fd); + g_io_channel_set_flags (io_channel, G_IO_FLAG_NONBLOCK, NULL); + g_io_add_watch (io_channel, G_IO_IN | G_IO_HUP, poller_have_data, NULL); - g_main_loop_run (loop); + g_main_loop_run (loop); } /* ---------------------------------------------------------------------------------------------------- */ @@ -247,42 +260,45 @@ poller_run (gint fd) static gint poller_daemon_write_end_fd; gboolean -poller_setup (int argc, char *argv[]) +poller_setup (int argc, + char *argv[]) { - gint pipefds[2]; - gboolean ret; - - ret = FALSE; - - if (pipe (pipefds) != 0) { - g_warning ("Couldn't set up polling process, pipe() failed: %m"); - goto out; - } - - switch (fork ()) { - case 0: - /* child */ - close (pipefds[1]); /* close write end */ - set_proc_title_init (argc, argv); - poller_run (pipefds[0]); - break; - - default: - /* parent */ - close (pipefds[0]); /* close read end */ - poller_daemon_write_end_fd = pipefds[1]; - break; - - case -1: - g_warning ("Couldn't set up polling process, fork() failed: %m"); - goto out; - break; - } - - ret = TRUE; + gint pipefds[2]; + gboolean ret; + + ret = FALSE; + + if (pipe (pipefds) != 0) + { + g_warning ("Couldn't set up polling process, pipe() failed: %m"); + goto out; + } + + switch (fork ()) + { + case 0: + /* child */ + close (pipefds[1]); /* close write end */ + set_proc_title_init (argc, argv); + poller_run (pipefds[0]); + break; + + default: + /* parent */ + close (pipefds[0]); /* close read end */ + poller_daemon_write_end_fd = pipefds[1]; + break; + + case -1: + g_warning ("Couldn't set up polling process, fork() failed: %m"); + goto out; + break; + } + + ret = TRUE; out: - return ret; + return ret; } /* ---------------------------------------------------------------------------------------------------- */ @@ -290,44 +306,46 @@ poller_setup (int argc, char *argv[]) void poller_set_devices (GList *devices) { - GList *l; - gchar **device_array; - guint n; - gchar *joined; - gchar *devices_to_poll; - static gchar *devices_currently_polled = NULL; + GList *l; + gchar **device_array; + guint n; + gchar *joined; + gchar *devices_to_poll; + static gchar *devices_currently_polled = NULL; - device_array = g_new0 (gchar *, g_list_length (devices) + 2); + device_array = g_new0 (gchar *, g_list_length (devices) + 2); - for (l = devices, n = 0; l != NULL; l = l->next) { - Device *device = DEVICE (l->data); + for (l = devices, n = 0; l != NULL; l = l->next) + { + Device *device = DEVICE (l->data); - device_array[n++] = device->priv->device_file; - } + device_array[n++] = device->priv->device_file; + } - g_qsort_with_data (device_array, n, sizeof (gchar *), (GCompareDataFunc) g_strcmp0, NULL); + g_qsort_with_data (device_array, n, sizeof(gchar *), (GCompareDataFunc) g_strcmp0, NULL); - device_array[n] = "\n"; + device_array[n] = "\n"; - joined = g_strjoinv (" ", device_array); - g_free (device_array); - devices_to_poll = g_strconcat ("set-poll:", - joined, - NULL); - g_free (joined); + joined = g_strjoinv (" ", device_array); + g_free (device_array); + devices_to_poll = g_strconcat ("set-poll:", joined, NULL); + g_free (joined); - /* only poke the polling process if the list of currently polled devices change */ - if (g_strcmp0 (devices_to_poll, devices_currently_polled) != 0) { - g_free (devices_currently_polled); - devices_currently_polled = devices_to_poll; + /* only poke the polling process if the list of currently polled devices change */ + if (g_strcmp0 (devices_to_poll, devices_currently_polled) != 0) + { + g_free (devices_currently_polled); + devices_currently_polled = devices_to_poll; #ifdef POLL_SHOW_DEBUG - g_print ("**** POLLER (%d): Sending poll command: '%s'\n", getpid (), devices_currently_polled); + g_print ("**** POLLER (%d): Sending poll command: '%s'\n", getpid (), devices_currently_polled); #endif - write (poller_daemon_write_end_fd, devices_currently_polled, strlen (devices_currently_polled)); - } else { - g_free (devices_to_poll); - } + write (poller_daemon_write_end_fd, devices_currently_polled, strlen (devices_currently_polled)); + } + else + { + g_free (devices_to_poll); + } } /* ---------------------------------------------------------------------------------------------------- */ diff --git a/src/poller.h b/src/poller.h index 32daafa..21a7a25 100644 --- a/src/poller.h +++ b/src/poller.h @@ -26,6 +26,6 @@ gboolean poller_setup (int argc, char *argv[]); /* media detection polling */ -void poller_set_devices (GList *devices); +void poller_set_devices (GList *devices); #endif /* __POLLER_H */ diff --git a/src/port-private.c b/src/port-private.c index cc40b9e..7b28cf4 100644 --- a/src/port-private.c +++ b/src/port-private.c @@ -36,9 +36,7 @@ emit_changed_idle_cb (gpointer data) if (!port->priv->removed) { g_print ("**** EMITTING CHANGED for %s\n", port->priv->native_path); - g_signal_emit_by_name (port->priv->daemon, - "port-changed", - port->priv->object_path); + g_signal_emit_by_name (port->priv->daemon, "port-changed", port->priv->object_path); g_signal_emit_by_name (port, "changed"); } port->priv->emit_changed_idle_id = 0; @@ -48,7 +46,8 @@ emit_changed_idle_cb (gpointer data) } static void -emit_changed (Port *port, const gchar *name) +emit_changed (Port *port, + const gchar *name) { //g_debug ("property %s changed for %s", name, port->priv->port_file); @@ -58,15 +57,16 @@ emit_changed (Port *port, const gchar *name) if (port->priv->emit_changed_idle_id == 0) { port->priv->emit_changed_idle_id = g_idle_add_full (G_PRIORITY_DEFAULT, - emit_changed_idle_cb, - g_object_ref (port), - (GDestroyNotify) g_object_unref); + emit_changed_idle_cb, + g_object_ref (port), + (GDestroyNotify) g_object_unref); } } } void -port_set_adapter (Port *port, const gchar *value) +port_set_adapter (Port *port, + const gchar *value) { if (G_UNLIKELY (g_strcmp0 (port->priv->adapter, value) != 0)) { @@ -77,7 +77,8 @@ port_set_adapter (Port *port, const gchar *value) } void -port_set_parent (Port *port, const gchar *value) +port_set_parent (Port *port, + const gchar *value) { if (G_UNLIKELY (g_strcmp0 (port->priv->parent, value) != 0)) { @@ -88,11 +89,12 @@ port_set_parent (Port *port, const gchar *value) } void -port_set_number (Port *port, gint value) +port_set_number (Port *port, + gint value) { if (G_UNLIKELY (port->priv->number != value)) { - port->priv->number = value; + port->priv->number = value; emit_changed (port, "number"); } } diff --git a/src/port-private.h b/src/port-private.h index 34fd763..e83d151 100644 --- a/src/port-private.h +++ b/src/port-private.h @@ -29,42 +29,46 @@ G_BEGIN_DECLS -typedef enum { - PORT_TYPE_ATA, - PORT_TYPE_SAS +typedef enum +{ + PORT_TYPE_ATA, + PORT_TYPE_SAS } PortType; struct PortPrivate { - DBusGConnection *system_bus_connection; - Daemon *daemon; - GUdevDevice *d; + DBusGConnection *system_bus_connection; + Daemon *daemon; + GUdevDevice *d; - gchar *object_path; - gchar *native_path; - gboolean removed; + gchar *object_path; + gchar *native_path; + gboolean removed; - /* if non-zero, the id of the idle for emitting a 'change' signal */ - guint emit_changed_idle_id; + /* if non-zero, the id of the idle for emitting a 'change' signal */ + guint emit_changed_idle_id; - /* used for internal bookkeeping */ - PortType port_type; - gchar *native_path_for_device_prefix; + /* used for internal bookkeeping */ + PortType port_type; + gchar *native_path_for_device_prefix; - /**************/ - /* Properties */ - /**************/ + /**************/ + /* Properties */ + /**************/ - gchar *adapter; - gchar *parent; - gint number; + gchar *adapter; + gchar *parent; + gint number; }; /* property setters */ -void port_set_adapter (Port *port, const gchar *value); -void port_set_parent (Port *port, const gchar *value); -void port_set_number (Port *port, gint value); +void port_set_adapter (Port *port, + const gchar *value); +void port_set_parent (Port *port, + const gchar *value); +void port_set_number (Port *port, + gint value); G_END_DECLS diff --git a/src/port.c b/src/port.c index ac67ca9..603b78f 100644 --- a/src/port.c +++ b/src/port.c @@ -43,147 +43,162 @@ /*--------------------------------------------------------------------------------------------------------------*/ #include "port-glue.h" -static void port_class_init (PortClass *klass); -static void port_init (Port *seat); -static void port_finalize (GObject *object); +static void +port_class_init (PortClass *klass); +static void +port_init (Port *seat); +static void +port_finalize (GObject *object); -static gboolean update_info (Port *port); +static gboolean +update_info (Port *port); -static void drain_pending_changes (Port *port, gboolean force_update); +static void +drain_pending_changes (Port *port, + gboolean force_update); enum -{ - PROP_0, - PROP_NATIVE_PATH, + { + PROP_0, + PROP_NATIVE_PATH, - PROP_ADAPTER, - PROP_PARENT, - PROP_NUMBER, -}; + PROP_ADAPTER, + PROP_PARENT, + PROP_NUMBER, + }; enum -{ - CHANGED_SIGNAL, - LAST_SIGNAL, -}; + { + CHANGED_SIGNAL, + LAST_SIGNAL, + }; -static guint signals[LAST_SIGNAL] = { 0 }; +static guint signals[LAST_SIGNAL] = + { 0 }; G_DEFINE_TYPE (Port, port, G_TYPE_OBJECT) #define PORT_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), TYPE_PORT, PortPrivate)) static void -get_property (GObject *object, - guint prop_id, - GValue *value, - GParamSpec *pspec) +get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) { - Port *port = PORT (object); - - switch (prop_id) { - case PROP_NATIVE_PATH: - g_value_set_string (value, port->priv->native_path); - break; - - case PROP_ADAPTER: - if (port->priv->adapter != NULL) - g_value_set_boxed (value, port->priv->adapter); - else - g_value_set_boxed (value, "/"); - break; - - case PROP_PARENT: - if (port->priv->parent != NULL) - g_value_set_boxed (value, port->priv->parent); - else - g_value_set_boxed (value, "/"); - break; - - case PROP_NUMBER: - g_value_set_int (value, port->priv->number); - break; - - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } + Port *port = PORT (object); + + switch (prop_id) + { + case PROP_NATIVE_PATH: + g_value_set_string (value, port->priv->native_path); + break; + + case PROP_ADAPTER: + if (port->priv->adapter != NULL) + g_value_set_boxed (value, port->priv->adapter); + else + g_value_set_boxed (value, "/"); + break; + + case PROP_PARENT: + if (port->priv->parent != NULL) + g_value_set_boxed (value, port->priv->parent); + else + g_value_set_boxed (value, "/"); + break; + + case PROP_NUMBER: + g_value_set_int (value, port->priv->number); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } } static void port_class_init (PortClass *klass) { - GObjectClass *object_class = G_OBJECT_CLASS (klass); - - object_class->finalize = port_finalize; - object_class->get_property = get_property; - - g_type_class_add_private (klass, sizeof (PortPrivate)); - - signals[CHANGED_SIGNAL] = - g_signal_new ("changed", - G_OBJECT_CLASS_TYPE (klass), - G_SIGNAL_RUN_LAST | G_SIGNAL_DETAILED, - 0, - NULL, NULL, - g_cclosure_marshal_VOID__VOID, - G_TYPE_NONE, 0); - - dbus_g_object_type_install_info (TYPE_PORT, &dbus_glib_port_object_info); - - g_object_class_install_property ( - object_class, - PROP_NATIVE_PATH, - g_param_spec_string ("native-path", NULL, NULL, NULL, G_PARAM_READABLE)); - g_object_class_install_property ( - object_class, - PROP_ADAPTER, - g_param_spec_boxed ("adapter", NULL, NULL, DBUS_TYPE_G_OBJECT_PATH, G_PARAM_READABLE)); - g_object_class_install_property ( - object_class, - PROP_PARENT, - g_param_spec_boxed ("parent", NULL, NULL, DBUS_TYPE_G_OBJECT_PATH, G_PARAM_READABLE)); - g_object_class_install_property ( - object_class, - PROP_NUMBER, - g_param_spec_int ("number", NULL, NULL, G_MININT, G_MAXINT, -1, G_PARAM_READABLE)); + GObjectClass *object_class = G_OBJECT_CLASS (klass); + + object_class->finalize = port_finalize; + object_class->get_property = get_property; + + g_type_class_add_private (klass, sizeof(PortPrivate)); + + signals[CHANGED_SIGNAL] = g_signal_new ("changed", + G_OBJECT_CLASS_TYPE (klass), + G_SIGNAL_RUN_LAST | G_SIGNAL_DETAILED, + 0, + NULL, + NULL, + g_cclosure_marshal_VOID__VOID, + G_TYPE_NONE, + 0); + + dbus_g_object_type_install_info (TYPE_PORT, &dbus_glib_port_object_info); + + g_object_class_install_property (object_class, PROP_NATIVE_PATH, g_param_spec_string ("native-path", + NULL, + NULL, + NULL, + G_PARAM_READABLE)); + g_object_class_install_property (object_class, PROP_ADAPTER, g_param_spec_boxed ("adapter", + NULL, + NULL, + DBUS_TYPE_G_OBJECT_PATH, + G_PARAM_READABLE)); + g_object_class_install_property (object_class, PROP_PARENT, g_param_spec_boxed ("parent", + NULL, + NULL, + DBUS_TYPE_G_OBJECT_PATH, + G_PARAM_READABLE)); + g_object_class_install_property (object_class, PROP_NUMBER, g_param_spec_int ("number", + NULL, + NULL, + G_MININT, + G_MAXINT, + -1, + G_PARAM_READABLE)); } static void port_init (Port *port) { - port->priv = PORT_GET_PRIVATE (port); - port->priv->number = -1; + port->priv = PORT_GET_PRIVATE (port); + port->priv->number = -1; } static void port_finalize (GObject *object) { - Port *port; + Port *port; - g_return_if_fail (object != NULL); - g_return_if_fail (IS_PORT (object)); + g_return_if_fail (object != NULL); + g_return_if_fail (IS_PORT (object)); - port = PORT (object); - g_return_if_fail (port->priv != NULL); + port = PORT (object); + g_return_if_fail (port->priv != NULL); - /* g_debug ("finalizing %s", port->priv->native_path); */ + /* g_debug ("finalizing %s", port->priv->native_path); */ - g_object_unref (port->priv->d); - g_object_unref (port->priv->daemon); - g_free (port->priv->object_path); + g_object_unref (port->priv->d); + g_object_unref (port->priv->daemon); + g_free (port->priv->object_path); - g_free (port->priv->native_path); - g_free (port->priv->native_path_for_device_prefix); + g_free (port->priv->native_path); + g_free (port->priv->native_path_for_device_prefix); - if (port->priv->emit_changed_idle_id > 0) - g_source_remove (port->priv->emit_changed_idle_id); + if (port->priv->emit_changed_idle_id > 0) + g_source_remove (port->priv->emit_changed_idle_id); - /* free properties */ - g_free (port->priv->adapter); - g_free (port->priv->parent); + /* free properties */ + g_free (port->priv->adapter); + g_free (port->priv->parent); - G_OBJECT_CLASS (port_parent_class)->finalize (object); + G_OBJECT_CLASS (port_parent_class)->finalize (object); } /** @@ -197,37 +212,42 @@ port_finalize (GObject *object) static char * compute_object_path (Port *port) { - const gchar *basename; - GString *s; - guint n; - - basename = strrchr (port->priv->native_path, '/'); - if (basename != NULL) { - basename++; - } else { - basename = port->priv->native_path; + const gchar *basename; + GString *s; + guint n; + + basename = strrchr (port->priv->native_path, '/'); + if (basename != NULL) + { + basename++; + } + else + { + basename = port->priv->native_path; + } + + s = g_string_new (port->priv->parent); + g_string_append_c (s, '/'); + 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); } - - s = g_string_new (port->priv->parent); - g_string_append_c (s, '/'); - 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 _ */ - g_string_append_printf (s, "_%02x", c); - } + else + { + /* Escape bytes not in [A-Z][a-z][0-9] as _ */ + g_string_append_printf (s, "_%02x", c); } + } - return g_string_free (s, FALSE); + return g_string_free (s, FALSE); } /* ---------------------------------------------------------------------------------------------------- */ @@ -235,125 +255,131 @@ compute_object_path (Port *port) static gboolean register_disks_port (Port *port) { - DBusConnection *connection; - GError *error = NULL; - - port->priv->system_bus_connection = dbus_g_bus_get (DBUS_BUS_SYSTEM, &error); - if (port->priv->system_bus_connection == NULL) { - if (error != NULL) { - g_critical ("error getting system bus: %s", error->message); - g_error_free (error); - } - goto error; + DBusConnection *connection; + GError *error = NULL; + + port->priv->system_bus_connection = dbus_g_bus_get (DBUS_BUS_SYSTEM, &error); + if (port->priv->system_bus_connection == NULL) + { + if (error != NULL) + { + g_critical ("error getting system bus: %s", error->message); + g_error_free (error); } - connection = dbus_g_connection_get_connection (port->priv->system_bus_connection); + goto error; + } + connection = dbus_g_connection_get_connection (port->priv->system_bus_connection); - port->priv->object_path = compute_object_path (port); + port->priv->object_path = compute_object_path (port); - /* safety first */ - if (dbus_g_connection_lookup_g_object (port->priv->system_bus_connection, - port->priv->object_path) != NULL) { - g_error ("**** HACK: Wanting to register object at path `%s' but there is already an " - "object there. This is an internal error in the daemon. Aborting.\n", - port->priv->object_path); - } + /* safety first */ + if (dbus_g_connection_lookup_g_object (port->priv->system_bus_connection, port->priv->object_path) != NULL) + { + g_error ("**** HACK: Wanting to register object at path `%s' but there is already an " + "object there. This is an internal error in the daemon. Aborting.\n", port->priv->object_path); + } - dbus_g_connection_register_g_object (port->priv->system_bus_connection, - port->priv->object_path, - G_OBJECT (port)); + dbus_g_connection_register_g_object (port->priv->system_bus_connection, port->priv->object_path, G_OBJECT (port)); - return TRUE; + return TRUE; -error: - return FALSE; + error: + return FALSE; } void port_removed (Port *port) { - port->priv->removed = TRUE; + port->priv->removed = TRUE; - dbus_g_connection_unregister_g_object (port->priv->system_bus_connection, - G_OBJECT (port)); - g_assert (dbus_g_connection_lookup_g_object (port->priv->system_bus_connection, - port->priv->object_path) == NULL); + dbus_g_connection_unregister_g_object (port->priv->system_bus_connection, G_OBJECT (port)); + g_assert (dbus_g_connection_lookup_g_object (port->priv->system_bus_connection, port->priv->object_path) == NULL); } Port * -port_new (Daemon *daemon, GUdevDevice *d) +port_new (Daemon *daemon, + GUdevDevice *d) { - Port *port; - const char *native_path; + Port *port; + const char *native_path; + + port = NULL; + native_path = g_udev_device_get_sysfs_path (d); + + port = PORT (g_object_new (TYPE_PORT, NULL)); + port->priv->d = g_object_ref (d); + port->priv->daemon = g_object_ref (daemon); + port->priv->native_path = g_strdup (native_path); + + if (!update_info (port)) + { + g_object_unref (port); + port = NULL; + goto out; + } + + if (!register_disks_port (PORT (port))) + { + g_object_unref (port); + port = NULL; + goto out; + } - port = NULL; - native_path = g_udev_device_get_sysfs_path (d); - - port = PORT (g_object_new (TYPE_PORT, NULL)); - port->priv->d = g_object_ref (d); - port->priv->daemon = g_object_ref (daemon); - port->priv->native_path = g_strdup (native_path); - - if (!update_info (port)) { - g_object_unref (port); - port = NULL; - goto out; - } - - if (!register_disks_port (PORT (port))) { - g_object_unref (port); - port = NULL; - goto out; - } - -out: - return port; + out: + return port; } static void -drain_pending_changes (Port *port, gboolean force_update) +drain_pending_changes (Port *port, + gboolean force_update) { - gboolean emit_changed; - - emit_changed = FALSE; - - /* the update-in-idle is set up if, and only if, there are pending changes - so - * we should emit a 'change' event only if it is set up - */ - if (port->priv->emit_changed_idle_id != 0) { - g_source_remove (port->priv->emit_changed_idle_id); - port->priv->emit_changed_idle_id = 0; - emit_changed = TRUE; - } - - if ((!port->priv->removed) && (emit_changed || force_update)) { - if (port->priv->object_path != NULL) { - g_print ("**** EMITTING CHANGED for %s\n", port->priv->native_path); - g_signal_emit_by_name (port, "changed"); - g_signal_emit_by_name (port->priv->daemon, "port-changed", port->priv->object_path); - } + gboolean emit_changed; + + emit_changed = FALSE; + + /* the update-in-idle is set up if, and only if, there are pending changes - so + * we should emit a 'change' event only if it is set up + */ + if (port->priv->emit_changed_idle_id != 0) + { + g_source_remove (port->priv->emit_changed_idle_id); + port->priv->emit_changed_idle_id = 0; + emit_changed = TRUE; + } + + if ((!port->priv->removed) && (emit_changed || force_update)) + { + if (port->priv->object_path != NULL) + { + g_print ("**** EMITTING CHANGED for %s\n", port->priv->native_path); + g_signal_emit_by_name (port, "changed"); + g_signal_emit_by_name (port->priv->daemon, "port-changed", port->priv->object_path); } + } } /* called by the daemon on the 'change' uevent */ gboolean -port_changed (Port *port, GUdevDevice *d, gboolean synthesized) +port_changed (Port *port, + GUdevDevice *d, + gboolean synthesized) { - gboolean keep_port; + gboolean keep_port; - g_object_unref (port->priv->d); - port->priv->d = g_object_ref (d); + g_object_unref (port->priv->d); + port->priv->d = g_object_ref (d); - keep_port = update_info (port); + keep_port = update_info (port); - /* this 'change' event might prompt us to remove the port */ - if (!keep_port) - goto out; + /* this 'change' event might prompt us to remove the port */ + if (!keep_port) + goto out; - /* no, it's good .. keep it.. and always force a 'change' signal if the event isn't synthesized */ - drain_pending_changes (port, !synthesized); + /* no, it's good .. keep it.. and always force a 'change' signal if the event isn't synthesized */ + drain_pending_changes (port, !synthesized); -out: - return keep_port; + out: + return keep_port; } /* ---------------------------------------------------------------------------------------------------- */ @@ -361,149 +387,165 @@ out: const char * port_local_get_object_path (Port *port) { - return port->priv->object_path; + return port->priv->object_path; } const char * port_local_get_native_path (Port *port) { - return port->priv->native_path; + return port->priv->native_path; } gboolean local_port_encloses_native_path (Port *port, - const gchar *native_path) + const gchar *native_path) { - gboolean ret; - - ret = FALSE; - - if (port->priv->port_type == PORT_TYPE_ATA) { - - ret = g_str_has_prefix (native_path, port->priv->native_path_for_device_prefix); - - } else if (port->priv->port_type == PORT_TYPE_SAS) { - GDir *dir; - gchar *s; - const gchar *name; - const gchar *phy_kernel_name; - gchar **tokens; - gchar **tokens_copy; - guint num_tokens; - gint n; - - phy_kernel_name = g_udev_device_get_name (port->priv->d); - - /* Typically it looks like this for a device - * - * .../host6/port-6:0/end_device-6:0/target6:0:0/6:0:0:0/block/sda - * - * with - * - * # ls /sys/devices/pci0000:00/0000:00:01.0/0000:07:00.0/host6/port-6:0/ - * end_device-6:0 phy-6:0 power sas_port uevent - * - * Or for an expander it may look like - * - * .../host7/port-7:0/expander-7:0/sas_expander/expander-7:0 - * - * with - * - * # ls /sys/devices/pci0000:00/0000:00:03.0/0000:06:00.0/host7/port-7:0/ - * expander-7:0 phy-7:0 phy-7:1 phy-7:2 phy-7:3 power sas_port uevent - * - * Hmm, unfortunately there are no helpful symlinks we can use to - * easily get the information. So we search backwards for the first - * port-* directory. Then we look for a matching phy-name inside - * that directory. We always stop at "/expander-" and "/host" elements. - * - * We always stop if we find an el - * - * (TODO: Ugh, this is probably pretty expensive syscall-, memory- and - * computation-wise. We really need symlinks in sysfs for this.) - */ - //g_debug ("Path is %s", native_path); - - tokens = g_strsplit (native_path, "/", 0); - num_tokens = g_strv_length (tokens); - /* Copy the pointers so everything can be freed */ - tokens_copy = g_memdup (tokens, sizeof (gchar*) * (num_tokens + 1)); - s = NULL; - for (n = num_tokens - 2; n >= 0; n--) { - //g_debug ("Token %s", tokens[n]); - - if (g_str_has_prefix (tokens[n], "port-")) { - /* found it */ - tokens[n+1] = NULL; - s = g_strjoinv ("/", tokens); - break; - } else if (g_str_has_prefix (tokens[n], "expander-")) { - break; - } else if (g_str_has_prefix (tokens[n], "host")) { - break; - } - } - g_strfreev (tokens_copy); - g_free (tokens); - - //g_debug ("-> Port path %s", s); - - if (s != NULL) { - dir = g_dir_open (s, 0, NULL); - if (dir != NULL) { - while ((name = g_dir_read_name (dir)) != NULL) { - if (g_strcmp0 (name, phy_kernel_name) == 0) { - ret = TRUE; - break; - } - } - g_dir_close (dir); - } - g_free (s); + gboolean ret; + + ret = FALSE; + + if (port->priv->port_type == PORT_TYPE_ATA) + { + + ret = g_str_has_prefix (native_path, port->priv->native_path_for_device_prefix); + + } + else if (port->priv->port_type == PORT_TYPE_SAS) + { + GDir *dir; + gchar *s; + const gchar *name; + const gchar *phy_kernel_name; + gchar **tokens; + gchar **tokens_copy; + guint num_tokens; + gint n; + + phy_kernel_name = g_udev_device_get_name (port->priv->d); + + /* Typically it looks like this for a device + * + * .../host6/port-6:0/end_device-6:0/target6:0:0/6:0:0:0/block/sda + * + * with + * + * # ls /sys/devices/pci0000:00/0000:00:01.0/0000:07:00.0/host6/port-6:0/ + * end_device-6:0 phy-6:0 power sas_port uevent + * + * Or for an expander it may look like + * + * .../host7/port-7:0/expander-7:0/sas_expander/expander-7:0 + * + * with + * + * # ls /sys/devices/pci0000:00/0000:00:03.0/0000:06:00.0/host7/port-7:0/ + * expander-7:0 phy-7:0 phy-7:1 phy-7:2 phy-7:3 power sas_port uevent + * + * Hmm, unfortunately there are no helpful symlinks we can use to + * easily get the information. So we search backwards for the first + * port-* directory. Then we look for a matching phy-name inside + * that directory. We always stop at "/expander-" and "/host" elements. + * + * We always stop if we find an el + * + * (TODO: Ugh, this is probably pretty expensive syscall-, memory- and + * computation-wise. We really need symlinks in sysfs for this.) + */ + //g_debug ("Path is %s", native_path); + + tokens = g_strsplit (native_path, "/", 0); + num_tokens = g_strv_length (tokens); + /* Copy the pointers so everything can be freed */ + tokens_copy = g_memdup (tokens, sizeof(gchar*) * (num_tokens + 1)); + s = NULL; + for (n = num_tokens - 2; n >= 0; n--) + { + //g_debug ("Token %s", tokens[n]); + + if (g_str_has_prefix (tokens[n], "port-")) + { + /* found it */ + tokens[n + 1] = NULL; + s = g_strjoinv ("/", tokens); + break; + } + else if (g_str_has_prefix (tokens[n], "expander-")) + { + break; + } + else if (g_str_has_prefix (tokens[n], "host")) + { + break; + } + } + g_strfreev (tokens_copy); + g_free (tokens); + + //g_debug ("-> Port path %s", s); + + if (s != NULL) + { + dir = g_dir_open (s, 0, NULL); + if (dir != NULL) + { + while ((name = g_dir_read_name (dir)) != NULL) + { + if (g_strcmp0 (name, phy_kernel_name) == 0) + { + ret = TRUE; + break; + } } + g_dir_close (dir); + } + g_free (s); } + } - return ret; + return ret; } /* ---------------------------------------------------------------------------------------------------- */ static char * -sysfs_resolve_link (const char *sysfs_path, const char *name) +sysfs_resolve_link (const char *sysfs_path, + const char *name) { - char *full_path; - char link_path[PATH_MAX]; - char resolved_path[PATH_MAX]; - ssize_t num; - gboolean found_it; - - found_it = FALSE; - - full_path = g_build_filename (sysfs_path, name, NULL); - - //g_debug ("name='%s'", name); - //g_debug ("full_path='%s'", full_path); - num = readlink (full_path, link_path, sizeof (link_path) - 1); - if (num != -1) { - char *absolute_path; - - link_path[num] = '\0'; - - //g_debug ("link_path='%s'", link_path); - absolute_path = g_build_filename (sysfs_path, link_path, NULL); - //g_debug ("absolute_path='%s'", absolute_path); - if (realpath (absolute_path, resolved_path) != NULL) { - //g_debug ("resolved_path='%s'", resolved_path); - found_it = TRUE; - } - g_free (absolute_path); + char *full_path; + char link_path[PATH_MAX]; + char resolved_path[PATH_MAX]; + ssize_t num; + gboolean found_it; + + found_it = FALSE; + + full_path = g_build_filename (sysfs_path, name, NULL); + + //g_debug ("name='%s'", name); + //g_debug ("full_path='%s'", full_path); + num = readlink (full_path, link_path, sizeof(link_path) - 1); + if (num != -1) + { + char *absolute_path; + + link_path[num] = '\0'; + + //g_debug ("link_path='%s'", link_path); + absolute_path = g_build_filename (sysfs_path, link_path, NULL); + //g_debug ("absolute_path='%s'", absolute_path); + if (realpath (absolute_path, resolved_path) != NULL) + { + //g_debug ("resolved_path='%s'", resolved_path); + found_it = TRUE; } - g_free (full_path); - - if (found_it) - return g_strdup (resolved_path); - else - return NULL; + g_free (absolute_path); + } + g_free (full_path); + + if (found_it) + return g_strdup (resolved_path); + else + return NULL; } /* ---------------------------------------------------------------------------------------------------- */ @@ -512,141 +554,143 @@ static gint int_compare_func (gconstpointer a, gconstpointer b) { - gint a_val; - gint b_val; + gint a_val; + gint b_val; - a_val = *((gint *) a); - b_val = *((gint *) b); + a_val = *((gint *) a); + b_val = *((gint *) b); - return a_val - b_val; + return a_val - b_val; } /* Update info for an ATA port */ static gboolean -update_info_ata (Port *port, +update_info_ata (Port *port, Adapter *adapter) { - GDir *dir; - GError *error; - gboolean ret; - const gchar *name; - GArray *numbers; - guint n; - const gchar *basename; - gint port_host_number; - gint port_number; - - ret = FALSE; - port_number = -1; - dir = NULL; - numbers = NULL; - - /* First, figure out prefix used for matching the device on the port */ - if (port->priv->native_path_for_device_prefix == NULL) { - port->priv->native_path_for_device_prefix = - sysfs_resolve_link (g_udev_device_get_sysfs_path (port->priv->d), - "device"); - if (port->priv->native_path_for_device_prefix == NULL) { - g_warning ("Unable to resolve 'device' symlink for %s", - g_udev_device_get_sysfs_path (port->priv->d)); - goto out; - } - } - - /* Second, figure out the port number. - * - * As ATA drivers create one scsi_host objects for each port - * the port number can be inferred from the numbering of the - * scsi_host objects. - * - * We also want to check that the scsi_host object *really* - * stems from SATA. There doesn't seem to be an easy way of - * doing this so the heuristic used right now is that it - * the scsi_host is ATA if, and only if, there is more than - * one scsi_host.... - * - * (TODO: we could match on driver names instead? Anyway, - * there are plans to properly support the ATA - * topology (including PMP) once libata switches - * away from SCSI. Once this is available these - * hacks can go away...) - */ - - basename = strrchr (port->priv->native_path, '/'); - if (basename == NULL || sscanf (basename + 1, "host%d", &port_host_number) != 1) { - g_warning ("Cannot extract port host number from %s", port->priv->native_path); - goto out; - } - - dir = g_dir_open (adapter_local_get_native_path (adapter), - 0, - &error); - if (dir == NULL) { - g_warning ("Unable to open %s: %s", - adapter_local_get_native_path (adapter), - error->message); - g_error_free (error); - goto out; - } - - numbers = g_array_new (FALSE, FALSE, sizeof (gint)); - - while ((name = g_dir_read_name (dir)) != NULL) { - gint number; - - if (sscanf (name, "host%d", &number) != 1) - continue; - - g_array_append_val (numbers, number); + GDir *dir; + GError *error; + gboolean ret; + const gchar *name; + GArray *numbers; + guint n; + const gchar *basename; + gint port_host_number; + gint port_number; + + ret = FALSE; + port_number = -1; + dir = NULL; + numbers = NULL; + + /* First, figure out prefix used for matching the device on the port */ + if (port->priv->native_path_for_device_prefix == NULL) + { + port->priv->native_path_for_device_prefix = sysfs_resolve_link (g_udev_device_get_sysfs_path (port->priv->d), + "device"); + if (port->priv->native_path_for_device_prefix == NULL) + { + g_warning ("Unable to resolve 'device' symlink for %s", g_udev_device_get_sysfs_path (port->priv->d)); + goto out; } - - if (numbers->len < 2) { - /* This is (probably, see above) ATA since there isn't at least two - * scsi_host objects. - */ - goto out; - } - - g_array_sort (numbers, int_compare_func); - - for (n = 0; n < numbers->len; n++) { - gint number; - - number = ((gint *) numbers->data) [n]; - - if (number == port_host_number) { - port_number = n; - break; - } + } + + /* Second, figure out the port number. + * + * As ATA drivers create one scsi_host objects for each port + * the port number can be inferred from the numbering of the + * scsi_host objects. + * + * We also want to check that the scsi_host object *really* + * stems from SATA. There doesn't seem to be an easy way of + * doing this so the heuristic used right now is that it + * the scsi_host is ATA if, and only if, there is more than + * one scsi_host.... + * + * (TODO: we could match on driver names instead? Anyway, + * there are plans to properly support the ATA + * topology (including PMP) once libata switches + * away from SCSI. Once this is available these + * hacks can go away...) + */ + + basename = strrchr (port->priv->native_path, '/'); + if (basename == NULL || sscanf (basename + 1, "host%d", &port_host_number) != 1) + { + g_warning ("Cannot extract port host number from %s", port->priv->native_path); + goto out; + } + + dir = g_dir_open (adapter_local_get_native_path (adapter), 0, &error); + if (dir == NULL) + { + g_warning ("Unable to open %s: %s", adapter_local_get_native_path (adapter), error->message); + g_error_free (error); + goto out; + } + + numbers = g_array_new (FALSE, FALSE, sizeof(gint)); + + while ((name = g_dir_read_name (dir)) != NULL) + { + gint number; + + if (sscanf (name, "host%d", &number) != 1) + continue; + + g_array_append_val (numbers, number); + } + + if (numbers->len < 2) + { + /* This is (probably, see above) ATA since there isn't at least two + * scsi_host objects. + */ + goto out; + } + + g_array_sort (numbers, int_compare_func); + + for (n = 0; n < numbers->len; n++) + { + gint number; + + number = ((gint *) numbers->data)[n]; + + if (number == port_host_number) + { + port_number = n; + break; } + } - port_set_number (port, port_number); - port->priv->port_type = PORT_TYPE_ATA; - ret = TRUE; + port_set_number (port, port_number); + port->priv->port_type = PORT_TYPE_ATA; + ret = TRUE; out: - if (dir != NULL) - g_dir_close (dir); - if (numbers != NULL) - g_array_unref (numbers); + if (dir != NULL) + g_dir_close (dir); + if (numbers != NULL) + g_array_unref (numbers); - return ret; + return ret; } /* ---------------------------------------------------------------------------------------------------- */ /* Update info for a SAS PHY */ static gboolean -update_info_sas_phy (Port *port, +update_info_sas_phy (Port *port, Adapter *adapter) { - gint port_number; + gint port_number; - port_number = g_udev_device_get_sysfs_attr_as_int (port->priv->d, "phy_identifier"); - port_set_number (port, port_number); - port->priv->port_type = PORT_TYPE_SAS; + port_number = g_udev_device_get_sysfs_attr_as_int (port->priv->d, "phy_identifier"); + port_set_number (port, port_number); + port->priv->port_type = PORT_TYPE_SAS; - return TRUE; + return TRUE; } /* ---------------------------------------------------------------------------------------------------- */ @@ -666,46 +710,47 @@ update_info_sas_phy (Port *port, static gboolean update_info (Port *port) { - gboolean ret; - Adapter *adapter; - Expander *expander; + gboolean ret; + Adapter *adapter; + Expander *expander; - ret = FALSE; + ret = FALSE; - adapter = daemon_local_find_enclosing_adapter (port->priv->daemon, - port->priv->native_path); + adapter = daemon_local_find_enclosing_adapter (port->priv->daemon, port->priv->native_path); - expander = daemon_local_find_enclosing_expander (port->priv->daemon, - port->priv->native_path); + expander = daemon_local_find_enclosing_expander (port->priv->daemon, port->priv->native_path); #if 0 - g_debug ("Adapter=%s and Expander=%s for %s", - adapter != NULL ? adapter_local_get_native_path (adapter) : "(none)", - expander != NULL ? expander_local_get_native_path (expander) : "(none)", - g_udev_device_get_sysfs_path (port->priv->d)); + g_debug ("Adapter=%s and Expander=%s for %s", + adapter != NULL ? adapter_local_get_native_path (adapter) : "(none)", + expander != NULL ? expander_local_get_native_path (expander) : "(none)", + g_udev_device_get_sysfs_path (port->priv->d)); #endif - /* Need to have at least an adapter to continue */ - if (adapter == NULL) - goto out; - - port_set_adapter (port, adapter_local_get_object_path (adapter)); - if (expander != NULL) - port_set_parent (port, expander_local_get_object_path (expander)); - else - port_set_parent (port, adapter_local_get_object_path (adapter)); - - if (g_strcmp0 (g_udev_device_get_subsystem (port->priv->d), "scsi_host") == 0) { - if (!update_info_ata (port, adapter)) - goto out; - } else { - if (!update_info_sas_phy (port, adapter)) - goto out; - } - - ret = TRUE; + /* Need to have at least an adapter to continue */ + if (adapter == NULL) + goto out; + + port_set_adapter (port, adapter_local_get_object_path (adapter)); + if (expander != NULL) + port_set_parent (port, expander_local_get_object_path (expander)); + else + port_set_parent (port, adapter_local_get_object_path (adapter)); + + if (g_strcmp0 (g_udev_device_get_subsystem (port->priv->d), "scsi_host") == 0) + { + if (!update_info_ata (port, adapter)) + goto out; + } + else + { + if (!update_info_sas_phy (port, adapter)) + goto out; + } + + ret = TRUE; out: - return ret; + return ret; } diff --git a/src/port.h b/src/port.h index 5c61812..6397853 100644 --- a/src/port.h +++ b/src/port.h @@ -36,37 +36,37 @@ G_BEGIN_DECLS #define IS_PORT_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), TYPE_PORT)) #define PORT_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), TYPE_PORT, PortClass)) -typedef struct PortClass PortClass; +typedef struct PortClass PortClass; typedef struct PortPrivate PortPrivate; struct Port { - GObject parent; - PortPrivate *priv; + GObject parent; + PortPrivate *priv; }; struct PortClass { - GObjectClass parent_class; + GObjectClass parent_class; }; -GType port_get_type (void) G_GNUC_CONST; +GType port_get_type (void) G_GNUC_CONST; -Port *port_new (Daemon *daemon, - GUdevDevice *d); +Port *port_new (Daemon *daemon, + GUdevDevice *d); -gboolean port_changed (Port *port, - GUdevDevice *d, - gboolean synthesized); +gboolean port_changed (Port *port, + GUdevDevice *d, + gboolean synthesized); -void port_removed (Port *port); +void port_removed (Port *port); /* local methods */ const char *port_local_get_object_path (Port *port); const char *port_local_get_native_path (Port *port); gboolean local_port_encloses_native_path (Port *port, - const gchar *native_path); + const gchar *native_path); G_END_DECLS diff --git a/src/private.h b/src/private.h index fe504de..e93eabb 100644 --- a/src/private.h +++ b/src/private.h @@ -26,7 +26,7 @@ G_BEGIN_DECLS Mount *_mount_new (dev_t dev, - const gchar *mount_path); + const gchar *mount_path); G_END_DECLS diff --git a/src/probers/devkit-disks-dm-export.c b/src/probers/devkit-disks-dm-export.c index 1b60432..5b90b73 100644 --- a/src/probers/devkit-disks-dm-export.c +++ b/src/probers/devkit-disks-dm-export.c @@ -8,7 +8,7 @@ static void usage (void) { - fprintf (stderr, "incorrect usage\n"); + fprintf (stderr, "incorrect usage\n"); } /* based on the export patch in https://bugzilla.redhat.com/show_bug.cgi?id=438604 */ @@ -16,135 +16,147 @@ usage (void) static int export (int major, int minor) { - int ret; - struct dm_task *dmt; - void *next; - uint64_t start, length; - char *target_type; - char *params; - const char *name; - const char *uuid; - struct dm_info info; - - ret = 1; - dmt = NULL; - - if (!(dmt = dm_task_create (DM_DEVICE_STATUS))) { - perror ("dm_task_create"); - goto out; + int ret; + struct dm_task *dmt; + void *next; + uint64_t start, length; + char *target_type; + char *params; + const char *name; + const char *uuid; + struct dm_info info; + + ret = 1; + dmt = NULL; + + if (!(dmt = dm_task_create (DM_DEVICE_STATUS))) + { + perror ("dm_task_create"); + goto out; + } + + if (!dm_task_set_major (dmt, major)) + { + perror ("dm_task_set_major"); + goto out; + } + + if (!dm_task_set_minor (dmt, minor)) + { + perror ("dm_task_set_minor"); + goto out; + } + + if (!dm_task_run(dmt)) + { + perror ("dm_task_run"); + goto out; + } + + if (!dm_task_get_info (dmt, &info) || !info.exists) + { + perror ("dm_task_get_info"); + goto out; + } + + if ((name = dm_task_get_name (dmt)) == NULL) + { + perror ("dm_task_get_name"); + goto out; + } + + uuid = dm_task_get_uuid (dmt); + + printf("UDISKS_DM_NAME=%s\n", name); + + if ((uuid = dm_task_get_uuid (dmt)) && *uuid) + printf("UDISKS_DM_UUID=%s\n", uuid); + + if (!info.exists) + { + printf("UDISKS_DM_STATE=NOTPRESENT\n"); + goto out; + } + + printf("UDISKS_DM_STATE=%s\n", + info.suspended ? "SUSPENDED" : + (info.read_only ? " READONLY" : "ACTIVE")); + + if (!info.live_table && !info.inactive_table) + printf("UDISKS_DM_TABLE_STATE=NONE\n"); + else + printf("UDISKS_DM_TABLE_STATE=%s%s%s\n", + info.live_table ? "LIVE" : "", + info.live_table && info.inactive_table ? "/" : "", + info.inactive_table ? "INACTIVE" : ""); + + if (info.open_count != -1) + printf("UDISKS_DM_OPENCOUNT=%d\n", info.open_count); + + printf("UDISKS_DM_LAST_EVENT_NR=%" PRIu32 "\n", info.event_nr); + + printf("UDISKS_DM_MAJOR=%d\n", info.major); + printf("UDISKS_DM_MINOR=%d\n", info.minor); + + if (info.target_count != -1) + printf("UDISKS_DM_TARGET_COUNT=%d\n", info.target_count); + + /* export all table types */ + next = NULL; + next = dm_get_next_target (dmt, next, &start, &length, &target_type, ¶ms); + if (target_type != NULL) + { + printf("UDISKS_DM_TARGET_TYPES=%s", target_type); + while (next != NULL) + { + next = dm_get_next_target (dmt, next, &start, &length, &target_type, ¶ms); + if (target_type) + printf(",%s", target_type); } + printf("\n"); + } - if (!dm_task_set_major (dmt, major)) { - perror ("dm_task_set_major"); - goto out; - } - - if (!dm_task_set_minor (dmt, minor)) { - perror ("dm_task_set_minor"); - goto out; - } - - if (!dm_task_run(dmt)) { - perror ("dm_task_run"); - goto out; - } - - if (!dm_task_get_info (dmt, &info) || !info.exists) { - perror ("dm_task_get_info"); - goto out; - } - - if ((name = dm_task_get_name (dmt)) == NULL) { - perror ("dm_task_get_name"); - goto out; - } - - uuid = dm_task_get_uuid (dmt); - - printf("UDISKS_DM_NAME=%s\n", name); - - if ((uuid = dm_task_get_uuid (dmt)) && *uuid) - printf("UDISKS_DM_UUID=%s\n", uuid); - - if (!info.exists) { - printf("UDISKS_DM_STATE=NOTPRESENT\n"); - goto out; - } + ret = 0; - printf("UDISKS_DM_STATE=%s\n", - info.suspended ? "SUSPENDED" : - (info.read_only ? " READONLY" : "ACTIVE")); - - if (!info.live_table && !info.inactive_table) - printf("UDISKS_DM_TABLE_STATE=NONE\n"); - else - printf("UDISKS_DM_TABLE_STATE=%s%s%s\n", - info.live_table ? "LIVE" : "", - info.live_table && info.inactive_table ? "/" : "", - info.inactive_table ? "INACTIVE" : ""); - - if (info.open_count != -1) - printf("UDISKS_DM_OPENCOUNT=%d\n", info.open_count); - - printf("UDISKS_DM_LAST_EVENT_NR=%" PRIu32 "\n", info.event_nr); - - printf("UDISKS_DM_MAJOR=%d\n", info.major); - printf("UDISKS_DM_MINOR=%d\n", info.minor); - - if (info.target_count != -1) - printf("UDISKS_DM_TARGET_COUNT=%d\n", info.target_count); - - /* export all table types */ - next = NULL; - next = dm_get_next_target (dmt, next, &start, &length, &target_type, ¶ms); - if (target_type != NULL) { - printf("UDISKS_DM_TARGET_TYPES=%s", target_type); - while (next != NULL) { - next = dm_get_next_target (dmt, next, &start, &length, &target_type, ¶ms); - if (target_type) - printf(",%s", target_type); - } - printf("\n"); - } - - ret = 0; - -out: - if (dmt != NULL) - dm_task_destroy(dmt); - return ret; + out: + if (dmt != NULL) + dm_task_destroy(dmt); + return ret; } - int -main (int argc, char *argv[]) +main (int argc, + char *argv[]) { - int ret; - int major; - int minor; - char *endp; - - ret = 1; - - if (argc != 3) { - usage (); - goto out; - } - - major = strtol (argv[1], &endp, 10); - if (endp == NULL || *endp != '\0') { - usage (); - goto out; - } - - minor = strtol (argv[2], &endp, 10); - if (endp == NULL || *endp != '\0') { - usage (); - goto out; - } - - ret = export (major, minor); - -out: - return ret; + int ret; + int major; + int minor; + char *endp; + + ret = 1; + + if (argc != 3) + { + usage (); + goto out; + } + + major = strtol (argv[1], &endp, 10); + if (endp == NULL || *endp != '\0') + { + usage (); + goto out; + } + + minor = strtol (argv[2], &endp, 10); + if (endp == NULL || *endp != '\0') + { + usage (); + goto out; + } + + ret = export (major, minor); + + out: + return ret; } diff --git a/src/probers/devkit-disks-probe-ata-smart.c b/src/probers/devkit-disks-probe-ata-smart.c index 8e36f1a..0f4e583 100644 --- a/src/probers/devkit-disks-probe-ata-smart.c +++ b/src/probers/devkit-disks-probe-ata-smart.c @@ -27,43 +27,47 @@ static void usage (void) { - fprintf (stderr, "incorrect usage\n"); + fprintf (stderr, "incorrect usage\n"); } int -main (int argc, char *argv[]) +main (int argc, + char *argv[]) { - int ret; - const char *device; - SkDisk *d; - SkBool smart_is_available; + int ret; + const char *device; + SkDisk *d; + SkBool smart_is_available; - d = NULL; - ret = 1; + d = NULL; + ret = 1; - if (argc != 2) { - usage (); - goto out; - } + if (argc != 2) + { + usage (); + goto out; + } - device = argv[1]; + device = argv[1]; - if (sk_disk_open (device, &d) < 0) { - fprintf (stderr, "Failed to open disk %s: %s\n", device, strerror (errno)); - goto out; - } + if (sk_disk_open (device, &d) < 0) + { + fprintf (stderr, "Failed to open disk %s: %s\n", device, strerror (errno)); + goto out; + } - if (sk_disk_smart_is_available (d, &smart_is_available) != 0) { - fprintf (stderr, "Failed to determine if smart is available for %s: %s\n", device, strerror (errno)); - goto out; - } + if (sk_disk_smart_is_available (d, &smart_is_available) != 0) + { + fprintf (stderr, "Failed to determine if smart is available for %s: %s\n", device, strerror (errno)); + goto out; + } - printf ("UDISKS_ATA_SMART_IS_AVAILABLE=%d\n", smart_is_available); + printf ("UDISKS_ATA_SMART_IS_AVAILABLE=%d\n", smart_is_available); - ret = 0; + ret = 0; out: - if (d != NULL) - sk_disk_free (d); - return ret; + if (d != NULL) + sk_disk_free (d); + return ret; } diff --git a/src/probers/devkit-disks-probe-sas-expander.c b/src/probers/devkit-disks-probe-sas-expander.c index c6fc954..ce1e0c0 100644 --- a/src/probers/devkit-disks-probe-sas-expander.c +++ b/src/probers/devkit-disks-probe-sas-expander.c @@ -32,99 +32,103 @@ static guchar * do_smp_command (const gchar *smp_command_line, - gsize *out_smp_response_len) + gsize *out_smp_response_len) { - guchar *ret; - gchar *command_line; - gchar *prog_stdout; - gint prog_exit_status; - GError *error; - - ret = NULL; - error = NULL; - - command_line = g_strdup_printf ("sh -c '%s |base64 -w0'", smp_command_line); - if (!g_spawn_command_line_sync (command_line, &prog_stdout, NULL, &prog_exit_status, &error)) { - g_printerr ("Error spawning `%s': %s", command_line, error->message); - g_error_free (error); - goto out; - } - - if (!WIFEXITED (prog_exit_status)) - goto out; - - if (WEXITSTATUS (prog_exit_status) != 0) - goto out; - - if (prog_stdout == NULL || strlen (prog_stdout) == 0) - goto out; - - ret = g_base64_decode (prog_stdout, out_smp_response_len); - if (ret == NULL) { - g_printerr ("Error decoding SMP response\n"); - goto out; - } + guchar *ret; + gchar *command_line; + gchar *prog_stdout; + gint prog_exit_status; + GError *error; + + ret = NULL; + error = NULL; + + command_line = g_strdup_printf ("sh -c '%s |base64 -w0'", smp_command_line); + if (!g_spawn_command_line_sync (command_line, &prog_stdout, NULL, &prog_exit_status, &error)) + { + g_printerr ("Error spawning `%s': %s", command_line, error->message); + g_error_free (error); + goto out; + } + + if (!WIFEXITED (prog_exit_status)) + goto out; + + if (WEXITSTATUS (prog_exit_status) != 0) + goto out; + + if (prog_stdout == NULL || strlen (prog_stdout) == 0) + goto out; + + ret = g_base64_decode (prog_stdout, out_smp_response_len); + if (ret == NULL) + { + g_printerr ("Error decoding SMP response\n"); + goto out; + } out: - g_free (command_line); - g_free (prog_stdout); - return ret; + g_free (command_line); + g_free (prog_stdout); + return ret; } gint -main (int argc, char *argv[]) +main (int argc, + char *argv[]) { - gint ret; - gchar *basename; - const gchar *sysfs_path; - gchar *bsg_name; - guchar *smp_response; - gsize smp_response_len; - gchar *s; - - ret = 1; - basename = NULL; - bsg_name = NULL; - smp_response = NULL; - - if (argc != 2) { - g_printerr ("Usage: %s \n", argv[0]); - goto out; - } - sysfs_path = argv[1]; - - basename = g_path_get_basename (sysfs_path); - bsg_name = g_strdup_printf ("/dev/bsg/%s", basename); - - s = g_strdup_printf ("smp_rep_manufacturer -r %s", bsg_name); - smp_response = do_smp_command (s, &smp_response_len); - g_free (s); - if (smp_response == NULL) - goto out; - - gchar *vendor; - gchar *model; - gchar *revision; - - /* 9.4.3.5 REPORT MANUFACTURER INFORMATION function: - * - * VENDOR IDENTIFICATION is 8 bytes of ASCII from bytes 12 through 19 - * PRODUCT IDENTIFICATION is 16 bytes of ASCII from bytes 20 through 35 - * PRODUCT REVISION LEVEL is 4 bytes of ASCII from bytes 36 through 39 - */ - vendor = g_strndup ((const gchar *) smp_response + 12, 8); - model = g_strndup ((const gchar *) smp_response + 20, 16); - revision = g_strndup ((const gchar *) smp_response + 36, 4); - - g_print ("ID_VENDOR=%s\n", vendor); - g_print ("ID_MODEL=%s\n", model); - g_print ("ID_REVISION=%s\n", revision); - - ret = 0; + gint ret; + gchar *basename; + const gchar *sysfs_path; + gchar *bsg_name; + guchar *smp_response; + gsize smp_response_len; + gchar *s; + + ret = 1; + basename = NULL; + bsg_name = NULL; + smp_response = NULL; + + if (argc != 2) + { + g_printerr ("Usage: %s \n", argv[0]); + goto out; + } + sysfs_path = argv[1]; + + basename = g_path_get_basename (sysfs_path); + bsg_name = g_strdup_printf ("/dev/bsg/%s", basename); + + s = g_strdup_printf ("smp_rep_manufacturer -r %s", bsg_name); + smp_response = do_smp_command (s, &smp_response_len); + g_free (s); + if (smp_response == NULL) + goto out; + + gchar *vendor; + gchar *model; + gchar *revision; + + /* 9.4.3.5 REPORT MANUFACTURER INFORMATION function: + * + * VENDOR IDENTIFICATION is 8 bytes of ASCII from bytes 12 through 19 + * PRODUCT IDENTIFICATION is 16 bytes of ASCII from bytes 20 through 35 + * PRODUCT REVISION LEVEL is 4 bytes of ASCII from bytes 36 through 39 + */ + vendor = g_strndup ((const gchar *) smp_response + 12, 8); + model = g_strndup ((const gchar *) smp_response + 20, 16); + revision = g_strndup ((const gchar *) smp_response + 36, 4); + + g_print ("ID_VENDOR=%s\n", vendor); + g_print ("ID_MODEL=%s\n", model); + g_print ("ID_REVISION=%s\n", revision); + + ret = 0; out: - g_free (basename); - g_free (bsg_name); - g_free (smp_response); - return ret; + g_free (basename); + g_free (bsg_name); + g_free (smp_response); + return ret; } diff --git a/src/probers/part-id.c b/src/probers/part-id.c index 64a4f42..d6aebbc 100644 --- a/src/probers/part-id.c +++ b/src/probers/part-id.c @@ -33,229 +33,256 @@ #include "helpers/partutil.h" static void -usage (int argc, char *argv[]) +usage (int argc, + char *argv[]) { - execlp ("man", "man", "part_id", NULL); - g_printerr ("Cannot show man page: %m\n"); - exit (1); + execlp ("man", "man", "part_id", NULL); + g_printerr ("Cannot show man page: %m\n"); + exit (1); } static int -sysfs_get_int (const char *dir, const char *attribute) +sysfs_get_int (const char *dir, + const char *attribute) { - int result; - char *contents; - char *filename; - - result = 0; - filename = g_build_filename (dir, attribute, NULL); - if (g_file_get_contents (filename, &contents, NULL, NULL)) { - result = strtol (contents, NULL, 0); - g_free (contents); - } - g_free (filename); - - - return result; + int result; + char *contents; + char *filename; + + result = 0; + filename = g_build_filename (dir, attribute, NULL); + if (g_file_get_contents (filename, &contents, NULL, NULL)) + { + result = strtol (contents, NULL, 0); + g_free (contents); + } + g_free (filename); + + return result; } static guint64 -sysfs_get_uint64 (const char *dir, const char *attribute) +sysfs_get_uint64 (const char *dir, + const char *attribute) { - guint64 result; - char *contents; - char *filename; - - result = 0; - filename = g_build_filename (dir, attribute, NULL); - if (g_file_get_contents (filename, &contents, NULL, NULL)) { - result = strtoll (contents, NULL, 0); - g_free (contents); - } - g_free (filename); - - return result; + guint64 result; + char *contents; + char *filename; + + result = 0; + filename = g_build_filename (dir, attribute, NULL); + if (g_file_get_contents (filename, &contents, NULL, NULL)) + { + result = strtoll (contents, NULL, 0); + g_free (contents); + } + g_free (filename); + + return result; } int -main (int argc, char *argv[]) +main (int argc, + char *argv[]) { - guint n; - gint fd; - gint partition_number; - gchar *devpath; - const gchar *device_file; - gchar *partition_table_device_file; - struct udev *udev; - PartitionTable *partition_table; - - udev = NULL; - devpath = NULL; - partition_table_device_file = NULL; - partition_table = NULL; - - udev = udev_new (); - if (udev == NULL) { - g_printerr ("Error initializing libudev: %m\n"); - goto out; + guint n; + gint fd; + gint partition_number; + gchar *devpath; + const gchar *device_file; + gchar *partition_table_device_file; + struct udev *udev; + PartitionTable *partition_table; + + udev = NULL; + devpath = NULL; + partition_table_device_file = NULL; + partition_table = NULL; + + udev = udev_new (); + if (udev == NULL) + { + g_printerr ("Error initializing libudev: %m\n"); + goto out; + } + + device_file = NULL; + for (n = 1; n < (guint) argc; n++) + { + if (strcmp (argv[n], "--help") == 0) + { + usage (argc, argv); + return 0; } - - device_file = NULL; - for (n = 1; n < (guint) argc; n++) { - if (strcmp (argv[n], "--help") == 0) { - usage (argc, argv); - return 0; - } else { - if (device_file != NULL) - usage (argc, argv); - device_file = argv[n]; - } - } - - if (device_file == NULL) { - g_printerr ("no device\n"); - goto out; + else + { + if (device_file != NULL) + usage (argc, argv); + device_file = argv[n]; } - - devpath = getenv ("DEVPATH"); - if (devpath != NULL) { - devpath = g_build_filename ("/sys", devpath, NULL); - } else { - struct udev_device *device; - struct stat statbuf; - - if (stat (device_file, &statbuf) != 0) { - g_printerr ("Error statting %s: %m\n", device_file); - goto out; - } - - device = udev_device_new_from_devnum (udev, 'b', statbuf.st_rdev); - if (device == NULL) { - g_printerr ("Error getting udev device for %s: %m\n", device_file); - goto out; - } - devpath = g_strdup (udev_device_get_syspath (device)); - udev_device_unref (device); + } + + if (device_file == NULL) + { + g_printerr ("no device\n"); + goto out; + } + + devpath = getenv ("DEVPATH"); + if (devpath != NULL) + { + devpath = g_build_filename ("/sys", devpath, NULL); + } + else + { + struct udev_device *device; + struct stat statbuf; + + if (stat (device_file, &statbuf) != 0) + { + g_printerr ("Error statting %s: %m\n", device_file); + goto out; } - partition_number = sysfs_get_int (devpath, "partition"); - - /* find device file for partition table device */ - if (partition_number > 0) { - struct udev_device *device; - gchar *partition_table_devpath; - - /* partition */ - partition_table_devpath = g_strdup (devpath); - for (n = strlen (partition_table_devpath) - 1; partition_table_devpath[n] != '/'; n--) - partition_table_devpath[n] = '\0'; - partition_table_devpath[n] = '\0'; - - device = udev_device_new_from_syspath (udev, partition_table_devpath); - if (device == NULL) { - g_printerr ("Error getting udev device for syspath %s: %m\n", partition_table_devpath); - goto out; - } - partition_table_device_file = g_strdup (udev_device_get_devnode (device)); - udev_device_unref (device); - if (partition_table_device_file == NULL) { - /* This Should Not Happen™, but was reported in a distribution upgrade - scenario, so handle it gracefully */ - g_printerr ("Error getting devnode from udev device path %s: %m\n", partition_table_devpath); - goto out; - } - g_free (partition_table_devpath); - } else { - /* not partition */ - partition_table_device_file = g_strdup (device_file); + device = udev_device_new_from_devnum (udev, 'b', statbuf.st_rdev); + if (device == NULL) + { + g_printerr ("Error getting udev device for %s: %m\n", device_file); + goto out; } - - fd = open (partition_table_device_file, O_RDONLY); - - /* TODO: right now we also use part_id to determine if media is available or not. This - * should probably be done elsewhere - */ - if (partition_number == 0) { - if (fd < 0) { - g_print ("UDISKS_MEDIA_AVAILABLE=0\n"); - } else { - g_print ("UDISKS_MEDIA_AVAILABLE=1\n"); - } + devpath = g_strdup (udev_device_get_syspath (device)); + udev_device_unref (device); + } + + partition_number = sysfs_get_int (devpath, "partition"); + + /* find device file for partition table device */ + if (partition_number > 0) + { + struct udev_device *device; + gchar *partition_table_devpath; + + /* partition */ + partition_table_devpath = g_strdup (devpath); + for (n = strlen (partition_table_devpath) - 1; partition_table_devpath[n] != '/'; n--) + partition_table_devpath[n] = '\0'; + partition_table_devpath[n] = '\0'; + + device = udev_device_new_from_syspath (udev, partition_table_devpath); + if (device == NULL) + { + g_printerr ("Error getting udev device for syspath %s: %m\n", partition_table_devpath); + goto out; } - - if (fd < 0) { - g_printerr ("Error opening %s: %m\n", partition_table_device_file); - goto out; + partition_table_device_file = g_strdup (udev_device_get_devnode (device)); + udev_device_unref (device); + if (partition_table_device_file == NULL) + { + /* This Should Not Happen™, but was reported in a distribution upgrade + scenario, so handle it gracefully */ + g_printerr ("Error getting devnode from udev device path %s: %m\n", partition_table_devpath); + goto out; } - partition_table = part_table_load_from_disk (fd); - if (partition_table == NULL) { - g_printerr ("No partition table found on %s: %m\n", partition_table_device_file); - goto out; + g_free (partition_table_devpath); + } + else + { + /* not partition */ + partition_table_device_file = g_strdup (device_file); + } + + fd = open (partition_table_device_file, O_RDONLY); + + /* TODO: right now we also use part_id to determine if media is available or not. This + * should probably be done elsewhere + */ + if (partition_number == 0) + { + if (fd < 0) + { + g_print ("UDISKS_MEDIA_AVAILABLE=0\n"); } - close (fd); - - if (partition_number > 0) { - guint64 partition_offset; - PartitionTable *partition_table_for_entry; - gint entry_num; - gchar *type; - gchar *label; - gchar *uuid; - gchar **flags; - gchar *flags_combined; - guint64 size; - - /* partition */ - partition_offset = sysfs_get_uint64 (devpath, "start") * 512; - part_table_find (partition_table, - partition_offset, - &partition_table_for_entry, - &entry_num); - if (entry_num == -1) { - g_printerr ("Error finding partition at offset %" G_GUINT64_FORMAT " on %s\n", - partition_offset, - partition_table_device_file); - goto out; - } - - type = part_table_entry_get_type (partition_table_for_entry, entry_num); - label = part_table_entry_get_label (partition_table_for_entry, entry_num); - uuid = part_table_entry_get_uuid (partition_table_for_entry, entry_num); - flags = part_table_entry_get_flags (partition_table_for_entry, entry_num); - size = part_table_entry_get_size (partition_table_for_entry, entry_num); - - flags_combined = g_strjoinv (" ", flags); - - g_print ("UDISKS_PARTITION=1\n"); - g_print ("UDISKS_PARTITION_SCHEME=%s\n", - //part_get_scheme_name (part_table_get_scheme (partition_table_for_entry))); - part_get_scheme_name (part_table_get_scheme (partition_table))); - g_print ("UDISKS_PARTITION_NUMBER=%d\n", partition_number); - g_print ("UDISKS_PARTITION_TYPE=%s\n", type != NULL ? type : ""); - g_print ("UDISKS_PARTITION_SIZE=%" G_GINT64_FORMAT "\n", size); - g_print ("UDISKS_PARTITION_LABEL=%s\n", label != NULL ? label : ""); - g_print ("UDISKS_PARTITION_UUID=%s\n", uuid != NULL ? uuid : ""); - g_print ("UDISKS_PARTITION_FLAGS=%s\n", flags_combined); - - g_free (type); - g_free (label); - g_free (uuid); - g_strfreev (flags); - g_free (flags_combined); - } else { - g_print ("UDISKS_PARTITION_TABLE=1\n"); - g_print ("UDISKS_PARTITION_TABLE_SCHEME=%s\n", - part_get_scheme_name (part_table_get_scheme (partition_table))); + else + { + g_print ("UDISKS_MEDIA_AVAILABLE=1\n"); + } + } + + if (fd < 0) + { + g_printerr ("Error opening %s: %m\n", partition_table_device_file); + goto out; + } + partition_table = part_table_load_from_disk (fd); + if (partition_table == NULL) + { + g_printerr ("No partition table found on %s: %m\n", partition_table_device_file); + goto out; + } + close (fd); + + if (partition_number > 0) + { + guint64 partition_offset; + PartitionTable *partition_table_for_entry; + gint entry_num; + gchar *type; + gchar *label; + gchar *uuid; + gchar **flags; + gchar *flags_combined; + guint64 size; + + /* partition */ + partition_offset = sysfs_get_uint64 (devpath, "start") * 512; + part_table_find (partition_table, partition_offset, &partition_table_for_entry, &entry_num); + if (entry_num == -1) + { + g_printerr ("Error finding partition at offset %" G_GUINT64_FORMAT " on %s\n", + partition_offset, + partition_table_device_file); + goto out; } -out: - g_free (devpath); - g_free (partition_table_device_file); - if (partition_table != NULL) - part_table_free (partition_table); - if (udev != NULL) - udev_unref (udev); - - return 0; + type = part_table_entry_get_type (partition_table_for_entry, entry_num); + label = part_table_entry_get_label (partition_table_for_entry, entry_num); + uuid = part_table_entry_get_uuid (partition_table_for_entry, entry_num); + flags = part_table_entry_get_flags (partition_table_for_entry, entry_num); + size = part_table_entry_get_size (partition_table_for_entry, entry_num); + + flags_combined = g_strjoinv (" ", flags); + + g_print ("UDISKS_PARTITION=1\n"); + g_print ("UDISKS_PARTITION_SCHEME=%s\n", + //part_get_scheme_name (part_table_get_scheme (partition_table_for_entry))); + part_get_scheme_name (part_table_get_scheme (partition_table))); + g_print ("UDISKS_PARTITION_NUMBER=%d\n", partition_number); + g_print ("UDISKS_PARTITION_TYPE=%s\n", type != NULL ? type : ""); + g_print ("UDISKS_PARTITION_SIZE=%" G_GINT64_FORMAT "\n", size); + g_print ("UDISKS_PARTITION_LABEL=%s\n", label != NULL ? label : ""); + g_print ("UDISKS_PARTITION_UUID=%s\n", uuid != NULL ? uuid : ""); + g_print ("UDISKS_PARTITION_FLAGS=%s\n", flags_combined); + + g_free (type); + g_free (label); + g_free (uuid); + g_strfreev (flags); + g_free (flags_combined); + } + else + { + g_print ("UDISKS_PARTITION_TABLE=1\n"); + g_print ("UDISKS_PARTITION_TABLE_SCHEME=%s\n", part_get_scheme_name (part_table_get_scheme (partition_table))); + } + + out: + g_free (devpath); + g_free (partition_table_device_file); + if (partition_table != NULL) + part_table_free (partition_table); + if (udev != NULL) + udev_unref (udev); + + return 0; } diff --git a/src/types.h b/src/types.h index 56d5875..f02a6fc 100644 --- a/src/types.h +++ b/src/types.h @@ -25,17 +25,15 @@ G_BEGIN_DECLS -typedef struct Daemon Daemon; - -typedef struct Device Device; -typedef struct Adapter Adapter; -typedef struct Expander Expander; -typedef struct Port Port; +typedef struct Daemon Daemon; +typedef struct Device Device; +typedef struct Adapter Adapter; +typedef struct Expander Expander; +typedef struct Port Port; typedef struct Mount Mount; typedef struct MountMonitor MountMonitor; typedef struct Inhibitor Inhibitor; -typedef struct AtaSmartDb AtaSmartDb; G_END_DECLS diff --git a/tools/udisks.c b/tools/udisks.c index b871d26..bbd5f1a 100644 --- a/tools/udisks.c +++ b/tools/udisks.c @@ -49,70 +49,67 @@ #include "udisks-device-glue.h" #include "udisks-marshal.h" -static DBusGConnection *bus = NULL; -static DBusGProxy *disks_proxy = NULL; -static GMainLoop *loop; - -static gboolean opt_dump = FALSE; -static gboolean opt_enumerate = FALSE; -static gboolean opt_enumerate_device_files = FALSE; -static gboolean opt_monitor = FALSE; -static gboolean opt_monitor_detail = FALSE; -static char *opt_show_info = NULL; -static char *opt_inhibit_polling = NULL; -static char *opt_poll_for_media = NULL; -static gboolean opt_inhibit = FALSE; -static gboolean opt_inhibit_all_polling = FALSE; -static char *opt_drive_spindown = NULL; -static gboolean opt_drive_spindown_all = FALSE; -static gint opt_spindown_seconds = 0; -static char *opt_mount = NULL; -static char *opt_mount_fstype = NULL; -static char *opt_mount_options = NULL; -static char *opt_unmount = NULL; -static char *opt_unmount_options = NULL; -static char *opt_detach = NULL; -static char *opt_detach_options = NULL; -static char *opt_ata_smart_refresh = NULL; -static gboolean opt_ata_smart_wakeup = FALSE; -static char *opt_ata_smart_simulate = NULL; - +static DBusGConnection *bus = NULL; +static DBusGProxy *disks_proxy = NULL; +static GMainLoop *loop; + +static gboolean opt_dump = FALSE; +static gboolean opt_enumerate = FALSE; +static gboolean opt_enumerate_device_files = FALSE; +static gboolean opt_monitor = FALSE; +static gboolean opt_monitor_detail = FALSE; +static char *opt_show_info = NULL; +static char *opt_inhibit_polling = NULL; +static char *opt_poll_for_media = NULL; +static gboolean opt_inhibit = FALSE; +static gboolean opt_inhibit_all_polling = FALSE; +static char *opt_drive_spindown = NULL; +static gboolean opt_drive_spindown_all = FALSE; +static gint opt_spindown_seconds = 0; +static char *opt_mount = NULL; +static char *opt_mount_fstype = NULL; +static char *opt_mount_options = NULL; +static char *opt_unmount = NULL; +static char *opt_unmount_options = NULL; +static char *opt_detach = NULL; +static char *opt_detach_options = NULL; +static char *opt_ata_smart_refresh = NULL; +static gboolean opt_ata_smart_wakeup = FALSE; +static char *opt_ata_smart_simulate = NULL; static gboolean do_monitor (void); static void do_show_info (const char *object_path); static void do_ata_smart_refresh (const gchar *object_path, - gboolean wakeup, + gboolean wakeup, const gchar *simulate_path) { - DBusGProxy *proxy; - GError *error; - GPtrArray *options; - - options = g_ptr_array_new (); - if (!wakeup) - g_ptr_array_add (options, g_strdup ("nowakeup")); - if (simulate_path != NULL) - g_ptr_array_add (options, g_strdup_printf ("simulate=%s", simulate_path)); - g_ptr_array_add (options, NULL); - - proxy = dbus_g_proxy_new_for_name (bus, - "org.freedesktop.UDisks", - object_path, - "org.freedesktop.UDisks.Device"); - error = NULL; - if (!org_freedesktop_UDisks_Device_drive_ata_smart_refresh_data (proxy, - (const char **) options->pdata, - &error)) { - g_print ("Refreshing ATA SMART data failed: %s\n", error->message); - g_error_free (error); - } else { - do_show_info (object_path); - } - - g_ptr_array_foreach (options, (GFunc) g_free, NULL); - g_ptr_array_free (options, TRUE); + DBusGProxy *proxy; + GError *error; + GPtrArray *options; + + options = g_ptr_array_new (); + if (!wakeup) + g_ptr_array_add (options, g_strdup ("nowakeup")); + if (simulate_path != NULL) + g_ptr_array_add (options, g_strdup_printf ("simulate=%s", simulate_path)); + g_ptr_array_add (options, NULL); + + proxy = dbus_g_proxy_new_for_name (bus, "org.freedesktop.UDisks", object_path, "org.freedesktop.UDisks.Device"); + error = NULL; + if (!org_freedesktop_UDisks_Device_drive_ata_smart_refresh_data (proxy, (const char **) options->pdata, &error)) + { + g_print ("Refreshing ATA SMART data failed: %s\n", error->message); + g_error_free (error); + } + else + { + do_show_info (object_path); + } + + g_ptr_array_foreach (options, (GFunc) g_free, NULL); + g_ptr_array_free (options, TRUE); } static void @@ -120,155 +117,153 @@ do_mount (const char *object_path, const char *filesystem_type, const char *options) { - char *mount_path; - DBusGProxy *proxy; - GError *error; - char **mount_options; - - mount_options = NULL; - if (options != NULL) - mount_options = g_strsplit (options, ",", 0); - - proxy = dbus_g_proxy_new_for_name (bus, - "org.freedesktop.UDisks", - object_path, - "org.freedesktop.UDisks.Device"); - error = NULL; - if (!org_freedesktop_UDisks_Device_filesystem_mount (proxy, - filesystem_type, - (const char **) mount_options, - &mount_path, - &error)) { - g_print ("Mount failed: %s\n", error->message); - g_error_free (error); - goto out; - } - - g_print ("Mounted %s at %s\n", object_path, mount_path); - g_free (mount_path); -out: - g_strfreev (mount_options); + char *mount_path; + DBusGProxy *proxy; + GError *error; + char **mount_options; + + mount_options = NULL; + if (options != NULL) + mount_options = g_strsplit (options, ",", 0); + + proxy = dbus_g_proxy_new_for_name (bus, "org.freedesktop.UDisks", object_path, "org.freedesktop.UDisks.Device"); + error = NULL; + if (!org_freedesktop_UDisks_Device_filesystem_mount (proxy, + filesystem_type, + (const char **) mount_options, + &mount_path, + &error)) + { + g_print ("Mount failed: %s\n", error->message); + g_error_free (error); + goto out; + } + + g_print ("Mounted %s at %s\n", object_path, mount_path); + g_free (mount_path); + out: + g_strfreev (mount_options); } static void do_unmount (const char *object_path, const char *options) { - DBusGProxy *proxy; - GError *error; - char **unmount_options; + DBusGProxy *proxy; + GError *error; + char **unmount_options; - unmount_options = NULL; - if (options != NULL) - unmount_options = g_strsplit (options, ",", 0); + unmount_options = NULL; + if (options != NULL) + unmount_options = g_strsplit (options, ",", 0); - proxy = dbus_g_proxy_new_for_name (bus, - "org.freedesktop.UDisks", - object_path, - "org.freedesktop.UDisks.Device"); - - error = NULL; - if (!org_freedesktop_UDisks_Device_filesystem_unmount (proxy, - (const char **) unmount_options, - &error)) { - g_print ("Unmount failed: %s\n", error->message); - g_error_free (error); - } + proxy = dbus_g_proxy_new_for_name (bus, "org.freedesktop.UDisks", object_path, "org.freedesktop.UDisks.Device"); + + error = NULL; + if (!org_freedesktop_UDisks_Device_filesystem_unmount (proxy, (const char **) unmount_options, &error)) + { + g_print ("Unmount failed: %s\n", error->message); + g_error_free (error); + } - g_strfreev (unmount_options); + g_strfreev (unmount_options); } static void do_detach (const char *object_path, const char *options) { - DBusGProxy *proxy; - GError *error; - char **unmount_options; + DBusGProxy *proxy; + GError *error; + char **unmount_options; - unmount_options = NULL; - if (options != NULL) - unmount_options = g_strsplit (options, ",", 0); + unmount_options = NULL; + if (options != NULL) + unmount_options = g_strsplit (options, ",", 0); - proxy = dbus_g_proxy_new_for_name (bus, - "org.freedesktop.UDisks", - object_path, - "org.freedesktop.UDisks.Device"); - - error = NULL; - if (!org_freedesktop_UDisks_Device_drive_detach (proxy, - (const char **) options, - &error)) { - g_print ("Detach failed: %s\n", error->message); - g_error_free (error); - } + proxy = dbus_g_proxy_new_for_name (bus, "org.freedesktop.UDisks", object_path, "org.freedesktop.UDisks.Device"); - g_strfreev (unmount_options); + error = NULL; + if (!org_freedesktop_UDisks_Device_drive_detach (proxy, (const char **) options, &error)) + { + g_print ("Detach failed: %s\n", error->message); + g_error_free (error); + } + + g_strfreev (unmount_options); } static void -device_added_signal_handler (DBusGProxy *proxy, const char *object_path, gpointer user_data) +device_added_signal_handler (DBusGProxy *proxy, + const char *object_path, + gpointer user_data) { g_print ("added: %s\n", object_path); - if (opt_monitor_detail) { - do_show_info (object_path); - g_print ("\n"); - } + if (opt_monitor_detail) + { + do_show_info (object_path); + g_print ("\n"); + } } static void -device_changed_signal_handler (DBusGProxy *proxy, const char *object_path, gpointer user_data) +device_changed_signal_handler (DBusGProxy *proxy, + const char *object_path, + gpointer user_data) { g_print ("changed: %s\n", object_path); - if (opt_monitor_detail) { - /* TODO: would be nice to just show the diff */ - do_show_info (object_path); - g_print ("\n"); - } + if (opt_monitor_detail) + { + /* TODO: would be nice to just show the diff */ + do_show_info (object_path); + g_print ("\n"); + } } static void -print_job (gboolean job_in_progress, +print_job (gboolean job_in_progress, const char *job_id, - uid_t job_initiated_by_uid, - gboolean job_is_cancellable, - double job_percentage) + uid_t job_initiated_by_uid, + gboolean job_is_cancellable, + double job_percentage) { - if (job_in_progress) { - g_print (" job underway: %s", job_id); - if (job_percentage >= 0) - g_print (", %3.0lf%% complete", job_percentage); - if (job_is_cancellable) - g_print (", cancellable"); - g_print (", initiated by uid %d", job_initiated_by_uid); - g_print ("\n"); - } else { - g_print (" job underway: no\n"); - } + if (job_in_progress) + { + g_print (" job underway: %s", job_id); + if (job_percentage >= 0) + g_print (", %3.0lf%% complete", job_percentage); + if (job_is_cancellable) + g_print (", cancellable"); + g_print (", initiated by uid %d", job_initiated_by_uid); + g_print ("\n"); + } + else + { + g_print (" job underway: no\n"); + } } static void device_job_changed_signal_handler (DBusGProxy *proxy, const char *object_path, - gboolean job_in_progress, + gboolean job_in_progress, const char *job_id, - guint32 job_initiated_by_uid, - gboolean job_is_cancellable, - double job_percentage, - gpointer user_data) + guint32 job_initiated_by_uid, + gboolean job_is_cancellable, + double job_percentage, + gpointer user_data) { g_print ("job-changed: %s\n", object_path); - if (opt_monitor_detail) { - print_job (job_in_progress, - job_id, - job_initiated_by_uid, - job_is_cancellable, - job_percentage); - } + if (opt_monitor_detail) + { + print_job (job_in_progress, job_id, job_initiated_by_uid, job_is_cancellable, job_percentage); + } } static void -device_removed_signal_handler (DBusGProxy *proxy, const char *object_path, gpointer user_data) +device_removed_signal_handler (DBusGProxy *proxy, + const char *object_path, + gpointer user_data) { g_print ("removed: %s\n", object_path); } @@ -279,7 +274,6 @@ device_removed_signal_handler (DBusGProxy *proxy, const char *object_path, gpoin G_TYPE_STRING, \ G_TYPE_INVALID)) - /* --- SUCKY CODE BEGIN --- */ /* This totally sucks; dbus-bindings-tool and dbus-glib should be able @@ -290,482 +284,486 @@ device_removed_signal_handler (DBusGProxy *proxy, const char *object_path, gpoin typedef struct { - char *native_path; - - guint64 device_detection_time; - guint64 device_media_detection_time; - gint64 device_major; - gint64 device_minor; - char *device_file; - char **device_file_by_id; - char **device_file_by_path; - gboolean device_is_system_internal; - gboolean device_is_partition; - gboolean device_is_partition_table; - gboolean device_is_removable; - gboolean device_is_media_available; - gboolean device_is_media_change_detected; - gboolean device_is_media_change_detection_polling; - gboolean device_is_media_change_detection_inhibitable; - gboolean device_is_media_change_detection_inhibited; - gboolean device_is_read_only; - gboolean device_is_drive; - gboolean device_is_optical_disc; - gboolean device_is_luks; - gboolean device_is_luks_cleartext; - gboolean device_is_mounted; - gboolean device_is_linux_md_component; - gboolean device_is_linux_md; - char **device_mount_paths; - uid_t device_mounted_by_uid; - gboolean device_presentation_hide; - gboolean device_presentation_nopolicy; - char *device_presentation_name; - char *device_presentation_icon_name; - guint64 device_size; - guint64 device_block_size; - - gboolean job_in_progress; - char *job_id; - uid_t job_initiated_by_uid; - gboolean job_is_cancellable; - double job_percentage; - - char *id_usage; - char *id_type; - char *id_version; - char *id_uuid; - char *id_label; - - char *partition_slave; - char *partition_scheme; - int partition_number; - char *partition_type; - char *partition_label; - char *partition_uuid; - char **partition_flags; - guint64 partition_offset; - guint64 partition_size; - - char *partition_table_scheme; - int partition_table_count; - - char *luks_holder; - - char *luks_cleartext_slave; - uid_t luks_cleartext_unlocked_by_uid; - - char *drive_vendor; - char *drive_model; - char *drive_revision; - char *drive_serial; - char *drive_wwn; - char *drive_connection_interface; - guint64 drive_connection_speed; - char **drive_media_compatibility; - char *drive_media; - gboolean drive_is_media_ejectable; - gboolean drive_can_detach; - gboolean drive_can_spindown; - gboolean drive_is_rotational; - guint drive_rotation_rate; - char *drive_write_cache; - char *drive_adapter; - char **drive_ports; - - gboolean optical_disc_is_blank; - gboolean optical_disc_is_appendable; - gboolean optical_disc_is_closed; - guint optical_disc_num_tracks; - guint optical_disc_num_audio_tracks; - guint optical_disc_num_sessions; - - gboolean drive_ata_smart_is_available; - guint64 drive_ata_smart_time_collected; - gchar *drive_ata_smart_status; - gchar *drive_ata_smart_blob; - gsize drive_ata_smart_blob_size; - - char *linux_md_component_level; - int linux_md_component_position; - int linux_md_component_num_raid_devices; - char *linux_md_component_uuid; - char *linux_md_component_home_host; - char *linux_md_component_name; - char *linux_md_component_version; - char *linux_md_component_holder; - char **linux_md_component_state; - - char *linux_md_state; - char *linux_md_level; - int linux_md_num_raid_devices; - char *linux_md_uuid; - char *linux_md_home_host; - char *linux_md_name; - char *linux_md_version; - char **linux_md_slaves; - gboolean linux_md_is_degraded; - char *linux_md_sync_action; - double linux_md_sync_percentage; - guint64 linux_md_sync_speed; + char *native_path; + + guint64 device_detection_time; + guint64 device_media_detection_time; + gint64 device_major; + gint64 device_minor; + char *device_file; + char **device_file_by_id; + char **device_file_by_path; + gboolean device_is_system_internal; + gboolean device_is_partition; + gboolean device_is_partition_table; + gboolean device_is_removable; + gboolean device_is_media_available; + gboolean device_is_media_change_detected; + gboolean device_is_media_change_detection_polling; + gboolean device_is_media_change_detection_inhibitable; + gboolean device_is_media_change_detection_inhibited; + gboolean device_is_read_only; + gboolean device_is_drive; + gboolean device_is_optical_disc; + gboolean device_is_luks; + gboolean device_is_luks_cleartext; + gboolean device_is_mounted; + gboolean device_is_linux_md_component; + gboolean device_is_linux_md; + char **device_mount_paths; + uid_t device_mounted_by_uid; + gboolean device_presentation_hide; + gboolean device_presentation_nopolicy; + char *device_presentation_name; + char *device_presentation_icon_name; + guint64 device_size; + guint64 device_block_size; + + gboolean job_in_progress; + char *job_id; + uid_t job_initiated_by_uid; + gboolean job_is_cancellable; + double job_percentage; + + char *id_usage; + char *id_type; + char *id_version; + char *id_uuid; + char *id_label; + + char *partition_slave; + char *partition_scheme; + int partition_number; + char *partition_type; + char *partition_label; + char *partition_uuid; + char **partition_flags; + guint64 partition_offset; + guint64 partition_size; + + char *partition_table_scheme; + int partition_table_count; + + char *luks_holder; + + char *luks_cleartext_slave; + uid_t luks_cleartext_unlocked_by_uid; + + char *drive_vendor; + char *drive_model; + char *drive_revision; + char *drive_serial; + char *drive_wwn; + char *drive_connection_interface; + guint64 drive_connection_speed; + char **drive_media_compatibility; + char *drive_media; + gboolean drive_is_media_ejectable; + gboolean drive_can_detach; + gboolean drive_can_spindown; + gboolean drive_is_rotational; + guint drive_rotation_rate; + char *drive_write_cache; + char *drive_adapter; + char **drive_ports; + + gboolean optical_disc_is_blank; + gboolean optical_disc_is_appendable; + gboolean optical_disc_is_closed; + guint optical_disc_num_tracks; + guint optical_disc_num_audio_tracks; + guint optical_disc_num_sessions; + + gboolean drive_ata_smart_is_available; + guint64 drive_ata_smart_time_collected; + gchar *drive_ata_smart_status; + gchar *drive_ata_smart_blob; + gsize drive_ata_smart_blob_size; + + char *linux_md_component_level; + int linux_md_component_position; + int linux_md_component_num_raid_devices; + char *linux_md_component_uuid; + char *linux_md_component_home_host; + char *linux_md_component_name; + char *linux_md_component_version; + char *linux_md_component_holder; + char **linux_md_component_state; + + char *linux_md_state; + char *linux_md_level; + int linux_md_num_raid_devices; + char *linux_md_uuid; + char *linux_md_home_host; + char *linux_md_name; + char *linux_md_version; + char **linux_md_slaves; + gboolean linux_md_is_degraded; + char *linux_md_sync_action; + double linux_md_sync_percentage; + guint64 linux_md_sync_speed; } DeviceProperties; static void -collect_props (const char *key, const GValue *value, DeviceProperties *props) +collect_props (const char *key, + const GValue *value, + DeviceProperties *props) { - gboolean handled = TRUE; - - if (strcmp (key, "NativePath") == 0) - props->native_path = g_strdup (g_value_get_string (value)); - - else if (strcmp (key, "DeviceDetectionTime") == 0) - props->device_detection_time = g_value_get_uint64 (value); - else if (strcmp (key, "DeviceMediaDetectionTime") == 0) - props->device_media_detection_time = g_value_get_uint64 (value); - else if (strcmp (key, "DeviceMajor") == 0) - props->device_major = g_value_get_int64 (value); - else if (strcmp (key, "DeviceMinor") == 0) - props->device_minor = g_value_get_int64 (value); - else if (strcmp (key, "DeviceFile") == 0) - props->device_file = g_strdup (g_value_get_string (value)); - else if (strcmp (key, "DeviceFileById") == 0) - props->device_file_by_id = g_strdupv (g_value_get_boxed (value)); - else if (strcmp (key, "DeviceFileByPath") == 0) - props->device_file_by_path = g_strdupv (g_value_get_boxed (value)); - else if (strcmp (key, "DeviceIsSystemInternal") == 0) - props->device_is_system_internal = g_value_get_boolean (value); - else if (strcmp (key, "DeviceIsPartition") == 0) - props->device_is_partition = g_value_get_boolean (value); - else if (strcmp (key, "DeviceIsPartitionTable") == 0) - props->device_is_partition_table = g_value_get_boolean (value); - else if (strcmp (key, "DeviceIsRemovable") == 0) - props->device_is_removable = g_value_get_boolean (value); - else if (strcmp (key, "DeviceIsMediaAvailable") == 0) - props->device_is_media_available = g_value_get_boolean (value); - else if (strcmp (key, "DeviceIsMediaChangeDetected") == 0) - props->device_is_media_change_detected = g_value_get_boolean (value); - else if (strcmp (key, "DeviceIsMediaChangeDetectionPolling") == 0) - props->device_is_media_change_detection_polling = g_value_get_boolean (value); - else if (strcmp (key, "DeviceIsMediaChangeDetectionInhibitable") == 0) - props->device_is_media_change_detection_inhibitable = g_value_get_boolean (value); - else if (strcmp (key, "DeviceIsMediaChangeDetectionInhibited") == 0) - props->device_is_media_change_detection_inhibited = g_value_get_boolean (value); - else if (strcmp (key, "DeviceIsReadOnly") == 0) - props->device_is_read_only = g_value_get_boolean (value); - else if (strcmp (key, "DeviceIsDrive") == 0) - props->device_is_drive = g_value_get_boolean (value); - else if (strcmp (key, "DeviceIsOpticalDisc") == 0) - props->device_is_optical_disc = g_value_get_boolean (value); - else if (strcmp (key, "DeviceIsLuks") == 0) - props->device_is_luks = g_value_get_boolean (value); - else if (strcmp (key, "DeviceIsLuksCleartext") == 0) - props->device_is_luks_cleartext = g_value_get_boolean (value); - else if (strcmp (key, "DeviceIsLinuxMdComponent") == 0) - props->device_is_linux_md_component = g_value_get_boolean (value); - else if (strcmp (key, "DeviceIsLinuxMd") == 0) - props->device_is_linux_md = g_value_get_boolean (value); - else if (strcmp (key, "DeviceIsMounted") == 0) - props->device_is_mounted = g_value_get_boolean (value); - else if (strcmp (key, "DeviceMountPaths") == 0) - props->device_mount_paths = g_strdupv (g_value_get_boxed (value)); - else if (strcmp (key, "DeviceMountedByUid") == 0) - props->device_mounted_by_uid = g_value_get_uint (value); - else if (strcmp (key, "DevicePresentationHide") == 0) - props->device_presentation_hide = g_value_get_boolean (value); - else if (strcmp (key, "DevicePresentationNopolicy") == 0) - props->device_presentation_nopolicy = g_value_get_boolean (value); - else if (strcmp (key, "DevicePresentationName") == 0) - props->device_presentation_name = g_strdup (g_value_get_string (value)); - else if (strcmp (key, "DevicePresentationIconName") == 0) - props->device_presentation_icon_name = g_strdup (g_value_get_string (value)); - else if (strcmp (key, "DeviceSize") == 0) - props->device_size = g_value_get_uint64 (value); - else if (strcmp (key, "DeviceBlockSize") == 0) - props->device_block_size = g_value_get_uint64 (value); - - else if (strcmp (key, "JobInProgress") == 0) - props->job_in_progress = g_value_get_boolean (value); - else if (strcmp (key, "JobId") == 0) - props->job_id = g_strdup (g_value_get_string (value)); - else if (strcmp (key, "JobInitiatedByUid") == 0) - props->job_initiated_by_uid = g_value_get_uint (value); - else if (strcmp (key, "JobIsCancellable") == 0) - props->job_is_cancellable = g_value_get_boolean (value); - else if (strcmp (key, "JobPercentage") == 0) - props->job_percentage = g_value_get_double (value); - - else if (strcmp (key, "IdUsage") == 0) - props->id_usage = g_strdup (g_value_get_string (value)); - else if (strcmp (key, "IdType") == 0) - props->id_type = g_strdup (g_value_get_string (value)); - else if (strcmp (key, "IdVersion") == 0) - props->id_version = g_strdup (g_value_get_string (value)); - else if (strcmp (key, "IdUuid") == 0) - props->id_uuid = g_strdup (g_value_get_string (value)); - else if (strcmp (key, "IdLabel") == 0) - props->id_label = g_strdup (g_value_get_string (value)); - - else if (strcmp (key, "PartitionSlave") == 0) - props->partition_slave = g_strdup (g_value_get_boxed (value)); - else if (strcmp (key, "PartitionScheme") == 0) - props->partition_scheme = g_strdup (g_value_get_string (value)); - else if (strcmp (key, "PartitionNumber") == 0) - props->partition_number = g_value_get_int (value); - else if (strcmp (key, "PartitionType") == 0) - props->partition_type = g_strdup (g_value_get_string (value)); - else if (strcmp (key, "PartitionLabel") == 0) - props->partition_label = g_strdup (g_value_get_string (value)); - else if (strcmp (key, "PartitionUuid") == 0) - props->partition_uuid = g_strdup (g_value_get_string (value)); - else if (strcmp (key, "PartitionFlags") == 0) - props->partition_flags = g_strdupv (g_value_get_boxed (value)); - else if (strcmp (key, "PartitionOffset") == 0) - props->partition_offset = g_value_get_uint64 (value); - else if (strcmp (key, "PartitionSize") == 0) - props->partition_size = g_value_get_uint64 (value); - - else if (strcmp (key, "PartitionTableScheme") == 0) - props->partition_table_scheme = g_strdup (g_value_get_string (value)); - else if (strcmp (key, "PartitionTableCount") == 0) - props->partition_table_count = g_value_get_int (value); - - else if (strcmp (key, "LuksHolder") == 0) - props->luks_holder = g_strdup (g_value_get_boxed (value)); - - else if (strcmp (key, "LuksCleartextSlave") == 0) - props->luks_cleartext_slave = g_strdup (g_value_get_boxed (value)); - else if (strcmp (key, "LuksCleartextUnlockedByUid") == 0) - props->luks_cleartext_unlocked_by_uid = g_value_get_uint (value); - - else if (strcmp (key, "DriveVendor") == 0) - props->drive_vendor = g_strdup (g_value_get_string (value)); - else if (strcmp (key, "DriveModel") == 0) - props->drive_model = g_strdup (g_value_get_string (value)); - else if (strcmp (key, "DriveRevision") == 0) - props->drive_revision = g_strdup (g_value_get_string (value)); - else if (strcmp (key, "DriveSerial") == 0) - props->drive_serial = g_strdup (g_value_get_string (value)); - else if (strcmp (key, "DriveWwn") == 0) - props->drive_wwn = g_strdup (g_value_get_string (value)); - else if (strcmp (key, "DriveConnectionInterface") == 0) - props->drive_connection_interface = g_strdup (g_value_get_string (value)); - else if (strcmp (key, "DriveConnectionSpeed") == 0) - props->drive_connection_speed = g_value_get_uint64 (value); - else if (strcmp (key, "DriveMediaCompatibility") == 0) - props->drive_media_compatibility = g_strdupv (g_value_get_boxed (value)); - else if (strcmp (key, "DriveMedia") == 0) - props->drive_media = g_strdup (g_value_get_string (value)); - else if (strcmp (key, "DriveIsMediaEjectable") == 0) - props->drive_is_media_ejectable = g_value_get_boolean (value); - else if (strcmp (key, "DriveCanDetach") == 0) - props->drive_can_detach = g_value_get_boolean (value); - else if (strcmp (key, "DriveCanSpindown") == 0) - props->drive_can_spindown = g_value_get_boolean (value); - else if (strcmp (key, "DriveIsRotational") == 0) - props->drive_is_rotational = g_value_get_boolean (value); - else if (strcmp (key, "DriveRotationRate") == 0) - props->drive_rotation_rate = g_value_get_uint (value); - else if (strcmp (key, "DriveWriteCache") == 0) - props->drive_write_cache = g_strdup (g_value_get_string (value)); - else if (strcmp (key, "DriveAdapter") == 0) - props->drive_adapter = g_strdup (g_value_get_boxed (value)); - else if (strcmp (key, "DrivePorts") == 0) { - guint n; - GPtrArray *object_paths; - - object_paths = g_value_get_boxed (value); - - props->drive_ports = g_new0 (char *, object_paths->len + 1); - for (n = 0; n < object_paths->len; n++) - props->drive_ports[n] = g_strdup (object_paths->pdata[n]); - props->drive_ports[n] = NULL; - } - - else if (strcmp (key, "OpticalDiscIsBlank") == 0) - props->optical_disc_is_blank = g_value_get_boolean (value); - else if (strcmp (key, "OpticalDiscIsAppendable") == 0) - props->optical_disc_is_appendable = g_value_get_boolean (value); - else if (strcmp (key, "OpticalDiscIsClosed") == 0) - props->optical_disc_is_closed = g_value_get_boolean (value); - else if (strcmp (key, "OpticalDiscNumTracks") == 0) - props->optical_disc_num_tracks = g_value_get_uint (value); - else if (strcmp (key, "OpticalDiscNumAudioTracks") == 0) - props->optical_disc_num_audio_tracks = g_value_get_uint (value); - else if (strcmp (key, "OpticalDiscNumSessions") == 0) - props->optical_disc_num_sessions = g_value_get_uint (value); - - else if (strcmp (key, "DriveAtaSmartIsAvailable") == 0) - props->drive_ata_smart_is_available = g_value_get_boolean (value); - else if (strcmp (key, "DriveAtaSmartTimeCollected") == 0) - props->drive_ata_smart_time_collected = g_value_get_uint64 (value); - else if (strcmp (key, "DriveAtaSmartStatus") == 0) - props->drive_ata_smart_status = g_strdup (g_value_get_string (value)); - else if (strcmp (key, "DriveAtaSmartBlob") == 0) { - GArray *a = g_value_get_boxed (value); - g_free (props->drive_ata_smart_blob); - props->drive_ata_smart_blob = g_memdup (a->data, a->len); - props->drive_ata_smart_blob_size = a->len; - } - - else if (strcmp (key, "LinuxMdComponentLevel") == 0) - props->linux_md_component_level = g_strdup (g_value_get_string (value)); - else if (strcmp (key, "LinuxMdComponentPosition") == 0) - props->linux_md_component_position = g_value_get_int (value); - else if (strcmp (key, "LinuxMdComponentNumRaidDevices") == 0) - props->linux_md_component_num_raid_devices = g_value_get_int (value); - else if (strcmp (key, "LinuxMdComponentUuid") == 0) - props->linux_md_component_uuid = g_strdup (g_value_get_string (value)); - else if (strcmp (key, "LinuxMdComponentHomeHost") == 0) - props->linux_md_component_home_host = g_strdup (g_value_get_string (value)); - else if (strcmp (key, "LinuxMdComponentName") == 0) - props->linux_md_component_name = g_strdup (g_value_get_string (value)); - else if (strcmp (key, "LinuxMdComponentVersion") == 0) - props->linux_md_component_version = g_strdup (g_value_get_string (value)); - else if (strcmp (key, "LinuxMdComponentHolder") == 0) - props->linux_md_component_holder = g_strdup (g_value_get_boxed (value)); - else if (strcmp (key, "LinuxMdComponentState") == 0) - props->linux_md_component_state = g_strdupv (g_value_get_boxed (value)); - - else if (strcmp (key, "LinuxMdState") == 0) - props->linux_md_state = g_strdup (g_value_get_string (value)); - else if (strcmp (key, "LinuxMdLevel") == 0) - props->linux_md_level = g_strdup (g_value_get_string (value)); - else if (strcmp (key, "LinuxMdNumRaidDevices") == 0) - props->linux_md_num_raid_devices = g_value_get_int (value); - else if (strcmp (key, "LinuxMdUuid") == 0) - props->linux_md_uuid = g_strdup (g_value_get_string (value)); - else if (strcmp (key, "LinuxMdHomeHost") == 0) - props->linux_md_home_host = g_strdup (g_value_get_string (value)); - else if (strcmp (key, "LinuxMdName") == 0) - props->linux_md_name = g_strdup (g_value_get_string (value)); - else if (strcmp (key, "LinuxMdVersion") == 0) - props->linux_md_version = g_strdup (g_value_get_string (value)); - else if (strcmp (key, "LinuxMdSlaves") == 0) { - guint n; - GPtrArray *object_paths; - - object_paths = g_value_get_boxed (value); - - props->linux_md_slaves = g_new0 (char *, object_paths->len + 1); - for (n = 0; n < object_paths->len; n++) - props->linux_md_slaves[n] = g_strdup (object_paths->pdata[n]); - props->linux_md_slaves[n] = NULL; - } - else if (strcmp (key, "LinuxMdIsDegraded") == 0) - props->linux_md_is_degraded = g_value_get_boolean (value); - else if (strcmp (key, "LinuxMdSyncAction") == 0) - props->linux_md_sync_action = g_strdup (g_value_get_string (value)); - else if (strcmp (key, "LinuxMdSyncPercentage") == 0) - props->linux_md_sync_percentage = g_value_get_double (value); - else if (strcmp (key, "LinuxMdSyncSpeed") == 0) - props->linux_md_sync_speed = g_value_get_uint64 (value); - - else - handled = FALSE; - - if (!handled) - g_warning ("unhandled property '%s'", key); + gboolean handled = TRUE; + + if (strcmp (key, "NativePath") == 0) + props->native_path = g_strdup (g_value_get_string (value)); + + else if (strcmp (key, "DeviceDetectionTime") == 0) + props->device_detection_time = g_value_get_uint64 (value); + else if (strcmp (key, "DeviceMediaDetectionTime") == 0) + props->device_media_detection_time = g_value_get_uint64 (value); + else if (strcmp (key, "DeviceMajor") == 0) + props->device_major = g_value_get_int64 (value); + else if (strcmp (key, "DeviceMinor") == 0) + props->device_minor = g_value_get_int64 (value); + else if (strcmp (key, "DeviceFile") == 0) + props->device_file = g_strdup (g_value_get_string (value)); + else if (strcmp (key, "DeviceFileById") == 0) + props->device_file_by_id = g_strdupv (g_value_get_boxed (value)); + else if (strcmp (key, "DeviceFileByPath") == 0) + props->device_file_by_path = g_strdupv (g_value_get_boxed (value)); + else if (strcmp (key, "DeviceIsSystemInternal") == 0) + props->device_is_system_internal = g_value_get_boolean (value); + else if (strcmp (key, "DeviceIsPartition") == 0) + props->device_is_partition = g_value_get_boolean (value); + else if (strcmp (key, "DeviceIsPartitionTable") == 0) + props->device_is_partition_table = g_value_get_boolean (value); + else if (strcmp (key, "DeviceIsRemovable") == 0) + props->device_is_removable = g_value_get_boolean (value); + else if (strcmp (key, "DeviceIsMediaAvailable") == 0) + props->device_is_media_available = g_value_get_boolean (value); + else if (strcmp (key, "DeviceIsMediaChangeDetected") == 0) + props->device_is_media_change_detected = g_value_get_boolean (value); + else if (strcmp (key, "DeviceIsMediaChangeDetectionPolling") == 0) + props->device_is_media_change_detection_polling = g_value_get_boolean (value); + else if (strcmp (key, "DeviceIsMediaChangeDetectionInhibitable") == 0) + props->device_is_media_change_detection_inhibitable = g_value_get_boolean (value); + else if (strcmp (key, "DeviceIsMediaChangeDetectionInhibited") == 0) + props->device_is_media_change_detection_inhibited = g_value_get_boolean (value); + else if (strcmp (key, "DeviceIsReadOnly") == 0) + props->device_is_read_only = g_value_get_boolean (value); + else if (strcmp (key, "DeviceIsDrive") == 0) + props->device_is_drive = g_value_get_boolean (value); + else if (strcmp (key, "DeviceIsOpticalDisc") == 0) + props->device_is_optical_disc = g_value_get_boolean (value); + else if (strcmp (key, "DeviceIsLuks") == 0) + props->device_is_luks = g_value_get_boolean (value); + else if (strcmp (key, "DeviceIsLuksCleartext") == 0) + props->device_is_luks_cleartext = g_value_get_boolean (value); + else if (strcmp (key, "DeviceIsLinuxMdComponent") == 0) + props->device_is_linux_md_component = g_value_get_boolean (value); + else if (strcmp (key, "DeviceIsLinuxMd") == 0) + props->device_is_linux_md = g_value_get_boolean (value); + else if (strcmp (key, "DeviceIsMounted") == 0) + props->device_is_mounted = g_value_get_boolean (value); + else if (strcmp (key, "DeviceMountPaths") == 0) + props->device_mount_paths = g_strdupv (g_value_get_boxed (value)); + else if (strcmp (key, "DeviceMountedByUid") == 0) + props->device_mounted_by_uid = g_value_get_uint (value); + else if (strcmp (key, "DevicePresentationHide") == 0) + props->device_presentation_hide = g_value_get_boolean (value); + else if (strcmp (key, "DevicePresentationNopolicy") == 0) + props->device_presentation_nopolicy = g_value_get_boolean (value); + else if (strcmp (key, "DevicePresentationName") == 0) + props->device_presentation_name = g_strdup (g_value_get_string (value)); + else if (strcmp (key, "DevicePresentationIconName") == 0) + props->device_presentation_icon_name = g_strdup (g_value_get_string (value)); + else if (strcmp (key, "DeviceSize") == 0) + props->device_size = g_value_get_uint64 (value); + else if (strcmp (key, "DeviceBlockSize") == 0) + props->device_block_size = g_value_get_uint64 (value); + + else if (strcmp (key, "JobInProgress") == 0) + props->job_in_progress = g_value_get_boolean (value); + else if (strcmp (key, "JobId") == 0) + props->job_id = g_strdup (g_value_get_string (value)); + else if (strcmp (key, "JobInitiatedByUid") == 0) + props->job_initiated_by_uid = g_value_get_uint (value); + else if (strcmp (key, "JobIsCancellable") == 0) + props->job_is_cancellable = g_value_get_boolean (value); + else if (strcmp (key, "JobPercentage") == 0) + props->job_percentage = g_value_get_double (value); + + else if (strcmp (key, "IdUsage") == 0) + props->id_usage = g_strdup (g_value_get_string (value)); + else if (strcmp (key, "IdType") == 0) + props->id_type = g_strdup (g_value_get_string (value)); + else if (strcmp (key, "IdVersion") == 0) + props->id_version = g_strdup (g_value_get_string (value)); + else if (strcmp (key, "IdUuid") == 0) + props->id_uuid = g_strdup (g_value_get_string (value)); + else if (strcmp (key, "IdLabel") == 0) + props->id_label = g_strdup (g_value_get_string (value)); + + else if (strcmp (key, "PartitionSlave") == 0) + props->partition_slave = g_strdup (g_value_get_boxed (value)); + else if (strcmp (key, "PartitionScheme") == 0) + props->partition_scheme = g_strdup (g_value_get_string (value)); + else if (strcmp (key, "PartitionNumber") == 0) + props->partition_number = g_value_get_int (value); + else if (strcmp (key, "PartitionType") == 0) + props->partition_type = g_strdup (g_value_get_string (value)); + else if (strcmp (key, "PartitionLabel") == 0) + props->partition_label = g_strdup (g_value_get_string (value)); + else if (strcmp (key, "PartitionUuid") == 0) + props->partition_uuid = g_strdup (g_value_get_string (value)); + else if (strcmp (key, "PartitionFlags") == 0) + props->partition_flags = g_strdupv (g_value_get_boxed (value)); + else if (strcmp (key, "PartitionOffset") == 0) + props->partition_offset = g_value_get_uint64 (value); + else if (strcmp (key, "PartitionSize") == 0) + props->partition_size = g_value_get_uint64 (value); + + else if (strcmp (key, "PartitionTableScheme") == 0) + props->partition_table_scheme = g_strdup (g_value_get_string (value)); + else if (strcmp (key, "PartitionTableCount") == 0) + props->partition_table_count = g_value_get_int (value); + + else if (strcmp (key, "LuksHolder") == 0) + props->luks_holder = g_strdup (g_value_get_boxed (value)); + + else if (strcmp (key, "LuksCleartextSlave") == 0) + props->luks_cleartext_slave = g_strdup (g_value_get_boxed (value)); + else if (strcmp (key, "LuksCleartextUnlockedByUid") == 0) + props->luks_cleartext_unlocked_by_uid = g_value_get_uint (value); + + else if (strcmp (key, "DriveVendor") == 0) + props->drive_vendor = g_strdup (g_value_get_string (value)); + else if (strcmp (key, "DriveModel") == 0) + props->drive_model = g_strdup (g_value_get_string (value)); + else if (strcmp (key, "DriveRevision") == 0) + props->drive_revision = g_strdup (g_value_get_string (value)); + else if (strcmp (key, "DriveSerial") == 0) + props->drive_serial = g_strdup (g_value_get_string (value)); + else if (strcmp (key, "DriveWwn") == 0) + props->drive_wwn = g_strdup (g_value_get_string (value)); + else if (strcmp (key, "DriveConnectionInterface") == 0) + props->drive_connection_interface = g_strdup (g_value_get_string (value)); + else if (strcmp (key, "DriveConnectionSpeed") == 0) + props->drive_connection_speed = g_value_get_uint64 (value); + else if (strcmp (key, "DriveMediaCompatibility") == 0) + props->drive_media_compatibility = g_strdupv (g_value_get_boxed (value)); + else if (strcmp (key, "DriveMedia") == 0) + props->drive_media = g_strdup (g_value_get_string (value)); + else if (strcmp (key, "DriveIsMediaEjectable") == 0) + props->drive_is_media_ejectable = g_value_get_boolean (value); + else if (strcmp (key, "DriveCanDetach") == 0) + props->drive_can_detach = g_value_get_boolean (value); + else if (strcmp (key, "DriveCanSpindown") == 0) + props->drive_can_spindown = g_value_get_boolean (value); + else if (strcmp (key, "DriveIsRotational") == 0) + props->drive_is_rotational = g_value_get_boolean (value); + else if (strcmp (key, "DriveRotationRate") == 0) + props->drive_rotation_rate = g_value_get_uint (value); + else if (strcmp (key, "DriveWriteCache") == 0) + props->drive_write_cache = g_strdup (g_value_get_string (value)); + else if (strcmp (key, "DriveAdapter") == 0) + props->drive_adapter = g_strdup (g_value_get_boxed (value)); + else if (strcmp (key, "DrivePorts") == 0) + { + guint n; + GPtrArray *object_paths; + + object_paths = g_value_get_boxed (value); + + props->drive_ports = g_new0 (char *, object_paths->len + 1); + for (n = 0; n < object_paths->len; n++) + props->drive_ports[n] = g_strdup (object_paths->pdata[n]); + props->drive_ports[n] = NULL; + } + + else if (strcmp (key, "OpticalDiscIsBlank") == 0) + props->optical_disc_is_blank = g_value_get_boolean (value); + else if (strcmp (key, "OpticalDiscIsAppendable") == 0) + props->optical_disc_is_appendable = g_value_get_boolean (value); + else if (strcmp (key, "OpticalDiscIsClosed") == 0) + props->optical_disc_is_closed = g_value_get_boolean (value); + else if (strcmp (key, "OpticalDiscNumTracks") == 0) + props->optical_disc_num_tracks = g_value_get_uint (value); + else if (strcmp (key, "OpticalDiscNumAudioTracks") == 0) + props->optical_disc_num_audio_tracks = g_value_get_uint (value); + else if (strcmp (key, "OpticalDiscNumSessions") == 0) + props->optical_disc_num_sessions = g_value_get_uint (value); + + else if (strcmp (key, "DriveAtaSmartIsAvailable") == 0) + props->drive_ata_smart_is_available = g_value_get_boolean (value); + else if (strcmp (key, "DriveAtaSmartTimeCollected") == 0) + props->drive_ata_smart_time_collected = g_value_get_uint64 (value); + else if (strcmp (key, "DriveAtaSmartStatus") == 0) + props->drive_ata_smart_status = g_strdup (g_value_get_string (value)); + else if (strcmp (key, "DriveAtaSmartBlob") == 0) + { + GArray *a = g_value_get_boxed (value); + g_free (props->drive_ata_smart_blob); + props->drive_ata_smart_blob = g_memdup (a->data, a->len); + props->drive_ata_smart_blob_size = a->len; + } + + else if (strcmp (key, "LinuxMdComponentLevel") == 0) + props->linux_md_component_level = g_strdup (g_value_get_string (value)); + else if (strcmp (key, "LinuxMdComponentPosition") == 0) + props->linux_md_component_position = g_value_get_int (value); + else if (strcmp (key, "LinuxMdComponentNumRaidDevices") == 0) + props->linux_md_component_num_raid_devices = g_value_get_int (value); + else if (strcmp (key, "LinuxMdComponentUuid") == 0) + props->linux_md_component_uuid = g_strdup (g_value_get_string (value)); + else if (strcmp (key, "LinuxMdComponentHomeHost") == 0) + props->linux_md_component_home_host = g_strdup (g_value_get_string (value)); + else if (strcmp (key, "LinuxMdComponentName") == 0) + props->linux_md_component_name = g_strdup (g_value_get_string (value)); + else if (strcmp (key, "LinuxMdComponentVersion") == 0) + props->linux_md_component_version = g_strdup (g_value_get_string (value)); + else if (strcmp (key, "LinuxMdComponentHolder") == 0) + props->linux_md_component_holder = g_strdup (g_value_get_boxed (value)); + else if (strcmp (key, "LinuxMdComponentState") == 0) + props->linux_md_component_state = g_strdupv (g_value_get_boxed (value)); + + else if (strcmp (key, "LinuxMdState") == 0) + props->linux_md_state = g_strdup (g_value_get_string (value)); + else if (strcmp (key, "LinuxMdLevel") == 0) + props->linux_md_level = g_strdup (g_value_get_string (value)); + else if (strcmp (key, "LinuxMdNumRaidDevices") == 0) + props->linux_md_num_raid_devices = g_value_get_int (value); + else if (strcmp (key, "LinuxMdUuid") == 0) + props->linux_md_uuid = g_strdup (g_value_get_string (value)); + else if (strcmp (key, "LinuxMdHomeHost") == 0) + props->linux_md_home_host = g_strdup (g_value_get_string (value)); + else if (strcmp (key, "LinuxMdName") == 0) + props->linux_md_name = g_strdup (g_value_get_string (value)); + else if (strcmp (key, "LinuxMdVersion") == 0) + props->linux_md_version = g_strdup (g_value_get_string (value)); + else if (strcmp (key, "LinuxMdSlaves") == 0) + { + guint n; + GPtrArray *object_paths; + + object_paths = g_value_get_boxed (value); + + props->linux_md_slaves = g_new0 (char *, object_paths->len + 1); + for (n = 0; n < object_paths->len; n++) + props->linux_md_slaves[n] = g_strdup (object_paths->pdata[n]); + props->linux_md_slaves[n] = NULL; + } + else if (strcmp (key, "LinuxMdIsDegraded") == 0) + props->linux_md_is_degraded = g_value_get_boolean (value); + else if (strcmp (key, "LinuxMdSyncAction") == 0) + props->linux_md_sync_action = g_strdup (g_value_get_string (value)); + else if (strcmp (key, "LinuxMdSyncPercentage") == 0) + props->linux_md_sync_percentage = g_value_get_double (value); + else if (strcmp (key, "LinuxMdSyncSpeed") == 0) + props->linux_md_sync_speed = g_value_get_uint64 (value); + + else + handled = FALSE; + + if (!handled) + g_warning ("unhandled property '%s'", key); } static void device_properties_free (DeviceProperties *props) { - g_free (props->native_path); - g_free (props->device_file); - g_strfreev (props->device_file_by_id); - g_strfreev (props->device_file_by_path); - g_strfreev (props->device_mount_paths); - g_free (props->device_presentation_name); - g_free (props->device_presentation_icon_name); - g_free (props->job_id); - g_free (props->id_usage); - g_free (props->id_type); - g_free (props->id_version); - g_free (props->id_uuid); - g_free (props->id_label); - g_free (props->partition_slave); - g_free (props->partition_type); - g_free (props->partition_label); - g_free (props->partition_uuid); - g_strfreev (props->partition_flags); - g_free (props->partition_table_scheme); - g_free (props->luks_holder); - g_free (props->luks_cleartext_slave); - g_free (props->drive_model); - g_free (props->drive_vendor); - g_free (props->drive_revision); - g_free (props->drive_serial); - g_free (props->drive_wwn); - g_free (props->drive_connection_interface); - g_strfreev (props->drive_media_compatibility); - g_free (props->drive_media); - g_free (props->drive_write_cache); - g_free (props->drive_adapter); - g_strfreev (props->drive_ports); - - g_free (props->drive_ata_smart_status); - g_free (props->drive_ata_smart_blob); - - g_free (props->linux_md_component_level); - g_free (props->linux_md_component_uuid); - g_free (props->linux_md_component_home_host); - g_free (props->linux_md_component_name); - g_free (props->linux_md_component_version); - g_free (props->linux_md_component_holder); - g_strfreev (props->linux_md_component_state); - - g_free (props->linux_md_state); - g_free (props->linux_md_level); - g_free (props->linux_md_uuid); - g_free (props->linux_md_home_host); - g_free (props->linux_md_name); - g_free (props->linux_md_version); - g_strfreev (props->linux_md_slaves); - g_free (props->linux_md_sync_action); - g_free (props); + g_free (props->native_path); + g_free (props->device_file); + g_strfreev (props->device_file_by_id); + g_strfreev (props->device_file_by_path); + g_strfreev (props->device_mount_paths); + g_free (props->device_presentation_name); + g_free (props->device_presentation_icon_name); + g_free (props->job_id); + g_free (props->id_usage); + g_free (props->id_type); + g_free (props->id_version); + g_free (props->id_uuid); + g_free (props->id_label); + g_free (props->partition_slave); + g_free (props->partition_type); + g_free (props->partition_label); + g_free (props->partition_uuid); + g_strfreev (props->partition_flags); + g_free (props->partition_table_scheme); + g_free (props->luks_holder); + g_free (props->luks_cleartext_slave); + g_free (props->drive_model); + g_free (props->drive_vendor); + g_free (props->drive_revision); + g_free (props->drive_serial); + g_free (props->drive_wwn); + g_free (props->drive_connection_interface); + g_strfreev (props->drive_media_compatibility); + g_free (props->drive_media); + g_free (props->drive_write_cache); + g_free (props->drive_adapter); + g_strfreev (props->drive_ports); + + g_free (props->drive_ata_smart_status); + g_free (props->drive_ata_smart_blob); + + g_free (props->linux_md_component_level); + g_free (props->linux_md_component_uuid); + g_free (props->linux_md_component_home_host); + g_free (props->linux_md_component_name); + g_free (props->linux_md_component_version); + g_free (props->linux_md_component_holder); + g_strfreev (props->linux_md_component_state); + + g_free (props->linux_md_state); + g_free (props->linux_md_level); + g_free (props->linux_md_uuid); + g_free (props->linux_md_home_host); + g_free (props->linux_md_name); + g_free (props->linux_md_version); + g_strfreev (props->linux_md_slaves); + g_free (props->linux_md_sync_action); + g_free (props); } static DeviceProperties * device_properties_get (DBusGConnection *bus, const char *object_path) { - DeviceProperties *props; - GError *error; - GHashTable *hash_table; - DBusGProxy *prop_proxy; - const char *ifname = "org.freedesktop.UDisks.Device"; - - props = g_new0 (DeviceProperties, 1); - - prop_proxy = dbus_g_proxy_new_for_name (bus, - "org.freedesktop.UDisks", - object_path, - "org.freedesktop.DBus.Properties"); - error = NULL; - if (!dbus_g_proxy_call (prop_proxy, - "GetAll", - &error, - G_TYPE_STRING, - ifname, - G_TYPE_INVALID, - dbus_g_type_get_map ("GHashTable", G_TYPE_STRING, G_TYPE_VALUE), - &hash_table, - G_TYPE_INVALID)) { - g_warning ("Couldn't call GetAll() to get properties for %s: %s", object_path, error->message); - g_error_free (error); - - device_properties_free (props); - props = NULL; - goto out; - } + DeviceProperties *props; + GError *error; + GHashTable *hash_table; + DBusGProxy *prop_proxy; + const char *ifname = "org.freedesktop.UDisks.Device"; + + props = g_new0 (DeviceProperties, 1); + + prop_proxy + = dbus_g_proxy_new_for_name (bus, "org.freedesktop.UDisks", object_path, "org.freedesktop.DBus.Properties"); + error = NULL; + if (!dbus_g_proxy_call (prop_proxy, + "GetAll", + &error, + G_TYPE_STRING, + ifname, + G_TYPE_INVALID, + dbus_g_type_get_map ("GHashTable", G_TYPE_STRING, G_TYPE_VALUE), + &hash_table, + G_TYPE_INVALID)) + { + g_warning ("Couldn't call GetAll() to get properties for %s: %s", object_path, error->message); + g_error_free (error); + + device_properties_free (props); + props = NULL; + goto out; + } + + g_hash_table_foreach (hash_table, (GHFunc) collect_props, props); + + g_hash_table_unref (hash_table); - g_hash_table_foreach (hash_table, (GHFunc) collect_props, props); - - g_hash_table_unref (hash_table); - -out: - g_object_unref (prop_proxy); - return props; + out: + g_object_unref (prop_proxy); + return props; } /* --- SUCKY CODE END --- */ @@ -773,448 +771,508 @@ out: static gboolean do_monitor (void) { - GError *error; + GError *error; - g_print ("Monitoring activity from the disks daemon. Press Ctrl+C to cancel.\n"); + g_print ("Monitoring activity from the disks daemon. Press Ctrl+C to cancel.\n"); - error = NULL; + error = NULL; - dbus_g_proxy_connect_signal (disks_proxy, "DeviceAdded", - G_CALLBACK (device_added_signal_handler), NULL, NULL); - dbus_g_proxy_connect_signal (disks_proxy, "DeviceRemoved", - G_CALLBACK (device_removed_signal_handler), NULL, NULL); - dbus_g_proxy_connect_signal (disks_proxy, "DeviceChanged", - G_CALLBACK (device_changed_signal_handler), NULL, NULL); - dbus_g_proxy_connect_signal (disks_proxy, "DeviceJobChanged", - G_CALLBACK (device_job_changed_signal_handler), NULL, NULL); - g_main_loop_run (loop); + dbus_g_proxy_connect_signal (disks_proxy, "DeviceAdded", G_CALLBACK (device_added_signal_handler), NULL, NULL); + dbus_g_proxy_connect_signal (disks_proxy, "DeviceRemoved", G_CALLBACK (device_removed_signal_handler), NULL, NULL); + dbus_g_proxy_connect_signal (disks_proxy, "DeviceChanged", G_CALLBACK (device_changed_signal_handler), NULL, NULL); + dbus_g_proxy_connect_signal (disks_proxy, + "DeviceJobChanged", + G_CALLBACK (device_job_changed_signal_handler), + NULL, + NULL); + g_main_loop_run (loop); - return FALSE; + return FALSE; } static gboolean has_colors (void) { - static gboolean ret = FALSE; - static gboolean checked = FALSE; + static gboolean ret = FALSE; + static gboolean checked = FALSE; - if (checked) - return ret; + if (checked) + return ret; - if (isatty (STDOUT_FILENO)) { - ret = TRUE; - } + if (isatty (STDOUT_FILENO)) + { + ret = TRUE; + } - checked = TRUE; + checked = TRUE; - return ret; + return ret; } static void begin_highlight (void) { - if (has_colors ()) - g_print ("\x1B[1;31m"); + if (has_colors ()) + g_print ("\x1B[1;31m"); } static void end_highlight (void) { - if (has_colors ()) - g_print ("\x1B[0m"); + if (has_colors ()) + g_print ("\x1B[0m"); } static const gchar * ata_smart_status_to_desc (const gchar *status, - gboolean *out_highlight) + gboolean *out_highlight) { - const gchar *desc; - gboolean highlight; - - highlight = FALSE; - if (g_strcmp0 (status, "GOOD") == 0) { - desc = "Good"; - } else if (g_strcmp0 (status, "BAD_ATTRIBUTE_IN_THE_PAST") == 0) { - desc = "Disk was used outside of design parameters in the past"; - } else if (g_strcmp0 (status, "BAD_SECTOR") == 0) { - desc = "Disk has a few bad sectors"; - } else if (g_strcmp0 (status, "BAD_ATTRIBUTE_NOW") == 0) { - desc = "Disk is being used outside of design parameters"; - highlight = TRUE; - } else if (g_strcmp0 (status, "BAD_SECTOR_MANY") == 0) { - desc = "Disk reports many bad sectors"; - highlight = TRUE; - } else if (g_strcmp0 (status, "BAD_STATUS") == 0) { - desc = "Disk failure is imminent"; - highlight = TRUE; - } else { - desc = status; - } - - if (out_highlight != NULL) - *out_highlight = highlight; - - return desc; + const gchar *desc; + gboolean highlight; + + highlight = FALSE; + if (g_strcmp0 (status, "GOOD") == 0) + { + desc = "Good"; + } + else if (g_strcmp0 (status, "BAD_ATTRIBUTE_IN_THE_PAST") == 0) + { + desc = "Disk was used outside of design parameters in the past"; + } + else if (g_strcmp0 (status, "BAD_SECTOR") == 0) + { + desc = "Disk has a few bad sectors"; + } + else if (g_strcmp0 (status, "BAD_ATTRIBUTE_NOW") == 0) + { + desc = "Disk is being used outside of design parameters"; + highlight = TRUE; + } + else if (g_strcmp0 (status, "BAD_SECTOR_MANY") == 0) + { + desc = "Disk reports many bad sectors"; + highlight = TRUE; + } + else if (g_strcmp0 (status, "BAD_STATUS") == 0) + { + desc = "Disk failure is imminent"; + highlight = TRUE; + } + else + { + desc = status; + } + + if (out_highlight != NULL) + *out_highlight = highlight; + + return desc; } static gchar * -get_ata_smart_unit (guint unit, guint64 pretty_value) +get_ata_smart_unit (guint unit, + guint64 pretty_value) { - gchar *ret; - - switch (unit) { - default: - case SK_SMART_ATTRIBUTE_UNIT_UNKNOWN: - case SK_SMART_ATTRIBUTE_UNIT_NONE: - ret = g_strdup_printf ("%" G_GUINT64_FORMAT, pretty_value); - break; - - case SK_SMART_ATTRIBUTE_UNIT_MSECONDS: - if (pretty_value > 1000 * 60 * 60 * 24) { - ret = g_strdup_printf ("%3.1f days", pretty_value / 1000.0 / 60.0 / 60.0 / 24.0); - } else if (pretty_value > 1000 * 60 * 60) { - ret = g_strdup_printf ("%3.1f hours", pretty_value / 1000.0 / 60.0 / 60.0); - } else if (pretty_value > 1000 * 60) { - ret = g_strdup_printf ("%3.1f mins", pretty_value / 1000.0 / 60.0); - } else if (pretty_value > 1000) { - ret = g_strdup_printf ("%3.1f secs", pretty_value / 1000.0); - } else { - ret = g_strdup_printf ("%d msec", (gint) pretty_value); - } - break; + gchar *ret; + + switch (unit) + { + default: + case SK_SMART_ATTRIBUTE_UNIT_UNKNOWN: + case SK_SMART_ATTRIBUTE_UNIT_NONE: + ret = g_strdup_printf ("%" G_GUINT64_FORMAT, pretty_value); + break; + + case SK_SMART_ATTRIBUTE_UNIT_MSECONDS: + if (pretty_value > 1000 * 60 * 60 * 24) + { + ret = g_strdup_printf ("%3.1f days", pretty_value / 1000.0 / 60.0 / 60.0 / 24.0); + } + else if (pretty_value > 1000 * 60 * 60) + { + ret = g_strdup_printf ("%3.1f hours", pretty_value / 1000.0 / 60.0 / 60.0); + } + else if (pretty_value > 1000 * 60) + { + ret = g_strdup_printf ("%3.1f mins", pretty_value / 1000.0 / 60.0); + } + else if (pretty_value > 1000) + { + ret = g_strdup_printf ("%3.1f secs", pretty_value / 1000.0); + } + else + { + ret = g_strdup_printf ("%d msec", (gint) pretty_value); + } + break; - case SK_SMART_ATTRIBUTE_UNIT_SECTORS: - ret = g_strdup_printf ("%" G_GUINT64_FORMAT " sectors", pretty_value); - break; + case SK_SMART_ATTRIBUTE_UNIT_SECTORS: + ret = g_strdup_printf ("%" G_GUINT64_FORMAT " sectors", pretty_value); + break; - case SK_SMART_ATTRIBUTE_UNIT_MKELVIN: - ret = g_strdup_printf ("%.3gC / %.3gF", - pretty_value / 1000.0 - 273.15, - (pretty_value / 1000.0 - 273.15) * 9.0 / 5.0 + 32.0); - break; - } + case SK_SMART_ATTRIBUTE_UNIT_MKELVIN: + ret = g_strdup_printf ("%.3gC / %.3gF", pretty_value / 1000.0 - 273.15, (pretty_value / 1000.0 - 273.15) * 9.0 + / 5.0 + 32.0); + break; + } - return ret; + return ret; } static void -print_ata_smart_attr (SkDisk *d, const SkSmartAttributeParsedData *a, void *user_data) +print_ata_smart_attr (SkDisk *d, + const SkSmartAttributeParsedData *a, + void *user_data) { - const gchar *assessment; - const gchar *type; - const gchar *updates; - gchar *current_str; - gchar *worst_str; - gchar *threshold_str; - gchar *pretty; - - pretty = get_ata_smart_unit (a->pretty_unit, a->pretty_value); - - if (!a->good_now_valid) { - assessment = " n/a "; - } else { - if (!a->good_now) { - assessment = " FAIL "; - } else { - if (a->good_in_the_past_valid && !a->good_in_the_past) { - assessment = "FAIL_PAST"; - } else { - assessment = " good "; - } - } + const gchar *assessment; + const gchar *type; + const gchar *updates; + gchar *current_str; + gchar *worst_str; + gchar *threshold_str; + gchar *pretty; + + pretty = get_ata_smart_unit (a->pretty_unit, a->pretty_value); + + if (!a->good_now_valid) + { + assessment = " n/a "; + } + else + { + if (!a->good_now) + { + assessment = " FAIL "; } - - if (a->online) - updates = "Online "; - else - updates = "Offline"; - - if (a->prefailure) - type = "Pre-fail"; - else - type = "Old-age "; - - if (a->current_value_valid) - current_str = g_strdup_printf ("%3d", a->current_value); - else - current_str = g_strdup ("n/a"); - - if (a->worst_value_valid) - worst_str = g_strdup_printf ("%3d", a->worst_value); - else - worst_str = g_strdup ("n/a"); - - if (a->threshold_valid) - threshold_str = g_strdup_printf ("%3d", a->threshold); - else - threshold_str = g_strdup ("n/a"); - - if (a->warn) - begin_highlight (); - - g_print (" %-27s %s|%s|%s %s %-11s %s %s\n", - a->name, - current_str, - worst_str, - threshold_str, - assessment, - pretty, - type, - updates); - - if (a->warn) - end_highlight (); - - g_free (current_str); - g_free (worst_str); - g_free (threshold_str); - g_free (pretty); + else + { + if (a->good_in_the_past_valid && !a->good_in_the_past) + { + assessment = "FAIL_PAST"; + } + else + { + assessment = " good "; + } + } + } + + if (a->online) + updates = "Online "; + else + updates = "Offline"; + + if (a->prefailure) + type = "Pre-fail"; + else + type = "Old-age "; + + if (a->current_value_valid) + current_str = g_strdup_printf ("%3d", a->current_value); + else + current_str = g_strdup ("n/a"); + + if (a->worst_value_valid) + worst_str = g_strdup_printf ("%3d", a->worst_value); + else + worst_str = g_strdup ("n/a"); + + if (a->threshold_valid) + threshold_str = g_strdup_printf ("%3d", a->threshold); + else + threshold_str = g_strdup ("n/a"); + + if (a->warn) + begin_highlight (); + + g_print (" %-27s %s|%s|%s %s %-11s %s %s\n", + a->name, + current_str, + worst_str, + threshold_str, + assessment, + pretty, + type, + updates); + + if (a->warn) + end_highlight (); + + g_free (current_str); + g_free (worst_str); + g_free (threshold_str); + g_free (pretty); } static void do_show_info (const char *object_path) { - guint n; - DeviceProperties *props; - struct tm *time_tm; - time_t time; - char time_buf[256]; - - props = device_properties_get (bus, object_path); - if (props == NULL) - return; - - time = (time_t) props->device_detection_time; - time_tm = localtime (&time); - strftime (time_buf, sizeof time_buf, "%c", time_tm); - - g_print ("Showing information for %s\n", object_path); - g_print (" native-path: %s\n", props->native_path); - g_print (" device: %" G_GINT64_MODIFIER "d:%" G_GINT64_MODIFIER "d\n", - props->device_major, - props->device_minor); - g_print (" device-file: %s\n", props->device_file); - for (n = 0; props->device_file_by_id[n] != NULL; n++) - g_print (" by-id: %s\n", (char *) props->device_file_by_id[n]); - for (n = 0; props->device_file_by_path[n] != NULL; n++) - g_print (" by-path: %s\n", (char *) props->device_file_by_path[n]); - g_print (" detected at: %s\n", time_buf); - g_print (" system internal: %d\n", props->device_is_system_internal); - g_print (" removable: %d\n", props->device_is_removable); - g_print (" has media: %d", props->device_is_media_available); - if (props->device_media_detection_time != 0) { - time = (time_t) props->device_media_detection_time; - time_tm = localtime (&time); - strftime (time_buf, sizeof time_buf, "%c", time_tm); - g_print (" (detected at %s)", time_buf); + guint n; + DeviceProperties *props; + struct tm *time_tm; + time_t time; + char time_buf[256]; + + props = device_properties_get (bus, object_path); + if (props == NULL) + return; + + time = (time_t) props->device_detection_time; + time_tm = localtime (&time); + strftime (time_buf, sizeof time_buf, "%c", time_tm); + + g_print ("Showing information for %s\n", object_path); + g_print (" native-path: %s\n", props->native_path); + g_print (" device: %" G_GINT64_MODIFIER "d:%" G_GINT64_MODIFIER "d\n", + props->device_major, + props->device_minor); + g_print (" device-file: %s\n", props->device_file); + for (n = 0; props->device_file_by_id[n] != NULL; n++) + g_print (" by-id: %s\n", (char *) props->device_file_by_id[n]); + for (n = 0; props->device_file_by_path[n] != NULL; n++) + g_print (" by-path: %s\n", (char *) props->device_file_by_path[n]); + g_print (" detected at: %s\n", time_buf); + g_print (" system internal: %d\n", props->device_is_system_internal); + g_print (" removable: %d\n", props->device_is_removable); + g_print (" has media: %d", props->device_is_media_available); + if (props->device_media_detection_time != 0) + { + time = (time_t) props->device_media_detection_time; + time_tm = localtime (&time); + strftime (time_buf, sizeof time_buf, "%c", time_tm); + g_print (" (detected at %s)", time_buf); + } + g_print ("\n"); + g_print (" detects change: %d\n", props->device_is_media_change_detected); + g_print (" detection by polling: %d\n", props->device_is_media_change_detection_polling); + g_print (" detection inhibitable: %d\n", props->device_is_media_change_detection_inhibitable); + g_print (" detection inhibited: %d\n", props->device_is_media_change_detection_inhibited); + g_print (" is read only: %d\n", props->device_is_read_only); + g_print (" is mounted: %d\n", props->device_is_mounted); + g_print (" mount paths: "); + for (n = 0; props->device_mount_paths != NULL && props->device_mount_paths[n] != NULL; n++) + { + if (n != 0) + g_print (", "); + g_print ("%s", props->device_mount_paths[n]); + } + g_print ("\n"); + g_print (" mounted by uid: %d\n", props->device_mounted_by_uid); + g_print (" presentation hide: %d\n", props->device_presentation_hide); + g_print (" presentation nopolicy: %d\n", props->device_presentation_nopolicy); + g_print (" presentation name: %s\n", props->device_presentation_name); + g_print (" presentation icon: %s\n", props->device_presentation_icon_name); + g_print (" size: %" G_GUINT64_FORMAT "\n", props->device_size); + g_print (" block size: %" G_GUINT64_FORMAT "\n", props->device_block_size); + + print_job (props->job_in_progress, + props->job_id, + props->job_initiated_by_uid, + props->job_is_cancellable, + props->job_percentage); + g_print (" usage: %s\n", props->id_usage); + g_print (" type: %s\n", props->id_type); + g_print (" version: %s\n", props->id_version); + g_print (" uuid: %s\n", props->id_uuid); + g_print (" label: %s\n", props->id_label); + if (props->device_is_linux_md_component) + { + g_print (" linux md component:\n"); + g_print (" RAID level: %s\n", props->linux_md_component_level); + g_print (" position: %d\n", props->linux_md_component_position); + g_print (" num components: %d\n", props->linux_md_component_num_raid_devices); + g_print (" uuid: %s\n", props->linux_md_component_uuid); + g_print (" home host: %s\n", props->linux_md_component_home_host); + g_print (" name: %s\n", props->linux_md_component_name); + g_print (" version: %s\n", props->linux_md_component_version); + g_print (" holder: %s\n", g_strcmp0 (props->linux_md_component_holder, "/") == 0 ? "(none)" + : props->linux_md_component_holder); + g_print (" state: "); + for (n = 0; props->linux_md_component_state != NULL && props->linux_md_component_state[n] != NULL; n++) + { + if (n > 0) + g_print (", "); + g_print ("%s", props->linux_md_component_state[n]); } - g_print ("\n"); - g_print (" detects change: %d\n", props->device_is_media_change_detected); - g_print (" detection by polling: %d\n", props->device_is_media_change_detection_polling); - g_print (" detection inhibitable: %d\n", props->device_is_media_change_detection_inhibitable); - g_print (" detection inhibited: %d\n", props->device_is_media_change_detection_inhibited); - g_print (" is read only: %d\n", props->device_is_read_only); - g_print (" is mounted: %d\n", props->device_is_mounted); - g_print (" mount paths: "); - for (n = 0; props->device_mount_paths != NULL && props->device_mount_paths[n] != NULL; n++) { - if (n != 0) - g_print (", "); - g_print ("%s", props->device_mount_paths[n]); + g_print ("\n"); + } + if (props->device_is_linux_md) + { + g_print (" linux md:\n"); + g_print (" state: %s\n", props->linux_md_state); + g_print (" RAID level: %s\n", props->linux_md_level); + g_print (" uuid: %s\n", props->linux_md_uuid); + g_print (" home host: %s\n", props->linux_md_home_host); + g_print (" name: %s\n", props->linux_md_name); + g_print (" num comp: %d\n", props->linux_md_num_raid_devices); + g_print (" version: %s\n", props->linux_md_version); + g_print (" degraded: %d\n", props->linux_md_is_degraded); + g_print (" sync action: %s\n", props->linux_md_sync_action); + if (strcmp (props->linux_md_sync_action, "idle") != 0) + { + g_print (" complete: %3.01f%%\n", props->linux_md_sync_percentage); + g_print (" speed: %" G_GINT64_FORMAT " bytes/sec\n", props->linux_md_sync_speed); } - g_print ("\n"); - g_print (" mounted by uid: %d\n", props->device_mounted_by_uid); - g_print (" presentation hide: %d\n", props->device_presentation_hide); - g_print (" presentation nopolicy: %d\n", props->device_presentation_nopolicy); - g_print (" presentation name: %s\n", props->device_presentation_name); - g_print (" presentation icon: %s\n", props->device_presentation_icon_name); - g_print (" size: %" G_GUINT64_FORMAT "\n", props->device_size); - g_print (" block size: %" G_GUINT64_FORMAT "\n", props->device_block_size); - - print_job (props->job_in_progress, - props->job_id, - props->job_initiated_by_uid, - props->job_is_cancellable, - props->job_percentage); - g_print (" usage: %s\n", props->id_usage); - g_print (" type: %s\n", props->id_type); - g_print (" version: %s\n", props->id_version); - g_print (" uuid: %s\n", props->id_uuid); - g_print (" label: %s\n", props->id_label); - if (props->device_is_linux_md_component) { - g_print (" linux md component:\n"); - g_print (" RAID level: %s\n", props->linux_md_component_level); - g_print (" position: %d\n", props->linux_md_component_position); - g_print (" num components: %d\n", props->linux_md_component_num_raid_devices); - g_print (" uuid: %s\n", props->linux_md_component_uuid); - g_print (" home host: %s\n", props->linux_md_component_home_host); - g_print (" name: %s\n", props->linux_md_component_name); - g_print (" version: %s\n", props->linux_md_component_version); - g_print (" holder: %s\n", - g_strcmp0 (props->linux_md_component_holder, "/") == 0 ? "(none)" : props->linux_md_component_holder); - g_print (" state: "); - for (n = 0; - props->linux_md_component_state != NULL && props->linux_md_component_state[n] != NULL; - n++) { - if (n > 0) - g_print (", "); - g_print ("%s", props->linux_md_component_state[n]); - } - g_print ("\n"); + g_print (" slaves:\n"); + for (n = 0; props->linux_md_slaves[n] != NULL; n++) + g_print (" %s\n", props->linux_md_slaves[n]); + } + if (props->device_is_luks) + { + g_print (" luks device:\n"); + g_print (" holder: %s\n", props->luks_holder); + } + if (props->device_is_luks_cleartext) + { + g_print (" cleartext luks device:\n"); + g_print (" backed by: %s\n", props->luks_cleartext_slave); + g_print (" unlocked by: uid %d\n", props->luks_cleartext_unlocked_by_uid); + } + if (props->device_is_partition_table) + { + g_print (" partition table:\n"); + g_print (" scheme: %s\n", props->partition_table_scheme); + g_print (" count: %d\n", props->partition_table_count); + } + if (props->device_is_partition) + { + g_print (" partition:\n"); + g_print (" part of: %s\n", props->partition_slave); + g_print (" scheme: %s\n", props->partition_scheme); + g_print (" number: %d\n", props->partition_number); + g_print (" type: %s\n", props->partition_type); + g_print (" flags: "); + for (n = 0; props->partition_flags[n] != NULL; n++) + g_print (" %s", (char *) props->partition_flags[n]); + g_print ("\n"); + g_print (" offset: %" G_GINT64_FORMAT "\n", props->partition_offset); + g_print (" size: %" G_GINT64_FORMAT "\n", props->partition_size); + g_print (" label: %s\n", props->partition_label); + g_print (" uuid: %s\n", props->partition_uuid); + } + if (props->device_is_optical_disc) + { + g_print (" optical disc:\n"); + g_print (" blank: %d\n", props->optical_disc_is_blank); + g_print (" appendable: %d\n", props->optical_disc_is_appendable); + g_print (" closed: %d\n", props->optical_disc_is_closed); + g_print (" num tracks: %d\n", props->optical_disc_num_tracks); + g_print (" num audio tracks: %d\n", props->optical_disc_num_audio_tracks); + g_print (" num sessions: %d\n", props->optical_disc_num_sessions); + } + if (props->device_is_drive) + { + g_print (" drive:\n"); + g_print (" vendor: %s\n", props->drive_vendor); + g_print (" model: %s\n", props->drive_model); + g_print (" revision: %s\n", props->drive_revision); + g_print (" serial: %s\n", props->drive_serial); + g_print (" WWN: %s\n", props->drive_wwn); + g_print (" detachable: %d\n", props->drive_can_detach); + g_print (" can spindown: %d\n", props->drive_can_spindown); + if (props->drive_is_rotational) + { + if (props->drive_rotation_rate > 0) + { + g_print (" rotational media: Yes, at %d RPM\n", props->drive_rotation_rate); + } + else + { + g_print (" rotational media: Yes, unknown rate\n"); + } } - if (props->device_is_linux_md) { - g_print (" linux md:\n"); - g_print (" state: %s\n", props->linux_md_state); - g_print (" RAID level: %s\n", props->linux_md_level); - g_print (" uuid: %s\n", props->linux_md_uuid); - g_print (" home host: %s\n", props->linux_md_home_host); - g_print (" name: %s\n", props->linux_md_name); - g_print (" num comp: %d\n", props->linux_md_num_raid_devices); - g_print (" version: %s\n", props->linux_md_version); - g_print (" degraded: %d\n", props->linux_md_is_degraded); - g_print (" sync action: %s\n", props->linux_md_sync_action); - if (strcmp (props->linux_md_sync_action, "idle") != 0) { - g_print (" complete: %3.01f%%\n", props->linux_md_sync_percentage); - g_print (" speed: %" G_GINT64_FORMAT " bytes/sec\n", props->linux_md_sync_speed); - } - g_print (" slaves:\n"); - for (n = 0; props->linux_md_slaves[n] != NULL; n++) - g_print (" %s\n", props->linux_md_slaves[n]); + else + { + g_print (" rotational media: No\n"); } - if (props->device_is_luks) { - g_print (" luks device:\n"); - g_print (" holder: %s\n", props->luks_holder); + if (props->drive_write_cache == NULL || strlen (props->drive_write_cache) == 0) + { + g_print (" write-cache: unknown\n"); } - if (props->device_is_luks_cleartext) { - g_print (" cleartext luks device:\n"); - g_print (" backed by: %s\n", props->luks_cleartext_slave); - g_print (" unlocked by: uid %d\n", props->luks_cleartext_unlocked_by_uid); + else + { + g_print (" write-cache: %s\n", props->drive_write_cache); } - if (props->device_is_partition_table) { - g_print (" partition table:\n"); - g_print (" scheme: %s\n", props->partition_table_scheme); - g_print (" count: %d\n", props->partition_table_count); + g_print (" ejectable: %d\n", props->drive_is_media_ejectable); + g_print (" adapter: %s\n", strlen (props->drive_adapter) > 1 ? props->drive_adapter : "Unknown"); + g_print (" ports: \n"); + for (n = 0; props->drive_ports != NULL && props->drive_ports[n] != NULL; n++) + { + g_print (" %s\n", props->drive_ports[n]); } - if (props->device_is_partition) { - g_print (" partition:\n"); - g_print (" part of: %s\n", props->partition_slave); - g_print (" scheme: %s\n", props->partition_scheme); - g_print (" number: %d\n", props->partition_number); - g_print (" type: %s\n", props->partition_type); - g_print (" flags: "); - for (n = 0; props->partition_flags[n] != NULL; n++) - g_print (" %s", (char *) props->partition_flags[n]); - g_print ("\n"); - g_print (" offset: %" G_GINT64_FORMAT "\n", props->partition_offset); - g_print (" size: %" G_GINT64_FORMAT "\n", props->partition_size); - g_print (" label: %s\n", props->partition_label); - g_print (" uuid: %s\n", props->partition_uuid); + g_print (" media: %s\n", props->drive_media); + g_print (" compat: "); + for (n = 0; props->drive_media_compatibility[n] != NULL; n++) + g_print (" %s", (char *) props->drive_media_compatibility[n]); + g_print ("\n"); + if (props->drive_connection_interface == NULL || strlen (props->drive_connection_interface) == 0) + g_print (" interface: (unknown)\n"); + else + g_print (" interface: %s\n", props->drive_connection_interface); + if (props->drive_connection_speed == 0) + g_print (" if speed: (unknown)\n"); + else + g_print (" if speed: %" G_GINT64_FORMAT " bits/s\n", props->drive_connection_speed); + + /* ------------------------------------------------------------------------------------------------- */ + + if (!props->drive_ata_smart_is_available) + { + g_print (" ATA SMART: not available\n"); } - if (props->device_is_optical_disc) { - g_print (" optical disc:\n"); - g_print (" blank: %d\n", props->optical_disc_is_blank); - g_print (" appendable: %d\n", props->optical_disc_is_appendable); - g_print (" closed: %d\n", props->optical_disc_is_closed); - g_print (" num tracks: %d\n", props->optical_disc_num_tracks); - g_print (" num audio tracks: %d\n", props->optical_disc_num_audio_tracks); - g_print (" num sessions: %d\n", props->optical_disc_num_sessions); + else if (props->drive_ata_smart_time_collected == 0) + { + g_print (" ATA SMART: Data not collected\n"); } - if (props->device_is_drive) { - g_print (" drive:\n"); - g_print (" vendor: %s\n", props->drive_vendor); - g_print (" model: %s\n", props->drive_model); - g_print (" revision: %s\n", props->drive_revision); - g_print (" serial: %s\n", props->drive_serial); - g_print (" WWN: %s\n", props->drive_wwn); - g_print (" detachable: %d\n", props->drive_can_detach); - g_print (" can spindown: %d\n", props->drive_can_spindown); - if (props->drive_is_rotational) { - if (props->drive_rotation_rate > 0) { - g_print (" rotational media: Yes, at %d RPM\n", props->drive_rotation_rate); - } else { - g_print (" rotational media: Yes, unknown rate\n"); - } - } else { - g_print (" rotational media: No\n"); - } - if (props->drive_write_cache == NULL || strlen (props->drive_write_cache) == 0) { - g_print (" write-cache: unknown\n"); - } else { - g_print (" write-cache: %s\n", props->drive_write_cache); - } - g_print (" ejectable: %d\n", props->drive_is_media_ejectable); - g_print (" adapter: %s\n", strlen (props->drive_adapter) > 1 ? props->drive_adapter : "Unknown"); - g_print (" ports: \n"); - for (n = 0; props->drive_ports != NULL && props->drive_ports[n] != NULL; n++) { - g_print (" %s\n", props->drive_ports[n]); - } - g_print (" media: %s\n", props->drive_media); - g_print (" compat: "); - for (n = 0; props->drive_media_compatibility[n] != NULL; n++) - g_print (" %s", (char *) props->drive_media_compatibility[n]); - g_print ("\n"); - if (props->drive_connection_interface == NULL || strlen (props->drive_connection_interface) == 0) - g_print (" interface: (unknown)\n"); - else - g_print (" interface: %s\n", props->drive_connection_interface); - if (props->drive_connection_speed == 0) - g_print (" if speed: (unknown)\n"); - else - g_print (" if speed: %" G_GINT64_FORMAT " bits/s\n", props->drive_connection_speed); - - /* ------------------------------------------------------------------------------------------------- */ - - if (!props->drive_ata_smart_is_available) { - g_print (" ATA SMART: not available\n"); - } else if (props->drive_ata_smart_time_collected == 0) { - g_print (" ATA SMART: Data not collected\n"); - } else { - SkDisk *d; - - time = (time_t) props->drive_ata_smart_time_collected; - time_tm = localtime (&time); - strftime (time_buf, sizeof time_buf, "%c", time_tm); - - - g_print (" ATA SMART: Updated at %s\n", time_buf); - - if (props->drive_ata_smart_status == NULL || strlen (props->drive_ata_smart_status) == 0) { - g_print (" overall assessment: UNKNOWN\n"); - } else { - const gchar *status_desc; - gboolean do_highlight; - - status_desc = ata_smart_status_to_desc (props->drive_ata_smart_status, &do_highlight); - - if (do_highlight) - begin_highlight (); - g_print (" overall assessment: %s\n", status_desc); - if (do_highlight) - end_highlight (); - } - - if (sk_disk_open (NULL, &d) == 0) { - if (sk_disk_set_blob (d, - props->drive_ata_smart_blob, - props->drive_ata_smart_blob_size) == 0) { - g_print ("===============================================================================\n"); - g_print (" Attribute Current|Worst|Threshold Status Value Type Updates\n"); - g_print ("===============================================================================\n"); - - sk_disk_smart_parse_attributes (d, - print_ata_smart_attr, - NULL); - } - sk_disk_free (d); - } + else + { + SkDisk *d; + time = (time_t) props->drive_ata_smart_time_collected; + time_tm = localtime (&time); + strftime (time_buf, sizeof time_buf, "%c", time_tm); - } + g_print (" ATA SMART: Updated at %s\n", time_buf); - /* ------------------------------------------------------------------------------------------------- */ + if (props->drive_ata_smart_status == NULL || strlen (props->drive_ata_smart_status) == 0) + { + g_print (" overall assessment: UNKNOWN\n"); + } + else + { + const gchar *status_desc; + gboolean do_highlight; + status_desc = ata_smart_status_to_desc (props->drive_ata_smart_status, &do_highlight); + + if (do_highlight) + begin_highlight (); + g_print (" overall assessment: %s\n", status_desc); + if (do_highlight) + end_highlight (); + } + + if (sk_disk_open (NULL, &d) == 0) + { + if (sk_disk_set_blob (d, + props->drive_ata_smart_blob, + props->drive_ata_smart_blob_size) == 0) + { + g_print ("===============================================================================\n"); + g_print (" Attribute Current|Worst|Threshold Status Value Type Updates\n"); + g_print ("===============================================================================\n"); + + sk_disk_smart_parse_attributes (d, print_ata_smart_attr, NULL); + } + sk_disk_free (d); + } } - device_properties_free (props); + + /* ------------------------------------------------------------------------------------------------- */ + + } + device_properties_free (props); } /* ---------------------------------------------------------------------------------------------------- */ @@ -1222,649 +1280,691 @@ do_show_info (const char *object_path) static gint do_poll_for_media (const char *object_path) { - DBusGProxy *proxy; - GError *error; - gint ret; + DBusGProxy *proxy; + GError *error; + gint ret; - ret = 1; + ret = 1; - proxy = dbus_g_proxy_new_for_name (bus, - "org.freedesktop.UDisks", - object_path, - "org.freedesktop.UDisks.Device"); - - error = NULL; - if (!org_freedesktop_UDisks_Device_drive_poll_media (proxy, - &error)) { - g_print ("Poll for media failed: %s\n", error->message); - g_error_free (error); - goto out; - } + proxy = dbus_g_proxy_new_for_name (bus, "org.freedesktop.UDisks", object_path, "org.freedesktop.UDisks.Device"); - ret = 0; + error = NULL; + if (!org_freedesktop_UDisks_Device_drive_poll_media (proxy, &error)) + { + g_print ("Poll for media failed: %s\n", error->message); + g_error_free (error); + goto out; + } -out: - return ret; + ret = 0; + + out: + return ret; } /* ---------------------------------------------------------------------------------------------------- */ static gint do_inhibit_polling (const char *object_path, - gint argc, - gchar *argv[]) + gint argc, + gchar *argv[]) { - char *cookie; - DBusGProxy *proxy; - GError *error; - char **options; - gint ret; - - options = NULL; - cookie = NULL; - ret = 127; - - if (argc > 0 && strcmp (argv[0], "--") == 0) { - argv++; - argc--; - } - - proxy = dbus_g_proxy_new_for_name (bus, - "org.freedesktop.UDisks", - object_path, - "org.freedesktop.UDisks.Device"); - - error = NULL; - if (!org_freedesktop_UDisks_Device_drive_inhibit_polling (proxy, - (const char **) options, - &cookie, - &error)) { - g_print ("Inhibit polling failed: %s\n", error->message); - g_error_free (error); - goto out; + char *cookie; + DBusGProxy *proxy; + GError *error; + char **options; + gint ret; + + options = NULL; + cookie = NULL; + ret = 127; + + if (argc > 0 && strcmp (argv[0], "--") == 0) + { + argv++; + argc--; + } + + proxy = dbus_g_proxy_new_for_name (bus, "org.freedesktop.UDisks", object_path, "org.freedesktop.UDisks.Device"); + + error = NULL; + if (!org_freedesktop_UDisks_Device_drive_inhibit_polling (proxy, (const char **) options, &cookie, &error)) + { + g_print ("Inhibit polling failed: %s\n", error->message); + g_error_free (error); + goto out; + } + + if (argc == 0) + { + g_print ("Inhibiting polling on %s. Press Ctrl+C to exit.\n", object_path); + while (TRUE) + sleep (100000000); + } + else + { + GError * error; + gint exit_status; + + error = NULL; + if (!g_spawn_sync (NULL, /* working dir */ + argv, NULL, /* envp */ + G_SPAWN_SEARCH_PATH, NULL, /* child_setup */ + NULL, /* user_data */ + NULL, /* standard_output */ + NULL, /* standard_error */ + &exit_status, /* exit_status */ + &error)) + { + g_printerr ("Error launching program: %s\n", error->message); + g_error_free (error); + ret = 126; + goto out; } - if (argc == 0) { - g_print ("Inhibiting polling on %s. Press Ctrl+C to exit.\n", object_path); - while (TRUE) - sleep (100000000); - } else { - GError *error; - gint exit_status; - - error = NULL; - if (!g_spawn_sync (NULL, /* working dir */ - argv, - NULL, /* envp */ - G_SPAWN_SEARCH_PATH, - NULL, /* child_setup */ - NULL, /* user_data */ - NULL, /* standard_output */ - NULL, /* standard_error */ - &exit_status, /* exit_status */ - &error)) { - g_printerr ("Error launching program: %s\n", error->message); - g_error_free (error); - ret = 126; - goto out; - } + if (WIFEXITED (exit_status)) + ret = WEXITSTATUS (exit_status); + else + ret = 125; + } - if (WIFEXITED (exit_status)) - ret = WEXITSTATUS (exit_status); - else - ret = 125; - } - -out: - g_free (cookie); - return ret; + out: + g_free (cookie); + return ret; } /* ---------------------------------------------------------------------------------------------------- */ static gint -do_inhibit_all_polling (gint argc, - gchar *argv[]) +do_inhibit_all_polling (gint argc, + gchar *argv[]) { - char *cookie; - DBusGProxy *proxy; - GError *error; - char **options; - gint ret; - - options = NULL; - cookie = NULL; - ret = 127; - - if (argc > 0 && strcmp (argv[0], "--") == 0) { - argv++; - argc--; - } - - proxy = dbus_g_proxy_new_for_name (bus, - "org.freedesktop.UDisks", - "/org/freedesktop/UDisks", - "org.freedesktop.UDisks"); - - error = NULL; - if (!org_freedesktop_UDisks_drive_inhibit_all_polling (proxy, - (const char **) options, - &cookie, - &error)) { - g_print ("Inhibit all polling failed: %s\n", error->message); - g_error_free (error); - goto out; + char *cookie; + DBusGProxy *proxy; + GError *error; + char **options; + gint ret; + + options = NULL; + cookie = NULL; + ret = 127; + + if (argc > 0 && strcmp (argv[0], "--") == 0) + { + argv++; + argc--; + } + + proxy + = dbus_g_proxy_new_for_name (bus, "org.freedesktop.UDisks", "/org/freedesktop/UDisks", "org.freedesktop.UDisks"); + + error = NULL; + if (!org_freedesktop_UDisks_drive_inhibit_all_polling (proxy, (const char **) options, &cookie, &error)) + { + g_print ("Inhibit all polling failed: %s\n", error->message); + g_error_free (error); + goto out; + } + + if (argc == 0) + { + g_print ("Inhibiting polling on all devices. Press Ctrl+C to exit.\n"); + while (TRUE) + sleep (100000000); + } + else + { + GError * error; + gint exit_status; + + error = NULL; + if (!g_spawn_sync (NULL, /* working dir */ + argv, NULL, /* envp */ + G_SPAWN_SEARCH_PATH, NULL, /* child_setup */ + NULL, /* user_data */ + NULL, /* standard_output */ + NULL, /* standard_error */ + &exit_status, /* exit_status */ + &error)) + { + g_printerr ("Error launching program: %s\n", error->message); + g_error_free (error); + ret = 126; + goto out; } - if (argc == 0) { - g_print ("Inhibiting polling on all devices. Press Ctrl+C to exit.\n"); - while (TRUE) - sleep (100000000); - } else { - GError *error; - gint exit_status; - - error = NULL; - if (!g_spawn_sync (NULL, /* working dir */ - argv, - NULL, /* envp */ - G_SPAWN_SEARCH_PATH, - NULL, /* child_setup */ - NULL, /* user_data */ - NULL, /* standard_output */ - NULL, /* standard_error */ - &exit_status, /* exit_status */ - &error)) { - g_printerr ("Error launching program: %s\n", error->message); - g_error_free (error); - ret = 126; - goto out; - } - - if (WIFEXITED (exit_status)) - ret = WEXITSTATUS (exit_status); - else - ret = 125; - } + if (WIFEXITED (exit_status)) + ret = WEXITSTATUS (exit_status); + else + ret = 125; + } -out: - g_free (cookie); - return ret; + out: + g_free (cookie); + return ret; } /* ---------------------------------------------------------------------------------------------------- */ static gint do_set_spindown (const char *object_path, - gint argc, - gchar *argv[]) + gint argc, + gchar *argv[]) { - char *cookie; - DBusGProxy *proxy; - GError *error; - char **options; - gint ret; - - options = NULL; - cookie = NULL; - ret = 127; - - if (argc > 0 && strcmp (argv[0], "--") == 0) { - argv++; - argc--; - } - - proxy = dbus_g_proxy_new_for_name (bus, - "org.freedesktop.UDisks", - object_path, - "org.freedesktop.UDisks.Device"); - - error = NULL; - if (!org_freedesktop_UDisks_Device_drive_set_spindown_timeout (proxy, - opt_spindown_seconds, - (const char **) options, - &cookie, - &error)) { - g_print ("Setting spindown failed: %s\n", error->message); - g_error_free (error); - goto out; + char *cookie; + DBusGProxy *proxy; + GError *error; + char **options; + gint ret; + + options = NULL; + cookie = NULL; + ret = 127; + + if (argc > 0 && strcmp (argv[0], "--") == 0) + { + argv++; + argc--; + } + + proxy = dbus_g_proxy_new_for_name (bus, "org.freedesktop.UDisks", object_path, "org.freedesktop.UDisks.Device"); + + error = NULL; + if (!org_freedesktop_UDisks_Device_drive_set_spindown_timeout (proxy, + opt_spindown_seconds, + (const char **) options, + &cookie, + &error)) + { + g_print ("Setting spindown failed: %s\n", error->message); + g_error_free (error); + goto out; + } + + if (argc == 0) + { + g_print ("Set spindown on %s to %d seconds. Press Ctrl+C to exit.\n", object_path, opt_spindown_seconds); + while (TRUE) + sleep (100000000); + } + else + { + GError * error; + gint exit_status; + + error = NULL; + if (!g_spawn_sync (NULL, /* working dir */ + argv, NULL, /* envp */ + G_SPAWN_SEARCH_PATH, NULL, /* child_setup */ + NULL, /* user_data */ + NULL, /* standard_output */ + NULL, /* standard_error */ + &exit_status, /* exit_status */ + &error)) + { + g_printerr ("Error launching program: %s\n", error->message); + g_error_free (error); + ret = 126; + goto out; } - if (argc == 0) { - g_print ("Set spindown on %s to %d seconds. Press Ctrl+C to exit.\n", - object_path, opt_spindown_seconds); - while (TRUE) - sleep (100000000); - } else { - GError *error; - gint exit_status; - - error = NULL; - if (!g_spawn_sync (NULL, /* working dir */ - argv, - NULL, /* envp */ - G_SPAWN_SEARCH_PATH, - NULL, /* child_setup */ - NULL, /* user_data */ - NULL, /* standard_output */ - NULL, /* standard_error */ - &exit_status, /* exit_status */ - &error)) { - g_printerr ("Error launching program: %s\n", error->message); - g_error_free (error); - ret = 126; - goto out; - } - - if (WIFEXITED (exit_status)) - ret = WEXITSTATUS (exit_status); - else - ret = 125; - } + if (WIFEXITED (exit_status)) + ret = WEXITSTATUS (exit_status); + else + ret = 125; + } -out: - g_free (cookie); - return ret; + out: + g_free (cookie); + return ret; } /* ---------------------------------------------------------------------------------------------------- */ static gint -do_set_spindown_all (gint argc, - gchar *argv[]) +do_set_spindown_all (gint argc, + gchar *argv[]) { - char *cookie; - DBusGProxy *proxy; - GError *error; - char **options; - gint ret; - - options = NULL; - cookie = NULL; - ret = 127; - - if (argc > 0 && strcmp (argv[0], "--") == 0) { - argv++; - argc--; - } - - proxy = dbus_g_proxy_new_for_name (bus, - "org.freedesktop.UDisks", - "/org/freedesktop/UDisks", - "org.freedesktop.UDisks"); - - error = NULL; - if (!org_freedesktop_UDisks_drive_set_all_spindown_timeouts (proxy, - opt_spindown_seconds, - (const char **) options, - &cookie, - &error)) { - g_print ("Setting spindown failed: %s\n", error->message); - g_error_free (error); - goto out; + char *cookie; + DBusGProxy *proxy; + GError *error; + char **options; + gint ret; + + options = NULL; + cookie = NULL; + ret = 127; + + if (argc > 0 && strcmp (argv[0], "--") == 0) + { + argv++; + argc--; + } + + proxy + = dbus_g_proxy_new_for_name (bus, "org.freedesktop.UDisks", "/org/freedesktop/UDisks", "org.freedesktop.UDisks"); + + error = NULL; + if (!org_freedesktop_UDisks_drive_set_all_spindown_timeouts (proxy, + opt_spindown_seconds, + (const char **) options, + &cookie, + &error)) + { + g_print ("Setting spindown failed: %s\n", error->message); + g_error_free (error); + goto out; + } + + if (argc == 0) + { + g_print ("Set spindown for all drives to %d seconds. Press Ctrl+C to exit.\n", opt_spindown_seconds); + while (TRUE) + sleep (100000000); + } + else + { + GError * error; + gint exit_status; + + error = NULL; + if (!g_spawn_sync (NULL, /* working dir */ + argv, NULL, /* envp */ + G_SPAWN_SEARCH_PATH, NULL, /* child_setup */ + NULL, /* user_data */ + NULL, /* standard_output */ + NULL, /* standard_error */ + &exit_status, /* exit_status */ + &error)) + { + g_printerr ("Error launching program: %s\n", error->message); + g_error_free (error); + ret = 126; + goto out; } - if (argc == 0) { - g_print ("Set spindown for all drives to %d seconds. Press Ctrl+C to exit.\n", - opt_spindown_seconds); - while (TRUE) - sleep (100000000); - } else { - GError *error; - gint exit_status; - - error = NULL; - if (!g_spawn_sync (NULL, /* working dir */ - argv, - NULL, /* envp */ - G_SPAWN_SEARCH_PATH, - NULL, /* child_setup */ - NULL, /* user_data */ - NULL, /* standard_output */ - NULL, /* standard_error */ - &exit_status, /* exit_status */ - &error)) { - g_printerr ("Error launching program: %s\n", error->message); - g_error_free (error); - ret = 126; - goto out; - } - - if (WIFEXITED (exit_status)) - ret = WEXITSTATUS (exit_status); - else - ret = 125; - } + if (WIFEXITED (exit_status)) + ret = WEXITSTATUS (exit_status); + else + ret = 125; + } -out: - g_free (cookie); - return ret; + out: + g_free (cookie); + return ret; } /* ---------------------------------------------------------------------------------------------------- */ static gint -do_inhibit (gint argc, - gchar *argv[]) +do_inhibit (gint argc, + gchar *argv[]) { - char *cookie; - DBusGProxy *proxy; - GError *error; - gint ret; - - cookie = NULL; - ret = 127; - - if (argc > 0 && strcmp (argv[0], "--") == 0) { - argv++; - argc--; - } - - proxy = dbus_g_proxy_new_for_name (bus, - "org.freedesktop.UDisks", - "/org/freedesktop/UDisks", - "org.freedesktop.UDisks"); - - error = NULL; - if (!org_freedesktop_UDisks_inhibit (proxy, - &cookie, - &error)) { - g_print ("Inhibit all polling failed: %s\n", error->message); - g_error_free (error); - goto out; + char *cookie; + DBusGProxy *proxy; + GError *error; + gint ret; + + cookie = NULL; + ret = 127; + + if (argc > 0 && strcmp (argv[0], "--") == 0) + { + argv++; + argc--; + } + + proxy + = dbus_g_proxy_new_for_name (bus, "org.freedesktop.UDisks", "/org/freedesktop/UDisks", "org.freedesktop.UDisks"); + + error = NULL; + if (!org_freedesktop_UDisks_inhibit (proxy, &cookie, &error)) + { + g_print ("Inhibit all polling failed: %s\n", error->message); + g_error_free (error); + goto out; + } + + if (argc == 0) + { + g_print ("Inhibiting the daemon. Press Ctrl+C to exit.\n"); + while (TRUE) + sleep (100000000); + } + else + { + GError * error; + gint exit_status; + + error = NULL; + if (!g_spawn_sync (NULL, /* working dir */ + argv, NULL, /* envp */ + G_SPAWN_SEARCH_PATH, NULL, /* child_setup */ + NULL, /* user_data */ + NULL, /* standard_output */ + NULL, /* standard_error */ + &exit_status, /* exit_status */ + &error)) + { + g_printerr ("Error launching program: %s\n", error->message); + g_error_free (error); + ret = 126; + goto out; } - if (argc == 0) { - g_print ("Inhibiting the daemon. Press Ctrl+C to exit.\n"); - while (TRUE) - sleep (100000000); - } else { - GError *error; - gint exit_status; - - error = NULL; - if (!g_spawn_sync (NULL, /* working dir */ - argv, - NULL, /* envp */ - G_SPAWN_SEARCH_PATH, - NULL, /* child_setup */ - NULL, /* user_data */ - NULL, /* standard_output */ - NULL, /* standard_error */ - &exit_status, /* exit_status */ - &error)) { - g_printerr ("Error launching program: %s\n", error->message); - g_error_free (error); - ret = 126; - goto out; - } + if (WIFEXITED (exit_status)) + ret = WEXITSTATUS (exit_status); + else + ret = 125; + } - if (WIFEXITED (exit_status)) - ret = WEXITSTATUS (exit_status); - else - ret = 125; - } - -out: - g_free (cookie); - return ret; + out: + g_free (cookie); + return ret; } /* ---------------------------------------------------------------------------------------------------- */ static gint -ptr_str_array_compare (const gchar **a, const gchar **b) +ptr_str_array_compare (const gchar **a, + const gchar **b) { - return g_strcmp0 (*a, *b); + return g_strcmp0 (*a, *b); } static gchar * device_file_to_object_path (const gchar *device_file) { - gchar *object_path; - DBusGProxy *proxy; - GError *error; - struct stat statbuf; - - object_path = NULL; - error = NULL; - - if (stat (device_file, &statbuf) != 0) { - g_print ("Cannot stat device file %s: %m\n", device_file); - goto out; - } - - if (!S_ISBLK (statbuf.st_mode)) { - g_print ("Device file %s is not a block device: %m\n", device_file); - goto out; - } - - proxy = dbus_g_proxy_new_for_name (bus, - "org.freedesktop.UDisks", - "/org/freedesktop/UDisks", - "org.freedesktop.UDisks"); - - error = NULL; - if (!org_freedesktop_UDisks_find_device_by_major_minor (proxy, - major (statbuf.st_rdev), - minor (statbuf.st_rdev), - &object_path, - &error)) { - g_print ("Cannot find device with major:minor %d:%d: %s\n", - major (statbuf.st_rdev), - minor (statbuf.st_rdev), - error->message); - g_error_free (error); - goto out; - } + gchar *object_path; + DBusGProxy *proxy; + GError *error; + struct stat statbuf; + + object_path = NULL; + error = NULL; + + if (stat (device_file, &statbuf) != 0) + { + g_print ("Cannot stat device file %s: %m\n", device_file); + goto out; + } + + if (!S_ISBLK (statbuf.st_mode)) + { + g_print ("Device file %s is not a block device: %m\n", device_file); + goto out; + } + + proxy + = dbus_g_proxy_new_for_name (bus, "org.freedesktop.UDisks", "/org/freedesktop/UDisks", "org.freedesktop.UDisks"); + + error = NULL; + if (!org_freedesktop_UDisks_find_device_by_major_minor (proxy, + major (statbuf.st_rdev), + minor (statbuf.st_rdev), + &object_path, + &error)) + { + g_print ("Cannot find device with major:minor %d:%d: %s\n", + major (statbuf.st_rdev), + minor (statbuf.st_rdev), + error->message); + g_error_free (error); + goto out; + } out: - return object_path; + return object_path; } - int -main (int argc, char **argv) +main (int argc, + char **argv) { - int ret; - GOptionContext *context; - GError *error = NULL; - unsigned int n; - gchar *device_file; - static GOptionEntry entries [] = { - { "enumerate", 0, 0, G_OPTION_ARG_NONE, &opt_enumerate, "Enumerate objects paths for devices", NULL }, - { "enumerate-device-files", 0, 0, G_OPTION_ARG_NONE, &opt_enumerate_device_files, "Enumerate device files for devices", NULL }, - { "dump", 0, 0, G_OPTION_ARG_NONE, &opt_dump, "Dump all information about all devices", NULL }, - { "monitor", 0, 0, G_OPTION_ARG_NONE, &opt_monitor, "Monitor activity from the disk daemon", NULL }, - { "monitor-detail", 0, 0, G_OPTION_ARG_NONE, &opt_monitor_detail, "Monitor with detail", NULL }, - { "show-info", 0, 0, G_OPTION_ARG_STRING, &opt_show_info, "Show information about a device file", NULL }, - { "inhibit-polling", 0, 0, G_OPTION_ARG_STRING, &opt_inhibit_polling, "Inhibit polling", NULL }, - { "inhibit-all-polling", 0, 0, G_OPTION_ARG_NONE, &opt_inhibit_all_polling, "Inhibit all polling", NULL }, - { "poll-for-media", 0, 0, G_OPTION_ARG_STRING, &opt_poll_for_media, "Poll for media", NULL }, - { "set-spindown", 0, 0, G_OPTION_ARG_STRING, &opt_drive_spindown, "Set spindown timeout for drive", NULL }, - { "set-spindown-all", 0, 0, G_OPTION_ARG_NONE, &opt_drive_spindown_all, "Set spindown timeout for all drives", NULL }, - { "spindown-timeout", 0, 0, G_OPTION_ARG_INT, &opt_spindown_seconds, "Spindown timeout in seconds", NULL }, - { "inhibit", 0, 0, G_OPTION_ARG_NONE, &opt_inhibit, "Inhibit the daemon", NULL }, - - { "mount", 0, 0, G_OPTION_ARG_STRING, &opt_mount, "Mount the given device", NULL }, - { "mount-fstype", 0, 0, G_OPTION_ARG_STRING, &opt_mount_fstype, "Specify file system type", NULL }, - { "mount-options", 0, 0, G_OPTION_ARG_STRING, &opt_mount_options, "Mount options separated by comma", NULL }, - - { "unmount", 0, 0, G_OPTION_ARG_STRING, &opt_unmount, "Unmount the given device", NULL }, - { "unmount-options", 0, 0, G_OPTION_ARG_STRING, &opt_unmount_options, "Unmount options separated by comma", NULL }, - { "detach", 0, 0, G_OPTION_ARG_STRING, &opt_detach, "Detach the given device", NULL }, - { "detach-options", 0, 0, G_OPTION_ARG_STRING, &opt_detach_options, "Detach options separated by comma", NULL }, - { "ata-smart-refresh", 0, 0, G_OPTION_ARG_STRING, &opt_ata_smart_refresh, "Refresh ATA SMART data", NULL }, - { "ata-smart-wakeup", 0, 0, G_OPTION_ARG_NONE, &opt_ata_smart_wakeup, "Wake up the disk if it is not awake", NULL }, - { "ata-smart-simulate", 0, 0, G_OPTION_ARG_STRING, &opt_ata_smart_simulate, "Inject libatasmart BLOB for testing", NULL }, - { NULL } - }; - - setlocale (LC_ALL, ""); - - ret = 1; - device_file = NULL; - - g_type_init (); - - context = g_option_context_new ("udisks commandline tool"); - g_option_context_set_description (context, "See the udisks man page for details."); - g_option_context_add_main_entries (context, entries, NULL); - g_option_context_parse (context, &argc, &argv, NULL); - - loop = g_main_loop_new (NULL, FALSE); - - bus = dbus_g_bus_get (DBUS_BUS_SYSTEM, &error); - if (bus == NULL) { - g_warning ("Couldn't connect to system bus: %s", error->message); - g_error_free (error); - goto out; + int ret; + GOptionContext *context; + GError *error = NULL; + unsigned int n; + gchar *device_file; + static GOptionEntry + entries[] = + { + { "enumerate", 0, 0, G_OPTION_ARG_NONE, &opt_enumerate, "Enumerate objects paths for devices", NULL }, + { "enumerate-device-files", 0, 0, G_OPTION_ARG_NONE, &opt_enumerate_device_files, + "Enumerate device files for devices", NULL }, + { "dump", 0, 0, G_OPTION_ARG_NONE, &opt_dump, "Dump all information about all devices", NULL }, + { "monitor", 0, 0, G_OPTION_ARG_NONE, &opt_monitor, "Monitor activity from the disk daemon", NULL }, + { "monitor-detail", 0, 0, G_OPTION_ARG_NONE, &opt_monitor_detail, "Monitor with detail", NULL }, + { "show-info", 0, 0, G_OPTION_ARG_STRING, &opt_show_info, "Show information about a device file", NULL }, + { "inhibit-polling", 0, 0, G_OPTION_ARG_STRING, &opt_inhibit_polling, "Inhibit polling", NULL }, + { "inhibit-all-polling", 0, 0, G_OPTION_ARG_NONE, &opt_inhibit_all_polling, "Inhibit all polling", NULL }, + { "poll-for-media", 0, 0, G_OPTION_ARG_STRING, &opt_poll_for_media, "Poll for media", NULL }, + { "set-spindown", 0, 0, G_OPTION_ARG_STRING, &opt_drive_spindown, "Set spindown timeout for drive", NULL }, + { "set-spindown-all", 0, 0, G_OPTION_ARG_NONE, &opt_drive_spindown_all, + "Set spindown timeout for all drives", NULL }, + { "spindown-timeout", 0, 0, G_OPTION_ARG_INT, &opt_spindown_seconds, "Spindown timeout in seconds", NULL }, + { "inhibit", 0, 0, G_OPTION_ARG_NONE, &opt_inhibit, "Inhibit the daemon", NULL }, + + { "mount", 0, 0, G_OPTION_ARG_STRING, &opt_mount, "Mount the given device", NULL }, + { "mount-fstype", 0, 0, G_OPTION_ARG_STRING, &opt_mount_fstype, "Specify file system type", NULL }, + { "mount-options", 0, 0, G_OPTION_ARG_STRING, &opt_mount_options, "Mount options separated by comma", + NULL }, + + { "unmount", 0, 0, G_OPTION_ARG_STRING, &opt_unmount, "Unmount the given device", NULL }, + { "unmount-options", 0, 0, G_OPTION_ARG_STRING, &opt_unmount_options, + "Unmount options separated by comma", NULL }, + { "detach", 0, 0, G_OPTION_ARG_STRING, &opt_detach, "Detach the given device", NULL }, + { "detach-options", 0, 0, G_OPTION_ARG_STRING, &opt_detach_options, "Detach options separated by comma", + NULL }, + { "ata-smart-refresh", 0, 0, G_OPTION_ARG_STRING, &opt_ata_smart_refresh, "Refresh ATA SMART data", NULL }, + { "ata-smart-wakeup", 0, 0, G_OPTION_ARG_NONE, &opt_ata_smart_wakeup, + "Wake up the disk if it is not awake", NULL }, + { "ata-smart-simulate", 0, 0, G_OPTION_ARG_STRING, &opt_ata_smart_simulate, + "Inject libatasmart BLOB for testing", NULL }, + { NULL } }; + + setlocale (LC_ALL, ""); + + ret = 1; + device_file = NULL; + + g_type_init (); + + context = g_option_context_new ("udisks commandline tool"); + g_option_context_set_description (context, "See the udisks man page for details."); + g_option_context_add_main_entries (context, entries, NULL); + g_option_context_parse (context, &argc, &argv, NULL); + + loop = g_main_loop_new (NULL, FALSE); + + bus = dbus_g_bus_get (DBUS_BUS_SYSTEM, &error); + if (bus == NULL) + { + g_warning ("Couldn't connect to system bus: %s", error->message); + g_error_free (error); + goto out; + } + + dbus_g_object_register_marshaller (udisks_marshal_VOID__BOXED_BOOLEAN_STRING_UINT_BOOLEAN_DOUBLE, + G_TYPE_NONE, + DBUS_TYPE_G_OBJECT_PATH, + G_TYPE_BOOLEAN, + G_TYPE_STRING, + G_TYPE_UINT, + G_TYPE_BOOLEAN, + G_TYPE_DOUBLE, + G_TYPE_INVALID); + + disks_proxy = dbus_g_proxy_new_for_name (bus, + "org.freedesktop.UDisks", + "/org/freedesktop/UDisks", + "org.freedesktop.UDisks"); + dbus_g_proxy_add_signal (disks_proxy, "DeviceAdded", DBUS_TYPE_G_OBJECT_PATH, G_TYPE_INVALID); + dbus_g_proxy_add_signal (disks_proxy, "DeviceRemoved", DBUS_TYPE_G_OBJECT_PATH, G_TYPE_INVALID); + dbus_g_proxy_add_signal (disks_proxy, "DeviceChanged", DBUS_TYPE_G_OBJECT_PATH, G_TYPE_INVALID); + dbus_g_proxy_add_signal (disks_proxy, + "DeviceJobChanged", + DBUS_TYPE_G_OBJECT_PATH, + G_TYPE_BOOLEAN, + G_TYPE_STRING, + G_TYPE_UINT, + G_TYPE_BOOLEAN, + G_TYPE_DOUBLE, + G_TYPE_INVALID); + + if (opt_dump) + { + GPtrArray *devices; + if (!org_freedesktop_UDisks_enumerate_devices (disks_proxy, &devices, &error)) + { + g_warning ("Couldn't enumerate devices: %s", error->message); + g_error_free (error); + goto out; } - - dbus_g_object_register_marshaller ( - udisks_marshal_VOID__BOXED_BOOLEAN_STRING_UINT_BOOLEAN_DOUBLE, - G_TYPE_NONE, - DBUS_TYPE_G_OBJECT_PATH, - G_TYPE_BOOLEAN, - G_TYPE_STRING, - G_TYPE_UINT, - G_TYPE_BOOLEAN, - G_TYPE_DOUBLE, - G_TYPE_INVALID); - - disks_proxy = dbus_g_proxy_new_for_name (bus, - "org.freedesktop.UDisks", - "/org/freedesktop/UDisks", - "org.freedesktop.UDisks"); - dbus_g_proxy_add_signal (disks_proxy, "DeviceAdded", DBUS_TYPE_G_OBJECT_PATH, G_TYPE_INVALID); - dbus_g_proxy_add_signal (disks_proxy, "DeviceRemoved", DBUS_TYPE_G_OBJECT_PATH, G_TYPE_INVALID); - dbus_g_proxy_add_signal (disks_proxy, "DeviceChanged", DBUS_TYPE_G_OBJECT_PATH, G_TYPE_INVALID); - dbus_g_proxy_add_signal (disks_proxy, - "DeviceJobChanged", - DBUS_TYPE_G_OBJECT_PATH, - G_TYPE_BOOLEAN, - G_TYPE_STRING, - G_TYPE_UINT, - G_TYPE_BOOLEAN, - G_TYPE_DOUBLE, - G_TYPE_INVALID); - - if (opt_dump) { - GPtrArray *devices; - if (!org_freedesktop_UDisks_enumerate_devices (disks_proxy, &devices, &error)) { - g_warning ("Couldn't enumerate devices: %s", error->message); - g_error_free (error); - goto out; - } - g_ptr_array_sort (devices, (GCompareFunc) ptr_str_array_compare); - g_print ("========================================================================\n"); - for (n = 0; n < devices->len; n++) { - char *object_path = devices->pdata[n]; - do_show_info (object_path); - g_print ("\n" - "========================================================================\n"); - } - g_ptr_array_foreach (devices, (GFunc) g_free, NULL); - g_ptr_array_free (devices, TRUE); - } else if (opt_enumerate) { - GPtrArray *devices; - if (!org_freedesktop_UDisks_enumerate_devices (disks_proxy, &devices, &error)) { - g_warning ("Couldn't enumerate devices: %s", error->message); - g_error_free (error); - goto out; - } - for (n = 0; n < devices->len; n++) { - char *object_path = devices->pdata[n]; - g_print ("%s\n", object_path); - } - g_ptr_array_foreach (devices, (GFunc) g_free, NULL); - g_ptr_array_free (devices, TRUE); - } else if (opt_enumerate_device_files) { - gchar **device_files; - if (!org_freedesktop_UDisks_enumerate_device_files (disks_proxy, &device_files, &error)) { - g_warning ("Couldn't enumerate device files: %s", error->message); - g_error_free (error); - goto out; - } - for (n = 0; device_files != NULL && device_files[n] != NULL; n++) { - g_print ("%s\n", device_files[n]); - } - g_strfreev (device_files); - } else if (opt_monitor || opt_monitor_detail) { - if (!do_monitor ()) - goto out; - } else if (opt_show_info != NULL) { - device_file = device_file_to_object_path (opt_show_info); - if (device_file == NULL) - goto out; - do_show_info (device_file); - } else if (opt_inhibit_polling != NULL) { - device_file = device_file_to_object_path (opt_inhibit_polling); - if (device_file == NULL) - goto out; - ret = do_inhibit_polling (device_file, argc - 1, argv + 1); - goto out; - } else if (opt_poll_for_media != NULL) { - device_file = device_file_to_object_path (opt_poll_for_media); - if (device_file == NULL) - goto out; - ret = do_poll_for_media (device_file); - goto out; - } else if (opt_inhibit_all_polling) { - ret = do_inhibit_all_polling (argc - 1, argv + 1); - goto out; - } else if (opt_drive_spindown != NULL) { - device_file = device_file_to_object_path (opt_drive_spindown); - if (device_file == NULL) - goto out; - ret = do_set_spindown (device_file, argc - 1, argv + 1); - goto out; - } else if (opt_drive_spindown_all) { - ret = do_set_spindown_all (argc - 1, argv + 1); - goto out; - } else if (opt_inhibit) { - ret = do_inhibit (argc - 1, argv + 1); - goto out; - } else if (opt_mount != NULL) { - device_file = device_file_to_object_path (opt_mount); - if (device_file == NULL) - goto out; - do_mount (device_file, opt_mount_fstype, opt_mount_options); - } else if (opt_unmount != NULL) { - device_file = device_file_to_object_path (opt_unmount); - if (device_file == NULL) - goto out; - do_unmount (device_file, opt_unmount_options); - } else if (opt_detach != NULL) { - device_file = device_file_to_object_path (opt_detach); - if (device_file == NULL) - goto out; - do_detach (device_file, opt_detach_options); - } else if (opt_ata_smart_refresh != NULL) { - device_file = device_file_to_object_path (opt_ata_smart_refresh); - if (device_file == NULL) - goto out; - do_ata_smart_refresh (device_file, opt_ata_smart_wakeup, opt_ata_smart_simulate); - } else { - gchar *usage; - - usage = g_option_context_get_help (context, FALSE, NULL); - g_printerr ("%s", usage); - g_free (usage); - - ret = 1; - goto out; + g_ptr_array_sort (devices, (GCompareFunc) ptr_str_array_compare); + g_print ("========================================================================\n"); + for (n = 0; n < devices->len; n++) + { + char *object_path = devices->pdata[n]; + do_show_info (object_path); + g_print ("\n" + "========================================================================\n"); } + g_ptr_array_foreach (devices, (GFunc) g_free, NULL); + g_ptr_array_free (devices, TRUE); + } + else if (opt_enumerate) + { + GPtrArray *devices; + if (!org_freedesktop_UDisks_enumerate_devices (disks_proxy, &devices, &error)) + { + g_warning ("Couldn't enumerate devices: %s", error->message); + g_error_free (error); + goto out; + } + for (n = 0; n < devices->len; n++) + { + char *object_path = devices->pdata[n]; + g_print ("%s\n", object_path); + } + g_ptr_array_foreach (devices, (GFunc) g_free, NULL); + g_ptr_array_free (devices, TRUE); + } + else if (opt_enumerate_device_files) + { + gchar **device_files; + if (!org_freedesktop_UDisks_enumerate_device_files (disks_proxy, &device_files, &error)) + { + g_warning ("Couldn't enumerate device files: %s", error->message); + g_error_free (error); + goto out; + } + for (n = 0; device_files != NULL && device_files[n] != NULL; n++) + { + g_print ("%s\n", device_files[n]); + } + g_strfreev (device_files); + } + else if (opt_monitor || opt_monitor_detail) + { + if (!do_monitor ()) + goto out; + } + else if (opt_show_info != NULL) + { + device_file = device_file_to_object_path (opt_show_info); + if (device_file == NULL) + goto out; + do_show_info (device_file); + } + else if (opt_inhibit_polling != NULL) + { + device_file = device_file_to_object_path (opt_inhibit_polling); + if (device_file == NULL) + goto out; + ret = do_inhibit_polling (device_file, argc - 1, argv + 1); + goto out; + } + else if (opt_poll_for_media != NULL) + { + device_file = device_file_to_object_path (opt_poll_for_media); + if (device_file == NULL) + goto out; + ret = do_poll_for_media (device_file); + goto out; + } + else if (opt_inhibit_all_polling) + { + ret = do_inhibit_all_polling (argc - 1, argv + 1); + goto out; + } + else if (opt_drive_spindown != NULL) + { + device_file = device_file_to_object_path (opt_drive_spindown); + if (device_file == NULL) + goto out; + ret = do_set_spindown (device_file, argc - 1, argv + 1); + goto out; + } + else if (opt_drive_spindown_all) + { + ret = do_set_spindown_all (argc - 1, argv + 1); + goto out; + } + else if (opt_inhibit) + { + ret = do_inhibit (argc - 1, argv + 1); + goto out; + } + else if (opt_mount != NULL) + { + device_file = device_file_to_object_path (opt_mount); + if (device_file == NULL) + goto out; + do_mount (device_file, opt_mount_fstype, opt_mount_options); + } + else if (opt_unmount != NULL) + { + device_file = device_file_to_object_path (opt_unmount); + if (device_file == NULL) + goto out; + do_unmount (device_file, opt_unmount_options); + } + else if (opt_detach != NULL) + { + device_file = device_file_to_object_path (opt_detach); + if (device_file == NULL) + goto out; + do_detach (device_file, opt_detach_options); + } + else if (opt_ata_smart_refresh != NULL) + { + device_file = device_file_to_object_path (opt_ata_smart_refresh); + if (device_file == NULL) + goto out; + do_ata_smart_refresh (device_file, opt_ata_smart_wakeup, opt_ata_smart_simulate); + } + else + { + gchar *usage; + + usage = g_option_context_get_help (context, FALSE, NULL); + g_printerr ("%s", usage); + g_free (usage); + + ret = 1; + goto out; + } + + ret = 0; - ret = 0; - -out: - g_free (device_file); - if (disks_proxy != NULL) - g_object_unref (disks_proxy); - if (bus != NULL) - dbus_g_connection_unref (bus); - g_option_context_free (context); - - return ret; + out: + g_free (device_file); + if (disks_proxy != NULL) + g_object_unref (disks_proxy); + if (bus != NULL) + dbus_g_connection_unref (bus); + g_option_context_free (context); + + return ret; } diff --git a/tools/umount-udisks.c b/tools/umount-udisks.c index c8a6b50..87a7f64 100644 --- a/tools/umount-udisks.c +++ b/tools/umount-udisks.c @@ -50,96 +50,96 @@ static void do_unmount (const char *object_path, const char *options) { - DBusGProxy *proxy; - GError *error; - char **unmount_options; - - unmount_options = NULL; - if (options != NULL) - unmount_options = g_strsplit (options, ",", 0); - - proxy = dbus_g_proxy_new_for_name (bus, - "org.freedesktop.UDisks", - object_path, - "org.freedesktop.UDisks.Device"); - - error = NULL; - if (!org_freedesktop_UDisks_Device_filesystem_unmount (proxy, - (const char **) unmount_options, - &error)) { - g_print ("Unmount failed: %s\n", error->message); - g_error_free (error); - goto out; - } -out: - g_strfreev (unmount_options); + DBusGProxy *proxy; + GError *error; + char **unmount_options; + + unmount_options = NULL; + if (options != NULL) + unmount_options = g_strsplit (options, ",", 0); + + proxy = dbus_g_proxy_new_for_name (bus, "org.freedesktop.UDisks", object_path, "org.freedesktop.UDisks.Device"); + + error = NULL; + if (!org_freedesktop_UDisks_Device_filesystem_unmount (proxy, (const char **) unmount_options, &error)) + { + g_print ("Unmount failed: %s\n", error->message); + g_error_free (error); + goto out; + } + out: + g_strfreev (unmount_options); } int -main (int argc, char **argv) +main (int argc, + char **argv) { - GError *error; - DBusGProxy *disks_proxy; - int ret; - char *object_path; - struct stat st; - char *path; - - ret = 1; - bus = NULL; - path = NULL; - disks_proxy = NULL; - - g_type_init (); - - if (argc < 2 || strlen (argv[1]) == 0) { - fprintf (stderr, "%s: this program is only supposed to be invoked by umount(8).\n", argv[0]); - goto out; - } - - error = NULL; - bus = dbus_g_bus_get (DBUS_BUS_SYSTEM, &error); - if (bus == NULL) { - g_warning ("Couldn't connect to system bus: %s", error->message); - g_error_free (error); - goto out; - } - - disks_proxy = dbus_g_proxy_new_for_name (bus, - "org.freedesktop.UDisks", - "/org/freedesktop/UDisks", - "org.freedesktop.UDisks"); - - error = NULL; - - if (stat (argv[1], &st) < 0) { - fprintf (stderr, "%s: could not stat %s: %s\n", argv[0], argv[1], strerror (errno)); - goto out; - } - - if (S_ISBLK (st.st_mode)) { - path = g_strdup (argv[1]); - } - else { - path = g_strdup_printf ("/dev/block/%d:%d", major (st.st_dev), minor (st.st_dev)); - } - - if (!org_freedesktop_UDisks_find_device_by_device_file (disks_proxy, - path, - &object_path, - &error)) { - fprintf (stderr, "%s: no device for %s: %s\n", argv[0], argv[1], error->message); - g_error_free (error); - goto out; - } - do_unmount (object_path, NULL); - g_free (object_path); - -out: - g_free (path); - if (disks_proxy != NULL) - g_object_unref (disks_proxy); - if (bus != NULL) - dbus_g_connection_unref (bus); - return ret; + GError *error; + DBusGProxy *disks_proxy; + int ret; + char *object_path; + struct stat st; + char *path; + + ret = 1; + bus = NULL; + path = NULL; + disks_proxy = NULL; + + g_type_init (); + + if (argc < 2 || strlen (argv[1]) == 0) + { + fprintf (stderr, "%s: this program is only supposed to be invoked by umount(8).\n", argv[0]); + goto out; + } + + error = NULL; + bus = dbus_g_bus_get (DBUS_BUS_SYSTEM, &error); + if (bus == NULL) + { + g_warning ("Couldn't connect to system bus: %s", error->message); + g_error_free (error); + goto out; + } + + disks_proxy = dbus_g_proxy_new_for_name (bus, + "org.freedesktop.UDisks", + "/org/freedesktop/UDisks", + "org.freedesktop.UDisks"); + + error = NULL; + + if (stat (argv[1], &st) < 0) + { + fprintf (stderr, "%s: could not stat %s: %s\n", argv[0], argv[1], strerror (errno)); + goto out; + } + + if (S_ISBLK (st.st_mode)) + { + path = g_strdup (argv[1]); + } + else + { + path = g_strdup_printf ("/dev/block/%d:%d", major (st.st_dev), minor (st.st_dev)); + } + + if (!org_freedesktop_UDisks_find_device_by_device_file (disks_proxy, path, &object_path, &error)) + { + fprintf (stderr, "%s: no device for %s: %s\n", argv[0], argv[1], error->message); + g_error_free (error); + goto out; + } + do_unmount (object_path, NULL); + g_free (object_path); + + out: + g_free (path); + if (disks_proxy != NULL) + g_object_unref (disks_proxy); + if (bus != NULL) + dbus_g_connection_unref (bus); + return ret; }