| dwmstatus-netusage.c - sites - public wiki contents of suckless.org | |
| git clone git://git.suckless.org/sites | |
| Log | |
| Files | |
| Refs | |
| --- | |
| 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… | |
| 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.sour… | |
| 75 sscanf(datastart + 1, "%llu %*d %*d %*d %*d %*d … | |
| 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 … | |
| 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 |