-audstatus/*
-bitmaps/*
-*.log
-*.o
-sysstatus
+/audstatus
+/bitmaps
+/build
+.log
+.o
-CC=gcc
-CCFLAGS=-Wall -Wextra -O3
-LDOUT=sysstatus
-LIBS=-lasound
+PROJ := sysstatus
-sysstatus: *.c *.h Makefile
- make -C statuses
- $(CC) $(CCFLAGS) -o $(LDOUT) $(LIBS) sysstatus.c statuses/*.o
+LIBRARIES := alsa
+BUILDDIR := build
+INCLUDEDIR := include
+SRCDIR := src
+
+EXE := $(BUILDDIR)/$(PROJ)
+HEADERS := $(shell find $(INCLUDEDIR)/ -iname "*.h")
+HEADERS += $(shell find $(SRCDIR)/ -iname "*.h")
+
+INCLUDES := $(patsubst %, -I%, $(INCLUDEDIR) $(SRCDIR))
+CFLAGS := -O3 -Wall -Wextra
+LDFLAGS :=
+
+SOURCES := $(shell find $(SRCDIR)/ -iname "*.c")
+OBJS := $(patsubst %.c, $(BUILDDIR)/%.o, $(SOURCES))
+
+INCLUDES += $(shell pkg-config --cflags-only-I $(LIBRARIES))
+CFLAGS += $(shell pkg-config --cflags-only-other $(LIBRARIES))
+LDFLAGS += $(shell pkg-config --libs $(LIBRARIES))
+
+
+
+.PHONY: default
+default: $(EXE)
+
+
+.PHONY: debug
+debug: $(EXE)
+ gdb $(EXE) $(shell ps -e | sed "s/^ *\([0-9]\+\) .*$(PROJ).*$$/\1/g;te;d;:e")
+
+
+$(EXE): $(OBJS)
+ @if [ ! -d $(BUILDDIR) ] ; then echo "Error: Build dir '$(BUILDDIR)' does not exist." ; false ; fi
+ gcc -o $@ $^ $(LDFLAGS)
+
+
+$(BUILDDIR)/$(SRCDIR)/%.o: $(SRCDIR)/%.c $(HEADERS)
+ @if [ ! -d $(dir $@) ] ; then mkdir -p $(dir $@) ; fi
+ gcc $(INCLUDES) $(CFLAGS) -c -o $@ $<
+
+
+.PHONY: clean
clean:
- make -C statuses clean
- rm -f sysstatus
+ rm -f $(STATICLIB)
+ rm -f $(OBJS)
+ rm -rf $(BUILDDIR)/
+
+
+.PHONY: distclean
+distclean: clean
+ find . -xdev -name "*~" -exec rm {} \;
+ find . -xdev -name "core" -exec rm {} \;
+++ /dev/null
-
-#ifndef __CONFIG_H__
-#define __CONFIG_H__
-
-#define UPDATE_SECS 1
-
-//#define SHOW_SECONDS
-
-#define NUM_CPUS 2
-#define CPU_HISTORY_SIZE 10
-
-#define POWER_BASEDIR "/sys/class/power_supply/"
-#define NETIF_BASEDIR "/sys/class/net/"
-
-#endif
+++ /dev/null
-#!/bin/sh
-
-cd ~/sysstatus/
-make
-
-./runstatus.sh
--- /dev/null
+
+#ifndef __CONFIG_H__
+#define __CONFIG_H__
+
+#define UPDATE_SECS 1
+
+//#define SHOW_SECONDS
+
+#define NUM_CPUS 2
+#define CPU_HISTORY_SIZE 10
+
+#define POWER_BASEDIR "/sys/class/power_supply/"
+#define NETIF_BASEDIR "/sys/class/net/"
+
+#endif
--- /dev/null
+
+#ifndef __BATTERY_H__
+#define __BATTERY_H__
+
+void status_battery(char *batname);
+
+#endif
--- /dev/null
+
+#ifndef __CPUUSAGE_H__
+#define __CPUUSAGE_H__
+
+void status_cpuusage();
+
+#endif
--- /dev/null
+
+#ifndef __DATETIME_H__
+#define __DATETIME_H__
+
+void status_datetime();
+
+#endif
--- /dev/null
+
+#ifndef __FAN_H__
+#define __FAN_H__
+
+void status_fan(char *title, char *sysfile);
+
+#endif
--- /dev/null
+
+#ifndef __MEMUSAGE_H__
+#define __MEMUSAGE_H__
+
+void status_memusage();
+
+#endif
--- /dev/null
+
+#ifndef __NETIF_H__
+#define __NETIF_H__
+
+void status_netif(char *ifname);
+
+#endif
--- /dev/null
+
+#ifndef __TEMP_H__
+#define __TEMP_H__
+
+void status_temp(char *title, char *sysfile);
+
+#endif
--- /dev/null
+
+#ifndef __UPTIME_H__
+#define __UPTIME_H__
+
+void status_uptime();
+
+#endif
--- /dev/null
+
+#ifndef __VOLUME_ALSA_H__
+#define __VOLUME_ALSA_H__
+
+#include <alsa/asoundlib.h>
+
+int status_volume_alsa(char *cardname, char *mixername, snd_mixer_selem_channel_id_t channel);
+
+#endif
--- /dev/null
+
+#ifndef __TOOLS_H__
+#define __TOOLS_H__
+
+char powerToChar(int power);
+void statusError(char *where, char *what, char *extra);
+ssize_t fileRead(char *buf, size_t bufsize, char *file);
+
+#endif
cd ~/sysstatus/
killall sysstatus
-./sysstatus | dzen2 -ta l -fn "$FONT" -bg black -w $((RESX)) -y $((RESY+82)) -h 18 -ta r -expand left -e ""
+./build/sysstatus | dzen2 -ta l -fn "$FONT" -bg black -w $((RESX)) -y $((RESY+82)) -h 18 -ta r -expand left -e ""
#./sysstatus | tee /dev/shm/sysstatus-log | dzen2 -ta l -fn "$FONT" -bg black -y $((RESY+82)) -h 18 -ta r -expand left -e ""
--- /dev/null
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+
+#include "status/battery.h"
+#include "tools.h"
+
+#ifndef POWER_BASEDIR
+ #define POWER_BASEDIR "/sys/class/power_supply/"
+#endif
+
+
+void status_battery(char *batname)
+{
+ char batpath[256];
+ int batpathlen;
+
+ char stline[16];
+ ssize_t stlen;
+
+ int chargeNow = 0;
+ int chargeFull = -1;
+ int chargePercent = -1;
+ int battW = 1;
+ float battTime = -1;
+
+
+ /* Prepare path */
+ batpathlen = sizeof(POWER_BASEDIR) - 1 + strlen(batname);
+ if (batpathlen + 1 + sizeof("/energy_full") >= sizeof(batpath)) {
+ statusError("status_battery",
+ "batpath buffer too small",
+ batname);
+ return;
+ }
+ strcpy(batpath, POWER_BASEDIR);
+ strcat(batpath, batname);
+
+
+ /* Is the battery present? */
+ if (access(batpath, F_OK)) {
+ //printf(" ^fg(grey)[%s] ", batname);
+ return;
+ }
+
+
+ /* Get info */
+ strcpy(&batpath[batpathlen], "/energy_now");
+ stlen = fileRead(stline, sizeof(stline), batpath);
+ if (stlen > 0) {
+ chargeNow = atoi(stline);
+ }
+
+ strcpy(&batpath[batpathlen], "/energy_full");
+ stlen = fileRead(stline, sizeof(stline), batpath);
+ if (stlen > 0) {
+ chargeFull = atoi(stline);
+ }
+
+ strcpy(&batpath[batpathlen], "/power_now");
+ stlen = fileRead(stline, sizeof(stline), batpath);
+ if (stlen > 0) {
+ battW = atoi(stline);
+ }
+
+
+ /* Prettyprint */
+ if (chargeFull > 0) {
+ chargePercent = chargeNow / (chargeFull / 100);
+ }
+
+ if (chargePercent <= 40) {
+ if (chargePercent <= 25) {
+ if (chargePercent <= 10) {
+ fputs("^fg(red)", stdout);
+ } else {
+ // 11-25%
+ fputs("^fg(orange)", stdout);
+ }
+ } else {
+ // 26-40%
+ fputs("^fg(yellow)", stdout);
+ }
+ } else {
+ if (chargePercent > 70) {
+ fputs("^fg(white)", stdout);
+ } else {
+ // 41-70%
+ fputs("^fg(green)", stdout);
+ }
+ }
+
+ battTime = (float)chargeNow / (float)battW;
+
+ if (battW == 0) {
+ // fully charged and not in use
+ printf(" %s: %d%% _ _ ",
+ batname, chargePercent);
+ } else {
+ printf(" %s: %d%% %.1fh %.1fW ",
+ batname, chargePercent, battTime, (float)battW / 1000000.0);
+ }
+}
--- /dev/null
+#include <stdio.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <stdlib.h>
+
+#include "status/cpuusage.h"
+#include "config.h"
+
+#ifndef NUM_CPUS
+ #define NUM_CPUS 1
+#endif
+#ifndef CPU_HISTORY_SIZE
+ #define CPU_HISTORY_SIZE 1
+#endif
+#if CPU_HISTORY_SIZE < 1
+ #define CPU_HISTORY_SIZE 1
+#endif
+
+
+unsigned long last_cpu_used = 0;
+unsigned long last_cpu_total = 0;
+float cpu_history[CPU_HISTORY_SIZE]; // don't care about init values
+
+void status_cpuusage()
+{
+ double loadavg[3] = { -13.37, -13.37, -13.37 } ;
+
+ char *stline = NULL;
+ size_t stlen;
+ FILE *stfile;
+
+ unsigned long cpu_user;
+ unsigned long cpu_nice;
+ unsigned long cpu_sys;
+ unsigned long cpu_used;
+ unsigned long cpu_idle;
+ unsigned long cpu_total;
+ int i;
+
+
+ // Error signaling color
+ fputs("^fg(yellow)", stdout);
+
+ stfile = fopen("/proc/stat", "r");
+ if (stfile != NULL) {
+ for(i = CPU_HISTORY_SIZE - 1; i > 0; i--) {
+ cpu_history[i] = cpu_history[i - 1];
+ }
+
+ stlen = getline(&stline, &stlen, stfile);
+ fclose(stfile);
+
+ if ( 4 == sscanf(stline, "%*s %ld %ld %ld %ld",
+ &cpu_user, &cpu_nice, &cpu_sys, &cpu_idle) ) {
+ cpu_used = cpu_user + cpu_nice + cpu_sys;
+ cpu_total = cpu_used + cpu_idle;
+
+ // Now do the percentage
+ cpu_history[0] = (float)(cpu_used - last_cpu_used) /
+ (float)(cpu_total - last_cpu_total);
+
+ last_cpu_used = cpu_used;
+ last_cpu_total = cpu_total;
+
+
+ if (cpu_history[0] < 0.4) {
+ // CPU idling OK
+ fputs("^fg(#0077FF)", stdout);
+ } else {
+ // CPU busy
+ fputs("^fg(#FF00FF)", stdout);
+ }
+
+ //printf(" CPU: %.0f%% ", cpu_history[0] * 100);
+ }
+
+ free(stline);
+ }
+
+
+ if (getloadavg(loadavg, 3) > 0) {
+ printf(" %s%.0f,%.0f,%.0f,%.0f ",
+ cpu_history[0] < 0.1000 ? " " : "",
+ cpu_history[0] * 100,
+ loadavg[0] * (100 / 1),
+ loadavg[1] * (100 / 1), // (100 / NUM_CPUS)
+ loadavg[2] * (100 / 1));
+ }
+
+ //fputs(" CPU usage ", stdout);
+}
--- /dev/null
+#include <stdio.h>
+#include <time.h>
+
+#include "status/datetime.h"
+#include "config.h"
+
+
+void status_datetime()
+{
+ time_t nows = 0;
+ struct tm *nowtm;
+
+ nows = time(NULL);
+ if (nows == ((time_t) -1)) {
+ printf(" ^fg(red)ERROR: DATETIME");
+ return;
+ }
+
+ nowtm = localtime(&nows);
+
+ printf(" ^fg(#666666)%d.%d.%d ^fg(grey)%d:%.2d"
+ #ifdef SHOW_SECONDS
+ ":%.2d"
+ #endif
+ " "
+ ,nowtm -> tm_mday,
+ (nowtm -> tm_mon) + 1,
+ (nowtm -> tm_year) + 1900,
+ nowtm -> tm_hour,
+ nowtm -> tm_min
+
+ #ifdef SHOW_SECONDS
+ ,nowtm -> tm_sec
+ #endif
+ );
+}
--- /dev/null
+#include <stdio.h>
+#include <fcntl.h>
+#include <unistd.h>
+
+#include "status/fan.h"
+#include "tools.h"
+
+
+void status_fan(char *title, char *sysfile)
+{
+ char stline[16];
+ ssize_t stlen;
+
+ stlen = fileRead(stline, sizeof(stline), sysfile);
+ if (stlen <= 0) {
+ return;
+ }
+
+ // Read a valid value? Sometimes we get garbage from sysfs...
+ if (stlen > 5) {
+ printf(" ^fg(red)%sERROR ", title);
+ return;
+ }
+
+ fputs(" ^fg(#CCCCCC)", stdout);
+ fputs(title, stdout);
+ fwrite(stline, 1, stlen - 1, stdout);
+ fputs(" rpm ", stdout);
+}
--- /dev/null
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "status/memusage.h"
+#include "tools.h"
+
+
+void status_memusage()
+{
+ char *stline = NULL;
+ size_t stlen;
+ FILE *stfile;
+
+ int memtotal = 0;
+ int memfree = 0;
+ int memused;
+ int membuffers = 0;
+ int memcached = 0;
+
+
+ stfile = fopen("/proc/meminfo", "r");
+ if (stfile != NULL) {
+ stlen = getline(&stline, &stlen, stfile);
+ memtotal = atoi(&stline[17]);
+
+ stlen = getline(&stline, &stlen, stfile);
+ memfree = atoi(&stline[17]);
+
+ stlen = getline(&stline, &stlen, stfile);
+ membuffers = atoi(&stline[17]);
+
+ stlen = getline(&stline, &stlen, stfile);
+ memcached = atoi(&stline[17]);
+ free(stline);
+
+ fclose(stfile);
+
+ memused = memtotal - memfree - memcached - membuffers;
+
+ memused /= 1024; // Just show MBs used
+
+ /* Change color based on % of RAM used */
+ if ((float)memused / (float)memtotal < 0.85) {
+ fputs("^fg(green)", stdout);
+ } else {
+ fputs("^fg(red)", stdout);
+ }
+
+ printf(" Mem: %d M ", memused);
+ }
+}
--- /dev/null
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+
+#include "status/netif.h"
+#include "tools.h"
+#include "config.h"
+
+#ifndef NETIF_BASEDIR
+ #define NETIF_BASEDIR "/sys/class/net/"
+#endif
+
+
+void status_netif(char *ifname)
+{
+ char ifpath[256];
+ int ifpathlen;
+
+ char stline[16];
+ ssize_t stlen;
+
+ double ifsum = 0.0;
+ int ifsumpower;
+
+
+ /* Prepare path */
+ ifpathlen = sizeof(NETIF_BASEDIR) - 1 + strlen(ifname);
+ if (ifpathlen + 1 + sizeof("/statistics/rx_bytes") >= sizeof(ifpath)) {
+ statusError("status_netif",
+ "ifpath buffer too small",
+ ifname);
+ return;
+ }
+ strcpy(ifpath, NETIF_BASEDIR);
+ strcat(ifpath, ifname);
+
+
+ /* Is the interface up? */
+ if (access(ifpath, F_OK)) {
+ //printf(" ^fg(grey)[%s] ", ifname);
+ return;
+ }
+
+
+ strcpy(&ifpath[ifpathlen], "/carrier");
+ stlen = fileRead(stline, sizeof(stline), ifpath);
+ if (stlen > 0) {
+ if (stline[0] == '1') {
+ fputs("^fg(yellow)", stdout);
+ } else {
+ //fputs("^fg(red)", stdout);
+ return;
+ }
+ } else {
+ return;
+ }
+
+ strcpy(&ifpath[ifpathlen], "/statistics/rx_bytes");
+ stlen = fileRead(stline, sizeof(stline), ifpath);
+ if (stlen > 0) {
+ ifsum = atof(stline);
+ }
+
+ strcpy(&ifpath[ifpathlen], "/statistics/tx_bytes");
+ stlen = fileRead(stline, sizeof(stline), ifpath);
+ if (stlen > 0) {
+ ifsum += atof(stline);
+ }
+
+
+ for(ifsumpower = 0; ifsum >= 1024.0; ifsumpower++) {
+ ifsum = ifsum / 1024;
+ }
+
+ printf(" %s: %.*f %c ", ifname,
+ ifsumpower ? ifsumpower - 1 : ifsumpower,
+ ifsum,
+ powerToChar(ifsumpower));
+}
--- /dev/null
+#include <stdio.h>
+#include <fcntl.h>
+#include <unistd.h>
+
+#include "status/temp.h"
+#include "tools.h"
+
+
+void status_temp(char *title, char *sysfile)
+{
+ char stline[16];
+ ssize_t stlen;
+
+ stlen = fileRead(stline, sizeof(stline), sysfile);
+ if (stlen <= 0) {
+ return;
+ }
+
+ /*
+ * Read a valid value?
+ * Sometimes we get garbage from sysfs...
+ */
+ if (stlen < 6 || stlen > 7) {
+ printf(" ^fg(red)%sERROR ", title);
+ return;
+ }
+
+ fputs(" ^fg(#FF33FF)", stdout);
+ fputs(title, stdout);
+ fwrite(stline, 1, stlen - 4, stdout);
+ /*
+ fputs(".", stdout);
+ fwrite(&stline[stlen - 3], 1, 1, stdout);
+ */
+ fputs("°C ", stdout);
+}
--- /dev/null
+#include <stdio.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <stdlib.h>
+
+#include "status/uptime.h"
+#include "tools.h"
+#include "config.h"
+
+void status_uptime()
+{
+ char stline[16];
+ ssize_t stlen;
+ int i;
+ int upts, uptm, upth, uptd;
+
+ fputs(" ^fg(#AAAAAA)up: ", stdout);
+
+ stlen = fileRead(stline, sizeof(stline), "/proc/uptime");
+ if (stlen < 0) {
+ fputs(" ^fg(red)ERROR ", stdout);
+ return;
+ }
+
+ /* Cut first element */
+ for(i = 0; i < stlen; i++) {
+ if (stline[i] == ' ') {
+ stline[i] = '\0';
+ break;
+ }
+ }
+
+ // Split time into days, hours, mins, secs
+ upts = atoi(stline);
+ uptd = upts / (24 * 60 * 60);
+ upts -= uptd * (24 * 60 * 60);
+ upth = upts / (60 * 60);
+ upts -= upth * (60 * 60);
+ uptm = upts / (60);
+ upts -= uptm * (60);
+
+ if (uptd > 0) {
+ printf("%dd ", uptd);
+ }
+
+ printf("%d:%.2d"
+ #ifdef SHOW_SECONDS
+ ":%.2d"
+ #endif
+
+ " "
+ ,upth
+ ,uptm
+
+ #ifdef SHOW_SECONDS
+ ,upts
+ #endif
+ );
+}
--- /dev/null
+#include <alsa/asoundlib.h>
+
+#include "status/volume_alsa.h"
+
+
+int status_volume_alsa(char *cardname, char *mixername, snd_mixer_selem_channel_id_t channel)
+{
+ snd_mixer_t *handle = NULL;
+ snd_mixer_elem_t *elem;
+ snd_mixer_selem_id_t *sid;
+
+ long min = 0, max = 0;
+ long volume;
+ int on_off;
+
+
+ snd_mixer_selem_id_alloca(&sid);
+
+ if (snd_mixer_open(&handle, 0) < 0) {
+ return -1;
+ }
+
+ if (snd_mixer_attach(handle, cardname) < 0) {
+ goto ERROR;
+ }
+
+ snd_mixer_selem_id_set_name(sid, mixername);
+
+ if (snd_mixer_selem_register(handle, NULL, NULL) < 0) {
+ goto ERROR;
+ }
+
+ if (snd_mixer_load(handle) < 0) {
+ goto ERROR;
+ }
+
+ elem = snd_mixer_find_selem(handle, sid);
+ if (!elem) {
+ goto ERROR;
+ }
+
+ if (snd_mixer_selem_has_playback_volume(elem)
+ && snd_mixer_selem_has_playback_channel(elem, channel)) {
+ snd_mixer_selem_get_playback_switch(elem, channel, &on_off);
+ if (on_off) {
+ fputs("^fg(#22FF22)", stdout);
+ } else {
+ fputs("^fg(red)", stdout);
+ }
+
+ snd_mixer_selem_get_playback_volume_range(elem, &min, &max);
+
+ snd_mixer_selem_get_playback_volume(elem, channel, &volume);
+ fputs("^ca(1, amixer sset Master toggle)", stdout);
+ fputs("^ca(4, amixer sset Master 2+ unmute)", stdout);
+ fputs("^ca(5, amixer sset Master 2- unmute)", stdout);
+ printf(" Vol: %d ", (int)volume);
+ fputs("^ca()", stdout);
+ fputs("^ca()", stdout);
+ fputs("^ca()", stdout);
+ }
+
+ snd_mixer_close(handle);
+
+ return 0;
+
+ ERROR:
+
+ snd_mixer_close(handle);
+ return -1;
+}
--- /dev/null
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "config.h"
+#include "status/battery.h"
+#include "status/cpuusage.h"
+#include "status/datetime.h"
+#include "status/fan.h"
+#include "status/memusage.h"
+#include "status/netif.h"
+#include "status/volume_alsa.h"
+#include "status/temp.h"
+#include "status/uptime.h"
+
+
+void updatestatus()
+{
+ //status_uptime();
+
+ status_cpuusage();
+
+ status_battery("BAT0");
+ status_battery("BAT1");
+
+ status_memusage();
+
+ status_netif("eth0");
+ //status_netif("eth1");
+ //status_netif("eth2");
+ status_netif("wlan0");
+ //status_netif("wlan1");
+ status_netif("wlan2");
+ //status_netif("usb0");
+ status_netif("ppp0");
+
+ //status_temp("GPU: ", "/sys/class/hwmon/hwmon0/device/temp4_input");
+ //status_temp("CPU: ", "/sys/class/hwmon/hwmon0/device/temp2_input");
+ status_temp("CPU: ", "/sys/devices/platform/coretemp.0/temp1_input");
+
+ status_fan("Fan: ", "/sys/devices/platform/thinkpad_hwmon/fan1_input");
+
+ status_volume_alsa("default", "Master", 0);
+
+ status_datetime();
+
+ fputs("\n", stdout);
+ fflush(stdout);
+}
+
+int main()
+{
+ struct timeval tv;
+
+ for(;;)
+ {
+ updatestatus();
+
+ tv.tv_sec = UPDATE_SECS;
+ tv.tv_usec = 0;
+
+ select(0, NULL, NULL, NULL, &tv);
+ }
+
+ return 0;
+}
--- /dev/null
+#include <stdio.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include "tools.h"
+
+char powerToChar(int power)
+{
+ switch(power)
+ {
+ case 0:
+ return 'b';
+ case 1:
+ return 'k';
+ case 2:
+ return 'M';
+ case 3:
+ return 'G';
+ case 4:
+ return 'T';
+ case 5:
+ return 'P';
+ case 6:
+ return 'E';
+ }
+
+ return '?';
+}
+
+
+void statusError(char *where, char *what, char *extra)
+{
+ fprintf(stderr, "%s: %s", where, what);
+ if (extra) {
+ fprintf(stderr, " -- %s", extra);
+ }
+ fputs("\n", stderr);
+}
+
+
+ssize_t fileRead(char *buf, size_t bufsize, char *file)
+{
+ int fd;
+ int readbytes;
+
+ fd = open(file, 0);
+ if (fd < 0) {
+ return -1;
+ }
+
+ readbytes = read(fd, buf, bufsize - 1);
+ close(fd);
+
+ if (readbytes > 0) {
+ buf[readbytes] = '\0';
+ } else {
+ buf[0] = '\0';
+ }
+
+ return readbytes;
+}
+++ /dev/null
-STATUSES=battery.o cpuusage.o datetime.o fan.o memusage.o netif.o temp.o uptime.o volume_alsa.o
-OTHERS=tools.o
-
-all: *.c *.h ../config.h Makefile $(STATUSES) $(OTHERS)
-
-.c.o:
- $(CC) $(CCFLAGS) -c -o $@ $<
-
-clean:
- rm -f *.o
+++ /dev/null
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include "string.h"
-#include "battery.h"
-
-#ifndef POWER_BASEDIR
- #define POWER_BASEDIR "/sys/class/power_supply/"
-#endif
-
-
-void status_battery(char *batname)
-{
- char batpath[256];
- int batpathlen;
-
- char stline[16];
- ssize_t stlen;
-
- int chargeNow = 0;
- int chargeFull = -1;
- int chargePercent = -1;
- int battW = 1;
- int battV = 0;
- float battTime = -1;
-
-
- /* Prepare path */
- batpathlen = sizeof(POWER_BASEDIR) - 1 + strlen(batname);
- if (batpathlen + 1 + sizeof("/energy_full") >= sizeof(batpath)) {
- statusError("status_battery",
- "batpath buffer too small",
- batname);
- return;
- }
- strcpy(batpath, POWER_BASEDIR);
- strcat(batpath, batname);
-
-
- /* Is the battery present? */
- if (access(batpath, F_OK)) {
- //printf(" ^fg(grey)[%s] ", batname);
- return;
- }
-
-
- /* Get info */
- strcpy(&batpath[batpathlen], "/energy_now");
- stlen = fileRead(stline, sizeof(stline), batpath);
- if (stlen > 0) {
- chargeNow = atoi(stline);
- }
-
- strcpy(&batpath[batpathlen], "/energy_full");
- stlen = fileRead(stline, sizeof(stline), batpath);
- if (stlen > 0) {
- chargeFull = atoi(stline);
- }
-
- strcpy(&batpath[batpathlen], "/power_now");
- stlen = fileRead(stline, sizeof(stline), batpath);
- if (stlen > 0) {
- battW = atoi(stline);
- }
-
- strcpy(&batpath[batpathlen], "/voltage_now");
- stlen = fileRead(stline, sizeof(stline), batpath);
- if (stlen > 0) {
- battV = atoi(stline);
- }
-
-
- /* Prettyprint */
- if (chargeFull > 0) {
- chargePercent = chargeNow / (chargeFull / 100);
- }
-
- if (chargePercent <= 40) {
- if (chargePercent <= 25) {
- if (chargePercent <= 10) {
- fputs("^fg(red)", stdout);
- } else {
- // 11-25%
- fputs("^fg(orange)", stdout);
- }
- } else {
- // 26-40%
- fputs("^fg(yellow)", stdout);
- }
- } else {
- if (chargePercent > 70) {
- fputs("^fg(white)", stdout);
- } else {
- // 41-70%
- fputs("^fg(green)", stdout);
- }
- }
-
- battTime = (float)chargeNow / (float)battW;
-
- if (battW == 0) {
- // fully charged and not in use
- printf(" %s: %d%% _ _ ",
- batname, chargePercent);
- } else {
- printf(" %s: %d%% %.1fh %.1fW ",
- batname, chargePercent, battTime, (float)battW / 1000000.0);
- }
-}
+++ /dev/null
-
-#ifndef __BATTERY_H__
-#define __BATTERY_H__
-
-void status_battery(char *batname);
-
-#endif
+++ /dev/null
-#include <stdio.h>
-#include <fcntl.h>
-#include <unistd.h>
-#include <stdlib.h>
-#include "cpuusage.h"
-#include "../config.h"
-
-#ifndef NUM_CPUS
- #define NUM_CPUS 1
-#endif
-#ifndef CPU_HISTORY_SIZE
- #define CPU_HISTORY_SIZE 1
-#endif
-#if CPU_HISTORY_SIZE < 1
- #define CPU_HISTORY_SIZE 1
-#endif
-
-
-unsigned long last_cpu_used = 0;
-unsigned long last_cpu_total = 0;
-float cpu_history[CPU_HISTORY_SIZE]; // don't care about init values
-
-void status_cpuusage()
-{
- double loadavg[3] = { -13.37, -13.37, -13.37 } ;
-
- char *stline = NULL;
- size_t stlen;
- FILE *stfile;
-
- unsigned long cpu_user;
- unsigned long cpu_nice;
- unsigned long cpu_sys;
- unsigned long cpu_used;
- unsigned long cpu_idle;
- unsigned long cpu_total;
- int i;
-
-
- // Error signaling color
- fputs("^fg(yellow)", stdout);
-
- stfile = fopen("/proc/stat", "r");
- if (stfile != NULL) {
- for(i = CPU_HISTORY_SIZE - 1; i > 0; i--) {
- cpu_history[i] = cpu_history[i - 1];
- }
-
- stlen = getline(&stline, &stlen, stfile);
- fclose(stfile);
-
- if ( 4 == sscanf(stline, "%*s %ld %ld %ld %ld",
- &cpu_user, &cpu_nice, &cpu_sys, &cpu_idle) ) {
- cpu_used = cpu_user + cpu_nice + cpu_sys;
- cpu_total = cpu_used + cpu_idle;
-
- // Now do the percentage
- cpu_history[0] = (float)(cpu_used - last_cpu_used) /
- (float)(cpu_total - last_cpu_total);
-
- last_cpu_used = cpu_used;
- last_cpu_total = cpu_total;
-
-
- if (cpu_history[0] < 0.4) {
- // CPU idling OK
- fputs("^fg(#0077FF)", stdout);
- } else {
- // CPU busy
- fputs("^fg(#FF00FF)", stdout);
- }
-
- //printf(" CPU: %.0f%% ", cpu_history[0] * 100);
- }
-
- free(stline);
- }
-
-
- if (getloadavg(loadavg, 3) > 0) {
- printf(" %s%.0f,%.0f,%.0f,%.0f ",
- cpu_history[0] < 0.1000 ? " " : "",
- cpu_history[0] * 100,
- loadavg[0] * (100 / 1),
- loadavg[1] * (100 / 1), // (100 / NUM_CPUS)
- loadavg[2] * (100 / 1));
- }
-
- //fputs(" CPU usage ", stdout);
-}
+++ /dev/null
-
-#ifndef __CPUUSAGE_H__
-#define __CPUUSAGE_H__
-
-void status_cpuusage();
-
-#endif
+++ /dev/null
-#include <stdio.h>
-#include <time.h>
-#include "datetime.h"
-#include "../config.h"
-
-void status_datetime()
-{
- time_t nows = 0;
- struct tm *nowtm;
-
- nows = time(NULL);
- if (nows == ((time_t) -1)) {
- printf(" ^fg(red)ERROR: DATETIME");
- return;
- }
-
- nowtm = localtime(&nows);
-
- printf(" ^fg(#666666)%d.%d.%d ^fg(grey)%d:%.2d"
- #ifdef SHOW_SECONDS
- ":%.2d"
- #endif
- " "
- ,nowtm -> tm_mday,
- (nowtm -> tm_mon) + 1,
- (nowtm -> tm_year) + 1900,
- nowtm -> tm_hour,
- nowtm -> tm_min
-
- #ifdef SHOW_SECONDS
- ,nowtm -> tm_sec
- #endif
- );
-}
+++ /dev/null
-
-#ifndef __DATETIME_H__
-#define __DATETIME_H__
-
-void status_datetime();
-
-#endif
+++ /dev/null
-#include <stdio.h>
-#include <fcntl.h>
-#include <unistd.h>
-#include "fan.h"
-
-void status_fan(char *title, char *sysfile)
-{
- char stline[16];
- int stfile;
- ssize_t stlen;
-
- stlen = fileRead(stline, sizeof(stline), sysfile);
- if (stlen <= 0) {
- return;
- }
-
- // Read a valid value? Sometimes we get garbage from sysfs...
- if (stlen > 5) {
- printf(" ^fg(red)%sERROR ", title);
- return;
- }
-
- fputs(" ^fg(#CCCCCC)", stdout);
- fputs(title, stdout);
- fwrite(stline, 1, stlen - 1, stdout);
- fputs(" rpm ", stdout);
-}
+++ /dev/null
-
-#ifndef __FAN_H__
-#define __FAN_H__
-
-void status_fan(char *title, char *sysfile);
-
-#endif
+++ /dev/null
-#include <stdio.h>
-#include <stdlib.h>
-#include "memusage.h"
-#include "tools.h"
-
-void status_memusage()
-{
- char *stline = NULL;
- size_t stlen;
- FILE *stfile;
-
- int memtotal = 0;
- int memfree = 0;
- int memused;
- int membuffers = 0;
- int memcached = 0;
-
-
- stfile = fopen("/proc/meminfo", "r");
- if (stfile != NULL) {
- stlen = getline(&stline, &stlen, stfile);
- memtotal = atoi(&stline[17]);
-
- stlen = getline(&stline, &stlen, stfile);
- memfree = atoi(&stline[17]);
-
- stlen = getline(&stline, &stlen, stfile);
- membuffers = atoi(&stline[17]);
-
- stlen = getline(&stline, &stlen, stfile);
- memcached = atoi(&stline[17]);
- free(stline);
-
- fclose(stfile);
-
- memused = memtotal - memfree - memcached - membuffers;
-
- memused /= 1024; // Just show MBs used
-
- /* Change color based on % of RAM used */
- if ((float)memused / (float)memtotal < 0.85) {
- fputs("^fg(green)", stdout);
- } else {
- fputs("^fg(red)", stdout);
- }
-
- printf(" Mem: %d M ", memused);
- }
-}
+++ /dev/null
-
-#ifndef __MEMUSAGE_H__
-#define __MEMUSAGE_H__
-
-void status_memusage();
-
-#endif
+++ /dev/null
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <string.h>
-#include "netif.h"
-#include "tools.h"
-#include "../config.h"
-
-#ifndef NETIF_BASEDIR
- #define NETIF_BASEDIR "/sys/class/net/"
-#endif
-
-
-void status_netif(char *ifname)
-{
- char ifpath[256];
- int ifpathlen;
-
- char stline[16];
- ssize_t stlen;
-
- double ifsum = 0.0;
- int ifsumpower;
-
-
- /* Prepare path */
- ifpathlen = sizeof(NETIF_BASEDIR) - 1 + strlen(ifname);
- if (ifpathlen + 1 + sizeof("/statistics/rx_bytes") >= sizeof(ifpath)) {
- statusError("status_netif",
- "ifpath buffer too small",
- ifname);
- return;
- }
- strcpy(ifpath, NETIF_BASEDIR);
- strcat(ifpath, ifname);
-
-
- /* Is the interface up? */
- if (access(ifpath, F_OK)) {
- //printf(" ^fg(grey)[%s] ", ifname);
- return;
- }
-
-
- strcpy(&ifpath[ifpathlen], "/carrier");
- stlen = fileRead(stline, sizeof(stline), ifpath);
- if (stlen > 0) {
- if (stline[0] == '1') {
- fputs("^fg(yellow)", stdout);
- } else {
- //fputs("^fg(red)", stdout);
- return;
- }
- } else {
- return;
- }
-
- strcpy(&ifpath[ifpathlen], "/statistics/rx_bytes");
- stlen = fileRead(stline, sizeof(stline), ifpath);
- if (stlen > 0) {
- ifsum = atof(stline);
- }
-
- strcpy(&ifpath[ifpathlen], "/statistics/tx_bytes");
- stlen = fileRead(stline, sizeof(stline), ifpath);
- if (stlen > 0) {
- ifsum += atof(stline);
- }
-
-
- for(ifsumpower = 0; ifsum >= 1024.0; ifsumpower++) {
- ifsum = ifsum / 1024;
- }
-
- printf(" %s: %.*f %c ", ifname,
- ifsumpower ? ifsumpower - 1 : ifsumpower,
- ifsum,
- powerToChar(ifsumpower));
-}
+++ /dev/null
-
-#ifndef __NETIF_H__
-#define __NETIF_H__
-
-void status_netif(char *ifname);
-
-#endif
+++ /dev/null
-#include <stdio.h>
-#include <fcntl.h>
-#include <unistd.h>
-#include "temp.h"
-
-void status_temp(char *title, char *sysfile)
-{
- char stline[16];
- int stfile;
- ssize_t stlen;
-
- stlen = fileRead(stline, sizeof(stline), sysfile);
- if (stlen <= 0) {
- return;
- }
-
- /*
- * Read a valid value?
- * Sometimes we get garbage from sysfs...
- */
- if (stlen < 6 || stlen > 7) {
- printf(" ^fg(red)%sERROR ", title);
- return;
- }
-
- fputs(" ^fg(#FF33FF)", stdout);
- fputs(title, stdout);
- fwrite(stline, 1, stlen - 4, stdout);
- /*
- fputs(".", stdout);
- fwrite(&stline[stlen - 3], 1, 1, stdout);
- */
- fputs("°C ", stdout);
-}
+++ /dev/null
-
-#ifndef __TEMP_H__
-#define __TEMP_H__
-
-void status_temp(char *title, char *sysfile);
-
-#endif
+++ /dev/null
-#include <stdio.h>
-#include <fcntl.h>
-#include <unistd.h>
-#include "tools.h"
-
-char powerToChar(int power)
-{
- switch(power)
- {
- case 0:
- return 'b';
- case 1:
- return 'k';
- case 2:
- return 'M';
- case 3:
- return 'G';
- case 4:
- return 'T';
- case 5:
- return 'P';
- case 6:
- return 'E';
- }
-
- return '?';
-}
-
-
-void statusError(char *where, char *what, char *extra)
-{
- fprintf(stderr, "%s: %s", where, what);
- if (extra) {
- fprintf(stderr, " -- %s", extra);
- }
- fputs("\n", stderr);
-}
-
-
-ssize_t fileRead(char *buf, size_t bufsize, char *file)
-{
- int fd;
- int readbytes;
-
- fd = open(file, 0);
- if (fd < 0) {
- return -1;
- }
-
- readbytes = read(fd, buf, bufsize - 1);
- close(fd);
-
- if (readbytes > 0) {
- buf[readbytes] = '\0';
- } else {
- buf[0] = '\0';
- }
-
- return readbytes;
-}
+++ /dev/null
-
-#ifndef __TOOLS_H__
-#define __TOOLS_H__
-
-char powerToChar(int power);
-void statusError(char *where, char *what, char *extra);
-ssize_t fileRead(char *buf, size_t bufsize, char *file);
-
-#endif
+++ /dev/null
-#include <stdio.h>
-#include <fcntl.h>
-#include <unistd.h>
-#include <stdlib.h>
-#include "uptime.h"
-#include "../config.h"
-
-void status_uptime()
-{
- char stline[16];
- int stfile;
- ssize_t stlen;
- int i;
- int upts, uptm, upth, uptd;
-
- fputs(" ^fg(#AAAAAA)up: ", stdout);
-
- stlen = fileRead(stline, sizeof(stline), "/proc/uptime");
- if (stlen < 0) {
- fputs(" ^fg(red)ERROR ", stdout);
- return;
- }
-
- /* Cut first element */
- for(i = 0; i < stlen; i++) {
- if (stline[i] == ' ') {
- stline[i] = '\0';
- break;
- }
- }
-
- // Split time into days, hours, mins, secs
- upts = atoi(stline);
- uptd = upts / (24 * 60 * 60);
- upts -= uptd * (24 * 60 * 60);
- upth = upts / (60 * 60);
- upts -= upth * (60 * 60);
- uptm = upts / (60);
- upts -= uptm * (60);
-
- if (uptd > 0) {
- printf("%dd ", uptd);
- }
-
- printf("%d:%.2d"
- #ifdef SHOW_SECONDS
- ":%.2d"
- #endif
-
- " "
- ,upth
- ,uptm
-
- #ifdef SHOW_SECONDS
- ,upts
- #endif
- );
-}
+++ /dev/null
-
-#ifndef __UPTIME_H__
-#define __UPTIME_H__
-
-void status_uptime();
-
-#endif
+++ /dev/null
-#include <alsa/asoundlib.h>
-#include "volume_alsa.h"
-
-int status_volume_alsa(char *cardname, char *mixername, snd_mixer_selem_channel_id_t channel)
-{
- snd_mixer_t *handle = NULL;
- snd_mixer_elem_t *elem;
- snd_mixer_selem_id_t *sid;
-
- long min = 0, max = 0;
- long volume;
- int on_off;
-
-
- snd_mixer_selem_id_alloca(&sid);
-
- if (snd_mixer_open(&handle, 0) < 0) {
- return -1;
- }
-
- if (snd_mixer_attach(handle, cardname) < 0) {
- goto ERROR;
- }
-
- snd_mixer_selem_id_set_name(sid, mixername);
-
- if (snd_mixer_selem_register(handle, NULL, NULL) < 0) {
- goto ERROR;
- }
-
- if (snd_mixer_load(handle) < 0) {
- goto ERROR;
- }
-
- elem = snd_mixer_find_selem(handle, sid);
- if (!elem) {
- goto ERROR;
- }
-
- if (snd_mixer_selem_has_playback_volume(elem)
- && snd_mixer_selem_has_playback_channel(elem, channel)) {
- snd_mixer_selem_get_playback_switch(elem, channel, &on_off);
- if (on_off) {
- fputs("^fg(#22FF22)", stdout);
- } else {
- fputs("^fg(red)", stdout);
- }
-
- snd_mixer_selem_get_playback_volume_range(elem, &min, &max);
-
- snd_mixer_selem_get_playback_volume(elem, channel, &volume);
- fputs("^ca(1, amixer sset Master toggle)", stdout);
- fputs("^ca(4, amixer sset Master 2+ unmute)", stdout);
- fputs("^ca(5, amixer sset Master 2- unmute)", stdout);
- printf(" Vol: %d ", (int)volume);
- fputs("^ca()", stdout);
- fputs("^ca()", stdout);
- fputs("^ca()", stdout);
- }
-
- snd_mixer_close(handle);
-
- return 0;
-
- ERROR:
-
- snd_mixer_close(handle);
- return -1;
-}
+++ /dev/null
-
-#ifndef __VOLUME_ALSA_H__
-#define __VOLUME_ALSA_H__
-
-#include <alsa/asoundlib.h>
-
-int status_volume_alsa(char *cardname, char *mixername, snd_mixer_selem_channel_id_t channel);
-
-#endif
+++ /dev/null
-#include <stdio.h>
-#include <stdlib.h>
-#include "config.h"
-#include "statuses/battery.h"
-#include "statuses/cpuusage.h"
-#include "statuses/datetime.h"
-#include "statuses/fan.h"
-#include "statuses/memusage.h"
-#include "statuses/netif.h"
-#include "statuses/volume_alsa.h"
-#include "statuses/temp.h"
-#include "statuses/uptime.h"
-
-
-void updatestatus()
-{
- //status_uptime();
-
- status_cpuusage();
-
- status_battery("BAT0");
- status_battery("BAT1");
-
- status_memusage();
-
- status_netif("eth0");
- //status_netif("eth1");
- //status_netif("eth2");
- status_netif("wlan0");
- //status_netif("wlan1");
- status_netif("wlan2");
- //status_netif("usb0");
- status_netif("ppp0");
-
- //status_temp("GPU: ", "/sys/class/hwmon/hwmon0/device/temp4_input");
- //status_temp("CPU: ", "/sys/class/hwmon/hwmon0/device/temp2_input");
- status_temp("CPU: ", "/sys/devices/platform/coretemp.0/temp1_input");
-
- status_fan("Fan: ", "/sys/devices/platform/thinkpad_hwmon/fan1_input");
-
- status_volume_alsa("default", "Master", 0);
-
- status_datetime();
-
- fputs("\n", stdout);
- fflush(stdout);
-}
-
-int main()
-{
- struct timeval tv;
-
- for(;;)
- {
- updatestatus();
-
- tv.tv_sec = UPDATE_SECS;
- tv.tv_usec = 0;
-
- select(0, NULL, NULL, NULL, &tv);
- }
-
- return 0;
-}