diff options
| -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 | 
