Full Code of drkhsh/slstatus for AI

master 614c275b4206 cached
33 files
66.6 KB
21.8k tokens
79 symbols
1 requests
Download .txt
Repository: drkhsh/slstatus
Branch: master
Commit: 614c275b4206
Files: 33
Total size: 66.6 KB

Directory structure:
gitextract_t17m0v2w/

├── LICENSE
├── Makefile
├── README
├── arg.h
├── components/
│   ├── battery.c
│   ├── cat.c
│   ├── cpu.c
│   ├── datetime.c
│   ├── disk.c
│   ├── entropy.c
│   ├── hostname.c
│   ├── ip.c
│   ├── kernel_release.c
│   ├── keyboard_indicators.c
│   ├── keymap.c
│   ├── load_avg.c
│   ├── netspeeds.c
│   ├── num_files.c
│   ├── ram.c
│   ├── run_command.c
│   ├── swap.c
│   ├── temperature.c
│   ├── uptime.c
│   ├── user.c
│   ├── volume.c
│   └── wifi.c
├── config.def.h
├── config.mk
├── slstatus.1
├── slstatus.c
├── slstatus.h
├── util.c
└── util.h

================================================
FILE CONTENTS
================================================

================================================
FILE: LICENSE
================================================
ISC License

Copyright 2016-2026 Aaron Marcher <me@drkhsh.at>

Copyright 2016 Roy Freytag <rfreytag@hs-mittweida.de>
Copyright 2016 Vincent Loupmon <vincentloupmon@gmail.com>
Copyright 2016 Daniel Walter <d.walter@0x90.at>
Copyright 2016-2018 Ali H. Fardan <raiz@firemail.cc>
Copyright 2016 Jody Leonard <me@jodyleonard.com>
Copyright 2016-2018 Quentin Rameau <quinq@fifth.space>
Copyright 2016 Mike Coddington <mike@coddington.us>
Copyright 2016-2018 Ivan J. <parazyd@dyne.org>
Copyright 2017 Tobias Stoeckmann <tobias@stoeckmann.org>
Copyright 2017-2018 Laslo Hunhold <dev@frign.de>
Copyright 2018 Darron Anderson <darronanderson@protonmail.com>
Copyright 2018 Josuah Demangeon <mail@josuah.net>
Copyright 2018 Tobias Tschinkowitz <tobias@he4d.net>
Copyright 2018 David Demelier <markand@malikania.fr>
Copyright 2018-2012 Michael Buch <michaelbuch12@gmail.com>
Copyright 2018 Ian Remmler <ian@remmler.org>
Copyright 2016-2019 Joerg Jung <jung@openbsd.org>
Copyright 2019 Ryan Kes <alrayyes@gmail.com>
Copyright 2019 Cem Keylan <cem@ckyln.com>
Copyright 2019 Spiros Thanasoulas <dsp@2f30.org>
Copyright 2019-2022 Ingo Feinerer <feinerer@logic.at>
Copyright 2020 Alexandre Ratchov <alex@caoua.org>
Copyright 2020 Mart Lubbers <mart@martlubbers.net>
Copyright 2020 Daniel Moch <daniel@danielmoch.com>
Copyright 2022 Nickolas Raymond Kaczynski <nrk@disroot.org>
Copyright 2022 Patrick Iacob <iacobp@oregonstate.edu>
Copyright 2021-2022 Steven Ward <planet36@gmail.com>
Copyright 2025 Joakim Sindholt <opensource@zhasha.com>
Copyright 2025 Al <eirann@disroot.org>
Copyright 2025 sewn <sewn@disroot.org>

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.


================================================
FILE: Makefile
================================================
# 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"


================================================
FILE: README
================================================
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), interface status
- 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.


================================================
FILE: arg.h
================================================
/* 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


================================================
FILE: components/battery.c
================================================
/* See LICENSE file for copyright and license details. */
#include <stdio.h>
#include <string.h>

#include "../slstatus.h"
#include "../util.h"

#if defined(__linux__)
/*
 * https://www.kernel.org/doc/html/latest/power/power_supply_class.html
 */
	#include <limits.h>
	#include <stdint.h>
	#include <unistd.h>

	#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[13];

		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[13];

		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", &current_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 <fcntl.h>
	#include <machine/apmvar.h>
	#include <sys/ioctl.h>
	#include <unistd.h>

	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 <sys/sysctl.h>

	#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


================================================
FILE: components/cat.c
================================================
/* See LICENSE file for copyright and license details. */
#include <stdio.h>
#include <string.h>

#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;
}



================================================
FILE: components/cpu.c
================================================
/* See LICENSE file for copyright and license details. */
#include <stdint.h>
#include <stdio.h>
#include <string.h>

#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 <sys/param.h>
	#include <sys/sched.h>
	#include <sys/sysctl.h>

	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 <devstat.h>
	#include <sys/param.h>
	#include <sys/sysctl.h>

	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


================================================
FILE: components/datetime.c
================================================
/* See LICENSE file for copyright and license details. */
#include <stdio.h>
#include <time.h>

#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;
}


================================================
FILE: components/disk.c
================================================
/* See LICENSE file for copyright and license details. */
#include <stdio.h>
#include <sys/statvfs.h>

#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);
}


================================================
FILE: components/entropy.c
================================================
/* See LICENSE file for copyright and license details. */
#include "../slstatus.h"
#if defined(__linux__)
	#include <stdint.h>
	#include <stdio.h>

	#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


================================================
FILE: components/hostname.c
================================================
/* See LICENSE file for copyright and license details. */
#include <stdio.h>
#include <unistd.h>

#include "../slstatus.h"
#include "../util.h"

const char *
hostname(const char *unused)
{
	if (gethostname(buf, sizeof(buf)) < 0) {
		warn("gethostbyname:");
		return NULL;
	}

	return buf;
}


================================================
FILE: components/ip.c
================================================
/* See LICENSE file for copyright and license details. */
#include <ifaddrs.h>
#include <netdb.h>
#include <net/if.h>
#include <stdio.h>
#include <string.h>
#if defined(__OpenBSD__)
	#include <sys/socket.h>
	#include <sys/types.h>
#elif defined(__FreeBSD__)
	#include <netinet/in.h>
	#include <sys/socket.h>
#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);
}

const char *
up(const char *interface)
{
	struct ifaddrs *ifaddr, *ifa;

	if (getifaddrs(&ifaddr) < 0) {
		warn("getifaddrs:");
		return NULL;
	}

	for (ifa = ifaddr; ifa != NULL; ifa = ifa->ifa_next) {
		if (!ifa->ifa_addr)
			continue;

		if (!strcmp(ifa->ifa_name, interface)) {
			freeifaddrs(ifaddr);
			return ifa->ifa_flags & IFF_UP ? "up" : "down";
		}
	}

	freeifaddrs(ifaddr);

	return NULL;
}


================================================
FILE: components/kernel_release.c
================================================
/* See LICENSE file for copyright and license details. */
#include <stdio.h>
#include <sys/utsname.h>

#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);
}


================================================
FILE: components/keyboard_indicators.c
================================================
/* See LICENSE file for copyright and license details. */
#include <ctype.h>
#include <stdio.h>
#include <string.h>
#include <X11/Xlib.h>

#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;
}


================================================
FILE: components/keymap.c
================================================
/* See LICENSE file for copyright and license details. */
#include <ctype.h>
#include <stdlib.h>
#include <string.h>
#include <X11/XKBlib.h>
#include <X11/Xlib.h>

#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;
}


================================================
FILE: components/load_avg.c
================================================
/* See LICENSE file for copyright and license details. */
#include <stdio.h>
#include <stdlib.h>

#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]);
}


================================================
FILE: components/netspeeds.c
================================================
/* See LICENSE file for copyright and license details. */
#include <limits.h>
#include <stdio.h>

#include "../slstatus.h"
#include "../util.h"

#if defined(__linux__)
	#include <stdint.h>

	#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 <ifaddrs.h>
	#include <net/if.h>
	#include <string.h>
	#include <sys/types.h>
	#include <sys/socket.h>

	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


================================================
FILE: components/num_files.c
================================================
/* See LICENSE file for copyright and license details. */
#include <dirent.h>
#include <stdio.h>
#include <string.h>

#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);
}


================================================
FILE: components/ram.c
================================================
/* See LICENSE file for copyright and license details. */
#include <stdio.h>

#include "../slstatus.h"
#include "../util.h"

#if defined(__linux__)
	#include <stdint.h>

	const char *
	ram_free(const char *unused)
	{
		uintmax_t free;
		FILE *fp;

		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, shmem, sreclaimable;
		int percent;
		FILE *fp;

		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 - sreclaimable + shmem) / 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, shmem, sreclaimable;
		FILE *fp;

		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);

		used = total - free - buffers - cached - sreclaimable + shmem;
		return fmt_human(used * 1024, 1024);
	}
#elif defined(__OpenBSD__)
	#include <stdlib.h>
	#include <sys/sysctl.h>
	#include <sys/types.h>
	#include <unistd.h>

	#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 <sys/sysctl.h>
	#include <sys/vmmeter.h>
	#include <unistd.h>
	#include <vm/vm_param.h>

	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


================================================
FILE: components/run_command.c
================================================
/* See LICENSE file for copyright and license details. */
#include <stdio.h>
#include <string.h>

#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;
}


================================================
FILE: components/swap.c
================================================
/* See LICENSE file for copyright and license details. */
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#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 <stdlib.h>
	#include <sys/swap.h>
	#include <sys/types.h>
	#include <unistd.h>

	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 <fcntl.h>
	#include <kvm.h>
	#include <stdlib.h>
	#include <sys/types.h>
	#include <unistd.h>

	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


================================================
FILE: components/temperature.c
================================================
/* See LICENSE file for copyright and license details. */
#include <stddef.h>

#include "../slstatus.h"
#include "../util.h"


#if defined(__linux__)
	#include <stdint.h>

	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 <stdio.h>
	#include <sys/time.h> /* before <sys/sensors.h> for struct timeval */
	#include <sys/sensors.h>
	#include <sys/sysctl.h>

	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 <stdio.h>
	#include <stdlib.h>
	#include <sys/sysctl.h>

	#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


================================================
FILE: components/uptime.c
================================================
/* See LICENSE file for copyright and license details. */
#include <stdint.h>
#include <stdio.h>
#include <time.h>

#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);
}


================================================
FILE: components/user.c
================================================
/* See LICENSE file for copyright and license details. */
#include <pwd.h>
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>

#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());
}


================================================
FILE: components/volume.c
================================================
/* See LICENSE file for copyright and license details. */
#include <fcntl.h>
#include <stdio.h>
#include <string.h>
#include <sys/ioctl.h>
#include <unistd.h>

#include "../slstatus.h"
#include "../util.h"

#if defined(__OpenBSD__) | defined(__FreeBSD__)
	#include <poll.h>
	#include <sndio.h>
	#include <stdlib.h>
	#include <sys/queue.h>

	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;
		}
		if (c == NULL)
			return;
		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 <sys/soundcard.h>

	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


================================================
FILE: components/wifi.c
================================================
/* See LICENSE file for copyright and license details. */
#include <ifaddrs.h>
#include <stdio.h>
#include <string.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
#include <unistd.h>

#include "../slstatus.h"
#include "../util.h"

#define RSSI_TO_PERC(rssi) \
			rssi >= -50 ? 100 : \
			(rssi <= -100 ? 0 : \
			(2 * (rssi + 100)))

#if defined(__linux__)
	#include <stdint.h>
	#include <net/if.h>
	#include <linux/netlink.h>
	#include <linux/genetlink.h>
	#include <linux/nl80211.h>

	static int nlsock = -1;
	static uint32_t seq = 1;
	static char resp[4096];

	static char *
	findattr(int attr, const char *p, const char *e, size_t *len)
	{
		while (p < e) {
			struct nlattr nla;
			memcpy(&nla, p, sizeof(nla));
			if (nla.nla_type == attr) {
				*len = nla.nla_len - NLA_HDRLEN;
				return (char *)(p + NLA_HDRLEN);
			}
			p += NLA_ALIGN(nla.nla_len);
		}
		return NULL;
	}

	static uint16_t
	nl80211fam(void)
	{
		static const char family[] = "nl80211";
		static uint16_t id;
		ssize_t r;
		size_t len;
		char ctrl[NLMSG_HDRLEN+GENL_HDRLEN+NLA_HDRLEN+NLA_ALIGN(sizeof(family))] = {0}, *p = ctrl;

		if (id)
			return id;

		memcpy(p, &(struct nlmsghdr){
			.nlmsg_len = sizeof(ctrl),
			.nlmsg_type = GENL_ID_CTRL,
			.nlmsg_flags = NLM_F_REQUEST,
			.nlmsg_seq = seq++,
			.nlmsg_pid = 0,
		}, sizeof(struct nlmsghdr));
		p += NLMSG_HDRLEN;
		memcpy(p, &(struct genlmsghdr){
			.cmd = CTRL_CMD_GETFAMILY,
			.version = 1,
		}, sizeof(struct genlmsghdr));
		p += GENL_HDRLEN;
		memcpy(p, &(struct nlattr){
			.nla_len = NLA_HDRLEN+sizeof(family),
			.nla_type = CTRL_ATTR_FAMILY_NAME,
		}, sizeof(struct nlattr));
		p += NLA_HDRLEN;
		memcpy(p, family, sizeof(family));

		if (nlsock < 0)
			nlsock = socket(AF_NETLINK, SOCK_RAW, NETLINK_GENERIC);
		if (nlsock < 0) {
			warn("socket 'AF_NETLINK':");
			return 0;
		}
		if (send(nlsock, ctrl, sizeof(ctrl), 0) != sizeof(ctrl)) {
			warn("send 'AF_NETLINK':");
			return 0;
		}
		r = recv(nlsock, resp, sizeof(resp), 0);
		if (r < 0) {
			warn("recv 'AF_NETLINK':");
			return 0;
		}
		if ((size_t)r <= sizeof(ctrl))
			return 0;
		p = findattr(CTRL_ATTR_FAMILY_ID, resp + sizeof(ctrl), resp + r, &len);
		if (p && len == 2)
			memcpy(&id, p, 2);

		return id;
	}

	static int
	ifindex(const char *interface)
	{
		static struct ifreq ifr;
		static int ifsock = -1;

		if (ifsock < 0)
			ifsock = socket(AF_UNIX, SOCK_DGRAM, 0);
		if (ifsock < 0) {
			warn("socket 'AF_UNIX':");
			return -1;
		}
		if (strcmp(ifr.ifr_name, interface) != 0) {
			strcpy(ifr.ifr_name, interface);
		}
		if (ioctl(ifsock, SIOCGIFINDEX, &ifr) != 0) {
			warn("ioctl 'SIOCGIFINDEX':");
			return -1;
		}
		return ifr.ifr_ifindex;
	}

	const char *
	wifi_essid(const char *interface)
	{
		uint16_t fam = nl80211fam();
		ssize_t r;
		size_t len;
		char req[NLMSG_HDRLEN+GENL_HDRLEN+NLA_HDRLEN+NLA_ALIGN(4)] = {0}, *p = req;
		int idx = ifindex(interface);
		if (!fam) {
			fprintf(stderr, "nl80211 family not found\n");
			return NULL;
		}
		if (idx < 0) {
			fprintf(stderr, "interface %s not found\n", interface);
			return NULL;
		}

		memcpy(p, &(struct nlmsghdr){
			.nlmsg_len = sizeof(req),
			.nlmsg_type = fam,
			.nlmsg_flags = NLM_F_REQUEST,
			.nlmsg_seq = seq++,
			.nlmsg_pid = 0,
		}, sizeof(struct nlmsghdr));
		p += NLMSG_HDRLEN;
		memcpy(p, &(struct genlmsghdr){
			.cmd = NL80211_CMD_GET_INTERFACE,
			.version = 1,
		}, sizeof(struct genlmsghdr));
		p += GENL_HDRLEN;
		memcpy(p, &(struct nlattr){
			.nla_len = NLA_HDRLEN+4,
			.nla_type = NL80211_ATTR_IFINDEX,
		}, sizeof(struct nlattr));
		p += NLA_HDRLEN;
		memcpy(p, &(uint32_t){idx}, 4);

		if (send(nlsock, req, sizeof(req), 0) != sizeof(req)) {
			warn("send 'AF_NETLINK':");
			return NULL;
		}
		r = recv(nlsock, resp, sizeof(resp), 0);
		if (r < 0) {
			warn("recv 'AF_NETLINK':");
			return NULL;
		}

		if ((size_t)r <= NLMSG_HDRLEN + GENL_HDRLEN)
			return NULL;
		p = findattr(NL80211_ATTR_SSID, resp + NLMSG_HDRLEN + GENL_HDRLEN, resp + r, &len);
		if (p)
			p[len] = 0;

		return p;
	}

	const char *
	wifi_perc(const char *interface)
	{
		static char strength[4];
		struct nlmsghdr hdr;
		uint16_t fam = nl80211fam();
		ssize_t r;
		size_t len;
		char req[NLMSG_HDRLEN + GENL_HDRLEN + NLA_HDRLEN + NLA_ALIGN(4)] = {0}, *p = req, *e;
		int idx = ifindex(interface);

		if (idx < 0) {
			fprintf(stderr, "interface %s not found\n", interface);
			return NULL;
		}

		memcpy(p, &(struct nlmsghdr){
			.nlmsg_len = sizeof(req),
			.nlmsg_type = fam,
			.nlmsg_flags = NLM_F_REQUEST|NLM_F_DUMP,
			.nlmsg_seq = seq++,
			.nlmsg_pid = 0,
		}, sizeof(struct nlmsghdr));
		p += NLMSG_HDRLEN;
		memcpy(p, &(struct genlmsghdr){
			.cmd = NL80211_CMD_GET_STATION,
			.version = 1,
		}, sizeof(struct genlmsghdr));
		p += GENL_HDRLEN;
		memcpy(p, &(struct nlattr){
			.nla_len = NLA_HDRLEN + 4,
			.nla_type = NL80211_ATTR_IFINDEX,
		}, sizeof(struct nlattr));
		p += NLA_HDRLEN;
		memcpy(p, &idx, 4);

		if (send(nlsock, req, sizeof(req), 0) != sizeof(req)) {
			warn("send 'AF_NETLINK':");
			return NULL;
		}

		*strength = 0;
		while (1) {
			r = recv(nlsock, resp, sizeof(resp), 0);
			if (r < 0) {
				warn("recv 'AF_NETLINK':");
				return NULL;
			}
			if ((size_t)r < sizeof(hdr))
				return NULL;

			for (p = resp; p != resp + r && (size_t)(resp + r-p) >= sizeof(hdr); p = e) {
				memcpy(&hdr, p, sizeof(hdr));
				e = resp + r - p < hdr.nlmsg_len ? resp + r : p + hdr.nlmsg_len;

				if (!*strength && hdr.nlmsg_len > NLMSG_HDRLEN+GENL_HDRLEN) {
					p += NLMSG_HDRLEN+GENL_HDRLEN;
					p = findattr(NL80211_ATTR_STA_INFO, p, e, &len);
					if (p)
						p = findattr(NL80211_STA_INFO_SIGNAL_AVG, p, e, &len);
					if (p && len == 1)
						snprintf(strength, sizeof(strength), "%d", RSSI_TO_PERC(*p));
				}
				if (hdr.nlmsg_type == NLMSG_DONE)
					return *strength ? strength : NULL;
			}
		}
	}
#elif defined(__OpenBSD__)
	#include <net/if.h>
	#include <net/if_media.h>
	#include <net80211/ieee80211.h>
	#include <sys/select.h> /* before <sys/ieee80211_ioctl.h> for NBBY */
	#include <net80211/ieee80211_ioctl.h>
	#include <stdlib.h>
	#include <sys/types.h>

	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 <net/if.h>
	#include <net80211/ieee80211_ioctl.h>

	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


================================================
FILE: config.def.h
================================================
/* 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 */
	{ datetime, "%s",           "%F %T" },
};


================================================
FILE: config.mk
================================================
# slstatus version
VERSION = 1.1

# customize below to fit your system

# paths
PREFIX = /usr/local
MANPREFIX = $(PREFIX)/share/man

X11INC = /usr/X11R6/include
X11LIB = /usr/X11R6/lib

# flags
CPPFLAGS = -I$(X11INC) -D_DEFAULT_SOURCE -DVERSION=\"${VERSION}\"
CFLAGS   = -std=c99 -pedantic -Wall -Wextra -Wno-unused-parameter -Os
LDFLAGS  = -L$(X11LIB) -s
# OpenBSD: add -lsndio
# FreeBSD: add -lkvm -lsndio
LDLIBS   = -lX11

# compiler and linker
CC = cc


================================================
FILE: slstatus.1
================================================
.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


================================================
FILE: slstatus.c
================================================
/* See LICENSE file for copyright and license details. */
#include <errno.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <X11/Xlib.h>

#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);
		break;
	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, &current) < 0)
				die("clock_gettime:");
			difftimespec(&diff, &current, &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;
}


================================================
FILE: slstatus.h
================================================
/* 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);
const char *up(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);


================================================
FILE: util.c
================================================
/* See LICENSE file for copyright and license details. */
#include <errno.h>
#include <stdarg.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#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;
}

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;
}


================================================
FILE: util.h
================================================
/* See LICENSE file for copyright and license details. */
#include <stdint.h>
#include <stdio.h>

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, ...);
int lscanf(FILE *fp, const char *key, const char *fmt, void *res);
Download .txt
gitextract_t17m0v2w/

├── LICENSE
├── Makefile
├── README
├── arg.h
├── components/
│   ├── battery.c
│   ├── cat.c
│   ├── cpu.c
│   ├── datetime.c
│   ├── disk.c
│   ├── entropy.c
│   ├── hostname.c
│   ├── ip.c
│   ├── kernel_release.c
│   ├── keyboard_indicators.c
│   ├── keymap.c
│   ├── load_avg.c
│   ├── netspeeds.c
│   ├── num_files.c
│   ├── ram.c
│   ├── run_command.c
│   ├── swap.c
│   ├── temperature.c
│   ├── uptime.c
│   ├── user.c
│   ├── volume.c
│   └── wifi.c
├── config.def.h
├── config.mk
├── slstatus.1
├── slstatus.c
├── slstatus.h
├── util.c
└── util.h
Download .txt
SYMBOL INDEX (79 symbols across 17 files)

FILE: components/battery.c
  function load_apm_power_info (line 120) | static int
  type apm_power_info (line 143) | struct apm_power_info
  type apm_power_info (line 161) | struct apm_power_info
  type apm_power_info (line 178) | struct apm_power_info

FILE: components/disk.c
  type statvfs (line 11) | struct statvfs
  type statvfs (line 24) | struct statvfs
  type statvfs (line 38) | struct statvfs
  type statvfs (line 51) | struct statvfs

FILE: components/ip.c
  type ifaddrs (line 21) | struct ifaddrs
  type sockaddr_in6 (line 34) | struct sockaddr_in6
  type ifaddrs (line 67) | struct ifaddrs

FILE: components/kernel_release.c
  type utsname (line 11) | struct utsname

FILE: components/keymap.c
  function valid_layout_or_variant (line 11) | static int

FILE: components/netspeeds.c
  type ifaddrs (line 65) | struct ifaddrs
  type if_data (line 66) | struct if_data
  type if_data (line 81) | struct if_data
  type ifaddrs (line 99) | struct ifaddrs
  type if_data (line 100) | struct if_data
  type if_data (line 115) | struct if_data

FILE: components/num_files.c
  type dirent (line 12) | struct dirent

FILE: components/ram.c
  function load_uvmexp (line 100) | inline int
  type uvmexp (line 117) | struct uvmexp
  type uvmexp (line 131) | struct uvmexp
  type uvmexp (line 144) | struct uvmexp
  type uvmexp (line 156) | struct uvmexp
  type vmtotal (line 172) | struct vmtotal
  type vmtotal (line 176) | struct vmtotal

FILE: components/swap.c
  function get_swap_info (line 11) | static int
  function getstats (line 108) | static int
  function getswapinfo (line 197) | static int getswapinfo(struct kvm_swap *swap_info, size_t size)
  type kvm_swap (line 220) | struct kvm_swap
  type kvm_swap (line 235) | struct kvm_swap
  type kvm_swap (line 250) | struct kvm_swap
  type kvm_swap (line 264) | struct kvm_swap

FILE: components/temperature.c
  type sensor (line 32) | struct sensor

FILE: components/uptime.c
  type timespec (line 22) | struct timespec

FILE: components/user.c
  type passwd (line 19) | struct passwd

FILE: components/volume.c
  type control (line 17) | struct control {
  type pollfd (line 29) | struct pollfd
  type sioctl_hdl (line 30) | struct sioctl_hdl
  function ondesc (line 36) | static void
  function onval (line 83) | static void
  function cleanup (line 97) | static void
  function init (line 117) | static int
  type control (line 151) | struct control

FILE: components/wifi.c
  type nlattr (line 32) | struct nlattr
  function nl80211fam (line 43) | static uint16_t
  function ifindex (line 99) | static int
  type nlmsghdr (line 138) | struct nlmsghdr
  type nlmsghdr (line 144) | struct nlmsghdr
  type genlmsghdr (line 146) | struct genlmsghdr
  type genlmsghdr (line 149) | struct genlmsghdr
  type nlattr (line 151) | struct nlattr
  type nlattr (line 154) | struct nlattr
  type nlmsghdr (line 181) | struct nlmsghdr
  type nlmsghdr (line 193) | struct nlmsghdr
  type nlmsghdr (line 199) | struct nlmsghdr
  type genlmsghdr (line 201) | struct genlmsghdr
  type genlmsghdr (line 204) | struct genlmsghdr
  type nlattr (line 206) | struct nlattr
  type nlattr (line 209) | struct nlattr
  function load_ieee80211_nodereq (line 254) | static int
  type ieee80211_nodereq (line 293) | struct ieee80211_nodereq
  type ieee80211_nodereq (line 311) | struct ieee80211_nodereq
  function load_ieee80211req (line 322) | int
  type ieee80211req_sta_req (line 348) | struct ieee80211req_sta_req

FILE: config.def.h
  type arg (line 67) | struct arg

FILE: slstatus.c
  type arg (line 14) | struct arg {
  function terminate (line 26) | static void
  function difftimespec (line 33) | static void
  function usage (line 41) | static void
  function main (line 47) | int

FILE: util.c
  function verr (line 13) | static void
  function warn (line 26) | void
  function die (line 36) | void
  function evsnprintf (line 48) | static int
  function esnprintf (line 66) | int
  function pscanf (line 124) | int
  function lscanf (line 143) | int
Condensed preview — 33 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (77K chars).
[
  {
    "path": "LICENSE",
    "chars": 2298,
    "preview": "ISC License\n\nCopyright 2016-2026 Aaron Marcher <me@drkhsh.at>\n\nCopyright 2016 Roy Freytag <rfreytag@hs-mittweida.de>\nCop"
  },
  {
    "path": "Makefile",
    "chars": 1773,
    "preview": "# See LICENSE file for copyright and license details\n# slstatus - suckless status monitor\n.POSIX:\n\ninclude config.mk\n\nRE"
  },
  {
    "path": "README",
    "chars": 1762,
    "preview": "slstatus - suckless status\n==========================\nslstatus is a small tool for providing system status information t"
  },
  {
    "path": "arg.h",
    "chars": 1684,
    "preview": "/* See LICENSE file for copyright and license details. */\n#ifndef ARG_H\n#define ARG_H\n\nextern char *argv0;\n\n/* int main("
  },
  {
    "path": "components/battery.c",
    "chars": 5232,
    "preview": "/* See LICENSE file for copyright and license details. */\n#include <stdio.h>\n#include <string.h>\n\n#include \"../slstatus."
  },
  {
    "path": "components/cat.c",
    "chars": 652,
    "preview": "/* See LICENSE file for copyright and license details. */\n#include <stdio.h>\n#include <string.h>\n\n#include \"../slstatus."
  },
  {
    "path": "components/cpu.c",
    "chars": 3434,
    "preview": "/* See LICENSE file for copyright and license details. */\n#include <stdint.h>\n#include <stdio.h>\n#include <string.h>\n\n#i"
  },
  {
    "path": "components/datetime.c",
    "chars": 358,
    "preview": "/* See LICENSE file for copyright and license details. */\n#include <stdio.h>\n#include <time.h>\n\n#include \"../slstatus.h\""
  },
  {
    "path": "components/disk.c",
    "chars": 1016,
    "preview": "/* See LICENSE file for copyright and license details. */\n#include <stdio.h>\n#include <sys/statvfs.h>\n\n#include \"../slst"
  },
  {
    "path": "components/entropy.c",
    "chars": 617,
    "preview": "/* See LICENSE file for copyright and license details. */\n#include \"../slstatus.h\"\n#if defined(__linux__)\n\t#include <std"
  },
  {
    "path": "components/hostname.c",
    "chars": 291,
    "preview": "/* See LICENSE file for copyright and license details. */\n#include <stdio.h>\n#include <unistd.h>\n\n#include \"../slstatus."
  },
  {
    "path": "components/ip.c",
    "chars": 1632,
    "preview": "/* See LICENSE file for copyright and license details. */\n#include <ifaddrs.h>\n#include <netdb.h>\n#include <net/if.h>\n#i"
  },
  {
    "path": "components/kernel_release.c",
    "chars": 327,
    "preview": "/* See LICENSE file for copyright and license details. */\n#include <stdio.h>\n#include <sys/utsname.h>\n\n#include \"../slst"
  },
  {
    "path": "components/keyboard_indicators.c",
    "chars": 1238,
    "preview": "/* See LICENSE file for copyright and license details. */\n#include <ctype.h>\n#include <stdio.h>\n#include <string.h>\n#inc"
  },
  {
    "path": "components/keymap.c",
    "chars": 1869,
    "preview": "/* See LICENSE file for copyright and license details. */\n#include <ctype.h>\n#include <stdlib.h>\n#include <string.h>\n#in"
  },
  {
    "path": "components/load_avg.c",
    "chars": 375,
    "preview": "/* See LICENSE file for copyright and license details. */\n#include <stdio.h>\n#include <stdlib.h>\n\n#include \"../slstatus."
  },
  {
    "path": "components/netspeeds.c",
    "chars": 2890,
    "preview": "/* See LICENSE file for copyright and license details. */\n#include <limits.h>\n#include <stdio.h>\n\n#include \"../slstatus."
  },
  {
    "path": "components/num_files.c",
    "chars": 534,
    "preview": "/* See LICENSE file for copyright and license details. */\n#include <dirent.h>\n#include <stdio.h>\n#include <string.h>\n\n#i"
  },
  {
    "path": "components/ram.c",
    "chars": 4859,
    "preview": "/* See LICENSE file for copyright and license details. */\n#include <stdio.h>\n\n#include \"../slstatus.h\"\n#include \"../util"
  },
  {
    "path": "components/run_command.c",
    "chars": 501,
    "preview": "/* See LICENSE file for copyright and license details. */\n#include <stdio.h>\n#include <string.h>\n\n#include \"../slstatus."
  },
  {
    "path": "components/swap.c",
    "chars": 5044,
    "preview": "/* See LICENSE file for copyright and license details. */\n#include <stdint.h>\n#include <stdio.h>\n#include <stdlib.h>\n#in"
  },
  {
    "path": "components/temperature.c",
    "chars": 1436,
    "preview": "/* See LICENSE file for copyright and license details. */\n#include <stddef.h>\n\n#include \"../slstatus.h\"\n#include \"../uti"
  },
  {
    "path": "components/uptime.c",
    "chars": 702,
    "preview": "/* See LICENSE file for copyright and license details. */\n#include <stdint.h>\n#include <stdio.h>\n#include <time.h>\n\n#inc"
  },
  {
    "path": "components/user.c",
    "chars": 531,
    "preview": "/* See LICENSE file for copyright and license details. */\n#include <pwd.h>\n#include <stdio.h>\n#include <sys/types.h>\n#in"
  },
  {
    "path": "components/volume.c",
    "chars": 4347,
    "preview": "/* See LICENSE file for copyright and license details. */\n#include <fcntl.h>\n#include <stdio.h>\n#include <string.h>\n#inc"
  },
  {
    "path": "components/wifi.c",
    "chars": 9668,
    "preview": "/* See LICENSE file for copyright and license details. */\n#include <ifaddrs.h>\n#include <stdio.h>\n#include <string.h>\n#i"
  },
  {
    "path": "config.def.h",
    "chars": 3991,
    "preview": "/* See LICENSE file for copyright and license details. */\n\n/* interval between updates (in ms) */\nconst unsigned int int"
  },
  {
    "path": "config.mk",
    "chars": 456,
    "preview": "# slstatus version\nVERSION = 1.1\n\n# customize below to fit your system\n\n# paths\nPREFIX = /usr/local\nMANPREFIX = $(PREFIX"
  },
  {
    "path": "slstatus.1",
    "chars": 965,
    "preview": ".Dd 2023-04-23\n.Dt SLSTATUS 1\n.Os\n.Sh NAME\n.Nm slstatus\n.Nd suckless status\n.Sh SYNOPSIS\n.Nm\n.Op Fl s\n.Op Fl 1\n.Sh DESCR"
  },
  {
    "path": "slstatus.c",
    "chars": 2643,
    "preview": "/* See LICENSE file for copyright and license details. */\n#include <errno.h>\n#include <signal.h>\n#include <stdio.h>\n#inc"
  },
  {
    "path": "slstatus.h",
    "chars": 2065,
    "preview": "/* See LICENSE file for copyright and license details. */\n\n/* battery */\nconst char *battery_perc(const char *);\nconst c"
  },
  {
    "path": "util.c",
    "chars": 2539,
    "preview": "/* See LICENSE file for copyright and license details. */\n#include <errno.h>\n#include <stdarg.h>\n#include <stdint.h>\n#in"
  },
  {
    "path": "util.h",
    "chars": 519,
    "preview": "/* See LICENSE file for copyright and license details. */\n#include <stdint.h>\n#include <stdio.h>\n\nextern char buf[1024];"
  }
]

About this extraction

This page contains the full source code of the drkhsh/slstatus GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 33 files (66.6 KB), approximately 21.8k tokens, and a symbol index with 79 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.

Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.

Copied to clipboard!