dwmclock-netstat.c (3760B)
1 #include <X11/Xlib.h> 2 #include <X11/Xatom.h> 3 #include <time.h> 4 #include <locale.h> 5 #include <unistd.h> 6 #include <stdio.h> 7 #include <sys/types.h> 8 #include <sys/stat.h> 9 #include <fcntl.h> 10 #include <string.h> 11 #include <stdint.h> 12 #include <inttypes.h> 13 #include <math.h> 14 15 #define IFNAMSIZ 16 16 17 18 static const char* determine_def_if(void) { 19 FILE *f; 20 const char* ret = 0; 21 static char buf[IFNAMSIZ]; 22 char filebuf[256]; 23 f = fopen("/proc/net/route", "r"); 24 if (f) { 25 while (fgets(filebuf, sizeof filebuf, f)) { 26 char *tab = strchr(filebuf, '\t'); 27 if (tab && !strncmp(tab + 1, "00000000", 8)) { 28 memcpy(buf, filebuf, tab - filebuf); 29 buf[tab - filebuf] = 0; 30 ret = buf; 31 break; 32 } 33 } 34 fclose(f); 35 } 36 return ret; 37 } 38 39 static uint64_t readfile(const char* filename) { 40 FILE* f; 41 uint64_t ret = 0, tmp; 42 f = fopen(filename, "r"); 43 if (f) { 44 if (fscanf(f, "%"SCNu64, &tmp) == 1) 45 ret = tmp; 46 fclose(f); 47 } 48 return ret; 49 } 50 51 static uint64_t get_rx_bytes(const char* interface) 52 { 53 char fnbuf[sizeof "/sys/class/net//statistics/rx_bytes" + IFNAMSIZ]; 54 strcpy(fnbuf, "/sys/class/net/"); 55 strcat(fnbuf, interface); 56 strcat(fnbuf, "/statistics/rx_bytes"); 57 return readfile(fnbuf); 58 } 59 60 static uint64_t get_tx_bytes(const char* interface) 61 { 62 char fnbuf[sizeof "/sys/class/net//statistics/rx_bytes" + IFNAMSIZ]; 63 strcpy(fnbuf, "/sys/class/net/"); 64 strcat(fnbuf, interface); 65 strcat(fnbuf, "/statistics/tx_bytes"); 66 return readfile(fnbuf); 67 } 68 69 static int get_suff(uint64_t x) 70 { 71 int r = -1 + !x; 72 while (x) { 73 r++; 74 x >>= 10; 75 } 76 return r; 77 } 78 79 int main(void) { 80 Display *dpy; 81 Window root; 82 int loadfd; 83 84 setlocale(LC_ALL, ""); 85 dpy = XOpenDisplay(0); 86 if (dpy) { 87 struct timespec tm, s; 88 ssize_t rv; 89 char oldif[IFNAMSIZ] = {0}; 90 uint64_t rxb, txb; 91 static const char suffixes[] = " KMGT"; // let's stay real here 92 root = XDefaultRootWindow(dpy); 93 clock_gettime(CLOCK_REALTIME, &tm); 94 s.tv_sec = 0; 95 s.tv_nsec = 1000000000 - tm.tv_nsec; 96 do rv = nanosleep(&s, &s); 97 while (rv == -1 && s.tv_nsec); 98 for (;;) { 99 char buf[100]; // estimate 100 const char *thisif = determine_def_if(); 101 uint64_t currxb, curtxb; 102 int idx; 103 int i; 104 if (thisif) 105 { 106 if (strcmp(thisif, oldif)) 107 { 108 strcpy(oldif, thisif); 109 rxb = txb = 0; 110 } 111 i = 0; 112 buf[i++] = oldif[0]; 113 buf[i++] = ' '; 114 buf[i++] = 'v'; 115 currxb = get_rx_bytes(oldif); 116 curtxb = get_tx_bytes(oldif); 117 idx = get_suff(currxb - rxb); 118 i += snprintf(buf + i, sizeof buf - i, "%.1f%c", (double)(currxb - rxb) / pow(1024, idx), suffixes[idx]); 119 rxb = currxb; 120 buf[i++] = ' '; 121 buf[i++] = '^'; 122 idx = get_suff(curtxb - txb); 123 i += snprintf(buf + i, sizeof buf - i, "%.1f%c", (double)(curtxb - txb) / pow(1024, idx), suffixes[idx]); 124 txb = curtxb; 125 } 126 else 127 buf[i++] = 'n'; 128 buf[i++] = ' '; 129 buf[i++] = '|'; 130 buf[i++] = ' '; 131 time_t t; 132 size_t l; 133 t = time(0); 134 l = strftime(buf + i, sizeof buf - i, "%c", localtime(&t)); 135 XStoreName(dpy, root, buf); 136 XSync(dpy, False); 137 sleep(1); 138 } 139 } 140 }