diskspace_timechk.c - sites - public wiki contents of suckless.org
 (HTM) git clone git://git.suckless.org/sites
 (DIR) Log
 (DIR) Files
 (DIR) Refs
       ---
       diskspace_timechk.c (7336B)
       ---
            1 #define _BSD_SOURCE
            2 #define _GNU_SOURCE
            3 #include <unistd.h>
            4 #include <stdio.h>
            5 #include <stdlib.h>
            6 #include <stdarg.h>
            7 #include <string.h>
            8 #include <strings.h>
            9 #include <sys/time.h>
           10 #include <time.h>
           11 #include <sys/types.h>
           12 #include <dirent.h>
           13 #include <sys/statvfs.h>
           14 
           15 #include <X11/Xlib.h>
           16 
           17 char *tzparis = "Europe/Paris";
           18 
           19 static Display *dpy;
           20 
           21 char *
           22 smprintf(char *fmt, ...)
           23 {
           24         va_list fmtargs;
           25         char *buf = NULL;
           26 
           27         va_start(fmtargs, fmt);
           28         if (vasprintf(&buf, fmt, fmtargs) == -1){
           29                 fprintf(stderr, "malloc vasprintf\n");
           30                 exit(1);
           31     }
           32         va_end(fmtargs);
           33 
           34         return buf;
           35 }
           36 
           37 void
           38 settz(char *tzname)
           39 {
           40         setenv("TZ", tzname, 1);
           41 }
           42 
           43 char *
           44 mktimes(char *fmt, char *tzname)
           45 {
           46         char buf[129];
           47         time_t tim;
           48         struct tm *timtm;
           49 
           50         memset(buf, 0, sizeof(buf));
           51         settz(tzname);
           52         tim = time(NULL);
           53         timtm = localtime(&tim);
           54         if (timtm == NULL) {
           55                 perror("localtime");
           56                 exit(1);
           57         }
           58 
           59         if (!strftime(buf, sizeof(buf)-1, fmt, timtm)) {
           60                 fprintf(stderr, "strftime == 0\n");
           61                 exit(1);
           62         }
           63 
           64         return smprintf(buf);
           65 }
           66 
           67 void
           68 setstatus(char *str)
           69 {
           70         XStoreName(dpy, DefaultRootWindow(dpy), str);
           71         XSync(dpy, False);
           72 }
           73 
           74 char *
           75 loadavg(void)
           76 {
           77         double avgs[3];
           78 
           79         if (getloadavg(avgs, 3) < 0) {
           80                 perror("getloadavg");
           81                 exit(1);
           82         }
           83 
           84         return smprintf("%.2f %.2f %.2f", avgs[0], avgs[1], avgs[2]);
           85 }
           86 
           87 char *
           88 readfile(char *base, char *file)
           89 {
           90         char *path, line[513];
           91         FILE *fd;
           92 
           93         memset(line, 0, sizeof(line));
           94 
           95         path = smprintf("%s/%s", base, file);
           96         fd = fopen(path, "r");
           97         if (fd == NULL)
           98                 return NULL;
           99         free(path);
          100 
          101         if (fgets(line, sizeof(line)-1, fd) == NULL)
          102                 return NULL;
          103         fclose(fd);
          104 
          105         return smprintf("%s", line);
          106 }
          107 
          108 /*
          109  * Linux seems to change the filenames after suspend/hibernate
          110  * according to a random scheme. So just check for both possibilities.
          111  */
          112 char *
          113 getbattery(char *base)
          114 {
          115         char *co;
          116         int descap, remcap;
          117 
          118         descap = -1;
          119         remcap = -1;
          120 
          121         co = readfile(base, "present");
          122         if (co == NULL || co[0] != '1') {
          123                 if (co != NULL) free(co);
          124                 return smprintf("?");
          125         }
          126         free(co);
          127 
          128         co = readfile(base, "charge_full_design");
          129         if (co == NULL) {
          130                 co = readfile(base, "energy_full_design");
          131                 if (co == NULL)
          132                         return smprintf("");
          133         }
          134         sscanf(co, "%d", &descap);
          135         free(co);
          136 
          137         co = readfile(base, "charge_now");
          138         if (co == NULL) {
          139                 co = readfile(base, "energy_now");
          140                 if (co == NULL)
          141                         return smprintf("");
          142         }
          143         sscanf(co, "%d", &remcap);
          144         free(co);
          145 
          146         if (remcap < 0 || descap < 0)
          147                 return smprintf("invalid");
          148 
          149         return smprintf("%.0f", ((float)remcap / (float)descap) * 100);
          150 }
          151 
          152 int
          153 parse_netdev(unsigned long long int *receivedabs, unsigned long long int *sentabs)
          154 {
          155         char *buf;
          156         char *eth0start;
          157         static int bufsize;
          158         FILE *devfd;
          159 
          160         buf = (char *) calloc(255, 1);
          161         bufsize = 255;
          162         devfd = fopen("/proc/net/dev", "r");
          163 
          164         // ignore the first two lines of the file
          165         fgets(buf, bufsize, devfd);
          166         fgets(buf, bufsize, devfd);
          167 
          168         while (fgets(buf, bufsize, devfd)) {
          169             if ((eth0start = strstr(buf, "wlan0:")) != NULL) {
          170 
          171                 // With thanks to the conky project at http://conky.sourceforge.net/
          172                 sscanf(eth0start + 6, "%llu  %*d     %*d  %*d  %*d  %*d   %*d        %*d       %llu",\
          173                        receivedabs, sentabs);
          174                 fclose(devfd);
          175                 free(buf);
          176                 return 0;
          177             }
          178         }
          179     fclose(devfd);
          180         free(buf);
          181         return 1;
          182 }
          183 
          184 char *
          185 get_netusage()
          186 {
          187         unsigned long long int oldrec, oldsent, newrec, newsent;
          188         double downspeed, upspeed;
          189         char *downspeedstr, *upspeedstr;
          190         char *retstr;
          191         int retval;
          192 
          193         downspeedstr = (char *) malloc(15);
          194         upspeedstr = (char *) malloc(15);
          195         retstr = (char *) malloc(42);
          196 
          197         retval = parse_netdev(&oldrec, &oldsent);
          198         if (retval) {
          199             fprintf(stdout, "Error when parsing /proc/net/dev file.\n");
          200             exit(1);
          201         }
          202 
          203         sleep(1);
          204         retval = parse_netdev(&newrec, &newsent);
          205         if (retval) {
          206             fprintf(stdout, "Error when parsing /proc/net/dev file.\n");
          207             exit(1);
          208         }
          209 
          210         downspeed = (newrec - oldrec) / 1024.0;
          211         if (downspeed > 1024.0) {
          212             downspeed /= 1024.0;
          213             sprintf(downspeedstr, "%.3f MB/s", downspeed);
          214         } else {
          215             sprintf(downspeedstr, "%.2f KB/s", downspeed);
          216         }
          217 
          218         upspeed = (newsent - oldsent) / 1024.0;
          219         if (upspeed > 1024.0) {
          220             upspeed /= 1024.0;
          221             sprintf(upspeedstr, "%.3f MB/s", upspeed);
          222         } else {
          223             sprintf(upspeedstr, "%.2f KB/s", upspeed);
          224         }
          225         sprintf(retstr, "D: %s U: %s", downspeedstr, upspeedstr);
          226 
          227         free(downspeedstr);
          228         free(upspeedstr);
          229         return retstr;
          230 }
          231 
          232 char *get_nmail(char *directory, char *label)
          233 {
          234     /* directory : Maildir path 
          235     * return label : number_of_new_mails
          236     */
          237     
          238     int n = 0;
          239     DIR* dir = NULL;
          240     struct dirent* rf = NULL;
          241 
          242     dir = opendir(directory); /* try to open directory */
          243     if (dir == NULL)
          244         perror("");
          245 
          246     while ((rf = readdir(dir)) != NULL) /*count number of file*/
          247     {
          248         if (strcmp(rf->d_name, ".") != 0 &&
          249             strcmp(rf->d_name, "..") != 0)
          250             n++;
          251     }
          252     closedir(dir);
          253 
          254     if (n == 0) 
          255        return smprintf("");
          256     else 
          257        return smprintf("%s%d",label, n);
          258 
          259 }
          260 
          261 int runevery(time_t *ltime, int sec){
          262     /* return 1 if sec elapsed since last run
          263      * else return 0 
          264     */
          265     time_t now = time(NULL);
          266     
          267     if ( difftime(now, *ltime ) >= sec)
          268     {
          269         *ltime = now;
          270         return(1);
          271     }
          272     else 
          273         return(0);
          274 }
          275 
          276 char *get_freespace(char *mntpt){
          277     struct statvfs data;
          278     double total, used = 0;
          279 
          280     if ( (statvfs(mntpt, &data)) < 0){
          281                 fprintf(stderr, "can't get info on disk.\n");
          282                 return("?");
          283     }
          284     total = (data.f_blocks * data.f_frsize);
          285     used = (data.f_blocks - data.f_bfree) * data.f_frsize ;
          286     return(smprintf("%.0f", (used/total*100)));
          287 }
          288 
          289 int
          290 main(void)
          291 {
          292         char *status = NULL;
          293         char *avgs = NULL;
          294         char *tmprs = NULL;
          295     char *bat = NULL;
          296     char *netstats = NULL;
          297     char *mail_laposte = NULL;
          298     char *mail_fac = NULL;
          299     char *mail_lavabit = NULL;
          300     char *mail_tl = NULL;
          301     char *rootfs = NULL;
          302     char *homefs = NULL;
          303     time_t count5min = 0;
          304     time_t count60 = 0;
          305     
          306         if (!(dpy = XOpenDisplay(NULL))) {
          307                 fprintf(stderr, "dwmstatus: cannot open display.\n");
          308                 return 1;
          309         }
          310 
          311         for (;;sleep(1)) {
          312             /* checks every minutes */
          313             if ( runevery(&count60, 60) )
          314         {
          315             free(tmprs);
          316             free(bat);
          317             free(rootfs);
          318             free(homefs);
          319             tmprs = mktimes("%d/%m/%y %H:%M", tzparis);
          320             bat = getbattery("/sys/class/power_supply/BAT0/");
          321             homefs = get_freespace("/home");
          322             rootfs = get_freespace("/");
          323         }
          324         /* checks mail every 5 minutes */
          325         if (runevery(&count5min, 300) )
          326         {
          327             free(mail_laposte);
          328             free(mail_fac);
          329             free(mail_lavabit);
          330             free(mail_tl);
          331             mail_laposte = get_nmail("/home/xavier/Maildir/fac/new", " Fac:");
          332             mail_fac = get_nmail("/home/xavier/Maildir/lavabit/new", " Lavabit:");
          333             mail_lavabit = get_nmail("/home/xavier/Maildir/toilelibre/new", " TL:");
          334             mail_tl = get_nmail("/home/xavier/Maildir/laposte/new", " Laposte:");
          335         }
          336         /* checks every second */
          337                 avgs = loadavg();
          338         netstats = get_netusage();
          339 
          340                 status = smprintf("%s%s%s%s | %s | /:%s% /home:%s% | B:%s% | %s | %s",
          341                                  mail_tl, mail_fac, mail_lavabit, mail_laposte,
          342                                  netstats, rootfs, homefs, bat, avgs, tmprs);
          343                 setstatus(status);
          344                 free(avgs);
          345         free(netstats);
          346                 free(status);
          347         }
          348 
          349         XCloseDisplay(dpy);
          350 
          351         return 0;
          352 }
          353