diff options
author | Lucas de Castro Borges <lucas@gnuabordo.com.br> | 2024-04-22 00:35:53 -0300 |
---|---|---|
committer | Lucas de Castro Borges <lucas@gnuabordo.com.br> | 2024-04-22 00:35:53 -0300 |
commit | 5f01c706267c595de92406a32e7f31ef5056c2d0 (patch) | |
tree | d1e74ef54efc41ada622900fe3e2a50dee44a237 /modules/computer/modules.c | |
parent | 09fcc751ef158898c315ebc9299a0fa3a722d914 (diff) |
New upstream version 2.0.3preupstream/2.0.3pre
Diffstat (limited to 'modules/computer/modules.c')
-rw-r--r-- | modules/computer/modules.c | 471 |
1 files changed, 347 insertions, 124 deletions
diff --git a/modules/computer/modules.c b/modules/computer/modules.c index df876e3a..14028362 100644 --- a/modules/computer/modules.c +++ b/modules/computer/modules.c @@ -1,10 +1,10 @@ /* * HardInfo - Displays System Information - * Copyright (C) 2003-2006 Leandro A. F. Pereira <leandro@hardinfo.org> + * Copyright (C) 2003-2006 L. A. F. Pereira <l@tia.mat.br> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, version 2. + * the Free Software Foundation, version 2 or later. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of @@ -17,161 +17,384 @@ */ #include <string.h> +#include <sys/utsname.h> +#include <json-glib/json-glib.h> -#include "hardinfo.h" +#include "syncmanager.h" #include "computer.h" #include "cpu_util.h" /* for STRIFNULL() */ +#include "hardinfo.h" -#define GET_STR(field_name,ptr) \ - if (!ptr && strstr(tmp[0], field_name)) { \ - ptr = g_markup_escape_text(g_strstrip(tmp[1]), strlen(tmp[1])); \ - g_strfreev(tmp); \ - continue; \ - } +#define GET_STR(field_name, ptr) \ + if (!ptr && strstr(tmp[0], field_name)) { \ + ptr = g_markup_escape_text(g_strstrip(tmp[1]), strlen(tmp[1])); \ + g_strfreev(tmp); \ + continue; \ + } GHashTable *_module_hash_table = NULL; +static gchar *kernel_modules_dir = NULL; + +enum icons { + ICON_INVALID = 0, + + ICON_AUDIO, + ICON_BLUETOOTH, + ICON_CAMERA_WEB, + ICON_CDROM, + ICON_CRYPTOHASH, + ICON_DEVICES, + ICON_HDD, + ICON_INPUTDEVICES, + ICON_JOYSTICK, + ICON_KEYBOARD, + ICON_MEDIA_FLOPPY, + ICON_MEDIA_REMOVABLE, + ICON_MEMORY, + ICON_MONITOR, + ICON_MOUSE, + ICON_NETWORK, + ICON_NETWORK_CONNECTIONS, + ICON_NETWORK_INTERFACE, + ICON_THERM, + ICON_USB, + ICON_WIRELESS, + + ICON_MAX, +}; + +static const char *icon_table[ICON_MAX] = { + [ICON_AUDIO] = "audio", + [ICON_BLUETOOTH] = "bluetooth", + [ICON_CAMERA_WEB] = "camera-web", + [ICON_CDROM] = "cdrom", + [ICON_CRYPTOHASH] = "cryptohash", + [ICON_DEVICES] = "devices", + [ICON_HDD] = "hdd", + [ICON_INPUTDEVICES] = "inputdevices", + [ICON_JOYSTICK] = "joystick", + [ICON_KEYBOARD] = "keyboard", + [ICON_MEDIA_FLOPPY] = "media-floppy", + [ICON_MEDIA_REMOVABLE] = "media-removable", + [ICON_MEMORY] = "memory", + [ICON_MONITOR] = "monitor", + [ICON_MOUSE] = "mouse", + [ICON_NETWORK] = "network", + [ICON_NETWORK_CONNECTIONS] = "network-connections", + [ICON_NETWORK_INTERFACE] = "network-interface", + [ICON_THERM] = "therm", + [ICON_USB] = "usb", + [ICON_WIRELESS] = "wireless", +}; + +/* Keep this sorted by reverse strlen(dir)! */ +static const struct { + const gchar *dir; + enum icons icon; +} modules_icons[] = { + {"drivers/input/joystick/", ICON_JOYSTICK}, + {"drivers/input/keyboard/", ICON_KEYBOARD}, + {"drivers/media/usb/uvc/", ICON_CAMERA_WEB}, + {"drivers/net/wireless/", ICON_WIRELESS}, + {"drivers/net/ethernet/", ICON_NETWORK_INTERFACE}, + {"drivers/input/mouse/", ICON_MOUSE}, + {"drivers/bluetooth/", ICON_BLUETOOTH}, + {"drivers/media/v4l", ICON_CAMERA_WEB}, + {"arch/x86/crypto/", ICON_CRYPTOHASH}, + {"drivers/crypto/", ICON_CRYPTOHASH}, + {"net/bluetooth/", ICON_BLUETOOTH}, + {"drivers/input/", ICON_INPUTDEVICES}, + {"drivers/cdrom/", ICON_CDROM}, + {"drivers/hwmon/", ICON_THERM}, + {"drivers/iommu/", ICON_MEMORY}, + {"net/wireless/", ICON_WIRELESS}, + {"drivers/nvme/", ICON_HDD}, + {"net/ethernet/", ICON_NETWORK_INTERFACE}, + {"drivers/scsi/", ICON_HDD}, + {"drivers/edac/", ICON_MEMORY}, + {"drivers/hid/", ICON_INPUTDEVICES}, + {"drivers/gpu/", ICON_MONITOR}, + {"drivers/i2c/", ICON_MEMORY}, + {"drivers/ata/", ICON_HDD}, + {"drivers/usb/", ICON_USB}, + {"drivers/pci/", ICON_DEVICES}, + {"drivers/net/", ICON_NETWORK}, + {"drivers/mmc/", ICON_MEDIA_REMOVABLE}, + {"crypto/", ICON_CRYPTOHASH}, + {"sound/", ICON_AUDIO}, + {"net/", ICON_NETWORK_CONNECTIONS}, + {"fs/", ICON_MEDIA_FLOPPY}, + {}, +}; + +static GHashTable *module_icons; -void -scan_modules_do(void) +static void build_icon_table_iter(JsonObject *object, + const gchar *key, + JsonNode *value, + gpointer user_data) { + char *key_copy = g_strdup(key); + char *p; + + for (p = key_copy; *p; p++) { + if (*p == '_') + *p = '-'; + } + + enum icons icon; + const gchar *value_str = json_node_get_string(value); + for (icon = ICON_INVALID; icon < ICON_MAX; icon++) { + const char *icon_name = icon_table[icon]; + + if (!icon_name) + continue; + + if (g_str_equal(value_str, icon_name)) { + g_hash_table_insert(module_icons, + key_copy, GINT_TO_POINTER(icon)); + return; + } + } + + g_free(key_copy); +} + +void kernel_module_icon_init(void) +{ + gchar *icon_json; + + static SyncEntry sync_entry = { + .name = N_("Update kernel module icon table"), + .file_name = "kernel-module-icons.json", + }; + sync_manager_add_entry(&sync_entry); + + icon_json = g_build_filename(g_get_user_config_dir(), + "hardinfo", "kernel-module-icons.json", + NULL); + + module_icons = g_hash_table_new(g_str_hash, g_str_equal); + + if (!g_file_test(icon_json, G_FILE_TEST_EXISTS)) + goto out; + + JsonParser *parser = json_parser_new(); + if (!json_parser_load_from_file(parser, icon_json, NULL)) + goto out_destroy_parser; + + JsonNode *root = json_parser_get_root(parser); + if (json_node_get_node_type(root) != JSON_NODE_OBJECT) + goto out_destroy_parser; + + JsonObject *icons = json_node_get_object(root); + if (!icons) + goto out_destroy_parser; + + json_object_foreach_member(icons, build_icon_table_iter, NULL); + +out_destroy_parser: + g_object_unref(parser); + +out: + g_free(icon_json); +} + +static const gchar* get_module_icon(const char *modname, const char *path) +{ + char *modname_temp = g_strdup(modname); + char *p; + for (p = modname_temp; *p; p++) { + if (*p == '_') + *p = '-'; + } + gpointer icon = g_hash_table_lookup(module_icons, modname_temp); + g_free(modname_temp); + if (icon) + return icon_table[GPOINTER_TO_INT(icon)]; + + if (path == NULL) /* modinfo couldn't find module path */ + return NULL; + + if (kernel_modules_dir == NULL) { + struct utsname utsbuf; + uname(&utsbuf); + kernel_modules_dir = g_strdup_printf("/lib/modules/%s/kernel/", utsbuf.release); + } + + if (!g_str_has_prefix(path, kernel_modules_dir)) + return NULL; + + const gchar *path_no_prefix = path + strlen(kernel_modules_dir); + const size_t path_no_prefix_len = strlen(path_no_prefix); + int i; + + for (i = 0; modules_icons[i].dir; i++) { + if (g_str_has_prefix(path_no_prefix, modules_icons[i].dir)) + return icon_table[modules_icons[i].icon]; + } + + return NULL; +} + +void scan_modules_do(void) { FILE *lsmod; gchar buffer[1024]; gchar *lsmod_path; + gchar *module_icons; + const gchar *icon; - if (!_module_hash_table) { - _module_hash_table = g_hash_table_new(g_str_hash, g_str_equal); - } + if (!_module_hash_table) { _module_hash_table = g_hash_table_new(g_str_hash, g_str_equal); } g_free(module_list); + kernel_modules_dir = NULL; module_list = NULL; + module_icons = NULL; moreinfo_del_with_prefix("COMP:MOD"); lsmod_path = find_program("lsmod"); - if (!lsmod_path) - return; + if (!lsmod_path) return; lsmod = popen(lsmod_path, "r"); if (!lsmod) { g_free(lsmod_path); - return; + return; } - (void)fgets(buffer, 1024, lsmod); /* Discards the first line */ + (void)fgets(buffer, 1024, lsmod); /* Discards the first line */ while (fgets(buffer, 1024, lsmod)) { - gchar *buf, *strmodule, *hashkey; - gchar *author = NULL, - *description = NULL, - *license = NULL, - *deps = NULL, *vermagic = NULL, *filename = NULL, modname[64]; - FILE *modi; - glong memory; - - shell_status_pulse(); - - buf = buffer; - - sscanf(buf, "%s %ld", modname, &memory); - - hashkey = g_strdup_printf("MOD%s", modname); - buf = g_strdup_printf("/sbin/modinfo %s 2>/dev/null", modname); - - modi = popen(buf, "r"); - while (fgets(buffer, 1024, modi)) { - gchar **tmp = g_strsplit(buffer, ":", 2); - - GET_STR("author", author); - GET_STR("description", description); - GET_STR("license", license); - GET_STR("depends", deps); - GET_STR("vermagic", vermagic); - GET_STR("filename", filename); - - g_strfreev(tmp); - } - pclose(modi); - g_free(buf); - - /* old modutils includes quotes in some strings; strip them */ - /*remove_quotes(modname); - remove_quotes(description); - remove_quotes(vermagic); - remove_quotes(author); - remove_quotes(license); */ - - /* old modutils displays <none> when there's no value for a - given field; this is not desirable in the module name - display, so change it to an empty string */ - if (description && g_str_equal(description, "<none>")) { - g_free(description); - description = g_strdup(""); - - g_hash_table_insert(_module_hash_table, - g_strdup(modname), + gchar *buf, *strmodule, *hashkey; + gchar *author = NULL, *description = NULL, *license = NULL, *deps = NULL, *vermagic = NULL, + *filename = NULL, *srcversion = NULL, *version = NULL, *retpoline = NULL, + *intree = NULL, modname[64]; + FILE *modi; + glong memory; + + shell_status_pulse(); + + buf = buffer; + + sscanf(buf, "%s %ld", modname, &memory); + + hashkey = g_strdup_printf("MOD%s", modname); + buf = g_strdup_printf("/sbin/modinfo %s 2>/dev/null", modname); + + modi = popen(buf, "r"); + while (fgets(buffer, 1024, modi)) { + gchar **tmp = g_strsplit(buffer, ":", 2); + + GET_STR("author", author); + GET_STR("description", description); + GET_STR("license", license); + GET_STR("depends", deps); + GET_STR("vermagic", vermagic); + GET_STR("filename", filename); + GET_STR("srcversion", srcversion); /* so "version" doesn't catch */ + GET_STR("version", version); + GET_STR("retpoline", retpoline); + GET_STR("intree", intree); + + g_strfreev(tmp); + } + pclose(modi); + g_free(buf); + + /* old modutils includes quotes in some strings; strip them */ + /*remove_quotes(modname); + remove_quotes(description); + remove_quotes(vermagic); + remove_quotes(author); + remove_quotes(license); */ + + /* old modutils displays <none> when there's no value for a + given field; this is not desirable in the module name + display, so change it to an empty string */ + if (description && g_str_equal(description, "<none>")) { + g_free(description); + description = g_strdup(""); + + g_hash_table_insert(_module_hash_table, g_strdup(modname), g_strdup_printf("Kernel module (%s)", modname)); - } else { - g_hash_table_insert(_module_hash_table, - g_strdup(modname), - g_strdup(description)); + } else { + g_hash_table_insert(_module_hash_table, g_strdup(modname), g_strdup(description)); } - /* append this module to the list of modules */ - module_list = h_strdup_cprintf("$%s$%s=%s\n", - module_list, - hashkey, - modname, - description ? description : ""); - - STRIFNULL(filename, _("(Not available)") ); - STRIFNULL(description, _("(Not available)") ); - STRIFNULL(vermagic, _("(Not available)") ); - STRIFNULL(author, _("(Not available)") ); - STRIFNULL(license, _("(Not available)") ); - - /* create the module information string */ - strmodule = g_strdup_printf("[%s]\n" - "%s=%s\n" - "%s=%.2f %s\n" - "[%s]\n" - "%s=%s\n" - "%s=%s\n" - "%s=%s\n" - "[%s]\n" - "%s=%s\n" - "%s=%s\n", - _("Module Information"), - _("Path"), filename, - _("Used Memory"), memory / 1024.0, _("KiB"), - _("Description"), - _("Name"), modname, - _("Description"), description, - _("Version Magic"), vermagic, - _("Copyright"), - _("Author"), author, - _("License"), license ); - - /* if there are dependencies, append them to that string */ - if (deps && strlen(deps)) { - gchar **tmp = g_strsplit(deps, ",", 0); - - strmodule = h_strconcat(strmodule, - "\n[", _("Dependencies"), "]\n", - g_strjoinv("=\n", tmp), - "=\n", NULL); - g_strfreev(tmp); - g_free(deps); - } + /* append this module to the list of modules */ + module_list = h_strdup_cprintf("$%s$%s=%s\n", module_list, hashkey, modname, + description ? description : ""); + icon = get_module_icon(modname, filename); + module_icons = h_strdup_cprintf("Icon$%s$%s=%s.png\n", module_icons, hashkey, + modname, icon ? icon: "module"); + + STRIFNULL(filename, _("(Not available)")); + STRIFNULL(description, _("(Not available)")); + STRIFNULL(vermagic, _("(Not available)")); + STRIFNULL(author, _("(Not available)")); + STRIFNULL(license, _("(Not available)")); + STRIFNULL(version, _("(Not available)")); + + gboolean ry = FALSE, ity = FALSE; + if (retpoline && *retpoline == 'Y') ry = TRUE; + if (intree && *intree == 'Y') ity = TRUE; - moreinfo_add_with_prefix("COMP", hashkey, strmodule); - g_free(hashkey); + g_free(retpoline); + g_free(intree); - g_free(license); - g_free(description); - g_free(author); - g_free(vermagic); - g_free(filename); + retpoline = g_strdup(ry ? _("Yes") : _("No")); + intree = g_strdup(ity ? _("Yes") : _("No")); + + /* create the module information string */ + strmodule = g_strdup_printf("[%s]\n" + "%s=%s\n" + "%s=%.2f %s\n" + "[%s]\n" + "%s=%s\n" + "%s=%s\n" + "%s=%s\n" + "%s=%s\n" + "%s=%s\n" + "%s=%s\n" + "[%s]\n" + "%s=%s\n" + "%s=%s\n", + _("Module Information"), _("Path"), filename, _("Used Memory"), + memory / 1024.0, _("KiB"), _("Description"), _("Name"), modname, + _("Description"), description, _("Version Magic"), vermagic, + _("Version"), version, _("In Linus' Tree"), intree, + _("Retpoline Enabled"), retpoline, _("Copyright"), _("Author"), + author, _("License"), license); + + /* if there are dependencies, append them to that string */ + if (deps && strlen(deps)) { + gchar **tmp = g_strsplit(deps, ",", 0); + + strmodule = h_strconcat(strmodule, "\n[", _("Dependencies"), "]\n", + g_strjoinv("=\n", tmp), "=\n", NULL); + g_strfreev(tmp); + g_free(deps); + } + + moreinfo_add_with_prefix("COMP", hashkey, strmodule); + g_free(hashkey); + + g_free(license); + g_free(description); + g_free(author); + g_free(vermagic); + g_free(filename); + g_free(srcversion); + g_free(version); + g_free(retpoline); + g_free(intree); } pclose(lsmod); g_free(lsmod_path); + g_free(kernel_modules_dir); + + if (module_list != NULL && module_icons != NULL) { + module_list = h_strdup_cprintf("[$ShellParam$]\n%s", module_list, module_icons); + } + g_free(module_icons); } |