diff --git a/LICENSE b/LICENSE index 9fae663..859df8b 100644 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,6 @@ ISC License -Copyright 2016-2025 Aaron Marcher +Copyright 2016-2026 Aaron Marcher Copyright 2016 Roy Freytag Copyright 2016 Vincent Loupmon @@ -21,7 +21,7 @@ Copyright 2018 Ian Remmler Copyright 2016-2019 Joerg Jung Copyright 2019 Ryan Kes Copyright 2019 Cem Keylan -Copyright 2019 Dimitris Papastamos +Copyright 2019 Spiros Thanasoulas Copyright 2019-2022 Ingo Feinerer Copyright 2020 Alexandre Ratchov Copyright 2020 Mart Lubbers diff --git a/components/battery.c b/components/battery.c index 1c753f9..f2dc393 100644 --- a/components/battery.c +++ b/components/battery.c @@ -62,7 +62,7 @@ { "Not charging", "o" }, }; size_t i; - char path[PATH_MAX], state[12]; + char path[PATH_MAX], state[13]; if (esnprintf(path, sizeof(path), POWER_SUPPLY_STATUS, bat) < 0) return NULL; @@ -81,7 +81,7 @@ { uintmax_t charge_now, current_now, m, h; double timeleft; - char path[PATH_MAX], state[12]; + char path[PATH_MAX], state[13]; if (esnprintf(path, sizeof(path), POWER_SUPPLY_STATUS, bat) < 0) return NULL; diff --git a/components/battery.o b/components/battery.o new file mode 100644 index 0000000..dea927a Binary files /dev/null and b/components/battery.o differ diff --git a/components/cat.o b/components/cat.o new file mode 100644 index 0000000..ffc6a18 Binary files /dev/null and b/components/cat.o differ diff --git a/components/cpu.o b/components/cpu.o new file mode 100644 index 0000000..3d5efac Binary files /dev/null and b/components/cpu.o differ diff --git a/components/datetime.o b/components/datetime.o new file mode 100644 index 0000000..bedc621 Binary files /dev/null and b/components/datetime.o differ diff --git a/components/disk.o b/components/disk.o new file mode 100644 index 0000000..b051fdd Binary files /dev/null and b/components/disk.o differ diff --git a/components/entropy.o b/components/entropy.o new file mode 100644 index 0000000..0611d9c Binary files /dev/null and b/components/entropy.o differ diff --git a/components/hostname.o b/components/hostname.o new file mode 100644 index 0000000..ed8e54a Binary files /dev/null and b/components/hostname.o differ diff --git a/components/ip.o b/components/ip.o new file mode 100644 index 0000000..7c75c70 Binary files /dev/null and b/components/ip.o differ diff --git a/components/kernel_release.o b/components/kernel_release.o new file mode 100644 index 0000000..d214b3c Binary files /dev/null and b/components/kernel_release.o differ diff --git a/components/keyboard_indicators.o b/components/keyboard_indicators.o new file mode 100644 index 0000000..fddf659 Binary files /dev/null and b/components/keyboard_indicators.o differ diff --git a/components/keymap.o b/components/keymap.o new file mode 100644 index 0000000..bd690f8 Binary files /dev/null and b/components/keymap.o differ diff --git a/components/load_avg.o b/components/load_avg.o new file mode 100644 index 0000000..946966e Binary files /dev/null and b/components/load_avg.o differ diff --git a/components/netspeeds.o b/components/netspeeds.o new file mode 100644 index 0000000..ffcb639 Binary files /dev/null and b/components/netspeeds.o differ diff --git a/components/num_files.o b/components/num_files.o new file mode 100644 index 0000000..4fdd111 Binary files /dev/null and b/components/num_files.o differ diff --git a/components/ram.c b/components/ram.c index 15c4b74..bf71dcf 100644 --- a/components/ram.c +++ b/components/ram.c @@ -11,36 +11,45 @@ ram_free(const char *unused) { uintmax_t free; + FILE *fp; - if (pscanf("/proc/meminfo", - "MemTotal: %ju kB\n" - "MemFree: %ju kB\n" - "MemAvailable: %ju kB\n", - &free, &free, &free) != 3) + if (!(fp = fopen("/proc/meminfo", "r"))) return NULL; + if (lscanf(fp, "MemFree:", "%ju kB", &free) != 1) { + fclose(fp); + return NULL; + } + + fclose(fp); return fmt_human(free * 1024, 1024); } const char * ram_perc(const char *unused) { - uintmax_t total, free, buffers, cached; + uintmax_t total, free, buffers, cached, shmem, sreclaimable; int percent; + FILE *fp; - if (pscanf("/proc/meminfo", - "MemTotal: %ju kB\n" - "MemFree: %ju kB\n" - "MemAvailable: %ju kB\n" - "Buffers: %ju kB\n" - "Cached: %ju kB\n", - &total, &free, &buffers, &buffers, &cached) != 5) + if (!(fp = fopen("/proc/meminfo", "r"))) return NULL; + if (lscanf(fp, "MemTotal:", "%ju kB", &total) != 1 || + lscanf(fp, "MemFree:", "%ju kB", &free) != 1 || + lscanf(fp, "Buffers:", "%ju kB", &buffers) != 1 || + lscanf(fp, "Cached:", "%ju kB", &cached) != 1 || + lscanf(fp, "Shmem:", "%ju kB", &shmem) != 1 || + lscanf(fp, "SReclaimable:", "%ju kB", &sreclaimable) != 1) { + fclose(fp); + return NULL; + } + fclose(fp); + if (total == 0) return NULL; - percent = 100 * ((total - free) - (buffers + cached)) / total; + percent = 100 * (total - free - buffers - cached - sreclaimable + shmem) / total; return bprintf("%d", percent); } @@ -59,18 +68,24 @@ const char * ram_used(const char *unused) { - uintmax_t total, free, buffers, cached, used; + uintmax_t total, free, buffers, cached, used, shmem, sreclaimable; + FILE *fp; - if (pscanf("/proc/meminfo", - "MemTotal: %ju kB\n" - "MemFree: %ju kB\n" - "MemAvailable: %ju kB\n" - "Buffers: %ju kB\n" - "Cached: %ju kB\n", - &total, &free, &buffers, &buffers, &cached) != 5) + if (!(fp = fopen("/proc/meminfo", "r"))) return NULL; - used = (total - free - buffers - cached); + if (lscanf(fp, "MemTotal:", "%ju kB", &total) != 1 || + lscanf(fp, "MemFree:", "%ju kB", &free) != 1 || + lscanf(fp, "Buffers:", "%ju kB", &buffers) != 1 || + lscanf(fp, "Cached:", "%ju kB", &cached) != 1 || + lscanf(fp, "Shmem:", "%ju kB", &shmem) != 1 || + lscanf(fp, "SReclaimable:", "%ju kB", &sreclaimable) != 1) { + fclose(fp); + return NULL; + } + fclose(fp); + + used = total - free - buffers - cached - sreclaimable + shmem; return fmt_human(used * 1024, 1024); } #elif defined(__OpenBSD__) diff --git a/components/ram.o b/components/ram.o new file mode 100644 index 0000000..a3d7f78 Binary files /dev/null and b/components/ram.o differ diff --git a/components/run_command.o b/components/run_command.o new file mode 100644 index 0000000..2beb247 Binary files /dev/null and b/components/run_command.o differ diff --git a/components/swap.o b/components/swap.o new file mode 100644 index 0000000..acb689c Binary files /dev/null and b/components/swap.o differ diff --git a/components/temperature.o b/components/temperature.o new file mode 100644 index 0000000..baa2598 Binary files /dev/null and b/components/temperature.o differ diff --git a/components/uptime.o b/components/uptime.o new file mode 100644 index 0000000..63cdc0d Binary files /dev/null and b/components/uptime.o differ diff --git a/components/user.o b/components/user.o new file mode 100644 index 0000000..32644f5 Binary files /dev/null and b/components/user.o differ diff --git a/components/volume.c b/components/volume.c index 6cec556..692742a 100644 --- a/components/volume.c +++ b/components/volume.c @@ -89,6 +89,8 @@ if (c->addr == addr) break; } + if (c == NULL) + return; c->val = val; } @@ -217,3 +219,33 @@ return bprintf("%d", v & 0xff); } #endif + +const char * +vol_perc_pw(const char *sink) +{ + FILE *fp; + char buf[64], cmd[64]; + double v; + + if (esnprintf(cmd, sizeof(cmd), "wpctl get-volume %s", sink) < 0) + return NULL; + + if (!(fp = popen(cmd, "r"))) { + warn("popen '%s':", cmd); + return NULL; + } + + if (!fgets(buf, sizeof(buf), fp)) { + pclose(fp); + return NULL; + } + pclose(fp); + + if (strstr(buf, "[MUTED]")) + return "mute"; + + if (sscanf(buf, "Volume: %lf", &v) != 1) + return NULL; + + return bprintf("%d%%", (int)(v * 100 + 0.5)); +} diff --git a/components/volume.o b/components/volume.o new file mode 100644 index 0000000..a63a146 Binary files /dev/null and b/components/volume.o differ diff --git a/components/wifi.c b/components/wifi.c index 23af201..8b33baa 100644 --- a/components/wifi.c +++ b/components/wifi.c @@ -110,10 +110,10 @@ } if (strcmp(ifr.ifr_name, interface) != 0) { strcpy(ifr.ifr_name, interface); - if (ioctl(ifsock, SIOCGIFINDEX, &ifr) != 0) { - warn("ioctl 'SIOCGIFINDEX':"); - return -1; - } + } + if (ioctl(ifsock, SIOCGIFINDEX, &ifr) != 0) { + warn("ioctl 'SIOCGIFINDEX':"); + return -1; } return ifr.ifr_ifindex; } diff --git a/components/wifi.o b/components/wifi.o new file mode 100644 index 0000000..ab8776a Binary files /dev/null and b/components/wifi.o differ diff --git a/config.def.h b/config.def.h index 100093e..557a9d6 100644 --- a/config.def.h +++ b/config.def.h @@ -65,6 +65,9 @@ static const char unknown_str[] = "n/a"; * wifi_perc WiFi signal in percent interface name (wlan0) */ static const struct arg args[] = { - /* function format argument */ - { datetime, "%s", "%F %T" }, + /* function format argument */ + { wifi_perc, " wifi %s%% |", "wlan0" }, + { battery_perc, " bat %s%% |", "BAT0" }, + { vol_perc_pw, " vol %s |", "@DEFAULT_AUDIO_SINK@" }, + { datetime, " %s", "%F %T" }, }; diff --git a/config.h b/config.h new file mode 100644 index 0000000..e39941e --- /dev/null +++ b/config.h @@ -0,0 +1,74 @@ +/* See LICENSE file for copyright and license details. */ + +/* interval between updates (in ms) */ +const unsigned int interval = 1000; + +/* text to show if no value can be retrieved */ +static const char unknown_str[] = "n/a"; + +/* maximum output string length */ +#define MAXLEN 2048 + +/* + * function description argument (example) + * + * battery_perc battery percentage battery name (BAT0) + * NULL on OpenBSD/FreeBSD + * battery_remaining battery remaining HH:MM battery name (BAT0) + * NULL on OpenBSD/FreeBSD + * battery_state battery charging state battery name (BAT0) + * NULL on OpenBSD/FreeBSD + * cat read arbitrary file path + * cpu_freq cpu frequency in MHz NULL + * cpu_perc cpu usage in percent NULL + * datetime date and time format string (%F %T) + * disk_free free disk space in GB mountpoint path (/) + * disk_perc disk usage in percent mountpoint path (/) + * disk_total total disk space in GB mountpoint path (/) + * disk_used used disk space in GB mountpoint path (/) + * entropy available entropy NULL + * gid GID of current user NULL + * hostname hostname NULL + * ipv4 IPv4 address interface name (eth0) + * ipv6 IPv6 address interface name (eth0) + * kernel_release `uname -r` NULL + * keyboard_indicators caps/num lock indicators format string (c?n?) + * see keyboard_indicators.c + * keymap layout (variant) of current NULL + * keymap + * load_avg load average NULL + * netspeed_rx receive network speed interface name (wlan0) + * netspeed_tx transfer network speed interface name (wlan0) + * num_files number of files in a directory path + * (/home/foo/Inbox/cur) + * ram_free free memory in GB NULL + * ram_perc memory usage in percent NULL + * ram_total total memory size in GB NULL + * ram_used used memory in GB NULL + * run_command custom shell command command (echo foo) + * swap_free free swap in GB NULL + * swap_perc swap usage in percent NULL + * swap_total total swap size in GB NULL + * swap_used used swap in GB NULL + * temp temperature in degree celsius sensor file + * (/sys/class/thermal/...) + * NULL on OpenBSD + * thermal zone on FreeBSD + * (tz0, tz1, etc.) + * uid UID of current user NULL + * up interface is running interface name (eth0) + * uptime system uptime NULL + * username username of current user NULL + * vol_perc OSS/ALSA volume in percent mixer file (/dev/mixer) + * NULL on OpenBSD/FreeBSD + * wifi_essid WiFi ESSID interface name (wlan0) + * wifi_perc WiFi signal in percent interface name (wlan0) + */ +static const struct arg args[] = { + /* function format argument */ + {run_command, "%s | ", "playerctl metadata --player=spotify --format '{{artist}} - {{title}}'"}, + {battery_perc, " bat %s%%", "BAT0"}, + {battery_state, "%s |", "BAT0"}, + {vol_perc_pw, " vol %s |", "@DEFAULT_AUDIO_SINK@"}, + {datetime, " %s", "%d.%m.%Y | %H:%M"}, +}; diff --git a/slstatus b/slstatus new file mode 100755 index 0000000..53cd485 Binary files /dev/null and b/slstatus differ diff --git a/slstatus.h b/slstatus.h index 394281c..d58dda9 100644 --- a/slstatus.h +++ b/slstatus.h @@ -79,6 +79,7 @@ const char *username(const char *unused); /* volume */ const char *vol_perc(const char *card); +const char *vol_perc_pw(const char *sink); /* wifi */ const char *wifi_essid(const char *interface); diff --git a/slstatus.o b/slstatus.o new file mode 100644 index 0000000..b541cd5 Binary files /dev/null and b/slstatus.o differ diff --git a/util.c b/util.c index bca9b2e..d33cf9d 100644 --- a/util.c +++ b/util.c @@ -139,3 +139,20 @@ pscanf(const char *path, const char *fmt, ...) return (n == EOF) ? -1 : n; } + +int +lscanf(FILE *fp, const char *key, const char *fmt, void *res) +{ + int n; + char line[256]; + + n = -1; + while (fgets(line, sizeof(line), fp)) + if (strncmp(line, key, strlen(key)) == 0) { + n = sscanf(line + strlen(key), fmt, res); + break; + } + + rewind(fp); + return (n == 1) ? 1 : -1; +} diff --git a/util.h b/util.h index cf4b027..7a960aa 100644 --- a/util.h +++ b/util.h @@ -1,5 +1,6 @@ /* See LICENSE file for copyright and license details. */ #include +#include extern char buf[1024]; @@ -14,3 +15,4 @@ int esnprintf(char *str, size_t size, const char *fmt, ...); const char *bprintf(const char *fmt, ...); const char *fmt_human(uintmax_t num, int base); int pscanf(const char *path, const char *fmt, ...); +int lscanf(FILE *fp, const char *key, const char *fmt, void *res); diff --git a/util.o b/util.o new file mode 100644 index 0000000..1c4a2f0 Binary files /dev/null and b/util.o differ