dwmclock-netstat.c - sites - public wiki contents of suckless.org | |
git clone git://git.suckless.org/sites | |
Log | |
Files | |
Refs | |
--- | |
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… | |
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… | |
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 } |