diskspace_timechk.c - sites - public wiki contents of suckless.org | |
git clone git://git.suckless.org/sites | |
Log | |
Files | |
Refs | |
--- | |
diskspace_timechk.c (7336B) | |
--- | |
1 #define _BSD_SOURCE | |
2 #define _GNU_SOURCE | |
3 #include <unistd.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 <dirent.h> | |
13 #include <sys/statvfs.h> | |
14 | |
15 #include <X11/Xlib.h> | |
16 | |
17 char *tzparis = "Europe/Paris"; | |
18 | |
19 static Display *dpy; | |
20 | |
21 char * | |
22 smprintf(char *fmt, ...) | |
23 { | |
24 va_list fmtargs; | |
25 char *buf = NULL; | |
26 | |
27 va_start(fmtargs, fmt); | |
28 if (vasprintf(&buf, fmt, fmtargs) == -1){ | |
29 fprintf(stderr, "malloc vasprintf\n"); | |
30 exit(1); | |
31 } | |
32 va_end(fmtargs); | |
33 | |
34 return buf; | |
35 } | |
36 | |
37 void | |
38 settz(char *tzname) | |
39 { | |
40 setenv("TZ", tzname, 1); | |
41 } | |
42 | |
43 char * | |
44 mktimes(char *fmt, char *tzname) | |
45 { | |
46 char buf[129]; | |
47 time_t tim; | |
48 struct tm *timtm; | |
49 | |
50 memset(buf, 0, sizeof(buf)); | |
51 settz(tzname); | |
52 tim = time(NULL); | |
53 timtm = localtime(&tim); | |
54 if (timtm == NULL) { | |
55 perror("localtime"); | |
56 exit(1); | |
57 } | |
58 | |
59 if (!strftime(buf, sizeof(buf)-1, fmt, timtm)) { | |
60 fprintf(stderr, "strftime == 0\n"); | |
61 exit(1); | |
62 } | |
63 | |
64 return smprintf(buf); | |
65 } | |
66 | |
67 void | |
68 setstatus(char *str) | |
69 { | |
70 XStoreName(dpy, DefaultRootWindow(dpy), str); | |
71 XSync(dpy, False); | |
72 } | |
73 | |
74 char * | |
75 loadavg(void) | |
76 { | |
77 double avgs[3]; | |
78 | |
79 if (getloadavg(avgs, 3) < 0) { | |
80 perror("getloadavg"); | |
81 exit(1); | |
82 } | |
83 | |
84 return smprintf("%.2f %.2f %.2f", avgs[0], avgs[1], avgs[2]); | |
85 } | |
86 | |
87 char * | |
88 readfile(char *base, char *file) | |
89 { | |
90 char *path, line[513]; | |
91 FILE *fd; | |
92 | |
93 memset(line, 0, sizeof(line)); | |
94 | |
95 path = smprintf("%s/%s", base, file); | |
96 fd = fopen(path, "r"); | |
97 if (fd == NULL) | |
98 return NULL; | |
99 free(path); | |
100 | |
101 if (fgets(line, sizeof(line)-1, fd) == NULL) | |
102 return NULL; | |
103 fclose(fd); | |
104 | |
105 return smprintf("%s", line); | |
106 } | |
107 | |
108 /* | |
109 * Linux seems to change the filenames after suspend/hibernate | |
110 * according to a random scheme. So just check for both possibilities. | |
111 */ | |
112 char * | |
113 getbattery(char *base) | |
114 { | |
115 char *co; | |
116 int descap, remcap; | |
117 | |
118 descap = -1; | |
119 remcap = -1; | |
120 | |
121 co = readfile(base, "present"); | |
122 if (co == NULL || co[0] != '1') { | |
123 if (co != NULL) free(co); | |
124 return smprintf("?"); | |
125 } | |
126 free(co); | |
127 | |
128 co = readfile(base, "charge_full_design"); | |
129 if (co == NULL) { | |
130 co = readfile(base, "energy_full_design"); | |
131 if (co == NULL) | |
132 return smprintf(""); | |
133 } | |
134 sscanf(co, "%d", &descap); | |
135 free(co); | |
136 | |
137 co = readfile(base, "charge_now"); | |
138 if (co == NULL) { | |
139 co = readfile(base, "energy_now"); | |
140 if (co == NULL) | |
141 return smprintf(""); | |
142 } | |
143 sscanf(co, "%d", &remcap); | |
144 free(co); | |
145 | |
146 if (remcap < 0 || descap < 0) | |
147 return smprintf("invalid"); | |
148 | |
149 return smprintf("%.0f", ((float)remcap / (float)descap) * 100); | |
150 } | |
151 | |
152 int | |
153 parse_netdev(unsigned long long int *receivedabs, unsigned long long int… | |
154 { | |
155 char *buf; | |
156 char *eth0start; | |
157 static int bufsize; | |
158 FILE *devfd; | |
159 | |
160 buf = (char *) calloc(255, 1); | |
161 bufsize = 255; | |
162 devfd = fopen("/proc/net/dev", "r"); | |
163 | |
164 // ignore the first two lines of the file | |
165 fgets(buf, bufsize, devfd); | |
166 fgets(buf, bufsize, devfd); | |
167 | |
168 while (fgets(buf, bufsize, devfd)) { | |
169 if ((eth0start = strstr(buf, "wlan0:")) != NULL) { | |
170 | |
171 // With thanks to the conky project at http://conky.sour… | |
172 sscanf(eth0start + 6, "%llu %*d %*d %*d %*d %*d … | |
173 receivedabs, sentabs); | |
174 fclose(devfd); | |
175 free(buf); | |
176 return 0; | |
177 } | |
178 } | |
179 fclose(devfd); | |
180 free(buf); | |
181 return 1; | |
182 } | |
183 | |
184 char * | |
185 get_netusage() | |
186 { | |
187 unsigned long long int oldrec, oldsent, newrec, newsent; | |
188 double downspeed, upspeed; | |
189 char *downspeedstr, *upspeedstr; | |
190 char *retstr; | |
191 int retval; | |
192 | |
193 downspeedstr = (char *) malloc(15); | |
194 upspeedstr = (char *) malloc(15); | |
195 retstr = (char *) malloc(42); | |
196 | |
197 retval = parse_netdev(&oldrec, &oldsent); | |
198 if (retval) { | |
199 fprintf(stdout, "Error when parsing /proc/net/dev file.\n"); | |
200 exit(1); | |
201 } | |
202 | |
203 sleep(1); | |
204 retval = parse_netdev(&newrec, &newsent); | |
205 if (retval) { | |
206 fprintf(stdout, "Error when parsing /proc/net/dev file.\n"); | |
207 exit(1); | |
208 } | |
209 | |
210 downspeed = (newrec - oldrec) / 1024.0; | |
211 if (downspeed > 1024.0) { | |
212 downspeed /= 1024.0; | |
213 sprintf(downspeedstr, "%.3f MB/s", downspeed); | |
214 } else { | |
215 sprintf(downspeedstr, "%.2f KB/s", downspeed); | |
216 } | |
217 | |
218 upspeed = (newsent - oldsent) / 1024.0; | |
219 if (upspeed > 1024.0) { | |
220 upspeed /= 1024.0; | |
221 sprintf(upspeedstr, "%.3f MB/s", upspeed); | |
222 } else { | |
223 sprintf(upspeedstr, "%.2f KB/s", upspeed); | |
224 } | |
225 sprintf(retstr, "D: %s U: %s", downspeedstr, upspeedstr); | |
226 | |
227 free(downspeedstr); | |
228 free(upspeedstr); | |
229 return retstr; | |
230 } | |
231 | |
232 char *get_nmail(char *directory, char *label) | |
233 { | |
234 /* directory : Maildir path | |
235 * return label : number_of_new_mails | |
236 */ | |
237 | |
238 int n = 0; | |
239 DIR* dir = NULL; | |
240 struct dirent* rf = NULL; | |
241 | |
242 dir = opendir(directory); /* try to open directory */ | |
243 if (dir == NULL) | |
244 perror(""); | |
245 | |
246 while ((rf = readdir(dir)) != NULL) /*count number of file*/ | |
247 { | |
248 if (strcmp(rf->d_name, ".") != 0 && | |
249 strcmp(rf->d_name, "..") != 0) | |
250 n++; | |
251 } | |
252 closedir(dir); | |
253 | |
254 if (n == 0) | |
255 return smprintf(""); | |
256 else | |
257 return smprintf("%s%d",label, n); | |
258 | |
259 } | |
260 | |
261 int runevery(time_t *ltime, int sec){ | |
262 /* return 1 if sec elapsed since last run | |
263 * else return 0 | |
264 */ | |
265 time_t now = time(NULL); | |
266 | |
267 if ( difftime(now, *ltime ) >= sec) | |
268 { | |
269 *ltime = now; | |
270 return(1); | |
271 } | |
272 else | |
273 return(0); | |
274 } | |
275 | |
276 char *get_freespace(char *mntpt){ | |
277 struct statvfs data; | |
278 double total, used = 0; | |
279 | |
280 if ( (statvfs(mntpt, &data)) < 0){ | |
281 fprintf(stderr, "can't get info on disk.\n"); | |
282 return("?"); | |
283 } | |
284 total = (data.f_blocks * data.f_frsize); | |
285 used = (data.f_blocks - data.f_bfree) * data.f_frsize ; | |
286 return(smprintf("%.0f", (used/total*100))); | |
287 } | |
288 | |
289 int | |
290 main(void) | |
291 { | |
292 char *status = NULL; | |
293 char *avgs = NULL; | |
294 char *tmprs = NULL; | |
295 char *bat = NULL; | |
296 char *netstats = NULL; | |
297 char *mail_laposte = NULL; | |
298 char *mail_fac = NULL; | |
299 char *mail_lavabit = NULL; | |
300 char *mail_tl = NULL; | |
301 char *rootfs = NULL; | |
302 char *homefs = NULL; | |
303 time_t count5min = 0; | |
304 time_t count60 = 0; | |
305 | |
306 if (!(dpy = XOpenDisplay(NULL))) { | |
307 fprintf(stderr, "dwmstatus: cannot open display.\n"); | |
308 return 1; | |
309 } | |
310 | |
311 for (;;sleep(1)) { | |
312 /* checks every minutes */ | |
313 if ( runevery(&count60, 60) ) | |
314 { | |
315 free(tmprs); | |
316 free(bat); | |
317 free(rootfs); | |
318 free(homefs); | |
319 tmprs = mktimes("%d/%m/%y %H:%M", tzparis); | |
320 bat = getbattery("/sys/class/power_supply/BAT0/"); | |
321 homefs = get_freespace("/home"); | |
322 rootfs = get_freespace("/"); | |
323 } | |
324 /* checks mail every 5 minutes */ | |
325 if (runevery(&count5min, 300) ) | |
326 { | |
327 free(mail_laposte); | |
328 free(mail_fac); | |
329 free(mail_lavabit); | |
330 free(mail_tl); | |
331 mail_laposte = get_nmail("/home/xavier/Maildir/fac/new", " F… | |
332 mail_fac = get_nmail("/home/xavier/Maildir/lavabit/new", " L… | |
333 mail_lavabit = get_nmail("/home/xavier/Maildir/toilelibre/ne… | |
334 mail_tl = get_nmail("/home/xavier/Maildir/laposte/new", " La… | |
335 } | |
336 /* checks every second */ | |
337 avgs = loadavg(); | |
338 netstats = get_netusage(); | |
339 | |
340 status = smprintf("%s%s%s%s | %s | /:%s% /home:%s% | B:%… | |
341 mail_tl, mail_fac, mail_lavabit, mail_l… | |
342 netstats, rootfs, homefs, bat, avgs, tm… | |
343 setstatus(status); | |
344 free(avgs); | |
345 free(netstats); | |
346 free(status); | |
347 } | |
348 | |
349 XCloseDisplay(dpy); | |
350 | |
351 return 0; | |
352 } | |
353 |