sites

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs

commit a81aa8b06f3b1b076e592772255303bcc507a8db
parent 9b14e95c80e952c160203ff7b3cf368c6f66ba9a
Author: Thuban <thuban@singularity.fr>
Date:   Sat, 30 Mar 2013 15:53:56 +0100

Add dynamic_info.c

Diffstat:
Adwm.suckless.org/dwmstatus/dynamic_info.c | 436+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Mdwm.suckless.org/dwmstatus/index.md | 3+++
2 files changed, 439 insertions(+), 0 deletions(-)

diff --git a/dwm.suckless.org/dwmstatus/dynamic_info.c b/dwm.suckless.org/dwmstatus/dynamic_info.c @@ -0,0 +1,436 @@ +#define _BSD_SOURCE +#define _GNU_SOURCE +#include <unistd.h> +#include <stdio.h> +#include <stdlib.h> +#include <stdarg.h> +#include <string.h> +#include <strings.h> +#include <sys/time.h> +#include <time.h> +#include <sys/types.h> +#include <dirent.h> +#include <sys/statvfs.h> + + +#include <X11/Xlib.h> + +char *tzparis = "Europe/Paris"; + +static Display *dpy; + +char * +smprintf(char *fmt, ...) +{ + va_list fmtargs; + char *buf = NULL; + + va_start(fmtargs, fmt); + if (vasprintf(&buf, fmt, fmtargs) == -1){ + fprintf(stderr, "malloc vasprintf\n"); + exit(1); + } + va_end(fmtargs); + + return buf; +} + +char* +runcmd(char* cmd) { + FILE* fp = popen(cmd, "r"); + if (fp == NULL) return NULL; + char ln[50]; + fgets(ln, sizeof(ln)-1, fp); + pclose(fp); + ln[strlen(ln)-1]='\0'; + return smprintf("%s", ln); +} + +void +settz(char *tzname) +{ + setenv("TZ", tzname, 1); +} + +char * +mktimes(char *fmt, char *tzname) +{ + char buf[129]; + time_t tim; + struct tm *timtm; + + memset(buf, 0, sizeof(buf)); + settz(tzname); + tim = time(NULL); + timtm = localtime(&tim); + if (timtm == NULL) { + perror("localtime"); + exit(1); + } + + if (!strftime(buf, sizeof(buf)-1, fmt, timtm)) { + fprintf(stderr, "strftime == 0\n"); + exit(1); + } + + return smprintf(buf); +} + +void +setstatus(char *str) +{ + XStoreName(dpy, DefaultRootWindow(dpy), str); + XSync(dpy, False); +} + +char * +loadavg(void) +{ + double avgs[3]; + + if (getloadavg(avgs, 3) < 0) { + perror("getloadavg"); + exit(1); + } + + return smprintf("%.2f %.2f %.2f", avgs[0], avgs[1], avgs[2]); +} + +int +getvolume() { + int volume; + sscanf(runcmd("amixer | grep -A 6 Master | grep 'Mono: Playback'\ + | grep -o '[0-9%]*%'"), "%i%%", &volume); + return volume; + +} + +char * +getmpdstat() { + return runcmd("/home/xavier/.Scripts/xfcebar.sh"); + +} + +char * +readfile(char *base, char *file) +{ + char *path, line[513]; + FILE *fd; + + memset(line, 0, sizeof(line)); + + path = smprintf("%s/%s", base, file); + fd = fopen(path, "r"); + if (fd == NULL) + return NULL; + free(path); + + if (fgets(line, sizeof(line)-1, fd) == NULL) + return NULL; + fclose(fd); + + return smprintf("%s", line); +} + + +char * +tmpinfo() +{ + /* usr path as a buffer for any text */ + char *path = "/tmp/dwmbuf"; + char line[255]; + char *toprint = NULL; + FILE *fin; + FILE *fout; + int c = 0; + + fin = fopen(path, "r"); + if (fin == NULL) + return(smprintf("%s"," ")); + + fout = fopen("/tmp/.dwmbuf.tmp", "w"); + if (fout == NULL) + { + fclose(fin); + return(smprintf("%s"," ")); + } + + while (fgets(line, sizeof(line), fin)) + { + if (c == 0) + line[strlen(line)-1]='\0'; + toprint = smprintf("%s",line); + if (c > 0) + fputs(line, fout); + c += 1; + } + + fclose(fin); + fclose(fout); + + rename("/tmp/.dwmbuf.tmp", path); + + if (toprint != NULL) + return(smprintf("%s",toprint)); + else + return(smprintf("%s"," ")); +} + +/* + * Linux seems to change the filenames after suspend/hibernate + * according to a random scheme. So just check for both possibilities. + */ +char * +getbattery(char *base) +{ + char *co; + int descap, remcap; + + descap = -1; + remcap = -1; + + co = readfile(base, "present"); + if (co == NULL || co[0] != '1') { + if (co != NULL) free(co); + return smprintf("?"); + } + free(co); + + co = readfile(base, "charge_full_design"); + if (co == NULL) { + co = readfile(base, "energy_full_design"); + if (co == NULL) + return smprintf(""); + } + sscanf(co, "%d", &descap); + free(co); + + co = readfile(base, "charge_now"); + if (co == NULL) { + co = readfile(base, "energy_now"); + if (co == NULL) + return smprintf(""); + } + sscanf(co, "%d", &remcap); + free(co); + + if (remcap < 0 || descap < 0) + return smprintf("invalid"); + + return smprintf("%.0f", ((float)remcap / (float)descap) * 100); +} + +int +parse_netdev(unsigned long long int *receivedabs, unsigned long long int *sentabs) +{ + char *buf; + char *eth0start; + static int bufsize; + FILE *devfd; + + buf = (char *) calloc(255, 1); + bufsize = 255; + devfd = fopen("/proc/net/dev", "r"); + + // ignore the first two lines of the file + fgets(buf, bufsize, devfd); + fgets(buf, bufsize, devfd); + + while (fgets(buf, bufsize, devfd)) { + if ((eth0start = strstr(buf, "wlan0:")) != NULL) { + + // With thanks to the conky project at http://conky.sourceforge.net/ + sscanf(eth0start + 6, "%llu %*d %*d %*d %*d %*d %*d %*d %llu",\ + receivedabs, sentabs); + fclose(devfd); + free(buf); + return 0; + } + } + fclose(devfd); + free(buf); + return 1; +} + +char * +get_netusage() +{ + unsigned long long int oldrec, oldsent, newrec, newsent; + double downspeed, upspeed; + char *downspeedstr, *upspeedstr; + char *retstr; + int retval; + + downspeedstr = (char *) malloc(15); + upspeedstr = (char *) malloc(15); + retstr = (char *) malloc(42); + + retval = parse_netdev(&oldrec, &oldsent); + if (retval) { + fprintf(stdout, "Error when parsing /proc/net/dev file.\n"); + exit(1); + } + + sleep(1); + retval = parse_netdev(&newrec, &newsent); + if (retval) { + fprintf(stdout, "Error when parsing /proc/net/dev file.\n"); + exit(1); + } + + downspeed = (newrec - oldrec) / 1024.0; + if (downspeed > 1024.0) { + downspeed /= 1024.0; + sprintf(downspeedstr, "%.3f MB/s", downspeed); + } else { + sprintf(downspeedstr, "%.2f KB/s", downspeed); + } + + upspeed = (newsent - oldsent) / 1024.0; + if (upspeed > 1024.0) { + upspeed /= 1024.0; + sprintf(upspeedstr, "%.3f MB/s", upspeed); + } else { + sprintf(upspeedstr, "%.2f KB/s", upspeed); + } + sprintf(retstr, "D: %s U: %s", downspeedstr, upspeedstr); + + free(downspeedstr); + free(upspeedstr); + return retstr; +} + +char *get_nmail(char *directory, char *label) +{ + /* directory : Maildir path + * return label : number_of_new_mails + */ + + int n = 0; + DIR* dir = NULL; + struct dirent* rf = NULL; + + dir = opendir(directory); /* try to open directory */ + if (dir == NULL) + perror(""); + + while ((rf = readdir(dir)) != NULL) /*count number of file*/ + { + if (strcmp(rf->d_name, ".") != 0 && + strcmp(rf->d_name, "..") != 0) + n++; + } + closedir(dir); + + if (n == 0) + return smprintf(""); + else + return smprintf("%s%d",label, n); + +} + +int runevery(time_t *ltime, int sec){ + /* return 1 if sec elapsed since last run + * else return 0 + */ + time_t now = time(NULL); + + if ( difftime(now, *ltime ) >= sec) + { + *ltime = now; + return(1); + } + else + return(0); +} + +char *get_freespace(char *mntpt){ + struct statvfs data; + double total, used = 0; + + if ( (statvfs(mntpt, &data)) < 0){ + fprintf(stderr, "can't get info on disk.\n"); + return("?"); + } + total = (data.f_blocks * data.f_frsize); + used = (data.f_blocks - data.f_bfree) * data.f_frsize ; + return(smprintf("%.1f", (used/total*100))); +} + + +int +main(void) +{ + char *status = NULL; + char *avgs = NULL; + char *tmprs = NULL; + char *bat = NULL; + //char *netstats = NULL; + char *mail_laposte = NULL; + char *mail_fac = NULL; + char *mail_lavabit = NULL; + char *mail_tl = NULL; + char *rootfs = NULL; + char *homefs = NULL; + time_t count5min = 0; + time_t count60 = 0; + time_t count5 = 0; + int volume = 0; + char *mpd = NULL; + char *info = NULL; + + if (!(dpy = XOpenDisplay(NULL))) { + fprintf(stderr, "dwmstatus: cannot open display.\n"); + return 1; + } + + for (;;sleep(1)) { + /* checks every minutes */ + if ( runevery(&count60, 60) ) + { + free(tmprs); + free(bat); + free(info); + tmprs = mktimes("%d/%m/%y %H:%M", tzparis); + bat = getbattery("/sys/class/power_supply/BAT0/"); + info = tmpinfo(); + } + if (runevery(&count5, 5)){ + free(homefs); + free(rootfs); + homefs = get_freespace("/home"); + rootfs = get_freespace("/"); + } + /* checks mail every 5 minutes */ + if (runevery(&count5min, 300) ) + { + free(mail_laposte); + free(mail_fac); + free(mail_lavabit); + free(mail_tl); + mail_laposte = get_nmail("/home/xavier/Maildir/fac/new", " Fac:"); + mail_fac = get_nmail("/home/xavier/Maildir/lavabit/new", " Lavabit:"); + mail_lavabit = get_nmail("/home/xavier/Maildir/toilelibre/new", " TL:"); + mail_tl = get_nmail("/home/xavier/Maildir/laposte/new", " Laposte:"); + } + /* checks every second */ + avgs = loadavg(); + //netstats = get_netusage(); + volume = getvolume(); + mpd = getmpdstat(); + + status = smprintf("%s %s %s%s%s%s | /:%s% /home:%s% | B:%s% | %s | V:%i%% | %s", + info, mpd, + mail_tl, mail_fac, mail_lavabit, mail_laposte, + rootfs, homefs, bat, avgs, volume, tmprs); + setstatus(status); + free(avgs); + free(mpd); + free(status); + } + + XCloseDisplay(dpy); + + return 0; +} + diff --git a/dwm.suckless.org/dwmstatus/index.md b/dwm.suckless.org/dwmstatus/index.md @@ -36,6 +36,9 @@ add them here as file or as code example. * [Counting number of mails in a Maildir/new](mail_counter.c) * [Get disk usage and execute some check at different moments](diskspace_timechk.c) : Because you don't want to check new mails every second * [Detecting Man-In-The-Middle](dwmstatus-mitm.c) +* [Show line per line the content of a file](dynamic_info.c) : See + tmpinfo function. It prints line after line the content of + /tmp/dwmbuf. Questions ---------