diff options
author | bigbear <ns@bigbear.dk> | 2024-02-08 19:52:52 +0100 |
---|---|---|
committer | bigbear <ns@bigbear.dk> | 2024-02-08 19:52:52 +0100 |
commit | 9a05f56e1bf36abab41d12f92f2c75266c44bd4a (patch) | |
tree | f9ac600d137939dd484732515363a2337bdc6535 /hardinfo | |
parent | 0f5dea06fa62062c7e98b36945a63aae7835a80a (diff) |
Clean - HARDINFO2 BASE
Diffstat (limited to 'hardinfo')
-rw-r--r-- | hardinfo/binreloc.c | 668 | ||||
-rw-r--r-- | hardinfo/cpu_util.c | 251 | ||||
-rw-r--r-- | hardinfo/dmi_util.c | 450 | ||||
-rw-r--r-- | hardinfo/dt_util.c | 1187 | ||||
-rw-r--r-- | hardinfo/expr.c | 250 | ||||
-rw-r--r-- | hardinfo/gg_key_file_parse_string_as_value.c | 111 | ||||
-rw-r--r-- | hardinfo/gg_strescape.c | 138 | ||||
-rw-r--r-- | hardinfo/gpu_util.c | 477 | ||||
-rw-r--r-- | hardinfo/hardinfo.c | 169 | ||||
-rw-r--r-- | hardinfo/hinote_util.c | 27 | ||||
-rw-r--r-- | hardinfo/info.c | 584 | ||||
-rw-r--r-- | hardinfo/pci_util.c | 463 | ||||
-rw-r--r-- | hardinfo/problem_marker.c | 13 | ||||
-rw-r--r-- | hardinfo/socket.c | 127 | ||||
-rw-r--r-- | hardinfo/storage_util.c | 250 | ||||
-rw-r--r-- | hardinfo/udisks2_util.c | 639 | ||||
-rw-r--r-- | hardinfo/usb_util.c | 553 | ||||
-rw-r--r-- | hardinfo/util.c | 1445 | ||||
-rw-r--r-- | hardinfo/vendor.c | 655 | ||||
-rw-r--r-- | hardinfo/x_util.c | 342 |
20 files changed, 0 insertions, 8799 deletions
diff --git a/hardinfo/binreloc.c b/hardinfo/binreloc.c deleted file mode 100644 index f47a3fae..00000000 --- a/hardinfo/binreloc.c +++ /dev/null @@ -1,668 +0,0 @@ -/* - * BinReloc - a library for creating relocatable executables - * Written by: Hongli Lai <h.lai@chello.nl> - * http://autopackage.org/ - * - * This source code is public domain. You can relicense this code - * under whatever license you want. - * - * See http://autopackage.org/docs/binreloc/ for - * more information and how to use this. - */ - -#ifndef __BINRELOC_C__ -#define __BINRELOC_C__ - -#include <sys/types.h> -#include <sys/stat.h> -#include <unistd.h> -#include <stdio.h> -#include <stdlib.h> -#include <limits.h> -#include <string.h> -#include "binreloc.h" -#include "config.h" - -G_BEGIN_DECLS -/** @internal - * Find the canonical filename of the executable. Returns the filename - * (which must be freed) or NULL on error. If the parameter 'error' is - * not NULL, the error code will be stored there, if an error occured. - */ -static char *_br_find_exe(GbrInitError * error) -{ - char *path, *path2, *line, *result; - size_t buf_size; - ssize_t size; - struct stat stat_buf; - FILE *f; - - /* Read from /proc/self/exe (symlink) */ - if (sizeof(path) > SSIZE_MAX) - buf_size = SSIZE_MAX - 1; - else - buf_size = PATH_MAX - 1; - path = (char *) g_try_malloc(buf_size); - if (path == NULL) { - /* Cannot allocate memory. */ - if (error) - *error = GBR_INIT_ERROR_NOMEM; - return NULL; - } - path2 = (char *) g_try_malloc(buf_size); - if (path2 == NULL) { - /* Cannot allocate memory. */ - if (error) - *error = GBR_INIT_ERROR_NOMEM; - g_free(path); - return NULL; - } - - strncpy(path2, "/proc/self/exe", buf_size - 1); - - while (1) { - int i; - - size = readlink(path2, path, buf_size - 1); - if (size == -1) { - /* Error. */ - g_free(path2); - break; - } - - /* readlink() success. */ - path[size] = '\0'; - - /* Check whether the symlink's target is also a symlink. - * We want to get the final target. */ - i = stat(path, &stat_buf); - if (i == -1) { - /* Error. */ - g_free(path2); - break; - } - - /* stat() success. */ - if (!S_ISLNK(stat_buf.st_mode)) { - /* path is not a symlink. Done. */ - g_free(path2); - return path; - } - - /* path is a symlink. Continue loop and resolve this. */ - strncpy(path, path2, buf_size - 1); - } - - - /* readlink() or stat() failed; this can happen when the program is - * running in Valgrind 2.2. Read from /proc/self/maps as fallback. */ - - buf_size = PATH_MAX + 128; - line = (char *) g_try_realloc(path, buf_size); - if (line == NULL) { - /* Cannot allocate memory. */ - g_free(path); - if (error) - *error = GBR_INIT_ERROR_NOMEM; - return NULL; - } - - f = fopen("/proc/self/maps", "r"); - if (f == NULL) { - g_free(line); - if (error) - *error = GBR_INIT_ERROR_OPEN_MAPS; - return NULL; - } - - /* The first entry should be the executable name. */ - result = fgets(line, (int) buf_size, f); - if (result == NULL) { - fclose(f); - g_free(line); - if (error) - *error = GBR_INIT_ERROR_READ_MAPS; - return NULL; - } - - /* Get rid of newline character. */ - buf_size = strlen(line); - if (buf_size <= 0) { - /* Huh? An empty string? */ - fclose(f); - g_free(line); - if (error) - *error = GBR_INIT_ERROR_INVALID_MAPS; - return NULL; - } - if (line[buf_size - 1] == 10) - line[buf_size - 1] = 0; - - /* Extract the filename; it is always an absolute path. */ - path = strchr(line, '/'); - - /* Sanity check. */ - if (strstr(line, " r-xp ") == NULL || path == NULL) { - fclose(f); - g_free(line); - if (error) - *error = GBR_INIT_ERROR_INVALID_MAPS; - return NULL; - } - - path = g_strdup(path); - g_free(line); - fclose(f); - return path; -} - - -/** @internal - * Find the canonical filename of the executable which owns symbol. - * Returns a filename which must be freed, or NULL on error. - */ -static char *_br_find_exe_for_symbol(const void *symbol, - GbrInitError * error) -{ -#define SIZE PATH_MAX + 100 - FILE *f; - size_t address_string_len; - char *address_string, line[SIZE], *found; - - if (symbol == NULL) - return (char *) NULL; - - f = fopen("/proc/self/maps", "r"); - if (f == NULL) - return (char *) NULL; - - address_string_len = 4; - address_string = (char *) g_try_malloc(address_string_len); - found = (char *) NULL; - - while (!feof(f)) { - char *start_addr, *end_addr, *end_addr_end, *file; - void *start_addr_p, *end_addr_p; - size_t len; - - if (fgets(line, SIZE, f) == NULL) - break; - - /* Sanity check. */ - if (strstr(line, " r-xp ") == NULL || strchr(line, '/') == NULL) - continue; - - /* Parse line. */ - start_addr = line; - end_addr = strchr(line, '-'); - file = strchr(line, '/'); - - /* More sanity check. */ - if (!(file > end_addr && end_addr != NULL && end_addr[0] == '-')) - continue; - - end_addr[0] = '\0'; - end_addr++; - end_addr_end = strchr(end_addr, ' '); - if (end_addr_end == NULL) - continue; - - end_addr_end[0] = '\0'; - len = strlen(file); - if (len == 0) - continue; - if (file[len - 1] == '\n') - file[len - 1] = '\0'; - - /* Get rid of "(deleted)" from the filename. */ - len = strlen(file); - if (len > 10 && strcmp(file + len - 10, " (deleted)") == 0) - file[len - 10] = '\0'; - - /* I don't know whether this can happen but better safe than sorry. */ - len = strlen(start_addr); - if (len != strlen(end_addr)) - continue; - - - /* Transform the addresses into a string in the form of 0xdeadbeef, - * then transform that into a pointer. */ - if (address_string_len < len + 3) { - address_string_len = len + 3; - address_string = - (char *) g_try_realloc(address_string, address_string_len); - } - - memcpy(address_string, "0x", 2); - memcpy(address_string + 2, start_addr, len); - address_string[2 + len] = '\0'; - sscanf(address_string, "%p", &start_addr_p); - - memcpy(address_string, "0x", 2); - memcpy(address_string + 2, end_addr, len); - address_string[2 + len] = '\0'; - sscanf(address_string, "%p", &end_addr_p); - - - if (symbol >= start_addr_p && symbol < end_addr_p) { - found = file; - break; - } - } - - g_free(address_string); - fclose(f); - - if (found == NULL) - return (char *) NULL; - else - return g_strdup(found); -} - - -static gchar *exe = NULL; - -static void set_gerror(GError ** error, GbrInitError errcode); - - -/** Initialize the BinReloc library (for applications). - * - * This function must be called before using any other BinReloc functions. - * It attempts to locate the application's canonical filename. - * - * @note If you want to use BinReloc for a library, then you should call - * gbr_init_lib() instead. - * - * @param error If BinReloc failed to initialize, then the error report will - * be stored in this variable. Set to NULL if you don't want an - * error report. See the #GbrInitError for a list of error - * codes. - * - * @returns TRUE on success, FALSE if BinReloc failed to initialize. - */ -gboolean gbr_init(GError ** error) -{ - GbrInitError errcode = 0; - - /* Locate the application's filename. */ - exe = _br_find_exe(&errcode); - if (exe != NULL) - /* Success! */ - return TRUE; - else { - /* Failed :-( */ - set_gerror(error, errcode); - return FALSE; - } -} - - -/** Initialize the BinReloc library (for libraries). - * - * This function must be called before using any other BinReloc functions. - * It attempts to locate the calling library's canonical filename. - * - * @note The BinReloc source code MUST be included in your library, or this - * function won't work correctly. - * - * @returns TRUE on success, FALSE if a filename cannot be found. - */ -gboolean gbr_init_lib(GError ** error) -{ - GbrInitError errcode = 0; - - exe = _br_find_exe_for_symbol((const void *) "", &errcode); - if (exe != NULL) - /* Success! */ - return TRUE; - else { - /* Failed :-( */ - set_gerror(error, errcode); - return exe != NULL; - } -} - - -static void set_gerror(GError ** error, GbrInitError errcode) -{ - gchar *error_message; - - if (error == NULL) - return; - - switch (errcode) { - case GBR_INIT_ERROR_NOMEM: - error_message = "Cannot allocate memory."; - break; - case GBR_INIT_ERROR_OPEN_MAPS: - error_message = "Unable to open /proc/self/maps for reading."; - break; - case GBR_INIT_ERROR_READ_MAPS: - error_message = "Unable to read from /proc/self/maps."; - break; - case GBR_INIT_ERROR_INVALID_MAPS: - error_message = "The file format of /proc/self/maps is invalid."; - break; - case GBR_INIT_ERROR_DISABLED: - error_message = "Binary relocation support is disabled."; - break; - default: - error_message = "Unknown error."; - break; - }; - g_set_error(error, g_quark_from_static_string("GBinReloc"), - errcode, "%s", error_message); -} - - -/** Find the canonical filename of the current application. - * - * @param default_exe A default filename which will be used as fallback. - * @returns A string containing the application's canonical filename, - * which must be freed when no longer necessary. If BinReloc is - * not initialized, or if the initialization function failed, - * then a copy of default_exe will be returned. If default_exe - * is NULL, then NULL will be returned. - */ -gchar *gbr_find_exe(const gchar * default_exe) -{ - if (exe == NULL) { - /* BinReloc is not initialized. */ - if (default_exe != NULL) - return g_strdup(default_exe); - else - return NULL; - } - return g_strdup(exe); -} - - -/** Locate the directory in which the current application is installed. - * - * The prefix is generated by the following pseudo-code evaluation: - * \code - * dirname(exename) - * \endcode - * - * @param default_dir A default directory which will used as fallback. - * @return A string containing the directory, which must be freed when no - * longer necessary. If BinReloc is not initialized, or if the - * initialization function failed, then a copy of default_dir - * will be returned. If default_dir is NULL, then NULL will be - * returned. - */ -gchar *gbr_find_exe_dir(const gchar * default_dir) -{ - if (exe == NULL) { - /* BinReloc not initialized. */ - if (default_dir != NULL) - return g_strdup(default_dir); - else - return NULL; - } - - return g_path_get_dirname(exe); -} - - -/** Locate the prefix in which the current application is installed. - * - * The prefix is generated by the following pseudo-code evaluation: - * \code - * dirname(dirname(exename)) - * \endcode - * - * @param default_prefix A default prefix which will used as fallback. - * @return A string containing the prefix, which must be freed when no - * longer necessary. If BinReloc is not initialized, or if the - * initialization function failed, then a copy of default_prefix - * will be returned. If default_prefix is NULL, then NULL will be - * returned. - */ -gchar *gbr_find_prefix(const gchar * default_prefix) -{ - gchar *dir1, *dir2; - - if (exe == NULL) { - /* BinReloc not initialized. */ - if (default_prefix != NULL) - return g_strdup(default_prefix); - else - return NULL; - } - - dir1 = g_path_get_dirname(exe); - dir2 = g_path_get_dirname(dir1); - g_free(dir1); - return dir2; -} - - -/** Locate the application's binary folder. - * - * The path is generated by the following pseudo-code evaluation: - * \code - * prefix + "/bin" - * \endcode - * - * @param default_bin_dir A default path which will used as fallback. - * @return A string containing the bin folder's path, which must be freed when - * no longer necessary. If BinReloc is not initialized, or if the - * initialization function failed, then a copy of default_bin_dir will - * be returned. If default_bin_dir is NULL, then NULL will be returned. - */ -gchar *gbr_find_bin_dir(const gchar * default_bin_dir) -{ - gchar *prefix, *dir; - - prefix = gbr_find_prefix(NULL); - if (prefix == NULL) { - /* BinReloc not initialized. */ - if (default_bin_dir != NULL) - return g_strdup(default_bin_dir); - else - return NULL; - } - - dir = g_build_filename(prefix, "bin", NULL); - g_free(prefix); - return dir; -} - - -/** Locate the application's superuser binary folder. - * - * The path is generated by the following pseudo-code evaluation: - * \code - * prefix + "/sbin" - * \endcode - * - * @param default_sbin_dir A default path which will used as fallback. - * @return A string containing the sbin folder's path, which must be freed when - * no longer necessary. If BinReloc is not initialized, or if the - * initialization function failed, then a copy of default_sbin_dir will - * be returned. If default_bin_dir is NULL, then NULL will be returned. - */ -gchar *gbr_find_sbin_dir(const gchar * default_sbin_dir) -{ - gchar *prefix, *dir; - - prefix = gbr_find_prefix(NULL); - if (prefix == NULL) { - /* BinReloc not initialized. */ - if (default_sbin_dir != NULL) - return g_strdup(default_sbin_dir); - else - return NULL; - } - - dir = g_build_filename(prefix, "sbin", NULL); - g_free(prefix); - return dir; -} - - -/** Locate the application's data folder. - * - * The path is generated by the following pseudo-code evaluation: - * \code - * prefix + "/share" - * \endcode - * - * @param default_data_dir A default path which will used as fallback. - * @return A string containing the data folder's path, which must be freed when - * no longer necessary. If BinReloc is not initialized, or if the - * initialization function failed, then a copy of default_data_dir - * will be returned. If default_data_dir is NULL, then NULL will be - * returned. - */ -gchar *gbr_find_data_dir(const gchar * default_data_dir) -{ - gchar *prefix, *dir; - - prefix = gbr_find_prefix(NULL); - if (prefix == NULL) { - /* BinReloc not initialized. */ - if (default_data_dir != NULL) - return g_strdup(default_data_dir); - else - return NULL; - } - - dir = g_build_filename(prefix, "share", NULL); - g_free(prefix); - return dir; -} - - -/** Locate the application's localization folder. - * - * The path is generated by the following pseudo-code evaluation: - * \code - * prefix + "/share/locale" - * \endcode - * - * @param default_locale_dir A default path which will used as fallback. - * @return A string containing the localization folder's path, which must be freed when - * no longer necessary. If BinReloc is not initialized, or if the - * initialization function failed, then a copy of default_locale_dir will be returned. - * If default_locale_dir is NULL, then NULL will be returned. - */ -gchar *gbr_find_locale_dir(const gchar * default_locale_dir) -{ - gchar *data_dir, *dir; - - data_dir = gbr_find_data_dir(NULL); - if (data_dir == NULL) { - /* BinReloc not initialized. */ - if (default_locale_dir != NULL) - return g_strdup(default_locale_dir); - else - return NULL; - } - - dir = g_build_filename(data_dir, "locale", NULL); - g_free(data_dir); - return dir; -} - - -/** Locate the application's library folder. - * - * The path is generated by the following pseudo-code evaluation: - * \code - * prefix + "/lib" - * \endcode - * - * @param default_lib_dir A default path which will used as fallback. - * @return A string containing the library folder's path, which must be freed when - * no longer necessary. If BinReloc is not initialized, or if the - * initialization function failed, then a copy of default_lib_dir will be returned. - * If default_lib_dir is NULL, then NULL will be returned. - */ -gchar *gbr_find_lib_dir(const gchar * default_lib_dir) -{ - gchar *prefix, *dir; - - prefix = gbr_find_prefix(NULL); - if (prefix == NULL) { - /* BinReloc not initialized. */ - if (default_lib_dir != NULL) - return g_strdup(default_lib_dir); - else - return NULL; - } - - dir = g_build_filename(prefix, LIBDIR, NULL); - - g_free(prefix); - return dir; -} - - -/** Locate the application's libexec folder. - * - * The path is generated by the following pseudo-code evaluation: - * \code - * prefix + "/libexec" - * \endcode - * - * @param default_libexec_dir A default path which will used as fallback. - * @return A string containing the libexec folder's path, which must be freed when - * no longer necessary. If BinReloc is not initialized, or if the initialization - * function failed, then a copy of default_libexec_dir will be returned. - * If default_libexec_dir is NULL, then NULL will be returned. - */ -gchar *gbr_find_libexec_dir(const gchar * default_libexec_dir) -{ - gchar *prefix, *dir; - - prefix = gbr_find_prefix(NULL); - if (prefix == NULL) { - /* BinReloc not initialized. */ - if (default_libexec_dir != NULL) - return g_strdup(default_libexec_dir); - else - return NULL; - } - - dir = g_build_filename(prefix, "libexec", NULL); - g_free(prefix); - return dir; -} - - -/** Locate the application's configuration files folder. - * - * The path is generated by the following pseudo-code evaluation: - * \code - * prefix + "/etc" - * \endcode - * - * @param default_etc_dir A default path which will used as fallback. - * @return A string containing the etc folder's path, which must be freed when - * no longer necessary. If BinReloc is not initialized, or if the initialization - * function failed, then a copy of default_etc_dir will be returned. - * If default_etc_dir is NULL, then NULL will be returned. - */ -gchar *gbr_find_etc_dir(const gchar * default_etc_dir) -{ - gchar *prefix, *dir; - - prefix = gbr_find_prefix(NULL); - if (prefix == NULL) { - /* BinReloc not initialized. */ - if (default_etc_dir != NULL) - return g_strdup(default_etc_dir); - else - return NULL; - } - - dir = g_build_filename(prefix, "etc", NULL); - g_free(prefix); - return dir; -} - - -G_END_DECLS -#endif /* __BINRELOC_C__ */ diff --git a/hardinfo/cpu_util.c b/hardinfo/cpu_util.c deleted file mode 100644 index 8db5f61a..00000000 --- a/hardinfo/cpu_util.c +++ /dev/null @@ -1,251 +0,0 @@ -/* - * HardInfo - Displays System Information - * Copyright (C) 2003-2006 L. A. F. Pereira <l@tia.mat.br> - * This file by Burt P. <pburt0@gmail.com> - * - * 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. - * - * This program 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include <string.h> -#include "hardinfo.h" -#include "cpu_util.h" -#include "cpubits.h" - -#define CPU_TOPO_NULL -9877 - -const gchar *byte_order_str() { -#if G_BYTE_ORDER == G_LITTLE_ENDIAN - return _("Little Endian"); -#else - return _("Big Endian"); -#endif -} - -int processor_has_flag(gchar * strflags, gchar * strflag) -{ - gchar **flags; - gint ret = 0; - if (strflags == NULL || strflag == NULL) - return 0; - flags = g_strsplit(strflags, " ", 0); - ret = g_strv_contains((const gchar * const *)flags, strflag); - g_strfreev(flags); - return ret; -} - -gchar* get_cpu_str(const gchar* file, gint cpuid) { - gchar *tmp0 = NULL; - gchar *tmp1 = NULL; - tmp0 = g_strdup_printf("/sys/devices/system/cpu/cpu%d/%s", cpuid, file); - g_file_get_contents(tmp0, &tmp1, NULL, NULL); - g_free(tmp0); - return tmp1; -} - -gint get_cpu_int(const char* item, int cpuid, int null_val) { - gchar *fc = NULL; - int ret = null_val; - fc = get_cpu_str(item, cpuid); - if (fc) { - ret = atol(fc); - g_free(fc); - } - return ret; -} - -/* cpubits is 32768 bits long - * core_ids are not unique among physical_ids - * hack up cpubits into 128 packs of 256 cores - * to make cores unique in cpubits */ -#define MAX_CORES_PER_PACK 256 -#define MAX_PACKS 128 - -int cpu_procs_cores_threads_nodes(int *p, int *c, int *t, int *n) -{ - cpubits *threads, *cores, *packs; - char *tmp; - int i, m, pack_id, core_id; - - g_file_get_contents("/sys/devices/system/cpu/present", &tmp, NULL, NULL); - if (tmp == NULL) { - *p = *c = *t = *n = -1; - return 0; - } - - threads = cpubits_from_str(tmp); - cores = cpubits_from_str(""); - packs = cpubits_from_str(""); - m = cpubits_max(threads); - for (i = 0; i <= m; i++) { - pack_id = get_cpu_int("topology/physical_package_id", i, CPU_TOPO_NULL); - core_id = get_cpu_int("topology/core_id", i, CPU_TOPO_NULL); - if (pack_id < 0) - pack_id = 0; - CPUBIT_SET(packs, pack_id); - if (core_id >= 0) { - CPUBIT_SET(cores, (pack_id * MAX_CORES_PER_PACK) + core_id); - } - } - - *t = cpubits_count(threads); - *c = cpubits_count(cores); - *p = cpubits_count(packs); - - g_free(tmp); - g_file_get_contents("/sys/devices/system/node/possible", &tmp, NULL, NULL); - if (tmp != NULL) { - cpubits *nodes = cpubits_from_str(tmp); - if (nodes) - *n = cpubits_count(nodes); - free(nodes); - } - - if (!*c) - *c = 1; - if (!*p) - *p = 1; - if (!*n) - *n = 1; - - g_free(threads); - g_free(cores); - g_free(packs); - g_free(tmp); - return 1; -} - -cpufreq_data *cpufreq_new(gint id) -{ - cpufreq_data *cpufd; - cpufd = malloc(sizeof(cpufreq_data)); - if (cpufd) { - memset(cpufd, 0, sizeof(cpufreq_data)); - cpufd->id = id; - cpufreq_update(cpufd, 0); - } - return cpufd; -} - -void cpufreq_update(cpufreq_data *cpufd, int cur_only) -{ - if (cpufd) { - cpufd->cpukhz_cur = get_cpu_int("cpufreq/scaling_cur_freq", cpufd->id, 0); - if (cur_only) return; - cpufd->scaling_driver = get_cpu_str("cpufreq/scaling_driver", cpufd->id); - cpufd->scaling_governor = get_cpu_str("cpufreq/scaling_governor", cpufd->id); - cpufd->transition_latency = get_cpu_int("cpufreq/cpuinfo_transition_latency", cpufd->id, 0); - cpufd->cpukhz_min = get_cpu_int("cpufreq/scaling_min_freq", cpufd->id, 0); - cpufd->cpukhz_max = get_cpu_int("cpufreq/scaling_max_freq", cpufd->id, 0); - if (cpufd->scaling_driver == NULL) cpufd->scaling_driver = g_strdup("(Unknown)"); - if (cpufd->scaling_governor == NULL) cpufd->scaling_governor = g_strdup("(Unknown)"); - - /* x86 uses freqdomain_cpus, all others use affected_cpus */ - cpufd->shared_list = get_cpu_str("cpufreq/freqdomain_cpus", cpufd->id); - if (cpufd->shared_list == NULL) cpufd->shared_list = get_cpu_str("cpufreq/affected_cpus", cpufd->id); - if (cpufd->shared_list == NULL) cpufd->shared_list = g_strdup_printf("%d", cpufd->id); - } -} - -void cpufreq_free(cpufreq_data *cpufd) -{ - if (cpufd) { - g_free(cpufd->scaling_driver); - g_free(cpufd->scaling_governor); - } - g_free(cpufd); -} - -cpu_topology_data *cputopo_new(gint id) -{ - cpu_topology_data *cputd; - cputd = malloc(sizeof(cpu_topology_data)); - if (cputd) { - memset(cputd, 0, sizeof(cpu_topology_data)); - cputd->id = id; - cputd->socket_id = get_cpu_int("topology/physical_package_id", id, CPU_TOPO_NULL); - cputd->core_id = get_cpu_int("topology/core_id", id, CPU_TOPO_NULL); - cputd->book_id = get_cpu_int("topology/book_id", id, CPU_TOPO_NULL); - cputd->drawer_id = get_cpu_int("topology/drawer_id", id, CPU_TOPO_NULL); - } - return cputd; - -} - -void cputopo_free(cpu_topology_data *cputd) -{ - g_free(cputd); -} - -gchar *cpufreq_section_str(cpufreq_data *cpufd) -{ - if (cpufd == NULL) - return g_strdup(""); - - if (cpufd->cpukhz_min || cpufd->cpukhz_max || cpufd->cpukhz_cur) { - return g_strdup_printf( - "[%s]\n" - "%s=%d %s\n" - "%s=%d %s\n" - "%s=%d %s\n" - "%s=%d %s\n" - "%s=%s\n" - "%s=%s\n", - _("Frequency Scaling"), - _("Minimum"), cpufd->cpukhz_min, _("kHz"), - _("Maximum"), cpufd->cpukhz_max, _("kHz"), - _("Current"), cpufd->cpukhz_cur, _("kHz"), - _("Transition Latency"), cpufd->transition_latency, _("ns"), - _("Governor"), cpufd->scaling_governor, - _("Driver"), cpufd->scaling_driver); - } else { - return g_strdup_printf( - "[%s]\n" - "%s=%s\n", - _("Frequency Scaling"), - _("Driver"), cpufd->scaling_driver); - } -} - -gchar *cputopo_section_str(cpu_topology_data *cputd) -{ - static const char na[] = N_("(Not Available)"); - char sock_str[64] = "", core_str[64] = ""; - char book_str[64] = "", drawer_str[64] = ""; - - if (cputd == NULL) - return g_strdup(""); - - if (cputd->socket_id != CPU_TOPO_NULL && cputd->socket_id != -1) - sprintf(sock_str, "%s=%d\n", _("Socket"), cputd->socket_id); - else - sprintf(sock_str, "%s=%s\n", _("Socket"), na); - - if (cputd->core_id != CPU_TOPO_NULL) - sprintf(core_str, "%s=%d\n", _("Core"), cputd->core_id); - else - sprintf(core_str, "%s=%s\n", _("Core"), na); - - if (cputd->book_id != CPU_TOPO_NULL) - sprintf(core_str, "%s=%d\n", _("Book"), cputd->book_id); - if (cputd->book_id != CPU_TOPO_NULL) - sprintf(core_str, "%s=%d\n", _("Drawer"), cputd->drawer_id); - - return g_strdup_printf( - "[%s]\n" - "%s=%d\n" - "%s%s%s%s", - _("Topology"), - _("ID"), cputd->id, - sock_str, core_str, book_str, drawer_str ); -} diff --git a/hardinfo/dmi_util.c b/hardinfo/dmi_util.c deleted file mode 100644 index 94351ad7..00000000 --- a/hardinfo/dmi_util.c +++ /dev/null @@ -1,450 +0,0 @@ -/* - * HardInfo - Displays System Information - * Copyright (C) 2003-2017 L. A. F. Pereira <l@tia.mat.br> - * This file - * Copyright (C) 2017 Burt P. <pburt0@gmail.com> - * - * 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. - * - * This program 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "hardinfo.h" -#include "dmi_util.h" - -static const char *dmi_type_strings[] = { - [0] = N_("BIOS Information"), - [1] = N_("System"), - [2] = N_("Base Board"), - [3] = N_("Chassis"), - [4] = N_("Processor"), - [5] = N_("Memory Controller"), - [6] = N_("Memory Module"), - [7] = N_("Cache"), - [8] = N_("Port Connector"), - [9] = N_("System Slots"), - [10] = N_("On Board Devices"), - [11] = N_("OEM Strings"), - [12] = N_("System Configuration Options"), - [13] = N_("BIOS Language"), - [14] = N_("Group Associations"), - [15] = N_("System Event Log"), - [16] = N_("Physical Memory Array"), - [17] = N_("Memory Device"), - [18] = N_("32-bit Memory Error"), - [19] = N_("Memory Array Mapped Address"), - [20] = N_("Memory Device Mapped Address"), - [21] = N_("Built-in Pointing Device"), - [22] = N_("Portable Battery"), - [23] = N_("System Reset"), - [24] = N_("Hardware Security"), - [25] = N_("System Power Controls"), - [26] = N_("Voltage Probe"), - [27] = N_("Cooling Device"), - [28] = N_("Temperature Probe"), - [29] = N_("Electrical Current Probe"), - [30] = N_("Out-of-band Remote Access"), - [31] = N_("Boot Integrity Services"), - [32] = N_("System Boot"), - [33] = N_("64-bit Memory Error"), - [34] = N_("Management Device"), - [35] = N_("Management Device Component"), - [36] = N_("Management Device Threshold Data"), - [37] = N_("Memory Channel"), - [38] = N_("IPMI Device"), - [39] = N_("Power Supply"), - [40] = N_("Additional Information"), - [41] = N_("Onboard Device"), - //127 = End of Table -}; - -/* frees the string and sets it NULL if it is to be ignored - * returns -1 if error, 0 if ok, 1 if ignored */ -static int ignore_placeholder_strings(gchar **pstr) { - gchar *chk, *p; - chk = g_strdup(*pstr); - - if (pstr == NULL || *pstr == NULL) - return -1; -#define DMI_IGNORE(m) if (strcasecmp(m, *pstr) == 0) { g_free(chk); g_free(*pstr); *pstr = NULL; return 1; } - DMI_IGNORE("To be filled by O.E.M."); - DMI_IGNORE("Default String"); - DMI_IGNORE("System Product Name"); - DMI_IGNORE("System Manufacturer"); - DMI_IGNORE("System Version"); - DMI_IGNORE("System Serial Number"); - DMI_IGNORE("Rev X.0x"); /* ASUS board version nonsense */ - DMI_IGNORE("x.x"); /* Gigabyte board version nonsense */ - DMI_IGNORE("NA"); - DMI_IGNORE("SKU"); - - /* noticed on an HP x360 with Insyde BIOS */ - DMI_IGNORE("Type2 - Board Asset Tag"); - DMI_IGNORE("Type1ProductConfigId"); - - /* Toshiba Laptop with Insyde BIOS */ - DMI_IGNORE("Base Board Version"); - DMI_IGNORE("No Asset Tag"); - DMI_IGNORE("None"); - DMI_IGNORE("Type1Family"); - DMI_IGNORE("123456789"); - - /* ASUS socket 775 MB */ - DMI_IGNORE("Asset-1234567890"); - DMI_IGNORE("MB-1234567890"); - DMI_IGNORE("Chassis Serial Number"); - DMI_IGNORE("Chassis Version"); - DMI_IGNORE("Chassis Manufacture"); - - /* Zotac version nonsense */ - p = chk; - while (*p != 0) { *p = 'x'; p++; } /* all X */ - DMI_IGNORE(chk); - p = chk; - while (*p != 0) { *p = '0'; p++; } /* all 0 */ - DMI_IGNORE(chk); - - /*... more, I'm sure. */ - - g_free(chk); - return 0; -} - -static const char *dmi_sysfs_root(void) { - char *candidates[] = { - "/sys/devices/virtual/dmi", - "/sys/class/dmi", - NULL - }; - int i = 0; - while (candidates[i] != NULL) { - if(access(candidates[i], F_OK) != -1) - return candidates[i]; - i++; - } - return NULL; -} - -int dmi_str_status(const char *id_str) { - gchar *str = dmi_get_str_abs(id_str); - int ret = 1; - - if (!str) - ret = 0; - - if ( ignore_placeholder_strings(&str) > 0 ) - ret = -1; - - g_free(str); - return ret; -} - -char *dmi_get_str(const char *id_str) { - gchar *ret = dmi_get_str_abs(id_str); - /* return NULL on empty */ - if (ret && *ret == 0) { - g_free(ret); - ret = NULL; - } - ignore_placeholder_strings(&ret); - return ret; -} - -char *dmi_get_str_abs(const char *id_str) { - static struct { - char *id; - char *path; - } tab_dmi_sysfs[] = { - /* dmidecode -> 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" }, - { "baseboard-version", "id/board_version" }, - { "baseboard-serial-number", "id/board_serial" }, - { "baseboard-asset-tag", "id/board_asset_tag" }, - { "system-product-name", "id/product_name" }, - { "system-manufacturer", "id/sys_vendor" }, - { "system-serial-number", "id/product_serial" }, - { "system-product-family", "id/product_family" }, - { "system-version", "id/product_version" }, - { "system-uuid", "product_uuid" }, - { "system-sku", "id/product_sku" }, /*dmidecode doesn't actually support this one*/ - { "chassis-type", "id/chassis_type" }, - { "chassis-serial-number", "id/chassis_serial" }, - { "chassis-manufacturer", "id/chassis_vendor" }, - { "chassis-version", "id/chassis_version" }, - { "chassis-asset-tag", "id/chassis_asset_tag" }, - { NULL, NULL } - }; - const gchar *dmi_root = dmi_sysfs_root(); - gchar *ret = NULL; - gchar full_path[PATH_MAX]; - gboolean spawned; - gchar *out, *err; - - int i = 0; - - /* try sysfs first */ - if (dmi_root) { - while (tab_dmi_sysfs[i].id != NULL) { - if (strcmp(id_str, tab_dmi_sysfs[i].id) == 0) { - snprintf(full_path, PATH_MAX, "%s/%s", dmi_root, tab_dmi_sysfs[i].path); - if (g_file_get_contents(full_path, &ret, NULL, NULL) ) - goto dmi_str_done; - } - i++; - } - } - - /* try dmidecode, but may require root */ - snprintf(full_path, PATH_MAX, "dmidecode -s %s", id_str); - spawned = hardinfo_spawn_command_line_sync(full_path, - &out, &err, &i, NULL); - if (spawned) { - if (i == 0) - ret = out; - else - g_free(out); - - g_free(err); - } - -dmi_str_done: - if (ret != NULL) { - ret = strend(ret, '\n'); - ret = g_strstrip(ret); - } - return ret; -} - -char *dmi_chassis_type_str(int chassis_type, gboolean with_val) { - static const char *types[] = { - N_("Invalid chassis type (0)"), - N_("Unknown chassis type"), /* 1 is "Other", but not helpful in HardInfo */ - N_("Unknown chassis type"), - N_("Desktop"), - N_("Low-profile Desktop"), - N_("Pizza Box"), - N_("Mini Tower"), - N_("Tower"), - N_("Portable"), - N_("Laptop"), - N_("Notebook"), - N_("Handheld"), - N_("Docking Station"), - N_("All-in-one"), - N_("Subnotebook"), - N_("Space-saving"), - N_("Lunch Box"), - N_("Main Server Chassis"), - N_("Expansion Chassis"), - N_("Sub Chassis"), - N_("Bus Expansion Chassis"), - N_("Peripheral Chassis"), - 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) { - gchar *chassis = dmi_get_str("chassis-type"); - if (chassis) { - chassis_type = atoi(chassis); - g_free(chassis); - } else - chassis_type = -1; - } - - if (chassis_type >= 0 && chassis_type < (int)G_N_ELEMENTS(types)) { - if (with_val) - return g_strdup_printf("[%d] %s", chassis_type, _(types[chassis_type])); - - return g_strdup(_(types[chassis_type])); - } - return NULL; -} - -/* TODO: something better maybe */ -static char *dd_cache[128] = {}; -void dmidecode_cache_free() -{ int i; for(i = 0; i < 128; i++) g_free(dd_cache[i]); } - -char *dmidecode_read(const dmi_type *type) { - gchar *ret = NULL; - gchar full_path[PATH_MAX]; - gboolean spawned; - gchar *out, *err; - - int i = 0; - - if (type) { - if (dd_cache[*type]) - return g_strdup(dd_cache[*type]); - snprintf(full_path, PATH_MAX, "dmidecode -t %"PRId32, *type); - } else { - if (dd_cache[127]) - return g_strdup(dd_cache[127]); - snprintf(full_path, PATH_MAX, "dmidecode"); - } - - spawned = hardinfo_spawn_command_line_sync(full_path, - &out, &err, &i, NULL); - if (spawned) { - if (i == 0) - ret = out; - else - g_free(out); - - g_free(err); - } - - if (ret) { - if (type) - dd_cache[*type] = g_strdup(ret); - else - dd_cache[127] = g_strdup(ret); - } - - return ret; -} - -dmi_handle_list *dmi_handle_list_add(dmi_handle_list *hl, dmi_handle_ext new_handle_ext) { - if (new_handle_ext.type < G_N_ELEMENTS(dmi_type_strings) ) - new_handle_ext.type_str = dmi_type_strings[new_handle_ext.type]; - if (!hl) { - hl = malloc(sizeof(dmi_handle_list)); - hl->count = 1; - hl->handles = malloc(sizeof(dmi_handle) * hl->count); - hl->handles_ext = malloc(sizeof(dmi_handle_ext) * hl->count); - } else { - hl->count++; - hl->handles = realloc(hl->handles, sizeof(dmi_handle) * hl->count); - hl->handles_ext = realloc(hl->handles_ext, sizeof(dmi_handle_ext) * hl->count); - } - hl->handles_ext[hl->count - 1] = new_handle_ext; - hl->handles[hl->count - 1] = new_handle_ext.id; - - return hl; -} - -dmi_handle_list *dmidecode_handles(const dmi_type *type) { - gchar *full = NULL, *p = NULL, *next_nl = NULL; - dmi_handle_list *hl = NULL; - - // Handle 0x003B, DMI type 9, 17 bytes - - full = dmidecode_read(type); - if (full) { - p = full; - while(next_nl = strchr(p, '\n')) { - unsigned int ch = 0, ct = 0, cb = 0; - strend(p, '\n'); - if (sscanf(p, "Handle 0x%X, DMI type %u, %u bytes", &ch, &ct, &cb) > 0) { - if (type && !ct) ct = *type; - hl = dmi_handle_list_add(hl, (dmi_handle_ext){.id = ch, .type = ct, .size = cb}); - } - p = next_nl + 1; - } - free(full); - } - return hl; -} - -void dmi_handle_list_free(dmi_handle_list *hl) { - if (hl) { - free(hl->handles); - free(hl->handles_ext); - } - free(hl); -} - -char *dmidecode_match(const char *name, const dmi_type *type, const dmi_handle *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(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 dmi_type *type) { - dmi_handle_list *hl = NULL; - gchar *full = NULL, *p = NULL, *next_nl = NULL; - unsigned int ch = 0, ct = 0, cb = 0; - int ln = 0, lnv = 0; - - if (!name) return NULL; - ln = strlen(name); - lnv = (value) ? strlen(value) : 0; - - full = dmidecode_read(type); - if (full) { - p = full; - while(next_nl = strchr(p, '\n')) { - strend(p, '\n'); - if (!(sscanf(p, "Handle 0x%X, DMI type %u, %u bytes", &ch, &ct, &cb) > 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, (dmi_handle_ext){.id = ch, .type = ct, .size = cb}); - } - } - } - p = next_nl + 1; - } - free(full); - } - - return hl; -} diff --git a/hardinfo/dt_util.c b/hardinfo/dt_util.c deleted file mode 100644 index 1f65d9c6..00000000 --- a/hardinfo/dt_util.c +++ /dev/null @@ -1,1187 +0,0 @@ -/* - * HardInfo - Displays System Information - * Copyright (C) 2003-2007 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. - * - * This program 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ -/* - * Device Tree support by Burt P. <pburt0@gmail.com> - * Sources: - * http://elinux.org/Device_Tree_Usage - * http://elinux.org/Device_Tree_Mysteries - */ -#include <unistd.h> -#include <sys/types.h> -#include <inttypes.h> /* for PRIu64 */ -#include <endian.h> -#include "hardinfo.h" -#include "dt_util.h" -#include "appf.h" - -static struct { - char *name; int type; -} prop_types[] = { - { "name", DTP_STR }, - { "compatible", DTP_STR }, - { "model", DTP_STR }, - { "reg", DTP_REG }, - { "clocks", DTP_CLOCKS }, - { "gpios", DTP_GPIOS }, - { "cs-gpios", DTP_GPIOS }, - { "phandle", DTP_PH }, - { "interrupts", DTP_INTRUPT }, - { "interrupts-extended", DTP_INTRUPT_EX }, - { "interrupt-parent", DTP_PH_REF }, - { "interrupt-controller", DTP_EMPTY }, - { "regulator-min-microvolt", DTP_UINT }, - { "regulator-max-microvolt", DTP_UINT }, - { "clock-frequency", DTP_UINT }, - { "dmas", DTP_DMAS }, - { "dma-channels", DTP_UINT }, - { "dma-requests", DTP_UINT }, - - /* operating-points-v2: */ - /* https://www.kernel.org/doc/Documentation/devicetree/bindings/opp/opp.txt */ - { "operating-points-v2", DTP_PH_REF_OPP2 }, - { "opp-hz", DTP_UINT64 }, - { "opp-microvolt", DTP_UINT }, - { "opp-microvolt-L0", DTP_UINT }, /* opp-microvolt-<named>, but this kind of */ - { "opp-microvolt-L1", DTP_UINT }, /* wildcard matching isn't supported yet */ - { "opp-microamp", DTP_UINT }, - { "clock-latency-ns", DTP_UINT }, - - { NULL, 0 }, -}; - -static struct { - char *name; uint32_t v; -} default_values[] = { - { "#address-cells", 2 }, - { "#size-cells", 1 }, - { "#dma-cells", 1 }, - { NULL, 0 }, -}; - -struct _dtr_map { - uint32_t v; /* phandle */ - char *label; /* alias */ - char *path; - struct _dtr_map *next; -}; -typedef struct _dtr_map dtr_map; - -struct _dtr { - dtr_map *aliases; - dtr_map *symbols; - dtr_map *phandles; - char *base_path; - char *log; -}; - -struct _dtr_obj { - char *path; - union { - void *data; - char *data_str; - dt_uint *data_int; - dt_uint64 *data_int64; - }; - char *name; - uint32_t length; - int type; - char *prefix; /* if the name has a manufacturer's prefix or null */ - char *np_name; /* the name without any prefix. points into .prefix or .name, do not free */ - const char *alias; /* null until first dtr_obj_alias(). do not free */ - const char *symbol; /* null until first dtr_obj_symbol(). do not free */ - dtr *dt; -}; - -dtr_map *dtr_map_add(dtr_map *map, uint32_t v, const char *label, const char *path) { - dtr_map *it; - dtr_map *nmap = malloc(sizeof(dtr_map)); - memset(nmap, 0, sizeof(dtr_map)); - nmap->v = v; - - if (label != NULL) nmap->label = strdup(label); - if (path != NULL) nmap->path = strdup(path); - if (map == NULL) - return nmap; - - it = map; - while(it->next != NULL) - it = it->next; - it->next = nmap; - - return nmap; -} - -void dtr_map_free(dtr_map *map) { - dtr_map *it; - while(map != NULL) { - it = map->next; - free(map->label); - free(map->path); - free(map); - map = it; - } -} - -/* simple sort for maps - * sv: 1 = sort by v, 0 = sort by label */ -void dtr_map_sort(dtr_map *map, int sv) -{ - int done = 0, cmp; - dtr_map *this, *next, *top = NULL, *next_top; - uint32_t tmp_v; - char *tmp_l, *tmp_p; - if (map == NULL) return; - do { - this = map; - next_top = NULL; - while(this != NULL) { - next = this->next; - if (this == top) - break; - if (next == NULL) - break; - if (sv) - cmp = (this->v > next->v) ? 1 : 0; - else - cmp = strcmp(this->label, next->label); - if (cmp > 0) { - tmp_v = this->v; this->v = next->v; next->v = tmp_v; - tmp_l = this->label; this->label = next->label; next->label = tmp_l; - tmp_p = this->path; this->path = next->path; next->path = tmp_p; - next_top = this; - } - this = next; - } - if (next_top == NULL) - done = 1; - else - top = next_top; - } while (!done); -} - -const char *dtr_phandle_lookup(dtr *s, uint32_t v) { - dtr_map *phi = s->phandles; - /* 0 and 0xffffffff are invalid phandle values */ - /* TODO: perhaps "INVALID" or something */ - if (v == 0 || v == 0xffffffff) - return NULL; - while(phi != NULL) { - if (phi->v == v) - return phi->path; - phi = phi->next; - } - return NULL; -} - -const char *dtr_alias_lookup(dtr *s, const char* label) { - dtr_map *ali = s->aliases; - while(ali != NULL) { - if (strcmp(ali->label, label) == 0) - return ali->path; - ali = ali->next; - } - return NULL; -} - -const char *dtr_alias_lookup_by_path(dtr *s, const char* path) { - dtr_map *ali = s->aliases; - while(ali != NULL) { - if (strcmp(ali->path, path) == 0) - return ali->label; - ali = ali->next; - } - return NULL; -} - -const char *dtr_symbol_lookup_by_path(dtr *s, const char* path) { - dtr_map *ali = s->symbols; - while(ali != NULL) { - if (strcmp(ali->path, path) == 0) - return ali->label; - ali = ali->next; - } - return NULL; -} - -void _dtr_read_aliases(dtr *); -void _dtr_read_symbols(dtr *); -void _dtr_map_phandles(dtr *, char *np); -int dtr_inh_find(dtr_obj *obj, char *qprop, int limit); -#define UMIN(a,b) MIN(((uint32_t)(a)), ((uint32_t)(b))) - -const char *dtr_find_device_tree_root() { - char *candidates[] = { - "/proc/device-tree", - "/sys/firmware/devicetree/base", - /* others? */ - NULL - }; - int i = 0; - while (candidates[i] != NULL) { - if(access(candidates[i], F_OK) != -1) - return candidates[i]; - i++; - } - return NULL; -} - -dtr *dtr_new_x(const char *base_path, int fast) { - dtr *dt = malloc(sizeof(dtr)); - if (dt != NULL) { - memset(dt, 0, sizeof(dtr)); - dt->log = strdup(""); - - if (base_path == NULL) - base_path = DTR_ROOT; - - if (base_path != NULL) - dt->base_path = strdup(base_path); - else { - dtr_msg(dt, "%s", "Device Tree not found."); - return dt; - } - - /* build alias and phandle lists */ - dt->aliases = NULL; - dt->symbols = NULL; - dt->phandles = NULL; - if (!fast) { - _dtr_read_aliases(dt); - _dtr_read_symbols(dt); - _dtr_map_phandles(dt, ""); - } - } - return dt; -} - -dtr *dtr_new(const char *base_path) { - return dtr_new_x(base_path, 0); -} - -void dtr_free(dtr *s) { - if (s != NULL) { - dtr_map_free(s->aliases); - dtr_map_free(s->symbols); - dtr_map_free(s->phandles); - free(s->base_path); - free(s->log); - free(s); - } -} - -int dtr_was_found(dtr *s) { - if (s != NULL) { - if (s->base_path != NULL) - return 1; - } - return 0; -} - -void dtr_msg(dtr *s, char *fmt, ...) { - gchar *buf, *tmp; - va_list args; - - va_start(args, fmt); - buf = g_strdup_vprintf(fmt, args); - va_end(args); - - tmp = g_strdup_printf("%s%s", s->log, buf); - g_free(s->log); - s->log = tmp; -} - -char *dtr_messages(dtr *s) { - if (s != NULL) - return strdup(s->log); - else - return NULL; -} - -const char *dtr_base_path(dtr *s) { - if (s) - return s->base_path; - return NULL; -} - -/*glib, but _dt_obj *prop uses malloc() and std types */ -dtr_obj *dtr_obj_read(dtr *s, const char *dtp) { - char *full_path; - char *slash, *coma; - dtr_obj *obj; - - if (dtp == NULL) - return NULL; - - obj = malloc(sizeof(dtr_obj)); - if (obj != NULL) { - memset(obj, 0, sizeof(dtr_obj)); - - obj->dt = s; - if (*dtp != '/') { - /* doesn't start with slash, use alias */ - obj->path = (char*)dtr_alias_lookup(s, dtp); - if (obj->path != NULL) - obj->path = strdup(obj->path); - else { - dtr_obj_free(obj); - return NULL; - } - } else - obj->path = strdup(dtp); - - /* find name after last slash, or start */ - slash = strrchr(obj->path, '/'); - if (slash != NULL) - obj->name = strdup(slash + 1); - else - obj->name = strdup(obj->path); - - /* find manufacturer prefix */ - obj->prefix = strdup(obj->name); - coma = strchr(obj->prefix, ','); - if (coma != NULL) { - /* coma -> null; .np_name starts after */ - *coma = 0; - obj->np_name = coma + 1; - } else { - obj->np_name = obj->name; - free(obj->prefix); - obj->prefix = NULL; - } - - /* read data */ - full_path = g_strdup_printf("%s%s", s->base_path, obj->path); - if ( g_file_test(full_path, G_FILE_TEST_IS_DIR) ) { - obj->type = DT_NODE; - } else { - if (!g_file_get_contents(full_path, (gchar**)&obj->data, (gsize*)&obj->length, NULL)) { - dtr_obj_free(obj); - g_free(full_path); - return NULL; - } - obj->type = dtr_guess_type(obj); - } - g_free(full_path); - - return obj; - } - return NULL; -} - -void dtr_obj_free(dtr_obj *s) { - if (s != NULL) { - free(s->path); - free(s->name); - free(s->prefix); - free(s->data); - free(s); - } -} - -int dtr_obj_type(dtr_obj *s) { - if (s) - return s->type; - return DT_TYPE_ERR; -} - -char *dtr_obj_alias(dtr_obj *s) { - if (s) { - if (s->alias == NULL) - s->alias = dtr_alias_lookup_by_path(s->dt, s->path); - return (char*)s->alias; - } - return NULL; -} - -char *dtr_obj_symbol(dtr_obj *s) { - if (s) { - if (s->symbol == NULL) - s->symbol = dtr_symbol_lookup_by_path(s->dt, s->path); - return (char*)s->symbol; - } - return NULL; -} - -char *dtr_obj_path(dtr_obj *s) { - if (s) - return s->path; - return NULL; -} - -char *dtr_obj_full_path(dtr_obj *s) { - if (s) { - if (strcmp(s->path, "/") == 0) - return g_strdup_printf("%s", s->dt->base_path); - else - return g_strdup_printf("%s%s", s->dt->base_path, s->path); - } - return NULL; -} - -dtr_obj *dtr_get_prop_obj(dtr *s, dtr_obj *node, const char *name) { - dtr_obj *prop; - char *ptmp; - ptmp = g_strdup_printf("%s/%s", (node == NULL) ? "" : node->path, name); - prop = dtr_obj_read(s, ptmp); - g_free(ptmp); - return prop; -} - -char *dtr_get_prop_str(dtr *s, dtr_obj *node, const char *name) { - dtr_obj *prop; - char *ptmp; - char *ret = NULL; - - ptmp = g_strdup_printf("%s/%s", (node == NULL) ? "" : node->path, name); - prop = dtr_obj_read(s, ptmp); - if (prop != NULL && prop->data != NULL) { - ret = strdup(prop->data_str); - dtr_obj_free(prop); - } - g_free(ptmp); - return ret; -} - -char *dtr_get_string(const char *p, int decode) { - dtr *dt = dtr_new_x(NULL, 1); - dtr_obj *obj; - char *ret = NULL; - if (decode) { - obj = dtr_get_prop_obj(dt, NULL, p); - ret = dtr_str(obj); - dtr_obj_free(obj); - } else - ret = dtr_get_prop_str(dt, NULL, p); - dtr_free(dt); - return ret; -} - -uint32_t dtr_get_prop_u32(dtr *s, dtr_obj *node, const char *name) { - dtr_obj *prop; - char *ptmp; - uint32_t ret = 0; - - ptmp = g_strdup_printf("%s/%s", (node == NULL) ? "" : node->path, name); - prop = dtr_obj_read(s, ptmp); - if (prop != NULL) { - if (prop->data != NULL) - ret = be32toh(*prop->data_int); - dtr_obj_free(prop); - } - g_free(ptmp); - return ret; -} - -uint64_t dtr_get_prop_u64(dtr *s, dtr_obj *node, const char *name) { - dtr_obj *prop; - char *ptmp; - uint64_t ret = 0; - - ptmp = g_strdup_printf("%s/%s", (node == NULL) ? "" : node->path, name); - prop = dtr_obj_read(s, ptmp); - if (prop != NULL) { - if (prop->data != NULL) - ret = be64toh(*prop->data_int64); - dtr_obj_free(prop); - } - g_free(ptmp); - return ret; -} - -int dtr_guess_type(dtr_obj *obj) { - char *tmp, *dash; - uint32_t i = 0, anc = 0, might_be_str = 1; - - if (obj->length == 0) - return DTP_EMPTY; - - /* special #(.*)-cells names are UINT */ - if (*obj->name == '#') { - dash = strrchr(obj->name, '-'); - if (dash != NULL) { - if (strcmp(dash, "-cells") == 0) - return DTP_UINT; - } - } - - /* /aliases/ * and /__symbols__/ * are always strings */ - if (strncmp(obj->path, "/aliases/", strlen("/aliases/") ) == 0) - return DTP_STR; - if (strncmp(obj->path, "/__symbols__/", strlen("/__symbols__/") ) == 0) - return DTP_STR; - - /* /__overrides__/ * */ - if (strncmp(obj->path, "/__overrides__/", strlen("/__overrides__/") ) == 0) - if (strcmp(obj->name, "name") != 0) - return DTP_OVR; - - /* lookup known type */ - while (prop_types[i].name != NULL) { - if (strcmp(obj->name, prop_types[i].name) == 0) - return prop_types[i].type; - i++; - } - - /* maybe a string? */ - for (i = 0; i < obj->length; i++) { - tmp = obj->data_str + i; - if ( isalnum(*tmp) ) anc++; /* count the alpha-nums */ - if ( isprint(*tmp) || *tmp == 0 ) - continue; - might_be_str = 0; - break; - } - if (might_be_str && - ( anc >= obj->length - 2 /* all alpha-nums but ^/ and \0$ */ - || anc >= 5 ) /*arbitrary*/) - return DTP_STR; - - /* multiple of 4 bytes, try list of hex values */ - if (!(obj->length % 4)) - return DTP_HEX; - - return DTP_UNK; -} - -char *dtr_elem_phref(dtr *s, dt_uint e, int show_path, const char *extra) { - const char *ph_path, *al_label; - char *ret = NULL; - ph_path = dtr_phandle_lookup(s, be32toh(e)); - if (ph_path != NULL) { - /* TODO: alias or symbol? */ - al_label = dtr_symbol_lookup_by_path(s, ph_path); - if (al_label != NULL) { - if (show_path) - ret = g_strdup_printf("&%s (%s) %s", al_label, ph_path, extra ? extra : ""); - else - ret = g_strdup_printf("&%s %s", al_label, extra ? extra : ""); - } else { - if (show_path) - ret = g_strdup_printf("0x%x (%s) %s", be32toh(e), ph_path, extra ? extra : ""); - } - } - if (ret == NULL) - ret = dtr_elem_hex(e); - return ret; -} - -char *dtr_elem_oppv2(dtr_obj* obj) { - char opp_str[512] = ""; - dtr_obj *parent = dtr_get_parent_obj(obj); - if (parent) { - dt_opp_range *opp = dtr_get_opp_range(obj->dt, parent->path); - if (opp) { - snprintf(opp_str, 511, "[%d - %d %s]", opp->khz_min, opp->khz_max, _("kHz")); - g_free(opp); - } - dtr_obj_free(parent); - } - return dtr_elem_phref(obj->dt, *obj->data_int, 1, opp_str); -} - -char *dtr_elem_hex(dt_uint e) { - return g_strdup_printf("0x%x", be32toh(e) ); -} - -char *dtr_elem_byte(uint8_t e) { - return g_strdup_printf("%x", e); -} - -char *dtr_elem_uint(dt_uint e) { - return g_strdup_printf("%u", be32toh(e) ); -} - -char *dtr_elem_uint64(dt_uint64 e) { - return g_strdup_printf("%" PRIu64, be64toh(e) ); -} - -char *dtr_list_byte(uint8_t *bytes, unsigned long count) { - char *ret, *dest; - char buff[4] = ""; /* max element: " 00\0" */ - uint32_t v; - unsigned long i, l; - l = count * 4 + 1; - ret = malloc(l); - memset(ret, 0, l); - strcpy(ret, "["); - dest = ret + 1; - for (i = 0; i < count; i++) { - v = bytes[i]; - l = sprintf(buff, "%s%02x", (i) ? " " : "", v); - strncpy(dest, buff, l); - dest += l; - } - strcpy(dest, "]"); - return ret; -} - -char *dtr_list_hex(dt_uint *list, unsigned long count) { - char *ret, *dest; - char buff[12] = ""; /* max element: " 0x00000000\0" */ - unsigned long i, l; - l = count * 12 + 1; - dest = ret = malloc(l); - memset(ret, 0, l); - for (i = 0; i < count; i++) { - l = sprintf(buff, "%s0x%x", (i) ? " " : "", be32toh(list[i])); - strncpy(dest, buff, l); - dest += l; - } - return ret; -} - -/*cstd, except for g_strescape()*/ -char *dtr_list_str0(const char *data, uint32_t length) { - char *tmp, *esc, *next_str; - char ret[1024] = ""; - uint32_t l, tl; - - /* treat as null-separated string list */ - tl = 0; - strcpy(ret, ""); - tmp = ret; - next_str = (char*)data; - while(next_str != NULL) { - l = strlen(next_str); - esc = g_strescape(next_str, NULL); - sprintf(tmp, "%s\"%s\"", - strlen(ret) ? ", " : "", esc); - free(esc); - tmp += strlen(tmp); - tl += l + 1; next_str += l + 1; - if (tl >= length) break; - } - - return strdup(ret); -} - -char *dtr_list_override(dtr_obj *obj) { - /* <phref, string "property:value"> ... */ - char *ret = NULL; - char *ph, *str; - char *src; - uint32_t consumed = 0; - int l; - src = obj->data_str; - while (consumed + 5 <= obj->length) { - ph = dtr_elem_phref(obj->dt, *(dt_uint*)src, 1, NULL); - src += 4; consumed += 4; - l = strlen(src) + 1; /* consume the null */ - str = dtr_list_str0(src, l); - 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 = appfsp(ret, "%s", str); - free(str); - } - return ret; -} - -uint32_t dtr_get_phref_prop(dtr *s, uint32_t phandle, char *prop) { - const char *ph_path; - char *tmp; - uint32_t ret; - ph_path = dtr_phandle_lookup(s, phandle); - tmp = g_strdup_printf("%s/%s", ph_path, prop); - ret = dtr_get_prop_u32(s, NULL, tmp); - free(tmp); - return ret; -} - -char *dtr_list_phref(dtr_obj *obj, char *ext_cell_prop) { - /* <phref, #XXX-cells> */ - int count = obj->length / 4; - int i = 0, ext_cells = 0; - char *ph, *ext, *ret = NULL; - - while (i < count) { - if (ext_cell_prop == NULL) - ext_cells = 0; - else - ext_cells = dtr_get_phref_prop(obj->dt, be32toh(obj->data_int[i]), 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 = appfsp(ret, "<%s%s%s>", - ph, (ext_cells) ? " " : "", ext); - g_free(ph); - g_free(ext); - } - return ret; -} - -char *dtr_list_interrupts(dtr_obj *obj) { - char *ext, *ret = NULL; - uint32_t iparent, icells; - int count, i = 0; - - iparent = dtr_inh_find(obj, "interrupt-parent", 0); - if (!iparent) { - dtr_msg(obj->dt, "Did not find an interrupt-parent for %s", obj->path); - goto intr_err; - } - icells = dtr_get_phref_prop(obj->dt, iparent, "#interrupt-cells"); - if (!icells) { - dtr_msg(obj->dt, "Invalid #interrupt-cells value %d for %s", icells, obj->path); - goto intr_err; - } - - count = obj->length / 4; - while (i < count) { - icells = UMIN(icells, count - i); - ext = dtr_list_hex((obj->data_int + i), icells); i+=icells; - ret = appfsp(ret, "<%s>", ext); - } - return ret; - -intr_err: - return dtr_list_hex(obj->data_int, obj->length); - -} - -char *dtr_list_reg(dtr_obj *obj) { - char *tup_str, *ret = NULL; - uint32_t acells, scells, tup_len; - uint32_t extra, consumed; /* bytes */ - uint32_t *next; - - acells = dtr_inh_find(obj, "#address-cells", 2); - scells = dtr_inh_find(obj, "#size-cells", 2); - tup_len = acells + scells; - extra = obj->length % (tup_len * 4); - consumed = 0; /* bytes */ - - //printf("list reg: %s\n ... acells: %u, scells: %u, extra: %u\n", obj->path, acells, scells, extra); - - if (extra) { - /* error: length is not a multiple of tuples */ - dtr_msg(obj->dt, "Data length (%u) is not a multiple of (#address-cells:%u + #size-cells:%u) for %s\n", - obj->length, acells, scells, obj->path); - return dtr_list_hex(obj->data, obj->length / 4); - } - - next = obj->data_int; - consumed = 0; - while (consumed + (tup_len * 4) <= obj->length) { - tup_str = dtr_list_hex(next, tup_len); - ret = appfsp(ret, "<%s>", tup_str); - free(tup_str); - consumed += (tup_len * 4); - next += tup_len; - } - - //printf(" ... %s\n", ret); - return ret; -} - -char* dtr_str(dtr_obj *obj) { - char *ret; - int type; - - if (obj == NULL) return NULL; - type = obj->type; - - if (type == DTP_PH_REF) { - if (!DTEX_PHREFS || obj->length != 4) - type = DTP_HEX; - } - - switch(type) { - case DT_NODE: - ret = strdup("{node}"); - break; - case DTP_EMPTY: - ret = strdup("{empty}"); - break; - case DTP_STR: - ret = dtr_list_str0(obj->data_str, obj->length); - break; - case DTP_OVR: - ret = dtr_list_override(obj); - break; - case DTP_REG: - /* <#address-cells #size-cells> */ - ret = dtr_list_reg(obj); - break; - case DTP_INTRUPT: - ret = dtr_list_interrupts(obj); - break; - case DTP_INTRUPT_EX: - /* <phref, #interrupt-cells"> */ - ret = dtr_list_phref(obj, "#interrupt-cells"); - break; - case DTP_CLOCKS: - /* <phref, #clock-cells"> */ - ret = dtr_list_phref(obj, "#clock-cells"); - break; - case DTP_GPIOS: - /* <phref, #gpio-cells"> */ - ret = dtr_list_phref(obj, "#gpio-cells"); - break; - case DTP_DMAS: - /* <phref, #dma-cells"> */ - ret = dtr_list_phref(obj, "#dma-cells"); - break; - case DTP_PH: - case DTP_HEX: - if (obj->length % 4) - ret = dtr_list_byte((uint8_t*)obj->data, obj->length); - else - ret = dtr_list_hex(obj->data, obj->length / 4); - break; - case DTP_PH_REF: - ret = dtr_elem_phref(obj->dt, *obj->data_int, 1, NULL); - break; - case DTP_PH_REF_OPP2: - ret = dtr_elem_oppv2(obj); - break; - case DTP_UINT: - ret = dtr_elem_uint(*obj->data_int); - break; - case DTP_UINT64: - ret = dtr_elem_uint64(*obj->data_int64); - break; - case DTP_UNK: - default: - if (obj->length > 64) /* maybe should use #define at the top */ - ret = g_strdup_printf("{data} (%lu bytes)", (long unsigned int)obj->length); - else - ret = dtr_list_byte((uint8_t*)obj->data, obj->length); - break; - } - - return ret; -} - -dtr_obj *dtr_get_parent_obj(dtr_obj *obj) { - char *slash, *parent; - dtr_obj *ret = NULL; - - if (obj == NULL) - return NULL; - - parent = strdup(obj->path); - slash = strrchr(parent, '/'); - if (slash != NULL) { - *slash = 0; - if (strlen(parent) > 0) - ret = dtr_obj_read(obj->dt, parent); - else - ret = dtr_obj_read(obj->dt, "/"); - } - free(parent); - return ret; -} - -/* find the value of a path-inherited property by climbing the path */ -int dtr_inh_find(dtr_obj *obj, char *qprop, int limit) { - dtr_obj *tobj, *pobj = NULL, *qobj; - uint32_t ret = 0; - int i, found = 0; - - if (!limit) limit = 1000; - - tobj = obj; - while (tobj != NULL) { - pobj = dtr_get_parent_obj(tobj); - if (tobj != obj) - dtr_obj_free(tobj); - if (!limit || pobj == NULL) break; - qobj = dtr_get_prop_obj(obj->dt, pobj, qprop); - if (qobj != NULL) { - ret = be32toh(*qobj->data_int); - found = 1; - dtr_obj_free(qobj); - break; - } - tobj = pobj; - limit--; - } - dtr_obj_free(pobj); - - if (!found) { - i = 0; - while(default_values[i].name != NULL) { - if (strcmp(default_values[i].name, qprop) == 0) { - ret = default_values[i].v; - dtr_msg(obj->dt, "Using default value %d for %s in %s\n", ret, qprop, obj->path); - break; - } - i++; - } - } - - return ret; -} - -dt_opp_range *dtr_get_opp_range(dtr *s, const char *name) { - dt_opp_range *ret = NULL; - dtr_obj *obj = NULL, *table_obj = NULL, *row_obj = NULL; - uint32_t opp_ph = 0; - const char *opp_table_path = NULL; - char *tab_compat = NULL, *tab_status = NULL; - const gchar *fn; - gchar *full_path; - GDir *dir; - uint64_t khz = 0; - uint32_t lns = 0; - char *row_status = NULL; - uint32_t i = 0; - - if (!s) - return NULL; - - obj = dtr_obj_read(s, name); - if (!obj) - goto get_opp_finish; - - opp_ph = dtr_get_prop_u32(s, obj, "operating-points-v2"); /* OPPv2 */ - table_obj = dtr_get_prop_obj(s, obj, "operating-points"); /* OPPv1 */ - if (!opp_ph) { - if (table_obj) { - /* only v1 */ - ret = g_new0(dt_opp_range, 1); - ret->version = 1; - ret->clock_latency_ns = dtr_get_prop_u32(s, obj, "clock-latency"); - - /* pairs of (kHz,uV) */ - for (i = 0; i < table_obj->length; i += 2) { - khz = table_obj->data_int[i]; - if (khz > ret->khz_max) - ret->khz_max = khz; - if (khz < ret->khz_min || ret->khz_min == 0) - ret->khz_min = khz; - } - - } else { - /* is clock-frequency available? */ - khz = dtr_get_prop_u32(s, obj, "clock-frequency"); - if (khz) { - ret = g_new0(dt_opp_range, 1); - ret->version = 0; - ret->khz_max = khz; - ret->clock_latency_ns = dtr_get_prop_u32(s, obj, "clock-latency"); - } - } - goto get_opp_finish; - } else { - /* use v2 if both available */ - dtr_obj_free(table_obj); - table_obj = NULL; - } - - opp_table_path = dtr_phandle_lookup(s, opp_ph); - if (!opp_table_path) - goto get_opp_finish; - - table_obj = dtr_obj_read(s, opp_table_path); - if (!table_obj) - goto get_opp_finish; - - tab_compat = dtr_get_prop_str(s, table_obj, "compatible"); - tab_status = dtr_get_prop_str(s, table_obj, "status"); - - if (!tab_compat || strcmp(tab_compat, "operating-points-v2") != 0) - goto get_opp_finish; - if (tab_status && strcmp(tab_status, "disabled") == 0) - goto get_opp_finish; - - ret = g_new0(dt_opp_range, 1); - ret->version = 2; - ret->phandle = opp_ph; - - full_path = dtr_obj_full_path(table_obj); - dir = g_dir_open(full_path, 0 , NULL); - if (dir) { - while((fn = g_dir_read_name(dir)) != NULL) { - row_obj = dtr_get_prop_obj(s, table_obj, fn); - if (row_obj->type == DT_NODE) { - row_status = dtr_get_prop_str(s, row_obj, "status"); - if (!row_status || strcmp(row_status, "disabled") != 0) { - khz = dtr_get_prop_u64(s, row_obj, "opp-hz"); - khz /= 1000; /* 64b hz -> 32b khz */ - lns = dtr_get_prop_u32(s, row_obj, "clock-latency-ns"); - if (khz > ret->khz_max) - ret->khz_max = khz; - if (khz < ret->khz_min || ret->khz_min == 0) - ret->khz_min = khz; - ret->clock_latency_ns = lns; - } - } - free(row_status); row_status = NULL; - dtr_obj_free(row_obj); - row_obj = NULL; - } - g_dir_close(dir); - } - g_free(full_path); - -get_opp_finish: - dtr_obj_free(obj); - dtr_obj_free(table_obj); - free(tab_status); - free(tab_compat); - free(row_status); - return ret; -} - - -void _dtr_read_aliases(dtr *s) { - gchar *dir_path; - GDir *dir; - const gchar *fn; - dtr_obj *anode, *prop; - dtr_map *al; - anode = dtr_obj_read(s, "/aliases"); - - dir_path = g_strdup_printf("%s/aliases", s->base_path); - dir = g_dir_open(dir_path, 0 , NULL); - if (dir) { - while((fn = g_dir_read_name(dir)) != NULL) { - prop = dtr_get_prop_obj(s, anode, fn); - if (prop->type == DTP_STR) { - if (*prop->data_str == '/') { - al = dtr_map_add(s->aliases, 0, prop->name, prop->data_str); - if (s->aliases == NULL) - s->aliases = al; - } - } - dtr_obj_free(prop); - } - g_dir_close(dir); - } - g_free(dir_path); - dtr_obj_free(anode); - dtr_map_sort(s->aliases, 0); -} - -void _dtr_read_symbols(dtr *s) { - gchar *dir_path; - GDir *dir; - const gchar *fn; - dtr_obj *anode, *prop; - dtr_map *al; - anode = dtr_obj_read(s, "/__symbols__"); - - dir_path = g_strdup_printf("%s/__symbols__", s->base_path); - dir = g_dir_open(dir_path, 0 , NULL); - if (dir) { - while((fn = g_dir_read_name(dir)) != NULL) { - prop = dtr_get_prop_obj(s, anode, fn); - if (prop->type == DTP_STR) { - if (*prop->data_str == '/') { - al = dtr_map_add(s->symbols, 0, prop->name, prop->data_str); - if (s->symbols == NULL) - s->symbols = al; - } - } - dtr_obj_free(prop); - } - g_dir_close(dir); - } - g_free(dir_path); - dtr_obj_free(anode); - dtr_map_sort(s->symbols, 0); -} - -/* TODO: rewrite */ -void _dtr_map_phandles(dtr *s, char *np) { - gchar *dir_path; - gchar *ftmp, *ntmp, *ptmp; - const gchar *fn; - GDir *dir; - dtr_obj *prop, *ph_prop; - dtr_map *ph; - - if (np == NULL) np = ""; - dir_path = g_strdup_printf("%s/%s", s->base_path, np); - - prop = dtr_obj_read(s, np); - dir = g_dir_open(dir_path, 0 , NULL); - if (dir) { - while((fn = g_dir_read_name(dir)) != NULL) { - ftmp = g_strdup_printf("%s/%s", dir_path, fn); - if ( g_file_test(ftmp, G_FILE_TEST_IS_DIR) ) { - ntmp = g_strdup_printf("%s/%s", np, fn); - ptmp = g_strdup_printf("%s/phandle", ntmp); - ph_prop = dtr_obj_read(s, ptmp); - if (ph_prop != NULL) { - ph = dtr_map_add(s->phandles, be32toh(*ph_prop->data_int), NULL, ntmp); - if (s->phandles == NULL) - s->phandles = ph; - } - _dtr_map_phandles(s, ntmp); - g_free(ptmp); - g_free(ntmp); - dtr_obj_free(ph_prop); - } - g_free(ftmp); - } - g_dir_close(dir); - } - dtr_obj_free(prop); - dtr_map_sort(s->phandles, 1); -} - -/* - * Maybe these should move to devicetree.c, but would have to expose - * struct internals. - */ - -/* kvl: 0 = key is label, 1 = key is v */ -char *dtr_map_info_section(dtr *s, dtr_map *map, char *title, int kvl) { - gchar *tmp, *ret; - const gchar *sym; - ret = g_strdup_printf("[%s]\n", _(title)); - dtr_map *it = map; - while(it != NULL) { - if (kvl) { - sym = dtr_symbol_lookup_by_path(s, it->path); - if (sym != NULL) - tmp = g_strdup_printf("%s0x%x (%s)=%s\n", ret, - it->v, sym, it->path); - else - tmp = g_strdup_printf("%s0x%x=%s\n", ret, - it->v, it->path); - } else - tmp = g_strdup_printf("%s%s=%s\n", ret, - it->label, it->path); - g_free(ret); - ret = tmp; - it = it->next; - } - - return ret; -} - -char *dtr_maps_info(dtr *s) { - gchar *ph_map, *al_map, *sy_map, *ret; - - ph_map = dtr_map_info_section(s, s->phandles, _("phandle Map"), 1); - al_map = dtr_map_info_section(s, s->aliases, _("Alias Map"), 0); - sy_map = dtr_map_info_section(s, s->symbols, _("Symbol Map"), 0); - ret = g_strdup_printf("%s%s%s", ph_map, sy_map, al_map); - g_free(ph_map); - g_free(al_map); - g_free(sy_map); - return ret; -} diff --git a/hardinfo/expr.c b/hardinfo/expr.c deleted file mode 100644 index 83e1e02c..00000000 --- a/hardinfo/expr.c +++ /dev/null @@ -1,250 +0,0 @@ -/* - * HardInfo - Displays System Information - * Copyright (C) 2003-2007 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. - * - * This program 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ -/* - * This is only used to compute sensor values, hence the only variable supported is '@'. - * The '`' operator (ln(x)) is not available, nor multi-line formulas. - */ - -#include <glib.h> -#include <string.h> -#include <stdio.h> -#include <ctype.h> -#include <math.h> - -#include "expr.h" -#include "config.h" - -static MathToken *new_operator(gchar op) -{ - MathToken *t = g_new0(MathToken, 1); - - t->val.op = op; - t->type = TOKEN_OPERATOR; /* operator */ - - return t; -} - -static MathToken *new_variable(gchar var) -{ - MathToken *t = g_new0(MathToken, 1); - - t->val.op = '@'; - t->type = TOKEN_VARIABLE; /* variable */ - - return t; -} - -static MathToken *new_value(gfloat value) -{ - MathToken *t = g_new0(MathToken, 1); - - t->val.value = value; - t->type = TOKEN_VALUE; /* value */ - - return t; -} - -static inline gint priority(char operation) -{ - switch (operation) { - case '^': - return 3; - case '*': - case '/': - return 2; - case '+': - case '-': - return 1; - case '(': - return 0; - } - - return 0; -} - -GSList *math_infix_to_postfix(GSList * infix) -{ - MathToken *stack[500]; - gint t_sp = 0; - - GSList *postfix = NULL, *p; - MathToken *top; - - for (p = infix; p; p = p->next) { - MathToken *t = (MathToken *) p->data; - - if (t->type == TOKEN_OPERATOR && t->val.op == '(') { - stack[++t_sp] = t; - } else if (t->type == TOKEN_OPERATOR && t->val.op == ')') { - for (top = stack[t_sp]; t_sp != 0 && top->val.op != '('; - top = stack[t_sp]) { - postfix = g_slist_append(postfix, stack[t_sp--]); - } - t_sp--; - } else if (t->type != TOKEN_OPERATOR) { - postfix = g_slist_append(postfix, t); - } else if (t_sp == 0) { - stack[++t_sp] = t; - } else { - while (t_sp != 0 - && priority(t->val.op) <= priority(stack[t_sp]->val.op)) - postfix = g_slist_append(postfix, stack[t_sp--]); - stack[++t_sp] = t; - } - } - - while (t_sp) - postfix = g_slist_append(postfix, stack[t_sp--]); - - return postfix; -} - -static inline gfloat __result(gfloat op1, gfloat op2, gchar operation) -{ - switch (operation) { - case '^': - return powf(op1, op2); - case '+': - return op1 + op2; - case '-': - return op1 - op2; - case '/': - return op1 / op2; - case '*': - return op1 * op2; - } - - return 0; -} - -gfloat math_postfix_eval(GSList * postfix, gfloat at_value) -{ - GSList *p; - gfloat stack[500]; - gint sp = 0; - - memset(stack, 0, sizeof(gfloat) * 500); - - for (p = postfix; p; p = p->next) { - MathToken *t = (MathToken *) p->data; - - if (t->type == TOKEN_VARIABLE) { - stack[++sp] = at_value; - } else if (t->type == TOKEN_VALUE) { - stack[++sp] = t->val.value; - } else { - gfloat op1, op2; - - op2 = stack[sp--]; - op1 = stack[sp]; - - stack[sp] = __result(op1, op2, t->val.op); - } - } - - return stack[sp]; -} - -GSList *math_string_to_infix(gchar * string) -{ - GSList *infix = NULL; - gchar *expr = string; - - for (; *expr; expr++) { - if (strchr("+-/*^()", *expr)) { - infix = g_slist_append(infix, new_operator(*expr)); - } else if (strchr("@", *expr)) { - infix = g_slist_append(infix, new_variable(*expr)); - } else if (strchr("-.1234567890", *expr)) { - gchar value[32], *v = value; - gfloat floatval; - - do { - *v++ = *expr++; - } while (*expr && strchr("-.1234567890", *expr)); - expr--; - *v = '\0'; - - sscanf(value, "%f", &floatval); - - infix = g_slist_append(infix, new_value(floatval)); - } else if (!isspace(*expr)) { - g_print("Invalid token: [%c][%d]\n", *expr, *expr); - math_infix_free(infix, TRUE); - return NULL; - } - } - - return infix; -} - -void math_infix_free(GSList * infix, gboolean free_tokens) -{ - GSList *p; - - if (!free_tokens) - for (p = infix; p; p = g_slist_delete_link(p, p)); - else - for (p = infix; p; p = g_slist_delete_link(p, p)) { - MathToken *t = (MathToken *) p->data; - g_free(t); - } -} - -GSList *math_string_to_postfix(gchar * string) -{ - GSList *infix; - GSList *postfix; - - infix = math_string_to_infix(string); - if (!infix) - return NULL; - - postfix = math_infix_to_postfix(infix); - math_infix_free(infix, FALSE); - - return postfix; -} - -gfloat math_string_eval(gchar * string, gfloat at_value) -{ - GSList *postfix; - gfloat val; - - postfix = math_string_to_postfix(string); - val = math_postfix_eval(postfix, at_value); - math_postfix_free(postfix, TRUE); - - return val; -} - -#ifdef MATH_TEST -int main(void) -{ - GSList *postfix; - - gchar *expr = "0.9*(@+(5.2*0.923+3*(2.0)))"; - - postfix = math_string_to_postfix(expr); - g_print("%s = %f (must be 18.71964)\n", expr, - math_postfix_eval(postfix, 10)); - math_postfix_free(postfix, TRUE); - - return 0; -} -#endif diff --git a/hardinfo/gg_key_file_parse_string_as_value.c b/hardinfo/gg_key_file_parse_string_as_value.c deleted file mode 100644 index 7e871bc1..00000000 --- a/hardinfo/gg_key_file_parse_string_as_value.c +++ /dev/null @@ -1,111 +0,0 @@ -/* 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/>. - */ - -#include <glib.h> - -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/gg_strescape.c b/hardinfo/gg_strescape.c deleted file mode 100644 index ada9cf89..00000000 --- a/hardinfo/gg_strescape.c +++ /dev/null @@ -1,138 +0,0 @@ -/* Base on: GLIB - Library of useful routines for C programming - * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald - * - * 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 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, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -#include <glib.h> - -guchar excmap_def[256] = {1,0}; -static void make_excmap_def() { - int i; - for(i=0; i<256; i++){ - switch ((guchar)i) - { - case '\b': - case '\f': - case '\n': - case '\r': - case '\t': - case '\\': - case '"': - excmap_def[i] = 0; - break; - default: - if ((i < ' ') || (i >= 0177)) - excmap_def[i] = 0; - else - excmap_def[i] = 1; - break; - } - } -} - -gchar * -gg_strescape (const gchar *source, - const gchar *exceptions, - const gchar *extra) -{ - const guchar *p; - gchar *dest; - gchar *q; - guchar excmap[256]; - - g_return_val_if_fail (source != NULL, NULL); - - if (excmap_def[0]) /* [0] should be 0 or it isn't initialized */ - make_excmap_def(); - - memcpy(excmap, excmap_def, 256); - - p = (guchar *) source; - /* Each source byte needs maximally four destination chars (\777) */ - q = dest = g_malloc (strlen (source) * 4 + 1); - - if (exceptions) - { - guchar *e = (guchar *) exceptions; - - while (*e) - { - excmap[*e] = 1; - e++; - } - } - - if (extra) - { - guchar *e = (guchar *) extra; - - while (*e) - { - excmap[*e] = 0; - e++; - } - } - - while (*p) - { - if (excmap[*p]) - *q++ = *p; - else - { - switch (*p) - { - case '\b': - *q++ = '\\'; - *q++ = 'b'; - break; - case '\f': - *q++ = '\\'; - *q++ = 'f'; - break; - case '\n': - *q++ = '\\'; - *q++ = 'n'; - break; - case '\r': - *q++ = '\\'; - *q++ = 'r'; - break; - case '\t': - *q++ = '\\'; - *q++ = 't'; - break; - case '\\': - *q++ = '\\'; - *q++ = '\\'; - break; - case '"': - *q++ = '\\'; - *q++ = '"'; - break; - default: - *q++ = '\\'; - *q++ = '0' + (((*p) >> 6) & 07); - *q++ = '0' + (((*p) >> 3) & 07); - *q++ = '0' + ((*p) & 07); - break; - } - } - p++; - } - *q = 0; - return dest; -} diff --git a/hardinfo/gpu_util.c b/hardinfo/gpu_util.c deleted file mode 100644 index 29f6c77e..00000000 --- a/hardinfo/gpu_util.c +++ /dev/null @@ -1,477 +0,0 @@ -/* - * HardInfo - Displays System Information - * Copyright (C) 2003-2017 L. A. F. Pereira <l@tia.mat.br> - * This file - * Copyright (C) 2018 Burt P. <pburt0@gmail.com> - * - * 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. - * - * This program 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "hardinfo.h" -#include "gpu_util.h" -#include "nice_name.h" -#include "cpu_util.h" /* for EMPIFNULL() */ - -nvgpu *nvgpu_new() { - return g_new0(nvgpu, 1); -} - -void nvgpu_free(nvgpu *s) { - if (s) { - free(s->model); - free(s->bios_version); - free(s->uuid); - } -} - -static char *_line_value(char *line, const char *prefix) { - if (g_str_has_prefix(g_strstrip(line), prefix)) { - line += strlen(prefix) + 1; - return g_strstrip(line); - } else - return NULL; -} - -static gboolean nv_fill_procfs_info(gpud *s) { - gchar *data, *p, *l, *next_nl; - gchar *pci_loc = pci_address_str(s->pci_dev->domain, s->pci_dev->bus, s->pci_dev->device, s->pci_dev->function); - gchar *nvi_file = g_strdup_printf("/proc/driver/nvidia/gpus/%s/information", pci_loc); - - g_file_get_contents(nvi_file, &data, NULL, NULL); - g_free(pci_loc); - g_free(nvi_file); - - if (data) { - s->nv_info = nvgpu_new(); - p = data; - while(next_nl = strchr(p, '\n')) { - strend(p, '\n'); - g_strstrip(p); - if (l = _line_value(p, "Model")) { - s->nv_info->model = g_strdup(l); - goto nv_details_next; - } - if (l = _line_value(p, "GPU UUID")) { - s->nv_info->uuid = g_strdup(l); - goto nv_details_next; - } - if (l = _line_value(p, "Video BIOS")) { - s->nv_info->bios_version = g_strdup(l); - goto nv_details_next; - } - - /* TODO: more details */ - - nv_details_next: - p = next_nl + 1; - } - g_free(data); - return TRUE; - } - return FALSE; -} - -static void intel_fill_freq(gpud *s) { - gchar path[256] = ""; - gchar *min_mhz = NULL, *max_mhz = NULL; - if (s->sysfs_drm_path) { - snprintf(path, 255, "%s/%s/gt_min_freq_mhz", s->sysfs_drm_path, s->id); - g_file_get_contents(path, &min_mhz, NULL, NULL); - snprintf(path, 255, "%s/%s/gt_max_freq_mhz", s->sysfs_drm_path, s->id); - g_file_get_contents(path, &max_mhz, NULL, NULL); - - if (min_mhz) - s->khz_min = atoi(min_mhz) * 1000; - if (max_mhz) - s->khz_max = atoi(max_mhz) * 1000; - - g_free(min_mhz); - g_free(max_mhz); - } -} - -static void amdgpu_parse_dpmclk(gchar *path, int *min, int *max) { - gchar *data = NULL, *p, *next_nl; - int sp, i, clk; - - *min = -1; - *max = -1; - - g_file_get_contents(path, &data, NULL, NULL); - if (data) { - p = data; - - while(next_nl = strchr(p, '\n')) { - strend(p, '\n'); - sp = sscanf(p, "%d: %dMhz", &i, &clk); - - if (sp == 2) { - if (clk > 0) { - if (*min < 0 || clk < *min) - *min = clk; - if (clk > *max) - *max = clk; - } - } - - p = next_nl + 1; - } - } - g_free(data); -} - -static void amdgpu_fill_freq(gpud *s) { - gchar path[256] = ""; - int clk_min = -1, clk_max = -1, mem_clk_min = -1, mem_clk_max = -1; - - if (s->sysfs_drm_path) { - /* core */ - snprintf(path, 255, "%s/%s/device/pp_dpm_sclk", s->sysfs_drm_path, s->id); - amdgpu_parse_dpmclk(path, &clk_min, &clk_max); - - if (clk_max > 0) - s->khz_max = clk_max * 1000; - if (clk_min > 0) - s->khz_min = clk_min * 1000; - - /* memory */ - snprintf(path, 255, "%s/%s/device/pp_dpm_mclk", s->sysfs_drm_path, s->id); - amdgpu_parse_dpmclk(path, &mem_clk_min, &mem_clk_max); - - if (mem_clk_max > 0) - s->mem_khz_max = mem_clk_max * 1000; - if (mem_clk_min > 0) - s->mem_khz_min = mem_clk_min * 1000; - } -} - -gpud *gpud_new() { - return g_new0(gpud, 1); -} - -void gpud_free(gpud *s) { - if (s) { - free(s->id); - free(s->nice_name); - free(s->vendor_str); - free(s->device_str); - free(s->location); - free(s->drm_dev); - free(s->sysfs_drm_path); - free(s->dt_compat); - g_free(s->dt_opp); - pcid_free(s->pci_dev); - nvgpu_free(s->nv_info); - g_free(s); - } -} - -void gpud_list_free(gpud *s) { - gpud *n; - while(s != NULL) { - n = s->next; - gpud_free(s); - s = n; - } -} - -/* returns number of items after append */ -static int gpud_list_append(gpud *l, gpud *n) { - int c = 0; - while(l != NULL) { - c++; - if (l->next == NULL) { - if (n != NULL) { - l->next = n; - c++; - } - break; - } - l = l->next; - } - return c; -} - -int gpud_list_count(gpud *s) { - return gpud_list_append(s, NULL); -} - -/* TODO: In the future, when there is more vendor specific information available in - * the gpu struct, then more precise names can be given to each gpu */ -static void make_nice_name(gpud *s) { - - /* NV information available */ - if (s->nv_info && s->nv_info->model) { - s->nice_name = g_strdup_printf("%s %s", "NVIDIA", s->nv_info->model); - return; - } - - static const char unk_v[] = "Unknown"; /* do not... */ - static const char unk_d[] = "Device"; /* ...translate */ - const char *vendor_str = s->vendor_str; - const char *device_str = s->device_str; - if (!vendor_str) - vendor_str = unk_v; - if (!device_str) - device_str = unk_d; - - /* try and a get a "short name" for the vendor */ - vendor_str = vendor_get_shortest_name(vendor_str); - - 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); - /* Try and shorten it to the chip code name only, at least */ - char *b = strchr(full_name, '['); - if (b) *b = '\0'; - s->nice_name = g_strdup_printf("%s %s", "AMD/ATI", g_strstrip(full_name)); - free(full_name); - } else { - /* nothing nicer */ - s->nice_name = g_strdup_printf("%s %s", vendor_str, device_str); - } - -} - -/* Look for this kind of thing: - * * /soc/gpu - * * /gpu@ff300000 - * - * Usually a gpu dt node will have ./name = "gpu" - */ -static gchar *dt_find_gpu(dtr *dt, char *np) { - gchar *dir_path, *dt_path, *ret; - gchar *ftmp, *ntmp; - const gchar *fn; - GDir *dir; - dtr_obj *obj; - - /* consider self */ - obj = dtr_obj_read(dt, np); - dt_path = dtr_obj_path(obj); - ntmp = strstr(dt_path, "/gpu"); - if (ntmp) { - /* was found in node name */ - if ( strchr(ntmp+1, '/') == NULL) { - ftmp = ntmp + 4; - /* should either be NULL or @ */ - if (*ftmp == '\0' || *ftmp == '@') - return g_strdup(dt_path); - } - } - - /* search children ... */ - dir_path = g_strdup_printf("%s/%s", dtr_base_path(dt), np); - dir = g_dir_open(dir_path, 0 , NULL); - if (dir) { - while((fn = g_dir_read_name(dir)) != NULL) { - ftmp = g_strdup_printf("%s/%s", dir_path, fn); - if ( g_file_test(ftmp, G_FILE_TEST_IS_DIR) ) { - if (strcmp(np, "/") == 0) - ntmp = g_strdup_printf("/%s", fn); - else - ntmp = g_strdup_printf("%s/%s", np, fn); - ret = dt_find_gpu(dt, ntmp); - g_free(ntmp); - if (ret != NULL) { - g_free(ftmp); - g_dir_close(dir); - return ret; - } - } - g_free(ftmp); - } - g_dir_close(dir); - } - - return NULL; -} - -gpud *dt_soc_gpu() { - static const char std_soc_gpu_drm_path[] = "/sys/devices/platform/soc/soc:gpu/drm"; - - /* compatible contains a list of compatible hardware, so be careful - * with matching order. - * ex: "ti,omap3-beagleboard-xm", "ti,omap3450", "ti,omap3"; - * matches "omap3 family" first. - * ex: "brcm,bcm2837", "brcm,bcm2836"; - * would match 2836 when it is a 2837. - */ - const struct { - char *search_str; - char *vendor; - char *soc; - } dt_compat_searches[] = { - { "brcm,bcm2837-vc4", "Broadcom", "VideoCore IV" }, - { "brcm,bcm2836-vc4", "Broadcom", "VideoCore IV" }, - { "brcm,bcm2835-vc4", "Broadcom", "VideoCore IV" }, - { "arm,mali-450", "ARM", "Mali 450" }, - { "arm,mali", "ARM", "Mali family" }, - { NULL, NULL, NULL } - }; - char tmp_path[256] = ""; - char *dt_gpu_path = NULL; - char *compat = NULL; - char *vendor = NULL, *device = NULL; - int i; - - gpud *gpu = NULL; - - dtr *dt = dtr_new(NULL); - if (!dtr_was_found(dt)) - goto dt_gpu_end; - - dt_gpu_path = dt_find_gpu(dt, "/"); - - if (dt_gpu_path == NULL) - goto dt_gpu_end; - - snprintf(tmp_path, 255, "%s/compatible", dt_gpu_path); - compat = dtr_get_string(tmp_path, 1); - - if (compat == NULL) - goto dt_gpu_end; - - gpu = gpud_new(); - - i = 0; - while(dt_compat_searches[i].search_str != NULL) { - if (strstr(compat, dt_compat_searches[i].search_str) != NULL) { - vendor = dt_compat_searches[i].vendor; - device = dt_compat_searches[i].soc; - break; - } - i++; - } - - gpu->dt_compat = compat; - gpu->dt_vendor = vendor; - gpu->dt_device = device; - gpu->dt_path = dt_gpu_path; - snprintf(tmp_path, 255, "%s/status", dt_gpu_path); - gpu->dt_status = dtr_get_string(tmp_path, 1); - snprintf(tmp_path, 255, "%s/name", dt_gpu_path); - gpu->dt_name = dtr_get_string(tmp_path, 1); - gpu->dt_opp = dtr_get_opp_range(dt, dt_gpu_path); - if (gpu->dt_opp) { - gpu->khz_max = gpu->dt_opp->khz_max; - gpu->khz_min = gpu->dt_opp->khz_min; - } - EMPIFNULL(gpu->dt_name); - EMPIFNULL(gpu->dt_status); - - gpu->id = strdup("dt-soc-gpu"); - gpu->location = strdup("SOC"); - - if (access(std_soc_gpu_drm_path, F_OK) != -1) - gpu->sysfs_drm_path = strdup(std_soc_gpu_drm_path); - if (vendor) gpu->vendor_str = strdup(vendor); - if (device) gpu->device_str = strdup(device); - make_nice_name(gpu); - - -dt_gpu_end: - dtr_free(dt); - return gpu; -} - -gpud *gpu_get_device_list() { - int cn = 0; - gpud *list = NULL; - -/* Can we just ask DRM someway? ... */ - /* TODO: yes. /sys/class/drm/card* */ - -/* Try PCI ... */ - pcid_list pci_list = pci_get_device_list(0x300,0x3ff); - GSList *l = pci_list; - - if (l) { - while(l) { - pcid *curr = (pcid*)l->data; - char *pci_loc = NULL; - gpud *new_gpu = gpud_new(); - new_gpu->pci_dev = curr; - - pci_loc = pci_address_str(curr->domain, curr->bus, curr->device, curr->function); - - int len; - char drm_id[512] = "", card_id[64] = ""; - char *drm_dev = NULL; - gchar *drm_path = - g_strdup_printf("/dev/dri/by-path/pci-%s-card", pci_loc); - memset(drm_id, 0, 512); - if ((len = readlink(drm_path, drm_id, sizeof(drm_id)-1)) != -1) - drm_id[len] = '\0'; - g_free(drm_path); - - if (strlen(drm_id) != 0) { - /* drm has the card */ - drm_dev = strstr(drm_id, "card"); - if (drm_dev) - snprintf(card_id, 64, "%s", drm_dev); - } - - if (strlen(card_id) == 0) { - /* fallback to our own counter */ - snprintf(card_id, 64, "pci-dc%d", cn); - cn++; - } - - if (drm_dev) - new_gpu->drm_dev = strdup(drm_dev); - - char *sysfs_path_candidate = g_strdup_printf("%s/%s/drm", SYSFS_PCI_ROOT, pci_loc); - if (access(sysfs_path_candidate, F_OK) != -1) { - new_gpu->sysfs_drm_path = sysfs_path_candidate; - } else - free(sysfs_path_candidate); - new_gpu->location = g_strdup_printf("PCI/%s", pci_loc); - new_gpu->id = strdup(card_id); - if (curr->vendor_id_str) new_gpu->vendor_str = strdup(curr->vendor_id_str); - if (curr->device_id_str) new_gpu->device_str = strdup(curr->device_id_str); - nv_fill_procfs_info(new_gpu); - intel_fill_freq(new_gpu); - amdgpu_fill_freq(new_gpu); - make_nice_name(new_gpu); - if (list == NULL) - list = new_gpu; - else - gpud_list_append(list, new_gpu); - - free(pci_loc); - l=l->next; - } - - /* don't pcid_list_free(pci_list); They will be freed by gpud_free() */ - g_slist_free(pci_list); /* just the linking data */ - return list; - } - -/* Try Device Tree ... */ - list = dt_soc_gpu(); - if (list) return list; - -/* Try other things ... */ - - return list; -} - - diff --git a/hardinfo/hardinfo.c b/hardinfo/hardinfo.c deleted file mode 100644 index 1488e0a1..00000000 --- a/hardinfo/hardinfo.c +++ /dev/null @@ -1,169 +0,0 @@ -/* - * HardInfo - Displays System Information - * Copyright (C) 2003-2009 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. - * - * This program 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include <config.h> -#include <shell.h> - -#include <report.h> -#include <hardinfo.h> -#include <iconcache.h> -#include <stock.h> -#include <vendor.h> - -#include <binreloc.h> - -ProgramParameters params = { 0 }; - -int main(int argc, char **argv) -{ - int exit_code = 0; - GSList *modules; - - setlocale(LC_ALL, ""); - bindtextdomain("hardinfo", LOCALEDIR); - textdomain("hardinfo"); - - DEBUG("HardInfo version " VERSION ". Debug version."); - - /* parse all command line parameters */ - parameters_init(&argc, &argv, ¶ms); - - /* show version information and quit */ - if (params.show_version) { - g_print("HardInfo version " VERSION "\n"); - g_print - (_(/*/ %d will be latest year of copyright*/ "Copyright (C) 2003-%d L. A. F. Pereira. See COPYING for details.\n\n"), HARDINFO_COPYRIGHT_LATEST_YEAR ); - - g_print(_("Compile-time options:\n" - " Release version: %s (%s)\n" - " BinReloc enabled: %s\n" - " Data prefix: %s\n" - " Library prefix: %s\n" - " Compiled for: %s\n"), - RELEASE ? _("Yes") : "No (" VERSION ")", ARCH, - ENABLE_BINRELOC ? _("Yes") : _("No"), - PREFIX, LIBPREFIX, PLATFORM); - - DEBUG(" Debugging is enabled."); - - /* show also available modules */ - params.list_modules = TRUE; - } - - /* initialize the binreloc library, so we can load program data */ - if (!binreloc_init(FALSE)) - g_error(_("Failed to find runtime data.\n\n" - "\342\200\242 Is HardInfo correctly installed?\n" - "\342\200\242 See if %s and %s exists and you have read permission."), - PREFIX, LIBPREFIX); - - /* list all module names */ - if (params.list_modules) { - g_print(_("Modules:\n" - "%-20s %-15s %-12s\n"), _("File Name"), _("Name"), _("Version")); - - for (modules = modules_load_all(); modules; - modules = modules->next) { - ShellModule *module = (ShellModule *) modules->data; - const ModuleAbout *ma = module_get_about(module); - gchar *name = g_path_get_basename(g_module_name(module->dll)); - - g_print("%-20s %-15s %-12s\n", name, module->name, ma->version); - - g_free(name); - } - - return 0; - } - - if (!params.create_report && !params.run_benchmark) { - /* we only try to open the UI if the user didn't ask for a report. */ - params.gui_running = ui_init(&argc, &argv); - - /* as a fallback, if GTK+ initialization failed, run in report - generation mode. */ - if (!params.gui_running) { - params.create_report = TRUE; - /* ... it is possible to -f html without -r */ - if (params.report_format != REPORT_FORMAT_HTML) - params.markup_ok = FALSE; - } - } - - if (params.use_modules) { - /* load only selected modules */ - DEBUG("loading user-selected modules"); - modules = modules_load_selected(); - } else { - /* load all modules */ - DEBUG("loading all modules"); - modules = modules_load_all(); - } - - /* initialize vendor database */ - vendor_init(); - - /* initialize moreinfo */ - moreinfo_init(); - - if (params.run_benchmark) { - gchar *result; - - result = module_call_method_param("benchmark::runBenchmark", params.run_benchmark); - if (!result) { - fprintf(stderr, _("Unknown benchmark ``%s'' or benchmark.so not loaded"), params.run_benchmark); - exit_code = 1; - } else { - fprintf(stderr, "\n"); - g_print("%s\n", result); - g_free(result); - } - } else if (params.gui_running) { - /* initialize gui and start gtk+ main loop */ - icon_cache_init(); - stock_icons_init(); - - shell_init(modules); - - DEBUG("entering gtk+ main loop"); - - gtk_main(); - } else if (params.create_report) { - /* generate report */ - gchar *report; - - DEBUG("generating report"); - - report = report_create_from_module_list_format(modules, - params. - report_format); - g_print("%s", report); - - g_free(report); - } else { - g_error(_("Don't know what to do. Exiting.")); - } - - moreinfo_shutdown(); - vendor_cleanup(); - dmidecode_cache_free(); - free_auto_free_final(); - - DEBUG("finished"); - return exit_code; -} diff --git a/hardinfo/hinote_util.c b/hardinfo/hinote_util.c deleted file mode 100644 index efc85be0..00000000 --- a/hardinfo/hinote_util.c +++ /dev/null @@ -1,27 +0,0 @@ - -#include "hardinfo.h" - -/* requires COMPILE_FLAGS "-std=c99" */ - -static const char bullet_yes[] = "<big><b>\u2713</b></big>"; -static const char bullet_no[] = "<big><b>\u2022<tt> </tt></b></big>"; -static const char bullet_yes_text[] = "[X]"; -static const char bullet_no_text[] = "[ ]"; - -gboolean note_cond_bullet(gboolean cond, gchar *note_buff, const gchar *desc_str) { - int l = strlen(note_buff); - if (params.markup_ok) - snprintf(note_buff + l, note_max_len - l - 1, "%s %s\n", - cond ? bullet_yes : bullet_no, desc_str); - else - snprintf(note_buff + l, note_max_len - l - 1, "%s %s\n", - cond ? bullet_yes_text : bullet_no_text, desc_str); - return cond; -} - -gboolean note_require_tool(const gchar *tool, gchar *note_buff, const gchar *desc_str) { - gchar *tl = find_program((gchar*)tool); - gboolean found = note_cond_bullet(!!tl, note_buff, desc_str); - g_free(tl); - return found; -} diff --git a/hardinfo/info.c b/hardinfo/info.c deleted file mode 100644 index 5e6db7e4..00000000 --- a/hardinfo/info.c +++ /dev/null @@ -1,584 +0,0 @@ -/* - * HardInfo - Displays System Information - * Copyright (C) 2017 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. - * - * This program 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#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. */ -/* Now in hardinfo.h -- #include "gg_key_file_parse_string_as_value.c" */ - -static const gchar *info_column_titles[] = { - "TextValue", "Value", "Progress", "Extra1", "Extra2" -}; - -struct Info *info_new(void) -{ - struct Info *info = g_new0(struct Info, 1); - - info->groups = g_array_new(FALSE, FALSE, sizeof(struct InfoGroup)); - info->view_type = SHELL_VIEW_NORMAL; - info->column_headers_visible = FALSE; - info->zebra_visible = FALSE; - info->normalize_percentage = TRUE; - - return info; -} - -void info_group_add_field(struct InfoGroup *group, struct InfoField field) -{ - if (!group) - return; - - /* info_field_last() */ - if (!field.name) - return; - - g_array_append_val(group->fields, field); -} - -void info_group_add_fieldsv(struct InfoGroup *group, va_list ap) -{ - while (1) { - struct InfoField field = va_arg(ap, struct InfoField); - - /* info_field_last() */ - if (!field.name) - break; - - g_array_append_val(group->fields, field); - } -} - -void info_group_add_fields(struct InfoGroup *group, ...) -{ - va_list ap; - - va_start(ap, group); - info_group_add_fieldsv(group, ap); - va_end(ap); -} - -struct InfoGroup *info_add_group(struct Info *info, const gchar *group_name, ...) -{ - struct InfoGroup group = { - .name = group_name, - .fields = g_array_new(FALSE, FALSE, sizeof(struct InfoField)) - }; - va_list ap; - - va_start(ap, group_name); - info_group_add_fieldsv(&group, ap); - va_end(ap); - - g_array_append_val(info->groups, group); - - return &g_array_index(info->groups, struct InfoGroup, info->groups->len - 1); -} - -struct InfoField info_field_printf(const gchar *name, const gchar *format, ...) -{ - gchar *value; - va_list ap; - - va_start(ap, format); - value = g_strdup_vprintf(format, ap); - va_end(ap); - - return (struct InfoField) { - .name = name, - .value = value, - .free_value_on_flatten = TRUE, - }; -} - -void info_group_strip_extra(struct InfoGroup *group) -{ - guint fi; - char *val, *oldval; - struct InfoField *field; - - for (fi = 0; fi < group->fields->len; fi++) { - field = &g_array_index(group->fields, struct InfoField, fi); - if (field->value){ - val = strrchr(field->value, '|'); - if (val) { - oldval = (gchar*)field->value; - field->value = strdup(val + 1); - g_free(oldval); - } - } - } -} - -void info_add_computed_group(struct Info *info, const gchar *name, const gchar *value) -{ - /* This is a scaffolding method: HardInfo should move away from pre-computing - * the strings in favor of storing InfoGroups instead; while modules are not - * fully converted, use this instead. */ - struct Info *tmp_info = NULL; - struct InfoGroup donor = {}; - gchar *tmp_str = NULL; - - if (name) - tmp_str = g_strdup_printf("[%s]\n%s", name, value); - else - tmp_str = g_strdup(value); - - tmp_info = info_unflatten(tmp_str); - if (tmp_info->groups->len != 1) { - fprintf(stderr, - "info_add_computed_group(): expected only one group in value! (actual: %d)\n", - tmp_info->groups->len); - } else { - donor = g_array_index(tmp_info->groups, struct InfoGroup, 0); - g_array_append_val(info->groups, donor); - } - - g_free(tmp_info); // TODO: doesn't do enough - g_free(tmp_str); -} - -void info_add_computed_group_wo_extra(struct Info *info, const gchar *name, const gchar *value) -{ - /* This is a scaffolding method: HardInfo should move away from pre-computing - * the strings in favor of storing InfoGroups instead; while modules are not - * fully converted, use this instead. */ - struct InfoGroup *agroup; - - info_add_computed_group(info, name, value); - if (info->groups->len > 0) { - agroup = &g_array_index(info->groups, struct InfoGroup, info->groups->len - 1); - info_group_strip_extra(agroup); - } -} - -void info_set_column_title(struct Info *info, const gchar *column, const gchar *title) -{ - int i; - - for (i = 0; i < G_N_ELEMENTS(info_column_titles); i++) { - if (g_str_equal(info_column_titles[i], column)) { - info->column_titles[i] = title; - return; - } - } -} - -void info_set_column_headers_visible(struct Info *info, gboolean setting) -{ - info->column_headers_visible = setting; -} - -void info_set_zebra_visible(struct Info *info, gboolean setting) -{ - info->zebra_visible = setting; -} - -void info_set_normalize_percentage(struct Info *info, gboolean setting) -{ - info->normalize_percentage = setting; -} - -void info_set_view_type(struct Info *info, ShellViewType setting) -{ - info->view_type = setting; -} - -void info_set_reload_interval(struct Info *info, int setting) -{ - info->reload_interval = setting; -} - -static int info_field_cmp_name_ascending(const void *a, const void *b) -{ - const struct InfoField *aa = a, *bb = b; - return g_strcmp0(aa->name, bb->name); -} - -static int info_field_cmp_name_descending(const void *a, const void *b) -{ - const struct InfoField *aa = a, *bb = b; - return g_strcmp0(bb->name, aa->name); -} - -static int info_field_cmp_value_ascending(const void *a, const void *b) -{ - const struct InfoField *aa = a, *bb = b; - return g_strcmp0(aa->value, bb->value); -} - -static int info_field_cmp_value_descending(const void *a, const void *b) -{ - const struct InfoField *aa = a, *bb = b; - return g_strcmp0(bb->value, aa->value); -} - -static int info_field_cmp_tag_ascending(const void *a, const void *b) -{ - const struct InfoField *aa = a, *bb = b; - return g_strcmp0(aa->tag, bb->tag); -} - -static int info_field_cmp_tag_descending(const void *a, const void *b) -{ - const struct InfoField *aa = a, *bb = b; - return g_strcmp0(bb->tag, aa->tag); -} - -static const GCompareFunc sort_functions[INFO_GROUP_SORT_MAX] = { - [INFO_GROUP_SORT_NONE] = NULL, - [INFO_GROUP_SORT_NAME_ASCENDING] = info_field_cmp_name_ascending, - [INFO_GROUP_SORT_NAME_DESCENDING] = info_field_cmp_name_descending, - [INFO_GROUP_SORT_VALUE_ASCENDING] = info_field_cmp_value_ascending, - [INFO_GROUP_SORT_VALUE_DESCENDING] = info_field_cmp_value_descending, - [INFO_GROUP_SORT_TAG_ASCENDING] = info_field_cmp_tag_ascending, - [INFO_GROUP_SORT_TAG_DESCENDING] = info_field_cmp_tag_descending, -}; - -static void field_free_strings(struct InfoField *field) -{ - if (field->free_value_on_flatten) - g_free((gchar *)field->value); - if (field->free_name_on_flatten) - g_free((gchar *)field->name); - g_free(field->tag); -} - -static void free_group_fields(struct InfoGroup *group) -{ - if (group && group->fields) { - guint i; - - for (i = 0; i < group->fields->len; i++) { - struct InfoField *field = - &g_array_index(group->fields, struct InfoField, i); - field_free_strings(field); - } - - g_array_free(group->fields, TRUE); - } -} - -static void flatten_group(GString *output, const struct InfoGroup *group, guint group_count) -{ - guint i; - - if (group->name != NULL) - g_string_append_printf(output, "[%s#%d]\n", group->name, group_count); - - if (group->sort != INFO_GROUP_SORT_NONE) - g_array_sort(group->fields, sort_functions[group->sort]); - - if (group->fields) { - for (i = 0; i < group->fields->len; i++) { - struct InfoField *field = &g_array_index(group->fields, struct InfoField, i); - gchar tmp_tag[256] = ""; /* for generated tag */ - - gboolean do_escape = TRUE; /* refers to the value side only */ - if (field->value && strchr(field->value, '|') ) { - /* turning off escaping for values that may have columns */ - do_escape = FALSE; - /* TODO:/FIXME: struct InfoField should store the column values - * in an array instead of packing them into one value with '|'. - * Then each value can be escaped and joined together with '|' - * for flatten(). unflatten() can then split on non-escaped '|', - * and unescape the result values into the column value array. - * Another way to do this might be to check - * .column_headers_visible in struct Info, but that is not - * available here. - */ - } - - const gchar *tp = field->tag; - gboolean tagged = !!tp; - gboolean flagged = field->highlight || field->report_details || field->value_has_vendor; - if (!tp) { - snprintf(tmp_tag, 255, "ITEM%d-%d", group_count, i); - tp = tmp_tag; - } - if (!field->label_is_escaped) { - if (strchr(field->name, '=') - || strchr(field->name, '$')) { - // TODO: what about # ? - gchar *ofn = (gchar*)field->name; - field->name = key_label_escape(ofn); - g_free(ofn); - field->label_is_escaped = TRUE; - } - } - if (tagged || flagged || field->icon) { - g_string_append_printf(output, "$%s%s%s%s%s$", - field->label_is_escaped ? "@" : "", - field->highlight ? "*" : "", - field->report_details ? "!" : "", - field->value_has_vendor ? "^" : "", - tp); - } - - if (do_escape) { - 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 { - g_string_append_printf(output, "%s=%s\n", field->name, field->value); - } - } - } else if (group->computed) { - g_string_append_printf(output, "%s\n", group->computed); - } -} - -static void flatten_shell_param(GString *output, const struct InfoGroup *group, guint group_count) -{ - guint i; - - if (!group->fields) - return; - - for (i = 0; i < group->fields->len; i++) { - struct InfoField *field = &g_array_index(group->fields, struct InfoField, i); - gchar tmp_tag[256] = ""; /* for generated tag */ - - const gchar *tp = field->tag; - gboolean tagged = !!tp; - if (!tp) { - snprintf(tmp_tag, 255, "ITEM%d-%d", group_count, i); - tp = tmp_tag; - } - - if (field->update_interval) { - g_string_append_printf(output, "UpdateInterval$%s%s%s=%d\n", - tagged ? tp : "", tagged ? "$" : "", /* tag and close or nothing */ - field->name, - field->update_interval); - } - - if (field->icon) { - g_string_append_printf(output, "Icon$%s$=%s\n", - tp, field->icon); - } - } -} - -static void flatten_shell_param_global(GString *output, const struct Info *info) -{ - int i; - - g_string_append_printf(output, "ViewType=%d\n", info->view_type); - g_string_append_printf(output, "ShowColumnHeaders=%s\n", - info->column_headers_visible ? "true" : "false"); - - if (info->zebra_visible) - g_string_append(output, "Zebra=1\n"); - - if (info->reload_interval) - g_string_append_printf(output, "ReloadInterval=%d\n", info->reload_interval); - - if (!info->normalize_percentage) - g_string_append(output, "NormalizePercentage=false\n"); - - for (i = 0; i < G_N_ELEMENTS(info_column_titles); i++) { - if (!info->column_titles[i]) - continue; - - g_string_append_printf(output, "ColumnTitle$%s=%s\n", - info_column_titles[i], info->column_titles[i]); - } -} - -gchar *info_flatten(struct Info *info) -{ - /* This is a scaffolding method: eventually the HardInfo shell should - * understand a struct Info instead of parsing these strings, which are - * brittle and unnecessarily complicates things. Being a temporary - * method, no attention is paid to improve the memory allocation - * strategy. */ - GString *values; - GString *shell_param; - guint i; - - values = g_string_new(NULL); - shell_param = g_string_new(NULL); - - if (info->groups) { - for (i = 0; i < info->groups->len; i++) { - struct InfoGroup *group = - &g_array_index(info->groups, struct InfoGroup, i); - - flatten_group(values, group, i); - flatten_shell_param(shell_param, group, i); - - free_group_fields(group); - } - - g_array_free(info->groups, TRUE); - } - - flatten_shell_param_global(shell_param, info); - g_string_append_printf(values, "[$ShellParam$]\n%s", shell_param->str); - - g_string_free(shell_param, TRUE); - g_free(info); - - return g_string_free(values, FALSE); -} - -void info_remove_group(struct Info *info, guint index) -{ - struct InfoGroup *grp; - - if (index >= info->groups->len) - return; - - grp = &g_array_index(info->groups, struct InfoGroup, index); - free_group_fields(grp); - - g_array_remove_index(info->groups, index); -} - -struct InfoField *info_find_field(struct Info *info, const gchar *tag, const gchar *name) { - struct InfoGroup *group; - struct InfoField *field; - int gi,fi; - for (gi = 0; gi < info->groups->len; gi++) { - struct InfoGroup *group = &g_array_index(info->groups, struct InfoGroup, gi); - for (fi = 0; fi < group->fields->len; fi++) { - struct InfoField *field = &g_array_index(group->fields, struct InfoField, fi); - if (tag && SEQ(tag, field->tag) ) - return field; - else if (name && SEQ(name, field->name) ) - return field; - } - } - return NULL; -} - -#define VAL_FALSE_OR_TRUE ((!g_strcmp0(value, "true") || !g_strcmp0(value, "1")) ? TRUE : FALSE) - -struct Info *info_unflatten(const gchar *str) -{ - struct Info *info = info_new(); - GKeyFile *key_file = g_key_file_new(); - gchar **groups; - gsize ngroups; - int g, k, spg = -1; - - g_key_file_load_from_data(key_file, str, strlen(str), 0, NULL); - groups = g_key_file_get_groups(key_file, &ngroups); - for (g = 0; groups[g]; g++) { - gchar *group_name = groups[g]; - gchar **keys = g_key_file_get_keys(key_file, group_name, NULL, NULL); - - if (*group_name == '$') { - /* special group */ - if (SEQ(group_name, "$ShellParam$") ) - spg = g; /* handle after all groups are added */ - else { - /* This special group is unknown and won't be handled, so - * the name will not be linked anywhere. */ - g_free(group_name); - continue; - } - } else { - /* normal group */ - struct InfoGroup group = {}; - group.name = group_name; - group.fields = g_array_new(FALSE, FALSE, sizeof(struct InfoField)); - group.sort = INFO_GROUP_SORT_NONE; - - for (k = 0; keys[k]; k++) { - struct InfoField field = {}; - gchar *flags, *tag, *name, *label, *dis; - key_get_components(keys[k], &flags, &tag, &name, &label, &dis, TRUE); - gchar *value = g_key_file_get_value(key_file, group_name, keys[k], NULL); - - field.tag = tag; - field.name = name; - field.value = value; - if (key_label_is_escaped(flags)) - field.label_is_escaped = TRUE; - if (key_wants_details(flags)) - field.report_details = TRUE; - if (key_is_highlighted(flags)) - field.highlight = TRUE; - if (key_value_has_vendor_string(flags)) - field.value_has_vendor = TRUE; - field.free_value_on_flatten = TRUE; - field.free_name_on_flatten = TRUE; - - g_free(flags); - g_free(label); - g_free(dis); - g_array_append_val(group.fields, field); - } - g_array_append_val(info->groups, group); - } - } - - if (spg >= 0) { - gchar *group_name = groups[spg]; - gchar **keys = g_key_file_get_keys(key_file, group_name, NULL, NULL); - for (k = 0; keys[k]; k++) { - gchar *value = g_key_file_get_value(key_file, group_name, keys[k], NULL); - gchar *parm = NULL; - if (SEQ(keys[k], "ViewType")) { - info_set_view_type(info, atoi(value)); - } else if (SEQ(keys[k], "ShowColumnHeaders")) { - info_set_column_headers_visible(info, VAL_FALSE_OR_TRUE); - } else if (SEQ(keys[k], "Zebra")) { - info_set_zebra_visible(info, VAL_FALSE_OR_TRUE); - } else if (SEQ(keys[k], "ReloadInterval")) { - info_set_reload_interval(info, atoi(value)); - } else if (SEQ(keys[k], "NormalizePercentage")) { - info_set_normalize_percentage(info, VAL_FALSE_OR_TRUE); - } else if (g_str_has_prefix(keys[k], "ColumnTitle$")) { - info_set_column_title(info, strchr(keys[k], '$') + 1, value); - } else if (g_str_has_prefix(keys[k], "Icon$")) { - const gchar *chk_name = NULL; - gchar *chk_tag = NULL; - parm = strchr(keys[k], '$'); - if (key_is_flagged(parm)) - chk_tag = key_mi_tag(parm); - struct InfoField *field = info_find_field(info, chk_tag, NULL); - if (field) - field->icon = value; - g_free(chk_tag); - } else if (g_str_has_prefix(keys[k], "UpdateInterval$")) { - const gchar *chk_name = NULL; - gchar *chk_tag = NULL; - parm = strchr(keys[k], '$'); - if (key_is_flagged(parm)) { - chk_tag = key_mi_tag(parm); - chk_name = key_get_name(parm); - } else - chk_name = key_get_name(parm+1); - struct InfoField *field = info_find_field(info, chk_tag, chk_name); - if (field) - field->update_interval = atoi(value); - g_free(chk_tag); - } - } - g_free(group_name); - g_strfreev(keys); - } - - return info; -} diff --git a/hardinfo/pci_util.c b/hardinfo/pci_util.c deleted file mode 100644 index ccf4f7c4..00000000 --- a/hardinfo/pci_util.c +++ /dev/null @@ -1,463 +0,0 @@ -/* - * HardInfo - Displays System Information - * Copyright (C) 2003-2017 L. A. F. Pereira <l@tia.mat.br> - * This file - * Copyright (C) 2018 Burt P. <pburt0@gmail.com> - * - * 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. - * - * This program 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "hardinfo.h" -#include "pci_util.h" -#include "util_ids.h" - -gchar *pci_ids_file = NULL; -GTimer *pci_ids_timer = NULL; -const gboolean nolspci = FALSE; /* true for testing */ - -/* Two pieces of info still only from lspci: - * - kernel driver in use - * - kernel modules list - * - * TODO: could use readlink() and basename() to get kernel driver from sysfs - * - /sys/bus/pci/devices/<addy>/driver is a symlink - */ - -const gchar *find_pci_ids_file() { - if (pci_ids_file) { - if (!strstr(pci_ids_file, ".min")) - return pci_ids_file; - if (g_timer_elapsed(pci_ids_timer, NULL) > 2.0) { - /* try again for the full version */ - DEBUG("find_pci_ids_file() found only a \".min\" version, trying again..."); - g_free(pci_ids_file); - pci_ids_file = NULL; - } - } - char *file_search_order[] = { - g_strdup("/usr/share/hwdata/pci.ids"), - g_strdup("/usr/share/misc/pci.ids"), - g_build_filename(g_get_user_config_dir(), "hardinfo", "pci.ids", NULL), - g_build_filename(params.path_data, "pci.ids", NULL), - g_build_filename(g_get_user_config_dir(), "hardinfo", "pci.ids.min", NULL), - g_build_filename(params.path_data, "pci.ids.min", NULL), - NULL - }; - int n; - for(n = 0; file_search_order[n]; n++) { - if (!pci_ids_file && !access(file_search_order[n], R_OK)) - pci_ids_file = file_search_order[n]; - else - g_free(file_search_order[n]); - } - DEBUG("find_pci_ids_file() result: %s", pci_ids_file); - if (pci_ids_file) { - if (!pci_ids_timer) - pci_ids_timer = g_timer_new(); - else - g_timer_reset(pci_ids_timer); - } - return pci_ids_file; -} - -char *pci_lookup_ids_vendor_str(uint32_t id) { - gchar *ret = NULL; - - ids_query_result result = {}; - gchar *qpath; - - if (!find_pci_ids_file()) - return FALSE; - - qpath = g_strdup_printf("%04x", id); - scan_ids_file(pci_ids_file, qpath, &result, -1); - if (result.results[0]) { - ret = g_strdup(result.results[0]); - } - g_free(qpath); - - return ret; -} - -static gboolean pci_lookup_ids(pcid *d) { - gboolean ret = FALSE; - ids_query_result result = {}; - gchar *qpath; - - if (!find_pci_ids_file()) - return FALSE; - - /* lookup vendor, device, sub device */ - qpath = g_strdup_printf("%04x/%04x/%04x %04x", - d->vendor_id, d->device_id, d->sub_vendor_id, d->sub_device_id); - scan_ids_file(pci_ids_file, qpath, &result, -1); - if (result.results[0]) { - if (d->vendor_id_str) g_free(d->vendor_id_str); - d->vendor_id_str = g_strdup(result.results[0]); - ret = TRUE; - } - if (result.results[1]) { - if (d->device_id_str) g_free(d->device_id_str); - d->device_id_str = g_strdup(result.results[1]); - ret = TRUE; - } - if (result.results[2]) { - if (d->sub_device_id_str) g_free(d->sub_device_id_str); - d->sub_device_id_str = g_strdup(result.results[2]); - ret = TRUE; - } - g_free(qpath); - - /* lookup sub vendor by itself */ - qpath = g_strdup_printf("%04x", d->sub_vendor_id); - scan_ids_file(pci_ids_file, qpath, &result, -1); - if (result.results[0]) { - if (d->sub_vendor_id_str) g_free(d->sub_vendor_id_str); - d->sub_vendor_id_str = g_strdup(result.results[0]); - ret = TRUE; - }; - g_free(qpath); - - /* lookup class */ - qpath = g_strdup_printf("C %02x/%02x", (d->class >> 8) & 0xff, (d->class & 0xff)); - scan_ids_file(pci_ids_file, qpath, &result, -1); - if (result.results[0]) { - if (d->class_str) g_free(d->class_str); - d->class_str = g_strdup(result.results[0]); - if (result.results[1] - && !SEQ(result.results[0], result.results[1]) ) { - /* options 1: results[0] + " :: " + results[1] */ - //d->class_str = appf(d->class_str, " :: ", "%s", result.results[1]); - - /* option 2: results[1] or results[0] */ - g_free(d->class_str); - d->class_str = g_strdup(result.results[1]); - } - ret = TRUE; - } - g_free(qpath); - - return ret; -} - -gint pcid_cmp_by_addy(gconstpointer a, gconstpointer b) -{ - const struct pcid *dev_a = a; - const struct pcid *dev_b = b; - - if (!dev_a) - return !!dev_b; - if (!dev_b) - return !!dev_a; - - return g_strcmp0(dev_a->slot_str, dev_b->slot_str); -} - -void pcid_free(pcid *s) { - if (s) { - g_free(s->slot_str); - g_free(s->class_str); - g_free(s->vendor_id_str); - g_free(s->device_id_str); - g_free(s->sub_vendor_id_str); - g_free(s->sub_device_id_str); - g_free(s->driver); - g_free(s->driver_list); - g_free(s); - } -} - -static char *lspci_line_value(char *line, const char *prefix) { - if (g_str_has_prefix(g_strstrip(line), prefix)) { - line += strlen(prefix) + 1; - return g_strstrip(line); - } else - return NULL; -} - -/* read output line of lspci -vmmnn */ -static int lspci_line_string_and_code(char *line, char *prefix, char **str, uint32_t *code) { - char *l = lspci_line_value(line, prefix); - char *e; - - if (l) { - e = strchr(l, 0); - while (e > l && *e != '[') e--; - sscanf(e, "[%x]", code); - *e = 0; /* terminate at start of code */ - if (*str) free(*str); /* free if replacing */ - *str = strdup(g_strstrip(l)); - } - return 0; -} - -static gboolean pci_fill_details(pcid *s) { - if (nolspci) return FALSE; - gboolean spawned; - gchar *out, *err, *p, *l, *next_nl; - gchar *pci_loc = pci_address_str(s->domain, s->bus, s->device, s->function); - gchar *lspci_cmd = g_strdup_printf("lspci -D -s %s -vvv", pci_loc); - - spawned = hardinfo_spawn_command_line_sync(lspci_cmd, - &out, &err, NULL, NULL); - g_free(lspci_cmd); - g_free(pci_loc); - if (spawned) { - p = out; - while(next_nl = strchr(p, '\n')) { - strend(p, '\n'); - g_strstrip(p); - if (l = lspci_line_value(p, "Kernel driver in use")) { - s->driver = g_strdup(l); - goto pci_details_next; - } - if (l = lspci_line_value(p, "Kernel modules")) { - s->driver_list = g_strdup(l); - goto pci_details_next; - } - /* TODO: more details */ - - pci_details_next: - p = next_nl + 1; - } - g_free(out); - g_free(err); - return TRUE; - } - return FALSE; -} - -char *pci_address_str(uint32_t dom, uint32_t bus, uint32_t dev, uint32_t func) { - return g_strdup_printf("%04x:%02x:%02x.%01x", dom, bus, dev, func); -} - -/* /sys/bus/pci/devices/0000:01:00.0/ */ -char *_sysfs_bus_pci(uint32_t dom, uint32_t bus, uint32_t dev, uint32_t func, const char *item) { - char *ret = NULL, *pci_loc, *sysfs_path; - pci_loc = pci_address_str(dom, bus, dev, func); - sysfs_path = g_strdup_printf("%s/%s/%s", SYSFS_PCI_ROOT, pci_loc, item); - g_file_get_contents(sysfs_path, &ret, NULL, NULL); - free(pci_loc); - free(sysfs_path); - return ret; -} - -gboolean _sysfs_bus_pci_read_hex(uint32_t dom, uint32_t bus, uint32_t dev, uint32_t func, const char *item, uint32_t *val) { - char *tmp = _sysfs_bus_pci(dom, bus, dev, func, item); - uint32_t tval; - if (tmp && val) { - int ec = sscanf(tmp, "%x", &tval); - free(tmp); - if (ec) { - *val = tval; - return TRUE; - } - } - return FALSE; -} - -/* https://www.kernel.org/doc/Documentation/ABI/testing/sysfs-bus-pci */ -static gboolean pci_get_device_sysfs(uint32_t dom, uint32_t bus, uint32_t dev, uint32_t func, pcid *s) { - char *tmp = NULL; - int ec = 0; - float tf; - s->domain = dom; - s->bus = bus; - s->device = dev; - s->function = func; - s->slot_str = s->slot_str ? s->slot_str : pci_address_str(dom, bus, dev, func); - if (! _sysfs_bus_pci_read_hex(dom, bus, dev, func, "class", &s->class) ) - return FALSE; - s->class >>= 8; /* TODO: find out why */ - _sysfs_bus_pci_read_hex(dom, bus, dev, func, "device", &s->device_id); - _sysfs_bus_pci_read_hex(dom, bus, dev, func, "vendor", &s->vendor_id); - _sysfs_bus_pci_read_hex(dom, bus, dev, func, "subsystem_device", &s->sub_device_id); - _sysfs_bus_pci_read_hex(dom, bus, dev, func, "subsystem_vendor", &s->sub_vendor_id); - _sysfs_bus_pci_read_hex(dom, bus, dev, func, "revision", &s->revision); - - tmp = _sysfs_bus_pci(dom, bus, dev, func, "max_link_speed"); - if (tmp) { - ec = sscanf(tmp, "%f GT/s", &tf); - if (ec) s->pcie_speed_max = tf; - free(tmp); - } - tmp = _sysfs_bus_pci(dom, bus, dev, func, "current_link_speed"); - if (tmp) { - ec = sscanf(tmp, "%f GT/s", &tf); - if (ec) s->pcie_speed_curr = tf; - free(tmp); - } - tmp = _sysfs_bus_pci(dom, bus, dev, func, "max_link_width"); - if (tmp) { - s->pcie_width_max = strtoul(tmp, NULL, 0); - free(tmp); - } - tmp = _sysfs_bus_pci(dom, bus, dev, func, "max_link_width"); - if (tmp) { - s->pcie_width_curr = strtoul(tmp, NULL, 0); - free(tmp); - } - return TRUE; -} - -static gboolean pci_get_device_lspci(uint32_t dom, uint32_t bus, uint32_t dev, uint32_t func, pcid *s) { - if (nolspci) return FALSE; - gboolean spawned; - gchar *out, *err, *p, *l, *next_nl; - gchar *pci_loc = pci_address_str(dom, bus, dev, func); - gchar *lspci_cmd = g_strdup_printf("lspci -D -s %s -vmmnn", pci_loc); - - s->domain = dom; - s->bus = bus; - s->device = dev; - s->function = func; - - spawned = hardinfo_spawn_command_line_sync(lspci_cmd, - &out, &err, NULL, NULL); - g_free(lspci_cmd); - if (spawned) { - p = out; - while(next_nl = strchr(p, '\n')) { - strend(p, '\n'); - g_strstrip(p); - if (l = lspci_line_value(p, "Slot")) { - s->slot_str = g_strdup(l); - if (strcmp(s->slot_str, pci_loc) != 0) { - printf("PCI: %s != %s\n", s->slot_str, pci_loc); - } - } - if (l = lspci_line_value(p, "Rev")) { - s->revision = strtol(l, NULL, 16); - } - lspci_line_string_and_code(p, "Class", &s->class_str, &s->class); - lspci_line_string_and_code(p, "Vendor", &s->vendor_id_str, &s->vendor_id); - lspci_line_string_and_code(p, "Device", &s->device_id_str, &s->device_id); - lspci_line_string_and_code(p, "SVendor", &s->sub_vendor_id_str, &s->sub_vendor_id); - lspci_line_string_and_code(p, "SDevice", &s->sub_device_id_str, &s->sub_device_id); - - p = next_nl + 1; - } - g_free(out); - g_free(err); - g_free(pci_loc); - return TRUE; - } - g_free(pci_loc); - return FALSE; -} - -pcid *pci_get_device_str(const char *addy) { - uint32_t dom, bus, dev, func; - int ec; - if (addy) { - ec = sscanf(addy, "%x:%x:%x.%x", &dom, &bus, &dev, &func); - if (ec == 4) { - return pci_get_device(dom, bus, dev, func); - } - } - return NULL; -} - -pcid *pci_get_device(uint32_t dom, uint32_t bus, uint32_t dev, uint32_t func) { - pcid *s = pcid_new(); - gboolean ok = FALSE; - if (s) { - ok = pci_get_device_sysfs(dom, bus, dev, func, s); - if (ok) { - ok |= pci_lookup_ids(s); - if (!ok) - ok |= pci_get_device_lspci(dom, bus, dev, func, s); - } - if (!ok) { - pcid_free(s); - s = NULL; - } - } - return s; -} - -static pcid_list pci_get_device_list_lspci(uint32_t class_min, uint32_t class_max) { - if (nolspci) return NULL; - gboolean spawned; - gchar *out, *err, *p, *next_nl; - pcid_list dl = NULL; - pcid *nd; - uint32_t dom, bus, dev, func, cls; - int ec; - - if (class_max == 0) class_max = 0xffff; - - spawned = hardinfo_spawn_command_line_sync("lspci -D -mn", - &out, &err, NULL, NULL); - if (spawned) { - p = out; - while(next_nl = strchr(p, '\n')) { - strend(p, '\n'); - ec = sscanf(p, "%x:%x:%x.%x \"%x\"", &dom, &bus, &dev, &func, &cls); - if (ec == 5) { - if (cls >= class_min && cls <= class_max) { - nd = pci_get_device(dom, bus, dev, func); - pci_fill_details(nd); - dl = g_slist_append(dl, nd); - } - } - p = next_nl + 1; - } - g_free(out); - g_free(err); - } - return dl; -} - -static pcid_list pci_get_device_list_sysfs(uint32_t class_min, uint32_t class_max) { - pcid_list dl = NULL; - pcid *nd; - uint32_t dom, bus, dev, func, cls; - int ec; - - if (class_max == 0) class_max = 0xffff; - - const gchar *f = NULL; - GDir *d = g_dir_open("/sys/bus/pci/devices", 0, NULL); - if (!d) return 0; - - while((f = g_dir_read_name(d))) { - ec = sscanf(f, "%x:%x:%x.%x", &dom, &bus, &dev, &func); - if (ec == 4) { - gchar *cf = g_strdup_printf("/sys/bus/pci/devices/%s/class", f); - gchar *cstr = NULL; - if (g_file_get_contents(cf, &cstr, NULL, NULL) ) { - cls = strtoul(cstr, NULL, 16) >> 8; - if (cls >= class_min && cls <= class_max) { - nd = pci_get_device(dom, bus, dev, func); - pci_fill_details(nd); - dl = g_slist_append(dl, nd); - } - } - g_free(cstr); - g_free(cf); - } - } - g_dir_close(d); - return dl; -} - -pcid_list pci_get_device_list(uint32_t class_min, uint32_t class_max) { - pcid_list dl = NULL; - dl = pci_get_device_list_sysfs(class_min, class_max); - if (!dl) - dl = pci_get_device_list_lspci(class_min, class_max); - return dl; -} - diff --git a/hardinfo/problem_marker.c b/hardinfo/problem_marker.c deleted file mode 100644 index 1e0c2aed..00000000 --- a/hardinfo/problem_marker.c +++ /dev/null @@ -1,13 +0,0 @@ - -#include "hardinfo.h" - -/* requires COMPILE_FLAGS "-std=c99" */ - -const char *problem_marker() { - static const char as_markup[] = "<big><b>\u26A0</b></big>"; - static const char as_text[] = "(!)"; - if (params.markup_ok) - return as_markup; - else - return as_text; -} diff --git a/hardinfo/socket.c b/hardinfo/socket.c deleted file mode 100644 index 6e3a3f9e..00000000 --- a/hardinfo/socket.c +++ /dev/null @@ -1,127 +0,0 @@ -/* - * HardInfo - Displays System Information - * Copyright (C) 2003-2007 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. - * - * This program 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include <stdio.h> -#include <string.h> -#include <arpa/inet.h> -#include <errno.h> -#include <netdb.h> -#include <netinet/in.h> -#include <sys/socket.h> -#include <sys/types.h> -#include <unistd.h> - -#include <glib.h> - -#include "socket.h" - -Socket *sock_connect(gchar * host, gint port) -{ - struct sockaddr_in server; - Socket *s; - int sock; - - sock = socket(AF_INET, SOCK_STREAM, 0); - if (sock > 0) { - memset(&server, 0, sizeof(server)); - server.sin_family = AF_INET; - server.sin_addr.s_addr = inet_addr(host); - server.sin_port = htons(port); - - if (connect(sock, (struct sockaddr *) (void *) &server, sizeof(server)) < 0) { - goto cleanup; - } - - s = g_new0(Socket, 1); - s->sock = sock; - - return s; - } - -cleanup: - close(sock); - - return NULL; -} - -/* From: http://www.erlenstar.demon.co.uk/unix/faq_3.html#SEC26 */ -static inline int __sock_is_ready(Socket * s, int mode) -{ - int rc, fd = s->sock; - fd_set fds; - struct timeval tv; - - FD_ZERO(&fds); - FD_SET(fd, &fds); - tv.tv_sec = tv.tv_usec = 0; - - if (mode == 0) { - /* read */ - rc = select(fd + 1, &fds, NULL, NULL, &tv); - } else { - /* write */ - rc = select(fd + 1, NULL, &fds, NULL, &tv); - } - - if (rc < 0) - return -1; - - return FD_ISSET(fd, &fds) ? 1 : 0; -} - -int sock_ready_to_read(Socket * s) -{ - return __sock_is_ready(s, 0); -} - -int sock_ready_to_write(Socket * s) -{ - return __sock_is_ready(s, 1); -} - -int sock_read(Socket * s, gchar * buffer, gint size) -{ - if (size > 2 && sock_ready_to_read(s)) { - gint n; - - n = read(s->sock, buffer, size - 1); - if (n > 0) { - buffer[n] = '\0'; - } else { - return 0; - } - - return n; - } - - return 0; -} - -int sock_write(Socket * s, gchar * str) -{ - while (!sock_ready_to_write(s)); - - return write(s->sock, str, strlen(str)); -} - -void sock_close(Socket * s) -{ - shutdown(s->sock, 2); - close(s->sock); - g_free(s); -} diff --git a/hardinfo/storage_util.c b/hardinfo/storage_util.c deleted file mode 100644 index 7e61d336..00000000 --- a/hardinfo/storage_util.c +++ /dev/null @@ -1,250 +0,0 @@ -#include "udisks2_util.h" -#include "storage_util.h" -#include "util_ids.h" -#include "hardinfo.h" - -gchar *sdcard_ids_file = NULL; -gchar *oui_ids_file = NULL; - -// moved from udisks2_util.h -void find_sdcard_ids_file() { - if (sdcard_ids_file) return; - char *file_search_order[] = { - g_build_filename(g_get_user_config_dir(), "hardinfo", "sdcard.ids", NULL), - g_build_filename(params.path_data, "sdcard.ids", NULL), - NULL - }; - int n; - for(n = 0; file_search_order[n]; n++) { - 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]); - } -} - -void find_oui_ids_file() { - if (oui_ids_file) return; - char *file_search_order[] = { - g_build_filename(g_get_user_config_dir(), "hardinfo", "ieee_oui.ids", NULL), - g_build_filename(params.path_data, "ieee_oui.ids", NULL), - NULL - }; - int n; - for(n = 0; file_search_order[n]; n++) { - if (!oui_ids_file && !access(file_search_order[n], R_OK)) - oui_ids_file = file_search_order[n]; - else - g_free(file_search_order[n]); - } -} - -gchar* get_oui_from_wwid(gchar* wwid){ - gchar* ret = NULL; - - if (g_str_has_prefix(wwid, "nna.")) { - if (strlen(wwid)*4 < 48) - return NULL; - - switch (wwid[4]){ - case '1': - case '2': - ret = g_strndup(wwid + 8, 6); - break; - case '5': - case '6': - ret = g_strndup(wwid + 5, 6); - break; - } - } - else if(g_str_has_prefix(wwid, "eui.")) { - if (strlen(wwid)*4 < 48) - return NULL; - ret = g_strndup(wwid+4, 6); - } - - return ret; -} - -gchar* get_oui_company(gchar* oui){ - ids_query_result result = {}; - - if (!oui_ids_file) - find_oui_ids_file(); - - scan_ids_file(oui_ids_file, oui, &result, -1); - if (result.results[0]) - return g_strdup(result.results[0]); - - return NULL; -} - -// moved from udisks2_util.h -void check_sdcard_vendor(u2driveext *e) { - if (!e || !e->d) return; - if (!e->d->media) return; - if (! (g_str_has_prefix(e->d->media, "flash_sd") - || g_str_has_prefix(e->d->media, "flash_mmc") )) return; - if (e->d->vendor && e->d->vendor[0]) return; - if (!e->d->block_dev) return; - - if (!sdcard_ids_file) - find_sdcard_ids_file(); - - gchar *qpath = NULL; - ids_query_result result = {}; - - gchar *oemid_path = g_strdup_printf("/sys/block/%s/device/oemid", e->d->block_dev); - gchar *manfid_path = g_strdup_printf("/sys/block/%s/device/manfid", e->d->block_dev); - gchar *oemid = NULL, *manfid = NULL; - g_file_get_contents(oemid_path, &oemid, NULL, NULL); - g_file_get_contents(manfid_path, &manfid, NULL, NULL); - - unsigned int id = oemid?strtol(oemid, NULL, 16):0; - char c2 = id & 0xff, c1 = (id >> 8) & 0xff; - - qpath = g_strdup_printf("OEMID %02x%02x", (unsigned int)c1, (unsigned int)c2); - scan_ids_file(sdcard_ids_file, qpath, &result, -1); - g_free(oemid); - if (result.results[0]) - oemid = g_strdup(result.results[0]); - else - oemid = g_strdup_printf("OEM %02x%02x \"%c%c\"", - (unsigned int)c1, (unsigned int)c2, - isprint(c1) ? c1 : '.', isprint(c2) ? c2 : '.'); - g_free(qpath); - - id = manfid?strtol(manfid, NULL, 16):0; - qpath = g_strdup_printf("MANFID %06x", id); - scan_ids_file(sdcard_ids_file, qpath, &result, -1); - g_free(manfid); - if (result.results[0]) - manfid = g_strdup(result.results[0]); - else - manfid = g_strdup_printf("MANF %06x", id); - g_free(qpath); - - vendor_list vl = NULL; - const Vendor *v = NULL; - v = vendor_match(oemid, NULL); - if (v) vl = vendor_list_append(vl, v); - v = vendor_match(manfid, NULL); - if (v) vl = vendor_list_append(vl, v); - vl = vendor_list_remove_duplicates_deep(vl); - e->vendors = vendor_list_concat(e->vendors, vl); - - g_free(e->d->vendor); - if (g_strcmp0(oemid, manfid) == 0) - e->d->vendor = g_strdup(oemid); - else - e->d->vendor = g_strdup_printf("%s / %s", oemid, manfid); - - g_free(oemid); - g_free(manfid); - g_free(oemid_path); - g_free(manfid_path); - - if (e->d->revision && e->d->revision[0]) return; - - /* bonus: revision */ - gchar *fwrev_path = g_strdup_printf("/sys/block/%s/device/fwrev", e->d->block_dev); - gchar *hwrev_path = g_strdup_printf("/sys/block/%s/device/hwrev", e->d->block_dev); - gchar *fwrev = NULL, *hwrev = NULL; - g_file_get_contents(fwrev_path, &fwrev, NULL, NULL); - g_file_get_contents(hwrev_path, &hwrev, NULL, NULL); - - unsigned int fw = fwrev ? strtol(fwrev, NULL, 16) : 0; - unsigned int hw = hwrev ? strtol(hwrev, NULL, 16) : 0; - g_free(e->d->revision); - e->d->revision = g_strdup_printf("%02x.%02x", hw, fw); - - g_free(fwrev); - g_free(hwrev); - g_free(fwrev_path); - g_free(hwrev_path); - -} - -void set_nvme_controller_info(u2driveext *e){ - gchar *path = g_strdup_printf("/sys/block/%s/device/device", e->d->block_dev); - gchar *systarget = g_file_read_link(path, NULL); - gchar *target = systarget ? g_filename_to_utf8(systarget, -1, NULL, NULL, NULL) : NULL; - gchar *pci_addy = target ? g_path_get_basename(target) : NULL; - e->nvme_controller = pci_addy ? pci_get_device_str(pci_addy) : NULL; - g_free(path); - g_free(systarget); - g_free(target); - g_free(pci_addy); - if (e->nvme_controller) { - e->vendors = vendor_list_append(e->vendors, - vendor_match(e->nvme_controller->vendor_id_str, NULL)); - e->vendors = vendor_list_append(e->vendors, - vendor_match(e->nvme_controller->sub_vendor_id_str, NULL)); - } -} - -GSList* get_udisks2_drives_ext(void){ - GSList *node, *list; - u2driveext* extdrive; - - list = get_udisks2_all_drives_info(); - - for (node = list; node != NULL; node = node->next) { - extdrive = u2drive_ext((udiskd *)node->data); - node->data = extdrive; - - if (!extdrive->d->vendor || !extdrive->d->vendor[0]) { - // sometimes vendors adds their name to the model field - const Vendor *v = vendor_match(extdrive->d->model, NULL); - if (v) - extdrive->d->vendor = g_strdup(v->name); - } - - check_sdcard_vendor(extdrive); - - extdrive->vendors = vendor_list_append(extdrive->vendors, vendor_match(extdrive->d->vendor, NULL)); - - // get OUI from WWID - if (extdrive->d->wwid) { - extdrive->wwid_oui.oui = get_oui_from_wwid(extdrive->d->wwid); - if (extdrive->wwid_oui.oui) { - extdrive->wwid_oui.vendor = get_oui_company(extdrive->wwid_oui.oui); - } - if (extdrive->wwid_oui.vendor){ - extdrive->vendors = vendor_list_append(extdrive->vendors, vendor_match(extdrive->wwid_oui.vendor, NULL)); - } - } - - // NVMe PCI device - if (strstr(extdrive->d->block_dev, "nvme")) { - set_nvme_controller_info(extdrive); - } - - extdrive->vendors = gg_slist_remove_null(extdrive->vendors); - extdrive->vendors = vendor_list_remove_duplicates_deep(extdrive->vendors); - - } - return list; -} - - -u2driveext* u2drive_ext(udiskd * udisks_drive_data) { - u2driveext* data = g_new0(u2driveext, 1); - data->d = udisks_drive_data; - return data; -} - -void u2driveext_free(u2driveext *u) { - if (u) { - udiskd_free(u->d); - g_free(u->wwid_oui.oui); - g_free(u->wwid_oui.vendor); - pcid_free(u->nvme_controller); - g_free(u); - } -} - -void storage_shutdown(){ - g_free(sdcard_ids_file); - g_free(oui_ids_file); -} diff --git a/hardinfo/udisks2_util.c b/hardinfo/udisks2_util.c deleted file mode 100644 index 8e6ebd94..00000000 --- a/hardinfo/udisks2_util.c +++ /dev/null @@ -1,639 +0,0 @@ -#include <gio/gio.h> -#include "udisks2_util.h" - -#define UDISKS2_INTERFACE "org.freedesktop.UDisks2" -#define UDISKS2_MANAGER_INTERFACE "org.freedesktop.UDisks2.Manager" -#define UDISKS2_BLOCK_INTERFACE "org.freedesktop.UDisks2.Block" -#define UDISKS2_LOOP_INTERFACE "org.freedesktop.UDisks2.Loop" -#define UDISKS2_PARTITION_INTERFACE "org.freedesktop.UDisks2.Partition" -#define UDISKS2_PART_TABLE_INTERFACE "org.freedesktop.UDisks2.PartitionTable" -#define UDISKS2_DRIVE_INTERFACE "org.freedesktop.UDisks2.Drive" -#define UDISKS2_DRIVE_ATA_INTERFACE "org.freedesktop.UDisks2.Drive.Ata" -#define DBUS_PROPERTIES_INTERFACE "org.freedesktop.DBus.Properties" -#define UDISKS2_MANAGER_OBJ_PATH "/org/freedesktop/UDisks2/Manager" -#define UDISKS2_BLOCK_DEVICES_PATH "/org/freedesktop/UDisks2/block_devices" - -#define STRDUP_IF_NOT_EMPTY(S) (g_strcmp0(S, "") == 0) ? NULL: g_strdup(S); - -GDBusConnection* udisks2_conn = NULL; - -GVariant* get_dbus_property(GDBusProxy* proxy, const gchar *interface, - const gchar *property) { - GVariant *result, *v = NULL; - GError *error = NULL; - - result = g_dbus_proxy_call_sync(proxy, "Get", - g_variant_new ("(ss)", interface, property), - G_DBUS_CALL_FLAGS_NONE, -1, NULL, &error); - - if (error != NULL) { - g_error_free (error); - return NULL; - } - - g_variant_get(result, "(v)", &v); - g_variant_unref(result); - return v; -} - -// this function works with udisks2 version 2.7.2 or newer -GSList* get_block_dev_paths_from_udisks2(GDBusConnection* conn){ - GDBusProxy *proxy; - GVariant *options, *v; - GVariantIter *iter; - GError *error = NULL; - GSList *block_paths = NULL; - const gchar *block_path = NULL; - - proxy = g_dbus_proxy_new_sync(conn, G_DBUS_PROXY_FLAGS_NONE, NULL, - UDISKS2_INTERFACE, UDISKS2_MANAGER_OBJ_PATH, - UDISKS2_MANAGER_INTERFACE, NULL, &error); - options = g_variant_new_parsed("@a{sv} { %s: <true> }", - "auth.no_user_interaction"); - if (error != NULL){ - g_error_free (error); - g_object_unref(proxy); - return NULL; - } - - v = g_dbus_proxy_call_sync(proxy, "GetBlockDevices", - g_variant_new_tuple(&options, 1), - G_DBUS_CALL_FLAGS_NONE, -1, NULL, &error); - g_object_unref(proxy); - - if (error != NULL){ - g_error_free (error); - return NULL; - } - - g_variant_get(v, "(ao)", &iter); - while (g_variant_iter_loop (iter, "o", &block_path)){ - block_paths = g_slist_append(block_paths, g_strdup(block_path)); - } - - g_variant_iter_free (iter); - g_variant_unref(v); - return block_paths; -} - -GSList* get_block_dev_paths_from_sysfs(){ - GSList *block_paths = NULL; - GDir *dir; - gchar *path; - const gchar *entry; - - dir = g_dir_open("/sys/class/block", 0, NULL); - if (!dir) - return NULL; - - while ((entry = g_dir_read_name(dir))) { - path = g_strdup_printf("%s/%s", UDISKS2_BLOCK_DEVICES_PATH, entry); - block_paths = g_slist_append(block_paths, path); - } - - g_dir_close(dir); - return block_paths; -} - -GSList* udisks2_drives_func_caller(GDBusConnection* conn, - gpointer (*func)(const char*, GDBusProxy*, - GDBusProxy*, const char*)) { - GDBusProxy *block_proxy, *drive_proxy; - GVariant *block_v, *v; - GSList *result_list = NULL, *block_dev_list, *node; - GError *error = NULL; - gpointer output; - - gchar *block_path = NULL; - const gchar *block_dev, *drive_path = NULL; - - if (conn == NULL) - return NULL; - - // get block devices - block_dev_list = get_block_dev_paths_from_udisks2(conn); - if (block_dev_list == NULL) - block_dev_list = get_block_dev_paths_from_sysfs(); - - for (node = block_dev_list; node != NULL; node = node->next) { - block_path = (gchar *)node->data; - block_proxy = g_dbus_proxy_new_sync(conn, G_DBUS_PROXY_FLAGS_NONE, - NULL, UDISKS2_INTERFACE, block_path, - DBUS_PROPERTIES_INTERFACE, NULL, &error); - if (error){ - g_error_free(error); - error = NULL; - continue; - } - - // Skip partitions - v = get_dbus_property(block_proxy, UDISKS2_PARTITION_INTERFACE, "Size"); - if (v){ - g_variant_unref(v); - g_object_unref(block_proxy); - continue; - } - - // Skip loop devices - v = get_dbus_property(block_proxy, UDISKS2_LOOP_INTERFACE, "BackingFile"); - if (v){ - g_variant_unref(v); - g_object_unref(block_proxy); - continue; - } - - block_dev = block_path + strlen(UDISKS2_BLOCK_DEVICES_PATH) + 1; - drive_path = NULL; - - // let's find drive proxy - v = get_dbus_property(block_proxy, UDISKS2_BLOCK_INTERFACE, "Drive"); - if (v){ - drive_path = g_variant_get_string(v, NULL); - - if (g_strcmp0(drive_path, "/") != 0){ - drive_proxy = g_dbus_proxy_new_sync(conn, - G_DBUS_PROXY_FLAGS_NONE, NULL, - UDISKS2_INTERFACE, drive_path, - DBUS_PROPERTIES_INTERFACE, NULL, &error); - - if (error == NULL) { - // call requested function - output = func(block_dev, block_proxy, drive_proxy, drive_path); - - if (output != NULL){ - result_list = g_slist_append(result_list, output); - } - g_object_unref(drive_proxy); - } - else { - g_error_free(error); - error = NULL; - } - } - g_variant_unref(v); - } - g_object_unref(block_proxy); - } - g_slist_free_full(block_dev_list, g_free); - - return result_list; -} - -GDBusConnection* get_udisks2_connection(void) { - GDBusConnection *conn; - GDBusProxy *proxy; - GError *error = NULL; - GVariant *result = NULL; - - // connection to system bus - conn = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &error); - if (error != NULL) { - g_error_free (error); - return NULL; - } - - // let's check if udisks2 is responding - proxy = g_dbus_proxy_new_sync(conn, G_DBUS_PROXY_FLAGS_NONE, NULL, - UDISKS2_INTERFACE, UDISKS2_MANAGER_OBJ_PATH, - DBUS_PROPERTIES_INTERFACE, NULL, &error); - if (error != NULL) { - g_error_free (error); - g_object_unref(conn); - return NULL; - } - - result = get_dbus_property(proxy, UDISKS2_MANAGER_INTERFACE, "Version"); - g_object_unref(proxy); - if (error != NULL) { - g_error_free (error); - return NULL; - } - - // OK, let's return connection to system bus - g_variant_unref(result); - return conn; -} - -udiskt* udiskt_new() { - return g_new0(udiskt, 1); -} - -udisksa* udisksa_new() { - return g_new0(udisksa, 1); -} - -udiskp* udiskp_new() { - return g_new0(udiskp, 1); -} - -udiskd* udiskd_new() { - return g_new0(udiskd, 1); -} - - -void udiskt_free(udiskt *u) { - if (u) { - g_free(u->drive); - g_free(u); - } -} - -void udisksa_free(udisksa *u) { - if (u) { - g_free(u->identifier); - udisksa_free(u->next); - g_free(u); - } -} - -void udiskp_free(udiskp *u) { - if (u) { - g_free(u->block); - g_free(u->type); - g_free(u->version); - g_free(u->label); - udiskp_free(u->next); - g_free(u); - } -} - -void udiskd_free(udiskd *u) { - if (u) { - g_free(u->model); - g_free(u->vendor); - g_free(u->revision); - g_free(u->block_dev); - g_free(u->serial); - g_free(u->wwid); - g_free(u->connection_bus); - g_free(u->partition_table); - udiskp_free(u->partitions); - udisksa_free(u->smart_attributes); - g_free(u->media); - g_strfreev(u->media_compatibility); - g_free(u); - } -} - - -udiskp* get_udisks2_partition_info(const gchar *part_path) { - GVariant *v; - GDBusProxy *proxy; - GError *error = NULL; - udiskp* partition; - const gchar *str; - - if (!g_str_has_prefix(part_path, UDISKS2_BLOCK_DEVICES_PATH)) { - return NULL; - } - - partition = udiskp_new(); - partition->block = g_strdup(part_path + strlen(UDISKS2_BLOCK_DEVICES_PATH) + 1); - - proxy = g_dbus_proxy_new_sync(udisks2_conn, G_DBUS_PROXY_FLAGS_NONE, - NULL, UDISKS2_INTERFACE, part_path, - DBUS_PROPERTIES_INTERFACE, NULL, &error); - if (error == NULL) { - v = get_dbus_property(proxy, UDISKS2_BLOCK_INTERFACE, "IdLabel"); - if (v) { - str = g_variant_get_string(v, NULL); - partition->label = STRDUP_IF_NOT_EMPTY(str); - g_variant_unref(v); - } - v = get_dbus_property(proxy, UDISKS2_BLOCK_INTERFACE, "IdType"); - if (v) { - str = g_variant_dup_string(v, NULL); - partition->type = STRDUP_IF_NOT_EMPTY(str); - g_variant_unref(v); - } - v = get_dbus_property(proxy, UDISKS2_BLOCK_INTERFACE, "IdVersion"); - if (v) { - str = g_variant_dup_string(v, NULL); - partition->version = STRDUP_IF_NOT_EMPTY(str); - g_variant_unref(v); - } - v = get_dbus_property(proxy, UDISKS2_BLOCK_INTERFACE, "Size"); - if (v) { - partition->size = g_variant_get_uint64(v); - g_variant_unref(v); - } - } - else{ - g_error_free(error); - } - - g_object_unref(proxy); - return partition; -} - -gpointer get_udisks2_temp(const char *blockdev, GDBusProxy *block, - GDBusProxy *drive, const char *drivepath){ - GVariant *v; - gboolean smart_enabled = FALSE; - udiskt* disk_temp = NULL; - - v = get_dbus_property(drive, UDISKS2_DRIVE_ATA_INTERFACE, "SmartEnabled"); - if (v) { - smart_enabled = g_variant_get_boolean(v); - g_variant_unref(v); - } - - if (!smart_enabled) { - return NULL; - } - - v = get_dbus_property(drive, UDISKS2_DRIVE_ATA_INTERFACE, "SmartTemperature"); - if (v) { - disk_temp = udiskt_new(); - disk_temp->temperature = (gint32) (g_variant_get_double(v) - 273.15); - g_variant_unref(v); - } - - if (!disk_temp) { - return NULL; - } - - v = get_dbus_property(drive, UDISKS2_DRIVE_INTERFACE, "Model"); - if (v) { - disk_temp->drive = g_variant_dup_string(v, NULL); - g_variant_unref(v); - } - - return disk_temp; -} - -gchar* get_udisks2_smart_attributes(udiskd* dsk, const char *drivepath){ - GDBusProxy *proxy; - GVariant *options, *v, *v2; - GVariantIter *iter; - GError *error = NULL; - const char* aidenf; - guint8 aid; - gint32 avalue, aworst, athreshold, pretty_unit; - gint64 pretty; - udisksa *lastp = NULL, *p; - - proxy = g_dbus_proxy_new_sync(udisks2_conn, G_DBUS_PROXY_FLAGS_NONE, NULL, - UDISKS2_INTERFACE, drivepath, - UDISKS2_DRIVE_ATA_INTERFACE, NULL, &error); - - options = g_variant_new_parsed("@a{sv} { %s: <true> }", - "auth.no_user_interaction"); - if (error != NULL){ - g_error_free (error); - return NULL; - } - - v = g_dbus_proxy_call_sync(proxy, "SmartGetAttributes", - g_variant_new_tuple(&options, 1), - G_DBUS_CALL_FLAGS_NONE, -1, NULL, &error); - g_object_unref(proxy); - - if (error != NULL){ - g_error_free (error); - g_object_unref(proxy); - return NULL; - } - - v2 = g_variant_get_child_value(v, 0); - iter = g_variant_iter_new(v2); - - // id(y), identifier(s), flags(q), value(i), worst(i), threshold(i), - // pretty(x), pretty_unit(i), expansion(a{sv}) - // pretty_unit = 0 (unknown), 1 (dimensionless), 2 (milliseconds), 3 (sectors), 4 (millikelvin). - while (g_variant_iter_loop (iter, "(ysqiiixia{sv})", &aid, &aidenf, NULL, &avalue, - &aworst, &athreshold, &pretty, &pretty_unit, NULL)){ - p = udisksa_new(); - p->id = aid; - p->identifier = g_strdup(aidenf); - p->value = avalue; - p->worst = aworst; - p->threshold = athreshold; - switch (pretty_unit){ - case 1: - p->interpreted_unit = UDSK_INTPVAL_DIMENSIONLESS; - p->interpreted = pretty; - break; - case 2: - if (pretty > 1000*60*60){ // > 1h - p->interpreted_unit = UDSK_INTPVAL_HOURS; - p->interpreted = pretty / (1000*60*60); - } - else{ - p->interpreted_unit = UDSK_INTPVAL_MILISECONDS; - p->interpreted = pretty; - } - break; - case 3: - p->interpreted_unit = UDSK_INTPVAL_SECTORS; - p->interpreted = pretty; - break; - case 4: - p->interpreted_unit = UDSK_INTPVAL_CELSIUS; - p->interpreted = (pretty - 273150) / 1000; //mK to °C - break; - default: - p->interpreted_unit = UDSK_INTPVAL_SKIP; - p->interpreted = -1; - break; - } - p->next = NULL; - - if (lastp == NULL) - dsk->smart_attributes = p; - else - lastp->next = p; - - lastp = p; - } - g_variant_iter_free (iter); - g_variant_unref(v2); - g_variant_unref(v); - - return NULL; -} - -gpointer get_udisks2_drive_info(const char *blockdev, GDBusProxy *block, - GDBusProxy *drive, const char *drivepath) { - GVariant *v; - GVariantIter *iter; - const gchar *str, *part; - udiskd *u = NULL; - udiskp **p = NULL; - gsize n, i; - u = udiskd_new(); - u->block_dev = g_strdup(blockdev); - - v = get_dbus_property(drive, UDISKS2_DRIVE_INTERFACE, "Model"); - if (v){ - u->model = g_variant_dup_string(v, NULL); - g_variant_unref(v); - } - v = get_dbus_property(drive, UDISKS2_DRIVE_INTERFACE, "Vendor"); - if (v){ - u->vendor = g_variant_dup_string(v, NULL); - g_variant_unref(v); - } - v = get_dbus_property(drive, UDISKS2_DRIVE_INTERFACE, "Revision"); - if (v){ - u->revision = g_variant_dup_string(v, NULL); - g_variant_unref(v); - } - v = get_dbus_property(drive, UDISKS2_DRIVE_INTERFACE, "Serial"); - if (v){ - u->serial = g_variant_dup_string(v, NULL); - g_variant_unref(v); - } - v = get_dbus_property(drive, UDISKS2_DRIVE_INTERFACE, "WWN"); - if (v){ - str = g_variant_get_string(v, NULL); - if (g_str_has_prefix(str, "0x")) { - u->wwid = g_strdup_printf("nna.%s", str+2); - } - else if (g_str_has_prefix(str, "nna.") || g_str_has_prefix(str, "eui.")) { - u->wwid = g_strdup(str); - } - g_variant_unref(v); - } - v = get_dbus_property(drive, UDISKS2_DRIVE_INTERFACE, "ConnectionBus"); - if (v){ - u->connection_bus = g_variant_dup_string(v, NULL); - g_variant_unref(v); - } - v = get_dbus_property(drive, UDISKS2_DRIVE_INTERFACE, "RotationRate"); - if (v){ - u->rotation_rate = g_variant_get_int32(v); - g_variant_unref(v); - } - v = get_dbus_property(drive, UDISKS2_DRIVE_INTERFACE, "Size"); - if (v){ - u->size = g_variant_get_uint64(v); - g_variant_unref(v); - } - v = get_dbus_property(drive, UDISKS2_DRIVE_INTERFACE, "Media"); - if (v){ - str = g_variant_get_string(v, NULL); - if (strcmp(str, "") != 0) { - u->media = g_strdup(str); - } - g_variant_unref(v); - } - v = get_dbus_property(drive, UDISKS2_DRIVE_INTERFACE, "MediaCompatibility"); - if (v){ - g_variant_get(v, "as", &iter); - n = g_variant_iter_n_children(iter); - u->media_compatibility = g_malloc0_n(n + 1, sizeof(gchar*)); - - i = 0; - while (g_variant_iter_loop (iter, "s", &str) && i < n){ - u->media_compatibility[i] = g_strdup(str); - i++; - } - - g_variant_iter_free (iter); - g_variant_unref(v); - } - v = get_dbus_property(drive, UDISKS2_DRIVE_INTERFACE, "Ejectable"); - if (v){ - u->ejectable = g_variant_get_boolean(v); - g_variant_unref(v); - } - v = get_dbus_property(drive, UDISKS2_DRIVE_INTERFACE, "Removable"); - if (v){ - u->removable = g_variant_get_boolean(v); - g_variant_unref(v); - } - v = get_dbus_property(drive, UDISKS2_DRIVE_ATA_INTERFACE, "PmSupported"); - if (v){ - u->pm_supported = g_variant_get_boolean(v); - g_variant_unref(v); - } - v = get_dbus_property(drive, UDISKS2_DRIVE_ATA_INTERFACE, "ApmSupported"); - if (v){ - u->apm_supported = g_variant_get_boolean(v); - g_variant_unref(v); - } - v = get_dbus_property(drive, UDISKS2_DRIVE_ATA_INTERFACE, "AamSupported"); - if (v){ - u->aam_supported = g_variant_get_boolean(v); - g_variant_unref(v); - } - v = get_dbus_property(drive, UDISKS2_DRIVE_ATA_INTERFACE, "SmartSupported"); - if (v){ - u->smart_supported = g_variant_get_boolean(v); - g_variant_unref(v); - } - v = get_dbus_property(drive, UDISKS2_DRIVE_ATA_INTERFACE, "SmartEnabled"); - if (v){ - u->smart_enabled = g_variant_get_boolean(v); - g_variant_unref(v); - } - if (u->smart_enabled){ - v = get_dbus_property(drive, UDISKS2_DRIVE_ATA_INTERFACE, "SmartPowerOnSeconds"); - if (v){ - u->smart_poweron = g_variant_get_uint64(v); - g_variant_unref(v); - } - v = get_dbus_property(drive, UDISKS2_DRIVE_ATA_INTERFACE, "SmartNumBadSectors"); - if (v){ - u->smart_bad_sectors = g_variant_get_int64(v); - g_variant_unref(v); - } - v = get_dbus_property(drive, UDISKS2_DRIVE_ATA_INTERFACE, "SmartTemperature"); - if (v){ - u->smart_temperature = (gint) (g_variant_get_double(v) - 273.15); - g_variant_unref(v); - } - v = get_dbus_property(drive, UDISKS2_DRIVE_ATA_INTERFACE, "SmartFailing"); - if (v){ - u->smart_failing = g_variant_get_boolean(v); - g_variant_unref(v); - } - get_udisks2_smart_attributes(u, drivepath); - } - - v = get_dbus_property(block, UDISKS2_PART_TABLE_INTERFACE, "Type"); - if (v){ - u->partition_table = g_variant_dup_string(v, NULL); - g_variant_unref(v); - } - // 'Partitions' property is available in udisks2 version 2.7.2 or newer - v = get_dbus_property(block, UDISKS2_PART_TABLE_INTERFACE, "Partitions"); - if (v){ - g_variant_get(v, "ao", &iter); - - p = &(u->partitions); - while (g_variant_iter_loop (iter, "o", &str)) { - *p = get_udisks2_partition_info(str); - if (*p != NULL){ - p = &((*p)->next); - } - } - - g_variant_iter_free (iter); - g_variant_unref(v); - } - - return u; -} - -GSList* get_udisks2_temps(void){ - return udisks2_drives_func_caller(udisks2_conn, get_udisks2_temp); -} - -GSList* get_udisks2_all_drives_info(void){ - return udisks2_drives_func_caller(udisks2_conn, get_udisks2_drive_info); -} - -void udisks2_init(){ - if (udisks2_conn == NULL){ - udisks2_conn = get_udisks2_connection(); - } -} - -void udisks2_shutdown(){ - if (udisks2_conn != NULL){ - g_object_unref(udisks2_conn); - udisks2_conn = NULL; - } -} diff --git a/hardinfo/usb_util.c b/hardinfo/usb_util.c deleted file mode 100644 index 6f9f9ef8..00000000 --- a/hardinfo/usb_util.c +++ /dev/null @@ -1,553 +0,0 @@ -/* - * HardInfo - Displays System Information - * Copyright (C) 2003-2017 L. A. F. Pereira <l@tia.mat.br> - * This file - * Copyright (C) 2017 Burt P. <pburt0@gmail.com> - * Copyright (C) 2019 Ondrej ÄŒerman - * - * 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. - * - * This program 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#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); -} - -void usbi_free(usbi *s) { - if (s) { - g_free(s->if_label); - g_free(s->if_class_str); - g_free(s->if_subclass_str); - g_free(s->if_protocol_str); - g_free(s->driver); - g_free(s); - } -} - -void usbi_list_free(usbi *s) { - usbi *n; - while(s != NULL) { - n = s->next; - usbi_free(s); - s = n; - } -} - -usbd *usbd_new() { - return g_new0(usbd, 1); -} - -void usbd_free(usbd *s) { - if (s) { - usbi_list_free(s->if_list); - vendor_list_free(s->vendors); - g_free(s->vendor); - g_free(s->product); - g_free(s->manufacturer); - 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); - } -} - -void usbd_list_free(usbd *s) { - usbd *n; - while(s != NULL) { - n = s->next; - usbd_free(s); - s = n; - } -} - -/* returns number of items after append */ -static int usbd_list_append(usbd *l, usbd *n) { - int c = 0; - while(l != NULL) { - c++; - if (l->next == NULL) { - if (n != NULL) { - l->next = n; - c++; - } - break; - } - l = l->next; - } - return c; -} - -/* returns new top of the list */ -static usbd *usbd_list_append_sorted(usbd *l, usbd *n) { - usbd *b = NULL; - usbd *t = l; - - if (n == NULL) - return l; - - while(l != NULL) { - if ((n->bus > l->bus) || - ((n->bus == l->bus) && (n->dev >= l->dev))) { - if (l->next == NULL) { - l->next = n; - break; - } - b = l; - l = l->next; - } - else { - if (b == NULL) { - t = n; - n->next = l; - } - else { - b->next = n; - n->next = l; - } - break; - } - } - - return t; -} - -gboolean usbd_append_interface(usbd *dev, usbi *new_if){ - usbi *curr_if; - if (dev->if_list == NULL){ - dev->if_list = new_if; - return TRUE; - } - - if (dev->if_list->if_number == new_if->if_number) - return FALSE; - - curr_if = dev->if_list; - while(curr_if->next != NULL) { - curr_if = curr_if->next; - if (curr_if->if_number == new_if->if_number) - return FALSE; - } - curr_if->next = new_if; - return TRUE; -} - -int usbd_list_count(usbd *s) { - return usbd_list_append(s, NULL); -} - -static char *lsusb_line_value(char *line, const char *prefix) { - if (g_str_has_prefix(line, prefix)) { - line += strlen(prefix) + 1; - return g_strstrip(line); - } else - return NULL; -} - -static gboolean usb_get_device_lsusb(int bus, int dev, usbd *s) { - gboolean spawned; - gchar *out, *err, *p, *l, *t, *next_nl; - gchar *lsusb_cmd = g_strdup_printf("lsusb -s %d:%d -v", bus, dev); - usbi *curr_if = NULL; // do not free - - s->bus = bus; - s->dev = dev; - - spawned = hardinfo_spawn_command_line_sync(lsusb_cmd, - &out, &err, NULL, NULL); - g_free(lsusb_cmd); - if (spawned) { - if (strstr(err, "information will be missing")) { - s->user_scan = TRUE; - } - p = out; - while(next_nl = strchr(p, '\n')) { - strend(p, '\n'); - g_strstrip(p); - - // device info - if (l = lsusb_line_value(p, "idVendor")) { - s->vendor_id = strtol(l, NULL, 0); - if (t = strchr(l, ' ')) - s->vendor = g_strdup(t + 1); - } else if (l = lsusb_line_value(p, "idProduct")) { - s->product_id = strtol(l, NULL, 0); - if (t = strchr(l, ' ')) - s->product = g_strdup(t + 1); - } else if (l = lsusb_line_value(p, "MaxPower")) { - s->max_curr_ma = atoi(l); - } else if (l = lsusb_line_value(p, "bcdUSB")) { - s->usb_version = g_strdup(l); - } else if (l = lsusb_line_value(p, "bcdDevice")) { - s->device_version = g_strdup(l); - } else if (l = lsusb_line_value(p, "bDeviceClass")) { - s->dev_class = atoi(l); - if (t = strchr(l, ' ')) - s->dev_class_str = g_strdup(t + 1); - } else if (l = lsusb_line_value(p, "bDeviceSubClass")) { - 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")) { - curr_if = usbi_new(); - curr_if->if_number = atoi(l); - - // This may parse same interface multiple times when there - // are multiple Configuration descriptors per device - // As a workaround usbd_append_interface appends interface - // with same if_number only once - if (!usbd_append_interface(s, curr_if)){ - usbi_free(curr_if); - curr_if = NULL; - } - } else if (l = lsusb_line_value(p, "bInterfaceClass")) { - if (curr_if != NULL){ - curr_if->if_class = atoi(l); - if (t = strchr(l, ' ')) - curr_if->if_class_str = g_strdup(t + 1); - } - } else if (l = lsusb_line_value(p, "bInterfaceSubClass")) { - if (curr_if != NULL){ - curr_if->if_subclass = atoi(l); - if (t = strchr(l, ' ')) - curr_if->if_subclass_str = g_strdup(t + 1); - } - } else if (l = lsusb_line_value(p, "bInterfaceProtocol")) { - if (curr_if != NULL){ - curr_if->if_protocol = atoi(l); - if (t = strchr(l, ' ')) - curr_if->if_protocol_str = g_strdup(t + 1); - } - } else if (l = lsusb_line_value(p, "iInterface")) { - if (curr_if != NULL){ - if (t = strchr(l, ' ')) - curr_if->if_label = g_strdup(t + 1); - } - } - - p = next_nl + 1; - } - g_free(out); - g_free(err); - return TRUE; - } - return FALSE; -} - -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)){ - return FALSE; - } - - tmp = g_strdup_printf("%s/driver", ifpath); - drvpath = g_file_read_link(tmp, NULL); - g_free(tmp); - if (drvpath){ - intf->driver = g_path_get_basename(drvpath); - g_free(drvpath); - } - else{ - intf->driver = g_strdup(_("(None)")); - } - - intf->if_number = number; - intf->if_class = h_sysfs_read_hex(ifpath, "bInterfaceClass"); - intf->if_subclass = h_sysfs_read_hex(ifpath, "bInterfaceSubClass"); - intf->if_protocol = h_sysfs_read_hex(ifpath, "bInterfaceProtocol"); - - 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; -} - -static 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]); - } -} - -void usb_lookup_ids_vendor_product_str(gint vendor_id, gint product_id, - gchar **vendor_str, gchar **product_str) { - ids_query_result result = {}; - gchar *qpath; - - if (!usb_ids_file) - find_usb_ids_file(); - if (!usb_ids_file) - return; - - qpath = g_strdup_printf("%04x/%04x", vendor_id, product_id); - scan_ids_file(usb_ids_file, qpath, &result, -1); - if (result.results[0]) - *vendor_str = g_strdup(result.results[0]); - if (result.results[1]) - *product_str = g_strdup(result.results[1]); - g_free(qpath); -} - -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, 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"); - s->vendor_id = h_sysfs_read_hex(sysfspath, "idVendor"); - s->product_id = h_sysfs_read_hex(sysfspath, "idProduct"); - s->manufacturer = h_sysfs_read_string(sysfspath, "manufacturer"); - s->device = h_sysfs_read_string(sysfspath, "product"); - 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++){ - intf = usbi_new(); - ok = usb_get_interface_sysfs(conf, i, sysfspath, intf); - if (ok){ - if (!usbd_append_interface(s, intf)){ - usbi_free(intf); - } - } - else{ - usbi_free(intf); - } - } - } - else{ // improve existing list - intf = s->if_list; - while (intf){ - usb_get_interface_sysfs(conf, intf->if_number, sysfspath, intf); - intf = intf->next; - } - } - - return TRUE; -} - -usbd *usb_get_device(int bus, int dev, const gchar* sysfspath) { - usbd *s = usbd_new(); - int ok = 0; - if (s) { - /* try sysfs */ - 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; - } - } - return s; -} - -static usbd *usb_get_device_list_lsusb() { - gboolean spawned; - gchar *out, *err, *p, *next_nl; - usbd *head = NULL, *nd; - int bus, dev, vend, prod, ec; - - spawned = hardinfo_spawn_command_line_sync("lsusb", - &out, &err, NULL, NULL); - if (spawned) { - p = out; - while(next_nl = strchr(p, '\n')) { - strend(p, '\n'); - ec = sscanf(p, "Bus %d Device %d: ID %x:%x", &bus, &dev, &vend, &prod); - if (ec == 4) { - nd = usb_get_device(bus, dev, NULL); - if (head == NULL) { - head = nd; - } else { - usbd_list_append(head, nd); - } - } - p = next_nl + 1; - } - g_free(out); - g_free(err); - } - return head; -} - -static usbd *usb_get_device_list_sysfs() { - GDir *dir; - GRegex *regex; - GMatchInfo *match_info; - usbd *head = NULL, *nd; - gchar *devpath; - const char *entry; - int bus, dev; - - regex = g_regex_new("^([0-9]+-[0-9]+([.][0-9]+)*)|(usb[0-9]+)$", 0, 0, NULL); - if (!regex){ - return NULL; - } - - dir = g_dir_open(SYSFS_DIR_USB_DEVICES, 0, NULL); - if (!dir){ - return NULL; - } - - while ((entry = g_dir_read_name(dir))) { - g_regex_match(regex, entry, 0, &match_info); - - if (g_match_info_matches(match_info)) { - devpath = g_build_filename(SYSFS_DIR_USB_DEVICES, entry, NULL); - bus = h_sysfs_read_int(devpath, "busnum"); - dev = h_sysfs_read_int(devpath, "devnum"); - - if (bus > 0 && dev > 0){ - nd = usb_get_device(bus, dev, devpath); - if (head == NULL) { - head = nd; - } else { - head = usbd_list_append_sorted(head, nd); - } - } - g_free(devpath); - } - g_match_info_free(match_info); - } - - g_dir_close(dir); - g_regex_unref(regex); - - return head; -} - -usbd *usb_get_device_list() { - usbd *lst, *l; - - lst = usb_get_device_list_sysfs(); - if (lst == NULL) - lst = usb_get_device_list_lsusb(); - - l = lst; - while(l) { - l->vendors = vendor_list_remove_duplicates_deep(vendors_match(l->vendor, l->manufacturer, NULL)); - l = l->next; - } - - return lst; -} diff --git a/hardinfo/util.c b/hardinfo/util.c deleted file mode 100644 index 38c7bce1..00000000 --- a/hardinfo/util.c +++ /dev/null @@ -1,1445 +0,0 @@ -/* - * HardInfo - Displays System Information - * Copyright (C) 2003-2007 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. - * - * This program 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/* - * Functions h_strdup_cprintf and h_strconcat are based on GLib version 2.4.6 - * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald - * - * 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 of the License, or (at your option) any later version. - * - */ - -#include <config.h> - -#include <report.h> -#include <string.h> -#include <shell.h> -#include <iconcache.h> -#include <hardinfo.h> -#include <gtk/gtk.h> - -#include <binreloc.h> - -#include <sys/stat.h> -#include <sys/types.h> - -#define KiB 1024 -#define MiB 1048576 -#define GiB 1073741824 -#define TiB 1099511627776 -#define PiB 1125899906842624 - -static GSList *modules_list = NULL; - -void sync_manager_clear_entries(void); - -gchar *find_program(gchar *program_name) -{ - int i; - char *temp; - static GHashTable *cache = NULL; - const char *path[] = { "/usr/local/bin", "/usr/local/sbin", - "/usr/bin", "/usr/sbin", - "/bin", "/sbin", - NULL }; - - /* we don't need to call stat() every time: cache the results */ - if (!cache) { - cache = g_hash_table_new(g_str_hash, g_str_equal); - } else if ((temp = g_hash_table_lookup(cache, program_name))) { - return g_strdup(temp); - } - - for (i = 0; path[i]; i++) { - temp = g_build_filename(path[i], program_name, NULL); - - if (g_file_test(temp, G_FILE_TEST_IS_EXECUTABLE)) { - g_hash_table_insert(cache, program_name, g_strdup(temp)); - return temp; - } - - g_free(temp); - } - - /* our search has failed; use GLib's search (which uses $PATH env var) */ - if ((temp = g_find_program_in_path(program_name))) { - g_hash_table_insert(cache, program_name, g_strdup(temp)); - return temp; - } - - return NULL; -} - -gchar *seconds_to_string(unsigned int seconds) -{ - unsigned int hours, minutes, days; - const gchar *days_fmt, *hours_fmt, *minutes_fmt, *seconds_fmt; - gchar *full_fmt, *ret = g_strdup(""); - - minutes = seconds / 60; - seconds %= 60; - hours = minutes / 60; - minutes %= 60; - days = hours / 24; - hours %= 24; - - days_fmt = ngettext("%d day", "%d days", days); - hours_fmt = ngettext("%d hour", "%d hours", hours); - minutes_fmt = ngettext("%d minute", "%d minutes", minutes); - seconds_fmt = ngettext("%d second", "%d seconds", seconds); - - if (days) { - full_fmt = g_strdup_printf("%s %s %s %s", days_fmt, hours_fmt, minutes_fmt, seconds_fmt); - ret = g_strdup_printf(full_fmt, days, hours, minutes, seconds); - } else if (hours) { - full_fmt = g_strdup_printf("%s %s %s", hours_fmt, minutes_fmt, seconds_fmt); - ret = g_strdup_printf(full_fmt, hours, minutes, seconds); - } else if (minutes) { - full_fmt = g_strdup_printf("%s %s", minutes_fmt, seconds_fmt); - ret = g_strdup_printf(full_fmt, minutes, seconds); - } else { - ret = g_strdup_printf(seconds_fmt, seconds); - } - g_free(full_fmt); - return ret; -} - -gchar *size_human_readable(gfloat size) -{ - if (size < KiB) - return g_strdup_printf(_("%.1f B"), size); - if (size < MiB) - return g_strdup_printf(_("%.1f KiB"), size / KiB); - if (size < GiB) - return g_strdup_printf(_("%.1f MiB"), size / MiB); - if (size < TiB) - return g_strdup_printf(_("%.1f GiB"), size / GiB); - if (size < PiB) - return g_strdup_printf(_("%.1f TiB"), size / TiB); - - return g_strdup_printf(_("%.1f PiB"), size / PiB); -} - -char *strend(gchar * str, gchar chr) -{ - if (!str) - return NULL; - - char *p; - if ((p = g_utf8_strchr(str, -1, chr))) - *p = 0; - - return str; -} - -void remove_quotes(gchar * str) -{ - if (!str) - return; - - while (*str == '"') - *(str++) = ' '; - - strend(str, '"'); -} - -void remove_linefeed(gchar * str) -{ - strend(str, '\n'); -} - -void widget_set_cursor(GtkWidget * widget, GdkCursorType cursor_type) -{ - GdkCursor *cursor; - GdkDisplay *display; - GdkWindow *gdk_window; - - display = gtk_widget_get_display(widget); - cursor = gdk_cursor_new_for_display(display, cursor_type); - gdk_window = gtk_widget_get_window(widget); - if (cursor) { - gdk_window_set_cursor(gdk_window, cursor); - gdk_display_flush(display); -#if GTK_CHECK_VERSION(3, 0, 0) - g_object_unref(cursor); -#else - gdk_cursor_unref(cursor); -#endif - } - - while (gtk_events_pending()) - gtk_main_iteration(); -} - -static gboolean __nonblock_cb(gpointer data) -{ - gtk_main_quit(); - return FALSE; -} - -void nonblock_sleep(guint msec) -{ - g_timeout_add(msec, (GSourceFunc) __nonblock_cb, NULL); - gtk_main(); -} - -static void __expand_cb(GtkWidget * widget, gpointer data) -{ - if (GTK_IS_EXPANDER(widget)) { - gtk_expander_set_expanded(GTK_EXPANDER(widget), TRUE); - } else if (GTK_IS_CONTAINER(widget)) { - gtk_container_foreach(GTK_CONTAINER(widget), - (GtkCallback) __expand_cb, NULL); - } -} - -void file_chooser_open_expander(GtkWidget * chooser) -{ - gtk_container_foreach(GTK_CONTAINER(chooser), - (GtkCallback) __expand_cb, NULL); -} - -void file_chooser_add_filters(GtkWidget * chooser, FileTypes * filters) -{ - GtkFileFilter *filter; - gint i; - - for (i = 0; filters[i].name; i++) { - filter = gtk_file_filter_new(); - gtk_file_filter_add_mime_type(filter, filters[i].mime_type); - gtk_file_filter_set_name(filter, filters[i].name); - gtk_file_chooser_add_filter(GTK_FILE_CHOOSER(chooser), filter); - } -} - -gchar *file_chooser_get_extension(GtkWidget * chooser, FileTypes * filters) -{ - GtkFileFilter *filter; - const gchar *filter_name; - gint i; - - filter = gtk_file_chooser_get_filter(GTK_FILE_CHOOSER(chooser)); - filter_name = gtk_file_filter_get_name(filter); - for (i = 0; filters[i].name; i++) { - if (g_str_equal(filter_name, filters[i].name)) { - return filters[i].extension; - } - } - - return NULL; -} - -gpointer file_types_get_data_by_name(FileTypes * filters, gchar * filename) -{ - gint i; - - for (i = 0; filters[i].name; i++) { - if (g_str_has_suffix(filename, filters[i].extension)) { - return filters[i].data; - } - } - - return NULL; -} - -gchar *file_chooser_build_filename(GtkWidget * chooser, gchar * extension) -{ - gchar *filename = - gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(chooser)); - gchar *retval; - - if (g_str_has_suffix(filename, extension)) { - return filename; - } - - retval = g_strconcat(filename, extension, NULL); - g_free(filename); - - return retval; -} - -gboolean binreloc_init(gboolean try_hardcoded) -{ - GError *error = NULL; - gchar *tmp; - - DEBUG("initializing binreloc (hardcoded = %d)", try_hardcoded); - - /* If the runtime data directories we previously found, don't even try - to find them again. */ - if (params.path_data && params.path_lib) { - DEBUG("data and lib path already found."); - return TRUE; - } - - if (try_hardcoded || !gbr_init(&error)) { - /* We were asked to try hardcoded paths or BinReloc failed to initialize. */ - params.path_data = g_strdup(PREFIX); - params.path_lib = g_strdup(LIBPREFIX); - - if (error) { - g_error_free(error); - } - - DEBUG("%strying hardcoded paths.", - try_hardcoded ? "" : "binreloc init failed. "); - } else { - /* If we were able to initialize BinReloc, build the default data - and library paths. */ - DEBUG("done, trying to use binreloc paths."); - - tmp = gbr_find_data_dir(PREFIX); - params.path_data = g_build_filename(tmp, "hardinfo", NULL); - g_free(tmp); - - tmp = gbr_find_lib_dir(PREFIX); - params.path_lib = g_build_filename(tmp, "hardinfo", NULL); - g_free(tmp); - } - - DEBUG("searching for runtime data on these locations:"); - DEBUG(" lib: %s", params.path_lib); - DEBUG(" data: %s", params.path_data); - - /* Try to see if the uidefs.xml file isn't missing. This isn't the - definitive test, but it should do okay for most situations. */ - tmp = g_build_filename(params.path_data, "benchmark.data", NULL); - if (!g_file_test(tmp, G_FILE_TEST_EXISTS)) { - DEBUG("runtime data not found"); - - g_free(params.path_data); - g_free(params.path_lib); - g_free(tmp); - - params.path_data = params.path_lib = NULL; - - if (try_hardcoded) { - /* We tried the hardcoded paths, but still was unable to find the - runtime data. Give up. */ - DEBUG("giving up"); - return FALSE; - } else { - /* Even though BinReloc worked OK, the runtime data was not found. - Try the hardcoded paths. */ - DEBUG("trying to find elsewhere"); - return binreloc_init(TRUE); - } - } - g_free(tmp); - - DEBUG("runtime data found!"); - /* We found the runtime data; hope everything is fine */ - return TRUE; -} - -static void -log_handler(const gchar * log_domain, - GLogLevelFlags log_level, - const gchar * message, gpointer user_data) -{ - if (!params.gui_running) { - /* No GUI running: spit the message to the terminal */ - g_print("\n\n*** %s: %s\n\n", - (log_level & G_LOG_FLAG_FATAL) ? _("Error") : _("Warning"), - message); - } else { - /* Hooray! We have a GUI running! */ - GtkWidget *dialog; - - dialog = gtk_message_dialog_new_with_markup(NULL, GTK_DIALOG_MODAL, - (log_level & - G_LOG_FLAG_FATAL) ? - GTK_MESSAGE_ERROR : - GTK_MESSAGE_WARNING, - GTK_BUTTONS_CLOSE, - "<big><b>%s</b></big>\n\n%s", - (log_level & - G_LOG_FLAG_FATAL) ? - _("Fatal Error") : - _("Warning"), message); - - gtk_dialog_run(GTK_DIALOG(dialog)); - gtk_widget_destroy(dialog); - } -} - -void parameters_init(int *argc, char ***argv, ProgramParameters * param) -{ - static gboolean create_report = FALSE; - static gboolean force_all_details = FALSE; - static gboolean show_version = FALSE; - static gboolean list_modules = FALSE; - static gboolean autoload_deps = FALSE; - static gboolean run_xmlrpc_server = FALSE; - static gboolean skip_benchmarks = FALSE; - static gboolean quiet = FALSE; - static gchar *report_format = NULL; - static gchar *run_benchmark = NULL; - static gchar *result_format = NULL; - static gchar *bench_user_note = NULL; - static gchar **use_modules = NULL; - static gint max_bench_results = 10; - - static GOptionEntry options[] = { - { - .long_name = "quiet", - .short_name = 'q', - .arg = G_OPTION_ARG_NONE, - .arg_data = &quiet, - .description = N_("do not print status messages to standard output")}, - { - .long_name = "generate-report", - .short_name = 'r', - .arg = G_OPTION_ARG_NONE, - .arg_data = &create_report, - .description = N_("creates a report and prints to standard output")}, - { - .long_name = "report-format", - .short_name = 'f', - .arg = G_OPTION_ARG_STRING, - .arg_data = &report_format, - .description = N_("chooses a report format ([text], html)")}, - { - .long_name = "run-benchmark", - .short_name = 'b', - .arg = G_OPTION_ARG_STRING, - .arg_data = &run_benchmark, - .description = N_("run benchmark; requires benchmark.so to be loaded")}, - { - .long_name = "user-note", - .short_name = 'u', - .arg = G_OPTION_ARG_STRING, - .arg_data = &bench_user_note, - .description = N_("note attached to benchmark results")}, - { - .long_name = "result-format", - .short_name = 'g', - .arg = G_OPTION_ARG_STRING, - .arg_data = &result_format, - .description = N_("benchmark result format ([short], conf, shell)")}, - { - .long_name = "max-results", - .short_name = 'n', - .arg = G_OPTION_ARG_INT, - .arg_data = &max_bench_results, - .description = N_("maximum number of benchmark results to include (-1 for no limit, default is 10)")}, - { - .long_name = "list-modules", - .short_name = 'l', - .arg = G_OPTION_ARG_NONE, - .arg_data = &list_modules, - .description = N_("lists modules")}, - { - .long_name = "load-module", - .short_name = 'm', - .arg = G_OPTION_ARG_STRING_ARRAY, - .arg_data = &use_modules, - .description = N_("specify module to load")}, - { - .long_name = "autoload-deps", - .short_name = 'a', - .arg = G_OPTION_ARG_NONE, - .arg_data = &autoload_deps, - .description = N_("automatically load module dependencies")}, -#ifdef HAS_LIBSOUP - { - .long_name = "xmlrpc-server", - .short_name = 'x', - .arg = G_OPTION_ARG_NONE, - .arg_data = &run_xmlrpc_server, - .description = N_("run in XML-RPC server mode")}, -#endif /* HAS_LIBSOUP */ - { - .long_name = "version", - .short_name = 'v', - .arg = G_OPTION_ARG_NONE, - .arg_data = &show_version, - .description = N_("shows program version and quit")}, - { - .long_name = "skip-benchmarks", - .short_name = 's', - .arg = G_OPTION_ARG_NONE, - .arg_data = &skip_benchmarks, - .description = N_("do not run benchmarks")}, - { - .long_name = "very-verbose", - .short_name = 'w', /* like -vv */ - .arg = G_OPTION_ARG_NONE, - .arg_data = &force_all_details, - .description = N_("show all details")}, - {NULL} - }; - GOptionContext *ctx; - - ctx = g_option_context_new(_("- System Profiler and Benchmark tool")); - g_option_context_set_ignore_unknown_options(ctx, FALSE); - g_option_context_set_help_enabled(ctx, TRUE); - - g_option_context_add_main_entries(ctx, options, *(argv)[0]); - g_option_context_parse(ctx, argc, argv, NULL); - - g_option_context_free(ctx); - - if (*argc >= 2) { - g_print(_("Unrecognized arguments.\n" - "Try ``%s --help'' for more information.\n"), *(argv)[0]); - exit(1); - } - - param->create_report = create_report; - param->report_format = REPORT_FORMAT_TEXT; - param->show_version = show_version; - param->list_modules = list_modules; - param->use_modules = use_modules; - param->run_benchmark = run_benchmark; - param->result_format = result_format; - param->max_bench_results = max_bench_results; - param->autoload_deps = autoload_deps; - param->run_xmlrpc_server = run_xmlrpc_server; - param->skip_benchmarks = skip_benchmarks; - param->force_all_details = force_all_details; - param->quiet = quiet; - param->argv0 = *(argv)[0]; - - if (report_format) { - if (g_str_equal(report_format, "html")) - param->report_format = REPORT_FORMAT_HTML; - if (g_str_equal(report_format, "shell")) - param->report_format = REPORT_FORMAT_SHELL; - } - - /* clean user note */ - if (bench_user_note) { - char *p = NULL; - while(p = strchr(bench_user_note, ';')) { *p = ','; } - param->bench_user_note = - gg_key_file_parse_string_as_value(bench_user_note, '|'); - } - - /* html ok? - * gui: yes - * report html: yes - * report text: no - * anything else? */ - param->markup_ok = TRUE; - if (param->create_report && param->report_format != REPORT_FORMAT_HTML) - param->markup_ok = FALSE; - - // TODO: fmt_opts: FMT_OPT_ATERM, FMT_OPT_HTML, FMT_OPT_PANGO... - param->fmt_opts = FMT_OPT_NONE; - - gchar *confdir = g_build_filename(g_get_user_config_dir(), "hardinfo", NULL); - if (!g_file_test(confdir, G_FILE_TEST_EXISTS)) { - mkdir(confdir, 0744); - } - g_free(confdir); -} - -gboolean ui_init(int *argc, char ***argv) -{ - DEBUG("initializing gtk+ UI"); - - g_set_application_name("HardInfo"); - g_log_set_handler(NULL, - G_LOG_LEVEL_WARNING | G_LOG_FLAG_FATAL | - G_LOG_LEVEL_ERROR, log_handler, NULL); - - return gtk_init_check(argc, argv); -} - -/* Copyright: Jens Låås, SLU 2002 */ -gchar *strreplacechr(gchar * string, gchar * replace, gchar new_char) -{ - gchar *s; - for (s = string; *s; s++) - if (strchr(replace, *s)) - *s = new_char; - - return string; -} - -gchar *strreplace(gchar *string, gchar *replace, gchar *replacement) -{ - gchar **tmp, *ret; - - tmp = g_strsplit(string, replace, 0); - ret = g_strjoinv(replacement, tmp); - g_strfreev(tmp); - - return ret; -} - -static GHashTable *__module_methods = NULL; - -static void module_register_methods(ShellModule * module) -{ - const ShellModuleMethod *(*get_methods)(void); - gchar *method_name; - - if (__module_methods == NULL) { - __module_methods = g_hash_table_new(g_str_hash, g_str_equal); - } - - if (g_module_symbol - (module->dll, "hi_exported_methods", (gpointer)&get_methods)) { - const ShellModuleMethod *methods; - - for (methods = get_methods(); methods->name; methods++) { - ShellModuleMethod method = *methods; - gchar *name = g_path_get_basename(g_module_name(module->dll)); - gchar *simple_name = strreplace(name, "lib", ""); - - strend(simple_name, '.'); - - method_name = g_strdup_printf("%s::%s", simple_name, method.name); - g_hash_table_insert(__module_methods, method_name, - method.function); - g_free(name); - g_free(simple_name); - } - } - -} - -gchar *module_call_method(gchar * method) -{ - gchar *(*function) (void); - - if (__module_methods == NULL) { - return NULL; - } - - function = g_hash_table_lookup(__module_methods, method); - return function ? g_strdup(function()) : NULL; -} - -/* FIXME: varargs? */ -gchar *module_call_method_param(gchar * method, gchar * parameter) -{ - gchar *(*function) (gchar *param); - - if (__module_methods == NULL) { - return NULL; - } - - function = g_hash_table_lookup(__module_methods, method); - return function ? g_strdup(function(parameter)) : NULL; -} - -static gboolean remove_module_methods(gpointer key, gpointer value, gpointer data) -{ - return g_str_has_prefix(key, data); -} - -static void module_unload(ShellModule * module) -{ - GSList *entry; - - if (module->dll) { - gchar *name; - - if (module->deinit) { - DEBUG("cleaning up module \"%s\"", module->name); - module->deinit(); - } else { - DEBUG("module \"%s\" does not need cleanup", module->name); - } - - name = g_path_get_basename(g_module_name(module->dll)); - g_hash_table_foreach_remove(__module_methods, remove_module_methods, name); - - g_module_close(module->dll); - g_free(name); - } - - g_free(module->name); - g_object_unref(module->icon); - - for (entry = module->entries; entry; entry = entry->next) { - ShellModuleEntry *e = (ShellModuleEntry *)entry->data; - - g_source_remove_by_user_data(e); - g_free(e); - } - - g_slist_free(module->entries); - g_free(module); -} - - -void module_unload_all(void) -{ - Shell *shell; - GSList *module, *merge_id; - - shell = shell_get_main_shell(); - - sync_manager_clear_entries(); - shell_clear_timeouts(shell); - shell_clear_tree_models(shell); - shell_clear_field_updates(); - shell_set_title(shell, NULL); - - for (module = shell->tree->modules; module; module = module->next) { - module_unload((ShellModule *)module->data); - } - - for (merge_id = shell->merge_ids; merge_id; merge_id = merge_id->next) { - gtk_ui_manager_remove_ui(shell->ui_manager, - GPOINTER_TO_INT(merge_id->data)); - } - g_slist_free(shell->tree->modules); - g_slist_free(shell->merge_ids); - - shell->merge_ids = NULL; - shell->tree->modules = NULL; - shell->selected = NULL; -} - -static ShellModule *module_load(gchar * filename) -{ - ShellModule *module; - gchar *tmp; - - module = g_new0(ShellModule, 1); - - if (params.gui_running) { - gchar *tmpicon, *dot, *simple_name; - - tmpicon = g_strdup(filename); - dot = g_strrstr(tmpicon, "." G_MODULE_SUFFIX); - - *dot = '\0'; - - simple_name = strreplace(tmpicon, "lib", ""); - - tmp = g_strdup_printf("%s.png", simple_name); - module->icon = icon_cache_get_pixbuf(tmp); - - g_free(tmp); - g_free(tmpicon); - g_free(simple_name); - } - - tmp = g_build_filename(params.path_lib, "modules", filename, NULL); - module->dll = g_module_open(tmp, G_MODULE_BIND_LAZY); - DEBUG("gmodule resource for ``%s'' is %p (%s)", tmp, module->dll, g_module_error()); - g_free(tmp); - - if (module->dll) { - void (*init) (void); - ModuleEntry *(*get_module_entries) (void); - gint(*weight_func) (void); - gchar *(*name_func) (void); - ModuleEntry *entries; - gint i = 0; - - if (!g_module_symbol(module->dll, "hi_module_get_entries", (gpointer) & get_module_entries) || - !g_module_symbol(module->dll, "hi_module_get_name", (gpointer) & name_func)) { - DEBUG("cannot find needed symbols; is ``%s'' a real module?", filename); - goto failed; - } - - if (g_module_symbol(module->dll, "hi_module_init", (gpointer) & init)) { - DEBUG("initializing module ``%s''", filename); - init(); - } - - g_module_symbol(module->dll, "hi_module_get_weight", - (gpointer) & weight_func); - - module->weight = weight_func ? weight_func() : 0; - module->name = name_func(); - - g_module_symbol(module->dll, "hi_module_get_about", - (gpointer) & (module->aboutfunc)); - g_module_symbol(module->dll, "hi_module_deinit", - (gpointer) & (module->deinit)); - g_module_symbol(module->dll, "hi_module_get_summary", - (gpointer) & (module->summaryfunc)); - - entries = get_module_entries(); - while (entries[i].name) { - if (*entries[i].name == '#') { i++; continue; } /* skip */ - - ShellModuleEntry *entry = g_new0(ShellModuleEntry, 1); - - if (params.gui_running) { - entry->icon = icon_cache_get_pixbuf(entries[i].icon); - } - entry->icon_file = entries[i].icon; - - g_module_symbol(module->dll, "hi_more_info", - (gpointer) & (entry->morefunc)); - g_module_symbol(module->dll, "hi_get_field", - (gpointer) & (entry->fieldfunc)); - g_module_symbol(module->dll, "hi_note_func", - (gpointer) & (entry->notefunc)); - - entry->name = _(entries[i].name); //gettext unname N_() in computer.c line 67 etc... - entry->scan_func = entries[i].scan_callback; - entry->func = entries[i].callback; - entry->number = i; - entry->flags = entries[i].flags; - - module->entries = g_slist_append(module->entries, entry); - - i++; - } - - DEBUG("registering methods for module ``%s''", filename); - module_register_methods(module); - } else { - DEBUG("cannot g_module_open(``%s''). permission problem?", filename); - failed: - DEBUG("loading module %s failed: %s", filename, g_module_error()); - - g_free(module->name); - g_free(module); - module = NULL; - } - - return module; -} - -static gboolean module_in_module_list(gchar * module, gchar ** module_list) -{ - int i = 0; - - if (!module_list) - return TRUE; - - for (; module_list[i]; i++) { - if (g_str_equal(module_list[i], module)) - return TRUE; - } - - return FALSE; -} - -static gint module_cmp(gconstpointer m1, gconstpointer m2) -{ - ShellModule *a = (ShellModule *) m1; - ShellModule *b = (ShellModule *) m2; - - return a->weight - b->weight; -} - -#if 0 -static void module_entry_free(gpointer data, gpointer user_data) -{ - ShellModuleEntry *entry = (ShellModuleEntry *) data; - - if (entry) { - g_free(entry->name); - g_object_unref(entry->icon); - - g_free(entry); - } -} -#endif - -const ModuleAbout *module_get_about(ShellModule * module) -{ - if (module->aboutfunc) { - return module->aboutfunc(); - } - - return NULL; -} - -static GSList *modules_check_deps(GSList * modules) -{ - GSList *mm; - ShellModule *module; - - for (mm = modules; mm; mm = mm->next) { - gchar **(*get_deps) (void); - gchar **deps; - gint i; - - module = (ShellModule *) mm->data; - - if (g_module_symbol(module->dll, "hi_module_get_dependencies", - (gpointer) & get_deps)) { - for (i = 0, deps = get_deps(); deps[i]; i++) { - GSList *l; - ShellModule *m; - gboolean found = FALSE; - - for (l = modules; l && !found; l = l->next) { - m = (ShellModule *) l->data; - gchar *name = g_path_get_basename(g_module_name(m->dll)); - - found = g_str_equal(name, deps[i]); - g_free(name); - } - - if (!found) { - if (params.autoload_deps) { - ShellModule *mod = module_load(deps[i]); - - if (mod) - modules = g_slist_append(modules, mod); - modules = modules_check_deps(modules); /* re-check dependencies */ - - break; - } - - if (params.gui_running) { - GtkWidget *dialog; - - dialog = gtk_message_dialog_new(NULL, - GTK_DIALOG_DESTROY_WITH_PARENT, - GTK_MESSAGE_QUESTION, - GTK_BUTTONS_NONE, - _("Module \"%s\" depends on module \"%s\", load it?"), - module->name, - deps[i]); - gtk_dialog_add_buttons(GTK_DIALOG(dialog), - "_No", - GTK_RESPONSE_REJECT, - "_Open", - GTK_RESPONSE_ACCEPT, NULL); - - if (gtk_dialog_run(GTK_DIALOG(dialog)) == - GTK_RESPONSE_ACCEPT) { - ShellModule *mod = module_load(deps[i]); - - if (mod) - modules = g_slist_prepend(modules, mod); - modules = modules_check_deps(modules); /* re-check dependencies */ - } else { - g_error("HardInfo cannot run without loading the additional module."); - exit(1); - } - - gtk_widget_destroy(dialog); - } else { - g_error(_("Module \"%s\" depends on module \"%s\"."), - module->name, deps[i]); - } - } - } - } - } - - return modules; -} - - -GSList *modules_get_list() -{ - return modules_list; -} - -static GSList *modules_load(gchar ** module_list) -{ - GDir *dir; - GSList *modules = NULL; - ShellModule *module; - gchar *filename; - - filename = g_build_filename(params.path_lib, "modules", NULL); - dir = g_dir_open(filename, 0, NULL); - g_free(filename); - - if (dir) { - while ((filename = (gchar *) g_dir_read_name(dir))) { - if (g_strrstr(filename, "." G_MODULE_SUFFIX) && - module_in_module_list(filename, module_list) && - ((module = module_load(filename)))) { - modules = g_slist_prepend(modules, module); - } - } - - g_dir_close(dir); - } - - modules = modules_check_deps(modules); - - if (g_slist_length(modules) == 0) { - if (params.use_modules == NULL) { - g_error - (_("No module could be loaded. Check permissions on \"%s\" and try again."), - params.path_lib); - } else { - g_error - (_("No module could be loaded. Please use hardinfo -l to list all avai" - "lable modules and try again with a valid module list.")); - - } - } - - modules_list = g_slist_sort(modules, module_cmp); - return modules_list; -} - -GSList *modules_load_selected(void) -{ - return modules_load(params.use_modules); -} - -GSList *modules_load_all(void) -{ - return modules_load(NULL); -} - -gint tree_view_get_visible_height(GtkTreeView * tv) -{ - GtkTreePath *path; - GdkRectangle rect; - GtkTreeIter iter; - GtkTreeModel *model = gtk_tree_view_get_model(tv); - gint nrows = 1; - - path = gtk_tree_path_new_first(); - gtk_tree_view_get_cell_area(GTK_TREE_VIEW(tv), path, NULL, &rect); - - /* FIXME: isn't there any easier way to tell the number of rows? */ - gtk_tree_model_get_iter_first(model, &iter); - do { - nrows++; - } while (gtk_tree_model_iter_next(model, &iter)); - - gtk_tree_path_free(path); - - return nrows * rect.height; -} - -void module_entry_scan_all_except(ModuleEntry * entries, gint except_entry) -{ - ModuleEntry entry; - gint i = 0; - void (*scan_callback) (gboolean reload); - gchar *text; - - shell_view_set_enabled(FALSE); - - for (entry = entries[0]; entry.name; entry = entries[++i]) { - if (i == except_entry) - continue; - - text = g_strdup_printf(_("Scanning: %s..."), _(entry.name)); - shell_status_update(text); - g_free(text); - - if ((scan_callback = entry.scan_callback)) { - scan_callback(FALSE); - } - } - - shell_view_set_enabled(TRUE); - shell_status_update(_("Done.")); -} - -void module_entry_scan_all(ModuleEntry * entries) -{ - module_entry_scan_all_except(entries, -1); -} - -void module_entry_reload(ShellModuleEntry * module_entry) -{ - - if (module_entry->scan_func) { - module_entry->scan_func(TRUE); - } -} - -void module_entry_scan(ShellModuleEntry * module_entry) -{ - if (module_entry->scan_func) { - module_entry->scan_func(FALSE); - } -} - -gchar *module_entry_get_field(ShellModuleEntry * module_entry, gchar * field) -{ - if (module_entry->fieldfunc) { - return module_entry->fieldfunc(field); - } - - return NULL; -} - -gchar *module_entry_function(ShellModuleEntry * module_entry) -{ - if (module_entry->func) { - return module_entry->func(); - } - - return NULL; -} - -gchar *module_entry_get_moreinfo(ShellModuleEntry * module_entry, gchar * field) -{ - if (module_entry->morefunc) { - return module_entry->morefunc(field); - } - - return NULL; -} - -const gchar *module_entry_get_note(ShellModuleEntry * module_entry) -{ - if (module_entry->notefunc) { - return module_entry->notefunc(module_entry->number); - } - - return NULL; -} - -gchar *h_strdup_cprintf(const gchar * format, gchar * source, ...) -{ - gchar *buffer, *retn; - va_list args; - - va_start(args, source); - buffer = g_strdup_vprintf(format, args); - va_end(args); - - if (source) { - retn = g_strconcat(source, buffer, NULL); - g_free(buffer); - g_free(source); - } else { - retn = buffer; - } - - return retn; -} - -gchar *h_strconcat(gchar * string1, ...) -{ - gsize l; - va_list args; - gchar *s; - gchar *concat; - gchar *ptr; - - if (!string1) - return NULL; - - l = 1 + strlen(string1); - va_start(args, string1); - s = va_arg(args, gchar *); - while (s) { - l += strlen(s); - s = va_arg(args, gchar *); - } - va_end(args); - - concat = g_new(gchar, l); - ptr = concat; - - ptr = g_stpcpy(ptr, string1); - va_start(args, string1); - s = va_arg(args, gchar *); - while (s) { - ptr = g_stpcpy(ptr, s); - s = va_arg(args, gchar *); - } - va_end(args); - - g_free(string1); - - return concat; -} - -static gboolean h_hash_table_remove_all_true(gpointer key, gpointer data, gpointer user_data) -{ - return TRUE; -} - -void -h_hash_table_remove_all(GHashTable *hash_table) -{ - g_hash_table_foreach_remove(hash_table, - h_hash_table_remove_all_true, - NULL); -} - -gfloat -h_sysfs_read_float(const gchar *endpoint, const gchar *entry) -{ - gchar *tmp, *buffer; - gfloat return_value = 0.0f; - - tmp = g_build_filename(endpoint, entry, NULL); - if (g_file_get_contents(tmp, &buffer, NULL, NULL)) - return_value = atof(buffer); - - g_free(tmp); - g_free(buffer); - - return return_value; -} - -gint -h_sysfs_read_int(const gchar *endpoint, const gchar *entry) -{ - gchar *tmp, *buffer; - gint return_value = 0; - - tmp = g_build_filename(endpoint, entry, NULL); - if (g_file_get_contents(tmp, &buffer, NULL, NULL)) - return_value = atoi(buffer); - - g_free(tmp); - g_free(buffer); - - return return_value; -} - -gint -h_sysfs_read_hex(const gchar *endpoint, const gchar *entry) -{ - gchar *tmp, *buffer; - gint return_value = 0; - - tmp = g_build_filename(endpoint, entry, NULL); - if (g_file_get_contents(tmp, &buffer, NULL, NULL)) - return_value = (gint) strtoll(buffer, NULL, 16); - - g_free(tmp); - g_free(buffer); - - return return_value; -} - -gchar * -h_sysfs_read_string(const gchar *endpoint, const gchar *entry) -{ - gchar *tmp, *return_value; - - tmp = g_build_filename(endpoint, entry, NULL); - if (!g_file_get_contents(tmp, &return_value, NULL, NULL)) { - g_free(return_value); - - return_value = NULL; - } else { - return_value = g_strstrip(return_value); - } - - g_free(tmp); - - return return_value; -} - -static GHashTable *_moreinfo = NULL; - -void -moreinfo_init(void) -{ - if (G_UNLIKELY(_moreinfo)) { - DEBUG("moreinfo already initialized"); - return; - } - DEBUG("initializing moreinfo"); - _moreinfo = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, g_free); -} - -void -moreinfo_shutdown(void) -{ - if (G_UNLIKELY(!_moreinfo)) { - DEBUG("moreinfo not initialized"); - return; - } - DEBUG("shutting down moreinfo"); - g_hash_table_destroy(_moreinfo); - _moreinfo = NULL; -} - -void -moreinfo_add_with_prefix(gchar *prefix, gchar *key, gchar *value) -{ - if (G_UNLIKELY(!_moreinfo)) { - DEBUG("moreinfo not initialized"); - return; - } - - if (prefix) { - gchar *hashkey = g_strconcat(prefix, ":", key, NULL); - g_hash_table_insert(_moreinfo, hashkey, value); - return; - } - - g_hash_table_insert(_moreinfo, g_strdup(key), value); -} - -void -moreinfo_add(gchar *key, gchar *value) -{ - moreinfo_add_with_prefix(NULL, key, value); -} - -static gboolean -_moreinfo_del_cb(gpointer key, gpointer value, gpointer data) -{ - return g_str_has_prefix(key, data); -} - -void -moreinfo_del_with_prefix(gchar *prefix) -{ - if (G_UNLIKELY(!_moreinfo)) { - DEBUG("moreinfo not initialized"); - return; - } - - g_hash_table_foreach_remove(_moreinfo, _moreinfo_del_cb, prefix); -} - -void -moreinfo_clear(void) -{ - if (G_UNLIKELY(!_moreinfo)) { - DEBUG("moreinfo not initialized"); - return; - } - h_hash_table_remove_all(_moreinfo); -} - -gchar * -moreinfo_lookup_with_prefix(gchar *prefix, gchar *key) -{ - if (G_UNLIKELY(!_moreinfo)) { - DEBUG("moreinfo not initialized"); - return 0; - } - - if (prefix) { - gchar *lookup_key = g_strconcat(prefix, ":", key, NULL); - gchar *result = g_hash_table_lookup(_moreinfo, lookup_key); - g_free(lookup_key); - return result; - } - - return g_hash_table_lookup(_moreinfo, key); -} - -gchar * -moreinfo_lookup(gchar *key) -{ - return moreinfo_lookup_with_prefix(NULL, key); -} - -#if !GLIB_CHECK_VERSION(2,44,0) -gboolean g_strv_contains(const gchar * const * strv, const gchar *str) { - /* g_strv_contains() requires glib>2.44 - * fallback for older versions */ - gint i = 0; - while(strv[i] != NULL) { - if (g_strcmp0(strv[i], str) == 0) - return 1; - i++; - } - return 0; -} -#endif - -gchar *hardinfo_clean_grpname(const gchar *v, int replacing) { - gchar *clean, *p; - - p = clean = g_strdup(v); - while (*p != 0) { - switch(*p) { - case '[': - *p = '('; break; - case ']': - *p = ')'; break; - default: - break; - } - p++; - } - if (replacing) - g_free((gpointer)v); - return clean; -} - -/* Hardinfo labels that have # are truncated and/or hidden. - * Labels can't have $ because that is the delimiter in - * moreinfo. */ -gchar *hardinfo_clean_label(const gchar *v, int replacing) { - gchar *clean, *p; - - p = clean = g_strdup(v); - while (*p != 0) { - switch(*p) { - case '#': case '$': - *p = '_'; - break; - default: - break; - } - p++; - } - if (replacing) - g_free((gpointer)v); - return clean; -} - -/* hardinfo uses the values as {ht,x}ml, apparently */ -gchar *hardinfo_clean_value(const gchar *v, int replacing) { - gchar *clean, *tmp; - gchar **vl; - if (v == NULL) return NULL; - - vl = g_strsplit(v, "&", -1); - if (g_strv_length(vl) > 1) - clean = g_strjoinv("&", vl); - else - clean = g_strdup(v); - g_strfreev(vl); - - vl = g_strsplit(clean, "<", -1); - if (g_strv_length(vl) > 1) { - tmp = g_strjoinv("<", vl); - g_free(clean); - clean = tmp; - } - g_strfreev(vl); - - vl = g_strsplit(clean, ">", -1); - if (g_strv_length(vl) > 1) { - tmp = g_strjoinv(">", vl); - g_free(clean); - clean = tmp; - } - g_strfreev(vl); - - if (replacing) - g_free((gpointer)v); - return clean; -} - -gboolean hardinfo_spawn_command_line_sync(const gchar *command_line, - gchar **standard_output, - gchar **standard_error, - gint *exit_status, - GError **error) -{ - shell_status_pulse(); - return g_spawn_command_line_sync(command_line, standard_output, - standard_error, exit_status, error); -} diff --git a/hardinfo/vendor.c b/hardinfo/vendor.c deleted file mode 100644 index cb9cc9ba..00000000 --- a/hardinfo/vendor.c +++ /dev/null @@ -1,655 +0,0 @@ -/* - * HardInfo - Displays System Information - * Copyright (C) 2003-2009 L. A. F. Pereira <l@tia.mat.br> - * - * List of vendors based on GtkSysInfo (c) Pissens Sebastien. - * - * 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. - * - * This program 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include <string.h> -#include <gtk/gtk.h> - -#include "vendor.h" -#include "syncmanager.h" -#include "config.h" -#include "hardinfo.h" -#include "strstr_word.h" -#include "util_sysobj.h" /* for appfsp() and SEQ() */ - -/* { match_string, match_rule, name, url } */ -static Vendor vendors_builtin[] = { - /* BIOS manufacturers */ - { "American Megatrends", 0, "American Megatrends", "www.ami.com"}, - { "Award", 0, "Award Software International", "www.award-bios.com"}, - { "Phoenix", 0, "Phoenix Technologies", "www.phoenix.com"}, - /* x86 vendor strings */ - { "AMDisbetter!", 0, "Advanced Micro Devices", "www.amd.com" }, - { "AuthenticAMD", 0, "Advanced Micro Devices", "www.amd.com" }, - { "CentaurHauls", 0, "VIA (formerly Centaur Technology)", "www.via.tw" }, - { "CyrixInstead", 0, "Cyrix", "" }, - { "GenuineIntel", 0, "Intel", "www.intel.com" }, - { "TransmetaCPU", 0, "Transmeta", "" }, - { "GenuineTMx86", 0, "Transmeta", "" }, - { "Geode by NSC", 0, "National Semiconductor", "" }, - { "NexGenDriven", 0, "NexGen", "" }, - { "RiseRiseRise", 0, "Rise Technology", "" }, - { "SiS SiS SiS", 0, "Silicon Integrated Systems", "" }, - { "UMC UMC UMC", 0, "United Microelectronics Corporation", "" }, - { "VIA VIA VIA", 0, "VIA", "www.via.tw" }, - { "Vortex86 SoC", 0, "DMP Electronics", "" }, - /* x86 VM vendor strings */ - { "KVMKVMKVM", 0, "KVM", "" }, - { "Microsoft Hv", 0, "Microsoft Hyper-V", "www.microsoft.com" }, - { "lrpepyh vr", 0, "Parallels", "" }, - { "VMwareVMware", 0, "VMware", "" }, - { "XenVMMXenVMM", 0, "Xen HVM", "" }, -}; - -#define ven_msg(msg, ...) fprintf (stderr, "[%s] " msg "\n", __FUNCTION__, ##__VA_ARGS__) /**/ -#define ven_file_err(msg, ...) { \ - ven_msg(msg, ##__VA_ARGS__); \ - fflush(stderr); \ - if (vendor_die_on_error) exit(-1); } - -static vendor_list vendors = NULL; -const vendor_list get_vendors_list() { return vendors; } -gboolean vendor_die_on_error = FALSE; - -/* sort the vendor list by length of match_string, - * LONGEST first */ -int vendor_sort (const Vendor *ap, const Vendor *bp) { - int la = 0, lb = 0; - if (ap) la = ap->weight; - if (bp) lb = bp->weight; - return lb-la; -} - -static int read_from_vendor_conf(const char *path) { - GKeyFile *vendors_file; - gchar *tmp; - gint num_vendors, i, count = 0; /* num_vendors is file-reported, count is actual */ - - DEBUG("using vendor.conf format loader for %s", path); - - vendors_file = g_key_file_new(); - if (g_key_file_load_from_file(vendors_file, path, 0, NULL)) { - num_vendors = g_key_file_get_integer(vendors_file, "vendors", "number", NULL); - - for (i = num_vendors - 1; i >= 0; i--) { - Vendor *v = g_new0(Vendor, 1); - - tmp = g_strdup_printf("vendor%d", i); - - v->match_string = g_key_file_get_string(vendors_file, tmp, "match_string", NULL); - if (v->match_string == NULL) { - /* try old name */ - v->match_string = g_key_file_get_string(vendors_file, tmp, "id", NULL); - } - if (v->match_string) { - v->match_rule = g_key_file_get_integer(vendors_file, tmp, "match_case", NULL); - v->name = g_key_file_get_string(vendors_file, tmp, "name", NULL); - v->name_short = g_key_file_get_string(vendors_file, tmp, "name_short", NULL); - v->url = g_key_file_get_string(vendors_file, tmp, "url", NULL); - v->url_support = g_key_file_get_string(vendors_file, tmp, "url_support", NULL); - - vendors = g_slist_prepend(vendors, v); - count++; - } else { - /* don't add if match_string is null */ - g_free(v); - } - - g_free(tmp); - } - g_key_file_free(vendors_file); - DEBUG("... found %d match strings", count); - return count; - } - g_key_file_free(vendors_file); - return 0; -} - -static int read_from_vendor_ids(const char *path) { -#define VEN_BUFF_SIZE 128 -#define VEN_FFWD() while(isspace((unsigned char)*p)) p++; -#define VEN_CHK(TOK) (strncmp(p, TOK, tl = strlen(TOK)) == 0 && (ok = 1)) - char buff[VEN_BUFF_SIZE] = ""; - - char vars[7][VEN_BUFF_SIZE]; - char *name = vars[0]; - char *name_short = vars[1]; - char *url = vars[2]; - char *url_support = vars[3]; - char *wikipedia = vars[4]; - char *note = vars[5]; - char *ansi_color = vars[6]; - int name_rule_count = -1; - - int count = 0; - FILE *fd; - char *p, *b; - int tl, line = -1, ok = 0; - - DEBUG("using vendor.ids format loader for %s", path); - - fd = fopen(path, "r"); - if (!fd) return 0; - - while (fgets(buff, VEN_BUFF_SIZE, fd)) { - ok = 0; - line++; - - b = strchr(buff, '\n'); - if (b) - *b = 0; - else - ven_file_err("%s:%d: line longer than VEN_BUFF_SIZE (%lu)", path, line, (unsigned long)VEN_BUFF_SIZE); - - b = strchr(buff, '#'); - if (b) *b = 0; /* line ends at comment */ - - p = buff; - VEN_FFWD(); - if (VEN_CHK("name ")) { - if (name_rule_count == 0) - ven_file_err("%s:%d: name \"%s\" had no match rules", path, line, name); - strncpy(name, p + tl, VEN_BUFF_SIZE - 1); - strcpy(name_short, ""); - strcpy(url, ""); - strcpy(url_support, ""); - strcpy(wikipedia, ""); - strcpy(note, ""); - strcpy(ansi_color, ""); - name_rule_count = 0; - } - if (VEN_CHK("name_short ")) - strncpy(name_short, p + tl, VEN_BUFF_SIZE - 1); - if (VEN_CHK("url ")) - strncpy(url, p + tl, VEN_BUFF_SIZE - 1); - if (VEN_CHK("url_support ")) - strncpy(url_support, p + tl, VEN_BUFF_SIZE - 1); - if (VEN_CHK("wikipedia ")) - strncpy(wikipedia, p + tl, VEN_BUFF_SIZE - 1); - if (VEN_CHK("note ")) - strncpy(note, p + tl, VEN_BUFF_SIZE - 1); - if (VEN_CHK("ansi_color ")) - strncpy(ansi_color, p + tl, VEN_BUFF_SIZE - 1); - -#define dup_if_not_empty(s) (strlen(s) ? g_strdup(s) : NULL) - - int mrule = -1; - if (VEN_CHK("match_string ")) - mrule = VENDOR_MATCH_RULE_WORD_IGNORE_CASE; - else if (VEN_CHK("match_string_case ")) - mrule = VENDOR_MATCH_RULE_WORD_MATCH_CASE; - else if (VEN_CHK("match_string_exact ")) - mrule = VENDOR_MATCH_RULE_EXACT; - else if (VEN_CHK("match_string_prefix ")) - mrule = VENDOR_MATCH_RULE_WORD_PREFIX_IGNORE_CASE; - else if (VEN_CHK("match_string_prefix_case ")) - mrule = VENDOR_MATCH_RULE_WORD_PREFIX_MATCH_CASE; - else if (VEN_CHK("match_string_suffix ")) - mrule = VENDOR_MATCH_RULE_WORD_PREFIX_IGNORE_CASE; - else if (VEN_CHK("match_string_suffix_case ")) - mrule = VENDOR_MATCH_RULE_WORD_PREFIX_MATCH_CASE; - else if (VEN_CHK("match_string_num_prefix ")) - mrule = VENDOR_MATCH_RULE_NUM_PREFIX_IGNORE_CASE; - else if (VEN_CHK("match_string_num_prefix_case ")) - mrule = VENDOR_MATCH_RULE_NUM_PREFIX_MATCH_CASE; - - if (mrule >= 0) { - Vendor *v = g_new0(Vendor, 1); - v->file_line = line; - v->match_string = g_strdup(p+tl); - v->ms_length = strlen(v->match_string); - v->match_rule = mrule; - v->name = g_strdup(name); - v->name_short = dup_if_not_empty(name_short); - v->url = dup_if_not_empty(url); - v->url_support = dup_if_not_empty(url_support); - v->wikipedia = dup_if_not_empty(wikipedia); - v->note = dup_if_not_empty(note); - v->ansi_color = dup_if_not_empty(ansi_color); - - v->weight = v->ms_length; - /* NUM_PREFIX rules consider +1 characters */ - if (v->match_rule == VENDOR_MATCH_RULE_NUM_PREFIX_MATCH_CASE - || v->match_rule == VENDOR_MATCH_RULE_NUM_PREFIX_IGNORE_CASE) - v->weight++; - - v->has_parens = g_utf8_strchr(v->match_string, -1, '(') ? TRUE : FALSE; - - vendors = g_slist_prepend(vendors, v); - name_rule_count++; - count++; - } - - g_strstrip(buff); - if (!ok && *buff != 0) - ven_file_err("unrecognised item at %s:%d, %s", path, line, buff); - } - - fclose(fd); - - DEBUG("... found %d match strings", count); - - return count; -} - -void vendor_init(void) -{ - gchar *path; - static SyncEntry se = { - .name = N_("Update vendor list"), - .file_name = "vendor.ids", - }; - - /* already initialized */ - if (vendors) return; - - DEBUG("initializing vendor list"); - sync_manager_add_entry(&se); - - char *file_search_order[] = { - /* new format */ - g_build_filename(g_get_user_config_dir(), "hardinfo", "vendor.ids", NULL), - g_build_filename(params.path_data, "vendor.ids", NULL), - /* old format */ - g_build_filename(g_get_user_config_dir(), "hardinfo", "vendor.conf", NULL), - g_build_filename(g_get_home_dir(), ".hardinfo", "vendor.conf", NULL), /* old place */ - g_build_filename(params.path_data, "vendor.conf", NULL), - NULL - }; - - int n = 0; - while (file_search_order[n]) { - DEBUG("searching for vendor data at %s ...", file_search_order[n]); - if (!access(file_search_order[n], R_OK)) { - path = file_search_order[n]; - DEBUG("... file exists."); - break; - } - n++; - } - - int fail = 1; - - /* new format */ - if (path && strstr(path, "vendor.ids")) { - fail = !read_from_vendor_ids(path); - } - - /* old format */ - if (path && strstr(path, "vendor.conf")) { - fail = !read_from_vendor_conf(path); - } - - if (fail) { - gint i; - - DEBUG("vendor data not found, using internal database"); - - for (i = G_N_ELEMENTS(vendors_builtin) - 1; i >= 0; i--) { - vendors = g_slist_prepend(vendors, (gpointer) &vendors_builtin[i]); - } - } - - /* sort the vendor list by length of match string so that short strings are - * less likely to incorrectly match. - * example: ST matches ASUSTeK but SEAGATE is not ASUS */ - vendors = g_slist_sort(vendors, (GCompareFunc)vendor_sort); - - /* free search location strings */ - n = 0; - while (file_search_order[n]) { - free(file_search_order[n]); - n++; - } -} - -void vendor_cleanup() { - DEBUG("cleanup vendor list"); - g_slist_free_full(vendors, (GDestroyNotify)vendor_free); -} - -void vendor_free(Vendor *v) { - if (v) { - g_free(v->name); - g_free(v->name_short); - g_free(v->url); - g_free(v->url_support); - g_free(v->ansi_color); - g_free(v->match_string); - g_free(v); - } -} - -const Vendor *vendor_match(const gchar *id_str, ...) { - Vendor *ret = NULL; - va_list ap, ap2; - gchar *tmp = NULL, *p = NULL; - int tl = 0, c = 0; - - if (id_str) { - c++; - tl += strlen(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 = appfsp(tmp, "%s", p); - p = va_arg(ap, gchar*); - } - va_end(ap); - } - if (!c || tl == 0) - return NULL; - - vendor_list vl = vendors_match_core(tmp, 1); - if (vl) { - ret = (Vendor*)vl->data; - vendor_list_free(vl); - } - return ret; -} - -static const gchar *vendor_get_name_ex(const gchar * id_str, short shortest) { - const Vendor *v = vendor_match(id_str, NULL); - - if (v) { - if (shortest) { - int sl = strlen(id_str); - int nl = (v->name) ? strlen(v->name) : 0; - int snl = (v->name_short) ? strlen(v->name_short) : 0; - if (!nl) nl = 9999; - if (!snl) snl = 9999; - /* if id_str is shortest, then return as if - * not found (see below). - * if all equal then prefer - * name_short > name > id_str. */ - if (nl < snl) - return (sl < nl) ? id_str : v->name; - else - return (sl < snl) ? id_str : v->name_short; - } else - return v->name; - } - - return id_str; /* Preserve an old behavior, but what about const? */ -} - -const gchar *vendor_get_name(const gchar * id_str) { - return vendor_get_name_ex(id_str, 0); -} - -const gchar *vendor_get_shortest_name(const gchar * id_str) { - return vendor_get_name_ex(id_str, 1); -} - -const gchar *vendor_get_url(const gchar * id_str) { - const Vendor *v = vendor_match(id_str, NULL); - - if (v) - return v->url; - - return NULL; -} - -gchar *vendor_get_link(const gchar *id_str) -{ - const Vendor *v = vendor_match(id_str, NULL); - - if (!v) { - return g_strdup(id_str); - } - - return vendor_get_link_from_vendor(v); -} - -gchar *vendor_get_link_from_vendor(const Vendor *v) -{ -#if GTK_CHECK_VERSION(2, 18, 0) - gboolean gtk_label_link_ok = TRUE; -#else - gboolean gtk_label_link_ok = FALSE; -#endif - gboolean link_ok = params.markup_ok && gtk_label_link_ok; - /* If using a real link, and wikipedia is available, - * target that instead of url. There's usually much more - * information there, plus easily click through to company url. */ - gboolean link_wikipedia = TRUE; - - if (!v) - return g_strdup(_("Unknown")); - - gchar *url = NULL; - - if (link_ok && link_wikipedia && v->wikipedia - || v->wikipedia && !v->url) - url = g_strdup_printf("http://wikipedia.com/wiki/%s", v->wikipedia); - else if (v->url) - url = g_strdup(v->url); - - if (!url) - return g_strdup(v->name); - - auto_free(url); - - if (link_ok) { - const gchar *prefix; - - if (!strncmp(url, "http://", sizeof("http://") - 1) || - !strncmp(url, "https://", sizeof("https://") - 1)) { - prefix = ""; - } else { - prefix = "http://"; - } - - return g_strdup_printf("<a href=\"%s%s\">%s</a>", prefix, url, v->name); - } - - return g_strdup_printf("%s (%s)", v->name, url); -} - -vendor_list vendor_list_concat_va(int count, vendor_list vl, ...) { - vendor_list ret = vl, p = NULL; - va_list ap; - va_start(ap, vl); - if (count > 0) { - count--; /* includes vl */ - while (count) { - p = va_arg(ap, vendor_list); - ret = g_slist_concat(ret, p); - count--; - } - } else { - p = va_arg(ap, vendor_list); - while (p) { - ret = g_slist_concat(ret, p); - p = va_arg(ap, vendor_list); - } - } - va_end(ap); - return ret; -} - -int vendor_cmp_deep(const Vendor *a, const Vendor *b) { - int r; - if (a && !b) return 1; - if (!a && b) return -1; - if (!a && !b) return 0; - r = g_strcmp0(a->name, b->name); - if (!!r) return r; - r = g_strcmp0(a->name_short, b->name_short); - if (!!r) return r; - r = g_strcmp0(a->ansi_color, b->ansi_color); - if (!!r) return r; - r = g_strcmp0(a->url, b->url); - if (!!r) return r; - r = g_strcmp0(a->url_support, b->url_support); - if (!!r) return r; - r = g_strcmp0(a->wikipedia, b->wikipedia); - if (!!r) return r; - return 0; -} - -vendor_list vendor_list_remove_duplicates_deep(vendor_list vl) { - /* vendor_list is GSList* */ - GSList *tvl = vl; - GSList *evl = NULL; - while(tvl) { - const Vendor *tv = tvl->data; - evl = tvl->next; - while(evl) { - const Vendor *ev = evl->data; - if (vendor_cmp_deep(ev, tv) == 0) { - GSList *next = evl->next; - vl = g_slist_delete_link(vl, evl); - evl = next; - } else - evl = evl->next; - } - tvl = tvl->next; - } - return vl; -} - -vendor_list vendors_match(const gchar *id_str, ...) { - va_list ap, ap2; - gchar *tmp = NULL, *p = NULL; - int tl = 0, c = 0; - - if (id_str) { - c++; - tl += strlen(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 = appfsp(tmp, "%s", p); - p = va_arg(ap, gchar*); - } - va_end(ap); - } - if (!c || tl == 0) - return NULL; - - return vendors_match_core(tmp, -1); -} - -vendor_list vendors_match_core(const gchar *str, int limit) { - gchar *p = NULL; - GSList *vlp; - int found = 0; - vendor_list ret = NULL; - - /* pass [array_index]: function - * 1st [3]: only check match strings that have () in them - * 2nd [2]: ignore text in (), like (formerly ...) or (nee ...), - * but unfortunately also (now ...) - * 3rd [1]: (passes[0]): full text */ - gchar *passes[3] = { g_strdup(str), g_strdup(str), g_strdup(str) }; - int pass = 1; p = passes[1]; - while((p = strchr(p, '('))) { - pass = 3; p++; - while(*p && *p != ')') { *p = ' '; p++; } - } - - for (; pass > 0; pass--) { - for (vlp = vendors; vlp; vlp = vlp->next) { - Vendor *v = (Vendor *)vlp->data; - char *m = NULL; - - if (!v) continue; - if (!v->match_string) continue; - - if (v->has_parens) - if (pass != 3) continue; - - //ven_msg("pass:%d <<%s>> EXAMINE: \"%s\"", pass, v->match_string, passes[pass-1]); - int epass; - -#define standard_match_work_inner(fn) { \ - /* clear so it doesn't match again */ \ - for(epass = pass; epass > 0; epass--) \ - { char *s = passes[epass-1] + (m - passes[pass-1]); \ - char *e = s + v->ms_length; \ - for(; s < e; s++) *s = ' '; \ - g_strstrip(passes[epass-1]); } \ - /* add to return list */ \ - ret = vendor_list_append(ret, v); \ - found++; \ - if (*passes[0] == 0) \ - goto vendors_match_core_finish; \ - if (limit > 0 && found >= limit) \ - goto vendors_match_core_finish; } -#define standard_match_work(fn) \ - if ((m = fn(passes[pass-1], v->match_string))) \ - standard_match_work_inner(); - - switch(v->match_rule) { - case VENDOR_MATCH_RULE_EXACT: - if (SEQ(passes[pass-1], v->match_string) ) { - /* add to return list */ - ret = vendor_list_append(ret, v); - found++; - goto vendors_match_core_finish; /* no way for any other match to happen */ - } - break; - case VENDOR_MATCH_RULE_WORD_IGNORE_CASE: - standard_match_work(strcasestr_word); - break; - case VENDOR_MATCH_RULE_WORD_MATCH_CASE: - standard_match_work(strstr_word); - break; - case VENDOR_MATCH_RULE_WORD_PREFIX_MATCH_CASE: - standard_match_work(strstr_word_prefix); - break; - case VENDOR_MATCH_RULE_WORD_PREFIX_IGNORE_CASE: - standard_match_work(strcasestr_word_prefix); - break; - case VENDOR_MATCH_RULE_WORD_SUFFIX_MATCH_CASE: - standard_match_work(strstr_word_suffix); - break; - case VENDOR_MATCH_RULE_WORD_SUFFIX_IGNORE_CASE: - standard_match_work(strcasestr_word_suffix); - break; - case VENDOR_MATCH_RULE_NUM_PREFIX_IGNORE_CASE: - if ((m = strstr_word_prefix(passes[pass-1], v->match_string))) - if (isdigit(m[v->ms_length])) - standard_match_work_inner(); - break; - case VENDOR_MATCH_RULE_NUM_PREFIX_MATCH_CASE: - if ((m = strcasestr_word_prefix(passes[pass-1], v->match_string))) - if (isdigit(m[v->ms_length])) - standard_match_work_inner(); - break; - } - } - } - -vendors_match_core_finish: - - g_free(passes[0]); - g_free(passes[1]); - g_free(passes[2]); - return ret; -} diff --git a/hardinfo/x_util.c b/hardinfo/x_util.c deleted file mode 100644 index 2187b224..00000000 --- a/hardinfo/x_util.c +++ /dev/null @@ -1,342 +0,0 @@ -/* - * HardInfo - Displays System Information - * Copyright (C) 2003-2017 L. A. F. Pereira <l@tia.mat.br> - * This file - * Copyright (C) 2018 Burt P. <pburt0@gmail.com> - * - * 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. - * - * This program 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "hardinfo.h" -#include "x_util.h" -#include <X11/Xlib.h> - -/* wayland stuff lives here for now */ - -wl_info *get_walyand_info() { - wl_info *s = malloc(sizeof(wl_info)); - memset(s, 0, sizeof(wl_info)); - s->xdg_session_type = g_strdup( getenv("XDG_SESSION_TYPE") ); - if (s->xdg_session_type == NULL) - s->xdg_session_type = strdup("x11"); - s->display_name = g_strdup( getenv("WAYLAND_DISPLAY") ); - return s; -} - -void wl_free(wl_info *s) { - if (s) { - free(s->xdg_session_type); - free(s->display_name); - free(s); - } -} - -/* get x information from xrandr, xdpyinfo, and glxinfo */ - -static char *simple_line_value(char *line, const char *prefix) { - if (g_str_has_prefix(g_strstrip(line), prefix)) { - line += strlen(prefix) + 1; - return g_strstrip(line); - } else - return NULL; -} - -gboolean fill_glx_info(glx_info *glx) { - gboolean spawned; - gchar *out, *err, *p, *l, *next_nl; - gchar *glx_cmd = g_strdup("glxinfo"); - -#define GLX_MATCH_LINE(prefix_str, struct_member) \ - if (l = simple_line_value(p, prefix_str)) { glx->struct_member = g_strdup(l); goto glx_next_line; } - - spawned = hardinfo_spawn_command_line_sync(glx_cmd, - &out, &err, NULL, NULL); - g_free(glx_cmd); - if (spawned) { - p = out; - while(next_nl = strchr(p, '\n')) { - strend(p, '\n'); - g_strstrip(p); - GLX_MATCH_LINE("GLX version", glx_version); - GLX_MATCH_LINE("OpenGL vendor string", ogl_vendor); - GLX_MATCH_LINE("OpenGL renderer string", ogl_renderer); - GLX_MATCH_LINE("OpenGL renderer string", ogl_renderer); - GLX_MATCH_LINE("OpenGL core profile version string", ogl_core_version); - GLX_MATCH_LINE("OpenGL core profile shading language version string", ogl_core_sl_version); - GLX_MATCH_LINE("OpenGL version string", ogl_version); - GLX_MATCH_LINE("OpenGL shading language version string", ogl_sl_version); - GLX_MATCH_LINE("OpenGL ES profile version string", ogles_version); - GLX_MATCH_LINE("OpenGL ES profile shading language version string", ogles_sl_version); - - if (l = simple_line_value(p, "direct rendering")) { - if (strstr(p, "Yes")) - glx->direct_rendering = 1; - goto glx_next_line; - } - - glx_next_line: - p = next_nl + 1; - } - g_free(out); - g_free(err); - return TRUE; - } - return FALSE; -} - -glx_info *glx_create() { - glx_info *s = malloc(sizeof(glx_info)); - memset(s, 0, sizeof(glx_info)); - return s; -} - -void glx_free(glx_info *s) { - if (s) { - free(s->glx_version); - free(s->ogl_vendor); - free(s->ogl_renderer); - free(s->ogl_core_version); - free(s->ogl_core_sl_version); - free(s->ogl_version); - free(s->ogl_sl_version); - free(s->ogles_version); - free(s->ogles_sl_version); - free(s); - } -} - -gboolean fill_xinfo(xinfo *xi) { - gboolean spawned; - gchar *out, *err, *p, *l, *next_nl; - gchar *xi_cmd = g_strdup("xdpyinfo"); - -#define XI_MATCH_LINE(prefix_str, struct_member) \ - if (l = simple_line_value(p, prefix_str)) { xi->struct_member = g_strdup(l); goto xi_next_line; } - - spawned = hardinfo_spawn_command_line_sync(xi_cmd, - &out, &err, NULL, NULL); - g_free(xi_cmd); - if (spawned) { - p = out; - while(next_nl = strchr(p, '\n')) { - strend(p, '\n'); - g_strstrip(p); - XI_MATCH_LINE("name of display", display_name); - XI_MATCH_LINE("vendor string", vendor); - XI_MATCH_LINE("vendor release number", release_number); - XI_MATCH_LINE("XFree86 version", version); - XI_MATCH_LINE("X.Org version", version); - - xi_next_line: - p = next_nl + 1; - } - g_free(out); - g_free(err); - return TRUE; - } - return FALSE; -} - -gboolean fill_xrr_info(xrr_info *xrr) { - gboolean spawned; - gchar *out, *err, *p, *next_nl; - gchar *xrr_cmd = g_strdup("xrandr --prop"); - int ec; - - x_screen ts; - x_output to; - char output_id[128]; - char status[128]; - char alist[512]; - - memset(&ts, 0, sizeof(x_screen)); - memset(&to, 0, sizeof(x_output)); - memset(output_id, 0, sizeof(output_id)); - memset(status, 0, sizeof(status)); - memset(alist, 0, sizeof(alist)); - - spawned = hardinfo_spawn_command_line_sync(xrr_cmd, - &out, &err, NULL, NULL); - g_free(xrr_cmd); - if (spawned) { - p = out; - while(next_nl = strchr(p, '\n')) { - strend(p, '\n'); - g_strstrip(p); - - ec = sscanf(p, "Screen %d: minimum %d x %d, current %d x %d, maximum %d x %d", - &ts.number, - &ts.min_px_width, &ts.min_px_height, - &ts.px_width, &ts.px_height, - &ts.max_px_width, &ts.max_px_height); - if (ec == 7) { - /* new screen */ - xrr->screen_count++; - if (xrr->screens == NULL) - xrr->screens = malloc(xrr->screen_count * sizeof(x_screen)); - else - xrr->screens = realloc(xrr->screens, xrr->screen_count * sizeof(x_screen)); - memcpy(&xrr->screens[xrr->screen_count-1], &ts, sizeof(x_screen)); - memset(&ts, 0, sizeof(x_screen)); /* clear the temp */ - goto xrr_next_line; - } - - /* looking for: - * <output_id> (connected|disconnected|unknown connection) (primary|?) <%dx%d+%d+%d> (attribute_list) mm x mm - */ - ec = sscanf(p, "%127s %127[^(](%511[^)]", output_id, status, alist); - if (ec == 3) { - int is_output = 0, found_rect = 0, n = 0; - gchar **ot = g_strsplit(status, " ", 0); - - /* find rect */ - while (ot[n] != NULL) { - ec = sscanf(ot[n], "%dx%d+%d+%d", &to.px_width, &to.px_height, &to.px_offset_x, &to.px_offset_y); - if (ec == 4) { - found_rect = 1; - break; - } - n++; - } - if (found_rect) - to.screen = xrr->screen_count - 1; - else - to.screen = -1; - - if (strcmp("disconnected", ot[0]) == 0) { - is_output = 1; - to.connected = 0; - } else - if (strcmp("unknown", ot[0]) == 0 && strcmp("connection", ot[1]) == 0) { - is_output = 1; - to.connected = -1; - } else - if (strcmp("connected", ot[0]) == 0) { - is_output = 1; - to.connected = 1; - } - g_strfreev(ot); - if (is_output) { - strncpy(to.name, output_id, 63); - xrr->output_count++; - if (xrr->outputs == NULL) - xrr->outputs = malloc(xrr->output_count * sizeof(x_output)); - else - xrr->outputs = realloc(xrr->outputs, xrr->output_count * sizeof(x_output)); - memcpy(&xrr->outputs[xrr->output_count-1], &to, sizeof(x_output)); - memset(&to, 0, sizeof(x_output)); /* clear the temp */ - goto xrr_next_line; - } - } - - xrr_next_line: - p = next_nl + 1; - } - g_free(out); - g_free(err); - return TRUE; - } - return FALSE; -} - -gboolean fill_basic_xlib(xinfo *xi) { - Display *display; - int s, w, h, rn; - - display = XOpenDisplay(NULL); - if (display) { - if (!xi->display_name) - xi->display_name = XDisplayName(NULL); - - if (!xi->vendor) - xi->vendor = XServerVendor(display); - - if (!xi->release_number) { - rn = XVendorRelease(display); - xi->release_number = g_strdup_printf("%d", rn); - } - - if (!xi->xrr->screen_count) { - s = DefaultScreen(display); - w = XDisplayWidth(display, s); - h = XDisplayHeight(display, s); - - /* create at least one screen */ - x_screen ts; - memset(&ts, 0, sizeof(x_screen)); - ts.number = s; - ts.px_width = w; - ts.px_height = h; - - xi->xrr->screen_count++; - if (xi->xrr->screens == NULL) - xi->xrr->screens = malloc(xi->xrr->screen_count * sizeof(x_screen)); - else - xi->xrr->screens = realloc(xi->xrr->screens, xi->xrr->screen_count * sizeof(x_screen)); - memcpy(&xi->xrr->screens[xi->xrr->screen_count-1], &ts, sizeof(x_screen)); - } - return TRUE; - } - return FALSE; -} - -xrr_info *xrr_create() { - xrr_info *xrr = malloc(sizeof(xrr_info)); - memset(xrr, 0, sizeof(xrr_info)); - return xrr; -} - -void xrr_free(xrr_info *xrr) { - if (xrr) { - free(xrr->screens); - free(xrr->outputs); - free(xrr->providers); - free(xrr->monitors); - free(xrr); - } -} - -xinfo *xinfo_get_info() { - int fail = 0; - xinfo *xi = malloc(sizeof(xinfo)); - memset(xi, 0, sizeof(xinfo)); - xi->glx = glx_create(); - xi->xrr = xrr_create(); - - if ( !fill_xinfo(xi) ) - fail++; - if ( !fill_xrr_info(xi->xrr) ) - fail++; - if ( !fill_glx_info(xi->glx) ) - fail++; - - if (fail) { - /* as fallback, try xlib directly */ - if ( !fill_basic_xlib(xi) ) - xi->nox = 1; - } - return xi; -} - -void xinfo_free(xinfo *xi) { - if (xi) { - free(xi->display_name); - free(xi->vendor); - free(xi->version); - free(xi->release_number); - xrr_free(xi->xrr); - glx_free(xi->glx); - free(xi); - } -} |