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); |