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  | 
