wmtime: Bump to version 1.3.
[dockapps.git] / wmifs / wmifs / wmifs.c
blob9495135712049dd7ff6481dbb2e9640848c7503e
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 02/29/2004 (Tom Marshall, tommy@home.tig-grr.com)
78 * Patch to add a special interface name "auto" for the -i
79 option. "wmifs -i auto" will automatically select the
80 first up interface.
81 01/08/2004 (Peter Samuelson, peter@samba-tng.org)
82 * Patch to make make sampling and scrolling intervals
83 customizable, adds new options -I and -s.
84 01/15/2002 (Matyas Koszik, koszik@debijan.lonyay.edu.hu)
85 * Patch that fixes segfaults on long interface names.
86 08/31/2001 (Davi Leal, davileal@terra.es)
87 * Patch that cuts long interface names, so they look
88 good in wmifs. For example, "dummy0" gets displayed
89 as "dumm0", "vmnet10" as "vmn10", etc.
90 06/16/2001 (Jorge GarcĂ­a, Jorge.Garcia@uv.es)
91 * Added the LockMode, so wmifs doesn't swap to another
92 interface if the one requested with "-i" isn't up.
93 05/06/2001 (Jordi Mallach, jordi@sindominio.net)
94 * Integrated many patches, fixing issues with suspended
95 wmifs.
96 07/21/1999 (Stephen Pitts, smpitts@midsouth.rr.com)
97 * Added new constant: BUFFER_SIZE to determine the size
98 of the buffer used in fgets() operations. Right now,
99 its at 512 bytes. Fixed crashing on my system when
100 one line of /proc/net/dev was longer than 128 bytes
101 04/05/1998 (Martijn Pieterse, pieterse@xs4all.nl)
102 * Changed the "middle of the waveform" line color
103 * Moved the RedrawWindow out of the main loop.
104 Lightens the system load
105 02/05/1998 (Martijn Pieterse, pieterse@xs4all.nl)
106 * Torn wmppp and wmifs apart.
107 This is gonna be wmifs
108 * Added parse_rcfile
109 * Added waitpid, to get rid of the zombies, spotteb by Alessandro Usseglio Viretta
110 30/04/1998 (Martijn Pieterse, pieterse@xs4all.nl)
111 * Used the DrawStats routine from wmifs in wmppp
112 * I decided to add a list in this source file
113 with name of ppl who helped me build this code better.
114 * I finally removed the /proc/net/route dependancy
115 All of the connections are taken from /proc/net/dev.
116 /proc/net/route is still used for checking if it is on-line.
117 27/04/1998 (Martijn Pieterse, pieterse@xs4all.nl)
118 * WMIFS: stats scrolled, while red led burning
119 * WMPPP: changed positions of line speed
120 25/04/1998 (Martijn Pieterse, pieterse@xs4all.nl)
121 * Changed the checknetdevs routine, a lot!
122 23/04/1998 (Martijn Pieterse, pieterse@xs4all.nl)
123 * Added line speed detection. via seperate exec. (this has to be suid root!)
124 Speed has to be no more than 99999
125 * Added speed and forcespeed in ~/.wmppprc and /etc/wmppprc
126 * wmifs: added on-line detection scheme, update the bitmap coordinates
127 * wmppp: the x-button now allways disconnects.
128 22/04/1998 (Martijn Pieterse, pieterse@xs4all.nl)
129 * Added /etc/wmppprc support, including "forced" mode.
130 * Added /etc/wmifsrc support, including "forced" mode.
131 21/04/1998 (Martijn Pieterse, pieterse@xs4all.nl)
132 * Moved the stats one pixel down.
133 * Added status led in wmifs.
134 * Changed RX/TX leds of wmifs to resemble wmppp
135 * Added the "dot" between eth.0 ppp.0 etc.
136 * Changed to wmifs stats to match wmppp stats (only pppX changed)
137 * Made sure that when specified -t 1, it stayed that way, even
138 when longer than 100 minutes online
139 * With -t 1, jump from 59:59 to 01:00 instead of 99:59 to 01:40
140 16/04/1998 (Martijn Pieterse, pieterse@xs4all.nl)
141 * Added "all" devices in wmifs
142 * Added "lo" support only if aked via -i
143 * Added on-line time detection (using /var/run/ppp0.pid)
144 * Added time-out for the orange led. (one minute)
145 15/04/1998 (Martijn Pieterse, pieterse@xs4all.nl)
146 * Another wmppp-master.xpm.
147 Line speed detection being the main problem here.. :(
148 * Moved START_COMMAND / STOP_COMMAND to ~/.wmppprc
149 Return 0, everything went ok.
150 Return 10, the command did not work.
151 Please note, these functions are ran in the background.
152 * Removed the ability to configure
153 * When "v" is clicked, an orange led will appear.
154 if the connect script fails (return value == 10)
155 it will become dark again. Else the on-line detection will
156 pick it up, and "green" it.
157 14/04/1998 (Martijn Pieterse, pieterse@xs4all.nl)
158 * Added "-timer"
159 * Added "-display" support
160 * Changed pixmap to a no-name pixmap.
161 + Changed LED positions
162 + Changed Timer position
163 + Changed Stats Size
164 05/04/1998 (Martijn Pieterse, pieterse@xs4all.nl)
165 * Added ~/.wmifsrc support.
166 * Put some code in DrawStats
167 * Check devices when pressing "device change"
168 03/04/1998 (Martijn Pieterse, pieterse@xs4all.nl)
169 * Added code for wmifs
170 28/03/1998 (Martijn Pieterse, pieterse@xs4all.nl)
171 * forgot what i did.. :)
172 27/03/1998 (Martijn Pieterse, pieterse@xs4all.nl)
173 * Added on-line detection
174 Scan through /proc/net/route and check everye line
175 for "ppp".
176 * A bit of code clean-up.
179 #include <stdlib.h>
180 #include <stdio.h>
181 #include <time.h>
182 #include <string.h>
183 #include <fcntl.h>
184 #include <unistd.h>
185 #include <ctype.h>
187 #include <sys/wait.h>
188 #include <sys/stat.h>
189 #include <sys/param.h>
190 #include <sys/types.h>
191 #include <sys/ioctl.h>
192 #include <sys/socket.h>
193 #include <sys/time.h>
195 #include <X11/Xlib.h>
196 #include <X11/xpm.h>
197 #include <X11/extensions/shape.h>
199 #include <net/ppp_defs.h>
200 #include <net/if_ppp.h>
202 #include "../wmgeneral/wmgeneral.h"
203 #include "../wmgeneral/misc.h"
205 #include "wmifs-master.xpm"
206 #include "wmifs-mask.xbm"
208 /* How often to check for new network interface, in ms */
209 #define CHECK_INTERFACE_INTERVAL 5000
211 /* How often to query the interfaces, in ms */
212 #define DEFAULT_SAMPLE_INTERVAL 50
214 /***********/
215 /* Defines */
216 /***********/
218 #ifndef ifr__name
219 #define ifr__name ifr_name
220 #endif
222 #ifndef stats_ptr
223 #define stats_ptr stats.p.FIXME
224 #endif
226 /* Fill in and uncomment the hardcoded actions */
227 /* #define LEFT_ACTION (NULL) */
228 /* #define MIDDLE_ACTION (NULL) */
229 /* #define RIGHT_ACTION (NULL) */
231 /* Defines voor alle coordinate */
233 #define LED_NET_RX (4)
234 #define LED_NET_TX (5)
235 #define LED_NET_POWER (6)
237 #define WMIFS_VERSION "1.4"
239 /* the size of the buffer read from /proc/net/ */
240 #define BUFFER_SIZE 512
241 /**********************/
242 /* External Variables */
243 /**********************/
245 extern char **environ;
247 /********************/
248 /* Global Variables */
249 /********************/
251 char *active_interface = NULL;
252 int TimerDivisor = 60;
253 int WaveForm = 0;
254 int LockMode = 0;
255 int SampleInt = DEFAULT_SAMPLE_INTERVAL;
256 int ScrollSpeed = CHECK_INTERFACE_INTERVAL;
258 /*****************/
259 /* PPP variables */
260 /*****************/
262 #define PPP_UNIT 0
263 int ppp_h = -1;
265 #define PPP_STATS_HIS 54
267 /***********************/
268 /* Function Prototypes */
269 /***********************/
271 void usage(void);
272 void printversion(void);
273 void DrawTime(int, int);
274 void DrawStats(int *, int, int, int, int);
276 void SetOnLED(int);
277 void SetErrLED(int);
278 void SetWaitLED(int);
279 void SetOffLED(int);
281 void ButtonUp(int);
282 void ButtonDown(int);
284 void wmifs_routine(int, char **);
286 void get_ppp_stats(struct ppp_stats *cur);
289 /********/
290 /* Main */
291 /********/
293 int main(int argc, char *argv[])
296 int i;
299 /* Parse Command Line */
301 for (i = 1; i < argc; i++) {
302 char *arg = argv[i];
304 if (*arg == '-') {
305 switch (arg[1]) {
306 case 'd':
307 if (strcmp(arg+1, "display")) {
308 usage();
309 exit(1);
311 break;
312 case 'i':
313 active_interface = argv[i+1];
314 i++;
315 break;
316 case 'I':
317 SampleInt = atof(argv[i+1]) * 1000;
318 i++;
319 break;
320 case 'l':
321 LockMode = 1;
322 break;
323 case 's':
324 ScrollSpeed = atof(argv[i+1]) * 1000;
325 i++;
326 break;
327 case 'v':
328 printversion();
329 exit(0);
330 break;
331 case 'w':
332 WaveForm = 1;
333 break;
334 default:
335 usage();
336 exit(0);
337 break;
342 wmifs_routine(argc, argv);
343 return 0;
346 /*******************************************************************************\
347 |* wmifs_routine *|
348 \*******************************************************************************/
350 #define MAX_STAT_DEVICES 16
352 typedef struct {
354 char name[8];
355 int his[55][2];
356 long istatlast;
357 long ostatlast;
359 } stat_dev;
361 stat_dev stat_devices[MAX_STAT_DEVICES];
363 char *left_action = NULL;
364 char *right_action = NULL;
365 char *middle_action = NULL;
367 int checknetdevs(void);
368 int get_statistics(char *, long *, long *, long *, long *);
369 int stillonline(char *);
370 void DrawActiveIFS(char *);
372 void wmifs_routine(int argc, char **argv)
375 rckeys wmifs_keys[] = {
376 { "left", &left_action },
377 { "middle", &middle_action },
378 { "right", &right_action },
379 { NULL, NULL }
383 int i, j;
384 XEvent Event;
385 int but_stat = -1;
387 int stat_online;
388 int stat_current;
390 unsigned int curtime;
391 unsigned int nexttime;
392 struct timeval tv, tv2;
394 long ipacket, opacket, istat, ostat;
396 char temp[BUFFER_SIZE];
397 char *p;
399 for (i = 0; i < MAX_STAT_DEVICES; i++) {
400 stat_devices[i].name[0] = 0;
401 for (j = 0; j < 48; j++) {
402 stat_devices[i].his[j][0] = 0;
403 stat_devices[i].his[j][1] = 0;
407 stat_online = checknetdevs();
409 stat_current = 0;
410 if (active_interface) {
411 int isauto = !strcmp(active_interface, "auto");
412 for (i = 0; i < stat_online; i++) {
413 if ((isauto && stillonline(stat_devices[i].name)) ||
414 !strcmp(stat_devices[i].name, active_interface)) {
415 stat_current = i;
416 break;
421 #ifdef LEFT_ACTION
422 left_action = strdup(LEFT_ACTION);
423 #endif
424 #ifdef MIDDLE_ACTION
425 middle_action = strdup(MIDDLE_ACTION);
426 #endif
427 #ifdef RIGHT_ACTION
428 right_action = strdup(RIGHT_ACTION);
429 #endif
431 /* Scan throught the .rc files */
432 parse_rcfile("/etc/wmifsrc", wmifs_keys);
434 p = getenv("HOME");
435 if (p == NULL || *p == 0) {
436 fprintf(stderr, "Unknown $HOME directory, please check your environment\n");
437 return;
439 strcpy(temp, p);
440 strcat(temp, "/.wmifsrc");
441 parse_rcfile(temp, wmifs_keys);
443 parse_rcfile("/etc/wmifsrc.fixed", wmifs_keys);
445 openXwindow(argc, argv, wmifs_master_xpm, wmifs_mask_bits, wmifs_mask_width, wmifs_mask_height);
447 /* > Button */
448 AddMouseRegion(0, 5, 5, 35, 15);
449 AddMouseRegion(1, 5, 20, 58, 58);
451 gettimeofday(&tv2, NULL);
452 nexttime = ScrollSpeed;
454 DrawActiveIFS(stat_devices[stat_current].name);
456 while (1) {
457 gettimeofday(&tv, NULL);
458 curtime = (tv.tv_sec - tv2.tv_sec) * 1000
459 + (tv.tv_usec - tv2.tv_usec) / 1000;
461 waitpid(0, NULL, WNOHANG);
463 for (i = 0; i < stat_online; i++) {
464 get_statistics(stat_devices[i].name, &ipacket, &opacket, &istat, &ostat);
465 stat_devices[i].his[53][0] += istat - stat_devices[i].istatlast;
466 stat_devices[i].his[53][1] += ostat - stat_devices[i].ostatlast;
469 if (i == stat_current) {
470 if (!stillonline(stat_devices[i].name))
471 SetErrLED(LED_NET_POWER);
472 else
473 SetOnLED(LED_NET_POWER);
475 if (stat_devices[i].istatlast == istat)
476 SetOffLED(LED_NET_RX);
477 else
478 SetOnLED(LED_NET_RX);
480 if (stat_devices[i].ostatlast == ostat)
481 SetOffLED(LED_NET_TX);
482 else
483 SetOnLED(LED_NET_TX);
486 stat_devices[i].istatlast = istat;
487 stat_devices[i].ostatlast = ostat;
489 RedrawWindow();
491 if (curtime >= nexttime) {
492 nexttime = curtime + ScrollSpeed;
494 DrawStats(&stat_devices[stat_current].his[0][0], 54, 40, 5, 58);
495 for (i = 0; i < stat_online; i++) {
496 if (stillonline(stat_devices[i].name)) {
497 for (j = 1; j < 54; j++) {
498 stat_devices[i].his[j-1][0] = stat_devices[i].his[j][0];
499 stat_devices[i].his[j-1][1] = stat_devices[i].his[j][1];
501 stat_devices[i].his[53][0] = 0;
502 stat_devices[i].his[53][1] = 0;
505 RedrawWindow();
508 while (XPending(display)) {
509 XNextEvent(display, &Event);
510 switch (Event.type) {
511 case Expose:
512 RedrawWindow();
513 break;
514 case DestroyNotify:
515 XCloseDisplay(display);
516 exit(0);
517 break;
518 case ButtonPress:
519 but_stat = CheckMouseRegion(Event.xbutton.x, Event.xbutton.y);
520 break;
521 case ButtonRelease:
522 i = CheckMouseRegion(Event.xbutton.x, Event.xbutton.y);
524 if (but_stat == i && but_stat >= 0) {
525 switch (but_stat) {
526 case 0:
527 /* re-read the table */
528 strcpy(temp, stat_devices[stat_current].name);
529 stat_online = checknetdevs();
530 stat_current = 0;
531 for (i = 0; i < stat_online; i++) {
532 if (!strcmp(temp, stat_devices[i].name))
533 stat_current = i;
536 stat_current++;
537 if (stat_current == stat_online)
538 stat_current = 0;
540 DrawActiveIFS(stat_devices[stat_current].name);
542 DrawStats(&stat_devices[stat_current].his[0][0], 54, 40, 5, 58);
543 break;
544 case 1:
545 switch (Event.xbutton.button) {
546 case 1:
547 if (left_action)
548 execCommand(left_action);
549 break;
550 case 2:
551 if (middle_action)
552 execCommand(middle_action);
553 break;
554 case 3:
555 if (right_action)
556 execCommand(right_action);
557 break;
559 break;
563 but_stat = -1;
564 RedrawWindow();
565 break;
569 usleep(SampleInt * 1000);
573 /*******************************************************************************\
574 |* void DrawActiveIFS(char *) *|
575 \*******************************************************************************/
577 void DrawActiveIFS(char *real_name)
580 /* Cijfers op: 0,65
581 Letters op: 0,75
582 Alles 9 hoog, 6 breedt
584 Destinatie: 5,5
587 int i;
588 int c;
589 int k;
590 int len;
591 char name[256];
594 copyXPMArea(5, 84, 30, 10, 5, 5);
597 strcpy(name, real_name);
598 len = strlen(name);
599 if (len > 5) {
600 for (i = len-5; i < len && !(name[i] >= '0' && name[i] <= '9'); i++)
602 for (; i <= len; i++) /* '=' to get the '\0' character moved too \*/
603 name[i-(len-5)] = name[i];
606 k = 5;
607 for (i = 0; name[i]; i++) {
608 if (i == strlen(name)-1 && strlen(name) <= 4 && name[strlen(name)-1] >= '0' &&
609 name[strlen(name)-1] <= '9') {
610 copyXPMArea(61, 64, 4, 9, k, 5);
611 k += 4;
613 c = toupper(name[i]);
614 if (c >= 'A' && c <= 'Z') {
615 c -= 'A';
616 copyXPMArea(c * 6, 74, 6, 9, k, 5);
617 k += 6;
618 } else {
619 c -= '0';
620 copyXPMArea(c * 6, 64, 6, 9, k, 5);
621 k += 6;
627 /*******************************************************************************\
628 |* get_statistics *|
629 \*******************************************************************************/
631 int get_statistics(char *devname, long *ip, long *op, long *is, long *os)
634 FILE *fp;
635 char temp[BUFFER_SIZE];
636 char *p;
637 char *tokens = " |:\n";
638 int input, output;
639 int i;
640 int found;
641 struct ppp_stats ppp_cur, ppp_old;
642 static int ppp_opened;
645 if (!strncmp(devname, "ppp", 3)) {
646 if (!ppp_opened) {
647 /* Open the ppp device. */
648 memset(&ppp_cur, 0, sizeof(ppp_cur));
649 ppp_h = socket(AF_INET, SOCK_DGRAM, 0);
650 if (ppp_h < 0)
651 return -1;
652 get_ppp_stats(&ppp_cur);
653 ppp_old = ppp_cur;
654 ppp_opened = 1;
657 get_ppp_stats(&ppp_cur);
659 *op = ppp_cur.p.ppp_opackets;
660 *ip = ppp_cur.p.ppp_ipackets;
662 *is = ppp_cur.p.ppp_ibytes;
663 *os = ppp_cur.p.ppp_obytes;
665 return 0;
668 /* Read from /proc/net/dev the stats! */
669 fp = fopen("/proc/net/dev", "r");
670 if (!fgets(temp, BUFFER_SIZE, fp)) {
671 fclose(fp);
672 return -1;
674 if (!fgets(temp, BUFFER_SIZE, fp)) {
675 fclose(fp);
676 return -1;
679 input = -1;
680 output = -1;
681 i = 0;
682 found = -1;
684 p = strtok(temp, tokens);
685 do {
686 if (!(strcmp(p, "packets"))) {
687 if (input == -1)
688 input = i;
689 else
690 output = i;
692 i++;
693 p = strtok(NULL, tokens);
694 } while (input == -1 || output == -1);
696 while (fgets(temp, BUFFER_SIZE, fp)) {
697 if (strstr(temp, devname)) {
698 found = 0;
699 p = strtok(temp, tokens);
700 i = 0;
701 do {
702 if (i == input) {
703 *ip = *is = atoi(p);
704 input = -1;
706 if (i == output) {
707 *op = *os = atoi(p);
708 output = -1;
710 i++;
711 p = strtok(NULL, tokens);
712 } while (input != -1 || output != -1);
715 fclose(fp);
717 return found;
720 /*******************************************************************************\
721 |* stillonline *|
722 \*******************************************************************************/
724 int stillonline(char *ifs)
727 FILE *fp;
728 char temp[BUFFER_SIZE];
729 int i;
731 i = 0;
732 fp = fopen("/proc/net/route", "r");
733 if (fp) {
734 while (fgets(temp, BUFFER_SIZE, fp)) {
735 if (strstr(temp, ifs)) {
736 i = 1; /* Line is alive */
737 break;
740 fclose(fp);
742 return i;
745 /*******************************************************************************\
746 |* checknetdevs *|
747 \*******************************************************************************/
749 int checknetdevs(void)
752 FILE *fd;
753 char temp[BUFFER_SIZE];
754 char *p;
755 int i = 0, j;
756 int k;
757 int devsfound = 0;
758 char *tokens = " :\t\n";
759 char foundbuffer[MAX_STAT_DEVICES][8];
761 for (i = 0; i < MAX_STAT_DEVICES; i++)
762 foundbuffer[i][0] = 0;
764 /* foundbuffer vullen met info uit /proc/net/dev */
766 fd = fopen("/proc/net/dev", "r");
767 if (fd) {
768 /* Skip the first 2 lines */
769 if (!fgets(temp, BUFFER_SIZE, fd)) {
770 fclose(fd);
771 return -1;
773 if (!fgets(temp, BUFFER_SIZE, fd)) {
774 fclose(fd);
775 return -1;
777 while (fgets(temp, BUFFER_SIZE, fd)) {
778 p = strtok(temp, tokens);
779 if (p == NULL) {
780 printf("Barfed on: %s", temp);
781 break;
783 /* Skip dummy code */
785 if (!strncmp(p, "dummy", 5))
786 continue;
788 /* If p == "lo", and active_interface (as given on the cmd line) != "lo",
789 skip it! */
791 if (strcmp(p, "lo") || (active_interface && !strcmp(active_interface, "lo"))) {
792 strcpy(foundbuffer[devsfound], p);
793 devsfound++;
795 if (devsfound >= MAX_STAT_DEVICES)
796 break;
798 fclose(fd);
801 /* Nu foundbuffer naar stat_devices[].name kopieeren */
803 for (i = 0; i < MAX_STAT_DEVICES; i++) {
804 /* Loop stat_devices na, als die naam niet voorkomt in foundbuffer, kill! */
806 if (stat_devices[i].name[0]) {
807 k = 0;
808 for (j = 0; j < MAX_STAT_DEVICES; j++) {
809 if (!strcmp(stat_devices[i].name, foundbuffer[j])) {
810 k = 1;
811 foundbuffer[j][0] = 0;
814 if (!k)
815 stat_devices[i].name[0] = 0;
819 for (i = 0, j = 0; j < MAX_STAT_DEVICES; i++, j++) {
821 while (!stat_devices[j].name[0] && j < MAX_STAT_DEVICES)
822 j++;
824 if (j < MAX_STAT_DEVICES && i != j)
825 stat_devices[i] = stat_devices[j];
827 i--;
829 for (j = 0; j < MAX_STAT_DEVICES; j++) {
830 if (foundbuffer[j][0]) {
832 strcpy(stat_devices[i].name, foundbuffer[j]);
834 for (k = 0; k < 48; k++) {
835 stat_devices[i].his[k][0] = 0;
836 stat_devices[i].his[k][1] = 0;
839 i++;
842 if (LockMode && active_interface != NULL) {
843 k = 0;
844 for (j = 0; j < i; j++)
845 if (!strcmp(stat_devices[j].name, active_interface)) {
846 k = 1;
847 break;
849 if (!k) {
850 strcpy(stat_devices[i].name, active_interface);
851 for (k = 0; k < 48; k++) {
852 stat_devices[i].his[k][0] = 0;
853 stat_devices[i].his[k][1] = 0;
855 devsfound++;
859 return devsfound;
862 /*******************************************************************************\
863 |* DrawStats *|
864 \*******************************************************************************/
866 void DrawStats(int *his, int num, int size, int x_left, int y_bottom)
869 int pixels_per_byte;
870 int j, k;
871 int *p;
872 int p0, p1, p2, p3;
874 pixels_per_byte = size;
875 p = his;
876 for (j = 0; j < num; j++) {
877 if (p[0] + p[1] > pixels_per_byte)
878 pixels_per_byte = p[0] + p[1];
879 p += 2;
882 pixels_per_byte /= size;
883 p = his;
885 for (k = 0; k < num; k++) {
886 p0 = p[0];
887 p1 = p[1];
890 if (WaveForm) {
891 p2 = 0;
892 p3 = 1;
893 for (j = 0; j < size; j++) {
894 if (j < p0 / pixels_per_byte)
895 copyXPMArea(100+2, 68, 1, 1, k+x_left, y_bottom-size/2+p2/2);
896 else if (j < (p0 + p1) / pixels_per_byte)
897 copyXPMArea(100+1, 68, 1, 1, k+x_left, y_bottom-size/2+p2/2);
898 else
899 copyXPMArea(100+0, 68, 1, 1, k+x_left, y_bottom-size/2+p2/2);
901 p2 = (p2 + p3);
902 p3 *= -1;
903 p2 *= -1;
905 copyXPMArea(100+3, 68, 1, 1, k+x_left, y_bottom-size/2);
906 } else {
907 for (j = 0; j < size; j++) {
908 if (j < p0 / pixels_per_byte)
909 copyXPMArea(100+2, 68, 1, 1, k+x_left, y_bottom-j);
910 else if (j < (p0 + p1) / pixels_per_byte)
911 copyXPMArea(100+1, 68, 1, 1, k+x_left, y_bottom-j);
912 else
913 copyXPMArea(100+0, 68, 1, 1, k+x_left, y_bottom-j);
916 p += 2;
920 /*******************************************************************************\
921 |* usage *|
922 \*******************************************************************************/
924 void usage(void)
927 fprintf(stderr, "\nwmifs - programming: tijno, (de)bugging & design: warpstah, webhosting: bobby\n\n");
928 fprintf(stderr, "usage:\n");
929 fprintf(stderr, "\t-d <display name>\n");
930 fprintf(stderr, "\t-h\tthis help screen\n");
931 fprintf(stderr, "\t-i <interface name>\tdefault (as it appears in /proc/net/route)\n");
932 fprintf(stderr, "\t-I <interval>\tsampling interval, in seconds (default: 0.05)\n");
933 fprintf(stderr, "\t-l\tstarts in lock mode\n");
934 fprintf(stderr, "\t-s <interval>\tscrolling interval, in seconds (default: 5)\n");
935 fprintf(stderr, "\t-v\tprint the version number\n");
936 fprintf(stderr, "\t-w\twaveform load\n");
937 fprintf(stderr, "\n");
940 /*******************************************************************************\
941 |* printversion *|
942 \*******************************************************************************/
944 void printversion(void)
947 fprintf(stderr, "%s\n", WMIFS_VERSION);
950 /*******************************************************************************\
951 |* get_ppp_stats *|
952 \*******************************************************************************/
954 void get_ppp_stats(struct ppp_stats *cur)
957 struct ifpppstatsreq req;
959 memset(&req, 0, sizeof(req));
961 req.stats_ptr = (caddr_t) &req.stats;
963 sprintf(req.ifr__name, "ppp%d", PPP_UNIT);
965 if (ioctl(ppp_h, SIOCGPPPSTATS, &req) < 0)
966 /* fprintf(stderr, "heyho!\n") */;
967 *cur = req.stats;
970 #define LED_SZE_X (4)
971 #define LED_SZE_Y (4)
973 #define LED_ON_NET_X (87)
974 #define LED_ON_NET_Y (66)
975 #define LED_OFF_NET_X (93)
976 #define LED_OFF_NET_Y (66)
977 #define LED_ERR_NET_X (81)
978 #define LED_ERR_NET_Y (66)
979 #define LED_ON_SW_NET_X (49)
980 #define LED_ON_SW_NET_Y (85)
981 #define LED_OFF_SW_NET_X (44)
982 #define LED_OFF_SW_NET_Y (85)
984 #define LED_PWR_X (53)
985 #define LED_PWR_Y (7)
986 #define LED_SND_X (47)
987 #define LED_SND_Y (7)
988 #define LED_RCV_X (41)
989 #define LED_RCV_Y (7)
991 #define LED_SW_X (38)
992 #define LED_SW_Y (14)
994 /*******************************************************************************\
995 |* SetOnLED *|
996 \*******************************************************************************/
997 void SetOnLED(int led)
1000 switch (led) {
1002 case LED_NET_RX:
1003 copyXPMArea(LED_ON_NET_X, LED_ON_NET_Y, LED_SZE_X, LED_SZE_Y, LED_RCV_X, LED_RCV_Y);
1004 break;
1005 case LED_NET_TX:
1006 copyXPMArea(LED_ON_NET_X, LED_ON_NET_Y, LED_SZE_X, LED_SZE_Y, LED_SND_X, LED_SND_Y);
1007 break;
1008 case LED_NET_POWER:
1009 copyXPMArea(LED_ON_NET_X, LED_ON_NET_Y, LED_SZE_X, LED_SZE_Y, LED_PWR_X, LED_PWR_Y);
1010 break;
1014 /*******************************************************************************\
1015 |* SetOffLED *|
1016 \*******************************************************************************/
1017 void SetOffLED(int led)
1020 switch (led) {
1022 case LED_NET_RX:
1023 copyXPMArea(LED_OFF_NET_X, LED_OFF_NET_Y, LED_SZE_X, LED_SZE_Y, LED_RCV_X, LED_RCV_Y);
1024 break;
1025 case LED_NET_TX:
1026 copyXPMArea(LED_OFF_NET_X, LED_OFF_NET_Y, LED_SZE_X, LED_SZE_Y, LED_SND_X, LED_SND_Y);
1027 break;
1028 case LED_NET_POWER:
1029 copyXPMArea(LED_OFF_NET_X, LED_OFF_NET_Y, LED_SZE_X, LED_SZE_Y, LED_PWR_X, LED_PWR_Y);
1030 break;
1034 /*******************************************************************************\
1035 |* SetErrLED *|
1036 \*******************************************************************************/
1037 void SetErrLED(int led)
1040 switch (led) {
1041 case LED_NET_POWER:
1042 copyXPMArea(LED_ERR_NET_X, LED_ERR_NET_Y, LED_SZE_X, LED_SZE_Y, LED_PWR_X, LED_PWR_Y);
1043 break;