diff --git a/Makefile b/Makefile index 1ae1dc8..e42617b 100644 --- a/Makefile +++ b/Makefile @@ -1,4 +1,4 @@ -CFLAGS=-O2 -Wall -Wextra -lX11 -lpci +CFLAGS=-O2 -Wall -Wextra -lX11 -lwayland-client -lpci PREFIX=/usr CACHE=$(shell if [ "$$XDG_CACHE_HOME" ]; then echo "$$XDG_CACHE_HOME"; else echo "$$HOME"/.cache; fi) diff --git a/paleofetch.c b/paleofetch.c index 765cfcd..7bc9946 100644 --- a/paleofetch.c +++ b/paleofetch.c @@ -1,4 +1,3 @@ -#pragma GCC diagnostic ignored "-Wunused-function" #include #include #include @@ -15,6 +14,8 @@ #include #include +#include +#include #include "paleofetch.h" #include "config.h" @@ -23,158 +24,158 @@ #define COUNT(x) (int)(sizeof x / sizeof *x) #define halt_and_catch_fire(fmt, ...) \ - do { \ - if(status != 0) { \ - fprintf(stderr, "paleofetch: " fmt "\n", ##__VA_ARGS__); \ - exit(status); \ - } \ - } while(0) + do { \ + if (status != 0) { \ + fprintf(stderr, "paleofetch: " fmt "\n", ##__VA_ARGS__); \ + exit(status); \ + } \ + } while(0) struct conf { - char *label, *(*function)(); - bool cached; + char *label, *(*function)(); + bool cached; } config[] = CONFIG; struct { - char *substring; - char *repl_str; - size_t length; - size_t repl_len; + char *substring; + char *repl_str; + size_t length; + size_t repl_len; } cpu_config[] = CPU_CONFIG, gpu_config[] = GPU_CONFIG; -Display *display; struct statvfs file_stats; struct utsname uname_info; struct sysinfo my_sysinfo; int title_length, status; -/* - * Replaces the first newline character with null terminator - */ void remove_newline(char *s) { - while (*s != '\0' && *s != '\n') - s++; - *s = '\0'; + while (*s != '\0' && *s != '\n') { + s++; + } + *s = '\0'; } -/* - * Replaces the first newline character with null terminator - * and returns the length of the string - */ int remove_newline_get_length(char *s) { - int i; - for (i = 0; *s != '\0' && *s != '\n'; s++, i++); - *s = '\0'; - return i; + int i; + for (i = 0; *s != '\0' && *s != '\n'; s++, i++); + *s = '\0'; + return i; } -/* - * Cleans up repeated spaces in a string - * Trim spaces at the front of a string - */ void truncate_spaces(char *str) { - int src = 0, dst = 0; - while(*(str + dst) == ' ') dst++; + int src = 0, dst = 0; + while (*(str + dst) == ' ') dst++; - while(*(str + dst) != '\0') { - *(str + src) = *(str + dst); - if(*(str + (dst++)) == ' ') - while(*(str + dst) == ' ') dst++; - - src++; + while (*(str + dst) != '\0') { + *(str + src) = *(str + dst); + if(*(str + (dst++)) == ' ') { + while (*(str + dst) == ' ') { + dst++; + } } - *(str + src) = '\0'; + src++; + } + + *(str + src) = '\0'; } -/* - * Removes the first len characters of substring from str - * Assumes that strlen(substring) >= len - * Returns index where substring was found, or -1 if substring isn't found - */ void remove_substring(char *str, const char* substring, size_t len) { - /* shift over the rest of the string to remove substring */ - char *sub = strstr(str, substring); - if(sub == NULL) return; + char *sub = strstr(str, substring); + if (sub == NULL) { + return; + } - int i = 0; - do *(sub+i) = *(sub+i+len); - while(*(sub+(++i)) != '\0'); + int i = 0; + do { + *(sub+i) = *(sub+i+len); + } while (*(sub+(++i)) != '\0'); } -/* - * Replaces the first sub_len characters of sub_str from str - * with the first repl_len characters of repl_str - */ void replace_substring(char *str, const char *sub_str, const char *repl_str, size_t sub_len, size_t repl_len) { - char buffer[BUF_SIZE / 2]; - char *start = strstr(str, sub_str); - if (start == NULL) return; // substring not found + char buffer[BUF_SIZE / 2]; + char *start = strstr(str, sub_str); + if (start == NULL) { + return; + } - /* check if we have enough space for new substring */ - if (strlen(str) - sub_len + repl_len >= BUF_SIZE / 2) { - status = -1; - halt_and_catch_fire("new substring too long to replace"); - } + if (strlen(str) - sub_len + repl_len >= BUF_SIZE / 2) { + status = -1; + halt_and_catch_fire("new substring too long to replace"); + } - strcpy(buffer, start + sub_len); - strncpy(start, repl_str, repl_len); - strcpy(start + repl_len, buffer); + strcpy(buffer, start + sub_len); + strncpy(start, repl_str, repl_len); + strcpy(start + repl_len, buffer); } static char *get_title() { - // reduce the maximum size for these, so that we don't over-fill the title string - char hostname[BUF_SIZE / 3]; - status = gethostname(hostname, BUF_SIZE / 3); - halt_and_catch_fire("unable to retrieve host name"); + char hostname[BUF_SIZE / 3]; + status = gethostname(hostname, BUF_SIZE / 3); + halt_and_catch_fire("unable to retrieve host name"); - char username[BUF_SIZE / 3]; - status = getlogin_r(username, BUF_SIZE / 3); + char *username = getenv("USER"); + if (username == NULL) { halt_and_catch_fire("unable to retrieve login name"); + } - title_length = strlen(hostname) + strlen(username) + 1; + title_length = strlen(hostname) + strlen(username) + 1; - char *title = malloc(BUF_SIZE); - snprintf(title, BUF_SIZE, TITLECOLOR"%s\e[0m@"TITLECOLOR"%s", username, hostname); + char *title = malloc(BUF_SIZE); + snprintf(title, BUF_SIZE, TITLECOLOR"%s\e[0m@"TITLECOLOR"%s", username, hostname); - return title; + return title; } static char *get_bar() { - char *bar = malloc(BUF_SIZE); - char *s = bar; - for(int i = 0; i < title_length; i++) *(s++) = '-'; - *s = '\0'; - return bar; + char *bar = malloc(BUF_SIZE); + char *s = bar; + for (int i = 0; i < title_length; i++) { + *(s++) = '-'; + } + *s = '\0'; + return bar; } static char *get_os() { - char *os = malloc(BUF_SIZE), - *name = malloc(BUF_SIZE), - *line = NULL; - size_t len; - FILE *os_release = fopen("/etc/os-release", "r"); - if(os_release == NULL) { - status = -1; - halt_and_catch_fire("unable to open /etc/os-release"); + char *os = malloc(BUF_SIZE), *name = malloc(BUF_SIZE), *line = NULL; + size_t len; + FILE *os_release = fopen("/etc/os-release", "r"); + if (os_release == NULL) { + status = -1; + halt_and_catch_fire("unable to open /etc/os-release"); + } + + while (getline(&line, &len, os_release) != -1) { + if (sscanf(line, "NAME=\"%[^\"]+", name) > 0) { + break; } + } - while (getline(&line, &len, os_release) != -1) { - if (sscanf(line, "NAME=\"%[^\"]+", name) > 0) break; - } + free(line); + fclose(os_release); + snprintf(os, BUF_SIZE, "%s %s", name, uname_info.machine); + free(name); - free(line); - fclose(os_release); - snprintf(os, BUF_SIZE, "%s %s", name, uname_info.machine); - free(name); - - return os; + return os; } static char *get_kernel() { - char *kernel = malloc(BUF_SIZE); - strncpy(kernel, uname_info.release, BUF_SIZE); - return kernel; + struct utsname uname_info; + + if (uname(&uname_info) == -1) { + return "不明"; + } + + char *kernel = malloc(BUF_SIZE); + if (kernel == NULL) { + return "不明"; + } + + strncpy(kernel, uname_info.release, BUF_SIZE); + kernel[BUF_SIZE -1] = '\0'; + + return kernel; } static char *get_host() { @@ -214,25 +215,24 @@ model_fallback: } static char *get_uptime() { - long seconds = my_sysinfo.uptime; - struct { char *name; int secs; } units[] = { - { "day", 60 * 60 * 24 }, - { "hour", 60 * 60 }, - { "min", 60 }, - }; + long seconds = my_sysinfo.uptime; + struct { char *name; int secs; } units[] = { + { "day", 60 * 60 * 24 }, + { "hour", 60 * 60 }, + { "min", 60 }, + }; - int n, len = 0; - char *uptime = malloc(BUF_SIZE); - for (int i = 0; i < 3; ++i ) { - if ((n = seconds / units[i].secs) || i == 2) /* always print minutes */ - len += snprintf(uptime + len, BUF_SIZE - len, - "%d %s%s, ", n, units[i].name, n != 1 ? "s": ""); - seconds %= units[i].secs; + int n, len = 0; + char *uptime = malloc(BUF_SIZE); + for (int i = 0; i < 3; ++i ) { + if ((n = seconds / units[i].secs) || i == 2) { + len += snprintf(uptime + len, BUF_SIZE - len, "%d %s%s, ", n, units[i].name, n != 1 ? "s": ""); } + seconds %= units[i].secs; + } - // null-terminate at the trailing comma - uptime[len - 2] = '\0'; - return uptime; + uptime[len - 2] = '\0'; + return uptime; } static char *get_packages() { @@ -242,72 +242,89 @@ static char *get_packages() { } static char *get_shell() { - char *shell = malloc(BUF_SIZE); - char *shell_path = getenv("SHELL"); - char *shell_name = strrchr(getenv("SHELL"), '/'); + char *shell = malloc(BUF_SIZE); + char *shell_path = getenv("SHELL"); + char *shell_name = strrchr(getenv("SHELL"), '/'); - if(shell_name == NULL) /* if $SHELL doesn't have a '/' */ - strncpy(shell, shell_path, BUF_SIZE - 1); /* copy the whole thing over */ - else - strncpy(shell, shell_name + 1, BUF_SIZE - 1); /* o/w copy past the last '/' */ + if (shell_name == NULL) { + strncpy(shell, shell_path, BUF_SIZE - 1); + } else { + strncpy(shell, shell_name + 1, BUF_SIZE - 1); + } - return shell; + return shell; } static char *get_resolution() { - int screen, width, height; - char *resolution = malloc(BUF_SIZE); - - if (display != NULL) { - screen = DefaultScreen(display); - - width = DisplayWidth(display, screen); - height = DisplayHeight(display, screen); + int screen, width, height; + char *resolution = malloc(BUF_SIZE); + char *wayland_display = getenv("WAYLAND_DISPLAY"); - snprintf(resolution, BUF_SIZE, "%dx%d", width, height); - } else { - DIR *dir; - struct dirent *entry; - char dir_name[] = "/sys/class/drm"; - char modes_file_name[BUF_SIZE * 2]; - FILE *modes; - char *line = NULL; - size_t len; - - /* preload resolution with empty string, in case we cant find a resolution through parsing */ - strncpy(resolution, "", BUF_SIZE); - - dir = opendir(dir_name); - if (dir == NULL) { - status = -1; - halt_and_catch_fire("Could not open /sys/class/drm to determine resolution in tty mode."); - } - /* parse through all directories and look for a non empty modes file */ - while ((entry = readdir(dir)) != NULL) { - if (entry->d_type == DT_LNK) { - snprintf(modes_file_name, BUF_SIZE * 2, "%s/%s/modes", dir_name, entry->d_name); - - modes = fopen(modes_file_name, "r"); - if (modes != NULL) { - if (getline(&line, &len, modes) != -1) { - strncpy(resolution, line, BUF_SIZE - 1); - remove_newline(resolution); - - free(line); - fclose(modes); - - break; - } - - fclose(modes); - } - } - } - - closedir(dir); + if (wayland_display != NULL) { // TODO + struct wl_display *dp = wl_display_connect(NULL); + if (dp == NULL) { + exit(EXIT_FAILURE); } - return resolution; + struct wl_registry *rg = wl_display_get_registry(dp); + if (rg == NULL) { + wl_display_disconnect(dp); + exit(EXIT_FAILURE); + } + + wl_display_disconnect(dp); + } else { + Display *display = XOpenDisplay(NULL); + if (display != NULL) { + screen = DefaultScreen(display); + + width = DisplayWidth(display, screen); + height = DisplayHeight(display, screen); + + snprintf(resolution, BUF_SIZE, "%dx%d", width, height); + } else { + DIR *dir; + struct dirent *entry; + char dir_name[] = "/sys/class/drm"; + char modes_file_name[BUF_SIZE * 2]; + FILE *modes; + char *line = NULL; + size_t len; + + strncpy(resolution, "", BUF_SIZE); + + dir = opendir(dir_name); + if (dir == NULL) { + status = -1; + halt_and_catch_fire("Could not open /sys/class/drm to determine resolution in tty mode."); + } + + while ((entry = readdir(dir)) != NULL) { + if (entry->d_type == DT_LNK) { + snprintf(modes_file_name, BUF_SIZE * 2, "%s/%s/modes", dir_name, entry->d_name); + + modes = fopen(modes_file_name, "r"); + if (modes != NULL) { + if (getline(&line, &len, modes) != -1) { + strncpy(resolution, line, BUF_SIZE - 1); + remove_newline(resolution); + + free(line); + fclose(modes); + + break; + } + + fclose(modes); + } + } + } + + closedir(dir); + } + } + + return resolution; } static char *get_wm() { @@ -353,7 +370,7 @@ static char *get_wm() { Display *dpy = XOpenDisplay(NULL); if (dpy == NULL) { - fprintf(stderr, "Unable to connect to display\n"); + //fprintf(stderr, "Unable to connect to display\n"); return strdup("不明"); } @@ -389,331 +406,324 @@ static char *get_wm() { return wm_name; } -static char *get_terminal() { +static void get_terminal_wayland(char *terminal) { + struct wl_display *display = wl_display_connect(NULL); + if (!display) { + return; + } + + wl_display_disconnect(display); +} + +static void get_terminal_x11(char *terminal) { + Display *display = XOpenDisplay(NULL); + if (!display) { + return; + } + + Atom a, active, class; + unsigned long _, window; unsigned char *prop; - char *terminal = malloc(BUF_SIZE); - if (display != NULL) { - unsigned long _, // not unused, but we don't need the results - window = RootWindow(display, XDefaultScreen(display)); - Atom a, - active = XInternAtom(display, "_NET_ACTIVE_WINDOW", True), - class = XInternAtom(display, "WM_CLASS", True); + window = RootWindow(display, XDefaultScreen(display)); + active = XInternAtom(display, "_NET_ACTIVE_WINDOW", True); + class = XInternAtom(display, "WM_CLASS", True); -#define GetProp(property) \ - XGetWindowProperty(display, window, property, 0, 64, 0, 0, &a, (int *)&_, &_, &_, &prop); - - GetProp(active); + if (XGetWindowProperty(display, window, active, 0, 64, 0, 0, &a, (int *)&_, &_, &_, &prop) == Success) { window = (prop[3] << 24) + (prop[2] << 16) + (prop[1] << 8) + prop[0]; free(prop); - if(!window) goto terminal_fallback; - GetProp(class); -#undef GetProp - snprintf(terminal, BUF_SIZE, "%s", prop); - free(prop); - } else { -terminal_fallback: - strncpy(terminal, getenv("TERM"), BUF_SIZE - 1); /* fallback to old method */ - if (strcmp(terminal, "linux") == 0) { - strncpy(terminal, ttyname(STDIN_FILENO), BUF_SIZE - 1); + if (window && XGetWindowProperty(display, window, class, 0, 64, 0, 0, &a, (int *)&_, &_, &_, &prop) == Success) { + snprintf(terminal, BUF_SIZE, "%s", prop); + free(prop); } } - return terminal; + XCloseDisplay(display); +} + +static char *get_terminal() { + //unsigned char *prop; + char *terminal = calloc(1, BUF_SIZE); + if (!terminal) { + return "不明"; + } + char *wayland_display = getenv("WAYLAND_DISPLAY"); + + if (wayland_display != NULL) { // TODO + get_terminal_wayland(terminal); + } else { + get_terminal_x11(terminal); + + if (!(*terminal)) { + strncpy(terminal, getenv("TERM"), BUF_SIZE - 1); + if (strcmp(terminal, "linux") == 0) { + strncpy(terminal, ttyname(STDIN_FILENO), BUF_SIZE -1); + } + } + } + + return terminal; } static char *get_cpu() { - FILE *cpuinfo = fopen("/proc/cpuinfo", "r"); /* read from cpu info */ - if(cpuinfo == NULL) { - status = -1; - halt_and_catch_fire("Unable to open cpuinfo"); - } + FILE *cpuinfo = fopen("/proc/cpuinfo", "r"); + if (cpuinfo == NULL) { + status = -1; + halt_and_catch_fire("Unable to open cpuinfo"); + } - char *cpu_model = malloc(BUF_SIZE / 2); - char *line = NULL; - size_t len; /* unused */ - int num_cores = 0, cpu_freq, prec = 3; - double freq; - char freq_unit[] = "GHz"; + char *cpu_model = malloc(BUF_SIZE / 2); + char *line = NULL; + size_t len; + int num_cores = 0, cpu_freq, prec = 3; + double freq; + char freq_unit[] = "GHz"; - /* read the model name into cpu_model, and increment num_cores every time model name is found */ - while(getline(&line, &len, cpuinfo) != -1) { - num_cores += sscanf(line, "model name : %[^\n@]", cpu_model); - } - free(line); - fclose(cpuinfo); + while (getline(&line, &len, cpuinfo) != -1) { + num_cores += sscanf(line, "model name : %[^\n@]", cpu_model); + } + free(line); + fclose(cpuinfo); - FILE *cpufreq = fopen("/sys/devices/system/cpu/cpu0/cpufreq/cpuinfo_max_freq", "r"); - line = NULL; + FILE *cpufreq = fopen("/sys/devices/system/cpu/cpu0/cpufreq/cpuinfo_max_freq", "r"); + line = NULL; - if (cpufreq != NULL) { - if (getline(&line, &len, cpufreq) != -1) { - sscanf(line, "%d", &cpu_freq); - cpu_freq /= 1000; // convert kHz to MHz - } else { - fclose(cpufreq); - free(line); - goto cpufreq_fallback; - } + if (cpufreq != NULL) { + if (getline(&line, &len, cpufreq) != -1) { + sscanf(line, "%d", &cpu_freq); + cpu_freq /= 1000; } else { + fclose(cpufreq); + free(line); + goto cpufreq_fallback; + } + } else { cpufreq_fallback: - cpufreq = fopen("/proc/cpuinfo", "r"); /* read from cpu info */ - if (cpufreq == NULL) { - status = -1; - halt_and_catch_fire("Unable to open cpuinfo"); - } - - while (getline(&line, &len, cpufreq) != -1) { - if (sscanf(line, "cpu MHz : %lf", &freq) > 0) break; - } - - cpu_freq = (int) freq; + cpufreq = fopen("/proc/cpuinfo", "r"); + if (cpufreq == NULL) { + status = -1; + halt_and_catch_fire("Unable to open cpuinfo"); } - free(line); - fclose(cpufreq); + while (getline(&line, &len, cpufreq) != -1) { + if (sscanf(line, "cpu MHz : %lf", &freq) > 0) { + break; + } + } - if (cpu_freq < 1000) { - freq = (double) cpu_freq; - freq_unit[0] = 'M'; // make MHz from GHz - prec = 0; // show frequency as integer value + cpu_freq = (int) freq; + } + + free(line); + fclose(cpufreq); + + if (cpu_freq < 1000) { + freq = (double) cpu_freq; + freq_unit[0] = 'M'; + prec = 0; + } else { + freq = cpu_freq / 1000.0; + + while (cpu_freq % 10 == 0) { + --prec; + cpu_freq /= 10; + } + + if (prec == 0) { + prec = 1; + } + } + + for (int i = 0; i < COUNT(cpu_config); ++i) { + if (cpu_config[i].repl_str == NULL) { + remove_substring(cpu_model, cpu_config[i].substring, cpu_config[i].length); } else { - freq = cpu_freq / 1000.0; // convert MHz to GHz and cast to double - - while (cpu_freq % 10 == 0) { - --prec; - cpu_freq /= 10; - } - - if (prec == 0) prec = 1; // we don't want zero decimal places + replace_substring(cpu_model, cpu_config[i].substring, cpu_config[i].repl_str, cpu_config[i].length, cpu_config[i].repl_len); } + } - /* remove unneeded information */ - for (int i = 0; i < COUNT(cpu_config); ++i) { - if (cpu_config[i].repl_str == NULL) { - remove_substring(cpu_model, cpu_config[i].substring, cpu_config[i].length); - } else { - replace_substring(cpu_model, cpu_config[i].substring, cpu_config[i].repl_str, cpu_config[i].length, cpu_config[i].repl_len); - } - } + char *cpu = malloc(BUF_SIZE); + snprintf(cpu, BUF_SIZE, "%s (%d) @ %.*f%s", cpu_model, num_cores, prec, freq, freq_unit); + free(cpu_model); - char *cpu = malloc(BUF_SIZE); - snprintf(cpu, BUF_SIZE, "%s (%d) @ %.*f%s", cpu_model, num_cores, prec, freq, freq_unit); - free(cpu_model); + truncate_spaces(cpu); - truncate_spaces(cpu); - - if(num_cores == 0) - *cpu = '\0'; - return cpu; + if (num_cores == 0) { + *cpu = '\0'; + } + return cpu; } static char *find_gpu(int index) { - // inspired by https://github.com/pciutils/pciutils/edit/master/example.c - /* it seems that pci_lookup_name needs to be given a buffer, but I can't for the life of my figure out what its for */ - char buffer[BUF_SIZE], *device_class, *gpu = malloc(BUF_SIZE); - struct pci_access *pacc; - struct pci_dev *dev; - int gpu_index = 0; - bool found = false; + char buffer[BUF_SIZE], *device_class, *gpu = malloc(BUF_SIZE); + struct pci_access *pacc; + struct pci_dev *dev; + int gpu_index = 0; + bool found = false; - pacc = pci_alloc(); - pci_init(pacc); - pci_scan_bus(pacc); - dev = pacc->devices; + pacc = pci_alloc(); + pci_init(pacc); + pci_scan_bus(pacc); + dev = pacc->devices; - while(dev != NULL) { - pci_fill_info(dev, PCI_FILL_IDENT | PCI_FILL_BASES | PCI_FILL_CLASS); - device_class = pci_lookup_name(pacc, buffer, sizeof(buffer), PCI_LOOKUP_CLASS, dev->device_class); - if(strcmp("VGA compatible controller", device_class) == 0 || strcmp("3D controller", device_class) == 0) { - strncpy(gpu, pci_lookup_name(pacc, buffer, sizeof(buffer), PCI_LOOKUP_DEVICE | PCI_LOOKUP_VENDOR, dev->vendor_id, dev->device_id), BUF_SIZE - 1); - if(gpu_index == index) { - found = true; - break; - } else { - gpu_index++; - } - } - - dev = dev->next; + while (dev != NULL) { + pci_fill_info(dev, PCI_FILL_IDENT | PCI_FILL_BASES | PCI_FILL_CLASS); + device_class = pci_lookup_name(pacc, buffer, sizeof(buffer), PCI_LOOKUP_CLASS, dev->device_class); + if (strcmp("VGA compatible controller", device_class) == 0 || strcmp("3D controller", device_class) == 0) { + strncpy(gpu, pci_lookup_name(pacc, buffer, sizeof(buffer), PCI_LOOKUP_DEVICE | PCI_LOOKUP_VENDOR, dev->vendor_id, dev->device_id), BUF_SIZE - 1); + if (gpu_index == index) { + found = true; + break; + } else { + gpu_index++; + } } - if (found == false) *gpu = '\0'; // empty string, so it will not be printed + dev = dev->next; + } - pci_cleanup(pacc); + if (found == false) { + *gpu = '\0'; + } - /* remove unneeded information */ - for (int i = 0; i < COUNT(gpu_config); ++i) { - if (gpu_config[i].repl_str == NULL) { - remove_substring(gpu, gpu_config[i].substring, gpu_config[i].length); - } else { - replace_substring(gpu, gpu_config[i].substring, gpu_config[i].repl_str, gpu_config[i].length, gpu_config[i].repl_len); - } + pci_cleanup(pacc); + + for (int i = 0; i < COUNT(gpu_config); ++i) { + if (gpu_config[i].repl_str == NULL) { + remove_substring(gpu, gpu_config[i].substring, gpu_config[i].length); + } else { + replace_substring(gpu, gpu_config[i].substring, gpu_config[i].repl_str, gpu_config[i].length, gpu_config[i].repl_len); } + } - truncate_spaces(gpu); + truncate_spaces(gpu); - return gpu; + return gpu; } static char *get_gpu1() { - return find_gpu(0); -} - -static char *get_gpu2() { - return find_gpu(1); + return find_gpu(0); } static char *get_memory() { - int total_memory, used_memory; - int total, shared, memfree, buffers, cached, reclaimable; + int total_memory, used_memory; + int total, shared, memfree, buffers, cached, reclaimable; - FILE *meminfo = fopen("/proc/meminfo", "r"); /* get infomation from meminfo */ - if(meminfo == NULL) { - status = -1; - halt_and_catch_fire("Unable to open meminfo"); - } + FILE *meminfo = fopen("/proc/meminfo", "r"); + if (meminfo == NULL) { + status = -1; + halt_and_catch_fire("Unable to open meminfo"); + } - /* We parse through all lines of meminfo and scan for the information we need */ - char *line = NULL; // allocation handled automatically by getline() - size_t len; /* unused */ + char *line = NULL; + size_t len; - /* parse until EOF */ - while (getline(&line, &len, meminfo) != -1) { - /* if sscanf doesn't find a match, pointer is untouched */ - sscanf(line, "MemTotal: %d", &total); - sscanf(line, "Shmem: %d", &shared); - sscanf(line, "MemFree: %d", &memfree); - sscanf(line, "Buffers: %d", &buffers); - sscanf(line, "Cached: %d", &cached); - sscanf(line, "SReclaimable: %d", &reclaimable); - } + while (getline(&line, &len, meminfo) != -1) { + sscanf(line, "MemTotal: %d", &total); + sscanf(line, "Shmem: %d", &shared); + sscanf(line, "MemFree: %d", &memfree); + sscanf(line, "Buffers: %d", &buffers); + sscanf(line, "Cached: %d", &cached); + sscanf(line, "SReclaimable: %d", &reclaimable); + } - free(line); + free(line); + fclose(meminfo); - fclose(meminfo); + used_memory = (total + shared - memfree - buffers - cached - reclaimable) / 1024; + total_memory = total / 1024; + int percentage = (int) (100 * (used_memory / (double) total_memory)); - /* use same calculation as neofetch */ - used_memory = (total + shared - memfree - buffers - cached - reclaimable) / 1024; - total_memory = total / 1024; - int percentage = (int) (100 * (used_memory / (double) total_memory)); + char *memory = malloc(BUF_SIZE); + snprintf(memory, BUF_SIZE, "%dMiB / %dMiB (%d%%)", used_memory, total_memory, percentage); - char *memory = malloc(BUF_SIZE); - snprintf(memory, BUF_SIZE, "%dMiB / %dMiB (%d%%)", used_memory, total_memory, percentage); - - return memory; -} - -static char *get_disk_usage(const char *folder) { - char *disk_usage = malloc(BUF_SIZE); - long total, used, free; - int percentage; - status = statvfs(folder, &file_stats); - halt_and_catch_fire("Error getting disk usage for %s", folder); - total = file_stats.f_blocks * file_stats.f_frsize; - free = file_stats.f_bfree * file_stats.f_frsize; - used = total - free; - percentage = (used / (double) total) * 100; -#define TO_GB(A) ((A) / (1024.0 * 1024 * 1024)) - snprintf(disk_usage, BUF_SIZE, "%.1fGiB / %.1fGiB (%d%%)", TO_GB(used), TO_GB(total), percentage); -#undef TO_GB - return disk_usage; -} - -static char *get_disk_usage_root() { - return get_disk_usage("/"); -} - -static char *get_disk_usage_home() { - return get_disk_usage("/home"); + return memory; } static char *get_colors1() { - char *colors1 = malloc(BUF_SIZE); - char *s = colors1; + char *colors1 = malloc(BUF_SIZE); + char *s = colors1; - for(int i = 0; i < 8; i++) { - sprintf(s, "\e[4%dm ", i); - s += 8; - } - snprintf(s, 5, "\e[0m"); + for (int i = 0; i < 8; i++) { + sprintf(s, "\e[4%dm ", i); + s += 8; + } + snprintf(s, 5, "\e[0m"); - return colors1; + return colors1; } static char *get_colors2() { - char *colors2 = malloc(BUF_SIZE); - char *s = colors2; + char *colors2 = malloc(BUF_SIZE); + char *s = colors2; - for(int i = 8; i < 16; i++) { - sprintf(s, "\e[48;5;%dm ", i); - s += 12 + (i >= 10 ? 1 : 0); - } - snprintf(s, 5, "\e[0m"); + for (int i = 8; i < 16; i++) { + sprintf(s, "\e[48;5;%dm ", i); + s += 12 + (i >= 10 ? 1 : 0); + } + snprintf(s, 5, "\e[0m"); - return colors2; + return colors2; } static char *spacer() { - return calloc(1, 1); // freeable, null-terminated string of length 1 + return calloc(1, 1); } char *get_cache_file() { - char *cache_file = malloc(BUF_SIZE); - char *env = getenv("XDG_CACHE_HOME"); - if(env == NULL) - snprintf(cache_file, BUF_SIZE, "%s/.cache/paleofetch", getenv("HOME")); - else - snprintf(cache_file, BUF_SIZE, "%s/paleofetch", env); + char *cache_file = malloc(BUF_SIZE); + char *env = getenv("XDG_CACHE_HOME"); + if (env == NULL) { + snprintf(cache_file, BUF_SIZE, "%s/.cache/paleofetch", getenv("HOME")); + } else { + snprintf(cache_file, BUF_SIZE, "%s/paleofetch", env); + } - return cache_file; + return cache_file; } -/* This isn't especially robust, but as long as we're the only one writing - * to our cache file, the format is simple, effective, and fast. One way - * we might get in trouble would be if the user decided not to have any - * sort of sigil (like ':') after their labels. */ char *search_cache(char *cache_data, char *label) { - char *start = strstr(cache_data, label); - if(start == NULL) { - status = ENODATA; - halt_and_catch_fire("cache miss on key '%s'; need to --recache?", label); - } - start += strlen(label); - char *end = strchr(start, ';'); - char *buf = calloc(1, BUF_SIZE); - // skip past the '=' and stop just before the ';' - strncpy(buf, start + 1, end - start - 1); + char *start = strstr(cache_data, label); + if (start == NULL) { + status = ENODATA; + halt_and_catch_fire("cache miss on key '%s'; need to --recache?", label); + } + start += strlen(label); + char *end = strchr(start, ';'); + char *buf = calloc(1, BUF_SIZE); + strncpy(buf, start + 1, end - start - 1); - return buf; + return buf; } char *get_value(struct conf c, int read_cache, char *cache_data) { - char *value; + char *value; - // If the user's config specifies that this value should be cached - if(c.cached && read_cache) // and we have a cache to read from - value = search_cache(cache_data, c.label); // grab it from the cache - else { - // Otherwise, call the associated function to get the value - value = c.function(); - if(c.cached) { // and append it to our cache data if appropriate - char *buf = malloc(BUF_SIZE); - sprintf(buf, "%s=%s;", c.label, value); - strcat(cache_data, buf); - free(buf); - } + if (c.cached && read_cache) { + value = search_cache(cache_data, c.label); + } else { + value = c.function(); + if (c.cached) { + char *buf = malloc(BUF_SIZE); + sprintf(buf, "%s=%s;", c.label, value); + strcat(cache_data, buf); + free(buf); } + } - return value; + return value; } int main(int argc, char *argv[]) { - char *cache, *cache_data = NULL; - FILE *cache_file; - int read_cache; + char *cache, *cache_data = NULL; + FILE *cache_file; + int read_cache; + char *wayland_display = getenv("WAYLAND_DISPLAY"); + if (wayland_display != NULL) { // TODO + } else { + Display *display; status = uname(&uname_info); halt_and_catch_fire("uname failed"); status = sysinfo(&my_sysinfo); @@ -721,60 +731,57 @@ int main(int argc, char *argv[]) { display = XOpenDisplay(NULL); cache = get_cache_file(); - if(argc == 2 && strcmp(argv[1], "--recache") == 0) - read_cache = 0; - else { - cache_file = fopen(cache, "r"); - read_cache = cache_file != NULL; + if (argc == 2 && strcmp(argv[1], "--recache") == 0) { + read_cache = 0; + } else { + cache_file = fopen(cache, "r"); + read_cache = cache_file != NULL; } - if(!read_cache) - cache_data = calloc(4, BUF_SIZE); // should be enough - else { - size_t len; /* unused */ - getline(&cache_data, &len, cache_file); - fclose(cache_file); // We just need the first (and only) line. + if (!read_cache) { + cache_data = calloc(4, BUF_SIZE); + } else { + size_t len; + getline(&cache_data, &len, cache_file); + fclose(cache_file); } int offset = 0; for (int i = 0; i < COUNT(LOGO); i++) { - // If we've run out of information to show... - if(i >= COUNT(config) - offset) // just print the next line of the logo - printf("%s\n", LOGO[i]); - else { - // Otherwise, we've got a bit of work to do. - char *label = config[i+offset].label, - *value = get_value(config[i+offset], read_cache, cache_data); - if (strcmp(value, "") != 0) { // check if value is an empty string - printf("%s"COLOR"%s\e[0m%s\n", LOGO[i], label, value); // just print if not empty - } else { - if (strcmp(label, "") != 0) { // check if label is empty, otherwise it's a spacer - ++offset; // print next line of information - free(value); // free memory allocated for empty value - label = config[i+offset].label; // read new label and value - value = get_value(config[i+offset], read_cache, cache_data); - } - printf("%s"COLOR"%s\e[0m%s\n", LOGO[i], label, value); - } + if (i >= COUNT(config) - offset) { + printf("%s\n", LOGO[i]); + } else { + char *label = config[i+offset].label, *value = get_value(config[i+offset], read_cache, cache_data); + if (strcmp(value, "") != 0) { + printf("%s"COLOR"%s\e[0m%s\n", LOGO[i], label, value); + } else { + if (strcmp(label, "") != 0) { + ++offset; free(value); - + label = config[i+offset].label; + value = get_value(config[i+offset], read_cache, cache_data); + } + printf("%s"COLOR"%s\e[0m%s\n", LOGO[i], label, value); } + free(value); + + } } puts("\e[0m"); - /* Write out our cache data (if we have any). */ - if(!read_cache && *cache_data) { - cache_file = fopen(cache, "w"); - fprintf(cache_file, "%s", cache_data); - fclose(cache_file); + if (!read_cache && *cache_data) { + cache_file = fopen(cache, "w"); + fprintf(cache_file, "%s", cache_data); + fclose(cache_file); } free(cache); free(cache_data); - if(display != NULL) { - XCloseDisplay(display); + if (display != NULL) { + XCloseDisplay(display); } + } - return 0; + return 0; } diff --git a/paleofetch.h b/paleofetch.h index 2b0444c..e808e68 100644 --- a/paleofetch.h +++ b/paleofetch.h @@ -14,10 +14,7 @@ static char *get_title(), *get_terminal(), *get_cpu(), *get_gpu1(), - *get_gpu2(), *get_memory(), - *get_disk_usage_root(), - *get_disk_usage_home(), *get_colors1(), *get_colors2(), *spacer();