wmshutdown: Destroy dialog window before shutting down. This is especially useful...
[dockapps.git] / wmifs / wmifs.c
blobe9dd8bbfba41338e9238a41741de7e1399f6c4de
1 /* WMiFS - a complete network monitoring dock.app
2 Copyright (C) 1997, 1998 Martijn Pieterse <pieterse@xs4all.nl>
3 Copyright (C) 1997, 1998 Antoine Nulle <warp@xs4all.nl>
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2 of the License, or
8 (at your option) any later version.
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License along
16 with this program; if not, write to the Free Software Foundation, Inc.,
17 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19 Best viewed with vim5, using ts=4
21 This code was mainly put together by looking at the
22 following programs:
24 asclock
25 A neat piece of equip, used to display the date
26 and time on the screen.
27 Comes with every AfterStep installation.
29 Source used:
30 How do I create a not so solid window?
31 How do I open a window?
32 How do I use pixmaps?
34 pppstats
35 A program that prints the amount of data that
36 is transferred over a ppp-line.
38 Source used:
39 How do I read the ppp device?
40 ------------------------------------------------------------
42 Author: Martijn Pieterse (pieterse@xs4all.nl)
44 This program was hacked together between the 7th of March
45 and the 14th of March 1998.
47 This program might be Y2K resistant. We shall see. :)
49 This program is distributed under the GPL license.
50 (as were asclock and pppstats)
52 Known Features: (or in non M$ talk, BUGS)
53 * only ppp0 will be read
54 use wmifs if you want to read more than one ppp connection
55 not sure about this.
56 * the leds won't be reliable with
57 more than 1 ppp connection
58 * there is an iconwin, and win variable.
59 I have no clue why only win shouldn't
60 be enough. Will check it out later.
61 * The afterstep what seems the shift the
62 pixmap a bit. Don't know how and why.
63 It works in the WindowManager.
65 Things to do:
66 Split up main()
68 ----
69 Thanks
70 ----
72 Most of the ideas, and jumpstarting it:
74 #linuxnl, without this irc-channel wmppp would've never seen the light!
76 CCC (Constructive Code Criticism):
78 Marcelo E. Magallon
79 Thanks a LOT! It takes a while to get me convinced... :)
82 Minor bugs and ideas:
84 Marc De Scheemaecker / David Mihm / Chris Soghoian /
85 Alessandro Usseglio Viretta
87 and ofcourse numerous ppl who send us bug reports.
88 (numerous? hmm.. todo: rephrase this :) )
91 ----
92 Changes:
93 ---
94 02/29/2004 (Tom Marshall, tommy@home.tig-grr.com)
95 * Patch to add a special interface name "auto" for the -i
96 option. "wmifs -i auto" will automatically select the
97 first up interface.
98 01/08/2004 (Peter Samuelson, peter@samba-tng.org)
99 * Patch to make make sampling and scrolling intervals
100 customizable, adds new options -I and -s.
101 01/15/2002 (Matyas Koszik, koszik@debijan.lonyay.edu.hu)
102 * Patch that fixes segfaults on long interface names.
103 08/31/2001 (Davi Leal, davileal@terra.es)
104 * Patch that cuts long interface names, so they look
105 good in wmifs. For example, "dummy0" gets displayed
106 as "dumm0", "vmnet10" as "vmn10", etc.
107 06/16/2001 (Jorge GarcĂ­a, Jorge.Garcia@uv.es)
108 * Added the LockMode, so wmifs doesn't swap to another
109 interface if the one requested with "-i" isn't up.
110 05/06/2001 (Jordi Mallach, jordi@sindominio.net)
111 * Integrated many patches, fixing issues with suspended
112 wmifs.
113 07/21/1999 (Stephen Pitts, smpitts@midsouth.rr.com)
114 * Added new constant: BUFFER_SIZE to determine the size
115 of the buffer used in fgets() operations. Right now,
116 its at 512 bytes. Fixed crashing on my system when
117 one line of /proc/net/dev was longer than 128 bytes
118 04/05/1998 (Martijn Pieterse, pieterse@xs4all.nl)
119 * Changed the "middle of the waveform" line color
120 * Moved the RedrawWindow out of the main loop.
121 Lightens the system load
122 02/05/1998 (Martijn Pieterse, pieterse@xs4all.nl)
123 * Torn wmppp and wmifs apart.
124 This is gonna be wmifs
125 * Added parse_rcfile
126 * Added waitpid, to get rid of the zombies, spotteb by Alessandro Usseglio Viretta
127 30/04/1998 (Martijn Pieterse, pieterse@xs4all.nl)
128 * Used the DrawStats routine from wmifs in wmppp
129 * I decided to add a list in this source file
130 with name of ppl who helped me build this code better.
131 * I finally removed the /proc/net/route dependency
132 All of the connections are taken from /proc/net/dev.
133 /proc/net/route is still used for checking if it is on-line.
134 27/04/1998 (Martijn Pieterse, pieterse@xs4all.nl)
135 * WMIFS: stats scrolled, while red led burning
136 * WMPPP: changed positions of line speed
137 25/04/1998 (Martijn Pieterse, pieterse@xs4all.nl)
138 * Changed the checknetdevs routine, a lot!
139 23/04/1998 (Martijn Pieterse, pieterse@xs4all.nl)
140 * Added line speed detection. via separate exec. (this has to be suid root!)
141 Speed has to be no more than 99999
142 * Added speed and forcespeed in ~/.wmppprc and /etc/wmppprc
143 * wmifs: added on-line detection scheme, update the bitmap coordinates
144 * wmppp: the x-button now allways disconnects.
145 22/04/1998 (Martijn Pieterse, pieterse@xs4all.nl)
146 * Added /etc/wmppprc support, including "forced" mode.
147 * Added /etc/wmifsrc support, including "forced" mode.
148 21/04/1998 (Martijn Pieterse, pieterse@xs4all.nl)
149 * Moved the stats one pixel down.
150 * Added status led in wmifs.
151 * Changed RX/TX leds of wmifs to resemble wmppp
152 * Added the "dot" between eth.0 ppp.0 etc.
153 * Changed to wmifs stats to match wmppp stats (only pppX changed)
154 * Made sure that when specified -t 1, it stayed that way, even
155 when longer than 100 minutes online
156 * With -t 1, jump from 59:59 to 01:00 instead of 99:59 to 01:40
157 16/04/1998 (Martijn Pieterse, pieterse@xs4all.nl)
158 * Added "all" devices in wmifs
159 * Added "lo" support only if aked via -i
160 * Added on-line time detection (using /var/run/ppp0.pid)
161 * Added time-out for the orange led. (one minute)
162 15/04/1998 (Martijn Pieterse, pieterse@xs4all.nl)
163 * Another wmppp-master.xpm.
164 Line speed detection being the main problem here.. :(
165 * Moved START_COMMAND / STOP_COMMAND to ~/.wmppprc
166 Return 0, everything went ok.
167 Return 10, the command did not work.
168 Please note, these functions are ran in the background.
169 * Removed the ability to configure
170 * When "v" is clicked, an orange led will appear.
171 if the connect script fails (return value == 10)
172 it will become dark again. Else the on-line detection will
173 pick it up, and "green" it.
174 14/04/1998 (Martijn Pieterse, pieterse@xs4all.nl)
175 * Added "-timer"
176 * Added "-display" support
177 * Changed pixmap to a no-name pixmap.
178 + Changed LED positions
179 + Changed Timer position
180 + Changed Stats Size
181 05/04/1998 (Martijn Pieterse, pieterse@xs4all.nl)
182 * Added ~/.wmifsrc support.
183 * Put some code in DrawStats
184 * Check devices when pressing "device change"
185 03/04/1998 (Martijn Pieterse, pieterse@xs4all.nl)
186 * Added code for wmifs
187 28/03/1998 (Martijn Pieterse, pieterse@xs4all.nl)
188 * forgot what i did.. :)
189 27/03/1998 (Martijn Pieterse, pieterse@xs4all.nl)
190 * Added on-line detection
191 Scan through /proc/net/route and check everye line
192 for "ppp".
193 * A bit of code clean-up.
196 #define _DEFAULT_SOURCE
197 #include <X11/X.h> /* for ButtonPress, ButtonRelease, etc */
198 #include <X11/Xlib.h> /* for XEvent, XButtonEvent, etc */
199 #include <X11/xpm.h> /* for XpmColorSymbol, Pixel, etc */
200 #include <ctype.h> /* for toupper */
201 #include <linux/ppp_defs.h> /* for ppp_stats, pppstat */
202 #include <net/if_ppp.h> /* for ifpppstatsreq, ifr__name, etc */
203 #include <stddef.h> /* for size_t */
204 #include <stdio.h> /* for fprintf, NULL, stderr, etc */
205 #include <stdlib.h> /* for exit, atof, atoi, getenv */
206 #include <string.h> /* for strcmp, strcpy, strlen, etc */
207 #include <sys/ioctl.h> /* for ioctl */
208 #include <sys/socket.h> /* for socket, AF_INET */
209 #include <sys/time.h> /* for timeval, gettimeofday */
210 #include <sys/wait.h> /* for waitpid, WNOHANG */
211 #include <time.h> /* for timespec, nanosleep */
212 #include <libdockapp/misc.h> /* for execCommand */
213 #include <libdockapp/wmgeneral.h> /* for copyXPMArea, display, etc */
214 #include "wmifs-mask.xbm" /* for wmifs_mask_bits, etc */
215 #include "wmifs-master.xpm" /* for wmifs_master_xpm */
217 /* How often to check for new network interface, in ms */
218 #define CHECK_INTERFACE_INTERVAL 5000
220 /* How often to query the interfaces, in ms */
221 #define DEFAULT_SAMPLE_INTERVAL 50
223 /***********/
224 /* Defines */
225 /***********/
227 #ifndef ifr__name
228 #define ifr__name ifr_name
229 #endif
231 #ifndef stats_ptr
232 #define stats_ptr stats.p.FIXME
233 #endif
235 /* Fill in and uncomment the hardcoded actions */
236 /* #define LEFT_ACTION (NULL) */
237 /* #define MIDDLE_ACTION (NULL) */
238 /* #define RIGHT_ACTION (NULL) */
240 /* Defines voor alle coordinate */
242 #define LED_NET_RX (4)
243 #define LED_NET_TX (5)
244 #define LED_NET_POWER (6)
246 /* the size of the buffer read from /proc/net/ */
247 #define BUFFER_SIZE 512
249 /**********************/
250 /* External Variables */
251 /**********************/
253 extern char **environ;
255 /********************/
256 /* Global Variables */
257 /********************/
259 char *active_interface = NULL;
260 int TimerDivisor = 60;
261 int WaveForm = 0;
262 int LockMode = 0;
263 int SampleInt = DEFAULT_SAMPLE_INTERVAL;
264 int ScrollSpeed = CHECK_INTERFACE_INTERVAL;
265 XpmIcon wmgen;
266 char color[256];
268 /*****************/
269 /* PPP variables */
270 /*****************/
272 #define PPP_UNIT 0
273 int ppp_h = -1;
275 #define PPP_STATS_HIS 54
277 /***********************/
278 /* Function Prototypes */
279 /***********************/
281 void usage(void);
282 void printversion(void);
283 void DrawTime(int, int);
284 void DrawStats(int *, int, int, int, int);
286 void SetOnLED(int);
287 void SetErrLED(int);
288 void SetWaitLED(int);
289 void SetOffLED(int);
291 void ButtonUp(int);
292 void ButtonDown(int);
294 void wmifs_routine(int, char **);
296 void get_ppp_stats(struct ppp_stats *cur);
299 /********/
300 /* Main */
301 /********/
303 int main(int argc, char *argv[])
306 int i;
308 color[0] = 0;
310 /* Parse Command Line */
312 for (i = 1; i < argc; i++) {
313 char *arg = argv[i];
315 if (*arg == '-') {
316 switch (arg[1]) {
317 case 'c' :
318 if (argc > i+1) {
319 strncpy(color, argv[i+1], sizeof(color));
320 i++;
322 break;
323 case 'd':
324 if (strcmp(arg+1, "display")) {
325 usage();
326 exit(1);
328 break;
329 case 'g':
330 if (strcmp(arg+1, "geometry")) {
331 usage();
332 exit(1);
334 break;
335 case 'i':
336 active_interface = argv[i+1];
337 i++;
338 break;
339 case 'I':
340 SampleInt = atof(argv[i+1]) * 1000;
341 i++;
342 break;
343 case 'l':
344 LockMode = 1;
345 break;
346 case 's':
347 ScrollSpeed = atof(argv[i+1]) * 1000;
348 i++;
349 break;
350 case 'v':
351 printversion();
352 exit(0);
353 break;
354 case 'w':
355 WaveForm = 1;
356 break;
357 default:
358 if (strcmp(argv[i-1], "-geometry")) {
359 usage();
360 exit(0);
362 break;
367 wmifs_routine(argc, argv);
368 return 0;
371 Pixel scale_pixel(Pixel pixel, float scale)
373 int red, green, blue;
375 red = pixel / ( 1 << 16 );
376 green = pixel % (1 << 16) / (1 << 8);
377 blue = pixel % (1 << 8);
379 red *= scale;
380 green *= scale;
381 blue *= scale;
383 return red * (1 << 16) + green * (1 << 8) + blue;
386 /*******************************************************************************\
387 |* wmifs_routine *|
388 \*******************************************************************************/
390 #define MAX_STAT_DEVICES 16
392 typedef struct {
394 char name[IFNAMSIZ];
395 int his[55][2];
396 long istatlast;
397 long ostatlast;
399 } stat_dev;
401 stat_dev stat_devices[MAX_STAT_DEVICES];
403 char *left_action = NULL;
404 char *right_action = NULL;
405 char *middle_action = NULL;
407 int checknetdevs(void);
408 int get_statistics(char *, long *, long *, long *, long *);
409 int stillonline(char *);
410 void DrawActiveIFS(char *);
412 void wmifs_routine(int argc, char **argv)
415 rckeys wmifs_keys[] = {
416 { "left", &left_action },
417 { "middle", &middle_action },
418 { "right", &right_action },
419 { NULL, NULL }
423 int i, j;
424 XEvent Event;
425 int but_stat = -1;
427 int stat_online;
428 int stat_current;
429 int first_time = 1;
431 unsigned int curtime;
432 unsigned int nexttime;
433 struct timeval tv, tv2;
435 long ipacket, opacket, istat, ostat;
437 char temp[BUFFER_SIZE];
438 char *p;
440 for (i = 0; i < MAX_STAT_DEVICES; i++) {
441 stat_devices[i].name[0] = 0;
442 for (j = 0; j < 48; j++) {
443 stat_devices[i].his[j][0] = 0;
444 stat_devices[i].his[j][1] = 0;
448 stat_online = checknetdevs();
450 stat_current = 0;
451 if (active_interface) {
452 int isauto = !strcmp(active_interface, "auto");
453 for (i = 0; i < stat_online; i++) {
454 if ((isauto && stillonline(stat_devices[i].name)) ||
455 !strcmp(stat_devices[i].name, active_interface)) {
456 stat_current = i;
457 break;
462 #ifdef LEFT_ACTION
463 left_action = strdup(LEFT_ACTION);
464 #endif
465 #ifdef MIDDLE_ACTION
466 middle_action = strdup(MIDDLE_ACTION);
467 #endif
468 #ifdef RIGHT_ACTION
469 right_action = strdup(RIGHT_ACTION);
470 #endif
472 /* Scan throught the .rc files */
473 parse_rcfile(CONF"/wmifsrc", wmifs_keys);
475 p = getenv("HOME");
476 if (p == NULL || *p == 0) {
477 fprintf(stderr, "Unknown $HOME directory, please check your environment\n");
478 return;
480 strncpy(temp, p, BUFFER_SIZE - 10);
481 strcat(temp, "/.wmifsrc");
482 parse_rcfile(temp, wmifs_keys);
484 parse_rcfile(CONF"/wmifsrc.fixed", wmifs_keys);
486 /* set user-defined colors */
487 if (color[0] != 0) {
488 Window Root;
489 XColor col;
490 XWindowAttributes attributes;
491 int screen;
492 Pixel pixel;
493 #define NUMSYMBOLS 4
494 XpmColorSymbol user_color[NUMSYMBOLS] = {
495 {NULL, "#2081B2CAAEBA", 0}, /* + */
496 {NULL, "#28A23CF338E3", 0}, /* O */
497 {NULL, "#000049244103", 0}, /* @ */
498 {NULL, "#18618A288617", 0}, /* # */
502 /* code based on GetColor() from wmgeneral.c */
503 /* we need a temporary display to parse the color */
504 display = XOpenDisplay(NULL);
505 screen = DefaultScreen(display);
506 Root = RootWindow(display, screen);
507 XGetWindowAttributes(display, Root, &attributes);
509 col.pixel = 0;
510 if (!XParseColor(display, attributes.colormap, color, &col)) {
511 fprintf(stderr, "wmtime: can't parse %s.\n", color);
512 goto draw_window;
513 } else if (!XAllocColor(display, attributes.colormap, &col)) {
514 fprintf(stderr, "wmtime: can't allocate %s.\n", color);
515 goto draw_window;
518 pixel = col.pixel;
520 /* replace colors from wmtime-master.xpm */
521 user_color[0].pixel = pixel;
522 user_color[1].pixel = scale_pixel(pixel, .3);
523 user_color[2].pixel = scale_pixel(pixel, .4);
524 user_color[3].pixel = scale_pixel(pixel, .8);
526 wmgen.attributes.valuemask |= XpmColorSymbols;
527 wmgen.attributes.numsymbols = NUMSYMBOLS;
528 wmgen.attributes.colorsymbols = user_color;
530 XCloseDisplay(display);
533 draw_window:
534 openXwindow(argc, argv, wmifs_master_xpm, (char*)wmifs_mask_bits, wmifs_mask_width, wmifs_mask_height);
536 /* > Button */
537 AddMouseRegion(0, 5, 5, 35, 15);
538 AddMouseRegion(1, 5, 20, 58, 58);
540 gettimeofday(&tv2, NULL);
541 nexttime = ScrollSpeed;
543 DrawActiveIFS(stat_devices[stat_current].name);
545 while (1) {
546 struct timespec ts;
548 gettimeofday(&tv, NULL);
549 curtime = (tv.tv_sec - tv2.tv_sec) * 1000
550 + (tv.tv_usec - tv2.tv_usec) / 1000;
552 waitpid(0, NULL, WNOHANG);
554 for (i = 0; i < stat_online; i++) {
555 get_statistics(stat_devices[i].name, &ipacket, &opacket, &istat, &ostat);
557 if (first_time) {
558 first_time = 0;
559 } else {
560 stat_devices[i].his[53][0] += istat - stat_devices[i].istatlast;
561 stat_devices[i].his[53][1] += ostat - stat_devices[i].ostatlast;
564 if (i == stat_current) {
565 if (!stillonline(stat_devices[i].name))
566 SetErrLED(LED_NET_POWER);
567 else
568 SetOnLED(LED_NET_POWER);
570 if (stat_devices[i].istatlast == istat)
571 SetOffLED(LED_NET_RX);
572 else
573 SetOnLED(LED_NET_RX);
575 if (stat_devices[i].ostatlast == ostat)
576 SetOffLED(LED_NET_TX);
577 else
578 SetOnLED(LED_NET_TX);
581 stat_devices[i].istatlast = istat;
582 stat_devices[i].ostatlast = ostat;
584 RedrawWindow();
586 if (curtime >= nexttime) {
587 nexttime = curtime + ScrollSpeed;
589 DrawStats(&stat_devices[stat_current].his[0][0], 54, 40, 5, 58);
590 for (i = 0; i < stat_online; i++) {
591 if (stillonline(stat_devices[i].name)) {
592 for (j = 1; j < 54; j++) {
593 stat_devices[i].his[j-1][0] = stat_devices[i].his[j][0];
594 stat_devices[i].his[j-1][1] = stat_devices[i].his[j][1];
596 stat_devices[i].his[53][0] = 0;
597 stat_devices[i].his[53][1] = 0;
600 RedrawWindow();
603 while (XPending(display)) {
604 XNextEvent(display, &Event);
605 switch (Event.type) {
606 case Expose:
607 RedrawWindow();
608 break;
609 case DestroyNotify:
610 XCloseDisplay(display);
611 exit(0);
612 break;
613 case ButtonPress:
614 but_stat = CheckMouseRegion(Event.xbutton.x, Event.xbutton.y);
615 break;
616 case ButtonRelease:
617 i = CheckMouseRegion(Event.xbutton.x, Event.xbutton.y);
619 if (but_stat == i && but_stat >= 0) {
620 switch (but_stat) {
621 case 0:
622 /* re-read the table */
623 strcpy(temp, stat_devices[stat_current].name);
624 stat_online = checknetdevs();
625 stat_current = 0;
626 for (i = 0; i < stat_online; i++) {
627 if (!strcmp(temp, stat_devices[i].name))
628 stat_current = i;
631 stat_current++;
632 if (stat_current == stat_online)
633 stat_current = 0;
635 DrawActiveIFS(stat_devices[stat_current].name);
637 DrawStats(&stat_devices[stat_current].his[0][0], 54, 40, 5, 58);
638 break;
639 case 1:
640 switch (Event.xbutton.button) {
641 case 1:
642 if (left_action)
643 execCommand(left_action);
644 break;
645 case 2:
646 if (middle_action)
647 execCommand(middle_action);
648 break;
649 case 3:
650 if (right_action)
651 execCommand(right_action);
652 break;
654 break;
658 but_stat = -1;
659 RedrawWindow();
660 break;
663 ts.tv_sec = 0;
664 ts.tv_nsec = SampleInt * 1000000;
665 nanosleep(&ts, NULL);
669 /*******************************************************************************\
670 |* void DrawActiveIFS(char *) *|
671 \*******************************************************************************/
673 void DrawActiveIFS(char *real_name)
676 /* Cijfers op: 0,65
677 Letters op: 0,75
678 Alles 9 hoog, 6 breedt
680 Destinatie: 5,5
683 size_t i;
684 int k;
685 size_t len;
686 char name[256];
689 copyXPMArea(5, 84, 30, 10, 5, 5);
692 strcpy(name, real_name);
693 len = strlen(name);
694 if (len > 5) {
695 for (i = len-5; i < len && !(name[i] >= '0' && name[i] <= '9'); i++)
697 for (; i <= len; i++) /* '=' to get the '\0' character moved too \*/
698 name[i-(len-5)] = name[i];
701 k = 5;
702 for (i = 0; name[i]; i++) {
703 int c;
705 if (i == strlen(name)-1 && strlen(name) <= 4 && name[strlen(name)-1] >= '0' &&
706 name[strlen(name)-1] <= '9') {
707 copyXPMArea(61, 64, 4, 9, k, 5);
708 k += 4;
710 c = toupper(name[i]);
711 if (c >= 'A' && c <= 'Z') {
712 c -= 'A';
713 copyXPMArea(c * 6, 74, 6, 9, k, 5);
714 k += 6;
715 } else {
716 c -= '0';
717 copyXPMArea(c * 6, 64, 6, 9, k, 5);
718 k += 6;
724 /*******************************************************************************\
725 |* get_statistics *|
726 \*******************************************************************************/
728 int get_statistics(char *devname, long *ip, long *op, long *is, long *os)
731 FILE *fp;
732 char temp[BUFFER_SIZE];
733 char *p, *saveptr;
734 char *tokens = " |:\n";
735 int input, output;
736 int i;
737 int found;
738 struct ppp_stats ppp_cur;
741 if (!strncmp(devname, "ppp", 3)) {
742 static int ppp_opened;
744 if (!ppp_opened) {
745 /* Open the ppp device. */
746 memset(&ppp_cur, 0, sizeof(ppp_cur));
747 ppp_h = socket(AF_INET, SOCK_DGRAM, 0);
748 if (ppp_h < 0)
749 return -1;
750 get_ppp_stats(&ppp_cur);
751 ppp_opened = 1;
754 get_ppp_stats(&ppp_cur);
756 *op = ppp_cur.p.ppp_opackets;
757 *ip = ppp_cur.p.ppp_ipackets;
759 *is = ppp_cur.p.ppp_ibytes;
760 *os = ppp_cur.p.ppp_obytes;
762 return 0;
765 /* Read from /proc/net/dev the stats! */
766 fp = fopen("/proc/net/dev", "r");
767 if (!fp)
768 return -1;
769 if (!fgets(temp, BUFFER_SIZE, fp)) {
770 fclose(fp);
771 return -1;
773 if (!fgets(temp, BUFFER_SIZE, fp)) {
774 fclose(fp);
775 return -1;
778 input = -1;
779 output = -1;
780 i = 0;
781 found = -1;
783 p = strtok_r(temp, tokens, &saveptr);
784 do {
785 if (!(strcmp(p, "packets"))) {
786 if (input == -1)
787 input = i;
788 else
789 output = i;
791 i++;
792 p = strtok_r(NULL, tokens, &saveptr);
793 } while (input == -1 || output == -1);
795 while (fgets(temp, BUFFER_SIZE, fp)) {
796 if (strstr(temp, devname)) {
797 found = 0;
798 p = strtok_r(temp, tokens, &saveptr);
799 i = 0;
800 do {
801 if (i == input) {
802 *ip = *is = atoi(p);
803 input = -1;
805 if (i == output) {
806 *op = *os = atoi(p);
807 output = -1;
809 i++;
810 p = strtok_r(NULL, tokens, &saveptr);
811 } while (input != -1 || output != -1);
814 fclose(fp);
816 return found;
819 /*******************************************************************************\
820 |* stillonline *|
821 \*******************************************************************************/
823 int stillonline(char *ifs)
826 FILE *fp;
827 int i;
829 i = 0;
830 fp = fopen("/proc/net/route", "r");
831 if (fp) {
832 char temp[BUFFER_SIZE];
834 while (fgets(temp, BUFFER_SIZE, fp)) {
835 if (strstr(temp, ifs)) {
836 i = 1; /* Line is alive */
837 break;
840 fclose(fp);
842 return i;
845 /*******************************************************************************\
846 |* checknetdevs *|
847 \*******************************************************************************/
849 int checknetdevs(void)
852 FILE *fd;
853 int i = 0, j;
854 int k;
855 int devsfound = 0;
856 char foundbuffer[MAX_STAT_DEVICES][IFNAMSIZ];
858 for (i = 0; i < MAX_STAT_DEVICES; i++)
859 foundbuffer[i][0] = 0;
861 /* foundbuffer vullen met info uit /proc/net/dev */
863 fd = fopen("/proc/net/dev", "r");
864 if (fd) {
865 char temp[BUFFER_SIZE];
867 /* Skip the first 2 lines */
868 if (!fgets(temp, BUFFER_SIZE, fd)) {
869 fclose(fd);
870 return -1;
872 if (!fgets(temp, BUFFER_SIZE, fd)) {
873 fclose(fd);
874 return -1;
876 while (fgets(temp, BUFFER_SIZE, fd)) {
877 char *p, *saveptr;
878 char *tokens = " :\t\n";
880 p = strtok_r(temp, tokens, &saveptr);
881 if (p == NULL) {
882 printf("Barfed on: %s", temp);
883 break;
885 /* Skip dummy code */
887 if (!strncmp(p, "dummy", 5))
888 continue;
890 /* If p == "lo", and active_interface (as given on the cmd line) != "lo",
891 skip it! */
893 if (strcmp(p, "lo") || (active_interface && !strcmp(active_interface, "lo"))) {
894 strncpy(foundbuffer[devsfound], p, IFNAMSIZ);
895 devsfound++;
897 if (devsfound >= MAX_STAT_DEVICES)
898 break;
900 fclose(fd);
903 /* Nu foundbuffer naar stat_devices[].name kopieeren */
905 for (i = 0; i < MAX_STAT_DEVICES; i++) {
906 /* Loop stat_devices na, als die naam niet voorkomt in foundbuffer, kill! */
908 if (stat_devices[i].name[0]) {
909 k = 0;
910 for (j = 0; j < MAX_STAT_DEVICES; j++) {
911 if (!strcmp(stat_devices[i].name, foundbuffer[j])) {
912 k = 1;
913 foundbuffer[j][0] = 0;
916 if (!k)
917 stat_devices[i].name[0] = 0;
921 for (i = 0, j = 0; j < MAX_STAT_DEVICES; i++, j++) {
923 while (!stat_devices[j].name[0] && j < MAX_STAT_DEVICES)
924 j++;
926 if (j < MAX_STAT_DEVICES && i != j)
927 stat_devices[i] = stat_devices[j];
929 i--;
931 for (j = 0; j < MAX_STAT_DEVICES; j++) {
932 if (foundbuffer[j][0]) {
934 strncpy(stat_devices[i].name, foundbuffer[j], IFNAMSIZ);
936 for (k = 0; k < 48; k++) {
937 stat_devices[i].his[k][0] = 0;
938 stat_devices[i].his[k][1] = 0;
941 i++;
944 if (LockMode && active_interface != NULL) {
945 k = 0;
946 for (j = 0; j < i; j++)
947 if (!strcmp(stat_devices[j].name, active_interface)) {
948 k = 1;
949 break;
951 if (!k) {
952 strncpy(stat_devices[i].name, active_interface, IFNAMSIZ);
953 for (k = 0; k < 48; k++) {
954 stat_devices[i].his[k][0] = 0;
955 stat_devices[i].his[k][1] = 0;
957 devsfound++;
961 return devsfound;
964 /*******************************************************************************\
965 |* DrawStats *|
966 \*******************************************************************************/
968 void DrawStats(int *his, int num, int size, int x_left, int y_bottom)
971 int pixels_per_byte;
972 int j, k;
973 int *p;
974 int p2, p3;
976 pixels_per_byte = size;
977 p = his;
978 for (j = 0; j < num; j++) {
979 if (p[0] + p[1] > pixels_per_byte)
980 pixels_per_byte = p[0] + p[1];
981 p += 2;
984 pixels_per_byte /= size;
985 p = his;
987 for (k = 0; k < num; k++) {
988 int p0, p1;
990 p0 = p[0];
991 p1 = p[1];
994 if (WaveForm) {
995 p2 = 0;
996 p3 = 1;
997 for (j = 0; j < size; j++) {
998 if (j < p0 / pixels_per_byte)
999 copyXPMArea(100+2, 68, 1, 1, k+x_left, y_bottom-size/2+p2/2);
1000 else if (j < (p0 + p1) / pixels_per_byte)
1001 copyXPMArea(100+1, 68, 1, 1, k+x_left, y_bottom-size/2+p2/2);
1002 else
1003 copyXPMArea(100+0, 68, 1, 1, k+x_left, y_bottom-size/2+p2/2);
1005 p2 = (p2 + p3);
1006 p3 *= -1;
1007 p2 *= -1;
1009 copyXPMArea(100+3, 68, 1, 1, k+x_left, y_bottom-size/2);
1010 } else {
1011 for (j = 0; j < size; j++) {
1012 if (j < p0 / pixels_per_byte)
1013 copyXPMArea(100+2, 68, 1, 1, k+x_left, y_bottom-j);
1014 else if (j < (p0 + p1) / pixels_per_byte)
1015 copyXPMArea(100+1, 68, 1, 1, k+x_left, y_bottom-j);
1016 else
1017 copyXPMArea(100+0, 68, 1, 1, k+x_left, y_bottom-j);
1020 p += 2;
1024 /*******************************************************************************\
1025 |* usage *|
1026 \*******************************************************************************/
1028 void usage(void)
1031 fprintf(stderr, "\nwmifs - programming: tijno, (de)bugging & design: warpstah, webhosting: bobby\n\n");
1032 fprintf(stderr, "usage:\n");
1033 fprintf(stderr, "\t-c <color>\t\tset color\n");
1034 fprintf(stderr, "\t-display <display name>\tset display\n");
1035 fprintf(stderr, "\t-geometry +x+y\t\tset window position\n");
1036 fprintf(stderr, "\t-h\t\t\tthis help screen\n");
1037 fprintf(stderr, "\t-i <interface name>\tdefault (as it appears in /proc/net/route)\n");
1038 fprintf(stderr, "\t-I <interval>\t\tsampling interval, in seconds (default: 0.05)\n");
1039 fprintf(stderr, "\t-l\t\t\tstarts in lock mode\n");
1040 fprintf(stderr, "\t-s <interval>\t\tscrolling interval, in seconds (default: 5)\n");
1041 fprintf(stderr, "\t-v\t\t\tprint the version number\n");
1042 fprintf(stderr, "\t-w\t\t\twaveform load\n");
1043 fprintf(stderr, "\n");
1046 /*******************************************************************************\
1047 |* printversion *|
1048 \*******************************************************************************/
1050 void printversion(void)
1053 fprintf(stderr, "%s\n", PACKAGE_STRING);
1056 /*******************************************************************************\
1057 |* get_ppp_stats *|
1058 \*******************************************************************************/
1060 void get_ppp_stats(struct ppp_stats *cur)
1063 struct ifpppstatsreq req;
1065 memset(&req, 0, sizeof(req));
1067 req.stats_ptr = (void *) &req.stats;
1069 sprintf(req.ifr__name, "ppp%d", PPP_UNIT);
1071 if (ioctl(ppp_h, SIOCGPPPSTATS, &req) < 0) {
1072 /* fprintf(stderr, "heyho!\n") */;
1074 *cur = req.stats;
1077 #define LED_SZE_X (4)
1078 #define LED_SZE_Y (4)
1080 #define LED_ON_NET_X (87)
1081 #define LED_ON_NET_Y (66)
1082 #define LED_OFF_NET_X (93)
1083 #define LED_OFF_NET_Y (66)
1084 #define LED_ERR_NET_X (81)
1085 #define LED_ERR_NET_Y (66)
1086 #define LED_ON_SW_NET_X (49)
1087 #define LED_ON_SW_NET_Y (85)
1088 #define LED_OFF_SW_NET_X (44)
1089 #define LED_OFF_SW_NET_Y (85)
1091 #define LED_PWR_X (53)
1092 #define LED_PWR_Y (7)
1093 #define LED_SND_X (47)
1094 #define LED_SND_Y (7)
1095 #define LED_RCV_X (41)
1096 #define LED_RCV_Y (7)
1098 #define LED_SW_X (38)
1099 #define LED_SW_Y (14)
1101 /*******************************************************************************\
1102 |* SetOnLED *|
1103 \*******************************************************************************/
1104 void SetOnLED(int led)
1107 switch (led) {
1109 case LED_NET_RX:
1110 copyXPMArea(LED_ON_NET_X, LED_ON_NET_Y, LED_SZE_X, LED_SZE_Y, LED_RCV_X, LED_RCV_Y);
1111 break;
1112 case LED_NET_TX:
1113 copyXPMArea(LED_ON_NET_X, LED_ON_NET_Y, LED_SZE_X, LED_SZE_Y, LED_SND_X, LED_SND_Y);
1114 break;
1115 case LED_NET_POWER:
1116 copyXPMArea(LED_ON_NET_X, LED_ON_NET_Y, LED_SZE_X, LED_SZE_Y, LED_PWR_X, LED_PWR_Y);
1117 break;
1121 /*******************************************************************************\
1122 |* SetOffLED *|
1123 \*******************************************************************************/
1124 void SetOffLED(int led)
1127 switch (led) {
1129 case LED_NET_RX:
1130 copyXPMArea(LED_OFF_NET_X, LED_OFF_NET_Y, LED_SZE_X, LED_SZE_Y, LED_RCV_X, LED_RCV_Y);
1131 break;
1132 case LED_NET_TX:
1133 copyXPMArea(LED_OFF_NET_X, LED_OFF_NET_Y, LED_SZE_X, LED_SZE_Y, LED_SND_X, LED_SND_Y);
1134 break;
1135 case LED_NET_POWER:
1136 copyXPMArea(LED_OFF_NET_X, LED_OFF_NET_Y, LED_SZE_X, LED_SZE_Y, LED_PWR_X, LED_PWR_Y);
1137 break;
1141 /*******************************************************************************\
1142 |* SetErrLED *|
1143 \*******************************************************************************/
1144 void SetErrLED(int led)
1147 switch (led) {
1148 case LED_NET_POWER:
1149 copyXPMArea(LED_ERR_NET_X, LED_ERR_NET_Y, LED_SZE_X, LED_SZE_Y, LED_PWR_X, LED_PWR_Y);
1150 break;