diff options
author | Burt P <pburt0@gmail.com> | 2017-12-25 13:59:02 -0600 |
---|---|---|
committer | Leandro A. F. Pereira <leandro@hardinfo.org> | 2018-10-22 19:45:23 -0700 |
commit | d5a5d7b946ae5fff92d10acb78e87fdd48e8085f (patch) | |
tree | 194e5ffee33badda4739ef3ca93844d445582189 | |
parent | 459f2b1922fff188ea7912dca0f83ebc587a11c4 (diff) |
dmi_util: extend chassis_type table; add some functions to get information from dmidecode
Signed-off-by: Burt P <pburt0@gmail.com>
-rw-r--r-- | hardinfo/dmi_util.c | 146 | ||||
-rw-r--r-- | includes/dmi_util.h | 18 |
2 files changed, 164 insertions, 0 deletions
diff --git a/hardinfo/dmi_util.c b/hardinfo/dmi_util.c index 25ec8288..98c2ac72 100644 --- a/hardinfo/dmi_util.c +++ b/hardinfo/dmi_util.c @@ -152,6 +152,18 @@ char *dmi_chassis_type_str(int chassis_type, gboolean with_val) { N_("RAID Chassis"), N_("Rack Mount Chassis"), N_("Sealed-case PC"), + N_("Multi-system"), + N_("CompactPCI"), + N_("AdvancedTCA"), + N_("Blade"), + N_("Blade Enclosing"), + N_("Tablet"), + N_("Convertible"), + N_("Detachable"), + N_("IoT Gateway"), + N_("Embedded PC"), + N_("Mini PC"), + N_("Stick PC"), }; if (chassis_type <= 0) { @@ -171,3 +183,137 @@ char *dmi_chassis_type_str(int chassis_type, gboolean with_val) { } return NULL; } + +char *dmidecode_read(const unsigned long *dmi_type) { + gchar *ret = NULL; + gchar full_path[PATH_MAX]; + gboolean spawned; + gchar *out, *err; + + int i = 0; + + if (dmi_type) + snprintf(full_path, PATH_MAX, "dmidecode -t %lu", *dmi_type); + else + snprintf(full_path, PATH_MAX, "dmidecode"); + + 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 ret; +} + +dmi_handle_list *dmi_handle_list_add(dmi_handle_list *hl, unsigned int new_handle) { + if (!hl) { + hl = malloc(sizeof(dmi_handle_list)); + hl->count = 1; + hl->handles = malloc(sizeof(unsigned long) * hl->count); + } else { + hl->count++; + hl->handles = realloc(hl->handles, sizeof(unsigned long) * hl->count); + } + hl->handles[hl->count - 1] = new_handle; + return hl; +} + +dmi_handle_list *dmidecode_handles(const unsigned long *dmi_type) { + gchar *full = NULL, *p = NULL, *next_nl = NULL; + dmi_handle_list *hl = NULL; + unsigned int ch = 0; + + full = dmidecode_read(dmi_type); + if (full) { + p = full; + while(next_nl = strchr(p, '\n')) { + strend(p, '\n'); + if (sscanf(p, "Handle 0x%X", &ch) > 0) { + hl = dmi_handle_list_add(hl, ch); + } + p = next_nl + 1; + } + free(full); + } + return hl; +} + +void dmi_handle_list_free(dmi_handle_list *hl) { + if (hl) + free(hl->handles); + free(hl); +} + +char *dmidecode_match(const char *name, const unsigned long *dmi_type, const unsigned long *handle) { + gchar *ret = NULL, *full = NULL, *p = NULL, *next_nl = NULL; + unsigned int ch = 0; + int ln = 0; + + if (!name) return NULL; + ln = strlen(name); + + full = dmidecode_read(dmi_type); + if (full) { + p = full; + while(next_nl = strchr(p, '\n')) { + strend(p, '\n'); + if (!sscanf(p, "Handle 0x%X", &ch) > 0 ) { + if (!handle || *handle == ch) { + while(*p == '\t') p++; + if (strncmp(p, name, ln) == 0) { + if (*(p + ln) == ':') { + p = p + ln + 1; + while(*p == ' ') p++; + ret = strdup(p); + break; + } + } + } + } + p = next_nl + 1; + } + free(full); + } + + return ret; +} + +dmi_handle_list *dmidecode_match_value(const char *name, const char *value, const unsigned long *dmi_type) { + dmi_handle_list *hl = NULL; + gchar *full = NULL, *p = NULL, *next_nl = NULL; + unsigned int ch = 0; + int ln = 0, lnv = 0; + + if (!name) return NULL; + ln = strlen(name); + lnv = (value) ? strlen(value) : 0; + + full = dmidecode_read(dmi_type); + if (full) { + p = full; + while(next_nl = strchr(p, '\n')) { + strend(p, '\n'); + if (!sscanf(p, "Handle 0x%X", &ch) > 0 ) { + while(*p == '\t') p++; + if (strncmp(p, name, ln) == 0) { + if (*(p + ln) == ':') { + p = p + ln + 1; + while(*p == ' ') p++; + if (!value || strncmp(p, value, lnv) == 0) + hl = dmi_handle_list_add(hl, ch); + } + } + } + p = next_nl + 1; + } + free(full); + } + + return hl; +} diff --git a/includes/dmi_util.h b/includes/dmi_util.h index aecda739..7ef33681 100644 --- a/includes/dmi_util.h +++ b/includes/dmi_util.h @@ -28,4 +28,22 @@ char *dmi_get_str(const char *id_str); * "Desktop". */ char *dmi_chassis_type_str(int chassis_type, gboolean with_val); +typedef struct { + unsigned long count; + unsigned long *handles; +} dmi_handle_list; + +/* get a list of handles that match a dmi_type */ +dmi_handle_list *dmidecode_handles(const unsigned long *dmi_type); +void dmi_handle_list_free(dmi_handle_list *hl); + +/* get a list of handles which have a name, and/or optional value, and/or limit to an optional dmi_type + * dmidecode_match_value("Name", NULL, NULL) : all dmi handles with an item called "Name" + * dmidecode_match_value("Name", "Value", NULL) : all dmi_handles with an item called "Name" that has a value of "Value" + * dmidecode_match_value("Name", "Value", &dt) : all dmi_handles with "Name: Value" that are of type stored in dt */ +dmi_handle_list *dmidecode_match_value(const char *name, const char *value, const unsigned long *dmi_type); + +/* get the first value for name, limiting to optional dmi_type and/or optional handle */ +char *dmidecode_match(const char *name, const unsigned long *dmi_type, const unsigned long *handle); + #endif |