diff options
| -rw-r--r-- | includes/devices.h | 5 | ||||
| -rw-r--r-- | modules/devices/dmi.c | 196 | 
2 files changed, 82 insertions, 119 deletions
| diff --git a/includes/devices.h b/includes/devices.h index 00787331..c5a02077 100644 --- a/includes/devices.h +++ b/includes/devices.h @@ -72,6 +72,9 @@ void sensors_shutdown(void);  void scan_spd_do(void);  #endif /* ARCH_x86 */ +/* DMI */ +char *dmi_get_str(const char *id_str); +  extern gchar *battery_list;  extern gchar *input_icons;  extern gchar *input_list; @@ -91,10 +94,10 @@ extern GHashTable *sensor_labels;  extern GModule *cups;  #if defined(ARCH_x86) || defined(ARCH_x86_64) -extern gchar *dmi_info;  extern gchar *spd_info;  #endif +extern gchar *dmi_info;  extern gchar *dtree_info;  #endif /* __DEVICES_H__ */ 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" | 
