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