aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--hardinfo/udisks2_util.c205
-rw-r--r--includes/udisks2_util.h8
-rw-r--r--modules/devices.c11
-rw-r--r--modules/devices/storage.c217
-rw-r--r--pixmaps/media-floppy.pngbin0 -> 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
new file mode 100644
index 00000000..4c4c74a0
--- /dev/null
+++ b/pixmaps/media-floppy.png
Binary files differ