commit - 0c5cb071191e1ef383a3460f0ffd8356692e4913
commit + 1157627b862a560c1fc5bc7187ec0b77bd75d146
blob - 5d2fc8e15b42e88ca7161f818e2d0e78ac4758e2
blob + 6efe31da62cbed8fe0aed6abb85dd8e3df8ccf02
--- Makefile
+++ Makefile
LDFLAGS =
LDLIBS = $(shell pkg-config --libs xft x11)
-all: bxbar bxinfo
+all: bxbar bxinfo bxnet
bxbar: bxbar.o
$(CC) $(LDFLAGS) -o $@ bxbar.o $(LDLIBS)
bxinfo: bxinfo.o
$(CC) -o $@ bxinfo.o -lX11
+bxnet: bxnet.o
+ $(CC) -o $@ bxnet.o -lX11
+
clean:
rm -f bxbar bxbar.o
rm -f bxinfo bxinfo.o
+ rm -f bxnet bxnet.o
install:
install -d $(DESTDIR)$(PREFIX)/bin
install -m 755 bxbar $(DESTDIR)$(PREFIX)/bin/bxbar
install -m 755 bxinfo $(DESTDIR)$(PREFIX)/bin/bxinfo
+ install -m 755 bxnet $(DESTDIR)$(PREFIX)/bin/bxnet
install -m 755 bxbarrc.lua $(DESTDIR)$(PREFIX)/bin/bxbarrc.lua
uninstall:
rm -f $(DESTDIR)$(PREFIX)/bin/bxbar
rm -f $(DESTDIR)$(PREFIX)/bin/bxinfo
+ rm -f $(DESTDIR)$(PREFIX)/bin/bxnet
rm -f $(DESTDIR)$(PREFIX)/bin/bxbarrc.lua
.PHONY: all clean install uninstall
blob - 8fa6c143e0075ca003d757ad1ba6f17179818ac2
blob + 2f76ebb2abc7bd4924b30f1350d2cd0a8d5396e9
--- bxbarrc.lua
+++ bxbarrc.lua
return "[" .. bar .. "] " .. cap .. "%" .. charging
end
+local function get_network()
+ local h = io.popen("bxnet", "r")
+ if not h then return "--/--" end
+ local status = h:read("*l")
+ h:close()
+ return status or "--/--"
+end
+
-- Discover battery path once at startup
local bat_path = find_battery_path()
local ws, title = get_x11_info()
local dt = os.date("%Y-%m-%d %a %H:%M")
local bat = bat_path and get_battery(bat_path) or ""
+ local net = get_network()
local left = ws .. " " .. title
- local right = bat .. " " .. dt
+ local right = net .. " " .. bat .. " " .. dt
io.write(left .. string.char(1) .. right .. "\n")
io.flush()
blob - 7d3a78ec662265c9b3363c03bbc80f79e8b96c43
blob + 9ca29e1d98c28da7af66269bdd54a7f44f0d19d2
--- config.def.h
+++ config.def.h
#define BG_COLOR "#000000"
#define FONT "monospace:size=14"
#define DELIMITER '\x01'
+#define IFNAMSIZ 16
+/* Network Status Icons */
+#define NET_ETH_ICON "[---]"
+#define NET_WLAN_ICON "<--->"
+#define NET_NONE_ICON "--/--"
#define DEBUG_LOGGING 0
blob - /dev/null
blob + 1c4718aba2d64e731392d48fd0990b30ab9f47f7 (mode 644)
--- /dev/null
+++ bxnet.c
+/*
+ * bxnet - A basic X network helper
+ * Queries /sys/class/net/ and prints the active interface status to stdout.
+ * See LICENSE.md and README.md for details.
+ */
+
+#define _POSIX_C_SOURCE 200809L
+
+#include <stdio.h>
+#include <string.h>
+#include <dirent.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+
+#include "config.h"
+
+#define SYS_NET_PATH "/sys/class/net"
+
+static int is_dir(const char *path);
+
+/* Read a file and trim the trailing newline.
+ * Returns 1 on success, 0 on failure. */
+static int
+read_sys_file(const char *path, char *buf, size_t buflen)
+{
+ FILE *f = fopen(path, "r");
+ if (!f) return 0;
+
+ if (!fgets(buf, buflen, f)) {
+ fclose(f);
+ return 0;
+ }
+ fclose(f);
+
+ /* Strip trailing whitespace/newline */
+ buf[strcspn(buf, "\r\n")] = '\0';
+ return 1;
+}
+
+/* Check the operstate of an interface.
+ * Returns 1 if "up", 0 otherwise. */
+static int
+is_iface_up(const char *iface)
+{
+ char path[256], state[16];
+ snprintf(path, sizeof(path), "%s/%s/operstate", SYS_NET_PATH, iface);
+ if (!read_sys_file(path, state, sizeof(state)))
+ return 0;
+ return strcmp(state, "up") == 0;
+}
+
+/* Check if a path is a directory.
+ * Returns 1 if directory, 0 otherwise. */
+static int
+is_dir(const char *path)
+{
+ struct stat st;
+ if (stat(path, &st) != 0)
+ return 0;
+ return S_ISDIR(st.st_mode);
+}
+
+int
+main(void)
+{
+ DIR *d = opendir(SYS_NET_PATH);
+ if (!d) {
+ /* If we can't even read /sys, just return the down state */
+ puts(NET_NONE_ICON);
+ return 1;
+ }
+
+ struct dirent *de;
+ int found_eth = 0, found_wlan = 0;
+
+ while ((de = readdir(d)) != NULL) {
+ if (de->d_name[0] == '.' || strcmp(de->d_name, "lo") == 0)
+ continue;
+
+ if (!is_iface_up(de->d_name))
+ continue;
+
+ /* Check for wireless/ subdirectory — kernel-level indicator of WiFi */
+ char wireless_path[64];
+ int iface_len = strnlen(de->d_name, IFNAMSIZ);
+ snprintf(wireless_path, sizeof(wireless_path),
+ "%s/%.*s/wireless", SYS_NET_PATH, iface_len, de->d_name);
+ if (is_dir(wireless_path)) {
+ found_wlan = 1;
+ } else {
+ /* Assume Ethernet for other "up" interfaces */
+ found_eth = 1;
+ }
+ }
+ closedir(d);
+
+ if (found_eth) puts(NET_ETH_ICON);
+ else if (found_wlan) puts(NET_WLAN_ICON);
+ else puts(NET_NONE_ICON);
+
+ return 0;
+}
+