1153 lines
30 KiB
C
1153 lines
30 KiB
C
/* WMiFS - a complete network monitoring dock.app
|
|
Copyright (C) 1997, 1998 Martijn Pieterse <pieterse@xs4all.nl>
|
|
Copyright (C) 1997, 1998 Antoine Nulle <warp@xs4all.nl>
|
|
|
|
This program is free software; you can redistribute it and/or modify
|
|
it under the terms of the GNU General Public License as published by
|
|
the Free Software Foundation; either version 2 of the License, or
|
|
(at your option) any later version.
|
|
|
|
This program is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
GNU General Public License for more details.
|
|
|
|
You should have received a copy of the GNU General Public License along
|
|
with this program; if not, write to the Free Software Foundation, Inc.,
|
|
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
|
|
|
Best viewed with vim5, using ts=4
|
|
|
|
This code was mainly put together by looking at the
|
|
following programs:
|
|
|
|
asclock
|
|
A neat piece of equip, used to display the date
|
|
and time on the screen.
|
|
Comes with every AfterStep installation.
|
|
|
|
Source used:
|
|
How do I create a not so solid window?
|
|
How do I open a window?
|
|
How do I use pixmaps?
|
|
|
|
pppstats
|
|
A program that prints the amount of data that
|
|
is transferred over a ppp-line.
|
|
|
|
Source used:
|
|
How do I read the ppp device?
|
|
------------------------------------------------------------
|
|
|
|
Author: Martijn Pieterse (pieterse@xs4all.nl)
|
|
|
|
This program was hacked together between the 7th of March
|
|
and the 14th of March 1998.
|
|
|
|
This program might be Y2K resistant. We shall see. :)
|
|
|
|
This program is distributed under the GPL license.
|
|
(as were asclock and pppstats)
|
|
|
|
Known Features: (or in non M$ talk, BUGS)
|
|
* only ppp0 will be read
|
|
use wmifs if you want to read more than one ppp connection
|
|
not sure about this.
|
|
* the leds won't be reliable with
|
|
more than 1 ppp connection
|
|
* there is an iconwin, and win variable.
|
|
I have no clue why only win shouldn't
|
|
be enough. Will check it out later.
|
|
* The afterstep what seems the shift the
|
|
pixmap a bit. Don't know how and why.
|
|
It works in the WindowManager.
|
|
|
|
Things to do:
|
|
Split up main()
|
|
|
|
----
|
|
Thanks
|
|
----
|
|
|
|
Most of the ideas, and jumpstarting it:
|
|
|
|
#linuxnl, without this irc-channel wmppp would've never seen the light!
|
|
|
|
CCC (Constructive Code Criticism):
|
|
|
|
Marcelo E. Magallon
|
|
Thanks a LOT! It takes a while to get me convinced... :)
|
|
|
|
|
|
Minor bugs and ideas:
|
|
|
|
Marc De Scheemaecker / David Mihm / Chris Soghoian /
|
|
Alessandro Usseglio Viretta
|
|
|
|
and ofcourse numerous ppl who send us bug reports.
|
|
(numerous? hmm.. todo: rephrase this :) )
|
|
|
|
|
|
----
|
|
Changes:
|
|
---
|
|
02/29/2004 (Tom Marshall, tommy@home.tig-grr.com)
|
|
* Patch to add a special interface name "auto" for the -i
|
|
option. "wmifs -i auto" will automatically select the
|
|
first up interface.
|
|
01/08/2004 (Peter Samuelson, peter@samba-tng.org)
|
|
* Patch to make make sampling and scrolling intervals
|
|
customizable, adds new options -I and -s.
|
|
01/15/2002 (Matyas Koszik, koszik@debijan.lonyay.edu.hu)
|
|
* Patch that fixes segfaults on long interface names.
|
|
08/31/2001 (Davi Leal, davileal@terra.es)
|
|
* Patch that cuts long interface names, so they look
|
|
good in wmifs. For example, "dummy0" gets displayed
|
|
as "dumm0", "vmnet10" as "vmn10", etc.
|
|
06/16/2001 (Jorge García, Jorge.Garcia@uv.es)
|
|
* Added the LockMode, so wmifs doesn't swap to another
|
|
interface if the one requested with "-i" isn't up.
|
|
05/06/2001 (Jordi Mallach, jordi@sindominio.net)
|
|
* Integrated many patches, fixing issues with suspended
|
|
wmifs.
|
|
07/21/1999 (Stephen Pitts, smpitts@midsouth.rr.com)
|
|
* Added new constant: BUFFER_SIZE to determine the size
|
|
of the buffer used in fgets() operations. Right now,
|
|
its at 512 bytes. Fixed crashing on my system when
|
|
one line of /proc/net/dev was longer than 128 bytes
|
|
04/05/1998 (Martijn Pieterse, pieterse@xs4all.nl)
|
|
* Changed the "middle of the waveform" line color
|
|
* Moved the RedrawWindow out of the main loop.
|
|
Lightens the system load
|
|
02/05/1998 (Martijn Pieterse, pieterse@xs4all.nl)
|
|
* Torn wmppp and wmifs apart.
|
|
This is gonna be wmifs
|
|
* Added parse_rcfile
|
|
* Added waitpid, to get rid of the zombies, spotteb by Alessandro Usseglio Viretta
|
|
30/04/1998 (Martijn Pieterse, pieterse@xs4all.nl)
|
|
* Used the DrawStats routine from wmifs in wmppp
|
|
* I decided to add a list in this source file
|
|
with name of ppl who helped me build this code better.
|
|
* I finally removed the /proc/net/route dependency
|
|
All of the connections are taken from /proc/net/dev.
|
|
/proc/net/route is still used for checking if it is on-line.
|
|
27/04/1998 (Martijn Pieterse, pieterse@xs4all.nl)
|
|
* WMIFS: stats scrolled, while red led burning
|
|
* WMPPP: changed positions of line speed
|
|
25/04/1998 (Martijn Pieterse, pieterse@xs4all.nl)
|
|
* Changed the checknetdevs routine, a lot!
|
|
23/04/1998 (Martijn Pieterse, pieterse@xs4all.nl)
|
|
* Added line speed detection. via separate exec. (this has to be suid root!)
|
|
Speed has to be no more than 99999
|
|
* Added speed and forcespeed in ~/.wmppprc and /etc/wmppprc
|
|
* wmifs: added on-line detection scheme, update the bitmap coordinates
|
|
* wmppp: the x-button now allways disconnects.
|
|
22/04/1998 (Martijn Pieterse, pieterse@xs4all.nl)
|
|
* Added /etc/wmppprc support, including "forced" mode.
|
|
* Added /etc/wmifsrc support, including "forced" mode.
|
|
21/04/1998 (Martijn Pieterse, pieterse@xs4all.nl)
|
|
* Moved the stats one pixel down.
|
|
* Added status led in wmifs.
|
|
* Changed RX/TX leds of wmifs to resemble wmppp
|
|
* Added the "dot" between eth.0 ppp.0 etc.
|
|
* Changed to wmifs stats to match wmppp stats (only pppX changed)
|
|
* Made sure that when specified -t 1, it stayed that way, even
|
|
when longer than 100 minutes online
|
|
* With -t 1, jump from 59:59 to 01:00 instead of 99:59 to 01:40
|
|
16/04/1998 (Martijn Pieterse, pieterse@xs4all.nl)
|
|
* Added "all" devices in wmifs
|
|
* Added "lo" support only if aked via -i
|
|
* Added on-line time detection (using /var/run/ppp0.pid)
|
|
* Added time-out for the orange led. (one minute)
|
|
15/04/1998 (Martijn Pieterse, pieterse@xs4all.nl)
|
|
* Another wmppp-master.xpm.
|
|
Line speed detection being the main problem here.. :(
|
|
* Moved START_COMMAND / STOP_COMMAND to ~/.wmppprc
|
|
Return 0, everything went ok.
|
|
Return 10, the command did not work.
|
|
Please note, these functions are ran in the background.
|
|
* Removed the ability to configure
|
|
* When "v" is clicked, an orange led will appear.
|
|
if the connect script fails (return value == 10)
|
|
it will become dark again. Else the on-line detection will
|
|
pick it up, and "green" it.
|
|
14/04/1998 (Martijn Pieterse, pieterse@xs4all.nl)
|
|
* Added "-timer"
|
|
* Added "-display" support
|
|
* Changed pixmap to a no-name pixmap.
|
|
+ Changed LED positions
|
|
+ Changed Timer position
|
|
+ Changed Stats Size
|
|
05/04/1998 (Martijn Pieterse, pieterse@xs4all.nl)
|
|
* Added ~/.wmifsrc support.
|
|
* Put some code in DrawStats
|
|
* Check devices when pressing "device change"
|
|
03/04/1998 (Martijn Pieterse, pieterse@xs4all.nl)
|
|
* Added code for wmifs
|
|
28/03/1998 (Martijn Pieterse, pieterse@xs4all.nl)
|
|
* forgot what i did.. :)
|
|
27/03/1998 (Martijn Pieterse, pieterse@xs4all.nl)
|
|
* Added on-line detection
|
|
Scan through /proc/net/route and check everye line
|
|
for "ppp".
|
|
* A bit of code clean-up.
|
|
*/
|
|
|
|
#define _DEFAULT_SOURCE
|
|
#include <X11/X.h> /* for ButtonPress, ButtonRelease, etc */
|
|
#include <X11/Xlib.h> /* for XEvent, XButtonEvent, etc */
|
|
#include <X11/xpm.h> /* for XpmColorSymbol, Pixel, etc */
|
|
#include <ctype.h> /* for toupper */
|
|
#include <linux/ppp_defs.h> /* for ppp_stats, pppstat */
|
|
#include <net/if_ppp.h> /* for ifpppstatsreq, ifr__name, etc */
|
|
#include <stddef.h> /* for size_t */
|
|
#include <stdio.h> /* for fprintf, NULL, stderr, etc */
|
|
#include <stdlib.h> /* for exit, atof, atoi, getenv */
|
|
#include <string.h> /* for strcmp, strcpy, strlen, etc */
|
|
#include <sys/ioctl.h> /* for ioctl */
|
|
#include <sys/socket.h> /* for socket, AF_INET */
|
|
#include <sys/time.h> /* for timeval, gettimeofday */
|
|
#include <sys/wait.h> /* for waitpid, WNOHANG */
|
|
#include <time.h> /* for timespec, nanosleep */
|
|
#include <libdockapp/misc.h> /* for execCommand */
|
|
#include <libdockapp/wmgeneral.h> /* for copyXPMArea, display, etc */
|
|
#include "wmifs-mask.xbm" /* for wmifs_mask_bits, etc */
|
|
#include "wmifs-master.xpm" /* for wmifs_master_xpm */
|
|
|
|
/* How often to check for new network interface, in ms */
|
|
#define CHECK_INTERFACE_INTERVAL 5000
|
|
|
|
/* How often to query the interfaces, in ms */
|
|
#define DEFAULT_SAMPLE_INTERVAL 50
|
|
|
|
/***********/
|
|
/* Defines */
|
|
/***********/
|
|
|
|
#ifndef ifr__name
|
|
#define ifr__name ifr_name
|
|
#endif
|
|
|
|
#ifndef stats_ptr
|
|
#define stats_ptr stats.p.FIXME
|
|
#endif
|
|
|
|
/* Fill in and uncomment the hardcoded actions */
|
|
/* #define LEFT_ACTION (NULL) */
|
|
/* #define MIDDLE_ACTION (NULL) */
|
|
/* #define RIGHT_ACTION (NULL) */
|
|
|
|
/* Defines voor alle coordinate */
|
|
|
|
#define LED_NET_RX (4)
|
|
#define LED_NET_TX (5)
|
|
#define LED_NET_POWER (6)
|
|
|
|
/* the size of the buffer read from /proc/net/ */
|
|
#define BUFFER_SIZE 512
|
|
|
|
/**********************/
|
|
/* External Variables */
|
|
/**********************/
|
|
|
|
extern char **environ;
|
|
|
|
/********************/
|
|
/* Global Variables */
|
|
/********************/
|
|
|
|
char *active_interface = NULL;
|
|
int TimerDivisor = 60;
|
|
int WaveForm = 0;
|
|
int LockMode = 0;
|
|
int SampleInt = DEFAULT_SAMPLE_INTERVAL;
|
|
int ScrollSpeed = CHECK_INTERFACE_INTERVAL;
|
|
XpmIcon wmgen;
|
|
char color[256];
|
|
|
|
/*****************/
|
|
/* PPP variables */
|
|
/*****************/
|
|
|
|
#define PPP_UNIT 0
|
|
int ppp_h = -1;
|
|
|
|
#define PPP_STATS_HIS 54
|
|
|
|
/***********************/
|
|
/* Function Prototypes */
|
|
/***********************/
|
|
|
|
void usage(void);
|
|
void printversion(void);
|
|
void DrawTime(int, int);
|
|
void DrawStats(int *, int, int, int, int);
|
|
|
|
void SetOnLED(int);
|
|
void SetErrLED(int);
|
|
void SetWaitLED(int);
|
|
void SetOffLED(int);
|
|
|
|
void ButtonUp(int);
|
|
void ButtonDown(int);
|
|
|
|
void wmifs_routine(int, char **);
|
|
|
|
void get_ppp_stats(struct ppp_stats *cur);
|
|
|
|
|
|
/********/
|
|
/* Main */
|
|
/********/
|
|
|
|
int main(int argc, char *argv[])
|
|
{
|
|
|
|
int i;
|
|
|
|
color[0] = 0;
|
|
|
|
/* Parse Command Line */
|
|
|
|
for (i = 1; i < argc; i++) {
|
|
char *arg = argv[i];
|
|
|
|
if (*arg == '-') {
|
|
switch (arg[1]) {
|
|
case 'c' :
|
|
if (argc > i+1) {
|
|
strncpy(color, argv[i+1], sizeof(color));
|
|
i++;
|
|
}
|
|
break;
|
|
case 'd':
|
|
if (strcmp(arg+1, "display")) {
|
|
usage();
|
|
exit(1);
|
|
}
|
|
break;
|
|
case 'g':
|
|
if (strcmp(arg+1, "geometry")) {
|
|
usage();
|
|
exit(1);
|
|
}
|
|
break;
|
|
case 'i':
|
|
active_interface = argv[i+1];
|
|
i++;
|
|
break;
|
|
case 'I':
|
|
SampleInt = atof(argv[i+1]) * 1000;
|
|
i++;
|
|
break;
|
|
case 'l':
|
|
LockMode = 1;
|
|
break;
|
|
case 's':
|
|
ScrollSpeed = atof(argv[i+1]) * 1000;
|
|
i++;
|
|
break;
|
|
case 'v':
|
|
printversion();
|
|
exit(0);
|
|
break;
|
|
case 'w':
|
|
WaveForm = 1;
|
|
break;
|
|
default:
|
|
if (strcmp(argv[i-1], "-geometry")) {
|
|
usage();
|
|
exit(0);
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
wmifs_routine(argc, argv);
|
|
return 0;
|
|
}
|
|
|
|
Pixel scale_pixel(Pixel pixel, float scale)
|
|
{
|
|
int red, green, blue;
|
|
|
|
red = pixel / ( 1 << 16 );
|
|
green = pixel % (1 << 16) / (1 << 8);
|
|
blue = pixel % (1 << 8);
|
|
|
|
red *= scale;
|
|
green *= scale;
|
|
blue *= scale;
|
|
|
|
return red * (1 << 16) + green * (1 << 8) + blue;
|
|
}
|
|
|
|
/*******************************************************************************\
|
|
|* wmifs_routine *|
|
|
\*******************************************************************************/
|
|
|
|
#define MAX_STAT_DEVICES 16
|
|
|
|
typedef struct {
|
|
|
|
char name[IFNAMSIZ];
|
|
int his[55][2];
|
|
long istatlast;
|
|
long ostatlast;
|
|
|
|
} stat_dev;
|
|
|
|
stat_dev stat_devices[MAX_STAT_DEVICES];
|
|
|
|
char *left_action = NULL;
|
|
char *right_action = NULL;
|
|
char *middle_action = NULL;
|
|
|
|
int checknetdevs(void);
|
|
int get_statistics(char *, long *, long *, long *, long *);
|
|
int stillonline(char *);
|
|
void DrawActiveIFS(char *);
|
|
|
|
void wmifs_routine(int argc, char **argv)
|
|
{
|
|
|
|
rckeys wmifs_keys[] = {
|
|
{ "left", &left_action },
|
|
{ "middle", &middle_action },
|
|
{ "right", &right_action },
|
|
{ NULL, NULL }
|
|
};
|
|
|
|
|
|
int i, j;
|
|
XEvent Event;
|
|
int but_stat = -1;
|
|
|
|
int stat_online;
|
|
int stat_current;
|
|
int first_time = 1;
|
|
|
|
unsigned int curtime;
|
|
unsigned int nexttime;
|
|
struct timeval tv, tv2;
|
|
|
|
long ipacket, opacket, istat, ostat;
|
|
|
|
char temp[BUFFER_SIZE];
|
|
char *p;
|
|
|
|
for (i = 0; i < MAX_STAT_DEVICES; i++) {
|
|
stat_devices[i].name[0] = 0;
|
|
for (j = 0; j < 48; j++) {
|
|
stat_devices[i].his[j][0] = 0;
|
|
stat_devices[i].his[j][1] = 0;
|
|
}
|
|
}
|
|
|
|
stat_online = checknetdevs();
|
|
|
|
stat_current = 0;
|
|
if (active_interface) {
|
|
int isauto = !strcmp(active_interface, "auto");
|
|
for (i = 0; i < stat_online; i++) {
|
|
if ((isauto && stillonline(stat_devices[i].name)) ||
|
|
!strcmp(stat_devices[i].name, active_interface)) {
|
|
stat_current = i;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
#ifdef LEFT_ACTION
|
|
left_action = strdup(LEFT_ACTION);
|
|
#endif
|
|
#ifdef MIDDLE_ACTION
|
|
middle_action = strdup(MIDDLE_ACTION);
|
|
#endif
|
|
#ifdef RIGHT_ACTION
|
|
right_action = strdup(RIGHT_ACTION);
|
|
#endif
|
|
|
|
/* Scan throught the .rc files */
|
|
parse_rcfile(CONF"/wmifsrc", wmifs_keys);
|
|
|
|
p = getenv("HOME");
|
|
if (p == NULL || *p == 0) {
|
|
fprintf(stderr, "Unknown $HOME directory, please check your environment\n");
|
|
return;
|
|
}
|
|
strncpy(temp, p, BUFFER_SIZE - 10);
|
|
strcat(temp, "/.wmifsrc");
|
|
parse_rcfile(temp, wmifs_keys);
|
|
|
|
parse_rcfile(CONF"/wmifsrc.fixed", wmifs_keys);
|
|
|
|
/* set user-defined colors */
|
|
if (color[0] != 0) {
|
|
Window Root;
|
|
XColor col;
|
|
XWindowAttributes attributes;
|
|
int screen;
|
|
Pixel pixel;
|
|
#define NUMSYMBOLS 4
|
|
XpmColorSymbol user_color[NUMSYMBOLS] = {
|
|
{NULL, "#2081B2CAAEBA", 0}, /* + */
|
|
{NULL, "#28A23CF338E3", 0}, /* O */
|
|
{NULL, "#000049244103", 0}, /* @ */
|
|
{NULL, "#18618A288617", 0}, /* # */
|
|
};
|
|
|
|
|
|
/* code based on GetColor() from wmgeneral.c */
|
|
/* we need a temporary display to parse the color */
|
|
display = XOpenDisplay(NULL);
|
|
screen = DefaultScreen(display);
|
|
Root = RootWindow(display, screen);
|
|
XGetWindowAttributes(display, Root, &attributes);
|
|
|
|
col.pixel = 0;
|
|
if (!XParseColor(display, attributes.colormap, color, &col)) {
|
|
fprintf(stderr, "wmtime: can't parse %s.\n", color);
|
|
goto draw_window;
|
|
} else if (!XAllocColor(display, attributes.colormap, &col)) {
|
|
fprintf(stderr, "wmtime: can't allocate %s.\n", color);
|
|
goto draw_window;
|
|
}
|
|
|
|
pixel = col.pixel;
|
|
|
|
/* replace colors from wmtime-master.xpm */
|
|
user_color[0].pixel = pixel;
|
|
user_color[1].pixel = scale_pixel(pixel, .3);
|
|
user_color[2].pixel = scale_pixel(pixel, .4);
|
|
user_color[3].pixel = scale_pixel(pixel, .8);
|
|
|
|
wmgen.attributes.valuemask |= XpmColorSymbols;
|
|
wmgen.attributes.numsymbols = NUMSYMBOLS;
|
|
wmgen.attributes.colorsymbols = user_color;
|
|
|
|
XCloseDisplay(display);
|
|
}
|
|
|
|
draw_window:
|
|
openXwindow(argc, argv, wmifs_master_xpm, (char*)wmifs_mask_bits, wmifs_mask_width, wmifs_mask_height);
|
|
|
|
/* > Button */
|
|
AddMouseRegion(0, 5, 5, 35, 15);
|
|
AddMouseRegion(1, 5, 20, 58, 58);
|
|
|
|
gettimeofday(&tv2, NULL);
|
|
nexttime = ScrollSpeed;
|
|
|
|
DrawActiveIFS(stat_devices[stat_current].name);
|
|
|
|
while (1) {
|
|
struct timespec ts;
|
|
|
|
gettimeofday(&tv, NULL);
|
|
curtime = (tv.tv_sec - tv2.tv_sec) * 1000
|
|
+ (tv.tv_usec - tv2.tv_usec) / 1000;
|
|
|
|
waitpid(0, NULL, WNOHANG);
|
|
|
|
for (i = 0; i < stat_online; i++) {
|
|
get_statistics(stat_devices[i].name, &ipacket, &opacket, &istat, &ostat);
|
|
|
|
if (first_time) {
|
|
first_time = 0;
|
|
} else {
|
|
stat_devices[i].his[53][0] += istat - stat_devices[i].istatlast;
|
|
stat_devices[i].his[53][1] += ostat - stat_devices[i].ostatlast;
|
|
}
|
|
|
|
if (i == stat_current) {
|
|
if (!stillonline(stat_devices[i].name))
|
|
SetErrLED(LED_NET_POWER);
|
|
else
|
|
SetOnLED(LED_NET_POWER);
|
|
|
|
if (stat_devices[i].istatlast == istat)
|
|
SetOffLED(LED_NET_RX);
|
|
else
|
|
SetOnLED(LED_NET_RX);
|
|
|
|
if (stat_devices[i].ostatlast == ostat)
|
|
SetOffLED(LED_NET_TX);
|
|
else
|
|
SetOnLED(LED_NET_TX);
|
|
}
|
|
|
|
stat_devices[i].istatlast = istat;
|
|
stat_devices[i].ostatlast = ostat;
|
|
}
|
|
RedrawWindow();
|
|
|
|
if (curtime >= nexttime) {
|
|
nexttime = curtime + ScrollSpeed;
|
|
|
|
DrawStats(&stat_devices[stat_current].his[0][0], 54, 40, 5, 58);
|
|
for (i = 0; i < stat_online; i++) {
|
|
if (stillonline(stat_devices[i].name)) {
|
|
for (j = 1; j < 54; j++) {
|
|
stat_devices[i].his[j-1][0] = stat_devices[i].his[j][0];
|
|
stat_devices[i].his[j-1][1] = stat_devices[i].his[j][1];
|
|
}
|
|
stat_devices[i].his[53][0] = 0;
|
|
stat_devices[i].his[53][1] = 0;
|
|
}
|
|
}
|
|
RedrawWindow();
|
|
}
|
|
|
|
while (XPending(display)) {
|
|
XNextEvent(display, &Event);
|
|
switch (Event.type) {
|
|
case Expose:
|
|
RedrawWindow();
|
|
break;
|
|
case DestroyNotify:
|
|
XCloseDisplay(display);
|
|
exit(0);
|
|
break;
|
|
case ButtonPress:
|
|
but_stat = CheckMouseRegion(Event.xbutton.x, Event.xbutton.y);
|
|
break;
|
|
case ButtonRelease:
|
|
i = CheckMouseRegion(Event.xbutton.x, Event.xbutton.y);
|
|
|
|
if (but_stat == i && but_stat >= 0) {
|
|
switch (but_stat) {
|
|
case 0:
|
|
/* re-read the table */
|
|
strcpy(temp, stat_devices[stat_current].name);
|
|
stat_online = checknetdevs();
|
|
stat_current = 0;
|
|
for (i = 0; i < stat_online; i++) {
|
|
if (!strcmp(temp, stat_devices[i].name))
|
|
stat_current = i;
|
|
}
|
|
|
|
stat_current++;
|
|
if (stat_current == stat_online)
|
|
stat_current = 0;
|
|
|
|
DrawActiveIFS(stat_devices[stat_current].name);
|
|
|
|
DrawStats(&stat_devices[stat_current].his[0][0], 54, 40, 5, 58);
|
|
break;
|
|
case 1:
|
|
switch (Event.xbutton.button) {
|
|
case 1:
|
|
if (left_action)
|
|
execCommand(left_action);
|
|
break;
|
|
case 2:
|
|
if (middle_action)
|
|
execCommand(middle_action);
|
|
break;
|
|
case 3:
|
|
if (right_action)
|
|
execCommand(right_action);
|
|
break;
|
|
}
|
|
break;
|
|
|
|
}
|
|
}
|
|
but_stat = -1;
|
|
RedrawWindow();
|
|
break;
|
|
}
|
|
}
|
|
ts.tv_sec = 0;
|
|
ts.tv_nsec = SampleInt * 1000000;
|
|
nanosleep(&ts, NULL);
|
|
}
|
|
}
|
|
|
|
/*******************************************************************************\
|
|
|* void DrawActiveIFS(char *) *|
|
|
\*******************************************************************************/
|
|
|
|
void DrawActiveIFS(char *real_name)
|
|
{
|
|
|
|
/* Cijfers op: 0,65
|
|
Letters op: 0,75
|
|
Alles 9 hoog, 6 breedt
|
|
|
|
Destinatie: 5,5
|
|
*/
|
|
|
|
size_t i;
|
|
int k;
|
|
size_t len;
|
|
char name[256];
|
|
|
|
|
|
copyXPMArea(5, 84, 30, 10, 5, 5);
|
|
|
|
|
|
strcpy(name, real_name);
|
|
len = strlen(name);
|
|
if (len > 5) {
|
|
for (i = len-5; i < len && !(name[i] >= '0' && name[i] <= '9'); i++)
|
|
;
|
|
for (; i <= len; i++) /* '=' to get the '\0' character moved too \*/
|
|
name[i-(len-5)] = name[i];
|
|
}
|
|
|
|
k = 5;
|
|
for (i = 0; name[i]; i++) {
|
|
int c;
|
|
|
|
if (i == strlen(name)-1 && strlen(name) <= 4 && name[strlen(name)-1] >= '0' &&
|
|
name[strlen(name)-1] <= '9') {
|
|
copyXPMArea(61, 64, 4, 9, k, 5);
|
|
k += 4;
|
|
}
|
|
c = toupper(name[i]);
|
|
if (c >= 'A' && c <= 'Z') {
|
|
c -= 'A';
|
|
copyXPMArea(c * 6, 74, 6, 9, k, 5);
|
|
k += 6;
|
|
} else {
|
|
c -= '0';
|
|
copyXPMArea(c * 6, 64, 6, 9, k, 5);
|
|
k += 6;
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
/*******************************************************************************\
|
|
|* get_statistics *|
|
|
\*******************************************************************************/
|
|
|
|
int get_statistics(char *devname, long *ip, long *op, long *is, long *os)
|
|
{
|
|
|
|
FILE *fp;
|
|
char temp[BUFFER_SIZE];
|
|
char *p, *saveptr;
|
|
char *tokens = " |:\n";
|
|
int input, output;
|
|
int i;
|
|
int found;
|
|
struct ppp_stats ppp_cur;
|
|
|
|
|
|
if (!strncmp(devname, "ppp", 3)) {
|
|
static int ppp_opened;
|
|
|
|
if (!ppp_opened) {
|
|
/* Open the ppp device. */
|
|
memset(&ppp_cur, 0, sizeof(ppp_cur));
|
|
ppp_h = socket(AF_INET, SOCK_DGRAM, 0);
|
|
if (ppp_h < 0)
|
|
return -1;
|
|
get_ppp_stats(&ppp_cur);
|
|
ppp_opened = 1;
|
|
}
|
|
|
|
get_ppp_stats(&ppp_cur);
|
|
|
|
*op = ppp_cur.p.ppp_opackets;
|
|
*ip = ppp_cur.p.ppp_ipackets;
|
|
|
|
*is = ppp_cur.p.ppp_ibytes;
|
|
*os = ppp_cur.p.ppp_obytes;
|
|
|
|
return 0;
|
|
}
|
|
|
|
/* Read from /proc/net/dev the stats! */
|
|
fp = fopen("/proc/net/dev", "r");
|
|
if (!fp)
|
|
return -1;
|
|
if (!fgets(temp, BUFFER_SIZE, fp)) {
|
|
fclose(fp);
|
|
return -1;
|
|
}
|
|
if (!fgets(temp, BUFFER_SIZE, fp)) {
|
|
fclose(fp);
|
|
return -1;
|
|
}
|
|
|
|
input = -1;
|
|
output = -1;
|
|
i = 0;
|
|
found = -1;
|
|
|
|
p = strtok_r(temp, tokens, &saveptr);
|
|
do {
|
|
if (!(strcmp(p, "packets"))) {
|
|
if (input == -1)
|
|
input = i;
|
|
else
|
|
output = i;
|
|
}
|
|
i++;
|
|
p = strtok_r(NULL, tokens, &saveptr);
|
|
} while (input == -1 || output == -1);
|
|
|
|
while (fgets(temp, BUFFER_SIZE, fp)) {
|
|
if (strstr(temp, devname)) {
|
|
found = 0;
|
|
p = strtok_r(temp, tokens, &saveptr);
|
|
i = 0;
|
|
do {
|
|
if (i == input) {
|
|
*ip = *is = atoi(p);
|
|
input = -1;
|
|
}
|
|
if (i == output) {
|
|
*op = *os = atoi(p);
|
|
output = -1;
|
|
}
|
|
i++;
|
|
p = strtok_r(NULL, tokens, &saveptr);
|
|
} while (input != -1 || output != -1);
|
|
}
|
|
}
|
|
fclose(fp);
|
|
|
|
return found;
|
|
}
|
|
|
|
/*******************************************************************************\
|
|
|* stillonline *|
|
|
\*******************************************************************************/
|
|
|
|
int stillonline(char *ifs)
|
|
{
|
|
|
|
FILE *fp;
|
|
int i;
|
|
|
|
i = 0;
|
|
fp = fopen("/proc/net/route", "r");
|
|
if (fp) {
|
|
char temp[BUFFER_SIZE];
|
|
|
|
while (fgets(temp, BUFFER_SIZE, fp)) {
|
|
if (strstr(temp, ifs)) {
|
|
i = 1; /* Line is alive */
|
|
break;
|
|
}
|
|
}
|
|
fclose(fp);
|
|
}
|
|
return i;
|
|
}
|
|
|
|
/*******************************************************************************\
|
|
|* checknetdevs *|
|
|
\*******************************************************************************/
|
|
|
|
int checknetdevs(void)
|
|
{
|
|
|
|
FILE *fd;
|
|
int i = 0, j;
|
|
int k;
|
|
int devsfound = 0;
|
|
char foundbuffer[MAX_STAT_DEVICES][IFNAMSIZ];
|
|
|
|
for (i = 0; i < MAX_STAT_DEVICES; i++)
|
|
foundbuffer[i][0] = 0;
|
|
|
|
/* foundbuffer vullen met info uit /proc/net/dev */
|
|
|
|
fd = fopen("/proc/net/dev", "r");
|
|
if (fd) {
|
|
char temp[BUFFER_SIZE];
|
|
|
|
/* Skip the first 2 lines */
|
|
if (!fgets(temp, BUFFER_SIZE, fd)) {
|
|
fclose(fd);
|
|
return -1;
|
|
}
|
|
if (!fgets(temp, BUFFER_SIZE, fd)) {
|
|
fclose(fd);
|
|
return -1;
|
|
}
|
|
while (fgets(temp, BUFFER_SIZE, fd)) {
|
|
char *p, *saveptr;
|
|
char *tokens = " :\t\n";
|
|
|
|
p = strtok_r(temp, tokens, &saveptr);
|
|
if (p == NULL) {
|
|
printf("Barfed on: %s", temp);
|
|
break;
|
|
}
|
|
/* Skip dummy code */
|
|
|
|
if (!strncmp(p, "dummy", 5))
|
|
continue;
|
|
|
|
/* If p == "lo", and active_interface (as given on the cmd line) != "lo",
|
|
skip it! */
|
|
|
|
if (strcmp(p, "lo") || (active_interface && !strcmp(active_interface, "lo"))) {
|
|
strncpy(foundbuffer[devsfound], p, IFNAMSIZ);
|
|
devsfound++;
|
|
}
|
|
if (devsfound >= MAX_STAT_DEVICES)
|
|
break;
|
|
}
|
|
fclose(fd);
|
|
}
|
|
|
|
/* Nu foundbuffer naar stat_devices[].name kopieeren */
|
|
|
|
for (i = 0; i < MAX_STAT_DEVICES; i++) {
|
|
/* Loop stat_devices na, als die naam niet voorkomt in foundbuffer, kill! */
|
|
|
|
if (stat_devices[i].name[0]) {
|
|
k = 0;
|
|
for (j = 0; j < MAX_STAT_DEVICES; j++) {
|
|
if (!strcmp(stat_devices[i].name, foundbuffer[j])) {
|
|
k = 1;
|
|
foundbuffer[j][0] = 0;
|
|
}
|
|
}
|
|
if (!k)
|
|
stat_devices[i].name[0] = 0;
|
|
}
|
|
}
|
|
|
|
for (i = 0, j = 0; j < MAX_STAT_DEVICES; i++, j++) {
|
|
|
|
while (!stat_devices[j].name[0] && j < MAX_STAT_DEVICES)
|
|
j++;
|
|
|
|
if (j < MAX_STAT_DEVICES && i != j)
|
|
stat_devices[i] = stat_devices[j];
|
|
}
|
|
i--;
|
|
|
|
for (j = 0; j < MAX_STAT_DEVICES; j++) {
|
|
if (foundbuffer[j][0]) {
|
|
|
|
strncpy(stat_devices[i].name, foundbuffer[j], IFNAMSIZ);
|
|
|
|
for (k = 0; k < 48; k++) {
|
|
stat_devices[i].his[k][0] = 0;
|
|
stat_devices[i].his[k][1] = 0;
|
|
}
|
|
|
|
i++;
|
|
}
|
|
}
|
|
if (LockMode && active_interface != NULL) {
|
|
k = 0;
|
|
for (j = 0; j < i; j++)
|
|
if (!strcmp(stat_devices[j].name, active_interface)) {
|
|
k = 1;
|
|
break;
|
|
}
|
|
if (!k) {
|
|
strncpy(stat_devices[i].name, active_interface, IFNAMSIZ);
|
|
for (k = 0; k < 48; k++) {
|
|
stat_devices[i].his[k][0] = 0;
|
|
stat_devices[i].his[k][1] = 0;
|
|
}
|
|
devsfound++;
|
|
}
|
|
|
|
}
|
|
return devsfound;
|
|
}
|
|
|
|
/*******************************************************************************\
|
|
|* DrawStats *|
|
|
\*******************************************************************************/
|
|
|
|
void DrawStats(int *his, int num, int size, int x_left, int y_bottom)
|
|
{
|
|
|
|
int pixels_per_byte;
|
|
int j, k;
|
|
int *p;
|
|
int p2, p3;
|
|
|
|
pixels_per_byte = size;
|
|
p = his;
|
|
for (j = 0; j < num; j++) {
|
|
if (p[0] + p[1] > pixels_per_byte)
|
|
pixels_per_byte = p[0] + p[1];
|
|
p += 2;
|
|
}
|
|
|
|
pixels_per_byte /= size;
|
|
p = his;
|
|
|
|
for (k = 0; k < num; k++) {
|
|
int p0, p1;
|
|
|
|
p0 = p[0];
|
|
p1 = p[1];
|
|
|
|
|
|
if (WaveForm) {
|
|
p2 = 0;
|
|
p3 = 1;
|
|
for (j = 0; j < size; j++) {
|
|
if (j < p0 / pixels_per_byte)
|
|
copyXPMArea(100+2, 68, 1, 1, k+x_left, y_bottom-size/2+p2/2);
|
|
else if (j < (p0 + p1) / pixels_per_byte)
|
|
copyXPMArea(100+1, 68, 1, 1, k+x_left, y_bottom-size/2+p2/2);
|
|
else
|
|
copyXPMArea(100+0, 68, 1, 1, k+x_left, y_bottom-size/2+p2/2);
|
|
|
|
p2 = (p2 + p3);
|
|
p3 *= -1;
|
|
p2 *= -1;
|
|
}
|
|
copyXPMArea(100+3, 68, 1, 1, k+x_left, y_bottom-size/2);
|
|
} else {
|
|
for (j = 0; j < size; j++) {
|
|
if (j < p0 / pixels_per_byte)
|
|
copyXPMArea(100+2, 68, 1, 1, k+x_left, y_bottom-j);
|
|
else if (j < (p0 + p1) / pixels_per_byte)
|
|
copyXPMArea(100+1, 68, 1, 1, k+x_left, y_bottom-j);
|
|
else
|
|
copyXPMArea(100+0, 68, 1, 1, k+x_left, y_bottom-j);
|
|
}
|
|
}
|
|
p += 2;
|
|
}
|
|
}
|
|
|
|
/*******************************************************************************\
|
|
|* usage *|
|
|
\*******************************************************************************/
|
|
|
|
void usage(void)
|
|
{
|
|
|
|
fprintf(stderr, "\nwmifs - programming: tijno, (de)bugging & design: warpstah, webhosting: bobby\n\n");
|
|
fprintf(stderr, "usage:\n");
|
|
fprintf(stderr, "\t-c <color>\t\tset color\n");
|
|
fprintf(stderr, "\t-display <display name>\tset display\n");
|
|
fprintf(stderr, "\t-geometry +x+y\t\tset window position\n");
|
|
fprintf(stderr, "\t-h\t\t\tthis help screen\n");
|
|
fprintf(stderr, "\t-i <interface name>\tdefault (as it appears in /proc/net/route)\n");
|
|
fprintf(stderr, "\t-I <interval>\t\tsampling interval, in seconds (default: 0.05)\n");
|
|
fprintf(stderr, "\t-l\t\t\tstarts in lock mode\n");
|
|
fprintf(stderr, "\t-s <interval>\t\tscrolling interval, in seconds (default: 5)\n");
|
|
fprintf(stderr, "\t-v\t\t\tprint the version number\n");
|
|
fprintf(stderr, "\t-w\t\t\twaveform load\n");
|
|
fprintf(stderr, "\n");
|
|
}
|
|
|
|
/*******************************************************************************\
|
|
|* printversion *|
|
|
\*******************************************************************************/
|
|
|
|
void printversion(void)
|
|
{
|
|
|
|
fprintf(stderr, "%s\n", PACKAGE_STRING);
|
|
}
|
|
|
|
/*******************************************************************************\
|
|
|* get_ppp_stats *|
|
|
\*******************************************************************************/
|
|
|
|
void get_ppp_stats(struct ppp_stats *cur)
|
|
{
|
|
|
|
struct ifpppstatsreq req;
|
|
|
|
memset(&req, 0, sizeof(req));
|
|
|
|
req.stats_ptr = (void *) &req.stats;
|
|
|
|
sprintf(req.ifr__name, "ppp%d", PPP_UNIT);
|
|
|
|
if (ioctl(ppp_h, SIOCGPPPSTATS, &req) < 0) {
|
|
/* fprintf(stderr, "heyho!\n") */;
|
|
}
|
|
*cur = req.stats;
|
|
}
|
|
|
|
#define LED_SZE_X (4)
|
|
#define LED_SZE_Y (4)
|
|
|
|
#define LED_ON_NET_X (87)
|
|
#define LED_ON_NET_Y (66)
|
|
#define LED_OFF_NET_X (93)
|
|
#define LED_OFF_NET_Y (66)
|
|
#define LED_ERR_NET_X (81)
|
|
#define LED_ERR_NET_Y (66)
|
|
#define LED_ON_SW_NET_X (49)
|
|
#define LED_ON_SW_NET_Y (85)
|
|
#define LED_OFF_SW_NET_X (44)
|
|
#define LED_OFF_SW_NET_Y (85)
|
|
|
|
#define LED_PWR_X (53)
|
|
#define LED_PWR_Y (7)
|
|
#define LED_SND_X (47)
|
|
#define LED_SND_Y (7)
|
|
#define LED_RCV_X (41)
|
|
#define LED_RCV_Y (7)
|
|
|
|
#define LED_SW_X (38)
|
|
#define LED_SW_Y (14)
|
|
|
|
/*******************************************************************************\
|
|
|* SetOnLED *|
|
|
\*******************************************************************************/
|
|
void SetOnLED(int led)
|
|
{
|
|
|
|
switch (led) {
|
|
|
|
case LED_NET_RX:
|
|
copyXPMArea(LED_ON_NET_X, LED_ON_NET_Y, LED_SZE_X, LED_SZE_Y, LED_RCV_X, LED_RCV_Y);
|
|
break;
|
|
case LED_NET_TX:
|
|
copyXPMArea(LED_ON_NET_X, LED_ON_NET_Y, LED_SZE_X, LED_SZE_Y, LED_SND_X, LED_SND_Y);
|
|
break;
|
|
case LED_NET_POWER:
|
|
copyXPMArea(LED_ON_NET_X, LED_ON_NET_Y, LED_SZE_X, LED_SZE_Y, LED_PWR_X, LED_PWR_Y);
|
|
break;
|
|
}
|
|
}
|
|
|
|
/*******************************************************************************\
|
|
|* SetOffLED *|
|
|
\*******************************************************************************/
|
|
void SetOffLED(int led)
|
|
{
|
|
|
|
switch (led) {
|
|
|
|
case LED_NET_RX:
|
|
copyXPMArea(LED_OFF_NET_X, LED_OFF_NET_Y, LED_SZE_X, LED_SZE_Y, LED_RCV_X, LED_RCV_Y);
|
|
break;
|
|
case LED_NET_TX:
|
|
copyXPMArea(LED_OFF_NET_X, LED_OFF_NET_Y, LED_SZE_X, LED_SZE_Y, LED_SND_X, LED_SND_Y);
|
|
break;
|
|
case LED_NET_POWER:
|
|
copyXPMArea(LED_OFF_NET_X, LED_OFF_NET_Y, LED_SZE_X, LED_SZE_Y, LED_PWR_X, LED_PWR_Y);
|
|
break;
|
|
}
|
|
}
|
|
|
|
/*******************************************************************************\
|
|
|* SetErrLED *|
|
|
\*******************************************************************************/
|
|
void SetErrLED(int led)
|
|
{
|
|
|
|
switch (led) {
|
|
case LED_NET_POWER:
|
|
copyXPMArea(LED_ERR_NET_X, LED_ERR_NET_Y, LED_SZE_X, LED_SZE_Y, LED_PWR_X, LED_PWR_Y);
|
|
break;
|
|
}
|
|
}
|