From: norly Date: Thu, 17 Nov 2011 23:05:15 +0000 (+0100) Subject: Ye Olde Brick, hacked one very late night in 2010. X-Git-Url: https://git.enpas.org/?p=sysstatus.git;a=commitdiff_plain;h=5a9cc1b0d20efa65d10adaaf06d0ef0aa089663c Ye Olde Brick, hacked one very late night in 2010. Full of inefficient or maybe broken code, as well as the occasional memory leak. I am not proud of it and I was *really* tired back then. While this was an experiment in writing (f)ugly code and I just wanted something running, I have to admit that this code has served me well ever since. Too well to be bothered to ever look at it again, really... --- 5a9cc1b0d20efa65d10adaaf06d0ef0aa089663c diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..324252d --- /dev/null +++ b/.gitignore @@ -0,0 +1,4 @@ +audstatus/* +bitmaps/* +*.log +sysstatus diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..fd50152 --- /dev/null +++ b/Makefile @@ -0,0 +1,16 @@ +build: + gcc -Wall -o sysstatus sysstatus.c \ + statuses/tools.c \ + statuses/uptime.c \ + statuses/memusage.c \ + statuses/cpuusage.c \ + statuses/netif.c \ + statuses/netif_named.c \ + statuses/power.c \ + statuses/volume_alsa.c \ + statuses/temp.c \ + statuses/datetime.c \ + -lasound + +clean: + rm -f sysstatus diff --git a/config.h b/config.h new file mode 100644 index 0000000..7879911 --- /dev/null +++ b/config.h @@ -0,0 +1,14 @@ + +#ifndef __CONFIG_H__ +#define __CONFIG_H__ + +#define UPDATE_SECS 1 + +//#define SHOW_SECONDS + +#define CPU_HISTORY_SIZE 10 +#define NUM_CPUS 2 + +#define IFNAME "ppp0" + +#endif diff --git a/devstatus.sh b/devstatus.sh new file mode 100755 index 0000000..e78c3f4 --- /dev/null +++ b/devstatus.sh @@ -0,0 +1,6 @@ +#!/bin/sh + +cd ~/sysstatus/ +make + +./runstatus.sh diff --git a/runstatus.sh b/runstatus.sh new file mode 100755 index 0000000..c2b1564 --- /dev/null +++ b/runstatus.sh @@ -0,0 +1,12 @@ +#!/bin/sh + +RES=$(xrandr --prop | sed "s/Screen 0:[^,]*, current \(.*\) x \(.*\),.*/\1,\2/g;te;d;:e") +RESX=${RES%%,*} +RESY=${RES##*,} +FONT="-misc-fixed-medium-r-normal--13-120-75-75-C-70-iso8859-1" +#FONT="-*-fixed-medium-r-semicondensed-*-13-*-*-*-*-*-*-*" + +cd ~/sysstatus/ +killall sysstatus +./sysstatus | dzen2 -ta l -fn "$FONT" -bg black -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 "" diff --git a/statuses/cpuusage.c b/statuses/cpuusage.c new file mode 100644 index 0000000..fa92829 --- /dev/null +++ b/statuses/cpuusage.c @@ -0,0 +1,85 @@ +#include +#include +#include +#include +#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; + + + fputs("^fg(yellow)", stdout); // Error signaling color + + 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) + fputs("^fg(#0077FF)", stdout); // CPU idling OK + else + fputs("^fg(#FF00FF)", stdout); // CPU busy + + //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); +} diff --git a/statuses/cpuusage.h b/statuses/cpuusage.h new file mode 100644 index 0000000..1de2aed --- /dev/null +++ b/statuses/cpuusage.h @@ -0,0 +1,7 @@ + +#ifndef __CPUUSAGE_H__ +#define __CPUUSAGE_H__ + +void status_cpuusage(); + +#endif diff --git a/statuses/datetime.c b/statuses/datetime.c new file mode 100644 index 0000000..7c0e479 --- /dev/null +++ b/statuses/datetime.c @@ -0,0 +1,36 @@ +#include +#include +#include "datetime.h" +#include "../config.h" + +void status_datetime() +{ + time_t nows = 0; + struct tm *nowtm; + + nows = time(NULL); + if (nows != ((time_t) -1)) + { + 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 + + ); + } + else + printf(" ^fg(red)ERROR: DATETIME"); +} diff --git a/statuses/datetime.h b/statuses/datetime.h new file mode 100644 index 0000000..e4c9554 --- /dev/null +++ b/statuses/datetime.h @@ -0,0 +1,7 @@ + +#ifndef __DATETIME_H__ +#define __DATETIME_H__ + +void status_datetime(); + +#endif diff --git a/statuses/memusage.c b/statuses/memusage.c new file mode 100644 index 0000000..10d3732 --- /dev/null +++ b/statuses/memusage.c @@ -0,0 +1,48 @@ +#include +#include +#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 + + if ((float)memused / (float)memtotal < 0.85) + fputs("^fg(green)", stdout); // < 85% mem used + else + fputs("^fg(red)", stdout); // >= 85% mem used + + printf(" Mem: %d M ", memused); + } +} diff --git a/statuses/memusage.h b/statuses/memusage.h new file mode 100644 index 0000000..9db9719 --- /dev/null +++ b/statuses/memusage.h @@ -0,0 +1,7 @@ + +#ifndef __MEMUSAGE_H__ +#define __MEMUSAGE_H__ + +void status_memusage(); + +#endif diff --git a/statuses/netif.c b/statuses/netif.c new file mode 100644 index 0000000..944fe2c --- /dev/null +++ b/statuses/netif.c @@ -0,0 +1,52 @@ +#include +#include +#include +#include +#include "netif.h" +#include "tools.h" +#include "../config.h" + +void status_netif() +{ + char stline[16]; + int stfile; + size_t stlen; + + double ifsum; + int ifsumpower; + + + stfile = open("/sys/class/net/" IFNAME "/carrier", 0); + if (stfile != -1) + { + stlen = read(stfile, stline, sizeof(stline) - 1); + close(stfile); + if (stline[0] == '1') + fputs("^fg(yellow)", stdout); + else + fputs("^fg(red)", stdout); + } + + stfile = open("/sys/class/net/" IFNAME "/statistics/rx_bytes", 0); + if (stfile != -1) + { + stlen = read(stfile, stline, sizeof(stline) - 1); + close(stfile); + stline[stlen] = '\0'; + ifsum = atof(stline); + } + + stfile = open("/sys/class/net/" IFNAME "/statistics/tx_bytes", 0); + if (stfile != -1) + { + stlen = read(stfile, stline, sizeof(stline) - 1); + close(stfile); + stline[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)); +} diff --git a/statuses/netif.h b/statuses/netif.h new file mode 100644 index 0000000..2f6685e --- /dev/null +++ b/statuses/netif.h @@ -0,0 +1,7 @@ + +#ifndef __NETIF_H__ +#define __NETIF_H__ + +void status_netif(); + +#endif diff --git a/statuses/netif_named.c b/statuses/netif_named.c new file mode 100644 index 0000000..3fa90f1 --- /dev/null +++ b/statuses/netif_named.c @@ -0,0 +1,76 @@ +#include +#include +#include +#include +#include +#include "netif_named.h" +#include "tools.h" + +#define NETIF_BASEDIR "/sys/class/net/" + +void status_netif_named(char *ifname) +{ + char stline[16]; + int stfile; + size_t stlen; + + double ifsum; + int ifsumpower; + + char *stfilename = NULL; + + stfilename = malloc(sizeof(NETIF_BASEDIR) - 1 + strlen(ifname) + sizeof("/statistics/rx_bytes")); + + strcpy(stfilename, NETIF_BASEDIR); + strcat(stfilename, ifname); + + if (access(stfilename, F_OK)) + { + //printf(" ^fg(grey)[%s] ", ifname); + return; + } + + strcat(stfilename, "/carrier"); + stfile = open(stfilename, 0); + if (stfile != -1) + { + stlen = read(stfile, stline, sizeof(stline) - 1); + close(stfile); + if (stline[0] == '1') + fputs("^fg(yellow)", stdout); + else + { + //fputs("^fg(red)", stdout); + return; + } + } + + strcpy(stfilename, NETIF_BASEDIR); + strcat(stfilename, ifname); + strcat(stfilename, "/statistics/rx_bytes"); + stfile = open(stfilename, 0); + if (stfile != -1) + { + stlen = read(stfile, stline, sizeof(stline) - 1); + close(stfile); + stline[stlen] = '\0'; + ifsum = atof(stline); + } + + strcpy(stfilename, NETIF_BASEDIR); + strcat(stfilename, ifname); + strcat(stfilename, "/statistics/tx_bytes"); + stfile = open(stfilename, 0); + if (stfile != -1) + { + stlen = read(stfile, stline, sizeof(stline) - 1); + close(stfile); + stline[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)); +} diff --git a/statuses/netif_named.h b/statuses/netif_named.h new file mode 100644 index 0000000..adb4a3e --- /dev/null +++ b/statuses/netif_named.h @@ -0,0 +1,7 @@ + +#ifndef __NETIF_NAMED_H__ +#define __NETIF_NAMED_H__ + +void status_netif_named(char *ifname); + +#endif diff --git a/statuses/power.c b/statuses/power.c new file mode 100644 index 0000000..47277d0 --- /dev/null +++ b/statuses/power.c @@ -0,0 +1,101 @@ +#include +#include +#include +#include +#include "power.h" + +void status_power() +{ + char *stline; + size_t stlen; + FILE *stfile; + + int batt_now = 0; + int batt_full = -1; + int batt_percent = -1; + int batt_current = 1; + int batt_voltage = 0; + float batt_time = -1; + float batt_watts = -1; + + stfile = fopen("/sys/class/power_supply/BAT0/energy_now", "r"); + if (stfile != NULL) + { + stline = NULL; + stlen = getline(&stline, &stlen, stfile); + fclose(stfile); + + batt_now = atoi(stline); + free(stline); + } + + stfile = fopen("/sys/class/power_supply/BAT0/energy_full", "r"); + if (stfile != NULL) + { + stline = NULL; + stlen = getline(&stline, &stlen, stfile); + fclose(stfile); + + batt_full = atoi(stline); + free(stline); + } + + stfile = fopen("/sys/class/power_supply/BAT0/current_now", "r"); + if (stfile != NULL) + { + stline = NULL; + stlen = getline(&stline, &stlen, stfile); + fclose(stfile); + + batt_current = atoi(stline); + free(stline); + } + + stfile = fopen("/sys/class/power_supply/BAT0/voltage_now", "r"); + if (stfile != NULL) + { + stline = NULL; + stlen = getline(&stline, &stlen, stfile); + fclose(stfile); + + batt_voltage = atoi(stline); + free(stline); + } + + // Hack for chinese battery. + //batt_now -= 27220000; + //batt_full = 27000000; + + if (batt_full > 0) + batt_percent = batt_now / (batt_full / 100); + + if (batt_percent <= 40) // 40 + { + if (batt_percent <= 25) // 25 + { + if (batt_percent <= 10) // 10 + fputs("^fg(red)", stdout); + else // 11-25% + fputs("^fg(orange)", stdout); + } + else // 26-40% + fputs("^fg(yellow)", stdout); + } + else + { + if (batt_percent > 70) // 70 + fputs("^fg(white)", stdout); + else // 41-70% + fputs("^fg(green)", stdout); + } + + batt_time = (float)batt_now / (float)batt_current; + batt_watts = ((float)batt_voltage / 1000000) * ((float)batt_current / 10000000); + + if (batt_watts == 0) // fully charged and on AC + printf(" BAT0: %d%% _ _ ", batt_percent); + else + printf(" BAT0: %d%% %.1fh %.1fW ", batt_percent, batt_time, batt_watts); + + //fputs(" Power status ", stdout); +} diff --git a/statuses/power.h b/statuses/power.h new file mode 100644 index 0000000..db06166 --- /dev/null +++ b/statuses/power.h @@ -0,0 +1,7 @@ + +#ifndef __POWER_H__ +#define __POWER_H__ + +void status_power(); + +#endif diff --git a/statuses/temp.c b/statuses/temp.c new file mode 100644 index 0000000..83e1ac9 --- /dev/null +++ b/statuses/temp.c @@ -0,0 +1,31 @@ +#include +#include +#include +#include "temp.h" + +void status_temp(char *title, char *sysfile) +{ + char stline[16]; + int stfile; + size_t stlen; + + stfile = open(sysfile, 0); + if (stfile != -1) + { + stlen = read(stfile, stline, sizeof(stline)); + close(stfile); + if (stlen >= 6 && stlen <= 7) + { + 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); + } + else + printf(" ^fg(red)%sERROR ", title); + } +} diff --git a/statuses/temp.h b/statuses/temp.h new file mode 100644 index 0000000..0856a17 --- /dev/null +++ b/statuses/temp.h @@ -0,0 +1,7 @@ + +#ifndef __TEMP_H__ +#define __TEMP_H__ + +void status_temp(char *title, char *sysfile); + +#endif diff --git a/statuses/tools.c b/statuses/tools.c new file mode 100644 index 0000000..1e0385d --- /dev/null +++ b/statuses/tools.c @@ -0,0 +1,24 @@ +#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 '?'; +} diff --git a/statuses/tools.h b/statuses/tools.h new file mode 100644 index 0000000..1b9f344 --- /dev/null +++ b/statuses/tools.h @@ -0,0 +1,7 @@ + +#ifndef __TOOLS_H__ +#define __TOOLS_H__ + +char powertochar(int power); + +#endif diff --git a/statuses/uptime.c b/statuses/uptime.c new file mode 100644 index 0000000..8db1c45 --- /dev/null +++ b/statuses/uptime.c @@ -0,0 +1,53 @@ +#include +#include +#include +#include +#include "uptime.h" + +void status_uptime() +{ + char stline[16]; + int stfile; + size_t stlen; + int i; + int upts, uptm, upth, uptd; + + stfile = open("/proc/uptime", 0); + if (stfile != -1) + { + stlen = read(stfile, stline, sizeof(stline)); + close(stfile); + + for(i = 0; i < stlen; i++) + if (stline[i] == ' ') + stline[i] = '\0'; + + 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); + + fputs(" ^fg(#AAAAAA)up: ", stdout); + + if (uptd > 0) + printf("%dd ", uptd); + + printf("%d:%.2d" + + #ifdef SHOW_SECONDS + ":%.2d" + #endif + + " " + ,upth + ,uptm + + #ifdef SHOW_SECONDS + ,upts + #endif + ); + } +} diff --git a/statuses/uptime.h b/statuses/uptime.h new file mode 100644 index 0000000..153f35d --- /dev/null +++ b/statuses/uptime.h @@ -0,0 +1,7 @@ + +#ifndef __UPTIME_H__ +#define __UPTIME_H__ + +void status_uptime(); + +#endif diff --git a/statuses/volume_alsa.c b/statuses/volume_alsa.c new file mode 100644 index 0000000..0b1546a --- /dev/null +++ b/statuses/volume_alsa.c @@ -0,0 +1,63 @@ +#include +#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; +} diff --git a/statuses/volume_alsa.h b/statuses/volume_alsa.h new file mode 100644 index 0000000..044824d --- /dev/null +++ b/statuses/volume_alsa.h @@ -0,0 +1,9 @@ + +#ifndef __VOLUME_ALSA_H__ +#define __VOLUME_ALSA_H__ + +#include + +int status_volume_alsa(char *cardname, char *mixername, snd_mixer_selem_channel_id_t channel); + +#endif diff --git a/sysstatus.c b/sysstatus.c new file mode 100644 index 0000000..835f865 --- /dev/null +++ b/sysstatus.c @@ -0,0 +1,66 @@ +#include +#include +#include +#include +//#include +//#include +//#include +//#include +//#include +#include "statuses/uptime.h" +#include "statuses/memusage.h" +#include "statuses/cpuusage.h" +#include "statuses/netif.h" +#include "statuses/netif_named.h" +#include "statuses/power.h" +#include "statuses/volume_alsa.h" +#include "statuses/temp.h" +#include "statuses/datetime.h" +#include "config.h" + +void updatestatus() +{ + //status_uptime(); + + status_cpuusage(); + + status_power(); + + status_memusage(); + + //status_netif(); + status_netif_named("eth0"); + status_netif_named("eth1"); + status_netif_named("wlan0"); + status_netif_named("wlan1"); + status_netif_named("ppp0"); + + status_temp("GPU: ", "/sys/class/hwmon/hwmon0/device/temp4_input"); + status_temp("CPU: ", "/sys/class/hwmon/hwmon0/device/temp2_input"); + + status_volume_alsa("default", "Master", 0); + + status_datetime(); + + fputs("\n", stdout); + fflush(stdout); +} + +int main() +{ + struct timeval tv; + + updatestatus(); + + for(;;) + { + tv.tv_sec = UPDATE_SECS; + tv.tv_usec = 0; + + select(0, NULL, NULL, NULL, &tv); + + updatestatus(); + } + + return 0; +}