summaryrefslogtreecommitdiff
path: root/modules/devices/dmi.c
diff options
context:
space:
mode:
authorBurt P <pburt0@gmail.com>2017-08-15 13:51:56 -0500
committerLeandro A. F. Pereira <leandro@hardinfo.org>2017-08-27 08:21:05 -0700
commit90ef50fd3877856769acb87ba19d864db106c760 (patch)
treed2b74b2070bdeea251ff5478cb1b0647afb3b844 /modules/devices/dmi.c
parent201edf4795724b6de5e15882582856367ed15343 (diff)
DMI: create single dmi_get_str() that uses sysfs with dmidecode fallback
Signed-off-by: Burt P <pburt0@gmail.com>
Diffstat (limited to 'modules/devices/dmi.c')
-rw-r--r--modules/devices/dmi.c196
1 files changed, 78 insertions, 118 deletions
diff --git a/modules/devices/dmi.c b/modules/devices/dmi.c
index 5f87df13..25bdc2d8 100644
--- a/modules/devices/dmi.c
+++ b/modules/devices/dmi.c
@@ -27,117 +27,91 @@ typedef struct _DMIInfo DMIInfo;
struct _DMIInfo {
const gchar *name;
- const gchar *file; /* for sysfs */
- const gchar *param; /* for dmidecode */
+ const gchar *id_str;
};
DMIInfo dmi_info_table[] = {
- { "$BIOS", NULL, NULL },
- { "Date", "/sys/class/dmi/id/bios_date", "bios-release-date" },
- { "Vendor", "/sys/class/dmi/id/bios_vendor", "bios-vendor" },
- { "Version#0", "/sys/class/dmi/id/bios_version", "bios-version" },
- { "$Board", NULL, NULL },
- { "Name", "/sys/class/dmi/id/board_name", "baseboard-product-name" },
- { "Vendor", "/sys/class/dmi/id/board_vendor", "baseboard-manufacturer" },
- { "$Product", NULL, NULL },
- { "Name", "/sys/class/dmi/id/product_name", "system-product-name" },
- { "Family", "/sys/class/dmi/id/product_family", "system-product-family" },
- { "Version#1", "/sys/class/dmi/id/product_version", "system-product-version" },
+ { "$BIOS", NULL },
+ { "Date", "bios-release-date" },
+ { "Vendor", "bios-vendor" },
+ { "Version#0", "bios-version" },
+ { "$Board", NULL },
+ { "Name", "baseboard-product-name" },
+ { "Vendor", "baseboard-manufacturer" },
+ { "$Product", NULL },
+ { "Name", "system-product-name" },
+ { "Family", "system-product-family" },
+ { "Version#1", "system-product-version" },
};
gchar *dmi_info = NULL;
-static void add_to_moreinfo(const char *group, const char *key, char *value)
-{
- char *new_key = g_strconcat("DMI:", group, ":", key, NULL);
- moreinfo_add_with_prefix("DEV", new_key, g_strdup(g_strstrip(value)));
-}
-
-gboolean dmi_get_info_dmidecode()
-{
- FILE *dmi_pipe;
- gchar buffer[256];
- const gchar *group;
- DMIInfo *info;
- gboolean dmi_failed = FALSE;
- gint i;
-
- if (dmi_info) {
- g_free(dmi_info);
- dmi_info = NULL;
+char *dmi_get_str(const char *id_str) {
+ static struct {
+ char *id;
+ char *path;
+ } tab_dmi_sysfs[] = {
+ { "bios-release-date", "id/bios_date" },
+ { "bios-vendor", "id/bios_vendor" },
+ { "bios-version", "id/bios_version" },
+ { "baseboard-product-name", "id/board_name" },
+ { "baseboard-manufacturer", "id/board_vendor" },
+ { "system-product-name", "id/product_name" },
+ { "system-product-family", "id/product_family" },
+ { "system-product-version", "id/product_version" },
+ { "chassis-type", "id/chassis_type" },
+ { NULL, NULL }
+ };
+ gchar *path = NULL, *full_path = NULL, *ret = NULL;
+ gboolean spawned;
+ gchar *out, *err;
+
+ int i = 0;
+ while (tab_dmi_sysfs[i].id != NULL) {
+ if (strcmp(id_str, tab_dmi_sysfs[i].id) == 0) {
+ path = tab_dmi_sysfs[i].path;
+ break;
+ }
+ i++;
}
- for (i = 0; i < G_N_ELEMENTS(dmi_info_table); i++) {
- info = &dmi_info_table[i];
-
- if (*(info->name) == '$') {
- group = info->name + 1;
- dmi_info = h_strdup_cprintf("[%s]\n", dmi_info, group);
- } else {
- gchar *temp;
-
- if (!info->param)
- continue;
-
- temp = g_strconcat("dmidecode -s ", info->param, NULL);
- if ((dmi_pipe = popen(temp, "r"))) {
- g_free(temp);
-
- (void)fgets(buffer, 256, dmi_pipe);
- if (pclose(dmi_pipe)) {
- dmi_failed = TRUE;
- break;
- }
-
- add_to_moreinfo(group, info->name, buffer);
-
- const gchar *url = vendor_get_url(buffer);
- if (url) {
- const gchar *vendor = vendor_get_name(buffer);
- if (g_strstr_len(vendor, -1, g_strstrip(buffer)) ||
- g_strstr_len(g_strstrip(buffer), -1, vendor)) {
- dmi_info = h_strdup_cprintf("%s=%s (%s)\n",
- dmi_info,
- info->name,
- g_strstrip(buffer),
- url);
- } else {
- dmi_info = h_strdup_cprintf("%s=%s (%s, %s)\n",
- dmi_info,
- info->name,
- g_strstrip(buffer),
- vendor, url);
- }
- } else {
- dmi_info = h_strdup_cprintf("%s=%s\n",
- dmi_info,
- info->name,
- buffer);
- }
- } else {
- g_free(temp);
- dmi_failed = TRUE;
- break;
- }
- }
+ /* try sysfs first */
+ if (path) {
+ full_path = g_strdup_printf("/sys/class/dmi/%s", path);
+ if (g_file_get_contents(full_path, &ret, NULL, NULL) )
+ goto dmi_str_done;
}
- if (dmi_failed) {
- g_free(dmi_info);
- dmi_info = NULL;
+ /* try dmidecode, but may require root */
+ full_path = g_strconcat("dmidecode -s ", id_str, NULL);
+ spawned = g_spawn_command_line_sync(full_path,
+ &out, &err, &i, NULL);
+ if (spawned) {
+ if (i == 0)
+ ret = out;
+ else
+ g_free(out);
+ g_free(err);
}
- return !dmi_failed;
+dmi_str_done:
+ g_free(full_path);
+ return ret;
+}
+
+static void add_to_moreinfo(const char *group, const char *key, char *value)
+{
+ char *new_key = g_strconcat("DMI:", group, ":", key, NULL);
+ moreinfo_add_with_prefix("DEV", new_key, g_strdup(g_strstrip(value)));
}
-gboolean dmi_get_info_sys()
+gboolean dmi_get_info()
{
- FILE *dmi_file;
- gchar buffer[256];
const gchar *group = NULL;
DMIInfo *info;
gboolean dmi_succeeded = FALSE;
gint i;
+ gchar *value;
if (dmi_info) {
g_free(dmi_info);
@@ -150,35 +124,25 @@ gboolean dmi_get_info_sys()
if (*(info->name) == '$') {
group = info->name + 1;
dmi_info = h_strdup_cprintf("[%s]\n", dmi_info, group);
- } else if (group && info->file) {
- if ((dmi_file = fopen(info->file, "r"))) {
- (void)fgets(buffer, 256, dmi_file);
- fclose(dmi_file);
+ } else if (group && info->id_str) {
+ value = dmi_get_str(info->id_str);
- add_to_moreinfo(group, info->name, buffer);
+ if (value != NULL) {
+ add_to_moreinfo(group, info->name, value);
- const gchar *url = vendor_get_url(buffer);
+ const gchar *url = vendor_get_url(value);
if (url) {
- const gchar *vendor = vendor_get_name(buffer);
- if (g_strstr_len(vendor, -1, g_strstrip(buffer)) ||
- g_strstr_len(g_strstrip(buffer), -1, vendor)) {
- dmi_info = h_strdup_cprintf("%s=%s (%s)\n",
- dmi_info,
- info->name,
- g_strstrip(buffer),
- url);
- } else {
- dmi_info = h_strdup_cprintf("%s=%s (%s, %s)\n",
- dmi_info,
- info->name,
- g_strstrip(buffer),
- vendor, url);
- }
+ const gchar *vendor = vendor_get_name(value);
+ dmi_info = h_strdup_cprintf("%s=%s (%s, %s)\n",
+ dmi_info,
+ info->name,
+ g_strstrip(value),
+ vendor, url);
} else {
dmi_info = h_strdup_cprintf("%s=%s\n",
dmi_info,
info->name,
- g_strstrip(buffer));
+ g_strstrip(value));
}
dmi_succeeded = TRUE;
} else {
@@ -202,11 +166,7 @@ void __scan_dmi()
{
gboolean dmi_ok;
- dmi_ok = dmi_get_info_sys();
-
- if (!dmi_ok) {
- dmi_ok = dmi_get_info_dmidecode();
- }
+ dmi_ok = dmi_get_info();
if (!dmi_ok) {
dmi_info = g_strdup("[No DMI information]\n"