diff options
| -rw-r--r-- | hardinfo/udisks2_util.c | 88 | ||||
| -rw-r--r-- | includes/udisks2_util.h | 11 | ||||
| -rw-r--r-- | modules/devices/storage.c | 35 | 
3 files changed, 129 insertions, 5 deletions
| diff --git a/hardinfo/udisks2_util.c b/hardinfo/udisks2_util.c index 8aa54f72..11e091b9 100644 --- a/hardinfo/udisks2_util.c +++ b/hardinfo/udisks2_util.c @@ -201,7 +201,8 @@ GSList* get_block_dev_paths_from_sysfs(){  }  GSList* udisks2_drives_func_caller(GDBusConnection* conn, -                                   gpointer (*func)(const char*, GDBusProxy*, GDBusProxy*)) { +                                   gpointer (*func)(const char*, GDBusProxy*, +                                   GDBusProxy*, const char*)) {      GDBusProxy *block_proxy, *drive_proxy;      GVariant *block_v, *v;      GSList *result_list = NULL, *block_dev_list, *node; @@ -262,7 +263,7 @@ GSList* udisks2_drives_func_caller(GDBusConnection* conn,                  if (error == NULL) {                      // call requested function -                    output = func(block_dev, block_proxy, drive_proxy); +                    output = func(block_dev, block_proxy, drive_proxy, drive_path);                      if (output != NULL){                          result_list = g_slist_append(result_list, output); @@ -322,6 +323,10 @@ udiskt* udiskt_new() {      return g_new0(udiskt, 1);  } +udisksa* udisksa_new() { +    return g_new0(udisksa, 1); +} +  udiskp* udiskp_new() {      return g_new0(udiskp, 1);  } @@ -330,6 +335,7 @@ udiskd* udiskd_new() {      return g_new0(udiskd, 1);  } +  void udiskt_free(udiskt *u) {      if (u) {          g_free(u->drive); @@ -337,6 +343,14 @@ void udiskt_free(udiskt *u) {      }  } +void udisksa_free(udisksa *u) { +    if (u) { +        g_free(u->identifier); +        udisksa_free(u->next); +        g_free(u); +    } +} +  void udiskp_free(udiskp *u) {      if (u) {          g_free(u->block); @@ -358,12 +372,14 @@ void udiskd_free(udiskd *u) {          g_free(u->connection_bus);          g_free(u->partition_table);          udiskp_free(u->partitions); +        udisksa_free(u->smart_attributes);          g_free(u->media);          g_strfreev(u->media_compatibility);          g_free(u);      }  } +  udiskp* get_udisks2_partition_info(const gchar *part_path) {      GVariant *v;      GDBusProxy *proxy; @@ -414,7 +430,8 @@ udiskp* get_udisks2_partition_info(const gchar *part_path) {      return partition;  } -gpointer get_udisks2_temp(const char *blockdev, GDBusProxy *block, GDBusProxy *drive){ +gpointer get_udisks2_temp(const char *blockdev, GDBusProxy *block, +                          GDBusProxy *drive, const char *drivepath){      GVariant *v;      gboolean smart_enabled = FALSE;      udiskt* disk_temp = NULL; @@ -449,7 +466,69 @@ gpointer get_udisks2_temp(const char *blockdev, GDBusProxy *block, GDBusProxy *d      return disk_temp;  } -gpointer get_udisks2_drive_info(const char *blockdev, GDBusProxy *block, GDBusProxy *drive) { +gchar* get_udisks2_smart_attributes(udiskd* dsk, const char *drivepath){ +    GDBusProxy *proxy; +    GVariant *options, *v, *v2; +    GVariantIter *iter; +    GError *error = NULL; +    const char* aidenf; +    guint8 aid; +    gint16 avalue, aworst, athreshold; +    gint64 pretty; +    udisksa *lastp = NULL, *p; + +    proxy = g_dbus_proxy_new_sync(udisks2_conn, G_DBUS_PROXY_FLAGS_NONE, NULL, +                                  UDISKS2_INTERFACE, drivepath, +                                  UDISKS2_DRIVE_ATA_INTERFACE, NULL, &error); + +    options = g_variant_new_parsed("@a{sv} { %s: <true> }", +                                   "auth.no_user_interaction"); +    if (error != NULL){ +        g_error_free (error); +        return NULL; +    } + +    v = g_dbus_proxy_call_sync(proxy, "SmartGetAttributes", +                               g_variant_new_tuple(&options, 1), +                               G_DBUS_CALL_FLAGS_NONE, -1, NULL, &error); +    g_object_unref(proxy); + +    if (error != NULL){ +        g_error_free (error); +        g_object_unref(proxy); +        return NULL; +    } + +    v2 = g_variant_get_child_value(v, 0); +    iter = g_variant_iter_new(v2); + +    // id(y), identifier(s), flags(q), value(i), worst(i), threshold(i), +    // pretty(x), pretty_unit(i), expansion(a{sv}) +    while (g_variant_iter_loop (iter, "(ysqiiixia{sv})", &aid, &aidenf, NULL, &avalue, &aworst, &athreshold, NULL, NULL, NULL)){ +        p = udisksa_new(); +        p->id = aid; +        p->identifier = g_strdup(aidenf); +        p->value = avalue; +        p->worst = aworst; +        p->threshold = athreshold; +        p->next = NULL; + +        if (lastp == NULL) +            dsk->smart_attributes = p; +        else +            lastp->next = p; + +        lastp = p; +    } +    g_variant_iter_free (iter); +    g_variant_unref(v2); +    g_variant_unref(v); + +    return NULL; +} + +gpointer get_udisks2_drive_info(const char *blockdev, GDBusProxy *block, +                                GDBusProxy *drive, const char *drivepath) {      GVariant *v;      GVariantIter *iter;      const gchar *str, *part; @@ -573,6 +652,7 @@ gpointer get_udisks2_drive_info(const char *blockdev, GDBusProxy *block, GDBusPr              u->smart_failing = g_variant_get_boolean(v);              g_variant_unref(v);          } +        get_udisks2_smart_attributes(u, drivepath);      }      v = get_dbus_property(block, UDISKS2_PART_TABLE_INTERFACE, "Type"); diff --git a/includes/udisks2_util.h b/includes/udisks2_util.h index 813825cb..acd2282f 100644 --- a/includes/udisks2_util.h +++ b/includes/udisks2_util.h @@ -9,6 +9,15 @@ typedef struct udiskp {      struct udiskp* next;  } udiskp; +typedef struct udisksa { +    guint8 id; +    gchar *identifier; +    gint value; +    gint worst; +    gint threshold; +    struct udisksa* next; +} udisksa; +  typedef struct udiskd {      gchar *model;      gchar *vendor; @@ -33,6 +42,7 @@ typedef struct udiskd {      guint64 smart_poweron;      gint64 smart_bad_sectors;      gint32 smart_temperature; +    udisksa *smart_attributes;      vendor_list vendors;  } udiskd; @@ -40,7 +50,6 @@ typedef struct udiskt {      gchar *drive;      gint32 temperature;  } udiskt; -  void udisks2_init();  void udisks2_shutdown();  GSList *get_udisks2_temps(); diff --git a/modules/devices/storage.c b/modules/devices/storage.c index def39839..cedaed85 100644 --- a/modules/devices/storage.c +++ b/modules/devices/storage.c @@ -29,6 +29,7 @@ gboolean __scan_udisks2_devices(void) {      GSList *node, *drives;      udiskd *disk;      udiskp *part; +    udisksa *attrib;      gchar *udisks2_storage_list = NULL, *features = NULL, *moreinfo = NULL;      gchar *devid, *label, *size, *tmp = NULL, *media_comp = NULL;      const gchar *url, *vendor_str, *media_label, *icon, *media_curr = NULL; @@ -199,6 +200,40 @@ gboolean __scan_udisks2_devices(void) {                                          disk->smart_bad_sectors,                                          disk->smart_poweron/(60*60*24), (disk->smart_poweron/60/60) % 24,                                          disk->smart_temperature); + +            if (disk->smart_attributes != NULL) { +                moreinfo = h_strdup_cprintf(_("[S.M.A.R.T. Attributes]\n" +                                            "Attribute=Normalized Value / Worst / Threshold\n"), +                                            moreinfo); + +                attrib = disk->smart_attributes; + +                while (attrib != NULL){ +                    tmp = g_strdup(""); +                    if (attrib->value != -1) +                        tmp = h_strdup_cprintf("%3d", tmp, attrib->value); +                    else +                        tmp = h_strdup_cprintf("???", tmp); + +                    if (attrib->worst != -1) +                        tmp = h_strdup_cprintf(" / %3d", tmp, attrib->worst); +                    else +                        tmp = h_strdup_cprintf(" / ???", tmp); + +                    if (attrib->threshold != -1) +                        tmp = h_strdup_cprintf(" / %3d", tmp, attrib->threshold); +                    else +                        tmp = h_strdup_cprintf(" / ???", tmp); + +                    moreinfo = h_strdup_cprintf(_("(%d) %s=%s\n"), +                                            moreinfo, +                                            attrib->id, +                                            attrib->identifier, +                                            tmp); +                    g_free(tmp); +                    attrib = attrib->next; +                } +            }          }          if (disk->partition_table || disk->partitions) {              moreinfo = h_strdup_cprintf(_("[Partition table]\n" | 
