/*==============================================================================
M A I N . C
This is the main module for the 'wmnet' project.This code was
originally based on the 'wmifs' project done by Martijn Pieterse
(pieterse @ xs4all.nl).I was going to originally port his code, but
since most of the guts was Linux - specific, I really only ended up
using the X windows code.
main.c,v 1.15 1999/01/30 05:32:23 rneswold Exp
==============================================================================*/
#include <stdlib.h>
#include <stdio.h>
#include <ctype.h>
#include <string.h>
#include <unistd.h>
#include <X11/Xlib.h>
#include <X11/xpm.h>
#include "wmnet.h"
#include "wmgeneral.h"
#include "wmnet-master.xpm"
#include "wmnet-mask.xbm"
#define LED_NET_1 (1)
#define LED_NET_2 (2)
#define LED_NET_3 (3)
#define LED_SZE_X (4)
#define LED_SZE_Y (4)
#define LED_ON_NET_X (87)
#define LED_ON_NET_Y (92)
#define LED_OFF_NET_X (93)
#define LED_OFF_NET_Y (92)
#define LED_ERR_NET_X (81)
#define LED_ERR_NET_Y (92)
#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)
/* Function prototypes... */
static void DrawActiveIFS(char const *);
static void DrawStats(unsigned, int, int, int);
static unsigned findInterface(char const*);
static void printversion(void);
static char const *rateToStr(unsigned long);
static double getRate(unsigned long, char *);
static void SetErrLED(int);
static void SetOffLED(int);
static void SetOnLED(int);
static void usage(void);
static void wmnet_routine(int, char **);
/* Local variables... */
static char* active_interface = NULL;
static int delay = 1;
/*------------------------------------------------------------------------------
DrawActiveIFS
------------------------------------------------------------------------------*/
static void DrawActiveIFS(char const* name)
{
copyXPMArea(5, 110, 30, 10, 5, 5);
if (name) {
int ii, kk = 5;
for (ii = 0; name[ii]; ++ii) {
int const ch = toupper(name[ii]);
if (ch >= 'A' && ch <= 'Z')
copyXPMArea((ch - 'A') * 6, 100, 6, 9, kk, 5);
else
copyXPMArea((ch - '0') * 6, 90, 6, 9, kk, 5);
kk += 6;
}
}
}
/*------------------------------------------------------------------------------
DrawStats
------------------------------------------------------------------------------*/
static void DrawStats(unsigned ifCurr, int height, int x_left, int y_bottom)
{
unsigned baseLine = y_bottom - height / 2;
unsigned maxVal = 0, ii, currVal = 0;
char const* ptr = 0;
/* Find the maximum value. We'll scale the graph to this value. */
unsigned long rcv, xmt;
for (ii = 0; ii < G_WIDTH; ++ii) {
ifGetData(ifCurr, ii, &xmt, &rcv);
xmt /= delay;
rcv /= delay;
currVal = xmt > rcv ? xmt : rcv ;
if (currVal > maxVal)
maxVal = currVal;
}
/* Now draw the data points. */
for (ii = 0; ii < G_WIDTH; ++ii) {
unsigned long rcv, xmt;
unsigned long start = baseLine, stop = baseLine;
int jj;
if (maxVal > 0) {
ifGetData(ifCurr, ii, &xmt, &rcv);
xmt /= delay;
rcv /= delay;
start = baseLine + (xmt * height) / (2 * maxVal);
stop = baseLine - (rcv * height) / (2 * maxVal);
}
for (jj = 0; jj < height; ++jj)
if (y_bottom - jj <= start && y_bottom - jj >= stop)
copyXPMArea(99 + 1, 106, 1, 1, ii + x_left, y_bottom - jj);
else
copyXPMArea(99, 106, 1, 1, ii + x_left, y_bottom - jj);
/* Draw the base line. */
copyXPMArea(100, 106, 1, 1, ii + x_left, baseLine);
}
/* Now draw the download data rate... */
/* Clear area */
copyXPMArea( 6, 111, 54 , 9 , 6, 63);
ptr = rateToStr(rcv);
copyXPMArea(('D' - 'A') * 6, 100, 6, 9, 6,
62);
copyXPMArea(64, 90, 4, 9, 12,
62);
for (ii = 20; *ptr; ++ptr)
if (isdigit(*ptr)) {
copyXPMArea((*ptr - '0') * 6, 90, 6, 9, 1 + ii, 62 );
ii += 6;
} else if ('.' == *ptr) {
copyXPMArea(60, 90, 4, 9, 1 + ii, 62);
ii += 4;
} else {
copyXPMArea((toupper(*ptr) - 'A') * 6, 100, 6, 9, 1 + ii,
62);
ii += 6;
}
/* Now draw the upload data rate... */
/* Clear area */
copyXPMArea( 6, 111, 54 , 9 , 6, 76);
ptr = rateToStr(xmt);
copyXPMArea(('U' - 'A') * 6, 100, 6, 9, 6,
75);
copyXPMArea(64, 90, 4, 9, 12,
75);
for (ii = 20; *ptr; ++ptr)
if (isdigit(*ptr)) {
copyXPMArea((*ptr - '0') * 6, 90, 6, 9, 1 + ii, 75 );
ii += 6;
} else if ('.' == *ptr) {
copyXPMArea(60, 90, 4, 9, 1 + ii, 75);
ii += 4;
} else {
copyXPMArea((toupper(*ptr) - 'A') * 6, 100, 6, 9, 1 + ii,
75);
ii += 6;
}
/* Finally, update the LEDs. */
if (ifIsUp(ifCurr))
SetOnLED(LED_NET_1);
else
SetOffLED(LED_NET_1);
if (ifIsRunning(ifCurr))
SetOnLED(LED_NET_2);
else
SetOffLED(LED_NET_2);
if (ifIsPromisc(ifCurr))
SetErrLED(LED_NET_3);
else
SetOffLED(LED_NET_3);
}
/*------------------------------------------------------------------------------
findInterface
This function attempt to find the indicated interface. It returns the
index of the interface, or zero if the interface isn't found.
------------------------------------------------------------------------------*/
static unsigned findInterface(char const* name)
{
unsigned ii;
/* Since strcasecmp doesn't like NULL pointers, make sure we don't
pass one to it. */
if (name)
for (ii = 0; ii < ifTotal(); ++ii)
if (!strcasecmp(name, ifName(ii)))
return ii;
return 0;
}
/*------------------------------------------------------------------------------
printversion
------------------------------------------------------------------------------*/
static void printversion(void)
{
fprintf(stderr, "wmnet, v1p2\n");
}
/*------------------------------------------------------------------------------
rateToStr
Converts a data rate into its string representation.The string is
saved in a static buffer which is overwritten for each call.
------------------------------------------------------------------------------*/
static char const* rateToStr(unsigned long rate)
{
static char buffer[14];
char scaleFactor='\0', *ptr = buffer;
double drate = getRate(rate,&scaleFactor);
/* Transform the rate value into a left - justified string. */
ptr+=sprintf(ptr,"%.1f",drate);
*ptr++ = scaleFactor;
*ptr = '\0';
return buffer;
}
/*------------------------------------------------------------------------------
getRate
------------------------------------------------------------------------------*/
static double getRate(unsigned long rate, char *scaleFactor)
{
double drate = rate;
/* Based upon its magnitude, determine how much 'rate' needs to be
scaled and also indicate its unit of scale. */
if (rate > 1048576) {
drate /= 1048576;
*scaleFactor = 'M';
} else if (rate > 1024) {
drate /= 1024;
*scaleFactor = 'K';
}
return drate;
}
/*------------------------------------------------------------------------------
SetErrLED
------------------------------------------------------------------------------*/
static void SetErrLED(int led)
{
if (LED_NET_3 == led)
copyXPMArea(LED_ERR_NET_X, LED_ERR_NET_Y, LED_SZE_X, LED_SZE_Y,
LED_PWR_X, LED_PWR_Y);
}
/*------------------------------------------------------------------------------
SetOffLED
------------------------------------------------------------------------------*/
static void SetOffLED(int led)
{
int x, y;
switch (led) {
case LED_NET_1:
x = LED_RCV_X;
y = LED_RCV_Y;
break;
case LED_NET_2:
x = LED_SND_X;
y = LED_SND_Y;
break;
case LED_NET_3:
x = LED_PWR_X;
y = LED_PWR_Y;
break;
default:
return;
}
copyXPMArea(LED_OFF_NET_X, LED_OFF_NET_Y, LED_SZE_X, LED_SZE_Y, x, y);
}
/*------------------------------------------------------------------------------
SetOnLED
------------------------------------------------------------------------------*/
static void SetOnLED(int led)
{
int x, y;
switch (led) {
case LED_NET_1:
x = LED_RCV_X;
y = LED_RCV_Y;
break;
case LED_NET_2:
x = LED_SND_X;
y = LED_SND_Y;
break;
case LED_NET_3:
x = LED_PWR_X;
y = LED_PWR_Y;
break;
default:
return;
}
copyXPMArea(LED_ON_NET_X, LED_ON_NET_Y, LED_SZE_X, LED_SZE_Y, x, y);
}
/*------------------------------------------------------------------------------
usage
------------------------------------------------------------------------------*/
static void usage(void)
{
static char const txt[] =
"\nwmnet, v1p2 - A network interface monitor for WindowMaker.\n\n"
"\t-h this help screen\n"
"\t-i name start with interface 'name'\n"
"\t-u delay seconds between samples (defaults to 1)\n"
"\t-geom <geometry> geometry to use\n"
"\t-v print the version number\n";
fputs(txt, stderr);
}
/*------------------------------------------------------------------------------
wmnet_routine
------------------------------------------------------------------------------*/
static void wmnet_routine(int argc, char **argv)
{
unsigned ifCurr = findInterface(active_interface);
int i;
XEvent Event;
int but_stat = -1;
/* Build up our X connection. */
openXwindow(argc, argv, wmnet_master_xpm, wmnet_mask_bits,
wmnet_mask_width, wmnet_mask_height);
/* > Button */
AddMouseRegion(0, 5, 5, 35, 15);
AddMouseRegion(1, 5, 20, 58, 58);
DrawActiveIFS(ifName(ifCurr));
DrawStats(ifCurr, 40, 5, 58);
RedrawWindow();
while (1) {
static int count = 0;
/* After 1 second (10 * 100 milliseconds), take new samples and
redraw the graph. */
if (++count == 10 * delay) {
ifSample();
DrawStats(ifCurr, 40, 5, 58);
RedrawWindow();
count = 0;
}
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) {
ifCurr = (ifCurr + 1) % ifTotal();
DrawActiveIFS(ifName(ifCurr));
DrawStats(ifCurr, 40, 5, 58);
}
but_stat = -1;
RedrawWindow();
break;
}
}
usleep(100000L);
}
}
/*------------------------------------------------------------------------------
main
------------------------------------------------------------------------------*/
int main(int argc, char *argv[])
{
int ii;
for (ii = 1; ii < argc; ++ii) {
char const* const arg = argv[ii];
if (*arg == '-') {
switch (arg[1]) {
case 'i':
if (ii + 1 < argc)
active_interface = argv[++ii];
else {
printf("wmnet: must specify the interface\n");
return 0;
}
break;
case 'u':
if (ii + 1 < argc) {
delay = atoi(argv[++ii]);
if (delay < 1)
delay = 1;
} else {
printf("wmnet: must specify a delay\n");
return 0;
}
break;
case 'v':
printversion();
return 0;
case 'g':
if (ii + 1 == argc) {
printf("wmnet: must specify geometry\n");
return 0;
}
break;
default:
usage();
return 0;
}
}
}
(void) ifInit();
wmnet_routine(argc, argv);
return 0;
}
syntax highlighted by Code2HTML, v. 0.9.1