diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/status/battery.c | 104 | ||||
-rw-r--r-- | src/status/cpuusage.c | 91 | ||||
-rw-r--r-- | src/status/datetime.c | 36 | ||||
-rw-r--r-- | src/status/fan.c | 29 | ||||
-rw-r--r-- | src/status/memusage.c | 51 | ||||
-rw-r--r-- | src/status/netif.c | 80 | ||||
-rw-r--r-- | src/status/temp.c | 36 | ||||
-rw-r--r-- | src/status/uptime.c | 59 | ||||
-rw-r--r-- | src/status/volume_alsa.c | 71 | ||||
-rw-r--r-- | src/sysstatus.c | 65 | ||||
-rw-r--r-- | src/tools/tools.c | 60 |
11 files changed, 682 insertions, 0 deletions
diff --git a/src/status/battery.c b/src/status/battery.c new file mode 100644 index 0000000..34bfcc0 --- /dev/null +++ b/src/status/battery.c @@ -0,0 +1,104 @@ +#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); + } +} diff --git a/src/status/cpuusage.c b/src/status/cpuusage.c new file mode 100644 index 0000000..1bb34ae --- /dev/null +++ b/src/status/cpuusage.c @@ -0,0 +1,91 @@ +#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); +} diff --git a/src/status/datetime.c b/src/status/datetime.c new file mode 100644 index 0000000..a25d411 --- /dev/null +++ b/src/status/datetime.c @@ -0,0 +1,36 @@ +#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 + ); +} diff --git a/src/status/fan.c b/src/status/fan.c new file mode 100644 index 0000000..0e7cfdf --- /dev/null +++ b/src/status/fan.c @@ -0,0 +1,29 @@ +#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); +} diff --git a/src/status/memusage.c b/src/status/memusage.c new file mode 100644 index 0000000..6a6cb21 --- /dev/null +++ b/src/status/memusage.c @@ -0,0 +1,51 @@ +#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); + } +} diff --git a/src/status/netif.c b/src/status/netif.c new file mode 100644 index 0000000..23e6520 --- /dev/null +++ b/src/status/netif.c @@ -0,0 +1,80 @@ +#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)); +} diff --git a/src/status/temp.c b/src/status/temp.c new file mode 100644 index 0000000..e6763d0 --- /dev/null +++ b/src/status/temp.c @@ -0,0 +1,36 @@ +#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); +} diff --git a/src/status/uptime.c b/src/status/uptime.c new file mode 100644 index 0000000..106051c --- /dev/null +++ b/src/status/uptime.c @@ -0,0 +1,59 @@ +#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 + ); +} diff --git a/src/status/volume_alsa.c b/src/status/volume_alsa.c new file mode 100644 index 0000000..41f61b8 --- /dev/null +++ b/src/status/volume_alsa.c @@ -0,0 +1,71 @@ +#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; +} diff --git a/src/sysstatus.c b/src/sysstatus.c new file mode 100644 index 0000000..bbc945b --- /dev/null +++ b/src/sysstatus.c @@ -0,0 +1,65 @@ +#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; +} diff --git a/src/tools/tools.c b/src/tools/tools.c new file mode 100644 index 0000000..abb8a0d --- /dev/null +++ b/src/tools/tools.c @@ -0,0 +1,60 @@ +#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; +} |