2 Best viewed with vim5, using ts=4
4 This code was mainly put together by looking at the
8 A neat piece of equip, used to display the date
9 and time on the screen.
10 Comes with every AfterStep installation.
13 How do I create a not so solid window?
14 How do I open a window?
18 A program that prints the amount of data that
19 is transferred over a ppp-line.
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
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.
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):
62 Thanks a LOT! It takes a while to get me convinced... :)
67 Marc De Scheemaecker / David Mihm / Chris Soghoian /
68 Alessandro Usseglio Viretta / Dan Pascu
70 and ofcourse numerous ppl who send us bug reports.
71 (numerous? hmm.. todo: rephrase this :) )
77 12/05/1998 (Antoine Nulle), warp@xs4all.nl)
78 * Made wmifs.c libc5 compatible version
79 04/05/1998 (Martijn Pieterse, pieterse@xs4all.nl)
80 * Changed the "middle of the waveform" line color
81 * Moved the RedrawWindow out of the main loop.
82 Lightens the system load
83 02/05/1998 (Martijn Pieterse, pieterse@xs4all.nl)
84 * Torn wmppp and wmifs apart.
85 This is gonna be wmifs
87 * Added waitpid, to get rid of the zombies, spotteb by Alessandro Usseglio Viretta
88 30/04/1998 (Martijn Pieterse, pieterse@xs4all.nl)
89 * Used the DrawStats routine from wmifs in wmppp
90 * I decided to add a list in this source file
91 with name of ppl who helped me build this code better.
92 * I finally removed the /proc/net/route dependancy
93 All of the connections are taken from /proc/net/dev.
94 /proc/net/route is still used for checking if it is on-line.
95 27/04/1998 (Martijn Pieterse, pieterse@xs4all.nl)
96 * WMIFS: stats scrolled, while red led burning
97 * WMPPP: changed positions of line speed
98 25/04/1998 (Martijn Pieterse, pieterse@xs4all.nl)
99 * Changed the checknetdevs routine, a lot!
100 23/04/1998 (Martijn Pieterse, pieterse@xs4all.nl)
101 * Added line speed detection. via seperate exec. (this has to be suid root!)
102 Speed has to be no more than 99999
103 * Added speed and forcespeed in ~/.wmppprc and /etc/wmppprc
104 * wmifs: added on-line detection scheme, update the bitmap coordinates
105 * wmppp: the x-button now allways disconnects.
106 22/04/1998 (Martijn Pieterse, pieterse@xs4all.nl)
107 * Added /etc/wmppprc support, including "forced" mode.
108 * Added /etc/wmifsrc support, including "forced" mode.
109 21/04/1998 (Martijn Pieterse, pieterse@xs4all.nl)
110 * Moved the stats one pixel down.
111 * Added status led in wmifs.
112 * Changed RX/TX leds of wmifs to resemble wmppp
113 * Added the "dot" between eth.0 ppp.0 etc.
114 * Changed to wmifs stats to match wmppp stats (only pppX changed)
115 * Made sure that when specified -t 1, it stayed that way, even
116 when longer than 100 minutes online
117 * With -t 1, jump from 59:59 to 01:00 instead of 99:59 to 01:40
118 16/04/1998 (Martijn Pieterse, pieterse@xs4all.nl)
119 * Added "all" devices in wmifs
120 * Added "lo" support only if aked via -i
121 * Added on-line time detection (using /var/run/ppp0.pid)
122 * Added time-out for the orange led. (one minute)
123 15/04/1998 (Martijn Pieterse, pieterse@xs4all.nl)
124 * Another wmppp-master.xpm.
125 Line speed detection being the main problem here.. :(
126 * Moved START_COMMAND / STOP_COMMAND to ~/.wmppprc
127 Return 0, everything went ok.
128 Return 10, the command did not work.
129 Please note, these functions are ran in the background.
130 * Removed the ability to configure
131 * When "v" is clicked, an orange led will appear.
132 if the connect script fails (return value == 10)
133 it will become dark again. Else the on-line detection will
134 pick it up, and "green" it.
135 14/04/1998 (Martijn Pieterse, pieterse@xs4all.nl)
137 * Added "-display" support
138 * Changed pixmap to a no-name pixmap.
139 + Changed LED positions
140 + Changed Timer position
142 05/04/1998 (Martijn Pieterse, pieterse@xs4all.nl)
143 * Added ~/.wmifsrc support.
144 * Put some code in DrawStats
145 * Check devices when pressing "device change"
146 03/04/1998 (Martijn Pieterse, pieterse@xs4all.nl)
147 * Added code for wmifs
148 28/03/1998 (Martijn Pieterse, pieterse@xs4all.nl)
149 * forgot what i did.. :)
150 27/03/1998 (Martijn Pieterse, pieterse@xs4all.nl)
151 * Added on-line detection
152 Scan through /proc/net/route and check everye line
154 * A bit of code clean-up.
165 #include <sys/wait.h>
166 #include <sys/stat.h>
167 #include <sys/param.h>
168 #include <sys/types.h>
169 #include <sys/ioctl.h>
170 #include <sys/socket.h>
172 #include <X11/Xlib.h>
174 #include <X11/extensions/shape.h>
176 #include <net/ppp_defs.h>
177 #include <net/if_ppp.h>
179 #include "../wmgeneral/wmgeneral.h"
180 #include "../wmgeneral/misc.h"
182 #include "wmifs-master.xpm"
183 #include "wmifs-mask.xbm"
189 /* Fill in the hardcoded actions */
190 #define LEFT_ACTION (NULL)
191 #define MIDDLE_ACTION (NULL)
192 #define RIGHT_ACTION (NULL)
194 /* Defines voor alle coordinate */
196 #define LED_NET_RX (4)
197 #define LED_NET_TX (5)
198 #define LED_NET_POWER (6)
200 #define WMIFS_VERSION "1.2.1"
202 /**********************/
203 /* External Variables */
204 /**********************/
206 extern char **environ
;
208 /********************/
209 /* Global Variables */
210 /********************/
213 char *active_interface
= NULL
;
224 #define PPP_STATS_HIS 54
226 /***********************/
227 /* Function Prototypes */
228 /***********************/
231 void printversion(void);
232 void DrawTime(int, int);
233 void DrawStats(int *, int, int, int, int);
237 void SetWaitLED(int);
241 void ButtonDown(int);
243 void wmifs_routine(int, char **);
245 void get_ppp_stats(struct ppp_stats
*cur
);
252 void main(int argc
, char *argv
[]) {
257 /* Parse Command Line */
260 if (strlen(ProgName
) >= 5)
261 ProgName
+= (strlen(ProgName
) - 5);
263 for (i
=1; i
<argc
; i
++) {
269 if (strcmp(arg
+1, "display")) {
275 active_interface
= argv
[i
+1];
293 wmifs_routine(argc
, argv
);
296 /*******************************************************************************\
298 \*******************************************************************************/
300 #define MAX_STAT_DEVICES 4
311 stat_dev stat_devices
[MAX_STAT_DEVICES
];
313 char *left_action
= NULL
;
314 char *right_action
= NULL
;
315 char *middle_action
= NULL
;
317 int checknetdevs(void);
318 int get_statistics(char *, long *, long *, long *, long *);
319 int stillonline(char *);
320 void DrawActiveIFS(char *);
322 void wmifs_routine(int argc
, char **argv
) {
324 rckeys wmifs_keys
[] = {
325 { "left", &left_action
},
326 { "middle", &middle_action
},
327 { "right", &right_action
},
343 long ipacket
, opacket
, istat
, ostat
;
348 for (i
=0; i
<MAX_STAT_DEVICES
; i
++) {
349 stat_devices
[i
].name
[0] = 0;
350 for (j
=0; j
<48; j
++) {
351 stat_devices
[i
].his
[j
][0] = 0;
352 stat_devices
[i
].his
[j
][1] = 0;
356 stat_online
= checknetdevs();
359 if (active_interface
) {
360 for (i
=0; i
<stat_online
; i
++) {
361 if (!strcmp(stat_devices
[i
].name
, active_interface
))
366 if (LEFT_ACTION
) left_action
= strdup(LEFT_ACTION
);
367 if (MIDDLE_ACTION
) middle_action
= strdup(MIDDLE_ACTION
);
368 if (RIGHT_ACTION
) right_action
= strdup(RIGHT_ACTION
);
370 /* Scan throught the .rc files */
371 strcpy(temp
, "/etc/wmifsrc");
372 parse_rcfile(temp
, wmifs_keys
);
376 strcat(temp
, "/.wmifsrc");
377 parse_rcfile(temp
, wmifs_keys
);
379 strcpy(temp
, "/etc/wmifsrc.fixed");
380 parse_rcfile(temp
, wmifs_keys
);
382 openXwindow(argc
, argv
, wmifs_master_xpm
, wmifs_mask_bits
, wmifs_mask_width
, wmifs_mask_height
);
385 AddMouseRegion(0, 5, 5, 35, 15);
386 AddMouseRegion(1, 5, 20, 58, 58);
389 nexttime
= starttime
+ 5;
391 for (i
=0; i
<stat_online
; i
++) {
392 get_statistics(stat_devices
[i
].name
, &ipacket
, &opacket
, &istat
, &ostat
);
393 stat_devices
[i
].istatlast
= istat
;
394 stat_devices
[i
].ostatlast
= ostat
;
397 DrawActiveIFS(stat_devices
[stat_current
].name
);
401 waitpid(0, NULL
, WNOHANG
);
403 for (i
=0; i
<stat_online
; i
++) {
404 get_statistics(stat_devices
[i
].name
, &ipacket
, &opacket
, &istat
, &ostat
);
405 stat_devices
[i
].his
[53][0] += istat
- stat_devices
[i
].istatlast
;
406 stat_devices
[i
].his
[53][1] += ostat
- stat_devices
[i
].ostatlast
;
409 if (i
== stat_current
) {
410 if (!stillonline(stat_devices
[i
].name
)) {
411 SetErrLED(LED_NET_POWER
);
413 SetOnLED(LED_NET_POWER
);
416 if (stat_devices
[i
].istatlast
== istat
)
417 SetOffLED(LED_NET_RX
);
419 SetOnLED(LED_NET_RX
);
421 if (stat_devices
[i
].ostatlast
== ostat
)
422 SetOffLED(LED_NET_TX
);
424 SetOnLED(LED_NET_TX
);
427 stat_devices
[i
].istatlast
= istat
;
428 stat_devices
[i
].ostatlast
= ostat
;
432 if (curtime
>= nexttime
) {
435 for (i
=0; i
<stat_online
; i
++) {
436 if (i
== stat_current
) {
438 DrawStats(&stat_devices
[i
].his
[0][0], 54, 40, 5, 58);
440 if (stillonline(stat_devices
[i
].name
)) {
441 for (j
=1; j
<54; j
++) {
442 stat_devices
[i
].his
[j
-1][0] = stat_devices
[i
].his
[j
][0];
443 stat_devices
[i
].his
[j
-1][1] = stat_devices
[i
].his
[j
][1];
445 stat_devices
[i
].his
[53][0] = 0;
446 stat_devices
[i
].his
[53][1] = 0;
452 while (XPending(display
)) {
453 XNextEvent(display
, &Event
);
454 switch (Event
.type
) {
459 XCloseDisplay(display
);
463 i
= CheckMouseRegion(Event
.xbutton
.x
, Event
.xbutton
.y
);
468 i
= CheckMouseRegion(Event
.xbutton
.x
, Event
.xbutton
.y
);
470 if (but_stat
== i
&& but_stat
>= 0) {
473 /* re-read the table */
474 strcpy(temp
, stat_devices
[stat_current
].name
);
475 stat_online
= checknetdevs();
477 for (i
=0; i
<stat_online
; i
++) {
478 if (!strncmp(temp
, stat_devices
[i
].name
, 4)) {
484 if (stat_current
== stat_online
) stat_current
= 0;
486 DrawActiveIFS(stat_devices
[stat_current
].name
);
488 DrawStats(&stat_devices
[stat_current
].his
[0][0], 54, 40, 5, 58);
491 switch (Event
.xbutton
.button
) {
494 execCommand(left_action
);
498 execCommand(middle_action
);
502 execCommand(right_action
);
519 /*******************************************************************************\
520 |* void DrawActiveIFS(char *) *|
521 \*******************************************************************************/
523 void DrawActiveIFS(char *name
) {
527 Alles 9 hoog, 6 breedt
537 copyXPMArea(5, 84, 30, 10, 5, 5);
541 for (i
=0; name
[i
]; i
++) {
542 if (i
== strlen(name
)-1 && strlen(name
) <= 4 && name
[strlen(name
)-1] >= '0' && name
[strlen(name
)-1] <= '9') {
543 copyXPMArea(61, 64, 4, 9, k
, 5);
546 c
= toupper(name
[i
]);
547 if (c
>= 'A' && c
<= 'Z') {
549 copyXPMArea(c
* 6, 74, 6, 9, k
, 5);
553 copyXPMArea(c
* 6, 64, 6, 9, k
, 5);
560 /*******************************************************************************\
562 \*******************************************************************************/
564 int get_statistics(char *devname
, long *ip
, long *op
, long *is
, long *os
) {
569 char *tokens
= " |:\n";
573 struct ppp_stats ppp_cur
, ppp_old
;
574 static int ppp_opened
= 0;
577 if (!strncmp(devname
, "ppp", 3)) {
579 /* Open the ppp device. */
580 memset(&ppp_cur
, 0, sizeof(ppp_cur
));
581 if ((ppp_h
= socket(AF_INET
, SOCK_DGRAM
, 0)) < 0)
583 get_ppp_stats(&ppp_cur
);
588 get_ppp_stats(&ppp_cur
);
590 *op
= ppp_cur
.p
.ppp_opackets
;
591 *ip
= ppp_cur
.p
.ppp_ipackets
;
593 *is
= ppp_cur
.p
.ppp_ibytes
;
594 *os
= ppp_cur
.p
.ppp_obytes
;
599 /* Read from /proc/net/dev the stats! */
600 fp
= fopen("/proc/net/dev", "r");
601 fgets(temp
, 128, fp
);
602 fgets(temp
, 128, fp
);
609 p
= strtok(temp
, tokens
);
611 if (!(strcmp(p
, "packets"))) {
612 if (input
== -1) input
= i
;
616 p
= strtok(NULL
, tokens
);
617 } while (input
== -1 || output
== -1);
619 while (fgets(temp
, 128, fp
)) {
620 if (strstr(temp
, devname
)) {
622 p
= strtok(temp
, tokens
);
634 p
= strtok(NULL
, tokens
);
635 } while (input
!= -1 || output
!= -1);
643 /*******************************************************************************\
645 \*******************************************************************************/
647 int stillonline(char *ifs
) {
654 fp
= fopen("/proc/net/route", "r");
656 while (fgets(temp
, 128, fp
)) {
657 if (strstr(temp
, ifs
)) {
658 i
= 1; /* Line is alive */
666 /*******************************************************************************\
668 \*******************************************************************************/
670 int checknetdevs(void) {
678 char *tokens
= " :\t\n";
679 char foundbuffer
[MAX_STAT_DEVICES
][8];
681 for (i
=0; i
<MAX_STAT_DEVICES
; i
++) {
682 foundbuffer
[i
][0] = 0;
685 /* foundbuffer vullen met info uit /proc/net/dev */
687 fd
= fopen("/proc/net/dev", "r");
689 /* Skip the first 2 lines */
690 fgets(temp
, 128, fd
);
691 fgets(temp
, 128, fd
);
692 while (fgets(temp
, 128, fd
)) {
693 p
= strtok(temp
, tokens
);
695 /* Skip dummy code */
697 if (!strncmp(p
, "dummy", 5))
700 /* If p == "lo", and active_interface (as given on the cmd line) != "lo",
703 if (strcmp(p
, "lo") || (active_interface
&& !strcmp(active_interface
, "lo"))) {
704 strcpy(foundbuffer
[devsfound
], p
);
711 /* Nu foundbuffer naar stat_devices[].name kopieeren */
713 for (i
=0; i
<MAX_STAT_DEVICES
; i
++) {
714 /* Loop stat_devices na, als die naam niet voorkomt in foundbuffer, kill! */
716 if (stat_devices
[i
].name
[0]) {
718 for (j
=0; j
<MAX_STAT_DEVICES
; j
++) {
719 if (!strcmp(stat_devices
[i
].name
, foundbuffer
[j
])) {
721 foundbuffer
[j
][0] = 0;
724 if (!k
) stat_devices
[i
].name
[0] = 0;
728 for (i
=0, j
=0; j
<MAX_STAT_DEVICES
; i
++) {
730 while (!stat_devices
[j
].name
[0] && j
< MAX_STAT_DEVICES
)
733 if (j
< MAX_STAT_DEVICES
&& i
!= j
) {
734 stat_devices
[i
] = stat_devices
[j
];
741 for (j
=0; j
<MAX_STAT_DEVICES
; j
++) {
742 if (foundbuffer
[j
][0]) {
744 strcpy(stat_devices
[i
].name
, foundbuffer
[j
]);
746 for (k
=0; k
<48; k
++) {
747 stat_devices
[i
].his
[k
][0] = 0;
748 stat_devices
[i
].his
[k
][1] = 0;
759 /*******************************************************************************\
761 \*******************************************************************************/
763 void DrawStats(int *his
, int num
, int size
, int x_left
, int y_bottom
) {
770 pixels_per_byte
= 1*size
;
772 for (j
=0; j
<num
; j
++) {
773 if (p
[0] + p
[1] > pixels_per_byte
)
774 pixels_per_byte
= p
[0] + p
[1];
778 pixels_per_byte
/= size
;
781 for (k
=0; k
<num
; k
++) {
789 for (j
=0; j
<size
; j
++) {
790 if (j
< p0
/ pixels_per_byte
)
791 copyXPMArea(100+2, 68, 1, 1, k
+x_left
, y_bottom
-size
/2+p2
/2);
792 else if (j
< (p0
+ p1
) / pixels_per_byte
)
793 copyXPMArea(100+1, 68, 1, 1, k
+x_left
, y_bottom
-size
/2+p2
/2);
795 copyXPMArea(100+0, 68, 1, 1, k
+x_left
, y_bottom
-size
/2+p2
/2);
801 copyXPMArea(100+3, 68, 1, 1, k
+x_left
, y_bottom
-size
/2);
803 for (j
=0; j
<size
; j
++) {
804 if (j
< p0
/ pixels_per_byte
)
805 copyXPMArea(100+2, 68, 1, 1, k
+x_left
, y_bottom
-j
);
806 else if (j
< (p0
+ p1
) / pixels_per_byte
)
807 copyXPMArea(100+1, 68, 1, 1, k
+x_left
, y_bottom
-j
);
809 copyXPMArea(100+0, 68, 1, 1, k
+x_left
, y_bottom
-j
);
816 /*******************************************************************************\
818 \*******************************************************************************/
822 fprintf(stderr
, "\nwmifs - programming: tijno, (de)bugging & design: warpstah, webhosting: bobby \n\n");
823 fprintf(stderr
, "usage:\n");
824 fprintf(stderr
, "\t-d <display name>\n");
825 fprintf(stderr
, "\t-h\tthis help screen\n");
826 fprintf(stderr
, "\t-i <interface name>\tdefault (as it appears in /proc/net/route)\n");
827 fprintf(stderr
, "\t-v\tprint the version number\n");
828 fprintf(stderr
, "\t-w\twaveform load\n");
829 fprintf(stderr
, "\n");
832 /*******************************************************************************\
834 \*******************************************************************************/
836 void printversion(void) {
838 fprintf(stderr
, "%s\n", WMIFS_VERSION
);
841 /*******************************************************************************\
843 \*******************************************************************************/
845 void get_ppp_stats(struct ppp_stats
*cur
) {
847 struct ifpppstatsreq req
;
849 memset(&req
, 0, sizeof(req
));
851 req
.stats_ptr
= (caddr_t
) &req
.stats
;
853 sprintf(req
.ifr__name
, "ppp%d", PPP_UNIT
);
855 if (ioctl(ppp_h
, SIOCGPPPSTATS
, &req
) < 0) {
856 fprintf(stderr
, "heyho!\n");
862 #define LED_SZE_X (4)
863 #define LED_SZE_Y (4)
865 #define LED_ON_NET_X (87)
866 #define LED_ON_NET_Y (66)
867 #define LED_OFF_NET_X (93)
868 #define LED_OFF_NET_Y (66)
869 #define LED_ERR_NET_X (81)
870 #define LED_ERR_NET_Y (66)
871 #define LED_ON_SW_NET_X (49)
872 #define LED_ON_SW_NET_Y (85)
873 #define LED_OFF_SW_NET_X (44)
874 #define LED_OFF_SW_NET_Y (85)
876 #define LED_PWR_X (53)
877 #define LED_PWR_Y (7)
878 #define LED_SND_X (47)
879 #define LED_SND_Y (7)
880 #define LED_RCV_X (41)
881 #define LED_RCV_Y (7)
883 #define LED_SW_X (38)
884 #define LED_SW_Y (14)
886 /*******************************************************************************\
888 \*******************************************************************************/
889 void SetOnLED(int led
) {
894 copyXPMArea(LED_ON_NET_X
, LED_ON_NET_Y
, LED_SZE_X
, LED_SZE_Y
, LED_RCV_X
, LED_RCV_Y
);
897 copyXPMArea(LED_ON_NET_X
, LED_ON_NET_Y
, LED_SZE_X
, LED_SZE_Y
, LED_SND_X
, LED_SND_Y
);
900 copyXPMArea(LED_ON_NET_X
, LED_ON_NET_Y
, LED_SZE_X
, LED_SZE_Y
, LED_PWR_X
, LED_PWR_Y
);
905 /*******************************************************************************\
907 \*******************************************************************************/
908 void SetOffLED(int led
) {
913 copyXPMArea(LED_OFF_NET_X
, LED_OFF_NET_Y
, LED_SZE_X
, LED_SZE_Y
, LED_RCV_X
, LED_RCV_Y
);
916 copyXPMArea(LED_OFF_NET_X
, LED_OFF_NET_Y
, LED_SZE_X
, LED_SZE_Y
, LED_SND_X
, LED_SND_Y
);
919 copyXPMArea(LED_OFF_NET_X
, LED_OFF_NET_Y
, LED_SZE_X
, LED_SZE_Y
, LED_PWR_X
, LED_PWR_Y
);
924 /*******************************************************************************\
926 \*******************************************************************************/
927 void SetErrLED(int led
) {
931 copyXPMArea(LED_ERR_NET_X
, LED_ERR_NET_Y
, LED_SZE_X
, LED_SZE_Y
, LED_PWR_X
, LED_PWR_Y
);