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 |