summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authornorly <ny-git@enpas.org>2013-02-15 01:19:41 +0000
committernorly <ny-git@enpas.org>2013-02-15 01:30:22 +0000
commit430ce2a8749eb90ca0f8cdf18f5b217128c43e79 (patch)
tree8c838780bda4c7ebf4f778ca307f01b2d39bdfbe /src
parent2ddbfa53a31360e50565345a1ac08c0799c8243e (diff)
Better file structure and build system
Also fix some warnings
Diffstat (limited to 'src')
-rw-r--r--src/status/battery.c104
-rw-r--r--src/status/cpuusage.c91
-rw-r--r--src/status/datetime.c36
-rw-r--r--src/status/fan.c29
-rw-r--r--src/status/memusage.c51
-rw-r--r--src/status/netif.c80
-rw-r--r--src/status/temp.c36
-rw-r--r--src/status/uptime.c59
-rw-r--r--src/status/volume_alsa.c71
-rw-r--r--src/sysstatus.c65
-rw-r--r--src/tools/tools.c60
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;
+}