diff options
author | Ondrej Čerman <ondrej.cerman@gmail.com> | 2018-11-27 23:25:42 +0100 |
---|---|---|
committer | Leandro A. F. Pereira <leandro@hardinfo.org> | 2018-11-30 04:57:38 -0800 |
commit | bca05f203758173c227aed228463fdddefcd8c6a (patch) | |
tree | 760dc8abb94d5279f62990ff9e4d41e97fe7bda3 /hardinfo/udisks2_util.c | |
parent | 0f3cf14d062ccd89467ecd933081b18a4e6636b9 (diff) |
devices/storage: added udisks2 support
Diffstat (limited to 'hardinfo/udisks2_util.c')
-rw-r--r-- | hardinfo/udisks2_util.c | 235 |
1 files changed, 235 insertions, 0 deletions
diff --git a/hardinfo/udisks2_util.c b/hardinfo/udisks2_util.c new file mode 100644 index 00000000..bf7948b3 --- /dev/null +++ b/hardinfo/udisks2_util.c @@ -0,0 +1,235 @@ +#include <gio/gio.h> +#include "udisks2_util.h" +#include "hardinfo.h" + +#define UDISKS2_INTERFACE "org.freedesktop.UDisks2" +#define UDISKS2_MANAGER_INTERFACE "org.freedesktop.UDisks2.Manager" +#define UDISKS2_BLOCK_INTERFACE "org.freedesktop.UDisks2.Block" +#define UDISKS2_DRIVE_INTERFACE "org.freedesktop.UDisks2.Drive" +#define UDISKS2_DRIVE_ATA_INTERFACE "org.freedesktop.UDisks2.Drive.Ata" +#define DBUS_PROPERTIES_INTERFACE "org.freedesktop.DBus.Properties" +#define UDISKS2_MANAGER_OBJ_PATH "/org/freedesktop/UDisks2/Manager" +#define UDISKS2_BLOCK_DEVICES_PATH "/org/freedesktop/UDisks2/block_devices" + +GDBusConnection* udisks2_conn = NULL; + +GVariant* get_dbus_property(GDBusProxy* proxy, const gchar *interface, + const gchar *property) { + GVariant *result, *v = NULL; + GError *error = NULL; + + result = g_dbus_proxy_call_sync(proxy, "Get", + g_variant_new ("(ss)", interface, property), + G_DBUS_CALL_FLAGS_NONE, -1, NULL, &error); + + if (error != NULL) { + g_error_free (error); + return NULL; + } + + g_variant_get(result, "(v)", &v); + g_variant_unref(result); + return v; +} + +GDBusProxy* get_udisks2_drive_proxy(GDBusConnection *conn, const gchar* blockdev_name) { + GDBusProxy *proxy; + GVariant *v; + GError *error = NULL; + gchar *path; + const gchar *drive_path; + + // get block device proxy + path = g_strdup_printf("%s/%s", UDISKS2_BLOCK_DEVICES_PATH, blockdev_name); + proxy = g_dbus_proxy_new_sync(conn, G_DBUS_PROXY_FLAGS_NONE, NULL, + UDISKS2_INTERFACE, path, + DBUS_PROPERTIES_INTERFACE, NULL, &error); + g_free(path); + path = NULL; + if (error != NULL) { + g_error_free (error); + g_object_unref(proxy); + return NULL; + } + + // get drive object path + v = get_dbus_property(proxy, UDISKS2_BLOCK_INTERFACE, "Drive"); + if (v) { + drive_path = g_variant_get_string(v, NULL); + if (strcmp(drive_path, "/") != 0) { + path = g_strdup(drive_path); + } + g_variant_unref(v); + } + g_object_unref(proxy); + proxy = NULL; + + if (path == NULL) + return NULL; + + // get drive proxy + proxy = g_dbus_proxy_new_sync(conn, G_DBUS_PROXY_FLAGS_NONE, NULL, + UDISKS2_INTERFACE, path, + DBUS_PROPERTIES_INTERFACE, NULL, &error); + g_free(path); + if (error != NULL) { + g_error_free (error); + return NULL; + } + + return proxy; +} + +GDBusConnection* get_udisks2_connection(void) { + GDBusConnection *conn; + GDBusProxy *proxy; + GError *error = NULL; + GVariant *result = NULL; + + // connection to system bus + conn = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &error); + if (error != NULL) { + g_error_free (error); + return NULL; + } + + // let's check if udisks2 is responding + proxy = g_dbus_proxy_new_sync(conn, G_DBUS_PROXY_FLAGS_NONE, NULL, + UDISKS2_INTERFACE, UDISKS2_MANAGER_OBJ_PATH, + DBUS_PROPERTIES_INTERFACE, NULL, &error); + if (error != NULL) { + g_error_free (error); + g_object_unref(conn); + return NULL; + } + + result = get_dbus_property(proxy, UDISKS2_MANAGER_INTERFACE, "Version"); + g_object_unref(proxy); + if (error != NULL) { + g_error_free (error); + return NULL; + } + + // OK, let's return connection to system bus + g_variant_unref(result); + return conn; +} + +udiskd *udiskd_new() { + return g_new0(udiskd, 1); +} + +void udiskd_free(udiskd *u) { + if (u) { + g_free(u->block_dev); + g_free(u->media); + g_free(u->media_compatibility); + g_free(u); + } +} + +udiskd *get_udisks2_drive_info(const gchar *blockdev) { + GDBusProxy *drive; + GVariant *v; + const gchar *str; + udiskd *u; + + drive = get_udisks2_drive_proxy(udisks2_conn, blockdev); + if (!drive){ + return NULL; + } + + u = udiskd_new(); + u->block_dev = g_strdup(blockdev); + + v = get_dbus_property(drive, UDISKS2_DRIVE_INTERFACE, "Serial"); + if (v){ + u->serial = g_variant_dup_string(v, NULL); + g_variant_unref(v); + } + v = get_dbus_property(drive, UDISKS2_DRIVE_INTERFACE, "RotationRate"); + if (v){ + u->rotation_rate = g_variant_get_int32(v); + g_variant_unref(v); + } + v = get_dbus_property(drive, UDISKS2_DRIVE_INTERFACE, "Size"); + if (v){ + u->size = g_variant_get_uint64(v); + g_variant_unref(v); + } + v = get_dbus_property(drive, UDISKS2_DRIVE_INTERFACE, "Media"); + if (v){ + str = g_variant_get_string(v, NULL); + if (strcmp(str, "") != 0) { + u->media = g_strdup(str); + } + g_variant_unref(v); + } + v = get_dbus_property(drive, UDISKS2_DRIVE_INTERFACE, "MediaCompatibility"); + if (v){ + GVariantIter *iter; + g_variant_get(v, "as", &iter); + while (g_variant_iter_loop (iter, "s", &str)){ + if (u->media_compatibility == NULL){ + u->media_compatibility = g_strdup(str); + } + else{ + u->media_compatibility = h_strdup_cprintf(", %s", u->media_compatibility, str); + } + } + g_variant_iter_free (iter); + g_variant_unref(v); + } + v = get_dbus_property(drive, UDISKS2_DRIVE_INTERFACE, "Ejectable"); + if (v){ + u->ejectable = g_variant_get_boolean(v); + g_variant_unref(v); + } + v = get_dbus_property(drive, UDISKS2_DRIVE_INTERFACE, "Removable"); + if (v){ + u->removable = g_variant_get_boolean(v); + g_variant_unref(v); + } + v = get_dbus_property(drive, UDISKS2_DRIVE_ATA_INTERFACE, "SmartEnabled"); + if (v){ + u->smart_enabled = g_variant_get_boolean(v); + g_variant_unref(v); + } + if (u->smart_enabled){ + v = get_dbus_property(drive, UDISKS2_DRIVE_ATA_INTERFACE, "SmartPowerOnSeconds"); + if (v){ + u->smart_poweron = g_variant_get_uint64(v); + g_variant_unref(v); + } + v = get_dbus_property(drive, UDISKS2_DRIVE_ATA_INTERFACE, "SmartNumBadSectors"); + if (v){ + u->smart_bad_sectors = g_variant_get_int64(v); + g_variant_unref(v); + } + v = get_dbus_property(drive, UDISKS2_DRIVE_ATA_INTERFACE, "SmartTemperature"); + if (v){ + u->smart_temperature = (gint) (g_variant_get_double(v) - 273.15); + g_variant_unref(v); + } + v = get_dbus_property(drive, UDISKS2_DRIVE_ATA_INTERFACE, "SmartFailing"); + if (v){ + u->smart_failing = g_variant_get_boolean(v); + g_variant_unref(v); + } + } + + g_object_unref(drive); + return u; +} + +gboolean udisks2_init(){ + udisks2_conn = get_udisks2_connection(); + return (udisks2_conn != NULL); +} + +void udisks2_shutdown(){ + if (udisks2_conn != NULL){ + g_object_unref(udisks2_conn); + udisks2_conn = NULL; + } +} |