summaryrefslogtreecommitdiff
path: root/modules
diff options
context:
space:
mode:
authorSimon Quigley <tsimonq2@ubuntu.com>2017-08-16 04:32:39 -0500
committerSimon Quigley <tsimonq2@ubuntu.com>2017-08-16 04:32:39 -0500
commit9a9db98089717990cd5e0eef529f6bb0819ebe46 (patch)
treea9afaabce984d5fe552fa8bf1a9405db9bdd2699 /modules
parent69a2124e9a081518297951256eb5c8d72d93361f (diff)
New upstream version 0.5.1+git20170815
Diffstat (limited to 'modules')
-rw-r--r--modules/benchmark.c100
-rw-r--r--modules/benchmark/zlib.c71
-rw-r--r--modules/computer.c642
-rw-r--r--modules/computer/alsa.c28
-rw-r--r--modules/computer/boots.c19
-rw-r--r--modules/computer/environment.c10
-rw-r--r--modules/computer/filesystem.c114
-rw-r--r--modules/computer/languages.c96
-rw-r--r--modules/computer/memory.c27
-rw-r--r--modules/computer/modules.c80
-rw-r--r--modules/computer/os.c511
-rw-r--r--modules/computer/uptime.c43
-rw-r--r--modules/computer/users.c21
-rw-r--r--modules/devices.c389
-rw-r--r--modules/devices/alpha/processor.c74
-rw-r--r--modules/devices/arm/arm_data.c95
-rw-r--r--modules/devices/arm/processor.c258
-rw-r--r--modules/devices/cpu_util.c225
-rw-r--r--modules/devices/cpubits.c113
-rw-r--r--modules/devices/devicetree.c272
-rw-r--r--modules/devices/devicetree/dt_util.c1040
-rw-r--r--modules/devices/devicetree/pmac_data.c98
-rw-r--r--modules/devices/devicetree/rpi_data.c166
-rw-r--r--modules/devices/devmemory.c56
-rw-r--r--modules/devices/dmi.c55
-rw-r--r--modules/devices/ia64/processor.c209
-rw-r--r--modules/devices/inputdevices.c94
-rw-r--r--modules/devices/m68k/processor.c75
-rw-r--r--modules/devices/mips/processor.c66
-rw-r--r--modules/devices/parisc/processor.c221
-rw-r--r--modules/devices/pci.c79
-rw-r--r--modules/devices/ppc/processor.c207
-rw-r--r--modules/devices/riscv/processor.c233
-rw-r--r--modules/devices/riscv/riscv_data.c212
-rw-r--r--modules/devices/riscv/riscv_data.h33
-rw-r--r--modules/devices/s390/processor.c172
-rw-r--r--modules/devices/sensors.c535
-rw-r--r--modules/devices/sh/processor.c78
-rw-r--r--modules/devices/sparc/processor.c50
-rw-r--r--modules/devices/spd-decode.c23
-rw-r--r--modules/devices/usb.c244
-rw-r--r--modules/devices/x86/processor.c506
-rw-r--r--modules/devices/x86/x86_data.c344
-rw-r--r--modules/devices/x86/x86_data.h28
l---------modules/devices/x86_641
-rw-r--r--modules/network.c189
-rw-r--r--modules/network/net.c399
47 files changed, 6172 insertions, 2429 deletions
diff --git a/modules/benchmark.c b/modules/benchmark.c
index 94997df8..50fddf4d 100644
--- a/modules/benchmark.c
+++ b/modules/benchmark.c
@@ -36,6 +36,7 @@ void scan_bfsh(gboolean reload);
void scan_cryptohash(gboolean reload);
void scan_fib(gboolean reload);
void scan_nqueens(gboolean reload);
+void scan_zlib(gboolean reload);
void scan_gui(gboolean reload);
gchar *callback_fft();
@@ -44,6 +45,7 @@ gchar *callback_bfsh();
gchar *callback_fib();
gchar *callback_cryptohash();
gchar *callback_nqueens();
+gchar *callback_zlib();
gchar *callback_gui();
static ModuleEntry entries[] = {
@@ -51,9 +53,12 @@ static ModuleEntry entries[] = {
{N_("CPU CryptoHash"), "cryptohash.png", callback_cryptohash, scan_cryptohash, MODULE_FLAG_NONE},
{N_("CPU Fibonacci"), "nautilus.png", callback_fib, scan_fib, MODULE_FLAG_NONE},
{N_("CPU N-Queens"), "nqueens.png", callback_nqueens, scan_nqueens, MODULE_FLAG_NONE},
+ {N_("CPU Zlib"), "file-roller.png", callback_zlib, scan_zlib, MODULE_FLAG_NONE},
{N_("FPU FFT"), "fft.png", callback_fft, scan_fft, MODULE_FLAG_NONE},
{N_("FPU Raytracing"), "raytrace.png", callback_raytr, scan_raytr, MODULE_FLAG_NONE},
+#if !GTK_CHECK_VERSION(3,0,0)
{N_("GPU Drawing"), "module.png", callback_gui, scan_gui, MODULE_FLAG_NO_REMOTE},
+#endif
{NULL}
};
@@ -187,30 +192,30 @@ static gchar *__benchmark_include_results(gdouble result,
{
GKeyFile *conf;
gchar **machines;
- gchar *path, *results = g_strdup(""), *return_value, *processor_frequency;
+ gchar *path, *results = g_strdup(""), *return_value, *processor_frequency, *processor_name;
int i;
conf = g_key_file_new();
path = g_build_filename(g_get_home_dir(), ".hardinfo", "benchmark.conf", NULL);
if (!g_file_test(path, G_FILE_TEST_EXISTS)) {
- DEBUG("local benchmark.conf not found, trying system-wide");
- g_free(path);
- path = g_build_filename(params.path_data, "benchmark.conf", NULL);
+ DEBUG("local benchmark.conf not found, trying system-wide");
+ g_free(path);
+ path = g_build_filename(params.path_data, "benchmark.conf", NULL);
}
g_key_file_load_from_file(conf, path, 0, NULL);
machines = g_key_file_get_keys(conf, benchmark, NULL, NULL);
for (i = 0; machines && machines[i]; i++) {
- gchar *value, *cleaned_machine;
+ gchar *value, *cleaned_machine;
- value = g_key_file_get_value(conf, benchmark, machines[i], NULL);
- cleaned_machine = clean_cpuname(machines[i]);
- results = h_strconcat(results, cleaned_machine, "=", value, "\n", NULL);
+ value = g_key_file_get_value(conf, benchmark, machines[i], NULL);
+ cleaned_machine = clean_cpuname(machines[i]);
+ results = h_strconcat(results, cleaned_machine, "=", value, "\n", NULL);
- g_free(value);
- g_free(cleaned_machine);
+ g_free(value);
+ g_free(cleaned_machine);
}
g_strfreev(machines);
@@ -218,30 +223,37 @@ static gchar *__benchmark_include_results(gdouble result,
g_key_file_free(conf);
if (result > 0.0f) {
- processor_frequency = module_call_method("devices::getProcessorFrequency");
- return_value = g_strdup_printf(_("[$ShellParam$]\n"
- "Zebra=1\n"
- "OrderType=%d\n"
- "ViewType=3\n"
- "ColumnTitle$Extra1=CPU Clock\n"
- "ColumnTitle$Progress=Results\n"
- "ColumnTitle$TextValue=CPU\n"
- "ShowColumnHeaders=true\n"
- "[%s]\n"
- "<big><b>This Machine</b></big>=%.3f|%s MHz\n"
- "%s"), order_type, benchmark, result, processor_frequency, results);
+ processor_name = module_call_method("devices::getProcessorName");
+ processor_frequency = module_call_method("devices::getProcessorFrequencyDesc");
+ return_value = g_strdup_printf("[$ShellParam$]\n"
+ "Zebra=1\n"
+ "OrderType=%d\n"
+ "ViewType=3\n"
+ "ColumnTitle$Extra1=%s\n" /* CPU Clock */
+ "ColumnTitle$Progress=%s\n" /* Results */
+ "ColumnTitle$TextValue=%s\n" /* CPU */
+ "ShowColumnHeaders=true\n"
+ "[%s]\n"
+ "<big><b>%s</b></big>=%.3f|%s\n"
+ "%s", order_type,
+ _("CPU Config"), _("Results"), _("CPU"),
+ benchmark,
+ processor_name, result, processor_frequency, results);
g_free(processor_frequency);
+ g_free(processor_name);
} else {
- return_value = g_strdup_printf(_("[$ShellParam$]\n"
- "Zebra=1\n"
- "OrderType=%d\n"
- "ViewType=3\n"
- "ColumnTitle$Extra1=CPU Clock\n"
- "ColumnTitle$Progress=Results\n"
- "ColumnTitle$TextValue=CPU\n"
- "ShowColumnHeaders=true\n"
- "[%s]\n"
- "%s"), order_type, benchmark, results);
+ return_value = g_strdup_printf("[$ShellParam$]\n"
+ "Zebra=1\n"
+ "OrderType=%d\n"
+ "ViewType=3\n"
+ "ColumnTitle$Extra1=%s\n" /* CPU Clock */
+ "ColumnTitle$Progress=%s\n" /* Results */
+ "ColumnTitle$TextValue=%s\n" /* CPU */
+ "ShowColumnHeaders=true\n"
+ "[%s]\n%s",
+ order_type,
+ _("CPU Config"), _("Results"), _("CPU"),
+ benchmark, results);
}
return return_value;
}
@@ -306,6 +318,12 @@ gchar *callback_fib()
"CPU Fibonacci");
}
+gchar *callback_zlib()
+{
+ return benchmark_include_results(bench_results[BENCHMARK_ZLIB],
+ "CPU Zlib");
+}
+
typedef struct _BenchmarkDialog BenchmarkDialog;
struct _BenchmarkDialog {
GtkWidget *dialog;
@@ -348,7 +366,7 @@ static gboolean do_benchmark_handler(GIOChannel *source,
static void do_benchmark(void (*benchmark_function)(void), int entry)
{
int old_priority = 0;
-
+
if (params.gui_running && !sending_benchmark_results) {
gchar *argv[] = { params.argv0, "-b", entries[entry].name,
"-m", "benchmark.so", "-a", NULL };
@@ -364,7 +382,7 @@ static void do_benchmark(void (*benchmark_function)(void), int entry)
shell_view_set_enabled(FALSE);
shell_status_update(bench_status);
-
+
g_free(bench_status);
bench_image = icon_cache_get_image("benchmark.png");
@@ -388,7 +406,7 @@ static void do_benchmark(void (*benchmark_function)(void), int entry)
benchmark_dialog = g_new0(BenchmarkDialog, 1);
benchmark_dialog->dialog = bench_dialog;
benchmark_dialog->result = -1.0f;
-
+
if (!g_path_is_absolute(params.argv0)) {
spawn_flags |= G_SPAWN_SEARCH_PATH;
}
@@ -432,7 +450,7 @@ static void do_benchmark(void (*benchmark_function)(void), int entry)
return;
}
-
+
gtk_widget_destroy(bench_dialog);
g_free(benchmark_dialog);
shell_status_set_enabled(TRUE);
@@ -504,12 +522,20 @@ void scan_fib(gboolean reload)
SCAN_END();
}
+void scan_zlib(gboolean reload)
+{
+ SCAN_START();
+ do_benchmark(benchmark_zlib, BENCHMARK_ZLIB);
+ SCAN_END();
+}
+
const gchar *hi_note_func(gint entry)
{
switch (entry) {
case BENCHMARK_CRYPTOHASH:
return _("Results in MiB/second. Higher is better.");
+ case BENCHMARK_ZLIB:
case BENCHMARK_GUI:
return _("Results in HIMarks. Higher is better.");
@@ -595,7 +621,7 @@ static gchar *get_benchmark_results()
g_free(machineram);
sending_benchmark_results = FALSE;
-
+
return result;
}
diff --git a/modules/benchmark/zlib.c b/modules/benchmark/zlib.c
new file mode 100644
index 00000000..eeec9d0e
--- /dev/null
+++ b/modules/benchmark/zlib.c
@@ -0,0 +1,71 @@
+/*
+ * HardInfo - Displays System Information
+ * Copyright (C) 2017 Leandro A. F. Pereira <leandro@hardinfo.org>
+ *
+ * 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 <glib.h>
+#include <stdlib.h>
+#include <zlib.h>
+
+#include "benchmark.h"
+
+static gpointer zlib_for(unsigned int start, unsigned int end, void *data, gint thread_number)
+{
+ char *compressed;
+ uLong bound = compressBound(bound);
+ unsigned int i;
+
+ compressed = malloc(bound);
+ if (!compressed)
+ return NULL;
+
+ for (i = start; i <= end; i++) {
+ char uncompressed[65536];
+ uLong compressedBound = bound;
+ uLong destBound = sizeof(uncompressed);
+
+ compress(compressed, &compressedBound, data, 65536);
+ uncompress(uncompressed, &destBound, compressed, compressedBound);
+ }
+
+ free(compressed);
+
+ return NULL;
+}
+
+void
+benchmark_zlib(void)
+{
+ gdouble elapsed = 0;
+ gchar *tmpsrc, *bdata_path;
+
+ bdata_path = g_build_filename(params.path_data, "benchmark.data", NULL);
+ if (!g_file_get_contents(bdata_path, &tmpsrc, NULL, NULL)) {
+ g_free(bdata_path);
+ return;
+ }
+
+ shell_view_set_enabled(FALSE);
+ shell_status_update("Running Zlib benchmark...");
+
+ elapsed = benchmark_parallel_for(0, 50000, zlib_for, tmpsrc);
+
+ g_free(bdata_path);
+ g_free(tmpsrc);
+
+ gdouble marks = (50000. * 65536.) / (elapsed * 840205128.);
+ bench_results[BENCHMARK_ZLIB] = marks;
+}
diff --git a/modules/computer.c b/modules/computer.c
index eda405e8..513d94f5 100644
--- a/modules/computer.c
+++ b/modules/computer.c
@@ -16,13 +16,14 @@
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
+#include <config.h>
+#include <gtk/gtk.h>
+#include <stdarg.h>
#include <stdlib.h>
#include <string.h>
-#include <gtk/gtk.h>
-#include <config.h>
-#include <time.h>
#include <string.h>
#include <sys/stat.h>
+#include <time.h>
#include <hardinfo.h>
#include <iconcache.h>
@@ -31,21 +32,22 @@
#include <vendor.h>
#include "computer.h"
+#include "info.h"
/* Callbacks */
-gchar *callback_summary();
-gchar *callback_os();
-gchar *callback_modules();
-gchar *callback_boots();
-gchar *callback_locales();
-gchar *callback_fs();
-gchar *callback_display();
-gchar *callback_network();
-gchar *callback_users();
-gchar *callback_groups();
-gchar *callback_env_var();
+gchar *callback_summary(void);
+gchar *callback_os(void);
+gchar *callback_modules(void);
+gchar *callback_boots(void);
+gchar *callback_locales(void);
+gchar *callback_fs(void);
+gchar *callback_display(void);
+gchar *callback_network(void);
+gchar *callback_users(void);
+gchar *callback_groups(void);
+gchar *callback_env_var(void);
#if GLIB_CHECK_VERSION(2,14,0)
-gchar *callback_dev();
+gchar *callback_dev(void);
#endif /* GLIB_CHECK_VERSION(2,14,0) */
/* Scan callbacks */
@@ -81,6 +83,7 @@ static ModuleEntry entries[] = {
{NULL},
};
+
gchar *module_list = NULL;
Computer *computer = NULL;
@@ -89,7 +92,7 @@ gchar *hi_more_info(gchar * entry)
gchar *info = moreinfo_lookup_with_prefix("COMP", entry);
if (info)
- return g_strdup(info);
+ return g_strdup(info);
return g_strdup_printf("[%s]", entry);
}
@@ -99,22 +102,22 @@ gchar *hi_get_field(gchar * field)
gchar *tmp;
if (g_str_equal(field, _("Memory"))) {
- MemoryInfo *mi = computer_get_memory();
- tmp = g_strdup_printf(_("%dMB (%dMB used)"), mi->total, mi->used);
- g_free(mi);
+ MemoryInfo *mi = computer_get_memory();
+ tmp = g_strdup_printf(_("%dMB (%dMB used)"), mi->total, mi->used);
+ g_free(mi);
} else if (g_str_equal(field, _("Uptime"))) {
- tmp = computer_get_formatted_uptime();
+ tmp = computer_get_formatted_uptime();
} else if (g_str_equal(field, _("Date/Time"))) {
- time_t t = time(NULL);
+ time_t t = time(NULL);
- tmp = g_new0(gchar, 64);
- strftime(tmp, 64, "%c", localtime(&t));
+ tmp = g_new0(gchar, 64);
+ strftime(tmp, 64, "%c", localtime(&t));
} else if (g_str_equal(field, _("Load Average"))) {
- tmp = computer_get_formatted_loadavg();
+ tmp = computer_get_formatted_loadavg();
} else if (g_str_equal(field, _("Available entropy in /dev/random"))) {
- tmp = computer_get_entropy_avail();
+ tmp = computer_get_entropy_avail();
} else {
- tmp = g_strdup_printf("Unknown field: %s", field);
+ tmp = g_strdup_printf("Unknown field: %s", field);
}
return tmp;
}
@@ -189,7 +192,7 @@ static gchar *dev_list = NULL;
void scan_dev(gboolean reload)
{
SCAN_START();
-
+
int i;
struct {
gchar *compiler_name;
@@ -198,8 +201,13 @@ void scan_dev(gboolean reload)
gboolean stdout;
} detect_lang[] = {
{ N_("Scripting Languages"), NULL, FALSE },
- { N_("CPython"), "python -V", "\\d+\\.\\d+\\.\\d+", TRUE },
+ { N_("Gambas3 (gbr3)"), "gbr3 --version", "\\d+\\.\\d+\\.\\d+", TRUE },
+ { N_("Python"), "python -V", "\\d+\\.\\d+\\.\\d+", FALSE },
+ { N_("Python2"), "python2 -V", "\\d+\\.\\d+\\.\\d+", FALSE },
+ { N_("Python3"), "python3 -V", "\\d+\\.\\d+\\.\\d+", TRUE },
{ N_("Perl"), "perl -v", "\\d+\\.\\d+\\.\\d+", TRUE },
+ { N_("Perl6 (VM)"), "perl6 -v", "(?<=This is ).*", TRUE },
+ { N_("Perl6"), "perl6 -v", "(?<=implementing Perl )\\w*\\.\\w*", TRUE },
{ N_("PHP"), "php --version", "\\d+\\.\\d+\\.\\S+", TRUE},
{ N_("Ruby"), "ruby --version", "\\d+\\.\\d+\\.\\d+", TRUE },
{ N_("Bash"), "bash --version", "\\d+\\.\\d+\\.\\S+", TRUE},
@@ -207,6 +215,7 @@ void scan_dev(gboolean reload)
{ N_("C (GCC)"), "gcc -v", "\\d+\\.\\d+\\.\\d+", FALSE },
{ N_("C (Clang)"), "clang -v", "\\d+\\.\\d+", FALSE },
{ N_("D (dmd)"), "dmd --help", "\\d+\\.\\d+", TRUE },
+ { N_("Gambas3 (gbc3)"), "gbc3 --version", "\\d+\\.\\d+\\.\\d+", FALSE },
{ N_("Java"), "javac -version", "\\d+\\.\\d+\\.\\d+", FALSE },
{ N_("CSharp (Mono, old)"), "mcs --version", "\\d+\\.\\d+\\.\\d+\\.\\d+", TRUE },
{ N_("CSharp (Mono)"), "gmcs --version", "\\d+\\.\\d+\\.\\d+\\.\\d+", TRUE },
@@ -216,36 +225,38 @@ void scan_dev(gboolean reload)
{ N_("Go"), "go version", "\\d+\\.\\d+\\.?\\d* ", TRUE },
{ N_("Tools"), NULL, FALSE },
{ N_("make"), "make --version", "\\d+\\.\\d+", TRUE },
- { N_("GDB"), "gdb --version", "\\d+\\.\\S+", TRUE },
+ { N_("GDB"), "gdb --version", "(?<=^GNU gdb ).*", TRUE },
{ N_("strace"), "strace -V", "\\d+\\.\\d+\\.?\\d*", TRUE },
{ N_("valgrind"), "valgrind --version", "\\d+\\.\\d+\\.\\S+", TRUE },
{ N_("QMake"), "qmake --version", "\\d+\\.\\S+", TRUE},
{ N_("CMake"), "cmake --version", "\\d+\\.\\d+\\.?\\d*", TRUE},
+ { N_("Gambas3 IDE"), "gambas3 --version", "\\d+\\.\\d+\\.\\d+", FALSE },
};
-
+
g_free(dev_list);
-
+
dev_list = g_strdup("");
-
+
for (i = 0; i < G_N_ELEMENTS(detect_lang); i++) {
gchar *version = NULL;
- gchar *output;
+ gchar *output, *ignored;
gchar *temp;
GRegex *regex;
GMatchInfo *match_info;
gboolean found;
-
+
if (!detect_lang[i].regex) {
- dev_list = h_strdup_cprintf("[%s]\n", dev_list, detect_lang[i].compiler_name);
+ dev_list = h_strdup_cprintf("[%s]\n", dev_list, _(detect_lang[i].compiler_name));
continue;
}
-
+
if (detect_lang[i].stdout) {
- found = g_spawn_command_line_sync(detect_lang[i].version_command, &output, NULL, NULL, NULL);
+ found = g_spawn_command_line_sync(detect_lang[i].version_command, &output, &ignored, NULL, NULL);
} else {
- found = g_spawn_command_line_sync(detect_lang[i].version_command, NULL, &output, NULL, NULL);
+ found = g_spawn_command_line_sync(detect_lang[i].version_command, &ignored, &output, NULL, NULL);
}
-
+ g_free(ignored);
+
if (found) {
regex = g_regex_new(detect_lang[i].regex, 0, 0, NULL);
@@ -253,41 +264,131 @@ void scan_dev(gboolean reload)
if (g_match_info_matches(match_info)) {
version = g_match_info_fetch(match_info, 0);
}
-
+
g_match_info_free(match_info);
g_regex_unref(regex);
g_free(output);
}
-
- if (version) {
- dev_list = h_strdup_cprintf("%s=%s\n", dev_list, detect_lang[i].compiler_name, version);
- g_free(version);
- } else {
- dev_list = h_strdup_cprintf(_("%s=Not found\n"), dev_list, detect_lang[i].compiler_name);
- }
-
+
+ if (version == NULL)
+ version = strdup(_("Not found"));
+
+ dev_list = h_strdup_cprintf("%s=%s\n", dev_list, detect_lang[i].compiler_name, version);
+ g_free(version);
+
temp = g_strdup_printf(_("Detecting version: %s"),
detect_lang[i].compiler_name);
shell_status_update(temp);
g_free(temp);
}
-
+
SCAN_END();
}
-gchar *callback_dev()
+gchar *callback_dev(void)
{
- return g_strdup_printf(_("[$ShellParam$]\n"
- "ColumnTitle$TextValue=Program\n"
- "ColumnTitle$Value=Version\n"
- "ShowColumnHeaders=true\n"
- "%s"), dev_list);
+ return g_strdup_printf(
+ "[$ShellParam$]\n"
+ "ColumnTitle$TextValue=%s\n" /* Program */
+ "ColumnTitle$Value=%s\n" /* Version */
+ "ShowColumnHeaders=true\n"
+ "%s",
+ _("Program"), _("Version"),
+ dev_list);
}
#endif /* GLIB_CHECK_VERSION(2,14,0) */
+static gchar *detect_machine_type(void)
+{
+ GDir *dir;
+ gchar *chassis;
+
+ if (g_file_get_contents("/sys/devices/virtual/dmi/id/chassis_type", &chassis, NULL, NULL)) {
+ 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"),
+ };
+ int chassis_type = atoi(idle_free(chassis));
+
+ if (chassis_type >= 0 && chassis_type < G_N_ELEMENTS(types))
+ return g_strdup(_(types[chassis_type]));
+ }
+
+ if (g_file_test("/proc/pmu/info", G_FILE_TEST_EXISTS))
+ return g_strdup(_("Laptop"));
+
+ dir = g_dir_open("/proc/acpi/battery", 0, NULL);
+ if (dir) {
+ const gchar *name = g_dir_read_name(dir);
+
+ g_dir_close(dir);
+
+ if (name)
+ return g_strdup(_("Laptop"));
+ }
+
+ dir = g_dir_open("/sys/class/power_supply", 0, NULL);
+ if (dir) {
+ const gchar *name;
+
+ while ((name = g_dir_read_name(dir))) {
+ gchar *contents;
+ gchar type[PATH_MAX];
+ int r;
+
+ r = snprintf(type, sizeof(type), "%s/%s/type",
+ "/sys/class/power_supply", name);
+ if (r < 0 || r > PATH_MAX)
+ continue;
+
+ if (g_file_get_contents(type, &contents, NULL, NULL)) {
+ if (g_str_has_prefix(contents, "Battery")) {
+ g_free(contents);
+ g_dir_close(dir);
+
+ return g_strdup(_("Laptop"));
+ }
+
+ g_free(contents);
+ }
+ }
+
+ g_dir_close(dir);
+ }
+
+ /* FIXME: check if batteries are found using /proc/apm */
+
+ /* FIXME: use dmidecode if available to get chassis type */
+
+ return g_strdup(_("Unknown physical machine type"));
+}
+
/* Table based off imvirt by Thomas Liske <liske@ibh.de>
Copyright (c) 2008 IBH IT-Service GmbH under GPLv2. */
-gchar *computer_get_virtualization()
+gchar *computer_get_virtualization(void)
{
gboolean found = FALSE;
gint i, j;
@@ -324,18 +425,18 @@ gchar *computer_get_virtualization()
{ " hypervisor", "Virtual (hypervisor present)"} ,
{ NULL }
};
-
+
DEBUG("Detecting virtual machine");
if (g_file_test("/proc/xen", G_FILE_TEST_EXISTS)) {
DEBUG("/proc/xen found; assuming Xen");
return g_strdup("Xen");
}
-
+
for (i = 0; files[i+1]; i++) {
gchar buffer[512];
FILE *file;
-
+
if ((file = fopen(files[i], "r"))) {
while (!found && fgets(buffer, 512, file)) {
for (j = 0; vm_types[j+1].str; j++) {
@@ -345,200 +446,191 @@ gchar *computer_get_virtualization()
}
}
}
-
+
fclose(file);
-
+
if (found) {
DEBUG("%s found (by reading file %s)",
vm_types[j].vmtype, files[i]);
return g_strdup(vm_types[j].vmtype);
}
}
-
+
}
-
+
DEBUG("no virtual machine detected; assuming physical machine");
-
- return g_strdup(_("Physical machine"));
-}
-
-gchar *callback_summary()
-{
- gchar *processor_name, *alsa_cards;
- gchar *input_devices, *printers;
- gchar *storage_devices, *summary;
- gchar *virt;
-
- processor_name = module_call_method("devices::getProcessorName");
- alsa_cards = computer_get_alsacards(computer);
- input_devices = module_call_method("devices::getInputDevices");
- printers = module_call_method("devices::getPrinters");
- storage_devices = module_call_method("devices::getStorageDevices");
- virt = computer_get_virtualization();
-
- summary = g_strdup_printf(_("[$ShellParam$]\n"
- "UpdateInterval$Memory=1000\n"
- "UpdateInterval$Date/Time=1000\n"
- "#ReloadInterval=5000\n"
- "[Computer]\n"
- "Processor=%s\n"
- "Memory=...\n"
- "Machine Type=%s\n"
- "Operating System=%s\n"
- "User Name=%s\n"
- "Date/Time=...\n"
- "[Display]\n"
- "Resolution=%dx%d pixels\n"
- "OpenGL Renderer=%s\n"
- "X11 Vendor=%s\n"
- "\n%s\n"
- "[Input Devices]\n%s\n"
- "\n%s\n"
- "\n%s\n"),
- processor_name,
- virt,
- computer->os->distro,
- computer->os->username,
- computer->display->width,
- computer->display->height,
- computer->display->ogl_renderer,
- computer->display->vendor,
- alsa_cards,
- input_devices, printers, storage_devices);
-
- g_free(processor_name);
- g_free(alsa_cards);
- g_free(input_devices);
- g_free(printers);
- g_free(storage_devices);
- g_free(virt);
-
- return summary;
-}
-
-gchar *callback_os()
-{
- return g_strdup_printf(_("[$ShellParam$]\n"
- "UpdateInterval$Uptime=10000\n"
- "UpdateInterval$Load Average=1000\n"
- "UpdateInterval$Available entropy in /dev/random=1000\n"
- "[Version]\n"
- "Kernel=%s\n"
- "Version=%s\n"
- "C Library=%s\n"
- "Distribution=%s\n"
- "[Current Session]\n"
- "Computer Name=%s\n"
- "User Name=%s\n"
- "#Language=%s\n"
- "Home Directory=%s\n"
- "Desktop Environment=%s\n"
- "[Misc]\n"
- "Uptime=...\n"
- "Load Average=...\n"
- "Available entropy in /dev/random=..."),
- computer->os->kernel,
- computer->os->kernel_version,
- computer->os->libc,
- computer->os->distro,
- computer->os->hostname,
- computer->os->username,
- computer->os->language,
- computer->os->homedir,
- computer->os->desktop);
-}
-
-gchar *callback_modules()
-{
- return g_strdup_printf(_("[Loaded Modules]\n"
- "%s"
- "[$ShellParam$]\n"
- "ViewType=1\n"
- "ColumnTitle$TextValue=Name\n"
- "ColumnTitle$Value=Description\n"
- "ShowColumnHeaders=true\n"), module_list);
-}
-
-gchar *callback_boots()
-{
- return g_strdup_printf(_("[$ShellParam$]\n"
- "ColumnTitle$TextValue=Date & Time\n"
- "ColumnTitle$Value=Kernel Version\n"
- "ShowColumnHeaders=true\n"
- "\n"
- "%s"), computer->os->boots);
-}
-
-gchar *callback_locales()
-{
- return g_strdup_printf(_("[$ShellParam$]\n"
- "ViewType=1\n"
- "ColumnTitle$TextValue=Language Code\n"
- "ColumnTitle$Value=Name\n"
- "ShowColumnHeaders=true\n"
- "[Available Languages]\n"
- "%s"), computer->os->languages);
-}
-
-gchar *callback_fs()
-{
- return g_strdup_printf(_("[$ShellParam$]\n"
- "ViewType=4\n"
- "ReloadInterval=5000\n"
- "Zebra=1\n"
- "NormalizePercentage=false\n"
- "ColumnTitle$Extra1=Mount Point\n"
- "ColumnTitle$Progress=Usage\n"
- "ColumnTitle$TextValue=Device\n"
- "ShowColumnHeaders=true\n"
- "[Mounted File Systems]\n%s\n"), fs_list);
-}
-
-gchar *callback_display()
-{
- return g_strdup_printf(_("[Display]\n"
- "Resolution=%dx%d pixels\n"
- "Vendor=%s\n"
- "Version=%s\n"
- "[Monitors]\n"
- "%s"
- "[Extensions]\n"
- "%s"
- "[OpenGL]\n"
- "Vendor=%s\n"
- "Renderer=%s\n"
- "Version=%s\n"
- "Direct Rendering=%s\n"),
- computer->display->width,
- computer->display->height,
- computer->display->vendor,
- computer->display->version,
- computer->display->monitors,
- computer->display->extensions,
- computer->display->ogl_vendor,
- computer->display->ogl_renderer,
- computer->display->ogl_version,
- computer->display->dri ? _("Y_es") : _("No"));
-}
-
-gchar *callback_users()
-{
- return g_strdup_printf("[$ShellParam$]\n"
- "ReloadInterval=10000\n"
- "ViewType=1\n"
- "[Users]\n"
- "%s\n", users);
-}
-
-gchar *callback_groups()
-{
- return g_strdup_printf(_("[$ShellParam$]\n"
- "ReloadInterval=10000\n"
- "ColumnTitle$TextValue=Name\n"
- "ColumnTitle$Value=Group ID\n"
- "ShowColumnHeaders=true\n"
- "[Groups]\n"
- "%s\n"), groups);
+
+ return detect_machine_type();
+}
+
+gchar *callback_summary(void)
+{
+ struct Info *info = info_new();
+
+ info_add_group(info, _("Computer"),
+ info_field_printf(_("Processor"), "%s",
+ module_call_method("devices::getProcessorName")),
+ info_field_update(_("Memory"), 1000),
+ info_field_printf(_("Machine Type"), "%s",
+ computer_get_virtualization()),
+ info_field(_("Operating System"), computer->os->distro),
+ info_field(_("User Name"), computer->os->username),
+ info_field_update(_("Date/Time"), 1000),
+ info_field_last());
+
+ info_add_group(info, _("Display"),
+ info_field_printf(_("Resolution"), _(/* label for resolution */ "%dx%d pixels"),
+ computer->display->width, computer->display->height),
+ info_field(_("OpenGL Renderer"), computer->display->ogl_renderer),
+ info_field(_("X11 Vendor"), computer->display->vendor),
+ info_field_last());
+
+ info_add_computed_group(info, _("Audio Devices"),
+ idle_free(computer_get_alsacards(computer)));
+ info_add_computed_group(info, _("Input Devices"),
+ idle_free(module_call_method("devices::getInputDevices")));
+ info_add_computed_group(info, _("Printers"),
+ idle_free(module_call_method("devices::getPrinters")));
+ info_add_computed_group(info, _("Storage"),
+ idle_free(module_call_method("devices::getStorageDevices")));
+
+ return info_flatten(info);
+}
+
+gchar *callback_os(void)
+{
+ struct Info *info = info_new();
+
+ info_add_group(info, _("Version"),
+ info_field(_("Kernel"), computer->os->kernel),
+ info_field(_("Version"), computer->os->kernel_version),
+ info_field(_("C Library"), computer->os->libc),
+ info_field(_("Distribution"), computer->os->distro),
+ info_field_last());
+
+ info_add_group(info, _("Current Session"),
+ info_field(_("Computer Name"), computer->os->hostname),
+ info_field(_("User Name"), computer->os->username),
+ info_field(_("Language"), computer->os->language),
+ info_field(_("Home Directory"), computer->os->homedir),
+ info_field_last());
+
+ info_add_group(info, _("Misc"),
+ info_field_update(_("Uptime"), 1000),
+ info_field_update(_("Load Average"), 10000),
+ info_field_update(_("Available entropy in /dev/random"), 1000),
+ info_field_last());
+
+ return info_flatten(info);
+}
+
+gchar *callback_modules(void)
+{
+ struct Info *info = info_new();
+
+ info_add_computed_group(info, _("Loaded Modules"), module_list);
+
+ info_set_column_title(info, "TextValue", _("Name"));
+ info_set_column_title(info, "Value", _("Description"));
+ info_set_column_headers_visible(info, TRUE);
+ info_set_view_type(info, SHELL_VIEW_DUAL);
+
+ return info_flatten(info);
+}
+
+gchar *callback_boots(void)
+{
+ struct Info *info = info_new();
+
+ info_add_computed_group(info, _("Boots"), computer->os->boots);
+
+ info_set_column_title(info, "TextValue", _("Date & Time"));
+ info_set_column_title(info, "Value", _("Kernel Version"));
+ info_set_column_headers_visible(info, TRUE);
+
+ return info_flatten(info);
+}
+
+gchar *callback_locales(void)
+{
+ struct Info *info = info_new();
+
+ info_add_computed_group(info, _("Available Languages"), computer->os->languages);
+
+ info_set_column_title(info, "TextValue", _("Language Code"));
+ info_set_column_title(info, "Value", _("Name"));
+ info_set_view_type(info, SHELL_VIEW_DUAL);
+ info_set_column_headers_visible(info, TRUE);
+
+ return info_flatten(info);
+}
+
+gchar *callback_fs(void)
+{
+ struct Info *info = info_new();
+
+ info_add_computed_group(info, _("Mounted File Systems"), fs_list);
+
+ info_set_column_title(info, "Extra1", _("Mount Point"));
+ info_set_column_title(info, "Progress", _("Usage"));
+ info_set_column_title(info, "TextValue", _("Device"));
+ info_set_column_headers_visible(info, TRUE);
+ info_set_view_type(info, SHELL_VIEW_PROGRESS_DUAL);
+ info_set_zebra_visible(info, TRUE);
+ info_set_normalize_percentage(info, FALSE);
+
+ return info_flatten(info);
+}
+
+gchar *callback_display(void)
+{
+ struct Info *info = info_new();
+
+ info_add_group(info, _("Display"),
+ info_field_printf(_("Resolution"), _(/* resolution WxH unit */ "%dx%d pixels"),
+ computer->display->width, computer->display->height),
+ info_field(_("Vendor"), computer->display->vendor),
+ info_field(_("Version"), computer->display->version),
+ info_field_last());
+
+ info_add_computed_group(info, _("Monitors"), computer->display->monitors);
+
+ info_add_group(info, _("OpenGL"),
+ info_field(_("Vendor"), computer->display->ogl_vendor),
+ info_field(_("Renderer"), computer->display->ogl_renderer),
+ info_field(_("Version"), computer->display->ogl_version),
+ info_field(_("Direct Rendering"),
+ computer->display->dri ? _("Yes") : _("No")),
+ info_field_last());
+
+ info_add_computed_group(info, _("Extensions"), computer->display->extensions);
+
+ return info_flatten(info);
+}
+
+gchar *callback_users(void)
+{
+ struct Info *info = info_new();
+
+ info_add_computed_group(info, _("Users"), users);
+ info_set_view_type(info, SHELL_VIEW_DUAL);
+ info_set_reload_interval(info, 10000);
+
+ return info_flatten(info);
+}
+
+gchar *callback_groups(void)
+{
+ struct Info *info = info_new();
+
+ info_add_computed_group(info, _("Group"), groups);
+
+ info_set_column_title(info, "TextValue", _("Name"));
+ info_set_column_title(info, "Value", _("Group ID"));
+ info_set_column_headers_visible(info, TRUE);
+ info_set_reload_interval(info, 10000);
+
+ return info_flatten(info);
}
gchar *get_os_kernel(void)
@@ -569,16 +661,16 @@ gchar *get_display_summary(void)
gchar *get_kernel_module_description(gchar *module)
{
gchar *description;
-
+
if (!_module_hash_table) {
scan_modules(FALSE);
}
-
+
description = g_hash_table_lookup(_module_hash_table, module);
if (!description) {
return NULL;
}
-
+
return g_strdup(description);
}
@@ -587,19 +679,19 @@ gchar *get_audio_cards(void)
if (!computer->alsa) {
computer->alsa = computer_get_alsainfo();
}
-
+
return computer_get_alsacards(computer);
}
ShellModuleMethod *hi_exported_methods(void)
{
static ShellModuleMethod m[] = {
- {"getOSKernel", get_os_kernel},
- {"getOS", get_os},
- {"getDisplaySummary", get_display_summary},
- {"getAudioCards", get_audio_cards},
- {"getKernelModuleDescription", get_kernel_module_description},
- {NULL}
+ {"getOSKernel", get_os_kernel},
+ {"getOS", get_os},
+ {"getDisplaySummary", get_display_summary},
+ {"getAudioCards", get_audio_cards},
+ {"getKernelModuleDescription", get_kernel_module_description},
+ {NULL}
};
return m;
@@ -629,30 +721,34 @@ gchar **hi_module_get_dependencies(void)
gchar *hi_module_get_summary(void)
{
- return g_strdup("[Operating System]\n"
+ return g_strdup_printf("[%s]\n"
"Icon=os.png\n"
"Method=computer::getOS\n"
- "[CPU]\n"
+ "[%s]\n"
"Icon=processor.png\n"
- "Method=devices::getProcessorName\n"
- "[RAM]\n"
+ "Method=devices::getProcessorNameAndDesc\n"
+ "[%s]\n"
"Icon=memory.png\n"
"Method=devices::getMemoryTotal\n"
- "[Motherboard]\n"
+ "[%s]\n"
"Icon=module.png\n"
"Method=devices::getMotherboard\n"
- "[Graphics]\n"
+ "[%s]\n"
"Icon=monitor.png\n"
"Method=computer::getDisplaySummary\n"
- "[Storage]\n"
+ "[%s]\n"
"Icon=hdd.png\n"
"Method=devices::getStorageDevices\n"
- "[Printers]\n"
+ "[%s]\n"
"Icon=printer.png\n"
"Method=devices::getPrinters\n"
- "[Audio]\n"
+ "[%s]\n"
"Icon=audio.png\n"
- "Method=computer::getAudioCards\n");
+ "Method=computer::getAudioCards\n",
+ _("Operating System"),
+ _("CPU"), _("RAM"), _("Motherboard"), _("Graphics"),
+ _("Storage"), _("Printers"), _("Audio")
+ );
}
void hi_module_deinit(void)
@@ -672,7 +768,7 @@ void hi_module_deinit(void)
g_free(computer->os->boots);
g_free(computer->os);
}
-
+
if (computer->display) {
g_free(computer->display->ogl_vendor);
g_free(computer->display->ogl_renderer);
@@ -684,15 +780,15 @@ void hi_module_deinit(void)
g_free(computer->display->monitors);
g_free(computer->display);
}
-
+
if (computer->alsa) {
g_slist_free(computer->alsa->cards);
g_free(computer->alsa);
}
-
+
g_free(computer->date_time);
g_free(computer);
-
+
moreinfo_del_with_prefix("COMP");
}
@@ -704,11 +800,11 @@ void hi_module_init(void)
ModuleAbout *hi_module_get_about(void)
{
static ModuleAbout ma[] = {
- {
- .author = "Leandro A. F. Pereira",
- .description = N_("Gathers high-level computer information"),
- .version = VERSION,
- .license = "GNU GPL version 2"}
+ {
+ .author = "Leandro A. F. Pereira",
+ .description = N_("Gathers high-level computer information"),
+ .version = VERSION,
+ .license = "GNU GPL version 2"}
};
return ma;
diff --git a/modules/computer/alsa.c b/modules/computer/alsa.c
index e1e7b946..00c1fceb 100644
--- a/modules/computer/alsa.c
+++ b/modules/computer/alsa.c
@@ -23,16 +23,16 @@ gchar *
computer_get_alsacards(Computer * computer)
{
GSList *p;
- gchar *tmp = g_strdup(_("[Audio Devices]\n"));
+ gchar *tmp = g_strdup_printf("[%s]\n", _("Audio Devices"));
gint n = 0;
if (computer->alsa) {
- for (p = computer->alsa->cards; p; p = p->next) {
- AlsaCard *ac = (AlsaCard *) p->data;
+ for (p = computer->alsa->cards; p; p = p->next) {
+ AlsaCard *ac = (AlsaCard *) p->data;
- tmp = h_strdup_cprintf(_("Audio Adapter#%d=%s\n"),
- tmp, ++n, ac->friendly_name);
- }
+ tmp = h_strdup_cprintf("%s#%d=%s\n", tmp,
+ _("Audio Adapter"), ++n, ac->friendly_name);
+ }
}
return tmp;
@@ -48,22 +48,22 @@ computer_get_alsainfo(void)
cards = fopen("/proc/asound/cards", "r");
if (!cards)
- return NULL;
+ return NULL;
ai = g_new0(AlsaInfo, 1);
while (fgets(buffer, 128, cards)) {
- gchar **tmp;
+ gchar **tmp;
- ac = g_new0(AlsaCard, 1);
+ ac = g_new0(AlsaCard, 1);
- tmp = g_strsplit(buffer, ":", 0);
+ tmp = g_strsplit(buffer, ":", 0);
- ac->friendly_name = g_strdup(tmp[1]);
- ai->cards = g_slist_append(ai->cards, ac);
+ ac->friendly_name = g_strdup(tmp[1]);
+ ai->cards = g_slist_append(ai->cards, ac);
- g_strfreev(tmp);
- (void)fgets(buffer, 128, cards); /* skip next line */
+ g_strfreev(tmp);
+ (void)fgets(buffer, 128, cards); /* skip next line */
}
fclose(cards);
diff --git a/modules/computer/boots.c b/modules/computer/boots.c
index 478e89ac..d8a6d32a 100644
--- a/modules/computer/boots.c
+++ b/modules/computer/boots.c
@@ -30,22 +30,22 @@ scan_boots_real(void)
scan_os(FALSE);
if (!computer->os->boots)
- computer->os->boots = g_strdup(_("[Boots]\n"));
+ computer->os->boots = g_strdup_printf("[%s]\n", _("Boots"));
else
return;
-
+
last = popen("last", "r");
if (last) {
while (fgets(buffer, 256, last)) {
if (strstr(buffer, "system boot")) {
gchar **tmp, *buf = buffer;
-
+
strend(buffer, '\n');
-
+
while (*buf) {
if (*buf == ' ' && *(buf + 1) == ' ') {
memmove(buf, buf + 1, strlen(buf) + 1);
-
+
buf--;
} else {
buf++;
@@ -53,13 +53,14 @@ scan_boots_real(void)
}
tmp = g_strsplit(buffer, " ", 0);
- computer->os->boots = h_strdup_cprintf("\n%s %s %s %s=%s|%s",
- computer->os->boots,
- tmp[4], tmp[5], tmp[6], tmp[7], tmp[3], tmp[8]);
+ computer->os->boots =
+ h_strdup_cprintf("\n%s %s %s %s=%s|%s",
+ computer->os->boots,
+ tmp[4], tmp[5], tmp[6], tmp[7], tmp[3], tmp[8]);
g_strfreev(tmp);
}
}
-
+
pclose(last);
}
}
diff --git a/modules/computer/environment.c b/modules/computer/environment.c
index 2a8d235c..dc0fb6f3 100644
--- a/modules/computer/environment.c
+++ b/modules/computer/environment.c
@@ -23,19 +23,19 @@ static gchar *_env = NULL;
void scan_env_var(gboolean reload)
{
SCAN_START();
-
+
gchar **envlist;
gint i;
-
+
g_free(_env);
-
- _env = g_strdup(_("[Environment Variables]\n"));
+
+ _env = g_strdup_printf("[%s]\n", _("Environment Variables") );
for (i = 0, envlist = g_listenv(); envlist[i]; i++) {
_env = h_strdup_cprintf("%s=%s\n", _env,
envlist[i], g_getenv(envlist[i]));
}
g_strfreev(envlist);
-
+
SCAN_END();
}
diff --git a/modules/computer/filesystem.c b/modules/computer/filesystem.c
index a7162777..397dc636 100644
--- a/modules/computer/filesystem.c
+++ b/modules/computer/filesystem.c
@@ -16,8 +16,8 @@
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*
* Some code from xfce4-mount-plugin, version 0.4.3
- * Copyright (C) 2005 Jean-Baptiste jb_dul@yahoo.com
- * Distributed under the terms of GNU GPL 2.
+ * Copyright (C) 2005 Jean-Baptiste jb_dul@yahoo.com
+ * Distributed under the terms of GNU GPL 2.
*/
#include <string.h>
@@ -41,62 +41,64 @@ scan_filesystems(void)
mtab = fopen("/etc/mtab", "r");
if (!mtab)
- return;
+ return;
while (fgets(buf, 1024, mtab)) {
- gfloat size, used, avail;
- gchar **tmp;
-
- tmp = g_strsplit(buf, " ", 0);
- if (!statfs(tmp[1], &sfs)) {
- gfloat use_ratio;
-
- size = (float) sfs.f_bsize * (float) sfs.f_blocks;
- avail = (float) sfs.f_bsize * (float) sfs.f_bavail;
- used = size - avail;
-
- if (size == 0.0f) {
- continue;
- }
-
- if (avail == 0.0f) {
- use_ratio = 100.0f;
- } else {
- use_ratio = 100.0f * (used / size);
- }
-
- gchar *strsize = size_human_readable(size),
- *stravail = size_human_readable(avail),
- *strused = size_human_readable(used);
-
- gchar *strhash;
-
- strreplacechr(tmp[0], "#", '_');
- strhash = g_strdup_printf("[%s]\n"
- "Filesystem=%s\n"
- "Mounted As=%s\n"
- "Mount Point=%s\n"
- "Size=%s\n"
- "Used=%s\n"
- "Available=%s\n",
- tmp[0],
- tmp[2],
- strstr(tmp[3], "rw") ? "Read-Write" :
- "Read-Only", tmp[1], strsize, strused,
- stravail);
- gchar *key = g_strdup_printf("FS%d", ++count);
- moreinfo_add_with_prefix("COMP", key, strhash);
- g_free(key);
-
- fs_list = h_strdup_cprintf("$FS%d$%s=%.2f %% (%s of %s)|%s\n",
- fs_list,
- count, tmp[0], use_ratio, stravail, strsize, tmp[1]);
-
- g_free(strsize);
- g_free(stravail);
- g_free(strused);
- }
- g_strfreev(tmp);
+ gfloat size, used, avail;
+ gchar **tmp;
+
+ tmp = g_strsplit(buf, " ", 0);
+ if (!statfs(tmp[1], &sfs)) {
+ gfloat use_ratio;
+
+ size = (float) sfs.f_bsize * (float) sfs.f_blocks;
+ avail = (float) sfs.f_bsize * (float) sfs.f_bavail;
+ used = size - avail;
+
+ if (size == 0.0f) {
+ continue;
+ }
+
+ if (avail == 0.0f) {
+ use_ratio = 100.0f;
+ } else {
+ use_ratio = 100.0f * (used / size);
+ }
+
+ gchar *strsize = size_human_readable(size),
+ *stravail = size_human_readable(avail),
+ *strused = size_human_readable(used);
+
+ gchar *strhash;
+
+ strreplacechr(tmp[0], "#", '_');
+ strhash = g_strdup_printf("[%s]\n"
+ "%s=%s\n"
+ "%s=%s\n"
+ "%s=%s\n"
+ "%s=%s\n"
+ "%s=%s\n"
+ "%s=%s\n",
+ tmp[0], /* path */
+ _("Filesystem"), tmp[2],
+ _("Mounted As"), ( strstr(tmp[3], "rw") != NULL) ? _("Read-Write") : _("Read-Only"),
+ _("Mount Point"), tmp[1],
+ _("Size"), strsize,
+ _("Used"), strused,
+ _("Available"), stravail);
+ gchar *key = g_strdup_printf("FS%d", ++count);
+ moreinfo_add_with_prefix("COMP", key, strhash);
+ g_free(key);
+
+ fs_list = h_strdup_cprintf("$FS%d$%s=%.2f %% (%s of %s)|%s\n",
+ fs_list,
+ count, tmp[0], use_ratio, stravail, strsize, tmp[1]);
+
+ g_free(strsize);
+ g_free(stravail);
+ g_free(strused);
+ }
+ g_strfreev(tmp);
}
fclose(mtab);
diff --git a/modules/computer/languages.c b/modules/computer/languages.c
index 5877c41c..d4681839 100644
--- a/modules/computer/languages.c
+++ b/modules/computer/languages.c
@@ -20,6 +20,7 @@
#include "hardinfo.h"
#include "computer.h"
+#include "cpu_util.h" /* for UNKIFNULL() */
void
scan_languages(OperatingSystem * os)
@@ -67,43 +68,64 @@ scan_languages(OperatingSystem * os)
g_strfreev(tmp);
} else {
- gchar *currlocale;
-
- retval = h_strdup_cprintf("$%s$%s=%s\n", retval, name, name, title);
-
-#define FIELD(f) f ? f : "(Unknown)"
- currlocale = g_strdup_printf("[Locale Information]\n"
- "Name=%s (%s)\n"
- "Source=%s\n"
- "Address=%s\n"
- "Email=%s\n"
- "Language=%s\n"
- "Territory=%s\n"
- "Revision=%s\n"
- "Date=%s\n"
- "Codeset=%s\n",
- name, FIELD(title),
- FIELD(source), FIELD(address),
- FIELD(email), FIELD(language),
- FIELD(territory), FIELD(revision),
- FIELD(date), FIELD(codeset));
-#undef FIELD
-
- moreinfo_add_with_prefix("COMP", name, currlocale);
-
- g_free(title);
- g_free(source);
- g_free(address);
- g_free(email);
- g_free(language);
- g_free(territory);
- g_free(revision);
- g_free(date);
- g_free(codeset);
-
- title = source = address = email = language = territory = \
- revision = date = codeset = NULL;
- }
+ gchar *currlocale;
+
+ retval = h_strdup_cprintf("$%s$%s=%s\n", retval, name, name, title);
+
+ UNKIFNULL(title);
+ UNKIFNULL(source);
+ UNKIFNULL(address);
+ UNKIFNULL(email);
+ UNKIFNULL(language);
+ UNKIFNULL(territory);
+ UNKIFNULL(revision);
+ UNKIFNULL(date);
+ UNKIFNULL(codeset);
+
+ /* values may have & */
+ title = hardinfo_clean_value(title, 1);
+ source = hardinfo_clean_value(source, 1);
+ address = hardinfo_clean_value(address, 1);
+ email = hardinfo_clean_value(email, 1);
+ language = hardinfo_clean_value(language, 1);
+ territory = hardinfo_clean_value(territory, 1);
+
+ currlocale = g_strdup_printf("[%s]\n"
+ /* Name */ "%s=%s (%s)\n"
+ /* Source */ "%s=%s\n"
+ /* Address */ "%s=%s\n"
+ /* Email */ "%s=%s\n"
+ /* Language */ "%s=%s\n"
+ /* Territory */"%s=%s\n"
+ /* Revision */ "%s=%s\n"
+ /* Date */ "%s=%s\n"
+ /* Codeset */ "%s=%s\n",
+ _("Locale Information"),
+ _("Name"), name, title,
+ _("Source"), source,
+ _("Address"), address,
+ _("E-mail"), email,
+ _("Language"), language,
+ _("Territory"), territory,
+ _("Revision"), revision,
+ _("Date"), date,
+ _("Codeset"), codeset );
+
+ moreinfo_add_with_prefix("COMP", name, currlocale);
+
+ g_free(title);
+ g_free(source);
+ g_free(address);
+ g_free(email);
+ g_free(language);
+ g_free(territory);
+ g_free(revision);
+ g_free(date);
+ g_free(codeset);
+
+ title = source = address = email = language = territory = \
+ revision = date = codeset = NULL;
+ }
}
fclose(locale);
diff --git a/modules/computer/memory.c b/modules/computer/memory.c
index 3d320e8a..dc8599c2 100644
--- a/modules/computer/memory.c
+++ b/modules/computer/memory.c
@@ -28,23 +28,26 @@ computer_get_memory(void)
procmem = fopen("/proc/meminfo", "r");
if (!procmem)
- return NULL;
+ return NULL;
mi = g_new0(MemoryInfo, 1);
while (fgets(buffer, 128, procmem)) {
- gchar **tmp = g_strsplit(buffer, ":", 2);
-
- tmp[0] = g_strstrip(tmp[0]);
- tmp[1] = g_strstrip(tmp[1]);
-
- get_int("MemTotal", mi->total);
- get_int("MemFree", mi->free);
- get_int("Cached", mi->cached);
-
- g_strfreev(tmp);
+ gchar **tmp = g_strsplit(buffer, ":", 2);
+ if (tmp[1] == NULL) {
+ g_strfreev(tmp);
+ continue;
+ }
+ tmp[0] = g_strstrip(tmp[0]);
+ tmp[1] = g_strstrip(tmp[1]);
+
+ get_int("MemTotal", mi->total);
+ get_int("MemFree", mi->free);
+ get_int("Cached", mi->cached);
+
+ g_strfreev(tmp);
}
fclose(procmem);
-
+
mi->used = mi->total - mi->free;
mi->total /= 1000;
diff --git a/modules/computer/modules.c b/modules/computer/modules.c
index bbc05f42..df876e3a 100644
--- a/modules/computer/modules.c
+++ b/modules/computer/modules.c
@@ -20,6 +20,7 @@
#include "hardinfo.h"
#include "computer.h"
+#include "cpu_util.h" /* for STRIFNULL() */
#define GET_STR(field_name,ptr) \
if (!ptr && strstr(tmp[0], field_name)) { \
@@ -42,7 +43,7 @@ scan_modules_do(void)
}
g_free(module_list);
-
+
module_list = NULL;
moreinfo_del_with_prefix("COMP:MOD");
@@ -51,7 +52,7 @@ scan_modules_do(void)
return;
lsmod = popen(lsmod_path, "r");
if (!lsmod) {
- g_free(lsmod_path);
+ g_free(lsmod_path);
return;
}
@@ -99,7 +100,7 @@ scan_modules_do(void)
remove_quotes(license); */
/* old modutils displays <none> when there's no value for a
- given field; this is not desirable in the module name
+ given field; this is not desirable in the module name
display, so change it to an empty string */
if (description && g_str_equal(description, "&lt;none&gt;")) {
g_free(description);
@@ -121,38 +122,45 @@ scan_modules_do(void)
modname,
description ? description : "");
-#define NONE_IF_NULL(var) (var) ? (var) : "N/A"
-
- /* create the module information string */
- strmodule = g_strdup_printf("[Module Information]\n"
- "Path=%s\n"
- "Used Memory=%.2fKiB\n"
- "[Description]\n"
- "Name=%s\n"
- "Description=%s\n"
- "Version Magic=%s\n"
- "[Copyright]\n"
- "Author=%s\n"
- "License=%s\n",
- NONE_IF_NULL(filename),
- memory / 1024.0,
- modname,
- NONE_IF_NULL(description),
- NONE_IF_NULL(vermagic),
- NONE_IF_NULL(author),
- NONE_IF_NULL(license));
-
- /* if there are dependencies, append them to that string */
- if (deps && strlen(deps)) {
- gchar **tmp = g_strsplit(deps, ",", 0);
-
- strmodule = h_strconcat(strmodule,
- "\n[Dependencies]\n",
- g_strjoinv("=\n", tmp),
- "=\n", NULL);
- g_strfreev(tmp);
- g_free(deps);
- }
+ STRIFNULL(filename, _("(Not available)") );
+ STRIFNULL(description, _("(Not available)") );
+ STRIFNULL(vermagic, _("(Not available)") );
+ STRIFNULL(author, _("(Not available)") );
+ STRIFNULL(license, _("(Not available)") );
+
+ /* create the module information string */
+ strmodule = g_strdup_printf("[%s]\n"
+ "%s=%s\n"
+ "%s=%.2f %s\n"
+ "[%s]\n"
+ "%s=%s\n"
+ "%s=%s\n"
+ "%s=%s\n"
+ "[%s]\n"
+ "%s=%s\n"
+ "%s=%s\n",
+ _("Module Information"),
+ _("Path"), filename,
+ _("Used Memory"), memory / 1024.0, _("KiB"),
+ _("Description"),
+ _("Name"), modname,
+ _("Description"), description,
+ _("Version Magic"), vermagic,
+ _("Copyright"),
+ _("Author"), author,
+ _("License"), license );
+
+ /* if there are dependencies, append them to that string */
+ if (deps && strlen(deps)) {
+ gchar **tmp = g_strsplit(deps, ",", 0);
+
+ strmodule = h_strconcat(strmodule,
+ "\n[", _("Dependencies"), "]\n",
+ g_strjoinv("=\n", tmp),
+ "=\n", NULL);
+ g_strfreev(tmp);
+ g_free(deps);
+ }
moreinfo_add_with_prefix("COMP", hashkey, strmodule);
g_free(hashkey);
@@ -164,6 +172,6 @@ scan_modules_do(void)
g_free(filename);
}
pclose(lsmod);
-
+
g_free(lsmod_path);
}
diff --git a/modules/computer/os.c b/modules/computer/os.c
index 3caf6c26..a8886f64 100644
--- a/modules/computer/os.c
+++ b/modules/computer/os.c
@@ -16,6 +16,7 @@
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
+#include <gdk/gdkx.h>
#include <string.h>
#include <sys/utsname.h>
#include "hardinfo.h"
@@ -24,219 +25,350 @@
static gchar *
get_libc_version(void)
{
- FILE *libc;
- gchar buf[256], *tmp, *p;
- char *libc_paths[] = {
- "/lib/ld-uClibc.so.0", "/lib64/ld-uClibc.so.0",
- "/lib/libc.so.6", "/lib64/libc.so.6"
- };
- int i;
-
- for (i=0; i < 4; i++) {
- if (g_file_test(libc_paths[i], G_FILE_TEST_EXISTS)) break;
- }
- switch (i) {
- case 0: case 1: return g_strdup("uClibc Library");
- case 2: case 3: break; // gnu libc, continue processing
- default: goto err;
- }
-
- libc = popen(libc_paths[i], "r");
- if (!libc) goto err;
-
- (void)fgets(buf, 256, libc);
- if (pclose(libc)) goto err;
-
- tmp = strstr(buf, "version ");
- if (!tmp) goto err;
-
- p = strchr(tmp, ',');
- if (p) *p = '\0';
- else goto err;
-
- return g_strdup_printf(_("GNU C Library version %s (%sstable)"),
- strchr(tmp, ' ') + 1,
- strstr(buf, " stable ") ? "" : _("un"));
- err:
+ static const struct {
+ const char *test_cmd;
+ const char *match_str;
+ const char *lib_name;
+ gboolean try_ver_str;
+ gboolean use_stderr;
+ } libs[] = {
+ { "ldd --version", "GLIBC", N_("GNU C Library"), TRUE, FALSE},
+ { "ldd --version", "GNU libc", N_("GNU C Library"), TRUE, FALSE},
+ { "ldconfig -V", "GLIBC", N_("GNU C Library"), TRUE, FALSE},
+ { "ldconfig -V", "GNU libc", N_("GNU C Library"), TRUE, FALSE},
+ { "ldconfig -v", "uClibc", N_("uClibc or uClibc-ng"), FALSE, FALSE},
+ { "diet", "diet version", N_("diet libc"), TRUE, TRUE},
+ { NULL }
+ };
+ int i;
+
+ for (i = 0; libs[i].test_cmd; i++) {
+ gboolean spawned;
+ gchar *out, *err, *p;
+
+ spawned = g_spawn_command_line_sync(libs[i].test_cmd,
+ &out, &err, NULL, NULL);
+ if (!spawned)
+ continue;
+
+ if (libs[i].use_stderr) {
+ p = strend(idle_free(err), '\n');
+ g_free(out);
+ } else {
+ p = strend(idle_free(out), '\n');
+ g_free(err);
+ }
+
+ if (!p || !strstr(p, libs[i].match_str))
+ continue;
+
+ if (libs[i].try_ver_str) {
+ /* skip the first word, likely "ldconfig" or name of utility */
+ const gchar *ver_str = strchr(p, ' ');
+
+ if (ver_str) {
+ return g_strdup_printf("%s / %s", _(libs[i].lib_name),
+ ver_str + 1);
+ }
+ }
+
+ return g_strdup(_(libs[i].lib_name));
+ }
+
return g_strdup(_("Unknown"));
}
-#include <gdk/gdkx.h>
+static gchar *detect_kde_version(void)
+{
+ const gchar *cmd;
+ const gchar *tmp = g_getenv("KDE_SESSION_VERSION");
+ gchar *out;
+ gboolean spawned;
+
+ if (tmp && tmp[0] == '4') {
+ cmd = "kwin --version";
+ } else {
+ cmd = "kcontrol --version";
+ }
+
+ spawned = g_spawn_command_line_sync(cmd, &out, NULL, NULL, NULL);
+ if (!spawned)
+ return NULL;
+
+ tmp = strstr(idle_free(out), "KDE: ");
+ return tmp ? g_strdup(tmp + strlen("KDE: ")) : NULL;
+}
+
+static gchar *
+detect_gnome_version(void)
+{
+ gchar *tmp;
+ gchar *out;
+ gboolean spawned;
+
+ spawned = g_spawn_command_line_sync(
+ "gnome-shell --version", &out, NULL, NULL, NULL);
+ if (spawned) {
+ tmp = strstr(idle_free(out), _("GNOME Shell "));
+
+ if (tmp) {
+ tmp += strlen(_("GNOME Shell "));
+ return g_strdup_printf("GNOME %s", strend(tmp, '\n'));
+ }
+ }
+
+ spawned = g_spawn_command_line_sync(
+ "gnome-about --gnome-version", &out, NULL, NULL, NULL);
+ if (spawned) {
+ tmp = strstr(idle_free(out), _("Version: "));
+
+ if (tmp) {
+ tmp += strlen(_("Version: "));
+ return g_strdup_printf("GNOME %s", strend(tmp, '\n'));
+ }
+ }
+
+ return NULL;
+}
-void
-detect_desktop_environment(OperatingSystem * os)
+static gchar *
+detect_window_manager(void)
{
- const gchar *tmp = g_getenv("GNOME_DESKTOP_SESSION_ID");
- FILE *version;
- char vers[16];
+ GdkScreen *screen = gdk_screen_get_default();
+ const gchar *windowman;
+ const gchar *curdesktop;
+
+ if (!screen || !GDK_IS_SCREEN(screen))
+ return NULL;
+
+ windowman = gdk_x11_screen_get_window_manager_name(screen);
+ if (g_str_equal(windowman, "Xfwm4"))
+ return g_strdup("XFCE 4");
+
+ curdesktop = g_getenv("XDG_CURRENT_DESKTOP");
+ if (curdesktop) {
+ const gchar *desksession = g_getenv("DESKTOP_SESSION");
+
+ if (desksession && !g_str_equal(curdesktop, desksession))
+ return g_strdup(desksession);
+ }
+
+ return g_strdup_printf(_("Unknown (Window Manager: %s)"), windowman);
+}
+
+static gchar *
+desktop_with_session_type(const gchar *desktop_env)
+{
+ const char *tmp;
+
+ tmp = g_getenv("XDG_SESSION_TYPE");
if (tmp) {
- /* FIXME: this might not be true, as the gnome-panel in path
- may not be the one that's running.
- see where the user's running panel is and run *that* to
- obtain the version. */
- version = popen("gnome-about --gnome-version", "r");
- if (version) {
- (void)fscanf(version, _("Version: %s"), vers);
- if (pclose(version))
- goto unknown;
- } else {
- goto unknown;
- }
-
- os->desktop = g_strdup_printf("GNOME %s", vers);
- } else if (g_getenv("KDE_FULL_SESSION")) {
-
- if (g_getenv("KDE_SESSION_VERSION") && strstr(g_getenv("KDE_SESSION_VERSION"),(gchar *)"4")) {
- version = popen("kwin --version", "r");
- } else {
- version = popen("kcontrol --version", "r");
- }
-
- if (version) {
- char buf[32];
-
- (void)fgets(buf, 32, version);
-
- (void)fscanf(version, "KDE: %s", vers);
- if (pclose(version))
- goto unknown;
- } else {
- goto unknown;
- }
-
- os->desktop = g_strdup_printf("KDE %s", vers);
- } else {
- unknown:
- os->desktop = NULL;
-
- if (!g_getenv("DISPLAY")) {
- os->desktop = g_strdup(_("Terminal"));
- } else {
- GdkScreen *screen = gdk_screen_get_default();
-
- if (screen && GDK_IS_SCREEN(screen)) {
- const gchar *windowman;
-
- windowman = gdk_x11_screen_get_window_manager_name(screen);
- if (g_str_equal(windowman, "Xfwm4")) {
- /* FIXME: check if xprop -root | grep XFCE_DESKTOP_WINDOW is defined */
- os->desktop = g_strdup("XFCE 4");
- } else if ((tmp = g_getenv("XDG_CURRENT_DESKTOP"))) {
- os->desktop = g_strdup(tmp);
- if ((tmp = g_getenv("DESKTOP_SESSION")) && !g_str_equal(os->desktop, tmp)) {
- g_free(os->desktop);
- os->desktop = g_strdup(tmp);
- }
- }
-
- if (!os->desktop) {
- os->desktop = g_strdup_printf(_("Unknown (Window Manager: %s)"),
- windowman);
- }
- } else {
- os->desktop = g_strdup(_("Unknown"));
- }
- }
+ if (!g_str_equal(tmp, "unspecified"))
+ return g_strdup_printf(_(/*/{desktop environment} on {session type}*/ "%s on %s"), desktop_env, tmp);
+ }
+
+ return g_strdup(desktop_env);
+}
+
+static gchar *
+detect_xdg_environment(const gchar *env_var)
+{
+ const gchar *tmp;
+
+ tmp = g_getenv(env_var);
+ if (!tmp)
+ return NULL;
+
+ if (g_str_equal(tmp, "GNOME") || g_str_equal(tmp, "gnome")) {
+ gchar *maybe_gnome = detect_gnome_version();
+
+ if (maybe_gnome)
+ return maybe_gnome;
}
+ if (g_str_equal(tmp, "KDE") || g_str_equal(tmp, "kde")) {
+ gchar *maybe_kde = detect_kde_version();
+
+ if (maybe_kde)
+ return maybe_kde;
+ }
+
+ return g_strdup(tmp);
+}
+
+static gchar *
+detect_desktop_environment(void)
+{
+ const gchar *tmp;
+ gchar *windowman;
+
+ windowman = detect_xdg_environment("XDG_CURRENT_DESKTOP");
+ if (windowman)
+ return windowman;
+ windowman = detect_xdg_environment("XDG_SESSION_DESKTOP");
+ if (windowman)
+ return windowman;
+
+ tmp = g_getenv("KDE_FULL_SESSION");
+ if (tmp) {
+ gchar *maybe_kde = detect_kde_version();
+
+ if (maybe_kde)
+ return maybe_kde;
+ }
+ tmp = g_getenv("GNOME_DESKTOP_SESSION_ID");
+ if (tmp) {
+ gchar *maybe_gnome = detect_gnome_version();
+
+ if (maybe_gnome)
+ return maybe_gnome;
+ }
+
+ windowman = detect_window_manager();
+ if (windowman)
+ return windowman;
+
+ if (!g_getenv("DISPLAY"))
+ return g_strdup(_("Terminal"));
+
+ return g_strdup(_("Unknown"));
}
gchar *
computer_get_entropy_avail(void)
{
+ gchar tab_entropy_fstr[][32] = {
+ N_(/*/bits of entropy for rng (0)*/ "(None or not available)"),
+ N_(/*/bits of entropy for rng (low/poor value)*/ "%d bits (low)"),
+ N_(/*/bits of entropy for rng (medium value)*/ "%d bits (medium)"),
+ N_(/*/bits of entropy for rng (high/good value)*/ "%d bits (healthy)")
+ };
gint bits = h_sysfs_read_int("/proc/sys/kernel/random", "entropy_avail");
- if (bits < 200)
- return g_strdup_printf("%d bits (low)", bits);
- if (bits < 3000)
- return g_strdup_printf("%d bits (medium)", bits);
- return g_strdup_printf("%d bits (healthy)", bits);
+ if (bits > 3000) return g_strdup_printf(_(tab_entropy_fstr[3]), bits);
+ if (bits > 200) return g_strdup_printf(_(tab_entropy_fstr[2]), bits);
+ if (bits > 1) return g_strdup_printf(_(tab_entropy_fstr[1]), bits);
+ return g_strdup_printf(_(tab_entropy_fstr[0]), bits);
}
-OperatingSystem *
-computer_get_os(void)
+gchar *
+computer_get_language(void)
{
- struct utsname utsbuf;
- OperatingSystem *os;
+ gchar *tab_lang_env[] =
+ { "LANGUAGE", "LANG", "LC_ALL", "LC_MESSAGES", NULL };
+ gchar *lc = NULL, *env = NULL, *ret = NULL;
+ gint i = 0;
+
+ lc = setlocale(LC_ALL, NULL);
+
+ while (tab_lang_env[i] != NULL) {
+ env = g_strdup( g_getenv(tab_lang_env[i]) );
+ if (env != NULL) break;
+ i++;
+ }
+
+ if (env != NULL)
+ if (lc != NULL)
+ ret = g_strdup_printf("%s (%s)", lc, env);
+ else
+ ret = g_strdup_printf("%s", env);
+ else
+ if (lc != NULL)
+ ret = g_strdup_printf("%s", lc);
+
+ if (ret == NULL)
+ ret = g_strdup( _("(Unknown)") );
+
+ return ret;
+}
+
+static gchar *
+detect_distro(void)
+{
+ static const struct {
+ const gchar *file;
+ const gchar *codename;
+ const gchar *override;
+ } distro_db[] = {
+#define DB_PREFIX "/etc/"
+ { DB_PREFIX "arch-release", "arch", "Arch Linux" },
+ { DB_PREFIX "fatdog-version", "fatdog" },
+ { DB_PREFIX "debian_version", "deb" },
+ { DB_PREFIX "slackware-version", "slk" },
+ { DB_PREFIX "mandrake-release", "mdk" },
+ { DB_PREFIX "mandriva-release", "mdv" },
+ { DB_PREFIX "fedora-release", "fdra" },
+ { DB_PREFIX "coas", "coas" },
+ { DB_PREFIX "environment.corel", "corel"},
+ { DB_PREFIX "gentoo-release", "gnt" },
+ { DB_PREFIX "conectiva-release", "cnc" },
+ { DB_PREFIX "versão-conectiva", "cnc" },
+ { DB_PREFIX "turbolinux-release", "tl" },
+ { DB_PREFIX "yellowdog-release", "yd" },
+ { DB_PREFIX "sabayon-release", "sbn" },
+ { DB_PREFIX "arch-release", "arch" },
+ { DB_PREFIX "enlisy-release", "enlsy" },
+ { DB_PREFIX "SuSE-release", "suse" },
+ { DB_PREFIX "sun-release", "sun" },
+ { DB_PREFIX "zenwalk-version", "zen" },
+ { DB_PREFIX "DISTRO_SPECS", "ppy", "Puppy Linux" },
+ { DB_PREFIX "puppyversion", "ppy", "Puppy Linux" },
+ { DB_PREFIX "distro-release", "fl" },
+ { DB_PREFIX "vine-release", "vine" },
+ { DB_PREFIX "PartedMagic-version", "pmag" },
+ /*
+ * RedHat must be the *last* one to be checked, since
+ * some distros (like Mandrake) includes a redhat-relase
+ * file too.
+ */
+ { DB_PREFIX "redhat-release", "rh" },
+#undef DB_PREFIX
+ { NULL, NULL }
+ };
+ gchar *contents;
int i;
- os = g_new0(OperatingSystem, 1);
+ if (g_spawn_command_line_sync("lsb_release -d", &contents, NULL, NULL, NULL)) {
+ gchar *tmp = strstr(idle_free(contents), "Description:\t");
- /* Attempt to get the Distribution name; try using /etc/lsb-release first,
- then doing the legacy method (checking for /etc/$DISTRO-release files) */
- if (g_file_test("/etc/lsb-release", G_FILE_TEST_EXISTS)) {
- FILE *release;
- gchar buffer[128];
+ if (tmp)
+ return g_strdup(tmp + strlen("Description:\t"));
+ }
- release = popen("lsb_release -d", "r");
- if (release) {
- (void)fgets(buffer, 128, release);
- pclose(release);
+ for (i = 0; distro_db[i].file; i++) {
+ if (!g_file_get_contents(distro_db[i].file, &contents, NULL, NULL))
+ continue;
- os->distro = buffer;
- os->distro = g_strdup(os->distro + strlen("Description:\t"));
+ if (distro_db[i].override) {
+ g_free(contents);
+ return g_strdup(distro_db[i].override);
}
- } else if (g_file_test("/etc/arch-release", G_FILE_TEST_EXISTS)) {
- os->distrocode = g_strdup("arch");
- os->distro = g_strdup("Arch Linux");
- } else {
- for (i = 0;; i++) {
- if (distro_db[i].file == NULL) {
- os->distrocode = g_strdup("unk");
- os->distro = g_strdup(_("Unknown distribution"));
- break;
- }
- if (g_file_test(distro_db[i].file, G_FILE_TEST_EXISTS)) {
- FILE *distro_ver;
- char buf[128];
-
- distro_ver = fopen(distro_db[i].file, "r");
- if (distro_ver) {
- (void)fgets(buf, 128, distro_ver);
- fclose(distro_ver);
- } else {
- continue;
- }
-
- buf[strlen(buf) - 1] = 0;
-
- if (!os->distro) {
- /*
- * HACK: Some Debian systems doesn't include
- * the distribuition name in /etc/debian_release,
- * so add them here.
- */
- if (!strncmp(distro_db[i].codename, "deb", 3) &&
- ((buf[0] >= '0' && buf[0] <= '9') || buf[0] != 'D')) {
- os->distro = g_strdup_printf
- ("Debian GNU/Linux %s", buf);
- } else {
- os->distro = g_strdup(buf);
- }
- }
-
- if (g_str_equal(distro_db[i].codename, "ppy")) {
- gchar *tmp;
- tmp = g_strdup_printf("Puppy Linux");
- g_free(os->distro);
- os->distro = tmp;
- }
-
- if (g_str_equal(distro_db[i].codename, "fatdog")) {
- gchar *tmp;
- tmp = g_strdup_printf("Fatdog64 [%.10s]", os->distro);
- g_free(os->distro);
- os->distro = tmp;
- }
-
- os->distrocode = g_strdup(distro_db[i].codename);
-
- break;
- }
+ if (g_str_equal(distro_db[i].codename, "deb")) {
+ /* HACK: Some Debian systems doesn't include the distribuition
+ * name in /etc/debian_release, so add them here. */
+ if (isdigit(contents[0]) || contents[0] != 'D')
+ return g_strdup_printf("Debian GNU/Linux %s", (char*)idle_free(contents));
}
+
+ if (g_str_equal(distro_db[i].codename, "fatdog"))
+ return g_strdup_printf("Fatdog64 [%.10s]", (char*)idle_free(contents));
+
+ return contents;
}
- os->distro = g_strstrip(os->distro);
+ return g_strdup(_("Unknown"));
+}
+
+OperatingSystem *
+computer_get_os(void)
+{
+ struct utsname utsbuf;
+ OperatingSystem *os;
+ int i;
+
+ os = g_new0(OperatingSystem, 1);
+
+ os->distro = g_strstrip(detect_distro());
/* Kernel and hostname info */
uname(&utsbuf);
@@ -244,13 +376,16 @@ computer_get_os(void)
os->kernel = g_strdup_printf("%s %s (%s)", utsbuf.sysname,
utsbuf.release, utsbuf.machine);
os->hostname = g_strdup(utsbuf.nodename);
- os->language = g_strdup(g_getenv("LC_MESSAGES"));
+ os->language = computer_get_language();
os->homedir = g_strdup(g_get_home_dir());
os->username = g_strdup_printf("%s (%s)",
g_get_user_name(), g_get_real_name());
os->libc = get_libc_version();
scan_languages(os);
- detect_desktop_environment(os);
+
+ os->desktop = detect_desktop_environment();
+ if (os->desktop)
+ os->desktop = desktop_with_session_type(idle_free(os->desktop));
os->entropy_avail = computer_get_entropy_avail();
diff --git a/modules/computer/uptime.c b/modules/computer/uptime.c
index 8eb563fa..5f0f1942 100644
--- a/modules/computer/uptime.c
+++ b/modules/computer/uptime.c
@@ -26,11 +26,11 @@ computer_get_uptime(void)
gulong minutes;
if ((procuptime = fopen("/proc/uptime", "r")) != NULL) {
- (void)fscanf(procuptime, "%lu", &minutes);
- ui->minutes = minutes / 60;
- fclose(procuptime);
+ (void)fscanf(procuptime, "%lu", &minutes);
+ ui->minutes = minutes / 60;
+ fclose(procuptime);
} else {
- return NULL;
+ return NULL;
}
ui->hours = ui->minutes / 60;
@@ -45,32 +45,27 @@ gchar *
computer_get_formatted_uptime()
{
UptimeInfo *ui;
- gchar *tmp;
+ const gchar *days_fmt, *hours_fmt, *minutes_fmt;
+ gchar *full_fmt = NULL, *ret = NULL;
ui = computer_get_uptime();
- /* FIXME: Use ngettext */
-#define plural(x) ((x > 1) ? "s" : "")
+ days_fmt = ngettext("%d day", "%d days", ui->days);
+ hours_fmt = ngettext("%d hour", "%d hours", ui->hours);
+ minutes_fmt = ngettext("%d minute", "%d minutes", ui->minutes);
if (ui->days < 1) {
- if (ui->hours < 1) {
- tmp =
- g_strdup_printf("%d minute%s", ui->minutes,
- plural(ui->minutes));
- } else {
- tmp =
- g_strdup_printf("%d hour%s, %d minute%s", ui->hours,
- plural(ui->hours), ui->minutes,
- plural(ui->minutes));
- }
+ if (ui->hours < 1) {
+ ret = g_strdup_printf(minutes_fmt, ui->minutes);
+ } else {
+ full_fmt = g_strdup_printf("%s %s", hours_fmt, minutes_fmt);
+ ret = g_strdup_printf(full_fmt, ui->hours, ui->minutes);
+ }
} else {
- tmp =
- g_strdup_printf("%d day%s, %d hour%s and %d minute%s",
- ui->days, plural(ui->days), ui->hours,
- plural(ui->hours), ui->minutes,
- plural(ui->minutes));
+ full_fmt = g_strdup_printf("%s %s %s", days_fmt, hours_fmt, minutes_fmt);
+ ret = g_strdup_printf(full_fmt, ui->days, ui->hours, ui->minutes);
}
-
+ g_free(full_fmt);
g_free(ui);
- return tmp;
+ return ret;
}
diff --git a/modules/computer/users.c b/modules/computer/users.c
index e8f891ac..f47320bb 100644
--- a/modules/computer/users.c
+++ b/modules/computer/users.c
@@ -39,15 +39,16 @@ scan_users_do(void)
while (passwd_) {
gchar *key = g_strdup_printf("USER%s", passwd_->pw_name);
- gchar *val = g_strdup_printf("[User Information]\n"
- "User ID=%d\n"
- "Group ID=%d\n"
- "Home directory=%s\n"
- "Default shell=%s\n",
- (gint) passwd_->pw_uid,
- (gint) passwd_->pw_gid,
- passwd_->pw_dir,
- passwd_->pw_shell);
+ gchar *val = g_strdup_printf("[%s]\n"
+ "%s=%d\n"
+ "%s=%d\n"
+ "%s=%s\n"
+ "%s=%s\n",
+ _("User Information"),
+ _("User ID"), (gint) passwd_->pw_uid,
+ _("Group ID"), (gint) passwd_->pw_gid,
+ _("Home Directory"), passwd_->pw_dir,
+ _("Default Shell"), passwd_->pw_shell);
moreinfo_add_with_prefix("COMP", key, val);
strend(passwd_->pw_gecos, ',');
@@ -55,6 +56,6 @@ scan_users_do(void)
passwd_ = getpwent();
g_free(key);
}
-
+
endpwent();
}
diff --git a/modules/devices.c b/modules/devices.c
index 87bb8a80..9c7a184d 100644
--- a/modules/devices.c
+++ b/modules/devices.c
@@ -37,6 +37,7 @@
#include <socket.h>
#include "devices.h"
+#include "dt_util.h"
gchar *callback_processors();
gchar *callback_memory();
@@ -51,6 +52,7 @@ gchar *callback_usb();
gchar *callback_dmi();
gchar *callback_spd();
#endif
+gchar *callback_dtree();
gchar *callback_device_resources();
void scan_processors(gboolean reload);
@@ -66,6 +68,7 @@ void scan_usb(gboolean reload);
void scan_dmi(gboolean reload);
void scan_spd(gboolean reload);
#endif
+void scan_dtree(gboolean reload);
void scan_device_resources(gboolean reload);
gboolean root_required_for_resources(void);
@@ -73,6 +76,7 @@ gboolean root_required_for_resources(void);
gchar *hi_more_info(gchar *entry);
enum {
+ ENTRY_DTREE,
ENTRY_PROCESSOR,
ENTRY_MEMORY,
ENTRY_PCI,
@@ -100,9 +104,14 @@ static ModuleEntry entries[] = {
#if defined(ARCH_x86) || defined(ARCH_x86_64)
[ENTRY_DMI] = {N_("DMI"), "computer.png", callback_dmi, scan_dmi, MODULE_FLAG_NONE},
[ENTRY_SPD] = {N_("Memory SPD"), "memory.png", callback_spd, scan_spd, MODULE_FLAG_NONE},
+ [ENTRY_DTREE] = {"#"},
+#else
+ [ENTRY_DMI] = {"#"},
+ [ENTRY_SPD] = {"#"},
+ [ENTRY_DTREE] = {N_("Device Tree"), "devices.png", callback_dtree, scan_dtree, MODULE_FLAG_NONE},
#endif /* x86 or x86_64 */
[ENTRY_RESOURCES] = {N_("Resources"), "resources.png", callback_device_resources, scan_device_resources, MODULE_FLAG_NONE},
- {NULL}
+ { NULL }
};
static GSList *processors = NULL;
@@ -117,21 +126,127 @@ gchar *lginterval = NULL;
#include <vendor.h>
-gchar *get_processor_name(void)
+static gint proc_cmp_model_name(Processor *a, Processor *b) {
+ return g_strcmp0(a->model_name, b->model_name);
+}
+
+static gint proc_cmp_max_freq(Processor *a, Processor *b) {
+ if (a->cpu_mhz == b->cpu_mhz)
+ return 0;
+ if (a->cpu_mhz > b->cpu_mhz)
+ return -1;
+ return 1;
+}
+
+gchar *processor_describe_default(GSList * processors)
{
- scan_processors(FALSE);
+ int packs, cores, threads;
+ const gchar *packs_fmt, *cores_fmt, *threads_fmt;
+ gchar *ret, *full_fmt;
- Processor *p = (Processor *) processors->data;
+ cpu_procs_cores_threads(&packs, &cores, &threads);
- if (g_slist_length(processors) > 1) {
- return idle_free(g_strdup_printf("%dx %s",
- g_slist_length(processors),
- p->model_name));
+ /* if topology info was available, else fallback to old method */
+ if (cores > 0) {
+ packs_fmt = ngettext("%d physical processor", "%d physical processors", packs);
+ cores_fmt = ngettext("%d core", "%d cores", cores);
+ threads_fmt = ngettext("%d thread", "%d threads", threads);
+ full_fmt = g_strdup_printf(_(/*/NP procs; NC cores; NT threads*/ "%s; %s; %s"), packs_fmt, cores_fmt, threads_fmt);
+ ret = g_strdup_printf(full_fmt, packs, cores, threads);
+ g_free(full_fmt);
+ return ret;
} else {
- return p->model_name;
+ return processor_describe_by_counting_names(processors);
+ }
+}
+
+gchar *processor_name_default(GSList * processors)
+{
+ gchar *ret = g_strdup("");
+ GSList *tmp, *l;
+ Processor *p;
+ gchar *cur_str = NULL;
+ gint cur_count = 0;
+
+ tmp = g_slist_copy(processors);
+ tmp = g_slist_sort(tmp, (GCompareFunc)proc_cmp_model_name);
+
+ for (l = tmp; l; l = l->next) {
+ p = (Processor*)l->data;
+ if (cur_str == NULL) {
+ cur_str = p->model_name;
+ cur_count = 1;
+ } else {
+ if(g_strcmp0(cur_str, p->model_name)) {
+ ret = h_strdup_cprintf("%s%s", ret, strlen(ret) ? "; " : "", cur_str);
+ cur_str = p->model_name;
+ cur_count = 1;
+ } else {
+ cur_count++;
+ }
+ }
+ }
+ ret = h_strdup_cprintf("%s%s", ret, strlen(ret) ? "; " : "", cur_str);
+ g_slist_free(tmp);
+ return ret;
+}
+
+/* TODO: prefix counts are threads when they should be cores. */
+gchar *processor_describe_by_counting_names(GSList * processors)
+{
+ gchar *ret = g_strdup("");
+ GSList *tmp, *l;
+ Processor *p;
+ gchar *cur_str = NULL;
+ gint cur_count = 0;
+
+ tmp = g_slist_copy(processors);
+ tmp = g_slist_sort(tmp, (GCompareFunc)proc_cmp_model_name);
+
+ for (l = tmp; l; l = l->next) {
+ p = (Processor*)l->data;
+ if (cur_str == NULL) {
+ cur_str = p->model_name;
+ cur_count = 1;
+ } else {
+ if(g_strcmp0(cur_str, p->model_name)) {
+ ret = h_strdup_cprintf("%s%dx %s", ret, strlen(ret) ? " + " : "", cur_count, cur_str);
+ cur_str = p->model_name;
+ cur_count = 1;
+ } else {
+ cur_count++;
+ }
+ }
}
+ ret = h_strdup_cprintf("%s%dx %s", ret, strlen(ret) ? " + " : "", cur_count, cur_str);
+ g_slist_free(tmp);
+ return ret;
+}
+
+gchar *get_processor_name(void)
+{
+ scan_processors(FALSE);
+ return processor_name(processors);
+}
+
+gchar *get_processor_desc(void)
+{
+ scan_processors(FALSE);
+ return processor_describe(processors);
+}
+
+gchar *get_processor_name_and_desc(void)
+{
+ scan_processors(FALSE);
+ gchar* name = processor_name(processors);
+ gchar* desc = processor_describe(processors);
+ gchar* nd = g_strdup_printf("%s\n%s", name, desc);
+ g_free(name);
+ g_free(desc);
+ return nd;
}
+
gchar *get_storage_devices(void)
{
scan_storage(FALSE);
@@ -160,175 +275,127 @@ gchar *get_processor_count(void)
return g_strdup_printf("%d", g_slist_length(processors));
}
-gchar *get_processor_frequency(void)
+/* TODO: maybe move into processor.c along with processor_name() etc.
+ * Could mention the big.LITTLE cluster arangement for ARM that kind of thing.
+ * TODO: prefix counts are threads when they should be cores. */
+gchar *processor_frequency_desc(GSList * processors)
+{
+ gchar *ret = g_strdup("");
+ GSList *tmp, *l;
+ Processor *p;
+ float cur_val = -1;
+ gint cur_count = 0;
+
+ tmp = g_slist_copy(processors);
+ tmp = g_slist_sort(tmp, (GCompareFunc)proc_cmp_max_freq);
+
+ for (l = tmp; l; l = l->next) {
+ p = (Processor*)l->data;
+ if (cur_val == -1) {
+ cur_val = p->cpu_mhz;
+ cur_count = 1;
+ } else {
+ if(cur_val != p->cpu_mhz) {
+ ret = h_strdup_cprintf("%s%dx %.2f %s", ret, strlen(ret) ? " + " : "", cur_count, cur_val, _("MHz") );
+ cur_val = p->cpu_mhz;
+ cur_count = 1;
+ } else {
+ cur_count++;
+ }
+ }
+ }
+ ret = h_strdup_cprintf("%s%dx %.2f %s", ret, strlen(ret) ? " + " : "", cur_count, cur_val, _("MHz"));
+ g_slist_free(tmp);
+ return ret;
+}
+
+gchar *get_processor_frequency_desc(void)
+{
+ scan_processors(FALSE);
+ return processor_frequency_desc(processors);
+}
+
+gchar *get_processor_max_frequency(void)
{
+ GSList *l;
Processor *p;
+ float max_freq = 0;
scan_processors(FALSE);
- p = (Processor *)processors->data;
- if (p->cpu_mhz == 0.0f) {
+ for (l = processors; l; l = l->next) {
+ p = (Processor*)l->data;
+ if (p->cpu_mhz > max_freq)
+ max_freq = p->cpu_mhz;
+ }
+
+ if (max_freq == 0.0f) {
return g_strdup(N_("Unknown"));
} else {
- return g_strdup_printf("%.0f", p->cpu_mhz);
+ return g_strdup_printf("%.2f %s", max_freq, _("MHz") );
}
}
gchar *get_pci_device_description(gchar *pci_id)
{
gchar *description;
-
+
if (!_pci_devices) {
scan_pci(FALSE);
}
-
+
if ((description = g_hash_table_lookup(_pci_devices, pci_id))) {
return g_strdup(description);
}
-
+
return NULL;
}
gchar *get_memory_total(void)
{
scan_memory(FALSE);
- return moreinfo_lookup ("DEV:Total Memory"); //hi_more_info(N_("Total Memory"));
-}
-
-/* information table from: http://elinux.org/RPi_HardwareHistory */
-static struct {
- char *value, *intro, *model, *pcb, *mem, *mfg;
-} rpi_boardinfo[] = {
-/* Value Introduction Model Name PCB rev. Memory Manufacturer *
- * Raspberry Pi %s */
- { "Beta", "Q1 2012", "B (Beta)", "?", "256MB", "(Beta board)" },
- { "0002", "Q1 2012", "B", "1.0", "256MB", "?" },
- { "0003", "Q3 2012", "B (ECN0001)", "1.0", "256MB", "(Fuses mod and D14 removed)" },
- { "0004", "Q3 2012", "B", "2.0", "256MB", "Sony" },
- { "0005", "Q4 2012", "B", "2.0", "256MB", "Qisda" },
- { "0006", "Q4 2012", "B", "2.0", "256MB", "Egoman" },
- { "0007", "Q1 2013", "A", "2.0", "256MB", "Egoman" },
- { "0008", "Q1 2013", "A", "2.0", "256MB", "Sony" },
- { "0009", "Q1 2013", "A", "2.0", "256MB", "Qisda" },
- { "000d", "Q4 2012", "B", "2.0", "512MB", "Egoman" },
- { "000e", "Q4 2012", "B", "2.0", "512MB", "Sony" },
- { "000f", "Q4 2012", "B", "2.0", "512MB", "Qisda" },
- { "0010", "Q3 2014", "B+", "1.0", "512MB", "Sony" },
- { "0011", "Q2 2014", "Compute Module 1", "1.0", "512MB", "Sony" },
- { "0012", "Q4 2014", "A+", "1.1", "256MB", "Sony" },
- { "0013", "Q1 2015", "B+", "1.2", "512MB", "?" },
- { "0014", "Q2 2014", "Compute Module 1", "1.0", "512MB", "Embest" },
- { "0015", "?", "A+", "1.1", "256MB/512MB", "Embest" },
- { "a01040", "Unknown", "2 Model B", "1.0", "1GB", "Sony" },
- { "a01041", "Q1 2015", "2 Model B", "1.1", "1GB", "Sony" },
- { "a21041", "Q1 2015", "2 Model B", "1.1", "1GB", "Embest" },
- { "a22042", "Q3 2016", "2 Model B", "1.2", "1GB", "Embest" }, /* (with BCM2837) */
- { "900021", "Q3 2016", "A+", "1.1", "512MB", "Sony" },
- { "900032", "Q2 2016?", "B+", "1.2", "512MB", "Sony" },
- { "900092", "Q4 2015", "Zero", "1.2", "512MB", "Sony" },
- { "900093", "Q2 2016", "Zero", "1.3", "512MB", "Sony" },
- { "920093", "Q4 2016?", "Zero", "1.3", "512MB", "Embest" },
- { "9000c1", "Q1 2017", "Zero W", "1.1", "512MB", "Sony" },
- { "a02082", "Q1 2016", "3 Model B", "1.2", "1GB", "Sony" },
- { "a020a0", "Q1 2017", "Compute Module 3 or CM3 Lite", "1.0", "1GB", "Sony" },
- { "a22082", "Q1 2016", "3 Model B", "1.2", "1GB", "Embest" },
- { "a32082", "Q4 2016", "3 Model B", "1.2", "1GB", "Sony Japan" },
- { NULL, NULL, NULL, NULL, NULL, NULL }
-};
-
-static gchar *rpi_get_boardname(void) {
- int i = 0, c = 0;
- gchar *ret = NULL;
- gchar *soc = NULL;
- gchar *revision = NULL;
- int overvolt = 0;
- FILE *cpuinfo;
- gchar buffer[128];
-
- cpuinfo = fopen("/proc/cpuinfo", "r");
- if (!cpuinfo)
- return NULL;
- while (fgets(buffer, 128, cpuinfo)) {
- gchar **tmp = g_strsplit(buffer, ":", 2);
- tmp[0] = g_strstrip(tmp[0]);
- tmp[1] = g_strstrip(tmp[1]);
- get_str("Revision", revision);
- get_str("Hardware", soc);
- }
- fclose(cpuinfo);
-
- if (revision == NULL || soc == NULL) {
- g_free(soc);
- g_free(revision);
- return NULL;
- }
-
- if (g_str_has_prefix(revision, "1000"))
- overvolt = 1;
-
- while (rpi_boardinfo[i].value != NULL) {
- if (overvolt)
- /* +4 to ignore the 1000 prefix */
- c = g_strcmp0(revision+4, rpi_boardinfo[i].value);
- else
- c = g_strcmp0(revision, rpi_boardinfo[i].value);
-
- if (c == 0) {
- ret = g_strdup_printf("Raspberry Pi %s (%s) pcb-rev:%s soc:%s mem:%s mfg-by:%s%s",
- rpi_boardinfo[i].model, rpi_boardinfo[i].intro,
- rpi_boardinfo[i].pcb, soc,
- rpi_boardinfo[i].mem, rpi_boardinfo[i].mfg,
- (overvolt) ? " (over-volted)" : "" );
- break;
- }
- i++;
- }
- g_free(soc);
- g_free(revision);
- return ret;
+ return moreinfo_lookup ("DEV:MemTotal");
}
gchar *get_motherboard(void)
{
- char *board_name, *board_vendor;
+ char *board_name, *board_vendor, *product_version;
+
#if defined(ARCH_x86) || defined(ARCH_x86_64)
scan_dmi(FALSE);
board_name = moreinfo_lookup("DEV:DMI:Board:Name");
board_vendor = moreinfo_lookup("DEV:DMI:Board:Vendor");
-
- if (board_name && board_vendor && *board_name && *board_vendor)
- return g_strconcat(board_vendor, " ", board_name, NULL);
- else if (board_name && *board_name)
- return g_strconcat(board_name, _(" (vendor unknown)"), NULL);
- else if (board_vendor && *board_vendor)
- return g_strconcat(board_vendor, _(" (model unknown)"), NULL);
-#else
- /* use device tree "model" */
- if (g_file_get_contents("/proc/device-tree/model", &board_vendor, NULL, NULL)) {
-
- /* if a raspberry pi, try and get a more detailed name */
- if (g_str_has_prefix(board_vendor, "Raspberry Pi")) {
- board_name = rpi_get_boardname();
- if (board_name != NULL) {
- g_free(board_vendor);
- return board_name;
- }
- }
+ product_version = moreinfo_lookup("DEV:DMI:Product:Version#1");
- return board_vendor;
- }
+ if (!board_name || !*board_name)
+ board_name = _(" (model unknown)");
+ if (!board_vendor || !*board_vendor)
+ board_vendor = _(" (vendor unknown)");
+
+ if (product_version && *product_version)
+ return g_strdup_printf("%s / %s (%s)", product_version, board_name, board_vendor);
+
+ return g_strconcat(board_vendor, " ", board_name, NULL);
#endif
+ /* use device tree "model" */
+ board_vendor = dtr_get_string("/model", 0);
+ if (board_vendor != NULL)
+ return board_vendor;
+
return g_strdup(_("Unknown"));
}
ShellModuleMethod *hi_exported_methods(void)
{
static ShellModuleMethod m[] = {
- {"getProcessorCount", get_processor_count},
+ {"getProcessorCount", get_processor_count},
{"getProcessorName", get_processor_name},
- {"getProcessorFrequency", get_processor_frequency},
+ {"getProcessorDesc", get_processor_desc},
+ {"getProcessorNameAndDesc", get_processor_name_and_desc},
+ {"getProcessorFrequency", get_processor_max_frequency},
+ {"getProcessorFrequencyDesc", get_processor_frequency_desc},
{"getMemoryTotal", get_memory_total},
{"getStorageDevices", get_storage_devices},
{"getPrinters", get_printers},
@@ -344,7 +411,7 @@ ShellModuleMethod *hi_exported_methods(void)
gchar *hi_more_info(gchar * entry)
{
gchar *info = moreinfo_lookup_with_prefix("DEV", entry);
-
+
if (info)
return g_strdup(info);
@@ -377,6 +444,13 @@ void scan_spd(gboolean reload)
}
#endif
+void scan_dtree(gboolean reload)
+{
+ SCAN_START();
+ __scan_dtree();
+ SCAN_END();
+}
+
void scan_processors(gboolean reload)
{
SCAN_START();
@@ -462,15 +536,28 @@ gchar *callback_spd()
}
#endif
+gchar *callback_dtree()
+{
+ return g_strdup_printf("%s"
+ "[$ShellParam$]\n"
+ "ViewType=1\n", dtree_info);
+}
+
gchar *callback_memory()
{
return g_strdup_printf("[Memory]\n"
- "%s\n"
- "[$ShellParam$]\n"
- "ViewType=2\n"
- "LoadGraphSuffix= kB\n"
- "RescanInterval=2000\n"
- "%s\n", meminfo, lginterval);
+ "%s\n"
+ "[$ShellParam$]\n"
+ "ViewType=2\n"
+ "LoadGraphSuffix= kB\n"
+ "RescanInterval=2000\n"
+ "ColumnTitle$TextValue=%s\n"
+ "ColumnTitle$Extra1=%s\n"
+ "ColumnTitle$Value=%s\n"
+ "ShowColumnHeaders=true\n"
+ "%s\n", meminfo,
+ _("Field"), _("Description"), _("Value"), /* column labels */
+ lginterval);
}
gchar *callback_battery()
@@ -489,8 +576,20 @@ gchar *callback_pci()
gchar *callback_sensors()
{
- return g_strdup_printf("[$ShellParam$]\n"
- "ReloadInterval=5000\n" "%s", sensors);
+ return g_strdup_printf("[Sensors]\n"
+ "%s\n"
+ "[$ShellParam$]\n"
+ "ViewType=2\n"
+ "LoadGraphSuffix=\n"
+ "ColumnTitle$TextValue=%s\n"
+ "ColumnTitle$Value=%s\n"
+ "ColumnTitle$Extra1=%s\n"
+ "ShowColumnHeaders=true\n"
+ "RescanInterval=5000\n"
+ "%s",
+ sensors,
+ _("Sensor"), _("Value"), _("Type"), /* column labels */
+ lginterval);
}
gchar *callback_printers()
@@ -564,7 +663,7 @@ void hi_module_init(void)
.save_to = "cpuflags.conf",
.get_data = NULL
};
-
+
sync_manager_add_entry(&se);
}
#endif /* defined(ARCH_x86) */
@@ -606,7 +705,7 @@ const gchar *hi_note_func(gint entry)
{
if (entry == ENTRY_RESOURCES) {
if (root_required_for_resources()) {
- return g_strdup_printf(_("Resource information requires superuser privileges"));
+ return g_strdup(_("Resource information requires superuser privileges"));
}
}
return NULL;
diff --git a/modules/devices/alpha/processor.c b/modules/devices/alpha/processor.c
index f55526f7..c7862232 100644
--- a/modules/devices/alpha/processor.c
+++ b/modules/devices/alpha/processor.c
@@ -18,6 +18,7 @@
#include "hardinfo.h"
#include "devices.h"
+#include "cpu_util.h"
GSList *
processor_scan(void)
@@ -25,54 +26,69 @@ processor_scan(void)
Processor *processor;
FILE *cpuinfo;
gchar buffer[128];
+ long long hz = 0;
- cpuinfo = fopen("/proc/cpuinfo", "r");
+ cpuinfo = fopen(PROC_CPUINFO, "r");
if (!cpuinfo)
- return NULL;
+ return NULL;
processor = g_new0(Processor, 1);
while (fgets(buffer, 128, cpuinfo)) {
- gchar **tmp = g_strsplit(buffer, ":", 2);
+ gchar **tmp = g_strsplit(buffer, ":", 2);
- if (tmp[0] && tmp[1]) {
- tmp[0] = g_strstrip(tmp[0]);
- tmp[1] = g_strstrip(tmp[1]);
+ if (tmp[0] && tmp[1]) {
+ tmp[0] = g_strstrip(tmp[0]);
+ tmp[1] = g_strstrip(tmp[1]);
- get_str("cpu model", processor->model_name);
- get_float("BogoMIPS", processor->bogomips);
- get_str("platform string", processor->strmodel);
+ get_str("cpu model", processor->model_name);
+ get_float("BogoMIPS", processor->bogomips);
+ get_str("platform string", processor->strmodel);
+ get_str("cycle frequency [Hz]", processor->cycle_frequency_hz_str);
- }
- g_strfreev(tmp);
+ }
+ g_strfreev(tmp);
}
-
+
+ fclose(cpuinfo);
+
gchar *tmp = g_strconcat("Alpha ", processor->model_name, NULL);
g_free(processor->model_name);
processor->model_name = tmp;
- processor->cpu_mhz = 0.0f;
- fclose(cpuinfo);
+ if (processor->cycle_frequency_hz_str) {
+ hz = atoll(processor->cycle_frequency_hz_str);
+ processor->cpu_mhz = hz;
+ processor->cpu_mhz /= 1000000;
+ } else
+ processor->cpu_mhz = 0.0f;
return g_slist_append(NULL, processor);
}
+gchar *processor_name(GSList * processors) {
+ return processor_name_default(processors);
+}
+
+gchar *processor_describe(GSList * processors) {
+ return processor_describe_default(processors);
+}
+
gchar *
processor_get_info(GSList *processors)
{
- Processor *processor = (Processor *)processors->data;
+ Processor *processor = (Processor *)processors->data;
- return g_strdup_printf("[Processor]\n"
- "Model=%s\n"
- "Platform String=%s\n"
- "BogoMIPS=%.2f"
- "Byte Order=%s\n",
- processor->model_name,
- processor->strmodel,
- processor->bogomips,
-#if G_BYTE_ORDER == G_LITTLE_ENDIAN
- "Little Endian"
-#else
- "Big Endian"
-#endif
- );
+ return g_strdup_printf("[%s]\n"
+ "%s=%s\n"
+ "%s=%s\n"
+ "%s=%.2f %s\n" /* frequency */
+ "%s=%.2f\n" /* bogomips */
+ "%s=%s\n", /* byte order */
+ _("Processor"),
+ _("Model"), processor->model_name,
+ _("Platform String"), processor->strmodel,
+ _("Frequency"), processor->cpu_mhz, _("MHz"),
+ _("BogoMips"), processor->bogomips,
+ _("Byte Order"), byte_order_str()
+ );
}
diff --git a/modules/devices/arm/arm_data.c b/modules/devices/arm/arm_data.c
index 2e2cbe60..60e8ea34 100644
--- a/modules/devices/arm/arm_data.c
+++ b/modules/devices/arm/arm_data.c
@@ -23,6 +23,13 @@
#include <string.h>
#include "arm_data.h"
+#ifndef C_
+#define C_(Ctx, String) String
+#endif
+#ifndef NC_
+#define NC_(Ctx, String) String
+#endif
+
/* sources:
* https://unix.stackexchange.com/a/43563
* git:linux/arch/arm/kernel/setup.c
@@ -32,47 +39,46 @@ static struct {
char *name, *meaning;
} tab_flag_meaning[] = {
/* arm/hw_cap */
- { "swp", "SWP instruction (atomic read-modify-write)" },
- { "half", "Half-word loads and stores" },
- { "thumb", "Thumb (16-bit instruction set)" },
- { "26bit", "26-Bit Model (Processor status register folded into program counter)" },
- { "fastmult", "32x32->64-bit multiplication" },
- { "fpa", "Floating point accelerator" },
- { "vfp", "VFP (early SIMD vector floating point instructions)" },
- { "edsp", "DSP extensions (the 'e' variant of the ARM9 CPUs, and all others above)" },
- { "java", "Jazelle (Java bytecode accelerator)" },
- { "iwmmxt", "SIMD instructions similar to Intel MMX" },
- { "crunch", "MaverickCrunch coprocessor (if kernel support enabled)" },
- { "thumbee", "ThumbEE" },
- { "neon", "Advanced SIMD/NEON on AArch32" },
- { "evtstrm", "kernel event stream using generic architected timer" },
- { "vfpv3", "VFP version 3" },
- { "vfpv3d16", "VFP version 3 with 16 D-registers" },
- { "vfpv4", "VFP version 4 with fast context switching" },
- { "vfpd32", "VFP with 32 D-registers" },
- { "tls", "TLS register" },
- { "idiva", "SDIV and UDIV hardware division in ARM mode" },
- { "idivt", "SDIV and UDIV hardware division in Thumb mode" },
- { "lpae", "40-bit Large Physical Address Extension" },
+ { "swp", NC_("arm-flag", /*/flag:swp*/ "SWP instruction (atomic read-modify-write)") },
+ { "half", NC_("arm-flag", /*/flag:half*/ "Half-word loads and stores") },
+ { "thumb", NC_("arm-flag", /*/flag:thumb*/ "Thumb (16-bit instruction set)") },
+ { "26bit", NC_("arm-flag", /*/flag:26bit*/ "26-Bit Model (Processor status register folded into program counter)") },
+ { "fastmult", NC_("arm-flag", /*/flag:fastmult*/ "32x32->64-bit multiplication") },
+ { "fpa", NC_("arm-flag", /*/flag:fpa*/ "Floating point accelerator") },
+ { "vfp", NC_("arm-flag", /*/flag:vfp*/ "VFP (early SIMD vector floating point instructions)") },
+ { "edsp", NC_("arm-flag", /*/flag:edsp*/ "DSP extensions (the 'e' variant of the ARM9 CPUs, and all others above)") },
+ { "java", NC_("arm-flag", /*/flag:java*/ "Jazelle (Java bytecode accelerator)") },
+ { "iwmmxt", NC_("arm-flag", /*/flag:iwmmxt*/ "SIMD instructions similar to Intel MMX") },
+ { "crunch", NC_("arm-flag", /*/flag:crunch*/ "MaverickCrunch coprocessor (if kernel support enabled)") },
+ { "thumbee", NC_("arm-flag", /*/flag:thumbee*/ "ThumbEE") },
+ { "neon", NC_("arm-flag", /*/flag:neon*/ "Advanced SIMD/NEON on AArch32") },
+ { "evtstrm", NC_("arm-flag", /*/flag:evtstrm*/ "Kernel event stream using generic architected timer") },
+ { "vfpv3", NC_("arm-flag", /*/flag:vfpv3*/ "VFP version 3") },
+ { "vfpv3d16", NC_("arm-flag", /*/flag:vfpv3d16*/ "VFP version 3 with 16 D-registers") },
+ { "vfpv4", NC_("arm-flag", /*/flag:vfpv4*/ "VFP version 4 with fast context switching") },
+ { "vfpd32", NC_("arm-flag", /*/flag:vfpd32*/ "VFP with 32 D-registers") },
+ { "tls", NC_("arm-flag", /*/flag:tls*/ "TLS register") },
+ { "idiva", NC_("arm-flag", /*/flag:idiva*/ "SDIV and UDIV hardware division in ARM mode") },
+ { "idivt", NC_("arm-flag", /*/flag:idivt*/ "SDIV and UDIV hardware division in Thumb mode") },
+ { "lpae", NC_("arm-flag", /*/flag:lpae*/ "40-bit Large Physical Address Extension") },
/* arm/hw_cap2 */
- { "pmull", "64x64->128-bit F2m multiplication (arch>8)" },
- { "aes", "Crypto:AES (arch>8)" },
- { "sha1", "Crypto:SHA1 (arch>8)" },
- { "sha2", "Crypto:SHA2 (arch>8)" },
- { "crc32", "CRC32 checksum instructions (arch>8)" },
+ { "pmull", NC_("arm-flag", /*/flag:pmull*/ "64x64->128-bit F2m multiplication (arch>8)") },
+ { "aes", NC_("arm-flag", /*/flag:aes*/ "Crypto:AES (arch>8)") },
+ { "sha1", NC_("arm-flag", /*/flag:sha1*/ "Crypto:SHA1 (arch>8)") },
+ { "sha2", NC_("arm-flag", /*/flag:sha2*/ "Crypto:SHA2 (arch>8)") },
+ { "crc32", NC_("arm-flag", /*/flag:crc32*/ "CRC32 checksum instructions (arch>8)") },
/* arm64/hw_cap */
- { "fp", "" },
- { "asimd", "Advanced SIMD/NEON on AArch64 (arch>8)" },
- { "atomics", "" },
- { "fphp", "" },
- { "asimdhp", "" },
- { "cpuid", "" },
- { "asimdrdm", "" },
- { "jscvt", "" },
- { "fcma", "" },
- { "lrcpc", "" },
-
- { NULL, NULL},
+ { "fp", NULL },
+ { "asimd", NC_("arm-flag", /*/flag:asimd*/ "Advanced SIMD/NEON on AArch64 (arch>8)") },
+ { "atomics", NULL },
+ { "fphp", NULL },
+ { "asimdhp", NULL },
+ { "cpuid", NULL },
+ { "asimdrdm", NULL },
+ { "jscvt", NULL },
+ { "fcma", NULL },
+ { "lrcpc", NULL },
+ { NULL, NULL }
};
static struct {
@@ -108,9 +114,11 @@ static struct {
/*d */ { 0xd01, "Cortex-A32" },
/*dt*/ { 0xd03, "Cortex-A53" },
/*d */ { 0xd04, "Cortex-A35" },
+ /*d */ { 0xd05, "Cortex-A55" },
/*d */ { 0xd07, "Cortex-A57 MPCore" },
/*d */ { 0xd08, "Cortex-A72" },
/*d */ { 0xd09, "Cortex-A73" },
+ /*d */ { 0xd0a, "Cortex-A75" },
{ 0, NULL},
};
@@ -143,8 +151,11 @@ const char *arm_flag_meaning(const char *flag) {
int i = 0;
if (flag)
while(tab_flag_meaning[i].name != NULL) {
- if (strcmp(tab_flag_meaning[i].name, flag) == 0)
- return tab_flag_meaning[i].meaning;
+ if (strcmp(tab_flag_meaning[i].name, flag) == 0) {
+ if (tab_flag_meaning[i].meaning != NULL)
+ return C_("arm-flag", tab_flag_meaning[i].meaning);
+ else return NULL;
+ }
i++;
}
return NULL;
@@ -220,7 +231,7 @@ char *arm_decoded_name(const char *imp, const char *part, const char *var, const
p = strtol(rev, NULL, 0);
imp_name = (char*) arm_implementer(imp);
part_desc = (char*) arm_part(imp, part);
- arch_name = (char *) arm_arch(arch);
+ arch_name = (char*) arm_arch(arch);
if (imp_name || part_desc) {
if (arch_name != arch)
sprintf(dnbuff, "%s %s r%dp%d (%s)",
diff --git a/modules/devices/arm/processor.c b/modules/devices/arm/processor.c
index ad7adf7f..e9446229 100644
--- a/modules/devices/arm/processor.c
+++ b/modules/devices/arm/processor.c
@@ -18,6 +18,8 @@
#include "hardinfo.h"
#include "devices.h"
+#include "cpu_util.h"
+#include "dt_util.h"
#include "arm_data.h"
#include "arm_data.c"
@@ -34,34 +36,6 @@ static const gchar *arm_mode_str[] = {
"A32 on A64",
};
-static gint get_cpu_int(const gchar* file, gint cpuid) {
- gchar *tmp0 = NULL;
- gchar *tmp1 = NULL;
- gint ret = 0;
-
- tmp0 = g_strdup_printf("/sys/devices/system/cpu/cpu%d/%s", cpuid, file);
- g_file_get_contents(tmp0, &tmp1, NULL, NULL);
- if (tmp1)
- ret = atol(tmp1);
- g_free(tmp0);
- g_free(tmp1);
- return ret;
-}
-
-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;
-}
-
-#define PROC_CPUINFO "/proc/cpuinfo"
-
GSList *
processor_scan(void)
{
@@ -70,7 +44,6 @@ processor_scan(void)
FILE *cpuinfo;
gchar buffer[128];
gchar *rep_pname = NULL;
- gchar *tmpfreq_str = NULL;
GSList *pi = NULL;
cpuinfo = fopen(PROC_CPUINFO, "r");
@@ -101,7 +74,7 @@ processor_scan(void)
processor->id = atol(tmp[1]);
if (rep_pname)
- processor->model_name = g_strdup(rep_pname);
+ processor->linux_name = g_strdup(rep_pname);
g_strfreev(tmp);
continue;
@@ -117,11 +90,11 @@ processor_scan(void)
processor->id = 0;
if (rep_pname)
- processor->model_name = g_strdup(rep_pname);
+ processor->linux_name = g_strdup(rep_pname);
}
if (processor) {
- get_str("model name", processor->model_name);
+ get_str("model name", processor->linux_name);
get_str("Features", processor->flags);
get_float("BogoMIPS", processor->bogomips);
@@ -166,29 +139,26 @@ processor_scan(void)
processor = (Processor *) pi->data;
/* strings can't be null or segfault later */
-#define STRIFNULL(f,cs) if (processor->f == NULL) processor->f = g_strdup(cs);
-#define UNKIFNULL(f) STRIFNULL(f, "(Unknown)")
-#define EMPIFNULL(f) STRIFNULL(f, "")
- STRIFNULL(model_name, "ARM Processor");
- EMPIFNULL(flags);
- UNKIFNULL(cpu_implementer);
- UNKIFNULL(cpu_architecture);
- UNKIFNULL(cpu_variant);
- UNKIFNULL(cpu_part);
- UNKIFNULL(cpu_revision);
-
- processor->decoded_name = arm_decoded_name(
+ STRIFNULL(processor->linux_name, _("ARM Processor") );
+ EMPIFNULL(processor->flags);
+ UNKIFNULL(processor->cpu_implementer);
+ UNKIFNULL(processor->cpu_architecture);
+ UNKIFNULL(processor->cpu_variant);
+ UNKIFNULL(processor->cpu_part);
+ UNKIFNULL(processor->cpu_revision);
+
+ processor->model_name = arm_decoded_name(
processor->cpu_implementer, processor->cpu_part,
processor->cpu_variant, processor->cpu_revision,
- processor->cpu_architecture, processor->model_name);
- UNKIFNULL(decoded_name);
-
- /* freq */
- processor->cpukhz_cur = get_cpu_int("cpufreq/scaling_cur_freq", processor->id);
- processor->cpukhz_min = get_cpu_int("cpufreq/scaling_min_freq", processor->id);
- processor->cpukhz_max = get_cpu_int("cpufreq/scaling_max_freq", processor->id);
- if (processor->cpukhz_max)
- processor->cpu_mhz = processor->cpukhz_max / 1000;
+ processor->cpu_architecture, processor->linux_name);
+ UNKIFNULL(processor->model_name);
+
+ /* topo & freq */
+ processor->cpufreq = cpufreq_new(processor->id);
+ processor->cputopo = cputopo_new(processor->id);
+
+ if (processor->cpufreq->cpukhz_max)
+ processor->cpu_mhz = processor->cpufreq->cpukhz_max / 1000;
else
processor->cpu_mhz = 0.0f;
@@ -236,78 +206,168 @@ gchar *processor_get_capabilities_from_flags(gchar * strflags)
gchar *
processor_get_detailed_info(Processor *processor)
{
- gchar *tmp_flags, *tmp_imp, *tmp_part, *tmp_arch, *ret;
+ gchar *tmp_flags, *tmp_imp, *tmp_part, *tmp_arch, *tmp_cpufreq, *tmp_topology, *ret;
tmp_flags = processor_get_capabilities_from_flags(processor->flags);
tmp_imp = (char*)arm_implementer(processor->cpu_implementer);
tmp_part = (char*)arm_part(processor->cpu_implementer, processor->cpu_part);
tmp_arch = (char*)arm_arch_more(processor->cpu_architecture);
- ret = g_strdup_printf("[Processor]\n"
- "Linux Name=%s\n"
- "Decoded Name=%s\n"
- "Mode=%s\n"
- "BogoMips=%.2f\n"
- "Endianesss="
-#if G_BYTE_ORDER == G_LITTLE_ENDIAN
- "Little Endian"
-#else
- "Big Endian"
-#endif
- "\n"
- "[Frequency Scaling]\n"
- "Minimum=%d kHz\n"
- "Maximum=%d kHz\n"
- "Current=%d kHz\n"
- "[ARM]\n"
- "Implementer=[%s] %s\n"
- "Part=[%s] %s\n"
- "Architecture=[%s] %s\n"
- "Variant=%s\n"
- "Revision=%s\n"
- "[Capabilities]\n"
+ tmp_topology = cputopo_section_str(processor->cputopo);
+ tmp_cpufreq = cpufreq_section_str(processor->cpufreq);
+
+ ret = g_strdup_printf("[%s]\n"
+ "%s=%s\n" /* linux name */
+ "%s=%s\n" /* decoded name */
+ "%s=%s\n" /* mode */
+ "%s=%.2f %s\n" /* frequency */
+ "%s=%.2f\n" /* bogomips */
+ "%s=%s\n" /* byte order */
+ "%s" /* topology */
+ "%s" /* frequency scaling */
+ "[%s]\n" /* ARM */
+ "%s=[%s] %s\n" /* implementer */
+ "%s=[%s] %s\n" /* part */
+ "%s=[%s] %s\n" /* architecture */
+ "%s=%s\n" /* variant */
+ "%s=%s\n" /* revision */
+ "[%s]\n" /* flags */
"%s"
- "%s",
- processor->model_name,
- processor->decoded_name,
- arm_mode_str[processor->mode],
- processor->bogomips,
- processor->cpukhz_min,
- processor->cpukhz_max,
- processor->cpukhz_cur,
- processor->cpu_implementer, (tmp_imp) ? tmp_imp : "",
- processor->cpu_part, (tmp_part) ? tmp_part : "",
- processor->cpu_architecture, (tmp_arch) ? tmp_arch : "",
- processor->cpu_variant,
- processor->cpu_revision,
- tmp_flags,
+ "%s", /* empty */
+ _("Processor"),
+ _("Linux Name"), processor->linux_name,
+ _("Decoded Name"), processor->model_name,
+ _("Mode"), arm_mode_str[processor->mode],
+ _("Frequency"), processor->cpu_mhz, _("MHz"),
+ _("BogoMips"), processor->bogomips,
+ _("Byte Order"), byte_order_str(),
+ tmp_topology,
+ tmp_cpufreq,
+ _("ARM"),
+ _("Implementer"), processor->cpu_implementer, (tmp_imp) ? tmp_imp : "",
+ _("Part"), processor->cpu_part, (tmp_part) ? tmp_part : "",
+ _("Architecture"), processor->cpu_architecture, (tmp_arch) ? tmp_arch : "",
+ _("Variant"), processor->cpu_variant,
+ _("Revision"), processor->cpu_revision,
+ _("Capabilities"), tmp_flags,
"");
g_free(tmp_flags);
+ g_free(tmp_cpufreq);
+ g_free(tmp_topology);
+ return ret;
+}
+gchar *processor_name(GSList *processors) {
+ /* 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.
+ */
+#define UNKSOC "(Unknown)"
+ const struct {
+ char *search_str;
+ char *vendor;
+ char *soc;
+ } dt_compat_searches[] = {
+ { "brcm,bcm2837", "Broadcom", "BCM2837" },
+ { "brcm,bcm2836", "Broadcom", "BCM2836" },
+ { "brcm,bcm2835", "Broadcom", "BCM2835" },
+ { "ti,omap5432", "Texas Instruments", "OMAP5432" },
+ { "ti,omap5430", "Texas Instruments", "OMAP5430" },
+ { "ti,omap4470", "Texas Instruments", "OMAP4470" },
+ { "ti,omap4460", "Texas Instruments", "OMAP4460" },
+ { "ti,omap4430", "Texas Instruments", "OMAP4430" },
+ { "ti,omap3620", "Texas Instruments", "OMAP3620" },
+ { "ti,omap3450", "Texas Instruments", "OMAP3450" },
+ { "ti,omap5", "Texas Instruments", "OMAP5-family" },
+ { "ti,omap4", "Texas Instruments", "OMAP4-family" },
+ { "ti,omap3", "Texas Instruments", "OMAP3-family" },
+ { "ti,omap2", "Texas Instruments", "OMAP2-family" },
+ { "ti,omap1", "Texas Instruments", "OMAP1-family" },
+ { "qcom,msm8939", "Qualcomm", "Snapdragon 615"},
+ { "qcom,msm", "Qualcomm", "Snapdragon-family"},
+ { "nvidia,tegra" "nVidia", "Tegra-family" },
+ { "bcm,", "Broadcom", UNKSOC },
+ { "nvidia," "nVidia", UNKSOC },
+ { "rockchip," "Rockchip", UNKSOC },
+ { "ti,", "Texas Instruments", UNKSOC },
+ { "qcom,", "Qualcom", UNKSOC },
+ { NULL, NULL }
+ };
+ gchar *ret = NULL;
+ gchar *compat = NULL;
+ int i;
+
+ compat = dtr_get_string("/compatible", 1);
+
+ if (compat != NULL) {
+ i = 0;
+ while(dt_compat_searches[i].search_str != NULL) {
+ if (strstr(compat, dt_compat_searches[i].search_str) != NULL) {
+ ret = g_strdup_printf("%s %s", dt_compat_searches[i].vendor, dt_compat_searches[i].soc);
+ break;
+ }
+ i++;
+ }
+ }
+ g_free(compat);
+ UNKIFNULL(ret);
+ return ret;
+}
+
+gchar *processor_describe(GSList * processors) {
+ return processor_describe_by_counting_names(processors);
+}
+
+gchar *processor_meta(GSList * processors) {
+ gchar *meta_soc = processor_name(processors);
+ gchar *meta_cpu_desc = processor_describe(processors);
+ gchar *meta_cpu_topo = processor_describe_default(processors);
+ gchar *meta_clocks = processor_frequency_desc(processors);
+ gchar *ret = NULL;
+ UNKIFNULL(meta_cpu_desc);
+ ret = g_strdup_printf("[%s]\n"
+ "%s=%s\n"
+ "%s=%s\n"
+ "%s=%s\n"
+ "%s=%s\n",
+ _("SOC/Package"),
+ _("Name"), meta_soc,
+ _("Description"), meta_cpu_desc,
+ _("Topology"), meta_cpu_topo,
+ _("Clocks"), meta_clocks );
+ g_free(meta_soc);
+ g_free(meta_cpu_desc);
+ g_free(meta_cpu_topo);
+ g_free(meta_clocks);
return ret;
}
gchar *processor_get_info(GSList * processors)
{
Processor *processor;
-
- if (g_slist_length(processors) > 1) {
gchar *ret, *tmp, *hashkey;
+ gchar *meta; /* becomes owned by more_info? no need to free? */
GSList *l;
- tmp = g_strdup("");
+ tmp = g_strdup_printf("$CPU_META$%s=\n", _("SOC/Package Information") );
+
+ meta = processor_meta(processors);
+ moreinfo_add_with_prefix("DEV", "CPU_META", meta);
for (l = processors; l; l = l->next) {
processor = (Processor *) l->data;
- tmp = g_strdup_printf(_("%s$CPU%d$%s=%.2fMHz\n"),
+ tmp = g_strdup_printf("%s$CPU%d$%s=%.2f %s\n",
tmp, processor->id,
processor->model_name,
- processor->cpu_mhz);
+ processor->cpu_mhz, _("MHz"));
hashkey = g_strdup_printf("CPU%d", processor->id);
moreinfo_add_with_prefix("DEV", hashkey,
processor_get_detailed_info(processor));
- g_free(hashkey);
+ g_free(hashkey);
}
ret = g_strdup_printf("[$ShellParam$]\n"
@@ -317,8 +377,4 @@ gchar *processor_get_info(GSList * processors)
g_free(tmp);
return ret;
- }
-
- processor = (Processor *) processors->data;
- return processor_get_detailed_info(processor);
}
diff --git a/modules/devices/cpu_util.c b/modules/devices/cpu_util.c
new file mode 100644
index 00000000..f5bddd5c
--- /dev/null
+++ b/modules/devices/cpu_util.c
@@ -0,0 +1,225 @@
+/*
+ * HardInfo - Displays System Information
+ * Copyright (C) 2003-2006 Leandro A. F. Pereira <leandro@hardinfo.org>
+ * 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.c"
+
+#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(int *p, int *c, int *t) {
+ 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) {
+ 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) { 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);
+ if (!*c) *c = 1;
+ if (!*p) *p = 1;
+ free(threads);
+ free(cores);
+ free(packs);
+ free(tmp);
+ return 1;
+ } else {
+ *p = *c = *t = -1;
+ return 0;
+ }
+}
+
+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)");
+ }
+}
+
+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/modules/devices/cpubits.c b/modules/devices/cpubits.c
new file mode 100644
index 00000000..ba9bffc7
--- /dev/null
+++ b/modules/devices/cpubits.c
@@ -0,0 +1,113 @@
+/*
+ * rpiz - https://github.com/bp0/rpiz
+ * 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; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * 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 Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include <stdint.h>
+
+typedef uint32_t cpubits;
+uint32_t cpubits_count(cpubits *b);
+cpubits *cpubits_from_str(char *str);
+char *cpubits_to_str(cpubits *bits, char *str, int max_len);
+
+#define CPUBITS_SIZE 4096 /* bytes, multiple of sizeof(uint32_t) */
+#define CPUBIT_SET(BITS, BIT) (BITS[BIT/32] |= (1 << BIT%32))
+#define CPUBIT_GET(BITS, BIT) ((BITS[BIT/32] & (1 << BIT%32)) >> BIT%32)
+#define CPUBITS_CLEAR(BITS) memset(BITS, 0, CPUBITS_SIZE)
+
+uint32_t cpubits_count(cpubits *b) {
+ static const uint32_t max = CPUBITS_SIZE * 8;
+ uint32_t count = 0, i = 0;
+ while (i < max) {
+ count += CPUBIT_GET(b, i);
+ i++;
+ }
+ return count;
+}
+
+int cpubits_max(cpubits *b) {
+ int i = CPUBITS_SIZE * 8;
+ while (i >= 0) {
+ if (CPUBIT_GET(b, i))
+ break;
+ i--;
+ }
+ return i;
+}
+
+cpubits *cpubits_from_str(char *str) {
+ char *v, *nv, *hy;
+ int r0, r1;
+ cpubits *newbits = malloc(CPUBITS_SIZE);
+ if (newbits) {
+ memset(newbits, 0, CPUBITS_SIZE);
+ if (str != NULL) {
+ v = (char*)str;
+ while ( *v != 0 ) {
+ nv = strchr(v, ','); /* strchrnul() */
+ if (nv == NULL) nv = strchr(v, 0); /* equivalent */
+ hy = strchr(v, '-');
+ if (hy && hy < nv) {
+ r0 = strtol(v, NULL, 0);
+ r1 = strtol(hy + 1, NULL, 0);
+ } else {
+ r0 = r1 = strtol(v, NULL, 0);
+ }
+ for (; r0 <= r1; r0++) {
+ CPUBIT_SET(newbits, r0);
+ }
+ v = (*nv == ',') ? nv + 1 : nv;
+ }
+ }
+ }
+ return newbits;
+}
+
+char *cpubits_to_str(cpubits *bits, char *str, int max_len) {
+ static const uint32_t max = CPUBITS_SIZE * 8;
+ uint32_t i = 1, seq_start = 0, seq_last = 0, seq = 0, l = 0;
+ char buffer[65536] = "";
+ if (CPUBIT_GET(bits, 0)) {
+ seq = 1;
+ strcpy(buffer, "0");
+ }
+ while (i < max) {
+ if (CPUBIT_GET(bits, i) ) {
+ seq_last = i;
+ if (!seq) {
+ seq = 1;
+ seq_start = i;
+ l = strlen(buffer);
+ sprintf(buffer + l, "%s%d", l ? "," : "", i);
+ }
+ } else {
+ if (seq && seq_last != seq_start) {
+ l = strlen(buffer);
+ sprintf(buffer + l, "-%d", seq_last);
+ }
+ seq = 0;
+ }
+ i++;
+ }
+ if (str == NULL)
+ return strdup(buffer);
+ else {
+ strncpy(str, buffer, max_len);
+ return str;
+ }
+}
diff --git a/modules/devices/devicetree.c b/modules/devices/devicetree.c
new file mode 100644
index 00000000..6fce066a
--- /dev/null
+++ b/modules/devices/devicetree.c
@@ -0,0 +1,272 @@
+/*
+ * HardInfo - Displays System Information
+ * Copyright (C) 2003-2007 Leandro A. F. Pereira <leandro@hardinfo.org>
+ *
+ * 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 <stdint.h>
+#include "hardinfo.h"
+#include "devices.h"
+#include "cpu_util.h"
+#include "dt_util.h"
+
+#include "devicetree/rpi_data.c"
+#include "devicetree/pmac_data.c"
+
+dtr *dt;
+gchar *dtree_info = NULL;
+
+gchar *get_node(char *np) {
+ gchar *nodes = NULL, *props = NULL, *ret = NULL;
+ gchar *tmp = NULL, *pstr = NULL, *lstr = NULL;
+ gchar *dir_path;
+ gchar *node_path;
+ const gchar *fn;
+ GDir *dir;
+ dtr_obj *node, *child;
+
+ props = g_strdup_printf("[%s]\n", _("Properties") );
+ nodes = g_strdup_printf("[%s]\n", _("Children") );
+ node = dtr_obj_read(dt, np);
+ dir_path = dtr_obj_full_path(node);
+
+ dir = g_dir_open(dir_path, 0 , NULL);
+ if (dir) {
+ while((fn = g_dir_read_name(dir)) != NULL) {
+ child = dtr_get_prop_obj(dt, node, fn);
+ pstr = hardinfo_clean_value(dtr_str(child), 1);
+ lstr = hardinfo_clean_label(fn, 0);
+ if (dtr_obj_type(child) == DT_NODE) {
+ tmp = g_strdup_printf("%s%s=%s\n",
+ nodes, lstr, pstr);
+ g_free(nodes);
+ nodes = tmp;
+ } else {
+ tmp = g_strdup_printf("%s%s=%s\n",
+ props, lstr, pstr);
+ g_free(props);
+ props = tmp;
+ }
+ dtr_obj_free(child);
+ g_free(pstr);
+ g_free(lstr);
+ }
+ }
+ g_dir_close(dir);
+ g_free(dir_path);
+
+ lstr = dtr_obj_alias(node);
+ pstr = dtr_obj_symbol(node);
+ ret = g_strdup_printf("[%s]\n"
+ "%s=%s\n"
+ "%s=%s\n"
+ "%s=%s\n"
+ "%s%s",
+ _("Node"),
+ _("Node Path"), dtr_obj_path(node),
+ _("Alias"), (lstr != NULL) ? lstr : _("(None)"),
+ _("Symbol"), (pstr != NULL) ? pstr : _("(None)"),
+ props, nodes);
+
+ dtr_obj_free(node);
+ g_free(props);
+ g_free(nodes);
+ return ret;
+}
+
+/* different from dtr_get_string() in that it re-uses the existing dt */
+char *get_dt_string(char *path, int decode) {
+ dtr_obj *obj;
+ char *ret = NULL;
+ if (decode) {
+ obj = dtr_get_prop_obj(dt, NULL, path);
+ ret = dtr_str(obj);
+ dtr_obj_free(obj);
+ } else
+ ret = dtr_get_prop_str(dt, NULL, path);
+ return ret;
+}
+
+gchar *get_summary() {
+ char *model = NULL, *compat = NULL;
+ char *tmp[10];
+ char *ret = NULL;
+
+ model = get_dt_string("/model", 0);
+ compat = get_dt_string("/compatible", 1);
+ UNKIFNULL(model);
+ EMPIFNULL(compat);
+
+ /* Expand on the DT information from known machines, like RPi.
+ * RPi stores a revision value in /proc/cpuinfo that can be used
+ * to look up details. This is just a nice place to pull it all
+ * together for DT machines, with a nice fallback.
+ * PPC Macs could be handled this way too. They store
+ * machine identifiers in /proc/cpuinfo. */
+ if ( strstr(model, "Raspberry Pi") != NULL
+ || strstr(compat, "raspberrypi") != NULL ) {
+ tmp[0] = get_dt_string("/serial-number", 1);
+ tmp[1] = get_dt_string("/soc/gpu/compatible", 1);
+ tmp[9] = rpi_board_details();
+ tmp[8] = g_strdup_printf(
+ "[%s]\n" "%s=%s\n" "%s=%s\n",
+ _("Platform"),
+ _("Compatible"), compat,
+ _("GPU-compatible"), tmp[1] );
+ if (tmp[9] != NULL) {
+ ret = g_strdup_printf("%s%s", tmp[9], tmp[8]);
+ } else {
+ ret = g_strdup_printf(
+ "[%s]\n" "%s=%s\n" "%s=%s\n" "%s=%s\n" "%s",
+ _("Raspberry Pi or Compatible"),
+ _("Model"), model,
+ _("Serial Number"), tmp[0],
+ _("RCode"), _("No revision code available; unable to lookup model details."),
+ tmp[8]);
+ }
+ free(tmp[0]); free(tmp[1]);
+ free(tmp[9]); free(tmp[8]);
+ }
+
+ /* Power Macintosh */
+ if (strstr(compat, "PowerBook") != NULL
+ || strstr(compat, "MacRISC") != NULL
+ || strstr(compat, "Power Macintosh") != NULL) {
+ tmp[9] = ppc_mac_details();
+ if (tmp[9] != NULL) {
+ tmp[0] = get_dt_string("/serial-number", 1);
+ ret = g_strdup_printf(
+ "%s[%s]\n" "%s=%s\n", tmp[9],
+ _("More"),
+ _("Serial Number"), tmp[0] );
+ free(tmp[0]);
+ }
+ free(tmp[9]);
+ }
+
+ /* fallback */
+ if (ret == NULL) {
+ tmp[0] = get_dt_string("/serial-number", 1);
+ EMPIFNULL(tmp[0]);
+ ret = g_strdup_printf(
+ "[%s]\n"
+ "%s=%s\n"
+ "%s=%s\n"
+ "%s=%s\n",
+ _("Board"),
+ _("Model"), model,
+ _("Serial Number"), tmp[0],
+ _("Compatible"), compat);
+ free(tmp[0]);
+ }
+ free(model);
+ return ret;
+}
+
+void mi_add(const char *key, const char *value) {
+ gchar *ckey, *rkey;
+
+ ckey = hardinfo_clean_label(key, 0);
+ rkey = g_strdup_printf("%s:%s", "DTREE", ckey);
+
+ dtree_info = h_strdup_cprintf("$%s$%s=\n", dtree_info, rkey, ckey);
+ moreinfo_add_with_prefix("DEV", rkey, g_strdup(value));
+
+ g_free(ckey);
+ g_free(rkey);
+}
+
+void add_keys(char *np) {
+ gchar *dir_path, *dt_path;
+ gchar *ftmp, *ntmp;
+ gchar *n_info;
+ const gchar *fn;
+ GDir *dir;
+ dtr_obj *obj;
+
+ /* add self */
+ obj = dtr_obj_read(dt, np);
+ dt_path = dtr_obj_path(obj);
+ n_info = get_node(dt_path);
+ mi_add(dt_path, n_info);
+
+ 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);
+ add_keys(ntmp);
+ g_free(ntmp);
+ }
+ g_free(ftmp);
+ }
+ }
+ g_dir_close(dir);
+}
+
+char *msg_section(int dump) {
+ gchar *aslbl = NULL;
+ gchar *messages = dtr_messages(dt);
+ gchar *ret = g_strdup_printf("[%s]\n", _("Messages"));
+ gchar **lines = g_strsplit(messages, "\n", 0);
+ int i = 0;
+ while(lines[i] != NULL) {
+ aslbl = hardinfo_clean_label(lines[i], 0);
+ ret = appf(ret, "%s=\n", aslbl);
+ g_free(aslbl);
+ i++;
+ }
+ g_strfreev(lines);
+ if (dump)
+ printf("%s", messages);
+ g_free(messages);
+ return ret;
+}
+
+void __scan_dtree()
+{
+ dt = dtr_new(NULL);
+ gchar *summary = get_summary();
+ gchar *maps = dtr_maps_info(dt);
+ gchar *messages = NULL;
+
+ dtree_info = g_strdup("[Device Tree]\n");
+ mi_add("Summary", summary);
+ mi_add("Maps", maps);
+
+ if(dtr_was_found(dt))
+ add_keys("/");
+ messages = msg_section(0);
+ mi_add("Messages", messages);
+
+ //printf("%s\n", dtree_info);
+
+ g_free(summary);
+ g_free(maps);
+ g_free(messages);
+ dtr_free(dt);
+}
diff --git a/modules/devices/devicetree/dt_util.c b/modules/devices/devicetree/dt_util.c
new file mode 100644
index 00000000..9678042d
--- /dev/null
+++ b/modules/devices/devicetree/dt_util.c
@@ -0,0 +1,1040 @@
+/*
+ * HardInfo - Displays System Information
+ * Copyright (C) 2003-2007 Leandro A. F. Pereira <leandro@hardinfo.org>
+ *
+ * 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 <endian.h>
+#include "hardinfo.h"
+#include "dt_util.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 },
+ { 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;
+ };
+ 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, *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);
+
+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 && prop->data != NULL) {
+ ret = be32toh(*prop->data_int);
+ dtr_obj_free(prop);
+ }
+ g_free(ptmp);
+ return ret;
+}
+
+int dtr_guess_type(dtr_obj *obj) {
+ char *tmp, *dash;
+ int 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 *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)", al_label, ph_path);
+ else
+ ret = g_strdup_printf("&%s", al_label);
+ } else {
+ if (show_path)
+ ret = g_strdup_printf("0x%x (%s)", be32toh(e), ph_path);
+ }
+ }
+ if (ret == NULL)
+ ret = dtr_elem_hex(e);
+ return ret;
+}
+
+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_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];
+ sprintf(buff, "%s%02x", (i) ? " " : "", v);
+ l = strlen(buff);
+ 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++) {
+ sprintf(buff, "%s0x%x", (i) ? " " : "", be32toh(list[i]));
+ l = strlen(buff);
+ 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;
+ int l, consumed = 0;
+ src = obj->data_str;
+ while (consumed + 5 <= obj->length) {
+ ph = dtr_elem_phref(obj->dt, *(dt_uint*)src, 1);
+ src += 4; consumed += 4;
+ l = strlen(src) + 1; /* consume the null */
+ str = dtr_list_str0(src, l);
+ ret = appf(ret, "<%s -> %s>", ph, str);
+ src += l; consumed += l;
+ free(ph);
+ free(str);
+ }
+ if (consumed < obj->length) {
+ str = dtr_list_byte(src, obj->length - consumed);
+ ret = appf(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_path;
+ 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); i++;
+ if (ext_cells > count - i) ext_cells = count - i;
+ ext = dtr_list_hex((obj->data_int + i), ext_cells); i+=ext_cells;
+ ret = appf(ret, "<%s%s%s>",
+ 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 = MIN(icells, count - i);
+ ext = dtr_list_hex((obj->data_int + i), icells); i+=icells;
+ ret = appf(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 tups, extra, consumed; /* extra and consumed are bytes */
+ uint32_t *next;
+
+ acells = dtr_inh_find(obj, "#address-cells", 2);
+ scells = dtr_inh_find(obj, "#size-cells", 2);
+ tup_len = acells + scells;
+ tups = obj->length / (tup_len * 4);
+ 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 = appf(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);
+ break;
+ case DTP_UINT:
+ ret = dtr_elem_uint(*obj->data_int);
+ break;
+ case DTP_UNK:
+ default:
+ if (obj->length > 64) /* maybe should use #define at the top */
+ ret = g_strdup_printf(ret, "{data} (%lu bytes)", 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, *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;
+}
+
+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;
+ uint32_t phandle;
+
+ 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;
+}
+
+char *appf(char *src, char *fmt, ...) {
+ gchar *buf, *ret;
+ va_list args;
+
+ va_start(args, fmt);
+ buf = g_strdup_vprintf(fmt, args);
+ va_end(args);
+
+ if (src != NULL) {
+ ret = g_strdup_printf("%s%s%s", src, sp_sep(src), buf);
+ g_free(buf);
+ g_free(src);
+ } else
+ ret = buf;
+
+ return ret;
+}
+
diff --git a/modules/devices/devicetree/pmac_data.c b/modules/devices/devicetree/pmac_data.c
new file mode 100644
index 00000000..b236aef1
--- /dev/null
+++ b/modules/devices/devicetree/pmac_data.c
@@ -0,0 +1,98 @@
+/*
+ * HardInfo - Displays System Information
+ * Copyright (C) 2003-2007 Leandro A. F. Pereira <leandro@hardinfo.org>
+ *
+ * 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 "cpu_util.h" /* for PROC_CPUINFO */
+
+static gchar *ppc_mac_details(void) {
+ int i = 0;
+ gchar *ret = NULL;
+ gchar *platform = NULL;
+ gchar *model = NULL;
+ gchar *machine = NULL;
+ gchar *motherboard = NULL;
+ gchar *detected_as = NULL;
+ gchar *pmac_flags = NULL;
+ gchar *l2_cache = NULL;
+ gchar *pmac_gen = NULL;
+
+ FILE *cpuinfo;
+ gchar buffer[128];
+
+ cpuinfo = fopen(PROC_CPUINFO, "r");
+ if (!cpuinfo)
+ return NULL;
+ while (fgets(buffer, 128, cpuinfo)) {
+ gchar **tmp = g_strsplit(buffer, ":", 2);
+ if (tmp[1] == NULL) {
+ g_strfreev(tmp);
+ continue;
+ }
+ tmp[0] = g_strstrip(tmp[0]);
+ tmp[1] = g_strstrip(tmp[1]);
+ get_str("platform", platform);
+ get_str("model", model);
+ get_str("machine", machine);
+ get_str("motherboard", motherboard);
+ get_str("detected as", detected_as);
+ get_str("pmac flags", pmac_flags);
+ get_str("L2 cache", l2_cache);
+ get_str("pmac-generation", pmac_gen);
+ }
+ fclose(cpuinfo);
+
+ if (machine == NULL)
+ goto pmd_exit;
+
+ UNKIFNULL(platform);
+ UNKIFNULL(model);
+ UNKIFNULL(motherboard);
+ UNKIFNULL(detected_as);
+ UNKIFNULL(pmac_flags);
+ UNKIFNULL(l2_cache);
+ UNKIFNULL(pmac_gen);
+
+ ret = g_strdup_printf("[%s]\n"
+ "%s=%s\n"
+ "%s=%s\n"
+ "%s=%s\n"
+ "%s=%s\n"
+ "%s=%s\n"
+ "%s=%s\n"
+ "%s=%s\n"
+ "%s=%s\n",
+ _("Apple Power Macintosh"),
+ _("Platform"), platform,
+ _("Model"), model,
+ _("Machine"), machine,
+ _("Motherboard"), motherboard,
+ _("Detected as"), detected_as,
+ _("PMAC Flags"), pmac_flags,
+ _("L2 Cache"), l2_cache,
+ _("PMAC Generation"), pmac_gen );
+
+pmd_exit:
+ g_free(platform);
+ g_free(model);
+ g_free(machine);
+ g_free(motherboard);
+ g_free(detected_as);
+ g_free(pmac_flags);
+ g_free(l2_cache);
+ g_free(pmac_gen);
+ return ret;
+}
diff --git a/modules/devices/devicetree/rpi_data.c b/modules/devices/devicetree/rpi_data.c
new file mode 100644
index 00000000..d0132e3a
--- /dev/null
+++ b/modules/devices/devicetree/rpi_data.c
@@ -0,0 +1,166 @@
+/*
+ * HardInfo - Displays System Information
+ * Copyright (C) 2003-2007 Leandro A. F. Pereira <leandro@hardinfo.org>
+ * This file from: rpiz - https://github.com/bp0/rpiz
+ * 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
+ */
+
+static char unk[] = "(Unknown)";
+
+/* information table from: http://elinux.org/RPi_HardwareHistory */
+static struct {
+ char *value, *intro, *model, *pcb, *mem, *mfg, *soc;
+} rpi_boardinfo[] = {
+/* Value Introduction Model Name PCB rev. Memory(spec) Manufacturer SOC(spec) *
+ * Raspberry Pi %s */
+ { unk, unk, unk, unk, unk, unk, NULL },
+ { "Beta", "Q1 2012", "B (Beta)", unk, "256MB", "(Beta board)", NULL },
+ { "0002", "Q1 2012", "B", "1.0", "256MB", unk, "BCM2835" },
+ { "0003", "Q3 2012", "B (ECN0001)", "1.0", "256MB", "(Fuses mod and D14 removed)", NULL },
+ { "0004", "Q3 2012", "B", "2.0", "256MB", "Sony", NULL },
+ { "0005", "Q4 2012", "B", "2.0", "256MB", "Qisda", NULL },
+ { "0006", "Q4 2012", "B", "2.0", "256MB", "Egoman", NULL },
+ { "0007", "Q1 2013", "A", "2.0", "256MB", "Egoman", NULL },
+ { "0008", "Q1 2013", "A", "2.0", "256MB", "Sony", NULL },
+ { "0009", "Q1 2013", "A", "2.0", "256MB", "Qisda", NULL },
+ { "000d", "Q4 2012", "B", "2.0", "512MB", "Egoman", NULL },
+ { "000e", "Q4 2012", "B", "2.0", "512MB", "Sony", NULL },
+ { "000f", "Q4 2012", "B", "2.0", "512MB", "Qisda", NULL },
+ { "0010", "Q3 2014", "B+", "1.0", "512MB", "Sony", NULL },
+ { "0011", "Q2 2014", "Compute Module 1", "1.0", "512MB", "Sony", NULL },
+ { "0012", "Q4 2014", "A+", "1.1", "256MB", "Sony", NULL },
+ { "0013", "Q1 2015", "B+", "1.2", "512MB", unk, NULL },
+ { "0014", "Q2 2014", "Compute Module 1", "1.0", "512MB", "Embest", NULL },
+ { "0015", unk, "A+", "1.1", "256MB/512MB", "Embest", NULL },
+ { "a01040", unk, "2 Model B", "1.0", "1GB", "Sony", "BCM2836" },
+ { "a01041", "Q1 2015", "2 Model B", "1.1", "1GB", "Sony", "BCM2836" },
+ { "a21041", "Q1 2015", "2 Model B", "1.1", "1GB", "Embest", "BCM2836" },
+ { "a22042", "Q3 2016", "2 Model B", "1.2", "1GB", "Embest", "BCM2837" }, /* (with BCM2837) */
+ { "900021", "Q3 2016", "A+", "1.1", "512MB", "Sony", NULL },
+ { "900032", "Q2 2016?", "B+", "1.2", "512MB", "Sony", NULL },
+ { "900092", "Q4 2015", "Zero", "1.2", "512MB", "Sony", NULL },
+ { "900093", "Q2 2016", "Zero", "1.3", "512MB", "Sony", NULL },
+ { "920093", "Q4 2016?", "Zero", "1.3", "512MB", "Embest", NULL },
+ { "9000c1", "Q1 2017", "Zero W", "1.1", "512MB", "Sony", NULL },
+ { "a02082", "Q1 2016", "3 Model B", "1.2", "1GB", "Sony", "BCM2837" },
+ { "a020a0", "Q1 2017", "Compute Module 3 or CM3 Lite", "1.0", "1GB", "Sony", NULL },
+ { "a22082", "Q1 2016", "3 Model B", "1.2", "1GB", "Embest", "BCM2837" },
+ { "a32082", "Q4 2016", "3 Model B", "1.2", "1GB", "Sony Japan", NULL },
+ { NULL, NULL, NULL, NULL, NULL, NULL, NULL }
+};
+
+
+/* return number of chars to skip */
+static int rpi_ov_check(const char *r_code) {
+ /* sources differ. prefix is either 1000... or just 1... */
+ //if (strncmp(r, "1000", 4) == 0)
+ // return 4;
+ if (strncmp(r_code, "1", 1) == 0)
+ return 1;
+ return 0;
+}
+
+static int rpi_code_match(const char* code0, const char* code1) {
+ int c0, c1;
+ if (code0 == NULL || code1 == NULL) return 0;
+ c0 = strtol(code0, NULL, 16);
+ c1 = strtol(code1, NULL, 16);
+ if (c0 && c1)
+ return (c0 == c1) ? 1 : 0;
+ else
+ return (strcmp(code0, code1) == 0) ? 1 : 0;
+}
+
+static int rpi_find_board(const char *r_code) {
+ int i = 0;
+ char *r = (char*)r_code;
+ if (r_code == NULL)
+ return 0;
+ /* ignore the overvolt prefix */
+ r += rpi_ov_check(r_code);
+ while (rpi_boardinfo[i].value != NULL) {
+ if (rpi_code_match(r, rpi_boardinfo[i].value))
+ return i;
+
+ i++;
+ }
+ return 0;
+}
+
+/* ------------------------- */
+
+#include "cpu_util.h" /* for PROC_CPUINFO */
+
+static gchar *rpi_board_details(void) {
+ int i = 0;
+ gchar *ret = NULL;
+ gchar *soc = NULL;
+ gchar *serial = NULL;
+ gchar *revision = NULL;
+ int ov = 0;
+ FILE *cpuinfo;
+ gchar buffer[128];
+
+ cpuinfo = fopen(PROC_CPUINFO, "r");
+ if (!cpuinfo)
+ return NULL;
+ while (fgets(buffer, 128, cpuinfo)) {
+ gchar **tmp = g_strsplit(buffer, ":", 2);
+ if (tmp[1] == NULL) {
+ g_strfreev(tmp);
+ continue;
+ }
+ tmp[0] = g_strstrip(tmp[0]);
+ tmp[1] = g_strstrip(tmp[1]);
+ get_str("Revision", revision);
+ get_str("Hardware", soc);
+ get_str("Serial", serial);
+ }
+ fclose(cpuinfo);
+
+ if (revision == NULL || soc == NULL) {
+ g_free(soc);
+ g_free(revision);
+ return NULL;
+ }
+
+ ov = rpi_ov_check(revision);
+ i = rpi_find_board(revision);
+ ret = g_strdup_printf("[%s]\n"
+ "%s=%s %s\n"
+ "%s=%s\n"
+ "%s=%s\n"
+ "%s=%s\n"
+ "%s=%s\n"
+ "%s=%s\n"
+ "%s=%s\n"
+ "%s=%s\n"
+ "%s=%s\n",
+ _("Raspberry Pi"),
+ _("Board Name"), _("Raspberry Pi"), rpi_boardinfo[i].model,
+ _("PCB Revision"), rpi_boardinfo[i].pcb,
+ _("Introduction"), rpi_boardinfo[i].intro,
+ _("Manufacturer"), rpi_boardinfo[i].mfg,
+ _("RCode"), rpi_boardinfo[i].value,
+ _("SOC (spec)"), rpi_boardinfo[i].soc,
+ _("Memory (spec)"), rpi_boardinfo[i].mem,
+ _("Serial Number"), serial,
+ _("Permanent overvolt bit"), (ov) ? C_("rpi-ov-bit", "Set") : C_("rpi-ov-bit", "Not set") );
+
+ g_free(soc);
+ g_free(revision);
+ return ret;
+}
diff --git a/modules/devices/devmemory.c b/modules/devices/devmemory.c
index 7131536c..080e2bbe 100644
--- a/modules/devices/devmemory.c
+++ b/modules/devices/devmemory.c
@@ -23,10 +23,10 @@ GHashTable *memlabels = NULL;
void scan_memory_do(void)
{
- gchar **keys, *tmp;
+ gchar **keys, *tmp, *tmp_label;
static gint offset = -1;
gint i;
-
+
if (offset == -1) {
/* gah. linux 2.4 adds three lines of data we don't need in
/proc/meminfo */
@@ -38,38 +38,42 @@ void scan_memory_do(void)
offset = 0;
}
}
-
+
g_file_get_contents("/proc/meminfo", &meminfo, NULL, NULL);
-
+
keys = g_strsplit(meminfo, "\n", 0);
g_free(meminfo);
g_free(lginterval);
-
+
meminfo = g_strdup("");
lginterval = g_strdup("");
-
+
for (i = offset; keys[i]; i++) {
gchar **newkeys = g_strsplit(keys[i], ":", 0);
-
+
if (!newkeys[0]) {
g_strfreev(newkeys);
break;
}
-
+
+ g_strstrip(newkeys[0]);
g_strstrip(newkeys[1]);
-
- if ((tmp = g_hash_table_lookup(memlabels, newkeys[0]))) {
- g_free(newkeys[0]);
- newkeys[0] = g_strdup(tmp);
- }
-
+
+ /* try to find a localizable label */
+ tmp = g_hash_table_lookup(memlabels, newkeys[0]);
+ if (tmp)
+ tmp_label = _(tmp);
+ else
+ tmp_label = ""; /* or newkeys[0] */
+ /* although it doesn't matter... */
+
moreinfo_add_with_prefix("DEV", newkeys[0], g_strdup(newkeys[1]));
- tmp = g_strconcat(meminfo, newkeys[0], "=", newkeys[1], "\n", NULL);
+ tmp = g_strconcat(meminfo, newkeys[0], "=", newkeys[1], "|", tmp_label, "\n", NULL);
g_free(meminfo);
meminfo = tmp;
-
+
tmp = g_strconcat(lginterval,
"UpdateInterval$", newkeys[0], "=1000\n", NULL);
g_free(lginterval);
@@ -86,21 +90,21 @@ void init_memory_labels(void)
char *proc_label;
char *real_label;
} proc2real[] = {
- { "MemTotal", N_("Total Memory") },
- { "MemFree", N_("Free Memory") },
- { "SwapCached", N_("Cached Swap") },
- { "HighTotal", N_("High Memory") },
- { "HighFree", N_("Free High Memory") },
- { "LowTotal", N_("Low Memory") },
- { "LowFree", N_("Free Low Memory") },
- { "SwapTotal", N_("Virtual Memory") },
- { "SwapFree", N_("Free Virtual Memory") },
+ { "MemTotal", N_("Total Memory") },
+ { "MemFree", N_("Free Memory") },
+ { "SwapCached", N_("Cached Swap") },
+ { "HighTotal", N_("High Memory") },
+ { "HighFree", N_("Free High Memory") },
+ { "LowTotal", N_("Low Memory") },
+ { "LowFree", N_("Free Low Memory") },
+ { "SwapTotal", N_("Virtual Memory") },
+ { "SwapFree", N_("Free Virtual Memory") },
{ NULL },
};
gint i;
memlabels = g_hash_table_new(g_str_hash, g_str_equal);
-
+
for (i = 0; proc2real[i].proc_label; i++) {
g_hash_table_insert(memlabels, proc2real[i].proc_label,
_(proc2real[i].real_label));
diff --git a/modules/devices/dmi.c b/modules/devices/dmi.c
index 61cea65d..5f87df13 100644
--- a/modules/devices/dmi.c
+++ b/modules/devices/dmi.c
@@ -22,7 +22,7 @@
#include <sys/types.h>
#include "devices.h"
-
+
typedef struct _DMIInfo DMIInfo;
struct _DMIInfo {
@@ -35,10 +35,14 @@ DMIInfo dmi_info_table[] = {
{ "$BIOS", NULL, NULL },
{ "Date", "/sys/class/dmi/id/bios_date", "bios-release-date" },
{ "Vendor", "/sys/class/dmi/id/bios_vendor", "bios-vendor" },
- { "Version", "/sys/class/dmi/id/bios_version", "bios-version" },
+ { "Version#0", "/sys/class/dmi/id/bios_version", "bios-version" },
{ "$Board", NULL, NULL },
{ "Name", "/sys/class/dmi/id/board_name", "baseboard-product-name" },
{ "Vendor", "/sys/class/dmi/id/board_vendor", "baseboard-manufacturer" },
+ { "$Product", NULL, NULL },
+ { "Name", "/sys/class/dmi/id/product_name", "system-product-name" },
+ { "Family", "/sys/class/dmi/id/product_family", "system-product-family" },
+ { "Version#1", "/sys/class/dmi/id/product_version", "system-product-version" },
};
gchar *dmi_info = NULL;
@@ -62,16 +66,16 @@ gboolean dmi_get_info_dmidecode()
g_free(dmi_info);
dmi_info = NULL;
}
-
+
for (i = 0; i < G_N_ELEMENTS(dmi_info_table); i++) {
info = &dmi_info_table[i];
-
+
if (*(info->name) == '$') {
group = info->name + 1;
dmi_info = h_strdup_cprintf("[%s]\n", dmi_info, group);
} else {
gchar *temp;
-
+
if (!info->param)
continue;
@@ -84,7 +88,7 @@ gboolean dmi_get_info_dmidecode()
dmi_failed = TRUE;
break;
}
-
+
add_to_moreinfo(group, info->name, buffer);
const gchar *url = vendor_get_url(buffer);
@@ -115,14 +119,14 @@ gboolean dmi_get_info_dmidecode()
dmi_failed = TRUE;
break;
}
- }
+ }
}
-
+
if (dmi_failed) {
g_free(dmi_info);
dmi_info = NULL;
}
-
+
return !dmi_failed;
}
@@ -132,17 +136,17 @@ gboolean dmi_get_info_sys()
gchar buffer[256];
const gchar *group = NULL;
DMIInfo *info;
- gboolean dmi_failed = FALSE;
+ gboolean dmi_succeeded = FALSE;
gint i;
-
+
if (dmi_info) {
g_free(dmi_info);
dmi_info = NULL;
}
-
+
for (i = 0; i < G_N_ELEMENTS(dmi_info_table); i++) {
info = &dmi_info_table[i];
-
+
if (*(info->name) == '$') {
group = info->name + 1;
dmi_info = h_strdup_cprintf("[%s]\n", dmi_info, group);
@@ -152,7 +156,7 @@ gboolean dmi_get_info_sys()
fclose(dmi_file);
add_to_moreinfo(group, info->name, buffer);
-
+
const gchar *url = vendor_get_url(buffer);
if (url) {
const gchar *vendor = vendor_get_name(buffer);
@@ -176,31 +180,34 @@ gboolean dmi_get_info_sys()
info->name,
g_strstrip(buffer));
}
+ dmi_succeeded = TRUE;
} else {
- dmi_failed = TRUE;
- break;
+ dmi_info = h_strdup_cprintf("%s=%s\n",
+ dmi_info,
+ info->name,
+ _("(Not available; Perhaps try running HardInfo as root.)") );
}
- }
+ }
}
-
- if (dmi_failed) {
+
+ if (!dmi_succeeded) {
g_free(dmi_info);
dmi_info = NULL;
}
-
- return !dmi_failed;
+
+ return dmi_succeeded;
}
void __scan_dmi()
{
gboolean dmi_ok;
-
+
dmi_ok = dmi_get_info_sys();
-
+
if (!dmi_ok) {
dmi_ok = dmi_get_info_dmidecode();
}
-
+
if (!dmi_ok) {
dmi_info = g_strdup("[No DMI information]\n"
"There was an error retrieving the information.=\n"
diff --git a/modules/devices/ia64/processor.c b/modules/devices/ia64/processor.c
index 55e5e3a8..c4d06a71 100644
--- a/modules/devices/ia64/processor.c
+++ b/modules/devices/ia64/processor.c
@@ -18,61 +18,198 @@
#include "hardinfo.h"
#include "devices.h"
+#include "cpu_util.h"
GSList *
processor_scan(void)
{
- Processor *processor;
+ GSList *procs = NULL;
+ Processor *processor = NULL;
FILE *cpuinfo;
gchar buffer[128];
+ gchar *rep_pname = NULL;
+ GSList *pi = NULL;
- cpuinfo = fopen("/proc/cpuinfo", "r");
+ cpuinfo = fopen(PROC_CPUINFO, "r");
if (!cpuinfo)
- return NULL;
+ return NULL;
- processor = g_new0(Processor, 1);
+#define CHECK_FOR(k) (g_str_has_prefix(tmp[0], k))
while (fgets(buffer, 128, cpuinfo)) {
- gchar **tmp = g_strsplit(buffer, ":", 2);
+ gchar **tmp = g_strsplit(buffer, ":", 2);
+ if (tmp[0] && tmp[1]) {
+ tmp[0] = g_strstrip(tmp[0]);
+ tmp[1] = g_strstrip(tmp[1]);
+ } else {
+ g_strfreev(tmp);
+ continue;
+ }
+
+ get_str("Processor", rep_pname);
+
+ if ( CHECK_FOR("processor") ) {
+ /* finish previous */
+ if (processor) {
+ procs = g_slist_append(procs, processor);
+ }
+
+ /* start next */
+ processor = g_new0(Processor, 1);
+ processor->id = atol(tmp[1]);
+
+ if (rep_pname)
+ processor->model_name = g_strdup(rep_pname);
- if (tmp[0] && tmp[1]) {
- tmp[0] = g_strstrip(tmp[0]);
- tmp[1] = g_strstrip(tmp[1]);
+ g_strfreev(tmp);
+ continue;
+ }
- get_str("vendor", processor->model_name);
- get_str("arch", processor->vendor_id);
- get_str("family", processor->strmodel);
- get_float("BogoMIPS", processor->bogomips);
+ if (!processor &&
+ ( CHECK_FOR("vendor")
+ || CHECK_FOR("arch")
+ || CHECK_FOR("family") ) ) {
- }
- g_strfreev(tmp);
+ /* single proc/core may not have "processor : n" */
+ processor = g_new0(Processor, 1);
+ processor->id = 0;
+
+ if (rep_pname)
+ processor->model_name = g_strdup(rep_pname);
+ }
+
+ if (processor) {
+ get_str("vendor", processor->vendor_id);
+ get_str("archrev", processor->archrev);
+ get_str("arch", processor->arch);
+ get_str("family", processor->family);
+ get_str("features", processor->features);
+ get_int("model", processor->model);
+ get_int("revision", processor->revision);
+ get_float("BogoMIPS", processor->bogomips);
+ get_float("cpu MHz", processor->cpu_mhz);
+ get_int("cpu regs", processor->cpu_regs);
+ }
+ g_strfreev(tmp);
}
- processor->cpu_mhz = 0.0f;
-
+ if (processor)
+ procs = g_slist_append(procs, processor);
+
+ g_free(rep_pname);
fclose(cpuinfo);
- return g_slist_append(NULL, processor);
+ /* TODO: redup */
+
+ /* data not from /proc/cpuinfo */
+ for (pi = procs; pi; pi = pi->next) {
+ processor = (Processor *) pi->data;
+
+ /* strings can't be null or segfault later */
+ STRIFNULL(processor->model_name, _("IA64 Processor") );
+ UNKIFNULL(processor->vendor_id);
+ STRIFNULL(processor->arch, "IA-64");
+ STRIFNULL(processor->archrev, "0");
+ UNKIFNULL(processor->family);
+ UNKIFNULL(processor->features);
+
+ /* topo & freq */
+ processor->cpufreq = cpufreq_new(processor->id);
+ processor->cputopo = cputopo_new(processor->id);
+
+ if (processor->cpufreq->cpukhz_max)
+ processor->cpu_mhz = processor->cpufreq->cpukhz_max / 1000;
+
+ }
+
+ return procs;
+}
+
+gchar *processor_name(GSList * processors) {
+ return processor_name_default(processors);
+}
+
+gchar *processor_describe(GSList * processors) {
+ return processor_describe_default(processors);
}
gchar *
-processor_get_info(GSList *processors)
+processor_get_detailed_info(Processor *processor)
{
- Processor *processor = (Processor *)processors->data;
-
- return g_strdup_printf("[Processor]\n"
- "Model=%s\n"
- "Architecture=%s\n"
- "Family=%sMHz\n"
- "BogoMIPS=%s\n"
- "Byte Order=%s\n",
- processor->model_name,
- processor->vendor_id,
- processor->strmodel,
- processor->bogomips,
-#if G_BYTE_ORDER == G_LITTLE_ENDIAN
- "Little Endian"
-#else
- "Big Endian"
-#endif
- );
+ gchar *tmp_cpufreq, *tmp_topology, *ret;
+
+ tmp_topology = cputopo_section_str(processor->cputopo);
+ tmp_cpufreq = cpufreq_section_str(processor->cpufreq);
+
+ ret = g_strdup_printf("[%s]\n"
+ "%s=%s\n" /* name */
+ "%s=%s\n" /* vendor */
+ "%s=%s\n" /* arch */
+ "%s=%s\n" /* archrev */
+ "%s=%s\n" /* family */
+ "%s=%d\n" /* model no. */
+ "%s=%d\n" /* revision */
+ "%s=%.2f %s\n" /* frequency */
+ "%s=%.2f\n" /* bogomips */
+ "%s=%s\n" /* byte order */
+ "%s=%d\n" /* regs */
+ "%s=%s\n" /* features */
+ "%s" /* topology */
+ "%s" /* frequency scaling */
+ "%s",/* empty */
+ _("Processor"),
+ _("Name"), processor->model_name,
+ _("Vendor"), processor->vendor_id,
+ _("Architecture"), processor->arch,
+ _("Architecture Revision"), processor->archrev,
+ _("Family"), processor->family,
+ _("Model"), processor->model,
+ _("Revision"), processor->revision,
+ _("Frequency"), processor->cpu_mhz, _("MHz"),
+ _("BogoMips"), processor->bogomips,
+ _("Byte Order"), byte_order_str(),
+ _("CPU regs"), processor->cpu_regs,
+ _("Features"), processor->features,
+ tmp_topology,
+ tmp_cpufreq,
+ "");
+ g_free(tmp_cpufreq);
+ g_free(tmp_topology);
+ return ret;
+}
+
+gchar *processor_get_info(GSList * processors)
+{
+ Processor *processor;
+
+ if (g_slist_length(processors) > 1) {
+ gchar *ret, *tmp, *hashkey;
+ GSList *l;
+
+ tmp = g_strdup("");
+
+ for (l = processors; l; l = l->next) {
+ processor = (Processor *) l->data;
+
+ tmp = g_strdup_printf("%s$CPU%d$%s=%.2f %s\n",
+ tmp, processor->id,
+ processor->model_name,
+ processor->cpu_mhz, _("MHz"));
+
+ hashkey = g_strdup_printf("CPU%d", processor->id);
+ moreinfo_add_with_prefix("DEV", hashkey,
+ processor_get_detailed_info(processor));
+ g_free(hashkey);
+ }
+
+ ret = g_strdup_printf("[$ShellParam$]\n"
+ "ViewType=1\n"
+ "[Processors]\n"
+ "%s", tmp);
+ g_free(tmp);
+
+ return ret;
+ }
+
+ processor = (Processor *) processors->data;
+ return processor_get_detailed_info(processor);
}
diff --git a/modules/devices/inputdevices.c b/modules/devices/inputdevices.c
index d3f8847f..cf1728a9 100644
--- a/modules/devices/inputdevices.c
+++ b/modules/devices/inputdevices.c
@@ -85,55 +85,55 @@ __scan_input_devices(void)
if (name && strstr(name, "PC Speaker")) {
d = 3; // INPUT_PCSPKR
}
-
- tmp = g_strdup_printf("INP%d", ++n);
- input_list = h_strdup_cprintf("$%s$%s=\n",
- input_list,
- tmp, name);
- input_icons = h_strdup_cprintf("Icon$%s$%s=%s\n",
- input_icons,
- tmp, name,
- input_devices[d].icon);
- gchar *strhash = g_strdup_printf("[Device Information]\n"
- "Name=%s\n"
- "Type=%s\n"
- "Bus=0x%x\n",
- name,
- input_devices[d].name,
- bus);
-
- const gchar *url = vendor_get_url(name);
- if (url) {
- strhash = h_strdup_cprintf("Vendor=%s (%s)\n",
- strhash,
- vendor_get_name(name),
- url);
- } else {
- strhash = h_strdup_cprintf("Vendor=%x\n",
- strhash,
- vendor);
- }
- strhash = h_strdup_cprintf("Product=0x%x\n"
- "Version=0x%x\n",
- strhash, product, version);
-
- if (phys && phys[1] != 0) {
- strhash = h_strdup_cprintf("Connected to=%s\n",
- strhash, phys);
- }
-
- if (phys && strstr(phys, "ir")) {
- strhash = h_strdup_cprintf("InfraRed port=yes\n",
- strhash);
- }
-
- moreinfo_add_with_prefix("DEV", tmp, strhash);
- g_free(tmp);
+ tmp = g_strdup_printf("INP%d", ++n);
+ input_list = h_strdup_cprintf("$%s$%s=\n",
+ input_list,
+ tmp, name);
+ input_icons = h_strdup_cprintf("Icon$%s$%s=%s\n",
+ input_icons,
+ tmp, name,
+ input_devices[d].icon);
+
+ const gchar *v_url = (gchar*)vendor_get_url(name);
+ const gchar *v_name = (gchar*)vendor_get_name(name);
+ gchar *v_str = NULL;
+ if (v_url != NULL)
+ v_str = g_strdup_printf("[0x%x] %s (%s)", vendor, v_name, v_url);
+ else
+ v_str = g_strdup_printf("0x%x", vendor);
+ v_str = hardinfo_clean_value(v_str, 1);
+ name = hardinfo_clean_value(name, 1);
+
+ gchar *strhash = g_strdup_printf("[%s]\n"
+ /* Name */ "%s=%s\n"
+ /* Type */ "%s=%s\n"
+ /* Bus */ "%s=0x%x\n"
+ /* Vendor */ "%s=%s\n"
+ /* Product */"%s=0x%x\n"
+ /* Version */"%s=0x%x\n",
+ _("Device Information"),
+ _("Name"), name,
+ _("Type"), input_devices[d].name,
+ _("Bus"), bus,
+ _("Vendor"), v_str,
+ _("Product"), product,
+ _("Version"), version );
- g_free(phys);
- g_free(name);
- }
+ if (phys && phys[1] != 0) {
+ strhash = h_strdup_cprintf("%s=%s\n", strhash, _("Connected to"), phys);
+ }
+
+ if (phys && strstr(phys, "ir")) {
+ strhash = h_strdup_cprintf("%s=%s\n", strhash, _("InfraRed port"), _("Yes") );
+ }
+
+ moreinfo_add_with_prefix("DEV", tmp, strhash);
+ g_free(tmp);
+ g_free(v_str);
+ g_free(phys);
+ g_free(name);
+ }
}
fclose(dev);
diff --git a/modules/devices/m68k/processor.c b/modules/devices/m68k/processor.c
index d9902428..e030732a 100644
--- a/modules/devices/m68k/processor.c
+++ b/modules/devices/m68k/processor.c
@@ -18,6 +18,7 @@
#include "hardinfo.h"
#include "devices.h"
+#include "cpu_util.h"
GSList *
processor_scan(void)
@@ -26,54 +27,66 @@ processor_scan(void)
FILE *cpuinfo;
gchar buffer[128];
- cpuinfo = fopen("/proc/cpuinfo", "r");
+ cpuinfo = fopen(PROC_CPUINFO, "r");
if (!cpuinfo)
- return NULL;
+ return NULL;
processor = g_new0(Processor, 1);
while (fgets(buffer, 128, cpuinfo)) {
- gchar **tmp = g_strsplit(buffer, ":", 2);
+ gchar **tmp = g_strsplit(buffer, ":", 2);
- if (tmp[0] && tmp[1]) {
- tmp[0] = g_strstrip(tmp[0]);
- tmp[1] = g_strstrip(tmp[1]);
+ if (tmp[0] && tmp[1]) {
+ tmp[0] = g_strstrip(tmp[0]);
+ tmp[1] = g_strstrip(tmp[1]);
- get_str("CPU", processor->model_name);
- get_float("Clocking", processor->cpu_mhz);
- get_float("bogomips", processor->bogomips);
-
- get_str("FPU", processor->has_fpu);
- }
- g_strfreev(tmp);
+ get_str("CPU", processor->model_name);
+ get_str("MMU", processor->mmu_name);
+ get_str("FPU", processor->fpu_name);
+ get_float("Clocking", processor->cpu_mhz);
+ get_float("BogoMips", processor->bogomips);
+ get_str("Calibration", processor->calibration);
+ }
+ g_strfreev(tmp);
}
-
+
gchar *tmp;
tmp = g_strconcat("Motorola ", processor->model_name, NULL);
g_free(processor->model_name);
processor->model_name = tmp;
-
+
fclose(cpuinfo);
return g_slist_append(NULL, processor);
}
+gchar *processor_name(GSList * processors) {
+ return processor_name_default(processors);
+}
+
+gchar *processor_describe(GSList * processors) {
+ return processor_describe_default(processors);
+}
+
gchar *
processor_get_info(GSList *processors)
{
- Processor *processor = (Processor *)processors->data;
-
- return g_strdup_printf("[Processor]\n"
- "Name=%s\n"
- "Frequency=%.2fMHz\n"
- "BogoMips=%.2f\n"
- "Byte Order=%s\n",
- processor->model_name,
- processor->cpu_mhz,
- processor->bogomips,
-#if G_BYTE_ORDER == G_LITTLE_ENDIAN
- "Little Endian"
-#else
- "Big Endian"
-#endif
- );
+ Processor *processor = (Processor *)processors->data;
+
+ return g_strdup_printf("[%s]\n"
+ "%s=%s\n" /* cpu */
+ "%s=%s\n" /* mmu */
+ "%s=%s\n" /* fpu */
+ "%s=%.2f %s\n" /* frequency */
+ "%s=%.2f\n" /* bogomips */
+ "%s=%s\n" /* byte order */
+ "%s=%s\n", /* calibration */
+ _("Processor"),
+ _("Model"), processor->model_name,
+ _("MMU"), processor->mmu_name,
+ _("FPU"), processor->fpu_name,
+ _("Frequency"), processor->cpu_mhz, _("MHz"),
+ _("BogoMips"), processor->bogomips,
+ _("Byte Order"), byte_order_str(),
+ _("Calibration"), processor->calibration
+ );
}
diff --git a/modules/devices/mips/processor.c b/modules/devices/mips/processor.c
index 86c9b958..b31af7dd 100644
--- a/modules/devices/mips/processor.c
+++ b/modules/devices/mips/processor.c
@@ -18,6 +18,7 @@
#include "hardinfo.h"
#include "devices.h"
+#include "cpu_util.h"
GSList *
processor_scan(void)
@@ -26,24 +27,24 @@ processor_scan(void)
FILE *cpuinfo;
gchar buffer[128];
- cpuinfo = fopen("/proc/cpuinfo", "r");
+ cpuinfo = fopen(PROC_CPUINFO, "r");
if (!cpuinfo)
- return NULL;
+ return NULL;
processor = g_new0(Processor, 1);
while (fgets(buffer, 128, cpuinfo)) {
- gchar **tmp = g_strsplit(buffer, ":", 2);
+ gchar **tmp = g_strsplit(buffer, ":", 2);
- if (tmp[0] && tmp[1]) {
- tmp[0] = g_strstrip(tmp[0]);
- tmp[1] = g_strstrip(tmp[1]);
+ if (tmp[0] && tmp[1]) {
+ tmp[0] = g_strstrip(tmp[0]);
+ tmp[1] = g_strstrip(tmp[1]);
- get_str("system type", processor->model_name);
- get_str("cpu model", processor->vendor_id);
- get_float("cpu MHz", processor->cpu_mhz);
- get_float("BogoMIPS", processor->bogomips);
- }
- g_strfreev(tmp);
+ get_str("system type", processor->vendor_id);
+ get_str("cpu model", processor->model_name);
+ get_float("cpu MHz", processor->cpu_mhz);
+ get_float("BogoMIPS", processor->bogomips);
+ }
+ g_strfreev(tmp);
}
fclose(cpuinfo);
@@ -51,25 +52,30 @@ processor_scan(void)
return g_slist_append(NULL, processor);
}
+gchar *processor_name(GSList * processors) {
+ return processor_name_default(processors);
+}
+
+gchar *processor_describe(GSList * processors) {
+ return processor_describe_default(processors);
+}
+
gchar *
processor_get_info(GSList *processors)
{
- Processor *processor = (Processor *)processors->data;
-
- return g_strdup_printf("[Processor]\n"
- "System Type=%s\n"
- "CPU Model=%s\n"
- "Frequency=%.2fMHz\n"
- "BogoMIPS=%.2f\n"
- "Byte Order=%s\n",
- processor->model_name,
- processor->vendor_id,
- processor->cpu_mhz,
- processor->bogomips,
-#if G_BYTE_ORDER == G_LITTLE_ENDIAN
- "Little Endian"
-#else
- "Big Endian"
-#endif
- );
+ Processor *processor = (Processor *)processors->data;
+
+ return g_strdup_printf("[%s]\n"
+ "%s=%s\n"
+ "%s=%s\n"
+ "%s=%.2f %s\n" /* frequency */
+ "%s=%.2f\n" /* bogomips */
+ "%s=%s\n", /* byte order */
+ _("Processor"),
+ _("Model"), processor->model_name,
+ _("System Type"), processor->vendor_id,
+ _("Frequency"), processor->cpu_mhz, _("MHz"),
+ _("BogoMips"), processor->bogomips,
+ _("Byte Order"), byte_order_str()
+ );
}
diff --git a/modules/devices/parisc/processor.c b/modules/devices/parisc/processor.c
index 83672126..9ca38d12 100644
--- a/modules/devices/parisc/processor.c
+++ b/modules/devices/parisc/processor.c
@@ -18,70 +18,193 @@
#include "hardinfo.h"
#include "devices.h"
+#include "cpu_util.h"
GSList *
-processors_scan(void)
+processor_scan(void)
{
- Processor *processor;
+ GSList *procs = NULL;
+ Processor *processor = NULL;
FILE *cpuinfo;
gchar buffer[128];
+ gchar *rep_pname = NULL;
+ GSList *pi = NULL;
- cpuinfo = fopen("/proc/cpuinfo", "r");
+ cpuinfo = fopen(PROC_CPUINFO, "r");
if (!cpuinfo)
- return NULL;
+ return NULL;
- processor = g_new0(Processor, 1);
+#define CHECK_FOR(k) (g_str_has_prefix(tmp[0], k))
while (fgets(buffer, 128, cpuinfo)) {
- gchar **tmp = g_strsplit(buffer, ":", 2);
-
- if (tmp[0] && tmp[1]) {
- tmp[0] = g_strstrip(tmp[0]);
- tmp[1] = g_strstrip(tmp[1]);
-
- get_str("cpu family", processor->model_name);
- get_str("cpu", processor->vendor_id);
- get_float("cpu MHz", processor->cpu_mhz);
- get_float("bogomips", processor->bogomips);
-
- get_str("model name", processor->strmodel);
-
- get_int("I-cache", processor->has_fpu);
- get_int("D-cache", processor->flags);
-
- }
- g_strfreev(tmp);
+ gchar **tmp = g_strsplit(buffer, ":", 2);
+ if (tmp[0] && tmp[1]) {
+ tmp[0] = g_strstrip(tmp[0]);
+ tmp[1] = g_strstrip(tmp[1]);
+ } else {
+ g_strfreev(tmp);
+ continue;
+ }
+
+ get_str("Processor", rep_pname);
+
+ if ( CHECK_FOR("processor") ) {
+ /* finish previous */
+ if (processor) {
+ procs = g_slist_append(procs, processor);
+ }
+
+ /* start next */
+ processor = g_new0(Processor, 1);
+ processor->id = atol(tmp[1]);
+
+ if (rep_pname)
+ processor->model_name = g_strdup(rep_pname);
+
+ g_strfreev(tmp);
+ continue;
+ }
+
+ if (!processor &&
+ ( CHECK_FOR("cpu family")
+ || CHECK_FOR("cpu MHz")
+ || CHECK_FOR("cpu") ) ) {
+
+ /* single proc/core may not have "processor : n" */
+ processor = g_new0(Processor, 1);
+ processor->id = 0;
+
+ if (rep_pname)
+ processor->model_name = g_strdup(rep_pname);
+ }
+
+ if (processor) {
+ get_str("cpu family", processor->cpu_family);
+ get_float("cpu MHz", processor->cpu_mhz);
+ get_str("cpu", processor->model_name);
+ get_float("bogomips", processor->bogomips);
+ get_str("model name", processor->strmodel);
+ get_str("I-cache", processor->icache_str);
+ get_str("D-cache", processor->dcache_str);
+ get_str("hversion", processor->hversion);
+ get_str("sversion", processor->sversion);
+ }
+ g_strfreev(tmp);
}
+ if (processor)
+ procs = g_slist_append(procs, processor);
+
+ g_free(rep_pname);
fclose(cpuinfo);
- return g_slist_append(NULL, processor);
+ /* TODO: redup */
+
+ /* data not from /proc/cpuinfo */
+ for (pi = procs; pi; pi = pi->next) {
+ processor = (Processor *) pi->data;
+
+ /* strings can't be null or segfault later */
+ STRIFNULL(processor->model_name, _("PA-RISC Processor") );
+ STRIFNULL(processor->cpu_family, "PA-RISC");
+ UNKIFNULL(processor->strmodel);
+
+ /* topo & freq */
+ processor->cpufreq = cpufreq_new(processor->id);
+ processor->cputopo = cputopo_new(processor->id);
+
+ if (processor->cpufreq->cpukhz_max)
+ processor->cpu_mhz = processor->cpufreq->cpukhz_max / 1000;
+
+ }
+
+ return procs;
+}
+
+gchar *processor_name(GSList * processors) {
+ return processor_name_default(processors);
+}
+
+gchar *processor_describe(GSList * processors) {
+ return processor_describe_default(processors);
}
gchar *
-processor_get_info(GSList *processors)
+processor_get_detailed_info(Processor *processor)
+{
+ gchar *tmp_cpufreq, *tmp_topology, *ret;
+
+ tmp_topology = cputopo_section_str(processor->cputopo);
+ tmp_cpufreq = cpufreq_section_str(processor->cpufreq);
+
+ ret = g_strdup_printf("[%s]\n"
+ "%s=%s\n"
+ "%s=%s\n"
+ "%s=%s\n" /* model name */
+ "%s=%.2f %s\n" /* frequency */
+ "%s=%.2f\n" /* bogomips */
+ "%s=%s\n" /* byte order */
+ "%s=%s\n" /* hversion */
+ "%s=%s\n" /* sversion */
+ "[%s]\n"
+ "I-Cache=%s\n"
+ "D-Cache=%s\n"
+ "%s" /* topology */
+ "%s" /* frequency scaling */
+ "%s",/* empty */
+ _("Processor"),
+ _("Model"), processor->model_name,
+ _("Architecture"), processor->cpu_family,
+ _("System"), processor->strmodel,
+ _("Frequency"), processor->cpu_mhz, _("MHz"),
+ _("BogoMips"), processor->bogomips,
+ _("Byte Order"), byte_order_str(),
+ _("HVersion"), processor->hversion,
+ _("SVersion"), processor->sversion,
+ _("Cache"),
+ processor->icache_str,
+ processor->dcache_str,
+ tmp_topology,
+ tmp_cpufreq,
+ "");
+
+ g_free(tmp_cpufreq);
+ g_free(tmp_topology);
+ return ret;
+}
+
+gchar *processor_get_info(GSList * processors)
{
- Processor *processor = (Processor *)processors->data;
-
- return g_strdup_printf("[Processor]\n"
- "CPU Family=%s\n"
- "CPU=%s\n"
- "Frequency=%.2fMHz\n"
- "Bogomips=%.2f\n"
- "Model Name=%s\n"
- "Byte Order=%s\n"
- "[Cache]\n"
- "I-Cache=%s\n"
- "D-Cache=%s\n",
- processor->model_name,
- processor->vendor_id,
- processor->cpu_mhz,
- processor->bogomips,
- processor->strmodel,
-#if G_BYTE_ORDER == G_LITTLE_ENDIAN
- "Little Endian",
-#else
- "Big Endian",
-#endif
- processor->has_fpu,
- processor->flags);
+ Processor *processor;
+
+ if (g_slist_length(processors) > 1) {
+ gchar *ret, *tmp, *hashkey;
+ GSList *l;
+
+ tmp = g_strdup("");
+
+ for (l = processors; l; l = l->next) {
+ processor = (Processor *) l->data;
+
+ tmp = g_strdup_printf("%s$CPU%d$%s=%.2f %s\n",
+ tmp, processor->id,
+ processor->model_name,
+ processor->cpu_mhz, _("MHz"));
+
+ hashkey = g_strdup_printf("CPU%d", processor->id);
+ moreinfo_add_with_prefix("DEV", hashkey,
+ processor_get_detailed_info(processor));
+ g_free(hashkey);
+ }
+
+ ret = g_strdup_printf("[$ShellParam$]\n"
+ "ViewType=1\n"
+ "[Processors]\n"
+ "%s", tmp);
+ g_free(tmp);
+
+ return ret;
+ }
+
+ processor = (Processor *) processors->data;
+ return processor_get_detailed_info(processor);
}
diff --git a/modules/devices/pci.c b/modules/devices/pci.c
index 91ff914d..c1965a63 100644
--- a/modules/devices/pci.c
+++ b/modules/devices/pci.c
@@ -40,13 +40,13 @@ scan_pci_do(void)
gchar buffer[256], *buf, *strhash = NULL, *strdevice = NULL;
gchar *category = NULL, *name = NULL, *icon, *lspci_path, *command_line = NULL;
gint n = 0, x = 0;
-
+
if ((lspci_path = find_program("lspci")) == NULL) {
goto pci_error;
} else {
command_line = g_strdup_printf("%s -v", lspci_path);
}
-
+
if (!_pci_devices) {
_pci_devices = g_hash_table_new(g_str_hash, g_str_equal);
}
@@ -60,11 +60,11 @@ scan_pci_do(void)
}
} else {
gchar *tmp;
-
+
tmp = g_strdup_printf("%s -i '%s'", command_line, buf);
g_free(buf);
buf = tmp;
-
+
DEBUG("using updated PCI IDs (from %s)", buf);
if (!(lspci = popen(tmp, "r"))) {
g_free(buf);
@@ -103,30 +103,31 @@ scan_pci_do(void)
g_strfreev(list);
if (irq)
- strdevice = h_strdup_cprintf("IRQ=%d\n", strdevice, irq);
+ strdevice = h_strdup_cprintf("%s=%d\n", strdevice, _("IRQ"), irq);
if (freq)
- strdevice = h_strdup_cprintf("Frequency=%dMHz\n", strdevice, freq);
+ strdevice = h_strdup_cprintf("%s=%d %s\n", strdevice, _("Frequency"), freq, _("MHz") );
if (latency)
- strdevice = h_strdup_cprintf("Latency=%d\n", strdevice, latency);
+ strdevice = h_strdup_cprintf("%s=%d\n", strdevice, _("Latency"), latency);
- strdevice = h_strdup_cprintf("Bus Master=%s\n", strdevice, bus_master ? "Yes" : "No");
+ strdevice = h_strdup_cprintf("%s=%s\n", strdevice, _("Bus Master"), bus_master ? _("Yes") : _("No") );
} else if (!strncmp(buf, "Kernel modules", 14)) {
WALK_UNTIL(' ');
WALK_UNTIL(':');
buf++;
-
- strdevice = h_strdup_cprintf("Kernel modules=%s\n", strdevice, buf);
+
+ strdevice = h_strdup_cprintf("%s=%s\n", strdevice, _("Kernel modules"), buf);
} else if (!strncmp(buf, "Subsystem", 9)) {
WALK_UNTIL(' ');
buf++;
const gchar *oem_vendor_url = vendor_get_url(buf);
- if (oem_vendor_url)
- strdevice = h_strdup_cprintf("OEM Vendor=%s (%s)\n",
+ if (oem_vendor_url)
+ strdevice = h_strdup_cprintf(_("%s=%s (%s)\n"),
strdevice,
+ _("OEM Vendor"),
vendor_get_name(buf),
oem_vendor_url);
} else if (!strncmp(buf, "Capabilities", 12)
- && !strstr(buf, "only to root") &&
+ && !strstr(buf, "only to root") &&
!strstr(buf, "access denied")) {
WALK_UNTIL(' ');
WALK_UNTIL(']');
@@ -144,13 +145,13 @@ scan_pci_do(void)
WALK_UNTIL('[');
sscanf(buf, "[size=%d%c", &mem, &unit);
- strdevice = h_strdup_cprintf("Memory#%d=%d%cB (%s%s)\n",
- strdevice, ++x,
+ strdevice = h_strdup_cprintf("%s#%d=%d%cB (%s%s)\n",
+ strdevice, _("Memory"), ++x,
mem,
(unit == ']') ? ' ' : unit,
_32bit ? "32-bit, " : "",
- prefetch ? "prefetchable" :
- "non-prefetchable");
+ prefetch ? _("prefetchable") :
+ _("non-prefetchable") );
} else if (!strncmp(buf, "I/O ports at", 12)) {
guint io_addr, io_size;
@@ -158,8 +159,8 @@ scan_pci_do(void)
sscanf(buf, "I/O ports at %x [size=%d]", &io_addr, &io_size);
strdevice =
- h_strdup_cprintf("I/O ports at#%d=0x%x - 0x%x\n",
- strdevice, ++x, io_addr,
+ h_strdup_cprintf("%s#%d=0x%x - 0x%x\n",
+ strdevice, _("I/O ports at"), ++x, io_addr,
io_addr + io_size - 1);
} else if ((buf[0] >= '0' && buf[0] <= '9') && (buf[4] == ':' || buf[2] == ':')) {
gint bus, device, function, domain;
@@ -197,51 +198,57 @@ scan_pci_do(void)
else if (strstr(category, "Multimedia")) icon = "media";
else if (strstr(category, "USB")) icon = "usb";
else icon = "pci";
-
+
name = g_strdup(buf);
g_hash_table_insert(_pci_devices,
g_strdup_printf("0000:%02x:%02x.%x", bus, device, function),
name);
- strhash = g_strdup_printf("PCI%d", n);
- strdevice = g_strdup_printf("[Device Information]\n"
- "Name=%s\n"
- "Class=%s\n"
- "Domain=%d\n"
- "Bus, device, function=%d, %d, %d\n",
- name, category, domain, bus,
- device, function);
-
+ strhash = g_strdup_printf("PCI%d", n);
+ strdevice = g_strdup_printf("[%s]\n"
+ /* Name */ "%s=%s\n"
+ /* Class */ "%s=%s\n"
+ /* Domain */ "%s=%d\n"
+ /* Bus, device, function */
+ "%s=%d, %d, %d\n",
+ _("Device Information"),
+ _("Name"), name,
+ _("Class"), category,
+ _("Domain"), domain,
+ _("Bus, device, function"),
+ bus, device, function);
+
const gchar *url = vendor_get_url(name);
if (url) {
- strdevice = h_strdup_cprintf("Vendor=%s (%s)\n",
+ strdevice = h_strdup_cprintf("%s=%s (%s)\n",
strdevice,
+ _("Vendor"),
vendor_get_name(name),
url);
}
-
+
g_hash_table_insert(_pci_devices,
g_strdup_printf("0000:%02x:%02x.%x", bus, device, function),
g_strdup(name));
-
+
pci_list = h_strdup_cprintf("$PCI%d$%s=%s\n", pci_list, n, category, name);
n++;
}
}
-
+
if (pclose(lspci)) {
pci_error:
/* error (no pci, perhaps?) */
- pci_list = g_strconcat(pci_list, "No PCI devices found=\n", NULL);
+ pci_list = g_strconcat(pci_list, _("No PCI devices found"), "=\n", NULL);
} else if (strhash) {
- /* insert the last device */
+ /* insert the last device */
moreinfo_add_with_prefix("DEV", strhash, strdevice);
g_free(strhash);
g_free(category);
g_free(name);
}
-
+
g_free(lspci_path);
g_free(command_line);
}
diff --git a/modules/devices/ppc/processor.c b/modules/devices/ppc/processor.c
index a7988f97..3360a136 100644
--- a/modules/devices/ppc/processor.c
+++ b/modules/devices/ppc/processor.c
@@ -18,68 +18,189 @@
#include "hardinfo.h"
#include "devices.h"
+#include "cpu_util.h"
GSList *
processor_scan(void)
{
- Processor *processor;
+ GSList *procs = NULL;
+ Processor *processor = NULL;
FILE *cpuinfo;
gchar buffer[128];
+ gchar *rep_pname = NULL;
+ GSList *pi = NULL;
- cpuinfo = fopen("/proc/cpuinfo", "r");
+ cpuinfo = fopen(PROC_CPUINFO, "r");
if (!cpuinfo)
- return NULL;
+ return NULL;
- processor = g_new0(Processor, 1);
+#define CHECK_FOR(k) (g_str_has_prefix(tmp[0], k))
while (fgets(buffer, 128, cpuinfo)) {
- gchar **tmp = g_strsplit(buffer, ":", 2);
+ gchar **tmp = g_strsplit(buffer, ":", 2);
+ if (tmp[0] && tmp[1]) {
+ tmp[0] = g_strstrip(tmp[0]);
+ tmp[1] = g_strstrip(tmp[1]);
+ } else {
+ g_strfreev(tmp);
+ continue;
+ }
+
+ get_str("Processor", rep_pname);
+
+ if ( CHECK_FOR("processor") ) {
+ /* finish previous */
+ if (processor) {
+ procs = g_slist_append(procs, processor);
+ }
+
+ /* start next */
+ processor = g_new0(Processor, 1);
+ processor->id = atol(tmp[1]);
+
+ if (rep_pname)
+ processor->model_name = g_strdup(rep_pname);
- if (tmp[0] && tmp[1]) {
- tmp[0] = g_strstrip(tmp[0]);
- tmp[1] = g_strstrip(tmp[1]);
+ g_strfreev(tmp);
+ continue;
+ }
- get_str("cpu", processor->model_name);
- get_str("machine", processor->vendor_id);
- get_int("L2 cache", processor->cache_size);
- get_float("clock", processor->cpu_mhz);
- get_float("bogomips", processor->bogomips);
+ if (!processor &&
+ ( CHECK_FOR("cpu")
+ || CHECK_FOR("clock")
+ || CHECK_FOR("revision") ) ) {
- }
- g_strfreev(tmp);
+ /* single proc/core may not have "processor : n" */
+ processor = g_new0(Processor, 1);
+ processor->id = 0;
+
+ if (rep_pname)
+ processor->model_name = g_strdup(rep_pname);
+ }
+
+ if (processor) {
+ get_str("cpu", processor->model_name);
+ get_str("revision", processor->revision);
+ get_float("clock", processor->cpu_mhz);
+ get_float("BogoMIPS", processor->bogomips);
+ }
+ g_strfreev(tmp);
}
-
- gchar *tmp = g_strdup_printf("PowerPC %s (%.2fMHz)",
- processor->model_name,
- processor->cpu_mhz);
- g_free(processor->model_name);
- processor->model_name = tmp;
+ if (processor)
+ procs = g_slist_append(procs, processor);
+
+ g_free(rep_pname);
fclose(cpuinfo);
- return g_slist_append(NULL, processor);
+ /* re-duplicate missing data for /proc/cpuinfo variant that de-duplicated it */
+#define REDUP(f) if (dproc->f && !processor->f) processor->f = g_strdup(dproc->f);
+ Processor *dproc;
+ GSList *l;
+ l = procs = g_slist_reverse(procs);
+ while (l) {
+ processor = l->data;
+ if (processor->model_name) {
+ dproc = processor;
+ } else if (dproc) {
+ REDUP(model_name);
+ REDUP(revision);
+ }
+ l = g_slist_next(l);
+ }
+ procs = g_slist_reverse(procs);
+
+ /* data not from /proc/cpuinfo */
+ for (pi = procs; pi; pi = pi->next) {
+ processor = (Processor *) pi->data;
+
+ /* strings can't be null or segfault later */
+ STRIFNULL(processor->model_name, _("POWER Processor") );
+ UNKIFNULL(processor->revision);
+
+ /* topo & freq */
+ processor->cpufreq = cpufreq_new(processor->id);
+ processor->cputopo = cputopo_new(processor->id);
+
+ if (processor->cpufreq->cpukhz_max)
+ processor->cpu_mhz = processor->cpufreq->cpukhz_max / 1000;
+
+ }
+
+ return procs;
+}
+
+gchar *processor_name(GSList * processors) {
+ return processor_name_default(processors);
+}
+
+gchar *processor_describe(GSList * processors) {
+ return processor_describe_default(processors);
}
gchar *
-processor_get_info(GSList *processors)
+processor_get_detailed_info(Processor *processor)
{
- Processor *processor = (Processor *)processors->data;
-
- return g_strdup_printf("[Processor]\n"
- "Machine=%s\n"
- "CPU=%s\n"
- "L2 Cache=%dkB\n"
- "Frequency=%.2fMHz\n"
- "BogoMips=%.2f\n"
- "Byte Order=%s\n",
- processor->vendor_id,
- processor->model_name,
- processor->cache_size,
- processor->cpu_mhz,
- processor->bogomips,
-#if G_BYTE_ORDER == G_LITTLE_ENDIAN
- "Little Endian"
-#else
- "Big Endian"
-#endif
- );
+ gchar *tmp_cpufreq, *tmp_topology, *ret;
+
+ tmp_topology = cputopo_section_str(processor->cputopo);
+ tmp_cpufreq = cpufreq_section_str(processor->cpufreq);
+
+ ret = g_strdup_printf("[%s]\n"
+ "%s=%s\n" /* model */
+ "%s=%s\n" /* revision */
+ "%s=%.2f %s\n" /* frequency */
+ "%s=%.2f\n" /* bogomips */
+ "%s=%s\n" /* byte order */
+ "%s" /* topology */
+ "%s" /* frequency scaling */
+ "%s",/* empty */
+ _("Processor"),
+ _("Model"), processor->model_name,
+ _("Revision"), processor->revision,
+ _("Frequency"), processor->cpu_mhz, _("MHz"),
+ _("BogoMips"), processor->bogomips,
+ _("Byte Order"), byte_order_str(),
+ tmp_topology,
+ tmp_cpufreq,
+ "");
+ g_free(tmp_cpufreq);
+ g_free(tmp_topology);
+ return ret;
+}
+
+gchar *processor_get_info(GSList * processors)
+{
+ Processor *processor;
+
+ if (g_slist_length(processors) > 1) {
+ gchar *ret, *tmp, *hashkey;
+ GSList *l;
+
+ tmp = g_strdup("");
+
+ for (l = processors; l; l = l->next) {
+ processor = (Processor *) l->data;
+
+ tmp = g_strdup_printf("%s$CPU%d$%s=%.2f %s\n",
+ tmp, processor->id,
+ processor->model_name,
+ processor->cpu_mhz, _("MHz"));
+
+ hashkey = g_strdup_printf("CPU%d", processor->id);
+ moreinfo_add_with_prefix("DEV", hashkey,
+ processor_get_detailed_info(processor));
+ g_free(hashkey);
+ }
+
+ ret = g_strdup_printf("[$ShellParam$]\n"
+ "ViewType=1\n"
+ "[Processors]\n"
+ "%s", tmp);
+ g_free(tmp);
+
+ return ret;
+ }
+
+ processor = (Processor *) processors->data;
+ return processor_get_detailed_info(processor);
}
diff --git a/modules/devices/riscv/processor.c b/modules/devices/riscv/processor.c
new file mode 100644
index 00000000..afddf89d
--- /dev/null
+++ b/modules/devices/riscv/processor.c
@@ -0,0 +1,233 @@
+/*
+ * HardInfo - Displays System Information
+ * Copyright (C) 2003-2006 Leandro A. F. Pereira <leandro@hardinfo.org>
+ *
+ * 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
+ */
+
+/* source: https://github.com/riscv/riscv-linux/blob/riscv-next/arch/riscv/kernel/cpu.c */
+
+#include "hardinfo.h"
+#include "devices.h"
+#include "cpu_util.h"
+
+#include "riscv_data.h"
+#include "riscv_data.c"
+
+GSList *
+processor_scan(void)
+{
+ GSList *procs = NULL;
+ Processor *processor = NULL;
+ FILE *cpuinfo;
+ gchar buffer[128];
+ gchar *rep_pname = NULL;
+ gchar *tmpfreq_str = NULL;
+ GSList *pi = NULL;
+
+ cpuinfo = fopen(PROC_CPUINFO, "r");
+ if (!cpuinfo)
+ return NULL;
+
+#define CHECK_FOR(k) (g_str_has_prefix(tmp[0], k))
+ while (fgets(buffer, 128, cpuinfo)) {
+ gchar **tmp = g_strsplit(buffer, ":", 2);
+ if (tmp[0] && tmp[1]) {
+ tmp[0] = g_strstrip(tmp[0]);
+ tmp[1] = g_strstrip(tmp[1]);
+ } else {
+ g_strfreev(tmp);
+ continue;
+ }
+
+ //get_str("Processor", rep_pname);
+
+ if ( CHECK_FOR("hart") ) {
+ /* finish previous */
+ if (processor) {
+ procs = g_slist_append(procs, processor);
+ }
+
+ /* start next */
+ processor = g_new0(Processor, 1);
+ processor->id = atol(tmp[1]);
+
+ if (rep_pname)
+ processor->model_name = g_strdup(rep_pname);
+
+ g_strfreev(tmp);
+ continue;
+ }
+
+ if (!processor &&
+ ( CHECK_FOR("mmu")
+ || CHECK_FOR("isa")
+ || CHECK_FOR("uarch") ) ) {
+
+ /* single proc/core may not have "hart : n" */
+ processor = g_new0(Processor, 1);
+ processor->id = 0;
+
+ if (rep_pname)
+ processor->model_name = g_strdup(rep_pname);
+ }
+
+ if (processor) {
+ get_str("mmu", processor->mmu);
+ get_str("isa", processor->isa);
+ get_str("uarch", processor->uarch);
+ }
+ g_strfreev(tmp);
+ }
+
+ if (processor)
+ procs = g_slist_append(procs, processor);
+
+ g_free(rep_pname);
+ fclose(cpuinfo);
+
+ /* TODO: redup */
+
+ /* data not from /proc/cpuinfo */
+ for (pi = procs; pi; pi = pi->next) {
+ processor = (Processor *) pi->data;
+
+ /* strings can't be null or segfault later */
+ STRIFNULL(processor->model_name, _("RISC-V Processor") );
+ UNKIFNULL(processor->mmu);
+ UNKIFNULL(processor->isa);
+ UNKIFNULL(processor->uarch);
+
+ processor->flags = riscv_isa_to_flags(processor->isa);
+
+ /* topo & freq */
+ processor->cpufreq = cpufreq_new(processor->id);
+ processor->cputopo = cputopo_new(processor->id);
+
+ if (processor->cpufreq->cpukhz_max)
+ processor->cpu_mhz = processor->cpufreq->cpukhz_max / 1000;
+ else
+ processor->cpu_mhz = 0.0f;
+ }
+
+ return procs;
+}
+
+gchar *processor_get_capabilities_from_flags(gchar * strflags)
+{
+ gchar **flags, **old;
+ gchar *tmp = NULL;
+ gint j = 0;
+
+ flags = g_strsplit(strflags, " ", 0);
+ old = flags;
+
+ while (flags[j]) {
+ const gchar *meaning = riscv_ext_meaning( flags[j] );
+
+ if (meaning) {
+ tmp = h_strdup_cprintf("%s=%s\n", tmp, flags[j], meaning);
+ } else {
+ tmp = h_strdup_cprintf("%s=\n", tmp, flags[j]);
+ }
+ j++;
+ }
+ if (tmp == NULL || g_strcmp0(tmp, "") == 0)
+ tmp = g_strdup_printf("%s=%s\n", "empty", _("Empty List"));
+
+ g_strfreev(old);
+ return tmp;
+}
+
+gchar *processor_name(GSList * processors) {
+ return processor_name_default(processors);
+}
+
+gchar *processor_describe(GSList * processors) {
+ return processor_describe_default(processors);
+}
+
+gchar *
+processor_get_detailed_info(Processor *processor)
+{
+ gchar *tmp_flags, *tmp_cpufreq, *tmp_topology, *ret;
+ tmp_flags = processor_get_capabilities_from_flags(processor->flags);
+ tmp_topology = cputopo_section_str(processor->cputopo);
+ tmp_cpufreq = cpufreq_section_str(processor->cpufreq);
+
+ ret = g_strdup_printf("[%s]\n"
+ "%s=%s\n" /* model */
+ "%s=%s\n" /* isa */
+ "%s=%s\n" /* uarch */
+ "%s=%s\n" /* mmu */
+ "%s=%.2f %s\n" /* frequency */
+ "%s=%s\n" /* byte order */
+ "%s" /* topology */
+ "%s" /* frequency scaling */
+ "[%s]\n" /* extensions */
+ "%s"
+ "%s",/* empty */
+ _("Processor"),
+ _("Model"), processor->model_name,
+ _("Architecture"), processor->isa,
+ _("uarch"), processor->uarch,
+ _("MMU"), processor->mmu,
+ _("Frequency"), processor->cpu_mhz, _("MHz"),
+ _("Byte Order"), byte_order_str(),
+ tmp_topology,
+ tmp_cpufreq,
+ _("Capabilities"), tmp_flags,
+ "");
+ g_free(tmp_flags);
+ g_free(tmp_cpufreq);
+ g_free(tmp_topology);
+ return ret;
+}
+
+gchar *processor_get_info(GSList * processors)
+{
+ Processor *processor;
+
+ if (g_slist_length(processors) > 1) {
+ gchar *ret, *tmp, *hashkey;
+ GSList *l;
+
+ tmp = g_strdup("");
+
+ for (l = processors; l; l = l->next) {
+ processor = (Processor *) l->data;
+
+ tmp = g_strdup_printf("%s$CPU%d$%s=%.2f %s\n",
+ tmp, processor->id,
+ processor->model_name,
+ processor->cpu_mhz, _("MHz"));
+
+ hashkey = g_strdup_printf("CPU%d", processor->id);
+ moreinfo_add_with_prefix("DEV", hashkey,
+ processor_get_detailed_info(processor));
+ g_free(hashkey);
+ }
+
+ ret = g_strdup_printf("[$ShellParam$]\n"
+ "ViewType=1\n"
+ "[Processors]\n"
+ "%s", tmp);
+ g_free(tmp);
+
+ return ret;
+ }
+
+ processor = (Processor *) processors->data;
+ return processor_get_detailed_info(processor);
+}
diff --git a/modules/devices/riscv/riscv_data.c b/modules/devices/riscv/riscv_data.c
new file mode 100644
index 00000000..4ae68ef4
--- /dev/null
+++ b/modules/devices/riscv/riscv_data.c
@@ -0,0 +1,212 @@
+/*
+ * rpiz - https://github.com/bp0/rpiz
+ * 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; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * 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 Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <ctype.h>
+#include "riscv_data.h"
+
+#ifndef C_
+#define C_(Ctx, String) String
+#endif
+#ifndef NC_
+#define NC_(Ctx, String) String
+#endif
+
+static struct {
+ char *name, *meaning;
+} tab_ext_meaning[] = {
+ { "RV32", NC_("rv-ext", /*/ext:RV32*/ "RISC-V 32-bit") },
+ { "RV64", NC_("rv-ext", /*/ext:RV64*/ "RISC-V 64-bit") },
+ { "RV128", NC_("rv-ext", /*/ext:RV128*/ "RISC-V 128-bit") },
+ { "E", NC_("rv-ext", /*/ext:E*/ "Base embedded integer instructions (15 registers)") },
+ { "I", NC_("rv-ext", /*/ext:I*/ "Base integer instructions (31 registers)") },
+ { "M", NC_("rv-ext", /*/ext:M*/ "Hardware integer multiply and divide") },
+ { "A", NC_("rv-ext", /*/ext:A*/ "Atomic memory operations") },
+ { "C", NC_("rv-ext", /*/ext:C*/ "Compressed 16-bit instructions") },
+ { "F", NC_("rv-ext", /*/ext:F*/ "Floating-point instructions, single-precision") },
+ { "D", NC_("rv-ext", /*/ext:D*/ "Floating-point instructions, double-precision") },
+ { "Q", NC_("rv-ext", /*/ext:Q*/ "Floating-point instructions, quad-precision") },
+ { "B", NC_("rv-ext", /*/ext:B*/ "Bit manipulation instructions") },
+ { "V", NC_("rv-ext", /*/ext:V*/ "Vector operations") },
+ { "T", NC_("rv-ext", /*/ext:T*/ "Transactional memory") },
+ { "P", NC_("rv-ext", /*/ext:P*/ "Packed SIMD instructions") },
+ { "L", NC_("rv-ext", /*/ext:L*/ "Decimal floating-point instructions") },
+ { "J", NC_("rv-ext", /*/ext:J*/ "Dynamically translated languages") },
+ { "N", NC_("rv-ext", /*/ext:N*/ "User-level interrupts") },
+ { NULL, NULL }
+};
+
+static char all_extensions[1024] = "";
+
+#define APPEND_EXT(f) strcat(all_extensions, f); strcat(all_extensions, " ");
+const char *riscv_ext_list() {
+ int i = 0, built = 0;
+ built = strlen(all_extensions);
+ if (!built) {
+ while(tab_ext_meaning[i].name != NULL) {
+ APPEND_EXT(tab_ext_meaning[i].name);
+ i++;
+ }
+ }
+ return all_extensions;
+}
+
+const char *riscv_ext_meaning(const char *ext) {
+ int i = 0, l = 0;
+ char *c = NULL;
+ if (ext) {
+ c = strchr(ext, ':'); /* allow extension:version, ignore version */
+ if (c != NULL)
+ l = c - ext;
+ else
+ l = strlen(ext);
+ while(tab_ext_meaning[i].name != NULL) {
+ if (strncasecmp(tab_ext_meaning[i].name, ext, l) == 0) {
+ if (tab_ext_meaning[i].meaning != NULL)
+ return C_("rv-ext", tab_ext_meaning[i].meaning);
+ else return NULL;
+ }
+ i++;
+ }
+ }
+ return NULL;
+}
+
+/* see RISC-V spec 2.2: Chapter 22: ISA Subset Naming Conventions */
+
+/* Spec says case-insensitve, but I prefer single-letter extensions
+ * capped and version string (like "2p1") with a lowercase p. */
+#define RV_FIX_CASE(fstr,vo) \
+ p = fstr; while (*p != 0 && *p != ':') { if (!vo) *p = toupper(*p); p++; } \
+ if (*p == ':') while (*p != 0) { if (*p == 'P') *p = 'p'; p++; }
+
+static int riscv_isa_next(const char *isap, char *flag) {
+ char *p = NULL, *start = NULL;
+ char *next_sep = NULL, *next_digit = NULL;
+ int skip_len = 0, tag_len = 0, ver_len = 0;
+ char ext_str[32], ver_str[32];
+
+ if (isap == NULL)
+ return 0;
+
+ /* find start by skipping any '_' */
+ start = (char*)isap;
+ while (*start != 0 && *start == '_') { start++; skip_len++; };
+ if (*start == 0)
+ return 0;
+
+ /* find next '_' or \0 */
+ p = start; while (*p != 0 && *p != '_') { p++; }; next_sep = p;
+
+ /* find next digit that may be a version, find length of version */
+ p = start; while (*p != 0 && !isdigit(*p)) { p++; };
+ if (isdigit(*p)) next_digit = p;
+ if (next_digit) {
+ while (*p != 0 && (isdigit(*p) || *p == 'p' || *p == 'P') ) {
+ if ((*p == 'p' || *p == 'P') && !isdigit(*(p+1)) )
+ break;
+ ver_len++;
+ p++;
+ }
+ }
+
+ /* is next version nearer than next separator */
+ p = start;
+ if (next_digit && next_digit < next_sep)
+ tag_len = next_digit - p;
+ else {
+ tag_len = next_sep - p;
+ ver_len = 0;
+ }
+
+ switch(*p) {
+ case 'S': case 's': /* supervisor extension */
+ case 'X': case 'x': /* custom extension */
+ /* custom supervisor extension (SX..) handled by S */
+ break;
+ default: /* single character (standard) extension */
+ tag_len = 1;
+ if (next_digit != p+1) ver_len = 0;
+ break;
+ }
+
+ memset(ext_str, 0, 32);
+ memset(ver_str, 0, 32);
+ if (ver_len) {
+ strncpy(ext_str, p, tag_len);
+ strncpy(ver_str, next_digit, ver_len);
+ sprintf(flag, "%s:%s", ext_str, ver_str);
+ if (tag_len == 1) {
+ RV_FIX_CASE(flag, 0);
+ } else {
+ RV_FIX_CASE(flag, 1);
+ }
+ return skip_len + tag_len + ver_len;
+ } else {
+ strncpy(ext_str, p, tag_len);
+ sprintf(flag, "%s", ext_str);
+ if (tag_len == 1) { RV_FIX_CASE(flag, 0); }
+ return skip_len + tag_len;
+ }
+}
+
+#define FSTR_SIZE 1024
+#define RV_CHECK_FOR(e) ( strncasecmp(ps, e, 2) == 0 )
+#define ADD_EXT_FLAG(ext) el = strlen(ext); strncpy(pd, ext, el); strncpy(pd + el, " ", 1); pd += el + 1;
+char *riscv_isa_to_flags(const char *isa) {
+ char *flags = NULL, *ps = (char*)isa, *pd = NULL;
+ char flag_buf[64] = "";
+ int isa_len = 0, tl = 0, el = 0; /* el used in macro */
+
+ if (isa) {
+ isa_len = strlen(isa);
+ flags = malloc(FSTR_SIZE);
+ if (flags) {
+ memset(flags, 0, FSTR_SIZE);
+ ps = (char*)isa;
+ pd = flags;
+ if ( RV_CHECK_FOR("RV") )
+ { ps += 2; }
+ if ( RV_CHECK_FOR("32") )
+ { ADD_EXT_FLAG("RV32"); ps += 2; }
+ else if ( RV_CHECK_FOR("64") )
+ { ADD_EXT_FLAG("RV64"); ps += 2; }
+ else if ( RV_CHECK_FOR("128") )
+ { ADD_EXT_FLAG("RV128"); ps += 3; }
+
+ while( (tl = riscv_isa_next(ps, flag_buf)) ) {
+ if (flag_buf[0] == 'G') { /* G = IMAFD */
+ flag_buf[0] = 'I'; ADD_EXT_FLAG(flag_buf);
+ flag_buf[0] = 'M'; ADD_EXT_FLAG(flag_buf);
+ flag_buf[0] = 'A'; ADD_EXT_FLAG(flag_buf);
+ flag_buf[0] = 'F'; ADD_EXT_FLAG(flag_buf);
+ flag_buf[0] = 'D'; ADD_EXT_FLAG(flag_buf);
+ } else {
+ ADD_EXT_FLAG(flag_buf);
+ }
+ ps += tl;
+ if (ps - isa >= isa_len) break; /* just in case */
+ }
+ }
+ }
+ return flags;
+}
diff --git a/modules/devices/riscv/riscv_data.h b/modules/devices/riscv/riscv_data.h
new file mode 100644
index 00000000..1d3a0a48
--- /dev/null
+++ b/modules/devices/riscv/riscv_data.h
@@ -0,0 +1,33 @@
+/*
+ * rpiz - https://github.com/bp0/rpiz
+ * 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; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * 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 Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef _RISCVDATA_H_
+#define _RISCVDATA_H_
+
+/* convert RISC-V ISA string to flags list */
+char *riscv_isa_to_flags(const char *isa);
+
+/* all known extensions as flags list */
+const char *riscv_ext_list(void);
+
+/* get meaning of flag */
+const char *riscv_ext_meaning(const char *ext);
+
+#endif
diff --git a/modules/devices/s390/processor.c b/modules/devices/s390/processor.c
index 99f1c8bd..cf45c33c 100644
--- a/modules/devices/s390/processor.c
+++ b/modules/devices/s390/processor.c
@@ -18,61 +18,163 @@
#include "hardinfo.h"
#include "devices.h"
+#include "string.h"
+#include "cpu_util.h"
GSList *
processor_scan(void)
{
- Processor *processor;
+ GSList *procs = NULL;
+ Processor *processor = NULL;
FILE *cpuinfo;
gchar buffer[128];
+ gchar *vendor_id = NULL;
+ gint num_procs = 0;
+ gfloat bogomips = 0.0f;
+ GSList *pi = NULL;
- cpuinfo = fopen("/proc/cpuinfo", "r");
+ cpuinfo = fopen(PROC_CPUINFO, "r");
if (!cpuinfo)
- return NULL;
+ return NULL;
- processor = g_new0(Processor, 1);
+#define CHECK_FOR(k) (g_str_has_prefix(tmp[0], k))
while (fgets(buffer, 128, cpuinfo)) {
- gchar **tmp = g_strsplit(buffer, ":", 2);
+ gchar **tmp = g_strsplit(buffer, ":", 2);
+ if (tmp[0] && tmp[1]) {
+ tmp[0] = g_strstrip(tmp[0]);
+ tmp[1] = g_strstrip(tmp[1]);
+ } else {
+ g_strfreev(tmp);
+ continue;
+ }
+
+ get_str("vendor_id", vendor_id);
+ get_int("# processors", num_procs);
+ get_int("bogomips per cpu", bogomips);
+
+ if ( CHECK_FOR("processor") ) {
+ /* finish previous */
+ if (processor) {
+ procs = g_slist_append(procs, processor);
+ }
+
+ /* start next */
+ processor = g_new0(Processor, 1);
+ if (strlen(tmp[0]) >= 10)
+ processor->id = atol(tmp[0] + 10); /* processor n: ... */
+ else
+ processor->id = 0; /* idk */
+ processor->proc_str = g_strdup(tmp[1]);
- if (tmp[0] && tmp[1]) {
- tmp[0] = g_strstrip(tmp[0]);
- tmp[1] = g_strstrip(tmp[1]);
+ if (vendor_id)
+ processor->model_name = g_strdup(vendor_id);
+ if (bogomips)
+ processor->bogomips = bogomips;
- get_str("vendor_id", processor->vendor_id);
- get_float("# processors", processor->cache_size);
- get_int("bogomips per cpu", processor->bogomips);
+ g_strfreev(tmp);
+ continue;
+ }
- }
- g_strfreev(tmp);
+ g_strfreev(tmp);
}
- processor->cpu_mhz = 0.0f;
-
- processor->model_name = g_strconcat("S390 ", processor->vendor_id, NULL);
- g_free(processor->vendor_id);
+ if (processor)
+ procs = g_slist_append(procs, processor);
+ g_free(vendor_id);
fclose(cpuinfo);
- return g_slist_append(NULL, processor);
+ /* data not from /proc/cpuinfo */
+ for (pi = procs; pi; pi = pi->next) {
+ processor = (Processor *) pi->data;
+
+ /* strings can't be null or segfault later */
+ STRIFNULL(processor->model_name, _("S390 Processor") );
+ UNKIFNULL(processor->proc_str);
+
+ /* topo & freq */
+ processor->cpufreq = cpufreq_new(processor->id);
+ processor->cputopo = cputopo_new(processor->id);
+
+ if (processor->cpufreq->cpukhz_max)
+ processor->cpu_mhz = processor->cpufreq->cpukhz_max / 1000;
+ else
+ processor->cpu_mhz = 0.0f;
+
+ }
+
+ return procs;
+}
+
+gchar *processor_name(GSList * processors) {
+ return processor_name_default(processors);
+}
+
+gchar *processor_describe(GSList * processors) {
+ return processor_describe_default(processors);
}
gchar *
-processor_get_info(GSList *processors)
+processor_get_detailed_info(Processor *processor)
+{
+ gchar *tmp_cpufreq, *tmp_topology, *ret;
+ tmp_topology = cputopo_section_str(processor->cputopo);
+ tmp_cpufreq = cpufreq_section_str(processor->cpufreq);
+
+ ret = g_strdup_printf("[%s]\n"
+ "%s=%s\n" /* model */
+ "%s=%s\n" /* proc string */
+ "%s=%.2f\n" /* bogomips */
+ "%s=%s\n" /* byte order */
+ "%s" /* topology */
+ "%s", /* frequency scaling */
+ _("Processor"),
+ _("Model"), processor->model_name,
+ _("ID String"), processor->proc_str,
+ _("BogoMips"), processor->bogomips,
+ _("Byte Order"), byte_order_str(),
+ tmp_topology,
+ tmp_cpufreq
+ );
+ g_free(tmp_cpufreq);
+ g_free(tmp_topology);
+ return ret;
+}
+
+gchar *processor_get_info(GSList * processors)
{
- Processor *processor = (Processor *)processors->data;
-
- return g_strdup_printf("[Processor]\n"
- "Model=%s\n"
- "Processors=%d\n"
- "BogoMips per CPU=%.2f"
- "Byte Order=%s\n",
- processor->model_name,
- processor->cache_size,
- processor->bogomips,
-#if G_BYTE_ORDER == G_LITTLE_ENDIAN
- "Little Endian"
-#else
- "Big Endian"
-#endif
- );
+ Processor *processor;
+
+ if (g_slist_length(processors) > 1) {
+ gchar *ret, *tmp, *hashkey;
+ GSList *l;
+
+ tmp = g_strdup("");
+
+ for (l = processors; l; l = l->next) {
+ processor = (Processor *) l->data;
+
+ tmp = g_strdup_printf("%s$CPU%d$%s=%.2f %s\n",
+ tmp, processor->id,
+ processor->model_name,
+ processor->cpu_mhz, _("MHz"));
+
+ hashkey = g_strdup_printf("CPU%d", processor->id);
+ moreinfo_add_with_prefix("DEV", hashkey,
+ processor_get_detailed_info(processor));
+ g_free(hashkey);
+ }
+
+ ret = g_strdup_printf("[$ShellParam$]\n"
+ "ViewType=1\n"
+ "[Processors]\n"
+ "%s", tmp);
+ g_free(tmp);
+
+ return ret;
+ }
+
+ processor = (Processor *) processors->data;
+ return processor_get_detailed_info(processor);
}
+
diff --git a/modules/devices/sensors.c b/modules/devices/sensors.c
index 84e89361..c9d78ff7 100644
--- a/modules/devices/sensors.c
+++ b/modules/devices/sensors.c
@@ -27,8 +27,7 @@ gchar *sensors = NULL;
GHashTable *sensor_compute = NULL;
GHashTable *sensor_labels = NULL;
-static void read_sensor_labels(gchar * driver)
-{
+static void read_sensor_labels(gchar *driver) {
FILE *conf;
gchar buf[256], *line, *p;
gboolean lock = FALSE;
@@ -38,7 +37,8 @@ static void read_sensor_labels(gchar * driver)
conf = fopen("/etc/sensors3.conf", "r");
/* If it fails, try to open sensors.conf */
- if (!conf) conf = fopen("/etc/sensors.conf", "r");
+ if (!conf)
+ conf = fopen("/etc/sensors.conf", "r");
if (!conf) {
/* Cannot open config file. */
@@ -46,117 +46,129 @@ static void read_sensor_labels(gchar * driver)
}
while (fgets(buf, 256, conf)) {
- line = buf;
-
- remove_linefeed(line);
- strend(line, '#');
-
- if (*line == '\0') {
- continue;
- } else if (lock && strstr(line, "label")) { /* label lines */
- gchar **names = g_strsplit(strstr(line, "label") + 5, " ", 0);
- gchar *name = NULL, *value = NULL;
-
- for (i = 0; names[i]; i++) {
- if (names[i][0] == '\0')
- continue;
-
- if (!name)
- name = g_strdup(names[i]);
- else if (!value)
- value = g_strdup(names[i]);
- else
- value = g_strconcat(value, " ", names[i], NULL);
- }
-
- remove_quotes(value);
- g_hash_table_insert(sensor_labels, name, value);
-
- g_strfreev(names);
- } else if (lock && strstr(line, "ignore")) { /* ignore lines */
- p = strstr(line, "ignore") + 6;
- if (!strchr(p, ' '))
- continue;
-
- while (*p == ' ')
- p++;
- g_hash_table_insert(sensor_labels, g_strdup(p), "ignore");
- } else if (lock && strstr(line, "compute")) { /* compute lines */
- gchar **formulas =
- g_strsplit(strstr(line, "compute") + 7, " ", 0);
- gchar *name = NULL, *formula = NULL;
-
- for (i = 0; formulas[i]; i++) {
- if (formulas[i][0] == '\0')
- continue;
- if (formulas[i][0] == ',')
- break;
-
- if (!name)
- name = g_strdup(formulas[i]);
- else if (!formula)
- formula = g_strdup(formulas[i]);
- else
- formula = g_strconcat(formula, formulas[i], NULL);
- }
-
- g_strfreev(formulas);
- g_hash_table_insert(sensor_compute, name,
- math_string_to_postfix(formula));
- } else if (g_str_has_prefix(line, "chip")) { /* chip lines (delimiter) */
- if (lock == FALSE) {
- gchar **chips = g_strsplit(line, " ", 0);
-
- for (i = 1; chips[i]; i++) {
- strend(chips[i], '*');
-
- if (g_str_has_prefix(chips[i] + 1, driver)) {
- lock = TRUE;
- break;
- }
- }
-
- g_strfreev(chips);
- } else {
- break;
- }
- }
+ line = buf;
+
+ remove_linefeed(line);
+ strend(line, '#');
+
+ if (*line == '\0') {
+ continue;
+ } else if (lock && strstr(line, "label")) { /* label lines */
+ gchar **names = g_strsplit(strstr(line, "label") + 5, " ", 0);
+ gchar *name = NULL, *value = NULL;
+
+ for (i = 0; names[i]; i++) {
+ if (names[i][0] == '\0')
+ continue;
+
+ if (!name)
+ name = g_strdup(names[i]);
+ else if (!value)
+ value = g_strdup(names[i]);
+ else
+ value = g_strconcat(value, " ", names[i], NULL);
+ }
+
+ remove_quotes(value);
+ g_hash_table_insert(sensor_labels, name, value);
+
+ g_strfreev(names);
+ } else if (lock && strstr(line, "ignore")) { /* ignore lines */
+ p = strstr(line, "ignore") + 6;
+ if (!strchr(p, ' '))
+ continue;
+
+ while (*p == ' ')
+ p++;
+ g_hash_table_insert(sensor_labels, g_strdup(p), "ignore");
+ } else if (lock && strstr(line, "compute")) { /* compute lines */
+ gchar **formulas = g_strsplit(strstr(line, "compute") + 7, " ", 0);
+ gchar *name = NULL, *formula = NULL;
+
+ for (i = 0; formulas[i]; i++) {
+ if (formulas[i][0] == '\0')
+ continue;
+ if (formulas[i][0] == ',')
+ break;
+
+ if (!name)
+ name = g_strdup(formulas[i]);
+ else if (!formula)
+ formula = g_strdup(formulas[i]);
+ else
+ formula = g_strconcat(formula, formulas[i], NULL);
+ }
+
+ g_strfreev(formulas);
+ g_hash_table_insert(sensor_compute, name,
+ math_string_to_postfix(formula));
+ } else if (g_str_has_prefix(line,
+ "chip")) { /* chip lines (delimiter) */
+ if (lock == FALSE) {
+ gchar **chips = g_strsplit(line, " ", 0);
+
+ for (i = 1; chips[i]; i++) {
+ strend(chips[i], '*');
+
+ if (g_str_has_prefix(chips[i] + 1, driver)) {
+ lock = TRUE;
+ break;
+ }
+ }
+
+ g_strfreev(chips);
+ } else {
+ break;
+ }
+ }
}
fclose(conf);
}
-static gchar *get_sensor_label(gchar * sensor)
-{
+static void add_sensor(const char *type,
+ const char *sensor,
+ const char *driver,
+ double value,
+ const char *unit) {
+ char key[64];
+
+ sensors = h_strdup_cprintf("%s/%s=%.2f%s|%s\n", sensors,
+ driver, sensor, value, unit, type);
+
+ snprintf(key, sizeof(key), "%s/%s", driver, sensor);
+ moreinfo_add_with_prefix("DEV", key, g_strdup_printf("%.2f%s", value, unit));
+
+ lginterval = h_strdup_cprintf("UpdateInterval$%s=1000\n", lginterval, key);
+}
+
+static gchar *get_sensor_label(gchar *sensor) {
gchar *ret;
ret = g_hash_table_lookup(sensor_labels, sensor);
if (!ret)
- ret = g_strdup(sensor);
+ ret = g_strdup(sensor);
else
- ret = g_strdup(ret);
+ ret = g_strdup(ret);
return ret;
}
-static float adjust_sensor(gchar * name, float value)
-{
+static float adjust_sensor(gchar *name, float value) {
GSList *postfix;
postfix = g_hash_table_lookup(sensor_compute, name);
if (!postfix)
- return value;
+ return value;
return math_postfix_eval(postfix, value);
}
-static char *get_sensor_path(int number, const char *prefix)
-{
+static char *get_sensor_path(int number, const char *prefix) {
return g_strdup_printf("/sys/class/hwmon/hwmon%d/%s", number, prefix);
}
-static char *determine_driver_for_hwmon_path(char *path)
-{
+static char *determine_driver_for_hwmon_path(char *path) {
char *tmp, *driver;
tmp = g_strdup_printf("%s/device/driver", path);
@@ -190,165 +202,171 @@ struct HwmonSensor {
const char *friendly_name;
const char *path_format;
const char *key_format;
- const char *value_format;
+ const char *unit;
const float adjust_ratio;
const int begin_at;
};
static const struct HwmonSensor hwmon_sensors[] = {
- { "Cooling Fans", "%s/fan%d_input", "fan%d", "%s (%s)=%.0fRPM\n", 1.0, 1 },
- { "Temperature", "%s/temp%d_input", "temp%d", "%s (%s)=%.2f\302\260C\n", 1000.0, 1 },
- { "Voltage Values", "%s/in%d_input", "in%d", "%s (%s)=%.3fV\n", 1000.0, 0 },
- { NULL, NULL, NULL, NULL, 0.0, 0 },
+ {
+ "Fan",
+ "%s/fan%d_input",
+ "fan%d",
+ "RPM",
+ 1.0,
+ 1
+ },
+ {
+ "Temperature",
+ "%s/temp%d_input",
+ "temp%d",
+ "\302\260C",
+ 1000.0,
+ 1
+ },
+ {
+ "Voltage",
+ "%s/in%d_input",
+ "in%d",
+ "V",
+ 1000.0,
+ 0
+ },
+ { }
};
-static const char *hwmon_prefix[] = { "device", "", NULL };
+static const char *hwmon_prefix[] = {"device", "", NULL};
-static void read_sensors_hwmon(void)
-{
+static void read_sensors_hwmon(void) {
int hwmon, count;
gchar *path_hwmon, *path_sensor, *tmp, *driver, *name, *mon;
const char **prefix;
-
+
for (prefix = hwmon_prefix; *prefix; prefix++) {
- hwmon = 0;
- path_hwmon = get_sensor_path(hwmon, *prefix);
- while (path_hwmon && g_file_test(path_hwmon, G_FILE_TEST_EXISTS)) {
- const struct HwmonSensor *sensor;
-
- driver = determine_driver_for_hwmon_path(path_hwmon);
- DEBUG("hwmon%d has driver=%s", hwmon, driver);
-
- if (!sensor_labels) {
- read_sensor_labels(driver);
- }
-
- for (sensor = hwmon_sensors; sensor->friendly_name; sensor++) {
- char *output = NULL;
- DEBUG("current sensor type=%s", sensor->friendly_name);
-
- for (count = sensor->begin_at;; count++) {
- path_sensor = g_strdup_printf(sensor->path_format, path_hwmon, count);
- DEBUG("should be reading from %s", path_sensor);
- if (!g_file_get_contents(path_sensor, &tmp, NULL, NULL)) {
- g_free(path_sensor);
- if (count<256)
- continue; // brute-force find all
- else
- break;
- }
-
- mon = g_strdup_printf(sensor->key_format, count);
- name = get_sensor_label(mon);
- if (!g_str_equal(name, "ignore")) {
- output = h_strdup_cprintf(sensor->value_format,
- output, name, driver,
- adjust_sensor(mon,
- atof(tmp) / sensor->adjust_ratio));
- }
-
- g_free(tmp);
- g_free(mon);
- g_free(name);
- g_free(path_sensor);
- }
-
- if (output) {
- sensors = g_strconcat(sensors, "[", sensor->friendly_name, "]\n", output, "\n", NULL);
- g_free(output);
- }
- }
-
- g_free(path_hwmon);
- g_free(driver);
-
- path_hwmon = get_sensor_path(++hwmon, *prefix);
- }
-
- g_free(path_hwmon);
- }
+ hwmon = 0;
+ path_hwmon = get_sensor_path(hwmon, *prefix);
+ while (path_hwmon && g_file_test(path_hwmon, G_FILE_TEST_EXISTS)) {
+ const struct HwmonSensor *sensor;
+
+ driver = determine_driver_for_hwmon_path(path_hwmon);
+ DEBUG("hwmon%d has driver=%s", hwmon, driver);
+
+ if (!sensor_labels) {
+ read_sensor_labels(driver);
+ }
+
+ for (sensor = hwmon_sensors; sensor->friendly_name; sensor++) {
+ DEBUG("current sensor type=%s", sensor->friendly_name);
+
+ for (count = sensor->begin_at;; count++) {
+ path_sensor =
+ g_strdup_printf(sensor->path_format, path_hwmon, count);
+ DEBUG("should be reading from %s", path_sensor);
+ if (!g_file_get_contents(path_sensor, &tmp, NULL, NULL)) {
+ g_free(path_sensor);
+ if (count < 256)
+ continue; // brute-force find all
+ else
+ break;
+ }
+
+ mon = g_strdup_printf(sensor->key_format, count);
+ name = get_sensor_label(mon);
+ if (!g_str_equal(name, "ignore")) {
+ float adjusted = adjust_sensor(mon,
+ atof(tmp) / sensor->adjust_ratio);
+
+ add_sensor(sensor->friendly_name,
+ name,
+ driver,
+ adjusted,
+ sensor->unit);
+ }
+
+ g_free(tmp);
+ g_free(mon);
+ g_free(name);
+ g_free(path_sensor);
+ }
+ }
+
+ g_free(path_hwmon);
+ g_free(driver);
+
+ path_hwmon = get_sensor_path(++hwmon, *prefix);
+ }
+
+ g_free(path_hwmon);
+ }
}
-static void read_sensors_acpi(void)
-{
+static void read_sensors_acpi(void) {
const gchar *path_tz = "/proc/acpi/thermal_zone";
if (g_file_test(path_tz, G_FILE_TEST_EXISTS)) {
- GDir *tz;
-
- if ((tz = g_dir_open(path_tz, 0, NULL))) {
- const gchar *entry;
- gchar *temp = g_strdup("");
-
- while ((entry = g_dir_read_name(tz))) {
- gchar *path =
- g_strdup_printf("%s/%s/temperature", path_tz, entry);
- gchar *contents;
+ GDir *tz;
- if (g_file_get_contents(path, &contents, NULL, NULL)) {
- int temperature;
+ if ((tz = g_dir_open(path_tz, 0, NULL))) {
+ const gchar *entry;
- sscanf(contents, "temperature: %d C", &temperature);
+ while ((entry = g_dir_read_name(tz))) {
+ gchar *path =
+ g_strdup_printf("%s/%s/temperature", path_tz, entry);
+ gchar *contents;
- temp = h_strdup_cprintf("\n%s=%d\302\260C\n",
- temp, entry, temperature);
+ if (g_file_get_contents(path, &contents, NULL, NULL)) {
+ int temperature;
- g_free(contents);
- }
- }
+ sscanf(contents, "temperature: %d C", &temperature);
- if (*temp != '\0')
- sensors =
- h_strdup_cprintf("\n[ACPI Thermal Zone]\n%s",
- sensors, temp);
+ add_sensor("Temperature",
+ entry,
+ "ACPI Thermal Zone",
+ temperature,
+ "\302\260C");
+ }
+ }
- g_dir_close(tz);
- }
+ g_dir_close(tz);
+ }
}
-
}
-static void read_sensors_sys_thermal(void)
-{
+static void read_sensors_sys_thermal(void) {
const gchar *path_tz = "/sys/class/thermal";
if (g_file_test(path_tz, G_FILE_TEST_EXISTS)) {
- GDir *tz;
-
- if ((tz = g_dir_open(path_tz, 0, NULL))) {
- const gchar *entry;
- gchar *temp = g_strdup("");
+ GDir *tz;
- while ((entry = g_dir_read_name(tz))) {
- gchar *path =
- g_strdup_printf("%s/%s/temp", path_tz, entry);
- gchar *contents;
+ if ((tz = g_dir_open(path_tz, 0, NULL))) {
+ const gchar *entry;
+ gchar *temp = g_strdup("");
- if (g_file_get_contents(path, &contents, NULL, NULL)) {
- int temperature;
+ while ((entry = g_dir_read_name(tz))) {
+ gchar *path = g_strdup_printf("%s/%s/temp", path_tz, entry);
+ gchar *contents;
- sscanf(contents, "%d", &temperature);
+ if (g_file_get_contents(path, &contents, NULL, NULL)) {
+ int temperature;
- temp = h_strdup_cprintf("\n%s=%.2f\302\260C\n",
- temp, entry, (1.0*temperature/1000));
+ sscanf(contents, "%d", &temperature);
- g_free(contents);
- }
- }
+ add_sensor("Temperature",
+ entry,
+ "thermal",
+ temperature / 1000.0,
+ "\302\260C");
- if (*temp != '\0')
- sensors =
- h_strdup_cprintf("\n[ACPI Thermal Zone (sysfs)]\n%s",
- sensors, temp);
+ g_free(contents);
+ }
+ }
- g_dir_close(tz);
- }
+ g_dir_close(tz);
+ }
}
-
}
-static void read_sensors_omnibook(void)
-{
+static void read_sensors_omnibook(void) {
const gchar *path_ob = "/proc/omnibook/temperature";
gchar *contents;
@@ -357,88 +375,79 @@ static void read_sensors_omnibook(void)
sscanf(contents, "CPU temperature: %d C", &temperature);
- sensors = h_strdup_cprintf("\n[Omnibook]\n"
- "CPU temperature=%d\302\260C\n",
- sensors, temperature);
+ add_sensor("Temperature",
+ "CPU",
+ "omnibook",
+ temperature,
+ "\302\260C\n");
g_free(contents);
}
}
-static void read_sensors_hddtemp(void)
-{
+static void read_sensors_hddtemp(void) {
Socket *s;
- static gchar *old = NULL;
gchar buffer[1024];
gint len = 0;
- if ((s = sock_connect("127.0.0.1", 7634))) {
- while (!len)
- len = sock_read(s, buffer, sizeof(buffer));
- sock_close(s);
-
- if (len > 2 && buffer[0] == '|' && buffer[1] == '/') {
- gchar **disks;
- int i;
-
- g_free(old);
-
- old = g_strdup("[Hard Disk Temperature]\n");
-
- disks = g_strsplit(buffer, "\n", 0);
- for (i = 0; disks[i]; i++) {
- gchar **fields = g_strsplit(disks[i] + 1, "|", 5);
-
- /*
- * 0 -> /dev/hda
- * 1 -> FUJITSU MHV2080AH
- * 2 -> 41
- * 3 -> C
- */
- old = h_strdup_cprintf("\n%s (%s)=%s\302\260%s\n",
- old,
- fields[1], fields[0],
- fields[2], fields[3]);
-
- g_strfreev(fields);
- }
+ if (!(s = sock_connect("127.0.0.1", 7634)))
+ return;
- g_strfreev(disks);
- }
- } else {
- g_free(old);
- old = NULL;
- }
+ while (!len)
+ len = sock_read(s, buffer, sizeof(buffer));
+ sock_close(s);
+
+ if (len > 2 && buffer[0] == '|' && buffer[1] == '/') {
+ gchar **disks;
+ int i;
+
+ disks = g_strsplit(buffer, "\n", 0);
+ for (i = 0; disks[i]; i++) {
+ gchar **fields = g_strsplit(disks[i] + 1, "|", 5);
+
+ /*
+ * 0 -> /dev/hda
+ * 1 -> FUJITSU MHV2080AH
+ * 2 -> 41
+ * 3 -> C
+ */
+ const gchar *unit = strcmp(fields[3], "C")
+ ? "\302\260C" : "\302\260F";
+ add_sensor("Hard Drive",
+ fields[1],
+ "hddtemp",
+ atoi(fields[2]),
+ unit);
+
+ g_strfreev(fields);
+ }
- if (old) {
- sensors = g_strconcat(sensors, "\n", old, NULL);
+ g_strfreev(disks);
}
}
-void scan_sensors_do(void)
-{
+void scan_sensors_do(void) {
g_free(sensors);
-
sensors = g_strdup("");
+ g_free(lginterval);
+ lginterval = g_strdup("");
+
read_sensors_hwmon();
read_sensors_acpi();
read_sensors_sys_thermal();
read_sensors_omnibook();
read_sensors_hddtemp();
-
/* FIXME: Add support for ibm acpi and more sensors */
}
-void sensors_init(void)
-{
- sensor_labels = g_hash_table_new_full(g_str_hash, g_str_equal,
- g_free, g_free);
+void sensors_init(void) {
+ sensor_labels =
+ g_hash_table_new_full(g_str_hash, g_str_equal, g_free, g_free);
sensor_compute = g_hash_table_new(g_str_hash, g_str_equal);
}
-void sensors_shutdown(void)
-{
+void sensors_shutdown(void) {
g_hash_table_destroy(sensor_labels);
g_hash_table_destroy(sensor_compute);
}
diff --git a/modules/devices/sh/processor.c b/modules/devices/sh/processor.c
index cbd9a60a..9da2f9b0 100644
--- a/modules/devices/sh/processor.c
+++ b/modules/devices/sh/processor.c
@@ -18,6 +18,7 @@
#include "hardinfo.h"
#include "devices.h"
+#include "cpu_util.h"
GSList *
processor_scan(void)
@@ -26,50 +27,67 @@ processor_scan(void)
FILE *cpuinfo;
gchar buffer[128];
- cpuinfo = fopen("/proc/cpuinfo", "r");
+ cpuinfo = fopen(PROC_CPUINFO, "r");
if (!cpuinfo)
- return NULL;
+ return NULL;
processor = g_new0(Processor, 1);
while (fgets(buffer, 128, cpuinfo)) {
- gchar **tmp = g_strsplit(buffer, ":", 2);
+ gchar **tmp = g_strsplit(buffer, ":", 2);
- if (tmp[0] && tmp[1]) {
- tmp[0] = g_strstrip(tmp[0]);
- tmp[1] = g_strstrip(tmp[1]);
+ if (tmp[0] && tmp[1]) {
+ tmp[0] = g_strstrip(tmp[0]);
+ tmp[1] = g_strstrip(tmp[1]);
- get_str("machine", processor->model_name);
- get_str("cpu type", processor->vendor_id);
- get_float("bogomips", processor->bogomips);
- processor->cpu_mhz = processor->bogomips;
- }
- g_strfreev(tmp);
+ get_str("machine", processor->vendor_id);
+ get_str("cpu type", processor->model_name);
+ get_str("cpu family", processor->family);
+ get_float("cpu clock", processor->cpu_mhz);
+ get_float("bus clock", processor->bus_mhz);
+ get_float("module clock", processor->mod_mhz);
+ get_float("bogomips", processor->bogomips);
+ }
+ g_strfreev(tmp);
}
fclose(cpuinfo);
+ STRIFNULL(processor->model_name, _("SuperH Processor"));
+ UNKIFNULL(processor->vendor_id);
+
return g_slist_append(NULL, processor);
}
+gchar *processor_name(GSList * processors) {
+ return processor_name_default(processors);
+}
+
+gchar *processor_describe(GSList * processors) {
+ return processor_describe_default(processors);
+}
+
gchar *
processor_get_info(GSList *processors)
{
- Processor *processor = (Processor *)processors->data;
-
- return g_strdup_printf("[Processor]\n"
- "System Type=%s\n"
- "CPU Model=%s\n"
- "Frequency=%.2fMHz\n"
- "BogoMIPS=%.2f\n"
- "Byte Order=%s\n",
- processor->model_name,
- processor->vendor_id,
- processor->cpu_mhz,
- processor->bogomips,
-#if G_BYTE_ORDER == G_LITTLE_ENDIAN
- "Little Endian"
-#else
- "Big Endian"
-#endif
- );
+ Processor *processor = (Processor *)processors->data;
+
+ return g_strdup_printf("[%s]\n"
+ "%s=%s\n" /* cpu type */
+ "%s=%s\n" /* machine */
+ "%s=%s\n" /* family */
+ "%s=%.2f %s\n" /* frequency */
+ "%s=%.2f %s\n" /* bus frequency */
+ "%s=%.2f %s\n" /* module frequency */
+ "%s=%.2f\n" /* bogomips */
+ "%s=%s\n", /* byte order */
+ _("Processor"),
+ _("Name"), processor->model_name,
+ _("Machine"), processor->vendor_id,
+ _("Family"), processor->family,
+ _("Frequency"), processor->cpu_mhz, _("MHz"),
+ _("Bus Frequency"), processor->bus_mhz, _("MHz"),
+ _("Module Frequency"), processor->mod_mhz, _("MHz"),
+ _("BogoMips"), processor->bogomips,
+ _("Byte Order"), byte_order_str()
+ );
}
diff --git a/modules/devices/sparc/processor.c b/modules/devices/sparc/processor.c
index 594117a7..32c7aa94 100644
--- a/modules/devices/sparc/processor.c
+++ b/modules/devices/sparc/processor.c
@@ -18,6 +18,7 @@
#include "hardinfo.h"
#include "devices.h"
+#include "cpu_util.h"
GSList *
processor_scan(void)
@@ -26,22 +27,23 @@ processor_scan(void)
FILE *cpuinfo;
gchar buffer[128];
- cpuinfo = fopen("/proc/cpuinfo", "r");
+ cpuinfo = fopen(PROC_CPUINFO, "r");
if (!cpuinfo)
- return NULL;
+ return NULL;
processor = g_new0(Processor, 1);
while (fgets(buffer, 128, cpuinfo)) {
- gchar **tmp = g_strsplit(buffer, ":", 2);
+ gchar **tmp = g_strsplit(buffer, ":", 2);
- if (tmp[0] && tmp[1]) {
- tmp[0] = g_strstrip(tmp[0]);
- tmp[1] = g_strstrip(tmp[1]);
+ if (tmp[0] && tmp[1]) {
+ tmp[0] = g_strstrip(tmp[0]);
+ tmp[1] = g_strstrip(tmp[1]);
- get_str("cpu", processor->model_name);
- get_str("fpu", processor->has_fpu);
- }
- g_strfreev(tmp);
+ get_str("cpucaps", processor->cpucaps);
+ get_str("cpu", processor->model_name);
+ get_str("fpu", processor->has_fpu);
+ }
+ g_strfreev(tmp);
}
fclose(cpuinfo);
@@ -51,14 +53,28 @@ processor_scan(void)
return g_slist_append(NULL, processor);
}
+gchar *processor_name(GSList * processors) {
+ return processor_name_default(processors);
+}
+
+gchar *processor_describe(GSList * processors) {
+ return processor_describe_default(processors);
+}
+
gchar *
processor_get_info(GSList *processors)
{
- Processor *processor = (Processor *)processors->data;
-
- return g_strdup_printf("[Processor]\n"
- "CPU=%s\n"
- "FPU=%s\n",
- processor->model_name,
- processor->has_fpu);
+ Processor *processor = (Processor *)processors->data;
+
+ return g_strdup_printf("[%s]\n"
+ "%s=%s\n" /* cpu */
+ "%s=%s\n" /* fpu */
+ "%s=%s\n" /* byte order */
+ "%s=%s\n", /* caps */
+ _("Processor"),
+ _("CPU"), processor->model_name,
+ _("FPU"), processor->has_fpu,
+ _("Byte Order"), byte_order_str(),
+ _("Capabilities"), processor->cpucaps
+ );
}
diff --git a/modules/devices/spd-decode.c b/modules/devices/spd-decode.c
index ac1dd52b..2db4895b 100644
--- a/modules/devices/spd-decode.c
+++ b/modules/devices/spd-decode.c
@@ -11,12 +11,12 @@
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
- *
+ *
* 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., 675 Mass Ave, Cambridge, MA 02139, USA.
@@ -1497,13 +1497,16 @@ void scan_spd_do(void)
g_slist_free(dimm_list);
g_free(spd_info);
- spd_info = g_strdup_printf("[SPD]\n"
- "%s\n"
- "[$ShellParam$]\n"
- "ViewType=1\n"
- "ColumnTitle$TextValue=Bank\n"
- "ColumnTitle$Extra1=Size\n"
- "ColumnTitle$Extra2=Manufacturer\n"
- "ColumnTitle$Value=Model\n" "ShowColumnHeaders=true\n", list);
+ spd_info = g_strdup_printf("[%s]\n"
+ "%s\n"
+ "[$ShellParam$]\n"
+ "ViewType=1\n"
+ "ColumnTitle$TextValue=%s\n" /* Bank */
+ "ColumnTitle$Extra1=%s\n" /* Size */
+ "ColumnTitle$Extra2=%s\n" /* Manufacturer */
+ "ColumnTitle$Value=%s\n" /* Model */
+ "ShowColumnHeaders=true\n",
+ _("SPD"), list,
+ _("Bank"), _("Size"), _("Manufacturer"), _("Model") );
g_free(list);
}
diff --git a/modules/devices/usb.c b/modules/devices/usb.c
index 3a93a3b6..e5088bd2 100644
--- a/modules/devices/usb.c
+++ b/modules/devices/usb.c
@@ -41,51 +41,59 @@ void __scan_usb_sysfs_add_device(gchar * endpoint, int n)
version = h_sysfs_read_float(endpoint, "version");
if (!(mxpwr = h_sysfs_read_string(endpoint, "bMaxPower"))) {
- mxpwr = g_strdup("0 mA");
+ mxpwr = g_strdup_printf("%d %s", 0 , _("mA") );
}
if (!(manufacturer = h_sysfs_read_string(endpoint, "manufacturer"))) {
- manufacturer = g_strdup("Unknown");
+ manufacturer = g_strdup(_("(Unknown)"));
}
if (!(product = h_sysfs_read_string(endpoint, "product"))) {
- if (classid == 9) {
- product = g_strdup_printf("USB %.2f Hub", version);
- } else {
- product = g_strdup_printf("Unknown USB %.2f Device (class %d)", version, classid);
- }
+ if (classid == 9) {
+ product = g_strdup_printf(_(/*/%.2f is version*/ "USB %.2f Hub"), version);
+ } else {
+ product = g_strdup_printf(_("Unknown USB %.2f Device (class %d)"), version, classid);
+ }
}
- const gchar *url = vendor_get_url(manufacturer);
- if (url) {
- tmp = g_strdup_printf("%s (%s)", vendor_get_name(manufacturer), url);
-
- g_free(manufacturer);
- manufacturer = tmp;
+ const gchar *v_url = vendor_get_url(manufacturer);
+ const gchar *v_name = vendor_get_name(manufacturer);
+ gchar *v_str;
+ if (v_url != NULL) {
+ v_str = g_strdup_printf("%s (%s)", v_name, v_url);
+ } else {
+ v_str = g_strdup_printf("%s", manufacturer);
}
tmp = g_strdup_printf("USB%d", n);
usb_list = h_strdup_cprintf("$%s$%s=\n", usb_list, tmp, product);
- strhash = g_strdup_printf("[Device Information]\n"
- "Product=%s\n"
- "Manufacturer=%s\n"
- "Speed=%.2fMbit/s\n"
- "Max Current=%s\n"
- "[Misc]\n"
- "USB Version=%.2f\n"
- "Class=0x%x\n"
- "Vendor=0x%x\n"
- "Product ID=0x%x\n"
- "Bus=%d\n",
- product,
- manufacturer,
- speed,
- mxpwr,
- version, classid, vendor, prodid, bus);
+ strhash = g_strdup_printf("[%s]\n"
+ /* Product */ "%s=%s\n"
+ /* Manufacturer */ "%s=%s\n"
+ /* Speed */ "%s=%.2f %s\n"
+ /* Max Current */ "%s=%s\n"
+ "[%s]\n"
+ /* USB Version */ "%s=%.2f\n"
+ /* Class */ "%s=0x%x\n"
+ /* Vendor */ "%s=0x%x\n"
+ /* Product ID */ "%s=0x%x\n"
+ /* Bus */ "%s=%d\n",
+ _("Device Information"),
+ _("Product"), product,
+ _("Manufacturer"), v_str,
+ _("Speed"), speed, _("Mbit/s"),
+ _("Max Current"), mxpwr,
+ _("Misc"),
+ _("USB Version"), version,
+ _("Class"), classid,
+ _("Vendor ID"), vendor,
+ _("Product ID"), prodid,
+ _("Bus"), bus);
moreinfo_add_with_prefix("DEV", tmp, strhash);
g_free(tmp);
+ g_free(v_str);
g_free(manufacturer);
g_free(product);
g_free(mxpwr);
@@ -106,7 +114,7 @@ gboolean __scan_usb_sysfs(void)
moreinfo_del_with_prefix("DEV:USB");
g_free(usb_list);
}
- usb_list = g_strdup("[USB Devices]\n");
+ usb_list = g_strdup_printf("[%s]\n", _("USB Devices"));
while ((filename = (gchar *) g_dir_read_name(sysfs))) {
gchar *endpoint =
@@ -145,7 +153,7 @@ gboolean __scan_usb_procfs(void)
moreinfo_del_with_prefix("DEV:USB");
g_free(usb_list);
}
- usb_list = g_strdup("[USB Devices]\n");
+ usb_list = g_strdup_printf("[%s]\n", _("USB Devices"));
while (fgets(buffer, 128, dev)) {
tmp = buffer;
@@ -179,50 +187,68 @@ gboolean __scan_usb_procfs(void)
if (product && *product == '\0') {
g_free(product);
if (classid == 9) {
- product = g_strdup_printf("USB %.2f Hub", ver);
+ product = g_strdup_printf(_("USB %.2f Hub"), ver);
} else {
- product = g_strdup_printf("Unknown USB %.2f Device (class %d)", ver, classid);
+ product = g_strdup_printf(_("Unknown USB %.2f Device (class %d)"), ver, classid);
}
}
- if (classid == 9) { /* hub */
- usb_list = h_strdup_cprintf("[%s#%d]\n", usb_list, product, n);
- } else { /* everything else */
- usb_list = h_strdup_cprintf("$%s$%s=\n", usb_list, tmp, product);
-
- const gchar *url = vendor_get_url(manuf);
- if (url) {
- gchar *tmp = g_strdup_printf("%s (%s)", vendor_get_name(manuf),
- url);
- g_free(manuf);
- manuf = tmp;
- }
-
- gchar *strhash = g_strdup_printf("[Device Information]\n" "Product=%s\n",
- product);
- if (manuf && strlen(manuf))
- strhash = h_strdup_cprintf("Manufacturer=%s\n", strhash, manuf);
-
- strhash = h_strdup_cprintf("[Port #%d]\n"
- "Speed=%.2fMbit/s\n"
- "Max Current=%s\n"
- "[Misc]\n"
- "USB Version=%.2f\n"
- "Revision=%.2f\n"
- "Class=0x%x\n"
- "Vendor=0x%x\n"
- "Product ID=0x%x\n"
- "Bus=%d\n" "Level=%d\n",
- strhash, port, speed, mxpwr, ver, rev, classid, vendor, prodid, bus, level);
-
- moreinfo_add_with_prefix("DEV", tmp, strhash);
- g_free(tmp);
- }
+ if (classid == 9) { /* hub */
+ usb_list = h_strdup_cprintf("[%s#%d]\n", usb_list, product, n);
+ } else { /* everything else */
+ usb_list = h_strdup_cprintf("$%s$%s=\n", usb_list, tmp, product);
+
+ EMPIFNULL(manuf);
+ const gchar *v_url = vendor_get_url(manuf);
+ const gchar *v_name = vendor_get_name(manuf);
+ gchar *v_str = NULL;
+ if (strlen(manuf)) {
+ if (v_url != NULL)
+ v_str = g_strdup_printf("%s (%s)", v_name, v_url);
+ else
+ v_str = g_strdup_printf("%s", manuf);
+ }
+ UNKIFNULL(v_str);
+ UNKIFNULL(product);
+
+ gchar *strhash = g_strdup_printf("[%s]\n" "%s=%s\n" "%s=%s\n",
+ _("Device Information"),
+ _("Product"), product,
+ _("Manufacturer"), v_str);
+
+ strhash = h_strdup_cprintf("[%s #%d]\n"
+ /* Speed */ "%s=%.2f %s\n"
+ /* Max Current */ "%s=%s\n"
+ "[%s]\n"
+ /* USB Version */ "%s=%.2f\n"
+ /* Revision */ "%s=%.2f\n"
+ /* Class */ "%s=0x%x\n"
+ /* Vendor */ "%s=0x%x\n"
+ /* Product ID */ "%s=0x%x\n"
+ /* Bus */ "%s=%d\n"
+ /* Level */ "%s=%d\n",
+ strhash,
+ _("Port"), port,
+ _("Speed"), speed, _("Mbit/s"),
+ _("Max Current"), mxpwr,
+ _("Misc"),
+ _("USB Version"), ver,
+ _("Revision"), rev,
+ _("Class"), classid,
+ _("Vendor ID"), vendor,
+ _("Product ID"), prodid,
+ _("Bus"), bus,
+ _("Level"), level);
+
+ moreinfo_add_with_prefix("DEV", tmp, strhash);
+ g_free(v_str);
+ g_free(tmp);
+ }
g_free(manuf);
g_free(product);
- manuf = g_strdup("");
- product = g_strdup("");
+ manuf = NULL;
+ product = NULL;
port = classid = 0;
}
}
@@ -274,35 +300,63 @@ void __scan_usb_lsusb_add_device(char *buffer, int bufsize, FILE * lsusb, int us
}
if (dev_class && strstr(dev_class, "0 (Defined at Interface level)")) {
- g_free(dev_class);
- if (int_class) {
- dev_class = int_class;
- } else {
- dev_class = g_strdup("Unknown");
- }
+ g_free(dev_class);
+ if (int_class) {
+ dev_class = int_class;
+ } else {
+ dev_class = g_strdup(_("(Unknown)"));
+ }
} else
- dev_class = g_strdup("Unknown");
+ dev_class = g_strdup(_("(Unknown)"));
tmp = g_strdup_printf("USB%d", usb_device_number);
usb_list = h_strdup_cprintf("$%s$%s=\n", usb_list, tmp, name);
- strhash = g_strdup_printf("[Device Information]\n"
- "Product=%s\n"
- "Manufacturer=%s\n"
- "Max Current=%s\n"
- "[Misc]\n"
- "USB Version=%s\n"
- "Class=%s\n"
- "Vendor=0x%x\n"
- "Product ID=0x%x\n"
- "Bus=%d\n",
- product ? g_strstrip(product) : "Unknown",
- vendor ? g_strstrip(vendor) : "Unknown",
- max_power ? g_strstrip(max_power) : "Unknown",
- version ? g_strstrip(version) : "Unknown",
- dev_class ? g_strstrip(dev_class) : "Unknown", vendor_id, product_id, bus);
+ const gchar *v_url = vendor_get_url(vendor);
+ const gchar *v_name = vendor_get_name(vendor);
+ gchar *v_str;
+ if (v_url != NULL) {
+ v_str = g_strdup_printf("%s (%s)", v_name, v_url);
+ } else {
+ v_str = g_strdup_printf("%s", g_strstrip(vendor) );
+ }
+
+ if (max_power != NULL) {
+ int mA = atoi(g_strstrip(max_power));
+ gchar *trent_steel = g_strdup_printf("%d %s", mA, _("mA"));
+ g_free(max_power);
+ max_power = trent_steel;
+ }
+
+ UNKIFNULL(product);
+ UNKIFNULL(v_str);
+ UNKIFNULL(max_power);
+ UNKIFNULL(version);
+ UNKIFNULL(dev_class);
+
+ strhash = g_strdup_printf("[%s]\n"
+ /* Product */ "%s=%s\n"
+ /* Manufacturer */ "%s=%s\n"
+ /* Max Current */ "%s=%s\n"
+ "[%s]\n"
+ /* USB Version */ "%s=%s\n"
+ /* Class */ "%s=%s\n"
+ /* Vendor ID */ "%s=0x%x\n"
+ /* Product ID */ "%s=0x%x\n"
+ /* Bus */ "%s=%d\n",
+ _("Device Information"),
+ _("Product"), g_strstrip(product),
+ _("Vendor"), v_str,
+ _("Max Current"), g_strstrip(max_power),
+ _("Misc"),
+ _("USB Version"), g_strstrip(version),
+ _("Class"), g_strstrip(dev_class),
+ _("Vendor ID"), vendor_id,
+ _("Product ID"), product_id,
+ _("Bus"), bus);
moreinfo_add_with_prefix("DEV", tmp, strhash);
+ g_free(v_str);
g_free(vendor);
g_free(product);
g_free(max_power);
@@ -356,25 +410,25 @@ gboolean __scan_usb_lsusb(void)
if (usb_list) {
moreinfo_del_with_prefix("DEV:USB");
- g_free(usb_list);
+ g_free(usb_list);
}
- usb_list = g_strdup("[USB Devices]\n");
+ usb_list = g_strdup_printf("[%s]\n", _("USB Devices"));
while (fgets(buffer, sizeof(buffer), temp_lsusb)) {
if (g_str_has_prefix(buffer, "Bus ")) {
__scan_usb_lsusb_add_device(buffer, sizeof(buffer), temp_lsusb, ++usb_device_number);
}
}
-
+
fclose(temp_lsusb);
-
+
return usb_device_number > 0;
}
void __scan_usb(void)
{
if (!__scan_usb_procfs()) {
- if (!__scan_usb_sysfs()) {
+ if (!__scan_usb_sysfs()) {
__scan_usb_lsusb();
}
}
diff --git a/modules/devices/x86/processor.c b/modules/devices/x86/processor.c
index 25dc6c4a..ad3c7ca4 100644
--- a/modules/devices/x86/processor.c
+++ b/modules/devices/x86/processor.c
@@ -18,6 +18,10 @@
#include "hardinfo.h"
#include "devices.h"
+#include "cpu_util.h"
+
+#include "x86_data.h"
+#include "x86_data.c"
/*
* This function is partly based on x86cpucaps
@@ -148,10 +152,10 @@ static gchar *__cache_get_info_as_string(Processor *processor)
for (cache_list = processor->cache; cache_list; cache_list = cache_list->next) {
cache = (ProcessorCache *)cache_list->data;
- result = h_strdup_cprintf("Level %d (%s)=%d-way set-associative, %d sets, %dKB size\n",
+ result = h_strdup_cprintf(_("Level %d (%s)=%d-way set-associative, %d sets, %dKB size\n"),
result,
cache->level,
- cache->type,
+ C_("cache-type", cache->type),
cache->ways_of_associativity,
cache->number_of_sets,
cache->size);
@@ -160,6 +164,14 @@ static gchar *__cache_get_info_as_string(Processor *processor)
return result;
}
+/* This is not used directly, but creates translatable strings for
+ * the type string returned from /sys/.../cache */
+static const char* cache_types[] = {
+ NC_("cache-type", /*/cache type, as appears in: Level 1 (Data)*/ "Data"),
+ NC_("cache-type", /*/cache type, as appears in: Level 1 (Instruction)*/ "Instruction"),
+ NC_("cache-type", /*/cache type, as appears in: Level 2 (Unified)*/ "Unified")
+};
+
static void __cache_obtain_info(Processor *processor)
{
ProcessorCache *cache;
@@ -214,33 +226,6 @@ fail:
g_free(endpoint);
}
-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;
-}
-
-static gint get_cpu_int(const gchar* file, gint cpuid) {
- gchar *tmp0 = NULL;
- gchar *tmp1 = NULL;
- gint ret = 0;
-
- tmp0 = g_strdup_printf("/sys/devices/system/cpu/cpu%d/%s", cpuid, file);
- g_file_get_contents(tmp0, &tmp1, NULL, NULL);
- if (tmp1)
- ret = atol(tmp1);
-
- g_free(tmp0);
- g_free(tmp1);
- return ret;
-}
-
GSList *processor_scan(void)
{
GSList *procs = NULL, *l = NULL;
@@ -248,7 +233,7 @@ GSList *processor_scan(void)
FILE *cpuinfo;
gchar buffer[512];
- cpuinfo = fopen("/proc/cpuinfo", "r");
+ cpuinfo = fopen(PROC_CPUINFO, "r");
if (!cpuinfo)
return NULL;
@@ -280,6 +265,7 @@ GSList *processor_scan(void)
get_str("flags", processor->flags);
get_str("bugs", processor->bugs);
get_str("power management", processor->pm);
+ get_str("microcode", processor->microcode);
get_int("cache size", processor->cache_size);
get_float("cpu MHz", processor->cpu_mhz);
get_float("bogomips", processor->bogomips);
@@ -290,6 +276,7 @@ GSList *processor_scan(void)
get_str("hlt_bug", processor->bug_hlt);
get_str("f00f_bug", processor->bug_f00f);
get_str("coma_bug", processor->bug_coma);
+ /* sep_bug? */
get_int("model", processor->model);
get_int("cpu family", processor->family);
@@ -298,6 +285,8 @@ GSList *processor_scan(void)
g_strfreev(tmp);
}
+ fclose(cpuinfo);
+
/* finish last */
if (processor)
procs = g_slist_append(procs, processor);
@@ -305,9 +294,17 @@ GSList *processor_scan(void)
for (l = procs; l; l = l->next) {
processor = (Processor *) l->data;
+ STRIFNULL(processor->microcode, _("(Not Available)") );
+
get_processor_strfamily(processor);
__cache_obtain_info(processor);
+#define NULLIFNOTYES(f) if (processor->f) if (strcmp(processor->f, "yes") != 0) { g_free(processor->f); processor->f = NULL; }
+ NULLIFNOTYES(bug_fdiv);
+ NULLIFNOTYES(bug_hlt);
+ NULLIFNOTYES(bug_f00f);
+ NULLIFNOTYES(bug_coma);
+
if (processor->bugs == NULL || g_strcmp0(processor->bugs, "") == 0) {
g_free(processor->bugs);
/* make bugs list on old kernels that don't offer one */
@@ -337,291 +334,38 @@ GSList *processor_scan(void)
g_strchug(processor->pm);
}
- /* freq */
- processor->cpukhz_cur = get_cpu_int("cpufreq/scaling_cur_freq", processor->id);
- processor->cpukhz_min = get_cpu_int("cpufreq/scaling_min_freq", processor->id);
- processor->cpukhz_max = get_cpu_int("cpufreq/scaling_max_freq", processor->id);
- if (processor->cpukhz_max)
- processor->cpu_mhz = processor->cpukhz_max / 1000;
- }
-
- fclose(cpuinfo);
-
- return procs;
-}
-
-/*
- * Sources:
- * - Linux' cpufeature.h
- * - http://gentoo-wiki.com/Cpuinfo
- * - Intel IA-32 Architecture Software Development Manual
- * - https://unix.stackexchange.com/questions/43539/what-do-the-flags-in-proc-cpuinfo-mean
- */
-static struct {
- char *name, *meaning;
-} flag_meaning[] = {
- { "3dnow", "3DNow! Technology" },
- { "3dnowext", "Extended 3DNow! Technology" },
- { "fpu", "Floating Point Unit" },
- { "vme", "Virtual 86 Mode Extension" },
- { "de", "Debug Extensions - I/O breakpoints" },
- { "pse", "Page Size Extensions (4MB pages)" },
- { "tsc", "Time Stamp Counter and RDTSC instruction" },
- { "msr", "Model Specific Registers" },
- { "pae", "Physical Address Extensions" },
- { "mce", "Machine Check Architecture" },
- { "cx8", "CMPXCHG8 instruction" },
- { "apic", "Advanced Programmable Interrupt Controller" },
- { "sep", "Fast System Call (SYSENTER/SYSEXIT)" },
- { "mtrr", "Memory Type Range Registers" },
- { "pge", "Page Global Enable" },
- { "mca", "Machine Check Architecture" },
- { "cmov", "Conditional Move instruction" },
- { "pat", "Page Attribute Table" },
- { "pse36", "36bit Page Size Extensions" },
- { "psn", "96 bit Processor Serial Number" },
- { "mmx", "MMX technology" },
- { "mmxext", "Extended MMX Technology" },
- { "cflush", "Cache Flush" },
- { "dtes", "Debug Trace Store" },
- { "fxsr", "FXSAVE and FXRSTOR instructions" },
- { "kni", "Streaming SIMD instructions" },
- { "xmm", "Streaming SIMD instructions" },
- { "ht", "HyperThreading" },
- { "mp", "Multiprocessing Capable" },
- { "sse", "SSE instructions" },
- { "sse2", "SSE2 (WNI) instructions" },
- { "acc", "Automatic Clock Control" },
- { "ia64", "IA64 Instructions" },
- { "syscall", "SYSCALL and SYSEXIT instructions" },
- { "nx", "No-execute Page Protection" },
- { "xd", "Execute Disable" },
- { "clflush", "Cache Line Flush instruction" },
- { "acpi", "Thermal Monitor and Software Controlled Clock" },
- { "dts", "Debug Store" },
- { "ss", "Self Snoop" },
- { "tm", "Thermal Monitor" },
- { "pbe", "Pending Break Enable" },
- { "pb", "Pending Break Enable" },
- { "pn", "Processor serial number" },
- { "ds", "Debug Store" },
- { "xmm2", "Streaming SIMD Extensions-2" },
- { "xmm3", "Streaming SIMD Extensions-3" },
- { "selfsnoop", "CPU self snoop" },
- { "rdtscp", "RDTSCP" },
- { "recovery", "CPU in recovery mode" },
- { "longrun", "Longrun power control" },
- { "lrti", "LongRun table interface" },
- { "cxmmx", "Cyrix MMX extensions" },
- { "k6_mtrr", "AMD K6 nonstandard MTRRs" },
- { "cyrix_arr", "Cyrix ARRs (= MTRRs)" },
- { "centaur_mcr","Centaur MCRs (= MTRRs)" },
- { "constant_tsc","TSC ticks at a constant rate" },
- { "up", "smp kernel running on up" },
- { "fxsave_leak","FXSAVE leaks FOP/FIP/FOP" },
- { "arch_perfmon","Intel Architectural PerfMon" },
- { "pebs", "Precise-Event Based Sampling" },
- { "bts", "Branch Trace Store" },
- { "sync_rdtsc", "RDTSC synchronizes the CPU" },
- { "rep_good", "rep microcode works well on this CPU" },
- { "mwait", "Monitor/Mwait support" },
- { "ds_cpl", "CPL Qualified Debug Store" },
- { "est", "Enhanced SpeedStep" },
- { "tm2", "Thermal Monitor 2" },
- { "cid", "Context ID" },
- { "xtpr", "Send Task Priority Messages" },
- { "xstore", "on-CPU RNG present (xstore insn)" },
- { "xstore_en", "on-CPU RNG enabled" },
- { "xcrypt", "on-CPU crypto (xcrypt insn)" },
- { "xcrypt_en", "on-CPU crypto enabled" },
- { "ace2", "Advanced Cryptography Engine v2" },
- { "ace2_en", "ACE v2 enabled" },
- { "phe", "PadLock Hash Engine" },
- { "phe_en", "PHE enabled" },
- { "pmm", "PadLock Montgomery Multiplier" },
- { "pmm_en", "PMM enabled" },
- { "lahf_lm", "LAHF/SAHF in long mode" },
- { "cmp_legacy", "HyperThreading not valid" },
- { "lm", "LAHF/SAHF in long mode" },
- { "ds_cpl", "CPL Qualified Debug Store" },
- { "vmx", "Virtualization support (Intel)" },
- { "svm", "Virtualization support (AMD)" },
- { "est", "Enhanced SpeedStep" },
- { "tm2", "Thermal Monitor 2" },
- { "ssse3", "Supplemental Streaming SIMD Extension 3" },
- { "cx16", "CMPXCHG16B instruction" },
- { "xptr", "Send Task Priority Messages" },
- { "pebs", "Precise Event Based Sampling" },
- { "bts", "Branch Trace Store" },
- { "ida", "Intel Dynamic Acceleration" },
- { "arch_perfmon","Intel Architectural PerfMon" },
- { "pni", "Streaming SIMD Extension 3 (Prescott New Instruction)" },
- { "rep_good", "rep microcode works well on this CPU" },
- { "ts", "Thermal Sensor" },
- { "sse3", "Streaming SIMD Extension 3" },
- { "sse4", "Streaming SIMD Extension 4" },
- { "tni", "Tejas New Instruction" },
- { "nni", "Nehalem New Instruction" },
- { "tpr", "Task Priority Register" },
- { "vid", "Voltage Identifier" },
- { "fid", "Frequency Identifier" },
- { "dtes64", "64-bit Debug Store" },
- { "monitor", "Monitor/Mwait support" },
- { "sse4_1", "Streaming SIMD Extension 4.1" },
- { "sse4_2", "Streaming SIMD Extension 4.2" },
- { "nopl", "NOPL instructions" },
- { "cxmmx", "Cyrix MMX extensions" },
- { "xtopology", "CPU topology enum extensions" },
- { "nonstop_tsc", "TSC does not stop in C states" },
- { "eagerfpu", "Non lazy FPU restor" },
- { "pclmulqdq", "Perform a Carry-Less Multiplication of Quadword instruction" },
- { "smx", "Safer mode: TXT (TPM support)" },
- { "pdcm", "Performance capabilities" },
- { "pcid", "Process Context Identifiers" },
- { "x2apic", "x2APIC" },
- { "popcnt", "Set bit count instructions" },
- { "aes", "Advanced Encryption Standard" },
- { "aes-ni", "Advanced Encryption Standard (New Instructions)" },
- { "xsave", "Save Processor Extended States" },
- { "avx", "Advanced Vector Instructions" },
- { NULL, NULL },
-};
-
-static struct {
- char *name, *meaning;
-} bug_meaning[] = {
- { "f00f", "Intel F00F bug" },
- { "fdiv", "FPU FDIV" },
- { "coma", "Cyrix 6x86 coma" },
- { "tlb_mmatch", "AMD Erratum 383" },
- { "apic_c1e", "AMD Erratum 400" },
- { "11ap", "Bad local APIC aka 11AP" },
- { "fxsave_leak", "FXSAVE leaks FOP/FIP/FOP" },
- { "clflush_monitor", "AAI65, CLFLUSH required before MONITOR" },
- { "sysret_ss_attrs", "SYSRET doesn't fix up SS attrs" },
- { "espfix", "IRET to 16-bit SS corrupts ESP/RSP high bits" },
- { "null_seg", "Nulling a selector preserves the base" }, /* see: detect_null_seg_behavior() */
- { "swapgs_fence","SWAPGS without input dep on GS" },
- { "monitor", "IPI required to wake up remote CPU" },
- { "amd_e400", "AMD Erratum 400" },
- { NULL, NULL },
-};
-
-/* from arch/x86/kernel/cpu/powerflags.h */
-static struct {
- char *name, *meaning;
-} pm_meaning[] = {
- { "ts", "temperature sensor" },
- { "fid", "frequency id control" },
- { "vid", "voltage id control" },
- { "ttp", "thermal trip" },
- { "tm", "hardware thermal control" },
- { "stc", "software thermal control" },
- { "100mhzsteps", "100 MHz multiplier control" },
- { "hwpstate", "hardware P-state control" },
-/* { "", "tsc invariant mapped to constant_tsc" }, */
- { "cpb", "core performance boost" },
- { "eff_freq_ro", "Readonly aperf/mperf" },
- { "proc_feedback", "processor feedback interface" },
- { "acc_power", "accumulated power mechanism" },
- { NULL, NULL },
-};
-
-GHashTable *cpu_flags = NULL;
-
-static void
-populate_cpu_flags_list_internal()
-{
- int i;
-
- DEBUG("using internal CPU flags database");
+ /* topo & freq */
+ processor->cpufreq = cpufreq_new(processor->id);
+ processor->cputopo = cputopo_new(processor->id);
- for (i = 0; flag_meaning[i].name != NULL; i++) {
- g_hash_table_insert(cpu_flags, flag_meaning[i].name,
- flag_meaning[i].meaning);
+ if (processor->cpufreq->cpukhz_max)
+ processor->cpu_mhz = processor->cpufreq->cpukhz_max / 1000;
}
- for (i = 0; bug_meaning[i].name != NULL; i++) {
- g_hash_table_insert(cpu_flags, bug_meaning[i].name,
- bug_meaning[i].meaning);
- }
- for (i = 0; pm_meaning[i].name != NULL; i++) {
- g_hash_table_insert(cpu_flags, pm_meaning[i].name,
- pm_meaning[i].meaning);
- }
-}
-
-void cpu_flags_init(void)
-{
- gint i;
- gchar *path;
-
- cpu_flags = g_hash_table_new(g_str_hash, g_str_equal);
-
- path = g_build_filename(g_get_home_dir(), ".hardinfo", "cpuflags.conf", NULL);
- if (!g_file_test(path, G_FILE_TEST_EXISTS)) {
- populate_cpu_flags_list_internal();
- } else {
- GKeyFile *flags_file;
- DEBUG("using %s as CPU flags database", path);
-
- flags_file = g_key_file_new();
- if (g_key_file_load_from_file(flags_file, path, 0, NULL)) {
- gchar **flag_keys;
-
- flag_keys = g_key_file_get_keys(flags_file, "flags",
- NULL, NULL);
- if (!flag_keys) {
- DEBUG("error while using %s as CPU flags database, falling back to internal",
- path);
- populate_cpu_flags_list_internal();
- } else {
- for (i = 0; flag_keys[i]; i++) {
- gchar *meaning;
-
- meaning = g_key_file_get_string(flags_file, "flags",
- flag_keys[i], NULL);
-
- g_hash_table_insert(cpu_flags, g_strdup(flag_keys[i]), meaning);
-
- /* can't free meaning */
- }
-
- g_strfreev(flag_keys);
- }
- }
-
- g_key_file_free(flags_file);
- }
-
- g_free(path);
+ return procs;
}
-gchar *processor_get_capabilities_from_flags(gchar * strflags)
+gchar *processor_get_capabilities_from_flags(gchar *strflags, gchar *lookup_prefix)
{
- /* FIXME:
- * - Separate between processor capabilities, additional instructions and whatnot.
- */
gchar **flags, **old;
+ gchar tmp_flag[64] = "";
+ const gchar *meaning;
gchar *tmp = NULL;
gint j = 0;
- if (!cpu_flags) {
- cpu_flags_init();
- }
-
flags = g_strsplit(strflags, " ", 0);
old = flags;
while (flags[j]) {
- gchar *meaning = g_hash_table_lookup(cpu_flags, flags[j]);
+ sprintf(tmp_flag, "%s%s", lookup_prefix, flags[j]);
+ meaning = x86_flag_meaning(tmp_flag);
- if (meaning) {
- tmp = h_strdup_cprintf("%s=%s\n", tmp, flags[j], meaning);
+ if (meaning) {
+ tmp = h_strdup_cprintf("%s=%s\n", tmp, flags[j], meaning);
} else {
- tmp = h_strdup_cprintf("%s=\n", tmp, flags[j]);
+ tmp = h_strdup_cprintf("%s=\n", tmp, flags[j]);
}
- j++;
+ j++;
}
if (tmp == NULL || g_strcmp0(tmp, "") == 0)
tmp = g_strdup_printf("%s=%s\n", "empty", _("Empty List"));
@@ -632,96 +376,120 @@ gchar *processor_get_capabilities_from_flags(gchar * strflags)
gchar *processor_get_detailed_info(Processor * processor)
{
- gchar *tmp_flags, *tmp_bugs, *tmp_pm, *ret, *cache_info;
+ gchar *tmp_flags, *tmp_bugs, *tmp_pm, *tmp_cpufreq, *tmp_topology, *ret, *cache_info;
- tmp_flags = processor_get_capabilities_from_flags(processor->flags);
- tmp_bugs = processor_get_capabilities_from_flags(processor->bugs);
- tmp_pm = processor_get_capabilities_from_flags(processor->pm);
+ tmp_flags = processor_get_capabilities_from_flags(processor->flags, "");
+ tmp_bugs = processor_get_capabilities_from_flags(processor->bugs, "bug:");
+ tmp_pm = processor_get_capabilities_from_flags(processor->pm, "pm:");
cache_info = __cache_get_info_as_string(processor);
- ret = g_strdup_printf(_("[Processor]\n"
- "Name=%s\n"
- "Family, model, stepping=%d, %d, %d (%s)\n"
- "Vendor=%s\n"
- "[Configuration]\n"
- "Cache Size=%dkb\n"
- "Frequency=%.2fMHz\n"
- "BogoMIPS=%.2f\n"
- "Byte Order=%s\n"
- "[Frequency Scaling]\n"
- "Minimum=%d kHz\n"
- "Maximum=%d kHz\n"
- "Current=%d kHz\n"
- "[Features]\n"
- "Has FPU=%s\n"
- "[Cache]\n"
- "%s\n"
- "[Power Management]\n"
- "%s"
- "[Bugs]\n"
- "%s"
- "[Capabilities]\n"
- "%s"),
- processor->model_name,
- processor->family,
- processor->model,
- processor->stepping,
- processor->strmodel,
- vendor_get_name(processor->vendor_id),
- processor->cache_size,
- processor->cpu_mhz, processor->bogomips,
-#if G_BYTE_ORDER == G_LITTLE_ENDIAN
- "Little Endian",
-#else
- "Big Endian",
-#endif
- processor->cpukhz_min,
- processor->cpukhz_max,
- processor->cpukhz_cur,
- processor->has_fpu ? processor->has_fpu : "no",
- cache_info,
- tmp_pm, tmp_bugs, tmp_flags);
+ tmp_topology = cputopo_section_str(processor->cputopo);
+ tmp_cpufreq = cpufreq_section_str(processor->cpufreq);
+
+ ret = g_strdup_printf("[%s]\n"
+ "%s=%s\n"
+ "%s=%d, %d, %d (%s)\n" /* family, model, stepping (decoded name) */
+ "%s=%s\n" /* vendor */
+ "%s=%s\n" /* microcode */
+ "[%s]\n" /* configuration */
+ "%s=%d %s\n" /* cache size (from cpuinfo) */
+ "%s=%.2f %s\n" /* frequency */
+ "%s=%.2f\n" /* bogomips */
+ "%s=%s\n" /* byte order */
+ "%s" /* topology */
+ "%s" /* frequency scaling */
+ "[%s]\n" /* cache */
+ "%s\n"
+ "[%s]\n" /* pm */
+ "%s"
+ "[%s]\n" /* bugs */
+ "%s"
+ "[%s]\n" /* flags */
+ "%s",
+ _("Processor"),
+ _("Model Name"), processor->model_name,
+ _("Family, model, stepping"),
+ processor->family,
+ processor->model,
+ processor->stepping,
+ processor->strmodel,
+ _("Vendor"), vendor_get_name(processor->vendor_id),
+ _("Microcode Version"), processor->microcode,
+ _("Configuration"),
+ _("Cache Size"), processor->cache_size, _("kb"),
+ _("Frequency"), processor->cpu_mhz, _("MHz"),
+ _("BogoMips"), processor->bogomips,
+ _("Byte Order"), byte_order_str(),
+ tmp_topology,
+ tmp_cpufreq,
+ _("Cache"), cache_info,
+ _("Power Management"), tmp_pm,
+ _("Bug Workarounds"), tmp_bugs,
+ _("Capabilities"), tmp_flags );
g_free(tmp_flags);
g_free(tmp_bugs);
g_free(tmp_pm);
g_free(cache_info);
+ g_free(tmp_cpufreq);
+ g_free(tmp_topology);
+ return ret;
+}
+
+gchar *processor_name(GSList * processors) {
+ return processor_name_default(processors);
+}
+gchar *processor_describe(GSList * processors) {
+ return processor_describe_default(processors);
+}
+
+gchar *processor_meta(GSList * processors) {
+ gchar *meta_cpu_name = processor_name(processors);
+ gchar *meta_cpu_desc = processor_describe(processors);
+ gchar *ret = NULL;
+ UNKIFNULL(meta_cpu_desc);
+ ret = g_strdup_printf("[%s]\n"
+ "%s=%s\n"
+ "%s=%s\n",
+ _("Package Information"),
+ _("Name"), meta_cpu_name,
+ _("Description"), meta_cpu_desc);
+ g_free(meta_cpu_desc);
return ret;
}
gchar *processor_get_info(GSList * processors)
{
Processor *processor;
+ gchar *ret, *tmp, *hashkey;
+ gchar *meta; /* becomes owned by more_info? no need to free? */
+ GSList *l;
- if (g_slist_length(processors) > 1) {
- gchar *ret, *tmp, *hashkey;
- GSList *l;
-
- tmp = g_strdup("");
+ tmp = g_strdup_printf("$CPU_META$%s=\n", _("Package Information") );
- for (l = processors; l; l = l->next) {
- processor = (Processor *) l->data;
+ meta = processor_meta(processors);
+ moreinfo_add_with_prefix("DEV", "CPU_META", meta);
- tmp = g_strdup_printf(_("%s$CPU%d$%s=%.2fMHz\n"),
- tmp, processor->id,
- processor->model_name,
- processor->cpu_mhz);
-
- hashkey = g_strdup_printf("CPU%d", processor->id);
- moreinfo_add_with_prefix("DEV", hashkey,
- processor_get_detailed_info(processor));
- g_free(hashkey);
- }
+ for (l = processors; l; l = l->next) {
+ processor = (Processor *) l->data;
- ret = g_strdup_printf("[$ShellParam$]\n"
- "ViewType=1\n"
- "[Processors]\n"
- "%s", tmp);
- g_free(tmp);
+ tmp = g_strdup_printf("%s$CPU%d$%s=%.2f %s\n",
+ tmp, processor->id,
+ processor->model_name,
+ processor->cpu_mhz, _("MHz"));
- return ret;
+ hashkey = g_strdup_printf("CPU%d", processor->id);
+ moreinfo_add_with_prefix("DEV", hashkey,
+ processor_get_detailed_info(processor));
+ g_free(hashkey);
}
- processor = (Processor *) processors->data;
- return processor_get_detailed_info(processor);
+ ret = g_strdup_printf("[$ShellParam$]\n"
+ "ViewType=1\n"
+ "[Processors]\n"
+ "%s", tmp);
+ g_free(tmp);
+
+ return ret;
}
+
diff --git a/modules/devices/x86/x86_data.c b/modules/devices/x86/x86_data.c
new file mode 100644
index 00000000..ebd434bb
--- /dev/null
+++ b/modules/devices/x86/x86_data.c
@@ -0,0 +1,344 @@
+/*
+ * rpiz - https://github.com/bp0/rpiz
+ * 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; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * 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 Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include "x86_data.h"
+
+#ifndef C_
+#define C_(Ctx, String) String
+#endif
+#ifndef NC_
+#define NC_(Ctx, String) String
+#endif
+
+/* sources:
+ * https://unix.stackexchange.com/a/43540
+ * https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable.git/tree/arch/x86/include/asm/cpufeatures.h?id=refs/tags/v4.9
+ * hardinfo: modules/devices/x86/processor.c
+ */
+static struct {
+ char *name, *meaning;
+} tab_flag_meaning[] = {
+/* Intel-defined CPU features, CPUID level 0x00000001 (edx)
+ * See also Wikipedia and table 2-27 in Intel Advanced Vector Extensions Programming Reference */
+ { "fpu", NC_("x86-flag", /*/flag:fpu*/ "Onboard FPU (floating point support)") },
+ { "vme", NC_("x86-flag", /*/flag:vme*/ "Virtual 8086 mode enhancements") },
+ { "de", NC_("x86-flag", /*/flag:de*/ "Debugging Extensions (CR4.DE)") },
+ { "pse", NC_("x86-flag", /*/flag:pse*/ "Page Size Extensions (4MB memory pages)") },
+ { "tsc", NC_("x86-flag", /*/flag:tsc*/ "Time Stamp Counter (RDTSC)") },
+ { "msr", NC_("x86-flag", /*/flag:msr*/ "Model-Specific Registers (RDMSR, WRMSR)") },
+ { "pae", NC_("x86-flag", /*/flag:pae*/ "Physical Address Extensions (support for more than 4GB of RAM)") },
+ { "mce", NC_("x86-flag", /*/flag:mce*/ "Machine Check Exception") },
+ { "cx8", NC_("x86-flag", /*/flag:cx8*/ "CMPXCHG8 instruction (64-bit compare-and-swap)") },
+ { "apic", NC_("x86-flag", /*/flag:apic*/ "Onboard APIC") },
+ { "sep", NC_("x86-flag", /*/flag:sep*/ "SYSENTER/SYSEXIT") },
+ { "mtrr", NC_("x86-flag", /*/flag:mtrr*/ "Memory Type Range Registers") },
+ { "pge", NC_("x86-flag", /*/flag:pge*/ "Page Global Enable (global bit in PDEs and PTEs)") },
+ { "mca", NC_("x86-flag", /*/flag:mca*/ "Machine Check Architecture") },
+ { "cmov", NC_("x86-flag", /*/flag:cmov*/ "CMOV instructions (conditional move) (also FCMOV)") },
+ { "pat", NC_("x86-flag", /*/flag:pat*/ "Page Attribute Table") },
+ { "pse36", NC_("x86-flag", /*/flag:pse36*/ "36-bit PSEs (huge pages)") },
+ { "pn", NC_("x86-flag", /*/flag:pn*/ "Processor serial number") },
+ { "clflush", NC_("x86-flag", /*/flag:clflush*/ "Cache Line Flush instruction") },
+ { "dts", NC_("x86-flag", /*/flag:dts*/ "Debug Store (buffer for debugging and profiling instructions), or alternately: digital thermal sensor") },
+ { "acpi", NC_("x86-flag", /*/flag:acpi*/ "ACPI via MSR (temperature monitoring and clock speed modulation)") },
+ { "mmx", NC_("x86-flag", /*/flag:mmx*/ "Multimedia Extensions") },
+ { "fxsr", NC_("x86-flag", /*/flag:fxsr*/ "FXSAVE/FXRSTOR, CR4.OSFXSR") },
+ { "sse", NC_("x86-flag", /*/flag:sse*/ "Intel SSE vector instructions") },
+ { "sse2", NC_("x86-flag", /*/flag:sse2*/ "SSE2") },
+ { "ss", NC_("x86-flag", /*/flag:ss*/ "CPU self snoop") },
+ { "ht", NC_("x86-flag", /*/flag:ht*/ "Hyper-Threading") },
+ { "tm", NC_("x86-flag", /*/flag:tm*/ "Automatic clock control (Thermal Monitor)") },
+ { "ia64", NC_("x86-flag", /*/flag:ia64*/ "Intel Itanium Architecture 64-bit (not to be confused with Intel's 64-bit x86 architecture with flag x86-64 or \"AMD64\" bit indicated by flag lm)") },
+ { "pbe", NC_("x86-flag", /*/flag:pbe*/ "Pending Break Enable (PBE# pin) wakeup support") },
+/* AMD-defined CPU features, CPUID level 0x80000001
+ * See also Wikipedia and table 2-23 in Intel Advanced Vector Extensions Programming Reference */
+ { "syscall", NC_("x86-flag", /*/flag:syscall*/ "SYSCALL (Fast System Call) and SYSRET (Return From Fast System Call)") },
+ { "mp", NC_("x86-flag", /*/flag:mp*/ "Multiprocessing Capable.") },
+ { "nx", NC_("x86-flag", /*/flag:nx*/ "Execute Disable") },
+ { "mmxext", NC_("x86-flag", /*/flag:mmxext*/ "AMD MMX extensions") },
+ { "fxsr_opt", NC_("x86-flag", /*/flag:fxsr_opt*/ "FXSAVE/FXRSTOR optimizations") },
+ { "pdpe1gb", NC_("x86-flag", /*/flag:pdpe1gb*/ "One GB pages (allows hugepagesz=1G)") },
+ { "rdtscp", NC_("x86-flag", /*/flag:rdtscp*/ "Read Time-Stamp Counter and Processor ID") },
+ { "lm", NC_("x86-flag", /*/flag:lm*/ "Long Mode (x86-64: amd64, also known as Intel 64, i.e. 64-bit capable)") },
+ { "3dnow", NC_("x86-flag", /*/flag:3dnow*/ "3DNow! (AMD vector instructions, competing with Intel's SSE1)") },
+ { "3dnowext", NC_("x86-flag", /*/flag:3dnowext*/ "AMD 3DNow! extensions") },
+/* Transmeta-defined CPU features, CPUID level 0x80860001 */
+ { "recovery", NC_("x86-flag", /*/flag:recovery*/ "CPU in recovery mode") },
+ { "longrun", NC_("x86-flag", /*/flag:longrun*/ "Longrun power control") },
+ { "lrti", NC_("x86-flag", /*/flag:lrti*/ "LongRun table interface") },
+/* Other features, Linux-defined mapping */
+ { "cxmmx", NC_("x86-flag", /*/flag:cxmmx*/ "Cyrix MMX extensions") },
+ { "k6_mtrr", NC_("x86-flag", /*/flag:k6_mtrr*/ "AMD K6 nonstandard MTRRs") },
+ { "cyrix_arr", NC_("x86-flag", /*/flag:cyrix_arr*/ "Cyrix ARRs (= MTRRs)") },
+ { "centaur_mcr", NC_("x86-flag", /*/flag:centaur_mcr*/ "Centaur MCRs (= MTRRs)") },
+ { "constant_tsc", NC_("x86-flag", /*/flag:constant_tsc*/ "TSC ticks at a constant rate") },
+ { "up", NC_("x86-flag", /*/flag:up*/ "SMP kernel running on UP") },
+ { "art", NC_("x86-flag", /*/flag:art*/ "Always-Running Timer") },
+ { "arch_perfmon", NC_("x86-flag", /*/flag:arch_perfmon*/ "Intel Architectural PerfMon") },
+ { "pebs", NC_("x86-flag", /*/flag:pebs*/ "Precise-Event Based Sampling") },
+ { "bts", NC_("x86-flag", /*/flag:bts*/ "Branch Trace Store") },
+ { "rep_good", NC_("x86-flag", /*/flag:rep_good*/ "rep microcode works well") },
+ { "acc_power", NC_("x86-flag", /*/flag:acc_power*/ "AMD accumulated power mechanism") },
+ { "nopl", NC_("x86-flag", /*/flag:nopl*/ "The NOPL (0F 1F) instructions") },
+ { "xtopology", NC_("x86-flag", /*/flag:xtopology*/ "cpu topology enum extensions") },
+ { "tsc_reliable", NC_("x86-flag", /*/flag:tsc_reliable*/ "TSC is known to be reliable") },
+ { "nonstop_tsc", NC_("x86-flag", /*/flag:nonstop_tsc*/ "TSC does not stop in C states") },
+ { "extd_apicid", NC_("x86-flag", /*/flag:extd_apicid*/ "has extended APICID (8 bits)") },
+ { "amd_dcm", NC_("x86-flag", /*/flag:amd_dcm*/ "multi-node processor") },
+ { "aperfmperf", NC_("x86-flag", /*/flag:aperfmperf*/ "APERFMPERF") },
+ { "eagerfpu", NC_("x86-flag", /*/flag:eagerfpu*/ "Non lazy FPU restore") },
+ { "nonstop_tsc_s3", NC_("x86-flag", /*/flag:nonstop_tsc_s3*/ "TSC doesn't stop in S3 state") },
+ { "mce_recovery", NC_("x86-flag", /*/flag:mce_recovery*/ "CPU has recoverable machine checks") },
+/* Intel-defined CPU features, CPUID level 0x00000001 (ecx)
+ * See also Wikipedia and table 2-26 in Intel Advanced Vector Extensions Programming Reference */
+ { "pni", NC_("x86-flag", /*/flag:pni*/ "SSE-3 (\"Prescott New Instructions\")") },
+ { "pclmulqdq", NC_("x86-flag", /*/flag:pclmulqdq*/ "Perform a Carry-Less Multiplication of Quadword instruction - accelerator for GCM)") },
+ { "dtes64", NC_("x86-flag", /*/flag:dtes64*/ "64-bit Debug Store") },
+ { "monitor", NC_("x86-flag", /*/flag:monitor*/ "Monitor/Mwait support (Intel SSE3 supplements)") },
+ { "ds_cpl", NC_("x86-flag", /*/flag:ds_cpl*/ "CPL Qual. Debug Store") },
+ { "vmx", NC_("x86-flag", /*/flag:vmx*/ "Hardware virtualization, Intel VMX") },
+ { "smx", NC_("x86-flag", /*/flag:smx*/ "Safer mode TXT (TPM support)") },
+ { "est", NC_("x86-flag", /*/flag:est*/ "Enhanced SpeedStep") },
+ { "tm2", NC_("x86-flag", /*/flag:tm2*/ "Thermal Monitor 2") },
+ { "ssse3", NC_("x86-flag", /*/flag:ssse3*/ "Supplemental SSE-3") },
+ { "cid", NC_("x86-flag", /*/flag:cid*/ "Context ID") },
+ { "sdbg", NC_("x86-flag", /*/flag:sdbg*/ "silicon debug") },
+ { "fma", NC_("x86-flag", /*/flag:fma*/ "Fused multiply-add") },
+ { "cx16", NC_("x86-flag", /*/flag:cx16*/ "CMPXCHG16B") },
+ { "xtpr", NC_("x86-flag", /*/flag:xtpr*/ "Send Task Priority Messages") },
+ { "pdcm", NC_("x86-flag", /*/flag:pdcm*/ "Performance Capabilities") },
+ { "pcid", NC_("x86-flag", /*/flag:pcid*/ "Process Context Identifiers") },
+ { "dca", NC_("x86-flag", /*/flag:dca*/ "Direct Cache Access") },
+ { "sse4_1", NC_("x86-flag", /*/flag:sse4_1*/ "SSE-4.1") },
+ { "sse4_2", NC_("x86-flag", /*/flag:sse4_2*/ "SSE-4.2") },
+ { "x2apic", NC_("x86-flag", /*/flag:x2apic*/ "x2APIC") },
+ { "movbe", NC_("x86-flag", /*/flag:movbe*/ "Move Data After Swapping Bytes instruction") },
+ { "popcnt", NC_("x86-flag", /*/flag:popcnt*/ "Return the Count of Number of Bits Set to 1 instruction (Hamming weight, i.e. bit count)") },
+ { "tsc_deadline_timer", NC_("x86-flag", /*/flag:tsc_deadline_timer*/ "Tsc deadline timer") },
+ { "aes/aes-ni", NC_("x86-flag", /*/flag:aes/aes-ni*/ "Advanced Encryption Standard (New Instructions)") },
+ { "xsave", NC_("x86-flag", /*/flag:xsave*/ "Save Processor Extended States: also provides XGETBY,XRSTOR,XSETBY") },
+ { "avx", NC_("x86-flag", /*/flag:avx*/ "Advanced Vector Extensions") },
+ { "f16c", NC_("x86-flag", /*/flag:f16c*/ "16-bit fp conversions (CVT16)") },
+ { "rdrand", NC_("x86-flag", /*/flag:rdrand*/ "Read Random Number from hardware random number generator instruction") },
+ { "hypervisor", NC_("x86-flag", /*/flag:hypervisor*/ "Running on a hypervisor") },
+/* VIA/Cyrix/Centaur-defined CPU features, CPUID level 0xC0000001 */
+ { "rng", NC_("x86-flag", /*/flag:rng*/ "Random Number Generator present (xstore)") },
+ { "rng_en", NC_("x86-flag", /*/flag:rng_en*/ "Random Number Generator enabled") },
+ { "ace", NC_("x86-flag", /*/flag:ace*/ "on-CPU crypto (xcrypt)") },
+ { "ace_en", NC_("x86-flag", /*/flag:ace_en*/ "on-CPU crypto enabled") },
+ { "ace2", NC_("x86-flag", /*/flag:ace2*/ "Advanced Cryptography Engine v2") },
+ { "ace2_en", NC_("x86-flag", /*/flag:ace2_en*/ "ACE v2 enabled") },
+ { "phe", NC_("x86-flag", /*/flag:phe*/ "PadLock Hash Engine") },
+ { "phe_en", NC_("x86-flag", /*/flag:phe_en*/ "PHE enabled") },
+ { "pmm", NC_("x86-flag", /*/flag:pmm*/ "PadLock Montgomery Multiplier") },
+ { "pmm_en", NC_("x86-flag", /*/flag:pmm_en*/ "PMM enabled") },
+/* More extended AMD flags: CPUID level 0x80000001, ecx */
+ { "lahf_lm", NC_("x86-flag", /*/flag:lahf_lm*/ "Load AH from Flags (LAHF) and Store AH into Flags (SAHF) in long mode") },
+ { "cmp_legacy", NC_("x86-flag", /*/flag:cmp_legacy*/ "If yes HyperThreading not valid") },
+ { "svm", NC_("x86-flag", /*/flag:svm*/ "\"Secure virtual machine\": AMD-V") },
+ { "extapic", NC_("x86-flag", /*/flag:extapic*/ "Extended APIC space") },
+ { "cr8_legacy", NC_("x86-flag", /*/flag:cr8_legacy*/ "CR8 in 32-bit mode") },
+ { "abm", NC_("x86-flag", /*/flag:abm*/ "Advanced Bit Manipulation") },
+ { "sse4a", NC_("x86-flag", /*/flag:sse4a*/ "SSE-4A") },
+ { "misalignsse", NC_("x86-flag", /*/flag:misalignsse*/ "indicates if a general-protection exception (#GP) is generated when some legacy SSE instructions operate on unaligned data. Also depends on CR0 and Alignment Checking bit") },
+ { "3dnowprefetch", NC_("x86-flag", /*/flag:3dnowprefetch*/ "3DNow prefetch instructions") },
+ { "osvw", NC_("x86-flag", /*/flag:osvw*/ "indicates OS Visible Workaround, which allows the OS to work around processor errata.") },
+ { "ibs", NC_("x86-flag", /*/flag:ibs*/ "Instruction Based Sampling") },
+ { "xop", NC_("x86-flag", /*/flag:xop*/ "extended AVX instructions") },
+ { "skinit", NC_("x86-flag", /*/flag:skinit*/ "SKINIT/STGI instructions") },
+ { "wdt", NC_("x86-flag", /*/flag:wdt*/ "Watchdog timer") },
+ { "lwp", NC_("x86-flag", /*/flag:lwp*/ "Light Weight Profiling") },
+ { "fma4", NC_("x86-flag", /*/flag:fma4*/ "4 operands MAC instructions") },
+ { "tce", NC_("x86-flag", /*/flag:tce*/ "translation cache extension") },
+ { "nodeid_msr", NC_("x86-flag", /*/flag:nodeid_msr*/ "NodeId MSR") },
+ { "tbm", NC_("x86-flag", /*/flag:tbm*/ "Trailing Bit Manipulation") },
+ { "topoext", NC_("x86-flag", /*/flag:topoext*/ "Topology Extensions CPUID leafs") },
+ { "perfctr_core", NC_("x86-flag", /*/flag:perfctr_core*/ "Core Performance Counter Extensions") },
+ { "perfctr_nb", NC_("x86-flag", /*/flag:perfctr_nb*/ "NB Performance Counter Extensions") },
+ { "bpext", NC_("x86-flag", /*/flag:bpext*/ "data breakpoint extension") },
+ { "ptsc", NC_("x86-flag", /*/flag:ptsc*/ "performance time-stamp counter") },
+ { "perfctr_l2", NC_("x86-flag", /*/flag:perfctr_l2*/ "L2 Performance Counter Extensions") },
+ { "mwaitx", NC_("x86-flag", /*/flag:mwaitx*/ "MWAIT extension (MONITORX/MWAITX)") },
+/* Auxiliary flags: Linux defined - For features scattered in various CPUID levels */
+ { "cpb", NC_("x86-flag", /*/flag:cpb*/ "AMD Core Performance Boost") },
+ { "epb", NC_("x86-flag", /*/flag:epb*/ "IA32_ENERGY_PERF_BIAS support") },
+ { "hw_pstate", NC_("x86-flag", /*/flag:hw_pstate*/ "AMD HW-PState") },
+ { "proc_feedback", NC_("x86-flag", /*/flag:proc_feedback*/ "AMD ProcFeedbackInterface") },
+ { "intel_pt", NC_("x86-flag", /*/flag:intel_pt*/ "Intel Processor Tracing") },
+/* Virtualization flags: Linux defined */
+ { "tpr_shadow", NC_("x86-flag", /*/flag:tpr_shadow*/ "Intel TPR Shadow") },
+ { "vnmi", NC_("x86-flag", /*/flag:vnmi*/ "Intel Virtual NMI") },
+ { "flexpriority", NC_("x86-flag", /*/flag:flexpriority*/ "Intel FlexPriority") },
+ { "ept", NC_("x86-flag", /*/flag:ept*/ "Intel Extended Page Table") },
+ { "vpid", NC_("x86-flag", /*/flag:vpid*/ "Intel Virtual Processor ID") },
+ { "vmmcall", NC_("x86-flag", /*/flag:vmmcall*/ "prefer VMMCALL to VMCALL") },
+/* Intel-defined CPU features, CPUID level 0x00000007:0 (ebx) */
+ { "fsgsbase", NC_("x86-flag", /*/flag:fsgsbase*/ "{RD/WR}{FS/GS}BASE instructions") },
+ { "tsc_adjust", NC_("x86-flag", /*/flag:tsc_adjust*/ "TSC adjustment MSR") },
+ { "bmi1", NC_("x86-flag", /*/flag:bmi1*/ "1st group bit manipulation extensions") },
+ { "hle", NC_("x86-flag", /*/flag:hle*/ "Hardware Lock Elision") },
+ { "avx2", NC_("x86-flag", /*/flag:avx2*/ "AVX2 instructions") },
+ { "smep", NC_("x86-flag", /*/flag:smep*/ "Supervisor Mode Execution Protection") },
+ { "bmi2", NC_("x86-flag", /*/flag:bmi2*/ "2nd group bit manipulation extensions") },
+ { "erms", NC_("x86-flag", /*/flag:erms*/ "Enhanced REP MOVSB/STOSB") },
+ { "invpcid", NC_("x86-flag", /*/flag:invpcid*/ "Invalidate Processor Context ID") },
+ { "rtm", NC_("x86-flag", /*/flag:rtm*/ "Restricted Transactional Memory") },
+ { "cqm", NC_("x86-flag", /*/flag:cqm*/ "Cache QoS Monitoring") },
+ { "mpx", NC_("x86-flag", /*/flag:mpx*/ "Memory Protection Extension") },
+ { "avx512f", NC_("x86-flag", /*/flag:avx512f*/ "AVX-512 foundation") },
+ { "avx512dq", NC_("x86-flag", /*/flag:avx512dq*/ "AVX-512 Double/Quad instructions") },
+ { "rdseed", NC_("x86-flag", /*/flag:rdseed*/ "The RDSEED instruction") },
+ { "adx", NC_("x86-flag", /*/flag:adx*/ "The ADCX and ADOX instructions") },
+ { "smap", NC_("x86-flag", /*/flag:smap*/ "Supervisor Mode Access Prevention") },
+ { "clflushopt", NC_("x86-flag", /*/flag:clflushopt*/ "CLFLUSHOPT instruction") },
+ { "clwb", NC_("x86-flag", /*/flag:clwb*/ "CLWB instruction") },
+ { "avx512pf", NC_("x86-flag", /*/flag:avx512pf*/ "AVX-512 Prefetch") },
+ { "avx512er", NC_("x86-flag", /*/flag:avx512er*/ "AVX-512 Exponential and Reciprocal") },
+ { "avx512cd", NC_("x86-flag", /*/flag:avx512cd*/ "AVX-512 Conflict Detection") },
+ { "sha_ni", NC_("x86-flag", /*/flag:sha_ni*/ "SHA1/SHA256 Instruction Extensions") },
+ { "avx512bw", NC_("x86-flag", /*/flag:avx512bw*/ "AVX-512 Byte/Word instructions") },
+ { "avx512vl", NC_("x86-flag", /*/flag:avx512vl*/ "AVX-512 128/256 Vector Length extensions") },
+/* Extended state features, CPUID level 0x0000000d:1 (eax) */
+ { "xsaveopt", NC_("x86-flag", /*/flag:xsaveopt*/ "Optimized XSAVE") },
+ { "xsavec", NC_("x86-flag", /*/flag:xsavec*/ "XSAVEC") },
+ { "xgetbv1", NC_("x86-flag", /*/flag:xgetbv1*/ "XGETBV with ECX = 1") },
+ { "xsaves", NC_("x86-flag", /*/flag:xsaves*/ "XSAVES/XRSTORS") },
+/* Intel-defined CPU QoS sub-leaf, CPUID level 0x0000000F:0 (edx) */
+ { "cqm_llc", NC_("x86-flag", /*/flag:cqm_llc*/ "LLC QoS") },
+/* Intel-defined CPU QoS sub-leaf, CPUID level 0x0000000F:1 (edx) */
+ { "cqm_occup_llc", NC_("x86-flag", /*/flag:cqm_occup_llc*/ "LLC occupancy monitoring") },
+ { "cqm_mbm_total", NC_("x86-flag", /*/flag:cqm_mbm_total*/ "LLC total MBM monitoring") },
+ { "cqm_mbm_local", NC_("x86-flag", /*/flag:cqm_mbm_local*/ "LLC local MBM monitoring") },
+/* AMD-defined CPU features, CPUID level 0x80000008 (ebx) */
+ { "clzero", NC_("x86-flag", /*/flag:clzero*/ "CLZERO instruction") },
+ { "irperf", NC_("x86-flag", /*/flag:irperf*/ "instructions retired performance counter") },
+/* Thermal and Power Management leaf, CPUID level 0x00000006 (eax) */
+ { "dtherm", NC_("x86-flag", /*/flag:dtherm*/ "digital thermal sensor") }, /* formerly dts */
+ { "ida", NC_("x86-flag", /*/flag:ida*/ "Intel Dynamic Acceleration") },
+ { "arat", NC_("x86-flag", /*/flag:arat*/ "Always Running APIC Timer") },
+ { "pln", NC_("x86-flag", /*/flag:pln*/ "Intel Power Limit Notification") },
+ { "pts", NC_("x86-flag", /*/flag:pts*/ "Intel Package Thermal Status") },
+ { "hwp", NC_("x86-flag", /*/flag:hwp*/ "Intel Hardware P-states") },
+ { "hwp_notify", NC_("x86-flag", /*/flag:hwp_notify*/ "HWP notification") },
+ { "hwp_act_window", NC_("x86-flag", /*/flag:hwp_act_window*/ "HWP Activity Window") },
+ { "hwp_epp", NC_("x86-flag", /*/flag:hwp_epp*/ "HWP Energy Performance Preference") },
+ { "hwp_pkg_req", NC_("x86-flag", /*/flag:hwp_pkg_req*/ "HWP package-level request") },
+/* AMD SVM Feature Identification, CPUID level 0x8000000a (edx) */
+ { "npt", NC_("x86-flag", /*/flag:npt*/ "AMD Nested Page Table support") },
+ { "lbrv", NC_("x86-flag", /*/flag:lbrv*/ "AMD LBR Virtualization support") },
+ { "svm_lock", NC_("x86-flag", /*/flag:svm_lock*/ "AMD SVM locking MSR") },
+ { "nrip_save", NC_("x86-flag", /*/flag:nrip_save*/ "AMD SVM next_rip save") },
+ { "tsc_scale", NC_("x86-flag", /*/flag:tsc_scale*/ "AMD TSC scaling support") },
+ { "vmcb_clean", NC_("x86-flag", /*/flag:vmcb_clean*/ "AMD VMCB clean bits support") },
+ { "flushbyasid", NC_("x86-flag", /*/flag:flushbyasid*/ "AMD flush-by-ASID support") },
+ { "decodeassists", NC_("x86-flag", /*/flag:decodeassists*/ "AMD Decode Assists support") },
+ { "pausefilter", NC_("x86-flag", /*/flag:pausefilter*/ "AMD filtered pause intercept") },
+ { "pfthreshold", NC_("x86-flag", /*/flag:pfthreshold*/ "AMD pause filter threshold") },
+ { "avic", NC_("x86-flag", /*/flag:avic*/ "Virtual Interrupt Controller") },
+/* Intel-defined CPU features, CPUID level 0x00000007:0 (ecx) */
+ { "pku", NC_("x86-flag", /*/flag:pku*/ "Protection Keys for Userspace") },
+ { "ospke", NC_("x86-flag", /*/flag:ospke*/ "OS Protection Keys Enable") },
+/* AMD-defined CPU features, CPUID level 0x80000007 (ebx) */
+ { "overflow_recov", NC_("x86-flag", /*/flag:overflow_recov*/ "MCA overflow recovery support") },
+ { "succor", NC_("x86-flag", /*/flag:succor*/ "uncorrectable error containment and recovery") },
+ { "smca", NC_("x86-flag", /*/flag:smca*/ "Scalable MCA") },
+
+/* bug workarounds */
+ { "bug:f00f", NC_("x86-flag", /*/bug:f00f*/ "Intel F00F bug") },
+ { "bug:fdiv", NC_("x86-flag", /*/bug:fdiv*/ "FPU FDIV") },
+ { "bug:coma", NC_("x86-flag", /*/bug:coma*/ "Cyrix 6x86 coma") },
+ { "bug:tlb_mmatch", NC_("x86-flag", /*/bug:tlb_mmatch*/ "AMD Erratum 383") },
+ { "bug:apic_c1e", NC_("x86-flag", /*/bug:apic_c1e*/ "AMD Erratum 400") },
+ { "bug:11ap", NC_("x86-flag", /*/bug:11ap*/ "Bad local APIC aka 11AP") },
+ { "bug:fxsave_leak", NC_("x86-flag", /*/bug:fxsave_leak*/ "FXSAVE leaks FOP/FIP/FOP") },
+ { "bug:clflush_monitor", NC_("x86-flag", /*/bug:clflush_monitor*/ "AAI65, CLFLUSH required before MONITOR") },
+ { "bug:sysret_ss_attrs", NC_("x86-flag", /*/bug:sysret_ss_attrs*/ "SYSRET doesn't fix up SS attrs") },
+ { "bug:espfix", NC_("x86-flag", /*/bug:espfix*/ "IRET to 16-bit SS corrupts ESP/RSP high bits") },
+ { "bug:null_seg", NC_("x86-flag", /*/bug:null_seg*/ "Nulling a selector preserves the base") }, /* see: detect_null_seg_behavior() */
+ { "bug:swapgs_fence", NC_("x86-flag", /*/bug:swapgs_fence*/ "SWAPGS without input dep on GS") },
+ { "bug:monitor", NC_("x86-flag", /*/bug:monitor*/ "IPI required to wake up remote CPU") },
+ { "bug:amd_e400", NC_("x86-flag", /*/bug:amd_e400*/ "AMD Erratum 400") },
+/* power management
+ * ... from arch/x86/kernel/cpu/powerflags.h */
+ { "pm:ts", NC_("x86-flag", /*/flag:pm:ts*/ "temperature sensor") },
+ { "pm:fid", NC_("x86-flag", /*/flag:pm:fid*/ "frequency id control") },
+ { "pm:vid", NC_("x86-flag", /*/flag:pm:vid*/ "voltage id control") },
+ { "pm:ttp", NC_("x86-flag", /*/flag:pm:ttp*/ "thermal trip") },
+ { "pm:tm", NC_("x86-flag", /*/flag:pm:tm*/ "hardware thermal control") },
+ { "pm:stc", NC_("x86-flag", /*/flag:pm:stc*/ "software thermal control") },
+ { "pm:100mhzsteps", NC_("x86-flag", /*/flag:pm:100mhzsteps*/ "100 MHz multiplier control") },
+ { "pm:hwpstate", NC_("x86-flag", /*/flag:pm:hwpstate*/ "hardware P-state control") },
+ { "pm:cpb", NC_("x86-flag", /*/flag:pm:cpb*/ "core performance boost") },
+ { "pm:eff_freq_ro", NC_("x86-flag", /*/flag:pm:eff_freq_ro*/ "Readonly aperf/mperf") },
+ { "pm:proc_feedback", NC_("x86-flag", /*/flag:pm:proc_feedback*/ "processor feedback interface") },
+ { "pm:acc_power", NC_("x86-flag", /*/flag:pm:acc_power*/ "accumulated power mechanism") },
+ { NULL, NULL},
+};
+
+static char all_flags[4096] = "";
+
+#define APPEND_FLAG(f) strcat(all_flags, f); strcat(all_flags, " ");
+const char *x86_flag_list() {
+ int i = 0, built = 0;
+ built = strlen(all_flags);
+ if (!built) {
+ while(tab_flag_meaning[i].name != NULL) {
+ APPEND_FLAG(tab_flag_meaning[i].name);
+ i++;
+ }
+ }
+ return all_flags;
+}
+
+const char *x86_flag_meaning(const char *flag) {
+ int i = 0;
+ if (flag)
+ while(tab_flag_meaning[i].name != NULL) {
+ if (strcmp(tab_flag_meaning[i].name, flag) == 0) {
+ if (tab_flag_meaning[i].meaning != NULL)
+ return C_("x86-flag", tab_flag_meaning[i].meaning);
+ else return NULL;
+ }
+ i++;
+ }
+ return NULL;
+}
+
+static void x86_flag_find_dups(void) {
+ int t, i;
+
+ t = 0;
+ while(tab_flag_meaning[t].name != NULL) {
+ i = t+1;
+ while(tab_flag_meaning[i].name != NULL) {
+ if (strcmp(tab_flag_meaning[t].name, tab_flag_meaning[i].name) == 0) {
+ printf("x86-flag duplicate definition: %s\n ... %d: %s\n ... %d: %s\n",
+ tab_flag_meaning[i].name,
+ t, tab_flag_meaning[t].meaning,
+ i, tab_flag_meaning[i].meaning);
+ }
+ i++;
+ }
+ t++;
+ }
+}
diff --git a/modules/devices/x86/x86_data.h b/modules/devices/x86/x86_data.h
new file mode 100644
index 00000000..66a4c80f
--- /dev/null
+++ b/modules/devices/x86/x86_data.h
@@ -0,0 +1,28 @@
+/*
+ * rpiz - https://github.com/bp0/rpiz
+ * 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; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * 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 Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef _X86DATA_H_
+#define _X86DATA_H_
+
+/* cpu flags from /proc/cpuinfo */
+const char *x86_flag_list(void); /* list of all known flags */
+const char *x86_flag_meaning(const char *flag); /* lookup flag meaning */
+
+#endif
diff --git a/modules/devices/x86_64 b/modules/devices/x86_64
deleted file mode 120000
index de1ff735..00000000
--- a/modules/devices/x86_64
+++ /dev/null
@@ -1 +0,0 @@
-./x86 \ No newline at end of file
diff --git a/modules/network.c b/modules/network.c
index 18f8ba65..f27a159a 100644
--- a/modules/network.c
+++ b/modules/network.c
@@ -80,51 +80,46 @@ void scan_statistics(gboolean reload)
FILE *netstat;
gchar buffer[256];
gchar *netstat_path;
-
+ int line = 0;
+
SCAN_START();
-
+
g_free(__statistics);
__statistics = g_strdup("");
-
+
if ((netstat_path = find_program("netstat"))) {
gchar *command_line = g_strdup_printf("%s -s", netstat_path);
-
+
if ((netstat = popen(command_line, "r"))) {
while (fgets(buffer, 256, netstat)) {
if (!isspace(buffer[0]) && strchr(buffer, ':')) {
gchar *tmp;
-
+
tmp = g_ascii_strup(strend(buffer, ':'), -1);
-
+
__statistics = h_strdup_cprintf("[%s]\n",
__statistics,
tmp);
-
g_free(tmp);
- } else if (isdigit(buffer[4])) {
- gchar *tmp1 = buffer + 4,
- *tmp2 = tmp1;
-
- while (*tmp2 && !isspace(*tmp2)) tmp2++;
- *tmp2 = 0;
- tmp2++;
-
- *tmp2 = toupper(*tmp2);
-
- __statistics = h_strdup_cprintf("%s=%s\n",
+
+ } else {
+ gchar *tmp = buffer;
+
+ while (*tmp && isspace(*tmp)) tmp++;
+
+ __statistics = h_strdup_cprintf("<b> </b>#%d=%s\n",
__statistics,
- g_strstrip(tmp1),
- g_strstrip(tmp2));
+ line++, tmp);
}
}
pclose(netstat);
}
-
+
g_free(command_line);
g_free(netstat_path);
}
-
+
SCAN_END();
}
@@ -133,24 +128,24 @@ void scan_dns(gboolean reload)
{
FILE *resolv;
gchar buffer[256];
-
+
SCAN_START();
-
+
g_free(__nameservers);
__nameservers = g_strdup("");
-
+
if ((resolv = fopen("/etc/resolv.conf", "r"))) {
while (fgets(buffer, 256, resolv)) {
if (g_str_has_prefix(buffer, "nameserver")) {
gchar *ip;
struct sockaddr_in sa;
char hbuf[NI_MAXHOST];
-
+
ip = g_strstrip(buffer + sizeof("nameserver"));
-
+
sa.sin_family = AF_INET;
sa.sin_addr.s_addr = inet_addr(ip);
-
+
if (getnameinfo((struct sockaddr *)&sa, sizeof(sa), hbuf, sizeof(hbuf), NULL, 0, NI_NAMEREQD)) {
__nameservers = h_strdup_cprintf("%s=\n",
__nameservers,
@@ -159,15 +154,15 @@ void scan_dns(gboolean reload)
__nameservers = h_strdup_cprintf("%s=%s\n",
__nameservers,
ip, hbuf);
-
- }
-
+
+ }
+
shell_status_pulse();
- }
+ }
}
fclose(resolv);
}
-
+
SCAN_END();
}
@@ -184,15 +179,15 @@ void scan_route(gboolean reload)
FILE *route;
gchar buffer[256];
gchar *route_path;
-
+
SCAN_START();
g_free(__routing_table);
__routing_table = g_strdup("");
-
+
if ((route_path = find_program("route"))) {
gchar *command_line = g_strdup_printf("%s -n", route_path);
-
+
if ((route = popen(command_line, "r"))) {
/* eat first two lines */
(void)fgets(buffer, 256, route);
@@ -203,7 +198,7 @@ void scan_route(gboolean reload)
buffer[31] = '\0';
buffer[47] = '\0';
buffer[53] = '\0';
-
+
__routing_table = h_strdup_cprintf("%s / %s=%s|%s|%s\n",
__routing_table,
g_strstrip(buffer), g_strstrip(buffer + 16),
@@ -211,14 +206,14 @@ void scan_route(gboolean reload)
g_strstrip(buffer + 48),
g_strstrip(buffer + 32));
}
-
+
pclose(route);
}
-
+
g_free(command_line);
g_free(route_path);
}
-
+
SCAN_END();
}
@@ -227,12 +222,12 @@ void scan_arp(gboolean reload)
{
FILE *arp;
gchar buffer[256];
-
+
SCAN_START();
g_free(__arp_table);
__arp_table = g_strdup("");
-
+
if ((arp = fopen("/proc/net/arp", "r"))) {
/* eat first line */
(void)fgets(buffer, 256, arp);
@@ -240,17 +235,17 @@ void scan_arp(gboolean reload)
while (fgets(buffer, 256, arp)) {
buffer[15] = '\0';
buffer[58] = '\0';
-
+
__arp_table = h_strdup_cprintf("%s=%s|%s\n",
__arp_table,
g_strstrip(buffer),
g_strstrip(buffer + 72),
g_strstrip(buffer + 41));
}
-
+
fclose(arp);
}
-
+
SCAN_END();
}
@@ -260,15 +255,15 @@ void scan_connections(gboolean reload)
FILE *netstat;
gchar buffer[256];
gchar *netstat_path;
-
+
SCAN_START();
g_free(__connections);
__connections = g_strdup("");
-
+
if ((netstat_path = find_program("netstat"))) {
gchar *command_line = g_strdup_printf("%s -an", netstat_path);
-
+
if ((netstat = popen("netstat -an", "r"))) {
while (fgets(buffer, 256, netstat)) {
buffer[6] = '\0';
@@ -284,91 +279,99 @@ void scan_connections(gboolean reload)
g_strstrip(buffer + 68)); /* state */
}
}
-
+
pclose(netstat);
}
-
+
g_free(command_line);
g_free(netstat_path);
}
-
+
SCAN_END();
}
gchar *callback_arp()
{
- return g_strdup_printf(_("[ARP Table]\n"
+ return g_strdup_printf("[%s]\n"
"%s\n"
"[$ShellParam$]\n"
"ReloadInterval=3000\n"
- "ColumnTitle$TextValue=IP Address\n"
- "ColumnTitle$Value=Interface\n"
- "ColumnTitle$Extra1=MAC Address\n"
- "ShowColumnHeaders=true\n"),
- __arp_table);
+ "ColumnTitle$TextValue=%s\n" /* IP Address */
+ "ColumnTitle$Value=%s\n" /* Interface */
+ "ColumnTitle$Extra1=%s\n" /* MAC Address */
+ "ShowColumnHeaders=true\n",
+ _("ARP Table"), __arp_table,
+ _("IP Address"), _("Interface"), _("MAC Address") );
}
gchar *callback_shares()
{
- return g_strdup_printf("[SAMBA]\n"
- "%s\n"
- "[NFS]\n"
- "%s", smb_shares_list, nfs_shares_list);
+ return g_strdup_printf("[%s]\n"
+ "%s\n"
+ "[%s]\n"
+ "%s",
+ _("SAMBA"), smb_shares_list,
+ _("NFS"), nfs_shares_list);
}
gchar *callback_dns()
{
- return g_strdup_printf(_("[Name servers]\n"
+ return g_strdup_printf("[%s]\n"
"%s\n"
"[$ShellParam$]\n"
- "ColumnTitle$TextValue=IP Address\n"
- "ColumnTitle$Value=Name\n"
- "ShowColumnHeaders=true\n"), __nameservers);
+ "ColumnTitle$TextValue=%s\n" /* IP Address */
+ "ColumnTitle$Value=%s\n" /* Name */
+ "ShowColumnHeaders=true\n",
+ _("Name Servers"), __nameservers,
+ _("IP Address"), _("Name") );
}
gchar *callback_connections()
{
- return g_strdup_printf(_("[Connections]\n"
+ return g_strdup_printf("[%s]\n"
"%s\n"
"[$ShellParam$]\n"
"ReloadInterval=3000\n"
- "ColumnTitle$TextValue=Local Address\n"
- "ColumnTitle$Value=Protocol\n"
- "ColumnTitle$Extra1=Foreign Address\n"
- "ColumnTitle$Extra2=State\n"
- "ShowColumnHeaders=true\n"),
- __connections);
+ "ColumnTitle$TextValue=%s\n" /* Local Address */
+ "ColumnTitle$Value=%s\n" /* Protocol */
+ "ColumnTitle$Extra1=%s\n" /* Foreign Address */
+ "ColumnTitle$Extra2=%s\n" /* State */
+ "ShowColumnHeaders=true\n",
+ _("Connections"), __connections,
+ _("Local Address"), _("Protocol"), _("Foreign Address"), _("State") );
}
gchar *callback_network()
{
- return g_strdup_printf(_("%s\n"
- "[$ShellParam$]\n"
- "ReloadInterval=3000\n"
- "ViewType=1\n"
- "ColumnTitle$TextValue=Interface\n"
- "ColumnTitle$Value=IP Address\n"
- "ColumnTitle$Extra1=Sent\n"
- "ColumnTitle$Extra2=Received\n"
- "ShowColumnHeaders=true\n"
- "%s"),
- network_interfaces,
- network_icons);
+ return g_strdup_printf("%s\n"
+ "[$ShellParam$]\n"
+ "ReloadInterval=3000\n"
+ "ViewType=1\n"
+ "ColumnTitle$TextValue=%s\n" /* Interface */
+ "ColumnTitle$Value=%s\n" /* IP Address */
+ "ColumnTitle$Extra1=%s\n" /* Sent */
+ "ColumnTitle$Extra2=%s\n" /* Received */
+ "ShowColumnHeaders=true\n"
+ "%s",
+ network_interfaces,
+ _("Interface"), _("IP Address"), _("Sent"), _("Received"),
+ network_icons);
}
gchar *callback_route()
{
- return g_strdup_printf(_("[IP routing table]\n"
+ return g_strdup_printf("[%s]\n"
"%s\n"
"[$ShellParam$]\n"
"ViewType=0\n"
"ReloadInterval=3000\n"
- "ColumnTitle$TextValue=Destination / Gateway\n"
- "ColumnTitle$Value=Interface\n"
- "ColumnTitle$Extra1=Flags\n"
- "ColumnTitle$Extra2=Mask\n"
- "ShowColumnHeaders=true\n"),
- __routing_table);
+ "ColumnTitle$TextValue=%s\n" /* Destination / Gateway */
+ "ColumnTitle$Value=%s\n" /* Interface */
+ "ColumnTitle$Extra1=%s\n" /* Flags */
+ "ColumnTitle$Extra2=%s\n" /* Mask */
+ "ShowColumnHeaders=true\n",
+ _("IP routing table"), __routing_table,
+ _("Destination/Gateway"), _("Interface"), _("Flags"), _("Mask") );
}
gchar *callback_statistics()
@@ -411,12 +414,12 @@ void hi_module_init(void)
void hi_module_deinit(void)
{
moreinfo_del_with_prefix("NET");
-
+
g_free(smb_shares_list);
g_free(nfs_shares_list);
g_free(network_interfaces);
g_free(network_icons);
-
+
g_free(__statistics);
g_free(__nameservers);
g_free(__arp_table);
diff --git a/modules/network/net.c b/modules/network/net.c
index ebb0612a..99a5e616 100644
--- a/modules/network/net.c
+++ b/modules/network/net.c
@@ -40,7 +40,7 @@
#include <linux/wireless.h>
#else
#include <net/if.h>
-#endif /* HAS_LINUX_WE */
+#endif /* HAS_LINUX_WE */
#include "hardinfo.h"
#include "network.h"
@@ -57,18 +57,26 @@ struct _NetInfo {
char broadcast[16];
#ifdef HAS_LINUX_WE
- char wi_essid[IW_ESSID_MAX_SIZE + 1];
+ char wi_essid[IW_ESSID_MAX_SIZE + 1];
int wi_rate;
int wi_mode, wi_status;
gboolean wi_has_txpower;
struct iw_param wi_txpower;
- int wi_quality_level, wi_signal_level, wi_noise_level;
+ int wi_quality_level, wi_signal_level, wi_noise_level;
gboolean is_wireless;
#endif
};
#ifdef HAS_LINUX_WE
-const gchar *wi_operation_modes[] = { "Auto", "Ad-Hoc", "Managed", "Master", "Repeater", "Secondary", "Unknown" };
+const gchar *wi_operation_modes[] = {
+ NC_("wi-op-mode", "Auto"),
+ NC_("wi-op-mode", "Ad-Hoc"),
+ NC_("wi-op-mode", "Managed"),
+ NC_("wi-op-mode", "Master"),
+ NC_("wi-op-mode", "Repeater"),
+ NC_("wi-op-mode", "Secondary"),
+ NC_("wi-op-mode", "(Unknown)")
+};
void get_wireless_info(int fd, NetInfo *netinfo)
{
@@ -78,16 +86,16 @@ void get_wireless_info(int fd, NetInfo *netinfo)
int r, trash;
netinfo->is_wireless = FALSE;
-
+
if ((wrls = fopen("/proc/net/wireless", "r"))) {
while (fgets(wbuf, 256, wrls)) {
if (strchr(wbuf, ':') && strstr(wbuf, netinfo->name)) {
gchar *buf1 = wbuf;
-
+
netinfo->is_wireless = TRUE;
-
+
buf1 = strchr(buf1, ':') + 1;
-
+
if (strchr(buf1, '.')) {
sscanf(buf1, "%d %d. %d. %d %d %d %d %d %d %d",
&(netinfo->wi_status),
@@ -104,7 +112,7 @@ void get_wireless_info(int fd, NetInfo *netinfo)
&trash, &trash, &trash, &trash, &trash,
&trash);
}
-
+
break;
}
}
@@ -113,14 +121,14 @@ void get_wireless_info(int fd, NetInfo *netinfo)
if (!netinfo->is_wireless)
return;
-
+
strncpy(wi_req.ifr_name, netinfo->name, 16);
-
+
/* obtain essid */
wi_req.u.essid.pointer = netinfo->wi_essid;
wi_req.u.essid.length = IW_ESSID_MAX_SIZE + 1;
wi_req.u.essid.flags = 0;
-
+
if (ioctl(fd, SIOCGIWESSID, &wi_req) < 0) {
strcpy(netinfo->wi_essid, "");
} else {
@@ -133,7 +141,7 @@ void get_wireless_info(int fd, NetInfo *netinfo)
} else {
netinfo->wi_rate = wi_req.u.bitrate.value;
}
-
+
/* obtain operation mode */
if (ioctl(fd, SIOCGIWMODE, &wi_req) < 0) {
netinfo->wi_mode = 0;
@@ -144,19 +152,19 @@ void get_wireless_info(int fd, NetInfo *netinfo)
netinfo->wi_mode = 6;
}
}
-
+
#if WIRELESS_EXT >= 10
/* obtain txpower */
if (ioctl(fd, SIOCGIWTXPOW, &wi_req) < 0) {
netinfo->wi_has_txpower = FALSE;
} else {
netinfo->wi_has_txpower = TRUE;
-
+
memcpy(&netinfo->wi_txpower, &wi_req.u.txpower, sizeof(struct iw_param));
}
#else
netinfo->wi_has_txpower = FALSE;
-#endif /* WIRELESS_EXT >= 10 */
+#endif /* WIRELESS_EXT >= 10 */
}
#endif /* HAS_LINUX_WE */
@@ -174,47 +182,47 @@ void get_net_info(char *if_name, NetInfo * netinfo)
/* MTU */
strcpy(ifr.ifr_name, if_name);
if (ioctl(fd, SIOCGIFMTU, &ifr) < 0) {
- netinfo->mtu = 0;
+ netinfo->mtu = 0;
} else {
- netinfo->mtu = ifr.ifr_mtu;
+ netinfo->mtu = ifr.ifr_mtu;
}
/* HW Address */
strcpy(ifr.ifr_name, if_name);
if (ioctl(fd, SIOCGIFHWADDR, &ifr) < 0) {
- memset(netinfo->mac, 0, 8);
+ memset(netinfo->mac, 0, 8);
} else {
- memcpy(netinfo->mac, ifr.ifr_ifru.ifru_hwaddr.sa_data, 8);
+ memcpy(netinfo->mac, ifr.ifr_ifru.ifru_hwaddr.sa_data, 8);
}
/* IP Address */
strcpy(ifr.ifr_name, if_name);
if (ioctl(fd, SIOCGIFADDR, &ifr) < 0) {
- netinfo->ip[0] = 0;
+ netinfo->ip[0] = 0;
} else {
- snprintf(netinfo->ip, sizeof(netinfo->ip), "%s",
- inet_ntoa(((struct sockaddr_in *) &ifr.ifr_addr)->
- sin_addr));
+ snprintf(netinfo->ip, sizeof(netinfo->ip), "%s",
+ inet_ntoa(((struct sockaddr_in *) &ifr.ifr_addr)->
+ sin_addr));
}
/* Mask Address */
strcpy(ifr.ifr_name, if_name);
if (ioctl(fd, SIOCGIFNETMASK, &ifr) < 0) {
- netinfo->mask[0] = 0;
+ netinfo->mask[0] = 0;
} else {
- snprintf(netinfo->mask, sizeof(netinfo->mask), "%s",
- inet_ntoa(((struct sockaddr_in *) &ifr.ifr_addr)->
- sin_addr));
+ snprintf(netinfo->mask, sizeof(netinfo->mask), "%s",
+ inet_ntoa(((struct sockaddr_in *) &ifr.ifr_addr)->
+ sin_addr));
}
/* Broadcast Address */
strcpy(ifr.ifr_name, if_name);
if (ioctl(fd, SIOCGIFBRDADDR, &ifr) < 0) {
- netinfo->broadcast[0] = 0;
+ netinfo->broadcast[0] = 0;
} else {
- snprintf(netinfo->broadcast, sizeof(netinfo->broadcast), "%s",
- inet_ntoa(((struct sockaddr_in *) &ifr.ifr_addr)->
- sin_addr));
+ snprintf(netinfo->broadcast, sizeof(netinfo->broadcast), "%s",
+ inet_ntoa(((struct sockaddr_in *) &ifr.ifr_addr)->
+ sin_addr));
}
#ifdef HAS_LINUX_WE
@@ -230,34 +238,41 @@ static struct {
char *label;
char *icon;
} netdev2type[] = {
- { "eth", "Ethernet", "network-interface" },
- { "lo", "Loopback", "network" },
- { "ppp", "Point-to-Point", "modem" },
- { "ath", "Wireless", "wireless" },
- { "wlan", "Wireless", "wireless" },
- { "ra", "Wireless", "wireless" },
- { "wl", "Wireless", "wireless" },
- { "wmaster", "Wireless", "wireless" },
- { "tun", "Virtual Point-to-Point (TUN)", "network" },
- { "tap", "Ethernet (TAP)", "network" },
- { "plip", "Parallel Line Internet Protocol", "network" },
- { "irlan", "Infrared", "network" },
- { "slip", "Serial Line Internet Protocol", "network" },
- { "isdn", "Integrated Services Digital Network", "modem" },
- { "sit", "IPv6-over-IPv4 Tunnel", "network" },
- { "vmnet8", "VMWare Virtual Network Interface (NAT)", "computer" },
- { "vmnet", "VMWare Virtual Network Interface", "computer" },
- { "pan", "Personal Area Network (PAN)", "bluetooth" },
- { "bnep", "Bluetooth", "bluetooth" },
- { "br", "Bridge Interface", "network" },
- { "ham", "Hamachi Virtual Personal Network", "network"},
- { "net", "Ethernet", "network-interface" },
- { "ifb", "Intermediate Functional Block", "network" },
- { "gre", "GRE Network Tunnel", "network" },
- { "msh", "Mesh Network", "wireless" },
- { "wmaster", "Wireless Master Interface", "wireless" },
- { "vboxnet", "VirtualBox Virtual Network Interface", "network" },
- { NULL, "Unknown", "network" },
+ /* Classic */
+ { "eth", NC_("net-if-type", "Ethernet"), "network-interface" },
+ { "lo", NC_("net-if-type", "Loopback"), "network" },
+ { "ppp", NC_("net-if-type", "Point-to-Point"), "modem" },
+ { "ath", NC_("net-if-type", "Wireless"), "wireless" },
+ { "wlan", NC_("net-if-type", "Wireless"), "wireless" },
+ { "ra", NC_("net-if-type", "Wireless"), "wireless" },
+ { "wmaster", NC_("net-if-type", "Wireless"), "wireless" },
+ { "tun", NC_("net-if-type", "Virtual Point-to-Point (TUN)"), "network" },
+ { "tap", NC_("net-if-type", "Ethernet (TAP)"), "network" },
+ { "plip", NC_("net-if-type", "Parallel Line Internet Protocol"), "network" },
+ { "irlan", NC_("net-if-type", "Infrared"), "network" },
+ { "slip", NC_("net-if-type", "Serial Line Internet Protocol"), "network" },
+ { "isdn", NC_("net-if-type", "Integrated Services Digital Network"), "modem" },
+ { "sit", NC_("net-if-type", "IPv6-over-IPv4 Tunnel"), "network" },
+ { "vmnet8", NC_("net-if-type", "VMWare Virtual Network Interface (NAT)"), "computer" },
+ { "vmnet", NC_("net-if-type", "VMWare Virtual Network Interface"), "computer" },
+ { "pan", NC_("net-if-type", "Personal Area Network (PAN)"), "bluetooth" },
+ { "bnep", NC_("net-if-type", "Bluetooth"), "bluetooth" },
+ { "br", NC_("net-if-type", "Bridge Interface"), "network" },
+ { "ham", NC_("net-if-type", "Hamachi Virtual Personal Network"), "network"},
+ { "net", NC_("net-if-type", "Ethernet"), "network-interface" },
+ { "ifb", NC_("net-if-type", "Intermediate Functional Block"), "network" },
+ { "gre", NC_("net-if-type", "GRE Network Tunnel"), "network" },
+ { "msh", NC_("net-if-type", "Mesh Network"), "wireless" },
+ { "wmaster", NC_("net-if-type", "Wireless Master Interface"), "wireless" },
+ { "vboxnet", NC_("net-if-type", "VirtualBox Virtual Network Interface"), "network" },
+
+ /* Predictable network interface device names (systemd) */
+ { "en", NC_("net-if-type", "Ethernet"), "network-interface" },
+ { "sl", NC_("net-if-type", "Serial Line Internet Protocol"), "network" },
+ { "wl", NC_("net-if-type", "Wireless"), "wireless" },
+ { "ww", NC_("net-if-type", "Wireless (WAN)"), "wireless" },
+
+ { NULL, NC_("net-if-type", "(Unknown)"), "network" },
};
static void net_get_iface_type(gchar * name, gchar ** type, gchar ** icon, NetInfo *ni)
@@ -266,19 +281,19 @@ static void net_get_iface_type(gchar * name, gchar ** type, gchar ** icon, NetIn
#ifdef HAS_LINUX_WE
if (ni->is_wireless) {
- *type = "Wireless";
+ *type = "Wireless"; /* translated when used */
*icon = "wireless";
-
+
return;
}
#endif
for (i = 0; netdev2type[i].type; i++) {
- if (g_str_has_prefix(name, netdev2type[i].type))
- break;
+ if (g_str_has_prefix(name, netdev2type[i].type))
+ break;
}
- *type = netdev2type[i].label;
+ *type = netdev2type[i].label; /* translated when used */
*icon = netdev2type[i].icon;
}
@@ -288,6 +303,30 @@ remove_net_devices(gpointer key, gpointer value, gpointer data)
return g_str_has_prefix(key, "NET");
}
+#ifdef HAS_LINUX_WE
+const char *wifi_bars(int signal, int noise)
+{
+ float quality;
+
+ if (signal <= -100)
+ quality = 0.0;
+ else if (signal >= -50)
+ quality = 1.0;
+ else
+ quality = (2.0 * (signal + 100.0)) / 100.0;
+
+ if (quality < 0.20)
+ return "▰▱▱▱▱";
+ if (quality < 0.40)
+ return "▰▰▱▱▱";
+ if (quality < 0.60)
+ return "▰▰▰▱▱";
+ if (quality < 0.80)
+ return "▰▰▰▰▱";
+ return "▰▰▰▰▰";
+}
+#endif
+
static void scan_net_interfaces_24(void)
{
FILE *proc_net;
@@ -303,20 +342,20 @@ static void scan_net_interfaces_24(void)
gdouble trans_packets;
if (!g_file_test("/proc/net/dev", G_FILE_TEST_EXISTS)) {
- if (network_interfaces) {
- g_free(network_interfaces);
- network_interfaces = g_strdup("[Network Interfaces]\n"
- "None found=\n");
- }
+ if (network_interfaces) {
+ g_free(network_interfaces);
+ network_interfaces = g_strdup_printf("[%s]]\n%s=\n",
+ _("Network Interfaces"), _("None Found") );
+ }
- return;
+ return;
}
g_free(network_interfaces);
g_free(network_icons);
- network_interfaces = g_strdup("[Network Interfaces]\n");
+ network_interfaces = g_strdup_printf("[%s]\n", _("Network Interfaces"));
network_icons = g_strdup("");
proc_net = fopen("/proc/net/dev", "r");
@@ -324,118 +363,126 @@ static void scan_net_interfaces_24(void)
return;
while (fgets(buffer, 256, proc_net)) {
- if (strchr(buffer, ':')) {
- gint trash;
- gchar ifacename[16];
- gchar *buf = buffer;
- gchar *iface_type, *iface_icon;
- gint i;
-
- buf = g_strstrip(buf);
-
- memset(ifacename, 0, 16);
-
- for (i = 0; buffer[i] != ':' && i < 16; i++) {
- ifacename[i] = buffer[i];
- }
-
- buf = strchr(buf, ':') + 1;
-
- /* iface: bytes packets errs drop fifo frame compressed multicast */
- sscanf(buf, "%lf %lf %lf %d %d %d %d %d %lf %lf %lf",
- &recv_bytes, &recv_packets,
- &recv_errors, &trash, &trash, &trash, &trash,
- &trash, &trans_bytes, &trans_packets, &trans_errors);
-
- gdouble recv_mb = recv_bytes / 1048576.0;
- gdouble trans_mb = trans_bytes / 1048576.0;
-
- get_net_info(ifacename, &ni);
-
- devid = g_strdup_printf("NET%s", ifacename);
-
- network_interfaces =
- h_strdup_cprintf
- ("$%s$%s=%s|%.2lfMiB|%.2lfMiB\n",
- network_interfaces, devid, ifacename, ni.ip[0] ? ni.ip : "",
- trans_mb, recv_mb);
- net_get_iface_type(ifacename, &iface_type, &iface_icon, &ni);
-
- network_icons = h_strdup_cprintf("Icon$%s$%s=%s.png\n",
- network_icons, devid,
- ifacename, iface_icon);
-
- detailed = g_strdup_printf("[Network Adapter Properties]\n"
- "Interface Type=%s\n"
- "Hardware Address (MAC)=%02x:%02x:%02x:%02x:%02x:%02x\n"
- "MTU=%d\n"
- "[Transfer Details]\n"
- "Bytes Received=%.0lf (%.2fMiB)\n"
- "Bytes Sent=%.0lf (%.2fMiB)\n",
- iface_type,
- ni.mac[0], ni.mac[1],
- ni.mac[2], ni.mac[3],
- ni.mac[4], ni.mac[5],
- ni.mtu,
- recv_bytes, recv_mb,
- trans_bytes, trans_mb);
-
+ if (strchr(buffer, ':')) {
+ gint trash;
+ gchar ifacename[16];
+ gchar *buf = buffer;
+ gchar *iface_type, *iface_icon;
+ gint i;
+
+ buf = g_strstrip(buf);
+
+ memset(ifacename, 0, 16);
+
+ for (i = 0; buffer[i] != ':' && i < 16; i++) {
+ ifacename[i] = buffer[i];
+ }
+
+ buf = strchr(buf, ':') + 1;
+
+ /* iface: bytes packets errs drop fifo frame compressed multicast */
+ sscanf(buf, "%lf %lf %lf %d %d %d %d %d %lf %lf %lf",
+ &recv_bytes, &recv_packets,
+ &recv_errors, &trash, &trash, &trash, &trash,
+ &trash, &trans_bytes, &trans_packets, &trans_errors);
+
+ gdouble recv_mb = recv_bytes / 1048576.0;
+ gdouble trans_mb = trans_bytes / 1048576.0;
+
+ get_net_info(ifacename, &ni);
+
+ devid = g_strdup_printf("NET%s", ifacename);
+
+ network_interfaces =
+ h_strdup_cprintf
+ ("$%s$%s=%s|%.2lf%s|%.2lf%s\n",
+ network_interfaces, devid, ifacename, ni.ip[0] ? ni.ip : "",
+ trans_mb, _("MiB"), recv_mb, _("MiB"));
+ net_get_iface_type(ifacename, &iface_type, &iface_icon, &ni);
+
+ network_icons = h_strdup_cprintf("Icon$%s$%s=%s.png\n",
+ network_icons, devid,
+ ifacename, iface_icon);
+
+ detailed = g_strdup_printf("[%s]\n"
+ "%s=%s\n" /* Interface Type */
+ "%s=%02x:%02x:%02x:%02x:%02x:%02x\n" /* MAC */
+ "%s=%d\n" /* MTU */
+ "[%s]\n" /*Transfer Details*/
+ "%s=%.0lf (%.2f%s)\n" /* Bytes Received */
+ "%s=%.0lf (%.2f%s)\n" /* Bytes Sent */,
+ _("Network Adapter Properties"),
+ _("Interface Type"), C_("net-if-type", iface_type),
+ _("Hardware Address (MAC)"),
+ ni.mac[0], ni.mac[1],
+ ni.mac[2], ni.mac[3],
+ ni.mac[4], ni.mac[5],
+ _("MTU"), ni.mtu,
+ _("Transfer Details"),
+ _("Bytes Received"), recv_bytes, recv_mb, _("MiB"),
+ _("Bytes Sent"), trans_bytes, trans_mb, _("MiB"));
+
#ifdef HAS_LINUX_WE
- if (ni.is_wireless) {
- gchar *txpower;
-
- if (ni.wi_has_txpower) {
+ if (ni.is_wireless) {
+ gchar *txpower;
+
+ if (ni.wi_has_txpower) {
gint mw, dbm;
-
+
if (ni.wi_txpower.flags & IW_TXPOW_MWATT) {
- mw = ni.wi_txpower.value;
- dbm = (int) ceil(10.0 * log10((double) ni.wi_txpower.value));
+ mw = ni.wi_txpower.value;
+ dbm = (int) ceil(10.0 * log10((double) ni.wi_txpower.value));
} else {
- dbm = ni.wi_txpower.value;
- mw = (int) floor(pow(10.0, ((double) dbm / 10.0)));
+ dbm = ni.wi_txpower.value;
+ mw = (int) floor(pow(10.0, ((double) dbm / 10.0)));
}
-
- txpower = g_strdup_printf("%ddBm (%dmW)", dbm, mw);
- } else {
- txpower = g_strdup("Unknown");
- }
-
- detailed = h_strdup_cprintf("\n[Wireless Properties]\n"
- "Network Name (SSID)=%s\n"
- "Bit Rate=%dMb/s\n"
- "Transmission Power=%s\n"
- "Mode=%s\n"
- "Status=%d\n"
- "Link Quality=%d\n"
- "Signal / Noise=%d dBm / %d dBm\n",
- detailed,
- ni.wi_essid,
- ni.wi_rate / 1000000,
- txpower,
- wi_operation_modes[ni.wi_mode],
- ni.wi_status,
- ni.wi_quality_level,
- ni.wi_signal_level,
- ni.wi_noise_level);
-
- g_free(txpower);
+
+ txpower = g_strdup_printf("%d%s (%d%s)", dbm, _("dBm"), mw, _("mW"));
+ } else {
+ txpower = g_strdup(_("(Unknown)"));
}
+
+ detailed = h_strdup_cprintf("\n[%s]\n"
+ "%s=%s\n" /* Network Name (SSID) */
+ "%s=%d%s\n" /* Bit Rate */
+ "%s=%s\n" /* Transmission Power */
+ "%s=%s\n" /* Mode */
+ "%s=%d\n" /* Status */
+ "%s=%d\n" /* Link Quality */
+ "%s=%d %s / %d %s (%s)\n",
+ detailed,
+ _("Wireless Properties"),
+ _("Network Name (SSID)"), ni.wi_essid,
+ _("Bit Rate"), ni.wi_rate / 1000000, _("Mb/s"),
+ _("Transmission Power"), txpower,
+ _("Mode"), C_("wi-op-mode", wi_operation_modes[ni.wi_mode]),
+ _("Status"), ni.wi_status,
+ _("Link Quality"), ni.wi_quality_level,
+ _("Signal / Noise"),
+ ni.wi_signal_level, _("dBm"),
+ ni.wi_noise_level, _("dBm"),
+ wifi_bars(ni.wi_signal_level, ni.wi_noise_level));
+
+ g_free(txpower);
+ }
#endif
- if (ni.ip[0] || ni.mask[0] || ni.broadcast[0]) {
- detailed =
- h_strdup_cprintf("\n[Internet Protocol (IPv4)]\n"
- "IP Address=%s\n" "Mask=%s\n"
- "Broadcast Address=%s\n", detailed,
- ni.ip[0] ? ni.ip : "Not set",
- ni.mask[0] ? ni.mask : "Not set",
- ni.broadcast[0] ? ni.
- broadcast : "Not set");
- }
-
- moreinfo_add_with_prefix("NET", devid, detailed);
- g_free(devid);
- }
+ if (ni.ip[0] || ni.mask[0] || ni.broadcast[0]) {
+ detailed =
+ h_strdup_cprintf("\n[%s]\n"
+ "%s=%s\n"
+ "%s=%s\n"
+ "%s=%s\n", detailed,
+ _("Internet Protocol (IPv4)"),
+ _("IP Address"), ni.ip[0] ? ni.ip : _("(Not set)"),
+ _("Mask"), ni.mask[0] ? ni.mask : _("(Not set)"),
+ _("Broadcast Address"),
+ ni.broadcast[0] ? ni.broadcast : _("(Not set)") );
+ }
+
+ moreinfo_add_with_prefix("NET", devid, detailed);
+ g_free(devid);
+ }
}
fclose(proc_net);
}