dwmstatus-netusage.c - sites - public wiki contents of suckless.org
(HTM) git clone git://git.suckless.org/sites
(DIR) Log
(DIR) Files
(DIR) 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 *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