sites

public wiki contents of suckless.org
git clone git://git.suckless.org/sites
Log | Files | Refs

commit 891ec00535c38bec3cfca595e94dec27f1e785d3
parent 1771eed85a7b3bc1e518d8307f64c4481b455128
Author: Aaron Marcher <me@drkhsh.at>
Date:   Fri, 18 May 2018 11:14:11 +0200

Rename status to status monitor

Diffstat:
dwm.suckless.org/status/barM.c | 108-------------------------------------------------------------------------------
dwm.suckless.org/status/batterystatus.c | 53-----------------------------------------------------
dwm.suckless.org/status/diskspace_timechk.c | 353-------------------------------------------------------------------------------
dwm.suckless.org/status/dwmclock-netstat.c | 140-------------------------------------------------------------------------------
dwm.suckless.org/status/dwmstatus-mitm.c | 136-------------------------------------------------------------------------------
dwm.suckless.org/status/dwmstatus-netusage.c | 207-------------------------------------------------------------------------------
dwm.suckless.org/status/dwmstatus-temperature.c | 15---------------
dwm.suckless.org/status/dynamic_info.c | 436-------------------------------------------------------------------------------
dwm.suckless.org/status/fifo.c | 50--------------------------------------------------
dwm.suckless.org/status/getvol.c | 40----------------------------------------
dwm.suckless.org/status/index.md | 61-------------------------------------------------------------
dwm.suckless.org/status/mail_counter.c | 100-------------------------------------------------------------------------------
dwm.suckless.org/status/mpdstatus.c | 57---------------------------------------------------------
dwm.suckless.org/status/new-acpi-battery.c | 65-----------------------------------------------------------------
dwm.suckless.org/status/profil-dwmstatus-1.0.c | 128-------------------------------------------------------------------------------
dwm.suckless.org/status/scripts/basic_collection/index.md | 9---------
dwm.suckless.org/status/scripts/email_notifier_script/index.md | 62--------------------------------------------------------------
dwm.suckless.org/status/scripts/simple_monitors/index.md | 46----------------------------------------------
dwm.suckless.org/status/uptime.c | 153-------------------------------------------------------------------------------
dwm.suckless.org/status_monitor/barM.c | 108+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
dwm.suckless.org/status_monitor/batterystatus.c | 53+++++++++++++++++++++++++++++++++++++++++++++++++++++
dwm.suckless.org/status_monitor/diskspace_timechk.c | 353+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
dwm.suckless.org/status_monitor/dwmclock-netstat.c | 140+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
dwm.suckless.org/status_monitor/dwmstatus-mitm.c | 136+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
dwm.suckless.org/status_monitor/dwmstatus-netusage.c | 207+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
dwm.suckless.org/status_monitor/dwmstatus-temperature.c | 15+++++++++++++++
dwm.suckless.org/status_monitor/dynamic_info.c | 436+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
dwm.suckless.org/status_monitor/fifo.c | 50++++++++++++++++++++++++++++++++++++++++++++++++++
dwm.suckless.org/status_monitor/getvol.c | 40++++++++++++++++++++++++++++++++++++++++
dwm.suckless.org/status_monitor/index.md | 61+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
dwm.suckless.org/status_monitor/mail_counter.c | 100+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
dwm.suckless.org/status_monitor/mpdstatus.c | 57+++++++++++++++++++++++++++++++++++++++++++++++++++++++++
dwm.suckless.org/status_monitor/new-acpi-battery.c | 65+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
dwm.suckless.org/status_monitor/profil-dwmstatus-1.0.c | 128+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
dwm.suckless.org/status_monitor/scripts/basic_collection/index.md | 9+++++++++
dwm.suckless.org/status_monitor/scripts/email_notifier_script/index.md | 62++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
dwm.suckless.org/status_monitor/scripts/simple_monitors/index.md | 46++++++++++++++++++++++++++++++++++++++++++++++
dwm.suckless.org/status_monitor/uptime.c | 153+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
38 files changed, 2219 insertions(+), 2219 deletions(-)

diff --git a/dwm.suckless.org/status/barM.c b/dwm.suckless.org/status/barM.c @@ -1,108 +0,0 @@ -/* - * Copyright (C) 2014,2015 levi0x0 with enhancements by ProgrammerNerd - * - * barM (bar_monitor or BarMonitor) is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This is a new version of bar monitor, even less lines of code more effective. - * - * Read main() to configure your new status Bar. - * - * compile: gcc -o barM barM.c -O2 -s -lX11 - * - * mv barM /usr/local/bin/ - */ - -#include <stdio.h> -#include <stdlib.h> -#include <time.h> -#include <string.h> -#include <stdarg.h> -#include <X11/Xlib.h> -#include <sys/utsname.h> -#include <sys/sysinfo.h> - -/* - * Put this in your .xinitrc file: - * - * barM& - * - */ - -#define VERSION "0.12" -#define TIME_FORMAT "%H:%M) (%d-%m-%Y" -#define MAXSTR 1024 - -static const char * date(void); -static const char * getuname(void); -static const char * ram(void); -static void XSetRoot(const char *name); -/*Append here your functions.*/ -static const char*(*const functab[])(void)={ - ram,date -}; - -int main(void){ - char status[MAXSTR]; - /* It is foolish to repeatedly update uname. */ - int ret; - {struct utsname u; - if(uname(&u)){ - perror("uname failed"); - return 1; - } - ret=snprintf(status,sizeof(status),"(%s %s %s) ",u.sysname,u.nodename,u.release);} - char*off=status+ret; - if(off>=(status+MAXSTR)){ - XSetRoot(status); - return 1;/*This should not happen*/ - } - for(;;){ - int left=sizeof(status)-ret,i; - char*sta=off; - for(i = 0; i<sizeof(functab)/sizeof(functab[0]); ++i ) { - int ret=snprintf(sta,left,"(%s) ",functab[i]()); - sta+=ret; - left-=ret; - if(sta>=(status+MAXSTR))/*When snprintf has to resort to truncating a string it will return the length as if it were not truncated.*/ - break; - } - XSetRoot(status); - sleep(1); - } - return 0; -} - -/* Returns the date*/ -static const char * date(void){ - static char date[MAXSTR]; - time_t now = time(0); - - strftime(date, MAXSTR, TIME_FORMAT, localtime(&now)); - return date; -} -/* Returns a string that contains the amount of free and available ram in megabytes*/ -static const char * ram(void){ - static char ram[MAXSTR]; - struct sysinfo s; - sysinfo(&s); - snprintf(ram,sizeof(ram),"%.1fM,%.1fM",((double)(s.totalram-s.freeram))/1048576.,((double)s.totalram)/1048576.); - return ram; -} - -static void XSetRoot(const char *name){ - Display *display; - - if (( display = XOpenDisplay(0x0)) == NULL ) { - fprintf(stderr, "[barM] cannot open display!\n"); - exit(1); - } - - XStoreName(display, DefaultRootWindow(display), name); - XSync(display, 0); - - XCloseDisplay(display); -} - diff --git a/dwm.suckless.org/status/batterystatus.c b/dwm.suckless.org/status/batterystatus.c @@ -1,53 +0,0 @@ -#define BATT_NOW "/sys/class/power_supply/BAT0/charge_now" -#define BATT_FULL "/sys/class/power_supply/BAT0/charge_full" -#define BATT_STATUS "/sys/class/power_supply/BAT0/status" - -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <errno.h> - -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 * -getbattery(){ - long lnum1, lnum2 = 0; - char *status = malloc(sizeof(char)*12); - char s = '?'; - FILE *fp = NULL; - if ((fp = fopen(BATT_NOW, "r"))) { - fscanf(fp, "%ld\n", &lnum1); - fclose(fp); - fp = fopen(BATT_FULL, "r"); - fscanf(fp, "%ld\n", &lnum2); - fclose(fp); - fp = fopen(BATT_STATUS, "r"); - fscanf(fp, "%s\n", status); - fclose(fp); - if (strcmp(status,"Charging") == 0) - s = '+'; - if (strcmp(status,"Discharging") == 0) - s = '-'; - if (strcmp(status,"Full") == 0) - s = '='; - return smprintf("%c%ld%%", s,(lnum1/(lnum2/100))); - } - else return smprintf(""); -} - - - diff --git a/dwm.suckless.org/status/diskspace_timechk.c b/dwm.suckless.org/status/diskspace_timechk.c @@ -1,353 +0,0 @@ -#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; -} - -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]); -} - -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); -} - -/* - * 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("%.0f", (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; - - 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(rootfs); - free(homefs); - tmprs = mktimes("%d/%m/%y %H:%M", tzparis); - bat = getbattery("/sys/class/power_supply/BAT0/"); - 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(); - - status = smprintf("%s%s%s%s | %s | /:%s% /home:%s% | B:%s% | %s | %s", - mail_tl, mail_fac, mail_lavabit, mail_laposte, - netstats, rootfs, homefs, bat, avgs, tmprs); - setstatus(status); - free(avgs); - free(netstats); - free(status); - } - - XCloseDisplay(dpy); - - return 0; -} - diff --git a/dwm.suckless.org/status/dwmclock-netstat.c b/dwm.suckless.org/status/dwmclock-netstat.c @@ -1,140 +0,0 @@ -#include <X11/Xlib.h> -#include <X11/Xatom.h> -#include <time.h> -#include <locale.h> -#include <unistd.h> -#include <stdio.h> -#include <sys/types.h> -#include <sys/stat.h> -#include <fcntl.h> -#include <string.h> -#include <stdint.h> -#include <inttypes.h> -#include <math.h> - -#define IFNAMSIZ 16 - - -static const char* determine_def_if(void) { - FILE *f; - const char* ret = 0; - static char buf[IFNAMSIZ]; - char filebuf[256]; - f = fopen("/proc/net/route", "r"); - if (f) { - while (fgets(filebuf, sizeof filebuf, f)) { - char *tab = strchr(filebuf, '\t'); - if (tab && !strncmp(tab + 1, "00000000", 8)) { - memcpy(buf, filebuf, tab - filebuf); - buf[tab - filebuf] = 0; - ret = buf; - break; - } - } - fclose(f); - } - return ret; -} - -static uint64_t readfile(const char* filename) { - FILE* f; - uint64_t ret = 0, tmp; - f = fopen(filename, "r"); - if (f) { - if (fscanf(f, "%"SCNu64, &tmp) == 1) - ret = tmp; - fclose(f); - } - return ret; -} - -static uint64_t get_rx_bytes(const char* interface) -{ - char fnbuf[sizeof "/sys/class/net//statistics/rx_bytes" + IFNAMSIZ]; - strcpy(fnbuf, "/sys/class/net/"); - strcat(fnbuf, interface); - strcat(fnbuf, "/statistics/rx_bytes"); - return readfile(fnbuf); -} - -static uint64_t get_tx_bytes(const char* interface) -{ - char fnbuf[sizeof "/sys/class/net//statistics/rx_bytes" + IFNAMSIZ]; - strcpy(fnbuf, "/sys/class/net/"); - strcat(fnbuf, interface); - strcat(fnbuf, "/statistics/tx_bytes"); - return readfile(fnbuf); -} - -static int get_suff(uint64_t x) -{ - int r = -1 + !x; - while (x) { - r++; - x >>= 10; - } - return r; -} - -int main(void) { - Display *dpy; - Window root; - int loadfd; - - setlocale(LC_ALL, ""); - dpy = XOpenDisplay(0); - if (dpy) { - struct timespec tm, s; - ssize_t rv; - char oldif[IFNAMSIZ] = {0}; - uint64_t rxb, txb; - static const char suffixes[] = " KMGT"; // let's stay real here - root = XDefaultRootWindow(dpy); - clock_gettime(CLOCK_REALTIME, &tm); - s.tv_sec = 0; - s.tv_nsec = 1000000000 - tm.tv_nsec; - do rv = nanosleep(&s, &s); - while (rv == -1 && s.tv_nsec); - for (;;) { - char buf[100]; // estimate - const char *thisif = determine_def_if(); - uint64_t currxb, curtxb; - int idx; - int i; - if (thisif) - { - if (strcmp(thisif, oldif)) - { - strcpy(oldif, thisif); - rxb = txb = 0; - } - i = 0; - buf[i++] = oldif[0]; - buf[i++] = ' '; - buf[i++] = 'v'; - currxb = get_rx_bytes(oldif); - curtxb = get_tx_bytes(oldif); - idx = get_suff(currxb - rxb); - i += snprintf(buf + i, sizeof buf - i, "%.1f%c", (double)(currxb - rxb) / pow(1024, idx), suffixes[idx]); - rxb = currxb; - buf[i++] = ' '; - buf[i++] = '^'; - idx = get_suff(curtxb - txb); - i += snprintf(buf + i, sizeof buf - i, "%.1f%c", (double)(curtxb - txb) / pow(1024, idx), suffixes[idx]); - txb = curtxb; - } - else - buf[i++] = 'n'; - buf[i++] = ' '; - buf[i++] = '|'; - buf[i++] = ' '; - time_t t; - size_t l; - t = time(0); - l = strftime(buf + i, sizeof buf - i, "%c", localtime(&t)); - XStoreName(dpy, root, buf); - XSync(dpy, False); - sleep(1); - } - } -} diff --git a/dwm.suckless.org/status/dwmstatus-mitm.c b/dwm.suckless.org/status/dwmstatus-mitm.c @@ -1,136 +0,0 @@ -/* Here is a helper function that warns you if someone tries to sniff your - * network traffic (i.e. a Man-In-The-Middle attack ran against you thanks - * to ARP cache poisoning). - * - * It must be called regularly because it monitors changes in the ARP table - * If a host got a new MAC address, it will alert during ALERT_TIMEOUT seconds. - * If the MAC address remains the same, it assumes it is just a new host. - * Otherwise, if it keep changing, it will keep on alerting. - * - * Returns true on success, false otherwise. - * - * Written by vladz (vladz AT devzero.fr). - * Updated by mephesto1337 ( dwm-status AT junk-mail.fr ) - */ - -#include <arpa/inet.h> -#include <linux/if_ether.h> -#include <netinet/in.h> -#include <stdbool.h> -#include <stdint.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <time.h> - - -// Some useful macros -#define CHK(expr, cond) \ - do { \ - if ( (expr) cond ) { \ - fprintf(stderr, "%s failed", #expr); \ - goto fail; \ - } \ - } while ( 0 ) - -#define CHK_NEG(expr) CHK((long)(expr), < 0L) -#define CHK_FALSE(expr) CHK(!!(expr), == false) -#define CHK_NULL(expr) CHK(expr, == NULL) -#define SAFE_FREE(func, ptr) \ - do { \ - if ( ptr != NULL ) { \ - func(ptr); \ - } \ - ptr = NULL; \ - } while ( 0 ) -#define ARRAY_SIZE(x) (sizeof(x) / sizeof(x[0])) - -#define ALERT_TIMEOUT ((time_t)40L) // In seconds - -/* The hard maximum number of entries kept in the ARP cache is obtained via - * "sysctl net.ipv4.neigh.default.gc_thresh3" (see arp(7)). Default value - * for Linux is 1024. - */ -#define MAX_ARP_CACHE_ENTRIES 1024 - - -struct ether_ip_s { - union { - uint8_t mac[ETH_ALEN]; - unsigned long lmac; - }; - time_t last_changed; - in_addr_t ip; -}; - -struct ether_ip_s table[MAX_ARP_CACHE_ENTRIES]; -size_t table_size = 0; - - -bool lookup_and_insert(const struct ether_ip_s *new); - -bool check_arp_table(char *message, size_t len) { - FILE *f; - struct ether_ip_s tmp; - char ip_address[32]; - char mac_address[32]; - - snprintf(message, len, "ARP table OK"); - CHK_NULL(f = fopen("/proc/net/arp", "r")); - time(&tmp.last_changed); - fscanf(f, "%*[^\n]\n"); - while ( !feof(f) ) { - CHK(fscanf(f, "%s%*[ ]0x%*x%*[ ]0x%*x%*[ ]%[a-f0-9:]%*[^\n]\n", ip_address, mac_address), != 2); - CHK_NEG(inet_pton(AF_INET, ip_address, &tmp.ip)); - - tmp.lmac = 0UL; - CHK(sscanf( - mac_address, "%02hhx:%02hhx:%02hhx:%02hhx:%02hhx:%02hhx", - &tmp.mac[0], &tmp.mac[1], &tmp.mac[2], &tmp.mac[3], &tmp.mac[4], &tmp.mac[5] - ), != 6); - - if ( ! lookup_and_insert(&tmp) ) { - snprintf(message, len, "Possible MITM attack, please check %s", ip_address); - break; - } - } - SAFE_FREE(fclose, f); - return true; - - fail: - SAFE_FREE(fclose, f); - snprintf(message, len, "ARP table ???"); - return false; -} - -bool lookup_and_insert(const struct ether_ip_s *new) { - for ( size_t i = 0; i < table_size; i++ ) { - if ( table[i].ip == new->ip ) { - if ( table[i].lmac != new->lmac ) { - if ( table[i].last_changed + ALERT_TIMEOUT > new->last_changed ) { - return false; - } else { - // Update the DB, it must be a new host - table[i].lmac = new->lmac; - table[i].last_changed = new->last_changed; - return true; - } - } else { - // Update last seen - table[i].last_changed = new->last_changed; - return true; - } - } - } - - if ( table_size < ARRAY_SIZE(table) ) { - memcpy(&table[table_size], new, sizeof(struct ether_ip_s)); - table_size++; - } else { - // To big, let's restart from the begining - table_size = 0; - return false; - } - - return true; -} diff --git a/dwm.suckless.org/status/dwmstatus-netusage.c b/dwm.suckless.org/status/dwmstatus-netusage.c @@ -1,207 +0,0 @@ -#define _BSD_SOURCE -#include <unistd.h> -#include <stdbool.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 <sys/wait.h> - -#include <X11/Xlib.h> - -char *tzargentina = "America/Buenos_Aires"; -char *tzutc = "UTC"; -char *tzberlin = "Europe/Berlin"; - -static Display *dpy; - -char * -smprintf(char *fmt, ...) -{ - va_list fmtargs; - char *ret; - int len; - - va_start(fmtargs, fmt); - len = vsnprintf(NULL, 0, fmt, fmtargs); - va_end(fmtargs); - - ret = malloc(++len); - if (ret == NULL) { - perror("malloc"); - exit(1); - } - - va_start(fmtargs, fmt); - vsnprintf(ret, len, fmt, fmtargs); - va_end(fmtargs); - - return ret; -} - -void -settz(char *tzname) -{ - setenv("TZ", tzname, 1); -} - -int -parse_netdev(unsigned long long int *receivedabs, unsigned long long int *sentabs) -{ - char buf[255]; - char *datastart; - static int bufsize; - int rval; - FILE *devfd; - unsigned long long int receivedacc, sentacc; - - bufsize = 255; - devfd = fopen("/proc/net/dev", "r"); - rval = 1; - - // Ignore the first two lines of the file - fgets(buf, bufsize, devfd); - fgets(buf, bufsize, devfd); - - while (fgets(buf, bufsize, devfd)) { - if ((datastart = strstr(buf, "lo:")) == NULL) { - datastart = strstr(buf, ":"); - - // With thanks to the conky project at http://conky.sourceforge.net/ - sscanf(datastart + 1, "%llu %*d %*d %*d %*d %*d %*d %*d %llu",\ - &receivedacc, &sentacc); - *receivedabs += receivedacc; - *sentabs += sentacc; - rval = 0; - } - } - - fclose(devfd); - return rval; -} - -void -calculate_speed(char *speedstr, unsigned long long int newval, unsigned long long int oldval) -{ - double speed; - speed = (newval - oldval) / 1024.0; - if (speed > 1024.0) { - speed /= 1024.0; - sprintf(speedstr, "%.3f MB/s", speed); - } else { - sprintf(speedstr, "%.2f KB/s", speed); - } -} - -char * -get_netusage(unsigned long long int *rec, unsigned long long int *sent) -{ - unsigned long long int newrec, newsent; - newrec = newsent = 0; - char downspeedstr[15], upspeedstr[15]; - static char retstr[42]; - int retval; - - retval = parse_netdev(&newrec, &newsent); - if (retval) { - fprintf(stdout, "Error when parsing /proc/net/dev file.\n"); - exit(1); - } - - calculate_speed(downspeedstr, newrec, *rec); - calculate_speed(upspeedstr, newsent, *sent); - - sprintf(retstr, "down: %s up: %s", downspeedstr, upspeedstr); - - *rec = newrec; - *sent = newsent; - return retstr; -} - -char * -mktimes(char *fmt, char *tzname) -{ - char buf[129]; - time_t tim; - struct tm *timtm; - - bzero(buf, 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("%s", 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 -main(void) -{ - char *status; - char *avgs; - char *tmar; - char *tmutc; - char *tmbln; - char *netstats; - static unsigned long long int rec, sent; - - if (!(dpy = XOpenDisplay(NULL))) { - fprintf(stderr, "dwmstatus: cannot open display.\n"); - return 1; - } - - parse_netdev(&rec, &sent); - for (;;sleep(1)) { - avgs = loadavg(); - tmar = mktimes("%H:%M", tzargentina); - tmutc = mktimes("%H:%M", tzutc); - tmbln = mktimes("KW %W %a %d %b %H:%M %Z %Y", tzberlin); - netstats = get_netusage(&rec, &sent); - - status = smprintf("[L: %s|N: %s|A: %s|U: %s|%s]", - avgs, netstats, tmar, tmutc, tmbln); - setstatus(status); - free(avgs); - free(tmar); - free(tmutc); - free(tmbln); - free(status); - } - - XCloseDisplay(dpy); - - return 0; -} - diff --git a/dwm.suckless.org/status/dwmstatus-temperature.c b/dwm.suckless.org/status/dwmstatus-temperature.c @@ -1,15 +0,0 @@ -/* - * gettemperature("/sys/class/hwmon/hwmon0/device", "temp1_input"); - */ - -char * -gettemperature(char *base, char *sensor) -{ - char *co; - - co = readfile(base, sensor); - if (co == NULL) - return smprintf(""); - return smprintf("%02.0f°C", atof(co) / 1000); -} - diff --git a/dwm.suckless.org/status/dynamic_info.c b/dwm.suckless.org/status/dynamic_info.c @@ -1,436 +0,0 @@ -#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/status/fifo.c b/dwm.suckless.org/status/fifo.c @@ -1,50 +0,0 @@ -/* - * send anything in dwm status bar with fifo - * example : echo "hello" >> /tmp/dwm.fifo - * Author: Xavier Cartron (XC), thuban@yeuxdelibad.net -*/ - -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <fcntl.h> -#include <sys/types.h> -#include <sys/stat.h> - -#define FIFO "/tmp/dwm.fifo" - -char * -snotif() -{ - char buf[BUFSIZ]; - int len = 0; - - int f = open(FIFO, O_NONBLOCK | O_RDWR); - if (f == -1){ - return smprintf("%s",""); - } - - len = read(f, buf, sizeof(buf)); - if (len == -1){ - perror("fifo read"); - close(f); - return smprintf("%s",""); - } - close(f); - - buf[len-1] = ' '; - - return smprintf("%s",buf); -} - -int -main(void) -{ - int ret = 0; - ret = mkfifo(FIFO, ACCESSPERMS); - if (ret == -1) perror("fifo creation"); - - // your code - - return 0; -} diff --git a/dwm.suckless.org/status/getvol.c b/dwm.suckless.org/status/getvol.c @@ -1,40 +0,0 @@ -/* include this into your dwmstatus.c and use get_vol() as volume. - * if your audio card and subunit numbers differ from 0,0 you might havo - * to use amixer, aplay and the /proc/asound file tree to adapt. - * - * I had compilation issues. As result i had to drop the -std=c99 and - * -pedantic flags from the config.mk - */ - -#include <alsa/asoundlib.h> -#include <alsa/control.h> - -int -get_vol(void) -{ - int vol; - snd_hctl_t *hctl; - snd_ctl_elem_id_t *id; - snd_ctl_elem_value_t *control; - -// To find card and subdevice: /proc/asound/, aplay -L, amixer controls - snd_hctl_open(&hctl, "hw:0", 0); - snd_hctl_load(hctl); - - snd_ctl_elem_id_alloca(&id); - snd_ctl_elem_id_set_interface(id, SND_CTL_ELEM_IFACE_MIXER); - -// amixer controls - snd_ctl_elem_id_set_name(id, "Master Playback Volume"); - - snd_hctl_elem_t *elem = snd_hctl_find_elem(hctl, id); - - snd_ctl_elem_value_alloca(&control); - snd_ctl_elem_value_set_id(control, id); - - snd_hctl_elem_read(elem, control); - vol = (int)snd_ctl_elem_value_get_integer(control,0); - - snd_hctl_close(hctl); - return vol; -} diff --git a/dwm.suckless.org/status/index.md b/dwm.suckless.org/status/index.md @@ -1,61 +0,0 @@ -status -====== - -The status bar text of **dwm** is stored in the WM_NAME X11 property of the -root window, which is managed by dwm. - -It can be easily set and retrieved using standard Unix tools. - - xsetroot -name $status - - xprop -root -notype -f WM_NAME "8u" \ - | sed -n -r 's/WM_NAME = \"(.*)\"/\1/p' - -Using shell scripts very well leads to big scripts, which pull in unneeded -dependencies. One solution for this is to write everything in C, which is much -more efficient. - -slstatus - suckless status --------------------------- - -General purpose status monitor for dwm and other window managers for Linux and -OpenBSD written in C for maxium efficiency. - -You can read more [on the project page](https://tools.suckless.org/slstatus/). - -User submitted versions ------------------------ - -Please add your own version of dwmstatus here (keeping the list sorted). - -* [barM](barM.c) - can display all, time/date, ram usage, output of commands (the New BarMonitor). -* [dstat](https://www.umaxx.net/dl) [Screenshot](https://www.umaxx.net/dstat.png) - displays the current network throughput, CPU usage, performance settings, battery status, temperature, volume settings, as well as the current date and time (OpenBSD only, no support for Linux). -* [dwms](https://github.com/ianremmler/dwms) - displays time, network, audio, and battery status, written in Go using XGB. -* [dwmsd](https://github.com/johnko/dwmsd) - a daemon that listens on localhost tcp (may be useful as a base for asynchronous updates) -* [dwmstat](https://notabug.org/kl3/dwmstat) - small and simple | IP, CPU temperature, system volume, current local time (and more) | config.h | OpenBSD -* [go-dwmstatus](https://github.com/oniichaNj/go-dwmstatus) - A Go bar that prints current MPD song, load averages, time/date and battery percentage. -* [gods](https://github.com/schachmat/gods) - implemented in Go. prints network speed, cpu, ram, date/time -* [profil-dwmstatus-1.0.c](profil-dwmstatus-1.0.c) - cpufreq, battery percent and date/time -* [suspend-statusbar.c](https://github.com/snobb/dwm-statusbar) - date, loadavg, battery and more. If battery goes below threshold - run suspend command - -Helper functions ----------------- - -If you have simple C functions for gathering system information, please -add them here (keeping the list sorted). - -* [ACPI battery status on Linux](new-acpi-battery.c) -* [Battery on Linux](batterystatus.c): Battery percentage and status. + if - charging, - if discharging, = if full. -* [Detecting Man-In-The-Middle](dwmstatus-mitm.c) -* [Disk usage and execute some check at different moments](diskspace_timechk.c) -* [FIFO info](fifo.c): Replaces dynamic_info. -* [Line per line the content of a file](dynamic_info.c): See - tmpinfo function. It prints line after line the content of - /tmp/dwmbuf. -* [MPD title/artist](mpdstatus.c) -* [Number of new mails in a Maildir](mail_counter.c) -* [Temperature from /sys on Linux](dwmstatus-temperature.c) -* [Uptime](uptime.c) -* [Up-, and downspeeds of all network interfaces from /proc/net on Linux](dwmstatus-netusage.c) -* [Volume via ALSA API](getvol.c) diff --git a/dwm.suckless.org/status/mail_counter.c b/dwm.suckless.org/status/mail_counter.c @@ -1,100 +0,0 @@ -// Fichier: dwmstatus.c -// Crée le 10 déc. 2012 22:28:11 -// Dernière modification: 21 déc. 2012 16:25:16 - -#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 <sys/wait.h> -#include <dirent.h> - -#include <X11/Xlib.h> - -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; -} - -void -setstatus(char *str) -{ - XStoreName(dpy, DefaultRootWindow(dpy), str); - XSync(dpy, False); -} - -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 -main(void) -{ - char *status; - char *newmails; - - if (!(dpy = XOpenDisplay(NULL))) { - fprintf(stderr, "dwmstatus: cannot open display.\n"); - return 1; - } - - for (;;sleep(60)) { - newmails = get_nmail("/home/xavier/Maildir/laposte/new", "Mails:"); - - - status = smprintf("%s",newmails); - setstatus(status); - free(newmails); - free(status); - } - - XCloseDisplay(dpy); - - return 0; -} - diff --git a/dwm.suckless.org/status/mpdstatus.c b/dwm.suckless.org/status/mpdstatus.c @@ -1,57 +0,0 @@ -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <mpd/client.h> - -/* add to config.mk : -# mpd -+ MPDLIB = -lmpdclient -+ MPDFLAG = -DMPD - -- LIBS = -L/usr/lib -lc -L${X11LIB} -lX11 -+ LIBS = -L/usr/lib -lc -L${X11LIB} -lX11 ${MPDLIB} - -- CPPFLAGS = -DVERSION=\"${VERSION}\" -+ CPPFLAGS = ${MPDFLAG} -DVERSION=\"${VERSION}\" -*/ -/* simple function to retrieve mpd status */ -char * -getmpdstat() { - struct mpd_song * song = NULL; - const char * title = NULL; - const char * artist = NULL; - char * retstr = NULL; - int elapsed = 0, total = 0; - struct mpd_connection * conn ; - if (!(conn = mpd_connection_new("localhost", 0, 30000)) || - mpd_connection_get_error(conn)){ - return smprintf(""); - } - - mpd_command_list_begin(conn, true); - mpd_send_status(conn); - mpd_send_current_song(conn); - mpd_command_list_end(conn); - - struct mpd_status* theStatus = mpd_recv_status(conn); - if ((theStatus) && (mpd_status_get_state(theStatus) == MPD_STATE_PLAY)) { - mpd_response_next(conn); - song = mpd_recv_song(conn); - title = smprintf("%s",mpd_song_get_tag(song, MPD_TAG_TITLE, 0)); - artist = smprintf("%s",mpd_song_get_tag(song, MPD_TAG_ARTIST, 0)); - - elapsed = mpd_status_get_elapsed_time(theStatus); - total = mpd_status_get_total_time(theStatus); - mpd_song_free(song); - retstr = smprintf("%.2d:%.2d/%.2d:%.2d %s - %s", - elapsed/60, elapsed%60, - total/60, total%60, - artist, title); - free((char*)title); - free((char*)artist); - } - else retstr = smprintf(""); - mpd_response_finish(conn); - mpd_connection_free(conn); - return retstr; -} diff --git a/dwm.suckless.org/status/new-acpi-battery.c b/dwm.suckless.org/status/new-acpi-battery.c @@ -1,65 +0,0 @@ -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); -} - -/* - * 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("not present"); - } - 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); -} - diff --git a/dwm.suckless.org/status/profil-dwmstatus-1.0.c b/dwm.suckless.org/status/profil-dwmstatus-1.0.c @@ -1,128 +0,0 @@ -/* made by profil 2011-12-29. -** -** Compile with: -** gcc -Wall -pedantic -std=c99 -lX11 status.c -*/ -#include <stdio.h> -#include <stdlib.h> -#include <unistd.h> -#include <time.h> -#include <X11/Xlib.h> - -static Display *dpy; - -void setstatus(char *str) { - XStoreName(dpy, DefaultRootWindow(dpy), str); - XSync(dpy, False); -} - -float getfreq(char *file) { - FILE *fd; - char *freq; - float ret; - - freq = malloc(10); - fd = fopen(file, "r"); - if(fd == NULL) { - fprintf(stderr, "Cannot open '%s' for reading.\n", file); - exit(1); - } - - fgets(freq, 10, fd); - fclose(fd); - - ret = atof(freq)/1000000; - free(freq); - return ret; -} - -char *getdatetime() { - char *buf; - time_t result; - struct tm *resulttm; - - if((buf = malloc(sizeof(char)*65)) == NULL) { - fprintf(stderr, "Cannot allocate memory for buf.\n"); - exit(1); - } - result = time(NULL); - resulttm = localtime(&result); - if(resulttm == NULL) { - fprintf(stderr, "Error getting localtime.\n"); - exit(1); - } - if(!strftime(buf, sizeof(char)*65-1, "%a %b %d %H:%M:%S", resulttm)) { - fprintf(stderr, "strftime is 0.\n"); - exit(1); - } - - return buf; -} - -float getbattery() { - FILE *fd; - int energy_now, energy_full, voltage_now; - - fd = fopen("/sys/class/power_supply/BAT0/energy_now", "r"); - if(fd == NULL) { - fprintf(stderr, "Error opening energy_now.\n"); - return -1; - } - fscanf(fd, "%d", &energy_now); - fclose(fd); - - - fd = fopen("/sys/class/power_supply/BAT0/energy_full", "r"); - if(fd == NULL) { - fprintf(stderr, "Error opening energy_full.\n"); - return -1; - } - fscanf(fd, "%d", &energy_full); - fclose(fd); - - - fd = fopen("/sys/class/power_supply/BAT0/voltage_now", "r"); - if(fd == NULL) { - fprintf(stderr, "Error opening voltage_now.\n"); - return -1; - } - fscanf(fd, "%d", &voltage_now); - fclose(fd); - - - return ((float)energy_now * 1000 / (float)voltage_now) * 100 / ((float)energy_full * 1000 / (float)voltage_now); -} - -int main(void) { - char *status; - float cpu0, cpu1; - char *datetime; - int bat0; - - - if (!(dpy = XOpenDisplay(NULL))) { - fprintf(stderr, "Cannot open display.\n"); - return 1; - } - - if((status = malloc(200)) == NULL) - exit(1); - - - for (;;sleep(1)) { - cpu0 = getfreq("/sys/devices/system/cpu/cpu0/cpufreq/scaling_cur_freq"); - cpu1 = getfreq("/sys/devices/system/cpu/cpu1/cpufreq/scaling_cur_freq"); - datetime = getdatetime(); - bat0 = getbattery(); - snprintf(status, 200, "%0.2f, %0.2f | %.2lf%% | %s", cpu0, cpu1, bat0, datetime); - - free(datetime); - setstatus(status); - } - - free(status); - XCloseDisplay(dpy); - - return 0; -} - diff --git a/dwm.suckless.org/status/scripts/basic_collection/index.md b/dwm.suckless.org/status/scripts/basic_collection/index.md @@ -1,9 +0,0 @@ -Scripts collection -================== - -Description ------------ - -A basic collection of simple, fully POSIX sh compliant scripts to get various -system information among other useful things can be found at kl3's [scripts](https://notabug.org/kl3/scripts) -repository. Feel free to copy, adapt and/or improve them. diff --git a/dwm.suckless.org/status/scripts/email_notifier_script/index.md b/dwm.suckless.org/status/scripts/email_notifier_script/index.md @@ -1,62 +0,0 @@ -email notifier script -===================== - -Description ------------ - -This init script is based on some ideas taken from the dwm ML. It adds email -notification using `fetchmail`. It also adds the functionality of showing the -content of the file `$HOME/.message` when it exists. This can be used for -displaying info by other programs writing to this file. - -When a new email arrives a flashing text message is shown on the dwm's -status bar. - -Config .fetchmailrc -------------------- -This config works with GMail over IMAP with the IDLE extension for low bandwidth usage: - - poll imap.gmail.com port 993 proto IMAP user "<your_user>@gmail.com" - there with password "<your_pass>" keep ssl idle - -Init script ------------ - -The notification is flashing during 60 seconds, then it is removed. Lines -written to `.message` are displayed during a second in the status bar. If -`.message` is deleted, the normal status message (date and uptime) returns. - -A pipe must be used with `fetchmail` when using IDLE extension because this way -it waits for updates from the inbox not doing polling. -If the `.message` file exists with some content, it is preserved and no email -notification is shown. - - fetchmail --check 2>/dev/null | while read line; do - new=`echo $line | sed 's/(//' | awk '{print $1-$3}'` - if [ $new != 0 ] && [ ! -e ~/.message ]; then - echo "New mail($new)" > ~/.message - echo "!!! !!! !!!" >> ~/.message - sleep 60 - if grep '^New mail' ~/.message >/dev/null 2>/dev/null; then - rm -f ~/.message - fi - fi - done & - while true; do - if [ -r ~/.message ]; then - while read line; do - xsetroot -name "$line" - sleep 1 - done < ~/.message - else - xsetroot -name "`date` `uptime | sed 's/.*,//'`" - sleep 1 - fi - done & - exec dwm - rm -f ~/.message - -Author ------- - -- Ricardo Catalinas Jiménez <[jimenezrick@gmail.com](mailto:jimenezrick@gmail.com)> diff --git a/dwm.suckless.org/status/scripts/simple_monitors/index.md b/dwm.suckless.org/status/scripts/simple_monitors/index.md @@ -1,46 +0,0 @@ -Simple Monitors -=== - -Description ---- - -These are just very simple monitors for the dwm status bar. - -Battery ---- - -Your battery may be called something different, so check /proc/acpi for its name. Also, change 89000 to whatever the capacity is for your battery. -This returns the remaining battery power as a percentage. - - $(echo $(awk '/rem/ { print $3/89000 }' /proc/acpi/battery/BAT0/state| hoc| cut -c3,4)% - -hoc comes from plan9port or 9base. - -Depending on your system, you can also use - - cat /sys/class/power_supply/BAT0/capacity - -to get your battery status in percentage. - -Ram used ---- - -Return the amount of ram used, in megabytes. - - $(free -m |awk '/cache:/ { print $3"M" }') - -Temperature ---- - -Returns the temperature of the cpu, in celcius. - - $(awk '{ print $2 }' /proc/acpi/thermal_zone/THM0/temperature)C - -Volume ---- - - amixer get Front | tail -n1 | awk '{ print $5 }' | tr -d [] - -Change "Front" to your audio device - -I told you they were simple. diff --git a/dwm.suckless.org/status/uptime.c b/dwm.suckless.org/status/uptime.c @@ -1,153 +0,0 @@ -#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 <sys/sysinfo.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; -} - -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]); -} - - -char * -up() { - struct sysinfo info; - int h,m = 0; - sysinfo(&info); - h = info.uptime/3600; - m = (info.uptime - h*3600 )/60; - return smprintf("%dh%dm",h,m); -} - - -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); -} - -int -main(void) -{ - char *status = NULL; - char *tmprs = NULL; - char *avgs = NULL; - time_t count60 = 0; - char *uptm = 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(uptm); - tmprs = mktimes("%d/%m/%y %H:%M", tzparis); - uptm = up(); - } - /* checks every second */ - avgs = loadavg(); - - status = smprintf("%s | Up:%s | %s", - avgs, uptm, tmprs); - setstatus(status); - free(avgs); - free(status); - } - - XCloseDisplay(dpy); - - return 0; -} - diff --git a/dwm.suckless.org/status_monitor/barM.c b/dwm.suckless.org/status_monitor/barM.c @@ -0,0 +1,108 @@ +/* + * Copyright (C) 2014,2015 levi0x0 with enhancements by ProgrammerNerd + * + * barM (bar_monitor or BarMonitor) is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This is a new version of bar monitor, even less lines of code more effective. + * + * Read main() to configure your new status Bar. + * + * compile: gcc -o barM barM.c -O2 -s -lX11 + * + * mv barM /usr/local/bin/ + */ + +#include <stdio.h> +#include <stdlib.h> +#include <time.h> +#include <string.h> +#include <stdarg.h> +#include <X11/Xlib.h> +#include <sys/utsname.h> +#include <sys/sysinfo.h> + +/* + * Put this in your .xinitrc file: + * + * barM& + * + */ + +#define VERSION "0.12" +#define TIME_FORMAT "%H:%M) (%d-%m-%Y" +#define MAXSTR 1024 + +static const char * date(void); +static const char * getuname(void); +static const char * ram(void); +static void XSetRoot(const char *name); +/*Append here your functions.*/ +static const char*(*const functab[])(void)={ + ram,date +}; + +int main(void){ + char status[MAXSTR]; + /* It is foolish to repeatedly update uname. */ + int ret; + {struct utsname u; + if(uname(&u)){ + perror("uname failed"); + return 1; + } + ret=snprintf(status,sizeof(status),"(%s %s %s) ",u.sysname,u.nodename,u.release);} + char*off=status+ret; + if(off>=(status+MAXSTR)){ + XSetRoot(status); + return 1;/*This should not happen*/ + } + for(;;){ + int left=sizeof(status)-ret,i; + char*sta=off; + for(i = 0; i<sizeof(functab)/sizeof(functab[0]); ++i ) { + int ret=snprintf(sta,left,"(%s) ",functab[i]()); + sta+=ret; + left-=ret; + if(sta>=(status+MAXSTR))/*When snprintf has to resort to truncating a string it will return the length as if it were not truncated.*/ + break; + } + XSetRoot(status); + sleep(1); + } + return 0; +} + +/* Returns the date*/ +static const char * date(void){ + static char date[MAXSTR]; + time_t now = time(0); + + strftime(date, MAXSTR, TIME_FORMAT, localtime(&now)); + return date; +} +/* Returns a string that contains the amount of free and available ram in megabytes*/ +static const char * ram(void){ + static char ram[MAXSTR]; + struct sysinfo s; + sysinfo(&s); + snprintf(ram,sizeof(ram),"%.1fM,%.1fM",((double)(s.totalram-s.freeram))/1048576.,((double)s.totalram)/1048576.); + return ram; +} + +static void XSetRoot(const char *name){ + Display *display; + + if (( display = XOpenDisplay(0x0)) == NULL ) { + fprintf(stderr, "[barM] cannot open display!\n"); + exit(1); + } + + XStoreName(display, DefaultRootWindow(display), name); + XSync(display, 0); + + XCloseDisplay(display); +} + diff --git a/dwm.suckless.org/status_monitor/batterystatus.c b/dwm.suckless.org/status_monitor/batterystatus.c @@ -0,0 +1,53 @@ +#define BATT_NOW "/sys/class/power_supply/BAT0/charge_now" +#define BATT_FULL "/sys/class/power_supply/BAT0/charge_full" +#define BATT_STATUS "/sys/class/power_supply/BAT0/status" + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <errno.h> + +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 * +getbattery(){ + long lnum1, lnum2 = 0; + char *status = malloc(sizeof(char)*12); + char s = '?'; + FILE *fp = NULL; + if ((fp = fopen(BATT_NOW, "r"))) { + fscanf(fp, "%ld\n", &lnum1); + fclose(fp); + fp = fopen(BATT_FULL, "r"); + fscanf(fp, "%ld\n", &lnum2); + fclose(fp); + fp = fopen(BATT_STATUS, "r"); + fscanf(fp, "%s\n", status); + fclose(fp); + if (strcmp(status,"Charging") == 0) + s = '+'; + if (strcmp(status,"Discharging") == 0) + s = '-'; + if (strcmp(status,"Full") == 0) + s = '='; + return smprintf("%c%ld%%", s,(lnum1/(lnum2/100))); + } + else return smprintf(""); +} + + + diff --git a/dwm.suckless.org/status_monitor/diskspace_timechk.c b/dwm.suckless.org/status_monitor/diskspace_timechk.c @@ -0,0 +1,353 @@ +#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; +} + +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]); +} + +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); +} + +/* + * 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("%.0f", (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; + + 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(rootfs); + free(homefs); + tmprs = mktimes("%d/%m/%y %H:%M", tzparis); + bat = getbattery("/sys/class/power_supply/BAT0/"); + 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(); + + status = smprintf("%s%s%s%s | %s | /:%s% /home:%s% | B:%s% | %s | %s", + mail_tl, mail_fac, mail_lavabit, mail_laposte, + netstats, rootfs, homefs, bat, avgs, tmprs); + setstatus(status); + free(avgs); + free(netstats); + free(status); + } + + XCloseDisplay(dpy); + + return 0; +} + diff --git a/dwm.suckless.org/status_monitor/dwmclock-netstat.c b/dwm.suckless.org/status_monitor/dwmclock-netstat.c @@ -0,0 +1,140 @@ +#include <X11/Xlib.h> +#include <X11/Xatom.h> +#include <time.h> +#include <locale.h> +#include <unistd.h> +#include <stdio.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> +#include <string.h> +#include <stdint.h> +#include <inttypes.h> +#include <math.h> + +#define IFNAMSIZ 16 + + +static const char* determine_def_if(void) { + FILE *f; + const char* ret = 0; + static char buf[IFNAMSIZ]; + char filebuf[256]; + f = fopen("/proc/net/route", "r"); + if (f) { + while (fgets(filebuf, sizeof filebuf, f)) { + char *tab = strchr(filebuf, '\t'); + if (tab && !strncmp(tab + 1, "00000000", 8)) { + memcpy(buf, filebuf, tab - filebuf); + buf[tab - filebuf] = 0; + ret = buf; + break; + } + } + fclose(f); + } + return ret; +} + +static uint64_t readfile(const char* filename) { + FILE* f; + uint64_t ret = 0, tmp; + f = fopen(filename, "r"); + if (f) { + if (fscanf(f, "%"SCNu64, &tmp) == 1) + ret = tmp; + fclose(f); + } + return ret; +} + +static uint64_t get_rx_bytes(const char* interface) +{ + char fnbuf[sizeof "/sys/class/net//statistics/rx_bytes" + IFNAMSIZ]; + strcpy(fnbuf, "/sys/class/net/"); + strcat(fnbuf, interface); + strcat(fnbuf, "/statistics/rx_bytes"); + return readfile(fnbuf); +} + +static uint64_t get_tx_bytes(const char* interface) +{ + char fnbuf[sizeof "/sys/class/net//statistics/rx_bytes" + IFNAMSIZ]; + strcpy(fnbuf, "/sys/class/net/"); + strcat(fnbuf, interface); + strcat(fnbuf, "/statistics/tx_bytes"); + return readfile(fnbuf); +} + +static int get_suff(uint64_t x) +{ + int r = -1 + !x; + while (x) { + r++; + x >>= 10; + } + return r; +} + +int main(void) { + Display *dpy; + Window root; + int loadfd; + + setlocale(LC_ALL, ""); + dpy = XOpenDisplay(0); + if (dpy) { + struct timespec tm, s; + ssize_t rv; + char oldif[IFNAMSIZ] = {0}; + uint64_t rxb, txb; + static const char suffixes[] = " KMGT"; // let's stay real here + root = XDefaultRootWindow(dpy); + clock_gettime(CLOCK_REALTIME, &tm); + s.tv_sec = 0; + s.tv_nsec = 1000000000 - tm.tv_nsec; + do rv = nanosleep(&s, &s); + while (rv == -1 && s.tv_nsec); + for (;;) { + char buf[100]; // estimate + const char *thisif = determine_def_if(); + uint64_t currxb, curtxb; + int idx; + int i; + if (thisif) + { + if (strcmp(thisif, oldif)) + { + strcpy(oldif, thisif); + rxb = txb = 0; + } + i = 0; + buf[i++] = oldif[0]; + buf[i++] = ' '; + buf[i++] = 'v'; + currxb = get_rx_bytes(oldif); + curtxb = get_tx_bytes(oldif); + idx = get_suff(currxb - rxb); + i += snprintf(buf + i, sizeof buf - i, "%.1f%c", (double)(currxb - rxb) / pow(1024, idx), suffixes[idx]); + rxb = currxb; + buf[i++] = ' '; + buf[i++] = '^'; + idx = get_suff(curtxb - txb); + i += snprintf(buf + i, sizeof buf - i, "%.1f%c", (double)(curtxb - txb) / pow(1024, idx), suffixes[idx]); + txb = curtxb; + } + else + buf[i++] = 'n'; + buf[i++] = ' '; + buf[i++] = '|'; + buf[i++] = ' '; + time_t t; + size_t l; + t = time(0); + l = strftime(buf + i, sizeof buf - i, "%c", localtime(&t)); + XStoreName(dpy, root, buf); + XSync(dpy, False); + sleep(1); + } + } +} diff --git a/dwm.suckless.org/status_monitor/dwmstatus-mitm.c b/dwm.suckless.org/status_monitor/dwmstatus-mitm.c @@ -0,0 +1,136 @@ +/* Here is a helper function that warns you if someone tries to sniff your + * network traffic (i.e. a Man-In-The-Middle attack ran against you thanks + * to ARP cache poisoning). + * + * It must be called regularly because it monitors changes in the ARP table + * If a host got a new MAC address, it will alert during ALERT_TIMEOUT seconds. + * If the MAC address remains the same, it assumes it is just a new host. + * Otherwise, if it keep changing, it will keep on alerting. + * + * Returns true on success, false otherwise. + * + * Written by vladz (vladz AT devzero.fr). + * Updated by mephesto1337 ( dwm-status AT junk-mail.fr ) + */ + +#include <arpa/inet.h> +#include <linux/if_ether.h> +#include <netinet/in.h> +#include <stdbool.h> +#include <stdint.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <time.h> + + +// Some useful macros +#define CHK(expr, cond) \ + do { \ + if ( (expr) cond ) { \ + fprintf(stderr, "%s failed", #expr); \ + goto fail; \ + } \ + } while ( 0 ) + +#define CHK_NEG(expr) CHK((long)(expr), < 0L) +#define CHK_FALSE(expr) CHK(!!(expr), == false) +#define CHK_NULL(expr) CHK(expr, == NULL) +#define SAFE_FREE(func, ptr) \ + do { \ + if ( ptr != NULL ) { \ + func(ptr); \ + } \ + ptr = NULL; \ + } while ( 0 ) +#define ARRAY_SIZE(x) (sizeof(x) / sizeof(x[0])) + +#define ALERT_TIMEOUT ((time_t)40L) // In seconds + +/* The hard maximum number of entries kept in the ARP cache is obtained via + * "sysctl net.ipv4.neigh.default.gc_thresh3" (see arp(7)). Default value + * for Linux is 1024. + */ +#define MAX_ARP_CACHE_ENTRIES 1024 + + +struct ether_ip_s { + union { + uint8_t mac[ETH_ALEN]; + unsigned long lmac; + }; + time_t last_changed; + in_addr_t ip; +}; + +struct ether_ip_s table[MAX_ARP_CACHE_ENTRIES]; +size_t table_size = 0; + + +bool lookup_and_insert(const struct ether_ip_s *new); + +bool check_arp_table(char *message, size_t len) { + FILE *f; + struct ether_ip_s tmp; + char ip_address[32]; + char mac_address[32]; + + snprintf(message, len, "ARP table OK"); + CHK_NULL(f = fopen("/proc/net/arp", "r")); + time(&tmp.last_changed); + fscanf(f, "%*[^\n]\n"); + while ( !feof(f) ) { + CHK(fscanf(f, "%s%*[ ]0x%*x%*[ ]0x%*x%*[ ]%[a-f0-9:]%*[^\n]\n", ip_address, mac_address), != 2); + CHK_NEG(inet_pton(AF_INET, ip_address, &tmp.ip)); + + tmp.lmac = 0UL; + CHK(sscanf( + mac_address, "%02hhx:%02hhx:%02hhx:%02hhx:%02hhx:%02hhx", + &tmp.mac[0], &tmp.mac[1], &tmp.mac[2], &tmp.mac[3], &tmp.mac[4], &tmp.mac[5] + ), != 6); + + if ( ! lookup_and_insert(&tmp) ) { + snprintf(message, len, "Possible MITM attack, please check %s", ip_address); + break; + } + } + SAFE_FREE(fclose, f); + return true; + + fail: + SAFE_FREE(fclose, f); + snprintf(message, len, "ARP table ???"); + return false; +} + +bool lookup_and_insert(const struct ether_ip_s *new) { + for ( size_t i = 0; i < table_size; i++ ) { + if ( table[i].ip == new->ip ) { + if ( table[i].lmac != new->lmac ) { + if ( table[i].last_changed + ALERT_TIMEOUT > new->last_changed ) { + return false; + } else { + // Update the DB, it must be a new host + table[i].lmac = new->lmac; + table[i].last_changed = new->last_changed; + return true; + } + } else { + // Update last seen + table[i].last_changed = new->last_changed; + return true; + } + } + } + + if ( table_size < ARRAY_SIZE(table) ) { + memcpy(&table[table_size], new, sizeof(struct ether_ip_s)); + table_size++; + } else { + // To big, let's restart from the begining + table_size = 0; + return false; + } + + return true; +} diff --git a/dwm.suckless.org/status_monitor/dwmstatus-netusage.c b/dwm.suckless.org/status_monitor/dwmstatus-netusage.c @@ -0,0 +1,207 @@ +#define _BSD_SOURCE +#include <unistd.h> +#include <stdbool.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 <sys/wait.h> + +#include <X11/Xlib.h> + +char *tzargentina = "America/Buenos_Aires"; +char *tzutc = "UTC"; +char *tzberlin = "Europe/Berlin"; + +static Display *dpy; + +char * +smprintf(char *fmt, ...) +{ + va_list fmtargs; + char *ret; + int len; + + va_start(fmtargs, fmt); + len = vsnprintf(NULL, 0, fmt, fmtargs); + va_end(fmtargs); + + ret = malloc(++len); + if (ret == NULL) { + perror("malloc"); + exit(1); + } + + va_start(fmtargs, fmt); + vsnprintf(ret, len, fmt, fmtargs); + va_end(fmtargs); + + return ret; +} + +void +settz(char *tzname) +{ + setenv("TZ", tzname, 1); +} + +int +parse_netdev(unsigned long long int *receivedabs, unsigned long long int *sentabs) +{ + char buf[255]; + char *datastart; + static int bufsize; + int rval; + FILE *devfd; + unsigned long long int receivedacc, sentacc; + + bufsize = 255; + devfd = fopen("/proc/net/dev", "r"); + rval = 1; + + // Ignore the first two lines of the file + fgets(buf, bufsize, devfd); + fgets(buf, bufsize, devfd); + + while (fgets(buf, bufsize, devfd)) { + if ((datastart = strstr(buf, "lo:")) == NULL) { + datastart = strstr(buf, ":"); + + // With thanks to the conky project at http://conky.sourceforge.net/ + sscanf(datastart + 1, "%llu %*d %*d %*d %*d %*d %*d %*d %llu",\ + &receivedacc, &sentacc); + *receivedabs += receivedacc; + *sentabs += sentacc; + rval = 0; + } + } + + fclose(devfd); + return rval; +} + +void +calculate_speed(char *speedstr, unsigned long long int newval, unsigned long long int oldval) +{ + double speed; + speed = (newval - oldval) / 1024.0; + if (speed > 1024.0) { + speed /= 1024.0; + sprintf(speedstr, "%.3f MB/s", speed); + } else { + sprintf(speedstr, "%.2f KB/s", speed); + } +} + +char * +get_netusage(unsigned long long int *rec, unsigned long long int *sent) +{ + unsigned long long int newrec, newsent; + newrec = newsent = 0; + char downspeedstr[15], upspeedstr[15]; + static char retstr[42]; + int retval; + + retval = parse_netdev(&newrec, &newsent); + if (retval) { + fprintf(stdout, "Error when parsing /proc/net/dev file.\n"); + exit(1); + } + + calculate_speed(downspeedstr, newrec, *rec); + calculate_speed(upspeedstr, newsent, *sent); + + sprintf(retstr, "down: %s up: %s", downspeedstr, upspeedstr); + + *rec = newrec; + *sent = newsent; + return retstr; +} + +char * +mktimes(char *fmt, char *tzname) +{ + char buf[129]; + time_t tim; + struct tm *timtm; + + bzero(buf, 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("%s", 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 +main(void) +{ + char *status; + char *avgs; + char *tmar; + char *tmutc; + char *tmbln; + char *netstats; + static unsigned long long int rec, sent; + + if (!(dpy = XOpenDisplay(NULL))) { + fprintf(stderr, "dwmstatus: cannot open display.\n"); + return 1; + } + + parse_netdev(&rec, &sent); + for (;;sleep(1)) { + avgs = loadavg(); + tmar = mktimes("%H:%M", tzargentina); + tmutc = mktimes("%H:%M", tzutc); + tmbln = mktimes("KW %W %a %d %b %H:%M %Z %Y", tzberlin); + netstats = get_netusage(&rec, &sent); + + status = smprintf("[L: %s|N: %s|A: %s|U: %s|%s]", + avgs, netstats, tmar, tmutc, tmbln); + setstatus(status); + free(avgs); + free(tmar); + free(tmutc); + free(tmbln); + free(status); + } + + XCloseDisplay(dpy); + + return 0; +} + diff --git a/dwm.suckless.org/status_monitor/dwmstatus-temperature.c b/dwm.suckless.org/status_monitor/dwmstatus-temperature.c @@ -0,0 +1,15 @@ +/* + * gettemperature("/sys/class/hwmon/hwmon0/device", "temp1_input"); + */ + +char * +gettemperature(char *base, char *sensor) +{ + char *co; + + co = readfile(base, sensor); + if (co == NULL) + return smprintf(""); + return smprintf("%02.0f°C", atof(co) / 1000); +} + diff --git a/dwm.suckless.org/status_monitor/dynamic_info.c b/dwm.suckless.org/status_monitor/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/status_monitor/fifo.c b/dwm.suckless.org/status_monitor/fifo.c @@ -0,0 +1,50 @@ +/* + * send anything in dwm status bar with fifo + * example : echo "hello" >> /tmp/dwm.fifo + * Author: Xavier Cartron (XC), thuban@yeuxdelibad.net +*/ + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <fcntl.h> +#include <sys/types.h> +#include <sys/stat.h> + +#define FIFO "/tmp/dwm.fifo" + +char * +snotif() +{ + char buf[BUFSIZ]; + int len = 0; + + int f = open(FIFO, O_NONBLOCK | O_RDWR); + if (f == -1){ + return smprintf("%s",""); + } + + len = read(f, buf, sizeof(buf)); + if (len == -1){ + perror("fifo read"); + close(f); + return smprintf("%s",""); + } + close(f); + + buf[len-1] = ' '; + + return smprintf("%s",buf); +} + +int +main(void) +{ + int ret = 0; + ret = mkfifo(FIFO, ACCESSPERMS); + if (ret == -1) perror("fifo creation"); + + // your code + + return 0; +} diff --git a/dwm.suckless.org/status_monitor/getvol.c b/dwm.suckless.org/status_monitor/getvol.c @@ -0,0 +1,40 @@ +/* include this into your dwmstatus.c and use get_vol() as volume. + * if your audio card and subunit numbers differ from 0,0 you might havo + * to use amixer, aplay and the /proc/asound file tree to adapt. + * + * I had compilation issues. As result i had to drop the -std=c99 and + * -pedantic flags from the config.mk + */ + +#include <alsa/asoundlib.h> +#include <alsa/control.h> + +int +get_vol(void) +{ + int vol; + snd_hctl_t *hctl; + snd_ctl_elem_id_t *id; + snd_ctl_elem_value_t *control; + +// To find card and subdevice: /proc/asound/, aplay -L, amixer controls + snd_hctl_open(&hctl, "hw:0", 0); + snd_hctl_load(hctl); + + snd_ctl_elem_id_alloca(&id); + snd_ctl_elem_id_set_interface(id, SND_CTL_ELEM_IFACE_MIXER); + +// amixer controls + snd_ctl_elem_id_set_name(id, "Master Playback Volume"); + + snd_hctl_elem_t *elem = snd_hctl_find_elem(hctl, id); + + snd_ctl_elem_value_alloca(&control); + snd_ctl_elem_value_set_id(control, id); + + snd_hctl_elem_read(elem, control); + vol = (int)snd_ctl_elem_value_get_integer(control,0); + + snd_hctl_close(hctl); + return vol; +} diff --git a/dwm.suckless.org/status_monitor/index.md b/dwm.suckless.org/status_monitor/index.md @@ -0,0 +1,61 @@ +status monitor +============== + +The status bar text of **dwm** is stored in the WM_NAME X11 property of the +root window, which is managed by dwm. + +It can be easily set and retrieved using standard Unix tools. + + xsetroot -name $status + + xprop -root -notype -f WM_NAME "8u" \ + | sed -n -r 's/WM_NAME = \"(.*)\"/\1/p' + +Using shell scripts very well leads to big scripts, which pull in unneeded +dependencies. One solution for this is to write everything in C, which is much +more efficient. + +slstatus - suckless status +-------------------------- + +General purpose status monitor for dwm and other window managers for Linux and +OpenBSD written in C for maxium efficiency. + +You can read more [on the project page](https://tools.suckless.org/slstatus/). + +User submitted versions +----------------------- + +Please add your own version of dwmstatus here (keeping the list sorted). + +* [barM](barM.c) - can display all, time/date, ram usage, output of commands (the New BarMonitor). +* [dstat](https://www.umaxx.net/dl) [Screenshot](https://www.umaxx.net/dstat.png) - displays the current network throughput, CPU usage, performance settings, battery status, temperature, volume settings, as well as the current date and time (OpenBSD only, no support for Linux). +* [dwms](https://github.com/ianremmler/dwms) - displays time, network, audio, and battery status, written in Go using XGB. +* [dwmsd](https://github.com/johnko/dwmsd) - a daemon that listens on localhost tcp (may be useful as a base for asynchronous updates) +* [dwmstat](https://notabug.org/kl3/dwmstat) - small and simple | IP, CPU temperature, system volume, current local time (and more) | config.h | OpenBSD +* [go-dwmstatus](https://github.com/oniichaNj/go-dwmstatus) - A Go bar that prints current MPD song, load averages, time/date and battery percentage. +* [gods](https://github.com/schachmat/gods) - implemented in Go. prints network speed, cpu, ram, date/time +* [profil-dwmstatus-1.0.c](profil-dwmstatus-1.0.c) - cpufreq, battery percent and date/time +* [suspend-statusbar.c](https://github.com/snobb/dwm-statusbar) - date, loadavg, battery and more. If battery goes below threshold - run suspend command + +Helper functions +---------------- + +If you have simple C functions for gathering system information, please +add them here (keeping the list sorted). + +* [ACPI battery status on Linux](new-acpi-battery.c) +* [Battery on Linux](batterystatus.c): Battery percentage and status. + if + charging, - if discharging, = if full. +* [Detecting Man-In-The-Middle](dwmstatus-mitm.c) +* [Disk usage and execute some check at different moments](diskspace_timechk.c) +* [FIFO info](fifo.c): Replaces dynamic_info. +* [Line per line the content of a file](dynamic_info.c): See + tmpinfo function. It prints line after line the content of + /tmp/dwmbuf. +* [MPD title/artist](mpdstatus.c) +* [Number of new mails in a Maildir](mail_counter.c) +* [Temperature from /sys on Linux](dwmstatus-temperature.c) +* [Uptime](uptime.c) +* [Up-, and downspeeds of all network interfaces from /proc/net on Linux](dwmstatus-netusage.c) +* [Volume via ALSA API](getvol.c) diff --git a/dwm.suckless.org/status_monitor/mail_counter.c b/dwm.suckless.org/status_monitor/mail_counter.c @@ -0,0 +1,100 @@ +// Fichier: dwmstatus.c +// Crée le 10 déc. 2012 22:28:11 +// Dernière modification: 21 déc. 2012 16:25:16 + +#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 <sys/wait.h> +#include <dirent.h> + +#include <X11/Xlib.h> + +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; +} + +void +setstatus(char *str) +{ + XStoreName(dpy, DefaultRootWindow(dpy), str); + XSync(dpy, False); +} + +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 +main(void) +{ + char *status; + char *newmails; + + if (!(dpy = XOpenDisplay(NULL))) { + fprintf(stderr, "dwmstatus: cannot open display.\n"); + return 1; + } + + for (;;sleep(60)) { + newmails = get_nmail("/home/xavier/Maildir/laposte/new", "Mails:"); + + + status = smprintf("%s",newmails); + setstatus(status); + free(newmails); + free(status); + } + + XCloseDisplay(dpy); + + return 0; +} + diff --git a/dwm.suckless.org/status_monitor/mpdstatus.c b/dwm.suckless.org/status_monitor/mpdstatus.c @@ -0,0 +1,57 @@ +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <mpd/client.h> + +/* add to config.mk : +# mpd ++ MPDLIB = -lmpdclient ++ MPDFLAG = -DMPD + +- LIBS = -L/usr/lib -lc -L${X11LIB} -lX11 ++ LIBS = -L/usr/lib -lc -L${X11LIB} -lX11 ${MPDLIB} + +- CPPFLAGS = -DVERSION=\"${VERSION}\" ++ CPPFLAGS = ${MPDFLAG} -DVERSION=\"${VERSION}\" +*/ +/* simple function to retrieve mpd status */ +char * +getmpdstat() { + struct mpd_song * song = NULL; + const char * title = NULL; + const char * artist = NULL; + char * retstr = NULL; + int elapsed = 0, total = 0; + struct mpd_connection * conn ; + if (!(conn = mpd_connection_new("localhost", 0, 30000)) || + mpd_connection_get_error(conn)){ + return smprintf(""); + } + + mpd_command_list_begin(conn, true); + mpd_send_status(conn); + mpd_send_current_song(conn); + mpd_command_list_end(conn); + + struct mpd_status* theStatus = mpd_recv_status(conn); + if ((theStatus) && (mpd_status_get_state(theStatus) == MPD_STATE_PLAY)) { + mpd_response_next(conn); + song = mpd_recv_song(conn); + title = smprintf("%s",mpd_song_get_tag(song, MPD_TAG_TITLE, 0)); + artist = smprintf("%s",mpd_song_get_tag(song, MPD_TAG_ARTIST, 0)); + + elapsed = mpd_status_get_elapsed_time(theStatus); + total = mpd_status_get_total_time(theStatus); + mpd_song_free(song); + retstr = smprintf("%.2d:%.2d/%.2d:%.2d %s - %s", + elapsed/60, elapsed%60, + total/60, total%60, + artist, title); + free((char*)title); + free((char*)artist); + } + else retstr = smprintf(""); + mpd_response_finish(conn); + mpd_connection_free(conn); + return retstr; +} diff --git a/dwm.suckless.org/status_monitor/new-acpi-battery.c b/dwm.suckless.org/status_monitor/new-acpi-battery.c @@ -0,0 +1,65 @@ +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); +} + +/* + * 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("not present"); + } + 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); +} + diff --git a/dwm.suckless.org/status_monitor/profil-dwmstatus-1.0.c b/dwm.suckless.org/status_monitor/profil-dwmstatus-1.0.c @@ -0,0 +1,128 @@ +/* made by profil 2011-12-29. +** +** Compile with: +** gcc -Wall -pedantic -std=c99 -lX11 status.c +*/ +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> +#include <time.h> +#include <X11/Xlib.h> + +static Display *dpy; + +void setstatus(char *str) { + XStoreName(dpy, DefaultRootWindow(dpy), str); + XSync(dpy, False); +} + +float getfreq(char *file) { + FILE *fd; + char *freq; + float ret; + + freq = malloc(10); + fd = fopen(file, "r"); + if(fd == NULL) { + fprintf(stderr, "Cannot open '%s' for reading.\n", file); + exit(1); + } + + fgets(freq, 10, fd); + fclose(fd); + + ret = atof(freq)/1000000; + free(freq); + return ret; +} + +char *getdatetime() { + char *buf; + time_t result; + struct tm *resulttm; + + if((buf = malloc(sizeof(char)*65)) == NULL) { + fprintf(stderr, "Cannot allocate memory for buf.\n"); + exit(1); + } + result = time(NULL); + resulttm = localtime(&result); + if(resulttm == NULL) { + fprintf(stderr, "Error getting localtime.\n"); + exit(1); + } + if(!strftime(buf, sizeof(char)*65-1, "%a %b %d %H:%M:%S", resulttm)) { + fprintf(stderr, "strftime is 0.\n"); + exit(1); + } + + return buf; +} + +float getbattery() { + FILE *fd; + int energy_now, energy_full, voltage_now; + + fd = fopen("/sys/class/power_supply/BAT0/energy_now", "r"); + if(fd == NULL) { + fprintf(stderr, "Error opening energy_now.\n"); + return -1; + } + fscanf(fd, "%d", &energy_now); + fclose(fd); + + + fd = fopen("/sys/class/power_supply/BAT0/energy_full", "r"); + if(fd == NULL) { + fprintf(stderr, "Error opening energy_full.\n"); + return -1; + } + fscanf(fd, "%d", &energy_full); + fclose(fd); + + + fd = fopen("/sys/class/power_supply/BAT0/voltage_now", "r"); + if(fd == NULL) { + fprintf(stderr, "Error opening voltage_now.\n"); + return -1; + } + fscanf(fd, "%d", &voltage_now); + fclose(fd); + + + return ((float)energy_now * 1000 / (float)voltage_now) * 100 / ((float)energy_full * 1000 / (float)voltage_now); +} + +int main(void) { + char *status; + float cpu0, cpu1; + char *datetime; + int bat0; + + + if (!(dpy = XOpenDisplay(NULL))) { + fprintf(stderr, "Cannot open display.\n"); + return 1; + } + + if((status = malloc(200)) == NULL) + exit(1); + + + for (;;sleep(1)) { + cpu0 = getfreq("/sys/devices/system/cpu/cpu0/cpufreq/scaling_cur_freq"); + cpu1 = getfreq("/sys/devices/system/cpu/cpu1/cpufreq/scaling_cur_freq"); + datetime = getdatetime(); + bat0 = getbattery(); + snprintf(status, 200, "%0.2f, %0.2f | %.2lf%% | %s", cpu0, cpu1, bat0, datetime); + + free(datetime); + setstatus(status); + } + + free(status); + XCloseDisplay(dpy); + + return 0; +} + diff --git a/dwm.suckless.org/status_monitor/scripts/basic_collection/index.md b/dwm.suckless.org/status_monitor/scripts/basic_collection/index.md @@ -0,0 +1,9 @@ +Scripts collection +================== + +Description +----------- + +A basic collection of simple, fully POSIX sh compliant scripts to get various +system information among other useful things can be found at kl3's [scripts](https://notabug.org/kl3/scripts) +repository. Feel free to copy, adapt and/or improve them. diff --git a/dwm.suckless.org/status_monitor/scripts/email_notifier_script/index.md b/dwm.suckless.org/status_monitor/scripts/email_notifier_script/index.md @@ -0,0 +1,62 @@ +email notifier script +===================== + +Description +----------- + +This init script is based on some ideas taken from the dwm ML. It adds email +notification using `fetchmail`. It also adds the functionality of showing the +content of the file `$HOME/.message` when it exists. This can be used for +displaying info by other programs writing to this file. + +When a new email arrives a flashing text message is shown on the dwm's +status bar. + +Config .fetchmailrc +------------------- +This config works with GMail over IMAP with the IDLE extension for low bandwidth usage: + + poll imap.gmail.com port 993 proto IMAP user "<your_user>@gmail.com" + there with password "<your_pass>" keep ssl idle + +Init script +----------- + +The notification is flashing during 60 seconds, then it is removed. Lines +written to `.message` are displayed during a second in the status bar. If +`.message` is deleted, the normal status message (date and uptime) returns. + +A pipe must be used with `fetchmail` when using IDLE extension because this way +it waits for updates from the inbox not doing polling. +If the `.message` file exists with some content, it is preserved and no email +notification is shown. + + fetchmail --check 2>/dev/null | while read line; do + new=`echo $line | sed 's/(//' | awk '{print $1-$3}'` + if [ $new != 0 ] && [ ! -e ~/.message ]; then + echo "New mail($new)" > ~/.message + echo "!!! !!! !!!" >> ~/.message + sleep 60 + if grep '^New mail' ~/.message >/dev/null 2>/dev/null; then + rm -f ~/.message + fi + fi + done & + while true; do + if [ -r ~/.message ]; then + while read line; do + xsetroot -name "$line" + sleep 1 + done < ~/.message + else + xsetroot -name "`date` `uptime | sed 's/.*,//'`" + sleep 1 + fi + done & + exec dwm + rm -f ~/.message + +Author +------ + +- Ricardo Catalinas Jiménez <[jimenezrick@gmail.com](mailto:jimenezrick@gmail.com)> diff --git a/dwm.suckless.org/status_monitor/scripts/simple_monitors/index.md b/dwm.suckless.org/status_monitor/scripts/simple_monitors/index.md @@ -0,0 +1,46 @@ +Simple Monitors +=== + +Description +--- + +These are just very simple monitors for the dwm status bar. + +Battery +--- + +Your battery may be called something different, so check /proc/acpi for its name. Also, change 89000 to whatever the capacity is for your battery. +This returns the remaining battery power as a percentage. + + $(echo $(awk '/rem/ { print $3/89000 }' /proc/acpi/battery/BAT0/state| hoc| cut -c3,4)% + +hoc comes from plan9port or 9base. + +Depending on your system, you can also use + + cat /sys/class/power_supply/BAT0/capacity + +to get your battery status in percentage. + +Ram used +--- + +Return the amount of ram used, in megabytes. + + $(free -m |awk '/cache:/ { print $3"M" }') + +Temperature +--- + +Returns the temperature of the cpu, in celcius. + + $(awk '{ print $2 }' /proc/acpi/thermal_zone/THM0/temperature)C + +Volume +--- + + amixer get Front | tail -n1 | awk '{ print $5 }' | tr -d [] + +Change "Front" to your audio device + +I told you they were simple. diff --git a/dwm.suckless.org/status_monitor/uptime.c b/dwm.suckless.org/status_monitor/uptime.c @@ -0,0 +1,153 @@ +#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 <sys/sysinfo.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; +} + +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]); +} + + +char * +up() { + struct sysinfo info; + int h,m = 0; + sysinfo(&info); + h = info.uptime/3600; + m = (info.uptime - h*3600 )/60; + return smprintf("%dh%dm",h,m); +} + + +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); +} + +int +main(void) +{ + char *status = NULL; + char *tmprs = NULL; + char *avgs = NULL; + time_t count60 = 0; + char *uptm = 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(uptm); + tmprs = mktimes("%d/%m/%y %H:%M", tzparis); + uptm = up(); + } + /* checks every second */ + avgs = loadavg(); + + status = smprintf("%s | Up:%s | %s", + avgs, uptm, tmprs); + setstatus(status); + free(avgs); + free(status); + } + + XCloseDisplay(dpy); + + return 0; +} +