diff options
Diffstat (limited to 'hardinfo')
| -rw-r--r-- | hardinfo/dt_util.c | 30 | ||||
| -rw-r--r-- | hardinfo/gg_key_file_parse_string_as_value.c | 109 | ||||
| -rw-r--r-- | hardinfo/gpu_util.c | 18 | ||||
| -rw-r--r-- | hardinfo/info.c | 13 | ||||
| -rw-r--r-- | hardinfo/udisks2_util.c | 2 | ||||
| -rw-r--r-- | hardinfo/usb_util.c | 101 | ||||
| -rw-r--r-- | hardinfo/util.c | 32 | ||||
| -rw-r--r-- | hardinfo/vendor.c | 19 | 
8 files changed, 240 insertions, 84 deletions
| diff --git a/hardinfo/dt_util.c b/hardinfo/dt_util.c index da38fd91..2d1b60a0 100644 --- a/hardinfo/dt_util.c +++ b/hardinfo/dt_util.c @@ -27,6 +27,7 @@  #include <endian.h>  #include "hardinfo.h"  #include "dt_util.h" +#include "appf.h"  static struct {      char *name; int type; @@ -682,14 +683,14 @@ char *dtr_list_override(dtr_obj *obj) {          src += 4; consumed += 4;          l = strlen(src) + 1; /* consume the null */          str = dtr_list_str0(src, l); -        ret = appf(ret, "<%s -> %s>", ph, str); +        ret = appfsp(ret, "<%s -> %s>", ph, str);          src += l; consumed += l;          free(ph);          free(str);      }      if (consumed < obj->length) {          str = dtr_list_byte((uint8_t*)src, obj->length - consumed); -        ret = appf(ret, "%s", str); +        ret = appfsp(ret, "%s", str);          free(str);      }      return ret; @@ -720,7 +721,7 @@ char *dtr_list_phref(dtr_obj *obj, char *ext_cell_prop) {          ph = dtr_elem_phref(obj->dt, obj->data_int[i], 0, NULL); i++;          if (ext_cells > count - i) ext_cells = count - i;          ext = dtr_list_hex((obj->data_int + i), ext_cells); i+=ext_cells; -        ret = appf(ret, "<%s%s%s>", +        ret = appfsp(ret, "<%s%s%s>",              ph, (ext_cells) ? " " : "", ext);          g_free(ph);          g_free(ext); @@ -748,7 +749,7 @@ char *dtr_list_interrupts(dtr_obj *obj) {      while (i < count) {          icells = UMIN(icells, count - i);          ext = dtr_list_hex((obj->data_int + i), icells); i+=icells; -        ret = appf(ret, "<%s>", ext); +        ret = appfsp(ret, "<%s>", ext);      }      return ret; @@ -782,7 +783,7 @@ char *dtr_list_reg(dtr_obj *obj) {      consumed = 0;      while (consumed + (tup_len * 4) <= obj->length) {          tup_str = dtr_list_hex(next, tup_len); -        ret = appf(ret, "<%s>", tup_str); +        ret = appfsp(ret, "<%s>", tup_str);          free(tup_str);          consumed += (tup_len * 4);          next += tup_len; @@ -1184,22 +1185,3 @@ char *dtr_maps_info(dtr *s) {      g_free(sy_map);      return ret;  } - -char *appf(char *src, char *fmt, ...) { -    gchar *buf, *ret; -    va_list args; - -    va_start(args, fmt); -    buf = g_strdup_vprintf(fmt, args); -    va_end(args); - -    if (src != NULL) { -        ret = g_strdup_printf("%s%s%s", src, sp_sep(src), buf); -        g_free(buf); -        g_free(src); -    } else -        ret = buf; - -    return ret; -} - diff --git a/hardinfo/gg_key_file_parse_string_as_value.c b/hardinfo/gg_key_file_parse_string_as_value.c new file mode 100644 index 00000000..496b1d35 --- /dev/null +++ b/hardinfo/gg_key_file_parse_string_as_value.c @@ -0,0 +1,109 @@ +/* From: gkeyfile.c - key file parser + * + *  Copyright 2004  Red Hat, Inc. + *  Copyright 2009-2010  Collabora Ltd. + *  Copyright 2009  Nokia Corporation + * + * Written by Ray Strode <rstrode@redhat.com> + *            Matthias Clasen <mclasen@redhat.com> + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library; if not, see <http://www.gnu.org/licenses/>. + */ + +static gchar * +gg_key_file_parse_string_as_value (const gchar *string, const gchar list_separator) +{ +  gchar *value, *p, *q; +  gsize length; +  gboolean parsing_leading_space; + +  length = strlen (string) + 1; + +  /* Worst case would be that every character needs to be escaped. +   * In other words every character turns to two characters. */ +  value = g_new (gchar, 2 * length); + +  p = (gchar *) string; +  q = value; +  parsing_leading_space = TRUE; +  while (p < (string + length - 1)) +    { +      gchar escaped_character[3] = { '\\', 0, 0 }; + +      switch (*p) +        { +        case ' ': +          if (parsing_leading_space) +            { +              escaped_character[1] = 's'; +              strcpy (q, escaped_character); +              q += 2; +            } +          else +            { +	      *q = *p; +	      q++; +            } +          break; +        case '\t': +          if (parsing_leading_space) +            { +              escaped_character[1] = 't'; +              strcpy (q, escaped_character); +              q += 2; +            } +          else +            { +	      *q = *p; +	      q++; +            } +          break; +        case '\n': +          escaped_character[1] = 'n'; +          strcpy (q, escaped_character); +          q += 2; +          break; +        case '\r': +          escaped_character[1] = 'r'; +          strcpy (q, escaped_character); +          q += 2; +          break; +        case '\\': +          escaped_character[1] = '\\'; +          strcpy (q, escaped_character); +          q += 2; +          parsing_leading_space = FALSE; +          break; +        default: +	  if (list_separator && *p == list_separator) +	    { +	      escaped_character[1] = list_separator; +	      strcpy (q, escaped_character); +	      q += 2; +              parsing_leading_space = TRUE; +	    } +	  else +	    { +	      *q = *p; +	      q++; +              parsing_leading_space = FALSE; +	    } +          break; +        } +      p++; +    } +  *q = '\0'; + +  return value; +} diff --git a/hardinfo/gpu_util.c b/hardinfo/gpu_util.c index 17c79a73..b203b426 100644 --- a/hardinfo/gpu_util.c +++ b/hardinfo/gpu_util.c @@ -20,7 +20,7 @@  #include "hardinfo.h"  #include "gpu_util.h" - +#include "nice_name.h"  #include "cpu_util.h" /* for EMPIFNULL() */  nvgpu *nvgpu_new() { @@ -229,16 +229,12 @@ static void make_nice_name(gpud *s) {      /* try and a get a "short name" for the vendor */      vendor_str = vendor_get_shortest_name(vendor_str); -    /* These two former special cases are currently handled by the vendor_get_shortest_name() -     * function well enough, but the notes are preserved here. */ -        /* nvidia PCI strings are pretty nice already, -         * just shorten the company name */ -        // s->nice_name = g_strdup_printf("%s %s", "nVidia", device_str); -        /* Intel Graphics may have very long names, like "Intel Corporation Seventh Generation Something Core Something Something Integrated Graphics Processor Revision Ninety-four" -         * but for now at least shorten "Intel Corporation" to just "Intel" */ -        // s->nice_name = g_strdup_printf("%s %s", "Intel", device_str); - -    if (strstr(vendor_str, "AMD")) { +    if (strstr(vendor_str, "Intel")) { +        gchar *device_str_clean = strdup(device_str); +        nice_name_intel_gpu_device(device_str_clean); +        s->nice_name = g_strdup_printf("%s %s", vendor_str, device_str_clean); +        g_free(device_str_clean); +    } else if (strstr(vendor_str, "AMD")) {          /* AMD PCI strings are crazy stupid because they use the exact same           * chip and device id for a zillion "different products" */          char *full_name = strdup(device_str); diff --git a/hardinfo/info.c b/hardinfo/info.c index bfc11fc2..cf6af9f9 100644 --- a/hardinfo/info.c +++ b/hardinfo/info.c @@ -17,6 +17,13 @@   */  #include "hardinfo.h" +#include "util_sysobj.h" /* for SEQ() */ + +/* Using a slightly modified gg_key_file_parse_string_as_value() + * from GLib in flatten(), to escape characters and the separator. + * The function is not public in GLib and we don't have a GKeyFile + * to pass it anyway. */ +#include "gg_key_file_parse_string_as_value.c"  static const gchar *info_column_titles[] = {      "TextValue", "Value", "Progress", "Extra1", "Extra2" @@ -267,7 +274,9 @@ static void flatten_group(GString *output, const struct InfoGroup *group, guint                      tp);              } -            g_string_append_printf(output, "%s=%s\n", field->name, field->value); +            gchar *escaped_value = gg_key_file_parse_string_as_value(field->value, '|'); +            g_string_append_printf(output, "%s=%s\n", field->name, escaped_value); +            g_free(escaped_value);          }      } else if (group->computed) {          g_string_append_printf(output, "%s\n", group->computed); @@ -369,8 +378,6 @@ gchar *info_flatten(struct Info *info)      return g_string_free(values, FALSE);  } -#define SEQ(a,b) (g_strcmp0(a,b) == 0) -  struct InfoField *info_find_field(struct Info *info, const gchar *tag, const gchar *name) {      struct InfoGroup *group;      struct InfoField *field; diff --git a/hardinfo/udisks2_util.c b/hardinfo/udisks2_util.c index 0687b14a..8aa54f72 100644 --- a/hardinfo/udisks2_util.c +++ b/hardinfo/udisks2_util.c @@ -30,7 +30,7 @@ void find_sdcard_ids_file() {      };      int n;      for(n = 0; file_search_order[n]; n++) { -        if (!access(file_search_order[n], R_OK)) +        if (!sdcard_ids_file && !access(file_search_order[n], R_OK))              sdcard_ids_file = file_search_order[n];          else              g_free(file_search_order[n]); diff --git a/hardinfo/usb_util.c b/hardinfo/usb_util.c index cc839b9a..a758026f 100644 --- a/hardinfo/usb_util.c +++ b/hardinfo/usb_util.c @@ -21,9 +21,12 @@  #include "hardinfo.h"  #include "usb_util.h" +#include "util_ids.h"  #define SYSFS_DIR_USB_DEVICES "/sys/bus/usb/devices" +gchar *usb_ids_file = NULL; +  usbi *usbi_new() {      return g_new0(usbi, 1);  } @@ -61,8 +64,10 @@ void usbd_free(usbd *s) {          g_free(s->device);          g_free(s->usb_version);          g_free(s->device_version); +        g_free(s->serial);          g_free(s->dev_class_str);          g_free(s->dev_subclass_str); +        g_free(s->dev_protocol_str);          g_free(s);      }  } @@ -203,6 +208,19 @@ static gboolean usb_get_device_lsusb(int bus, int dev, usbd *s) {                  s->dev_subclass = atoi(l);                  if (t = strchr(l, ' '))                      s->dev_subclass_str = g_strdup(t + 1); +            } else if (l = lsusb_line_value(p, "bDeviceProtocol")) { +                s->dev_protocol = atoi(l); +                if (t = strchr(l, ' ')) +                    s->dev_protocol_str = g_strdup(t + 1); +            } else if (l = lsusb_line_value(p, "iManufacturer")) { +                if (t = strchr(l, ' ')) +                    s->manufacturer = g_strdup(t + 1); +            } else if (l = lsusb_line_value(p, "iProduct")) { +                if (t = strchr(l, ' ')) +                    s->device = g_strdup(t + 1); +            } else if (l = lsusb_line_value(p, "iSerial")) { +                if (t = strchr(l, ' ')) +                    s->serial = g_strdup(t + 1);              // interface info              } else if (l = lsusb_line_value(p, "bInterfaceNumber")) { @@ -254,6 +272,7 @@ static gboolean usb_get_device_lsusb(int bus, int dev, usbd *s) {  static gboolean usb_get_interface_sysfs(int conf, int number,                                          const char* devpath, usbi *intf){      gchar *ifpath, *drvpath, *tmp; +    ids_query_result result = {};      ifpath = g_strdup_printf("%s:%d.%d", devpath, conf, number);      if (!g_file_test(ifpath, G_FILE_TEST_EXISTS)){ @@ -279,17 +298,53 @@ static gboolean usb_get_interface_sysfs(int conf, int number,      if (intf->if_label == NULL)          intf->if_label = h_sysfs_read_string(ifpath, "interface"); +    if (intf->if_class_str == NULL && intf->if_subclass_str == NULL +                                   && intf->if_protocol_str == NULL) { +        tmp = g_strdup_printf("C %02x/%02x/%02x", intf->if_class, +                               intf->if_subclass, intf->if_protocol); +        scan_ids_file(usb_ids_file, tmp, &result, -1); +        if (result.results[0]) +            intf->if_class_str = g_strdup(result.results[0]); +        if (result.results[1]) +            intf->if_subclass_str = g_strdup(result.results[1]); +        if (result.results[2]) +            intf->if_protocol_str = g_strdup(result.results[2]); +        g_free(tmp); +    } +      g_free(ifpath);      return TRUE;  } +void find_usb_ids_file() { +    if (usb_ids_file) return; +    char *file_search_order[] = { +        g_build_filename(g_get_user_config_dir(), "hardinfo", "usb.ids", NULL), +        g_build_filename(params.path_data, "usb.ids", NULL), +        NULL +    }; +    int n; +    for(n = 0; file_search_order[n]; n++) { +        if (!usb_ids_file && !access(file_search_order[n], R_OK)) +            usb_ids_file = file_search_order[n]; +        else +            g_free(file_search_order[n]); +    } +} +  static gboolean usb_get_device_sysfs(int bus, int dev, const char* sysfspath, usbd *s) {      usbi *intf;      gboolean ok; -    int i, if_count = 0, conf = 0; +    int i, if_count = 0, conf = 0, ver; +    ids_query_result result = {}; +    gchar *qpath; +      if (sysfspath == NULL)          return FALSE; +    if (!usb_ids_file) +        find_usb_ids_file(); +      s->bus = bus;      s->dev = dev;      s->dev_class = h_sysfs_read_hex(sysfspath, "bDeviceClass"); @@ -300,13 +355,48 @@ static gboolean usb_get_device_sysfs(int bus, int dev, const char* sysfspath, us      s->max_curr_ma = h_sysfs_read_int(sysfspath, "bMaxPower");      s->dev_class = h_sysfs_read_hex(sysfspath, "bDeviceClass");      s->dev_subclass = h_sysfs_read_hex(sysfspath, "bDeviceSubClass"); +    s->dev_protocol = h_sysfs_read_hex(sysfspath, "bDeviceProtocol");      s->speed_mbs = h_sysfs_read_int(sysfspath, "speed"); +    if (s->product == NULL && s->vendor == NULL) { +        qpath = g_strdup_printf("%04x/%04x", s->vendor_id, s->product_id); +        scan_ids_file(usb_ids_file, qpath, &result, -1); +        if (result.results[0]) +            s->vendor = g_strdup(result.results[0]); +        if (result.results[1]) +            s->product = g_strdup(result.results[1]); +        g_free(qpath); +    } + +    if (s->dev_class_str == NULL && s->dev_subclass_str == NULL +                                 && s->dev_protocol_str == NULL) { +        qpath = g_strdup_printf("C %02x/%02x/%02x", s->dev_class, +                                   s->dev_subclass, s->dev_protocol); +        scan_ids_file(usb_ids_file, qpath, &result, -1); +        if (result.results[0]) +            s->dev_class_str = g_strdup(result.results[0]); +        if (result.results[1]) +            s->dev_subclass_str = g_strdup(result.results[1]); +        if (result.results[2]) +            s->dev_protocol_str = g_strdup(result.results[2]); +        g_free(qpath); +    } +      conf = h_sysfs_read_hex(sysfspath, "bConfigurationValue");      if (s->usb_version == NULL)          s->usb_version = h_sysfs_read_string(sysfspath, "version"); +    if (s->serial == NULL) +        s->serial = h_sysfs_read_string(sysfspath, "serial"); + +    if (s->device_version == NULL) { +        ver = h_sysfs_read_int(sysfspath, "bcdDevice"); +        if (ver > 0){ +            s->device_version = g_strdup_printf("%d.%02d", ver/100, ver%100); +        } +    } +      if (s->if_list == NULL){ // create interfaces list          if_count = h_sysfs_read_int(sysfspath, "bNumInterfaces");          for (i = 0; i <= if_count; i++){ @@ -337,11 +427,12 @@ usbd *usb_get_device(int bus, int dev, const gchar* sysfspath) {      usbd *s = usbd_new();      int ok = 0;      if (s) { -        /* try lsusb */ -        ok = usb_get_device_lsusb(bus, dev, s);          /* try sysfs */ -        ok |= usb_get_device_sysfs(bus, dev, sysfspath, s); - +        ok = usb_get_device_sysfs(bus, dev, sysfspath, s); +        if (!ok) { +            /* try lsusb */ +            ok = usb_get_device_lsusb(bus, dev, s); +        }          if (!ok) {              usbd_free(s);              s = NULL; diff --git a/hardinfo/util.c b/hardinfo/util.c index b35b2461..1b92457c 100644 --- a/hardinfo/util.c +++ b/hardinfo/util.c @@ -539,38 +539,6 @@ gboolean ui_init(int *argc, char ***argv)      return gtk_init_check(argc, argv);  } -void open_url(gchar * url) -{ -    const gchar *browsers[] = { -	"xdg-open", "gnome-open", "kfmclient openURL", -	"sensible-browser", "firefox", "epiphany", -	"iceweasel", "seamonkey", "galeon", "mozilla", -	"opera", "konqueror", "netscape", "links -g", -	NULL -    }; -    gint i = 0; -    gchar *browser = (gchar *)g_getenv("BROWSER"); - -    if (!browser || *browser == '\0') { -    	browser = (gchar *)browsers[i++]; -    } - -    do { -	gchar *cmdline = g_strdup_printf("%s '%s'", browser, url); - -	if (g_spawn_command_line_async(cmdline, NULL)) { -	    g_free(cmdline); -	    return; -	} - -	g_free(cmdline); - -    	browser = (gchar *)browsers[i++]; -    } while (browser); - -    g_warning(_("Couldn't find a Web browser to open URL %s."), url); -} -  /* Copyright: Jens Låås, SLU 2002 */  gchar *strreplacechr(gchar * string, gchar * replace, gchar new_char)  { diff --git a/hardinfo/vendor.c b/hardinfo/vendor.c index bd2642d8..83c99fcf 100644 --- a/hardinfo/vendor.c +++ b/hardinfo/vendor.c @@ -26,9 +26,7 @@  #include "config.h"  #include "hardinfo.h"  #include "strstr_word.h" - -#include "dt_util.h" /* for appf() */ -#define SEQ(a,b) (g_strcmp0(a,b) == 0) +#include "util_sysobj.h" /* for appfsp() and SEQ() */  /* { match_string, match_rule, name, url } */  static Vendor vendors_builtin[] = { @@ -347,14 +345,14 @@ const Vendor *vendor_match(const gchar *id_str, ...) {      if (id_str) {          c++;          tl += strlen(id_str); -        tmp = appf(tmp, "%s", id_str); +        tmp = appfsp(tmp, "%s", id_str);          va_start(ap, id_str);          p = va_arg(ap, gchar*);          while(p) {              c++;              tl += strlen(p); -            tmp = appf(tmp, "%s", p); +            tmp = appfsp(tmp, "%s", p);              p = va_arg(ap, gchar*);          }          va_end(ap); @@ -425,6 +423,11 @@ gchar *vendor_get_link(const gchar *id_str)  gchar *vendor_get_link_from_vendor(const Vendor *v)  { +    gboolean label_link_ok = FALSE; +#if GTK_CHECK_VERSION(2, 18, 0) +    label_link_ok = TRUE; +#endif +      if (!v) {          return g_strdup(_("Unknown"));      } @@ -433,7 +436,7 @@ gchar *vendor_get_link_from_vendor(const Vendor *v)          return g_strdup(v->name);      } -    if (params.markup_ok) { +    if (params.markup_ok && label_link_ok) {          const gchar *prefix;          if (!strncmp(v->url, "http://", sizeof("http://") - 1) || @@ -506,14 +509,14 @@ vendor_list vendors_match(const gchar *id_str, ...) {      if (id_str) {          c++;          tl += strlen(id_str); -        tmp = appf(tmp, "%s", id_str); +        tmp = appfsp(tmp, "%s", id_str);          va_start(ap, id_str);          p = va_arg(ap, gchar*);          while(p) {              c++;              tl += strlen(p); -            tmp = appf(tmp, "%s", p); +            tmp = appfsp(tmp, "%s", p);              p = va_arg(ap, gchar*);          }          va_end(ap); | 
