aboutsummaryrefslogtreecommitdiff
path: root/modules/computer
diff options
context:
space:
mode:
Diffstat (limited to 'modules/computer')
-rw-r--r--modules/computer/alsa.c71
-rw-r--r--modules/computer/boots.c68
-rw-r--r--modules/computer/display.c74
-rw-r--r--modules/computer/environment.c45
-rw-r--r--modules/computer/filesystem.c108
-rw-r--r--modules/computer/groups.c45
-rw-r--r--modules/computer/languages.c182
-rw-r--r--modules/computer/loadavg.c68
-rw-r--r--modules/computer/memory.c62
-rw-r--r--modules/computer/memory_usage.c125
-rw-r--r--modules/computer/modules.c400
-rw-r--r--modules/computer/os.c582
-rw-r--r--modules/computer/ubuntu_flavors.c90
-rw-r--r--modules/computer/uptime.c72
-rw-r--r--modules/computer/users.c61
15 files changed, 2053 insertions, 0 deletions
diff --git a/modules/computer/alsa.c b/modules/computer/alsa.c
new file mode 100644
index 00000000..f74d2752
--- /dev/null
+++ b/modules/computer/alsa.c
@@ -0,0 +1,71 @@
+/*
+ * HardInfo - Displays System Information
+ * Copyright (C) 2003-2006 L. A. F. Pereira <l@tia.mat.br>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, version 2 or later.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "hardinfo.h"
+#include "computer.h"
+
+gchar *
+computer_get_alsacards(Computer * computer)
+{
+ GSList *p;
+ 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;
+
+ tmp = h_strdup_cprintf("%s#%d=%s\n", tmp,
+ _("Audio Adapter"), ++n, ac->friendly_name);
+ }
+ }
+
+ return tmp;
+}
+
+AlsaInfo *
+computer_get_alsainfo(void)
+{
+ AlsaInfo *ai;
+ AlsaCard *ac;
+ FILE *cards;
+ gchar buffer[128];
+
+ cards = fopen("/proc/asound/cards", "r");
+ if (!cards)
+ return NULL;
+
+ ai = g_new0(AlsaInfo, 1);
+
+ while (fgets(buffer, 128, cards)) {
+ gchar **tmp;
+
+ ac = g_new0(AlsaCard, 1);
+
+ tmp = g_strsplit(buffer, ":", 0);
+
+ 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 */
+ }
+ fclose(cards);
+
+ return ai;
+}
diff --git a/modules/computer/boots.c b/modules/computer/boots.c
new file mode 100644
index 00000000..52c122e4
--- /dev/null
+++ b/modules/computer/boots.c
@@ -0,0 +1,68 @@
+/*
+ * HardInfo - Displays System Information
+ * Copyright (C) 2003-2007 L. A. F. Pereira <l@tia.mat.br>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, version 2 or later.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include "hardinfo.h"
+#include "computer.h"
+
+extern void scan_os(gboolean reload);
+
+void
+scan_boots_real(void)
+{
+ gchar **tmp;
+ gboolean spawned;
+ gchar *out, *err, *p, *s, *next_nl;
+
+ scan_os(FALSE);
+
+ if (!computer->os->boots)
+ computer->os->boots = strdup("");
+ else
+ return;
+
+ spawned = hardinfo_spawn_command_line_sync("last",
+ &out, &err, NULL, NULL);
+ if (spawned && out != NULL) {
+ p = out;
+ while(next_nl = strchr(p, '\n')) {
+ strend(p, '\n');
+ if (strstr(p, "system boot")) {
+ s = p;
+ while (*s) {
+ if (*s == ' ' && *(s + 1) == ' ') {
+ memmove(s, s + 1, strlen(s) + 1);
+ s--;
+ } else {
+ s++;
+ }
+ }
+ tmp = g_strsplit(p, " ", 0);
+ computer->os->boots =
+ h_strdup_cprintf("\n%s %s %s %s=%s",
+ computer->os->boots,
+ tmp[4], tmp[5], tmp[6], tmp[7], tmp[3]);
+ g_strfreev(tmp);
+ }
+ p = next_nl + 1;
+ }
+ g_free(out);
+ g_free(err);
+ }
+}
diff --git a/modules/computer/display.c b/modules/computer/display.c
new file mode 100644
index 00000000..98cb7bf7
--- /dev/null
+++ b/modules/computer/display.c
@@ -0,0 +1,74 @@
+/*
+ * HardInfo - Displays System Information
+ * Copyright (C) 2003-2007 L. A. F. Pereira <l@tia.mat.br>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, version 2 or later.
+ *
+ * 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 "computer.h"
+
+DisplayInfo *computer_get_display(void) {
+ DisplayInfo *di = g_new0(DisplayInfo, 1);
+ wl_info *wl = get_walyand_info();
+ xinfo *xi = xinfo_get_info();
+ xrr_info *xrr = xi->xrr;
+ glx_info *glx = xi->glx;
+
+ di->width = di->height = 0;
+ if (xrr->screen_count > 0) {
+ di->width = xrr->screens[0].px_width;
+ di->height = xrr->screens[0].px_height;
+ }
+ di->vendor = xi->vendor;
+ di->session_type = wl->xdg_session_type;
+
+ if (strcmp(di->session_type, "x11") == 0 ) {
+ if (xi->nox) {
+ di->display_server = g_strdup(_("(Unknown)"));
+ /* assumed x11 previously, because it wasn't set */
+ free(wl->xdg_session_type);
+ di->session_type = wl->xdg_session_type = NULL;
+ } else if (xi->vendor && xi->version)
+ di->display_server = g_strdup_printf("%s %s", xi->vendor, xi->version );
+ else if (xi->vendor && xi->release_number)
+ di->display_server = g_strdup_printf("[X11] %s %s", xi->vendor, xi->release_number );
+ else
+ di->display_server = g_strdup("X11");
+ } else
+ if (strcmp(di->session_type, "wayland") == 0 ) {
+ di->display_server = g_strdup("Wayland");
+ } else
+ if (strcmp(di->session_type, "mir") == 0 ) {
+ di->display_server = g_strdup("Mir");
+ } else {
+ di->display_server = g_strdup(_("(Unknown)"));
+ }
+
+ di->xi = xi;
+ di->wl = wl;
+ return di;
+}
+
+void computer_free_display(DisplayInfo *di) {
+ /* fyi: DisplayInfo is in computer.h */
+ if (di) {
+ free(di->display_server);
+ xinfo_free(di->xi);
+ wl_free(di->wl);
+ free(di);
+ }
+}
diff --git a/modules/computer/environment.c b/modules/computer/environment.c
new file mode 100644
index 00000000..2f29c861
--- /dev/null
+++ b/modules/computer/environment.c
@@ -0,0 +1,45 @@
+/*
+ * HardInfo - Displays System Information
+ * Copyright (C) 2003-2008 L. A. F. Pereira <l@tia.mat.br>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, version 2 or later.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "hardinfo.h"
+#include "computer.h"
+
+static gchar *_env = NULL;
+void scan_env_var(gboolean reload)
+{
+ SCAN_START();
+
+ gchar **envlist;
+ gint i;
+
+ g_free(_env);
+
+ _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();
+}
+
+gchar *callback_env_var(void)
+{
+ return g_strdup(_env);
+}
diff --git a/modules/computer/filesystem.c b/modules/computer/filesystem.c
new file mode 100644
index 00000000..e9c84811
--- /dev/null
+++ b/modules/computer/filesystem.c
@@ -0,0 +1,108 @@
+/*
+ * HardInfo - Displays System Information
+ * Copyright (C) 2003-2006 L. A. F. Pereira <l@tia.mat.br>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, version 2 or later.
+ *
+ * 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
+ *
+ * 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.
+ */
+
+#include <string.h>
+#include <sys/vfs.h>
+#include "hardinfo.h"
+#include "computer.h"
+
+gchar *fs_list = NULL;
+
+void
+scan_filesystems(void)
+{
+ FILE *mtab;
+ gchar buf[1024];
+ struct statfs sfs;
+ int count = 0;
+
+ g_free(fs_list);
+ fs_list = g_strdup("");
+ moreinfo_del_with_prefix("COMP:FS");
+
+ mtab = fopen("/etc/mtab", "r");
+ if (!mtab)
+ 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;
+
+ gboolean rw = strstr(tmp[3], "rw") != NULL;
+
+ 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"), rw ? _("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%s=%.2f %% (%s of %s)|%s\n",
+ fs_list,
+ count, tmp[0], rw ? "" : "🔒",
+ 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/groups.c b/modules/computer/groups.c
new file mode 100644
index 00000000..9371e211
--- /dev/null
+++ b/modules/computer/groups.c
@@ -0,0 +1,45 @@
+/*
+ * HardInfo - Displays System Information
+ * Copyright (C) 2012 L. A. F. Pereira <l@tia.mat.br>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, version 2 or later.
+ *
+ * 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 <sys/types.h>
+#include <grp.h>
+#include "hardinfo.h"
+#include "computer.h"
+
+gchar *groups = NULL;
+
+void
+scan_groups_do(void)
+{
+ struct group *group_;
+
+ setgrent();
+ group_ = getgrent();
+ if (!group_)
+ return;
+
+ g_free(groups);
+ groups = g_strdup("");
+
+ while (group_) {
+ groups = h_strdup_cprintf("%s=%d\n", groups, group_->gr_name, group_->gr_gid);
+ group_ = getgrent();
+ }
+
+ endgrent();
+}
diff --git a/modules/computer/languages.c b/modules/computer/languages.c
new file mode 100644
index 00000000..b2d4910f
--- /dev/null
+++ b/modules/computer/languages.c
@@ -0,0 +1,182 @@
+/*
+ * HardInfo - Displays System Information
+ * Copyright (C) 2003-2007 L. A. F. Pereira <l@tia.mat.br>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, version 2 or later.
+ *
+ * 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 "computer.h"
+#include "cpu_util.h" /* for UNKIFNULL() */
+
+typedef struct {
+ gchar name[32];
+ gchar *title,
+ *source,
+ *address,
+ *email,
+ *language,
+ *territory,
+ *revision,
+ *date,
+ *codeset;
+} locale_info;
+
+void locale_info_free(locale_info *s) {
+ if (s) {
+ g_free(s->title);
+ g_free(s->source);
+ g_free(s->address);
+ g_free(s->email);
+ g_free(s->language);
+ g_free(s->territory);
+ g_free(s->revision);
+ g_free(s->date);
+ g_free(s->codeset);
+ free(s);
+ }
+}
+
+/* TODO: use info_* */
+gchar *locale_info_section(locale_info *s) {
+ gchar *name = g_strdup(s->name);
+ gchar *title = g_strdup(s->title),
+ *source = g_strdup(s->source),
+ *address = g_strdup(s->address),
+ *email = g_strdup(s->email),
+ *language = g_strdup(s->language),
+ *territory = g_strdup(s->territory),
+ *revision = g_strdup(s->revision),
+ *date = g_strdup(s->date),
+ *codeset = g_strdup(s->codeset);
+
+ 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);
+
+ gchar *ret = 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 );
+ g_free(name);
+ 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);
+ return ret;
+}
+
+void
+scan_languages(OperatingSystem * os)
+{
+ gboolean spawned;
+ gchar *out, *err, *p, *next_nl;
+
+ gchar *ret = NULL;
+ locale_info *curr = NULL;
+ int last = 0;
+
+ spawned = hardinfo_spawn_command_line_sync("locale -va",
+ &out, &err, NULL, NULL);
+ if (spawned) {
+ ret = g_strdup("");
+ p = out;
+ while(1) {
+ /* `locale -va` doesn't end the last locale block
+ * with an \n, which makes this more complicated */
+ next_nl = strchr(p, '\n');
+ if (next_nl == NULL)
+ next_nl = strchr(p, 0);
+ last = (*next_nl == 0) ? 1 : 0;
+ strend(p, '\n');
+ if (strncmp(p, "locale:", 7) == 0) {
+ curr = g_new0(locale_info, 1);
+ sscanf(p, "locale: %s", curr->name);
+ /* TODO: 'directory:' and 'archive:' */
+ } else if (strchr(p, '|')) {
+ do {/* get_str() has a continue in it,
+ * how fn frustrating that was to figure out */
+ gchar **tmp = g_strsplit(p, "|", 2);
+ tmp[0] = g_strstrip(tmp[0]);
+ if (tmp[1]) {
+ tmp[1] = g_strstrip(tmp[1]);
+ get_str("title", curr->title);
+ get_str("source", curr->source);
+ get_str("address", curr->address);
+ get_str("email", curr->email);
+ get_str("language", curr->language);
+ get_str("territory", curr->territory);
+ get_str("revision", curr->revision);
+ get_str("date", curr->date);
+ get_str("codeset", curr->codeset);
+ }
+ g_strfreev(tmp);
+ } while (0);
+ } else if (strstr(p, "------")) {
+ /* do nothing */
+ } else if (curr) {
+ /* a blank line is the end of a locale */
+ gchar *li_str = locale_info_section(curr);
+ gchar *clean_title = hardinfo_clean_value(curr->title, 0); /* may contain & */
+ ret = h_strdup_cprintf("$%s$%s=%s\n", ret, curr->name, curr->name, clean_title);
+ moreinfo_add_with_prefix("COMP", g_strdup(curr->name), li_str); /* becomes owned by moreinfo */
+ locale_info_free(curr);
+ curr = NULL;
+ g_free(clean_title);
+ }
+ if (last) break;
+ p = next_nl + 1;
+ }
+ g_free(out);
+ g_free(err);
+ }
+ os->languages = ret;
+}
diff --git a/modules/computer/loadavg.c b/modules/computer/loadavg.c
new file mode 100644
index 00000000..802ae2aa
--- /dev/null
+++ b/modules/computer/loadavg.c
@@ -0,0 +1,68 @@
+/*
+ * HardInfo - Displays System Information
+ * Copyright (C) 2003-2006 L. A. F. Pereira <l@tia.mat.br>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, version 2 or later.
+ *
+ * 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 "computer.h"
+
+static gboolean
+computer_get_loadinfo(LoadInfo *li)
+{
+ FILE *procloadavg;
+ char buf[64];
+ int ret;
+
+ procloadavg = fopen("/proc/loadavg", "r");
+ if (!procloadavg)
+ return FALSE;
+
+ if (!fgets(buf, sizeof(buf), procloadavg)) {
+ fclose(procloadavg);
+ return FALSE;
+ }
+
+ ret = sscanf(buf, "%f %f %f", &li->load1, &li->load5, &li->load15);
+ if (ret != 3) {
+ size_t len = strlen(buf);
+ size_t i;
+
+ for (i = 0; i < len; i++) {
+ if (buf[i] == '.')
+ buf[i] = ',';
+ }
+
+ ret = sscanf(buf, "%f %f %f", &li->load1, &li->load5, &li->load15);
+ }
+
+ fclose(procloadavg);
+
+ return ret == 3;
+}
+
+gchar *
+computer_get_formatted_loadavg()
+{
+ LoadInfo li;
+
+ if (!computer_get_loadinfo(&li))
+ return g_strdup(_("Couldn't obtain load average"));
+
+ return g_strdup_printf("%.2f, %.2f, %.2f", li.load1, li.load5,
+ li.load15);
+}
diff --git a/modules/computer/memory.c b/modules/computer/memory.c
new file mode 100644
index 00000000..994e4040
--- /dev/null
+++ b/modules/computer/memory.c
@@ -0,0 +1,62 @@
+/*
+ * HardInfo - Displays System Information
+ * Copyright (C) 2003-2006 L. A. F. Pereira <l@tia.mat.br>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, version 2 or later.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "hardinfo.h"
+#include "computer.h"
+
+MemoryInfo *
+computer_get_memory(void)
+{
+ MemoryInfo *mi;
+ FILE *procmem;
+ gchar buffer[128];
+
+ procmem = fopen("/proc/meminfo", "r");
+ if (!procmem)
+ return NULL;
+ mi = g_new0(MemoryInfo, 1);
+
+ while (fgets(buffer, 128, procmem)) {
+ 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;
+ mi->cached /= 1000;
+ mi->used /= 1000;
+ mi->free /= 1000;
+
+ mi->used -= mi->cached;
+ mi->ratio = 1 - (gdouble) mi->used / mi->total;
+
+ return mi;
+}
diff --git a/modules/computer/memory_usage.c b/modules/computer/memory_usage.c
new file mode 100644
index 00000000..12c62fe7
--- /dev/null
+++ b/modules/computer/memory_usage.c
@@ -0,0 +1,125 @@
+/*
+ * HardInfo - Displays System Information
+ * Copyright (C) 2003-2007 L. A. F. Pereira <l@tia.mat.br>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, version 2 or later.
+ *
+ * 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 "devices.h"
+
+GHashTable *memlabels = NULL;
+
+void scan_memory_do(void)
+{
+ gchar **keys, *tmp, *tmp_label, *trans_val;
+ 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.
+ * The lines look something like this:
+ * total: used: free: shared: buffers: cached:
+ * Mem: 3301101568 1523159040 1777942528 0 3514368 1450356736
+ * Swap: 0 0 0
+ */
+ gchar *os_kernel = module_call_method("computer::getOSKernel");
+ if (os_kernel) {
+ offset = strstr(os_kernel, "Linux 2.4") ? 3 : 0;
+ g_free(os_kernel);
+ } else {
+ 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]);
+
+ /* 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... */
+
+ if (strstr(newkeys[1], "kB")) {
+ trans_val = g_strdup_printf("%d %s", atoi(newkeys[1]), _("KiB") );
+ } else {
+ trans_val = strdup(newkeys[1]);
+ }
+
+ moreinfo_add_with_prefix("DEV", newkeys[0], g_strdup(trans_val));
+
+ tmp = g_strconcat(meminfo, newkeys[0], "=", trans_val, "|", tmp_label, "\n", NULL);
+ g_free(meminfo);
+ meminfo = tmp;
+
+ g_free(trans_val);
+
+ tmp = g_strconcat(lginterval,
+ "UpdateInterval$", newkeys[0], "=1000\n", NULL);
+ g_free(lginterval);
+ lginterval = tmp;
+
+ g_strfreev(newkeys);
+ }
+ g_strfreev(keys);
+}
+
+void init_memory_labels(void)
+{
+ static const struct {
+ 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") },
+ { 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/computer/modules.c b/modules/computer/modules.c
new file mode 100644
index 00000000..14028362
--- /dev/null
+++ b/modules/computer/modules.c
@@ -0,0 +1,400 @@
+/*
+ * HardInfo - Displays System Information
+ * Copyright (C) 2003-2006 L. A. F. Pereira <l@tia.mat.br>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, version 2 or later.
+ *
+ * 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 <sys/utsname.h>
+#include <json-glib/json-glib.h>
+
+#include "syncmanager.h"
+#include "computer.h"
+#include "cpu_util.h" /* for STRIFNULL() */
+#include "hardinfo.h"
+
+#define GET_STR(field_name, ptr) \
+ if (!ptr && strstr(tmp[0], field_name)) { \
+ ptr = g_markup_escape_text(g_strstrip(tmp[1]), strlen(tmp[1])); \
+ g_strfreev(tmp); \
+ continue; \
+ }
+
+GHashTable *_module_hash_table = NULL;
+static gchar *kernel_modules_dir = NULL;
+
+enum icons {
+ ICON_INVALID = 0,
+
+ ICON_AUDIO,
+ ICON_BLUETOOTH,
+ ICON_CAMERA_WEB,
+ ICON_CDROM,
+ ICON_CRYPTOHASH,
+ ICON_DEVICES,
+ ICON_HDD,
+ ICON_INPUTDEVICES,
+ ICON_JOYSTICK,
+ ICON_KEYBOARD,
+ ICON_MEDIA_FLOPPY,
+ ICON_MEDIA_REMOVABLE,
+ ICON_MEMORY,
+ ICON_MONITOR,
+ ICON_MOUSE,
+ ICON_NETWORK,
+ ICON_NETWORK_CONNECTIONS,
+ ICON_NETWORK_INTERFACE,
+ ICON_THERM,
+ ICON_USB,
+ ICON_WIRELESS,
+
+ ICON_MAX,
+};
+
+static const char *icon_table[ICON_MAX] = {
+ [ICON_AUDIO] = "audio",
+ [ICON_BLUETOOTH] = "bluetooth",
+ [ICON_CAMERA_WEB] = "camera-web",
+ [ICON_CDROM] = "cdrom",
+ [ICON_CRYPTOHASH] = "cryptohash",
+ [ICON_DEVICES] = "devices",
+ [ICON_HDD] = "hdd",
+ [ICON_INPUTDEVICES] = "inputdevices",
+ [ICON_JOYSTICK] = "joystick",
+ [ICON_KEYBOARD] = "keyboard",
+ [ICON_MEDIA_FLOPPY] = "media-floppy",
+ [ICON_MEDIA_REMOVABLE] = "media-removable",
+ [ICON_MEMORY] = "memory",
+ [ICON_MONITOR] = "monitor",
+ [ICON_MOUSE] = "mouse",
+ [ICON_NETWORK] = "network",
+ [ICON_NETWORK_CONNECTIONS] = "network-connections",
+ [ICON_NETWORK_INTERFACE] = "network-interface",
+ [ICON_THERM] = "therm",
+ [ICON_USB] = "usb",
+ [ICON_WIRELESS] = "wireless",
+};
+
+/* Keep this sorted by reverse strlen(dir)! */
+static const struct {
+ const gchar *dir;
+ enum icons icon;
+} modules_icons[] = {
+ {"drivers/input/joystick/", ICON_JOYSTICK},
+ {"drivers/input/keyboard/", ICON_KEYBOARD},
+ {"drivers/media/usb/uvc/", ICON_CAMERA_WEB},
+ {"drivers/net/wireless/", ICON_WIRELESS},
+ {"drivers/net/ethernet/", ICON_NETWORK_INTERFACE},
+ {"drivers/input/mouse/", ICON_MOUSE},
+ {"drivers/bluetooth/", ICON_BLUETOOTH},
+ {"drivers/media/v4l", ICON_CAMERA_WEB},
+ {"arch/x86/crypto/", ICON_CRYPTOHASH},
+ {"drivers/crypto/", ICON_CRYPTOHASH},
+ {"net/bluetooth/", ICON_BLUETOOTH},
+ {"drivers/input/", ICON_INPUTDEVICES},
+ {"drivers/cdrom/", ICON_CDROM},
+ {"drivers/hwmon/", ICON_THERM},
+ {"drivers/iommu/", ICON_MEMORY},
+ {"net/wireless/", ICON_WIRELESS},
+ {"drivers/nvme/", ICON_HDD},
+ {"net/ethernet/", ICON_NETWORK_INTERFACE},
+ {"drivers/scsi/", ICON_HDD},
+ {"drivers/edac/", ICON_MEMORY},
+ {"drivers/hid/", ICON_INPUTDEVICES},
+ {"drivers/gpu/", ICON_MONITOR},
+ {"drivers/i2c/", ICON_MEMORY},
+ {"drivers/ata/", ICON_HDD},
+ {"drivers/usb/", ICON_USB},
+ {"drivers/pci/", ICON_DEVICES},
+ {"drivers/net/", ICON_NETWORK},
+ {"drivers/mmc/", ICON_MEDIA_REMOVABLE},
+ {"crypto/", ICON_CRYPTOHASH},
+ {"sound/", ICON_AUDIO},
+ {"net/", ICON_NETWORK_CONNECTIONS},
+ {"fs/", ICON_MEDIA_FLOPPY},
+ {},
+};
+
+static GHashTable *module_icons;
+
+static void build_icon_table_iter(JsonObject *object,
+ const gchar *key,
+ JsonNode *value,
+ gpointer user_data)
+{
+ char *key_copy = g_strdup(key);
+ char *p;
+
+ for (p = key_copy; *p; p++) {
+ if (*p == '_')
+ *p = '-';
+ }
+
+ enum icons icon;
+ const gchar *value_str = json_node_get_string(value);
+ for (icon = ICON_INVALID; icon < ICON_MAX; icon++) {
+ const char *icon_name = icon_table[icon];
+
+ if (!icon_name)
+ continue;
+
+ if (g_str_equal(value_str, icon_name)) {
+ g_hash_table_insert(module_icons,
+ key_copy, GINT_TO_POINTER(icon));
+ return;
+ }
+ }
+
+ g_free(key_copy);
+}
+
+void kernel_module_icon_init(void)
+{
+ gchar *icon_json;
+
+ static SyncEntry sync_entry = {
+ .name = N_("Update kernel module icon table"),
+ .file_name = "kernel-module-icons.json",
+ };
+ sync_manager_add_entry(&sync_entry);
+
+ icon_json = g_build_filename(g_get_user_config_dir(),
+ "hardinfo", "kernel-module-icons.json",
+ NULL);
+
+ module_icons = g_hash_table_new(g_str_hash, g_str_equal);
+
+ if (!g_file_test(icon_json, G_FILE_TEST_EXISTS))
+ goto out;
+
+ JsonParser *parser = json_parser_new();
+ if (!json_parser_load_from_file(parser, icon_json, NULL))
+ goto out_destroy_parser;
+
+ JsonNode *root = json_parser_get_root(parser);
+ if (json_node_get_node_type(root) != JSON_NODE_OBJECT)
+ goto out_destroy_parser;
+
+ JsonObject *icons = json_node_get_object(root);
+ if (!icons)
+ goto out_destroy_parser;
+
+ json_object_foreach_member(icons, build_icon_table_iter, NULL);
+
+out_destroy_parser:
+ g_object_unref(parser);
+
+out:
+ g_free(icon_json);
+}
+
+static const gchar* get_module_icon(const char *modname, const char *path)
+{
+ char *modname_temp = g_strdup(modname);
+ char *p;
+ for (p = modname_temp; *p; p++) {
+ if (*p == '_')
+ *p = '-';
+ }
+ gpointer icon = g_hash_table_lookup(module_icons, modname_temp);
+ g_free(modname_temp);
+ if (icon)
+ return icon_table[GPOINTER_TO_INT(icon)];
+
+ if (path == NULL) /* modinfo couldn't find module path */
+ return NULL;
+
+ if (kernel_modules_dir == NULL) {
+ struct utsname utsbuf;
+ uname(&utsbuf);
+ kernel_modules_dir = g_strdup_printf("/lib/modules/%s/kernel/", utsbuf.release);
+ }
+
+ if (!g_str_has_prefix(path, kernel_modules_dir))
+ return NULL;
+
+ const gchar *path_no_prefix = path + strlen(kernel_modules_dir);
+ const size_t path_no_prefix_len = strlen(path_no_prefix);
+ int i;
+
+ for (i = 0; modules_icons[i].dir; i++) {
+ if (g_str_has_prefix(path_no_prefix, modules_icons[i].dir))
+ return icon_table[modules_icons[i].icon];
+ }
+
+ return NULL;
+}
+
+void scan_modules_do(void) {
+ FILE *lsmod;
+ gchar buffer[1024];
+ gchar *lsmod_path;
+ gchar *module_icons;
+ const gchar *icon;
+
+ if (!_module_hash_table) { _module_hash_table = g_hash_table_new(g_str_hash, g_str_equal); }
+
+ g_free(module_list);
+
+ kernel_modules_dir = NULL;
+ module_list = NULL;
+ module_icons = NULL;
+ moreinfo_del_with_prefix("COMP:MOD");
+
+ lsmod_path = find_program("lsmod");
+ if (!lsmod_path) return;
+ lsmod = popen(lsmod_path, "r");
+ if (!lsmod) {
+ g_free(lsmod_path);
+ return;
+ }
+
+ (void)fgets(buffer, 1024, lsmod); /* Discards the first line */
+
+ while (fgets(buffer, 1024, lsmod)) {
+ gchar *buf, *strmodule, *hashkey;
+ gchar *author = NULL, *description = NULL, *license = NULL, *deps = NULL, *vermagic = NULL,
+ *filename = NULL, *srcversion = NULL, *version = NULL, *retpoline = NULL,
+ *intree = NULL, modname[64];
+ FILE *modi;
+ glong memory;
+
+ shell_status_pulse();
+
+ buf = buffer;
+
+ sscanf(buf, "%s %ld", modname, &memory);
+
+ hashkey = g_strdup_printf("MOD%s", modname);
+ buf = g_strdup_printf("/sbin/modinfo %s 2>/dev/null", modname);
+
+ modi = popen(buf, "r");
+ while (fgets(buffer, 1024, modi)) {
+ gchar **tmp = g_strsplit(buffer, ":", 2);
+
+ GET_STR("author", author);
+ GET_STR("description", description);
+ GET_STR("license", license);
+ GET_STR("depends", deps);
+ GET_STR("vermagic", vermagic);
+ GET_STR("filename", filename);
+ GET_STR("srcversion", srcversion); /* so "version" doesn't catch */
+ GET_STR("version", version);
+ GET_STR("retpoline", retpoline);
+ GET_STR("intree", intree);
+
+ g_strfreev(tmp);
+ }
+ pclose(modi);
+ g_free(buf);
+
+ /* old modutils includes quotes in some strings; strip them */
+ /*remove_quotes(modname);
+ remove_quotes(description);
+ remove_quotes(vermagic);
+ remove_quotes(author);
+ remove_quotes(license); */
+
+ /* old modutils displays <none> when there's no value for a
+ given field; this is not desirable in the module name
+ display, so change it to an empty string */
+ if (description && g_str_equal(description, "&lt;none&gt;")) {
+ g_free(description);
+ description = g_strdup("");
+
+ g_hash_table_insert(_module_hash_table, g_strdup(modname),
+ g_strdup_printf("Kernel module (%s)", modname));
+ } else {
+ g_hash_table_insert(_module_hash_table, g_strdup(modname), g_strdup(description));
+ }
+
+ /* append this module to the list of modules */
+ module_list = h_strdup_cprintf("$%s$%s=%s\n", module_list, hashkey, modname,
+ description ? description : "");
+ icon = get_module_icon(modname, filename);
+ module_icons = h_strdup_cprintf("Icon$%s$%s=%s.png\n", module_icons, hashkey,
+ modname, icon ? icon: "module");
+
+ STRIFNULL(filename, _("(Not available)"));
+ STRIFNULL(description, _("(Not available)"));
+ STRIFNULL(vermagic, _("(Not available)"));
+ STRIFNULL(author, _("(Not available)"));
+ STRIFNULL(license, _("(Not available)"));
+ STRIFNULL(version, _("(Not available)"));
+
+ gboolean ry = FALSE, ity = FALSE;
+ if (retpoline && *retpoline == 'Y') ry = TRUE;
+ if (intree && *intree == 'Y') ity = TRUE;
+
+ g_free(retpoline);
+ g_free(intree);
+
+ retpoline = g_strdup(ry ? _("Yes") : _("No"));
+ intree = g_strdup(ity ? _("Yes") : _("No"));
+
+ /* create the module information string */
+ strmodule = g_strdup_printf("[%s]\n"
+ "%s=%s\n"
+ "%s=%.2f %s\n"
+ "[%s]\n"
+ "%s=%s\n"
+ "%s=%s\n"
+ "%s=%s\n"
+ "%s=%s\n"
+ "%s=%s\n"
+ "%s=%s\n"
+ "[%s]\n"
+ "%s=%s\n"
+ "%s=%s\n",
+ _("Module Information"), _("Path"), filename, _("Used Memory"),
+ memory / 1024.0, _("KiB"), _("Description"), _("Name"), modname,
+ _("Description"), description, _("Version Magic"), vermagic,
+ _("Version"), version, _("In Linus' Tree"), intree,
+ _("Retpoline Enabled"), retpoline, _("Copyright"), _("Author"),
+ author, _("License"), license);
+
+ /* if there are dependencies, append them to that string */
+ if (deps && strlen(deps)) {
+ gchar **tmp = g_strsplit(deps, ",", 0);
+
+ strmodule = h_strconcat(strmodule, "\n[", _("Dependencies"), "]\n",
+ g_strjoinv("=\n", tmp), "=\n", NULL);
+ g_strfreev(tmp);
+ g_free(deps);
+ }
+
+ moreinfo_add_with_prefix("COMP", hashkey, strmodule);
+ g_free(hashkey);
+
+ g_free(license);
+ g_free(description);
+ g_free(author);
+ g_free(vermagic);
+ g_free(filename);
+ g_free(srcversion);
+ g_free(version);
+ g_free(retpoline);
+ g_free(intree);
+ }
+ pclose(lsmod);
+
+ g_free(lsmod_path);
+ g_free(kernel_modules_dir);
+
+ if (module_list != NULL && module_icons != NULL) {
+ module_list = h_strdup_cprintf("[$ShellParam$]\n%s", module_list, module_icons);
+ }
+ g_free(module_icons);
+}
diff --git a/modules/computer/os.c b/modules/computer/os.c
new file mode 100644
index 00000000..7648eef3
--- /dev/null
+++ b/modules/computer/os.c
@@ -0,0 +1,582 @@
+/*
+ * HardInfo - Displays System Information
+ * Copyright (C) 2003-2006 L. A. F. Pereira <l@tia.mat.br>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, version 2 or later.
+ *
+ * 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 <gdk/gdkx.h>
+#include <string.h>
+#include <sys/utsname.h>
+#include "hardinfo.h"
+#include "computer.h"
+#include "distro_flavors.h"
+
+static gchar *
+get_libc_version(void)
+{
+ 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 = hardinfo_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"));
+}
+
+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 = hardinfo_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 = hardinfo_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 = hardinfo_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;
+}
+
+
+static gchar *
+detect_mate_version(void)
+{
+ gchar *tmp;
+ gchar *out;
+ gboolean spawned;
+
+ spawned = hardinfo_spawn_command_line_sync(
+ "mate-about --version", &out, NULL, NULL, NULL);
+ if (spawned) {
+ tmp = strstr(idle_free(out), _("MATE Desktop Environment "));
+
+ if (tmp) {
+ tmp += strlen(_("MATE Desktop Environment "));
+ return g_strdup_printf("MATE %s", strend(tmp, '\n'));
+ }
+ }
+
+ return NULL;
+}
+
+static gchar *
+detect_window_manager(void)
+{
+ const gchar *curdesktop;
+ const gchar* windowman;
+ GdkScreen *screen = gdk_screen_get_default();
+
+#if GTK_CHECK_VERSION(3,0,0)
+ if (GDK_IS_X11_SCREEN(screen)) {
+#else
+ if (screen && GDK_IS_SCREEN(screen)) {
+#endif
+ windowman = gdk_x11_screen_get_window_manager_name(screen);
+ } else return g_strdup("Not X11");
+
+ 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) {
+ 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;
+ }
+ if (g_str_equal(tmp, "MATE") || g_str_equal(tmp, "mate")) {
+ gchar *maybe_mate = detect_mate_version();
+
+ if (maybe_mate)
+ return maybe_mate;
+ }
+
+ 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_dmesg_status(void)
+{
+ gchar *out = NULL, *err = NULL;
+ int ex = 1, result = 0;
+ hardinfo_spawn_command_line_sync("dmesg", &out, &err, &ex, NULL);
+ g_free(out);
+ g_free(err);
+ result += (getuid() == 0) ? 2 : 0;
+ result += ex ? 1 : 0;
+ switch(result) {
+ case 0: /* readable, user */
+ return g_strdup(_("User access allowed"));
+ case 1: /* unreadable, user */
+ return g_strdup(_("User access forbidden"));
+ case 2: /* readable, root */
+ return g_strdup(_("Access allowed (running as superuser)"));
+ case 3: /* unreadable, root */
+ return g_strdup(_("Access forbidden? (running as superuser)"));
+ }
+ return g_strdup(_("(Unknown)"));
+}
+
+gchar *
+computer_get_aslr(void)
+{
+ switch (h_sysfs_read_int("/proc/sys/kernel", "randomize_va_space")) {
+ case 0:
+ return g_strdup(_("Disabled"));
+ case 1:
+ return g_strdup(_("Partially enabled (mmap base+stack+VDSO base)"));
+ case 2:
+ return g_strdup(_("Fully enabled (mmap base+stack+VDSO base+heap)"));
+ default:
+ 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 > 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);
+}
+
+gchar *
+computer_get_language(void)
+{
+ 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 Distro
+parse_os_release(void)
+{
+ gchar *pretty_name = NULL;
+ gchar *id = NULL;
+ gchar *codename = NULL;
+ gchar **split, *contents, **line;
+
+ if (!g_file_get_contents("/usr/lib/os-release", &contents, NULL, NULL))
+ return (Distro) {};
+
+ split = g_strsplit(idle_free(contents), "\n", 0);
+ if (!split)
+ return (Distro) {};
+
+ for (line = split; *line; line++) {
+ if (!strncmp(*line, "ID=", sizeof("ID=") - 1)) {
+ id = g_strdup(*line + strlen("ID="));
+ } else if (!strncmp(*line, "CODENAME=", sizeof("CODENAME=") - 1)) {
+ codename = g_strdup(*line + strlen("CODENAME="));
+ } else if (!strncmp(*line, "PRETTY_NAME=", sizeof("PRETTY_NAME=") - 1)) {
+ pretty_name = g_strdup(*line +
+ strlen("PRETTY_NAME=\""));
+ strend(pretty_name, '"');
+ }
+ }
+
+ g_strfreev(split);
+
+ if (pretty_name)
+ return (Distro) { .distro = pretty_name, .codename = codename, .id = id };
+
+ g_free(id);
+ return (Distro) {};
+}
+
+static Distro
+parse_lsb_release(void)
+{
+ gchar *pretty_name = NULL;
+ gchar *id = NULL;
+ gchar *codename = NULL;
+ gchar **split, *contents, **line;
+
+ if (!hardinfo_spawn_command_line_sync("/usr/bin/lsb_release -di", &contents, NULL, NULL, NULL))
+ return (Distro) {};
+
+ split = g_strsplit(idle_free(contents), "\n", 0);
+ if (!split)
+ return (Distro) {};
+
+ for (line = split; *line; line++) {
+ if (!strncmp(*line, "Distributor ID:\t", sizeof("Distributor ID:\t") - 1)) {
+ id = g_utf8_strdown(*line + strlen("Distributor ID:\t"), -1);
+ } else if (!strncmp(*line, "Codename:\t", sizeof("Codename:\t") - 1)) {
+ codename = g_utf8_strdown(*line + strlen("Codename:\t"), -1);
+ } else if (!strncmp(*line, "Description:\t", sizeof("Description:\t") - 1)) {
+ pretty_name = g_strdup(*line + strlen("Description:\t"));
+ }
+ }
+
+ g_strfreev(split);
+
+ if (pretty_name)
+ return (Distro) { .distro = pretty_name, .codename = codename, .id = id };
+
+ g_free(id);
+ return (Distro) {};
+}
+
+static Distro
+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", "debian" },
+ { DB_PREFIX "slackware-version", "slk" },
+ { DB_PREFIX "mandrake-release", "mdk" },
+ { DB_PREFIX "mandriva-release", "mdv" },
+ { DB_PREFIX "fedora-release", "fedora" },
+ { 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 "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 }
+ };
+ Distro distro;
+ gchar *contents;
+ int i;
+
+ distro = parse_os_release();
+ if (distro.distro)
+ return distro;
+
+ distro = parse_lsb_release();
+ if (distro.distro)
+ return distro;
+
+ for (i = 0; distro_db[i].file; i++) {
+ if (!g_file_get_contents(distro_db[i].file, &contents, NULL, NULL))
+ continue;
+
+ if (distro_db[i].override) {
+ g_free(contents);
+ return (Distro) { .distro = g_strdup(distro_db[i].override),
+ .codename = g_strdup(distro_db[i].codename) };
+ }
+
+ if (g_str_equal(distro_db[i].codename, "debian")) {
+ /* 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 (Distro) {
+ .distro = g_strdup_printf("Debian GNU/Linux %s", (char*)idle_free(contents)),
+ .codename = g_strdup(distro_db[i].codename)
+ };
+ }
+
+ if (g_str_equal(distro_db[i].codename, "fatdog")) {
+ return (Distro) {
+ .distro = g_strdup_printf("Fatdog64 [%.10s]", (char*)idle_free(contents)),
+ .codename = g_strdup(distro_db[i].codename)
+ };
+ }
+
+ return (Distro) { .distro = contents, .codename = g_strdup(distro_db[i].codename) };
+ }
+
+ return (Distro) { .distro = g_strdup(_("Unknown")) };
+}
+
+OperatingSystem *
+computer_get_os(void)
+{
+ struct utsname utsbuf;
+ OperatingSystem *os;
+ int i;
+
+ os = g_new0(OperatingSystem, 1);
+
+ Distro distro = detect_distro();
+ os->distro = g_strstrip(distro.distro);
+ os->distroid = distro.id;
+ os->distrocode = distro.codename;
+
+ /* Kernel and hostname info */
+ uname(&utsbuf);
+ os->kernel_version = g_strdup(utsbuf.version);
+ os->kernel = g_strdup_printf("%s %s (%s)", utsbuf.sysname,
+ utsbuf.release, utsbuf.machine);
+ os->kcmdline = h_sysfs_read_string("/proc", "cmdline");
+ os->hostname = g_strdup(utsbuf.nodename);
+ 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);
+
+ 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();
+
+ if (g_strcmp0(os->distrocode, "ubuntu") == 0) {
+ GSList *flavs = ubuntu_flavors_scan();
+ if (flavs) {
+ /* just use the first one */
+ os->distro_flavor = (DistroFlavor*)flavs->data;
+ }
+ g_slist_free(flavs);
+ }
+
+ return os;
+}
+
+const gchar *
+computer_get_selinux(void)
+{
+ int r;
+ gboolean spawned = hardinfo_spawn_command_line_sync("selinuxenabled",
+ NULL, NULL, &r, NULL);
+
+ if (!spawned)
+ return _("Not installed");
+
+ if (r == 0)
+ return _("Enabled");
+
+ return _("Disabled");
+}
+
+gchar *
+computer_get_lsm(void)
+{
+ gchar *contents;
+
+ if (!g_file_get_contents("/sys/kernel/security/lsm", &contents, NULL, NULL))
+ return g_strdup(_("Unknown"));
+
+ return contents;
+}
diff --git a/modules/computer/ubuntu_flavors.c b/modules/computer/ubuntu_flavors.c
new file mode 100644
index 00000000..ac67d665
--- /dev/null
+++ b/modules/computer/ubuntu_flavors.c
@@ -0,0 +1,90 @@
+/*
+ * HardInfo - Displays System Information
+ * Copyright (C) 2003-2019 L. A. F. Pereira <l@tia.mat.br>
+ * This file 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 or later.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <hardinfo.h>
+#include "distro_flavors.h"
+#include "util_sysobj.h" /* for appfsp() */
+
+static const UbuntuFlavor ubuntu_flavors[] = {
+ { "Vanilla Server", "distros/ubuntu.svg", "https://ubuntu.org", "ubuntu-server" },
+ { "Vanilla Desktop", "distros/ubuntu.svg", "https://ubuntu.org", "ubuntu-desktop" },
+ { "Xubuntu", "distros/xubuntu.svg", "https://xubuntu.org", "xubuntu-desktop" },
+ { "Kubuntu", "distros/kubuntu.png", "https://kubuntu.org", "kubuntu-desktop" },
+ { "Lubuntu", "distros/lubuntu.png", "https://lubuntu.me", "lubuntu-desktop" }, /* formerly or also lubuntu.net? */
+ { "Ubuntu MATE", "distros/ubuntu-mate.png", "https://ubuntu-mate.org", "ubuntu-mate-desktop" },
+ { "Ubuntu Budgie", "distros/ubuntu-budgie.png", "https://ubuntubudgie.org", "ubuntu-budgie-desktop" },
+ { "UbuntuKylin (做最有中国味的操作系统)", "distros/ubuntu-kylin.png", "https://www.ubuntukylin.com", "ubuntukylin-desktop" },
+ { "UbuntuStudio", "distros/ubuntu-studio.png", "https://ubuntustudio.org", "ubuntustudio-desktop" },
+ /* Deprecated flavors */
+ { "Ubuntu GNOME", "distros/ubuntu-gnome.png", "https://ubuntugnome.org", "ubuntu-gnome-desktop" },
+ // Edubuntu
+ // Mythbuntu
+ { NULL }
+};
+
+static const UbuntuFlavor *_find_flavor(const gchar *pkg) {
+ int i = 0;
+ for(; ubuntu_flavors[i].base.name; i++) {
+ if (SEQ(ubuntu_flavors[i].package, pkg))
+ return &ubuntu_flavors[i];
+ }
+ return NULL;
+}
+
+/* items are const; free with g_slist_free() */
+GSList *ubuntu_flavors_scan(void) {
+ GSList *ret = NULL;
+ gboolean spawned;
+ gchar *out, *err, *p, *next_nl;
+ gint exit_status;
+ const UbuntuFlavor *f = NULL;
+ gchar *cmd_line = g_strdup("apt-cache policy");
+ int i;
+ for(i = 0; ubuntu_flavors[i].base.name; i++) {
+ cmd_line = appfsp(cmd_line, "%s", ubuntu_flavors[i].package);
+ }
+ if (!i)
+ return NULL;
+
+ spawned = hardinfo_spawn_command_line_sync(cmd_line,
+ &out, &err, &exit_status, NULL);
+ if (spawned) {
+ p = out;
+ while(next_nl = strchr(p, '\n')) {
+ strend(p, '\n');
+ int mc = 0;
+ char pkg[32] = "";
+ if (*p != ' ' && *p != '\t')
+ mc = sscanf(p, "%31s", pkg);
+ if (mc == 1) {
+ strend(pkg, ':');
+ f = _find_flavor(pkg);
+ } else if
+ (g_strstr_len(p, -1, "Installed:")
+ && !g_strstr_len(p, -1, "(none)") ) {
+ ret = g_slist_append(ret, (void*)f);
+ }
+ p = next_nl + 1;
+ }
+ g_free(out);
+ g_free(err);
+ }
+ g_free(cmd_line);
+ return ret;
+}
diff --git a/modules/computer/uptime.c b/modules/computer/uptime.c
new file mode 100644
index 00000000..8aef1530
--- /dev/null
+++ b/modules/computer/uptime.c
@@ -0,0 +1,72 @@
+/*
+ * HardInfo - Displays System Information
+ * Copyright (C) 2003-2006 L. A. F. Pereira <l@tia.mat.br>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, version 2 or later.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+#include "hardinfo.h"
+#include "computer.h"
+
+UptimeInfo *
+computer_get_uptime(void)
+{
+ UptimeInfo *ui = g_new0(UptimeInfo, 1);
+ FILE *procuptime;
+ gulong minutes;
+
+ if ((procuptime = fopen("/proc/uptime", "r")) != NULL) {
+ (void)fscanf(procuptime, "%lu", &minutes);
+ ui->minutes = minutes / 60;
+ fclose(procuptime);
+ } else {
+ g_free(ui);
+ return NULL;
+ }
+
+ ui->hours = ui->minutes / 60;
+ ui->minutes %= 60;
+ ui->days = ui->hours / 24;
+ ui->hours %= 24;
+
+ return ui;
+}
+
+gchar *
+computer_get_formatted_uptime()
+{
+ UptimeInfo *ui;
+ const gchar *days_fmt, *hours_fmt, *minutes_fmt;
+ gchar *full_fmt = NULL, *ret = NULL;
+
+ ui = computer_get_uptime();
+
+ 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) {
+ 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 {
+ 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 ret;
+}
diff --git a/modules/computer/users.c b/modules/computer/users.c
new file mode 100644
index 00000000..75e24f26
--- /dev/null
+++ b/modules/computer/users.c
@@ -0,0 +1,61 @@
+/*
+ * HardInfo - Displays System Information
+ * Copyright (C) 2003-2009 L. A. F. Pereira <l@tia.mat.br>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, version 2 or later.
+ *
+ * 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 <pwd.h>
+#include "hardinfo.h"
+#include "computer.h"
+
+gchar *users = NULL;
+
+void
+scan_users_do(void)
+{
+ struct passwd *passwd_;
+ passwd_ = getpwent();
+ if (!passwd_)
+ return;
+
+ if (users) {
+ g_free(users);
+ moreinfo_del_with_prefix("COMP:USER");
+ }
+
+ users = g_strdup("");
+
+ while (passwd_) {
+ gchar *key = g_strdup_printf("USER%s", passwd_->pw_name);
+ 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, ',');
+ users = h_strdup_cprintf("$%s$%s=%s\n", users, key, passwd_->pw_name, passwd_->pw_gecos);
+ passwd_ = getpwent();
+ g_free(key);
+ }
+
+ endpwent();
+}