From fc7f734a48c7587ba001bed7f9f012f7105301dd Mon Sep 17 00:00:00 2001 From: TolaMironcenko Date: Wed, 10 Jul 2024 09:24:28 +0700 Subject: [PATCH] added slstatus --- dwm/slstatus/.vscode/settings.json | 5 + dwm/slstatus/LICENSE | 43 +++ dwm/slstatus/Makefile | 69 +++++ dwm/slstatus/README | 65 +++++ dwm/slstatus/arg.h | 33 +++ dwm/slstatus/components/battery.c | 247 ++++++++++++++++ dwm/slstatus/components/battery.o | Bin 0 -> 5136 bytes dwm/slstatus/components/cat.c | 32 ++ dwm/slstatus/components/cat.o | Bin 0 -> 2088 bytes dwm/slstatus/components/cpu.c | 157 ++++++++++ dwm/slstatus/components/cpu.o | Bin 0 -> 3136 bytes dwm/slstatus/components/datetime.c | 20 ++ dwm/slstatus/components/datetime.o | Bin 0 -> 1920 bytes dwm/slstatus/components/disk.c | 59 ++++ dwm/slstatus/components/disk.o | Bin 0 -> 3120 bytes dwm/slstatus/components/entropy.c | 29 ++ dwm/slstatus/components/entropy.o | Bin 0 -> 1784 bytes dwm/slstatus/components/hostname.c | 17 ++ dwm/slstatus/components/hostname.o | Bin 0 -> 1640 bytes dwm/slstatus/components/ip.c | 61 ++++ dwm/slstatus/components/ip.o | Bin 0 -> 2544 bytes dwm/slstatus/components/kernel_release.c | 19 ++ dwm/slstatus/components/kernel_release.o | Bin 0 -> 1832 bytes dwm/slstatus/components/keyboard_indicators.c | 50 ++++ dwm/slstatus/components/keyboard_indicators.o | Bin 0 -> 2408 bytes dwm/slstatus/components/keymap.c | 86 ++++++ dwm/slstatus/components/keymap.o | Bin 0 -> 4024 bytes dwm/slstatus/components/load_avg.c | 19 ++ dwm/slstatus/components/load_avg.o | Bin 0 -> 1864 bytes dwm/slstatus/components/netspeeds.c | 129 +++++++++ dwm/slstatus/components/netspeeds.o | Bin 0 -> 2760 bytes dwm/slstatus/components/num_files.c | 32 ++ dwm/slstatus/components/num_files.o | Bin 0 -> 2152 bytes dwm/slstatus/components/ram.c | 212 ++++++++++++++ dwm/slstatus/components/ram.o | Bin 0 -> 3072 bytes dwm/slstatus/components/run_command.c | 31 ++ dwm/slstatus/components/run_command.o | Bin 0 -> 2104 bytes dwm/slstatus/components/swap.c | 274 ++++++++++++++++++ dwm/slstatus/components/swap.o | Bin 0 -> 3880 bytes dwm/slstatus/components/temperature.c | 73 +++++ dwm/slstatus/components/temperature.o | Bin 0 -> 1704 bytes dwm/slstatus/components/uptime.c | 34 +++ dwm/slstatus/components/uptime.o | Bin 0 -> 1968 bytes dwm/slstatus/components/user.c | 33 +++ dwm/slstatus/components/user.o | Bin 0 -> 2192 bytes dwm/slstatus/components/volume.c | 219 ++++++++++++++ dwm/slstatus/components/volume.o | Bin 0 -> 3616 bytes dwm/slstatus/components/wifi.c | 267 +++++++++++++++++ dwm/slstatus/components/wifi.o | Bin 0 -> 4264 bytes dwm/slstatus/config.def.h | 70 +++++ dwm/slstatus/config.h | 77 +++++ dwm/slstatus/config.mk | 22 ++ dwm/slstatus/slstatus | Bin 0 -> 31832 bytes dwm/slstatus/slstatus.1 | 47 +++ dwm/slstatus/slstatus.c | 134 +++++++++ dwm/slstatus/slstatus.h | 84 ++++++ dwm/slstatus/slstatus.o | Bin 0 -> 6512 bytes dwm/slstatus/util.c | 141 +++++++++ dwm/slstatus/util.h | 16 + dwm/slstatus/util.o | Bin 0 -> 5552 bytes 60 files changed, 2906 insertions(+) create mode 100644 dwm/slstatus/.vscode/settings.json create mode 100644 dwm/slstatus/LICENSE create mode 100644 dwm/slstatus/Makefile create mode 100644 dwm/slstatus/README create mode 100644 dwm/slstatus/arg.h create mode 100644 dwm/slstatus/components/battery.c create mode 100644 dwm/slstatus/components/battery.o create mode 100644 dwm/slstatus/components/cat.c create mode 100644 dwm/slstatus/components/cat.o create mode 100644 dwm/slstatus/components/cpu.c create mode 100644 dwm/slstatus/components/cpu.o create mode 100644 dwm/slstatus/components/datetime.c create mode 100644 dwm/slstatus/components/datetime.o create mode 100644 dwm/slstatus/components/disk.c create mode 100644 dwm/slstatus/components/disk.o create mode 100644 dwm/slstatus/components/entropy.c create mode 100644 dwm/slstatus/components/entropy.o create mode 100644 dwm/slstatus/components/hostname.c create mode 100644 dwm/slstatus/components/hostname.o create mode 100644 dwm/slstatus/components/ip.c create mode 100644 dwm/slstatus/components/ip.o create mode 100644 dwm/slstatus/components/kernel_release.c create mode 100644 dwm/slstatus/components/kernel_release.o create mode 100644 dwm/slstatus/components/keyboard_indicators.c create mode 100644 dwm/slstatus/components/keyboard_indicators.o create mode 100644 dwm/slstatus/components/keymap.c create mode 100644 dwm/slstatus/components/keymap.o create mode 100644 dwm/slstatus/components/load_avg.c create mode 100644 dwm/slstatus/components/load_avg.o create mode 100644 dwm/slstatus/components/netspeeds.c create mode 100644 dwm/slstatus/components/netspeeds.o create mode 100644 dwm/slstatus/components/num_files.c create mode 100644 dwm/slstatus/components/num_files.o create mode 100644 dwm/slstatus/components/ram.c create mode 100644 dwm/slstatus/components/ram.o create mode 100644 dwm/slstatus/components/run_command.c create mode 100644 dwm/slstatus/components/run_command.o create mode 100644 dwm/slstatus/components/swap.c create mode 100644 dwm/slstatus/components/swap.o create mode 100644 dwm/slstatus/components/temperature.c create mode 100644 dwm/slstatus/components/temperature.o create mode 100644 dwm/slstatus/components/uptime.c create mode 100644 dwm/slstatus/components/uptime.o create mode 100644 dwm/slstatus/components/user.c create mode 100644 dwm/slstatus/components/user.o create mode 100644 dwm/slstatus/components/volume.c create mode 100644 dwm/slstatus/components/volume.o create mode 100644 dwm/slstatus/components/wifi.c create mode 100644 dwm/slstatus/components/wifi.o create mode 100644 dwm/slstatus/config.def.h create mode 100644 dwm/slstatus/config.h create mode 100644 dwm/slstatus/config.mk create mode 100755 dwm/slstatus/slstatus create mode 100644 dwm/slstatus/slstatus.1 create mode 100644 dwm/slstatus/slstatus.c create mode 100644 dwm/slstatus/slstatus.h create mode 100644 dwm/slstatus/slstatus.o create mode 100644 dwm/slstatus/util.c create mode 100644 dwm/slstatus/util.h create mode 100644 dwm/slstatus/util.o diff --git a/dwm/slstatus/.vscode/settings.json b/dwm/slstatus/.vscode/settings.json new file mode 100644 index 0000000..2fe711a --- /dev/null +++ b/dwm/slstatus/.vscode/settings.json @@ -0,0 +1,5 @@ +{ + "files.associations": { + "slstatus.h": "c" + } +} \ No newline at end of file diff --git a/dwm/slstatus/LICENSE b/dwm/slstatus/LICENSE new file mode 100644 index 0000000..8bee9c8 --- /dev/null +++ b/dwm/slstatus/LICENSE @@ -0,0 +1,43 @@ +ISC License + +Copyright 2016-2022 Aaron Marcher + +Copyright 2016 Roy Freytag +Copyright 2016 Vincent Loupmon +Copyright 2016 Daniel Walter +Copyright 2016-2018 Ali H. Fardan +Copyright 2016 Jody Leonard +Copyright 2016-2018 Quentin Rameau +Copyright 2016 Mike Coddington +Copyright 2016-2018 Ivan J. +Copyright 2017 Tobias Stoeckmann +Copyright 2017-2018 Laslo Hunhold +Copyright 2018 Darron Anderson +Copyright 2018 Josuah Demangeon +Copyright 2018 Tobias Tschinkowitz +Copyright 2018 David Demelier +Copyright 2018-2012 Michael Buch +Copyright 2018 Ian Remmler +Copyright 2016-2019 Joerg Jung +Copyright 2019 Ryan Kes +Copyright 2019 Cem Keylan +Copyright 2019 Dimitris Papastamos +Copyright 2019-2022 Ingo Feinerer +Copyright 2020 Alexandre Ratchov +Copyright 2020 Mart Lubbers +Copyright 2020 Daniel Moch +Copyright 2022 Nickolas Raymond Kaczynski +Copyright 2022 Patrick Iacob +Copyright 2021-2022 Steven Ward + +Permission to use, copy, modify, and/or distribute this software for any +purpose with or without fee is hereby granted, provided that the above +copyright notice and this permission notice appear in all copies. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. diff --git a/dwm/slstatus/Makefile b/dwm/slstatus/Makefile new file mode 100644 index 0000000..7a18274 --- /dev/null +++ b/dwm/slstatus/Makefile @@ -0,0 +1,69 @@ +# See LICENSE file for copyright and license details +# slstatus - suckless status monitor +.POSIX: + +include config.mk + +REQ = util +COM =\ + components/battery\ + components/cat\ + components/cpu\ + components/datetime\ + components/disk\ + components/entropy\ + components/hostname\ + components/ip\ + components/kernel_release\ + components/keyboard_indicators\ + components/keymap\ + components/load_avg\ + components/netspeeds\ + components/num_files\ + components/ram\ + components/run_command\ + components/swap\ + components/temperature\ + components/uptime\ + components/user\ + components/volume\ + components/wifi + +all: slstatus + +$(COM:=.o): config.mk $(REQ:=.h) slstatus.h +slstatus.o: slstatus.c slstatus.h arg.h config.h config.mk $(REQ:=.h) + +.c.o: + $(CC) -o $@ -c $(CPPFLAGS) $(CFLAGS) $< + +config.h: + cp config.def.h $@ + +slstatus: slstatus.o $(COM:=.o) $(REQ:=.o) + $(CC) -o $@ $(LDFLAGS) $(COM:=.o) $(REQ:=.o) slstatus.o $(LDLIBS) + +clean: + rm -f slstatus slstatus.o $(COM:=.o) $(REQ:=.o) slstatus-${VERSION}.tar.gz + +dist: + rm -rf "slstatus-$(VERSION)" + mkdir -p "slstatus-$(VERSION)/components" + cp -R LICENSE Makefile README config.mk config.def.h \ + arg.h slstatus.h slstatus.c $(REQ:=.c) $(REQ:=.h) \ + slstatus.1 "slstatus-$(VERSION)" + cp -R $(COM:=.c) "slstatus-$(VERSION)/components" + tar -cf - "slstatus-$(VERSION)" | gzip -c > "slstatus-$(VERSION).tar.gz" + rm -rf "slstatus-$(VERSION)" + +install: all + mkdir -p "$(DESTDIR)$(PREFIX)/bin" + cp -f slstatus "$(DESTDIR)$(PREFIX)/bin" + chmod 755 "$(DESTDIR)$(PREFIX)/bin/slstatus" + mkdir -p "$(DESTDIR)$(MANPREFIX)/man1" + cp -f slstatus.1 "$(DESTDIR)$(MANPREFIX)/man1" + chmod 644 "$(DESTDIR)$(MANPREFIX)/man1/slstatus.1" + +uninstall: + rm -f "$(DESTDIR)$(PREFIX)/bin/slstatus" + rm -f "$(DESTDIR)$(MANPREFIX)/man1/slstatus.1" diff --git a/dwm/slstatus/README b/dwm/slstatus/README new file mode 100644 index 0000000..12d38bf --- /dev/null +++ b/dwm/slstatus/README @@ -0,0 +1,65 @@ +slstatus - suckless status +========================== +slstatus is a small tool for providing system status information to other +programs over the EWMH property of the root window (used by dwm(1)) or +standard input/output. It is designed to be as efficient as possible by +only issuing the minimum of system calls required. + + +Features +-------- +- Battery percentage/state/time left +- Cat (read file) +- CPU usage +- CPU frequency +- Custom shell commands +- Date and time +- Disk status (free storage, percentage, total storage and used storage) +- Available entropy +- Username/GID/UID +- Hostname +- IP address (IPv4 and IPv6) +- Kernel version +- Keyboard indicators +- Keymap +- Load average +- Network speeds (RX and TX) +- Number of files in a directory (hint: Maildir) +- Memory status (free memory, percentage, total memory and used memory) +- Swap status (free swap, percentage, total swap and used swap) +- Temperature +- Uptime +- Volume percentage +- WiFi signal percentage and ESSID + + +Requirements +------------ +Currently slstatus works on FreeBSD, Linux and OpenBSD. +In order to build slstatus you need the Xlib header files. + +- For volume percentage on Linux the kernel module `snd-mixer-oss` must be + loaded. +- For volume percentage on FreeBSD, `sndio` must be installed. + + +Installation +------------ +Edit config.mk to match your local setup (slstatus is installed into the +/usr/local namespace by default). + +Afterwards enter the following command to build and install slstatus (if +necessary as root): + + make clean install + + +Running slstatus +---------------- +See the man page for details. + + +Configuration +------------- +slstatus can be customized by creating a custom config.h and (re)compiling the +source code. This keeps it fast, secure and simple. diff --git a/dwm/slstatus/arg.h b/dwm/slstatus/arg.h new file mode 100644 index 0000000..5f1f408 --- /dev/null +++ b/dwm/slstatus/arg.h @@ -0,0 +1,33 @@ +/* See LICENSE file for copyright and license details. */ +#ifndef ARG_H +#define ARG_H + +extern char *argv0; + +/* int main(int argc, char *argv[]) */ +#define ARGBEGIN for (argv0 = *argv, *argv ? (argc--, argv++) : ((void *)0); \ + *argv && (*argv)[0] == '-' && (*argv)[1]; argc--, argv++) { \ + int i_, argused_; \ + if ((*argv)[1] == '-' && !(*argv)[2]) { \ + argc--, argv++; \ + break; \ + } \ + for (i_ = 1, argused_ = 0; (*argv)[i_]; i_++) { \ + switch ((*argv)[i_]) +#define ARGEND if (argused_) { \ + if ((*argv)[i_ + 1]) { \ + break; \ + } else { \ + argc--, argv++; \ + break; \ + } \ + } \ + } \ + } +#define ARGC() ((*argv)[i_]) +#define ARGF_(x) (((*argv)[i_ + 1]) ? (argused_ = 1, &((*argv)[i_ + 1])) : \ + (*(argv + 1)) ? (argused_ = 1, *(argv + 1)) : (x)) +#define EARGF(x) ARGF_(((x), exit(1), (char *)0)) +#define ARGF() ARGF_((char *)0) + +#endif diff --git a/dwm/slstatus/components/battery.c b/dwm/slstatus/components/battery.c new file mode 100644 index 0000000..1c753f9 --- /dev/null +++ b/dwm/slstatus/components/battery.c @@ -0,0 +1,247 @@ +/* See LICENSE file for copyright and license details. */ +#include +#include + +#include "../slstatus.h" +#include "../util.h" + +#if defined(__linux__) +/* + * https://www.kernel.org/doc/html/latest/power/power_supply_class.html + */ + #include + #include + #include + + #define POWER_SUPPLY_CAPACITY "/sys/class/power_supply/%s/capacity" + #define POWER_SUPPLY_STATUS "/sys/class/power_supply/%s/status" + #define POWER_SUPPLY_CHARGE "/sys/class/power_supply/%s/charge_now" + #define POWER_SUPPLY_ENERGY "/sys/class/power_supply/%s/energy_now" + #define POWER_SUPPLY_CURRENT "/sys/class/power_supply/%s/current_now" + #define POWER_SUPPLY_POWER "/sys/class/power_supply/%s/power_now" + + static const char * + pick(const char *bat, const char *f1, const char *f2, char *path, + size_t length) + { + if (esnprintf(path, length, f1, bat) > 0 && + access(path, R_OK) == 0) + return f1; + + if (esnprintf(path, length, f2, bat) > 0 && + access(path, R_OK) == 0) + return f2; + + return NULL; + } + + const char * + battery_perc(const char *bat) + { + int cap_perc; + char path[PATH_MAX]; + + if (esnprintf(path, sizeof(path), POWER_SUPPLY_CAPACITY, bat) < 0) + return NULL; + if (pscanf(path, "%d", &cap_perc) != 1) + return NULL; + + return bprintf("%d", cap_perc); + } + + const char * + battery_state(const char *bat) + { + static struct { + char *state; + char *symbol; + } map[] = { + { "Charging", "+" }, + { "Discharging", "-" }, + { "Full", "o" }, + { "Not charging", "o" }, + }; + size_t i; + char path[PATH_MAX], state[12]; + + if (esnprintf(path, sizeof(path), POWER_SUPPLY_STATUS, bat) < 0) + return NULL; + if (pscanf(path, "%12[a-zA-Z ]", state) != 1) + return NULL; + + for (i = 0; i < LEN(map); i++) + if (!strcmp(map[i].state, state)) + break; + + return (i == LEN(map)) ? "?" : map[i].symbol; + } + + const char * + battery_remaining(const char *bat) + { + uintmax_t charge_now, current_now, m, h; + double timeleft; + char path[PATH_MAX], state[12]; + + if (esnprintf(path, sizeof(path), POWER_SUPPLY_STATUS, bat) < 0) + return NULL; + if (pscanf(path, "%12[a-zA-Z ]", state) != 1) + return NULL; + + if (!pick(bat, POWER_SUPPLY_CHARGE, POWER_SUPPLY_ENERGY, path, + sizeof(path)) || + pscanf(path, "%ju", &charge_now) < 0) + return NULL; + + if (!strcmp(state, "Discharging")) { + if (!pick(bat, POWER_SUPPLY_CURRENT, POWER_SUPPLY_POWER, path, + sizeof(path)) || + pscanf(path, "%ju", ¤t_now) < 0) + return NULL; + + if (current_now == 0) + return NULL; + + timeleft = (double)charge_now / (double)current_now; + h = timeleft; + m = (timeleft - (double)h) * 60; + + return bprintf("%juh %jum", h, m); + } + + return ""; + } +#elif defined(__OpenBSD__) + #include + #include + #include + #include + + static int + load_apm_power_info(struct apm_power_info *apm_info) + { + int fd; + + fd = open("/dev/apm", O_RDONLY); + if (fd < 0) { + warn("open '/dev/apm':"); + return 0; + } + + memset(apm_info, 0, sizeof(struct apm_power_info)); + if (ioctl(fd, APM_IOC_GETPOWER, apm_info) < 0) { + warn("ioctl 'APM_IOC_GETPOWER':"); + close(fd); + return 0; + } + return close(fd), 1; + } + + const char * + battery_perc(const char *unused) + { + struct apm_power_info apm_info; + + if (load_apm_power_info(&apm_info)) + return bprintf("%d", apm_info.battery_life); + + return NULL; + } + + const char * + battery_state(const char *unused) + { + struct { + unsigned int state; + char *symbol; + } map[] = { + { APM_AC_ON, "+" }, + { APM_AC_OFF, "-" }, + }; + struct apm_power_info apm_info; + size_t i; + + if (load_apm_power_info(&apm_info)) { + for (i = 0; i < LEN(map); i++) + if (map[i].state == apm_info.ac_state) + break; + + return (i == LEN(map)) ? "?" : map[i].symbol; + } + + return NULL; + } + + const char * + battery_remaining(const char *unused) + { + struct apm_power_info apm_info; + unsigned int h, m; + + if (load_apm_power_info(&apm_info)) { + if (apm_info.ac_state != APM_AC_ON) { + h = apm_info.minutes_left / 60; + m = apm_info.minutes_left % 60; + return bprintf("%uh %02um", h, m); + } else { + return ""; + } + } + + return NULL; + } +#elif defined(__FreeBSD__) + #include + + #define BATTERY_LIFE "hw.acpi.battery.life" + #define BATTERY_STATE "hw.acpi.battery.state" + #define BATTERY_TIME "hw.acpi.battery.time" + + const char * + battery_perc(const char *unused) + { + int cap_perc; + size_t len; + + len = sizeof(cap_perc); + if (sysctlbyname(BATTERY_LIFE, &cap_perc, &len, NULL, 0) < 0 || !len) + return NULL; + + return bprintf("%d", cap_perc); + } + + const char * + battery_state(const char *unused) + { + int state; + size_t len; + + len = sizeof(state); + if (sysctlbyname(BATTERY_STATE, &state, &len, NULL, 0) < 0 || !len) + return NULL; + + switch (state) { + case 0: /* FALLTHROUGH */ + case 2: + return "+"; + case 1: + return "-"; + default: + return "?"; + } + } + + const char * + battery_remaining(const char *unused) + { + int rem; + size_t len; + + len = sizeof(rem); + if (sysctlbyname(BATTERY_TIME, &rem, &len, NULL, 0) < 0 || !len + || rem < 0) + return NULL; + + return bprintf("%uh %02um", rem / 60, rem % 60); + } +#endif diff --git a/dwm/slstatus/components/battery.o b/dwm/slstatus/components/battery.o new file mode 100644 index 0000000000000000000000000000000000000000..f98fb2b341b0ba2314dd1c4aaea89bdb386bce6e GIT binary patch literal 5136 zcmb_gZEPGz8J;`awN1m`r6j?SL_Hz9y*BaLYn(QGHFvdBZ`vbmi6hc{a9y9*vB`aD zcTcq|Xc{@LSh*(!fdWE8r9b+kQh(%6et;lcomPY*kX=;}D56m#p`-@2H4>tk4pPM{?R-4*ydN|3?(Ezh-<^FR8i_C|5q2MI^d!pIVyw|l^Jbc@XK|LqXL#=#-apO}fn^@K0{&e6_-4JH^{!^Uw>eG}Ik0j0&U3BA zX+YICmN!W#>s=N^H>$sR(C{uEI+8h@IdYzyePGl!!aBFO&p7e7F7h~T%(wO=xxJI! z9R%ogqgLqdXqcaA)$7aKjM`S{Vsx~-m52Nn?rHTx^{sgq&|7+)BgXvqxutPq+Ximh zZS(OHufXG>Bj+=S#-ErUQf72N0!oGh0v|39cXyF}Ze^~{13Hkcjd!oZ*bc-+qqJ5* zKt`>XNBia;@9)O^w^`Qvt59|~8LQ`w*;nJn?1!z@%SNpY#N|%o<;$&m=7+a-AbNjc zZipV?iRElI1H-$9N$dS{7icJgV`R4IsLp)$coJI7Q|HNUXRUfAiqsbAM{PfPUcouR}s`` zcbtqi!j64sH;owc!`*QTA$Ia!-W#QSnR|V@eZ`2~y|BE|@RnxZju=ZK%=8{i9AP)(TP4drI+H7vpST$-KWW-WEzausW|a+3IUJcP9le>BKZ*Zk zx@y~2$(6Pz6Xc-ChTst9x3OOKK($a{Wwy8MCIYuu-2by&8uAV9O|y}qp)V$qBYXGX zmCy%MdP+|W^bZX7?-&^16daQYdXNM}Vo?^U1CwWVMD#legKY3C7J2e(EHWLBY+l#i zaf--;gl`dJ-$H%A7OzD|w614cMzq8;ts`1;w(YB0e{`>w9M%#Ut&0fvYaL0VjtadR z>WmhDCi;lhHA{MD5>Z?0A|#`A(9lkLo~8$~fP(vY6h1QWk%5m9Z7~sjPD>IJI3enn z>G?TyNIt^kLb}7g?xjS_?;|%TbFJnDOtrH2SDTHt1gqE>y_K4@#sR?BO7vRzE(Alo zv4zSAyCneAL5r~#1()#Wc!R&v65{op0`I;KWo)~^?+W3%z#j_X_Xym#*BJbgz#nTs zypxfgC3k|E`Ml*gGJ;&ivMC5BZp~{I?4n zl^Xxu3SW(Xr@~)HIx?PJ3jRq2->2Z3f?I3YuPA){)RFe56~4MYClo%;56S$y3692KlvHofvo>g#lABn~V+X~o!5MQ3h^$;%4U6yiYimo|EwQKwJq-@z%!A!Z%rIA1On>1N7OrLt?K=$_Zhk5SP-TB@dS#9KDq%6)^@ zWNyMXiCFD(-9#wvbmz-o;=;NJ)ADLG& zU+xfi$PH_U(Iz6&AsE5^2sS^iKJHPl>EE`gAw>G$9&#wVvffR6w8Q?>ZN8zjUj=0% zX!(saRn68fjs+vB^O7-iu}9(cL!QGw&KOmm7XIb?D#xV0tdT*`m+zhAof7)E->M?# zE$b2u%C^dTN$9H>+F|ZfgyDOvzPsR^5&Ge{WZd9DPSXRMVf{-&|6d>}64w7NjWt{U zMX~;m3te>a9g_Mof1CM+%0=-)T@iud8-sgISRdccaPAPq>KGvTgI@(@c>VCrX{O&V O{=fT4py@Zl`u_zkEYMc~ literal 0 HcmV?d00001 diff --git a/dwm/slstatus/components/cat.c b/dwm/slstatus/components/cat.c new file mode 100644 index 0000000..07944cc --- /dev/null +++ b/dwm/slstatus/components/cat.c @@ -0,0 +1,32 @@ +/* See LICENSE file for copyright and license details. */ +#include +#include + +#include "../slstatus.h" +#include "../util.h" + +const char * +cat(const char *path) +{ + char *f; + FILE *fp; + + if (!(fp = fopen(path, "r"))) { + warn("fopen '%s':", path); + return NULL; + } + + f = fgets(buf, sizeof(buf) - 1, fp); + if (fclose(fp) < 0) { + warn("fclose '%s':", path); + return NULL; + } + if (!f) + return NULL; + + if ((f = strrchr(buf, '\n'))) + f[0] = '\0'; + + return buf[0] ? buf : NULL; +} + diff --git a/dwm/slstatus/components/cat.o b/dwm/slstatus/components/cat.o new file mode 100644 index 0000000000000000000000000000000000000000..3ca0447deb5d8d032115d9a09777937af272f8e4 GIT binary patch literal 2088 zcmbuAOHUI~6vt0n5LBELqK1fzS*TPZleU5}7)c8XC8@>-EEI_u>J$=bi!(z6jlslV z(!?fi{0@E!()fyBz=a!EE=*jYD;JpH`On-_hOyn~Np9~szw@|r9|zVi=O?0(2#G{! zly)tlM6cU+^^B)xNTWlPoypaPVP~gjZsw}n*T2EYRlnqF7d>sG?w-xp27UTISADa& z6C=u3w^ZQPRP~*wZq(O~?B=EF9!%B04_w*!>i*h1z!e%-{I4{t+q`mMV^=44NDtAJG$&S7%P^sUag}r1W$$J(L_yr%{2h zO`QkoaS%l*QV(pM&&Idqj1F@gB=YD6MONdHzOIhWm+Ty3cHHw2y}~@E#cRoV$n%r227wDbJo|G=dqkAY( zx8hoeA7#5IP~Y1NvtvBsp;(wYk7oQt3qH_-r&{oHEjSfS*C>#YA5Y>Zg`YH_{}gC` zrAWmE%XQRqpogYiCdaky!lKPJ<)m;f{66XTjxRl|L+}Q0ro!cJ5f7j61nUrRT&C~~ zfGmjJ&qMeGAPYF2xbSH}7SzGF37-XILHt1;!XE&#fa8vZuLH8k_iU?uRejvx60Zk1 zavEYdYbDp5Cxg$-pBF{5ttHcNtyPzdd!}oWG4D8J*cBKE=O!bgP$`wHGKZ8au4Qm* z4LYt_xUcMm@`|x+bJN=H8mFS5wRpE^ncn|DkN@2XRZD%v0i#1r%fLc{qP zm4D3-Yy5`um)O(n{^Niwa?iMb^ta>-Z?-n_@V^3bUd`xTywPwzYKHHg5q(q}8if%M VRjxt0S! +#include +#include + +#include "../slstatus.h" +#include "../util.h" + +#if defined(__linux__) + #define CPU_FREQ "/sys/devices/system/cpu/cpu0/cpufreq/scaling_cur_freq" + + const char * + cpu_freq(const char *unused) + { + uintmax_t freq; + + /* in kHz */ + if (pscanf(CPU_FREQ, "%ju", &freq) != 1) + return NULL; + + return fmt_human(freq * 1000, 1000); + } + + const char * + cpu_perc(const char *unused) + { + static long double a[7]; + long double b[7], sum; + + memcpy(b, a, sizeof(b)); + /* cpu user nice system idle iowait irq softirq */ + if (pscanf("/proc/stat", "%*s %Lf %Lf %Lf %Lf %Lf %Lf %Lf", + &a[0], &a[1], &a[2], &a[3], &a[4], &a[5], &a[6]) + != 7) + return NULL; + + if (b[0] == 0) + return NULL; + + sum = (b[0] + b[1] + b[2] + b[3] + b[4] + b[5] + b[6]) - + (a[0] + a[1] + a[2] + a[3] + a[4] + a[5] + a[6]); + + if (sum == 0) + return NULL; + + return bprintf("%d", (int)(100 * + ((b[0] + b[1] + b[2] + b[5] + b[6]) - + (a[0] + a[1] + a[2] + a[5] + a[6])) / sum)); + } +#elif defined(__OpenBSD__) + #include + #include + #include + + const char * + cpu_freq(const char *unused) + { + int freq, mib[2]; + size_t size; + + mib[0] = CTL_HW; + mib[1] = HW_CPUSPEED; + + size = sizeof(freq); + + /* in MHz */ + if (sysctl(mib, 2, &freq, &size, NULL, 0) < 0) { + warn("sysctl 'HW_CPUSPEED':"); + return NULL; + } + + return fmt_human(freq * 1E6, 1000); + } + + const char * + cpu_perc(const char *unused) + { + int mib[2]; + static uintmax_t a[CPUSTATES]; + uintmax_t b[CPUSTATES], sum; + size_t size; + + mib[0] = CTL_KERN; + mib[1] = KERN_CPTIME; + + size = sizeof(a); + + memcpy(b, a, sizeof(b)); + if (sysctl(mib, 2, &a, &size, NULL, 0) < 0) { + warn("sysctl 'KERN_CPTIME':"); + return NULL; + } + if (b[0] == 0) + return NULL; + + sum = (a[CP_USER] + a[CP_NICE] + a[CP_SYS] + a[CP_INTR] + a[CP_IDLE]) - + (b[CP_USER] + b[CP_NICE] + b[CP_SYS] + b[CP_INTR] + b[CP_IDLE]); + + if (sum == 0) + return NULL; + + return bprintf("%d", 100 * + ((a[CP_USER] + a[CP_NICE] + a[CP_SYS] + + a[CP_INTR]) - + (b[CP_USER] + b[CP_NICE] + b[CP_SYS] + + b[CP_INTR])) / sum); + } +#elif defined(__FreeBSD__) + #include + #include + #include + + const char * + cpu_freq(const char *unused) + { + int freq; + size_t size; + + size = sizeof(freq); + /* in MHz */ + if (sysctlbyname("hw.clockrate", &freq, &size, NULL, 0) < 0 || !size) { + warn("sysctlbyname 'hw.clockrate':"); + return NULL; + } + + return fmt_human(freq * 1E6, 1000); + } + + const char * + cpu_perc(const char *unused) + { + size_t size; + static long a[CPUSTATES]; + long b[CPUSTATES], sum; + + size = sizeof(a); + memcpy(b, a, sizeof(b)); + if (sysctlbyname("kern.cp_time", &a, &size, NULL, 0) < 0 || !size) { + warn("sysctlbyname 'kern.cp_time':"); + return NULL; + } + if (b[0] == 0) + return NULL; + + sum = (a[CP_USER] + a[CP_NICE] + a[CP_SYS] + a[CP_INTR] + a[CP_IDLE]) - + (b[CP_USER] + b[CP_NICE] + b[CP_SYS] + b[CP_INTR] + b[CP_IDLE]); + + if (sum == 0) + return NULL; + + return bprintf("%d", 100 * + ((a[CP_USER] + a[CP_NICE] + a[CP_SYS] + + a[CP_INTR]) - + (b[CP_USER] + b[CP_NICE] + b[CP_SYS] + + b[CP_INTR])) / sum); + } +#endif diff --git a/dwm/slstatus/components/cpu.o b/dwm/slstatus/components/cpu.o new file mode 100644 index 0000000000000000000000000000000000000000..626fa681bb11f82ef25c44f9a896d86cc8d33c5d GIT binary patch literal 3136 zcma)7O>A355Z>n`#I(UNQ4kR=!V=FYh35IE2`W{oERv9S2q;3OjcCDk9J@|yJFfi< zO%9qHh|e9@cBiYroJQymc2c+tbvRDl3&`a`o2!u0C3?U3OWg*QWKE+Nvyg zYJNbUq42A}wxy`#)1k%M>e{{968$zSFQ8JjCu+W!pMN;D*Czt`!ek;)wBnZVkJI{h-xEXq{l|RWLmz&8$QSB0LPp3J4u*S! zec`ZZCJ!HdXcKY}E}<;~<6hRJPF-hHr{vn@kA!x~s~u=-buW-J@PpD810V4CTxUG) z!zA`XCz{2iL!O(O>#XNnZP0UzzT4Uv&w}RqbDzgOxIgZ3+m5>o2yGTmws$d!rbf0q ztxfjsc4DohY7RUv&HHU`UzQyKUWub7PI}2!TEsCYNb)NZ|3txGlXz0Wbz6TGKTmt%Jil|``yBYs z632eg-|X)r8HD}fV>&7Y#$#+Sic?uDJ|>K!RjBhcONC@6Zdl1nmN3TSR$Lfk#iB3@ zlThGJ4{t+F6s=xiBqp=jWRCoElUCB8_qWHsB2qt>D;e~d(-pC%C=jzJ({#DwS@jj+ z!UVKVx9R1WW-!S zrxVFP$aua-Z02>DpCSXx>;r!H8S9rKU%Y3kJIAYe@%dp55Z*bguf}glAVxMPsqs@} z+^v7^%0B>JAN_-S%<s`y M{x>k0gVgx{0hb8MxBvhE literal 0 HcmV?d00001 diff --git a/dwm/slstatus/components/datetime.c b/dwm/slstatus/components/datetime.c new file mode 100644 index 0000000..5b10daf --- /dev/null +++ b/dwm/slstatus/components/datetime.c @@ -0,0 +1,20 @@ +/* See LICENSE file for copyright and license details. */ +#include +#include + +#include "../slstatus.h" +#include "../util.h" + +const char * +datetime(const char *fmt) +{ + time_t t; + + t = time(NULL); + if (!strftime(buf, sizeof(buf), fmt, localtime(&t))) { + warn("strftime: Result string exceeds buffer size"); + return NULL; + } + + return buf; +} diff --git a/dwm/slstatus/components/datetime.o b/dwm/slstatus/components/datetime.o new file mode 100644 index 0000000000000000000000000000000000000000..be8618c9299773ee0e6ce9bd06ff1bea3c89502f GIT binary patch literal 1920 zcmb_cOKTHR6uy(THfjx{R8U)C7O7O!OA@Mf;x<5;v|y7j9fD)bma5NvAQ{h##EXbH4Mqx#!$F&u%TAmlWv4d}RFq{naH>h9-Z|&f- zy>qtX{i37Z*}*6K#mANAnCFcAOtAdZuHA`&0|2jWhWm&yT?Ie?!Yz^4cBR|fE+ z;P?vjlX)SR7E)bXRO)%B0*{~(3Ldj~;I0Y+y77Cj zgDH>%@P|m4zY3BNBN-)O{su?_;xQ!VS3nXFKSaX(Do6t250fxo2T1^bgoJsEbO3cA zT}ZE8^_?{#>7<>t#G0!rj`UT_7m~W=2)X8YLb`Pr2&a22WWHXlsv3pV>b{b6buWc2 z()N0-DI0FRp;v-R9UQomWXE;U-v7n@=c12EL1=IOtj?e1K)v?n z(-ZDH|B@aE&l&T_JL7!j`|XXb8hU>|#~5+^w&CY|)a;!-{4IT;MHmt2vRww>+kW}a NHTkp~*-?7){{WLP(Cz>L literal 0 HcmV?d00001 diff --git a/dwm/slstatus/components/disk.c b/dwm/slstatus/components/disk.c new file mode 100644 index 0000000..e19a693 --- /dev/null +++ b/dwm/slstatus/components/disk.c @@ -0,0 +1,59 @@ +/* See LICENSE file for copyright and license details. */ +#include +#include + +#include "../slstatus.h" +#include "../util.h" + +const char * +disk_free(const char *path) +{ + struct statvfs fs; + + if (statvfs(path, &fs) < 0) { + warn("statvfs '%s':", path); + return NULL; + } + + return fmt_human(fs.f_frsize * fs.f_bavail, 1024); +} + +const char * +disk_perc(const char *path) +{ + struct statvfs fs; + + if (statvfs(path, &fs) < 0) { + warn("statvfs '%s':", path); + return NULL; + } + + return bprintf("%d", (int)(100 * + (1 - ((double)fs.f_bavail / (double)fs.f_blocks)))); +} + +const char * +disk_total(const char *path) +{ + struct statvfs fs; + + if (statvfs(path, &fs) < 0) { + warn("statvfs '%s':", path); + return NULL; + } + + return fmt_human(fs.f_frsize * fs.f_blocks, 1024); +} + +const char * +disk_used(const char *path) +{ + struct statvfs fs; + + if (statvfs(path, &fs) < 0) { + warn("statvfs '%s':", path); + return NULL; + } + + return fmt_human(fs.f_frsize * (fs.f_blocks - fs.f_bfree), 1024); +} diff --git a/dwm/slstatus/components/disk.o b/dwm/slstatus/components/disk.o new file mode 100644 index 0000000000000000000000000000000000000000..15a48fd8b8aa34d0cc22da411eb2f77b246fea4f GIT binary patch literal 3120 zcmcIl&2Jk;6rXjQCTWY;RH=w)4|{N^OUo*Dii9cwt`g{|Dn$Z{T2bL_>~$Tb{*ZT5 z926i@6e&?!DMI3c_yf3c<%CSiAynePKY%z^EeGlY7eM9xX6JdQTL(}CPkQrae(!7M z?VH(8Uc2~u%CZELC0-Hnicuk2Bk{bbrbS_kw0K*tez#JQo5v?|gvyO;*^b=!UEU6} zBllpo)?GT9@5+szf`i`S{@KlyjX{t9WnB%GZXe4aV9qF&)i+`sas~{YN~9<+l*+Y*Qq`Nk5qY%yc3I4|+VhRD8X;jb^t5s@@KxJz52A-r z>pvbvbQ*giN)hiPW;_p&2==4Ij9&mq1pFW|<0XJZzz-2Kz6OvenfJ2@ej@MZ8c*i^ z&9H}#-Ld>n|1rt zz|Fj08@QQwN8`!w^@Cw==6zt`W?ofzIzQ@Q=5=TdLVPgOjGi#geO^o8d=G9VaJ~n^ z4VLPmH%BsTN3zDVwtvHOL%$OWx8jAKaOZ+Rxa}quFsDblzbpsgOTsNT>vg|D_Kjxf zyYx=Kpe~4BUvDhBt#*^{N4P|ei0;?uf_ZhHkF{s%kS9u;eCdjWfexC*qqY7FN{8VX zF=}5VHfa`3OqA39hiML9^Z;l)66zfUj@~orLLx8glKFA(5p%Epcpnfm`diXO6X$=L z0WCQ{%Oc^JNB;$FL}FI&KlwKE`B}c9{U>8rHEU^qe(zY#d0D=z{aMfQ*1xP@l^lkN zljd6*NbZaG&3Qhi3HFlo?`q&nHqXJ_0R1u0U+;gN4Yf@A{{ + #include + + #include "../util.h" + + #define ENTROPY_AVAIL "/proc/sys/kernel/random/entropy_avail" + + const char * + entropy(const char *unused) + { + uintmax_t num; + + if (pscanf(ENTROPY_AVAIL, "%ju", &num) != 1) + return NULL; + + return bprintf("%ju", num); + } +#elif defined(__OpenBSD__) | defined(__FreeBSD__) + const char * + entropy(const char *unused) + { + // https://www.unicode.org/charts/PDF/U2200.pdf + /* Unicode Character 'INFINITY' (U+221E) */ + return "\u221E"; + } +#endif diff --git a/dwm/slstatus/components/entropy.o b/dwm/slstatus/components/entropy.o new file mode 100644 index 0000000000000000000000000000000000000000..fbc73ae760db44d1e38551d56f445cfcdd021f91 GIT binary patch literal 1784 zcmbtUPiqrV5T8vG8!?6`6$(|@Ln`s#OEyFhp(Q2Ou24j*J%~uyBpXwcY~t=l5(21(+0AheL}| zfd0avUi8!=B;hRV==+z*)c4msG5V?xf2C^rIJ%l4cyuQn*CzVt#{s!V@3qPFb1$Kf z3u%4y&BOHZqjbEcUt97L+?WpzKc=31Sbg4uY}f8ov(CWDHci_yTUpz%YMpl0v|PK> z9h8li#$F3xt5mwJX14C{UQxAz(1fPubNNE^k=>*k*-WN3l5v9O5!H>t@98|>!kimF;|0=b zk5bArW8V7&Jr~e8AE@J<4KW&ypA(D*NFRe=KL!VR-=Yd)yOg7c#u#*+s$tck(zW+2 zw+`j9;~Ldwx!P!!>)v$y`==8`kZG0vPJQy<)5mEZj9*2ah_F-0jIR@jMED{y<2wW* z5l%y3Tt%IT`V!AbID@upR6sbc?aKyhw%Ia-YxZ3bHN!PPR2&C{-64a*al1fNJMA{! z2?(p>ngUnqhWFCaerELqE^gPf-2tXjL9gNN`vRmKHh7# zS5Tq5Dl#BtLtau}+B6@^<;7l>_+^O)ehZ%Go%DxAxIgU~)%@Rl4Rfic{Jc@~iTm^Z zFwXs17STa^jsv9pBqe|2?B+a{_t3#Q$B_IPGy-}!_A&Zse~;`W+6OWxd@jC!>4q1m zP|a}uvTSsV1Emb-<1cgW{J+bBJZGB!X=Ki4d|q#A^+5LjLIzR-nf_woe5x6qJwlL? a{ny9{kSsex&Y?Ch|BuXnJ&W{}aQ;7HN3%8n literal 0 HcmV?d00001 diff --git a/dwm/slstatus/components/hostname.c b/dwm/slstatus/components/hostname.c new file mode 100644 index 0000000..dab8b63 --- /dev/null +++ b/dwm/slstatus/components/hostname.c @@ -0,0 +1,17 @@ +/* See LICENSE file for copyright and license details. */ +#include +#include + +#include "../slstatus.h" +#include "../util.h" + +const char * +hostname(const char *unused) +{ + if (gethostname(buf, sizeof(buf)) < 0) { + warn("gethostbyname:"); + return NULL; + } + + return buf; +} diff --git a/dwm/slstatus/components/hostname.o b/dwm/slstatus/components/hostname.o new file mode 100644 index 0000000000000000000000000000000000000000..d3f15e78864239ee6dd8e62500f4f7c52dead5ba GIT binary patch literal 1640 zcmb_cL2DCH5S~q|jaXwW3PKfD1gW5pY^WdwWhH1M6cNRPc+gGUHej=x?!IE9haSX3 z4h8RC{3R0f;!!+#^V*}{g*xBvoAzbddJsRDyqWKPGw)^IB-^)F?o=Fy1P&vajn@z8lft=Y)9BwMHO6x1GdU4(BX=b_eE8 zvDGJ~S#;(Q{=y+Vp{wYr>XKS%HK?<>N~YPM>1B{aoGZP&sgzJIQ;g%-#JkSBDPMVTRVg!)$ zRFLY%{eBp+B#L#YcoeRtI_SPI@mjR021z^!6FuZq6byS$R}*~m{{ok*U>49D8@>tT zJ!KDC8}l5XSH4ZM|I-Mc8U8r0pkyvFH^3z}@OT3o13R$%;`vv24>kWa-{V}=G(SuB za>)57g)pm}FRRZy{9>QBjb476Cd{<(CI7DFiw5g^JFtAo6Y4QLnA3@wDFMQeAII3#C=okS5|35gVn2(yp ew`YpJn0(Ba4MXo!_ +#include +#include +#include +#if defined(__OpenBSD__) + #include + #include +#elif defined(__FreeBSD__) + #include + #include +#endif + +#include "../slstatus.h" +#include "../util.h" + +static const char * +ip(const char *interface, unsigned short sa_family) +{ + struct ifaddrs *ifaddr, *ifa; + int s; + char host[NI_MAXHOST]; + + if (getifaddrs(&ifaddr) < 0) { + warn("getifaddrs:"); + return NULL; + } + + for (ifa = ifaddr; ifa != NULL; ifa = ifa->ifa_next) { + if (!ifa->ifa_addr) + continue; + + s = getnameinfo(ifa->ifa_addr, sizeof(struct sockaddr_in6), + host, NI_MAXHOST, NULL, 0, NI_NUMERICHOST); + if (!strcmp(ifa->ifa_name, interface) && + (ifa->ifa_addr->sa_family == sa_family)) { + freeifaddrs(ifaddr); + if (s != 0) { + warn("getnameinfo: %s", gai_strerror(s)); + return NULL; + } + return bprintf("%s", host); + } + } + + freeifaddrs(ifaddr); + + return NULL; +} + +const char * +ipv4(const char *interface) +{ + return ip(interface, AF_INET); +} + +const char * +ipv6(const char *interface) +{ + return ip(interface, AF_INET6); +} diff --git a/dwm/slstatus/components/ip.o b/dwm/slstatus/components/ip.o new file mode 100644 index 0000000000000000000000000000000000000000..5b9db6713f358d539f608bb4c35863c95aa6f330 GIT binary patch literal 2544 zcmbuAU1(cn7{{NJwp*s%p|b-6o$P>}WH=8=sG{|QoOZQm7-i@xOk1-Rp- z`}v$VXJ>M+#uSC56ncfaElG)-9o>31sAfr}-DJFN%o+Y&Mv>5V^r6TW71emvf2t&f_UFQc7q1$f&rn`36DJahwiknJ#B=^{{trRxo#TzxYRha+CrXE3NUnZsHhIRN zr*Yfc=ilkLbfz=?AH|I6*7p9K|94~=!(Hd?U(Mzh!4`_<(|dzGc|)DC&Rxb<-(4`~ zjRoVqOItBs*sa_5+wHAKP`kmkCEF{PtYXovPZHOwR>dw?OSMVuK%MwUv(wX)T5|S{ zxr17ILQm^yEtASjq@K-Wh=(SP(-0>%pcpAFFeyc}{v40Jrv4ItUA-Qk=h6UJQ&WbT zG*pdU*mX*c6OHgN4hCdluMp-xAJn=`G;MaL~y zy%OaaS%s7N!t%*{$tth#G;0&cp5srQ*8?GzcXGPd?#KXS;VVL)qWBPVjQL;v@%>=T45zT<{QJX@>vDcsW(7+{?9K>-=({NWWO*bsW_XAT z(jW|b*dAww?>-#EaFPDeb;1vJ{|~YLjgT*@QU8Ad7x`Pt literal 0 HcmV?d00001 diff --git a/dwm/slstatus/components/kernel_release.c b/dwm/slstatus/components/kernel_release.c new file mode 100644 index 0000000..36a6a44 --- /dev/null +++ b/dwm/slstatus/components/kernel_release.c @@ -0,0 +1,19 @@ +/* See LICENSE file for copyright and license details. */ +#include +#include + +#include "../slstatus.h" +#include "../util.h" + +const char * +kernel_release(const char *unused) +{ + struct utsname udata; + + if (uname(&udata) < 0) { + warn("uname:"); + return NULL; + } + + return bprintf("%s", udata.release); +} diff --git a/dwm/slstatus/components/kernel_release.o b/dwm/slstatus/components/kernel_release.o new file mode 100644 index 0000000000000000000000000000000000000000..eef4c7c965f27a4932d3df4c2d0370e7d40dce3b GIT binary patch literal 1832 zcmbtU&ubG=5S~q18?}}iiV79Up_NMYkquR(XbA-EDn&u?;3;gpKmyS)!Du>JIB29>eI|iCY<(@nZ$P_zUXYG?T*vF3P&?` z=f?@B{bA-g6Na}tI^t}<*43-d{FH7NjduC1FPQRq-FF+_BF%e3w*C$47|GMhMp>uS}A1lW5+_IFN+?!flsAYu;xb>lmsBYXNd-+fNay7wRcpBB@wkf5KhFv1dC+?7KYDh*4s006{3AjbE%Qa^ znTIX=XVU1SG2|N|ywr)l!2z))2l{Kj(`UzX?{N(KKCqMQe={}l=aTa`VS2y@ddBNh zX3%9xG&)|-uj +#include +#include +#include + +#include "../slstatus.h" +#include "../util.h" + +/* + * fmt consists of uppercase or lowercase 'c' for caps lock and/or 'n' for num + * lock, each optionally followed by '?', in the order of indicators desired. + * If followed by '?', the letter with case preserved is included in the output + * if the corresponding indicator is on. Otherwise, the letter is always + * included, lowercase when off and uppercase when on. + */ +const char * +keyboard_indicators(const char *fmt) +{ + Display *dpy; + XKeyboardState state; + size_t fmtlen, i, n; + int togglecase, isset; + char key; + + if (!(dpy = XOpenDisplay(NULL))) { + warn("XOpenDisplay: Failed to open display"); + return NULL; + } + XGetKeyboardControl(dpy, &state); + XCloseDisplay(dpy); + + fmtlen = strnlen(fmt, 4); + for (i = n = 0; i < fmtlen; i++) { + key = tolower(fmt[i]); + if (key != 'c' && key != 'n') + continue; + + togglecase = (i + 1 >= fmtlen || fmt[i + 1] != '?'); + isset = (state.led_mask & (1 << (key == 'n'))); + + if (togglecase) + buf[n++] = isset ? toupper(key) : key; + else if (isset) + buf[n++] = fmt[i]; + } + + buf[n] = 0; + return buf; +} diff --git a/dwm/slstatus/components/keyboard_indicators.o b/dwm/slstatus/components/keyboard_indicators.o new file mode 100644 index 0000000000000000000000000000000000000000..88dcdf03d04578f71e9f2cf115f0445d0db087aa GIT binary patch literal 2408 zcmbu9Pi)&%9LJyAWGyUn%Rr)HLoz5sK?5tPGO3#i#7VZgTE?caj__xT+{DFIQ#;r% z>H-HUbwx8Fzy+yCuDk8HQ;9T2uN-y&Aptjr20}Zc4Tay&dCz-T&INvw{eJKB`~H6K z+3(LsCo8AMB#Cg7$gAX0k5fYKCLj5Qz%3A&93a}8+C^lLKB&{=<^#L^!`JvVXO92r z?avKLoAdLp6{f!2yNM9P$(v)~buXk-&waN&pwDdg>2y$2pW6Kq>J>i8?`YTZ>b*&b z^t5X!RUh2GcUA8_3u)xr#8INde5wuoXd?J-njB_tePikV_wQWN-qkK?m$llh>e-fQ zmsh=3)99Q~P8q9Bv!PH&aR4igAtz*^R63z#7G7U^QOV`ioSIW+v$Of^vDsN14h?^X z0uL?+=*Sq6`pCFRtk2i*DHf1EI8UT2)6${T#N-zctN=gEVi^<{<>}AIit@~7<3(BN zC5m$9)1)S6Ki;Rwb6XQ-`73EWCCPJTIjhMTkbo3Yit;2YGNQrK337iB7aotJ{`-aI$80mL0=w)K=}r zYTclY>#233R!Z5p5E1tm*)Uw2R2NKoniVNIHg%mQS#Gb8YN_dXCfka{qpsaFZBnb% zX{Tk@sMB;dOt;o_>H=%GS|RhOQD3Xot+m<;>|&UHV9&D__ad&|!@sI7x*0G zsNW~>vjU$G_*;x)9o%xf{$<9o&SL^!6Zqo--xTjs11V}L|yhgqPh-tP!9J1QR~k7x@m*NcBrYs z(SJEu2-bhkZmTU9E)$n_AQcOmR&B*K*3EDR|I1Mz8$TJ>O0)v&@bk!H?Dz04IRqa5 zt3pVIj*bv)k|p4ppv$k784QBG01tB9L!w#Hfmkq#UjmLb|7$+(W2_lo#Neax@sA9< z;hT@o+X6(;$NNgO9ux4pn8$b?ZxrJfHKpv2ie+P3Rn(2cBIVCz_8nqiYX{ c>@av8JA$!tA$bD4xO|Jv|HDu@bfWqH0Il3%wg3PC literal 0 HcmV?d00001 diff --git a/dwm/slstatus/components/keymap.c b/dwm/slstatus/components/keymap.c new file mode 100644 index 0000000..f8a2a47 --- /dev/null +++ b/dwm/slstatus/components/keymap.c @@ -0,0 +1,86 @@ +/* See LICENSE file for copyright and license details. */ +#include +#include +#include +#include +#include + +#include "../slstatus.h" +#include "../util.h" + +static int +valid_layout_or_variant(char *sym) +{ + size_t i; + /* invalid symbols from xkb rules config */ + static const char *invalid[] = { "evdev", "inet", "pc", "base" }; + + for (i = 0; i < LEN(invalid); i++) + if (!strncmp(sym, invalid[i], strlen(invalid[i]))) + return 0; + + return 1; +} + +static char * +get_layout(char *syms, int grp_num) +{ + char *tok, *layout; + int grp; + + layout = NULL; + tok = strtok(syms, "+:"); + for (grp = 0; tok && grp <= grp_num; tok = strtok(NULL, "+:")) { + if (!valid_layout_or_variant(tok)) { + continue; + } else if (strlen(tok) == 1 && isdigit(tok[0])) { + /* ignore :2, :3, :4 (additional layout groups) */ + continue; + } + layout = tok; + grp++; + } + + return layout; +} + +const char * +keymap(const char *unused) +{ + Display *dpy; + XkbDescRec *desc; + XkbStateRec state; + char *symbols; + const char *layout; + + layout = NULL; + + if (!(dpy = XOpenDisplay(NULL))) { + warn("XOpenDisplay: Failed to open display"); + return NULL; + } + if (!(desc = XkbAllocKeyboard())) { + warn("XkbAllocKeyboard: Failed to allocate keyboard"); + goto end; + } + if (XkbGetNames(dpy, XkbSymbolsNameMask, desc)) { + warn("XkbGetNames: Failed to retrieve key symbols"); + goto end; + } + if (XkbGetState(dpy, XkbUseCoreKbd, &state)) { + warn("XkbGetState: Failed to retrieve keyboard state"); + goto end; + } + if (!(symbols = XGetAtomName(dpy, desc->names->symbols))) { + warn("XGetAtomName: Failed to get atom name"); + goto end; + } + layout = bprintf("%s", get_layout(symbols, state.group)); + XFree(symbols); +end: + XkbFreeKeyboard(desc, XkbSymbolsNameMask, 1); + if (XCloseDisplay(dpy)) + warn("XCloseDisplay: Failed to close display"); + + return layout; +} diff --git a/dwm/slstatus/components/keymap.o b/dwm/slstatus/components/keymap.o new file mode 100644 index 0000000000000000000000000000000000000000..166aa6c8593532e81087e4a8f26dc2c4f14276bc GIT binary patch literal 4024 zcmb`KUuYaf9LMMKr->RbvHy%#>w?!3sa@`3Ytv9Qn_SW<9&NEr4QPAayW2EJ?qByd zF_B^mvBG*rOT`Bt^{Kw7AgBnI+O$v+L5iSQtdF*&Q2J64g!udJ&Lnf|?StYEW@qLz z-`{WMW_EwOcXBv2(iDj>X%Y4;Tj@#4*q8UMv*`$-*KT6P+`Y}`55_j1$AZ;JhI^UjySk^AjKv|URl3w+?zY4*(`TKZCu5sw#j)YU zT|U1Zi%a=yag(tQ-^E?vr>{9P$(@B*$BE;7{(h)^Kb|Z1Y^s&Jzbzphb6o2prZYsoiV@FuG9lu7Qr{iqK;?nlX=qc#lu0VRBiqQFiu($N`0J=h{T)Cush4~e5+xb*>#0b-Uf~ZaJg#t6->>j)MZZt* z;Q9|KdUc%{Mc<*sDJXj6Qn}6l5GHx2;F?GMbHrMgO{b3$$ILJtkF8fv$d+vt zOx>|&9H!??$7Fh@T4lOjMh9|w*;5xHk5G#Sb$k#Nn4T>ci&lwTOJ&E>>D9m0dx}N> zSZPYH*z}oYJF_B&HIW{-@d5L{m_||X(}Qo?0b(%ue)4<1R<=>&>~U`oP*Lq?Bm=S^ z#3tg*F^@bax&NC5$62bjv2OEMM#M2KgD0tlnE%y3LB5FDOGPy~|JuNWvMcLhazZ;e z|9}9R8kE|>{s6H?`*#jWitMO&^`9A>QE>mph++P?(8=nkm|x~C$>q9bZPI{jOAYE1 z!5<_BgWBW7an!-%Iwkyr>yqmi;TZBeVg~&`75)=aDC(g9>%<%FU%U99D(^Gge?Zb- x@ +#include + +#include "../slstatus.h" +#include "../util.h" + +const char * +load_avg(const char *unused) +{ + double avgs[3]; + + if (getloadavg(avgs, 3) < 0) { + warn("getloadavg: Failed to obtain load average"); + return NULL; + } + + return bprintf("%.2f %.2f %.2f", avgs[0], avgs[1], avgs[2]); +} diff --git a/dwm/slstatus/components/load_avg.o b/dwm/slstatus/components/load_avg.o new file mode 100644 index 0000000000000000000000000000000000000000..2e5d9a05691d2233f8d5d3ef7ca40a460fa6d2c3 GIT binary patch literal 1864 zcmbW1-D(q25XWbe)<&!~mLi1;-HTM>N7rnqs6{2v+OAMUq=H_BO|to*$!^`OwN=53 z;zcP!AHgROpFje7;hR*@3-wy4^WU7=q}vpv17~OEH#6s)oH;pf@2@N+G>t?wx<@@v zDABiM&n|>!fyU@8S=&FepAoBAyLV=?Y*;&QGLzQM{&!@(>uimi9qavFI3Y1RKc@ej zORr|q{9VbURP0ld-JwjFV(qSGCM(v}iEzGPxC^(xX1~;&py}Bad!sh5FWHTzQ_%xY z_ez1?aCJm2zN$wbqUD8!c|E)Q@X2M}oHI@z8k; z^WZE>kk$c{v(S`(ni*uGt4MqGn6%BbHZ?ku+T&#Kiz?b>Y_XkwR#<$UN4)0M-RF0en|H&3`HX45>;Q6Un^F*!8FD5L(q#;JpLYZB@4)s;DPHW zd=`)e`6E1pF9Nb4A2H#N09nA$B;gJq3pjc%TxT1Cc`za|+FPx_E|Jj={I0Hx%yU z +#include + +#include "../slstatus.h" +#include "../util.h" + +#if defined(__linux__) + #include + + #define NET_RX_BYTES "/sys/class/net/%s/statistics/rx_bytes" + #define NET_TX_BYTES "/sys/class/net/%s/statistics/tx_bytes" + + const char * + netspeed_rx(const char *interface) + { + uintmax_t oldrxbytes; + static uintmax_t rxbytes; + extern const unsigned int interval; + char path[PATH_MAX]; + + oldrxbytes = rxbytes; + + if (esnprintf(path, sizeof(path), NET_RX_BYTES, interface) < 0) + return NULL; + if (pscanf(path, "%ju", &rxbytes) != 1) + return NULL; + if (oldrxbytes == 0) + return NULL; + + return fmt_human((rxbytes - oldrxbytes) * 1000 / interval, + 1024); + } + + const char * + netspeed_tx(const char *interface) + { + uintmax_t oldtxbytes; + static uintmax_t txbytes; + extern const unsigned int interval; + char path[PATH_MAX]; + + oldtxbytes = txbytes; + + if (esnprintf(path, sizeof(path), NET_TX_BYTES, interface) < 0) + return NULL; + if (pscanf(path, "%ju", &txbytes) != 1) + return NULL; + if (oldtxbytes == 0) + return NULL; + + return fmt_human((txbytes - oldtxbytes) * 1000 / interval, + 1024); + } +#elif defined(__OpenBSD__) | defined(__FreeBSD__) + #include + #include + #include + #include + #include + + const char * + netspeed_rx(const char *interface) + { + struct ifaddrs *ifal, *ifa; + struct if_data *ifd; + uintmax_t oldrxbytes; + static uintmax_t rxbytes; + extern const unsigned int interval; + int if_ok = 0; + + oldrxbytes = rxbytes; + + if (getifaddrs(&ifal) < 0) { + warn("getifaddrs failed"); + return NULL; + } + rxbytes = 0; + for (ifa = ifal; ifa; ifa = ifa->ifa_next) + if (!strcmp(ifa->ifa_name, interface) && + (ifd = (struct if_data *)ifa->ifa_data)) + rxbytes += ifd->ifi_ibytes, if_ok = 1; + + freeifaddrs(ifal); + if (!if_ok) { + warn("reading 'if_data' failed"); + return NULL; + } + if (oldrxbytes == 0) + return NULL; + + return fmt_human((rxbytes - oldrxbytes) * 1000 / interval, + 1024); + } + + const char * + netspeed_tx(const char *interface) + { + struct ifaddrs *ifal, *ifa; + struct if_data *ifd; + uintmax_t oldtxbytes; + static uintmax_t txbytes; + extern const unsigned int interval; + int if_ok = 0; + + oldtxbytes = txbytes; + + if (getifaddrs(&ifal) < 0) { + warn("getifaddrs failed"); + return NULL; + } + txbytes = 0; + for (ifa = ifal; ifa; ifa = ifa->ifa_next) + if (!strcmp(ifa->ifa_name, interface) && + (ifd = (struct if_data *)ifa->ifa_data)) + txbytes += ifd->ifi_obytes, if_ok = 1; + + freeifaddrs(ifal); + if (!if_ok) { + warn("reading 'if_data' failed"); + return NULL; + } + if (oldtxbytes == 0) + return NULL; + + return fmt_human((txbytes - oldtxbytes) * 1000 / interval, + 1024); + } +#endif diff --git a/dwm/slstatus/components/netspeeds.o b/dwm/slstatus/components/netspeeds.o new file mode 100644 index 0000000000000000000000000000000000000000..a85a3b6478a302767bd9c5c1693e14b714e146b1 GIT binary patch literal 2760 zcmdUw&ud&&6vxk-q;1r8h!Sz2DkCJ)T78o@v>+-nCD>dgO0iUwBIC>CjTtjD8Q;B; z8AY^cg)jtMxadEixD?zJ7iB=fu3Wehy3l1oQMyt=i0Av>J(I0+aOa-;Ip^GS zf1G#cy=PX=6@q|70(zRpBcVj<$XKssYK@9?j4rC}Kh@5?AlGS@=z_ZZONo0md;n}s z4W}1Qu%fmsy_;OZ7U}cVna8Sl_5O<5qh-f$8&-NS>nt>xa4hwVTUv z7+JviVc5H=CjnV-b9ZtR{}n(M-~U36Gmc#1f5~#pbC<(6EcfTZ`9Z*sa+7&>09h~( zYEAg3fGpreZop>H7?+bjd9z#9on0S>!ZPL777cEWNacGjhp>QoWF@>vI zQ9yngNGm!eqVPOyf=>EBkMK znZt1usAX4bcF?rvBsOnIsC(Q|O&n~04Upw08-SXHD(_YaMi#tJ;J8ayKJyb{NG0?k;I=LqfC?h($| s`L5ag@7oRIo1PR8=HETyAGh`QE(VVH=XW>TCdJ>d>wm|Ih3d!u4Mt>@A^-pY literal 0 HcmV?d00001 diff --git a/dwm/slstatus/components/num_files.c b/dwm/slstatus/components/num_files.c new file mode 100644 index 0000000..df0acd1 --- /dev/null +++ b/dwm/slstatus/components/num_files.c @@ -0,0 +1,32 @@ +/* See LICENSE file for copyright and license details. */ +#include +#include +#include + +#include "../slstatus.h" +#include "../util.h" + +const char * +num_files(const char *path) +{ + struct dirent *dp; + DIR *dir; + int num; + + if (!(dir = opendir(path))) { + warn("opendir '%s':", path); + return NULL; + } + + num = 0; + while ((dp = readdir(dir))) { + if (!strcmp(dp->d_name, ".") || !strcmp(dp->d_name, "..")) + continue; /* skip self and parent */ + + num++; + } + + closedir(dir); + + return bprintf("%d", num); +} diff --git a/dwm/slstatus/components/num_files.o b/dwm/slstatus/components/num_files.o new file mode 100644 index 0000000000000000000000000000000000000000..567431c0eb0753c55c169069e48949004cc18a54 GIT binary patch literal 2152 zcmbu9TWb?h5P&D?)n1m^dI{8r^`SOWyJXWAw4x+UYPT3lX|1%@P`1g|1aot<#a16g ziiLmyAN&FSlz<5S03Stt5UC1Y-UNj@vwJ4pF3F1yoINw&T+W_zX7|xd@|xf00~Q}# zg+q%ez<&Fo9<|jdNYD?l))r!}p1g@RIQJ$5^m`s^gUQ|p4;#crwf zwG_EumdZvklQZR!;mXJqD4-}XoB^1P$EW1b?ELb1S)EW+MU^Ar$V7ND62W@3JsC#_ z4h#W5`0B1LAI}%dZKi?yTkZ4jcAqA$T?wQ_2DHNCFm=wem1focbiQc0fejYS)w>7!Jemk%O z@9d}y2p%|!;k4j`9`5XoPU)zeMRUNluDy3;qd2^^DRaC9zubaPx8T=X@TC?Uid%*C z&0OB7C}~iVag`nsdW_Q}eCP+!MqnCx2HOcLmYFV;A)PN(46--MX0B*$!hPK=+I@pd zV&4F?;rMgl$Vq}I)Jt@w%!di05I=^4`6YrV#CvcsPY^_*`s8Cy{YK)APdV7;y{L11 zPH?J2x5)gli+8&Cp5RoUdWhqP6_MGPsHEJMLhbgW|O>AS+dQ`}O@Cf=B7?O-YuG_vcP zrd}`_Z}4A=jM?2qDh%#-_ED@`hR~ohjJhG}8Z`?_w@9G7B9%Y?AURRa;UF%; z3EA?770>Kl{{s4{=D+5vm`gS3U+ETJ|CAe|&g=6W6)fzD`yy=qXR@2~c%Bpa?B}_Y z0~m3_ia y%$u!Ec`wBJ3u2~kk@o4$r<&foM+85_hE~XMi73|~$5CsRpB3-_uo3Af-u%Db2n0<4 literal 0 HcmV?d00001 diff --git a/dwm/slstatus/components/ram.c b/dwm/slstatus/components/ram.c new file mode 100644 index 0000000..15c4b74 --- /dev/null +++ b/dwm/slstatus/components/ram.c @@ -0,0 +1,212 @@ +/* See LICENSE file for copyright and license details. */ +#include + +#include "../slstatus.h" +#include "../util.h" + +#if defined(__linux__) + #include + + const char * + ram_free(const char *unused) + { + uintmax_t free; + + if (pscanf("/proc/meminfo", + "MemTotal: %ju kB\n" + "MemFree: %ju kB\n" + "MemAvailable: %ju kB\n", + &free, &free, &free) != 3) + return NULL; + + return fmt_human(free * 1024, 1024); + } + + const char * + ram_perc(const char *unused) + { + uintmax_t total, free, buffers, cached; + int percent; + + 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) + return NULL; + + if (total == 0) + return NULL; + + percent = 100 * ((total - free) - (buffers + cached)) / total; + return bprintf("%d", percent); + } + + const char * + ram_total(const char *unused) + { + uintmax_t total; + + if (pscanf("/proc/meminfo", "MemTotal: %ju kB\n", &total) + != 1) + return NULL; + + return fmt_human(total * 1024, 1024); + } + + const char * + ram_used(const char *unused) + { + uintmax_t total, free, buffers, cached, used; + + 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) + return NULL; + + used = (total - free - buffers - cached); + return fmt_human(used * 1024, 1024); + } +#elif defined(__OpenBSD__) + #include + #include + #include + #include + + #define LOG1024 10 + #define pagetok(size, pageshift) (size_t)(size << (pageshift - LOG1024)) + + inline int + load_uvmexp(struct uvmexp *uvmexp) + { + int uvmexp_mib[] = {CTL_VM, VM_UVMEXP}; + size_t size; + + size = sizeof(*uvmexp); + + if (sysctl(uvmexp_mib, 2, uvmexp, &size, NULL, 0) >= 0) + return 1; + + return 0; + } + + const char * + ram_free(const char *unused) + { + struct uvmexp uvmexp; + int free_pages; + + if (!load_uvmexp(&uvmexp)) + return NULL; + + free_pages = uvmexp.npages - uvmexp.active; + return fmt_human(pagetok(free_pages, uvmexp.pageshift) * + 1024, 1024); + } + + const char * + ram_perc(const char *unused) + { + struct uvmexp uvmexp; + int percent; + + if (!load_uvmexp(&uvmexp)) + return NULL; + + percent = uvmexp.active * 100 / uvmexp.npages; + return bprintf("%d", percent); + } + + const char * + ram_total(const char *unused) + { + struct uvmexp uvmexp; + + if (!load_uvmexp(&uvmexp)) + return NULL; + + return fmt_human(pagetok(uvmexp.npages, + uvmexp.pageshift) * 1024, 1024); + } + + const char * + ram_used(const char *unused) + { + struct uvmexp uvmexp; + + if (!load_uvmexp(&uvmexp)) + return NULL; + + return fmt_human(pagetok(uvmexp.active, + uvmexp.pageshift) * 1024, 1024); + } +#elif defined(__FreeBSD__) + #include + #include + #include + #include + + const char * + ram_free(const char *unused) { + struct vmtotal vm_stats; + int mib[] = {CTL_VM, VM_TOTAL}; + size_t len; + + len = sizeof(struct vmtotal); + if (sysctl(mib, 2, &vm_stats, &len, NULL, 0) < 0 + || !len) + return NULL; + + return fmt_human(vm_stats.t_free * getpagesize(), 1024); + } + + const char * + ram_total(const char *unused) { + unsigned int npages; + size_t len; + + len = sizeof(npages); + if (sysctlbyname("vm.stats.vm.v_page_count", + &npages, &len, NULL, 0) < 0 || !len) + return NULL; + + return fmt_human(npages * getpagesize(), 1024); + } + + const char * + ram_perc(const char *unused) { + unsigned int npages; + unsigned int active; + size_t len; + + len = sizeof(npages); + if (sysctlbyname("vm.stats.vm.v_page_count", + &npages, &len, NULL, 0) < 0 || !len) + return NULL; + + if (sysctlbyname("vm.stats.vm.v_active_count", + &active, &len, NULL, 0) < 0 || !len) + return NULL; + + return bprintf("%d", active * 100 / npages); + } + + const char * + ram_used(const char *unused) { + unsigned int active; + size_t len; + + len = sizeof(active); + if (sysctlbyname("vm.stats.vm.v_active_count", + &active, &len, NULL, 0) < 0 || !len) + return NULL; + + return fmt_human(active * getpagesize(), 1024); + } +#endif diff --git a/dwm/slstatus/components/ram.o b/dwm/slstatus/components/ram.o new file mode 100644 index 0000000000000000000000000000000000000000..848d15b2351c6205b72ddf411a2d99d7a9bdaea5 GIT binary patch literal 3072 zcmcgtO>7%Q6dpTCYeKRLRfHmy!yX*uD0G`OiHIVK+$K$?s*55Neku^o#@@vtUfbAf z)IudHMI4M3sb?x7xN+pj3AqLFdxBeUEf+v==>ez^Qh48bUNW7y0_DJy=I4FyZ|1!> zyYHOMFDDZT!ITish<%PxA+DzO_qlkR6P6eia{IRlxibeu?wrC>lAXcH4EXj^I^}j{ z`^R(b+p>MmE`nzY#j~t!0j(4KBpk_ zMv%M;lBXb<{LWIEPC@2!C!Zc$mBeRO-R_0S9@WHT640KC#`qCiKb=yYdH-& zn#SB8u-NJfa;saCf8K3>>2~){mg#e{d7SLuuOItp-`xGSHGc5cza}X~|HI8EW#|EvLSc(^u%;dJX#D^nxF*)grI5U{Ai@vbW9*6R_OyeVsr3rngz~HY)p| zI9YGhiYG%q+^hyQaX2SuT0!79ntPEJy<*uf?XhCAbkMO7D~pQ@c4p<-=cjCU)^Q!z z&dy|KXXdh5^dU8#uxSj@ARUnui7qgvgyQ)vj4MInt>;AI(pcj7$kEg_5(0lr$$YF! zmYrO;QZ{X8!4tiYY01h}EV*p0p10&_E0=uHO2PIe$cWZ4!S>~zZ5=$(dzehy6)Od} zAK|=%;_hxg*+8F{eKb}?7Vf8!m>m*N-4BaL6n@sgA658u13#|t4-DKU{+M>2ICq3i z(HNs)(hLFp@P!B9=Lv^@_8ZrLu(b#1zoPUxaqGl`0vhmBP>m4R1A>MZIz{2+7iTcJ zn6j9j#54dm584MY$|g>ozOs-jS6MqY8NP%Lj10(vj8YTa)X#YVlcS&f1i zi160pU90Jrgy_{tP@f7hK;!S-9$7dG5peV`<4*u20`?FM##aCm0UxHpIPMPu{xA*3 zD*%b$A6>$D6CjZp_oE(sAnx}HhyD>7?B|ZAKdRw>Xt;i!BdQMYgPgFRQ4QDgFsX1e z52rL-&%+BEuEz~D|9T!m4cFsd*Zk=D|4zg8xVJT2k87(u;Jz44^J>F5_c_;*aqj2H z(C2;@PV;gYc^kAwjow=3UBj<$2*13!`i!K3!m{%jaDX({|N(X z<@mhj2*)1ZSDkLD^Yg!rWo*amITG-mb+G>aAMbyWbn%W&^?M31&&Byi4A2`i5Z|=V zsDxgFl18RIzHj~N|DpQet}9#AAMcp$x&HlP!{k#H|EfyPh_W^9;nS==?B`Yg)xc4XAP5XZU1e*2V literal 0 HcmV?d00001 diff --git a/dwm/slstatus/components/run_command.c b/dwm/slstatus/components/run_command.c new file mode 100644 index 0000000..93bf6da --- /dev/null +++ b/dwm/slstatus/components/run_command.c @@ -0,0 +1,31 @@ +/* See LICENSE file for copyright and license details. */ +#include +#include + +#include "../slstatus.h" +#include "../util.h" + +const char * +run_command(const char *cmd) +{ + char *p; + FILE *fp; + + if (!(fp = popen(cmd, "r"))) { + warn("popen '%s':", cmd); + return NULL; + } + + p = fgets(buf, sizeof(buf) - 1, fp); + if (pclose(fp) < 0) { + warn("pclose '%s':", cmd); + return NULL; + } + if (!p) + return NULL; + + if ((p = strrchr(buf, '\n'))) + p[0] = '\0'; + + return buf[0] ? buf : NULL; +} diff --git a/dwm/slstatus/components/run_command.o b/dwm/slstatus/components/run_command.o new file mode 100644 index 0000000000000000000000000000000000000000..dcc18459c8e53c2e2d0c4060649979625800782f GIT binary patch literal 2104 zcmbtVOHUI~6h3W1P;sn8lNyYfjeH?CZmxIkAfFv0W9+*77QyU{PXbI>W~x_QYpdp5%2o$F_Cu!fc6%>E zl&$P2;m%~`y=!jOHcsv5C2B62sQu`_vGvXQy?ul$)U&u~Awy7MN7#kbW`zEGlF6fCtBVi=;WIQ<-A4(=sfv`-S z8|tx$!W63cmd<=1=G)HeYQ$-! z*BWU$%YL`7zPlFY`ng2|TDb8RJoclRexwDTZo!YY;K^Dm&gV;oLaw-I1p+`*k zKDGhyI9%Z`gJeK^n49oe9{?U#UifK{4AjBggr5b;fc_{q;U9uzfbZfa{3b|-%x71v ztK!jhUi7+;M@}7vy-{#-3uN$~dHsr5mbscU9CO_vV=?FC$XKv#GOQ9D$obKcfwMA; zEGd>8)8MBzU^}_|1LZFl*Nn2okJxfHI28rWmH8zrS1{`{_%B1}Y`m#MfhsBG%RQGc zw0`ukgS}1pNw#CSER0T-fHQ$94?Bh+<2*O;N)F1!XE6eOaQurLN6mlDPjD`3dcS&X zD9HF&pC2;5^eGO)#(VeUr*h;yNKEpipX7kpqCwx)jBKL4%N*Wc!<}S5s`7*LlKp3i z3%n0VgZU|yf76rIzrp-fjx;-e9VA1}8Rw7pE&0MX8yk7}?*N8XkGG3E8q7z{;Mp@p cpVWe;;P{}*)tM7)HOn7X^M6uTdPXq+FZ=cT5dZ)H literal 0 HcmV?d00001 diff --git a/dwm/slstatus/components/swap.c b/dwm/slstatus/components/swap.c new file mode 100644 index 0000000..f270d93 --- /dev/null +++ b/dwm/slstatus/components/swap.c @@ -0,0 +1,274 @@ +/* See LICENSE file for copyright and license details. */ +#include +#include +#include +#include + +#include "../slstatus.h" +#include "../util.h" + +#if defined(__linux__) + static int + get_swap_info(long *s_total, long *s_free, long *s_cached) + { + FILE *fp; + struct { + const char *name; + const size_t len; + long *var; + } ent[] = { + { "SwapTotal", sizeof("SwapTotal") - 1, s_total }, + { "SwapFree", sizeof("SwapFree") - 1, s_free }, + { "SwapCached", sizeof("SwapCached") - 1, s_cached }, + }; + size_t line_len = 0, i, left; + char *line = NULL; + + /* get number of fields we want to extract */ + for (i = 0, left = 0; i < LEN(ent); i++) + if (ent[i].var) + left++; + + if (!(fp = fopen("/proc/meminfo", "r"))) { + warn("fopen '/proc/meminfo':"); + return 1; + } + + /* read file line by line and extract field information */ + while (left > 0 && getline(&line, &line_len, fp) >= 0) { + for (i = 0; i < LEN(ent); i++) { + if (ent[i].var && + !strncmp(line, ent[i].name, ent[i].len)) { + sscanf(line + ent[i].len + 1, + "%ld kB\n", ent[i].var); + left--; + break; + } + } + } + free(line); + if (ferror(fp)) { + warn("getline '/proc/meminfo':"); + return 1; + } + + fclose(fp); + return 0; + } + + const char * + swap_free(const char *unused) + { + long free; + + if (get_swap_info(NULL, &free, NULL)) + return NULL; + + return fmt_human(free * 1024, 1024); + } + + const char * + swap_perc(const char *unused) + { + long total, free, cached; + + if (get_swap_info(&total, &free, &cached) || total == 0) + return NULL; + + return bprintf("%d", 100 * (total - free - cached) / total); + } + + const char * + swap_total(const char *unused) + { + long total; + + if (get_swap_info(&total, NULL, NULL)) + return NULL; + + return fmt_human(total * 1024, 1024); + } + + const char * + swap_used(const char *unused) + { + long total, free, cached; + + if (get_swap_info(&total, &free, &cached)) + return NULL; + + return fmt_human((total - free - cached) * 1024, 1024); + } +#elif defined(__OpenBSD__) + #include + #include + #include + #include + + static int + getstats(int *total, int *used) + { + struct swapent *sep, *fsep; + int rnswap, nswap, i; + + if ((nswap = swapctl(SWAP_NSWAP, 0, 0)) < 1) { + warn("swaptctl 'SWAP_NSWAP':"); + return 1; + } + if (!(fsep = sep = calloc(nswap, sizeof(*sep)))) { + warn("calloc 'nswap':"); + return 1; + } + if ((rnswap = swapctl(SWAP_STATS, (void *)sep, nswap)) < 0) { + warn("swapctl 'SWAP_STATA':"); + return 1; + } + if (nswap != rnswap) { + warn("getstats: SWAP_STATS != SWAP_NSWAP"); + return 1; + } + + *total = 0; + *used = 0; + + for (i = 0; i < rnswap; i++) { + *total += sep->se_nblks >> 1; + *used += sep->se_inuse >> 1; + } + + free(fsep); + + return 0; + } + + const char * + swap_free(const char *unused) + { + int total, used; + + if (getstats(&total, &used)) + return NULL; + + return fmt_human((total - used) * 1024, 1024); + } + + const char * + swap_perc(const char *unused) + { + int total, used; + + if (getstats(&total, &used)) + return NULL; + + if (total == 0) + return NULL; + + return bprintf("%d", 100 * used / total); + } + + const char * + swap_total(const char *unused) + { + int total, used; + + if (getstats(&total, &used)) + return NULL; + + return fmt_human(total * 1024, 1024); + } + + const char * + swap_used(const char *unused) + { + int total, used; + + if (getstats(&total, &used)) + return NULL; + + return fmt_human(used * 1024, 1024); + } +#elif defined(__FreeBSD__) + #include + #include + #include + #include + #include + + static int getswapinfo(struct kvm_swap *swap_info, size_t size) + { + kvm_t *kd; + + kd = kvm_openfiles(NULL, "/dev/null", NULL, 0, NULL); + if (kd == NULL) { + warn("kvm_openfiles '/dev/null':"); + return 0; + } + + if (kvm_getswapinfo(kd, swap_info, size, 0 /* Unused flags */) < 0) { + warn("kvm_getswapinfo:"); + kvm_close(kd); + return 0; + } + + kvm_close(kd); + return 1; + } + + const char * + swap_free(const char *unused) + { + struct kvm_swap swap_info[1]; + long used, total; + + if (!getswapinfo(swap_info, 1)) + return NULL; + + total = swap_info[0].ksw_total; + used = swap_info[0].ksw_used; + + return fmt_human((total - used) * getpagesize(), 1024); + } + + const char * + swap_perc(const char *unused) + { + struct kvm_swap swap_info[1]; + long used, total; + + if (!getswapinfo(swap_info, 1)) + return NULL; + + total = swap_info[0].ksw_total; + used = swap_info[0].ksw_used; + + return bprintf("%d", used * 100 / total); + } + + const char * + swap_total(const char *unused) + { + struct kvm_swap swap_info[1]; + long total; + + if (!getswapinfo(swap_info, 1)) + return NULL; + + total = swap_info[0].ksw_total; + + return fmt_human(total * getpagesize(), 1024); + } + + const char * + swap_used(const char *unused) + { + struct kvm_swap swap_info[1]; + long used; + + if (!getswapinfo(swap_info, 1)) + return NULL; + + used = swap_info[0].ksw_used; + + return fmt_human(used * getpagesize(), 1024); + } +#endif diff --git a/dwm/slstatus/components/swap.o b/dwm/slstatus/components/swap.o new file mode 100644 index 0000000000000000000000000000000000000000..d20814e68c7077396307f1d532f8cdb09c764e80 GIT binary patch literal 3880 zcmb`JduUr#9LG=kaNX-J&TU3EBtqt*(=4g2wquT_?Y2{CWo+#p=*-gOW+}~U$&Kr@ z;-HIi$)Y0oL_xtngfW=7|AZOcoKwL+_Sc~Q2m@E`WD4SA=;H5t?>Xt&B>_QyaL?m& zzQ5mj-E;1Je%tW&7MF`jbFr;#p(ZI~A1+-e_gTe0rm^KLyf?fjJQf}u+Z~$aGuNi# zyxg|lPXcZZ`jWiT4lOsQeL-#-KF+@!^!XP9QK7Fx6!tB#M5Dfg@bcEZ27NtBd1t7~ zOEq43l*DYsYv=gPO&9cTUg-wnGqW{5bHidDROT#d>v^fV;`k}3%rAIp)>z6b@HE?e z^F6#g?eo}T^SYIr=O8};x$Qn*93hc=q*N;ghi1-uMtXlO{=~~&K3*YTZvJSw4VP0? zDOIOV4Oikm?{LNNCFd^;l}CLYL!=!xuXB^ic2}UKYVo6?%JgcNn8L7mgV(;X+JD$n ztJOl)Pp}ylnD5|Xbi7PU8|NGCg*Mvlcr)jx%*#(42tOG<5Pm8gq2;;e30(@+Xh*ul zju<|Q@%{rq=5ZjhIk`FQCoV*@uY@{NPkF(qz3S&fSor)RtyZh;#%v-PRCcd~y8JER+_iHzPr5NB-1z`$m& zf5+ov_jyBIflwgi?F@Ey1-m;t@$xh5Ec4QXb4V)I!dz7_X)aNhXMUAva6Pk&xu)E% zwaXTDyh4qf_&U+{HpKm!`{kB?&GS-gzviv9^=tkU?O`qW!fj!#XJ*lM?X;`)IhWQm zpasL4pClwDmwv5-G4zoXv34OJ)VwVtS_k+s)XAPkGN=Vx4%_@q)X7x6hw7&-%Gfw^ z=ntTW=7yoSv0rM96s-+zJ_MsRtIMsqQ*Dh!tlO>LhQeCGaigi`wJPoG4i!>)z2II4 zzhCgX9ek7E0SE6Ae8jff2TLn)z_yE=24uM)?4o*v6D^o9}E3>3l+#@{IgU>zh?xu-ctw)bTI^C zINT8wBi2n27#;{RN2uU}RN02;>q{qHCSVGU|vw3+*u!51##L_tyiA)r- zvEJTDp%9B^66{DcpJ9nuDqGO0tzblBlaW|*GLnc+q^z+-61b%jX(N&>rlT2~<@9`v zjpy zKrEY1>lu<{vW6a@Pw|7+Ar$pPnPPzc3Fy2TN68fd^&}n1Xj&Ho`j45H{IT^obE@@; z${MlWvQ4}uvTA+Tuor!GVi&A`cq-<^X5bx%ulxw(8x6ac9&krDY>yK_Oy=zW0b+>h zl>b}*kcinyxoXmXLWNY8{mZ;hu%JWtsTh#_HI)2Fx)-3&z=5=*=VVzuqb5C@jKTKcXA_tKL$+ptew?Ur~g0Qp|qL+ literal 0 HcmV?d00001 diff --git a/dwm/slstatus/components/temperature.c b/dwm/slstatus/components/temperature.c new file mode 100644 index 0000000..7cf1394 --- /dev/null +++ b/dwm/slstatus/components/temperature.c @@ -0,0 +1,73 @@ +/* See LICENSE file for copyright and license details. */ +#include + +#include "../slstatus.h" +#include "../util.h" + + +#if defined(__linux__) + #include + + const char * + temp(const char *file) + { + uintmax_t temp; + + if (pscanf(file, "%ju", &temp) != 1) + return NULL; + + return bprintf("%ju", temp / 1000); + } +#elif defined(__OpenBSD__) + #include + #include /* before for struct timeval */ + #include + #include + + const char * + temp(const char *unused) + { + int mib[5]; + size_t size; + struct sensor temp; + + mib[0] = CTL_HW; + mib[1] = HW_SENSORS; + mib[2] = 0; /* cpu0 */ + mib[3] = SENSOR_TEMP; + mib[4] = 0; /* temp0 */ + + size = sizeof(temp); + + if (sysctl(mib, 5, &temp, &size, NULL, 0) < 0) { + warn("sysctl 'SENSOR_TEMP':"); + return NULL; + } + + /* kelvin to celsius */ + return bprintf("%d", (int)((float)(temp.value-273150000) / 1E6)); + } +#elif defined(__FreeBSD__) + #include + #include + #include + + #define ACPI_TEMP "hw.acpi.thermal.%s.temperature" + + const char * + temp(const char *zone) + { + char buf[256]; + int temp; + size_t len; + + len = sizeof(temp); + snprintf(buf, sizeof(buf), ACPI_TEMP, zone); + if (sysctlbyname(buf, &temp, &len, NULL, 0) < 0 + || !len) + return NULL; + + /* kelvin to decimal celcius */ + return bprintf("%d.%d", (temp - 2731) / 10, abs((temp - 2731) % 10)); + } +#endif diff --git a/dwm/slstatus/components/temperature.o b/dwm/slstatus/components/temperature.o new file mode 100644 index 0000000000000000000000000000000000000000..31e02ae15f584288decdf98364eefcec0d1ad08d GIT binary patch literal 1704 zcmbtTPiqrV5T8v`6S2lsdQfU%!BisZV>eV#50a8jw0iK6 zQz$~eg@T{JTToH)=m${nRM3Mx=|PAy+c)WE*Pc;*Er+0gDFL zU_W9MAUC$}7Xr5c88`~J?dQ`J+PyD!_lI7!w~{ltAfC^rt-js+wnKF9&EQjK8p-VI z9qeR%wtHXgU%Phiz10sAz9%qw>rOUZwa-rm9prdG*xh&fgSRt}IsgmB;#DKJuypsF zVa*ClSVrE=&zhI=d4MD?VxW$rVg@8Y>l4PJshIz5QW4sdTcB;|+SEiUy^Z8)#7Rk3 z=rfnmyNRWYk+_%9=Q3%6;)MDpVRsP6jm4bku^^FlJ1VrV6QTTI4~U&Y)kjl<$T$Gc z9e{&$8*SHfWXE$w1;k>}3?OLx6{lH)a@$*N${LhPzH};UrAmFRRC89>gT?T}XPQ8t zM&i$4PtK?W;_0s#pAX@OLiocFo(kcH!l^&$P=vqPkWLwdFTFimXU}uj9U_9wGRt>aS1`5(N*D +#include +#include + +#include "../slstatus.h" +#include "../util.h" + +#if defined(CLOCK_BOOTTIME) + #define UPTIME_FLAG CLOCK_BOOTTIME +#elif defined(CLOCK_UPTIME) + #define UPTIME_FLAG CLOCK_UPTIME +#else + #define UPTIME_FLAG CLOCK_MONOTONIC +#endif + +const char * +uptime(const char *unused) +{ + char warn_buf[256]; + uintmax_t h, m; + struct timespec uptime; + + if (clock_gettime(UPTIME_FLAG, &uptime) < 0) { + snprintf(warn_buf, sizeof(warn_buf), "clock_gettime %d", UPTIME_FLAG); + warn(warn_buf); + return NULL; + } + + h = uptime.tv_sec / 3600; + m = uptime.tv_sec % 3600 / 60; + + return bprintf("%juh %jum", h, m); +} diff --git a/dwm/slstatus/components/uptime.o b/dwm/slstatus/components/uptime.o new file mode 100644 index 0000000000000000000000000000000000000000..e6394bf3049374f7a9e961b4d3baeab9e5419263 GIT binary patch literal 1968 zcmbtUOKTHR6h4!_qShFtLZL1ONu@;{GNB@hkCdt%p@>ujMIlU*X;Yh*lPR{kkRl49 z6kNEdAmUPR(}kOEG^n`tAGj6jLRTUP^?Wz?CX->Z(GTvNbH4MsbI+Z5cyZ=ZMAJw? zqjS`@6ibxsZR=^FrYS~y>Dv1Nwyf3fI%nmrwTaO&*!8!GVJ56~FA@EQ@W+i6!&<+c z7~T@`>jy!ajdy5f)xU}uv(eVJlh)dWM06`2LzT0Lww_zRes7(DR{w0(zX;o^e=r*& z+gf`jdgiU8Lt+zNUz1<`guUJRm@8ItiR`2C)K*HKoh75@xlLJ6n(Gv8!*iBBGV-=( zlaZ~}$Z#t#5YE?{j9jHua>^W1u6T~YSNXU&A!*N-myD`gsXDH=!l@|e6f$$JU2@ae(+ z$JmFO|C(=dE^4a(3abLDKi)Qs>Vh0(bd|&|v-znV%L>?ME=b$gZ&YZ^(hDIb;6#&Q!kQ!+N9J shU_1ea*#RvHG}!68Js;+^h& +#include +#include +#include + +#include "../slstatus.h" +#include "../util.h" + +const char * +gid(const char *unused) +{ + return bprintf("%d", getgid()); +} + +const char * +username(const char *unused) +{ + struct passwd *pw; + + if (!(pw = getpwuid(geteuid()))) { + warn("getpwuid '%d':", geteuid()); + return NULL; + } + + return bprintf("%s", pw->pw_name); +} + +const char * +uid(const char *unused) +{ + return bprintf("%d", geteuid()); +} diff --git a/dwm/slstatus/components/user.o b/dwm/slstatus/components/user.o new file mode 100644 index 0000000000000000000000000000000000000000..c3444331a57068a40dd80ad0c580b907b8a0906d GIT binary patch literal 2192 zcmb`H-%Aux6vxk)ruk#ptmuak^I{g%w6htBRBSBf1{M+~DpaiQxQgzNW=GU|=&1*Z z!2hFvVj-yhh#q>Z$KC@w-#h25<8}8XI&kNl`#C@Eo%`$E)XbwU#~~Gm9?)S=DN(xT z(9Rh%M=2Vj*`MeXKHi5~+WX=+f5DnJc<*cMecz0R3m-BP5{48${Fj{G@wr`swrQu0QVip6_Ne+40PsY!>sNZf-6&OrL|O zi<~ByiX(mf=dz12)`0oT{#4)8zyf>Y zygBhF^8_7Jm`6ALJ~-xJaH7r5V2t?hjM4fG8LNkeTO>B(eh=3=DwnuBoTzW+$_zSv zG}QF2bl_K+qmJgAHDPwEL;T$iJlBEWW{&zt)|44-HGZZRXA>Jd8J}hByYLVATO+;gK)n5 zAKc_&nj;}h$9Ck+hs+wZx8?0ROR6k~i+8P7>J=savcI+biaPO067~wzgVX^0> z>mPfGUbBIkc79q0TGK$$cK#;wcKcrdWGTeTyeW8-G++0>-PlOkk@06m +#include +#include +#include +#include + +#include "../slstatus.h" +#include "../util.h" + +#if defined(__OpenBSD__) | defined(__FreeBSD__) + #include + #include + #include + #include + + struct control { + LIST_ENTRY(control) next; + unsigned int addr; + #define CTRL_NONE 0 + #define CTRL_LEVEL 1 + #define CTRL_MUTE 2 + unsigned int type; + unsigned int maxval; + unsigned int val; + }; + + static LIST_HEAD(, control) controls = LIST_HEAD_INITIALIZER(controls); + static struct pollfd *pfds; + static struct sioctl_hdl *hdl; + static int initialized; + + /* + * Call-back to obtain the description of all audio controls. + */ + static void + ondesc(void *unused, struct sioctl_desc *desc, int val) + { + struct control *c, *ctmp; + unsigned int type = CTRL_NONE; + + if (desc == NULL) + return; + + /* Delete existing audio control with the same address. */ + LIST_FOREACH_SAFE(c, &controls, next, ctmp) { + if (desc->addr == c->addr) { + LIST_REMOVE(c, next); + free(c); + break; + } + } + + /* Only match output.level and output.mute audio controls. */ + if (desc->group[0] != 0 || + strcmp(desc->node0.name, "output") != 0) + return; + if (desc->type == SIOCTL_NUM && + strcmp(desc->func, "level") == 0) + type = CTRL_LEVEL; + else if (desc->type == SIOCTL_SW && + strcmp(desc->func, "mute") == 0) + type = CTRL_MUTE; + else + return; + + c = malloc(sizeof(struct control)); + if (c == NULL) { + warn("sndio: failed to allocate audio control\n"); + return; + } + + c->addr = desc->addr; + c->type = type; + c->maxval = desc->maxval; + c->val = val; + LIST_INSERT_HEAD(&controls, c, next); + } + + /* + * Call-back invoked whenever an audio control changes. + */ + static void + onval(void *unused, unsigned int addr, unsigned int val) + { + struct control *c; + + LIST_FOREACH(c, &controls, next) { + if (c->addr == addr) + break; + } + c->val = val; + } + + static void + cleanup(void) + { + struct control *c; + + if (hdl) { + sioctl_close(hdl); + hdl = NULL; + } + + free(pfds); + pfds = NULL; + + while (!LIST_EMPTY(&controls)) { + c = LIST_FIRST(&controls); + LIST_REMOVE(c, next); + free(c); + } + } + + static int + init(void) + { + hdl = sioctl_open(SIO_DEVANY, SIOCTL_READ, 0); + if (hdl == NULL) { + warn("sndio: cannot open device"); + goto failed; + } + + if (!sioctl_ondesc(hdl, ondesc, NULL)) { + warn("sndio: cannot set control description call-back"); + goto failed; + } + + if (!sioctl_onval(hdl, onval, NULL)) { + warn("sndio: cannot set control values call-back"); + goto failed; + } + + pfds = calloc(sioctl_nfds(hdl), sizeof(struct pollfd)); + if (pfds == NULL) { + warn("sndio: cannot allocate pollfd structures"); + goto failed; + } + + return 1; + failed: + cleanup(); + return 0; + } + + const char * + vol_perc(const char *unused) + { + struct control *c; + int n, v, value; + + if (!initialized) + initialized = init(); + + if (hdl == NULL) + return NULL; + + n = sioctl_pollfd(hdl, pfds, POLLIN); + if (n > 0) { + n = poll(pfds, n, 0); + if (n > 0) { + if (sioctl_revents(hdl, pfds) & POLLHUP) { + warn("sndio: disconnected"); + cleanup(); + initialized = 0; + return NULL; + } + } + } + + value = 100; + LIST_FOREACH(c, &controls, next) { + if (c->type == CTRL_MUTE && c->val == 1) + value = 0; + else if (c->type == CTRL_LEVEL) { + v = (c->val * 100 + c->maxval / 2) / c->maxval; + /* For multiple channels return the minimum. */ + if (v < value) + value = v; + } + } + + return bprintf("%d", value); + } +#else + #include + + const char * + vol_perc(const char *card) + { + size_t i; + int v, afd, devmask; + char *vnames[] = SOUND_DEVICE_NAMES; + + if ((afd = open(card, O_RDONLY | O_NONBLOCK)) < 0) { + warn("open '%s':", card); + return NULL; + } + + if (ioctl(afd, (int)SOUND_MIXER_READ_DEVMASK, &devmask) < 0) { + warn("ioctl 'SOUND_MIXER_READ_DEVMASK':"); + close(afd); + return NULL; + } + for (i = 0; i < LEN(vnames); i++) { + if (devmask & (1 << i) && !strcmp("vol", vnames[i])) { + if (ioctl(afd, MIXER_READ(i), &v) < 0) { + warn("ioctl 'MIXER_READ(%ld)':", i); + close(afd); + return NULL; + } + } + } + + close(afd); + + return bprintf("%d", v & 0xff); + } +#endif diff --git a/dwm/slstatus/components/volume.o b/dwm/slstatus/components/volume.o new file mode 100644 index 0000000000000000000000000000000000000000..b7ab3c439192df5d04e9ca6f66732a5a0509b57a GIT binary patch literal 3616 zcmds(O>7%g5P-+|s|&#iP(-S7Fj7JsMP0>C3L!wTo21=B5>S3n5ER#0Z(=L9*Q_^b z0!XB4sW8D(4i)O52LwWJ0I3yH1rn+(N@DGh@hdDPq*Jd9j)q>ciLP3{OmFWiT+Me@LqNKVZD4uuRKRywCcj!2g}#W zSM8ZvnF6tXs^;38EE_}`Xwp?=BgWE^cSI@dnm)5)YxR2{J zx;^SAe<1zZvBc|%V^?U>|6{R=W+B|!QR*CktYtX4aOcEJQ)5HP(WBGDM?v|Mm9P&D#TDw?Tz(}rBOU_w4? zfRRSEL~Sv!O#`xXscZo(x2B+|8ya)#UPx!>qEyAG>V;wkV~ZJU!GXnW+O)tju&;Sna19%uMgADKby4u4P-~@bEY$X4eIgV-(=Zf@oN7E0TC1yX3WOqv z5}`H>ITQ+V(hiEcYJfjBYBkr_+~ENA_^T!L&~y*>j)Qx7s~gz_?k4qRJ;MBcA0u-g z^QgifXa0i1JJEm0H-Gn?A?v~7jlDgA&Zb&?UXAkp{Qihv<;wr1t(H=!P_uk01b==OCeY$`w9I5QXBKu?TkvqEI}o0^x5H zM4|Wxun0dx5QXA*VG&*-h@$p?*269jp)K)W`FM+uU-fbSxIZ(eacRp)Kfn0m{m-@T zfVt+;9=h=T>;h(TC{Yn3yGe4)qf64yG3ctwy7Ye_`{so19$No18|DOG- z!mqO*W=-pp%BEdm;qdGh`_9KvF-egbu^@r!f_ zqD=G0qVZ`Ab$q%PiK*l3+deV|u<*3Rg(uM>=KX8g#31=UZ6Vi^e9^;5$?j3&+IT|p z-$j}wPxKh)OS|Yk^?|rS@+9sJH0V{SkK51r>b&IrN&X@l)Tf%C;rwX{WUc1EiM-bL zyH1w?imVg*e)OM6@`cwLoARnW{sn$uy0dEK(=fGORgu^4EOq7+_5IP^Q!D>hp8tw3 ImrOPPU&8>uHUIzs literal 0 HcmV?d00001 diff --git a/dwm/slstatus/components/wifi.c b/dwm/slstatus/components/wifi.c new file mode 100644 index 0000000..4543d32 --- /dev/null +++ b/dwm/slstatus/components/wifi.c @@ -0,0 +1,267 @@ +/* See LICENSE file for copyright and license details. */ +#include +#include +#include +#include +#include +#include + +#include "../slstatus.h" +#include "../util.h" + +#define RSSI_TO_PERC(rssi) \ + rssi >= -50 ? 100 : \ + (rssi <= -100 ? 0 : \ + (2 * (rssi + 100))) + +#if defined(__linux__) + #include + #include + + #define NET_OPERSTATE "/sys/class/net/%s/operstate" + + const char * + wifi_perc(const char *interface) + { + int cur; + size_t i; + char *p, *datastart; + char path[PATH_MAX]; + char status[5]; + FILE *fp; + + if (esnprintf(path, sizeof(path), NET_OPERSTATE, interface) < 0) + return NULL; + if (!(fp = fopen(path, "r"))) { + warn("fopen '%s':", path); + return NULL; + } + p = fgets(status, 5, fp); + fclose(fp); + if (!p || strcmp(status, "up\n") != 0) + return NULL; + + if (!(fp = fopen("/proc/net/wireless", "r"))) { + warn("fopen '/proc/net/wireless':"); + return NULL; + } + + for (i = 0; i < 3; i++) + if (!(p = fgets(buf, sizeof(buf) - 1, fp))) + break; + + fclose(fp); + if (i < 2 || !p) + return NULL; + + if (!(datastart = strstr(buf, interface))) + return NULL; + + datastart = (datastart+(strlen(interface)+1)); + sscanf(datastart + 1, " %*d %d %*d %*d\t\t %*d\t " + "%*d\t\t%*d\t\t %*d\t %*d\t\t %*d", &cur); + + /* 70 is the max of /proc/net/wireless */ + return bprintf("%d", (int)((float)cur / 70 * 100)); + } + + const char * + wifi_essid(const char *interface) + { + static char id[IW_ESSID_MAX_SIZE+1]; + int sockfd; + struct iwreq wreq; + + memset(&wreq, 0, sizeof(struct iwreq)); + wreq.u.essid.length = IW_ESSID_MAX_SIZE+1; + if (esnprintf(wreq.ifr_name, sizeof(wreq.ifr_name), "%s", + interface) < 0) + return NULL; + + if ((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) { + warn("socket 'AF_INET':"); + return NULL; + } + wreq.u.essid.pointer = id; + if (ioctl(sockfd,SIOCGIWESSID, &wreq) < 0) { + warn("ioctl 'SIOCGIWESSID':"); + close(sockfd); + return NULL; + } + + close(sockfd); + + if (!strcmp(id, "")) + return NULL; + + return id; + } +#elif defined(__OpenBSD__) + #include + #include + #include + #include /* before for NBBY */ + #include + #include + #include + + static int + load_ieee80211_nodereq(const char *interface, struct ieee80211_nodereq *nr) + { + struct ieee80211_bssid bssid; + int sockfd; + uint8_t zero_bssid[IEEE80211_ADDR_LEN]; + + memset(&bssid, 0, sizeof(bssid)); + memset(nr, 0, sizeof(struct ieee80211_nodereq)); + if ((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) { + warn("socket 'AF_INET':"); + return 0; + } + strlcpy(bssid.i_name, interface, sizeof(bssid.i_name)); + if ((ioctl(sockfd, SIOCG80211BSSID, &bssid)) < 0) { + warn("ioctl 'SIOCG80211BSSID':"); + close(sockfd); + return 0; + } + memset(&zero_bssid, 0, sizeof(zero_bssid)); + if (memcmp(bssid.i_bssid, zero_bssid, + IEEE80211_ADDR_LEN) == 0) { + close(sockfd); + return 0; + } + strlcpy(nr->nr_ifname, interface, sizeof(nr->nr_ifname)); + memcpy(&nr->nr_macaddr, bssid.i_bssid, sizeof(nr->nr_macaddr)); + if ((ioctl(sockfd, SIOCG80211NODE, nr)) < 0 && nr->nr_rssi) { + warn("ioctl 'SIOCG80211NODE':"); + close(sockfd); + return 0; + } + + return close(sockfd), 1; + } + + const char * + wifi_perc(const char *interface) + { + struct ieee80211_nodereq nr; + int q; + + if (load_ieee80211_nodereq(interface, &nr)) { + if (nr.nr_max_rssi) + q = IEEE80211_NODEREQ_RSSI(&nr); + else + q = RSSI_TO_PERC(nr.nr_rssi); + + return bprintf("%d", q); + } + + return NULL; + } + + const char * + wifi_essid(const char *interface) + { + struct ieee80211_nodereq nr; + + if (load_ieee80211_nodereq(interface, &nr)) + return bprintf("%s", nr.nr_nwid); + + return NULL; + } +#elif defined(__FreeBSD__) + #include + #include + + int + load_ieee80211req(int sock, const char *interface, void *data, int type, size_t *len) + { + char warn_buf[256]; + struct ieee80211req ireq; + memset(&ireq, 0, sizeof(ireq)); + ireq.i_type = type; + ireq.i_data = (caddr_t) data; + ireq.i_len = *len; + + strlcpy(ireq.i_name, interface, sizeof(ireq.i_name)); + if (ioctl(sock, SIOCG80211, &ireq) < 0) { + snprintf(warn_buf, sizeof(warn_buf), + "ioctl: 'SIOCG80211': %d", type); + warn(warn_buf); + return 0; + } + + *len = ireq.i_len; + return 1; + } + + const char * + wifi_perc(const char *interface) + { + union { + struct ieee80211req_sta_req sta; + uint8_t buf[24 * 1024]; + } info; + uint8_t bssid[IEEE80211_ADDR_LEN]; + int rssi_dbm; + int sockfd; + size_t len; + const char *fmt; + + if ((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) { + warn("socket 'AF_INET':"); + return NULL; + } + + /* Retreive MAC address of interface */ + len = IEEE80211_ADDR_LEN; + fmt = NULL; + if (load_ieee80211req(sockfd, interface, &bssid, IEEE80211_IOC_BSSID, &len)) + { + /* Retrieve info on station with above BSSID */ + memset(&info, 0, sizeof(info)); + memcpy(info.sta.is_u.macaddr, bssid, sizeof(bssid)); + + len = sizeof(info); + if (load_ieee80211req(sockfd, interface, &info, IEEE80211_IOC_STA_INFO, &len)) { + rssi_dbm = info.sta.info[0].isi_noise + + info.sta.info[0].isi_rssi / 2; + + fmt = bprintf("%d", RSSI_TO_PERC(rssi_dbm)); + } + } + + close(sockfd); + return fmt; + } + + const char * + wifi_essid(const char *interface) + { + char ssid[IEEE80211_NWID_LEN + 1]; + size_t len; + int sockfd; + const char *fmt; + + if ((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) { + warn("socket 'AF_INET':"); + return NULL; + } + + fmt = NULL; + len = sizeof(ssid); + memset(&ssid, 0, len); + if (load_ieee80211req(sockfd, interface, &ssid, IEEE80211_IOC_SSID, &len)) { + if (len < sizeof(ssid)) + len += 1; + else + len = sizeof(ssid); + + ssid[len - 1] = '\0'; + fmt = bprintf("%s", ssid); + } + + close(sockfd); + return fmt; + } +#endif diff --git a/dwm/slstatus/components/wifi.o b/dwm/slstatus/components/wifi.o new file mode 100644 index 0000000000000000000000000000000000000000..dd05aef3fb4a3784b82e525331a5c5a799cb32a8 GIT binary patch literal 4264 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 literal 0 HcmV?d00001 diff --git a/dwm/slstatus/slstatus.1 b/dwm/slstatus/slstatus.1 new file mode 100644 index 0000000..73e7a60 --- /dev/null +++ b/dwm/slstatus/slstatus.1 @@ -0,0 +1,47 @@ +.Dd 2023-04-23 +.Dt SLSTATUS 1 +.Os +.Sh NAME +.Nm slstatus +.Nd suckless status +.Sh SYNOPSIS +.Nm +.Op Fl s +.Op Fl 1 +.Sh DESCRIPTION +.Nm +is a small tool for providing system status information to other programs +over the EWMH +.Em WM_NAME +property of the root window (used by +.Xr dwm 1 ) or standard input/output. It is designed to be as efficient as possible by +only issuing the minimum of system calls required. +.P +By default, +.Nm +outputs to WM_NAME. +.Sh OPTIONS +.Bl -tag -width Ds +.It Fl v +Print version information to stderr, then exit. +.It Fl s +Write to stdout instead of WM_NAME. +.It Fl 1 +Write once to stdout and quit. +.El +.Sh CUSTOMIZATION +.Nm +can be customized by creating a custom config.h and (re)compiling the source +code. This keeps it fast, secure and simple. +.Sh SIGNALS +.Nm +responds to the following signals: +.Pp +.Bl -tag -width TERM -compact +.It USR1 +Triggers an instant redraw. +.El +.Sh AUTHORS +See the LICENSE file for the authors. +.Sh SEE ALSO +.Xr dwm 1 diff --git a/dwm/slstatus/slstatus.c b/dwm/slstatus/slstatus.c new file mode 100644 index 0000000..fd31313 --- /dev/null +++ b/dwm/slstatus/slstatus.c @@ -0,0 +1,134 @@ +/* See LICENSE file for copyright and license details. */ +#include +#include +#include +#include +#include +#include +#include + +#include "arg.h" +#include "slstatus.h" +#include "util.h" + +struct arg { + const char *(*func)(const char *); + const char *fmt; + const char *args; +}; + +char buf[1024]; +static volatile sig_atomic_t done; +static Display *dpy; + +#include "config.h" + +static void +terminate(const int signo) +{ + if (signo != SIGUSR1) + done = 1; +} + +static void +difftimespec(struct timespec *res, struct timespec *a, struct timespec *b) +{ + res->tv_sec = a->tv_sec - b->tv_sec - (a->tv_nsec < b->tv_nsec); + res->tv_nsec = a->tv_nsec - b->tv_nsec + + (a->tv_nsec < b->tv_nsec) * 1E9; +} + +static void +usage(void) +{ + die("usage: %s [-v] [-s] [-1]", argv0); +} + +int +main(int argc, char *argv[]) +{ + struct sigaction act; + struct timespec start, current, diff, intspec, wait; + size_t i, len; + int sflag, ret; + char status[MAXLEN]; + const char *res; + + sflag = 0; + ARGBEGIN { + case 'v': + die("slstatus-"VERSION); + case '1': + done = 1; + /* FALLTHROUGH */ + case 's': + sflag = 1; + break; + default: + usage(); + } ARGEND + + if (argc) + usage(); + + memset(&act, 0, sizeof(act)); + act.sa_handler = terminate; + sigaction(SIGINT, &act, NULL); + sigaction(SIGTERM, &act, NULL); + act.sa_flags |= SA_RESTART; + sigaction(SIGUSR1, &act, NULL); + + if (!sflag && !(dpy = XOpenDisplay(NULL))) + die("XOpenDisplay: Failed to open display"); + + do { + if (clock_gettime(CLOCK_MONOTONIC, &start) < 0) + die("clock_gettime:"); + + status[0] = '\0'; + for (i = len = 0; i < LEN(args); i++) { + if (!(res = args[i].func(args[i].args))) + res = unknown_str; + + if ((ret = esnprintf(status + len, sizeof(status) - len, + args[i].fmt, res)) < 0) + break; + + len += ret; + } + + if (sflag) { + puts(status); + fflush(stdout); + if (ferror(stdout)) + die("puts:"); + } else { + if (XStoreName(dpy, DefaultRootWindow(dpy), status) < 0) + die("XStoreName: Allocation failed"); + XFlush(dpy); + } + + if (!done) { + if (clock_gettime(CLOCK_MONOTONIC, ¤t) < 0) + die("clock_gettime:"); + difftimespec(&diff, ¤t, &start); + + intspec.tv_sec = interval / 1000; + intspec.tv_nsec = (interval % 1000) * 1E6; + difftimespec(&wait, &intspec, &diff); + + if (wait.tv_sec >= 0 && + nanosleep(&wait, NULL) < 0 && + errno != EINTR) + die("nanosleep:"); + } + } while (!done); + + if (!sflag) { + XStoreName(dpy, DefaultRootWindow(dpy), NULL); + if (XCloseDisplay(dpy) < 0) + die("XCloseDisplay: Failed to close display"); + } + + return 0; +} diff --git a/dwm/slstatus/slstatus.h b/dwm/slstatus/slstatus.h new file mode 100644 index 0000000..8ef5874 --- /dev/null +++ b/dwm/slstatus/slstatus.h @@ -0,0 +1,84 @@ +/* See LICENSE file for copyright and license details. */ + +/* battery */ +const char *battery_perc(const char *); +const char *battery_remaining(const char *); +const char *battery_state(const char *); + +/* cat */ +const char *cat(const char *path); + +/* cpu */ +const char *cpu_freq(const char *unused); +const char *cpu_perc(const char *unused); + +/* datetime */ +const char *datetime(const char *fmt); + +/* disk */ +const char *disk_free(const char *path); +const char *disk_perc(const char *path); +const char *disk_total(const char *path); +const char *disk_used(const char *path); + +/* entropy */ +const char *entropy(const char *unused); + +/* hostname */ +const char *hostname(const char *unused); + +/* ip */ +const char *ipv4(const char *interface); +const char *ipv6(const char *interface); + +/* kernel_release */ +const char *kernel_release(const char *unused); + +/* keyboard_indicators */ +const char *keyboard_indicators(const char *fmt); + +/* keymap */ +const char *keymap(const char *unused); + +/* load_avg */ +const char *load_avg(const char *unused); + +/* netspeeds */ +const char *netspeed_rx(const char *interface); +const char *netspeed_tx(const char *interface); + +/* num_files */ +const char *num_files(const char *path); + +/* ram */ +const char *ram_free(const char *unused); +const char *ram_perc(const char *unused); +const char *ram_total(const char *unused); +const char *ram_used(const char *unused); + +/* run_command */ +const char *run_command(const char *cmd); + +/* swap */ +const char *swap_free(const char *unused); +const char *swap_perc(const char *unused); +const char *swap_total(const char *unused); +const char *swap_used(const char *unused); + +/* temperature */ +const char *temp(const char *); + +/* uptime */ +const char *uptime(const char *unused); + +/* user */ +const char *gid(const char *unused); +const char *uid(const char *unused); +const char *username(const char *unused); + +/* volume */ +const char *vol_perc(const char *card); + +/* wifi */ +const char *wifi_essid(const char *interface); +const char *wifi_perc(const char *interface); diff --git a/dwm/slstatus/slstatus.o b/dwm/slstatus/slstatus.o new file mode 100644 index 0000000000000000000000000000000000000000..71f5422ec94058abec679f4d60e2dcf9a8fc3b67 GIT binary patch literal 6512 zcmd6re{5S<700jR{8|@mx82r^G4@uRk*tkthjdLtU~zu5H_Ylbny^3@oLA>1v69%9 z-*ZW-u4~n1o97ye5F%oe(1bKq8by@=snbg94pzEV6%MO)S zS*w0gg9P1vCaTEIoHi}p%9*W^P?+UReZuI}noMn1>z)y~nRttgu;B+YMyfAqW~TMI zPHmf>oHoWZE3KsgYhyNNiRpA=Dn4OYR&vJZWSN|0cCz7}Ryu3!(1B>tX;A1^GM&=K zMF^JCQ)zSBFft(QolcuZg*G6pX)HCe4|}&yV@=z%ra|`i!ZR9xCM55lSokg$HZfcA z?(u?M+{B`fM86ariVhC#%>RoY{OfP)8RLc8F<#i%)C_aM^FIilN0$G9=fza<`I1#z zzQ7N?Qr{nWJ67C`GsX-33@i2@=xEK&J^hg9@Fgo7{V7iCf$Ocgbq8jvSZ;Os!s1Am znOheFVagrQDwvw{-2XYP%v}&;RKR4qUML(wt9f z6-k!!Ky@nc}|!efD0@sy}753$p%9@$X+1I4Z_FzGyhmizlI#9FS& zK=Y+pA76k4Y8>#K8`%1{+-c~f)gH^sUKYgsiC%DG!}9H1*`vi?Ss%+^=ZPn;U|-H& zspH-!(U})A_7r?{C^T$AOz(WjKmQgw6|G?4zs&+KSiweK7!1}&O8!Smybucp_=bic z&wt3b{>J}oiML$7%Ki6VhSFp8SN#DI9`cVtbjDlGM_#?^|MJ+$fAg9o3d& z9hU}t_~w6?%eX&!9T2-rL)$HE-WB)S^Y&Ly=HKYYVrvhc~yi z31v0hHMnpGfQVHwPYIa{<&ou^fMHUf0ngqqGS6(lb4Np6{ZSAHpzaewVcTeOxWbbC z$_qx1FYt}39$(|vy*)mySl#1mK2j6)g`cR6`Z^BP4fu|(@&3r`>*)1`qrPU4fD~MM ze6Tof3Hw>i{!y+}?_C}+idhq~6*n)dT~Wru z9dKbB)wCMYU4r9F(M~G<1}J*)B_-1_WkBvFoM7O~aTK@bUp(ImiClaIp#S2DCpDeI zu3`5OhNjq1pnt%@`$V~heZ|2CBp-F~9in`*gEF>L^5qfRl3|h6u>B5?5y|roo`CWi zGXG-V0h@$NttoX$x$vwD-{-=yAC=;N$Av%V!k>5H$6ff3UHD5b{G1EF=)y0%@ONDJ zH5Xnd-w{x~A_ZLd?Jj)13*YF%?{nc%7tVpNhUZ8{CiW-60SrmS&sOlGDvmd;she0(}*PO@<$n@wlQ z(U}cz6BSFxWfqTvCY6q>1NF+|GgQN=9uDJ)$*DLVwb>Yq8js~Hk;%m~MmE8+`b<1$ z8e_t+(v}XQq&a0XVcBrXn48fv4Ekzh_kd`3ZX7pAo!ljOqQp;!n(tP^8^OK-Css^7 zgyTC+@nDg%!6i;L>^n@@PrTH) z)=G};ew=W8J}^0XmkY=JuJrhgQt=;@T+Po7u?URqA{NLiC!bzgA)S@GpetZ z9OwUTxKy0gM8BHwMxv+Vx|`^6>ec+;PxR|aoG%dl8p0nYdK!P2=xO{BqW=_$lW^#( zae$Ea5cmI^=*=4_ku+KS;CtL-%jG( zO85?0wE-IrcwN)jTyevFd=UdmVMKtt@Nj5IZXJy(#EWVaBTNAS>}Y} zSy-iqq@m)g_v|R)8Rrm=u> z_z?(2B?6*ntz1STA%aTKD<74I5~c+wlSF!E#z;Z%RN68^@T0L+90p{0B9#kevhc@U z)|!(cjmh{p90v?Jl>aHyz+0_74b&|Q0SduJElv21!*@eBg#|e_!*Z7V`U-eul zevjnx@q&__)V@?@l{?$Vy@@fM{-e^N0Xs*MMr<@AaA8dQ*EuU*-K! zfi~_vn);(j +#include +#include +#include +#include +#include + +#include "util.h" + +char *argv0; + +static void +verr(const char *fmt, va_list ap) +{ + vfprintf(stderr, fmt, ap); + + if (fmt[0] && fmt[strlen(fmt) - 1] == ':') { + fputc(' ', stderr); + perror(NULL); + } else { + fputc('\n', stderr); + } +} + +void +warn(const char *fmt, ...) +{ + va_list ap; + + va_start(ap, fmt); + verr(fmt, ap); + va_end(ap); +} + +void +die(const char *fmt, ...) +{ + va_list ap; + + va_start(ap, fmt); + verr(fmt, ap); + va_end(ap); + + exit(1); +} + +static int +evsnprintf(char *str, size_t size, const char *fmt, va_list ap) +{ + int ret; + + ret = vsnprintf(str, size, fmt, ap); + + if (ret < 0) { + warn("vsnprintf:"); + return -1; + } else if ((size_t)ret >= size) { + warn("vsnprintf: Output truncated"); + return -1; + } + + return ret; +} + +int +esnprintf(char *str, size_t size, const char *fmt, ...) +{ + va_list ap; + int ret; + + va_start(ap, fmt); + ret = evsnprintf(str, size, fmt, ap); + va_end(ap); + + return ret; +} + +const char * +bprintf(const char *fmt, ...) +{ + va_list ap; + int ret; + + va_start(ap, fmt); + ret = evsnprintf(buf, sizeof(buf), fmt, ap); + va_end(ap); + + return (ret < 0) ? NULL : buf; +} + +const char * +fmt_human(uintmax_t num, int base) +{ + double scaled; + size_t i, prefixlen; + const char **prefix; + const char *prefix_1000[] = { "", "k", "M", "G", "T", "P", "E", "Z", + "Y" }; + const char *prefix_1024[] = { "", "Ki", "Mi", "Gi", "Ti", "Pi", "Ei", + "Zi", "Yi" }; + + switch (base) { + case 1000: + prefix = prefix_1000; + prefixlen = LEN(prefix_1000); + break; + case 1024: + prefix = prefix_1024; + prefixlen = LEN(prefix_1024); + break; + default: + warn("fmt_human: Invalid base"); + return NULL; + } + + scaled = num; + for (i = 0; i < prefixlen && scaled >= base; i++) + scaled /= base; + + return bprintf("%.1f %s", scaled, prefix[i]); +} + +int +pscanf(const char *path, const char *fmt, ...) +{ + FILE *fp; + va_list ap; + int n; + + if (!(fp = fopen(path, "r"))) { + warn("fopen '%s':", path); + return -1; + } + va_start(ap, fmt); + n = vfscanf(fp, fmt, ap); + va_end(ap); + fclose(fp); + + return (n == EOF) ? -1 : n; +} diff --git a/dwm/slstatus/util.h b/dwm/slstatus/util.h new file mode 100644 index 0000000..cf4b027 --- /dev/null +++ b/dwm/slstatus/util.h @@ -0,0 +1,16 @@ +/* See LICENSE file for copyright and license details. */ +#include + +extern char buf[1024]; + +#define LEN(x) (sizeof(x) / sizeof((x)[0])) + +extern char *argv0; + +void warn(const char *, ...); +void die(const char *, ...); + +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, ...); diff --git a/dwm/slstatus/util.o b/dwm/slstatus/util.o new file mode 100644 index 0000000000000000000000000000000000000000..c4fa245044a20b3115c29eeb38e61ad1e5a5d6ea GIT binary patch literal 5552 zcmdUyZ){Y>7Qkn>i!7*j7gVzTdGUU@6$)|b*5ZS{;A`#H4qC8EF+$a{-9L1t-L7}< z)?$dZDNnhnP57V*AB-VU5)zHU#F&_!LhUarVXYQHZVcxDE zjPK>WliWFTe)r7GnVEBEb|35Nxy|qMF)2QF3#(d^GInlRwcakO?JUF$ww1dJ-2Eqa zf8|r(g!%MFd^eB9#NQa7UWYYjEq70H*Rg`)1)ql6#NLK-TXDrP6W)7t>UcO-?mvSK zIMk0Vg$kLI-<&`SJ*?txpViFW9&3G%8@JkfpvL!=oWF*e;#O~{smIzGYU;D{p{8f7 z31|~)dfqx9^o!OZp#P*@;F92$Nx8?mH~_C=QsaaE+51F6`{iBorf?# z64U(8FX}7;vB@y=2yRhm==Wy3j34A1%MFZ;g)8%oed^^@ zoka6??nFN(+Ywwk_vhD^gNC&BR))JzSqA~YM>?|?7hZgj=MSUROO|MH{_y05c^KPS zGkF0ccUI%aQ2mgBLsix+rkb?NL?+?|~|<>Mcp;Y(%_ z%`SxQEiHsrzaJ}QLThL3%NIfq%<^)HPyM{4_${CIVuY@}po>@Y>DISt^rJpLc^v0< z<_5@Ju^JGWhvqu^Hn~4;C%K`(0(fratsS zJbQ~c^1keG@f-=`*1*Yf4z!v9%DF;4o^;>xYQMAL?tK6K9rw*aU;jrkR>v;KuySS3)N5LLb>nfT3LJDdv0RZsr>g`>wrg zaqs{*TfncQcPZ2zMtI7<*)ShlYJ@wDVArK_BYc|?#G@}xey^hLHct8cFBw6oV&6OA zL3s`fdk2k~(b1Kknob&ll8)l~wf!=QweWF_}!MFqL zhjOiV4VBfs_-zA&gGdux7ub^u6>CdY1G}WcW#w{F`FDN=@k^y6>8pva)cEzp|E}>y z;(3j)A#Q6t1~wi8x~vCKi+9xFybj+|hi?PE9M(;)m&i3>JL>rFCjV<_sYU()8?EE- zkpCOxFY*%DqjmiElmF9xsDOwZ1$_XXTI=u>aE$*6N(qs#z@8=kXaFi8B2PgdhNo6P zFVx|$*Wq)(mxA$+%^ptJIW{m*a1zPg1IeM?1DQm2n5D95mLAVKEG^H@>e0yt zsk^~qrg~_yd?A_00l=dVI?NVElN&Y+jAaNXhezQoP1w7}n&oul&wAXB%i#G1e%7L_ zAO~Dt{FWp)iR=DriKD*(kM!?Scu3&}+!@De>I-%3RmM9RQgfld063UJTEK#U{%I{ zOyl>#JCu_O#~haar-@_y>bUnK0Kxgmph!tn>V>}N>fYMgh04+{2==Y#a$33U|YYJLg`1*Ri**-b#6 z1Cn#%^30L^cH)>bD3bShCNoJ(j^{VZDo<7Xd&!m`tn|N|INl#9lJ|KgYbP!FJ!J3H zxSZFJ#_uINukn7e$2I-{*%KO1kiB2yDY6e}d>7dVHU1#khcrGywn-ZE3LhzQeqIvNaOPUI<9efPo37dyr)>SuxG?c41#uSPY=nOogPj^o%FcFqN18g zI0+UVEEK>VMFZQwZ&wygj*g6^bKsX7b<$Dzy?Ud#JILOZD@OA++yS<;hq_7+4P@-Z zNSdPh0kI?t$S)Q+~qsFr!08cwS7YSZIAQ3v3(8O_q2tgvAV)*+C zIk^#q-?KFCkqYrDre@y&cCGOv`0;}r#m+%+d>lg`KSoR+e~1=D`h%Mg-M$$p4$;w)EXO`aB`fd!0