diff options
-rw-r--r-- | hardinfo/udisks2_util.c | 205 | ||||
-rw-r--r-- | includes/udisks2_util.h | 8 | ||||
-rw-r--r-- | modules/devices.c | 11 | ||||
-rw-r--r-- | modules/devices/storage.c | 217 | ||||
-rw-r--r-- | pixmaps/media-floppy.png | bin | 0 -> 1006 bytes |
5 files changed, 306 insertions, 135 deletions
diff --git a/hardinfo/udisks2_util.c b/hardinfo/udisks2_util.c index 575e2bc6..619cddf1 100644 --- a/hardinfo/udisks2_util.c +++ b/hardinfo/udisks2_util.c @@ -5,6 +5,8 @@ #define UDISKS2_INTERFACE "org.freedesktop.UDisks2" #define UDISKS2_MANAGER_INTERFACE "org.freedesktop.UDisks2.Manager" #define UDISKS2_BLOCK_INTERFACE "org.freedesktop.UDisks2.Block" +#define UDISKS2_LOOP_INTERFACE "org.freedesktop.UDisks2.Loop" +#define UDISKS2_PARTITION_INTERFACE "org.freedesktop.UDisks2.Partition" #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" @@ -32,52 +34,146 @@ GVariant* get_dbus_property(GDBusProxy* proxy, const gchar *interface, return v; } -GDBusProxy* get_udisks2_drive_proxy(GDBusConnection *conn, const gchar* blockdev_name) { +// this function works with udisks2 version 2.7.2 or newer +GSList* get_block_dev_paths_from_udisks2(GDBusConnection* conn){ GDBusProxy *proxy; - GVariant *v; + GVariant *options, *v; + GVariantIter *iter; GError *error = NULL; - gchar *path; - const gchar *drive_path; + GSList *block_paths = NULL; + const gchar *block_path = NULL; - // 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) { + UDISKS2_INTERFACE, UDISKS2_MANAGER_OBJ_PATH, + UDISKS2_MANAGER_INTERFACE, NULL, &error); + options = g_variant_new_parsed("@a{sv} { %s: <true> }", + "auth.no_user_interaction"); + 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); - } + v = g_dbus_proxy_call_sync(proxy, "GetBlockDevices", + g_variant_new_tuple(&options, 1), + G_DBUS_CALL_FLAGS_NONE, -1, NULL, &error); g_object_unref(proxy); - proxy = NULL; - if (path == NULL) + if (error != NULL){ + g_error_free (error); 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); + g_variant_get(v, "(ao)", &iter); + while (g_variant_iter_loop (iter, "o", &block_path)){ + block_paths = g_slist_append(block_paths, g_strdup(block_path)); + } + + g_variant_iter_free (iter); + g_variant_unref(v); + return block_paths; +} + +GSList* get_block_dev_paths_from_sysfs(){ + GSList *block_paths = NULL; + GDir *dir; + gchar *path; + const gchar *entry; + + dir = g_dir_open("/sys/class/block", 0, NULL); + if (!dir) return NULL; + + while ((entry = g_dir_read_name(dir))) { + path = g_strdup_printf("%s/%s", UDISKS2_BLOCK_DEVICES_PATH, entry); + block_paths = g_slist_append(block_paths, path); } - return proxy; + g_dir_close(dir); + return block_paths; +} + +GSList* udisks2_drives_func_caller(GDBusConnection* conn, + gpointer (*func)(const char*, GDBusProxy*)) { + GDBusProxy *proxy, *drive_proxy; + GVariant *block_v, *v; + GSList *result_list = NULL, *block_dev_list, *node; + GError *error = NULL; + gpointer output; + + gchar *block_path = NULL; + const gchar *block_dev, *drive_path = NULL; + + if (conn == NULL) + return NULL; + + // get block devices + block_dev_list = get_block_dev_paths_from_udisks2(conn); + if (block_dev_list == NULL) + block_dev_list = get_block_dev_paths_from_sysfs(); + + for (node = block_dev_list; node != NULL; node = node->next) { + block_path = (gchar *)node->data; + proxy = g_dbus_proxy_new_sync(conn, G_DBUS_PROXY_FLAGS_NONE, + NULL, UDISKS2_INTERFACE, block_path, + DBUS_PROPERTIES_INTERFACE, NULL, &error); + if (error){ + g_error_free(error); + error = NULL; + continue; + } + + // Skip partitions + v = get_dbus_property(proxy, UDISKS2_PARTITION_INTERFACE, "Size"); + if (v){ + g_variant_unref(v); + g_object_unref(proxy); + continue; + } + + // Skip loop devices + v = get_dbus_property(proxy, UDISKS2_LOOP_INTERFACE, "BackingFile"); + if (v){ + g_variant_unref(v); + g_object_unref(proxy); + continue; + } + + block_dev = block_path + strlen(UDISKS2_BLOCK_DEVICES_PATH) + 1; + drive_path = NULL; + + // let's find drive proxy + v = get_dbus_property(proxy, UDISKS2_BLOCK_INTERFACE, "Drive"); + if (v){ + drive_path = g_variant_get_string(v, NULL); + + if (g_strcmp0(drive_path, "/") != 0){ + drive_proxy = g_dbus_proxy_new_sync(conn, + G_DBUS_PROXY_FLAGS_NONE, NULL, + UDISKS2_INTERFACE, drive_path, + DBUS_PROPERTIES_INTERFACE, NULL, &error); + + if (error == NULL) { + // call requested function + output = func(block_dev, drive_proxy); + + if (output != NULL){ + result_list = g_slist_append(result_list, output); + } + g_object_unref(drive_proxy); + } + else { + g_error_free(error); + error = NULL; + } + } + g_variant_unref(v); + } + g_object_unref(proxy); + } + g_slist_free_full(block_dev_list, g_free); + + return result_list; } GDBusConnection* get_udisks2_connection(void) { @@ -115,39 +211,57 @@ GDBusConnection* get_udisks2_connection(void) { return conn; } -udiskd *udiskd_new() { +udiskd* udiskd_new() { return g_new0(udiskd, 1); } void udiskd_free(udiskd *u) { if (u) { + g_free(u->model); + g_free(u->vendor); + g_free(u->revision); g_free(u->block_dev); g_free(u->serial); + g_free(u->connection_bus); g_free(u->media); g_free(u->media_compatibility); g_free(u); } } -udiskd *get_udisks2_drive_info(const gchar *blockdev) { - GDBusProxy *drive; +gpointer get_udisks2_drive_info(const char *blockdev, GDBusProxy *drive) { GVariant *v; const gchar *str; - udiskd *u; - - drive = get_udisks2_drive_proxy(udisks2_conn, blockdev); - if (!drive){ - return NULL; - } + udiskd *u = NULL; u = udiskd_new(); u->block_dev = g_strdup(blockdev); + v = get_dbus_property(drive, UDISKS2_DRIVE_INTERFACE, "Model"); + if (v){ + u->model = g_variant_dup_string(v, NULL); + g_variant_unref(v); + } + v = get_dbus_property(drive, UDISKS2_DRIVE_INTERFACE, "Vendor"); + if (v){ + u->vendor = g_variant_dup_string(v, NULL); + g_variant_unref(v); + } + v = get_dbus_property(drive, UDISKS2_DRIVE_INTERFACE, "Revision"); + if (v){ + u->revision = g_variant_dup_string(v, NULL); + g_variant_unref(v); + } 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, "ConnectionBus"); + if (v){ + u->connection_bus = 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); @@ -218,14 +332,17 @@ udiskd *get_udisks2_drive_info(const gchar *blockdev) { g_variant_unref(v); } } - - g_object_unref(drive); return u; } -gboolean udisks2_init(){ - udisks2_conn = get_udisks2_connection(); - return (udisks2_conn != NULL); +GSList* get_udisks2_all_drives_info(void){ + return udisks2_drives_func_caller(udisks2_conn, get_udisks2_drive_info); +} + +void udisks2_init(){ + if (udisks2_conn == NULL){ + udisks2_conn = get_udisks2_connection(); + } } void udisks2_shutdown(){ diff --git a/includes/udisks2_util.h b/includes/udisks2_util.h index 86417095..6b0d9c53 100644 --- a/includes/udisks2_util.h +++ b/includes/udisks2_util.h @@ -1,6 +1,10 @@ typedef struct udiskd { + gchar *model; + gchar *vendor; + gchar *revision; gchar *block_dev; gchar *serial; + gchar *connection_bus; gboolean ejectable; gboolean removable; gint32 rotation_rate; @@ -14,6 +18,6 @@ typedef struct udiskd { gint32 smart_temperature; } udiskd; -gboolean udisks2_init(); +void udisks2_init(); void udisks2_shutdown(); -udiskd *get_udisks2_drive_info(const gchar *blockdev); +GSList *get_udisks2_all_drives_info(); diff --git a/modules/devices.c b/modules/devices.c index fa474180..1c3253e4 100644 --- a/modules/devices.c +++ b/modules/devices.c @@ -38,6 +38,7 @@ #include "devices.h" #include "dt_util.h" +#include "udisks2_util.h" gchar *callback_processors(); gchar *callback_gpu(); @@ -616,8 +617,10 @@ void scan_storage(gboolean reload) g_free(storage_list); storage_list = g_strdup(""); - __scan_ide_devices(); - __scan_scsi_devices(); + if (!__scan_udisks2_devices()) { + __scan_ide_devices(); + __scan_scsi_devices(); + } SCAN_END(); } @@ -791,14 +794,14 @@ void hi_module_init(void) init_memory_labels(); init_cups(); sensors_init(); - storage_init(); + udisks2_init(); } void hi_module_deinit(void) { moreinfo_del_with_prefix("DEV"); sensors_shutdown(); - storage_shutdown(); + udisks2_shutdown(); g_hash_table_destroy(memlabels); g_module_close(cups); } diff --git a/modules/devices/storage.c b/modules/devices/storage.c index 26b10097..e5ad84b8 100644 --- a/modules/devices/storage.c +++ b/modules/devices/storage.c @@ -23,88 +23,146 @@ #include "udisks2_util.h" gchar *storage_icons = NULL; -gboolean udisks2_available = FALSE; -gboolean print_udisks2_info(const gchar *blockdev_name, gchar **str) { +gboolean __scan_udisks2_devices(void) { + GSList *node, *drives; udiskd *disk; - gchar *features = NULL; + gchar *udisks2_storage_list = NULL, *features = NULL, *moreinfo = NULL; + gchar *devid, *label; + const gchar *url, *vendor_str, *icon; + int n = 0, i; + + static struct { + char *media_prefix; + char *icon; + } media2icon[] = { + { "thumb", "usbfldisk"}, + { "flash", "usbfldisk"}, + { "floppy", "media-floppy"}, + { "optical", "cdrom"}, + { NULL, NULL} + }; + + moreinfo_del_with_prefix("DEV:UDISKS"); + udisks2_storage_list = g_strdup(_("\n[UDisks2]\n")); + + drives = get_udisks2_all_drives_info(); + for (node = drives; node != NULL; node = node->next) { + disk = (udiskd *)node->data; + devid = g_strdup_printf("UDISKS%d", n++); + + if (disk->vendor && strlen(disk->vendor) > 0) { + label = g_strdup_printf("%s %s", disk->vendor, disk->model); + vendor_str = disk->vendor; + } + else{ + label = g_strdup(disk->model); + vendor_str = disk->model; + } - disk = get_udisks2_drive_info(blockdev_name); - if (disk == NULL) { - return FALSE; - } + icon = NULL; + if (disk->media_compatibility){ + for (i = 0; media2icon[i].media_prefix != NULL; i++) { + if (g_str_has_prefix(disk->media_compatibility, + media2icon[i].media_prefix)) { + icon = media2icon[i].icon; + break; + } + } + } + if (icon == NULL && disk->ejectable && g_strcmp0(disk->connection_bus, "usb") == 0) { + icon = "usbfldisk"; + } + if (icon == NULL){ + icon = "hdd"; + } - features = h_strdup_cprintf("%s", features, disk->removable ? _("Removable"): _("Fixed")); - if (disk->ejectable) { - features = h_strdup_cprintf(", %s", features, _("Ejectable")); - } - if (disk->smart_enabled) { - features = h_strdup_cprintf(", %s", features, _("Smart monitoring")); - } + url = vendor_get_url(vendor_str); + udisks2_storage_list = h_strdup_cprintf("$%s$%s=\n", udisks2_storage_list, devid, label); + storage_icons = h_strdup_cprintf("Icon$%s$%s=%s.png\n", storage_icons, devid, label, icon); + features = h_strdup_cprintf("%s", features, disk->removable ? _("Removable"): _("Fixed")); - *str = h_strdup_cprintf(_( "Block Device=%s\n" - "Serial=%s\n" - "Size=%s\n" - "Features=%s\n"), - *str, - disk->block_dev, - disk->serial, - size_human_readable((gfloat) disk->size), - features); - - if (disk->rotation_rate > 0){ - *str = h_strdup_cprintf(_("Rotation Rate=%d\n"), *str, disk->rotation_rate); - } - if (disk->media_compatibility || disk->media){ - *str = h_strdup_cprintf(_( "Media=%s\n" - "Media compatibility=%s\n"), - *str, - disk->media ? disk->media : _("(None)"), - disk->media_compatibility ? disk->media_compatibility : _("(Unknown)")); - } - if (disk->smart_enabled){ - *str = h_strdup_cprintf(_( "[Smart monitoring]\n" - "Status=%s\n" - "Bad Sectors=%ld\n" - "Power on time=%d days %d hours\n" - "Temperature=%d°C\n"), - *str, - disk->smart_failing ? _("Failing"): _("OK"), - disk->smart_bad_sectors, - disk->smart_poweron/(60*60*24), (disk->smart_poweron/60/60) % 24, - disk->smart_temperature); - } + if (disk->ejectable) { + features = h_strdup_cprintf(", %s", features, _("Ejectable")); + } + if (disk->smart_enabled) { + features = h_strdup_cprintf(", %s", features, _("Smart monitoring")); + } - g_free(features); - udiskd_free(disk); + moreinfo = g_strdup_printf(_("[Drive Information]\n" + "Model=%s\n"), + label); + if (url) { + moreinfo = h_strdup_cprintf(_("Vendor=%s (%s)\n"), + moreinfo, + vendor_get_name(vendor_str), + url); + } + else { + moreinfo = h_strdup_cprintf(_("Vendor=%s\n"), + moreinfo, + vendor_get_name(vendor_str)); + } - return TRUE; -} + moreinfo = h_strdup_cprintf(_("Revision=%s\n" + "Block Device=%s\n" + "Serial=%s\n" + "Size=%s\n" + "Features=%s\n"), + moreinfo, + disk->revision, + disk->block_dev, + disk->serial, + size_human_readable((gfloat) disk->size), + features); + + if (disk->rotation_rate > 0) { + moreinfo = h_strdup_cprintf(_("Rotation Rate=%d\n"), moreinfo, disk->rotation_rate); + } + if (disk->media_compatibility || disk->media) { + moreinfo = h_strdup_cprintf(_("Media=%s\n" + "Media compatibility=%s\n"), + moreinfo, + disk->media ? disk->media : _("(None)"), + disk->media_compatibility ? disk->media_compatibility : _("(Unknown)")); + } + if (disk->connection_bus && strlen(disk->connection_bus) > 0) { + moreinfo = h_strdup_cprintf(_("Connection bus=%s\n"), moreinfo, disk->connection_bus); + } + if (disk->smart_enabled) { + moreinfo = h_strdup_cprintf(_("[Smart monitoring]\n" + "Status=%s\n" + "Bad Sectors=%ld\n" + "Power on time=%d days %d hours\n" + "Temperature=%d°C\n"), + moreinfo, + disk->smart_failing ? _("Failing"): _("OK"), + disk->smart_bad_sectors, + disk->smart_poweron/(60*60*24), (disk->smart_poweron/60/60) % 24, + disk->smart_temperature); + } + + moreinfo_add_with_prefix("DEV", devid, moreinfo); + g_free(devid); + g_free(features); + g_free(label); -void print_scsi_dev_info(gint controller, gint channel, gint id, gint lun, gchar **str) { - gchar *path; - GDir *dir; - const gchar *entry; + features = NULL; + moreinfo = NULL; + devid = NULL; - path = g_strdup_printf("/sys/class/scsi_device/%d:%d:%d:%d/device/block/", controller, channel, id, lun); - dir = g_dir_open(path, 0, NULL); - if (!dir){ - g_free(path); - return; + udiskd_free(disk); } + g_slist_free(drives); - if ((entry = g_dir_read_name(dir))) { - gboolean udisk_info = FALSE; - if (udisks2_available) { - udisk_info = print_udisks2_info(entry, str); - } - if (!udisk_info) { - // TODO: fallback - } + if (n) { + storage_list = h_strconcat(storage_list, udisks2_storage_list, NULL); + g_free(udisks2_storage_list); + return TRUE; } - g_dir_close(dir); - g_free(path); + g_free(udisks2_storage_list); + return FALSE; } /* SCSI support by Pascal F.Martin <pascalmartin@earthlink.net> */ @@ -210,22 +268,19 @@ void __scan_scsi_devices(void) } strhash = h_strdup_cprintf(_("Type=%s\n" - "Revision=%s\n"), - strhash, - type, - revision); - - print_scsi_dev_info(scsi_controller, scsi_channel, scsi_id, scsi_lun, &strhash); - - strhash = h_strdup_cprintf(_("[SCSI Controller]\n" + "Revision=%s\n" + "[SCSI Controller]\n" "Controller=scsi%d\n" "Channel=%d\n" "ID=%d\n" "LUN=%d\n"), strhash, + type, + revision, scsi_controller, scsi_channel, scsi_id, scsi_lun); + moreinfo_add_with_prefix("DEV", devid, strhash); g_free(devid); @@ -463,11 +518,3 @@ void __scan_ide_devices(void) g_free(ide_storage_list); } } - -void storage_init(void) { - udisks2_available = udisks2_init(); -} - -void storage_shutdown(void) { - udisks2_shutdown(); -} diff --git a/pixmaps/media-floppy.png b/pixmaps/media-floppy.png Binary files differnew file mode 100644 index 00000000..4c4c74a0 --- /dev/null +++ b/pixmaps/media-floppy.png |