diff options
Diffstat (limited to 'modules/computer')
| -rw-r--r-- | modules/computer/alsa.c | 71 | ||||
| -rw-r--r-- | modules/computer/boots.c | 68 | ||||
| -rw-r--r-- | modules/computer/display.c | 74 | ||||
| -rw-r--r-- | modules/computer/environment.c | 45 | ||||
| -rw-r--r-- | modules/computer/filesystem.c | 108 | ||||
| -rw-r--r-- | modules/computer/groups.c | 45 | ||||
| -rw-r--r-- | modules/computer/languages.c | 182 | ||||
| -rw-r--r-- | modules/computer/loadavg.c | 68 | ||||
| -rw-r--r-- | modules/computer/memory.c | 62 | ||||
| -rw-r--r-- | modules/computer/memory_usage.c | 125 | ||||
| -rw-r--r-- | modules/computer/modules.c | 400 | ||||
| -rw-r--r-- | modules/computer/os.c | 582 | ||||
| -rw-r--r-- | modules/computer/ubuntu_flavors.c | 90 | ||||
| -rw-r--r-- | modules/computer/uptime.c | 72 | ||||
| -rw-r--r-- | modules/computer/users.c | 61 | 
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, "<none>")) { +            g_free(description); +            description = g_strdup(""); + +            g_hash_table_insert(_module_hash_table, g_strdup(modname), +                                g_strdup_printf("Kernel module (%s)", modname)); +        } else { +            g_hash_table_insert(_module_hash_table, g_strdup(modname), g_strdup(description)); +        } + +        /* 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(); +} | 
