diff options
Diffstat (limited to 'modules')
-rw-r--r-- | modules/devices/dmi.c | 196 |
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" |