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 WindowMaker 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 Authors: Martijn Pieterse (pieterse@xs4all.nl)
26 Antoine Nulle (warp@xs4all.nl)
28 This program might be Y2K resistant. We shall see. :)
30 This program is distributed under the GPL license.
31 (as were asclock and pppstats)
33 Known Features: (or in non M$ talk, BUGS)
34 * none known so far in this release
40 CCC (Constructive Code Criticism):
43 Thanks a LOT! It takes a while to get me convinced... :)
48 Marc De Scheemaecker / David Mihm / Chris Soghoian /
49 Alessandro Usseglio Viretta
51 and ofcourse numerous ppl who send us bug reports.
52 (numerous? hmm.. todo: rephrase this :) )
53 Make that numberous m8ey :)
58 05/09/1998 (Martijn Pieterse, pieterse@xs4all.nl)
60 Speed-O-Meter (after 60 seconds)
61 Fixed Error reporting when pressing X
62 Removed the ugly kb lines
63 Stopped clearing on-line time when pressing X
64 Added createXBMfromXPM
65 08/05/1998 (Martijn Pieterse, pieterse@xs4all.nl)
66 * Removed some code from get_statistics
67 * Check if "ifdown" is empty before execCommanding it!
68 07/05/1998 (Martijn Pieterse, pieterse@xs4all.nl)
69 * Made the program use the xpm like warp wanted it to be :)
70 04/05/1998 (Martijn Pieterse, pieterse@xs4all.nl)
71 * Added pppX support. (EXPERIMENTAL!)
72 Removed HARD_CODED_DEV. (that stayed in long! :) )
73 * Changed 33600 speed indication to 33k6
74 Bugs if larger than 115k2 (depends on how much 1's present)
75 Moved the speed ind. code to DrawSpeedInd
76 * Added 1k lines in the stats
77 * Moved all the "ppp0" references into HARD_CODED_DEV.
79 03/05/1998 (Martijn Pieterse, pieterse@xs4all.nl)
80 * Removed the number after -t.
81 02/05/1998 (Martijn Pieterse, pieterse@xs4all.nl)
82 * Removed the heyho code :)
83 * Changed read_rc_file to parse_rcfile. suggested bt Marcelo E. Magallon
84 * Added some extra checks for the -t option.
85 If no number was given, it would core dump
86 30/04/1998 (Martijn Pieterse, pieterse@xs4all.nl)
87 * Added execCommand code. (taken from windowmaker soure, as advised by Marcelo E. Magallon)
88 * Cleaned the source up a bit
89 * Decided to split op wmppp and wmifs
90 This is gonna be wmppp
91 * Used the DrawStats routine from wmifs in wmppp
92 * I decided to add a list in this source file
93 with name of ppl who helped me build this code better.
94 * I finally removed the /proc/net/route dependancy
95 All of the connections are taken from /proc/net/dev.
96 /proc/net/route is still used for checking if it is on-line.
97 27/04/1998 (Martijn Pieterse, pieterse@xs4all.nl)
98 * WMIFS: stats scrolled, while red led burning
99 * WMPPP: changed positions of line speed
100 25/04/1998 (Martijn Pieterse, pieterse@xs4all.nl)
101 * Changed the checknetdevs routine, a lot!
102 23/04/1998 (Martijn Pieterse, pieterse@xs4all.nl)
103 * Added line speed detection. via seperate exec. (this has to be suid root!)
104 Speed has to be no more than 99999
105 * Added speed and forcespeed in ~/.wmppprc and /etc/wmppprc
106 * wmifs: added on-line detection scheme, update the bitmap coordinates
107 * wmppp: the x-button now allways disconnects.
108 22/04/1998 (Martijn Pieterse, pieterse@xs4all.nl)
109 * Added /etc/wmppprc support, including "forced" mode.
110 * Added /etc/wmifsrc support, including "forced" mode.
111 21/04/1998 (Martijn Pieterse, pieterse@xs4all.nl)
112 * Moved the stats one pixel down.
113 * Added status led in wmifs.
114 * Changed RX/TX leds of wmifs to resemble wmppp
115 * Added the "dot" between eth.0 ppp.0 etc.
116 * Changed to wmifs stats to match wmppp stats (only pppX changed)
117 * Made sure that when specified -t 1, it stayed that way, even
118 when longer than 100 minutes online
119 * With -t 1, jump from 59:59 to 01:00 instead of 99:59 to 01:40
120 16/04/1998 (Martijn Pieterse, pieterse@xs4all.nl)
121 * Added "all" devices in wmifs
122 * Added "lo" support only if aked via -i
123 * Added on-line time detection (using /var/run/ppp0.pid)
124 * Added time-out for the orange led. (one minute)
125 15/04/1998 (Martijn Pieterse, pieterse@xs4all.nl)
126 * Another wmppp-master.xpm.
127 Line speed detection being the main problem here.. :(
128 * Moved START_COMMAND / STOP_COMMAND to ~/.wmppprc
129 Return 0, everything went ok.
130 Return 10, the command did not work.
131 Please note, these functions are ran in the background.
132 * Removed the ability to configure
133 * When "v" is clicked, an orange led will appear.
134 if the connect script fails (return value == 10)
135 it will become dark again. Else the on-line detection will
136 pick it up, and "green" it.
137 14/04/1998 (Martijn Pieterse, pieterse@xs4all.nl)
139 * Added "-display" support
140 * Changed pixmap to a no-name pixmap.
141 + Changed LED positions
142 + Changed Timer position
144 05/04/1998 (Martijn Pieterse, pieterse@xs4all.nl)
145 * Added ~/.wmifsrc support.
146 * Put some code in DrawStats
147 * Check devices when pressing "device change"
148 03/04/1998 (Martijn Pieterse, pieterse@xs4all.nl)
149 * Added code for wmifs
150 28/03/1998 (Martijn Pieterse, pieterse@xs4all.nl)
151 * forgot what i did.. :)
152 27/03/1998 (Martijn Pieterse, pieterse@xs4all.nl)
153 * Added on-line detection
154 Scan through /proc/net/route and check everye line
156 * A bit of code clean-up.
167 #include <sys/wait.h>
168 #include <sys/stat.h>
169 #include <sys/param.h>
170 #include <sys/types.h>
171 #include <sys/ioctl.h>
172 #include <sys/socket.h>
174 #include <net/ppp_defs.h>
175 #include <net/if_ppp.h>
177 #include <X11/Xlib.h>
179 #include <X11/extensions/shape.h>
181 #include "../wmgeneral/wmgeneral.h"
182 #include "../wmgeneral/misc.h"
184 #include "wmppp-master.xpm"
190 #define START_ACTION (NULL)
191 #define STOP_ACTION (NULL)
192 #define SPEED_ACTION (NULL)
193 #define IFDOWN_ACTION (NULL)
195 #define STAMP_FILE_PRE "/var/run/wmppp."
197 /* Defines voor alle coordinate */
199 #define LED_PPP_RX (1)
200 #define LED_PPP_TX (2)
201 #define LED_PPP_POWER (3)
209 #define TIMER_SRC_Y (65)
210 #define TIMER_DES_Y (6)
211 #define TIMER_SZE_X (6)
213 #define WMPPP_VERSION "1.3.0"
215 #define ORANGE_LED_TIMEOUT (60)
217 /**********************/
218 /* External Variables */
219 /**********************/
221 extern char **environ
;
223 /********************/
224 /* Global Variables */
225 /********************/
228 char *active_interface
= "ppp0";
232 int wmppp_mask_width
= 64;
233 int wmppp_mask_height
= 64;
234 char wmppp_mask_bits
[64*64];
244 #define PPP_STATS_HIS 54
248 int ppp_history
[PPP_STATS_HIS
+1][2];
250 /***********************/
251 /* Function Prototypes */
252 /***********************/
255 void printversion(void);
256 void DrawTime(int, int);
257 void DrawStats(int *, int, int, int, int);
258 void DrawSpeedInd(char *);
259 void DrawLoadInd(int);
263 void SetWaitLED(int);
267 void ButtonDown(int);
269 void wmppp_routine(int, char **);
271 int get_statistics(char *, long *, long *, long *, long *);
272 void get_ppp_stats(struct ppp_stats
*cur
);
273 int stillonline(char *);
280 int main(int argc
, char *argv
[]) {
285 /* Parse Command Line */
288 if (strlen(ProgName
) >= 5)
289 ProgName
+= (strlen(ProgName
) - 5);
291 for (i
=1; i
<argc
; i
++) {
297 if (strcmp(arg
+1, "display")) {
303 if (strcmp(arg
+1, "geometry")) {
313 /* following removed to allow experiments with
314 * new devices, i.e. ippp
317 if (strncmp(argv
[i
+1], "ppp", 3)) {
322 active_interface
= argv
[i
+1];
334 updaterate
= atoi(argv
[i
]);
335 if (updaterate
< 1 || updaterate
> 10) {
352 wmppp_routine(argc
, argv
);
361 char *start_action
= NULL
;
362 char *stop_action
= NULL
;
363 char *speed_action
= NULL
;
364 char *ifdown_action
= NULL
;
365 char *stamp_file
= NULL
;
367 void wmppp_routine(int argc
, char **argv
) {
369 rckeys wmppp_keys
[] = {
370 { "start", &start_action
},
371 { "stop", &stop_action
},
372 { "speed", &speed_action
},
373 { "ifdown", &ifdown_action
},
374 { "stampfile", &stamp_file
},
389 long ppp_send
,ppp_sl
=-1;
390 long ppp_recv
,ppp_rl
=-1;
391 long ppp_sbytes
,ppp_rbytes
;
392 long ppp_osbytes
,ppp_orbytes
;
396 pid_t stop_child
= 0;
397 pid_t start_child
= 0;
407 /* Initialize some stuff */
409 get_statistics(active_interface
, &ppp_rl
, &ppp_sl
, &ppp_orbytes
, &ppp_osbytes
);
411 /* Scan through ~/.wmifsrc for the mouse button actions. */
412 if (START_ACTION
) start_action
= strdup(START_ACTION
);
413 if (STOP_ACTION
) stop_action
= strdup(STOP_ACTION
);
414 if (SPEED_ACTION
) speed_action
= strdup(SPEED_ACTION
);
415 if (IFDOWN_ACTION
) ifdown_action
= strdup(IFDOWN_ACTION
);
416 if (STAMP_FILE_PRE
) {
417 sprintf (temp
, "%s%s", STAMP_FILE_PRE
, active_interface
);
418 stamp_file
= strdup (temp
);
422 strcpy(temp
, "/etc/wmppprc");
423 parse_rcfile(temp
, wmppp_keys
);
427 strcat(temp
, "/.wmppprc");
428 parse_rcfile(temp
, wmppp_keys
);
430 strcpy(temp
, "/etc/wmppprc.fixed");
431 parse_rcfile(temp
, wmppp_keys
);
433 /* Open the display */
435 createXBMfromXPM(wmppp_mask_bits
, wmppp_master_xpm
, wmppp_mask_width
, wmppp_mask_height
);
437 openXwindow(argc
, argv
, wmppp_master_xpm
, wmppp_mask_bits
, wmppp_mask_width
, wmppp_mask_height
);
440 AddMouseRegion(0, 35, 48, 46, 58);
442 AddMouseRegion(1, 47, 48, 58, 58);
445 currenttime
= time(0);
449 copyXPMArea(28, 95, 25, 11, 5, 48);
451 /* wmppp main loop */
453 lasttime
= currenttime
;
454 currenttime
= time(0);
455 /* Check if any child has left the playground */
456 i
= waitpid(0, &status
, WNOHANG
);
457 if (i
== stop_child
&& stop_child
!= 0) {
460 SetOffLED(LED_PPP_POWER
);
461 SetOffLED(LED_PPP_RX
);
462 SetOffLED(LED_PPP_TX
);
463 copyXPMArea(28, 95, 25, 11, 5, 48);
469 if (i
== start_child
&& start_child
!= 0) {
470 if (WIFEXITED(status
)) {
471 if (WEXITSTATUS(status
) == 10) {
474 copyXPMArea(28, 95, 25, 11, 5, 48);
475 SetOffLED(LED_PPP_POWER
);
483 /* On-line detectie! 1x per second */
485 if (currenttime
!= lasttime
) {
488 if (stillonline(active_interface
)) {
491 starttime
= currenttime
;
493 if (stat(stamp_file
, &st
) == 0)
494 starttime
= st
.st_mtime
;
496 SetOnLED(LED_PPP_POWER
);
499 copyXPMArea(28, 95, 25, 11, 5, 48);
502 DrawSpeedInd(speed_action
);
504 speed_ind
= currenttime
+ 60;
509 if (!i
&& starttime
) {
511 SetErrLED(LED_PPP_POWER
);
513 copyXPMArea(0, 95, 26, 11, 5, 48);
516 execCommand(ifdown_action
);
522 if (waittime
&& waittime
<= currenttime
) {
523 SetOffLED(LED_PPP_POWER
);
528 /* If we are on-line. Print the time we are */
530 i
= currenttime
- starttime
;
534 if (TimerDivisor
== 1)
535 if (i
> 59 * 60 + 59) i
/= 60;
538 hour
= (i
/ 60) % 100;
539 i
= hour
* 100 + minute
;
541 DrawTime(i
, currenttime
% 2);
542 /* We are online, so we can check for send/recv packets */
544 get_statistics(active_interface
, &ppp_recv
, &ppp_send
, &ppp_rbytes
, &ppp_sbytes
);
546 if (ppp_send
!= ppp_sl
) SetOnLED(LED_PPP_TX
);
547 else SetOffLED(LED_PPP_TX
);
549 if (ppp_recv
!= ppp_rl
) SetOnLED(LED_PPP_RX
);
550 else SetOffLED(LED_PPP_RX
);
555 /* Every five seconds we check to load on the line */
557 if ((currenttime
- ppptime
>= 0) || (ppptime
== 0)) {
559 ppptime
= currenttime
+ updaterate
;
561 ppp_history
[PPP_STATS_HIS
][0] = ppp_rbytes
- ppp_orbytes
;
562 ppp_history
[PPP_STATS_HIS
][1] = ppp_sbytes
- ppp_osbytes
;
564 ppp_orbytes
= ppp_rbytes
;
565 ppp_osbytes
= ppp_sbytes
;
567 DrawStats(&ppp_history
[0][0], 54, 25, 5, 43);
569 for (j
=1; j
<55; j
++) {
570 ppp_history
[j
-1][0] = ppp_history
[j
][0];
571 ppp_history
[j
-1][1] = ppp_history
[j
][1];
573 if (currenttime
> speed_ind
) {
574 DrawLoadInd((ppp_history
[54][0] + ppp_history
[54][1]) / updaterate
);
582 while (XPending(display
)) {
583 XNextEvent(display
, &Event
);
584 switch (Event
.type
) {
589 XCloseDisplay(display
);
590 while (start_child
| stop_child
) {
591 i
= waitpid(0, &status
, WNOHANG
);
592 if (i
== stop_child
) stop_child
= 0;
593 if (i
== start_child
) start_child
= 0;
599 i
= CheckMouseRegion(Event
.xbutton
.x
, Event
.xbutton
.y
);
613 i
= CheckMouseRegion(Event
.xbutton
.x
, Event
.xbutton
.y
);
614 // Button but_stat omhoogdoen!
624 if (i
== but_stat
&& but_stat
>= 0) {
628 copyXPMArea(28, 95, 25, 11, 5, 48);
630 start_child
= execCommand(start_action
);
631 SetWaitLED(LED_PPP_POWER
);
632 waittime
= ORANGE_LED_TIMEOUT
+ currenttime
;
637 if (stop_child
== 0) {
638 stop_child
= execCommand(stop_action
);
655 /*******************************************************************************\
657 \*******************************************************************************/
659 int get_statistics(char *devname
, long *ip
, long *op
, long *is
, long *os
) {
661 struct ppp_stats ppp_cur
;
662 static int ppp_opened
= 0;
666 /* Open the ppp device. */
667 memset(&ppp_cur
, 0, sizeof(ppp_cur
));
668 if ((ppp_h
= socket(AF_INET
, SOCK_DGRAM
, 0)) < 0)
673 get_ppp_stats(&ppp_cur
);
675 *op
= ppp_cur
.p
.ppp_opackets
;
676 *ip
= ppp_cur
.p
.ppp_ipackets
;
678 *is
= ppp_cur
.p
.ppp_ibytes
;
679 *os
= ppp_cur
.p
.ppp_obytes
;
684 /*******************************************************************************\
686 \*******************************************************************************/
688 int stillonline(char *ifs
) {
695 fp
= fopen("/proc/net/route", "r");
697 while (fgets(temp
, 128, fp
)) {
698 if (strstr(temp
, ifs
)) {
699 i
= 1; /* Line is alive */
707 /*******************************************************************************\
709 \*******************************************************************************/
711 void DrawTime(int i
, int j
) {
715 copyXPMArea(TIMER_SZE_X
*((i
/ k
)%10)+1, TIMER_SRC_Y
, 5, 7, 6+6*0, TIMER_DES_Y
);
717 copyXPMArea(TIMER_SZE_X
*((i
/ k
)%10)+1, TIMER_SRC_Y
, 5, 7, 6+6*1, TIMER_DES_Y
);
721 copyXPMArea(62, TIMER_SRC_Y
, 1, 7, 6+6*2+1, TIMER_DES_Y
);
723 copyXPMArea(63, TIMER_SRC_Y
, 1, 7, 6+6*2+1, TIMER_DES_Y
);
725 copyXPMArea(TIMER_SZE_X
*((i
/ k
)%10)+1, TIMER_SRC_Y
, 5, 7, 6+6*2 + 4, TIMER_DES_Y
);
727 copyXPMArea(TIMER_SZE_X
*((i
/ k
)%10)+1, TIMER_SRC_Y
, 5, 7, 6+6*3 + 4, TIMER_DES_Y
);
730 /*******************************************************************************\
732 \*******************************************************************************/
734 void DrawStats(int *his
, int num
, int size
, int x_left
, int y_bottom
) {
740 pixels_per_byte
= 1*size
;
742 for (j
=0; j
<num
; j
++) {
743 if (p
[0] + p
[1] > pixels_per_byte
)
744 pixels_per_byte
= p
[0] + p
[1];
748 pixels_per_byte
/= size
;
751 for (k
=0; k
<num
; k
++) {
754 for (j
=0; j
<size
; j
++) {
756 if (j
< p
[0] / pixels_per_byte
)
757 copyXPMArea(57+2, 85, 1, 1, k
+x_left
, y_bottom
-j
);
758 else if (j
< (p
[0] + p
[1]) / pixels_per_byte
)
759 copyXPMArea(57+1, 85, 1, 1, k
+x_left
, y_bottom
-j
);
761 copyXPMArea(57+0, 85, 1, 1, k
+x_left
, y_bottom
-j
);
767 /*******************************************************************************\
769 \*******************************************************************************/
771 void PrintLittle(int i
, int *k
) {
776 /* Print the "k" letter */
777 copyXPMArea(11*5-5, 86, 4, 9, *k
, 48);
781 copyXPMArea(13*5-5, 86, 4, 9, *k
, 48);
785 copyXPMArea(45, 86, 5, 9, *k
, 48);
789 copyXPMArea(i
*5-5, 86, 5, 9, *k
, 48);
794 void DrawSpeedInd(char *speed_action
) {
801 fp
= popen(speed_action
, "r");
806 while (fgets(temp
, 128, fp
))
811 if ((p
=strstr(temp
, "CONNECT"))) {
812 linespeed
= atoi(p
+ 8);
817 i
= (linespeed
% 1000) / 100;
822 copyXPMArea(50, 86, 5, 9, k
, 48);
825 PrintLittle(linespeed
% 10, &k
);
831 /*******************************************************************************\
833 \*******************************************************************************/
835 void DrawLoadInd(int speed
) {
840 for (i
=0; i
<5; i
++) PrintLittle(-1, &k
);
844 /* If speed is greater than 99999, display it in K */
848 PrintLittle(-2, &k
) ;
852 PrintLittle(speed
% 10, &k
);
857 /*******************************************************************************\
859 \*******************************************************************************/
863 fprintf(stderr
, "\nwmppp - programming: tijno, design & ideas: warp\n\n");
864 fprintf(stderr
, "usage:\n");
865 fprintf(stderr
, "-display <display name>\n");
866 fprintf(stderr
, "-geometry +XPOS+YPOS initial window position\n");
867 fprintf(stderr
, "-h this help screen\n");
868 fprintf(stderr
, "-i <device> (ppp0, ppp1, etc) EXPERIMENTAL! Please send bugreports!\n");
869 fprintf(stderr
, "-t set the on-line timer to MM:SS instead of HH:MM\n");
870 fprintf(stderr
, "-u <update rate> (1..10), default 5 seconds\n");
871 fprintf(stderr
, "-v print the version number\n");
872 fprintf(stderr
, "\n");
875 /*******************************************************************************\
877 \*******************************************************************************/
879 void printversion(void) {
881 fprintf(stderr
, "%s\n", WMPPP_VERSION
);
884 /*******************************************************************************\
886 \*******************************************************************************/
888 void get_ppp_stats(struct ppp_stats
*cur
) {
890 struct ifpppstatsreq req
;
892 memset(&req
, 0, sizeof(req
));
894 req
.stats_ptr
= (caddr_t
) &req
.stats
;
896 strcpy(req
.ifr__name
, active_interface
);
898 if (ioctl(ppp_h
, SIOCGPPPSTATS
, &req
) >= 0)
902 #define LED_ON_X (50)
903 #define LED_ON_Y (80)
904 #define LED_OFF_Y (75)
905 #define LED_OFF_X (50)
907 #define LED_ERR_X (56)
908 #define LED_ERR_Y (75)
909 #define LED_WTE_X (56)
910 #define LED_WTE_Y (80)
911 #define LED_SZE_X (4)
912 #define LED_SZE_Y (4)
914 #define LED_PWR_X (53)
915 #define LED_PWR_Y (7)
916 #define LED_SND_X (47)
917 #define LED_SND_Y (7)
918 #define LED_RCV_X (41)
919 #define LED_RCV_Y (7)
921 #define LED_SW_X (38)
922 #define LED_SW_Y (14)
924 /*******************************************************************************\
926 \*******************************************************************************/
927 void SetOnLED(int led
) {
931 copyXPMArea(LED_ON_X
, LED_ON_Y
, LED_SZE_X
, LED_SZE_Y
, LED_PWR_X
, LED_PWR_Y
);
934 copyXPMArea(LED_ON_X
, LED_ON_Y
, LED_SZE_X
, LED_SZE_Y
, LED_RCV_X
, LED_RCV_Y
);
937 copyXPMArea(LED_ON_X
, LED_ON_Y
, LED_SZE_X
, LED_SZE_Y
, LED_SND_X
, LED_SND_Y
);
942 /*******************************************************************************\
944 \*******************************************************************************/
945 void SetOffLED(int led
) {
949 copyXPMArea(LED_OFF_X
, LED_OFF_Y
, LED_SZE_X
, LED_SZE_Y
, LED_PWR_X
, LED_PWR_Y
);
952 copyXPMArea(LED_OFF_X
, LED_OFF_Y
, LED_SZE_X
, LED_SZE_Y
, LED_RCV_X
, LED_RCV_Y
);
955 copyXPMArea(LED_OFF_X
, LED_OFF_Y
, LED_SZE_X
, LED_SZE_Y
, LED_SND_X
, LED_SND_Y
);
961 /*******************************************************************************\
963 \*******************************************************************************/
964 void SetErrLED(int led
) {
968 copyXPMArea(LED_ERR_X
, LED_ERR_Y
, LED_SZE_X
, LED_SZE_Y
, LED_PWR_X
, LED_PWR_Y
);
973 /*******************************************************************************\
975 \*******************************************************************************/
976 void SetWaitLED(int led
) {
980 copyXPMArea(LED_WTE_X
, LED_WTE_Y
, LED_SZE_X
, LED_SZE_Y
, LED_PWR_X
, LED_PWR_Y
);
985 /*******************************************************************************\
987 \*******************************************************************************/
988 void ButtonUp(int button
) {
992 copyXPMArea(24, 74, 12, 11, 35, 48);
995 copyXPMArea(36, 74, 12, 11, 47, 48);
1000 /*******************************************************************************\
1002 \*******************************************************************************/
1003 void ButtonDown(int button
) {
1007 copyXPMArea(0, 74, 12, 11, 35, 48);
1010 copyXPMArea(12, 74, 12, 11, 47, 48);