wmifs: Make sampling and scrolling intervals customizable.
[dockapps.git] / wmifs / wmifs / wmifs.c
blob9f5374bbcf2903cfe09c18b00a749cbb738b4286
1 /*
2 Best viewed with vim5, using ts=4
4 This code was mainly put together by looking at the
5 following programs:
7 asclock
8 A neat piece of equip, used to display the date
9 and time on the screen.
10 Comes with every AfterStep installation.
12 Source used:
13 How do I create a not so solid window?
14 How do I open a window?
15 How do I use pixmaps?
17 pppstats
18 A program that prints the amount of data that
19 is transferred over a ppp-line.
21 Source used:
22 How do I read the ppp device?
23 ------------------------------------------------------------
25 Author: Martijn Pieterse (pieterse@xs4all.nl)
27 This program was hacked together between the 7th of March
28 and the 14th of March 1998.
30 This program might be Y2K resistant. We shall see. :)
32 This program is distributed under the GPL license.
33 (as were asclock and pppstats)
35 Known Features: (or in non M$ talk, BUGS)
36 * only ppp0 will be read
37 use wmifs if you want to read more than one ppp connection
38 not sure about this.
39 * the leds won't be reliable with
40 more than 1 ppp connection
41 * there is an iconwin, and win variable.
42 I have no clue why only win shouldn't
43 be enough. Will check it out later.
44 * The afterstep what seems the shift the
45 pixmap a bit. Don't know how and why.
46 It works in the WindowManager.
48 Things to do:
49 Split up main()
51 ----
52 Thanks
53 ----
55 Most of the ideas, and jumpstarting it:
57 #linuxnl, without this irc-channel wmppp would've never seen the light!
59 CCC (Constructive Code Criticism):
61 Marcelo E. Magallon
62 Thanks a LOT! It takes a while to get me convinced... :)
65 Minor bugs and ideas:
67 Marc De Scheemaecker / David Mihm / Chris Soghoian /
68 Alessandro Usseglio Viretta
70 and ofcourse numerous ppl who send us bug reports.
71 (numerous? hmm.. todo: rephrase this :) )
74 ----
75 Changes:
76 ---
77 01/08/2004 (Peter Samuelson, peter@samba-tng.org)
78 * Patch to make make sampling and scrolling intervals
79 customizable, adds new options -I and -s.
80 01/15/2002 (Matyas Koszik, koszik@debijan.lonyay.edu.hu)
81 * Patch that fixes segfaults on long interface names.
82 08/31/2001 (Davi Leal, davileal@terra.es)
83 * Patch that cuts long interface names, so they look
84 good in wmifs. For example, "dummy0" gets displayed
85 as "dumm0", "vmnet10" as "vmn10", etc.
86 06/16/2001 (Jorge GarcĂ­a, Jorge.Garcia@uv.es)
87 * Added the LockMode, so wmifs doesn't swap to another
88 interface if the one requested with "-i" isn't up.
89 05/06/2001 (Jordi Mallach, jordi@sindominio.net)
90 * Integrated many patches, fixing issues with suspended
91 wmifs.
92 07/21/1999 (Stephen Pitts, smpitts@midsouth.rr.com)
93 * Added new constant: BUFFER_SIZE to determine the size
94 of the buffer used in fgets() operations. Right now,
95 its at 512 bytes. Fixed crashing on my system when
96 one line of /proc/net/dev was longer than 128 bytes
97 04/05/1998 (Martijn Pieterse, pieterse@xs4all.nl)
98 * Changed the "middle of the waveform" line color
99 * Moved the RedrawWindow out of the main loop.
100 Lightens the system load
101 02/05/1998 (Martijn Pieterse, pieterse@xs4all.nl)
102 * Torn wmppp and wmifs apart.
103 This is gonna be wmifs
104 * Added parse_rcfile
105 * Added waitpid, to get rid of the zombies, spotteb by Alessandro Usseglio Viretta
106 30/04/1998 (Martijn Pieterse, pieterse@xs4all.nl)
107 * Used the DrawStats routine from wmifs in wmppp
108 * I decided to add a list in this source file
109 with name of ppl who helped me build this code better.
110 * I finally removed the /proc/net/route dependancy
111 All of the connections are taken from /proc/net/dev.
112 /proc/net/route is still used for checking if it is on-line.
113 27/04/1998 (Martijn Pieterse, pieterse@xs4all.nl)
114 * WMIFS: stats scrolled, while red led burning
115 * WMPPP: changed positions of line speed
116 25/04/1998 (Martijn Pieterse, pieterse@xs4all.nl)
117 * Changed the checknetdevs routine, a lot!
118 23/04/1998 (Martijn Pieterse, pieterse@xs4all.nl)
119 * Added line speed detection. via seperate exec. (this has to be suid root!)
120 Speed has to be no more than 99999
121 * Added speed and forcespeed in ~/.wmppprc and /etc/wmppprc
122 * wmifs: added on-line detection scheme, update the bitmap coordinates
123 * wmppp: the x-button now allways disconnects.
124 22/04/1998 (Martijn Pieterse, pieterse@xs4all.nl)
125 * Added /etc/wmppprc support, including "forced" mode.
126 * Added /etc/wmifsrc support, including "forced" mode.
127 21/04/1998 (Martijn Pieterse, pieterse@xs4all.nl)
128 * Moved the stats one pixel down.
129 * Added status led in wmifs.
130 * Changed RX/TX leds of wmifs to resemble wmppp
131 * Added the "dot" between eth.0 ppp.0 etc.
132 * Changed to wmifs stats to match wmppp stats (only pppX changed)
133 * Made sure that when specified -t 1, it stayed that way, even
134 when longer than 100 minutes online
135 * With -t 1, jump from 59:59 to 01:00 instead of 99:59 to 01:40
136 16/04/1998 (Martijn Pieterse, pieterse@xs4all.nl)
137 * Added "all" devices in wmifs
138 * Added "lo" support only if aked via -i
139 * Added on-line time detection (using /var/run/ppp0.pid)
140 * Added time-out for the orange led. (one minute)
141 15/04/1998 (Martijn Pieterse, pieterse@xs4all.nl)
142 * Another wmppp-master.xpm.
143 Line speed detection being the main problem here.. :(
144 * Moved START_COMMAND / STOP_COMMAND to ~/.wmppprc
145 Return 0, everything went ok.
146 Return 10, the command did not work.
147 Please note, these functions are ran in the background.
148 * Removed the ability to configure
149 * When "v" is clicked, an orange led will appear.
150 if the connect script fails (return value == 10)
151 it will become dark again. Else the on-line detection will
152 pick it up, and "green" it.
153 14/04/1998 (Martijn Pieterse, pieterse@xs4all.nl)
154 * Added "-timer"
155 * Added "-display" support
156 * Changed pixmap to a no-name pixmap.
157 + Changed LED positions
158 + Changed Timer position
159 + Changed Stats Size
160 05/04/1998 (Martijn Pieterse, pieterse@xs4all.nl)
161 * Added ~/.wmifsrc support.
162 * Put some code in DrawStats
163 * Check devices when pressing "device change"
164 03/04/1998 (Martijn Pieterse, pieterse@xs4all.nl)
165 * Added code for wmifs
166 28/03/1998 (Martijn Pieterse, pieterse@xs4all.nl)
167 * forgot what i did.. :)
168 27/03/1998 (Martijn Pieterse, pieterse@xs4all.nl)
169 * Added on-line detection
170 Scan through /proc/net/route and check everye line
171 for "ppp".
172 * A bit of code clean-up.
175 #include <stdlib.h>
176 #include <stdio.h>
177 #include <time.h>
178 #include <string.h>
179 #include <fcntl.h>
180 #include <unistd.h>
181 #include <ctype.h>
183 #include <sys/wait.h>
184 #include <sys/stat.h>
185 #include <sys/param.h>
186 #include <sys/types.h>
187 #include <sys/ioctl.h>
188 #include <sys/socket.h>
189 #include <sys/time.h>
191 #include <X11/Xlib.h>
192 #include <X11/xpm.h>
193 #include <X11/extensions/shape.h>
195 #include <net/ppp_defs.h>
196 #include <net/if_ppp.h>
198 #include "../wmgeneral/wmgeneral.h"
199 #include "../wmgeneral/misc.h"
201 #include "wmifs-master.xpm"
202 #include "wmifs-mask.xbm"
204 /* How often to check for new network interface, in ms */
205 #define CHECK_INTERFACE_INTERVAL 5000
207 /* How often to query the interfaces, in ms */
208 #define DEFAULT_SAMPLE_INTERVAL 50
210 /***********/
211 /* Defines */
212 /***********/
214 /* Fill in the hardcoded actions */
215 #define LEFT_ACTION (NULL)
216 #define MIDDLE_ACTION (NULL)
217 #define RIGHT_ACTION (NULL)
219 /* Defines voor alle coordinate */
221 #define LED_NET_RX (4)
222 #define LED_NET_TX (5)
223 #define LED_NET_POWER (6)
225 #define WMIFS_VERSION "1.3b1"
227 /* the size of the buffer read from /proc/net/ */
228 #define BUFFER_SIZE 512
229 /**********************/
230 /* External Variables */
231 /**********************/
233 extern char **environ;
235 /********************/
236 /* Global Variables */
237 /********************/
239 char *ProgName;
240 char *active_interface = NULL;
241 int TimerDivisor=60;
242 int WaveForm=0;
243 int LockMode=0;
244 int SampleInt = DEFAULT_SAMPLE_INTERVAL;
245 int ScrollSpeed = CHECK_INTERFACE_INTERVAL;
247 /*****************/
248 /* PPP variables */
249 /*****************/
251 #define PPP_UNIT 0
252 int ppp_h = -1;
254 #define PPP_STATS_HIS 54
256 /***********************/
257 /* Function Prototypes */
258 /***********************/
260 void usage(void);
261 void printversion(void);
262 void DrawTime(int, int);
263 void DrawStats(int *, int, int, int, int);
265 void SetOnLED(int);
266 void SetErrLED(int);
267 void SetWaitLED(int);
268 void SetOffLED(int);
270 void ButtonUp(int);
271 void ButtonDown(int);
273 void wmifs_routine(int, char **);
275 void get_ppp_stats(struct ppp_stats *cur);
278 /********/
279 /* Main */
280 /********/
282 int main(int argc, char *argv[]) {
284 int i;
287 /* Parse Command Line */
289 ProgName = argv[0];
290 if (strlen(ProgName) >= 5)
291 ProgName += (strlen(ProgName) - 5);
293 for (i=1; i<argc; i++) {
294 char *arg = argv[i];
296 if (*arg=='-') {
297 switch (arg[1]) {
298 case 'd' :
299 if (strcmp(arg+1, "display")) {
300 usage();
301 exit(1);
303 break;
304 case 'i' :
305 active_interface = argv[i+1];
306 i++;
307 break;
308 case 'I' :
309 SampleInt = atof(argv[i+1]) * 1000;
310 i++;
311 break;
312 case 'l' :
313 LockMode = 1;
314 break;
315 case 's' :
316 ScrollSpeed = atof(argv[i+1]) * 1000;
317 i++;
318 break;
319 case 'v' :
320 printversion();
321 exit(0);
322 break;
323 case 'w' :
324 WaveForm = 1;
325 break;
326 default:
327 usage();
328 exit(0);
329 break;
334 wmifs_routine(argc, argv);
335 return 0;
338 /*******************************************************************************\
339 |* wmifs_routine *|
340 \*******************************************************************************/
342 #define MAX_STAT_DEVICES 16
344 typedef struct {
346 char name[8];
347 int his[55][2];
348 long istatlast;
349 long ostatlast;
351 } stat_dev;
353 stat_dev stat_devices[MAX_STAT_DEVICES];
355 char *left_action = NULL;
356 char *right_action = NULL;
357 char *middle_action = NULL;
359 int checknetdevs(void);
360 int get_statistics(char *, long *, long *, long *, long *);
361 int stillonline(char *);
362 void DrawActiveIFS(char *);
364 void wmifs_routine(int argc, char **argv) {
366 rckeys wmifs_keys[] = {
367 { "left", &left_action },
368 { "middle", &middle_action },
369 { "right", &right_action },
370 { NULL, NULL }
374 int i,j;
375 XEvent Event;
376 int but_stat = -1;
378 int stat_online;
379 int stat_current;
381 unsigned int curtime;
382 unsigned int nexttime;
383 struct timeval tv, tv2;
385 long ipacket, opacket, istat, ostat;
387 char temp[BUFFER_SIZE];
388 char *p;
390 for (i=0; i<MAX_STAT_DEVICES; i++) {
391 stat_devices[i].name[0] = 0;
392 for (j=0; j<48; j++) {
393 stat_devices[i].his[j][0] = 0;
394 stat_devices[i].his[j][1] = 0;
398 stat_online = checknetdevs();
400 stat_current = 0;
401 if (active_interface) {
402 for (i=0; i<stat_online; i++) {
403 if (!strcmp(stat_devices[i].name, active_interface))
404 stat_current = i;
408 if (LEFT_ACTION) left_action = strdup(LEFT_ACTION);
409 if (MIDDLE_ACTION) middle_action = strdup(MIDDLE_ACTION);
410 if (RIGHT_ACTION) right_action = strdup(RIGHT_ACTION);
412 /* Scan throught the .rc files */
413 strcpy(temp, "/etc/wmifsrc");
414 parse_rcfile(temp, wmifs_keys);
416 p = getenv("HOME");
417 strcpy(temp, p);
418 strcat(temp, "/.wmifsrc");
419 parse_rcfile(temp, wmifs_keys);
421 strcpy(temp, "/etc/wmifsrc.fixed");
422 parse_rcfile(temp, wmifs_keys);
424 openXwindow(argc, argv, wmifs_master_xpm, wmifs_mask_bits, wmifs_mask_width, wmifs_mask_height);
426 /* > Button */
427 AddMouseRegion(0, 5, 5, 35, 15);
428 AddMouseRegion(1, 5, 20, 58, 58);
430 gettimeofday(&tv2, NULL);
431 nexttime = ScrollSpeed;
433 for (i=0; i<stat_online; i++) {
434 get_statistics(stat_devices[i].name, &ipacket, &opacket, &istat, &ostat);
435 stat_devices[i].istatlast = istat;
436 stat_devices[i].ostatlast = ostat;
439 DrawActiveIFS(stat_devices[stat_current].name);
441 while (1) {
442 gettimeofday(&tv, NULL);
443 curtime = (tv.tv_sec - tv2.tv_sec) * 1000
444 + (tv.tv_usec - tv2.tv_usec) / 1000;
446 waitpid(0, NULL, WNOHANG);
448 for (i=0; i<stat_online; i++) {
449 get_statistics(stat_devices[i].name, &ipacket, &opacket, &istat, &ostat);
450 stat_devices[i].his[53][0] += istat - stat_devices[i].istatlast;
451 stat_devices[i].his[53][1] += ostat - stat_devices[i].ostatlast;
454 if (i == stat_current) {
455 if (!stillonline(stat_devices[i].name)) {
456 SetErrLED(LED_NET_POWER);
457 } else {
458 SetOnLED(LED_NET_POWER);
461 if (stat_devices[i].istatlast == istat)
462 SetOffLED(LED_NET_RX);
463 else
464 SetOnLED(LED_NET_RX);
466 if (stat_devices[i].ostatlast == ostat)
467 SetOffLED(LED_NET_TX);
468 else
469 SetOnLED(LED_NET_TX);
472 stat_devices[i].istatlast = istat;
473 stat_devices[i].ostatlast = ostat;
474 RedrawWindow();
477 if (curtime >= nexttime) {
478 nexttime=curtime+ScrollSpeed;
480 for (i=0; i<stat_online; i++) {
481 if (i == stat_current) {
483 DrawStats(&stat_devices[i].his[0][0], 54, 40, 5, 58);
485 if (stillonline(stat_devices[i].name)) {
486 for (j=1; j<54; j++) {
487 stat_devices[i].his[j-1][0] = stat_devices[i].his[j][0];
488 stat_devices[i].his[j-1][1] = stat_devices[i].his[j][1];
490 stat_devices[i].his[53][0] = 0;
491 stat_devices[i].his[53][1] = 0;
494 RedrawWindow();
497 while (XPending(display)) {
498 XNextEvent(display, &Event);
499 switch (Event.type) {
500 case Expose:
501 RedrawWindow();
502 break;
503 case DestroyNotify:
504 XCloseDisplay(display);
505 exit(0);
506 break;
507 case ButtonPress:
508 i = CheckMouseRegion(Event.xbutton.x, Event.xbutton.y);
510 but_stat = i;
511 break;
512 case ButtonRelease:
513 i = CheckMouseRegion(Event.xbutton.x, Event.xbutton.y);
515 if (but_stat == i && but_stat >= 0) {
516 switch (but_stat) {
517 case 0 :
518 /* re-read the table */
519 strcpy(temp, stat_devices[stat_current].name);
520 stat_online = checknetdevs();
521 stat_current = 0;
522 for (i=0; i<stat_online; i++) {
523 if (!strcmp(temp, stat_devices[i].name)) {
524 stat_current = i;
528 stat_current++;
529 if (stat_current == stat_online) stat_current = 0;
531 DrawActiveIFS(stat_devices[stat_current].name);
533 DrawStats(&stat_devices[stat_current].his[0][0], 54, 40, 5, 58);
534 break;
535 case 1:
536 switch (Event.xbutton.button) {
537 case 1:
538 if (left_action)
539 execCommand(left_action);
540 break;
541 case 2:
542 if (middle_action)
543 execCommand(middle_action);
544 break;
545 case 3:
546 if (right_action)
547 execCommand(right_action);
548 break;
550 break;
554 but_stat = -1;
555 RedrawWindow();
556 break;
560 usleep(SampleInt * 1000);
564 /*******************************************************************************\
565 |* void DrawActiveIFS(char *) *|
566 \*******************************************************************************/
568 void DrawActiveIFS(char *real_name) {
570 /* Cijfers op: 0,65
571 Letters op: 0,75
572 Alles 9 hoog, 6 breedt
574 Destinatie: 5,5
577 int i;
578 int c;
579 int k;
580 int len;
581 char name[256];
584 copyXPMArea(5, 84, 30, 10, 5, 5);
587 strcpy(name,real_name);
588 len = strlen(name);
589 if (len > 5)
591 for (i=len-5; i<len && !(name[i]>='0' && name[i]<='9'); i++) ;
592 for (; i<=len; i++) /* '=' to get the '\0' character moved too \*/
593 name[i-(len-5)] = name[i];
596 k = 5;
597 for (i=0; name[i]; i++) {
598 if (i == strlen(name)-1 && strlen(name) <= 4 && name[strlen(name)-1] >= '0' && name[strlen(name)-1] <= '9') {
599 copyXPMArea(61, 64, 4, 9, k, 5);
600 k+=4;
602 c = toupper(name[i]);
603 if (c >= 'A' && c <= 'Z') {
604 c -= 'A';
605 copyXPMArea(c * 6, 74, 6, 9, k, 5);
606 k += 6;
607 } else {
608 c -= '0';
609 copyXPMArea(c * 6, 64, 6, 9, k, 5);
610 k += 6;
616 /*******************************************************************************\
617 |* get_statistics *|
618 \*******************************************************************************/
620 int get_statistics(char *devname, long *ip, long *op, long *is, long *os) {
622 FILE *fp;
623 char temp[BUFFER_SIZE];
624 char *p;
625 char *tokens = " |:\n";
626 int input, output;
627 int i;
628 int found;
629 struct ppp_stats ppp_cur, ppp_old;
630 static int ppp_opened = 0;
633 if (!strncmp(devname, "ppp", 3)) {
634 if (!ppp_opened) {
635 /* Open the ppp device. */
636 memset(&ppp_cur, 0, sizeof(ppp_cur));
637 if ((ppp_h = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
638 return -1;
639 get_ppp_stats(&ppp_cur);
640 ppp_old = ppp_cur;
641 ppp_opened = 1;
644 get_ppp_stats(&ppp_cur);
646 *op = ppp_cur.p.ppp_opackets;
647 *ip = ppp_cur.p.ppp_ipackets;
649 *is = ppp_cur.p.ppp_ibytes;
650 *os = ppp_cur.p.ppp_obytes;
652 return 0;
655 /* Read from /proc/net/dev the stats! */
656 fp = fopen("/proc/net/dev", "r");
657 fgets(temp, BUFFER_SIZE, fp);
658 fgets(temp, BUFFER_SIZE, fp);
660 input = -1;
661 output = -1;
662 i = 0;
663 found = -1;
665 p = strtok(temp, tokens);
666 do {
667 if (!(strcmp(p, "packets"))) {
668 if (input == -1) input = i;
669 else output = i;
671 i++;
672 p = strtok(NULL, tokens);
673 } while (input == -1 || output == -1);
675 while (fgets(temp, BUFFER_SIZE, fp)) {
676 if (strstr(temp, devname)) {
677 found = 0;
678 p = strtok(temp, tokens);
679 i = 0;
680 do {
681 if (i == input) {
682 *ip = *is = atoi(p);
683 input = -1;
685 if (i == output) {
686 *op = *os = atoi(p);
687 output = -1;
689 i++;
690 p = strtok(NULL, tokens);
691 } while (input != -1 || output != -1);
694 fclose(fp);
696 return found;
699 /*******************************************************************************\
700 |* stillonline *|
701 \*******************************************************************************/
703 int stillonline(char *ifs) {
705 FILE *fp;
706 char temp[BUFFER_SIZE];
707 int i;
709 i = 0;
710 fp = fopen("/proc/net/route", "r");
711 if (fp) {
712 while (fgets(temp, BUFFER_SIZE, fp)) {
713 if (strstr(temp, ifs)) {
714 i = 1; /* Line is alive */
715 break;
718 fclose(fp);
720 return i;
723 /*******************************************************************************\
724 |* checknetdevs *|
725 \*******************************************************************************/
727 int checknetdevs(void) {
729 FILE *fd;
730 char temp[BUFFER_SIZE];
731 char *p;
732 int i=0,j;
733 int k;
734 int devsfound=0;
735 char *tokens = " :\t\n";
736 char foundbuffer[MAX_STAT_DEVICES][8];
738 for (i=0; i<MAX_STAT_DEVICES; i++) {
739 foundbuffer[i][0] = 0;
742 /* foundbuffer vullen met info uit /proc/net/dev */
744 fd = fopen("/proc/net/dev", "r");
745 if (fd) {
746 /* Skip the first 2 lines */
747 fgets(temp, BUFFER_SIZE, fd);
748 fgets(temp, BUFFER_SIZE, fd);
749 while (fgets(temp, BUFFER_SIZE, fd)) {
750 p = strtok(temp, tokens);
751 if(p == NULL) {
752 printf("Barfed on: %s", temp);
753 break;
755 /* Skip dummy code */
757 if (!strncmp(p, "dummy", 5))
758 continue;
760 /* If p == "lo", and active_interface (as given on the cmd line) != "lo",
761 skip it! */
763 if (strcmp(p, "lo") || (active_interface && !strcmp(active_interface, "lo"))) {
764 strcpy(foundbuffer[devsfound], p);
765 devsfound++;
767 if (devsfound >= MAX_STAT_DEVICES)
768 break;
770 fclose(fd);
773 /* Nu foundbuffer naar stat_devices[].name kopieeren */
775 for (i=0; i<MAX_STAT_DEVICES; i++) {
776 /* Loop stat_devices na, als die naam niet voorkomt in foundbuffer, kill! */
778 if (stat_devices[i].name[0]) {
779 k = 0;
780 for (j=0; j<MAX_STAT_DEVICES; j++) {
781 if (!strcmp(stat_devices[i].name, foundbuffer[j])) {
782 k = 1;
783 foundbuffer[j][0] = 0;
786 if (!k) stat_devices[i].name[0] = 0;
790 for (i=0, j=0; j<MAX_STAT_DEVICES; i++, j++) {
792 while (!stat_devices[j].name[0] && j < MAX_STAT_DEVICES)
793 j++;
795 if (j < MAX_STAT_DEVICES && i != j) {
796 stat_devices[i] = stat_devices[j];
799 i--;
801 for (j=0; j<MAX_STAT_DEVICES; j++) {
802 if (foundbuffer[j][0]) {
804 strcpy(stat_devices[i].name, foundbuffer[j]);
806 for (k=0; k<48; k++) {
807 stat_devices[i].his[k][0] = 0;
808 stat_devices[i].his[k][1] = 0;
811 i++;
814 if (LockMode && active_interface != NULL) {
815 k = 0;
816 for (j=0; j<i; j++)
817 if (!strcmp(stat_devices[j].name, active_interface)) {
818 k = 1;
819 break;
821 if (!k) {
822 strcpy(stat_devices[i].name, active_interface);
823 for (k=0; k<48; k++) {
824 stat_devices[i].his[k][0] = 0;
825 stat_devices[i].his[k][1] = 0;
827 devsfound++;
831 return devsfound;
834 /*******************************************************************************\
835 |* DrawStats *|
836 \*******************************************************************************/
838 void DrawStats(int *his, int num, int size, int x_left, int y_bottom) {
840 int pixels_per_byte;
841 int j,k;
842 int *p;
843 int p0,p1,p2,p3;
845 pixels_per_byte = 1*size;
846 p = his;
847 for (j=0; j<num; j++) {
848 if (p[0] + p[1] > pixels_per_byte)
849 pixels_per_byte = p[0] + p[1];
850 p += 2;
853 pixels_per_byte /= size;
854 p = his;
856 for (k=0; k<num; k++) {
857 p0 = p[0];
858 p1 = p[1];
861 if (WaveForm) {
862 p2 = 0;
863 p3 = 1;
864 for (j=0; j<size; j++) {
865 if (j < p0 / pixels_per_byte)
866 copyXPMArea(100+2, 68, 1, 1, k+x_left, y_bottom-size/2+p2/2);
867 else if (j < (p0 + p1) / pixels_per_byte)
868 copyXPMArea(100+1, 68, 1, 1, k+x_left, y_bottom-size/2+p2/2);
869 else
870 copyXPMArea(100+0, 68, 1, 1, k+x_left, y_bottom-size/2+p2/2);
872 p2 = (p2 + p3);
873 p3 *= -1;
874 p2 *= -1;
876 copyXPMArea(100+3, 68, 1, 1, k+x_left, y_bottom-size/2);
877 } else {
878 for (j=0; j<size; j++) {
879 if (j < p0 / pixels_per_byte)
880 copyXPMArea(100+2, 68, 1, 1, k+x_left, y_bottom-j);
881 else if (j < (p0 + p1) / pixels_per_byte)
882 copyXPMArea(100+1, 68, 1, 1, k+x_left, y_bottom-j);
883 else
884 copyXPMArea(100+0, 68, 1, 1, k+x_left, y_bottom-j);
887 p += 2;
891 /*******************************************************************************\
892 |* usage *|
893 \*******************************************************************************/
895 void usage(void) {
897 fprintf(stderr, "\nwmifs - programming: tijno, (de)bugging & design: warpstah, webhosting: bobby \n\n");
898 fprintf(stderr, "usage:\n");
899 fprintf(stderr, "\t-d <display name>\n");
900 fprintf(stderr, "\t-h\tthis help screen\n");
901 fprintf(stderr, "\t-i <interface name>\tdefault (as it appears in /proc/net/route)\n");
902 fprintf(stderr, "\t-I <interval>\tsampling interval, in seconds (default: 0.05)\n");
903 fprintf(stderr, "\t-l\tstarts in lock mode\n");
904 fprintf(stderr, "\t-s <interval>\tscrolling interval, in seconds (default: 5)\n");
905 fprintf(stderr, "\t-v\tprint the version number\n");
906 fprintf(stderr, "\t-w\twaveform load\n");
907 fprintf(stderr, "\n");
910 /*******************************************************************************\
911 |* printversion *|
912 \*******************************************************************************/
914 void printversion(void) {
916 fprintf(stderr, "%s\n", WMIFS_VERSION);
919 /*******************************************************************************\
920 |* get_ppp_stats *|
921 \*******************************************************************************/
923 void get_ppp_stats(struct ppp_stats *cur) {
925 struct ifpppstatsreq req;
927 memset(&req, 0, sizeof(req));
929 req.stats_ptr = (caddr_t) &req.stats;
931 sprintf(req.ifr__name, "ppp%d", PPP_UNIT);
933 if (ioctl(ppp_h, SIOCGPPPSTATS, &req) < 0) {
934 /* fprintf(stderr, "heyho!\n"); */
936 *cur = req.stats;
939 #define LED_SZE_X (4)
940 #define LED_SZE_Y (4)
942 #define LED_ON_NET_X (87)
943 #define LED_ON_NET_Y (66)
944 #define LED_OFF_NET_X (93)
945 #define LED_OFF_NET_Y (66)
946 #define LED_ERR_NET_X (81)
947 #define LED_ERR_NET_Y (66)
948 #define LED_ON_SW_NET_X (49)
949 #define LED_ON_SW_NET_Y (85)
950 #define LED_OFF_SW_NET_X (44)
951 #define LED_OFF_SW_NET_Y (85)
953 #define LED_PWR_X (53)
954 #define LED_PWR_Y (7)
955 #define LED_SND_X (47)
956 #define LED_SND_Y (7)
957 #define LED_RCV_X (41)
958 #define LED_RCV_Y (7)
960 #define LED_SW_X (38)
961 #define LED_SW_Y (14)
963 /*******************************************************************************\
964 |* SetOnLED *|
965 \*******************************************************************************/
966 void SetOnLED(int led) {
968 switch (led) {
970 case LED_NET_RX:
971 copyXPMArea(LED_ON_NET_X, LED_ON_NET_Y, LED_SZE_X, LED_SZE_Y, LED_RCV_X, LED_RCV_Y);
972 break;
973 case LED_NET_TX:
974 copyXPMArea(LED_ON_NET_X, LED_ON_NET_Y, LED_SZE_X, LED_SZE_Y, LED_SND_X, LED_SND_Y);
975 break;
976 case LED_NET_POWER:
977 copyXPMArea(LED_ON_NET_X, LED_ON_NET_Y, LED_SZE_X, LED_SZE_Y, LED_PWR_X, LED_PWR_Y);
978 break;
982 /*******************************************************************************\
983 |* SetOffLED *|
984 \*******************************************************************************/
985 void SetOffLED(int led) {
987 switch (led) {
989 case LED_NET_RX:
990 copyXPMArea(LED_OFF_NET_X, LED_OFF_NET_Y, LED_SZE_X, LED_SZE_Y, LED_RCV_X, LED_RCV_Y);
991 break;
992 case LED_NET_TX:
993 copyXPMArea(LED_OFF_NET_X, LED_OFF_NET_Y, LED_SZE_X, LED_SZE_Y, LED_SND_X, LED_SND_Y);
994 break;
995 case LED_NET_POWER:
996 copyXPMArea(LED_OFF_NET_X, LED_OFF_NET_Y, LED_SZE_X, LED_SZE_Y, LED_PWR_X, LED_PWR_Y);
997 break;
1001 /*******************************************************************************\
1002 |* SetErrLED *|
1003 \*******************************************************************************/
1004 void SetErrLED(int led) {
1006 switch (led) {
1007 case LED_NET_POWER:
1008 copyXPMArea(LED_ERR_NET_X, LED_ERR_NET_Y, LED_SZE_X, LED_SZE_Y, LED_PWR_X, LED_PWR_Y);
1009 break;