wmload: Add manpage from Debian.
[dockapps.git] / wmfsm / wmfsm / wmfsm.c
blob1eb5185540e410f3609f411fbee2648b5339d166
1 /*
3 * wmfsm (C) 1999 Stefan Eilemann (Stefan.Eilemann@dlr.de)
5 * - Shows file system usage ala mfsm
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2, or (at your option)
13 * any later version.
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
20 * You should have received a copy of the GNU General Public License
21 * along with this program (see the file COPYING); if not, write to the
22 * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
23 * Boston, MA 02110-1301, USA
27 * Changes: #include "../ChangeLog"
36 * Includes
38 #include <stdio.h>
39 #include <unistd.h>
40 #include <stdlib.h>
41 #include <ctype.h>
42 #include <string.h>
43 #include <X11/X.h>
44 #include <X11/xpm.h>
45 #include "../wmgeneral/wmgeneral.h"
46 #include "wmfsm_master.xpm"
47 #include "wmfsm_mask.xbm"
49 #ifdef HAVE_CONFIG_H
50 #include "config.h"
51 #endif
53 #ifdef SVR4
54 #include <netdb.h>
55 #include <sys/systeminfo.h>
56 #endif /* SVR4 */
58 #ifdef HAVE_SYS_VFS_H
59 #include <sys/vfs.h>
60 #endif
61 #ifdef HAVE_SYS_STATFS_H
62 #include <sys/statfs.h>
63 #endif
64 #ifdef HAVE_SYS_MOUNT_H
65 #include <sys/mount.h>
66 #endif
67 #ifdef HAVE_SYS_PARAM_H
68 #include <sys/param.h>
69 #endif
70 #ifdef HAVE_SYS_TYPES_H
71 #include <sys/types.h>
72 #endif
74 #ifdef STATFS_2_ARGUMENTS
75 # define STATFS(a,b) statfs(a,b)
76 #elif defined STATFS_4_ARGUMENTS
77 # define STATFS(a,b) statfs(a,b,sizeof(struct statfs),0)
78 #else
79 # define STATFS(a,b) statfs(a,b) /* Maybe configure got messed up */
80 #endif
83 #if defined IRIX64
84 # include <sys/types.h>
85 # define STATFS(a,b) statfs(a,b,sizeof(struct statfs),0)
86 #elif defined linux
87 # define STATFS(a,b) statfs(a,b)
88 #elif defined(SunOS)
89 # define STATFS(a,b) statfs(a,b,sizeof(struct statfs),0)
90 #elif defined(__OpenBSD__) || defined(__FreeBSD__)
91 # define STATFS(a,b) statfs(a,b)
92 # include <sys/param.h>
93 #endif
96 #define _GNU_SOURCE
97 #include <getopt.h>
99 * Delay between refreshes (in microseconds), uses the 10*DELAY_10
100 * coz irix has max of 100000L :(.
102 #define DELAY_10 99999L
103 #define LENMP 5 /*max 10, number char for mountpoint */
105 /*modes for drawing*/
106 #define NORMAL 0
107 #define FIRE 1
110 void ParseCMDLine(int argc, char *argv[]);
111 void pressEvent(XButtonEvent * xev);
112 void readFileSystems(void);
113 void excludeFileSystems(void);
114 void print_usage(void);
116 int UpToDate = 0;
117 int ForceUpdate = 1;
118 char *mp[100];
119 int per[9];
120 int numberfs;
121 int mode = FIRE;
122 int blink = 1;
123 int blinkper = 95;
124 char dummy[4096];
125 char *myName;
126 int delay = DELAY_10;
127 char appearance[256] = "";
129 int xpos[] = { 66, 71, 76, 81, 86, 91, /* A B C D E F */
130 66, 71, 76, 81, 86, 91, /* G H I J K L */
131 66, 71, 76, 81, 86, 91, /* M N O P Q R */
132 66, 71, 76, 81, 86, 91, /* S T U V W X */
133 66, 71, 76, 81, 86, 91, /* Y Z / _ - . */
134 96, 101, /* 0 1 */
135 96, 101, /* 2 3 */
136 96, 101, /* 4 5 */
137 96, 101, /* 6 7 */
138 96, 101
139 }; /* 8 9 */
141 int ypos[] = { 4, 4, 4, 4, 4, 4,
142 9, 9, 9, 9, 9, 9,
143 14, 14, 14, 14, 14, 14,
144 19, 19, 19, 19, 19, 19,
145 24, 24, 24, 24, 24, 24,
146 4, 4,
147 9, 9,
148 14, 14,
149 19, 19,
150 24, 24
155 * main
158 main(int argc, char *argv[])
161 XEvent event;
162 int dx, dy;
163 char hostname[100];
164 int i, j, k;
165 int xpm_free = 0;
166 int c, on[9] = { 1, 1, 1, 1, 1, 1, 1, 1, 1 };
167 struct statfs buffer;
168 char **pixmap;
171 * Parse any command line arguments.
173 myName = strdup(argv[0]);
174 ParseCMDLine(argc, argv);
176 if (appearance[0] == 0) {
177 pixmap = wmfsm_master_xpm;
178 } else {
179 if (XpmReadFileToData(appearance, &pixmap) != XpmSuccess) {
180 fprintf(stderr, "warning: could not read appearance file; using default.\n");
181 pixmap = wmfsm_master_xpm;
182 } else {
183 xpm_free = 1;
187 openXwindow(argc, argv, pixmap, wmfsm_mask_bits, wmfsm_mask_width, wmfsm_mask_height);
189 if (xpm_free)
190 XpmFree(pixmap);
192 #ifndef SVR4
193 if (gethostname(hostname, 100) != 0) {
194 perror("gethostname");
195 exit(10);
197 #else
198 if (sysinfo(SI_HOSTNAME, hostname, 100) < 0) {
199 perror("sysinfo(SI_HOSTNAME)");
200 exit(20);
202 #endif
203 while (1) {
205 readFileSystems ();
206 usleep (100);
209 * Process any pending X events.
211 while (XPending(display)) {
212 XNextEvent(display, &event);
213 switch (event.type) {
214 case Expose:
215 RedrawWindow();
216 break;
217 case ButtonPress:
218 pressEvent(&event.xbutton);
219 mode = (mode + 1) % 2;
220 break;
221 case ButtonRelease:
222 break;
225 /*! Here read data
227 for (i = 0; i < numberfs; i++) {
228 if (STATFS(mp[i], &buffer) != -1) {
229 per[i] = 100 - (int) ((float) buffer.f_bfree / (float) buffer.f_blocks * 100.0);
233 * Draw window.
236 * Clear window.
238 copyXPMArea(5, 69, 54, 54, 5, 5);
239 /*! here draw values
240 * void copyXPMArea(int x, int y, int sx, int sy, int dx, int dy)
243 if (numberfs > 4) {
244 for (i = 0, dy = 0; i < numberfs; i++) {
245 for (j = 0, dx = 0; j < LENMP && (unsigned int)j < strlen(mp[i]); j++) {
246 k = j + (strlen(mp[i]) > LENMP ? strlen(mp[i]) - LENMP : 0);
247 c = (int) mp[i][k];
248 switch (c) {
249 case '/':
250 c = 123;
251 break;
252 case '_':
253 c = 124;
254 break;
255 case '0':
256 case '1':
257 case '2':
258 case '3':
259 case '4':
260 case '5':
261 case '6':
262 case '7':
263 case '8':
264 case '9':
265 c += 79;
266 break;
267 default:
268 c = tolower(c);
269 break;
271 copyXPMArea(xpos[c - 97], ypos[c - 97], 5, 5, 6 + dx, 5 + dy);
272 dx += 5;
274 c = (int) ((float) per[i] * 0.52 + 66.0);
275 k = (10 - LENMP) * 5 + 2;
276 k = (float) per[i] / 100.0 * k;
277 k = LENMP * 5 + k;
278 k = k < LENMP * 5 + 1 ? LENMP * 5 + 1 : k;
279 c = c > 66 ? c : 66;
280 c = c > 117 ? 117 : c;
281 if (blink) {
282 if ((int) per[i] >= blinkper)
283 on[i] = !on[i];
284 else
285 on[i] = 1;
287 else
288 on[i] = 1;
290 for (j = LENMP * 5; j < k; j++) {
291 if (mode == FIRE && on[i])
292 copyXPMArea(66 + (float) (j - LENMP * 5) * 52.0 / (float) ((10 - LENMP) * 5), 29, 1, 5, 6 + j, 5 + dy);
293 else if (mode == NORMAL && on[i])
294 copyXPMArea(c, 29, 1, 5, 6 + j, 5 + dy);
296 dy += 6;
299 else { /*one fs in two lines */
300 for (i = 0, dy = 0; i < numberfs; i++) {
301 for (j = 0, dx = 0; j < 10 && (unsigned int)j < strlen(mp[i]); j++) {
302 c = (int) mp[i][j + (strlen(mp[i]) > 10 ? strlen(mp[i]) - 10 : 0)];
303 switch (c) {
304 case '/':
305 c = 123;
306 break;
307 case '_':
308 c = 124;
309 break;
310 case '0':
311 case '1':
312 case '2':
313 case '3':
314 case '4':
315 case '5':
316 case '6':
317 case '7':
318 case '8':
319 case '9':
320 c += 79;
321 break;
322 default:
323 c = tolower(c);
324 break;
326 copyXPMArea(xpos[c - 97], ypos[c - 97], 5, 5, 6 + dx, 5 + dy);
327 dx += 5;
329 dy += 6;
330 c = (int) ((float) per[i] * 0.52 + 66.0);
331 k = (float) per[i] / 100.0 * 52;
332 k = k < 1 ? 1 : k;
333 c = c > 66 ? c : 66;
334 c = c > 117 ? 117 : c;
335 if (blink) {
336 if ((int) per[i] >= blinkper)
337 on[i] = !on[i];
338 else
339 on[i] = 1;
341 else
342 on[i] = 1;
344 for (j = 0; j < k; j++) {
345 if (mode == FIRE && on[i])
346 copyXPMArea(66 + (float) (j) * 52.0 / 50.0, 29, 1, 5, 6 + j, 5 + dy);
347 else if (mode == NORMAL && on[i])
348 copyXPMArea(c, 29, 1, 5, 6 + j, 5 + dy);
350 dy += 6;
353 if (numberfs < 9) {
354 for (j = 0, dx = 0, dy = 47; j < 10 && (unsigned int)j < strlen(hostname); j++) {
355 c = (int) hostname[j];
356 switch (c) {
357 case '/':
358 c = 123;
359 break;
360 case '_':
361 c = 124;
362 break;
363 case '-':
364 c = 125;
365 break;
366 case '.':
367 c = 126;
368 break;
369 case '0':
370 case '1':
371 case '2':
372 case '3':
373 case '4':
374 case '5':
375 case '6':
376 case '7':
377 case '8':
378 case '9':
379 c += 79;
380 break;
381 default:
382 c = tolower(c);
383 break;
385 copyXPMArea(xpos[c - 97], ypos[c - 97], 5, 5, 6 + dx, 6 + dy);
386 dx += 5;
390 RedrawWindow();
392 * Wait for next update
394 i = 0;
395 while (i < 10) {
396 usleep(delay);
397 i++;
405 * ParseCMDLine()
407 void
408 ParseCMDLine(int argc, char *argv[])
411 int c, option_index;
412 static struct option long_options[] = {
413 {"fire", no_argument, 0, 'f'},
414 {"normal", no_argument, 0, 'n'},
415 {"blink", no_argument, &blink, 1},
416 {"noblink", no_argument, &blink, 0},
417 {"delay", required_argument, 0, 'd'},
418 {"appearance", required_argument, 0, 'a'},
419 {"help", no_argument, 0, 'h'},
420 {"version", no_argument, 0, 'v'},
421 {0, 0, 0, 0}
423 while (1) {
424 c = getopt_long(argc, argv, "a:bd:fhnv", long_options, &option_index);
425 if (c == -1)
426 break;
427 switch (c) {
428 case 0: /* If blink or noblink was toggled */
429 break;
430 case 'a':
431 strcpy(appearance, optarg);
432 break;
433 case 'b':
434 blink = 1;
435 break;
436 case 'd':
437 delay = atoi(optarg);
438 break;
439 case 'f':
440 mode = FIRE;
441 break;
442 case 'h':
443 print_usage();
444 exit(0);
445 case 'n':
446 mode = NORMAL;
447 break;
448 case 'v':
449 printf("wmfsm version: %s\n", PACKAGE_VERSION);
450 exit(0);
451 case '?':
452 break;
453 default:
454 print_usage();
455 exit(1);
461 void
462 print_usage()
465 printf("usage: wmfsm \n");
466 printf("\t--normal, -n\t\tDraw bars in normal mode.\n");
467 printf("\t--fire, -f\t\tDraw bars in fire mode.\n");
468 printf("\t--[no]blink\t\tBlinks if a filesystem is 95 percent full.\n");
469 printf("\t-display <Display>\tUse alternate X display.\n");
470 printf("\t--delay <number>, -d\tUse a delay that is not the default.\n");
471 printf("\t--appearance <file>, -a\tSelect an appearance file.\n");
472 printf("\t-h\t\t\tDisplay help screen.\n");
475 void
476 pressEvent(XButtonEvent * xev)
478 (void)xev;
479 ForceUpdate = 1;
480 return;
483 void
484 readFileSystems()
486 /* Wipe mp[] */
487 int i;
488 for (i = 0; i < 100; i++)
489 if (mp[i]) {
490 free(mp[i]);
491 mp[i]=0;
494 /* Look for the goods between #if defined(__OpenBSD__) -- tschroed */
495 #if defined(__OpenBSD__) || defined(__FreeBSD__)
496 #define MAXMOUNT 32
497 struct statfs sfs[MAXMOUNT];
498 int fscount;
500 /* OpenBSD has no /etc/mtab, we use getfsstat instead -- tschroed */
501 if ((fscount = getfsstat(sfs, sizeof(sfs), 0)) == -1) {
502 perror("getfsstat");
503 exit(1);
505 for (numberfs = 0; numberfs < fscount; numberfs++)
506 /* We won't watch RO mounts. */
507 if (sfs[numberfs].f_flags & MNT_RDONLY) {
508 numberfs--;
509 fscount--;
511 else
512 mp[numberfs] = strdup(sfs[numberfs].f_mntonname);
513 #else /* __OpenBSD__ || __FreeBSD__ */
515 FILE *fp;
516 char mountPoint[255], dummy[255], fstype[255], options[255];
518 #if defined(SunOS)
519 /* Solaris uses /etc/mnttab */
520 fp = fopen("/etc/mnttab", "r");
521 if (!fp) {
522 fprintf(stderr, "%s:Can't open /etc/mnttab for reading\n", myName);
523 exit(1);
525 #else
526 fp = fopen("/etc/mtab", "r");
527 if (!fp) {
528 fprintf(stderr, "%s:Can't open /etc/mtab for reading\n", myName);
529 exit(1);
531 #endif
533 numberfs = 0;
534 while (!feof(fp) && numberfs < 100) {
535 #if defined(SunOS)
536 /* only five entries per row in /etc/mnttab */
537 if (fscanf(fp, "%s %s %s %s %s\n", dummy, mountPoint, fstype, options, dummy) < 5)
538 fprintf(stderr, "%s:/etc/mnttab not in expected format\n", myName);
539 #else
540 if (fscanf(fp, "%s %s %s %s %s %s\n", dummy, mountPoint, fstype, options, dummy, dummy) < 6)
541 fprintf(stderr, "%s:/etc/mtab not in expected format\n", myName);
542 #endif
544 if (
545 #if defined IRIX64 || defined(SunOS)
546 strcmp(fstype, "hwgfs") && strcmp(fstype, "autofs") && strcmp(fstype, "proc") && strcmp(fstype, "fd") && !strstr(options, "ignore")
547 #elif defined linux
548 strcmp(fstype, "proc") && strcmp(fstype, "tmpfs") && strcmp(fstype, "devfs") && strcmp(fstype, "ramfs") && strcmp(fstype, "sysfs") && strcmp(fstype, "devpts") && strcmp(fstype, "usbfs")
549 #else
551 #endif
553 if (mp[numberfs]) free(mp[numberfs]);
554 mp[numberfs++] = strdup(mountPoint);
557 #endif /* __OpenBSD__ || __FreeBSD__ */
559 fclose (fp);
560 excludeFileSystems();
563 void
564 excludeFileSystems()
566 char confFileName[255];
567 char workString[255];
568 int i, j, exnumberfs = 0;
569 int excluded, finalnumberfs = 0;
570 char *mount_points[100];
571 FILE *confFile;
572 int include = -1;
573 int included = 0;
575 strncpy(confFileName, (char *) getenv("HOME"), 245);
576 strcat(confFileName, "/.wmfsmrc");
577 confFile = fopen(confFileName, "r");
578 if (confFile) {
579 while (!feof(confFile)) {
580 if (fgets(workString, 255, confFile)) {
581 if(strstr(workString, "\n")){
582 /* This is probably dangerous, but easy */
583 *(strstr(workString, "\n")) = '\0';
585 if (!strcmp(workString, "[include]")) {
586 include = 1;
588 else if (!strcmp(workString, "[exclude]")) {
589 include = 0;
591 else {
592 mount_points[exnumberfs] = strdup(workString);
593 exnumberfs++;
598 if (include < 0) {
599 printf("wmfsm: Please specify either to include or exclude filesystems.\n");
600 exit(1);
602 fclose(confFile);
604 else {
605 numberfs = numberfs > 9 ? 9 : numberfs;
606 goto CLEANUP;
608 if (!exnumberfs) {
609 numberfs = numberfs > 9 ? 9 : numberfs;
610 goto CLEANUP;
612 excluded = 0;
613 for (i = 0; i < numberfs; i++) {
614 for (j = 0, excluded = 0; j < exnumberfs; j++) {
615 if (!strcmp(mp[i], mount_points[j]) && !include) {
616 excluded = 1;
617 } else if (!strcmp(mp[i], mount_points[j]) && include) {
618 included = 1;
621 if ((!excluded && !include) || (included && include)) {
622 if (finalnumberfs == i) {
623 finalnumberfs++;
624 } else {
625 if (mp[finalnumberfs]) free(mp[finalnumberfs]);
626 mp[finalnumberfs++] = strdup(mp[i]);
629 included = excluded = 0;
631 numberfs = finalnumberfs > 9 ? 9 : finalnumberfs;
633 CLEANUP:
634 for (j = 0; j < exnumberfs; j++)
635 if (mount_points[j]) {
636 free(mount_points[j]);
637 mount_points[j]=0;