dwmstatus-netusage.c (3845B)
1 #define _BSD_SOURCE 2 #include <unistd.h> 3 #include <stdbool.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 <sys/wait.h> 13 14 #include <X11/Xlib.h> 15 16 char *tzargentina = "America/Buenos_Aires"; 17 char *tzutc = "UTC"; 18 char *tzberlin = "Europe/Berlin"; 19 20 static Display *dpy; 21 22 char * 23 smprintf(char *fmt, ...) 24 { 25 va_list fmtargs; 26 char *ret; 27 int len; 28 29 va_start(fmtargs, fmt); 30 len = vsnprintf(NULL, 0, fmt, fmtargs); 31 va_end(fmtargs); 32 33 ret = malloc(++len); 34 if (ret == NULL) { 35 perror("malloc"); 36 exit(1); 37 } 38 39 va_start(fmtargs, fmt); 40 vsnprintf(ret, len, fmt, fmtargs); 41 va_end(fmtargs); 42 43 return ret; 44 } 45 46 void 47 settz(char *tzname) 48 { 49 setenv("TZ", tzname, 1); 50 } 51 52 int 53 parse_netdev(unsigned long long int *receivedabs, unsigned long long int *sentabs) 54 { 55 char buf[255]; 56 char *datastart; 57 static int bufsize; 58 int rval; 59 FILE *devfd; 60 unsigned long long int receivedacc, sentacc; 61 62 bufsize = 255; 63 devfd = fopen("/proc/net/dev", "r"); 64 rval = 1; 65 66 // Ignore the first two lines of the file 67 fgets(buf, bufsize, devfd); 68 fgets(buf, bufsize, devfd); 69 70 while (fgets(buf, bufsize, devfd)) { 71 if ((datastart = strstr(buf, "lo:")) == NULL) { 72 datastart = strstr(buf, ":"); 73 74 // With thanks to the conky project at http://conky.sourceforge.net/ 75 sscanf(datastart + 1, "%llu %*d %*d %*d %*d %*d %*d %*d %llu",\ 76 &receivedacc, &sentacc); 77 *receivedabs += receivedacc; 78 *sentabs += sentacc; 79 rval = 0; 80 } 81 } 82 83 fclose(devfd); 84 return rval; 85 } 86 87 void 88 calculate_speed(char *speedstr, unsigned long long int newval, unsigned long long int oldval) 89 { 90 double speed; 91 speed = (newval - oldval) / 1024.0; 92 if (speed > 1024.0) { 93 speed /= 1024.0; 94 sprintf(speedstr, "%.3f MB/s", speed); 95 } else { 96 sprintf(speedstr, "%.2f KB/s", speed); 97 } 98 } 99 100 char * 101 get_netusage(unsigned long long int *rec, unsigned long long int *sent) 102 { 103 unsigned long long int newrec, newsent; 104 newrec = newsent = 0; 105 char downspeedstr[15], upspeedstr[15]; 106 static char retstr[42]; 107 int retval; 108 109 retval = parse_netdev(&newrec, &newsent); 110 if (retval) { 111 fprintf(stdout, "Error when parsing /proc/net/dev file.\n"); 112 exit(1); 113 } 114 115 calculate_speed(downspeedstr, newrec, *rec); 116 calculate_speed(upspeedstr, newsent, *sent); 117 118 sprintf(retstr, "down: %s up: %s", downspeedstr, upspeedstr); 119 120 *rec = newrec; 121 *sent = newsent; 122 return retstr; 123 } 124 125 char * 126 mktimes(char *fmt, char *tzname) 127 { 128 char buf[129]; 129 time_t tim; 130 struct tm *timtm; 131 132 bzero(buf, sizeof(buf)); 133 settz(tzname); 134 tim = time(NULL); 135 timtm = localtime(&tim); 136 if (timtm == NULL) { 137 perror("localtime"); 138 exit(1); 139 } 140 141 if (!strftime(buf, sizeof(buf)-1, fmt, timtm)) { 142 fprintf(stderr, "strftime == 0\n"); 143 exit(1); 144 } 145 146 return smprintf("%s", buf); 147 } 148 149 void 150 setstatus(char *str) 151 { 152 XStoreName(dpy, DefaultRootWindow(dpy), str); 153 XSync(dpy, False); 154 } 155 156 char * 157 loadavg(void) 158 { 159 double avgs[3]; 160 161 if (getloadavg(avgs, 3) < 0) { 162 perror("getloadavg"); 163 exit(1); 164 } 165 166 return smprintf("%.2f %.2f %.2f", avgs[0], avgs[1], avgs[2]); 167 } 168 169 int 170 main(void) 171 { 172 char *status; 173 char *avgs; 174 char *tmar; 175 char *tmutc; 176 char *tmbln; 177 char *netstats; 178 static unsigned long long int rec, sent; 179 180 if (!(dpy = XOpenDisplay(NULL))) { 181 fprintf(stderr, "dwmstatus: cannot open display.\n"); 182 return 1; 183 } 184 185 parse_netdev(&rec, &sent); 186 for (;;sleep(1)) { 187 avgs = loadavg(); 188 tmar = mktimes("%H:%M", tzargentina); 189 tmutc = mktimes("%H:%M", tzutc); 190 tmbln = mktimes("KW %W %a %d %b %H:%M %Z %Y", tzberlin); 191 netstats = get_netusage(&rec, &sent); 192 193 status = smprintf("[L: %s|N: %s|A: %s|U: %s|%s]", 194 avgs, netstats, tmar, tmutc, tmbln); 195 setstatus(status); 196 free(avgs); 197 free(tmar); 198 free(tmutc); 199 free(tmbln); 200 free(status); 201 } 202 203 XCloseDisplay(dpy); 204 205 return 0; 206 } 207